From 9e44967224c7c33406ed6ccfc226a3a93d2c8e96 Mon Sep 17 00:00:00 2001 From: Kinjal Pravinbhai Patel Date: Wed, 26 Aug 2015 17:01:54 +0530 Subject: [PATCH] sw_apps: openamp echo test is modified to support freertos Signed-off-by: Kinjal Pravinbhai Patel Acked-for-series: Anirudha Sarangi --- .../data/openamp_echo_test.tcl | 20 +- lib/sw_apps/openamp_echo_test/src/baremetal.c | 83 +++-- lib/sw_apps/openamp_echo_test/src/baremetal.h | 21 ++ lib/sw_apps/openamp_echo_test/src/echo_test.c | 180 ++++++++-- lib/sw_apps/openamp_echo_test/src/lscript.ld | 4 +- .../openamp_echo_test/src/lscript_freertos.ld | 328 ++++++++++++++++++ lib/sw_apps/openamp_echo_test/src/platform.c | 6 +- lib/sw_apps/openamp_echo_test/src/rsc_table.h | 3 +- lib/sw_apps/openamp_echo_test/src/xpqueue.c | 93 +++++ lib/sw_apps/openamp_echo_test/src/xpqueue.h | 62 ++++ 10 files changed, 738 insertions(+), 62 deletions(-) create mode 100644 lib/sw_apps/openamp_echo_test/src/lscript_freertos.ld create mode 100644 lib/sw_apps/openamp_echo_test/src/xpqueue.c create mode 100644 lib/sw_apps/openamp_echo_test/src/xpqueue.h diff --git a/lib/sw_apps/openamp_echo_test/data/openamp_echo_test.tcl b/lib/sw_apps/openamp_echo_test/data/openamp_echo_test.tcl index db91e6ff..6c574e9d 100755 --- a/lib/sw_apps/openamp_echo_test/data/openamp_echo_test.tcl +++ b/lib/sw_apps/openamp_echo_test/data/openamp_echo_test.tcl @@ -46,8 +46,8 @@ proc check_standalone_os {} { } set os [lindex $oslist 0]; - if { $os != "standalone" } { - error "This application is supported only on the Standalone Board Support Package."; + if { ( $os != "standalone" ) && ( $os != "freertos821_xilinx" ) } { + error "This application is supported only on the Standalone Board Support Package and freertos821."; } } @@ -90,7 +90,21 @@ proc check_stdout_hw {} { } proc swapp_generate {} { - return; + set oslist [get_os]; + if { [llength $oslist] != 1 } { + return 0; + } + set os [lindex $oslist 0]; + if { $os != "standalone" } { + set ld_file "lscript.ld" + set ld_file_new "lscript_freertos.ld" + file rename -force $ld_file_new $ld_file + file delete -force $ld_file_new + } else { + set ld_file "lscript_freertos.ld" + file delete -force $ld_file + } + return; } proc swapp_get_linker_constraints {} { diff --git a/lib/sw_apps/openamp_echo_test/src/baremetal.c b/lib/sw_apps/openamp_echo_test/src/baremetal.c index dc9c0c91..4ea19525 100644 --- a/lib/sw_apps/openamp_echo_test/src/baremetal.c +++ b/lib/sw_apps/openamp_echo_test/src/baremetal.c @@ -30,21 +30,25 @@ */ #include #include -#include "xparameters.h" #include "xil_exception.h" #include "xscugic.h" -#include "xil_cache.h" -#include "xil_mmu.h" +#include "xil_mpu.h" #include "baremetal.h" #include "env.h" - -XScuGic InterruptController; +#include "platform.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 zynqMP_r5_gic_initialize() { +#ifndef USE_FREERTOS u32 Status; - Xil_ExceptionDisable(); - XScuGic_Config *IntcConfig; /* The configuration parameters of the interrupt controller */ /* @@ -55,7 +59,7 @@ int zynqMP_r5_gic_initialize() { return XST_FAILURE; } - Status = XScuGic_CfgInitialize(&InterruptController, IntcConfig, + Status = XScuGic_CfgInitialize(&xInterruptController, IntcConfig, IntcConfig->CpuBaseAddress); if (Status != XST_SUCCESS) { return XST_FAILURE; @@ -66,26 +70,54 @@ int zynqMP_r5_gic_initialize() { * logic in the ARM processor. */ Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_IRQ_INT, - (Xil_ExceptionHandler) zynqMP_r5_irq_isr, - &InterruptController); - + XScuGic_InterruptHandler,&xInterruptController); Xil_ExceptionEnable(); +#endif + OpenAMPInstPtr.IntrID=VRING1_IPI_INTR_VECT; + XScuGic_Connect(&xInterruptController, VRING1_IPI_INTR_VECT, + (Xil_ExceptionHandler)zynqMP_r5_irq_isr, + &OpenAMPInstPtr); return 0; } -extern void bm_env_isr(int vector); -void zynqMP_r5_irq_isr() { +void zynqMP_r5_irq_isr(void *OpenAMPInst) { - unsigned int raw_irq; - int irq_vector; - raw_irq = (unsigned int)XScuGic_CPUReadReg(&InterruptController,XSCUGIC_INT_ACK_OFFSET); - irq_vector = (int) (raw_irq & XSCUGIC_ACK_INTID_MASK); + struct XOpenAMPInstPtr *OpenAMPInstance; + int idx; + struct isr_info *info; + OpenAMPInstance = (struct XOpenAMPInstPtr *)OpenAMPInst; + xInsideISR=1; - bm_env_isr(irq_vector); + for(idx = 0; idx < ISR_COUNT; idx++) + { + info = &isr_table[idx]; + if(info->vector == OpenAMPInstance->IntrID) + { + unsigned long ipi_base_addr = *((unsigned long *)info->data); + OpenAMPInstance->IPI_Status = (unsigned int)Xil_In32(ipi_base_addr + IPI_ISR_OFFSET); + Xil_Out32((ipi_base_addr + IPI_ISR_OFFSET), OpenAMPInstance->IPI_Status); + break; + } + } + env_release_sync_lock(OpenAMPInstance->lock); + xInsideISR=0; +} - XScuGic_CPUWriteReg(&InterruptController,XSCUGIC_EOI_OFFSET, raw_irq); +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; + } + } } /* @@ -160,9 +192,8 @@ void ipi_unregister_handler(unsigned long ipi_base_addr, unsigned int intr_mask) memset(&(ipi_handler_table[ipi_hd_i]), 0, sizeof(struct ipi_handler_info)); } -void ipi_isr(int vect_id, void *data, unsigned int inr_status) { +void ipi_isr(int vect_id, void *data, unsigned int ipi_intr_status) { 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 { Xil_Out32((ipi_base_addr + IPI_ISR_OFFSET), ipi_intr_status); @@ -236,12 +267,18 @@ unsigned 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 unsigned int value = 0; ARM_AR_INT_BITS_GET(&value); @@ -253,7 +290,7 @@ void disable_global_interrupts() { old_value = value; } - +#endif } /*==================================================================*/ diff --git a/lib/sw_apps/openamp_echo_test/src/baremetal.h b/lib/sw_apps/openamp_echo_test/src/baremetal.h index 39627929..78141c99 100644 --- a/lib/sw_apps/openamp_echo_test/src/baremetal.h +++ b/lib/sw_apps/openamp_echo_test/src/baremetal.h @@ -32,10 +32,30 @@ #ifndef _BAREMETAL_H #define _BAREMETAL_H +#include "amp_os.h" #include "xil_types.h" #include "xparameters.h" #include "xil_cache.h" #include "xreg_cortexr5.h" +#ifdef USE_FREERTOS +#include "FreeRTOS.h" +#include "semphr.h" +#include "task.h" +#include "queue.h" +#include "timers.h" +#endif +#include "xpqueue.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 INTC_DEVICE_ID XPAR_SCUGIC_0_DEVICE_ID @@ -97,5 +117,6 @@ 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 process_communication(struct XOpenAMPInstPtr OpenAMPInstance); #endif /* _BAREMETAL_H */ diff --git a/lib/sw_apps/openamp_echo_test/src/echo_test.c b/lib/sw_apps/openamp_echo_test/src/echo_test.c index 6d87e34b..ae86a93c 100644 --- a/lib/sw_apps/openamp_echo_test/src/echo_test.c +++ b/lib/sw_apps/openamp_echo_test/src/echo_test.c @@ -81,49 +81,159 @@ #include "baremetal.h" #include "xil_cache.h" #include "xil_mmu.h" -#include "xstatus.h" #include "xreg_cortexr5.h" +#include "xil_exception.h" #define SHUTDOWN_MSG 0xEF56A55A +#ifdef USE_FREERTOS +#define DELAY_200MSEC 200/portTICK_PERIOD_MS +#endif /* 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 init_system(); +static void communication_task(); +static void echo_test(); -/* Globals */ +/* 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, echo_data; +static TimerHandle_t stop_scheduler; +#else +static queue_data *send_data, *echo_data; +#endif +static queue_data recv_echo_data; +#ifdef USE_FREERTOS +static TaskHandle_t comm_task; +static TaskHandle_t echo_tst; +static QueueSetHandle_t comm_queueset; +static QueueHandle_t echo_queue; +#else +static pq_queue_t *echo_queue; +#endif + +/* Globals */ extern const struct remote_resource_table resources; +struct XOpenAMPInstPtr OpenAMPInstPtr; /* Application entry point */ int main() { - int status = 0; + Xil_ExceptionDisable(); - /* Initialize HW system components */ - init_system(); +#ifdef USE_FREERTOS + BaseType_t stat; - rsc_info.rsc_tab = (struct resource_table *)&resources; - rsc_info.size = sizeof(resources); + /* Create the tasks */ + stat = xTaskCreate(communication_task, ( const char * ) "HW2", + 1024, NULL,2,&comm_task); + if(stat != pdPASS) + return -1; - /* Initialize RPMSG framework */ - status = remoteproc_resource_init(&rsc_info, rpmsg_channel_created, rpmsg_channel_deleted, rpmsg_read_cb, - &proc); + stat = xTaskCreate(echo_test, ( const char * ) "HW2", + 1024, NULL, 1, &echo_tst ); + if(stat != pdPASS) + return -1; - if (status < 0) { - return -1; - } + /*Create Queues*/ + echo_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); - while(1) { - __asm__ ( "\ - wfi\n\t" \ - ); - }; +#else - return 0; + /*Create Queues*/ + echo_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); + + zynqMP_r5_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(VRING1_IPI_INTR_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); + echo_test(); + /* Wait for the result data on queue */ + 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 echo_test(){ +#ifdef USE_FREERTOS + for( ;; ){ + /* Wait to receive data for matrix multiplication */ + if( xQueueReceive( echo_queue, &echo_data, portMAX_DELAY )){ + /* + * The data can be processed here and send back + * Since it is simple echo test, the data is sent without + * processing + */ + xQueueSend( OpenAMPInstPtr.send_queue, &echo_data, portMAX_DELAY ); + } + } +#else + /* check whether data is received for matrix multiplication */ + if(pq_qlength(echo_queue) > 0){ + echo_data = pq_dequeue(echo_queue); + /* + * The data can be processed here and send back + * Since it is simple echo test, the data is sent without + * processing + */ + pq_enqueue(OpenAMPInstPtr.send_queue, echo_data); + } + +#endif } static void rpmsg_channel_created(struct rpmsg_channel *rp_chnl) { @@ -132,23 +242,33 @@ static void rpmsg_channel_created(struct rpmsg_channel *rp_chnl) { RPMSG_ADDR_ANY); } -static void rpmsg_channel_deleted(struct rpmsg_channel *rp_chnl) { +#ifdef USE_FREERTOS +static void StopSchedulerTmrCallBack(TimerHandle_t timer) +{ + vTaskEndScheduler(); +} +#endif +static void rpmsg_channel_deleted(struct rpmsg_channel *rp_chnl) { } 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); +#ifdef USE_FREERTOS + int TempTimerId; + stop_scheduler = xTimerCreate("TMR", DELAY_200MSEC, pdFALSE, (void *)&TempTimerId, StopSchedulerTmrCallBack); + xTimerStart(stop_scheduler, 0); +#endif } else { - /* Send data back to master*/ - rpmsg_send(rp_chnl, data, len); +/* copy the received data and send to matrix mul task over queue */ + recv_echo_data.data = data; + recv_echo_data.length = len; +#ifdef USE_FREERTOS + xQueueSend( echo_queue, &recv_echo_data, portMAX_DELAY ); +#else + pq_enqueue(echo_queue, &recv_echo_data); +#endif } } - -static void init_system() { - - /* Initilaize GIC */ - zynqMP_r5_gic_initialize(); - -} diff --git a/lib/sw_apps/openamp_echo_test/src/lscript.ld b/lib/sw_apps/openamp_echo_test/src/lscript.ld index 6612d721..76f86356 100644 --- a/lib/sw_apps/openamp_echo_test/src/lscript.ld +++ b/lib/sw_apps/openamp_echo_test/src/lscript.ld @@ -294,7 +294,7 @@ _SDA2_BASE_ = __sdata2_start + ((__sbss2_end - __sdata2_start) / 2 ); . += _HEAP_SIZE; _heap_end = .; HeapLimit = .; -} > ps8_ocm_ram_1_S_AXI_BASEADDR +} > ps8_ddr_S_AXI_BASEADDR .stack (NOLOAD) : { . = ALIGN(16); @@ -322,7 +322,7 @@ _SDA2_BASE_ = __sdata2_start + ((__sbss2_end - __sdata2_start) / 2 ); . += _UNDEF_STACK_SIZE; . = ALIGN(16); __undef_stack = .; -} > ps8_ocm_ram_1_S_AXI_BASEADDR +} > ps8_ddr_S_AXI_BASEADDR _end = .; } diff --git a/lib/sw_apps/openamp_echo_test/src/lscript_freertos.ld b/lib/sw_apps/openamp_echo_test/src/lscript_freertos.ld new file mode 100644 index 00000000..9d98a4c2 --- /dev/null +++ b/lib/sw_apps/openamp_echo_test/src/lscript_freertos.ld @@ -0,0 +1,328 @@ +/****************************************************************************** +* +* 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 +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ + +_STACK_SIZE = DEFINED(_STACK_SIZE) ? _STACK_SIZE : 0x1000; +_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 : 1024; +_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 +{ + ps8_bbram_0_S_AXI_BASEADDR : ORIGIN = 0xFFCC4000, LENGTH = 0x00001000 + ps8_csu_ram_0_S_AXI_BASEADDR : ORIGIN = 0xFFC40000, LENGTH = 0x00008000 + ps8_ddr_S_AXI_BASEADDR : ORIGIN = 0x3ED00000, LENGTH = 0x00040000 + ps8_ocm_ram_1_S_AXI_BASEADDR : ORIGIN = 0xFFFF0000, LENGTH = 0x00010000 + ps8_r5_tcm_ram_0_S_AXI_BASEADDR : ORIGIN = 0x00000050, LENGTH = 0x0001FFB1 +} + +/* Specify the default entry point to the program */ + +/* ENTRY(_boot) */ + +ENTRY(_vector_table) + +/* Define the sections, and where they are mapped in memory */ + +SECTIONS +{ + +.vectors : { + *(.vectors) +} > ps8_ocm_ram_1_S_AXI_BASEADDR + + +_binary_firmware1_start = 0; +_binary_firmware1_end = 0; +_binary_firmware2_start = 0; +_binary_firmware2_end = 0; + +.text : { + *(.boot) + *(.text) + *(.text.*) + *(.gnu.linkonce.t.*) + *(.plt) + *(.gnu_warning) + *(.gcc_execpt_table) + *(.glue_7) + *(.glue_7t) + *(.vfp11_veneer) + *(.ARM.extab) + *(.gnu.linkonce.armextab.*) +} > ps8_ddr_S_AXI_BASEADDR + +.init : { + KEEP (*(.init)) +} > ps8_ddr_S_AXI_BASEADDR + +.fini : { + KEEP (*(.fini)) +} > ps8_ddr_S_AXI_BASEADDR + +.interp : { + KEEP (*(.interp)) +} > ps8_ddr_S_AXI_BASEADDR + +.note-ABI-tag : { + KEEP (*(.note-ABI-tag)) +} > ps8_ddr_S_AXI_BASEADDR + +.rodata : { + __rodata_start = .; + *(.rodata) + *(.rodata.*) + *(.gnu.linkonce.r.*) + __rodata_end = .; +} > ps8_ddr_S_AXI_BASEADDR + +.rodata1 : { + __rodata1_start = .; + *(.rodata1) + *(.rodata1.*) + __rodata1_end = .; +} > ps8_ddr_S_AXI_BASEADDR + +.sdata2 : { + __sdata2_start = .; + *(.sdata2) + *(.sdata2.*) + *(.gnu.linkonce.s2.*) + __sdata2_end = .; +} > ps8_ddr_S_AXI_BASEADDR + +.sbss2 : { + __sbss2_start = .; + *(.sbss2) + *(.sbss2.*) + *(.gnu.linkonce.sb2.*) + __sbss2_end = .; +} > ps8_ddr_S_AXI_BASEADDR + +.data : { + __data_start = .; + *(.data) + *(.data.*) + *(.gnu.linkonce.d.*) + *(.jcr) + *(.got) + *(.got.plt) + __data_end = .; +} > ps8_ddr_S_AXI_BASEADDR + +.data1 : { + __data1_start = .; + *(.data1) + *(.data1.*) + __data1_end = .; +} > ps8_ddr_S_AXI_BASEADDR + +.got : { + *(.got) +} > ps8_ddr_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___ = .; +} > ps8_ddr_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___ = .; +} > ps8_ddr_S_AXI_BASEADDR + +.fixup : { + __fixup_start = .; + *(.fixup) + __fixup_end = .; +} > ps8_ddr_S_AXI_BASEADDR + +.eh_frame : { + *(.eh_frame) +} > ps8_ddr_S_AXI_BASEADDR + +.eh_framehdr : { + __eh_framehdr_start = .; + *(.eh_framehdr) + __eh_framehdr_end = .; +} > ps8_ddr_S_AXI_BASEADDR + +.gcc_except_table : { + *(.gcc_except_table) +} > ps8_ddr_S_AXI_BASEADDR + +.mmu_tbl (ALIGN(16384)) : { + __mmu_tbl_start = .; + *(.mmu_tbl) + __mmu_tbl_end = .; +} > ps8_ddr_S_AXI_BASEADDR + +.ARM.exidx : { + __exidx_start = .; + *(.ARM.exidx*) + *(.gnu.linkonce.armexidix.*.*) + __exidx_end = .; +} > ps8_ddr_S_AXI_BASEADDR + +.preinit_array : { + __preinit_array_start = .; + KEEP (*(SORT(.preinit_array.*))) + KEEP (*(.preinit_array)) + __preinit_array_end = .; +} > ps8_ddr_S_AXI_BASEADDR + +.init_array : { + __init_array_start = .; + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array)) + __init_array_end = .; +} > ps8_ddr_S_AXI_BASEADDR + +.fini_array : { + __fini_array_start = .; + KEEP (*(SORT(.fini_array.*))) + KEEP (*(.fini_array)) + __fini_array_end = .; +} > ps8_ddr_S_AXI_BASEADDR + +.ARM.attributes : { + __ARM.attributes_start = .; + *(.ARM.attributes) + __ARM.attributes_end = .; +} > ps8_ddr_S_AXI_BASEADDR + +.sdata : { + __sdata_start = .; + *(.sdata) + *(.sdata.*) + *(.gnu.linkonce.s.*) + __sdata_end = .; +} > ps8_ddr_S_AXI_BASEADDR + +.sbss (NOLOAD) : { + __sbss_start = .; + *(.sbss) + *(.sbss.*) + *(.gnu.linkonce.sb.*) + __sbss_end = .; +} > ps8_ddr_S_AXI_BASEADDR + +.tdata : { + __tdata_start = .; + *(.tdata) + *(.tdata.*) + *(.gnu.linkonce.td.*) + __tdata_end = .; +} > ps8_ddr_S_AXI_BASEADDR + +.tbss : { + __tbss_start = .; + *(.tbss) + *(.tbss.*) + *(.gnu.linkonce.tb.*) + __tbss_end = .; +} > ps8_ddr_S_AXI_BASEADDR + +.bss (NOLOAD) : { + . = ALIGN(4); + __bss_start__ = .; + *(.bss) + *(.bss.*) + *(.gnu.linkonce.b.*) + *(COMMON) + . = ALIGN(4); + __bss_end__ = .; +} > ps8_ddr_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 = .; +} > ps8_ddr_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 = .; +} > ps8_ddr_S_AXI_BASEADDR + +_end = .; +} diff --git a/lib/sw_apps/openamp_echo_test/src/platform.c b/lib/sw_apps/openamp_echo_test/src/platform.c index c2467647..fc67413d 100644 --- a/lib/sw_apps/openamp_echo_test/src/platform.c +++ b/lib/sw_apps/openamp_echo_test/src/platform.c @@ -76,9 +76,10 @@ int _enable_interrupt(struct proc_vring *vring_hw) { /* Register ISR*/ env_register_isr(vring_hw->intr_info.vect_id, &(chn_ipi_info->ipi_base_addr), ipi_isr); /* Enable IPI interrupt */ - env_enable_interrupt(vring_hw->intr_info.vect_id, + /* 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); + vring_hw->intr_info.trigger_type);*/ return 0; } @@ -95,6 +96,7 @@ void _notify(int cpu_id, struct proc_intr *intr_info) { if (chn_ipi_info == NULL) return; platform_dcache_all_flush(); + env_wmb(); /* Trigger IPI */ ipi_trigger(chn_ipi_info->ipi_base_addr, chn_ipi_info->ipi_chn_mask); } diff --git a/lib/sw_apps/openamp_echo_test/src/rsc_table.h b/lib/sw_apps/openamp_echo_test/src/rsc_table.h index 5af45cbd..e167051a 100644 --- a/lib/sw_apps/openamp_echo_test/src/rsc_table.h +++ b/lib/sw_apps/openamp_echo_test/src/rsc_table.h @@ -44,9 +44,8 @@ struct remote_resource_table { unsigned int reserved[2]; unsigned int offset[NO_RESOURCE_ENTRIES]; /* text carve out entry */ - - struct fw_rsc_carveout ddr_cout; struct fw_rsc_carveout ocm_1_cout; + struct fw_rsc_carveout ddr_cout; /* rpmsg vdev entry */ struct fw_rsc_vdev rpmsg_vdev; struct fw_rsc_vdev_vring rpmsg_vring0; diff --git a/lib/sw_apps/openamp_echo_test/src/xpqueue.c b/lib/sw_apps/openamp_echo_test/src/xpqueue.c new file mode 100644 index 00000000..dd446e3a --- /dev/null +++ b/lib/sw_apps/openamp_echo_test/src/xpqueue.c @@ -0,0 +1,93 @@ +/****************************************************************************** +* +* Copyright (C) 2007 - 2014 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* Use of the Software is limited solely to applications: +* (a) running on a Xilinx device, or +* (b) that interact with a Xilinx device through a bus or interconnect. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +* XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ + +#include + +#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; +} diff --git a/lib/sw_apps/openamp_echo_test/src/xpqueue.h b/lib/sw_apps/openamp_echo_test/src/xpqueue.h new file mode 100644 index 00000000..579be463 --- /dev/null +++ b/lib/sw_apps/openamp_echo_test/src/xpqueue.h @@ -0,0 +1,62 @@ +/****************************************************************************** +* +* Copyright (C) 2007 - 2014 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* Use of the Software is limited solely to applications: +* (a) running on a Xilinx device, or +* (b) that interact with a Xilinx device through a bus or interconnect. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +* XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ + +#ifndef __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