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 
10 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
11 FILE_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 */
49 struct memmap_region {
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  */
71 static inline __attribute__ (( always_inline )) void
72 memmap_init ( uint64_t min, struct memmap_region *region ) {
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  */
86 static inline __attribute__ (( always_inline )) int
87 memmap_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  */
98 static inline __attribute__ (( always_inline )) uint64_t
99 memmap_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 */
106 struct used_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  */
135 void 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  */
144 void 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  */
153 static inline __attribute__ (( always_inline )) void
154 memmap_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  */
216 static 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 
230 extern void memmap_update ( struct memmap_region *region, uint64_t start,
231  uint64_t size, unsigned int flags,
232  const char *name );
233 extern void memmap_update_used ( struct memmap_region *region );
234 extern size_t memmap_largest ( physaddr_t *start );
235 
236 #endif /* _IPXE_MEMMAP_H */
static int memmap_is_usable(const struct memmap_region *region)
Check if memory region is usable.
Definition: memmap.h:87
#define __attribute__(x)
Definition: compiler.h:10
size_t size
Length of region.
Definition: memmap.h:112
static void memmap_use(struct used_region *used, physaddr_t start, size_t size)
Update an in-use memory region.
Definition: memmap.h:154
const char * name
Definition: ath9k_hw.c:1986
iPXE internal APIs
uint64_t max
Maximum address in region.
Definition: memmap.h:53
uint16_t size
Buffer size.
Definition: dwmac.h:14
Flattened Device Tree memory map.
#define DBGC(...)
Definition: compiler.h:505
#define min(x, y)
Definition: ath.h:36
unsigned long long uint64_t
Definition: stdint.h:13
size_t memmap_largest(physaddr_t *start)
Find largest usable memory region.
Definition: memmap.c:120
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
uint32_t start
Starting offset.
Definition: netvsc.h:12
physaddr_t start
Start address.
Definition: memmap.h:110
void memmap_describe(uint64_t min, int hide, struct memmap_region *region)
Describe memory region from system memory map.
Definition: null_memmap.h:29
#define for_each_memmap(region, hide)
Iterate over memory regions.
Definition: memmap.h:184
FILE_SECBOOT(PERMITTED)
uint8_t flags
Flags.
Definition: ena.h:18
An in-use memory region.
Definition: memmap.h:106
unsigned int flags
Region flags.
Definition: memmap.h:55
const char * name
Region name (for debug messages)
Definition: memmap.h:57
unsigned long physaddr_t
Definition: stdint.h:20
I/O API configuration.
static void memmap_dump_all(int hide)
Dump system memory map (for debugging)
Definition: memmap.h:216
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 MEMMAP_FL_MEMORY
Contains memory.
Definition: memmap.h:60
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
const char * name
Region name.
Definition: memmap.h:108
Linker tables.
uint64_t min
Minimum address in region.
Definition: memmap.h:51
Null system memory map API.
A memory region descriptor.
Definition: memmap.h:49
static void memmap_init(uint64_t min, struct memmap_region *region)
Initialise memory region descriptor.
Definition: memmap.h:72
FILE_LICENCE(GPL2_OR_LATER_OR_UBDL)
#define DBG_LOG
Definition: compiler.h:317
#define NULL
NULL pointer (VOID *)
Definition: Base.h:322
void memmap_sync(void)
Synchronise in-use regions with the externally visible system memory map.
Definition: fdtmem.h:26