sw_apps: added support for cortexA9 to openamp matrix multiply application

Signed-off-by: Kinjal Pravinbhai Patel <patelki@xilinx.com>
Acked-by: Anirudha Sarangi <anirudh@xilinx.com>
This commit is contained in:
Kinjal Pravinbhai Patel 2015-10-08 14:40:20 +05:30 committed by Nava kishore Manne
parent 0bcca21961
commit 5a398f8caa
25 changed files with 2025 additions and 5 deletions

View file

@ -73,10 +73,9 @@ proc swapp_is_supported_hw {} {
set proc_type [common::get_property IP_NAME [hsi::get_cells -hier $hw_processor]];
if { $proc_type != "psu_cortexr5" } {
error "This application is supported only for CortexR5 processors.";
if { ( $proc_type != "psu_cortexr5" ) && ( $proc_type != "ps7_cortexa9" ) } {
error "This application is supported only for CortexR5 and Cortex-A9 processors.";
}
return 1;
}
@ -94,6 +93,27 @@ proc swapp_generate {} {
if { [llength $oslist] != 1 } {
return 0;
}
set proc_instance [hsi::get_sw_processor];
set hw_processor [common::get_property HW_INSTANCE $proc_instance]
set proc_type [common::get_property IP_NAME [hsi::get_cells -hier $hw_processor]];
if { $proc_type == "psu_cortexr5" } {
set srcdir "ARM_R5/"
foreach entry [glob -nocomplain [file join $srcdir *]] {
file copy -force $entry "."
}
file delete -force "ARM_R5"
file delete -force "ARM_A9"
} elseif { $proc_type == "ps7_cortexa9" } {
set srcdir "ARM_A9/"
foreach entry [glob -nocomplain [file join $srcdir *]] {
file copy -force $entry "."
}
file delete -force "ARM_R5"
file delete -force "ARM_A9"
}
set os [lindex $oslist 0];
if { $os != "standalone" } {
set ld_file "lscript.ld"
@ -114,9 +134,9 @@ proc swapp_get_linker_constraints {} {
}
proc swapp_get_supported_processors {} {
return "psu_cortexr5";
return "psu_cortexr5 ps7_cortexa9";
}
proc swapp_get_supported_os {} {
return "freertos821_xilinx standalone";
}
}

View file

@ -0,0 +1,254 @@
/*
* 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 "baremetal.h"
#include "env.h"
#include "xscugic.h"
#ifdef USE_FREERTOS
extern XScuGic xInterruptController;
#else
XScuGic xInterruptController;
#endif
extern struct isr_info isr_table[ISR_COUNT];
extern struct XOpenAMPInstPtr OpenAMPInstPtr;
unsigned int xInsideISR;
int zc702evk_gic_initialize() {
void *intr_id;
#ifndef USE_FREERTOS
u32 Status;
XScuGic_Config *IntcConfig; /* The configuration parameters of the interrupt controller */
/*
* Initialize the interrupt controller driver
*/
IntcConfig = XScuGic_LookupConfig(INTC_DEVICE_ID);
if (NULL == IntcConfig) {
return XST_FAILURE;
}
Status = XScuGic_CfgInitialize(&xInterruptController, IntcConfig,
IntcConfig->CpuBaseAddress);
if (Status != XST_SUCCESS) {
return XST_FAILURE;
}
/*
* Register the interrupt handler to the hardware interrupt handling
* logic in the ARM processor.
*/
Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_IRQ_INT,
(Xil_ExceptionHandler)XScuGic_InterruptHandler,&xInterruptController);
Xil_ExceptionEnable();
#endif
intr_id = (void *)VRING1_IPI_VECT;
XScuGic_Connect(&xInterruptController, VRING1_IPI_VECT,
(Xil_ExceptionHandler)zynqa9_irq_isr,
intr_id);
intr_id = (void *)VRING0_IPI_VECT;
XScuGic_Connect(&xInterruptController, VRING0_IPI_VECT,
(Xil_ExceptionHandler)zynqa9_irq_isr,
intr_id);
return 0;
}
int platform_interrupt_enable(int vector_id, INT_TRIG_TYPE trigger_type,
int priority) {
unsigned long bit_shift;
unsigned long temp32 = 0;
/* Determine the necessary bit shift in this target / priority register
for this interrupt vector ID */
bit_shift = ((vector_id) % 4) * 8;
/* Read-modify-write the priority register for this interrupt */
temp32 = XScuGic_DistReadReg(&xInterruptController,XSCUGIC_PRIORITY_OFFSET_CALC(vector_id));
/* Set new priority. */
temp32 |= (priority << (bit_shift + 4));
XScuGic_DistWriteReg(&xInterruptController,XSCUGIC_PRIORITY_OFFSET_CALC(vector_id),temp32);
/* Write to the appropriate bit in the enable set register for this
vector ID to enable the interrupt */
XScuGic_EnableIntr(&xInterruptController.Config->DistBaseAddress,vector_id);
/* Return the vector ID */
return (vector_id);
}
int platform_interrupt_disable(int vector_id) {
XScuGic_DisableIntr(&xInterruptController.Config->DistBaseAddress,vector_id);
/* Return the vector ID */
return (vector_id);
}
extern void bm_env_isr(int vector);
/* IRQ handler */
void zynqa9_irq_isr(void *interrupt_id) {
xInsideISR=1;
OpenAMPInstPtr.IntrID = (unsigned int)interrupt_id;
env_release_sync_lock(OpenAMPInstPtr.lock);
xInsideISR=0;
}
void process_communication(struct XOpenAMPInstPtr OpenAMPInstance) {
int idx;
struct isr_info *info;
for(idx = 0; idx < ISR_COUNT; idx++)
{
info = &isr_table[idx];
if(info->vector == OpenAMPInstance.IntrID)
{
info->isr(info->vector , info->data, OpenAMPInstance.IPI_Status);
break;
}
}
}
int old_value = 0;
void restore_global_interrupts() {
#ifdef USE_FREERTOS
taskENABLE_INTERRUPTS();
#else
ARM_AR_INT_BITS_SET(old_value);
#endif
}
void disable_global_interrupts() {
#ifdef USE_FREERTOS
taskDISABLE_INTERRUPTS();
#else
int value = 0;
ARM_AR_INT_BITS_GET(&value);
if (value != old_value) {
ARM_AR_INT_BITS_SET(ARM_AR_INTERRUPTS_DISABLE_BITS);
old_value = value;
}
#endif
}
/***********************************************************************
*
*
* arm_ar_map_mem_region
*
*
* This function sets-up the region of memory based on the given
* attributes
*
* @param vrt_addr - virtual address of region
* @param phy_addr - physical address of region
* @parma size - size of region
* @param is_mem_mapped - memory mapped or not
* @param cache_type - cache type of region
*
*
* OUTPUTS
*
* None
*
***********************************************************************/
void arm_ar_map_mem_region(unsigned int vrt_addr, unsigned int phy_addr,
unsigned int size, int is_mem_mapped,
CACHE_TYPE cache_type) {
unsigned int ttb_value;
phy_addr &= ARM_AR_MEM_TTB_SECT_SIZE_MASK;
vrt_addr &= ARM_AR_MEM_TTB_SECT_SIZE_MASK;
ttb_value = ARM_AR_MEM_TTB_DESC_ALL_ACCESS;
if (!is_mem_mapped) {
/* Set cache related bits in translation table entry.
NOTE: Default is uncached instruction and data. */
if (cache_type == WRITEBACK) {
/* Update translation table entry value */
ttb_value |= (ARM_AR_MEM_TTB_DESC_B | ARM_AR_MEM_TTB_DESC_C);
} else if (cache_type == WRITETHROUGH) {
/* Update translation table entry value */
ttb_value |= ARM_AR_MEM_TTB_DESC_C;
}
/* In case of un-cached memory, set TEX 0 bit to set memory
attribute to normal. */
else if (cache_type == NOCACHE) {
ttb_value |= ARM_AR_MEM_TTB_DESC_TEX;
}
}
Xil_SetTlbAttributes(phy_addr,ttb_value);
}
void platform_map_mem_region(unsigned int vrt_addr, unsigned int phy_addr,
unsigned int size, unsigned int flags) {
int is_mem_mapped = 0;
int cache_type = 0;
if ((flags & (0x0f << 4 )) == MEM_MAPPED)
{
is_mem_mapped = 1;
}
if ((flags & 0x0f) == WB_CACHE) {
cache_type = WRITEBACK;
}
else if((flags & 0x0f) == WT_CACHE) {
cache_type = WRITETHROUGH;
}
else {
cache_type = NOCACHE;
}
arm_ar_map_mem_region(vrt_addr, phy_addr, size, is_mem_mapped, cache_type);
}
void platform_cache_all_flush_invalidate() {
Xil_L1DCacheFlush();
}
void platform_cache_disable() {
Xil_L1DCacheDisable();
}
unsigned long platform_vatopa(void *addr) {
return (((unsigned long)addr & (~( 0x0fff << 20))) | (0x08 << 24));
}
void *platform_patova(unsigned long addr){
return ((void *)addr);
}

