Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
6c09a4c
Started a ThreadX module port for the Cortex-R52, headers first
fdesbiens Aug 18, 2026
25f7ab0
Added the PMSAv8-R region setup and fault handler for the module port
fdesbiens Aug 18, 2026
2e653cb
Completed the portable half of the R52 module manager sources
fdesbiens Aug 18, 2026
473598f
Programmed MPU regions directly instead of through PRSELR, and moved …
fdesbiens Aug 18, 2026
f1ee258
Added the module scheduler's region switch, with the offsets checked …
fdesbiens Aug 18, 2026
a20def0
Added the abort-vector fault capture, and found three bugs writing it
fdesbiens Aug 18, 2026
1526683
Added the module user-mode entry, the only way a module reaches the k…
fdesbiens Aug 18, 2026
80289e7
Added the supervisor call handler: the privilege boundary itself
fdesbiens Aug 18, 2026
4989b76
Added the module thread stack build, which decides the mode a module …
fdesbiens Aug 18, 2026
601cfd3
Moved module-port threads to SYS mode, which the context paths depend on
fdesbiens Aug 18, 2026
f9630c4
Disabled the port dispatch, and added the module-side library
fdesbiens Aug 18, 2026
d6ed619
Added the module preamble, which checks its own declared size
fdesbiens Aug 18, 2026
96057be
Added a sample module that tests the boundary rather than the API
fdesbiens Aug 18, 2026
c762453
Added the module manager sample, whose expected result is a fault
fdesbiens Aug 18, 2026
572c780
Routed the board's SVC and abort vectors to the module port, when bui…
fdesbiens Aug 18, 2026
2dc72a6
Built the module manager example, and found five ways it can look rig…
fdesbiens Aug 18, 2026
a782765
Built the module as its own image, because one link cannot hold both
fdesbiens Aug 19, 2026
c8c0730
Gave the kernel a window onto the module area, owned by the scheduler
fdesbiens Aug 19, 2026
8fff64d
Moved the scheduler into System mode, and borrowed SVC for the return
fdesbiens Aug 19, 2026
284f92c
Seeded r0 and r1 so the module shell entry has its arguments
fdesbiens Aug 19, 2026
0dfdbb1
Moved the module's kernel gateway out of the kernel's code region
fdesbiens Aug 19, 2026
26e8999
Drove the manager from a thread, and gave it the object pool it needs
fdesbiens Aug 19, 2026
f766806
Stored the preamble's entry points relative to their own words
fdesbiens Aug 19, 2026
9bc9158
Added the silicon run and diagnostic scripts for the module demonstra…
fdesbiens Aug 19, 2026
6d55e55
Made modules relocatable, so one blob runs at any address
fdesbiens Aug 19, 2026
bdbc8a2
Proved the relocation by running the same blob from two addresses
fdesbiens Aug 19, 2026
8c7033e
Fixed the module fault-notify path and covered both abort types
fdesbiens Aug 19, 2026
a7d4865
Masked the shared region's limit to the protection granule
fdesbiens Aug 20, 2026
2099f85
Added the module isolation regression on the Armv8-R AEM FVP
fdesbiens Aug 20, 2026
7a6e368
Added the shared-region regression to both module examples
fdesbiens Aug 20, 2026
8a5ea88
Applied the kernel warning set to the module port, and unified the mo…
fdesbiens Aug 20, 2026
4b6b4f7
Woke the CLZ priority search, which had never once run under GCC
fdesbiens Aug 20, 2026
b60eff1
Documented the CLZ search, and corrected the readme's AP claim
fdesbiens Aug 20, 2026
85ef1f5
Required user mode and memory protection together on the R52 module port
fdesbiens Aug 26, 2026
7db8ecc
Tested the entry pointer, not the thread pointer, for Thumb module state
fdesbiens Aug 31, 2026
af703b3
Rejected empty and wrapping shared-memory grants on the R52 module port
fdesbiens Aug 31, 2026
3dfbe2a
Took the machine-specific paths out of the S32Z280 module harness
fdesbiens Aug 31, 2026
8f1b1ed
Corrected the R52 MPU register-access and region-overlap claims
fdesbiens Aug 31, 2026
18c9f7d
Merge remote-tracking branch 'origin/dev' into pr639-review
fdesbiens Sep 9, 2026
d99d4b4
Gave the module window region a home in the port rather than a board …
fdesbiens Sep 9, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
358 changes: 357 additions & 1 deletion ports/cortex_r52/gnu/example_build/fvp_baser_aemv8r/CMakeLists.txt

