1 /** @file
2 *
3 *  Copyright (c) 2011-2015, 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 #ifndef __LINUX_LOADER_H__
16 #define __LINUX_LOADER_H__
17 
18 #include <Library/BdsLib.h>
19 #include <Library/DebugLib.h>
20 #include <Library/HiiLib.h>
21 #include <Library/MemoryAllocationLib.h>
22 #include <Library/PerformanceLib.h>
23 #include <Library/PrintLib.h>
24 #include <Library/ShellLib.h>
25 #include <Library/UefiBootServicesTableLib.h>
26 #include <Library/UefiLib.h>
27 
28 #include <Protocol/EfiShellParameters.h>
29 #include <Protocol/EfiShell.h>
30 
31 #include <libfdt.h>
32 
33 //
34 // Definitions
35 //
36 
37 #define MAX_MSG_LEN 80
38 
39 #define LINUX_UIMAGE_SIGNATURE    0x56190527
40 #define LINUX_KERNEL_MAX_OFFSET   (SystemMemoryBase + PcdGet32(PcdArmLinuxKernelMaxOffset))
41 #define LINUX_ATAG_MAX_OFFSET     (SystemMemoryBase + PcdGet32(PcdArmLinuxAtagMaxOffset))
42 #define LINUX_FDT_MAX_OFFSET      (SystemMemoryBase + PcdGet32(PcdArmLinuxFdtMaxOffset))
43 
44 #define ARM_FDT_MACHINE_TYPE      0xFFFFFFFF
45 
46 // Additional size that could be used for FDT entries added by the UEFI OS Loader
47 // Estimation based on: EDID (300bytes) + bootargs (200bytes) + initrd region (20bytes)
48 //                      + system memory region (20bytes) + mp_core entries (200 bytes)
49 #define FDT_ADDITIONAL_ENTRIES_SIZE     0x300
50 
51 //
52 // Global variables
53 //
54 extern CONST EFI_GUID mLinuxLoaderHiiGuid;
55 extern EFI_HANDLE mLinuxLoaderHiiHandle;
56 
57 //
58 // Local Types
59 //
60 typedef struct _SYSTEM_MEMORY_RESOURCE {
61   LIST_ENTRY                  Link; // This attribute must be the first entry of this structure (to avoid pointer computation)
62   EFI_PHYSICAL_ADDRESS        PhysicalStart;
63   UINT64                      ResourceLength;
64 } SYSTEM_MEMORY_RESOURCE;
65 
66 typedef VOID (*LINUX_KERNEL)(UINT32 Zero, UINT32 Arch, UINTN ParametersBase);
67 
68 //
69 // Functions
70 //
71 EFI_STATUS
72 PrintHii (
73   IN CONST CHAR8          *Language OPTIONAL,
74   IN CONST EFI_STRING_ID  HiiFormatStringId,
75   ...
76   );
77 
78 VOID
79 PrintHelp (
80   IN CONST CHAR8  *Language OPTIONAL
81   );
82 
83 EFI_STATUS
84 ProcessShellParameters (
85   OUT  CHAR16   **KernelPath,
86   OUT  CHAR16   **FdtPath,
87   OUT  CHAR16   **InitrdPath,
88   OUT  CHAR16   **LinuxCommandLine,
89   OUT  UINTN    *AtagMachineType
90   );
91 
92 EFI_STATUS
93 ProcessAppCommandLine (
94   OUT  CHAR16   **KernelTextDevicePath,
95   OUT  CHAR16   **FdtTextDevicePath,
96   OUT  CHAR16   **InitrdTextDevicePath,
97   OUT  CHAR16   **LinuxCommandLine,
98   OUT  UINTN    *AtagMachineType
99   );
100 
101 VOID
102 PrintPerformance (
103   VOID
104   );
105 
106 EFI_STATUS
107 GetSystemMemoryResources (
108   IN  LIST_ENTRY *ResourceList
109   );
110 
111 EFI_STATUS
112 PrepareFdt (
113   IN     EFI_PHYSICAL_ADDRESS SystemMemoryBase,
114   IN     CONST CHAR8*         CommandLineArguments,
115   IN     EFI_PHYSICAL_ADDRESS InitrdImage,
116   IN     UINTN                InitrdImageSize,
117   IN OUT EFI_PHYSICAL_ADDRESS *FdtBlobBase,
118   IN OUT UINTN                *FdtBlobSize
119   );
120 
121 /**
122   Start a Linux kernel from a Device Path
123 
124   @param  SystemMemoryBase      Base of the system memory
125   @param  LinuxKernel           Device Path to the Linux Kernel
126   @param  Parameters            Linux kernel arguments
127   @param  Fdt                   Device Path to the Flat Device Tree
128   @param  MachineType           ARM machine type value
129 
130   @retval EFI_SUCCESS           All drivers have been connected
131   @retval EFI_NOT_FOUND         The Linux kernel Device Path has not been found
132   @retval EFI_OUT_OF_RESOURCES  There is not enough resource memory to store the matching results.
133   @retval RETURN_UNSUPPORTED    ATAG is not support by this architecture
134 
135 **/
136 EFI_STATUS
137 BootLinuxAtag (
138   IN  EFI_PHYSICAL_ADDRESS      SystemMemoryBase,
139   IN  EFI_DEVICE_PATH_PROTOCOL* LinuxKernelDevicePath,
140   IN  EFI_DEVICE_PATH_PROTOCOL* InitrdDevicePath,
141   IN  CONST CHAR8*              CommandLineArguments,
142   IN  UINTN                     MachineType
143   );
144 
145 /**
146   Start a Linux kernel from a Device Path
147 
148   @param[in]  LinuxKernelDevicePath  Device Path to the Linux Kernel
149   @param[in]  InitrdDevicePath       Device Path to the Initrd
150   @param[in]  Arguments              Linux kernel arguments
151 
152   @retval EFI_SUCCESS           All drivers have been connected
153   @retval EFI_NOT_FOUND         The Linux kernel Device Path has not been found
154   @retval EFI_OUT_OF_RESOURCES  There is not enough resource memory to store the matching results.
155 
156 **/
157 EFI_STATUS
158 BootLinuxFdt (
159   IN  EFI_PHYSICAL_ADDRESS      SystemMemoryBase,
160   IN  EFI_DEVICE_PATH_PROTOCOL* LinuxKernelDevicePath,
161   IN  EFI_DEVICE_PATH_PROTOCOL* InitrdDevicePath,
162   IN  EFI_DEVICE_PATH_PROTOCOL* FdtDevicePath,
163   IN  CONST CHAR8*              Arguments
164   );
165 
166 #endif /* __LINUX_LOADER_H__ */
167