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