misc: Improve printing effectively on panics and errors
This commit is contained in:
parent
e76c8d47a9
commit
7f14f2f0d0
@ -36,15 +36,13 @@ noreturn void uefi_entry(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable)
|
||||
|
||||
EFI_STATUS status;
|
||||
|
||||
term_fallback();
|
||||
|
||||
status = gBS->SetWatchdogTimer(0, 0x10000, 0, NULL);
|
||||
if (status) {
|
||||
term_vbe(NULL, 0, 0);
|
||||
early_term = true;
|
||||
print("WARNING: Failed to disable watchdog timer!\n");
|
||||
}
|
||||
|
||||
term_notready();
|
||||
|
||||
init_memmap();
|
||||
|
||||
#if defined (__x86_64__) || defined (__i386__)
|
||||
@ -64,9 +62,6 @@ noreturn void uefi_entry(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable)
|
||||
EFI_HANDLE current_handle = ImageHandle;
|
||||
for (;;) {
|
||||
if (current_handle == NULL) {
|
||||
term_vbe(NULL, 0, 0);
|
||||
early_term = true;
|
||||
|
||||
print("WARNING: Could not meaningfully match the boot device handle with a volume.\n");
|
||||
print(" Using the first volume containing a Limine configuration!\n");
|
||||
|
||||
@ -94,8 +89,9 @@ noreturn void uefi_entry(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable)
|
||||
break;
|
||||
}
|
||||
|
||||
if (boot_volume != NULL)
|
||||
if (boot_volume != NULL) {
|
||||
stage3_common();
|
||||
}
|
||||
|
||||
panic(false, "No volume contained a Limine configuration file");
|
||||
}
|
||||
@ -112,8 +108,9 @@ noreturn void uefi_entry(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable)
|
||||
|
||||
boot_volume = disk_volume_from_efi_handle(loaded_image->DeviceHandle);
|
||||
|
||||
if (boot_volume != NULL)
|
||||
if (boot_volume != NULL) {
|
||||
stage3_common();
|
||||
}
|
||||
|
||||
current_handle = loaded_image->ParentHandle;
|
||||
}
|
||||
@ -121,8 +118,6 @@ noreturn void uefi_entry(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable)
|
||||
#endif
|
||||
|
||||
noreturn void stage3_common(void) {
|
||||
term_notready();
|
||||
|
||||
#if defined (__x86_64__) || defined (__i386__)
|
||||
init_flush_irqs();
|
||||
init_io_apics();
|
||||
|
@ -617,7 +617,6 @@ bool gterm_init(char *config, size_t *_rows, size_t *_cols, size_t width, size_t
|
||||
&& width == 0
|
||||
&& height == 0
|
||||
&& fbinfo.framebuffer_bpp == 32
|
||||
&& !early_term
|
||||
&& serial == last_serial
|
||||
&& config == last_config) {
|
||||
*_rows = rows;
|
||||
@ -633,7 +632,6 @@ bool gterm_init(char *config, size_t *_rows, size_t *_cols, size_t width, size_t
|
||||
&& fbinfo.framebuffer_width == width
|
||||
&& fbinfo.framebuffer_height == height
|
||||
&& fbinfo.framebuffer_bpp == 32
|
||||
&& !early_term
|
||||
&& serial == last_serial
|
||||
&& config == last_config) {
|
||||
*_rows = rows;
|
||||
@ -642,8 +640,6 @@ bool gterm_init(char *config, size_t *_rows, size_t *_cols, size_t width, size_t
|
||||
return true;
|
||||
}
|
||||
|
||||
early_term = false;
|
||||
|
||||
// We force bpp to 32
|
||||
if (!fb_init(&fbinfo, width, height, 32))
|
||||
return false;
|
||||
|
@ -21,45 +21,11 @@ noreturn void panic(bool allow_menu, const char *fmt, ...) {
|
||||
|
||||
quiet = false;
|
||||
|
||||
static bool is_nested = false;
|
||||
|
||||
if (is_nested) {
|
||||
goto nested;
|
||||
}
|
||||
|
||||
is_nested = true;
|
||||
|
||||
#if defined (BIOS)
|
||||
if (stage3_loaded == true && term_backend == NOT_READY) {
|
||||
early_term = true;
|
||||
term_vbe(NULL, 0, 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined (UEFI)
|
||||
if (term_backend == NOT_READY) {
|
||||
if (term_enabled_once) {
|
||||
term_vbe(NULL, 0, 0);
|
||||
} else {
|
||||
term_fallback();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
nested:
|
||||
if (term_backend == NOT_READY) {
|
||||
term_fallback();
|
||||
}
|
||||
|
||||
#if defined (BIOS)
|
||||
if (stage3_loaded) {
|
||||
#endif
|
||||
if (term_backend != FALLBACK) {
|
||||
print("\033[31mPANIC\033[37;1m\033[0m: ");
|
||||
#if defined (BIOS)
|
||||
} else {
|
||||
print("PANIC: ");
|
||||
}
|
||||
#endif
|
||||
vprint(fmt, args);
|
||||
|
||||
va_end(args);
|
||||
|
@ -11,29 +11,6 @@
|
||||
#include <sys/cpu.h>
|
||||
#include <drivers/serial.h>
|
||||
|
||||
#if defined (BIOS)
|
||||
static void s2_print(const char *s, size_t len) {
|
||||
for (size_t i = 0; i < len; i++) {
|
||||
struct rm_regs r = {0};
|
||||
char c = s[i];
|
||||
|
||||
switch (c) {
|
||||
case '\n':
|
||||
r.eax = 0x0e00 | '\r';
|
||||
rm_int(0x10, &r, &r);
|
||||
r = (struct rm_regs){0};
|
||||
r.eax = 0x0e00 | '\n';
|
||||
rm_int(0x10, &r, &r);
|
||||
break;
|
||||
default:
|
||||
r.eax = 0x0e00 | s[i];
|
||||
rm_int(0x10, &r, &r);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static const char *base_digits = "0123456789abcdef";
|
||||
|
||||
#define PRINT_BUF_MAX 4096
|
||||
@ -142,6 +119,10 @@ void print(const char *fmt, ...) {
|
||||
static char print_buf[PRINT_BUF_MAX];
|
||||
|
||||
void vprint(const char *fmt, va_list args) {
|
||||
if (quiet) {
|
||||
return;
|
||||
}
|
||||
|
||||
size_t print_buf_i = 0;
|
||||
|
||||
for (;;) {
|
||||
@ -218,15 +199,7 @@ void vprint(const char *fmt, va_list args) {
|
||||
}
|
||||
|
||||
out:
|
||||
#if defined (BIOS)
|
||||
if (stage3_loaded) {
|
||||
#endif
|
||||
term_write((uint64_t)(uintptr_t)print_buf, print_buf_i);
|
||||
#if defined (BIOS)
|
||||
} else {
|
||||
s2_print(print_buf, print_buf_i);
|
||||
}
|
||||
#endif
|
||||
term_write((uint64_t)(uintptr_t)print_buf, print_buf_i);
|
||||
|
||||
for (size_t i = 0; i < print_buf_i; i++) {
|
||||
#if defined (__x86_64__) || defined (__i386__)
|
||||
@ -234,7 +207,7 @@ out:
|
||||
outb(0xe9, print_buf[i]);
|
||||
}
|
||||
#endif
|
||||
if ((term_backend != NOT_READY && serial) || COM_OUTPUT) {
|
||||
if (serial || COM_OUTPUT) {
|
||||
switch (print_buf[i]) {
|
||||
case '\n':
|
||||
serial_out('\r');
|
||||
|
@ -52,7 +52,7 @@ void term_deinit(void) {
|
||||
gterm_deinit();
|
||||
}
|
||||
|
||||
term_notready();
|
||||
term_fallback();
|
||||
}
|
||||
|
||||
void term_vbe(char *config, size_t width, size_t height) {
|
||||
@ -109,8 +109,6 @@ void term_vbe(char *config, size_t width, size_t height) {
|
||||
term_context_restore = gterm_context_restore;
|
||||
term_full_refresh = gterm_full_refresh;
|
||||
|
||||
term_enabled_once = true;
|
||||
|
||||
term_backend = VBE;
|
||||
}
|
||||
|
||||
@ -183,8 +181,6 @@ void term_textmode(void) {
|
||||
return;
|
||||
}
|
||||
|
||||
term_notready();
|
||||
|
||||
init_vga_textmode(&term_rows, &term_cols, true);
|
||||
|
||||
if (serial) {
|
||||
@ -222,8 +218,6 @@ void term_textmode(void) {
|
||||
term_context_restore = text_context_restore;
|
||||
term_full_refresh = text_full_refresh;
|
||||
|
||||
term_enabled_once = true;
|
||||
|
||||
term_backend = TEXTMODE;
|
||||
}
|
||||
#endif
|
||||
@ -260,9 +254,6 @@ static uint8_t xfer_buf[TERM_XFER_CHUNK];
|
||||
bool term_autoflush = true;
|
||||
|
||||
void term_write(uint64_t buf, uint64_t count) {
|
||||
if (term_backend == NOT_READY)
|
||||
return;
|
||||
|
||||
switch (count) {
|
||||
case TERM_CTX_SIZE: {
|
||||
uint64_t ret = context_size();
|
||||
|
@ -39,7 +39,7 @@ extern struct term_context {
|
||||
} term_context;
|
||||
|
||||
enum {
|
||||
NOT_READY,
|
||||
_NOT_READY,
|
||||
VBE,
|
||||
TEXTMODE,
|
||||
FALLBACK
|
||||
@ -49,8 +49,6 @@ extern int current_video_mode;
|
||||
extern int term_backend;
|
||||
extern size_t term_rows, term_cols;
|
||||
extern bool term_runtime;
|
||||
extern bool early_term;
|
||||
extern bool term_enabled_once;
|
||||
|
||||
void term_fallback(void);
|
||||
|
||||
@ -58,7 +56,6 @@ void term_reinit(void);
|
||||
void term_deinit(void);
|
||||
void term_vbe(char *config, size_t width, size_t height);
|
||||
void term_textmode(void);
|
||||
void term_notready(void);
|
||||
void term_putchar(uint8_t c);
|
||||
void term_write(uint64_t buf, uint64_t count);
|
||||
|
||||
|
@ -5,13 +5,10 @@
|
||||
#include <lib/misc.h>
|
||||
#include <lib/real.h>
|
||||
|
||||
bool early_term = false;
|
||||
|
||||
no_unwind int current_video_mode = -1;
|
||||
int term_backend = NOT_READY;
|
||||
int term_backend = _NOT_READY;
|
||||
size_t term_rows, term_cols;
|
||||
bool term_runtime = false;
|
||||
bool term_enabled_once = false;
|
||||
|
||||
void (*raw_putchar)(uint8_t c);
|
||||
void (*clear)(bool move);
|
||||
@ -139,6 +136,8 @@ static void fallback_get_cursor_pos(size_t *x, size_t *y) {
|
||||
}
|
||||
#endif
|
||||
|
||||
static void term_notready(void);
|
||||
|
||||
void term_fallback(void) {
|
||||
#if defined (UEFI)
|
||||
if (!efi_boot_services_exited) {
|
||||
@ -194,9 +193,7 @@ static void notready_uint64_t(uint64_t n) {
|
||||
(void)n;
|
||||
}
|
||||
|
||||
void term_notready(void) {
|
||||
term_backend = NOT_READY;
|
||||
|
||||
static void term_notready(void) {
|
||||
raw_putchar = notready_raw_putchar;
|
||||
clear = notready_clear;
|
||||
enable_cursor = notready_void;
|
||||
|
@ -601,8 +601,6 @@ noreturn void _menu(bool timeout_enabled) {
|
||||
randomise_mem_str = config_get_value(NULL, 0, "RANDOMIZE_MEMORY");
|
||||
bool randomise_mem = randomise_mem_str != NULL && strcmp(randomise_mem_str, "yes") == 0;
|
||||
if (randomise_mem) {
|
||||
term_vbe(NULL, 0, 0);
|
||||
early_term = true;
|
||||
pmm_randomise_memory();
|
||||
}
|
||||
|
||||
@ -650,6 +648,7 @@ noreturn void _menu(bool timeout_enabled) {
|
||||
// default entry is valid.
|
||||
print_tree(NULL, 0, 0, selected_entry, menu_tree, &selected_menu_entry);
|
||||
if (selected_menu_entry == NULL || selected_menu_entry->sub != NULL) {
|
||||
quiet = false;
|
||||
print("Default entry is not valid or directory, booting to menu.\n");
|
||||
skip_timeout = true;
|
||||
} else {
|
||||
@ -664,7 +663,6 @@ noreturn void _menu(bool timeout_enabled) {
|
||||
char *graphics = "yes";
|
||||
#endif
|
||||
|
||||
reterm:
|
||||
if (graphics == NULL || strcmp(graphics, "no") != 0) {
|
||||
size_t req_width = 0, req_height = 0, req_bpp = 0;
|
||||
|
||||
@ -695,6 +693,7 @@ refresh:
|
||||
}
|
||||
|
||||
while (menu_tree == NULL) {
|
||||
quiet = false;
|
||||
print("Config file %s.\n\n", config_ready ? "contains no valid entries" : "not found");
|
||||
print("For information on the format of Limine config entries, consult CONFIG.md in\n");
|
||||
print("the root of the Limine source repository.\n\n");
|
||||
@ -765,14 +764,10 @@ refresh:
|
||||
term_double_buffer_flush();
|
||||
if ((c = pit_sleep_and_quit_on_keypress(1))) {
|
||||
skip_timeout = true;
|
||||
if (quiet) {
|
||||
quiet = false;
|
||||
goto reterm;
|
||||
} else {
|
||||
print("\e[2K");
|
||||
term_double_buffer_flush();
|
||||
goto timeout_aborted;
|
||||
}
|
||||
quiet = false;
|
||||
print("\e[2K");
|
||||
term_double_buffer_flush();
|
||||
goto timeout_aborted;
|
||||
}
|
||||
}
|
||||
goto autoboot;
|
||||
@ -826,10 +821,10 @@ timeout_aborted:
|
||||
selected_menu_entry->expanded = !selected_menu_entry->expanded;
|
||||
goto refresh;
|
||||
}
|
||||
if (term_backend == NOT_READY) {
|
||||
if (term_backend == FALLBACK) {
|
||||
term_vbe(NULL, 0, 0);
|
||||
#if defined (BIOS)
|
||||
if (term_backend == NOT_READY) {
|
||||
if (term_backend == FALLBACK) {
|
||||
term_textmode();
|
||||
}
|
||||
#endif
|
||||
@ -876,6 +871,7 @@ noreturn void boot(char *config) {
|
||||
}
|
||||
|
||||
if (!strcmp(proto, "stivale1") || !strcmp(proto, "stivale") || !strcmp(proto, "stivale2")) {
|
||||
quiet = false;
|
||||
print("The stivale and stivale2 protocols are no longer supported as of Limine 4.x\n");
|
||||
print("Please notify kernel maintainers to move to the Limine boot protocol or\n");
|
||||
print("roll back to Limine 3.x.\n\n");
|
||||
@ -885,18 +881,21 @@ noreturn void boot(char *config) {
|
||||
#if defined (__x86_64__) || defined (__i386__)
|
||||
linux_load(config, cmdline);
|
||||
#else
|
||||
quiet = false;
|
||||
print("TODO: Linux is not available on aarch64.\n\n");
|
||||
#endif
|
||||
} else if (!strcmp(proto, "multiboot1") || !strcmp(proto, "multiboot")) {
|
||||
#if defined (__x86_64__) || defined (__i386__)
|
||||
multiboot1_load(config, cmdline);
|
||||
#else
|
||||
quiet = false;
|
||||
print("Multiboot 1 is not available on aarch64.\n\n");
|
||||
#endif
|
||||
} else if (!strcmp(proto, "multiboot2")) {
|
||||
#if defined (__x86_64__) || defined (__i386__)
|
||||
multiboot2_load(config, cmdline);
|
||||
#else
|
||||
quiet = false;
|
||||
print("Multiboot 2 is not available on aarch64.\n\n");
|
||||
#endif
|
||||
} else if (!strcmp(proto, "chainload_next")) {
|
||||
@ -905,5 +904,5 @@ noreturn void boot(char *config) {
|
||||
chainload(config);
|
||||
}
|
||||
|
||||
panic(true, "Incorrect protocol specified for kernel.");
|
||||
panic(true, "Unsupported protocol specified for kernel.");
|
||||
}
|
||||
|
@ -738,6 +738,7 @@ FEAT_START
|
||||
FEAT_END
|
||||
|
||||
term_deinit();
|
||||
quiet = true;
|
||||
|
||||
if (!fb_init(&fb, req_width, req_height, req_bpp)) {
|
||||
panic(true, "limine: Could not acquire framebuffer");
|
||||
|
@ -496,6 +496,7 @@ noreturn void linux_load(char *config, char *cmdline) {
|
||||
///////////////////////////////////////
|
||||
|
||||
term_deinit();
|
||||
quiet = true;
|
||||
|
||||
struct screen_info *screen_info = &boot_params->screen_info;
|
||||
|
||||
|
@ -303,6 +303,7 @@ noreturn void multiboot1_load(char *config, char *cmdline) {
|
||||
multiboot1_info->flags |= (1 << 9);
|
||||
|
||||
term_deinit();
|
||||
quiet = true;
|
||||
|
||||
if (header.flags & (1 << 2)) {
|
||||
size_t req_width = header.fb_width;
|
||||
|
@ -498,6 +498,7 @@ noreturn void multiboot2_load(char *config, char* cmdline) {
|
||||
tag->common.size = sizeof(struct multiboot_tag_framebuffer);
|
||||
|
||||
term_deinit();
|
||||
quiet = true;
|
||||
|
||||
if (fbtag) {
|
||||
size_t req_width = fbtag->width;
|
||||
|
Loading…
Reference in New Issue
Block a user