intc: Create a new version v3.4

This patch creates a new v3.4 of intc driver and deprecates older v3.3.

Signed-off-by: Shubhrajyoti Datta <shubhraj@xilinx.com>
This commit is contained in:
Shubhrajyoti Datta 2015-06-30 11:35:31 +05:30 committed by Nava kishore Manne
parent 58e0fb3ac2
commit e703803892
18 changed files with 5159 additions and 0 deletions

View file

@ -0,0 +1,73 @@
###############################################################################
#
# Copyright (C) 2005 - 2014 Xilinx, Inc. All rights reserved.
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# Use of the Software is limited solely to applications:
# (a) running on a Xilinx device, or
# (b) that interact with a Xilinx device through a bus or interconnect.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
# OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
#
# Except as contained in this notice, the name of the Xilinx shall not be used
# in advertising or otherwise to promote the sale, use or other dealings in
# this Software without prior written authorization from Xilinx.
#
# MODIFICATION HISTORY:
#
# Ver Who Date Changes
# -------- ------ -------- --------------------------------------------------
# 3.0 adk 10/12/13 Removed support for dcr_intc intc_core xps_intc
##############################################################################
## @BEGIN_CHANGELOG EDK_M
##
## 11/18/09 ktn Removed support for opb_intc
##
## @END_CHANGELOG
## @BEGIN_CHANGELOG EDK_MS3
##
## 06/16/10 sv Added support for axi_intc
##
## @END_CHANGELOG
OPTION psf_version = 2.1;
BEGIN driver intc
OPTION DRC = intc_drc;
OPTION supported_peripherals = (axi_intc);
OPTION driver_state = ACTIVE;
OPTION copyfiles = all;
OPTION VERSION = 3.4;
OPTION NAME = intc;
OPTION INTC_TYPE = XIntc;
BEGIN ARRAY interrupt_handler
PROPERTY desc = "Interrupt Handler";
PROPERTY size = 1, permit = none;
PROPERTY state = deprecated;
PARAM name = int_handler, default = XIntc_DeviceInterruptHandler, desc = "Interrupt Handler", type = string;
PARAM name = int_port, default = Irq, desc = "Interrupt pin associated with the interrupt handler", permit=none;
PARAM name = int_handler_arg, desc = "Argument type to Handler function", type = enum, values= ("Use baseaddress"=C_BASEADDR, "Use device id"=DEVICE_ID), default = DEVICE_ID ;
END ARRAY
END driver

View file

@ -0,0 +1,685 @@
###############################################################################
#
# Copyright (C) 2005 - 2014 Xilinx, Inc. All rights reserved.
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# Use of the Software is limited solely to applications:
# (a) running on a Xilinx device, or
# (b) that interact with a Xilinx device through a bus or interconnect.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
# OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
#
# Except as contained in this notice, the name of the Xilinx shall not be used
# in advertising or otherwise to promote the sale, use or other dealings in
# this Software without prior written authorization from Xilinx.
#
# MODIFICATION HISTORY:
# Ver Who Date Changes
# -------- ------ -------- ------------------------------------
# 3.0 adk 12/10/13 Updated as per the New Tcl API's
##############################################################################
## @BEGIN_CHANGELOG
##
## 09/17/07 ecm Removed the PCI specific connections
## Moved to the Linux MLD.
## 10/24/07 rpm Fixed KIND_OF_INTR bug in canonicals and
## also generalized match on external interrupts
## 06/25/09 sdm Updated so that canonical definitions are
## not generated when instance name matches
## canonical name
## 04/27/10 sdm Updated the tcl so that the defintions are generated in
## the xparameters.h to know whether the optional registers
## SIE, CIE and IVR are enabled in the HW - Refer CR 555392
## 05/24/11 hvm updated tcl to generate vector ids for external interrupts
## CR565336
## 06/15/11 hvm Updated tcl with bypassing the external interrupt definition
## in xredefine_intc function. CR613925.
## 01/19/12 Updated the intc_define_use_dcr function so that it doesnot
## error out if there is more than one bus interface to the
## intc controller. The new common::version of the AXI_INTC can have two
## bus interfaces to support the fast interrupt for MicroBlaze.
## Updated for the generation of the C_HAS_FAST xparameters
## 08/16/12 bss added generation of C_IVAR_RESET_VALUE xparameters
##
## 01/29/13 bss Added check_cascade and get_intctype to support
## Cascade mode. Modified intc_define_vector_table procedure
## to generate interrupt IDs as 32..63 and 64..95 and so on
## for Slave controllers in Cascade mode
## 01/22/14 bss Modified check_cascade to fix CR#764865
## 17/02/14 adk Fixed the CR:771287 in intc_define_vector_table
## if number of interrupt ports not equal to total numer of
## interrupts returning immediatly.And in the xredefine_intc
## if there is not interrupt source returining immediately.
## 4/8/14 bss Modified xredefine_intc to handle external interrupt pins
## correctly (CR#799609).
## 11/3/14 adk added generation of C_HAS_ILR parameter to xparameters.h
## (CR#828046).
##
##
##
## @END_CHANGELOG
############################################################
# Global interrupt handlers array, default handler routine
############################################################
array set interrupt_handlers ""
set default_interrupt_handler "XNullHandler"
set cascade 0
set intrid 0
array set source_port_name ""
array set source_name ""
array set source_port_type ""
array set source_driver ""
array set source_interrupt_handler ""
array set source_interrupt_id ""
set total_source_intrs 0
############################################################
# DRC procedure
############################################################
proc intc_drc {drv_handle} {
}
############################################################
# "generate" procedure
############################################################
proc generate {drv_handle} {
# Generate the following definitions in xparameters.h
# 2. BASEADDR, HIGHADDR, C_NUM_INTR_INPUTS, XPAR_INTC_MAX_NUM_INTR_INPUTS
set periphs [::hsi::utils::get_common_driver_ips $drv_handle]
set count [llength $periphs]
variable cascade
if {$count > 1} {
set cascade [check_cascade $drv_handle]
}
if {$cascade == 0} {
::hsi::utils::define_max $drv_handle "xparameters.h" "XPAR_INTC_MAX_NUM_INTR_INPUTS" "C_NUM_INTR_INPUTS"
} else {
set maxintrs 0
foreach periph $periphs {
set intrs [common::get_property CONFIG.C_NUM_INTR_INPUTS $periph]
set maxintrs [expr "$maxintrs + $intrs"]
}
set file_handle [::hsi::utils::open_include_file "xparameters.h"]
puts $file_handle "#define XPAR_INTC_MAX_NUM_INTR_INPUTS $maxintrs"
close $file_handle
}
foreach periph $periphs {
set fast [::hsi::utils::get_param_value $periph "C_HAS_FAST"]
set nested [::hsi::utils::get_param_value $periph "C_HAS_ILR"]
if {$fast == 1 && $nested == 1} {
puts "ERROR: Internal error: Interrupt Controller Driver has no support for nesting fast interrupts"
}
if {$cascade == 1 && $nested == 1} {
puts "ERROR: Internal error: Interrupt Controller Driver has no support for nesting interrupts in Cascaded mode"
}
}
::hsi::utils::define_if_all $drv_handle "xparameters.h" "XIntc" "C_HAS_IPR" "C_HAS_SIE" "C_HAS_CIE" "C_HAS_IVR" "C_HAS_ILR"
::hsi::utils::define_include_file $drv_handle "xparameters.h" "XIntc" "NUM_INSTANCES" "DEVICE_ID" "C_BASEADDR" "C_HIGHADDR" "C_KIND_OF_INTR" "C_HAS_FAST" "C_IVAR_RESET_VALUE" "C_NUM_INTR_INPUTS"
# Define XPAR_SINGLE_DEVICE_ID
if {$count == 1} {
::hsi::utils::define_with_names $drv_handle [::hsi::utils::get_common_driver_ips $drv_handle] "xparameters.h" "XPAR_INTC_SINGLE_BASEADDR" "C_BASEADDR" "XPAR_INTC_SINGLE_HIGHADDR" "C_HIGHADDR" "XPAR_INTC_SINGLE_DEVICE_ID" "DEVICE_ID"
}
set config_inc [::hsi::utils::open_include_file "xparameters.h"]
# Generate config table, vector tables
intc_define_config_file $drv_handle $periphs $config_inc
close $config_inc
# Generate canonical xparameters
xdefine_canonical_xpars $drv_handle "xparameters.h" "Intc" "DEVICE_ID" "C_BASEADDR" "C_HIGHADDR" "C_KIND_OF_INTR" "C_HAS_FAST" "C_IVAR_RESET_VALUE" "C_NUM_INTR_INPUTS"
}
##########################################################################
# Generate Configuration C file xintc_g.c
# This file has the Config Table and vector tables for each intc instance
# as required by Xilinx intc driver
##########################################################################
proc intc_define_config_file {drv_handle periphs config_inc} {
variable interrupt_handlers
variable default_interrupt_handler
variable cascade
# set isr_options to be XIN_SVC_SGL_ISR_OPTION as defined in xintc.h
set isr_options XIN_SVC_SGL_ISR_OPTION
set file_name "xintc_g.c"
set drv_string "XIntc"
set args [list "DEVICE_ID" "C_BASEADDR" "C_KIND_OF_INTR" "C_HAS_FAST" "C_IVAR_RESET_VALUE" "C_NUM_INTR_INPUTS"]
set filename [file join "src" $file_name]
file delete $filename
set config_file [open $filename w]
::hsi::utils::write_c_header $config_file "Driver configuration"
puts $config_file "#include \"xparameters.h\""
puts $config_file "#include \"[string tolower $drv_string].h\""
puts $config_file "\n"
set tmp_filename [file join "src" "tmpconfig.c"]
set tmp_config_file [open $tmp_filename w]
puts $tmp_config_file "\n/*"
puts $tmp_config_file "* The configuration table for devices"
puts $tmp_config_file "*/\n"
puts $tmp_config_file [format "%s_Config %s_ConfigTable\[\] =" $drv_string $drv_string]
puts $tmp_config_file "\{"
set start_comma ""
foreach periph $periphs {
set periph_name [string toupper [get_property NAME $periph ]]
set xpar_periph_name [::hsi::utils::format_xparam_name $periph_name]
if {$cascade == 1} {
puts $config_inc [format "#define XPAR_%s_%s %d" [string toupper [common::get_property NAME $periph ]] "TYPE" [get_intctype $periph]]
} else {
puts $config_inc [format "#define XPAR_%s_%s %d" [string toupper [common::get_property NAME $periph ]] "TYPE" $cascade]
}
puts $tmp_config_file [format "%s\t\{" $start_comma]
set comma ""
foreach arg $args {
# Check if this is a driver parameter or a peripheral parameter
set value [common::get_property CONFIG.$arg $drv_handle ]
if {[llength $value] == 0} {
puts -nonewline $tmp_config_file [format "%s\t\t%s" $comma [::hsi::utils::get_ip_param_name $periph $arg]]
} else {
puts -nonewline $tmp_config_file [format "%s\t\t%s" $comma [::hsi::utils::get_driver_param_name $drv_string $arg]]
}
set comma ",\n"
}
# add the OPTIONS as an arg to the config table - default OPTIONS value is XIN_SVC_SGL_ISR_OPTION
puts -nonewline $tmp_config_file [format "%s\t\t%s" $comma $isr_options]
puts -nonewline $tmp_config_file ",\n\t\t"
puts -nonewline $tmp_config_file [format "XPAR_%s_%s" [string toupper [common::get_property NAME $periph]] "TYPE"]
# generate the vector table for this intc instance
intc_define_vector_table $periph $config_inc $tmp_config_file
puts $config_inc "\n/******************************************************************/\n"
puts -nonewline $tmp_config_file "\n\t\}"
set start_comma ",\n"
}
puts $tmp_config_file "\n\};"
close $tmp_config_file
# Write out the extern definitions of handlers...
foreach elem [array names interrupt_handlers] {
puts $config_file [format "extern void %s (void *);" $elem ]
}
# copy over the tmp_config_file contents to config_file
set tmp_config_file [open $tmp_filename r]
while {![eof $tmp_config_file]} {
gets $tmp_config_file line
puts $config_file $line
}
close $tmp_config_file
file delete -force $tmp_filename
close $config_file
}
proc intc_define_vector_table {periph config_inc config_file} {
variable interrupt_handlers
variable default_interrupt_handler
variable cascade
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 $periph intr]
# 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_NUM_INTR_INPUTS $periph]
#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
}
#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
}
puts -nonewline $config_file ",\n\t\t\{"
set comma "\n"
for {set i 0} {$i < $total_source_intrs} {incr i} {
puts $config_file [format "%s\t\t\t\{" $comma ]
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" $source_xparam_name [string toupper $source_port_name($i)] [expr 1 << $i]]
if {$cascade ==1} {
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)] $source_interrupt_id($i)]
} else {
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" $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)]
} 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\}"
}
################################################
# 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
}
#
# Given a list of arguments, define each as a canonical constant name, using
# the driver name, in an include file.
#
proc xdefine_canonical_xpars {drv_handle file_name drv_string args} {
variable cascade
# Open include file
set file_handle [::hsi::utils::open_include_file $file_name]
# Get all the peripherals connected to this driver
set periphs [::hsi::utils::get_common_driver_ips $drv_handle]
# Get the names of all the peripherals connected to this driver
foreach periph $periphs {
set peripheral_name [string toupper [common::get_property NAME $periph]]
lappend peripherals $peripheral_name
}
# Get possible canonical names for all the peripherals connected to this driver
set device_id 0
foreach periph $periphs {
set canonical_name [string toupper [format "%s_%s" $drv_string $device_id]]
lappend canonicals $canonical_name
# Create a list of IDs of the peripherals whose hardware instance name
# doesn't match the canonical name. These IDs can be used later to
# generate canonical definitions
if { [lsearch $peripherals $canonical_name] < 0 } {
lappend indices $device_id
}
incr device_id
}
set i 0
foreach periph $periphs {
set periph_name [string toupper [common::get_property NAME $periph]]
# Generate canonical definitions only for the peripherals whose
# canonical name is not the same as hardware instance name
if { [lsearch $canonicals $periph_name] < 0 } {
puts $file_handle "/* Canonical definitions for peripheral $periph_name */"
set canonical_name [format "%s_%s" $drv_string [lindex $indices $i]]
foreach arg $args {
set lvalue [::hsi::utils::get_driver_param_name $canonical_name $arg]
# The commented out rvalue is the name of the instance-specific constant
# set rvalue [::hsi::utils::get_ip_param_name $periph $arg]
# The rvalue set below is the actual value of the parameter
set rvalue [::hsi::utils::get_param_value $periph $arg]
if {[llength $rvalue] == 0} {
set rvalue 0
}
set rvalue [::hsi::utils::format_addr_string $rvalue $arg]
puts $file_handle "#define $lvalue $rvalue"
}
if {$cascade == 1} {
puts $file_handle "#define [::hsi::utils::get_driver_param_name $canonical_name "INTC_TYPE"] [get_intctype $periph]"
} else {
puts $file_handle "#define [::hsi::utils::get_driver_param_name $canonical_name "INTC_TYPE"] $cascade"
}
puts $file_handle ""
incr i
}
}
#
# Now redefine the Interrupt ID constants
#
xredefine_intc $drv_handle $file_handle
puts $file_handle "\n/******************************************************************/\n"
close $file_handle
}
################################################
#
# intc redefines
#
################################################
proc xredefine_intc {drvhandle config_inc} {
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
# Next define interrupt IDs for each connected peripheral
set periphs [::hsi::utils::get_common_driver_ips $drvhandle]
set device_id 0
set periph_name [string toupper "intc"]
foreach periph $periphs {
#update global array of Interrupt sources for this periph
intc_update_source_array $periph
lappend source_list
for {set j 0 } { $j < $total_source_intrs } { incr j} {
lappend source_list $source_name($j)
}
# Get the edk based name of peripheral for printing redefines
set periph_ip_name [common::get_property NAME $periph]
set num_intr_inputs [common::get_property CONFIG.C_NUM_INTR_INPUTS $periph]
for {set i 0} {$i < $num_intr_inputs} {incr i} {
if {[string compare -nocase $source_name($i) "system"] == 0} {
continue
}
set drv [hsi::get_drivers -filter "HW_INSTANCE==$source_name($i)"]
if {[llength $source_name($i)] != 0 && [llength $drv] != 0} {
set instance [xfind_instance $drv $source_name($i)]
set drvname [common::get_property NAME $drv]
#
# Handle reference cores, which have non-reference driver names
#
if {[string compare -nocase $drvname "touchscreen_ref"] == 0} {
set drvname "touchscreen"
} elseif {[string compare -nocase $drvname "ps2_ref"] == 0} {
set drvname "ps2"
set instance [expr $instance*2]
if {[string match -nocase "*SYS_INTR2" $source_port_name($i)] == 1} {
incr instance
}
}
#
# Define the interrupt vector IDs in xparameters.h for each core
# that is connected to this intc.
#
set drvname [string toupper $drvname]
#
# Treat sources with multiple interrupt ports slightly different
# by including the interrupt port name in the canonical constant
# name
#
if { [lcount $source_list $source_name($i)] > 1} {
set port_name [string toupper $source_port_name($i)]
#
# If there are multiple interrupt ports for axi_ethernet, do not include
# the port name in the canonical name, for the port "INTERRUPT". Other ports
# will have the port name in the canonical name. This is to make sure that
# the canonical name for the port INTERRUPT will remain same irrespective of
# whether the design has a single interrupt port or multiple interrupt ports
#
if {[string compare -nocase $drvname "axiethernet"] == 0} {
if {[string compare -nocase $port_name "INTERRUPT"] == 0} {
set first_part [format "#define XPAR_%s_%s_%s_%s_VEC_ID" $periph_name $device_id $drvname $instance]
} else {
set first_part [format "#define XPAR_%s_%s_%s_%s_%s_VEC_ID" $periph_name $device_id $drvname $instance $port_name]
}
} else {
set first_part [format "#define XPAR_%s_%s_%s_%s_%s_VEC_ID" $periph_name $device_id $drvname $instance $port_name]
}
} else {
set first_part [format "#define XPAR_%s_%s_%s_%s_VEC_ID" $periph_name $device_id $drvname $instance]
}
set second_part [format "XPAR_%s_%s_%s_INTR" [string toupper $periph_ip_name] [string toupper $source_name($i)] [string toupper $source_port_name($i)] ]
if {[string compare -nocase $drvname "generic"] != 0} {
set first_part_xparam_name [::hsi::utils::format_xparam_name $first_part]
set second_part_xparam_name [::hsi::utils::format_xparam_name $second_part]
puts $config_inc "$first_part_xparam_name $second_part_xparam_name"
}
}
}
incr device_id
}
}
###################################################################
#
# Get the number of elements in the given list that match the
# given entry. Assume elements are strings.
#
###################################################################
proc lcount {list match_entry} {
set len [llength $list]
set count 0
for {set i 0} {$i < $len} {incr i} {
set entry [lindex $list $i]
if { [string compare -nocase $entry $match_entry] == 0} {
incr count
}
}
return $count
}
###################################################################
#
# Get the HW instance number for a particular device. This will be used to enumerate
# the vector ID defines if more than one interrupt from the core is connected to the
# interrupt controller.
#
###################################################################
proc xfind_instance {drvhandle instname} {
set instlist [::hsi::utils::get_common_driver_ips $drvhandle]
set i 0
foreach inst $instlist {
set name [common::get_property NAME $inst]
if {[string compare -nocase $instname $name] == 0} {
return $i
}
incr i
}
set i 0
return $i
}
###################################################################################
#
# Checks whether system has Cascade interrupt controllers
#
###################################################################################
proc check_cascade {drv_handle} {
set periphs [::hsi::utils::get_common_driver_ips $drv_handle]
foreach periph $periphs {
set i 0
set source_pins [::hsi::utils::get_interrupt_sources $periph]
foreach source_pin $source_pins {
set source_pin_name($i) [common::get_property NAME $source_pin]
if { [::hsi::utils::is_external_pin $source_pin] } {
continue
}
set source_periph [hsi::get_cells -of_objects $source_pin ]
set source_type [common::get_property IP_TYPE $source_periph]
if {[string compare -nocase $source_type "INTERRUPT_CNTLR"] == 0} {
return 1
}
}
}
return 0
}
##################################################################
#
# Returns Interrupt controller type
# 1 - primary instance
# 2 - secondary instance
# 3 - last instance
#
##################################################################
proc get_intctype {periph} {
set iscascade [::hsi::utils::get_param_value $periph "C_EN_CASCADE_MODE"]
set ismaster [::hsi::utils::get_param_value $periph "C_CASCADE_MASTER"]
if {$iscascade == 1 && $ismaster == 1} {
set retval 1
} elseif {$iscascade == 1 && $ismaster == 0} {
set retval 2
} elseif {$iscascade == 0 && $ismaster == 0} {
set retval 3
} else {
error "ERROR: The C_CASCADE_MASTER is allowed to set only when the C_EN_CASCADE_MODE is set to 1"
}
return $retval
}
###############################################################################
# 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]
puts "source_pins = $source_pins of intc = $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
}

