This commit is contained in:
Yanyan Jiang 2020-02-01 12:00:41 +00:00
parent 126dcd9333
commit 364f12191c
3 changed files with 40 additions and 45 deletions

View File

@ -1,6 +1,3 @@
#ifndef __X86_H__
#define __X86_H__
// CPU rings
#define DPL_KERN 0x0 // Kernel (ring 0)
#define DPL_USER 0x3 // User (ring 3)
@ -120,30 +117,36 @@ typedef struct {
uint32_t base_31_24 : 8; // High bits of segment base address
} SegDesc;
#define SEG16(type, base, lim, dpl) (SegDesc) \
{ (lim) & 0xffff, (uintptr_t)(base) & 0xffff, \
((uintptr_t)(base) >> 16) & 0xff, type, 0, dpl, 1, \
(uintptr_t)(lim) >> 16, 0, 0, 1, 0, (uintptr_t)(base) >> 24 }
#define SEG32(type, base, lim, dpl) (SegDesc) \
{ ((lim) >> 12) & 0xffff, (uintptr_t)(base) & 0xffff, \
((uintptr_t)(base) >> 16) & 0xff, type, 1, dpl, 1, \
(uintptr_t)(lim) >> 28, 0, 0, 1, 1, (uintptr_t)(base) >> 24 }
#define SEG64(type, dpl) (SegDesc) \
{ 0, 0, 0, type, 1, dpl, 1, 0, 0, 1, 0, 0 }
#define SEG32(type, base, lim, dpl) (SegDesc) \
{ ((lim) >> 12) & 0xffff, (uint32_t)(base) & 0xffff, \
((uint32_t)(base) >> 16) & 0xff, type, 1, dpl, 1, \
(uint32_t)(lim) >> 28, 0, 0, 1, 1, (uint32_t)(base) >> 24 }
#define SEG16(type, base, lim, dpl) (SegDesc) \
{ (lim) & 0xffff, (uint32_t)(base) & 0xffff, \
#define SEGTSS64(type, base, lim, dpl) (SegDesc) \
{ (lim) & 0xffff, (uint32_t)(base) & 0xffff, \
((uint32_t)(base) >> 16) & 0xff, type, 0, dpl, 1, \
(uint32_t)(lim) >> 16, 0, 0, 1, 0, (uint32_t)(base) >> 24 }
(uint32_t)(lim) >> 16, 0, 0, 0, 0, (uint32_t)(base) >> 24 }
// Gate descriptors for interrupts and traps
typedef struct {
uint32_t off_15_0 : 16; // Low 16 bits of offset in segment
uint32_t cs : 16; // Code segment selector
uint32_t args : 5; // # args, 0 for interrupt/trap gates
uint32_t rsv1 : 3; // Reserved(should be zero I guess)
uint32_t type : 4; // Type(STS_{TG,IG32,TG32})
uint32_t s : 1; // Must be 0 (system)
uint32_t dpl : 2; // Descriptor(meaning new) privilege level
uint32_t p : 1; // Present
uint32_t off_31_16 : 16; // High bits of offset in segment
uint32_t off_15_0 : 16; // Low 16 bits of offset in segment
uint32_t cs : 16; // Code segment selector
uint32_t args : 5; // # args, 0 for interrupt/trap gates
uint32_t rsv1 : 3; // Reserved(should be zero I guess)
uint32_t type : 4; // Type(STS_{TG,IG32,TG32})
uint32_t s : 1; // Must be 0 (system)
uint32_t dpl : 2; // Descriptor(meaning new) privilege level
uint32_t p : 1; // Present
uint32_t off_31_16 : 16; // High bits of offset in segment
} GateDesc32;
#define GATE32(type, cs, entry, dpl) (GateDesc32) \
@ -151,17 +154,17 @@ typedef struct {
1, (uint32_t)(entry) >> 16 }
typedef struct {
uint32_t off_15_0 : 16;
uint32_t cs : 16;
uint32_t isv : 3;
uint32_t zero1 : 5;
uint32_t type : 4;
uint32_t zero2 : 1;
uint32_t dpl : 2;
uint32_t p : 1;
uint32_t off_15_0 : 16;
uint32_t cs : 16;
uint32_t isv : 3;
uint32_t zero1 : 5;
uint32_t type : 4;
uint32_t zero2 : 1;
uint32_t dpl : 2;
uint32_t p : 1;
uint32_t off_31_16 : 16;
uint32_t off_63_32 : 32;
uint32_t rsv : 32;
uint32_t rsv : 32;
} GateDesc64;
#define GATE64(type, cs, entry, dpl) (GateDesc64) \
@ -323,6 +326,4 @@ static inline void stack_switch_call(void *sp, void *entry, uintptr_t arg) {
);
}
#endif
#endif
#endif // __ASSEMBLER__

View File

@ -97,14 +97,13 @@ void __am_lapic_init() {
void __am_percpu_initgdt() {
#if __x86_64__
SegDesc *gdt = CPU->gdt;
uint64_t tss = (uint64_t)(&CPU->tss);
gdt[SEG_KCODE] = SEG64(STA_X | STA_R, DPL_KERN);
gdt[SEG_KDATA] = SEG64(STA_W, DPL_KERN);
gdt[SEG_UCODE] = SEG64(STA_X | STA_R, DPL_USER);
gdt[SEG_UDATA] = SEG64(STA_W, DPL_USER);
((uint64_t *)gdt)[SEG_TSS+0] = (sizeof(CPU->tss) - 1) | ((tss & 0xffffff) << 16) |
(0x00e9LL << 40) | (((tss >> 24) & 0xff) << 56);
((uint64_t *)gdt)[SEG_TSS+1] = (tss >> 32);
TSS64 *tss = &CPU->tss;
gdt[SEG_KCODE] = SEG64(STA_X | STA_R, DPL_KERN);
gdt[SEG_KDATA] = SEG64(STA_W, DPL_KERN);
gdt[SEG_UCODE] = SEG64(STA_X | STA_R, DPL_USER);
gdt[SEG_UDATA] = SEG64(STA_W, DPL_USER);
gdt[SEG_TSS] = SEG16(STS_T32A, tss, sizeof(*tss)-1, DPL_KERN);
bug_on((uintptr_t)tss >> 32);
set_gdt(gdt, sizeof(gdt[0]) * (NR_SEG + 1));
set_tr(KSEL(SEG_TSS));
#else

View File

@ -1,6 +1,3 @@
#ifndef __X86_64_QEMU_H__
#define __X86_64_QEMU_H__
#define MAX_CPU 8
#define BOOT_REC_ADDR 0x07000
#define ARG_ADDR 0x10000
@ -132,5 +129,3 @@ void __am_percpu_initlapic();
void __am_stop_the_world();
#endif
#endif