176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/*
376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Copyright (C) 2013 Jerry Hoemann <jerry.hoemann@hp.com>
476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *
576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *
676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Application to allocate memory at EFI.  Syntax of command
776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * mimics the EFI Boot Service "AllocatePages."
876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *
976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * See UEFI spec 2.3, Section 6.2.
1076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *
1176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *
1276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
1376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
1476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
1576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
1676d05dc695b06c4e987bb8078f78032441e1430cGreg HartmanFS1:\> memmap
1776d05dc695b06c4e987bb8078f78032441e1430cGreg HartmanType      Start            End              #pages             Attributes
1876d05dc695b06c4e987bb8078f78032441e1430cGreg HartmanBS_Code   0000000000000000-0000000000000FFF 0000000000000001 000000000000000F
1976d05dc695b06c4e987bb8078f78032441e1430cGreg HartmanAvailable 0000000000001000-000000000008DFFF 000000000000008D 000000000000000F
2076d05dc695b06c4e987bb8078f78032441e1430cGreg HartmanReserved  000000000008E000-000000000008FFFF 0000000000000002 000000000000000F
2176d05dc695b06c4e987bb8078f78032441e1430cGreg HartmanAvailable 0000000000090000-000000000009FFFF 0000000000000010 000000000000000F
2276d05dc695b06c4e987bb8078f78032441e1430cGreg HartmanAvailable 0000000000100000-000000000FFFFFFF 000000000000FF00 000000000000000F
2376d05dc695b06c4e987bb8078f78032441e1430cGreg HartmanBS_Code   0000000010000000-0000000010061FFF 0000000000000062 000000000000000F
2476d05dc695b06c4e987bb8078f78032441e1430cGreg HartmanAvailable 0000000010062000-000000005CDFFFFF 000000000004CD9E 000000000000000F
2576d05dc695b06c4e987bb8078f78032441e1430cGreg HartmanACPI_NVS  000000005CE00000-000000005DDFFFFF 0000000000001000 000000000000000F
2676d05dc695b06c4e987bb8078f78032441e1430cGreg HartmanBS_Data   000000005DE00000-000000005DFFFFFF 0000000000000200 000000000000000F
2776d05dc695b06c4e987bb8078f78032441e1430cGreg HartmanAvailable 000000005E000000-000000005EF1CFFF 0000000000000F1D 000000000000000F
2876d05dc695b06c4e987bb8078f78032441e1430cGreg HartmanBS_Data   000000005EF1D000-00000000709FBFFF 0000000000011ADF 000000000000000F
2976d05dc695b06c4e987bb8078f78032441e1430cGreg HartmanAvailable 00000000709FC000-00000000710E3FFF 00000000000006E8 000000000000000F
3076d05dc695b06c4e987bb8078f78032441e1430cGreg HartmanLoaderCode 00000000710E4000-00000000711FEFFF 000000000000011B 000000000000000F
3176d05dc695b06c4e987bb8078f78032441e1430cGreg HartmanAvailable 00000000711FF000-0000000071901FFF 0000000000000703 000000000000000F
3276d05dc695b06c4e987bb8078f78032441e1430cGreg HartmanBS_Code   0000000071902000-00000000721FEFFF 00000000000008FD 000000000000000F
3376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
3476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
3576d05dc695b06c4e987bb8078f78032441e1430cGreg HartmanExample to allocat 5 pages type BootCode at address 20000000 (hex)
3676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
3776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
3876d05dc695b06c4e987bb8078f78032441e1430cGreg HartmanFS1:\> AllocPages.efi 2 3 5 20000000
3976d05dc695b06c4e987bb8078f78032441e1430cGreg HartmanAllocatePage: __AllocType__ __MemType__ __NumPages__ [__Addr__]
4076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman__AllocType__ {0,1,2} -- Any, MaxAddr, Addr
4176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman__MemType__   {0..13}, Reserved ==0, LCode==1, LData==2, BSCode==3, BSData==4, ...
4276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman__NumPages__  {0..F000000}
4376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman[__Addr__]     0... 3FFFFFFFFFFF
4476d05dc695b06c4e987bb8078f78032441e1430cGreg HartmanAll numbers in hex no leading 0x
4576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
4676d05dc695b06c4e987bb8078f78032441e1430cGreg HartmanAllocatPage(2,3,5,20000000)
4776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
4876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
4976d05dc695b06c4e987bb8078f78032441e1430cGreg HartmanExample to allocat 5 pages type BootCode at address 30000000 (hex)
5076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
5176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
5276d05dc695b06c4e987bb8078f78032441e1430cGreg HartmanFS1:\> AllocPages.efi 2 3 5 30000000
5376d05dc695b06c4e987bb8078f78032441e1430cGreg HartmanAllocatePage: __AllocType__ __MemType__ __NumPages__ [__Addr__]
5476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman__AllocType__ {0,1,2} -- Any, MaxAddr, Addr
5576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman__MemType__   {0..13}, Reserved ==0, LCode==1, LData==2, BSCode==3, BSData==4, ...
5676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman__NumPages__  {0..F000000}
5776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman[__Addr__]     0... 3FFFFFFFFFFF
5876d05dc695b06c4e987bb8078f78032441e1430cGreg HartmanAll numbers in hex no leading 0x
5976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
6076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
6176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
6276d05dc695b06c4e987bb8078f78032441e1430cGreg HartmanFS1:\> memmap
6376d05dc695b06c4e987bb8078f78032441e1430cGreg HartmanType      Start            End              #pages             Attributes
6476d05dc695b06c4e987bb8078f78032441e1430cGreg HartmanBS_Code   0000000000000000-0000000000000FFF 0000000000000001 000000000000000F
6576d05dc695b06c4e987bb8078f78032441e1430cGreg HartmanAvailable 0000000000001000-000000000008DFFF 000000000000008D 000000000000000F
6676d05dc695b06c4e987bb8078f78032441e1430cGreg HartmanReserved  000000000008E000-000000000008FFFF 0000000000000002 000000000000000F
6776d05dc695b06c4e987bb8078f78032441e1430cGreg HartmanAvailable 0000000000090000-000000000009FFFF 0000000000000010 000000000000000F
6876d05dc695b06c4e987bb8078f78032441e1430cGreg HartmanAvailable 0000000000100000-000000000FFFFFFF 000000000000FF00 000000000000000F
6976d05dc695b06c4e987bb8078f78032441e1430cGreg HartmanBS_Code   0000000010000000-0000000010061FFF 0000000000000062 000000000000000F
7076d05dc695b06c4e987bb8078f78032441e1430cGreg HartmanAvailable 0000000010062000-000000001FFFFFFF 000000000000FF9E 000000000000000F
7176d05dc695b06c4e987bb8078f78032441e1430cGreg HartmanBS_Code   0000000020000000-0000000020004FFF 0000000000000005 000000000000000F
7276d05dc695b06c4e987bb8078f78032441e1430cGreg HartmanAvailable 0000000020005000-000000002FFFFFFF 000000000000FFFB 000000000000000F
7376d05dc695b06c4e987bb8078f78032441e1430cGreg HartmanBS_Code   0000000030000000-0000000030004FFF 0000000000000005 000000000000000F
7476d05dc695b06c4e987bb8078f78032441e1430cGreg HartmanAvailable 0000000030005000-000000005CDFFFFF 000000000002CDFB 000000000000000F
7576d05dc695b06c4e987bb8078f78032441e1430cGreg HartmanACPI_NVS  000000005CE00000-000000005DDFFFFF 0000000000001000 000000000000000F
7676d05dc695b06c4e987bb8078f78032441e1430cGreg HartmanBS_Data   000000005DE00000-000000005DFFFFFF 0000000000000200 000000000000000F
7776d05dc695b06c4e987bb8078f78032441e1430cGreg HartmanAvailable 000000005E000000-000000005EF1CFFF 0000000000000F1D 000000000000000F
7876d05dc695b06c4e987bb8078f78032441e1430cGreg HartmanBS_Data   000000005EF1D000-00000000709FBFFF 0000000000011ADF 000000000000000F
7976d05dc695b06c4e987bb8078f78032441e1430cGreg HartmanAvailable 00000000709FC000-00000000710E3FFF 00000000000006E8 000000000000000F
8076d05dc695b06c4e987bb8078f78032441e1430cGreg HartmanLoaderCode 00000000710E4000-00000000711FEFFF 000000000000011B 000000000000000F
8176d05dc695b06c4e987bb8078f78032441e1430cGreg HartmanAvailable 00000000711FF000-0000000071901FFF 0000000000000703 000000000000000F
8276d05dc695b06c4e987bb8078f78032441e1430cGreg HartmanBS_Code   0000000071902000-00000000721FEFFF 00000000000008FD 000000000000000F
8376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
8476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
8576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
8676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
8776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
8876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */
8976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
9076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#include <efi.h>
9176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#include <efilib.h>
9276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#include <argify.h>
9376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
9476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
9576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define MAX_NUM_PAGES 0x000000000F000000
9676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define MAX_ADDR ((1ULL << 46) - 1)
9776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
9876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
9976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#ifdef DEBUG
10076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#undef DEBUG
10176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#endif
10276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define DEBUG 0
10376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
10476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
10576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
10676d05dc695b06c4e987bb8078f78032441e1430cGreg HartmanEFI_STATUS
10776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanefi_main (EFI_HANDLE image, EFI_SYSTEM_TABLE *systab)
10876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{
10976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
11076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	EFI_STATUS efi_status;
11176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	EFI_GUID LoadedImageProtocol = LOADED_IMAGE_PROTOCOL;
11276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	EFI_LOADED_IMAGE *info;
11376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
11476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	CHAR16 arglist[MAX_ARGS+1] = {0};
11576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	CHAR16 *argv[MAX_ARGS];
11676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	INTN argc = 0;
11776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	INTN err = 0;
11876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
11976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	INTN AllocType = -1;
12076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	INTN MemType = -1;
12176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	INTN NumPages = -1;
12276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	UINTN Addr = 0;
12376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
12476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	InitializeLib(image, systab);
12576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
12676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman        efi_status = uefi_call_wrapper( BS->HandleProtocol, 3, image,
12776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman                &LoadedImageProtocol, &info);
12876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
12976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
13076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	Print(L"AllocatePage: __AllocType__ __MemType__ __NumPages__ [__Addr__]\n");
13176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	Print(L"__AllocType__ {0,1,2} -- Any, MaxAddr, Addr\n");
13276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	Print(L"__MemType__   {0..13}, Reserved ==0, LCode==1, LData==2, BSCode==3, BSData==4, ...\n");
13376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	Print(L"__NumPages__  {0..%x}\n", MAX_NUM_PAGES);
13476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	Print(L"[__Addr__]     0... %llx\n", MAX_ADDR);
13576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	Print(L"All numbers in hex no leading 0x\n");
13676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	Print(L"\n");
13776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
13876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#if DEBUG
13976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	Print(L"%s\n", info->LoadOptions);
14076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#endif
14176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
14276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
14376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#if DEBUG
14476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	Print(L"Set up arglist\n");
14576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#endif
14676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	CopyMem(arglist, info->LoadOptions, info->LoadOptionsSize);
14776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#if DEBUG
14876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	Print(L"arglist = <%s>\n", arglist);
14976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#endif
15076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
15176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#if DEBUG
15276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	Print(L"Now try argify\n");
15376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#endif
15476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	argc = argify(arglist, info->LoadOptionsSize, argv);
15576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#if DEBUG
15676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	Print(L"argc = %d\n", argc);
15776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#endif
15876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
15976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#if DEBUG
16076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	for (c = 0;  c < argc;  c++ ) {
16176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		Print(L"argv[%d] = <%s>\n", c, argv[c]);
16276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	}
16376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#endif
16476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	if ( (argc < 3) || (argc > 5) ) {
16576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		Print(L"Wrong argument count\n");
16676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		return EFI_SUCCESS;
16776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	}
16876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
16976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	AllocType = xtoi(argv[1]);
17076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	MemType   = xtoi(argv[2]);
17176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	NumPages  = xtoi(argv[3]);
17276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	if ( argc == 5 ) Addr = xtoi(argv[4]);
17376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
17476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	if ( (AllocType < 0) || (AllocType > 2)) {
17576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		Print(L"Invalid AllocType\n");
17676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		err++;
17776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	}
17876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	if ( (MemType < 0) || (MemType > 13) ) {
17976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		Print(L"Invalid MemType\n");
18076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		err++;
18176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	}
18276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	if ( (NumPages < 0) || (NumPages > MAX_NUM_PAGES) ) {
18376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		Print(L"Inavlid NumPages\n");
18476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		err++;
18576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	}
18676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	if ( Addr > MAX_ADDR ) {
18776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		Print(L"Inavlid Address\n");
18876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		err++;
18976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	}
19076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	if ( err ) {
19176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		return EFI_INVALID_PARAMETER;
19276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	}
19376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
19476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	Print(L"AllocatPage(%d,%d,%d,%lx)\n", AllocType, MemType, NumPages, Addr);
19576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
19676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	efi_status = uefi_call_wrapper(BS->AllocatePages, 4, AllocType, MemType, NumPages, &Addr);
19776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
19876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	if ( EFI_ERROR(efi_status) ) {
19976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		Print(L"Allocate Pages Failed: %d\n", efi_status);
20076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		return efi_status;
20176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	}
20276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
20376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	return EFI_SUCCESS;
20476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}
205