iomodule: Fix for BSP Generation error with iomodule.

This patch updates the iomodule_define_vector_table proc by
removing old hsi commands like xget_handle and also updates
the generate proc to get iomodule canonical definitions in
xparameters.h

Signed-off-by: Naga Sureshkumar Relli <nagasure@xilinx.com>
Reviewed-by: Anirudha Sarangi   <anirudh@xilinx.com>
This commit is contained in:
Naga Sureshkumar Relli 2015-07-21 14:10:09 +05:30 committed by Nava kishore Manne
parent 6e365cf4e0
commit f40ca1f4d4
2 changed files with 142 additions and 80 deletions

View file

@ -39,7 +39,7 @@ BEGIN driver iomodule
OPTION supported_peripherals = (iomodule);
OPTION driver_state = ACTIVE;
OPTION copyfiles = all;
OPTION VERSION = 2.1;
OPTION VERSION = 2.2;
OPTION NAME = iomodule;
OPTION INTC_TYPE = XIOModule;

View file

@ -35,6 +35,11 @@
# 2.0 adk 12/10/13 Updated as per the New Tcl API's
# 2.0 bss 05/02/14 Modified to generate PITx_EXPIRED_MASK parameter
# to fix CR#794167.
# 2.2 nsk 21/07/15 Updated iomodule_define_vector_table by removing
# absoluted hsi commands like xget_handle.CR#865544.
# Modified generate proc to get canonical defintions
# in xparameters.h.
#
##############################################################################
@ -115,9 +120,9 @@ proc generate {drv_handle} {
# 7. INTC
set intc_params [list "C_INTC_LEVEL_EDGE" "C_INTC_POSITIVE"]
set all_params [concat $gpo1_params $gpo2_params $gpo3_params $gpo4_params $intc_params]
set params [concat $gpo1_params $gpo2_params $gpo3_params $gpo4_params $intc_params]
eval [xdefine_include_file_hex $drv_handle "xparameters.h" "XIOModule" $all_params]
eval [xdefine_include_file_hex $drv_handle "xparameters.h" "XIOModule" $params]
# 7. INTC: Set XPAR_IOMODULE_INTC_MAX_INTR_SIZE
set max_intr_size 0
@ -139,7 +144,7 @@ proc generate {drv_handle} {
"XPAR_IOMODULE_SINGLE_BASEADDR" "C_BASEADDR" \
"XPAR_IOMODULE_SINGLE_HIGHADDR" "C_HIGHADDR" \
"XPAR_IOMODULE_INTC_SINGLE_DEVICE_ID" "DEVICE_ID"
}
}
set config_inc [hsi::utils::open_include_file "xparameters.h"]
puts $config_inc "#define XPAR_IOMODULE_INTC_MAX_INTR_SIZE $max_intr_size"
@ -148,6 +153,7 @@ proc generate {drv_handle} {
close $config_inc
xdefine_canonical_xpars $drv_handle "xparameters.h" "IOModule" $all_params
}
@ -288,108 +294,80 @@ proc iomodule_define_vector_table {periph config_inc config_file} {
variable interrupt_handlers
variable default_interrupt_handler
variable source_port_name
variable source_name
variable source_port_type
variable source_driver
variable source_interrupt_handler
variable source_interrupt_id
variable total_source_intrs
#update global array of Interrupt sources for this periph
intc_update_source_array $periph
set periph_name [common::get_property NAME $periph]
set interrupt_pin [hsi::get_pins -of_objects [get_cells $periph] -filter {TYPE==INTERRUPT&&DIRECTION==I}]
# Get ports that are driving the interrupt
set source_ports [hsi::utils::get_interrupt_sources $periph]
set num_intr_inputs [get_num_intr_inputs $periph]
set num_intr_internal [get_num_intr_internal $periph]
# Get pins/ports that are driving the interrupt
lappend source_pins
set source_pins [::hsi::utils::get_source_pins $interrupt_pin]
set num_intr_inputs [common::get_property CONFIG.C_INTC_INTR_SIZE $periph]
if {$num_intr_inputs != [llength $source_ports]} {
error "ERROR: Internal error: Number of interrupt inputs on $periph_name ($num_intr_inputs) is not the same as length of total number of interrupt sources ([llength $source_ports]). If any interrupt source is a vector then libgen does not support this use case" "" "hsi_error"
#calculate the total interrupt sources
set total_intr_ports [::hsi::utils::get_connected_pin_count $interrupt_pin]
if {$num_intr_inputs != $total_intr_ports} {
puts "ERROR: Internal error: Num intr inputs $num_intr_inputs not the \
same as length of ::hsi::utils::get_interrupt_sources [llength \
$source_pins] hsi_error"
return
}
set i 0
foreach source_pin $source_ports {
set source_periph [hsi::get_cells -of_objects $source_pin ]
if { [llength $source_periph ] == 0} {
#external interrupt port case
set width [hsi::utils::get_port_width $source_pin]
for { set j 0 } { $j < $width } { incr j } {
set source_port_name($i) "[common::get_property NAME $source_pin]_$j"
set source_name($i) "system"
set port_type($i) "global"
set source_driver ""
set source_interrupt_handler($i) $default_interrupt_handler
incr i
}
} else {
#peripheral interrrupt case
set port_type($i) "local"
set source_name($i) [common::get_property NAME $source_periph]
set source_port_name($i) [common::get_property NAME $source_pin]
set source_driver [hsi::get_drivers -filter "HW_INSTANCE==$source_periph"]
set source_interrupt_handler($i) $default_interrupt_handler
incr i
}
if {[string compare -nocase $source_driver ""] != 0} {
set int_array [hsi::get_arrays interrupt_handler -of_objects $source_driver]
if {[string compare -nocase $int_array ""] != 0} {
set int_array_elems [xget_handle $int_array "ELEMENTS" "*"]
foreach int_array_elem $int_array_elems {
set int_port [common::get_property CONFIG.int_port $int_array_elem]
set mhs_handle [common::get_property CONFIG.mhsinst $int_array_elem]
if {[string compare -nocase $int_port $source_port_name] == 0 && \
$mhs_handle == $source_periph } {
set source_interrupt_handler($i) [common::get_property CONFIG.int_handler $int_array_elem]
# copy this handler to interrupt_handlers
set arrsize [array size interrupt_handlers]
iomodule_add_handler $source_interrupt_handler($i)
set source_handler_arg($i) [common::get_property CONFIG.int_handler_arg $int_array_elem]
if {[string compare -nocase $source_handler_arg($i) DEVICE_ID] == 0 } {
set source_handler_arg($i) [::hsi::utils::get_ip_param_name $source_periph "DEVICE_ID"]
}
break
}
}
}
}
#Check if default_interrupt_handler has to have an extern definition
if {[array size interrupt_handlers] < $total_source_intrs } {
intc_add_handler $default_interrupt_handler
}
# Check if default_interrupt_handler has to have an extern definition
if {[array size interrupt_handlers] < [llength $source_ports]} {
iomodule_add_handler $default_interrupt_handler
}
# Write vector table to the config_file
puts -nonewline $config_file ",\n\t\t\{"
set comma "\n"
for {set i 0} {$i < $num_intr_internal} {incr i} {
for {set i 0} {$i < $total_source_intrs} {incr i} {
set source_ip $source_name($i)
if { [llength $source_ip] != 0 && [llength [hsi::get_cells $source_ip]] \
!= 0} {
set ip_name [common::get_property IP_NAME [hsi::get_cells $source_ip]]
if { [string compare -nocase $ip_name "xlconstant"] == 0 } {
#do no generate interrupt handler entries for xlconstant
continue
}
}
puts $config_file [format "%s\t\t\t\{" $comma ]
puts $config_file [format "\t\t\t\t%s," $default_interrupt_handler ]
puts $config_file "\t\t\t\t(void *)XNULL"
puts -nonewline $config_file "\t\t\t\}"
set comma ",\n"
}
for {set i 0} {$i < $num_intr_inputs} {incr i} {
puts $config_file [format "%s\t\t\t\{" $comma ]
puts $config_file [format "\t\t\t\t%s," $source_interrupt_handler($i)]
puts $config_file [format "\t\t\t\t%s," $source_interrupt_handler($i) ]
if {[llength $source_name($i)] == 0} {
puts $config_file "\t\t\t\t(void *)XNULL"
} else {
set sname [string toupper $source_name($i)]
set source_xparam_name [::hsi::utils::format_xparam_name $sname]
set pname [string toupper $periph_name]
set periph_xparam_name [::hsi::utils::format_xparam_name $pname]
puts $config_inc [format "#define XPAR_%s_%s_MASK %#08X" \
[string toupper $source_name($i)] \
[string toupper $source_port_name($i)] [expr 1 << $i]]
puts $config_inc [format "#define XPAR_%s_%s_%s_INTR %d" \
[string toupper $periph_name] \
[string toupper $source_name($i)] \
[string toupper $source_port_name($i)] $i]
$source_xparam_name [string toupper $source_port_name($i)] \
[expr 1 << $i]]
puts $config_inc [format "#define XPAR_%s_%s_%s_INTR %d" [string \
toupper $periph_name] [string toupper $source_name($i)] [string \
toupper $source_port_name($i)] $i]
if {[string compare -nocase "global" $port_type($i) ] != 0 && \
if {[string compare -nocase "global" $source_port_type($i) ] != 0 && \
[string compare $source_interrupt_handler($i) $default_interrupt_handler ] != 0} {
puts $config_file [format "\t\t\t\t(void *) %s" $source_handler_arg($i)]
puts $config_file [format "\t\t\t\t(void *) %s" \
$source_handler_arg($i)]
} else {
puts $config_file "\t\t\t\t(void *) XNULL"
}
}
puts -nonewline $config_file "\t\t\t\}"
set comma ",\n"
}
puts $config_file "\n\t\t\}"
}
##########################################################################
@ -808,3 +786,87 @@ proc xdefine_include_file {drv_handle file_name drv_string args} {
puts $file_handle "\n/******************************************************************/\n"
close $file_handle
}
################################################
# This procedure creates a unique list of
# handlers that needs to have an extern defn.
# in xparameters.h
################################################
proc intc_add_handler {handler} {
variable interrupt_handlers
set interrupt_handlers($handler) 1
}
###############################################################################
# this proc traverse all the interrupt source of peripheral and create a array
# will the the details
###############################################################################
proc intc_update_source_array {periph} {
variable default_interrupt_handler
variable source_port_name
variable source_name
variable source_port_type
variable source_driver
variable source_interrupt_handler
variable source_interrupt_id
variable total_source_intrs
array unset source_port_name
array unset source_name
array unset source_port_type
array unset source_driver
array unset source_interrupt_handler
array unset source_interrupt_id
lappend source_pins
set source_pins [::hsi::utils::get_interrupt_sources $periph]
set intr_cnt 0
foreach source_pin $source_pins {
#default value as per external processor
set t_source_port_name [common::get_property NAME $source_pin]
set t_source_name "system"
set t_ip_name ""
set t_port_type "global"
set t_source_driver ""
set t_source_interrupt_handler $default_interrupt_handler
set t_source_intrrupt_id "-1"
#if interrupt is coming from IP, update it.
if { [::hsi::utils::is_external_pin $source_pin] == 0} {
set source_periph [hsi::get_cells -of_objects $source_pin]
set t_source_name [common::get_property NAME $source_periph]
set t_ip_name $t_source_name
set t_port_type "local"
set t_source_driver [hsi::get_drivers -filter "HW_INSTANCE==$t_source_name"]
}
set port_intr_id [::hsi::utils::get_interrupt_id $t_ip_name $source_pin]
if { [llength $port_intr_id ] > 1 } {
#this is the case of vector interrupt port
set j 0
foreach pin_id $port_intr_id {
set source_port_name($intr_cnt) "${t_source_port_name}_$j"
set source_name($intr_cnt) $t_source_name
set source_port_type($intr_cnt) $t_port_type
set source_driver($intr_cnt) $t_source_driver
set source_interrupt_handler($intr_cnt) $t_source_interrupt_handler
set source_interrupt_id($intr_cnt) $pin_id
incr intr_cnt
incr j
}
} else {
set source_port_name($intr_cnt) "${t_source_port_name}"
set source_name($intr_cnt) $t_source_name
set source_port_type($intr_cnt) $t_port_type
set source_driver($intr_cnt) $t_source_driver
set source_interrupt_handler($intr_cnt) $t_source_interrupt_handler
set source_interrupt_id($intr_cnt) $port_intr_id
incr intr_cnt
}
}
set total_source_intrs $intr_cnt
}