Deleted Added
full compact
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 ---