A pc/mem.h => pc/mem.h +99 -0
@@ 0,0 1,99 @@
+#define SELGDT (0<<3) /* selector is in gdt */
+#define SELLDT (1<<3) /* selector is in ldt */
+
+#define SELECTOR(i, t, p) (((i)<<4) | (t) | (p))
+
+/*
+ * segment descriptor/gate
+ */
+typedef struct Segdesc Segdesc;
+struct Segdesc
+{
+ ulong d0;
+ ulong d1;
+};
+#define SEGDATA (0x10<<8) /* data/stack segment */
+#define SEGEXEC (0x18<<8) /* executable segment */
+#define SEGCG (0x0C<<8) /* call gate */
+#define SEGIG (0x0E<<8) /* interrupt gate */
+#define SEGTG (0x0F<<8) /* task gate */
+
+#define SEGP (1<<15) /* segment present */
+#define SEGPL(x) ((x)<<13) /* priority level */
+#define SEGB (1<<22) /* granularity 1==4k (for expand-down) */
+#define SEGG (1<<23) /* granularity 1==4k (for other) */
+#define SEGE (1<<10) /* expand down */
+#define SEGW (1<<9) /* writable (for data/stack) */
+#define SEGR (1<<9) /* readable (for code) */
+#define SEGD (1<<22) /* default 1==32bit (for code) */
+
+/*
+ * gate initializers
+ */
+#define TRAPGATE(s,o,p) { (o)&0xFFFF0000|SEGP|SEGPL(p)|SEGTG, (o)&0xFFFF|((s)<<16) }
+#define INTRGATE(s,o,p) { (o)&0xFFFF0000|SEGP|SEGPL(p)|SEGIG, (o)&0xFFFF|((s)<<16) }
+#define CALLGATE(s,o,p) { (o)&0xFFFF0000|SEGP|SEGPL(p)|SEGCG, (o)&0xFFFF|((s)<<16) }
+
+/*
+ * segment descriptor initializers
+ */
+#define DATASEG(p) { SEGG|(0xF<<16)|SEGP|SEGPL(p)|SEGDATA|SEGW, 0xFFFF }
+#define EXECSEG(p) { SEGG|SEGD|(0xF<<16)|SEGP|SEGPL(p)|SEGEXEC|SEGR, 0xFFFF }
+
+/*
+ * known segments (in GDT) and their selectors
+ */
+enum
+{
+ NULLSEG=0, /* null segment */
+ KESEG= 1, /* kernel executable */
+ KDSEG= 2, /* kernel data/stack */
+ UESEG= 3, /* user executable */
+ UDSEG= 4, /* user data/stack */
+ SYSGATE=5, /* system call gate */
+};
+#define NULLSEL SELECTOR(NULLSEG, SELGDT, 0)
+#define KESEL SELECTOR(KESEG, SELGDT, 0)
+#define KDSEL SELECTOR(KDSEG, SELGDT, 0)
+#define KSSEL SELECTOR(KDSEG, SELGDT, 0)
+#define UESEL SELECTOR(UESEG, SELGDT, 3)
+#define UDSEL SELECTOR(UDSEG, SELGDT, 3)
+#define USSEL SELECTOR(UDSEG, SELGDT, 3)
+
+/*
+ * task state segment. Plan 9 ignores all the task switching goo and just
+ * uses the tss for esp0 and ss0 on gate's into the kernel, interrupts,
+ * and exceptions. The rest is completely ignored.
+ *
+ * This means that we only need one tss in the whole system.
+ */
+typedef struct Tss Tss;
+struct Tss
+{
+ ulong backlink; /* unused */
+ ulong esp0; /* pl0 stack pointer */
+ ulong ss0; /* pl0 stack selector */
+ ulong esp1; /* pl1 stack pointer */
+ ulong ss1; /* pl1 stack selector */
+ ulong esp2; /* pl2 stack pointer */
+ ulong ss2; /* pl2 stack selector */
+ ulong cr3; /* page table descriptor */
+ ulong eip; /* instruction pointer */
+ ulong eflags; /* processor flags */
+ ulong eax; /* general (hah?) registers */
+ ulong ecx;
+ ulong edx;
+ ulong ebx;
+ ulong esp;
+ ulong ebp;
+ ulong esi;
+ ulong edi;
+ ulong es; /* segment selectors */
+ ulong cs;
+ ulong ss;
+ ulong ds;
+ ulong fs;
+ ulong gs;
+ ulong ldt; /* local descriptor table */
+ ulong iomap; /* io map base */
+};
M pc/mmu.c => pc/mmu.c +12 -5
@@ 5,9 5,16 @@
#include "fns.h"
#include "io.h"
-
-
-void
-mapstack(Proc *p)
+/*
+ * global descriptor table describing all segments
+ */
+Segdesc gdt[1024] =
{
-}
+[NULLSEG] { 0, 0}, /* null descriptor */
+[KESEG] EXECSEG(0), /* kernel code */
+[KDSEG] DATASEG(0), /* kernel data/stack */
+[UESEG] EXECSEG(3), /* user code */
+[UDSEG] DATASEG(3), /* user data/stack */
+[SYSGATE] CALLGATE(KESEG, syscall, 3), /* call gate for system calls */
+ { 0, 0}, /* the rest */
+};
A pc/trap.c => pc/trap.c +65 -0
@@ 0,0 1,65 @@
+#include "u.h"
+#include "lib.h"
+#include "mem.h"
+#include "dat.h"
+#include "fns.h"
+#include "io.h"
+
+void ediv(void);
+void edebug(void);
+void enmi(void);
+void ebp(void);
+void eover(void);
+void ebound(void);
+void ebadop(void);
+void enoco(void);
+void edfault(void);
+void enoway(void);
+void etss(void);
+void enoseg(void);
+void estack(void);
+void eprot(void);
+void efault(void);
+
+/*
+ * exception types
+ */
+enum {
+ Ediv= 0, /* divide error */
+ Edebug= 1, /* debug exceptions */
+ Enmi= 2, /* non-maskable interrupt */
+ Ebp= 3, /* INT 3 */
+ Eover= 4, /* overflow */
+ Ebound= 5, /* bounds check */
+ Ebadop= 6, /* invalid opcode */
+ Enoco= 7, /* coprocessor not available */
+ Edfault=8, /* double fault */
+ Etss= 10, /* invalid tss */
+ Enoseg= 11, /* segment not present */
+ Estack= 12, /* stack exception */
+ Eprot= 13, /* general protection */
+ Efault= 14, /* page fault */
+ Eco= 16, /* coprocessor error */
+};
+
+/*
+ * exception/trap gates
+ */
+Segdesc ilt[256] =
+{
+[Ediv] TRAPGATE(KESEL, ediv, 3),
+[Edebug] TRAPGATE(KESEL, edebug, 3),
+[Enmi] INTRGATE(KESEL, enmi, 3),
+[Ebp] TRAPGATE(KESEL, ebp, 3),
+[Eover] TRAPGATE(KESEL, eover, 3),
+[Ebound] TRAPGATE(KESEL, ebound, 3),
+[Ebadop] TRAPGATE(KESEL, ebadop, 3),
+[Enoco] TRAPGATE(KESEL, enoco, 3),
+[Edfault] TRAPGATE(KESEL, edfault, 3),
+[Etss] TRAPGATE(KESEL, etss, 3),
+[Enoseg] TRAPGATE(KESEL, enoseg, 3),
+[Estack] TRAPGATE(KESEL, estack, 3),
+[Eprot] TRAPGATE(KESEL, eprot, 3),
+[Efault] TRAPGATE(KESEL, efault, 3),
+[Eco] TRAPGATE(KESEL, eco, 3),
+};
M port/devroot.c => port/devroot.c +13 -0
@@ 11,6 11,7 @@ enum{
Qbin,
Qboot,
Qcfs,
+ Qcryptfs,
Qdev,
Qenv,
Qproc,
@@ 19,6 20,9 @@ enum{
extern long cfslen;
extern ulong cfscode[];
+extern long cryptfslen;
+extern ulong cryptfscode[];
+
Dirtab rootdir[]={
"bin", {Qbin|CHDIR}, 0, 0700,
@@ 26,6 30,7 @@ Dirtab rootdir[]={
"dev", {Qdev|CHDIR}, 0, 0700,
"env", {Qenv|CHDIR}, 0, 0700,
"proc", {Qproc|CHDIR}, 0, 0700,
+ "cryptfs", {Qcryptfs}, 0, 0700,
"cfs", {Qcfs}, 0, 0700,
};
@@ 113,6 118,14 @@ rootread(Chan *c, void *buf, long n, ulong offset)
memmove(buf, ((char*)cfscode)+offset, n);
return n;
+ case Qcryptfs: /* cryptfs */
+ if(offset >= cryptfslen)
+ return 0;
+ if(offset+n > cryptfslen)
+ n = cryptfslen - offset;
+ memmove(buf, ((char*)cryptfscode)+offset, n);
+ return n;
+
case Qdev:
return 0;
}