drivers: scugic: deprecated version 3.0 and created a new minor version 3.1
Signed-off-by: Kinjal Pravinbhai Patel <patelki@xilinx.com>
This commit is contained in:
parent
c7791d8bb0
commit
de71767f08
17 changed files with 4508 additions and 0 deletions
42
XilinxProcessorIPLib/drivers/scugic/data/scugic.mdd
Normal file
42
XilinxProcessorIPLib/drivers/scugic/data/scugic.mdd
Normal file
|
@ -0,0 +1,42 @@
|
|||
###############################################################################
|
||||
#
|
||||
# Copyright (C) 2011 - 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
|
||||
# XILINX 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.
|
||||
#
|
||||
###############################################################################
|
||||
OPTION psf_version = 2.1;
|
||||
|
||||
BEGIN driver scugic
|
||||
|
||||
OPTION supported_peripherals = (ps7_scugic psu_scugic psu_acpu_gic psu_rcpu_gic);
|
||||
OPTION driver_state = ACTIVE;
|
||||
OPTION copyfiles = all;
|
||||
OPTION VERSION = 3.1;
|
||||
OPTION NAME = scugic;
|
||||
OPTION INTC_TYPE = XScuGic;
|
||||
END driver
|
562
XilinxProcessorIPLib/drivers/scugic/data/scugic.tcl
Normal file
562
XilinxProcessorIPLib/drivers/scugic/data/scugic.tcl
Normal file
|
@ -0,0 +1,562 @@
|
|||
###############################################################################
|
||||
#
|
||||
# Copyright (C) 2011 - 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
|
||||
# XILINX 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
|
||||
# ----- ---- -------- -----------------------------------------------
|
||||
# 1.00a sdm 04/18/11 Created
|
||||
# 1.05a hk 06/26/13 Modified to export external interrupts correctly
|
||||
# to xparameters.h. Fix for CR's 690505, 708928 & 719359
|
||||
# 2.0 adk 12/10/13 Updated as per the New Tcl API's
|
||||
# 2.1 adk 25/04/14 Added support for corenIRQ/FIQ interrupts.Fix for the
|
||||
# CR#789373
|
||||
# 3.0 pkp 12/09/14 Added support for Zynq Ultrascale Mp
|
||||
##############################################################################
|
||||
|
||||
#uses "xillib.tcl"
|
||||
|
||||
############################################################
|
||||
# "generate" procedure
|
||||
############################################################
|
||||
proc generate {drv_handle} {
|
||||
xdefine_gic_params $drv_handle
|
||||
|
||||
xdefine_zynq_include_file $drv_handle "xparameters.h" "XScuGic" "NUM_INSTANCES" "DEVICE_ID" "C_S_AXI_BASEADDR" "C_S_AXI_HIGHADDR" "C_DIST_BASEADDR"
|
||||
xdefine_zynq_config_file $drv_handle "xscugic_g.c" "XScuGic" "DEVICE_ID" "C_S_AXI_BASEADDR" "C_DIST_BASEADDR"
|
||||
xdefine_zynq_canonical_xpars $drv_handle "xparameters.h" "ScuGic" "DEVICE_ID" "C_S_AXI_BASEADDR" "C_S_AXI_HIGHADDR" "C_DIST_BASEADDR"
|
||||
|
||||
}
|
||||
|
||||
#
|
||||
# Given a list of arguments, define them all in an include file.
|
||||
# Similar to proc xdefine_include_file, except that uses regsub
|
||||
# to replace "S_AXI_" with "".
|
||||
#
|
||||
proc xdefine_zynq_include_file {drv_handle file_name drv_string args} {
|
||||
# Open include file
|
||||
set file_handle [::hsi::utils::open_include_file $file_name]
|
||||
|
||||
# Get all peripherals connected to this driver
|
||||
set periphs [::hsi::utils::get_common_driver_ips $drv_handle]
|
||||
|
||||
#Get the processor instance name
|
||||
set sw_proc_handle [hsi::get_sw_processor]
|
||||
set hw_proc_handle [hsi::get_cells [common::get_property HW_INSTANCE $sw_proc_handle] ]
|
||||
set proctype [common::get_property IP_NAME $hw_proc_handle]
|
||||
#Get proper gic instance for periphs in case of zynqmp
|
||||
foreach periph $periphs {
|
||||
if {([string compare -nocase $proctype "ps7_cortexa9"] == 0)||
|
||||
(([string compare -nocase $proctype "psu_cortexa53"] == 0)&&([string compare -nocase $periph "psu_acpu_gic"] == 0))||
|
||||
(([string compare -nocase $proctype "psu_cortexr5"] == 0)&&([string compare -nocase $periph "psu_rcpu_gic"] == 0))} {
|
||||
lappend newperiphs $periph
|
||||
}
|
||||
}
|
||||
set periphs $newperiphs
|
||||
|
||||
|
||||
# Handle special cases
|
||||
set arg "NUM_INSTANCES"
|
||||
set posn [lsearch -exact $args $arg]
|
||||
if {$posn > -1} {
|
||||
puts $file_handle "/* Definitions for driver [string toupper [common::get_property NAME $drv_handle]] */"
|
||||
# Define NUM_INSTANCES
|
||||
puts $file_handle "#define [::hsi::utils::get_driver_param_name $drv_string $arg] [llength $periphs]"
|
||||
set args [lreplace $args $posn $posn]
|
||||
}
|
||||
# Check if it is a driver parameter
|
||||
|
||||
lappend newargs
|
||||
foreach arg $args {
|
||||
set value [common::get_property CONFIG.$arg $drv_handle]
|
||||
if {[llength $value] == 0} {
|
||||
lappend newargs $arg
|
||||
} else {
|
||||
puts $file_handle "#define [::hsi::utils::get_driver_param_name $drv_string $arg] [common::get_property CONFIG.$arg $drv_handle]"
|
||||
}
|
||||
}
|
||||
set args $newargs
|
||||
# Print all parameters for all peripherals
|
||||
set device_id 0
|
||||
foreach periph $periphs {
|
||||
puts $file_handle ""
|
||||
puts $file_handle "/* Definitions for peripheral [string toupper [common::get_property NAME $periph]] */"
|
||||
foreach arg $args {
|
||||
if {[string compare -nocase "DEVICE_ID" $arg] == 0} {
|
||||
set value $device_id
|
||||
incr device_id
|
||||
} elseif {[string compare -nocase "C_S_AXI_BASEADDR" $arg] == 0} {
|
||||
if {[string compare -nocase $proctype "psu_cortexr5"] == 0} {
|
||||
set value 0xF9001000
|
||||
} elseif {[string compare -nocase $proctype "ps7_cortexa9"] == 0} {
|
||||
set value [common::get_property CONFIG.$arg $periph]
|
||||
} else {
|
||||
set value 0xF9020000
|
||||
}
|
||||
} elseif {[string compare -nocase "C_S_AXI_HIGHADDR" $arg] == 0} {
|
||||
if {[string compare -nocase $proctype "psu_cortexr5"] == 0} {
|
||||
set value 0xF9001FFF
|
||||
} elseif {[string compare -nocase $proctype "ps7_cortexa9"] == 0} {
|
||||
set value [common::get_property CONFIG.$arg $periph]
|
||||
} else {
|
||||
set value 0xF9020FFF
|
||||
}
|
||||
} elseif {[string compare -nocase "C_DIST_BASEADDR" $arg] == 0} {
|
||||
if {[string compare -nocase $proctype "psu_cortexr5"] == 0} {
|
||||
set value 0xF9000000
|
||||
} elseif {[string compare -nocase $proctype "ps7_cortexa9"] == 0} {
|
||||
set value 0xf8f01000
|
||||
} else {
|
||||
set value 0xF9010000
|
||||
}
|
||||
} else {
|
||||
set value [common::get_property CONFIG.$arg $periph]
|
||||
}
|
||||
if {[llength $value] == 0} {
|
||||
set value 0
|
||||
}
|
||||
set value [::hsi::utils::format_addr_string $value $arg]
|
||||
set arg_name [::hsi::utils::get_ip_param_name $periph $arg]
|
||||
regsub "S_AXI_" $arg_name "" arg_name
|
||||
if {[string compare -nocase "HW_VER" $arg] == 0} {
|
||||
puts $file_handle "#define $arg_name \"$value\""
|
||||
} else {
|
||||
puts $file_handle "#define $arg_name $value"
|
||||
}
|
||||
}
|
||||
puts $file_handle ""
|
||||
}
|
||||
puts $file_handle "\n/******************************************************************/\n"
|
||||
close $file_handle
|
||||
}
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# xdefine_zynq_canonical_xpars - Used to print out canonical defines for a driver.
|
||||
# Similar to proc xdefine_config_file, except that uses regsub to replace "S_AXI_"
|
||||
# with "".
|
||||
#-----------------------------------------------------------------------------
|
||||
proc xdefine_zynq_canonical_xpars {drv_handle file_name drv_string args} {
|
||||
# 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 processor instance name
|
||||
set sw_proc_handle [hsi::get_sw_processor]
|
||||
set hw_proc_handle [hsi::get_cells [common::get_property HW_INSTANCE $sw_proc_handle] ]
|
||||
set proctype [common::get_property IP_NAME $hw_proc_handle]
|
||||
|
||||
#Get proper gic instance for periphs in case of zynqmp
|
||||
foreach periph $periphs {
|
||||
if {([string compare -nocase $proctype "ps7_cortexa9"] == 0)||
|
||||
(([string compare -nocase $proctype "psu_cortexa53"] == 0)&&([string compare -nocase $periph "psu_acpu_gic"] == 0))||
|
||||
(([string compare -nocase $proctype "psu_cortexr5"] == 0)&&([string compare -nocase $periph "psu_rcpu_gic"] == 0))} {
|
||||
lappend newperiphs $periph
|
||||
}
|
||||
}
|
||||
set periphs $newperiphs
|
||||
|
||||
# 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]
|
||||
# replace S_SXI_ with CPU_. This is a temporary fix. Revist when the
|
||||
# S_AXI_DIST_BASEADDR is generated by the tools
|
||||
regsub "S_AXI_" $lvalue "CPU_" lvalue
|
||||
|
||||
# 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
|
||||
if {[string compare -nocase "C_S_AXI_BASEADDR" $arg] == 0} {
|
||||
if {[string compare -nocase $proctype "psu_cortexr5"] == 0} {
|
||||
set rvalue 0xF9001000
|
||||
} elseif {[string compare -nocase $proctype "ps7_cortexa9"] == 0} {
|
||||
set rvalue [common::get_property CONFIG.$arg $periph]
|
||||
} else {
|
||||
set rvalue 0xF9020000
|
||||
}
|
||||
} elseif {[string compare -nocase "C_S_AXI_HIGHADDR" $arg] == 0} {
|
||||
if {[string compare -nocase $proctype "psu_cortexr5"] == 0} {
|
||||
set rvalue 0xF9001FFF
|
||||
} elseif {[string compare -nocase $proctype "ps7_cortexa9"] == 0} {
|
||||
set rvalue [common::get_property CONFIG.$arg $periph]
|
||||
} else {
|
||||
set rvalue 0xF9020FFF
|
||||
}
|
||||
} elseif {[string compare -nocase "C_DIST_BASEADDR" $arg] == 0} {
|
||||
if {[string compare -nocase $proctype "psu_cortexr5"] == 0} {
|
||||
set rvalue 0xF9000000
|
||||
} elseif {[string compare -nocase $proctype "ps7_cortexa9"] == 0} {
|
||||
set rvalue 0xf8f01000
|
||||
} else {
|
||||
set rvalue 0xF9010000
|
||||
}
|
||||
} else {
|
||||
set rvalue [common::get_property CONFIG.$arg $periph]
|
||||
}
|
||||
if {[llength $rvalue] == 0} {
|
||||
set rvalue 0
|
||||
}
|
||||
set rvalue [::hsi::utils::format_addr_string $rvalue $arg]
|
||||
|
||||
puts $file_handle "#define $lvalue $rvalue"
|
||||
|
||||
}
|
||||
puts $file_handle ""
|
||||
incr i
|
||||
}
|
||||
}
|
||||
|
||||
puts $file_handle "\n/******************************************************************/\n"
|
||||
close $file_handle
|
||||
}
|
||||
|
||||
#
|
||||
# Create configuration C file as required by Xilinx Zynq drivers
|
||||
# Similar to proc define_config_file, except that uses regsub
|
||||
# to replace "S_AXI_" with ""
|
||||
#
|
||||
|
||||
proc xdefine_zynq_config_file {drv_handle file_name drv_string args} {
|
||||
set args [::hsi::utils::get_exact_arg_list $args]
|
||||
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/*"
|
||||
puts $config_file "* The configuration table for devices"
|
||||
puts $config_file "*/\n"
|
||||
puts $config_file [format "%s_Config %s_ConfigTable\[\] =" $drv_string $drv_string]
|
||||
puts $config_file "\{"
|
||||
set periphs [::hsi::utils::get_common_driver_ips $drv_handle]
|
||||
|
||||
#Get the processor instance name
|
||||
set sw_proc_handle [hsi::get_sw_processor]
|
||||
set hw_proc_handle [hsi::get_cells [common::get_property HW_INSTANCE $sw_proc_handle] ]
|
||||
set proctype [common::get_property IP_NAME $hw_proc_handle]
|
||||
|
||||
#Get proper gic instance for periphs in case of zynqmp
|
||||
foreach periph $periphs {
|
||||
if {([string compare -nocase $proctype "ps7_cortexa9"] == 0)||
|
||||
(([string compare -nocase $proctype "psu_cortexa53"] == 0)&&([string compare -nocase $periph "psu_acpu_gic"] == 0))||
|
||||
(([string compare -nocase $proctype "psu_cortexr5"] == 0)&&([string compare -nocase $periph "psu_rcpu_gic"] == 0))} {
|
||||
lappend newperiphs $periph
|
||||
}
|
||||
}
|
||||
set periphs $newperiphs
|
||||
set start_comma ""
|
||||
foreach periph $periphs {
|
||||
puts $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} {
|
||||
set local_value [common::get_property CONFIG.$arg $periph ]
|
||||
# If a parameter isn't found locally (in the current
|
||||
# peripheral), we will (for some obscure and ancient reason)
|
||||
# look in peripherals connected via point to point links
|
||||
if { [string compare -nocase $local_value ""] == 0} {
|
||||
set p2p_name [::hsi::utils::get_p2p_name $periph $arg]
|
||||
if { [string compare -nocase $p2p_name ""] == 0} {
|
||||
set arg_name [::hsi::utils::get_ip_param_name $periph $arg]
|
||||
regsub "S_AXI_" $arg_name "" arg_name
|
||||
puts -nonewline $config_file [format "%s\t\t%s" $comma $arg_name]
|
||||
} else {
|
||||
regsub "S_AXI_" $p2p_name "" p2p_name
|
||||
puts -nonewline $config_file [format "%s\t\t%s" $comma $p2p_name]
|
||||
}
|
||||
} else {
|
||||
set arg_name [::hsi::utils::get_ip_param_name $periph $arg]
|
||||
regsub "S_AXI_" $arg_name "" arg_name
|
||||
puts -nonewline $config_file [format "%s\t\t%s" $comma $arg_name]
|
||||
}
|
||||
} else {
|
||||
set arg_name [::hsi::utils::get_driver_param_name $drv_string $arg]
|
||||
regsub "S_AXI_" $arg_name "" arg_name
|
||||
puts -nonewline $config_file [format "%s\t\t%s" $comma $arg_name]
|
||||
}
|
||||
set comma ",\n"
|
||||
}
|
||||
puts -nonewline $config_file "\n\t\}"
|
||||
set start_comma ",\n"
|
||||
}
|
||||
puts $config_file "\n\};"
|
||||
|
||||
puts $config_file "\n";
|
||||
|
||||
close $config_file
|
||||
}
|
||||
|
||||
proc xdefine_gic_params {drvhandle} {
|
||||
|
||||
#Get the processor instance name
|
||||
set sw_proc_handle [hsi::get_sw_processor]
|
||||
set hw_proc_handle [hsi::get_cells [common::get_property HW_INSTANCE $sw_proc_handle] ]
|
||||
set proctype [common::get_property IP_NAME $hw_proc_handle]
|
||||
# Fix me
|
||||
# Avoid generating fabric interrupts for zynqmp till the issue is fixed
|
||||
if {([string compare -nocase $proctype "psu_cortexa53"] == 0) || ([string compare -nocase $proctype "psu_cortexr5"] == 0)} {
|
||||
} else {
|
||||
|
||||
set config_inc [::hsi::utils::open_include_file "xparameters.h"]
|
||||
# Next define interrupt IDs for each connected peripheral
|
||||
|
||||
set periphs [::hsi::utils::get_common_driver_ips $drvhandle]
|
||||
set device_id 0
|
||||
|
||||
foreach periph $periphs {
|
||||
|
||||
# get the gic mode information
|
||||
set scugic_mode [common::get_property CONFIG.C_IRQ_F2P_MODE $periph]
|
||||
|
||||
# Get the edk based name of peripheral for printing redefines
|
||||
set edk_periph_name [common::get_property NAME $periph]
|
||||
|
||||
# Get ports that are driving the interrupt
|
||||
set source_ports [::hsi::utils::get_interrupt_sources $periph]
|
||||
set i 0
|
||||
lappend source_list
|
||||
foreach source_port $source_ports {
|
||||
|
||||
if {[llength $source_port] ==0 } {
|
||||
continue
|
||||
}
|
||||
set portType [common::get_property TYPE $source_port]
|
||||
if { [string compare -nocase $portType "INTERRUPT"] } {
|
||||
continue
|
||||
}
|
||||
|
||||
set external_pin [::hsi::utils::is_external_pin $source_port]
|
||||
if {$external_pin} {
|
||||
set source_port_name($i) [common::get_property NAME $source_port]
|
||||
set source_periph($i) ""
|
||||
set source_name($i) "system"
|
||||
} else {
|
||||
set source_port_name($i) [common::get_property NAME $source_port]
|
||||
set source_ip [hsi::get_cells -of_objects $source_port]
|
||||
if { [common::get_property IS_PL $source_ip] == 0 } {
|
||||
#add only PL IP. Return all PS IPs
|
||||
continue
|
||||
}
|
||||
set source_periph($i) $source_ip
|
||||
set source_name($i) [common::get_property NAME $source_periph($i)]
|
||||
}
|
||||
lappend source_list $source_name($i)
|
||||
incr i
|
||||
}
|
||||
|
||||
set num_intr_inputs $i
|
||||
if {$num_intr_inputs == 0} {
|
||||
close $config_inc
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
puts $config_inc "/* Definitions for Fabric interrupts connected to $edk_periph_name */"
|
||||
for {set i 0} {$i < $num_intr_inputs} {incr i} {
|
||||
set ip_name $source_name($i)
|
||||
set port_name $source_port_name($i)
|
||||
set port_obj [::hsi::get_ports $port_name]
|
||||
set port_intr_id [::hsi::utils::get_interrupt_id $ip_name $port_name]
|
||||
if { [string compare -nocase $ip_name "system"] } {
|
||||
set ip_obj [::hsi::get_cells $ip_name]
|
||||
if {[llength $ip_obj]} {
|
||||
set port_obj [::hsi::get_pins -of_objects $ip_obj $port_name]
|
||||
}
|
||||
} else {
|
||||
set port_intr_id [::hsi::utils::get_interrupt_id "" $port_name]
|
||||
}
|
||||
if { [llength $port_intr_id] > 1 } {
|
||||
set j 0
|
||||
foreach intr_id $port_intr_id {
|
||||
puts $config_inc [format "#define XPAR_FABRIC_%s_%s_INTR %d" \
|
||||
[string toupper $ip_name] [string toupper "${port_name}$j"] $intr_id ]
|
||||
incr j
|
||||
}
|
||||
} else {
|
||||
puts $config_inc [format "#define XPAR_FABRIC_%s_%s_INTR %d" \
|
||||
[string toupper $ip_name] [string toupper $port_name] $port_intr_id]
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
puts $config_inc "\n/******************************************************************/\n"
|
||||
puts $config_inc "/* Canonical definitions for Fabric interrupts connected to $edk_periph_name */"
|
||||
|
||||
for {set i 0} {$i < $num_intr_inputs} {incr i} {
|
||||
|
||||
# Skip global (external) ports
|
||||
if {[string compare -nocase $source_periph($i) ""] != 0} {
|
||||
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]
|
||||
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_VEC_ID" "FABRIC" $drvname $instance]
|
||||
} else {
|
||||
set first_part [format "#define XPAR_%s_%s_%s_%s_VEC_ID" "FABRIC" $drvname $instance $port_name]
|
||||
}
|
||||
} else {
|
||||
set first_part [format "#define XPAR_%s_%s_%s_%s_VEC_ID" "FABRIC" $drvname $instance $port_name]
|
||||
}
|
||||
} else {
|
||||
set first_part [format "#define XPAR_%s_%s_%s_VEC_ID" "FABRIC" $drvname $instance]
|
||||
}
|
||||
|
||||
set second_part [format "XPAR_%s_%s_%s_INTR" "FABRIC" [string toupper $source_name($i)] [string toupper $source_port_name($i)] ]
|
||||
|
||||
if {[string compare -nocase $drvname "generic"] != 0} {
|
||||
puts $config_inc "$first_part $second_part"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
incr device_id
|
||||
}
|
||||
|
||||
puts $config_inc "\n/******************************************************************/\n"
|
||||
close $config_inc
|
||||
}
|
||||
}
|
||||
|
||||
###################################################################
|
||||
#
|
||||
# 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
|
||||
}
|
||||
|
||||
###################################################################
|
||||
#
|
||||
# Get the type of port, whether it is "local" (from an IP), or
|
||||
# "global" (from external source).
|
||||
#
|
||||
###################################################################
|
||||
proc xget_port_type {port} {
|
||||
set periph [hsi::get_cells -of_objects $port]
|
||||
if {[llength $periph] == 0} {
|
||||
return "global"
|
||||
} else {
|
||||
return "local"
|
||||
}
|
||||
}
|
43
XilinxProcessorIPLib/drivers/scugic/data/scugic_header.h
Normal file
43
XilinxProcessorIPLib/drivers/scugic/data/scugic_header.h
Normal file
|
@ -0,0 +1,43 @@
|
|||
/* $Id: intc_header.h,v 1.1.4.1 2010/09/17 05:32:46 svemula Exp $ */
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2011 - 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
|
||||
* XILINX 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 SCUGIC_HEADER_H /* prevent circular inclusions */
|
||||
#define SCUGIC_HEADER_H /* by using protection macros */
|
||||
|
||||
#include "xil_assert.h"
|
||||
#include "xil_types.h"
|
||||
#include "xstatus.h"
|
||||
|
||||
int ScuGicSelfTestExample(u16 DeviceId);
|
||||
int ScuGicInterruptSetup(XScuGic *IntcInstancePtr, u16 DeviceId);
|
||||
|
||||
#endif
|
152
XilinxProcessorIPLib/drivers/scugic/data/scugic_tapp.tcl
Normal file
152
XilinxProcessorIPLib/drivers/scugic/data/scugic_tapp.tcl
Normal file
|
@ -0,0 +1,152 @@
|
|||
###############################################################################
|
||||
#
|
||||
# Copyright (C) 2011 - 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
|
||||
# XILINX 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
|
||||
## ----- ---- -------- ----------------------------------------------------
|
||||
## 1.00a sdm 05/24/11 First release
|
||||
## 3.0 adk 12/10/13 Updated as per the New Tcl API's
|
||||
##############################################################################
|
||||
|
||||
# Uses $XILINX_EDK/bin/lib/xillib_sw.tcl
|
||||
# -----------------------------------------------------------------
|
||||
# Software Project Types (swproj):
|
||||
# 0 : MemoryTest - Calls basic memorytest routines
|
||||
# 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 {xscugic.h xil_exception.h scugic_header.h}
|
||||
return $inc_file_lines
|
||||
}
|
||||
}
|
||||
|
||||
proc gen_src_files {swproj mhsinst} {
|
||||
if {$swproj == 0} {
|
||||
return ""
|
||||
}
|
||||
if {$swproj == 1} {
|
||||
set inc_file_lines {examples/xscugic_tapp_example.c data/scugic_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 ipname [common::get_property NAME $mhsinst]
|
||||
set decl " static XScuGic ${ipname};"
|
||||
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 = ScuGicSelfTestExample(${deviceid});
|
||||
Status = ScuGicInterruptSetup(&${intcvar}, ${deviceid});
|
||||
|
||||
}"
|
||||
|
||||
|
||||
} else {
|
||||
|
||||
append testfunc_call "
|
||||
|
||||
{
|
||||
int Status;
|
||||
|
||||
print(\"\\r\\n Running ScuGicSelfTestExample() for ${ipname}...\\r\\n\");
|
||||
|
||||
Status = ScuGicSelfTestExample(${deviceid});
|
||||
|
||||
if (Status == 0) {
|
||||
print(\"ScuGicSelfTestExample PASSED\\r\\n\");
|
||||
}
|
||||
else {
|
||||
print(\"ScuGicSelfTestExample FAILED\\r\\n\");
|
||||
}
|
||||
}"
|
||||
|
||||
append testfunc_call "
|
||||
|
||||
{
|
||||
int Status;
|
||||
|
||||
Status = ScuGicInterruptSetup(&${intcvar}, ${deviceid});
|
||||
if (Status == 0) {
|
||||
print(\"ScuGic Interrupt Setup PASSED\\r\\n\");
|
||||
}
|
||||
else {
|
||||
print(\"ScuGic Interrupt Setup FAILED\\r\\n\");
|
||||
}
|
||||
}"
|
||||
|
||||
|
||||
}
|
||||
return $testfunc_call
|
||||
|
||||
}
|
19
XilinxProcessorIPLib/drivers/scugic/examples/index.html
Executable file
19
XilinxProcessorIPLib/drivers/scugic/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 scugic_v2_1 </h1>
|
||||
<HR>
|
||||
<ul>
|
||||
<li>xscugic_low_level_example.c <a href="xscugic_low_level_example.c">(source)</a> </li>
|
||||
<li>xscugic_example.c <a href="xscugic_example.c">(source)</a> </li>
|
||||
<li>xscugic_tapp_example.c <a href="xscugic_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>
|
313
XilinxProcessorIPLib/drivers/scugic/examples/xscugic_example.c
Normal file
313
XilinxProcessorIPLib/drivers/scugic/examples/xscugic_example.c
Normal file
|
@ -0,0 +1,313 @@
|
|||
/* $Id: xscugic_example.c,v 1.1.2.2 2011/03/23 07:46:43 sadanan Exp $ */
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2010 - 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
|
||||
* XILINX 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 xscugic_example.c
|
||||
*
|
||||
* This file contains a design example using the Interrupt Controller driver
|
||||
* (XScuGic) 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.
|
||||
*
|
||||
* @note
|
||||
*
|
||||
* None
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* MODIFICATION HISTORY:
|
||||
* Ver Who Date Changes
|
||||
* ----- ---- -------- ----------------------------------------------------
|
||||
* 1.00a drg 01/18/10 First release
|
||||
* </pre>
|
||||
******************************************************************************/
|
||||
|
||||
/***************************** Include Files *********************************/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "xil_io.h"
|
||||
#include "xil_exception.h"
|
||||
#include "xparameters.h"
|
||||
#include "xil_cache.h"
|
||||
#include "xil_printf.h"
|
||||
#include "xil_types.h"
|
||||
#include "xscugic.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_SCUGIC_0_DEVICE_ID
|
||||
#define INTC_DEVICE_INT_ID 0x0E
|
||||
|
||||
/**************************** Type Definitions *******************************/
|
||||
|
||||
/***************** Macros (Inline Functions) Definitions *********************/
|
||||
|
||||
/************************** Function Prototypes ******************************/
|
||||
int ScuGicExample(u16 DeviceId);
|
||||
int SetUpInterruptSystem(XScuGic *XScuGicInstancePtr);
|
||||
void DeviceDriverHandler(void *CallbackRef);
|
||||
|
||||
/************************** Variable Definitions *****************************/
|
||||
|
||||
XScuGic InterruptController; /* Instance of the Interrupt Controller */
|
||||
static XScuGic_Config *GicConfig; /* The configuration parameters of the
|
||||
controller */
|
||||
|
||||
/*
|
||||
* Create a shared variable to be used by the main thread of processing and
|
||||
* the interrupt processing
|
||||
*/
|
||||
volatile static int InterruptProcessed = FALSE;
|
||||
|
||||
static void AssertPrint(const char8 *FilenamePtr, s32 LineNumber){
|
||||
xil_printf("ASSERT: File Name: %s ", FilenamePtr);
|
||||
xil_printf("Line Number: %d\r\n",LineNumber);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* 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;
|
||||
|
||||
|
||||
/*
|
||||
* Setup an assert call back to get some info if we assert.
|
||||
*/
|
||||
Xil_AssertSetCallback(AssertPrint);
|
||||
|
||||
xil_printf("GIC Example Test\r\n");
|
||||
|
||||
/*
|
||||
* Run the Gic example , specify the Device ID generated in xparameters.h
|
||||
*/
|
||||
Status = ScuGicExample(INTC_DEVICE_ID);
|
||||
if (Status != XST_SUCCESS) {
|
||||
xil_printf("GIC Example Test Failed\r\n");
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
xil_printf("Successfully ran GIC Example Test\r\n");
|
||||
return XST_SUCCESS;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* This function is an example of how to use the interrupt controller driver
|
||||
* (XScuGic) 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 ScuGicExample(u16 DeviceId)
|
||||
{
|
||||
int Status;
|
||||
|
||||
/*
|
||||
* Initialize the interrupt controller driver so that it is ready to
|
||||
* use.
|
||||
*/
|
||||
GicConfig = XScuGic_LookupConfig(DeviceId);
|
||||
if (NULL == GicConfig) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
Status = XScuGic_CfgInitialize(&InterruptController, GicConfig,
|
||||
GicConfig->CpuBaseAddress);
|
||||
if (Status != XST_SUCCESS) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Perform a self-test to ensure that the hardware was built
|
||||
* correctly
|
||||
*/
|
||||
Status = XScuGic_SelfTest(&InterruptController);
|
||||
if (Status != XST_SUCCESS) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Setup the Interrupt System
|
||||
*/
|
||||
Status = SetUpInterruptSystem(&InterruptController);
|
||||
if (Status != XST_SUCCESS) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
/*
|
||||
* 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 = XScuGic_Connect(&InterruptController, INTC_DEVICE_INT_ID,
|
||||
(Xil_ExceptionHandler)DeviceDriverHandler,
|
||||
(void *)&InterruptController);
|
||||
|
||||
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
|
||||
*/
|
||||
XScuGic_Enable(&InterruptController, INTC_DEVICE_INT_ID);
|
||||
|
||||
/*
|
||||
* Simulate the Interrupt
|
||||
*/
|
||||
Status = XScuGic_SoftwareIntr(&InterruptController,
|
||||
INTC_DEVICE_INT_ID,
|
||||
XSCUGIC_SPI_CPU0_MASK);
|
||||
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 XScuGicInstancePtr is the instance of the interrupt controller
|
||||
* that needs to be worked on.
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
****************************************************************************/
|
||||
int SetUpInterruptSystem(XScuGic *XScuGicInstancePtr)
|
||||
{
|
||||
|
||||
/*
|
||||
* Connect the interrupt controller interrupt handler to the hardware
|
||||
* interrupt handling logic in the ARM processor.
|
||||
*/
|
||||
Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT,
|
||||
(Xil_ExceptionHandler) XScuGic_InterruptHandler,
|
||||
XScuGicInstancePtr);
|
||||
|
||||
/*
|
||||
* Enable interrupts in the ARM
|
||||
*/
|
||||
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 XScuGic driver. It was given to the XScuGic
|
||||
* driver in the XScuGic_Connect() function call. It is typically
|
||||
* a pointer to the device driver instance variable.
|
||||
* In this example, we do not care about the callback
|
||||
* reference, so we passed it a 0 when connecting the handler to
|
||||
* the XScuGic 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,389 @@
|
|||
/* $Id: xscugic_low_level_example.c,v 1.1.2.2 2011/03/23 07:46:42 sadanan Exp $ */
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2010 - 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
|
||||
* XILINX 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 xscugic_low_level_example.c
|
||||
*
|
||||
* This file contains a design example using the low level driver, interface
|
||||
* of the Interrupt Controller driver.
|
||||
*
|
||||
* This example shows the use of the Interrupt Controller with the ARM
|
||||
* processor.
|
||||
*
|
||||
* @note
|
||||
*
|
||||
* none
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* MODIFICATION HISTORY:
|
||||
*
|
||||
* Ver Who Date Changes
|
||||
* ----- ---- -------- ---------------------------------------------------------
|
||||
* 1.00a drg 01/30/10 First release
|
||||
* </pre>
|
||||
******************************************************************************/
|
||||
|
||||
/***************************** Include Files *********************************/
|
||||
|
||||
#include <stdio.h>
|
||||
#include "xparameters.h"
|
||||
#include "xil_exception.h"
|
||||
#include "xscugic_hw.h"
|
||||
#include "xil_printf.h"
|
||||
#include "xstatus.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 CPU_BASEADDR XPAR_SCUGIC_0_CPU_BASEADDR
|
||||
#define DIST_BASEADDR XPAR_SCUGIC_0_DIST_BASEADDR
|
||||
|
||||
|
||||
#define GIC_DEVICE_INT_MASK 0x02010003 /* Bit [25:24] Target list filter
|
||||
Bit [23:16] 16 = Target CPU iface 0
|
||||
Bit [3:0] identifies the SFI */
|
||||
|
||||
/**************************** Type Definitions *******************************/
|
||||
|
||||
/***************** Macros (Inline Functions) Definitions *********************/
|
||||
|
||||
/************************** Function Prototypes ******************************/
|
||||
|
||||
static int ScuGicLowLevelExample(u32 CpuBaseAddress, u32 DistBaseAddress);
|
||||
|
||||
void SetupInterruptSystem();
|
||||
|
||||
void LowInterruptHandler(void *CallbackRef);
|
||||
|
||||
static void GicDistInit(u32 BaseAddress);
|
||||
|
||||
static void GicCPUInit(u32 BaseAddress);
|
||||
|
||||
|
||||
/************************** Variable Definitions *****************************/
|
||||
|
||||
/*
|
||||
* Create a shared variable to be used by the main thread of processing and
|
||||
* the interrupt processing
|
||||
*/
|
||||
volatile static u32 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
|
||||
*/
|
||||
xil_printf("Low Level GIC Example Test\r\n");
|
||||
Status = ScuGicLowLevelExample(CPU_BASEADDR, DIST_BASEADDR);
|
||||
if (Status != XST_SUCCESS) {
|
||||
xil_printf("Low Level GIC Example Test Failed\r\n");
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
xil_printf("Successfully ran Low Level GIC Example Test\r\n");
|
||||
|
||||
return XST_SUCCESS;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* This function is an example of how to use the interrupt controller driver
|
||||
* (XScuGic) 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 CpuBaseAddress is Base Address of the Interrupt Controller
|
||||
* Device
|
||||
*
|
||||
* @return XST_SUCCESS to indicate success, otherwise XST_FAILURE
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
******************************************************************************/
|
||||
static int ScuGicLowLevelExample(u32 CpuBaseAddress, u32 DistBaseAddress)
|
||||
{
|
||||
|
||||
|
||||
GicDistInit(DistBaseAddress);
|
||||
|
||||
GicCPUInit(CpuBaseAddress);
|
||||
|
||||
/*
|
||||
* This step is processor specific, connect the handler for the
|
||||
* interrupt controller to the interrupt source for the processor
|
||||
*/
|
||||
SetupInterruptSystem();
|
||||
|
||||
/*
|
||||
* Enable the software interrupts only.
|
||||
*/
|
||||
XScuGic_WriteReg(DistBaseAddress, XSCUGIC_ENABLE_SET_OFFSET, 0x0000FFFF);
|
||||
|
||||
/*
|
||||
* Cause (simulate) an interrupt so the handler will be called.
|
||||
* This is done by changing the interrupt source to be software driven,
|
||||
* then set a bit which simulates an interrupt.
|
||||
*/
|
||||
XScuGic_WriteReg(DistBaseAddress, XSCUGIC_SFI_TRIG_OFFSET, GIC_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 != 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return XST_SUCCESS;
|
||||
}
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* This function connects the interrupt handler of the interrupt controller to
|
||||
* the processor. This function is separate 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(void)
|
||||
{
|
||||
/*
|
||||
* Connect the interrupt controller interrupt handler to the hardware
|
||||
* interrupt handling logic in the ARM processor.
|
||||
*/
|
||||
Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_IRQ_INT,
|
||||
(Xil_ExceptionHandler) LowInterruptHandler,
|
||||
(void *)CPU_BASEADDR);
|
||||
|
||||
/*
|
||||
* Enable interrupts in the ARM
|
||||
*/
|
||||
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 XScuGic driver. It was given to the XScuGic driver in the
|
||||
* XScuGic_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
|
||||
* XScuGic driver and we make no use of it here.
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
******************************************************************************/
|
||||
void LowInterruptHandler(void *CallbackRef)
|
||||
{
|
||||
u32 BaseAddress;
|
||||
u32 IntID;
|
||||
|
||||
|
||||
if (NULL == CallbackRef) {
|
||||
return;
|
||||
}
|
||||
|
||||
BaseAddress = (u32)CallbackRef;
|
||||
|
||||
/*
|
||||
* Read the int_ack register to identify the interrupt and
|
||||
* make sure it is valid.
|
||||
*/
|
||||
IntID = XScuGic_ReadReg(BaseAddress, XSCUGIC_INT_ACK_OFFSET) &
|
||||
XSCUGIC_ACK_INTID_MASK;
|
||||
if(XSCUGIC_MAX_NUM_INTR_INPUTS < IntID){
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* If the interrupt is shared, do some locking here if there are
|
||||
* multiple processors.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Execute the ISR. For this example set the global to 1.
|
||||
* The software trigger is cleared by the ACK.
|
||||
*/
|
||||
InterruptProcessed = 1;
|
||||
|
||||
/*
|
||||
* Write to the EOI register, we are all done here.
|
||||
* Let this function return, the boot code will restore the stack.
|
||||
*/
|
||||
XScuGic_WriteReg(BaseAddress, XSCUGIC_EOI_OFFSET, IntID);
|
||||
}
|
||||
|
||||
|
||||
static void GicDistInit(u32 BaseAddress)
|
||||
{
|
||||
u32 Int_Id;
|
||||
|
||||
XScuGic_WriteReg(BaseAddress, XSCUGIC_DIST_EN_OFFSET, 0UL);
|
||||
|
||||
/*
|
||||
* Set the security domains in the int_security registers for non-secure interrupts
|
||||
* All are secure, so leave at the default. Set to 1 for non-secure interrupts.
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* For the Shared Peripheral Interrupts INT_ID[MAX..32], set:
|
||||
*/
|
||||
|
||||
/*
|
||||
* 1. The trigger mode in the int_config register
|
||||
*/
|
||||
for(Int_Id = 32; Int_Id<XSCUGIC_MAX_NUM_INTR_INPUTS;Int_Id+=16) {
|
||||
/*
|
||||
* Each INT_ID uses two bits, or 16 INT_ID per register
|
||||
* Set them all to be level sensitive, active HIGH.
|
||||
*/
|
||||
XScuGic_WriteReg(BaseAddress,
|
||||
XSCUGIC_INT_CFG_OFFSET + (Int_Id * 4)/16, 0UL);
|
||||
}
|
||||
|
||||
|
||||
#define DEFAULT_PRIORITY 0xa0a0a0a0UL
|
||||
#define DEFAULT_TARGET 0x01010101UL
|
||||
for(Int_Id = 0; Int_Id < XSCUGIC_MAX_NUM_INTR_INPUTS; Int_Id+=4){
|
||||
/*
|
||||
* 2. The priority using int the priority_level register
|
||||
* The priority_level and spi_target registers use one byte
|
||||
* per INT_ID.
|
||||
* Write a default value that can be changed elsewhere.
|
||||
*/
|
||||
XScuGic_WriteReg(BaseAddress,
|
||||
XSCUGIC_PRIORITY_OFFSET +((Int_Id *4)/4),
|
||||
DEFAULT_PRIORITY);
|
||||
}
|
||||
|
||||
for(Int_Id = 32; Int_Id<XSCUGIC_MAX_NUM_INTR_INPUTS;Int_Id+=4){
|
||||
/*
|
||||
* 3. The CPU interface in the spi_target register
|
||||
*/
|
||||
XScuGic_WriteReg(BaseAddress,
|
||||
XSCUGIC_SPI_TARGET_OFFSET +((Int_Id *4)/4),
|
||||
DEFAULT_TARGET);
|
||||
}
|
||||
|
||||
for(Int_Id = 0; Int_Id<XSCUGIC_MAX_NUM_INTR_INPUTS;Int_Id+=32){
|
||||
/*
|
||||
* 4. Enable the SPI using the enable_set register.
|
||||
* Leave all disabled for now.
|
||||
*/
|
||||
XScuGic_WriteReg(BaseAddress,
|
||||
XSCUGIC_DISABLE_OFFSET +((Int_Id *4)/32), 0xFFFFFFFFUL);
|
||||
|
||||
}
|
||||
|
||||
XScuGic_WriteReg(BaseAddress, XSCUGIC_DIST_EN_OFFSET, 0x01UL);
|
||||
}
|
||||
|
||||
static void GicCPUInit(u32 BaseAddress)
|
||||
{
|
||||
/*
|
||||
* Program the priority mask of the CPU using the Priority mask register
|
||||
*/
|
||||
XScuGic_WriteReg(BaseAddress, XSCUGIC_CPU_PRIOR_OFFSET, 0xF0);
|
||||
|
||||
|
||||
/*
|
||||
* If the CPU operates in both security domains, set parameters in the control_s register.
|
||||
* 1. Set FIQen=1 to use FIQ for secure interrupts,
|
||||
* 2. Program the AckCtl bit
|
||||
* 3. Program the SBPR bit to select the binary pointer behavior
|
||||
* 4. Set EnableS = 1 to enable secure interrupts
|
||||
* 5. Set EnbleNS = 1 to enable non secure interrupts
|
||||
*/
|
||||
|
||||
/*
|
||||
* If the CPU operates only in the secure domain, setup the control_s register.
|
||||
* 1. Set FIQen=1,
|
||||
* 2. Set EnableS=1, to enable the CPU interface to signal secure interrupts.
|
||||
*/
|
||||
XScuGic_WriteReg(BaseAddress, XSCUGIC_CONTROL_OFFSET, 0x01);
|
||||
|
||||
}
|
|
@ -0,0 +1,242 @@
|
|||
/* $Id: xintc_tapp_example.c,v 1.1.4.1 2010/09/17 05:32:46 svemula Exp $ */
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2011 - 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
|
||||
* XILINX 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 xscugic_tapp_example.c
|
||||
*
|
||||
* This file contains a self test example using the Interrupt Controller driver
|
||||
* (XScuGic) 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.
|
||||
*
|
||||
* 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 sdm 05/29/11 Created for Test App Integration
|
||||
* </pre>
|
||||
******************************************************************************/
|
||||
|
||||
/***************************** Include Files *********************************/
|
||||
|
||||
#include "xparameters.h"
|
||||
#include "xstatus.h"
|
||||
#include "xscugic.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_SCUGIC_SINGLE_DEVICE_ID
|
||||
#endif
|
||||
|
||||
/**************************** Type Definitions *******************************/
|
||||
|
||||
|
||||
/***************** Macros (Inline Functions) Definitions *********************/
|
||||
|
||||
|
||||
/************************** Function Prototypes ******************************/
|
||||
|
||||
int ScuGicSelfTestExample(u16 DeviceId);
|
||||
int ScuGicInterruptSetup(XScuGic *IntcInstancePtr, u16 DeviceId);
|
||||
|
||||
/************************** Variable Definitions *****************************/
|
||||
|
||||
|
||||
static XScuGic IntcInstance; /* 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 Scu Gic Intc example, specify the Device ID generated in
|
||||
* xparameters.h.
|
||||
*/
|
||||
Status = ScuGicSelfTestExample(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 (XScuGic) 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 ScuGicSelfTestExample(u16 DeviceId)
|
||||
{
|
||||
int Status;
|
||||
static XScuGic_Config *GicConfig;
|
||||
|
||||
/*
|
||||
* Initialize the interrupt controller driver so that it is ready to
|
||||
* use.
|
||||
*/
|
||||
GicConfig = XScuGic_LookupConfig(DeviceId);
|
||||
if (NULL == GicConfig) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
Status = XScuGic_CfgInitialize(&IntcInstance, GicConfig,
|
||||
GicConfig->CpuBaseAddress);
|
||||
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 ScuGicInterruptSetup(XScuGic *IntcInstancePtr, u16 DeviceId)
|
||||
{
|
||||
|
||||
int Status;
|
||||
static XScuGic_Config *GicConfig;
|
||||
|
||||
/*
|
||||
* Initialize the interrupt controller driver so that it is ready to
|
||||
* use.
|
||||
*/
|
||||
GicConfig = XScuGic_LookupConfig(DeviceId);
|
||||
if (NULL == GicConfig) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
Status = XScuGic_CfgInitialize(IntcInstancePtr, GicConfig,
|
||||
GicConfig->CpuBaseAddress);
|
||||
if (Status != XST_SUCCESS) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize the exception table.
|
||||
*/
|
||||
Xil_ExceptionInit();
|
||||
|
||||
|
||||
/*
|
||||
* Connect the interrupt controller interrupt handler to the hardware
|
||||
* interrupt handling logic in the processor.
|
||||
*/
|
||||
Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_IRQ_INT,
|
||||
(Xil_ExceptionHandler)XScuGic_InterruptHandler,
|
||||
IntcInstancePtr);
|
||||
|
||||
/*
|
||||
* Enable exceptions.
|
||||
*/
|
||||
Xil_ExceptionEnable();
|
||||
|
||||
|
||||
return XST_SUCCESS;
|
||||
|
||||
}
|
40
XilinxProcessorIPLib/drivers/scugic/src/Makefile
Normal file
40
XilinxProcessorIPLib/drivers/scugic/src/Makefile
Normal file
|
@ -0,0 +1,40 @@
|
|||
COMPILER=
|
||||
ARCHIVER=
|
||||
CP=cp
|
||||
COMPILER_FLAGS=
|
||||
EXTRA_COMPILER_FLAGS=
|
||||
LIB=libxil.a
|
||||
|
||||
CC_FLAGS = $(COMPILER_FLAGS)
|
||||
ECC_FLAGS = $(EXTRA_COMPILER_FLAGS)
|
||||
|
||||
RELEASEDIR=../../../lib
|
||||
INCLUDEDIR=../../../include
|
||||
INCLUDES=-I./. -I${INCLUDEDIR}
|
||||
|
||||
OUTS = *.o
|
||||
|
||||
LIBSOURCES:=*.c
|
||||
INCLUDEFILES:=*.h
|
||||
|
||||
OBJECTS = $(addsuffix .o, $(basename $(wildcard *.c)))
|
||||
|
||||
libs: banner scugic_libs clean
|
||||
|
||||
%.o: %.c
|
||||
${COMPILER} $(CC_FLAGS) $(ECC_FLAGS) $(INCLUDES) -o $@ $<
|
||||
|
||||
banner:
|
||||
echo "Compiling scugic"
|
||||
|
||||
scugic_libs: ${OBJECTS}
|
||||
$(ARCHIVER) -r ${RELEASEDIR}/${LIB} ${OBJECTS}
|
||||
|
||||
.PHONY: include
|
||||
include: scugic_includes
|
||||
|
||||
scugic_includes:
|
||||
${CP} ${INCLUDEFILES} ${INCLUDEDIR}
|
||||
|
||||
clean:
|
||||
rm -rf ${OBJECTS}
|
712
XilinxProcessorIPLib/drivers/scugic/src/xscugic.c
Normal file
712
XilinxProcessorIPLib/drivers/scugic/src/xscugic.c
Normal file
|
@ -0,0 +1,712 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2010 - 2015 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
|
||||
* XILINX 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 xscugic.c
|
||||
*
|
||||
* Contains required functions for the XScuGic driver for the Interrupt
|
||||
* Controller. See xscugic.h for a detailed description of the driver.
|
||||
*
|
||||
* <pre>
|
||||
* MODIFICATION HISTORY:
|
||||
*
|
||||
* Ver Who Date Changes
|
||||
* ----- ---- -------- --------------------------------------------------------
|
||||
* 1.00a drg 01/19/10 First release
|
||||
* 1.01a sdm 11/09/11 Changes are made in function XScuGic_CfgInitialize. Since
|
||||
* "Config" entry is now made as pointer in the XScuGic
|
||||
* structure, necessary changes are made.
|
||||
* The HandlerTable can now be populated through the low
|
||||
* level routine XScuGic_RegisterHandler added in this
|
||||
* release. Hence necessary checks are added not to
|
||||
* overwrite the HandlerTable entriesin function
|
||||
* XScuGic_CfgInitialize.
|
||||
* 1.03a srt 02/27/13 Added APIs
|
||||
* - XScuGic_SetPriTrigTypeByDistAddr()
|
||||
* - XScuGic_GetPriTrigTypeByDistAddr()
|
||||
* Removed Offset calculation macros, defined in _hw.h
|
||||
* (CR 702687)
|
||||
* Added support to direct interrupts to the appropriate CPU. Earlier
|
||||
* interrupts were directed to CPU1 (hard coded). Now depending
|
||||
* upon the CPU selected by the user (xparameters.h), interrupts
|
||||
* will be directed to the relevant CPU. This fixes CR 699688.
|
||||
*
|
||||
* 1.04a hk 05/04/13 Assigned EffectiveAddr to CpuBaseAddress in
|
||||
* XScuGic_CfgInitialize. Fix for CR#704400 to remove warnings.
|
||||
* Moved functions XScuGic_SetPriTrigTypeByDistAddr and
|
||||
* XScuGic_GetPriTrigTypeByDistAddr to xscugic_hw.c.
|
||||
* This is fix for CR#705621.
|
||||
* 1.06a asa 16/11/13 Fix for CR#749178. Assignment for EffectiveAddr
|
||||
* in function XScuGic_CfgInitialize is removed as it was
|
||||
* a bug.
|
||||
* 3.00 kvn 02/13/14 Modified code for MISRA-C:2012 compliance.
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
/***************************** Include Files *********************************/
|
||||
#include "xil_types.h"
|
||||
#include "xil_assert.h"
|
||||
#include "xscugic.h"
|
||||
#include "xparameters.h"
|
||||
|
||||
/************************** Constant Definitions *****************************/
|
||||
|
||||
|
||||
/**************************** Type Definitions *******************************/
|
||||
|
||||
|
||||
/***************** Macros (Inline Functions) Definitions *********************/
|
||||
|
||||
/************************** Variable Definitions *****************************/
|
||||
|
||||
/************************** Function Prototypes ******************************/
|
||||
|
||||
static void StubHandler(void *CallBackRef);
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* DistributorInit initializes the distributor of the GIC. The
|
||||
* initialization entails:
|
||||
*
|
||||
* - Write the trigger mode, priority and target CPU
|
||||
* - All interrupt sources are disabled
|
||||
* - Enable the distributor
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XScuGic instance.
|
||||
* @param CpuID is the Cpu ID to be initialized.
|
||||
*
|
||||
* @return None
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
******************************************************************************/
|
||||
static void DistributorInit(XScuGic *InstancePtr, u32 CpuID)
|
||||
{
|
||||
u32 Int_Id;
|
||||
u32 LocalCpuID = CpuID;
|
||||
|
||||
#if USE_AMP==1
|
||||
#warning "Building GIC for AMP"
|
||||
|
||||
/*
|
||||
* The distrubutor should not be initialized by FreeRTOS in the case of
|
||||
* AMP -- it is assumed that Linux is the master of this device in that
|
||||
* case.
|
||||
*/
|
||||
return;
|
||||
#endif
|
||||
Xil_AssertVoid(InstancePtr != NULL);
|
||||
XScuGic_DistWriteReg(InstancePtr, XSCUGIC_DIST_EN_OFFSET, 0U);
|
||||
|
||||
/*
|
||||
* Set the security domains in the int_security registers for
|
||||
* non-secure interrupts
|
||||
* All are secure, so leave at the default. Set to 1 for non-secure
|
||||
* interrupts.
|
||||
*/
|
||||
|
||||
/*
|
||||
* For the Shared Peripheral Interrupts INT_ID[MAX..32], set:
|
||||
*/
|
||||
|
||||
/*
|
||||
* 1. The trigger mode in the int_config register
|
||||
* Only write to the SPI interrupts, so start at 32
|
||||
*/
|
||||
for (Int_Id = 32U; Int_Id < XSCUGIC_MAX_NUM_INTR_INPUTS; Int_Id=Int_Id+16U) {
|
||||
/*
|
||||
* Each INT_ID uses two bits, or 16 INT_ID per register
|
||||
* Set them all to be level sensitive, active HIGH.
|
||||
*/
|
||||
XScuGic_DistWriteReg(InstancePtr,
|
||||
XSCUGIC_INT_CFG_OFFSET_CALC(Int_Id),
|
||||
0U);
|
||||
}
|
||||
|
||||
|
||||
#define DEFAULT_PRIORITY 0xa0a0a0a0U
|
||||
for (Int_Id = 0U; Int_Id < XSCUGIC_MAX_NUM_INTR_INPUTS; Int_Id=Int_Id+4U) {
|
||||
/*
|
||||
* 2. The priority using int the priority_level register
|
||||
* The priority_level and spi_target registers use one byte per
|
||||
* INT_ID.
|
||||
* Write a default value that can be changed elsewhere.
|
||||
*/
|
||||
XScuGic_DistWriteReg(InstancePtr,
|
||||
XSCUGIC_PRIORITY_OFFSET_CALC(Int_Id),
|
||||
DEFAULT_PRIORITY);
|
||||
}
|
||||
|
||||
for (Int_Id = 32U; Int_Id<XSCUGIC_MAX_NUM_INTR_INPUTS;Int_Id=Int_Id+4U) {
|
||||
/*
|
||||
* 3. The CPU interface in the spi_target register
|
||||
* Only write to the SPI interrupts, so start at 32
|
||||
*/
|
||||
LocalCpuID |= LocalCpuID << 8U;
|
||||
LocalCpuID |= LocalCpuID << 16U;
|
||||
|
||||
XScuGic_DistWriteReg(InstancePtr,
|
||||
XSCUGIC_SPI_TARGET_OFFSET_CALC(Int_Id),
|
||||
LocalCpuID);
|
||||
}
|
||||
|
||||
for (Int_Id = 0U; Int_Id<XSCUGIC_MAX_NUM_INTR_INPUTS;Int_Id=Int_Id+32U) {
|
||||
/*
|
||||
* 4. Enable the SPI using the enable_set register. Leave all
|
||||
* disabled for now.
|
||||
*/
|
||||
XScuGic_DistWriteReg(InstancePtr,
|
||||
XSCUGIC_EN_DIS_OFFSET_CALC(XSCUGIC_DISABLE_OFFSET, Int_Id),
|
||||
0xFFFFFFFFU);
|
||||
|
||||
}
|
||||
|
||||
XScuGic_DistWriteReg(InstancePtr, XSCUGIC_DIST_EN_OFFSET,
|
||||
XSCUGIC_EN_INT_MASK);
|
||||
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* CPUInitialize initializes the CPU Interface of the GIC. The initialization entails:
|
||||
*
|
||||
* - Set the priority of the CPU
|
||||
* - Enable the CPU interface
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XScuGic instance.
|
||||
*
|
||||
* @return None
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
******************************************************************************/
|
||||
static void CPUInitialize(XScuGic *InstancePtr)
|
||||
{
|
||||
/*
|
||||
* Program the priority mask of the CPU using the Priority mask register
|
||||
*/
|
||||
XScuGic_CPUWriteReg(InstancePtr, XSCUGIC_CPU_PRIOR_OFFSET, 0xF0U);
|
||||
|
||||
|
||||
/*
|
||||
* If the CPU operates in both security domains, set parameters in the
|
||||
* control_s register.
|
||||
* 1. Set FIQen=1 to use FIQ for secure interrupts,
|
||||
* 2. Program the AckCtl bit
|
||||
* 3. Program the SBPR bit to select the binary pointer behavior
|
||||
* 4. Set EnableS = 1 to enable secure interrupts
|
||||
* 5. Set EnbleNS = 1 to enable non secure interrupts
|
||||
*/
|
||||
|
||||
/*
|
||||
* If the CPU operates only in the secure domain, setup the
|
||||
* control_s register.
|
||||
* 1. Set FIQen=1,
|
||||
* 2. Set EnableS=1, to enable the CPU interface to signal secure interrupts.
|
||||
* Only enable the IRQ output unless secure interrupts are needed.
|
||||
*/
|
||||
XScuGic_CPUWriteReg(InstancePtr, XSCUGIC_CONTROL_OFFSET, 0x07U);
|
||||
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* CfgInitialize a specific interrupt controller instance/driver. The
|
||||
* initialization entails:
|
||||
*
|
||||
* - Initialize fields of the XScuGic structure
|
||||
* - Initial vector table with stub function calls
|
||||
* - All interrupt sources are disabled
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XScuGic instance.
|
||||
* @param ConfigPtr is a pointer to a config table for the particular
|
||||
* device this driver is associated with.
|
||||
* @param EffectiveAddr is the device base address in the virtual memory
|
||||
* address space. The caller is responsible for keeping the address
|
||||
* mapping from EffectiveAddr to the device physical base address
|
||||
* unchanged once this function is invoked. Unexpected errors may
|
||||
* occur if the address mapping changes after this function is
|
||||
* called. If address translation is not used, use
|
||||
* Config->BaseAddress for this parameters, passing the physical
|
||||
* address instead.
|
||||
*
|
||||
* @return
|
||||
* - XST_SUCCESS if initialization was successful
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
******************************************************************************/
|
||||
s32 XScuGic_CfgInitialize(XScuGic *InstancePtr,
|
||||
XScuGic_Config *ConfigPtr,
|
||||
u32 EffectiveAddr)
|
||||
{
|
||||
u32 Int_Id;
|
||||
u32 Cpu_Id = (u32)XPAR_CPU_ID + (u32)1;
|
||||
(void) EffectiveAddr;
|
||||
|
||||
Xil_AssertNonvoid(InstancePtr != NULL);
|
||||
Xil_AssertNonvoid(ConfigPtr != NULL);
|
||||
|
||||
if(InstancePtr->IsReady != XIL_COMPONENT_IS_READY) {
|
||||
|
||||
InstancePtr->IsReady = 0;
|
||||
InstancePtr->Config = ConfigPtr;
|
||||
|
||||
|
||||
for (Int_Id = 0U; Int_Id<XSCUGIC_MAX_NUM_INTR_INPUTS;Int_Id++) {
|
||||
/*
|
||||
* Initalize the handler to point to a stub to handle an
|
||||
* interrupt which has not been connected to a handler. Only
|
||||
* initialize it if the handler is 0 which means it was not
|
||||
* initialized statically by the tools/user. Set the callback
|
||||
* reference to this instance so that unhandled interrupts
|
||||
* can be tracked.
|
||||
*/
|
||||
if ((InstancePtr->Config->HandlerTable[Int_Id].Handler == NULL)) {
|
||||
InstancePtr->Config->HandlerTable[Int_Id].Handler =
|
||||
StubHandler;
|
||||
}
|
||||
InstancePtr->Config->HandlerTable[Int_Id].CallBackRef =
|
||||
InstancePtr;
|
||||
}
|
||||
|
||||
DistributorInit(InstancePtr, Cpu_Id);
|
||||
CPUInitialize(InstancePtr);
|
||||
|
||||
InstancePtr->IsReady = XIL_COMPONENT_IS_READY;
|
||||
}
|
||||
|
||||
return XST_SUCCESS;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* Makes the connection between the Int_Id of the interrupt source and the
|
||||
* associated handler that is to run when the interrupt is recognized. The
|
||||
* argument provided in this call as the Callbackref is used as the argument
|
||||
* for the handler when it is called.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XScuGic instance.
|
||||
* @param Int_Id contains the ID of the interrupt source and should be
|
||||
* in the range of 0 to XSCUGIC_MAX_NUM_INTR_INPUTS - 1
|
||||
* @param Handler to the handler for that interrupt.
|
||||
* @param CallBackRef is the callback reference, usually the instance
|
||||
* pointer of the connecting driver.
|
||||
*
|
||||
* @return
|
||||
*
|
||||
* - XST_SUCCESS if the handler was connected correctly.
|
||||
*
|
||||
* @note
|
||||
*
|
||||
* WARNING: The handler provided as an argument will overwrite any handler
|
||||
* that was previously connected.
|
||||
*
|
||||
****************************************************************************/
|
||||
s32 XScuGic_Connect(XScuGic *InstancePtr, u32 Int_Id,
|
||||
Xil_InterruptHandler Handler, void *CallBackRef)
|
||||
{
|
||||
/*
|
||||
* Assert the arguments
|
||||
*/
|
||||
Xil_AssertNonvoid(InstancePtr != NULL);
|
||||
Xil_AssertNonvoid(Int_Id < XSCUGIC_MAX_NUM_INTR_INPUTS);
|
||||
Xil_AssertNonvoid(Handler != NULL);
|
||||
Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
|
||||
|
||||
/*
|
||||
* The Int_Id is used as an index into the table to select the proper
|
||||
* handler
|
||||
*/
|
||||
InstancePtr->Config->HandlerTable[Int_Id].Handler = Handler;
|
||||
InstancePtr->Config->HandlerTable[Int_Id].CallBackRef = CallBackRef;
|
||||
|
||||
return XST_SUCCESS;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* Updates the interrupt table with the Null Handler and NULL arguments at the
|
||||
* location pointed at by the Int_Id. This effectively disconnects that interrupt
|
||||
* source from any handler. The interrupt is disabled also.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XScuGic instance to be worked on.
|
||||
* @param Int_Id contains the ID of the interrupt source and should
|
||||
* be in the range of 0 to XSCUGIC_MAX_NUM_INTR_INPUTS - 1
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
****************************************************************************/
|
||||
void XScuGic_Disconnect(XScuGic *InstancePtr, u32 Int_Id)
|
||||
{
|
||||
u32 Mask;
|
||||
|
||||
/*
|
||||
* Assert the arguments
|
||||
*/
|
||||
Xil_AssertVoid(InstancePtr != NULL);
|
||||
Xil_AssertVoid(Int_Id < XSCUGIC_MAX_NUM_INTR_INPUTS);
|
||||
Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
|
||||
|
||||
/*
|
||||
* The Int_Id is used to create the appropriate mask for the
|
||||
* desired bit position. Int_Id currently limited to 0 - 31
|
||||
*/
|
||||
Mask = 0x00000001U << (Int_Id % 32U);
|
||||
|
||||
/*
|
||||
* Disable the interrupt such that it won't occur while disconnecting
|
||||
* the handler, only disable the specified interrupt id without modifying
|
||||
* the other interrupt ids
|
||||
*/
|
||||
XScuGic_DistWriteReg(InstancePtr, (u32)XSCUGIC_DISABLE_OFFSET +
|
||||
((Int_Id / 32U) * 4U), Mask);
|
||||
|
||||
/*
|
||||
* Disconnect the handler and connect a stub, the callback reference
|
||||
* must be set to this instance to allow unhandled interrupts to be
|
||||
* tracked
|
||||
*/
|
||||
InstancePtr->Config->HandlerTable[Int_Id].Handler = StubHandler;
|
||||
InstancePtr->Config->HandlerTable[Int_Id].CallBackRef = InstancePtr;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* Enables the interrupt source provided as the argument Int_Id. Any pending
|
||||
* interrupt condition for the specified Int_Id will occur after this function is
|
||||
* called.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XScuGic instance.
|
||||
* @param Int_Id contains the ID of the interrupt source and should be
|
||||
* in the range of 0 to XSCUGIC_MAX_NUM_INTR_INPUTS - 1
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
****************************************************************************/
|
||||
void XScuGic_Enable(XScuGic *InstancePtr, u32 Int_Id)
|
||||
{
|
||||
u32 Mask;
|
||||
|
||||
/*
|
||||
* Assert the arguments
|
||||
*/
|
||||
Xil_AssertVoid(InstancePtr != NULL);
|
||||
Xil_AssertVoid(Int_Id < XSCUGIC_MAX_NUM_INTR_INPUTS);
|
||||
Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
|
||||
|
||||
/*
|
||||
* The Int_Id is used to create the appropriate mask for the
|
||||
* desired bit position. Int_Id currently limited to 0 - 31
|
||||
*/
|
||||
Mask = 0x00000001U << (Int_Id % 32U);
|
||||
|
||||
/*
|
||||
* Enable the selected interrupt source by setting the
|
||||
* corresponding bit in the Enable Set register.
|
||||
*/
|
||||
XScuGic_DistWriteReg(InstancePtr, (u32)XSCUGIC_ENABLE_SET_OFFSET +
|
||||
((Int_Id / 32U) * 4U), Mask);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* Disables the interrupt source provided as the argument Int_Id such that the
|
||||
* interrupt controller will not cause interrupts for the specified Int_Id. The
|
||||
* interrupt controller will continue to hold an interrupt condition for the
|
||||
* Int_Id, but will not cause an interrupt.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XScuGic instance.
|
||||
* @param Int_Id contains the ID of the interrupt source and should be
|
||||
* in the range of 0 to XSCUGIC_MAX_NUM_INTR_INPUTS - 1
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
****************************************************************************/
|
||||
void XScuGic_Disable(XScuGic *InstancePtr, u32 Int_Id)
|
||||
{
|
||||
u32 Mask;
|
||||
|
||||
/*
|
||||
* Assert the arguments
|
||||
*/
|
||||
Xil_AssertVoid(InstancePtr != NULL);
|
||||
Xil_AssertVoid(Int_Id < XSCUGIC_MAX_NUM_INTR_INPUTS);
|
||||
Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
|
||||
|
||||
/*
|
||||
* The Int_Id is used to create the appropriate mask for the
|
||||
* desired bit position. Int_Id currently limited to 0 - 31
|
||||
*/
|
||||
Mask = 0x00000001U << (Int_Id % 32U);
|
||||
|
||||
/*
|
||||
* Disable the selected interrupt source by setting the
|
||||
* corresponding bit in the IDR.
|
||||
*/
|
||||
XScuGic_DistWriteReg(InstancePtr, (u32)XSCUGIC_DISABLE_OFFSET +
|
||||
((Int_Id / 32U) * 4U), Mask);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* 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. A simulated interrupt allows the interrupt
|
||||
* controller to be tested without any device to drive an interrupt input
|
||||
* signal into it.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XScuGic instance.
|
||||
* @param Int_Id is the software interrupt ID to simulate an interrupt.
|
||||
* @param Cpu_Id is the list of CPUs to send the interrupt.
|
||||
*
|
||||
* @return
|
||||
*
|
||||
* XST_SUCCESS if successful, or XST_FAILURE if the interrupt could not be
|
||||
* simulated
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
******************************************************************************/
|
||||
s32 XScuGic_SoftwareIntr(XScuGic *InstancePtr, u32 Int_Id, u32 Cpu_Id)
|
||||
{
|
||||
u32 Mask;
|
||||
|
||||
/*
|
||||
* Assert the arguments
|
||||
*/
|
||||
Xil_AssertNonvoid(InstancePtr != NULL);
|
||||
Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
|
||||
Xil_AssertNonvoid(Int_Id <= 15U) ;
|
||||
Xil_AssertNonvoid(Cpu_Id <= 255U) ;
|
||||
|
||||
|
||||
/*
|
||||
* The Int_Id is used to create the appropriate mask for the
|
||||
* desired interrupt. Int_Id currently limited to 0 - 15
|
||||
* Use the target list for the Cpu ID.
|
||||
*/
|
||||
Mask = ((Cpu_Id << 16U) | Int_Id) &
|
||||
(XSCUGIC_SFI_TRIG_CPU_MASK | XSCUGIC_SFI_TRIG_INTID_MASK);
|
||||
|
||||
/*
|
||||
* Write to the Software interrupt trigger register. Use the appropriate
|
||||
* CPU Int_Id.
|
||||
*/
|
||||
XScuGic_DistWriteReg(InstancePtr, XSCUGIC_SFI_TRIG_OFFSET, Mask);
|
||||
|
||||
/* Indicate the interrupt was successfully simulated */
|
||||
|
||||
return XST_SUCCESS;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* A stub for the asynchronous callback. The stub is here in case the upper
|
||||
* layers forget to set the handler.
|
||||
*
|
||||
* @param CallBackRef is a pointer to the upper layer callback reference
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
******************************************************************************/
|
||||
static void StubHandler(void *CallBackRef) {
|
||||
/*
|
||||
* verify that the inputs are valid
|
||||
*/
|
||||
Xil_AssertVoid(CallBackRef != NULL);
|
||||
|
||||
/*
|
||||
* Indicate another unhandled interrupt for stats
|
||||
*/
|
||||
((XScuGic *)((void *)CallBackRef))->UnhandledInterrupts++;
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
/**
|
||||
* Sets the interrupt priority and trigger type for the specificd IRQ source.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the instance to be worked on.
|
||||
* @param Int_Id is the IRQ source number to modify
|
||||
* @param Priority is the new priority for the IRQ source. 0 is highest
|
||||
* priority, 0xF8 (248) is lowest. There are 32 priority levels
|
||||
* supported with a step of 8. Hence the supported priorities are
|
||||
* 0, 8, 16, 32, 40 ..., 248.
|
||||
* @param Trigger is the new trigger type for the IRQ source.
|
||||
* Each bit pair describes the configuration for an INT_ID.
|
||||
* SFI Read Only b10 always
|
||||
* PPI Read Only depending on how the PPIs are configured.
|
||||
* b01 Active HIGH level sensitive
|
||||
* b11 Rising edge sensitive
|
||||
* SPI LSB is read only.
|
||||
* b01 Active HIGH level sensitive
|
||||
* b11 Rising edge sensitive/
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
*****************************************************************************/
|
||||
void XScuGic_SetPriorityTriggerType(XScuGic *InstancePtr, u32 Int_Id,
|
||||
u8 Priority, u8 Trigger)
|
||||
{
|
||||
u32 RegValue;
|
||||
u8 LocalPriority;
|
||||
LocalPriority = Priority;
|
||||
|
||||
Xil_AssertVoid(InstancePtr != NULL);
|
||||
Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
|
||||
Xil_AssertVoid(Int_Id < XSCUGIC_MAX_NUM_INTR_INPUTS);
|
||||
Xil_AssertVoid(Trigger <= (u8)XSCUGIC_INT_CFG_MASK);
|
||||
Xil_AssertVoid(LocalPriority <= (u8)XSCUGIC_MAX_INTR_PRIO_VAL);
|
||||
|
||||
/*
|
||||
* Determine the register to write to using the Int_Id.
|
||||
*/
|
||||
RegValue = XScuGic_DistReadReg(InstancePtr,
|
||||
XSCUGIC_PRIORITY_OFFSET_CALC(Int_Id));
|
||||
|
||||
/*
|
||||
* The priority bits are Bits 7 to 3 in GIC Priority Register. This
|
||||
* means the number of priority levels supported are 32 and they are
|
||||
* in steps of 8. The priorities can be 0, 8, 16, 32, 48, ... etc.
|
||||
* The lower order 3 bits are masked before putting it in the register.
|
||||
*/
|
||||
LocalPriority = LocalPriority & (u8)XSCUGIC_INTR_PRIO_MASK;
|
||||
/*
|
||||
* Shift and Mask the correct bits for the priority and trigger in the
|
||||
* register
|
||||
*/
|
||||
RegValue &= ~(XSCUGIC_PRIORITY_MASK << ((Int_Id%4U)*8U));
|
||||
RegValue |= (u32)LocalPriority << ((Int_Id%4U)*8U);
|
||||
|
||||
/*
|
||||
* Write the value back to the register.
|
||||
*/
|
||||
XScuGic_DistWriteReg(InstancePtr, XSCUGIC_PRIORITY_OFFSET_CALC(Int_Id),
|
||||
RegValue);
|
||||
|
||||
/*
|
||||
* Determine the register to write to using the Int_Id.
|
||||
*/
|
||||
RegValue = XScuGic_DistReadReg(InstancePtr,
|
||||
XSCUGIC_INT_CFG_OFFSET_CALC (Int_Id));
|
||||
|
||||
/*
|
||||
* Shift and Mask the correct bits for the priority and trigger in the
|
||||
* register
|
||||
*/
|
||||
RegValue &= ~(XSCUGIC_INT_CFG_MASK << ((Int_Id%16U)*2U));
|
||||
RegValue |= (u32)Trigger << ((Int_Id%16U)*2U);
|
||||
|
||||
/*
|
||||
* Write the value back to the register.
|
||||
*/
|
||||
XScuGic_DistWriteReg(InstancePtr, XSCUGIC_INT_CFG_OFFSET_CALC(Int_Id),
|
||||
RegValue);
|
||||
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
/**
|
||||
* Gets the interrupt priority and trigger type for the specificd IRQ source.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the instance to be worked on.
|
||||
* @param Int_Id is the IRQ source number to modify
|
||||
* @param Priority is a pointer to the value of the priority of the IRQ
|
||||
* source. This is a return value.
|
||||
* @param Trigger is pointer to the value of the trigger of the IRQ
|
||||
* source. This is a return value.
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note None
|
||||
*
|
||||
*****************************************************************************/
|
||||
void XScuGic_GetPriorityTriggerType(XScuGic *InstancePtr, u32 Int_Id,
|
||||
u8 *Priority, u8 *Trigger)
|
||||
{
|
||||
u32 RegValue;
|
||||
|
||||
Xil_AssertVoid(InstancePtr != NULL);
|
||||
Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
|
||||
Xil_AssertVoid(Int_Id < XSCUGIC_MAX_NUM_INTR_INPUTS);
|
||||
Xil_AssertVoid(Priority != NULL);
|
||||
Xil_AssertVoid(Trigger != NULL);
|
||||
|
||||
/*
|
||||
* Determine the register to read to using the Int_Id.
|
||||
*/
|
||||
RegValue = XScuGic_DistReadReg(InstancePtr,
|
||||
XSCUGIC_PRIORITY_OFFSET_CALC(Int_Id));
|
||||
|
||||
/*
|
||||
* Shift and Mask the correct bits for the priority and trigger in the
|
||||
* register
|
||||
*/
|
||||
RegValue = RegValue >> ((Int_Id%4U)*8U);
|
||||
*Priority = (u8)(RegValue & XSCUGIC_PRIORITY_MASK);
|
||||
|
||||
/*
|
||||
* Determine the register to read to using the Int_Id.
|
||||
*/
|
||||
RegValue = XScuGic_DistReadReg(InstancePtr,
|
||||
XSCUGIC_INT_CFG_OFFSET_CALC (Int_Id));
|
||||
|
||||
/*
|
||||
* Shift and Mask the correct bits for the priority and trigger in the
|
||||
* register
|
||||
*/
|
||||
RegValue = RegValue >> ((Int_Id%16U)*2U);
|
||||
|
||||
*Trigger = (u8)(RegValue & XSCUGIC_INT_CFG_MASK);
|
||||
}
|
315
XilinxProcessorIPLib/drivers/scugic/src/xscugic.h
Normal file
315
XilinxProcessorIPLib/drivers/scugic/src/xscugic.h
Normal file
|
@ -0,0 +1,315 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2010 - 2015 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
|
||||
* XILINX 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 xscugic.h
|
||||
*
|
||||
* The generic interrupt controller driver component.
|
||||
*
|
||||
* The interrupt controller driver uses the idea of priority for the various
|
||||
* handlers. Priority is an integer within the range of 1 and 31 inclusive with
|
||||
* default of 1 being the highest priority interrupt source. The priorities
|
||||
* of the various sources can be dynamically altered as needed through
|
||||
* hardware configuration.
|
||||
*
|
||||
* The generic interrupt controller supports the following
|
||||
* features:
|
||||
*
|
||||
* - specific individual interrupt enabling/disabling
|
||||
* - specific individual interrupt acknowledging
|
||||
* - attaching specific callback function to handle interrupt source
|
||||
* - assigning desired priority to interrupt source if default is not
|
||||
* acceptable.
|
||||
*
|
||||
* Details about connecting the interrupt handler of the driver are contained
|
||||
* in the source file specific to interrupt processing, xscugic_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 device ID of the interrupt controller device is used by the driver as a
|
||||
* direct index into the configuration data table. The user should populate the
|
||||
* vector table with handlers and callbacks at run-time using the
|
||||
* XScuGic_Connect() and XScuGic_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
|
||||
* user must use XScuGic_Connect() when the interrupt handler takes an
|
||||
* argument other than the base address.
|
||||
*
|
||||
* <b>Nested Interrupts Processing</b>
|
||||
*
|
||||
* Nested interrupts are not supported by this driver.
|
||||
*
|
||||
* NOTE:
|
||||
* The generic interrupt controller is not a part of the snoop control unit
|
||||
* as indicated by the prefix "scu" in the name of the driver.
|
||||
* It is an independent module in APU.
|
||||
*
|
||||
* <pre>
|
||||
* MODIFICATION HISTORY:
|
||||
*
|
||||
* Ver Who Date Changes
|
||||
* ----- ---- -------- ---------------------------------------------------------
|
||||
* 1.00a drg 01/19/00 First release
|
||||
* 1.01a sdm 11/09/11 The XScuGic and XScuGic_Config structures have changed.
|
||||
* The HandlerTable (of type XScuGic_VectorTableEntry) is
|
||||
* moved to XScuGic_Config structure from XScuGic structure.
|
||||
*
|
||||
* The "Config" entry in XScuGic structure is made as
|
||||
* pointer for better efficiency.
|
||||
*
|
||||
* A new file named as xscugic_hw.c is now added. It is
|
||||
* to implement low level driver routines without using
|
||||
* any xscugic instance pointer. They are useful when the
|
||||
* user wants to use xscugic through device id or
|
||||
* base address. The driver routines provided are explained
|
||||
* below.
|
||||
* XScuGic_DeviceInitialize that takes device id as
|
||||
* argument and initializes the device (without calling
|
||||
* XScuGic_CfgInitialize).
|
||||
* XScuGic_DeviceInterruptHandler that takes device id
|
||||
* as argument and calls appropriate handlers from the
|
||||
* HandlerTable.
|
||||
* XScuGic_RegisterHandler that registers a new handler
|
||||
* by taking xscugic hardware base address as argument.
|
||||
* LookupConfigByBaseAddress is used to return the
|
||||
* corresponding config structure from XScuGic_ConfigTable
|
||||
* based on the scugic base address passed.
|
||||
* 1.02a sdm 12/20/11 Removed AckBeforeService from the XScuGic_Config
|
||||
* structure.
|
||||
* 1.03a srt 02/27/13 Moved Offset calculation macros from *.c and *_hw.c to
|
||||
* *_hw.h
|
||||
* Added APIs
|
||||
* - XScuGic_SetPriTrigTypeByDistAddr()
|
||||
* - XScuGic_GetPriTrigTypeByDistAddr()
|
||||
* (CR 702687)
|
||||
* Added support to direct interrupts to the appropriate CPU. Earlier
|
||||
* interrupts were directed to CPU1 (hard coded). Now depending
|
||||
* upon the CPU selected by the user (xparameters.h), interrupts
|
||||
* will be directed to the relevant CPU. This fixes CR 699688.
|
||||
* 1.04a hk 05/04/13 Assigned EffectiveAddr to CpuBaseAddress in
|
||||
* XScuGic_CfgInitialize. Fix for CR#704400 to remove warnings.
|
||||
* Moved functions XScuGic_SetPriTrigTypeByDistAddr and
|
||||
* XScuGic_GetPriTrigTypeByDistAddr to xscugic_hw.c.
|
||||
* This is fix for CR#705621.
|
||||
* 1.05a hk 06/26/13 Modified tcl to export external interrupts correctly to
|
||||
* xparameters.h. Fix for CR's 690505, 708928 & 719359.
|
||||
* 2.0 adk 12/10/13 Updated as per the New Tcl API's
|
||||
* 2.1 adk 25/04/14 Fixed the CR:789373 changes are made in the driver tcl file.
|
||||
* 3.00 kvn 02/13/15 Modified code for MISRA-C:2012 compliance.
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef XSCUGIC_H /* prevent circular inclusions */
|
||||
#define XSCUGIC_H /* by using protection macros */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
/***************************** Include Files *********************************/
|
||||
|
||||
#include "xstatus.h"
|
||||
#include "xil_io.h"
|
||||
#include "xscugic_hw.h"
|
||||
#include "xil_exception.h"
|
||||
|
||||
/************************** Constant Definitions *****************************/
|
||||
|
||||
|
||||
/**************************** 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 low level driver and an instance pointer for the high level driver.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
Xil_InterruptHandler Handler;
|
||||
void *CallBackRef;
|
||||
} XScuGic_VectorTableEntry;
|
||||
|
||||
/**
|
||||
* This typedef contains configuration information for the device.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
u16 DeviceId; /**< Unique ID of device */
|
||||
u32 CpuBaseAddress; /**< CPU Interface Register base address */
|
||||
u32 DistBaseAddress; /**< Distributor Register base address */
|
||||
XScuGic_VectorTableEntry HandlerTable[XSCUGIC_MAX_NUM_INTR_INPUTS];/**<
|
||||
Vector table of interrupt handlers */
|
||||
} XScuGic_Config;
|
||||
|
||||
/**
|
||||
* The XScuGic 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
|
||||
{
|
||||
XScuGic_Config *Config; /**< Configuration table entry */
|
||||
u32 IsReady; /**< Device is initialized and ready */
|
||||
u32 UnhandledInterrupts; /**< Intc Statistics */
|
||||
} XScuGic;
|
||||
|
||||
/***************** Macros (Inline Functions) Definitions *********************/
|
||||
|
||||
/****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* Write the given CPU Interface register
|
||||
*
|
||||
* @param InstancePtr is a pointer to the instance to be worked on.
|
||||
* @param RegOffset is the register offset to be written
|
||||
* @param Data is the 32-bit value to write to the register
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note
|
||||
* C-style signature:
|
||||
* void XScuGic_CPUWriteReg(XScuGic *InstancePtr, u32 RegOffset, u32 Data)
|
||||
*
|
||||
*****************************************************************************/
|
||||
#define XScuGic_CPUWriteReg(InstancePtr, RegOffset, Data) \
|
||||
(XScuGic_WriteReg(((InstancePtr)->Config->CpuBaseAddress), (RegOffset), \
|
||||
((u32)(Data))))
|
||||
|
||||
/****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* Read the given CPU Interface register
|
||||
*
|
||||
* @param InstancePtr is a pointer to the instance to be worked on.
|
||||
* @param RegOffset is the register offset to be read
|
||||
*
|
||||
* @return The 32-bit value of the register
|
||||
*
|
||||
* @note
|
||||
* C-style signature:
|
||||
* u32 XScuGic_CPUReadReg(XScuGic *InstancePtr, u32 RegOffset)
|
||||
*
|
||||
*****************************************************************************/
|
||||
#define XScuGic_CPUReadReg(InstancePtr, RegOffset) \
|
||||
(XScuGic_ReadReg(((InstancePtr)->Config->CpuBaseAddress), (RegOffset)))
|
||||
|
||||
/****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* Write the given Distributor Interface register
|
||||
*
|
||||
* @param InstancePtr is a pointer to the instance to be worked on.
|
||||
* @param RegOffset is the register offset to be written
|
||||
* @param Data is the 32-bit value to write to the register
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note
|
||||
* C-style signature:
|
||||
* void XScuGic_DistWriteReg(XScuGic *InstancePtr, u32 RegOffset, u32 Data)
|
||||
*
|
||||
*****************************************************************************/
|
||||
#define XScuGic_DistWriteReg(InstancePtr, RegOffset, Data) \
|
||||
(XScuGic_WriteReg(((InstancePtr)->Config->DistBaseAddress), (RegOffset), \
|
||||
((u32)(Data))))
|
||||
|
||||
/****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* Read the given Distributor Interface register
|
||||
*
|
||||
* @param InstancePtr is a pointer to the instance to be worked on.
|
||||
* @param RegOffset is the register offset to be read
|
||||
*
|
||||
* @return The 32-bit value of the register
|
||||
*
|
||||
* @note
|
||||
* C-style signature:
|
||||
* u32 XScuGic_DistReadReg(XScuGic *InstancePtr, u32 RegOffset)
|
||||
*
|
||||
*****************************************************************************/
|
||||
#define XScuGic_DistReadReg(InstancePtr, RegOffset) \
|
||||
(XScuGic_ReadReg(((InstancePtr)->Config->DistBaseAddress), (RegOffset)))
|
||||
|
||||
/************************** Function Prototypes ******************************/
|
||||
|
||||
/*
|
||||
* Required functions in xscugic.c
|
||||
*/
|
||||
|
||||
s32 XScuGic_Connect(XScuGic *InstancePtr, u32 Int_Id,
|
||||
Xil_InterruptHandler Handler, void *CallBackRef);
|
||||
void XScuGic_Disconnect(XScuGic *InstancePtr, u32 Int_Id);
|
||||
|
||||
void XScuGic_Enable(XScuGic *InstancePtr, u32 Int_Id);
|
||||
void XScuGic_Disable(XScuGic *InstancePtr, u32 Int_Id);
|
||||
|
||||
s32 XScuGic_CfgInitialize(XScuGic *InstancePtr, XScuGic_Config *ConfigPtr,
|
||||
u32 EffectiveAddr);
|
||||
|
||||
s32 XScuGic_SoftwareIntr(XScuGic *InstancePtr, u32 Int_Id, u32 Cpu_Id);
|
||||
|
||||
void XScuGic_GetPriorityTriggerType(XScuGic *InstancePtr, u32 Int_Id,
|
||||
u8 *Priority, u8 *Trigger);
|
||||
void XScuGic_SetPriorityTriggerType(XScuGic *InstancePtr, u32 Int_Id,
|
||||
u8 Priority, u8 Trigger);
|
||||
|
||||
/*
|
||||
* Initialization functions in xscugic_sinit.c
|
||||
*/
|
||||
XScuGic_Config *XScuGic_LookupConfig(u16 DeviceId);
|
||||
|
||||
/*
|
||||
* Interrupt functions in xscugic_intr.c
|
||||
*/
|
||||
void XScuGic_InterruptHandler(XScuGic *InstancePtr);
|
||||
|
||||
/*
|
||||
* Self-test functions in xscugic_selftest.c
|
||||
*/
|
||||
s32 XScuGic_SelfTest(XScuGic *InstancePtr);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* end of protection macro */
|
93
XilinxProcessorIPLib/drivers/scugic/src/xscugic_g.c
Normal file
93
XilinxProcessorIPLib/drivers/scugic/src/xscugic_g.c
Normal file
|
@ -0,0 +1,93 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2010 - 2015 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
|
||||
* XILINX 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 xscugic_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 drg 01/19/10 First release
|
||||
* 3.00 kvn 02/13/15 Modified code for MISRA-C:2012 compliance.
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @internal
|
||||
*
|
||||
* This configuration table contains entries that are modified at runtime by the
|
||||
* driver. This table reflects only the hardware configuration of the device.
|
||||
* This Intc configuration table contains software information in addition to
|
||||
* hardware configuration.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
/***************************** Include Files *********************************/
|
||||
|
||||
#include "xscugic.h"
|
||||
#include "xparameters.h"
|
||||
|
||||
/************************** Constant Definitions *****************************/
|
||||
|
||||
/**************************** Type Definitions *******************************/
|
||||
|
||||
/***************** Macros (Inline Functions) Definitions *********************/
|
||||
|
||||
/************************** Function Prototypes ******************************/
|
||||
|
||||
/************************** Variable Prototypes ******************************/
|
||||
|
||||
/**
|
||||
* This table contains configuration information for each GIC device
|
||||
* in the system. The XScuGic 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 XScuGic_Config data structure in xscugic.h for details on how
|
||||
* this table should be initialized.
|
||||
*/
|
||||
XScuGic_Config XScuGic_ConfigTable[XPAR_XSCUGIC_NUM_INSTANCES] =
|
||||
{
|
||||
{
|
||||
(u16)XPAR_SCUGIC_0_DEVICE_ID, /* Unique ID of device */
|
||||
(u32)XPAR_SCUGIC_0_CPU_BASEADDR, /* CPU Interface base address */
|
||||
(u32)XPAR_SCUGIC_0_DIST_BASEADDR /* Distributor base address */
|
||||
}
|
||||
};
|
567
XilinxProcessorIPLib/drivers/scugic/src/xscugic_hw.c
Normal file
567
XilinxProcessorIPLib/drivers/scugic/src/xscugic_hw.c
Normal file
|
@ -0,0 +1,567 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2010 - 2015 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
|
||||
* XILINX 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 xscugic_hw.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.
|
||||
* These routines are used when the user does not want to create an instance of
|
||||
* XScuGic structure but still wants to use the ScuGic device. Hence the
|
||||
* routines provided here take device id or scugic base address as arguments.
|
||||
* Separate static versions of DistInit and CPUInit are provided to implement
|
||||
* the low level driver routines.
|
||||
*
|
||||
* <pre>
|
||||
* MODIFICATION HISTORY:
|
||||
*
|
||||
* Ver Who Date Changes
|
||||
* ----- ---- -------- -------------------------------------------------------
|
||||
* 1.01a sdm 07/18/11 First release
|
||||
* 1.03a srt 02/27/13 Moved Offset calculation macros from *_hw.c (CR
|
||||
* 702687).
|
||||
* Added support to direct interrupts to the appropriate CPU.
|
||||
* Earlier interrupts were directed to CPU1 (hard coded). Now
|
||||
* depending upon the CPU selected by the user (xparameters.h),
|
||||
* interrupts will be directed to the relevant CPU.
|
||||
* This fixes CR 699688.
|
||||
* 1.04a hk 05/04/13 Fix for CR#705621. Moved functions
|
||||
* XScuGic_SetPriTrigTypeByDistAddr and
|
||||
* XScuGic_GetPriTrigTypeByDistAddr here from xscugic.c
|
||||
* 3.00 kvn 02/13/15 Modified code for MISRA-C:2012 compliance.
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
|
||||
/***************************** Include Files *********************************/
|
||||
|
||||
#include "xil_types.h"
|
||||
#include "xil_assert.h"
|
||||
#include "xscugic.h"
|
||||
#include "xparameters.h"
|
||||
|
||||
/************************** Constant Definitions *****************************/
|
||||
|
||||
/**************************** Type Definitions *******************************/
|
||||
|
||||
/***************** Macros (Inline Functions) Definitions *********************/
|
||||
|
||||
/************************** Function Prototypes ******************************/
|
||||
|
||||
static void DistInit(XScuGic_Config *Config, u32 CpuID);
|
||||
static void CPUInit(XScuGic_Config *Config);
|
||||
static XScuGic_Config *LookupConfigByBaseAddress(u32 CpuBaseAddress);
|
||||
|
||||
/************************** Variable Definitions *****************************/
|
||||
|
||||
extern XScuGic_Config XScuGic_ConfigTable[XPAR_XSCUGIC_NUM_INSTANCES];
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* DistInit initializes the distributor of the GIC. The
|
||||
* initialization entails:
|
||||
*
|
||||
* - Write the trigger mode, priority and target CPU
|
||||
* - All interrupt sources are disabled
|
||||
* - Enable the distributor
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XScuGic instance.
|
||||
* @param CpuID is the Cpu ID to be initialized.
|
||||
*
|
||||
* @return None
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
******************************************************************************/
|
||||
static void DistInit(XScuGic_Config *Config, u32 CpuID)
|
||||
{
|
||||
u32 Int_Id;
|
||||
u32 LocalCpuID = CpuID;
|
||||
|
||||
#if USE_AMP==1
|
||||
#warning "Building GIC for AMP"
|
||||
|
||||
/*
|
||||
* The distrubutor should not be initialized by FreeRTOS in the case of
|
||||
* AMP -- it is assumed that Linux is the master of this device in that
|
||||
* case.
|
||||
*/
|
||||
return;
|
||||
#endif
|
||||
|
||||
XScuGic_WriteReg(Config->DistBaseAddress, XSCUGIC_DIST_EN_OFFSET, 0U);
|
||||
|
||||
/*
|
||||
* Set the security domains in the int_security registers for non-secure
|
||||
* interrupts. All are secure, so leave at the default. Set to 1 for
|
||||
* non-secure interrupts.
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* For the Shared Peripheral Interrupts INT_ID[MAX..32], set:
|
||||
*/
|
||||
|
||||
/*
|
||||
* 1. The trigger mode in the int_config register
|
||||
* Only write to the SPI interrupts, so start at 32
|
||||
*/
|
||||
for (Int_Id = 32U; Int_Id<XSCUGIC_MAX_NUM_INTR_INPUTS;Int_Id=Int_Id+16U) {
|
||||
/*
|
||||
* Each INT_ID uses two bits, or 16 INT_ID per register
|
||||
* Set them all to be level sensitive, active HIGH.
|
||||
*/
|
||||
XScuGic_WriteReg(Config->DistBaseAddress,
|
||||
XSCUGIC_INT_CFG_OFFSET_CALC(Int_Id), 0U);
|
||||
}
|
||||
|
||||
|
||||
#define DEFAULT_PRIORITY 0xa0a0a0a0U
|
||||
for (Int_Id = 0U; Int_Id<XSCUGIC_MAX_NUM_INTR_INPUTS;Int_Id=Int_Id+4U) {
|
||||
/*
|
||||
* 2. The priority using int the priority_level register
|
||||
* The priority_level and spi_target registers use one byte per
|
||||
* INT_ID.
|
||||
* Write a default value that can be changed elsewhere.
|
||||
*/
|
||||
XScuGic_WriteReg(Config->DistBaseAddress,
|
||||
XSCUGIC_PRIORITY_OFFSET_CALC(Int_Id),
|
||||
DEFAULT_PRIORITY);
|
||||
}
|
||||
|
||||
for (Int_Id = 32U; Int_Id<XSCUGIC_MAX_NUM_INTR_INPUTS;Int_Id=Int_Id+4U) {
|
||||
/*
|
||||
* 3. The CPU interface in the spi_target register
|
||||
* Only write to the SPI interrupts, so start at 32
|
||||
*/
|
||||
LocalCpuID |= LocalCpuID << 8U;
|
||||
LocalCpuID |= LocalCpuID << 16U;
|
||||
|
||||
XScuGic_WriteReg(Config->DistBaseAddress,
|
||||
XSCUGIC_SPI_TARGET_OFFSET_CALC(Int_Id), LocalCpuID);
|
||||
}
|
||||
|
||||
for (Int_Id = 0U; Int_Id<XSCUGIC_MAX_NUM_INTR_INPUTS;Int_Id=Int_Id+32U) {
|
||||
/*
|
||||
* 4. Enable the SPI using the enable_set register. Leave all disabled
|
||||
* for now.
|
||||
*/
|
||||
XScuGic_WriteReg(Config->DistBaseAddress,
|
||||
XSCUGIC_EN_DIS_OFFSET_CALC(XSCUGIC_DISABLE_OFFSET,
|
||||
Int_Id),
|
||||
0xFFFFFFFFU);
|
||||
|
||||
}
|
||||
|
||||
XScuGic_WriteReg(Config->DistBaseAddress, XSCUGIC_DIST_EN_OFFSET,
|
||||
XSCUGIC_EN_INT_MASK);
|
||||
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* CPUInit initializes the CPU Interface of the GIC. The initialization entails:
|
||||
*
|
||||
* - Set the priority of the CPU.
|
||||
* - Enable the CPU interface
|
||||
*
|
||||
* @param ConfigPtr is a pointer to a config table for the particular
|
||||
* device this driver is associated with.
|
||||
*
|
||||
* @return None
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
******************************************************************************/
|
||||
static void CPUInit(XScuGic_Config *Config)
|
||||
{
|
||||
/*
|
||||
* Program the priority mask of the CPU using the Priority mask
|
||||
* register
|
||||
*/
|
||||
XScuGic_WriteReg(Config->CpuBaseAddress, XSCUGIC_CPU_PRIOR_OFFSET,
|
||||
0xF0U);
|
||||
|
||||
/*
|
||||
* If the CPU operates in both security domains, set parameters in the
|
||||
* control_s register.
|
||||
* 1. Set FIQen=1 to use FIQ for secure interrupts,
|
||||
* 2. Program the AckCtl bit
|
||||
* 3. Program the SBPR bit to select the binary pointer behavior
|
||||
* 4. Set EnableS = 1 to enable secure interrupts
|
||||
* 5. Set EnbleNS = 1 to enable non secure interrupts
|
||||
*/
|
||||
|
||||
/*
|
||||
* If the CPU operates only in the secure domain, setup the
|
||||
* control_s register.
|
||||
* 1. Set FIQen=1,
|
||||
* 2. Set EnableS=1, to enable the CPU interface to signal secure .
|
||||
* interrupts Only enable the IRQ output unless secure interrupts
|
||||
* are needed.
|
||||
*/
|
||||
XScuGic_WriteReg(Config->CpuBaseAddress, XSCUGIC_CONTROL_OFFSET, 0x07U);
|
||||
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* CfgInitialize a specific interrupt controller instance/driver. The
|
||||
* initialization entails:
|
||||
*
|
||||
* - Initialize fields of the XScuGic structure
|
||||
* - Initial vector table with stub function calls
|
||||
* - All interrupt sources are disabled
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XScuGic instance to be worked on.
|
||||
* @param ConfigPtr is a pointer to a config table for the particular device
|
||||
* this driver is associated with.
|
||||
* @param EffectiveAddr is the device base address in the virtual memory address
|
||||
* space. The caller is responsible for keeping the address mapping
|
||||
* from EffectiveAddr to the device physical base address unchanged
|
||||
* once this function is invoked. Unexpected errors may occur if the
|
||||
* address mapping changes after this function is called. If address
|
||||
* translation is not used, use Config->BaseAddress for this parameters,
|
||||
* passing the physical address instead.
|
||||
*
|
||||
* @return
|
||||
*
|
||||
* - XST_SUCCESS if initialization was successful
|
||||
*
|
||||
* @note
|
||||
*
|
||||
* None.
|
||||
*
|
||||
******************************************************************************/
|
||||
s32 XScuGic_DeviceInitialize(u32 DeviceId)
|
||||
{
|
||||
XScuGic_Config *Config;
|
||||
u32 Cpu_Id = (u32)XPAR_CPU_ID + (u32)1;
|
||||
|
||||
Config = &XScuGic_ConfigTable[(u32 )DeviceId];
|
||||
|
||||
DistInit(Config, Cpu_Id);
|
||||
|
||||
CPUInit(Config);
|
||||
|
||||
return XST_SUCCESS;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
* This function is the primary interrupt handler for the driver. It must be
|
||||
* connected to the interrupt source such that it 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 Interrupt Type information 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.
|
||||
*
|
||||
* @param DeviceId is the unique identifier for the ScuGic device.
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
******************************************************************************/
|
||||
void XScuGic_DeviceInterruptHandler(void *DeviceId)
|
||||
{
|
||||
|
||||
u32 InterruptID;
|
||||
u32 IntIDFull;
|
||||
XScuGic_VectorTableEntry *TablePtr;
|
||||
XScuGic_Config *CfgPtr;
|
||||
|
||||
CfgPtr = &XScuGic_ConfigTable[(INTPTR )DeviceId];
|
||||
|
||||
/*
|
||||
* Read the int_ack register to identify the highest priority
|
||||
* interrupt ID and make sure it is valid. Reading Int_Ack will
|
||||
* clear the interrupt in the GIC.
|
||||
*/
|
||||
IntIDFull = XScuGic_ReadReg(CfgPtr->CpuBaseAddress, XSCUGIC_INT_ACK_OFFSET);
|
||||
InterruptID = IntIDFull & XSCUGIC_ACK_INTID_MASK;
|
||||
if(XSCUGIC_MAX_NUM_INTR_INPUTS < InterruptID){
|
||||
goto IntrExit;
|
||||
}
|
||||
|
||||
/*
|
||||
* If the interrupt is shared, do some locking here if there are
|
||||
* multiple processors.
|
||||
*/
|
||||
/*
|
||||
* If pre-eption is required:
|
||||
* Re-enable pre-emption by setting the CPSR I bit for non-secure ,
|
||||
* interrupts or the F bit for secure interrupts
|
||||
*/
|
||||
|
||||
/*
|
||||
* If we need to change security domains, issue a SMC instruction here.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Execute the ISR. Jump into the Interrupt service routine based on
|
||||
* the IRQSource. A software trigger is cleared by the ACK.
|
||||
*/
|
||||
TablePtr = &(CfgPtr->HandlerTable[InterruptID]);
|
||||
if(TablePtr != NULL) {
|
||||
TablePtr->Handler(TablePtr->CallBackRef);
|
||||
}
|
||||
|
||||
IntrExit:
|
||||
/*
|
||||
* Write to the EOI register, we are all done here.
|
||||
* Let this function return, the boot code will restore the stack.
|
||||
*/
|
||||
XScuGic_WriteReg(CfgPtr->CpuBaseAddress, XSCUGIC_EOI_OFFSET, IntIDFull);
|
||||
|
||||
/*
|
||||
* Return from the interrupt. Change security domains could happen
|
||||
* here.
|
||||
*/
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* @param BaseAddress is the CPU Interface Register 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 XScuGic_RegisterHandler(u32 BaseAddress, s32 InterruptID,
|
||||
Xil_InterruptHandler IntrHandler, void *CallBackRef)
|
||||
{
|
||||
XScuGic_Config *CfgPtr;
|
||||
CfgPtr = LookupConfigByBaseAddress(BaseAddress);
|
||||
|
||||
if(CfgPtr != NULL) {
|
||||
if( IntrHandler != NULL) {
|
||||
CfgPtr->HandlerTable[InterruptID].Handler = IntrHandler;
|
||||
}
|
||||
if( CallBackRef != NULL) {
|
||||
CfgPtr->HandlerTable[InterruptID].CallBackRef = CallBackRef;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* Looks up the device configuration based on the CPU interface base address of
|
||||
* the device. A table contains the configuration info for each device in the
|
||||
* system.
|
||||
*
|
||||
* @param CpuBaseAddress is the CPU Interface Register base address.
|
||||
*
|
||||
* @return A pointer to the configuration structure for the specified
|
||||
* device, or NULL if the device was not found.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
******************************************************************************/
|
||||
static XScuGic_Config *LookupConfigByBaseAddress(u32 CpuBaseAddress)
|
||||
{
|
||||
XScuGic_Config *CfgPtr = NULL;
|
||||
u32 Index;
|
||||
|
||||
for (Index = 0U; Index < XPAR_SCUGIC_NUM_INSTANCES; Index++) {
|
||||
if (XScuGic_ConfigTable[Index].CpuBaseAddress ==
|
||||
CpuBaseAddress) {
|
||||
CfgPtr = &XScuGic_ConfigTable[Index];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return (XScuGic_Config *)CfgPtr;
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
/**
|
||||
* Sets the interrupt priority and trigger type for the specificd IRQ source.
|
||||
*
|
||||
* @param BaseAddr is the device base address
|
||||
* @param Int_Id is the IRQ source number to modify
|
||||
* @param Priority is the new priority for the IRQ source. 0 is highest
|
||||
* priority, 0xF8 (248) is lowest. There are 32 priority levels
|
||||
* supported with a step of 8. Hence the supported priorities are
|
||||
* 0, 8, 16, 32, 40 ..., 248.
|
||||
* @param Trigger is the new trigger type for the IRQ source.
|
||||
* Each bit pair describes the configuration for an INT_ID.
|
||||
* SFI Read Only b10 always
|
||||
* PPI Read Only depending on how the PPIs are configured.
|
||||
* b01 Active HIGH level sensitive
|
||||
* b11 Rising edge sensitive
|
||||
* SPI LSB is read only.
|
||||
* b01 Active HIGH level sensitive
|
||||
* b11 Rising edge sensitive/
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note This API has the similar functionality of XScuGic_SetPriority
|
||||
* TriggerType() and should be used when there is no InstancePtr.
|
||||
*
|
||||
*****************************************************************************/
|
||||
void XScuGic_SetPriTrigTypeByDistAddr(u32 DistBaseAddress, u32 Int_Id,
|
||||
u8 Priority, u8 Trigger)
|
||||
{
|
||||
u32 RegValue;
|
||||
u8 LocalPriority = Priority;
|
||||
|
||||
Xil_AssertVoid(Int_Id < XSCUGIC_MAX_NUM_INTR_INPUTS);
|
||||
Xil_AssertVoid(Trigger <= XSCUGIC_INT_CFG_MASK);
|
||||
Xil_AssertVoid(LocalPriority <= XSCUGIC_MAX_INTR_PRIO_VAL);
|
||||
|
||||
/*
|
||||
* Determine the register to write to using the Int_Id.
|
||||
*/
|
||||
RegValue = XScuGic_ReadReg(DistBaseAddress,
|
||||
XSCUGIC_PRIORITY_OFFSET_CALC(Int_Id));
|
||||
|
||||
/*
|
||||
* The priority bits are Bits 7 to 3 in GIC Priority Register. This
|
||||
* means the number of priority levels supported are 32 and they are
|
||||
* in steps of 8. The priorities can be 0, 8, 16, 32, 48, ... etc.
|
||||
* The lower order 3 bits are masked before putting it in the register.
|
||||
*/
|
||||
LocalPriority = LocalPriority & XSCUGIC_INTR_PRIO_MASK;
|
||||
/*
|
||||
* Shift and Mask the correct bits for the priority and trigger in the
|
||||
* register
|
||||
*/
|
||||
RegValue &= ~(XSCUGIC_PRIORITY_MASK << ((Int_Id%4U)*8U));
|
||||
RegValue |= (u32)LocalPriority << ((Int_Id%4U)*8U);
|
||||
|
||||
/*
|
||||
* Write the value back to the register.
|
||||
*/
|
||||
XScuGic_WriteReg(DistBaseAddress, XSCUGIC_PRIORITY_OFFSET_CALC(Int_Id),
|
||||
RegValue);
|
||||
/*
|
||||
* Determine the register to write to using the Int_Id.
|
||||
*/
|
||||
RegValue = XScuGic_ReadReg(DistBaseAddress,
|
||||
XSCUGIC_INT_CFG_OFFSET_CALC (Int_Id));
|
||||
|
||||
/*
|
||||
* Shift and Mask the correct bits for the priority and trigger in the
|
||||
* register
|
||||
*/
|
||||
RegValue &= ~(XSCUGIC_INT_CFG_MASK << ((Int_Id%16U)*2U));
|
||||
RegValue |= (u32)Trigger << ((Int_Id%16U)*2U);
|
||||
|
||||
/*
|
||||
* Write the value back to the register.
|
||||
*/
|
||||
XScuGic_WriteReg(DistBaseAddress, XSCUGIC_INT_CFG_OFFSET_CALC(Int_Id),
|
||||
RegValue);
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
/**
|
||||
* Gets the interrupt priority and trigger type for the specificd IRQ source.
|
||||
*
|
||||
* @param BaseAddr is the device base address
|
||||
* @param Int_Id is the IRQ source number to modify
|
||||
* @param Priority is a pointer to the value of the priority of the IRQ
|
||||
* source. This is a return value.
|
||||
* @param Trigger is pointer to the value of the trigger of the IRQ
|
||||
* source. This is a return value.
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note This API has the similar functionality of XScuGic_GetPriority
|
||||
* TriggerType() and should be used when there is no InstancePtr.
|
||||
*
|
||||
*****************************************************************************/
|
||||
void XScuGic_GetPriTrigTypeByDistAddr(u32 DistBaseAddress, u32 Int_Id,
|
||||
u8 *Priority, u8 *Trigger)
|
||||
{
|
||||
u32 RegValue;
|
||||
|
||||
Xil_AssertVoid(Int_Id < XSCUGIC_MAX_NUM_INTR_INPUTS);
|
||||
Xil_AssertVoid(Priority != NULL);
|
||||
Xil_AssertVoid(Trigger != NULL);
|
||||
|
||||
/*
|
||||
* Determine the register to read to using the Int_Id.
|
||||
*/
|
||||
RegValue = XScuGic_ReadReg(DistBaseAddress,
|
||||
XSCUGIC_PRIORITY_OFFSET_CALC(Int_Id));
|
||||
|
||||
/*
|
||||
* Shift and Mask the correct bits for the priority and trigger in the
|
||||
* register
|
||||
*/
|
||||
RegValue = RegValue >> ((Int_Id%4U)*8U);
|
||||
*Priority = (u8)(RegValue & XSCUGIC_PRIORITY_MASK);
|
||||
|
||||
/*
|
||||
* Determine the register to read to using the Int_Id.
|
||||
*/
|
||||
RegValue = XScuGic_ReadReg(DistBaseAddress,
|
||||
XSCUGIC_INT_CFG_OFFSET_CALC (Int_Id));
|
||||
|
||||
/*
|
||||
* Shift and Mask the correct bits for the priority and trigger in the
|
||||
* register
|
||||
*/
|
||||
RegValue = RegValue >> ((Int_Id%16U)*2U);
|
||||
|
||||
*Trigger = (u8)(RegValue & XSCUGIC_INT_CFG_MASK);
|
||||
}
|
637
XilinxProcessorIPLib/drivers/scugic/src/xscugic_hw.h
Normal file
637
XilinxProcessorIPLib/drivers/scugic/src/xscugic_hw.h
Normal file
|
@ -0,0 +1,637 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2010 - 2015 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
|
||||
* XILINX 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 xscugic_hw.h
|
||||
*
|
||||
* This header file contains identifiers and HW access 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.
|
||||
* The driver functions/APIs are defined in xscugic.h.
|
||||
*
|
||||
* This GIC device has two parts, a distributor and CPU interface(s). Each part
|
||||
* has separate register definition sections.
|
||||
*
|
||||
*
|
||||
* <pre>
|
||||
* MODIFICATION HISTORY:
|
||||
*
|
||||
* Ver Who Date Changes
|
||||
* ----- ---- -------- -----------------------------------------------------
|
||||
* 1.00a drg 01/19/10 First release
|
||||
* 1.01a sdm 11/09/11 "xil_exception.h" added as include.
|
||||
* Macros XScuGic_EnableIntr and XScuGic_DisableIntr are
|
||||
* added to enable or disable interrupts based on
|
||||
* Distributor Register base address. Normally users use
|
||||
* XScuGic instance and call XScuGic_Enable or
|
||||
* XScuGic_Disable to enable/disable interrupts. These
|
||||
* new macros are provided when user does not want to
|
||||
* use an instance pointer but still wants to enable or
|
||||
* disable interrupts.
|
||||
* Function prototypes for functions (present in newly
|
||||
* added file xscugic_hw.c) are added.
|
||||
* 1.03a srt 02/27/13 Moved Offset calculation macros from *_hw.c (CR
|
||||
* 702687).
|
||||
* 1.04a hk 05/04/13 Fix for CR#705621. Moved function prototypes
|
||||
* XScuGic_SetPriTrigTypeByDistAddr and
|
||||
* XScuGic_GetPriTrigTypeByDistAddr here from xscugic.h
|
||||
* 3.0 pkp 12/09/14 changed XSCUGIC_MAX_NUM_INTR_INPUTS for
|
||||
* Zynq Ultrascale Mp
|
||||
* 3.0 kvn 02/13/14 Modified code for MISRA-C:2012 compliance.
|
||||
* </pre>
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef XSCUGIC_HW_H /* prevent circular inclusions */
|
||||
#define XSCUGIC_HW_H /* by using protection macros */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/***************************** Include Files *********************************/
|
||||
|
||||
#include "xil_types.h"
|
||||
#include "xil_assert.h"
|
||||
#include "xil_io.h"
|
||||
#include "xil_exception.h"
|
||||
|
||||
/************************** Constant Definitions *****************************/
|
||||
|
||||
/*
|
||||
* The maximum number of interrupts supported by the hardware.
|
||||
*/
|
||||
#ifdef __ARM_NEON__
|
||||
#define XSCUGIC_MAX_NUM_INTR_INPUTS 95U /* Maximum number of interrupt defined by Zynq */
|
||||
#else
|
||||
#define XSCUGIC_MAX_NUM_INTR_INPUTS 195U /* Maximum number of interrupt defined by Zynq Ultrascale Mp */
|
||||
#endif
|
||||
|
||||
/*
|
||||
* The maximum priority value that can be used in the GIC.
|
||||
*/
|
||||
#define XSCUGIC_MAX_INTR_PRIO_VAL 248U
|
||||
#define XSCUGIC_INTR_PRIO_MASK 0x000000F8U
|
||||
|
||||
/** @name Distributor Interface Register Map
|
||||
*
|
||||
* Define the offsets from the base address for all Distributor registers of
|
||||
* the interrupt controller, some registers may be reserved in the hardware
|
||||
* device.
|
||||
* @{
|
||||
*/
|
||||
#define XSCUGIC_DIST_EN_OFFSET 0x00000000U /**< Distributor Enable
|
||||
Register */
|
||||
#define XSCUGIC_IC_TYPE_OFFSET 0x00000004U /**< Interrupt Controller
|
||||
Type Register */
|
||||
#define XSCUGIC_DIST_IDENT_OFFSET 0x00000008U /**< Implementor ID
|
||||
Register */
|
||||
#define XSCUGIC_SECURITY_OFFSET 0x00000080U /**< Interrupt Security
|
||||
Register */
|
||||
#define XSCUGIC_ENABLE_SET_OFFSET 0x00000100U /**< Enable Set
|
||||
Register */
|
||||
#define XSCUGIC_DISABLE_OFFSET 0x00000180U /**< Enable Clear Register */
|
||||
#define XSCUGIC_PENDING_SET_OFFSET 0x00000200U /**< Pending Set
|
||||
Register */
|
||||
#define XSCUGIC_PENDING_CLR_OFFSET 0x00000280U /**< Pending Clear
|
||||
Register */
|
||||
#define XSCUGIC_ACTIVE_OFFSET 0x00000300U /**< Active Status Register */
|
||||
#define XSCUGIC_PRIORITY_OFFSET 0x00000400U /**< Priority Level Register */
|
||||
#define XSCUGIC_SPI_TARGET_OFFSET 0x00000800U /**< SPI Target
|
||||
Register 0x800-0x8FB */
|
||||
#define XSCUGIC_INT_CFG_OFFSET 0x00000C00U /**< Interrupt Configuration
|
||||
Register 0xC00-0xCFC */
|
||||
#define XSCUGIC_PPI_STAT_OFFSET 0x00000D00U /**< PPI Status Register */
|
||||
#define XSCUGIC_SPI_STAT_OFFSET 0x00000D04U /**< SPI Status Register
|
||||
0xd04-0xd7C */
|
||||
#define XSCUGIC_AHB_CONFIG_OFFSET 0x00000D80U /**< AHB Configuration
|
||||
Register */
|
||||
#define XSCUGIC_SFI_TRIG_OFFSET 0x00000F00U /**< Software Triggered
|
||||
Interrupt Register */
|
||||
#define XSCUGIC_PERPHID_OFFSET 0x00000FD0U /**< Peripheral ID Reg */
|
||||
#define XSCUGIC_PCELLID_OFFSET 0x00000FF0U /**< Pcell ID Register */
|
||||
/* @} */
|
||||
|
||||
/** @name Distributor Enable Register
|
||||
* Controls if the distributor response to external interrupt inputs.
|
||||
* @{
|
||||
*/
|
||||
#define XSCUGIC_EN_INT_MASK 0x00000001U /**< Interrupt In Enable */
|
||||
/* @} */
|
||||
|
||||
/** @name Interrupt Controller Type Register
|
||||
* @{
|
||||
*/
|
||||
#define XSCUGIC_LSPI_MASK 0x0000F800U /**< Number of Lockable
|
||||
Shared Peripheral
|
||||
Interrupts*/
|
||||
#define XSCUGIC_DOMAIN_MASK 0x00000400U /**< Number os Security domains*/
|
||||
#define XSCUGIC_CPU_NUM_MASK 0x000000E0U /**< Number of CPU Interfaces */
|
||||
#define XSCUGIC_NUM_INT_MASK 0x0000001FU /**< Number of Interrupt IDs */
|
||||
/* @} */
|
||||
|
||||
/** @name Implementor ID Register
|
||||
* Implementor and revision information.
|
||||
* @{
|
||||
*/
|
||||
#define XSCUGIC_REV_MASK 0x00FFF000U /**< Revision Number */
|
||||
#define XSCUGIC_IMPL_MASK 0x00000FFFU /**< Implementor */
|
||||
/* @} */
|
||||
|
||||
/** @name Interrupt Security Registers
|
||||
* Each bit controls the security level of an interrupt, either secure or non
|
||||
* secure. These registers can only be accessed using secure read and write.
|
||||
* There are registers for each of the CPU interfaces at offset 0x080. A
|
||||
* register set for the SPI interrupts is available to all CPU interfaces.
|
||||
* There are up to 32 of these registers staring at location 0x084.
|
||||
* @{
|
||||
*/
|
||||
#define XSCUGIC_INT_NS_MASK 0x00000001U /**< Each bit corresponds to an
|
||||
INT_ID */
|
||||
/* @} */
|
||||
|
||||
/** @name Enable Set Register
|
||||
* Each bit controls the enabling of an interrupt, a 0 is disabled, a 1 is
|
||||
* enabled. Writing a 0 has no effect. Use the ENABLE_CLR register to set a
|
||||
* bit to 0.
|
||||
* There are registers for each of the CPU interfaces at offset 0x100. With up
|
||||
* to 8 registers aliased to the same address. A register set for the SPI
|
||||
* interrupts is available to all CPU interfaces.
|
||||
* There are up to 32 of these registers staring at location 0x104.
|
||||
* @{
|
||||
*/
|
||||
#define XSCUGIC_INT_EN_MASK 0x00000001U /**< Each bit corresponds to an
|
||||
INT_ID */
|
||||
/* @} */
|
||||
|
||||
/** @name Enable Clear Register
|
||||
* Each bit controls the disabling of an interrupt, a 0 is disabled, a 1 is
|
||||
* enabled. Writing a 0 has no effect. Writing a 1 disables an interrupt and
|
||||
* sets the corresponding bit to 0.
|
||||
* There are registers for each of the CPU interfaces at offset 0x180. With up
|
||||
* to 8 registers aliased to the same address.
|
||||
* A register set for the SPI interrupts is available to all CPU interfaces.
|
||||
* There are up to 32 of these registers staring at location 0x184.
|
||||
* @{
|
||||
*/
|
||||
#define XSCUGIC_INT_CLR_MASK 0x00000001U /**< Each bit corresponds to an
|
||||
INT_ID */
|
||||
/* @} */
|
||||
|
||||
/** @name Pending Set Register
|
||||
* Each bit controls the Pending or Active and Pending state of an interrupt, a
|
||||
* 0 is not pending, a 1 is pending. Writing a 0 has no effect. Writing a 1 sets
|
||||
* an interrupt to the pending state.
|
||||
* There are registers for each of the CPU interfaces at offset 0x200. With up
|
||||
* to 8 registers aliased to the same address.
|
||||
* A register set for the SPI interrupts is available to all CPU interfaces.
|
||||
* There are up to 32 of these registers staring at location 0x204.
|
||||
* @{
|
||||
*/
|
||||
#define XSCUGIC_PEND_SET_MASK 0x00000001U /**< Each bit corresponds to an
|
||||
INT_ID */
|
||||
/* @} */
|
||||
|
||||
/** @name Pending Clear Register
|
||||
* Each bit can clear the Pending or Active and Pending state of an interrupt, a
|
||||
* 0 is not pending, a 1 is pending. Writing a 0 has no effect. Writing a 1
|
||||
* clears the pending state of an interrupt.
|
||||
* There are registers for each of the CPU interfaces at offset 0x280. With up
|
||||
* to 8 registers aliased to the same address.
|
||||
* A register set for the SPI interrupts is available to all CPU interfaces.
|
||||
* There are up to 32 of these registers staring at location 0x284.
|
||||
* @{
|
||||
*/
|
||||
#define XSCUGIC_PEND_CLR_MASK 0x00000001U /**< Each bit corresponds to an
|
||||
INT_ID */
|
||||
/* @} */
|
||||
|
||||
/** @name Active Status Register
|
||||
* Each bit provides the Active status of an interrupt, a
|
||||
* 0 is not Active, a 1 is Active. This is a read only register.
|
||||
* There are registers for each of the CPU interfaces at offset 0x300. With up
|
||||
* to 8 registers aliased to each address.
|
||||
* A register set for the SPI interrupts is available to all CPU interfaces.
|
||||
* There are up to 32 of these registers staring at location 0x380.
|
||||
* @{
|
||||
*/
|
||||
#define XSCUGIC_ACTIVE_MASK 0x00000001U /**< Each bit corresponds to an
|
||||
INT_ID */
|
||||
/* @} */
|
||||
|
||||
/** @name Priority Level Register
|
||||
* Each byte in a Priority Level Register sets the priority level of an
|
||||
* interrupt. Reading the register provides the priority level of an interrupt.
|
||||
* There are registers for each of the CPU interfaces at offset 0x400 through
|
||||
* 0x41C. With up to 8 registers aliased to each address.
|
||||
* 0 is highest priority, 0xFF is lowest.
|
||||
* A register set for the SPI interrupts is available to all CPU interfaces.
|
||||
* There are up to 255 of these registers staring at location 0x420.
|
||||
* @{
|
||||
*/
|
||||
#define XSCUGIC_PRIORITY_MASK 0x000000FFU /**< Each Byte corresponds to an
|
||||
INT_ID */
|
||||
#define XSCUGIC_PRIORITY_MAX 0x000000FFU /**< Highest value of a priority
|
||||
actually the lowest priority*/
|
||||
/* @} */
|
||||
|
||||
/** @name SPI Target Register 0x800-0x8FB
|
||||
* Each byte references a separate SPI and programs which of the up to 8 CPU
|
||||
* interfaces are sent a Pending interrupt.
|
||||
* There are registers for each of the CPU interfaces at offset 0x800 through
|
||||
* 0x81C. With up to 8 registers aliased to each address.
|
||||
* A register set for the SPI interrupts is available to all CPU interfaces.
|
||||
* There are up to 255 of these registers staring at location 0x820.
|
||||
*
|
||||
* This driver does not support multiple CPU interfaces. These are included
|
||||
* for complete documentation.
|
||||
* @{
|
||||
*/
|
||||
#define XSCUGIC_SPI_CPU7_MASK 0x00000080U /**< CPU 7 Mask*/
|
||||
#define XSCUGIC_SPI_CPU6_MASK 0x00000040U /**< CPU 6 Mask*/
|
||||
#define XSCUGIC_SPI_CPU5_MASK 0x00000020U /**< CPU 5 Mask*/
|
||||
#define XSCUGIC_SPI_CPU4_MASK 0x00000010U /**< CPU 4 Mask*/
|
||||
#define XSCUGIC_SPI_CPU3_MASK 0x00000008U /**< CPU 3 Mask*/
|
||||
#define XSCUGIC_SPI_CPU2_MASK 0x00000003U /**< CPU 2 Mask*/
|
||||
#define XSCUGIC_SPI_CPU1_MASK 0x00000002U /**< CPU 1 Mask*/
|
||||
#define XSCUGIC_SPI_CPU0_MASK 0x00000001U /**< CPU 0 Mask*/
|
||||
/* @} */
|
||||
|
||||
/** @name Interrupt Configuration Register 0xC00-0xCFC
|
||||
* The interrupt configuration registers program an SFI to be active HIGH level
|
||||
* sensitive or rising edge sensitive.
|
||||
* Each bit pair describes the configuration for an INT_ID.
|
||||
* SFI Read Only b10 always
|
||||
* PPI Read Only depending on how the PPIs are configured.
|
||||
* b01 Active HIGH level sensitive
|
||||
* b11 Rising edge sensitive
|
||||
* SPI LSB is read only.
|
||||
* b01 Active HIGH level sensitive
|
||||
* b11 Rising edge sensitive/
|
||||
* There are registers for each of the CPU interfaces at offset 0xC00 through
|
||||
* 0xC04. With up to 8 registers aliased to each address.
|
||||
* A register set for the SPI interrupts is available to all CPU interfaces.
|
||||
* There are up to 255 of these registers staring at location 0xC08.
|
||||
* @{
|
||||
*/
|
||||
#define XSCUGIC_INT_CFG_MASK 0x00000003U /**< */
|
||||
/* @} */
|
||||
|
||||
/** @name PPI Status Register
|
||||
* Enables an external AMBA master to access the status of the PPI inputs.
|
||||
* A CPU can only read the status of its local PPI signals and cannot read the
|
||||
* status for other CPUs.
|
||||
* This register is aliased for each CPU interface.
|
||||
* @{
|
||||
*/
|
||||
#define XSCUGIC_PPI_C15_MASK 0x00008000U /**< PPI Status */
|
||||
#define XSCUGIC_PPI_C14_MASK 0x00004000U /**< PPI Status */
|
||||
#define XSCUGIC_PPI_C13_MASK 0x00002000U /**< PPI Status */
|
||||
#define XSCUGIC_PPI_C12_MASK 0x00001000U /**< PPI Status */
|
||||
#define XSCUGIC_PPI_C11_MASK 0x00000800U /**< PPI Status */
|
||||
#define XSCUGIC_PPI_C10_MASK 0x00000400U /**< PPI Status */
|
||||
#define XSCUGIC_PPI_C09_MASK 0x00000200U /**< PPI Status */
|
||||
#define XSCUGIC_PPI_C08_MASK 0x00000100U /**< PPI Status */
|
||||
#define XSCUGIC_PPI_C07_MASK 0x00000080U /**< PPI Status */
|
||||
#define XSCUGIC_PPI_C06_MASK 0x00000040U /**< PPI Status */
|
||||
#define XSCUGIC_PPI_C05_MASK 0x00000020U /**< PPI Status */
|
||||
#define XSCUGIC_PPI_C04_MASK 0x00000010U /**< PPI Status */
|
||||
#define XSCUGIC_PPI_C03_MASK 0x00000008U /**< PPI Status */
|
||||
#define XSCUGIC_PPI_C02_MASK 0x00000004U /**< PPI Status */
|
||||
#define XSCUGIC_PPI_C01_MASK 0x00000002U /**< PPI Status */
|
||||
#define XSCUGIC_PPI_C00_MASK 0x00000001U /**< PPI Status */
|
||||
/* @} */
|
||||
|
||||
/** @name SPI Status Register 0xd04-0xd7C
|
||||
* Enables an external AMBA master to access the status of the SPI inputs.
|
||||
* There are up to 63 registers if the maximum number of SPI inputs are
|
||||
* configured.
|
||||
* @{
|
||||
*/
|
||||
#define XSCUGIC_SPI_N_MASK 0x00000001U /**< Each bit corresponds to an SPI
|
||||
input */
|
||||
/* @} */
|
||||
|
||||
/** @name AHB Configuration Register
|
||||
* Provides the status of the CFGBIGEND input signal and allows the endianess
|
||||
* of the GIC to be set.
|
||||
* @{
|
||||
*/
|
||||
#define XSCUGIC_AHB_END_MASK 0x00000004U /**< 0-GIC uses little Endian,
|
||||
1-GIC uses Big Endian */
|
||||
#define XSCUGIC_AHB_ENDOVR_MASK 0x00000002U /**< 0-Uses CFGBIGEND control,
|
||||
1-use the AHB_END bit */
|
||||
#define XSCUGIC_AHB_TIE_OFF_MASK 0x00000001U /**< State of CFGBIGEND */
|
||||
|
||||
/* @} */
|
||||
|
||||
/** @name Software Triggered Interrupt Register
|
||||
* Controls issueing of software interrupts.
|
||||
* @{
|
||||
*/
|
||||
#define XSCUGIC_SFI_SELFTRIG_MASK 0x02010000U
|
||||
#define XSCUGIC_SFI_TRIG_TRGFILT_MASK 0x03000000U /**< Target List filter
|
||||
b00-Use the target List
|
||||
b01-All CPUs except requester
|
||||
b10-To Requester
|
||||
b11-reserved */
|
||||
#define XSCUGIC_SFI_TRIG_CPU_MASK 0x00FF0000U /**< CPU Target list */
|
||||
#define XSCUGIC_SFI_TRIG_SATT_MASK 0x00008000U /**< 0= Use a secure interrupt */
|
||||
#define XSCUGIC_SFI_TRIG_INTID_MASK 0x0000000FU /**< Set to the INTID
|
||||
signaled to the CPU*/
|
||||
/* @} */
|
||||
|
||||
/** @name CPU Interface Register Map
|
||||
*
|
||||
* Define the offsets from the base address for all CPU registers of the
|
||||
* interrupt controller, some registers may be reserved in the hardware device.
|
||||
* @{
|
||||
*/
|
||||
#define XSCUGIC_CONTROL_OFFSET 0x00000000U /**< CPU Interface Control
|
||||
Register */
|
||||
#define XSCUGIC_CPU_PRIOR_OFFSET 0x00000004U /**< Priority Mask Reg */
|
||||
#define XSCUGIC_BIN_PT_OFFSET 0x00000008U /**< Binary Point Register */
|
||||
#define XSCUGIC_INT_ACK_OFFSET 0x0000000CU /**< Interrupt ACK Reg */
|
||||
#define XSCUGIC_EOI_OFFSET 0x00000010U /**< End of Interrupt Reg */
|
||||
#define XSCUGIC_RUN_PRIOR_OFFSET 0x00000014U /**< Running Priority Reg */
|
||||
#define XSCUGIC_HI_PEND_OFFSET 0x00000018U /**< Highest Pending Interrupt
|
||||
Register */
|
||||
#define XSCUGIC_ALIAS_BIN_PT_OFFSET 0x0000001CU /**< Aliased non-Secure
|
||||
Binary Point Register */
|
||||
|
||||
/**< 0x00000020 to 0x00000FBC are reserved and should not be read or written
|
||||
* to. */
|
||||
/* @} */
|
||||
|
||||
|
||||
/** @name Control Register
|
||||
* CPU Interface Control register definitions
|
||||
* All bits are defined here although some are not available in the non-secure
|
||||
* mode.
|
||||
* @{
|
||||
*/
|
||||
#define XSCUGIC_CNTR_SBPR_MASK 0x00000010U /**< Secure Binary Pointer,
|
||||
0=separate registers,
|
||||
1=both use bin_pt_s */
|
||||
#define XSCUGIC_CNTR_FIQEN_MASK 0x00000008U /**< Use nFIQ_C for secure
|
||||
interrupts,
|
||||
0= use IRQ for both,
|
||||
1=Use FIQ for secure, IRQ for non*/
|
||||
#define XSCUGIC_CNTR_ACKCTL_MASK 0x00000004U /**< Ack control for secure or non secure */
|
||||
#define XSCUGIC_CNTR_EN_NS_MASK 0x00000002U /**< Non Secure enable */
|
||||
#define XSCUGIC_CNTR_EN_S_MASK 0x00000001U /**< Secure enable, 0=Disabled, 1=Enabled */
|
||||
/* @} */
|
||||
|
||||
/** @name Priority Mask Register
|
||||
* Priority Mask register definitions
|
||||
* The CPU interface does not send interrupt if the level of the interrupt is
|
||||
* lower than the level of the register.
|
||||
* @{
|
||||
*/
|
||||
/*#define XSCUGIC_PRIORITY_MASK 0x000000FFU*/ /**< All interrupts */
|
||||
/* @} */
|
||||
|
||||
/** @name Binary Point Register
|
||||
* Binary Point register definitions
|
||||
* @{
|
||||
*/
|
||||
|
||||
#define XSCUGIC_BIN_PT_MASK 0x00000007U /**< Binary point mask value
|
||||
Value Secure Non-secure
|
||||
b000 0xFE 0xFF
|
||||
b001 0xFC 0xFE
|
||||
b010 0xF8 0xFC
|
||||
b011 0xF0 0xF8
|
||||
b100 0xE0 0xF0
|
||||
b101 0xC0 0xE0
|
||||
b110 0x80 0xC0
|
||||
b111 0x00 0x80
|
||||
*/
|
||||
/*@}*/
|
||||
|
||||
/** @name Interrupt Acknowledge Register
|
||||
* Interrupt Acknowledge register definitions
|
||||
* Identifies the current Pending interrupt, and the CPU ID for software
|
||||
* interrupts.
|
||||
*/
|
||||
#define XSCUGIC_ACK_INTID_MASK 0x000003FFU /**< Interrupt ID */
|
||||
#define XSCUGIC_CPUID_MASK 0x00000C00U /**< CPU ID */
|
||||
/* @} */
|
||||
|
||||
/** @name End of Interrupt Register
|
||||
* End of Interrupt register definitions
|
||||
* Allows the CPU to signal the GIC when it completes an interrupt service
|
||||
* routine.
|
||||
*/
|
||||
#define XSCUGIC_EOI_INTID_MASK 0x000003FFU /**< Interrupt ID */
|
||||
|
||||
/* @} */
|
||||
|
||||
/** @name Running Priority Register
|
||||
* Running Priority register definitions
|
||||
* Identifies the interrupt priority level of the highest priority active
|
||||
* interrupt.
|
||||
*/
|
||||
#define XSCUGIC_RUN_PRIORITY_MASK 0x000000FFU /**< Interrupt Priority */
|
||||
/* @} */
|
||||
|
||||
/*
|
||||
* Highest Pending Interrupt register definitions
|
||||
* Identifies the interrupt priority of the highest priority pending interupt
|
||||
*/
|
||||
#define XSCUGIC_PEND_INTID_MASK 0x000003FFU /**< Pending Interrupt ID */
|
||||
/*#define XSCUGIC_CPUID_MASK 0x00000C00U */ /**< CPU ID */
|
||||
/* @} */
|
||||
|
||||
/***************** Macros (Inline Functions) Definitions *********************/
|
||||
|
||||
/****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* Read the Interrupt Configuration Register offset for an interrupt id.
|
||||
*
|
||||
* @param InterruptID is the interrupt number.
|
||||
*
|
||||
* @return The 32-bit value of the offset
|
||||
*
|
||||
* @note
|
||||
*
|
||||
*****************************************************************************/
|
||||
#define XSCUGIC_INT_CFG_OFFSET_CALC(InterruptID) \
|
||||
((u32)XSCUGIC_INT_CFG_OFFSET + (((InterruptID)/16U) * 4U))
|
||||
|
||||
/****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* Read the Interrupt Priority Register offset for an interrupt id.
|
||||
*
|
||||
* @param InterruptID is the interrupt number.
|
||||
*
|
||||
* @return The 32-bit value of the offset
|
||||
*
|
||||
* @note
|
||||
*
|
||||
*****************************************************************************/
|
||||
#define XSCUGIC_PRIORITY_OFFSET_CALC(InterruptID) \
|
||||
((u32)XSCUGIC_PRIORITY_OFFSET + (((InterruptID)/4U) * 4U))
|
||||
|
||||
/****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* Read the SPI Target Register offset for an interrupt id.
|
||||
*
|
||||
* @param InterruptID is the interrupt number.
|
||||
*
|
||||
* @return The 32-bit value of the offset
|
||||
*
|
||||
* @note
|
||||
*
|
||||
*****************************************************************************/
|
||||
#define XSCUGIC_SPI_TARGET_OFFSET_CALC(InterruptID) \
|
||||
((u32)XSCUGIC_SPI_TARGET_OFFSET + (((InterruptID)/4U) * 4U))
|
||||
|
||||
/****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* Read the Interrupt Clear-Enable Register offset for an interrupt ID
|
||||
*
|
||||
* @param Register is the register offset for the clear/enable bank.
|
||||
* @param InterruptID is the interrupt number.
|
||||
*
|
||||
* @return The 32-bit value of the offset
|
||||
*
|
||||
* @note
|
||||
*
|
||||
*****************************************************************************/
|
||||
#define XSCUGIC_EN_DIS_OFFSET_CALC(Register, InterruptID) \
|
||||
((Register) + (((InterruptID)/32U) * 4U))
|
||||
|
||||
/****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* Read the given Intc register.
|
||||
*
|
||||
* @param BaseAddress is the base address of the device.
|
||||
* @param RegOffset is the register offset to be read
|
||||
*
|
||||
* @return The 32-bit value of the register
|
||||
*
|
||||
* @note
|
||||
* C-style signature:
|
||||
* u32 XScuGic_ReadReg(u32 BaseAddress, u32 RegOffset)
|
||||
*
|
||||
*****************************************************************************/
|
||||
#define XScuGic_ReadReg(BaseAddress, RegOffset) \
|
||||
(Xil_In32((BaseAddress) + (RegOffset)))
|
||||
|
||||
|
||||
/****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* Write the given Intc register.
|
||||
*
|
||||
* @param BaseAddress is the base address of the device.
|
||||
* @param RegOffset is the register offset to be written
|
||||
* @param Data is the 32-bit value to write to the register
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note
|
||||
* C-style signature:
|
||||
* void XScuGic_WriteReg(u32 BaseAddress, u32 RegOffset, u32 Data)
|
||||
*
|
||||
*****************************************************************************/
|
||||
#define XScuGic_WriteReg(BaseAddress, RegOffset, Data) \
|
||||
(Xil_Out32(((BaseAddress) + (RegOffset)), ((u32)(Data))))
|
||||
|
||||
|
||||
/****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* Enable specific interrupt(s) in the interrupt controller.
|
||||
*
|
||||
* @param DistBaseAddress is the Distributor Register base address of the
|
||||
* device
|
||||
* @param Int_Id is the ID of the interrupt source and should be in the
|
||||
* range of 0 to XSCUGIC_MAX_NUM_INTR_INPUTS - 1
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note C-style signature:
|
||||
* void XScuGic_EnableIntr(u32 DistBaseAddress, u32 Int_Id)
|
||||
*
|
||||
*****************************************************************************/
|
||||
#define XScuGic_EnableIntr(DistBaseAddress, Int_Id) \
|
||||
XScuGic_WriteReg((DistBaseAddress), \
|
||||
XSCUGIC_ENABLE_SET_OFFSET + (((Int_Id) / 32U) * 4U), \
|
||||
(0x00000001U << ((Int_Id) % 32U)))
|
||||
|
||||
/****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* Disable specific interrupt(s) in the interrupt controller.
|
||||
*
|
||||
* @param DistBaseAddress is the Distributor Register base address of the
|
||||
* device
|
||||
* @param Int_Id is the ID of the interrupt source and should be in the
|
||||
* range of 0 to XSCUGIC_MAX_NUM_INTR_INPUTS - 1
|
||||
*
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note C-style signature:
|
||||
* void XScuGic_DisableIntr(u32 DistBaseAddress, u32 Int_Id)
|
||||
*
|
||||
*****************************************************************************/
|
||||
#define XScuGic_DisableIntr(DistBaseAddress, Int_Id) \
|
||||
XScuGic_WriteReg((DistBaseAddress), \
|
||||
XSCUGIC_DISABLE_OFFSET + (((Int_Id) / 32U) * 4U), \
|
||||
(0x00000001U << ((Int_Id) % 32U)))
|
||||
|
||||
|
||||
/************************** Function Prototypes ******************************/
|
||||
|
||||
void XScuGic_DeviceInterruptHandler(void *DeviceId);
|
||||
s32 XScuGic_DeviceInitialize(u32 DeviceId);
|
||||
void XScuGic_RegisterHandler(u32 BaseAddress, s32 InterruptID,
|
||||
Xil_InterruptHandler Handler, void *CallBackRef);
|
||||
void XScuGic_SetPriTrigTypeByDistAddr(u32 DistBaseAddress, u32 Int_Id,
|
||||
u8 Priority, u8 Trigger);
|
||||
void XScuGic_GetPriTrigTypeByDistAddr(u32 DistBaseAddress, u32 Int_Id,
|
||||
u8 *Priority, u8 *Trigger);
|
||||
/************************** Variable Definitions *****************************/
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* end of protection macro */
|
170
XilinxProcessorIPLib/drivers/scugic/src/xscugic_intr.c
Normal file
170
XilinxProcessorIPLib/drivers/scugic/src/xscugic_intr.c
Normal file
|
@ -0,0 +1,170 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2010 - 2015 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
|
||||
* XILINX 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 xscugic_intr.c
|
||||
*
|
||||
* This file contains the interrupt processing for the driver for the Xilinx
|
||||
* Interrupt Controller. The interrupt processing is partitioned separately 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.
|
||||
*
|
||||
* The interrupt handler, XScuGic_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.
|
||||
*
|
||||
* The interrupt processing may be used by connecting the interrupt handler to
|
||||
* the interrupt system. The handler does not save and restore the processor
|
||||
* context but only handles the processing of the Interrupt Controller. The user
|
||||
* is encouraged to supply their own interrupt handler when performance tuning is
|
||||
* deemed necessary.
|
||||
*
|
||||
* <pre>
|
||||
* MODIFICATION HISTORY:
|
||||
*
|
||||
* Ver Who Date Changes
|
||||
* ----- ---- -------- ---------------------------------------------------------
|
||||
* 1.00a drg 01/19/10 First release
|
||||
* 1.01a sdm 11/09/11 XScuGic_InterruptHandler has changed correspondingly
|
||||
* since the HandlerTable has now moved to XScuGic_Config.
|
||||
* 3.00 kvn 02/13/15 Modified code for MISRA-C:2012 compliance.
|
||||
*
|
||||
* </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 "xscugic.h"
|
||||
|
||||
/************************** Constant Definitions *****************************/
|
||||
|
||||
/**************************** Type Definitions *******************************/
|
||||
|
||||
/***************** Macros (Inline Functions) Definitions *********************/
|
||||
|
||||
/************************** Function Prototypes ******************************/
|
||||
|
||||
/************************** Variable Definitions *****************************/
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
* This function is the primary interrupt handler for the driver. It must be
|
||||
* connected to the interrupt source such that it 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 Interrupt Type information 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.
|
||||
*
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XScuGic instance.
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
******************************************************************************/
|
||||
void XScuGic_InterruptHandler(XScuGic *InstancePtr)
|
||||
{
|
||||
|
||||
u32 InterruptID;
|
||||
u32 IntIDFull;
|
||||
XScuGic_VectorTableEntry *TablePtr;
|
||||
|
||||
/* Assert that the pointer to the instance is valid
|
||||
*/
|
||||
Xil_AssertVoid(InstancePtr != NULL);
|
||||
|
||||
/*
|
||||
* Read the int_ack register to identify the highest priority interrupt ID
|
||||
* and make sure it is valid. Reading Int_Ack will clear the interrupt
|
||||
* in the GIC.
|
||||
*/
|
||||
IntIDFull = XScuGic_CPUReadReg(InstancePtr, XSCUGIC_INT_ACK_OFFSET);
|
||||
InterruptID = IntIDFull & XSCUGIC_ACK_INTID_MASK;
|
||||
|
||||
if(XSCUGIC_MAX_NUM_INTR_INPUTS < InterruptID){
|
||||
goto IntrExit;
|
||||
}
|
||||
|
||||
/*
|
||||
* If the interrupt is shared, do some locking here if there are multiple
|
||||
* processors.
|
||||
*/
|
||||
/*
|
||||
* If pre-eption is required:
|
||||
* Re-enable pre-emption by setting the CPSR I bit for non-secure ,
|
||||
* interrupts or the F bit for secure interrupts
|
||||
*/
|
||||
|
||||
/*
|
||||
* If we need to change security domains, issue a SMC instruction here.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Execute the ISR. Jump into the Interrupt service routine based on the
|
||||
* IRQSource. A software trigger is cleared by the ACK.
|
||||
*/
|
||||
TablePtr = &(InstancePtr->Config->HandlerTable[InterruptID]);
|
||||
if(TablePtr != NULL) {
|
||||
TablePtr->Handler(TablePtr->CallBackRef);
|
||||
}
|
||||
|
||||
IntrExit:
|
||||
/*
|
||||
* Write to the EOI register, we are all done here.
|
||||
* Let this function return, the boot code will restore the stack.
|
||||
*/
|
||||
XScuGic_CPUWriteReg(InstancePtr, XSCUGIC_EOI_OFFSET, IntIDFull);
|
||||
|
||||
/*
|
||||
* Return from the interrupt. Change security domains could happen here.
|
||||
*/
|
||||
}
|
112
XilinxProcessorIPLib/drivers/scugic/src/xscugic_selftest.c
Normal file
112
XilinxProcessorIPLib/drivers/scugic/src/xscugic_selftest.c
Normal file
|
@ -0,0 +1,112 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2010 - 2015 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
|
||||
* XILINX 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 xscugic_selftest.c
|
||||
*
|
||||
* Contains diagnostic self-test functions for the XScuGic driver.
|
||||
* <pre>
|
||||
* MODIFICATION HISTORY:
|
||||
*
|
||||
* Ver Who Date Changes
|
||||
* ----- ---- -------- -----------------------------------------------
|
||||
* 1.00a drg 01/19/10 First release
|
||||
* 3.00 kvn 02/13/15 Modified code for MISRA-C:2012 compliance.
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
/***************************** Include Files *********************************/
|
||||
|
||||
#include "xil_types.h"
|
||||
#include "xil_assert.h"
|
||||
#include "xscugic.h"
|
||||
|
||||
/************************** Constant Definitions *****************************/
|
||||
|
||||
#define XSCUGIC_PCELL_ID 0xB105F00DU
|
||||
|
||||
/**************************** Type Definitions *******************************/
|
||||
|
||||
|
||||
/***************** Macros (Inline Functions) Definitions *********************/
|
||||
|
||||
|
||||
/************************** Function Prototypes ******************************/
|
||||
|
||||
/************************** Variable Definitions *****************************/
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* Run a self-test on the driver/device. This test reads the ID registers and
|
||||
* compares them.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XScuGic instance.
|
||||
*
|
||||
* @return
|
||||
*
|
||||
* - XST_SUCCESS if self-test is successful.
|
||||
* - XST_FAILURE if the self-test is not successful.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
******************************************************************************/
|
||||
s32 XScuGic_SelfTest(XScuGic *InstancePtr)
|
||||
{
|
||||
u32 RegValue1 = 0U;
|
||||
u32 Index;
|
||||
s32 Status;
|
||||
|
||||
/*
|
||||
* Assert the arguments
|
||||
*/
|
||||
Xil_AssertNonvoid(InstancePtr != NULL);
|
||||
Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
|
||||
|
||||
/*
|
||||
* Read the ID registers.
|
||||
*/
|
||||
for(Index=0U; Index<=3U; Index++) {
|
||||
RegValue1 |= XScuGic_DistReadReg(InstancePtr,
|
||||
((u32)XSCUGIC_PCELLID_OFFSET + (Index * 4U))) << (Index * 8U);
|
||||
}
|
||||
|
||||
if(XSCUGIC_PCELL_ID != RegValue1){
|
||||
Status = XST_FAILURE;
|
||||
} else {
|
||||
Status = XST_SUCCESS;
|
||||
}
|
||||
return Status;
|
||||
}
|
100
XilinxProcessorIPLib/drivers/scugic/src/xscugic_sinit.c
Normal file
100
XilinxProcessorIPLib/drivers/scugic/src/xscugic_sinit.c
Normal file
|
@ -0,0 +1,100 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2010 - 2015 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
|
||||
* XILINX 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 xscugic_sinit.c
|
||||
*
|
||||
* Contains static init functions for the XScuGic driver for the Interrupt
|
||||
* Controller. See xscugic.h for a detailed description of the driver.
|
||||
*
|
||||
* <pre>
|
||||
* MODIFICATION HISTORY:
|
||||
*
|
||||
* Ver Who Date Changes
|
||||
* ----- ---- -------- --------------------------------------------------------
|
||||
* 1.00a drg 01/19/10 First release
|
||||
* 3.00 kvn 02/13/15 Modified code for MISRA-C:2012 compliance.
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
/***************************** Include Files *********************************/
|
||||
|
||||
#include "xil_types.h"
|
||||
#include "xil_assert.h"
|
||||
#include "xparameters.h"
|
||||
#include "xscugic.h"
|
||||
|
||||
/************************** Constant Definitions *****************************/
|
||||
|
||||
|
||||
/**************************** Type Definitions *******************************/
|
||||
|
||||
|
||||
/***************** Macros (Inline Functions) Definitions *********************/
|
||||
|
||||
/************************** Variable Definitions *****************************/
|
||||
|
||||
extern XScuGic_Config XScuGic_ConfigTable[XPAR_SCUGIC_NUM_INSTANCES];
|
||||
|
||||
/************************** Function Prototypes ******************************/
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* Looks up the device configuration based on the unique device ID. A table
|
||||
* contains the configuration info for each device in the system.
|
||||
*
|
||||
* @param DeviceId is the unique identifier for a device.
|
||||
*
|
||||
* @return A pointer to the XScuGic configuration structure for the
|
||||
* specified device, or NULL if the device was not found.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
******************************************************************************/
|
||||
XScuGic_Config *XScuGic_LookupConfig(u16 DeviceId)
|
||||
{
|
||||
XScuGic_Config *CfgPtr = NULL;
|
||||
u32 Index;
|
||||
|
||||
for (Index=0U; Index < (u32)XPAR_SCUGIC_NUM_INSTANCES; Index++) {
|
||||
if (XScuGic_ConfigTable[Index].DeviceId == DeviceId) {
|
||||
CfgPtr = &XScuGic_ConfigTable[Index];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return (XScuGic_Config *)CfgPtr;
|
||||
}
|
Loading…
Add table
Reference in a new issue