17585SAli.Saidi@arm.com/* 27585SAli.Saidi@arm.com * Copyright (c) 2010 ARM Limited 37585SAli.Saidi@arm.com * All rights reserved 47585SAli.Saidi@arm.com * 57585SAli.Saidi@arm.com * The license below extends only to copyright in the software and shall 67585SAli.Saidi@arm.com * not be construed as granting a license to any other intellectual 77585SAli.Saidi@arm.com * property including but not limited to intellectual property relating 87585SAli.Saidi@arm.com * to a hardware implementation of the functionality of the software 97585SAli.Saidi@arm.com * licensed hereunder. You may use the software subject to the license 107585SAli.Saidi@arm.com * terms below provided that you ensure that this notice is replicated 117585SAli.Saidi@arm.com * unmodified and in its entirety in all distributions of the software, 127585SAli.Saidi@arm.com * modified or unmodified, in source code or in binary form. 137585SAli.Saidi@arm.com * 147585SAli.Saidi@arm.com * Redistribution and use in source and binary forms, with or without 157585SAli.Saidi@arm.com * modification, are permitted provided that the following conditions are 167585SAli.Saidi@arm.com * met: redistributions of source code must retain the above copyright 177585SAli.Saidi@arm.com * notice, this list of conditions and the following disclaimer; 187585SAli.Saidi@arm.com * redistributions in binary form must reproduce the above copyright 197585SAli.Saidi@arm.com * notice, this list of conditions and the following disclaimer in the 207585SAli.Saidi@arm.com * documentation and/or other materials provided with the distribution; 217585SAli.Saidi@arm.com * neither the name of the copyright holders nor the names of its 227585SAli.Saidi@arm.com * contributors may be used to endorse or promote products derived from 237585SAli.Saidi@arm.com * this software without specific prior written permission. 247585SAli.Saidi@arm.com * 257585SAli.Saidi@arm.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 267585SAli.Saidi@arm.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 277585SAli.Saidi@arm.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 287585SAli.Saidi@arm.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 297585SAli.Saidi@arm.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 307585SAli.Saidi@arm.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 317585SAli.Saidi@arm.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 327585SAli.Saidi@arm.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 337585SAli.Saidi@arm.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 347585SAli.Saidi@arm.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 357585SAli.Saidi@arm.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 367585SAli.Saidi@arm.com * 377585SAli.Saidi@arm.com * Authors: Ali Saidi 387585SAli.Saidi@arm.com */ 397585SAli.Saidi@arm.com 407585SAli.Saidi@arm.com#ifndef __ARCH_ARM_LINUX_ATAG_HH__ 417585SAli.Saidi@arm.com#define __ARCH_ARM_LINUX_ATAG_HH__ 427585SAli.Saidi@arm.com 437585SAli.Saidi@arm.com#include <cstring> 447585SAli.Saidi@arm.com#include <string> 458229Snate@binkert.org 467585SAli.Saidi@arm.com#include "base/types.hh" 477585SAli.Saidi@arm.com 487585SAli.Saidi@arm.comenum { 497585SAli.Saidi@arm.com CoreTag = 0x54410001, 507585SAli.Saidi@arm.com MemTag = 0x54410002, 517585SAli.Saidi@arm.com RevTag = 0x54410007, 527585SAli.Saidi@arm.com SerialTag = 0x54410006, 537585SAli.Saidi@arm.com CmdTag = 0x54410009, 548902Sandreas.hansson@arm.com NoneTag = 0x00000000 557585SAli.Saidi@arm.com}; 567585SAli.Saidi@arm.com 577585SAli.Saidi@arm.comclass AtagHeader 587585SAli.Saidi@arm.com{ 597585SAli.Saidi@arm.com protected: 607585SAli.Saidi@arm.com uint32_t *storage; 617585SAli.Saidi@arm.com uint32_t _size; 627585SAli.Saidi@arm.com 637585SAli.Saidi@arm.com public: 647585SAli.Saidi@arm.com /** Tag (normally starts with 'T''A' and 16 bits of number */ 657585SAli.Saidi@arm.com virtual uint32_t tag() = 0; 667585SAli.Saidi@arm.com /** If the header should be 0 size */ 677585SAli.Saidi@arm.com virtual bool null() { return false; } 687585SAli.Saidi@arm.com 697585SAli.Saidi@arm.com uint32_t size() const { return _size; } 707585SAli.Saidi@arm.com 717585SAli.Saidi@arm.com AtagHeader(uint32_t s) 727585SAli.Saidi@arm.com : _size(s) 737585SAli.Saidi@arm.com { 747585SAli.Saidi@arm.com storage = new uint32_t[size()]; 757585SAli.Saidi@arm.com } 767585SAli.Saidi@arm.com 777585SAli.Saidi@arm.com virtual ~AtagHeader() 787585SAli.Saidi@arm.com { 797585SAli.Saidi@arm.com delete[] storage; 807585SAli.Saidi@arm.com } 817585SAli.Saidi@arm.com 827585SAli.Saidi@arm.com uint32_t copyOut(uint8_t *p) 837585SAli.Saidi@arm.com { 847585SAli.Saidi@arm.com storage[0] = null() ? 0 : size(); 857585SAli.Saidi@arm.com storage[1] = tag(); 867585SAli.Saidi@arm.com memcpy(p, storage, size() << 2); 877585SAli.Saidi@arm.com return size() << 2; 887585SAli.Saidi@arm.com } 897585SAli.Saidi@arm.com}; 907585SAli.Saidi@arm.com 917585SAli.Saidi@arm.comclass AtagCore : public AtagHeader 927585SAli.Saidi@arm.com{ 937585SAli.Saidi@arm.com public: 947585SAli.Saidi@arm.com static const uint32_t Size = 5; 957585SAli.Saidi@arm.com uint32_t tag() { return CoreTag; } 967585SAli.Saidi@arm.com 977585SAli.Saidi@arm.com void flags(uint32_t i) { storage[2] = i; } 987585SAli.Saidi@arm.com void pagesize(uint32_t i) { storage[3] = i; } 997585SAli.Saidi@arm.com void rootdev(uint32_t i) { storage[4] = i; } 1007585SAli.Saidi@arm.com AtagCore() 1017585SAli.Saidi@arm.com : AtagHeader(Size) 1027585SAli.Saidi@arm.com {} 1037585SAli.Saidi@arm.com}; 1047585SAli.Saidi@arm.com 1057585SAli.Saidi@arm.comclass AtagMem : public AtagHeader 1067585SAli.Saidi@arm.com{ 1077585SAli.Saidi@arm.com public: 1087585SAli.Saidi@arm.com static const uint32_t Size = 4; 1097585SAli.Saidi@arm.com uint32_t tag() { return MemTag; } 1107585SAli.Saidi@arm.com 1117585SAli.Saidi@arm.com void memSize(uint32_t i) { storage[2] = i; } 1127585SAli.Saidi@arm.com void memStart(uint32_t i) { storage[3] = i; } 1137585SAli.Saidi@arm.com AtagMem() 1147585SAli.Saidi@arm.com : AtagHeader(Size) 1157585SAli.Saidi@arm.com {} 1167585SAli.Saidi@arm.com}; 1177585SAli.Saidi@arm.com 1187585SAli.Saidi@arm.comclass AtagRev : public AtagHeader 1197585SAli.Saidi@arm.com{ 1207585SAli.Saidi@arm.com public: 1217585SAli.Saidi@arm.com static const uint32_t Size = 3; 1227585SAli.Saidi@arm.com uint32_t tag() { return RevTag; } 1237585SAli.Saidi@arm.com 1247585SAli.Saidi@arm.com void rev(uint32_t i) { storage[2] = i; } 1257585SAli.Saidi@arm.com AtagRev() 1267585SAli.Saidi@arm.com : AtagHeader(Size) 1277585SAli.Saidi@arm.com {} 1287585SAli.Saidi@arm.com}; 1297585SAli.Saidi@arm.com 1307585SAli.Saidi@arm.com 1317585SAli.Saidi@arm.comclass AtagSerial : public AtagHeader 1327585SAli.Saidi@arm.com{ 1337585SAli.Saidi@arm.com public: 1347585SAli.Saidi@arm.com static const uint32_t Size = 4; 1357585SAli.Saidi@arm.com uint32_t tag() { return SerialTag; } 1367585SAli.Saidi@arm.com 1377585SAli.Saidi@arm.com void sn(uint64_t i) { storage[2] = (uint32_t)i; storage[3] = i >> 32; } 1387585SAli.Saidi@arm.com AtagSerial() 1397585SAli.Saidi@arm.com : AtagHeader(Size) 1407585SAli.Saidi@arm.com {} 1417585SAli.Saidi@arm.com}; 1427585SAli.Saidi@arm.com 1437585SAli.Saidi@arm.comclass AtagCmdline : public AtagHeader 1447585SAli.Saidi@arm.com{ 1457585SAli.Saidi@arm.com public: 1467585SAli.Saidi@arm.com static const uint32_t Size = 3; 1477585SAli.Saidi@arm.com uint32_t tag() { return CmdTag; } 1487585SAli.Saidi@arm.com 1497585SAli.Saidi@arm.com void cmdline(const std::string &s) 1507585SAli.Saidi@arm.com { 1517585SAli.Saidi@arm.com // Add one for null terminator 1527585SAli.Saidi@arm.com int len = s.length() + 1; 1537585SAli.Saidi@arm.com 1547585SAli.Saidi@arm.com // 2 + ceiling(len/4) 1557585SAli.Saidi@arm.com _size = 2 + ((len + 3) >> 2); 1567585SAli.Saidi@arm.com 1577585SAli.Saidi@arm.com delete[] storage; 1587585SAli.Saidi@arm.com storage = new uint32_t[size()]; 1598884SAli.Saidi@ARM.com // Initialize the last byte of memory here beacuse it might be slightly 1608884SAli.Saidi@ARM.com // longer than needed and mis-speculation of the NULL in the O3 CPU can 1618884SAli.Saidi@ARM.com // change stats ever so slightly when that happens. 1628884SAli.Saidi@ARM.com storage[size() - 1] = 0; 1637585SAli.Saidi@arm.com strcpy((char*)&storage[2] , s.c_str()); 1647585SAli.Saidi@arm.com } 1657585SAli.Saidi@arm.com AtagCmdline() 1667585SAli.Saidi@arm.com : AtagHeader(Size) 1677585SAli.Saidi@arm.com {} 1687585SAli.Saidi@arm.com}; 1697585SAli.Saidi@arm.com 1707585SAli.Saidi@arm.comclass AtagNone : public AtagHeader 1717585SAli.Saidi@arm.com{ 1727585SAli.Saidi@arm.com public: 1737585SAli.Saidi@arm.com static const uint32_t Size = 2; 1747585SAli.Saidi@arm.com virtual bool null() { return true; } 1757585SAli.Saidi@arm.com uint32_t tag() { return NoneTag; } 1767585SAli.Saidi@arm.com AtagNone() 1777585SAli.Saidi@arm.com : AtagHeader(Size) 1787585SAli.Saidi@arm.com {} 1797585SAli.Saidi@arm.com}; 1807585SAli.Saidi@arm.com/* 1817585SAli.Saidi@arm.com// 1827585SAli.Saidi@arm.com// example ARM Linux bootloader code 1837585SAli.Saidi@arm.com// this example is distributed under the BSD licence 1847585SAli.Saidi@arm.com// Code taken from http://www.simtec.co.uk/products/SWLINUX/files/booting_article.html 1857585SAli.Saidi@arm.com/// 1867585SAli.Saidi@arm.com 1877585SAli.Saidi@arm.com// list of possible tags 1887585SAli.Saidi@arm.com#define ATAG_NONE 0x00000000 1897585SAli.Saidi@arm.com#define ATAG_CORE 0x54410001 1907585SAli.Saidi@arm.com#define ATAG_MEM 0x54410002 1917585SAli.Saidi@arm.com#define ATAG_VIDEOTEXT 0x54410003 1927585SAli.Saidi@arm.com#define ATAG_RAMDISK 0x54410004 1937585SAli.Saidi@arm.com#define ATAG_INITRD2 0x54420005 1947585SAli.Saidi@arm.com#define ATAG_SERIAL 0x54410006 1957585SAli.Saidi@arm.com#define ATAG_REVISION 0x54410007 1967585SAli.Saidi@arm.com#define ATAG_VIDEOLFB 0x54410008 1977585SAli.Saidi@arm.com#define ATAG_CMDLINE 0x54410009 1987585SAli.Saidi@arm.com 1997585SAli.Saidi@arm.com// structures for each atag 2007585SAli.Saidi@arm.comstruct atag_header { 2017585SAli.Saidi@arm.com u32 size; // length of tag in words including this header 2027585SAli.Saidi@arm.com u32 tag; // tag type 2037585SAli.Saidi@arm.com}; 2047585SAli.Saidi@arm.com 2057585SAli.Saidi@arm.comstruct atag_core { 2067585SAli.Saidi@arm.com u32 flags; 2077585SAli.Saidi@arm.com u32 pagesize; 2087585SAli.Saidi@arm.com u32 rootdev; 2097585SAli.Saidi@arm.com}; 2107585SAli.Saidi@arm.com 2117585SAli.Saidi@arm.comstruct atag_mem { 2127585SAli.Saidi@arm.com u32 size; 2137585SAli.Saidi@arm.com u32 start; 2147585SAli.Saidi@arm.com}; 2157585SAli.Saidi@arm.com 2167585SAli.Saidi@arm.comstruct atag_videotext { 2177585SAli.Saidi@arm.com u8 x; 2187585SAli.Saidi@arm.com u8 y; 2197585SAli.Saidi@arm.com u16 video_page; 2207585SAli.Saidi@arm.com u8 video_mode; 2217585SAli.Saidi@arm.com u8 video_cols; 2227585SAli.Saidi@arm.com u16 video_ega_bx; 2237585SAli.Saidi@arm.com u8 video_lines; 2247585SAli.Saidi@arm.com u8 video_isvga; 2257585SAli.Saidi@arm.com u16 video_points; 2267585SAli.Saidi@arm.com}; 2277585SAli.Saidi@arm.com 2287585SAli.Saidi@arm.comstruct atag_ramdisk { 2297585SAli.Saidi@arm.com u32 flags; 2307585SAli.Saidi@arm.com u32 size; 2317585SAli.Saidi@arm.com u32 start; 2327585SAli.Saidi@arm.com}; 2337585SAli.Saidi@arm.com 2347585SAli.Saidi@arm.comstruct atag_initrd2 { 2357585SAli.Saidi@arm.com u32 start; 2367585SAli.Saidi@arm.com u32 size; 2377585SAli.Saidi@arm.com}; 2387585SAli.Saidi@arm.com 2397585SAli.Saidi@arm.comstruct atag_serialnr { 2407585SAli.Saidi@arm.com u32 low; 2417585SAli.Saidi@arm.com u32 high; 2427585SAli.Saidi@arm.com}; 2437585SAli.Saidi@arm.com 2447585SAli.Saidi@arm.comstruct atag_revision { 2457585SAli.Saidi@arm.com u32 rev; 2467585SAli.Saidi@arm.com}; 2477585SAli.Saidi@arm.com 2487585SAli.Saidi@arm.comstruct atag_videolfb { 2497585SAli.Saidi@arm.com u16 lfb_width; 2507585SAli.Saidi@arm.com u16 lfb_height; 2517585SAli.Saidi@arm.com u16 lfb_depth; 2527585SAli.Saidi@arm.com u16 lfb_linelength; 2537585SAli.Saidi@arm.com u32 lfb_base; 2547585SAli.Saidi@arm.com u32 lfb_size; 2557585SAli.Saidi@arm.com u8 red_size; 2567585SAli.Saidi@arm.com u8 red_pos; 2577585SAli.Saidi@arm.com u8 green_size; 2587585SAli.Saidi@arm.com u8 green_pos; 2597585SAli.Saidi@arm.com u8 blue_size; 2607585SAli.Saidi@arm.com u8 blue_pos; 2617585SAli.Saidi@arm.com u8 rsvd_size; 2627585SAli.Saidi@arm.com u8 rsvd_pos; 2637585SAli.Saidi@arm.com}; 2647585SAli.Saidi@arm.com 2657585SAli.Saidi@arm.comstruct atag_cmdline { 2667585SAli.Saidi@arm.com char cmdline[1]; 2677585SAli.Saidi@arm.com}; 2687585SAli.Saidi@arm.com 2697585SAli.Saidi@arm.comstruct atag { 2707585SAli.Saidi@arm.com struct atag_header hdr; 2717585SAli.Saidi@arm.com union { 2727585SAli.Saidi@arm.com struct atag_core core; 2737585SAli.Saidi@arm.com struct atag_mem mem; 2747585SAli.Saidi@arm.com struct atag_videotext videotext; 2757585SAli.Saidi@arm.com struct atag_ramdisk ramdisk; 2767585SAli.Saidi@arm.com struct atag_initrd2 initrd2; 2777585SAli.Saidi@arm.com struct atag_serialnr serialnr; 2787585SAli.Saidi@arm.com struct atag_revision revision; 2797585SAli.Saidi@arm.com struct atag_videolfb videolfb; 2807585SAli.Saidi@arm.com struct atag_cmdline cmdline; 2817585SAli.Saidi@arm.com } u; 2827585SAli.Saidi@arm.com}; 2837585SAli.Saidi@arm.com*/ 2847585SAli.Saidi@arm.com 2857585SAli.Saidi@arm.com 2867585SAli.Saidi@arm.com#endif // __ARCH_ARM_LINUX_ATAG_HH__ 287