[memmap] Allow explicit colour selection for memory map debug messages

Provide DBGC_MEMMAP() as a replacement for memmap_dump(), allowing the
colour used to match other messages within the same message group.

Retain a dedicated colour for output from memmap_dump_all(), on the
basis that it is generally most useful to visually compare full memory
dumps against previous full memory dumps.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
This commit is contained in:
Michael Brown
2025-05-25 12:06:53 +01:00
parent 8d88870da5
commit 09140ab2c1
7 changed files with 36 additions and 33 deletions

View File

@@ -80,7 +80,7 @@ __asmcall void relocate ( struct i386_all_regs *ix86 ) {
* away with using just 32-bit arithmetic after this
* stage.
*/
memmap_dump ( &region );
DBGC_MEMMAP ( &region, &region );
if ( region.min > max ) {
DBGC ( &region, "...starts after max=%#08lx\n", max );
break;

View File

@@ -120,7 +120,7 @@ static void multiboot_build_memmap ( struct image *image,
/* Ignore any non-memory regions */
if ( ! ( region.flags & MEMMAP_FL_MEMORY ) )
continue;
memmap_dump ( &region );
DBGC_MEMMAP ( image, &region );
/* Check Multiboot memory map limit */
if ( ! remaining ) {

View File

@@ -273,7 +273,7 @@ physaddr_t fdtmem_relocate ( struct fdt_header *hdr, physaddr_t max ) {
/* Parse FDT */
if ( ( rc = fdt_parse ( &fdt, hdr, -1UL ) ) != 0 ) {
DBGC ( &region, "FDTMEM could not parse FDT: %s\n",
DBGC ( hdr, "FDTMEM could not parse FDT: %s\n",
strerror ( rc ) );
/* Refuse relocation if we have no FDT */
return old;
@@ -282,7 +282,7 @@ physaddr_t fdtmem_relocate ( struct fdt_header *hdr, physaddr_t max ) {
/* Determine required length */
len = fdtmem_len ( &fdt );
assert ( len > 0 );
DBGC ( &region, "FDTMEM requires %#zx + %#zx => %#zx bytes for "
DBGC ( hdr, "FDTMEM requires %#zx + %#zx => %#zx bytes for "
"relocation\n", memsz, fdt.len, len );
/* Construct memory map and choose a relocation address */
@@ -297,7 +297,7 @@ physaddr_t fdtmem_relocate ( struct fdt_header *hdr, physaddr_t max ) {
next = ( region.max + 1 );
/* Dump region descriptor (for debugging) */
memmap_dump ( &region );
DBGC_MEMMAP ( hdr, &region );
assert ( region.max >= region.min );
/* Use highest possible region */
@@ -313,7 +313,7 @@ physaddr_t fdtmem_relocate ( struct fdt_header *hdr, physaddr_t max ) {
}
}
DBGC ( &region, "FDTMEM relocating %#08lx => [%#08lx,%#08lx]\n",
DBGC ( hdr, "FDTMEM relocating %#08lx => [%#08lx,%#08lx]\n",
old, new, ( ( physaddr_t ) ( new + len - 1 ) ) );
return new;
}

View File

@@ -127,7 +127,7 @@ size_t memmap_largest ( physaddr_t *start ) {
*start = 0;
largest = 0;
for_each_memmap ( &region, 1 ) {
memmap_dump ( &region );
DBGC_MEMMAP ( &region, &region );
if ( ! memmap_is_usable ( &region ) )
continue;
size = memmap_size ( &region );

View File

@@ -102,7 +102,7 @@ static int lkrn_ram ( struct image *image, struct lkrn_context *ctx ) {
/* Locate start of RAM */
for_each_memmap ( &region, 0 ) {
memmap_dump ( &region );
DBGC_MEMMAP ( image, &region );
if ( ! ( region.flags & MEMMAP_FL_MEMORY ) )
continue;
ctx->ram = region.min;

View File

@@ -65,11 +65,11 @@ int prep_segment ( void *segment, size_t filesz, size_t memsz ) {
physaddr_t end = ( start + memsz );
physaddr_t max;
DBGC ( &region, "SEGMENT [%#08lx,%#08lx,%#08lx)\n", start, mid, end );
DBGC ( segment, "SEGMENT [%#08lx,%#08lx,%#08lx)\n", start, mid, end );
/* Check for malformed lengths */
if ( filesz > memsz ) {
DBGC ( &region, "SEGMENT [%#08lx,%#08lx,%#08lx) is "
DBGC ( segment, "SEGMENT [%#08lx,%#08lx,%#08lx) is "
"malformed\n", start, mid, end );
return -EINVAL;
}
@@ -81,18 +81,18 @@ int prep_segment ( void *segment, size_t filesz, size_t memsz ) {
/* Check for address space overflow */
if ( max < start ) {
DBGC ( &region, "SEGMENT [%#08lx,%#08lx,%#08lx) wraps "
DBGC ( segment, "SEGMENT [%#08lx,%#08lx,%#08lx) wraps "
"around\n", start, mid, end );
return -EINVAL;
}
/* Describe region containing this segment */
memmap_describe ( start, 1, &region );
memmap_dump ( &region );
DBGC_MEMMAP ( segment, &region );
/* Fail unless region is usable and sufficiently large */
if ( ( ! memmap_is_usable ( &region ) ) || ( region.max < max ) ) {
DBGC ( &region, "SEGMENT [%#08lx,%#08lx,%#08lx) does not fit "
DBGC ( segment, "SEGMENT [%#08lx,%#08lx,%#08lx) does not fit "
"into available memory\n", start, mid, end );
return -ERANGE_SEGMENT;
}

View File

@@ -183,26 +183,29 @@ memmap_use ( struct used_region *used, physaddr_t start, size_t size ) {
#define for_each_memmap( region, hide ) \
for_each_memmap_from ( (region), 0, (hide) )
#define DBG_MEMMAP_IF( level, region ) do { \
const char *name = (region)->name; \
unsigned int flags = (region)->flags; \
\
DBG_IF ( level, "MEMMAP (%s%s%s%s) [%#08llx,%#08llx]%s%s\n", \
( ( flags & MEMMAP_FL_MEMORY ) ? "M" : "-" ), \
( ( flags & MEMMAP_FL_RESERVED ) ? "R" : "-" ), \
( ( flags & MEMMAP_FL_USED ) ? "U" : "-" ), \
( ( flags & MEMMAP_FL_INACCESSIBLE ) ? "X" : "-" ), \
( ( unsigned long long ) (region)->min ), \
( ( unsigned long long ) (region)->max ), \
( name ? " " : "" ), ( name ? name : "" ) ); \
} while ( 0 )
/**
* Dump memory region descriptor (for debugging)
*
* @v region Region descriptor
*/
static inline void memmap_dump ( const struct memmap_region *region ) {
const char *name = region->name;
unsigned int flags = region->flags;
#define DBGC_MEMMAP_IF( level, id, ... ) do { \
DBG_AC_IF ( level, id ); \
DBG_MEMMAP_IF ( level, __VA_ARGS__ ); \
DBG_DC_IF ( level ); \
} while ( 0 )
/* Dump region information */
DBGC ( region, "MEMMAP (%s%s%s%s) [%#08llx,%#08llx]%s%s\n",
( ( flags & MEMMAP_FL_MEMORY ) ? "M" : "-" ),
( ( flags & MEMMAP_FL_RESERVED ) ? "R" : "-" ),
( ( flags & MEMMAP_FL_USED ) ? "U" : "-" ),
( ( flags & MEMMAP_FL_INACCESSIBLE ) ? "X" : "-" ),
( ( unsigned long long ) region->min ),
( ( unsigned long long ) region->max ),
( name ? " " : "" ), ( name ? name : "" ) );
}
#define DBGC_MEMMAP( ... ) DBGC_MEMMAP_IF ( LOG, ##__VA_ARGS__ )
#define DBGC2_MEMMAP( ... ) DBGC_MEMMAP_IF ( EXTRA, ##__VA_ARGS__ )
#define DBGCP_MEMMAP( ... ) DBGC_MEMMAP_IF ( PROFILE, ##__VA_ARGS__ )
/**
* Dump system memory map (for debugging)
@@ -217,10 +220,10 @@ static inline void memmap_dump_all ( int hide ) {
return;
/* Describe all memory regions */
DBGC ( &region, "MEMMAP with in-use regions %s:\n",
DBGC ( &memmap_describe, "MEMMAP with in-use regions %s:\n",
( hide ? "hidden" : "ignored" ) );
for_each_memmap ( &region, hide )
memmap_dump ( &region );
DBGC_MEMMAP ( &memmap_describe, &region );
}
extern void memmap_update ( struct memmap_region *region, uint64_t start,