View file

@ -0,0 +1,203 @@
/*
* 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.
*/
#ifndef _BAREMETAL_H
#define _BAREMETAL_H
#include "xpqueue.h"
#include "platform.h"
#include "amp_os.h"
#ifdef USE_FREERTOS
#include "FreeRTOS.h"
#include "task.h"
#include "timers.h"
#include "queue.h"
#endif
#include "xpqueue.h"
#include "xil_mmu.h"
#include "xil_cache.h"
#include "xil_exception.h"
struct XOpenAMPInstPtr{
unsigned int IntrID;
unsigned int IPI_Status;
void *lock;
#ifdef USE_FREERTOS
QueueHandle_t send_queue;
#else
pq_queue_t *send_queue;
#endif
};
/* Define bit values for the architecture's status register / machine state register /
etc that are used to enable and disable interrupts for the given architecture. */
#define ARM_AR_INTERRUPTS_DISABLE_BITS 0x000000C0
#define ARM_AR_INTERRUPTS_ENABLE_BITS 0x00000000
#define INTC_DEVICE_ID XPAR_SCUGIC_0_DEVICE_ID
/* This macro writes the c (control) bits of the current program status register (CPSR) */
#define ARM_AR_CPSR_C_WRITE(c_bits) \
{ \
asm volatile(" MSR CPSR_c, %0" \
: /* No outputs */ \
: "I" (c_bits) ); \
}
/* This macro reads the current program status register (CPSR - all fields) */
#define ARM_AR_CPSR_CXSF_READ(cpsr_cxsf_ptr) \
{ \
asm volatile(" MRS %0, CPSR" \
: "=r" (*(cpsr_cxsf_ptr)) \
: /* No inputs */ ); \
}
/* 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; \
\
ARM_AR_CPSR_CXSF_READ(&tmp_val); \
tmp_val &= ~ARM_AR_INTERRUPTS_DISABLE_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; \
\
ARM_AR_CPSR_CXSF_READ(&tmp_val); \
tmp_val &= ARM_AR_INTERRUPTS_DISABLE_BITS; \
*get_bits_ptr = tmp_val; \
}
#define ARM_AR_INTERRUPTS_DISABLE_BITS 0x000000C0
#define ARM_AR_INTERRUPTS_ENABLE_BITS 0x00000000
/* Macro used to make a 32-bit value with the specified bit set */
#define ESAL_GE_MEM_32BIT_SET(bit_num) (1UL<<(bit_num))
/* Macro used to make a 32-bit value with the specified bit clear */
#define ESAL_GE_MEM_32BIT_CLEAR(bit_num) ~(1UL<<(bit_num))
/* Translation table is 16K in size */
#define ARM_AR_MEM_TTB_SIZE 16*1024
/* Each TTB descriptor covers a 1MB region */
#define ARM_AR_MEM_TTB_SECT_SIZE 1024*1024
/* Mask off lower bits of addr */
#define ARM_AR_MEM_TTB_SECT_SIZE_MASK (~(ARM_AR_MEM_TTB_SECT_SIZE-1UL))
/* Define shift to convert memory address to index of translation table entry (descriptor).
Shift 20 bits (for a 1MB section) - 2 bits (for a 4 byte TTB descriptor) */
#define ARM_AR_MEM_TTB_SECT_TO_DESC_SHIFT (20-2)
/* Define domain access values */
#define ARM_AR_MEM_DOMAIN_D0_MANAGER_ACCESS 0x3
#define ARM_AR_MEM_TTB_DESC_BACKWARDS ESAL_GE_MEM_32BIT_SET(4)
#define ARM_AR_MEM_TTB_DESC_AP_MANAGER (ESAL_GE_MEM_32BIT_SET(10) | \
ESAL_GE_MEM_32BIT_SET(11))
#define ARM_AR_MEM_TTB_DESC_SECT ESAL_GE_MEM_32BIT_SET(1)
/* Define translation table descriptor bits */
#define ARM_AR_MEM_TTB_DESC_B ESAL_GE_MEM_32BIT_SET(2)
#define ARM_AR_MEM_TTB_DESC_C ESAL_GE_MEM_32BIT_SET(3)
#define ARM_AR_MEM_TTB_DESC_TEX ESAL_GE_MEM_32BIT_SET(12)
#define ARM_AR_MEM_TTB_DESC_S ESAL_GE_MEM_32BIT_SET(16)
/* MVA Format SBZ mask */
#define ARM_AR_MEM_MVA_SBZ_MASK ~(ARM_AR_MEM_CACHE_LINE_SIZE - 1UL)
/* Defines related to Cache Level ID Register */
#define ARM_AR_MEM_DCACHE_SIZE_SHIFT 16
#define ARM_AR_MEM_CACHE_SIZE_BIT 4
#define ARM_AR_MEM_CACHE_SIZE_MASK 0xF
/* Define all access (manager access permission / not cachable / not bufferd) */
#define ARM_AR_MEM_TTB_DESC_ALL_ACCESS (ARM_AR_MEM_TTB_DESC_AP_MANAGER | \
ARM_AR_MEM_TTB_DESC_SECT)
typedef enum {
TRIG_NOT_SUPPORTED,
TRIG_RISING_EDGE,
TRIG_FALLING_EDGE,
TRIG_LEVEL_LOW,
TRIG_LEVEL_HIGH,
TRIG_RISING_FALLING_EDGES,
TRIG_HIGH_LOW_RISING_FALLING_EDGES
} INT_TRIG_TYPE;
typedef enum {
NOCACHE,
WRITEBACK,
WRITETHROUGH
} CACHE_TYPE;
int arm_ar_mem_enable_mmu();
void arm_ar_map_mem_region(unsigned int vrt_addr, unsigned int phy_addr,
unsigned int size, int is_mem_mapped, CACHE_TYPE cache_type);
int zc702evk_gic_initialize();
int zc702evk_gic_interrupt_enable(int vector_id, INT_TRIG_TYPE trigger_type,
int priority);
int zc702evk_gic_interrupt_disable(int vector_id);
void zc702evk_gic_pr_int_initialize(void);
void arm_arch_install_isr_vector_table(unsigned long addr);
void restore_global_interrupts();
void disable_global_interrupts();
void init_arm_stacks(void);
int platform_interrupt_enable(int vector_id, INT_TRIG_TYPE trigger_type,
int priority);
int platform_interrupt_disable(int vector_id);
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);
void zynqa9_irq_isr();
void process_communication(struct XOpenAMPInstPtr OpenAMPInstance);
#endif /* _BAREMETAL_H */

