URL
https://opencores.org/ocsvn/open8_urisc/open8_urisc/trunk
Subversion Repositories open8_urisc
Compare Revisions
- This comparison shows the changes necessary to convert path
/open8_urisc
- from Rev 303 to Rev 304
- ↔ Reverse comparison
Rev 303 → Rev 304
/trunk/taskmgr/taskmgr_const.s
297,29 → 297,59
STA R0, TaskMgr.Fault_Task; |
.ENDM |
|
; TASK_SETUP is a template used to generate code that sets up a single task's |
; stack and stack pointer for each a task. This macros will temporarily |
; relocate the stack pointer, push the task's initial state to the task's |
; stack. Note that it is important to also ensure that the stack has data to |
; not only restore the return address, but also R7:R0, as well as the flag |
; state. |
.MACRO TASK_SETUP |
; BACKUP_FULL_CONTEXT pushes all 8 registers to the stack |
.MACRO BACKUP_FULL_CONTEXT |
PSH R0 |
PSH R1 |
PSH R2 |
PSH R3 |
PSH R4 |
PSH R5 |
PSH R6 |
PSH R7 |
.ENDM |
|
; Setup a pointer in R3:R2 to the beginning of the parameter |
; table to load task information from. |
LDI R0, #\@ |
; RESTORE_FULL_CONTEXT pops all 8 registers off of the stack |
.MACRO RESTORE_FULL_CONTEXT |
POP R7 |
POP R6 |
POP R5 |
POP R4 |
POP R3 |
POP R2 |
POP R1 |
POP R0 |
.ENDM |
|
; REINIT_TASK_TABLE_PTR uses the This_Task variable to configure R3:R2 as a |
; pointer into the TASK_PARAMS table. |
.MACRO REINIT_TASK_TABLE_PTR |
LDA R0, TaskMgr.This_Task |
LDI R1, #PARAM_TABLE_OFFSET |
MUL R1 |
|
LDA R2, TASK_PARAMS_PTR + 0 ; Load R3:R2 with the start of the |
LDA R3, TASK_PARAMS_PTR + 1 ; task paramenter region |
LDA R3, TASK_PARAMS_PTR + 1 ; task parameter region |
|
ADD R2 |
ADD R2 ; Add [R3:R2] + [R1:R0] -> [R3:R2] |
T0X R2 |
TX0 R1 |
ADC R3 |
T0X R3 |
.ENDM |
|
; SETUP_TASK is a template used to generate code that sets up a single task's |
; stack and stack pointer for each a task. This macros will temporarily |
; relocate the stack pointer, push the task's initial state to the task's |
; stack. Note that it is important to also ensure that the stack has data to |
; not only restore the return address, but also R7:R0, as well as the flag |
; state. |
.MACRO SETUP_TASK |
LDI R0, #\@ |
STA R0, TaskMgr.This_Task ; Write This_Task |
|
REINIT_TASK_TABLE_PTR ; Use This_Task to initialize R3:R2 |
|
; Get the task's starting stack address from the table and load |
; it into the CPU SP |
LDO R2, PARAM_STACK_ADDR_HIGH |
330,7 → 360,7
; From here on out, the CPU SP is pointing to the target task's |
; stack region, so we can initialize its stack memory |
|
; Write initial flag value |
; Write initial flag value to simulate entering code as an ISR |
CLR R0 |
PSH R0 |
|
346,27 → 376,41
|
; Setup the initial reg values |
CLR R0 ; Initialize all registers to 0 |
PSH R0 ; R0 |
PSH R0 ; R1 |
PSH R0 ; R2 |
PSH R0 ; R3 |
PSH R0 ; R4 |
PSH R0 ; R5 |
PSH R0 ; R6 |
PSH R0 ; R7 |
T0X R1 |
T0X R2 |
T0X R3 |
T0X R4 |
T0X R5 |
T0X R6 |
T0X R7 |
|
; Once the task's stack has been initialized, retrieve the new |
; stack pointer from the SP and store it in the task's backup |
; variable. |
; Once the task's initial state has been created, "suspend" |
; the task. This will effective initialize its state and |
; SP pointer |
SUSPEND_THIS_TASK |
.ENDM |
|
LDI R0, #\@ |
LDI R1, #STACK_TABLE_OFFSET |
; SUSPEND_THIS_TASK pushes all of the registers to a task's stack, then |
; backups up the stack pointer to the system memory backup location for that |
; task. |
.MACRO SUSPEND_THIS_TASK |
BACKUP_FULL_CONTEXT |
BACKUP_STACK_POINTER |
.ENDM |
|
; BACKUP_STACK_POINTER uses the This_Task variable to configure R3:R2 as a |
; pointer into the system memory where stack pointer backups are stored, then |
; obtains the current stack address and pushes it to the task's backup |
; SP variable |
.MACRO BACKUP_STACK_POINTER |
LDA R0, TaskMgr.This_Task ; Get the task number |
LDI R1, #STACK_TABLE_OFFSET ; Multiply it by 2 |
MUL R1 |
|
LDA R2, STACK_MEMORY_PTR + 0 |
LDA R3, STACK_MEMORY_PTR + 1 |
LDA R2, STACK_MEMORY_PTR + 0 ; Load R3:R2 with the start of the |
LDA R3, STACK_MEMORY_PTR + 1 ; stack memory region |
|
ADD R2 |
ADD R2 ; Add [R3:R2] + [R1:R0] -> [R3:R2] |
T0X R2 |
TX0 R1 |
ADC R3 |
378,18 → 422,10
STO R2,1 |
.ENDM |
|
; INSTANCE_TASK_SETUP expands to create setup code for all of the tasks based |
; on the template above. There should be one setup per task, hence the repeat |
; based on TASK_COUNT |
.MACRO INSTANCE_TASK_SETUP |
.REPT TASK_COUNT |
TASK_SETUP |
.ENDR |
.ENDM |
|
; REINIT_STACK_BUFFER_PTR uses the This_Task variable to configure R3:R2 as a |
; pointer into the system memory where stack pointer backups are stored. |
.MACRO REINIT_STACK_BUFFER_PTR |
; RESTORE_STACK_POINTER uses the This_Task variable to configure R3:R2 as a |
; pointer into the system memory where stack pointer backups are stored. It |
; then looks up the task's SP backup variable and pushes it back to the CPU SP |
.MACRO RESTORE_STACK_POINTER |
LDA R0, TaskMgr.This_Task ; Get the task number |
LDI R1, #STACK_TABLE_OFFSET ; Multiply it by 2 |
MUL R1 |
402,91 → 438,16
TX0 R1 |
ADC R3 |
T0X R3 |
.ENDM |
|
|
; REINIT_TASK_TABLE_PTR uses the This_Task variable to configure R3:R2 as a |
; pointer into the TASK_PARAMS table. |
.MACRO REINIT_TASK_TABLE_PTR |
|
LDA R0, TaskMgr.This_Task |
LDI R1, #PARAM_TABLE_OFFSET |
MUL R1 |
|
LDA R2, TASK_PARAMS_PTR + 0 ; Load R3:R2 with the start of the |
LDA R3, TASK_PARAMS_PTR + 1 ; task parameter region |
|
ADD R2 ; Add [R3:R2] + [R1:R0] -> [R3:R2] |
T0X R2 |
TX0 R1 |
ADC R3 |
T0X R3 |
.ENDM |
|
; BACKUP_FULL_CONTEXT pushes all 8 registers to the stack |
.MACRO BACKUP_FULL_CONTEXT |
PSH R0 |
PSH R1 |
PSH R2 |
PSH R3 |
PSH R4 |
PSH R5 |
PSH R6 |
PSH R7 |
.ENDM |
|
; RESTORE_FULL_CONTEXT pops all 8 registers off of the stack |
.MACRO RESTORE_FULL_CONTEXT |
POP R7 |
POP R6 |
POP R5 |
POP R4 |
POP R3 |
POP R2 |
POP R1 |
POP R0 |
.ENDM |
|
; SUSPEND_CURRENT_TASK pushes all of the registers to a task's stack, then |
; backups up the stack pointer to the system memory backup location for that |
; task. |
.MACRO SUSPEND_CURRENT_TASK |
BACKUP_FULL_CONTEXT |
|
REINIT_STACK_BUFFER_PTR |
|
RETRIEVE_SP ; Copy CPU SP -> R1:R0 |
STX R2 ; Push R1:R0 -> [R3:R2]* |
TX0 R1 |
STO R2,1 |
.ENDM |
|
; AWAKEN_NEXT_TASK is responsible for updating the Next_Task variable, then |
; using it to restore the stack pointer from the system memory copy. It then |
; updates the memory write protection parameters and I/O write qualification |
; register for the new task. Finally, it resets the pre-emption timer and |
; restores the register state from the task's stack. |
.MACRO AWAKEN_NEXT_TASK |
LDA R1, TaskMgr.Next_Task ; Copy Next_Task -> This_Task |
STA R1, TaskMgr.This_Task |
|
; This is a simple round-robin scheduler, unless an ISR alters the Next_Task |
; variable, so increment the task count, check it against the total task |
; count, and reset it to task 0 if necessary. |
|
INC R1 ; Increment the task count |
LDI R0, #TASK_COUNT ; Compare it with the task count |
XOR R1 |
BNZ _TS_ADV_TN_\@ ; If it matches the task count |
LDI R1, #$00 ; reset the counter to zero |
_TS_ADV_TN_\@:STA R1, TaskMgr.Next_Task ; Store the new value into Next_Task |
|
REINIT_STACK_BUFFER_PTR ; Lookup the new task's table pointer |
LDO R2,1 ; Copy [R3:R2]* -> R1:R0 |
T0X R1 |
LDX R2 |
RELOCATE_SP ; Update R1:R0 -> CPU SP |
.ENDM |
|
; RESTORE_TASK_PERMISSIONS looks up the current (new) task's RAM & I/O write |
; permissions (masks) and reconfigures the hardware to allow access. |
.MACRO RESTORE_TASK_PERMISSIONS |
REINIT_TASK_TABLE_PTR ; Setup R3:R2 to point to the task table |
|
; Rewrite the RAM WPR register for this task. Note that the WPR |
505,11 → 466,42
|
LDO R2, PARAM_WQL_LOW ; Update the new task's WQL |
STA R0, IO_WRITE_QUAL |
.ENDM |
|
; INIT_NEXT_TASK forces the Next_Task variable to 0 (Task 0) |
.MACRO INIT_NEXT_TASK |
CLR R0 |
STA R0, TaskMgr.Next_Task |
.ENDM |
|
; ADVANCE_NEXT_TASK implements the simple scheduler. By default, the task |
; manager uses a simple round-robin scheduler, unless an ISR alters the |
; Next_Task variable, so increment the task count, check it against the |
; total task count, and reset it to task 0 if necessary. |
.MACRO ADVANCE_NEXT_TASK |
LDA R1, TaskMgr.Next_Task ; Copy Next_Task -> This_Task |
STA R1, TaskMgr.This_Task |
|
INC R1 ; Increment the task count |
LDI R0, #TASK_COUNT ; Compare it with the task count |
XOR R1 |
BNZ _TS_ADV_TN_\@ ; If it matches the task count |
LDI R1, #$00 ; reset the counter to zero |
_TS_ADV_TN_\@:STA R1, TaskMgr.Next_Task ; Store the new value into Next_Task |
.ENDM |
|
; AWAKEN_NEXT_TASK is responsible for updating the Next_Task variable, then |
; using it to restore the stack pointer from the system memory copy. It then |
; updates the memory write protection parameters and I/O write qualification |
; register for the new task. Finally, it resets the pre-emption timer and |
; restores the register state from the task's stack. |
.MACRO AWAKEN_NEXT_TASK |
ADVANCE_NEXT_TASK ; Advance the task positions |
RESTORE_STACK_POINTER ; Lookup the new task's table pointer |
RESTORE_TASK_PERMISSIONS ; Restore the task's write access masks |
RESET_PREEMPTION_TIMER ; Reset the PIT timer |
|
RESTORE_FULL_CONTEXT ; Restore the new task's register state |
RTI |
RTI ; Return to the new task |
.ENDM |
;------------------------------------------------------------------------------ |
|
523,10 → 515,13
; panic ISR is in place. |
;------------------------------------------------------------------------------ |
|
; INIT_NEXT_TASK forces the Next_Task variable to 0 (Task 0) |
.MACRO INIT_NEXT_TASK |
CLR R0 |
STA R0, TaskMgr.Next_Task |
; INSTANCE_TASK_SETUP expands to create setup code for all of the tasks based |
; on the template above. There should be one setup per task, hence the repeat |
; based on TASK_COUNT |
.MACRO INSTANCE_TASK_SETUP |
.REPT TASK_COUNT |
SETUP_TASK |
.ENDR |
.ENDM |
|
.MACRO BOOT_SYSTEM |
563,11 → 558,11
ENABLE_CPU_INTS ; Enable the CPU interrupt inputs |
|
; Like the task switcher ISR, restore the full CPU state for the first task |
INIT_NEXT_TASK |
AWAKEN_NEXT_TASK |
INIT_NEXT_TASK ; Reset the next task to task 0 |
AWAKEN_NEXT_TASK ; Load task 0's context to system |
|
; Create all of the task loops here. |
INSTANCE_TASK_LOOPS |
INSTANCE_TASK_LOOPS ; Instantiate the main task loops |
.ENDM |
;------------------------------------------------------------------------------ |
|
721,7 → 716,7
;------------------------------------------------------------------------------ |
|
.MACRO SWITCH_TASKS |
SUSPEND_CURRENT_TASK |
SUSPEND_THIS_TASK |
AWAKEN_NEXT_TASK |
.ENDM |
|