View file

@ -0,0 +1,42 @@
/******************************************************************************
*
* Copyright (C) 2012 - 2014 Xilinx, Inc. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* Use of the Software is limited solely to applications:
* (a) running on a Xilinx device, or
* (b) that interact with a Xilinx device through a bus or interconnect.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Except as contained in this notice, the name of the Xilinx shall not be used
* in advertising or otherwise to promote the sale, use or other dealings in
* this Software without prior written authorization from Xilinx.
*
******************************************************************************/
#ifndef INTC_HEADER_H /* prevent circular inclusions */
#define INTC_HEADER_H /* by using protection macros */
#include "xil_assert.h"
#include "xil_types.h"
#include "xstatus.h"
int IntcSelfTestExample(u16 DeviceId);
int IntcInterruptSetup(XIntc *IntcInstancePtr, u16 DeviceId);
#endif

View file

@ -0,0 +1,206 @@
###############################################################################
#
# Copyright (C) 2004 - 2014 Xilinx, Inc. All rights reserved.
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# Use of the Software is limited solely to applications:
# (a) running on a Xilinx device, or
# (b) that interact with a Xilinx device through a bus or interconnect.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
# OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
#
# Except as contained in this notice, the name of the Xilinx shall not be used
# in advertising or otherwise to promote the sale, use or other dealings in
# this Software without prior written authorization from Xilinx.
#
#
# MODIFICATION HISTORY:
# Ver Who Date Changes
# -------- ------ -------- ------------------------------------
# 3.0 adk 12/10/13 Updated as per the New Tcl API's
# 3.1 adk 8/4/14 Fix the CR:783248 Modified the Cascade logic
# in the app tcl
##############################################################################
## @BEGIN_CHANGELOG EDK_I_SP1
##
## - Initial Revision
##
## 01/30/13 bss Modified script to skip tests for Slave controllers in Cascade
## mode
## 02/26/13 bss Modified get_intr procedure to support Vivado designs
##
## @END_CHANGELOG
# Uses $XILINX_EDK/bin/lib/xillib_sw.tcl
# -----------------------------------------------------------------
# Software Project Types (swproj):
# 0 : MemoryTest - Calls basic memorytest routines from common driver dir
# 1 : PeripheralTest - Calls any existing polled_example and/or selftest
# -----------------------------------------------------------------
# -----------------------------------------------------------------
# TCL Procedures:
# -----------------------------------------------------------------
proc gen_include_files {swproj mhsinst} {
if {$swproj == 0} {
return ""
}
if {$swproj == 1} {
set inc_file_lines {xintc.h intc_header.h}
return $inc_file_lines
}
}
proc gen_src_files {swproj mhsinst} {
if {$swproj == 0} {
return ""
}
if {$swproj == 1} {
set inc_file_lines {examples/xintc_tapp_example.c data/intc_header.h}
return $inc_file_lines
}
}
proc gen_testfunc_def {swproj mhsinst} {
return ""
}
proc gen_init_code {swproj mhsinst} {
return ""
}
proc gen_testfunc_call {swproj mhsinst} {
if {$swproj == 0} {
return ""
}
set cascade [check_cascade $mhsinst]
if {$cascade == 1} {
set iscascade [common::get_property CONFIG.C_EN_CASCADE_MODE $mhsinst]
set ismaster [common::get_property CONFIG.C_CASCADE_MASTER $mhsinst]
if {!($iscascade == 1 && $ismaster == 1)} {
return ""
}
}
set ipname [common::get_property NAME $mhsinst]
set deviceid [::hsi::utils::get_ip_param_name $mhsinst "DEVICE_ID"]
set stdout [common::get_property CONFIG.STDOUT [hsi::get_os]]
if { $stdout == "" || $stdout == "none" } {
set hasStdout 0
} else {
set hasStdout 1
}
set intcvar intc
set testfunc_call ""
if {${hasStdout} == 0} {
append testfunc_call "
{
int status;
status = IntcSelfTestExample(${deviceid});
}"
set ifintr [::hsi::utils::is_ip_interrupting_current_proc $mhsinst]
if {$ifintr != 0} {
append testfunc_call "
{
int Status;
Status = IntcInterruptSetup(&${intcvar}, ${deviceid});
}"
}
} else {
append testfunc_call "
{
int status;
print(\"\\r\\n Running IntcSelfTestExample() for ${ipname}...\\r\\n\");
status = IntcSelfTestExample(${deviceid});
if (status == 0) {
print(\"IntcSelfTestExample PASSED\\r\\n\");
}
else {
print(\"IntcSelfTestExample FAILED\\r\\n\");
}
}"
set ifintr [::hsi::utils::is_ip_interrupting_current_proc $mhsinst]
if {$ifintr != 0} {
append testfunc_call "
{
int Status;
Status = IntcInterruptSetup(&${intcvar}, ${deviceid});
if (Status == 0) {
print(\"Intc Interrupt Setup PASSED\\r\\n\");
}
else {
print(\"Intc Interrupt Setup FAILED\\r\\n\");
}
}"
}
}
return $testfunc_call
}
proc check_cascade {mhsinst} {
set periphs [::hsi::utils::get_common_driver_ips $mhsinst]
foreach periph $periphs {
set i 0
set source_pins [::hsi::utils::get_interrupt_sources $periph]
foreach source_pin $source_pins {
set source_pin_name($i) [common::get_property NAME $source_pin]
if { [::hsi::utils::is_external_pin $source_pin] } {
continue
}
set source_periph [hsi::get_cells -of_objects $source_pin ]
set source_type [common::get_property IP_TYPE $source_periph]
if {[string compare -nocase $source_type "INTERRUPT_CNTLR"] == 0} {
return 1
}
}
}
return 0
}

View file

@ -0,0 +1,19 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
<html>
<head>
<meta http-equiv="Content-Language" content="en-us">
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Driver example applications</title>
<link rel="stylesheet" type="text/css" href="../help.css">
</head>
<body bgcolor="#FFFFFF">
<h1> Example Applications for the driver intc_v3_2 </h1>
<HR>
<ul>
<li>xintc_low_level_example.c <a href="xintc_low_level_example.c">(source)</a> </li>
<li>xintc_example.c <a href="xintc_example.c">(source)</a> </li>
<li>xintc_tapp_example.c <a href="xintc_tapp_example.c">(source)</a> </li>
</ul>
<p><font face="Times New Roman" color="#800000">Copyright <20> 1995-2014 Xilinx, Inc. All rights reserved.</font></p>
</body>
</html>

View file

@ -0,0 +1,348 @@
/******************************************************************************
*
* Copyright (C) 2002 - 2014 Xilinx, Inc. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* Use of the Software is limited solely to applications:
* (a) running on a Xilinx device, or
* (b) that interact with a Xilinx device through a bus or interconnect.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Except as contained in this notice, the name of the Xilinx shall not be used
* in advertising or otherwise to promote the sale, use or other dealings in
* this Software without prior written authorization from Xilinx.
*
******************************************************************************/
/******************************************************************************/
/**
*
* @file xintc_example.c
*
* This file contains a design example using the Interrupt Controller driver
* (XIntc) and hardware device. Please reference other device driver examples to
* see more examples of how the intc and interrupts can be used by a software
* application.
*
* This example shows the use of the Interrupt Controller both with a PowerPC
* and MicroBlaze processor.
*
* @note
* This example can also be used for Cascade mode interrupt
* controllers by using the interrupt IDs generated in
* xparameters.h. For Cascade mode, Interrupt IDs are generated
* in xparameters.h as shown below:
*
* Master/Primary INTC
* ______
* | |-0 Secondary INTC
* | |-. ______
* | |-. | |-32 Last INTC
* | |-. | |-. ______
* |______|<--31-----| |-. | |-64
* | |-. | |-.
* |______|<--63------| |-.
* | |-.
* |______|-95
*
* All driver functions has to be called using
* DeviceId/InstancePtr of Primary/Master Controller only. Driver
* functions takes care of Slave Controllers based on Interrupt
* ID passed. User must not use Interrupt source/ID 31 of Primary
* and Secondary controllers to call driver functions.
*
* <pre>
*
* MODIFICATION HISTORY:
* Ver Who Date Changes
* ----- ---- -------- ----------------------------------------------------
* 1.00b jhl 02/13/02 First release
* 1.00c rpm 11/13/03 Updated to show microblaze and PPC interrupt use and
* to use the common L0/L1 interrupt handler with device ID.
* 1.00c sv 06/29/05 Minor changes to comply to Doxygen and coding guidelines
* 2.00a ktn 10/20/09 Updated to use HAL Processor APIs amd minor modifications
* as per coding guidelines.
* </pre>
******************************************************************************/
/***************************** Include Files *********************************/
#include "xparameters.h"
#include "xstatus.h"
#include "xintc.h"
#include "xil_exception.h"
/************************** Constant Definitions *****************************/
/*
* The following constants map to the XPAR parameters created in the
* xparameters.h file. They are defined here such that a user can easily
* change all the needed parameters in one place.
*/
#define INTC_DEVICE_ID XPAR_INTC_0_DEVICE_ID
/*
* This is the Interrupt Number of the Device whose Interrupt Output is
* connected to the Input of the Interrupt Controller
*/
#define INTC_DEVICE_INT_ID XPAR_INTC_0_UARTLITE_0_VEC_ID
/**************************** Type Definitions *******************************/
/***************** Macros (Inline Functions) Definitions *********************/
/************************** Function Prototypes ******************************/
int IntcExample(u16 DeviceId);
int SetUpInterruptSystem(XIntc *XIntcInstancePtr);
void DeviceDriverHandler(void *CallbackRef);
/************************** Variable Definitions *****************************/
static XIntc InterruptController; /* Instance of the Interrupt Controller */
/*
* Create a shared variable to be used by the main thread of processing and
* the interrupt processing
*/
volatile static int InterruptProcessed = FALSE;
/*****************************************************************************/
/**
*
* This is the main function for the Interrupt Controller example.
*
* @param None.
*
* @return XST_SUCCESS to indicate success, otherwise XST_FAILURE.
*
* @note None.
*
****************************************************************************/
int main(void)
{
int Status;
/*
* Run the Intc example , specify the Device ID generated in
* xparameters.h
*/
Status = IntcExample(INTC_DEVICE_ID);
if (Status != XST_SUCCESS) {
return XST_FAILURE;
}
return XST_SUCCESS;
}
/*****************************************************************************/
/**
*
* This function is an example of how to use the interrupt controller driver
* component (XIntc) and the hardware device. This function is designed to
* work without any hardware devices to cause interrupts. It may not return
* if the interrupt controller is not properly connected to the processor in
* either software or hardware.
*
* This function relies on the fact that the interrupt controller hardware
* has come out of the reset state such that it will allow interrupts to be
* simulated by the software.
*
* @param DeviceId is Device ID of the Interrupt Controller Device,
* typically XPAR_<INTC_instance>_DEVICE_ID value from
* xparameters.h.
*
* @return XST_SUCCESS to indicate success, otherwise XST_FAILURE.
*
* @note None.
*
******************************************************************************/
int IntcExample(u16 DeviceId)
{
int Status;
/*
* Initialize the interrupt controller driver so that it is ready to
* use.
*/
Status = XIntc_Initialize(&InterruptController, DeviceId);
if (Status != XST_SUCCESS) {
return XST_FAILURE;
}
/*
* Perform a self-test to ensure that the hardware was built
* correctly.
*/
Status = XIntc_SelfTest(&InterruptController);
if (Status != XST_SUCCESS) {
return XST_FAILURE;
}
/*
* Setup the Interrupt System.
*/
Status = SetUpInterruptSystem(&InterruptController);
if (Status != XST_SUCCESS) {
return XST_FAILURE;
}
/*
* Simulate the Interrupt.
*/
Status = XIntc_SimulateIntr(&InterruptController, INTC_DEVICE_INT_ID);
if (Status != XST_SUCCESS) {
return XST_FAILURE;
}
/*
* Wait for the interrupt to be processed, if the interrupt does not
* occur this loop will wait forever.
*/
while (1)
{
/*
* If the interrupt occurred which is indicated by the global
* variable which is set in the device driver handler, then
* stop waiting.
*/
if (InterruptProcessed) {
break;
}
}
return XST_SUCCESS;
}
/******************************************************************************/
/**
*
* This function connects the interrupt handler of the interrupt controller to
* the processor. This function is seperate to allow it to be customized for
* each application. Each processor or RTOS may require unique processing to
* connect the interrupt handler.
*
* @param None.
*
* @return None.
*
* @note None.
*
****************************************************************************/
int SetUpInterruptSystem(XIntc *XIntcInstancePtr)
{
int Status;
/*
* Connect a device driver handler that will be called when an interrupt
* for the device occurs, the device driver handler performs the
* specific interrupt processing for the device.
*/
Status = XIntc_Connect(XIntcInstancePtr, INTC_DEVICE_INT_ID,
(XInterruptHandler)DeviceDriverHandler,
(void *)0);
if (Status != XST_SUCCESS) {
return XST_FAILURE;
}
/*
* Start the interrupt controller such that interrupts are enabled for
* all devices that cause interrupts, specify simulation mode so that
* an interrupt can be caused by software rather than a real hardware
* interrupt.
*/
Status = XIntc_Start(XIntcInstancePtr, XIN_SIMULATION_MODE);
if (Status != XST_SUCCESS) {
return XST_FAILURE;
}
/*
* Enable the interrupt for the device and then cause (simulate) an
* interrupt so the handlers will be called.
*/
XIntc_Enable(XIntcInstancePtr, INTC_DEVICE_INT_ID);
/*
* Initialize the exception table.
*/
Xil_ExceptionInit();
/*
* Register the interrupt controller handler with the exception table.
*/
Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT,
(Xil_ExceptionHandler)XIntc_InterruptHandler,
XIntcInstancePtr);
/*
* Enable exceptions.
*/
Xil_ExceptionEnable();
return XST_SUCCESS;
}
/******************************************************************************/
/**
*
* This function is designed to look like an interrupt handler in a device
* driver. This is typically a 2nd level handler that is called from the
* interrupt controller interrupt handler. This handler would typically
* perform device specific processing such as reading and writing the registers
* of the device to clear the interrupt condition and pass any data to an
* application using the device driver. Many drivers already provide this
* handler and the user is not required to create it.
*
* @param CallbackRef is passed back to the device driver's interrupt
* handler by the XIntc driver. It was given to the XIntc driver
* in the XIntc_Connect() function call. It is typically a pointer
* to the device driver instance variable if using the Xilinx
* Level 1 device drivers. In this example, we do not care about
* the callback reference, so we passed it a 0 when connecting the
* handler to the XIntc driver and we make no use of it here.
*
* @return None.
*
* @note None.
*
****************************************************************************/
void DeviceDriverHandler(void *CallbackRef)
{
/*
* Indicate the interrupt has been processed using a shared variable.
*/
InterruptProcessed = TRUE;
}

View file

@ -0,0 +1,302 @@
/******************************************************************************
*
* Copyright (C) 2002 - 2014 Xilinx, Inc. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* Use of the Software is limited solely to applications:
* (a) running on a Xilinx device, or
* (b) that interact with a Xilinx device through a bus or interconnect.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Except as contained in this notice, the name of the Xilinx shall not be used
* in advertising or otherwise to promote the sale, use or other dealings in
* this Software without prior written authorization from Xilinx.
*
******************************************************************************/
/******************************************************************************/
/**
*
* @file xintc_low_level_example.c
*
* This file contains a design example using the low level-0 driver, interface
* of the Interrupt Controller driver.
*
* This example shows the use of the Interrupt Controller both with a PowerPC
* and a MicroBlaze processor.
*
* @note
* This example can also be used for Cascade mode interrupt
* controllers by using the interrupt IDs generated in
* xparameters.h. For Cascade mode, Interrupt IDs are generated
* in xparameters.h as shown below:
*
* Master/Primary INTC
* ______
* | |-0 Secondary INTC
* | |-. ______
* | |-. | |-32 Last INTC
* | |-. | |-. ______
* |______|<--31-----| |-. | |-64
* | |-. | |-.
* |______|<--63------| |-.
* | |-.
* |______|-95
*
* All driver functions has to be called using BaseAddress
* of Primary/Master Controller only. Driver functions takes
* care of Slave Controllers based on Interrupt ID passed.
* User must not use Interrupt source/ID 31 of Primary and
* Secondary controllers to call driver functions.
*
*
* <pre>
*
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ---- -------- ---------------------------------------------------------
* 1.00c rpm 12/04/03 First release
* 1.00c sv 06/29/05 Minor changes to comply to Doxygen and coding guidelines
* 2.00a ktn 10/20/09 Updated to use HAL Processor APIs and _m is removed from
* all the macro names/definitions. Minor changes done as per
* coding guidelines.
* </pre>
******************************************************************************/
/***************************** Include Files *********************************/
#include "xparameters.h"
#include "xstatus.h"
#include "xintc_l.h"
#include "xil_exception.h"
/************************** Constant Definitions *****************************/
/*
* The following constants map to the XPAR parameters created in the
* xparameters.h file. They are defined here such that a user can easily
* change all the needed parameters in one place.
*/
#define INTC_BASEADDR XPAR_INTC_0_BASEADDR
#define INTC_DEVICE_ID XPAR_INTC_0_DEVICE_ID
#define INTC_DEVICE_INTR_ID XPAR_INTC_0_UARTLITE_0_VEC_ID
#define INTC_DEVICE_INT_MASK XPAR_RS232_UART_1_INTERRUPT_MASK
/**************************** Type Definitions *******************************/
/***************** Macros (Inline Functions) Definitions *********************/
/************************** Function Prototypes ******************************/
int IntcLowLevelExample(u32 IntcBaseAddress);
void SetupInterruptSystem();
void DeviceDriverHandler(void *CallbackRef);
/************************** Variable Definitions *****************************/
/*
* Create a shared variable to be used by the main thread of processing and
* the interrupt processing
*/
volatile static int InterruptProcessed = FALSE;
/*****************************************************************************/
/**
*
* This is the main function for the Interrupt Controller Low Level example.
*
* @param None.
*
* @return XST_SUCCESS to indicate success, otherwise XST_FAILURE.
*
* @note None.
*
******************************************************************************/
int main(void)
{
int Status;
/*
* Run the low level example of Interrupt Controller, specify the Base
* Address generated in xparameters.h.
*/
Status = IntcLowLevelExample(INTC_BASEADDR);
if (Status != XST_SUCCESS) {
return XST_FAILURE;
}
return XST_SUCCESS;
}
/*****************************************************************************/
/**
*
* This function is an example of how to use the interrupt controller driver
* component (XIntc) and the hardware device. This function is designed to
* work without any hardware devices to cause interrupts. It may not return
* if the interrupt controller is not properly connected to the processor in
* either software or hardware.
*
* This function relies on the fact that the interrupt controller hardware
* has come out of the reset state such that it will allow interrupts to be
* simulated by the software.
*
* @param IntcBaseAddress is Base Address of the the Interrupt Controller
* Device.
*
* @return XST_SUCCESS to indicate success, otherwise XST_FAILURE.
*
* @note None.
*
******************************************************************************/
int IntcLowLevelExample(u32 IntcBaseAddress)
{
/*
* Connect a device driver handler that will be called when an interrupt
* for the device occurs, the device driver handler performs the
* specific interrupt processing for the device.
*/
XIntc_RegisterHandler(IntcBaseAddress, INTC_DEVICE_INTR_ID,
(XInterruptHandler)DeviceDriverHandler,
(void *)0);
/*
* Enable interrupts for all devices that cause interrupts, and enable
* the INTC master enable bit.
*/
XIntc_EnableIntr(IntcBaseAddress, INTC_DEVICE_INT_MASK);
/*
* Set the master enable bit. Note that we do not enable hardware
* interrupts yet since we want to simulate an interrupt from software
* down below.
*/
XIntc_Out32(IntcBaseAddress + XIN_MER_OFFSET, XIN_INT_MASTER_ENABLE_MASK);
/*
* This step is processor specific, connect the handler for the
* interrupt controller to the interrupt source for the processor.
*/
SetupInterruptSystem();
/*
* Cause (simulate) an interrupt so the handler will be called. This is
* done by writing a 1 to the interrupt status bit for the device
* interrupt.
*/
XIntc_Out32(IntcBaseAddress + XIN_ISR_OFFSET, INTC_DEVICE_INT_MASK);
/*
* Wait for the interrupt to be processed, if the interrupt does not
* occur this loop will wait forever.
*/
while (1)
{
/*
* If the interrupt occurred which is indicated by the global
* variable which is set in the device driver handler, then
* stop waiting.
*/
if (InterruptProcessed) {
break;
}
}
return XST_SUCCESS;
}
/*****************************************************************************/
/**
*
* This function connects the interrupt handler of the interrupt controller to
* the processor. This function is seperate to allow it to be customized for
* each application. Each processor or RTOS may require unique processing to
* connect the interrupt handler.
*
* @param None.
*
* @return None.
*
* @note None.
*
******************************************************************************/
void SetupInterruptSystem()
{
/*
* Initialize the exception table.
*/
Xil_ExceptionInit();
/*
* Register the interrupt controller handler with the exception table.
*/
Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT,
(Xil_ExceptionHandler)XIntc_DeviceInterruptHandler,
INTC_DEVICE_ID);
/*
* Enable exceptions.
*/
Xil_ExceptionEnable();
}
/*****************************************************************************/
/**
*
* This function is designed to look like an interrupt handler in a device
* driver. This is typically a 2nd level handler that is called from the
* interrupt controller interrupt handler. This handler would typically
* perform device specific processing such as reading and writing the registers
* of the device to clear the interrupt condition and pass any data to an
* application using the device driver.
*
* @param CallbackRef is passed back to the device driver's interrupt
* handler by the XIntc driver. It was given to the XIntc driver
* in the XIntc_Connect() function call. It is typically a pointer
* to the device driver instance variable if using the Xilinx Level
* 1 device drivers. In this example, we do not care about the
* callback reference, so we passed it a 0 when connecting the
* handler to the XIntc driver and we make no use of it here.
*
* @return None.
*
* @note None.
*
******************************************************************************/
void DeviceDriverHandler(void *CallbackRef)
{
/*
* Indicate the interrupt has been processed using a shared variable.
*/
InterruptProcessed = TRUE;
}

View file

@ -0,0 +1,250 @@
/******************************************************************************
*
* Copyright (C) 2002 - 2014 Xilinx, Inc. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* Use of the Software is limited solely to applications:
* (a) running on a Xilinx device, or
* (b) that interact with a Xilinx device through a bus or interconnect.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Except as contained in this notice, the name of the Xilinx shall not be used
* in advertising or otherwise to promote the sale, use or other dealings in
* this Software without prior written authorization from Xilinx.
*
******************************************************************************/
/******************************************************************************/
/**
*
* @file xintc_tapp_example.c
*
* This file contains a self test example using the Interrupt Controller driver
* (XIntc) and hardware device. Please reference other device driver examples to
* see more examples of how the Intc and interrupts can be used by a software
* application.
*
* This example shows the use of the Interrupt Controller both with a PowerPC405
* and MicroBlaze processor.
*
* The TestApp Gen utility uses this file to perform the self test and setup
* of Intc for interrupts.
*
* @note
*
* None
*
* <pre>
*
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ---- -------- --------------------------------------------------------
* 1.00a sv 06/29/05 Created for Test App Integration
* 1.00c sn 05/09/06 Added Interrupt Setup Function
* 2.00a ktn 10/20/09 Updated to use HAL Processor APIs and minor changes as
* per coding guidelines.
* </pre>
******************************************************************************/
/***************************** Include Files *********************************/
#include "xparameters.h"
#include "xstatus.h"
#include "xintc.h"
#include "xil_exception.h"
/************************** Constant Definitions *****************************/
/*
* The following constants map to the XPAR parameters created in the
* xparameters.h file. They are defined here such that a user can easily
* change all the needed parameters in one place. This definition is not
* included if the example is generated from the TestAppGen test tool.
*/
#ifndef TESTAPP_GEN
#define INTC_DEVICE_ID XPAR_INTC_0_DEVICE_ID
#endif
/**************************** Type Definitions *******************************/
/***************** Macros (Inline Functions) Definitions *********************/
/************************** Function Prototypes ******************************/
int IntcSelfTestExample(u16 DeviceId);
int IntcInterruptSetup(XIntc *IntcInstancePtr, u16 DeviceId);
/************************** Variable Definitions *****************************/
static XIntc InterruptController; /* Instance of the Interrupt Controller */
/*****************************************************************************/
/**
*
* This is the main function for the Interrupt Controller example. This
* function is not included if the example is generated from the TestAppGen test
* tool.
*
* @param None.
*
* @return XST_SUCCESS to indicate success, otherwise XST_FAILURE.
*
* @note None.
*
******************************************************************************/
#ifndef TESTAPP_GEN
int main(void)
{
int Status;
/*
* Run the Intc example , specify the Device ID generated in
* xparameters.h.
*/
Status = IntcSelfTestExample(INTC_DEVICE_ID);
if (Status != XST_SUCCESS) {
return XST_FAILURE;
}
return XST_SUCCESS;
}
#endif
/*****************************************************************************/
/**
*
* This function runs a self-test on the driver/device. This is a destructive
* test. This function is an example of how to use the interrupt controller
* driver component (XIntc) and the hardware device. This function is designed
* to work without any hardware devices to cause interrupts. It may not return
* if the interrupt controller is not properly connected to the processor in
* either software or hardware.
*
* This function relies on the fact that the interrupt controller hardware
* has come out of the reset state such that it will allow interrupts to be
* simulated by the software.
*
* @param DeviceId is device ID of the Interrupt Controller Device,
* typically XPAR_<INTC_instance>_DEVICE_ID value from
* xparameters.h.
*
* @return XST_SUCCESS to indicate success, otherwise XST_FAILURE.
*
* @note None.
*
******************************************************************************/
int IntcSelfTestExample(u16 DeviceId)
{
int Status;
/*
* Initialize the interrupt controller driver so that it is ready to use.
*/
Status = XIntc_Initialize(&InterruptController, DeviceId);
if (Status != XST_SUCCESS) {
return XST_FAILURE;
}
/*
* Perform a self-test to ensure that the hardware was built correctly.
*/
Status = XIntc_SelfTest(&InterruptController);
if (Status != XST_SUCCESS) {
return XST_FAILURE;
}
return XST_SUCCESS;
}
/*****************************************************************************/
/**
*
* This function is used by the TestAppGen generated application to setup
* the interrupt controller.
*
* @param IntcInstancePtr is the reference to the Interrupt Controller
* instance.
* @param DeviceId is device ID of the Interrupt Controller Device,
* typically XPAR_<INTC_instance>_DEVICE_ID value from
* xparameters.h.
*
* @return XST_SUCCESS to indicate success, otherwise XST_FAILURE.
*
* @note None.
*
******************************************************************************/
int IntcInterruptSetup(XIntc *IntcInstancePtr, u16 DeviceId)
{
int Status;
/*
* Initialize the interrupt controller driver so that it is
* ready to use.
*/
Status = XIntc_Initialize(IntcInstancePtr, DeviceId);
if (Status != XST_SUCCESS) {
return XST_FAILURE;
}
/*
* Perform a self-test to ensure that the hardware was built correctly.
*/
Status = XIntc_SelfTest(IntcInstancePtr);
if (Status != XST_SUCCESS) {
return XST_FAILURE;
}
/*
* Initialize the exception table.
*/
Xil_ExceptionInit();
/*
* Register the interrupt controller handler with the exception table.
*/
Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT,
(Xil_ExceptionHandler)XIntc_DeviceInterruptHandler,
(void*) 0);
/*
* Enable exceptions.
*/
Xil_ExceptionEnable();
/*
* Start the interrupt controller such that interrupts are enabled for
* all devices that cause interrupts.
*/
Status = XIntc_Start(IntcInstancePtr, XIN_REAL_MODE);
if (Status != XST_SUCCESS) {
return XST_FAILURE;
}
return XST_SUCCESS;
}

View file

@ -0,0 +1,28 @@
COMPILER=
ARCHIVER=
CP=cp
COMPILER_FLAGS=
EXTRA_COMPILER_FLAGS=
LIB=libxil.a
LEVEL=0
RELEASEDIR=../../../lib
INCLUDEDIR=../../../include
INCLUDES=-I./. -I${INCLUDEDIR}
INCLUDEFILES=*.h
LIBSOURCES=*.c
OUTS = *.o
libs:
echo "Compiling intc"
$(COMPILER) $(COMPILER_FLAGS) $(EXTRA_COMPILER_FLAGS) $(INCLUDES) $(LIBSOURCES)
$(ARCHIVER) -r ${RELEASEDIR}/${LIB} ${OUTS}
make clean
include:
${CP} $(INCLUDEFILES) $(INCLUDEDIR)
clean:
rm -rf ${OUTS}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,366 @@
/******************************************************************************
*
* Copyright (C) 2002 - 2014 Xilinx, Inc. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* Use of the Software is limited solely to applications:
* (a) running on a Xilinx device, or
* (b) that interact with a Xilinx device through a bus or interconnect.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Except as contained in this notice, the name of the Xilinx shall not be used
* in advertising or otherwise to promote the sale, use or other dealings in
* this Software without prior written authorization from Xilinx.
*
******************************************************************************/
/*****************************************************************************/
/**
*
* @file xintc.h
*
* The Xilinx interrupt controller driver component. This component supports the
* Xilinx interrupt controller.
*
* The interrupt controller driver uses the idea of priority for the various
* handlers. Priority is an integer within the range of 0 and 31 inclusive with
* 0 being the highest priority interrupt source.
*
* The Xilinx interrupt controller supports the following features:
*
* - specific individual interrupt enabling/disabling
* - specific individual interrupt acknowledging
* - attaching specific callback function to handle interrupt source
* - master enable/disable
* - single callback per interrupt or all pending interrupts handled for
* each interrupt of the processor
*
* The acknowledgement of the interrupt within the interrupt controller is
* selectable, either prior to the device's handler being called or after
* the handler is called. This is necessary to support interrupt signal inputs
* which are either edge or level signals. Edge driven interrupt signals
* require that the interrupt is acknowledged prior to the interrupt being
* serviced in order to prevent the loss of interrupts which are occurring
* extremely close together. A level driven interrupt input signal requires
* the interrupt to acknowledged after servicing the interrupt to ensure that
* the interrupt only generates a single interrupt condition.
*
* Details about connecting the interrupt handler of the driver are contained
* in the source file specific to interrupt processing, xintc_intr.c.
*
* This driver is intended to be RTOS and processor independent. It works with
* physical addresses only. Any needs for dynamic memory management, threads
* or thread mutual exclusion, virtual memory, or cache control must be
* satisfied by the layer above this driver.
*
* <b>Interrupt Vector Tables</b>
*
* The interrupt vector table for each interrupt controller device is declared
* statically in xintc_g.c within the configuration data for each instance.
* The device ID of the interrupt controller device is used by the driver as a
* direct index into the configuration data table - to retrieve the vector table
* for an instance of the interrupt controller. The user should populate the
* vector table with handlers and callbacks at run-time using the XIntc_Connect()
* and XIntc_Disconnect() functions.
*
* Each vector table entry corresponds to a device that can generate an
* interrupt. Each entry contains an interrupt handler function and an argument
* to be passed to the handler when an interrupt occurs. The tools default this
* argument to the base address of the interrupting device. Note that the
* device driver interrupt handlers given in this file do not take a base
* address as an argument, but instead take a pointer to the driver instance.
* This means that although the table is created statically, the user must still
* use XIntc_Connect() when the interrupt handler takes an argument other than
* the base address. This is only to say that the existence of the static vector
* tables should not mislead the user into thinking they no longer need to
* register/connect interrupt handlers with this driver.
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ---- -------- -------------------------------------------------------
* 1.00a ecm 08/16/01 First release
* 1.00a rpm 01/09/02 Removed the AckLocation argument from XIntc_Connect().
* This information is now internal in xintc_g.c.
* 1.00b jhl 02/13/02 Repartitioned the driver for smaller files
* 1.00b jhl 04/24/02 Made LookupConfig function global and relocated config
* data type
* 1.00c rpm 10/17/03 New release. Support the static vector table created
* in the xintc_g.c configuration table. Moved vector
* table and options out of instance structure and into
* the configuration table.
* 1.10c mta 03/21/07 Updated to new coding style
* 1.11a sv 11/21/07 Updated driver to support access through a DCR bridge
* 2.00a ktn 10/20/09 Updated to use HAL Processor APIs and _m is removed from
* all the macro names/definitions.
* 2.01a sdm 04/27/10 Updated the tcl so that the defintions are generated in
* the xparameters.h to know whether the optional registers
* SIE, CIE and IVR are enabled in the HW - Refer CR 555392.
* This driver doesnot make use of these definitions and does
* not use the optional registers.
* 2.03a hvm 05/24/11 Updated the tcl to generate vector Ids for external
* interrupts. CR565336
* 2.04a bss 01/13/12 Added XIntc_ConnectFastHandler API for Fast Interrupt
* and XIntc_SetNormalIntrMode for setting to normal
* interrupt mode.
* 2.04a asa 03/19/12 Changed the XIntc_Config struct. The order of entries
* declared in the structure now matches with the
* XIntc_ConfigTable generated by the driver tcl.
* 2.05a bss 08/16/12 Updated to support relocatable vectors in Microblaze,
* added IntVectorAddr to XIntc_Config for this.
* Added XIntc_RegisterFastHandler API to register fast
* interrupt handlers using base address.
* 2.06a bss 01/28/13 To support Cascade mode:
* Added XIN_INTC_NOCASCADE,XIN_INTC_PRIMARY,
* XIN_INTC_SECONDARY,XIN_INTC_LAST and
* XIN_CONTROLLER_MAX_INTRS macros
* Added NumberofIntrs and IntcType fields in XIntc_Config
* structure.
* Modified XIntc_Initialize,XIntc_Start,XIntc_Connect
* XIntc_Disconnect,XIntc_Enable,XIntc_Disable,
* XIntc_Acknowledge,XIntc_ConnectFastHandler and
* XIntc_SetNormalIntrMode APIs.Added XIntc_InitializeSlaves
* API in xintc.c
* Modified XIntc_DeviceInterruptHandler,
* XIntc_SetIntrSvcOption,XIntc_RegisterHandler and
* XIntc_RegisterFastHandler APIs.Added XIntc_CascadeHandler
* API in xintc_l.c.
* Modified XIntc_SetOptions API in xintc_options.c.
* Modified XIntc_SimulateIntr API in xintc_selftest.c.
* Modified driver tcl:
* to check for Cascade mode and generate XPAR_INTC_TYPE
* for each controller.
* Generate XPAR_INTC_MAX_NUM_INTR_INPUTS by adding all
* interrupt sources of all Controllers in Cascade mode.
* 2.07a bss 10/18/13 To support Nested interrupts:
* Modified XIntc_DeviceInterruptHandler API.
* Added XIN_ILR_OFFSET macro in xintc_l.h.
* Modified driver tcl to generate HAS_ILR parameter in
* xparameters.h
* 3.0 bss 01/28/13 Modified xintc.c to initialize IVAR register with
* XPAR_MICROBLAZE_BASE_VECTORS + 0x10 to fix
* CR#765931.
* Modified driver tcl to generate XPAR_AXI_INTC_0_TYPE
* correctly(CR#764865).
*
* @note
* For Cascade mode, Interrupt IDs are generated in xparameters.h
* as shown below:
*
* Master/Primary INTC
* ______
* | |-0 Secondary INTC
* | |-. ______
* | |-. | |-32 Last INTC
* | |-. | |-. ______
* |______|<-31------| |-. | |-64
* | |-. | |-.
* |______|<-63-------| |-.
* | |-.
* |______|-95
*
* All driver functions has to be called using DeviceId/
* InstancePtr/BaseAddress of Primary/Master Controller and
* Interrupts IDs generated in xparameters.h only.
* Driver functions takes care of Slave Controllers based on
* Interrupt ID passed. User must not use Interrupt source/ID
* 31 of Primary and Secondary controllers to call driver
* functions.
*
* For nested interrupts, XIntc_DeviceInterruptHandler saves
* microblaze r14 register on entry and restores on exit. This is
* required since compiler does not support nesting. It enables
* Microblaze interrupts after blocking further interrupts from
* the current interrupt number and interrupts below current
* interrupt proirity by writing to Interrupt Level Register of
* INTC on entry. On exit, it disables microblaze interrupts and
* restores ILR register default value(0xFFFFFFFF)back. It is
* recommended to increase STACK_SIZE in linker script for nested
* interrupts.
* 3.0 adk 12/10/13 Updated as per the New Tcl API's
* 3.0 adk 17/02/14 Fixed the CR:771287 Changes are made in the intc
* driver tcl.
* 3.1 adk 8/4/14 Fixed the CR:783248 Changes are made in
* the test-app tcl
* 3.2 bss 4/8/14 Fixed driver tcl to handle external interrupt pins
* correctly (CR#799609).
* 3.3 adk 11/3/14 added generation of C_HAS_ILR parameter to
* xparameters.h.Changes are made in the driver tcl file
* (CR#828046).
*
* </pre>
*
******************************************************************************/
#ifndef XINTC_H /* prevent circular inclusions */
#define XINTC_H /* by using protection macros */
#ifdef __cplusplus
extern "C" {
#endif
/***************************** Include Files *********************************/
#include "xil_types.h"
#include "xil_assert.h"
#include "xparameters.h"
#include "xstatus.h"
#include "xintc_l.h"
/************************** Constant Definitions *****************************/
/**
* @name Configuration options
* These options are used in XIntc_SetOptions() to configure the device.
* @{
*/
/**
* <pre>
* XIN_SVC_SGL_ISR_OPTION Service the highest priority pending interrupt
* and then return.
* XIN_SVC_ALL_ISRS_OPTION Service all of the pending interrupts and then
* return.
* </pre>
*/
#define XIN_SVC_SGL_ISR_OPTION 1UL
#define XIN_SVC_ALL_ISRS_OPTION 2UL
/*@}*/
/**
* @name Start modes
* One of these values is passed to XIntc_Start() to start the device.
* @{
*/
/** Simulation only mode, no hardware interrupts recognized */
#define XIN_SIMULATION_MODE 0
/** Real mode, no simulation allowed, hardware interrupts recognized */
#define XIN_REAL_MODE 1
/*@}*/
/**
* @name Masks to specify Interrupt Controller Mode
* @{
*/
#define XIN_INTC_NOCASCADE 0 /* Normal - No Cascade Mode */
#define XIN_INTC_PRIMARY 1 /* Master/Primary controller */
#define XIN_INTC_SECONDARY 2 /* Secondary Slave Controllers */
#define XIN_INTC_LAST 3 /* Last Slave Controller */
/*@}*/
/**
* @name Mask to specify maximum number of interrupt sources per controller
* @{
*/
#define XIN_CONTROLLER_MAX_INTRS 32 /* Each Controller has 32
interrupt pins */
/*@}*/
/**************************** Type Definitions *******************************/
/**
* This typedef contains configuration information for the device.
*/
typedef struct {
u16 DeviceId; /**< Unique ID of device */
u32 BaseAddress; /**< Register base address */
u32 AckBeforeService; /**< Ack location per interrupt */
int FastIntr; /**< Fast Interrupt enabled */
u32 IntVectorAddr; /**< Interrupt Vector Address */
int NumberofIntrs; /**< Number of Interrupt sources */
u32 Options; /**< Device options */
int IntcType; /**< Intc type 0 - No Cascade Mode
1 - primary instance
2 - secondary instance
3 - last instance */
/** Static vector table of interrupt handlers */
#if XPAR_INTC_0_INTC_TYPE != XIN_INTC_NOCASCADE
XIntc_VectorTableEntry HandlerTable[XIN_CONTROLLER_MAX_INTRS];
#else
XIntc_VectorTableEntry HandlerTable[XPAR_INTC_MAX_NUM_INTR_INPUTS];
#endif
} XIntc_Config;
/**
* The XIntc driver instance data. The user is required to allocate a
* variable of this type for every intc device in the system. A pointer
* to a variable of this type is then passed to the driver API functions.
*/
typedef struct {
u32 BaseAddress; /**< Base address of registers */
u32 IsReady; /**< Device is initialized and ready */
u32 IsStarted; /**< Device has been started */
u32 UnhandledInterrupts; /**< Intc Statistics */
XIntc_Config *CfgPtr; /**< Pointer to instance config entry */
} XIntc;
/***************** Macros (Inline Functions) Definitions *********************/
/************************** Function Prototypes ******************************/
/*
* Required functions in xintc.c
*/
int XIntc_Initialize(XIntc * InstancePtr, u16 DeviceId);
int XIntc_Start(XIntc * InstancePtr, u8 Mode);
void XIntc_Stop(XIntc * InstancePtr);
int XIntc_Connect(XIntc * InstancePtr, u8 Id,
XInterruptHandler Handler, void *CallBackRef);
void XIntc_Disconnect(XIntc * InstancePtr, u8 Id);
void XIntc_Enable(XIntc * InstancePtr, u8 Id);
void XIntc_Disable(XIntc * InstancePtr, u8 Id);
void XIntc_Acknowledge(XIntc * InstancePtr, u8 Id);
XIntc_Config *XIntc_LookupConfig(u16 DeviceId);
int XIntc_ConnectFastHandler(XIntc *InstancePtr, u8 Id,
XFastInterruptHandler Handler);
void XIntc_SetNormalIntrMode(XIntc *InstancePtr, u8 Id);
/*
* Interrupt functions in xintr_intr.c
*/
void XIntc_VoidInterruptHandler(void);
void XIntc_InterruptHandler(XIntc * InstancePtr);
/*
* Options functions in xintc_options.c
*/
int XIntc_SetOptions(XIntc * InstancePtr, u32 Options);
u32 XIntc_GetOptions(XIntc * InstancePtr);
/*
* Self-test functions in xintc_selftest.c
*/
int XIntc_SelfTest(XIntc * InstancePtr);
int XIntc_SimulateIntr(XIntc * InstancePtr, u8 Id);
#ifdef __cplusplus
}
#endif
#endif /* end of protection macro */

View file

@ -0,0 +1,112 @@
/******************************************************************************
*
* Copyright (C) 2002 - 2014 Xilinx, Inc. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* Use of the Software is limited solely to applications:
* (a) running on a Xilinx device, or
* (b) that interact with a Xilinx device through a bus or interconnect.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Except as contained in this notice, the name of the Xilinx shall not be used
* in advertising or otherwise to promote the sale, use or other dealings in
* this Software without prior written authorization from Xilinx.
*
******************************************************************************/
/*****************************************************************************/
/**
*
* @file xintc_g.c
*
* This file contains a configuration table that specifies the configuration of
* interrupt controller devices in the system.
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ---- -------- -----------------------------------------------
* 1.00a rpm 01/09/02 First release
* 1.00b jhl 02/21/02 Repartitioned the driver for smaller files
* 1.00b jhl 04/24/02 Compressed the ack table into a bit mask.
* 1.00c rpm 10/17/03 New release. Support the static vector table created
* in the xintc_g.c configuration table.
* 1.10c mta 03/21/07 Updated to new coding style
* </pre>
*
* @internal
*
* This configuration table contains entries that are modified at runtime
* by the driver. The EDK tools populate the table with default values for the
* vector table and the options flag. These default values can be, and are,
* overwritten at runtime by the driver. This is a deviation from most drivers'
* configuration tables in that most are created statically by the tools and
* are never modified during runtime. Most tables reflect only the hardware
* configuration of the device. This Intc configuration table contains software
* information in addition to hardware configuration. The Intc configuration
* table should be considered an exception to the usage of the configuration
* table rather than the norm.
*
******************************************************************************/
/***************************** Include Files *********************************/
#include "xintc.h"
#include "xparameters.h"
/************************** Constant Definitions *****************************/
/**************************** Type Definitions *******************************/
/***************** Macros (Inline Functions) Definitions *********************/
/************************** Function Prototypes ******************************/
/************************** Variable Prototypes ******************************/
/**
* This table contains configuration information for each intc device
* in the system. The XIntc driver must know when to acknowledge the interrupt.
* The entry which specifies this as a bit mask where each bit corresponds to
* a specific interrupt. A bit set indicates to ack it before servicing it.
* Generally, acknowledge before service is used when the interrupt signal is
* edge-sensitive, and after when the signal is level-sensitive.
*
* Refer to the XIntc_Config data structure in xintc.h for details on how this
* table should be initialized.
*/
XIntc_Config XIntc_ConfigTable[XPAR_XINTC_NUM_INSTANCES] = {
{
XPAR_INTC_0_DEVICE_ID, /* Unique ID of device */
XPAR_INTC_0_BASEADDR, /* Register base address */
XPAR_INTC_0_ACK_BEFORE, /* Ack before or after service */
0 /* Device options */
}
,
{
XPAR_INTC_1_DEVICE_ID, /* Unique ID of device */
XPAR_INTC_1_BASEADDR, /* Register base address */
XPAR_INTC_1_ACK_BEFORE, /* Ack before or after service */
0 /* Device options */
}
};

View file

@ -0,0 +1,90 @@
/******************************************************************************
*
* Copyright (C) 2002 - 2014 Xilinx, Inc. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* Use of the Software is limited solely to applications:
* (a) running on a Xilinx device, or
* (b) that interact with a Xilinx device through a bus or interconnect.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Except as contained in this notice, the name of the Xilinx shall not be used
* in advertising or otherwise to promote the sale, use or other dealings in
* this Software without prior written authorization from Xilinx.
*
******************************************************************************/
/*****************************************************************************/
/**
*
* @file xintc_i.h
*
* This file contains data which is shared between files and internal to the
* XIntc component. It is intended for internal use only.
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ---- -------- -------------------------------------------------------
* 1.00b jhl 02/06/02 First release
* 1.00b jhl 04/24/02 Moved register definitions to xintc_l.h
* 1.00c rpm 10/17/03 New release. Removed extern of global, single instance
* pointer.
* 1.10c mta 03/21/07 Updated to new coding style
* 2.00a ktn 10/20/09 Updated to use HAL Processor APIs.
* </pre>
*
******************************************************************************/
#ifndef XINTC_I_H /* prevent circular inclusions */
#define XINTC_I_H /* by using protection macros */
#ifdef __cplusplus
extern "C" {
#endif
/***************************** Include Files *********************************/
#include "xil_types.h"
#include "xil_assert.h"
#include "xintc.h"
/************************** Constant Definitions *****************************/
/**************************** Type Definitions *******************************/
/***************** Macros (Inline Functions) Definitions *********************/
/************************** Function Prototypes ******************************/
/************************** Variable Definitions *****************************/
extern u32 XIntc_BitPosMask[];
extern XIntc_Config XIntc_ConfigTable[];
#ifdef __cplusplus
}
#endif
#endif

View file

@ -0,0 +1,173 @@
/******************************************************************************
*
* Copyright (C) 2002 - 2014 Xilinx, Inc. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* Use of the Software is limited solely to applications:
* (a) running on a Xilinx device, or
* (b) that interact with a Xilinx device through a bus or interconnect.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Except as contained in this notice, the name of the Xilinx shall not be used
* in advertising or otherwise to promote the sale, use or other dealings in
* this Software without prior written authorization from Xilinx.
*
******************************************************************************/
/*****************************************************************************/
/**
*
* @file xintc_intr.c
*
* This file contains the interrupt processing for the XIntc component which
* is the driver for the Xilinx Interrupt Controller. The interrupt
* processing is partitioned seperately such that users are not required to
* use the provided interrupt processing. This file requires other files of
* the driver to be linked in also.
*
* Two different interrupt handlers are provided for this driver such that the
* user must select the appropriate handler for the application. The first
* interrupt handler, XIntc_VoidInterruptHandler, is provided for systems
* which use only a single interrupt controller or for systems that cannot
* otherwise provide an argument to the XIntc interrupt handler (e.g., the RTOS
* interrupt vector handler may not provide such a facility). The constant
* XPAR_INTC_SINGLE_DEVICE_ID must be defined for this handler to be included in
* the driver. The second interrupt handler, XIntc_InterruptHandler, uses an
* input argument which is an instance pointer to an interrupt controller driver
* such that multiple interrupt controllers can be supported. This handler
* requires the calling function to pass it the appropriate argument, so another
* level of indirection may be required.
*
* Note that both of these handlers are now only provided for backward
* compatibility. The handler defined in xintc_l.c is the recommended handler.
*
* The interrupt processing may be used by connecting one of the interrupt
* handlers to the interrupt system. These handlers do not save and restore
* the processor context but only handle the processing of the Interrupt
* Controller. The two handlers are provided as working examples. The user is
* encouraged to supply their own interrupt handler when performance tuning is
* deemed necessary.
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ---- -------- ---------------------------------------------------------
* 1.00b jhl 02/13/02 First release
* 1.00c rpm 10/17/03 New release. Support the static vector table created
* in the xintc_g.c configuration table. Collapse handlers
* to use the XIntc_DeviceInterruptHandler() in xintc_l.c.
* 1.00c rpm 04/09/04 Added conditional compilation around the old handler
* XIntc_VoidInterruptHandler(). This handler will only be
* include/compiled if XPAR_INTC_SINGLE_DEVICE_ID is defined.
* 1.10c mta 03/21/07 Updated to new coding style
* 2.00a ktn 10/20/09 Updated to use HAL Processor APIs.
*
* </pre>
*
* @internal
*
* This driver assumes that the context of the processor has been saved prior to
* the calling of the Interrupt Controller interrupt handler and then restored
* after the handler returns. This requires either the running RTOS to save the
* state of the machine or that a wrapper be used as the destination of the
* interrupt vector to save the state of the processor and restore the state
* after the interrupt handler returns.
*
******************************************************************************/
/***************************** Include Files *********************************/
#include "xil_types.h"
#include "xil_assert.h"
#include "xparameters.h"
#include "xintc.h"
/************************** Constant Definitions *****************************/
/**************************** Type Definitions *******************************/
/***************** Macros (Inline Functions) Definitions *********************/
/************************** Function Prototypes ******************************/
/************************** Variable Definitions *****************************/
/*****************************************************************************/
/**
*
* Interrupt handler for the driver used when there can be no argument passed
* to the handler. This function is provided mostly for backward compatibility.
* The user should use XIntc_DeviceInterruptHandler(), defined in xintc_l.c,
* if possible.
*
* The user must connect this function to the interrupt system such that it is
* called whenever the devices which are connected to it cause an interrupt.
*
* @return None.
*
* @note
*
* The constant XPAR_INTC_SINGLE_DEVICE_ID must be defined for this handler
* to be included in the driver compilation.
*
******************************************************************************/
#ifdef XPAR_INTC_SINGLE_DEVICE_ID
void XIntc_VoidInterruptHandler(void)
{
/* Use the single instance to call the main interrupt handler */
XIntc_DeviceInterruptHandler((void *) XPAR_INTC_SINGLE_DEVICE_ID);
}
#endif
/*****************************************************************************/
/**
*
* The interrupt handler for the driver. This function is provided mostly for
* backward compatibility. The user should use XIntc_DeviceInterruptHandler(),
* defined in xintc_l.c when possible and pass the device ID of the interrupt
* controller device as its argument.
*
* The user must connect this function to the interrupt system such that it is
* called whenever the devices which are connected to it cause an interrupt.
*
* @param InstancePtr is a pointer to the XIntc instance to be worked on.
*
* @return None.
*
* @note None.
*
******************************************************************************/
void XIntc_InterruptHandler(XIntc * InstancePtr)
{
/* Assert that the pointer to the instance is valid
*/
Xil_AssertVoid(InstancePtr != NULL);
/* Use the instance's device ID to call the main interrupt handler.
* (the casts are to avoid a compiler warning)
*/
XIntc_DeviceInterruptHandler((void *)
((u32) (InstancePtr->CfgPtr->DeviceId)));
}

View file

@ -0,0 +1,662 @@
/******************************************************************************
*
* Copyright (C) 2002 - 2014 Xilinx, Inc. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* Use of the Software is limited solely to applications:
* (a) running on a Xilinx device, or
* (b) that interact with a Xilinx device through a bus or interconnect.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Except as contained in this notice, the name of the Xilinx shall not be used
* in advertising or otherwise to promote the sale, use or other dealings in
* this Software without prior written authorization from Xilinx.
*
******************************************************************************/
/*****************************************************************************/
/**
*
* @file xintc_l.c
*
* This file contains low-level driver functions that can be used to access the
* device. The user should refer to the hardware device specification for more
* details of the device operation.
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ---- -------- -------------------------------------------------------
* 1.00b jhl 04/24/02 First release
* 1.00c rpm 10/17/03 New release. Support the static vector table created
* in the xintc_g.c configuration table.
* 1.00c rpm 04/09/04 Added conditional compilation around the old handler
* XIntc_LowLevelInterruptHandler(). This handler will only
* be include/compiled if XPAR_INTC_SINGLE_DEVICE_ID is
* defined.
* 1.10c mta 03/21/07 Updated to new coding style
* 1.10c ecm 07/09/07 Read the ISR after the Acknowledge in the interrupt
* handler to support architectures with posted write bus
* access issues.
* 2.00a ktn 10/20/09 Updated to use HAL Processor APIs and _m is removed
* from all the macro definitions.
* 2.04a bss 01/13/12 Removed the unused Register variable for warnings.
* 2.05a bss 08/18/12 Added XIntc_RegisterFastHandler API to register fast
* interrupt handlers using base address.
* 2.06a bss 01/28/13 To support Cascade mode:
* Modified XIntc_DeviceInterruptHandler,
* XIntc_SetIntrSvcOption,XIntc_RegisterHandler and
* XIntc_RegisterFastHandler APIs.
* Added XIntc_CascadeHandler API.
* 2.07a bss 10/18/13 Modified XIntc_DeviceInterruptHandler to support
* nested interrupts.
*
* </pre>
*
******************************************************************************/
/***************************** Include Files *********************************/
#include "xparameters.h"
#include "xil_types.h"
#include "xil_assert.h"
#include "xintc.h"
#include "xintc_i.h"
/************************** Constant Definitions *****************************/
/**************************** Type Definitions *******************************/
/***************** Macros (Inline Functions) Definitions *********************/
/************************** Function Prototypes ******************************/
static XIntc_Config *LookupConfigByBaseAddress(u32 BaseAddress);
#if XPAR_INTC_0_INTC_TYPE != XIN_INTC_NOCASCADE
static void XIntc_CascadeHandler(void *DeviceId);
#endif
/************************** Variable Definitions *****************************/
/*****************************************************************************/
/**
*
* This is the interrupt handler for the driver interface provided in this file
* when there can be no argument passed to the handler. In this case, we just
* use the globally defined device ID for the interrupt controller. This function
* is provided mostly for backward compatibility. The user should use
* XIntc_DeviceInterruptHandler() if possible.
*
* This function does not support multiple interrupt controller instances to be
* handled.
*
* The user must connect this function to the interrupt system such that it is
* called whenever the devices which are connected to it cause an interrupt.
*
* @return None.
*
* @note
*
* The constant XPAR_INTC_SINGLE_DEVICE_ID must be defined for this handler
* to be included in the driver compilation.
*
******************************************************************************/
#ifdef XPAR_INTC_SINGLE_DEVICE_ID
void XIntc_LowLevelInterruptHandler(void)
{
/*
* A level of indirection here because the interrupt handler used with
* the driver interface given in this file needs to remain void - no
* arguments. So we need the globally defined device ID of THE
* interrupt controller.
*/
XIntc_DeviceInterruptHandler((void *) XPAR_INTC_SINGLE_DEVICE_ID);
}
#endif
/*****************************************************************************/
/**
*
* This function is the primary interrupt handler for the driver. It must be
* connected to the interrupt source such that is called when an interrupt of
* the interrupt controller is active. It will resolve which interrupts are
* active and enabled and call the appropriate interrupt handler. It uses
* the AckBeforeService flag in the configuration data to determine when to
* acknowledge the interrupt. Highest priority interrupts are serviced first.
* This function assumes that an interrupt vector table has been previously
* initialized.It does not verify that entries in the table are valid before
* calling an interrupt handler. In Cascade mode this function calls
* XIntc_CascadeHandler to handle interrupts of Master and Slave controllers.
* This functions also handles interrupts nesting by saving and restoring link
* register of Microblaze and Interrupt Level register of interrupt controller
* properly.
* @param DeviceId is the zero-based device ID defined in xparameters.h
* of the interrupting interrupt controller. It is used as a direct
* index into the configuration data, which contains the vector
* table for the interrupt controller. Note that even though the
* argument is a void pointer, the value is not a pointer but the
* actual device ID. The void pointer type is necessary to meet
* the XInterruptHandler typedef for interrupt handlers.
*
* @return None.
*
* @note For nested interrupts, this function saves microblaze r14
* register on entry and restores on exit. This is required since
* compiler does not support nesting. This function enables
* Microblaze interrupts after blocking further interrupts
* from the current interrupt number and interrupts below current
* interrupt proirity by writing to Interrupt Level Register of
* INTC on entry. On exit, it disables microblaze interrupts and
* restores ILR register default value(0xFFFFFFFF)back. It is
* recommended to increase STACK_SIZE in linker script for nested
* interrupts.
*
******************************************************************************/
void XIntc_DeviceInterruptHandler(void *DeviceId)
{
u32 IntrStatus;
u32 IntrMask = 1;
int IntrNumber;
XIntc_Config *CfgPtr;
u32 Imr;
/* Get the configuration data using the device ID */
CfgPtr = &XIntc_ConfigTable[(u32)DeviceId];
#if XPAR_INTC_0_INTC_TYPE != XIN_INTC_NOCASCADE
if (CfgPtr->IntcType != XIN_INTC_NOCASCADE) {
XIntc_CascadeHandler(DeviceId);
}
else
#endif
{ /* This extra brace is required for compilation in Cascade Mode */
#if XPAR_XINTC_HAS_ILR == TRUE
#ifdef __MICROBLAZE__
volatile u32 R14_register;
/* Save r14 register */
R14_register = mfgpr(r14);
#endif
volatile u32 ILR_reg;
/* Save ILR register */
ILR_reg = Xil_In32(CfgPtr->BaseAddress + XIN_ILR_OFFSET);
#endif
/* Get the interrupts that are waiting to be serviced */
IntrStatus = XIntc_GetIntrStatus(CfgPtr->BaseAddress);
/* Mask the Fast Interrupts */
if (CfgPtr->FastIntr == TRUE) {
Imr = XIntc_In32(CfgPtr->BaseAddress + XIN_IMR_OFFSET);
IntrStatus &= ~Imr;
}
/* Service each interrupt that is active and enabled by
* checking each bit in the register from LSB to MSB which
* corresponds to an interrupt input signal
*/
for (IntrNumber = 0; IntrNumber < CfgPtr->NumberofIntrs;
IntrNumber++) {
if (IntrStatus & 1) {
XIntc_VectorTableEntry *TablePtr;
#if XPAR_XINTC_HAS_ILR == TRUE
/* Write to ILR the current interrupt
* number
*/
Xil_Out32(CfgPtr->BaseAddress +
XIN_ILR_OFFSET, IntrNumber);
/* Read back ILR to ensure the value
* has been updated and it is safe to
* enable interrupts
*/
Xil_In32(CfgPtr->BaseAddress +
XIN_ILR_OFFSET);
/* Enable interrupts */
Xil_ExceptionEnable();
#endif
/* If the interrupt has been setup to
* acknowledge it before servicing the
* interrupt, then ack it */
if (CfgPtr->AckBeforeService & IntrMask) {
XIntc_AckIntr(CfgPtr->BaseAddress,
IntrMask);
}
/* The interrupt is active and enabled, call
* the interrupt handler that was setup with
* the specified parameter
*/
TablePtr = &(CfgPtr->HandlerTable[IntrNumber]);
TablePtr->Handler(TablePtr->CallBackRef);
/* If the interrupt has been setup to
* acknowledge it after it has been serviced
* then ack it
*/
if ((CfgPtr->AckBeforeService &
IntrMask) == 0) {
XIntc_AckIntr(CfgPtr->BaseAddress,
IntrMask);
}
#if XPAR_XINTC_HAS_ILR == TRUE
/* Disable interrupts */
Xil_ExceptionDisable();
/* Restore ILR */
Xil_Out32(CfgPtr->BaseAddress + XIN_ILR_OFFSET,
ILR_reg);
#endif
/*
* Read the ISR again to handle architectures
* with posted write bus access issues.
*/
XIntc_GetIntrStatus(CfgPtr->BaseAddress);
/*
* If only the highest priority interrupt is to
* be serviced, exit loop and return after
* servicing
* the interrupt
*/
if (CfgPtr->Options == XIN_SVC_SGL_ISR_OPTION) {
#if XPAR_XINTC_HAS_ILR == TRUE
#ifdef __MICROBLAZE__
/* Restore r14 */
mtgpr(r14, R14_register);
#endif
#endif
return;
}
}
/* Move to the next interrupt to check */
IntrMask <<= 1;
IntrStatus >>= 1;
/* If there are no other bits set indicating that all
* interrupts have been serviced, then exit the loop
*/
if (IntrStatus == 0) {
break;
}
}
#if XPAR_XINTC_HAS_ILR == TRUE
#ifdef __MICROBLAZE__
/* Restore r14 */
mtgpr(r14, R14_register);
#endif
#endif
}
}
/*****************************************************************************/
/**
*
* Set the interrupt service option, which can configure the driver so that it
* services only a single interrupt at a time when an interrupt occurs, or
* services all pending interrupts when an interrupt occurs. The default
* behavior when using the driver interface given in xintc.h file is to service
* only a single interrupt, whereas the default behavior when using the driver
* interface given in this file is to service all outstanding interrupts when an
* interrupt occurs. In Cascade mode same Option is set to Slave controllers.
*
* @param BaseAddress is the unique identifier for a device.
* @param Option is XIN_SVC_SGL_ISR_OPTION if you want only a single
* interrupt serviced when an interrupt occurs, or
* XIN_SVC_ALL_ISRS_OPTION if you want all pending interrupts
* serviced when an interrupt occurs.
*
* @return None.
*
* @note
*
* Note that this function has no effect if the input base address is invalid.
*
******************************************************************************/
void XIntc_SetIntrSvcOption(u32 BaseAddress, int Option)
{
XIntc_Config *CfgPtr;
CfgPtr = LookupConfigByBaseAddress(BaseAddress);
if (CfgPtr != NULL) {
CfgPtr->Options = Option;
/* If Cascade mode set the option for all Slaves */
if (CfgPtr->IntcType != XIN_INTC_NOCASCADE) {
int Index;
for (Index = 1; Index <= XPAR_XINTC_NUM_INSTANCES - 1;
Index++) {
CfgPtr = XIntc_LookupConfig(Index);
CfgPtr->Options = Option;
}
}
}
}
/*****************************************************************************/
/**
*
* Register a handler function for a specific interrupt ID. The vector table
* of the interrupt controller is updated, overwriting any previous handler.
* The handler function will be called when an interrupt occurs for the given
* interrupt ID.
*
* This function can also be used to remove a handler from the vector table
* by passing in the XIntc_DefaultHandler() as the handler and NULL as the
* callback reference.
* In Cascade mode Interrupt Id is used to set Handler for corresponding Slave
* Controller
*
* @param BaseAddress is the base address of the interrupt controller
* whose vector table will be modified.
* @param InterruptId is the interrupt ID to be associated with the input
* handler.
* @param Handler is the function pointer that will be added to
* the vector table for the given interrupt ID.
* @param CallBackRef is the argument that will be passed to the new
* handler function when it is called. This is user-specific.
*
* @return None.
*
* @note
*
* Note that this function has no effect if the input base address is invalid.
*
******************************************************************************/
void XIntc_RegisterHandler(u32 BaseAddress, int InterruptId,
XInterruptHandler Handler, void *CallBackRef)
{
XIntc_Config *CfgPtr;
CfgPtr = LookupConfigByBaseAddress(BaseAddress);
if (CfgPtr != NULL) {
if (InterruptId > 31) {
CfgPtr = XIntc_LookupConfig(InterruptId/32);
CfgPtr->HandlerTable[InterruptId%32].Handler = Handler;
CfgPtr->HandlerTable[InterruptId%32].CallBackRef =
CallBackRef;
}
else {
CfgPtr->HandlerTable[InterruptId].Handler = Handler;
CfgPtr->HandlerTable[InterruptId].CallBackRef =
CallBackRef;
}
}
}
/*****************************************************************************/
/**
*
* Looks up the device configuration based on the base address of the device.
* A table contains the configuration info for each device in the system.
*
* @param BaseAddress is the unique identifier for a device.
*
* @return
*
* A pointer to the configuration structure for the specified device, or
* NULL if the device was not found.
*
* @note None.
*
******************************************************************************/
static XIntc_Config *LookupConfigByBaseAddress(u32 BaseAddress)
{
XIntc_Config *CfgPtr = NULL;
int Index;
for (Index = 0; Index < XPAR_XINTC_NUM_INSTANCES; Index++) {
if (XIntc_ConfigTable[Index].BaseAddress == BaseAddress) {
CfgPtr = &XIntc_ConfigTable[Index];
break;
}
}
return CfgPtr;
}
/*****************************************************************************/
/**
*
* Register a fast handler function for a specific interrupt ID. The handler
* function will be called when an interrupt occurs for the given interrupt ID.
* In Cascade mode Interrupt Id is used to set Handler for corresponding Slave
* Controller
*
* @param BaseAddress is the base address of the interrupt controller
* whose vector table will be modified.
* @param InterruptId is the interrupt ID to be associated with the input
* handler.
* @param FastHandler is the function pointer that will be called when
* interrupt occurs
*
* @return None.
*
* @note
*
* Note that this function has no effect if the input base address is invalid.
*
******************************************************************************/
void XIntc_RegisterFastHandler(u32 BaseAddress, u8 Id,
XFastInterruptHandler FastHandler)
{
u32 CurrentIER;
u32 Mask;
u32 Imr;
XIntc_Config *CfgPtr;
if (Id > 31) {
/* Enable user required Id in Slave controller */
CfgPtr = XIntc_LookupConfig(Id/32);
/* Get the Enabled Interrupts */
CurrentIER = XIntc_In32(CfgPtr->BaseAddress + XIN_IER_OFFSET);
/* Convert from integer id to bit mask */
Mask = XIntc_BitPosMask[(Id%32)];
/* Disable the Interrupt if it was enabled before calling
* this function
*/
if (CurrentIER & Mask) {
XIntc_Out32(CfgPtr->BaseAddress + XIN_IER_OFFSET,
(CurrentIER & ~Mask));
}
XIntc_Out32(CfgPtr->BaseAddress + XIN_IVAR_OFFSET +
((Id%32) * 4), (u32) FastHandler);
/* Slave controllers in Cascade Mode should have all as Fast
* interrupts or Normal interrupts, mixed interrupts are not
* supported
*/
XIntc_Out32(CfgPtr->BaseAddress + XIN_IMR_OFFSET, 0xFFFFFFFF);
/* Enable the Interrupt if it was enabled before calling this
* function
*/
if (CurrentIER & Mask) {
XIntc_Out32(CfgPtr->BaseAddress + XIN_IER_OFFSET,
(CurrentIER | Mask));
}
}
else {
CurrentIER = XIntc_In32(BaseAddress + XIN_IER_OFFSET);
/* Convert from integer id to bit mask */
Mask = XIntc_BitPosMask[Id];
if (CurrentIER & Mask) {
/* Disable Interrupt if it was enabled */
CurrentIER = XIntc_In32(BaseAddress + XIN_IER_OFFSET);
XIntc_Out32(BaseAddress + XIN_IER_OFFSET,
(CurrentIER & ~Mask));
}
XIntc_Out32(BaseAddress + XIN_IVAR_OFFSET + (Id * 4),
(u32) FastHandler);
Imr = XIntc_In32(BaseAddress + XIN_IMR_OFFSET);
XIntc_Out32(BaseAddress + XIN_IMR_OFFSET, Imr | Mask);
/* Enable Interrupt if it was enabled before calling
* this function
*/
if (CurrentIER & Mask) {
CurrentIER = XIntc_In32(BaseAddress + XIN_IER_OFFSET);
XIntc_Out32(BaseAddress + XIN_IER_OFFSET,
(CurrentIER | Mask));
}
}
}
#if XPAR_INTC_0_INTC_TYPE != XIN_INTC_NOCASCADE
/*****************************************************************************/
/**
*
* This function is called by primary interrupt handler for the driver to handle
* all Controllers in Cascade mode.It will resolve which interrupts are active
* and enabled and call the appropriate interrupt handler. It uses the
* AckBeforeService flag in the configuration data to determine when to
* acknowledge the interrupt. Highest priority interrupts are serviced first.
* This function assumes that an interrupt vector table has been previously
* initialized. It does not verify that entries in the table are valid before
* calling an interrupt handler.This function calls itself recursively to handle
* all interrupt controllers.
*
* @param DeviceId is the zero-based device ID defined in xparameters.h
* of the interrupting interrupt controller. It is used as a direct
* index into the configuration data, which contains the vector
* table for the interrupt controller.
*
* @return None.
*
* @note
*
******************************************************************************/
static void XIntc_CascadeHandler(void *DeviceId)
{
u32 IntrStatus;
u32 IntrMask = 1;
int IntrNumber;
u32 Imr;
XIntc_Config *CfgPtr;
static int Id = 0;
/* Get the configuration data using the device ID */
CfgPtr = &XIntc_ConfigTable[(u32)DeviceId];
/* Get the interrupts that are waiting to be serviced */
IntrStatus = XIntc_GetIntrStatus(CfgPtr->BaseAddress);
/* Mask the Fast Interrupts */
if (CfgPtr->FastIntr == TRUE) {
Imr = XIntc_In32(CfgPtr->BaseAddress + XIN_IMR_OFFSET);
IntrStatus &= ~Imr;
}
/* Service each interrupt that is active and enabled by
* checking each bit in the register from LSB to MSB which
* corresponds to an interrupt input signal
*/
for (IntrNumber = 0; IntrNumber < CfgPtr->NumberofIntrs; IntrNumber++) {
if (IntrStatus & 1) {
XIntc_VectorTableEntry *TablePtr;
/* In Cascade mode call this function recursively
* for interrupt id 31 and until interrupts of last
* instance/controller are handled
*/
if ((IntrNumber == 31) &&
(CfgPtr->IntcType != XIN_INTC_LAST) &&
(CfgPtr->IntcType != XIN_INTC_NOCASCADE)) {
XIntc_CascadeHandler((void *)++Id);
Id--;
}
/* If the interrupt has been setup to
* acknowledge it before servicing the
* interrupt, then ack it */
if (CfgPtr->AckBeforeService & IntrMask) {
XIntc_AckIntr(CfgPtr->BaseAddress, IntrMask);
}
/* Handler of 31 interrupt Id has to be called only
* for Last controller in cascade Mode
*/
if (!((IntrNumber == 31) &&
(CfgPtr->IntcType != XIN_INTC_LAST) &&
(CfgPtr->IntcType != XIN_INTC_NOCASCADE))) {
/* The interrupt is active and enabled, call
* the interrupt handler that was setup with
* the specified parameter
*/
TablePtr = &(CfgPtr->HandlerTable[IntrNumber]);
TablePtr->Handler(TablePtr->CallBackRef);
}
/* If the interrupt has been setup to acknowledge it
* after it has been serviced then ack it
*/
if ((CfgPtr->AckBeforeService & IntrMask) == 0) {
XIntc_AckIntr(CfgPtr->BaseAddress, IntrMask);
}
/*
* Read the ISR again to handle architectures with
* posted write bus access issues.
*/
XIntc_GetIntrStatus(CfgPtr->BaseAddress);
/*
* If only the highest priority interrupt is to be
* serviced, exit loop and return after servicing
* the interrupt
*/
if (CfgPtr->Options == XIN_SVC_SGL_ISR_OPTION) {
return;
}
}
/* Move to the next interrupt to check */
IntrMask <<= 1;
IntrStatus >>= 1;
/* If there are no other bits set indicating that all interrupts
* have been serviced, then exit the loop
*/
if (IntrStatus == 0) {
break;
}
}
}
#endif

View file

@ -0,0 +1,327 @@
/******************************************************************************
*
* Copyright (C) 2002 - 2014 Xilinx, Inc. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* Use of the Software is limited solely to applications:
* (a) running on a Xilinx device, or
* (b) that interact with a Xilinx device through a bus or interconnect.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Except as contained in this notice, the name of the Xilinx shall not be used
* in advertising or otherwise to promote the sale, use or other dealings in
* this Software without prior written authorization from Xilinx.
*
******************************************************************************/
/*****************************************************************************/
/**
*
* @file xintc_l.h
*
* This header file contains identifiers and low-level driver functions (or
* macros) that can be used to access the device. The user should refer to the
* hardware device specification for more details of the device operation.
*
*
* Note that users of the driver interface given in this file can register
* an interrupt handler dynamically (at run-time) using the
* XIntc_RegisterHandler() function.
* User of the driver interface given in xintc.h should still use
* XIntc_Connect(), as always.
* Also see the discussion of the interrupt vector tables in xintc.h.
*
* There are currently two interrupt handlers specified in this interface.
*
* - XIntc_LowLevelInterruptHandler() is a handler without any arguments that
* is used in cases where there is a single interrupt controller device in
* the system and the handler cannot be passed an argument. This function is
* provided mostly for backward compatibility.
*
* - XIntc_DeviceInterruptHandler() is a handler that takes a device ID as an
* argument, indicating which interrupt controller device in the system is
* causing the interrupt - thereby supporting multiple interrupt controllers.
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ---- -------- -----------------------------------------------------
* 1.00b jhl 04/24/02 First release
* 1.00c rpm 10/17/03 New release. Support the static vector table created
* in the xintc_g.c configuration table.
* 1.10c mta 03/21/07 Updated to new coding style
* 1.11a sv 11/21/07 Updated driver to support access through a DCR bridge
* 2.00a ktn 10/20/09 Updated to use HAL Processor APIs. _m is removed from all
* the macro definitions.
* 2.04a bss 01/13/12 Updated for adding defines for IMR and IVAR for
* the FAST Interrupt
* 2.05a bss 08/18/12 Added XIntc_RegisterFastHandler API to register fast
* interrupt handlers using base address.
* 2.07a bss 10/18/13 Added XIN_ILR_OFFSET macro for nested interrupts.
*
* </pre>
*
******************************************************************************/
#ifndef XINTC_L_H /* prevent circular inclusions */
#define XINTC_L_H /* by using protection macros */
#ifdef __cplusplus
extern "C" {
#endif
/***************************** Include Files *********************************/
#include "xil_types.h"
#include "xil_assert.h"
#include "xparameters.h"
#include "xil_io.h"
/*
* XPAR_XINTC_USE_DCR_BRIDGE has to be set to 1 if the Intc device will be
* accessed through a DCR bus connected to a bridge.
*/
#define XPAR_XINTC_USE_DCR_BRIDGE 0
#if ((XPAR_XINTC_USE_DCR != 0) || (XPAR_XINTC_USE_DCR_BRIDGE != 0))
#include "xio_dcr.h"
#endif
/************************** Constant Definitions *****************************/
/* define the offsets from the base address for all the registers of the
* interrupt controller, some registers may be optional in the hardware device
*/
#if ((XPAR_XINTC_USE_DCR != 0) || (XPAR_XINTC_USE_DCR_BRIDGE != 0))
#define XIN_ISR_OFFSET 0 /* Interrupt Status Register */
#define XIN_IPR_OFFSET 1 /* Interrupt Pending Register */
#define XIN_IER_OFFSET 2 /* Interrupt Enable Register */
#define XIN_IAR_OFFSET 3 /* Interrupt Acknowledge Register */
#define XIN_SIE_OFFSET 4 /* Set Interrupt Enable Register */
#define XIN_CIE_OFFSET 5 /* Clear Interrupt Enable Register */
#define XIN_IVR_OFFSET 6 /* Interrupt Vector Register */
#define XIN_MER_OFFSET 7 /* Master Enable Register */
#define XIN_IMR_OFFSET 8 /* Interrupt Mode Register , this is present
* only for Fast Interrupt */
#define XIN_IVAR_OFFSET 64 /* Interrupt Vector Address Register
* Interrupt 0 Offest, this is present
* only for Fast Interrupt */
#else /* ((XPAR_XINTC_USE_DCR != 0) || (XPAR_XINTC_USE_DCR_BRIDGE != 0)) */
#define XIN_ISR_OFFSET 0 /* Interrupt Status Register */
#define XIN_IPR_OFFSET 4 /* Interrupt Pending Register */
#define XIN_IER_OFFSET 8 /* Interrupt Enable Register */
#define XIN_IAR_OFFSET 12 /* Interrupt Acknowledge Register */
#define XIN_SIE_OFFSET 16 /* Set Interrupt Enable Register */
#define XIN_CIE_OFFSET 20 /* Clear Interrupt Enable Register */
#define XIN_IVR_OFFSET 24 /* Interrupt Vector Register */
#define XIN_MER_OFFSET 28 /* Master Enable Register */
#define XIN_IMR_OFFSET 32 /* Interrupt Mode Register , this is present
* only for Fast Interrupt */
#define XIN_ILR_OFFSET 36 /* Interrupt level register */
#define XIN_IVAR_OFFSET 0x100 /* Interrupt Vector Address Register
* Interrupt 0 Offest, this is present
* only for Fast Interrupt */
#endif /* ((XPAR_XINTC_USE_DCR != 0) || (XPAR_XINTC_USE_DCR_BRIDGE != 0)) */
/* Bit definitions for the bits of the MER register */
#define XIN_INT_MASTER_ENABLE_MASK 0x1UL
#define XIN_INT_HARDWARE_ENABLE_MASK 0x2UL /* once set cannot be cleared */
/**************************** Type Definitions *******************************/
/* The following data type defines each entry in an interrupt vector table.
* The callback reference is the base address of the interrupting device
* for the driver interface given in this file and an instance pointer for the
* driver interface given in xintc.h file.
*/
typedef struct {
XInterruptHandler Handler;
void *CallBackRef;
} XIntc_VectorTableEntry;
typedef void (*XFastInterruptHandler) (void);
/***************** Macros (Inline Functions) Definitions *********************/
/*
* Define the appropriate I/O access method to memory mapped I/O or DCR.
*/
#if ((XPAR_XINTC_USE_DCR != 0) || (XPAR_XINTC_USE_DCR_BRIDGE != 0))
#define XIntc_In32 XIo_DcrIn
#define XIntc_Out32 XIo_DcrOut
#else
#define XIntc_In32 Xil_In32
#define XIntc_Out32 Xil_Out32
#endif
/****************************************************************************/
/**
*
* Enable all interrupts in the Master Enable register of the interrupt
* controller. The interrupt controller defaults to all interrupts disabled
* from reset such that this macro must be used to enable interrupts.
*
* @param BaseAddress is the base address of the device.
*
* @return None.
*
* @note C-style signature:
* void XIntc_MasterEnable(u32 BaseAddress);
*
*****************************************************************************/
#define XIntc_MasterEnable(BaseAddress) \
XIntc_Out32((BaseAddress) + XIN_MER_OFFSET, \
XIN_INT_MASTER_ENABLE_MASK | XIN_INT_HARDWARE_ENABLE_MASK)
/****************************************************************************/
/**
*
* Disable all interrupts in the Master Enable register of the interrupt
* controller.
*
* @param BaseAddress is the base address of the device.
*
* @return None.
*
* @note C-style signature:
* void XIntc_MasterDisable(u32 BaseAddress);
*
*****************************************************************************/
#define XIntc_MasterDisable(BaseAddress) \
XIntc_Out32((BaseAddress) + XIN_MER_OFFSET, 0)
/****************************************************************************/
/**
*
* Enable specific interrupt(s) in the interrupt controller.
*
* @param BaseAddress is the base address of the device
* @param EnableMask is the 32-bit value to write to the enable register.
* Each bit of the mask corresponds to an interrupt input signal
* that is connected to the interrupt controller (INT0 = LSB).
* Only the bits which are set in the mask will enable interrupts.
*
* @return None.
*
* @note C-style signature:
* void XIntc_EnableIntr(u32 BaseAddress, u32 EnableMask);
*
*****************************************************************************/
#define XIntc_EnableIntr(BaseAddress, EnableMask) \
XIntc_Out32((BaseAddress) + XIN_IER_OFFSET, (EnableMask))
/****************************************************************************/
/**
*
* Disable specific interrupt(s) in the interrupt controller.
*
* @param BaseAddress is the base address of the device
* @param DisableMask is the 32-bit value to write to the enable register.
* Each bit of the mask corresponds to an interrupt input signal
* that is connected to the interrupt controller (INT0 = LSB).
* Only the bits which are set in the mask will disable interrupts.
*
* @return None.
*
* @note C-style signature:
* void XIntc_DisableIntr(u32 BaseAddress, u32 DisableMask);
*
*****************************************************************************/
#define XIntc_DisableIntr(BaseAddress, DisableMask) \
XIntc_Out32((BaseAddress) + XIN_IER_OFFSET, ~(DisableMask))
/****************************************************************************/
/**
*
* Acknowledge specific interrupt(s) in the interrupt controller.
*
* @param BaseAddress is the base address of the device
* @param AckMask is the 32-bit value to write to the acknowledge
* register. Each bit of the mask corresponds to an interrupt input
* signal that is connected to the interrupt controller (INT0 =
* LSB). Only the bits which are set in the mask will acknowledge
* interrupts.
*
* @return None.
*
* @note C-style signature:
* void XIntc_AckIntr(u32 BaseAddress, u32 AckMask);
*
*****************************************************************************/
#define XIntc_AckIntr(BaseAddress, AckMask) \
XIntc_Out32((BaseAddress) + XIN_IAR_OFFSET, (AckMask))
/****************************************************************************/
/**
*
* Get the interrupt status from the interrupt controller which indicates
* which interrupts are active and enabled.
*
* @param BaseAddress is the base address of the device
*
* @return The 32-bit contents of the interrupt status register. Each bit
* corresponds to an interrupt input signal that is connected to
* the interrupt controller (INT0 = LSB). Bits which are set
* indicate an active interrupt which is also enabled.
*
* @note C-style signature:
* u32 XIntc_GetIntrStatus(u32 BaseAddress);
*
*****************************************************************************/
#define XIntc_GetIntrStatus(BaseAddress) \
(XIntc_In32((BaseAddress) + XIN_ISR_OFFSET) & \
XIntc_In32((BaseAddress) + XIN_IER_OFFSET))
/************************** Function Prototypes ******************************/
/*
* Interrupt controller handlers, to be connected to processor exception
* handling code.
*/
void XIntc_LowLevelInterruptHandler(void);
void XIntc_DeviceInterruptHandler(void *DeviceId);
/* Various configuration functions */
void XIntc_SetIntrSvcOption(u32 BaseAddress, int Option);
void XIntc_RegisterHandler(u32 BaseAddress, int InterruptId,
XInterruptHandler Handler, void *CallBackRef);
void XIntc_RegisterFastHandler(u32 BaseAddress, u8 Id,
XFastInterruptHandler FastHandler);
/************************** Variable Definitions *****************************/
#ifdef __cplusplus
}
#endif
#endif /* end of protection macro */

View file

@ -0,0 +1,146 @@
/******************************************************************************
*
* Copyright (C) 2002 - 2014 Xilinx, Inc. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* Use of the Software is limited solely to applications:
* (a) running on a Xilinx device, or
* (b) that interact with a Xilinx device through a bus or interconnect.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Except as contained in this notice, the name of the Xilinx shall not be used
* in advertising or otherwise to promote the sale, use or other dealings in
* this Software without prior written authorization from Xilinx.
*
******************************************************************************/
/*****************************************************************************/
/**
*
* @file xintc_options.c
*
* Contains option functions for the XIntc driver. These functions allow the
* user to configure an instance of the XIntc driver. This file requires other
* files of the component to be linked in also.
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ---- -------- -----------------------------------------------------
* 1.00b jhl 02/21/02 First release
* 1.00c rpm 10/17/03 New release. Support the relocation of the options flag
* from the instance structure to the xintc_g.c
* configuration table.
* 1.10c mta 03/21/07 Updated to new coding style
* 2.00a ktn 10/20/09 Updated to use HAL Processor APIs
* 2.06a bss 01/28/13 To support Cascade mode:
* Modified XIntc_SetOptions API.
* </pre>
*
******************************************************************************/
/***************************** Include Files *********************************/
#include "xil_types.h"
#include "xil_assert.h"
#include "xintc.h"
/************************** Constant Definitions *****************************/
/**************************** Type Definitions *******************************/
/***************** Macros (Inline Functions) Definitions *********************/
/************************** Function Prototypes ******************************/
/************************** Variable Definitions *****************************/
/*****************************************************************************/
/**
*
* Set the options for the interrupt controller driver. In Cascade mode same
* Option is set to Slave controllers.
*
* @param InstancePtr is a pointer to the XIntc instance to be worked on.
* @param Options to be set. The available options are described in
* xintc.h.
*
* @return
* - XST_SUCCESS if the options were set successfully
* - XST_INVALID_PARAM if the specified option was not valid
*
* @note None.
*
****************************************************************************/
int XIntc_SetOptions(XIntc * InstancePtr, u32 Options)
{
XIntc_Config *CfgPtr;
Xil_AssertNonvoid(InstancePtr != NULL);
Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
/*
* Make sure option request is valid
*/
if ((Options == XIN_SVC_SGL_ISR_OPTION) ||
(Options == XIN_SVC_ALL_ISRS_OPTION)) {
InstancePtr->CfgPtr->Options = Options;
/* If Cascade mode set the option for all Slaves */
if (InstancePtr->CfgPtr->IntcType != XIN_INTC_NOCASCADE) {
int Index;
for (Index = 1; Index <= XPAR_XINTC_NUM_INSTANCES - 1;
Index++) {
CfgPtr = XIntc_LookupConfig(Index);
CfgPtr->Options = Options;
}
}
return XST_SUCCESS;
}
else {
return XST_INVALID_PARAM;
}
}
/*****************************************************************************/
/**
*
* Return the currently set options.
*
* @param InstancePtr is a pointer to the XIntc instance to be worked on.
*
* @return The currently set options. The options are described in xintc.h.
*
* @note None.
*
****************************************************************************/
u32 XIntc_GetOptions(XIntc * InstancePtr)
{
/*
* Assert the arguments
*/
Xil_AssertNonvoid(InstancePtr != NULL);
Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
return InstancePtr->CfgPtr->Options;
}

View file

@ -0,0 +1,252 @@
/******************************************************************************
*
* Copyright (C) 2002 - 2014 Xilinx, Inc. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* Use of the Software is limited solely to applications:
* (a) running on a Xilinx device, or
* (b) that interact with a Xilinx device through a bus or interconnect.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Except as contained in this notice, the name of the Xilinx shall not be used
* in advertising or otherwise to promote the sale, use or other dealings in
* this Software without prior written authorization from Xilinx.
*
******************************************************************************/
/*****************************************************************************/
/**
*
* @file xintc_selftest.c
*
* Contains diagnostic self-test functions for the XIntc component. This file
* requires other files of the component to be linked in also.
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ---- -------- -----------------------------------------------
* 1.00b jhl 02/21/02 First release
* 1.10c mta 03/21/07 Updated to new coding style
* 2.00a ktn 10/20/09 Updated to use HAL Processor APIs
* 2.04a bss 01/16/12 Removed CurrentMIE variable and reading of the
* MER register to remove warnings
* 2.06a bss 01/28/13 To support Cascade mode:
* Modified XIntc_SimulateIntr API.
* </pre>
*
******************************************************************************/
/***************************** Include Files *********************************/
#include "xil_types.h"
#include "xil_assert.h"
#include "xintc.h"
#include "xintc_i.h"
/************************** Constant Definitions *****************************/
#define XIN_TEST_MASK 1
/**************************** Type Definitions *******************************/
/***************** Macros (Inline Functions) Definitions *********************/
/************************** Function Prototypes ******************************/
/************************** Variable Definitions *****************************/
/*****************************************************************************/
/**
*
* Run a self-test on the driver/device. This is a destructive test.
*
* This involves forcing interrupts into the controller and verifying that they
* are recognized and can be acknowledged. This test will not succeed if the
* interrupt controller has been started in real mode such that interrupts
* cannot be forced.
*
* @param InstancePtr is a pointer to the XIntc instance to be worked on.
*
* @return
* - XST_SUCCESS if self-test is successful.
* - XST_INTC_FAIL_SELFTEST if the Interrupt controller fails the
* self-test. It will fail the self test if the device has
* previously been started in real mode.
*
* @note None.
*
******************************************************************************/
int XIntc_SelfTest(XIntc * InstancePtr)
{
u32 CurrentISR;
u32 Temp;
/*
* Assert the arguments
*/
Xil_AssertNonvoid(InstancePtr != NULL);
Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
/*
* Acknowledge all pending interrupts by reading the interrupt status
* register and writing the value to the acknowledge register
*/
Temp = XIntc_In32(InstancePtr->BaseAddress + XIN_ISR_OFFSET);
XIntc_Out32(InstancePtr->BaseAddress + XIN_IAR_OFFSET, Temp);
/*
* Verify that there are no interrupts by reading the interrupt status
*/
CurrentISR = XIntc_In32(InstancePtr->BaseAddress + XIN_ISR_OFFSET);
/*
* ISR should be zero after all interrupts are acknowledged
*/
if (CurrentISR != 0) {
return XST_INTC_FAIL_SELFTEST;
}
/*
* Set a bit in the ISR which simulates an interrupt
*/
XIntc_Out32(InstancePtr->BaseAddress + XIN_ISR_OFFSET, XIN_TEST_MASK);
/*
* Verify that it was set
*/
CurrentISR = XIntc_In32(InstancePtr->BaseAddress + XIN_ISR_OFFSET);
if (CurrentISR != XIN_TEST_MASK) {
return XST_INTC_FAIL_SELFTEST;
}
/*
* Acknowledge the interrupt
*/
XIntc_Out32(InstancePtr->BaseAddress + XIN_IAR_OFFSET, XIN_TEST_MASK);
/*
* Read back the ISR to verify that the interrupt is gone
*/
CurrentISR = XIntc_In32(InstancePtr->BaseAddress + XIN_ISR_OFFSET);
if (CurrentISR != 0) {
return XST_INTC_FAIL_SELFTEST;
}
return XST_SUCCESS;
}
/*****************************************************************************/
/**
*
* Allows software to simulate an interrupt in the interrupt controller. This
* function will only be successful when the interrupt controller has been
* started in simulation mode. Once it has been started in real mode,
* interrupts cannot be simulated. A simulated interrupt allows the interrupt
* controller to be tested without any device to drive an interrupt input
* signal into it. In Cascade mode writes to ISR of appropraite Slave
* controller depending on Id.
*
* @param InstancePtr is a pointer to the XIntc instance to be worked on.
* @param Id is the interrupt ID for which to simulate an interrupt.
*
* @return
* - XST_SUCCESS if successful
* - XST_FAILURE if the interrupt could not be
* simulated because the interrupt controller is or
* has previously been in real mode.
*
* @note None.
*
******************************************************************************/
int XIntc_SimulateIntr(XIntc * InstancePtr, u8 Id)
{
u32 Mask;
u32 MasterEnable;
XIntc_Config *CfgPtr;
int Index;
int DeviceId;
/*
* Assert the arguments
*/
Xil_AssertNonvoid(InstancePtr != NULL);
Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
Xil_AssertNonvoid(Id < XPAR_INTC_MAX_NUM_INTR_INPUTS);
/* Get the contents of the master enable register and determine if
* hardware interrupts have already been enabled, if so, this is a write
* once bit such that simulation can't be done at this point because
* the ISR register is no longer writable by software
*/
MasterEnable = XIntc_In32(InstancePtr->BaseAddress + XIN_MER_OFFSET);
if (MasterEnable & XIN_INT_HARDWARE_ENABLE_MASK) {
return XST_FAILURE;
}
if (Id > 31) {
DeviceId = Id/32;
CfgPtr = XIntc_LookupConfig(Id/32);
Mask = XIntc_BitPosMask[Id%32];
XIntc_Out32(CfgPtr->BaseAddress + XIN_ISR_OFFSET, Mask);
/* Generate interrupt for 31 by writing to Interrupt Status
* register of parent controllers. Primary controller ISR
* will be written last in the loop
*/
Mask = XIntc_BitPosMask[31];
for (Index = DeviceId - 1; Index >= 0; Index--)
{
CfgPtr = XIntc_LookupConfig(Index);
XIntc_Out32(CfgPtr->BaseAddress + XIN_ISR_OFFSET,
Mask);
}
}
else {
/*
* The Id is used to create the appropriate mask for the
* desired bit position.
*/
Mask = XIntc_BitPosMask[Id];
/*
* Enable the selected interrupt source by reading the interrupt
* enable register and then modifying only the specified
* interrupt id enable
*/
XIntc_Out32(InstancePtr->BaseAddress + XIN_ISR_OFFSET, Mask);
}
/* indicate the interrupt was successfully simulated */
return XST_SUCCESS;
}