ARM: Add system for ARM/Linux and bootstrapping
[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 #include "base/types.hh"
46
47 enum {
48 CoreTag = 0x54410001,
49 MemTag = 0x54410002,
50 RevTag = 0x54410007,
51 SerialTag = 0x54410006,
52 CmdTag = 0x54410009,
53 NoneTag = 0x00000000,
54 };
55
56 class AtagHeader
57 {
58 protected:
59 uint32_t *storage;
60 uint32_t _size;
61
62 public:
63 /** Tag (normally starts with 'T''A' and 16 bits of number */
64 virtual uint32_t tag() = 0;
65 /** If the header should be 0 size */
66 virtual bool null() { return false; }
67
68 uint32_t size() const { return _size; }
69
70 AtagHeader(uint32_t s)
71 : _size(s)
72 {
73 storage = new uint32_t[size()];
74 }
75
76 virtual ~AtagHeader()
77 {
78 delete[] storage;
79 }
80
81 uint32_t copyOut(uint8_t *p)
82 {
83 storage[0] = null() ? 0 : size();
84 storage[1] = tag();
85 memcpy(p, storage, size() << 2);
86 return size() << 2;
87 }
88 };
89
90 class AtagCore : public AtagHeader
91 {
92 public:
93 static const uint32_t Size = 5;
94 uint32_t tag() { return CoreTag; }
95
96 void flags(uint32_t i) { storage[2] = i; }
97 void pagesize(uint32_t i) { storage[3] = i; }
98 void rootdev(uint32_t i) { storage[4] = i; }
99 AtagCore()
100 : AtagHeader(Size)
101 {}
102 };
103
104 class AtagMem : public AtagHeader
105 {
106 public:
107 static const uint32_t Size = 4;
108 uint32_t tag() { return MemTag; }
109
110 void memSize(uint32_t i) { storage[2] = i; }
111 void memStart(uint32_t i) { storage[3] = i; }
112 AtagMem()
113 : AtagHeader(Size)
114 {}
115 };
116
117 class AtagRev : public AtagHeader
118 {
119 public:
120 static const uint32_t Size = 3;
121 uint32_t tag() { return RevTag; }
122
123 void rev(uint32_t i) { storage[2] = i; }
124 AtagRev()
125 : AtagHeader(Size)
126 {}
127 };
128
129
130 class AtagSerial : public AtagHeader
131 {
132 public:
133 static const uint32_t Size = 4;
134 uint32_t tag() { return SerialTag; }
135
136 void sn(uint64_t i) { storage[2] = (uint32_t)i; storage[3] = i >> 32; }
137 AtagSerial()
138 : AtagHeader(Size)
139 {}
140 };
141
142 class AtagCmdline : public AtagHeader
143 {
144 public:
145 static const uint32_t Size = 3;
146 uint32_t tag() { return CmdTag; }
147
148 void cmdline(const std::string &s)
149 {
150 // Add one for null terminator
151 int len = s.length() + 1;
152
153 // 2 + ceiling(len/4)
154 _size = 2 + ((len + 3) >> 2);
155
156 delete[] storage;
157 storage = new uint32_t[size()];
158
159 strcpy((char*)&storage[2] , s.c_str());
160 }
161 AtagCmdline()
162 : AtagHeader(Size)
163 {}
164 };
165
166 class AtagNone : public AtagHeader
167 {
168 public:
169 static const uint32_t Size = 2;
170 virtual bool null() { return true; }
171 uint32_t tag() { return NoneTag; }
172 AtagNone()
173 : AtagHeader(Size)
174 {}
175 };
176 /*
177 //
178 // example ARM Linux bootloader code
179 // this example is distributed under the BSD licence
180 // Code taken from http://www.simtec.co.uk/products/SWLINUX/files/booting_article.html
181 ///
182
183 // list of possible tags
184 #define ATAG_NONE 0x00000000
185 #define ATAG_CORE 0x54410001
186 #define ATAG_MEM 0x54410002
187 #define ATAG_VIDEOTEXT 0x54410003
188 #define ATAG_RAMDISK 0x54410004
189 #define ATAG_INITRD2 0x54420005
190 #define ATAG_SERIAL 0x54410006
191 #define ATAG_REVISION 0x54410007
192 #define ATAG_VIDEOLFB 0x54410008
193 #define ATAG_CMDLINE 0x54410009
194
195 // structures for each atag
196 struct atag_header {
197 u32 size; // length of tag in words including this header
198 u32 tag; // tag type
199 };
200
201 struct atag_core {
202 u32 flags;
203 u32 pagesize;
204 u32 rootdev;
205 };
206
207 struct atag_mem {
208 u32 size;
209 u32 start;
210 };
211
212 struct atag_videotext {
213 u8 x;
214 u8 y;
215 u16 video_page;
216 u8 video_mode;
217 u8 video_cols;
218 u16 video_ega_bx;
219 u8 video_lines;
220 u8 video_isvga;
221 u16 video_points;
222 };
223
224 struct atag_ramdisk {
225 u32 flags;
226 u32 size;
227 u32 start;
228 };
229
230 struct atag_initrd2 {
231 u32 start;
232 u32 size;
233 };
234
235 struct atag_serialnr {
236 u32 low;
237 u32 high;
238 };
239
240 struct atag_revision {
241 u32 rev;
242 };
243
244 struct atag_videolfb {
245 u16 lfb_width;
246 u16 lfb_height;
247 u16 lfb_depth;
248 u16 lfb_linelength;
249 u32 lfb_base;
250 u32 lfb_size;
251 u8 red_size;
252 u8 red_pos;
253 u8 green_size;
254 u8 green_pos;
255 u8 blue_size;
256 u8 blue_pos;
257 u8 rsvd_size;
258 u8 rsvd_pos;
259 };
260
261 struct atag_cmdline {
262 char cmdline[1];
263 };
264
265 struct atag {
266 struct atag_header hdr;
267 union {
268 struct atag_core core;
269 struct atag_mem mem;
270 struct atag_videotext videotext;
271 struct atag_ramdisk ramdisk;
272 struct atag_initrd2 initrd2;
273 struct atag_serialnr serialnr;
274 struct atag_revision revision;
275 struct atag_videolfb videolfb;
276 struct atag_cmdline cmdline;
277 } u;
278 };
279 */
280
281
282 #endif // __ARCH_ARM_LINUX_ATAG_HH__