Loading...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 | /* * arch/mips/kernel/head.S * * Copyright (C) 1994, 1995 Waldorf Electronics * Written by Ralf Baechle and Andreas Busse * * Head.S contains the MIPS exception handler and startup code. */ #include <linux/tasks.h> #include <asm/asm.h> #include <asm/segment.h> #include <asm/cachectl.h> #include <asm/mipsregs.h> #include <asm/mipsconfig.h> #include <asm/stackframe.h> #include <asm/bootinfo.h> #define PAGE_SIZE 0x1000 #define MODE_GLOBAL 0x0001 /* shared for all processes */ #define MODE_ALIAS 0x0016 /* uncachable */ .text .set mips3 /* * This is space for the interrupt handlers. * They are located at virtual address KSEG[01] (physical 0x0) */ /* * TLB refill, EXL == 0 */ .set noreorder .set noat LEAF(except_vec0) dmfc0 k1,CP0_CONTEXT dsra k1,1 lwu k0,(k1) # May cause another exception lwu k1,4(k1) dsrl k0,6 # Convert to EntryLo format dsrl k1,6 # Convert to EntryLo format dmtc0 k0,CP0_ENTRYLO0 dmtc0 k1,CP0_ENTRYLO1 nop # Needed for R4[04]00 pipeline tlbwr nop # Needed for R4[04]00 pipeline nop nop eret /* * Workaround for R4000 bug. For explanation see MIPS * docs. Note that this is so obscure that it will almost * never happen. Well, but Mips writes about its bugs. */ nop eret END(except_vec0) /* * XTLB refill, EXL == 0 * Should never be reached */ .org except_vec0+0x80 LEAF(except_vec1) PANIC("XTLB Refill exception.\n") 1: j 1b nop END(except_vec1) /* * Cache Error */ .org except_vec1+0x80 LEAF(except_vec2) /* * Famous last words: unreached */ mfc0 a1,CP0_ERROREPC PRINT("Cache error exception: c0_errorepc == %08x\n") 1: j 1b nop END(except_vec2) /* * General exception vector. */ .org except_vec2+0x80 NESTED(except_vec3, 0, sp) .set noat /* * Register saving is delayed as long as we don't know * which registers really need to be saved. */ mfc0 k1,CP0_CAUSE la k0,exception_handlers /* * Next lines assumes that the used CPU type has max. * 32 different types of exceptions. We might use this * to implement software exceptions in the future. */ andi k1,0x7c addu k0,k1 lw k0,(k0) NOP jr k0 nop END(except_vec3) .set at /******************************************************************************/ /* * Kernel entry */ .set noreorder NESTED(kernel_entry, 16, sp) /* * The following two symbols are used for kernel profiling. */ EXPORT(stext) EXPORT(_stext) #ifdef CONF_DISABLE_KSEG0_CACHING /* * Disable all caching for KSEG0. This option is useful * when cache trouble with drivers is suspected */ mfc0 t0,CP0_CONFIG ori t0,7 xori t0,5 mtc0 t0,CP0_CONFIG #endif /* * Clear BSS first so that there are no surprises... */ la t0,_edata la t1,_end sw zero,(t0) 1: addiu t0,4 bnel t0,t1,1b sw zero,(t0) /* * Initialize low level part of memory management * First flush the TLB to make sure that we don't get a * TLB shutdown during wire_mappings. */ jal tlbflush mtc0 zero,CP0_WIRED # delay slot jal wire_mappings nop /* * Stack for kernel and init */ la sp,init_user_stack+PAGE_SIZE-24 la t0,init_kernel_stack+PAGE_SIZE sw t0,kernelsp /* * Disable coprocessors; set ST0_CU0 to indicate that * we're running on the kernel stack */ mfc0 t0,CP0_STATUS li t1,~(ST0_CU1|ST0_CU2|ST0_CU3) and t0,t1 li t1,ST0_CU0 or t0,ST0_CU0 mtc0 t0,CP0_STATUS 1: jal start_kernel nop # delay slot /* * Main should never return here, but * just in case, we know what happens. */ b 1b nop # delay slot END(kernel_entry) /* * wire_mappings - used to map hardware registers */ LEAF(wire_mappings) /* * Get base address of map0 table for the * the board we're running on */ la t0,boot_info lw t1,OFFSET_BOOTINFO_MACHTYPE(t0) la t0,map0table sll t1,PTRLOG # machtype used as index addu t0,t1 lw t0,(t0) # get base address /* * Get number of wired TLB entries and * loop over selected map0 table. */ lw t1,(t0) # number of wired TLB entries move t2,zero # TLB entry counter addiu t3,t1,1 # wire one additional entry beqz t1,2f # null, exit mtc0 t3,CP0_WIRED # delay slot addiu t0,8 1: lw t4,24(t0) # PageMask ld t5,0(t0) # entryHi ld t6,8(t0) # entryLo0 ld t7,16(t0) # entryLo1 addiu t2,1 # increment ctr mtc0 t2,CP0_INDEX # set TLB entry mtc0 t4,CP0_PAGEMASK dmtc0 t5,CP0_ENTRYHI dmtc0 t6,CP0_ENTRYLO0 dmtc0 t7,CP0_ENTRYLO1 addiu t0,32 bne t1,t2,1b # next TLB entry tlbwi # delay slot /* * We use only 4k pages. Therefore the PageMask register * is expected to be setup for 4k pages. */ 2: li t0,PM_4K mtc0 t0,CP0_PAGEMASK /* * Now map the pagetables */ mtc0 zero,CP0_INDEX la t0,TLB_ROOT dmtc0 t0,CP0_ENTRYHI la t0,swapper_pg_dir-KSEG1 srl t0,6 ori t0,(MODE_ALIAS|MODE_GLOBAL) # uncachable, dirty, valid dmtc0 t0,CP0_ENTRYLO0 li t0,MODE_GLOBAL dmtc0 t0,CP0_ENTRYLO1 nop tlbwi # delayed /* * Load the context register with a value that allows * it to be used as fast as possible in tlb exceptions. * It is expected that this register's content will * NEVER be changed. */ li t0,TLBMAP dsll t0,1 dmtc0 t0,CP0_CONTEXT jr ra # delay slot nop END(wire_mappings) .data /* * Build an entry for table of wired entries */ #define MAPDATA(q1,q2,q3,w1) \ .quad q1; \ .quad q2; \ .quad q3; \ .word w1; \ .word 0 /* * Initial mapping tables for supported Mips boards. * First item is always the number of wired TLB entries, * following by EntryHi/EntryLo pairs and page mask. * Since everything must be quad-aligned (8) we insert * some dummy zeros. */ /* * Address table of mapping tables for supported Mips boards. * Add your own stuff here but don't forget to define your * target system in bootinfo.h */ map0table: PTR map0_dummy # machtype = unknown PTR map0_rpc # Deskstation rPC44 PTR map0_tyne # Deskstation Tyne PTR map0_pica61 # Acer Pica-61 PTR map0_magnum4000 # MIPS Magnum 4000PC (RC4030) map0_dummy: .word 0 # 0 entries .align 3 /* * Initial mappings for Deskstation rPC boards. * RB: Untested goodie - I don't have such a board. */ map0_rpc: .word 2 # no. of wired TLB entries .word 0 # pad for alignment MAPDATA(0xffffffffe0000000, 0x04020017, 0x00000001, PM_1M) # VESA DMA cache MAPDATA(0xffffffffe2000000, 0x24000017, 0x04000017, PM_16M) # VESA I/O and memory space /* * Initial mappings for Deskstation Tyne boards. */ map0_tyne: .word 2 # no. of wired TLB entries .word 0 # pad for alignment MAPDATA(0xffffffffe0000000, 0x04020017, 0x00000001, PM_1M) # VESA DMA cache MAPDATA(0xffffffffe2000000, 0x24000017, 0x04000017, PM_16M) # VESA I/O and memory space /* * Initial mapping for ACER PICA-61 boards. * FIXME: These are rather preliminary since many drivers, such as serial, * parallel, scsi and ethernet need some changes to distinguish between "local" * (built-in) and "optional" (ISA/PCI) I/O hardware. Local video ram is mapped * to the same location as the bios maps it to. Console driver has been changed * accordingly (new video type: VIDEO_TYPE_PICA_S3). * FIXME: Remove or merge some of the mappings. */ map0_pica61: .word 7 # no. wired TLB entries .word 0 # dummy MAPDATA(0xffffffffe0000000, 0x02000017, 0x00000001, PM_64K) # Local I/O space MAPDATA(0xffffffffe0100000, 0x03c00017, 0x00000001, PM_4K) # Interrupt source register MAPDATA(0xffffffffe0200000, 0x01800017, 0x01804017, PM_1M) # Local video control MAPDATA(0xffffffffe0400000, 0x01808017, 0x0180c017, PM_1M) # Extended video control MAPDATA(0xffffffffe0800000, 0x01000017, 0x01010017, PM_4M) # Local video memory (BIOS mapping) MAPDATA(0xffffffffe2000000, 0x02400017, 0x02440017, PM_16M) # ISA I/O and ISA memory space (both 16M) MAPDATA(0xffffffffffffe000, 0x00000001, 0x0001ffd7, PM_4K) # PCR (???) /* * Initial mapping for Mips Magnum 4000PC systems. * Do you believe me now that the Acer and Mips boxes are nearly the same ? :-) * FIXME: Remove or merge some of the mappings. */ map0_magnum4000: .word 8 # no. wired TLB entries .word 0 # dummy MAPDATA(0xffffffffe1000000, 0x03ffc013, 0x00000001, 0x7e000) # 0 MAPDATA(0xffffffffe0000000, 0x02000017, 0x00000001, 0x1e000) # 1 local I/O MAPDATA(0xffffffffe0100000, 0x03c00017, 0x00000001, 0) # 2 IRQ source MAPDATA(0xffffffffe0200000, 0x01800017, 0x01804017, 0x1fe000) # 3 local video ctrl MAPDATA(0xffffffffe0400000, 0x01808017, 0x0180c017, 0x1fe000) # 4 ext. video ctrl MAPDATA(0xffffffffe0800000, 0x01000017, 0x01010017, 0x7fe000) # 5 local video mem. MAPDATA(0xffffffffe2000000, 0x02400017, 0x02440017, 0x1ffe000) # 6 ISA I/O and mem. MAPDATA(0xffffffffffffe000, 0x00000001, 0x0001ffd7, 0) # 7 PCR .text .org 0x1000 .globl swapper_pg_dir swapper_pg_dir = . + (KSEG1-KSEG0) /* * The page tables are initialized to only 4MB here - the final page * tables are set up later depending on memory size. */ .org 0x2000 EXPORT(pg0) .org 0x3000 EXPORT(empty_bad_page) .org 0x4000 EXPORT(empty_bad_page_table) .org 0x5000 EXPORT(empty_zero_page) .org 0x6000 EXPORT(invalid_pte_table) .org 0x7000 EXPORT(cache_error_buffer) .fill 32*4,1,0 .data EXPORT(kernelsp) PTR 0 |