| @@ -1,331 +1,331 @@ | | | @@ -1,331 +1,331 @@ |
1 | /* $NetBSD: machdep.c,v 1.33 2011/11/27 21:38:17 reinoud Exp $ */ | | 1 | /* $NetBSD: machdep.c,v 1.34 2011/12/12 19:57:12 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 | * Copyright (c) 2007 Jared D. McNeill <jmcneill@invisible.ca> | | 5 | * Copyright (c) 2007 Jared D. McNeill <jmcneill@invisible.ca> |
6 | * All rights reserved. | | 6 | * All rights reserved. |
7 | * | | 7 | * |
8 | * Redistribution and use in source and binary forms, with or without | | 8 | * Redistribution and use in source and binary forms, with or without |
9 | * modification, are permitted provided that the following conditions | | 9 | * modification, are permitted provided that the following conditions |
10 | * are met: | | 10 | * are met: |
11 | * 1. Redistributions of source code must retain the above copyright | | 11 | * 1. Redistributions of source code must retain the above copyright |
12 | * notice, this list of conditions and the following disclaimer. | | 12 | * notice, this list of conditions and the following disclaimer. |
13 | * 2. Redistributions in binary form must reproduce the above copyright | | 13 | * 2. Redistributions in binary form must reproduce the above copyright |
14 | * notice, this list of conditions and the following disclaimer in the | | 14 | * notice, this list of conditions and the following disclaimer in the |
15 | * documentation and/or other materials provided with the distribution. | | 15 | * documentation and/or other materials provided with the distribution. |
16 | * | | 16 | * |
17 | * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS | | 17 | * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS |
18 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED | | 18 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED |
19 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | | 19 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
20 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS | | 20 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS |
21 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | | 21 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
22 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | | 22 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
23 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | | 23 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
24 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | | 24 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
25 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | | 25 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
26 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | | 26 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
27 | * POSSIBILITY OF SUCH DAMAGE. | | 27 | * POSSIBILITY OF SUCH DAMAGE. |
28 | */ | | 28 | */ |
29 | | | 29 | |
30 | #include "opt_memsize.h" | | 30 | #include "opt_memsize.h" |
31 | #include "opt_sdl.h" | | 31 | #include "opt_sdl.h" |
32 | #include "opt_urkelvisor.h" | | 32 | #include "opt_urkelvisor.h" |
33 | | | 33 | |
34 | #include <sys/cdefs.h> | | 34 | #include <sys/cdefs.h> |
35 | __KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.33 2011/11/27 21:38:17 reinoud Exp $"); | | 35 | __KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.34 2011/12/12 19:57:12 reinoud Exp $"); |
36 | | | 36 | |
37 | #include <sys/types.h> | | 37 | #include <sys/types.h> |
38 | #include <sys/param.h> | | 38 | #include <sys/param.h> |
39 | #include <sys/time.h> | | 39 | #include <sys/time.h> |
40 | #include <sys/exec.h> | | 40 | #include <sys/exec.h> |
41 | #include <sys/buf.h> | | 41 | #include <sys/buf.h> |
42 | #include <sys/boot_flag.h> | | 42 | #include <sys/boot_flag.h> |
43 | #include <sys/ucontext.h> | | 43 | #include <sys/ucontext.h> |
44 | #include <machine/pcb.h> | | 44 | #include <machine/pcb.h> |
45 | #include <machine/psl.h> | | 45 | #include <machine/psl.h> |
46 | | | 46 | |
47 | #include <uvm/uvm_extern.h> | | 47 | #include <uvm/uvm_extern.h> |
48 | #include <uvm/uvm_page.h> | | 48 | #include <uvm/uvm_page.h> |
49 | | | 49 | |
50 | #include <dev/mm.h> | | 50 | #include <dev/mm.h> |
51 | #include <machine/machdep.h> | | 51 | #include <machine/machdep.h> |
52 | #include <machine/thunk.h> | | 52 | #include <machine/thunk.h> |
53 | | | 53 | |
54 | #if defined(URKELVISOR) | | 54 | #if defined(URKELVISOR) |
55 | #include <machine/urkelvisor.h> | | 55 | #include <machine/urkelvisor.h> |
56 | #endif | | 56 | #endif |
57 | | | 57 | |
58 | char machine[] = "usermode"; | | 58 | char machine[] = "usermode"; |
59 | char machine_arch[] = "usermode"; | | 59 | char machine_arch[] = "usermode"; |
60 | | | 60 | |
61 | static char **saved_argv; | | 61 | static char **saved_argv; |
62 | char *usermode_root_image_path = NULL; | | 62 | char *usermode_root_image_path = NULL; |
63 | | | 63 | |
64 | void main(int argc, char *argv[]); | | 64 | void main(int argc, char *argv[]); |
65 | void usermode_reboot(void); | | 65 | void usermode_reboot(void); |
66 | | | 66 | |
67 | void | | 67 | void |
68 | main(int argc, char *argv[]) | | 68 | main(int argc, char *argv[]) |
69 | { | | 69 | { |
70 | #if defined(SDL) | | 70 | #if defined(SDL) |
71 | extern int genfb_thunkbus_cnattach(void); | | 71 | extern int genfb_thunkbus_cnattach(void); |
72 | #endif | | 72 | #endif |
73 | extern void ttycons_consinit(void); | | 73 | extern void ttycons_consinit(void); |
74 | extern void pmap_bootstrap(void); | | 74 | extern void pmap_bootstrap(void); |
75 | extern void kernmain(void); | | 75 | extern void kernmain(void); |
76 | int i, j, r, tmpopt = 0; | | 76 | int i, j, r, tmpopt = 0; |
77 | | | 77 | |
78 | saved_argv = argv; | | 78 | saved_argv = argv; |
79 | | | 79 | |
80 | #if defined(SDL) | | 80 | #if defined(SDL) |
81 | if (genfb_thunkbus_cnattach() == 0) | | 81 | if (genfb_thunkbus_cnattach() == 0) |
82 | #endif | | 82 | #endif |
83 | ttycons_consinit(); | | 83 | ttycons_consinit(); |
84 | | | 84 | |
85 | for (i = 1; i < argc; i++) { | | 85 | for (i = 1; i < argc; i++) { |
86 | if (argv[i][0] != '-') { | | 86 | if (argv[i][0] != '-') { |
87 | usermode_root_image_path = argv[i]; | | 87 | usermode_root_image_path = argv[i]; |
88 | continue; | | 88 | continue; |
89 | } | | 89 | } |
90 | for (j = 1; argv[i][j] != '\0'; j++) { | | 90 | for (j = 1; argv[i][j] != '\0'; j++) { |
91 | r = 0; | | 91 | r = 0; |
92 | BOOT_FLAG(argv[i][j], r); | | 92 | BOOT_FLAG(argv[i][j], r); |
93 | if (r == 0) { | | 93 | if (r == 0) { |
94 | printf("-%c: unknown flag\n", argv[i][j]); | | 94 | printf("-%c: unknown flag\n", argv[i][j]); |
95 | printf("usage: %s [-acdqsvxz]\n", argv[0]); | | 95 | printf("usage: %s [-acdqsvxz]\n", argv[0]); |
96 | printf(" (ex. \"%s -s\")\n", argv[0]); | | 96 | printf(" (ex. \"%s -s\")\n", argv[0]); |
97 | return; | | 97 | return; |
98 | } | | 98 | } |
99 | tmpopt |= r; | | 99 | tmpopt |= r; |
100 | } | | 100 | } |
101 | } | | 101 | } |
102 | boothowto = tmpopt; | | 102 | boothowto = tmpopt; |
103 | | | 103 | |
104 | uvm_setpagesize(); | | 104 | uvm_setpagesize(); |
105 | uvmexp.ncolors = 2; | | 105 | uvmexp.ncolors = 2; |
106 | | | 106 | |
107 | pmap_bootstrap(); | | 107 | pmap_bootstrap(); |
108 | | | 108 | |
109 | #if defined(URKELVISOR) | | 109 | #if defined(URKELVISOR) |
110 | urkelvisor_init(); | | 110 | urkelvisor_init(); |
111 | #endif | | 111 | #endif |
112 | | | 112 | |
113 | splinit(); | | 113 | splinit(); |
114 | splraise(IPL_HIGH); | | 114 | splraise(IPL_HIGH); |
115 | | | 115 | |
116 | kernmain(); | | 116 | kernmain(); |
117 | } | | 117 | } |
118 | | | 118 | |
119 | void | | 119 | void |
120 | usermode_reboot(void) | | 120 | usermode_reboot(void) |
121 | { | | 121 | { |
122 | struct thunk_itimerval itimer; | | 122 | struct thunk_itimerval itimer; |
123 | | | 123 | |
124 | /* make sure the timer is turned off */ | | 124 | /* make sure the timer is turned off */ |
125 | memset(&itimer, 0, sizeof(itimer)); | | 125 | memset(&itimer, 0, sizeof(itimer)); |
126 | thunk_setitimer(ITIMER_REAL, &itimer, NULL); | | 126 | thunk_setitimer(ITIMER_REAL, &itimer, NULL); |
127 | | | 127 | |
128 | if (thunk_execv(saved_argv[0], saved_argv) == -1) | | 128 | if (thunk_execv(saved_argv[0], saved_argv) == -1) |
129 | thunk_abort(); | | 129 | thunk_abort(); |
130 | /* NOTREACHED */ | | 130 | /* NOTREACHED */ |
131 | } | | 131 | } |
132 | | | 132 | |
133 | void | | 133 | void |
134 | setstatclockrate(int arg) | | 134 | setstatclockrate(int arg) |
135 | { | | 135 | { |
136 | } | | 136 | } |
137 | | | 137 | |
138 | void | | 138 | void |
139 | consinit(void) | | 139 | consinit(void) |
140 | { | | 140 | { |
141 | printf("NetBSD/usermode startup\n"); | | 141 | printf("NetBSD/usermode startup\n"); |
142 | } | | 142 | } |
143 | | | 143 | |
144 | void | | 144 | void |
145 | sendsig_siginfo(const ksiginfo_t *ksi, const sigset_t *mask) | | 145 | sendsig_siginfo(const ksiginfo_t *ksi, const sigset_t *mask) |
146 | { | | 146 | { |
147 | panic("%s not implemented", __func__); | | 147 | panic("%s not implemented", __func__); |
148 | } | | 148 | } |
149 | | | 149 | |
150 | int | | 150 | int |
151 | mm_md_physacc(paddr_t pa, vm_prot_t prog) | | 151 | mm_md_physacc(paddr_t pa, vm_prot_t prog) |
152 | { | | 152 | { |
153 | return 0; | | 153 | return 0; |
154 | } | | 154 | } |
155 | | | 155 | |
156 | | | 156 | |
157 | #ifdef __i386__ | | 157 | #ifdef __i386__ |
158 | | | 158 | |
159 | #if 0 | | 159 | #if 0 |
160 | static void dump_regs(ucontext_t *ctx); | | 160 | static void dump_regs(ucontext_t *ctx); |
161 | | | 161 | |
162 | static void | | 162 | static void |
163 | dump_regs(register_t *reg) | | 163 | dump_regs(register_t *reg) |
164 | { | | 164 | { |
165 | /* register dump before call */ | | 165 | /* register dump before call */ |
166 | const char *name[] = {"GS", "FS", "ES", "DS", "EDI", "ESI", "EBP", "ESP", | | 166 | const char *name[] = {"GS", "FS", "ES", "DS", "EDI", "ESI", "EBP", "ESP", |
167 | "EBX", "EDX", "ECX", "EAX", "TRAPNO", "ERR", "EIP", "CS", "EFL", | | 167 | "EBX", "EDX", "ECX", "EAX", "TRAPNO", "ERR", "EIP", "CS", "EFL", |
168 | "UESP", "SS"}; | | 168 | "UESP", "SS"}; |
169 | | | 169 | |
170 | for (i =0; i < 19; i++) | | 170 | for (i =0; i < 19; i++) |
171 | printf("reg[%02d] (%6s) = %"PRIx32"\n", i, name[i], reg[i]); | | 171 | printf("reg[%02d] (%6s) = %"PRIx32"\n", i, name[i], reg[i]); |
172 | } | | 172 | } |
173 | #endif | | 173 | #endif |
174 | | | 174 | |
175 | void | | 175 | void |
176 | setregs(struct lwp *l, struct exec_package *pack, vaddr_t stack) | | 176 | setregs(struct lwp *l, struct exec_package *pack, vaddr_t stack) |
177 | { | | 177 | { |
178 | struct pcb *pcb = lwp_getpcb(l); | | 178 | struct pcb *pcb = lwp_getpcb(l); |
179 | ucontext_t *ucp = &pcb->pcb_userret_ucp; | | 179 | ucontext_t *ucp = &pcb->pcb_userret_ucp; |
180 | uint *reg, i; | | 180 | uint *reg, i; |
181 | | | 181 | |
182 | #ifdef DEBUG_EXEC | | 182 | #ifdef DEBUG_EXEC |
183 | printf("setregs called: lwp %p, exec package %p, stack %p\n", | | 183 | printf("setregs called: lwp %p, exec package %p, stack %p\n", |
184 | l, pack, (void *) stack); | | 184 | l, pack, (void *) stack); |
185 | printf("current stat of pcb %p\n", pcb); | | 185 | printf("current stat of pcb %p\n", pcb); |
186 | printf("\tpcb->pcb_ucp.uc_stack.ss_sp = %p\n", | | 186 | printf("\tpcb->pcb_ucp.uc_stack.ss_sp = %p\n", |
187 | pcb->pcb_ucp.uc_stack.ss_sp); | | 187 | pcb->pcb_ucp.uc_stack.ss_sp); |
188 | printf("\tpcb->pcb_ucp.uc_stack.ss_size = %d\n", | | 188 | printf("\tpcb->pcb_ucp.uc_stack.ss_size = %d\n", |
189 | (int) pcb->pcb_ucp.uc_stack.ss_size); | | 189 | (int) pcb->pcb_ucp.uc_stack.ss_size); |
190 | printf("\tpcb->pcb_userret_ucp.uc_stack.ss_sp = %p\n", | | 190 | printf("\tpcb->pcb_userret_ucp.uc_stack.ss_sp = %p\n", |
191 | pcb->pcb_userret_ucp.uc_stack.ss_sp); | | 191 | pcb->pcb_userret_ucp.uc_stack.ss_sp); |
192 | printf("\tpcb->pcb_userret_ucp.uc_stack.ss_size = %d\n", | | 192 | printf("\tpcb->pcb_userret_ucp.uc_stack.ss_size = %d\n", |
193 | (int) pcb->pcb_userret_ucp.uc_stack.ss_size); | | 193 | (int) pcb->pcb_userret_ucp.uc_stack.ss_size); |
194 | #endif | | 194 | #endif |
195 | | | 195 | |
196 | reg = (int *) &ucp->uc_mcontext; | | 196 | reg = (int *) &ucp->uc_mcontext; |
197 | for (i = 4; i < 11; i++) | | 197 | for (i = 4; i < 11; i++) |
198 | reg[i] = 0; | | 198 | reg[i] = 0; |
199 | | | 199 | |
200 | ucp->uc_stack.ss_sp = (void *) (stack-4); /* to prevent clearing */ | | 200 | ucp->uc_stack.ss_sp = (void *) (stack-4); /* to prevent clearing */ |
201 | ucp->uc_stack.ss_size = 0; //pack->ep_ssize; | | 201 | ucp->uc_stack.ss_size = 0; //pack->ep_ssize; |
202 | thunk_makecontext(ucp, (void *) pack->ep_entry, 0, NULL, NULL, NULL); | | 202 | thunk_makecontext(ucp, (void *) pack->ep_entry, 0, NULL, NULL, NULL); |
203 | | | 203 | |
204 | /* patch up */ | | 204 | /* patch up */ |
205 | reg[ 8] = l->l_proc->p_psstrp; /* _REG_EBX */ | | 205 | reg[ 8] = l->l_proc->p_psstrp; /* _REG_EBX */ |
206 | reg[17] = (stack); /* _REG_UESP */ | | 206 | reg[17] = (stack); /* _REG_UESP */ |
207 | | | 207 | |
208 | //dump_regs(reg); | | 208 | //dump_regs(reg); |
209 | | | 209 | |
210 | #ifdef DEBUG_EXEC | | 210 | #ifdef DEBUG_EXEC |
211 | printf("updated pcb %p\n", pcb); | | 211 | printf("updated pcb %p\n", pcb); |
212 | printf("\tpcb->pcb_ucp.uc_stack.ss_sp = %p\n", | | 212 | printf("\tpcb->pcb_ucp.uc_stack.ss_sp = %p\n", |
213 | pcb->pcb_ucp.uc_stack.ss_sp); | | 213 | pcb->pcb_ucp.uc_stack.ss_sp); |
214 | printf("\tpcb->pcb_ucp.uc_stack.ss_size = %d\n", | | 214 | printf("\tpcb->pcb_ucp.uc_stack.ss_size = %d\n", |
215 | (int) pcb->pcb_ucp.uc_stack.ss_size); | | 215 | (int) pcb->pcb_ucp.uc_stack.ss_size); |
216 | printf("\tpcb->pcb_userret_ucp.uc_stack.ss_sp = %p\n", | | 216 | printf("\tpcb->pcb_userret_ucp.uc_stack.ss_sp = %p\n", |
217 | pcb->pcb_userret_ucp.uc_stack.ss_sp); | | 217 | pcb->pcb_userret_ucp.uc_stack.ss_sp); |
218 | printf("\tpcb->pcb_userret_ucp.uc_stack.ss_size = %d\n", | | 218 | printf("\tpcb->pcb_userret_ucp.uc_stack.ss_size = %d\n", |
219 | (int) pcb->pcb_userret_ucp.uc_stack.ss_size); | | 219 | (int) pcb->pcb_userret_ucp.uc_stack.ss_size); |
220 | printf("\tpack->ep_entry = %p\n", | | 220 | printf("\tpack->ep_entry = %p\n", |
221 | (void *) pack->ep_entry); | | 221 | (void *) pack->ep_entry); |
222 | #endif | | 222 | #endif |
223 | } | | 223 | } |
224 | | | 224 | |
225 | void | | 225 | void |
226 | md_syscall_get_syscallnumber(ucontext_t *ucp, uint32_t *code) | | 226 | md_syscall_get_syscallnumber(ucontext_t *ucp, uint32_t *code) |
227 | { | | 227 | { |
228 | uint *reg = (int *) &ucp->uc_mcontext; | | 228 | uint *reg = (int *) &ucp->uc_mcontext; |
229 | *code = reg[11]; /* EAX */ | | 229 | *code = reg[11]; /* EAX */ |
230 | } | | 230 | } |
231 | | | 231 | |
232 | int | | 232 | int |
233 | md_syscall_getargs(lwp_t *l, ucontext_t *ucp, int nargs, int argsize, | | 233 | md_syscall_getargs(lwp_t *l, ucontext_t *ucp, int nargs, int argsize, |
234 | register_t *args) | | 234 | register_t *args) |
235 | { | | 235 | { |
236 | uint *reg = (int *) &ucp->uc_mcontext; | | 236 | uint *reg = (int *) &ucp->uc_mcontext; |
237 | register_t *sp = (register_t *) reg[17];/* ESP */ | | 237 | register_t *sp = (register_t *) reg[17];/* ESP */ |
238 | int ret; | | 238 | int ret; |
239 | | | 239 | |
240 | //dump_regs(reg); | | 240 | //dump_regs(reg); |
241 | ret = copyin(sp + 1, args, argsize); | | 241 | ret = copyin(sp + 1, args, argsize); |
242 | | | 242 | |
243 | return ret; | | 243 | return ret; |
244 | } | | 244 | } |
245 | | | 245 | |
246 | void | | 246 | void |
247 | md_syscall_set_returnargs(lwp_t *l, ucontext_t *ucp, | | 247 | md_syscall_set_returnargs(lwp_t *l, ucontext_t *ucp, |
248 | int error, register_t *rval) | | 248 | int error, register_t *rval) |
249 | { | | 249 | { |
250 | register_t *reg = (register_t *) &ucp->uc_mcontext; | | 250 | register_t *reg = (register_t *) &ucp->uc_mcontext; |
251 | | | 251 | |
252 | reg[16] &= ~PSL_C; /* EFL */ | | 252 | reg[16] &= ~PSL_C; /* EFL */ |
253 | if (error) { | | 253 | if (error > 0) { |
254 | rval[0] = error; | | 254 | rval[0] = error; |
255 | reg[16] |= PSL_C; /* EFL */ | | 255 | reg[16] |= PSL_C; /* EFL */ |
256 | } | | 256 | } |
257 | | | 257 | |
258 | /* set return parameters */ | | 258 | /* set return parameters */ |
259 | reg[11] = rval[0]; /* EAX */ | | 259 | reg[11] = rval[0]; /* EAX */ |
260 | if (!error) | | 260 | if (error == 0) |
261 | reg[ 9] = rval[1]; /* EDX */ | | 261 | reg[ 9] = rval[1]; /* EDX */ |
262 | | | 262 | |
263 | //dump_regs(reg); | | 263 | //dump_regs(reg); |
264 | } | | 264 | } |
265 | | | 265 | |
266 | int | | 266 | int |
267 | md_syscall_check_opcode(void *ptr) | | 267 | md_syscall_check_opcode(void *ptr) |
268 | { | | 268 | { |
269 | uint16_t *p16; | | 269 | uint16_t *p16; |
270 | | | 270 | |
271 | /* undefined instruction */ | | 271 | /* undefined instruction */ |
272 | p16 = (uint16_t *) ptr; | | 272 | p16 = (uint16_t *) ptr; |
273 | if (*p16 == 0xff0f) | | 273 | if (*p16 == 0xff0f) |
274 | return 1; | | 274 | return 1; |
275 | if (*p16 == 0xff0b) | | 275 | if (*p16 == 0xff0b) |
276 | return 1; | | 276 | return 1; |
277 | | | 277 | |
278 | /* TODO int $80 and sysenter */ | | 278 | /* TODO int $80 and sysenter */ |
279 | return 0; | | 279 | return 0; |
280 | } | | 280 | } |
281 | | | 281 | |
282 | void | | 282 | void |
283 | md_syscall_get_opcode(ucontext_t *ucp, uint32_t *opcode) | | 283 | md_syscall_get_opcode(ucontext_t *ucp, uint32_t *opcode) |
284 | { | | 284 | { |
285 | uint *reg = (int *) &ucp->uc_mcontext; | | 285 | uint *reg = (int *) &ucp->uc_mcontext; |
286 | // uint8_t *p8 = (uint8_t *) (reg[14]); | | 286 | // uint8_t *p8 = (uint8_t *) (reg[14]); |
287 | uint16_t *p16 = (uint16_t*) (reg[14]); | | 287 | uint16_t *p16 = (uint16_t*) (reg[14]); |
288 | | | 288 | |
289 | *opcode = 0; | | 289 | *opcode = 0; |
290 | | | 290 | |
291 | if (*p16 == 0xff0f) | | 291 | if (*p16 == 0xff0f) |
292 | *opcode = *p16; | | 292 | *opcode = *p16; |
293 | if (*p16 == 0xff0b) | | 293 | if (*p16 == 0xff0b) |
294 | *opcode = *p16; | | 294 | *opcode = *p16; |
295 | | | 295 | |
296 | /* TODO int $80 and sysenter */ | | 296 | /* TODO int $80 and sysenter */ |
297 | } | | 297 | } |
298 | | | 298 | |
299 | void | | 299 | void |
300 | md_syscall_inc_pc(ucontext_t *ucp, uint32_t opcode) | | 300 | md_syscall_inc_pc(ucontext_t *ucp, uint32_t opcode) |
301 | { | | 301 | { |
302 | uint *reg = (int *) &ucp->uc_mcontext; | | 302 | uint *reg = (int *) &ucp->uc_mcontext; |
303 | | | 303 | |
304 | /* advance program counter */ | | 304 | /* advance program counter */ |
305 | if (opcode == 0xff0f) | | 305 | if (opcode == 0xff0f) |
306 | reg[14] += 2; /* EIP */ | | 306 | reg[14] += 2; /* EIP */ |
307 | if (opcode == 0xff0b) | | 307 | if (opcode == 0xff0b) |
308 | reg[14] += 2; /* EIP */ | | 308 | reg[14] += 2; /* EIP */ |
309 | | | 309 | |
310 | /* TODO int $80 and sysenter */ | | 310 | /* TODO int $80 and sysenter */ |
311 | } | | 311 | } |
312 | | | 312 | |
313 | void | | 313 | void |
314 | md_syscall_dec_pc(ucontext_t *ucp, uint32_t opcode) | | 314 | md_syscall_dec_pc(ucontext_t *ucp, uint32_t opcode) |
315 | { | | 315 | { |
316 | uint *reg = (int *) &ucp->uc_mcontext; | | 316 | uint *reg = (int *) &ucp->uc_mcontext; |
317 | | | 317 | |
318 | /* advance program counter */ | | 318 | /* advance program counter */ |
319 | if (opcode == 0xff0f) | | 319 | if (opcode == 0xff0f) |
320 | reg[14] -= 2; /* EIP */ | | 320 | reg[14] -= 2; /* EIP */ |
321 | if (opcode == 0xff0b) | | 321 | if (opcode == 0xff0b) |
322 | reg[14] -= 2; /* EIP */ | | 322 | reg[14] -= 2; /* EIP */ |
323 | | | 323 | |
324 | /* TODO int $80 and sysenter */ | | 324 | /* TODO int $80 and sysenter */ |
325 | } | | 325 | } |
326 | | | 326 | |
327 | | | 327 | |
328 | #else | | 328 | #else |
329 | # error machdep functions not yet ported to this architecture | | 329 | # error machdep functions not yet ported to this architecture |
330 | #endif | | 330 | #endif |
331 | | | 331 | |