1/*- 2 * Copyright (c) 1992 Terrence R. Lambert. 3 * Copyright (c) 1982, 1987, 1990 The Regents of the University of California. 4 * All rights reserved. 5 * 6 * This code is derived from software contributed to Berkeley by 7 * William Jolitz. 8 * --- 24 unchanged lines hidden (view full) --- 33 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 34 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 35 * SUCH DAMAGE. 36 * 37 * @(#)machdep.c 7.4 (Berkeley) 6/3/91 38 */ 39 40#include <sys/cdefs.h> |
41__FBSDID("$FreeBSD: head/sys/amd64/amd64/machdep.c 122292 2003-11-08 03:33:38Z peter $"); |
42 43#include "opt_atalk.h" 44#include "opt_compat.h" 45#include "opt_cpu.h" 46#include "opt_ddb.h" 47#include "opt_inet.h" 48#include "opt_ipx.h" 49#include "opt_isa.h" --- 461 unchanged lines hidden (view full) --- 511 load_gs(_udatasel); 512 pcb->pcb_ds = _udatasel; 513 pcb->pcb_es = _udatasel; 514 pcb->pcb_fs = _udatasel; 515 pcb->pcb_gs = _udatasel; 516 517 bzero((char *)regs, sizeof(struct trapframe)); 518 regs->tf_rip = entry; |
519 regs->tf_rsp = ((stack - 8) & ~0xF) + 8; 520 regs->tf_rdi = stack; /* argv */ 521 regs->tf_rflags = PSL_USER | (regs->tf_rflags & PSL_T); 522 regs->tf_ss = _udatasel; 523 regs->tf_cs = _ucodesel; 524 525 /* |
526 * Arrange to trap the next fpu or `fwait' instruction (see fpu.c 527 * for why fwait must be trapped at least if there is an fpu or an |
528 * emulator). This is mainly to handle the case where npx0 is not |
529 * configured, since the fpu routines normally set up the trap |
530 * otherwise. It should be done only at boot time, but doing it |
531 * here allows modifying `fpu_exists' for testing the emulator on 532 * systems with an fpu. |
533 */ 534 load_cr0(rcr0() | CR0_MP | CR0_TS); 535 |
536 /* Initialize the fpu (if any) for the current process. */ |
537 /* 538 * XXX the above load_cr0() also initializes it and is a layering |
539 * violation. It drops the fpu state partially |
540 * and this would be fatal if we were interrupted now, and decided 541 * to force the state to the pcb, and checked the invariant 542 * (CR0_TS clear) if and only if PCPU_GET(fpcurthread) != NULL). 543 * ALL of this can happen except the check. The check used to 544 * happen and be fatal later when we didn't complete the drop 545 * before returning to user mode. This should be fixed properly 546 * soon. 547 */ 548 fpstate_drop(td); 549} 550 551void 552cpu_setregs(void) 553{ 554 register_t cr0; 555 556 cr0 = rcr0(); |
557 cr0 |= CR0_NE; /* Done by fpuinit() */ |
558 cr0 |= CR0_MP | CR0_TS; /* Done at every execve() too. */ 559 cr0 |= CR0_WP | CR0_AM; 560 load_cr0(cr0); 561} 562 563static int 564sysctl_machdep_adjkerntz(SYSCTL_HANDLER_ARGS) 565{ --- 953 unchanged lines hidden (view full) --- 1519 tp->tf_ss = mcp->mc_ss; 1520 return (0); 1521} 1522 1523static void 1524get_fpcontext(struct thread *td, mcontext_t *mcp) 1525{ 1526 |
1527 mcp->mc_ownedfp = fpugetregs(td, (struct savefpu *)&mcp->mc_fpstate); 1528 mcp->mc_fpformat = fpuformat(); |
1529} 1530 1531static int 1532set_fpcontext(struct thread *td, const mcontext_t *mcp) 1533{ 1534 1535 if (mcp->mc_fpformat == _MC_FPFMT_NODEV) 1536 return (0); 1537 else if (mcp->mc_fpformat != _MC_FPFMT_XMM) 1538 return (EINVAL); 1539 else if (mcp->mc_ownedfp == _MC_FPOWNED_NONE) 1540 /* We don't care what state is left in the FPU or PCB. */ 1541 fpstate_drop(td); 1542 else if (mcp->mc_ownedfp == _MC_FPOWNED_FPU || 1543 mcp->mc_ownedfp == _MC_FPOWNED_PCB) { 1544 /* |
1545 * XXX we violate the dubious requirement that fpusetregs() |
1546 * be called with interrupts disabled. 1547 * XXX obsolete on trap-16 systems? 1548 */ |
1549 fpusetregs(td, (struct savefpu *)&mcp->mc_fpstate); |
1550 } else 1551 return (EINVAL); 1552 return (0); 1553} 1554 1555void 1556fpstate_drop(struct thread *td) 1557{ 1558 register_t s; 1559 1560 s = intr_disable(); 1561 if (PCPU_GET(fpcurthread) == td) |
1562 fpudrop(); |
1563 /* |
1564 * XXX force a full drop of the fpu. The above only drops it if we |
1565 * owned it. 1566 * |
1567 * XXX I don't much like fpugetregs()'s semantics of doing a full |
1568 * drop. Dropping only to the pcb matches fnsave's behaviour. 1569 * We only need to drop to !PCB_INITDONE in sendsig(). But |
1570 * sendsig() is the only caller of fpugetregs()... perhaps we just |
1571 * have too many layers. 1572 */ |
1573 curthread->td_pcb->pcb_flags &= ~PCB_FPUINITDONE; |
1574 intr_restore(s); 1575} 1576 1577int 1578fill_dbregs(struct thread *td, struct dbreg *dbregs) 1579{ 1580 1581 return (0); --- 62 unchanged lines hidden --- |