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

Emulated memory map implementation (see emu_memmap.h). More...

#include "emu_memmap.h"
#include <errno.h>
#include <sys/mman.h>
#include "emu_console.h"
#include "emu_host_io_internal.h"
#include "emu_mmio.h"
Include dependency graph for emu_memmap.c:

Go to the source code of this file.

Data Structures

struct  aliased_window_t
 One guest window that resolves onto a shared host aperture. More...

Macros

#define MAP_ANONYMOUS   MAP_ANON
 Portable spelling of the anonymous-mapping flag.

Enumerations

enum  ospi_xip_map_t : uint64_t {
  k_ospi_xip_base = 0x80000000UL ,
  k_ospi_ns_base = 0x90000000UL
}
enum  tsn_cal_seed_t : uint32_t {
  k_tsn_cal_addr = 0x02C1EDA0U ,
  k_tsn_cal_tscdr = 3000U ,
  k_tsn_cal_tscdr2 = 1000U
}
enum  backing_index_t : size_t {
  k_backing_sram = 0U ,
  k_backing_sdram = 1U ,
  k_backing_ospi = 2U
}
 Identity of each shared aperture within a workspace. More...
enum  backing_geometry_t : uint64_t {
  k_sram_size = 0x001D4000UL ,
  k_sdram_size = 0x04000000UL ,
  k_ospi_size = 0x04000000UL ,
  k_ns_sram2_offset = 0x00100000UL ,
  k_ns_sram2_size = 0x00080000UL ,
  k_logical_bytes = k_sram_size + k_sdram_size + k_ospi_size
}
 Exact logical extents of the three shared apertures. More...
enum  mmap_argument_t : int {
  k_mmap_no_fd = -1 ,
  k_mmap_no_offset = 0
}
 Fixed arguments for an anonymous host aperture mapping. More...

Functions

static RA8_INTERNAL emu_memmap_result_t internal_result (emu_memmap_status_t status, int os_error)
 Construct one exact lifecycle result.
static RA8_INTERNAL uint8_t * internal_window_host (const emu_memmap_workspace_t *workspace, uint64_t base, uint64_t size)
 Resolve a guest region base to its shared host aperture address.
static RA8_INTERNAL bool internal_backing_open (uint64_t size, emu_memmap_backing_t *backing)
 Acquire one zero-filled, lazily-committed host aperture mapping.
static RA8_INTERNAL void internal_backings_close (emu_memmap_workspace_t *workspace)
 Release every acquired aperture mapping in a workspace.
static RA8_INTERNAL void internal_seed_tsn (uc_engine *uc)
 Seed deterministic factory TSN calibration words.
static RA8_INTERNAL bool internal_map_periph_mmio (uc_engine *uc)
 Map the Secure peripheral window and its IDAU bit[28] NS alias.
static RA8_INTERNAL bool internal_map_regions (const emu_memmap_workspace_t *workspace, uc_engine *uc)
 Map every guest region into one engine, sharing the apertures.
emu_memmap_result_t emu_memmap_requirements (void)
 Report the immutable aliased-aperture backing geometry.
emu_memmap_result_t emu_memmap_open (emu_memmap_workspace_t *workspace)
 Create three independent, lazily-committed host aperture mappings.
emu_memmap_result_t emu_memmap_attach (emu_memmap_workspace_t *workspace, uc_engine *uc)
 Map one Unicorn engine onto the shared aperture backing.
bool emu_memmap_detach (emu_memmap_workspace_t *workspace, uc_engine *uc)
 Remove one engine binding before closing that Unicorn engine.
bool emu_memmap_close (emu_memmap_workspace_t *workspace)
 Release every host aperture mapping after all engines detached.
const mem_region_temu_memmap_regions (uint32_t *count)
 Implementation of emu_memmap_regions() – static table access.
uint64_t emu_memmap_mram_base (void)
 Implementation of emu_memmap_mram_base() – named MRAM lookup.

