xref: /plan9/sys/src/ape/lib/ap/power/notetramp.c (revision 7dd7cddf99dd7472612f1413b4da293630e6b1bc)
1*7dd7cddfSDavid du Colombier #include "../plan9/lib.h"
2*7dd7cddfSDavid du Colombier #include "../plan9/sys9.h"
3*7dd7cddfSDavid du Colombier #include <signal.h>
4*7dd7cddfSDavid du Colombier #include <setjmp.h>
5*7dd7cddfSDavid du Colombier 
6*7dd7cddfSDavid du Colombier /* A stack to hold pcs when signals nest */
7*7dd7cddfSDavid du Colombier #define MAXSIGSTACK 20
8*7dd7cddfSDavid du Colombier typedef struct Pcstack Pcstack;
9*7dd7cddfSDavid du Colombier static struct Pcstack {
10*7dd7cddfSDavid du Colombier 	int sig;
11*7dd7cddfSDavid du Colombier 	void (*hdlr)(int, char*, Ureg*);
12*7dd7cddfSDavid du Colombier 	unsigned long restorepc;
13*7dd7cddfSDavid du Colombier 	Ureg *u;
14*7dd7cddfSDavid du Colombier } pcstack[MAXSIGSTACK];
15*7dd7cddfSDavid du Colombier static int nstack = 0;
16*7dd7cddfSDavid du Colombier 
17*7dd7cddfSDavid du Colombier static void notecont(Ureg*, char*);
18*7dd7cddfSDavid du Colombier 
19*7dd7cddfSDavid du Colombier void
_notetramp(int sig,void (* hdlr)(int,char *,Ureg *),Ureg * u)20*7dd7cddfSDavid du Colombier _notetramp(int sig, void (*hdlr)(int, char*, Ureg*), Ureg *u)
21*7dd7cddfSDavid du Colombier {
22*7dd7cddfSDavid du Colombier 	Pcstack *p;
23*7dd7cddfSDavid du Colombier 
24*7dd7cddfSDavid du Colombier 	if(nstack >= MAXSIGSTACK)
25*7dd7cddfSDavid du Colombier 		_NOTED(1);	/* nesting too deep; just do system default */
26*7dd7cddfSDavid du Colombier 	p = &pcstack[nstack];
27*7dd7cddfSDavid du Colombier 	p->restorepc = u->pc;
28*7dd7cddfSDavid du Colombier 	p->sig = sig;
29*7dd7cddfSDavid du Colombier 	p->hdlr = hdlr;
30*7dd7cddfSDavid du Colombier 	p->u = u;
31*7dd7cddfSDavid du Colombier 	nstack++;
32*7dd7cddfSDavid du Colombier 	u->pc = (unsigned long) notecont;
33*7dd7cddfSDavid du Colombier 	_NOTED(2);	/* NSAVE: clear note but hold state */
34*7dd7cddfSDavid du Colombier }
35*7dd7cddfSDavid du Colombier 
36*7dd7cddfSDavid du Colombier static void
notecont(Ureg * u,char * s)37*7dd7cddfSDavid du Colombier notecont(Ureg *u, char *s)
38*7dd7cddfSDavid du Colombier {
39*7dd7cddfSDavid du Colombier 	Pcstack *p;
40*7dd7cddfSDavid du Colombier 	void(*f)(int, char*, Ureg*);
41*7dd7cddfSDavid du Colombier 
42*7dd7cddfSDavid du Colombier 	p = &pcstack[nstack-1];
43*7dd7cddfSDavid du Colombier 	f = p->hdlr;
44*7dd7cddfSDavid du Colombier 	u->pc = p->restorepc;
45*7dd7cddfSDavid du Colombier 	nstack--;
46*7dd7cddfSDavid du Colombier 	(*f)(p->sig, s, u);
47*7dd7cddfSDavid du Colombier 	_NOTED(3);	/* NRSTR */
48*7dd7cddfSDavid du Colombier }
49*7dd7cddfSDavid du Colombier 
50*7dd7cddfSDavid du Colombier #define JMPBUFPC 1
51*7dd7cddfSDavid du Colombier #define JMPBUFSP 0
52*7dd7cddfSDavid du Colombier 
53*7dd7cddfSDavid du Colombier extern sigset_t	_psigblocked;
54*7dd7cddfSDavid du Colombier 
55*7dd7cddfSDavid du Colombier void
siglongjmp(sigjmp_buf j,int ret)56*7dd7cddfSDavid du Colombier siglongjmp(sigjmp_buf j, int ret)
57*7dd7cddfSDavid du Colombier {
58*7dd7cddfSDavid du Colombier 	struct Ureg *u;
59*7dd7cddfSDavid du Colombier 
60*7dd7cddfSDavid du Colombier 	if(j[0])
61*7dd7cddfSDavid du Colombier 		_psigblocked = j[1];
62*7dd7cddfSDavid du Colombier 	if(nstack == 0 || pcstack[nstack-1].u->sp > j[2+JMPBUFSP])
63*7dd7cddfSDavid du Colombier 		longjmp(j+2, ret);
64*7dd7cddfSDavid du Colombier 	u = pcstack[nstack-1].u;
65*7dd7cddfSDavid du Colombier 	nstack--;
66*7dd7cddfSDavid du Colombier 	u->r3 = ret;
67*7dd7cddfSDavid du Colombier 	if(ret == 0)
68*7dd7cddfSDavid du Colombier 		u->r3 = 1;
69*7dd7cddfSDavid du Colombier 	u->pc = j[2+JMPBUFPC];
70*7dd7cddfSDavid du Colombier 	u->sp = j[2+JMPBUFSP];
71*7dd7cddfSDavid du Colombier 	_NOTED(3);	/* NRSTR */
72*7dd7cddfSDavid du Colombier }
73