iPXE
memmap.h
Go to the documentation of this file.
1#ifndef _IPXE_MEMMAP_H
2#define _IPXE_MEMMAP_H
3
4/** @file
5 *
6 * System memory map
7 *
8 */
9
10FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
11FILE_SECBOOT ( PERMITTED );
12
13#include <stddef.h>
14#include <stdint.h>
15#include <ipxe/api.h>
16#include <ipxe/tables.h>
17#include <config/ioapi.h>
18
19/**
20 * Calculate static inline memory map API function name
21 *
22 * @v _prefix Subsystem prefix
23 * @v _api_func API function
24 * @ret _subsys_func Subsystem API function
25 */
26#define MEMMAP_INLINE( _subsys, _api_func ) \
27 SINGLE_API_INLINE ( MEMMAP_PREFIX_ ## _subsys, _api_func )
28
29/**
30 * Provide a memory map API implementation
31 *
32 * @v _prefix Subsystem prefix
33 * @v _api_func API function
34 * @v _func Implementing function
35 */
36#define PROVIDE_MEMMAP( _subsys, _api_func, _func ) \
37 PROVIDE_SINGLE_API ( MEMMAP_PREFIX_ ## _subsys, _api_func, _func )
38
39/**
40 * Provide a static inline memory map API implementation
41 *
42 * @v _prefix Subsystem prefix
43 * @v _api_func API function
44 */
45#define PROVIDE_MEMMAP_INLINE( _subsys, _api_func ) \
46 PROVIDE_SINGLE_API_INLINE ( MEMMAP_PREFIX_ ## _subsys, _api_func )
47
48/** A memory region descriptor */
50 /** Minimum address in region */
52 /** Maximum address in region */
54 /** Region flags */
55 unsigned int flags;
56 /** Region name (for debug messages) */
57 const char *name;
58};
59
60#define MEMMAP_FL_MEMORY 0x0001 /**< Contains memory */
61#define MEMMAP_FL_RESERVED 0x0002 /**< Is reserved */
62#define MEMMAP_FL_USED 0x0004 /**< Is in use by iPXE */
63#define MEMMAP_FL_INACCESSIBLE 0x0008 /**< Outside of addressable range */
64
65/**
66 * Initialise memory region descriptor
67 *
68 * @v min Minimum address
69 * @v region Region descriptor to fill in
70 */
71static inline __attribute__ (( always_inline )) void
73
74 region->min = min;
75 region->max = ~( ( uint64_t ) 0 );
76 region->flags = 0;
77 region->name = NULL;
78}
79
80/**
81 * Check if memory region is usable
82 *
83 * @v region Region descriptor
84 * @ret is_usable Memory region is usable
85 */
86static inline __attribute__ (( always_inline )) int
87memmap_is_usable ( const struct memmap_region *region ) {
88
89 return ( region->flags == MEMMAP_FL_MEMORY );
90}
91
92/**
93 * Get remaining size of memory region (from the described address upwards)
94 *
95 * @v region Region descriptor
96 * @ret size Size of memory region
97 */
98static inline __attribute__ (( always_inline )) uint64_t
99memmap_size ( const struct memmap_region *region ) {
100
101 /* Calculate size, assuming overflow is known to be impossible */
102 return ( region->max - region->min + 1 );
103}
104
105/** An in-use memory region */
107 /** Region name */
108 const char *name;
109 /** Start address */
111 /** Length of region */
112 size_t size;
113};
114
115/** In-use memory region table */
116#define USED_REGIONS __table ( struct used_region, "used_regions" )
117
118/** Declare an in-use memory region */
119#define __used_region __table_entry ( USED_REGIONS, 01 )
120
121/* Include all architecture-independent ACPI API headers */
122#include <ipxe/null_memmap.h>
123#include <ipxe/fdtmem.h>
124
125/* Include all architecture-dependent ACPI API headers */
126#include <bits/memmap.h>
127
128/**
129 * Describe memory region from system memory map
130 *
131 * @v min Minimum address
132 * @v hide Hide in-use regions from the memory map
133 * @v region Region descriptor to fill in
134 */
135void memmap_describe ( uint64_t min, int hide, struct memmap_region *region );
136
137/**
138 * Synchronise in-use regions with the externally visible system memory map
139 *
140 * In environments such as x86 BIOS, we need to patch the global
141 * system memory map to hide our in-use regions, since there is no
142 * other way to communicate this information to external code.
143 */
144void memmap_sync ( void );
145
146/**
147 * Update an in-use memory region
148 *
149 * @v used In-use memory region
150 * @v start Start address
151 * @v size Length of region
152 */
153static inline __attribute__ (( always_inline )) void
154memmap_use ( struct used_region *used, physaddr_t start, size_t size ) {
155
156 /* Record region */
157 used->start = start;
158 used->size = size;
159
160 /* Synchronise externally visible memory map */
161 memmap_sync();
162}
163
164/**
165 * Iterate over memory regions from a given starting address
166 *
167 * @v region Region descriptor
168 * @v start Starting address
169 * @v hide Hide in-use regions from the memory map
170 */
171#define for_each_memmap_from( region, start, hide ) \
172 for ( (region)->min = (start), (region)->max = 0 ; \
173 ( ( ( (region)->max + 1 ) != 0 ) && \
174 ( memmap_describe ( (region)->min, (hide), \
175 (region) ), 1 ) ) ; \
176 (region)->min = ( (region)->max + 1 ) )
177
178/**
179 * Iterate over memory regions
180 *
181 * @v region Region descriptor
182 * @v hide Hide in-use regions from the memory map
183 */
184#define for_each_memmap( region, hide ) \
185 for_each_memmap_from ( (region), 0, (hide) )
186
187#define DBG_MEMMAP_IF( level, region ) do { \
188 const char *name = (region)->name; \
189 unsigned int flags = (region)->flags; \
190 \
191 DBG_IF ( level, "MEMMAP (%s%s%s%s) [%#08llx,%#08llx]%s%s\n", \
192 ( ( flags & MEMMAP_FL_MEMORY ) ? "M" : "-" ), \
193 ( ( flags & MEMMAP_FL_RESERVED ) ? "R" : "-" ), \
194 ( ( flags & MEMMAP_FL_USED ) ? "U" : "-" ), \
195 ( ( flags & MEMMAP_FL_INACCESSIBLE ) ? "X" : "-" ), \
196 ( ( unsigned long long ) (region)->min ), \
197 ( ( unsigned long long ) (region)->max ), \
198 ( name ? " " : "" ), ( name ? name : "" ) ); \
199 } while ( 0 )
200
201#define DBGC_MEMMAP_IF( level, id, ... ) do { \
202 DBG_AC_IF ( level, id ); \
203 DBG_MEMMAP_IF ( level, __VA_ARGS__ ); \
204 DBG_DC_IF ( level ); \
205 } while ( 0 )
206
207#define DBGC_MEMMAP( ... ) DBGC_MEMMAP_IF ( LOG, ##__VA_ARGS__ )
208#define DBGC2_MEMMAP( ... ) DBGC_MEMMAP_IF ( EXTRA, ##__VA_ARGS__ )
209#define DBGCP_MEMMAP( ... ) DBGC_MEMMAP_IF ( PROFILE, ##__VA_ARGS__ )
210
211/**
212 * Dump system memory map (for debugging)
213 *
214 * @v hide Hide in-use regions from the memory map
215 */
216static inline void memmap_dump_all ( int hide ) {
217 struct memmap_region region;
218
219 /* Do nothing unless debugging is enabled */
220 if ( ! DBG_LOG )
221 return;
222
223 /* Describe all memory regions */
224 DBGC ( &memmap_describe, "MEMMAP with in-use regions %s:\n",
225 ( hide ? "hidden" : "ignored" ) );
226 for_each_memmap ( &region, hide )
227 DBGC_MEMMAP ( &memmap_describe, &region );
228}
229
230extern void memmap_update ( struct memmap_region *region, uint64_t start,
231 uint64_t size, unsigned int flags,
232 const char *name );
233extern void memmap_update_used ( struct memmap_region *region );
234extern size_t memmap_largest ( physaddr_t *start );
235
236#endif /* _IPXE_MEMMAP_H */
#define NULL
NULL pointer (VOID *)
Definition Base.h:322
iPXE internal APIs
unsigned long physaddr_t
Definition stdint.h:20
unsigned long long uint64_t
Definition stdint.h:13
x86-specific system memory map API implementations
const char * name
Definition ath9k_hw.c:1986
#define min(x, y)
Definition ath.h:36
uint8_t flags
Flags.
Definition ena.h:7
Flattened Device Tree memory map.
#define DBGC(...)
Definition compiler.h:505
#define DBG_LOG
Definition compiler.h:317
uint32_t start
Starting offset.
Definition netvsc.h:1
uint16_t size
Buffer size.
Definition dwmac.h:3
#define FILE_LICENCE(_licence)
Declare a particular licence as applying to a file.
Definition compiler.h:896
#define FILE_SECBOOT(_status)
Declare a file's UEFI Secure Boot permission status.
Definition compiler.h:926
#define __attribute__(x)
Definition compiler.h:10
void memmap_update(struct memmap_region *region, uint64_t start, uint64_t size, unsigned int flags, const char *name)
Update memory region descriptor.
Definition memmap.c:47
static int memmap_is_usable(const struct memmap_region *region)
Check if memory region is usable.
Definition memmap.h:87
#define MEMMAP_FL_MEMORY
Contains memory.
Definition memmap.h:60
void memmap_describe(uint64_t min, int hide, struct memmap_region *region)
Describe memory region from system memory map.
Definition null_memmap.h:29
size_t memmap_largest(physaddr_t *start)
Find largest usable memory region.
Definition memmap.c:120
static void memmap_use(struct used_region *used, physaddr_t start, size_t size)
Update an in-use memory region.
Definition memmap.h:154
static uint64_t memmap_size(const struct memmap_region *region)
Get remaining size of memory region (from the described address upwards)
Definition memmap.h:99
#define for_each_memmap(region, hide)
Iterate over memory regions.
Definition memmap.h:184
void memmap_sync(void)
Synchronise in-use regions with the externally visible system memory map.
Definition fdtmem.h:26
static void memmap_dump_all(int hide)
Dump system memory map (for debugging)
Definition memmap.h:216
static void memmap_init(uint64_t min, struct memmap_region *region)
Initialise memory region descriptor.
Definition memmap.h:72
void memmap_update_used(struct memmap_region *region)
Update memory region descriptor based on all in-use memory regions.
Definition memmap.c:104
#define DBGC_MEMMAP(...)
Definition memmap.h:207
I/O API configuration.
Null system memory map API.
A memory region descriptor.
Definition memmap.h:49
const char * name
Region name (for debug messages)
Definition memmap.h:57
uint64_t min
Minimum address in region.
Definition memmap.h:51
unsigned int flags
Region flags.
Definition memmap.h:55
uint64_t max
Maximum address in region.
Definition memmap.h:53
An in-use memory region.
Definition memmap.h:106
const char * name
Region name.
Definition memmap.h:108
size_t size
Length of region.
Definition memmap.h:112
physaddr_t start
Start address.
Definition memmap.h:110
Linker tables.