Variables

static const mem_region_t s_regions []

Detailed Description

Emulated memory map implementation (see emu_memmap.h).

Keeps SRAM, SDRAM and OSPI bytes in three workspace-owned host mappings. Every attached engine binds the Secure aperture and its IDAU bit[28] Non-secure alias onto the SAME host pages with uc_mem_map_ptr, so Secure/Non-secure coherence and cpu0/cpu1 coherence are structural: a guest store stays on the translator's fast path and costs nothing beyond the store itself. All other ordinary regions remain private Unicorn mappings.

Since
0.1.0

Definition in file emu_memmap.c.

Macro Definition Documentation

◆ MAP_ANONYMOUS

#define MAP_ANONYMOUS   MAP_ANON

Portable spelling of the anonymous-mapping flag.

Build-configuration alias only: macOS SDKs that predate the MAP_ANONYMOUS spelling supply the same flag as MAP_ANON. Defined only when the platform header did not, so a host that has the standard name keeps it.

Note
Not a numeric constant of this module's own; it names a platform flag, which is why it is a macro rather than a typed enum.
Since
0.1.0

Definition at line 37 of file emu_memmap.c.

Referenced by internal_backing_open().

Enumeration Type Documentation

◆ backing_geometry_t

enum backing_geometry_t : uint64_t

Exact logical extents of the three shared apertures.

Enumerator
k_sram_size 

Exact on-chip SRAM extent.

k_sdram_size 

Exact external SDRAM extent.

k_ospi_size 

Exact OSPI XIP extent.

k_ns_sram2_offset 

SRAM offset the SRAM2 alias starts at.

k_ns_sram2_size 

SRAM2 alias extent.

k_logical_bytes 

Total logical bytes the three shared apertures span.

Definition at line 169 of file emu_memmap.c.

◆ backing_index_t

enum backing_index_t : size_t

Identity of each shared aperture within a workspace.

Enumerator
k_backing_sram 

On-chip SRAM aperture index.

k_backing_sdram 

External SDRAM aperture index.

k_backing_ospi 

OSPI XIP aperture index.

Definition at line 162 of file emu_memmap.c.

◆ mmap_argument_t

enum mmap_argument_t : int

Fixed arguments for an anonymous host aperture mapping.

Enumerator
k_mmap_no_fd 

Anonymous mappings are backed by no descriptor.

k_mmap_no_offset 

Anonymous mappings start at offset zero.

Definition at line 180 of file emu_memmap.c.

◆ ospi_xip_map_t

enum ospi_xip_map_t : uint64_t
Enumerator
k_ospi_xip_base 

OSPI XIP window: Secure physical base.

k_ospi_ns_base 

OSPI XIP window: NS alias (IDAU bit[28]=1).

Definition at line 140 of file emu_memmap.c.

◆ tsn_cal_seed_t

enum tsn_cal_seed_t : uint32_t
Enumerator
k_tsn_cal_addr 

TSCDR (+0x00), TSCDR2 (+0x04).

k_tsn_cal_tscdr 

12-bit calibration code at +125 degC.

k_tsn_cal_tscdr2 

12-bit calibration code at -40 degC.

Definition at line 155 of file emu_memmap.c.

Function Documentation

◆ emu_memmap_attach()

emu_memmap_result_t emu_memmap_attach ( emu_memmap_workspace_t * workspace,
uc_engine * uc )
nodiscard

Map one Unicorn engine onto the shared aperture backing.

Maps every RA8D2 region into uc. The six aliased windows – the SRAM/SRAM2, SDRAM and OSPI Secure views and their IDAU bit[28] Non-secure aliases – are bound with uc_mem_map_ptr onto the workspace's host pages, so a store through any of them is immediately visible through every other one and in every other engine bound to the same workspace, at no per-store cost. Every other region is an ordinary private Unicorn mapping.

