📄 start.s
字号:
/* $Id: start.S,v 1.7 2002/11/15 22:39:56 patrik Exp $ *//* * Copyright (c) 2000 Opsycon AB (www.opsycon.se) * Copyright (c) 2000 Rtmx, Inc (www.rtmx.com) * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed for Rtmx, Inc by * Opsycon Open System Consulting AB, Sweden. * 4. The name of the author may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * */#define DEBUG#include "target/pmon_target.h"#include <include/palomarii.h>#include <pmon/dev/cpc700.h>#include <powerpc.h> #ifndef INT_MASK#define INT_MASK(src, des) rlwinm des, src, 0, 17, 15#endif /* INT_MASK */ .space 0x100 .globl _start .globl start_start:start: .globl pmon_stackstack = start - 0x4000 /* 16K PMON stack */pmon_stack = start /* Top of stack */ .globl pmon_intstackintstack = stack - 0x2000 /* 8k PMON interrupt stack */pmon_intstack = stack /* Top of stack *//* Clear MSR to diable interrupts and checks */ andi. 1, 1, 0x0 mtmsr 1 /* Clear MSR *//* Clear mapping registers */ li 1, 0x0 mtibatu 0, 1 mtibatl 0, 1 mtibatu 1, 1 mtibatl 1, 1 mtibatu 2, 1 mtibatl 2, 1 mtibatu 3, 1 mtibatl 3, 1 mtdbatu 0, 1 mtdbatl 0, 1 mtdbatu 1, 1 mtdbatl 1, 1 mtdbatu 2, 1 mtdbatl 2, 1 mtdbatu 3, 1 mtdbatl 3, 1 isync sync sync lis 1, 0x8000 isync mtsr 0, 1 mtsr 1, 1 mtsr 2, 1 mtsr 3, 1 mtsr 4, 1 mtsr 5, 1 mtsr 6, 1 mtsr 7, 1 mtsr 8, 1 mtsr 9, 1 mtsr 10, 1 mtsr 11, 1 mtsr 12, 1 mtsr 13, 1 mtsr 14, 1 mtsr 15, 1 isync sync sync/* Turn off caches and invalidate them */ mfspr 3, HID0 isync rlwinm 4, 3, 0, 18, 15 /* clear d15 and d16 */ sync isync mtspr HID0, 4 /* turn off caches */ isync lis 3, 0 /* XXX 603/740 specific code */ ori 3, 3, 0x0c00 /* Enable & invalidate bits */ or 4, 4, 3 sync isync mtspr HID0, 4 andc 4, 4, 3 isync li 11, 0x2000 /* No harm */ mtspr CTR, 111: bdnz 1b isync mtspr HID0, 4 isync ori 4, 4, 0x8800 isync mtspr HID0, 4 /* turn on i-cache for speed */ rlwinm 4, 4, 0, 21, 19 /* clear the ICFI bit */ isync mtspr HID0, 4/* Get CPU type */ mfspr 28, 287 rlwinm 28, 28, 16, 16, 31/* Set r16 to the load vs link offset. */ bl 1f1: mflr 3 lis 16, 0xffff and. 16, 16, 3 lis 4, HI(start) sub 16, 16, 4 /* R16 is now load offset *//* * Find out if executing in ROM or RAM. Note memory size wired to 64Mb. */ lis 15, 0x0400 /* Memory size accumulator = 64MB */ lis 4, 0xf000 /* Last 256Mb segment */ and. 4, 4, 3 beq in_ram /* We are ram loaded! *//* * Set up on chip L2 cache controller. */ sync mfspr 4, L2CR sync isync rlwinm 4, 4, 0, 1, 31 mtspr L2CR, 4 sync isync lis 4, 0x3b01 /* parity disable, 1Mb /2.5 L2CLK (Okn was here)*/ ori 4, 4, 0x0 /* inst. cache enable, copy-back */ mtspr L2CR, 4 sync isync oris 3, 4, 0x0020 /* Invalidate cache */ mtspr L2CR, 3 sync isync1: mfspr 1, L2CR sync isync rlwinm 1, 1, 0, 31, 31 cmpwi 1, 0x1 beq 1b /* Wait until invalidate done. */ mtspr L2CR, 4 /* Clear invalidate bit. */ sync isync oris 4, 4, 0x8000 mtspr L2CR, 4 /* Enable L2 cache */ sync isync/* * Init the PCI/Memory controller (CPC700) */ lis 0, HI(CPC700_PCICFGADDR) ori 1, 0, 0x0000 ori 2, 0, 0x0004/**/ lis 3, 0x8000 ori 3, 3, CPC700_PCI_REV stwbrx 3, 0, 1 IORDER lwbrx 26, 0, 2 /* Get device revision number */ andi. 26, 26, 0x00ff /* Isolate revision bits. *//**/ lis 3, 0x8000 ori 3, 3, CPC700_PCI_CMD stwbrx 3, 0, 1 IORDER lhbrx 4, 0, 2 lis 3, 0x001f /* Enable and reset pci status */ ori 3, 3, 0xfc00 and 4, 4, 3 lis 3, 0xf900 ori 3, 3, 0x0106 or 4, 4, 3 sthbrx 4, 0, 2 /* XXX Check size of store... */ IORDER/* * Set up CPC700's memory configuration as follows: * * Starting Ending * Bank 0 (FFC0_0000 -- FFF0_0000) -- Boot ROM (8-bit) * Bank 1 (FF80_0000 -- FFB0_0000) -- FLASH 4M (8-bit) * Bank 2 (0000_0000 -- 03F0_0000) -- SDRAM 64M * Bank 3 -- tbd * Bank 4 (7FF0_0000 -- 7FF0_0000) -- CPLD */ lis 0, HI(CPC700_MEMCFGADDR) ori 1, 0, LO(CPC700_MEMCFGADDR) ori 2, 0, LO(CPC700_MEMCFGDATA)/**/ CPC700_MEM_SETUP(CPC700_MBEN, 0x80000000, 0x07ffffff) CPC700_MEM_SETUP(CPC700_MEMTYPE, 0x04000000, 0x003fffff) CPC700_MEM_SETUP(CPC700_RBW, 0x00000000, 0x003fffff) CPC700_MEM_SETUP(CPC700_RPB1P, 0x291990f0, 0x000fffff) CPC700_MEM_SETUP(CPC700_RTR, 0x03f80000, 0x0000ffff) CPC700_MEM_SETUP(CPC700_DAM, 0x04000000, 0x003fffff) CPC700_MEM_SETUP(CPC700_SDTR1, 0x0004880a, 0xfe0003e0) CPC700_MEM_SETUP(CPC700_ECCCF, 0x40200000, 0x370707ff) CPC700_MEM_SETUP(CPC700_RPB4P, 0x291990f0, 0x000fffff) CPC700_MEM_SETUP(CPC700_FWEN, 0x08000000, 0x000fffff) CPC700_MEM_SETUP(CPC700_MB0SA, 0xffc00000, 0x000fffff) CPC700_MEM_SETUP(CPC700_MB0EA, 0xfff00000, 0x000fffff) CPC700_MEM_SETUP(CPC700_MB1SA, 0xff800000, 0x000fffff) CPC700_MEM_SETUP(CPC700_MB1EA, 0xffb00000, 0x000fffff) CPC700_MEM_SETUP(CPC700_MB2SA, 0x00000000, 0x000fffff) CPC700_MEM_SETUP(CPC700_MB2EA, 0x03f00000, 0x000fffff) CPC700_MEM_SETUP(CPC700_MB4SA, 0x7ff00000, 0x000fffff) CPC700_MEM_SETUP(CPC700_MB4EA, 0x7ff00000, 0x000fffff) CPC700_MEM_SETUP(CPC700_MBEN, 0xe8000000, 0x07ffffff) CPC700_MEM_SETUP(CPC700_MCOPT1, 0x85000000, 0x18ffffff)/**//**/ li 4, 0x2000 mtctr 41: bdnz 1b /* Delay to allow memory to initialize *//**/ mfmsr 3 INT_MASK(3, 4) /* Disable interrupt */ ori 3, 3, 0x3002 /* set FP, ME and RI */ mtmsr 3/* * Now we need to enable the IBAT/DBAT (after setup) to be able to * access 0xfff00000+ if processor is 740/750! */ IBAT_SETUP(0, 0x00001fff, 0x0000001a) IBAT_SETUP(1, 0xf0001fff, 0xf000002a) IBAT_SETUP(2, 0x00000000, 0x00000000) IBAT_SETUP(3, 0x00000000, 0x00000000) DBAT_SETUP(0, 0x00000fff, 0x00000002) DBAT_SETUP(1, 0x7fc0007f, 0x7fc0002a) DBAT_SETUP(2, 0x80001fff, 0x80000022) DBAT_SETUP(3, 0xf8000fff, 0xf8000022) mfmsr 3 /* Enable translation */ ori 3, 3, 0x0010 isync mtmsr 3 sync/* Turn off bitfail LED to show that mem init is done */ lis 3, HIADJ(PALOMAR_CNTL_CLEAR) li 4, PALOMAR_LED_BITFAIL stb 4, LO(PALOMAR_CNTL_CLEAR)(3) lis 3, HIADJ(PALOMAR_CNTL_SET) li 4, PALOMAR_LED_USER stb 4, LO(PALOMAR_CNTL_SET)(3)/* Set up PCI to Palomar mapping. FFF0-> now readable so use a table. */ bl init_pmm .long CPC700_PMM0HIGH, 0x00000000 .long CPC700_PMM0LO, 0x00000000 .long CPC700_PMM0ADDR, 0x80000000 .long CPC700_PMM0MASK, 0xf0000001 .long CPC700_PMM1HIGH, 0x00000000 .long CPC700_PMM1LO, 0x10000000 .long CPC700_PMM1ADDR, 0x90000000 .long CPC700_PMM1MASK, 0xf0000001 .long CPC700_PTM1ADDR, 0x00000000 .long CPC700_PTM1SIZE, 0xfc000001 .long CPC700_PTM2ADDR, 0x00000000 .long CPC700_PTM2SIZE, 0x00000000 .long CPC700_PCICFGADDR, 0x80000000+0x14 .long CPC700_PCICFGADDR+4, 0x00000008 .long 0init_pmm: mflr 5 lwz 3, 0(5) /* address */1: lwz 4, 4(5) /* value */ stwbrx 4, 0, 3 addi 5, 5, 2*4 lwz 3, 0(5) and. 3, 3, 3 bne 1b/* * We init the IIC interface here, although doing it in C is an option. */ lis 3, HIADJ(CPC700_IIC0_MDBUF) addi 3, 3, LO(CPC700_IIC0_MDBUF) li 4, 0x0 stb 4, CPC700_IIC_LMADR(3) stb 4, CPC700_IIC_HMADR(3) stb 4, CPC700_IIC_LSADR(3) stb 4, CPC700_IIC_HSADR(3) li 4, 0x8 stb 4, CPC700_IIC_STS(3) li 4, 0x8f stb 4, CPC700_IIC_EXTSTS(3) li 4, 0x3 stb 4, CPC700_IIC_CLKDIV(3) li 4, 0x0 stb 4, CPC700_IIC_INTRMSK(3) stb 4, CPC700_IIC_XFRCNT(3) li 4, 0xf0 stb 4, CPC700_IIC_XTCNTLSS(3) li 4, 0x43 stb 4, CPC700_IIC_MDCNTL(3) li 4, 0x0 stb 4, CPC700_IIC_CNTL(3)/* * RAM memory should now be operational, we can call C-code (some * restrictions still do apply, like usage of initialised vars). * We scrub the entire memory to get rid of potential parity errors. */ lis 4, HIADJ(main_msg) addi 4, 4, LO(main_msg) add 4, 4, 16 bl serial_out srwi 3, 15, 2 /* Mem size div 4 */ li 4, 0x4000 /* Start from 0x4000 to preserve */ sub 3, 3, 4 /* message areas */ mtctr 31: stw 4, 0(4) /* Zero out what will be the stack */ addic 4, 4, 0x4 bdnz 1b b in_romin_ram: lis 4, HIADJ(ram_msg) addi 4, 4, LO(ram_msg) add 4, 4, 16 bl serial_outin_rom: lis 4, HI(start) addi 1, 4, -64 /* RAM START++ will be overwritten */ stw 15, 8(1) /* Save away memory size */ add 3, 4, 16 bl copytoram /* Go do PPC initialization */ cmpwi 3, 0 beq __go /* Verify after copy succeded *//* Turn on bitfail LED to show that mem init failed */ lis 3, HIADJ(PALOMAR_CNTL_SET) li 4, PALOMAR_LED_BITFAIL stb 4, LO(PALOMAR_CNTL_SET)(3) lis 4, HIADJ(fail_msg) addi 4, 4, LO(fail_msg) b bootinit_fail/* * All stations are GO for takeoff. * Lets go to the other end of the universe! */__go: lwz 3, 8(1) /* Memorysize */ mfspr 4, HID0 ori 4, 4, 0x4084 /* Enable D-cache */ isync /* Serialize disable and branch history enab */ mtspr HID0, 4 isync lis 1, HIADJ(STACKBASE) addi 1, 1, LO(STACKBASE) mtsprg 0, 1 addi 1, 1, LO(STACKSIZE-64) li 0, 0x0 /* Mark end of frames on stack */ stw 0, 0(1) stw 0, 4(1) lis 4, HIADJ(initppc) addi 4, 4, LO(initppc) mtlr 4 blr .rodatamain_msg: .asciz "\r\nPMON2000 PowerPC Initializing. Standby...\r\n"ram_msg: .asciz "\r\nPMON2000 PowerPC Ramloaded. Standby...\r\n"fail_msg: .asciz "PANIC! Verify after copy to ram failed!\r\n" .section ".text" .align 2/**/bootinit_abort: lis 4, HIADJ(abt_msg) addi 4, 4, LO(abt_msg)bootinit_fail: add 4, 4, 16 bl serial_out1: b 1b .section ".rodata"abt_msg: .asciz "PMON/PPC ABORT! No RAM memory found!\r\n" .section ".text" .align 2/**//* * Simple serial output routine used to communicate messages * during prom setup before 'real' driver is running. * This code simply displays a string of chars on the console. */serial_out:#ifdef POCONO lis 30, HIADJ(REAR_COM_BASE_ADDR) addi 30, 30, LO(REAR_COM_BASE_ADDR)#else lis 30, HIADJ(CPC700_UART0RBR) addi 30, 30, LO(CPC700_UART0RBR)#endif li 31, 1 stb 31, 4(30) /* DTR on */ IORDER li 31, 0x80 /* Get to divisor latch */ stb 31, 3(30) IORDER#ifdef POCONO li 31, 0x78 /* Baud rate */#else li 31, 0x35 /* Baud rate */#endif stb 31, 0(30) IORDER li 31, 0x0 stb 31, 1(30) IORDER li 31, 0x3 /* 8 bits no parity */ stb 31, 3(30) IORDER lis 31, 0x0002 /* let sio stabilize */ mtctr 311: bdnz 1b2: lbz 31, 0(4) cmpwi 31, 0 beq 4f3: lbz 31, 5(30) andi. 31, 31, 0x20 beq 3b /* Wait for tx buffer empty */ lbz 31, 0(4) stb 31, 0(30) /* send char */ IORDER addi 4, 4, 1 b 2b4: blr /* return *//**/ .globl tgt_putchartgt_putchar:#ifdef POCONO lis 9, HIADJ(REAR_COM_BASE_ADDR) addi 9, 9, LO(REAR_COM_BASE_ADDR)#else lis 9, HIADJ(CPC700_UART0RBR) addi 9, 9, LO(CPC700_UART0RBR)#endif1: lbz 0, 5(9) andi. 0, 0, 0x20 beq 1b stb 3, 0(9) blr/**/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -