diff options
Diffstat (limited to 'src/soc.zig')
| -rw-r--r-- | src/soc.zig | 15 |
1 files changed, 15 insertions, 0 deletions
diff --git a/src/soc.zig b/src/soc.zig index f022b50..172966e 100644 --- a/src/soc.zig +++ b/src/soc.zig @@ -94,6 +94,21 @@ pub const rom = struct { pub extern fn ets_printf(fmt: [*:0]const u8, ...) c_int; pub extern fn ets_delay_us(us: u32) void; + /// Invalidate the caches. `map` selects which, from `rom/cache.h:228-236`: + /// L1 ICache0 = 1, ICache1 = 2, L1 DCache = 0x10, L2 = 0x20; `cache_all` is all four. + /// + /// This is not optional on a large image, and finding that out took a while. The second-stage + /// bootloader leaves cache lines behind that do not match the mapping it finally installs, so an + /// application can read its own `.rodata` and get someone else's bytes - deterministically, + /// which is what makes it look like anything other than a cache. Measured: a load at 0x40035a1c + /// returned `93 85 85 0f`, and after touching 512 KiB to evict the line the same load returned + /// `3c ee 08 40`, which is what the image holds there. `_start` calls this before it clears + /// `.bss`, so nothing of ours is in flight when the lines are dropped. + pub extern fn Cache_Invalidate_All(map: u32) c_int; + + /// Every cache this chip has: L1 ICache0 | L1 ICache1 | L1 DCache | L2. + pub const cache_all: u32 = 0x33; + pub inline fn print(comptime fmt: [*:0]const u8, args: anytype) void { _ = @call(.auto, ets_printf, .{fmt} ++ args); } |
