openamp_echo_test: modified baremetal and platform code
This patch modifies the baremetal code to include ipi related code. It moves the baremetal specific platform API from platform.c to baremetal.c. It also moves the platform specific information from baremetal.h to platform.h. The patch also updates license information in linker script Signed-off-by: Kinjal Pravinbhai Patel <patelki@xilinx.com>
This commit is contained in:
parent
f8ebe0ef56
commit
07648bb90b
5 changed files with 431 additions and 189 deletions
|
@ -1,35 +1,33 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2014, Mentor Graphics Corporation
|
||||
* All rights reserved.
|
||||
*
|
||||
* Copyright (C) 2015 Xilinx, Inc. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the <ORGANIZATION> nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "xparameters.h"
|
||||
|
@ -37,8 +35,9 @@
|
|||
#include "xil_exception.h"
|
||||
#include "xscugic.h"
|
||||
#include "xil_cache.h"
|
||||
#include "platform.h"
|
||||
#include "xil_mmu.h"
|
||||
#include "baremetal.h"
|
||||
#include "platform.h"
|
||||
|
||||
XScuGic InterruptController;
|
||||
|
||||
|
@ -90,7 +89,6 @@ void zynqMP_r5_irq_isr() {
|
|||
XScuGic_CPUWriteReg(&InterruptController,XSCUGIC_EOI_OFFSET, raw_irq);
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
*
|
||||
*
|
||||
|
@ -112,17 +110,295 @@ void zynqMP_r5_irq_isr() {
|
|||
*
|
||||
***********************************************************************/
|
||||
void zynqMP_r5_map_mem_region(u32 addr, u32 size, u32 attrib) {
|
||||
|
||||
u32 Index,NumSize;
|
||||
|
||||
u32 Index, NumSize;
|
||||
/* Calculating the number of MBs required for the shared region*/
|
||||
NumSize = size / 0x100000;
|
||||
|
||||
/* Xil_SetTlbAttributes is designed to configure memory for 1MB
|
||||
region. The API is called multiple times to configure the number
|
||||
of MBs required by shared memory size (calculated as NumSize)*/
|
||||
* region. The API is called multiple times to configure the number
|
||||
* of MBs required by shared memory size (calculated as NumSize)*/
|
||||
for (Index = 0; Index < NumSize; Index ++)
|
||||
Xil_SetTlbAttributes(addr + 0x100000 * Index, attrib);
|
||||
}
|
||||
|
||||
/*
|
||||
***********************************************************************
|
||||
* IPI handling
|
||||
*
|
||||
***********************************************************************
|
||||
*/
|
||||
|
||||
#define IPI_TOTAL 11
|
||||
|
||||
typedef void (*ipi_handler_t)(unsigned long ipi_base_addr, unsigned int intr_mask, void *data);
|
||||
|
||||
struct ipi_handler_info {
|
||||
unsigned long ipi_base_addr;
|
||||
unsigned int intr_mask;
|
||||
void *data;
|
||||
ipi_handler_t ipi_handler;
|
||||
};
|
||||
|
||||
struct ipi_handler_info ipi_handler_table[IPI_TOTAL];
|
||||
|
||||
int ipi_index_map (unsigned int ipi_intr_mask) {
|
||||
switch (ipi_intr_mask) {
|
||||
case 0x08000000:
|
||||
return 10;
|
||||
case 0x04000000:
|
||||
return 9;
|
||||
case 0x02000000:
|
||||
return 8;
|
||||
case 0x01000000:
|
||||
return 7;
|
||||
case 0x00080000:
|
||||
return 6;
|
||||
case 0x00040000:
|
||||
return 5;
|
||||
case 0x00020000:
|
||||
return 4;
|
||||
case 0x00010000:
|
||||
return 3;
|
||||
case 0x00000200:
|
||||
return 2;
|
||||
case 0x00000100:
|
||||
return 1;
|
||||
case 0x00000001:
|
||||
return 0;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
void ipi_trigger(unsigned long ipi_base_addr, unsigned int trigger_mask) {
|
||||
Xil_Out32((ipi_base_addr + IPI_TRIG_OFFSET), trigger_mask);
|
||||
}
|
||||
|
||||
void ipi_register_handler(unsigned long ipi_base_addr, unsigned int intr_mask, void *data,
|
||||
void *ipi_handler) {
|
||||
int ipi_hd_i = ipi_index_map(intr_mask);
|
||||
if (ipi_hd_i < 0)
|
||||
return;
|
||||
ipi_handler_table[ipi_hd_i].ipi_base_addr = ipi_base_addr;
|
||||
ipi_handler_table[ipi_hd_i].intr_mask = intr_mask;
|
||||
ipi_handler_table[ipi_hd_i].ipi_handler = (ipi_handler_t)ipi_handler;
|
||||
ipi_handler_table[ipi_hd_i].data = data;
|
||||
Xil_Out32((ipi_base_addr + IPI_IER_OFFSET), intr_mask);
|
||||
}
|
||||
|
||||
void ipi_unregister_handler(unsigned long ipi_base_addr, unsigned int intr_mask) {
|
||||
int ipi_hd_i = ipi_index_map(intr_mask);
|
||||
if (ipi_hd_i < 0)
|
||||
return;
|
||||
memset(&(ipi_handler_table[ipi_hd_i]), 0, sizeof(struct ipi_handler_info));
|
||||
}
|
||||
|
||||
void ipi_isr(int vect_id, void *data) {
|
||||
unsigned long ipi_base_addr = *((unsigned long *)data);
|
||||
unsigned int ipi_intr_status = (unsigned int)Xil_In32(ipi_base_addr + IPI_ISR_OFFSET);
|
||||
int i = 0;
|
||||
do {
|
||||
for (i = 0; i < IPI_TOTAL; i++) {
|
||||
if (ipi_base_addr != ipi_handler_table[i].ipi_base_addr)
|
||||
continue;
|
||||
if (!(ipi_intr_status && (ipi_handler_table[i].intr_mask)))
|
||||
continue;
|
||||
Xil_Out32((ipi_base_addr + IPI_ISR_OFFSET), ipi_handler_table[i].intr_mask);
|
||||
ipi_handler_table[i].ipi_handler(ipi_base_addr, ipi_handler_table[i].intr_mask, ipi_handler_table[i].data);
|
||||
}
|
||||
ipi_intr_status = (unsigned int)Xil_In32(ipi_base_addr + IPI_ISR_OFFSET);
|
||||
}while (ipi_intr_status);
|
||||
}
|
||||
|
||||
int platform_interrupt_enable(unsigned int vector,unsigned int polarity,unsigned int priority) {
|
||||
XScuGic_EnableIntr(XPAR_SCUGIC_0_DIST_BASEADDR,vector);
|
||||
return (vector);
|
||||
}
|
||||
|
||||
int platform_interrupt_disable(unsigned int vector) {
|
||||
XScuGic_DisableIntr(XPAR_SCUGIC_0_DIST_BASEADDR,vector);
|
||||
return (vector);
|
||||
}
|
||||
|
||||
void platform_cache_all_flush_invalidate() {
|
||||
Xil_DCacheFlush();
|
||||
Xil_DCacheInvalidate();
|
||||
Xil_ICacheInvalidate();
|
||||
}
|
||||
|
||||
void platform_cache_disable() {
|
||||
Xil_DCacheDisable();
|
||||
Xil_ICacheDisable();
|
||||
}
|
||||
|
||||
void platform_map_mem_region(unsigned int va,unsigned int pa, unsigned int size,unsigned int flags) {
|
||||
return;
|
||||
}
|
||||
|
||||
unsigned long platform_vatopa(void *addr) {
|
||||
return ((unsigned long)addr);
|
||||
}
|
||||
|
||||
void *platform_patova(unsigned long addr) {
|
||||
return ((void *)addr);
|
||||
}
|
||||
|
||||
unsigned int old_value = 0;
|
||||
|
||||
void restore_global_interrupts() {
|
||||
|
||||
ARM_AR_INT_BITS_SET(old_value);
|
||||
|
||||
}
|
||||
|
||||
void disable_global_interrupts() {
|
||||
|
||||
unsigned int value = 0;
|
||||
|
||||
ARM_AR_INT_BITS_GET(&value);
|
||||
|
||||
if (value != old_value) {
|
||||
|
||||
ARM_AR_INT_BITS_SET(CORTEXR5_CPSR_INTERRUPTS_BITS);
|
||||
|
||||
old_value = value;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*==================================================================*/
|
||||
/* The function definitions below are provided to prevent the build */
|
||||
/* warnings for missing I/O function stubs in case of unhosted libs */
|
||||
/*==================================================================*/
|
||||
|
||||
#include <sys/stat.h>
|
||||
|
||||
/**
|
||||
* _fstat
|
||||
*
|
||||
* Status of an open file. For consistency with other minimal
|
||||
* implementations in these examples, all files are regarded
|
||||
* as character special devices.
|
||||
*
|
||||
* @param file - Unused.
|
||||
* @param st - Status structure.
|
||||
*
|
||||
*
|
||||
* A constant value of 0.
|
||||
*
|
||||
**/
|
||||
__attribute__((weak)) int _fstat(int file, struct stat * st)
|
||||
{
|
||||
return(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* isatty
|
||||
*
|
||||
*
|
||||
* Query whether output stream is a terminal. For consistency
|
||||
* with the other minimal implementations, which only support
|
||||
* output to stdout, this minimal implementation is suggested
|
||||
*
|
||||
* @param file - Unused
|
||||
*
|
||||
* @return s - A constant value of 1.
|
||||
*
|
||||
*/
|
||||
__attribute__((weak)) int _isatty(int file)
|
||||
{
|
||||
return(1);
|
||||
}
|
||||
|
||||
/**
|
||||
*_lseek
|
||||
*
|
||||
* Set position in a file. Minimal implementation.
|
||||
|
||||
*
|
||||
* @param file - Unused
|
||||
*
|
||||
* @param ptr - Unused
|
||||
*
|
||||
* @param dir - Unused
|
||||
*
|
||||
* @return - A constant value of 0.
|
||||
*
|
||||
*/
|
||||
__attribute__((weak)) int _lseek(int file, int ptr, int dir)
|
||||
{
|
||||
return(0);
|
||||
}
|
||||
|
||||
#if (RTL_RPC == 0)
|
||||
/**
|
||||
* _open
|
||||
*
|
||||
* Open a file. Minimal implementation
|
||||
*
|
||||
* @param filename - Unused
|
||||
* @param flags - Unused
|
||||
* @param mode - Unused
|
||||
*
|
||||
* return - A constant value of 1.
|
||||
*
|
||||
*/
|
||||
__attribute__((weak)) int _open(const char * filename, int flags, int mode)
|
||||
{
|
||||
/* Any number will work. */
|
||||
return(1);
|
||||
}
|
||||
|
||||
/**
|
||||
* _close
|
||||
*
|
||||
* Close a file. Minimal implementation.
|
||||
*
|
||||
*
|
||||
* @param file - Unused
|
||||
*
|
||||
*
|
||||
* return A constant value of -1.
|
||||
*
|
||||
*/
|
||||
__attribute__((weak)) int _close(int file)
|
||||
{
|
||||
return(-1);
|
||||
}
|
||||
|
||||
/**
|
||||
* _read
|
||||
*
|
||||
* Low level function to redirect IO to serial.
|
||||
*
|
||||
* @param fd - Unused
|
||||
* @param buffer - Buffer where read data will be placed.
|
||||
* @param buflen - Size (in bytes) of buffer.
|
||||
*
|
||||
* return - A constant value of 1.
|
||||
*
|
||||
*/
|
||||
__attribute__((weak)) int _read(int fd, char * buffer, int buflen)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* _write
|
||||
*
|
||||
* Low level function to redirect IO to serial.
|
||||
*
|
||||
*
|
||||
* @param file - Unused
|
||||
* @param CHAR *ptr - String to output
|
||||
* @param len - Length of the string
|
||||
*
|
||||
* return len - The length of the string
|
||||
*
|
||||
*/
|
||||
__attribute__((weak)) int _write (int file, const char * ptr, int len)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -34,13 +34,58 @@
|
|||
|
||||
#include "xil_types.h"
|
||||
#include "xparameters.h"
|
||||
|
||||
void zynqMP_r5_map_mem_region(u32 addr, u32 size, u32 attrib);
|
||||
int zynqMP_r5_gic_initialize();
|
||||
void zynqMP_r5_irq_isr();
|
||||
|
||||
#include "xil_cache.h"
|
||||
#include "xreg_cortexr5.h"
|
||||
|
||||
#define INTC_DEVICE_ID XPAR_SCUGIC_0_DEVICE_ID
|
||||
|
||||
#define platform_dcache_all_flush() { Xil_DCacheFlush(); }
|
||||
|
||||
#define platform_dcache_flush_range(addr, len) { Xil_DCacheFlushRange(addr, len); }
|
||||
|
||||
#define CORTEXR5_CPSR_INTERRUPTS_BITS (XREG_CPSR_IRQ_ENABLE | XREG_CPSR_FIQ_ENABLE)
|
||||
|
||||
/* This macro writes the current program status register (CPSR - all fields) */
|
||||
#define ARM_AR_CPSR_CXSF_WRITE(cpsr_cxsf_value) \
|
||||
{ \
|
||||
asm volatile(" MSR CPSR_cxsf, %0" \
|
||||
: /* No outputs */ \
|
||||
: "r" (cpsr_cxsf_value) ); \
|
||||
}
|
||||
|
||||
/* This macro sets the interrupt related bits in the status register / control
|
||||
register to the specified value. */
|
||||
#define ARM_AR_INT_BITS_SET(set_bits) \
|
||||
{ \
|
||||
int tmp_val; \
|
||||
tmp_val = mfcpsr(); \
|
||||
tmp_val &= ~((unsigned int)CORTEXR5_CPSR_INTERRUPTS_BITS); \
|
||||
tmp_val |= set_bits; \
|
||||
ARM_AR_CPSR_CXSF_WRITE(tmp_val); \
|
||||
}
|
||||
|
||||
/* This macro gets the interrupt related bits from the status register / control
|
||||
register. */
|
||||
#define ARM_AR_INT_BITS_GET(get_bits_ptr) \
|
||||
{ \
|
||||
int tmp_val; \
|
||||
tmp_val = mfcpsr(); \
|
||||
tmp_val &= CORTEXR5_CPSR_INTERRUPTS_BITS; \
|
||||
*get_bits_ptr = tmp_val; \
|
||||
}
|
||||
void zynqMP_r5_map_mem_region(u32 addr, u32 size, u32 attrib);
|
||||
|
||||
int zynqMP_r5_gic_initialize();
|
||||
void zynqMP_r5_irq_isr();
|
||||
|
||||
void restore_global_interrupts();
|
||||
void disable_global_interrupts();
|
||||
int platform_interrupt_enable(unsigned int vector,unsigned int polarity, unsigned int priority);
|
||||
int platform_interrupt_disable(unsigned int vector);
|
||||
void platform_cache_all_flush_invalidate();
|
||||
void platform_cache_disable();
|
||||
void platform_map_mem_region(unsigned int va,unsigned int pa, unsigned int size, unsigned int flags);
|
||||
unsigned long platform_vatopa(void *addr);
|
||||
void *platform_patova(unsigned long addr);
|
||||
|
||||
#endif /* _BAREMETAL_H */
|
||||
|
|
|
@ -1,14 +1,34 @@
|
|||
/*******************************************************************/
|
||||
/* */
|
||||
/* This file is automatically generated by linker script generator.*/
|
||||
/* */
|
||||
/* Version: */
|
||||
/* */
|
||||
/* Copyright (c) 2015 Xilinx, Inc. All rights reserved. */
|
||||
/* */
|
||||
/* Description : Cortex-R5 Linker Script */
|
||||
/* */
|
||||
/*******************************************************************/
|
||||
/******************************************************************************
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
_STACK_SIZE = DEFINED(_STACK_SIZE) ? _STACK_SIZE : 0x2000;
|
||||
_HEAP_SIZE = DEFINED(_HEAP_SIZE) ? _HEAP_SIZE : 0x4000;
|
||||
|
|
|
@ -37,14 +37,13 @@
|
|||
* DESCRIPTION
|
||||
*
|
||||
* This file is the Implementation of IPC hardware layer interface
|
||||
* for Xilinx ZynqMP platform.
|
||||
* for Xilinx Zynq ZC702EVK platform.
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
#include "platform.h"
|
||||
#include "xil_io.h"
|
||||
#include "xscugic.h"
|
||||
#include "xil_cache.h"
|
||||
#include "baremetal.h"
|
||||
|
||||
/*--------------------------- Globals ---------------------------------- */
|
||||
struct hil_platform_ops proc_ops = {
|
||||
.enable_interrupt = _enable_interrupt,
|
||||
|
@ -54,20 +53,32 @@ struct hil_platform_ops proc_ops = {
|
|||
.shutdown_cpu = _shutdown_cpu,
|
||||
};
|
||||
|
||||
unsigned int old_value = 0;
|
||||
extern void ipi_enable_interrupt(unsigned int vector);
|
||||
extern void ipi_isr(int vect_id, void *data);
|
||||
|
||||
extern void ipi_register_interrupt(unsigned long ipi_base_addr, unsigned int intr_mask, void *data, void *ipi_handler);
|
||||
|
||||
void _ipi_handler (unsigned long ipi_base_addr, unsigned int intr_mask, void *data) {
|
||||
struct proc_vring *vring_hw = (struct proc_vring *) data;
|
||||
platform_dcache_all_flush();
|
||||
hil_isr(vring_hw);
|
||||
}
|
||||
|
||||
void _ipi_handler_deinit (unsigned long ipi_base_addr, unsigned int intr_mask, void *data) {
|
||||
return;
|
||||
}
|
||||
|
||||
int _enable_interrupt(struct proc_vring *vring_hw) {
|
||||
|
||||
struct ipi_info *chn_ipi_info = (struct ipi_info *)(vring_hw->intr_info.data);
|
||||
|
||||
if (vring_hw->intr_info.vect_id < 0)
|
||||
return 0;
|
||||
|
||||
/* Register IPI handler */
|
||||
ipi_register_handler(chn_ipi_info->ipi_base_addr, chn_ipi_info->ipi_chn_mask, vring_hw, _ipi_handler);
|
||||
/* Register ISR*/
|
||||
env_register_isr(vring_hw->intr_info.vect_id, vring_hw, platform_isr);
|
||||
|
||||
env_register_isr(vring_hw->intr_info.vect_id, &(chn_ipi_info->ipi_base_addr), ipi_isr);
|
||||
/* Enable IPI interrupt */
|
||||
struct ipi_info *chn_ipi_info = (struct ipi_info *)(vring_hw->intr_info.data);
|
||||
Xil_Out32((chn_ipi_info->ipi_base_addr + IPI_IER_OFFSET), chn_ipi_info->ipi_chn_mask);
|
||||
/* Enable the interrupts */
|
||||
env_enable_interrupt(vring_hw->intr_info.vect_id,
|
||||
vring_hw->intr_info.priority,
|
||||
vring_hw->intr_info.trigger_type);
|
||||
|
@ -76,12 +87,9 @@ int _enable_interrupt(struct proc_vring *vring_hw) {
|
|||
|
||||
void _reg_ipi_after_deinit(struct proc_vring *vring_hw) {
|
||||
struct ipi_info *chn_ipi_info = (struct ipi_info *)(vring_hw->intr_info.data);
|
||||
|
||||
if (vring_hw->intr_info.vect_id < 0) {
|
||||
return;
|
||||
}
|
||||
env_update_isr(vring_hw->intr_info.vect_id, chn_ipi_info, deinit_isr);
|
||||
|
||||
env_disable_interrupts();
|
||||
ipi_register_handler(chn_ipi_info->ipi_base_addr, chn_ipi_info->ipi_chn_mask, 0, _ipi_handler_deinit);
|
||||
env_restore_interrupts();
|
||||
}
|
||||
|
||||
void _notify(int cpu_id, struct proc_intr *intr_info) {
|
||||
|
@ -91,7 +99,7 @@ void _notify(int cpu_id, struct proc_intr *intr_info) {
|
|||
return;
|
||||
platform_dcache_all_flush();
|
||||
/* Trigger IPI */
|
||||
Xil_Out32((chn_ipi_info->ipi_base_addr + IPI_TRIG_OFFSET), chn_ipi_info->ipi_chn_mask);
|
||||
ipi_trigger(chn_ipi_info->ipi_base_addr, chn_ipi_info->ipi_chn_mask);
|
||||
}
|
||||
|
||||
int _boot_cpu(int cpu_id, unsigned int load_addr) {
|
||||
|
@ -102,75 +110,3 @@ void _shutdown_cpu(int cpu_id) {
|
|||
return;
|
||||
}
|
||||
|
||||
void platform_isr(int vect_id, void *data) {
|
||||
struct proc_vring *vring_hw = (struct proc_vring *) data;
|
||||
struct ipi_info *chn_ipi_info = (struct ipi_info *)(vring_hw->intr_info.data);
|
||||
unsigned int ipi_intr_status = (unsigned int)Xil_In32(chn_ipi_info->ipi_base_addr + IPI_ISR_OFFSET);
|
||||
if ((ipi_intr_status & chn_ipi_info->ipi_chn_mask)) {
|
||||
platform_dcache_all_flush();
|
||||
hil_isr(vring_hw);
|
||||
Xil_Out32((chn_ipi_info->ipi_base_addr + IPI_ISR_OFFSET), chn_ipi_info->ipi_chn_mask);
|
||||
}
|
||||
}
|
||||
|
||||
void deinit_isr(int vect_id, void *data) {
|
||||
struct ipi_info *chn_ipi_info = (struct ipi_info *)data;
|
||||
unsigned int ipi_intr_status = (unsigned int)Xil_In32(chn_ipi_info->ipi_base_addr + IPI_ISR_OFFSET);
|
||||
if ((ipi_intr_status & chn_ipi_info->ipi_chn_mask)) {
|
||||
Xil_Out32((chn_ipi_info->ipi_base_addr + IPI_ISR_OFFSET), chn_ipi_info->ipi_chn_mask);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void platform_interrupt_enable(u32 vector,u32 polarity, u32 priority) {
|
||||
XScuGic_EnableIntr(XPAR_SCUGIC_0_DIST_BASEADDR,vector);
|
||||
}
|
||||
|
||||
void platform_interrupt_disable(unsigned int vector) {
|
||||
XScuGic_DisableIntr(XPAR_SCUGIC_0_DIST_BASEADDR,vector);
|
||||
}
|
||||
|
||||
void platform_cache_all_flush_invalidate() {
|
||||
Xil_DCacheFlush();
|
||||
Xil_DCacheInvalidate();
|
||||
Xil_ICacheInvalidate();
|
||||
}
|
||||
|
||||
void platform_cache_disable() {
|
||||
Xil_DCacheDisable();
|
||||
Xil_ICacheDisable();
|
||||
}
|
||||
|
||||
void platform_map_mem_region(unsigned int va,unsigned int pa, unsigned int size,int is_mem_mapped,int cache_type) {
|
||||
return;
|
||||
}
|
||||
|
||||
unsigned long platform_vatopa(unsigned long addr) {
|
||||
return ((unsigned long)addr);
|
||||
}
|
||||
|
||||
void *platform_patova(unsigned long addr) {
|
||||
return ((void *)addr);
|
||||
}
|
||||
|
||||
void restore_global_interrupts() {
|
||||
|
||||
ARM_AR_INT_BITS_SET(old_value);
|
||||
|
||||
}
|
||||
|
||||
void disable_global_interrupts() {
|
||||
|
||||
unsigned int value = 0;
|
||||
|
||||
ARM_AR_INT_BITS_GET(&value);
|
||||
|
||||
if (value != old_value) {
|
||||
|
||||
ARM_AR_INT_BITS_SET(CORTEXR5_CPSR_INTERRUPTS_BITS);
|
||||
|
||||
old_value = value;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -34,8 +34,7 @@
|
|||
|
||||
#include <stdio.h>
|
||||
#include "hil.h"
|
||||
#include "xil_cache.h"
|
||||
#include "xreg_cortexr5.h"
|
||||
|
||||
/* ------------------------- Macros --------------------------*/
|
||||
|
||||
/********************/
|
||||
|
@ -48,17 +47,6 @@ struct ipi_info {
|
|||
uint32_t ipi_chn_mask;
|
||||
};
|
||||
|
||||
int _enable_interrupt(struct proc_vring *vring_hw);
|
||||
void _reg_ipi_after_deinit(struct proc_vring *vring_hw);
|
||||
void _notify(int cpu_id, struct proc_intr *intr_info);
|
||||
int _boot_cpu(int cpu_id, unsigned int load_addr);
|
||||
void _shutdown_cpu(int cpu_id);
|
||||
void platform_isr(int vect_id, void *data);
|
||||
void deinit_isr(int vect_id, void *data);
|
||||
|
||||
#define platform_dcache_all_flush() { Xil_DCacheFlush(); }
|
||||
|
||||
#define platform_dcache_flush_range(addr, len) { Xil_DCacheFlushRange(addr, len); }
|
||||
/* IPI REGs OFFSET */
|
||||
#define IPI_TRIG_OFFSET 0x00000000 /* IPI trigger register offset */
|
||||
#define IPI_OBS_OFFSET 0x00000004 /* IPI observation register offset */
|
||||
|
@ -73,39 +61,16 @@ void deinit_isr(int vect_id, void *data);
|
|||
#define IPI_BASEADDR 0xff310000
|
||||
#define IPI_CHN_BITMASK 0x00000001 /* IPI channel bit mask APU<->RPU0 */
|
||||
#define VRING0_IPI_INTR_VECT -1
|
||||
#define VRING1_IPI_INTR_VECT 79
|
||||
#define VRING1_IPI_INTR_VECT 65
|
||||
#define MASTER_CPU_ID 0
|
||||
#define REMOTE_CPU_ID 1
|
||||
|
||||
#define CORTEXR5_CPSR_INTERRUPTS_BITS (XREG_CPSR_IRQ_ENABLE | XREG_CPSR_FIQ_ENABLE)
|
||||
|
||||
/* This macro writes the current program status register (CPSR - all fields) */
|
||||
#define ARM_AR_CPSR_CXSF_WRITE(cpsr_cxsf_value) \
|
||||
{ \
|
||||
asm volatile(" MSR CPSR_cxsf, %0" \
|
||||
: /* No outputs */ \
|
||||
: "r" (cpsr_cxsf_value) ); \
|
||||
}
|
||||
|
||||
/* This macro sets the interrupt related bits in the status register / control
|
||||
register to the specified value. */
|
||||
#define ARM_AR_INT_BITS_SET(set_bits) \
|
||||
{ \
|
||||
int tmp_val; \
|
||||
tmp_val = mfcpsr(); \
|
||||
tmp_val &= ~((unsigned int)CORTEXR5_CPSR_INTERRUPTS_BITS); \
|
||||
tmp_val |= set_bits; \
|
||||
ARM_AR_CPSR_CXSF_WRITE(tmp_val); \
|
||||
}
|
||||
|
||||
/* This macro gets the interrupt related bits from the status register / control
|
||||
register. */
|
||||
#define ARM_AR_INT_BITS_GET(get_bits_ptr) \
|
||||
{ \
|
||||
int tmp_val; \
|
||||
tmp_val = mfcpsr(); \
|
||||
tmp_val &= CORTEXR5_CPSR_INTERRUPTS_BITS; \
|
||||
*get_bits_ptr = tmp_val; \
|
||||
}
|
||||
int _enable_interrupt(struct proc_vring *vring_hw);
|
||||
void _reg_ipi_after_deinit(struct proc_vring *vring_hw);
|
||||
void _notify(int cpu_id, struct proc_intr *intr_info);
|
||||
int _boot_cpu(int cpu_id, unsigned int load_addr);
|
||||
void _shutdown_cpu(int cpu_id);
|
||||
void platform_isr(int vect_id, void *data);
|
||||
void deinit_isr(int vect_id, void *data);
|
||||
|
||||
#endif /* PLATFORM_H_ */
|
||||
|
|
Loading…
Add table
Reference in a new issue