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