atag.hh revision 7585
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
47enum {
48    CoreTag   = 0x54410001,
49    MemTag    = 0x54410002,
50    RevTag    = 0x54410007,
51    SerialTag = 0x54410006,
52    CmdTag    = 0x54410009,
53    NoneTag   = 0x00000000,
54};
55
56class 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
90class 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
104class 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
117class 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
130class 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
142class 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
166class 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
196struct atag_header {
197        u32 size; // length of tag in words including this header
198        u32 tag;  // tag type
199};
200
201struct atag_core {
202        u32 flags;
203        u32 pagesize;
204        u32 rootdev;
205};
206
207struct atag_mem {
208        u32     size;
209        u32     start;
210};
211
212struct 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
224struct atag_ramdisk {
225        u32 flags;
226        u32 size;
227        u32 start;
228};
229
230struct atag_initrd2 {
231        u32 start;
232        u32 size;
233};
234
235struct atag_serialnr {
236        u32 low;
237        u32 high;
238};
239
240struct atag_revision {
241        u32 rev;
242};
243
244struct 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
261struct atag_cmdline {
262        char    cmdline[1];
263};
264
265struct 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__
283