2020-05-24 23:30:55 +03:00
|
|
|
// SPDX-License-Identifier: GPL-2.0
|
2022-01-29 01:01:36 +03:00
|
|
|
// Copyright (C) 2020-2022 Martin Whitaker.
|
2023-11-29 14:53:05 +03:00
|
|
|
// Copyright (C) 2004-2023 Sam Demeulemeester.
|
2020-05-24 23:30:55 +03:00
|
|
|
|
|
|
|
#include <stdbool.h>
|
|
|
|
#include <stdint.h>
|
|
|
|
|
|
|
|
#include "cpuid.h"
|
|
|
|
#include "cpuinfo.h"
|
|
|
|
#include "hwctrl.h"
|
|
|
|
#include "io.h"
|
|
|
|
#include "keyboard.h"
|
2023-05-12 16:33:28 +03:00
|
|
|
#include "memctrl.h"
|
2022-04-04 19:31:54 +03:00
|
|
|
#include "serial.h"
|
2020-05-24 23:30:55 +03:00
|
|
|
#include "pmem.h"
|
2022-03-12 05:09:22 +03:00
|
|
|
#include "smbios.h"
|
2022-03-14 07:35:36 +03:00
|
|
|
#include "smbus.h"
|
Split SPD parsing and printing code from smbus.c to spd.c (#426)
* Split SPD parsing and printing code from smbus.c to spd.c
Move all SPD parsing and printing code from smbus.{c,h} to spd.{c,h}.
Introduce parse_spd() function, moving the parse_spd_* selection logic
from print_smbus_startup_info(), allowing to keep parse_spd_* static.
Remove static from get_spd() and update print_smbus_startup_info()
to use parse_spd() which also simplifies the code flow.
Move LINE_SPD into display.h and rename it to ROW_SPD. Update print_spdi()
to use explicit row number where the SPD info needs to be printed.
Rename ram_info into ram_info_t, rename print_smbus_startup_info()
into print_spd_startup_info.
Do not initialize ram.freq to 0, this is the initial value already.
Do not set curspd.isValid to False, the first thing that parse_spd()
does is setting the entire struct to 0, that also sets isValid to False.
print_spd_startup_info() from smbus.c is technically a skeleton now
so each arch can have its own version, adjusted as needed. Once
LA64 changes land, we can think how we can even make it arch agnostic.
* Add -fexcess-precision=standard to CFLAGS for build(32,64)/Makefile
Recent switch from -std=c11 to -std=gnu11 done in 53ca89f ("Add
initial NUMA awareness support") introduced a regression in SPD
parsing code (and potentially in other places) due to change of
floating point precision. Restore the original behavior by
adding -fexcess-precision=standard to CFLAGS.
Bug: https://github.com/memtest86plus/memtest86plus/issues/425
Fixes: https://github.com/memtest86plus/memtest86plus/commit/53ca89f8aeeea649a1b8c2d2d14ec121f7025f54
2024-08-08 03:41:19 +03:00
|
|
|
#include "spd.h"
|
2020-05-24 23:30:55 +03:00
|
|
|
#include "temperature.h"
|
|
|
|
#include "tsc.h"
|
|
|
|
|
|
|
|
#include "barrier.h"
|
|
|
|
#include "spinlock.h"
|
|
|
|
|
|
|
|
#include "config.h"
|
|
|
|
#include "error.h"
|
2023-01-03 02:39:10 +03:00
|
|
|
#include "build_version.h"
|
2020-05-24 23:30:55 +03:00
|
|
|
|
|
|
|
#include "tests.h"
|
|
|
|
|
|
|
|
#include "display.h"
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
// Constants
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
|
2022-07-17 21:20:52 +03:00
|
|
|
#define POP_STAT_R 12
|
|
|
|
#define POP_STAT_C 18
|
|
|
|
|
|
|
|
#define POP_STAT_W 44
|
2022-11-28 01:34:43 +03:00
|
|
|
#define POP_STAT_H 11
|
2022-07-17 21:20:52 +03:00
|
|
|
|
|
|
|
#define POP_STAT_LAST_R (POP_STAT_R + POP_STAT_H - 1)
|
|
|
|
#define POP_STAT_LAST_C (POP_STAT_C + POP_STAT_W - 1)
|
|
|
|
|
|
|
|
#define POP_STATUS_REGION POP_STAT_R, POP_STAT_C, POP_STAT_LAST_R, POP_STAT_LAST_C
|
|
|
|
|
2022-01-29 02:06:23 +03:00
|
|
|
#define SPINNER_PERIOD 100 // milliseconds
|
|
|
|
|
2020-05-24 23:30:55 +03:00
|
|
|
#define NUM_SPIN_STATES 4
|
|
|
|
|
|
|
|
static const char spin_state[NUM_SPIN_STATES] = { '|', '/', '-', '\\' };
|
|
|
|
|
2022-09-19 08:39:17 +03:00
|
|
|
static const char cpu_mode_str[3][4] = { "PAR", "SEQ", "RR " };
|
2022-04-11 20:37:52 +03:00
|
|
|
|
2020-05-24 23:30:55 +03:00
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
// Private Variables
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
static bool scroll_lock = false;
|
|
|
|
static bool scroll_wait = false;
|
|
|
|
|
2022-01-29 01:01:36 +03:00
|
|
|
static int spin_idx = 0; // current spinner position
|
2020-05-24 23:30:55 +03:00
|
|
|
|
|
|
|
static int pass_ticks = 0; // current value (ticks_per_pass is final value)
|
|
|
|
static int test_ticks = 0; // current value (ticks_per_test is final value)
|
|
|
|
|
|
|
|
static int pass_bar_length = 0; // currently displayed length
|
|
|
|
static int test_bar_length = 0; // currently displayed length
|
|
|
|
|
|
|
|
static uint64_t run_start_time = 0; // TSC time stamp
|
2022-01-29 02:06:23 +03:00
|
|
|
static uint64_t next_spin_time = 0; // TSC time stamp
|
2020-05-24 23:30:55 +03:00
|
|
|
|
2022-04-04 19:31:54 +03:00
|
|
|
static int prev_sec = -1; // previous second
|
|
|
|
static bool timed_update_done = false; // update cycle status
|
|
|
|
|
2022-07-17 21:20:52 +03:00
|
|
|
bool big_status_displayed = false;
|
|
|
|
static uint16_t popup_status_save_buffer[POP_STAT_W * POP_STAT_H];
|
|
|
|
|
2020-05-24 23:30:55 +03:00
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
// Variables
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
int scroll_message_row;
|
|
|
|
|
2022-04-07 03:27:41 +03:00
|
|
|
int max_cpu_temp = 0;
|
|
|
|
|
2022-04-15 18:04:22 +03:00
|
|
|
display_mode_t display_mode = DISPLAY_MODE_NA;
|
|
|
|
|
2020-05-24 23:30:55 +03:00
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
// Public Functions
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
void display_init(void)
|
|
|
|
{
|
|
|
|
cursor_off();
|
|
|
|
|
|
|
|
clear_screen();
|
|
|
|
|
2022-06-19 17:40:30 +03:00
|
|
|
/* The commented horizontal lines provide visual cue for where and how
|
|
|
|
* they will appear on the screen. They are drawn down below using
|
|
|
|
* Extended ASCII characters.
|
|
|
|
*/
|
|
|
|
|
2022-04-07 01:54:40 +03:00
|
|
|
set_foreground_colour(BLACK);
|
2020-05-24 23:30:55 +03:00
|
|
|
set_background_colour(WHITE);
|
|
|
|
clear_screen_region(0, 0, 0, 27);
|
2023-01-03 02:39:10 +03:00
|
|
|
prints(0, 0, " Memtest86+ v" MT_VERSION);
|
2022-04-07 01:54:40 +03:00
|
|
|
set_foreground_colour(RED);
|
2022-10-23 21:21:09 +03:00
|
|
|
printc(0, 15, '+');
|
2020-05-24 23:30:55 +03:00
|
|
|
set_foreground_colour(WHITE);
|
|
|
|
set_background_colour(BLUE);
|
2022-06-19 17:40:30 +03:00
|
|
|
prints(1, 0, "CLK/Temp: N/A | Pass %");
|
|
|
|
prints(2, 0, "L1 Cache: N/A | Test %");
|
|
|
|
prints(3, 0, "L2 Cache: N/A | Test #");
|
|
|
|
prints(4, 0, "L3 Cache: N/A | Testing:");
|
|
|
|
prints(5, 0, "Memory : N/A | Pattern:");
|
|
|
|
// prints(6, 0, "--------------------------------------------------------------------------------");
|
|
|
|
prints(7, 0, "CPU: SMP: N/A | Time: Status: Init.");
|
|
|
|
prints(8, 0, "Using: | Pass: Errors:");
|
|
|
|
// prints(9, 0, "--------------------------------------------------------------------------------");
|
|
|
|
|
2023-11-29 14:53:05 +03:00
|
|
|
if (ecc_status.ecc_enabled) {
|
|
|
|
prints(8, 57, "Err: ECC:");
|
|
|
|
}
|
|
|
|
|
2022-06-19 17:40:30 +03:00
|
|
|
for (int i = 0;i < 80; i++) {
|
|
|
|
print_char(6, i, 0xc4);
|
|
|
|
print_char(9, i, 0xc4);
|
|
|
|
}
|
|
|
|
for (int i = 0; i < 6; i++) {
|
|
|
|
print_char(i, 28, 0xb3);
|
2020-05-24 23:30:55 +03:00
|
|
|
}
|
2022-06-19 17:40:30 +03:00
|
|
|
for (int i = 7; i < 10; i++) {
|
|
|
|
print_char(i, 42, 0xb3);
|
|
|
|
}
|
|
|
|
|
|
|
|
print_char(6, 28, 0xc1);
|
|
|
|
print_char(6, 42, 0xc2);
|
|
|
|
print_char(9, 42, 0xc1);
|
2020-05-24 23:30:55 +03:00
|
|
|
|
|
|
|
set_foreground_colour(BLUE);
|
|
|
|
set_background_colour(WHITE);
|
|
|
|
clear_screen_region(ROW_FOOTER, 0, ROW_FOOTER, SCREEN_WIDTH - 1);
|
2022-04-08 20:26:31 +03:00
|
|
|
prints(ROW_FOOTER, 0, " <ESC> Exit <F1> Configuration <Space> Scroll Lock");
|
2023-01-03 02:39:10 +03:00
|
|
|
prints(ROW_FOOTER, 64, MT_VERSION "." GIT_HASH);
|
Add LoongArch support (#410)
* lib/assert: Add LoongArch assert support
Added LoongArch break 3 assert instruction.
Signed-off-by: Chao Li <lichao@loongson.cn>
* lib/barrier: Add barrier method for LoongArch
Added LoongArch barriers in barrier_spin_wait and barrier_halt_wait
functions.
Signed-off-by: Chao Li <lichao@loognson.cn>
* lib/spinlock: Add LoongArch CPU pause
Because the LoongArch haven't pause instruction, using eight nops to
replace the pause.
Signed-off-by: Chao Li <lichao@loongson.cn>
* lib/string: Make LoongArch use the string function in the file
Since LoongArch GCC doesn't have built-in string functions, use the
string function instance in the sting.c
Signed-off-by: Chao Li <lichao@loongson.cn>
* lib/unistd: Add LoongArch CPU pause
Because the LoongArch haven't pause instruction, using eight nops to
replace the pause.
Signed-off-by: Chao Li <lichao@loongson.cn>
* system/acpi: Reduce the way of search RSDP for non-x86 ARCHs
Searching RSDP from legacy BIOS EDBA and reserved areas is available
only on i386 and x64.
Signed-off-by: Chao Li <lichao@loongson.cn>
* system/cache: Add LoongArch64 cache operations support
Added cache operations support for LoongArch64.
Signed-off-by: Chao Li <lichao@loongson.cn>
* system/cpuid: Add the compile limit
Make the `cpuid` function action only on i386/x64.
Signed-off-by: Chao Li <lichao@loongson.cn>
* system/heap: Add heap support for LoongArch64
LoongArch64 uses the low 256MB as the low memory.
Signed-off-by: Chao Li <lichao@loongson.cn>
* system/memrw: Add 8-bit and 16-bit memory operations
Added 8-bit and 16-bit memory access operations, which 8-bit uses
`movb` and 16-bit is `movw`.
Signed-off-by: Chao Li <lichao@loongson.cn>
* system/memrw: Add LoongArch memory access operations
Added 8/16/32/64-bit memory access operations for LoongArch64.
Signed-off-by: Chao Li <lichao@loongson.cn>
* system: Add Loongson PCI vendor ID and Loongson 7A chipset EHCI workaround
1. Added Loongson PCI vendor ID.
2. Added Loongson 7A chipset ECHI workaround.
Signed-off-by: Chao Li <lichao@loongson.cn>
* system/io: Add LoongArch64 IO port operations
Added IO port operations for LoongArch64.
Signed-off-by: Chao Li <lichao@loongson.cn>
* system/reloc64: Add LoongArch64 relocations support
Added R_LARCH_RELATIVE and R_LARCH_NONE relocations support for
LoongArch64.
Signed-off-by: Chao Li <lichao@loongson.cn>
* system/serial: Add Loongson CPU serial port support
Add the serial port address perfix of Loongson CPU and obtain serial
port clock method.
Signed-off-by: Chao Li <lichao@loongson.cn>
* system/smbus: Rename smbus.c to i2c_x86.c
Renamed the smbus.c to i2c_x86.c in i386 and x64 platforms.
Signed-off-by: Chao Li <lichao@loongson.cn>
* system/smp: Add LoongArch SMP support
Added LoongArch multi-core support and a way of map to node numbers if
the NUMA is enabled.
Signed-off-by: Chao Li <lichao@loongson.cn>
* system/timers: Add LoongArch supports
In LoongArch, there is a stable counter that is independent of other
clocks, it like the TSC in x64. Using it to count the ticks per
millisecond.
Signed-off-by: Chao Li <lichao@loongson.cn>
* system/tsc: Add LoongArch support
Usually the frequency of stable counter is not same to CPU frequency, so
using the performance counter for the delay operations.
Signed-off-by: Chao Li <lichao@loongson.cn>
* system/usbhcd: Add LoongArch MMIO perfix
Added LoongArch64 MMIO address perfix, use for address the PCI memory
space.
Signed-off-by: Chao Li <lichao@loongson.cn>
* system/usbhcd: Add Loongson 7A2000 chipset OHCI BAR offset fix
If the BAR address is not fixed for the Loongson 7A2000 OHCI controller,
some prots will not be usable, This change currently only affects the
LoongArch platform.
Signed-off-by: Chao Li <lichao@loongson.cn>
* system: Add the way to IO access via MMIO
Usually, it is access the IO like PCI IO via MMIO on non-X86 ARCHs, so
a method to access IO via MMIO is added.
Signed-off-by: Chao Li <lichao@loongson.cn>
* system: Add the way to access PCI memory space via MMIO
Some uniformly address ARCHs access the PCI memory depended the MMIO, so
the method to access PCI memory via MMIO is added.
Signed-off-by: Chao Li <lichao@loongson.cn>
* app: Add LoongArch version support
Reduced the version field by two characters to support ARCH name
abbreviations with more than three characters, and added "la64" ARCH
version display.
Singed-off-by: Chao Li <lichao@loongson.cn>
* test/block_move: Add block move test via ASM for LoongArch
Add block move test inline assembly instance for LoongArch.
Signed-off-by: Chao Li <lichao@loongson.cn>
* test/mov_inv_fixed: Add LoongArch ASM version word write operation
Add LoongArch ASM version word write cycle if it uses the HAND_OPTIMISED.
Signed-off-by: Chao Li <lichao@loongson.cn>
* boot: Adjust the AP stack size for LoongArch
LoongArch exception will store all of the GP, FP and CSR on stack, it
need more stack size, make LoongArch AP using 2KB stack size.
Signed-off-by: Chao Li <lichao@loongson.cn>
* boot/efisetup: Add LoongArch CPU halt instruction
Add "idle 0" for LoongArch
Signed-off-by: Chao Li <lichao@loongson.cn>
* boot/efi: Limiting the ms_abi using scope
Make the ms_abi only work on i386 and x64.
Signed-off-by: Chao Li <lichao@loongson.cn>
* system/imc/loongson: Add Loongson LoongArch IMC support
Added the Loongson LoongArch CPU IMC instance, support read out the IMC
sequence, currently only supports reading MC0.
Signed-off-by: Chao Li <lichao@loongson.cn>
* app/loongarch: Add intrrupt handler for LoongArch
Added the LoongArch IRQ handler support.
Signed-off-by: Chao Li <lichao@loongson.cn>
* system/loongarch: Add LoongArch ARCH specific files
Added LoongArch ARCH specific files: cpuid.c, cpuinfo.c, hwctrl.c,
memctrl.c, temperature.c, vmem.c, registers.h
They use the same pubilc API for i386 and x64 platforms.
Signed-off-by: Chao Li <lichao@loongson.cn>
* boot: Add LoongArch startup and header
Added the header.S and startup64.S for LoongArch, CPU works on:
1. Page mode.
2. Load and store is cacheable.
3. Instructions is cacheable.
4. DMWn 0 and 1 is used.
5. To access non-cacheable areas, use the perfix 0x8000000000000000.
Signed-off Chao Li <lichao@loongson.cn>
* build64/la64: Add LoongArch64 build files
Add infrastructure files to build memtest86 plus for LoongArch64
platform.
Signed-off-by: Chao Li <lichao@loongson.cn>
* workflows: Add LoongArch64 CI supports
Adjust workflow logci, remvoe 32 and 64 wordsize, replace with "i386,
x86_64 and la64", add LoongArch64 build CI check.
Signed-off-by: Chao Li <lichao@loongson.cn>
---------
Signed-off-by: Chao Li <lichao@loongson.cn>
Signed-off-by: Chao Li <lichao@loognson.cn>
2024-08-30 14:38:46 +03:00
|
|
|
#if defined (__x86_64__)
|
|
|
|
prints(ROW_FOOTER, 74, ".x64");
|
|
|
|
#elif defined (__i386__)
|
|
|
|
prints(ROW_FOOTER, 74, ".x32");
|
|
|
|
#elif defined (__loongarch_lp64)
|
|
|
|
prints(ROW_FOOTER, 74, ".la64");
|
2022-04-07 02:48:27 +03:00
|
|
|
#endif
|
Add LoongArch support (#410)
* lib/assert: Add LoongArch assert support
Added LoongArch break 3 assert instruction.
Signed-off-by: Chao Li <lichao@loongson.cn>
* lib/barrier: Add barrier method for LoongArch
Added LoongArch barriers in barrier_spin_wait and barrier_halt_wait
functions.
Signed-off-by: Chao Li <lichao@loognson.cn>
* lib/spinlock: Add LoongArch CPU pause
Because the LoongArch haven't pause instruction, using eight nops to
replace the pause.
Signed-off-by: Chao Li <lichao@loongson.cn>
* lib/string: Make LoongArch use the string function in the file
Since LoongArch GCC doesn't have built-in string functions, use the
string function instance in the sting.c
Signed-off-by: Chao Li <lichao@loongson.cn>
* lib/unistd: Add LoongArch CPU pause
Because the LoongArch haven't pause instruction, using eight nops to
replace the pause.
Signed-off-by: Chao Li <lichao@loongson.cn>
* system/acpi: Reduce the way of search RSDP for non-x86 ARCHs
Searching RSDP from legacy BIOS EDBA and reserved areas is available
only on i386 and x64.
Signed-off-by: Chao Li <lichao@loongson.cn>
* system/cache: Add LoongArch64 cache operations support
Added cache operations support for LoongArch64.
Signed-off-by: Chao Li <lichao@loongson.cn>
* system/cpuid: Add the compile limit
Make the `cpuid` function action only on i386/x64.
Signed-off-by: Chao Li <lichao@loongson.cn>
* system/heap: Add heap support for LoongArch64
LoongArch64 uses the low 256MB as the low memory.
Signed-off-by: Chao Li <lichao@loongson.cn>
* system/memrw: Add 8-bit and 16-bit memory operations
Added 8-bit and 16-bit memory access operations, which 8-bit uses
`movb` and 16-bit is `movw`.
Signed-off-by: Chao Li <lichao@loongson.cn>
* system/memrw: Add LoongArch memory access operations
Added 8/16/32/64-bit memory access operations for LoongArch64.
Signed-off-by: Chao Li <lichao@loongson.cn>
* system: Add Loongson PCI vendor ID and Loongson 7A chipset EHCI workaround
1. Added Loongson PCI vendor ID.
2. Added Loongson 7A chipset ECHI workaround.
Signed-off-by: Chao Li <lichao@loongson.cn>
* system/io: Add LoongArch64 IO port operations
Added IO port operations for LoongArch64.
Signed-off-by: Chao Li <lichao@loongson.cn>
* system/reloc64: Add LoongArch64 relocations support
Added R_LARCH_RELATIVE and R_LARCH_NONE relocations support for
LoongArch64.
Signed-off-by: Chao Li <lichao@loongson.cn>
* system/serial: Add Loongson CPU serial port support
Add the serial port address perfix of Loongson CPU and obtain serial
port clock method.
Signed-off-by: Chao Li <lichao@loongson.cn>
* system/smbus: Rename smbus.c to i2c_x86.c
Renamed the smbus.c to i2c_x86.c in i386 and x64 platforms.
Signed-off-by: Chao Li <lichao@loongson.cn>
* system/smp: Add LoongArch SMP support
Added LoongArch multi-core support and a way of map to node numbers if
the NUMA is enabled.
Signed-off-by: Chao Li <lichao@loongson.cn>
* system/timers: Add LoongArch supports
In LoongArch, there is a stable counter that is independent of other
clocks, it like the TSC in x64. Using it to count the ticks per
millisecond.
Signed-off-by: Chao Li <lichao@loongson.cn>
* system/tsc: Add LoongArch support
Usually the frequency of stable counter is not same to CPU frequency, so
using the performance counter for the delay operations.
Signed-off-by: Chao Li <lichao@loongson.cn>
* system/usbhcd: Add LoongArch MMIO perfix
Added LoongArch64 MMIO address perfix, use for address the PCI memory
space.
Signed-off-by: Chao Li <lichao@loongson.cn>
* system/usbhcd: Add Loongson 7A2000 chipset OHCI BAR offset fix
If the BAR address is not fixed for the Loongson 7A2000 OHCI controller,
some prots will not be usable, This change currently only affects the
LoongArch platform.
Signed-off-by: Chao Li <lichao@loongson.cn>
* system: Add the way to IO access via MMIO
Usually, it is access the IO like PCI IO via MMIO on non-X86 ARCHs, so
a method to access IO via MMIO is added.
Signed-off-by: Chao Li <lichao@loongson.cn>
* system: Add the way to access PCI memory space via MMIO
Some uniformly address ARCHs access the PCI memory depended the MMIO, so
the method to access PCI memory via MMIO is added.
Signed-off-by: Chao Li <lichao@loongson.cn>
* app: Add LoongArch version support
Reduced the version field by two characters to support ARCH name
abbreviations with more than three characters, and added "la64" ARCH
version display.
Singed-off-by: Chao Li <lichao@loongson.cn>
* test/block_move: Add block move test via ASM for LoongArch
Add block move test inline assembly instance for LoongArch.
Signed-off-by: Chao Li <lichao@loongson.cn>
* test/mov_inv_fixed: Add LoongArch ASM version word write operation
Add LoongArch ASM version word write cycle if it uses the HAND_OPTIMISED.
Signed-off-by: Chao Li <lichao@loongson.cn>
* boot: Adjust the AP stack size for LoongArch
LoongArch exception will store all of the GP, FP and CSR on stack, it
need more stack size, make LoongArch AP using 2KB stack size.
Signed-off-by: Chao Li <lichao@loongson.cn>
* boot/efisetup: Add LoongArch CPU halt instruction
Add "idle 0" for LoongArch
Signed-off-by: Chao Li <lichao@loongson.cn>
* boot/efi: Limiting the ms_abi using scope
Make the ms_abi only work on i386 and x64.
Signed-off-by: Chao Li <lichao@loongson.cn>
* system/imc/loongson: Add Loongson LoongArch IMC support
Added the Loongson LoongArch CPU IMC instance, support read out the IMC
sequence, currently only supports reading MC0.
Signed-off-by: Chao Li <lichao@loongson.cn>
* app/loongarch: Add intrrupt handler for LoongArch
Added the LoongArch IRQ handler support.
Signed-off-by: Chao Li <lichao@loongson.cn>
* system/loongarch: Add LoongArch ARCH specific files
Added LoongArch ARCH specific files: cpuid.c, cpuinfo.c, hwctrl.c,
memctrl.c, temperature.c, vmem.c, registers.h
They use the same pubilc API for i386 and x64 platforms.
Signed-off-by: Chao Li <lichao@loongson.cn>
* boot: Add LoongArch startup and header
Added the header.S and startup64.S for LoongArch, CPU works on:
1. Page mode.
2. Load and store is cacheable.
3. Instructions is cacheable.
4. DMWn 0 and 1 is used.
5. To access non-cacheable areas, use the perfix 0x8000000000000000.
Signed-off Chao Li <lichao@loongson.cn>
* build64/la64: Add LoongArch64 build files
Add infrastructure files to build memtest86 plus for LoongArch64
platform.
Signed-off-by: Chao Li <lichao@loongson.cn>
* workflows: Add LoongArch64 CI supports
Adjust workflow logci, remvoe 32 and 64 wordsize, replace with "i386,
x86_64 and la64", add LoongArch64 build CI check.
Signed-off-by: Chao Li <lichao@loongson.cn>
---------
Signed-off-by: Chao Li <lichao@loongson.cn>
Signed-off-by: Chao Li <lichao@loognson.cn>
2024-08-30 14:38:46 +03:00
|
|
|
|
2020-05-24 23:30:55 +03:00
|
|
|
set_foreground_colour(WHITE);
|
|
|
|
set_background_colour(BLUE);
|
|
|
|
|
|
|
|
if (cpu_model) {
|
|
|
|
display_cpu_model(cpu_model);
|
|
|
|
}
|
|
|
|
if (clks_per_msec) {
|
|
|
|
display_cpu_clk((int)(clks_per_msec / 1000));
|
|
|
|
}
|
2022-04-15 21:28:16 +03:00
|
|
|
#if TESTWORD_WIDTH < 64
|
2022-04-14 04:29:20 +03:00
|
|
|
if (cpuid_info.flags.lm) {
|
2022-04-15 21:28:16 +03:00
|
|
|
display_cpu_addr_mode(" [LM]");
|
2022-04-14 04:29:20 +03:00
|
|
|
} else if (cpuid_info.flags.pae) {
|
2022-04-15 21:28:16 +03:00
|
|
|
display_cpu_addr_mode("[PAE]");
|
2022-04-14 04:29:20 +03:00
|
|
|
}
|
2022-04-15 21:28:16 +03:00
|
|
|
#endif
|
2020-05-24 23:30:55 +03:00
|
|
|
if (l1_cache) {
|
|
|
|
display_l1_cache_size(l1_cache);
|
|
|
|
}
|
|
|
|
if (l2_cache) {
|
|
|
|
display_l2_cache_size(l2_cache);
|
|
|
|
}
|
|
|
|
if (l3_cache) {
|
|
|
|
display_l3_cache_size(l3_cache);
|
|
|
|
}
|
2022-03-20 21:49:56 +03:00
|
|
|
if (l1_cache_speed) {
|
|
|
|
display_l1_cache_speed(l1_cache_speed);
|
|
|
|
}
|
|
|
|
if (l2_cache_speed) {
|
|
|
|
display_l2_cache_speed(l2_cache_speed);
|
|
|
|
}
|
|
|
|
if (l3_cache_speed) {
|
|
|
|
display_l3_cache_speed(l3_cache_speed);
|
|
|
|
}
|
|
|
|
if (ram_speed) {
|
|
|
|
display_ram_speed(ram_speed);
|
|
|
|
}
|
2020-05-24 23:30:55 +03:00
|
|
|
if (num_pm_pages) {
|
|
|
|
// Round to nearest MB.
|
|
|
|
display_memory_size(1024 * ((num_pm_pages + 128) / 256));
|
|
|
|
}
|
|
|
|
|
|
|
|
scroll_message_row = ROW_SCROLL_T;
|
|
|
|
}
|
|
|
|
|
2022-04-11 20:37:52 +03:00
|
|
|
void display_cpu_topology(void)
|
|
|
|
{
|
|
|
|
extern int num_enabled_cpus;
|
|
|
|
int num_cpu_sockets = 1;
|
|
|
|
|
2022-07-16 14:28:53 +03:00
|
|
|
// Display Thread Count and Thread Dispatch Mode
|
2022-04-15 18:04:22 +03:00
|
|
|
if (smp_enabled) {
|
2022-07-16 14:28:53 +03:00
|
|
|
if (cpuid_info.topology.is_hybrid && cpuid_info.topology.ecore_count > 0 && exclude_ecores) {
|
|
|
|
display_threading(num_enabled_cpus - cpuid_info.topology.ecore_count, cpu_mode_str[cpu_mode]);
|
|
|
|
} else {
|
|
|
|
display_threading(num_enabled_cpus, cpu_mode_str[cpu_mode]);
|
|
|
|
}
|
2022-04-11 20:37:52 +03:00
|
|
|
} else {
|
2022-04-14 04:29:20 +03:00
|
|
|
display_threading_disabled();
|
2022-04-11 20:37:52 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
// If topology failed, assume topology according to APIC
|
2022-04-15 18:04:22 +03:00
|
|
|
if (cpuid_info.topology.core_count <= 0) {
|
2022-04-11 20:37:52 +03:00
|
|
|
|
|
|
|
cpuid_info.topology.core_count = num_enabled_cpus;
|
|
|
|
cpuid_info.topology.thread_count = num_enabled_cpus;
|
|
|
|
|
|
|
|
if(cpuid_info.flags.htt && num_enabled_cpus >= 2 && num_enabled_cpus % 2 == 0) {
|
|
|
|
cpuid_info.topology.core_count /= 2;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Compute number of sockets according to individual CPU core count
|
2022-04-15 18:04:22 +03:00
|
|
|
if (num_enabled_cpus > cpuid_info.topology.thread_count &&
|
2022-07-16 14:28:53 +03:00
|
|
|
num_enabled_cpus % cpuid_info.topology.thread_count == 0) {
|
2022-04-11 20:37:52 +03:00
|
|
|
num_cpu_sockets = num_enabled_cpus / cpuid_info.topology.thread_count;
|
|
|
|
}
|
|
|
|
|
2022-07-16 14:28:53 +03:00
|
|
|
// Display P/E-Core count for Hybrid CPUs.
|
2022-04-15 18:04:22 +03:00
|
|
|
if (cpuid_info.topology.is_hybrid) {
|
2022-07-16 14:28:53 +03:00
|
|
|
if (cpuid_info.topology.pcore_count > 1) {
|
|
|
|
|
|
|
|
if (cpuid_info.flags.htt &&
|
|
|
|
(cpuid_info.topology.thread_count - cpuid_info.topology.ecore_count) == cpuid_info.topology.pcore_count) {
|
|
|
|
cpuid_info.topology.pcore_count /= 2;
|
|
|
|
}
|
|
|
|
|
|
|
|
display_cpu_topo_hybrid(cpuid_info.topology.pcore_count,
|
|
|
|
cpuid_info.topology.ecore_count,
|
|
|
|
cpuid_info.topology.thread_count);
|
|
|
|
} else {
|
|
|
|
display_cpu_topo_hybrid_short(cpuid_info.topology.thread_count);
|
|
|
|
}
|
2022-04-14 04:29:20 +03:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Condensed display for multi-socket motherboard
|
2022-04-15 18:04:22 +03:00
|
|
|
if (num_cpu_sockets > 1) {
|
2022-04-14 04:29:20 +03:00
|
|
|
display_cpu_topo_multi_socket(num_cpu_sockets,
|
|
|
|
num_cpu_sockets * cpuid_info.topology.core_count,
|
|
|
|
num_cpu_sockets * cpuid_info.topology.thread_count);
|
2022-04-11 20:37:52 +03:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2022-04-15 18:04:22 +03:00
|
|
|
if (cpuid_info.topology.thread_count < 100) {
|
2022-04-14 04:29:20 +03:00
|
|
|
display_cpu_topo(cpuid_info.topology.core_count,
|
|
|
|
cpuid_info.topology.thread_count);
|
2022-04-11 20:37:52 +03:00
|
|
|
} else {
|
2022-04-14 04:29:20 +03:00
|
|
|
display_cpu_topo_short(cpuid_info.topology.core_count,
|
|
|
|
cpuid_info.topology.thread_count);
|
2022-04-11 20:37:52 +03:00
|
|
|
}
|
2022-04-14 04:29:20 +03:00
|
|
|
|
2022-04-11 20:37:52 +03:00
|
|
|
}
|
|
|
|
|
2022-03-14 07:35:36 +03:00
|
|
|
void post_display_init(void)
|
|
|
|
{
|
|
|
|
print_smbios_startup_info();
|
Split SPD parsing and printing code from smbus.c to spd.c (#426)
* Split SPD parsing and printing code from smbus.c to spd.c
Move all SPD parsing and printing code from smbus.{c,h} to spd.{c,h}.
Introduce parse_spd() function, moving the parse_spd_* selection logic
from print_smbus_startup_info(), allowing to keep parse_spd_* static.
Remove static from get_spd() and update print_smbus_startup_info()
to use parse_spd() which also simplifies the code flow.
Move LINE_SPD into display.h and rename it to ROW_SPD. Update print_spdi()
to use explicit row number where the SPD info needs to be printed.
Rename ram_info into ram_info_t, rename print_smbus_startup_info()
into print_spd_startup_info.
Do not initialize ram.freq to 0, this is the initial value already.
Do not set curspd.isValid to False, the first thing that parse_spd()
does is setting the entire struct to 0, that also sets isValid to False.
print_spd_startup_info() from smbus.c is technically a skeleton now
so each arch can have its own version, adjusted as needed. Once
LA64 changes land, we can think how we can even make it arch agnostic.
* Add -fexcess-precision=standard to CFLAGS for build(32,64)/Makefile
Recent switch from -std=c11 to -std=gnu11 done in 53ca89f ("Add
initial NUMA awareness support") introduced a regression in SPD
parsing code (and potentially in other places) due to change of
floating point precision. Restore the original behavior by
adding -fexcess-precision=standard to CFLAGS.
Bug: https://github.com/memtest86plus/memtest86plus/issues/425
Fixes: https://github.com/memtest86plus/memtest86plus/commit/53ca89f8aeeea649a1b8c2d2d14ec121f7025f54
2024-08-08 03:41:19 +03:00
|
|
|
print_spd_startup_info();
|
2022-04-14 02:40:31 +03:00
|
|
|
|
2023-05-12 16:33:28 +03:00
|
|
|
if (imc.freq) {
|
|
|
|
// Try to get RAM information from IMC
|
2022-04-14 04:29:20 +03:00
|
|
|
display_spec_mode("IMC: ");
|
2023-05-12 16:33:28 +03:00
|
|
|
if (imc.type[3] == '5') {
|
|
|
|
display_spec_ddr5(imc.freq, imc.type, imc.tCL, imc.tCL_dec, imc.tRCD, imc.tRP, imc.tRAS);
|
|
|
|
} else {
|
|
|
|
display_spec_ddr(imc.freq, imc.type, imc.tCL, imc.tCL_dec, imc.tRCD, imc.tRP, imc.tRAS);
|
|
|
|
}
|
2022-04-15 18:04:22 +03:00
|
|
|
display_mode = DISPLAY_MODE_IMC;
|
2022-05-19 17:02:31 +03:00
|
|
|
} else if (ram.freq > 0 && ram.tCL > 0) {
|
2022-04-14 02:40:31 +03:00
|
|
|
// If not available, grab max memory specs from SPD
|
2022-04-14 04:29:20 +03:00
|
|
|
display_spec_mode("RAM: ");
|
2022-05-19 17:02:31 +03:00
|
|
|
if (ram.freq <= 166) {
|
|
|
|
display_spec_sdr(ram.freq, ram.type, ram.tCL, ram.tRCD, ram.tRP, ram.tRAS);
|
|
|
|
} else {
|
2022-08-26 22:56:12 +03:00
|
|
|
display_spec_ddr(ram.freq, ram.type, ram.tCL, ram.tCL_dec, ram.tRCD, ram.tRP, ram.tRAS);
|
2022-05-19 17:02:31 +03:00
|
|
|
}
|
2022-04-15 18:04:22 +03:00
|
|
|
display_mode = DISPLAY_MODE_SPD;
|
2022-04-14 02:40:31 +03:00
|
|
|
} else {
|
2022-04-15 18:04:22 +03:00
|
|
|
// If nothing available, fallback to "Using Core" Display
|
|
|
|
display_mode = DISPLAY_MODE_NA;
|
2022-04-14 02:40:31 +03:00
|
|
|
}
|
2022-03-14 07:35:36 +03:00
|
|
|
}
|
|
|
|
|
2020-05-24 23:30:55 +03:00
|
|
|
void display_start_run(void)
|
|
|
|
{
|
2022-03-14 07:35:36 +03:00
|
|
|
if (!enable_trace && !enable_sm) {
|
2020-12-11 19:07:12 +03:00
|
|
|
clear_message_area();
|
|
|
|
}
|
2022-03-14 07:35:36 +03:00
|
|
|
|
2023-11-29 14:53:05 +03:00
|
|
|
clear_screen_region(7, 49, 7, 57); // run time
|
|
|
|
|
|
|
|
if (ecc_status.ecc_enabled) {
|
|
|
|
clear_screen_region(8, 49, 8, 53); // pass number
|
|
|
|
clear_screen_region(8, 61, 8, 68); // error count
|
|
|
|
clear_screen_region(8, 74, 8, SCREEN_WIDTH - 1); // ecc error count
|
|
|
|
} else {
|
|
|
|
clear_screen_region(8, 49, 8, 59); // pass number
|
|
|
|
clear_screen_region(8, 68, 8, SCREEN_WIDTH - 1); // error count
|
|
|
|
}
|
|
|
|
|
2020-05-24 23:30:55 +03:00
|
|
|
display_pass_count(0);
|
2023-11-29 14:53:05 +03:00
|
|
|
error_count = 0;
|
|
|
|
display_error_count();
|
2022-01-29 01:47:25 +03:00
|
|
|
if (clks_per_msec > 0) {
|
|
|
|
// If we've measured the CPU speed, we know the TSC is available.
|
|
|
|
run_start_time = get_tsc();
|
2022-01-29 02:06:23 +03:00
|
|
|
next_spin_time = run_start_time + SPINNER_PERIOD * clks_per_msec;
|
2022-01-29 01:47:25 +03:00
|
|
|
}
|
2022-01-29 02:06:23 +03:00
|
|
|
display_spinner('-');
|
2022-04-08 20:26:31 +03:00
|
|
|
display_status("Testing");
|
2022-04-04 19:31:54 +03:00
|
|
|
|
|
|
|
if (enable_tty){
|
|
|
|
tty_full_redraw();
|
|
|
|
}
|
2020-05-24 23:30:55 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
void display_start_pass(void)
|
|
|
|
{
|
|
|
|
clear_screen_region(1, 39, 1, SCREEN_WIDTH - 1); // progress bar
|
|
|
|
display_pass_percentage(0);
|
|
|
|
pass_bar_length = 0;
|
|
|
|
pass_ticks = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
void display_start_test(void)
|
|
|
|
{
|
2022-04-15 21:28:16 +03:00
|
|
|
clear_screen_region(2, 39, 3, SCREEN_WIDTH - 1); // progress bar, test details
|
|
|
|
clear_screen_region(4, 39, 4, SCREEN_WIDTH - 6); // Avoid erasing paging mode
|
|
|
|
clear_screen_region(5, 39, 5, SCREEN_WIDTH - 1);
|
2020-05-24 23:30:55 +03:00
|
|
|
clear_screen_region(3, 36, 3, 37); // test number
|
|
|
|
display_test_percentage(0);
|
|
|
|
display_test_number(test_num);
|
|
|
|
display_test_description(test_list[test_num].description);
|
|
|
|
test_bar_length = 0;
|
|
|
|
test_ticks = 0;
|
2024-03-13 03:43:26 +03:00
|
|
|
|
|
|
|
#if 0
|
|
|
|
uint64_t current_time = get_tsc();
|
|
|
|
int secs = (current_time - run_start_time) / (1000 * (uint64_t)clks_per_msec);
|
|
|
|
int mins = secs / 60; secs %= 60;
|
|
|
|
int hours = mins / 60; mins %= 60;
|
|
|
|
do_trace(0, "T %i: %i:%02i:%02i", test_num, hours, mins, secs);
|
|
|
|
#endif
|
2020-05-24 23:30:55 +03:00
|
|
|
}
|
|
|
|
|
2023-11-29 14:53:05 +03:00
|
|
|
void display_error_count(void)
|
|
|
|
{
|
|
|
|
if (ecc_status.ecc_enabled) {
|
|
|
|
display_err_count_with_ecc(error_count, error_count_cecc);
|
|
|
|
} else {
|
|
|
|
display_err_count_without_ecc(error_count);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-05-22 19:02:54 +03:00
|
|
|
void display_temperature(void)
|
|
|
|
{
|
|
|
|
if (!enable_temperature) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
int actual_cpu_temp = get_cpu_temperature();
|
|
|
|
|
|
|
|
if (actual_cpu_temp == 0) {
|
|
|
|
if (max_cpu_temp == 0) {
|
|
|
|
enable_temperature = false;
|
|
|
|
}
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (max_cpu_temp < actual_cpu_temp ) {
|
|
|
|
max_cpu_temp = actual_cpu_temp;
|
|
|
|
}
|
|
|
|
|
|
|
|
int offset = actual_cpu_temp / 100 + max_cpu_temp / 100;
|
|
|
|
|
|
|
|
clear_screen_region(1, 18, 1, 22);
|
|
|
|
printf(1, 20-offset, "%2i/%2i%cC", actual_cpu_temp, max_cpu_temp, 0xF8);
|
|
|
|
}
|
|
|
|
|
2022-07-17 21:20:52 +03:00
|
|
|
void display_big_status(bool pass)
|
|
|
|
{
|
2023-01-04 18:16:55 +03:00
|
|
|
if (!enable_big_status || big_status_displayed) {
|
2022-07-17 21:20:52 +03:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
save_screen_region(POP_STATUS_REGION, popup_status_save_buffer);
|
|
|
|
|
|
|
|
set_background_colour(BLACK);
|
|
|
|
set_foreground_colour(pass ? GREEN : RED);
|
|
|
|
clear_screen_region(POP_STATUS_REGION);
|
|
|
|
|
|
|
|
if (pass) {
|
|
|
|
prints(POP_STAT_R+1, POP_STAT_C+5, "###### ## ##### ##### ");
|
|
|
|
prints(POP_STAT_R+2, POP_STAT_C+5, "## ## #### ## ## ## ## ");
|
|
|
|
prints(POP_STAT_R+3, POP_STAT_C+5, "## ## ## ## ## ## ");
|
|
|
|
prints(POP_STAT_R+4, POP_STAT_C+5, "###### ## ## ##### ##### ");
|
|
|
|
prints(POP_STAT_R+5, POP_STAT_C+5, "## ######## ## ## ");
|
|
|
|
prints(POP_STAT_R+6, POP_STAT_C+5, "## ## ## ## ## ## ## ");
|
|
|
|
prints(POP_STAT_R+7, POP_STAT_C+5, "## ## ## ##### ##### ");
|
|
|
|
} else {
|
|
|
|
prints(POP_STAT_R+1, POP_STAT_C+5, "####### ## ###### ## ");
|
|
|
|
prints(POP_STAT_R+2, POP_STAT_C+5, "## #### ## ## ");
|
|
|
|
prints(POP_STAT_R+3, POP_STAT_C+5, "## ## ## ## ## ");
|
|
|
|
prints(POP_STAT_R+4, POP_STAT_C+5, "##### ## ## ## ## ");
|
|
|
|
prints(POP_STAT_R+5, POP_STAT_C+5, "## ######## ## ## ");
|
|
|
|
prints(POP_STAT_R+6, POP_STAT_C+5, "## ## ## ## ## ");
|
|
|
|
prints(POP_STAT_R+7, POP_STAT_C+5, "## ## ## ###### ###### ");
|
|
|
|
}
|
2022-11-28 01:34:43 +03:00
|
|
|
|
|
|
|
prints(POP_STAT_R+8, POP_STAT_C+5, " ");
|
|
|
|
prints(POP_STAT_R+9, POP_STAT_C+5, "Press any key to remove this banner ");
|
|
|
|
|
2022-07-17 21:20:52 +03:00
|
|
|
set_background_colour(BLUE);
|
|
|
|
set_foreground_colour(WHITE);
|
|
|
|
big_status_displayed = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
void restore_big_status(void)
|
|
|
|
{
|
2022-10-23 18:32:17 +03:00
|
|
|
if (!big_status_displayed) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2022-07-17 21:20:52 +03:00
|
|
|
restore_screen_region(POP_STATUS_REGION, popup_status_save_buffer);
|
|
|
|
big_status_displayed = false;
|
|
|
|
}
|
|
|
|
|
2020-05-24 23:30:55 +03:00
|
|
|
void check_input(void)
|
|
|
|
{
|
2022-07-17 21:20:52 +03:00
|
|
|
char input_key = get_key();
|
|
|
|
|
|
|
|
if (input_key == '\0') {
|
|
|
|
return;
|
|
|
|
} else if (big_status_displayed) {
|
|
|
|
restore_big_status();
|
2023-03-29 19:29:59 +03:00
|
|
|
enable_big_status = false;
|
2022-07-17 21:20:52 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
switch (input_key) {
|
2020-05-24 23:30:55 +03:00
|
|
|
case ESC:
|
|
|
|
clear_message_area();
|
|
|
|
display_notice("Rebooting...");
|
|
|
|
reboot();
|
|
|
|
break;
|
|
|
|
case '1':
|
|
|
|
config_menu(false);
|
|
|
|
break;
|
|
|
|
case ' ':
|
|
|
|
set_scroll_lock(!scroll_lock);
|
|
|
|
break;
|
|
|
|
case '\n':
|
|
|
|
scroll_wait = false;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void set_scroll_lock(bool enabled)
|
|
|
|
{
|
|
|
|
scroll_lock = enabled;
|
|
|
|
set_foreground_colour(BLUE);
|
|
|
|
prints(ROW_FOOTER, 48, scroll_lock ? "unlock" : "lock ");
|
|
|
|
set_foreground_colour(WHITE);
|
|
|
|
}
|
|
|
|
|
|
|
|
void toggle_scroll_lock(void)
|
|
|
|
{
|
|
|
|
set_scroll_lock(!scroll_lock);
|
|
|
|
}
|
|
|
|
|
|
|
|
void scroll(void)
|
|
|
|
{
|
|
|
|
if (scroll_message_row < ROW_SCROLL_B) {
|
|
|
|
scroll_message_row++;
|
|
|
|
} else {
|
|
|
|
if (scroll_lock) {
|
2022-04-15 18:04:22 +03:00
|
|
|
display_footer_message("<Enter> Single step ");
|
2020-05-24 23:30:55 +03:00
|
|
|
}
|
|
|
|
scroll_wait = true;
|
|
|
|
do {
|
|
|
|
check_input();
|
|
|
|
} while (scroll_wait && scroll_lock);
|
|
|
|
|
|
|
|
scroll_wait = false;
|
|
|
|
clear_footer_message();
|
|
|
|
scroll_screen_region(ROW_SCROLL_T, 0, ROW_SCROLL_B, SCREEN_WIDTH - 1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-02-01 01:59:14 +03:00
|
|
|
void do_tick(int my_cpu)
|
2020-05-24 23:30:55 +03:00
|
|
|
{
|
2022-04-04 19:31:54 +03:00
|
|
|
int act_sec = 0;
|
2022-02-28 23:21:50 +03:00
|
|
|
bool use_spin_wait = (power_save < POWER_SAVE_HIGH);
|
|
|
|
if (use_spin_wait) {
|
|
|
|
barrier_spin_wait(run_barrier);
|
|
|
|
} else {
|
|
|
|
barrier_halt_wait(run_barrier);
|
|
|
|
}
|
2023-11-29 14:53:05 +03:00
|
|
|
|
2022-02-01 01:59:14 +03:00
|
|
|
if (master_cpu == my_cpu) {
|
2020-05-24 23:30:55 +03:00
|
|
|
check_input();
|
|
|
|
error_update();
|
|
|
|
}
|
2022-02-28 23:21:50 +03:00
|
|
|
if (use_spin_wait) {
|
|
|
|
barrier_spin_wait(run_barrier);
|
|
|
|
} else {
|
|
|
|
barrier_halt_wait(run_barrier);
|
|
|
|
}
|
2020-05-24 23:30:55 +03:00
|
|
|
|
|
|
|
// Only the master CPU does the update.
|
2022-02-01 01:59:14 +03:00
|
|
|
if (master_cpu != my_cpu) {
|
2020-05-24 23:30:55 +03:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
test_ticks++;
|
|
|
|
pass_ticks++;
|
|
|
|
|
|
|
|
pass_type_t pass_type = (pass_num == 0) ? FAST_PASS : FULL_PASS;
|
|
|
|
|
|
|
|
int pct = 0;
|
|
|
|
if (ticks_per_test[pass_type][test_num] > 0) {
|
|
|
|
pct = 100 * test_ticks / ticks_per_test[pass_type][test_num];
|
|
|
|
if (pct > 100) {
|
|
|
|
pct = 100;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
display_test_percentage(pct);
|
|
|
|
display_test_bar((BAR_LENGTH * pct) / 100);
|
|
|
|
|
|
|
|
pct = 0;
|
|
|
|
if (ticks_per_pass[pass_type] > 0) {
|
|
|
|
pct = 100 * pass_ticks / ticks_per_pass[pass_type];
|
|
|
|
if (pct > 100) {
|
|
|
|
pct = 100;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
display_pass_percentage(pct);
|
|
|
|
display_pass_bar((BAR_LENGTH * pct) / 100);
|
|
|
|
|
2022-01-29 02:06:23 +03:00
|
|
|
bool update_spinner = true;
|
2022-01-29 01:47:25 +03:00
|
|
|
if (clks_per_msec > 0) {
|
2022-01-29 02:06:23 +03:00
|
|
|
uint64_t current_time = get_tsc();
|
|
|
|
|
2022-10-23 18:32:17 +03:00
|
|
|
int secs = (current_time - run_start_time) / (1000 * (uint64_t)clks_per_msec);
|
2022-04-04 19:31:54 +03:00
|
|
|
int mins = secs / 60; secs %= 60; act_sec = secs;
|
2020-05-24 23:30:55 +03:00
|
|
|
int hours = mins / 60; mins %= 60;
|
|
|
|
display_run_time(hours, mins, secs);
|
2022-01-29 02:06:23 +03:00
|
|
|
|
|
|
|
if (current_time >= next_spin_time) {
|
|
|
|
next_spin_time = current_time + SPINNER_PERIOD * clks_per_msec;
|
|
|
|
} else {
|
|
|
|
update_spinner = false;
|
|
|
|
}
|
|
|
|
}
|
2022-04-04 19:31:54 +03:00
|
|
|
|
|
|
|
/* ---------------
|
|
|
|
* Timed functions
|
|
|
|
* --------------- */
|
|
|
|
|
|
|
|
// update spinner every SPINNER_PERIOD ms
|
2022-01-29 02:06:23 +03:00
|
|
|
if (update_spinner) {
|
|
|
|
spin_idx = (spin_idx + 1) % NUM_SPIN_STATES;
|
|
|
|
display_spinner(spin_state[spin_idx]);
|
2020-05-24 23:30:55 +03:00
|
|
|
}
|
|
|
|
|
2022-04-04 19:31:54 +03:00
|
|
|
// This only tick one time per second
|
|
|
|
if (!timed_update_done) {
|
|
|
|
|
2022-10-23 18:32:17 +03:00
|
|
|
// Display FAIL banner if (new) errors detected
|
2022-11-28 01:34:43 +03:00
|
|
|
if (err_banner_redraw && !big_status_displayed && error_count > 1) {
|
2022-10-23 18:32:17 +03:00
|
|
|
display_big_status(false);
|
|
|
|
}
|
|
|
|
|
2023-11-29 14:53:05 +03:00
|
|
|
// Check ECC Errors
|
|
|
|
memctrl_poll_ecc();
|
|
|
|
|
2022-05-22 19:02:54 +03:00
|
|
|
// Update temperature
|
|
|
|
display_temperature();
|
2022-04-04 19:31:54 +03:00
|
|
|
|
|
|
|
// Update TTY one time every TTY_UPDATE_PERIOD second(s)
|
|
|
|
if (enable_tty) {
|
|
|
|
|
|
|
|
if (act_sec % tty_update_period == 0) {
|
|
|
|
tty_partial_redraw();
|
|
|
|
}
|
|
|
|
}
|
2023-11-29 14:53:05 +03:00
|
|
|
|
2022-04-04 19:31:54 +03:00
|
|
|
timed_update_done = true;
|
|
|
|
}
|
2022-01-29 02:06:23 +03:00
|
|
|
|
2022-04-04 19:31:54 +03:00
|
|
|
if (act_sec != prev_sec) {
|
|
|
|
prev_sec = act_sec;
|
|
|
|
timed_update_done = false;
|
2020-05-24 23:30:55 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void do_trace(int my_cpu, const char *fmt, ...)
|
|
|
|
{
|
|
|
|
va_list args;
|
|
|
|
|
|
|
|
va_start(args, fmt);
|
|
|
|
spin_lock(error_mutex);
|
|
|
|
scroll();
|
|
|
|
printi(scroll_message_row, 0, my_cpu, 2, false, false);
|
|
|
|
vprintf(scroll_message_row, 4, fmt, args);
|
|
|
|
spin_unlock(error_mutex);
|
|
|
|
va_end(args);
|
|
|
|
}
|