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 48enum { 49 CoreTag = 0x54410001, 50 MemTag = 0x54410002, 51 RevTag = 0x54410007, 52 SerialTag = 0x54410006, 53 CmdTag = 0x54410009, 54 NoneTag = 0x00000000 55}; 56 57class 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 91class 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 105class 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 118class 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 131class 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 143class 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 170class 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 200struct atag_header { 201 u32 size; // length of tag in words including this header 202 u32 tag; // tag type 203}; 204 205struct atag_core { 206 u32 flags; 207 u32 pagesize; 208 u32 rootdev; 209}; 210 211struct atag_mem { 212 u32 size; 213 u32 start; 214}; 215 216struct 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 228struct atag_ramdisk { 229 u32 flags; 230 u32 size; 231 u32 start; 232}; 233 234struct atag_initrd2 { 235 u32 start; 236 u32 size; 237}; 238 239struct atag_serialnr { 240 u32 low; 241 u32 high; 242}; 243 244struct atag_revision { 245 u32 rev; 246}; 247 248struct 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 265struct atag_cmdline { 266 char cmdline[1]; 267}; 268 269struct 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__ 287