Skip to content

Commit

Permalink
Merge pull request #934 from iabdalkader/rpc_openamp_updates
Browse files Browse the repository at this point in the history
RPC/OpenAMP: Support loading sketches to SDRAM.
  • Loading branch information
facchinm authored Sep 9, 2024
2 parents 92eaf0e + 3b4c179 commit e10dfd2
Show file tree
Hide file tree
Showing 10 changed files with 487 additions and 156 deletions.
373 changes: 373 additions & 0 deletions libraries/RPC/LICENSE

Large diffs are not rendered by default.

31 changes: 31 additions & 0 deletions libraries/RPC/src/RPC.cpp
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
// Copyright (c) 2024 Arduino SA
// SPDX-License-Identifier: MPL-2.0
#include "RPC.h"

#define ENDPOINT_ID_RAW 0
Expand Down Expand Up @@ -161,6 +163,35 @@ int RPCClass::begin() {
#endif

#ifdef CORE_CM4
#if (CM4_BINARY_START >= 0x60000000) && (CM4_BINARY_START < 0xe0000000)
class M4Init {
public:
M4Init() {
// If the Cortex-M4 core is booting from SDRAM, the memory region must be
// configured as Strongly Ordered. Note that the Cortex-M4 core does not
// seem to implement speculative prefetching, so there is no need to protect
// the whole region from speculative prefetching with a second MPU region.
HAL_MPU_Disable();
MPU_Region_InitTypeDef MPU_InitStruct;
MPU_InitStruct.Number = MPU_REGION_NUMBER1;
MPU_InitStruct.Enable = MPU_REGION_ENABLE;
MPU_InitStruct.BaseAddress = CM4_BINARY_START;
MPU_InitStruct.Size = MPU_REGION_SIZE_1MB;
MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0;
MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE;
MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE;
MPU_InitStruct.IsCacheable = MPU_ACCESS_NOT_CACHEABLE;
MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE;
MPU_InitStruct.SubRegionDisable = 0x00;
HAL_MPU_ConfigRegion(&MPU_InitStruct);
HAL_MPU_Enable(MPU_PRIVILEGED_DEFAULT);
}
};

M4Init __m4init __attribute__ ((init_priority (101)));
#endif

int RPCClass::begin() {
eventThread = new rtos::Thread(osPriorityHigh, 16*1024, nullptr, "rpc_evt");
eventThread->start(&eventHandler);
Expand Down
2 changes: 2 additions & 0 deletions libraries/RPC/src/RPC.h
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
// Copyright (c) 2024 Arduino SA
// SPDX-License-Identifier: MPL-2.0
#ifdef __cplusplus

#ifndef __ARDUINO_RPC_IMPLEMENTATION__
Expand Down
2 changes: 2 additions & 0 deletions libraries/RPC/src/RPC_client.h
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
// Copyright (c) 2024 Arduino SA
// SPDX-License-Identifier: MPL-2.0
#include "Arduino.h"
#include "mbed.h"
#include "rpc/dispatcher.h"
Expand Down
4 changes: 3 additions & 1 deletion libraries/RPC/src/SerialRPC.cpp
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
// Copyright (c) 2024 Arduino SA
// SPDX-License-Identifier: MPL-2.0
#include "SerialRPC.h"
#include "RPC.h"

Expand All @@ -22,4 +24,4 @@ arduino::SerialRPCClass::operator bool() {
return RPC;
}

arduino::SerialRPCClass SerialRPC;
arduino::SerialRPCClass SerialRPC;
4 changes: 3 additions & 1 deletion libraries/RPC/src/SerialRPC.h
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
// Copyright (c) 2024 Arduino SA
// SPDX-License-Identifier: MPL-2.0
#ifndef __SERIAL_RPC__
#define __SERIAL_RPC__

Expand Down Expand Up @@ -69,4 +71,4 @@ class SerialRPCClass : public Stream {

extern arduino::SerialRPCClass SerialRPC;

#endif
#endif
3 changes: 3 additions & 0 deletions libraries/openamp_arduino/src/openamp_conf.h
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,9 @@ extern int __OPENAMP_region_end__[];
#define SHM_START_ADDRESS ((metal_phys_addr_t)__OPENAMP_region_start__)
#define SHM_SIZE (size_t)((void *)__OPENAMP_region_end__ - (void *) __OPENAMP_region_start__)

#define SHM_RSC_SIZE (1024)
#define SHM_RSC_ADDR ((void *)__OPENAMP_region_start__ - SHM_RSC_SIZE)

#endif

#define VRING_RX_ADDRESS SHM_START_ADDRESS
Expand Down
167 changes: 44 additions & 123 deletions libraries/openamp_arduino/src/rsc_table.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,137 +21,58 @@
******************************************************************************
*/

/** @addtogroup RSC_TABLE
* @{
*/

/** @addtogroup resource_table
* @{
*/

/** @addtogroup resource_table_Private_Includes
* @{
*/


#if defined(__ICCARM__) || defined (__CC_ARM)
#include <stddef.h> /* needed for offsetof definition*/
#endif
#include "rsc_table.h"
#include "openamp/open_amp.h"

/**
* @}
*/

/** @addtogroup resource_table_Private_TypesDefinitions
* @{
*/

/**
* @}
*/

/** @addtogroup resource_table_Private_Defines
* @{
*/

/* Place resource table in special ELF section */
#if defined(__GNUC__)
#define __section_t(S) __attribute__((__section__(#S)))
#define __resource __section_t(.resource_table)
#endif

#define RPMSG_IPU_C0_FEATURES 1
#define VRING_COUNT 2

/* VirtIO rpmsg device id */
#define VIRTIO_ID_RPMSG_ 7

#if defined (__LOG_TRACE_IO_)
extern char system_log_buf[];
#endif

#if defined(__GNUC__)
#if !defined (__CC_ARM)
/* Since GCC is not initializing the resource_table at startup, it is declared as volatile to avoid compiler optimization
* for the CM4 (see resource_table_init() below)
*/
volatile struct shared_resource_table __resource __attribute__((used)) resource_table;
#else
struct shared_resource_table __resource __attribute__((used)) resource_table = {
#endif
#elif defined(__ICCARM__)
__root struct shared_resource_table resource_table @ ".resource_table" = {
#endif

#if defined(__ICCARM__) || defined (__CC_ARM)
.version = 1,
.num = 2,
.reserved = {0, 0},
.offset = {
offsetof(struct shared_resource_table, vdev),
offsetof(struct shared_resource_table, cm_trace),
},

/* Virtio device entry */
.vdev= {
RSC_VDEV, VIRTIO_ID_RPMSG_, 0, RPMSG_IPU_C0_FEATURES, 0, 0, 0,
VRING_COUNT, {0, 0},
},

/* Vring rsc entry - part of vdev rsc entry */
.vring0 = {VRING_TX_ADDRESS, VRING_ALIGNMENT, VRING_NUM_BUFFS, VRING0_ID, 0},
.vring1 = {VRING_RX_ADDRESS, VRING_ALIGNMENT, VRING_NUM_BUFFS, VRING1_ID, 0},

#if defined (__LOG_TRACE_IO_)
.cm_trace = {
RSC_TRACE,
(uint32_t)system_log_buf, SYSTEM_TRACE_BUF_SZ, 0, "cm4_log",
},
#endif
} ;
#endif

void resource_table_init(int RPMsgRole, void **table_ptr, int *length)
{

#if defined (__GNUC__) && ! defined (__CC_ARM)
#ifdef CORE_CM7
/*
* Currently the GCC linker doesn't initialize the resource_table global variable at startup
* it is done here by the CM7 application.
*/
memset(&resource_table, '\0', sizeof(struct shared_resource_table));
resource_table.num = 1;
resource_table.version = 1;
resource_table.offset[0] = offsetof(struct shared_resource_table, vdev);

resource_table.vring0.da = VRING_TX_ADDRESS;
resource_table.vring0.align = VRING_ALIGNMENT;
resource_table.vring0.num = VRING_NUM_BUFFS;
resource_table.vring0.notifyid = VRING0_ID;

resource_table.vring1.da = VRING_RX_ADDRESS;
resource_table.vring1.align = VRING_ALIGNMENT;
resource_table.vring1.num = VRING_NUM_BUFFS;
resource_table.vring1.notifyid = VRING1_ID;


resource_table.vdev.type = RSC_VDEV;
resource_table.vdev.id = VIRTIO_ID_RPMSG_;
resource_table.vdev.num_of_vrings=VRING_COUNT;
resource_table.vdev.dfeatures = RPMSG_IPU_C0_FEATURES;
#else
/* For CM4 let's wait until the resource_table is correctly initialized */
while(resource_table.vring1.da != VRING_RX_ADDRESS)
{

}
#endif
#endif

(void)RPMsgRole;
*length = sizeof(resource_table);
*table_ptr = &resource_table;
void resource_table_init(int RPMsgRole, void **table_ptr, int *length) {
(void)RPMsgRole;
volatile struct shared_resource_table *resource_table = SHM_RSC_ADDR;

#ifdef CORE_CM7
memset(resource_table, 0, SHM_RSC_SIZE);
resource_table->num = 1;
resource_table->version = 1;
resource_table->offset[0] = offsetof(struct shared_resource_table, vdev);
#if defined (__LOG_TRACE_IO_)
resource_table->offset[1] = offsetof(struct shared_resource_table, cm_trace);
#endif

resource_table->vring0.da = VRING_TX_ADDRESS;
resource_table->vring0.align = VRING_ALIGNMENT;
resource_table->vring0.num = VRING_NUM_BUFFS;
resource_table->vring0.notifyid = VRING0_ID;

resource_table->vring1.da = VRING_RX_ADDRESS;
resource_table->vring1.align = VRING_ALIGNMENT;
resource_table->vring1.num = VRING_NUM_BUFFS;
resource_table->vring1.notifyid = VRING1_ID;

#if defined (__LOG_TRACE_IO_)
resource_table->cm_trace.type;
resource_table->cm_trace.da;
resource_table->cm_trace.len;
resource_table->cm_trace.reserved = 0;
resource_table->cm_trace.name = (uint8_t[]){"cm_trace"};
#endif

resource_table->vdev.type = RSC_VDEV;
resource_table->vdev.id = VIRTIO_ID_RPMSG;
resource_table->vdev.num_of_vrings=VRING_COUNT;
resource_table->vdev.dfeatures = (1 << VIRTIO_RPMSG_F_NS);
#else
// For CM4, wait until the resource_table is initialized by the host
while(resource_table->vring1.da != VRING_RX_ADDRESS) {

}
#endif

*length = SHM_RSC_SIZE;
*table_ptr = resource_table;
}
40 changes: 19 additions & 21 deletions mbed-os-to-arduino
Original file line number Diff line number Diff line change
Expand Up @@ -187,31 +187,16 @@ generate_flags () {
echo "Patching '-fno-exceptions' flag for $ARDUINOVARIANT/${fl}flags.txt"
sed -i '/-fno-exceptions/d' "$ARDUINOVARIANT"/${fl}flags.txt
set +e
HAS_OPENAMP_SECTION=`grep openamp_section "$ARDUINOVARIANT"/linker_script.ld`
HAS_PDM_SECTION=`grep pdm_section "$ARDUINOVARIANT"/linker_script.ld`
set -e
if [ x"$HAS_OPENAMP_SECTION" == x ]; then
echo "Adding OpenAMP section to $ARDUINOVARIANT/linker_script.ld"
OPENAMP_SECTION=".openamp_section (NOLOAD) : {\n \
. = ABSOLUTE(0x38000000);\n \
*(.resource_table)\n \
} >RAM_D3 AT > FLASH\n \
.pdm_section (NOLOAD) : {\n \
. = ABSOLUTE(0x3800FC00);\n \
if [ x"$HAS_PDM_SECTION" == x ]; then
echo "Adding PDM section to $ARDUINOVARIANT/linker_script.ld"
PDM_SECTION=".pdm_section 0x3800FC00 (NOLOAD): {\n \
*(.pdm_buffer)\n \
} > RAM_D3\n"

if [[ $ARDUINOVARIANT == *GENERIC*M4 ]]; then
echo "Fixing VTOR base in $ARDUINOVARIANT/linker_script.ld"
VTOR_SECTION="#if (CM4_BINARY_START == 0x60000000)\n \
REGION_ALIAS(\"RAM\", FLASH);\n \
#else\n \
REGION_ALIAS(\"RAM\", RAM_D2);\n \
#endif\n"
sed -i "s?REGION_ALIAS.*?${VTOR_SECTION}?g" $ARDUINOVARIANT/linker_script.ld
fi

if [[ $ARDUINOVARIANT == *PORTENTA*M7* || $ARDUINOVARIANT == *GIGA* || $ARDUINOVARIANT == *OPTA* ]]; then
OPENAMP_SECTION="${OPENAMP_SECTION} \
PDM_SECTION="${PDM_SECTION} \
_dtcm_lma = __etext + SIZEOF(.data);\n \
.dtcm : AT(_dtcm_lma) {\n \
_sdtcm = .;\n \
Expand All @@ -220,9 +205,22 @@ generate_flags () {
} > DTCMRAM"
fi

sed -i "s?.heap (COPY):?${OPENAMP_SECTION}\n .heap (COPY):?g" $ARDUINOVARIANT/linker_script.ld
sed -i "s?.heap (COPY):?${PDM_SECTION}\n .heap (COPY):?g" $ARDUINOVARIANT/linker_script.ld
OPENAMP_REGIONS="__OPENAMP_region_start__ = 0x38000400;\n__OPENAMP_region_end__ = 0x38000400 + LENGTH(RAM_D3) - 1K;"
sed -i "s?ENTRY(Reset_Handler)?${OPENAMP_REGIONS}\nENTRY(Reset_Handler)?g" $ARDUINOVARIANT/linker_script.ld

if [[ $ARDUINOVARIANT == *GENERIC*M4 ]]; then
echo "Fixing VTOR base in $ARDUINOVARIANT/linker_script.ld"
VTOR_SECTION="#if (CM4_BINARY_START == 0x60000000)\n \
REGION_ALIAS(\"RAM\", FLASH);\n \
#else\n \
REGION_ALIAS(\"RAM\", RAM_D2);\n \
#endif\n"
sed -i "s?REGION_ALIAS.*?${VTOR_SECTION}?g" $ARDUINOVARIANT/linker_script.ld
echo "Fixing shared memory attributes in $ARDUINOVARIANT/linker_script.ld"
sed -i "s?.heap (COPY)?.heap (NOLOAD)?g" $ARDUINOVARIANT/linker_script.ld
sed -i "s?.stack_dummy (COPY)?.stack_dummy (NOLOAD)?g" $ARDUINOVARIANT/linker_script.ld
fi
fi
echo "Patching linker scripts"
sed -i 's/0x8100000/CM4_BINARY_START/g' "$ARDUINOVARIANT"/linker_script.ld
Expand Down
17 changes: 7 additions & 10 deletions variants/GENERIC_STM32H747_M4/linker_script.ld
Original file line number Diff line number Diff line change
Expand Up @@ -91,24 +91,21 @@ SECTIONS
__bss_end__ = .;
_ebss = .;
} > RAM
.openamp_section (NOLOAD) : {
. = ABSOLUTE(0x38000000);
*(.resource_table)
} >RAM_D3 AT > FLASH
.pdm_section (NOLOAD) : {
. = ABSOLUTE(0x3800FC00);
*(.pdm_buffer)
} > RAM_D3

.heap (COPY):
.pdm_section 0x3800FC00 (NOLOAD): {
*(.pdm_buffer)
} > RAM_D3

.heap (NOLOAD):
{
__end__ = .;
PROVIDE(end = .);
*(.heap*)
. = ORIGIN(RAM) + LENGTH(RAM) - 0x400;
__HeapLimit = .;
} > RAM
.stack_dummy (COPY):

.stack_dummy (NOLOAD):
{
*(.stack*)
} > RAM
Expand Down

0 comments on commit e10dfd2

Please sign in to comment.