]> CyberLeo.Net >> Repos - FreeBSD/releng/7.2.git/blob - sys/ia64/ia64/efi.c
Create releng/7.2 from stable/7 in preparation for 7.2-RELEASE.
[FreeBSD/releng/7.2.git] / sys / ia64 / ia64 / efi.c
1 /*-
2  * Copyright (c) 2004 Marcel Moolenaar
3  * Copyright (c) 2001 Doug Rabson
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25  * SUCH DAMAGE.
26  */
27
28 #include <sys/cdefs.h>
29 __FBSDID("$FreeBSD$");
30
31 #include <sys/param.h>
32 #include <sys/systm.h>
33 #include <machine/bootinfo.h>
34 #include <machine/efi.h>
35 #include <machine/sal.h>
36
37 extern uint64_t ia64_call_efi_physical(uint64_t, uint64_t, uint64_t, uint64_t,
38     uint64_t, uint64_t);
39
40 static struct efi_systbl *efi_systbl;
41 static struct efi_cfgtbl *efi_cfgtbl;
42 static struct efi_rt *efi_runtime;
43
44 void
45 efi_boot_finish(void)
46 {
47 }
48
49 /*
50  * Collect the entry points for PAL and SAL. Be extra careful about NULL
51  * pointer values. We're running pre-console, so it's better to return
52  * error values than to cause panics, machine checks and other traps and
53  * faults. Keep this minimal...
54  */
55 int
56 efi_boot_minimal(uint64_t systbl)
57 {
58         struct efi_md *md;
59         efi_status status;
60
61         if (systbl == 0)
62                 return (EINVAL);
63         efi_systbl = (struct efi_systbl *)IA64_PHYS_TO_RR7(systbl);
64         if (efi_systbl->st_hdr.th_sig != EFI_SYSTBL_SIG) {
65                 efi_systbl = NULL;
66                 return (EFAULT);
67         }
68         efi_cfgtbl = (efi_systbl->st_cfgtbl == 0) ? NULL :
69             (struct efi_cfgtbl *)IA64_PHYS_TO_RR7(efi_systbl->st_cfgtbl);
70         if (efi_cfgtbl == NULL)
71                 return (ENOENT);
72         efi_runtime = (efi_systbl->st_rt == 0) ? NULL :
73             (struct efi_rt *)IA64_PHYS_TO_RR7(efi_systbl->st_rt);
74         if (efi_runtime == NULL)
75                 return (ENOENT);
76
77         /*
78          * Relocate runtime memory segments for firmware.
79          */
80         md = efi_md_first();
81         while (md != NULL) {
82                 if (md->md_attr & EFI_MD_ATTR_RT) {
83                         if (md->md_attr & EFI_MD_ATTR_WB)
84                                 md->md_virt =
85                                     (void *)IA64_PHYS_TO_RR7(md->md_phys);
86                         else if (md->md_attr & EFI_MD_ATTR_UC)
87                                 md->md_virt =
88                                     (void *)IA64_PHYS_TO_RR6(md->md_phys);
89                 }
90                 md = efi_md_next(md);
91         }
92         status = ia64_call_efi_physical((uint64_t)efi_runtime->rt_setvirtual,
93             bootinfo.bi_memmap_size, bootinfo.bi_memdesc_size,
94             bootinfo.bi_memdesc_version, bootinfo.bi_memmap, 0);
95         return ((status < 0) ? EFAULT : 0);
96 }
97
98 void *
99 efi_get_table(struct uuid *uuid)
100 {
101         struct efi_cfgtbl *ct;
102         u_long count;
103
104         if (efi_cfgtbl == NULL)
105                 return (NULL);
106         count = efi_systbl->st_entries;
107         ct = efi_cfgtbl;
108         while (count--) {
109                 if (!memcmp(&ct->ct_uuid, uuid, sizeof(*uuid)))
110                         return ((void *)IA64_PHYS_TO_RR7(ct->ct_data));
111                 ct++;
112         }
113         return (NULL);
114 }
115
116 void
117 efi_get_time(struct efi_tm *tm)
118 {
119
120         efi_runtime->rt_gettime(tm, NULL);
121 }
122
123 struct efi_md *
124 efi_md_first(void)
125 {
126
127         if (bootinfo.bi_memmap == 0)
128                 return (NULL);
129         return ((struct efi_md *)IA64_PHYS_TO_RR7(bootinfo.bi_memmap));
130 }
131
132 struct efi_md *
133 efi_md_next(struct efi_md *md)
134 {
135         uint64_t plim;
136
137         plim = IA64_PHYS_TO_RR7(bootinfo.bi_memmap + bootinfo.bi_memmap_size);
138         md = (struct efi_md *)((uintptr_t)md + bootinfo.bi_memdesc_size);
139         return ((md >= (struct efi_md *)plim) ? NULL : md);
140 }
141
142 void
143 efi_reset_system(void)
144 {
145
146         if (efi_runtime != NULL)
147                 efi_runtime->rt_reset(EFI_RESET_WARM, 0, 0, NULL);
148         panic("%s: unable to reset the machine", __func__);
149 }
150
151 efi_status
152 efi_set_time(struct efi_tm *tm)
153 {
154
155         return (efi_runtime->rt_settime(tm));
156 }