]> git.sur5r.net Git - freertos/blob
c7067eb24ecdaf8a6a8870833c1ef40fef9b2795
[freertos] /
1 ##############################################################################
2 #
3 # (c) Copyright 2011 Xilinx, Inc. All rights reserved.
4 #
5 # This file contains confidential and proprietary information of Xilinx, Inc.
6 # and is protected under U.S. and international copyright and other
7 # intellectual property laws.
8 #
9 # DISCLAIMER
10 # This disclaimer is not a license and does not grant any rights to the
11 # materials distributed herewith. Except as otherwise provided in a valid
12 # license issued to you by Xilinx, and to the maximum extent permitted by
13 # applicable law: (1) THESE MATERIALS ARE MADE AVAILABLE "AS IS" AND WITH ALL
14 # FAULTS, AND XILINX HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS,
15 # IMPLIED, OR STATUTORY, INCLUDING BUT NOT LIMITED TO WARRANTIES OF
16 # MERCHANTABILITY, NON-INFRINGEMENT, OR FITNESS FOR ANY PARTICULAR PURPOSE;
17 # and (2) Xilinx shall not be liable (whether in contract or tort, including
18 # negligence, or under any other theory of liability) for any loss or damage
19 # of any kind or nature related to, arising under or in connection with these
20 # materials, including for any direct, or any indirect, special, incidental,
21 # or consequential loss or damage (including loss of data, profits, goodwill,
22 # or any type of loss or damage suffered as a result of any action brought by
23 # a third party) even if such damage or loss was reasonably foreseeable or
24 # Xilinx had been advised of the possibility of the same.
25 #
26 # CRITICAL APPLICATIONS
27 # Xilinx products are not designed or intended to be fail-safe, or for use in
28 # any application requiring fail-safe performance, such as life-support or
29 # safety devices or systems, Class III medical devices, nuclear facilities,
30 # applications related to the deployment of airbags, or any other applications
31 # that could lead to death, personal injury, or severe property or
32 # environmental damage (individually and collectively, "Critical
33 # Applications"). Customer assumes the sole risk and liability of any use of
34 # Xilinx products in Critical Applications, subject only to applicable laws
35 # and regulations governing limitations on product liability.
36 #
37 # THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS PART OF THIS FILE
38 # AT ALL TIMES.
39 #
40 # This file is part of FreeRTOS.
41 #
42 # $Id: freertos_v2_1_0.tcl,v 1.1.2.8 2010/12/10 07:27:08 svemula Exp $
43 ###############################################################################
44
45 # standalone bsp version. set this to the latest "ACTIVE" version.
46 set standalone_version standalone_v3_01_a
47
48 proc kernel_drc {os_handle} {
49     set sw_proc_handle [xget_libgen_proc_handle]
50     set hw_proc_handle [xget_handle $sw_proc_handle "IPINST"]
51     set proctype [xget_value $hw_proc_handle "OPTION" "IPNAME"]
52     set compiler [xget_value $sw_proc_handle "PARAMETER" "COMPILER"]
53
54     # check for valid compiler
55     if { [string first "mb-gcc" $compiler] == 0 && [string first "mb-g++" $compiler] == 0} {
56         error "Wrong compiler requested. FreeRTOS can be compiled only with the GNU compiler for MicroBlaze." "" "mdt_error"
57     }
58
59     # check for valid stdio parameters
60     set stdin [xget_value $os_handle "PARAMETER" "STDIN"]
61     set stdout [xget_value $os_handle "PARAMETER" "STDOUT"]
62     if { $stdin == "none" || $stdout == "none" } {
63         error "The STDIN/STDOUT parameters are not set. FreeRTOS requires stdin/stdout to be set." "" "mdt_error"
64     }
65
66     # check if the design has a intc
67     set intr_port [xget_value $hw_proc_handle "PORT" "Interrupt"]
68     if { [llength $intr_port] == 0 } {
69         error "CPU has no connection to Interrupt controller." "" "mdt_error"
70     }
71
72     # support only AXI/PLB
73     set interconnect [xget_value $hw_proc_handle "PARAMETER" "C_INTERCONNECT"]
74     if { $interconnect == 1 } {
75         set bus_name [xget_hw_busif_value $hw_proc_handle "DPLB"]
76     } elseif { $interconnect == 2 } {
77         set bus_name [xget_hw_busif_value $hw_proc_handle "M_AXI_DP"]
78     } else {
79         error "FreeRTOS supports Microblaze with only a AXI or PLB interconnect" "" "mdt_error"
80     }
81
82     # obtain handles to all the peripherals in the design
83     set mhs_handle [xget_hw_parent_handle $hw_proc_handle]
84     set slave_ifs [xget_hw_connected_busifs_handle $mhs_handle $bus_name "slave"]
85     set timer_count 0
86     set timer_has_intr 0
87
88     # check for a valid timer
89     foreach if $slave_ifs {
90         set ip_handle [xget_hw_parent_handle $if]
91
92         if {$ip_handle != $hw_proc_handle} {
93             set type [xget_hw_value $ip_handle]
94             if { $type == "xps_timer" || $type == "axi_timer" } {
95                 incr timer_count
96                 
97                 # check if the timer interrupts are enabled
98                 set intr_port [xget_value $ip_handle "PORT" "Interrupt"]
99                 if { [llength $intr_port] != 0 } {
100                     set timer_has_intr 1
101                 }
102             }
103         }
104     }
105
106     if { $timer_count == 0 } {
107         error "FreeRTOS for Microblaze requires an axi_timer or xps_timer. The HW platform doesn't have a valid timer." "" "mdt_error"
108     }
109
110     if { $timer_has_intr == 0 } {
111         error "FreeRTOS for Microblaze requires interrupts enabled for a timer." "" "mdt_error"
112     }
113
114     set systmr_interval_ms [xget_value $os_handle "PARAMETER" "systmr_interval"]
115     if { $systmr_interval_ms <= 0 } {
116         error "Invalid value for parameter systmr_interval specified. Please specify a positive value." "" "mdt_error"
117     }
118
119     ### ToDo: Add DRC specific to FreeRTOS
120 }
121
122 proc generate {os_handle} {
123
124     variable standalone_version
125
126     set sw_proc_handle [xget_libgen_proc_handle]
127     set hw_proc_handle [xget_handle $sw_proc_handle "IPINST"]
128     set proctype [xget_value $hw_proc_handle "OPTION" "IPNAME"]
129     set procver [xget_value $hw_proc_handle "PARAMETER" "HW_VER"]
130     
131     set need_config_file "false"
132
133     # proctype should be "microblaze"
134     set mbsrcdir  "../${standalone_version}/src/microblaze"
135     set commondir   "../${standalone_version}/src/common"
136     set datadir   "../${standalone_version}/data"
137
138     foreach entry [glob -nocomplain [file join $commondir *]] {
139         file copy -force $entry [file join ".." "${standalone_version}" "src"]
140     }
141     
142     # proctype should be "microblaze"
143     switch -regexp $proctype {
144         "microblaze" { 
145
146             foreach entry [glob -nocomplain [file join $mbsrcdir *]] {
147                 if { [string first "microblaze_interrupt_handler" $entry] == -1 } { ;# Do not copy over the Standalone BSP exception handler
148                     file copy -force $entry [file join ".." "${standalone_version}" "src"]
149                 }
150             }
151             set need_config_file "true"
152         }
153         "default" {puts "unknown processor type $proctype\n"}
154     }
155
156     # Write the config.make file
157     set makeconfig [open "../standalone_v3_01_a/src/config.make" w]  
158     xprint_generated_header_tcl $makeconfig "Configuration parameters for Standalone Makefile"
159
160     if { $proctype == "microblaze" } {
161         if { [mb_has_exceptions $hw_proc_handle] } {
162             puts $makeconfig "LIBSOURCES = *.s *.c *.S"
163         } else {
164             puts $makeconfig "LIBSOURCES = *.s *.c"
165         }
166     }
167
168     puts $makeconfig "LIBS = standalone_libs"
169     close $makeconfig
170
171     # Remove microblaze directories...
172     file delete -force $mbsrcdir
173
174     # copy required files to the main src directory
175     file copy -force [file join src Source tasks.c] src
176     file copy -force [file join src Source queue.c] src
177     file copy -force [file join src Source list.c] src
178     file copy -force [file join src Source timers.c] src
179     file copy -force [file join src Source portable MemMang heap_3.c] src
180     file copy -force [file join src Source portable GCC MicroBlazeV8 port.c] src
181     file copy -force [file join src Source portable GCC MicroBlazeV8 port_exceptions.c] src
182     file copy -force [file join src Source portable GCC MicroBlazeV8 portasm.S] src
183     file copy -force [file join src Source portable GCC MicroBlazeV8 portmacro.h] src
184     set headers [glob -join ./src/Source/include *.\[h\]]
185     foreach header $headers {
186         file copy -force $header src
187     }
188
189     file delete -force [file join src Source]
190     file delete -force [file join src Source]
191
192     # Handle stdin and stdout
193     xhandle_stdin $os_handle
194     xhandle_stdout $os_handle
195
196     # Create config file for microblaze interrupt handling
197     if {[string compare -nocase $need_config_file "true"] == 0} {
198         xhandle_mb_interrupts
199     }
200
201     # Create config files for Microblaze exception handling
202     if { $proctype == "microblaze" && [mb_has_exceptions $hw_proc_handle] } {
203         xcreate_mb_exc_config_file 
204     }
205
206     # Create bspconfig file
207     set bspcfg_fn [file join ".." "${standalone_version}" "src"  "bspconfig.h"] 
208     file delete $bspcfg_fn
209     set bspcfg_fh [open $bspcfg_fn w]
210     xprint_generated_header $bspcfg_fh "Configurations for Standalone BSP"
211
212     if { $proctype == "microblaze" && [mb_has_pvr $hw_proc_handle] } {
213         
214         set pvr [xget_value $hw_proc_handle "PARAMETER" "C_PVR"]
215         
216         switch $pvr {
217             "0" {
218                 puts $bspcfg_fh "#define MICROBLAZE_PVR_NONE"
219             }
220             "1" {
221                 puts $bspcfg_fh "#define MICROBLAZE_PVR_BASIC"
222             }
223             "2" {
224                 puts $bspcfg_fh "#define MICROBLAZE_PVR_FULL"
225             }
226             "default" {
227                 puts $bspcfg_fh "#define MICROBLAZE_PVR_NONE"
228             }
229         }    
230     }
231
232     close $bspcfg_fh
233
234 # ToDO: FreeRTOS does not handle the following, refer xilkernel TCL script
235 # - MPU settings
236
237     set config_file [xopen_new_include_file "./src/FreeRTOSConfig.h" "FreeRTOS Configuration parameters"]
238     puts $config_file "\#include \"xparameters.h\" \n"
239
240     set val [xget_value $os_handle "PARAMETER" "use_preemption"]
241     if {$val == "false"} {
242         xput_define $config_file "configUSE_PREEMPTION" "0"
243     } else {
244         xput_define $config_file "configUSE_PREEMPTION" "1"
245     }
246
247     set val [xget_value $os_handle "PARAMETER" "use_mutexes"]
248     if {$val == "false"} {
249         xput_define $config_file "configUSE_MUTEXES" "0"
250     } else {
251         xput_define $config_file "configUSE_MUTEXES" "1"
252     }
253     
254     set val [xget_value $os_handle "PARAMETER" "use_recursive_mutexes"]
255     if {$val == "false"} {
256         xput_define $config_file "configUSE_RECURSIVE_MUTEXES" "0"
257     } else {
258         xput_define $config_file "configUSE_RECURSIVE_MUTEXES" "1"
259     }
260
261     set val [xget_value $os_handle "PARAMETER" "use_counting_semaphores"]
262     if {$val == "false"} {
263         xput_define $config_file "configUSE_COUNTING_SEMAPHORES" "0"
264     } else {
265         xput_define $config_file "configUSE_COUNTING_SEMAPHORES" "1"
266     }
267
268     set val [xget_value $os_handle "PARAMETER" "use_timers"]
269     if {$val == "false"} {
270         xput_define $config_file "configUSE_TIMERS" "0"
271     } else {
272         xput_define $config_file "configUSE_TIMERS" "1"
273     }
274
275     set val [xget_value $os_handle "PARAMETER" "use_idle_hook"]
276     if {$val == "false"} {
277         xput_define $config_file "configUSE_IDLE_HOOK"    "0"
278     } else {
279         xput_define $config_file "configUSE_IDLE_HOOK"    "1"
280     }
281
282     set val [xget_value $os_handle "PARAMETER" "use_tick_hook"]
283     if {$val == "false"} {
284         xput_define $config_file "configUSE_TICK_HOOK"    "0"
285     } else {
286         xput_define $config_file "configUSE_TICK_HOOK"    "1"
287     }
288
289     set val [xget_value $os_handle "PARAMETER" "use_malloc_failed_hook"]
290     if {$val == "false"} {
291         xput_define $config_file "configUSE_MALLOC_FAILED_HOOK"    "0"
292     } else {
293         xput_define $config_file "configUSE_MALLOC_FAILED_HOOK"    "1"
294     }
295
296     set val [xget_value $os_handle "PARAMETER" "use_trace_facility"]
297     if {$val == "false"} {
298         xput_define $config_file "configUSE_TRACE_FACILITY" "0"
299     } else {
300         xput_define $config_file "configUSE_TRACE_FACILITY" "1"
301     }
302
303     xput_define $config_file "configUSE_16_BIT_TICKS"   "0"
304     xput_define $config_file "configUSE_APPLICATION_TASK_TAG"   "0"
305     xput_define $config_file "configUSE_CO_ROUTINES"    "0"
306
307     # System timer tick rate (Microblaze only. kernel DRC ensures this)
308     set systmr_interval [xget_value $os_handle "PARAMETER" "systmr_interval"]
309     xput_define $config_file "configTICK_RATE_HZ"     $systmr_interval
310
311     set max_priorities [xget_value $os_handle "PARAMETER" "max_priorities"]
312     xput_define $config_file "configMAX_PRIORITIES"   $max_priorities
313     xput_define $config_file "configMAX_CO_ROUTINE_PRIORITIES" "2"
314     
315     set min_stack [xget_value $os_handle "PARAMETER" "minimal_stack_size"]
316     set min_stack [expr [expr $min_stack + 3] & 0xFFFFFFFC]
317     xput_define $config_file "configMINIMAL_STACK_SIZE" $min_stack
318
319     set total_heap_size [xget_value $os_handle "PARAMETER" "total_heap_size"]
320     set total_heap_size [expr [expr $total_heap_size + 3] & 0xFFFFFFFC]
321     xput_define $config_file "configTOTAL_HEAP_SIZE"  $total_heap_size
322
323     set max_task_name_len [xget_value $os_handle "PARAMETER" "max_task_name_len"]
324     xput_define $config_file "configMAX_TASK_NAME_LEN"  $max_task_name_len
325     
326     set val [xget_value $os_handle "PARAMETER" "idle_yield"]
327     if {$val == "false"} {
328         xput_define $config_file "configIDLE_SHOULD_YIELD"  "0"
329     } else {
330         xput_define $config_file "configIDLE_SHOULD_YIELD"  "1"
331     }
332
333     set val [xget_value $os_handle "PARAMETER" "check_for_stack_overflow"]
334     if {$val == "false"} {
335         xput_define $config_file "configCHECK_FOR_STACK_OVERFLOW"  "0"
336     } else {
337         xput_define $config_file "configCHECK_FOR_STACK_OVERFLOW"  "2"
338     }
339     
340     set val [xget_value $os_handle "PARAMETER" "queue_registry_size"]
341     if {$val == "false"} {
342         xput_define $config_file "configQUEUE_REGISTRY_SIZE"  "0"
343     } else {
344         xput_define $config_file "configQUEUE_REGISTRY_SIZE"  "10"
345     }
346
347     xput_define $config_file "configGENERATE_RUN_TIME_STATS"    "0"
348
349     set val [xget_value $os_handle "PARAMETER" "timer_task_priority"]
350     if {$val == "false"} {
351         xput_define $config_file "configTIMER_TASK_PRIORITY"  "0"
352     } else {
353         xput_define $config_file "configTIMER_TASK_PRIORITY"  "10"
354     }
355
356     set val [xget_value $os_handle "PARAMETER" "timer_command_queue_length"]
357     if {$val == "false"} {
358         xput_define $config_file "configTIMER_QUEUE_LENGTH"  "0"
359     } else {
360         xput_define $config_file "configTIMER_QUEUE_LENGTH"  "10"
361     }
362
363     set val [xget_value $os_handle "PARAMETER" "timer_task_stack_depth"]
364     if {$val == "false"} {
365         xput_define $config_file "configTIMER_TASK_STACK_DEPTH"  "0"
366     } else {
367         xput_define $config_file "configTIMER_TASK_STACK_DEPTH"  $min_stack
368     }
369
370     if { [mb_has_exceptions $hw_proc_handle] } {    
371         xput_define $config_file "configINSTALL_EXCEPTION_HANDLERS"  "1"
372     } else {
373         xput_define $config_file "configINSTALL_EXCEPTION_HANDLERS"  "0"
374     }
375
376     xput_define $config_file "configINTERRUPT_CONTROLLER_TO_USE"  "XPAR_INTC_SINGLE_DEVICE_ID"
377
378     xput_define $config_file "INCLUDE_vTaskCleanUpResources" "0"
379     xput_define $config_file "INCLUDE_vTaskDelay"        "1"
380     xput_define $config_file "INCLUDE_vTaskDelayUntil"   "1"
381     xput_define $config_file "INCLUDE_vTaskDelete"       "1"
382     xput_define $config_file "INCLUDE_xTaskGetCurrentTaskHandle"   "1"
383     xput_define $config_file "INCLUDE_xTaskGetIdleTaskHandle"      "1"
384     xput_define $config_file "INCLUDE_xTaskGetSchedulerState"  "1"
385     xput_define $config_file "INCLUDE_xTimerGetTimerTaskHandle"    "1"
386     xput_define $config_file "INCLUDE_uxTaskGetStackHighWaterMark"  "1"
387     xput_define $config_file "INCLUDE_uxTaskPriorityGet" "1"
388     xput_define $config_file "INCLUDE_vTaskPrioritySet"  "1"
389     xput_define $config_file "INCLUDE_xTaskResumeFromISR"  "1"
390     xput_define $config_file "INCLUDE_vTaskSuspend"      "1"
391     xput_define $config_file "INCLUDE_pcTaskNameGet"      "1"
392     xput_define $config_file "INCLUDE_xTaskIdleTaskHandleGet"      "1"
393     xput_define $config_file "INCLUDE_xTimerDaemonTaskHandleGet"      "1"
394
395     # complete the header protectors
396     puts $config_file "\#endif"
397     close $config_file
398 }
399
400 proc xopen_new_include_file { filename description } {
401     set inc_file [open $filename w]
402     xprint_generated_header $inc_file $description
403     set newfname [string map {. _} [lindex [split $filename {\/}] end]]
404     puts $inc_file "\#ifndef _[string toupper $newfname]"
405     puts $inc_file "\#define _[string toupper $newfname]\n\n"
406     return $inc_file
407 }
408
409 proc xadd_define { config_file os_handle parameter } {
410     set param_value [xget_value $os_handle "PARAMETER" $parameter]
411     puts $config_file "#define [string toupper $parameter] $param_value\n"
412
413     # puts "creating #define [string toupper $parameter] $param_value\n"
414 }
415
416 proc xput_define { config_file parameter param_value } {
417     puts $config_file "#define $parameter $param_value\n"
418
419     # puts "creating #define [string toupper $parameter] $param_value\n"
420 }
421
422 # args field of the array
423 proc xadd_extern_fname {initfile oshandle arrayname arg} { 
424
425     set arrhandle [xget_handle $oshandle "ARRAY" $arrayname]
426     set elements [xget_handle $arrhandle "ELEMENTS" "*"]
427     set count 0
428     set max_count [llength $elements]
429
430     foreach ele $elements {
431         incr count
432         set arg_value [xget_value $ele "PARAMETER" $arg]
433         puts $initfile "extern void $arg_value\(\)\;"
434     }
435     puts $initfile ""
436 }
437
438 # args is variable no - fields of the array
439 proc xadd_struct {initfile oshandle structtype structname arrayname args} { 
440
441     set arrhandle [xget_handle $oshandle "ARRAY" $arrayname]
442     set elements [xget_handle $arrhandle "ELEMENTS" "*"]
443     set count 0
444     set max_count [llength $elements]
445     puts $initfile "struct $structtype $structname\[$max_count\] = \{"
446
447     foreach ele $elements {
448         incr count
449         puts -nonewline $initfile "\t\{"
450         foreach field $args {
451             set field_value [xget_value $ele "PARAMETER" $field]
452             # puts "$arrayname ( $count )->$field is $field_value"
453             puts -nonewline $initfile "$field_value"
454             if { $field != [lindex $args end] } {
455                 puts -nonewline $initfile ","
456             }
457         }
458         if {$count < $max_count} {
459             puts $initfile "\},"
460         } else {
461             puts $initfile "\}"
462         }
463     }
464     puts $initfile "\}\;"
465 }
466
467 # return the sum of all the arg field values in arrayname
468 proc get_field_sum {oshandle arrayname arg} { 
469
470     set arrhandle [xget_handle $oshandle "ARRAY" $arrayname]
471     set elements [xget_handle $arrhandle "ELEMENTS" "*"]
472     set count 0
473     set max_count [llength $elements]
474   
475     foreach ele $elements {
476         set field_value [xget_value $ele "PARAMETER" $arg]
477         set count [expr $field_value+$count]
478     }
479     return $count
480 }
481
482 # return the sum of the product of field values in arrayname
483 proc get_field_product_sum {oshandle arrayname field1 field2} { 
484
485     set arrhandle [xget_handle $oshandle "ARRAY" $arrayname]
486     set elements [xget_handle $arrhandle "ELEMENTS" "*"]
487     set count 0
488     set max_count [llength $elements]
489
490     foreach ele $elements {
491         set field1_value [xget_value $ele "PARAMETER" $field1]
492         set field2_value [xget_value $ele "PARAMETER" $field2]
493         set incr_value [expr $field1_value*$field2_value]
494         set count [expr $count+$incr_value]
495     }
496     return $count
497 }
498
499 proc xhandle_mb_interrupts {} {
500
501     set default_interrupt_handler "XNullHandler"
502     set default_arg "XNULL"
503
504     set source_interrupt_handler $default_interrupt_handler
505     set source_handler_arg $default_arg
506     
507     # Handle the interrupt pin
508     set sw_proc_handle [xget_libgen_proc_handle] 
509     set periph [xget_handle $sw_proc_handle "IPINST"]
510     set source_ports [xget_interrupt_sources $periph]
511     if {[llength $source_ports] > 1} {
512         error "Too many interrupting ports on the MicroBlaze.  Should only find 1" "" "libgen_error"
513         return
514     }
515     
516     if {[llength $source_ports] == 1} {
517         set source_port [lindex $source_ports 0]
518         if {[llength $source_port] != 0} {
519             set source_port_name [xget_value $source_port "VALUE"]      
520             set source_periph [xget_handle $source_port "PARENT"]
521             set source_name [xget_value $source_periph "NAME"]
522             set source_driver [xget_sw_driver_handle_for_ipinst $sw_proc_handle $source_name]
523
524             if {[string compare -nocase $source_driver ""] != 0} {
525                 set int_array [xget_handle $source_driver "ARRAY" "interrupt_handler"]
526                 if {[llength $int_array] != 0} {
527                     set int_array_elems [xget_handle $int_array "ELEMENTS" "*"]
528                     if {[llength $int_array_elems] != 0} {
529                         foreach int_array_elem $int_array_elems {
530                             set int_port [xget_value $int_array_elem "PARAMETER" "int_port"]
531                             if {[llength $int_port] != 0} {
532                                 if {[string compare -nocase $int_port $source_port_name] == 0 } {
533                                     set source_interrupt_handler [xget_value $int_array_elem "PARAMETER" "int_handler"]
534                                     set source_handler_arg [xget_value $int_array_elem "PARAMETER" "int_handler_arg"]
535                                     if {[string compare -nocase $source_handler_arg DEVICE_ID] == 0 } {
536                                         set source_handler_arg [xget_name $source_periph "DEVICE_ID"]
537                                     } else {
538                                         if {[string compare -nocase "global" [xget_port_type $source_port]] == 0} {
539                                             set source_handler_arg $default_arg
540                                         } else {
541                                             set source_handler_arg [xget_name $source_periph "C_BASEADDR"]
542                                         }
543                                     }
544                                     break
545                                 }
546                             }
547                         }
548                     }
549                 }
550             }
551         }
552     }
553     
554     # Generate microblaze_interrupts_g.c file...
555     xcreate_mb_intr_config_file $source_interrupt_handler $source_handler_arg
556     
557 }
558
559
560 proc xcreate_mb_intr_config_file {handler arg} {
561     
562     set mb_table "MB_InterruptVectorTable"
563
564     set filename [file join "../standalone_v3_01_a/src" "microblaze_interrupts_g.c"] 
565     file delete $filename
566     set config_file [open $filename w]
567
568     xprint_generated_header $config_file "Interrupt Handler Table for MicroBlaze Processor"
569     
570     puts $config_file "#include \"microblaze_interrupts_i.h\""
571     puts $config_file "#include \"xparameters.h\""
572     puts $config_file "\n"
573     puts $config_file [format "extern void %s (void *);" $handler]
574     puts $config_file "\n/*"
575     puts $config_file "* The interrupt handler table for microblaze processor"
576     puts $config_file "*/\n"
577     puts $config_file [format "%sEntry %s\[\] =" $mb_table $mb_table]
578     puts $config_file "\{"
579     puts -nonewline $config_file [format "\{\t%s" $handler]
580     puts -nonewline $config_file [format ",\n\t(void*) %s\}" $arg]
581     puts -nonewline $config_file "\n\};"
582     puts $config_file "\n"
583     close $config_file
584 }
585
586
587 # -------------------------------------------
588 # Tcl procedure xcreate_mb_exc_config file
589 # -------------------------------------------
590 proc xcreate_mb_exc_config_file { } {
591     
592     set hfilename [file join "src" "microblaze_exceptions_g.h"] 
593     file delete $hfilename
594     set hconfig_file [open $hfilename w]
595
596     xprint_generated_header $hconfig_file "Exception Handling Header for MicroBlaze Processor"
597     
598     puts $hconfig_file "\n"
599
600     set sw_proc_handle [xget_libgen_proc_handle]
601     set hw_proc_handle [xget_handle $sw_proc_handle "IPINST"]
602     set procver [xget_value $hw_proc_handle "PARAMETER" "HW_VER"]
603
604     if { ![mb_has_exceptions $hw_proc_handle]} { ;# NO exceptions are enabled
605         close $hconfig_file              ;# Do not generate any info in either the header or the C file
606         return
607     }
608     
609     puts $hconfig_file "\#define MICROBLAZE_EXCEPTIONS_ENABLED 1"
610     if { [mb_can_handle_exceptions_in_delay_slots $procver] } {
611         puts $hconfig_file "#define MICROBLAZE_CAN_HANDLE_EXCEPTIONS_IN_DELAY_SLOTS"
612     }
613
614     close $hconfig_file
615 }
616
617 # --------------------------------------
618 # Tcl procedure post_generate
619 # This proc removes from libxil.a the basic 
620 # and standalone BSP versions of 
621 # _interrupt_handler and _hw_exception_handler
622 # routines
623 # --------------------------------------
624 proc post_generate {os_handle} {
625     set sw_proc_handle [xget_libgen_proc_handle]
626     set hw_proc_handle [xget_handle $sw_proc_handle "IPINST"]
627     set proctype [xget_value $hw_proc_handle "OPTION" "IPNAME"]
628     set procname [xget_value $hw_proc_handle "NAME"]
629
630     set procdrv [xget_sw_driver_handle_for_ipinst $sw_proc_handle $procname]
631     set archiver [xget_value $procdrv "PARAMETER" "archiver"]
632
633     if {[string compare -nocase $proctype "microblaze"] == 0 } {
634         # Remove _interrupt_handler.o from libxil.a for FreeRTOS
635                 set libxil_a [file join .. .. lib libxil.a]
636         exec $archiver -d $libxil_a   _interrupt_handler.o
637
638         # We have linkage problems due to how these platforms are defined. Can't do this right now.  
639         # # Remove _exception_handler.o from libxil.a for FreeRTOS
640         # exec bash -c "$archiver -d ../../lib/libxil.a _exception_handler.o"
641         
642         # Remove _hw_exception_handler.o from libxil.a for microblaze cores with exception support
643         if {[mb_has_exceptions $hw_proc_handle]} {
644             exec $archiver -d ../../lib/libxil.a _hw_exception_handler.o
645         }
646     }
647 }
648
649 # --------------------------------------
650 # Tcl procedure execs_generate
651 # This proc removes from libxil.a all 
652 # the stuff that we are overriding
653 # with xilkernel
654 # We currently override,
655 #  MicroBlaze
656 #   - Dummy _interrupt_hander and _hw_exception_handler 
657 #     (in post_generate)
658 #  PPC
659 #   - xvectors.o; sleep.o (IF config_time is true)
660 #  Common to all processors
661 #    - errno.o
662 # --------------------------------------
663 proc execs_generate {os_handle} {
664     set sw_proc_handle [xget_libgen_proc_handle]
665     set hw_proc_handle [xget_handle $sw_proc_handle "IPINST"]
666     set proctype [xget_value $hw_proc_handle "OPTION" "IPNAME"]
667     set procname [xget_value $hw_proc_handle "NAME"]
668
669     set procdrv [xget_sw_driver_handle_for_ipinst $sw_proc_handle $procname]
670     # Remove _interrupt_handler.o from libxil.a for mb-gcc
671     set archiver [xget_value $procdrv "PARAMETER" "archiver"]
672
673     set libxil_a [file join .. .. lib libxil.a]
674 #    exec $archiver -d $libxil_a  errno.o
675
676     # We have linkage problems due to how these platforms are defined. Can't do this right now.  
677     # exec "$archiver -d $libxil_a microblaze_interrupt_handler.o"
678 }
679
680 # --------------------------------------
681 # Return true if this MB has 
682 # exception handling support
683 # --------------------------------------
684 proc mb_has_exceptions { hw_proc_handle } {
685    
686     # Check if the following parameters exist on this MicroBlaze's MPD
687     set ee [xget_value $hw_proc_handle "PARAMETER" "C_UNALIGNED_EXCEPTIONS"]
688     if { $ee != "" } {
689         return true
690     }
691
692     set ee [xget_value $hw_proc_handle "PARAMETER" "C_ILL_OPCODE_EXCEPTION"]
693     if { $ee != "" } {
694         return true
695     }
696
697     set ee [xget_value $hw_proc_handle "PARAMETER" "C_IOPB_BUS_EXCEPTION"]
698     if { $ee != "" } {
699         return true
700     }
701
702     set ee [xget_value $hw_proc_handle "PARAMETER" "C_DOPB_BUS_EXCEPTION"]
703     if { $ee != "" } {
704         return true
705     }
706
707     set ee [xget_value $hw_proc_handle "PARAMETER" "C_DIV_BY_ZERO_EXCEPTION"]
708     if { $ee != "" } {
709         return true
710     } 
711
712     set ee [xget_value $hw_proc_handle "PARAMETER" "C_DIV_ZERO_EXCEPTION"]
713     if { $ee != "" } {
714         return true
715     } 
716
717     set ee [xget_value $hw_proc_handle "PARAMETER" "C_FPU_EXCEPTION"]
718     if { $ee != "" } {
719         return true
720     } 
721
722     set ee [xget_value $hw_proc_handle "PARAMETER" "C_USE_MMU"]
723     if { $ee != "" && $ee != 0 } {
724         return true
725     } 
726
727     return false
728 }
729
730 # --------------------------------------
731 # Return true if this MB has 
732 # FPU exception handling support
733 # --------------------------------------
734 proc mb_has_fpu_exceptions { hw_proc_handle } {
735     
736     # Check if the following parameters exist on this MicroBlaze's MPD
737     set ee [xget_value $hw_proc_handle "PARAMETER" "C_FPU_EXCEPTION"]
738     if { $ee != "" } {
739         return true
740     }
741
742     return false
743 }
744
745 # --------------------------------------
746 # Return true if this MB has PVR support
747 # --------------------------------------
748 proc mb_has_pvr { hw_proc_handle } {
749     
750     # Check if the following parameters exist on this MicroBlaze's MPD
751     set pvr [xget_value $hw_proc_handle "PARAMETER" "C_PVR"]
752     if { $pvr != "" } {
753         return true
754     } 
755
756     return false
757 }
758
759 # --------------------------------------
760 # Return true if MB ver 'procver' has 
761 # support for handling exceptions in 
762 # delay slots
763 # --------------------------------------
764 proc mb_can_handle_exceptions_in_delay_slots { procver } {
765     
766     if { [string compare -nocase $procver "5.00.a"] >= 0 } {
767         return true
768     } else {
769         return false
770     }
771 }
772
773 # --------------------------------------------------------------------------
774 # Gets all the handles that are memory controller cores.
775 # --------------------------------------------------------------------------
776 proc xget_memory_controller_handles { mhs } {
777    set ret_list ""
778
779    # Gets all MhsInsts in the system
780    set mhsinsts [xget_hw_ipinst_handle $mhs "*"]
781
782    # Loop thru each MhsInst and determine if have "ADDR_TYPE = MEMORY" in
783    # the parameters.
784    foreach mhsinst $mhsinsts {
785       # Gets all parameters of the component
786       set params [xget_hw_parameter_handle $mhsinst "*"]
787
788       # Loop thru each param and find tag "ADDR_TYPE = MEMORY"
789       foreach param $params {
790          if {$param == 0} {
791             continue
792          } elseif {$param == ""} {
793             continue
794          }
795          set addrTypeValue [ xget_hw_subproperty_value $param "ADDR_TYPE" ]
796
797          # Found tag! Add MhsInst to list and break to go to next MhsInst
798          if {[string compare -nocase $addrTypeValue "MEMORY"] == 0} {
799             lappend ret_list $mhsinst
800             break
801          }
802       }
803    }
804
805    return $ret_list
806 }