Userspace no longer includes the kernel's arch/*
authorBarret Rhoden <brho@cs.berkeley.edu>
Mon, 5 Apr 2010 04:10:50 +0000 (21:10 -0700)
committerKevin Klues <klueska@cs.berkeley.edu>
Thu, 3 Nov 2011 00:35:40 +0000 (17:35 -0700)
The kernel and userspace still share kern/include/ros/arch, which points
to arch specific folders, but not the entire kern/arch/XXX/ folder
(which is what kern/include/arch pointed to).  This helps sort out some
issues with repeated symbols (reboot in arch/arch.h conflicts with
libc), makes the kernel interface more explicit, and will help us to
avoid making changes to the kernel for no reason other than userspace
includes its files.

There are a few places where things are ghetto - mostly because they
ought to be solved properly (read_tsc()) or will go away with future
commits (segmentation stuff).

Long term, I'd like to minimize the amount of stuff in kern/include/ros,
even if it means having copies of arch-specific things.  And the copies
are not always copies - often there are slight differences between the
kernel and userspace.

18 files changed:
kern/arch/i686/atomic.h
kern/arch/i686/env.c
kern/arch/i686/membar.h [deleted file]
kern/arch/i686/mmu.h
kern/arch/i686/ros/membar.h [new file with mode: 0644]
kern/arch/i686/ros/mmu.h
kern/arch/sparc/atomic.h
kern/arch/sparc/membar.h [deleted file]
kern/arch/sparc/ros/membar.h [new file with mode: 0644]
kern/include/ros/procdata.h
kern/include/ros/ring_buffer.h
tests/breakpoint.c
tests/mhello.c
tests/mproctests.c
tests/proctests.c
tools/compilers/gcc-glibc/Makefile
tools/compilers/gcc-glibc/glibc-2.11.1-ros/sysdeps/ros/i386/tls.h
user/parlib/panic.c

index 9266ce3..14bfe65 100644 (file)
@@ -4,7 +4,6 @@
 #include <ros/common.h>
 #include <arch/x86.h>
 #include <arch/arch.h>
