esp32s3: replace inline ISR with full interrupt vector handler

Replace the minimal inline ISR (which only disabled INTENABLE) with a
full level-1 interrupt handler that saves/restores the interrupted
context and dispatches to Go's handleInterrupt.

The handler uses callx4 (not callx0) to call into Go code because:
- callx0 does not set PS.CALLINC, so the Go function's entry
  instruction uses stale CALLINC from the interrupted code, causing
  wrong window rotation and a garbage stack pointer.
- callx4 explicitly sets CALLINC=1, and our frame pointer (a1) is
  outside the callee's register window so it is preserved.

Also updates the USB Serial/JTAG ISR to disable INT_ENA (peripheral
level) instead of relying on INTENABLE, and adds signalInterrupt to
the dispatcher so sleepTicks can be woken by any interrupt.
This commit is contained in:
deadprogram
2026-04-02 14:09:31 +02:00
parent 3386316b9f
commit a6a4f85e61
3 changed files with 139 additions and 15 deletions
@@ -115,6 +115,9 @@ func handleInterrupt() {
}
}
// Signal to sleepTicks that an interrupt has occurred.
signalInterrupt()
inInterrupt = false
}
@@ -180,6 +183,9 @@ func callHandler(n int) {
//go:linkname callHandlers runtime/interrupt.callHandlers
func callHandlers(num int)
//go:linkname signalInterrupt runtime.signalInterrupt
func signalInterrupt()
var errInterruptRange = constError("interrupt for ESP32-S3 must be in range 6 through 30")
type constError string