limine: Change terminal write contract

This commit is contained in:
mintsuki 2022-04-02 10:05:14 +02:00
parent c052509567
commit 5f525a1052
7 changed files with 41 additions and 18 deletions

View File

@ -322,34 +322,38 @@ struct limine_terminal_request {
Response: Response:
```c ```c
typedef void (*limine_terminal_write)(struct limine_terminal *terminal, const char *string, uint64_t length);
struct limine_terminal_response { struct limine_terminal_response {
uint64_t revision; uint64_t revision;
uint64_t terminal_count; uint64_t terminal_count;
struct limine_terminal **terminals; struct limine_terminal **terminals;
limine_terminal_write write;
}; };
``` ```
* `terminal_count` - How many terminals are present. * `terminal_count` - How many terminals are present.
* `terminals` - Pointer to an array of `terminal_count` pointers to * `terminals` - Pointer to an array of `terminal_count` pointers to
`struct limine_terminal` structures. `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 ```c
typedef void (*limine_terminal_write)(const char *, uint64_t);
struct limine_terminal { struct limine_terminal {
uint32_t columns; uint32_t columns;
uint32_t rows; uint32_t rows;
struct limine_framebuffer *framebuffer; struct limine_framebuffer *framebuffer;
limine_terminal_write write;
}; };
``` ```
* `columns` and `rows` - Columns and rows provided by the terminal. * `columns` and `rows` - Columns and rows provided by the terminal.
* `framebuffer` - The framebuffer associated with this 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 Note: Omitting this request will cause the bootloader to not initialise
the terminal service. 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 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. The purpose of the last 3 arguments changes depending on the `type` argument.

View File

@ -108,9 +108,15 @@ static void *_get_request(uint64_t id[4]) {
extern symbol stivale2_term_write_entry; extern symbol stivale2_term_write_entry;
extern void *stivale2_rt_stack; extern void *stivale2_rt_stack;
extern uint64_t stivale2_term_callback_ptr; 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); void stivale2_term_callback(uint64_t, uint64_t, uint64_t, uint64_t, uint64_t);
#endif #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) { bool limine_load(char *config, char *cmdline) {
uint32_t eax, ebx, ecx, edx; uint32_t eax, ebx, ecx, edx;
@ -589,9 +595,10 @@ FEAT_START
stivale2_rt_stack = ext_mem_alloc(16384) + 16384; 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__) #elif defined (__x86_64__)
terminal->write = (uintptr_t)term_write; terminal_response->write = (uintptr_t)term_write_shim;
#endif #endif
term_fb_ptr = &terminal->framebuffer; term_fb_ptr = &terminal->framebuffer;

View File

@ -73,6 +73,7 @@
extern symbol stivale2_term_write_entry; extern symbol stivale2_term_write_entry;
void *stivale2_rt_stack = NULL; void *stivale2_rt_stack = NULL;
uint64_t stivale2_term_callback_ptr = 0; 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); void stivale2_term_callback(uint64_t, uint64_t, uint64_t, uint64_t, uint64_t);
#endif #endif
@ -574,6 +575,7 @@ failed_to_load_header_section:
stivale2_rt_stack = ext_mem_alloc(8192) + 8192; 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; tag->term_write = (uintptr_t)(void *)stivale2_term_write_entry;
#elif defined (__x86_64__) #elif defined (__x86_64__)
tag->term_write = (uintptr_t)term_write; tag->term_write = (uintptr_t)term_write;

View File

@ -15,6 +15,7 @@ section .text
extern term_write extern term_write
extern stivale2_rt_stack extern stivale2_rt_stack
extern stivale2_term_callback_ptr extern stivale2_term_callback_ptr
extern stivale2_term_write_ptr
global stivale2_term_callback global stivale2_term_callback
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_es wrt ..gotoff], es
mov word [rbx + user_ss wrt ..gotoff], ss mov word [rbx + user_ss wrt ..gotoff], ss
push rdx
push rsi push rsi
push rdi push rdi
@ -113,8 +115,8 @@ bits 32
mov es, ax mov es, ax
mov ss, ax mov ss, ax
call term_write call [ebx + stivale2_term_write_ptr wrt ..gotoff]
add esp, 16 add esp, 24
push dword [ebx + user_cs wrt ..gotoff] push dword [ebx + user_cs wrt ..gotoff]
call .p2 call .p2

View File

@ -13,6 +13,7 @@ section .text
extern term_write extern term_write
extern stivale2_rt_stack extern stivale2_rt_stack
extern stivale2_term_callback_ptr extern stivale2_term_callback_ptr
extern stivale2_term_write_ptr
global stivale2_term_callback global stivale2_term_callback
stivale2_term_callback: stivale2_term_callback:
@ -82,6 +83,7 @@ bits 64
mov word [user_es], es mov word [user_es], es
mov word [user_ss], ss mov word [user_ss], ss
push rdx
push rsi push rsi
push rdi push rdi
@ -95,8 +97,8 @@ bits 32
mov es, ax mov es, ax
mov ss, ax mov ss, ax
call term_write call [stivale2_term_write_ptr]
add esp, 16 add esp, 24
push dword [user_cs] push dword [user_cs]
push .mode64 push .mode64

View File

@ -171,20 +171,20 @@ struct limine_framebuffer_request {
struct limine_terminal; 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); typedef void (*limine_terminal_callback)(struct limine_terminal *, uint64_t, uint64_t, uint64_t, uint64_t);
struct limine_terminal { struct limine_terminal {
uint32_t columns; uint32_t columns;
uint32_t rows; uint32_t rows;
LIMINE_PTR(struct limine_framebuffer *) framebuffer; LIMINE_PTR(struct limine_framebuffer *) framebuffer;
LIMINE_PTR(limine_terminal_write) write;
}; };
struct limine_terminal_response { struct limine_terminal_response {
uint64_t revision; uint64_t revision;
uint64_t terminal_count; uint64_t terminal_count;
LIMINE_PTR(struct limine_terminal **) terminals; LIMINE_PTR(struct limine_terminal **) terminals;
LIMINE_PTR(limine_terminal_write) write;
}; };
struct limine_terminal_request { struct limine_terminal_request {

View File

@ -136,9 +136,15 @@ static void print_file(struct limine_file *file) {
extern char kernel_start[]; 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) { static void limine_main(void) {
if (_terminal_request.response) { if (_terminal_request.response) {
stivale2_print = _terminal_request.response->terminals[0]->write; stivale2_print = write_shim;
} }
e9_printf("\nWe're alive"); e9_printf("\nWe're alive");
@ -329,8 +335,8 @@ FEAT_START
e9_printf("Columns: %d", terminal->columns); e9_printf("Columns: %d", terminal->columns);
e9_printf("Rows: %d", terminal->rows); e9_printf("Rows: %d", terminal->rows);
e9_printf("Using framebuffer: %x", terminal->framebuffer); 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 FEAT_END
for (;;); for (;;);