Expand opt-in DMA arenas without aliasing CPU BIOS addresses

This commit is contained in:
Matthew Stanley
2026-09-11 23:03:40 -07:00
parent 2bcc7ae0ba
commit b4ea4c37e9
2 changed files with 40 additions and 14 deletions
+11 -6
View File
@@ -9,19 +9,24 @@ extern "C" {
/*
* GPU linked-list tags carry only 24 address bits. Trusted enhancements that
* need a larger primitive arena use this otherwise-unmapped 1 MiB aperture so
* need a larger primitive arena use this otherwise-unmapped 4 MiB aperture so
* their CPU pointers survive the tag truncation. Nothing is mapped until an
* enhancement explicitly allocates from it.
*/
#define PSX_MOD_GPU_DMA_APERTURE_BASE 0x00F00000u
#define PSX_MOD_GPU_DMA_APERTURE_SIZE (1u * 1024u * 1024u)
#define PSX_MOD_GPU_DMA_GUEST_BASE 0x80F00000u
#define PSX_MOD_GPU_DMA_APERTURE_BASE 0x00C00000u
#define PSX_MOD_GPU_DMA_APERTURE_SIZE (4u * 1024u * 1024u)
#define PSX_MOD_GPU_DMA_GUEST_BASE 0x80C00000u
static inline int psx_mod_gpu_dma_aperture_offset_for(
uint32_t address, uint32_t width, uint32_t used, uint32_t *offset) {
uint32_t canonical = address & 0x00FFFFFFu;
/* CPU addresses retain all physical bits after KSEG normalization. The
* BIOS at 0x1FC00000 must never alias the aperture at 0x00C00000.
* DMA callers pass an already-truncated 24-bit tag separately below. */
uint32_t canonical = address & 0x1FFFFFFFu;
uint32_t off;
if (canonical < PSX_MOD_GPU_DMA_APERTURE_BASE) return 0;
if (canonical < PSX_MOD_GPU_DMA_APERTURE_BASE ||
canonical >= 0x01000000u || used > PSX_MOD_GPU_DMA_APERTURE_SIZE)
return 0;
off = canonical - PSX_MOD_GPU_DMA_APERTURE_BASE;
if (off > used || width > used - off) return 0;
if (offset) *offset = off;
+29 -8
View File
@@ -15,29 +15,50 @@ static void check(int condition, const char *name) {
int main(void) {
uint32_t off = 0;
uint32_t base = PSX_MOD_GPU_DMA_APERTURE_BASE;
uint32_t size = PSX_MOD_GPU_DMA_APERTURE_SIZE;
uint32_t aliases[] = {0x1FC00000u, 0x9FC00000u, 0xBFC00000u,
0x1F000000u, 0x9F000000u, 0x1F801810u,
0xBF801810u, 0x1EFFFFFFu};
unsigned i;
check(psx_mod_gpu_dma_resolve_address_for(0x00F01234u, 0u) ==
(0x00F01234u & 0x001FFFFCu),
check(psx_mod_gpu_dma_resolve_address_for(base + 0x1234u, 0u) ==
((base + 0x1234u) & 0x001FFFFCu),
"unallocated aperture preserves retail 2 MiB folding");
check(psx_mod_gpu_dma_resolve_address_for(0x80F01234u, 0x20000u) ==
0x00F01234u,
check(psx_mod_gpu_dma_resolve_address_for(0x80000000u + base + 0x1234u, 0x20000u) ==
base + 0x1234u,
"allocated KSEG0 aperture pointer survives 24-bit DMA");
check(psx_mod_gpu_dma_resolve_address_for(0x00F30000u, 0x20000u) ==
(0x00F30000u & 0x001FFFFCu),
check(psx_mod_gpu_dma_resolve_address_for(base + 0x30000u, 0x20000u) ==
((base + 0x30000u) & 0x001FFFFCu),
"unallocated aperture tail remains folded");
check(psx_mod_gpu_dma_resolve_address_for(0x001ABCDEu, 0x20000u) ==
0x001ABCDCu,
"ordinary main RAM remains word-aligned and unchanged");
check(psx_mod_gpu_dma_aperture_offset_for(
0x00F1FFFCu, 4u, 0x20000u, &off) &&
base + 0x1FFFCu, 4u, 0x20000u, &off) &&
off == 0x1FFFCu,
"last allocated aperture word is accessible");
check(!psx_mod_gpu_dma_aperture_offset_for(
0x00F20000u, 4u, 0x20000u, &off),
base + 0x20000u, 4u, 0x20000u, &off),
"first unallocated aperture word is inaccessible");
check(!psx_mod_gpu_dma_aperture_offset_for(
0x00FFFFFCu, 8u, PSX_MOD_GPU_DMA_APERTURE_SIZE, &off),
"cross-boundary access is rejected");
for (i = 0; i < sizeof(aliases) / sizeof(aliases[0]); ++i)
check(!psx_mod_gpu_dma_aperture_offset_for(aliases[i], 4u, size, &off),
"CPU BIOS/expansion/MMIO addresses cannot alias DMA storage");
check(psx_mod_gpu_dma_aperture_offset_for(0xA0000000u + base, 4u, size, &off)
&& off == 0u, "KSEG1 CPU aperture alias resolves correctly");
check(psx_mod_gpu_dma_aperture_offset_for(base + size - 4u, 4u, size, &off)
&& off == size - 4u, "last word of full 4 MiB aperture is accessible");
check(!psx_mod_gpu_dma_aperture_offset_for(base - 4u, 4u, size, &off),
"word before aperture is rejected");
check(!psx_mod_gpu_dma_aperture_offset_for(base + size, 4u, size, &off),
"word after aperture is rejected");
check(!psx_mod_gpu_dma_aperture_offset_for(base, 4u, size + 4u, &off),
"invalid allocated size is rejected");
check(psx_mod_gpu_dma_resolve_address_for(base + size - 4u, size) ==
base + size - 4u, "full aperture DMA tag keeps its high address bits");
return failures ? 1 : 0;
}