]> git.proxmox.com Git - mirror_edk2.git/blame - ArmPkg/Library/BdsLib/BdsLinuxAtag.c
Update for NetworkPkg.
[mirror_edk2.git] / ArmPkg / Library / BdsLib / BdsLinuxAtag.c
CommitLineData
d9325c8e 1/** @file
2*
3* Copyright (c) 2011, 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#include "BdsInternal.h"
16
17// Point to the current ATAG
18STATIC LINUX_ATAG *mLinuxKernelCurrentAtag;
19
20STATIC
21VOID
22SetupCoreTag (
23 IN UINT32 PageSize
24 )
25{
26 mLinuxKernelCurrentAtag->header.size = tag_size(LINUX_ATAG_CORE);
27 mLinuxKernelCurrentAtag->header.type = ATAG_CORE;
28
29 mLinuxKernelCurrentAtag->body.core_tag.flags = 1; /* ensure read-only */
30 mLinuxKernelCurrentAtag->body.core_tag.pagesize = PageSize; /* systems PageSize (4k) */
31 mLinuxKernelCurrentAtag->body.core_tag.rootdev = 0; /* zero root device (typically overridden from kernel command line )*/
32
33 // move pointer to next tag
34 mLinuxKernelCurrentAtag = next_tag_address(mLinuxKernelCurrentAtag);
35}
36
37STATIC
38VOID
39SetupMemTag (
40 IN UINTN StartAddress,
41 IN UINT32 Size
42 )
43{
44 mLinuxKernelCurrentAtag->header.size = tag_size(LINUX_ATAG_MEM);
45 mLinuxKernelCurrentAtag->header.type = ATAG_MEM;
46
47 mLinuxKernelCurrentAtag->body.mem_tag.start = StartAddress; /* Start of memory chunk for AtagMem */
48 mLinuxKernelCurrentAtag->body.mem_tag.size = Size; /* Size of memory chunk for AtagMem */
49
50 // move pointer to next tag
51 mLinuxKernelCurrentAtag = next_tag_address(mLinuxKernelCurrentAtag);
52}
53
54STATIC
55VOID
56SetupCmdlineTag (
57 IN CONST CHAR8 *CmdLine
58 )
59{
60 UINT32 LineLength;
61
62 // Increment the line length by 1 to account for the null string terminator character
63 LineLength = AsciiStrLen(CmdLine) + 1;
64
65 /* Check for NULL strings.
66 * Do not insert a tag for an empty CommandLine, don't even modify the tag address pointer.
67 * Remember, you have at least one null string terminator character.
68 */
69 if(LineLength > 1) {
70 mLinuxKernelCurrentAtag->header.size = ((UINT32)sizeof(LINUX_ATAG_HEADER) + LineLength + (UINT32)3) >> 2;
71 mLinuxKernelCurrentAtag->header.type = ATAG_CMDLINE;
72
73 /* place CommandLine into tag */
74 AsciiStrCpy(mLinuxKernelCurrentAtag->body.cmdline_tag.cmdline, CmdLine);
75
76 // move pointer to next tag
77 mLinuxKernelCurrentAtag = next_tag_address(mLinuxKernelCurrentAtag);
78 }
79}
80
81STATIC
82VOID
83SetupEndTag (
84 VOID
85 )
86{
87 // Empty tag ends list; this has zero length and no body
88 mLinuxKernelCurrentAtag->header.type = ATAG_NONE;
89 mLinuxKernelCurrentAtag->header.size = 0;
90
91 /* We can not calculate the next address by using the standard macro:
92 * Params = next_tag_address(Params);
93 * because it relies on the header.size, which here it is 0 (zero).
94 * The easiest way is to add the sizeof(mLinuxKernelCurrentAtag->header).
95 */
96 mLinuxKernelCurrentAtag = (LINUX_ATAG*)((UINT32)mLinuxKernelCurrentAtag + sizeof(mLinuxKernelCurrentAtag->header));
97}
98
99EFI_STATUS
100PrepareAtagList (
19a7404a 101 IN CONST CHAR8* CommandLineString,
102 IN EFI_PHYSICAL_ADDRESS InitrdImage,
103 IN UINTN InitrdImageSize,
104 OUT EFI_PHYSICAL_ADDRESS *AtagBase,
105 OUT UINT32 *AtagSize
d9325c8e 106 )
107{
108 EFI_STATUS Status;
109 LIST_ENTRY *ResourceLink;
110 LIST_ENTRY ResourceList;
111 EFI_PHYSICAL_ADDRESS AtagStartAddress;
112 BDS_SYSTEM_MEMORY_RESOURCE *Resource;
113
114 AtagStartAddress = LINUX_ATAG_MAX_OFFSET;
115 Status = gBS->AllocatePages (AllocateMaxAddress, EfiBootServicesData, EFI_SIZE_TO_PAGES(ATAG_MAX_SIZE), &AtagStartAddress);
116 if (EFI_ERROR(Status)) {
117 DEBUG ((EFI_D_ERROR,"Failed to allocate Atag at 0x%lX (%r)\n",AtagStartAddress,Status));
118 Status = gBS->AllocatePages (AllocateAnyPages, EfiBootServicesData, EFI_SIZE_TO_PAGES(ATAG_MAX_SIZE), &AtagStartAddress);
119 ASSERT_EFI_ERROR(Status);
120 }
121
122 // Ready to setup the atag list
123 mLinuxKernelCurrentAtag = (LINUX_ATAG*)(UINTN)AtagStartAddress;
124
125 // Standard core tag 4k PageSize
126 SetupCoreTag( (UINT32)SIZE_4KB );
127
128 // Physical memory setup
129 GetSystemMemoryResources (&ResourceList);
130 ResourceLink = ResourceList.ForwardLink;
131 while (ResourceLink != NULL && ResourceLink != &ResourceList) {
132 Resource = (BDS_SYSTEM_MEMORY_RESOURCE*)ResourceLink;
133 DEBUG((EFI_D_INFO,"- [0x%08X,0x%08X]\n",(UINT32)Resource->PhysicalStart,(UINT32)Resource->PhysicalStart+(UINT32)Resource->ResourceLength));
134 SetupMemTag( (UINT32)Resource->PhysicalStart, (UINT32)Resource->ResourceLength );
135 ResourceLink = ResourceLink->ForwardLink;
136 }
137
138 // CommandLine setting root device
139 if (CommandLineString) {
140 SetupCmdlineTag (CommandLineString);
141 }
142
143 if (InitrdImageSize > 0 && InitrdImage != 0) {
144 mLinuxKernelCurrentAtag->header.size = tag_size(LINUX_ATAG_INITRD2);
145 mLinuxKernelCurrentAtag->header.type = ATAG_INITRD2;
146
147 mLinuxKernelCurrentAtag->body.initrd2_tag.start = (UINT32)InitrdImage;
148 mLinuxKernelCurrentAtag->body.initrd2_tag.size = (UINT32)InitrdImageSize;
149
150 // Move pointer to next tag
151 mLinuxKernelCurrentAtag = next_tag_address(mLinuxKernelCurrentAtag);
152 }
153
154 // End of tags
155 SetupEndTag();
156
157 // Calculate atag list size
19a7404a 158 *AtagBase = AtagStartAddress;
d9325c8e 159 *AtagSize = (UINT32)mLinuxKernelCurrentAtag - (UINT32)AtagStartAddress + 1;
160
161 return EFI_SUCCESS;
162}
163