Changeset 586 for trunk/softs/tsar_boot/src/reset.S
- Timestamp:
- Dec 4, 2013, 7:59:21 PM (11 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/softs/tsar_boot/src/reset.S
r567 r586 1 /* *1 /* 2 2 * \file : reset.S 3 3 * \date : 01/12/2012 4 4 * \author: Cesar FUGUET & Manuel BOUYER & Alain Greiner 5 5 * 6 * This is a boot code for a generic multi-clusters / multi-processors 7 * TSAR architecture (up to 256 clusters / up to 4 processors per cluster). 8 * There is one XICU, one TTY, one DMA and one stack segment per cluster. 9 * segment base adresses = base + cluster_segment_increment*cluster_id 10 * 11 * - Each processor initializes the Status Register (SR) to disable interrupts. 12 * - Each processor initializes the Count Register. 13 * - Each processor initialises its private XICU Write Triggered Interruption 14 * mask register. 15 * - Only processor 0 initializes the stack pointer ($29). 16 * - Only processor 0 (boot processor) executes the boot_load_elf function to 17 * load in memory the boot loader stored in the block BOOT_LOADER_LBA of 18 * the disk. 19 * - All non-boot processors wait in a low power consumption mode that the 20 * processor 0 wakes them using the IPI (Inter Processor Interruption) 21 * functionality of the XICU device. 6 * This is a generic reset code for a generic multi-clusters / multi-processors 7 * TSAR architecture (up to 256 clusters / up to 4 processors per cluster). 8 * 9 * There is one XICU, one TTY, one DMA, and one memory bank per cluster. 10 * 11 * This preloader uses a stack segment allocated in cluster 0, defined 12 * by the seg_reset_stack_base and seg_reset_stack_size parameters in ldscript. 13 * - Processor 0 uses a larger stack: 64 Kbytes. 14 * - Other processors use a smaller stack: 512 bytes. 15 * => the seg_stack_size cannot be smaller than 0x90000 bytes (576 K). 16 * Those stacks can be used by both the preloader and the boot-loader code. 17 * 18 * The replicated XICU is used to awake the sleeping processors: 19 * xicu_paddr_base = ICU_PADDR_BASE + (cluster_id << 32) 20 * 21 * It is intended to be used with various operating systems or nano kernels, 22 * including NetBSD, ALMOS, and GIET_VM. 23 * 24 * - Each processor initializes its Status Register (SR) to disable interrupts. 25 * - Each processor initializes its Count Register. 26 * - Each processor initialises its private XICU WTI mask register. 27 * - Each processor initializes its Stack Pointer. 28 * - Only processor 0 executes the reset_load_elf function to load into memory 29 * the system specific boot-loader stored on disk at BOOT_LOADER_LBA 30 * - All other processors wait in a low power consumption mode that the 31 * processor 0 wakes them using an IPI (Inter Processor Interruption) 22 32 */ 23 33 … … 25 35 #include <mips32_registers.h> 26 36 27 .section .boot,"ax",@progbits 28 29 .extern seg_stack_base 37 /* These define should be consistent with values defined in ma;xml file */ 38 39 .extern seg_reset_stack_base 40 .extern seg_reset_stack_size 41 42 .section .reset,"ax",@progbits 30 43 31 44 .extern dtb_addr 32 .extern boot_putc33 .extern boot_getc34 .extern boot_ioc_read35 .extern boot_elf_loader45 .extern reset_putc 46 .extern reset_getc 47 .extern reset_ioc_read 48 .extern reset_elf_loader 36 49 .extern memcpy 37 .extern boot_puts38 .extern boot_putx39 .extern boot_putd40 .extern boot_ioc_init50 .extern reset_puts 51 .extern reset_putx 52 .extern reset_putd 53 .extern reset_ioc_init 41 54 .extern versionstr 42 55 43 .globl boot /* Makereset an external symbol */44 .ent boot56 .globl reset /* Makes reset an external symbol */ 57 .ent reset 45 58 46 59 .align 2 47 60 .set noreorder 48 61 49 boot:50 b _ boot/* 0xbfc0000 */62 reset: 63 b _reset /* 0xbfc0000 */ 51 64 nop /* 0xbfc0004 */ 52 65 53 /* Addresses of the functions provided by this pre-loader*/54 55 .word BOOT_VERSION/* 0xbfc0008 */66 /* Addresses of the functions provided by this reset code */ 67 68 .word RESET_VERSION /* 0xbfc0008 */ 56 69 .word dtb_addr /* 0xbfc000c */ 57 .word boot_putc/* 0xbfc0010 */58 .word boot_getc/* 0xbfc0014 */59 .word boot_ioc_read/* 0xbfc0018 */60 .word boot_elf_loader/* 0xbfc001C */70 .word reset_putc /* 0xbfc0010 */ 71 .word reset_getc /* 0xbfc0014 */ 72 .word reset_ioc_read /* 0xbfc0018 */ 73 .word reset_elf_loader /* 0xbfc001C */ 61 74 .word memcpy /* 0xbfc0020 */ 62 .word boot_puts /* 0xbfc0024 */ 63 .word boot_putx /* 0xbfc0028 */ 64 .word boot_putd /* 0xbfc002C */ 65 66 _boot: 67 /* Disable interruptions, keep STATUSbev enabled */ 75 .word reset_puts /* 0xbfc0024 */ 76 .word reset_putx /* 0xbfc0028 */ 77 .word reset_putd /* 0xbfc002C */ 78 79 _reset: 80 81 /* All processors Disable interruptions, keep STATUSbev enabled */ 68 82 69 83 li k0, (1 << 22) 70 84 mtc0 k0, CP0_STATUS 71 85 72 /* Computes proc_id, local_id, cluster_id, andcluster_increment */86 /* All processors compute proc_id, local_id, cluster_id, cluster_increment */ 73 87 74 88 mfc0 k0, CP0_EBASE … … 85 99 sll k1, t2, 8 /* k1 <= 256*cluster_id */ 86 100 div k1, k0 /* LO <= cluster_id * 256 / NB_CLUSTERS */ 87 mflo k1 /* k1<= physical address extension (8 MSB) */88 89 /* Initialization of the count register in the coprocessor0 */101 mflo t7 /* t7 <= physical address extension (8 MSB) */ 102 103 /* All processors initialise the count register in CP0 */ 90 104 91 105 mtc0 zero, CP0_COUNT 92 106 93 /** 94 * Compute the output index for the Write Triggered Interruption mask. 95 * Each processor enable the WTI for its irq output 96 * Each processor may have IRQ_PER_PROC private irq outputs from the XICU 97 * In each cluster, the ICU base address depends on the cluster_id 98 */ 99 100 la t3, ICU_BASE 101 move t4, t1 /* t4 <= local_id */ 102 li t5, IRQ_PER_PROC /* t5 <= IRQ_PER_PROC */ 107 /* 108 * All processors enable the WTI for XICU 109 * Each processor may have IRQ_PER_PROC irq outputs from the XICU 110 * In each cluster, the XICU base address depends on the cluster_id 111 */ 112 113 la t3, ICU_PADDR_BASE /* t3 <= ICU base address */ 114 move t4, t1 /* t4 <= local_id */ 115 li t5, IRQ_PER_PROC /* t5 <= IRQ_PER_PROC */ 103 116 multu t4, t5 104 mflo t6 /* t6 <= IRQ_PER_PROC * local_id */105 sll t4, t6, 2 /* t4 <= OUT_INDEX = t6 * 4 */106 107 li t5, (0xC << 7) /* t5 <= FUNC = XICU_MSK_WTI */108 or t4, t4, t5 /* t4 <= FUNC | INDEX | 00 */109 or t5, t3, t4 /* t5 <= &XICU[MSK_WTI][OUT_INDEX] */117 mflo t6 /* t6 <= IRQ_PER_PROC * local_id */ 118 sll t4, t6, 2 /* t4 <= OUT_INDEX = t6 * 4 */ 119 120 li t5, (0xC << 7) /* t5 <= FUNC = XICU_MSK_WTI */ 121 or t4, t4, t5 /* t4 <= FUNC | INDEX | 00 */ 122 or t5, t3, t4 /* t5 <= &XICU[MSK_WTI][OUT_INDEX] */ 110 123 111 /* Compute andset WTI mask using the physical address extension */124 /* All processors set WTI mask using the physical address extension */ 112 125 113 126 li t4, 1 114 sllv t4, t4, t1 /* Set XICU[MSK_WTI][INDEX][local_id] */ 115 116 mtc2 k1, CP2_PADDR_EXT /* set PADDR extension */ 117 sw t4, 0(t3) /* XICU[MSK_WTI][INDEX] <= t4 */ 118 mtc2 zero, CP2_PADDR_EXT /* reset PADDR extension */ 119 120 /** 127 sllv t4, t4, t1 /* Set XICU[MSK_WTI][INDEX][local_id] */ 128 129 mtc2 t7, CP2_PADDR_EXT /* set PADDR extension */ 130 sw t4, 0(t5) /* XICU[MSK_WTI][INDEX] <= t4 */ 131 mtc2 zero, CP2_PADDR_EXT /* reset PADDR extension */ 132 133 /* All processors initializes stack pointer, depending on proc_id */ 134 135 la k0, seg_reset_stack_base 136 li k1, 0x10000 /* k1 <= P0 stack size == 64 Kbytes */ 137 addu sp, k0, k1 /* P0 stack from base to (base + 64K) */ 138 139 li k1, 0x200 /* k1 <= Pi stack size == 512 bytes */ 140 multu k1, t0 141 mflo k0 /* k0 <= 256 * proc_id */ 142 addu sp, sp, k1 143 addu sp, sp, k0 /* Pi stacks from base + 64K + proc_id*256 */ 144 145 /* 146 * Only processor 0 in cluster 0 loads and executes the boot-loader 121 147 * We have: 122 * t0: global id123 * t1: local id148 * t0: global proc_id 149 * t1: local proc_id 124 150 * t2: cluster id 125 * t3: xicu base address 126 * k1: Paddr extension depending on cluster_id 127 * 128 * Only processor 0 in cluster 0 executes the boot loader 151 * t3: xicu physical base address in cluster 0 152 * t7: paddr extension depending on cluster_id 129 153 */ 130 154 … … 132 156 nop 133 157 134 /* Initializes stack pointer */ 135 136 la sp, stk 137 138 la a0, versionstr 139 la k0, boot_puts 158 /* Processor 0 displays version for this reset code */ 159 160 # la a0, versionstr 161 # la k0, reset_puts 162 # jalr k0 163 # nop 164 165 166 #ifndef SOCLIB_IOC 167 168 /* Processor 0 Initialize the block device if required */ 169 170 la k0, reset_ioc_init 140 171 jalr k0 141 172 nop 142 173 143 #ifndef SOCLIB_IOC144 145 /* Initialize the block device */146 147 la k0, boot_ioc_init148 jalr k0149 nop150 151 174 #endif 152 175 153 /** 154 * Jump to the boot elf loader routine 155 * Passing as argument the block number in which it must be 156 * the executable elf file to load 157 */ 158 159 la k0, boot_elf_loader 176 /* 177 * Processor 0 jumps to the reset_elf_loader routine 178 * Passing as argument the block number in which is loaded the .elf file 179 */ 180 181 la k0, reset_elf_loader 160 182 li a0, BOOT_LOADER_LBA 161 183 jalr k0 162 184 nop 163 185 164 /* *165 * We jump to the entry point address defined in the166 * ELF file. This address is returned by boot_elf_loader function.186 /* 187 * Processor O jumps to the entry address defined in the .elf file, 188 * and returned by reset_elf_loader function. 167 189 * All function arguments are 0 168 190 */ … … 175 197 nop 176 198 177 /** 178 * Wait in low power consumption mode until the application wakes us. 179 * The application wakes up the non-boot CPUs using a IPI with a non-0 180 * value in the mailbox. This non-0 value is the address to jump to. 181 */ 182 183 _reset_wait: 184 /** 199 /* 200 * All processor (but processor 0) wait in low power mode 201 * until processor 0 wakes them using an IPI. 185 202 * We have: 186 203 * t0: global id 187 204 * t1: local id 188 205 * t2: cluster id 189 * t3: xicu base address 190 * k1: Paddr extension depending on cluster_id 191 */ 192 193 sll t4, t1, 2 /* t4 <= local_id * 4 */ 194 addu t5, t4, t3 /* t5 <= &XICU[WTI_REG][local_id] */ 206 * t3: xicu physical base address in cluster 0 207 * t7: Paddr extension depending on cluster_id 208 */ 209 210 _reset_wait: 211 212 sll t4, t1, 2 /* t4 <= local_id * 4 */ 213 addu t5, t4, t3 /* t5 <= &XICU[WTI_REG][local_id] */ 195 214 196 215 wait 197 216 198 /* read the address to jump with a physical read */ 199 200 mtc2 k1, CP2_PADDR_EXT /* set PADDR extension */ 217 /* 218 * All other processors, when exiting wait mode, 219 * read from XICU the address to jump. 220 * This address is the boot-loader entry address that has been 221 * written in the mailbox by the IPI sent by processor 0 222 */ 223 224 mtc2 t7, CP2_PADDR_EXT /* set PADDR extension */ 201 225 lw k0, 0(t5) /* k0 <= XICU[WTI_REG][local_id] */ 202 226 mtc2 zero, CP2_PADDR_EXT /* reset PADDR extension */ … … 206 230 207 231 /* Exception entry point */ 232 208 233 .org 0x0380 209 234 _excep: 210 mfc0 a0, CP0_STATUS /* first arg is status */211 mfc0 a1, CP0_CAUSE /* second arg is cause */212 mfc0 a2, CP0_EPC /* third argc is epc */235 mfc0 a0, CP0_STATUS /* first arg is status */ 236 mfc0 a1, CP0_CAUSE /* second arg is cause */ 237 mfc0 a2, CP0_EPC /* third argc is epc */ 213 238 nop 214 239 j handle_except 215 240 nop 216 241 217 .end boot242 .end reset 218 243 219 244 .set reorder 220 221 .section .data222 .space BOOT_STACK_SIZE223 stk:224 .space 1225 245 226 246 /*
Note: See TracChangeset
for help on using the changeset viewer.