Large diffs are not rendered by default.

149 changes: 149 additions & 0 deletions ports/cortex_r52/gnu/example_build/fvp_baser_aemv8r/cache.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
/***************************************************************************
* Copyright (c) 2026 Eclipse ThreadX contributors
*
* This program and the accompanying materials are made available under the
* terms of the MIT License which is available at
* https://opensource.org/licenses/MIT.
*
* AI Disclosure: This file was largely AI-generated by Claude Code (Opus 5).
* The AI-generated portions may be considered public domain (CC0-1.0)
* and not subject to the project's licence. The human contributor has
* reviewed and verified that the code is correct.
*
* SPDX-License-Identifier: MIT and CC0-1.0
**************************************************************************/

/**************************************************************************/
/* */
/* BOARD SUPPORT RELEASE */
/* */
/* cache.c Cortex-R52/GNU */
/* 6.5.2 */
/* AUTHOR */
/* */
/* Frédéric Desbiens, Eclipse Foundation */
/* */
/* DESCRIPTION */
/* */
/* Cache maintenance for a loader that copies code. See cache.h for */
/* why only these three functions exist. */
/* */
/* MISRA C:2012 deviations (justified) */
/* */
/* Directive 4.3 -- cache maintenance and CTR are reachable only */
/* through CP15; every access is encapsulated in a one-line accessor */
/* below and nowhere else in this file. */
/* Rule 11.6 (conversion between a pointer and an integer) -- a cache */
/* maintenance operation takes a virtual address as a register value, */
/* so the conversion is what the instruction requires. */
/* */
/**************************************************************************/

#include "cache.h"

/* The smallest data-cache line in the machine, from CTR.DminLine. Held as a
log2 of the number of 32-bit words, so the byte count is 4 << DminLine.
DminLine and not the L1 geometry: a maintenance-by-address walk has to step
by the smallest line any level implements, or it skips lines in that level. */

#define CTR_DMINLINE_SHIFT 16U
#define CTR_DMINLINE_MASK 0xFUL


/**************************************************************************/
/* CP15 accessors. The only assembly in this file (MISRA C:2012 Dir 4.3).*/
/**************************************************************************/

static unsigned long read_ctr(void)
{
unsigned long value;
__asm__ volatile("mrc p15, 0, %0, c0, c0, 1" : "=r"(value));
return value;
}

static void clean_dcache_line(unsigned long address)
{
__asm__ volatile("mcr p15, 0, %0, c7, c10, 1" :: "r"(address) : "memory");
}

static void invalidate_icache_all_op(void)
{
unsigned long zero = 0UL;
__asm__ volatile("mcr p15, 0, %0, c7, c5, 0" :: "r"(zero) : "memory");
}

static void data_sync_barrier(void)
{
__asm__ volatile("dsb sy" ::: "memory");
}

static void instruction_barrier(void)
{
__asm__ volatile("isb" ::: "memory");
}


/**************************************************************************/
/* cache_dcache_line_bytes */
/**************************************************************************/

unsigned long cache_dcache_line_bytes(void)
{
return 4UL << ((read_ctr() >> CTR_DMINLINE_SHIFT) & CTR_DMINLINE_MASK);
}


/**************************************************************************/
/* cache_clean_range */
/* */
/* Clean by virtual address over [start, start + length). */
/* */
/* The start is rounded DOWN to a line boundary and the walk continues */
/* past the end until the last line containing a requested byte has been */
/* cleaned. Rounding the start up instead would leave the first partial */
/* line dirty, which is the whole failure this exists to prevent and is */
/* invisible whenever the caller happens to be line aligned. */
/**************************************************************************/

void cache_clean_range(const void *start_address, unsigned long length)
{
unsigned long line = cache_dcache_line_bytes();
unsigned long address;
unsigned long end;

if (length == 0UL)
{
return;
}

address = (unsigned long) start_address;
end = address + length;

address &= ~(line - 1UL);

while (address < end)
{
clean_dcache_line(address);
address += line;
}

/* The stores have to be complete before anything fetches from the range. */

data_sync_barrier();
}


/**************************************************************************/
/* cache_invalidate_icache_all */
/**************************************************************************/

void cache_invalidate_icache_all(void)
{
invalidate_icache_all_op();

/* DSB then ISB: the invalidate must complete, and the pipeline must be
flushed of anything fetched before it did. */

data_sync_barrier();
instruction_barrier();
}
72 changes: 72 additions & 0 deletions ports/cortex_r52/gnu/example_build/fvp_baser_aemv8r/cache.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
/***************************************************************************
* Copyright (c) 2026 Eclipse ThreadX contributors
*
* This program and the accompanying materials are made available under the
* terms of the MIT License which is available at
* https://opensource.org/licenses/MIT.
*
* AI Disclosure: This file was largely AI-generated by Claude Code (Opus 5).
* The AI-generated portions may be considered public domain (CC0-1.0)
* and not subject to the project's licence. The human contributor has
* reviewed and verified that the code is correct.
*
* SPDX-License-Identifier: MIT and CC0-1.0
**************************************************************************/

/**************************************************************************/
/* */
/* BOARD SUPPORT RELEASE */
/* */
/* cache.h Cortex-R52/GNU */
/* 6.5.2 */
/* AUTHOR */
/* */
/* Frédéric Desbiens, Eclipse Foundation */
/* */
/* DESCRIPTION */
/* */
/* The cache maintenance a loader owes the instruction side, and */
/* nothing else. */
/* */
/* The S32Z280 board support carries a full cache driver -- enable, */
/* disable, geometry, set/way sweeps -- because silicon bring-up needed */
/* to ask the hardware what it had. None of that is needed here: the */
/* caches are turned on once in mpu_init and never turned off, and the */
/* model's geometry is not in question. What IS needed is the pair of */
/* operations that make copied code executable, so that is all this is. */
/* */
/* Why it is needed at all: the module area is Normal write-back memory, */
/* so a byte copy of module code leaves the bytes in dirty data-cache */
/* lines while the instruction side -- which is not coherent with the */
/* data cache on this core -- fetches whatever main memory still holds. */
/* Cleaning by address range and then invalidating the instruction cache */
/* is what closes that gap. */
/* */
/* By range rather than by set/way, deliberately. A set/way sweep needs */
/* the cache geometry and touches every line in the machine; the loader */
/* knows exactly which bytes it wrote, so the range form is both tighter */
/* and shorter to get right. */
/* */
/**************************************************************************/

#ifndef CACHE_H
#define CACHE_H

/* Clean (write back) the data cache over one address range, so that main
memory holds what the copy wrote. Rounds outwards to cache-line
boundaries; a length of zero does nothing. */

void cache_clean_range(const void *start_address, unsigned long length);

/* Invalidate the whole instruction cache, so no stale line from a previous
image at the same address can be served. Invalidate-all rather than by
range because it is one register write and this runs once per load. */

void cache_invalidate_icache_all(void);

/* Data cache line length in bytes, from CTR.DminLine. Published because the
range walk above depends on it and a caller may want to report it. */

unsigned long cache_dcache_line_bytes(void);

#endif /* CACHE_H */
Loading
Loading