/* * 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 #include #include #include #include #include #include #include #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