summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Brown2015-04-21 00:05:48 +0200
committerMichael Brown2015-04-21 00:35:11 +0200
commitac602126fafc5afe5669809ebe65bdc5a1de94e1 (patch)
tree8084edef903311458b94c7813e7e885622b15f77
parent[setup] Preserve real-mode stack during mode transition (diff)
downloadmemtest86-ac602126fafc5afe5669809ebe65bdc5a1de94e1.tar.gz
memtest86-ac602126fafc5afe5669809ebe65bdc5a1de94e1.tar.xz
memtest86-ac602126fafc5afe5669809ebe65bdc5a1de94e1.zip
[smp] Use highest free base memory page for SMP structures
Use the highest free base memory page to hold the AP trampoline code and the SMP barrier structure (rather than assuming that we can place the barrier structure at 0x9ff00 and the AP trampoline code at 0x9000). Signed-off-by: Michael Brown <mcb30@ipxe.org>
-rw-r--r--head.S2
-rw-r--r--main.c19
-rw-r--r--smp.c15
3 files changed, 17 insertions, 19 deletions
diff --git a/head.S b/head.S
index d551336..e8f64a8 100644
--- a/head.S
+++ b/head.S
@@ -806,7 +806,7 @@ idt_real:
.globl _ap_trampoline_protmode
.code16
_ap_trampoline_start:
- lgdt 0x0 /* will be fixed up later, see smp.c:BootAP()*/
+ cs lgdt 0x100 /* will be filled in by boot_ap() */
movl %cr0, %eax
orl $1, %eax
movl %eax, %cr0
diff --git a/main.c b/main.c
index 75fb5e5..144fb1b 100644
--- a/main.c
+++ b/main.c
@@ -40,6 +40,7 @@ extern void rand_seed(unsigned int seed1, unsigned int seed2, int cpu);
extern struct barrier_s *barr;
extern int num_cpus;
extern int act_cpus;
+extern unsigned smp_page;
static int find_ticks_for_test(int test);
void find_ticks_for_pass(void);
@@ -177,7 +178,8 @@ void btrace(int me, int line, char *msg, int wait, long v1, long v2)
/* Is tracing turned on? */
if (btflag == 0) return;
- spin_lock(&barr->mutex);
+ if (barr)
+ spin_lock(&barr->mutex);
y = tidx%13;
x = tidx/13*40;
cplace(y+11, x+1, ' ');
@@ -196,7 +198,8 @@ void btrace(int me, int line, char *msg, int wait, long v1, long v2)
if (wait) {
wait_keyup();
}
- spin_unlock(&barr->mutex);
+ if (barr)
+ spin_unlock(&barr->mutex);
}
/* Relocate the test to a new address. Be careful to not overlap! */
@@ -407,12 +410,12 @@ void test_start(void)
smp_set_ordinal(my_cpu_num, my_cpu_ord);
parse_command_line();
clear_screen();
- /* Initialize the barrier so the lock in btrace will work.
- * Will get redone later when we know how many CPUs we have */
- barrier_init(1);
btrace(my_cpu_num, __LINE__, "Begin ", 1, 0, 0);
/* Find memory size */
- mem_size(); /* must be called before initialise_cpus(); */
+ mem_size();
+ /* Reserve highest basemem page for SMP locks and bootstrap */
+ smp_page = --v->pmap[0].end;
+ barrier_init(1);
/* Fill in the CPUID table */
get_cpuid();
/* Startup the other CPUs */
@@ -438,10 +441,6 @@ void test_start(void)
}
win1_end = (high_test_adr >> 12);
- /* Adjust the map to not test the page at 939k,
- * reserved for locks */
- v->pmap[0].end--;
-
find_ticks_for_pass();
} else {
/* APs only, Register the APs */
diff --git a/smp.c b/smp.c
index 48fbb09..e1050ce 100644
--- a/smp.c
+++ b/smp.c
@@ -27,6 +27,8 @@ extern int maxcpus;
extern char cpu_mask[];
extern struct cpu_ident cpu_id;
+unsigned smp_page;
+
struct barrier_s *barr;
void smp_find_cpus();
@@ -34,7 +36,7 @@ void smp_find_cpus();
void barrier_init(int max)
{
/* Set the adddress of the barrier structure */
- barr = (struct barrier_s *)0x9ff00;
+ barr = (struct barrier_s *)((smp_page << 12) + 0x300);
barr->lck.slock = 1;
barr->mutex.slock = 1;
barr->maxproc = max;
@@ -258,9 +260,9 @@ void kick_cpu(unsigned cpu_num)
// These memory locations are used for the trampoline code and data.
-#define BOOTCODESTART 0x9000
-#define GDTPOINTERADDR 0x9100
-#define GDTADDR 0x9110
+#define BOOTCODESTART ((smp_page << 12))
+#define GDTPOINTERADDR (BOOTCODESTART + 0x100)
+#define GDTADDR (BOOTCODESTART + 0x110)
void boot_ap(unsigned cpu_num)
{
@@ -274,9 +276,6 @@ void boot_ap(unsigned cpu_num)
memcpy((uint8_t*)BOOTCODESTART, &_ap_trampoline_start, len);
- // Fixup the LGDT instruction to point to GDT pointer.
- PUT_MEM16(BOOTCODESTART + 3, GDTPOINTERADDR);
-
// Copy a pointer to the temporary GDT to addr GDTPOINTERADDR.
// The temporary gdt is at addr GDTADDR
PUT_MEM16(GDTPOINTERADDR, 4 * 8);
@@ -689,4 +688,4 @@ int smp_ord_to_cpu(int me)
if (num_to_ord[i] == me) return i;
}
return -1;
-} \ No newline at end of file
+}