Deleted Added
full compact
efimd.c (164010) efimd.c (219691)
1/*-
2 * Copyright (c) 2004, 2006 Marcel Moolenaar
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *

--- 11 unchanged lines hidden (view full) ---

20 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 */
26
27#include <sys/cdefs.h>
1/*-
2 * Copyright (c) 2004, 2006 Marcel Moolenaar
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *

--- 11 unchanged lines hidden (view full) ---

20 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 */
26
27#include <sys/cdefs.h>
28__FBSDID("$FreeBSD: head/sys/boot/ia64/efi/efimd.c 164010 2006-11-05 22:03:04Z marcel $");
28__FBSDID("$FreeBSD: head/sys/boot/ia64/efi/efimd.c 219691 2011-03-16 03:53:18Z marcel $");
29
30#include <stand.h>
31
32#include <efi.h>
33#include <efilib.h>
34
35#include <libia64.h>
36
37#define EFI_INTEL_FPSWA \
38 {0xc41b6531,0x97b9,0x11d3,{0x9a,0x29,0x00,0x90,0x27,0x3f,0xc1,0x4d}}
39
40static EFI_GUID fpswa_guid = EFI_INTEL_FPSWA;
41
42/* DIG64 Headless Console & Debug Port Table. */
43#define HCDP_TABLE_GUID \
44 {0xf951938d,0x620b,0x42ef,{0x82,0x79,0xa8,0x4b,0x79,0x61,0x78,0x98}}
45
46static EFI_GUID hcdp_guid = HCDP_TABLE_GUID;
47
29
30#include <stand.h>
31
32#include <efi.h>
33#include <efilib.h>
34
35#include <libia64.h>
36
37#define EFI_INTEL_FPSWA \
38 {0xc41b6531,0x97b9,0x11d3,{0x9a,0x29,0x00,0x90,0x27,0x3f,0xc1,0x4d}}
39
40static EFI_GUID fpswa_guid = EFI_INTEL_FPSWA;
41
42/* DIG64 Headless Console & Debug Port Table. */
43#define HCDP_TABLE_GUID \
44 {0xf951938d,0x620b,0x42ef,{0x82,0x79,0xa8,0x4b,0x79,0x61,0x78,0x98}}
45
46static EFI_GUID hcdp_guid = HCDP_TABLE_GUID;
47
48static EFI_MEMORY_DESCRIPTOR *memmap;
49static UINTN memmapsz;
48static UINTN mapkey;
50static UINTN mapkey;
51static UINTN descsz;
52static UINT32 descver;
49
53
50uint64_t
51ldr_alloc(vm_offset_t va)
54#define IA64_EFI_CHUNK_SIZE (32 * 1048576)
55static vm_paddr_t ia64_efi_chunk;
56
57#define IA64_EFI_PGTBLSZ_MAX 1048576
58static vm_paddr_t ia64_efi_pgtbl;
59static vm_size_t ia64_efi_pgtblsz;
60
61/* Don't allocate memory below the boundary */
62#define IA64_EFI_ALLOC_BOUNDARY 1048576
63
64static int
65ia64_efi_memmap_update(void)
52{
66{
67 EFI_STATUS status;
53
68
69 if (memmap != NULL) {
70 free(memmap);
71 memmap = NULL;
72 }
73
74 memmapsz = 0;
75 BS->GetMemoryMap(&memmapsz, NULL, &mapkey, &descsz, &descver);
76 if (memmapsz == 0)
77 return (FALSE);
78 memmap = malloc(memmapsz);
79 if (memmap == NULL)
80 return (FALSE);
81
82 status = BS->GetMemoryMap(&memmapsz, memmap, &mapkey, &descsz,
83 &descver);
84 if (EFI_ERROR(status)) {
85 free(memmap);
86 memmap = NULL;
87 return (FALSE);
88 }
89
90 return (TRUE);
91}
92
93static vm_paddr_t
94ia64_efi_alloc(vm_size_t sz)
95{
96 EFI_PHYSICAL_ADDRESS pa;
97 EFI_MEMORY_DESCRIPTOR *mm;
98 uint8_t *mmiter, *mmiterend;
99 vm_size_t memsz;
100 UINTN npgs;
101 EFI_STATUS status;
102
103 /* We can't allocate less than a page */
104 if (sz < EFI_PAGE_SIZE)
105 return (0);
106
107 /* The size must be a power of 2. */
108 if (sz & (sz - 1))
109 return (0);
110
111 if (!ia64_efi_memmap_update())
112 return (0);
113
114 mmiter = (void *)memmap;
115 mmiterend = mmiter + memmapsz;
116 for (; mmiter < mmiterend; mmiter += descsz) {
117 mm = (void *)mmiter;
118 if (mm->Type != EfiConventionalMemory)
119 continue;
120 memsz = mm->NumberOfPages * EFI_PAGE_SIZE;
121 if (mm->PhysicalStart + memsz <= IA64_EFI_ALLOC_BOUNDARY)
122 continue;
123 /*
124 * XXX We really should make sure the memory is local to the
125 * BSP.
126 */
127 pa = (mm->PhysicalStart < IA64_EFI_ALLOC_BOUNDARY) ?
128 IA64_EFI_ALLOC_BOUNDARY : mm->PhysicalStart;
129 pa = (pa + sz - 1) & ~(sz - 1);
130 if (pa + sz > mm->PhysicalStart + memsz)
131 continue;
132
133 npgs = EFI_SIZE_TO_PAGES(sz);
134 status = BS->AllocatePages(AllocateAddress, EfiLoaderData,
135 npgs, &pa);
136 if (!EFI_ERROR(status))
137 return (pa);
138 }
139
140 printf("%s: unable to allocate %lx bytes\n", __func__, sz);
54 return (0);
55}
56
141 return (0);
142}
143
144vm_paddr_t
145ia64_platform_alloc(vm_offset_t va, vm_size_t sz)
146{
147
148 if (va == 0) {
149 /* Page table itself. */
150 if (sz > IA64_EFI_PGTBLSZ_MAX)
151 return (0);
152 if (ia64_efi_pgtbl == 0)
153 ia64_efi_pgtbl = ia64_efi_alloc(IA64_EFI_PGTBLSZ_MAX);
154 if (ia64_efi_pgtbl != 0)
155 ia64_efi_pgtblsz = sz;
156 return (ia64_efi_pgtbl);
157 } else if (va < IA64_PBVM_BASE) {
158 /* Should not happen. */
159 return (0);
160 }
161
162 /* Loader virtual memory page. */
163 va -= IA64_PBVM_BASE;
164
165 /* Allocate a big chunk that can be wired with a single PTE. */
166 if (ia64_efi_chunk == 0)
167 ia64_efi_chunk = ia64_efi_alloc(IA64_EFI_CHUNK_SIZE);
168 if (va < IA64_EFI_CHUNK_SIZE)
169 return (ia64_efi_chunk + va);
170
171 /* Allocate a page at a time when we go beyond the chunk. */
172 return (ia64_efi_alloc(sz));
173}
174
175void
176ia64_platform_free(vm_offset_t va, vm_paddr_t pa, vm_size_t sz)
177{
178
179 BS->FreePages(pa, sz >> EFI_PAGE_SHIFT);
180}
181
57int
182int
58ldr_bootinfo(struct bootinfo *bi, uint64_t *bi_addr)
183ia64_platform_bootinfo(struct bootinfo *bi, struct bootinfo **res)
59{
60 VOID *fpswa;
184{
185 VOID *fpswa;
61 EFI_MEMORY_DESCRIPTOR *mm;
62 EFI_PHYSICAL_ADDRESS addr;
63 EFI_HANDLE handle;
64 EFI_STATUS status;
186 EFI_HANDLE handle;
187 EFI_STATUS status;
65 size_t bisz;
66 UINTN mmsz, pages, sz;
67 UINT32 mmver;
188 UINTN sz;
68
69 bi->bi_systab = (uint64_t)ST;
70 bi->bi_hcdp = (uint64_t)efi_get_table(&hcdp_guid);
71
72 sz = sizeof(EFI_HANDLE);
73 status = BS->LocateHandle(ByProtocol, &fpswa_guid, 0, &sz, &handle);
74 if (status == 0)
75 status = BS->HandleProtocol(handle, &fpswa_guid, &fpswa);
76 bi->bi_fpswa = (status == 0) ? (uint64_t)fpswa : 0;
77
189
190 bi->bi_systab = (uint64_t)ST;
191 bi->bi_hcdp = (uint64_t)efi_get_table(&hcdp_guid);
192
193 sz = sizeof(EFI_HANDLE);
194 status = BS->LocateHandle(ByProtocol, &fpswa_guid, 0, &sz, &handle);
195 if (status == 0)
196 status = BS->HandleProtocol(handle, &fpswa_guid, &fpswa);
197 bi->bi_fpswa = (status == 0) ? (uint64_t)fpswa : 0;
198
78 bisz = (sizeof(struct bootinfo) + 0x0f) & ~0x0f;
79
80 /*
81 * Allocate enough pages to hold the bootinfo block and the memory
82 * map EFI will return to us. The memory map has an unknown size,
83 * so we have to determine that first. Note that the AllocatePages
84 * call can itself modify the memory map, so we have to take that
85 * into account as well. The changes to the memory map are caused
86 * by splitting a range of free memory into two (AFAICT), so that
87 * one is marked as being loader data.
88 */
89 sz = 0;
90 BS->GetMemoryMap(&sz, NULL, &mapkey, &mmsz, &mmver);
91 sz += mmsz;
92 sz = (sz + 15) & ~15;
93 pages = EFI_SIZE_TO_PAGES(sz + bisz);
94 status = BS->AllocatePages(AllocateAnyPages, EfiLoaderData, pages,
95 &addr);
96 if (EFI_ERROR(status)) {
97 printf("%s: AllocatePages() returned 0x%lx\n", __func__,
98 (long)status);
199 if (!ia64_efi_memmap_update())
99 return (ENOMEM);
200 return (ENOMEM);
100 }
101
201
102 /*
103 * Read the memory map and stash it after bootinfo. Align the
104 * memory map on a 16-byte boundary (the bootinfo block is page
105 * aligned).
106 */
107 *bi_addr = addr;
108 mm = (void *)(addr + bisz);
109 sz = (EFI_PAGE_SIZE * pages) - bisz;
110 status = BS->GetMemoryMap(&sz, mm, &mapkey, &mmsz, &mmver);
111 if (EFI_ERROR(status)) {
112 printf("%s: GetMemoryMap() returned 0x%lx\n", __func__,
113 (long)status);
114 return (EINVAL);
115 }
116 bi->bi_memmap = (uint64_t)mm;
117 bi->bi_memmap_size = sz;
118 bi->bi_memdesc_size = mmsz;
119 bi->bi_memdesc_version = mmver;
202 bi->bi_memmap = (uint64_t)memmap;
203 bi->bi_memmap_size = memmapsz;
204 bi->bi_memdesc_size = descsz;
205 bi->bi_memdesc_version = descver;
120
206
121 bcopy(bi, (void *)(*bi_addr), sizeof(*bi));
207 if (IS_LEGACY_KERNEL())
208 *res = malloc(sizeof(**res));
209
122 return (0);
123}
124
125int
210 return (0);
211}
212
213int
126ldr_enter(const char *kernel)
214ia64_platform_enter(const char *kernel)
127{
128 EFI_STATUS status;
129
130 status = BS->ExitBootServices(IH, mapkey);
131 if (EFI_ERROR(status)) {
132 printf("%s: ExitBootServices() returned 0x%lx\n", __func__,
133 (long)status);
134 return (EINVAL);
135 }
136
137 return (0);
138}
215{
216 EFI_STATUS status;
217
218 status = BS->ExitBootServices(IH, mapkey);
219 if (EFI_ERROR(status)) {
220 printf("%s: ExitBootServices() returned 0x%lx\n", __func__,
221 (long)status);
222 return (EINVAL);
223 }
224
225 return (0);
226}