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

--- 21 unchanged lines hidden (view full) ---

30 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
31 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
32 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
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 * from: @(#)machdep.c 7.4 (Berkeley) 6/3/91
38 * $Id: machdep.c,v 1.99 1995/01/05 19:51:14 se Exp $
38 * $Id: machdep.c,v 1.100 1995/01/09 16:04:37 davidg Exp $
39 */
40
41#include "npx.h"
42#include "isa.h"
43
44#include <sys/param.h>
45#include <sys/systm.h>
46#include <sys/signalvar.h>

--- 407 unchanged lines hidden (view full) ---

454vmtime(otime, olbolt, oicr)
455 register int otime, olbolt, oicr;
456{
457
458 return (((time.tv_sec-otime)*60 + lbolt-olbolt)*16667);
459}
460#endif
461
462extern int kstack[];
462extern char kstack[];
463
464/*
465 * Send an interrupt to process.
466 *
467 * Stack is set up to allow sigcode stored
468 * in u. to call routine, followed by kcall
469 * to sigreturn routine below. After sigreturn
470 * resets the signal mask, the stack, and the

--- 131 unchanged lines hidden (view full) ---

602 */
603 scp = uap->sigcntxp;
604 fp = (struct sigframe *)
605 ((caddr_t)scp - offsetof(struct sigframe, sf_sc));
606
607 if (useracc((caddr_t)fp, sizeof (*fp), 0) == 0)
608 return(EINVAL);
609
610 /*
611 * Don't allow users to change privileged or reserved flags. Let
612 * the hardware check for changing to excess I/O privilege.
613 */
614#define EFLAGS_SECURE(ef, oef) ((((ef) ^ (oef)) & ~PSL_USERCHANGE) == 0)
615
616 eflags = scp->sc_ps;
611 if ((eflags & PSL_USERCLR) != 0 ||
612 (eflags & PSL_USERSET) != PSL_USERSET ||
613 (eflags & PSL_IOPL) < (regs[tEFLAGS] & PSL_IOPL)) {
617 if (!EFLAGS_SECURE(eflags, regs[tEFLAGS])) {
618#ifdef DEBUG
615 printf("sigreturn: eflags=0x%x\n", eflags);
619 printf("sigreturn: eflags = 0x%x\n", eflags);
620#endif
621 return(EINVAL);
622 }
623
624 /*
621 * Sanity check the user's selectors and error if they
622 * are suspect.
625 * Don't allow users to load a valid privileged %cs. Let the
626 * hardware check for invalid selectors, excess privilege in
627 * other selectors, invalid %eip's and invalid %esp's.
628 */
624#define max_ldt_sel(pcb) \
625 ((pcb)->pcb_ldt ? (pcb)->pcb_ldt_len : (sizeof(ldt) / sizeof(ldt[0])))
626
627#define valid_ldt_sel(sel) \
628 (ISLDT(sel) && ISPL(sel) == SEL_UPL && \
629 IDXSEL(sel) < max_ldt_sel(&p->p_addr->u_pcb))
630
631#define null_sel(sel) \
632 (!ISLDT(sel) && IDXSEL(sel) == 0)
633
634 if (((scp->sc_cs&0xffff) != _ucodesel && !valid_ldt_sel(scp->sc_cs)) ||
635 ((scp->sc_ss&0xffff) != _udatasel && !valid_ldt_sel(scp->sc_ss)) ||
636 ((scp->sc_ds&0xffff) != _udatasel && !valid_ldt_sel(scp->sc_ds) &&
637 !null_sel(scp->sc_ds)) ||
638 ((scp->sc_es&0xffff) != _udatasel && !valid_ldt_sel(scp->sc_es) &&
639 !null_sel(scp->sc_es))) {
629#define CS_SECURE(cs) (ISPL(cs) == SEL_UPL)
630 if (!CS_SECURE(scp->sc_cs)) {
631#ifdef DEBUG
641 printf("sigreturn: cs=0x%x ss=0x%x ds=0x%x es=0x%x\n",
642 scp->sc_cs, scp->sc_ss, scp->sc_ds, scp->sc_es);
632 printf("sigreturn: cs = 0x%x\n", scp->sc_cs);
633#endif
634 trapsignal(p, SIGBUS, T_PROTFLT);
635 return(EINVAL);
636 }
637
648#undef max_ldt_sel
649#undef valid_ldt_sel
650#undef null_sel
651
638 /* restore scratch registers */
639 regs[tEAX] = scp->sc_eax;
640 regs[tEBX] = scp->sc_ebx;
641 regs[tECX] = scp->sc_ecx;
642 regs[tEDX] = scp->sc_edx;
643 regs[tESI] = scp->sc_esi;
644 regs[tEDI] = scp->sc_edi;
645 regs[tCS] = scp->sc_cs;

--- 198 unchanged lines hidden (view full) ---

844 u_long entry;
845 u_long stack;
846{
847 int *regs = p->p_md.md_regs;
848
849 bzero(regs, sizeof(struct trapframe));
850 regs[tEIP] = entry;
851 regs[tESP] = stack;
866 regs[tEFLAGS] = PSL_USERSET | (regs[tEFLAGS] & PSL_T);
852 regs[tEFLAGS] = PSL_USER | (regs[tEFLAGS] & PSL_T);
853 regs[tSS] = _udatasel;
854 regs[tDS] = _udatasel;
855 regs[tES] = _udatasel;
856 regs[tCS] = _ucodesel;
857
858 p->p_addr->u_pcb.pcb_flags = 0; /* no fp at all */
859 load_cr0(rcr0() | CR0_TS); /* start emulating */
860#if NNPX > 0

--- 226 unchanged lines hidden (view full) ---

1087}
1088
1089#define IDTVEC(name) __CONCAT(X,name)
1090
1091extern inthand_t
1092 IDTVEC(div), IDTVEC(dbg), IDTVEC(nmi), IDTVEC(bpt), IDTVEC(ofl),
1093 IDTVEC(bnd), IDTVEC(ill), IDTVEC(dna), IDTVEC(dble), IDTVEC(fpusegm),
1094 IDTVEC(tss), IDTVEC(missing), IDTVEC(stk), IDTVEC(prot),
1109 IDTVEC(page), IDTVEC(rsvd), IDTVEC(fpu), IDTVEC(rsvd0),
1110 IDTVEC(rsvd1), IDTVEC(rsvd2), IDTVEC(rsvd3), IDTVEC(rsvd4),
1111 IDTVEC(rsvd5), IDTVEC(rsvd6), IDTVEC(rsvd7), IDTVEC(rsvd8),
1112 IDTVEC(rsvd9), IDTVEC(rsvd10), IDTVEC(rsvd11), IDTVEC(rsvd12),
1113 IDTVEC(rsvd13), IDTVEC(rsvd14), IDTVEC(syscall);
1095 IDTVEC(page), IDTVEC(rsvd), IDTVEC(fpu), IDTVEC(align),
1096 IDTVEC(syscall);
1097
1098void
1099sdtossd(sd, ssd)
1100 struct segment_descriptor *sd;
1101 struct soft_segment_descriptor *ssd;
1102{
1103 ssd->ssd_base = (sd->sd_hibase << 24) | sd->sd_lobase;
1104 ssd->ssd_limit = (sd->sd_hilimit << 16) | sd->sd_lolimit;

--- 64 unchanged lines hidden (view full) ---

1169#define VM_END_USER_R_ADDRESS (VM_END_USER_RW_ADDRESS + UPAGES * NBPG)
1170 ldt_segs[LUCODE_SEL].ssd_limit = i386_btop(VM_END_USER_R_ADDRESS) - 1;
1171 ldt_segs[LUDATA_SEL].ssd_limit = i386_btop(VM_END_USER_RW_ADDRESS) - 1;
1172 /* Note. eventually want private ldts per process */
1173 for (x = 0; x < NLDT; x++)
1174 ssdtosd(&ldt_segs[x], &ldt[x].sd);
1175
1176 /* exceptions */
1177 for (x = 0; x < NIDT; x++)
1178 setidt(x, &IDTVEC(rsvd), SDT_SYS386TGT, SEL_KPL);
1179 setidt(0, &IDTVEC(div), SDT_SYS386TGT, SEL_KPL);
1180 setidt(1, &IDTVEC(dbg), SDT_SYS386TGT, SEL_KPL);
1181 setidt(2, &IDTVEC(nmi), SDT_SYS386TGT, SEL_KPL);
1182 setidt(3, &IDTVEC(bpt), SDT_SYS386TGT, SEL_UPL);
1183 setidt(4, &IDTVEC(ofl), SDT_SYS386TGT, SEL_UPL);
1184 setidt(5, &IDTVEC(bnd), SDT_SYS386TGT, SEL_KPL);
1185 setidt(6, &IDTVEC(ill), SDT_SYS386TGT, SEL_KPL);
1186 setidt(7, &IDTVEC(dna), SDT_SYS386TGT, SEL_KPL);
1187 setidt(8, &IDTVEC(dble), SDT_SYS386TGT, SEL_KPL);
1188 setidt(9, &IDTVEC(fpusegm), SDT_SYS386TGT, SEL_KPL);
1189 setidt(10, &IDTVEC(tss), SDT_SYS386TGT, SEL_KPL);
1190 setidt(11, &IDTVEC(missing), SDT_SYS386TGT, SEL_KPL);
1191 setidt(12, &IDTVEC(stk), SDT_SYS386TGT, SEL_KPL);
1192 setidt(13, &IDTVEC(prot), SDT_SYS386TGT, SEL_KPL);
1193 setidt(14, &IDTVEC(page), SDT_SYS386TGT, SEL_KPL);
1194 setidt(15, &IDTVEC(rsvd), SDT_SYS386TGT, SEL_KPL);
1195 setidt(16, &IDTVEC(fpu), SDT_SYS386TGT, SEL_KPL);
1211 setidt(17, &IDTVEC(rsvd0), SDT_SYS386TGT, SEL_KPL);
1212 setidt(18, &IDTVEC(rsvd1), SDT_SYS386TGT, SEL_KPL);
1213 setidt(19, &IDTVEC(rsvd2), SDT_SYS386TGT, SEL_KPL);
1214 setidt(20, &IDTVEC(rsvd3), SDT_SYS386TGT, SEL_KPL);
1215 setidt(21, &IDTVEC(rsvd4), SDT_SYS386TGT, SEL_KPL);
1216 setidt(22, &IDTVEC(rsvd5), SDT_SYS386TGT, SEL_KPL);
1217 setidt(23, &IDTVEC(rsvd6), SDT_SYS386TGT, SEL_KPL);
1218 setidt(24, &IDTVEC(rsvd7), SDT_SYS386TGT, SEL_KPL);
1219 setidt(25, &IDTVEC(rsvd8), SDT_SYS386TGT, SEL_KPL);
1220 setidt(26, &IDTVEC(rsvd9), SDT_SYS386TGT, SEL_KPL);
1221 setidt(27, &IDTVEC(rsvd10), SDT_SYS386TGT, SEL_KPL);
1222 setidt(28, &IDTVEC(rsvd11), SDT_SYS386TGT, SEL_KPL);
1223 setidt(29, &IDTVEC(rsvd12), SDT_SYS386TGT, SEL_KPL);
1224 setidt(30, &IDTVEC(rsvd13), SDT_SYS386TGT, SEL_KPL);
1225 setidt(31, &IDTVEC(rsvd14), SDT_SYS386TGT, SEL_KPL);
1196 setidt(17, &IDTVEC(align), SDT_SYS386TGT, SEL_KPL);
1197
1198#include "isa.h"
1199#if NISA >0
1200 isa_defaultirq();
1201#endif
1202
1203 r_gdt.rd_limit = sizeof(gdt) - 1;
1204 r_gdt.rd_base = (int) gdt;

--- 206 unchanged lines hidden (view full) ---

1411 * The registers are in the frame; the frame is in the user area of
1412 * the process in question; when the process is active, the registers
1413 * are in "the kernel stack"; when it's not, they're still there, but
1414 * things get flipped around. So, since p->p_md.md_regs is the whole address
1415 * of the register set, take its offset from the kernel stack, and
1416 * index into the user block. Don't you just *love* virtual memory?
1417 * (I'm starting to think seymour is right...)
1418 */
1419#define TF_REGP(p) ((struct trapframe *) \
1420 ((char *)(p)->p_addr \
1421 + ((char *)(p)->p_md.md_regs - kstack)))
1422
1423int
1450ptrace_set_pc (struct proc *p, unsigned int addr) {
1451 void *regs = (char*)p->p_addr +
1452 ((char*) p->p_md.md_regs - (char*) kstack);
1453
1454 ((struct trapframe *)regs)->tf_eip = addr;
1455 return 0;
1424ptrace_set_pc(p, addr)
1425 struct proc *p;
1426 unsigned int addr;
1427{
1428 TF_REGP(p)->tf_eip = addr;
1429 return (0);
1430}
1431
1432int
1459ptrace_single_step (struct proc *p) {
1460 void *regs = (char*)p->p_addr +
1461 ((char*) p->p_md.md_regs - (char*) kstack);
1462
1463 ((struct trapframe *)regs)->tf_eflags |= PSL_T;
1464 return 0;
1433ptrace_single_step(p)
1434 struct proc *p;
1435{
1436 TF_REGP(p)->tf_eflags |= PSL_T;
1437 return (0);
1438}
1439
1467/*
1468 * Copy the registers to user-space.
1469 */
1470
1440int
1472ptrace_getregs (struct proc *p, unsigned int *addr) {
1441ptrace_getregs(p, addr)
1442 struct proc *p;
1443 unsigned int *addr;
1444{
1445 int error;
1474 struct reg regs = {0};
1446 struct reg regs;
1447
1476 error = fill_regs (p, &regs);
1448 error = fill_regs(p, ®s);
1449 if (error)
1478 return error;
1479
1480 return copyout (&regs, addr, sizeof (regs));
1450 return (error);
1451 return (copyout(&regs, addr, sizeof regs));
1452}
1453
1454int
1484ptrace_setregs (struct proc *p, unsigned int *addr) {
1455ptrace_setregs(p, addr)
1456 struct proc *p;
1457 unsigned int *addr;
1458{
1459 int error;
1486 struct reg regs = {0};
1460 struct reg regs;
1461
1488 error = copyin (addr, &regs, sizeof(regs));
1462 error = copyin(addr, &regs, sizeof regs);
1463 if (error)
1490 return error;
1464 return (error);
1465 return (set_regs(p, &regs));
1466}
1467
1492 return set_regs (p, &regs);
1468int ptrace_write_u(p, off, data)
1469 struct proc *p;
1470 vm_offset_t off;
1471 int data;
1472{
1473 struct trapframe frame_copy;
1474 vm_offset_t min;
1475 struct trapframe *tp;
1476
1477 /*
1478 * Privileged kernel state is scattered all over the user area.
1479 * Only allow write access to parts of regs and to fpregs.
1480 */
1481 min = (char *)p->p_md.md_regs - kstack;
1482 if (off >= min && off <= min + sizeof(struct trapframe) - sizeof(int)) {
1483 tp = TF_REGP(p);
1484 frame_copy = *tp;
1485 *(int *)((char *)&frame_copy + (off - min)) = data;
1486 if (!EFLAGS_SECURE(frame_copy.tf_eflags, tp->tf_eflags) ||
1487 !CS_SECURE(frame_copy.tf_cs))
1488 return (EINVAL);
1489 *(int*)((char *)p->p_addr + off) = data;
1490 return (0);
1491 }
1492 min = offsetof(struct user, u_pcb) + offsetof(struct pcb, pcb_savefpu);
1493 if (off >= min && off <= min + sizeof(struct save87) - sizeof(int)) {
1494 *(int*)((char *)p->p_addr + off) = data;
1495 return (0);
1496 }
1497 return (EFAULT);
1498}
1499
1500int
1496fill_regs(struct proc *p, struct reg *regs) {
1501fill_regs(p, regs)
1502 struct proc *p;
1503 struct reg *regs;
1504{
1505 struct trapframe *tp;
1498 void *ptr = (char*)p->p_addr +
1499 ((char*) p->p_md.md_regs - (char*) kstack);
1506
1501 tp = ptr;
1507 tp = TF_REGP(p);
1508 regs->r_es = tp->tf_es;
1509 regs->r_ds = tp->tf_ds;
1510 regs->r_edi = tp->tf_edi;
1511 regs->r_esi = tp->tf_esi;
1512 regs->r_ebp = tp->tf_ebp;
1513 regs->r_ebx = tp->tf_ebx;
1514 regs->r_edx = tp->tf_edx;
1515 regs->r_ecx = tp->tf_ecx;
1516 regs->r_eax = tp->tf_eax;
1517 regs->r_eip = tp->tf_eip;
1518 regs->r_cs = tp->tf_cs;
1519 regs->r_eflags = tp->tf_eflags;
1520 regs->r_esp = tp->tf_esp;
1521 regs->r_ss = tp->tf_ss;
1516 return 0;
1522 return (0);
1523}
1524
1525int
1520set_regs (struct proc *p, struct reg *regs) {
1526set_regs(p, regs)
1527 struct proc *p;
1528 struct reg *regs;
1529{
1530 struct trapframe *tp;
1522 void *ptr = (char*)p->p_addr +
1523 ((char*) p->p_md.md_regs - (char*) kstack);
1531
1525 tp = ptr;
1532 tp = TF_REGP(p);
1533 if (!EFLAGS_SECURE(regs->r_eflags, tp->tf_eflags) ||
1534 !CS_SECURE(regs->r_cs))
1535 return (EINVAL);
1536 tp->tf_es = regs->r_es;
1537 tp->tf_ds = regs->r_ds;
1538 tp->tf_edi = regs->r_edi;
1539 tp->tf_esi = regs->r_esi;
1540 tp->tf_ebp = regs->r_ebp;
1541 tp->tf_ebx = regs->r_ebx;
1542 tp->tf_edx = regs->r_edx;
1543 tp->tf_ecx = regs->r_ecx;
1544 tp->tf_eax = regs->r_eax;
1545 tp->tf_eip = regs->r_eip;
1546 tp->tf_cs = regs->r_cs;
1547 tp->tf_eflags = regs->r_eflags;
1548 tp->tf_esp = regs->r_esp;
1549 tp->tf_ss = regs->r_ss;
1540 return 0;
1550 return (0);
1551}
1552
1553#ifndef DDB
1554void
1555Debugger(const char *msg)
1556{
1557 printf("Debugger(\"%s\") called.\n", msg);
1558}

--- 73 unchanged lines hidden ---