diff options
author | Michael Brown | 2015-04-21 00:05:48 +0200 |
---|---|---|
committer | Michael Brown | 2015-04-21 00:35:11 +0200 |
commit | ac602126fafc5afe5669809ebe65bdc5a1de94e1 (patch) | |
tree | 8084edef903311458b94c7813e7e885622b15f77 | |
parent | [setup] Preserve real-mode stack during mode transition (diff) | |
download | memtest86-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.S | 2 | ||||
-rw-r--r-- | main.c | 19 | ||||
-rw-r--r-- | smp.c | 15 |
3 files changed, 17 insertions, 19 deletions
@@ -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 @@ -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 */ @@ -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 +} |