diff --git a/PROTOCOL.md b/PROTOCOL.md index 0a79d272..ce9ed30f 100644 --- a/PROTOCOL.md +++ b/PROTOCOL.md @@ -322,34 +322,38 @@ struct limine_terminal_request { Response: ```c +typedef void (*limine_terminal_write)(struct limine_terminal *terminal, const char *string, uint64_t length); + struct limine_terminal_response { uint64_t revision; uint64_t terminal_count; struct limine_terminal **terminals; + limine_terminal_write write; }; ``` * `terminal_count` - How many terminals are present. * `terminals` - Pointer to an array of `terminal_count` pointers to `struct limine_terminal` structures. +* `write` - Physical pointer to the terminal write() function. +The function is not thread-safe, nor reentrant, per-terminal. +This means multiple terminals may be called simultaneously, and multiple +callbacks may be handled simultaneously. +The `terminal` parameter points to the `struct limine_terminal` structure to +use to output the string; the `string` parameter points to a +string to print; the `length` paremeter contains the length, in bytes, of the +string to print. ```c -typedef void (*limine_terminal_write)(const char *, uint64_t); - struct limine_terminal { uint32_t columns; uint32_t rows; struct limine_framebuffer *framebuffer; - limine_terminal_write write; }; ``` * `columns` and `rows` - Columns and rows provided by the terminal. * `framebuffer` - The framebuffer associated with this terminal. -* `write` - Physical pointer to the terminal write() function. -The function is not thread-safe, nor reentrant, per-terminal. -This means multiple terminals may be called simultaneously, and multiple -callbacks may be handled simultaneously. Note: Omitting this request will cause the bootloader to not initialise the terminal service. @@ -373,7 +377,7 @@ void callback(struct limine_terminal *terminal, uint64_t type, uint64_t, uint64_ ``` The `terminal` argument is a pointer to the Limine terminal structure which -has the `write()` call that caused the callback. +represents the terminal that caused the callback. The purpose of the last 3 arguments changes depending on the `type` argument. diff --git a/common/protos/limine.c b/common/protos/limine.c index 0cd99fda..c5b6e134 100644 --- a/common/protos/limine.c +++ b/common/protos/limine.c @@ -108,9 +108,15 @@ static void *_get_request(uint64_t id[4]) { extern symbol stivale2_term_write_entry; extern void *stivale2_rt_stack; extern uint64_t stivale2_term_callback_ptr; +extern uint64_t stivale2_term_write_ptr; void stivale2_term_callback(uint64_t, uint64_t, uint64_t, uint64_t, uint64_t); #endif +static void term_write_shim(uint64_t context, uint64_t buf, uint64_t count) { + (void)context; + term_write(buf, count); +} + bool limine_load(char *config, char *cmdline) { uint32_t eax, ebx, ecx, edx; @@ -589,9 +595,10 @@ FEAT_START stivale2_rt_stack = ext_mem_alloc(16384) + 16384; } - terminal->write = (uintptr_t)(void *)stivale2_term_write_entry; + stivale2_term_write_ptr = (uintptr_t)term_write_shim; + terminal_response->write = (uintptr_t)(void *)stivale2_term_write_entry; #elif defined (__x86_64__) - terminal->write = (uintptr_t)term_write; + terminal_response->write = (uintptr_t)term_write_shim; #endif term_fb_ptr = &terminal->framebuffer; diff --git a/common/protos/stivale2.c b/common/protos/stivale2.c index 7fc8c3b8..26161e22 100644 --- a/common/protos/stivale2.c +++ b/common/protos/stivale2.c @@ -73,6 +73,7 @@ extern symbol stivale2_term_write_entry; void *stivale2_rt_stack = NULL; uint64_t stivale2_term_callback_ptr = 0; +uint64_t stivale2_term_write_ptr = 0; void stivale2_term_callback(uint64_t, uint64_t, uint64_t, uint64_t, uint64_t); #endif @@ -574,6 +575,7 @@ failed_to_load_header_section: stivale2_rt_stack = ext_mem_alloc(8192) + 8192; } + stivale2_term_write_ptr = (uintptr_t)term_write; tag->term_write = (uintptr_t)(void *)stivale2_term_write_entry; #elif defined (__x86_64__) tag->term_write = (uintptr_t)term_write; diff --git a/common/protos/stivale2_rt.asm32u b/common/protos/stivale2_rt.asm32u index a318f917..43222cfe 100644 --- a/common/protos/stivale2_rt.asm32u +++ b/common/protos/stivale2_rt.asm32u @@ -15,6 +15,7 @@ section .text extern term_write extern stivale2_rt_stack extern stivale2_term_callback_ptr +extern stivale2_term_write_ptr global stivale2_term_callback stivale2_term_callback: @@ -98,6 +99,7 @@ stivale2_term_write_entry: mov word [rbx + user_es wrt ..gotoff], es mov word [rbx + user_ss wrt ..gotoff], ss + push rdx push rsi push rdi @@ -113,8 +115,8 @@ bits 32 mov es, ax mov ss, ax - call term_write - add esp, 16 + call [ebx + stivale2_term_write_ptr wrt ..gotoff] + add esp, 24 push dword [ebx + user_cs wrt ..gotoff] call .p2 diff --git a/common/protos/stivale2_rt.asmb b/common/protos/stivale2_rt.asmb index 3f159c53..e979e6ef 100644 --- a/common/protos/stivale2_rt.asmb +++ b/common/protos/stivale2_rt.asmb @@ -13,6 +13,7 @@ section .text extern term_write extern stivale2_rt_stack extern stivale2_term_callback_ptr +extern stivale2_term_write_ptr global stivale2_term_callback stivale2_term_callback: @@ -82,6 +83,7 @@ bits 64 mov word [user_es], es mov word [user_ss], ss + push rdx push rsi push rdi @@ -95,8 +97,8 @@ bits 32 mov es, ax mov ss, ax - call term_write - add esp, 16 + call [stivale2_term_write_ptr] + add esp, 24 push dword [user_cs] push .mode64 diff --git a/limine.h b/limine.h index 5ad7b182..8136b3da 100644 --- a/limine.h +++ b/limine.h @@ -171,20 +171,20 @@ struct limine_framebuffer_request { struct limine_terminal; -typedef void (*limine_terminal_write)(const char *, uint64_t); +typedef void (*limine_terminal_write)(struct limine_terminal *, const char *, uint64_t); typedef void (*limine_terminal_callback)(struct limine_terminal *, uint64_t, uint64_t, uint64_t, uint64_t); struct limine_terminal { uint32_t columns; uint32_t rows; LIMINE_PTR(struct limine_framebuffer *) framebuffer; - LIMINE_PTR(limine_terminal_write) write; }; struct limine_terminal_response { uint64_t revision; uint64_t terminal_count; LIMINE_PTR(struct limine_terminal **) terminals; + LIMINE_PTR(limine_terminal_write) write; }; struct limine_terminal_request { diff --git a/test/limine.c b/test/limine.c index ecdfc6a5..e809ca00 100644 --- a/test/limine.c +++ b/test/limine.c @@ -136,9 +136,15 @@ static void print_file(struct limine_file *file) { extern char kernel_start[]; +static void write_shim(const char *s, uint64_t l) { + struct limine_terminal *terminal = _terminal_request.response->terminals[0]; + + _terminal_request.response->write(terminal, s, l); +} + static void limine_main(void) { if (_terminal_request.response) { - stivale2_print = _terminal_request.response->terminals[0]->write; + stivale2_print = write_shim; } e9_printf("\nWe're alive"); @@ -329,8 +335,8 @@ FEAT_START e9_printf("Columns: %d", terminal->columns); e9_printf("Rows: %d", terminal->rows); e9_printf("Using framebuffer: %x", terminal->framebuffer); - e9_printf("Write function at: %x", terminal->write); } + e9_printf("Write function at: %x", term_response->write); FEAT_END for (;;);