machdep.c (121228) | machdep.c (122292) |
---|---|
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> | 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 121228 2003-10-18 22:25:07Z njl $"); | 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; | 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 /* This strangeness is to ensure alignment after the implied return address */ | |
520 regs->tf_rsp = ((stack - 8) & ~0xF) + 8; 521 regs->tf_rdi = stack; /* argv */ 522 regs->tf_rflags = PSL_USER | (regs->tf_rflags & PSL_T); 523 regs->tf_ss = _udatasel; 524 regs->tf_cs = _ucodesel; 525 526 /* | 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 /* |
527 * Arrange to trap the next npx or `fwait' instruction (see npx.c 528 * for why fwait must be trapped at least if there is an npx or an | 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 |
529 * emulator). This is mainly to handle the case where npx0 is not | 528 * emulator). This is mainly to handle the case where npx0 is not |
530 * configured, since the npx routines normally set up the trap | 529 * configured, since the fpu routines normally set up the trap |
531 * otherwise. It should be done only at boot time, but doing it | 530 * otherwise. It should be done only at boot time, but doing it |
532 * here allows modifying `npx_exists' for testing the emulator on 533 * systems with an npx. | 531 * here allows modifying `fpu_exists' for testing the emulator on 532 * systems with an fpu. |
534 */ 535 load_cr0(rcr0() | CR0_MP | CR0_TS); 536 | 533 */ 534 load_cr0(rcr0() | CR0_MP | CR0_TS); 535 |
537 /* Initialize the npx (if any) for the current process. */ | 536 /* Initialize the fpu (if any) for the current process. */ |
538 /* 539 * XXX the above load_cr0() also initializes it and is a layering | 537 /* 538 * XXX the above load_cr0() also initializes it and is a layering |
540 * violation if NPX is configured. It drops the npx partially | 539 * violation. It drops the fpu state partially |
541 * and this would be fatal if we were interrupted now, and decided 542 * to force the state to the pcb, and checked the invariant 543 * (CR0_TS clear) if and only if PCPU_GET(fpcurthread) != NULL). 544 * ALL of this can happen except the check. The check used to 545 * happen and be fatal later when we didn't complete the drop 546 * before returning to user mode. This should be fixed properly 547 * soon. 548 */ 549 fpstate_drop(td); 550} 551 552void 553cpu_setregs(void) 554{ 555 register_t cr0; 556 557 cr0 = rcr0(); | 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(); |
558 cr0 |= CR0_NE; /* Done by npxinit() */ | 557 cr0 |= CR0_NE; /* Done by fpuinit() */ |
559 cr0 |= CR0_MP | CR0_TS; /* Done at every execve() too. */ 560 cr0 |= CR0_WP | CR0_AM; 561 load_cr0(cr0); 562} 563 564static int 565sysctl_machdep_adjkerntz(SYSCTL_HANDLER_ARGS) 566{ --- 953 unchanged lines hidden (view full) --- 1520 tp->tf_ss = mcp->mc_ss; 1521 return (0); 1522} 1523 1524static void 1525get_fpcontext(struct thread *td, mcontext_t *mcp) 1526{ 1527 | 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 |
1528 mcp->mc_ownedfp = npxgetregs(td, (struct savefpu *)&mcp->mc_fpstate); 1529 mcp->mc_fpformat = npxformat(); | 1527 mcp->mc_ownedfp = fpugetregs(td, (struct savefpu *)&mcp->mc_fpstate); 1528 mcp->mc_fpformat = fpuformat(); |
1530} 1531 1532static int 1533set_fpcontext(struct thread *td, const mcontext_t *mcp) 1534{ 1535 1536 if (mcp->mc_fpformat == _MC_FPFMT_NODEV) 1537 return (0); 1538 else if (mcp->mc_fpformat != _MC_FPFMT_XMM) 1539 return (EINVAL); 1540 else if (mcp->mc_ownedfp == _MC_FPOWNED_NONE) 1541 /* We don't care what state is left in the FPU or PCB. */ 1542 fpstate_drop(td); 1543 else if (mcp->mc_ownedfp == _MC_FPOWNED_FPU || 1544 mcp->mc_ownedfp == _MC_FPOWNED_PCB) { 1545 /* | 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 /* |
1546 * XXX we violate the dubious requirement that npxsetregs() | 1545 * XXX we violate the dubious requirement that fpusetregs() |
1547 * be called with interrupts disabled. 1548 * XXX obsolete on trap-16 systems? 1549 */ | 1546 * be called with interrupts disabled. 1547 * XXX obsolete on trap-16 systems? 1548 */ |
1550 npxsetregs(td, (struct savefpu *)&mcp->mc_fpstate); | 1549 fpusetregs(td, (struct savefpu *)&mcp->mc_fpstate); |
1551 } else 1552 return (EINVAL); 1553 return (0); 1554} 1555 1556void 1557fpstate_drop(struct thread *td) 1558{ 1559 register_t s; 1560 1561 s = intr_disable(); 1562 if (PCPU_GET(fpcurthread) == td) | 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) |
1563 npxdrop(); | 1562 fpudrop(); |
1564 /* | 1563 /* |
1565 * XXX force a full drop of the npx. The above only drops it if we | 1564 * XXX force a full drop of the fpu. The above only drops it if we |
1566 * owned it. 1567 * | 1565 * owned it. 1566 * |
1568 * XXX I don't much like npxgetregs()'s semantics of doing a full | 1567 * XXX I don't much like fpugetregs()'s semantics of doing a full |
1569 * drop. Dropping only to the pcb matches fnsave's behaviour. 1570 * We only need to drop to !PCB_INITDONE in sendsig(). But | 1568 * drop. Dropping only to the pcb matches fnsave's behaviour. 1569 * We only need to drop to !PCB_INITDONE in sendsig(). But |
1571 * sendsig() is the only caller of npxgetregs()... perhaps we just | 1570 * sendsig() is the only caller of fpugetregs()... perhaps we just |
1572 * have too many layers. 1573 */ | 1571 * have too many layers. 1572 */ |
1574 curthread->td_pcb->pcb_flags &= ~PCB_NPXINITDONE; | 1573 curthread->td_pcb->pcb_flags &= ~PCB_FPUINITDONE; |
1575 intr_restore(s); 1576} 1577 1578int 1579fill_dbregs(struct thread *td, struct dbreg *dbregs) 1580{ 1581 1582 return (0); --- 62 unchanged lines hidden --- | 1574 intr_restore(s); 1575} 1576 1577int 1578fill_dbregs(struct thread *td, struct dbreg *dbregs) 1579{ 1580 1581 return (0); --- 62 unchanged lines hidden --- |