OpenCores
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
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.