📄 start.s
字号:
/* $Id: start.S,v 1.2 2002/11/07 15:05:26 pefo Exp $ *//* * Copyright (c) 2000-2002 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"#ifndef INT_MASK#define INT_MASK(src, des) rlwinm des, src, 0, 17, 15#endif /* INT_MASK */#define HID0 1008#define CTR 9#define HIADJ(x) (x)@ha#define HI(x) (x)@h#define LO(x) (x)@l#define PRINTSTR(str) \ bl 9f; \ .asciz str; \ .align 2; \9: mflr 3; \ bl serial_out /* * Use this macro to prevent reordering by as/ld and processor */#define IORDER eieio; sync/* * Use this macro to address a config reg when R0 has base. */#define MAKEADR(adr) ori 3, 0, (adr); stwbrx 3, 0, 1; IORDER .space 0x100 .globl _start .globl start_start:start: .globl pmon_stackstack = start - 0x4000 /* Place PMON stack below PMON start in RAM */pmon_stack = start /* Top of stack */ .globl pmon_intstackintstack = stack - 0x2000 /* 8K 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 604 specific code */ ori 3, 3, 0xcc00 /* Enable & invalidate bits */ or 4, 4, 3 sync isync mtspr HID0, 4 andc 4, 4, 3 isync li 11, 0 ori 11, 11, 0x2000 mtspr CTR, 111: bdnz 1b isync mtspr HID0, 4 isync ori 4, 4, 0x8800 isync mtspr HID0, 4 /* turn on i-cache for speed *//* 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! */ PRINTSTR("\r\n\n\nPMON2000 PowerPC Initializing. Standby...\r\n")/* * Init the PCI/Memory controller (MPC106) */ lis 0, HI(MPC106_BASE) /* R0 is base reg thruout */ ori 1, 0, LO(MPC106_CFG_ADDR) /* R1 cfg addr */ ori 2, 0, LO(MPC106_CFG_DATA) /* R2 data pointer */ MAKEADR(MPC106_REG_REV) lbz 26, 0(2) /* get MPC106 chip revision */ IORDER/**/ MAKEADR(MPC106_REG_MCFG1) lwbrx 4, 0, 2 lis 3, 0x0008 andc 4, 4, 3 /* 0xfff7ffff = clear MEMG0 */ stwbrx 4, 0, 2/**/ isync /* now do pci init */ lis 3, 0x8080 /* subtile fumbling with ISA config in */ ori 3, 3, 0x084c /* the 82378ZB. 08 = devsel, 4c is offset */ lis 4, 0x5600 /* note! bytes reversed! */ ori 4, 4, 0x13f4 stw 4, 0(3) IORDER /**/ lis 3, HIADJ(P4E_MISC) lbz 4, LO(P4E_MISC)(3) andi. 4, 4, 0xfc /* LED bitfail off user off */ stb 4, LO(P4E_MISC)(3)#if 1/* * Configure L2 cache */ lis 6, HIADJ(P4E_CFG) lbz 7, LO(P4E_CFG)(6) /* Get L2 cache configuration *//**/ MAKEADR(MPC106_REG_CFG_AC) lwbrx 4, 0, 2/* XXX Next two instructions looks bogus. However it's put here as a * preparation for Eagle vs. Grackle support. Eagle preserves other bits */ xor 3, 3, 3 and 4, 4, 3 lis 3, 0x103a /* L2 Disable */ andi. 7, 7, P4E_CFG_L2 cmpwi 7, P4E_CFG_L2_NONE beq 2f lis 3, 0x903a /* L2 invalidate, 2 clk snoop */ ori 3, 3, 0x04c4 /* L2 = 256K - default */ cmpwi 7, P4E_CFG_L2_IS_512K bne 1f ori 3, 3, 0x04d4 /* L2 = 512K */ b 2f1: cmpwi 7, P4E_CFG_L2_IS_1M bne 2f ori 3, 3, 0x04e4 /* L2 = 1M */2: or 4, 4, 3 stwbrx 4, 0, 2 /* Set cache configuration */ IORDER lis 3, 0x1000 andc 4, 4, 3 /* L2 invalidate OFF */ lis 3, 0x4000 ori 3, 3, 0x4000 or 4, 4, 3 stwbrx 4, 0, 2 /* L2 Enable */ IORDER/* * Set up the cache controller */ MAKEADR(MPC106_REG_CFG_A8) lwbrx 4, 0, 2/* XXX Grackle mask 0x00000000, Eagle mask 0x00004100 (ifdefs later)*/ xor 3, 3, 3 and 4, 4, 3 lis 3, 0x7f21 oris 3, 3, 0x6 /* CPU type = 604 */ ori 3, 3, 0x1e99 /* Default = write thru cache */ ori 3, 3, 0x0004 /* PCI prefetch */ cmpwi 26, 0x40 /* Chip rev less than 4.0? */ blt 1f /* Yes, keep write thru */ rlwinm 3, 3, 0, 0, 29 /* else */ ori 3, 3, 0x2 /* Switch to write back! */1: or 4, 4, 3 stwbrx 4, 0, 2 IORDER#endif/* * Init PCI command and status registers */ MAKEADR(MPC106_REG_PCI_CMD) lhbrx 4, 0, 2 andi. 4, 4, 0xfca0 /* preserve */ ori 4, 4, 0x106 sthbrx 4, 0, 2 IORDER/**/ MAKEADR(MPC106_REG_PCI_STAT) li 3, 2 lhbrx 4, 3, 2 ori 4, 4, 0xf900 sthbrx 4, 3, 2 /* Clear PCI stat/error bits */ IORDER/* * Set up the memory controller */ lis 3, HIADJ(P4E_MISC) lbz 7, LO(P4E_MISC)(3) lis 3, HIADJ(P4E_MEZZ_CFG) lbz 8, LO(P4E_MEZZ_CFG)(3)/**/ MAKEADR(MPC106_REG_MCFG1) lwbrx 4, 0, 2 /* Get memcfg 1 */ lis 3, 0xf702 /* Adjust ROM waitstates */ cmpwi 26, 0x40 blt 1f oris 3, 3, 0x1 /* Chip rev 4.0+, enable parity */1: ori 3, 3, 0xaaaa /* 11 row bits */ and 4, 4, 3 or 4, 4, 3 stwbrx 4, 0, 2 IORDER/**/ MAKEADR(MPC106_REG_MCFG2) lwbrx 4, 0, 2 lis 3, 0xfffc /* Grackle preserve */ and 4, 4, 3 lis 3, 0 andi. 6, 7, P4E_MISC_MEM cmpwi 6, P4E_MISC_MEM_16FPM beq 1f cmpwi 6, P4E_MISC_MEM_32FPM beq 1f lis 3, 11: ori 3, 3, 0x1014 cmpwi 26, 0x40 blt 1f ori 3, 3, 0x1 /* RMW parity enable */1: or 4, 4, 3 stwbrx 4, 0, 2 /* Set mem config 2 */ IORDER/**/ MAKEADR(MPC106_REG_MCFG3) lwbrx 4, 0, 2 andis. 4, 4, 0xfff0 /* Preserve bits */ oris 4, 4, 0x0002 /* RASP=0101, CAS5=001, CP4=001 */ ori 4, 4, 0x925b /* CAS3=001, RCD2=110, RP1=011 */ stwbrx 4, 0, 2 IORDER/**/ MAKEADR(MPC106_REG_MCFG4) lwbrx 4, 0, 2 lis 3, 0x0010 /* XXX Grackle preserve */ andc 4, 4, 3 /* 0xffefffff */ or 4, 4, 3 /* Transparent latch */ stwbrx 4, 0, 2/**/ MAKEADR(MPC106_REG_MBEN) /* Bank enables */ li 3, 0x0 stb 3, 0(2) /* Disables all banks */ li 4, 0x0 li 9, 0x0 /* Bank select reg */ li 14, 0x0 /* Total mem size */ li 11, 0x0 /* Bank enables */ li 15, 0x0 /* Memory size accumulator */ li 12, 0x000a /* Bank 0,1 defaults to 11 row bits *//**/ andi. 6, 8, P4E_MEZZ1 /* Check for mezzanine memory */ cmpwi 6, P4E_MEZZ1_16FPM beq 16f cmpwi 6, P4E_MEZZ1_16EDO beq 16f cmpwi 6, P4E_MEZZ1_32FPM beq 32f cmpwi 6, P4E_MEZZ1_32EDO beq 32f cmpwi 6, P4E_MEZZ1_64EDO beq 64f cmpwi 6, P4E_MEZZ1_128EDO beq 128f b bootinit_abort /* Nothing found ! */16: lis 14, 0x0100 /* 16M */ li 9, 0x000f /* 16M ending address */ ori 11, 11, 0x0001 /* Enable bank 0 */ mr 13, 9 rlwinm 13, 13, 16, 8, 15 addis 13, 13, 1 addis 15, 15, 0x0100 b 9f32: lis 14, 0x0200 /* 32M */ li 4, 0x1000 /* 16M in 0, 16M in 1 */ li 9, 0x1f0f /* 16M, 32M ending address */ ori 11, 11, 0x0003 /* Enable bank 0 & 1 */ mr 13, 9 rlwinm 13, 13, 8, 8, 15 addis 13, 13, 1 addis 15, 15, 0x0200 b 9f64: lis 14, 0x0400 /* 64M */ li 12, 0x0003 li 4, 0x0000 li 9, 0x003f ori 11, 11, 0x0001 mr 13, 9 rlwinm 13, 13, 16, 8, 15 addis 13, 13, 1 addis 15, 15, 0x0400 b 9f128: lis 14, 0x0800 /* 128M */ li 12, 0x000f li 4, 0x4000 li 9, 0x7f3f ori 11, 11, 0x0003 mr 13, 9 rlwinm 13, 13, 8, 8, 15 addis 13, 13, 1 addis 15, 15, 0x08009: or 4, 4, 13 /* Bank 2 starting address *//**/ ori 12, 12, 0x00a0 andi. 6, 8, P4E_MEZZ2 cmpwi 6, P4E_MEZZ2_16FPM beq 16f cmpwi 6, P4E_MEZZ2_16EDO beq 16f cmpwi 6, P4E_MEZZ2_32FPM beq 32f cmpwi 6, P4E_MEZZ2_32EDO beq 32f cmpwi 6, P4E_MEZZ2_64EDO beq 64f cmpwi 6, P4E_MEZZ2_128EDO beq 128f b 9f16: addis 14, 14, 0x0100 /* bump 16M */ addis 13, 13, 0x000f or 9, 9, 13 ori 11, 11, 0x0004 addis 15, 15, 0x0100 b 9f32: addis 14, 14, 0x0200 /* bump 32M */ addis 13, 13, 0x000f or 9, 9, 13 rlwinm 13, 13, 8, 0, 7 addis 13, 13, 0x0100 or 4, 4, 13 addis 13, 13, 0x0f00 or 9, 9, 13 ori 11, 11, 0x000c addis 15, 15, 0x0200 b 9f64: addis 14, 14, 0x0400 /* bump 64M */ addis 13, 13, 0x003f or 9, 9, 13 ori 11, 11, 0x0004 andi. 12, 12, 0xff0f ori 12, 12, 0x0030 addis 15, 15, 0x0400 b 9f128: addis 14, 14, 0x0800 /* bump 128M */ addis 13, 13, 0x003f or 9, 9, 13 rlwinm 13, 13, 8, 0, 7 addis 13, 13, 0x0100 or 4, 4, 13 addis 13, 13, 0x3f00 or 9, 9, 13 ori 11, 11, 0x000c andi. 12, 12, 0xff0f /* hmm... */ ori 12, 12, 0x00f0 addis 15, 15, 0x08009:/**/ MAKEADR(MPC106_REG_MSTA_03) stwbrx 4, 0, 2 IORDER/**/ li 4, 0 MAKEADR(MPC106_REG_MSTA_47) stwbrx 4, 0, 2 IORDER/**/ lis 3, 0xfcfc ori 3, 3, 0xfcfc MAKEADR(MPC106_REG_EMSTA_03) lwbrx 4, 0, 2 and 4, 4, 3 stwbrx 4, 0, 2 IORDER MAKEADR(MPC106_REG_EMSTA_47) lwbrx 4, 0, 2 and 4, 4, 3 /* r3 = 0xfcfcfcfc */ stwbrx 4, 0, 2 IORDER/**/ MAKEADR(MPC106_REG_MEND_03) stwbrx 9, 0, 2 IORDER/**/ li 4, 0 MAKEADR(MPC106_REG_MEND_47) stwbrx 4, 0, 2 IORDER/**/ MAKEADR(MPC106_REG_EMEND_03) lwbrx 4, 0, 2 and 4, 4, 3 /* r3 = 0xfcfcfcfc */ stwbrx 4, 0, 2 IORDER/**/ MAKEADR(MPC106_REG_EMEND_47) lwbrx 4, 0, 2 and 4, 4, 3 /* r3 = 0xfcfcfcfc */ stwbrx 4, 0, 2 IORDER/**/ MAKEADR(MPC106_REG_MBEN) stb 11, 0(2)/**/ li 4, 0x2000 mtctr 41: bdnz 1b /* Delay to allow memory to initialize *//**/ MAKEADR(MPC106_REG_MCFG1) lwbrx 4, 0, 2 oris 4, 4, 0x0008 or 4, 4, 12 stwbrx 4, 0, 2/**/ 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/* * 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. */ PRINTSTR("Scrubbing memory. Standby...\r\n") li 4, 0x4000 /* Start from 0x4000 to preserve */ sub 3, 15, 4 /* message areas */ srwi 3, 3, 2 /* Mem size div 4 */ mtctr 31: stw 4, 0(4) /* Zero out what will be the stack */ addic 4, 4, 0x4 bdnz 1b PRINTSTR("Memory scrubbing done!\r\n")in_ram: lis 4, HI(start) addi 1, 4, -64 /* RAM START++ will be overwritten */ stw 15, 8(1) /* Save away memory size */ PRINTSTR("Moving PMON2000 to RAM!\r\n") add 3, 4, 16 bl copytoram /* Go do PPC initialization */ cmpwi 3, 0 beq gopmon PRINTSTR("Verify after copy failed! Halting!!\r\n")1: b 1bgopmon:/* * All stations are GO for takeoff. * Lets go to the other end of the universe! */ lwz 5, 8(1) /* Memorysize */ PRINTSTR("Success!\r\n") mfspr 4, HID0 ori 4, 4, 0xcc84 /* Enable D-cache */ /* Branch target cache on 604em is 0x0002 */ isync /* Serialize disable and branch history enab */ mtspr HID0, 4 isync lis r1, HIADJ(STACKBASE) addi r1, r1, LO(STACKBASE) mtsprg 0, r1 addi r1, r1, 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 or 3, 5, 5 blr/**/bootinit_abort: PRINTSTR("PMON/PPC ABORT! No RAM memory found!\r\n")1: b 1b/* * 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: lis 30, HIADJ(COM1_BASE_ADDR) addi 30, 30, LO(COM1_BASE_ADDR) li 31, 1 stb 31, 4(30) /* DTR on */ IORDER li 31, 0x80 /* Get to divisor latch */ stb 31, 3(30) IORDER li 31, 0x4 /* Baud rate */ 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, 0x0020 /* let sio stabilize */ mtctr 311: bdnz 1b2: lbz 31, 0(3) cmpwi 31, 0 beq 4f3: lbz 31, 5(30) andi. 31, 31, 0x20 beq 3b /* Wait for tx buffer empty */ lbz 31, 0(3) stb 31, 0(30) /* send char */ addi 3, 3, 1 b 2b4: blr /* return *//**/ .globl tgt_putchartgt_putchar: lis 9, HIADJ(COM1_BASE_ADDR) addi 9, 9, LO(COM1_BASE_ADDR)1: 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 + -