FreePages.c 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  1. /*
  2. * Copyright (C) 2013 Jerry Hoemann <jerry.hoemann@hp.com>
  3. *
  4. * Application to allocate memory at EFI. Syntax of command
  5. * mimics the EFI Boot Service "FreePages."
  6. *
  7. * See UEFI spec 2.3, Section 6.2.
  8. *
  9. Example freeing a 5 page BS_Code setment at address: 0000000020000000 (hex)
  10. FS1:\> memmap
  11. Type Start End #pages Attributes
  12. BS_Code 0000000000000000-0000000000000FFF 0000000000000001 000000000000000F
  13. Available 0000000000001000-000000000008DFFF 000000000000008D 000000000000000F
  14. Reserved 000000000008E000-000000000008FFFF 0000000000000002 000000000000000F
  15. Available 0000000000090000-000000000009FFFF 0000000000000010 000000000000000F
  16. Available 0000000000100000-000000000FFFFFFF 000000000000FF00 000000000000000F
  17. BS_Code 0000000010000000-0000000010061FFF 0000000000000062 000000000000000F
  18. Available 0000000010062000-000000001FFFFFFF 000000000000FF9E 000000000000000F
  19. BS_Code 0000000020000000-0000000020004FFF 0000000000000005 000000000000000F
  20. Available 0000000020005000-000000005DDFFFFF 000000000003DDFB 000000000000000F
  21. BS_Data 000000005DE00000-000000005DFFFFFF 0000000000000200 000000000000000F
  22. Available 000000005E000000-000000006DE7CFFF 000000000000FE7D 000000000000000F
  23. ACPI_NVS 000000006DE7D000-000000006EE7CFFF 0000000000001000 000000000000000F
  24. BS_Data 000000006EE7D000-00000000709FBFFF 0000000000001B7F 000000000000000F
  25. Available 00000000709FC000-00000000710E3FFF 00000000000006E8 000000000000000F
  26. FS1:\> FreePages 0000000020000000 5
  27. FreePages: __PhysAddr__ __PgCnt__
  28. __PhysAddr__ 0... 3FFFFFFFFFFF
  29. __PgCnt__ [0..F000000]
  30. All numbers hex w/ no leading 0x
  31. FreePages(20000000,5)
  32. FS1:\> memmap
  33. Type Start End #pages Attributes
  34. BS_Code 0000000000000000-0000000000000FFF 0000000000000001 000000000000000F
  35. Available 0000000000001000-000000000008DFFF 000000000000008D 000000000000000F
  36. Reserved 000000000008E000-000000000008FFFF 0000000000000002 000000000000000F
  37. Available 0000000000090000-000000000009FFFF 0000000000000010 000000000000000F
  38. Available 0000000000100000-000000000FFFFFFF 000000000000FF00 000000000000000F
  39. BS_Code 0000000010000000-0000000010061FFF 0000000000000062 000000000000000F
  40. Available 0000000010062000-000000005DDFFFFF 000000000004DD9E 000000000000000F
  41. BS_Data 000000005DE00000-000000005DFFFFFF 0000000000000200 000000000000000F
  42. Available 000000005E000000-000000006DE7CFFF 000000000000FE7D 000000000000000F
  43. ACPI_NVS 000000006DE7D000-000000006EE7CFFF 0000000000001000 000000000000000F
  44. BS_Data 000000006EE7D000-00000000709FBFFF 0000000000001B7F 000000000000000F
  45. Available 00000000709FC000-00000000710E3FFF 00000000000006E8 000000000000000F
  46. */
  47. #include <efi.h>
  48. #include <efilib.h>
  49. #include <argify.h>
  50. /*
  51. * FreePages: __PhysAddr__ __PgCnt__
  52. *
  53. */
  54. #define MAX_NUM_PAGES 0x000000000F000000
  55. #define MAX_ADDR ((1ULL << 46) - 1)
  56. #ifdef DEBUG
  57. #undef DEBUG
  58. #endif
  59. #define DEBUG 0
  60. EFI_STATUS
  61. efi_main (EFI_HANDLE image, EFI_SYSTEM_TABLE *systab)
  62. {
  63. EFI_STATUS efi_status;
  64. EFI_GUID LoadedImageProtocol = LOADED_IMAGE_PROTOCOL;
  65. EFI_LOADED_IMAGE *info;
  66. CHAR16 arglist[MAX_ARGS+1] = {0};
  67. CHAR16 *argv[MAX_ARGS];
  68. INTN argc = 0;
  69. INTN err = 0;
  70. INTN PgCnt = -1;
  71. UINTN PhysAddr = 0;
  72. InitializeLib(image, systab);
  73. efi_status = uefi_call_wrapper( BS->HandleProtocol, 3, image,
  74. &LoadedImageProtocol, &info);
  75. Print(L"FreePages: __PhysAddr__ __PgCnt__\n");
  76. Print(L"__PhysAddr__ 0... %llx\n", MAX_ADDR);
  77. Print(L"__PgCnt__ [0..%lx]\n", MAX_NUM_PAGES);
  78. Print(L"All numbers hex w/ no leading 0x\n");
  79. Print(L"\n");
  80. #if DEBUG
  81. Print(L"%s\n", info->LoadOptions);
  82. #endif
  83. #if DEBUG
  84. Print(L"Set up arglist\n");
  85. #endif
  86. CopyMem(arglist, info->LoadOptions, info->LoadOptionsSize);
  87. #if DEBUG
  88. Print(L"arglist = <%s>\n", arglist);
  89. #endif
  90. #if DEBUG
  91. Print(L"Now try argify\n");
  92. #endif
  93. argc = argify(arglist, info->LoadOptionsSize, argv);
  94. #if DEBUG
  95. Print(L"argc = %d\n", argc);
  96. #endif
  97. #if DEBUG
  98. for (c = 0; c < argc; c++ ) {
  99. Print(L"argv[%d] = <%s>\n", c, argv[c]);
  100. }
  101. #endif
  102. if (argc != 3) {
  103. Print(L"Invalid argument count\n");
  104. return EFI_SUCCESS;
  105. }
  106. PhysAddr = xtoi(argv[1]);
  107. PgCnt = xtoi(argv[2]);
  108. if ( (PgCnt < 0) || (PgCnt > MAX_NUM_PAGES) ) {
  109. Print(L"Inavlid PgCnt\n");
  110. err++;
  111. }
  112. if ( PhysAddr > MAX_ADDR ) {
  113. Print(L"Inavlid Address\n");
  114. err++;
  115. }
  116. if ( err ) {
  117. return EFI_SUCCESS;
  118. }
  119. Print(L"FreePages(%lx,%d)\n", PhysAddr, PgCnt);
  120. efi_status = uefi_call_wrapper(BS->FreePages, 2, PhysAddr, PgCnt);
  121. if ( EFI_ERROR(efi_status) ) {
  122. Print(L"Free Pages Failed: %d\n", efi_status);
  123. return efi_status;
  124. }
  125. return EFI_SUCCESS;
  126. }