|
ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
|
Cortex-M85 / RA8D2 core bring-up (called from Reset_Handler). More...
#include <stdint.h>#include "ra8_attributes.h"#include "ra8_boot_entry.h"#include "ra8_cgc.h"#include "trustzone_init.h"Go to the source code of this file.
Enumerations | |
| enum | ra8_core_addr_t : uintptr_t { k_ra8_scb_vtor_addr = 0xE000ED08UL , k_ra8_scb_ccr_addr = 0xE000ED14UL , k_ra8_scb_shcsr_addr = 0xE000ED24UL , k_ra8_scb_cpacr_addr = 0xE000ED88UL , k_ra8_scb_nsacr_addr = 0xE000ED8CUL , k_ra8_scb_iciallu = 0xE000EF50UL , k_ra8_scb_dciallu = 0xE000EF58UL , k_ra8_scb_csselr = 0xE000ED84UL , k_ra8_scb_ccsidr = 0xE000ED80UL , k_ra8_scb_dcisw = 0xE000EF60UL , k_ra8_fpu_fpccr_addr = 0xE000EF34UL , k_ra8_nvic_aircr = 0xE000ED0CUL , k_ra8_mpu_type_addr = 0xE000ED90UL , k_ra8_mpu_ctrl_addr = 0xE000ED94UL , k_ra8_mpu_rnr_addr = 0xE000ED98UL , k_ra8_mpu_rbar_addr = 0xE000ED9CUL , k_ra8_mpu_rlar_addr = 0xE000EDA0UL , k_ra8_mpu_mair0_addr = 0xE000EDC0UL , k_ra8_mpu_mair1_addr = 0xE000EDC4UL } |
| enum | : uint32_t { k_ra8_rbar_attr_ro_x = 0x02U , k_ra8_rbar_attr_rw_xn = 0x03U , k_ra8_rbar_attr_device_rw = 0x23U , k_ra8_mpu_rlar_enable = 1UL << 0 } |
| Programme and enable the Cortex-M85 core MPU. More... | |
| enum | : uint32_t { k_ra8_mpu_mram_base = 0x02000000UL , k_ra8_mpu_mram_limit = 0x020FFFE0UL , k_ra8_mpu_sram_base = 0x22000000UL , k_ra8_mpu_sram_limit = 0x221FFFE0UL , k_ra8_mpu_sdram_base = 0x68000000UL , k_ra8_mpu_sdram_limit = 0x6BFFFFE0UL , k_ra8_mpu_peri_base = 0x40000000UL , k_ra8_mpu_peri_limit = 0x47FFFFE0UL } |
Functions | |
| static uint32_t | internal_read32 (uintptr_t addr) |
| Read a 32-bit core/system register via a volatile load. | |
| static void | internal_write32 (uintptr_t addr, uint32_t value) |
| Write a 32-bit value to a core/system register via a volatile store. | |
| static void | internal_dsb (void) |
| Data Synchronization Barrier (DSB). | |
| static void | internal_isb (void) |
| Instruction Synchronization Barrier (ISB). | |
| static void | internal_disable_irq (void) |
Mask all maskable IRQs at the core (PRIMASK = 1, cpsid i). | |
| static void | internal_set_vtor (void) |
| Point VTOR at the physical vector table base. | |
| static void | internal_enable_fpu (void) |
| Grant full access to CP10 / CP11 (the FPU coprocessors). | |
| static void | internal_enable_fpu_lazy_stack (void) |
| Turn on FPU lazy stacking (FPCCR.LSPEN = 1, ASPEN = 1). | |
| static void | internal_enable_icache (void) |
| Invalidate and enable the Cortex-M85 I-cache. | |
| static void | internal_enable_dcache (void) |
| Invalidate and enable the Cortex-M85 D-cache. | |
| static void | internal_enable_branch_predictor (void) |
| Enable branch-target prediction (CCR.BP on Cortex-M85). | |
| static void | internal_set_priority_grouping (void) |
| Set NVIC priority grouping to 4 preempt bits / 0 sub-priority. | |
| static void | internal_mpu_set_region (uint32_t region, uint32_t base_attr, uint32_t limit_enable) |
| Program a single MPU region via RNR/RBAR/RLAR. | |
| static void | internal_mpu_init (void) |
| Programme and enable the Cortex-M85 core MPU. | |
| static void | internal_halt_secure_clock_fault (void) |
| Park forever after a Secure clock-tree bring-up failure. | |
| void | SystemInit (void) |
| Earliest C code the image runs: bring the core up before RAM init. | |
Variables | |
| const uint32_t | g_ra8_vector_table_start [] |
| uint32_t | g_ra8_ls_stack_top |
Cortex-M85 / RA8D2 core bring-up (called from Reset_Handler).
SystemInit() follows the CMSIS naming convention. Reset_Handler calls it after it has initialised the C runtime (copied .data, zeroed .bss), so it may read and write globals freely. It performs the CPU-core bring-up (VTOR / FPU / priority grouping) and then the Secure peripheral bring-up (clock tree + SAU + the BLXNS into the NS image), which does not return on hardware.
The function is C, not naked asm, so the stack, .data, and .bss must already be usable. Reset_Handler loads SP from the vector table and initialises the C runtime (.data copy + .bss zero) before calling SystemInit(), so reads and writes of initialised globals here are safe – which matters because the Secure clock + TrustZone bring-up it performs touches .data-resident driver state (e.g. log-tag pointers).
Definition in file system_init.c.
| anonymous enum : uint32_t |
Definition at line 402 of file system_init.c.
| anonymous enum : uint32_t |
Programme and enable the Cortex-M85 core MPU.
Installs four regions and enables the MPU with PRIVDEFENA so privileged mode still sees the default memory map for anything not explicitly covered:
Attribute indirection table:
Region base + limit addresses are encoded per ARMv8-M main-profile PMSAv8 rules: low 5 bits of RBAR hold AP[2:0] / SH[4:3] / XN, and RLAR holds the upper bound OR the enable flag in bit 0.
Definition at line 393 of file system_init.c.
| enum ra8_core_addr_t : uintptr_t |
Definition at line 65 of file system_init.c.
|
inlinestatic |
Mask all maskable IRQs at the core (PRIMASK = 1, cpsid i).
Gives the rest of SystemInit a deterministic, interrupt-free bring-up window; main() re-enables IRQs once every handler is wired up. Compiled out under RA8_OFF_TARGET.
Definition at line 188 of file system_init.c.
References RA8_INTERNAL.
Referenced by SystemInit().
|
inlinestatic |
Data Synchronization Barrier (DSB).
Stalls until every preceding memory access completes, so a register write (e.g. a cache or MPU enable) is in effect before later instructions observe it. Compiled out under RA8_OFF_TARGET, where the host emulator has no pipeline to drain.
Definition at line 148 of file system_init.c.
References RA8_INTERNAL.
Referenced by internal_enable_branch_predictor(), internal_enable_dcache(), internal_enable_fpu(), internal_enable_icache(), and internal_mpu_init().
|
static |
Enable branch-target prediction (CCR.BP on Cortex-M85).
Sets the architectural branch-prediction enable bit and retires the control-register update with data and instruction barriers.
< RA8 ccr bp.
Definition at line 336 of file system_init.c.
References internal_dsb(), internal_isb(), internal_read32(), internal_write32(), k_ra8_scb_ccr_addr, and RA8_INTERNAL.
Referenced by SystemInit().
|
static |
Invalidate and enable the Cortex-M85 D-cache.
The invalidate-by-set/way loop is omitted here for brevity – on the RA8D2 the boot ROM leaves the D-cache with all lines marked invalid, so a bulk CCR.DC = 1 write is safe. A production build should add a real CCSIDR-driven loop.
< RA8 ccr dc.
Definition at line 315 of file system_init.c.
References internal_dsb(), internal_isb(), internal_read32(), internal_write32(), k_ra8_scb_ccr_addr, and RA8_INTERNAL.
Referenced by SystemInit().
|
static |
Grant full access to CP10 / CP11 (the FPU coprocessors).
Sets the CP10 and CP11 access fields in SCB CPACR to full access, then issues a DSB + ISB so the FPU is usable before the first floating-point instruction is fetched. Without this, an FP access would raise a UsageFault (NOCP).
< RA8 cpacr cp10 cp11 full access.
Definition at line 235 of file system_init.c.
References internal_dsb(), internal_isb(), internal_read32(), internal_write32(), k_ra8_scb_cpacr_addr, and RA8_INTERNAL.
Referenced by SystemInit().
|
static |
Turn on FPU lazy stacking (FPCCR.LSPEN = 1, ASPEN = 1).
Sets LSPEN (lazy state preservation) and ASPEN (automatic state preservation) in FPCCR so exception entry reserves the FP stack frame but defers the costly FP register save until a handler actually uses the FPU – cutting interrupt latency for non-FP handlers.
< RA8 fpccr lspen.
< RA8 fpccr aspen.
Definition at line 261 of file system_init.c.
References internal_read32(), internal_write32(), k_ra8_fpu_fpccr_addr, and RA8_INTERNAL.
Referenced by SystemInit().
|
static |
Invalidate and enable the Cortex-M85 I-cache.
Invalidates all instruction-cache lines before setting CCR.IC and retires the state transition with data and instruction barriers.
< RA8 ccr ic.
Definition at line 283 of file system_init.c.
References internal_dsb(), internal_isb(), internal_read32(), internal_write32(), k_ra8_scb_ccr_addr, k_ra8_scb_iciallu, and RA8_INTERNAL.
Referenced by SystemInit().
|
static |
Park forever after a Secure clock-tree bring-up failure.
Reached only when ra8_cgc_init fails inside SystemInit. The NS-side NSC CGC veneers require PLL1 locked, and ra8_trustzone_init BLXNS-es into the NS world without returning – so a failed clock bring-up must NOT proceed to the world switch, which would run NS code on a dead clock tree. Parks in a wfi loop at this named, non-inlined symbol so a debugger or HIL probe can pin the secure-boot clock failure; the only escape is a watchdog or debugger reset.
Definition at line 500 of file system_init.c.
References RA8_INTERNAL.
Referenced by SystemInit().
|
inlinestatic |
Instruction Synchronization Barrier (ISB).
Flushes the pipeline so instructions after a context-altering register write (CPACR, CCR, ...) are re-fetched under the new context. Compiled out under RA8_OFF_TARGET.
Definition at line 168 of file system_init.c.
References RA8_INTERNAL.
Referenced by internal_enable_branch_predictor(), internal_enable_dcache(), internal_enable_fpu(), internal_enable_icache(), and internal_mpu_init().
|
static |
Programme and enable the Cortex-M85 core MPU.
Installs code, private SRAM, SDRAM, and peripheral regions before enabling the MPU with the privileged default memory map.
< RA8 MPU control enable.
< RA8 MPU control privdefena.
< RA8 mair0 default.
Definition at line 446 of file system_init.c.
References internal_dsb(), internal_isb(), internal_mpu_set_region(), internal_write32(), k_ra8_mpu_ctrl_addr, k_ra8_mpu_ctrl_enable, k_ra8_mpu_ctrl_privdefena, k_ra8_mpu_mair0_addr, k_ra8_mpu_mair1_addr, k_ra8_mpu_mram_base, k_ra8_mpu_mram_limit, k_ra8_mpu_peri_base, k_ra8_mpu_peri_limit, k_ra8_mpu_rlar_enable, k_ra8_mpu_sdram_base, k_ra8_mpu_sdram_limit, k_ra8_mpu_sram_base, k_ra8_mpu_sram_limit, k_ra8_rbar_attr_device_rw, k_ra8_rbar_attr_ro_x, k_ra8_rbar_attr_rw_xn, and RA8_INTERNAL.
Referenced by SystemInit().
|
static |
Program a single MPU region via RNR/RBAR/RLAR.
Selects one region and writes its base attributes and enabled limit exactly as prepared by internal_mpu_init().
| [in] | region | MPU region number to select. |
| [in] | base_attr | Aligned base address combined with RBAR attributes. |
| [in] | limit_enable | Aligned limit combined with RLAR attributes. |
Definition at line 428 of file system_init.c.
References internal_write32(), k_ra8_mpu_rbar_addr, k_ra8_mpu_rlar_addr, and k_ra8_mpu_rnr_addr.
Referenced by internal_mpu_init().
|
inlinestatic |
Read a 32-bit core/system register via a volatile load.
The volatile cast forces the access to happen exactly once and in program order relative to the other register touches in the bring-up sequence, so the compiler cannot cache or reorder it.
| [in] | addr | 32-bit-aligned MMIO / system-register address to read. |
addr. | 0 | Valid when the addressed field reads back zero. |
addr is a 32-bit-aligned, mapped system-register address. Definition at line 109 of file system_init.c.
References RA8_INTERNAL.
Referenced by internal_enable_branch_predictor(), internal_enable_dcache(), internal_enable_fpu(), internal_enable_fpu_lazy_stack(), and internal_enable_icache().
|
static |
Set NVIC priority grouping to 4 preempt bits / 0 sub-priority.
Writes AIRCR with the required VECTKEY and PRIGROUP = 3, so all available priority bits select the preemption level and none are sub-priority. This gives every configured IRQ a distinct preemption priority, matching the driver layer's priority assignments.
< Required write key.
< PRIGROUP = 3 -> 4 bits.
Definition at line 360 of file system_init.c.
References internal_write32(), k_ra8_nvic_aircr, and RA8_INTERNAL.
Referenced by SystemInit().
|
static |
Point VTOR at the physical vector table base.
Writes the absolute address of the .vectors section (pinned by the linker to the start of MRAM, 0x02000000) into the SCB VTOR register so exceptions vector to this image's handler table.
g_ra8_vector_table_start resolves to the table base. Definition at line 213 of file system_init.c.
References g_ra8_vector_table_start, internal_write32(), k_ra8_scb_vtor_addr, and RA8_INTERNAL.
Referenced by SystemInit().
|
inlinestatic |
Write a 32-bit value to a core/system register via a volatile store.
The volatile cast forces the store to be emitted exactly once and kept in program order with the surrounding register accesses, which the cache / FPU / MPU enable sequences below depend on.
| [in] | addr | 32-bit-aligned MMIO / system-register address to write. |
| [in] | value | 32-bit value to store at addr. |
addr is a 32-bit-aligned, mapped system-register address. addr holds value. Definition at line 129 of file system_init.c.
References RA8_INTERNAL.
Referenced by internal_enable_branch_predictor(), internal_enable_dcache(), internal_enable_fpu(), internal_enable_fpu_lazy_stack(), internal_enable_icache(), internal_mpu_init(), internal_mpu_set_region(), internal_set_priority_grouping(), and internal_set_vtor().
| void SystemInit | ( | void | ) |
Earliest C code the image runs: bring the core up before RAM init.
Called by Reset_Handler before .data is copied and .bss is zeroed, so it must not touch initialised or zero-initialised statics. Each image supplies its own definition – the shared board one under the board boot directories, or an application-local system_init.c where the clock tree or memory map diverges.
The name is the CMSIS convention; the startup code reaches it by that name, which is why it has external linkage.
Definition at line 516 of file system_init.c.
References internal_disable_irq(), internal_enable_branch_predictor(), internal_enable_dcache(), internal_enable_fpu(), internal_enable_fpu_lazy_stack(), internal_enable_icache(), internal_halt_secure_clock_fault(), internal_mpu_init(), internal_set_priority_grouping(), internal_set_vtor(), k_ra8_ok, ra8_cgc_init(), and ra8_trustzone_init().
|
extern |
|
extern |
Definition at line 294 of file vector_table.c.