1 /**
2 * \file
3 * Memory description functions.
4 * \ingroup l4_api
5 */
6 /*
7 * (c) 2007-2009 Adam Lackorzynski <adam@os.inf.tu-dresden.de>,
8 * Alexander Warg <warg@os.inf.tu-dresden.de>
9 * economic rights: Technische Universität Dresden (Germany)
10 *
11 * This file is part of TUD:OS and distributed under the terms of the
12 * GNU General Public License 2.
13 * Please see the COPYING-GPL-2 file for details.
14 *
15 * As a special exception, you may use this file as part of a free software
16 * library without restriction. Specifically, if other files instantiate
17 * templates or use macros or inline functions from this file, or you compile
18 * this file and link it with other files to produce an executable, this
19 * file does not by itself cause the resulting executable to be covered by
20 * the GNU General Public License. This exception does not however
21 * invalidate any other reasons why the executable file might be covered by
22 * the GNU General Public License.
23 */
24 #ifndef __L4SYS__MEMDESC_H__
25 #define __L4SYS__MEMDESC_H__
26
27 #include <l4/sys/kip.h>
28
29 /**
30 * \defgroup l4_kip_memdesc_api Memory descriptors (C version)
31 * \ingroup l4_kip_api
32 * C Interface for KIP memory descriptors.
33 *
34 * \includefile{l4/sys/memdesc.h}
35 *
36 * This module contains the C functions to access the memory descriptor in the
37 * kernel interface page (KIP).
38 */
39
40 /**
41 * Type of a memory descriptor.
42 * \ingroup l4_kip_memdesc_api
43 */
44 enum l4_mem_type_t
45 {
46 l4_mem_type_undefined = 0x0, ///< Undefined, unused descriptor
47 l4_mem_type_conventional = 0x1, ///< Conventional memory
48 l4_mem_type_reserved = 0x2, ///< Reserved memory for kernel etc.
49 l4_mem_type_dedicated = 0x3, ///< Dedicated memory (some device memory)
50 l4_mem_type_shared = 0x4, ///< Shared memory (not implemented)
51
52 l4_mem_type_info = 0xd, ///< Info from the boot loader
53 l4_mem_type_bootloader = 0xe, ///< Memory owned by the boot loader
54 l4_mem_type_archspecific = 0xf, ///< Architecture specific memory (e.g., ACPI memory)
55 };
56
57 /**
58 * Memory sub types for l4_mem_type_info descriptors
59 * \ingroup l4_kip_memdesc_api
60 */
61 enum l4_mem_info_sub_type_t
62 {
63 l4_mem_info_acpi_rsdp = 0 /**< Physical address of the ACPI root pointer. */
64 };
65
66
67 /**
68 * Memory descriptor data structure.
69 * \ingroup l4_kip_memdesc_api
70 *
71 * \note This data type is opaque, and must be accessed by the accessor
72 * functions defined in this module.
73 */
74 typedef struct l4_kernel_info_mem_desc_t
75 {
76 /// \internal
77 l4_umword_t l;
78 /// \internal
79 l4_umword_t h;
80 } l4_kernel_info_mem_desc_t;
81
82
83 /**
84 * Get pointer to memory descriptors from KIP.
85 * \ingroup l4_kip_memdesc_api
86 */
87 L4_INLINE
88 l4_kernel_info_mem_desc_t *
89 l4_kernel_info_get_mem_descs(l4_kernel_info_t *kip) L4_NOTHROW;
90
91 /**
92 * Get number of memory descriptors in KIP.
93 * \ingroup l4_kip_memdesc_api
94 *
95 * \return Number of memory descriptors.
96 */
97 L4_INLINE
98 unsigned
99 l4_kernel_info_get_num_mem_descs(l4_kernel_info_t *kip) L4_NOTHROW;
100
101 /**
102 * Populate a memory descriptor.
103 * \ingroup l4_kip_memdesc_api
104 *
105 * \param md Pointer to memory descriptor
106 * \param start Start of region
107 * \param end End of region
108 * \param type Type of region
109 * \param virt 1 if virtual region, 0 if physical region
110 * \param sub_type Sub type.
111 */
112 L4_INLINE
113 void
114 l4_kernel_info_set_mem_desc(l4_kernel_info_mem_desc_t *md,
115 l4_addr_t start,
116 l4_addr_t end,
117 unsigned type,
118 unsigned virt,
119 unsigned sub_type) L4_NOTHROW;
120
121 /**
122 * Get start address of the region described by the memory descriptor.
123 * \ingroup l4_kip_memdesc_api
124 *
125 * \return Start address.
126 */
127 L4_INLINE
128 l4_umword_t
129 l4_kernel_info_get_mem_desc_start(l4_kernel_info_mem_desc_t *md) L4_NOTHROW;
130
131 /**
132 * Get end address of the region described by the memory descriptor.
133 * \ingroup l4_kip_memdesc_api
134 *
135 * \return End address.
136 */
137 L4_INLINE
138 l4_umword_t
139 l4_kernel_info_get_mem_desc_end(l4_kernel_info_mem_desc_t *md) L4_NOTHROW;
140
141 /**
142 * Get type of the memory region.
143 * \ingroup l4_kip_memdesc_api
144 *
145 * \return Type of the region (see #l4_mem_type_t).
146 */
147 L4_INLINE
148 l4_umword_t
149 l4_kernel_info_get_mem_desc_type(l4_kernel_info_mem_desc_t *md) L4_NOTHROW;
150
151 /**
152 * Get sub-type of memory region.
153 * \ingroup l4_kip_memdesc_api
154 *
155 * \return Sub-type.
156 *
157 * The sub type is defined for architecture specific memory descriptors
158 * (see #l4_mem_type_archspecific) and has architecture specific meaning.
159 */
160 L4_INLINE
161 l4_umword_t
162 l4_kernel_info_get_mem_desc_subtype(l4_kernel_info_mem_desc_t *md) L4_NOTHROW;
163
164 /**
165 * Get virtual flag of the memory descriptor.
166 * \ingroup l4_kip_memdesc_api
167 *
168 * \return 1 if region is virtual memory, 0 if region is physical memory
169 */
170 L4_INLINE
171 l4_umword_t
172 l4_kernel_info_get_mem_desc_is_virtual(l4_kernel_info_mem_desc_t *md) L4_NOTHROW;
173
174 /*************************************************************************
175 * Implementations
176 *************************************************************************/
177
178 L4_INLINE
179 l4_kernel_info_mem_desc_t *
l4_kernel_info_get_mem_descs(l4_kernel_info_t * kip)180 l4_kernel_info_get_mem_descs(l4_kernel_info_t *kip) L4_NOTHROW
181 {
182 return (l4_kernel_info_mem_desc_t *)(((l4_addr_t)kip)
183 + (kip->mem_info >> (sizeof(l4_umword_t) * 4)));
184 }
185
186 L4_INLINE
187 unsigned
l4_kernel_info_get_num_mem_descs(l4_kernel_info_t * kip)188 l4_kernel_info_get_num_mem_descs(l4_kernel_info_t *kip) L4_NOTHROW
189 {
190 return kip->mem_info & ((1UL << (sizeof(l4_umword_t)*4)) -1);
191 }
192
193 L4_INLINE
194 void
l4_kernel_info_set_mem_desc(l4_kernel_info_mem_desc_t * md,l4_addr_t start,l4_addr_t end,unsigned type,unsigned virt,unsigned sub_type)195 l4_kernel_info_set_mem_desc(l4_kernel_info_mem_desc_t *md,
196 l4_addr_t start,
197 l4_addr_t end,
198 unsigned type,
199 unsigned virt,
200 unsigned sub_type) L4_NOTHROW
201 {
202 md->l = (start & ~0x3ffUL) | (type & 0x0f) | ((sub_type << 4) & 0x0f0)
203 | (virt ? 0x200 : 0x0);
204 md->h = end;
205 }
206
207
208 L4_INLINE
209 l4_umword_t
l4_kernel_info_get_mem_desc_start(l4_kernel_info_mem_desc_t * md)210 l4_kernel_info_get_mem_desc_start(l4_kernel_info_mem_desc_t *md) L4_NOTHROW
211 {
212 return md->l & ~0x3ffUL;
213 }
214
215 L4_INLINE
216 l4_umword_t
l4_kernel_info_get_mem_desc_end(l4_kernel_info_mem_desc_t * md)217 l4_kernel_info_get_mem_desc_end(l4_kernel_info_mem_desc_t *md) L4_NOTHROW
218 {
219 return md->h | 0x3ffUL;
220 }
221
222 L4_INLINE
223 l4_umword_t
l4_kernel_info_get_mem_desc_type(l4_kernel_info_mem_desc_t * md)224 l4_kernel_info_get_mem_desc_type(l4_kernel_info_mem_desc_t *md) L4_NOTHROW
225 {
226 return md->l & 0xf;
227 }
228
229 L4_INLINE
230 l4_umword_t
l4_kernel_info_get_mem_desc_subtype(l4_kernel_info_mem_desc_t * md)231 l4_kernel_info_get_mem_desc_subtype(l4_kernel_info_mem_desc_t *md) L4_NOTHROW
232 {
233 return (md->l & 0xf0) >> 4;
234 }
235
236 L4_INLINE
237 l4_umword_t
l4_kernel_info_get_mem_desc_is_virtual(l4_kernel_info_mem_desc_t * md)238 l4_kernel_info_get_mem_desc_is_virtual(l4_kernel_info_mem_desc_t *md) L4_NOTHROW
239 {
240 return md->l & 0x200;
241 }
242
243 #endif /* ! __L4SYS__MEMDESC_H__ */
244