sw_apps: openamp echo test is modified to support freertos
Signed-off-by: Kinjal Pravinbhai Patel <patelki@xilinx.com> Acked-for-series: Anirudha Sarangi <anirudh@xilinx.com>
This commit is contained in:
parent
0d7905e608
commit
9e44967224
10 changed files with 738 additions and 62 deletions
|
@ -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 {} {
|
||||
|
|
|
@ -30,21 +30,25 @@
|
|||
*/
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#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
|
||||
}
|
||||
|
||||
/*==================================================================*/
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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();
|
||||
|
||||
}
|
||||
|
|
|
@ -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 = .;
|
||||
}
|
||||
|
|
328
lib/sw_apps/openamp_echo_test/src/lscript_freertos.ld
Normal file
328
lib/sw_apps/openamp_echo_test/src/lscript_freertos.ld
Normal file
|
@ -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 = .;
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
93
lib/sw_apps/openamp_echo_test/src/xpqueue.c
Normal file
93
lib/sw_apps/openamp_echo_test/src/xpqueue.c
Normal file
|
@ -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 <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;
|
||||
}
|
62
lib/sw_apps/openamp_echo_test/src/xpqueue.h
Normal file
62
lib/sw_apps/openamp_echo_test/src/xpqueue.h
Normal file
|
@ -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
|
Loading…
Add table
Reference in a new issue