ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
Loading...
Searching...
No Matches
system_init.c File Reference

examples/ek_ra8d2/hil_needs_revalidation/cpu1_pingpong_ipc/src/system_init.c More...

#include <stdint.h>
#include "ra8_attributes.h"
#include "ra8_boot_entry.h"
#include "trustzone_init.h"
Include dependency graph for system_init.c:

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 one 32-bit core register through a volatile MMIO access.
static void internal_write32 (uintptr_t addr, uint32_t value)
 Write one 32-bit value to a core register.
static void internal_dsb (void)
 Complete outstanding explicit memory accesses on the target.
static void internal_isb (void)
 Flush the target instruction pipeline after a control-state change.
static void internal_disable_irq (void)
 Mask configurable interrupts during early core initialization.
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.
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

Detailed Description

examples/ek_ra8d2/hil_needs_revalidation/cpu1_pingpong_ipc/src/system_init.c

Cortex-M85 / RA8D2 core bring-up for cpu1_pingpong_ipc

SystemInit() follows the CMSIS naming convention and runs as the first C function out of reset, before Reset_Handler copies .data or zeroes .bss. Its responsibilities are strictly CPU-core level – anything peripheral-bus-side belongs in ra8_infrastructure_init() called from main() after the C runtime is live.

Bring-up sequence

  1. Set VTOR to the physical address of the vector table (so that linker relocations and later TrustZone / bootloader hand-offs work).
  2. Enable CP10 / CP11 so the FPU is usable before any floating-point instruction runs.
  3. Enable FPU lazy stacking (FPCCR.LSPEN) so ISRs do not pay the full FP-state save cost unless they touch the FPU.
  4. Enable the I-cache and D-cache (Cortex-M85 has both). Without this the core runs at a small fraction of its rated speed.
  5. Enable the branch-target predictor (CCR.BP).
  6. Programme NVIC priority grouping to 4 bits preempt / 0 bits sub (the standard embedded pattern).
  7. Disable interrupts until the application is ready – this mirrors CMSIS convention. main() re-enables via __enable_irq() once all drivers are up.

The function is C, not naked asm, so stack and BSS must already be usable. Reset_Handler loads SP from the vector table before calling SystemInit(), so the stack is fine; BSS is zeroed only after SystemInit() returns but SystemInit() writes to no BSS or data-section variables, so the ordering is safe.

Definition in file system_init.c.

Enumeration Type Documentation

◆ anonymous enum

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:

  • Region 0: MRAM (0x02000000, 1 MiB) – read + execute, inner/outer cacheable.
  • Region 1: SRAM (0x22000000, 2 MiB) – read + write, no execute.
  • Region 2: SDRAM (0x68000000, 64 MiB) – read + write, no execute.
  • Region 3: Peripherals (0x40000000, 128 MiB) – read + write, device memory, no execute.

Attribute indirection table:

  • MAIR0[0] = 0xFF (Normal inner + outer write-back / write-alloc).
  • MAIR0[1] = 0x44 (Normal non-cacheable).
  • MAIR0[2] = 0x04 (Device-nGnRE).

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.

Enumerator
k_ra8_rbar_attr_ro_x 

AP=RO, SH=none, XN=0.

k_ra8_rbar_attr_rw_xn 

AP=RW, SH=none, XN=1.

k_ra8_rbar_attr_device_rw 

AP=RW, SH=outer sh, XN=1, MAIR idx = device.

k_ra8_mpu_rlar_enable 

RA8 MPU rlar enable.

Definition at line 364 of file system_init.c.

◆ anonymous enum

anonymous enum : uint32_t
Enumerator
k_ra8_mpu_mram_base 

1 MiB MRAM code region.

k_ra8_mpu_mram_limit 

RA8 MPU MRAM limit.

k_ra8_mpu_sram_base 

2 MiB ECC SRAM region.

k_ra8_mpu_sram_limit 

RA8 MPU SRAM limit.

k_ra8_mpu_sdram_base 

64 MiB external SDRAM.

k_ra8_mpu_sdram_limit 

