📄 reset.s
字号:
/* * 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 * * File Name: entry.s * * Function: Entry code for the 405 ROM Monitor (openbios)running * on the Walnut board. * * Author: James Burke * * Change Activity- * * Date Description of Change BY * --------- --------------------- --- * 29-Apr-99 Created JWB * 17-Jun-99 Updated to run with caches on JWB * 23-Jun-99 Set MCOPT1 BRD_PRF bits to '01' for 16 byte PLB burst read * prefetch to improve SDRAM performance. JWB * 09-Jul-99 Added call to ppcDflush() after rom2ram() JWB * 14-Aug-99 Moved disabling of PCI addr pipelining for pass1 405GP bug. JWB * 24-Aug-99 Added pci ethernet functions to user callable functions. JWB * 07-Sep-99 Moved ppcDflush() call in boot_jump(); leave SDRAM address * pipelining enabled (default) in CNTRL1 reg. JWB * 22-Sep-99 Updated for sdram_init for 32MB SDRAM DIMM now being * shipped w/ the board JWB * 18-Apr-00 Integrated into the MicroMonitor platform. ELS * 21-Apr-00 Added INCLUDE_ECC to optionally disable ECC and ELS * INCLUDE_HERALD to optionally include the startup message. * * General notice: * This code is part of a boot-monitor package developed as a generic base * platform for embedded system designs. As such, it is likely to be * distributed to various projects beyond the control of the original * author. Please notify the author of any enhancements made or bugs found * so that all may benefit from the changes. In addition, notification back * to the author will allow the new user to pick up changes that may have * been made by other users after this version of the code was distributed. * * Author: Ed Sutter * email: esutter@lucent.com (home: lesutter@worldnet.att.net) * phone: 908-582-2351 (home: 908-889-5161) * * This reset code is a combination of code written by several developers. * The source code for the IBM "Walnut" BSP was used as a reference for this * bootup. */#include "config.h"#include "arch_ppc.h"#include "cpu_403.h"#define INCLUDE_ECC 0#define INCLUDE_HERALD 0#define ONE_BILLION 1000000000#define I_CACHEABLE_REGIONS 0x80000001#define D_CACHEABLE_REGIONS 0x80000000#define FPGA_BRDC 0xf0300004#define FPGA_BRDS2 0xf0300006#define EXT_TIMER_INPUT#define AUTO_MEMORY_CONFIG/* #define SECOND_BANK */#define PASS2_405GP/* * IIC Register Offsets */#define IIC0_BASE 0xef600500#define IICMDBUF 0x00#define IICSDBUF 0x02#define IICLMADR 0x04#define IICHMADR 0x05#define IICCNTL 0x06#define IICMDCNTL 0x07#define IICSTS 0x08#define IICEXTSTS 0x09#define IICLSADR 0x0A#define IICHSADR 0x0B#define IICCLKDIV 0x0C#define IICINTRMSK 0x0D#define IICXFRCNT 0x0E#define IICXTCNTLSS 0x0F#define IICDIRECTCNTL 0x10#define MONSTACKSIZE 4096#define INITIALIZE (3<<4) .globl MonStack .comm MonStack,MONSTACKSIZE .globl coldstart, warmstart .globl etheraddr, ipaddripaddr: .byte 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff .byte 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff .byte 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xffetheraddr: .byte 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff .byte 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff .byte 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff/* coldstart: * This is the code that is pointed to by the resetvector at 0xfffffffc. * If we get here, then we know that we took some kind of "hard" reset. * Some register must be preserved from here until the point where we * call start so that we can pass the state to start(). Since we got * here, we will load the register with INITIALIZE to indicate the fact * that we took a hard reset (or powerup). * Note that the register used should be the register that the compiler * would normally populate if calling a function with a single argument. * In this case, it is R3. */coldstart: xor r0,r0,r0 /* Clear R0 */ addi r3,r0,INITIALIZE/* warmstart: * This function can be entered either by having previously hit coldstart, * or by the monitor source code calling warmstart(). It is assumed to * be a function to the C-code, and it is passed a reason for the warmstart. * The register which the compiler uses for storage of the calling argument * must be saved so that it can be passed to start(). */warmstart: mr r15,r3 /* Copy r3 to r15 because between here and */ /* the call to start(), r3 is used a lot. */ xor r0,r0,r0 /* Clear R0 */ addi r4,r0,0x0000 /* Clear and set up some registers. */ mtsgr r4 mtdcwr r4 mtesr r4 /* clear Exception Syndrome Reg */ mttcr r4 /* clear Timer Control Reg */ mtxer r4 /* clear Fixed-Point Exception Reg */ addi r4,r0,0x1000 /* set ME bit (Machine Exceptions) */ oris r4,r4,0x0002 /* set CE bit (Critical Exceptions) */ mtmsr r4 /* change MSR */ ori r4,r0,0xffff /* set r4 to 0xFFFFFFFF (status in the */ /* dbsr is cleared by setting bits to 1) */ mtdbsr r4 /* clear/reset the dbsr */ /* Invalidate i-cache and then enable for defined memory regions. * Do the same for the d-cache. Be aware that the caches may be disabled * later in miscLib/main.c based on the user selected cache menu options. */ bl invalidate_icache addis r4,r0, I_CACHEABLE_REGIONS@h ori r4,r4, I_CACHEABLE_REGIONS@l mticcr r4 addis r4,r0, D_CACHEABLE_REGIONS@h ori r4,r4, D_CACHEABLE_REGIONS@l bl invalidate_dcache mtdccr r4 /* Initialize the External Bus Controller for external peripherals */ bl ext_busctl_init /* Initialize the Control 0 register for UART control. * Set UART1 for CTS/RTS and set the UART0 and UART1 external * clock enable to use the external serial clock instead of an * internally derived clock. Set the FPGA control reg for UART1 to * select CTS/RTS. */ addis r3,r0,0x0000 /* set CTS/RTS for UART1 and set ext */ ori r3,r3,0x00C0 /* clock for UART0 and UART1 */ mfdcr r4,cntrl0 /* read CNTRL0 */ or r3,r3,r4 /* read-modify-write */ mtdcr cntrl0,r3 /* set CNTRL0 */ addis r4,r0,FPGA_BRDC@h ori r4,r4,FPGA_BRDC@l lbz r3,0(r4) /* get FPGA board control reg */ eieio ori r3,r3,0x01 /* set UART1 control to select CTS/RTS */ stb r3,0(r4) /* Initialize the 405's first UART... * Optionally include a startup message. */ bl uart0_init#if INCLUDE_HERALD addis r3,r0,..herald_GP@h ori r3,r3,..herald_GP@l bl put_string#endif /* Initialize IIC Controller */ bl iic0_init /* We only want to run sdram_init out of a coldstart, so if R15 contains * the INITIALIZE value, we run sdram_init; else we skip over it. */ addi r3,r0,INITIALIZE cmp cr0,0,r15,r3 bne ..skip_sdraminit /* Initialize SDRAM Controller... * Include a message indicating that it will take a while if ECC is * enabled. */#if INCLUDE_ECC addis r3,r0,..sdram_start@h ori r3,r3,..sdram_start@l bl put_string#endif bl sdram_init..skip_sdraminit: /* Clear reservation bit. */ addis r4,r0,0x0000 lwarx r3,r0,r4 /* get some data/set resv bit stwcx. r3,r0,r4 /* store out and clear resv bit /* Flush data cache. */ bl ppcDflush /* Call calc_speed() to determine the 405GP system clock period, the * number of nanoseconds per clock of the 405GP SYS_CLOCK. * Set the global variable Sys_clock_period. */ bl calc_speed addis r4,r0,Sys_clock_period@h ori r4,r4,Sys_clock_period@l stw r3, 0(r4) /* Initialize the Control 1 register for Timer control. * The CPU timers can be incremented at the CPU clock frequency or * at the frequency of an external clock supplied to the TMR_CLK * input. The default register setting of Control 1 reg is to use * the CPU. The Walnut board supplies the TMR_CLK input with an * external clock equal to 1/4 of the 405GP SYS_CLOCK. Calculate * timer ticks per second based on which clock used and store in * the global variable Ticks_per_sec. */#ifdef EXT_TIMER_INPUT addis r5,r0,0x0080 /* set CPU ext timer clock enable */ /* to use external timer */ mfdcr r4,cntrl1 /* read CNTRL1 */ or r5,r5,r4 /* read-modify-write */ mtdcr cntrl1,r5 /* set CNTRL1 */ slwi r3,r3,2 /* multiply 405GP SYS_CLOCK period */ /* (still in r3) by 4 since on */ /* Walnut the ext timer clk is */ /* 1/4 of the 405GP SYS_CLOCK (ie, */ /* 4 times 405GP Sys_clock_period) */ addis r5,r0,ONE_BILLION@h /* calculate timer ticks per second */ ori r5,r5,ONE_BILLION@l /* by diving 1 billion by the timer */ divwu r3,r5,r3 /* clock period stored in r3 */ mfpvr r7 /* check PVR */ rlwinm r7,r7,0,0x000003FF /* use bits 22:31 of pvr to determine */ cmpi cr0,0,r7,0x0 /* if 405GP pass 1 (PVR=0x40110000) */ bne ..set_ticks /* if not pass 1 OK, set Ticks_per_sec */ /* to external timer clock speed in r3 */ mfdcr r5,pllmd /* else determine CPU/PLB ratio */ /* via PLL mode reg and mult ticks */ /* per sec by the CPU/PLB ratio. This */ /* is a pass 1 bug that will be fixed */ /* in pass 2. */ rlwinm r4,r5,15,0x3 /* get PLB to CPU divide bits (PLBDIV) */ addi r4,r4,0x1 /* add one to get divider (1,2,3,or 4) */ mullw r3,r3,r4 /* mult ticks per sec (still in r3 */ /* in MHz) by PLBDIV to get the CPU */ /* timer speed */#else /* Note that the method below may introduce a small error in timing. * For example, if the 405GP SYS_CLOCK period is 30ns, we divide * 1 billion by 30 to get 33,333,333Mhz. We then multiply this number * by FBKDIV and PLBDIV to get the CPU speed. If FBKDIV=2 and PLBDIV=2, * our calculated CPU speed is (33,333,333 x 2 x 2) = 133,333,332Mhz, * 1 Mhz lower than what it should be (133,333,333MHz). * It would be best to hard code Ticks_per_sec rather than try to * calculate it since in most environments the CPU speed will be known. * Here we are trying to support multiple CPU speeds. */ addis r5,r0,ONE_BILLION@h /* convert 405GP SYS_CLOCK period */ ori r5,r5,ONE_BILLION@l /* to MHz by diving 1 billion by */ divwu r3,r5,r3 /* the timer clock period stored in r3 */ mfdcr r5,pllmd /* read PLL Mode reg */ rlwinm r4,r5,3,0x7 /* get PLL forward divide bits (FWDDIV) */ cmpi cr0,0,r4,0x7 beq ..bypass_mode /* if FWDDIV=b'111' then bypass mode */ rlwinm r4,r5,7,0xF /* get PLL feedback divide bits(FBKDIV) */ mullw r3,r3,r4 /* mult 405GP speed (still in r3 */ /* in MHz) by FBKDIV to get PLB speed */ rlwinm r4,r5,15,0x3 /* get PLB to CPU divide bits (PLBDIV) */ addi r4,r4,0x1 /* add one to get divider (1,2,3,or 4) */ mullw r3,r3,r4 /* mult PLB clock speed (still in r3 */ /* in MHz) by PLBDIV to get the CPU */ /* clock speed */..bypass_mode: /* bypass mode; CPU clock period is */ /* the same as the 405GP SYS_CLOCK */ /* period - do not need to do anything */ /* since 405GP clock speed is */ /* still in r3 in MHz */#endif..set_ticks: addis r4,r0,Ticks_per_sec@h ori r4,r4,Ticks_per_sec@l stw r3, 0(r4) /* Check for 405GP pass1 and ensure PCI addr pipelining * disabled in the CNTRL1 reg. * This will be fixed in pass2. */ mfpvr r7 /* check PVR rlwinm r7,r7,0,0x000003FF /* use bits 22:31 of pvr to determine */ cmpi cr0,0,r7,0x0 /* if 405GP pass 1 (PVR=0x40110000) */ bne ..ok_cont mfdcr r4,cntrl1 /* read CNTRL1 */ rlwinm r4,r4,0,19,17 /* ensure bit 18 of cntrl1 (PCI addr */ /* pipeline enable) is off for pass1 */ mtdcr cntrl1,r4 /* set CNTRL1 */..ok_cont:SPInit: /* initialize the stack pointer (Diab/Data compiler needs 2 words) */ lis sp, (MonStack+(MONSTACKSIZE-8))@ha addi sp, sp, (MonStack+(MONSTACKSIZE-8))@l addi r7, r0, -8 and sp, sp, r7 /* 8-byte aligned (EABI spec) */ /* * initialize r2 and r13 according to EABI standard * Warning: The monitor cannot use the small data or small const areas. * When an application runs, it takes over R2 and R13 so the * monitor can't use them and allow itself to be called by the * application. This also means the monitor cannot call the * Diab/Data standard library since those functions do not * avoid these areas. */ lis r2, (_SDA2_BASE_)@ha addi r2, r2, (_SDA2_BASE_)@l lis r13, (_SDA_BASE_)@ha addi r13, r13, (_SDA_BASE_)@lGoToC: bl invalidate_icache /* Cache had been enabled previously, so */ addi r4,0, 0x0000 /* we need to shut if off prior to entering */ mticcr r4 /* C-level because the C-startup assumes */ addi r4,0, 0x0000 /* it starts with cache off, then it will */ bl invalidate_dcache /* appropriately enbable cache when it is */ mtdccr r4 /* ready (after calling FlashInit()). */ mr r3,r15 /* Copy r15 to r3. */ b start/**************************************************************************** * * Function: invalidate_icache */ .text .align 2 .globl invalidate_icacheinvalidate_icache: iccci r0,r0 /* for 405, iccci invalidates the */ blr /* entire I cache *//**************************************************************************** * * Function: invalidate_dcache */ .text .align 2
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -