[metal] Place GDT in read/write segment

The CPU absolutely needs to alter the GDT when loading the
task register (via ltr).  To account for this, I move the
GDT into a read/write data section.  There is still a "rump"
read-only GDT in the text section that is used by the real
mode bootloader.

I also delay the loading of the task register (ltr) until
after the IDT and TSS are finally set up.
This commit is contained in:
tkchia 2022-11-09 18:02:19 +00:00
parent 771566c8f8
commit 36b06ab73e
2 changed files with 45 additions and 37 deletions

View file

@ -1091,6 +1091,42 @@ ape_idata_idt:
ape_idata_idtend:
.previous
.section .piro.data.sort.metal_gdt,"aw",@progbits
.align 8
_gdt:
// G:granularity (1 limit *= 0x1000)
// D/B:default operation size (0 = 16|64bit, 1 = 32-bit)
// L:long mode
// AVL:this bit is thine (1<<52)
// P:present
// DPL:privilege
// data/code(1)
// data(0)code(1)
// conformingexpand-down
// writeablereadable
// accessedaccessed
//
//
//
//
// base address segment limit
// 32 bits 20 bits
//
// 6666555555555544444444443333333333222222222211111111110000000000
// 3210987654321098765432109876543210987654321098765432109876543210
//
.quad 0b0000000000000000000000000000000000000000000000000000000000000000 # 0
.quad 0b0000000000001111100110100000000000000000000000001111111111111111 # 8
.quad 0b0000000000001111100100100000000000000000000000001111111111111111 #16
.quad 0b0000000011001111100110100000000000000000000000001111111111111111 #24
.quad 0b0000000011001111100100100000000000000000000000001111111111111111 #32
.quad 0b0000000010101111100110110000000000000000000000001111111111111111 #40
.quad 0b0000000010101111100100110000000000000000000000001111111111111111 #48
.tssdescstub _tss #56,64
_gdt_end:
.endobj _gdt,global,hidden
.previous
.section .piro.data.sort.iat.1,"aw",@progbits
.type ape_idata_iatend,@object
.type ape_idata_iat,@object
@ -1149,47 +1185,20 @@ sconf: .short 1843200/*hz*/ / 16/*wut*/ / 9600/*baud*/
// Global Descriptor Table
.align 8
_gdtrlo:
.short 2f-1f-1 # table byte length
.long REAL(1f) # table address (base memory space)
.short 2f-_gdtlo-1 # table byte length
.long REAL(_gdtlo) # table address (base memory space)
.endobj _gdtrlo,global,hidden
_gdtr:
.short 2f-1f-1 # table byte length
.quad 1f # table address (final virtual space)
.short _gdt_end-_gdt-1 # table byte length
.quad _gdt # 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)
// L:long mode
// AVL:this bit is thine (1<<52)
// P:present
// DPL:privilege
// data/code(1)
// data(0)code(1)
// conformingexpand-down
// writeablereadable
// accessedaccessed
//
//
//
//
// base address segment limit
// 32 bits 20 bits
//
// 6666555555555544444444443333333333222222222211111111110000000000
// 3210987654321098765432109876543210987654321098765432109876543210
//
.quad 0b0000000000000000000000000000000000000000000000000000000000000000 # 0
.quad 0b0000000000001111100110100000000000000000000000001111111111111111 # 8
.quad 0b0000000000001111100100100000000000000000000000001111111111111111 #16
.quad 0b0000000011001111100110100000000000000000000000001111111111111111 #24
// Partial GDT with descriptors for switching to unreal mode or long mode.
_gdtlo = .-GDT_LEGACY_DATA
.quad 0b0000000011001111100100100000000000000000000000001111111111111111 #32
.quad 0b0000000010101111100110110000000000000000000000001111111111111111 #40
.quad 0b0000000010101111100100110000000000000000000000001111111111111111 #48
.tssdescstub _tss #56,64
2:
.endobj _gdt,global,hidden
/*
αcτµαlly pδrταblε εxεcµταblε § real mode
@ -1570,8 +1579,6 @@ long: movabs $BANE+PHYSICAL(0f),%rax
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

View file

@ -109,8 +109,7 @@ __excep0_isr:
isr_init:
testb IsMetal()
jz 9f
ezlea _tss+0x24,di # fill up TSS, we already loaded
# task register in ape/ape.S
ezlea _tss+0x24,di # fill up TSS
ezlea _isr_stk_1+ISR_STK_SZ,ax
and $-ISR_STK_ALIGN,%al # be paranoid & enforce correct
stosq # alignment of stack pointers
@ -142,6 +141,8 @@ isr_init:
stosq
add $__excep1_isr-__excep0_isr,%rdx
loop 1b
mov $GDT_LONG_TSS,%cl # load task register (cx = 0 here)
ltr %cx
9: ret
// String constants.