ipipsu_v1_0: Add IPI driver for ZynqMP
This is the initial version of Inter Processor Interrupt (IPI) driver for ZynqMP,including the required tcl and an example on using the driver. Signed-off-by: Jyotheeswar Reddy <jyothee@xilinx.com>
This commit is contained in:
parent
e395d1bf1b
commit
2889468869
9 changed files with 1546 additions and 0 deletions
42
XilinxProcessorIPLib/drivers/ipipsu/data/ipipsu.mdd
Normal file
42
XilinxProcessorIPLib/drivers/ipipsu/data/ipipsu.mdd
Normal file
|
@ -0,0 +1,42 @@
|
|||
###############################################################################
|
||||
#
|
||||
# Copyright (C) 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 THE
|
||||
# XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
|
||||
# OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
# SOFTWARE.
|
||||
#
|
||||
# Except as contained in this notice, the name of the Xilinx shall not be used
|
||||
# in advertising or otherwise to promote the sale, use or other dealings in
|
||||
# this Software without prior written authorization from Xilinx.
|
||||
#
|
||||
###############################################################################
|
||||
OPTION psf_version = 2.1;
|
||||
|
||||
BEGIN driver ipipsu
|
||||
|
||||
OPTION supported_peripherals = (psu_ipi);
|
||||
OPTION driver_state = ACTIVE;
|
||||
OPTION copyfiles = all;
|
||||
OPTION VERSION = 1.0;
|
||||
OPTION NAME = ipipsu;
|
||||
|
||||
END driver
|
210
XilinxProcessorIPLib/drivers/ipipsu/data/ipipsu.tcl
Normal file
210
XilinxProcessorIPLib/drivers/ipipsu/data/ipipsu.tcl
Normal file
|
@ -0,0 +1,210 @@
|
|||
###############################################################################
|
||||
#
|
||||
# Copyright (C) 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 THE
|
||||
# XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
|
||||
# OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
# SOFTWARE.
|
||||
#
|
||||
# Except as contained in this notice, the name of the Xilinx shall not be used
|
||||
# in advertising or otherwise to promote the sale, use or other dealings in
|
||||
# this Software without prior written authorization from Xilinx.
|
||||
#
|
||||
###############################################################################
|
||||
##############################################################################
|
||||
#
|
||||
# Modification History
|
||||
#
|
||||
# Ver Who Date Changes
|
||||
# ----- ---- -------- -----------------------------------------------
|
||||
# 1.00 mjr 02/03/15 Created
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
#uses "xillib.tcl"
|
||||
|
||||
proc ipi_format_hexmask {bitpos} {
|
||||
return [format "0x%08X" [expr 1<<$bitpos]]
|
||||
}
|
||||
proc ipi_define_xpar {inst param} {
|
||||
set param_name [string range $param [string length "CONFIG."] [string length $param]]
|
||||
set name [string range $param_name 2 end]
|
||||
set param_value [common::get_property $param [hsi::get_cells $inst]]
|
||||
if { [string compare $name "BIT_POSITION"] == 0} {
|
||||
set name "BIT_MASK"
|
||||
set param_value [ipi_format_hexmask $param_value]
|
||||
}
|
||||
return [format "#define XPAR_%s_%s %s" [string toupper $inst] $name $param_value]
|
||||
}
|
||||
|
||||
#Generate Config file with data structures describing the HW
|
||||
proc ipi_generate_config {drv_handle file_name} {
|
||||
|
||||
#Driver Prefix String
|
||||
set drv_string "XIpiPsu"
|
||||
|
||||
#The current processor
|
||||
set sw_proc_handle [::hsi::get_sw_processor]
|
||||
set hw_proc_handle [::hsi::get_cells [common::get_property hw_instance $sw_proc_handle]]
|
||||
|
||||
# List of IPIs owned by this processor
|
||||
set proc_ipi_list [lsearch -all -inline [get_property SLAVES $hw_proc_handle] psu_ipi_*]
|
||||
|
||||
# List of all IPIs on SoC
|
||||
set ipi_list [get_cells -filter { IP_NAME == "psu_ipi" }]
|
||||
|
||||
set cfgfilename [file join "src" $file_name]
|
||||
set config_file [open $cfgfilename w]
|
||||
|
||||
# Common Header
|
||||
::hsi::utils::write_c_header $config_file "Driver configuration"
|
||||
puts $config_file "#include \"xparameters.h\""
|
||||
puts $config_file "#include \"[string tolower $drv_string].h\""
|
||||
|
||||
# Start generating the Config table
|
||||
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 comma ""
|
||||
foreach ipi_inst $proc_ipi_list {
|
||||
puts $config_file $comma
|
||||
puts $config_file "\t\{"
|
||||
puts $config_file [format "\t\tXPAR_%s_%s" [string toupper $ipi_inst] "DEVICE_ID,"]
|
||||
puts $config_file [format "\t\tXPAR_%s_%s" [string toupper $ipi_inst] "BASE_ADDRESS,"]
|
||||
puts $config_file [format "\t\tXPAR_%s_%s" [string toupper $ipi_inst] "BIT_MASK,"]
|
||||
puts $config_file [format "\t\tXPAR_%s_%s" [string toupper $ipi_inst] "BUFFER_INDEX,"]
|
||||
puts $config_file [format "\t\tXPAR_%s_%s" [string toupper $ipi_inst] "INT_ID,"]
|
||||
|
||||
# Target Count
|
||||
puts $config_file [format "\t\tXPAR_%s_%s" [string toupper $drv_string] "NUM_TARGETS,"]
|
||||
|
||||
# Start generating Target Table with list if all IPI slots on SoC
|
||||
puts $config_file "\t\t\{"
|
||||
|
||||
set comma ""
|
||||
foreach ipi_inst $ipi_list {
|
||||
puts $config_file $comma
|
||||
puts $config_file "\t\t\t\{"
|
||||
puts $config_file [format "\t\t\t\tXPAR_%s_%s" [string toupper $ipi_inst] "BIT_MASK,"]
|
||||
puts $config_file [format "\t\t\t\tXPAR_%s_%s" [string toupper $ipi_inst] "BUFFER_INDEX"]
|
||||
puts -nonewline $config_file "\t\t\t\}"
|
||||
set comma ","
|
||||
}
|
||||
puts $config_file "\n\t\t\}"
|
||||
puts -nonewline $config_file "\t\}"
|
||||
set comma ",\n"
|
||||
}
|
||||
puts $config_file "\n\};"
|
||||
|
||||
close $config_file
|
||||
}
|
||||
proc ipi_generate_params {file_name} {
|
||||
#Driver Prefix String
|
||||
set drv_string "XIpiPsu"
|
||||
|
||||
# open the xparameters.h file
|
||||
set file_handle [::hsi::utils::open_include_file $file_name]
|
||||
|
||||
# List of all IPIs on SoC
|
||||
set ipi_list [get_cells -filter { IP_NAME == "psu_ipi" }]
|
||||
|
||||
#List of all processors on SoC
|
||||
set proc_list [get_cells -filter { IP_TYPE == "PROCESSOR" }]
|
||||
|
||||
#The current processor
|
||||
set sw_proc_handle [::hsi::get_sw_processor]
|
||||
set hw_proc_handle [::hsi::get_cells [common::get_property hw_instance $sw_proc_handle]]
|
||||
|
||||
|
||||
# List of IPIs owned by this processor
|
||||
set proc_ipi_list [lsearch -all -inline [get_property SLAVES $hw_proc_handle] psu_ipi_*]
|
||||
|
||||
#Total number of IPIs assigned to this proc
|
||||
puts $file_handle [format "#define XPAR_XIPIPSU_NUM_INSTANCES %s" [llength $proc_ipi_list]]
|
||||
puts $file_handle ""
|
||||
|
||||
# Generate all params for IPIs owned by this proc
|
||||
#Idx is used to track DEVICE_ID as we loop through the list
|
||||
set idx 0
|
||||
|
||||
foreach ipi_inst $proc_ipi_list {
|
||||
puts $file_handle [format "/* Parameter definitions for peripheral %s */" $ipi_inst]
|
||||
puts $file_handle [format "#define XPAR_%s_%s %s" [string toupper $ipi_inst] "DEVICE_ID" $idx]
|
||||
puts $file_handle [ipi_define_xpar $ipi_inst CONFIG.C_BASE_ADDRESS]
|
||||
puts $file_handle [ipi_define_xpar $ipi_inst CONFIG.C_BIT_POSITION]
|
||||
puts $file_handle [ipi_define_xpar $ipi_inst CONFIG.C_BUFFER_INDEX]
|
||||
puts $file_handle [ipi_define_xpar $ipi_inst CONFIG.C_INT_ID]
|
||||
puts $file_handle ""
|
||||
incr idx
|
||||
}
|
||||
|
||||
set idx 0
|
||||
foreach ipi_inst $proc_ipi_list {
|
||||
puts $file_handle [format "/* Canonical definitions for peripheral %s */" $ipi_inst]
|
||||
puts $file_handle [format "#define XPAR_%s_%s_%s XPAR_%s_%s" [string toupper $drv_string] $idx "DEVICE_ID" [string toupper $ipi_inst] "DEVICE_ID"]
|
||||
puts $file_handle [format "#define XPAR_%s_%s_%s XPAR_%s_%s" [string toupper $drv_string] $idx "BASE_ADDRESS" [string toupper $ipi_inst] "BASE_ADDRESS"]
|
||||
puts $file_handle [format "#define XPAR_%s_%s_%s XPAR_%s_%s" [string toupper $drv_string] $idx "BIT_MASK" [string toupper $ipi_inst] "BIT_MASK"]
|
||||
puts $file_handle [format "#define XPAR_%s_%s_%s XPAR_%s_%s" [string toupper $drv_string] $idx "BUFFER_INDEX" [string toupper $ipi_inst] "BUFFER_INDEX"]
|
||||
puts $file_handle [format "#define XPAR_%s_%s_%s XPAR_%s_%s" [string toupper $drv_string] $idx "INT_ID" [string toupper $ipi_inst] "INT_ID"]
|
||||
puts $file_handle ""
|
||||
incr idx
|
||||
}
|
||||
|
||||
#Total number of IPIs assigned to this proc
|
||||
puts $file_handle [format "#define XPAR_XIPIPSU_NUM_TARGETS %s" [llength $ipi_list]]
|
||||
puts $file_handle ""
|
||||
|
||||
foreach ipi_inst $ipi_list {
|
||||
puts $file_handle [ipi_define_xpar $ipi_inst CONFIG.C_BIT_POSITION]
|
||||
puts $file_handle [ipi_define_xpar $ipi_inst CONFIG.C_BUFFER_INDEX]
|
||||
puts ""
|
||||
}
|
||||
# Generate Canonical definitions to map IPI instance -> Processors
|
||||
puts $file_handle "/* Target List for referring to processor IPI Targets */"
|
||||
puts $file_handle ""
|
||||
foreach proc $proc_list {
|
||||
# List of IPIs owned by this processor
|
||||
set proc_slave_list [lsearch -all -inline [get_property SLAVES $proc] psu_ipi_*]
|
||||
|
||||
set idx 0
|
||||
foreach ipi_slave $proc_slave_list {
|
||||
puts $file_handle [format "#define XPAR_XIPIPS_TARGET_%s_CH%s_MASK XPAR_%s_BIT_MASK" [string toupper $proc] $idx [string toupper $ipi_slave]]
|
||||
puts $file_handle [format "#define XPAR_XIPIPS_TARGET_%s_CH%s_INDEX %s" [string toupper $proc] $idx [lsearch $ipi_list $ipi_slave]]
|
||||
puts ""
|
||||
incr idx
|
||||
}
|
||||
puts $file_handle ""
|
||||
}
|
||||
|
||||
# close the include file
|
||||
close $file_handle
|
||||
|
||||
}
|
||||
|
||||
|
||||
#This is called by HSI while generating the driver
|
||||
proc generate {drv_handle} {
|
||||
ipi_generate_params "xparameters.h"
|
||||
ipi_generate_config $drv_handle "xipipsu_g.c"
|
||||
}
|
|
@ -0,0 +1,315 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 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 THE
|
||||
* XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
|
||||
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* Except as contained in this notice, the name of the Xilinx shall not be used
|
||||
* in advertising or otherwise to promote the sale, use or other dealings in
|
||||
* this Software without prior written authorization from Xilinx.
|
||||
*
|
||||
******************************************************************************/
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
* @file xipipsu_self_test_example.c
|
||||
*
|
||||
* This file consists of a self test example which uses the XIpiPsu driver to
|
||||
* send an IPI message to self and get a response
|
||||
* Each IPI channel can trigger an interrupt to itself and can exchange messages
|
||||
* through the message buffer. This feature is used here to exercise the driver
|
||||
* APIs.
|
||||
* Example control flow:
|
||||
* - Init the IPI and GIC drivers
|
||||
* - Setup Interrupt System with IPI handler which inverts the received message
|
||||
* and sends back as response
|
||||
* - Write a Message and Trigger IPI to Self.
|
||||
* - Keep polling for response till timeout
|
||||
* - Interrupt handler receives IPI and sends back response
|
||||
* - Read the received response and do a sanity check
|
||||
* - Print PASS or FAIL based on sanity check of response message
|
||||
******************************************************************************/
|
||||
#include "stdlib.h"
|
||||
#include "xil_types.h"
|
||||
|
||||
/***************************** Include Files *********************************/
|
||||
|
||||
#include "xparameters.h"
|
||||
#include "xil_exception.h"
|
||||
#include "xil_cache.h"
|
||||
#include "xscugic.h"
|
||||
#include "xipipsu.h"
|
||||
#include "xipipsu_hw.h"
|
||||
|
||||
/************************* Test Configuration ********************************/
|
||||
/* IPI device ID to use for this test */
|
||||
#define TEST_CHANNEL_ID XPAR_XIPIPSU_1_DEVICE_ID
|
||||
/* Test message length in words. Max is 8 words (32 bytes) */
|
||||
#define TEST_MSG_LEN 8
|
||||
/* Interrupt Controller device ID */
|
||||
#define INTC_DEVICE_ID XPAR_SCUGIC_0_DEVICE_ID
|
||||
/* Time out parameter while polling for response */
|
||||
#define TIMEOUT_COUNT 10000
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
/* Global Instances of GIC and IPI devices */
|
||||
XScuGic GicInst;
|
||||
XIpiPsu IpiInst;
|
||||
|
||||
/* Buffers to store Test Data */
|
||||
u32 MsgBuffer[TEST_MSG_LEN];
|
||||
|
||||
static void InvertBuffer(u32 *BufPtr,u32 MsgLen)
|
||||
{
|
||||
u32 l_Index;
|
||||
|
||||
for(l_Index=0;l_Index<MsgLen; l_Index++){
|
||||
BufPtr[l_Index]= ~BufPtr[l_Index];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Interrupt Handler :
|
||||
* -Polls for each of the valid sources
|
||||
* -Checks if there is a message
|
||||
* -Reads the message
|
||||
* -Inverts the bits
|
||||
* -Sends back the inverted message as response
|
||||
*
|
||||
*/
|
||||
void IpiIntrHandler(void *XIpiPsuPtr)
|
||||
{
|
||||
|
||||
u32 IpiSrcMask; /**< Holds the IPI status register value */
|
||||
u32 Index;
|
||||
|
||||
u32 TmpBufPtr[TEST_MSG_LEN] = { 0 }; /**< Holds the received Message, later inverted and sent back as response*/
|
||||
|
||||
u32 SrcIndex;
|
||||
XIpiPsu *InstancePtr = (XIpiPsu *) XIpiPsuPtr;
|
||||
|
||||
xil_printf("---->Enter Interrupt Handler\r\n");
|
||||
|
||||
Xil_AssertVoid(InstancePtr!=NULL);
|
||||
|
||||
IpiSrcMask = XIpiPsu_GetInterruptStatus(InstancePtr);
|
||||
|
||||
/* Poll for each source and send Response (Response = ~Msg) */
|
||||
|
||||
for (SrcIndex = 0U; SrcIndex < InstancePtr->Config.TargetCount;
|
||||
SrcIndex++) {
|
||||
|
||||
if (IpiSrcMask & InstancePtr->Config.TargetList[SrcIndex].Mask) {
|
||||
|
||||
/* Read Incoming Message Buffer Corresponding to Source CPU */
|
||||
XIpiPsu_ReadMessage(InstancePtr,
|
||||
InstancePtr->Config.TargetList[SrcIndex].Mask, TmpBufPtr,
|
||||
TEST_MSG_LEN, XIPIPSU_BUF_TYPE_MSG);
|
||||
|
||||
xil_printf("Message Received:\r\n");
|
||||
|
||||
for (Index = 0; Index < TEST_MSG_LEN; Index++) {
|
||||
xil_printf("W%d: 0x%08x\r\n", Index, TmpBufPtr[Index]);
|
||||
}
|
||||
|
||||
/*Process the Received Message */
|
||||
InvertBuffer(TmpBufPtr, TEST_MSG_LEN);
|
||||
|
||||
/* Send Response */
|
||||
XIpiPsu_WriteMessage(InstancePtr,
|
||||
InstancePtr->Config.TargetList[SrcIndex].Mask, TmpBufPtr,
|
||||
TEST_MSG_LEN, XIPIPSU_BUF_TYPE_RESP);
|
||||
xil_printf("Sent back Inverted Message.\r\n");
|
||||
|
||||
/* Clear the Interrupt Status - This clears the OBS bit on teh SRC CPU registers */
|
||||
XIpiPsu_ClearInterruptStatus(InstancePtr,
|
||||
InstancePtr->Config.TargetList[SrcIndex].Mask);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
xil_printf("<----Exit Interrupt Handler\r\n");
|
||||
|
||||
}
|
||||
|
||||
|
||||
static XStatus SetupInterruptSystem(XScuGic *IntcInstancePtr,
|
||||
XIpiPsu *IpiInstancePtr, u32 IpiIntrId) {
|
||||
u32 Status = 0;
|
||||
XScuGic_Config *IntcConfig; /* Config for interrupt controller */
|
||||
|
||||
/* Initialize the interrupt controller driver */
|
||||
IntcConfig = XScuGic_LookupConfig(INTC_DEVICE_ID);
|
||||
if (NULL == IntcConfig) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
Status = XScuGic_CfgInitialize(&GicInst, IntcConfig,
|
||||
IntcConfig->CpuBaseAddress);
|
||||
if (Status != XST_SUCCESS) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Connect the interrupt controller interrupt handler to the
|
||||
* hardware interrupt handling logic in the processor.
|
||||
*/
|
||||
Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT,
|
||||
(Xil_ExceptionHandler) XScuGic_InterruptHandler, IntcInstancePtr);
|
||||
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
xil_printf("Interrupt ID: %d\r\n",IpiIntrId);
|
||||
Status = XScuGic_Connect(IntcInstancePtr, IpiIntrId,
|
||||
(Xil_InterruptHandler) IpiIntrHandler, (void *) IpiInstancePtr);
|
||||
|
||||
if (Status != XST_SUCCESS) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
/* Enable the interrupt for the device */
|
||||
XScuGic_Enable(IntcInstancePtr, IpiIntrId);
|
||||
|
||||
/* Enable interrupts */
|
||||
Xil_ExceptionEnable();
|
||||
|
||||
return XST_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Tests the IPI by sending a message and checking the response
|
||||
*/
|
||||
|
||||
static XStatus DoIpiTest(XIpiPsu *InstancePtr)
|
||||
{
|
||||
|
||||
u32 Index;
|
||||
u32 Status;
|
||||
|
||||
u32 TmpBuffer[TEST_MSG_LEN] = { 0 };
|
||||
|
||||
XIpiPsu_Config *DestCfgPtr;
|
||||
DestCfgPtr = XIpiPsu_LookupConfig(TEST_CHANNEL_ID);
|
||||
|
||||
xil_printf("Message Content:\r\n");
|
||||
for (Index = 0; Index < TEST_MSG_LEN; Index++) {
|
||||
MsgBuffer[Index] = rand();
|
||||
xil_printf("W%d: 0x%08x\r\n", Index, MsgBuffer[Index]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a Message to TEST_TARGET and WAIT for ACK
|
||||
*/
|
||||
XIpiPsu_WriteMessage(InstancePtr, DestCfgPtr->BitMask, MsgBuffer,
|
||||
TEST_MSG_LEN,
|
||||
XIPIPSU_BUF_TYPE_MSG);
|
||||
xil_printf("Triggering IPI and Waiting for Response...\r\n");
|
||||
XIpiPsu_TriggerIpi(InstancePtr, DestCfgPtr->BitMask);
|
||||
Status = XIpiPsu_PollForAck(InstancePtr, DestCfgPtr->BitMask,
|
||||
TIMEOUT_COUNT);
|
||||
|
||||
if (XST_SUCCESS == Status) {
|
||||
|
||||
xil_printf("Received response.\r\n");
|
||||
/**
|
||||
* Read the Response buffer
|
||||
*/
|
||||
XIpiPsu_ReadMessage(InstancePtr, DestCfgPtr->BitMask, TmpBuffer,
|
||||
TEST_MSG_LEN, XIPIPSU_BUF_TYPE_RESP);
|
||||
/**
|
||||
* Set the Status to SUCCESS; Status will be set to FAILURE incase the check fails
|
||||
* in the consequent code
|
||||
*/
|
||||
Status = XST_SUCCESS;
|
||||
/*
|
||||
* Check if RESPONSE == (~MSG)
|
||||
*/
|
||||
xil_printf("Message : Response\r\n");
|
||||
|
||||
for (Index = 0; Index < TEST_MSG_LEN; Index++) {
|
||||
xil_printf("W%d -> 0x%08x : 0x%08x\r\n", Index, MsgBuffer[Index],
|
||||
TmpBuffer[Index]);
|
||||
if (MsgBuffer[Index] != (~TmpBuffer[Index])) {
|
||||
Status = XST_FAILURE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
xil_printf("Error: Timed Out polling for response\r\n");
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
int main() {
|
||||
|
||||
XIpiPsu_Config *CfgPtr;
|
||||
|
||||
int Status = XST_FAILURE;
|
||||
xil_printf("Hello IPI! [Build: %s %s]\r\n", __DATE__, __TIME__);
|
||||
|
||||
Xil_DCacheDisable();
|
||||
|
||||
/* Look Up the config data */
|
||||
CfgPtr = XIpiPsu_LookupConfig(TEST_CHANNEL_ID);
|
||||
|
||||
/* Init with the Cfg Data */
|
||||
XIpiPsu_CfgInitialize(&IpiInst, CfgPtr, CfgPtr->BaseAddress);
|
||||
|
||||
/* Setup the GIC */
|
||||
SetupInterruptSystem(&GicInst, &IpiInst, (IpiInst.Config.IntId));
|
||||
|
||||
/* Enable reception of IPIs from all CPUs */
|
||||
XIpiPsu_InterruptEnable(&IpiInst, XIPIPSU_ALL_MASK);
|
||||
|
||||
/* Clear Any existing Interrupts */
|
||||
XIpiPsu_ClearInterruptStatus(&IpiInst, XIPIPSU_ALL_MASK);
|
||||
|
||||
/* Call the test routine */
|
||||
Status = DoIpiTest(&IpiInst);
|
||||
|
||||
/* Print the test result */
|
||||
if (XST_SUCCESS == Status) {
|
||||
xil_printf("\r\n --PASS-- \r\n");
|
||||
} else {
|
||||
xil_printf("\r\n --FAIL-- \r\n");
|
||||
}
|
||||
|
||||
do {
|
||||
/**
|
||||
* Do Nothing
|
||||
* We need to loop on to receive IPIs and respond to them
|
||||
*/
|
||||
__asm("wfi");
|
||||
} while (1);
|
||||
|
||||
/* Control never reaches here */
|
||||
return Status;
|
||||
|
||||
}
|
40
XilinxProcessorIPLib/drivers/ipipsu/src/Makefile
Normal file
40
XilinxProcessorIPLib/drivers/ipipsu/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 xipipsu_libs clean
|
||||
|
||||
%.o: %.c
|
||||
${COMPILER} $(CC_FLAGS) $(ECC_FLAGS) $(INCLUDES) -o $@ $<
|
||||
|
||||
banner:
|
||||
echo "Compiling ipipsu"
|
||||
|
||||
xipipsu_libs: ${OBJECTS}
|
||||
$(ARCHIVER) -r ${RELEASEDIR}/${LIB} ${OBJECTS}
|
||||
|
||||
.PHONY: include
|
||||
include: xipipsu_includes
|
||||
|
||||
xipipsu_includes:
|
||||
${CP} ${INCLUDEFILES} ${INCLUDEDIR}
|
||||
|
||||
clean:
|
||||
rm -rf ${OBJECTS}
|
347
XilinxProcessorIPLib/drivers/ipipsu/src/xipipsu.c
Normal file
347
XilinxProcessorIPLib/drivers/ipipsu/src/xipipsu.c
Normal file
|
@ -0,0 +1,347 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 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 THE
|
||||
* XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
|
||||
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* Except as contained in this notice, the name of the Xilinx shall not be used
|
||||
* in advertising or otherwise to promote the sale, use or other dealings in
|
||||
* this Software without prior written authorization from Xilinx.
|
||||
*
|
||||
******************************************************************************/
|
||||
/****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* @file xipipsu.c
|
||||
*
|
||||
* This file contains the implementation of the interface functions for XIpiPsu
|
||||
* driver. Refer to the header file xipipsu.h for more detailed information.
|
||||
*
|
||||
* <pre>
|
||||
* MODIFICATION HISTORY:
|
||||
*
|
||||
* Ver Who Date Changes
|
||||
* ----- ------ -------- ----------------------------------------------
|
||||
* 1.00 mjr 03/15/15 First Release
|
||||
* </pre>
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
/***************************** Include Files ********************************/
|
||||
#include "xipipsu.h"
|
||||
#include "xipipsu_hw.h"
|
||||
|
||||
/****************************************************************************/
|
||||
/**
|
||||
* Initialize the Instance pointer based on a given Config Pointer
|
||||
*
|
||||
* @param InstancePtr is a pointer to the instance to be worked on
|
||||
* @param CfgPtr is the device configuration structure containing required
|
||||
* hardware build data
|
||||
* @param EffectiveAddress is the base address of the device. If address
|
||||
* translation is not utilized, this parameter can be passed in using
|
||||
* CfgPtr->Config.BaseAddress to specify the physical base address.
|
||||
* @return XST_SUCCESS if initialization was successful
|
||||
* XST_FAILURE in case of failure
|
||||
*
|
||||
*/
|
||||
|
||||
XStatus XIpiPsu_CfgInitialize(XIpiPsu *InstancePtr, XIpiPsu_Config * CfgPtr,
|
||||
UINTPTR EffectiveAddress)
|
||||
{
|
||||
u32 Index;
|
||||
/* Verify arguments */
|
||||
Xil_AssertNonvoid(InstancePtr != NULL);
|
||||
Xil_AssertNonvoid(CfgPtr != NULL);
|
||||
/* Set device base address and ID */
|
||||
InstancePtr->Config.DeviceId = CfgPtr->DeviceId;
|
||||
InstancePtr->Config.BaseAddress = EffectiveAddress;
|
||||
InstancePtr->Config.BitMask = CfgPtr->BitMask;
|
||||
InstancePtr->Config.IntId = CfgPtr->IntId;
|
||||
|
||||
InstancePtr->Config.TargetCount = CfgPtr->TargetCount;
|
||||
|
||||
for (Index = 0; Index < CfgPtr->TargetCount; Index++) {
|
||||
InstancePtr->Config.TargetList[Index].Mask =
|
||||
CfgPtr->TargetList[Index].Mask;
|
||||
InstancePtr->Config.TargetList[Index].BufferIndex =
|
||||
CfgPtr->TargetList[Index].BufferIndex;
|
||||
}
|
||||
|
||||
/* Mark the component as Ready */
|
||||
InstancePtr->IsReady = XIL_COMPONENT_IS_READY;
|
||||
return (XST_SUCCESS);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Reset the given IPI register set.
|
||||
* This function can be called to disable the IPIs from all
|
||||
* the sources and clear any pending IPIs in status register
|
||||
*
|
||||
* @param InstancePtr is the pointer to current IPI instance
|
||||
*
|
||||
*/
|
||||
|
||||
void XIpiPsu_Reset(XIpiPsu *InstancePtr)
|
||||
{
|
||||
|
||||
Xil_AssertVoid(InstancePtr != NULL);
|
||||
Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
|
||||
|
||||
/**************Disable***************/
|
||||
|
||||
XIpiPsu_WriteReg(InstancePtr->Config.BaseAddress, XIPIPSU_IDR_OFFSET,
|
||||
XIPIPSU_ALL_MASK);
|
||||
|
||||
/**************Clear***************/
|
||||
XIpiPsu_WriteReg(InstancePtr->Config.BaseAddress, XIPIPSU_ISR_OFFSET,
|
||||
XIPIPSU_ALL_MASK);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Trigger an IPI to a Destination CPU
|
||||
*
|
||||
* @param InstancePtr is the pointer to current IPI instance
|
||||
* @param DestCpuMask is the Mask of the CPU to which IPI is to be triggered
|
||||
*
|
||||
*
|
||||
* @return XST_SUCCESS if successful
|
||||
* XST_FAILURE if an error occurred
|
||||
*/
|
||||
|
||||
XStatus XIpiPsu_TriggerIpi(XIpiPsu *InstancePtr, u32 DestCpuMask)
|
||||
{
|
||||
|
||||
Xil_AssertNonvoid(InstancePtr != NULL);
|
||||
Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
|
||||
|
||||
/* Trigger an IPI to the Target */
|
||||
XIpiPsu_WriteReg(InstancePtr->Config.BaseAddress, XIPIPSU_TRIG_OFFSET,
|
||||
DestCpuMask);
|
||||
return XST_SUCCESS;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Poll for an acknowledgement using Observation Register
|
||||
*
|
||||
* @param InstancePtr is the pointer to current IPI instance
|
||||
* @param DestCpuMask is the Mask of the destination CPU from which ACK is expected
|
||||
* @param TimeOutCount is the Count after which the routines returns failure
|
||||
*
|
||||
* @return XST_SUCCESS if successful
|
||||
* XST_FAILURE if a timeout occurred
|
||||
*/
|
||||
|
||||
XStatus XIpiPsu_PollForAck(XIpiPsu *InstancePtr, u32 DestCpuMask,
|
||||
u32 TimeOutCount)
|
||||
{
|
||||
u32 Flag, PollCount;
|
||||
XStatus Status;
|
||||
|
||||
Xil_AssertNonvoid(InstancePtr != NULL);
|
||||
Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
|
||||
|
||||
PollCount = 0;
|
||||
/* Poll the OBS register until the corresponding DestCpu bit is cleared */
|
||||
do {
|
||||
Flag = (XIpiPsu_ReadReg(InstancePtr->Config.BaseAddress,
|
||||
XIPIPSU_OBS_OFFSET)) & (DestCpuMask);
|
||||
PollCount++;
|
||||
/* Check if the IPI was Acknowledged by the Target or we Timed Out*/
|
||||
} while ((0x00000000U != Flag) && (PollCount < TimeOutCount));
|
||||
|
||||
if (PollCount >= TimeOutCount) {
|
||||
Status = XST_FAILURE;
|
||||
} else {
|
||||
Status = XST_SUCCESS;
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the Buffer Index for a CPU specified by Mask
|
||||
*
|
||||
* @param InstancePtr is the pointer to current IPI instance
|
||||
* @param CpuMask is the Mask of the CPU form which Index is required
|
||||
*
|
||||
* @return Buffer Index value if CPU Mask is valid
|
||||
* XIPIPSU_MAX_BUFF_INDEX+1 if not valid
|
||||
*
|
||||
* @note Static function used only by XIpiPsu_GetBufferAddress
|
||||
*
|
||||
*/
|
||||
static u32 XIpiPsu_GetBufferIndex(XIpiPsu *InstancePtr, u32 CpuMask)
|
||||
{
|
||||
u32 BufferIndex;
|
||||
u32 Index;
|
||||
/* Init Index with an invalid value */
|
||||
BufferIndex = XIPIPSU_MAX_BUFF_INDEX + 1;
|
||||
|
||||
/*Search for CPU in the List */
|
||||
for (Index = 0; Index < InstancePtr->Config.TargetCount; Index++) {
|
||||
/*If we find the CPU , then set the Index and break the loop*/
|
||||
if (InstancePtr->Config.TargetList[Index].Mask == CpuMask) {
|
||||
BufferIndex = InstancePtr->Config.TargetList[Index].BufferIndex;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Return the Index */
|
||||
return BufferIndex;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the Buffer Address for a given pair of CPUs
|
||||
*
|
||||
* @param InstancePtr is the pointer to current IPI instance
|
||||
* @param SrcCpuMask is the Mask for Source CPU
|
||||
* @param DestCpuMask is the Mask for Destination CPU
|
||||
* @param BufferType is either XIPIPSU_BUF_TYPE_MSG or XIPIPSU_BUF_TYPE_RESP
|
||||
*
|
||||
* @return Valid Buffer Address if no error
|
||||
* NULL if an error occurred in calculating Address
|
||||
*
|
||||
*/
|
||||
|
||||
static u32* XIpiPsu_GetBufferAddress(XIpiPsu *InstancePtr, u32 SrcCpuMask,
|
||||
u32 DestCpuMask, u32 BufferType)
|
||||
{
|
||||
#ifdef __aarch64__
|
||||
u64 BufferAddr;
|
||||
#else
|
||||
u32 BufferAddr;
|
||||
#endif
|
||||
|
||||
u32 SrcIndex;
|
||||
u32 DestIndex;
|
||||
/* Get the buffer indices */
|
||||
SrcIndex = XIpiPsu_GetBufferIndex(InstancePtr, SrcCpuMask);
|
||||
DestIndex = XIpiPsu_GetBufferIndex(InstancePtr, DestCpuMask);
|
||||
|
||||
/* If we got an invalid buffer index, then return NULL pointer, else valid address */
|
||||
if ((SrcIndex > XIPIPSU_MAX_BUFF_INDEX)
|
||||
|| (DestIndex > XIPIPSU_MAX_BUFF_INDEX)) {
|
||||
BufferAddr = 0U;
|
||||
} else {
|
||||
|
||||
if (XIPIPSU_BUF_TYPE_MSG == BufferType) {
|
||||
BufferAddr = XIPIPSU_MSG_RAM_BASE
|
||||
+ (SrcIndex * XIPIPSU_BUFFER_OFFSET_GROUP)
|
||||
+ (DestIndex * XIPIPSU_BUFFER_OFFSET_TARGET);
|
||||
} else if (XIPIPSU_BUF_TYPE_RESP == BufferType) {
|
||||
BufferAddr = XIPIPSU_MSG_RAM_BASE
|
||||
+ (SrcIndex * XIPIPSU_BUFFER_OFFSET_GROUP)
|
||||
+ (DestIndex * XIPIPSU_BUFFER_OFFSET_TARGET)
|
||||
+ (XIPIPSU_BUFFER_OFFSET_RESPONSE);
|
||||
} else {
|
||||
BufferAddr = 0U;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return (u32 *) BufferAddr;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Read an Incoming Message from a Source
|
||||
*
|
||||
* @param InstancePtr is the pointer to current IPI instance
|
||||
* @param SrcCpuMask is the Device Mask for the CPU which has sent the message
|
||||
* @param MsgPtr is the pointer to Buffer to which the read message needs to be stored
|
||||
* @param MsgLength is the length of the buffer/message
|
||||
* @param BufType is the type of buffer (XIPIPSU_BUF_TYPE_MSG or XIPIPSU_BUF_TYPE_RESP)
|
||||
*
|
||||
* @return XST_SUCCESS if successful
|
||||
* XST_FAILURE if an error occurred
|
||||
*/
|
||||
|
||||
XStatus XIpiPsu_ReadMessage(XIpiPsu *InstancePtr, u32 TargetMask, u32 *MsgPtr,
|
||||
u32 MsgLength, u8 BufferType)
|
||||
{
|
||||
u32 *BufferPtr;
|
||||
u32 Index;
|
||||
u32 Status;
|
||||
|
||||
Xil_AssertNonvoid(InstancePtr != NULL);
|
||||
Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
|
||||
Xil_AssertNonvoid(MsgPtr != NULL);
|
||||
Xil_AssertNonvoid(MsgLength <= XIPIPSU_MAX_MSG_LEN);
|
||||
|
||||
BufferPtr = XIpiPsu_GetBufferAddress(InstancePtr, TargetMask,
|
||||
InstancePtr->Config.BitMask, BufferType);
|
||||
if (BufferPtr != NULL) {
|
||||
/* Copy the IPI Buffer contents into Users's Buffer*/
|
||||
for (Index = 0; Index < MsgLength; Index++) {
|
||||
MsgPtr[Index] = BufferPtr[Index];
|
||||
}
|
||||
Status = XST_SUCCESS;
|
||||
} else {
|
||||
Status = XST_FAILURE;
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Send a Message to Destination
|
||||
*
|
||||
* @param InstancePtr is the pointer to current IPI instance
|
||||
* @param DestCpuMask is the Device Mask for the destination CPU
|
||||
* @param MsgPtr is the pointer to Buffer which contains the message to be sent
|
||||
* @param MsgLength is the length of the buffer/message
|
||||
* @param BufType is the type of buffer (XIPIPSU_BUF_TYPE_MSG or XIPIPSU_BUF_TYPE_RESP)
|
||||
*
|
||||
* @return XST_SUCCESS if successful
|
||||
* XST_FAILURE if an error occurred
|
||||
*/
|
||||
|
||||
XStatus XIpiPsu_WriteMessage(XIpiPsu *InstancePtr, u32 TargetMask, u32 *MsgPtr,
|
||||
u32 MsgLength, u8 BufferType)
|
||||
{
|
||||
u32 *BufferPtr;
|
||||
u32 Index;
|
||||
u32 Status;
|
||||
|
||||
Xil_AssertNonvoid(InstancePtr != NULL);
|
||||
Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
|
||||
Xil_AssertNonvoid(MsgPtr != NULL);
|
||||
Xil_AssertNonvoid(MsgLength <= XIPIPSU_MAX_MSG_LEN);
|
||||
|
||||
BufferPtr = XIpiPsu_GetBufferAddress(InstancePtr,
|
||||
InstancePtr->Config.BitMask, TargetMask, BufferType);
|
||||
if (BufferPtr != NULL) {
|
||||
/* Copy the Message to IPI Buffer */
|
||||
for (Index = 0; Index < MsgLength; Index++) {
|
||||
BufferPtr[Index] = MsgPtr[Index];
|
||||
}
|
||||
Status = XST_SUCCESS;
|
||||
} else {
|
||||
Status = XST_FAILURE;
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
277
XilinxProcessorIPLib/drivers/ipipsu/src/xipipsu.h
Normal file
277
XilinxProcessorIPLib/drivers/ipipsu/src/xipipsu.h
Normal file
|
@ -0,0 +1,277 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 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 THE
|
||||
* XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
|
||||
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* Except as contained in this notice, the name of the Xilinx shall not be used
|
||||
* in advertising or otherwise to promote the sale, use or other dealings in
|
||||
* this Software without prior written authorization from Xilinx.
|
||||
*
|
||||
******************************************************************************/
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
* @file xipipsu.h
|
||||
*
|
||||
* This is the header file for implementation of IPIPSU driver.
|
||||
* Inter Processor Interrupt (IPI) is used for communication between
|
||||
* different processors on ZynqMP SoC. Each IPI register set has Trigger, Status
|
||||
* and Observation registers for communication between processors. Each IPI path
|
||||
* has a 32 byte buffer associated with it and these buffers are located in the
|
||||
* XPPU RAM. This driver supports the following operations:
|
||||
*
|
||||
* - Trigger IPIs to CPUs on the SoC
|
||||
* - Write and Read Message buffers
|
||||
* - Read the status of Observation Register to get status of Triggered IPI
|
||||
* - Enable/Disable IPIs from selected Masters
|
||||
* - Read the Status register to get the source of an incoming IPI
|
||||
*
|
||||
* <b>Initialization</b>
|
||||
* The config data for the driver is loaded and is based on the HW build. The
|
||||
* XIpiPsu_Config data structure contains all the data related to the
|
||||
* IPI driver instance and also teh available Target CPUs.
|
||||
*
|
||||
* <b>Sending an IPI</b>
|
||||
* The following steps can be followed to send an IPI:
|
||||
* - Write the Message into Message Buffer using XIpiPsu_WriteMessage()
|
||||
* - Trigger IPI using XIpiPsu_TriggerIpi()
|
||||
* - Wait for Ack using XIpiPsu_PollForAck()
|
||||
* - Read response using XIpiPsu_ReadMessage()
|
||||
*
|
||||
* @note XIpiPsu_GetObsStatus() before sending an IPI to ensure that the
|
||||
* previous IPI was serviced by the target
|
||||
*
|
||||
* <b>Receiving an IPI</b>
|
||||
* To receive an IPI, the following sequence can be followed:
|
||||
* - Register an interrupt handler for the IPIs interrupt ID
|
||||
* - Enable the required sources using XIpiPsu_InterruptEnable()
|
||||
* - In the interrupt handler, Check for source using XIpiPsu_GetInterruptStatus
|
||||
* - Read the message form source using XIpiPsu_ReadMessage()
|
||||
* - Write the response using XIpiPsu_WriteMessage()
|
||||
* - Ack the IPI using XIpiPsu_ClearInterruptStatus()
|
||||
*
|
||||
* @note XIpiPsu_Reset can be used at startup to clear the status and
|
||||
* disable all sources
|
||||
*
|
||||
*/
|
||||
/*****************************************************************************/
|
||||
#ifndef XIPIPSU_H_
|
||||
#define XIPIPSU_H_
|
||||
|
||||
|
||||
/***************************** Include Files *********************************/
|
||||
#include "xil_io.h"
|
||||
#include "xstatus.h"
|
||||
#include "xipipsu_hw.h"
|
||||
|
||||
/************************** Constant Definitions *****************************/
|
||||
#define XIPIPSU_BUF_TYPE_MSG (0x00000001U)
|
||||
#define XIPIPSU_BUF_TYPE_RESP (0x00000002U)
|
||||
#define XIPIPSU_MAX_MSG_LEN XIPIPSU_MSG_BUF_SIZE
|
||||
/**************************** Type Definitions *******************************/
|
||||
/**
|
||||
* Data structure used to refer IPI Targets
|
||||
*/
|
||||
typedef struct {
|
||||
u32 Mask; /**< Bit Mask for the target */
|
||||
u32 BufferIndex; /**< Buffer Index used for calculating buffer address */
|
||||
} XIpiPsu_Target;
|
||||
|
||||
/**
|
||||
* This typedef contains configuration information for the device.
|
||||
*/
|
||||
typedef struct {
|
||||
u32 DeviceId; /**< Unique ID of device */
|
||||
u32 BaseAddress; /**< Base address of the device */
|
||||
u32 BitMask; /**< BitMask to be used to identify this CPU */
|
||||
u32 BufferIndex; /**< Index of the IPI Message Buffer */
|
||||
u32 IntId; /**< Interrupt ID on GIC **/
|
||||
u32 TargetCount; /**< Number of available IPI Targets */
|
||||
XIpiPsu_Target TargetList[XIPIPSU_MAX_TARGETS] ; /** < List of IPI Targets */
|
||||
} XIpiPsu_Config;
|
||||
|
||||
/**
|
||||
* The XIpiPsu driver instance data. The user is required to allocate a
|
||||
* variable of this type for each IPI device in the system. A pointer
|
||||
* to a variable of this type is then passed to the driver API functions.
|
||||
*/
|
||||
typedef struct {
|
||||
XIpiPsu_Config Config; /**< Configuration structure */
|
||||
u32 IsReady; /**< Device is initialized and ready */
|
||||
u32 Options; /**< Options set in the device */
|
||||
} XIpiPsu;
|
||||
|
||||
/***************** Macros (Inline Functions) Definitions *********************/
|
||||
/**
|
||||
*
|
||||
* Read the register specified by the base address and offset
|
||||
*
|
||||
* @param BaseAddress is the base address of the IPI instance
|
||||
* @param RegOffset is the offset of the register relative to base
|
||||
*
|
||||
* @return Value of the specified register
|
||||
* @note
|
||||
* C-style signature
|
||||
* u32 XIpiPsu_ReadReg(u32 BaseAddress, u32 RegOffset)
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
#define XIpiPsu_ReadReg(BaseAddress, RegOffset) \
|
||||
Xil_In32((BaseAddress) + (RegOffset))
|
||||
|
||||
/****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* Write a value into a register specified by base address and offset
|
||||
*
|
||||
* @param BaseAddress is the base address of the IPI instance
|
||||
* @param RegOffset is the offset of the register relative to base
|
||||
* @param Data is a 32-bit value that is to be written into the specified register
|
||||
*
|
||||
* @note
|
||||
* C-style signature
|
||||
* void XIpiPsu_WriteReg(u32 BaseAddress, u32 RegOffset, u32 Data)
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
#define XIpiPsu_WriteReg(BaseAddress, RegOffset, Data) \
|
||||
Xil_Out32(((BaseAddress) + (RegOffset)), (Data))
|
||||
|
||||
/****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* Enable interrupts specified in <i>Mask</i>. The corresponding interrupt for
|
||||
* each bit set to 1 in <i>Mask</i>, will be enabled.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the instance to be worked on.
|
||||
* @param Mask contains a bit mask of interrupts to enable. The mask can
|
||||
* be formed using a set of bitwise or'd values of individual CPU masks
|
||||
*
|
||||
* @note
|
||||
* C-style signature
|
||||
* void XIpiPsu_InterruptEnable(XIpiPsu *InstancePtr, u32 Mask)
|
||||
*
|
||||
*****************************************************************************/
|
||||
#define XIpiPsu_InterruptEnable(InstancePtr, Mask) \
|
||||
XIpiPsu_WriteReg((InstancePtr)->Config.BaseAddress, \
|
||||
XIPIPSU_IER_OFFSET, \
|
||||
((Mask) & XIPIPSU_ALL_MASK));
|
||||
|
||||
/****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* Disable interrupts specified in <i>Mask</i>. The corresponding interrupt for
|
||||
* each bit set to 1 in <i>Mask</i>, will be disabled.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the instance to be worked on.
|
||||
* @param Mask contains a bit mask of interrupts to disable. The mask can
|
||||
* be formed using a set of bitwise or'd values of individual CPU masks
|
||||
*
|
||||
* @note
|
||||
* C-style signature
|
||||
* void XIpiPsu_InterruptDisable(XIpiPsu *InstancePtr, u32 Mask)
|
||||
*
|
||||
*****************************************************************************/
|
||||
#define XIpiPsu_InterruptDisable(InstancePtr, Mask) \
|
||||
XIpiPsu_WriteReg((InstancePtr)->Config.BaseAddress, \
|
||||
XIPIPSU_IDR_OFFSET, \
|
||||
((Mask) & XIPIPSU_ALL_MASK));
|
||||
/****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* Get the <i>STATUS REGISTER</i> of the current IPI instance.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the instance to be worked on.
|
||||
* @return Returns the Interrupt Status register(ISR) contents
|
||||
* @note User needs to parse this 32-bit value to check the source CPU
|
||||
* C-style signature
|
||||
* u32 XIpiPsu_GetInterruptStatus(XIpiPsu *InstancePtr)
|
||||
*
|
||||
*****************************************************************************/
|
||||
#define XIpiPsu_GetInterruptStatus(InstancePtr) \
|
||||
XIpiPsu_ReadReg((InstancePtr)->Config.BaseAddress, \
|
||||
XIPIPSU_ISR_OFFSET)
|
||||
/****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* Clear the <i>STATUS REGISTER</i> of the current IPI instance.
|
||||
* The corresponding interrupt status for
|
||||
* each bit set to 1 in <i>Mask</i>, will be cleared
|
||||
*
|
||||
* @param InstancePtr is a pointer to the instance to be worked on.
|
||||
* @param Mask corresponding to the source CPU*
|
||||
*
|
||||
* @note This function should be used after handling the IPI.
|
||||
* Clearing the status will automatically clear the corresponding bit in
|
||||
* OBSERVATION register of Source CPU
|
||||
* C-style signature
|
||||
* void XIpiPsu_ClearInterruptStatus(XIpiPsu *InstancePtr, u32 Mask)
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
#define XIpiPsu_ClearInterruptStatus(InstancePtr, Mask) \
|
||||
XIpiPsu_WriteReg((InstancePtr)->Config.BaseAddress, \
|
||||
XIPIPSU_ISR_OFFSET, \
|
||||
((Mask) & XIPIPSU_ALL_MASK));
|
||||
/****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* Get the <i>OBSERVATION REGISTER</i> of the current IPI instance.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the instance to be worked on.
|
||||
* @return Returns the Observation register(OBS) contents
|
||||
* @note User needs to parse this 32-bit value to check the status of
|
||||
* individual CPUs
|
||||
* C-style signature
|
||||
* u32 XIpiPsu_GetObsStatus(XIpiPsu *InstancePtr)
|
||||
*
|
||||
*****************************************************************************/
|
||||
#define XIpiPsu_GetObsStatus(InstancePtr) \
|
||||
XIpiPsu_ReadReg((InstancePtr)->Config.BaseAddress, \
|
||||
XIPIPSU_OBS_OFFSET)
|
||||
/****************************************************************************/
|
||||
/************************** Function Prototypes *****************************/
|
||||
|
||||
/* Static lookup function implemented in xipipsu_sinit.c */
|
||||
|
||||
XIpiPsu_Config *XIpiPsu_LookupConfig(u32 DeviceId);
|
||||
|
||||
/* Interface Functions implemented in xipipsu.c */
|
||||
|
||||
XStatus XIpiPsu_CfgInitialize(XIpiPsu *InstancePtr, XIpiPsu_Config * CfgPtr,
|
||||
UINTPTR EffectiveAddress);
|
||||
|
||||
void XIpiPsu_Reset(XIpiPsu *InstancePtr);
|
||||
|
||||
XStatus XIpiPsu_TriggerIpi(XIpiPsu *InstancePtr, u32 DestCpuMask);
|
||||
|
||||
XStatus XIpiPsu_PollForAck(XIpiPsu *InstancePtr, u32 DestCpuMask,
|
||||
u32 TimeOutCount);
|
||||
|
||||
XStatus XIpiPsu_ReadMessage(XIpiPsu *InstancePtr, u32 SrcCpuMask, u32 *MsgPtr,
|
||||
u32 MsgLength, u8 BufType);
|
||||
|
||||
XStatus XIpiPsu_WriteMessage(XIpiPsu *InstancePtr, u32 DestCpuMask, u32 *MsgPtr,
|
||||
u32 MsgLength, u8 BufType);
|
||||
|
||||
#endif /* XIPIPSU_H_ */
|
152
XilinxProcessorIPLib/drivers/ipipsu/src/xipipsu_g.c
Normal file
152
XilinxProcessorIPLib/drivers/ipipsu/src/xipipsu_g.c
Normal file
|
@ -0,0 +1,152 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 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 THE
|
||||
* XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
|
||||
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* Except as contained in this notice, the name of the Xilinx shall not be used
|
||||
* in advertising or otherwise to promote the sale, use or other dealings in
|
||||
* this Software without prior written authorization from Xilinx.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#include "xparameters.h"
|
||||
#include "xipipsu.h"
|
||||
|
||||
/*
|
||||
* The configuration table for devices
|
||||
*/
|
||||
|
||||
XIpiPsu_Config XIpiPsu_ConfigTable[] =
|
||||
{
|
||||
|
||||
{
|
||||
XPAR_PSU_IPI_0_DEVICE_ID,
|
||||
XPAR_PSU_IPI_0_BASE_ADDRESS,
|
||||
XPAR_PSU_IPI_0_BIT_MASK,
|
||||
XPAR_PSU_IPI_0_BUFFER_INDEX,
|
||||
XPAR_PSU_IPI_0_INT_ID,
|
||||
XPAR_XIPIPSU_NUM_TARGETS,
|
||||
{
|
||||
{
|
||||
XPAR_PSU_IPI_0_BIT_MASK,
|
||||
XPAR_PSU_IPI_0_BUFFER_INDEX
|
||||
},
|
||||
{
|
||||
XPAR_PSU_IPI_1_BIT_MASK,
|
||||
XPAR_PSU_IPI_1_BUFFER_INDEX
|
||||
},
|
||||
{
|
||||
XPAR_PSU_IPI_2_BIT_MASK,
|
||||
XPAR_PSU_IPI_2_BUFFER_INDEX
|
||||
},
|
||||
{
|
||||
XPAR_PSU_IPI_3_BIT_MASK,
|
||||
XPAR_PSU_IPI_3_BUFFER_INDEX
|
||||
},
|
||||
{
|
||||
XPAR_PSU_IPI_4_BIT_MASK,
|
||||
XPAR_PSU_IPI_4_BUFFER_INDEX
|
||||
},
|
||||
{
|
||||
XPAR_PSU_IPI_5_BIT_MASK,
|
||||
XPAR_PSU_IPI_5_BUFFER_INDEX
|
||||
},
|
||||
{
|
||||
XPAR_PSU_IPI_6_BIT_MASK,
|
||||
XPAR_PSU_IPI_6_BUFFER_INDEX
|
||||
},
|
||||
{
|
||||
XPAR_PSU_IPI_7_BIT_MASK,
|
||||
XPAR_PSU_IPI_7_BUFFER_INDEX
|
||||
},
|
||||
{
|
||||
XPAR_PSU_IPI_8_BIT_MASK,
|
||||
XPAR_PSU_IPI_8_BUFFER_INDEX
|
||||
},
|
||||
{
|
||||
XPAR_PSU_IPI_9_BIT_MASK,
|
||||
XPAR_PSU_IPI_9_BUFFER_INDEX
|
||||
},
|
||||
{
|
||||
XPAR_PSU_IPI_10_BIT_MASK,
|
||||
XPAR_PSU_IPI_10_BUFFER_INDEX
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
XPAR_PSU_IPI_7_DEVICE_ID,
|
||||
XPAR_PSU_IPI_7_BASE_ADDRESS,
|
||||
XPAR_PSU_IPI_7_BIT_MASK,
|
||||
XPAR_PSU_IPI_7_BUFFER_INDEX,
|
||||
XPAR_PSU_IPI_7_INT_ID,
|
||||
XPAR_XIPIPSU_NUM_TARGETS,
|
||||
{
|
||||
{
|
||||
XPAR_PSU_IPI_0_BIT_MASK,
|
||||
XPAR_PSU_IPI_0_BUFFER_INDEX
|
||||
},
|
||||
{
|
||||
XPAR_PSU_IPI_1_BIT_MASK,
|
||||
XPAR_PSU_IPI_1_BUFFER_INDEX
|
||||
},
|
||||
{
|
||||
XPAR_PSU_IPI_2_BIT_MASK,
|
||||
XPAR_PSU_IPI_2_BUFFER_INDEX
|
||||
},
|
||||
{
|
||||
XPAR_PSU_IPI_3_BIT_MASK,
|
||||
XPAR_PSU_IPI_3_BUFFER_INDEX
|
||||
},
|
||||
{
|
||||
XPAR_PSU_IPI_4_BIT_MASK,
|
||||
XPAR_PSU_IPI_4_BUFFER_INDEX
|
||||
},
|
||||
{
|
||||
XPAR_PSU_IPI_5_BIT_MASK,
|
||||
XPAR_PSU_IPI_5_BUFFER_INDEX
|
||||
},
|
||||
{
|
||||
XPAR_PSU_IPI_6_BIT_MASK,
|
||||
XPAR_PSU_IPI_6_BUFFER_INDEX
|
||||
},
|
||||
{
|
||||
XPAR_PSU_IPI_7_BIT_MASK,
|
||||
XPAR_PSU_IPI_7_BUFFER_INDEX
|
||||
},
|
||||
{
|
||||
XPAR_PSU_IPI_8_BIT_MASK,
|
||||
XPAR_PSU_IPI_8_BUFFER_INDEX
|
||||
},
|
||||
{
|
||||
XPAR_PSU_IPI_9_BIT_MASK,
|
||||
XPAR_PSU_IPI_9_BUFFER_INDEX
|
||||
},
|
||||
{
|
||||
XPAR_PSU_IPI_10_BIT_MASK,
|
||||
XPAR_PSU_IPI_10_BUFFER_INDEX
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
76
XilinxProcessorIPLib/drivers/ipipsu/src/xipipsu_hw.h
Normal file
76
XilinxProcessorIPLib/drivers/ipipsu/src/xipipsu_hw.h
Normal file
|
@ -0,0 +1,76 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 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 THE
|
||||
* XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
|
||||
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* Except as contained in this notice, the name of the Xilinx shall not be used
|
||||
* in advertising or otherwise to promote the sale, use or other dealings in
|
||||
* this Software without prior written authorization from Xilinx.
|
||||
*
|
||||
******************************************************************************/
|
||||
/**
|
||||
*
|
||||
* @file xipipsu_hw.h
|
||||
*
|
||||
* This file contains macro definitions for low level HW related params
|
||||
*
|
||||
* <pre>
|
||||
* MODIFICATION HISTORY:
|
||||
*
|
||||
* Ver Who Date Changes
|
||||
* ----- --- -------- -----------------------------------------------.
|
||||
* 1.0 mjr 03/15/15 First release
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
******************************************************************************/
|
||||
#ifndef XIPIPSU_HW_H_ /* prevent circular inclusions */
|
||||
#define XIPIPSU_HW_H_ /* by using protection macros */
|
||||
|
||||
/************************** Constant Definitions *****************************/
|
||||
/* Message RAM related params */
|
||||
#define XIPIPSU_MSG_RAM_BASE 0xFF990000U
|
||||
#define XIPIPSU_MSG_BUF_SIZE 8U /* Size in Words */
|
||||
#define XIPIPSU_MAX_BUFF_INDEX 7
|
||||
|
||||
/* EIGHT pairs of TWO buffers(msg+resp) of THIRTY TWO bytes each */
|
||||
#define XIPIPSU_BUFFER_OFFSET_GROUP (8U * 2U * 32U)
|
||||
#define XIPIPSU_BUFFER_OFFSET_TARGET (32U * 2U)
|
||||
#define XIPIPSU_BUFFER_OFFSET_RESPONSE (32U)
|
||||
|
||||
/* Max Number of IPI slots on the device */
|
||||
#define XIPIPSU_MAX_TARGETS 11
|
||||
|
||||
/* Register Offsets for each member of IPI Register Set */
|
||||
#define XIPIPSU_TRIG_OFFSET 0x00U
|
||||
#define XIPIPSU_OBS_OFFSET 0x04U
|
||||
#define XIPIPSU_ISR_OFFSET 0x10U
|
||||
#define XIPIPSU_IMR_OFFSET 0x14U
|
||||
#define XIPIPSU_IER_OFFSET 0x18U
|
||||
#define XIPIPSU_IDR_OFFSET 0x1CU
|
||||
|
||||
/* MASK of all valid IPI bits in above registers */
|
||||
#define XIPIPSU_ALL_MASK 0x0F0F0301U
|
||||
|
||||
#endif /* XIPIPSU_HW_H_ */
|
87
XilinxProcessorIPLib/drivers/ipipsu/src/xipipsu_sinit.c
Normal file
87
XilinxProcessorIPLib/drivers/ipipsu/src/xipipsu_sinit.c
Normal file
|
@ -0,0 +1,87 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 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 THE
|
||||
* XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
|
||||
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* Except as contained in this notice, the name of the Xilinx shall not be used
|
||||
* in advertising or otherwise to promote the sale, use or other dealings in
|
||||
* this Software without prior written authorization from Xilinx.
|
||||
*
|
||||
******************************************************************************/
|
||||
/**
|
||||
*
|
||||
* @file xipipsu_sinit.c
|
||||
*
|
||||
* The implementation of the XIpiPsu component's static initialization
|
||||
* functionality.
|
||||
*
|
||||
* <pre>
|
||||
* MODIFICATION HISTORY:
|
||||
*
|
||||
* Ver Who Date Changes
|
||||
* ----- --- -------- -----------------------------------------------
|
||||
* 1.0 mjr 03/15/15 First release
|
||||
* </pre>
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
/***************************** Include Files *********************************/
|
||||
#include "xil_types.h"
|
||||
#include "xparameters.h"
|
||||
#include "xipipsu.h"
|
||||
|
||||
/************************** Variable Definitions *****************************/
|
||||
extern XIpiPsu_Config XIpiPsu_ConfigTable[];
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
/**
|
||||
*
|
||||
* 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 contains the ID of the device to look up the
|
||||
* configuration for.
|
||||
*
|
||||
* @return A pointer to the configuration found or NULL if the specified
|
||||
* device ID was not found. See xipipsu.h for the definition of
|
||||
* XIpiPsu_Config.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
******************************************************************************/
|
||||
XIpiPsu_Config *XIpiPsu_LookupConfig(u32 DeviceId)
|
||||
{
|
||||
XIpiPsu_Config *CfgPtr = NULL;
|
||||
int Index;
|
||||
|
||||
for (Index = 0; Index < XPAR_XIPIPSU_NUM_INSTANCES; Index++) {
|
||||
if (XIpiPsu_ConfigTable[Index].DeviceId == DeviceId) {
|
||||
CfgPtr = &XIpiPsu_ConfigTable[Index];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return CfgPtr;
|
||||
}
|
Loading…
Add table
Reference in a new issue