View file

@ -0,0 +1,290 @@
/*******************************************************************/
/* */
/* This file is automatically generated by linker script generator.*/
/* */
/* Version: */
/* */
/* Copyright (c) 2010 Xilinx, Inc. All rights reserved. */
/* */
/* Description : Cortex-A9 Linker Script */
/* */
/*******************************************************************/
_STACK_SIZE = DEFINED(_STACK_SIZE) ? _STACK_SIZE : 0x2000;
_HEAP_SIZE = DEFINED(_HEAP_SIZE) ? _HEAP_SIZE : 0x4000;
_ABORT_STACK_SIZE = DEFINED(_ABORT_STACK_SIZE) ? _ABORT_STACK_SIZE : 1024;
_SUPERVISOR_STACK_SIZE = DEFINED(_SUPERVISOR_STACK_SIZE) ? _SUPERVISOR_STACK_SIZE : 2048;
_IRQ_STACK_SIZE = DEFINED(_IRQ_STACK_SIZE) ? _IRQ_STACK_SIZE : 4096;
_FIQ_STACK_SIZE = DEFINED(_FIQ_STACK_SIZE) ? _FIQ_STACK_SIZE : 1024;
_UNDEF_STACK_SIZE = DEFINED(_UNDEF_STACK_SIZE) ? _UNDEF_STACK_SIZE : 1024;
/* Define Memories in the system */
MEMORY
{
ps7_ddr_0_S_AXI_BASEADDR : ORIGIN = 0x00100000, LENGTH = 0x08000000
ps7_ram_0_S_AXI_BASEADDR : ORIGIN = 0x00000000, LENGTH = 0x00030000
ps7_ram_1_S_AXI_BASEADDR : ORIGIN = 0xFFFF0000, LENGTH = 0x0000FE00
}
/* Specify the default entry point to the program */
ENTRY(_vector_table)
/* Define the sections, and where they are mapped in memory */
SECTIONS
{
.text : {
_binary_firmware1_start = 0;
_binary_firmware1_end = 0;
_binary_firmware2_start = 0;
_binary_firmware2_end = 0;
*(.vectors)
*(.boot)
*(.text)
*(.text.*)
*(.gnu.linkonce.t.*)
*(.plt)
*(.gnu_warning)
*(.gcc_execpt_table)
*(.glue_7)
*(.glue_7t)
*(.vfp11_veneer)
*(.ARM.extab)
*(.gnu.linkonce.armextab.*)
} > ps7_ddr_0_S_AXI_BASEADDR
.init : {
KEEP (*(.init))
} > ps7_ddr_0_S_AXI_BASEADDR
.fini : {
KEEP (*(.fini))
} > ps7_ddr_0_S_AXI_BASEADDR
.rodata : {
__rodata_start = .;
*(.rodata)
*(.rodata.*)
*(.gnu.linkonce.r.*)
__rodata_end = .;
} > ps7_ddr_0_S_AXI_BASEADDR
.rodata1 : {
__rodata1_start = .;
*(.rodata1)
*(.rodata1.*)
__rodata1_end = .;
} > ps7_ddr_0_S_AXI_BASEADDR
.sdata2 : {
__sdata2_start = .;
*(.sdata2)
*(.sdata2.*)
*(.gnu.linkonce.s2.*)
__sdata2_end = .;
} > ps7_ddr_0_S_AXI_BASEADDR
.sbss2 : {
__sbss2_start = .;
*(.sbss2)
*(.sbss2.*)
*(.gnu.linkonce.sb2.*)
__sbss2_end = .;
} > ps7_ddr_0_S_AXI_BASEADDR
.data : {
__data_start = .;
*(.data)
*(.data.*)
*(.gnu.linkonce.d.*)
*(.jcr)
*(.got)
*(.got.plt)
__data_end = .;
} > ps7_ddr_0_S_AXI_BASEADDR
.data1 : {
__data1_start = .;
*(.data1)
*(.data1.*)
__data1_end = .;
} > ps7_ddr_0_S_AXI_BASEADDR
.got : {
*(.got)
} > ps7_ddr_0_S_AXI_BASEADDR
.ctors : {
__CTOR_LIST__ = .;
___CTORS_LIST___ = .;
KEEP (*crtbegin.o(.ctors))
KEEP (*(EXCLUDE_FILE(*crtend.o) .ctors))
KEEP (*(SORT(.ctors.*)))
KEEP (*(.ctors))
__CTOR_END__ = .;
___CTORS_END___ = .;
} > ps7_ddr_0_S_AXI_BASEADDR
.dtors : {
__DTOR_LIST__ = .;
___DTORS_LIST___ = .;
KEEP (*crtbegin.o(.dtors))
KEEP (*(EXCLUDE_FILE(*crtend.o) .dtors))
KEEP (*(SORT(.dtors.*)))
KEEP (*(.dtors))
__DTOR_END__ = .;
___DTORS_END___ = .;
} > ps7_ddr_0_S_AXI_BASEADDR
.fixup : {
__fixup_start = .;
*(.fixup)
__fixup_end = .;
} > ps7_ddr_0_S_AXI_BASEADDR
.eh_frame : {
*(.eh_frame)
} > ps7_ddr_0_S_AXI_BASEADDR
.eh_framehdr : {
__eh_framehdr_start = .;
*(.eh_framehdr)
__eh_framehdr_end = .;
} > ps7_ddr_0_S_AXI_BASEADDR
.gcc_except_table : {
*(.gcc_except_table)
} > ps7_ddr_0_S_AXI_BASEADDR
.mmu_tbl (ALIGN(16384)) : {
__mmu_tbl_start = .;
*(.mmu_tbl)
__mmu_tbl_end = .;
} > ps7_ddr_0_S_AXI_BASEADDR
.ARM.exidx : {
__exidx_start = .;
*(.ARM.exidx*)
*(.gnu.linkonce.armexidix.*.*)
__exidx_end = .;
} > ps7_ddr_0_S_AXI_BASEADDR
.preinit_array : {
__preinit_array_start = .;
KEEP (*(SORT(.preinit_array.*)))
KEEP (*(.preinit_array))
__preinit_array_end = .;
} > ps7_ddr_0_S_AXI_BASEADDR
.init_array : {
__init_array_start = .;
KEEP (*(SORT(.init_array.*)))
KEEP (*(.init_array))
__init_array_end = .;
} > ps7_ddr_0_S_AXI_BASEADDR
.fini_array : {
__fini_array_start = .;
KEEP (*(SORT(.fini_array.*)))
KEEP (*(.fini_array))
__fini_array_end = .;
} > ps7_ddr_0_S_AXI_BASEADDR
.ARM.attributes : {
__ARM.attributes_start = .;
*(.ARM.attributes)
__ARM.attributes_end = .;
} > ps7_ddr_0_S_AXI_BASEADDR
.sdata : {
__sdata_start = .;
*(.sdata)
*(.sdata.*)
*(.gnu.linkonce.s.*)
__sdata_end = .;
} > ps7_ddr_0_S_AXI_BASEADDR
.sbss (NOLOAD) : {
__sbss_start = .;
*(.sbss)
*(.sbss.*)
*(.gnu.linkonce.sb.*)
__sbss_end = .;
} > ps7_ddr_0_S_AXI_BASEADDR
.tdata : {
__tdata_start = .;
*(.tdata)
*(.tdata.*)
*(.gnu.linkonce.td.*)
__tdata_end = .;
} > ps7_ddr_0_S_AXI_BASEADDR
.tbss : {
__tbss_start = .;
*(.tbss)
*(.tbss.*)
*(.gnu.linkonce.tb.*)
__tbss_end = .;
} > ps7_ddr_0_S_AXI_BASEADDR
.bss (NOLOAD) : {
__bss_start = .;
*(.bss)
*(.bss.*)
*(.gnu.linkonce.b.*)
*(COMMON)
__bss_end = .;
} > ps7_ddr_0_S_AXI_BASEADDR
_SDA_BASE_ = __sdata_start + ((__sbss_end - __sdata_start) / 2 );
_SDA2_BASE_ = __sdata2_start + ((__sbss2_end - __sdata2_start) / 2 );
/* Generate Stack and Heap definitions */
.heap (NOLOAD) : {
. = ALIGN(16);
_heap = .;
HeapBase = .;
_heap_start = .;
. += _HEAP_SIZE;
_heap_end = .;
HeapLimit = .;
} > ps7_ddr_0_S_AXI_BASEADDR
.stack (NOLOAD) : {
. = ALIGN(16);
_stack_end = .;
. += _STACK_SIZE;
_stack = .;
__stack = _stack;
. = ALIGN(16);
_irq_stack_end = .;
. += _IRQ_STACK_SIZE;
__irq_stack = .;
_supervisor_stack_end = .;
. += _SUPERVISOR_STACK_SIZE;
. = ALIGN(16);
__supervisor_stack = .;
_abort_stack_end = .;
. += _ABORT_STACK_SIZE;
. = ALIGN(16);
__abort_stack = .;
_fiq_stack_end = .;
. += _FIQ_STACK_SIZE;
. = ALIGN(16);
__fiq_stack = .;
_undef_stack_end = .;
. += _UNDEF_STACK_SIZE;
. = ALIGN(16);
__undef_stack = .;
} > ps7_ddr_0_S_AXI_BASEADDR
_end = .;
}

