kernel/eka/nkernsmp/arm/nccpu.cpp
changeset 43 96e5fb8b040d
child 90 947f0dc9f7a8
child 256 c1f20ce4abcf
equal deleted inserted replaced
-1:000000000000 43:96e5fb8b040d
       
     1 // Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of the License "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 // e32\nkernsmp\arm\nccpu.cpp
       
    15 // 
       
    16 //
       
    17 
       
    18 #include <arm.h>
       
    19 #include <arm_gic.h>
       
    20 #include <arm_scu.h>
       
    21 #include <arm_tmr.h>
       
    22 
       
    23 extern "C" {
       
    24 extern SVariantInterfaceBlock* VIB;
       
    25 }
       
    26 
       
    27 struct SAPBootPage : public SFullArmRegSet
       
    28 	{
       
    29 	volatile T_UintPtr	iAPBootPtr[KMaxCpus];
       
    30 	volatile T_UintPtr	iBootFlags;
       
    31 	volatile T_UintPtr	iBootFlags2;
       
    32 	volatile T_UintPtr	iBootFlags3;
       
    33 	volatile T_UintPtr	iBootFlags4;
       
    34 	volatile TUint64	iBPTimestamp;
       
    35 	volatile TUint64	iAPTimestamp;
       
    36 	};
       
    37 
       
    38 extern "C" void _ApEntry();
       
    39 extern "C" void KickCpu(volatile T_UintPtr* aPtr, T_UintPtr aRegsPhys);
       
    40 extern void DumpFullRegSet(SFullArmRegSet& a);
       
    41 
       
    42 TInt NKern::BootAP(volatile SAPBootInfo* aInfo)
       
    43 	{
       
    44 	volatile SArmAPBootInfo& a = *(volatile SArmAPBootInfo*)aInfo;
       
    45 	__KTRACE_OPT(KBOOT,DEBUGPRINT("NKern::BootAP %d %08x+%x", a.iCpu, a.iInitStackBase, a.iInitStackSize));
       
    46 
       
    47 	T_UintPtr bp_phys = a.iAPBootPhys;
       
    48 	T_UintPtr BootFlagsPhys = bp_phys + (T_UintPtr)_FOFF(SAPBootPage,iBootFlags);
       
    49 	volatile SAPBootPage& bootPage = *(volatile SAPBootPage*)a.iAPBootLin;
       
    50 	Arm::SaveState((SFullArmRegSet&)bootPage);
       
    51 	NKern::EnableAllInterrupts();	// Arm::SaveState() disables interrupts
       
    52 
       
    53 	TLinAddr BootFlagsLin = (TLinAddr)&bootPage.iBootFlags;
       
    54 	TLinAddr init_sp = a.iInitStackBase + a.iInitStackSize;
       
    55 
       
    56 	volatile T_UintPtr* pB = (volatile T_UintPtr*)BootFlagsLin;
       
    57 	*pB = 0;
       
    58 	pB[1] = 0;
       
    59 	pB[2] = 0;
       
    60 	pB[3] = 0;
       
    61 
       
    62 	__KTRACE_OPT(KBOOT,DEBUGPRINT("BootFlagsPhys=%08x BootFlagsLin=%08x RegsPhys=%08x RegsLin=%08x",
       
    63 		BootFlagsPhys, BootFlagsLin, bp_phys, &bootPage));
       
    64 	__KTRACE_OPT(KBOOT,DEBUGPRINT("SCU: iCtrl=%08x iConfig=%08x iCpuStat=%08x", SCU.iCtrl, SCU.iConfig, SCU.iCpuStatus));
       
    65 
       
    66 	bootPage.iN.iR13Abt		= a.iInitR13Abt;
       
    67 	bootPage.iN.iR13Und		= a.iInitR13Und;
       
    68 	bootPage.iN.iR13Irq		= a.iInitR13Irq;
       
    69 	bootPage.iN.iR13Fiq		= a.iInitR13Fiq;
       
    70 	bootPage.iN.iR13Svc		= init_sp;
       
    71 	bootPage.iN.iFlags		= 0x1D3;
       
    72 	bootPage.iN.iR1			= (TUint32)a.iAPBootPageDirPhys;
       
    73 	bootPage.iN.iR2			= TUint32(a.iAPBootCodeLin) - TUint32(a.iAPBootCodePhys);
       
    74 	bootPage.iN.iR3			= (TUint32)a.iAPBootLin;
       
    75 	bootPage.iN.iR4			= (TUint32)aInfo;
       
    76 	bootPage.iN.iR5			= BootFlagsPhys;
       
    77 	bootPage.iN.iR6			= BootFlagsLin;
       
    78 	bootPage.iN.iR7			= a.iInitStackSize;
       
    79 	bootPage.iN.iR15		= (TLinAddr)&_ApEntry;
       
    80 	bootPage.iB[0].iRWRWTID	= 0;
       
    81 	bootPage.iB[0].iRWROTID	= 0;
       
    82 	bootPage.iB[0].iRWNOTID	= 0;
       
    83 
       
    84 	__KTRACE_OPT(KBOOT,DumpFullRegSet((SFullArmRegSet&)bootPage));
       
    85 
       
    86 	arm_dsb();	// ensure writes to uncached memory visible
       
    87 
       
    88 	KickCpu(&bootPage.iAPBootPtr[a.iCpu], bp_phys);
       
    89 
       
    90 	TUint32 n = TUint32(VIB->iMaxCpuClock >> 3);
       
    91 	n = -n;
       
    92 	TUint32 b = 0;
       
    93 	do	{
       
    94 		++n;
       
    95 		b = *pB;
       
    96 		} while(b!=init_sp && n!=0);
       
    97 	arm_dsb();
       
    98 
       
    99 	__KTRACE_OPT(KBOOT,DEBUGPRINT("BootFlag=%08x %08x %08x %08x n=%d", b, n, pB[1], pB[2], pB[3]));
       
   100 	__KTRACE_OPT(KBOOT,DEBUGPRINT("SCU: iCtrl=%08x iConfig=%08x iCpuStat=%08x", SCU.iCtrl, SCU.iConfig, SCU.iCpuStatus));
       
   101 	if (n==0)
       
   102 		return KErrTimedOut;
       
   103 	NKern::DisableAllInterrupts();
       
   104 	arm_dsb();
       
   105 	while (bootPage.iBootFlags2==0)
       
   106 		{}
       
   107 	arm_dsb();
       
   108 	bootPage.iBootFlags2 = 2;
       
   109 	arm_dsb();
       
   110 	bootPage.iBPTimestamp = NKern::Timestamp();
       
   111 	arm_dsb();
       
   112 	while (bootPage.iBootFlags2==2)
       
   113 		{}
       
   114 	arm_dsb();
       
   115 	NKern::EnableAllInterrupts();
       
   116 	return KErrNone;
       
   117 	}
       
   118 
       
   119 void InitAPTimestamp(SNThreadCreateInfo& aInfo)
       
   120 	{
       
   121 	volatile SArmAPBootInfo& a = *(volatile SArmAPBootInfo*)aInfo.iParameterBlock;
       
   122 	volatile SAPBootPage& bootPage = *(volatile SAPBootPage*)a.iAPBootLin;
       
   123 	NKern::DisableAllInterrupts();
       
   124 	bootPage.iBootFlags2 = 1;
       
   125 	arm_dsb();
       
   126 	while (bootPage.iBootFlags2==1)
       
   127 		{}
       
   128 	arm_dsb();
       
   129 	bootPage.iAPTimestamp = NKern::Timestamp();
       
   130 	arm_dsb();
       
   131 	TUint64 bpt = bootPage.iBPTimestamp;
       
   132 	TUint64 apt = bootPage.iAPTimestamp;
       
   133 	TUint64 delta = bpt - apt;
       
   134 	SubScheduler().iLastTimestamp64 += delta;
       
   135 	__KTRACE_OPT(KBOOT,DEBUGPRINT("APT=0x%lx BPT=0x%lx Delta=0x%lx", apt, bpt, delta));
       
   136 	arm_dsb();
       
   137 	bootPage.iBootFlags2 = 3;
       
   138 	NKern::EnableAllInterrupts();
       
   139 	}
       
   140