iPXE
Macros | Functions
fdtmem.h File Reference

Flattened Device Tree memory map. More...

#include <stdint.h>

Go to the source code of this file.

Macros

#define MEMMAP_PREFIX_fdt   __fdt_
 

Functions

 FILE_LICENCE (GPL2_OR_LATER_OR_UBDL)
 
static __attribute__ ((always_inline)) void MEMMAP_INLINE(fdt
 Synchronise in-use regions with the externally visible system memory map. More...
 
static memmap_sync (void)
 Synchronise in-use regions with the externally visible system memory map. More...
 
physaddr_t fdtmem_relocate (struct fdt_header *hdr, physaddr_t max)
 Find a relocation address for iPXE. More...
 
int fdtmem_register (struct fdt_header *hdr, physaddr_t max)
 Copy and register system device tree. More...
 

Detailed Description

Flattened Device Tree memory map.

Definition in file fdtmem.h.

Macro Definition Documentation

◆ MEMMAP_PREFIX_fdt

#define MEMMAP_PREFIX_fdt   __fdt_

Definition at line 17 of file fdtmem.h.

Function Documentation

◆ FILE_LICENCE()

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL  )

◆ __attribute__()

static __attribute__ ( (always_inline)  )
inlinestatic

Synchronise in-use regions with the externally visible system memory map.

◆ memmap_sync()

static memmap_sync ( void  )

Synchronise in-use regions with the externally visible system memory map.

In environments such as x86 BIOS, we need to patch the global system memory map to hide our in-use regions, since there is no other way to communicate this information to external code.

Definition at line 25 of file fdtmem.h.

25  {
26  /* Nothing to do */
27 }

◆ fdtmem_relocate()

physaddr_t fdtmem_relocate ( struct fdt_header hdr,
physaddr_t  max 
)

Find a relocation address for iPXE.

Parameters
hdrFDT header
maxMaximum accessible physical address
Return values
newNew physical address for relocation

Find a suitably aligned address towards the top of existent 32-bit memory to which iPXE may be relocated, along with a copy of the system device tree.

This function may be called very early in initialisation, before .data is writable or .bss has been zeroed. Neither this function nor any function that it calls may write to or rely upon the zero initialisation of any static variables.

Definition at line 264 of file fdtmem.c.

264  {
265  struct fdt fdt;
266  struct memmap_region region;
269  physaddr_t old;
270  physaddr_t new;
271  physaddr_t try;
272  size_t len;
273  int rc;
274 
275  /* Sanity check */
276  assert ( ( max_align & ( max_align - 1 ) ) == 0 );
277 
278  /* Get current physical address */
279  old = virt_to_phys ( _prefix );
280 
281  /* Parse FDT */
282  if ( ( rc = fdt_parse ( &fdt, hdr, -1UL ) ) != 0 ) {
283  DBGC ( hdr, "FDTMEM could not parse FDT: %s\n",
284  strerror ( rc ) );
285  /* Refuse relocation if we have no FDT */
286  return old;
287  }
288 
289  /* Determine required length */
290  len = fdtmem_len ( &fdt );
291  assert ( len > 0 );
292  DBGC ( hdr, "FDTMEM requires %#zx + %#zx => %#zx bytes for "
293  "relocation\n", memsz, fdt.len, len );
294 
295  /* Limit relocation to 32-bit address space
296  *
297  * Devices with only 32-bit DMA addressing are relatively
298  * common even on systems with 64-bit CPUs. Limit relocation
299  * of iPXE to 32-bit address space so that I/O buffers and
300  * other DMA allocations will be accessible by 32-bit devices.
301  */
302  if ( max > FDTMEM_MAX32 )
303  max = FDTMEM_MAX32;
304 
305  /* Construct memory map and choose a relocation address */
306  new = old;
307  for ( addr = 0, next = 1 ; next ; addr = next ) {
308 
309  /* Describe region and in-use memory */
310  fdtmem_describe ( addr, max, &fdt, &region );
311  memmap_update ( &region, old, memsz, MEMMAP_FL_USED, "iPXE" );
312  memmap_update ( &region, virt_to_phys ( hdr ), fdt.len,
313  MEMMAP_FL_RESERVED, "FDT" );
314  next = ( region.max + 1 );
315 
316  /* Dump region descriptor (for debugging) */
317  DBGC_MEMMAP ( hdr, &region );
318  assert ( region.max >= region.min );
319 
320  /* Use highest possible region */
321  if ( memmap_is_usable ( &region ) &&
322  ( ( next == 0 ) || ( next >= len ) ) ) {
323 
324  /* Determine candidate address after alignment */
325  try = ( ( next - len ) & ~( max_align - 1 ) );
326 
327  /* Use this address if within region */
328  if ( try >= addr )
329  new = try;
330  }
331  }
332 
333  DBGC ( hdr, "FDTMEM relocating %#08lx => [%#08lx,%#08lx]\n",
334  old, new, ( ( physaddr_t ) ( new + len - 1 ) ) );
335  return new;
336 }
static int memmap_is_usable(const struct memmap_region *region)
Check if memory region is usable.
Definition: memmap.h:86
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
#define FDTMEM_MAX32
Maximum 32-bit physical address.
Definition: fdtmem.c:66
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
#define max(x, y)
Definition: ath.h:40
static size_t fdtmem_len(struct fdt *fdt)
Get length for copy of iPXE and device tree.
Definition: fdtmem.c:233
size_t len
Length of tree.
Definition: fdt.h:97
int fdt_parse(struct fdt *fdt, struct fdt_header *hdr, size_t max_len)
Parse device tree.
Definition: fdt.c:903
struct golan_inbox_hdr hdr
Message header.
Definition: CIB_PRM.h:28
#define DBGC(...)
Definition: compiler.h:505
int old
Definition: bitops.h:64
#define DBGC_MEMMAP(...)
Definition: memmap.h:206
#define MEMMAP_FL_USED
Is in use by iPXE.
Definition: memmap.h:61
static void fdtmem_describe(uint64_t min, uint64_t max, struct fdt *fdt, struct memmap_region *region)
Describe memory region.
Definition: fdtmem.c:211
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
ring len
Length.
Definition: dwmac.h:231
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
uint32_t addr
Buffer address.
Definition: dwmac.h:20
uint32_t next
Next descriptor address.
Definition: dwmac.h:22
unsigned long physaddr_t
Definition: stdint.h:20
static size_t max_align
Definition: fdtmem.c:55
A device tree.
Definition: fdt.h:88
#define MEMMAP_FL_RESERVED
Is reserved.
Definition: memmap.h:60
static size_t memsz
Definition: fdtmem.c:51
A memory region descriptor.
Definition: memmap.h:48
char _prefix[]
Start address of the iPXE image.