View file

@ -0,0 +1,290 @@
/*******************************************************************/
/* */
/* This file is automatically generated by linker script generator.*/
/* */
/* Version: */
/* */
/* Copyright (c) 2010 Xilinx, Inc. All rights reserved. */
/* */
/* Description : Cortex-A9 Linker Script */
/* */
/*******************************************************************/
_STACK_SIZE = DEFINED(_STACK_SIZE) ? _STACK_SIZE : 0x4000;
_HEAP_SIZE = DEFINED(_HEAP_SIZE) ? _HEAP_SIZE : 0x500;
_ABORT_STACK_SIZE = DEFINED(_ABORT_STACK_SIZE) ? _ABORT_STACK_SIZE : 1024;
_SUPERVISOR_STACK_SIZE = DEFINED(_SUPERVISOR_STACK_SIZE) ? _SUPERVISOR_STACK_SIZE : 2048;
_IRQ_STACK_SIZE = DEFINED(_IRQ_STACK_SIZE) ? _IRQ_STACK_SIZE : 4096;
_FIQ_STACK_SIZE = DEFINED(_FIQ_STACK_SIZE) ? _FIQ_STACK_SIZE : 1024;
_UNDEF_STACK_SIZE = DEFINED(_UNDEF_STACK_SIZE) ? _UNDEF_STACK_SIZE : 1024;
/* Define Memories in the system */
MEMORY
{
ps7_ddr_0_S_AXI_BASEADDR : ORIGIN = 0x00100000, LENGTH = 0x3FF00000
ps7_ram_0_S_AXI_BASEADDR : ORIGIN = 0x00000000, LENGTH = 0x00030000
ps7_ram_1_S_AXI_BASEADDR : ORIGIN = 0xFFFF0000, LENGTH = 0x0000FE00
}
/* Specify the default entry point to the program */
ENTRY(_vector_table)
/* Define the sections, and where they are mapped in memory */
SECTIONS
{
.text : {
_binary_firmware1_start = 0;
_binary_firmware1_end = 0;
_binary_firmware2_start = 0;
_binary_firmware2_end = 0;
*(.vectors)
*(.boot)
*(.text)
*(.text.*)
*(.gnu.linkonce.t.*)
*(.plt)
*(.gnu_warning)
*(.gcc_execpt_table)
*(.glue_7)
*(.glue_7t)
*(.vfp11_veneer)
*(.ARM.extab)
*(.gnu.linkonce.armextab.*)
} > ps7_ddr_0_S_AXI_BASEADDR
.init : {
KEEP (*(.init))
} > ps7_ddr_0_S_AXI_BASEADDR
.fini : {
KEEP (*(.fini))
} > ps7_ddr_0_S_AXI_BASEADDR
.rodata : {
__rodata_start = .;
*(.rodata)
*(.rodata.*)
*(.gnu.linkonce.r.*)
__rodata_end = .;
} > ps7_ddr_0_S_AXI_BASEADDR
.rodata1 : {
__rodata1_start = .;
*(.rodata1)
*(.rodata1.*)
__rodata1_end = .;
} > ps7_ddr_0_S_AXI_BASEADDR
.sdata2 : {
__sdata2_start = .;
*(.sdata2)
*(.sdata2.*)
*(.gnu.linkonce.s2.*)
__sdata2_end = .;
} > ps7_ddr_0_S_AXI_BASEADDR
.sbss2 : {
__sbss2_start = .;
*(.sbss2)
*(.sbss2.*)
*(.gnu.linkonce.sb2.*)
__sbss2_end = .;
} > ps7_ddr_0_S_AXI_BASEADDR
.data : {
__data_start = .;
*(.data)
*(.data.*)
*(.gnu.linkonce.d.*)
*(.jcr)
*(.got)
*(.got.plt)
__data_end = .;
} > ps7_ddr_0_S_AXI_BASEADDR
.data1 : {
__data1_start = .;
*(.data1)
*(.data1.*)
__data1_end = .;
} > ps7_ddr_0_S_AXI_BASEADDR
.got : {
*(.got)
} > ps7_ddr_0_S_AXI_BASEADDR
.ctors : {
__CTOR_LIST__ = .;
___CTORS_LIST___ = .;
KEEP (*crtbegin.o(.ctors))
KEEP (*(EXCLUDE_FILE(*crtend.o) .ctors))
KEEP (*(SORT(.ctors.*)))
KEEP (*(.ctors))
__CTOR_END__ = .;
___CTORS_END___ = .;
} > ps7_ddr_0_S_AXI_BASEADDR
.dtors : {
__DTOR_LIST__ = .;
___DTORS_LIST___ = .;
KEEP (*crtbegin.o(.dtors))
KEEP (*(EXCLUDE_FILE(*crtend.o) .dtors))
KEEP (*(SORT(.dtors.*)))
KEEP (*(.dtors))
__DTOR_END__ = .;
___DTORS_END___ = .;
} > ps7_ddr_0_S_AXI_BASEADDR
.fixup : {
__fixup_start = .;
*(.fixup)
__fixup_end = .;
} > ps7_ddr_0_S_AXI_BASEADDR
.eh_frame : {
*(.eh_frame)
} > ps7_ddr_0_S_AXI_BASEADDR
.eh_framehdr : {
__eh_framehdr_start = .;
*(.eh_framehdr)
__eh_framehdr_end = .;
} > ps7_ddr_0_S_AXI_BASEADDR
.gcc_except_table : {
*(.gcc_except_table)
} > ps7_ddr_0_S_AXI_BASEADDR
.mmu_tbl (ALIGN(16384)) : {
__mmu_tbl_start = .;
*(.mmu_tbl)
__mmu_tbl_end = .;
} > ps7_ddr_0_S_AXI_BASEADDR
.ARM.exidx : {
__exidx_start = .;
*(.ARM.exidx*)
*(.gnu.linkonce.armexidix.*.*)
__exidx_end = .;
} > ps7_ddr_0_S_AXI_BASEADDR
.preinit_array : {
__preinit_array_start = .;
KEEP (*(SORT(.preinit_array.*)))
KEEP (*(.preinit_array))
__preinit_array_end = .;
} > ps7_ddr_0_S_AXI_BASEADDR
.init_array : {
__init_array_start = .;
KEEP (*(SORT(.init_array.*)))
KEEP (*(.init_array))
__init_array_end = .;
} > ps7_ddr_0_S_AXI_BASEADDR
.fini_array : {
__fini_array_start = .;
KEEP (*(SORT(.fini_array.*)))
KEEP (*(.fini_array))
__fini_array_end = .;
} > ps7_ddr_0_S_AXI_BASEADDR
.ARM.attributes : {
__ARM.attributes_start = .;
*(.ARM.attributes)
__ARM.attributes_end = .;
} > ps7_ddr_0_S_AXI_BASEADDR
.sdata : {
__sdata_start = .;
*(.sdata)
*(.sdata.*)
*(.gnu.linkonce.s.*)
__sdata_end = .;
} > ps7_ddr_0_S_AXI_BASEADDR
.sbss (NOLOAD) : {
__sbss_start = .;
*(.sbss)
*(.sbss.*)
*(.gnu.linkonce.sb.*)
__sbss_end = .;
} > ps7_ddr_0_S_AXI_BASEADDR
.tdata : {
__tdata_start = .;
*(.tdata)
*(.tdata.*)
*(.gnu.linkonce.td.*)
__tdata_end = .;
} > ps7_ddr_0_S_AXI_BASEADDR
.tbss : {
__tbss_start = .;
*(.tbss)
*(.tbss.*)
*(.gnu.linkonce.tb.*)
__tbss_end = .;
} > ps7_ddr_0_S_AXI_BASEADDR
.bss (NOLOAD) : {
__bss_start = .;
*(.bss)
*(.bss.*)
*(.gnu.linkonce.b.*)
*(COMMON)
__bss_end = .;
} > ps7_ddr_0_S_AXI_BASEADDR
_SDA_BASE_ = __sdata_start + ((__sbss_end - __sdata_start) / 2 );
_SDA2_BASE_ = __sdata2_start + ((__sbss2_end - __sdata2_start) / 2 );
/* Generate Stack and Heap definitions */
.heap (NOLOAD) : {
. = ALIGN(16);
_heap = .;
HeapBase = .;
_heap_start = .;
. += _HEAP_SIZE;
_heap_end = .;
HeapLimit = .;
} > ps7_ddr_0_S_AXI_BASEADDR
.stack (NOLOAD) : {
. = ALIGN(16);
_stack_end = .;
. += _STACK_SIZE;
_stack = .;
__stack = _stack;
. = ALIGN(16);
_irq_stack_end = .;
. += _IRQ_STACK_SIZE;
__irq_stack = .;
_supervisor_stack_end = .;
. += _SUPERVISOR_STACK_SIZE;
. = ALIGN(16);
__supervisor_stack = .;
_abort_stack_end = .;
. += _ABORT_STACK_SIZE;
. = ALIGN(16);
__abort_stack = .;
_fiq_stack_end = .;
. += _FIQ_STACK_SIZE;
. = ALIGN(16);
__fiq_stack = .;
_undef_stack_end = .;
. += _UNDEF_STACK_SIZE;
. = ALIGN(16);
__undef_stack = .;
} > ps7_ddr_0_S_AXI_BASEADDR
_end = .;
}

