1135446Strhodes/* $NetBSD: FreePages.c,v 1.1.1.1 2018/08/16 18:17:47 jmcneill Exp $ */ 2135446Strhodes 3135446Strhodes 4135446Strhodes 5135446Strhodes/* 6135446Strhodes * Copyright (C) 2013 Jerry Hoemann <jerry.hoemann@hp.com> 7135446Strhodes * 8135446Strhodes * Application to allocate memory at EFI. Syntax of command 9135446Strhodes * mimics the EFI Boot Service "FreePages." 10135446Strhodes * 11135446Strhodes * See UEFI spec 2.3, Section 6.2. 12135446Strhodes * 13135446Strhodes 14135446StrhodesExample freeing a 5 page BS_Code setment at address: 0000000020000000 (hex) 15135446Strhodes 16135446Strhodes 17135446StrhodesFS1:\> memmap 18135446StrhodesType Start End #pages Attributes 19135446StrhodesBS_Code 0000000000000000-0000000000000FFF 0000000000000001 000000000000000F 20135446StrhodesAvailable 0000000000001000-000000000008DFFF 000000000000008D 000000000000000F 21135446StrhodesReserved 000000000008E000-000000000008FFFF 0000000000000002 000000000000000F 22135446StrhodesAvailable 0000000000090000-000000000009FFFF 0000000000000010 000000000000000F 23135446StrhodesAvailable 0000000000100000-000000000FFFFFFF 000000000000FF00 000000000000000F 24135446StrhodesBS_Code 0000000010000000-0000000010061FFF 0000000000000062 000000000000000F 25135446StrhodesAvailable 0000000010062000-000000001FFFFFFF 000000000000FF9E 000000000000000F 26135446StrhodesBS_Code 0000000020000000-0000000020004FFF 0000000000000005 000000000000000F 27135446StrhodesAvailable 0000000020005000-000000005DDFFFFF 000000000003DDFB 000000000000000F 28135446StrhodesBS_Data 000000005DE00000-000000005DFFFFFF 0000000000000200 000000000000000F 29135446StrhodesAvailable 000000005E000000-000000006DE7CFFF 000000000000FE7D 000000000000000F 30135446StrhodesACPI_NVS 000000006DE7D000-000000006EE7CFFF 0000000000001000 000000000000000F 31135446StrhodesBS_Data 000000006EE7D000-00000000709FBFFF 0000000000001B7F 000000000000000F 32135446StrhodesAvailable 00000000709FC000-00000000710E3FFF 00000000000006E8 000000000000000F 33135446Strhodes 34135446Strhodes 35135446StrhodesFS1:\> FreePages 0000000020000000 5 36135446StrhodesFreePages: __PhysAddr__ __PgCnt__ 37135446Strhodes__PhysAddr__ 0... 3FFFFFFFFFFF 38135446Strhodes__PgCnt__ [0..F000000] 39135446StrhodesAll numbers hex w/ no leading 0x 40135446Strhodes 41135446StrhodesFreePages(20000000,5) 42135446Strhodes 43135446Strhodes 44135446Strhodes 45135446StrhodesFS1:\> memmap 46135446StrhodesType Start End #pages Attributes 47135446StrhodesBS_Code 0000000000000000-0000000000000FFF 0000000000000001 000000000000000F 48135446StrhodesAvailable 0000000000001000-000000000008DFFF 000000000000008D 000000000000000F 49135446StrhodesReserved 000000000008E000-000000000008FFFF 0000000000000002 000000000000000F 50135446StrhodesAvailable 0000000000090000-000000000009FFFF 0000000000000010 000000000000000F 51135446StrhodesAvailable 0000000000100000-000000000FFFFFFF 000000000000FF00 000000000000000F 52135446StrhodesBS_Code 0000000010000000-0000000010061FFF 0000000000000062 000000000000000F 53135446StrhodesAvailable 0000000010062000-000000005DDFFFFF 000000000004DD9E 000000000000000F 54135446StrhodesBS_Data 000000005DE00000-000000005DFFFFFF 0000000000000200 000000000000000F 55135446StrhodesAvailable 000000005E000000-000000006DE7CFFF 000000000000FE7D 000000000000000F 56135446StrhodesACPI_NVS 000000006DE7D000-000000006EE7CFFF 0000000000001000 000000000000000F 57135446StrhodesBS_Data 000000006EE7D000-00000000709FBFFF 0000000000001B7F 000000000000000F 58135446StrhodesAvailable 00000000709FC000-00000000710E3FFF 00000000000006E8 000000000000000F 59135446Strhodes 60135446Strhodes 61135446Strhodes */ 62135446Strhodes 63135446Strhodes#include <efi.h> 64135446Strhodes#include <efilib.h> 65135446Strhodes 66135446Strhodes/* 67135446Strhodes * FreePages: __PhysAddr__ __PgCnt__ 68135446Strhodes * 69135446Strhodes */ 70135446Strhodes 71135446Strhodes#define MAX_NUM_PAGES 0x000000000F000000 72135446Strhodes 73135446Strhodes#define MAX_ADDR ((1ULL << 46) - 1) 74135446Strhodes 75135446Strhodes#ifdef DEBUG 76135446Strhodes#undef DEBUG 77135446Strhodes#endif 78135446Strhodes#define DEBUG 0 79135446Strhodes 80135446Strhodes 81135446StrhodesEFI_STATUS 82135446Strhodesefi_main (EFI_HANDLE image, EFI_SYSTEM_TABLE *systab) 83135446Strhodes{ 84135446Strhodes 85135446Strhodes EFI_STATUS efi_status; 86135446Strhodes CHAR16 **argv; 87135446Strhodes INTN argc = 0; 88135446Strhodes#if DEBUG 89135446Strhodes INTN c = 0; 90135446Strhodes#endif 91135446Strhodes INTN err = 0; 92135446Strhodes 93135446Strhodes INTN PgCnt = -1; 94135446Strhodes EFI_PHYSICAL_ADDRESS PhysAddr = 0; 95135446Strhodes 96135446Strhodes InitializeLib(image, systab); 97135446Strhodes 98135446Strhodes Print(L"FreePages: __PhysAddr__ __PgCnt__\n"); 99135446Strhodes Print(L"__PhysAddr__ 0... %llx\n", MAX_ADDR); 100135446Strhodes Print(L"__PgCnt__ [0..%lx]\n", MAX_NUM_PAGES); 101135446Strhodes Print(L"All numbers hex w/ no leading 0x\n"); 102135446Strhodes Print(L"\n"); 103135446Strhodes 104135446Strhodes#if DEBUG 105135446Strhodes Print(L"Now parse argc/argv\n"); 106135446Strhodes#endif 107135446Strhodes argc = GetShellArgcArgv(image, &argv); 108135446Strhodes#if DEBUG 109135446Strhodes Print(L"argc = %d\n", argc); 110135446Strhodes#endif 111135446Strhodes 112135446Strhodes#if DEBUG 113135446Strhodes for (c = 0; c < argc; c++ ) { 114135446Strhodes Print(L"argv[%d] = <%s>\n", c, argv[c]); 115135446Strhodes } 116135446Strhodes#endif 117135446Strhodes if (argc != 3) { 118135446Strhodes Print(L"Invalid argument count\n"); 119135446Strhodes return EFI_SUCCESS; 120135446Strhodes } 121135446Strhodes 122135446Strhodes PhysAddr = xtoi(argv[1]); 123135446Strhodes PgCnt = xtoi(argv[2]); 124135446Strhodes 125135446Strhodes if ( (PgCnt < 0) || (PgCnt > MAX_NUM_PAGES) ) { 126135446Strhodes Print(L"Inavlid PgCnt\n"); 127135446Strhodes err++; 128135446Strhodes } 129135446Strhodes if ( PhysAddr > MAX_ADDR ) { 130135446Strhodes Print(L"Inavlid Address\n"); 131135446Strhodes err++; 132135446Strhodes } 133135446Strhodes if ( err ) { 134135446Strhodes return EFI_SUCCESS; 135135446Strhodes } 136135446Strhodes 137135446Strhodes Print(L"FreePages(%lx,%d)\n", PhysAddr, PgCnt); 138135446Strhodes 139135446Strhodes efi_status = uefi_call_wrapper(BS->FreePages, 2, PhysAddr, PgCnt); 140135446Strhodes 141135446Strhodes if ( EFI_ERROR(efi_status) ) { 142135446Strhodes Print(L"Free Pages Failed: %d\n", efi_status); 143135446Strhodes return efi_status; 144135446Strhodes } 145135446Strhodes 146135446Strhodes return EFI_SUCCESS; 147135446Strhodes} 148135446Strhodes