diff --git a/sys/amd64/amd64/machdep.c b/sys/amd64/amd64/machdep.c --- a/sys/amd64/amd64/machdep.c +++ b/sys/amd64/amd64/machdep.c @@ -1272,16 +1272,6 @@ (boothowto & RB_VERBOSE)) printf("Physical memory use set to %ldK\n", Maxmem * 4); - /* - * Make hole for "AP -> long mode" bootstrap code. The - * mp_bootaddress vector is only available when the kernel - * is configured to support APs and APs for the system start - * in real mode mode (e.g. SMP bare metal). - */ -#ifdef SMP - alloc_ap_trampoline(physmap, &physmap_idx); -#endif - /* call pmap initialization to make new kernel address space */ pmap_bootstrap(&first); diff --git a/sys/amd64/amd64/mp_machdep.c b/sys/amd64/amd64/mp_machdep.c --- a/sys/amd64/amd64/mp_machdep.c +++ b/sys/amd64/amd64/mp_machdep.c @@ -323,7 +323,7 @@ int start_all_aps(void) { - vm_page_t m_pml4, m_pdp, m_pd[4]; + vm_page_t m_boottramp, m_pml4, m_pdp, m_pd[4]; pml5_entry_t old_pml45; pml4_entry_t *v_pml4; pdp_entry_t *v_pdp; @@ -334,6 +334,13 @@ mtx_init(&ap_boot_mtx, "ap boot", NULL, MTX_SPIN); + MPASS(bootMP_size <= PAGE_SIZE); + m_boottramp = vm_page_alloc_contig(NULL, 0, VM_ALLOC_NORMAL | + VM_ALLOC_NOBUSY | VM_ALLOC_NOOBJ, 1, 0, + (1ULL << 20), /* Trampoline should be below 1M for real mode */ + PAGE_SIZE, 0, VM_MEMATTR_DEFAULT); + boot_address = VM_PAGE_TO_PHYS(m_boottramp); + /* Create a transient 1:1 mapping of low 4G */ if (la57) { m_pml4 = pmap_page_alloc_below_4g(true); @@ -461,6 +468,7 @@ vm_page_free(m_pd[1]); vm_page_free(m_pd[0]); vm_page_free(m_pdp); + vm_page_free(m_boottramp); /* number of APs actually started */ return (mp_naps); diff --git a/sys/i386/i386/mp_machdep.c b/sys/i386/i386/mp_machdep.c --- a/sys/i386/i386/mp_machdep.c +++ b/sys/i386/i386/mp_machdep.c @@ -147,6 +147,57 @@ static char *ap_copyout_buf; static char *ap_tramp_stack_base; + +/* Allocate memory for the AP trampoline. */ +void +alloc_ap_trampoline(vm_paddr_t *physmap, unsigned int *physmap_idx) +{ + unsigned int i; + bool allocated; + + allocated = false; + for (i = *physmap_idx; i <= *physmap_idx; i -= 2) { + /* + * Find a memory region big enough and below the 1MB boundary + * for the trampoline code. + * NB: needs to be page aligned. + */ + if (physmap[i] >= MiB(1) || + (trunc_page(physmap[i + 1]) - round_page(physmap[i])) < + round_page(bootMP_size)) + continue; + + allocated = true; + /* + * Try to steal from the end of the region to mimic previous + * behaviour, else fallback to steal from the start. + */ + if (physmap[i + 1] < MiB(1)) { + boot_address = trunc_page(physmap[i + 1]); + if ((physmap[i + 1] - boot_address) < bootMP_size) + boot_address -= round_page(bootMP_size); + physmap[i + 1] = boot_address; + } else { + boot_address = round_page(physmap[i]); + physmap[i] = boot_address + round_page(bootMP_size); + } + if (physmap[i] == physmap[i + 1] && *physmap_idx != 0) { + memmove(&physmap[i], &physmap[i + 2], + sizeof(*physmap) * (*physmap_idx - i + 2)); + *physmap_idx -= 2; + } + break; + } + + if (!allocated) { + boot_address = basemem * 1024 - bootMP_size; + if (bootverbose) + printf( +"Cannot find enough space for the boot trampoline, placing it at %#x", + boot_address); + } +} + /* * Initialize the IPI handlers and start up the AP's. */ diff --git a/sys/x86/x86/mp_x86.c b/sys/x86/x86/mp_x86.c --- a/sys/x86/x86/mp_x86.c +++ b/sys/x86/x86/mp_x86.c @@ -939,56 +939,6 @@ return (mp_ncpus > 1); } -/* Allocate memory for the AP trampoline. */ -void -alloc_ap_trampoline(vm_paddr_t *physmap, unsigned int *physmap_idx) -{ - unsigned int i; - bool allocated; - - allocated = false; - for (i = *physmap_idx; i <= *physmap_idx; i -= 2) { - /* - * Find a memory region big enough and below the 1MB boundary - * for the trampoline code. - * NB: needs to be page aligned. - */ - if (physmap[i] >= MiB(1) || - (trunc_page(physmap[i + 1]) - round_page(physmap[i])) < - round_page(bootMP_size)) - continue; - - allocated = true; - /* - * Try to steal from the end of the region to mimic previous - * behaviour, else fallback to steal from the start. - */ - if (physmap[i + 1] < MiB(1)) { - boot_address = trunc_page(physmap[i + 1]); - if ((physmap[i + 1] - boot_address) < bootMP_size) - boot_address -= round_page(bootMP_size); - physmap[i + 1] = boot_address; - } else { - boot_address = round_page(physmap[i]); - physmap[i] = boot_address + round_page(bootMP_size); - } - if (physmap[i] == physmap[i + 1] && *physmap_idx != 0) { - memmove(&physmap[i], &physmap[i + 2], - sizeof(*physmap) * (*physmap_idx - i + 2)); - *physmap_idx -= 2; - } - break; - } - - if (!allocated) { - boot_address = basemem * 1024 - bootMP_size; - if (bootverbose) - printf( -"Cannot find enough space for the boot trampoline, placing it at %#x", - boot_address); - } -} - /* * AP CPU's call this to initialize themselves. */