Complete rewrite of the signal and spl framework for NetBSD/usermode Signals are now moved from the sigaltstack ASAP and stacked on a replacement stack for each processes. Preemption now works though could be enhanced a bit morediff -r1.25 -r1.26 src/sys/arch/usermode/dev/clock.c
(reinoud)
--- src/sys/arch/usermode/dev/clock.c 2012/01/14 21:42:51 1.25
+++ src/sys/arch/usermode/dev/clock.c 2012/01/21 22:09:56 1.26
@@ -1,14 +1,14 @@ | @@ -1,14 +1,14 @@ | |||
1 | /* $NetBSD: clock.c,v 1.25 2012/01/14 21:42:51 reinoud Exp $ */ | 1 | /* $NetBSD: clock.c,v 1.26 2012/01/21 22:09:56 reinoud Exp $ */ | |
2 | 2 | |||
3 | /*- | 3 | /*- | |
4 | * Copyright (c) 2007 Jared D. McNeill <jmcneill@invisible.ca> | 4 | * Copyright (c) 2007 Jared D. McNeill <jmcneill@invisible.ca> | |
5 | * All rights reserved. | 5 | * All rights reserved. | |
6 | * | 6 | * | |
7 | * Redistribution and use in source and binary forms, with or without | 7 | * Redistribution and use in source and binary forms, with or without | |
8 | * modification, are permitted provided that the following conditions | 8 | * modification, are permitted provided that the following conditions | |
9 | * are met: | 9 | * are met: | |
10 | * 1. Redistributions of source code must retain the above copyright | 10 | * 1. Redistributions of source code must retain the above copyright | |
11 | * notice, this list of conditions and the following disclaimer. | 11 | * notice, this list of conditions and the following disclaimer. | |
12 | * 2. Redistributions in binary form must reproduce the above copyright | 12 | * 2. Redistributions in binary form must reproduce the above copyright | |
13 | * notice, this list of conditions and the following disclaimer in the | 13 | * notice, this list of conditions and the following disclaimer in the | |
14 | * documentation and/or other materials provided with the distribution. | 14 | * documentation and/or other materials provided with the distribution. | |
@@ -19,130 +19,120 @@ | @@ -19,130 +19,120 @@ | |||
19 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS | 19 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS | |
20 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | 20 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | |
21 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | 21 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | |
22 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | 22 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |
23 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | 23 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | |
24 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | 24 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | |
25 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | 25 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | |
26 | * POSSIBILITY OF SUCH DAMAGE. | 26 | * POSSIBILITY OF SUCH DAMAGE. | |
27 | */ | 27 | */ | |
28 | 28 | |||
29 | #include "opt_hz.h" | 29 | #include "opt_hz.h" | |
30 | 30 | |||
31 | #include <sys/cdefs.h> | 31 | #include <sys/cdefs.h> | |
32 | __KERNEL_RCSID(0, "$NetBSD: clock.c,v 1.25 2012/01/14 21:42:51 reinoud Exp $"); | 32 | __KERNEL_RCSID(0, "$NetBSD: clock.c,v 1.26 2012/01/21 22:09:56 reinoud Exp $"); | |
33 | 33 | |||
34 | #include <sys/param.h> | 34 | #include <sys/param.h> | |
35 | #include <sys/proc.h> | 35 | #include <sys/proc.h> | |
36 | #include <sys/systm.h> | 36 | #include <sys/systm.h> | |
37 | #include <sys/device.h> | 37 | #include <sys/device.h> | |
38 | #include <sys/lwp.h> | 38 | #include <sys/lwp.h> | |
39 | #include <sys/cpu.h> | 39 | #include <sys/cpu.h> | |
40 | #include <sys/malloc.h> | 40 | #include <sys/malloc.h> | |
41 | #include <sys/timetc.h> | 41 | #include <sys/timetc.h> | |
42 | #include <sys/time.h> | 42 | #include <sys/time.h> | |
43 | 43 | |||
44 | #include <machine/pcb.h> | 44 | #include <machine/pcb.h> | |
45 | #include <machine/mainbus.h> | 45 | #include <machine/mainbus.h> | |
46 | #include <machine/thunk.h> | 46 | #include <machine/thunk.h> | |
47 | 47 | |||
48 | #include <dev/clock_subr.h> | 48 | #include <dev/clock_subr.h> | |
49 | 49 | |||
50 | static int clock_match(device_t, cfdata_t, void *); | 50 | static int clock_match(device_t, cfdata_t, void *); | |
51 | static void clock_attach(device_t, device_t, void *); | 51 | static void clock_attach(device_t, device_t, void *); | |
52 | 52 | |||
53 | static void clock_signal(int sig, siginfo_t *info, void *ctx); | |||
54 | static unsigned int clock_getcounter(struct timecounter *); | 53 | static unsigned int clock_getcounter(struct timecounter *); | |
55 | 54 | |||
56 | static int clock_todr_gettime(struct todr_chip_handle *, struct timeval *); | 55 | static int clock_todr_gettime(struct todr_chip_handle *, struct timeval *); | |
57 | 56 | |||
57 | extern void setup_clock_intr(void); | |||
58 | void clock_intr(void *priv); | |||
59 | ||||
60 | ||||
58 | struct clock_softc { | 61 | struct clock_softc { | |
59 | device_t sc_dev; | 62 | device_t sc_dev; | |
60 | struct todr_chip_handle sc_todr; | 63 | struct todr_chip_handle sc_todr; | |
61 | }; | 64 | }; | |
62 | 65 | |||
63 | static struct timecounter clock_timecounter = { | 66 | static struct timecounter clock_timecounter = { | |
64 | clock_getcounter, /* get_timecount */ | 67 | clock_getcounter, /* get_timecount */ | |
65 | 0, /* no poll_pps */ | 68 | 0, /* no poll_pps */ | |
66 | ~0u, /* counter_mask */ | 69 | ~0u, /* counter_mask */ | |
67 | 1000000000ULL, /* frequency */ | 70 | 1000000000ULL, /* frequency */ | |
68 | "CLOCK_MONOTONIC", /* name */ | 71 | "CLOCK_MONOTONIC", /* name */ | |
69 | -100, /* quality */ | 72 | -100, /* quality */ | |
70 | NULL, /* prev */ | 73 | NULL, /* prev */ | |
71 | NULL, /* next */ | 74 | NULL, /* next */ | |
72 | }; | 75 | }; | |
73 | 76 | |||
74 | timer_t clock_timerid; | 77 | timer_t clock_timerid; | |
78 | int clock_running = 0; | |||
75 | 79 | |||
76 | CFATTACH_DECL_NEW(clock, sizeof(struct clock_softc), | 80 | CFATTACH_DECL_NEW(clock, sizeof(struct clock_softc), | |
77 | clock_match, clock_attach, NULL, NULL); | 81 | clock_match, clock_attach, NULL, NULL); | |
78 | 82 | |||
79 | static int | 83 | static int | |
80 | clock_match(device_t parent, cfdata_t match, void *opaque) | 84 | clock_match(device_t parent, cfdata_t match, void *opaque) | |
81 | { | 85 | { | |
82 | struct thunkbus_attach_args *taa = opaque; | 86 | struct thunkbus_attach_args *taa = opaque; | |
83 | 87 | |||
84 | if (taa->taa_type != THUNKBUS_TYPE_CLOCK) | 88 | if (taa->taa_type != THUNKBUS_TYPE_CLOCK) | |
85 | return 0; | 89 | return 0; | |
86 | 90 | |||
87 | return 1; | 91 | return 1; | |
88 | } | 92 | } | |
89 | 93 | |||
90 | static void | 94 | static void | |
91 | clock_attach(device_t parent, device_t self, void *opaque) | 95 | clock_attach(device_t parent, device_t self, void *opaque) | |
92 | { | 96 | { | |
93 | static struct sigaction sa; | |||
94 | struct clock_softc *sc = device_private(self); | 97 | struct clock_softc *sc = device_private(self); | |
95 | 98 | |||
96 | aprint_naive("\n"); | 99 | aprint_naive("\n"); | |
97 | aprint_normal("\n"); | 100 | aprint_normal("\n"); | |
98 | 101 | |||
99 | sc->sc_dev = self; | 102 | sc->sc_dev = self; | |
100 | 103 | |||
101 | sc->sc_todr.todr_gettime = clock_todr_gettime; | 104 | sc->sc_todr.todr_gettime = clock_todr_gettime; | |
102 | todr_attach(&sc->sc_todr); | 105 | todr_attach(&sc->sc_todr); | |
103 | 106 | |||
104 | memset(&sa, 0, sizeof(sa)); | |||
105 | thunk_sigemptyset(&sa.sa_mask); | |||
106 | sa.sa_sigaction = clock_signal; | |||
107 | sa.sa_flags = SA_RESTART | SA_ONSTACK; | |||
108 | if (thunk_sigaction(SIGALRM, &sa, NULL) == -1) | |||
109 | panic("couldn't register SIGALRM handler : %d", | |||
110 | thunk_geterrno()); | |||
111 | ||||
112 | clock_timerid = thunk_timer_attach(); | 107 | clock_timerid = thunk_timer_attach(); | |
113 | ||||
114 | clock_timecounter.tc_quality = 1000; | 108 | clock_timecounter.tc_quality = 1000; | |
115 | tc_init(&clock_timecounter); | 109 | tc_init(&clock_timecounter); | |
110 | ||||
111 | setup_clock_intr(); | |||
112 | clock_running = 1; | |||
116 | } | 113 | } | |
117 | 114 | |||
118 | static void | 115 | void | |
119 | clock_intr(void *priv) | 116 | clock_intr(void *priv) | |
120 | { | 117 | { | |
121 | struct clockframe cf; | 118 | struct clockframe cf; | |
122 | int nticks = thunk_timer_getoverrun(clock_timerid) + 1; | 119 | int nticks = thunk_timer_getoverrun(clock_timerid) + 1; | |
123 | 120 | |||
124 | while (nticks-- > 0) { | 121 | while (nticks-- > 0) { | |
125 | hardclock(&cf); | 122 | hardclock(&cf); | |
126 | } | 123 | } | |
127 | } | 124 | } | |
128 | 125 | |||
129 | static void | |||
130 | clock_signal(int sig, siginfo_t *info, void *ctx) | |||
131 | { | |||
132 | curcpu()->ci_idepth++; | |||
133 | spl_intr(IPL_SOFTCLOCK, clock_intr, NULL); | |||
134 | curcpu()->ci_idepth--; | |||
135 | } | |||
136 | 126 | |||
137 | static unsigned int | 127 | static unsigned int | |
138 | clock_getcounter(struct timecounter *tc) | 128 | clock_getcounter(struct timecounter *tc) | |
139 | { | 129 | { | |
140 | return thunk_getcounter(); | 130 | return thunk_getcounter(); | |
141 | } | 131 | } | |
142 | 132 | |||
143 | static int | 133 | static int | |
144 | clock_todr_gettime(struct todr_chip_handle *tch, struct timeval *tv) | 134 | clock_todr_gettime(struct todr_chip_handle *tch, struct timeval *tv) | |
145 | { | 135 | { | |
146 | struct thunk_timeval ttv; | 136 | struct thunk_timeval ttv; | |
147 | int error; | 137 | int error; | |
148 | 138 |
--- src/sys/arch/usermode/dev/cpu.c 2012/01/18 19:17:02 1.68
+++ src/sys/arch/usermode/dev/cpu.c 2012/01/21 22:09:56 1.69
@@ -1,14 +1,14 @@ | @@ -1,14 +1,14 @@ | |||
1 | /* $NetBSD: cpu.c,v 1.68 2012/01/18 19:17:02 reinoud Exp $ */ | 1 | /* $NetBSD: cpu.c,v 1.69 2012/01/21 22:09:56 reinoud Exp $ */ | |
2 | 2 | |||
3 | /*- | 3 | /*- | |
4 | * Copyright (c) 2007 Jared D. McNeill <jmcneill@invisible.ca> | 4 | * Copyright (c) 2007 Jared D. McNeill <jmcneill@invisible.ca> | |
5 | * All rights reserved. | 5 | * All rights reserved. | |
6 | * | 6 | * | |
7 | * Redistribution and use in source and binary forms, with or without | 7 | * Redistribution and use in source and binary forms, with or without | |
8 | * modification, are permitted provided that the following conditions | 8 | * modification, are permitted provided that the following conditions | |
9 | * are met: | 9 | * are met: | |
10 | * 1. Redistributions of source code must retain the above copyright | 10 | * 1. Redistributions of source code must retain the above copyright | |
11 | * notice, this list of conditions and the following disclaimer. | 11 | * notice, this list of conditions and the following disclaimer. | |
12 | * 2. Redistributions in binary form must reproduce the above copyright | 12 | * 2. Redistributions in binary form must reproduce the above copyright | |
13 | * notice, this list of conditions and the following disclaimer in the | 13 | * notice, this list of conditions and the following disclaimer in the | |
14 | * documentation and/or other materials provided with the distribution. | 14 | * documentation and/or other materials provided with the distribution. | |
@@ -20,27 +20,27 @@ | @@ -20,27 +20,27 @@ | |||
20 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | 20 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | |
21 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | 21 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | |
22 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | 22 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |
23 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | 23 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | |
24 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | 24 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | |
25 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | 25 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | |
26 | * POSSIBILITY OF SUCH DAMAGE. | 26 | * POSSIBILITY OF SUCH DAMAGE. | |
27 | */ | 27 | */ | |
28 | 28 | |||
29 | #include "opt_cpu.h" | 29 | #include "opt_cpu.h" | |
30 | #include "opt_hz.h" | 30 | #include "opt_hz.h" | |
31 | 31 | |||
32 | #include <sys/cdefs.h> | 32 | #include <sys/cdefs.h> | |
33 | __KERNEL_RCSID(0, "$NetBSD: cpu.c,v 1.68 2012/01/18 19:17:02 reinoud Exp $"); | 33 | __KERNEL_RCSID(0, "$NetBSD: cpu.c,v 1.69 2012/01/21 22:09:56 reinoud Exp $"); | |
34 | 34 | |||
35 | #include <sys/param.h> | 35 | #include <sys/param.h> | |
36 | #include <sys/conf.h> | 36 | #include <sys/conf.h> | |
37 | #include <sys/proc.h> | 37 | #include <sys/proc.h> | |
38 | #include <sys/systm.h> | 38 | #include <sys/systm.h> | |
39 | #include <sys/device.h> | 39 | #include <sys/device.h> | |
40 | #include <sys/reboot.h> | 40 | #include <sys/reboot.h> | |
41 | #include <sys/lwp.h> | 41 | #include <sys/lwp.h> | |
42 | #include <sys/cpu.h> | 42 | #include <sys/cpu.h> | |
43 | #include <sys/mbuf.h> | 43 | #include <sys/mbuf.h> | |
44 | #include <sys/msgbuf.h> | 44 | #include <sys/msgbuf.h> | |
45 | #include <sys/kmem.h> | 45 | #include <sys/kmem.h> | |
46 | #include <sys/kernel.h> | 46 | #include <sys/kernel.h> | |
@@ -234,32 +234,33 @@ cpu_switchto(lwp_t *oldlwp, lwp_t *newlw | @@ -234,32 +234,33 @@ cpu_switchto(lwp_t *oldlwp, lwp_t *newlw | |||
234 | if (newpcb) { | 234 | if (newpcb) { | |
235 | thunk_printf_debug(" newpcb uc_link=%p, uc_stack.ss_sp=%p, " | 235 | thunk_printf_debug(" newpcb uc_link=%p, uc_stack.ss_sp=%p, " | |
236 | "uc_stack.ss_size=%d\n", | 236 | "uc_stack.ss_size=%d\n", | |
237 | newpcb->pcb_ucp.uc_link, | 237 | newpcb->pcb_ucp.uc_link, | |
238 | newpcb->pcb_ucp.uc_stack.ss_sp, | 238 | newpcb->pcb_ucp.uc_stack.ss_sp, | |
239 | (int)newpcb->pcb_ucp.uc_stack.ss_size); | 239 | (int)newpcb->pcb_ucp.uc_stack.ss_size); | |
240 | } | 240 | } | |
241 | #endif /* !CPU_DEBUG */ | 241 | #endif /* !CPU_DEBUG */ | |
242 | 242 | |||
243 | /* create atomic switcher */ | 243 | /* create atomic switcher */ | |
244 | thunk_makecontext(&sc->sc_ucp, (void (*)(void)) cpu_switchto_atomic, | 244 | thunk_makecontext(&sc->sc_ucp, (void (*)(void)) cpu_switchto_atomic, | |
245 | 2, oldlwp, newlwp, NULL); | 245 | 2, oldlwp, newlwp, NULL); | |
246 | 246 | |||
247 | if (!oldpcb) { | 247 | KASSERT(sc); | |
248 | thunk_setcontext(&sc->sc_ucp); | 248 | if (oldpcb) { | |
249 | /* never returns */ | |||
250 | } else { | |||
251 | thunk_swapcontext(&oldpcb->pcb_ucp, &sc->sc_ucp); | 249 | thunk_swapcontext(&oldpcb->pcb_ucp, &sc->sc_ucp); | |
252 | /* returns here */ | 250 | /* returns here */ | |
251 | } else { | |||
252 | thunk_setcontext(&sc->sc_ucp); | |||
253 | /* never returns */ | |||
253 | } | 254 | } | |
254 | 255 | |||
255 | #ifdef CPU_DEBUG | 256 | #ifdef CPU_DEBUG | |
256 | thunk_printf_debug("cpu_switchto: returning %p (was %p)\n", ci->ci_stash, oldlwp); | 257 | thunk_printf_debug("cpu_switchto: returning %p (was %p)\n", ci->ci_stash, oldlwp); | |
257 | #endif | 258 | #endif | |
258 | return ci->ci_stash; | 259 | return ci->ci_stash; | |
259 | } | 260 | } | |
260 | 261 | |||
261 | void | 262 | void | |
262 | cpu_dumpconf(void) | 263 | cpu_dumpconf(void) | |
263 | { | 264 | { | |
264 | #ifdef CPU_DEBUG | 265 | #ifdef CPU_DEBUG | |
265 | thunk_printf_debug("cpu_dumpconf\n"); | 266 | thunk_printf_debug("cpu_dumpconf\n"); | |
@@ -364,28 +365,30 @@ cpu_lwp_fork(struct lwp *l1, struct lwp | @@ -364,28 +365,30 @@ cpu_lwp_fork(struct lwp *l1, struct lwp | |||
364 | /* copy the PCB and its switchframes from parent */ | 365 | /* copy the PCB and its switchframes from parent */ | |
365 | memcpy(pcb2, pcb1, sizeof(struct pcb)); | 366 | memcpy(pcb2, pcb1, sizeof(struct pcb)); | |
366 | 367 | |||
367 | /* refresh context */ | 368 | /* refresh context */ | |
368 | if (thunk_getcontext(&pcb2->pcb_ucp)) | 369 | if (thunk_getcontext(&pcb2->pcb_ucp)) | |
369 | panic("getcontext failed"); | 370 | panic("getcontext failed"); | |
370 | 371 | |||
371 | /* recalculate the system stack top */ | 372 | /* recalculate the system stack top */ | |
372 | pcb2->sys_stack_top = pcb2->sys_stack + TRAPSTACKSIZE; | 373 | pcb2->sys_stack_top = pcb2->sys_stack + TRAPSTACKSIZE; | |
373 | 374 | |||
374 | /* get l2 its own stack */ | 375 | /* get l2 its own stack */ | |
375 | pcb2->pcb_ucp.uc_stack.ss_sp = pcb2->sys_stack; | 376 | pcb2->pcb_ucp.uc_stack.ss_sp = pcb2->sys_stack; | |
376 | pcb2->pcb_ucp.uc_stack.ss_size = pcb2->sys_stack_top - pcb2->sys_stack; | 377 | pcb2->pcb_ucp.uc_stack.ss_size = pcb2->sys_stack_top - pcb2->sys_stack; | |
377 | pcb2->pcb_ucp.uc_flags = _UC_STACK | _UC_CPU | _UC_SIGMASK; | |||
378 | pcb2->pcb_ucp.uc_link = &pcb2->pcb_userret_ucp; | 378 | pcb2->pcb_ucp.uc_link = &pcb2->pcb_userret_ucp; | |
379 | ||||
380 | thunk_sigemptyset(&pcb2->pcb_ucp.uc_sigmask); | |||
381 | pcb2->pcb_ucp.uc_flags = _UC_STACK | _UC_CPU | _UC_SIGMASK; | |||
379 | thunk_makecontext(&pcb2->pcb_ucp, | 382 | thunk_makecontext(&pcb2->pcb_ucp, | |
380 | (void (*)(void)) cpu_lwp_trampoline, | 383 | (void (*)(void)) cpu_lwp_trampoline, | |
381 | 3, &pcb2->pcb_ucp, func, arg); | 384 | 3, &pcb2->pcb_ucp, func, arg); | |
382 | } | 385 | } | |
383 | 386 | |||
384 | void | 387 | void | |
385 | cpu_initclocks(void) | 388 | cpu_initclocks(void) | |
386 | { | 389 | { | |
387 | extern timer_t clock_timerid; | 390 | extern timer_t clock_timerid; | |
388 | 391 | |||
389 | thunk_timer_start(clock_timerid, HZ); | 392 | thunk_timer_start(clock_timerid, HZ); | |
390 | } | 393 | } | |
391 | 394 | |||
@@ -402,27 +405,29 @@ cpu_startup(void) | @@ -402,27 +405,29 @@ cpu_startup(void) | |||
402 | initmsgbuf(um_msgbuf, msgbufsize); | 405 | initmsgbuf(um_msgbuf, msgbufsize); | |
403 | 406 | |||
404 | /* allocate a submap for physio, 1Mb enough? */ | 407 | /* allocate a submap for physio, 1Mb enough? */ | |
405 | minaddr = 0; | 408 | minaddr = 0; | |
406 | phys_map = uvm_km_suballoc(kernel_map, &minaddr, &maxaddr, | 409 | phys_map = uvm_km_suballoc(kernel_map, &minaddr, &maxaddr, | |
407 | 1024 * 1024, 0, false, NULL); | 410 | 1024 * 1024, 0, false, NULL); | |
408 | 411 | |||
409 | /* say hi! */ | 412 | /* say hi! */ | |
410 | banner(); | 413 | banner(); | |
411 | 414 | |||
412 | /* init lwp0 */ | 415 | /* init lwp0 */ | |
413 | memset(&lwp0pcb, 0, sizeof(lwp0pcb)); | 416 | memset(&lwp0pcb, 0, sizeof(lwp0pcb)); | |
414 | thunk_getcontext(&lwp0pcb.pcb_ucp); | 417 | thunk_getcontext(&lwp0pcb.pcb_ucp); | |
418 | thunk_sigemptyset(&lwp0pcb.pcb_ucp.uc_sigmask); | |||
415 | lwp0pcb.pcb_ucp.uc_flags = _UC_STACK | _UC_CPU | _UC_SIGMASK; | 419 | lwp0pcb.pcb_ucp.uc_flags = _UC_STACK | _UC_CPU | _UC_SIGMASK; | |
420 | ||||
416 | uvm_lwp_setuarea(&lwp0, (vaddr_t) &lwp0pcb); | 421 | uvm_lwp_setuarea(&lwp0, (vaddr_t) &lwp0pcb); | |
417 | memcpy(&lwp0pcb.pcb_userret_ucp, &lwp0pcb.pcb_ucp, sizeof(ucontext_t)); | 422 | memcpy(&lwp0pcb.pcb_userret_ucp, &lwp0pcb.pcb_ucp, sizeof(ucontext_t)); | |
418 | 423 | |||
419 | /* set stack top */ | 424 | /* set stack top */ | |
420 | lwp0pcb.sys_stack_top = lwp0pcb.sys_stack + TRAPSTACKSIZE; | 425 | lwp0pcb.sys_stack_top = lwp0pcb.sys_stack + TRAPSTACKSIZE; | |
421 | } | 426 | } | |
422 | 427 | |||
423 | void | 428 | void | |
424 | cpu_rootconf(void) | 429 | cpu_rootconf(void) | |
425 | { | 430 | { | |
426 | extern char *usermode_root_device; | 431 | extern char *usermode_root_device; | |
427 | device_t rdev; | 432 | device_t rdev; | |
428 | 433 |
--- src/sys/arch/usermode/dev/if_veth.c 2012/01/15 10:51:12 1.4
+++ src/sys/arch/usermode/dev/if_veth.c 2012/01/21 22:09:56 1.5
@@ -1,14 +1,14 @@ | @@ -1,14 +1,14 @@ | |||
1 | /* $NetBSD: if_veth.c,v 1.4 2012/01/15 10:51:12 jmcneill Exp $ */ | 1 | /* $NetBSD: if_veth.c,v 1.5 2012/01/21 22:09:56 reinoud Exp $ */ | |
2 | 2 | |||
3 | /*- | 3 | /*- | |
4 | * Copyright (c) 2011 Jared D. McNeill <jmcneill@invisible.ca> | 4 | * Copyright (c) 2011 Jared D. McNeill <jmcneill@invisible.ca> | |
5 | * All rights reserved. | 5 | * All rights reserved. | |
6 | * | 6 | * | |
7 | * Redistribution and use in source and binary forms, with or without | 7 | * Redistribution and use in source and binary forms, with or without | |
8 | * modification, are permitted provided that the following conditions | 8 | * modification, are permitted provided that the following conditions | |
9 | * are met: | 9 | * are met: | |
10 | * 1. Redistributions of source code must retain the above copyright | 10 | * 1. Redistributions of source code must retain the above copyright | |
11 | * notice, this list of conditions and the following disclaimer. | 11 | * notice, this list of conditions and the following disclaimer. | |
12 | * 2. Redistributions in binary form must reproduce the above copyright | 12 | * 2. Redistributions in binary form must reproduce the above copyright | |
13 | * notice, this list of conditions and the following disclaimer in the | 13 | * notice, this list of conditions and the following disclaimer in the | |
14 | * documentation and/or other materials provided with the distribution. | 14 | * documentation and/or other materials provided with the distribution. | |
@@ -17,27 +17,27 @@ | @@ -17,27 +17,27 @@ | |||
17 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED | 17 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED | |
18 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | 18 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | |
19 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS | 19 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS | |
20 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | 20 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | |
21 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | 21 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | |
22 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | 22 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |
23 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | 23 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | |
24 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | 24 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | |
25 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | 25 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | |
26 | * POSSIBILITY OF SUCH DAMAGE. | 26 | * POSSIBILITY OF SUCH DAMAGE. | |
27 | */ | 27 | */ | |
28 | 28 | |||
29 | #include <sys/cdefs.h> | 29 | #include <sys/cdefs.h> | |
30 | __KERNEL_RCSID(0, "$NetBSD: if_veth.c,v 1.4 2012/01/15 10:51:12 jmcneill Exp $"); | 30 | __KERNEL_RCSID(0, "$NetBSD: if_veth.c,v 1.5 2012/01/21 22:09:56 reinoud Exp $"); | |
31 | 31 | |||
32 | #include <sys/param.h> | 32 | #include <sys/param.h> | |
33 | #include <sys/proc.h> | 33 | #include <sys/proc.h> | |
34 | #include <sys/systm.h> | 34 | #include <sys/systm.h> | |
35 | #include <sys/kernel.h> | 35 | #include <sys/kernel.h> | |
36 | #include <sys/mbuf.h> | 36 | #include <sys/mbuf.h> | |
37 | #include <sys/socket.h> | 37 | #include <sys/socket.h> | |
38 | #include <sys/device.h> | 38 | #include <sys/device.h> | |
39 | 39 | |||
40 | #include <net/if.h> | 40 | #include <net/if.h> | |
41 | #include <net/if_ether.h> | 41 | #include <net/if_ether.h> | |
42 | #include <net/if_media.h> | 42 | #include <net/if_media.h> | |
43 | 43 | |||
@@ -179,30 +179,27 @@ veth_init(struct ifnet *ifp) | @@ -179,30 +179,27 @@ veth_init(struct ifnet *ifp) | |||
179 | veth_stop(ifp, 0); | 179 | veth_stop(ifp, 0); | |
180 | 180 | |||
181 | ifp->if_flags |= IFF_RUNNING; | 181 | ifp->if_flags |= IFF_RUNNING; | |
182 | ifp->if_flags &= ~IFF_OACTIVE; | 182 | ifp->if_flags &= ~IFF_OACTIVE; | |
183 | 183 | |||
184 | return 0; | 184 | return 0; | |
185 | } | 185 | } | |
186 | 186 | |||
187 | static int | 187 | static int | |
188 | veth_rx(void *priv) | 188 | veth_rx(void *priv) | |
189 | { | 189 | { | |
190 | struct veth_softc *sc = priv; | 190 | struct veth_softc *sc = priv; | |
191 | 191 | |||
192 | curcpu()->ci_idepth++; | 192 | softint_schedule(sc->sc_rx_intr); | |
193 | spl_intr(IPL_NET, softint_schedule, sc->sc_rx_intr); | |||
194 | curcpu()->ci_idepth--; | |||
195 | ||||
196 | return 0; | 193 | return 0; | |
197 | } | 194 | } | |
198 | 195 | |||
199 | static void | 196 | static void | |
200 | veth_softrx(void *priv) | 197 | veth_softrx(void *priv) | |
201 | { | 198 | { | |
202 | struct veth_softc *sc = priv; | 199 | struct veth_softc *sc = priv; | |
203 | struct ifnet *ifp = &sc->sc_ec.ec_if; | 200 | struct ifnet *ifp = &sc->sc_ec.ec_if; | |
204 | struct mbuf *m; | 201 | struct mbuf *m; | |
205 | ssize_t len; | 202 | ssize_t len; | |
206 | int s, avail; | 203 | int s, avail; | |
207 | 204 | |||
208 | for (;;) { | 205 | for (;;) { |
--- src/sys/arch/usermode/dev/ld_thunkbus.c 2012/01/09 21:01:31 1.29
+++ src/sys/arch/usermode/dev/ld_thunkbus.c 2012/01/21 22:09:57 1.30
@@ -1,14 +1,14 @@ | @@ -1,14 +1,14 @@ | |||
1 | /* $NetBSD: ld_thunkbus.c,v 1.29 2012/01/09 21:01:31 reinoud Exp $ */ | 1 | /* $NetBSD: ld_thunkbus.c,v 1.30 2012/01/21 22:09:57 reinoud Exp $ */ | |
2 | 2 | |||
3 | /*- | 3 | /*- | |
4 | * Copyright (c) 2011 Jared D. McNeill <jmcneill@invisible.ca> | 4 | * Copyright (c) 2011 Jared D. McNeill <jmcneill@invisible.ca> | |
5 | * All rights reserved. | 5 | * All rights reserved. | |
6 | * | 6 | * | |
7 | * Redistribution and use in source and binary forms, with or without | 7 | * Redistribution and use in source and binary forms, with or without | |
8 | * modification, are permitted provided that the following conditions | 8 | * modification, are permitted provided that the following conditions | |
9 | * are met: | 9 | * are met: | |
10 | * 1. Redistributions of source code must retain the above copyright | 10 | * 1. Redistributions of source code must retain the above copyright | |
11 | * notice, this list of conditions and the following disclaimer. | 11 | * notice, this list of conditions and the following disclaimer. | |
12 | * 2. Redistributions in binary form must reproduce the above copyright | 12 | * 2. Redistributions in binary form must reproduce the above copyright | |
13 | * notice, this list of conditions and the following disclaimer in the | 13 | * notice, this list of conditions and the following disclaimer in the | |
14 | * documentation and/or other materials provided with the distribution. | 14 | * documentation and/or other materials provided with the distribution. | |
@@ -17,27 +17,27 @@ | @@ -17,27 +17,27 @@ | |||
17 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED | 17 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED | |
18 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | 18 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | |
19 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS | 19 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS | |
20 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | 20 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | |
21 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | 21 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | |
22 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | 22 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |
23 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | 23 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | |
24 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | 24 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | |
25 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | 25 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | |
26 | * POSSIBILITY OF SUCH DAMAGE. | 26 | * POSSIBILITY OF SUCH DAMAGE. | |
27 | */ | 27 | */ | |
28 | 28 | |||
29 | #include <sys/cdefs.h> | 29 | #include <sys/cdefs.h> | |
30 | __KERNEL_RCSID(0, "$NetBSD: ld_thunkbus.c,v 1.29 2012/01/09 21:01:31 reinoud Exp $"); | 30 | __KERNEL_RCSID(0, "$NetBSD: ld_thunkbus.c,v 1.30 2012/01/21 22:09:57 reinoud Exp $"); | |
31 | 31 | |||
32 | #include <sys/param.h> | 32 | #include <sys/param.h> | |
33 | #include <sys/proc.h> | 33 | #include <sys/proc.h> | |
34 | #include <sys/systm.h> | 34 | #include <sys/systm.h> | |
35 | #include <sys/device.h> | 35 | #include <sys/device.h> | |
36 | #include <sys/buf.h> | 36 | #include <sys/buf.h> | |
37 | #include <sys/disk.h> | 37 | #include <sys/disk.h> | |
38 | #include <sys/kmem.h> | 38 | #include <sys/kmem.h> | |
39 | 39 | |||
40 | #include <dev/ldvar.h> | 40 | #include <dev/ldvar.h> | |
41 | 41 | |||
42 | #include <machine/mainbus.h> | 42 | #include <machine/mainbus.h> | |
43 | #include <machine/thunk.h> | 43 | #include <machine/thunk.h> | |
@@ -135,29 +135,27 @@ ld_thunkbus_attach(device_t parent, devi | @@ -135,29 +135,27 @@ ld_thunkbus_attach(device_t parent, devi | |||
135 | 135 | |||
136 | sc->busy = false; | 136 | sc->busy = false; | |
137 | 137 | |||
138 | ldattach(ld); | 138 | ldattach(ld); | |
139 | } | 139 | } | |
140 | 140 | |||
141 | #ifdef LD_USE_AIO | 141 | #ifdef LD_USE_AIO | |
142 | static int | 142 | static int | |
143 | ld_aio_sig(void *arg) | 143 | ld_aio_sig(void *arg) | |
144 | { | 144 | { | |
145 | struct ld_softc *ld = arg; | 145 | struct ld_softc *ld = arg; | |
146 | struct ld_thunkbus_softc *sc = (struct ld_thunkbus_softc *)ld; | 146 | struct ld_thunkbus_softc *sc = (struct ld_thunkbus_softc *)ld; | |
147 | 147 | |||
148 | curcpu()->ci_idepth++; | 148 | softint_schedule(sc->sc_ih); | |
149 | spl_intr(IPL_BIO, softint_schedule, sc->sc_ih); | |||
150 | curcpu()->ci_idepth--; | |||
151 | 149 | |||
152 | return 0; | 150 | return 0; | |
153 | } | 151 | } | |
154 | 152 | |||
155 | static int | 153 | static int | |
156 | ld_thunkbus_ldstart(struct ld_softc *ld, struct buf *bp) | 154 | ld_thunkbus_ldstart(struct ld_softc *ld, struct buf *bp) | |
157 | { | 155 | { | |
158 | struct ld_thunkbus_softc *sc = (struct ld_thunkbus_softc *)ld; | 156 | struct ld_thunkbus_softc *sc = (struct ld_thunkbus_softc *)ld; | |
159 | struct ld_thunkbus_transfer *tt = &sc->sc_tt; | 157 | struct ld_thunkbus_transfer *tt = &sc->sc_tt; | |
160 | off_t offset = bp->b_rawblkno * ld->sc_secsize; | 158 | off_t offset = bp->b_rawblkno * ld->sc_secsize; | |
161 | off_t disksize = ld->sc_secsize * ld->sc_secperunit; | 159 | off_t disksize = ld->sc_secsize * ld->sc_secperunit; | |
162 | int error; | 160 | int error; | |
163 | 161 | |||
@@ -240,27 +238,27 @@ ld_thunkbus_complete(void *arg) | @@ -240,27 +238,27 @@ ld_thunkbus_complete(void *arg) | |||
240 | 238 | |||
241 | 239 | |||
242 | static int | 240 | static int | |
243 | ld_thunkbus_ldstart(struct ld_softc *ld, struct buf *bp) | 241 | ld_thunkbus_ldstart(struct ld_softc *ld, struct buf *bp) | |
244 | { | 242 | { | |
245 | struct ld_thunkbus_softc *sc = (struct ld_thunkbus_softc *)ld; | 243 | struct ld_thunkbus_softc *sc = (struct ld_thunkbus_softc *)ld; | |
246 | struct ld_thunkbus_transfer *tt = &sc->sc_tt; | 244 | struct ld_thunkbus_transfer *tt = &sc->sc_tt; | |
247 | 245 | |||
248 | tt->tt_sc = sc; | 246 | tt->tt_sc = sc; | |
249 | tt->tt_bp = bp; | 247 | tt->tt_bp = bp; | |
250 | 248 | |||
251 | /* let the softint do the work */ | 249 | /* let the softint do the work */ | |
252 | sc->busy = true; | 250 | sc->busy = true; | |
253 | spl_intr(IPL_BIO, softint_schedule, sc->sc_ih); | 251 | softint_schedule(sc->sc_ih); | |
254 | 252 | |||
255 | return 0; | 253 | return 0; | |
256 | } | 254 | } | |
257 | 255 | |||
258 | static void | 256 | static void | |
259 | ld_thunkbus_complete(void *arg) | 257 | ld_thunkbus_complete(void *arg) | |
260 | { | 258 | { | |
261 | struct ld_softc *ld = arg; | 259 | struct ld_softc *ld = arg; | |
262 | struct ld_thunkbus_softc *sc = (struct ld_thunkbus_softc *)ld; | 260 | struct ld_thunkbus_softc *sc = (struct ld_thunkbus_softc *)ld; | |
263 | struct ld_thunkbus_transfer *tt = &sc->sc_tt; | 261 | struct ld_thunkbus_transfer *tt = &sc->sc_tt; | |
264 | struct buf *bp = tt->tt_bp; | 262 | struct buf *bp = tt->tt_bp; | |
265 | off_t offset = bp->b_rawblkno * ld->sc_secsize; | 263 | off_t offset = bp->b_rawblkno * ld->sc_secsize; | |
266 | int64_t ret; | 264 | int64_t ret; |
--- src/sys/arch/usermode/dev/ttycons.c 2011/12/27 20:59:45 1.17
+++ src/sys/arch/usermode/dev/ttycons.c 2012/01/21 22:09:57 1.18
@@ -1,14 +1,14 @@ | @@ -1,14 +1,14 @@ | |||
1 | /* $NetBSD: ttycons.c,v 1.17 2011/12/27 20:59:45 jmcneill Exp $ */ | 1 | /* $NetBSD: ttycons.c,v 1.18 2012/01/21 22:09:57 reinoud Exp $ */ | |
2 | 2 | |||
3 | /*- | 3 | /*- | |
4 | * Copyright (c) 2007 Jared D. McNeill <jmcneill@invisible.ca> | 4 | * Copyright (c) 2007 Jared D. McNeill <jmcneill@invisible.ca> | |
5 | * All rights reserved. | 5 | * All rights reserved. | |
6 | * | 6 | * | |
7 | * Redistribution and use in source and binary forms, with or without | 7 | * Redistribution and use in source and binary forms, with or without | |
8 | * modification, are permitted provided that the following conditions | 8 | * modification, are permitted provided that the following conditions | |
9 | * are met: | 9 | * are met: | |
10 | * 1. Redistributions of source code must retain the above copyright | 10 | * 1. Redistributions of source code must retain the above copyright | |
11 | * notice, this list of conditions and the following disclaimer. | 11 | * notice, this list of conditions and the following disclaimer. | |
12 | * 2. Redistributions in binary form must reproduce the above copyright | 12 | * 2. Redistributions in binary form must reproduce the above copyright | |
13 | * notice, this list of conditions and the following disclaimer in the | 13 | * notice, this list of conditions and the following disclaimer in the | |
14 | * documentation and/or other materials provided with the distribution. | 14 | * documentation and/or other materials provided with the distribution. | |
@@ -17,27 +17,27 @@ | @@ -17,27 +17,27 @@ | |||
17 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED | 17 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED | |
18 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | 18 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | |
19 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS | 19 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS | |
20 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | 20 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | |
21 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | 21 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | |
22 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | 22 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |
23 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | 23 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | |
24 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | 24 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | |
25 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | 25 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | |
26 | * POSSIBILITY OF SUCH DAMAGE. | 26 | * POSSIBILITY OF SUCH DAMAGE. | |
27 | */ | 27 | */ | |
28 | 28 | |||
29 | #include <sys/cdefs.h> | 29 | #include <sys/cdefs.h> | |
30 | __KERNEL_RCSID(0, "$NetBSD: ttycons.c,v 1.17 2011/12/27 20:59:45 jmcneill Exp $"); | 30 | __KERNEL_RCSID(0, "$NetBSD: ttycons.c,v 1.18 2012/01/21 22:09:57 reinoud Exp $"); | |
31 | 31 | |||
32 | #include <sys/param.h> | 32 | #include <sys/param.h> | |
33 | #include <sys/conf.h> | 33 | #include <sys/conf.h> | |
34 | #include <sys/proc.h> | 34 | #include <sys/proc.h> | |
35 | #include <sys/systm.h> | 35 | #include <sys/systm.h> | |
36 | #include <sys/device.h> | 36 | #include <sys/device.h> | |
37 | #include <sys/kauth.h> | 37 | #include <sys/kauth.h> | |
38 | #include <sys/termios.h> | 38 | #include <sys/termios.h> | |
39 | #include <sys/tty.h> | 39 | #include <sys/tty.h> | |
40 | 40 | |||
41 | #include <dev/cons.h> | 41 | #include <dev/cons.h> | |
42 | 42 | |||
43 | #include <machine/mainbus.h> | 43 | #include <machine/mainbus.h> | |
@@ -93,29 +93,29 @@ const struct cdevsw ttycons_cdevsw = { | @@ -93,29 +93,29 @@ const struct cdevsw ttycons_cdevsw = { | |||
93 | .d_stop = ttycons_stop, | 93 | .d_stop = ttycons_stop, | |
94 | .d_tty = ttycons_tty, | 94 | .d_tty = ttycons_tty, | |
95 | .d_poll = ttycons_poll, | 95 | .d_poll = ttycons_poll, | |
96 | .d_kqfilter = ttykqfilter, | 96 | .d_kqfilter = ttykqfilter, | |
97 | .d_flag = D_TTY, | 97 | .d_flag = D_TTY, | |
98 | }; | 98 | }; | |
99 | 99 | |||
100 | static void ttycons_start(struct tty *); | 100 | static void ttycons_start(struct tty *); | |
101 | static int ttycons_param(struct tty *, struct termios *); | 101 | static int ttycons_param(struct tty *, struct termios *); | |
102 | 102 | |||
103 | static int ttycons_intr(void *); | 103 | static int ttycons_intr(void *); | |
104 | static void ttycons_softintr(void *); | 104 | static void ttycons_softintr(void *); | |
105 | 105 | |||
106 | static void ttycons_ctrlc(int); | 106 | static sigfunc_t ttycons_ctrlc; | |
107 | static void ttycons_softctrlc(void *); | 107 | static void ttycons_softctrlc(void *); | |
108 | static void ttycons_ctrlz(int); | 108 | static sigfunc_t ttycons_ctrlz; | |
109 | static void ttycons_softctrlz(void *); | 109 | static void ttycons_softctrlz(void *); | |
110 | 110 | |||
111 | static int | 111 | static int | |
112 | ttycons_match(device_t parent, cfdata_t match, void *opaque) | 112 | ttycons_match(device_t parent, cfdata_t match, void *opaque) | |
113 | { | 113 | { | |
114 | struct thunkbus_attach_args *taa = opaque; | 114 | struct thunkbus_attach_args *taa = opaque; | |
115 | 115 | |||
116 | if (taa->taa_type != THUNKBUS_TYPE_TTYCONS) | 116 | if (taa->taa_type != THUNKBUS_TYPE_TTYCONS) | |
117 | return 0; | 117 | return 0; | |
118 | 118 | |||
119 | return 1; | 119 | return 1; | |
120 | } | 120 | } | |
121 | 121 | |||
@@ -144,28 +144,29 @@ ttycons_attach(device_t parent, device_t | @@ -144,28 +144,29 @@ ttycons_attach(device_t parent, device_t | |||
144 | if (sc->sc_rd_sih == NULL) | 144 | if (sc->sc_rd_sih == NULL) | |
145 | panic("couldn't establish ttycons intr handler\n"); | 145 | panic("couldn't establish ttycons intr handler\n"); | |
146 | 146 | |||
147 | sc->sc_ctrlc_sih = softint_establish(SOFTINT_SERIAL, | 147 | sc->sc_ctrlc_sih = softint_establish(SOFTINT_SERIAL, | |
148 | ttycons_softctrlc, sc); | 148 | ttycons_softctrlc, sc); | |
149 | if (sc->sc_ctrlc_sih == NULL) | 149 | if (sc->sc_ctrlc_sih == NULL) | |
150 | panic("couldn't establish ttycons ctrlc handler\n"); | 150 | panic("couldn't establish ttycons ctrlc handler\n"); | |
151 | sc->sc_ctrlz_sih = softint_establish(SOFTINT_SERIAL, | 151 | sc->sc_ctrlz_sih = softint_establish(SOFTINT_SERIAL, | |
152 | ttycons_softctrlz, sc); | 152 | ttycons_softctrlz, sc); | |
153 | if (sc->sc_ctrlz_sih == NULL) | 153 | if (sc->sc_ctrlz_sih == NULL) | |
154 | panic("couldn't establish ttycons ctrlz handler\n"); | 154 | panic("couldn't establish ttycons ctrlz handler\n"); | |
155 | 155 | |||
156 | sigio_intr_establish(ttycons_intr, sc); | 156 | sigio_intr_establish(ttycons_intr, sc); | |
157 | thunk_signal(SIGINT, ttycons_ctrlc); | 157 | signal_intr_establish(SIGINT, ttycons_ctrlc); | |
158 | thunk_signal(SIGTSTP, ttycons_ctrlz); | 158 | signal_intr_establish(SIGTSTP, ttycons_ctrlz); | |
159 | ||||
159 | if (thunk_set_stdin_sigio(true) != 0) | 160 | if (thunk_set_stdin_sigio(true) != 0) | |
160 | panic("couldn't enable stdin async mode"); | 161 | panic("couldn't enable stdin async mode"); | |
161 | } | 162 | } | |
162 | 163 | |||
163 | void | 164 | void | |
164 | ttycons_consinit(void) | 165 | ttycons_consinit(void) | |
165 | { | 166 | { | |
166 | struct thunk_termios t; | 167 | struct thunk_termios t; | |
167 | 168 | |||
168 | thunk_tcgetattr(0, &t); | 169 | thunk_tcgetattr(0, &t); | |
169 | t.c_lflag &= ~(ECHO|ICANON); | 170 | t.c_lflag &= ~(ECHO|ICANON); | |
170 | t.c_cc[VTIME] = 0; | 171 | t.c_cc[VTIME] = 0; | |
171 | t.c_cc[VMIN] = 1; | 172 | t.c_cc[VMIN] = 1; | |
@@ -351,84 +352,86 @@ static int | @@ -351,84 +352,86 @@ static int | |||
351 | ttycons_param(struct tty *t, struct termios *c) | 352 | ttycons_param(struct tty *t, struct termios *c) | |
352 | { | 353 | { | |
353 | t->t_ispeed = c->c_ispeed; | 354 | t->t_ispeed = c->c_ispeed; | |
354 | t->t_ospeed = c->c_ospeed; | 355 | t->t_ospeed = c->c_ospeed; | |
355 | t->t_cflag = c->c_cflag; | 356 | t->t_cflag = c->c_cflag; | |
356 | return 0; | 357 | return 0; | |
357 | } | 358 | } | |
358 | 359 | |||
359 | static int | 360 | static int | |
360 | ttycons_intr(void *priv) | 361 | ttycons_intr(void *priv) | |
361 | { | 362 | { | |
362 | struct ttycons_softc *sc = priv; | 363 | struct ttycons_softc *sc = priv; | |
363 | 364 | |||
364 | curcpu()->ci_idepth++; | 365 | softint_schedule(sc->sc_rd_sih); | |
365 | spl_intr(IPL_SERIAL, softint_schedule, sc->sc_rd_sih); | |||
366 | curcpu()->ci_idepth--; | |||
367 | 366 | |||
368 | return 0; | 367 | return 0; | |
369 | } | 368 | } | |
370 | 369 | |||
371 | static void | 370 | static void | |
372 | ttycons_softintr(void *priv) | 371 | ttycons_softintr(void *priv) | |
373 | { | 372 | { | |
374 | struct ttycons_softc *sc = priv; | 373 | struct ttycons_softc *sc = priv; | |
375 | struct tty *t = sc->sc_tty; | 374 | struct tty *t = sc->sc_tty; | |
376 | unsigned char ch; | 375 | unsigned char ch; | |
377 | int c; | 376 | int c; | |
378 | 377 | |||
379 | while ((c = thunk_pollchar()) >= 0) { | 378 | while ((c = thunk_pollchar()) >= 0) { | |
380 | ch = (unsigned char)c; | 379 | ch = (unsigned char)c; | |
381 | cn_check_magic(t->t_dev, ch, ttycons_cnm_state); | 380 | cn_check_magic(t->t_dev, ch, ttycons_cnm_state); | |
382 | t->t_linesw->l_rint(ch, t); | 381 | t->t_linesw->l_rint(ch, t); | |
383 | } | 382 | } | |
384 | } | 383 | } | |
385 | 384 | |||
385 | ||||
386 | /* | |||
387 | * handle SIGINT signal from trap.c | |||
388 | * | |||
389 | * argument 'pc' and 'va' are not used. | |||
390 | */ | |||
386 | static void | 391 | static void | |
387 | ttycons_ctrlc(int sig) | 392 | ttycons_ctrlc(vaddr_t from_userland, vaddr_t pc, vaddr_t va) | |
388 | { | 393 | { | |
389 | struct ttycons_softc *sc; | 394 | struct ttycons_softc *sc; | |
390 | 395 | |||
391 | curcpu()->ci_idepth++; | |||
392 | sc = device_lookup_private(&ttycons_cd, minor(cn_tab->cn_dev)); | 396 | sc = device_lookup_private(&ttycons_cd, minor(cn_tab->cn_dev)); | |
393 | if (sc) { | 397 | if (sc) | |
394 | spl_intr(IPL_SERIAL, softint_schedule, sc->sc_ctrlc_sih); | 398 | softint_schedule(sc->sc_ctrlc_sih); | |
395 | } | |||
396 | curcpu()->ci_idepth--; | |||
397 | 399 | |||
398 | } | 400 | } | |
399 | 401 | |||
400 | static void | 402 | static void | |
401 | ttycons_softctrlc(void *priv) | 403 | ttycons_softctrlc(void *priv) | |
402 | { | 404 | { | |
403 | struct ttycons_softc *sc = priv; | 405 | struct ttycons_softc *sc = priv; | |
404 | struct tty *t = sc->sc_tty; | 406 | struct tty *t = sc->sc_tty; | |
405 | unsigned char ch = 3; /* ETX */ | 407 | unsigned char ch = 3; /* ETX */ | |
406 | 408 | |||
407 | cn_check_magic(t->t_dev, ch, ttycons_cnm_state); | 409 | cn_check_magic(t->t_dev, ch, ttycons_cnm_state); | |
408 | t->t_linesw->l_rint(ch, t); | 410 | t->t_linesw->l_rint(ch, t); | |
409 | } | 411 | } | |
410 | 412 | |||
413 | /* | |||
414 | * handle SIGTSTP signal from trap.c | |||
415 | * | |||
416 | * argument 'pc' and 'va' are not used. | |||
417 | */ | |||
411 | static void | 418 | static void | |
412 | ttycons_ctrlz(int sig) | 419 | ttycons_ctrlz(vaddr_t from_userland, vaddr_t pc, vaddr_t va) | |
413 | { | 420 | { | |
414 | struct ttycons_softc *sc; | 421 | struct ttycons_softc *sc; | |
415 | 422 | |||
416 | curcpu()->ci_idepth++; | |||
417 | sc = device_lookup_private(&ttycons_cd, minor(cn_tab->cn_dev)); | 423 | sc = device_lookup_private(&ttycons_cd, minor(cn_tab->cn_dev)); | |
418 | if (sc) { | 424 | if (sc) | |
419 | spl_intr(IPL_SERIAL, softint_schedule, sc->sc_ctrlz_sih); | 425 | softint_schedule(sc->sc_ctrlz_sih); | |
420 | } | |||
421 | curcpu()->ci_idepth--; | |||
422 | ||||
423 | } | 426 | } | |
424 | 427 | |||
425 | static void | 428 | static void | |
426 | ttycons_softctrlz(void *priv) | 429 | ttycons_softctrlz(void *priv) | |
427 | { | 430 | { | |
428 | struct ttycons_softc *sc = priv; | 431 | struct ttycons_softc *sc = priv; | |
429 | struct tty *t = sc->sc_tty; | 432 | struct tty *t = sc->sc_tty; | |
430 | unsigned char ch = 26; /* SUB */ | 433 | unsigned char ch = 26; /* SUB */ | |
431 | 434 | |||
432 | cn_check_magic(t->t_dev, ch, ttycons_cnm_state); | 435 | cn_check_magic(t->t_dev, ch, ttycons_cnm_state); | |
433 | t->t_linesw->l_rint(ch, t); | 436 | t->t_linesw->l_rint(ch, t); | |
434 | } | 437 | } |
--- src/sys/arch/usermode/include/intr.h 2011/12/26 22:04:35 1.6
+++ src/sys/arch/usermode/include/intr.h 2012/01/21 22:09:57 1.7
@@ -1,14 +1,14 @@ | @@ -1,14 +1,14 @@ | |||
1 | /* $NetBSD: intr.h,v 1.6 2011/12/26 22:04:35 jmcneill Exp $ */ | 1 | /* $NetBSD: intr.h,v 1.7 2012/01/21 22:09:57 reinoud Exp $ */ | |
2 | 2 | |||
3 | /*- | 3 | /*- | |
4 | * Copyright (c) 2007 Jared D. McNeill <jmcneill@invisible.ca> | 4 | * Copyright (c) 2007 Jared D. McNeill <jmcneill@invisible.ca> | |
5 | * All rights reserved. | 5 | * All rights reserved. | |
6 | * | 6 | * | |
7 | * Redistribution and use in source and binary forms, with or without | 7 | * Redistribution and use in source and binary forms, with or without | |
8 | * modification, are permitted provided that the following conditions | 8 | * modification, are permitted provided that the following conditions | |
9 | * are met: | 9 | * are met: | |
10 | * 1. Redistributions of source code must retain the above copyright | 10 | * 1. Redistributions of source code must retain the above copyright | |
11 | * notice, this list of conditions and the following disclaimer. | 11 | * notice, this list of conditions and the following disclaimer. | |
12 | * 2. Redistributions in binary form must reproduce the above copyright | 12 | * 2. Redistributions in binary form must reproduce the above copyright | |
13 | * notice, this list of conditions and the following disclaimer in the | 13 | * notice, this list of conditions and the following disclaimer in the | |
14 | * documentation and/or other materials provided with the distribution. | 14 | * documentation and/or other materials provided with the distribution. | |
@@ -22,44 +22,51 @@ | @@ -22,44 +22,51 @@ | |||
22 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | 22 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |
23 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | 23 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | |
24 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | 24 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | |
25 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | 25 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | |
26 | * POSSIBILITY OF SUCH DAMAGE. | 26 | * POSSIBILITY OF SUCH DAMAGE. | |
27 | */ | 27 | */ | |
28 | 28 | |||
29 | #ifndef _ARCH_USERMODE_INCLUDE_INTR_H | 29 | #ifndef _ARCH_USERMODE_INCLUDE_INTR_H | |
30 | #define _ARCH_USERMODE_INCLUDE_INTR_H | 30 | #define _ARCH_USERMODE_INCLUDE_INTR_H | |
31 | 31 | |||
32 | #include <machine/intrdefs.h> | 32 | #include <machine/intrdefs.h> | |
33 | #include <sys/siginfo.h> | 33 | #include <sys/siginfo.h> | |
34 | 34 | |||
35 | void sigio_signal_handler(int, siginfo_t *, void *); | 35 | /* spl */ | |
36 | void * sigio_intr_establish(int (*)(void *), void *); | |||
37 | ||||
38 | void splinit(void); | 36 | void splinit(void); | |
39 | int splraise(int); | 37 | int splraise(int); | |
40 | void spllower(int); | 38 | void spllower(int); | |
41 | void spl_intr(int x, void (*func)(void *), void *arg); | 39 | void spl_intr(int x, void (*func)(void *), void *arg); | |
42 | 40 | |||
43 | #define spl0() spllower(IPL_NONE) | 41 | #define spl0() spllower(IPL_NONE) | |
44 | #define splx(x) spllower(x) | 42 | #define splx(x) spllower(x) | |
45 | 43 | |||
44 | /* traps */ | |||
45 | typedef void (sigfunc_t)(vaddr_t from_userland, vaddr_t pc, vaddr_t va); | |||
46 | extern void setup_signal_handlers(void); | |||
47 | extern void signal_intr_establish(int sig, sigfunc_t f); | |||
48 | extern void *sigio_intr_establish(int (*)(void *), void *); | |||
49 | ||||
50 | /* spl implementation */ | |||
46 | typedef uint8_t ipl_t; | 51 | typedef uint8_t ipl_t; | |
47 | typedef struct { | 52 | typedef struct { | |
48 | ipl_t _ipl; | 53 | ipl_t _ipl; | |
49 | } ipl_cookie_t; | 54 | } ipl_cookie_t; | |
50 | 55 | |||
51 | static inline ipl_cookie_t | 56 | static inline ipl_cookie_t | |
52 | makeiplcookie(ipl_t ipl) | 57 | makeiplcookie(ipl_t ipl) | |
53 | { | 58 | { | |
54 | return (ipl_cookie_t){._ipl = ipl}; | 59 | return (ipl_cookie_t){._ipl = ipl}; | |
55 | } | 60 | } | |
56 | 61 | |||
57 | static inline int | 62 | static inline int | |
58 | splraiseipl(ipl_cookie_t icookie) | 63 | splraiseipl(ipl_cookie_t icookie) | |
59 | { | 64 | { | |
60 | return splraise(icookie._ipl); | 65 | return splraise(icookie._ipl); | |
61 | } | 66 | } | |
62 | 67 | |||
63 | #include <sys/spl.h> | 68 | #include <sys/spl.h> | |
64 | 69 | |||
70 | /* for trap.c */ | |||
71 | ||||
65 | #endif /* !_ARCH_USERMODE_INCLUDE_INTR_H */ | 72 | #endif /* !_ARCH_USERMODE_INCLUDE_INTR_H */ |
--- src/sys/arch/usermode/usermode/intr.c 2012/01/09 22:20:53 1.14
+++ src/sys/arch/usermode/usermode/intr.c 2012/01/21 22:09:57 1.15
@@ -1,14 +1,14 @@ | @@ -1,14 +1,14 @@ | |||
1 | /* $NetBSD: intr.c,v 1.14 2012/01/09 22:20:53 reinoud Exp $ */ | 1 | /* $NetBSD: intr.c,v 1.15 2012/01/21 22:09:57 reinoud Exp $ */ | |
2 | 2 | |||
3 | /*- | 3 | /*- | |
4 | * Copyright (c) 2011 Jared D. McNeill <jmcneill@invisible.ca> | 4 | * Copyright (c) 2011 Jared D. McNeill <jmcneill@invisible.ca> | |
5 | * All rights reserved. | 5 | * All rights reserved. | |
6 | * | 6 | * | |
7 | * Redistribution and use in source and binary forms, with or without | 7 | * Redistribution and use in source and binary forms, with or without | |
8 | * modification, are permitted provided that the following conditions | 8 | * modification, are permitted provided that the following conditions | |
9 | * are met: | 9 | * are met: | |
10 | * 1. Redistributions of source code must retain the above copyright | 10 | * 1. Redistributions of source code must retain the above copyright | |
11 | * notice, this list of conditions and the following disclaimer. | 11 | * notice, this list of conditions and the following disclaimer. | |
12 | * 2. Redistributions in binary form must reproduce the above copyright | 12 | * 2. Redistributions in binary form must reproduce the above copyright | |
13 | * notice, this list of conditions and the following disclaimer in the | 13 | * notice, this list of conditions and the following disclaimer in the | |
14 | * documentation and/or other materials provided with the distribution. | 14 | * documentation and/or other materials provided with the distribution. | |
@@ -17,162 +17,46 @@ | @@ -17,162 +17,46 @@ | |||
17 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED | 17 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED | |
18 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | 18 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | |
19 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS | 19 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS | |
20 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | 20 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | |
21 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | 21 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | |
22 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | 22 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |
23 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | 23 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | |
24 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | 24 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | |
25 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | 25 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | |
26 | * POSSIBILITY OF SUCH DAMAGE. | 26 | * POSSIBILITY OF SUCH DAMAGE. | |
27 | */ | 27 | */ | |
28 | 28 | |||
29 | #include <sys/cdefs.h> | 29 | #include <sys/cdefs.h> | |
30 | __KERNEL_RCSID(0, "$NetBSD: intr.c,v 1.14 2012/01/09 22:20:53 reinoud Exp $"); | 30 | __KERNEL_RCSID(0, "$NetBSD: intr.c,v 1.15 2012/01/21 22:09:57 reinoud Exp $"); | |
31 | 31 | |||
32 | #include <sys/types.h> | 32 | #include <sys/types.h> | |
33 | 33 | |||
34 | #include <machine/intr.h> | 34 | #include <machine/intr.h> | |
35 | #include <machine/thunk.h> | 35 | #include <machine/thunk.h> | |
36 | 36 | |||
37 | struct intr_handler { | 37 | int usermode_x = IPL_NONE; | |
38 | int (*func)(void *); | |||
39 | void *arg; | |||
40 | }; | |||
41 | ||||
42 | #define SIGIO_MAX_HANDLERS 8 | |||
43 | ||||
44 | static struct intr_handler sigio_intr_handler[SIGIO_MAX_HANDLERS]; | |||
45 | ||||
46 | //#define INTR_USE_SIGPROCMASK | |||
47 | ||||
48 | #define MAX_QUEUED_EVENTS 128 | |||
49 | ||||
50 | static int usermode_x = IPL_NONE; | |||
51 | ||||
52 | #ifdef INTR_USE_SIGPROCMASK | |||
53 | static bool block_sigalrm = false; | |||
54 | #endif | |||
55 | ||||
56 | ||||
57 | struct spl_intr_event { | |||
58 | void (*func)(void *); | |||
59 | void *arg; | |||
60 | }; | |||
61 | ||||
62 | struct spl_intr_event spl_intrs[IPL_HIGH+1][MAX_QUEUED_EVENTS]; | |||
63 | int spl_intr_wr[IPL_HIGH+1]; | |||
64 | int spl_intr_rd[IPL_HIGH+1]; | |||
65 | 38 | |||
66 | void | 39 | void | |
67 | splinit(void) | 40 | splinit(void) | |
68 | { | 41 | { | |
69 | int i; | 42 | /* nothing */ | |
70 | for (i = 0; i <= IPL_HIGH; i++) { | |||
71 | spl_intr_rd[i] = 1; | |||
72 | spl_intr_wr[i] = 1; | |||
73 | } | |||
74 | } | |||
75 | ||||
76 | void | |||
77 | spl_intr(int x, void (*func)(void *), void *arg) | |||
78 | { | |||
79 | struct spl_intr_event *spli; | |||
80 | ||||
81 | if (x >= usermode_x) { | |||
82 | func(arg); | |||
83 | return; | |||
84 | } | |||
85 | ||||
86 | // dprintf_debug("spl_intr: queue %d when %d\n", x, usermode_x); | |||
87 | spli = &spl_intrs[x][spl_intr_wr[x]]; | |||
88 | spli->func = func; | |||
89 | spli->arg = arg; | |||
90 | ||||
91 | spl_intr_wr[x] = (spl_intr_wr[x] + 1) % MAX_QUEUED_EVENTS; | |||
92 | if (spl_intr_wr[x] == spl_intr_rd[x]) { | |||
93 | thunk_printf("%s: spl list %d full!\n", __func__, x); | |||
94 | panic("%s: spl list %d full!\n", __func__, x); | |||
95 | } | |||
96 | } | 43 | } | |
97 | 44 | |||
98 | int | 45 | int | |
99 | splraise(int x) | 46 | splraise(int x) | |
100 | { | 47 | { | |
101 | int oldx = usermode_x; | 48 | int oldx = usermode_x; | |
102 | 49 | |||
103 | if (x > usermode_x) { | 50 | if (x > usermode_x) | |
104 | usermode_x = x; | 51 | usermode_x = x; | |
105 | } | |||
106 | ||||
107 | #ifdef INTR_USE_SIGPROCMASK | |||
108 | if (x >= IPL_SCHED && !block_sigalrm) { | |||
109 | thunk_sigblock(SIGALRM); | |||
110 | block_sigalrm = true; | |||
111 | } | |||
112 | #endif | |||
113 | 52 | |||
114 | return oldx; | 53 | return oldx; | |
115 | } | 54 | } | |
116 | 55 | |||
117 | void | 56 | void | |
118 | spllower(int x) | 57 | spllower(int x) | |
119 | { | 58 | { | |
120 | struct spl_intr_event *spli; | 59 | if (usermode_x > x) | |
121 | int y; | |||
122 | ||||
123 | /* `eat' interrupts that came by until we got back to x */ | |||
124 | if (usermode_x > x) { | |||
125 | //restart: | |||
126 | for (y = usermode_x; y >= x; y--) { | |||
127 | while (spl_intr_rd[y] != spl_intr_wr[y]) { | |||
128 | // dprintf_debug("spl y %d firing\n", y); | |||
129 | spli = &spl_intrs[y][spl_intr_rd[y]]; | |||
130 | if (!spli->func) | |||
131 | panic("%s: spli->func is NULL for ipl %d, rd %d, wr %d\n", | |||
132 | __func__, y, spl_intr_rd[y], spl_intr_wr[y]); | |||
133 | spli->func(spli->arg); | |||
134 | spl_intr_rd[y] = (spl_intr_rd[y] + 1) % MAX_QUEUED_EVENTS; | |||
135 | // goto restart; | |||
136 | } | |||
137 | } | |||
138 | usermode_x = x; | 60 | usermode_x = x; | |
139 | } | |||
140 | ||||
141 | #ifdef INTR_USE_SIGPROCMASK | |||
142 | if (x < IPL_SCHED && block_sigalrm) { | |||
143 | thunk_sigunblock(SIGALRM); | |||
144 | block_sigalrm = false; | |||
145 | } | |||
146 | #endif | |||
147 | } | 61 | } | |
148 | 62 | |||
149 | void | |||
150 | sigio_signal_handler(int sig, siginfo_t *info, void *ctx) | |||
151 | { | |||
152 | struct intr_handler *sih; | |||
153 | unsigned int n; | |||
154 | ||||
155 | for (n = 0; n < SIGIO_MAX_HANDLERS; n++) { | |||
156 | sih = &sigio_intr_handler[n]; | |||
157 | if (sih->func) | |||
158 | sih->func(sih->arg); | |||
159 | } | |||
160 | } | |||
161 | ||||
162 | void * | |||
163 | sigio_intr_establish(int (*func)(void *), void *arg) | |||
164 | { | |||
165 | struct intr_handler *sih; | |||
166 | unsigned int n; | |||
167 | ||||
168 | for (n = 0; n < SIGIO_MAX_HANDLERS; n++) { | |||
169 | sih = &sigio_intr_handler[n]; | |||
170 | if (sih->func == NULL) { | |||
171 | sih->func = func; | |||
172 | sih->arg = arg; | |||
173 | return sih; | |||
174 | } | |||
175 | } | |||
176 | ||||
177 | panic("increase SIGIO_MAX_HANDLERS"); | |||
178 | } |
--- src/sys/arch/usermode/usermode/trap.c 2012/01/18 12:39:45 1.60
+++ src/sys/arch/usermode/usermode/trap.c 2012/01/21 22:09:57 1.61
@@ -1,14 +1,14 @@ | @@ -1,14 +1,14 @@ | |||
1 | /* $NetBSD: trap.c,v 1.60 2012/01/18 12:39:45 reinoud Exp $ */ | 1 | /* $NetBSD: trap.c,v 1.61 2012/01/21 22:09:57 reinoud Exp $ */ | |
2 | 2 | |||
3 | /*- | 3 | /*- | |
4 | * Copyright (c) 2011 Reinoud Zandijk <reinoud@netbsd.org> | 4 | * Copyright (c) 2011 Reinoud Zandijk <reinoud@netbsd.org> | |
5 | * All rights reserved. | 5 | * All rights reserved. | |
6 | * | 6 | * | |
7 | * Redistribution and use in source and binary forms, with or without | 7 | * Redistribution and use in source and binary forms, with or without | |
8 | * modification, are permitted provided that the following conditions | 8 | * modification, are permitted provided that the following conditions | |
9 | * are met: | 9 | * are met: | |
10 | * 1. Redistributions of source code must retain the above copyright | 10 | * 1. Redistributions of source code must retain the above copyright | |
11 | * notice, this list of conditions and the following disclaimer. | 11 | * notice, this list of conditions and the following disclaimer. | |
12 | * 2. Redistributions in binary form must reproduce the above copyright | 12 | * 2. Redistributions in binary form must reproduce the above copyright | |
13 | * notice, this list of conditions and the following disclaimer in the | 13 | * notice, this list of conditions and the following disclaimer in the | |
14 | * documentation and/or other materials provided with the distribution. | 14 | * documentation and/or other materials provided with the distribution. | |
@@ -17,142 +17,211 @@ | @@ -17,142 +17,211 @@ | |||
17 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED | 17 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED | |
18 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | 18 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | |
19 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS | 19 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS | |
20 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | 20 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | |
21 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | 21 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | |
22 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | 22 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |
23 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | 23 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | |
24 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | 24 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | |
25 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | 25 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | |
26 | * POSSIBILITY OF SUCH DAMAGE. | 26 | * POSSIBILITY OF SUCH DAMAGE. | |
27 | */ | 27 | */ | |
28 | 28 | |||
29 | #include <sys/cdefs.h> | 29 | #include <sys/cdefs.h> | |
30 | __KERNEL_RCSID(0, "$NetBSD: trap.c,v 1.60 2012/01/18 12:39:45 reinoud Exp $"); | 30 | __KERNEL_RCSID(0, "$NetBSD: trap.c,v 1.61 2012/01/21 22:09:57 reinoud Exp $"); | |
31 | 31 | |||
32 | #include <sys/types.h> | 32 | #include <sys/types.h> | |
33 | #include <sys/param.h> | 33 | #include <sys/param.h> | |
34 | #include <sys/systm.h> | 34 | #include <sys/systm.h> | |
35 | #include <sys/proc.h> | 35 | #include <sys/proc.h> | |
36 | #include <sys/systm.h> | 36 | #include <sys/systm.h> | |
37 | #include <sys/userret.h> | 37 | #include <sys/userret.h> | |
38 | #include <sys/kauth.h> | 38 | #include <sys/kauth.h> | |
39 | #include <sys/errno.h> | 39 | #include <sys/errno.h> | |
40 | 40 | |||
41 | #include <uvm/uvm_extern.h> | 41 | #include <uvm/uvm_extern.h> | |
42 | #include <machine/cpu.h> | 42 | #include <machine/cpu.h> | |
43 | #include <machine/pcb.h> | 43 | #include <machine/pcb.h> | |
44 | #include <machine/pmap.h> | 44 | #include <machine/pmap.h> | |
45 | #include <machine/machdep.h> | 45 | #include <machine/machdep.h> | |
46 | #include <machine/intr.h> | 46 | #include <machine/intr.h> | |
47 | #include <machine/thunk.h> | 47 | #include <machine/thunk.h> | |
48 | 48 | |||
49 | /* define maximum signal number */ | |||
50 | #ifndef NSIG | |||
51 | #define NSIG 64 | |||
52 | #endif | |||
49 | 53 | |||
50 | /* forwards and externals */ | 54 | /* forwards and externals */ | |
51 | void setup_signal_handlers(void); | 55 | void setup_signal_handlers(void); | |
52 | void stop_all_signal_handlers(void); | 56 | void stop_all_signal_handlers(void); | |
53 | 57 | |||
54 | static void mem_access_handler(int sig, siginfo_t *info, void *ctx); | 58 | static sigfunc_t pagefault; | |
55 | static void illegal_instruction_handler(int sig, siginfo_t *info, void *ctx); | 59 | static sigfunc_t illegal_instruction; | |
56 | extern int errno; | 60 | static sigfunc_t alarm; | |
61 | static sigfunc_t sigio; | |||
62 | ||||
63 | /* raw signal handlers */ | |||
64 | static stack_t sigstk; | |||
65 | ucontext_t jump_ucp; | |||
57 | 66 | |||
58 | static void pagefault(vaddr_t from_userland, vaddr_t pc, vaddr_t va); | 67 | sigfunc_t *sig_funcs[NSIG]; | |
59 | static void illegal_instruction(vaddr_t from_userland); | |||
60 | 68 | |||
61 | bool pmap_fault(pmap_t pmap, vaddr_t va, vm_prot_t *atype); | 69 | /* segv, bus */ | |
70 | extern bool pmap_fault(pmap_t pmap, vaddr_t va, vm_prot_t *atype); | |||
62 | 71 | |||
63 | static stack_t sigstk; | 72 | /* alarm */ | |
73 | void setup_clock_intr(void); | |||
74 | extern void clock_intr(void *priv); | |||
64 | 75 | |||
76 | extern int clock_running; | |||
77 | void *alrm_ih; | |||
78 | ||||
79 | /* sigio handlers */ | |||
80 | struct intr_handler { | |||
81 | int (*func)(void *); | |||
82 | void *arg; | |||
83 | }; | |||
84 | #define SIGIO_MAX_HANDLERS 8 | |||
85 | static struct intr_handler sigio_intr_handler[SIGIO_MAX_HANDLERS]; | |||
86 | ||||
87 | /* misc */ | |||
65 | int astpending = 0; | 88 | int astpending = 0; | |
66 | 89 | |||
90 | ||||
91 | /* XXX why is it here ? */ | |||
67 | void | 92 | void | |
68 | startlwp(void *arg) | 93 | startlwp(void *arg) | |
69 | { | 94 | { | |
70 | /* nothing here */ | 95 | /* nothing here */ | |
71 | } | 96 | } | |
72 | 97 | |||
73 | 98 | |||
74 | void | 99 | void | |
75 | setup_signal_handlers(void) | 100 | setup_signal_handlers(void) | |
76 | { | 101 | { | |
77 | static struct sigaction sa; | 102 | int i; | |
78 | 103 | |||
104 | /* | |||
105 | * Set up the alternative signal stack. This prevents signals to be | |||
106 | * pushed on the NetBSD/usermode userland's stack with all desastrous | |||
107 | * effects. Especially ld.so and friends have such tiny stacks that | |||
108 | * its not feasable. | |||
109 | */ | |||
79 | if ((sigstk.ss_sp = thunk_malloc(SIGSTKSZ)) == NULL) | 110 | if ((sigstk.ss_sp = thunk_malloc(SIGSTKSZ)) == NULL) | |
80 | panic("can't allocate signal stack space\n"); | 111 | panic("can't allocate signal stack space\n"); | |
81 | sigstk.ss_size = SIGSTKSZ; | 112 | sigstk.ss_size = SIGSTKSZ; | |
82 | sigstk.ss_flags = 0; | 113 | sigstk.ss_flags = 0; | |
83 | if (thunk_sigaltstack(&sigstk, 0) < 0) | 114 | if (thunk_sigaltstack(&sigstk, 0) < 0) | |
84 | panic("can't set alternate stacksize: %d", | 115 | panic("can't set alternate stacksize: %d", | |
85 | thunk_geterrno()); | 116 | thunk_geterrno()); | |
86 | 117 | |||
87 | /* SIGBUS and SIGSEGV need to be reentrant hence the SA_NODEFER */ | 118 | for (i = 0; i < NSIG; i++) | |
88 | sa.sa_flags = SA_RESTART | SA_SIGINFO | SA_ONSTACK | SA_NODEFER; | 119 | sig_funcs[i] = NULL; | |
89 | sa.sa_sigaction = mem_access_handler; | |||
90 | thunk_sigemptyset(&sa.sa_mask); | |||
91 | if (thunk_sigaction(SIGSEGV, &sa, NULL) == -1) | |||
92 | panic("couldn't register SIGSEGV handler: %d", | |||
93 | thunk_geterrno()); | |||
94 | if (thunk_sigaction(SIGBUS, &sa, NULL) == -1) | |||
95 | panic("couldn't register SIGBUS handler: %d", thunk_geterrno()); | |||
96 | ||||
97 | sa.sa_flags = SA_RESTART | SA_SIGINFO | SA_ONSTACK; | |||
98 | sa.sa_sigaction = illegal_instruction_handler; | |||
99 | thunk_sigemptyset(&sa.sa_mask); | |||
100 | if (thunk_sigaction(SIGILL, &sa, NULL) == -1) | |||
101 | panic("couldn't register SIGILL handler: %d", thunk_geterrno()); | |||
102 | 120 | |||
103 | sa.sa_flags = SA_RESTART | SA_SIGINFO | SA_ONSTACK; | 121 | /* HUP */ | |
104 | sa.sa_sigaction = sigio_signal_handler; | 122 | /* INT */ /* ttycons ^C */ | |
105 | thunk_sigemptyset(&sa.sa_mask); | 123 | /* QUIT */ | |
106 | if (thunk_sigaction(SIGIO, &sa, NULL) == -1) | 124 | signal_intr_establish(SIGILL, illegal_instruction); | |
107 | panic("couldn't register SIGIO handler: %d", thunk_geterrno()); | 125 | /* TRAP */ | |
126 | /* ABRT */ | |||
127 | /* SIGEMT */ | |||
128 | /* SIGFPE XXX! */ | |||
129 | /* KILL */ | |||
130 | signal_intr_establish(SIGBUS, pagefault); | |||
131 | signal_intr_establish(SIGSEGV, pagefault); | |||
132 | /* SYS */ | |||
133 | /* PIPE */ | |||
134 | signal_intr_establish(SIGALRM, alarm); | |||
135 | /* TERM */ | |||
136 | /* URG */ | |||
137 | /* STOP */ | |||
138 | /* TSTP */ /* ttycons ^Z */ | |||
139 | /* CONT */ | |||
140 | /* CHLD */ | |||
141 | /* GTTIN */ | |||
142 | /* TTOU */ | |||
143 | signal_intr_establish(SIGIO, sigio); | |||
144 | /* XCPU */ | |||
145 | /* XFSZ */ | |||
146 | /* VTALRM */ | |||
147 | /* PROF */ | |||
148 | /* WINCH */ | |||
149 | /* INFO */ | |||
150 | /* USR1 */ | |||
151 | /* USR2 */ | |||
152 | /* PWR */ | |||
108 | } | 153 | } | |
109 | 154 | |||
110 | 155 | |||
156 | /* XXX yes this is blunt */ | |||
111 | void | 157 | void | |
112 | stop_all_signal_handlers(void) | 158 | stop_all_signal_handlers(void) | |
113 | { | 159 | { | |
114 | thunk_sigblock(SIGALRM); | 160 | int i; | |
115 | thunk_sigblock(SIGIO); | 161 | for (i = 0; i < NSIG; i++) | |
116 | thunk_sigblock(SIGILL); | 162 | if (sig_funcs[i]) | |
117 | thunk_sigblock(SIGSEGV); | 163 | thunk_sigblock(i); | |
118 | thunk_sigblock(SIGBUS); | |||
119 | } | 164 | } | |
120 | 165 | |||
121 | 166 | |||
122 | /* ast and userret */ | |||
123 | void | 167 | void | |
124 | userret(struct lwp *l) | 168 | setup_clock_intr(void) | |
125 | { | 169 | { | |
126 | /* invoke MI userret code */ | 170 | /* setup soft interrupt handler */ | |
127 | mi_userret(l); | 171 | alrm_ih = softint_establish(SOFTINT_CLOCK, | |
172 | clock_intr, NULL); | |||
173 | } | |||
174 | ||||
175 | ||||
176 | /* ast and userret */ | |||
177 | static void | |||
178 | ast(struct lwp *l) | |||
179 | { | |||
180 | struct pcb *pcb; | |||
128 | 181 | |||
129 | while (astpending) { | 182 | if (!astpending) | |
130 | astpending = 0; | 183 | return; | |
184 | ||||
185 | astpending = 0; | |||
186 | curcpu()->ci_data.cpu_ntrap++; | |||
131 | 187 | |||
132 | curcpu()->ci_data.cpu_ntrap++; | |||
133 | #if 0 | 188 | #if 0 | |
134 | /* profiling */ | 189 | /* profiling */ | |
135 | if (l->l_pflag & LP_OWEUPC) { | 190 | if (l->l_pflag & LP_OWEUPC) { | |
136 | l->l_pflag &= ~LP_OWEUPC; | 191 | l->l_pflag &= ~LP_OWEUPC; | |
137 | ADDUPROF(l); | 192 | ADDUPROF(l); | |
138 | } | 193 | } | |
139 | #endif | 194 | #endif | |
140 | /* allow a forced task switch */ | |||
141 | if (l->l_cpu->ci_want_resched) | |||
142 | preempt(); | |||
143 | 195 | |||
144 | mi_userret(l); | 196 | /* allow a forced task switch */ | |
197 | if (curcpu()->ci_want_resched) { | |||
198 | curcpu()->ci_want_resched = 0; | |||
199 | preempt(); | |||
200 | /* returns here! */ | |||
145 | } | 201 | } | |
202 | KASSERT(l == curlwp); KASSERT(l); | |||
203 | pcb = lwp_getpcb(l); KASSERT(pcb); | |||
204 | mi_userret(l); | |||
205 | } | |||
206 | ||||
207 | ||||
208 | void | |||
209 | userret(struct lwp *l) | |||
210 | { | |||
211 | /* invoke MI userret code */ | |||
212 | mi_userret(l); | |||
213 | ||||
214 | ast(l); | |||
146 | } | 215 | } | |
147 | 216 | |||
148 | 217 | |||
149 | #ifdef DEBUG | 218 | #ifdef DEBUG | |
150 | /* | 219 | /* | |
151 | * Uncomment the following if you want to receive information about what | 220 | * Uncomment the following if you want to receive information about what | |
152 | * triggered the fault. Mainly for debugging and porting purposes | 221 | * triggered the fault. Mainly for debugging and porting purposes | |
153 | */ | 222 | */ | |
154 | static void | 223 | static void | |
155 | print_mem_access_siginfo(int sig, siginfo_t *info, void *ctx, | 224 | print_mem_access_siginfo(int sig, siginfo_t *info, void *ctx, | |
156 | vaddr_t pc, vaddr_t va, vaddr_t sp) | 225 | vaddr_t pc, vaddr_t va, vaddr_t sp) | |
157 | { | 226 | { | |
158 | #if 0 | 227 | #if 0 | |
@@ -165,31 +234,28 @@ print_mem_access_siginfo(int sig, siginf | @@ -165,31 +234,28 @@ print_mem_access_siginfo(int sig, siginf | |||
165 | if (info->si_code == SEGV_ACCERR) | 234 | if (info->si_code == SEGV_ACCERR) | |
166 | thunk_printf_debug("\t\tSEGV_ACCERR\n"); | 235 | thunk_printf_debug("\t\tSEGV_ACCERR\n"); | |
167 | if (info->si_code == BUS_ADRALN) | 236 | if (info->si_code == BUS_ADRALN) | |
168 | thunk_printf_debug("\t\tBUS_ADRALN\n"); | 237 | thunk_printf_debug("\t\tBUS_ADRALN\n"); | |
169 | if (info->si_code == BUS_ADRERR) | 238 | if (info->si_code == BUS_ADRERR) | |
170 | thunk_printf_debug("\t\tBUS_ADRERR\n"); | 239 | thunk_printf_debug("\t\tBUS_ADRERR\n"); | |
171 | if (info->si_code == BUS_OBJERR) | 240 | if (info->si_code == BUS_OBJERR) | |
172 | thunk_printf_debug("\t\tBUS_OBJERR\n"); | 241 | thunk_printf_debug("\t\tBUS_OBJERR\n"); | |
173 | thunk_printf_debug("\tsi_addr = %p\n", info->si_addr); | 242 | thunk_printf_debug("\tsi_addr = %p\n", info->si_addr); | |
174 | thunk_printf_debug("\tsi_trap = %d\n", info->si_trap); | 243 | thunk_printf_debug("\tsi_trap = %d\n", info->si_trap); | |
175 | #endif | 244 | #endif | |
176 | 245 | |||
177 | #if 0 | 246 | #if 0 | |
178 | printf("memaccess error, pc %p, va %p, " | 247 | thunk_printf("memaccess error, pc %p, va %p, sp %p\n", | |
179 | "sys_stack %p, sp %p, stack top %p\n", | 248 | (void *) pc, (void *) va, (void *) sp); | |
180 | (void *) pc, (void *) va, | |||
181 | (void *) pcb->sys_stack, (void *) sp, | |||
182 | (void *) pcb->sys_stack_top); | |||
183 | #endif | 249 | #endif | |
184 | } | 250 | } | |
185 | 251 | |||
186 | /* | 252 | /* | |
187 | * Uncomment the following if you want to receive information about what | 253 | * Uncomment the following if you want to receive information about what | |
188 | * triggered the fault. Mainly for debugging and porting purposes | 254 | * triggered the fault. Mainly for debugging and porting purposes | |
189 | */ | 255 | */ | |
190 | static void | 256 | static void | |
191 | print_illegal_instruction_siginfo(int sig, siginfo_t *info, void *ctx, | 257 | print_illegal_instruction_siginfo(int sig, siginfo_t *info, void *ctx, | |
192 | vaddr_t pc, vaddr_t va, vaddr_t sp) | 258 | vaddr_t pc, vaddr_t va, vaddr_t sp) | |
193 | { | 259 | { | |
194 | #if 0 | 260 | #if 0 | |
195 | thunk_printf("SIGILL!\n"); | 261 | thunk_printf("SIGILL!\n"); | |
@@ -210,155 +276,125 @@ print_illegal_instruction_siginfo(int si | @@ -210,155 +276,125 @@ print_illegal_instruction_siginfo(int si | |||
210 | thunk_printf("\t\tPrivileged register"); | 276 | thunk_printf("\t\tPrivileged register"); | |
211 | if (info->si_code == ILL_COPROC) | 277 | if (info->si_code == ILL_COPROC) | |
212 | thunk_printf("\t\tCoprocessor error"); | 278 | thunk_printf("\t\tCoprocessor error"); | |
213 | if (info->si_code == ILL_BADSTK) | 279 | if (info->si_code == ILL_BADSTK) | |
214 | thunk_printf("\t\tInternal stack error"); | 280 | thunk_printf("\t\tInternal stack error"); | |
215 | thunk_printf("\tsi_addr = %p\n", info->si_addr); | 281 | thunk_printf("\tsi_addr = %p\n", info->si_addr); | |
216 | thunk_printf("\tsi_trap = %d\n", info->si_trap); | 282 | thunk_printf("\tsi_trap = %d\n", info->si_trap); | |
217 | 283 | |||
218 | thunk_printf("%p : ", info->si_addr); | 284 | thunk_printf("%p : ", info->si_addr); | |
219 | for (int i = 0; i < 10; i++) | 285 | for (int i = 0; i < 10; i++) | |
220 | thunk_printf("%02x ", *((uint8_t *) info->si_addr + i)); | 286 | thunk_printf("%02x ", *((uint8_t *) info->si_addr + i)); | |
221 | thunk_printf("\n"); | 287 | thunk_printf("\n"); | |
222 | #endif | 288 | #endif | |
289 | ||||
290 | #if 0 | |||
291 | thunk_printf("sigill\n"); | |||
292 | #endif | |||
223 | } | 293 | } | |
224 | #else /* DEBUG */ | 294 | #else /* DEBUG */ | |
225 | #define print_mem_access_siginfo(s, i, c, p, v, sp) | 295 | #define print_mem_access_siginfo(s, i, c, p, v, sp) | |
226 | #define print_illegal_instruction_siginfo(s, i, c, p, v, sp) | 296 | #define print_illegal_instruction_siginfo(s, i, c, p, v, sp) | |
227 | #endif /* DEBUG */ | 297 | #endif /* DEBUG */ | |
228 | 298 | |||
229 | 299 | |||
230 | /* signal handler switching to a pagefault context */ | |||
231 | static void | 300 | static void | |
232 | mem_access_handler(int sig, siginfo_t *info, void *ctx) | 301 | handle_signal(int sig, siginfo_t *info, void *ctx) | |
233 | { | 302 | { | |
303 | sigfunc_t *f; | |||
234 | ucontext_t *ucp = ctx; | 304 | ucontext_t *ucp = ctx; | |
235 | struct lwp *l; | 305 | struct lwp *l; | |
236 | struct pcb *pcb; | 306 | struct pcb *pcb; | |
237 | vaddr_t va, sp, pc, fp; | 307 | vaddr_t va, sp, pc, fp; | |
238 | int from_userland; | 308 | int from_userland; | |
239 | 309 | |||
240 | assert((info->si_signo == SIGSEGV) || (info->si_signo == SIGBUS)); | 310 | if (sig == SIGBUS || sig == SIGSEGV || sig == SIGILL) { | |
311 | if (info->si_code == SI_NOINFO) | |||
312 | panic("received signal %d with no info", | |||
313 | info->si_signo); | |||
314 | } | |||
241 | 315 | |||
242 | if (info->si_code == SI_NOINFO) | 316 | f = sig_funcs[sig]; | |
243 | panic("received signal %d with no info", | 317 | KASSERT(f); | |
244 | info->si_signo); | |||
245 | 318 | |||
246 | l = curlwp; | 319 | l = curlwp; KASSERT(l); | |
247 | pcb = lwp_getpcb(l); | 320 | pcb = lwp_getpcb(l); KASSERT(pcb); | |
248 | 321 | |||
249 | /* get address of faulted memory access and make it page aligned */ | 322 | /* get address of possible faulted memory access and page aligne it */ | |
250 | va = (vaddr_t) info->si_addr; | 323 | va = (vaddr_t) info->si_addr; | |
251 | va = trunc_page(va); | 324 | va = trunc_page(va); | |
252 | 325 | |||
253 | /* get PC address of faulted memory instruction */ | 326 | /* get PC address of possibly faulted instruction */ | |
254 | pc = md_get_pc(ctx); | 327 | pc = md_get_pc(ctx); | |
255 | 328 | |||
256 | /* setup for pagefault context */ | 329 | /* nest it on the stack */ | |
257 | sp = md_get_sp(ctx); | 330 | sp = md_get_sp(ctx); | |
258 | 331 | |||
259 | print_mem_access_siginfo(sig, info, ctx, pc, va, sp); | 332 | if (sig == SIGBUS || sig == SIGSEGV) | |
333 | print_mem_access_siginfo(sig, info, ctx, pc, va, sp); | |||
334 | if (sig == SIGILL) | |||
335 | print_illegal_instruction_siginfo(sig, info, ctx, pc, va, sp); | |||
260 | 336 | |||
261 | /* if we're running on a stack of our own, use the system stack */ | 337 | /* if we're running on a stack of our own, use the system stack */ | |
262 | from_userland = 0; | 338 | from_userland = 0; | |
263 | if ((sp < (vaddr_t) pcb->sys_stack) || (sp > (vaddr_t) pcb->sys_stack_top)) { | 339 | if ((sp < (vaddr_t) pcb->sys_stack) || | |
340 | (sp > (vaddr_t) pcb->sys_stack_top)) { | |||
264 | sp = (vaddr_t) pcb->sys_stack_top - sizeof(register_t); | 341 | sp = (vaddr_t) pcb->sys_stack_top - sizeof(register_t); | |
265 | fp = (vaddr_t) &pcb->pcb_userret_ucp; | 342 | fp = (vaddr_t) &pcb->pcb_userret_ucp; | |
266 | if (pc < kmem_user_end) | 343 | if (pc < kmem_user_end) | |
267 | from_userland = 1; | 344 | from_userland = 1; | |
268 | } else { | 345 | } else { | |
269 | /* stack grows down */ | 346 | /* stack grows down */ | |
270 | fp = sp - sizeof(ucontext_t) - sizeof(register_t); /* slack */ | 347 | fp = sp - sizeof(ucontext_t) - sizeof(register_t); /* slack */ | |
271 | sp = fp - sizeof(register_t); /* slack */ | 348 | sp = fp - sizeof(register_t); /* slack */ | |
272 | 349 | |||
273 | /* sanity check before copying */ | 350 | /* sanity check before copying */ | |
274 | if (fp - 2*PAGE_SIZE < (vaddr_t) pcb->sys_stack) | 351 | if (fp - 2*PAGE_SIZE < (vaddr_t) pcb->sys_stack) | |
275 | panic("%s: out of system stack", __func__); | 352 | panic("%s: out of system stack", __func__); | |
276 | } | 353 | } | |
277 | 354 | |||
278 | memcpy((void *) fp, ucp, sizeof(ucontext_t)); | 355 | memcpy((void *) fp, ucp, sizeof(ucontext_t)); | |
356 | memcpy(&jump_ucp, ucp, sizeof(ucontext_t)); | |||
279 | 357 | |||
280 | /* create context for pagefault */ | 358 | /* create context */ | |
281 | pcb->pcb_ucp.uc_stack.ss_sp = (void *) pcb->sys_stack; | 359 | jump_ucp.uc_stack.ss_sp = (void *) pcb->sys_stack; | |
282 | pcb->pcb_ucp.uc_stack.ss_size = sp - (vaddr_t) pcb->sys_stack; | 360 | jump_ucp.uc_stack.ss_size = sp - (vaddr_t) pcb->sys_stack; | |
283 | pcb->pcb_ucp.uc_link = (void *) fp; /* link to old frame on stack */ | 361 | jump_ucp.uc_link = (void *) fp; /* link to old frame on stack */ | |
284 | 362 | |||
285 | pcb->pcb_ucp.uc_flags = _UC_STACK | _UC_CPU; | 363 | thunk_sigemptyset(&jump_ucp.uc_sigmask); | |
286 | thunk_makecontext(&pcb->pcb_ucp, (void (*)(void)) pagefault, | 364 | jump_ucp.uc_flags = _UC_STACK | _UC_CPU | _UC_SIGMASK; | |
365 | thunk_makecontext(&jump_ucp, | |||
366 | (void (*)(void)) f, | |||
287 | 3, (void *) from_userland, (void *) pc, (void *) va); | 367 | 3, (void *) from_userland, (void *) pc, (void *) va); | |
288 | 368 | |||
289 | /* switch to the new pagefault entry on return from signal */ | 369 | /* switch to the new context on return from signal */ | |
290 | memcpy(ctx, &pcb->pcb_ucp, sizeof(ucontext_t)); | 370 | thunk_setcontext(&jump_ucp); | |
371 | // memcpy(ctx, &pcb->pcb_ucp, sizeof(ucontext_t)); | |||
291 | } | 372 | } | |
292 | 373 | |||
293 | 374 | |||
294 | /* signal handler switching to a illegal instruction context */ | 375 | void | |
295 | static void | 376 | signal_intr_establish(int sig, sigfunc_t f) | |
296 | illegal_instruction_handler(int sig, siginfo_t *info, void *ctx) | |||
297 | { | 377 | { | |
298 | ucontext_t *ucp = ctx; | 378 | static struct sigaction sa; | |
299 | struct lwp *l; | |||
300 | struct pcb *pcb; | |||
301 | vaddr_t sp, pc, fp; | |||
302 | int from_userland; | |||
303 | ||||
304 | assert(info->si_signo == SIGILL); | |||
305 | ||||
306 | l = curlwp; | |||
307 | pcb = lwp_getpcb(l); | |||
308 | ||||
309 | /* get PC address of faulted instruction */ | |||
310 | pc = md_get_pc(ctx); | |||
311 | ||||
312 | /* setup for illegal_instruction context */ | |||
313 | sp = md_get_sp(ctx); | |||
314 | ||||
315 | print_illegal_instruction_siginfo(sig, info, ctx, pc, 0, sp); | |||
316 | ||||
317 | /* if we're running on a stack of our own, use the system stack */ | |||
318 | from_userland = 0; | |||
319 | if ((sp < (vaddr_t) pcb->sys_stack) || | |||
320 | (sp > (vaddr_t) pcb->sys_stack_top)) { | |||
321 | sp = (vaddr_t) pcb->sys_stack_top - sizeof(register_t); | |||
322 | fp = (vaddr_t) &pcb->pcb_userret_ucp; | |||
323 | ||||
324 | KASSERT(pc < kmem_user_end); | |||
325 | from_userland = 1; | |||
326 | } else { | |||
327 | panic("illegal instruction inside kernel?"); | |||
328 | #if 0 | |||
329 | /* stack grows down */ | |||
330 | fp = sp - sizeof(ucontext_t) - sizeof(register_t); /* slack */ | |||
331 | sp = fp - sizeof(register_t); /* slack */ | |||
332 | ||||
333 | /* sanity check before copying */ | |||
334 | if (fp - 2*PAGE_SIZE < (vaddr_t) pcb->sys_stack) | |||
335 | panic("%s: out of system stack", __func__); | |||
336 | #endif | |||
337 | } | |||
338 | ||||
339 | memcpy((void *) fp, ucp, sizeof(ucontext_t)); | |||
340 | 379 | |||
341 | /* create context for illegal instruction */ | 380 | sig_funcs[sig] = f; | |
342 | pcb->pcb_ucp.uc_stack.ss_sp = (void *) pcb->sys_stack; | |||
343 | pcb->pcb_ucp.uc_stack.ss_size = sp - (vaddr_t) pcb->sys_stack; | |||
344 | pcb->pcb_ucp.uc_link = (void *) fp; /* link to old frame on stack */ | |||
345 | ||||
346 | pcb->pcb_ucp.uc_flags = _UC_STACK | _UC_CPU; | |||
347 | thunk_makecontext(&pcb->pcb_ucp, (void (*)(void)) illegal_instruction, | |||
348 | 1, (void *) from_userland, NULL, NULL); | |||
349 | 381 | |||
350 | /* switch to the new illegal instruction entry on return from signal */ | 382 | sa.sa_flags = SA_RESTART | SA_SIGINFO | SA_ONSTACK; | |
351 | memcpy(ctx, &pcb->pcb_ucp, sizeof(ucontext_t)); | 383 | sa.sa_sigaction = (void *) handle_signal; | |
384 | thunk_sigfillset(&sa.sa_mask); | |||
385 | if (thunk_sigaction(sig, &sa, NULL) == -1) | |||
386 | panic("couldn't register SIG%d handler: %d", sig, | |||
387 | thunk_geterrno()); | |||
352 | } | 388 | } | |
353 | 389 | |||
354 | 390 | |||
355 | /* | 391 | /* | |
356 | * Context for handing page faults from the sigsegv handler; check if its a | 392 | * Context for handing page faults from the sigsegv handler; check if its a | |
357 | * pmap reference fault or let uvm handle it. | 393 | * pmap reference fault or let uvm handle it. | |
358 | */ | 394 | */ | |
359 | static void | 395 | static void | |
360 | pagefault(vaddr_t from_userland, vaddr_t pc, vaddr_t va) | 396 | pagefault(vaddr_t from_userland, vaddr_t pc, vaddr_t va) | |
361 | { | 397 | { | |
362 | struct proc *p; | 398 | struct proc *p; | |
363 | struct lwp *l; | 399 | struct lwp *l; | |
364 | struct pcb *pcb; | 400 | struct pcb *pcb; | |
@@ -367,38 +403,37 @@ pagefault(vaddr_t from_userland, vaddr_t | @@ -367,38 +403,37 @@ pagefault(vaddr_t from_userland, vaddr_t | |||
367 | vm_prot_t atype; | 403 | vm_prot_t atype; | |
368 | void *onfault; | 404 | void *onfault; | |
369 | int from_kernel, lwp_errno, error; | 405 | int from_kernel, lwp_errno, error; | |
370 | ksiginfo_t ksi; | 406 | ksiginfo_t ksi; | |
371 | 407 | |||
372 | l = curlwp; KASSERT(l); | 408 | l = curlwp; KASSERT(l); | |
373 | pcb = lwp_getpcb(l); | 409 | pcb = lwp_getpcb(l); | |
374 | p = l->l_proc; | 410 | p = l->l_proc; | |
375 | vm = p->p_vmspace; | 411 | vm = p->p_vmspace; | |
376 | 412 | |||
377 | lwp_errno = thunk_geterrno(); | 413 | lwp_errno = thunk_geterrno(); | |
378 | 414 | |||
379 | vm_map = &vm->vm_map; | 415 | vm_map = &vm->vm_map; | |
380 | from_kernel = (pc >= kmem_k_start); | 416 | from_kernel = (pc >= kmem_k_start) && (!from_userland); | |
381 | if (from_kernel && (va >= VM_MIN_KERNEL_ADDRESS)) | 417 | if (from_kernel && (va >= VM_MIN_KERNEL_ADDRESS)) | |
382 | vm_map = kernel_map; | 418 | vm_map = kernel_map; | |
383 | 419 | |||
384 | #if 0 | 420 | #if 0 | |
385 | thunk_printf("pagefault : pc %p, va %p\n", | 421 | thunk_printf("%s: l %p, pcb %p\n", __func__, l, pcb); | |
386 | (void *) pc, (void *) va); | 422 | thunk_printf("\tpc %p, va %p\n", (void *) pc, (void *) va); | |
387 | #endif | 423 | #endif | |
388 | 424 | |||
389 | /* can pmap handle it? on its own? (r/m) emulation */ | 425 | /* can pmap handle it? on its own? (r/m) emulation */ | |
390 | if (pmap_fault(vm_map->pmap, va, &atype)) { | 426 | if (pmap_fault(vm_map->pmap, va, &atype)) { | |
391 | // thunk_printf("pagefault leave (pmap)\n"); | |||
392 | /* no use doing anything else here */ | 427 | /* no use doing anything else here */ | |
393 | goto out_quick; | 428 | goto out_quick; | |
394 | } | 429 | } | |
395 | 430 | |||
396 | /* ask UVM */ | 431 | /* ask UVM */ | |
397 | thunk_printf_debug("pmap fault couldn't handle it! : " | 432 | thunk_printf_debug("pmap fault couldn't handle it! : " | |
398 | "derived atype %d\n", atype); | 433 | "derived atype %d\n", atype); | |
399 | 434 | |||
400 | onfault = pcb->pcb_onfault; | 435 | onfault = pcb->pcb_onfault; | |
401 | pcb->pcb_onfault = NULL; | 436 | pcb->pcb_onfault = NULL; | |
402 | error = uvm_fault(vm_map, va, atype); | 437 | error = uvm_fault(vm_map, va, atype); | |
403 | pcb->pcb_onfault = onfault; | 438 | pcb->pcb_onfault = onfault; | |
404 | 439 | |||
@@ -406,47 +441,48 @@ pagefault(vaddr_t from_userland, vaddr_t | @@ -406,47 +441,48 @@ pagefault(vaddr_t from_userland, vaddr_t | |||
406 | if (error == 0) | 441 | if (error == 0) | |
407 | uvm_grow(l->l_proc, va); | 442 | uvm_grow(l->l_proc, va); | |
408 | } | 443 | } | |
409 | if (error == EACCES) | 444 | if (error == EACCES) | |
410 | error = EFAULT; | 445 | error = EFAULT; | |
411 | 446 | |||
412 | /* if uvm handled it, return */ | 447 | /* if uvm handled it, return */ | |
413 | if (error == 0) { | 448 | if (error == 0) { | |
414 | // thunk_printf("pagefault leave (uvm)\n"); | 449 | // thunk_printf("pagefault leave (uvm)\n"); | |
415 | goto out; | 450 | goto out; | |
416 | } | 451 | } | |
417 | 452 | |||
418 | /* something got wrong */ | 453 | /* something got wrong */ | |
419 | thunk_printf("%s: uvm fault %d, pc %p, from_kernel %d\n", | 454 | thunk_printf("%s: uvm fault %d, pc %p, va %p, from_kernel %d\n", | |
420 | __func__, error, (void *) pc, from_kernel); | 455 | __func__, error, (void *) pc, (void *) va, from_kernel); | |
421 | 456 | |||
422 | /* check if its from copyin/copyout */ | 457 | /* check if its from copyin/copyout */ | |
423 | if (onfault) { | 458 | if (onfault) { | |
424 | panic("%s: can't call onfault yet\n", __func__); | 459 | panic("%s: can't call onfault yet\n", __func__); | |
425 | /* XXX implement me ? */ | 460 | /* XXX implement me ? */ | |
426 | /* jump to given onfault */ | 461 | /* jump to given onfault */ | |
427 | // tf = &kernel_tf; | 462 | // tf = &kernel_tf; | |
428 | // memset(tf, 0, sizeof(struct trapframe)); | 463 | // memset(tf, 0, sizeof(struct trapframe)); | |
429 | // tf->tf_pc = onfault; | 464 | // tf->tf_pc = onfault; | |
430 | // tf->tf_io[0] = (rv == EACCES) ? EFAULT : rv; | 465 | // tf->tf_io[0] = (rv == EACCES) ? EFAULT : rv; | |
431 | goto out; | 466 | goto out; | |
432 | } | 467 | } | |
433 | 468 | |||
434 | if (from_kernel) | 469 | if (from_kernel) | |
435 | panic("Unhandled page fault in kernel mode"); | 470 | panic("Unhandled page fault in kernel mode"); | |
436 | 471 | |||
437 | /* send signal */ | 472 | /* send signal */ | |
438 | thunk_printf("giving signal to userland\n"); | 473 | thunk_printf("giving signal to userland\n"); | |
439 | 474 | |||
475 | KASSERT(from_userland); | |||
440 | KSI_INIT_TRAP(&ksi); | 476 | KSI_INIT_TRAP(&ksi); | |
441 | ksi.ksi_signo = SIGSEGV; | 477 | ksi.ksi_signo = SIGSEGV; | |
442 | ksi.ksi_trap = 0; /* XXX */ | 478 | ksi.ksi_trap = 0; /* XXX */ | |
443 | ksi.ksi_code = (error == EPERM) ? SEGV_ACCERR : SEGV_MAPERR; | 479 | ksi.ksi_code = (error == EPERM) ? SEGV_ACCERR : SEGV_MAPERR; | |
444 | ksi.ksi_addr = (void *) va; | 480 | ksi.ksi_addr = (void *) va; | |
445 | 481 | |||
446 | if (error == ENOMEM) { | 482 | if (error == ENOMEM) { | |
447 | printf("UVM: pid %d.%d (%s), uid %d killed: " | 483 | printf("UVM: pid %d.%d (%s), uid %d killed: " | |
448 | "out of swap\n", | 484 | "out of swap\n", | |
449 | p->p_pid, l->l_lid, p->p_comm, | 485 | p->p_pid, l->l_lid, p->p_comm, | |
450 | l->l_cred ? kauth_cred_geteuid(l->l_cred) : -1); | 486 | l->l_cred ? kauth_cred_geteuid(l->l_cred) : -1); | |
451 | ksi.ksi_signo = SIGKILL; | 487 | ksi.ksi_signo = SIGKILL; | |
452 | } | 488 | } | |
@@ -458,51 +494,123 @@ pagefault(vaddr_t from_userland, vaddr_t | @@ -458,51 +494,123 @@ pagefault(vaddr_t from_userland, vaddr_t | |||
458 | #endif | 494 | #endif | |
459 | 495 | |||
460 | // thunk_printf("pagefault leave\n"); | 496 | // thunk_printf("pagefault leave\n"); | |
461 | out: | 497 | out: | |
462 | if (from_userland) | 498 | if (from_userland) | |
463 | userret(l); | 499 | userret(l); | |
464 | out_quick: | 500 | out_quick: | |
465 | thunk_seterrno(lwp_errno); | 501 | thunk_seterrno(lwp_errno); | |
466 | pcb->pcb_errno = lwp_errno; | 502 | pcb->pcb_errno = lwp_errno; | |
467 | } | 503 | } | |
468 | 504 | |||
469 | 505 | |||
470 | /* | 506 | /* | |
471 | * Context for handing illegal instruction from the sigill handler | 507 | * handle an illegal instruction. | |
508 | * | |||
509 | * arguments 'pc' and 'va' are ignored here | |||
472 | */ | 510 | */ | |
473 | static void | 511 | static void | |
474 | illegal_instruction(vaddr_t from_userland) | 512 | illegal_instruction(vaddr_t from_userland, vaddr_t pc, vaddr_t va) | |
475 | { | 513 | { | |
476 | struct lwp *l = curlwp; | 514 | struct lwp *l = curlwp; | |
477 | struct pcb *pcb = lwp_getpcb(l); | 515 | struct pcb *pcb = lwp_getpcb(l); | |
478 | ucontext_t *ucp = &pcb->pcb_userret_ucp; | 516 | ucontext_t *ucp = &pcb->pcb_userret_ucp; | |
479 | ksiginfo_t ksi; | 517 | ksiginfo_t ksi; | |
480 | 518 | |||
481 | // thunk_printf("illegal instruction\n"); | 519 | // thunk_printf("%s: l %p, pcb %p\n", __func__, l, pcb); | |
520 | ||||
521 | KASSERT(from_userland); | |||
522 | ||||
482 | /* if its a syscall ... */ | 523 | /* if its a syscall ... */ | |
483 | if (md_syscall_check_opcode(ucp)) { | 524 | if (md_syscall_check_opcode(ucp)) { | |
484 | syscall(); | 525 | syscall(); | |
485 | // thunk_printf("illegal instruction leave\n"); | |||
486 | KASSERT(from_userland); | |||
487 | userret(l); | 526 | userret(l); | |
488 | return; | 527 | return; | |
489 | } | 528 | } | |
490 | 529 | |||
491 | thunk_printf("%s: giving SIGILL (TRAP)\n", __func__); | 530 | thunk_printf("%s: giving SIGILL (TRAP)\n", __func__); | |
492 | 531 | |||
532 | KASSERT(from_userland); | |||
493 | KSI_INIT_TRAP(&ksi); | 533 | KSI_INIT_TRAP(&ksi); | |
494 | ksi.ksi_signo = SIGILL; | 534 | ksi.ksi_signo = SIGILL; | |
495 | ksi.ksi_trap = 0; /* XXX */ | 535 | ksi.ksi_trap = 0; /* XXX */ | |
496 | ksi.ksi_errno = 0; // info->si_errno; | 536 | ksi.ksi_errno = 0; // info->si_errno; | |
497 | ksi.ksi_code = 0; // info->si_code; | 537 | ksi.ksi_code = 0; // info->si_code; | |
498 | ksi.ksi_addr = (void *) md_get_pc(ucp); /* only relyable source */ | 538 | ksi.ksi_addr = (void *) md_get_pc(ucp); /* only relyable source */ | |
499 | 539 | |||
500 | #if 0 | 540 | #if 0 | |
501 | p->p_emul->e_trapsignal(l, &ksi); | 541 | p->p_emul->e_trapsignal(l, &ksi); | |
502 | #else | 542 | #else | |
503 | trapsignal(l, &ksi); | 543 | trapsignal(l, &ksi); | |
504 | #endif | 544 | #endif | |
505 | KASSERT(from_userland); | |||
506 | userret(l); | 545 | userret(l); | |
507 | } | 546 | } | |
508 | 547 | |||
548 | ||||
549 | /* | |||
550 | * handle alarm, a clock ticker. | |||
551 | * | |||
552 | * arguments 'pc' and 'va' are ignored here | |||
553 | */ | |||
554 | static void | |||
555 | alarm(vaddr_t from_userland, vaddr_t pc, vaddr_t va) | |||
556 | { | |||
557 | struct lwp *l = curlwp; | |||
558 | struct pcb *pcb = lwp_getpcb(l); KASSERT(pcb); | |||
559 | ||||
560 | if (!clock_running) | |||
561 | return; | |||
562 | // thunk_printf("%s: l %p, pcb %p\n", __func__, l, pcb); | |||
563 | ||||
564 | softint_schedule(alrm_ih); | |||
565 | ||||
566 | KASSERT(l == curlwp); | |||
567 | if (from_userland) | |||
568 | userret(l); | |||
569 | } | |||
570 | ||||
571 | ||||
572 | /* | |||
573 | * handle sigio, a mux for all io operations. | |||
574 | * | |||
575 | * arguments 'pc' and 'va' are ignored here | |||
576 | */ | |||
577 | static void | |||
578 | sigio(vaddr_t from_userland, vaddr_t pc, vaddr_t va) | |||
579 | { | |||
580 | struct lwp *l = curlwp; | |||
581 | struct pcb *pcb = lwp_getpcb(l); KASSERT(pcb); | |||
582 | struct intr_handler *sih; | |||
583 | unsigned int n; | |||
584 | ||||
585 | // thunk_printf("%s: l %p, pcb %p\n", __func__, l, pcb); | |||
586 | for (n = 0; n < SIGIO_MAX_HANDLERS; n++) { | |||
587 | sih = &sigio_intr_handler[n]; | |||
588 | if (sih->func) | |||
589 | sih->func(sih->arg); | |||
590 | } | |||
591 | ||||
592 | KASSERT(l == curlwp); | |||
593 | if (from_userland) | |||
594 | userret(l); /* or ast? */ | |||
595 | } | |||
596 | ||||
597 | ||||
598 | /* sigio register function */ | |||
599 | void * | |||
600 | sigio_intr_establish(int (*func)(void *), void *arg) | |||
601 | { | |||
602 | struct intr_handler *sih; | |||
603 | unsigned int n; | |||
604 | ||||
605 | for (n = 0; n < SIGIO_MAX_HANDLERS; n++) { | |||
606 | sih = &sigio_intr_handler[n]; | |||
607 | if (sih->func == NULL) { | |||
608 | sih->func = func; | |||
609 | sih->arg = arg; | |||
610 | return sih; | |||
611 | } | |||
612 | } | |||
613 | ||||
614 | panic("increase SIGIO_MAX_HANDLERS"); | |||
615 | } | |||
616 |