2 * Copyright (c) 1992 Terrence R. Lambert.
3 * Copyright (C) 1994, David Greenman
4 * Copyright (c) 1982, 1987, 1990, 1993
5 * The Regents of the University of California. All rights reserved.
7 * This code is derived from software contributed to Berkeley by
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 * 3. All advertising materials mentioning features or use of this software
19 * must display the following acknowledgement:
20 * This product includes software developed by the University of
21 * California, Berkeley and its contributors.
22 * 4. Neither the name of the University nor the names of its contributors
23 * may be used to endorse or promote products derived from this software
24 * without specific prior written permission.
26 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
27 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
29 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
30 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
31 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
32 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
33 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
34 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
35 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
38 * from: @(#)machdep.c 7.4 (Berkeley) 6/3/91
39 * $FreeBSD: src/sys/i386/i386/machdep.c,v 1.385.2.30 2003/05/31 08:48:05 alc Exp $
44 #include "opt_msgbuf.h"
47 #include <sys/param.h>
48 #include <sys/systm.h>
49 #include <sys/sysproto.h>
50 #include <sys/signalvar.h>
51 #include <sys/kernel.h>
52 #include <sys/linker.h>
53 #include <sys/malloc.h>
56 #include <sys/reboot.h>
58 #include <sys/msgbuf.h>
59 #include <sys/sysent.h>
60 #include <sys/sysctl.h>
61 #include <sys/vmmeter.h>
63 #include <sys/usched.h>
67 #include <vm/vm_param.h>
69 #include <vm/vm_kern.h>
70 #include <vm/vm_object.h>
71 #include <vm/vm_page.h>
72 #include <vm/vm_map.h>
73 #include <vm/vm_pager.h>
74 #include <vm/vm_extern.h>
76 #include <sys/thread2.h>
77 #include <sys/mplock2.h>
85 #include <machine/cpu.h>
86 #include <machine/clock.h>
87 #include <machine/specialreg.h>
88 #include <machine/md_var.h>
89 #include <machine/pcb_ext.h> /* pcb.h included via sys/user.h */
90 #include <machine/globaldata.h> /* CPU_prvspace */
91 #include <machine/smp.h>
92 #include <machine/cputypes.h>
94 #include <bus/isa/rtc.h>
95 #include <sys/random.h>
96 #include <sys/ptrace.h>
97 #include <machine/sigframe.h>
98 #include <unistd.h> /* umtx_* functions */
99 #include <pthread.h> /* pthread_yield() */
101 extern void dblfault_handler (void);
103 static void set_fpregs_xmm (struct save87
*, struct savexmm
*);
104 static void fill_fpregs_xmm (struct savexmm
*, struct save87
*);
106 int64_t tsc_offsets
[MAXCPU
];
108 #if defined(SWTCH_OPTIM_STATS)
109 extern int swtch_optim_stats
;
110 SYSCTL_INT(_debug
, OID_AUTO
, swtch_optim_stats
,
111 CTLFLAG_RD
, &swtch_optim_stats
, 0, "");
112 SYSCTL_INT(_debug
, OID_AUTO
, tlb_flush_count
,
113 CTLFLAG_RD
, &tlb_flush_count
, 0, "");
117 sysctl_hw_physmem(SYSCTL_HANDLER_ARGS
)
119 u_long pmem
= ctob(physmem
);
121 int error
= sysctl_handle_long(oidp
, &pmem
, 0, req
);
125 SYSCTL_PROC(_hw
, HW_PHYSMEM
, physmem
, CTLTYPE_ULONG
|CTLFLAG_RD
,
126 0, 0, sysctl_hw_physmem
, "LU", "Total system memory in bytes (number of pages * page size)");
129 sysctl_hw_usermem(SYSCTL_HANDLER_ARGS
)
132 int error
= sysctl_handle_int(oidp
, 0,
133 ctob((int)Maxmem
- vmstats
.v_wire_count
), req
);
137 SYSCTL_PROC(_hw
, HW_USERMEM
, usermem
, CTLTYPE_INT
|CTLFLAG_RD
,
138 0, 0, sysctl_hw_usermem
, "IU", "");
140 SYSCTL_ULONG(_hw
, OID_AUTO
, availpages
, CTLFLAG_RD
, &Maxmem
, 0, "");
143 * Send an interrupt to process.
145 * Stack is set up to allow sigcode stored
146 * at top to call routine, followed by kcall
147 * to sigreturn routine below. After sigreturn
148 * resets the signal mask, the stack, and the
149 * frame pointer, it returns to the user
153 sendsig(sig_t catcher
, int sig
, sigset_t
*mask
, u_long code
)
155 struct lwp
*lp
= curthread
->td_lwp
;
156 struct proc
*p
= lp
->lwp_proc
;
157 struct trapframe
*regs
;
158 struct sigacts
*psp
= p
->p_sigacts
;
159 struct sigframe sf
, *sfp
;
163 regs
= lp
->lwp_md
.md_regs
;
164 oonstack
= (lp
->lwp_sigstk
.ss_flags
& SS_ONSTACK
) ? 1 : 0;
166 /* Save user context */
167 bzero(&sf
, sizeof(struct sigframe
));
168 sf
.sf_uc
.uc_sigmask
= *mask
;
169 sf
.sf_uc
.uc_stack
= lp
->lwp_sigstk
;
170 sf
.sf_uc
.uc_mcontext
.mc_onstack
= oonstack
;
171 KKASSERT(__offsetof(struct trapframe
, tf_rdi
) == 0);
172 bcopy(regs
, &sf
.sf_uc
.uc_mcontext
.mc_rdi
, sizeof(struct trapframe
));
174 /* Make the size of the saved context visible to userland */
175 sf
.sf_uc
.uc_mcontext
.mc_len
= sizeof(sf
.sf_uc
.uc_mcontext
);
177 /* Allocate and validate space for the signal handler context. */
178 if ((lp
->lwp_flags
& LWP_ALTSTACK
) != 0 && !oonstack
&&
179 SIGISMEMBER(psp
->ps_sigonstack
, sig
)) {
180 sp
= (char *)(lp
->lwp_sigstk
.ss_sp
+ lp
->lwp_sigstk
.ss_size
-
181 sizeof(struct sigframe
));
182 lp
->lwp_sigstk
.ss_flags
|= SS_ONSTACK
;
184 /* We take red zone into account */
185 sp
= (char *)regs
->tf_rsp
- sizeof(struct sigframe
) - 128;
188 /* Align to 16 bytes */
189 sfp
= (struct sigframe
*)((intptr_t)sp
& ~0xFUL
);
191 /* Translate the signal is appropriate */
192 if (p
->p_sysent
->sv_sigtbl
) {
193 if (sig
<= p
->p_sysent
->sv_sigsize
)
194 sig
= p
->p_sysent
->sv_sigtbl
[_SIG_IDX(sig
)];
198 * Build the argument list for the signal handler.
200 * Arguments are in registers (%rdi, %rsi, %rdx, %rcx)
202 regs
->tf_rdi
= sig
; /* argument 1 */
203 regs
->tf_rdx
= (register_t
)&sfp
->sf_uc
; /* argument 3 */
205 if (SIGISMEMBER(psp
->ps_siginfo
, sig
)) {
207 * Signal handler installed with SA_SIGINFO.
209 * action(signo, siginfo, ucontext)
211 regs
->tf_rsi
= (register_t
)&sfp
->sf_si
; /* argument 2 */
212 regs
->tf_rcx
= (register_t
)regs
->tf_err
; /* argument 4 */
213 sf
.sf_ahu
.sf_action
= (__siginfohandler_t
*)catcher
;
215 /* fill siginfo structure */
216 sf
.sf_si
.si_signo
= sig
;
217 sf
.sf_si
.si_code
= code
;
218 sf
.sf_si
.si_addr
= (void *)regs
->tf_addr
;
221 * Old FreeBSD-style arguments.
223 * handler (signo, code, [uc], addr)
225 regs
->tf_rsi
= (register_t
)code
; /* argument 2 */
226 regs
->tf_rcx
= (register_t
)regs
->tf_addr
; /* argument 4 */
227 sf
.sf_ahu
.sf_handler
= catcher
;
232 * If we're a vm86 process, we want to save the segment registers.
233 * We also change eflags to be our emulated eflags, not the actual
236 if (regs
->tf_eflags
& PSL_VM
) {
237 struct trapframe_vm86
*tf
= (struct trapframe_vm86
*)regs
;
238 struct vm86_kernel
*vm86
= &lp
->lwp_thread
->td_pcb
->pcb_ext
->ext_vm86
;
240 sf
.sf_uc
.uc_mcontext
.mc_gs
= tf
->tf_vm86_gs
;
241 sf
.sf_uc
.uc_mcontext
.mc_fs
= tf
->tf_vm86_fs
;
242 sf
.sf_uc
.uc_mcontext
.mc_es
= tf
->tf_vm86_es
;
243 sf
.sf_uc
.uc_mcontext
.mc_ds
= tf
->tf_vm86_ds
;
245 if (vm86
->vm86_has_vme
== 0)
246 sf
.sf_uc
.uc_mcontext
.mc_eflags
=
247 (tf
->tf_eflags
& ~(PSL_VIF
| PSL_VIP
)) |
248 (vm86
->vm86_eflags
& (PSL_VIF
| PSL_VIP
));
251 * Clear PSL_NT to inhibit T_TSSFLT faults on return from
252 * syscalls made by the signal handler. This just avoids
253 * wasting time for our lazy fixup of such faults. PSL_NT
254 * does nothing in vm86 mode, but vm86 programs can set it
255 * almost legitimately in probes for old cpu types.
257 tf
->tf_eflags
&= ~(PSL_VM
| PSL_NT
| PSL_VIF
| PSL_VIP
);
262 * Save the FPU state and reinit the FP unit
264 npxpush(&sf
.sf_uc
.uc_mcontext
);
267 * Copy the sigframe out to the user's stack.
269 if (copyout(&sf
, sfp
, sizeof(struct sigframe
)) != 0) {
271 * Something is wrong with the stack pointer.
272 * ...Kill the process.
277 regs
->tf_rsp
= (register_t
)sfp
;
278 regs
->tf_rip
= PS_STRINGS
- *(p
->p_sysent
->sv_szsigcode
);
281 * i386 abi specifies that the direction flag must be cleared
284 regs
->tf_rflags
&= ~(PSL_T
|PSL_D
);
287 * 64 bit mode has a code and stack selector but
288 * no data or extra selector. %fs and %gs are not
291 regs
->tf_cs
= _ucodesel
;
292 regs
->tf_ss
= _udatasel
;
296 * Sanitize the trapframe for a virtual kernel passing control to a custom
297 * VM context. Remove any items that would otherwise create a privilage
300 * XXX at the moment we allow userland to set the resume flag. Is this a
304 cpu_sanitize_frame(struct trapframe
*frame
)
306 frame
->tf_cs
= _ucodesel
;
307 frame
->tf_ss
= _udatasel
;
308 /* XXX VM (8086) mode not supported? */
309 frame
->tf_rflags
&= (PSL_RF
| PSL_USERCHANGE
| PSL_VM_UNSUPP
);
310 frame
->tf_rflags
|= PSL_RESERVED_DEFAULT
| PSL_I
;
316 * Sanitize the tls so loading the descriptor does not blow up
317 * on us. For x86_64 we don't have to do anything.
320 cpu_sanitize_tls(struct savetls
*tls
)
326 * sigreturn(ucontext_t *sigcntxp)
328 * System call to cleanup state after a signal
329 * has been taken. Reset signal mask and
330 * stack state from context left by sendsig (above).
331 * Return to previous pc and psl as specified by
332 * context left by sendsig. Check carefully to
333 * make sure that the user has not modified the
334 * state to gain improper privileges.
336 #define EFL_SECURE(ef, oef) ((((ef) ^ (oef)) & ~PSL_USERCHANGE) == 0)
337 #define CS_SECURE(cs) (ISPL(cs) == SEL_UPL)
340 sys_sigreturn(struct sigreturn_args
*uap
)
342 struct lwp
*lp
= curthread
->td_lwp
;
343 struct trapframe
*regs
;
351 * We have to copy the information into kernel space so userland
352 * can't modify it while we are sniffing it.
354 regs
= lp
->lwp_md
.md_regs
;
355 error
= copyin(uap
->sigcntxp
, &uc
, sizeof(uc
));
359 rflags
= ucp
->uc_mcontext
.mc_rflags
;
361 /* VM (8086) mode not supported */
362 rflags
&= ~PSL_VM_UNSUPP
;
365 if (eflags
& PSL_VM
) {
366 struct trapframe_vm86
*tf
= (struct trapframe_vm86
*)regs
;
367 struct vm86_kernel
*vm86
;
370 * if pcb_ext == 0 or vm86_inited == 0, the user hasn't
371 * set up the vm86 area, and we can't enter vm86 mode.
373 if (lp
->lwp_thread
->td_pcb
->pcb_ext
== 0)
375 vm86
= &lp
->lwp_thread
->td_pcb
->pcb_ext
->ext_vm86
;
376 if (vm86
->vm86_inited
== 0)
379 /* go back to user mode if both flags are set */
380 if ((eflags
& PSL_VIP
) && (eflags
& PSL_VIF
))
381 trapsignal(lp
->lwp_proc
, SIGBUS
, 0);
383 if (vm86
->vm86_has_vme
) {
384 eflags
= (tf
->tf_eflags
& ~VME_USERCHANGE
) |
385 (eflags
& VME_USERCHANGE
) | PSL_VM
;
387 vm86
->vm86_eflags
= eflags
; /* save VIF, VIP */
388 eflags
= (tf
->tf_eflags
& ~VM_USERCHANGE
) | (eflags
& VM_USERCHANGE
) | PSL_VM
;
390 bcopy(&ucp
.uc_mcontext
.mc_gs
, tf
, sizeof(struct trapframe
));
391 tf
->tf_eflags
= eflags
;
392 tf
->tf_vm86_ds
= tf
->tf_ds
;
393 tf
->tf_vm86_es
= tf
->tf_es
;
394 tf
->tf_vm86_fs
= tf
->tf_fs
;
395 tf
->tf_vm86_gs
= tf
->tf_gs
;
396 tf
->tf_ds
= _udatasel
;
397 tf
->tf_es
= _udatasel
;
399 tf
->tf_fs
= _udatasel
;
400 tf
->tf_gs
= _udatasel
;
406 * Don't allow users to change privileged or reserved flags.
409 * XXX do allow users to change the privileged flag PSL_RF.
410 * The cpu sets PSL_RF in tf_eflags for faults. Debuggers
411 * should sometimes set it there too. tf_eflags is kept in
412 * the signal context during signal handling and there is no
413 * other place to remember it, so the PSL_RF bit may be
414 * corrupted by the signal handler without us knowing.
415 * Corruption of the PSL_RF bit at worst causes one more or
416 * one less debugger trap, so allowing it is fairly harmless.
418 if (!EFL_SECURE(rflags
& ~PSL_RF
, regs
->tf_rflags
& ~PSL_RF
)) {
419 kprintf("sigreturn: rflags = 0x%lx\n", (long)rflags
);
424 * Don't allow users to load a valid privileged %cs. Let the
425 * hardware check for invalid selectors, excess privilege in
426 * other selectors, invalid %eip's and invalid %esp's.
428 cs
= ucp
->uc_mcontext
.mc_cs
;
429 if (!CS_SECURE(cs
)) {
430 kprintf("sigreturn: cs = 0x%x\n", cs
);
431 trapsignal(lp
, SIGBUS
, T_PROTFLT
);
434 bcopy(&ucp
->uc_mcontext
.mc_rdi
, regs
, sizeof(struct trapframe
));
438 * Restore the FPU state from the frame
440 npxpop(&ucp
->uc_mcontext
);
442 if (ucp
->uc_mcontext
.mc_onstack
& 1)
443 lp
->lwp_sigstk
.ss_flags
|= SS_ONSTACK
;
445 lp
->lwp_sigstk
.ss_flags
&= ~SS_ONSTACK
;
447 lp
->lwp_sigmask
= ucp
->uc_sigmask
;
448 SIG_CANTMASK(lp
->lwp_sigmask
);
453 * cpu_idle() represents the idle LWKT. You cannot return from this function
454 * (unless you want to blow things up!). Instead we look for runnable threads
455 * and loop or halt as appropriate. Giant is not held on entry to the thread.
457 * The main loop is entered with a critical section held, we must release
458 * the critical section before doing anything else. lwkt_switch() will
459 * check for pending interrupts due to entering and exiting its own
462 * Note on cpu_idle_hlt: On an SMP system we rely on a scheduler IPI
463 * to wake a HLTed cpu up.
465 static int cpu_idle_hlt
= 1;
466 static int cpu_idle_hltcnt
;
467 static int cpu_idle_spincnt
;
468 SYSCTL_INT(_machdep
, OID_AUTO
, cpu_idle_hlt
, CTLFLAG_RW
,
469 &cpu_idle_hlt
, 0, "Idle loop HLT enable");
470 SYSCTL_INT(_machdep
, OID_AUTO
, cpu_idle_hltcnt
, CTLFLAG_RW
,
471 &cpu_idle_hltcnt
, 0, "Idle loop entry halts");
472 SYSCTL_INT(_machdep
, OID_AUTO
, cpu_idle_spincnt
, CTLFLAG_RW
,
473 &cpu_idle_spincnt
, 0, "Idle loop entry spins");
478 struct thread
*td
= curthread
;
479 struct mdglobaldata
*gd
= mdcpu
;
483 KKASSERT(td
->td_critcount
== 0);
488 * See if there are any LWKTs ready to go.
493 * The idle loop halts only if no threads are scheduleable
494 * and no signals have occured.
497 (td
->td_gd
->gd_reqflags
& RQF_IDLECHECK_WK_MASK
) == 0) {
499 if ((td
->td_gd
->gd_reqflags
& RQF_IDLECHECK_WK_MASK
) == 0) {
501 struct timeval tv1
, tv2
;
502 gettimeofday(&tv1
, NULL
);
504 reqflags
= gd
->mi
.gd_reqflags
&
505 ~RQF_IDLECHECK_WK_MASK
;
506 KKASSERT(gd
->mi
.gd_processing_ipiq
== 0);
507 umtx_sleep(&gd
->mi
.gd_reqflags
, reqflags
,
510 gettimeofday(&tv2
, NULL
);
511 if (tv2
.tv_usec
- tv1
.tv_usec
+
512 (tv2
.tv_sec
- tv1
.tv_sec
) * 1000000
514 kprintf("cpu %d idlelock %08x %08x\n",
524 __asm
__volatile("pause");
531 * Called by the spinlock code with or without a critical section held
532 * when a spinlock is found to be seriously constested.
534 * We need to enter a critical section to prevent signals from recursing
538 cpu_spinlock_contested(void)
544 * Clear registers on exec
547 exec_setregs(u_long entry
, u_long stack
, u_long ps_strings
)
549 struct thread
*td
= curthread
;
550 struct lwp
*lp
= td
->td_lwp
;
551 struct pcb
*pcb
= td
->td_pcb
;
552 struct trapframe
*regs
= lp
->lwp_md
.md_regs
;
554 /* was i386_user_cleanup() in NetBSD */
557 bzero((char *)regs
, sizeof(struct trapframe
));
558 regs
->tf_rip
= entry
;
559 regs
->tf_rsp
= ((stack
- 8) & ~0xFul
) + 8; /* align the stack */
560 regs
->tf_rdi
= stack
; /* argv */
561 regs
->tf_rflags
= PSL_USER
| (regs
->tf_rflags
& PSL_T
);
562 regs
->tf_ss
= _udatasel
;
563 regs
->tf_cs
= _ucodesel
;
564 regs
->tf_rbx
= ps_strings
;
567 * Reset the hardware debug registers if they were in use.
568 * They won't have any meaning for the newly exec'd process.
570 if (pcb
->pcb_flags
& PCB_DBREGS
) {
576 pcb
->pcb_dr7
= 0; /* JG set bit 10? */
577 if (pcb
== td
->td_pcb
) {
579 * Clear the debug registers on the running
580 * CPU, otherwise they will end up affecting
581 * the next process we switch to.
585 pcb
->pcb_flags
&= ~PCB_DBREGS
;
589 * Initialize the math emulator (if any) for the current process.
590 * Actually, just clear the bit that says that the emulator has
591 * been initialized. Initialization is delayed until the process
592 * traps to the emulator (if it is done at all) mainly because
593 * emulators don't provide an entry point for initialization.
595 pcb
->pcb_flags
&= ~FP_SOFTFP
;
598 * NOTE: do not set CR0_TS here. npxinit() must do it after clearing
599 * gd_npxthread. Otherwise a preemptive interrupt thread
600 * may panic in npxdna().
604 load_cr0(rcr0() | CR0_MP
);
608 * NOTE: The MSR values must be correct so we can return to
609 * userland. gd_user_fs/gs must be correct so the switch
610 * code knows what the current MSR values are.
612 pcb
->pcb_fsbase
= 0; /* Values loaded from PCB on switch */
614 /* Initialize the npx (if any) for the current process. */
619 * note: linux emulator needs edx to be 0x0 on entry, which is
620 * handled in execve simply by setting the 64 bit syscall
632 cr0
|= CR0_NE
; /* Done by npxinit() */
633 cr0
|= CR0_MP
| CR0_TS
; /* Done at every execve() too. */
634 cr0
|= CR0_WP
| CR0_AM
;
641 sysctl_machdep_adjkerntz(SYSCTL_HANDLER_ARGS
)
644 error
= sysctl_handle_int(oidp
, oidp
->oid_arg1
, oidp
->oid_arg2
,
646 if (!error
&& req
->newptr
)
651 SYSCTL_PROC(_machdep
, CPU_ADJKERNTZ
, adjkerntz
, CTLTYPE_INT
|CTLFLAG_RW
,
652 &adjkerntz
, 0, sysctl_machdep_adjkerntz
, "I", "");
654 extern u_long bootdev
; /* not a cdev_t - encoding is different */
655 SYSCTL_ULONG(_machdep
, OID_AUTO
, guessed_bootdev
,
656 CTLFLAG_RD
, &bootdev
, 0, "Boot device (not in cdev_t format)");
659 * Initialize 386 and configure to run kernel
663 * Initialize segments & interrupt table
666 extern struct user
*proc0paddr
;
671 IDTVEC(div
), IDTVEC(dbg
), IDTVEC(nmi
), IDTVEC(bpt
), IDTVEC(ofl
),
672 IDTVEC(bnd
), IDTVEC(ill
), IDTVEC(dna
), IDTVEC(fpusegm
),
673 IDTVEC(tss
), IDTVEC(missing
), IDTVEC(stk
), IDTVEC(prot
),
674 IDTVEC(page
), IDTVEC(mchk
), IDTVEC(rsvd
), IDTVEC(fpu
), IDTVEC(align
),
675 IDTVEC(xmm
), IDTVEC(dblfault
),
676 IDTVEC(fast_syscall
), IDTVEC(fast_syscall32
);
680 ptrace_set_pc(struct lwp
*lp
, unsigned long addr
)
682 lp
->lwp_md
.md_regs
->tf_rip
= addr
;
687 ptrace_single_step(struct lwp
*lp
)
689 lp
->lwp_md
.md_regs
->tf_rflags
|= PSL_T
;
694 fill_regs(struct lwp
*lp
, struct reg
*regs
)
696 struct trapframe
*tp
;
698 if ((tp
= lp
->lwp_md
.md_regs
) == NULL
)
700 bcopy(&tp
->tf_rdi
, ®s
->r_rdi
, sizeof(*regs
));
705 set_regs(struct lwp
*lp
, struct reg
*regs
)
707 struct trapframe
*tp
;
709 tp
= lp
->lwp_md
.md_regs
;
710 if (!EFL_SECURE(regs
->r_rflags
, tp
->tf_rflags
) ||
711 !CS_SECURE(regs
->r_cs
))
713 bcopy(®s
->r_rdi
, &tp
->tf_rdi
, sizeof(*regs
));
718 fill_fpregs_xmm(struct savexmm
*sv_xmm
, struct save87
*sv_87
)
720 struct env87
*penv_87
= &sv_87
->sv_env
;
721 struct envxmm
*penv_xmm
= &sv_xmm
->sv_env
;
724 /* FPU control/status */
725 penv_87
->en_cw
= penv_xmm
->en_cw
;
726 penv_87
->en_sw
= penv_xmm
->en_sw
;
727 penv_87
->en_tw
= penv_xmm
->en_tw
;
728 penv_87
->en_fip
= penv_xmm
->en_fip
;
729 penv_87
->en_fcs
= penv_xmm
->en_fcs
;
730 penv_87
->en_opcode
= penv_xmm
->en_opcode
;
731 penv_87
->en_foo
= penv_xmm
->en_foo
;
732 penv_87
->en_fos
= penv_xmm
->en_fos
;
735 for (i
= 0; i
< 8; ++i
)
736 sv_87
->sv_ac
[i
] = sv_xmm
->sv_fp
[i
].fp_acc
;
740 set_fpregs_xmm(struct save87
*sv_87
, struct savexmm
*sv_xmm
)
742 struct env87
*penv_87
= &sv_87
->sv_env
;
743 struct envxmm
*penv_xmm
= &sv_xmm
->sv_env
;
746 /* FPU control/status */
747 penv_xmm
->en_cw
= penv_87
->en_cw
;
748 penv_xmm
->en_sw
= penv_87
->en_sw
;
749 penv_xmm
->en_tw
= penv_87
->en_tw
;
750 penv_xmm
->en_fip
= penv_87
->en_fip
;
751 penv_xmm
->en_fcs
= penv_87
->en_fcs
;
752 penv_xmm
->en_opcode
= penv_87
->en_opcode
;
753 penv_xmm
->en_foo
= penv_87
->en_foo
;
754 penv_xmm
->en_fos
= penv_87
->en_fos
;
757 for (i
= 0; i
< 8; ++i
)
758 sv_xmm
->sv_fp
[i
].fp_acc
= sv_87
->sv_ac
[i
];
762 fill_fpregs(struct lwp
*lp
, struct fpreg
*fpregs
)
764 if (lp
->lwp_thread
== NULL
|| lp
->lwp_thread
->td_pcb
== NULL
)
767 fill_fpregs_xmm(&lp
->lwp_thread
->td_pcb
->pcb_save
.sv_xmm
,
768 (struct save87
*)fpregs
);
771 bcopy(&lp
->lwp_thread
->td_pcb
->pcb_save
.sv_87
, fpregs
, sizeof *fpregs
);
776 set_fpregs(struct lwp
*lp
, struct fpreg
*fpregs
)
779 set_fpregs_xmm((struct save87
*)fpregs
,
780 &lp
->lwp_thread
->td_pcb
->pcb_save
.sv_xmm
);
783 bcopy(fpregs
, &lp
->lwp_thread
->td_pcb
->pcb_save
.sv_87
, sizeof *fpregs
);
788 fill_dbregs(struct lwp
*lp
, struct dbreg
*dbregs
)
794 set_dbregs(struct lwp
*lp
, struct dbreg
*dbregs
)
801 * Return > 0 if a hardware breakpoint has been hit, and the
802 * breakpoint was in user space. Return 0, otherwise.
805 user_dbreg_trap(void)
807 u_int32_t dr7
, dr6
; /* debug registers dr6 and dr7 */
808 u_int32_t bp
; /* breakpoint bits extracted from dr6 */
809 int nbp
; /* number of breakpoints that triggered */
810 caddr_t addr
[4]; /* breakpoint addresses */
814 if ((dr7
& 0x000000ff) == 0) {
816 * all GE and LE bits in the dr7 register are zero,
817 * thus the trap couldn't have been caused by the
818 * hardware debug registers
825 bp
= dr6
& 0x0000000f;
829 * None of the breakpoint bits are set meaning this
830 * trap was not caused by any of the debug registers
836 * at least one of the breakpoints were hit, check to see
837 * which ones and if any of them are user space addresses
841 addr
[nbp
++] = (caddr_t
)rdr0();
844 addr
[nbp
++] = (caddr_t
)rdr1();
847 addr
[nbp
++] = (caddr_t
)rdr2();
850 addr
[nbp
++] = (caddr_t
)rdr3();
853 for (i
=0; i
<nbp
; i
++) {
855 (caddr_t
)VM_MAX_USER_ADDRESS
) {
857 * addr[i] is in user space
864 * None of the breakpoints are in user space.
877 cpu_feature
= regs
[3];
883 Debugger(const char *msg
)
885 kprintf("Debugger(\"%s\") called.\n", msg
);