#include <string.h>
#include <errno.h>
#include <ipxe/uaccess.h>
-#include <ipxe/io.h>
+#include <ipxe/memmap.h>
#include <ipxe/errortab.h>
#include <ipxe/segment.h>
* @ret rc Return status code
*/
int prep_segment ( void *segment, size_t filesz, size_t memsz ) {
- struct memory_map memmap;
+ struct memmap_region region;
physaddr_t start = virt_to_phys ( segment );
physaddr_t mid = ( start + filesz );
physaddr_t end = ( start + memsz );
- unsigned int i;
+ physaddr_t last;
- DBG ( "Preparing segment [%lx,%lx,%lx)\n", start, mid, end );
+ DBGC ( ®ion, "SEGMENT [%#08lx,%#08lx,%#08lx)\n", start, mid, end );
- /* Sanity check */
+ /* Check for malformed lengths */
if ( filesz > memsz ) {
- DBG ( "Insane segment [%lx,%lx,%lx)\n", start, mid, end );
+ DBGC ( ®ion, "SEGMENT [%#08lx,%#08lx,%#08lx) is "
+ "malformed\n", start, mid, end );
return -EINVAL;
}
- /* Get a fresh memory map. This allows us to automatically
- * avoid treading on any regions that Etherboot is currently
- * editing out of the memory map.
- */
- get_memmap ( &memmap );
+ /* Zero-length segments do not need a memory region */
+ if ( memsz == 0 )
+ return 0;
+ last = ( end - 1 );
- /* Look for a suitable memory region */
- for ( i = 0 ; i < memmap.count ; i++ ) {
- if ( ( start >= memmap.regions[i].start ) &&
- ( end <= memmap.regions[i].end ) ) {
- /* Found valid region: zero bss and return */
- memset ( ( segment + filesz ), 0, ( memsz - filesz ) );
- return 0;
- }
+ /* Check for address space overflow */
+ if ( last < start ) {
+ DBGC ( ®ion, "SEGMENT [%#08lx,%#08lx,%#08lx) wraps "
+ "around\n", start, mid, end );
+ return -EINVAL;
+ }
+
+ /* Describe region containing this segment */
+ memmap_describe ( start, 1, ®ion );
+ memmap_dump ( ®ion );
+
+ /* Fail unless region is usable and sufficiently large */
+ if ( ( ! memmap_is_usable ( ®ion ) ) || ( region.last < last ) ) {
+ DBGC ( ®ion, "SEGMENT [%#08lx,%#08lx,%#08lx) does not fit "
+ "into available memory\n", start, mid, end );
+ return -ERANGE_SEGMENT;
}
- /* No suitable memory region found */
- DBG ( "Segment [%lx,%lx,%lx) does not fit into available memory\n",
- start, mid, end );
- return -ERANGE_SEGMENT;
+ /* Found valid region: zero bss and return */
+ memset ( ( segment + filesz ), 0, ( memsz - filesz ) );
+ return 0;
}