RA8 MPU SDRAM limit.

k_ra8_mpu_peri_base 

Peripheral bus window base.

k_ra8_mpu_peri_limit 

RA8 MPU peri limit.

Definition at line 374 of file system_init.c.

◆ ra8_core_addr_t

enum ra8_core_addr_t : uintptr_t
Enumerator
k_ra8_scb_vtor_addr 

Vector table offset.

k_ra8_scb_ccr_addr 

Configuration control.

k_ra8_scb_shcsr_addr 

Handler control/state.

k_ra8_scb_cpacr_addr 

Coprocessor access.

k_ra8_scb_nsacr_addr 

Non-secure access.

k_ra8_scb_iciallu 

Invalidate I-cache.

k_ra8_scb_dciallu 

Invalidate D-cache.

k_ra8_scb_csselr 

Cache selector.

k_ra8_scb_ccsidr 

Cache size ID.

k_ra8_scb_dcisw 

D-cache set/way.

k_ra8_fpu_fpccr_addr 

FPU context control.

k_ra8_nvic_aircr 

Interrupt/reset control.

k_ra8_mpu_type_addr 

MPU type.

k_ra8_mpu_ctrl_addr 

MPU control.

k_ra8_mpu_rnr_addr 

MPU region number.

k_ra8_mpu_rbar_addr 

MPU region base.

k_ra8_mpu_rlar_addr 

MPU region limit.

k_ra8_mpu_mair0_addr 

MPU attributes 0.

k_ra8_mpu_mair1_addr 

MPU attributes 1.

Definition at line 55 of file system_init.c.

Function Documentation

◆ internal_disable_irq()

void internal_disable_irq ( void )
inlinestatic

Mask configurable interrupts during early core initialization.

Emits cpsid i on the target before any driver state exists; off-target builds retain the call structure without target assembly.

Precondition
Called in privileged mode before application interrupt enablement.
The caller accepts that interrupts remain masked on return.
Postcondition
Target PRIMASK prevents configurable interrupt delivery.
Off-target builds perform no instruction.
Note
The application explicitly enables interrupts after drivers are ready.
Since
0.1.0

Definition at line 171 of file system_init.c.

References RA8_INTERNAL.

◆ internal_dsb()

void internal_dsb ( void )
inlinestatic

Complete outstanding explicit memory accesses on the target.

Emits a full-system DSB on ARM builds and retains an empty, compile-checkable body for off-target builds.

Precondition
Called from privileged early-boot code.
No C runtime state is required.
Postcondition
Target execution passes a full-system data synchronization barrier.
Off-target builds perform no instruction.
Note
The compiler memory clobber also prevents reordering across the barrier.
Since
0.1.0

Definition at line 134 of file system_init.c.

References RA8_INTERNAL.

◆ internal_enable_branch_predictor()

void internal_enable_branch_predictor ( void )
static

Enable branch-target prediction (CCR.BP on Cortex-M85).

Precondition
Called during privileged core initialization.
CCR is readable and writable in the current security state.
Postcondition
CCR.BP is set and the transition is synchronized.
Existing unrelated CCR bits are preserved.
Note
The build currently references this helper without invoking it.
Since
0.1.0

< RA8 ccr bp.

Definition at line 309 of file system_init.c.

References internal_dsb(), internal_isb(), internal_read32(), internal_write32(), k_ra8_scb_ccr_addr, and RA8_INTERNAL.

◆ internal_enable_dcache()

void internal_enable_dcache ( void )
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.

Precondition
Boot ROM has left all data-cache lines invalid.
Core cache control registers are accessible.
Postcondition
CCR.DC is set and the transition is synchronized.
Existing unrelated CCR bits are preserved.
Note
This shortcut is valid only under the documented boot-ROM invariant.
Since
0.1.0

< RA8 ccr dc.

Definition at line 290 of file system_init.c.

References internal_dsb(), internal_isb(), internal_read32(), internal_write32(), k_ra8_scb_ccr_addr, and RA8_INTERNAL.

◆ internal_enable_fpu()

void internal_enable_fpu ( void )
static

