mirror of
https://github.com/memtest86plus/memtest86plus.git
synced 2024-11-23 08:26:23 -06:00
WIP BROKEN NX enablement, for now only for the second page directory.
TODO: * selective NX enablement on pd0, pd1 and pd3. Unconditional NX on the whole pd3 makes memtest86+ reboot in a QEMU-emulated computer. * if supported on all x86_64 CPUs, simply enable long mode and NX simultaneously ? A real K8 dual-core processor didn't seem to hate it, at least. * startup code: NX enablement for x86, on capable computers (CPUID 0x80000001, edx bit 20). * set the appropriate flag in the headers.
This commit is contained in:
parent
a541469850
commit
61afe1143b
@ -104,6 +104,7 @@ startup:
|
||||
movl %esi, boot_params_addr@GOTOFF(%ebx)
|
||||
|
||||
# ...and check if the processor supports long mode.
|
||||
# TODO and NX
|
||||
|
||||
movl $0x80000000, %eax # check if function 0x80000001 is available
|
||||
pushl %ebx # ebx is overwritten by cpuid
|
||||
@ -206,7 +207,7 @@ init_idt_descr:
|
||||
jz 1f # bail if not supported
|
||||
|
||||
movl %cr4, %eax # enable PAE
|
||||
orl $0x00000020, %eax
|
||||
orb $0x20, %al
|
||||
movl %eax, %cr4
|
||||
|
||||
leal pdp@GOTOFF(%ebx), %eax # set the page directory base address
|
||||
@ -219,7 +220,7 @@ init_idt_descr:
|
||||
|
||||
movl $0xc0000080, %ecx # enable long mode
|
||||
rdmsr
|
||||
orl $0x00000100, %eax
|
||||
orb $0x01, %ah
|
||||
wrmsr
|
||||
|
||||
leal pml4@GOTOFF(%ebx), %eax # set the page directory base address
|
||||
@ -648,17 +649,17 @@ gdt_end:
|
||||
|
||||
.data
|
||||
|
||||
.macro ptes64 start, count=64
|
||||
.quad \start + 0x0000000 + 0x83
|
||||
.quad \start + 0x0200000 + 0x83
|
||||
.quad \start + 0x0400000 + 0x83
|
||||
.quad \start + 0x0600000 + 0x83
|
||||
.quad \start + 0x0800000 + 0x83
|
||||
.quad \start + 0x0A00000 + 0x83
|
||||
.quad \start + 0x0C00000 + 0x83
|
||||
.quad \start + 0x0E00000 + 0x83
|
||||
.macro ptes64 start, flags, count=64
|
||||
.quad \start + 0x0000000 + \flags
|
||||
.quad \start + 0x0200000 + \flags
|
||||
.quad \start + 0x0400000 + \flags
|
||||
.quad \start + 0x0600000 + \flags
|
||||
.quad \start + 0x0800000 + \flags
|
||||
.quad \start + 0x0A00000 + \flags
|
||||
.quad \start + 0x0C00000 + \flags
|
||||
.quad \start + 0x0E00000 + \flags
|
||||
.if \count-1
|
||||
ptes64 "(\start+0x01000000)",\count-1
|
||||
ptes64 "(\start+0x01000000)", \flags, \count-1
|
||||
.endif
|
||||
.endm
|
||||
|
||||
@ -702,22 +703,22 @@ pdp:
|
||||
.align 4096
|
||||
.globl pd0
|
||||
pd0:
|
||||
ptes64 0x0000000000000000
|
||||
ptes64 0x0000000000000000,0x0000000000000083
|
||||
|
||||
.align 4096
|
||||
.globl pd1
|
||||
pd1:
|
||||
ptes64 0x0000000040000000
|
||||
ptes64 0x0000000040000000,0x0000000000000083
|
||||
|
||||
.align 4096
|
||||
.globl pd2
|
||||
pd2:
|
||||
ptes64 0x0000000080000000
|
||||
ptes64 0x0000000080000000,0x0000000000000083
|
||||
|
||||
.align 4096
|
||||
.globl pd3
|
||||
pd3:
|
||||
ptes64 0x00000000C0000000
|
||||
ptes64 0x00000000C0000000,0x0000000000000083
|
||||
|
||||
.previous
|
||||
|
||||
|
@ -71,14 +71,14 @@ startup32:
|
||||
# Enable PAE.
|
||||
|
||||
movl %cr4, %eax
|
||||
orl $0x20, %eax
|
||||
orb $0x20, %al
|
||||
movl %eax, %cr4
|
||||
|
||||
# Enable long mode.
|
||||
|
||||
movl $0xc0000080, %ecx
|
||||
rdmsr
|
||||
orl $0x00000100, %eax
|
||||
orb $0x01, %ah
|
||||
wrmsr
|
||||
|
||||
# Enable paging and protection.
|
||||
@ -162,6 +162,13 @@ startup:
|
||||
leaq _stacks(%rip), %rsp
|
||||
addq %rax, %rsp
|
||||
|
||||
# Enable NX.
|
||||
|
||||
movl $0xc0000080, %ecx
|
||||
rdmsr
|
||||
orb $0x08, %ah
|
||||
wrmsr
|
||||
|
||||
# Initialise the pml4 and pdp tables.
|
||||
|
||||
leaq pml4(%rip), %rcx
|
||||
@ -255,8 +262,8 @@ flush: movw $KERNEL_DS, %ax
|
||||
# Enable SSE.
|
||||
|
||||
movq %cr0, %rax
|
||||
andw $0xfffb, %ax # clear coprocessor emulation bit
|
||||
orw $0x0002, %ax # set coprocessor monitoring bit
|
||||
andb $0xfb, %al # clear coprocessor emulation bit
|
||||
orb $0x02, %al # set coprocessor monitoring bit
|
||||
mov %rax, %cr0
|
||||
movq %cr4, %rax
|
||||
orw $0x0600, %ax # set OSFXSR and OSXMMEXCPT
|
||||
@ -465,17 +472,17 @@ gdt_end:
|
||||
|
||||
.data
|
||||
|
||||
.macro ptes64 start, count=64
|
||||
.quad \start + 0x0000000 + 0x83
|
||||
.quad \start + 0x0200000 + 0x83
|
||||
.quad \start + 0x0400000 + 0x83
|
||||
.quad \start + 0x0600000 + 0x83
|
||||
.quad \start + 0x0800000 + 0x83
|
||||
.quad \start + 0x0A00000 + 0x83
|
||||
.quad \start + 0x0C00000 + 0x83
|
||||
.quad \start + 0x0E00000 + 0x83
|
||||
.macro ptes64 start, flags, count=64
|
||||
.quad \start + 0x0000000 + \flags
|
||||
.quad \start + 0x0200000 + \flags
|
||||
.quad \start + 0x0400000 + \flags
|
||||
.quad \start + 0x0600000 + \flags
|
||||
.quad \start + 0x0800000 + \flags
|
||||
.quad \start + 0x0A00000 + \flags
|
||||
.quad \start + 0x0C00000 + \flags
|
||||
.quad \start + 0x0E00000 + \flags
|
||||
.if \count-1
|
||||
ptes64 "(\start+0x01000000)",\count-1
|
||||
ptes64 "(\start+0x01000000)", \flags, \count-1
|
||||
.endif
|
||||
.endm
|
||||
|
||||
@ -514,22 +521,22 @@ pdp:
|
||||
.align 4096
|
||||
.globl pd0
|
||||
pd0:
|
||||
ptes64 0x0000000000000000
|
||||
ptes64 0x0000000000000000,0x0000000000000083
|
||||
|
||||
.align 4096
|
||||
.globl pd1
|
||||
pd1:
|
||||
ptes64 0x0000000040000000
|
||||
ptes64 0x0000000040000000,0x0000000000000083
|
||||
|
||||
.align 4096
|
||||
.globl pd2
|
||||
pd2:
|
||||
ptes64 0x0000000080000000
|
||||
ptes64 0x0000000080000000,0x8000000000000083
|
||||
|
||||
.align 4096
|
||||
.globl pd3
|
||||
pd3:
|
||||
ptes64 0x00000000C0000000
|
||||
ptes64 0x00000000C0000000,0x0000000000000083
|
||||
|
||||
.previous
|
||||
|
||||
@ -567,14 +574,14 @@ data32 lgdt ap_gdt_descr - ap_trampoline
|
||||
# Enable PAE.
|
||||
|
||||
movl %cr4, %eax
|
||||
orl $0x20, %eax
|
||||
orb $0x20, %al
|
||||
movl %eax, %cr4
|
||||
|
||||
# Enable long mode.
|
||||
|
||||
movl $0xc0000080, %ecx
|
||||
rdmsr
|
||||
orl $0x00000100, %eax
|
||||
orb $0x01, %ah
|
||||
wrmsr
|
||||
|
||||
# Enable paging and protection.
|
||||
@ -583,6 +590,13 @@ data32 lgdt ap_gdt_descr - ap_trampoline
|
||||
orl $0x80000001, %eax
|
||||
movl %eax, %cr0
|
||||
|
||||
# Enable NX.
|
||||
|
||||
movl $0xc0000080, %ecx
|
||||
rdmsr
|
||||
orb $0x08, %ah
|
||||
wrmsr
|
||||
|
||||
# Jump to the 64-bit entry point.
|
||||
ap_jump:
|
||||
data32 ljmp $KERNEL_CS, $0
|
||||
|
@ -100,7 +100,9 @@ typedef union {
|
||||
uint32_t : 12; // ECX feature flags, bit 20
|
||||
uint32_t x2apic : 1;
|
||||
uint32_t : 10; // ECX feature flags, bit 31
|
||||
uint32_t : 29; // EDX extended feature flags, bit 0
|
||||
uint32_t : 19; // EDX extended feature flags, bit 0
|
||||
uint32_t nx : 1;
|
||||
uint32_t : 9;
|
||||
uint32_t lm : 1;
|
||||
uint32_t : 2; // EDX extended feature flags, bit 31
|
||||
};
|
||||
|
@ -125,13 +125,14 @@ bool map_window(uintptr_t start_page)
|
||||
return false;
|
||||
}
|
||||
if (cpuid_info.flags.lm == 0 && (start_page >= PAGE_C(64,GB))) {
|
||||
// Fail, we want an address that is out of bounds
|
||||
// for PAE and no long mode (ie. 32 bit CPU).
|
||||
// Fail, we want an address that is out of bounds
|
||||
// for PAE and no long mode (ie. 32 bit CPU).
|
||||
return false;
|
||||
}
|
||||
// Compute the page table entries.
|
||||
uint64_t flags = cpuid_info.flags.nx ? UINT64_C(0x8000000000000083) : 0x83;
|
||||
for (uintptr_t i = 0; i < 512; i++) {
|
||||
pd2[i] = ((uint64_t)window << 30) + (i << VM_PAGE_SHIFT) + 0x83;
|
||||
pd2[i] = ((uint64_t)window << 30) + (i << VM_PAGE_SHIFT) + flags;
|
||||
}
|
||||
// Reload the PDBR to flush any remnants of the old mapping.
|
||||
load_pdbr();
|
||||
|
Loading…
Reference in New Issue
Block a user