summaryrefslogtreecommitdiff
path: root/src/net/hosted/sdkconfig.h
diff options
context:
space:
mode:
authorGabriel Schneider <[email protected]>2026-08-25 12:40:53 -0300
committerGabriel Schneider <[email protected]>2026-08-25 12:46:51 -0300
commitf5f8068fac59b4f16046c2022c2fc7c7e447ef4c (patch)
tree2731a3ed4e51cae09e184e25778eded5fc37d1f5 /src/net/hosted/sdkconfig.h
downloadesp32p4-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/net/hosted/sdkconfig.h')
-rw-r--r--src/net/hosted/sdkconfig.h139
1 files changed, 139 insertions, 0 deletions
diff --git a/src/net/hosted/sdkconfig.h b/src/net/hosted/sdkconfig.h
new file mode 100644
index 0000000..63e77e9
--- /dev/null
+++ b/src/net/hosted/sdkconfig.h
@@ -0,0 +1,139 @@
+/*
+ * The Kconfig surface ESP-Hosted's C compiles against in this project.
+ *
+ * Two parts, deliberately separated:
+ *
+ * sdkconfig_idf.h ESP-IDF v6.0.2's generated header, verbatim, from the build in
+ * 02-esp32p4-m3-radio that reached transport state "active" on this die.
+ * Unedited, so its provenance is checkable.
+ *
+ * this file that header, plus a short list of overrides. Each one states what it changes
+ * and why, so the delta from the proven configuration is reviewable rather than
+ * buried in 1,400 generated lines.
+ *
+ * The generated header is used rather than a hand-picked subset because ESP-Hosted's headers derive
+ * struct layouts and the slave target from these symbols: CONFIG_ESP_HOSTED_CP_TARGET_ESP32C6 is
+ * what defines H_SLAVE_TARGET_ESP32C6, and CONFIG_ESP_HOSTED_USE_MEMPOOL is what decides the length
+ * of hosted_osi_funcs_t (see abi_assert.c). Hand-picking would be a second, unproven configuration.
+ *
+ * Nothing here starts a FreeRTOS kernel or an IDF component. The CONFIG_FREERTOS_* values only
+ * shape type declarations; src/net/port.zig and src/io/p4.zig supply the runtime.
+ */
+
+#pragma once
+
+#include "sdkconfig_idf.h"
+
+/* ------------------------------------------------------------------------------------------------
+ * Override 1: SDIO queue depths, 20 -> 4 each.
+ *
+ * IDF's build ran with 20 TX and 20 RX descriptors. That is a reasonable number when the heap is
+ * PSRAM-backed; here it is not. Forty in-flight buffers at MAX_SDIO_BUFFER_SIZE (1536 B) reserve
+ * ~60 KB before a single task stack exists, and this image has ~128 KB of L2MEM in total with
+ * nothing initialising the 32 MB of PSRAM.
+ *
+ * Four each was the first attempt and it was measured wrong. Once the board associated, the AP's
+ * ordinary broadcast traffic filled a four-deep queue immediately: the console filled with
+ * "task still writing Rx data to queue!", the receive counter froze at 8 frames, and the board
+ * stopped answering ARP - so it took a DHCP lease and then went silent, which looked like a bug in
+ * the IP stack rather than a queue two sizes too small.
+ *
+ * Sixteen each was then too many, for the reason that makes this setting awkward: with the mempool
+ * off (override 3) every frame is a fresh `_h_malloc_align(MAX_TRANSPORT_BUFFER_SIZE, 64)` from our
+ * heap, so the depths bound peak heap demand at (tx + rx) x 1536 bytes. At sixteen each that is
+ * ~49 KB of a 56 KB heap, and the board duly ran out: "mempool OOM start (RX)" at 11 s, then
+ * "STA TX: mempool_alloc failed, dropping pkt", after which nothing moved in either direction.
+ *
+ * Eight each: ~24.5 KB peak, against a heap sized well above it in examples/http.zig. Deep enough
+ * that ordinary broadcast traffic does not fill the queue between two `tick`s, shallow enough that a
+ * burst cannot exhaust the heap and stop the transmit path as collateral damage. That second
+ * property is the one worth protecting: a receive queue that overflows drops a frame, but a heap
+ * that empties takes the whole radio down.
+ * ---------------------------------------------------------------------------------------------- */
+#undef CONFIG_ESP_HOSTED_SDIO_TX_Q_SIZE
+#define CONFIG_ESP_HOSTED_SDIO_TX_Q_SIZE 8
+#undef CONFIG_ESP_HOSTED_SDIO_RX_Q_SIZE
+#define CONFIG_ESP_HOSTED_SDIO_RX_Q_SIZE 8
+
+/* These two are aliases the transport reads; they must follow the values above rather than the
+ * originals, or the queues and the descriptors disagree about their own depth. */
+#undef CONFIG_ESP_SDIO_TX_Q_SIZE
+#define CONFIG_ESP_SDIO_TX_Q_SIZE CONFIG_ESP_HOSTED_SDIO_TX_Q_SIZE
+#undef CONFIG_ESP_SDIO_RX_Q_SIZE
+#define CONFIG_ESP_SDIO_RX_Q_SIZE CONFIG_ESP_HOSTED_SDIO_RX_Q_SIZE
+
+/* ------------------------------------------------------------------------------------------------
+ * Override 2: Bluetooth off.
+ *
+ * The IDF build this configuration came from used BLE through the C6, so it enabled NimBLE and the
+ * VHCI transport. This project does not do Bluetooth, and leaving it on is not free: ESP-Hosted's
+ * transport calls hci_drv_init() unconditionally (transport_drv.c:126), and with NimBLE enabled that
+ * pulls in the real vhci_drv.c and the whole NimBLE host - ble_transport_*, os_mbuf_*,
+ * ble_hs_mbuf_to_flat - which is another stack this image has no reason to carry.
+ *
+ * With these off, ESP-Hosted's own host/drivers/bt/hci_stub_drv.c compiles to a no-op hci_drv_init
+ * and a drop-everything hci_rx_handler. That file is in the source list in build.zig, which is why
+ * this is a configuration change rather than a Zig stub: the C already ships the right answer for a
+ * host without Bluetooth, and using it keeps one fewer thing for us to get wrong.
+ *
+ * The C6 still reports HCI capability in its capability byte (0x0d on this board). That is the
+ * coprocessor saying what it can do, not a request; declining is the host's decision.
+ * ---------------------------------------------------------------------------------------------- */
+#undef CONFIG_ESP_HOSTED_ENABLE_BT_NIMBLE
+#undef CONFIG_ESP_HOSTED_NIMBLE_HCI_VHCI
+#undef CONFIG_ESP_HOSTED_ENABLE_BT_BLUEDROID
+#undef CONFIG_ESP_HOSTED_BLUEDROID_HCI_VHCI
+#undef CONFIG_BT_ENABLED
+#undef CONFIG_BT_NIMBLE_ENABLED
+
+/* ------------------------------------------------------------------------------------------------
+ * Override 3: mempool off.
+ *
+ * ESP-Hosted's mempool recycles fixed-size packet buffers instead of going to malloc each time. It
+ * needs a backend, supplied by `os_mempool_get_ops()`, and on ESP-IDF that comes from FreeRTOS's own
+ * pool implementation. This image has no FreeRTOS, and mempool.c treats a null ops table as a hard
+ * failure rather than a fallback (mempool.c:63-65, "hosted mempool init failed: no mempool ops") -
+ * which is what the second run of examples/radio.zig printed.
+ *
+ * The choice is to write a pool backend or to switch the optimisation off. Off, for now: the
+ * allocator behind _h_malloc (src/net/heap.zig) is a coalescing free list over a static buffer, so
+ * the same-size churn mempool exists to avoid is already cheap and cannot fragment the way a
+ * general-purpose heap would. If profiling later says otherwise, the backend is a small job and this
+ * is the one line to flip back.
+ *
+ * Layout note, because this looks dangerous and is not: turning this off does NOT change
+ * hosted_osi_funcs_t. port_esp_hosted_host_config.h:127-131 defines H_USE_MEMPOOL to 1 or to 0, and
+ * the struct's four mempool members are guarded by `#ifdef`, which only asks whether the name is
+ * defined. Both ways the struct is 284 bytes. src/net/hosted/abi_assert.c asserts that directly.
+ * ---------------------------------------------------------------------------------------------- */
+#undef CONFIG_ESP_HOSTED_USE_MEMPOOL
+#define CONFIG_ESP_HOSTED_USE_MEMPOOL 0
+
+/* ------------------------------------------------------------------------------------------------
+ * Override 4: the ESP-Hosted CLI off.
+ *
+ * A console command set for poking the transport at runtime. It needs IDF's `console` component -
+ * esp_console_cmd_register, a line editor, and a UART driver - none of which exists in this image,
+ * and none of which this project wants: the serial line here is a log, not a shell.
+ *
+ * `H_ESP_HOSTED_CLI_ENABLED` is an `#ifdef` on the *value* of this symbol being defined
+ * (transport_drv.c:804), so it must be #undef'd rather than defined to 0.
+ * ---------------------------------------------------------------------------------------------- */
+#undef CONFIG_ESP_HOSTED_CLI_ENABLED
+
+/* ------------------------------------------------------------------------------------------------
+ * Override 5: compile DEBUG-level logging in.
+ *
+ * The generated configuration stops at CONFIG_LOG_MAXIMUM_LEVEL 3 (INFO), which compiles ESP_LOGD
+ * away entirely. That hides exactly the lines needed to tell a stalled receive path apart from a
+ * silent slave: sdio_drv.c:1190 logs "--- Wait for SDIO intr ---" at DEBUG on every pass of
+ * sdio_read_task, so its presence or absence answers "is the read task still looping?" directly.
+ *
+ * 4, not 5: VERBOSE adds a per-interrupt line that floods a 115200 baud console and changes the
+ * timing of the thing being measured.
+ *
+ * The runtime filter in src/net/hosted_glue.zig is separate and independent - this only decides what
+ * exists in the image to be filtered.
+ * ---------------------------------------------------------------------------------------------- */
+#undef CONFIG_LOG_MAXIMUM_LEVEL
+#define CONFIG_LOG_MAXIMUM_LEVEL 4