📄 start.s
字号:
/*
* Copyright (C) 1998 Dan Malek <dmalek@jlc.net>
* Copyright (C) 1999 Magnus Damm <kieraypc01.p.y.kie.era.ericsson.se>
* Copyright (C) 2000 Wolfgang Denk <wd@denx.de>
*
* See file CREDITS for list of people who contributed to this
* project.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
//------------------------------------------------------------------------------+
//
// This source code has been made available to you by IBM on an AS-IS
// basis. Anyone receiving this source is licensed under IBM
// copyrights to use it in any way he or she deems fit, including
// copying it, modifying it, compiling it, and redistributing it either
// with or without modifications. No license under IBM patents or
// patent applications is to be implied by the copyright license.
//
// Any user of this software should understand that IBM cannot provide
// technical support for this software and will not be responsible for
// any consequences resulting from the use of this software.
//
// Any person who transfers this source code or any derivative work
// must include the IBM copyright notice, this paragraph, and the
// preceding two paragraphs in the transferred software.
//
// COPYRIGHT I B M CORPORATION 1995
// LICENSED MATERIAL - PROGRAM PROPERTY OF I B M
//-------------------------------------------------------------------------------
/* ppcboot - Startup Code for IBM 4xx PowerPC based Embedded Boards
*
*
* The processor starts at 0xfffffffc and the code is executed
* from flash/rom.
* in memory, but as long we don't jump around before relocating.
* board_init lies at a quite high address and when the cpu has
* jumped there, everything is ok.
* This works because the cpu gives the FLASH (CS0) the whole
* address space at startup, and board_init lies as a echo of
* the flash somewhere up there in the memorymap.
*
* board_init will change CS0 to be positioned at the correct
* address and (s)dram will be positioned at address 0
*/
#include <config.h>
#include <mpc8xx.h>
#include <ppc4xx.h>
#include "version.h"
#define _LINUX_CONFIG_H 1 /* avoid reading Linux autoconf.h file */
#include <ppc_asm.tmpl>
#include <ppc_defs.h>
#include <asm/cache.h>
#include <asm/mmu.h>
/* We don't want the MMU yet.
*/
#undef MSR_KERNEL
#define MSR_KERNEL ( MSR_ME ) /* Machine Check */
/*
* Set up GOT: Global Offset Table
*
* Use r14 to access the GOT
*/
START_GOT
GOT_ENTRY(_GOT2_TABLE_)
GOT_ENTRY(_FIXUP_TABLE_)
GOT_ENTRY(_start)
GOT_ENTRY(_start_of_vectors)
GOT_ENTRY(_end_of_vectors)
GOT_ENTRY(transfer_to_handler)
GOT_ENTRY(_end)
GOT_ENTRY(.bss)
END_GOT
/*
* r3 - 1st arg to board_init(): IMMP pointer
* r4 - 2nd arg to board_init(): boot flag
*/
.text
.long 0x27051956 /* PPCBOOT Magic Number */
.globl version_string
version_string:
.ascii PPCBOOT_VERSION, " (", __DATE__, " - ", __TIME__, ")\0"
. = EXC_OFF_SYS_RESET
.globl _start
_start:
li r4, BOOTFLAG_COLD /* Normal Power-On: Boot from FLASH */
b boot_cold
. = EXC_OFF_SYS_RESET + 0x10
.globl _start_warm
_start_warm:
li r4, BOOTFLAG_WARM /* Software reboot */
b boot_warm
boot_cold:
boot_warm:
/*****************************************************************************/
#ifdef CONFIG_IOP480
//-----------------------------------------------------------------------
// Set up some machine state registers.
//-----------------------------------------------------------------------
addi r4,r0,0x0000 // initialize r4 to zero
mtspr esr,r4 // clear Exception Syndrome Reg
mttcr r4 // timer control register
addis r4,r0,0x0000
mtexier r4 // disable all interrupts
addi r4,r0,0x1000 // set ME bit (Machine Exceptions)
oris r4,r4,0x2 // set CE bit (Critical Exceptions)
mtmsr r4 // change MSR
addis r4,r0,0xFFFF // set r4 to 0xFFFFFFFF (status in the
ori r4,r4,0xFFFF // dbsr is cleared by setting bits to 1)
mtdbsr r4 // clear/reset the dbsr
mtexisr r4 // clear all pending interrupts
addis r4,r0,0x8000
mtexier r4 // enable critical exceptions
addis r4,r0,0x0000 // assume 403GCX - enable core clk
ori r4,r4,0x4020 // dbling (no harm done on GA and GC
mtiocr r4 // since bit not used) & DRC to latch
// data bus on rising edge of CAS
//-----------------------------------------------------------------------
// Clear XER.
//-----------------------------------------------------------------------
addis r0,r0,0x0000
mtxer r0
//-----------------------------------------------------------------------
// Invalidate i-cache and d-cache TAG arrays.
//-----------------------------------------------------------------------
addi r3,0,1024 // 1/4 of I-cache size, half of D-cache
addi r4,0,1024 // 1/4 of I-cache
..cloop:
iccci 0,r3
iccci r4,r3
dccci 0,r3
addic. r3,r3,-16 // move back one cache line
bne ..cloop // loop back to do rest until r3 = 0
//
// initialize IOP480 so it can read 1 MB code area for SRAM spaces
// this requires enabling MA[17..0], by default only MA[12..0] are enabled.
//
// first copy IOP480 register base address into r3
addis r3,0,0x5000 // IOP480 register base address hi
ori r3,r3,0x0000 // IOP480 register base address lo
// use r4 as the working variable
// turn on CS3 (LOCCTL.7)
lwz r4,0x84(r3) // LOCTL is at offset 0x84
andi. r4,r4,0xff7f // make bit 7 = 0 -- CS3 mode
stw r4,0x84(r3) // LOCTL is at offset 0x84
// turn on MA16..13 (LCS0BRD.12 = 0)
lwz r4,0x100(r3) // LCS0BRD is at offset 0x100
andi. r4,r4,0xefff // make bit 12 = 0
stw r4,0x100(r3) // LCS0BRD is at offset 0x100
// make sure above stores all comlete before going on
sync
// last thing, set local init status done bit (DEVINIT.31)
lwz r4,0x80(r3) // DEVINIT is at offset 0x80
oris r4,r4,0x8000 // make bit 31 = 1
stw r4,0x80(r3) // DEVINIT is at offset 0x80
// clear all pending interrupts and disable all interrupts
li r4,-1 // set p1 to 0xffffffff
stw r4,0x1b0(r3) // clear all pending interrupts
stw r4,0x1b8(r3) // clear all pending interrupts
li r4,0 // set r4 to 0
stw r4,0x1b4(r3) // disable all interrupts
stw r4,0x1bc(r3) // disable all interrupts
// make sure above stores all comlete before going on
sync
//-----------------------------------------------------------------------
// Enable two 128MB cachable regions.
//-----------------------------------------------------------------------
addis r1,r0,0x8000
addi r1,r1,0x0001
mticcr r1 // instruction cache
addis r1,r0,0x0000
addi r1,r1,0x0000
mtdccr r1 // data cache
addis r1,r0,CFG_INIT_RAM_ADDR@h
ori r1,r1,CFG_INIT_SP_OFFSET /* set up the stack to SDRAM */
GET_GOT /* initialize GOT access */
bl board_init_f /* run first part of init code (from Flash) */
#endif /* CONFIG_IOP480 */
/*****************************************************************************/
#ifdef CONFIG_PPC405GP
//-----------------------------------------------------------------------
// Clear and set up some registers.
//-----------------------------------------------------------------------
addi r4,r0,0x0000
mtspr sgr,r4
mtspr dcwr,r4
mtesr r4 // clear Exception Syndrome Reg
mttcr r4 // clear Timer Control Reg
mtxer r4 // clear Fixed-Point Exception Reg
mtevpr r4 // clear Exception Vector Prefix Reg
#if 1 /* test-only */
addi r4,r0,0x1000 // set ME bit (Machine Exceptions)
oris r4,r4,0x0002 // set CE bit (Critical Exceptions)
mtmsr r4 // change MSR
#else /* problems in rom2ram (see test-only in rom2ram!!!) */
addi r4,r0,0x0000 // dont set (!!!) ME bit (Machine Exceptions)
oris r4,r4,0x0002 // set CE bit (Critical Exceptions)
mtmsr r4 // change MSR
#endif
addi r4,r0,(0xFFFF-0x10000) // set r4 to 0xFFFFFFFF (status in the
// dbsr is cleared by setting bits to 1)
mtdbsr r4 // clear/reset the dbsr
//-----------------------------------------------------------------------
// Invalidate I and D caches. Enable I cache for defined memory regions
// to speed things up. Leave the D cache disabled for now. It will be
// enabled/left disabled later based on user selected menu options.
// Be aware that the I cache may be disabled later based on the menu
// options as well. See miscLib/main.c.
//-----------------------------------------------------------------------
bl invalidate_icache
bl invalidate_dcache
//-----------------------------------------------------------------------
// Enable two 128MB cachable regions.
//-----------------------------------------------------------------------
addis r4,r0,0x8000
addi r4,r4,0x0001
mticcr r4 // instruction cache
addis r4,r0,0x0000
addi r4,r4,0x0000
mtdccr r4 // data cache
//-----------------------------------------------------------------------
// Initialize the External Bus Controller for external peripherals
//-----------------------------------------------------------------------
bl ext_bus_cntlr_init
//-----------------------------------------------------------------------
// Initialize the On Chip Memory (4k SRAM)
//-----------------------------------------------------------------------
addis r4,r0,OCM_DATA_ADDR@h
ori r4,r4,OCM_DATA_ADDR@l
mtdcr ocmdsarc,r4
addis r4,r0,0xc000
ori r4,r4,0x0000
mtdcr ocmdscntl,r4
//-----------------------------------------------------------------------
// Initialize the Control 0 register for UART control.
// Set UART1 for CTS/RTS and set the UART0 and UART1 internal
// clock enable to use the internal serial clock instead of an
// external clock. Set the FPGA control reg for UART1 to
// select CTS/RTS.
//-----------------------------------------------------------------------
addis r3,r0,0x0000 // set CTS/RTS for UART1 and set int.
ori r3,r3,0x1022 // clock for UART0 and UART1 (/ 18)
mtdcr cntrl0,r3 // set CNTRL0
//-----------------------------------------------------------------------
// Initialize SDRAM Controller
//-----------------------------------------------------------------------
bl sdram_init
addis r1,r0,CFG_INIT_RAM_ADDR@h
ori r1,r1,CFG_INIT_SP_OFFSET /* set up the stack in internal SRAM */
GET_GOT /* initialize GOT access */
bl board_init_f /* run first part of init code (from Flash) */
#endif /* CONFIG_PPC405GP */
.globl _start_of_vectors
_start_of_vectors:
/* Machine check */
STD_EXCEPTION(0x200, MachineCheck, MachineCheckException)
/* Data Storage exception. "Never" generated on the 860. */
STD_EXCEPTION(0x300, DataStorage, UnknownException)
/* Instruction Storage exception. "Never" generated on the 860. */
STD_EXCEPTION(0x400, InstStorage, UnknownException)
/* External Interrupt exception. */
STD_EXCEPTION(0x500, ExtInterrupt, external_interrupt)
/* Alignment exception. */
. = 0x600
Alignment:
EXCEPTION_PROLOG
mfspr r4,DAR
stw r4,_DAR(r21)
mfspr r5,DSISR
stw r5,_DSISR(r21)
addi r3,r1,STACK_FRAME_OVERHEAD
li r20,MSR_KERNEL
rlwimi r20,r23,0,16,16 /* copy EE bit from saved MSR */
lwz r6,GOT(transfer_to_handler)
mtlr r6
blrl
.L_Alignment:
.long AlignmentException - _start + EXC_OFF_SYS_RESET
.long int_return - _start + EXC_OFF_SYS_RESET
/* Program check exception */
. = 0x700
ProgramCheck:
EXCEPTION_PROLOG
addi r3,r1,STACK_FRAME_OVERHEAD
li r20,MSR_KERNEL
rlwimi r20,r23,0,16,16 /* copy EE bit from saved MSR */
lwz r6,GOT(transfer_to_handler)
mtlr r6
blrl
.L_ProgramCheck:
.long ProgramCheckException - _start + EXC_OFF_SYS_RESET
.long int_return - _start + EXC_OFF_SYS_RESET
/* No FPU on MPC8xx. This exception is not supposed to happen.
*/
STD_EXCEPTION(0x800, FPUnavailable, UnknownException)
/* I guess we could implement decrementer, and may have
* to someday for timekeeping.
*/
STD_EXCEPTION(0x900, Decrementer, timer_interrupt)
STD_EXCEPTION(0xa00, Trap_0a, UnknownException)
STD_EXCEPTION(0xb00, Trap_0b, UnknownException)
STD_EXCEPTION(0xc00, SystemCall, UnknownException)
STD_EXCEPTION(0xd00, SingleStep, UnknownException)
STD_EXCEPTION(0xe00, Trap_0e, UnknownException)
STD_EXCEPTION(0xf00, Trap_0f, UnknownException)
/* On the MPC8xx, this is a software emulation interrupt. It occurs
* for all unimplemented and illegal instructions.
*/
STD_EXCEPTION(0x1000, PIT, PITException)
STD_EXCEPTION(0x1100, InstructionTLBMiss, UnknownException)
STD_EXCEPTION(0x1200, DataTLBMiss, UnknownException)
STD_EXCEPTION(0x1300, InstructionTLBError, UnknownException)
STD_EXCEPTION(0x1400, DataTLBError, UnknownException)
STD_EXCEPTION(0x1500, Reserved5, UnknownException)
STD_EXCEPTION(0x1600, Reserved6, UnknownException)
STD_EXCEPTION(0x1700, Reserved7, UnknownException)
STD_EXCEPTION(0x1800, Reserved8, UnknownException)
STD_EXCEPTION(0x1900, Reserved9, UnknownException)
STD_EXCEPTION(0x1a00, ReservedA, UnknownException)
STD_EXCEPTION(0x1b00, ReservedB, UnknownException)
STD_EXCEPTION(0x1c00, DataBreakpoint, UnknownException)
STD_EXCEPTION(0x1d00, InstructionBreakpoint, UnknownException)
STD_EXCEPTION(0x1e00, PeripheralBreakpoint, UnknownException)
STD_EXCEPTION(0x1f00, DevPortBreakpoint, UnknownException)
.globl _end_of_vectors
_end_of_vectors:
. = 0x2000
/*
* This code finishes saving the registers to the exception frame
* and jumps to the appropriate handler for the exception.
* Register r21 is pointer into trap frame, r1 has new stack pointer.
*/
.globl transfer_to_handler
transfer_to_handler:
stw r22,_NIP(r21)
lis r22,MSR_POW@h
andc r23,r23,r22
stw r23,_MSR(r21)
SAVE_GPR(7, r21)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -