mirror of
https://github.com/limine-bootloader/limine
synced 2025-03-14 05:22:59 +03:00
limine: Add support for MAX_PAGING_MODE config option
This commit is contained in:
parent
f4ebb6f4d7
commit
001a442750
@ -123,6 +123,9 @@ Editor control options:
|
||||
* `MODULE_CMDLINE` - A command line to be passed to a module. This key can also be specified multiple times. It applies to the module described by the last module key assigned.
|
||||
* `RESOLUTION` - The resolution to be used. This setting takes the form of `<width>x<height>x<bpp>`. If the resolution is not available, Limine will pick another one automatically. Omitting `<bpp>` will default to 32.
|
||||
* `KASLR` - For relocatable kernels, if set to `no`, disable kernel address space layout randomisation. KASLR is enabled by default.
|
||||
* `MAX_PAGING_MODE` - Limit the maximum paging mode to one of the following:
|
||||
- x86-64 and aarch64: `4level`, `5level`.
|
||||
- riscv64: `sv39`, `sv48`, `sv57`.
|
||||
|
||||
* multiboot1 and multiboot2 protocols:
|
||||
* `KERNEL_PATH` - The URI path of the kernel.
|
||||
|
@ -101,6 +101,7 @@ static const char *VALID_KEYS[] = {
|
||||
"RESOLUTION",
|
||||
"TEXTMODE",
|
||||
"KASLR",
|
||||
"MAX_PAGING_MODE",
|
||||
"DRIVE",
|
||||
"PARTITION",
|
||||
"MBR_ID",
|
||||
|
@ -440,22 +440,22 @@ noreturn void limine_load(char *config, char *cmdline) {
|
||||
printv("limine: Requests count: %u\n", requests_count);
|
||||
|
||||
// Paging Mode
|
||||
int paging_mode, max_paging_mode;
|
||||
int paging_mode, max_supported_paging_mode;
|
||||
|
||||
#if defined (__x86_64__) || defined (__i386__)
|
||||
paging_mode = max_paging_mode = PAGING_MODE_X86_64_4LVL;
|
||||
paging_mode = max_supported_paging_mode = PAGING_MODE_X86_64_4LVL;
|
||||
if (cpuid(0x00000007, 0, &eax, &ebx, &ecx, &edx) && (ecx & (1 << 16))) {
|
||||
printv("limine: CPU has 5-level paging support\n");
|
||||
max_paging_mode = PAGING_MODE_X86_64_5LVL;
|
||||
max_supported_paging_mode = PAGING_MODE_X86_64_5LVL;
|
||||
}
|
||||
|
||||
#elif defined (__aarch64__)
|
||||
paging_mode = max_paging_mode = PAGING_MODE_AARCH64_4LVL;
|
||||
paging_mode = max_supported_paging_mode = PAGING_MODE_AARCH64_4LVL;
|
||||
// TODO(qookie): aarch64 also has optional 5 level paging when using 4K pages
|
||||
|
||||
#elif defined (__riscv64)
|
||||
max_paging_mode = vmm_max_paging_mode();
|
||||
paging_mode = max_paging_mode >= PAGING_MODE_RISCV_SV48 ? PAGING_MODE_RISCV_SV48 : PAGING_MODE_RISCV_SV39;
|
||||
max_supported_paging_mode = vmm_max_paging_mode();
|
||||
paging_mode = max_supported_paging_mode >= PAGING_MODE_RISCV_SV48 ? PAGING_MODE_RISCV_SV48 : PAGING_MODE_RISCV_SV39;
|
||||
|
||||
#else
|
||||
#error Unknown architecture
|
||||
@ -475,14 +475,45 @@ FEAT_START
|
||||
if (pm_request == NULL)
|
||||
break;
|
||||
|
||||
if (pm_request->mode > LIMINE_PAGING_MODE_MAX) {
|
||||
print("warning: ignoring invalid mode in paging mode request\n");
|
||||
break;
|
||||
uint64_t paging_mode_max = LIMINE_PAGING_MODE_MAX;
|
||||
|
||||
char *max_paging_mode_s = config_get_value(config, 0, "MAX_PAGING_MODE");
|
||||
if (max_paging_mode_s != NULL) {
|
||||
#if defined (__x86_64__) || defined (__i386__)
|
||||
if (strcasecmp(max_paging_mode_s, "4level") == 0) {
|
||||
paging_mode_max = LIMINE_PAGING_MODE_X86_64_4LVL;
|
||||
} else if (strcasecmp(max_paging_mode_s, "5level") == 0) {
|
||||
paging_mode_max = LIMINE_PAGING_MODE_X86_64_5LVL;
|
||||
}
|
||||
#elif defined (__aarch64__)
|
||||
if (strcasecmp(max_paging_mode_s, "4level") == 0) {
|
||||
paging_mode_max = LIMINE_PAGING_MODE_AARCH64_4LVL;
|
||||
} else if (strcasecmp(max_paging_mode_s, "5level") == 0) {
|
||||
paging_mode_max = LIMINE_PAGING_MODE_AARCH64_5LVL;
|
||||
}
|
||||
#elif defined (__riscv64)
|
||||
if (strcasecmp(max_paging_mode_s, "sv39") == 0) {
|
||||
paging_mode_max = LIMINE_PAGING_MODE_RISCV_SV39;
|
||||
} else if (strcasecmp(max_paging_mode_s, "sv48") == 0) {
|
||||
paging_mode_max = LIMINE_PAGING_MODE_RISCV_SV48;
|
||||
} else if (strcasecmp(max_paging_mode_s, "sv57") == 0) {
|
||||
paging_mode_max = LIMINE_PAGING_MODE_RISCV_SV57;
|
||||
}
|
||||
#endif
|
||||
else {
|
||||
panic(true, "limine: Invalid MAX_PAGING_MODE: `%s`", max_paging_mode_s);
|
||||
}
|
||||
}
|
||||
|
||||
paging_mode = paging_mode_limine_to_vmm(pm_request->mode);
|
||||
if (paging_mode > max_paging_mode)
|
||||
paging_mode = max_paging_mode;
|
||||
uint64_t target_mode = pm_request->mode;
|
||||
if (pm_request->mode > paging_mode_max) {
|
||||
target_mode = paging_mode_max;
|
||||
}
|
||||
|
||||
paging_mode = paging_mode_limine_to_vmm(target_mode);
|
||||
if (paging_mode > max_supported_paging_mode) {
|
||||
paging_mode = max_supported_paging_mode;
|
||||
}
|
||||
|
||||
set_paging_mode(paging_mode, kaslr);
|
||||
paging_mode_set = true;
|
||||
|
@ -132,7 +132,7 @@ __attribute__((section(".limine_requests")))
|
||||
static volatile struct limine_paging_mode_request _pm_request = {
|
||||
.id = LIMINE_PAGING_MODE_REQUEST,
|
||||
.revision = 0, .response = NULL,
|
||||
.mode = LIMINE_PAGING_MODE_DEFAULT,
|
||||
.mode = LIMINE_PAGING_MODE_X86_64_5LVL,
|
||||
.flags = 0,
|
||||
};
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user