sw_apps: added support for cortexa9 to openamp rpc demo 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:21 +05:30 committed by Nava kishore Manne
parent 5a398f8caa
commit 44d2785d51
21 changed files with 1883 additions and 4 deletions

View file

@ -73,8 +73,8 @@ 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;
@ -89,11 +89,33 @@ proc check_stdout_hw {} {
return;
}
proc swapp_generate {} {
set oslist [get_os];
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 +136,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,258 @@
/*
* 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;
#ifndef USE_FREERTOS
process_communication(OpenAMPInstPtr);
#else
env_release_sync_lock(OpenAMPInstPtr.lock);
#endif
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,196 @@
/*
* 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 "platform.h"
#include "amp_os.h"
#ifdef USE_FREERTOS
#include "FreeRTOS.h"
#include "task.h"
#include "timers.h"
#include "queue.h"
#endif
#include "xil_mmu.h"
#include "xil_cache.h"
#include "xil_exception.h"
struct XOpenAMPInstPtr{
unsigned int IntrID;
unsigned int IPI_Status;
void *lock;
};
/* 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,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,287 @@
/*
* 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 proxy
* from the remote core. This application is meant to run on the remote CPU running
* bare-metal. It can print to master console and perform file I/O
* using proxy mechanism.
*
* The init_system is called from 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, this application will use the console to display
* print statements and execute file I/O on master by communicating with a proxy application
* running on the Linux 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 <string.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include "open_amp.h"
#include "rsc_table.h"
#include "baremetal.h"
#include "rpmsg_retarget.h"
#include "xil_cache.h"
#include "xil_mmu.h"
#define SHUTDOWN_MSG 0xEF56A55A
/* 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 shutdown_cb(struct rpmsg_channel *rp_chnl);
static void communication_task();
static void rpc_demo();
/* Static variables */
static struct rpmsg_channel *app_rp_chnl;
static struct remote_proc *proc = NULL;
static struct rsc_table_info rsc_info;
#ifdef USE_FREERTOS
static TaskHandle_t comm_task;
static TaskHandle_t rpc_dmo;
#endif
void *chnl_cb_flag;
/* Globals */
extern const struct remote_resource_table resources;
struct XOpenAMPInstPtr OpenAMPInstPtr;
#define REDEF_O_CREAT 100
#define REDEF_O_EXCL 200
#define REDEF_O_RDONLY 0
#define REDEF_O_WRONLY 1
#define REDEF_O_RDWR 2
#define REDEF_O_APPEND 2000
#define REDEF_O_ACCMODE 3
#define RPC_CHANNEL_READY_TO_CLOSE "rpc_channel_ready_to_close"
/* Application entry point */
int main() {
#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(rpc_demo, ( const char * ) "HW2",
2048, NULL, 1, &rpc_dmo );
if(stat != pdPASS)
return -1;
/*Create Queues*/
env_create_sync_lock(&OpenAMPInstPtr.lock,LOCKED);
env_create_sync_lock(&chnl_cb_flag,LOCKED);
/* Start the tasks and timer running. */
vTaskStartScheduler();
#else
env_create_sync_lock(&chnl_cb_flag,LOCKED);
communication_task();
#endif
while(1);
}
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;
}
env_enable_interrupt(VRING0_IPI_VECT, 0, 0);
env_enable_interrupt(VRING1_IPI_VECT, 0, 0);
#ifdef USE_FREERTOS
while (1) {
env_acquire_sync_lock(OpenAMPInstPtr.lock);
process_communication(OpenAMPInstPtr);
}
#else
rpc_demo();
#endif
}
void rpc_demo(){
int fd, bytes_written, bytes_read;
char fname[] = "remote.file";
char wbuff[50];
char rbuff[1024];
char ubuff[50];
float fdata;
int idata;
int ret;
env_acquire_sync_lock(chnl_cb_flag);
rpmsg_retarget_init(app_rp_chnl, shutdown_cb);
#ifdef USE_FREERTOS
printf("\r\nRemote>FreeRTOS Remote Procedure Call (RPC) Demonstration\r\n");
#else
printf("\r\nRemote>Baremetal Remote Procedure Call (RPC) Demonstration\r\n");
#endif
printf("\r\nRemote>***************************************************\r\n");
printf("\r\nRemote>Rpmsg based retargetting to proxy initialized..\r\n");
/* Remote performing file IO on Master */
printf("\r\nRemote>FileIO demo ..\r\n");
printf("\r\nRemote>Creating a file on master and writing to it..\r\n");
fd = open(fname, REDEF_O_CREAT | REDEF_O_WRONLY | REDEF_O_APPEND,
S_IRUSR | S_IWUSR);
printf("\r\nRemote>Opened file '%s' with fd = %d\r\n", fname, fd);
sprintf(wbuff, "This is a test string being written to file..");
bytes_written = write(fd, wbuff, strlen(wbuff));
printf("\r\nRemote>Wrote to fd = %d, size = %d, content = %s\r\n", fd,
bytes_written, wbuff);
close(fd);
printf("\r\nRemote>Closed fd = %d\r\n", fd);
/* Remote performing file IO on Master */
printf("\r\nRemote>Reading a file on master and displaying its contents..\r\n");
fd = open(fname, REDEF_O_RDONLY, S_IRUSR | S_IWUSR);
printf("\r\nRemote>Opened file '%s' with fd = %d\r\n", fname, fd);
bytes_read = read(fd, rbuff, 1024);
*(char*) (&rbuff[0] + bytes_read + 1) = 0;
printf( "\r\nRemote>Read from fd = %d, size = %d, printing contents below .. %s\r\n",
fd, bytes_read, rbuff);
close(fd);
printf("\r\nRemote>Closed fd = %d\r\n", fd);
while (1) {
/* Remote performing STDIO on Master */
printf("\r\nRemote>Remote firmware using scanf and printf ..\r\n");
printf("\r\nRemote>Scanning user input from master..\r\n");
printf("\r\nRemote>Enter name\r\n");
ret = scanf("%s", ubuff);
if (ret) {
printf("\r\nRemote>Enter age\r\n");
ret = scanf("%d", &idata);
if(ret) {
printf("\r\nRemote>Enter value for pi\r\n");
ret = scanf("%f", &fdata);
if(ret) {
printf("\r\nRemote>User name = '%s'\r\n", ubuff);
printf("\r\nRemote>User age = '%d'\r\n", idata);
printf("\r\nRemote>User entered value of pi = '%f'\r\n",fdata);
}
}
}
if(!ret) {
scanf("%s", ubuff);
printf("Remote> Invalid value. Starting again....");
} else {
printf("\r\nRemote>Repeat demo ? (enter yes or no) \r\n");
scanf("%s", ubuff);
if((strcmp(ubuff,"no")) && (strcmp(ubuff,"yes"))) {
printf("\r\nRemote>Invalid option. Starting again....\r\n");
} else if((!strcmp(ubuff,"no"))) {
printf("\r\nRemote>RPC retargetting quitting ...\r\n");
sprintf(wbuff, RPC_CHANNEL_READY_TO_CLOSE);
rpmsg_retarget_send(wbuff, sizeof(RPC_CHANNEL_READY_TO_CLOSE) + 1);
break;
}
}
}
printf("\r\nRemote> Firmware's rpmsg-openamp-demo-channel going down! \r\n");
while (1) {
__asm__ ( "\
wfi\n\t" \
);
}
}
static void rpmsg_channel_created(struct rpmsg_channel *rp_chnl) {
app_rp_chnl = rp_chnl;
env_release_sync_lock(chnl_cb_flag);
}
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) {
}
static void shutdown_cb(struct rpmsg_channel *rp_chnl) {
rpmsg_retarget_deinit(rp_chnl);
remoteproc_resource_deinit(proc);
}

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;
};