OpenCores
URL https://opencores.org/ocsvn/open8_urisc/open8_urisc/trunk

Subversion Repositories open8_urisc

[/] [open8_urisc/] [trunk/] [taskmgr/] [taskmgr_const.s] - Diff between revs 303 and 304

Go to most recent revision | Show entire file | Details | Blame | View Log

Rev 303 Rev 304
Line 295... Line 295...
              STA  R0, TaskMgr.Fault_Flag
              STA  R0, TaskMgr.Fault_Flag
              LDA  R0, TaskMgr.This_Task
              LDA  R0, TaskMgr.This_Task
              STA  R0, TaskMgr.Fault_Task;
              STA  R0, TaskMgr.Fault_Task;
.ENDM
.ENDM
 
 
; TASK_SETUP is a template used to generate code that sets up a single task's
; BACKUP_FULL_CONTEXT pushes all 8 registers to the stack
; stack and stack pointer for each a task. This macros will temporarily
.MACRO BACKUP_FULL_CONTEXT
;  relocate the stack pointer, push the task's initial state to the task's
              PSH  R0
;  stack. Note that it is important to also ensure that the stack has data to
              PSH  R1
;  not only restore the return address, but also R7:R0, as well as the flag
              PSH  R2
;  state.
              PSH  R3
.MACRO TASK_SETUP
              PSH  R4
 
              PSH  R5
 
              PSH  R6
 
              PSH  R7
 
.ENDM
 
 
              ; Setup a pointer in R3:R2 to the beginning of the parameter
; RESTORE_FULL_CONTEXT pops all 8 registers off of the stack
              ;  table to load task information from.
.MACRO RESTORE_FULL_CONTEXT
              LDI  R0, #\@
              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
              LDI  R1, #PARAM_TABLE_OFFSET
              MUL  R1
              MUL  R1
 
 
              LDA  R2, TASK_PARAMS_PTR + 0  ; Load R3:R2 with the start of the
              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
              T0X  R2
              TX0  R1
              TX0  R1
              ADC  R3
              ADC  R3
              T0X  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
              ; Get the task's starting stack address from the table and load
              ;  it into the CPU SP
              ;  it into the CPU SP
              LDO  R2, PARAM_STACK_ADDR_HIGH
              LDO  R2, PARAM_STACK_ADDR_HIGH
              T0X  R1
              T0X  R1
Line 328... Line 358...
              RELOCATE_SP                 ; R1:R0 -> CPU SP
              RELOCATE_SP                 ; R1:R0 -> CPU SP
 
 
              ; From here on out, the CPU SP is pointing to the target task's
              ; From here on out, the CPU SP is pointing to the target task's
              ;  stack region, so we can initialize its stack memory
              ;  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
              CLR  R0
              PSH  R0
              PSH  R0
 
 
              ; Initialize the return address to point to the "initialize"
              ; Initialize the return address to point to the "initialize"
              ;  portion of the task, so that the task can do its one-time
              ;  portion of the task, so that the task can do its one-time
Line 344... Line 374...
              LDO  R2, PARAM_MAIN_ADDR_LOW  ; Write return PC LSB
              LDO  R2, PARAM_MAIN_ADDR_LOW  ; Write return PC LSB
              PSH  R0
              PSH  R0
 
 
              ; Setup the initial reg values
              ; Setup the initial reg values
              CLR  R0                  ; Initialize all registers to 0
              CLR  R0                  ; Initialize all registers to 0
              PSH  R0                  ; R0
              T0X  R1
              PSH  R0                  ; R1
 
              PSH  R0                  ; R2
 
              PSH  R0                  ; R3
 
              PSH  R0                  ; R4
 
              PSH  R0                  ; R5
 
              PSH  R0                  ; R6
 
              PSH  R0                  ; 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.
 
 
 
              LDI  R0, #\@
 
              LDI  R1, #STACK_TABLE_OFFSET
 
              MUL  R1
 
 
 
              LDA  R2, STACK_MEMORY_PTR + 0
 
              LDA  R3, STACK_MEMORY_PTR + 1
 
 
 
              ADD  R2
 
              T0X  R2
              T0X  R2
              TX0  R1
 
              ADC  R3
 
              T0X  R3
              T0X  R3
 
              T0X  R4
              RETRIEVE_SP
              T0X  R5
              STX  R2
              T0X  R6
              TX0  R1
              T0X  R7
              STO  R2,1
 
 
              ; 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