Grant full access to CP10 / CP11 (the FPU coprocessors).

Sets both CPACR access fields and synchronizes the processor before subsequent floating-point instructions can execute.

Precondition
Called from privileged early-boot context.
CPACR is accessible in the current security state.
Postcondition
CP10 and CP11 allow full privileged and unprivileged access.
DSB and ISB make the permission change effective before return.
Note
Existing unrelated CPACR fields are preserved.
Since
0.1.0

< RA8 cpacr cp10 cp11 full access.

Definition at line 214 of file system_init.c.

References internal_dsb(), internal_isb(), internal_read32(), internal_write32(), k_ra8_scb_cpacr_addr, and RA8_INTERNAL.

◆ internal_enable_fpu_lazy_stack()

void internal_enable_fpu_lazy_stack ( void )
static

Turn on FPU lazy stacking (FPCCR.LSPEN = 1, ASPEN = 1).

Preserves existing FPCCR state while enabling automatic and lazy floating-point context preservation for exception entry.

Precondition
FPU coprocessor access has already been enabled.
FPCCR is accessible in the current security state.
Postcondition
FPCCR.ASPEN and FPCCR.LSPEN are set.
Unrelated FPCCR bits retain their prior values.
Note
No floating-point state is eagerly saved by this helper.
Since
0.1.0

< RA8 fpccr lspen.

< RA8 fpccr aspen.

Definition at line 237 of file system_init.c.

References internal_read32(), internal_write32(), k_ra8_fpu_fpccr_addr, and RA8_INTERNAL.

◆ internal_enable_icache()

void internal_enable_icache ( void )
static

Invalidate and enable the Cortex-M85 I-cache.

Invalidates all instruction-cache entries, sets CCR.IC, and uses architectural barriers around the transition.

Precondition
Called before normal application execution begins.
Core cache-maintenance registers are accessible.
Postcondition
The instruction cache is enabled with no stale entries retained.
Subsequent instruction fetches observe the enabled cache state.
Note
The build currently references this helper without invoking it.
Since
0.1.0

< RA8 ccr ic.

Definition at line 259 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.

◆ internal_isb()

void internal_isb ( void )
inlinestatic

Flush the target instruction pipeline after a control-state change.

Emits a full-system ISB on ARM builds and retains an empty, compile-checkable body for off-target builds.

Precondition
Called after a write that requires an instruction synchronization barrier.
No C runtime state is required.
Postcondition
Target execution observes subsequent instructions in the new context.
Off-target builds perform no instruction.
Note
The compiler memory clobber prevents motion across the barrier.
Since
0.1.0

Definition at line 153 of file system_init.c.

References RA8_INTERNAL.

◆ internal_mpu_init()

void internal_mpu_init ( void )
static

Programme and enable the Cortex-M85 core MPU.

Installs the four memory-map regions documented above, programs their MAIR attributes, and enables privileged default mapping.

Precondition
Called in privileged early-boot context with interrupts masked.
No concurrent agent is modifying the core MPU registers.
Postcondition
MRAM, SRAM, SDRAM, and peripheral regions have their intended access policy.
MPU_CTRL.ENABLE and MPU_CTRL.PRIVDEFENA are set after synchronization.
Note
The build currently references this helper without invoking it.
Since
0.1.0

< RA8 MPU control enable.

< RA8 MPU control privdefena.

< RA8 mair0 default.

Definition at line 417 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.

◆ internal_mpu_set_region()

void internal_mpu_set_region ( uint32_t region,
uint32_t base_attr,
uint32_t limit_enable )
static

Program a single MPU region via RNR/RBAR/RLAR.

Parameters
[in]regionMPU region number to select.
[in]base_attrEncoded RBAR base address and access attributes.
[in]limit_enableEncoded RLAR limit, MAIR index, and enable bit.
Precondition
The MPU is disabled or the selected region may be safely updated.
Encoded addresses obey the 32-byte PMSAv8 region alignment.
Postcondition
RNR selects region and its RBAR/RLAR values are installed.
Other MPU regions are unchanged.
Note
Callers perform any barrier sequence required after the region set.
Since
0.1.0

