limine: Change terminal write contract
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 (;;);
