xv6

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

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:
Minclude/memlayout.h | 4++++
Minclude/mmu.h | 12++++++++++++
Minclude/proc.h | 24+++++++++++++++++++++++-
Minclude/types.h | 4++++
Minclude/x86.h | 12++++++++++--
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)); }