ia64/xen-unstable

view extras/mini-os/arch/ia64/efi.c @ 13907:ac18d251df63

[IA64][MINIOS] Port of mini-os to ia64

ia64 specific parts of mini-os.

Minimal config:

# Kernel image file.
kernel = "mini-os.gz"
# Initial memory allocation (in megabytes) for the new domain.
memory = 64
# A name for your domain.
name = "Mini-OS"

Signed-off-by: Dietmar Hahn <dietmar.hahn@fujitsu-siemens.com>
author awilliam@xenbuild2.aw
date Thu Feb 15 13:13:36 2007 -0700 (2007-02-15)
parents
children 7ef733b961c8
line source
1 /*
2 * Done by Dietmar Hahn <dietmar.hahn@fujitsu-siemens.com>
3 * The code is partly taken from FreeBSD.
4 *
5 ***************************************************************************
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * SUCH DAMAGE.
27 *
28 */
31 #include "os.h"
32 #include "efi.h"
33 #include "page.h"
34 #include "lib.h"
35 #include "console.h"
38 /* The implementation is in fw.S. */
39 extern uint64_t
40 ia64_call_efi_func(uint64_t funcP,uint64_t a,uint64_t b,uint64_t c,uint64_t d);
42 int
43 efi_get_time(efi_time_t* tmP)
44 {
45 memset(tmP, 0, sizeof(efi_time_t));
46 if (ia64_call_efi_func((uint64_t)machineFwG.efi.getTimeF,
47 (uint64_t)tmP,
48 (uint64_t)NULL, 0, 0) != EFI_SUCCESS) {
49 printk("efi.getTime() failed\n");
50 return 0;
51 }
53 #if defined(BIG_ENDIAN)
54 tmP->Year = SWAP(tmP->Year);
55 tmP->TimeZone = SWAP(tmP->TimeZone);
56 tmP->Nanosecond = SWAP(tmP->Nanosecond);
57 #endif
59 return 1;
60 }
62 /*
63 * The function compares two efi_guid_t and returns 0 on equality, otherwise 1.
64 */
65 static int
66 efi_guid_cmp(efi_guid_t* a_le, efi_guid_t* b)
67 {
68 #if defined(BIG_ENDIAN)
69 if(SWAP(a_le->Data1) != b->Data1)
70 return 1;
71 if(SWAP(a_le->Data2) != b->Data2)
72 return 1;
73 if(SWAP(a_le->Data3) != b->Data3)
74 return 1;
75 return memcmp(a_le->Data4, b->Data4, sizeof(uint8_t)*8);
76 #else
77 return memcmp(a_le, b, sizeof(efi_guid_t));
78 #endif
79 }
81 void
82 init_efi(void)
83 {
84 efi_system_table_t* efiSysTableP;
85 int mdcnt, i, numConvMem;
86 efi_memory_descriptor_t *memdP, *mdP;
87 efi_status_t status;
88 char fwVendor[100] = "unknown";
89 efi_char16_t* fwP;
90 efi_runtime_services_t* rsP;
92 efi_configuration_table_t* confP = (efi_configuration_table_t*)0;
93 efi_guid_t sal = SAL_SYSTEM_TABLE_GUID;
94 efi_guid_t acpi = ACPI_TABLE_GUID;
95 efi_guid_t acpi20 = ACPI_20_TABLE_GUID;
97 memset(&machineFwG, 0, sizeof(machineFwG));
98 /* Read the efi_system_table. */
99 efiSysTableP = (efi_system_table_t*)__va(ia64BootParamG.efi_systab);
100 machineFwG.efi.efiSysTableP = efiSysTableP;
101 PRINT_BV("EfiSystemTable at: %p\n", efiSysTableP);
102 fwP = (uint16_t*) __va(SWAP(efiSysTableP->FirmwareVendor));
103 if (fwP) {
104 for (i = 0; i < (int)sizeof(fwVendor) - 1 && *fwP; ++i)
105 fwVendor[i] = SWAP(*fwP++);
106 fwVendor[i] = '\0';
107 }
108 PRINT_BV(" EFI-FirmwareVendor : %s\n", fwVendor);
109 PRINT_BV(" EFI-FirmwareRevision : %d\n",
110 SWAP(efiSysTableP->FirmwareRevision));
111 PRINT_BV(" EFI-SystemTable-Revision : %d.%d\n",
112 SWAP(efiSysTableP->Hdr.Revision)>>16,
113 SWAP(efiSysTableP->Hdr.Revision)&0xffff);
114 rsP = (efi_runtime_services_t*)
115 __va(SWAP(efiSysTableP->RuntimeServices));
116 mdcnt = ia64BootParamG.efi_memmap_size /
117 ia64BootParamG.efi_memdesc_size;
118 memdP = (efi_memory_descriptor_t*) __va(ia64BootParamG.efi_memmap);
120 PRINT_BV("EFI-Memorydescriptors: %d\n", mdcnt);
122 for (i = numConvMem = 0, mdP = memdP; i < mdcnt; i++,
123 mdP = NextMemoryDescriptor(mdP, ia64BootParamG.efi_memdesc_size)) {
124 /* Relocate runtime memory segments for firmware. */
125 PRINT_BV(" %d. Type: %x Attributes: 0x%lx\n",
126 i, SWAP(mdP->Type), SWAP(mdP->Attribute));
127 PRINT_BV(" PhysStart: 0x%lx NumPages: 0x%lx\n",
128 SWAP(mdP->PhysicalStart), SWAP(mdP->NumberOfPages));
129 switch (SWAP(mdP->Type)) {
130 case EfiRuntimeServicesData:
131 PRINT_BV(" -> EfiRuntimeServicesData\n");
132 break;
133 case EfiACPIReclaimMemory:
134 PRINT_BV(" -> EfiACPIReclaimMemory\n");
135 break;
136 case EfiACPIMemoryNVS:
137 PRINT_BV(" -> EfiACPIMemoryNVS\n");
138 break;
139 case EfiConventionalMemory:
140 PRINT_BV(" -> EfiConventionalMemory\n");
141 PRINT_BV(" start: 0x%lx end: 0x%lx\n",
142 SWAP(mdP->PhysicalStart),
143 SWAP(mdP->PhysicalStart)+
144 SWAP(mdP->NumberOfPages)*EFI_PAGE_SIZE);
145 if (numConvMem) {
146 printk(" Currently only one efi "
147 "memory chunk supported !!!\n");
148 break;
149 }
150 machineFwG.mach_mem_start =
151 SWAP(mdP->PhysicalStart);
152 machineFwG.mach_mem_size =
153 SWAP(mdP->NumberOfPages)*EFI_PAGE_SIZE;
154 numConvMem++;
155 break;
156 case EfiMemoryMappedIOPortSpace:
157 PRINT_BV(" -> EfiMemMappedIOPortSpace\n");
158 break;
159 case EfiPalCode:
160 machineFwG.ia64_pal_base =
161 __va(SWAP(mdP->PhysicalStart));
162 PRINT_BV(" -> EfiPalCode\n"
163 " start : %p\n",
164 machineFwG.ia64_pal_base);
165 break;
166 }
167 /* I have to setup the VirtualStart address of every
168 * RUNTIME-area in preparing the later call of
169 * SetVirtualAddressMap() therewidth the efi stuff uses
170 * virtual addressing and the efi runtime functions
171 * may be called directly.
172 */
173 if (SWAP(mdP->Attribute) & EFI_MEMORY_RUNTIME) {
174 if (SWAP(mdP->Attribute) & EFI_MEMORY_WB)
175 mdP->VirtualStart =
176 SWAP(__va(mdP->PhysicalStart));
177 else {
178 if (SWAP(mdP->Attribute) & EFI_MEMORY_UC)
179 printk("efi_init: RuntimeMemory with "
180 "UC attribute !!!!!!\n");
181 /*
182 mdP->VirtualStart =
183 IA64_PHYS_TO_RR6(mdP->PhysicalStart);
184 */
185 }
186 }
187 }
188 /* Now switch efi runtime stuff to virtual addressing. */
189 status = ia64_call_efi_physical(
190 (void*)__va(SWAP((uint64_t)rsP->SetVirtualAddressMap)),
191 ia64BootParamG.efi_memmap_size,
192 ia64BootParamG.efi_memdesc_size,
193 ia64BootParamG.efi_memdesc_version,
194 ia64BootParamG.efi_memmap);
195 status = EFI_SUCCESS;
196 if (status != EFI_SUCCESS) {
197 printk("warning: unable to switch EFI into virtual "
198 "(status=%lu)\n", status);
199 return;
200 }
201 /* Getting efi function pointer for getEfiTime. */
202 machineFwG.efi.getTimeF =
203 (efi_get_time_t)__va(SWAP((uint64_t)rsP->GetTime));
204 /* Getting efi function pointer for resetSystem. */
205 machineFwG.efi.resetSystemF =
206 (efi_reset_system_t)__va(SWAP((uint64_t)rsP->ResetSystem));
208 /* Scanning the Configuration table of the EfiSystemTable. */
209 PRINT_BV("NumberOfConfigTableEntries: %ld\n",
210 SWAP(efiSysTableP->NumberOfTableEntries));
212 confP = (efi_configuration_table_t*)
213 __va(SWAP(efiSysTableP->ConfigurationTable));
214 for (i = 0; i < SWAP(efiSysTableP->NumberOfTableEntries); i++) {
215 if (!efi_guid_cmp(&confP[i].VendorGuid, &sal)) {
216 machineFwG.ia64_sal_tableP = (sal_system_table_t*)
217 __va(SWAP((uint64_t) confP[i].VendorTable));
218 PRINT_BV(" Found SalSystemTable at: 0x%lx\n",
219 (uint64_t) machineFwG.ia64_sal_tableP);
220 continue;
221 }
222 if (!efi_guid_cmp(&confP[i].VendorGuid, &acpi)) {
223 machineFwG.ia64_efi_acpi_table =
224 __va(SWAP((uint64_t) confP[i].VendorTable));
225 PRINT_BV(" Found AcpiTable at: 0x%lx\n",
226 (uint64_t) machineFwG.ia64_efi_acpi_table);
227 continue;
228 }
229 if (!efi_guid_cmp(&confP[i].VendorGuid, &acpi20)) {
230 machineFwG.ia64_efi_acpi20_table =
231 __va(SWAP((uint64_t) confP[i].VendorTable));
232 PRINT_BV(" Found Acpi20Table at: 0x%lx\n",
233 (uint64_t) machineFwG.ia64_efi_acpi20_table);
234 continue;
235 }
236 }
237 }