1 /** @file
2 *
3 *  Copyright (c) 2011-2013, ARM Limited. All rights reserved.
4 *
5 *  This program and the accompanying materials
6 *  are licensed and made available under the terms and conditions of the BSD License
7 *  which accompanies this distribution.  The full text of the license may be found at
8 *  http://opensource.org/licenses/bsd-license.php
9 *
10 *  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 *  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
12 *
13 **/
14 
15 #include <Library/IoLib.h>
16 #include <Library/ArmPlatformLib.h>
17 #include <Library/DebugLib.h>
18 #include <Library/PcdLib.h>
19 
20 #include <Ppi/ArmMpCoreInfo.h>
21 
22 #include <ArmPlatform.h>
23 
24 ARM_CORE_INFO mVersatileExpressMpCoreInfoTable[] = {
25   {
26     // Cluster 0, Core 0
27     0x0, 0x0,
28 
29     // MP Core MailBox Set/Get/Clear Addresses and Clear Value
30     (EFI_PHYSICAL_ADDRESS)ARM_VE_SYS_FLAGS_REG,
31     (EFI_PHYSICAL_ADDRESS)ARM_VE_SYS_FLAGS_SET_REG,
32     (EFI_PHYSICAL_ADDRESS)ARM_VE_SYS_FLAGS_CLR_REG,
33     (UINT64)0xFFFFFFFF
34   },
35   {
36     // Cluster 0, Core 1
37     0x0, 0x1,
38 
39     // MP Core MailBox Set/Get/Clear Addresses and Clear Value
40     (EFI_PHYSICAL_ADDRESS)ARM_VE_SYS_FLAGS_REG,
41     (EFI_PHYSICAL_ADDRESS)ARM_VE_SYS_FLAGS_SET_REG,
42     (EFI_PHYSICAL_ADDRESS)ARM_VE_SYS_FLAGS_CLR_REG,
43     (UINT64)0xFFFFFFFF
44   },
45   {
46     // Cluster 0, Core 2
47     0x0, 0x2,
48 
49     // MP Core MailBox Set/Get/Clear Addresses and Clear Value
50     (EFI_PHYSICAL_ADDRESS)ARM_VE_SYS_FLAGS_REG,
51     (EFI_PHYSICAL_ADDRESS)ARM_VE_SYS_FLAGS_SET_REG,
52     (EFI_PHYSICAL_ADDRESS)ARM_VE_SYS_FLAGS_CLR_REG,
53     (UINT64)0xFFFFFFFF
54   },
55   {
56     // Cluster 0, Core 3
57     0x0, 0x3,
58 
59     // MP Core MailBox Set/Get/Clear Addresses and Clear Value
60     (EFI_PHYSICAL_ADDRESS)ARM_VE_SYS_FLAGS_REG,
61     (EFI_PHYSICAL_ADDRESS)ARM_VE_SYS_FLAGS_SET_REG,
62     (EFI_PHYSICAL_ADDRESS)ARM_VE_SYS_FLAGS_CLR_REG,
63     (UINT64)0xFFFFFFFF
64   },
65   {
66     // Cluster 1, Core 0
67     0x1, 0x0,
68 
69     // MP Core MailBox Set/Get/Clear Addresses and Clear Value
70     (EFI_PHYSICAL_ADDRESS)ARM_VE_SYS_FLAGS_REG,
71     (EFI_PHYSICAL_ADDRESS)ARM_VE_SYS_FLAGS_SET_REG,
72     (EFI_PHYSICAL_ADDRESS)ARM_VE_SYS_FLAGS_CLR_REG,
73     (UINT64)0xFFFFFFFF
74   },
75   {
76     // Cluster 1, Core 1
77     0x1, 0x1,
78 
79     // MP Core MailBox Set/Get/Clear Addresses and Clear Value
80     (EFI_PHYSICAL_ADDRESS)ARM_VE_SYS_FLAGS_REG,
81     (EFI_PHYSICAL_ADDRESS)ARM_VE_SYS_FLAGS_SET_REG,
82     (EFI_PHYSICAL_ADDRESS)ARM_VE_SYS_FLAGS_CLR_REG,
83     (UINT64)0xFFFFFFFF
84   },
85   {
86     // Cluster 1, Core 2
87     0x1, 0x2,
88 
89     // MP Core MailBox Set/Get/Clear Addresses and Clear Value
90     (EFI_PHYSICAL_ADDRESS)ARM_VE_SYS_FLAGS_REG,
91     (EFI_PHYSICAL_ADDRESS)ARM_VE_SYS_FLAGS_SET_REG,
92     (EFI_PHYSICAL_ADDRESS)ARM_VE_SYS_FLAGS_CLR_REG,
93     (UINT64)0xFFFFFFFF
94   },
95   {
96     // Cluster 1, Core 3
97     0x1, 0x3,
98 
99     // MP Core MailBox Set/Get/Clear Addresses and Clear Value
100     (EFI_PHYSICAL_ADDRESS)ARM_VE_SYS_FLAGS_REG,
101     (EFI_PHYSICAL_ADDRESS)ARM_VE_SYS_FLAGS_SET_REG,
102     (EFI_PHYSICAL_ADDRESS)ARM_VE_SYS_FLAGS_CLR_REG,
103     (UINT64)0xFFFFFFFF
104   }
105 };
106 
107 /**
108   Return the current Boot Mode
109 
110   This function returns the boot reason on the platform
111 
112   @return   Return the current Boot Mode of the platform
113 
114 **/
115 EFI_BOOT_MODE
ArmPlatformGetBootMode(VOID)116 ArmPlatformGetBootMode (
117   VOID
118   )
119 {
120   return BOOT_WITH_FULL_CONFIGURATION;
121 }
122 
123 /**
124   Initialize controllers that must setup in the normal world
125 
126   This function is called by the ArmPlatformPkg/Pei or ArmPlatformPkg/Pei/PlatformPeim
127   in the PEI phase.
128 
129 **/
130 RETURN_STATUS
ArmPlatformInitialize(IN UINTN MpId)131 ArmPlatformInitialize (
132   IN  UINTN                     MpId
133   )
134 {
135   if (!ArmPlatformIsPrimaryCore (MpId)) {
136     return RETURN_SUCCESS;
137   }
138 
139   // Disable memory remapping and return to normal mapping
140   MmioOr32 (SP810_CTRL_BASE, BIT8);
141 
142   return RETURN_SUCCESS;
143 }
144 
145 /**
146   Initialize the system (or sometimes called permanent) memory
147 
148   This memory is generally represented by the DRAM.
149 
150 **/
151 VOID
ArmPlatformInitializeSystemMemory(VOID)152 ArmPlatformInitializeSystemMemory (
153   VOID
154   )
155 {
156   // Nothing to do here
157 }
158 
159 EFI_STATUS
PrePeiCoreGetMpCoreInfo(OUT UINTN * CoreCount,OUT ARM_CORE_INFO ** ArmCoreTable)160 PrePeiCoreGetMpCoreInfo (
161   OUT UINTN                   *CoreCount,
162   OUT ARM_CORE_INFO           **ArmCoreTable
163   )
164 {
165   UINT32   ProcType;
166 
167   ProcType = MmioRead32 (ARM_VE_SYS_PROCID0_REG) & ARM_VE_SYS_PROC_ID_MASK;
168   if ((ProcType == ARM_VE_SYS_PROC_ID_CORTEX_A9) || (ProcType == ARM_VE_SYS_PROC_ID_CORTEX_A15)) {
169     // Only support one cluster on all but ARMv8 FVP platform. FVP still uses CortexA9 ID.
170     *CoreCount    = ArmGetCpuCountPerCluster ();
171     *ArmCoreTable = mVersatileExpressMpCoreInfoTable;
172     return EFI_SUCCESS;
173   } else {
174     return EFI_UNSUPPORTED;
175   }
176 }
177 
178 ARM_MP_CORE_INFO_PPI mMpCoreInfoPpi = { PrePeiCoreGetMpCoreInfo };
179 
180 EFI_PEI_PPI_DESCRIPTOR      gPlatformPpiTable[] = {
181   {
182     EFI_PEI_PPI_DESCRIPTOR_PPI,
183     &gArmMpCoreInfoPpiGuid,
184     &mMpCoreInfoPpi
185   }
186 };
187 
188 VOID
ArmPlatformGetPlatformPpiList(OUT UINTN * PpiListSize,OUT EFI_PEI_PPI_DESCRIPTOR ** PpiList)189 ArmPlatformGetPlatformPpiList (
190   OUT UINTN                   *PpiListSize,
191   OUT EFI_PEI_PPI_DESCRIPTOR  **PpiList
192   )
193 {
194   *PpiListSize = sizeof(gPlatformPpiTable);
195   *PpiList = gPlatformPpiTable;
196 }
197