summaryrefslogtreecommitdiffstats
path: root/main.c
diff options
context:
space:
mode:
Diffstat (limited to 'main.c')
-rw-r--r--main.c86
1 files changed, 66 insertions, 20 deletions
diff --git a/main.c b/main.c
index d0c9289..af3e150 100644
--- a/main.c
+++ b/main.c
@@ -40,6 +40,8 @@ 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;
+extern int conservative_smp;
static int find_ticks_for_test(int test);
void find_ticks_for_pass(void);
@@ -72,6 +74,7 @@ volatile short cpu_mode;
char cpu_mask[MAX_CPUS];
long bin_mask=0xffffffff;
short onepass;
+static short onefail;
volatile short btflag = 0;
volatile int test;
short restart_flag;
@@ -179,7 +182,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, ' ');
@@ -198,11 +202,12 @@ 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! */
-static void run_at(unsigned long addr, int cpu)
+void run_at(unsigned long addr, int cpu)
{
ulong *ja = (ulong *)(addr + startup_32 - _start);
@@ -233,12 +238,10 @@ switch_to_main_stack(unsigned cpu_num)
extern uintptr_t boot_stack_top;
uintptr_t *src, *dst;
int offs;
- uint8_t * stackAddr, *stackTop;
+ uint8_t *stackTop;
- stackAddr = (uint8_t *) &stacks[cpu_num][0];
+ stackTop = (uint8_t *) &stacks[MAX_CPUS - cpu_num][0];
- stackTop = stackAddr + STACKSIZE_BYTES;
-
src = (uintptr_t*)&boot_stack_top;
dst = (uintptr_t*)stackTop;
do {
@@ -259,12 +262,15 @@ switch_to_main_stack(unsigned cpu_num)
#define OLD_CL_MAGIC_ADDR ((unsigned short*) MK_PTR(INITSEG,0x20))
#define OLD_CL_MAGIC 0xA33F
#define OLD_CL_OFFSET_ADDR ((unsigned short*) MK_PTR(INITSEG,0x22))
+#define PXE_CL_MAGIC_ADDR ((unsigned short*) MK_PTR(BOOTSEG,0x20))
+#define PXE_CL_OFFSET_ADDR ((unsigned short*) MK_PTR(BOOTSEG,0x22))
static void parse_command_line(void)
{
long simple_strtoul(char *cmd, char *ptr, int base);
char *cp, dummy;
int i, j, k;
+ unsigned short offset;
if (cmdline_parsed)
return;
@@ -274,11 +280,15 @@ static void parse_command_line(void)
cpu_mask[i] = 1;
}
- if (*OLD_CL_MAGIC_ADDR != OLD_CL_MAGIC)
+ if (*OLD_CL_MAGIC_ADDR == OLD_CL_MAGIC) {
+ offset = *OLD_CL_OFFSET_ADDR;
+ cp = MK_PTR(INITSEG, offset);
+ } else if (*PXE_CL_MAGIC_ADDR == OLD_CL_MAGIC) {
+ offset = *PXE_CL_OFFSET_ADDR;
+ cp = MK_PTR(BOOTSEG, offset);
+ } else {
return;
-
- unsigned short offset = *OLD_CL_OFFSET_ADDR;
- cp = MK_PTR(INITSEG, offset);
+ }
/* skip leading spaces */
while (*cp == ' ')
@@ -299,11 +309,21 @@ static void parse_command_line(void)
cp += 8;
maxcpus=(int)simple_strtoul(cp, &dummy, 10);
}
+ /* Allow SMP to be enabled by default */
+ if (!mt86_strncmp(cp, "smp", 3)) {
+ cp += 3;
+ conservative_smp = 0;
+ }
/* Run one pass and exit if there are no errors */
if (!mt86_strncmp(cp, "onepass", 7)) {
cp += 7;
onepass++;
}
+ /* Exit immediately on failure */
+ if (!mt86_strncmp(cp, "onefail", 7)) {
+ cp += 7;
+ onefail++;
+ }
/* Setup a list of tests to run */
if (!mt86_strncmp(cp, "tstlist=", 8)) {
cp += 8;
@@ -398,12 +418,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(); */
+ /* Reserve highest basemem page for SMP locks and bootstrap */
+ smp_page = --vv->pmap[0].end;
+ barrier_init(1);
/* Fill in the CPUID table */
get_cpuid();
/* Startup the other CPUs */
@@ -429,10 +449,6 @@ void test_start(void)
}
win1_end = (high_test_adr >> 12);
- /* Adjust the map to not test the page at 939k,
- * reserved for locks */
- vv->pmap[0].end--;
-
find_ticks_for_pass();
} else {
/* APs only, Register the APs */
@@ -523,6 +539,25 @@ void test_start(void)
btrace(my_cpu_num, __LINE__, "Start Done", 1, 0, 0);
start_seq = 2;
+ /* Exit if testing has finished */
+ if (vv->exit) {
+ paging_off();
+ set_cache(1);
+ barrier();
+ if (my_cpu_num == 0) {
+ if (vv->ecount) {
+ exit(EXIT_FAILURE);
+ } else if (vv->pass) {
+ exit(EXIT_SUCCESS);
+ } else {
+ exit(EXIT_INCOMPLETE);
+ }
+ } else {
+ /* Halt APs */
+ __asm__ __volatile__ ( "cli ; hlt" );
+ }
+ }
+
/* Loop through all tests */
while (1) {
/* If the restart flag is set all initial params */
@@ -547,6 +582,11 @@ void test_start(void)
btrace(my_cpu_num, __LINE__, "Sched_Barr", 1,window,win_next);
barrier();
+ /* Exit if testing has finished */
+ if (vv->exit) {
+ run_at(LOW_TEST_ADR, my_cpu_num);
+ }
+
/* Don't go over the 8TB PAE limit */
if (win_next > MAX_MEM_PAGES) {
break;
@@ -737,6 +777,12 @@ void test_start(void)
} //????
btrace(my_cpu_num, __LINE__, "Next_CPU ",1,cpu_sel,test);
+ /* If onefail is enabled and we have seen any errors then
+ * exit the test */
+ if (onefail && vv->ecount) {
+ vv->exit++;
+ }
+
/* If this was the last test then we finished a pass */
if (pass_flag)
{
@@ -751,8 +797,8 @@ void test_start(void)
if (vv->ecount == 0)
{
/* If onepass is enabled and we did not get any errors
- * reboot to exit the test */
- if (onepass) { reboot(); }
+ * exit the test */
+ if (onepass) { vv->exit++; }
if (!btflag)
cprint(LINE_MSG, COL_MSG-8,
"** Pass complete, no errors, press Esc to exit **");