commit 615ab73fbd9838a96cef87381eaebac960705fc8
parent 8914ac6680f7b0c655d3886719c8efd6832c60c4
Author: Brian Swetland <swetland@frotz.net>
Date: Tue, 31 Dec 2013 12:46:36 -0800
update headers for 64bit support
- changes gated by #define X64
- struct context is different
- uintp is uint64 on x64 vs uint32 on x32
- 1st and 2nd level page tables are 512 entries on x64 (vs 1024)
- use gcc's __thread directive for cpu-local-storage on x64
- lgdt() and lidt() handle 64bit values on x64
Diffstat:
5 files changed, 53 insertions(+), 3 deletions(-)
diff --git a/include/memlayout.h b/include/memlayout.h
@@ -5,7 +5,11 @@
#define DEVSPACE 0xFE000000 // Other devices are at high addresses
// Key addresses for address space layout (see kmap in vm.c for layout)
+#if X64
+#define KERNBASE 0xFFFFFFFF80000000 // First kernel virtual address
+#else
#define KERNBASE 0x80000000 // First kernel virtual address
+#endif
#define KERNLINK (KERNBASE+EXTMEM) // Address where kernel is linked
#ifndef __ASSEMBLER__
diff --git a/include/mmu.h b/include/mmu.h
@@ -118,6 +118,17 @@ struct segdesc {
#define PGADDR(d, t, o) ((uintp)((d) << PDXSHIFT | (t) << PTXSHIFT | (o)))
// Page directory and page table constants.
+#if X64
+#define NPDENTRIES 512 // # directory entries per page directory
+#define NPTENTRIES 512 // # PTEs per page table
+#define PGSIZE 4096 // bytes mapped by a page
+
+#define PGSHIFT 12 // log2(PGSIZE)
+#define PTXSHIFT 12 // offset of PTX in a linear address
+#define PDXSHIFT 21 // offset of PDX in a linear address
+
+#define PXMASK 0x1FF
+#else
#define NPDENTRIES 1024 // # directory entries per page directory
#define NPTENTRIES 1024 // # PTEs per page table
#define PGSIZE 4096 // bytes mapped by a page
@@ -127,6 +138,7 @@ struct segdesc {
#define PDXSHIFT 22 // offset of PDX in a linear address
#define PXMASK 0x3FF
+#endif
#define PGROUNDUP(sz) (((sz)+((uintp)PGSIZE-1)) & ~((uintp)(PGSIZE-1)))
#define PGROUNDDOWN(a) (((a)) & ~((uintp)(PGSIZE-1)))
diff --git a/include/proc.h b/include/proc.h
@@ -10,10 +10,14 @@ struct cpu {
volatile uint started; // Has the CPU started?
int ncli; // Depth of pushcli nesting.
int intena; // Were interrupts enabled before pushcli?
-
+
// Cpu-local storage variables; see below
+#if X64
+ void *local;
+#else
struct cpu *cpu;
struct proc *proc; // The currently-running process.
+#endif
};
extern struct cpu cpus[NCPU];
@@ -27,8 +31,13 @@ extern int ncpu;
// holding those two variables in the local cpu's struct cpu.
// This is similar to how thread-local variables are implemented
// in thread libraries such as Linux pthreads.
+#if X64
+extern __thread struct cpu *cpu;
+extern __thread struct proc *proc;
+#else
extern struct cpu *cpu asm("%gs:0"); // &cpus[cpunum()]
extern struct proc *proc asm("%gs:4"); // cpus[cpunum()].proc
+#endif
//PAGEBREAK: 17
// Saved registers for kernel context switches.
@@ -41,6 +50,18 @@ extern struct proc *proc asm("%gs:4"); // cpus[cpunum()].proc
// The layout of the context matches the layout of the stack in swtch.S
// at the "Switch stacks" comment. Switch doesn't save eip explicitly,
// but it is on the stack and allocproc() manipulates it.
+#if X64
+struct context {
+ uintp r15;
+ uintp r14;
+ uintp r13;
+ uintp r12;
+ uintp r11;
+ uintp rbx;
+ uintp rbp;
+ uintp eip; //rip;
+};
+#else
struct context {
uintp edi;
uintp esi;
@@ -48,6 +69,7 @@ struct context {
uintp ebp;
uintp eip;
};
+#endif
enum procstate { UNUSED, EMBRYO, SLEEPING, RUNNABLE, RUNNING, ZOMBIE };
diff --git a/include/types.h b/include/types.h
@@ -5,6 +5,10 @@ typedef unsigned char uchar;
typedef unsigned int uint32;
typedef unsigned long uint64;
+#if X64
+typedef unsigned long uintp;
+#else
typedef unsigned int uintp;
+#endif
typedef uintp pde_t;
diff --git a/include/x86.h b/include/x86.h
@@ -62,11 +62,15 @@ struct segdesc;
static inline void
lgdt(struct segdesc *p, int size)
{
- volatile ushort pd[3];
+ volatile ushort pd[5];
pd[0] = size-1;
pd[1] = (uintp)p;
pd[2] = (uintp)p >> 16;
+#if X64
+ pd[3] = (uintp)p >> 32;
+ pd[4] = (uintp)p >> 48;
+#endif
asm volatile("lgdt (%0)" : : "r" (pd));
}
@@ -75,11 +79,15 @@ struct gatedesc;
static inline void
lidt(struct gatedesc *p, int size)
{
- volatile ushort pd[3];
+ volatile ushort pd[5];
pd[0] = size-1;
pd[1] = (uintp)p;
pd[2] = (uintp)p >> 16;
+#if X64
+ pd[3] = (uintp)p >> 32;
+ pd[4] = (uintp)p >> 48;
+#endif
asm volatile("lidt (%0)" : : "r" (pd));
}