📄 sb1250_altcpu.s
字号:
/* ********************************************************************* * Broadcom Common Firmware Environment (CFE) * * CPU init module File: sb1250_altcpu.S * * Secondary core startup routines 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"#ifdef _CFE_#include "cfe_devfuncs.h"#else#define CFE_EPTSEAL 0x43464531#endif#include "sb1250_defs.h"#include "sb1250_regs.h"#include "sb1250_scd.h"#include "cpu_config.h"/* ********************************************************************* * Macros ********************************************************************* */#include "mipsmacros.h"#define SETLEDS1(a,b,c,d) \ li a0,(((a)<<24)|((b)<<16)|((c)<<8)|(d)) ; \ JAL_KSEG1(board_setleds)#define SETLEDS(a,b,c,d) \ li a0,(((a)<<24)|((b)<<16)|((c)<<8)|(d)) ; \ JAL(board_setleds)/* ********************************************************************* * Initialized Data ********************************************************************* */ .sdata/* * Initial start addresses for secondary CPUs */ .globl cpu_startvectorscpu_startvectors: _VECT_ 0 # cpu #0 (not used) _VECT_ 0 # cpu #1 _VECT_ 0 # cpu #2 _VECT_ 0 # cpu #3/* * Initial values for SP, GP, and A1 (user argument) */cpu_start_spvals: _VECT_ 0 # cpu #0 (not used) _VECT_ 0 # cpu #1 _VECT_ 0 # cpu #2 _VECT_ 0 # cpu #3cpu_start_gpvals: _VECT_ 0 # cpu #0 (not used) _VECT_ 0 # cpu #1 _VECT_ 0 # cpu #2 _VECT_ 0 # cpu #3cpu_start_args: _VECT_ 0 # cpu #0 (not used) _VECT_ 0 # cpu #1 _VECT_ 0 # cpu #2 _VECT_ 0 # cpu #3 .extern mem_datareloc/* ********************************************************************* * Linkage Tables * * This table contains pointers to routines in other modules. * we do things this way so we can stay position-independent and * also avoid problems with the limitations of relative branching. ********************************************************************* */ .text .set mips64/* ********************************************************************* * ALTCPU_KSEG1_SWITCH * * Hack the return address so we will come back in KSEG1 (uncached) * * Input parameters: * nothing * * Return value: * nothing ********************************************************************* */altcpu_kseg1_switch: and ra,(K0SIZE-1) or ra,K1BASE jr ra/* ********************************************************************* * ALTCPU_KSEG0_SWITCH * * Hack the return address so we will come back in KSEG0 * * Input parameters: * nothing * * Return value: * nothing ********************************************************************* */altcpu_kseg0_switch: and ra,(K0SIZE-1) or ra,K0BASE jr ra/* ********************************************************************* * SB1250_ALTCPU_START1 * * Start secondary processor(s). These processors will start * running the code at ALTCPU_RESET (see below). We wait here * for the secondary processor(s) to finish their cache * initialization and then return. * * This routine is normally run from KSEG1 * * Input parameters: * nothing * * Return value: * nothing ********************************************************************* */LEAF(sb1250_altcpu_start1) /* * Don't do this if we have only one CPU. This way we can * support running the multiprocessor version of CFE * with only one core. */sb1250_altcpu_start1a: la t0,PHYS_TO_K1(A_SCD_SYSTEM_REVISION) ld t0,(t0) # Get system revision dsrl t0,S_SYS_PART # Shift part # to low bits dsrl t0,8 # isolate CPU part of number and t0,0x0F # T0 = number of CPUs bgt t0,1,1f # Keep going if more than one CPU j ra # Go back home, nothing to do1: /* * Clear out our mailbox registers (both CPUs) */ la a0,PHYS_TO_K1(A_IMR_REGISTER(0,R_IMR_MAILBOX_CLR_CPU)) dli t0,-1 # clear all 64 bits sd t0,(a0) la a0,PHYS_TO_K1(A_IMR_REGISTER(1,R_IMR_MAILBOX_CLR_CPU)) sd t0,(a0) /* * Let the secondary CPU(s) out of reset * * XXX This is very SB1250-specific at the moment. */ la a0,PHYS_TO_K1(A_SCD_SYSTEM_CFG) ld t0,0(a0) dli t1,M_SYS_CPU_RESET_1 # Reset mask not t1 # clear this bit and t0,t1 # New value to write sd t0,0(a0) # CPU1 is now running /* * Wait for the other CPU to ring our doorbell */1: la a0,PHYS_TO_K1(A_IMR_REGISTER(0,R_IMR_MAILBOX_CPU)); ld t0,(a0) # Read mailbox beq t0,zero,1b # Loop till the bit is set /* * Clear the mailbox to dismiss the pending interrupts */ la a0,PHYS_TO_K1(A_IMR_REGISTER(0,R_IMR_MAILBOX_CLR_CPU)) dli t0,-1 # clear all 64 bits sd t0,(a0) /* * Okay, it's safe to return */ j raEND(sb1250_altcpu_start1)/* ********************************************************************* * SB1250_ALTCPU_START2 * * Finish startup of secondary processor(s) - we pass the relocation * offset to the other CPUs here, and the CPUs relocate their * data segments and go to the idle loop. * * This routine is normally run from KSEG0 * * Input parameters: * a0 - data relocation offset (0=none) * * Return value: * nothing ********************************************************************* */LEAF(sb1250_altcpu_start2) /* * Don't do this if we have only one CPU. */ la t0,PHYS_TO_K1(A_SCD_SYSTEM_REVISION) ld t0,(t0) # Get system revision dsrl t0,S_SYS_PART # Shift part # to low bits dsrl t0,8 # isolate CPU part of number and t0,0x0F # T0 = number of CPUs bgt t0,1,1f # Keep going if more than one CPU j ra # Go back home, nothing to do1: /* * Let secondary CPU(s) run their idle loops. Set the * mailbox register to our relocation factor so we can read * it out of the mailbox register and relocate GP properly. */ la t1,PHYS_TO_K1(A_IMR_REGISTER(1,R_IMR_MAILBOX_SET_CPU)) or t0,a0,1 # hack - make sure reloc is nonzero sd t0,0(t1) # Write to mailbox register j ra END(sb1250_altcpu_start2)/* ********************************************************************* * SB1250_ALTCPU_KILL * * Kill a secondary CPU, causing it to return to the idle * loop. We do this by switching to uncached mode, * asserting RESET on the other CPU, and then re-run * ALTCPU_START again. * * Input parameters: * nothing * * Return value: * nothing ********************************************************************* */LEAF(sb1250_altcpu_kill) /* * Don't do this if we have only one CPU. */ la t0,PHYS_TO_K1(A_SCD_SYSTEM_REVISION) ld t0,(t0) # Get system revision dsrl t0,S_SYS_PART # Shift part # to low bits dsrl t0,8 # isolate CPU part of number and t0,0x0F # T0 = number of CPUs bgt t0,1,1f # Keep going if more than one CPU j ra # Go back home, nothing to do1: /* * More than one CPU, go ahead... */ move t7,ra # save RA, we'll make calls#ifdef _SB1250_PASS1_WORKAROUNDS_ # # Not sure what we need to do here wrt cacheability of # the genbus space, if anything. Some portion of CPU1's # istream will come from L1, but the data should all be from # DRAM. These references will be cacheable noncoherent, # should we worry if cpu0 is coherent shared at this time? # probably. ##endif # # XXX For now, this only works on dual-CPU machines. # XXX some work needs to be done to handle more than 2 cores. # move t0,zero # zero the start address la t1,cpu_startvectors SR t0,REGSIZE(t1) # Reset address of CPU1 # # Flush the D cache to ensure that the write above made it # out of our L1. # JAL(sb1250_l1cache_flush_d) # uses t0, t2, t3 # # Switch to KSEG1 to quiesce our cache activity. # bal altcpu_kseg1_switch # switch to uncached mode # # Force CPU1 into reset # li a0,PHYS_TO_K1(A_SCD_SYSTEM_CFG) ld t0,0(a0) dli t1,M_SYS_CPU_RESET_1 # Reset mask or t0,t1 # New value to write sd t0,0(a0) # CPU1 is now in reset # # Not sure how long we're supposed to wait. # ssnop ssnop ssnop ssnop # # Now restart CPU1 # bal sb1250_altcpu_start1a # # It's safe to be cached again. # bal altcpu_kseg0_switch # # At this point, CPU1 is waiting for us to indicate that it's # okay to use memory again. Ring its doorbell.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -