efi.c
来自「xen虚拟机源代码安装包」· C语言 代码 · 共 238 行
C
238 行
/* * Done by Dietmar Hahn <dietmar.hahn@fujitsu-siemens.com> * The code is partly taken from FreeBSD. * *************************************************************************** * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * */#include "os.h"#include "efi.h"#include "page.h"#include "lib.h"#include "console.h"/* The implementation is in fw.S. */extern uint64_tia64_call_efi_func(uint64_t funcP,uint64_t a,uint64_t b,uint64_t c,uint64_t d);intefi_get_time(efi_time_t* tmP){ memset(tmP, 0, sizeof(efi_time_t)); if (ia64_call_efi_func((uint64_t)machineFwG.efi.getTimeF, (uint64_t)tmP, (uint64_t)NULL, 0, 0) != EFI_SUCCESS) { printk("efi.getTime() failed\n"); return 0; }#if defined(BIG_ENDIAN) tmP->Year = SWAP(tmP->Year); tmP->TimeZone = SWAP(tmP->TimeZone); tmP->Nanosecond = SWAP(tmP->Nanosecond);#endif return 1;}/* * The function compares two efi_guid_t and returns 0 on equality, otherwise 1. */static intefi_guid_cmp(efi_guid_t* a_le, efi_guid_t* b){#if defined(BIG_ENDIAN) if(SWAP(a_le->Data1) != b->Data1) return 1; if(SWAP(a_le->Data2) != b->Data2) return 1; if(SWAP(a_le->Data3) != b->Data3) return 1; return memcmp(a_le->Data4, b->Data4, sizeof(uint8_t)*8);#else return memcmp(a_le, b, sizeof(efi_guid_t));#endif}voidinit_efi(void){ efi_system_table_t* efiSysTableP; int mdcnt, i, numConvMem; efi_memory_descriptor_t *memdP, *mdP; efi_status_t status; char fwVendor[100] = "unknown"; efi_char16_t* fwP; efi_runtime_services_t* rsP; efi_configuration_table_t* confP = (efi_configuration_table_t*)0; efi_guid_t sal = SAL_SYSTEM_TABLE_GUID; efi_guid_t acpi = ACPI_TABLE_GUID; efi_guid_t acpi20 = ACPI_20_TABLE_GUID; memset(&machineFwG, 0, sizeof(machineFwG)); /* Read the efi_system_table. */ efiSysTableP = (efi_system_table_t*)__va(ia64BootParamG.efi_systab); machineFwG.efi.efiSysTableP = efiSysTableP; PRINT_BV("EfiSystemTable at: %p\n", efiSysTableP); fwP = (uint16_t*) __va(SWAP(efiSysTableP->FirmwareVendor)); if (fwP) { for (i = 0; i < (int)sizeof(fwVendor) - 1 && *fwP; ++i) fwVendor[i] = SWAP(*fwP++); fwVendor[i] = '\0'; } PRINT_BV(" EFI-FirmwareVendor : %s\n", fwVendor); PRINT_BV(" EFI-FirmwareRevision : %d\n", SWAP(efiSysTableP->FirmwareRevision)); PRINT_BV(" EFI-SystemTable-Revision : %d.%d\n", SWAP(efiSysTableP->Hdr.Revision)>>16, SWAP(efiSysTableP->Hdr.Revision)&0xffff); rsP = (efi_runtime_services_t*) __va(SWAP(efiSysTableP->RuntimeServices)); mdcnt = ia64BootParamG.efi_memmap_size / ia64BootParamG.efi_memdesc_size; memdP = (efi_memory_descriptor_t*) __va(ia64BootParamG.efi_memmap); PRINT_BV("EFI-Memorydescriptors: %d\n", mdcnt); for (i = numConvMem = 0, mdP = memdP; i < mdcnt; i++, mdP = NextMemoryDescriptor(mdP, ia64BootParamG.efi_memdesc_size)) { /* Relocate runtime memory segments for firmware. */ PRINT_BV(" %d. Type: %x Attributes: 0x%lx\n", i, SWAP(mdP->Type), SWAP(mdP->Attribute)); PRINT_BV(" PhysStart: 0x%lx NumPages: 0x%lx\n", SWAP(mdP->PhysicalStart), SWAP(mdP->NumberOfPages)); switch (SWAP(mdP->Type)) { case EfiRuntimeServicesData: PRINT_BV(" -> EfiRuntimeServicesData\n"); break; case EfiACPIReclaimMemory: PRINT_BV(" -> EfiACPIReclaimMemory\n"); break; case EfiACPIMemoryNVS: PRINT_BV(" -> EfiACPIMemoryNVS\n"); break; case EfiConventionalMemory: PRINT_BV(" -> EfiConventionalMemory\n"); PRINT_BV(" start: 0x%lx end: 0x%lx\n", SWAP(mdP->PhysicalStart), SWAP(mdP->PhysicalStart)+ SWAP(mdP->NumberOfPages)*EFI_PAGE_SIZE); if (numConvMem) { printk(" Currently only one efi " "memory chunk supported !!!\n"); break; } machineFwG.mach_mem_start = SWAP(mdP->PhysicalStart); machineFwG.mach_mem_size = SWAP(mdP->NumberOfPages)*EFI_PAGE_SIZE; numConvMem++; break; case EfiMemoryMappedIOPortSpace: PRINT_BV(" -> EfiMemMappedIOPortSpace\n"); break; case EfiPalCode: machineFwG.ia64_pal_base = __va(SWAP(mdP->PhysicalStart)); PRINT_BV(" -> EfiPalCode\n" " start : %p\n", machineFwG.ia64_pal_base); break; } /* I have to setup the VirtualStart address of every * RUNTIME-area in preparing the later call of * SetVirtualAddressMap() therewidth the efi stuff uses * virtual addressing and the efi runtime functions * may be called directly. */ if (SWAP(mdP->Attribute) & EFI_MEMORY_RUNTIME) { if (SWAP(mdP->Attribute) & EFI_MEMORY_WB) mdP->VirtualStart = SWAP(__va(mdP->PhysicalStart)); else { if (SWAP(mdP->Attribute) & EFI_MEMORY_UC) printk("efi_init: RuntimeMemory with " "UC attribute !!!!!!\n"); /* mdP->VirtualStart = IA64_PHYS_TO_RR6(mdP->PhysicalStart); */ } } } /* Now switch efi runtime stuff to virtual addressing. */ status = ia64_call_efi_physical( (void*)__va(SWAP((uint64_t)rsP->SetVirtualAddressMap)), ia64BootParamG.efi_memmap_size, ia64BootParamG.efi_memdesc_size, ia64BootParamG.efi_memdesc_version, ia64BootParamG.efi_memmap); status = EFI_SUCCESS; if (status != EFI_SUCCESS) { printk("warning: unable to switch EFI into virtual " "(status=%lu)\n", status); return; } /* Getting efi function pointer for getEfiTime. */ machineFwG.efi.getTimeF = (efi_get_time_t)__va(SWAP((uint64_t)rsP->GetTime)); /* Getting efi function pointer for resetSystem. */ machineFwG.efi.resetSystemF = (efi_reset_system_t)__va(SWAP((uint64_t)rsP->ResetSystem)); /* Scanning the Configuration table of the EfiSystemTable. */ PRINT_BV("NumberOfConfigTableEntries: %ld\n", SWAP(efiSysTableP->NumberOfTableEntries)); confP = (efi_configuration_table_t*) __va(SWAP(efiSysTableP->ConfigurationTable)); for (i = 0; i < SWAP(efiSysTableP->NumberOfTableEntries); i++) { if (!efi_guid_cmp(&confP[i].VendorGuid, &sal)) { machineFwG.ia64_sal_tableP = (sal_system_table_t*) __va(SWAP((uint64_t) confP[i].VendorTable)); PRINT_BV(" Found SalSystemTable at: 0x%lx\n", (uint64_t) machineFwG.ia64_sal_tableP); continue; } if (!efi_guid_cmp(&confP[i].VendorGuid, &acpi)) { machineFwG.ia64_efi_acpi_table = __va(SWAP((uint64_t) confP[i].VendorTable)); PRINT_BV(" Found AcpiTable at: 0x%lx\n", (uint64_t) machineFwG.ia64_efi_acpi_table); continue; } if (!efi_guid_cmp(&confP[i].VendorGuid, &acpi20)) { machineFwG.ia64_efi_acpi20_table = __va(SWAP((uint64_t) confP[i].VendorTable)); PRINT_BV(" Found Acpi20Table at: 0x%lx\n", (uint64_t) machineFwG.ia64_efi_acpi20_table); continue; } }}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?