View file

@ -0,0 +1,272 @@
/*
* 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 Mentor Graphics Corporation 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.
*/
/**************************************************************************************
* This is a sample demonstration application that showcases usage of remoteproc
* and rpmsg APIs on the remote core. This application is meant to run on the remote CPU
* running bare-metal code. It receives two matrices from the master,
* multiplies them and returns the result to the master core.
*
* The init_system is called in the main function which defines a shared memory region in
* MPU settings for the communication between master and remote using
* zynqMP_r5_map_mem_region API,it also initializes interrupt controller
* GIC and register the interrupt service routine for IPI using
* zynqMP_r5_gic_initialize API.
*
* The remoteproc_resource_init API is being called to create the virtio/RPMsg devices
* required for IPC with the master context. Invocation of this API causes remoteproc on
* the bare-metal to use the rpmsg name service announcement feature to advertise the
* rpmsg channels served by the application.
*
* The master receives the advertisement messages and performs the following tasks:
* 1. Invokes the channel created callback registered by the master application
* 2. Responds to remote context with a name service acknowledgement message
* After the acknowledgement is received from master, remoteproc on the bare-metal
* invokes the RPMsg channel-created callback registered by the remote application.
* The RPMsg channel is established at this point. All RPMsg APIs can be used subsequently
* on both sides for run time communications between the master and remote software contexts.
*
* Upon running the master application to send data to remote core, master will
* generate the matrices and send to remote (bare-metal) by informing the bare-metal with
* an IPI, the remote will compute the resulting matrix and send the data back to
* master. Once the application is ran and task by the
* bare-metal application is done, master needs to properly shut down the remote
* processor
*
* To shut down the remote processor, the following steps are performed:
* 1. The master application sends an application-specific shutdown message
* to the remote context
* 2. This bare-metal application cleans up application resources,
* sends a shutdown acknowledge to master, and invokes remoteproc_resource_deinit
* API to de-initialize remoteproc on the bare-metal side.
* 3. On receiving the shutdown acknowledge message, the master application invokes
* the remoteproc_shutdown API to shut down the remote processor and de-initialize
* remoteproc using remoteproc_deinit on its side.
*
**************************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "open_amp.h"
#include "rsc_table.h"
#include "baremetal.h"
#include "xil_exception.h"
#define MAX_SIZE 6
#define NUM_MATRIX 2
#define SHUTDOWN_MSG 0xEF56A55A
typedef struct _matrix {
unsigned int size;
unsigned int elements[MAX_SIZE][MAX_SIZE];
} matrix;
/* Internal functions */
static void rpmsg_channel_created(struct rpmsg_channel *rp_chnl);
static void rpmsg_channel_deleted(struct rpmsg_channel *rp_chnl);
static void rpmsg_read_cb(struct rpmsg_channel *, void *, int, void *, unsigned long);
static void Matrix_Multiply(const matrix *m, const matrix *n, matrix *r);
static void communication_task();
static void matrix_mul();
/* Static variables */
static struct rpmsg_channel *app_rp_chnl;
static struct rpmsg_endpoint *rp_ept;
static struct remote_proc *proc = NULL;
static struct rsc_table_info rsc_info;
#ifdef USE_FREERTOS
static queue_data send_data,mat_array;
#else
static queue_data *send_data,*mat_array;
#endif
static queue_data recv_mat_data, mat_result_array;
#ifdef USE_FREERTOS
static TaskHandle_t comm_task;
static TaskHandle_t mat_mul;
static QueueSetHandle_t comm_queueset;
static QueueHandle_t mat_mul_queue;
#else
static pq_queue_t *mat_mul_queue;
#endif
static matrix matrix_array[NUM_MATRIX];
static matrix matrix_result;
/* Globals */
extern const struct remote_resource_table resources;
struct XOpenAMPInstPtr OpenAMPInstPtr;
/* Application entry point */
int main() {
Xil_ExceptionDisable();
#ifdef USE_FREERTOS
BaseType_t stat;
/* Create the tasks */
stat = xTaskCreate(communication_task, ( const char * ) "HW2",
1024, NULL,2,&comm_task);
if(stat != pdPASS)
return -1;
stat = xTaskCreate(matrix_mul, ( const char * ) "HW2",
1024, NULL, 1, &mat_mul );
if(stat != pdPASS)
return -1;
/*Create Queues*/
mat_mul_queue = xQueueCreate( 1, sizeof( queue_data ) );
OpenAMPInstPtr.send_queue = xQueueCreate( 1, sizeof( queue_data ) );
env_create_sync_lock(&OpenAMPInstPtr.lock,LOCKED);
/* Start the tasks and timer running. */
vTaskStartScheduler();
while(1);
#else
/*Create Queues*/
mat_mul_queue = pq_create_queue();
OpenAMPInstPtr.send_queue = pq_create_queue();
communication_task();
#endif
return 0;
}
void communication_task(){
int status;
rsc_info.rsc_tab = (struct resource_table *)&resources;
rsc_info.size = sizeof(resources);
zc702evk_gic_initialize();
/* Initialize RPMSG framework */
status = remoteproc_resource_init(&rsc_info, rpmsg_channel_created, rpmsg_channel_deleted,
rpmsg_read_cb ,&proc);
if (status < 0) {
return;
}
#ifdef USE_FREERTOS
comm_queueset = xQueueCreateSet( 2 );
xQueueAddToSet( OpenAMPInstPtr.send_queue, comm_queueset);
xQueueAddToSet( OpenAMPInstPtr.lock, comm_queueset);
#else
env_create_sync_lock(&OpenAMPInstPtr.lock,LOCKED);
#endif
env_enable_interrupt(VRING0_IPI_VECT, 0, 0);
env_enable_interrupt(VRING1_IPI_VECT, 0, 0);
while (1) {
#ifdef USE_FREERTOS
QueueSetMemberHandle_t xActivatedMember;
xActivatedMember = xQueueSelectFromSet( comm_queueset, portMAX_DELAY);
if( xActivatedMember == OpenAMPInstPtr.lock ) {
env_acquire_sync_lock(OpenAMPInstPtr.lock);
process_communication(OpenAMPInstPtr);
}
if (xActivatedMember == OpenAMPInstPtr.send_queue) {
xQueueReceive( OpenAMPInstPtr.send_queue, &send_data, 0 );
rpmsg_send(app_rp_chnl, send_data.data, send_data.length);
}
#else
env_acquire_sync_lock(OpenAMPInstPtr.lock);
process_communication(OpenAMPInstPtr);
matrix_mul();
if(pq_qlength(OpenAMPInstPtr.send_queue) > 0) {
send_data = pq_dequeue(OpenAMPInstPtr.send_queue);
/* Send the result of matrix multiplication back to master. */
rpmsg_send(app_rp_chnl, send_data->data, send_data->length);
}
#endif
}
}
void matrix_mul(){
#ifdef USE_FREERTOS
for( ;; ){
if( xQueueReceive(mat_mul_queue, &mat_array, portMAX_DELAY )){
env_memcpy(matrix_array, mat_array.data, mat_array.length);
Matrix_Multiply(&matrix_array[0], &matrix_array[1], &matrix_result);
mat_result_array.length = sizeof(matrix);
mat_result_array.data = &matrix_result;
xQueueSend( OpenAMPInstPtr.send_queue, &mat_result_array, portMAX_DELAY );
}
}
#else
if(pq_qlength(mat_mul_queue) > 0){
mat_array = pq_dequeue(mat_mul_queue);
env_memcpy(matrix_array, mat_array->data, mat_array->length);
/* Process received data and multiple matrices. */
Matrix_Multiply(&matrix_array[0], &matrix_array[1], &matrix_result);
mat_result_array.length = sizeof(matrix);
mat_result_array.data = &matrix_result;
pq_enqueue(OpenAMPInstPtr.send_queue, &mat_result_array);
}
#endif
}
static void rpmsg_channel_created(struct rpmsg_channel *rp_chnl) {
app_rp_chnl = rp_chnl;
rp_ept = rpmsg_create_ept(rp_chnl, rpmsg_read_cb, RPMSG_NULL,
RPMSG_ADDR_ANY);
}
static void rpmsg_channel_deleted(struct rpmsg_channel *rp_chnl) {
rpmsg_destroy_ept(rp_ept);
}
static void rpmsg_read_cb(struct rpmsg_channel *rp_chnl, void *data, int len,
void * priv, unsigned long src) {
if ((*(int *) data) == SHUTDOWN_MSG) {
remoteproc_resource_deinit(proc);
}else{
recv_mat_data.data = data;
recv_mat_data.length = len;
#ifdef USE_FREERTOS
xQueueSend(mat_mul_queue , &recv_mat_data, portMAX_DELAY );
#else
pq_enqueue(mat_mul_queue, &recv_mat_data);
#endif
}
}
static void Matrix_Multiply(const matrix *m, const matrix *n, matrix *r) {
int i, j, k;
env_memset(r, 0x0, sizeof(matrix));
r->size = m->size;
for (i = 0; i < m->size; ++i) {
for (j = 0; j < n->size; ++j) {
for (k = 0; k < r->size; ++k) {
r->elements[i][j] += m->elements[i][k] * n->elements[k][j];
}
}
}
}

