esp32s3: improve exception handlers, add procPin/procUnpin, and linker wrap flags

Rewrite kernel and double exception handlers to save EXCCAUSE/EPC1 to
RTC STORE registers before triggering a software reset, replacing the
LED-blink diagnostic with post-mortem debug info that survives reset.

Add user exception dispatch in the level-1 handler with a weak
espradio_user_exception symbol so programs without espradio still link.

Implement procPin/procUnpin for Xtensa using RSIL/WSR PS to properly
disable interrupts during atomic operations. Fix abort() to use a
waiti loop instead of bare spin.

Add --wrap ldflags for malloc/calloc/free/realloc/ppCheckTxConnTrafficIdle
to support espradio WiFi blob integration.

Signed-off-by: deadprogram <ron@hybridgroup.com>
This commit is contained in:
deadprogram
2026-04-07 12:15:39 +02:00
committed by Ron Evans
parent c3d514a751
commit a24dc8c543
4 changed files with 126 additions and 29 deletions
+20
View File
@@ -2,6 +2,8 @@
package runtime
import "device"
const GOARCH = "arm" // xtensa pretends to be arm
// The bitness of the CPU (e.g. 8, 32, 64).
@@ -19,3 +21,21 @@ func align(ptr uintptr) uintptr {
func getCurrentStackPointer() uintptr {
return uintptr(stacksave())
}
// Disable interrupts for procPin/procUnpin using the Xtensa RSIL/WSR PS
// instructions. A global variable is safe here because accesses happen
// with interrupts disabled.
var procPinnedMask uintptr
//go:linkname procPin sync/atomic.runtime_procPin
func procPin() {
// rsil sets PS.INTLEVEL=15 (mask all) and returns the old PS.
procPinnedMask = uintptr(device.AsmFull("rsil {}, 15", nil))
}
//go:linkname procUnpin sync/atomic.runtime_procUnpin
func procUnpin() {
device.AsmFull("wsr {state}, PS", map[string]interface{}{
"state": procPinnedMask,
})
}
+4 -1
View File
@@ -96,8 +96,11 @@ func init() {
}
func abort() {
// lock up forever
print("abort called\n")
// lock up forever
for {
device.Asm("waiti 0")
}
}
// interruptInit installs the Xtensa vector table by writing its address