Home | History | Annotate | Download | only in AARCH64
      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 
     23 GCC_ASM_EXPORT(ArmPlatformPeiBootAction)
     24 GCC_ASM_EXPORT(ArmPlatformIsPrimaryCore)
     25 GCC_ASM_EXPORT(ArmPlatformGetPrimaryCoreMpId)
     26 GCC_ASM_EXPORT(ArmPlatformGetCorePosition)
     27 GCC_ASM_EXPORT(ArmGetPhysAddrTop)
     28 
     29 GCC_ASM_IMPORT(_gPcd_FixedAtBuild_PcdArmPrimaryCore)
     30 GCC_ASM_IMPORT(_gPcd_FixedAtBuild_PcdArmPrimaryCoreMask)
     31 GCC_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 //   );
     41 ASM_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 //  );
    110 ASM_PFX(ArmPlatformGetPrimaryCoreMpId):
    111   LoadConstantToReg (_gPcd_FixedAtBuild_PcdArmPrimaryCore, x0)
    112   ldrh   w0, [x0]
    113   ret
    114 
    115 //UINTN
    116 //ArmPlatformIsPrimaryCore (
    117 //  IN UINTN MpId
    118 //  );
    119 ASM_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
    128 ASM_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 //  );
    138 ASM_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 
    156 ASM_FUNCTION_REMOVE_IF_UNREFERENCED
    157