1 /* $NetBSD: netbsd32_machdep.c,v 1.25 2024/06/18 13:29:56 rin Exp $ */
2
3 /*
4 * Copyright (c) 2018 Ryo Shimizu
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
20 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
22 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
24 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
25 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26 * POSSIBILITY OF SUCH DAMAGE.
27 */
28
29 #include <sys/cdefs.h>
30 __KERNEL_RCSID(0, "$NetBSD: netbsd32_machdep.c,v 1.25 2024/06/18 13:29:56 rin Exp $");
31
32 #if defined(_KERNEL_OPT)
33 #include "opt_compat_netbsd.h"
34 #endif
35
36 #include <sys/param.h>
37 #include <sys/core.h>
38 #include <sys/exec.h>
39 #include <sys/lwp.h>
40 #include <sys/ptrace.h>
41 #include <sys/ras.h>
42 #include <sys/signalvar.h>
43 #include <sys/syscallargs.h>
44 #include <sys/compat_stub.h>
45
46 #include <uvm/uvm_extern.h>
47
48 #include <compat/netbsd32/netbsd32.h>
49 #include <compat/netbsd32/netbsd32_exec.h>
50 #include <compat/netbsd32/netbsd32_syscallargs.h>
51
52 #include <aarch64/armreg.h>
53 #include <aarch64/frame.h>
54 #include <aarch64/machdep.h>
55 #include <aarch64/userret.h>
56
57 #include <arm/cpufunc.h>
58
59 const char machine32[] = MACHINE;
60 const char machine_arch32[] = MACHINE32_ARCH;
61
62 void
netbsd32_setregs(struct lwp * l,struct exec_package * pack,vaddr_t stack)63 netbsd32_setregs(struct lwp *l, struct exec_package *pack, vaddr_t stack)
64 {
65 struct proc * const p = l->l_proc;
66 struct trapframe * const tf = lwp_trapframe(l);
67
68 netbsd32_adjust_limits(p);
69
70 aarch64_setregs_ptrauth(l, false);
71
72 p->p_flag |= PK_32;
73
74 /*
75 * void __start(struct ps_strings *ps_strings, const Obj_Entry *obj,
76 * void (*cleanup)(void));
77 */
78 memset(tf, 0, sizeof(*tf));
79 tf->tf_reg[0] = (uint32_t)p->p_psstrp;
80 tf->tf_reg[12] = stack; /* r12 needed by pre 1.4 crt0.c */
81 tf->tf_reg[13] = stack; /* sp */
82 tf->tf_reg[14] = pack->ep_entry;/* lr */
83 tf->tf_reg[18] = 0x77777777; /* svc_lr. adjust to arm_machdep.c */
84 tf->tf_pc = pack->ep_entry;
85
86
87 /* set 32bit mode, and same endian as 64bit's */
88 #ifdef __AARCH64EB__
89 tf->tf_spsr = SPSR_M_USR32 | SPSR_A32_E;
90 #else
91 tf->tf_spsr = SPSR_M_USR32;
92 #endif
93
94 /* THUMB CODE? */
95 if (pack->ep_entry & 1)
96 tf->tf_spsr |= SPSR_A32_T;
97 }
98
99 int
netbsd32_ptrace_translate_request(int req)100 netbsd32_ptrace_translate_request(int req)
101 {
102
103 switch (req) {
104 case 0 ... PT_FIRSTMACH - 1:
105 return req;
106 case PT32_GETREGS:
107 return PT_GETREGS;
108 case PT32_SETREGS:
109 return PT_SETREGS;
110 case PT32_GETFPREGS:
111 return PT_GETFPREGS;
112 case PT32_SETFPREGS:
113 return PT_SETFPREGS;
114 /* not implemented for arm32 */
115 case PT32_STEP:
116 case PT32_SETSTEP:
117 case PT32_CLEARSTEP:
118 default:
119 return -1;
120 }
121 }
122
123 /* aarch32 fpscr register is assigned to two registers fpsr/fpcr on aarch64 */
124 #define FPSR_BITS \
125 (FPSR_N32|FPSR_Z32|FPSR_C32|FPSR_V32|FPSR_QC| \
126 FPSR_IDC|FPSR_IXC|FPSR_UFC|FPSR_OFC|FPSR_DZC|FPSR_IOC)
127 #define FPCR_BITS \
128 (FPCR_AHP|FPCR_DN|FPCR_FZ|FPCR_RMODE|FPCR_STRIDE|FPCR_LEN| \
129 FPCR_IDE|FPCR_IXE|FPCR_UFE|FPCR_OFE|FPCR_DZE|FPCR_IOE)
130
131 int
netbsd32_process_read_regs(struct lwp * l,struct reg32 * regs)132 netbsd32_process_read_regs(struct lwp *l, struct reg32 *regs)
133 {
134 struct proc * const p = l->l_proc;
135 struct trapframe *tf = lwp_trapframe(l);
136 int i;
137
138 if ((p->p_flag & PK_32) == 0)
139 return EINVAL;
140
141 for (i = 0; i < 13; i++)
142 regs->r[i] = tf->tf_reg[i]; /* r0-r12 */
143 regs->r_sp = tf->tf_reg[13]; /* r13 = sp */
144 regs->r_lr = tf->tf_reg[14]; /* r14 = lr */
145 regs->r_pc = tf->tf_pc; /* r15 = pc */
146 regs->r_cpsr = tf->tf_spsr;
147
148 /* THUMB CODE? */
149 if (tf->tf_spsr & SPSR_A32_T)
150 regs->r_pc |= 1;
151
152 return 0;
153 }
154
155 int
netbsd32_process_read_fpregs(struct lwp * l,struct fpreg32 * fpregs,size_t * lenp)156 netbsd32_process_read_fpregs(struct lwp *l, struct fpreg32 *fpregs,
157 size_t *lenp)
158 {
159 struct proc * const p = l->l_proc;
160 struct pcb * const pcb = lwp_getpcb(l);
161 int i, j;
162
163 if ((p->p_flag & PK_32) == 0)
164 return EINVAL;
165
166 KASSERT(*lenp <= sizeof(*fpregs));
167 fpu_save(l);
168
169 /*
170 * convert from aarch64's struct fpreg to arm's struct fpreg32
171 */
172 #define VFP_FPEXC_EN 0x40000000 /* VFP Enable bit */
173 #define VFP_FPEXC_VECITR 0x00000700 /* VECtor ITeRation count */
174 fpregs->fpr_vfp.vfp_fpexc = VFP_FPEXC_EN | VFP_FPEXC_VECITR;
175
176 fpregs->fpr_vfp.vfp_fpscr =
177 (pcb->pcb_fpregs.fpsr & FPSR_BITS) |
178 (pcb->pcb_fpregs.fpcr & FPCR_BITS);
179
180 fpregs->fpr_vfp.vfp_fpinst = 0;
181 fpregs->fpr_vfp.vfp_fpinst2 = 0;
182
183 for (i = j = 0; i < 16; i++) {
184 #ifdef __AARCH64EB__
185 fpregs->fpr_vfp.vfp_regs[j++] =
186 pcb->pcb_fpregs.fp_reg[i].u64[1];
187 fpregs->fpr_vfp.vfp_regs[j++] =
188 pcb->pcb_fpregs.fp_reg[i].u64[0];
189 #else
190 fpregs->fpr_vfp.vfp_regs[j++] =
191 pcb->pcb_fpregs.fp_reg[i].u64[0];
192 fpregs->fpr_vfp.vfp_regs[j++] =
193 pcb->pcb_fpregs.fp_reg[i].u64[1];
194 #endif
195 }
196
197 return 0;
198 }
199
200 int
netbsd32_process_write_regs(struct lwp * l,const struct reg32 * regs)201 netbsd32_process_write_regs(struct lwp *l, const struct reg32 *regs)
202 {
203 struct proc * const p = l->l_proc;
204 struct trapframe *tf = lwp_trapframe(l);
205 int i;
206
207 if ((p->p_flag & PK_32) == 0)
208 return EINVAL;
209
210 if (regs->r_pc >= VM_MAXUSER_ADDRESS32 ||
211 regs->r_sp >= VM_MAXUSER_ADDRESS32)
212 return EINVAL;
213
214 for (i = 0; i < 13; i++)
215 tf->tf_reg[i] = regs->r[i]; /* r0-r12 */
216 tf->tf_reg[13] = regs->r_sp; /* r13 = sp */
217 tf->tf_reg[14] = regs->r_lr; /* r14 = lr */
218 tf->tf_pc = regs->r_pc; /* r15 = pc */
219 tf->tf_spsr &= ~(SPSR_NZCV | SPSR_A32_T);
220 tf->tf_spsr |= regs->r_cpsr & (SPSR_NZCV | SPSR_A32_T);
221
222 /* THUMB CODE? */
223 if (regs->r_pc & 1)
224 tf->tf_spsr |= SPSR_A32_T;
225
226 return 0;
227 }
228
229 int
netbsd32_process_write_fpregs(struct lwp * l,const struct fpreg32 * fpregs,size_t len)230 netbsd32_process_write_fpregs(struct lwp *l, const struct fpreg32 *fpregs,
231 size_t len)
232 {
233 struct proc * const p = l->l_proc;
234 struct pcb * const pcb = lwp_getpcb(l);
235 int i, j;
236
237 if ((p->p_flag & PK_32) == 0)
238 return EINVAL;
239
240 KASSERT(len <= sizeof(*fpregs));
241 fpu_discard(l, true); // set used flag
242
243 pcb->pcb_fpregs.fpsr = fpregs->fpr_vfp.vfp_fpscr & FPSR_BITS;
244 pcb->pcb_fpregs.fpcr = fpregs->fpr_vfp.vfp_fpscr & FPCR_BITS;
245
246 for (i = j = 0; i < 16; i++) {
247 #ifdef __AARCH64EB__
248 pcb->pcb_fpregs.fp_reg[i].u64[1] =
249 fpregs->fpr_vfp.vfp_regs[j++];
250 pcb->pcb_fpregs.fp_reg[i].u64[0] =
251 fpregs->fpr_vfp.vfp_regs[j++];
252 #else
253 pcb->pcb_fpregs.fp_reg[i].u64[0] =
254 fpregs->fpr_vfp.vfp_regs[j++];
255 pcb->pcb_fpregs.fp_reg[i].u64[1] =
256 fpregs->fpr_vfp.vfp_regs[j++];
257 #endif
258 }
259
260 return 0;
261 }
262
263 int
cpu_coredump32(struct lwp * l,struct coredump_iostate * iocookie,struct core32 * chdr)264 cpu_coredump32(struct lwp *l, struct coredump_iostate *iocookie,
265 struct core32 *chdr)
266 {
267 struct netbsd32_cpustate md_core32;
268 struct coreseg32 cseg;
269 int error;
270
271 if (iocookie == NULL) {
272 CORE_SETMAGIC(*chdr, COREMAGIC, MID_ARM6, 0);
273 chdr->c_hdrsize = ALIGN32(sizeof(*chdr));
274 chdr->c_seghdrsize = ALIGN32(sizeof(cseg));
275 chdr->c_cpusize = sizeof(md_core32);
276 chdr->c_nseg++;
277 return 0;
278 }
279
280 error = netbsd32_process_read_regs(l, &md_core32.regs);
281 if (error)
282 return error;
283
284 error = netbsd32_process_read_fpregs(l, &md_core32.fpregs, NULL);
285 if (error)
286 return error;
287
288 CORE_SETMAGIC(cseg, CORESEGMAGIC, MID_ARM6, CORE_CPU);
289 cseg.c_addr = 0;
290 cseg.c_size = chdr->c_cpusize;
291
292 MODULE_HOOK_CALL(coredump_write_hook, (iocookie, UIO_SYSSPACE,
293 &cseg, chdr->c_seghdrsize), ENOSYS, error);
294 if (error)
295 return error;
296
297 MODULE_HOOK_CALL(coredump_write_hook, (iocookie, UIO_SYSSPACE,
298 &md_core32, sizeof(md_core32)), ENOSYS, error);
299
300 return error;
301 }
302
303 void
netbsd32_sendsig_siginfo(const ksiginfo_t * ksi,const sigset_t * mask)304 netbsd32_sendsig_siginfo(const ksiginfo_t *ksi, const sigset_t *mask)
305 {
306 struct lwp * const l = curlwp;
307 struct proc * const p = l->l_proc;
308 struct trapframe * const tf = lwp_trapframe(l);
309 stack_t * const ss = &l->l_sigstk;
310 const int signo = ksi->ksi_signo;
311 const struct sigaction * const sa = &SIGACTION(p, signo);
312 const struct sigact_sigdesc * const sdesc =
313 &p->p_sigacts->sa_sigdesc[signo];
314 const sig_t handler = sa->sa_handler;
315 struct netbsd32_sigframe_siginfo *fp, frame;
316 int error;
317
318 const bool onstack_p =
319 (ss->ss_flags & (SS_DISABLE | SS_ONSTACK)) == 0 &&
320 (sa->sa_flags & SA_ONSTACK);
321
322 vaddr_t sp = onstack_p ?
323 ((vaddr_t)ss->ss_sp + ss->ss_size) :
324 tf->tf_reg[13]; /* r13 = sp on aarch32 */
325
326 fp = (struct netbsd32_sigframe_siginfo *)sp;
327 fp = (struct netbsd32_sigframe_siginfo *)STACK_ALIGN(fp - 1, (8 - 1));
328
329 memset(&frame, 0, sizeof(frame));
330
331 /* XXX: netbsd32_ksi_to_si32 */
332 netbsd32_si_to_si32(&frame.sf_si, (const siginfo_t *)&ksi->ksi_info);
333
334 frame.sf_uc.uc_flags = _UC_SIGMASK;
335 frame.sf_uc.uc_sigmask = *mask;
336 frame.sf_uc.uc_link = (uint32_t)(uintptr_t)l->l_ctxlink;
337 frame.sf_uc.uc_flags |= (l->l_sigstk.ss_flags & SS_ONSTACK) ?
338 _UC_SETSTACK : _UC_CLRSTACK;
339 sendsig_reset(l, signo);
340
341 mutex_exit(p->p_lock);
342 cpu_getmcontext32(l, &frame.sf_uc.uc_mcontext, &frame.sf_uc.uc_flags);
343 error = copyout(&frame, fp, sizeof(frame));
344 mutex_enter(p->p_lock);
345
346 if (error != 0) {
347 /*
348 * Process has trashed its stack;
349 * give it an illegal instruction to halt it in its tracks.
350 */
351 sigexit(l, SIGILL);
352 /* NOTREACHED */
353 }
354
355 tf->tf_reg[0] = signo;
356 tf->tf_reg[1] = (uint32_t)(uintptr_t)&fp->sf_si;
357 tf->tf_reg[2] = (uint32_t)(uintptr_t)&fp->sf_uc;
358
359 /* the trampoline uses r5 as the uc address */
360 tf->tf_reg[5] = (uint32_t)(uintptr_t)&fp->sf_uc;
361 tf->tf_pc = (uint32_t)(uintptr_t)handler;
362
363 /* THUMB CODE? */
364 if (((uintptr_t)handler) & 1)
365 tf->tf_spsr |= SPSR_A32_T;
366 else
367 tf->tf_spsr &= ~SPSR_A32_T;
368
369 tf->tf_reg[13] = (uint32_t)(uintptr_t)fp; /* sp */
370 tf->tf_reg[14] = (uint32_t)(uintptr_t)sdesc->sd_tramp; /* lr */
371
372 /* Remember if we're now on the signal stack */
373 if (onstack_p)
374 ss->ss_flags |= SS_ONSTACK;
375 }
376
377 void
startlwp32(void * arg)378 startlwp32(void *arg)
379 {
380 ucontext32_t *uc = arg;
381 lwp_t *l = curlwp;
382 int error __diagused;
383
384 /*
385 * entity of *uc is ucontext_t. therefore
386 * ucontext_t must be greater than ucontext32_t
387 */
388 CTASSERT(sizeof(ucontext_t) >= sizeof(ucontext32_t));
389
390 error = cpu_setmcontext32(l, &uc->uc_mcontext, uc->uc_flags);
391 KASSERT(error == 0);
392
393 /* Note: we are freeing ucontext_t, not ucontext32_t. */
394 kmem_free(uc, sizeof(ucontext_t));
395 userret(l);
396 }
397
398 int
cpu_mcontext32_validate(struct lwp * l,const mcontext32_t * mcp)399 cpu_mcontext32_validate(struct lwp *l, const mcontext32_t *mcp)
400 {
401 struct proc * const p __diagused = l->l_proc;
402 const uint32_t spsr = mcp->__gregs[_REG_CPSR];
403
404 KASSERT(p->p_flag & PK_32);
405
406 if (__SHIFTOUT(spsr, SPSR_M) != SPSR_M_USR32)
407 return EINVAL;
408
409 #ifdef __AARCH64EB__
410 if ((spsr & SPSR_A32_E) == 0)
411 return EINVAL;
412 #else
413 if ((spsr & SPSR_A32_E) != 0)
414 return EINVAL;
415 #endif
416
417 if ((spsr & (SPSR_A|SPSR_I|SPSR_F)) != 0)
418 return EINVAL;
419
420 return 0;
421 }
422 void
cpu_getmcontext32(struct lwp * l,mcontext32_t * mcp,unsigned int * flagsp)423 cpu_getmcontext32(struct lwp *l, mcontext32_t *mcp, unsigned int *flagsp)
424 {
425 struct trapframe * const tf = lwp_trapframe(l);
426 __greg32_t *gr = mcp->__gregs;
427 void *ras_pc;
428
429 gr[_REG_R0] = tf->tf_reg[0];
430 gr[_REG_R1] = tf->tf_reg[1];
431 gr[_REG_R2] = tf->tf_reg[2];
432 gr[_REG_R3] = tf->tf_reg[3];
433 gr[_REG_R4] = tf->tf_reg[4];
434 gr[_REG_R5] = tf->tf_reg[5];
435 gr[_REG_R6] = tf->tf_reg[6];
436 gr[_REG_R7] = tf->tf_reg[7];
437 gr[_REG_R8] = tf->tf_reg[8];
438 gr[_REG_R9] = tf->tf_reg[9];
439 gr[_REG_R10] = tf->tf_reg[10];
440 gr[_REG_R11] = tf->tf_reg[11];
441 gr[_REG_R12] = tf->tf_reg[12];
442 gr[_REG_R13] = tf->tf_reg[13];
443 gr[_REG_R14] = tf->tf_reg[14];
444 gr[_REG_R15] = tf->tf_pc;
445 gr[_REG_CPSR] = tf->tf_spsr;
446
447 ras_pc = ras_lookup(l->l_proc, (void *)(uintptr_t)gr[_REG_R15]);
448 if (ras_pc != (void *)-1) {
449 gr[_REG_R15] = (__greg32_t)(uintptr_t)ras_pc;
450 }
451 *flagsp |= _UC_CPU;
452
453 /* fpu context */
454 if (fpu_used_p(l)) {
455 const struct pcb * const pcb = lwp_getpcb(l);
456 int i, j;
457
458 fpu_save(l);
459
460 for (i = j = 0; i < 16; i++) {
461 #ifdef __AARCH64EB__
462 mcp->__vfpregs.__vfp_fstmx[j++] =
463 pcb->pcb_fpregs.fp_reg[i].u64[1];
464 mcp->__vfpregs.__vfp_fstmx[j++] =
465 pcb->pcb_fpregs.fp_reg[i].u64[0];
466 #else
467 mcp->__vfpregs.__vfp_fstmx[j++] =
468 pcb->pcb_fpregs.fp_reg[i].u64[0];
469 mcp->__vfpregs.__vfp_fstmx[j++] =
470 pcb->pcb_fpregs.fp_reg[i].u64[1];
471 #endif
472 }
473
474 mcp->__vfpregs.__vfp_fpscr =
475 (pcb->pcb_fpregs.fpsr & FPSR_BITS) |
476 (pcb->pcb_fpregs.fpcr & FPCR_BITS);
477 mcp->__vfpregs.__vfp_fpsid = 0; /* XXX: build FPSID from MIDR */
478
479 *flagsp |= _UC_FPU;
480 }
481
482 mcp->_mc_tlsbase = (uint32_t)(uintptr_t)l->l_private;
483 *flagsp |= _UC_TLSBASE;
484 }
485
486 int
cpu_setmcontext32(struct lwp * l,const mcontext32_t * mcp,unsigned int flags)487 cpu_setmcontext32(struct lwp *l, const mcontext32_t *mcp, unsigned int flags)
488 {
489 struct trapframe * const tf = lwp_trapframe(l);
490 const __greg32_t * const gr = mcp->__gregs;
491 struct proc * const p = l->l_proc;
492 int error, i, j;
493
494 if (flags & _UC_CPU) {
495 error = cpu_mcontext32_validate(l, mcp);
496 if (error != 0)
497 return error;
498
499 tf->tf_reg[0] = gr[_REG_R0];
500 tf->tf_reg[1] = gr[_REG_R1];
501 tf->tf_reg[2] = gr[_REG_R2];
502 tf->tf_reg[3] = gr[_REG_R3];
503 tf->tf_reg[4] = gr[_REG_R4];
504 tf->tf_reg[5] = gr[_REG_R5];
505 tf->tf_reg[6] = gr[_REG_R6];
506 tf->tf_reg[7] = gr[_REG_R7];
507 tf->tf_reg[8] = gr[_REG_R8];
508 tf->tf_reg[9] = gr[_REG_R9];
509 tf->tf_reg[10] = gr[_REG_R10];
510 tf->tf_reg[11] = gr[_REG_R11];
511 tf->tf_reg[12] = gr[_REG_R12];
512 tf->tf_reg[13] = gr[_REG_R13];
513 tf->tf_reg[14] = gr[_REG_R14];
514 tf->tf_pc = gr[_REG_R15];
515 tf->tf_spsr = gr[_REG_CPSR];
516 }
517
518 if (flags & _UC_FPU) {
519 struct pcb * const pcb = lwp_getpcb(l);
520 fpu_discard(l, true);
521
522 for (i = j = 0; i < 16; i++) {
523 #ifdef __AARCH64EB__
524 pcb->pcb_fpregs.fp_reg[i].u64[1] =
525 mcp->__vfpregs.__vfp_fstmx[j++];
526 pcb->pcb_fpregs.fp_reg[i].u64[0] =
527 mcp->__vfpregs.__vfp_fstmx[j++];
528 #else
529 pcb->pcb_fpregs.fp_reg[i].u64[0] =
530 mcp->__vfpregs.__vfp_fstmx[j++];
531 pcb->pcb_fpregs.fp_reg[i].u64[1] =
532 mcp->__vfpregs.__vfp_fstmx[j++];
533 #endif
534 }
535 pcb->pcb_fpregs.fpsr =
536 mcp->__vfpregs.__vfp_fpscr & FPSR_BITS;
537 pcb->pcb_fpregs.fpcr =
538 mcp->__vfpregs.__vfp_fpscr & FPCR_BITS;
539 }
540
541 if (flags &_UC_TLSBASE)
542 l->l_private = (void *)(uintptr_t)mcp->_mc_tlsbase;
543
544 mutex_enter(p->p_lock);
545 if (flags & _UC_SETSTACK)
546 l->l_sigstk.ss_flags |= SS_ONSTACK;
547 if (flags & _UC_CLRSTACK)
548 l->l_sigstk.ss_flags &= ~SS_ONSTACK;
549 mutex_exit(p->p_lock);
550
551 return 0;
552 }
553
554 static int
arm32_sync_icache(struct lwp * l,const void * args,register_t * retval)555 arm32_sync_icache(struct lwp *l, const void *args, register_t *retval)
556 {
557 struct netbsd32_arm_sync_icache_args ua;
558 struct faultbuf fb;
559 int error;
560
561 error = copyin(args, &ua, sizeof(ua));
562 if (error != 0)
563 return error;
564
565 if ((vaddr_t)ua.addr + ua.len > VM_MAXUSER_ADDRESS32)
566 return EINVAL;
567
568 /* use cpu_set_onfault() by way of precaution */
569 if ((error = cpu_set_onfault(&fb)) == 0) {
570 pmap_icache_sync_range(
571 vm_map_pmap(&l->l_proc->p_vmspace->vm_map),
572 (vaddr_t)ua.addr, (vaddr_t)ua.addr + ua.len);
573 cpu_unset_onfault();
574 }
575
576 *retval = 0;
577 return error;
578 }
579
580 static int
arm32_drain_writebuf(struct lwp * l,const void * args,register_t * retval)581 arm32_drain_writebuf(struct lwp *l, const void *args, register_t *retval)
582 {
583 aarch64_drain_writebuf();
584
585 *retval = 0;
586 return 0;
587 }
588
589 int
netbsd32_sysarch(struct lwp * l,const struct netbsd32_sysarch_args * uap,register_t * retval)590 netbsd32_sysarch(struct lwp *l, const struct netbsd32_sysarch_args *uap,
591 register_t *retval)
592 {
593 /* {
594 syscallarg(int) op;
595 syscallarg(netbsd32_voidp) parms;
596 } */
597 int error;
598
599 switch (SCARG(uap, op)) {
600 case ARM_SYNC_ICACHE:
601 error = arm32_sync_icache(l,
602 NETBSD32PTR64(SCARG(uap, parms)), retval);
603 break;
604 case ARM_DRAIN_WRITEBUF:
605 error = arm32_drain_writebuf(l,
606 NETBSD32PTR64(SCARG(uap, parms)), retval);
607 break;
608 case ARM_VFP_FPSCR:
609 printf("%s: ARM_VFP_FPSCR not implemented\n", __func__);
610 error = EINVAL;
611 break;
612 case ARM_FPU_USED:
613 printf("%s: ARM_FPU_USED not implemented\n", __func__);
614 error = EINVAL;
615 break;
616 default:
617 printf("%s: op=%d: not implemented\n", __func__,
618 SCARG(uap, op));
619 error = EINVAL;
620 break;
621 }
622 return error;
623 }
624
625 vaddr_t
netbsd32_vm_default_addr(struct proc * p,vaddr_t base,vsize_t sz,int topdown)626 netbsd32_vm_default_addr(struct proc *p, vaddr_t base, vsize_t sz,
627 int topdown)
628 {
629 if (topdown)
630 return VM_DEFAULT_ADDRESS32_TOPDOWN(base, sz);
631 else
632 return VM_DEFAULT_ADDRESS32_BOTTOMUP(base, sz);
633 }
634
635 void
netbsd32_machdep_md_init(void)636 netbsd32_machdep_md_init(void)
637 {
638
639 /* nothing to do */
640 }
641
642 void
netbsd32_machdep_md_fini(void)643 netbsd32_machdep_md_fini(void)
644 {
645
646 /* nothing to do */
647 }
648