proc->thread stage 4: rework the VFS and DEVICE subsystems to take thread
[dragonfly.git] / sys / i386 / i386 / machdep.c
index 9470ff4..c96a536 100644 (file)
@@ -36,7 +36,7 @@
  *
  *     from: @(#)machdep.c     7.4 (Berkeley) 6/3/91
  * $FreeBSD: src/sys/i386/i386/machdep.c,v 1.385.2.30 2003/05/31 08:48:05 alc Exp $
- * $DragonFly: src/sys/i386/i386/Attic/machdep.c,v 1.5 2003/06/19 01:55:05 dillon Exp $
+ * $DragonFly: src/sys/i386/i386/Attic/machdep.c,v 1.12 2003/06/25 03:55:53 dillon Exp $
  */
 
 #include "apm.h"
@@ -720,6 +720,8 @@ sendsig(catcher, sig, mask, code)
 }
 
 /*
+ * osigreturn_args(struct osigcontext *sigcntxp)
+ *
  * System call to cleanup state after a signal
  * has been taken.  Reset signal mask and
  * stack state from context left by sendsig (above).
@@ -732,14 +734,11 @@ sendsig(catcher, sig, mask, code)
 #define        CS_SECURE(cs)           (ISPL(cs) == SEL_UPL)
 
 int
-osigreturn(p, uap)
-       struct proc *p;
-       struct osigreturn_args /* {
-               struct osigcontext *sigcntxp;
-       } */ *uap;
+osigreturn(struct osigreturn_args *uap)
 {
-       register struct osigcontext *scp;
-       register struct trapframe *regs = p->p_md.md_regs;
+       struct proc *p = curproc;
+       struct osigcontext *scp;
+       struct trapframe *regs = p->p_md.md_regs;
        int eflags;
 
        scp = uap->sigcntxp;
@@ -837,13 +836,13 @@ osigreturn(p, uap)
        return(EJUSTRETURN);
 }
 
+/*
+ * sigreturn(ucontext_t *sigcntxp)
+ */
 int