View file

@ -0,0 +1,96 @@
/*
* Copyright (c) 2014, Mentor Graphics Corporation
* 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 Mentor Graphics Corporation 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.
*/
/**************************************************************************
* FILE NAME
*
* platform.c
*
* DESCRIPTION
*
* This file is the Implementation of IPC hardware layer interface
* for Xilinx Zynq ZC702EVK platform.
*
**************************************************************************/
#include "platform.h"
/*--------------------------- Globals ---------------------------------- */
struct hil_platform_ops proc_ops = {
.enable_interrupt = _enable_interrupt,
.notify = _notify,
.boot_cpu = _boot_cpu,
.shutdown_cpu = _shutdown_cpu,
};
int _enable_interrupt(struct proc_vring *vring_hw) {
/* Register ISR*/
env_register_isr(vring_hw->intr_info.vect_id, vring_hw, platform_isr);
/* Enable the interrupts */
/* FIXME: enabled interrupt in application */
/*env_enable_interrupt(vring_hw->intr_info.vect_id,
vring_hw->intr_info.priority,
vring_hw->intr_info.trigger_type);*/
return 0;
}
void _notify(int cpu_id, struct proc_intr *intr_info) {
unsigned long mask = 0;
mask = ((1 << (GIC_CPU_ID_BASE + cpu_id)) | (intr_info->vect_id))
& (GIC_SFI_TRIG_CPU_MASK | GIC_SFI_TRIG_INTID_MASK);
Xil_Out32((GIC_DIST_BASE + GIC_DIST_SOFTINT), mask);
}
int _boot_cpu(int cpu_id, unsigned int load_addr) {
return -1;
}
void _shutdown_cpu(int cpu_id) {
unsigned int reg;
unlock_slcr();
reg = Xil_In32(ESAL_DP_SLCR_BASE + A9_CPU_SLCR_RESET_CTRL);
/* Assert reset signal and stop clock to halt the core */
reg |= (A9_CPU_SLCR_CLK_STOP | A9_CPU_SLCR_RST) << cpu_id;
Xil_Out32(ESAL_DP_SLCR_BASE + A9_CPU_SLCR_RESET_CTRL, reg);
lock_slcr();
}
void platform_isr(int vect_id, void *data,unsigned int intr_status) {
hil_isr(((struct proc_vring *) data));
}

