1 /*
2  * Copyright 2018 The Hafnium Authors.
3  *
4  * Use of this source code is governed by a BSD-style
5  * license that can be found in the LICENSE file or at
6  * https://opensource.org/licenses/BSD-3-Clause.
7  */
8 
9 #include "hf/layout.h"
10 
11 #include "hf/std.h"
12 
13 /**
14  * Get the address the .text section begins at.
15  */
layout_text_begin(void)16 paddr_t layout_text_begin(void)
17 {
18 	extern uint8_t text_begin[];
19 
20 	return pa_init((uintpaddr_t)text_begin);
21 }
22 
23 /**
24  * Get the address the .text section ends at.
25  */
layout_text_end(void)26 paddr_t layout_text_end(void)
27 {
28 	extern uint8_t text_end[];
29 
30 	return pa_init((uintpaddr_t)text_end);
31 }
32 
33 /**
34  * Get the address the .rodata section begins at.
35  */
layout_rodata_begin(void)36 paddr_t layout_rodata_begin(void)
37 {
38 	extern uint8_t rodata_begin[];
39 
40 	return pa_init((uintpaddr_t)rodata_begin);
41 }
42 
43 /**
44  * Get the address the .rodata section ends at.
45  */
layout_rodata_end(void)46 paddr_t layout_rodata_end(void)
47 {
48 	extern uint8_t rodata_end[];
49 
50 	return pa_init((uintpaddr_t)rodata_end);
51 }
52 
53 /**
54  * Get the address the .data section begins at.
55  */
layout_data_begin(void)56 paddr_t layout_data_begin(void)
57 {
58 	extern uint8_t data_begin[];
59 
60 	return pa_init((uintpaddr_t)data_begin);
61 }
62 
63 /**
64  * Get the address the .data section ends at.
65  */
layout_data_end(void)66 paddr_t layout_data_end(void)
67 {
68 	extern uint8_t data_end[];
69 
70 	return pa_init((uintpaddr_t)data_end);
71 }
72 
73 /**
74  * Get the address the .stacks section begins at.
75  */
layout_stacks_begin(void)76 paddr_t layout_stacks_begin(void)
77 {
78 	extern uint8_t stacks_begin[];
79 
80 	return pa_init((uintpaddr_t)stacks_begin);
81 }
82 
83 /**
84  * Get the address the .stacks section ends at.
85  */
layout_stacks_end(void)86 paddr_t layout_stacks_end(void)
87 {
88 	extern uint8_t stacks_end[];
89 
90 	return pa_init((uintpaddr_t)stacks_end);
91 }
92 
93 /**
94  * Get the address the .initrd section begins at.
95  */
layout_initrd_begin(void)96 paddr_t layout_initrd_begin(void)
97 {
98 	extern uint8_t initrd_begin[];
99 
100 	return pa_init((uintpaddr_t)initrd_begin);
101 }
102 
103 /**
104  * Get the address the .initrd section ends at.
105  */
layout_initrd_end(void)106 paddr_t layout_initrd_end(void)
107 {
108 	extern uint8_t initrd_end[];
109 
110 	return pa_init((uintpaddr_t)initrd_end);
111 }
112 
113 /**
114  * Get the address the .fdt section begins at.
115  */
layout_fdt_begin(void)116 paddr_t layout_fdt_begin(void)
117 {
118 	extern uint8_t fdt_begin[];
119 
120 	return pa_init((uintpaddr_t)fdt_begin);
121 }
122 
123 /**
124  * Get the address the .fdt section ends at.
125  */
layout_fdt_end(void)126 paddr_t layout_fdt_end(void)
127 {
128 	extern uint8_t fdt_end[];
129 
130 	return pa_init((uintpaddr_t)fdt_end);
131 }
132 
133 /**
134  * Get the address the loaded image ends at.
135  */
layout_image_end(void)136 paddr_t layout_image_end(void)
137 {
138 	extern uint8_t image_end[];
139 
140 	return pa_init((uintpaddr_t)image_end);
141 }
142 
143 /**
144  * Get the address to load the primary VM at.
145  *
146  * This is placed just after the image.
147  */
layout_primary_begin(void)148 paddr_t layout_primary_begin(void)
149 {
150 	paddr_t image_end = layout_image_end();
151 
152 	/*
153 	 * Linux usually expects to be loaded at offset 0x80000 into a 2MB
154 	 * aligned address.
155 	 * TODO: This is a hack, and isn't always correct. We should really read
156 	 * the alignment from the header of the binary, or have a bootloader
157 	 * within the VM do so.
158 	 */
159 	return pa_init(align_up(pa_addr(image_end), LINUX_ALIGNMENT) +
160 		       LINUX_OFFSET);
161 }
162