-sigreturn(p, uap)
-       struct proc *p;
-       struct sigreturn_args /* {
-               ucontext_t *sigcntxp;
-       } */ *uap;
+sigreturn(struct sigreturn_args *uap)
 {
+       struct proc *p = curproc;
        struct trapframe *regs;
        ucontext_t *ucp;
        int cs, eflags;
@@ -853,7 +852,7 @@ sigreturn(p, uap)
        if (!useracc((caddr_t)ucp, sizeof(struct osigcontext), VM_PROT_READ))
                return (EFAULT);
        if (((struct osigcontext *)ucp)->sc_trapno == 0x01d516)
-               return (osigreturn(p, (struct osigreturn_args *)uap));
+               return (osigreturn((struct osigreturn_args *)uap));
 
        /*
         * Since ucp is not an osigcontext but a ucontext_t, we have to
@@ -967,13 +966,12 @@ cpu_halt(void)
 }
 
 /*
- * Hook to idle the CPU when possible.   This is disabled by default for
- * the SMP case as there is a small window of opportunity whereby a ready
- * process is delayed to the next clock tick.  It should be safe to enable
- * for SMP if power is a concern.
+ * cpu_idle() represents the idle LWKT.  You cannot return from this function
+ * (unless you want to blow things up!).  Instead we look for runnable threads
+ * and loop or halt as appropriate.  Giant is not held on entry to the thread.
  *
- * On -stable, cpu_idle() is called with interrupts disabled and must
- * return with them enabled.
+ * Note on cpu_idle_hlt:  On an SMP system this may cause the system to 
+ * halt until the next clock tick, even if a thread is ready YYY
  */
 #ifdef SMP
 static int     cpu_idle_hlt = 0;
@@ -986,14 +984,19 @@ SYSCTL_INT(_machdep, OID_AUTO, cpu_idle_hlt, CTLFLAG_RW,
 void
 cpu_idle(void)
 {
-       if (cpu_idle_hlt) {
-               /*
-                * We must guarentee that hlt is exactly the instruction
-                * following the sti.
-                */
-               __asm __volatile("sti; hlt");
-       } else {
-               __asm __volatile("sti");
+       spl0();
+       for (;;) {
+               lwkt_switch();
+               if (cpu_idle_hlt) {
+                       /*
+                        * We must guarentee that hlt is exactly the instruction
+                        * following the sti.
+                        */
+                       __asm __volatile("sti; hlt");
+               } else {
+                       __asm __volatile("sti");
+               }
+               /* YYY BGL */
        }
 }
 
@@ -1861,13 +1864,16 @@ init386(first)
        /*
         * Prevent lowering of the ipl if we call tsleep() early.
         */
-       safepri = cpl;
+       gd = &CPU_prvspace[0].globaldata;
 
-       proc0.p_addr = proc0paddr;
+       lwkt_init_thread(&thread0, proc0paddr);
+       gd->gd_curthread = &thread0;
+       safepri = thread0.td_cpl = SWI_MASK | HWI_MASK;
+       thread0.td_switch = cpu_heavy_switch;   /* YYY eventually LWKT */
+       proc0.p_addr = (void *)thread0.td_kstack;
        proc0.p_thread = &thread0;
        thread0.td_proc = &proc0;
-       thread0.td_pcb = (struct pcb *)
-           ((char *)proc0paddr + UPAGES*PAGE_SIZE - sizeof(struct pcb));
+       thread0.td_flags = TDF_RUNNING;
 
        atdevbase = ISA_HOLE_START + KERNBASE;
 
@@ -1898,23 +1904,22 @@ init386(first)
 #ifdef SMP
        gdt_segs[GPRIV_SEL].ssd_limit =
                atop(sizeof(struct privatespace) - 1);
-       gdt_segs[GPRIV_SEL].ssd_base = (int) &SMP_prvspace[0];
+       gdt_segs[GPRIV_SEL].ssd_base = (int) &CPU_prvspace[0];
        gdt_segs[GPROC0_SEL].ssd_base =
-               (int) &SMP_prvspace[0].globaldata.gd_common_tss;
-       SMP_prvspace[0].globaldata.gd_prvspace = &SMP_prvspace[0];
-       gd = &SMP_prvspace[0].globaldata;
+               (int) &CPU_prvspace[0].globaldata.gd_common_tss;
 #else
        gdt_segs[GPRIV_SEL].ssd_limit = atop(0 - 1);
        gdt_segs[GPROC0_SEL].ssd_base = (int) &common_tss;
-       gd = &UP_globaldata;
 #endif
+       gd->gd_prvspace = &CPU_prvspace[0];
        /*
         * Note: on both UP and SMP curthread must be set non-NULL
         * early in the boot sequence because the system assumes
         * that 'curthread' is never NULL.
         */
        /* YYY use prvspace for UP too and set here rather then later */
-       gd->gd_curthread = &gd->gd_idlethread;
+       mi_gdinit(gd, 0);
+       cpu_gdinit(gd, 0);
 
        for (x = 0; x < NGDT; x++) {
 #ifdef BDE_DEBUGGER
@@ -2069,6 +2074,26 @@ init386(first)
        proc0.p_md.md_regs = &proc0_tf;
 }
 
+/*
+ * Initialize machine-dependant portions of the global data structure
+ *
+ *     YYY do we need to reserve pcb space for idlethread?
+ */
+void
+cpu_gdinit(struct globaldata *gd, int cpu)
+{
+       char *sp;
+
+       TAILQ_INIT(&gd->gd_tdfreeq);    /* for pmap_{new,dispose}_thread() */
+       if (cpu)
+           gd->gd_curthread = &gd->gd_idlethread;
+       sp = gd->gd_prvspace->idlestack;
+       lwkt_init_thread(&gd->gd_idlethread, sp);
+       gd->gd_idlethread.td_switch = cpu_lwkt_switch;
+       gd->gd_idlethread.td_sp -= sizeof(void *);
+       *(void **)gd->gd_idlethread.td_sp = cpu_idle_restore;
+}
+
 #if defined(I586_CPU) && !defined(NO_F00F_HACK)
 static void f00f_hack(void *unused);
 SYSINIT(f00f_hack, SI_SUB_INTRINSIC, SI_ORDER_FIRST, f00f_hack, NULL);
@@ -2408,7 +2433,7 @@ set_dbregs(p, dbregs)
                 * from within kernel mode?
                 */
                
-               if (suser(p) != 0) {
+               if (suser_cred(p->p_ucred, 0) != 0) {
                        if (dbregs->dr7 & 0x3) {
                                /* dr0 is enabled */
                                if (dbregs->dr0 >= VM_MAXUSER_ADDRESS)