📄 rominit.s
字号:
/* romInit.s - Sandpoint w/PPMC8240 ROM initialization module *//* Copyright 1984-2000 Wind River Systems, Inc. *//* Copyright 1996-1998 Motorola, Inc. *//*modification history--------------------01l,16jul02,pcs Add recognition of PCI DeviceID for the 8245 & 8241 processors.01k,25mar02,pcs Add recognition of MPC745001j,25jan02,mil Fixed diab build error on lwbrx.01i,22jan02,pcs Merge from Tor2.101h,20dec01,kab Fix for diab01g,31oct01,pcs Add support for 745001f,17may01,pch Add 7410 errata fix from sysALib.s01e,08may01,pch Add assembler abstractions (FUNC_EXPORT, FUNC_BEGIN, etc.)01d,07may01,pch Adjust cold-boot code along the lines of Motorola's DINK32 startup to fix power-on flakiness; rearrange code near label I_CACHE_ON_603 so that instructions which are supposed to be consecutive really are; increase delay loops; remove unused labels; add comments.01c,11apr01,mil Added detection for 741001b,12sep00,ksn added support for SP755 and SP7400 (teamF1)01a,10oct99,mtl written from SPS/Motorola & yk 750 by teamF1*//*DESCRIPTIONThis module contains the entry code for VxWorks images that startrunning from ROM, such as 'bootrom' and 'vxWorks_rom'.The entry point, romInit(), is the first code executed on power-up.It performs the minimal setup needed to callthe generic C routine romStart() with parameter BOOT_COLD.RomInit() typically masks interrupts in the processor, sets the initialstack pointer (to STACK_ADRS which is defined in configAll.h), andreadies system memory by configuring the DRAM controller if necessary.Other hardware and device initialization is performed later in theBSP's sysHwInit() routine.A second entry point in romInit.s is called romInitWarm(). It is calledby sysToMonitor() in sysLib.c to perform a warm boot.The warm-start entry point must be written to allow a parameter onthe stack to be passed to romStart().WARNING:This code must be Position Independent Code (PIC). This means that itshould not contain any absolute address references. If an absolute addressmust be used, it must be relocated by the macro ROM_ADRS(x). This macrowill convert the absolute reference to the appropriate address withinROM space no matter how the boot code was linked. (For PPC, ROM_ADRS doesnot work. You must subtract _romInit and add ROM_TEXT_ADRS to eachabsolute address). (NOTE: ROM_ADRS(x) macro does not work for currentPPC compiler).This code should not call out to subroutines declared in other modules,specifically sysLib.o, and sysALib.o. If an outside module is absolutelynecessary, it can be linked into the system by adding the moduleto the makefile variable BOOT_EXTRA. If the same module is referenced byother BSP code, then that module must be added to MACH_EXTRA as well.Note that some C compilers can generate code with absolute addresses.Such code should not be called from this module. If absolute addressescannot be avoided, then only ROM resident code can be generated from thismodule. Compressed and uncompressed bootroms or VxWorks images will notwork if absolute addresses are not processed by the macro ROM_ADRS.WARNING:The most common mistake in BSP development is to attempt to do too muchin romInit.s. This is not the main hardware initialization routine.Only do enough device initialization to get memory functioning. All otherdevice setup should be done in sysLib.c, as part of sysHwInit().Unlike other RTOS systems, VxWorks does not use a single linear deviceinitialization phase. It is common for inexperienced BSP writers to takea BSP from another RTOS, extract the assembly language hardware setupcode and try to paste it into this file. Because VxWorks provides 3different memory configurations, compressed, uncompressed, and rom-resident,this strategy will usually not work successfully.WARNING:The second most common mistake made by BSP writers is to assume thathardware or CPU setup functions done by romInit.o do not need to berepeated in sysALib.s or sysLib.c. A vxWorks image needs only the followingfrom a boot program: The startType code, and the boot parameters stringin memory. Each VxWorks image will completely reset the CPU and allhardware upon startup. The image should not rely on the boot program toinitialize any part of the system (it may assume that the memory controlleris initialized).This means that all initialization done by romInit.s must be repeated ineither sysALib.s or sysLib.c. The only exception here could be thememory controller. However, in most cases even that can bereinitialized without harm.Failure to follow this rule may require users to rebuild bootrom's forminor changes in configuration. It is WRS policy that bootroms and vxWorksimages should not be linked in this manner.INCLUDE FILES: mpc107.h*//* includes */#define _ASMLANGUAGE#include "vxWorks.h"#include "sysLib.h"#include "asm.h"#include "regs.h"#include "config.h"#include "mpc107.h"/* defines *//* * Some releases of h/arch/ppc/toolPpc.h had a bad definition of * LOADPTR. So we will define it correctly. [REMOVE WHEN NO LONGER NEEDED]. * This is tracked at WRS under SPR#20104. * LOADPTR initializes a register with a 32 bit constant, presumably the * address of something. */#undef LOADPTR#define LOADPTR(reg,const32) \ addis reg,r0,HIADJ(const32); addi reg,reg,LO(const32)/* * LOADVAR initializes a register with the contents of a specified memory * address. The difference being that the value loaded is the contents of * the memory location and not just the address of it. [REMOVE WHEN NO LONGER * NEEDED]. * This is tracked at WRS under SPR#20104. */#undef LOADVAR#define LOADVAR(reg,addr32) \ addis reg,r0,HIADJ(addr32); lwz reg,LO(addr32)(reg)/* * NOTE: Cannot use ROM_ADRS macro with HIADJ and LO macro * functions, for PPC */ /* Exported internal functions */ .data FUNC_EXPORT(_romInit) /* start of system code */ FUNC_EXPORT(romInit) /* start of system code */ FUNC_EXPORT(_romInitWarm) /* start of system code */ FUNC_EXPORT(romInitWarm) /* start of system code */ /* externals */ FUNC_IMPORT(romStart) /* system initialization routine */ _WRS_TEXT_SEG_START/******************************************************************************** romInit - entry point for VxWorks in ROM** romInit* (* int startType /@ only used by 2nd entry point @/* )*/ /* * After reset, the processor fetches from ROM_BASE_ADRS + 0x100. * We offset the _romInit entry by 0x100 bytes to compensate. * In other WRS PPC BSP's, this offset was accounted for in the * elfHex stage of building the rom image by setting HEX_FLAGS * to "-a 100". Explictly adding the space here seems more * straitforward, and it also helps when not using elfToHex * such as in a flash programmed binary image. Therefore * the Yellowknife BSP Makefile uses HEX_FLAGS of "-a 0". * This also means that ROM_TEXT_ADRS must be defined * equivalent to ROM_BASE_ADRS + 0x100 in config.h and Makefile. */ .space (0x100)FUNC_LABEL(_romInit)FUNC_BEGIN(romInit) /* This is the cold boot entry (ROM_TEXT_ADRS) */ /* * According to a comment in the DINK32 startup code, a 7400 * erratum requires an isync to be the first instruction executed * here. The isync plus the branch amount to 8 bytes, so omit the * nop which would otherwise follow the branch. */ isync bl cold /* * This warm boot entry point is defined as ROM_WARM_ADRS in config.h. * It is defined as an offset from ROM_TEXT_ADRS. Please make sure * that the offset from _romInit to romInitWarm matches that specified * in config.h. (WRS is standardizing this offset to 8 bytes.) */_romInitWarm:romInitWarm: /* * See above comment regarding a 7400 erratum. Since DINK32 * uses a common entry point for both cold and warm boot, it's * not clear which one requires the isync. isync is harmless, * so do it both places to be safe. */ isync bl warm /* * copyright notice appears at beginning of ROM (in TEXT segment) * This is also useful for debugging images. */ .ascii "Copyright 1984-1999 Wind River Systems, Inc." .align 2cold: li r11, BOOT_COLD bl start /* skip over next instruction */warm: or r11, r3, r3 /* startType to r11 */start: /* * DINK32 does a sync after the isync. It may or may not * be necessary, but should at least be harmless. */ sync /* Zero-out the CPU's registers */ xor r0,r0,0 /* DINK32 uses xor instead of addis */ mtspr SPRG0,r0 mtspr SPRG1,r0 mtspr SPRG2,r0 mtspr SPRG3,r0 /* initialize the stack pointer */ LOADPTR (sp, STACK_ADRS) /* Set MPU/MSR to a known state. Turn on FP */ LOADPTR (r3, _PPC_MSR_FP) sync mtmsr r3 isync sync /* DINK32 does both isync and sync after mtmsr */ /* Init the floating point control/status register */ mtfsfi 7,0x0 mtfsfi 6,0x0 mtfsfi 5,0x0 mtfsfi 4,0x0 mtfsfi 3,0x0 mtfsfi 2,0x0 mtfsfi 1,0x0 mtfsfi 0,0x0 isync /* Initialize the floating point data regsiters to a known state */ bl ifpdr_value .long 0x3f800000 /* 1.0 */ifpdr_value: mfspr r3,LR lfs f0,0(r3) lfs f1,0(r3) lfs f2,0(r3) lfs f3,0(r3) lfs f4,0(r3) lfs f5,0(r3) lfs f6,0(r3) lfs f7,0(r3) lfs f8,0(r3) lfs f9,0(r3) lfs f10,0(r3) lfs f11,0(r3) lfs f12,0(r3) lfs f13,0(r3) lfs f14,0(r3) lfs f15,0(r3) lfs f16,0(r3) lfs f17,0(r3) lfs f18,0(r3) lfs f19,0(r3) lfs f20,0(r3) lfs f21,0(r3) lfs f22,0(r3) lfs f23,0(r3) lfs f24,0(r3) lfs f25,0(r3) lfs f26,0(r3) lfs f27,0(r3) lfs f28,0(r3) lfs f29,0(r3) lfs f30,0(r3) lfs f31,0(r3) sync /* Set MPU/MSR to a known state. Turn off FP */ andi. r3, r3, 0 sync mtmsr r3 isync sync /* DINK32 does both isync and sync after mtmsr */ /* Init the Segment registers */ andi. r3, r3, 0 isync mtsr 0,r3 isync mtsr 1,r3 isync mtsr 2,r3 isync mtsr 3,r3 isync mtsr 4,r3 isync mtsr 5,r3 isync mtsr 6,r3 isync mtsr 7,r3 isync mtsr 8,r3 isync mtsr 9,r3 isync mtsr 10,r3 isync mtsr 11,r3 isync mtsr 12,r3 isync mtsr 13,r3 isync mtsr 14,r3 isync mtsr 15,r3 isync /* Turn off data and instruction cache control bits */ mfspr r3, HID0 isync rlwinm r4, r3, 0, 18, 15 /* r4 has ICE and DCE bits cleared */ sync isync mtspr HID0, r4 /* HID0 = r4 */ isync /* Get cpu type */ mfspr r28, PVR rlwinm r28, r28, 16, 16, 31 /* invalidate the MPU's data/instruction caches */ lis r3, 0x0 cmpli 0, 0, r28, CPU_TYPE_750 beq CPU_IS_750 cmpli 0, 0, r28, CPU_TYPE_7400 beq CPU_IS_750 cmpli 0, 0, r28, CPU_TYPE_7410 beq CPU_IS_7410 cmpli 0, 0, r28, CPU_TYPE_7450 beq CPU_IS_7450 cmpli 0, 0, r28, CPU_TYPE_7455 beq CPU_IS_7450 cmpli 0, 0, r28, CPU_TYPE_603 beq CPU_IS_603 cmpli 0, 0, r28, CPU_TYPE_603E beq CPU_IS_603 cmpli 0, 0, r28, CPU_TYPE_603P beq CPU_IS_603 cmpli 0, 0, r28, CPU_TYPE_604R bne CPU_NOT_604R /* CPU is 604R */ isync /* isync before changing cache enables */ mtspr HID0, r3 /* disable the caches */ isync ori r4, r4, 0x0002 /* disable BTAC by setting bit 30 */CPU_NOT_604R: /* Unrecognized CPU types jump here, and 604R falls in */ ori r3, r3, (_PPC_HID0_ICFI | _PPC_HID0_DCFI)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -