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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [uclinux/] [uClinux-2.0.x/] [arch/] [mips/] [kernel/] [head.S] - Rev 1781

Go to most recent revision | Compare with Previous | Blame | View Log

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

Go to most recent revision | Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

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