65816-llvm-mos/demos/gnoSignalProbe.c
2026-07-07 18:33:48 -05:00

43 lines
1.6 KiB
C

// Signals end-to-end regression for GNO: install a SIGALRM handler via our
// signal() (which routes the kernel callback through __sigTrampoline), arm a
// 1-second alarm, and pause(). The kernel delivers SIGALRM through the
// trampoline, which adapts the ORCA/C callee-pops frame to our arg0-in-A
// handler; the handler flips a flag + drops a marker, pause() returns (EINTR),
// and main verifies the handler ran and control resumed cleanly (proving the
// trampoline's ORCA callee-pop return kept the kernel's context-restore stack
// intact).
//
// Bank-2 absolute uint16 markers (DBR-independent), gnoHeapProbe convention:
// 0x025000 C0DE reached end (pause returned; no hang/crash)
// 0x025010 C41D the SIGALRM handler actually executed
// 0x025012 0001 handler-ran flag observed after pause (0xDEAD if not)
#include <stdint.h>
#include <signal.h>
#include <unistd.h>
#define M(a) (*(volatile uint16_t *)(a))
static volatile uint16_t rang;
static void onAlarm(int sig) {
(void)sig;
rang = 1;
M(0x025010UL) = 0xC41D; // handler executed via the trampoline
}
int main(void) {
M(0x025000UL) = 0x0000;
M(0x025010UL) = 0x0000;
M(0x025012UL) = 0x0000;
rang = 0;
signal(SIGALRM, onAlarm); // install through __sigTrampoline
alarm(1); // fire SIGALRM in ~1 second
pause(); // block until the signal is delivered
M(0x025012UL) = rang ? 0x0001 : 0xDEAD;
M(0x025000UL) = 0xC0DE; // reached end (returned cleanly)
for (volatile unsigned long j = 0; j < 300000UL; j++) {
}
return 0;
}