diff options
| author | Gabriel Schneider <[email protected]> | 2026-08-25 12:40:53 -0300 |
|---|---|---|
| committer | Gabriel Schneider <[email protected]> | 2026-08-25 12:46:51 -0300 |
| commit | f5f8068fac59b4f16046c2022c2fc7c7e447ef4c (patch) | |
| tree | 2731a3ed4e51cae09e184e25778eded5fc37d1f5 /src/oracle/clkrst_ref.c | |
| download | esp32p4-f5f8068fac59b4f16046c2022c2fc7c7e447ef4c.tar.gz esp32p4-f5f8068fac59b4f16046c2022c2fc7c7e447ef4c.zip | |
zig-p4: pure-Zig ESP32-P4 toolchain
build.zig generates the linker script and drives Zig's own LLD; tools/image.zig
turns the ELF into a flashable image and tools/{rom,serial}.zig speak the mask
ROM loader over the UART. No CMake, ninja, idf.py, esptool, or external linker.
src/soc.zig is a comptime register model over ESP-IDF's own *_reg.h headers;
src/hal/ adds peripheral sequences; src/io/ implements std.Io for the chip;
src/oracle/ diffs this HAL against ESP-IDF's on the die.
Diffstat (limited to 'src/oracle/clkrst_ref.c')
| -rw-r--r-- | src/oracle/clkrst_ref.c | 55 |
1 files changed, 55 insertions, 0 deletions
diff --git a/src/oracle/clkrst_ref.c b/src/oracle/clkrst_ref.c new file mode 100644 index 0000000..b35436c --- /dev/null +++ b/src/oracle/clkrst_ref.c @@ -0,0 +1,55 @@ +/* ESP-IDF's own bus-clock and reset control, as the reference for src/hal/clkrst.zig. + * + * This suite exists because of a specific bug. `clkrst.zig` maps each peripheral to the register and + * bit that gate and reset it, and that table is hand-written: the field macros do not say which + * register they live in, so every row is a transcription from ESP-IDF's LL source. Two rows were + * wrong. The second batch - timg0, timg1, systimer and twai0 - had their APB clock enables in + * HP_SYS_CLKRST_PERI_CLK_CTRL21 instead of SOC_CLK_CTRL2, so `setClockEnabled` poked a bit of an + * unrelated register. + * + * It survived a hardware test, which is the point. `examples/halcheck.zig` printed exactly the + * expected `twai0 boot=0 on=1 off=0`, because the write and the read-back both went through the same + * wrong address: a self-consistent test that would have passed with the chip unplugged. + * + * IDF reaches these bits by a completely independent path - its own generated struct definitions - + * so comparing against it is the check that a read-back cannot be. + */ + +/* IDF shadows every clock/reset LL function with a macro that references this identifier, which it + * deliberately never defines, so that an unguarded call fails to compile: the only legal caller + * holds a spinlock. There is no FreeRTOS here and core 1 is held in reset at power-on, so declaring + * the name is exactly as safe as the lock would be. IDF's own bootloader does the same thing + * (bootloader_support/src/bootloader_console.c:53). */ +static int __DECLARE_RCC_ATOMIC_ENV __attribute__((unused)); +/* IDF uses a second name for the same trick on the peripherals whose gate lives in a register shared + * with the CPU's own clocking - systimer among them. Same reasoning applies. */ +static int __DECLARE_RCC_RC_ATOMIC_ENV __attribute__((unused)); + +#include "hal/timg_ll.h" +#include "hal/systimer_ll.h" +#include "hal/uart_ll.h" + +void oracle_clkrst_timg_bus_clock(unsigned group, int enable) +{ + _timg_ll_enable_bus_clock(group, enable != 0); +} + +void oracle_clkrst_timg_reset(unsigned group) +{ + _timg_ll_reset_register(group); +} + +void oracle_clkrst_systimer_bus_clock(int enable) +{ + systimer_ll_enable_bus_clock(enable != 0); +} + +void oracle_clkrst_systimer_reset(void) +{ + systimer_ll_reset_register(); +} + +void oracle_clkrst_uart_bus_clock(unsigned port, int enable) +{ + _uart_ll_enable_bus_clock(port, enable != 0); +} |