Parameters
[in,out]workspaceOpen aperture backing.
[in,out]ucFresh Unicorn engine.
Returns
Lifecycle result with the aperture geometry.
Return values
k_emu_memmap_okThe engine is mapped and the binding recorded.
k_emu_memmap_invalidA null or unopened argument was supplied.
k_emu_memmap_unicornA region map or the MMIO window install failed.
Precondition
uc has no guest memory mappings.
workspace is open and has a free binding slot.
Postcondition
Success makes the shared apertures coherent with every bound engine.
Success records a binding that emu_memmap_close refuses to outlive.
Note
The caller still owns uc and must detach before closing it.
Since
0.1.0

Definition at line 463 of file emu_memmap.c.

References emu_memmap_binding_t::active, emu_memmap_workspace::bindings, internal_map_periph_mmio(), internal_map_regions(), internal_result(), internal_seed_tsn(), k_emu_memmap_binding_count, k_emu_memmap_invalid, k_emu_memmap_ok, k_emu_memmap_unicorn, and emu_memmap_workspace::open.

Referenced by internal_cpu1_engine_init(), and internal_main_open_engine().

◆ emu_memmap_close()

bool emu_memmap_close ( emu_memmap_workspace_t * workspace)

Release every host aperture mapping after all engines detached.

Refuses while any binding is active, because a bound engine holds uc_mem_map_ptr references into the very pages this call unmaps.

Parameters
[in,out]workspaceOpen or already-closed caller workspace.
Returns
True when closed or already closed; false while a binding is live.
Return values
trueEvery aperture mapping was released, or none was owned.
falseA binding is still active and nothing was released.
Precondition
workspace is non-null.
Every engine attached to workspace was detached first.
Postcondition
Success clears every backing pointer and the open flag.
Failure preserves the workspace so its engines can be detached.
Note
Calling this while an engine is still bound would strand that engine on unmapped host memory, so the refusal is load-bearing, not defensive.
Since
0.1.0

Definition at line 500 of file emu_memmap.c.

References emu_memmap_binding_t::active, emu_memmap_workspace::bindings, internal_backings_close(), k_emu_memmap_binding_count, and emu_memmap_workspace::open.

Referenced by internal_main_load_images(), main(), and priv_run_cleanup().

◆ emu_memmap_detach()

bool emu_memmap_detach ( emu_memmap_workspace_t * workspace,
uc_engine * uc )

Remove one engine binding before closing that Unicorn engine.

Releases the binding slot uc occupies. The engine keeps its mappings until the caller closes it, so detach must happen before emu_memmap_close unmaps the host pages those mappings point at.

Parameters
[in,out]workspaceOpen backing containing the binding.
[in,out]ucLive bound engine.
Returns
Whether exactly one active binding was removed.
Return values
trueThe binding for uc was found and released.
falseA null argument, or uc was not bound.
Precondition
workspace and uc are non-null.
The call executes on the emulator's single owning thread.
Postcondition
Success frees the binding slot for a later attach.
Ownership of caller-supplied storage is unchanged.
Note
The caller still owns and must close uc.
Since
0.1.0

Definition at line 486 of file emu_memmap.c.

References emu_memmap_binding_t::active, emu_memmap_workspace::bindings, k_emu_memmap_binding_count, and emu_memmap_binding_t::uc.

Referenced by emu_cpu1_close(), internal_cpu1_engine_init(), internal_main_load_images(), and priv_run_cleanup().

◆ emu_memmap_mram_base()

uint64_t emu_memmap_mram_base ( void )

Implementation of emu_memmap_mram_base() – named MRAM lookup.

Return the MRAM boot-vector base.

Definition at line 523 of file emu_memmap.c.

References s_regions.

Referenced by internal_main_reset_vector(), internal_main_run_loaded(), internal_on_intr(), and warm_reboot().

◆ emu_memmap_open()

emu_memmap_result_t emu_memmap_open ( emu_memmap_workspace_t * workspace)
nodiscard

