Files
jsix_import/src/kernel/panic.serial/main.cpp
Justin C. Miller 337b8bb36b [panic] Don't spin the CPU in panic
While waiting for the main panicing CPU to finish, don't spin the CPU
without using `asm("pause")` to lower power consumption. Some panics can
get stuck in this state and oh man do my fans spin up.
2023-08-31 19:43:26 -07:00

75 lines
1.9 KiB
C++

#include <util/new.h>
#include <util/no_construct.h>
#include "cpu.h"
#include "display.h"
#include "io.h"
#include "serial.h"
#include "symbol_table.h"
struct cpu_state;
bool main_cpu_done = false;
bool asserting_locked = false;
unsigned remaining = 0;
util::no_construct<panicking::serial_port> __com1_storage;
panicking::serial_port &com1 = __com1_storage.value;
util::no_construct<panicking::symbol_table> __syms_storage;
panicking::symbol_table &syms = __syms_storage.value;
static constexpr int order = __ATOMIC_ACQ_REL;
extern "C"
void panic_handler(const cpu_state *regs)
{
cpu_data &cpu = current_cpu();
panic_data *panic = cpu.panic;
// If we're not running on the CPU that panicked, wait
// for it to finish
if (!panic) {
while (!main_cpu_done) asm ("pause");
} else {
new (&com1) panicking::serial_port {panicking::COM1};
new (&syms) panicking::symbol_table {panic->symbol_data};
remaining = panic->cpus;
}
while (__atomic_test_and_set(&asserting_locked, order))
asm ("pause");
panicking::frame const *fp = nullptr;
asm ( "movq (%%rbp), %0" : "=r" (fp) );
if (panic)
print_header(com1, panic->message, panic->function,
panic->file, panic->line);
print_cpu(com1, cpu);
print_callstack(com1, syms, fp);
print_cpu_state(com1, *regs);
if (panic && panic->user_state)
print_user_state(com1, *panic->user_state);
__atomic_clear(&asserting_locked, order);
// If we're running on the CPU that panicked, tell the
// others we have finished
main_cpu_done = true;
if (__atomic_sub_fetch(&remaining, 1, order) == 0) {
// No remaining CPUs, if we're running on QEMU,
// tell it to exit
constexpr uint32_t exit_code = 255;
asm ( "outl %%eax, %%dx" :: "a"(exit_code), "d"(0xf4) );
}
while (1) asm ("hlt");
}
#define NDEBUG
#include "../cpprt.cpp"