efi - Add EFI run-time ABI support
[dragonfly.git] / sys / platform / pc64 / x86_64 / efirt.c
1 /*-
2  * Copyright (c) 2004 Marcel Moolenaar
3  * Copyright (c) 2001 Doug Rabson
4  * Copyright (c) 2016 The FreeBSD Foundation
5  * All rights reserved.
6  *
7  * Portions of this software were developed by Konstantin Belousov
8  * under sponsorship from the FreeBSD Foundation.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
13  * 1. Redistributions of source code must retain the above copyright
14  *    notice, this list of conditions and the following disclaimer.
15  * 2. Redistributions in binary form must reproduce the above copyright
16  *    notice, this list of conditions and the following disclaimer in the
17  *    documentation and/or other materials provided with the distribution.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
20  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
23  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29  * SUCH DAMAGE.
30  *
31  * $FreeBSD: head/sys/amd64/amd64/efirt.c 307391 2016-10-16 06:07:43Z kib $
32  */
33
34 #include <sys/param.h>
35 #include <sys/efi.h>
36 #include <sys/kernel.h>
37 #include <sys/linker.h>
38 #include <sys/lock.h>
39 #include <sys/module.h>
40 #include <sys/proc.h>
41 #include <sys/sched.h>
42 #include <sys/sysctl.h>
43 #include <sys/systm.h>
44 #include <sys/proc.h>
45 #include <sys/thread.h>
46 #include <sys/globaldata.h>
47
48 #include <vm/vm.h>
49 #include <vm/pmap.h>
50 #include <vm/vm_map.h>
51 #include <vm/vm_object.h>
52 #include <vm/vm_param.h>
53 #include <vm/vm_page.h>
54 #include <vm/vm_pager.h>
55 #include <vm/vm_extern.h>
56
57 #include <vm/vm_page2.h>
58 #include <sys/thread2.h>
59
60 #include <machine/efi.h>
61 #include <machine/metadata.h>
62 #include <machine/md_var.h>
63 #include <machine/smp.h>
64 #include <machine/vmparam.h>
65
66 static struct efi_systbl *efi_systbl;
67 static struct efi_cfgtbl *efi_cfgtbl;
68 static struct efi_rt *efi_runtime;
69
70 static int efi_status2err[25] = {
71         0,              /* EFI_SUCCESS */
72         ENOEXEC,        /* EFI_LOAD_ERROR */
73         EINVAL,         /* EFI_INVALID_PARAMETER */
74         ENOSYS,         /* EFI_UNSUPPORTED */
75         EMSGSIZE,       /* EFI_BAD_BUFFER_SIZE */
76         EOVERFLOW,      /* EFI_BUFFER_TOO_SMALL */
77         EBUSY,          /* EFI_NOT_READY */
78         EIO,            /* EFI_DEVICE_ERROR */
79         EROFS,          /* EFI_WRITE_PROTECTED */
80         EAGAIN,         /* EFI_OUT_OF_RESOURCES */
81         EIO,            /* EFI_VOLUME_CORRUPTED */
82         ENOSPC,         /* EFI_VOLUME_FULL */
83         ENXIO,          /* EFI_NO_MEDIA */
84         ESTALE,         /* EFI_MEDIA_CHANGED */
85         ENOENT,         /* EFI_NOT_FOUND */
86         EACCES,         /* EFI_ACCESS_DENIED */
87         ETIMEDOUT,      /* EFI_NO_RESPONSE */
88         EADDRNOTAVAIL,  /* EFI_NO_MAPPING */
89         ETIMEDOUT,      /* EFI_TIMEOUT */
90         EDOOFUS,        /* EFI_NOT_STARTED */
91         EALREADY,       /* EFI_ALREADY_STARTED */
92         ECANCELED,      /* EFI_ABORTED */
93         EPROTO,         /* EFI_ICMP_ERROR */
94         EPROTO,         /* EFI_TFTP_ERROR */
95         EPROTO          /* EFI_PROTOCOL_ERROR */
96 };
97
98 MALLOC_DEFINE(M_EFI, "efi", "EFI BIOS");
99
100 static int
101 efi_status_to_errno(efi_status status)
102 {
103         u_long code;
104
105         code = status & 0x3ffffffffffffffful;
106         return (code < nitems(efi_status2err) ? efi_status2err[code] : EDOOFUS);
107 }
108
109 static struct lock efi_lock;
110 static struct lock resettodr_lock;
111 static mcontext_t efi_ctx;
112 static struct vmspace *efi_savevm;
113 static struct vmspace *efi_vmspace;
114 static vm_object_t efi_obj;
115 static struct efi_md *efi_map;
116 static int efi_ndesc;
117 static int efi_descsz;
118
119 static void
120 efi_destroy_1t1_map(void)
121 {
122         vm_object_t obj;
123         vm_page_t m;
124
125         if ((obj = efi_obj) != NULL) {
126                 efi_obj = NULL;
127                 vm_object_hold(obj);
128                 vm_object_reference_locked(obj);        /* match deallocate */
129         }
130         if (efi_vmspace) {
131                 pmap_remove_pages(vmspace_pmap(efi_vmspace),
132                                   VM_MIN_USER_ADDRESS, VM_MAX_USER_ADDRESS);
133                 vm_map_remove(&efi_vmspace->vm_map,
134                               VM_MIN_USER_ADDRESS,
135                               VM_MAX_USER_ADDRESS);
136                 vmspace_rel(efi_vmspace);
137                 efi_vmspace = NULL;
138         }
139         if (obj) {
140                 while ((m = RB_ROOT(&obj->rb_memq)) != NULL) {
141                         vm_page_busy_wait(m, FALSE, "efipg");
142                         vm_page_unwire(m, 1);
143                         m->flags &= ~(PG_MAPPED | PG_WRITEABLE);
144                         cdev_pager_free_page(obj, m);
145                         kfree(m, M_EFI);
146                 }
147                 vm_object_drop(obj);
148                 vm_object_deallocate(obj);
149         }
150 }
151
152 static int
153 efi_pg_ctor(void *handle, vm_ooffset_t size, vm_prot_t prot,
154             vm_ooffset_t foff, struct ucred *cred, u_short *color)
155 {
156         *color = 0;
157         return 0;
158 }
159
160 static void
161 efi_pg_dtor(void *handle)
162 {
163 }
164
165 static int
166 efi_pg_fault(vm_object_t obj, vm_ooffset_t offset, int prot, vm_page_t *mres)
167 {
168         vm_page_t m;
169
170         m = *mres;
171         if ((m->flags & PG_FICTITIOUS) == 0) {
172                 *mres = NULL;
173                 vm_page_remove(m);
174                 vm_page_free(m);
175                 m = NULL;
176         }
177         if (m == NULL) {
178                 kprintf("efi_pg_fault: unmapped pg @%016jx\n", offset);
179                 return VM_PAGER_ERROR;
180         }
181
182         /*
183          * Shouldn't get hit, we pre-loaded all the pages.
184          */
185         kprintf("efi_pg_fault: ok %p/%p @%016jx m=%016jx,%016jx\n",
186                 obj, efi_obj, offset, m->pindex, m->phys_addr);
187
188         return VM_PAGER_OK;
189 }
190
191 static struct cdev_pager_ops efi_pager_ops = {
192         .cdev_pg_fault  = efi_pg_fault,
193         .cdev_pg_ctor   = efi_pg_ctor,
194         .cdev_pg_dtor   = efi_pg_dtor
195 };
196
197 static bool
198 efi_create_1t1_map(struct efi_md *map, int ndesc, int descsz)
199 {
200         vm_page_t m;
201         struct efi_md *p;
202         int i;
203         int count;
204         int result;
205
206         efi_map = map;
207         efi_ndesc = ndesc;
208         efi_descsz = descsz;
209
210         efi_vmspace = vmspace_alloc(VM_MIN_USER_ADDRESS, VM_MAX_USER_ADDRESS);
211         pmap_pinit2(vmspace_pmap(efi_vmspace));
212         efi_obj = cdev_pager_allocate(NULL, OBJT_MGTDEVICE, &efi_pager_ops,
213                                   VM_MAX_USER_ADDRESS,
214                                   VM_PROT_READ | VM_PROT_WRITE,
215                                   0, proc0.p_ucred);
216         vm_object_hold(efi_obj);
217
218         count = vm_map_entry_reserve(MAP_RESERVE_COUNT);
219         vm_map_lock(&efi_vmspace->vm_map);
220         result = vm_map_insert(&efi_vmspace->vm_map, &count, efi_obj, NULL,
221                               0, 0, VM_MAX_USER_ADDRESS,
222                               VM_MAPTYPE_NORMAL,
223                               VM_PROT_READ | VM_PROT_WRITE | VM_PROT_EXECUTE,
224                               VM_PROT_READ | VM_PROT_WRITE | VM_PROT_EXECUTE,
225                               0);
226         vm_map_unlock(&efi_vmspace->vm_map);
227         if (result != KERN_SUCCESS)
228                 goto fail;
229
230         for (i = 0, p = map;
231              i < ndesc; i++, p = efi_next_descriptor(p, descsz)) {
232                 vm_offset_t va;
233                 uint64_t idx;
234                 int mode;
235
236                 if ((p->md_attr & EFI_MD_ATTR_RT) == 0)
237                         continue;
238                 if (p->md_virt != NULL) {
239                         if (bootverbose)
240                                 kprintf("EFI Runtime entry %d is mapped\n", i);
241                         goto fail;
242                 }
243                 if ((p->md_phys & EFI_PAGE_MASK) != 0) {
244                         if (bootverbose)
245                                 kprintf("EFI Runtime entry %d is not aligned\n",
246                                     i);
247                         goto fail;
248                 }
249                 if (p->md_phys + p->md_pages * EFI_PAGE_SIZE < p->md_phys ||
250                     p->md_phys + p->md_pages * EFI_PAGE_SIZE >=
251                     VM_MAX_USER_ADDRESS) {
252                         kprintf("EFI Runtime entry %d is not in mappable for RT:"
253                             "base %#016jx %#jx pages\n",
254                             i, (uintmax_t)p->md_phys,
255                             (uintmax_t)p->md_pages);
256                         goto fail;
257                 }
258
259                 if ((p->md_attr & EFI_MD_ATTR_WB) != 0)
260                         mode = VM_MEMATTR_WRITE_BACK;
261                 else if ((p->md_attr & EFI_MD_ATTR_WT) != 0)
262                         mode = VM_MEMATTR_WRITE_THROUGH;
263                 else if ((p->md_attr & EFI_MD_ATTR_WC) != 0)
264                         mode = VM_MEMATTR_WRITE_COMBINING;
265                 else if ((p->md_attr & EFI_MD_ATTR_WP) != 0)
266                         mode = VM_MEMATTR_WRITE_PROTECTED;
267                 else if ((p->md_attr & EFI_MD_ATTR_UC) != 0)
268                         mode = VM_MEMATTR_UNCACHEABLE;
269                 else {
270                         if (bootverbose)
271                                 kprintf("EFI Runtime entry %d mapping "
272                                     "attributes unsupported\n", i);
273                         mode = VM_MEMATTR_UNCACHEABLE;
274                 }
275
276                 if (bootverbose) {
277                         kprintf("efirt: map %016jx-%016jx\n",
278                                 p->md_phys,
279                                 p->md_phys + IDX_TO_OFF(p->md_pages));
280                 }
281
282                 for (va = p->md_phys, idx = 0; idx < p->md_pages; idx++,
283                     va += PAGE_SIZE) {
284                         m = kmalloc(sizeof(*m), M_EFI, M_WAITOK | M_ZERO);
285                         /*m->flags |= PG_WRITEABLE;*/
286                         vm_page_initfake(m, va, mode);  /* va is phys addr */
287                         m->valid = VM_PAGE_BITS_ALL;
288                         m->dirty = m->valid;
289                         vm_page_insert(m, efi_obj, OFF_TO_IDX(va));
290                         vm_page_wakeup(m);
291                 }
292         }
293         vm_object_drop(efi_obj);
294         vm_map_entry_release(count);
295
296         return true;
297
298 fail:
299         vm_object_drop(efi_obj);
300         vm_map_entry_release(count);
301         efi_destroy_1t1_map();
302
303         return false;
304 }
305
306 /*
307  * Create an environment for the EFI runtime code call.  The most
308  * important part is creating the required 1:1 physical->virtual
309  * mappings for the runtime segments.  To do that, we manually create
310  * page table which unmap userspace but gives correct kernel mapping.
311  * The 1:1 mappings for runtime segments usually occupy low 4G of the
312  * physical address map.
313  *
314  * The 1:1 mappings were chosen over the SetVirtualAddressMap() EFI RT
315  * service, because there are some BIOSes which fail to correctly
316  * relocate itself on the call, requiring both 1:1 and virtual
317  * mapping.  As result, we must provide 1:1 mapping anyway, so no
318  * reason to bother with the virtual map, and no need to add a
319  * complexity into loader.
320  *
321  * The fpu_kern_enter() call allows firmware to use FPU, as mandated
322  * by the specification.  In particular, CR0.TS bit is cleared.  Also
323  * it enters critical section, giving us neccessary protection against
324  * context switch.
325  *
326  * There is no need to disable interrupts around the change of %cr3,
327  * the kernel mappings are correct, while we only grabbed the
328  * userspace portion of VA.  Interrupts handlers must not access
329  * userspace.  Having interrupts enabled fixes the issue with
330  * firmware/SMM long operation, which would negatively affect IPIs,
331  * esp. TLB shootdown requests.
332  */
333 static int
334 efi_enter(void)
335 {
336         thread_t td = curthread;
337
338         if (efi_runtime == NULL)
339                 return (ENXIO);
340         lockmgr(&efi_lock, LK_EXCLUSIVE);
341         efi_savevm = td->td_lwp->lwp_vmspace;
342         pmap_setlwpvm(td->td_lwp, efi_vmspace);
343         npxpush(&efi_ctx);
344         cpu_invltlb();
345
346         return (0);
347 }
348
349 static void
350 efi_leave(void)
351 {
352         thread_t td = curthread;
353
354         pmap_setlwpvm(td->td_lwp, efi_savevm);
355         npxpop(&efi_ctx);
356         cpu_invltlb();
357         efi_savevm = NULL;
358         lockmgr(&efi_lock, LK_RELEASE);
359 }
360
361 static int
362 efi_init(void)
363 {
364         struct efi_map_header *efihdr;
365         struct efi_md *map;
366         caddr_t kmdp;
367         size_t efisz;
368
369         lockinit(&efi_lock, "efi", 0, LK_CANRECURSE);
370         lockinit(&resettodr_lock, "efitodr", 0, LK_CANRECURSE);
371
372         if (efi_systbl_phys == 0) {
373                 if (bootverbose)
374                         kprintf("EFI systbl not available\n");
375                 return (ENXIO);
376         }
377         efi_systbl = (struct efi_systbl *)PHYS_TO_DMAP(efi_systbl_phys);
378         if (efi_systbl->st_hdr.th_sig != EFI_SYSTBL_SIG) {
379                 efi_systbl = NULL;
380                 if (bootverbose)
381                         kprintf("EFI systbl signature invalid\n");
382                 return (ENXIO);
383         }
384         efi_cfgtbl = (efi_systbl->st_cfgtbl == 0) ? NULL :
385             (struct efi_cfgtbl *)efi_systbl->st_cfgtbl;
386         if (efi_cfgtbl == NULL) {
387                 if (bootverbose)
388                         kprintf("EFI config table is not present\n");
389         }
390
391         kmdp = preload_search_by_type("elf kernel");
392         if (kmdp == NULL)
393                 kmdp = preload_search_by_type("elf64 kernel");
394         efihdr = (struct efi_map_header *)preload_search_info(kmdp,
395             MODINFO_METADATA | MODINFOMD_EFI_MAP);
396         if (efihdr == NULL) {
397                 if (bootverbose)
398                         kprintf("EFI map is not present\n");
399                 return (ENXIO);
400         }
401         efisz = (sizeof(struct efi_map_header) + 0xf) & ~0xf;
402         map = (struct efi_md *)((uint8_t *)efihdr + efisz);
403         if (efihdr->descriptor_size == 0)
404                 return (ENOMEM);
405
406         if (!efi_create_1t1_map(map, efihdr->memory_size /
407             efihdr->descriptor_size, efihdr->descriptor_size)) {
408                 if (bootverbose)
409                         kprintf("EFI cannot create runtime map\n");
410                 return (ENOMEM);
411         }
412
413         efi_runtime = (efi_systbl->st_rt == 0) ? NULL :
414                         (struct efi_rt *)efi_systbl->st_rt;
415         if (efi_runtime == NULL) {
416                 if (bootverbose)
417                         kprintf("EFI runtime services table is not present\n");
418                 efi_destroy_1t1_map();
419                 return (ENXIO);
420         }
421
422         return (0);
423 }
424
425 static void
426 efi_uninit(void)
427 {
428         efi_destroy_1t1_map();
429
430         efi_systbl = NULL;
431         efi_cfgtbl = NULL;
432         efi_runtime = NULL;
433
434         lockuninit(&efi_lock);
435         lockuninit(&resettodr_lock);
436 }
437
438 int
439 efi_get_table(struct uuid *uuid, void **ptr)
440 {
441         struct efi_cfgtbl *ct;
442         u_long count;
443
444         if (efi_cfgtbl == NULL)
445                 return (ENXIO);
446         count = efi_systbl->st_entries;
447         ct = efi_cfgtbl;
448         while (count--) {
449                 if (!bcmp(&ct->ct_uuid, uuid, sizeof(*uuid))) {
450                         *ptr = (void *)PHYS_TO_DMAP(ct->ct_data);
451                         return (0);
452                 }
453                 ct++;
454         }
455         return (ENOENT);
456 }
457
458 char SaveCode[1024];
459
460 int
461 efi_get_time_locked(struct efi_tm *tm)
462 {
463         efi_status status;
464         int error;
465
466         KKASSERT(lockowned(&resettodr_lock) != 0);
467         error = efi_enter();
468         if (error != 0)
469                 return (error);
470         status = efi_runtime->rt_gettime(tm, NULL);
471         efi_leave();
472         error = efi_status_to_errno(status);
473
474         return (error);
475 }
476
477 int
478 efi_get_time(struct efi_tm *tm)
479 {
480         int error;
481
482         if (efi_runtime == NULL)
483                 return (ENXIO);
484         lockmgr(&resettodr_lock, LK_EXCLUSIVE);
485         error = efi_get_time_locked(tm);
486         lockmgr(&resettodr_lock, LK_RELEASE);
487
488         return (error);
489 }
490
491 int
492 efi_reset_system(void)
493 {
494         int error;
495
496         error = efi_enter();
497         if (error != 0)
498                 return (error);
499         efi_runtime->rt_reset(EFI_RESET_WARM, 0, 0, NULL);
500         efi_leave();
501         return (EIO);
502 }
503
504 int
505 efi_set_time_locked(struct efi_tm *tm)
506 {
507         efi_status status;
508         int error;
509
510         KKASSERT(lockowned(&resettodr_lock) != 0);
511         error = efi_enter();
512         if (error != 0)
513                 return (error);
514         status = efi_runtime->rt_settime(tm);
515         efi_leave();
516         error = efi_status_to_errno(status);
517         return (error);
518 }
519
520 int
521 efi_set_time(struct efi_tm *tm)
522 {
523         int error;
524
525         if (efi_runtime == NULL)
526                 return (ENXIO);
527         lockmgr(&resettodr_lock, LK_EXCLUSIVE);
528         error = efi_set_time_locked(tm);
529         lockmgr(&resettodr_lock, LK_RELEASE);
530         return (error);
531 }
532
533 int
534 efi_var_get(efi_char *name, struct uuid *vendor, uint32_t *attrib,
535     size_t *datasize, void *data)
536 {
537         efi_status status;
538         int error;
539
540         error = efi_enter();
541         if (error != 0)
542                 return (error);
543         status = efi_runtime->rt_getvar(name, vendor, attrib, datasize, data);
544         efi_leave();
545         error = efi_status_to_errno(status);
546         return (error);
547 }
548
549 int
550 efi_var_nextname(size_t *namesize, efi_char *name, struct uuid *vendor)
551 {
552         efi_status status;
553         int error;
554
555         error = efi_enter();
556         if (error != 0)
557                 return (error);
558         status = efi_runtime->rt_scanvar(namesize, name, vendor);
559         efi_leave();
560         error = efi_status_to_errno(status);
561         return (error);
562 }
563
564 int
565 efi_var_set(efi_char *name, struct uuid *vendor, uint32_t attrib,
566     size_t datasize, void *data)
567 {
568         efi_status status;
569         int error;
570
571         error = efi_enter();
572         if (error != 0)
573                 return (error);
574         status = efi_runtime->rt_setvar(name, vendor, attrib, datasize, data);
575         efi_leave();
576         error = efi_status_to_errno(status);
577         return (error);
578 }
579
580 static int
581 efirt_modevents(module_t m, int event, void *arg __unused)
582 {
583
584         switch (event) {
585         case MOD_LOAD:
586                 return (efi_init());
587
588         case MOD_UNLOAD:
589                 efi_uninit();
590                 return (0);
591
592         case MOD_SHUTDOWN:
593                 return (0);
594
595         default:
596                 return (EOPNOTSUPP);
597         }
598 }
599
600 static moduledata_t efirt_moddata = {
601         .name = "efirt",
602         .evhand = efirt_modevents,
603         .priv = NULL,
604 };
605
606 DECLARE_MODULE(efirt, efirt_moddata, SI_SUB_DRIVERS, SI_ORDER_ANY);
607 MODULE_VERSION(efirt, 1);
608
609
610 /* XXX debug stuff */
611 static int
612 efi_time_sysctl_handler(SYSCTL_HANDLER_ARGS)
613 {
614         union {
615                 struct efi_tm tm;
616                 char buf[256];
617         } u;
618         int error, val;
619 #define tm      u.tm
620
621         val = 0;
622         error = sysctl_handle_int(oidp, &val, 0, req);
623         if (error != 0 || req->newptr == NULL)
624                 return (error);
625         error = efi_get_time(&tm);
626         if (error == 0) {
627                 uprintf("EFI reports: Year %d Month %d Day %d Hour %d Min %d "
628                     "Sec %d\n", tm.tm_year, tm.tm_mon, tm.tm_mday, tm.tm_hour,
629                     tm.tm_min, tm.tm_sec);
630         }
631         return (error);
632 }
633
634 #undef tm
635
636 SYSCTL_PROC(_debug, OID_AUTO, efi_time, CTLTYPE_INT | CTLFLAG_RW, NULL, 0,
637             efi_time_sysctl_handler, "I", "");