Create three independent, lazily-committed host aperture mappings.

Acquires one page-aligned zero-filled host mapping per shared aperture (SRAM, SDRAM, OSPI). The mappings are anonymous, so the 130 MiB of logical guest memory costs resident memory only for the pages the firmware actually touches. Distinct workspaces own distinct mappings and never share bytes.

Parameters
[out]workspaceReceives the owned mappings on success.
Returns
Exact geometry and completion status.
Return values
k_emu_memmap_okEvery aperture mapping was acquired.
k_emu_memmap_invalidworkspace was null or already open.
k_emu_memmap_backingA host mapping failed; os_error holds errno.
Precondition
workspace is non-null.
workspace is not already open; re-opening one is rejected rather than leaking the apertures it already owns.
Postcondition
Success leaves every aperture zero-filled and no page resident.
Failure acquires nothing and leaves workspace untouched.
Note
Distinct workspaces own independent mappings and state.
Since
0.1.0

Definition at line 439 of file emu_memmap.c.

References emu_memmap_workspace::backings, internal_backing_open(), internal_backings_close(), internal_result(), k_backing_ospi, k_backing_sdram, k_backing_sram, k_emu_memmap_backing, k_emu_memmap_backing_count, k_emu_memmap_invalid, k_emu_memmap_ok, k_ospi_size, k_sdram_size, k_sram_size, and emu_memmap_workspace::open.

Referenced by internal_main_open_memory().

◆ emu_memmap_regions()

const mem_region_t * emu_memmap_regions ( uint32_t * count)

Implementation of emu_memmap_regions() – static table access.

Return the static emulated memory-region table.

Definition at line 516 of file emu_memmap.c.

References s_regions.

◆ emu_memmap_requirements()

emu_memmap_result_t emu_memmap_requirements ( void )
nodiscard

Report the immutable aliased-aperture backing geometry.

Names the exact number of logical guest bytes the three shared apertures span, before any workspace or engine exists, so a caller can report the emulated memory footprint without opening anything.

Returns
Successful immutable requirement values.
Return values
valueA result whose status is always k_emu_memmap_ok.
Precondition
No precondition: the reported geometry is a compile-time constant.
The call executes on the emulator's single owning thread.
Postcondition
Reports 136134656 logical aperture bytes.
No workspace, mapping, or engine state changes.
Note
Pure and safe to call before any engine or workspace exists.
Since
0.1.0

Definition at line 434 of file emu_memmap.c.

References internal_result(), and k_emu_memmap_ok.

◆ internal_backing_open()

RA8_INTERNAL bool internal_backing_open ( uint64_t size,
emu_memmap_backing_t * backing )
static

Acquire one zero-filled, lazily-committed host aperture mapping.

Uses an anonymous mapping rather than an allocator: the pages are page-aligned (which uc_mem_map_ptr requires), start zeroed, and cost resident memory only once the firmware touches them, so mapping 130 MiB of guest memory does not cost 130 MiB of host memory.

Parameters
[in]sizeExact aperture byte length.
[out]backingReceives the acquired mapping.
Returns
Whether the aperture mapping was acquired.
Return values
truebacking holds a live page-aligned host mapping.
falseThe host refused the mapping; errno describes why.
Precondition
backing is non-null.
size is a non-zero multiple of k_page_size.
Postcondition
Success leaves every aperture byte zero and no page resident.
Failure leaves backing untouched.
Note
The operation is synchronous and does not transfer heap ownership.
Since
0.1.0

Definition at line 289 of file emu_memmap.c.

References k_mmap_no_fd, k_mmap_no_offset, MAP_ANONYMOUS, and RA8_INTERNAL.

Referenced by emu_memmap_open().

◆ internal_backings_close()

RA8_INTERNAL void internal_backings_close ( emu_memmap_workspace_t * workspace)
static

Release every acquired aperture mapping in a workspace.