.ENDM
 
 
; INSTANCE_TASK_SETUP expands to create setup code for all of the tasks based
; SUSPEND_THIS_TASK pushes all of the registers to a task's stack, then
;  on the template above. There should be one setup per task, hence the repeat
;  backups up the stack pointer to the system memory backup location for that
;  based on TASK_COUNT
;  task.
.MACRO INSTANCE_TASK_SETUP
.MACRO SUSPEND_THIS_TASK
          .REPT TASK_COUNT
              BACKUP_FULL_CONTEXT
              TASK_SETUP
              BACKUP_STACK_POINTER
          .ENDR
 
.ENDM
.ENDM
 
 
; REINIT_STACK_BUFFER_PTR uses the This_Task variable to configure R3:R2 as a
; 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.
;  pointer into the system memory where stack pointer backups are stored, then
.MACRO REINIT_STACK_BUFFER_PTR
;  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
              LDA  R0, TaskMgr.This_Task    ; Get the task number
              LDI  R1, #STACK_TABLE_OFFSET  ; Multiply it by 2
              LDI  R1, #STACK_TABLE_OFFSET  ; Multiply it by 2
              MUL  R1
              MUL  R1
 
 
              LDA  R2, STACK_MEMORY_PTR + 0 ; Load R3:R2 with the start of the
              LDA  R2, STACK_MEMORY_PTR + 0 ; Load R3:R2 with the start of the
Line 400... Line 413...
              ADD  R2                  ; Add [R3:R2] + [R1:R0] -> [R3:R2]
              ADD  R2                  ; Add [R3:R2] + [R1:R0] -> [R3:R2]
              T0X  R2
              T0X  R2
              TX0  R1
              TX0  R1
              ADC  R3
              ADC  R3
              T0X  R3
              T0X  R3
.ENDM
 
 
 
 
 
; REINIT_TASK_TABLE_PTR uses the This_Task variable to configure R3:R2 as a
              RETRIEVE_SP
;  pointer into the TASK_PARAMS table.
              STX  R2
.MACRO REINIT_TASK_TABLE_PTR
              TX0  R1
 
              STO  R2,1
 
.ENDM
 
 
              LDA  R0, TaskMgr.This_Task
; RESTORE_STACK_POINTER uses the This_Task variable to configure R3:R2 as a
              LDI  R1, #PARAM_TABLE_OFFSET
;  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
              MUL  R1
 
 
              LDA  R2, TASK_PARAMS_PTR + 0  ; Load R3:R2 with the start of the
              LDA  R2, STACK_MEMORY_PTR + 0 ; Load R3:R2 with the start of the
              LDA  R3, TASK_PARAMS_PTR + 1  ;  task parameter region
              LDA  R3, STACK_MEMORY_PTR + 1 ;  stack memory region
 
 
              ADD  R2                       ; Add [R3:R2] + [R1:R0] -> [R3:R2]
              ADD  R2                       ; Add [R3:R2] + [R1:R0] -> [R3:R2]
              T0X  R2
              T0X  R2
              TX0  R1
              TX0  R1
              ADC  R3
              ADC  R3
              T0X  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
              LDO  R2,1                ; Copy [R3:R2]* -> R1:R0
              T0X  R1
              T0X  R1
              LDX  R2
              LDX  R2
              RELOCATE_SP              ; Update R1:R0 -> CPU SP
              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
              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
              ; Rewrite the RAM WPR register for this task. Note that the WPR
              ; is a 32-bit register.
              ; is a 32-bit register.
              LDO  R2, PARAM_WPR_BYTE0
              LDO  R2, PARAM_WPR_BYTE0
