static int fix_sfi_table(char *sig, sfi_table_handler handler) { struct sfi_table_header *table = NULL; int ret = -EINVAL; table = get_sfi_table(sig); if (!table) goto exit; ret = handler(table); exit: return ret; }
int sfi_early_init(sfi_info_t *sfi_info) { int i; size_t syst_num; phys_addr_t low_frame; phys_addr_t high_frame; phys_addr_t syst_phys; memset(sfi_info, 0, sizeof(*sfi_info)); syst_phys = sfi_syst_phys(); if(syst_phys == -1) { return 0; } low_frame = high_frame = syst_phys; sfi_info->system_table = (sfi_system_table_t*) (((char*)map_virtual_page((syst_phys & 0xFFFFF000) | 3)) + (syst_phys & 0xFFF)); syst_num = SFI_NUM_SYST_ENTRIES(sfi_info->system_table); for(i = 0; i < syst_num; i++) { if(sfi_info->system_table->entries[i] > 0xFFFFFFFF) { panic("SFI table above 4G region"); } if(sfi_info->system_table->entries[i] < low_frame) { low_frame = sfi_info->system_table->entries[i]; } if(sfi_info->system_table->entries[i] > high_frame) { high_frame = sfi_info->system_table->entries[i]; } } sfi_info->low_frame = low_frame = low_frame & 0xFFFFF000; high_frame &= 0xFFFFF000; unmap_virtual_page(sfi_info->system_table); sfi_info->num_frames = ((high_frame - low_frame) / 0x1000) + 1; sfi_info->start_addr = map_contiguous_virtual_pages(low_frame | 3, sfi_info->num_frames); if(sfi_info->start_addr == NULL) { panic("Failed to map STI"); } sfi_info->system_table = (sfi_system_table_t*) SFI_PHYS_TO_VIRT(sfi_info, syst_phys); print_syst_table(sfi_info); sfi_info->cpus_table = get_sfi_table(sfi_info, SFI_SIG_CPUS); print_cpus_table(sfi_info); sfi_info->apic_table = get_sfi_table(sfi_info, SFI_SIG_APIC); print_apic_table(sfi_info); sfi_info->mmap_table = get_sfi_table(sfi_info, SFI_SIG_MMAP); print_mmap_table(sfi_info); sfi_info->freq_table = get_sfi_table(sfi_info, SFI_SIG_FREQ); print_freq_table(sfi_info); sfi_info->mtmr_table = get_sfi_table(sfi_info, SFI_SIG_MTMR); print_mtmr_table(sfi_info); sfi_info->mrtc_table = get_sfi_table(sfi_info, SFI_SIG_MRTC); print_mrtc_table(sfi_info); sfi_info->wake_table = get_sfi_table(sfi_info, SFI_SIG_WAKE); print_wake_table(sfi_info); sfi_info->devs_table = get_sfi_table(sfi_info, SFI_SIG_DEVS); print_devs_table(sfi_info); sfi_info->gpio_table = get_sfi_table(sfi_info, SFI_SIG_GPIO); print_gpio_table(sfi_info); sfi_info->xsdt_table = get_sfi_table(sfi_info, SFI_SIG_XSDT); print_xsdt_table(sfi_info); return 0; }