pr: ACPI Power Shutdown Implemented (#14)

* Flush PS/2 Devices on boot to avoid Locking dependent on the out buffer on real hardware / emulated PS2 over USB

Removed Slow and Unnessisarty flipping causing kconsole write slowdowns consequently speeding up the boot process

* sod wc

* ignoring dynamically created objects, added make run rule which will automatically detect the platform and then use the correct platform rule

* ACPI Power Shutdown
This commit is contained in:
Myles "Mellurboo" Wilson
2026-05-10 20:16:54 +01:00
committed by GitHub
parent 77744464e3
commit b85bb900e6
11 changed files with 516 additions and 98 deletions

View File

@@ -5,6 +5,8 @@
#include "wm.h"
#include "io.h"
#include "../drivers/acpi.h"
void k_memset(void *dest, int val, size_t len) {
unsigned char *ptr = (unsigned char *)dest;
while (len-- > 0) *ptr++ = (unsigned char)val;
@@ -16,6 +18,17 @@ void k_memcpy(void *dest, const void *src, size_t len) {
while (len-- > 0) *d++ = *s++;
}
int k_memcmp (const void *str1, const void *str2, size_t count) {
register const unsigned char *s1 = (const unsigned char*)str1;
register const unsigned char *s2 = (const unsigned char*)str2;
while (count-- > 0) {
if (*s1++ != *s2++)
return s1[-1] < s2[-1] ? -1 : 1;
}
return 0;
}
size_t k_strlen(const char *str) {
size_t len = 0;
while (str[len]) len++;
@@ -118,9 +131,7 @@ void k_reboot(void) {
}
void k_shutdown(void) {
outw(0xB004, 0x2000); // QEMU older / some pc machines
outw(0x604, 0x2000); // QEMU newer (i440fx/q35)
outw(0x4004, 0x3400); // VirtualBox fallback
acpi_shutdown();
}
volatile uint64_t beep_end_tick = 0;

View File

@@ -11,6 +11,7 @@
// Kernel string utilities
void k_memset(void *dest, int val, size_t len);
void k_memcpy(void *dest, const void *src, size_t len);
int k_memcmp (const void *str1, const void *str2, size_t count);
size_t k_strlen(const char *str);
int k_strcmp(const char *s1, const char *s2);
int k_strncmp(const char *s1, const char *s2, size_t n);

View File

@@ -26,6 +26,7 @@
#include "smp.h"
#include "work_queue.h"
#include "lapic.h"
#include "panic.h"
#include "fs/sysfs.h"
#include "fs/procfs.h"
#include "fs/bootfs.h"
@@ -34,6 +35,7 @@
#include "sys/bootfs_state.h"
#include "input/keymap.h"
#include "input/keyboard.h"
#include "../drivers/acpi.h"
extern void sysfs_init_subsystems(void);
@@ -78,6 +80,12 @@ static volatile struct limine_kernel_file_request kernel_file_request = {
.revision = 0
};
__attribute__((used, section(".requests")))
volatile struct limine_rsdp_request acpi_rsdp_request = {
.id = LIMINE_RSDP_REQUEST,
.revision = 0
};
__attribute__((used, section(".requests_start")))
static volatile struct limine_request *const requests_start_marker[] = {
(struct limine_request *)&framebuffer_request,
@@ -86,6 +94,7 @@ static volatile struct limine_request *const requests_start_marker[] = {
(struct limine_request *)&smp_request,
(struct limine_request *)&bootloader_info_request,
(struct limine_request *)&kernel_file_request,
(struct limine_request *)&acpi_rsdp_request,
NULL
};
@@ -366,9 +375,9 @@ void kmain(void) {
kconsole_set_color(0xFFFFFF55);
serial_write("Welcome to BoredOS!\n");
kconsole_set_color(0xFFFFFFFF);
acpi_init();
process_init();
fat32_init();
log_ok("FAT32 ready");

View File

@@ -17,129 +17,98 @@ static void draw_string_centered(int y, const char *s, uint32_t color) {
}
void kernel_panic(registers_t *regs, const char *error_name) {
// Disable interrupts to prevent nested panics
asm volatile("cli");
// Clear back buffer to black
graphics_clear_back_buffer(0x00000000);
int sh = get_screen_height();
int cy = sh / 2;
// Draw header
// Header
draw_string_centered(cy - 150, "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!", 0xFFFF0000);
draw_string_centered(cy - 130, "KERNEL EXCEPTION OCCURRED", 0xFFFFFFFF);
draw_string_centered(cy - 130, "KERNEL PANIC", 0xFFFFFFFF);
draw_string_centered(cy - 110, "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!", 0xFFFF0000);
// Error name
char err_buf[256];
char buf[256];
int pos = 0;
const char *prefix = "Exception: ";
while(prefix[pos]) { err_buf[pos] = prefix[pos]; pos++; }
const char *prefix = "Error: ";
while (prefix[pos]) { buf[pos] = prefix[pos]; pos++; }
int i = 0;
while(error_name[i]) { err_buf[pos++] = error_name[i++]; }
err_buf[pos] = 0;
draw_string_centered(cy - 70, err_buf, 0xFFFFCC00);
while (error_name[i]) { buf[pos++] = error_name[i++]; }
buf[pos] = 0;
draw_string_centered(cy - 70, buf, 0xFFFFCC00);
// Details - simplified centering by drawing them as a block or individually centered
char info_buf[64];
// Vector
pos = 0;
prefix = "Vector: ";
while(prefix[pos]) { info_buf[pos] = prefix[pos]; pos++; }
uint64_t v = regs->int_no;
const char* digits = "0123456789ABCDEF";
info_buf[pos++] = '0'; info_buf[pos++] = 'x';
for (int i = 15; i >= 0; i--) {
info_buf[pos + i] = digits[v & 0xF];
v >>= 4;
}
info_buf[pos + 16] = 0;
draw_string_centered(cy - 40, info_buf, 0xFFFFFFFF);
if (regs != NULL) {
// Exception details
char info_buf[64];
const char *digits = "0123456789ABCDEF";
// Error Code
pos = 0;
prefix = "Error Code: ";
while(prefix[pos]) { info_buf[pos] = prefix[pos]; pos++; }
v = regs->err_code;
info_buf[pos++] = '0'; info_buf[pos++] = 'x';
for (int i = 15; i >= 0; i--) {
info_buf[pos + i] = digits[v & 0xF];
v >>= 4;
}
info_buf[pos + 16] = 0;
draw_string_centered(cy - 20, info_buf, 0xFFFFFFFF);
#define FMT_HEX(prefix_str, value, color, y_offset) \
do { \
int pos = 0; \
const char *pfx = (prefix_str); \
while (pfx[pos]) { info_buf[pos] = pfx[pos]; pos++; } \
info_buf[pos++] = '0'; info_buf[pos++] = 'x'; \
uint64_t _v = (value); \
for (int _i = 15; _i >= 0; _i--) { \
info_buf[pos + _i] = digits[_v & 0xF]; _v >>= 4; \
} \
info_buf[pos + 16] = 0; \
draw_string_centered((y_offset), info_buf, (color)); \
} while (0)
// RIP
pos = 0;
prefix = "RIP: ";
while(prefix[pos]) { info_buf[pos] = prefix[pos]; pos++; }
v = regs->rip;
info_buf[pos++] = '0'; info_buf[pos++] = 'x';
for (int i = 15; i >= 0; i--) {
info_buf[pos + i] = digits[v & 0xF];
v >>= 4;
}
info_buf[pos + 16] = 0;
draw_string_centered(cy, info_buf, 0xFFFFFFFF);
FMT_HEX("Vector: ", regs->int_no, 0xFFFFFFFF, cy - 40);
FMT_HEX("Error Code: ", regs->err_code, 0xFFFFFFFF, cy - 20);
FMT_HEX("RIP: ", regs->rip, 0xFFFFFFFF, cy);
// CR2 for page faults
if (regs->int_no == 14) {
uint64_t cr2;
asm volatile("mov %%cr2, %0" : "=r"(cr2));
pos = 0;
prefix = "CR2: ";
while(prefix[pos]) { info_buf[pos] = prefix[pos]; pos++; }
info_buf[pos++] = '0'; info_buf[pos++] = 'x';
for (int i = 15; i >= 0; i--) {
info_buf[pos + i] = digits[cr2 & 0xF];
cr2 >>= 4;
if (regs->int_no == 14) {
uint64_t cr2;
asm volatile("mov %%cr2, %0" : "=r"(cr2));
FMT_HEX("CR2: ", cr2, 0xFFFF5555, cy + 20);
}
info_buf[pos + 16] = 0;
draw_string_centered(cy + 20, info_buf, 0xFFFF5555);
#undef FMT_HEX
}
// Message
draw_string_centered(cy + 100, "The system has been halted to prevent damage.", 0xFFFFFFFF);
draw_string_centered(cy + 120, "Please restart your computer.", 0xFFAAAAAA);
// Flip buffer to screen
graphics_mark_screen_dirty();
graphics_flip_buffer();
char hex_buf[17];
serial_write("\n*** KERNEL PANIC ***\n");
serial_write(error_name);
serial_write("\n");
serial_write("Vector: 0x");
k_itoa_hex(regs->int_no, hex_buf);
serial_write(hex_buf);
serial_write("\n");
if (regs != NULL) {
char hex_buf[17];
serial_write("Error Code: 0x");
k_itoa_hex(regs->err_code, hex_buf);
serial_write(hex_buf);
serial_write("\n");
serial_write("RIP: 0x");
k_itoa_hex(regs->rip, hex_buf);
serial_write(hex_buf);
serial_write("\n");
if (regs->int_no == 14) {
uint64_t cr2;
asm volatile("mov %%cr2, %0" : "=r"(cr2));
serial_write("CR2: 0x");
k_itoa_hex(cr2, hex_buf);
serial_write("Vector: 0x");
k_itoa_hex(regs->int_no, hex_buf);
serial_write(hex_buf);
serial_write("\n");
serial_write("Error Code: 0x");
k_itoa_hex(regs->err_code, hex_buf);
serial_write(hex_buf);
serial_write("\n");
serial_write("RIP: 0x");
k_itoa_hex(regs->rip, hex_buf);
serial_write(hex_buf);
serial_write("\n");
if (regs->int_no == 14) {
uint64_t cr2;
asm volatile("mov %%cr2, %0" : "=r"(cr2));
serial_write("CR2: 0x");
k_itoa_hex(cr2, hex_buf);
serial_write(hex_buf);
serial_write("\n");
}
}
// Halt
while(1) {
while (1) {
asm volatile("cli; hlt");
}
}

10
src/core/panic.h Normal file
View File

@@ -0,0 +1,10 @@
#ifndef PANIC_H
#define PANIC_H
#include "io.h"
#include "kutils.h"
#include "../sys/syscall.h"
void kernel_panic(registers_t *regs, const char *error_name);
#endif