Unmaps each live aperture and clears its record, so a partially acquired workspace and a fully closed one are released by the same code.

Parameters
[in,out]workspaceCaller-owned workspace whose apertures are released.
Precondition
workspace is non-null.
No engine binding still references these host pages.
Postcondition
Every backing pointer is nullptr and every size is zero.
Ownership of caller-supplied storage is unchanged.
Note
The operation is synchronous and does not transfer heap ownership.
Since
0.1.0

Definition at line 316 of file emu_memmap.c.

References emu_memmap_workspace::backings, emu_memmap_backing_t::host, k_emu_memmap_backing_count, RA8_INTERNAL, and emu_memmap_backing_t::size.

Referenced by emu_memmap_close(), and emu_memmap_open().

◆ internal_map_periph_mmio()

RA8_INTERNAL bool internal_map_periph_mmio ( uc_engine * uc)
static

Map the Secure peripheral window and its IDAU bit[28] NS alias.

Installs the modelled peripheral callbacks over 0x40000000 and over the Non-secure alias at 0x50000000, so an NS image reaches the same models.

Parameters
[in,out]ucUnicorn engine receiving the MMIO windows.
Returns
Whether both windows were installed.
Return values
trueBoth the Secure and Non-secure peripheral windows are live.
falseUnicorn refused a window; a diagnostic was written to stderr.
Precondition
uc is a fresh engine with no peripheral window installed.
The call executes on the emulator's single owning thread.
Postcondition
Success routes every peripheral access through the board models.
Ownership of caller-supplied storage is unchanged.
Note
The operation is synchronous and does not transfer heap ownership.
Since
0.1.0

Definition at line 363 of file emu_memmap.c.

References k_ns_alias_bit, k_periph_base, k_periph_size, mmio_read(), mmio_write(), priv_emu_io_errf(), and RA8_INTERNAL.

Referenced by emu_memmap_attach().

◆ internal_map_regions()

RA8_INTERNAL bool internal_map_regions ( const emu_memmap_workspace_t * workspace,
uc_engine * uc )
static

Map every guest region into one engine, sharing the apertures.

Each region either resolves to a shared host aperture – and is bound with uc_mem_map_ptr so it and its alias are one state – or becomes an ordinary private Unicorn mapping. Because the shared pages already hold the workspace's bytes, a freshly attached engine observes everything written before it existed with no replay step.

Parameters
[in]workspaceOpen workspace owning the aperture mappings.
[in,out]ucUnicorn engine receiving the regions.
Returns
Whether every region was mapped.
Return values
trueThe engine carries the complete RA8D2 region map.
falseA region map failed; a diagnostic was written to stderr.
Precondition
workspace is open with every aperture acquired.
uc has no guest memory mappings.
Postcondition
Success makes the six aliased windows share the workspace pages.
Ownership of caller-supplied storage is unchanged.
Note
The operation is synchronous and does not transfer heap ownership.
Since
0.1.0

Definition at line 415 of file emu_memmap.c.

References mem_region_t::base, internal_window_host(), mem_region_t::name, priv_emu_io_errf(), RA8_INTERNAL, s_regions, and mem_region_t::size.

Referenced by emu_memmap_attach().

◆ internal_result()

RA8_INTERNAL emu_memmap_result_t internal_result ( emu_memmap_status_t status,
int os_error )
static

Construct one exact lifecycle result.

Construct one exact lifecycle result; every lifecycle entry point reports the same immutable aperture geometry alongside its status so a caller never has to correlate two calls.

Parameters
[in]statusStatus value published by the operation.
[in]os_errorHost error code captured on failure, or zero.
Returns
The result produced by the emu memmap model.
Return values
valueThe operation-specific result value.
Precondition
Arguments satisfy the ranges documented for result.
The call executes on the emulator's single owning thread.
Postcondition
State changes remain confined to the returned value.
Ownership of caller-supplied storage is unchanged.
Note
The operation is synchronous and does not transfer heap ownership.
Since
0.1.0

