/* * Copyright (c) 2010 ARM Limited * All rights reserved * * The license below extends only to copyright in the software and shall * not be construed as granting a license to any other intellectual * property including but not limited to intellectual property relating * to a hardware implementation of the functionality of the software * licensed hereunder. You may use the software subject to the license * terms below provided that you ensure that this notice is replicated * unmodified and in its entirety in all distributions of the software, * modified or unmodified, in source code or in binary form. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer; * redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution; * neither the name of the copyright holders nor the names of its * contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * Authors: Ali Saidi */ #ifndef __ARCH_ARM_LINUX_ATAG_HH__ #define __ARCH_ARM_LINUX_ATAG_HH__ #include #include #include "base/types.hh" enum { CoreTag = 0x54410001, MemTag = 0x54410002, RevTag = 0x54410007, SerialTag = 0x54410006, CmdTag = 0x54410009, NoneTag = 0x00000000 }; class AtagHeader { protected: uint32_t *storage; uint32_t _size; public: /** Tag (normally starts with 'T''A' and 16 bits of number */ virtual uint32_t tag() = 0; /** If the header should be 0 size */ virtual bool null() { return false; } uint32_t size() const { return _size; } AtagHeader(uint32_t s) : _size(s) { storage = new uint32_t[size()]; } virtual ~AtagHeader() { delete[] storage; } uint32_t copyOut(uint8_t *p) { storage[0] = null() ? 0 : size(); storage[1] = tag(); memcpy(p, storage, size() << 2); return size() << 2; } }; class AtagCore : public AtagHeader { public: static const uint32_t Size = 5; uint32_t tag() { return CoreTag; } void flags(uint32_t i) { storage[2] = i; } void pagesize(uint32_t i) { storage[3] = i; } void rootdev(uint32_t i) { storage[4] = i; } AtagCore() : AtagHeader(Size) {} }; class AtagMem : public AtagHeader { public: static const uint32_t Size = 4; uint32_t tag() { return MemTag; } void memSize(uint32_t i) { storage[2] = i; } void memStart(uint32_t i) { storage[3] = i; } AtagMem() : AtagHeader(Size) {} }; class AtagRev : public AtagHeader { public: static const uint32_t Size = 3; uint32_t tag() { return RevTag; } void rev(uint32_t i) { storage[2] = i; } AtagRev() : AtagHeader(Size) {} }; class AtagSerial : public AtagHeader { public: static const uint32_t Size = 4; uint32_t tag() { return SerialTag; } void sn(uint64_t i) { storage[2] = (uint32_t)i; storage[3] = i >> 32; } AtagSerial() : AtagHeader(Size) {} }; class AtagCmdline : public AtagHeader { public: static const uint32_t Size = 3; uint32_t tag() { return CmdTag; } void cmdline(const std::string &s) { // Add one for null terminator int len = s.length() + 1; // 2 + ceiling(len/4) _size = 2 + ((len + 3) >> 2); delete[] storage; storage = new uint32_t[size()]; // Initialize the last byte of memory here beacuse it might be slightly // longer than needed and mis-speculation of the NULL in the O3 CPU can // change stats ever so slightly when that happens. storage[size() - 1] = 0; strcpy((char*)&storage[2] , s.c_str()); } AtagCmdline() : AtagHeader(Size) {} }; class AtagNone : public AtagHeader { public: static const uint32_t Size = 2; virtual bool null() { return true; } uint32_t tag() { return NoneTag; } AtagNone() : AtagHeader(Size) {} }; /* // // example ARM Linux bootloader code // this example is distributed under the BSD licence // Code taken from http://www.simtec.co.uk/products/SWLINUX/files/booting_article.html /// // list of possible tags #define ATAG_NONE 0x00000000 #define ATAG_CORE 0x54410001 #define ATAG_MEM 0x54410002 #define ATAG_VIDEOTEXT 0x54410003 #define ATAG_RAMDISK 0x54410004 #define ATAG_INITRD2 0x54420005 #define ATAG_SERIAL 0x54410006 #define ATAG_REVISION 0x54410007 #define ATAG_VIDEOLFB 0x54410008 #define ATAG_CMDLINE 0x54410009 // structures for each atag struct atag_header { u32 size; // length of tag in words including this header u32 tag; // tag type }; struct atag_core { u32 flags; u32 pagesize; u32 rootdev; }; struct atag_mem { u32 size; u32 start; }; struct atag_videotext { u8 x; u8 y; u16 video_page; u8 video_mode; u8 video_cols; u16 video_ega_bx; u8 video_lines; u8 video_isvga; u16 video_points; }; struct atag_ramdisk { u32 flags; u32 size; u32 start; }; struct atag_initrd2 { u32 start; u32 size; }; struct atag_serialnr { u32 low; u32 high; }; struct atag_revision { u32 rev; }; struct atag_videolfb { u16 lfb_width; u16 lfb_height; u16 lfb_depth; u16 lfb_linelength; u32 lfb_base; u32 lfb_size; u8 red_size; u8 red_pos; u8 green_size; u8 green_pos; u8 blue_size; u8 blue_pos; u8 rsvd_size; u8 rsvd_pos; }; struct atag_cmdline { char cmdline[1]; }; struct atag { struct atag_header hdr; union { struct atag_core core; struct atag_mem mem; struct atag_videotext videotext; struct atag_ramdisk ramdisk; struct atag_initrd2 initrd2; struct atag_serialnr serialnr; struct atag_revision revision; struct atag_videolfb videolfb; struct atag_cmdline cmdline; } u; }; */ #endif // __ARCH_ARM_LINUX_ATAG_HH__