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 <AsmMacroIoLibV8.h>
15#include <Base.h>
16#include <Library/ArmLib.h>
17#include <Library/PcdLib.h>
18#include <AutoGen.h>
19
20.text
21.align 2
22
23GCC_ASM_EXPORT(ArmPlatformPeiBootAction)
24GCC_ASM_EXPORT(ArmPlatformIsPrimaryCore)
25GCC_ASM_EXPORT(ArmPlatformGetPrimaryCoreMpId)
26GCC_ASM_EXPORT(ArmPlatformGetCorePosition)
27GCC_ASM_EXPORT(ArmGetPhysAddrTop)
28
29GCC_ASM_IMPORT(_gPcd_FixedAtBuild_PcdArmPrimaryCore)
30GCC_ASM_IMPORT(_gPcd_FixedAtBuild_PcdArmPrimaryCoreMask)
31GCC_ASM_IMPORT(_gPcd_FixedAtBuild_PcdCoreCount)
32
33.LArm64LinuxMagic:
34  .byte   0x41, 0x52, 0x4d, 0x64
35
36// VOID
37// ArmPlatformPeiBootAction (
38//   VOID   *DeviceTreeBaseAddress,   // passed by loader in x0
39//   VOID   *ImageBase                // passed by FDF trampoline in x1
40//   );
41ASM_PFX(ArmPlatformPeiBootAction):
42  mov   x29, x30            // preserve LR
43  mov   x28, x0             // preserve DTB pointer
44  mov   x27, x1             // preserve base of image pointer
45
46  //
47  // If we are booting from RAM using the Linux kernel boot protocol, x0 will
48  // point to the DTB image in memory. Otherwise, we are just coming out of
49  // reset, and x0 will be 0.
50  //
51  cbz   x0, .Lout
52
53  //
54  // The base of the runtime image has been preserved in x1. Check whether
55  // the expected magic number can be found in the header.
56  //
57  ldr   w8, .LArm64LinuxMagic
58  ldr   w9, [x1, #0x38]
59  cmp   w8, w9
60  bne   .Lout
61
62  //
63  //
64  // OK, so far so good. We have confirmed that we likely have a DTB and are
65  // booting via the arm64 Linux boot protocol. Update the base-of-image PCD
66  // to the actual relocated value, and add the shift of PcdFdBaseAddress to
67  // PcdFvBaseAddress as well
68  //
69  adr   x8, PcdGet64 (PcdFdBaseAddress)
70  adr   x9, PcdGet64 (PcdFvBaseAddress)
71  ldr   x6, [x8]
72  ldr   x7, [x9]
73  sub   x7, x7, x6
74  add   x7, x7, x1
75  str   x1, [x8]
76  str   x7, [x9]
77
78  //
79  // Discover the memory size and offset from the DTB, and record in the
80  // respective PCDs. This will also return false if a corrupt DTB is
81  // encountered. Since we are calling a C function, use the window at the
82  // beginning of the FD image as a temp stack.
83  //
84  adr   x1, PcdGet64 (PcdSystemMemorySize)
85  adr   x2, PcdGet64 (PcdSystemMemoryBase)
86  mov   sp, x7
87  bl    FindMemnode
88  cbz   x0, .Lout
89
90  //
91  // Copy the DTB to the slack space right after the 64 byte arm64/Linux style
92  // image header at the base of this image (defined in the FDF), and record the
93  // pointer in PcdDeviceTreeInitialBaseAddress.
94  //
95  adr   x8, PcdGet64 (PcdDeviceTreeInitialBaseAddress)
96  add   x27, x27, #0x40
97  str   x27, [x8]
98
99  mov   x0, x27
100  mov   x1, x28
101  bl    CopyFdt
102
103.Lout:
104  ret    x29
105
106//UINTN
107//ArmPlatformGetPrimaryCoreMpId (
108//  VOID
109//  );
110ASM_PFX(ArmPlatformGetPrimaryCoreMpId):
111  LoadConstantToReg (_gPcd_FixedAtBuild_PcdArmPrimaryCore, x0)
112  ldrh   w0, [x0]
113  ret
114
115//UINTN
116//ArmPlatformIsPrimaryCore (
117//  IN UINTN MpId
118//  );
119ASM_PFX(ArmPlatformIsPrimaryCore):
120  mov   x0, #1
121  ret
122
123//UINTN
124//ArmPlatformGetCorePosition (
125//  IN UINTN MpId
126//  );
127// With this function: CorePos = (ClusterId * 4) + CoreId
128ASM_PFX(ArmPlatformGetCorePosition):
129  and   x1, x0, #ARM_CORE_MASK
130  and   x0, x0, #ARM_CLUSTER_MASK
131  add   x0, x1, x0, LSR #6
132  ret
133
134//EFI_PHYSICAL_ADDRESS
135//GetPhysAddrTop (
136//  VOID
137//  );
138ASM_PFX(ArmGetPhysAddrTop):
139  mrs   x0, id_aa64mmfr0_el1
140  adr   x1, .LPARanges
141  and   x0, x0, #7
142  ldrb  w1, [x1, x0]
143  mov   x0, #1
144  lsl   x0, x0, x1
145  ret
146
147//
148// Bits 0..2 of the AA64MFR0_EL1 system register encode the size of the
149// physical address space support on this CPU:
150// 0 == 32 bits, 1 == 36 bits, etc etc
151// 6 and 7 are reserved
152//
153.LPARanges:
154  .byte 32, 36, 40, 42, 44, 48, -1, -1
155
156ASM_FUNCTION_REMOVE_IF_UNREFERENCED
157