Definition at line 398 of file system_init.c.

References internal_write32(), k_ra8_mpu_rbar_addr, k_ra8_mpu_rlar_addr, and k_ra8_mpu_rnr_addr.

◆ internal_read32()

uint32_t internal_read32 ( uintptr_t addr)
inlinestatic

Read one 32-bit core register through a volatile MMIO access.

Performs the minimal width-specific access used by the remaining early-boot helpers without depending on initialized runtime state.

Parameters
[in]addrAligned register address in the core peripheral window.
Returns
Register value observed by the processor.
Return values
0x00000000..0xFFFFFFFFExact 32-bit value returned by the register.
Precondition
addr is readable and aligned to four bytes.
Core-register access is permitted in the current security state.
Postcondition
Exactly one volatile 32-bit read has occurred.
No software-visible state other than the returned value is changed.
Note
Hardware read side effects, if any, are defined by the selected register.
Since
0.1.0

Definition at line 99 of file system_init.c.

References RA8_INTERNAL.

◆ internal_set_priority_grouping()

void internal_set_priority_grouping ( void )
static

Set NVIC priority grouping to 4 preempt bits / 0 sub-priority.

Writes AIRCR with its mandatory key and the firmware's selected PRIGROUP encoding.

Precondition
Configurable interrupts are masked.
AIRCR is writable from the current privileged security state.
Postcondition
AIRCR.PRIGROUP contains the four-preemption-bit configuration.
Interrupt priorities can be assigned under that grouping model.
Note
The write intentionally supplies the VECTKEY authorization value.
Since
0.1.0

< Required write key.

< PRIGROUP = 3 -> 4 bits.

Definition at line 330 of file system_init.c.

References internal_write32(), k_ra8_nvic_aircr, and RA8_INTERNAL.

◆ internal_set_vtor()

void internal_set_vtor ( void )
static

Point VTOR at the physical vector table base.

Writes the linker-provided vector-table address before any interrupt can be accepted by the application.

Precondition
g_ra8_vector_table_start is aligned as required by Cortex-M85 VTOR.
Configurable interrupts remain masked.
Postcondition
VTOR names the firmware's linked vector table.
Later exception entry resolves through that table.
Note
This helper touches only core MMIO and is safe before .data initialization.
Since
0.1.0

Definition at line 195 of file system_init.c.

References g_ra8_vector_table_start, internal_write32(), k_ra8_scb_vtor_addr, and RA8_INTERNAL.

◆ internal_write32()

void internal_write32 ( uintptr_t addr,
uint32_t value )
inlinestatic

Write one 32-bit value to a core register.

Performs the minimal width-specific access used by early boot and leaves ordering decisions to the helper that owns the register.

Parameters
[in]addrAligned register address in the core peripheral window.
[in]valueValue to store.
Precondition
addr is writable and aligned to four bytes.
Core-register access is permitted in the current security state.
Postcondition
Exactly one volatile 32-bit write has occurred.
Register-defined side effects may be visible to the processor.
Note
Callers add architectural barriers when a register requires them.
Since
0.1.0

Definition at line 117 of file system_init.c.

References RA8_INTERNAL.

◆ SystemInit()

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.

Precondition
The CPU is at the reset vector with interrupts masked.
.data has not been copied and .bss has not been zeroed.
Postcondition
The clock tree, cache and memory controller are configured.
It is safe for Reset_Handler to initialise RAM and call main.
Note
Not thread-safe; single-threaded reset context only.
Warning
Must not read or write any static that startup has yet to initialise – at this point they hold whatever SRAM held.
See also
Default_Handler()
Since
0.1.0

Definition at line 459 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_mpu_init(), internal_set_priority_grouping(), internal_set_vtor(), and ra8_trustzone_init().

Variable Documentation

◆ g_ra8_ls_stack_top

uint32_t g_ra8_ls_stack_top
extern

◆ g_ra8_vector_table_start

const uint32_t g_ra8_vector_table_start[]
extern

Definition at line 294 of file vector_table.c.