View file

@ -0,0 +1,66 @@
/*
* Copyright (c) 2014, Mentor Graphics Corporation
* 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 Mentor Graphics Corporation 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.
*/
#ifndef PLATFORM_H_
#define PLATFORM_H_
#include <stdio.h>
#include "hil.h"
/* IPC Device parameters */
#define SHM_ADDR (void *)0x08008000
#define SHM_SIZE 0x00200000
#define VRING0_IPI_VECT 15
#define VRING1_IPI_VECT 14
#define MASTER_CPU_ID 0
#define REMOTE_CPU_ID 1
/* ------------------------- Macros --------------------------*/
#define ESAL_DP_SLCR_BASE 0xF8000000
#define PERIPH_BASE1 0xF8F00000
#define GIC_DIST_BASE (PERIPH_BASE1 + 0x00001000)
#define GIC_DIST_SOFTINT 0xF00
#define GIC_SFI_TRIG_CPU_MASK 0x00FF0000
#define GIC_SFI_TRIG_SATT_MASK 0x00008000
#define GIC_SFI_TRIG_INTID_MASK 0x0000000F
#define GIC_CPU_ID_BASE (1 << 4)
#define A9_CPU_SLCR_RESET_CTRL 0x244
#define A9_CPU_SLCR_CLK_STOP (1 << 4)
#define A9_CPU_SLCR_RST (1 << 0)
#define unlock_slcr() Xil_Out32(ESAL_DP_SLCR_BASE + 0x08, 0xDF0DDF0D)
#define lock_slcr() Xil_Out32(ESAL_DP_SLCR_BASE + 0x04, 0x767B767B)
int _enable_interrupt(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,unsigned int intr_status);
#endif /* PLATFORM_H_ */

View file

@ -0,0 +1,227 @@
/*
* Copyright (c) 2014, Mentor Graphics Corporation
* 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 Mentor Graphics Corporation 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.
*/
/**************************************************************************
* FILE NAME
*
* platform_info.c
*
* DESCRIPTION
*
* This file implements APIs to get platform specific
* information for OpenAMP.
*
**************************************************************************/
#include "platform.h"
/* Reference implementation that show cases platform_get_cpu_info and
platform_get_for_firmware API implementation for Bare metal environment */
extern struct hil_platform_ops proc_ops;
/**
* This array provdes defnition of CPU nodes for master and remote
* context. It contains two nodes beacuse the same file is intended
* to use with both master and remote configurations. On zynq platform
* only one node defintion is required for master/remote as there
* are only two cores present in the platform.
*
* Only platform specific info is populated here. Rest of information
* is obtained during resource table parsing.The platform specific
* information includes;
*
* -CPU ID
* -Shared Memory
* -Interrupts
* -Channel info.
*
* Although the channel info is not platform specific information
* but it is conveneient to keep it in HIL so that user can easily
* provide it without modifying the generic part.
*
* It is good idea to define hil_proc structure with platform
* specific fields populated as this can be easily copied to hil_proc
* structure passed as parameter in platform_get_processor_info. The
* other option is to populate the required structures individually
* and copy them one by one to hil_proc structure in platform_get_processor_info
* function. The first option is adopted here.
*
*
* 1) First node in the array is intended for the remote contexts and it
* defines Master CPU ID, shared memory, interrupts info, number of channels
* and there names. This node defines only one channel
* "rpmsg-openamp-demo-channel".
*
* 2)Second node is required by the master and it defines remote CPU ID,
* shared memory and interrupts info. In general no channel info is required by the
* Master node, however in baremetal master and linux remote case the linux
* rpmsg bus driver behaves as master so the rpmsg driver on linux side still needs
* channel info. This information is not required by the masters for baremetal
* remotes.
*
*/
struct hil_proc proc_table []=
{
/* CPU node for remote context */
{
/* CPU ID of master */
MASTER_CPU_ID,
/* Shared memory info - Last field is not used currently */
{
SHM_ADDR, SHM_SIZE, 0x00
},
/* VirtIO device info */
{
/* Leave these three fields empty as these are obtained from rsc
* table.
*/
0, 0, 0,
/* Vring info */
{
{
/* Provide only vring interrupts info here. Other fields are
* obtained from the resource table so leave them empty.
*/
NULL, NULL, 0, 0,
{
VRING0_IPI_VECT,0x1006,1,NULL
}
},
{
NULL, NULL, 0, 0,
{
VRING1_IPI_VECT,0x1006,1,NULL
}
}
}
},
/* Number of RPMSG channels */
1,
/* RPMSG channel info - Only channel name is expected currently */
{
{"rpmsg-openamp-demo-channel"}
},
/* HIL platform ops table. */
&proc_ops,
/* Next three fields are for future use only */
0,
0,
NULL
},
/* CPU node for remote context */
{
/* CPU ID of remote */
REMOTE_CPU_ID,
/* Shared memory info - Last field is not used currently */
{
SHM_ADDR, SHM_SIZE, 0x00
},
/* VirtIO device info */
{
0, 0, 0,
{
{
/* Provide vring interrupts info here. Other fields are obtained
* from the rsc table so leave them empty.
*/
NULL, NULL, 0, 0,
{
VRING0_IPI_VECT,0x1006,1
}
},
{
NULL, NULL, 0, 0,
{
VRING1_IPI_VECT,0x1006,1
}
}
}
},
/* Number of RPMSG channels */
1,
/* RPMSG channel info - Only channel name is expected currently */
{
{"rpmsg-openamp-demo-channel"}
},
/* HIL platform ops table. */
&proc_ops,
/* Next three fields are for future use only */
0,
0,
NULL
}
};
/**
* platform_get_processor_info
*
* Copies the target info from the user defined data structures to
* HIL proc data structure.In case of remote contexts this function
* is called with the reserved CPU ID HIL_RSVD_CPU_ID, because for
* remotes there is only one master.
*
* @param proc - HIL proc to populate
* @param cpu_id - CPU ID
*
* return - status of execution
*/
int platform_get_processor_info(struct hil_proc *proc , int cpu_id) {
int idx;
for(idx = 0; idx < sizeof(proc_table)/sizeof(struct hil_proc); idx++) {
if((cpu_id == HIL_RSVD_CPU_ID) || (proc_table[idx].cpu_id == cpu_id) ) {
env_memcpy(proc,&proc_table[idx], sizeof(struct hil_proc));
return 0;
}
}
return -1;
}
int platform_get_processor_for_fw(char *fw_name) {
return 1;
}

