From 300e80c2e806d8ec08e9166fb726a4c6cc156b79 Mon Sep 17 00:00:00 2001 From: Rick Rongen Date: Wed, 3 Mar 2021 22:12:37 +0100 Subject: [PATCH] feat: added shutdown command --- kernel/command.c | 20 ++++++++++++++------ kernel/drivers/ports.h | 27 ++++++++++++++++++--------- kernel/libk/libk.c | 18 ++++++++++-------- kernel/libk/libk.h | 5 +++-- kernel/util/power.c | 15 +++++++++++++++ kernel/util/power.h | 11 +++++++++++ 6 files changed, 71 insertions(+), 25 deletions(-) create mode 100644 kernel/util/power.c create mode 100644 kernel/util/power.h diff --git a/kernel/command.c b/kernel/command.c index 6e11d9e..f35929b 100644 --- a/kernel/command.c +++ b/kernel/command.c @@ -19,6 +19,7 @@ #include #include #include +#include #define BOOTLOADER_NAME_MAX_LENGTH 64 #define CMDLINE_MAX_LENGTH 256 @@ -39,16 +40,23 @@ void ide(const char *arg); void echo(const char *arg); -void help(const char *arg); +void help(const char *args); + +void shutdown(const char *args); cmd_handler cmd_handlers[] = { - {"help\0", help}, - {"echo\0", echo}, - {"print\0", print}, - {"ide\0", ide}, + {"help\0", help}, + {"echo\0", echo}, + {"print\0", print}, + {"ide\0", ide}, + {"shutdown", shutdown}, {NULL, NULL}, }; +void shutdown(const char *args) { + power_shutdown(); +} + void print_bootinfo() { printf("Bootloader name: %s\n" "cmdline: %s\n", @@ -124,7 +132,7 @@ void store_bootloader_info(multiboot_info_t *multiboot_info) { } } -void noreturn main_loop(void* data) { +void noreturn main_loop(void *data) { while (true) { char *msg = readline(NULL); char *args = strchr(msg, ' '); diff --git a/kernel/drivers/ports.h b/kernel/drivers/ports.h index 88bff37..78ebb93 100644 --- a/kernel/drivers/ports.h +++ b/kernel/drivers/ports.h @@ -6,6 +6,17 @@ #define PORT_PIC_SLAVE_COMMAND 0xA0 #define PORT_PIC_SLAVE_DATA 0xA1 +// https://wiki.osdev.org/PIT +#define PORT_PIT_COMMAND 0x43 +#define PORT_PIT_DATA_0 0x40 +#define PORT_PIT_DATA_1 0x41 +#define PORT_PIT_DATA_3 0x42 + +// https://wiki.osdev.org/%228042%22_PS/2_Controller +#define PORT_PS2_DATA 0x60 +#define PORT_PS2_STATUS 0x64 +#define PORT_PS2_COMMAND 0x64 + //http://www.osdever.net/FreeVGA/vga/crtcreg.htm#0A #define PORT_REG_SCREEN_CTRL 0x3d4 #define PORT_REG_SCREEN_CTRL_CURSOR_H 0x0E @@ -29,16 +40,14 @@ #define PORT_SERIAL_MODEM_STATUS 6 #define PORT_SERIAL_SCRATCH 6 -// https://wiki.osdev.org/PIT -#define PORT_PIT_COMMAND 0x43 -#define PORT_PIT_DATA_0 0x40 -#define PORT_PIT_DATA_1 0x41 -#define PORT_PIT_DATA_3 0x42 +#define PORT_ACPI 0xB004 +#define PORT_ACPI_SHUTDOWN 0x2000 -// https://wiki.osdev.org/%228042%22_PS/2_Controller -#define PORT_PS2_DATA 0x60 -#define PORT_PS2_STATUS 0x64 -#define PORT_PS2_COMMAND 0x64 +#define PORT_QEMU_COMMAND 0x604 +#define PORT_QEMU_COMMAND_SHUTDOWN 0x2000 + +#define PORT_VBOX 0x4004 +#define PORT_VBOX_SHUTDOWN 0x3400 // https://wiki.osdev.org/PCI #define PORT_PCI_CONFIG_ADDRESS (0xCF8) diff --git a/kernel/libk/libk.c b/kernel/libk/libk.c index 373ac2e..89d01ff 100644 --- a/kernel/libk/libk.c +++ b/kernel/libk/libk.c @@ -3,8 +3,9 @@ // #include +#include +#include #include "libk.h" -#include "kprint.h" bool k_addr_in_kspace(void* addr) { return addr > kernel_start && addr < kernel_end; @@ -14,15 +15,16 @@ void k_wait_for_interrupt() { __asm__ __volatile__("hlt;"); } -void k_panics(const char *msg) { +void noreturn k_panics(const char *msg) { + // todo this is not printed kprint(msg); - kprint("PANIC!"); - __asm__ __volatile__("cli;" - "hlt;"); + k_panic(); } -void k_panic() { +void noreturn k_panic() { kprint("PANIC!"); - __asm__ __volatile__("cli;" - "hlt;"); + while (true) { + __asm__ __volatile__("cli;" + "hlt;"); + } } diff --git a/kernel/libk/libk.h b/kernel/libk/libk.h index 17c0213..9352359 100644 --- a/kernel/libk/libk.h +++ b/kernel/libk/libk.h @@ -4,6 +4,7 @@ #ifndef NEW_KERNEL_LIBK_H #define NEW_KERNEL_LIBK_H +#include #include extern void* _kernel_start; @@ -15,8 +16,8 @@ bool k_addr_in_kspace(void *addr); void k_wait_for_interrupt(); -void k_panics(const char *msg); +void noreturn k_panics(const char *msg); -void k_panic(); +void noreturn k_panic(); #endif //NEW_KERNEL_LIBK_H diff --git a/kernel/util/power.c b/kernel/util/power.c new file mode 100644 index 0000000..e98b241 --- /dev/null +++ b/kernel/util/power.c @@ -0,0 +1,15 @@ +// +// Created by rick on 03-03-21. +// + +#include +#include +#include +#include "power.h" + +void noreturn power_shutdown() { + port_word_out(PORT_ACPI, PORT_ACPI_SHUTDOWN); + port_word_out(PORT_QEMU_COMMAND, PORT_QEMU_COMMAND_SHUTDOWN); + port_word_out(PORT_VBOX, PORT_VBOX_SHUTDOWN); + k_panics("Failed to shut down!\n"); +} \ No newline at end of file diff --git a/kernel/util/power.h b/kernel/util/power.h new file mode 100644 index 0000000..17b1400 --- /dev/null +++ b/kernel/util/power.h @@ -0,0 +1,11 @@ +// +// Created by rick on 03-03-21. +// + +#ifndef NEW_KERNEL_POWER_H +#define NEW_KERNEL_POWER_H +#include + +void noreturn power_shutdown(); + +#endif //NEW_KERNEL_POWER_H