1// vim:set ft=cpp: -*- Mode: C++ -*- 2/*! 3 * \file 4 * L4::Kip class, memory descriptors. 5 * 6 * \author Alexander Warg <alexander.warg@os.inf.tu-dresden.de> 7 * \ingroup l4_api 8 * 9 */ 10/* 11 * (c) 2008-2009 Author(s) 12 * economic rights: Technische Universität Dresden (Germany) 13 * 14 * This file is part of TUD:OS and distributed under the terms of the 15 * GNU General Public License 2. 16 * Please see the COPYING-GPL-2 file for details. 17 * 18 * As a special exception, you may use this file as part of a free software 19 * library without restriction. Specifically, if other files instantiate 20 * templates or use macros or inline functions from this file, or you compile 21 * this file and link it with other files to produce an executable, this 22 * file does not by itself cause the resulting executable to be covered by 23 * the GNU General Public License. This exception does not however 24 * invalidate any other reasons why the executable file might be covered by 25 * the GNU General Public License. 26 */ 27#ifndef L4_SYS_KIP_H__ 28#define L4_SYS_KIP_H__ 29 30#include <l4/cxx/static_vector> 31 32/* C++ version of memory descriptors */ 33 34/** 35 * \defgroup l4_kip_api Kernel Interface Page 36 * \ingroup l4_api 37 * Kernel Interface Page. 38 * 39 * C++ interface for the Kernel Interface Page:<br> 40 * \includefile{l4/sys/kip} 41 */ 42 43namespace L4 44{ 45 namespace Kip 46 { 47 /** 48 * Memory descriptors stored in the kernel interface page. 49 * \ingroup l4_kip_api 50 * 51 * \includefile{l4/sys/kip} 52 */ 53 class Mem_desc 54 { 55 public: 56 /** 57 * Memory types. 58 */ 59 enum Mem_type 60 { 61 Undefined = 0x0, ///< Undefined memory 62 Conventional = 0x1, ///< Conventional memory 63 Reserved = 0x2, ///< Reserved region, do not use this memory 64 Dedicated = 0x3, ///< Dedicated 65 Shared = 0x4, ///< Shared 66 67 Info = 0xd, ///< Info by boot loader 68 Bootloader = 0xe, ///< Memory belongs to the boot loader 69 Arch = 0xf ///< Architecture specific memory 70 }; 71 72 /** 73 * Memory sub types for the Mem_type::Info type 74 */ 75 enum Info_sub_type 76 { 77 Info_acpi_rsdp = 0 ///< Physical address of the ACPI root pointer. 78 }; 79 80 private: 81 unsigned long _l, _h; 82 83 static unsigned long &memory_info(void *kip) noexcept 84 { return *((unsigned long *)kip + 21); } 85 86 static unsigned long memory_info(void const *kip) noexcept 87 { return *((unsigned long const *)kip + 21); } 88 89 public: 90 /** 91 * Get first memory descriptor. 92 * 93 * \param kip Pointer to the kernel info page 94 * 95 * \return First memory descriptor stored in the kernel info page 96 */ 97 static Mem_desc *first(void *kip) noexcept 98 { 99 return (Mem_desc *)((char *)kip 100 + (memory_info(kip) >> ((sizeof(unsigned long) / 2) * 8))); 101 } 102 103 static Mem_desc const *first(void const *kip) noexcept 104 { 105 return (Mem_desc const *)((char const *)kip 106 + (memory_info(kip) >> ((sizeof(unsigned long) / 2) * 8))); 107 } 108 109 /** 110 * Return number of memory descriptors stored in the kernel info page. 111 * 112 * \param kip Pointer to the kernel info page 113 * 114 * \return Number of memory descriptors in the kernel info page. 115 */ 116 static unsigned long count(void const *kip) noexcept 117 { 118 return memory_info(kip) 119 & ((1UL << ((sizeof(unsigned long) / 2) * 8)) - 1); 120 } 121 122 /** 123 * Set number of memory descriptors. 124 * 125 * \param kip Pointer to the kernel info page 126 * \param count Number of memory descriptors 127 */ 128 static void count(void *kip, unsigned count) noexcept 129 { 130 unsigned long &mi = memory_info(kip); 131 mi = (mi & ~((1UL << ((sizeof(unsigned long) / 2) * 8)) - 1)) | count; 132 } 133 134 /** 135 * Return enumerable list of memory descriptors 136 * 137 * \param kip Pointer to the kernel info page. 138 */ 139 static inline cxx::static_vector<Mem_desc const> all(void const *kip) 140 { 141 return cxx::static_vector<Mem_desc const>(Mem_desc::first(kip), 142 Mem_desc::count(kip)); 143 } 144 145 /** 146 * Return enumerable list of memory descriptors 147 * 148 * \param kip Pointer to the kernel info page. 149 */ 150 static inline cxx::static_vector<Mem_desc> all(void *kip) 151 { 152 return cxx::static_vector<Mem_desc>(Mem_desc::first(kip), 153 Mem_desc::count(kip)); 154 } 155 156 /** 157 * Initialize memory descriptor. 158 * 159 * \param start Start address 160 * \param end End address 161 * \param t Memory type 162 * \param st Memory subtype, defaults to 0 163 * \param virt True for virtual memory, false for physical memory, 164 * defaults to physical 165 */ 166 Mem_desc(unsigned long start, unsigned long end, 167 Mem_type t, unsigned char st = 0, bool virt = false) noexcept 168 : _l((start & ~0x3ffUL) | (t & 0x0f) | ((st << 4) & 0x0f0) 169 | (virt ? 0x0200 : 0x0)), _h(end | 0x3ffUL) 170 {} 171 172 /** 173 * Return start address of memory descriptor. 174 * 175 * \return Start address of memory descriptor 176 */ 177 unsigned long start() const noexcept { return _l & ~0x3ffUL; } 178 179 /** 180 * Return end address of memory descriptor. 181 * 182 * \return End address of memory descriptor 183 */ 184 unsigned long end() const noexcept { return _h | 0x3ffUL; } 185 186 /** 187 * Return size of region described by the memory descriptor. 188 * 189 * \return Size of the region described by the memory descriptor 190 */ 191 unsigned long size() const noexcept { return end() + 1 - start(); } 192 193 /** 194 * Return type of the memory descriptor. 195 * 196 * \return Type of the memory descriptor 197 */ 198 Mem_type type() const noexcept { return (Mem_type)(_l & 0x0f); } 199 200 /** 201 * Return sub-type of the memory descriptor. 202 * 203 * \return Sub-type of the memory descriptor 204 */ 205 unsigned char sub_type() const noexcept { return (_l >> 4) & 0x0f; } 206 207 /** 208 * Return whether the memory descriptor describes a virtual or 209 * physical region. 210 * 211 * \return True for virtual region, false for physical region. 212 */ 213 unsigned is_virtual() const noexcept { return _l & 0x200; } 214 215 /** 216 * Set values of a memory descriptor. 217 * 218 * \param start Start address 219 * \param end End address 220 * \param t Memory type 221 * \param st Sub-type, defaults to 0 222 * \param virt Virtual or physical memory region, defaults to physical 223 */ 224 void set(unsigned long start, unsigned long end, 225 Mem_type t, unsigned char st = 0, bool virt = false) noexcept 226 { 227 _l = (start & ~0x3ffUL) | (t & 0x0f) | ((st << 4) & 0x0f0) 228 | (virt?0x0200:0x0); 229 230 _h = end | 0x3ffUL; 231 } 232 233 }; 234 }; 235}; 236 237#endif 238