Page MenuHomeFreeBSD

D31343.diff
No OneTemporary

D31343.diff

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
@@ -112,7 +112,7 @@
* Local data and functions.
*/
-static int start_ap(int apic_id);
+static int start_ap(int apic_id, vm_paddr_t boot_address);
/*
* Initialize the IPI handlers and start up the AP's.
@@ -322,17 +322,25 @@
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;
pd_entry_t *v_pd;
+ vm_paddr_t boot_address;
u_int32_t mpbioswarmvec;
int apic_id, cpu, domain, i;
u_char mpbiosreason;
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);
@@ -382,7 +390,7 @@
/* copy the AP 1st level boot code */
bcopy(mptramp_start, (void *)PHYS_TO_DMAP(boot_address), bootMP_size);
if (bootverbose)
- printf("AP boot address %#x\n", boot_address);
+ printf("AP boot address %#lx\n", boot_address);
/* save the current value of the warm-start vector */
if (!efi_boot)
@@ -436,7 +444,7 @@
bootAP = cpu;
/* attempt to start the Application Processor */
- if (!start_ap(apic_id)) {
+ if (!start_ap(apic_id, boot_address)) {
/* restore the warmstart vector */
*(u_int32_t *) WARMBOOT_OFF = mpbioswarmvec;
panic("AP #%d (PHY# %d) failed!", cpu, apic_id);
@@ -461,6 +469,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);
@@ -474,7 +483,7 @@
* but it seems to work.
*/
static int
-start_ap(int apic_id)
+start_ap(int apic_id, vm_paddr_t boot_address)
{
int vector, ms;
int cpus;
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,61 @@
static char *ap_copyout_buf;
static char *ap_tramp_stack_base;
+
+unsigned int boot_address;
+
+#define MiB(v) (v ## ULL << 20)
+
+/* 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/include/x86_smp.h b/sys/x86/include/x86_smp.h
--- a/sys/x86/include/x86_smp.h
+++ b/sys/x86/include/x86_smp.h
@@ -23,6 +23,10 @@
struct pmap;
+#ifdef __i386__
+extern unsigned int boot_address;
+#endif
+
/* global data in mp_x86.c */
extern int mp_naps;
extern int boot_cpu_id;
@@ -32,7 +36,6 @@
extern void *dpcpu;
extern char *bootSTK;
extern void *bootstacks[];
-extern unsigned int boot_address;
extern unsigned int bootMP_size;
extern volatile int aps_ready;
extern struct mtx ap_boot_mtx;
@@ -84,12 +87,15 @@
typedef void (*smp_invl_cb_t)(struct pmap *, vm_offset_t addr1,
vm_offset_t addr2);
+#ifdef __i386__
+void alloc_ap_trampoline(vm_paddr_t *physmap, unsigned int *physmap_idx);
+#endif
+
/* functions in x86_mp.c */
void assign_cpu_ids(void);
void cpu_add(u_int apic_id, char boot_cpu);
void cpustop_handler(void);
void cpususpend_handler(void);
-void alloc_ap_trampoline(vm_paddr_t *physmap, unsigned int *physmap_idx);
void init_secondary_tail(void);
void init_secondary(void);
void ipi_startup(int apic_id, int vector);
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
@@ -168,14 +168,10 @@
int present;
} static caches[MAX_CACHE_LEVELS];
-unsigned int boot_address;
-
static bool stop_mwait = false;
SYSCTL_BOOL(_machdep, OID_AUTO, stop_mwait, CTLFLAG_RWTUN, &stop_mwait, 0,
"Use MONITOR/MWAIT when stopping CPU, if available");
-#define MiB(v) (v ## ULL << 20)
-
void
mem_range_AP_init(void)
{
@@ -939,56 +935,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.
*/

File Metadata

Mime Type
text/plain
Expires
Fri, Nov 28, 3:27 PM (17 h, 1 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
26287048
Default Alt Text
D31343.diff (7 KB)

Event Timeline