diff options
author | Damien Zammit <damien@zamaudio.com> | 2024-02-05 23:10:45 +0100 |
---|---|---|
committer | Samuel Thibault <samuel.thibault@ens-lyon.org> | 2024-02-05 23:10:45 +0100 |
commit | e211bdce3388a3c9e3dafab903dd53374f6d9759 (patch) | |
tree | f41868d1e2a30d6750efa9219649f06188080bdc /i386/i386at | |
parent | a923f97ff290a70fc224ac79ab276feae1cfbf53 (diff) | |
download | gnumach-e211bdce3388a3c9e3dafab903dd53374f6d9759.tar.gz gnumach-e211bdce3388a3c9e3dafab903dd53374f6d9759.tar.bz2 gnumach-e211bdce3388a3c9e3dafab903dd53374f6d9759.zip |
smp: Remove hardcoded AP_BOOT_ADDR
This took some time to figure out.
Involves a hand-crafted 16 bit assembly instruction [1]
because it requires an immediate for the memory address
of far jump. This required self-modifying code
to inject the next instruction, therefore I added a near
jump to clear the instruction cache queue in case the pipeline
cached the unmodified jump location.
[1] Intel Architecture Software Developer's Manual,
Volume 2: Instruction Set Reference Manual
Diffstat (limited to 'i386/i386at')
-rw-r--r-- | i386/i386at/model_dep.c | 18 |
1 files changed, 18 insertions, 0 deletions
diff --git a/i386/i386at/model_dep.c b/i386/i386at/model_dep.c index 9dbe7e01..e0995c96 100644 --- a/i386/i386at/model_dep.c +++ b/i386/i386at/model_dep.c @@ -66,6 +66,7 @@ #include <i386/locore.h> #include <i386/model_dep.h> #include <i386/smp.h> +#include <i386/seg.h> #include <i386at/acpi_parse_apic.h> #include <i386at/autoconf.h> #include <i386at/biosmem.h> @@ -125,6 +126,9 @@ char *kernel_cmdline = ""; extern char version[]; +/* Realmode temporary GDT */ +extern struct pseudo_descriptor gdt_descr_tmp; + /* If set, reboot the system on ctrl-alt-delete. */ boolean_t rebootflag = FALSE; /* exported to kdintr */ @@ -207,6 +211,20 @@ void machine_init(void) */ pmap_unmap_page_zero(); #endif + +#ifdef APIC + /* + * Grab an early page for AP boot code + */ + /* FIXME: this may not allocate from below 1MB, if within first 16MB */ + apboot_addr = vm_page_to_pa(vm_page_grab_contig(PAGE_SIZE, VM_PAGE_SEL_DMA)); + assert (apboot_addr < 0x100000); + + /* + * Patch the realmode gdt with the correct offset + */ + gdt_descr_tmp.linear_base += apboot_addr; +#endif } /* Conserve power on processor CPU. */ |