efi_umalloc.c
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 FILE_LICENCE ( GPL2_OR_LATER );
00020
00021 #include <assert.h>
00022 #include <gpxe/umalloc.h>
00023 #include <gpxe/efi/efi.h>
00024
00025
00026
00027
00028
00029
00030
00031
00032 #define UNOWHERE ( ~UNULL )
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044 static userptr_t efi_urealloc ( userptr_t old_ptr, size_t new_size ) {
00045 EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
00046 EFI_PHYSICAL_ADDRESS phys_addr;
00047 unsigned int new_pages, old_pages;
00048 userptr_t new_ptr = UNOWHERE;
00049 size_t old_size;
00050 EFI_STATUS efirc;
00051
00052
00053
00054
00055 if ( new_size ) {
00056 new_pages = ( EFI_SIZE_TO_PAGES ( new_size ) + 1 );
00057 if ( ( efirc = bs->AllocatePages ( AllocateAnyPages,
00058 EfiBootServicesData,
00059 new_pages,
00060 &phys_addr ) ) != 0 ) {
00061 DBG ( "EFI could not allocate %d pages: %s\n",
00062 new_pages, efi_strerror ( efirc ) );
00063 return UNULL;
00064 }
00065 assert ( phys_addr != 0 );
00066 new_ptr = phys_to_user ( phys_addr + EFI_PAGE_SIZE );
00067 copy_to_user ( new_ptr, -EFI_PAGE_SIZE,
00068 &new_size, sizeof ( new_size ) );
00069 DBG ( "EFI allocated %d pages at %llx\n",
00070 new_pages, phys_addr );
00071 }
00072
00073
00074
00075
00076
00077
00078 if ( old_ptr && ( old_ptr != UNOWHERE ) ) {
00079 copy_from_user ( &old_size, old_ptr, -EFI_PAGE_SIZE,
00080 sizeof ( old_size ) );
00081 memcpy_user ( new_ptr, 0, old_ptr, 0,
00082 ( (old_size < new_size) ? old_size : new_size ));
00083 old_pages = ( EFI_SIZE_TO_PAGES ( old_size ) + 1 );
00084 phys_addr = user_to_phys ( old_ptr, -EFI_PAGE_SIZE );
00085 if ( ( efirc = bs->FreePages ( phys_addr, old_pages ) ) != 0 ){
00086 DBG ( "EFI could not free %d pages at %llx: %s\n",
00087 old_pages, phys_addr, efi_strerror ( efirc ) );
00088
00089
00090
00091 }
00092 DBG ( "EFI freed %d pages at %llx\n", old_pages, phys_addr );
00093 }
00094
00095 return new_ptr;
00096 }
00097
00098 PROVIDE_UMALLOC ( efi, urealloc, efi_urealloc );