1//
2//  Copyright (c) 2011-2013, ARM Limited. All rights reserved.
3//
4//  This program and the accompanying materials
5//  are licensed and made available under the terms and conditions of the BSD License
6//  which accompanies this distribution.  The full text of the license may be found at
7//  http://opensource.org/licenses/bsd-license.php
8//
9//  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10//  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
11//
12//
13
14#include <AsmMacroIoLib.h>
15#include <Base.h>
16#include <Library/ArmLib.h>
17#include <Library/PcdLib.h>
18
19#include <Chipset/ArmCortexA9.h>
20
21#include <AutoGen.h>
22
23  INCLUDE AsmMacroIoLib.inc
24
25  EXPORT    ArmPlatformPeiBootAction
26  EXPORT    ArmGetCpuCountPerCluster
27  EXPORT    ArmPlatformIsPrimaryCore
28  EXPORT    ArmPlatformGetPrimaryCoreMpId
29  EXPORT    ArmPlatformGetCorePosition
30
31  IMPORT    _gPcd_FixedAtBuild_PcdArmPrimaryCore
32  IMPORT    _gPcd_FixedAtBuild_PcdArmPrimaryCoreMask
33
34  AREA RTSMHelper, CODE, READONLY
35
36ArmPlatformPeiBootAction FUNCTION
37  bx    lr
38  ENDFUNC
39
40// IN None
41// OUT r0 = SCU Base Address
42ArmGetScuBaseAddress FUNCTION
43  // Read Configuration Base Address Register. ArmCBar cannot be called to get
44  // the Configuration BAR as a stack is not necessary setup. The SCU is at the
45  // offset 0x0000 from the Private Memory Region.
46  mrc   p15, 4, r0, c15, c0, 0
47  bx  lr
48  ENDFUNC
49
50//UINTN
51//ArmPlatformGetPrimaryCoreMpId (
52//  VOID
53//  );
54ArmPlatformGetPrimaryCoreMpId FUNCTION
55  LoadConstantToReg (_gPcd_FixedAtBuild_PcdArmPrimaryCore, r0)
56  ldr   r0, [r0]
57  bx    lr
58  ENDFUNC
59
60// IN None
61// OUT r0 = number of cores present in the system
62ArmGetCpuCountPerCluster FUNCTION
63  stmfd SP!, {r1-r2}
64
65  // Read CP15 MIDR
66  mrc   p15, 0, r1, c0, c0, 0
67
68  // Check if the CPU is A15
69  mov   r1, r1, LSR #4
70  mov   r0, #ARM_CPU_TYPE_MASK
71  and   r1, r1, r0
72
73  mov   r0, #ARM_CPU_TYPE_A15
74  cmp   r1, r0
75  beq   _Read_cp15_reg
76
77_CPU_is_not_A15
78  mov   r2, lr                              ; Save link register
79  bl    ArmGetScuBaseAddress                ; Read SCU Base Address
80  mov   lr, r2                              ; Restore link register val
81  ldr   r0, [r0, #A9_SCU_CONFIG_OFFSET]     ; Read SCU Config reg to get CPU count
82  b     _Return
83
84_Read_cp15_reg
85  mrc   p15, 1, r0, c9, c0, 2            ; Read C9 register of CP15 to get CPU count
86  lsr   r0, #24
87
88
89_Return
90  and   r0, r0, #3
91  // Add '1' to the number of CPU on the Cluster
92  add   r0, r0, #1
93  ldmfd SP!, {r1-r2}
94  bx lr
95  ENDFUNC
96
97//UINTN
98//ArmPlatformIsPrimaryCore (
99//  IN UINTN MpId
100//  );
101ArmPlatformIsPrimaryCore FUNCTION
102  LoadConstantToReg (_gPcd_FixedAtBuild_PcdArmPrimaryCoreMask, r1)
103  ldr   r1, [r1]
104  and   r0, r0, r1
105  LoadConstantToReg (_gPcd_FixedAtBuild_PcdArmPrimaryCore, r1)
106  ldr   r1, [r1]
107  cmp   r0, r1
108  moveq r0, #1
109  movne r0, #0
110  bx    lr
111  ENDFUNC
112
113//UINTN
114//ArmPlatformGetCorePosition (
115//  IN UINTN MpId
116//  );
117ArmPlatformGetCorePosition FUNCTION
118  and   r1, r0, #ARM_CORE_MASK
119  and   r0, r0, #ARM_CLUSTER_MASK
120  add   r0, r1, r0, LSR #7
121  bx    lr
122  ENDFUNC
123
124  END
125