[25] | 1 | ################################################################################# |
---|
| 2 | # File : reset.s |
---|
| 3 | # Author : Alain Greiner |
---|
| 4 | # Date : 20/11/2009 |
---|
| 5 | ################################################################################# |
---|
| 6 | # This boot code creates four tasks running on the same processor, |
---|
| 7 | # and executing four different programs: main0, main1, main2, main3. |
---|
| 8 | # Each Task has his own terminal, and his own stack. |
---|
| 9 | # - It initializes the interrupt vector with 7 ISR addresses |
---|
| 10 | # ( timer, tty0, tty1, tty2, tty3, io, dma ) |
---|
| 11 | # - It initializes the _current_task_array & _task_number_array variables |
---|
| 12 | # - It initializes contexts for tasks T1,T2,T3 : EPC, SR, SP, RA |
---|
| 13 | # - It initializes registers for task T0 : EPC, SR, SP |
---|
| 14 | # - It initializes the Timer & ICU components. |
---|
| 15 | # - It jumps to main in user mode. |
---|
| 16 | ################################################################################# |
---|
| 17 | |
---|
| 18 | .section .reset,"ax",@progbits |
---|
| 19 | |
---|
| 20 | .extern seg_stack_base |
---|
| 21 | .extern seg_timer_base |
---|
| 22 | .extern seg_icu_base |
---|
| 23 | |
---|
| 24 | .extern _task_context |
---|
| 25 | .extern _current_task_array # running task index |
---|
| 26 | .extern _task_number_array # number of tasks |
---|
| 27 | |
---|
| 28 | .extern main0 |
---|
| 29 | .extern main1 |
---|
| 30 | .extern main2 |
---|
| 31 | .extern main3 |
---|
| 32 | |
---|
| 33 | .extern _interrupt_vector |
---|
| 34 | .extern _isr_tty_get_task0 |
---|
| 35 | .extern _isr_tty_get_task1 |
---|
| 36 | .extern _isr_tty_get_task2 |
---|
| 37 | .extern _isr_tty_get_task3 |
---|
| 38 | .extern _isr_ioc |
---|
| 39 | .extern _isr_dma |
---|
| 40 | .extern _isr_switch |
---|
| 41 | |
---|
| 42 | .globl reset # makes reset an external symbol |
---|
| 43 | .ent reset |
---|
| 44 | .align 2 |
---|
| 45 | |
---|
| 46 | reset: |
---|
| 47 | .set noreorder |
---|
| 48 | |
---|
| 49 | # initializes interrupt vector |
---|
| 50 | la $27, _interrupt_vector # $27 <= interrupt vector address |
---|
| 51 | la $26, _isr_switch # |
---|
| 52 | sw $26, 0($27) # interrupt_vector[0] <= _isr_switch |
---|
| 53 | la $26, _isr_tty_get_task0 # |
---|
| 54 | sw $26, 4($27) # interrupt_vector[1] <= _isr_tty_get_task0 |
---|
| 55 | la $26, _isr_tty_get_task1 # |
---|
| 56 | sw $26, 8($27) # interrupt_vector[2] <= _isr_tty_get_task1 |
---|
| 57 | la $26, _isr_tty_get_task2 # |
---|
| 58 | sw $26, 12($27) # interrupt_vector[3] <= _isr_tty_get_task2 |
---|
| 59 | la $26, _isr_tty_get_task3 # |
---|
| 60 | sw $26, 16($27) # interrupt_vector[4] <= _isr_tty_get_task3 |
---|
| 61 | la $26, _isr_ioc # |
---|
| 62 | sw $26, 20($27) # interrupt_vector[5] <= _isr_ioc |
---|
| 63 | la $26, _isr_dma # |
---|
| 64 | sw $26, 24($27) # interrupt_vector[6] <= _isr_dma |
---|
| 65 | |
---|
| 66 | # initializes task index & task number |
---|
| 67 | la $27, _current_task_array |
---|
| 68 | sw $0, 0($27) # task_index <= 0 |
---|
| 69 | la $27, _task_number_array |
---|
| 70 | li $26, 4 |
---|
| 71 | sw $26, 0($27) # task_number <= 4 |
---|
| 72 | |
---|
| 73 | # initializes stack pointers for tasks 1,2,3 (each stack is 64 KB) |
---|
| 74 | la $27, _task_context_array # $27 <= &ctx[] |
---|
| 75 | la $26, seg_stack_base |
---|
| 76 | li $10, 0x00020000 # 128 K |
---|
| 77 | add $10, $26, $10 |
---|
| 78 | sw $10, 4*(64+29)($27) # SP for task 1 |
---|
| 79 | li $10, 0x00030000 # 192 K |
---|
| 80 | add $10, $26, $10 |
---|
| 81 | sw $10, 4*(128+29)($27) # SP for task 2 |
---|
| 82 | li $10, 0x00040000 # 256 K |
---|
| 83 | add $10, $26, $10 |
---|
| 84 | sw $10, 4*(192+29)($27) # SP for task 3 |
---|
| 85 | |
---|
| 86 | # initializes EPC for tasks 1,2,3 (main1, main2, main3) |
---|
| 87 | la $26, main1 |
---|
| 88 | sw $26, 4*(64+32)($27) # EPC for task 1 |
---|
| 89 | la $26, main2 |
---|
| 90 | sw $26, 4*(128+32)($27) # EPC for task 2 |
---|
| 91 | la $26, main3 |
---|
| 92 | sw $26, 4*(192+32)($27) # EPC for task 3 |
---|
| 93 | |
---|
| 94 | # initializes RA for tasks 1,2,3 (to execute the eret instruction) |
---|
| 95 | la $26, to_user |
---|
| 96 | sw $26, 4*(64+31)($27) # $31 for task 1 |
---|
| 97 | sw $26, 4*(128+31)($27) # $31 for task 2 |
---|
| 98 | sw $26, 4*(192+31)($27) # $31 for task 3 |
---|
| 99 | |
---|
| 100 | # initializes SR sor tasks 1,2,3 (set UM, EXL, IE) |
---|
| 101 | li $26, 0x0000FF13 |
---|
| 102 | sw $26, 4*64($27) # SR for task 1 |
---|
| 103 | sw $26, 4*128($27) # SR for task 2 |
---|
| 104 | sw $26, 4*192($27) # SR for task 3 |
---|
| 105 | |
---|
| 106 | # ICU Configuration: 7 IRQs enabled : TIMER, IO, DMA |
---|
| 107 | la $27, seg_icu_base |
---|
| 108 | li $26, 0x7F |
---|
| 109 | sw $26, 8($27) # ICU mask <= 0111 1111 |
---|
| 110 | |
---|
| 111 | # TIMER Configuration: period = 10000 cycles |
---|
| 112 | la $27, seg_timer_base |
---|
| 113 | li $26, 10000 |
---|
| 114 | sw $26, 8($27) # period <= 10000 |
---|
| 115 | li $26, 0x3 |
---|
| 116 | sw $26, 4($27) # TIMER start |
---|
| 117 | |
---|
| 118 | # initializes Registers for T0 (size = 64K) |
---|
| 119 | la $26, seg_stack_base |
---|
| 120 | li $27, 0x10000 |
---|
| 121 | add $29, $26, $27 # SP for task 0 |
---|
| 122 | la $26, main0 |
---|
| 123 | mtc0 $26, $14 # EPC for task 0 |
---|
| 124 | li $26, 0x0000FF13 |
---|
| 125 | mtc0 $26, $12 # SR for task 0 |
---|
| 126 | |
---|
| 127 | # jump to address contained in EPC (in user mode) |
---|
| 128 | to_user: eret |
---|
| 129 | |
---|
| 130 | .end reset |
---|
| 131 | |
---|
| 132 | .set reorder |
---|