View file

@ -0,0 +1,94 @@
/*
* 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 Mentor Graphics Corporation 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.
*/
/* This file populates resource table for BM remote
* for use by the Linux Master */
#include "open_amp.h"
#include "rsc_table.h"
/* Place resource table in special ELF section */
#define __rsc_section(S) __attribute__((__section__(#S)))
#define __resource __rsc_section(.resource_table)
#define RPMSG_IPU_C0_FEATURES 1
/* VirtIO rpmsg device id */
#define VIRTIO_ID_RPMSG_ 7
/* Remote supports Name Service announcement */
#define VIRTIO_RPMSG_F_NS 0
/* Resource table entries */
#define ELF_START 0x00000000
#define ELF_END 0x08000000
#define NUM_VRINGS 0x02
#define VRING_ALIGN 0x1000
#define RING_TX 0x08000000
#define RING_RX 0x08004000
#define VRING_SIZE 256
#define NUM_TABLE_ENTRIES 2
#define CARVEOUT_SRC_OFFSETS offsetof(struct remote_resource_table, elf_cout),
#define CARVEOUT_SRC { RSC_CARVEOUT, ELF_START, ELF_START, ELF_END, 0, 0, "ELF_COUT", },
const struct remote_resource_table __resource resources =
{
/* Version */
1,
/* NUmber of table entries */
NUM_TABLE_ENTRIES,
/* reserved fields */
{ 0, 0,},
/* Offsets of rsc entries */
{
CARVEOUT_SRC_OFFSETS
offsetof(struct remote_resource_table, rpmsg_vdev),
},
/* End of ELF file */
CARVEOUT_SRC
/* Virtio device entry */
{ RSC_VDEV, VIRTIO_ID_RPMSG_, 0, RPMSG_IPU_C0_FEATURES, 0, 0, 0, NUM_VRINGS, {0, 0},
},
/* Vring rsc entry - part of vdev rsc entry */
{
RING_TX, VRING_ALIGN, VRING_SIZE, 1, 0
},
{
RING_RX, VRING_ALIGN, VRING_SIZE, 2, 0
},
};

View file

@ -0,0 +1,53 @@
/*
* 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 Mentor Graphics Corporation 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.
*/
/* This file populates resource table for BM remote
* for use by the Linux Master */
#include <stddef.h>
#include "open_amp.h"
#define NO_RESOURCE_ENTRIES 8
/* Resource table for the given remote */
struct remote_resource_table {
unsigned int version;
unsigned int num;
unsigned int reserved[2];
unsigned int offset[NO_RESOURCE_ENTRIES];
/* text carveout entry */
struct fw_rsc_carveout elf_cout;
/* rpmsg vdev entry */
struct fw_rsc_vdev rpmsg_vdev;
struct fw_rsc_vdev_vring rpmsg_vring0;
struct fw_rsc_vdev_vring rpmsg_vring1;
};

View file

@ -0,0 +1,93 @@
/******************************************************************************
*
* 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 <stdlib.h>
#include "xpqueue.h"
#define NUM_QUEUES 2
pq_queue_t pq_queue[NUM_QUEUES];
pq_queue_t *
pq_create_queue()
{
static int i;
pq_queue_t *q = NULL;
if (i >= NUM_QUEUES) {
return q;
}
q = &pq_queue[i++];
if (!q)
return q;
q->head = q->tail = q->len = 0;
return q;
}
int
pq_enqueue(pq_queue_t *q, queue_data *p)
{
if (q->len == PQ_QUEUE_SIZE)
return -1;
q->data[q->head] = p;
q->head = (q->head + 1)%PQ_QUEUE_SIZE;
q->len++;
return 0;
}
queue_data*
pq_dequeue(pq_queue_t *q)
{
int ptail;
if (q->len == 0)
return NULL;
ptail = q->tail;
q->tail = (q->tail + 1)%PQ_QUEUE_SIZE;
q->len--;
return q->data[ptail];
}
int
pq_qlength(pq_queue_t *q)
{
return q->len;
}

View file

@ -0,0 +1,62 @@
/******************************************************************************
*
* 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.
*
******************************************************************************/
#ifndef __LWIP_PBUF_QUEUE_H_
#define __LWIP_PBUF_QUEUE_H_
#include "xil_types.h"
#ifdef __cplusplus
extern "C" {
#endif
#define PQ_QUEUE_SIZE 20
typedef struct {
void *data;
u32 length;
} queue_data;
typedef struct {
queue_data *data[PQ_QUEUE_SIZE];
int head, tail, len;
} pq_queue_t;
pq_queue_t* pq_create_queue();
int pq_enqueue(pq_queue_t *q, queue_data *p);
queue_data* pq_dequeue(pq_queue_t *q);
int pq_qlength(pq_queue_t *q);
#ifdef __cplusplus
}
#endif
#endif