|
| 1 | +/* Memory Protection Abstractions |
| 2 | + * |
| 3 | + * Software abstractions for managing memory protection at different |
| 4 | + * granularities. These structures build upon hardware protection |
| 5 | + * mechanisms (such as RISC-V PMP) to provide flexible, architecture- |
| 6 | + * independent memory isolation. |
| 7 | + */ |
| 8 | + |
| 9 | +#pragma once |
| 10 | + |
| 11 | +#include <types.h> |
| 12 | + |
| 13 | +/* Forward declarations */ |
| 14 | +struct fpage; |
| 15 | +struct as; |
| 16 | + |
| 17 | +/* Flex Page |
| 18 | + * |
| 19 | + * Contiguous physical memory region with hardware-enforced protection. |
| 20 | + * Supports arbitrary base addresses and sizes without alignment constraints. |
| 21 | + */ |
| 22 | +typedef struct fpage { |
| 23 | + struct fpage *as_next; /* Next in address space list */ |
| 24 | + struct fpage *map_next; /* Next in mapping chain */ |
| 25 | + struct fpage *pmp_next; /* Next in PMP queue */ |
| 26 | + uint32_t base; /* Physical base address */ |
| 27 | + uint32_t size; /* Region size */ |
| 28 | + uint32_t rwx; /* R/W/X permission bits */ |
| 29 | + uint32_t pmp_id; /* PMP region index */ |
| 30 | + uint32_t flags; /* Status flags */ |
| 31 | + uint32_t priority; /* Eviction priority */ |
| 32 | + int used; /* Usage counter */ |
| 33 | +} fpage_t; |
| 34 | + |
| 35 | +/* Address Space |
| 36 | + * |
| 37 | + * Collection of flex pages forming a task's memory view. Can be shared |
| 38 | + * across multiple tasks. |
| 39 | + */ |
| 40 | +typedef struct as { |
| 41 | + uint32_t as_id; /* Address space identifier */ |
| 42 | + struct fpage *first; /* Head of flex page list */ |
| 43 | + struct fpage *pmp_first; /* Head of PMP-loaded list */ |
| 44 | + struct fpage *pmp_stack; /* Stack regions */ |
| 45 | + uint32_t shared; /* Shared flag */ |
| 46 | +} as_t; |
| 47 | + |
| 48 | +/* Memory Pool |
| 49 | + * |
| 50 | + * Static memory region descriptor for boot-time PMP initialization. |
| 51 | + */ |
| 52 | +typedef struct { |
| 53 | + const char *name; /* Pool name */ |
| 54 | + uintptr_t start; /* Start address */ |
| 55 | + uintptr_t end; /* End address */ |
| 56 | + uint32_t flags; /* Access permissions */ |
| 57 | + uint32_t tag; /* Pool type/priority */ |
| 58 | +} mempool_t; |
| 59 | + |
| 60 | +/* Memory Pool Declaration Helpers |
| 61 | + * |
| 62 | + * Simplifies memory pool initialization with designated initializers. |
| 63 | + * DECLARE_MEMPOOL_FROM_SYMBOLS uses token concatenation to construct |
| 64 | + * linker symbol names automatically. |
| 65 | + */ |
| 66 | +#define DECLARE_MEMPOOL(name_, start_, end_, flags_, tag_) \ |
| 67 | + { \ |
| 68 | + .name = (name_), \ |
| 69 | + .start = (uintptr_t)(start_), \ |
| 70 | + .end = (uintptr_t)(end_), \ |
| 71 | + .flags = (flags_), \ |
| 72 | + .tag = (tag_), \ |
| 73 | + } |
| 74 | + |
| 75 | +#define DECLARE_MEMPOOL_FROM_SYMBOLS(name_, sym_base_, flags_, tag_) \ |
| 76 | + DECLARE_MEMPOOL((name_), &(sym_base_##_start), &(sym_base_##_end), (flags_), (tag_)) |
0 commit comments