📄 init_mips.s
字号:
/* ********************************************************************* * Broadcom Common Firmware Environment (CFE) * * CPU init module File: init_mips.S * * This module contains the vectors and lowest-level CPU startup * functions for CFE. * * Author: Mitch Lichtenberg * ********************************************************************* * * Copyright 2000,2001,2002,2003 * Broadcom Corporation. All rights reserved. * * This software is furnished under license and may be used and * copied only in accordance with the following terms and * conditions. Subject to these conditions, you may download, * copy, install, use, modify and distribute modified or unmodified * copies of this software in source and/or binary form. No title * or ownership is transferred hereby. * * 1) Any source code used, modified or distributed must reproduce * and retain this copyright notice and list of conditions * as they appear in the source file. * * 2) No right is granted to use any trade name, trademark, or * logo of Broadcom Corporation. The "Broadcom Corporation" * name may not be used to endorse or promote products derived * from this software without the prior written permission of * Broadcom Corporation. * * 3) THIS SOFTWARE IS PROVIDED "AS-IS" AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING BUT NOT LIMITED TO, ANY IMPLIED * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR * PURPOSE, OR NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT * SHALL BROADCOM BE LIABLE FOR ANY DAMAGES WHATSOEVER, AND IN * PARTICULAR, BROADCOM SHALL NOT BE LIABLE FOR 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), EVEN IF ADVISED OF * THE POSSIBILITY OF SUCH DAMAGE. ********************************************************************* */#include "sbmips.h"#include "exception.h"#include "bsp_config.h"#include "cpu_config.h"#ifdef _CFE_#include "cfe_devfuncs.h"#else#if (CFG_BIENDIAN) && defined(__MIPSEB)#define CFE_EPTSEAL_REV 0x31454643#endif#define CFE_EPTSEAL 0x43464531#endif#if CFG_VAPI /* haul in SB1250-specfic stuff only for VAPI */#include "sb1250_defs.h"#ifdef _SB14XX_#include "bcm1480_regs.h"#include "bcm1480_scd.h"#define CHIP_RESET_DEFEAT bcm1480_reset_defeature#define CHIP_MAILBOX_SET_CPU A_BCM1480_IMR_REGISTER(0,R_BCM1480_IMR_MAILBOX_0_SET_CPU)#define CHIP_MAILBOX_CLR_CPU A_BCM1480_IMR_REGISTER(0,R_BCM1480_IMR_MAILBOX_0_CLR_CPU)#define CHIP_MAILBOX_CPU A_BCM1480_IMR_REGISTER(0,R_BCM1480_IMR_MAILBOX_0_CPU)#else#include "sb1250_regs.h"#include "sb1250_scd.h"#define CHIP_RESET_DEFEAT sb1250_reset_defeature#define CHIP_MAILBOX_SET_CPU A_IMR_REGISTER(0,R_IMR_MAILBOX_SET_CPU)#define CHIP_MAILBOX_CLR_CPU A_IMR_REGISTER(0,R_IMR_MAILBOX_CLR_CPU)#define CHIP_MAILBOX_CPU A_IMR_REGISTER(0,R_IMR_MAILBOX_CPU)#endif#endif#include "elf_mips.h"/* ********************************************************************* * Macros ********************************************************************* */#include "mipsmacros.h"/* ********************************************************************* * SETLEDS(a,b,c,d) * SETLEDS1(a,b,c,d) * * Sets the on-board LED display (if present). Two variants * of this routine are provided. If you're running KSEG1, * call the SETLEDS1 variant, else call SETLEDS. * * Input parameters: * a,b,c,d - four ASCII characters (literal constants) * * Return value: * a0,k1,ra trashed ********************************************************************* */#define SETLEDS(a,b,c,d) \ li a0,(((a)<<24)|((b)<<16)|((c)<<8)|(d)) ; \ JAL(board_setleds) ;#define SETLEDS1(a,b,c,d) \ li a0,(((a)<<24)|((b)<<16)|((c)<<8)|(d)) ; \ JAL_KSEG1(board_setleds) ;/* ********************************************************************* * Other constants ********************************************************************* *//* * This is the size of the stack, rounded to KByte boundaries. */#ifndef CFG_STACK_SIZE#error "CFG_STACK_SIZE not defined"#else#define STACK_SIZE ((CFG_STACK_SIZE+1023) & ~1023)#endif/* * Duplicates from cfe_iocb.h -- warning! */#define CFE_CACHE_FLUSH_D 1#define CFE_CACHE_INVAL_I 2#define CFE_CACHE_INVAL_D 4#define CFE_CACHE_INVAL_L2 8#define CFE_CACHE_FLUSH_L2 16#define CFE_CACHE_INVAL_RANGE 32#define CFE_CACHE_FLUSH_RANGE 64/* * To make life easier reading this code, define "KSEGBASE" * to either K0BASE or K1BASE depending on whether we're running * uncached. */#if CFG_RUNFROMKSEG0#define KSEGBASE K0BASE#else#define KSEGBASE K1BASE#endif/* ********************************************************************* * Names of registers used in this module ********************************************************************* */#define RELOCOFFSET s8 /* $30 (fp) */#define TEXTOFFSET t9 /* $25 (t9) */#define MEMTOP t8 /* $24 (t8) */#define TEXTBASE s7 /* $23 (s7) */ .sdata#include "initdata.h" /* declare variables we use here */ .extern _fdata .extern _edata .extern _etext/* ********************************************************************* * uninitialized data ********************************************************************* */ .bss .comm __junk,4/* ********************************************************************* * Exception Vectors ********************************************************************* */ .text .set noreorder/* * If we're building a bi-endian version, this is the base * address that we can expect to find the little-endian version * of the firmware. * * Warning: If you change this, you must also change * the linker script (arch/mips/common/src/cfe_ldscript.template) * and the mkflashimage program (hosttools/mkflashimage.c) */#define BIENDIAN_LE_BASE 0xBFD00000/* * Declare the actual vectors. This expands to code that * must be at the very beginning of the text segment. */DECLARE_VECTOR(0x0000,vec_reset,cpu_reset)DECLARE_VECTOR(0x0200,vec_tlbfill,cpu_tlbfill)DECLARE_XVECTOR(0x0280,vec_xtlbfill,cpu_xtlbfill,XTYPE_XTLBFILL)DECLARE_VECTOR(0x0300,vec_cacheerr,cpu_cacheerr)DECLARE_XVECTOR(0x0380,vec_exception,cpu_exception,XTYPE_EXCEPTION)DECLARE_XVECTOR(0x0400,vec_interrupt,cpu_interrupt,XTYPE_INTERRUPT)DECLARE_XVECTOR(0x0480,vec_ejtag,cpu_ejtag,XTYPE_EJTAG)/* * New location of CFE seal. Will eventually phase out the seal at * offset 0x508 */ .org 0x4E0cfe_seal: .word CFE_EPTSEAL .word CFE_EPTSEAL#if (CFG_BIENDIAN) && defined(__MIPSEB) .org 0x4E8cfe_seal_rev: .word CFE_EPTSEAL_REV .word CFE_EPTSEAL_REV#endif .set reorder/* ********************************************************************* * CFE Entry Point (used by OS boot loaders and such) ********************************************************************* */ .set noreorder#if !defined(_ZIPSTART_)DECLARE_VECTOR(0x0500,vec_apientry,cpu_apientry2)#endif#if !(CFG_BIENDIAN) .org 0x508 .word CFE_EPTSEAL .word CFE_EPTSEAL#endif/* ********************************************************************* * Verification APIs (if present) [SB1250-specific] ********************************************************************* */#if CFG_VAPI#if (CFG_RELOC)#error "CFG_VAPI is not compatible with relocatable code"#endif#include "vapi.h"/* * Vector should be 16 bytes long */#define VAPI_VECTOR(l,x) \ .extern x ; \ .org (l & 0xFFFF) ; \ j x ; \ nop ; \ .word VAPI_EPTSEAL ; \ .word VAPI_EPTSEALVAPI_VECTOR(VAPI_FUNC_EXIT,vapi_exit)VAPI_VECTOR(VAPI_FUNC_DUMPGPRS,vapi_dumpgprs)VAPI_VECTOR(VAPI_FUNC_SETLOG,vapi_setlog)VAPI_VECTOR(VAPI_FUNC_LOGVALUE,vapi_logsingle)VAPI_VECTOR(VAPI_FUNC_LOGDATA,vapi_logdata)VAPI_VECTOR(VAPI_FUNC_LOGTRACE,vapi_logtrace)VAPI_VECTOR(VAPI_FUNC_LOGSOC,vapi_savesoc)VAPI_VECTOR(VAPI_FUNC_LOGGPRS,vapi_loggprs)VAPI_VECTOR(VAPI_FUNC_DUMPSTRING,vapi_puts)VAPI_VECTOR(VAPI_FUNC_SETLEDS,vapi_setleds)VAPI_VECTOR(VAPI_FUNC_LOGFPRS,vapi_logfprs)#endif .set reorder/* ********************************************************************* * Segment Table. * * Addresses of data segments and of certain routines we're going * to call from KSEG1. These are here mostly for the * PIC case, since we can't count on the 'la' instruction to * do the expected thing (the assembler expands it into a macro * for doing GP-relative stuff, and the code is NOT GP-relative. * So, we (relocatably) get the offset of this table and then * index within it. * * Pointer values in this segment will be relative to KSEG0 for * cached versions of CFE, so we need to OR in K1BASE in the * case of calling to a uncached address. ********************************************************************* */#include "segtable.h"#if CFG_VAPI .org 0x600 # move past exception vectors#else .org 0x580 # move past exception vectors#endif .globl segment_tablesegment_table: _LONG_ _etext # [ 0] End of text (R_SEG_ETEXT) _LONG_ _fdata # [ 1] Beginning of data (R_SEG_FDATA) _LONG_ _edata # [ 2] End of data (R_SEG_EDATA) _LONG_ _end # [ 3] End of BSS (R_SEG_END) _LONG_ _ftext # [ 4] Beginning of text (R_SEG_FTEXT) _LONG_ _fbss # [ 5] Beginning of BSS (R_SEG_FBSS)/* ********************************************************************* * CPU API entry (needs to be in this file for the SVR4 PIC build) * Get our GP value from A0 first, then set it back. ********************************************************************* */cpu_apientry2:#if CFG_RELOC move k0,gp move gp,a0 la t9,cpu_apientry # This implicitly uses GP move gp,k0 jr t9#else j cpu_apientry#endif /* ********************************************************************* * CPU Startup Code ********************************************************************* */cpu_reset: /* * SVR4 PIC: Load GP with our nonrelocated value. Make * sure it is in KSEG1 because the caches aren't hot yet. */#if CFG_RELOC lui gp,%hi(_gp) addiu gp,%lo(_gp) or gp,gp,K1BASE#else move gp,zero # start with no GP.#endif#if CFG_VAPI /* * VAPI works by using the SCD to reset just the core. * Look for a special signature in the mailbox register * on CPU0 - if present, jump to the start of the diag. * Of course, you need a real 1250 to do this. */ li k0,PHYS_TO_K1(CHIP_MAILBOX_CPU) ld k0,0(k0) dli k1,VAPI_MAGIC_NUMBER_MC beq k0,k1,vapi_runmc dli k1,VAPI_MAGIC_NUMBER_UNC beq k0,k1,vapi_rununc dli k1,VAPI_MAGIC_NUMBER bne k0,k1,vapi_skip /* * The only CP0 init we do is to set K0 to cacheable */ mfc0 k0,C0_CONFIG # get current CONFIG register srl k0,k0,3 # strip out K0 bits sll k0,k0,3 # k0 bits now zero or k0,k0,K_CFG_K0COH_COHERENT # K0 is cacheable. mtc0 k0,C0_CONFIG /* * Set any required defeature bits (for VAPI diagnostics only) * they get cleared by the soft reset. */ jal CHIP_RESET_DEFEAT /* in sb1250_l1cache.S */ /* * Jump to the diagnostic. Two variants, one for cached * and one for uncached. */ li k0,VAPI_DIAG_ENTRY j k0vapi_rununc: li k0,VAPI_DIAG_ENTRY_UNC j k0vapi_runmc: li k0,VAPI_DIAG_ENTRY_MC j k0vapi_skip:#endif /* * Test the CAUSE and STATUS registers for why we * are here. Cold reset, Warm reset, and NMI all * use this vector. */ /* XXX */ /* * Test to see if we're on the secondary CPU. If so, * go do the initialization for that CPU. */ #if (CFG_MULTI_CPUS) JAL_KSEG1(CPUCFG_ALTCPU_RESET) /* does not return if on CPU1 */#endif#------------------------------------------------------------------------------ /* * Do low-level board initialization. This is our first * chance to customize the startup sequence. */ JAL_KSEG1(board_earlyinit) SETLEDS1('H','E','L','O') JAL_KSEG1(CPUCFG_CPUINIT) /* * Run some diagnostics */#if 0#if !CFG_MINIMAL_SIZE && !defined(_ZIPSTART_) SETLEDS1('T','S','T','1') JAL_KSEG1(CPUCFG_DIAG_TEST1)#endif#endif#------------------------------------------------------------------------------#if CFG_MULTI_CPUS /* * Spin up secondary CPU core(s) */ JAL_KSEG1(CPUCFG_ALTCPU_START1)#endif /* * Now, switch from KSEG1 to KSEG0 */#if CFG_RUNFROMKSEG0 bal cpu_kseg0_switch#endif /* * Now go back to a cacheable version of the GOT */#if CFG_RELOC lui gp,%hi(_gp) addiu gp,%lo(_gp)#endif#------------------------------------------------------------------------------ /* * Now running on cpu0 in K0SEG. */#if CFG_INIT_DRAM SETLEDS('D','R','A','M') JAL(board_draminfo)__DramInit: move a0,v0 # pass these params JAL(CPUCFG_DRAMINIT) move k0,v0 # Save in k0 for now#else li k0,(CFG_DRAM_SIZE * 1024)#if (CFG_DRAM_SIZE == 0) JAL(board_draminfo) # hack escape to board code b have_ram # assume non-DRAM memory#endif#endif#------------------------------------------------------------------------------#if (CFG_BOOTRAM || CFG_L2_RAM) b have_ram # No RAM is ok if using emulator RAM#endif bne k0,zero,have_ram SETLEDS('R','A','M','X') # die here if no ramdie1: b die1have_ram: /* * If this CPU supports 64-bit registers, set STATUS * to allow 64-bit accesses. */#if CPUCFG_REGS64 mfc0 t0,C0_SR or t0,t0,M_SR_KX mtc0 t0,C0_SR#endif#------------------------------------------------------------------------------ /* * K0 contains the RAM size (and therefore the top of RAM * offset). Start there, and subtract the amount of memory * we expect to use. If we have more than 256MB of * physical memory, work backwards from the 256MB * boundary. */ __CalcMemTop: li MEMTOP,256 # 256MB boundary bgt k0,MEMTOP,1f # use 256MB if k0 is greater move MEMTOP,k0 # otherwise keep top1: sll MEMTOP,20 # make into byte amount li RELOCOFFSET,0 # not relocating, no offset li TEXTOFFSET,0 /* * DRAM is now running, and we're alive in cacheable memory * on cpu0 in K0SEG. Set up GP. */#if !CFG_RELOC la gp,_gp add gp,RELOCOFFSET#endif /* * SVR4 PIC support: with the eventual demise of -membedded-pic, * This is the way we do relocations now. CFE as a shareable * library, wahoo! */#if CFG_RELOC#define REG_REL s0#define REG_RELSZ s1#define REG_SYMTAB s2#define REG_PLTGOT s3#define REG_GOTNO s4#define REG_SYMTABNO s5#define REG_GOTSYM s6__CopyCode: SETLEDS('C','O','P','Y') /* * Calculate final location of CFE. MEMTOP is our * top-of-memory address. */ la v0,_ftext la v1,_end sub v0,v1,v0 # v0 = size of text+init+bss add v0,v0,(CFG_HEAP_SIZE*1024)+STACK_SIZE add v0,v0,0xFFF and v0,~0xFFF # round down to 4K byte boundary subu TEXTBASE,MEMTOP,v0 # Start at this physical location#if CFG_RUNFROMKSEG0 or TEXTBASE,K0BASE#else or TEXTBASE,K1BASE#endif /* * TEXTBASE = desired target address
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -