summaryrefslogtreecommitdiff
path: root/src/kernel/dump.c
diff options
context:
space:
mode:
authorBenji Dial <benji6283@gmail.com>2021-02-16 20:38:53 -0500
committerBenji Dial <benji6283@gmail.com>2021-02-16 20:38:53 -0500
commit47513bd32c256c4f35e3a8ced7d9fd7e15903530 (patch)
treecafdf75d52a954814726e07445063c41bb6599f9 /src/kernel/dump.c
parentbd7facc4b5f53481dc85a15ba123361b2758655b (diff)
downloadportland-os-47513bd32c256c4f35e3a8ced7d9fd7e15903530.tar.gz
terminal application with ipc, shift+pause state dumper, hello world for terminal, meminfo popup program
Diffstat (limited to 'src/kernel/dump.c')
-rw-r--r--src/kernel/dump.c187
1 files changed, 187 insertions, 0 deletions
diff --git a/src/kernel/dump.c b/src/kernel/dump.c
new file mode 100644
index 0000000..d0c02e6
--- /dev/null
+++ b/src/kernel/dump.c
@@ -0,0 +1,187 @@
+#include <stdint.h>
+
+#include "paging.h"
+#include "task.h"
+#include "log.h"
+
+extern const void _kernel_data_start;
+extern const void _kernel_data_end;
+extern const void _kernel_bss_end;
+
+static inline char c(uint8_t n) {
+ return (n > 0x20) && (n < 0x7f) ? (char)n : '.';
+}
+
+static uint8_t last_line[16];
+enum {
+ SECTION_START,
+ DOT_DOT_DOT,
+ SKIP
+} last_line_mode;
+
+static void write_mem_line(uint32_t addr) {
+ const uint8_t *const at = (const uint8_t *)addr;
+ if (last_line_mode != SECTION_START) {
+ for (uint8_t i = 0; i < 16; ++i)
+ if (at[i] != last_line[i])
+ goto diff_line;
+ if (last_line_mode == DOT_DOT_DOT) {
+ logf(LOG_DUMP, " 0x%h ...", addr);
+ last_line_mode = SKIP;
+ }
+ return;
+ }
+diff_line:
+ logf(LOG_DUMP,
+ " 0x%h %hb %hb %hb %hb %hb %hb %hb %hb %hb %hb %hb %hb %hb %hb %hb %hb %c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c", addr,
+ at[0], at[1], at[2], at[3], at[4], at[5], at[6], at[7],
+ at[9], at[9], at[10], at[11], at[12], at[13], at[14], at[15],
+ c(at[0]), c(at[1]), c(at[2]), c(at[3]),
+ c(at[4]), c(at[5]), c(at[6]), c(at[7]),
+ c(at[8]), c(at[9]), c(at[10]), c(at[11]),
+ c(at[12]), c(at[13]), c(at[14]), c(at[15])
+ );
+ for (uint8_t i = 0; i < 16; ++i)
+ last_line[i] = at[1];
+ last_line_mode = DOT_DOT_DOT;
+}
+
+static void write_mem_page(uint32_t page) {
+ for (uint32_t i = page << 12; i < (page + 1) << 12; i += 16)
+ write_mem_line(i);
+}
+
+#include "kbd.h"
+
+#define WAIT_TASK tasks[i].waits[t].task - tasks + 1, tasks[i].waits[t].task->name
+
+void dump(enum kbd_isr_result kind, const uint32_t edi, const uint32_t esi, const uint32_t ebx, const uint32_t edx, const uint32_t ecx, const uint32_t eax, const uint32_t eip, const uint32_t cs, const uint32_t eflags, const uint32_t esp, const uint32_t ss) {
+ uint32_t cr3;
+ asm volatile (
+ "mov %%cr3, %0"
+ : "=a" (cr3));
+
+ logf(LOG_INFO, "Dump state...");
+
+ switch (kind) {
+ case DUMP:
+ logf(LOG_DUMP, "Tasks:");
+ for (uint8_t t = 0; t < MAX_TASKS; ++t)
+ if (tasks[t].page_directory) {
+ logf(LOG_DUMP, " %s (0x%hb):", tasks[t].name, t + 1);
+ if (tasks + t == active_task) {
+ logf(LOG_DUMP, " *Active task*");
+ logf(LOG_DUMP, " cr3: 0x%h", cr3);
+ logf(LOG_DUMP, " eip: 0x%h", eip);
+ logf(LOG_DUMP, " eax: 0x%h", eax);
+ logf(LOG_DUMP, " ebx: 0x%h", ebx);
+ logf(LOG_DUMP, " ecx: 0x%h", ecx);
+ logf(LOG_DUMP, " edx: 0x%h", edx);
+ logf(LOG_DUMP, " esi: 0x%h", esi);
+ logf(LOG_DUMP, " edi: 0x%h", edi);
+ logf(LOG_DUMP, " esp: 0x%h", esp);
+ logf(LOG_DUMP, " cs: 0x%hb", cs);
+ logf(LOG_DUMP, " ss: 0x%hb", ss);
+ logf(LOG_DUMP, " eflags: 0x%h", eflags);
+ }
+ else {
+ logf(LOG_DUMP, " Stored cr3: 0x%h", tasks[t].page_directory);
+ logf(LOG_DUMP, " Stored eip: 0x%h", tasks[t].ret_addr);
+ logf(LOG_DUMP, " Stored ebx: 0x%h", tasks[t].ebx);
+ logf(LOG_DUMP, " Stored ecx: 0x%h", tasks[t].ecx);
+ logf(LOG_DUMP, " Stored edx: 0x%h", tasks[t].edx);
+ logf(LOG_DUMP, " Stored esi: 0x%h", tasks[t].esi);
+ logf(LOG_DUMP, " Stored edi: 0x%h", tasks[t].edi);
+ logf(LOG_DUMP, " Stored ebp: 0x%h", tasks[t].ebp);
+ logf(LOG_DUMP, " Stored esp: 0x%h", tasks[t].esp);
+ }
+ logf(LOG_DUMP, " Stack size: %d kibibytes", -tasks[t].stack_bottom / 1024);
+ if (tasks[t].waiting) {
+ logf(LOG_DUMP, " Waits:");
+ for (uint8_t i = 0; i < MAX_WAITS; ++i)
+ switch (tasks[i].waits[t].mode) {
+ case NONE:
+ continue;
+ case PROCESS_END:
+ logf(LOG_DUMP, " Waiting for task 0x%hb (%s) to end", WAIT_TASK);
+ continue;
+ case WINDOW_ACTION:
+ logf(LOG_DUMP, " Waiting for window action");
+ continue;
+ case IPC_SENT:
+ logf(LOG_DUMP, " Waiting for IPC to be sent by 0x%hb (%s)", WAIT_TASK);
+ continue;
+ case IPC_SENT_ANY:
+ logf(LOG_DUMP, " Waiting for IPC to be sent by anyone");
+ continue;
+ case IPC_READ:
+ logf(LOG_DUMP, " Waiting for IPC to be read by 0x%hb (%s)", WAIT_TASK);
+ continue;
+ default:
+ logf(LOG_DUMP, " Other (corrupted?)");
+ continue;
+ }
+ }
+ else
+ logf(LOG_DUMP, " Not waiting.");
+ }
+ break;
+
+ case SHIFT_DUMP:
+
+ logf(LOG_DUMP, "Current task: 0x%hb (%s)", active_task - tasks + 1, active_task->name);
+ logf(LOG_DUMP, "Registers:");
+ logf(LOG_DUMP, " cr3: 0x%h", cr3);
+ logf(LOG_DUMP, " eip: 0x%h", eip);
+ logf(LOG_DUMP, " esp: 0x%h", esp);
+ logf(LOG_DUMP, " eax: 0x%h", eax);
+ logf(LOG_DUMP, " ebx: 0x%h", ebx);
+ logf(LOG_DUMP, " ecx: 0x%h", ecx);
+ logf(LOG_DUMP, " edx: 0x%h", edx);
+ logf(LOG_DUMP, " esi: 0x%h", esi);
+ logf(LOG_DUMP, " edi: 0x%h", edi);
+ logf(LOG_DUMP, " eflags: 0x%h", eflags);
+ logf(LOG_DUMP, " cs: 0x%hb", cs);
+ logf(LOG_DUMP, " ss: 0x%hb", ss);
+
+ logf(LOG_DUMP, "Kernel data section:");
+ last_line_mode = SECTION_START;
+ for (uint32_t i = (uint32_t)&_kernel_data_start & ~0xf; i < (((uint32_t)&_kernel_data_end - 1) & ~0xf) + 0x10; i += 0x10)
+ write_mem_line(i);
+ logf(LOG_DUMP, "Kernel bss section:");
+ last_line_mode = SECTION_START;
+ for (uint32_t i = 0x4000000; i < (((uint32_t)&_kernel_bss_end - 1) & ~0xf) + 1; i += 0x10)
+ write_mem_line(i);
+ logf(LOG_DUMP, "Kernel heap:");
+ last_line_mode = SECTION_START;
+ const uint32_t first_heap_page = (((uint32_t)&_kernel_bss_end - 1) >> 12) + 1;
+ for (uint8_t n = first_heap_page & 7; n < 8; ++n)
+ if (*(uint8_t *)(0x40000 + (first_heap_page >> 3)) & (1 << n))
+ write_mem_page((first_heap_page & ~7) | n);
+ for (uint8_t *i = (uint8_t *)(0x40000 + (first_heap_page >> 3) + 1); i < (uint8_t *)0x41000; ++i)
+ for (uint8_t n = 0; n < 8; ++n)
+ if (*i & (1 << n))
+ write_mem_page((i - (uint8_t *)0x40000) * 8 + n);
+
+ for (uint8_t t = 0; t < MAX_TASKS; ++t)
+ if (tasks[t].page_directory) {
+ logf(LOG_DUMP, "Task 0x%hb (%s)'s memory:", t + 1, tasks[t].name);
+ last_line_mode = SECTION_START;
+ const void *const pd = tasks[t].page_directory;
+ asm (
+ "mov %0, %%cr3"
+ : : "a" (pd));
+ for (uint32_t i = 0x08000000; i; i += 4096)
+ if (pd_is_mapped(pd, i))
+ for (uint32_t j = i; j < i + 4096; j += 16)
+ write_mem_line(j);
+ }
+ break;
+ }
+
+ logf(LOG_INFO, "Dumped state.");
+
+ asm (
+ "mov %0, %%cr3"
+ : : "a" (cr3));
+} \ No newline at end of file