arch,base,sim: Move Process loader hooks into the Process class.
[gem5.git] / src / arch / arm / linux / atag.hh
1 /*
2 * Copyright (c) 2010 ARM Limited
3 * All rights reserved
4 *
5 * The license below extends only to copyright in the software and shall
6 * not be construed as granting a license to any other intellectual
7 * property including but not limited to intellectual property relating
8 * to a hardware implementation of the functionality of the software
9 * licensed hereunder. You may use the software subject to the license
10 * terms below provided that you ensure that this notice is replicated
11 * unmodified and in its entirety in all distributions of the software,
12 * modified or unmodified, in source code or in binary form.
13 *
14 * Redistribution and use in source and binary forms, with or without
15 * modification, are permitted provided that the following conditions are
16 * met: redistributions of source code must retain the above copyright
17 * notice, this list of conditions and the following disclaimer;
18 * redistributions in binary form must reproduce the above copyright
19 * notice, this list of conditions and the following disclaimer in the
20 * documentation and/or other materials provided with the distribution;
21 * neither the name of the copyright holders nor the names of its
22 * contributors may be used to endorse or promote products derived from
23 * this software without specific prior written permission.
24 *
25 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
26 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
27 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
28 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
29 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
30 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
31 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
32 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
33 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
35 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 *
37 * Authors: Ali Saidi
38 */
39
40 #ifndef __ARCH_ARM_LINUX_ATAG_HH__
41 #define __ARCH_ARM_LINUX_ATAG_HH__
42
43 #include <cstring>
44 #include <string>
45
46 #include "base/types.hh"
47
48 enum {
49 CoreTag = 0x54410001,
50 MemTag = 0x54410002,
51 RevTag = 0x54410007,
52 SerialTag = 0x54410006,
53 CmdTag = 0x54410009,
54 NoneTag = 0x00000000
55 };
56
57 class AtagHeader
58 {
59 protected:
60 uint32_t *storage;
61 uint32_t _size;
62
63 public:
64 /** Tag (normally starts with 'T''A' and 16 bits of number */
65 virtual uint32_t tag() = 0;
66 /** If the header should be 0 size */
67 virtual bool null() { return false; }
68
69 uint32_t size() const { return _size; }
70
71 AtagHeader(uint32_t s)
72 : _size(s)
73 {
74 storage = new uint32_t[size()];
75 }
76
77 virtual ~AtagHeader()
78 {
79 delete[] storage;
80 }
81
82 uint32_t copyOut(uint8_t *p)
83 {
84 storage[0] = null() ? 0 : size();
85 storage[1] = tag();
86 memcpy(p, storage, size() << 2);
87 return size() << 2;
88 }
89 };
90
91 class AtagCore : public AtagHeader
92 {
93 public:
94 static const uint32_t Size = 5;
95 uint32_t tag() { return CoreTag; }
96
97 void flags(uint32_t i) { storage[2] = i; }
98 void pagesize(uint32_t i) { storage[3] = i; }
99 void rootdev(uint32_t i) { storage[4] = i; }
100 AtagCore()
101 : AtagHeader(Size)
102 {}
103 };
104
105 class AtagMem : public AtagHeader
106 {
107 public:
108 static const uint32_t Size = 4;
109 uint32_t tag() { return MemTag; }
110
111 void memSize(uint32_t i) { storage[2] = i; }
112 void memStart(uint32_t i) { storage[3] = i; }
113 AtagMem()
114 : AtagHeader(Size)
115 {}
116 };
117
118 class AtagRev : public AtagHeader
119 {
120 public:
121 static const uint32_t Size = 3;
122 uint32_t tag() { return RevTag; }
123
124 void rev(uint32_t i) { storage[2] = i; }
125 AtagRev()
126 : AtagHeader(Size)
127 {}
128 };
129
130
131 class AtagSerial : public AtagHeader
132 {
133 public:
134 static const uint32_t Size = 4;
135 uint32_t tag() { return SerialTag; }
136
137 void sn(uint64_t i) { storage[2] = (uint32_t)i; storage[3] = i >> 32; }
138 AtagSerial()
139 : AtagHeader(Size)
140 {}
141 };
142
143 class AtagCmdline : public AtagHeader
144 {
145 public:
146 static const uint32_t Size = 3;
147 uint32_t tag() { return CmdTag; }
148
149 void cmdline(const std::string &s)
150 {
151 // Add one for null terminator
152 int len = s.length() + 1;
153
154 // 2 + ceiling(len/4)
155 _size = 2 + ((len + 3) >> 2);
156
157 delete[] storage;
158 storage = new uint32_t[size()];
159 // Initialize the last byte of memory here beacuse it might be slightly
160 // longer than needed and mis-speculation of the NULL in the O3 CPU can
161 // change stats ever so slightly when that happens.
162 storage[size() - 1] = 0;
163 strcpy((char*)&storage[2] , s.c_str());
164 }
165 AtagCmdline()
166 : AtagHeader(Size)
167 {}
168 };
169
170 class AtagNone : public AtagHeader
171 {
172 public:
173 static const uint32_t Size = 2;
174 virtual bool null() { return true; }
175 uint32_t tag() { return NoneTag; }
176 AtagNone()
177 : AtagHeader(Size)
178 {}
179 };
180 /*
181 //
182 // example ARM Linux bootloader code
183 // this example is distributed under the BSD licence
184 // Code taken from http://www.simtec.co.uk/products/SWLINUX/files/booting_article.html
185 ///
186
187 // list of possible tags
188 #define ATAG_NONE 0x00000000
189 #define ATAG_CORE 0x54410001
190 #define ATAG_MEM 0x54410002
191 #define ATAG_VIDEOTEXT 0x54410003
192 #define ATAG_RAMDISK 0x54410004
193 #define ATAG_INITRD2 0x54420005
194 #define ATAG_SERIAL 0x54410006
195 #define ATAG_REVISION 0x54410007
196 #define ATAG_VIDEOLFB 0x54410008
197 #define ATAG_CMDLINE 0x54410009
198
199 // structures for each atag
200 struct atag_header {
201 u32 size; // length of tag in words including this header
202 u32 tag; // tag type
203 };
204
205 struct atag_core {
206 u32 flags;
207 u32 pagesize;
208 u32 rootdev;
209 };
210
211 struct atag_mem {
212 u32 size;
213 u32 start;
214 };
215
216 struct atag_videotext {
217 u8 x;
218 u8 y;
219 u16 video_page;
220 u8 video_mode;
221 u8 video_cols;
222 u16 video_ega_bx;
223 u8 video_lines;
224 u8 video_isvga;
225 u16 video_points;
226 };
227
228 struct atag_ramdisk {
229 u32 flags;
230 u32 size;
231 u32 start;
232 };
233
234 struct atag_initrd2 {
235 u32 start;
236 u32 size;
237 };
238
239 struct atag_serialnr {
240 u32 low;
241 u32 high;
242 };
243
244 struct atag_revision {
245 u32 rev;
246 };
247
248 struct atag_videolfb {
249 u16 lfb_width;
250 u16 lfb_height;
251 u16 lfb_depth;
252 u16 lfb_linelength;
253 u32 lfb_base;
254 u32 lfb_size;
255 u8 red_size;
256 u8 red_pos;
257 u8 green_size;
258 u8 green_pos;
259 u8 blue_size;
260 u8 blue_pos;
261 u8 rsvd_size;
262 u8 rsvd_pos;
263 };
264
265 struct atag_cmdline {
266 char cmdline[1];
267 };
268
269 struct atag {
270 struct atag_header hdr;
271 union {
272 struct atag_core core;
273 struct atag_mem mem;
274 struct atag_videotext videotext;
275 struct atag_ramdisk ramdisk;
276 struct atag_initrd2 initrd2;
277 struct atag_serialnr serialnr;
278 struct atag_revision revision;
279 struct atag_videolfb videolfb;
280 struct atag_cmdline cmdline;
281 } u;
282 };
283 */
284
285
286 #endif // __ARCH_ARM_LINUX_ATAG_HH__