References _prefix, addr, assert(), DBGC, DBGC_MEMMAP, fdt_parse(), fdtmem_describe(), fdtmem_len(), FDTMEM_MAX32, hdr, fdt::len, len, max, memmap_region::max, max_align, MEMMAP_FL_RESERVED, MEMMAP_FL_USED, memmap_is_usable(), memmap_update(), memsz, memmap_region::min, next, old, rc, and strerror().

◆ fdtmem_register()

int fdtmem_register ( struct fdt_header hdr,
physaddr_t  max 
)

Copy and register system device tree.

Parameters
hdrFDT header
maxMaximum accessible physical address
Return values
rcReturn status code

Definition at line 345 of file fdtmem.c.

345  {
346  struct fdt_header *copy;
347  struct fdt fdt;
348  int rc;
349 
350  /* Record maximum accessible physical address */
351  fdtmem_max = max;
352 
353  /* Parse FDT to obtain length */
354  if ( ( rc = fdt_parse ( &fdt, hdr, -1UL ) ) != 0 ) {
355  DBGC ( hdr, "FDTMEM could not parse FDT: %s\n",
356  strerror ( rc ) );
357  return rc;
358  }
359 
360  /* Copy device tree to end of iPXE image */
361  copy = ( ( void * ) _end );
362  memcpy ( copy, hdr, fdt.len );
363 
364  /* Update in-use memory region */
365  memmap_use ( &fdtmem_used, virt_to_phys ( _prefix ),
366  fdtmem_len ( &fdt ) );
367 
368  /* Register copy as system device tree */
369  if ( ( rc = fdt_parse ( &sysfdt, copy, -1UL ) ) != 0 ) {
370  DBGC ( hdr, "FDTMEM could not register FDT: %s\n",
371  strerror ( rc ) );
372  return rc;
373  }
374  assert ( sysfdt.len == fdt.len );
375 
376  /* Dump system memory map (for debugging) */
377  memmap_dump_all ( 1 );
378 
379  return 0;
380 }
static void memmap_use(struct used_region *used, physaddr_t start, size_t size)
Update an in-use memory region.
Definition: memmap.h:153
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
#define max(x, y)
Definition: ath.h:40
static size_t fdtmem_len(struct fdt *fdt)
Get length for copy of iPXE and device tree.
Definition: fdtmem.c:233
size_t len
Length of tree.
Definition: fdt.h:97
int fdt_parse(struct fdt *fdt, struct fdt_header *hdr, size_t max_len)
Parse device tree.
Definition: fdt.c:903
Device tree header.
Definition: fdt.h:18
struct golan_inbox_hdr hdr
Message header.
Definition: CIB_PRM.h:28
#define DBGC(...)
Definition: compiler.h:505
void * memcpy(void *dest, const void *src, size_t len) __nonnull
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
static physaddr_t fdtmem_max
Maximum accessible physical address.
Definition: fdtmem.c:63
char _end[]
End address of the iPXE image.
static void memmap_dump_all(int hide)
Dump system memory map (for debugging)
Definition: memmap.h:215
A device tree.
Definition: fdt.h:88
char _prefix[]
Start address of the iPXE image.
struct fdt sysfdt
The system flattened device tree (if present)
Definition: fdt.c:44

References _end, _prefix, assert(), DBGC, fdt_parse(), fdtmem_len(), fdtmem_max, hdr, fdt::len, max, memcpy(), memmap_dump_all(), memmap_use(), rc, strerror(), and sysfdt.