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:
parent
58e0fb3ac2
commit
e703803892
18 changed files with 5159 additions and 0 deletions
73
XilinxProcessorIPLib/drivers/intc/data/intc.mdd
Executable file
73
XilinxProcessorIPLib/drivers/intc/data/intc.mdd
Executable 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
|
685
XilinxProcessorIPLib/drivers/intc/data/intc.tcl
Executable file
685
XilinxProcessorIPLib/drivers/intc/data/intc.tcl
Executable 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
|
||||
}
|
42
XilinxProcessorIPLib/drivers/intc/data/intc_header.h
Normal file
42
XilinxProcessorIPLib/drivers/intc/data/intc_header.h
Normal 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
|
206
XilinxProcessorIPLib/drivers/intc/data/intc_tapp.tcl
Executable file
206
XilinxProcessorIPLib/drivers/intc/data/intc_tapp.tcl
Executable 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
|
||||
}
|
19
XilinxProcessorIPLib/drivers/intc/examples/index.html
Executable file
19
XilinxProcessorIPLib/drivers/intc/examples/index.html
Executable 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>
|
348
XilinxProcessorIPLib/drivers/intc/examples/xintc_example.c
Normal file
348
XilinxProcessorIPLib/drivers/intc/examples/xintc_example.c
Normal 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;
|
||||
|
||||
}
|
|
@ -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;
|
||||
|
||||
}
|
250
XilinxProcessorIPLib/drivers/intc/examples/xintc_tapp_example.c
Normal file
250
XilinxProcessorIPLib/drivers/intc/examples/xintc_tapp_example.c
Normal 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;
|
||||
|
||||
}
|
28
XilinxProcessorIPLib/drivers/intc/src/Makefile
Normal file
28
XilinxProcessorIPLib/drivers/intc/src/Makefile
Normal 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}
|
1078
XilinxProcessorIPLib/drivers/intc/src/xintc.c
Normal file
1078
XilinxProcessorIPLib/drivers/intc/src/xintc.c
Normal file
File diff suppressed because it is too large
Load diff
366
XilinxProcessorIPLib/drivers/intc/src/xintc.h
Normal file
366
XilinxProcessorIPLib/drivers/intc/src/xintc.h
Normal 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 */
|
112
XilinxProcessorIPLib/drivers/intc/src/xintc_g.c
Normal file
112
XilinxProcessorIPLib/drivers/intc/src/xintc_g.c
Normal 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 */
|
||||
}
|
||||
};
|
90
XilinxProcessorIPLib/drivers/intc/src/xintc_i.h
Normal file
90
XilinxProcessorIPLib/drivers/intc/src/xintc_i.h
Normal 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
|
173
XilinxProcessorIPLib/drivers/intc/src/xintc_intr.c
Normal file
173
XilinxProcessorIPLib/drivers/intc/src/xintc_intr.c
Normal 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)));
|
||||
}
|
662
XilinxProcessorIPLib/drivers/intc/src/xintc_l.c
Normal file
662
XilinxProcessorIPLib/drivers/intc/src/xintc_l.c
Normal 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
|
327
XilinxProcessorIPLib/drivers/intc/src/xintc_l.h
Normal file
327
XilinxProcessorIPLib/drivers/intc/src/xintc_l.h
Normal 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 */
|
146
XilinxProcessorIPLib/drivers/intc/src/xintc_options.c
Normal file
146
XilinxProcessorIPLib/drivers/intc/src/xintc_options.c
Normal 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;
|
||||
}
|
252
XilinxProcessorIPLib/drivers/intc/src/xintc_selftest.c
Normal file
252
XilinxProcessorIPLib/drivers/intc/src/xintc_selftest.c
Normal 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;
|
||||
}
|
Loading…
Add table
Reference in a new issue