Line 503... Line 464...
              LDO  R2, PARAM_WPR_BYTE3
              LDO  R2, PARAM_WPR_BYTE3
              STA  R0, WPR_MASK_3
              STA  R0, WPR_MASK_3
 
 
              LDO  R2, PARAM_WQL_LOW   ; Update the new task's WQL
              LDO  R2, PARAM_WQL_LOW   ; Update the new task's WQL
              STA  R0, IO_WRITE_QUAL
              STA  R0, IO_WRITE_QUAL
 
.ENDM
 
 
              RESET_PREEMPTION_TIMER   ; Reset the PIT timer
; 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
              RESTORE_FULL_CONTEXT     ; Restore the new task's register state
              RTI
              RTI                      ; Return to the new task
.ENDM
.ENDM
;------------------------------------------------------------------------------
;------------------------------------------------------------------------------
 
 
;------------------------------------------------------------------------------
;------------------------------------------------------------------------------
; System Start
; System Start
Line 521... Line 513...
;  in supervisor mode, something has gone horribly wrong. This branch locks the
;  in supervisor mode, something has gone horribly wrong. This branch locks the
;  main loop if the I bit is not set. This is probably unnecessary now that the
;  main loop if the I bit is not set. This is probably unnecessary now that the
;  panic ISR is in place.
;  panic ISR is in place.
;------------------------------------------------------------------------------
;------------------------------------------------------------------------------
 
 
; INIT_NEXT_TASK forces the Next_Task variable to 0 (Task 0)
; INSTANCE_TASK_SETUP expands to create setup code for all of the tasks based
.MACRO INIT_NEXT_TASK
;  on the template above. There should be one setup per task, hence the repeat
              CLR  R0
;  based on TASK_COUNT
              STA  R0, TaskMgr.Next_Task
.MACRO INSTANCE_TASK_SETUP
 
          .REPT TASK_COUNT
 
              SETUP_TASK
 
          .ENDR
.ENDM
.ENDM
 
 
.MACRO BOOT_SYSTEM
.MACRO BOOT_SYSTEM
; Before beginning, turn off all of the CPU interrupts (The NMI will still be
; Before beginning, turn off all of the CPU interrupts (The NMI will still be
;  active, but memory write protection is effectively disabled with the I-bit
;  active, but memory write protection is effectively disabled with the I-bit
Line 561... Line 556...
.ENDIF
.ENDIF
; Once the external interrupt manager is configured, enable the CPU interrupts
; Once the external interrupt manager is configured, enable the CPU interrupts
              ENABLE_CPU_INTS             ; Enable the CPU interrupt inputs
              ENABLE_CPU_INTS             ; Enable the CPU interrupt inputs
 
 
; Like the task switcher ISR, restore the full CPU state for the first task
; Like the task switcher ISR, restore the full CPU state for the first task
              INIT_NEXT_TASK
              INIT_NEXT_TASK              ; Reset the next task to task 0
              AWAKEN_NEXT_TASK
              AWAKEN_NEXT_TASK            ; Load task 0's context to system
 
 
; Create all of the task loops here.
; Create all of the task loops here.
              INSTANCE_TASK_LOOPS
              INSTANCE_TASK_LOOPS         ; Instantiate the main task loops
.ENDM
.ENDM
;------------------------------------------------------------------------------
;------------------------------------------------------------------------------
 
 
;------------------------------------------------------------------------------
;------------------------------------------------------------------------------
; Task Loops
; Task Loops
Line 719... Line 714...
;
;
; Handles switching context between tasks when called.
; Handles switching context between tasks when called.
;------------------------------------------------------------------------------
;------------------------------------------------------------------------------
 
 
.MACRO SWITCH_TASKS
.MACRO SWITCH_TASKS
              SUSPEND_CURRENT_TASK
              SUSPEND_THIS_TASK
              AWAKEN_NEXT_TASK
              AWAKEN_NEXT_TASK
.ENDM
.ENDM
 
 
;------------------------------------------------------------------------------
;------------------------------------------------------------------------------
 
 

powered by: WebSVN 2.1.0

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