iPXE
Functions
memblock.h File Reference

Largest memory block. More...

#include <stdint.h>
#include <ipxe/uaccess.h>

Go to the source code of this file.

Functions

 FILE_LICENCE (GPL2_OR_LATER_OR_UBDL)
size_t largest_memblock (userptr_t *start)
 Find largest usable memory region.

Detailed Description

Largest memory block.

Definition in file memblock.h.


Function Documentation

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL  )

Find largest usable memory region.

Return values:
startStart of region
lenLength of region

Definition at line 73 of file memtop_umalloc.c.

References memory_map::count, DBG, EM_MAX_ADDRESS, memory_region::end, get_memmap(), len, max, phys_to_user(), memory_map::regions, memory_region::start, and UNULL.

Referenced by init_eheap(), and initrd_startup().

                                             {
        struct memory_map memmap;
        struct memory_region *region;
        physaddr_t max = EM_MAX_ADDRESS;
        physaddr_t region_start;
        physaddr_t region_end;
        size_t region_len;
        unsigned int i;
        size_t len = 0;

        /* Avoid returning uninitialised data on error */
        *start = UNULL;

        /* Scan through all memory regions */
        get_memmap ( &memmap );
        for ( i = 0 ; i < memmap.count ; i++ ) {
                region = &memmap.regions[i];
                DBG ( "Considering [%llx,%llx)\n", region->start, region->end );

                /* Truncate block to maximum physical address */
                if ( region->start > max ) {
                        DBG ( "...starts after maximum address %lx\n", max );
                        continue;
                }
                region_start = region->start;
                if ( region->end > max ) {
                        DBG ( "...end truncated to maximum address %lx\n", max);
                        region_end = 0; /* =max, given the wraparound */
                } else {
                        region_end = region->end;
                }
                region_len = ( region_end - region_start );

                /* Use largest block */
                if ( region_len > len ) {
                        DBG ( "...new best block found\n" );
                        *start = phys_to_user ( region_start );
                        len = region_len;
                }
        }

        return len;
}