FreePages.c 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  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 <ParseCmdLine.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 c = 0;
  70. INTN err = 0;
  71. INTN PgCnt = -1;
  72. UINTN PhysAddr = 0;
  73. InitializeLib(image, systab);
  74. efi_status = uefi_call_wrapper( BS->HandleProtocol, 3, image,
  75. &LoadedImageProtocol, &info);
  76. Print(L"FreePages: __PhysAddr__ __PgCnt__\n");
  77. Print(L"__PhysAddr__ 0... %llx\n", MAX_ADDR);
  78. Print(L"__PgCnt__ [0..%lx]\n", MAX_NUM_PAGES);
  79. Print(L"All numbers hex w/ no leading 0x\n");
  80. Print(L"\n");
  81. #if DEBUG
  82. Print(L"%s\n", info->LoadOptions);
  83. #endif
  84. #if DEBUG
  85. Print(L"Set up arglist\n");
  86. #endif
  87. CopyMem(arglist, info->LoadOptions, info->LoadOptionsSize);
  88. #if DEBUG
  89. Print(L"arglist = <%s>\n", arglist);
  90. #endif
  91. #if DEBUG
  92. Print(L"Now try ParseCmdLine\n");
  93. #endif
  94. argc = ParseCmdLine(argv, arglist, info->LoadOptionsSize);
  95. #if DEBUG
  96. Print(L"argc = %d\n", argc);
  97. #endif
  98. #if DEBUG
  99. for (c = 0; c < argc; c++ ) {
  100. Print(L"argv[%d] = <%s>\n", c, argv[c]);
  101. }
  102. #endif
  103. if (argc != 3) {
  104. Print(L"Invalid argument count\n");
  105. return EFI_SUCCESS;
  106. }
  107. PhysAddr = xtoi(argv[1]);
  108. PgCnt = xtoi(argv[2]);
  109. if ( (PgCnt < 0) || (PgCnt > MAX_NUM_PAGES) ) {
  110. Print(L"Inavlid PgCnt\n");
  111. err++;
  112. }
  113. if ( PhysAddr > MAX_ADDR ) {
  114. Print(L"Inavlid Address\n");
  115. err++;
  116. }
  117. if ( err ) {
  118. return EFI_SUCCESS;
  119. }
  120. Print(L"FreePages(%lx,%d)\n", PhysAddr, PgCnt);
  121. efi_status = uefi_call_wrapper(BS->FreePages, 2, PhysAddr, PgCnt);
  122. if ( EFI_ERROR(efi_status) ) {
  123. Print(L"Free Pages Failed: %d\n", efi_status);
  124. return efi_status;
  125. }
  126. return EFI_SUCCESS;
  127. }