Definition at line 218 of file emu_memmap.c.

References k_logical_bytes, and RA8_INTERNAL.

Referenced by emu_memmap_attach(), emu_memmap_open(), and emu_memmap_requirements().

◆ internal_seed_tsn()

RA8_INTERNAL void internal_seed_tsn ( uc_engine * uc)
static

Seed deterministic factory TSN calibration words.

Writes the two-point trim pair into the engine's TRIM page (see tsn_cal_seed_t). The page is ordinary private Unicorn memory, so the seed is applied per engine at attach time.

Parameters
[in,out]ucUnicorn engine whose TRIM page receives the seed.
Precondition
The TRIM region covering k_tsn_cal_addr is mapped on uc.
The call executes on the emulator's single owning thread.
Postcondition
uc holds TSCDR at k_tsn_cal_addr and TSCDR2 at the next word.
No other engine or workspace state changes.
Note
The operation is synchronous and does not transfer heap ownership.
Since
0.1.0

Definition at line 340 of file emu_memmap.c.

References emu_mem_write(), k_tsn_cal_addr, k_tsn_cal_tscdr, k_tsn_cal_tscdr2, and RA8_INTERNAL.

Referenced by emu_memmap_attach().

◆ internal_window_host()

RA8_INTERNAL uint8_t * internal_window_host ( const emu_memmap_workspace_t * workspace,
uint64_t base,
uint64_t size )
static

Resolve a guest region base to its shared host aperture address.

Looks the region up in the aliased-window table and returns the host address the window starts at, after proving the whole window fits inside the aperture. Any region that is not an aliased window returns nullptr and is mapped as ordinary private Unicorn memory.

Parameters
[in]workspaceOpen workspace owning the aperture mappings.
[in]baseGuest base address of the region being mapped.
[in]sizeGuest byte length of the region being mapped.
Returns
The host address backing the window.
Return values
nullptrThe region is not shared, or it would overrun its aperture.
Precondition
workspace is open and every aperture mapping is acquired.
The call executes on the emulator's single owning thread.
Postcondition
No workspace, mapping, or engine state changes.
Ownership of caller-supplied storage is unchanged.
Note
The operation is synchronous and does not transfer heap ownership.
Since
0.1.0

Every guest window bound to shared host pages, Secure and NS alike.

Definition at line 244 of file emu_memmap.c.

References aliased_window_t::backing, emu_memmap_workspace::backings, aliased_window_t::base, emu_memmap_backing_t::host, k_backing_ospi, k_backing_sdram, k_backing_sram, k_ns_sdram_base, k_ns_sram2_base, k_ns_sram2_offset, k_ospi_ns_base, k_ospi_xip_base, k_sdram_base, k_sram_base, aliased_window_t::offset, and emu_memmap_backing_t::size.

Referenced by internal_map_regions().

Variable Documentation

◆ s_regions

const mem_region_t s_regions[]
static
Initial value:
= {
{"ITCM", 0x00000000UL, 0x00010000UL},
{"MRAM", 0x02000000UL, 0x00100000UL},
{"TRIM", 0x02C1E000UL, 0x00001000UL},
{"OFS_CFG", 0x02C9F000UL, 0x00001000UL},
{"OFS_OTP", 0x02E07000UL, 0x00011000UL},
{"DTCM", 0x20000000UL, 0x00010000UL},
{"SRAM", 0x22000000UL, 0x001D4000UL},
{"NS_SRAM2", 0x32100000UL, 0x00080000UL},
{"SDRAM", 0x68000000UL, 0x04000000UL},
{"NS_SDRAM", 0x78000000UL, 0x04000000UL},
{"OSPI", 0x80000000UL, 0x04000000UL},
{"NS_OSPI", 0x90000000UL, 0x04000000UL},
{"PPB", 0xE0000000UL, 0x00100000UL},
}

Definition at line 41 of file emu_memmap.c.