This is an automated email from the ASF dual-hosted git repository. xiaoxiang781216 pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/nuttx.git
commit 4416660ce229a8074d3eb121576b1698fcbe981e Author: dechao_gong <[email protected]> AuthorDate: Tue Sep 15 13:01:04 2026 +0800 arch/arm/ameba: enable SMP on AmebaSmart CA32 (RTL8730E) RTL8730E has dual Cortex-A32 cores (CA32) in the AP domain. Core1 is powered off by default and requires an explicit HSYS power-on sequence before ATF SP_MIN can service the PSCI CPU_ON call. Without it, SP_MIN writes the entry point to the mailbox and times out waiting for Core1 to poll it. Add rtl8730e_core1_power_on() that mirrors SDK smp.c:rtk_core1_power_on(): assert reset, assert isolation, two-stage power-on with up_udelay() for correct 50/50/500/50 us timing, then release isolation and reset. Call it from up_cpu_start() before psci_cpu_on(). Enable CONFIG_SMP / CONFIG_SMP_NCPUS=2 / CONFIG_ARM_PSCI in the nsh defconfig. Enabling SMP also exposed a latent WHC skb alignment bug: the Realtek WHC WiFi driver keeps the AP/NP DDR views coherent with by-VA DCache_Clean/Invalidate at SKB_CACHE_SZ (64 on RTL8730E) granularity, which requires every skb buffer to be cache-line aligned. The port had omitted CONFIG_MM_DEFAULT_ALIGNMENT (defaulting to 8; the 8721Dx parts set 32), so heap-allocated skb buffers were unaligned and the cache maintenance spilled onto the neighbouring skb struct, corrupting its immutable buf pointer (seen as skb->buf = 0x05 and a TX memcpy data abort on "renew wlan0"). This was harmless on single core -- the non-shareable DDR mapping made the stray maintenance a no-op -- but the SMP shareable mapping plus real dual-core concurrency turned it into a hard fault. Set CONFIG_MM_DEFAULT_ALIGNMENT=64 in the nsh defconfig. Hardware verified on RTL8730E (C-cut): /proc/cpuinfo shows both processor 0 and processor 1; getprime 2 completes two concurrent threads in ~573 ms (same as single-thread), confirming true parallel execution across both cores. "renew wlan0" now obtains a DHCP lease (192.168.1.101) without faulting. Assisted-by: Claude Sonnet 4.6 <[email protected]> Signed-off-by: dechao_gong <[email protected]> --- arch/arm/src/common/ameba/ameba_os_wrap.c | 13 +++- arch/arm/src/rtl8730e/rtl8730e_boot.c | 72 ++++++++++++++++++++++ boards/arm/rtl8730e/ca32-evb/configs/nsh/defconfig | 4 ++ 3 files changed, 86 insertions(+), 3 deletions(-) diff --git a/arch/arm/src/common/ameba/ameba_os_wrap.c b/arch/arm/src/common/ameba/ameba_os_wrap.c index ed40479a766..ed562e16740 100644 --- a/arch/arm/src/common/ameba/ameba_os_wrap.c +++ b/arch/arm/src/common/ameba/ameba_os_wrap.c @@ -170,9 +170,16 @@ bool os_heap_add(uint8_t *start_addr, size_t heap_size) * the NP DMAs them, so an unaligned base would clobber neighbouring data on * cache maintenance. whc_ipc_host_init_skb() outright rejects an unaligned * skb_data_buf ("skb_data_buf malloc fail!"), leaving the skb pool empty and - * the TX path handing the NP a garbage buffer pointer. This is guaranteed - * by CONFIG_MM_DEFAULT_ALIGNMENT=32 (>= SKB_CACHE_SZ) -- every NuttX heap - * block is then cache-line aligned, so plain kmm_* suffices here. + * the TX path handing the NP a garbage buffer pointer. Worse, when the pool + * squeaks past that check but is not aligned to the full cache line, the + * driver's by-VA DCache_Clean/Invalidate spills onto the neighbouring skb + * struct and corrupts its (immutable) buf pointer, so a later TX memcpy + * faults on a garbage skb->data (seen as skb->buf = 0x05). + * + * This is guaranteed by CONFIG_MM_DEFAULT_ALIGNMENT >= SKB_CACHE_SZ -- every + * NuttX heap block is then cache-line aligned, so plain kmm_* suffices here. + * SKB_CACHE_SZ is 32 on the other Ameba WHC parts but 64 on AmebaSmart + * (RTL8730E), so that board's defconfig sets CONFIG_MM_DEFAULT_ALIGNMENT=64. */ void *rtos_mem_malloc(uint32_t size) diff --git a/arch/arm/src/rtl8730e/rtl8730e_boot.c b/arch/arm/src/rtl8730e/rtl8730e_boot.c index 00e66e9baaa..54ca01ca684 100644 --- a/arch/arm/src/rtl8730e/rtl8730e_boot.c +++ b/arch/arm/src/rtl8730e/rtl8730e_boot.c @@ -25,6 +25,7 @@ ****************************************************************************/ #include <nuttx/config.h> +#include <nuttx/arch.h> #include "arm_internal.h" @@ -132,6 +133,71 @@ void arm_boot(void) #endif } +/* RTL8730E HSYS / CA32 register addresses for Core1 power sequencing. + * Core1 is powered off by default; ATF SP_MIN waits for Core1 to poll its + * mailbox but the core never wakes unless the HSYS power rails are enabled + * first. These constants mirror the SDK smp.c / ameba_hsys.h definitions + * without requiring vendor headers. + */ + +#define RTL8730E_HSYS_BASE 0x41000000u +#define RTL8730E_HSYS_HP_PWC 0x000u +#define RTL8730E_HSYS_HP_ISO 0x004u +#define RTL8730E_CA32_RST_CTRL 0x41000204u + +#define HSYS_PSW_HP_AP_CORE(x) (((x) & 0x3u) << 4) +#define HSYS_PSW_HP_AP_CORE_2ND(x) (((x) & 0x3u) << 6) +#define HSYS_ISO_HP_AP_CORE(x) (((x) & 0x3u) << 4) +#define HSYS_GET_ISO_HP_AP_CORE(x) (((x) >> 4) & 0x3u) +#define CA32_NCOREPORESET(x) (((x) & 0x3u) << 0) +#define CA32_NCORERESET(x) (((x) & 0x3u) << 4) + +static void rtl8730e_core1_power_on(void) +{ + volatile uint32_t *pwc = (volatile uint32_t *)(RTL8730E_HSYS_BASE + + RTL8730E_HSYS_HP_PWC); + volatile uint32_t *iso = (volatile uint32_t *)(RTL8730E_HSYS_BASE + + RTL8730E_HSYS_HP_ISO); + volatile uint32_t *rst = (volatile uint32_t *)RTL8730E_CA32_RST_CTRL; + uint32_t val; + + /* Assert reset on core1 */ + + *rst &= ~(CA32_NCOREPORESET(0x2u) | CA32_NCORERESET(0x2u)); + + /* Assert isolation on core1 */ + + val = *iso; + val |= HSYS_ISO_HP_AP_CORE(0x2u); + *iso = val; + up_udelay(50); + + /* First-stage power-on (mask 0x3 keeps core0 rails stable) */ + + val = *pwc; + val |= HSYS_PSW_HP_AP_CORE(0x3u); + *pwc = val; + up_udelay(50); + + /* Second-stage power-on */ + + val = *pwc; + val |= HSYS_PSW_HP_AP_CORE_2ND(0x3u); + *pwc = val; + up_udelay(500); + + /* Release isolation */ + + val = *iso; + val &= ~HSYS_ISO_HP_AP_CORE(0x3u); + *iso = val; + up_udelay(50); + + /* Release reset */ + + *rst |= (CA32_NCOREPORESET(0x2u) | CA32_NCORERESET(0x2u)); +} + #if defined(CONFIG_ARM_PSCI) && defined(CONFIG_SMP) int up_cpu_start(int cpu) { @@ -149,6 +215,12 @@ int up_cpu_start(int cpu) UP_DSB(); #endif + if (cpu == 1) + { + rtl8730e_core1_power_on(); + up_udelay(40); + } + return psci_cpu_on(cpu, (uintptr_t)__start); } #endif diff --git a/boards/arm/rtl8730e/ca32-evb/configs/nsh/defconfig b/boards/arm/rtl8730e/ca32-evb/configs/nsh/defconfig index a0bcfe619f1..e98deccb492 100644 --- a/boards/arm/rtl8730e/ca32-evb/configs/nsh/defconfig +++ b/boards/arm/rtl8730e/ca32-evb/configs/nsh/defconfig @@ -13,6 +13,9 @@ CONFIG_ARCH_BOARD_CA32_EVB=y CONFIG_ARCH_CHIP="rtl8730e" CONFIG_ARCH_CHIP_RTL8730E=y CONFIG_ARCH_INTERRUPTSTACK=2048 +CONFIG_ARM_PSCI=y +CONFIG_SMP=y +CONFIG_SMP_NCPUS=2 CONFIG_ARCH_LOWVECTORS=y CONFIG_IDENTITY_TEXTMAP=y CONFIG_ARM_SEMIHOSTING_HOSTFS=y @@ -38,6 +41,7 @@ CONFIG_HAVE_CXXINITIALIZE=y CONFIG_IDLETHREAD_STACKSIZE=4096 CONFIG_INIT_ENTRYPOINT="init_main" CONFIG_LIBC_EXECFUNCS=y +CONFIG_MM_DEFAULT_ALIGNMENT=64 CONFIG_MODULE=y CONFIG_NSH_BUILTIN_APPS=y CONFIG_NSH_FILEIOSIZE=512
