📄 fw-emu.c
字号:
u8 *cp, *cpe, checksum; p->checksum = 0; p->length = length; checksum = 0; for (cp=(u8*)p, cpe=cp+p->length; cp<cpe; cp++) checksum += *cp; p->checksum = -checksum;}voidacpi_checksum_rsdp20(acpi20_rsdp_t *p, int length){ u8 *cp, *cpe, checksum; p->checksum = 0; p->length = length; checksum = 0; for (cp=(u8*)p, cpe=cp+RSDP_CHECKSUM_LENGTH; cp<cpe; cp++) checksum += *cp; p->checksum = -checksum;}intnasid_present(int nasid){ int cnode; for (cnode=0; cnode<num_nodes; cnode++) if (GetNasid(cnode) == nasid) return 1; return 0;}voidsys_fw_init (const char *args, int arglen, int bsp){ /* * Use static variables to keep from overflowing the RSE stack */ static efi_system_table_t *efi_systab; static efi_runtime_services_t *efi_runtime; static efi_config_table_t *efi_tables; static ia64_sal_desc_ptc_t *sal_ptc; static ia64_sal_ptc_domain_info_t *sal_ptcdi; static ia64_sal_ptc_domain_proc_entry_t *sal_ptclid;#ifdef ACPI_1_0 static acpi_rsdp_t *acpi_rsdp; static acpi_rsdt_t *acpi_rsdt; static acpi_sapic_t *acpi_sapic; static acpi_entry_lsapic_t *acpi_lsapic;#endif static acpi20_rsdp_t *acpi20_rsdp; static acpi_xsdt_t *acpi_xsdt; static acpi_slit_t *acpi_slit; static acpi_madt_t *acpi_madt; static acpi20_entry_lsapic_t *lsapic20; static struct ia64_sal_systab *sal_systab; static acpi_srat_t *acpi_srat; static srat_cpu_affinity_t *srat_cpu_affinity; static srat_memory_affinity_t *srat_memory_affinity; static efi_memory_desc_t *efi_memmap, *md; static unsigned long *pal_desc, *sal_desc; static struct ia64_sal_desc_entry_point *sal_ed; static struct ia64_boot_param *bp; static struct ia64_sal_desc_ap_wakeup *sal_apwake; static unsigned char checksum; static char *cp, *cmd_line, *vendor; static void *ptr; static int mdsize, domain, last_domain ; static int i, j, cnode, max_nasid, nasid, cpu, num_memmd, cpus_found; /* * Pass the parameter base address to the build_efi_xxx routines. */#if defined(CONFIG_IA64_SGI_SN1) build_init(8LL*GB*base_nasid);#else build_init(0x3000000000UL | ((long)base_nasid<<38));#endif num_nodes = GetNumNodes(); num_cpus = GetNumCpus(); for (max_nasid=0, cnode=0; cnode<num_nodes; cnode++) max_nasid = MAX(max_nasid, GetNasid(cnode)); memset(fw_mem, 0, sizeof(fw_mem)); pal_desc = (unsigned long *) &pal_emulator; sal_desc = (unsigned long *) &sal_emulator; fix_function_pointer(&pal_emulator); fix_function_pointer(&sal_emulator); /* Align this to 16 bytes, probably EFI does this */ mdsize = (sizeof(efi_memory_desc_t) + 15) & ~15 ; cp = fw_mem; efi_systab = (void *) cp; cp += ALIGN8(sizeof(*efi_systab)); efi_runtime_p = efi_runtime = (void *) cp; cp += ALIGN8(sizeof(*efi_runtime)); efi_tables = (void *) cp; cp += ALIGN8(NUM_EFI_DESCS*sizeof(*efi_tables)); sal_systab = (void *) cp; cp += ALIGN8(sizeof(*sal_systab)); sal_ed = (void *) cp; cp += ALIGN8(sizeof(*sal_ed)); sal_ptc = (void *) cp; cp += ALIGN8(sizeof(*sal_ptc)); sal_apwake = (void *) cp; cp += ALIGN8(sizeof(*sal_apwake)); acpi20_rsdp = (void *) cp; cp += ALIGN8(sizeof(*acpi20_rsdp)); acpi_xsdt = (void *) cp; cp += ALIGN8(sizeof(*acpi_xsdt) + 64); /* save space for more OS defined table pointers. */#ifdef ACPI_1_0 acpi_rsdp = (void *) cp; cp += ALIGN8(sizeof(*acpi_rsdp)); acpi_rsdt = (void *) cp; cp += ALIGN8(sizeof(*acpi_rsdt)); acpi_sapic = (void *) cp; cp += sizeof(*acpi_sapic); acpi_lsapic = (void *) cp; cp += num_cpus*sizeof(*acpi_lsapic);#endif acpi_slit = (void *) cp; cp += ALIGN8(sizeof(*acpi_slit) + 8 + (max_nasid+1)*(max_nasid+1)); acpi_madt = (void *) cp; cp += ALIGN8(sizeof(*acpi_madt) + 8 * num_cpus+ 8); acpi_srat = (void *) cp; cp += ALIGN8(sizeof(acpi_srat_t)); cp += sizeof(srat_cpu_affinity_t)*num_cpus + sizeof(srat_memory_affinity_t)*num_nodes; vendor = (char *) cp; cp += ALIGN8(40); efi_memmap = (void *) cp; cp += ALIGN8(8*32*sizeof(*efi_memmap)); sal_ptcdi = (void *) cp; cp += ALIGN8(CPUS_PER_FSB*(1+num_nodes)*sizeof(*sal_ptcdi)); sal_ptclid = (void *) cp; cp += ALIGN8(((3+num_cpus)*sizeof(*sal_ptclid)+7)/8*8); cmd_line = (void *) cp; if (args) { if (arglen >= 1024) arglen = 1023; memcpy(cmd_line, args, arglen); } else { arglen = 0; } cmd_line[arglen] = '\0'; /* * For now, just bring up bash. * If you want to execute all the startup scripts, delete the "init=..". * You can also edit this line to pass other arguments to the kernel. * Note: disable kernel text replication. */ strcpy(cmd_line, "init=/bin/bash ktreplicate=0"); memset(efi_systab, 0, sizeof(efi_systab)); efi_systab->hdr.signature = EFI_SYSTEM_TABLE_SIGNATURE; efi_systab->hdr.revision = EFI_SYSTEM_TABLE_REVISION; efi_systab->hdr.headersize = sizeof(efi_systab->hdr); efi_systab->fw_vendor = __fwtab_pa(base_nasid, vendor); efi_systab->fw_revision = 1; efi_systab->runtime = __fwtab_pa(base_nasid, efi_runtime); efi_systab->nr_tables = 2; efi_systab->tables = __fwtab_pa(base_nasid, efi_tables); memcpy(vendor, "S\0i\0l\0i\0c\0o\0n\0-\0G\0r\0a\0p\0h\0i\0c\0s\0\0", 40); efi_runtime->hdr.signature = EFI_RUNTIME_SERVICES_SIGNATURE; efi_runtime->hdr.revision = EFI_RUNTIME_SERVICES_REVISION; efi_runtime->hdr.headersize = sizeof(efi_runtime->hdr); efi_runtime->get_time = __fwtab_pa(base_nasid, &efi_get_time); efi_runtime->set_time = __fwtab_pa(base_nasid, &efi_unimplemented); efi_runtime->get_wakeup_time = __fwtab_pa(base_nasid, &efi_unimplemented); efi_runtime->set_wakeup_time = __fwtab_pa(base_nasid, &efi_unimplemented); efi_runtime->set_virtual_address_map = __fwtab_pa(base_nasid, &efi_set_virtual_address_map); efi_runtime->get_variable = __fwtab_pa(base_nasid, &efi_unimplemented); efi_runtime->get_next_variable = __fwtab_pa(base_nasid, &efi_unimplemented); efi_runtime->set_variable = __fwtab_pa(base_nasid, &efi_unimplemented); efi_runtime->get_next_high_mono_count = __fwtab_pa(base_nasid, &efi_unimplemented); efi_runtime->reset_system = __fwtab_pa(base_nasid, &efi_reset_system); efi_tables->guid = SAL_SYSTEM_TABLE_GUID; efi_tables->table = __fwtab_pa(base_nasid, sal_systab); efi_tables++;#ifdef ACPI_1_0 efi_tables->guid = ACPI_TABLE_GUID; efi_tables->table = __fwtab_pa(base_nasid, acpi_rsdp); efi_tables++;#endif efi_tables->guid = ACPI_20_TABLE_GUID; efi_tables->table = __fwtab_pa(base_nasid, acpi20_rsdp); efi_tables++; fix_function_pointer(&efi_unimplemented); fix_function_pointer(&efi_get_time); fix_function_pointer(&efi_success); fix_function_pointer(&efi_reset_system); fix_function_pointer(&efi_set_virtual_address_map);#ifdef ACPI_1_0 /* fill in the ACPI system table - has a pointer to the ACPI table header */ memcpy(acpi_rsdp->signature, "RSD PTR ", 8); acpi_rsdp->rsdt = (struct acpi_rsdt*)__fwtab_pa(base_nasid, acpi_rsdt); acpi_table_init(&acpi_rsdt->header, ACPI_RSDT_SIG, ACPI_RSDT_SIG_LEN, 1, 1); acpi_rsdt->header.length = sizeof(acpi_rsdt_t); acpi_rsdt->entry_ptrs[0] = __fwtab_pa(base_nasid, acpi_sapic); memcpy(acpi_sapic->header.signature, "SPIC ", 4); acpi_sapic->header.length = sizeof(acpi_sapic_t)+num_cpus*sizeof(acpi_entry_lsapic_t); for (cnode=0; cnode<num_nodes; cnode++) { nasid = GetNasid(cnode); for(cpu=0; cpu<CPUS_PER_NODE; cpu++) { if (!IsCpuPresent(cnode, cpu)) continue; acpi_lsapic->type = ACPI_ENTRY_LOCAL_SAPIC; acpi_lsapic->length = sizeof(acpi_entry_lsapic_t); acpi_lsapic->acpi_processor_id = cnode*4+cpu; acpi_lsapic->flags = LSAPIC_ENABLED|LSAPIC_PRESENT;#if defined(CONFIG_IA64_SGI_SN1) acpi_lsapic->eid = cpu; acpi_lsapic->id = nasid;#else acpi_lsapic->eid = nasid&0xffff; acpi_lsapic->id = (cpu<<4) | (nasid>>16);#endif acpi_lsapic++; } }#endif /* fill in the ACPI20 system table - has a pointer to the ACPI table header */ memcpy(acpi20_rsdp->signature, "RSD PTR ", 8); acpi20_rsdp->xsdt = (struct acpi_xsdt*)__fwtab_pa(base_nasid, acpi_xsdt); acpi20_rsdp->revision = 2; acpi_checksum_rsdp20(acpi20_rsdp, sizeof(acpi20_rsdp_t)); /* Set up the XSDT table - contains pointers to the other ACPI tables */ acpi_table_init(&acpi_xsdt->header, ACPI_XSDT_SIG, ACPI_XSDT_SIG_LEN, 1, 1); acpi_xsdt->entry_ptrs[0] = __fwtab_pa(base_nasid, acpi_madt); acpi_xsdt->entry_ptrs[1] = __fwtab_pa(base_nasid, acpi_slit); acpi_xsdt->entry_ptrs[2] = __fwtab_pa(base_nasid, acpi_srat); acpi_checksum(&acpi_xsdt->header, sizeof(acpi_xsdt_t) + 16); /* Set up the MADT table */ acpi_table_init(&acpi_madt->header, ACPI_MADT_SIG, ACPI_MADT_SIG_LEN, 1, 1); lsapic20 = (acpi20_entry_lsapic_t*) (acpi_madt + 1); for (cnode=0; cnode<num_nodes; cnode++) { nasid = GetNasid(cnode); for(cpu=0; cpu<CPUS_PER_NODE; cpu++) { if (!IsCpuPresent(cnode, cpu)) continue; lsapic20->type = ACPI20_ENTRY_LOCAL_SAPIC; lsapic20->length = sizeof(acpi_entry_lsapic_t); lsapic20->acpi_processor_id = cnode*4+cpu; lsapic20->flags = LSAPIC_ENABLED|LSAPIC_PRESENT;#if defined(CONFIG_IA64_SGI_SN1) lsapic20->eid = cpu; lsapic20->id = nasid;#else lsapic20->eid = nasid&0xffff; lsapic20->id = (cpu<<4) | (nasid>>16);#endif lsapic20 = (acpi20_entry_lsapic_t*) ((long)lsapic20+sizeof(acpi_entry_lsapic_t)); } } acpi_checksum(&acpi_madt->header, (char*)lsapic20 - (char*)acpi_madt); /* Set up the SRAT table */ acpi_table_init(&acpi_srat->header, ACPI_SRAT_SIG, ACPI_SRAT_SIG_LEN, ACPI_SRAT_REVISION, 1); ptr = acpi_srat+1; for (cnode=0; cnode<num_nodes; cnode++) { nasid = GetNasid(cnode); srat_memory_affinity = ptr; ptr = srat_memory_affinity+1; srat_memory_affinity->type = SRAT_MEMORY_STRUCTURE; srat_memory_affinity->length = sizeof(srat_memory_affinity_t); srat_memory_affinity->proximity_domain = PROXIMITY_DOMAIN(nasid); srat_memory_affinity->base_addr_lo = 0; srat_memory_affinity->length_lo = 0;#if defined(CONFIG_IA64_SGI_SN1) srat_memory_affinity->base_addr_hi = nasid<<1; srat_memory_affinity->length_hi = SN1_NODE_SIZE>>32;#else srat_memory_affinity->base_addr_hi = (nasid<<6) | (3<<4); srat_memory_affinity->length_hi = SN2_NODE_SIZE>>32;#endif srat_memory_affinity->memory_type = ACPI_ADDRESS_RANGE_MEMORY; srat_memory_affinity->flags = SRAT_MEMORY_FLAGS_ENABLED; } for (cnode=0; cnode<num_nodes; cnode++) { nasid = GetNasid(cnode); for(cpu=0; cpu<CPUS_PER_NODE; cpu++) { if (!IsCpuPresent(cnode, cpu)) continue; srat_cpu_affinity = ptr; ptr = srat_cpu_affinity + 1; srat_cpu_affinity->type = SRAT_CPU_STRUCTURE; srat_cpu_affinity->length = sizeof(srat_cpu_affinity_t); srat_cpu_affinity->proximity_domain = PROXIMITY_DOMAIN(nasid); srat_cpu_affinity->flags = SRAT_CPU_FLAGS_ENABLED;#if defined(CONFIG_IA64_SGI_SN1) srat_cpu_affinity->apic_id = nasid; srat_cpu_affinity->local_sapic_eid = cpu;#else srat_cpu_affinity->local_sapic_eid = nasid&0xffff; srat_cpu_affinity->apic_id = (cpu<<4) | (nasid>>16);#endif } } acpi_checksum(&acpi_srat->header, (char*)ptr - (char*)acpi_srat); /* Set up the SLIT table */ acpi_table_init(&acpi_slit->header, ACPI_SLIT_SIG, ACPI_SLIT_SIG_LEN, ACPI_SLIT_REVISION, 1); acpi_slit->localities = PROXIMITY_DOMAIN(max_nasid)+1; cp=acpi_slit->entries; memset(cp, 255, acpi_slit->localities*acpi_slit->localities); for (i=0; i<=max_nasid; i++) for (j=0; j<=max_nasid; j++) if (nasid_present(i) && nasid_present(j)) *(cp+PROXIMITY_DOMAIN(i)*acpi_slit->localities+PROXIMITY_DOMAIN(j)) = 10 + MIN(254, 5*ABS(i-j)); cp = acpi_slit->entries + acpi_slit->localities*acpi_slit->localities; acpi_checksum(&acpi_slit->header, cp - (char*)acpi_slit); /* fill in the SAL system table: */ memcpy(sal_systab->signature, "SST_", 4); sal_systab->size = sizeof(*sal_systab); sal_systab->sal_rev_minor = 1; sal_systab->sal_rev_major = 0; sal_systab->entry_count = 3; strcpy(sal_systab->oem_id, "SGI"); strcpy(sal_systab->product_id, "SN1"); /* fill in an entry point: */ sal_ed->type = SAL_DESC_ENTRY_POINT; sal_ed->pal_proc = __fwtab_pa(base_nasid, pal_desc[0]); sal_ed->sal_proc = __fwtab_pa(base_nasid, sal_desc[0]); sal_ed->gp = __fwtab_pa(base_nasid, sal_desc[1]); /* kludge the PTC domain info */ sal_ptc->type = SAL_DESC_PTC; sal_ptc->num_domains = 0; sal_ptc->domain_info = __fwtab_pa(base_nasid, sal_ptcdi); cpus_found = 0; last_domain = -1; sal_ptcdi--; for (cnode=0; cnode<num_nodes; cnode++) { nasid = GetNasid(cnode); for(cpu=0; cpu<CPUS_PER_NODE; cpu++) { if (IsCpuPresent(cnode, cpu)) { domain = cnode*CPUS_PER_NODE + cpu/CPUS_PER_FSB; if (domain != last_domain) { sal_ptc->num_domains++; sal_ptcdi++; sal_ptcdi->proc_count = 0; sal_ptcdi->proc_list = __fwtab_pa(base_nasid, sal_ptclid); last_domain = domain; } sal_ptcdi->proc_count++; sal_ptclid->id = nasid; sal_ptclid->eid = cpu; sal_ptclid++; cpus_found++; } } } if (cpus_found != num_cpus) FPROM_BUG(); /* Make the AP WAKEUP entry */ sal_apwake->type = SAL_DESC_AP_WAKEUP; sal_apwake->mechanism = IA64_SAL_AP_EXTERNAL_INT; sal_apwake->vector = 18; for (checksum=0, cp=(char*)sal_systab; cp < (char *)efi_memmap; ++cp) checksum += *cp; sal_systab->checksum = -checksum; /* If the checksum is correct, the kernel tries to use the * table. We dont build enough table & the kernel aborts. * Note that the PROM hasd thhhe same problem!! */#ifdef DOESNT_WORK for (checksum=0, cp=(char*)acpi_rsdp, cpe=cp+RSDP_CHECKSUM_LENGTH; cp<cpe; ++cp) checksum += *cp; acpi_rsdp->checksum = -checksum;#endif md = &efi_memmap[0]; num_memmd = build_efi_memmap((void *)md, mdsize) ; bp = (struct ia64_boot_param*) __fwtab_pa(base_nasid, BOOT_PARAM_ADDR); bp->efi_systab = __fwtab_pa(base_nasid, &fw_mem); bp->efi_memmap = __fwtab_pa(base_nasid, efi_memmap); bp->efi_memmap_size = num_memmd*mdsize; bp->efi_memdesc_size = mdsize; bp->efi_memdesc_version = 0x101; bp->command_line = __fwtab_pa(base_nasid, cmd_line); bp->console_info.num_cols = 80; bp->console_info.num_rows = 25; bp->console_info.orig_x = 0; bp->console_info.orig_y = 24; bp->fpswa = 0; /* * Now pick the BSP & store it LID value in * a global variable. Note if BSP is greater than last cpu, * pick the last cpu. */ for (cnode=0; cnode<num_nodes; cnode++) { for(cpu=0; cpu<CPUS_PER_NODE; cpu++) { if (!IsCpuPresent(cnode, cpu)) continue;#ifdef CONFIG_IA64_SGI_SN1 bsp_lid = (GetNasid(cnode)<<24) | (cpu<<16);#else bsp_lid = (GetNasid(cnode)<<16) | (cpu<<28);#endif if (bsp-- > 0) continue; return; } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -