1/** @file
2*
3*  Copyright (c) 2011-2013, ARM Limited. All rights reserved.
4*  Copyright (c) 2014, Linaro Limited. All rights reserved.
5*  Copyright (c) 2014, Red Hat, Inc.
6*
7*
8*  This program and the accompanying materials
9*  are licensed and made available under the terms and conditions of the BSD License
10*  which accompanies this distribution.  The full text of the license may be found at
11*  http://opensource.org/licenses/bsd-license.php
12*
13*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
14*  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
15*
16**/
17
18#include <Library/IoLib.h>
19#include <Library/ArmPlatformLib.h>
20#include <Library/DebugLib.h>
21#include <Library/PcdLib.h>
22#include <ArmPlatform.h>
23#include <libfdt.h>
24#include <Pi/PiBootMode.h>
25#include <Uefi/UefiBaseType.h>
26#include <Uefi/UefiMultiPhase.h>
27
28/**
29  Return the current Boot Mode
30
31  This function returns the boot reason on the platform
32
33  @return   Return the current Boot Mode of the platform
34
35**/
36EFI_BOOT_MODE
37ArmPlatformGetBootMode (
38  VOID
39  )
40{
41  return BOOT_WITH_FULL_CONFIGURATION;
42}
43
44/**
45  This function is called by PrePeiCore, in the SEC phase.
46**/
47RETURN_STATUS
48ArmPlatformInitialize (
49  IN  UINTN                     MpId
50  )
51{
52  //
53  // We are relying on ArmPlatformInitializeSystemMemory () being called from
54  // InitializeMemory (), which only occurs if the following feature is disabled
55  //
56  ASSERT (!FeaturePcdGet (PcdSystemMemoryInitializeInSec));
57  return RETURN_SUCCESS;
58}
59
60/**
61  Initialize the system (or sometimes called permanent) memory
62
63  This memory is generally represented by the DRAM.
64
65  This function is called from InitializeMemory() in MemoryInitPeim, in the PEI
66  phase.
67**/
68VOID
69ArmPlatformInitializeSystemMemory (
70  VOID
71  )
72{
73  VOID         *DeviceTreeBase;
74  INT32        Node, Prev;
75  UINT64       NewBase, CurBase;
76  UINT64       NewSize, CurSize;
77  CONST CHAR8  *Type;
78  INT32        Len;
79  CONST UINT64 *RegProp;
80
81  NewBase = 0;
82  NewSize = 0;
83
84  DeviceTreeBase = (VOID *)(UINTN)PcdGet64 (PcdDeviceTreeInitialBaseAddress);
85  ASSERT (DeviceTreeBase != NULL);
86
87  //
88  // Make sure we have a valid device tree blob
89  //
90  ASSERT (fdt_check_header (DeviceTreeBase) == 0);
91
92  //
93  // Look for the lowest memory node
94  //
95  for (Prev = 0;; Prev = Node) {
96    Node = fdt_next_node (DeviceTreeBase, Prev, NULL);
97    if (Node < 0) {
98      break;
99    }
100
101    //
102    // Check for memory node
103    //
104    Type = fdt_getprop (DeviceTreeBase, Node, "device_type", &Len);
105    if (Type && AsciiStrnCmp (Type, "memory", Len) == 0) {
106      //
107      // Get the 'reg' property of this node. For now, we will assume
108      // two 8 byte quantities for base and size, respectively.
109      //
110      RegProp = fdt_getprop (DeviceTreeBase, Node, "reg", &Len);
111      if (RegProp != 0 && Len == (2 * sizeof (UINT64))) {
112
113        CurBase = fdt64_to_cpu (ReadUnaligned64 (RegProp));
114        CurSize = fdt64_to_cpu (ReadUnaligned64 (RegProp + 1));
115
116        DEBUG ((EFI_D_INFO, "%a: System RAM @ 0x%lx - 0x%lx\n",
117               __FUNCTION__, CurBase, CurBase + CurSize - 1));
118
119        if (NewBase > CurBase || NewBase == 0) {
120          NewBase = CurBase;
121          NewSize = CurSize;
122        }
123      } else {
124        DEBUG ((EFI_D_ERROR, "%a: Failed to parse FDT memory node\n",
125               __FUNCTION__));
126      }
127    }
128  }
129
130  //
131  // Make sure the start of DRAM matches our expectation
132  //
133  ASSERT (FixedPcdGet64 (PcdSystemMemoryBase) == NewBase);
134  PcdSet64 (PcdSystemMemorySize, NewSize);
135
136  //
137  // We need to make sure that the machine we are running on has at least
138  // 128 MB of memory configured, and is currently executing this binary from
139  // NOR flash. This prevents a device tree image in DRAM from getting
140  // clobbered when our caller installs permanent PEI RAM, before we have a
141  // chance of marking its location as reserved or copy it to a freshly
142  // allocated block in the permanent PEI RAM in the platform PEIM.
143  //
144  ASSERT (NewSize >= SIZE_128MB);
145  ASSERT (
146    (((UINT64)PcdGet64 (PcdFdBaseAddress) +
147      (UINT64)PcdGet32 (PcdFdSize)) <= NewBase) ||
148    ((UINT64)PcdGet64 (PcdFdBaseAddress) >= (NewBase + NewSize)));
149}
150
151VOID
152ArmPlatformGetPlatformPpiList (
153  OUT UINTN                   *PpiListSize,
154  OUT EFI_PEI_PPI_DESCRIPTOR  **PpiList
155  )
156{
157  *PpiListSize = 0;
158  *PpiList = NULL;
159}
160