/* The physical memory is laid out such that the secondary processor *spincodesitsat0x0000...0x00ff.Onserver,thevectorsfollow *usingthelayoutdescribedinexceptions-64s.S
*/
OPEN_FIXED_SECTION(first_256B, 0x0, 0x100)
USE_FIXED_SECTION(first_256B) /* *Offsetsarerelativefromthestartoffixedsection,and *first_256Bstartsat0.Offsetsareabiteasiertousehere *thanthefixedsectionentrymacros.
*/
. = 0x0
_GLOBAL(__start) /* NOP this out unconditionally */
BEGIN_FTR_SECTION
FIXUP_ENDIAN
b __start_initialization_multiplatform
END_FTR_SECTION(0, 1)
/* Catch branch to 0 in real mode */
trap
/* Secondary processors spin on this value until it becomes non-zero. *Whennon-zero,itcontainstherealaddressofthefunctionthecpu *shouldjumpto.
*/
.balign 8
.globl __secondary_hold_spinloop
__secondary_hold_spinloop:
.8byte 0x0
/* Secondary processors write this value with their cpu # */ /* after they enter the spin loop immediately below. */
.globl __secondary_hold_acknowledge
__secondary_hold_acknowledge:
.8byte 0x0
#ifdef CONFIG_RELOCATABLE /* This flag is set to 1 by a loader if the kernel should run *attheloadedaddressinsteadofthelinkedaddress.This *isusedbykexec-toolstokeepthekdumpkernelinthe *crash_kernelregion.Theloaderisresponsiblefor *observingthealignmentrequirement.
*/
#ifdef CONFIG_RELOCATABLE_TEST
#define RUN_AT_LOAD_DEFAULT 1/* Test relocation, do not copy to 0 */
#else
#define RUN_AT_LOAD_DEFAULT 0x72756e30 /* "run0" -- relocate to 0 by default */
#endif
/* Do not move this variable as kexec-tools knows about it. */
. = 0x5c
.globl __run_at_load
__run_at_load:
DEFINE_FIXED_SYMBOL(__run_at_load, first_256B)
.long RUN_AT_LOAD_DEFAULT
#endif
. = 0x60 /* *Thefollowingcodeisusedtoholdsecondaryprocessors *inaspinloopaftertheyhaveenteredthekernel,but *beforethebulkofthekernelhasbeenrelocated.Thiscode *isrelocatedtophysicaladdress0x60beforeprom_initisrun. *Allofitmustfitbelowthefirstexceptionvectorat0x100. *Use.globlherenot_GLOBALbecausewewant__secondary_hold *tobetheactualtextaddress,notadescriptor.
*/
.globl __secondary_hold
__secondary_hold:
FIXUP_ENDIAN
#ifndef CONFIG_PPC_BOOK3E_64
mfmsr r24
ori r24,r24,MSR_RI
mtmsrd r24 /* RI on */
#endif /* Grab our physical cpu number */
mr r24,r3 /* stash r4 for book3e */
mr r25,r4
/* Tell the master cpu we're here */ /* Relocation is off & we are located at an address less */ /* than 0x100, so only need to grab low order offset. */
std r24,(ABS_ADDR(__secondary_hold_acknowledge, first_256B))(0)
sync
/* All secondary cpus wait here until told to start. */ 100: ld r12,(ABS_ADDR(__secondary_hold_spinloop, first_256B))(0)
cmpdi 0,r12,0
beq 100b
/* start the specified thread */
LOAD_REG_ADDR(r5, DOTSYM(fsl_secondary_thread_init))
bl book3e_start_thread
/* stop the current thread */
mr r3, r8
bl book3e_stop_thread 10:
b 10b 20:
#else /* Now the MMU is off, can branch to our PAGE_OFFSET address */
bcl 20,31,$+4 1: mflr r11
addi r11,r11,(2f - 1b)
tovirt(r11, r11)
mtctr r11
bctr 2:
bl relative_toc
#endif
generic_secondary_common_init: /* Set up a paca value for this processor. Since we have the *physicalcpuidinr24,weneedtosearchthepacastofind *whichlogicalidmapstoourphysicalone.
*/
#ifndef CONFIG_SMP
b kexec_wait /* wait for next kernel if !SMP */
#else
LOAD_REG_ADDR(r8, paca_ptrs) /* Load paca_ptrs pointe */ ld r8,0(r8) /* Get base vaddr of array */
#if (NR_CPUS == 1) || defined(CONFIG_FORCE_NR_CPUS)
LOAD_REG_IMMEDIATE(r7, NR_CPUS)
#else
LOAD_REG_ADDR(r7, nr_cpu_ids) /* Load nr_cpu_ids address */
lwz r7,0(r7) /* also the max paca allocated */
#endif
li r5,0/* logical cpu id */ 1:
sldi r9,r5,3/* get paca_ptrs[] index from cpu id */ ldx r13,r9,r8 /* r13 = paca_ptrs[cpu id] */
lhz r6,PACAHWCPUID(r13) /* Load HW procid from paca */
cmpw r6,r24 /* Compare to our id */
beq 2f
addi r5,r5,1
cmpw r5,r7 /* Check if more pacas exist */
blt 1b
mr r3,r24 /* not found, copy phys to r3 */
b kexec_wait /* next kernel might do better */
2: SET_PACA(r13)
#ifdef CONFIG_PPC_BOOK3E_64
addi r12,r13,PACA_EXTLB /* and TLB exc frame in another */
mtspr SPRN_SPRG_TLB_EXFRAME,r12
#endif
/* From now on, r24 is expected to be logical cpuid */
mr r24,r5
/* Create a temp kernel stack for use before relocation is on. */ ld r1,PACAEMERGSP(r13)
subi r1,r1,STACK_FRAME_MIN_SIZE
/* See if we need to call a cpu state restore handler */
LOAD_REG_ADDR(r23, cur_cpu_spec) ld r23,0(r23) ld r12,CPU_SPEC_RESTORE(r23)
cmpdi 0,r12,0
beq 3f
#ifdef CONFIG_PPC64_ELF_ABI_V1 ld r12,0(r12)
#endif
mtctr r12
bctrl
/* Switch off MMU if not already off */
bl __mmu_off
/* Now the MMU is off, can return to our PAGE_OFFSET address */
tovirt(r25,r25)
mtlr r25
blr
SYM_FUNC_END(start_initialization_book3s)
#endif
/* *Hereisourmainkernelentrypoint.Wesupportcurrently2kindofentries *dependingonthevalueofr5. * *r5!= NULL -> OF entry, we go to prom_init, "legacy" parameter content *inr3...r7 * *r5==NULL->kexecstyleentry.r3isaphysicalpointertothe *DTblock,r4isaphysicalpointertothekernelitself *
*/
__start_initialization_multiplatform: /* Make sure we are running in 64 bits mode */
bl enable_64b_mode
/* Zero r13 (paca) so early program check / mce don't use it */
li r13,0
/* Get TOC pointer (current runtime address) */
bl relative_toc
/* These functions return to the virtual (PAGE_OFFSET) address */
#ifdef CONFIG_PPC_BOOK3E_64
bl start_initialization_book3e
#else
bl start_initialization_book3s
#endif /* CONFIG_PPC_BOOK3E_64 */
/* Get TOC pointer, virtual */
bl relative_toc
/* find out where we are now */
/* OPAL doesn't pass base address in r4, have to derive it. */
bcl 20,31,$+4 0: mflr r26 /* r26 = runtime addr here */
addis r26,r26,(_stext - 0b)@ha
addi r26,r26,(_stext - 0b)@l /* current runtime base addr */
/* find out where we are now */
bcl 20,31,$+4 0: mflr r26 /* r26 = runtime addr here */
addis r26,r26,(_stext - 0b)@ha
addi r26,r26,(_stext - 0b)@l /* current runtime base addr */
/* Do all of the interaction with OF client interface */
mr r8,r26
bl CFUNC(prom_init)
#endif /* #CONFIG_PPC_OF_BOOT_TRAMPOLINE */
/* We never return. We also hit that trap if trying to boot
* from OF while CONFIG_PPC_OF_BOOT_TRAMPOLINE isn't selected */
trap
.previous
__after_prom_start:
#ifdef CONFIG_RELOCATABLE /* process relocations for the final address of the kernel */
lwz r7,(FIXED_SYMBOL_ABS_ADDR(__run_at_load))(r26)
cmplwi cr0,r7,1/* flagged to stay where we are ? */
mr r25,r26 /* then use current kernel base */
beq 1f
LOAD_REG_IMMEDIATE(r25, PAGE_OFFSET) /* else use static kernel base */ 1: mr r3,r25
bl relocate
#if defined(CONFIG_PPC_BOOK3E_64) /* IVPR needs to be set after relocation. */
bl init_core_book3e
#endif
#endif
/* *Weneedtorunwith_stextatphysicaladdressPHYSICAL_START. *Thiswillleavesomecodeinthefirst256Bof *realmemory,whicharereservedforsoftwareuse. * *Note:ThisprocessoverwritestheOFexceptionvectors.
*/
LOAD_REG_IMMEDIATE(r3, PAGE_OFFSET)
mr r4,r26 /* Load the virtual source address into r4 */
cmpld r3,r4 /* Check if source == dest */
beq 9f /* If so skip the copy */
li r6,0x100 /* Start offset, the first 0x100 */ /* bytes were copied earlier. */
#ifdef CONFIG_PPC_BOOK3E_64
LOAD_REG_ADDR(r5, __end_interrupts)
LOAD_REG_ADDR(r11, _stext) sub r5,r5,r11
#else /* just copy interrupts */
LOAD_REG_IMMEDIATE_SYM(r5, r11, FIXED_SYMBOL_ABS_ADDR(__end_interrupts))
#endif
b 5f 3:
#endif /* # bytes of memory to copy */
lis r5,(ABS_ADDR(copy_to_here, text))@ha
addi r5,r5,(ABS_ADDR(copy_to_here, text))@l
bl copy_and_flush /* copy the first n bytes */ /* this includes the code being */ /* executed here. */ /* Jump to the copy of this code that we just made */
addis r8,r3,(ABS_ADDR(4f, text))@ha
addi r12,r8,(ABS_ADDR(4f, text))@l
mtctr r12
bctr
/* *Copyroutineusedtocopythekerneltostartatphysicaladdress0 *andflushandinvalidatethecachesasneeded. *r3=destaddr,r4=sourceaddr,r5=copylimit,r6=startoffset *onexit,r3,r4,r5areunchanged,r6isupdatedtobe>=r5. * *Note:thisroutine*only*clobbersr0,r6andlr
*/
_GLOBAL(copy_and_flush)
addi r5,r5,-8
addi r6,r6,-8 4: li r0,8/* Use the smallest common */ /* denominator cache line */ /* size. This results in */ /* extra cache line flushes */ /* but operation is correct. */ /* Can't get cache line size */ /* from NACA as it is being */ /* moved too. */
mtctr r0 /* put # words/line in ctr */ 3: addi r6,r6,8/* copy a cache line */ ldx r0,r6,r4
stdx r0,r6,r3
bdnz 3b
dcbst r6,r3 /* write it to memory */
sync
icbi r6,r3 /* flush the icache line */
cmpld 0,r6,r5
blt 4b
sync
addi r5,r5,8
addi r6,r6,8
isync
blr
_ASM_NOKPROBE_SYMBOL(copy_and_flush); /* Called in real mode */
.globl __secondary_start_pmac_0
__secondary_start_pmac_0: /* NB the entries for cpus 0, 1, 2 must each occupy 8 bytes. */
li r24,0
b 1f
li r24,1
b 1f
li r24,2
b 1f
li r24,3 1:
_GLOBAL(pmac_secondary_start) /* turn on 64-bit mode */
bl enable_64b_mode
li r0,0
mfspr r3,SPRN_HID4
rldimi r3,r0,40,23/* clear bit 23 (rm_ci) */
sync
mtspr SPRN_HID4,r3
isync
sync
slbia
/* Copy some CPU settings from CPU 0 */
bl __restore_cpu_ppc970
/* pSeries do that early though I don't think we really need it */
mfmsr r3
ori r3,r3,MSR_RI
mtmsrd r3 /* RI on */
/* Set up a paca value for this processor. */
LOAD_REG_ADDR(r4,paca_ptrs) /* Load paca pointer */ ld r4,0(r4) /* Get base vaddr of paca_ptrs array */
sldi r5,r24,3/* get paca_ptrs[] index from cpu id */ ldx r13,r5,r4 /* r13 = paca_ptrs[cpu id] */
SET_PACA(r13) /* Save vaddr of paca in an SPRG*/
/* Mark interrupts soft and hard disabled (they might be enabled *inthePACAwhendoinghotplug)
*/
li r0,IRQS_DISABLED
stb r0,PACAIRQSOFTMASK(r13)
li r0,PACA_IRQ_HARD_DIS
stb r0,PACAIRQHAPPENED(r13)
/* Create a temp kernel stack for use before relocation is on. */ ld r1,PACAEMERGSP(r13)
subi r1,r1,STACK_FRAME_MIN_SIZE
/* Clear backchain so we get nice backtraces */
li r7,0
mtlr r7
/* Mark interrupts soft and hard disabled (they might be enabled *inthePACAwhendoinghotplug)
*/
li r7,IRQS_DISABLED
stb r7,PACAIRQSOFTMASK(r13)
li r0,PACA_IRQ_HARD_DIS
stb r0,PACAIRQHAPPENED(r13)
/* enable MMU and jump to start_secondary */
LOAD_REG_ADDR(r3, start_secondary_prolog)
LOAD_REG_IMMEDIATE(r4, MSR_KERNEL)
/* *Thisiswherethemainkernelcodestarts.
*/
__REF
start_here_multiplatform: /* Adjust TOC for moved kernel. Could adjust when moving it instead. */
bl relative_toc
/* Clear out the BSS. It may have been done in prom_init, *alreadybutthat'sirrelevantsinceprom_initwillsoon *bedetachedfromthekernelcompletely.Besides,weneed *toclearitnowforkexec-styleentry.
*/
LOAD_REG_ADDR(r11,__bss_stop)
LOAD_REG_ADDR(r8,__bss_start) sub r11,r11,r8 /* bss size */
addi r11,r11,7/* round up to an even double word */
srdi. r11,r11,3/* shift right by 3 */
beq 4f
addi r8,r8,-8
li r0,0
mtctr r11 /* zero this many doublewords */ 3: stdu r0,8(r8)
bdnz 3b 4:
#ifndef CONFIG_PPC_BOOK3E_64
mfmsr r6
ori r6,r6,MSR_RI
mtmsrd r6 /* RI on */
#endif
#ifdef CONFIG_RELOCATABLE /* Save the physical address we're running at in kernstart_addr */
LOAD_REG_ADDR(r4, kernstart_addr)
clrldi r0,r25,2
std r0,0(r4)
#endif
/* set up a stack pointer */
LOAD_REG_ADDR(r3,init_thread_union)
LOAD_REG_IMMEDIATE(r1,THREAD_SIZE)
add r1,r3,r1
li r0,0
stdu r0,-STACK_FRAME_MIN_SIZE(r1)
/* This is where all platforms converge execution */
start_here_common: /* relocation is on at this point */
std r1,PACAKSAVE(r13)
/* Load the TOC (virtual address) */
LOAD_PACA_TOC()
/* Mark interrupts soft and hard disabled (they might be enabled *inthePACAwhendoinghotplug)
*/
li r0,IRQS_DISABLED
stb r0,PACAIRQSOFTMASK(r13)
li r0,PACA_IRQ_HARD_DIS
stb r0,PACAIRQHAPPENED(r13)
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.