mirror of
https://github.com/memtest86plus/memtest86plus.git
synced 2026-08-26 13:17:12 -05:00
Remove distinction between physical and virtual CPUs.
This is no longer needed, now we can display as many CPUs as we can physically handle.
This commit is contained in:
+17
-17
@@ -87,7 +87,7 @@ cpu_mode_t cpu_mode = PAR;
|
||||
|
||||
error_mode_t error_mode = ERROR_MODE_NONE;
|
||||
|
||||
cpu_state_t pcpu_state[MAX_PCPUS];
|
||||
cpu_state_t cpu_state[MAX_CPUS];
|
||||
|
||||
bool enable_temperature = false;
|
||||
bool enable_trace = false;
|
||||
@@ -508,8 +508,8 @@ static void error_mode_menu(void)
|
||||
static bool set_all_cpus(cpu_state_t state, int display_offset)
|
||||
{
|
||||
clear_popup_row(POP_R+16);
|
||||
for (int i = 1; i < num_pcpus; i++) {
|
||||
pcpu_state[i] = state;
|
||||
for (int i = 1; i < num_available_cpus; i++) {
|
||||
cpu_state[i] = state;
|
||||
display_enabled(POP_R+12, i - display_offset, state == CPU_STATE_ENABLED);
|
||||
}
|
||||
return true;
|
||||
@@ -520,11 +520,11 @@ static bool add_or_remove_cpu(bool add, int display_offset)
|
||||
|
||||
display_input_message(POP_R+16, "Enter CPU #");
|
||||
int n = read_value(POP_R+16, POP_LM+11, 2, 0);
|
||||
if (n < 1 || n >= num_pcpus) {
|
||||
if (n < 1 || n >= num_available_cpus) {
|
||||
display_error_message(POP_R+16, "Invalid CPU number");
|
||||
return false;
|
||||
}
|
||||
pcpu_state[n] = add ? CPU_STATE_ENABLED : CPU_STATE_DISABLED;
|
||||
cpu_state[n] = add ? CPU_STATE_ENABLED : CPU_STATE_DISABLED;
|
||||
display_enabled(POP_R+12, n - display_offset, add);
|
||||
clear_popup_row(POP_R+16);
|
||||
return true;
|
||||
@@ -534,18 +534,18 @@ static bool add_cpu_range(int display_offset)
|
||||
{
|
||||
display_input_message(POP_R+16, "Enter first CPU #");
|
||||
int n1 = read_value(POP_R+16, POP_LM+17, 2, 0);
|
||||
if (n1 < 1 || n1 >= num_pcpus) {
|
||||
if (n1 < 1 || n1 >= num_available_cpus) {
|
||||
display_error_message(POP_R+16, "Invalid CPU number");
|
||||
return false;
|
||||
}
|
||||
display_input_message(POP_R+16, "Enter last CPU #");
|
||||
int n2 = read_value(POP_R+16, POP_LM+16, 2, 0);
|
||||
if (n2 < n1 || n2 >= num_pcpus) {
|
||||
if (n2 < n1 || n2 >= num_available_cpus) {
|
||||
display_error_message(POP_R+16, "Invalid CPU range");
|
||||
return false;
|
||||
}
|
||||
for (int i = n1; i <= n2; i++) {
|
||||
pcpu_state[i] = CPU_STATE_ENABLED;
|
||||
cpu_state[i] = CPU_STATE_ENABLED;
|
||||
display_enabled(POP_R+12, i - display_offset, true);
|
||||
}
|
||||
clear_popup_row(POP_R+16);
|
||||
@@ -555,12 +555,12 @@ static bool add_cpu_range(int display_offset)
|
||||
static void display_cpu_selection(int display_offset)
|
||||
{
|
||||
clear_screen_region(POP_R+11, POP_C, POP_LAST_R, POP_LAST_C);
|
||||
display_selection_header(POP_R+10, num_pcpus - 1, display_offset);
|
||||
display_selection_header(POP_R+10, num_available_cpus - 1, display_offset);
|
||||
if (display_offset == 0) {
|
||||
printc(POP_R+12, POP_LM, 'B');
|
||||
}
|
||||
for (int i = 1; i < num_pcpus; i++) {
|
||||
display_enabled(POP_R+12, i - display_offset, pcpu_state[i] == CPU_STATE_ENABLED);
|
||||
for (int i = 1; i < num_available_cpus; i++) {
|
||||
display_enabled(POP_R+12, i - display_offset, cpu_state[i] == CPU_STATE_ENABLED);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -605,7 +605,7 @@ static void cpu_selection_menu(void)
|
||||
}
|
||||
break;
|
||||
case 'd':
|
||||
if (display_offset < (num_pcpus - SEL_AREA)) {
|
||||
if (display_offset < (num_available_cpus - SEL_AREA)) {
|
||||
display_offset += SEL_W;
|
||||
display_cpu_selection(display_offset);
|
||||
}
|
||||
@@ -641,8 +641,8 @@ void config_init(void)
|
||||
|
||||
error_mode = ERROR_MODE_ADDRESS;
|
||||
|
||||
for (int i = 0; i < MAX_PCPUS; i++) {
|
||||
pcpu_state[i] = CPU_STATE_ENABLED;
|
||||
for (int i = 0; i < MAX_CPUS; i++) {
|
||||
cpu_state[i] = CPU_STATE_ENABLED;
|
||||
}
|
||||
|
||||
enable_temperature = !no_temperature;
|
||||
@@ -673,9 +673,9 @@ void config_menu(bool initial)
|
||||
prints(POP_R+5, POP_LI, "<F3> CPU sequencing mode");
|
||||
prints(POP_R+6, POP_LI, "<F4> Error reporting mode");
|
||||
if (initial) {
|
||||
if (num_pcpus < 2) set_foreground_colour(BOLD+BLACK);
|
||||
if (num_available_cpus < 2) set_foreground_colour(BOLD+BLACK);
|
||||
prints(POP_R+7, POP_LI, "<F5> CPU selection");
|
||||
if (num_pcpus < 2) set_foreground_colour(WHITE);
|
||||
if (num_available_cpus < 2) set_foreground_colour(WHITE);
|
||||
if (no_temperature) set_foreground_colour(BOLD+BLACK);
|
||||
printf(POP_R+8, POP_LI, "<F6> Temperature %s", enable_temperature ? "disable" : "enable ");
|
||||
if (no_temperature) set_foreground_colour(WHITE);
|
||||
@@ -701,7 +701,7 @@ void config_menu(bool initial)
|
||||
break;
|
||||
case '5':
|
||||
if (initial) {
|
||||
if (num_pcpus > 1) {
|
||||
if (num_available_cpus > 1) {
|
||||
cpu_selection_menu();
|
||||
}
|
||||
} else {
|
||||
|
||||
+2
-2
@@ -4,7 +4,7 @@
|
||||
/*
|
||||
* Provides the configuration settings and pop-up menu.
|
||||
*
|
||||
* Copyright (C) 2020-2021 Martin Whitaker.
|
||||
* Copyright (C) 2020-2022 Martin Whitaker.
|
||||
*/
|
||||
|
||||
#include <stdbool.h>
|
||||
@@ -34,7 +34,7 @@ extern cpu_mode_t cpu_mode;
|
||||
|
||||
extern error_mode_t error_mode;
|
||||
|
||||
extern cpu_state_t pcpu_state[MAX_PCPUS];
|
||||
extern cpu_state_t cpu_state[MAX_CPUS];
|
||||
|
||||
extern bool enable_temperature;
|
||||
extern bool enable_trace;
|
||||
|
||||
+3
-3
@@ -229,17 +229,17 @@ void scroll(void)
|
||||
}
|
||||
}
|
||||
|
||||
void do_tick(int my_vcpu)
|
||||
void do_tick(int my_cpu)
|
||||
{
|
||||
barrier_wait(run_barrier);
|
||||
if (master_vcpu == my_vcpu) {
|
||||
if (master_cpu == my_cpu) {
|
||||
check_input();
|
||||
error_update();
|
||||
}
|
||||
barrier_wait(run_barrier);
|
||||
|
||||
// Only the master CPU does the update.
|
||||
if (master_vcpu != my_vcpu) {
|
||||
if (master_cpu != my_cpu) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
+4
-4
@@ -59,9 +59,9 @@
|
||||
#define display_cpu_mode(str) \
|
||||
prints(8, 11, str)
|
||||
|
||||
#define display_active_cpu(pcpu_num) \
|
||||
#define display_active_cpu(cpu_num) \
|
||||
prints(8, 25, "core #"); \
|
||||
printi(8, 31, pcpu_num, 3, false, true)
|
||||
printi(8, 31, cpu_num, 3, false, true)
|
||||
|
||||
#define display_all_active \
|
||||
prints(8, 25, "all cores")
|
||||
@@ -188,8 +188,8 @@ void toggle_scroll_lock(void);
|
||||
|
||||
void scroll(void);
|
||||
|
||||
void do_tick(int my_vcpu);
|
||||
void do_tick(int my_cpu);
|
||||
|
||||
void do_trace(int my_vcpu, const char *fmt, ...);
|
||||
void do_trace(int my_cpu, const char *fmt, ...);
|
||||
|
||||
#endif // DISPLAY_H
|
||||
|
||||
+3
-3
@@ -1,5 +1,5 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
// Copyright (C) 2020 Martin Whitaker.
|
||||
// Copyright (C) 2020-2022 Martin Whitaker.
|
||||
//
|
||||
// Derived from memtest86+ error.c
|
||||
//
|
||||
@@ -268,7 +268,7 @@ static void common_err(error_type_t type, uintptr_t addr, testword_t good, testw
|
||||
|
||||
set_foreground_colour(YELLOW);
|
||||
display_scrolled_message(0, " %2i %4i %2i %09x%03x (%kB)",
|
||||
smp_my_pcpu_num(), pass_num, test_num, page, offset, page << 2);
|
||||
smp_my_cpu_num(), pass_num, test_num, page, offset, page << 2);
|
||||
if (type == PARITY_ERROR) {
|
||||
display_scrolled_message(41, "%s", "Parity error detected near this address");
|
||||
} else {
|
||||
@@ -349,7 +349,7 @@ void parity_error(void)
|
||||
{
|
||||
// We don't know the real address that caused the parity error,
|
||||
// so use the last recorded test address.
|
||||
common_err(PARITY_ERROR, test_addr[my_vcpu_num()], 0, 0, false);
|
||||
common_err(PARITY_ERROR, test_addr[my_cpu_num()], 0, 0, false);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
// Copyright (C) 2020 Martin Whitaker.
|
||||
// Copyright (C) 2020-2022 Martin Whitaker.
|
||||
//
|
||||
// Derived from extract of memtest86+ lib.c:
|
||||
//
|
||||
@@ -119,7 +119,7 @@ void interrupt(struct trap_regs *trap_regs)
|
||||
|
||||
clear_message_area();
|
||||
|
||||
display_pinned_message(0, 0, "Unexpected interrupt on CPU %i", smp_my_pcpu_num());
|
||||
display_pinned_message(0, 0, "Unexpected interrupt on CPU %i", smp_my_cpu_num());
|
||||
if (trap_regs->vect <= 19) {
|
||||
display_pinned_message(2, 0, "Type: %s", codes[trap_regs->vect]);
|
||||
} else {
|
||||
|
||||
+46
-49
@@ -62,11 +62,11 @@
|
||||
|
||||
static volatile int init_state = 0;
|
||||
|
||||
static int num_enabled_cpus = 1;
|
||||
|
||||
static barrier_t *start_barrier = NULL;
|
||||
static spinlock_t *start_mutex = NULL;
|
||||
|
||||
static int8_t pcpu_num_to_vcpu_num[MAX_PCPUS];
|
||||
|
||||
static volatile bool start_run = false;
|
||||
static volatile bool start_pass = false;
|
||||
static volatile bool start_test = false;
|
||||
@@ -86,9 +86,9 @@ static volatile int test_stage = 0;
|
||||
|
||||
// These are exposed in test.h.
|
||||
|
||||
int num_vcpus = 1;
|
||||
volatile int num_active_cpus = 1;
|
||||
|
||||
volatile int master_vcpu = 0;
|
||||
volatile int master_cpu = 0;
|
||||
|
||||
barrier_t *run_barrier = NULL;
|
||||
|
||||
@@ -103,7 +103,7 @@ volatile int test_num = 0;
|
||||
volatile bool restart = false;
|
||||
volatile bool bail = false;
|
||||
|
||||
volatile uintptr_t test_addr[MAX_VCPUS];
|
||||
volatile uintptr_t test_addr[MAX_CPUS];
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Private Functions
|
||||
@@ -112,16 +112,16 @@ volatile uintptr_t test_addr[MAX_VCPUS];
|
||||
#define BARRIER(enabled) \
|
||||
if (enabled) { \
|
||||
if (TRACE_BARRIERS) { \
|
||||
trace(my_pcpu, "Start barrier wait at %s line %i", __FILE__, __LINE__); \
|
||||
trace(my_cpu, "Start barrier wait at %s line %i", __FILE__, __LINE__); \
|
||||
} \
|
||||
barrier_wait(start_barrier); \
|
||||
}
|
||||
|
||||
static void run_at(uintptr_t addr, int my_pcpu)
|
||||
static void run_at(uintptr_t addr, int my_cpu)
|
||||
{
|
||||
uintptr_t *new_start_addr = (uintptr_t *)(addr + startup - _start);
|
||||
|
||||
if (my_pcpu == 0) {
|
||||
if (my_cpu == 0) {
|
||||
memmove((void *)addr, &_start, _end - _start);
|
||||
}
|
||||
BARRIER(true);
|
||||
@@ -164,18 +164,17 @@ static void global_init(void)
|
||||
|
||||
clear_message_area();
|
||||
|
||||
display_available_cpus(num_pcpus);
|
||||
display_available_cpus(num_available_cpus);
|
||||
|
||||
num_vcpus = 0;
|
||||
for (int i = 0; i < num_pcpus; i++) {
|
||||
if (pcpu_state[i] == CPU_STATE_ENABLED) {
|
||||
pcpu_num_to_vcpu_num[i] = num_vcpus;
|
||||
num_vcpus++;
|
||||
num_enabled_cpus = 0;
|
||||
for (int i = 0; i < num_available_cpus; i++) {
|
||||
if (cpu_state[i] == CPU_STATE_ENABLED) {
|
||||
num_enabled_cpus++;
|
||||
}
|
||||
}
|
||||
display_enabled_cpus(num_vcpus);
|
||||
display_enabled_cpus(num_enabled_cpus);
|
||||
|
||||
master_vcpu = 0;
|
||||
master_cpu = 0;
|
||||
|
||||
if (enable_temperature) {
|
||||
int temp = get_cpu_temperature();
|
||||
@@ -199,13 +198,13 @@ static void global_init(void)
|
||||
trace(0, "ACPI RSDP found in %s at %0*x", rsdp_source, 2*sizeof(uintptr_t), rsdp_addr);
|
||||
}
|
||||
|
||||
start_barrier = smp_alloc_barrier(num_vcpus);
|
||||
run_barrier = smp_alloc_barrier(num_vcpus);
|
||||
start_barrier = smp_alloc_barrier(num_enabled_cpus);
|
||||
run_barrier = smp_alloc_barrier(num_enabled_cpus);
|
||||
|
||||
start_mutex = smp_alloc_mutex();
|
||||
error_mutex = smp_alloc_mutex();
|
||||
|
||||
int failed = smp_start(pcpu_state);
|
||||
int failed = smp_start(cpu_state);
|
||||
if (failed) {
|
||||
const char *message = "Failed to start CPU core %i. Press any key to reboot...";
|
||||
display_notice_with_args(strlen(message), message, failed);
|
||||
@@ -253,22 +252,22 @@ static void setup_vm_map(uintptr_t win_start, uintptr_t win_end)
|
||||
}
|
||||
}
|
||||
|
||||
static void test_all_windows(int my_pcpu, int my_vcpu)
|
||||
static void test_all_windows(int my_cpu)
|
||||
{
|
||||
int active_cpus = 1;
|
||||
bool i_am_master = (my_vcpu == master_vcpu) || dummy_run;
|
||||
num_active_cpus = 1;
|
||||
bool i_am_master = (my_cpu == master_cpu) || dummy_run;
|
||||
bool i_am_active = i_am_master;
|
||||
if (!dummy_run) {
|
||||
if (cpu_mode == PAR && test_list[test_num].cpu_mode == PAR) {
|
||||
active_cpus = num_vcpus;
|
||||
num_active_cpus = num_enabled_cpus;
|
||||
i_am_active = true;
|
||||
}
|
||||
}
|
||||
if (i_am_master) {
|
||||
barrier_init(run_barrier, active_cpus);
|
||||
barrier_init(run_barrier, num_active_cpus);
|
||||
if (!dummy_run) {
|
||||
if (active_cpus == 1) {
|
||||
display_active_cpu(my_pcpu);
|
||||
if (num_active_cpus == 1) {
|
||||
display_active_cpu(my_cpu);
|
||||
} else {
|
||||
display_all_active;
|
||||
}
|
||||
@@ -304,16 +303,16 @@ static void test_all_windows(int my_pcpu, int my_vcpu)
|
||||
// Relocate if necessary.
|
||||
if (window_num > 0) {
|
||||
if (!dummy_run && (uintptr_t)&_start != LOW_LOAD_ADDR) {
|
||||
run_at(LOW_LOAD_ADDR, my_pcpu);
|
||||
run_at(LOW_LOAD_ADDR, my_cpu);
|
||||
}
|
||||
} else {
|
||||
if (!dummy_run && (uintptr_t)&_start != HIGH_LOAD_ADDR) {
|
||||
run_at(HIGH_LOAD_ADDR, my_pcpu);
|
||||
run_at(HIGH_LOAD_ADDR, my_cpu);
|
||||
}
|
||||
}
|
||||
|
||||
if (i_am_master) {
|
||||
trace(my_vcpu, "start window %i", window_num);
|
||||
trace(my_cpu, "start window %i", window_num);
|
||||
switch (window_num) {
|
||||
case 0:
|
||||
window_start = 0;
|
||||
@@ -352,7 +351,7 @@ static void test_all_windows(int my_pcpu, int my_vcpu)
|
||||
// Either there is no PAE or we are at the PAE limit.
|
||||
break;
|
||||
}
|
||||
run_test(my_vcpu, test_num, test_stage, iterations);
|
||||
run_test(my_cpu, test_num, test_stage, iterations);
|
||||
}
|
||||
|
||||
if (i_am_master) {
|
||||
@@ -369,42 +368,40 @@ static void test_all_windows(int my_pcpu, int my_vcpu)
|
||||
|
||||
void main(void)
|
||||
{
|
||||
int my_pcpu;
|
||||
int my_cpu;
|
||||
if (init_state == 0) {
|
||||
// If this is the first time here, we must be CPU 0, as the APs haven't been started yet.
|
||||
my_pcpu = 0;
|
||||
my_cpu = 0;
|
||||
} else {
|
||||
my_pcpu = smp_my_pcpu_num();
|
||||
my_cpu = smp_my_cpu_num();
|
||||
}
|
||||
|
||||
if (init_state < 2) {
|
||||
// Global initialisation is done by the boot CPU.
|
||||
if (my_pcpu == 0) {
|
||||
if (my_cpu == 0) {
|
||||
init_state = 1;
|
||||
global_init();
|
||||
} else {
|
||||
pcpu_state[my_pcpu] = CPU_STATE_RUNNING;
|
||||
cpu_state[my_cpu] = CPU_STATE_RUNNING;
|
||||
}
|
||||
}
|
||||
BARRIER(true);
|
||||
init_state = 2;
|
||||
|
||||
#if TEST_INTERRUPT
|
||||
if (my_pcpu == 0) {
|
||||
if (my_cpu == 0) {
|
||||
__asm__ __volatile__ ("int $1");
|
||||
}
|
||||
#endif
|
||||
|
||||
int my_vcpu = pcpu_num_to_vcpu_num[my_pcpu];
|
||||
|
||||
// Due to the need to relocate ourselves in the middle of tests, the following
|
||||
// code cannot be written in the natural way as a set of nested loops. So we
|
||||
// have a single loop and use global state variables to allow us to restart
|
||||
// where we left off after each relocation.
|
||||
|
||||
while (1) {
|
||||
BARRIER((my_vcpu != 0) || !dummy_run);
|
||||
if (my_vcpu == 0) {
|
||||
BARRIER((my_cpu != 0) || !dummy_run);
|
||||
if (my_cpu == 0) {
|
||||
if (start_run) {
|
||||
pass_num = 0;
|
||||
start_pass = true;
|
||||
@@ -424,7 +421,7 @@ void main(void)
|
||||
}
|
||||
}
|
||||
if (start_test) {
|
||||
trace(my_vcpu, "start test %i", test_num);
|
||||
trace(my_cpu, "start test %i", test_num);
|
||||
test_stage = 0;
|
||||
rerun_test = true;
|
||||
if (dummy_run) {
|
||||
@@ -446,17 +443,17 @@ void main(void)
|
||||
}
|
||||
BARRIER(!dummy_run);
|
||||
if (test_list[test_num].enabled) {
|
||||
test_all_windows(my_pcpu, my_vcpu);
|
||||
test_all_windows(my_cpu);
|
||||
}
|
||||
BARRIER(!dummy_run);
|
||||
if (my_vcpu != 0) {
|
||||
if (my_cpu != 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
check_input();
|
||||
if (restart) {
|
||||
// The configuration has been changed.
|
||||
master_vcpu = 0;
|
||||
master_cpu = 0;
|
||||
start_run = true;
|
||||
dummy_run = true;
|
||||
restart = false;
|
||||
@@ -474,19 +471,19 @@ void main(void)
|
||||
switch (cpu_mode) {
|
||||
case PAR:
|
||||
if (test_list[test_num].cpu_mode == SEQ) {
|
||||
master_vcpu = (master_vcpu + 1) % num_vcpus;
|
||||
if (master_vcpu != 0) {
|
||||
master_cpu = (master_cpu + 1) % num_enabled_cpus;
|
||||
if (master_cpu != 0) {
|
||||
rerun_test = true;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case ONE:
|
||||
master_vcpu = (master_vcpu + 1) % num_vcpus;
|
||||
master_cpu = (master_cpu + 1) % num_enabled_cpus;
|
||||
break;
|
||||
case SEQ:
|
||||
master_vcpu = (master_vcpu + 1) % num_vcpus;
|
||||
if (master_vcpu != 0) {
|
||||
master_cpu = (master_cpu + 1) % num_enabled_cpus;
|
||||
if (master_cpu != 0) {
|
||||
rerun_test = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
+7
-12
@@ -4,32 +4,27 @@
|
||||
/*
|
||||
* Provides types and variables used when performing the memory tests.
|
||||
*
|
||||
* Copyright (C) 2020-2021 Martin Whitaker.
|
||||
* Copyright (C) 2020-2022 Martin Whitaker.
|
||||
*/
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "pmem.h"
|
||||
#include "smp.h"
|
||||
|
||||
#include "barrier.h"
|
||||
#include "spinlock.h"
|
||||
|
||||
/*
|
||||
* The maximum number of virtual CPUs supported. Note that the display can
|
||||
* only show the state of a maximum of 32 vCPUs.
|
||||
* The number of CPU cores being used for the current test.
|
||||
*/
|
||||
#define MAX_VCPUS 32
|
||||
extern volatile int num_active_cpus;
|
||||
|
||||
/*
|
||||
* The number of activated virtual CPUs.
|
||||
* The current master CPU.
|
||||
*/
|
||||
extern int num_vcpus;
|
||||
|
||||
/*
|
||||
* The current master virtual CPU.
|
||||
*/
|
||||
extern volatile int master_vcpu;
|
||||
extern volatile int master_cpu;
|
||||
|
||||
/*
|
||||
* A barrier used when running tests.
|
||||
@@ -100,6 +95,6 @@ extern volatile bool bail;
|
||||
/*
|
||||
* The base address of the block of memory currently being tested.
|
||||
*/
|
||||
extern volatile uintptr_t test_addr[MAX_VCPUS];
|
||||
extern volatile uintptr_t test_addr[MAX_CPUS];
|
||||
|
||||
#endif // TEST_H
|
||||
|
||||
+1
-1
@@ -101,7 +101,7 @@ startup:
|
||||
# Pick the correct stack. The stacks are allocated immediately
|
||||
# after the end of the loaded program, BSP first, then APs.
|
||||
|
||||
call smp_my_pcpu_num
|
||||
call smp_my_cpu_num
|
||||
movl $AP_STACK_SIZE, %edx
|
||||
mul %edx
|
||||
addl $BSP_STACK_SIZE, %eax
|
||||
|
||||
+1
-1
@@ -153,7 +153,7 @@ startup:
|
||||
# after the end of the loaded program, BSP first, then APs.
|
||||
|
||||
xorq %rax, %rax
|
||||
call smp_my_pcpu_num
|
||||
call smp_my_cpu_num
|
||||
movl $AP_STACK_SIZE, %edx
|
||||
mul %edx
|
||||
addq $BSP_STACK_SIZE, %rax
|
||||
|
||||
+4
-4
@@ -1,5 +1,5 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
// Copyright (C) 2020 Martin Whitaker.
|
||||
// Copyright (C) 2020-2022 Martin Whitaker.
|
||||
//
|
||||
// Derived from memtest86+ cpuid.h
|
||||
// (original contained no copyright statement)
|
||||
@@ -25,7 +25,7 @@ void cpuid_init(void)
|
||||
|
||||
// Get the max standard cpuid & vendor ID.
|
||||
cpuid(0x0, 0,
|
||||
&cpuid_info.max_vcpuid,
|
||||
&cpuid_info.max_cpuid,
|
||||
&cpuid_info.vendor_id.raw[0],
|
||||
&cpuid_info.vendor_id.raw[2],
|
||||
&cpuid_info.vendor_id.raw[1]
|
||||
@@ -33,7 +33,7 @@ void cpuid_init(void)
|
||||
cpuid_info.vendor_id.str[CPUID_VENDOR_STR_LENGTH - 1] = '\0';
|
||||
|
||||
// Get the processor family information & feature flags.
|
||||
if (cpuid_info.max_vcpuid >= 1) {
|
||||
if (cpuid_info.max_cpuid >= 1) {
|
||||
cpuid(0x1, 0,
|
||||
&cpuid_info.version.raw,
|
||||
&cpuid_info.proc_info.raw,
|
||||
@@ -43,7 +43,7 @@ void cpuid_init(void)
|
||||
}
|
||||
|
||||
// Get the digital thermal sensor & power management status bits.
|
||||
if (cpuid_info.max_vcpuid >= 6) {
|
||||
if (cpuid_info.max_cpuid >= 6) {
|
||||
cpuid(0x6, 0,
|
||||
&cpuid_info.dts_pmp,
|
||||
&dummy[0],
|
||||
|
||||
+2
-2
@@ -4,7 +4,7 @@
|
||||
/*
|
||||
* Provides access to the CPUID information.
|
||||
*
|
||||
* Copyright (C) 2020 Martin Whitaker.
|
||||
* Copyright (C) 2020-2022 Martin Whitaker.
|
||||
*
|
||||
* Derived from memtest86+ cpuid.h
|
||||
* (original contained no copyright statement)
|
||||
@@ -129,7 +129,7 @@ typedef union {
|
||||
} cpuid_custom_features;
|
||||
|
||||
typedef struct {
|
||||
uint32_t max_vcpuid;
|
||||
uint32_t max_cpuid;
|
||||
uint32_t max_xcpuid;
|
||||
uint32_t dts_pmp;
|
||||
cpuid_version_t version;
|
||||
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
// Copyright (C) 2020 Martin Whitaker.
|
||||
// Copyright (C) 2020-2022 Martin Whitaker.
|
||||
//
|
||||
// Derived from an extract of memtest86+ init.c:
|
||||
//
|
||||
@@ -65,7 +65,7 @@ static void determine_cache_size()
|
||||
l3_cache = 0;
|
||||
|
||||
// Use CPUID(4) if it is available.
|
||||
if (cpuid_info.max_vcpuid > 3) {
|
||||
if (cpuid_info.max_cpuid > 3) {
|
||||
cpuid4_eax_t eax;
|
||||
cpuid4_ebx_t ebx;
|
||||
cpuid4_ecx_t ecx;
|
||||
|
||||
+36
-36
@@ -236,9 +236,9 @@ static const efi_guid_t EFI_ACPI_2_RDSP_GUID = { 0x8868e871, 0xe4f1, 0x11d3, {0x
|
||||
|
||||
static volatile apic_register_t *apic = NULL;
|
||||
|
||||
static int8_t apic_id_to_pcpu_num[MAX_APIC_IDS];
|
||||
static int8_t apic_id_to_cpu_num[MAX_APIC_IDS];
|
||||
|
||||
static uint8_t pcpu_num_to_apic_id[MAX_PCPUS];
|
||||
static uint8_t cpu_num_to_apic_id[MAX_CPUS];
|
||||
|
||||
static uintptr_t smp_heap_page = 0;
|
||||
|
||||
@@ -248,7 +248,7 @@ static uintptr_t alloc_addr = 0;
|
||||
// Variables
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
int num_pcpus = 1; // There is always at least one CPU, the BSP
|
||||
int num_available_cpus = 1; // There is always at least one CPU, the BSP
|
||||
|
||||
const char *rsdp_source = "";
|
||||
|
||||
@@ -345,15 +345,15 @@ static bool read_mp_config_table(uintptr_t addr)
|
||||
|
||||
if (entry->cpu_flag & CPU_BOOTPROCESSOR) {
|
||||
// BSP is CPU 0
|
||||
pcpu_num_to_apic_id[0] = entry->apic_id;
|
||||
} else if (num_pcpus < MAX_PCPUS) {
|
||||
pcpu_num_to_apic_id[num_pcpus] = entry->apic_id;
|
||||
num_pcpus++;
|
||||
cpu_num_to_apic_id[0] = entry->apic_id;
|
||||
} else if (num_available_cpus < MAX_CPUS) {
|
||||
cpu_num_to_apic_id[num_available_cpus] = entry->apic_id;
|
||||
num_available_cpus++;
|
||||
}
|
||||
|
||||
// we cannot handle non-local 82489DX apics
|
||||
if ((entry->apic_ver & 0xf0) != 0x10) {
|
||||
num_pcpus = 1; // reset to initial value
|
||||
num_available_cpus = 1; // reset to initial value
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -375,7 +375,7 @@ static bool read_mp_config_table(uintptr_t addr)
|
||||
tab_entry_ptr += sizeof(mp_local_interrupt_entry_t);
|
||||
break;
|
||||
default:
|
||||
num_pcpus = 1; // reset to initial value
|
||||
num_available_cpus = 1; // reset to initial value
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -407,9 +407,9 @@ static bool find_cpus_in_floating_mp_struct(void)
|
||||
if (fp->feature[0] > 0 && fp->feature[0] <= 7) {
|
||||
// This is a default config, so plug in the numbers.
|
||||
apic = (volatile apic_register_t *)0xFEE00000;
|
||||
pcpu_num_to_apic_id[0] = 0;
|
||||
pcpu_num_to_apic_id[1] = 1;
|
||||
num_pcpus = 2;
|
||||
cpu_num_to_apic_id[0] = 0;
|
||||
cpu_num_to_apic_id[1] = 1;
|
||||
num_available_cpus = 2;
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -459,11 +459,11 @@ static bool parse_madt(void *addr)
|
||||
madt_processor_entry_t *entry = (madt_processor_entry_t *)tab_entry_ptr;
|
||||
if (entry->type == MP_PROCESSOR) {
|
||||
if (entry->flags & (MADT_PF_ENABLED|MADT_PF_ONLINE_CAPABLE)) {
|
||||
if (num_pcpus < MAX_PCPUS) {
|
||||
pcpu_num_to_apic_id[found_cpus] = entry->apic_id;
|
||||
if (num_available_cpus < MAX_CPUS) {
|
||||
cpu_num_to_apic_id[found_cpus] = entry->apic_id;
|
||||
// The first CPU is the BSP, don't increment.
|
||||
if (found_cpus > 0) {
|
||||
num_pcpus++;
|
||||
num_available_cpus++;
|
||||
}
|
||||
}
|
||||
found_cpus++;
|
||||
@@ -611,11 +611,11 @@ static bool find_cpus_in_rsdp(void)
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool start_cpu(int pcpu_num)
|
||||
static bool start_cpu(int cpu_num)
|
||||
{
|
||||
// This implements the universal algorithm described in section B.4 of the Intel Multiprocessor specification.
|
||||
|
||||
int apic_id = pcpu_num_to_apic_id[pcpu_num];
|
||||
int apic_id = cpu_num_to_apic_id[cpu_num];
|
||||
|
||||
// Pulse the INIT IPI.
|
||||
apic_write(APICR_ESR, 0);
|
||||
@@ -647,21 +647,21 @@ static bool start_cpu(int pcpu_num)
|
||||
void smp_init(bool smp_enable)
|
||||
{
|
||||
for (int i = 0; i < MAX_APIC_IDS; i++) {
|
||||
apic_id_to_pcpu_num[i] = 0;
|
||||
apic_id_to_cpu_num[i] = 0;
|
||||
}
|
||||
|
||||
for (int i = 0; i < MAX_PCPUS; i++) {
|
||||
pcpu_num_to_apic_id[i] = 0;
|
||||
for (int i = 0; i < MAX_CPUS; i++) {
|
||||
cpu_num_to_apic_id[i] = 0;
|
||||
}
|
||||
|
||||
num_pcpus = 1;
|
||||
num_available_cpus = 1;
|
||||
|
||||
if (smp_enable) {
|
||||
(void)(find_cpus_in_rsdp() || find_cpus_in_floating_mp_struct());
|
||||
}
|
||||
|
||||
for (int i = 0; i < num_pcpus; i++) {
|
||||
apic_id_to_pcpu_num[pcpu_num_to_apic_id[i]] = i;
|
||||
for (int i = 0; i < num_available_cpus; i++) {
|
||||
apic_id_to_cpu_num[cpu_num_to_apic_id[i]] = i;
|
||||
}
|
||||
|
||||
// Reserve last page of first segment for AP trampoline and sync objects.
|
||||
@@ -676,37 +676,37 @@ void smp_init(bool smp_enable)
|
||||
alloc_addr = HEAP_BASE_ADDR + ap_trampoline_size;
|
||||
}
|
||||
|
||||
int smp_start(cpu_state_t pcpu_state[MAX_PCPUS])
|
||||
int smp_start(cpu_state_t cpu_state[MAX_CPUS])
|
||||
{
|
||||
int pcpu_num;
|
||||
int cpu_num;
|
||||
|
||||
pcpu_state[0] = CPU_STATE_RUNNING; // we don't support disabling the boot CPU
|
||||
cpu_state[0] = CPU_STATE_RUNNING; // we don't support disabling the boot CPU
|
||||
|
||||
for (pcpu_num = 1; pcpu_num < num_pcpus; pcpu_num++) {
|
||||
if (pcpu_state[pcpu_num] == CPU_STATE_ENABLED) {
|
||||
if (!start_cpu(pcpu_num)) {
|
||||
return pcpu_num;
|
||||
for (cpu_num = 1; cpu_num < num_available_cpus; cpu_num++) {
|
||||
if (cpu_state[cpu_num] == CPU_STATE_ENABLED) {
|
||||
if (!start_cpu(cpu_num)) {
|
||||
return cpu_num;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int timeout = 100000;
|
||||
while (timeout > 0) {
|
||||
for (pcpu_num = 1; pcpu_num < num_pcpus; pcpu_num++) {
|
||||
if (pcpu_state[pcpu_num] == CPU_STATE_ENABLED) break;
|
||||
for (cpu_num = 1; cpu_num < num_available_cpus; cpu_num++) {
|
||||
if (cpu_state[cpu_num] == CPU_STATE_ENABLED) break;
|
||||
}
|
||||
if (pcpu_num == num_pcpus) {
|
||||
if (cpu_num == num_available_cpus) {
|
||||
return 0;
|
||||
}
|
||||
usleep(10);
|
||||
timeout--;
|
||||
}
|
||||
return pcpu_num;
|
||||
return cpu_num;
|
||||
}
|
||||
|
||||
int smp_my_pcpu_num(void)
|
||||
int smp_my_cpu_num(void)
|
||||
{
|
||||
return num_pcpus > 1 ? apic_id_to_pcpu_num[my_apic_id()] : 0;
|
||||
return num_available_cpus > 1 ? apic_id_to_cpu_num[my_apic_id()] : 0;
|
||||
}
|
||||
|
||||
barrier_t *smp_alloc_barrier(int num_threads)
|
||||
|
||||
+12
-12
@@ -16,11 +16,11 @@
|
||||
#include "spinlock.h"
|
||||
|
||||
/*
|
||||
* The maximum number of active CPU cores. In the current implementation this
|
||||
* is limited to 256 both by the number of available APIC IDs and the need to
|
||||
* fit both the program and the CPU stacks in low memory.
|
||||
* The maximum number of CPU cores that can be used. Currently this is limited
|
||||
* to 256 both by the number of available APIC IDs and the need to fit both
|
||||
* the program and the CPU stacks in low memory.
|
||||
*/
|
||||
#define MAX_PCPUS 256
|
||||
#define MAX_CPUS 256
|
||||
|
||||
/*
|
||||
* The current state of a CPU core.
|
||||
@@ -32,10 +32,10 @@ typedef enum __attribute__ ((packed)) {
|
||||
} cpu_state_t;
|
||||
|
||||
/*
|
||||
* The number of available physical CPU cores. Initially this is 1, but may
|
||||
* increase after calling smp_init().
|
||||
* The number of available CPU cores. Initially this is 1, but may increase
|
||||
* after calling smp_init().
|
||||
*/
|
||||
extern int num_pcpus;
|
||||
extern int num_available_cpus;
|
||||
|
||||
/*
|
||||
* The search step that located the ACPI RSDP (for debug).
|
||||
@@ -47,20 +47,20 @@ extern const char *rsdp_source;
|
||||
extern uintptr_t rsdp_addr;
|
||||
|
||||
/*
|
||||
* Initialises the SMP state and detects the number of physical CPUs.
|
||||
* Initialises the SMP state and detects the number of available CPUs.
|
||||
*/
|
||||
void smp_init(bool smp_enable);
|
||||
|
||||
/*
|
||||
* Starts the APs listed as enabled in pcpu_state. Returns 0 on success
|
||||
* Starts the APs listed as enabled in cpu_state. Returns 0 on success
|
||||
* or the index number of the lowest-numbered AP that failed to start.
|
||||
*/
|
||||
int smp_start(cpu_state_t pcpu_state[MAX_PCPUS]);
|
||||
int smp_start(cpu_state_t cpu_state[MAX_CPUS]);
|
||||
|
||||
/*
|
||||
* Returns the ordinal number of the calling PCPU.
|
||||
* Returns the ordinal number of the calling CPU.
|
||||
*/
|
||||
int smp_my_pcpu_num(void);
|
||||
int smp_my_cpu_num(void);
|
||||
|
||||
/*
|
||||
* Allocates and initialises a barrier object in pinned memory.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
// Copyright (C) 2020 Martin Whitaker.
|
||||
// Copyright (C) 2020-2022 Martin Whitaker.
|
||||
//
|
||||
// Derived from an extract of memtest86+ init.c:
|
||||
//
|
||||
@@ -32,7 +32,7 @@ int get_cpu_temperature(void)
|
||||
}
|
||||
|
||||
// Intel CPU
|
||||
if (cpuid_info.vendor_id.str[0] == 'G' && cpuid_info.max_vcpuid >= 6) {
|
||||
if (cpuid_info.vendor_id.str[0] == 'G' && cpuid_info.max_cpuid >= 6) {
|
||||
if (cpuid_info.dts_pmp & 1) {
|
||||
uint32_t msrl, msrh;
|
||||
|
||||
|
||||
+6
-6
@@ -1,5 +1,5 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
// Copyright (C) 2020-2021 Martin Whitaker.
|
||||
// Copyright (C) 2020-2022 Martin Whitaker.
|
||||
//
|
||||
// Derived from an extract of memtest86+ test.c:
|
||||
//
|
||||
@@ -26,20 +26,20 @@
|
||||
// Public Functions
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
int test_addr_walk1(int my_vcpu)
|
||||
int test_addr_walk1(int my_cpu)
|
||||
{
|
||||
int ticks = 0;
|
||||
|
||||
// There isn't a meaningful address for this test.
|
||||
test_addr[my_vcpu] = 0;
|
||||
test_addr[my_cpu] = 0;
|
||||
|
||||
testword_t invert = 0;
|
||||
for (int i = 0; i < 2; i++) {
|
||||
if (my_vcpu == master_vcpu) {
|
||||
if (my_cpu == master_cpu) {
|
||||
display_test_pattern_value(invert);
|
||||
}
|
||||
ticks++;
|
||||
if (my_vcpu < 0) {
|
||||
if (my_cpu < 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -83,7 +83,7 @@ int test_addr_walk1(int my_vcpu)
|
||||
|
||||
invert = ~invert;
|
||||
|
||||
do_tick(my_vcpu);
|
||||
do_tick(my_cpu);
|
||||
BAILOUT;
|
||||
}
|
||||
|
||||
|
||||
+22
-22
@@ -1,5 +1,5 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
// Copyright (C) 2020-2021 Martin Whitaker.
|
||||
// Copyright (C) 2020-2022 Martin Whitaker.
|
||||
//
|
||||
// Derived from an extract of memtest86+ test.c:
|
||||
//
|
||||
@@ -29,11 +29,11 @@
|
||||
// Private Functions
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
static int pattern_fill(int my_vcpu, testword_t pattern)
|
||||
static int pattern_fill(int my_cpu, testword_t pattern)
|
||||
{
|
||||
int ticks = 0;
|
||||
|
||||
if (my_vcpu == master_vcpu) {
|
||||
if (my_cpu == master_cpu) {
|
||||
display_test_pattern_value(pattern);
|
||||
}
|
||||
|
||||
@@ -54,24 +54,24 @@ static int pattern_fill(int my_vcpu, testword_t pattern)
|
||||
pe = end;
|
||||
}
|
||||
ticks++;
|
||||
if (my_vcpu < 0) {
|
||||
if (my_cpu < 0) {
|
||||
continue;
|
||||
}
|
||||
test_addr[my_vcpu] = (uintptr_t)p;
|
||||
test_addr[my_cpu] = (uintptr_t)p;
|
||||
do {
|
||||
write_word(p, pattern);
|
||||
} while (p++ < pe); // test before increment in case pointer overflows
|
||||
do_tick(my_vcpu);
|
||||
do_tick(my_cpu);
|
||||
BAILOUT;
|
||||
} while (!at_end && ++pe); // advance pe to next start point
|
||||
}
|
||||
|
||||
flush_caches(my_vcpu);
|
||||
flush_caches(my_cpu);
|
||||
|
||||
return ticks;
|
||||
}
|
||||
|
||||
static int pattern_check(int my_vcpu, testword_t pattern)
|
||||
static int pattern_check(int my_cpu, testword_t pattern)
|
||||
{
|
||||
int ticks = 0;
|
||||
|
||||
@@ -92,17 +92,17 @@ static int pattern_check(int my_vcpu, testword_t pattern)
|
||||
pe = end;
|
||||
}
|
||||
ticks++;
|
||||
if (my_vcpu < 0) {
|
||||
if (my_cpu < 0) {
|
||||
continue;
|
||||
}
|
||||
test_addr[my_vcpu] = (uintptr_t)p;
|
||||
test_addr[my_cpu] = (uintptr_t)p;
|
||||
do {
|
||||
testword_t actual = read_word(p);
|
||||
if (unlikely(actual != pattern)) {
|
||||
data_error(p, pattern, actual, true);
|
||||
}
|
||||
} while (p++ < pe); // test before increment in case pointer overflows
|
||||
do_tick(my_vcpu);
|
||||
do_tick(my_cpu);
|
||||
BAILOUT;
|
||||
} while (!at_end && ++pe); // advance pe to next start point
|
||||
}
|
||||
@@ -110,21 +110,21 @@ static int pattern_check(int my_vcpu, testword_t pattern)
|
||||
return ticks;
|
||||
}
|
||||
|
||||
static int fade_delay(int my_vcpu, int sleep_secs)
|
||||
static int fade_delay(int my_cpu, int sleep_secs)
|
||||
{
|
||||
int ticks = 0;
|
||||
|
||||
if (my_vcpu == master_vcpu) {
|
||||
if (my_cpu == master_cpu) {
|
||||
display_test_stage_description("fade over %i seconds", sleep_secs);
|
||||
}
|
||||
while (sleep_secs > 0) {
|
||||
sleep_secs--;
|
||||
ticks++;
|
||||
if (my_vcpu < 0) {
|
||||
if (my_cpu < 0) {
|
||||
continue;
|
||||
}
|
||||
sleep(1);
|
||||
do_tick(my_vcpu);
|
||||
do_tick(my_cpu);
|
||||
BAILOUT;
|
||||
}
|
||||
|
||||
@@ -135,7 +135,7 @@ static int fade_delay(int my_vcpu, int sleep_secs)
|
||||
// Public Functions
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
int test_bit_fade(int my_vcpu, int stage, int sleep_secs)
|
||||
int test_bit_fade(int my_cpu, int stage, int sleep_secs)
|
||||
{
|
||||
const testword_t all_zero = 0;
|
||||
const testword_t all_ones = ~all_zero;
|
||||
@@ -146,28 +146,28 @@ int test_bit_fade(int my_vcpu, int stage, int sleep_secs)
|
||||
|
||||
switch (stage) {
|
||||
case 0:
|
||||
ticks = pattern_fill(my_vcpu, all_zero);
|
||||
ticks = pattern_fill(my_cpu, all_zero);
|
||||
break;
|
||||
case 1:
|
||||
// Only sleep once.
|
||||
if (stage != last_stage) {
|
||||
ticks = fade_delay(my_vcpu, sleep_secs);
|
||||
ticks = fade_delay(my_cpu, sleep_secs);
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
ticks = pattern_check(my_vcpu, all_zero);
|
||||
ticks = pattern_check(my_cpu, all_zero);
|
||||
break;
|
||||
case 3:
|
||||
ticks = pattern_fill(my_vcpu, all_ones);
|
||||
ticks = pattern_fill(my_cpu, all_ones);
|
||||
break;
|
||||
case 4:
|
||||
// Only sleep once.
|
||||
if (stage != last_stage) {
|
||||
ticks = fade_delay(my_vcpu, sleep_secs);
|
||||
ticks = fade_delay(my_cpu, sleep_secs);
|
||||
}
|
||||
break;
|
||||
case 5:
|
||||
ticks = pattern_check(my_vcpu, all_ones);
|
||||
ticks = pattern_check(my_cpu, all_ones);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
||||
+17
-17
@@ -1,5 +1,5 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
// Copyright (C) 2020-2021 Martin Whitaker.
|
||||
// Copyright (C) 2020-2022 Martin Whitaker.
|
||||
//
|
||||
// Derived from an extract of memtest86+ test.c:
|
||||
//
|
||||
@@ -27,18 +27,18 @@
|
||||
// Public Functions
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
int test_block_move(int my_vcpu, int iterations)
|
||||
int test_block_move(int my_cpu, int iterations)
|
||||
{
|
||||
int ticks = 0;
|
||||
|
||||
if (my_vcpu == master_vcpu) {
|
||||
if (my_cpu == master_cpu) {
|
||||
display_test_pattern_name("block move");
|
||||
}
|
||||
|
||||
// Initialize memory with the initial pattern.
|
||||
for (int i = 0; i < vm_map_size; i++) {
|
||||
testword_t *start, *end;
|
||||
calculate_chunk(&start, &end, my_vcpu, i, 16 * sizeof(testword_t));
|
||||
calculate_chunk(&start, &end, my_cpu, i, 16 * sizeof(testword_t));
|
||||
|
||||
testword_t *p = start;
|
||||
testword_t *pe = start;
|
||||
@@ -53,10 +53,10 @@ int test_block_move(int my_vcpu, int iterations)
|
||||
pe = end;
|
||||
}
|
||||
ticks++;
|
||||
if (my_vcpu < 0) {
|
||||
if (my_cpu < 0) {
|
||||
continue;
|
||||
}
|
||||
test_addr[my_vcpu] = (uintptr_t)p;
|
||||
test_addr[my_cpu] = (uintptr_t)p;
|
||||
testword_t pattern1 = 1;
|
||||
do {
|
||||
testword_t pattern2 = ~pattern1;
|
||||
@@ -78,17 +78,17 @@ int test_block_move(int my_vcpu, int iterations)
|
||||
write_word(p + 15, pattern2);
|
||||
pattern1 = pattern1 << 1 | pattern1 >> (TESTWORD_WIDTH - 1); // rotate left
|
||||
} while (p <= (pe - 16) && (p += 16)); // test before increment in case pointer overflows
|
||||
do_tick(my_vcpu);
|
||||
do_tick(my_cpu);
|
||||
BAILOUT;
|
||||
} while (!at_end && ++pe); // advance pe to next start point
|
||||
}
|
||||
flush_caches(my_vcpu);
|
||||
flush_caches(my_cpu);
|
||||
|
||||
// Now move the data around. First move the data up half of the segment size
|
||||
// we are testing. Then move the data to the original location + 32 bytes.
|
||||
for (int i = 0; i < vm_map_size; i++) {
|
||||
testword_t *start, *end;
|
||||
calculate_chunk(&start, &end, my_vcpu, i, 16 * sizeof(testword_t));
|
||||
calculate_chunk(&start, &end, my_cpu, i, 16 * sizeof(testword_t));
|
||||
|
||||
testword_t *p = start;
|
||||
testword_t *pe = start;
|
||||
@@ -107,10 +107,10 @@ int test_block_move(int my_vcpu, int iterations)
|
||||
|
||||
for (int j = 0; j < iterations; j++) {
|
||||
ticks++;
|
||||
if (my_vcpu < 0) {
|
||||
if (my_cpu < 0) {
|
||||
continue;
|
||||
}
|
||||
test_addr[my_vcpu] = (uintptr_t)p;
|
||||
test_addr[my_cpu] = (uintptr_t)p;
|
||||
#ifdef __x86_64__
|
||||
__asm__ __volatile__ (
|
||||
"cld\n"
|
||||
@@ -188,19 +188,19 @@ int test_block_move(int my_vcpu, int iterations)
|
||||
: "edi", "esi", "ecx"
|
||||
);
|
||||
#endif
|
||||
do_tick(my_vcpu);
|
||||
do_tick(my_cpu);
|
||||
BAILOUT;
|
||||
}
|
||||
} while (!at_end && ++pe); // advance pe to next start point
|
||||
}
|
||||
|
||||
flush_caches(my_vcpu);
|
||||
flush_caches(my_cpu);
|
||||
|
||||
// Now check the data. The error checking is rather crude. We just check that the
|
||||
// adjacent words are the same.
|
||||
for (int i = 0; i < vm_map_size; i++) {
|
||||
testword_t *start, *end;
|
||||
calculate_chunk(&start, &end, my_vcpu, i, 16 * sizeof(testword_t));
|
||||
calculate_chunk(&start, &end, my_cpu, i, 16 * sizeof(testword_t));
|
||||
|
||||
testword_t *p = start;
|
||||
testword_t *pe = start;
|
||||
@@ -215,10 +215,10 @@ int test_block_move(int my_vcpu, int iterations)
|
||||
pe = end;
|
||||
}
|
||||
ticks++;
|
||||
if (my_vcpu < 0) {
|
||||
if (my_cpu < 0) {
|
||||
continue;
|
||||
}
|
||||
test_addr[my_vcpu] = (uintptr_t)p;
|
||||
test_addr[my_cpu] = (uintptr_t)p;
|
||||
do {
|
||||
testword_t p0 = read_word(p + 0);
|
||||
testword_t p1 = read_word(p + 1);
|
||||
@@ -226,7 +226,7 @@ int test_block_move(int my_vcpu, int iterations)
|
||||
data_error(p, p0, p1, false);
|
||||
}
|
||||
} while (p <= (pe - 2) && (p += 2)); // test before increment in case pointer overflows
|
||||
do_tick(my_vcpu);
|
||||
do_tick(my_cpu);
|
||||
BAILOUT;
|
||||
} while (!at_end && ++pe); // advance pe to next start point
|
||||
}
|
||||
|
||||
+16
-16
@@ -1,5 +1,5 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
// Copyright (C) 2020-2021 Martin Whitaker.
|
||||
// Copyright (C) 2020-2022 Martin Whitaker.
|
||||
//
|
||||
// Derived from an extract of memtest86+ test.c:
|
||||
//
|
||||
@@ -27,18 +27,18 @@
|
||||
// Public Functions
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
int test_modulo_n(int my_vcpu, int iterations, testword_t pattern1, testword_t pattern2, int n, int offset)
|
||||
int test_modulo_n(int my_cpu, int iterations, testword_t pattern1, testword_t pattern2, int n, int offset)
|
||||
{
|
||||
int ticks = 0;
|
||||
|
||||
if (my_vcpu == master_vcpu) {
|
||||
if (my_cpu == master_cpu) {
|
||||
display_test_pattern_values(pattern1, offset);
|
||||
}
|
||||
|
||||
// Write every nth location with pattern1.
|
||||
for (int i = 0; i < vm_map_size; i++) {
|
||||
testword_t *start, *end;
|
||||
calculate_chunk(&start, &end, my_vcpu, i, sizeof(testword_t));
|
||||
calculate_chunk(&start, &end, my_cpu, i, sizeof(testword_t));
|
||||
end -= n; // avoids pointer overflow when incrementing p
|
||||
|
||||
testword_t *p = start + offset; // we assume each chunk has at least 'n' words, so this won't overflow
|
||||
@@ -54,14 +54,14 @@ int test_modulo_n(int my_vcpu, int iterations, testword_t pattern1, testword_t p
|
||||
pe = end;
|
||||
}
|
||||
ticks++;
|
||||
if (my_vcpu < 0) {
|
||||
if (my_cpu < 0) {
|
||||
continue;
|
||||
}
|
||||
test_addr[my_vcpu] = (uintptr_t)p;
|
||||
test_addr[my_cpu] = (uintptr_t)p;
|
||||
do {
|
||||
write_word(p, pattern1);
|
||||
} while (p <= (pe - n) && (p += n)); // test before increment in case pointer overflows
|
||||
do_tick(my_vcpu);
|
||||
do_tick(my_cpu);
|
||||
BAILOUT;
|
||||
} while (!at_end && ++pe); // advance pe to next start point
|
||||
}
|
||||
@@ -70,7 +70,7 @@ int test_modulo_n(int my_vcpu, int iterations, testword_t pattern1, testword_t p
|
||||
for (int i = 0; i < iterations; i++) {
|
||||
for (int j = 0; j < vm_map_size; j++) {
|
||||
testword_t *start, *end;
|
||||
calculate_chunk(&start, &end, my_vcpu, j, sizeof(testword_t));
|
||||
calculate_chunk(&start, &end, my_cpu, j, sizeof(testword_t));
|
||||
|
||||
int k = 0;
|
||||
testword_t *p = start;
|
||||
@@ -86,10 +86,10 @@ int test_modulo_n(int my_vcpu, int iterations, testword_t pattern1, testword_t p
|
||||
pe = end;
|
||||
}
|
||||
ticks++;
|
||||
if (my_vcpu < 0) {
|
||||
if (my_cpu < 0) {
|
||||
continue;
|
||||
}
|
||||
test_addr[my_vcpu] = (uintptr_t)p;
|
||||
test_addr[my_cpu] = (uintptr_t)p;
|
||||
do {
|
||||
if (k != offset) {
|
||||
write_word(p, pattern2);
|
||||
@@ -99,18 +99,18 @@ int test_modulo_n(int my_vcpu, int iterations, testword_t pattern1, testword_t p
|
||||
k = 0;
|
||||
}
|
||||
} while (p++ < pe); // test before increment in case pointer overflows
|
||||
do_tick(my_vcpu);
|
||||
do_tick(my_cpu);
|
||||
BAILOUT;
|
||||
} while (!at_end && ++pe); // advance pe to next start point
|
||||
}
|
||||
}
|
||||
|
||||
flush_caches(my_vcpu);
|
||||
flush_caches(my_cpu);
|
||||
|
||||
// Now check every nth location.
|
||||
for (int i = 0; i < vm_map_size; i++) {
|
||||
testword_t *start, *end;
|
||||
calculate_chunk(&start, &end, my_vcpu, i, sizeof(testword_t));
|
||||
calculate_chunk(&start, &end, my_cpu, i, sizeof(testword_t));
|
||||
end -= n; // avoids pointer overflow when incrementing p
|
||||
|
||||
testword_t *p = start + offset; // we assume each chunk has at least 'offset' words, so this won't overflow
|
||||
@@ -126,17 +126,17 @@ int test_modulo_n(int my_vcpu, int iterations, testword_t pattern1, testword_t p
|
||||
pe = end;
|
||||
}
|
||||
ticks++;
|
||||
if (my_vcpu < 0) {
|
||||
if (my_cpu < 0) {
|
||||
continue;
|
||||
}
|
||||
test_addr[my_vcpu] = (uintptr_t)p;
|
||||
test_addr[my_cpu] = (uintptr_t)p;
|
||||
do {
|
||||
testword_t actual = read_word(p);
|
||||
if (unlikely(actual != pattern1)) {
|
||||
data_error(p, pattern1, actual, true);
|
||||
}
|
||||
} while (p <= (pe - n) && (p += n)); // test before increment in case pointer overflows
|
||||
do_tick(my_vcpu);
|
||||
do_tick(my_cpu);
|
||||
BAILOUT;
|
||||
} while (!at_end && ++pe); // advance pe to next start point
|
||||
}
|
||||
|
||||
+17
-17
@@ -1,5 +1,5 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
// Copyright (C) 2020-2021 Martin Whitaker.
|
||||
// Copyright (C) 2020-2022 Martin Whitaker.
|
||||
//
|
||||
// Derived from an extract of memtest86+ test.c:
|
||||
//
|
||||
@@ -29,18 +29,18 @@
|
||||
// Public Functions
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
int test_mov_inv_fixed(int my_vcpu, int iterations, testword_t pattern1, testword_t pattern2)
|
||||
int test_mov_inv_fixed(int my_cpu, int iterations, testword_t pattern1, testword_t pattern2)
|
||||
{
|
||||
int ticks = 0;
|
||||
|
||||
if (my_vcpu == master_vcpu) {
|
||||
if (my_cpu == master_cpu) {
|
||||
display_test_pattern_value(pattern1);
|
||||
}
|
||||
|
||||
// Initialize memory with the initial pattern.
|
||||
for (int i = 0; i < vm_map_size; i++) {
|
||||
testword_t *start, *end;
|
||||
calculate_chunk(&start, &end, my_vcpu, i, sizeof(testword_t));
|
||||
calculate_chunk(&start, &end, my_cpu, i, sizeof(testword_t));
|
||||
|
||||
volatile testword_t *p = start;
|
||||
volatile testword_t *pe = start;
|
||||
@@ -55,10 +55,10 @@ int test_mov_inv_fixed(int my_vcpu, int iterations, testword_t pattern1, testwor
|
||||
pe = end;
|
||||
}
|
||||
ticks++;
|
||||
if (my_vcpu < 0) {
|
||||
if (my_cpu < 0) {
|
||||
continue;
|
||||
}
|
||||
test_addr[my_vcpu] = (uintptr_t)p;
|
||||
test_addr[my_cpu] = (uintptr_t)p;
|
||||
#if HAND_OPTIMISED
|
||||
#ifdef __x86_64__
|
||||
uint64_t length = pe - p + 1;
|
||||
@@ -86,7 +86,7 @@ int test_mov_inv_fixed(int my_vcpu, int iterations, testword_t pattern1, testwor
|
||||
write_word(p, pattern1);
|
||||
} while (p++ < pe); // test before increment in case pointer overflows
|
||||
#endif
|
||||
do_tick(my_vcpu);
|
||||
do_tick(my_cpu);
|
||||
BAILOUT;
|
||||
} while (!at_end && ++pe); // advance pe to next start point
|
||||
}
|
||||
@@ -94,11 +94,11 @@ int test_mov_inv_fixed(int my_vcpu, int iterations, testword_t pattern1, testwor
|
||||
// Check for the current pattern and then write the alternate pattern for
|
||||
// each memory location. Test from the bottom up and then from the top down.
|
||||
for (int i = 0; i < iterations; i++) {
|
||||
flush_caches(my_vcpu);
|
||||
flush_caches(my_cpu);
|
||||
|
||||
for (int j = 0; j < vm_map_size; j++) {
|
||||
testword_t *start, *end;
|
||||
calculate_chunk(&start, &end, my_vcpu, j, sizeof(testword_t));
|
||||
calculate_chunk(&start, &end, my_cpu, j, sizeof(testword_t));
|
||||
|
||||
volatile testword_t *p = start;
|
||||
volatile testword_t *pe = start;
|
||||
@@ -113,10 +113,10 @@ int test_mov_inv_fixed(int my_vcpu, int iterations, testword_t pattern1, testwor
|
||||
pe = end;
|
||||
}
|
||||
ticks++;
|
||||
if (my_vcpu < 0) {
|
||||
if (my_cpu < 0) {
|
||||
continue;
|
||||
}
|
||||
test_addr[my_vcpu] = (uintptr_t)p;
|
||||
test_addr[my_cpu] = (uintptr_t)p;
|
||||
do {
|
||||
testword_t actual = read_word(p);
|
||||
if (unlikely(actual != pattern1)) {
|
||||
@@ -124,16 +124,16 @@ int test_mov_inv_fixed(int my_vcpu, int iterations, testword_t pattern1, testwor
|
||||
}
|
||||
write_word(p, pattern2);
|
||||
} while (p++ < pe); // test before increment in case pointer overflows
|
||||
do_tick(my_vcpu);
|
||||
do_tick(my_cpu);
|
||||
BAILOUT;
|
||||
} while (!at_end && ++pe); // advance pe to next start point
|
||||
}
|
||||
|
||||
flush_caches(my_vcpu);
|
||||
flush_caches(my_cpu);
|
||||
|
||||
for (int j = vm_map_size - 1; j >= 0; j--) {
|
||||
testword_t *start, *end;
|
||||
calculate_chunk(&start, &end, my_vcpu, j, sizeof(testword_t));
|
||||
calculate_chunk(&start, &end, my_cpu, j, sizeof(testword_t));
|
||||
|
||||
volatile testword_t *p = end;
|
||||
volatile testword_t *ps = end;
|
||||
@@ -148,10 +148,10 @@ int test_mov_inv_fixed(int my_vcpu, int iterations, testword_t pattern1, testwor
|
||||
ps = start;
|
||||
}
|
||||
ticks++;
|
||||
if (my_vcpu < 0) {
|
||||
if (my_cpu < 0) {
|
||||
continue;
|
||||
}
|
||||
test_addr[my_vcpu] = (uintptr_t)p;
|
||||
test_addr[my_cpu] = (uintptr_t)p;
|
||||
do {
|
||||
testword_t actual = read_word(p);
|
||||
if (unlikely(actual != pattern2)) {
|
||||
@@ -159,7 +159,7 @@ int test_mov_inv_fixed(int my_vcpu, int iterations, testword_t pattern1, testwor
|
||||
}
|
||||
write_word(p, pattern1);
|
||||
} while (p-- > ps); // test before decrement in case pointer overflows
|
||||
do_tick(my_vcpu);
|
||||
do_tick(my_cpu);
|
||||
BAILOUT;
|
||||
} while (!at_start && --ps); // advance ps to next start point
|
||||
}
|
||||
|
||||
+16
-16
@@ -1,5 +1,5 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
// Copyright (C) 2020-2021 Martin Whitaker.
|
||||
// Copyright (C) 2020-2022 Martin Whitaker.
|
||||
//
|
||||
// Derived from an extract of memtest86+ test.c:
|
||||
//
|
||||
@@ -30,7 +30,7 @@
|
||||
// Public Functions
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
int test_mov_inv_random(int my_vcpu)
|
||||
int test_mov_inv_random(int my_cpu)
|
||||
{
|
||||
int ticks = 0;
|
||||
|
||||
@@ -41,15 +41,15 @@ int test_mov_inv_random(int my_vcpu)
|
||||
seed = UINT64_C(0x12345678) * (1 + pass_num);
|
||||
}
|
||||
|
||||
if (my_vcpu == master_vcpu) {
|
||||
if (my_cpu == master_cpu) {
|
||||
display_test_pattern_value(seed);
|
||||
}
|
||||
|
||||
// Initialize memory with the initial pattern.
|
||||
random_seed(my_vcpu, seed);
|
||||
random_seed(my_cpu, seed);
|
||||
for (int i = 0; i < vm_map_size; i++) {
|
||||
testword_t *start, *end;
|
||||
calculate_chunk(&start, &end, my_vcpu, i, sizeof(testword_t));
|
||||
calculate_chunk(&start, &end, my_cpu, i, sizeof(testword_t));
|
||||
|
||||
volatile testword_t *p = start;
|
||||
volatile testword_t *pe = start;
|
||||
@@ -64,14 +64,14 @@ int test_mov_inv_random(int my_vcpu)
|
||||
pe = end;
|
||||
}
|
||||
ticks++;
|
||||
if (my_vcpu < 0) {
|
||||
if (my_cpu < 0) {
|
||||
continue;
|
||||
}
|
||||
test_addr[my_vcpu] = (uintptr_t)p;
|
||||
test_addr[my_cpu] = (uintptr_t)p;
|
||||
do {
|
||||
write_word(p, random(my_vcpu));
|
||||
write_word(p, random(my_cpu));
|
||||
} while (p++ < pe); // test before increment in case pointer overflows
|
||||
do_tick(my_vcpu);
|
||||
do_tick(my_cpu);
|
||||
BAILOUT;
|
||||
} while (!at_end && ++pe); // advance pe to next start point
|
||||
}
|
||||
@@ -80,12 +80,12 @@ int test_mov_inv_random(int my_vcpu)
|
||||
// memory location. Repeat.
|
||||
testword_t invert = 0;
|
||||
for (int i = 0; i < 2; i++) {
|
||||
flush_caches(my_vcpu);
|
||||
flush_caches(my_cpu);
|
||||
|
||||
random_seed(my_vcpu, seed);
|
||||
random_seed(my_cpu, seed);
|
||||
for (int j = 0; j < vm_map_size; j++) {
|
||||
testword_t *start, *end;
|
||||
calculate_chunk(&start, &end, my_vcpu, j, sizeof(testword_t));
|
||||
calculate_chunk(&start, &end, my_cpu, j, sizeof(testword_t));
|
||||
|
||||
volatile testword_t *p = start;
|
||||
volatile testword_t *pe = start;
|
||||
@@ -100,19 +100,19 @@ int test_mov_inv_random(int my_vcpu)
|
||||
pe = end;
|
||||
}
|
||||
ticks++;
|
||||
if (my_vcpu < 0) {
|
||||
if (my_cpu < 0) {
|
||||
continue;
|
||||
}
|
||||
test_addr[my_vcpu] = (uintptr_t)p;
|
||||
test_addr[my_cpu] = (uintptr_t)p;
|
||||
do {
|
||||
testword_t expect = random(my_vcpu) ^ invert;
|
||||
testword_t expect = random(my_cpu) ^ invert;
|
||||
testword_t actual = read_word(p);
|
||||
if (unlikely(actual != expect)) {
|
||||
data_error(p, expect, actual, true);
|
||||
}
|
||||
write_word(p, ~expect);
|
||||
} while (p++ < pe); // test before increment in case pointer overflows
|
||||
do_tick(my_vcpu);
|
||||
do_tick(my_cpu);
|
||||
BAILOUT;
|
||||
} while (!at_end && ++pe); // advance pe to next start point
|
||||
}
|
||||
|
||||
+17
-17
@@ -1,5 +1,5 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
// Copyright (C) 2020-2021 Martin Whitaker.
|
||||
// Copyright (C) 2020-2022 Martin Whitaker.
|
||||
//
|
||||
// Derived from an extract of memtest86+ test.c:
|
||||
//
|
||||
@@ -27,20 +27,20 @@
|
||||
// Public Functions
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
int test_mov_inv_walk1(int my_vcpu, int iterations, int offset, bool inverse)
|
||||
int test_mov_inv_walk1(int my_cpu, int iterations, int offset, bool inverse)
|
||||
{
|
||||
int ticks = 0;
|
||||
|
||||
testword_t pattern = (testword_t)1 << offset;
|
||||
|
||||
if (my_vcpu == master_vcpu) {
|
||||
if (my_cpu == master_cpu) {
|
||||
display_test_pattern_value(inverse ? ~pattern : pattern);
|
||||
}
|
||||
|
||||
// Initialize memory with the initial pattern.
|
||||
for (int i = 0; i < vm_map_size; i++) {
|
||||
testword_t *start, *end;
|
||||
calculate_chunk(&start, &end, my_vcpu, i, sizeof(testword_t));
|
||||
calculate_chunk(&start, &end, my_cpu, i, sizeof(testword_t));
|
||||
|
||||
volatile testword_t *p = start;
|
||||
volatile testword_t *pe = start;
|
||||
@@ -55,15 +55,15 @@ int test_mov_inv_walk1(int my_vcpu, int iterations, int offset, bool inverse)
|
||||
pe = end;
|
||||
}
|
||||
ticks++;
|
||||
if (my_vcpu < 0) {
|
||||
if (my_cpu < 0) {
|
||||
continue;
|
||||
}
|
||||
test_addr[my_vcpu] = (uintptr_t)p;
|
||||
test_addr[my_cpu] = (uintptr_t)p;
|
||||
do {
|
||||
write_word(p, inverse ? ~pattern : pattern);
|
||||
pattern = pattern << 1 | pattern >> (TESTWORD_WIDTH - 1); // rotate left
|
||||
} while (p++ < pe); // test before increment in case pointer overflows
|
||||
do_tick(my_vcpu);
|
||||
do_tick(my_cpu);
|
||||
BAILOUT;
|
||||
} while (!at_end && ++pe); // advance pe to next start point
|
||||
}
|
||||
@@ -73,11 +73,11 @@ int test_mov_inv_walk1(int my_vcpu, int iterations, int offset, bool inverse)
|
||||
for (int i = 0; i < iterations; i++) {
|
||||
pattern = (testword_t)1 << offset;
|
||||
|
||||
flush_caches(my_vcpu);
|
||||
flush_caches(my_cpu);
|
||||
|
||||
for (int j = 0; j < vm_map_size; j++) {
|
||||
testword_t *start, *end;
|
||||
calculate_chunk(&start, &end, my_vcpu, j, sizeof(testword_t));
|
||||
calculate_chunk(&start, &end, my_cpu, j, sizeof(testword_t));
|
||||
|
||||
volatile testword_t *p = start;
|
||||
volatile testword_t *pe = start;
|
||||
@@ -92,10 +92,10 @@ int test_mov_inv_walk1(int my_vcpu, int iterations, int offset, bool inverse)
|
||||
pe = end;
|
||||
}
|
||||
ticks++;
|
||||
if (my_vcpu < 0) {
|
||||
if (my_cpu < 0) {
|
||||
continue;
|
||||
}
|
||||
test_addr[my_vcpu] = (uintptr_t)p;
|
||||
test_addr[my_cpu] = (uintptr_t)p;
|
||||
do {
|
||||
testword_t expect = inverse ? ~pattern : pattern;
|
||||
testword_t actual = read_word(p);
|
||||
@@ -105,16 +105,16 @@ int test_mov_inv_walk1(int my_vcpu, int iterations, int offset, bool inverse)
|
||||
write_word(p, ~expect);
|
||||
pattern = pattern << 1 | pattern >> (TESTWORD_WIDTH - 1); // rotate left
|
||||
} while (p++ < pe); // test before increment in case pointer overflows
|
||||
do_tick(my_vcpu);
|
||||
do_tick(my_cpu);
|
||||
BAILOUT;
|
||||
} while (!at_end && ++pe); // advance pe to next start point
|
||||
}
|
||||
|
||||
flush_caches(my_vcpu);
|
||||
flush_caches(my_cpu);
|
||||
|
||||
for (int j = vm_map_size - 1; j >= 0; j--) {
|
||||
testword_t *start, *end;
|
||||
calculate_chunk(&start, &end, my_vcpu, j, sizeof(testword_t));
|
||||
calculate_chunk(&start, &end, my_cpu, j, sizeof(testword_t));
|
||||
|
||||
volatile testword_t *p = end;
|
||||
volatile testword_t *ps = end;
|
||||
@@ -129,10 +129,10 @@ int test_mov_inv_walk1(int my_vcpu, int iterations, int offset, bool inverse)
|
||||
ps = start;
|
||||
}
|
||||
ticks++;
|
||||
if (my_vcpu < 0) {
|
||||
if (my_cpu < 0) {
|
||||
continue;
|
||||
}
|
||||
test_addr[my_vcpu] = (uintptr_t)ps;
|
||||
test_addr[my_cpu] = (uintptr_t)ps;
|
||||
do {
|
||||
pattern = pattern >> 1 | pattern << (TESTWORD_WIDTH - 1); // rotate right
|
||||
testword_t expect = inverse ? pattern : ~pattern;
|
||||
@@ -142,7 +142,7 @@ int test_mov_inv_walk1(int my_vcpu, int iterations, int offset, bool inverse)
|
||||
}
|
||||
write_word(p, ~expect);
|
||||
} while (p-- > ps); // test before decrement in case pointer overflows
|
||||
do_tick(my_vcpu);
|
||||
do_tick(my_cpu);
|
||||
BAILOUT;
|
||||
} while (!at_start && --ps); // advance ps to next start point
|
||||
}
|
||||
|
||||
+17
-17
@@ -1,5 +1,5 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
// Copyright (C) 2020-2021 Martin Whitaker.
|
||||
// Copyright (C) 2020-2022 Martin Whitaker.
|
||||
//
|
||||
// Derived from an extract of memtest86+ test.c:
|
||||
//
|
||||
@@ -27,11 +27,11 @@
|
||||
// Private Functions
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
static int pattern_fill(int my_vcpu, testword_t offset)
|
||||
static int pattern_fill(int my_cpu, testword_t offset)
|
||||
{
|
||||
int ticks = 0;
|
||||
|
||||
if (my_vcpu == master_vcpu) {
|
||||
if (my_cpu == master_cpu) {
|
||||
display_test_pattern_name("own address");
|
||||
}
|
||||
|
||||
@@ -53,24 +53,24 @@ static int pattern_fill(int my_vcpu, testword_t offset)
|
||||
pe = end;
|
||||
}
|
||||
ticks++;
|
||||
if (my_vcpu < 0) {
|
||||
if (my_cpu < 0) {
|
||||
continue;
|
||||
}
|
||||
test_addr[my_vcpu] = (uintptr_t)p;
|
||||
test_addr[my_cpu] = (uintptr_t)p;
|
||||
do {
|
||||
write_word(p, (testword_t)p + offset);
|
||||
} while (p++ < pe); // test before increment in case pointer overflows
|
||||
do_tick(my_vcpu);
|
||||
do_tick(my_cpu);
|
||||
BAILOUT;
|
||||
} while (!at_end && ++pe); // advance pe to next start point
|
||||
}
|
||||
|
||||
flush_caches(my_vcpu);
|
||||
flush_caches(my_cpu);
|
||||
|
||||
return ticks;
|
||||
}
|
||||
|
||||
static int pattern_check(int my_vcpu, testword_t offset)
|
||||
static int pattern_check(int my_cpu, testword_t offset)
|
||||
{
|
||||
int ticks = 0;
|
||||
|
||||
@@ -92,10 +92,10 @@ static int pattern_check(int my_vcpu, testword_t offset)
|
||||
pe = end;
|
||||
}
|
||||
ticks++;
|
||||
if (my_vcpu < 0) {
|
||||
if (my_cpu < 0) {
|
||||
continue;
|
||||
}
|
||||
test_addr[my_vcpu] = (uintptr_t)p;
|
||||
test_addr[my_cpu] = (uintptr_t)p;
|
||||
do {
|
||||
testword_t expect = (testword_t)p + offset;
|
||||
testword_t actual = read_word(p);
|
||||
@@ -103,7 +103,7 @@ static int pattern_check(int my_vcpu, testword_t offset)
|
||||
data_error(p, expect, actual, true);
|
||||
}
|
||||
} while (p++ < pe); // test before increment in case pointer overflows
|
||||
do_tick(my_vcpu);
|
||||
do_tick(my_cpu);
|
||||
BAILOUT;
|
||||
} while (!at_end && ++pe); // advance pe to next start point
|
||||
}
|
||||
@@ -115,17 +115,17 @@ static int pattern_check(int my_vcpu, testword_t offset)
|
||||
// Public Functions
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
int test_own_addr1(int my_vcpu)
|
||||
int test_own_addr1(int my_cpu)
|
||||
{
|
||||
int ticks = 0;
|
||||
|
||||
ticks += pattern_fill(my_vcpu, 0);
|
||||
ticks += pattern_check(my_vcpu, 0);
|
||||
ticks += pattern_fill(my_cpu, 0);
|
||||
ticks += pattern_check(my_cpu, 0);
|
||||
|
||||
return ticks;
|
||||
}
|
||||
|
||||
int test_own_addr2(int my_vcpu, int stage)
|
||||
int test_own_addr2(int my_cpu, int stage)
|
||||
{
|
||||
static testword_t offset = 0;
|
||||
static int last_stage = -1;
|
||||
@@ -136,10 +136,10 @@ int test_own_addr2(int my_vcpu, int stage)
|
||||
|
||||
switch (stage) {
|
||||
case 0:
|
||||
ticks = pattern_fill(my_vcpu, offset);
|
||||
ticks = pattern_fill(my_cpu, offset);
|
||||
break;
|
||||
case 1:
|
||||
ticks = pattern_check(my_vcpu, offset);
|
||||
ticks = pattern_check(my_cpu, offset);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
||||
+10
-10
@@ -5,29 +5,29 @@
|
||||
* Provides the prototypes for the basic test functions used to implement
|
||||
* the tests.
|
||||
*
|
||||
* Copyright (C) 2020-2021 Martin Whitaker.
|
||||
* Copyright (C) 2020-2022 Martin Whitaker.
|
||||
*/
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "test.h"
|
||||
|
||||
int test_addr_walk1(int my_vcpu);
|
||||
int test_addr_walk1(int my_cpu);
|
||||
|
||||
int test_own_addr1(int my_vcpu);
|
||||
int test_own_addr1(int my_cpu);
|
||||
|
||||
int test_own_addr2(int my_vcpu, int stage);
|
||||
int test_own_addr2(int my_cpu, int stage);
|
||||
|
||||
int test_mov_inv_fixed(int my_vcpu, int iterations, testword_t pattern1, testword_t pattern2);
|
||||
int test_mov_inv_fixed(int my_cpu, int iterations, testword_t pattern1, testword_t pattern2);
|
||||
|
||||
int test_mov_inv_walk1(int my_vcpu, int iterations, int offset, bool inverse);
|
||||
int test_mov_inv_walk1(int my_cpu, int iterations, int offset, bool inverse);
|
||||
|
||||
int test_mov_inv_random(int my_vcpu);
|
||||
int test_mov_inv_random(int my_cpu);
|
||||
|
||||
int test_modulo_n(int my_vcpu, int iterations, testword_t pattern1, testword_t pattern2, int n, int offset);
|
||||
int test_modulo_n(int my_cpu, int iterations, testword_t pattern1, testword_t pattern2, int n, int offset);
|
||||
|
||||
int test_block_move(int my_vcpu, int iterations);
|
||||
int test_block_move(int my_cpu, int iterations);
|
||||
|
||||
int test_bit_fade(int my_vcpu, int stage, int sleep_secs);
|
||||
int test_bit_fade(int my_cpu, int stage, int sleep_secs);
|
||||
|
||||
#endif // TEST_FUNCS_H
|
||||
|
||||
+22
-21
@@ -1,5 +1,5 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
// Copyright (C) 2020-2021 Martin Whitaker.
|
||||
// Copyright (C) 2020-2022 Martin Whitaker.
|
||||
//
|
||||
// Partly derived from an extract of memtest86+ test.c:
|
||||
//
|
||||
@@ -16,6 +16,7 @@
|
||||
#include <stdint.h>
|
||||
|
||||
#include "cache.h"
|
||||
#include "smp.h"
|
||||
|
||||
#include "barrier.h"
|
||||
|
||||
@@ -40,22 +41,22 @@ typedef struct {
|
||||
// Private Variables
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
static prsg_state_t prsg_state[MAX_VCPUS];
|
||||
static prsg_state_t prsg_state[MAX_CPUS];
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Private Functions
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
static inline uint32_t prsg(int my_vcpu)
|
||||
static inline uint32_t prsg(int my_cpu)
|
||||
{
|
||||
// This implements a 64 bit linear feedback shift register with XNOR
|
||||
// feedback from taps 64, 63, 61, 60. It generates 32 new bits each
|
||||
// time the function is called. Because the feedback taps are all in
|
||||
// the upper 32 bits, we can generate the new bits in parallel.
|
||||
|
||||
uint64_t lfsr = prsg_state[my_vcpu].lfsr;
|
||||
uint64_t lfsr = prsg_state[my_cpu].lfsr;
|
||||
uint32_t feedback = ~((lfsr >> 32) ^ (lfsr >> 31) ^ (lfsr >> 29) ^ (lfsr >> 28));
|
||||
prsg_state[my_vcpu].lfsr = (lfsr << 32) | feedback;
|
||||
prsg_state[my_cpu].lfsr = (lfsr << 32) | feedback;
|
||||
return feedback;
|
||||
}
|
||||
|
||||
@@ -63,9 +64,9 @@ static inline uint32_t prsg(int my_vcpu)
|
||||
// Public Functions
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
void random_seed(int my_vcpu, uint64_t seed)
|
||||
void random_seed(int my_cpu, uint64_t seed)
|
||||
{
|
||||
if (my_vcpu < 0) {
|
||||
if (my_cpu < 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -73,38 +74,38 @@ void random_seed(int my_vcpu, uint64_t seed)
|
||||
if (~seed == 0) {
|
||||
seed = 0;
|
||||
}
|
||||
prsg_state[my_vcpu].lfsr = seed;
|
||||
prsg_state[my_cpu].lfsr = seed;
|
||||
}
|
||||
|
||||
testword_t random(int my_vcpu)
|
||||
testword_t random(int my_cpu)
|
||||
{
|
||||
if (my_vcpu < 0) {
|
||||
if (my_cpu < 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
testword_t value = prsg(my_vcpu);
|
||||
testword_t value = prsg(my_cpu);
|
||||
#if TESTWORD_WIDTH > 32
|
||||
value = value << 32 | prsg(my_vcpu);
|
||||
value = value << 32 | prsg(my_cpu);
|
||||
#endif
|
||||
return value;
|
||||
}
|
||||
|
||||
void calculate_chunk(testword_t **start, testword_t **end, int my_vcpu, int segment, size_t chunk_align)
|
||||
void calculate_chunk(testword_t **start, testword_t **end, int my_cpu, int segment, size_t chunk_align)
|
||||
{
|
||||
if (my_vcpu < 0) {
|
||||
my_vcpu = 0;
|
||||
if (my_cpu < 0) {
|
||||
my_cpu = 0;
|
||||
}
|
||||
|
||||
// If we are only running 1 CPU then test the whole segment.
|
||||
if (num_vcpus == 1) {
|
||||
if (num_active_cpus == 1) {
|
||||
*start = vm_map[segment].start;
|
||||
*end = vm_map[segment].end;
|
||||
} else {
|
||||
uintptr_t segment_size = (vm_map[segment].end - vm_map[segment].start + 1) * sizeof(testword_t);
|
||||
uintptr_t chunk_size = round_down(segment_size / num_vcpus, chunk_align);
|
||||
uintptr_t chunk_size = round_down(segment_size / num_active_cpus, chunk_align);
|
||||
|
||||
// Calculate chunk boundaries.
|
||||
*start = (testword_t *)((uintptr_t)vm_map[segment].start + chunk_size * my_vcpu);
|
||||
*start = (testword_t *)((uintptr_t)vm_map[segment].start + chunk_size * my_cpu);
|
||||
*end = (testword_t *)((uintptr_t)(*start) + chunk_size) - 1;
|
||||
|
||||
if (*end > vm_map[segment].end) {
|
||||
@@ -113,11 +114,11 @@ void calculate_chunk(testword_t **start, testword_t **end, int my_vcpu, int segm
|
||||
}
|
||||
}
|
||||
|
||||
void flush_caches(int my_vcpu)
|
||||
void flush_caches(int my_cpu)
|
||||
{
|
||||
if (my_vcpu >= 0) {
|
||||
if (my_cpu >= 0) {
|
||||
barrier_wait(run_barrier);
|
||||
if (my_vcpu == master_vcpu) {
|
||||
if (my_cpu == master_cpu) {
|
||||
cache_flush();
|
||||
}
|
||||
barrier_wait(run_barrier);
|
||||
|
||||
+8
-8
@@ -5,7 +5,7 @@
|
||||
* Provides some common definitions and helper functions for the memory
|
||||
* tests.
|
||||
*
|
||||
* Copyright (C) 2020-2021 Martin Whitaker.
|
||||
* Copyright (C) 2020-2022 Martin Whitaker.
|
||||
*/
|
||||
|
||||
#include <stddef.h>
|
||||
@@ -60,28 +60,28 @@ static inline uintptr_t round_up(uintptr_t value, size_t align_size)
|
||||
}
|
||||
|
||||
/*
|
||||
* Seeds the psuedo-random number generator for my_vcpu.
|
||||
* Seeds the psuedo-random number generator for my_cpu.
|
||||
*/
|
||||
void random_seed(int my_vcpu, uint64_t seed);
|
||||
void random_seed(int my_cpu, uint64_t seed);
|
||||
|
||||
/*
|
||||
* Returns a psuedo-random number for my_vcpu. The sequence of numbers returned
|
||||
* Returns a psuedo-random number for my_cpu. The sequence of numbers returned
|
||||
* is repeatable for a given starting seed. The sequence repeats after 2^64 - 1
|
||||
* numbers. Within that period, no number is repeated.
|
||||
*/
|
||||
testword_t random(int my_vcpu);
|
||||
testword_t random(int my_cpu);
|
||||
|
||||
/*
|
||||
* Calculates the start and end word address for the chunk of segment that is
|
||||
* to be tested by my_vcpu. The chunk start will be aligned to a multiple of
|
||||
* to be tested by my_cpu. The chunk start will be aligned to a multiple of
|
||||
* chunk_align.
|
||||
*/
|
||||
void calculate_chunk(testword_t **start, testword_t **end, int my_vcpu, int segment, size_t chunk_align);
|
||||
void calculate_chunk(testword_t **start, testword_t **end, int my_cpu, int segment, size_t chunk_align);
|
||||
|
||||
/*
|
||||
* Flushes the CPU caches. If SMP is enabled, synchronises the threads before
|
||||
* and after issuing the cache flush instruction.
|
||||
*/
|
||||
void flush_caches(int my_vcpu);
|
||||
void flush_caches(int my_cpu);
|
||||
|
||||
#endif // TEST_HELPER_H
|
||||
|
||||
+26
-26
@@ -1,5 +1,5 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
// Copyright (C) 2020 Martin Whitaker.
|
||||
// Copyright (C) 2020-2022 Martin Whitaker.
|
||||
//
|
||||
// Derived from an extract of memtest86+ main.c:
|
||||
//
|
||||
@@ -74,16 +74,16 @@ int ticks_per_test[NUM_PASS_TYPES][NUM_TEST_PATTERNS];
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
#define BARRIER \
|
||||
if (my_vcpu >= 0) { \
|
||||
if (my_cpu >= 0) { \
|
||||
if (TRACE_BARRIERS) { \
|
||||
trace(my_vcpu, "Run barrier wait at %s line %i", __FILE__, __LINE__); \
|
||||
trace(my_cpu, "Run barrier wait at %s line %i", __FILE__, __LINE__); \
|
||||
} \
|
||||
barrier_wait(run_barrier); \
|
||||
}
|
||||
|
||||
int run_test(int my_vcpu, int test, int stage, int iterations)
|
||||
int run_test(int my_cpu, int test, int stage, int iterations)
|
||||
{
|
||||
if (my_vcpu == master_vcpu) {
|
||||
if (my_cpu == master_cpu) {
|
||||
if ((uintptr_t)&_start > LOW_LOAD_ADDR) {
|
||||
// Relocated so we need to test all selected lower memory.
|
||||
vm_map[0].start = first_word_mapping(pm_limit_lower);
|
||||
@@ -107,20 +107,20 @@ int run_test(int my_vcpu, int test, int stage, int iterations)
|
||||
// Address test, walking ones.
|
||||
case 0:
|
||||
cache_off();
|
||||
ticks += test_addr_walk1(my_vcpu);
|
||||
ticks += test_addr_walk1(my_cpu);
|
||||
cache_on();
|
||||
BAILOUT;
|
||||
break;
|
||||
|
||||
// Address test, own address in window.
|
||||
case 1:
|
||||
ticks += test_own_addr1(my_vcpu);
|
||||
ticks += test_own_addr1(my_cpu);
|
||||
BAILOUT;
|
||||
break;
|
||||
|
||||
// Address test, own address + window.
|
||||
case 2:
|
||||
ticks += test_own_addr2(my_vcpu, stage);
|
||||
ticks += test_own_addr2(my_cpu, stage);
|
||||
BAILOUT;
|
||||
break;
|
||||
|
||||
@@ -130,11 +130,11 @@ int run_test(int my_vcpu, int test, int stage, int iterations)
|
||||
testword_t pattern2 = ~pattern1;
|
||||
|
||||
BARRIER;
|
||||
ticks += test_mov_inv_fixed(my_vcpu, iterations, pattern1, pattern2);
|
||||
ticks += test_mov_inv_fixed(my_cpu, iterations, pattern1, pattern2);
|
||||
BAILOUT;
|
||||
|
||||
BARRIER;
|
||||
ticks += test_mov_inv_fixed(my_vcpu, iterations, pattern2, pattern1);
|
||||
ticks += test_mov_inv_fixed(my_cpu, iterations, pattern2, pattern1);
|
||||
BAILOUT;
|
||||
} break;
|
||||
|
||||
@@ -149,11 +149,11 @@ int run_test(int my_vcpu, int test, int stage, int iterations)
|
||||
testword_t pattern2 = ~pattern1;
|
||||
|
||||
BARRIER;
|
||||
ticks += test_mov_inv_fixed(my_vcpu, iterations, pattern1, pattern2);
|
||||
ticks += test_mov_inv_fixed(my_cpu, iterations, pattern1, pattern2);
|
||||
BAILOUT;
|
||||
|
||||
BARRIER;
|
||||
ticks += test_mov_inv_fixed(my_vcpu, iterations, pattern2, pattern1);
|
||||
ticks += test_mov_inv_fixed(my_cpu, iterations, pattern2, pattern1);
|
||||
BAILOUT;
|
||||
|
||||
pattern1 >>= 1;
|
||||
@@ -163,16 +163,16 @@ int run_test(int my_vcpu, int test, int stage, int iterations)
|
||||
// Moving inversions, fixed random pattern.
|
||||
case 5:
|
||||
if (cpuid_info.flags.rdtsc) {
|
||||
random_seed(my_vcpu, get_tsc());
|
||||
random_seed(my_cpu, get_tsc());
|
||||
} else {
|
||||
random_seed(my_vcpu, UINT64_C(0x12345678) * (1 + pass_num));
|
||||
random_seed(my_cpu, UINT64_C(0x12345678) * (1 + pass_num));
|
||||
}
|
||||
for (int i = 0; i < iterations; i++) {
|
||||
testword_t pattern1 = random(my_vcpu);
|
||||
testword_t pattern1 = random(my_cpu);
|
||||
testword_t pattern2 = ~pattern1;
|
||||
|
||||
BARRIER;
|
||||
ticks += test_mov_inv_fixed(my_vcpu, 2, pattern1, pattern2);
|
||||
ticks += test_mov_inv_fixed(my_cpu, 2, pattern1, pattern2);
|
||||
BAILOUT;
|
||||
}
|
||||
break;
|
||||
@@ -181,18 +181,18 @@ int run_test(int my_vcpu, int test, int stage, int iterations)
|
||||
case 6:
|
||||
for (int offset = 0; offset < TESTWORD_WIDTH; offset++) {
|
||||
BARRIER;
|
||||
ticks += test_mov_inv_walk1(my_vcpu, iterations, offset, false);
|
||||
ticks += test_mov_inv_walk1(my_cpu, iterations, offset, false);
|
||||
BAILOUT;
|
||||
|
||||
BARRIER;
|
||||
ticks += test_mov_inv_walk1(my_vcpu, iterations, offset, true);
|
||||
ticks += test_mov_inv_walk1(my_cpu, iterations, offset, true);
|
||||
BAILOUT;
|
||||
}
|
||||
break;
|
||||
|
||||
// Block move.
|
||||
case 7:
|
||||
ticks += test_block_move(my_vcpu, iterations);
|
||||
ticks += test_block_move(my_cpu, iterations);
|
||||
BAILOUT;
|
||||
break;
|
||||
|
||||
@@ -200,7 +200,7 @@ int run_test(int my_vcpu, int test, int stage, int iterations)
|
||||
case 8:
|
||||
for (int i = 0; i < iterations; i++) {
|
||||
BARRIER;
|
||||
ticks += test_mov_inv_random(my_vcpu);
|
||||
ticks += test_mov_inv_random(my_cpu);
|
||||
BAILOUT;
|
||||
}
|
||||
break;
|
||||
@@ -208,21 +208,21 @@ int run_test(int my_vcpu, int test, int stage, int iterations)
|
||||
// Modulo 20 check, fixed random pattern.
|
||||
case 9:
|
||||
if (cpuid_info.flags.rdtsc) {
|
||||
random_seed(my_vcpu, get_tsc());
|
||||
random_seed(my_cpu, get_tsc());
|
||||
} else {
|
||||
random_seed(my_vcpu, UINT64_C(0x12345678) * (1 + pass_num));
|
||||
random_seed(my_cpu, UINT64_C(0x12345678) * (1 + pass_num));
|
||||
}
|
||||
for (int i = 0; i < iterations; i++) {
|
||||
for (int offset = 0; offset < MODULO_N; offset++) {
|
||||
testword_t pattern1 = random(my_vcpu);
|
||||
testword_t pattern1 = random(my_cpu);
|
||||
testword_t pattern2 = ~pattern1;
|
||||
|
||||
BARRIER;
|
||||
ticks += test_modulo_n(my_vcpu, 2, pattern1, pattern2, MODULO_N, offset);
|
||||
ticks += test_modulo_n(my_cpu, 2, pattern1, pattern2, MODULO_N, offset);
|
||||
BAILOUT;
|
||||
|
||||
BARRIER;
|
||||
ticks += test_modulo_n(my_vcpu, 2, pattern2, pattern1, MODULO_N, offset);
|
||||
ticks += test_modulo_n(my_cpu, 2, pattern2, pattern1, MODULO_N, offset);
|
||||
BAILOUT;
|
||||
}
|
||||
}
|
||||
@@ -230,7 +230,7 @@ int run_test(int my_vcpu, int test, int stage, int iterations)
|
||||
|
||||
// Bit fade test.
|
||||
case 10:
|
||||
ticks += test_bit_fade(my_vcpu, stage, iterations);
|
||||
ticks += test_bit_fade(my_cpu, stage, iterations);
|
||||
BAILOUT;
|
||||
break;
|
||||
}
|
||||
|
||||
+2
-2
@@ -4,7 +4,7 @@
|
||||
/*
|
||||
* Provides support for identifying and running the memory tests.
|
||||
*
|
||||
* Copyright (C) 2020 Martin Whitaker.
|
||||
* Copyright (C) 2020-2022 Martin Whitaker.
|
||||
*/
|
||||
|
||||
#include <stdbool.h>
|
||||
@@ -29,6 +29,6 @@ typedef enum { FAST_PASS, FULL_PASS, NUM_PASS_TYPES } pass_type_t;
|
||||
extern int ticks_per_pass[NUM_PASS_TYPES];
|
||||
extern int ticks_per_test[NUM_PASS_TYPES][NUM_TEST_PATTERNS];
|
||||
|
||||
int run_test(int my_vcpu, int test, int stage, int iterations);
|
||||
int run_test(int my_cpu, int test, int stage, int iterations);
|
||||
|
||||
#endif // TESTS_H
|
||||
|
||||
Reference in New Issue
Block a user