-#include <arch/membar.h>
 
 typedef void * RACY atomic_t;
 struct spinlock {
index 15f8554..19afc17 100644 (file)
@@ -15,6 +15,7 @@
 //
 void env_pop_tf(trapframe_t *tf)
 {
+       /* Bug with this whole idea (TODO: (TLSV))*/
        /* Load the LDT for this process.  Slightly ghetto doing it here. */
        segdesc_t *my_gdt = per_cpu_info[core_id()].gdt;
        /* copy-in and check the LDT location.  the segmentation hardware write the
diff --git a/kern/arch/i686/membar.h b/kern/arch/i686/membar.h
deleted file mode 100644 (file)
index 1fa5df9..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-#ifndef _ARCH_MEMBAR_H
-#define _ARCH_MEMBAR_H
-
-#define mb() {rmb(); wmb();}
-#define rmb() ({ asm volatile("lfence"); })
-#define wmb() 
-/* Force a wmb, used in cases where an IPI could beat a write, even though
- *  * write-orderings are respected. */
-#define wmb_f() ({ asm volatile("sfence"); })
-
-#endif
index 7c4ebbd..e4a84e4 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef ROS_INC_MMU_H
-#define ROS_INC_MMU_H
+#ifndef ROS_ARCH_MMU_H
+#define ROS_ARCH_MMU_H
 
 #ifndef __ASSEMBLER__
 #include <ros/common.h>
  *
  */
 
-// Global descriptor numbers
-#define GD_NULL   0x00     // NULL descriptor
-#define GD_KT     0x08     // kernel text
-#define GD_KD     0x10     // kernel data
-#define GD_UT     0x18     // user text
-#define GD_UD     0x20     // user data
-#define GD_TSS    0x28     // Task segment selector
-#define GD_LDT    0x30     // local descriptor table
-
-#ifdef __ASSEMBLER__
-
-/*
- * Macros to build GDT entries in assembly.
- */
-#define SEG_NULL                                               \
-       .word 0, 0;                                             \
-       .byte 0, 0, 0, 0
-#define SEG(type,base,lim)                                     \
-       .word (((lim) >> 12) & 0xffff), ((base) & 0xffff);      \
-       .byte (((base) >> 16) & 0xff), (0x90 | (type)),         \
-               (0xC0 | (((lim) >> 28) & 0xf)), (((base) >> 24) & 0xff)
-
-#else  // not __ASSEMBLER__
-
-#include <ros/common.h>
-
-// Segment Descriptors
-typedef struct Segdesc {
-       unsigned sd_lim_15_0 : 16;  // Low bits of segment limit
-       unsigned sd_base_15_0 : 16; // Low bits of segment base address
-       unsigned sd_base_23_16 : 8; // Middle bits of segment base address
-       unsigned sd_type : 4;       // Segment type (see STS_ constants)
-       unsigned sd_s : 1;          // 0 = system, 1 = application
-       unsigned sd_dpl : 2;        // Descriptor Privilege Level
-       unsigned sd_p : 1;          // Present
-       unsigned sd_lim_19_16 : 4;  // High bits of segment limit
-       unsigned sd_avl : 1;        // Unused (available for software use)
-       unsigned sd_rsv1 : 1;       // Reserved
-       unsigned sd_db : 1;         // 0 = 16-bit segment, 1 = 32-bit segment
-       unsigned sd_g : 1;          // Granularity: limit scaled by 4K when set
-       unsigned sd_base_31_24 : 8; // High bits of segment base address
-} segdesc_t;
-// Null segment
-#define SEG_NULL       { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
-// Segment that is loadable but faults when used
-#define SEG_FAULT      { 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0 }
-// Normal segment
-#define SEG(type, base, lim, dpl)                                                                      \
-{ ((lim) >> 12) & 0xffff, (base) & 0xffff, ((base) >> 16) & 0xff,      \
-    type, 1, dpl, 1, (unsigned) (lim) >> 28, 0, 0, 1, 1,                       \
-    (unsigned) (base) >> 24 }
-// System segment (LDT)
-#define SEG_SYS(type, base, lim, dpl)                                                                  \
-{ ((lim) >> 12) & 0xffff, (base) & 0xffff, ((base) >> 16) & 0xff,      \
-    type, 0, dpl, 1, (unsigned) (lim) >> 28, 0, 0, 1, 1,                       \
-    (unsigned) (base) >> 24 }
-
-#define SEG16(type, base, lim, dpl)                                                            \
-{ (lim) & 0xffff, (base) & 0xffff, ((base) >> 16) & 0xff,                      \
-    type, 1, dpl, 1, (unsigned) (lim) >> 16, 0, 0, 1, 0,                       \
-    (unsigned) (base) >> 24 }
-
-#define SEG16ROINIT(seg,type,base,lim,dpl) \
-       {\
-               (seg).sd_lim_15_0 = SINIT((lim) & 0xffff);\
-               (seg).sd_base_15_0 = SINIT((base)&0xffff);\
-               (seg).sd_base_23_16 = SINIT(((base)>>16)&0xff);\
-               (seg).sd_type = SINIT(type);\
-               (seg).sd_s = SINIT(1);\
-               (seg).sd_dpl = SINIT(dpl);\
-               (seg).sd_p = SINIT(1);\
-               (seg).sd_lim_19_16 = SINIT((unsigned)(lim)>>16);\
-               (seg).sd_avl = SINIT(0);\
-               (seg).sd_rsv1 = SINIT(0);\
-               (seg).sd_db = SINIT(1);\
-               (seg).sd_g = SINIT(0);\
-               (seg).sd_base_31_24 = SINIT((unsigned)(base)>> 24);\
-       }
-
-#endif /* !__ASSEMBLER__ */
-
-// Application segment type bits
-#define STA_X          0x8         // Executable segment
-#define STA_E          0x4         // Expand down (non-executable segments)
-#define STA_C          0x4         // Conforming code segment (executable only)
-#define STA_W          0x2         // Writeable (non-executable segments)
-#define STA_R          0x2         // Readable (executable segments)
-#define STA_A          0x1         // Accessed
-
-// System segment type bits
-#define STS_T16A       0x1         // Available 16-bit TSS
-#define STS_LDT                0x2         // Local Descriptor Table
-#define STS_T16B       0x3         // Busy 16-bit TSS
-#define STS_CG16       0x4         // 16-bit Call Gate
-#define STS_TG         0x5         // Task Gate / Coum Transmitions
-#define STS_IG16       0x6         // 16-bit Interrupt Gate
-#define STS_TG16       0x7         // 16-bit Trap Gate
-#define STS_T32A       0x9         // Available 32-bit TSS
-#define STS_T32B       0xB         // Busy 32-bit TSS
-#define STS_CG32       0xC         // 32-bit Call Gate
-#define STS_IG32       0xE         // 32-bit Interrupt Gate
-#define STS_TG32       0xF         // 32-bit Trap Gate
-
-#define SEG_COUNT      7               // Number of segments in the steady state
-#define LDT_SIZE       (8192 * sizeof(segdesc_t))
+/* Segment descriptor and macros temporarily moved to ros/arch/mmu.h.  Bring
+ * them back when fixing x86 TLS vulns (TLSV) */
 
 /*
  *
@@ -398,4 +295,4 @@ extern pseudodesc_t gdt_pd;
 
 #endif /* !__ASSEMBLER__ */
 
-#endif /* !ROS_INC_MMU_H */
+#endif /* !ROS_ARCH_MMU_H */
diff --git a/kern/arch/i686/ros/membar.h b/kern/arch/i686/ros/membar.h
new file mode 100644 (file)
index 0000000..1fa5df9
--- /dev/null
@@ -0,0 +1,11 @@
+#ifndef _ARCH_MEMBAR_H
+#define _ARCH_MEMBAR_H
+
+#define mb() {rmb(); wmb();}
+#define rmb() ({ asm volatile("lfence"); })
+#define wmb() 
+/* Force a wmb, used in cases where an IPI could beat a write, even though
+ *  * write-orderings are respected. */
+#define wmb_f() ({ asm volatile("sfence"); })
+
+#endif
index 4349224..4d6cec1 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef _ROS_ARCH_MMU_H
-#define _ROS_ARCH_MMU_H
+#ifndef _ROS_INC_ARCH_MMU_H
+#define _ROS_INC_ARCH_MMU_H
 
 #ifndef __ASSEMBLER__
 typedef unsigned long pte_t;
@@ -20,4 +20,114 @@ typedef unsigned long pde_t;
 
 #define JPGSIZE PTSIZE
 
-#endif
+
+/* Segment descriptor and macros temporarily here.  Remove them when fixing x86
+ * TLS vulns (TLSV) */
+
+// Global descriptor numbers
+#define GD_NULL   0x00     // NULL descriptor
+#define GD_KT     0x08     // kernel text
+#define GD_KD     0x10     // kernel data
+#define GD_UT     0x18     // user text
+#define GD_UD     0x20     // user data
+#define GD_TSS    0x28     // Task segment selector
+#define GD_LDT    0x30     // local descriptor table
+
+#ifdef __ASSEMBLER__
+
+/*
+ * Macros to build GDT entries in assembly.
+ */
+#define SEG_NULL                                               \
+       .word 0, 0;                                             \
+       .byte 0, 0, 0, 0
+#define SEG(type,base,lim)                                     \
+       .word (((lim) >> 12) & 0xffff), ((base) & 0xffff);      \
+       .byte (((base) >> 16) & 0xff), (0x90 | (type)),         \
+               (0xC0 | (((lim) >> 28) & 0xf)), (((base) >> 24) & 0xff)
+
+#else  // not __ASSEMBLER__
+
+#include <ros/common.h>
+
+// Segment Descriptors
+typedef struct Segdesc {
+       unsigned sd_lim_15_0 : 16;  // Low bits of segment limit
+       unsigned sd_base_15_0 : 16; // Low bits of segment base address
+       unsigned sd_base_23_16 : 8; // Middle bits of segment base address
+       unsigned sd_type : 4;       // Segment type (see STS_ constants)
+       unsigned sd_s : 1;          // 0 = system, 1 = application
+       unsigned sd_dpl : 2;        // Descriptor Privilege Level
+       unsigned sd_p : 1;          // Present
+       unsigned sd_lim_19_16 : 4;  // High bits of segment limit
+       unsigned sd_avl : 1;        // Unused (available for software use)
+       unsigned sd_rsv1 : 1;       // Reserved
+       unsigned sd_db : 1;         // 0 = 16-bit segment, 1 = 32-bit segment
+       unsigned sd_g : 1;          // Granularity: limit scaled by 4K when set
+       unsigned sd_base_31_24 : 8; // High bits of segment base address
+} segdesc_t;
+// Null segment
+#define SEG_NULL       { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
+// Segment that is loadable but faults when used
+#define SEG_FAULT      { 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0 }
+// Normal segment
+#define SEG(type, base, lim, dpl)                                                                      \
+{ ((lim) >> 12) & 0xffff, (base) & 0xffff, ((base) >> 16) & 0xff,      \
+    type, 1, dpl, 1, (unsigned) (lim) >> 28, 0, 0, 1, 1,                       \
+    (unsigned) (base) >> 24 }
+// System segment (LDT)
+#define SEG_SYS(type, base, lim, dpl)                                                                  \
+{ ((lim) >> 12) & 0xffff, (base) & 0xffff, ((base) >> 16) & 0xff,      \
+    type, 0, dpl, 1, (unsigned) (lim) >> 28, 0, 0, 1, 1,                       \
+    (unsigned) (base) >> 24 }
+
+#define SEG16(type, base, lim, dpl)                                                            \
+{ (lim) & 0xffff, (base) & 0xffff, ((base) >> 16) & 0xff,                      \
+    type, 1, dpl, 1, (unsigned) (lim) >> 16, 0, 0, 1, 0,                       \
+    (unsigned) (base) >> 24 }
+
+#define SEG16ROINIT(seg,type,base,lim,dpl) \
+       {\
+               (seg).sd_lim_15_0 = SINIT((lim) & 0xffff);\
+               (seg).sd_base_15_0 = SINIT((base)&0xffff);\
+               (seg).sd_base_23_16 = SINIT(((base)>>16)&0xff);\
+               (seg).sd_type = SINIT(type);\
+               (seg).sd_s = SINIT(1);\
+               (seg).sd_dpl = SINIT(dpl);\
+               (seg).sd_p = SINIT(1);\
+               (seg).sd_lim_19_16 = SINIT((unsigned)(lim)>>16);\
+               (seg).sd_avl = SINIT(0);\
+               (seg).sd_rsv1 = SINIT(0);\
+               (seg).sd_db = SINIT(1);\
+               (seg).sd_g = SINIT(0);\
+               (seg).sd_base_31_24 = SINIT((unsigned)(base)>> 24);\
+       }
+
+#endif /* !__ASSEMBLER__ */
+
+// Application segment type bits
+#define STA_X          0x8         // Executable segment
+#define STA_E          0x4         // Expand down (non-executable segments)
+#define STA_C          0x4         // Conforming code segment (executable only)
+#define STA_W          0x2         // Writeable (non-executable segments)
+#define STA_R          0x2         // Readable (executable segments)
+#define STA_A          0x1         // Accessed
+
+// System segment type bits
+#define STS_T16A       0x1         // Available 16-bit TSS
+#define STS_LDT                0x2         // Local Descriptor Table
+#define STS_T16B       0x3         // Busy 16-bit TSS
+#define STS_CG16       0x4         // 16-bit Call Gate
+#define STS_TG         0x5         // Task Gate / Coum Transmitions
+#define STS_IG16       0x6         // 16-bit Interrupt Gate
+#define STS_TG16       0x7         // 16-bit Trap Gate
+#define STS_T32A       0x9         // Available 32-bit TSS
+#define STS_T32B       0xB         // Busy 32-bit TSS
+#define STS_CG32       0xC         // 32-bit Call Gate
+#define STS_IG32       0xE         // 32-bit Interrupt Gate
+#define STS_TG32       0xF         // 32-bit Trap Gate
+
+#define SEG_COUNT      7               // Number of segments in the steady state
+#define LDT_SIZE       (8192 * sizeof(segdesc_t))
+
+#endif /* !ROS_INC_ARCH_MMU_H */
index 372ac15..bd0e8fc 100644 (file)
@@ -2,7 +2,7 @@
 #define ROS_INCLUDE_ATOMIC_H
 
 #include <ros/common.h>
-#include <arch/membar.h>
+#include <ros/arch/membar.h>
 
 typedef struct
 {
diff --git a/kern/arch/sparc/membar.h b/kern/arch/sparc/membar.h
deleted file mode 100644 (file)
index 2e8cc34..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-#ifndef _ARCH_MEMBAR_H
-#define _ARCH_MEMBAR_H
-
-#define mb() {rmb(); wmb();}
-#define rmb()
-#define wmb() ({ __asm__ __volatile__ ("stbar"); })
-/* Force a wmb, used in cases where an IPI could beat a write, even though
- *  * write-orderings are respected.  (Used by x86) */
-#define wmb_f() wmb()
-
-#endif
diff --git a/kern/arch/sparc/ros/membar.h b/kern/arch/sparc/ros/membar.h
new file mode 100644 (file)
index 0000000..2e8cc34
--- /dev/null
@@ -0,0 +1,11 @@
+#ifndef _ARCH_MEMBAR_H
+#define _ARCH_MEMBAR_H
+
+#define mb() {rmb(); wmb();}
+#define rmb()
+#define wmb() ({ __asm__ __volatile__ ("stbar"); })
+/* Force a wmb, used in cases where an IPI could beat a write, even though
+ *  * write-orderings are respected.  (Used by x86) */
+#define wmb_f() wmb()
+
+#endif
index aa2697b..d2e5703 100644 (file)
@@ -10,7 +10,6 @@
 #include <ros/common.h>
 #include <ros/procinfo.h>
 #include <ros/notification.h>
-#include <arch/mmu.h>
 
 typedef struct procdata {
        syscall_sring_t                 syscallring;
@@ -18,7 +17,7 @@ typedef struct procdata {
        sysevent_sring_t                syseventring;
        char                                    pad2[SYSEVENTRINGSIZE - sizeof(sysevent_sring_t)];
 #ifdef __i386__
-       segdesc_t                               *ldt; // TODO: bug with this.  needs to go
+       segdesc_t                               *ldt; // TODO: bug with this. (TLSV)
 #endif
        // TODO: will replace these in a later commit
        uintptr_t stack_pointers[MAX_NUM_CPUS];
index 0f8c203..06f4e61 100644 (file)
@@ -28,7 +28,7 @@
 #define ROS_INC_RING_BUFFER_H
 
 #include <string.h>
-#include <arch/membar.h>
+#include <ros/arch/membar.h>
 
 #define xen_mb()  mb()
 #define xen_rmb() rmb()
index f1fd28d..03793f1 100644 (file)
@@ -1,5 +1,19 @@
 // program to cause a breakpoint trap
-#include <arch/arch.h>
+
+// TODO: have arch specific user includes
+#ifdef __i386__
+static __inline void
+breakpoint(void)
+{
+       __asm __volatile("int3");
+}
+#else
+static __inline void
+breakpoint(void)
+{
+       asm volatile ("ta 0x7f");
+}
+#endif
 
 int main(int argc, char** argv)
 {
index 416f3b0..e2b5e3f 100644 (file)
@@ -4,22 +4,6 @@
 #include <stdio.h>
 #include <hart.h>
 
-// ghetto udelay, put in a lib somewhere and export the tsc freq
-#include <arch/arch.h>
-void udelay(uint64_t usec, uint64_t tsc_freq)
-{
-       uint64_t start, end, now;
-
-       start = read_tsc();
-    end = start + (tsc_freq * usec) / 1000000;
-       if (end == 0) printf("This is terribly wrong \n");
-       do {
-        cpu_relax();
-        now = read_tsc();
-       } while (now < end || (now > start && end < start));
-       return;
-}
-
 hart_barrier_t b;
 
 __thread int temp;
index 19c3ed9..37a2ded 100644 (file)
@@ -5,8 +5,37 @@
 #include <ros/resource.h>
 #include <stdio.h>
 
+#ifdef __i386__ // TODO: fix me with per-arch user includes
+static __inline uint64_t
+read_tsc(void)
+{
+       uint64_t tsc;
+       __asm __volatile("rdtsc" : "=A" (tsc));
+       return tsc;
+}
+
+static __inline void
+cpu_relax(void)
+{
+       asm volatile("pause" : : : "memory");
+}
+#else
+static __inline uint64_t
+read_tsc(void)
+{
+       return read_perfctr(0,0);
+}
+
+static __inline void
+cpu_relax(void)
+{
+       int ctr = 8;
+       asm volatile("1: deccc %0; bne 1b; nop" :
+                    "=r"(ctr) : "0"(ctr) : "cc","memory");
+}
+#endif
+
 // ghetto udelay, put in a lib somewhere and export the tsc freq
-#include <arch/arch.h>
 void udelay(uint64_t usec, uint64_t tsc_freq)
 {
        uint64_t start, end, now;
index 01d6286..cc4c6e2 100644 (file)
@@ -1,6 +1,5 @@
 #include <parlib.h>
 #include <stdio.h>
-#include <arch/arch.h>
 
 /* This runs a variety of process tests.  For now, it just tests single-core
  * yielding among a bunch of processes (which it creates).  It needs the
index fc25224..16991cf 100644 (file)
@@ -218,11 +218,13 @@ $(BINARY_PREFIX)gcc-stage2-builddir: gcc-$(GCC_VERSION)
        cp bits/stdio_lim.h $(INSTDIR)/$(ARCH)-ros/include/bits/
 
 .$(BINARY_PREFIX)ros-headers-install: $(ROSDIR)
-       mkdir -p $(INSTDIR)/$(ARCH)-ros/sys-include/arch
+       rm -rf $(INSTDIR)/$(ARCH)-ros/sys-include/ros/*
        cp -r $(ROSDIR)/kern/include/ros \
           $(INSTDIR)/$(ARCH)-ros/sys-include/
-       cp -r $(ROSDIR)/kern/arch/$(ROS_ARCH_DIR)/* \
-          $(INSTDIR)/$(ARCH)-ros/sys-include/arch/
+       rm -f $(INSTDIR)/$(ARCH)-ros/sys-include/ros/arch
+       mkdir $(INSTDIR)/$(ARCH)-ros/sys-include/ros/arch
+       cp -r $(ROSDIR)/kern/arch/$(ROS_ARCH_DIR)/ros/* \
+          $(INSTDIR)/$(ARCH)-ros/sys-include/ros/arch/
 
 .$(BINARY_PREFIX)gcc-stage1-configure: 
        $(MAKE) $(BINARY_PREFIX)gcc-stage1-builddir
index 3fec942..6035504 100644 (file)
@@ -34,7 +34,7 @@
 #include <ros/arch/bits/syscall.h>
 #include <ros/procinfo.h>
 #include <ros/procdata.h>
-#include <arch/mmu.h>
+#include <ros/arch/mmu.h>
 
 
 /* Type for the dtv.  */
@@ -441,6 +441,7 @@ static const char* tls_init_tp(void* thrdescr)
 
   int core_id = __syscall_sysenter(SYS_getvcoreid,0,0,0,0,0,NULL);
 
+  /* Bug with this whole idea (TODO: (TLSV))*/
   if(__procdata.ldt == NULL)
   {
     size_t sz= (sizeof(segdesc_t)*__procinfo.max_harts+PGSIZE-1)/PGSIZE*PGSIZE;
index 2f7b105..27b5011 100644 (file)
@@ -1,10 +1,25 @@
 
-#include <arch/arch.h>
+#include <ros/arch/arch.h>
 #include <stdio.h>
 #include <stdarg.h>
 
 char *argv0;
 
+// TODO: have arch specific user includes
+#ifdef __i386__
+static __inline void
+breakpoint(void)
+{
+       __asm __volatile("int3");
+}
+#else
+static __inline void
+breakpoint(void)
+{
+       asm volatile ("ta 0x7f");
+}
+#endif
+
 /*
  * Panic is called on unresolvable fatal errors.
  * It prints "panic: <message>", then causes a breakpoint exception,