Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F137952451
D31343.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
7 KB
Referenced Files
None
Subscribers
None
D31343.diff
View Options
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
Details
Attached
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)
Attached To
Mode
D31343: amd64: stop doing special allocation for the AP startup trampoline
Attached
Detach File
Event Timeline
Log In to Comment