fox32os: Implement multitasking and add a jump table for applications
This commit is contained in:
parent
6ae69cede7
commit
995b01dfd2
15
fox32os.def
Normal file
15
fox32os.def
Normal file
|
@ -0,0 +1,15 @@
|
|||
; fox32os routine definitions
|
||||
|
||||
; system jump table
|
||||
get_os_version: jmp [0x00000810]
|
||||
|
||||
; FXF jump table
|
||||
parse_fxf_binary: jmp [0x00000820]
|
||||
|
||||
; task jump table
|
||||
new_task: jmp [0x00000830]
|
||||
yield_task: jmp [0x00000834]
|
||||
end_current_task: jmp [0x00000838]
|
||||
|
||||
; memory jump table
|
||||
allocate_memory: jmp [0x00000840]
|
|
@ -4,13 +4,13 @@
|
|||
; inputs:
|
||||
; r0: pointer to memory buffer containing an FXF binary
|
||||
; outputs:
|
||||
; none
|
||||
execute_fxf_binary:
|
||||
; r0: relocation address
|
||||
parse_fxf_binary:
|
||||
; TODO: check the magic bytes and header version
|
||||
|
||||
call fxf_reloc
|
||||
|
||||
jmp r0
|
||||
ret
|
||||
|
||||
#include "fxf/reloc.asm"
|
||||
|
||||
|
|
|
@ -9,6 +9,27 @@ const FOX32OS_VERSION_PATCH: 0
|
|||
const BACKGROUND_COLOR: 0xFF674764
|
||||
const TEXT_COLOR: 0xFFFFFFFF
|
||||
|
||||
jmp entry
|
||||
|
||||
jump_table:
|
||||
; system jump table
|
||||
org.pad 0x00000810
|
||||
data.32 get_os_version
|
||||
|
||||
; FXF jump table
|
||||
org.pad 0x00000820
|
||||
data.32 parse_fxf_binary
|
||||
|
||||
; task jump table
|
||||
org.pad 0x00000830
|
||||
data.32 new_task
|
||||
data.32 yield_task
|
||||
data.32 end_current_task
|
||||
|
||||
; memory jump table
|
||||
org.pad 0x00000840
|
||||
data.32 allocate_memory
|
||||
|
||||
; initialization code
|
||||
entry:
|
||||
; clear the background
|
||||
|
@ -48,16 +69,23 @@ draw_startup_text:
|
|||
cmp r0, 0
|
||||
ifz jmp startup_error
|
||||
|
||||
; read the startup file into memory starting at the bottom of the kernel
|
||||
; read the startup file into memory starting at 0x03000000
|
||||
mov r0, startup_file_struct
|
||||
mov r1, kernel_bottom
|
||||
mov r1, 0x03000000
|
||||
call ryfs_read_whole_file
|
||||
|
||||
; relocate and execute it!!!
|
||||
mov r0, kernel_bottom
|
||||
call execute_fxf_binary
|
||||
; relocate and execute it as a new task
|
||||
mov r0, 0x03000000
|
||||
call parse_fxf_binary
|
||||
mov r1, r0
|
||||
mov r0, 0
|
||||
mov r2, rsp
|
||||
call new_task
|
||||
|
||||
rjmp 0
|
||||
; when the startup file yields for the first time, we'll end up back here
|
||||
; jump back to it without adding this "task" (not really a task) into the queue
|
||||
; this does not return
|
||||
call end_current_task
|
||||
|
||||
startup_error:
|
||||
mov r0, BACKGROUND_COLOR
|
||||
|
@ -74,8 +102,15 @@ startup_error:
|
|||
call draw_format_str_to_background
|
||||
rjmp 0
|
||||
|
||||
get_os_version:
|
||||
mov r0, FOX32OS_VERSION_MAJOR
|
||||
mov r1, FOX32OS_VERSION_MINOR
|
||||
mov r2, FOX32OS_VERSION_PATCH
|
||||
ret
|
||||
|
||||
#include "allocator.asm"
|
||||
#include "fxf/fxf.asm"
|
||||
#include "task.asm"
|
||||
|
||||
startup_str: data.str "fox32 - OS version %u.%u.%u" data.8 0
|
||||
startup_error_str: data.str "fox32 - OS version %u.%u.%u - startup.cfg is invalid!" data.8 0
|
||||
|
|
164
kernel/task.asm
Normal file
164
kernel/task.asm
Normal file
|
@ -0,0 +1,164 @@
|
|||
; task switching routines
|
||||
|
||||
; add a new task to the queue and jump to it immediately
|
||||
; inputs:
|
||||
; r0: task ID
|
||||
; r1: task instruction pointer
|
||||
; r2: task stack pointer
|
||||
; outputs:
|
||||
; none
|
||||
new_task:
|
||||
bse [task_id_bitmap], r0 ; mark this task ID as used
|
||||
|
||||
mov r4, r2
|
||||
mov r3, r1
|
||||
mov r2, r0
|
||||
|
||||
mov r0, [task_queue_ptr]
|
||||
call task_store
|
||||
mov [task_queue_ptr], r0
|
||||
|
||||
; fall-through
|
||||
|
||||
; switch to the next task in the queue
|
||||
; inputs:
|
||||
; none
|
||||
; outputs:
|
||||
; none
|
||||
yield_task:
|
||||
; add the current task back into the queue
|
||||
mov r0, current_task ; get the current task struct
|
||||
call task_load
|
||||
pop r3 ; pop the return address off of the stack
|
||||
mov r4, rsp
|
||||
mov r0, [task_queue_ptr]
|
||||
call task_store
|
||||
mov [task_queue_ptr], r0
|
||||
|
||||
jmp yield_task_0
|
||||
|
||||
; switch to the next task without adding the current task back into the queue
|
||||
; inputs:
|
||||
; none
|
||||
; outputs:
|
||||
; none
|
||||
end_current_task:
|
||||
cmp [task_queue_ptr], task_queue_bottom
|
||||
ifz jmp task_empty
|
||||
|
||||
mov r0, current_task ; get the current task struct
|
||||
call task_load
|
||||
bcl [task_id_bitmap], r2 ; mark this task ID as unused
|
||||
pop r0 ; pop the return address off of the stack
|
||||
yield_task_0:
|
||||
mov r0, task_queue_bottom
|
||||
call task_load
|
||||
mov r0, current_task
|
||||
call task_store
|
||||
|
||||
mov r1, task_queue_bottom
|
||||
yield_task_1:
|
||||
add r1, TASK_SIZE
|
||||
|
||||
cmp [task_queue_ptr], r1
|
||||
ifz jmp yield_task_2
|
||||
|
||||
mov r0, r1
|
||||
call task_load
|
||||
|
||||
mov r0, r1
|
||||
sub r0, TASK_SIZE
|
||||
call task_store
|
||||
|
||||
jmp yield_task_1
|
||||
yield_task_2:
|
||||
mov r0, current_task
|
||||
call task_load
|
||||
sub [task_queue_ptr], TASK_SIZE
|
||||
|
||||
mov rsp, r4
|
||||
jmp r3
|
||||
|
||||
; get the next unused task ID, starting at 1
|
||||
; inputs:
|
||||
; none
|
||||
; outputs:
|
||||
; r0: task ID, or zero if all IDs are used
|
||||
get_unused_task_id:
|
||||
mov r0, 1
|
||||
get_unused_task_id_loop:
|
||||
bts [task_id_bitmap], r0
|
||||
ifz ret
|
||||
inc r0
|
||||
cmp r0, 32
|
||||
iflt jmp get_unused_task_id_loop
|
||||
; if we reach this point, then add task IDs are used
|
||||
mov r0, 0
|
||||
ret
|
||||
|
||||
task_load:
|
||||
mov r2, [r0] ; task ID
|
||||
add r0, 4
|
||||
mov r3, [r0] ; instruction pointer
|
||||
add r0, 4
|
||||
mov r4, [r0] ; stack pointer
|
||||
add r0, 4
|
||||
ret
|
||||
|
||||
task_store:
|
||||
mov [r0], r2 ; task ID
|
||||
add r0, 4
|
||||
mov [r0], r3 ; instruction pointer
|
||||
add r0, 4
|
||||
mov [r0], r4 ; stack pointer
|
||||
add r0, 4
|
||||
ret
|
||||
|
||||
task_empty:
|
||||
mov r0, task_panic_str
|
||||
mov r1, task_queue_bottom ; show the address of the task queue in the panic brk output
|
||||
mov r2, [task_queue_ptr] ; show the the task queue pointer in the panic brk output
|
||||
call panic
|
||||
|
||||
task_panic_str: data.str "Task queue empty! Hanging here" data.8 10 data.8 0
|
||||
|
||||
const TASK_SIZE: 12
|
||||
task_id_bitmap: data.32 0
|
||||
current_task:
|
||||
data.32 0 ; task ID
|
||||
data.32 0 ; instruction pointer
|
||||
data.32 0 ; stack pointer
|
||||
task_queue_ptr: data.32 task_queue_bottom
|
||||
task_queue_bottom:
|
||||
data.32 0 data.32 0 data.32 0
|
||||
data.32 0 data.32 0 data.32 0
|
||||
data.32 0 data.32 0 data.32 0
|
||||
data.32 0 data.32 0 data.32 0
|
||||
data.32 0 data.32 0 data.32 0
|
||||
data.32 0 data.32 0 data.32 0
|
||||
data.32 0 data.32 0 data.32 0
|
||||
data.32 0 data.32 0 data.32 0
|
||||
data.32 0 data.32 0 data.32 0
|
||||
data.32 0 data.32 0 data.32 0
|
||||
data.32 0 data.32 0 data.32 0
|
||||
data.32 0 data.32 0 data.32 0
|
||||
data.32 0 data.32 0 data.32 0
|
||||
data.32 0 data.32 0 data.32 0
|
||||
data.32 0 data.32 0 data.32 0
|
||||
data.32 0 data.32 0 data.32 0
|
||||
data.32 0 data.32 0 data.32 0
|
||||
data.32 0 data.32 0 data.32 0
|
||||
data.32 0 data.32 0 data.32 0
|
||||
data.32 0 data.32 0 data.32 0
|
||||
data.32 0 data.32 0 data.32 0
|
||||
data.32 0 data.32 0 data.32 0
|
||||
data.32 0 data.32 0 data.32 0
|
||||
data.32 0 data.32 0 data.32 0
|
||||
data.32 0 data.32 0 data.32 0
|
||||
data.32 0 data.32 0 data.32 0
|
||||
data.32 0 data.32 0 data.32 0
|
||||
data.32 0 data.32 0 data.32 0
|
||||
data.32 0 data.32 0 data.32 0
|
||||
data.32 0 data.32 0 data.32 0
|
||||
data.32 0 data.32 0 data.32 0
|
||||
data.32 0 data.32 0 data.32 0
|
Loading…
Reference in New Issue
Block a user