Enable CPU exception handling w/ IDT & TSS (#640)

This commit is contained in:
tkchia 2022-09-30 05:43:08 +08:00 committed by GitHub
parent 09811e739f
commit bc8532688b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 231 additions and 7 deletions

View file

@ -1137,12 +1137,17 @@ sconf: .short 1843200/*hz*/ / 16/*wut*/ / 9600/*baud*/
.endobj sconf,global,hidden
// Global Descriptor Table
//
// @note address portion only concern legacy modes
.align 8
gdt: .short 2f-1f # table byte length
.long REAL(1f),0 # table address
.zero 2
_gdtrphy:
.short 2f-1f-1 # table byte length
.long REAL(1f) # table address (physical space)
.endobj _gdtrphy,global,hidden
_gdtr:
.short 2f-1f-1 # table byte length
.quad 1f # table address (final virtual space)
.endobj _gdtr,global,hidden
.align 8
_gdt:
1:
// G:granularity (1 limit *= 0x1000)
// D/B:default operation size (0 = 16|64bit, 1 = 32-bit)
@ -1172,7 +1177,9 @@ gdt: .short 2f-1f # table byte length
.quad 0b0000000011001111100100100000000000000000000000001111111111111111 #32
.quad 0b0000000010101111100110110000000000000000000000001111111111111111 #40
.quad 0b0000000010101111100100110000000000000000000000001111111111111111 #48
2: .endobj gdt,global,hidden
.tssdescstub _tss #56,64
2:
.endobj _gdt,global,hidden
/*
αcτµαlly pδrταblε εxεcµταblε § real mode
@ -1433,7 +1440,7 @@ golong: cli
rdmsr
or $EFER_LME|EFER_SCE,%eax
wrmsr
lgdt REAL(gdt)
lgdt REAL(_gdtrphy)
mov %cr0,%eax
or $CR0_PE|CR0_PG|CR0_MP,%eax
and $~CR0_EM,%eax
@ -1451,6 +1458,8 @@ long: xor %eax,%eax
mov %eax,%fs
mov %eax,%gs
mov $0x80000,%esp
mov $GDT_LONG_TSS,%al
ltr %ax
xor %r12d,%r12d
xor %r13d,%r13d
xor %r14d,%r14d
@ -1464,6 +1473,8 @@ long: xor %eax,%eax
call __map_phdrs
push $0x037f
fldcw (%rsp)
lgdt _gdtr # reload GDTR for
# virtual memory space
movabs $kernel,%rax
jmp *%rax
.endfn long

View file

@ -572,6 +572,9 @@ HIDDEN(v_ape_realslacksectors =
HIDDEN(v_ape_realpages = v_ape_realsectors / (4096 / 512));
HIDDEN(v_ape_highsectors =
(ROUNDUP(RVA(_edata), 512) / 512) - v_ape_realsectors);
PROVIDE_HIDDEN(_tss = 0);
PROVIDE_HIDDEN(_tss_end = 0);
TSSDESCSTUB2(_tss, _tss, _tss_end ? _tss_end - _tss - 1 : 0);
#endif
/* ZIP End of Central Directory header */

View file

@ -180,6 +180,12 @@
.stub \name\()_bcs\n,long
.endm
// Task State Segment Descriptor Entries.
.macro .tssdescstub name:req
.stub \name\()_desc_ent0,quad
.stub \name\()_desc_ent1,quad
.endm
/* clang-format on */
#elif defined(__LINKER__)
@ -257,5 +263,22 @@
(X) % 10 * 0x1000000 \
: 0xffffffffffffffff)
/**
* Laying out the GDT entries for a TSS for bare metal operation.
*/
#define TSSDESCSTUB2(SYM, BASE, LIM) \
HIDDEN(SYM##_desc_ent0 = TSSDESC_ENT0(BASE, LIM)); \
HIDDEN(SYM##_desc_ent1 = TSSDESC_ENT1(BASE)); \
ASSERT((LIM) >= 0 && (LIM) <= 0xffff, "bare metal TSS is suspiciously fat")
#define TSSDESC_ENT0(BASE, LIM) \
(((LIM) << 0 & 0x000000000000ffff) | \
((BASE) << 16 & 0x000000ffffff0000) | \
0x89 << 40 | \
((LIM) >> 16 << 48 & 0x000f000000000000) | \
0x2 << 52 | \
((BASE) >> 24 << 56 & 0xff00000000000000))
#define TSSDESC_ENT1(BASE) \
((BASE) >> 32 << 0 & 0x00000000ffffffff)
#endif /* __ASSEMBLER__ */
#endif /* APE_MACROS_H_ */