3 * Copyright (c) 2011, ARM Limited. All rights reserved.
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
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.
15 #include "BdsInternal.h"
17 // Point to the current ATAG
18 STATIC LINUX_ATAG
*mLinuxKernelCurrentAtag
;
26 mLinuxKernelCurrentAtag
->header
.size
= tag_size(LINUX_ATAG_CORE
);
27 mLinuxKernelCurrentAtag
->header
.type
= ATAG_CORE
;
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 )*/
33 // move pointer to next tag
34 mLinuxKernelCurrentAtag
= next_tag_address(mLinuxKernelCurrentAtag
);
40 IN UINTN StartAddress
,
44 mLinuxKernelCurrentAtag
->header
.size
= tag_size(LINUX_ATAG_MEM
);
45 mLinuxKernelCurrentAtag
->header
.type
= ATAG_MEM
;
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 */
50 // move pointer to next tag
51 mLinuxKernelCurrentAtag
= next_tag_address(mLinuxKernelCurrentAtag
);
57 IN CONST CHAR8
*CmdLine
62 // Increment the line length by 1 to account for the null string terminator character
63 LineLength
= AsciiStrLen(CmdLine
) + 1;
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.
70 mLinuxKernelCurrentAtag
->header
.size
= ((UINT32
)sizeof(LINUX_ATAG_HEADER
) + LineLength
+ (UINT32
)3) >> 2;
71 mLinuxKernelCurrentAtag
->header
.type
= ATAG_CMDLINE
;
73 /* place CommandLine into tag */
74 AsciiStrCpy(mLinuxKernelCurrentAtag
->body
.cmdline_tag
.cmdline
, CmdLine
);
76 // move pointer to next tag
77 mLinuxKernelCurrentAtag
= next_tag_address(mLinuxKernelCurrentAtag
);
87 // Empty tag ends list; this has zero length and no body
88 mLinuxKernelCurrentAtag
->header
.type
= ATAG_NONE
;
89 mLinuxKernelCurrentAtag
->header
.size
= 0;
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).
96 mLinuxKernelCurrentAtag
= (LINUX_ATAG
*)((UINT32
)mLinuxKernelCurrentAtag
+ sizeof(mLinuxKernelCurrentAtag
->header
));
101 IN CONST CHAR8
* CommandLineString
,
102 IN EFI_PHYSICAL_ADDRESS InitrdImage
,
103 IN UINTN InitrdImageSize
,
104 OUT EFI_PHYSICAL_ADDRESS
*AtagBase
,
109 LIST_ENTRY
*ResourceLink
;
110 LIST_ENTRY ResourceList
;
111 EFI_PHYSICAL_ADDRESS AtagStartAddress
;
112 BDS_SYSTEM_MEMORY_RESOURCE
*Resource
;
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
);
122 // Ready to setup the atag list
123 mLinuxKernelCurrentAtag
= (LINUX_ATAG
*)(UINTN
)AtagStartAddress
;
125 // Standard core tag 4k PageSize
126 SetupCoreTag( (UINT32
)SIZE_4KB
);
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
;
138 // CommandLine setting root device
139 if (CommandLineString
) {
140 SetupCmdlineTag (CommandLineString
);
143 if (InitrdImageSize
> 0 && InitrdImage
!= 0) {
144 mLinuxKernelCurrentAtag
->header
.size
= tag_size(LINUX_ATAG_INITRD2
);
145 mLinuxKernelCurrentAtag
->header
.type
= ATAG_INITRD2
;
147 mLinuxKernelCurrentAtag
->body
.initrd2_tag
.start
= (UINT32
)InitrdImage
;
148 mLinuxKernelCurrentAtag
->body
.initrd2_tag
.size
= (UINT32
)InitrdImageSize
;
150 // Move pointer to next tag
151 mLinuxKernelCurrentAtag
= next_tag_address(mLinuxKernelCurrentAtag
);
157 // Calculate atag list size
158 *AtagBase
= AtagStartAddress
;
159 *AtagSize
= (UINT32
)mLinuxKernelCurrentAtag
- (UINT32
)AtagStartAddress
+ 1;