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