static int __init smp_read_mpc(struct mp_config_table *mpc) { char str[16]; int count=sizeof(*mpc); int ioapics = 0; unsigned char *mpt=((unsigned char *)mpc)+count; if (memcmp(mpc->mpc_signature,MPC_SIGNATURE,4)) { panic("SMP mptable: bad signature [%c%c%c%c]!\n", mpc->mpc_signature[0], mpc->mpc_signature[1], mpc->mpc_signature[2], mpc->mpc_signature[3]); return 1; } if (mpf_checksum((unsigned char *)mpc,mpc->mpc_length)) { panic("SMP mptable: checksum error!\n"); return 1; } if (mpc->mpc_spec!=0x01 && mpc->mpc_spec!=0x04) { printk("Bad Config Table version (%d)!!\n",mpc->mpc_spec); return 1; } memcpy(str,mpc->mpc_oem,8); str[8]=0; memcpy(ioapic_OEM_ID,str,9); printk("OEM ID: %s ",str); memcpy(str,mpc->mpc_productid,12); str[12]=0; memcpy(ioapic_Product_ID,str,13); printk("Product ID: %s ",str); printk("APIC at: 0x%lX\n",mpc->mpc_lapic); /* save the local APIC address, it might be non-default */ mp_lapic_addr = mpc->mpc_lapic; /* * Now process the configuration blocks. */ while(count<mpc->mpc_length) { switch(*mpt) { case MP_PROCESSOR: { struct mpc_config_processor *m= (struct mpc_config_processor *)mpt; if (m->mpc_cpuflag&CPU_ENABLED) { printk("Processor #%d %s APIC version %d\n", m->mpc_apicid, mpc_family((m->mpc_cpufeature& CPU_FAMILY_MASK)>>8, (m->mpc_cpufeature& CPU_MODEL_MASK)>>4), m->mpc_apicver); #ifdef SMP_DEBUG if (m->mpc_featureflag&(1<<0)) printk(" Floating point unit present.\n"); if (m->mpc_featureflag&(1<<7)) printk(" Machine Exception supported.\n"); if (m->mpc_featureflag&(1<<8)) printk(" 64 bit compare & exchange supported.\n"); if (m->mpc_featureflag&(1<<9)) printk(" Internal APIC present.\n"); #endif if (m->mpc_cpuflag&CPU_BOOTPROCESSOR) { SMP_PRINTK((" Bootup CPU\n")); boot_cpu_id=m->mpc_apicid; } else /* Boot CPU already counted */ num_processors++; if (m->mpc_apicid>NR_CPUS) printk("Processor #%d unused. (Max %d processors).\n",m->mpc_apicid, NR_CPUS); else { cpu_present_map|=(1<<m->mpc_apicid); apic_version[m->mpc_apicid]=m->mpc_apicver; } } mpt+=sizeof(*m); count+=sizeof(*m); break; } case MP_BUS: { struct mpc_config_bus *m= (struct mpc_config_bus *)mpt; memcpy(str,m->mpc_bustype,6); str[6]=0; SMP_PRINTK(("Bus #%d is %s\n", m->mpc_busid, str)); if ((strncmp(m->mpc_bustype,"ISA",3) == 0) || (strncmp(m->mpc_bustype,"EISA",4) == 0)) mp_bus_id_to_type[m->mpc_busid] = MP_BUS_ISA; else if (strncmp(m->mpc_bustype,"PCI",3) == 0) { mp_bus_id_to_type[m->mpc_busid] = MP_BUS_PCI; mp_bus_id_to_pci_bus[m->mpc_busid] = mp_current_pci_id; mp_current_pci_id++; } mpt+=sizeof(*m); count+=sizeof(*m); break; } case MP_IOAPIC: { struct mpc_config_ioapic *m= (struct mpc_config_ioapic *)mpt; if (m->mpc_flags&MPC_APIC_USABLE) { ioapics++; printk("I/O APIC #%d Version %d at 0x%lX.\n", m->mpc_apicid,m->mpc_apicver, m->mpc_apicaddr); /* * we use the first one only currently */ if (ioapics == 1) mp_ioapic_addr = m->mpc_apicaddr; } mpt+=sizeof(*m); count+=sizeof(*m); break; } case MP_INTSRC: { struct mpc_config_intsrc *m= (struct mpc_config_intsrc *)mpt; mp_irqs [mp_irq_entries] = *m; if (++mp_irq_entries == MAX_IRQ_SOURCES) { printk("Max irq sources exceeded!!\n"); printk("Skipping remaining sources.\n"); --mp_irq_entries; } mpt+=sizeof(*m); count+=sizeof(*m); break; } case MP_LINTSRC: { struct mpc_config_intlocal *m= (struct mpc_config_intlocal *)mpt; mpt+=sizeof(*m); count+=sizeof(*m); break; } } }
static int smp_read_mpc(struct mp_config_table *mpc) { char str[16]; int count=sizeof(*mpc); int apics=0; unsigned char *mpt=((unsigned char *)mpc)+count; SMP_PRINTK(("MPC table being read at 0x%x.\n", mpc)); if(memcmp(mpc->mpc_signature,MPC_SIGNATURE,4)) { printk("Bad signature [%c%c%c%c].\n", mpc->mpc_signature[0], mpc->mpc_signature[1], mpc->mpc_signature[2], mpc->mpc_signature[3]); return 1; } if(mpf_checksum((unsigned char *)mpc,mpc->mpc_length)) { printk("Checksum error.\n"); return 1; } if(mpc->mpc_spec!=0x01 && mpc->mpc_spec!=0x04) { printk("Bad Config Table version (%d)!!\n",mpc->mpc_spec); return 1; } memcpy(str,mpc->mpc_oem,8); str[8]=0; printk("OEM ID: %s ",str); memcpy(str,mpc->mpc_productid,12); str[12]=0; printk("Product ID: %s ",str); printk("APIC at: 0x%lX\n",mpc->mpc_lapic); /* set the local APIC address */ apic_addr = mpc->mpc_lapic; /* * Now process the configuration blocks. */ while(count<mpc->mpc_length) { switch(*mpt) { case MP_PROCESSOR: { struct mpc_config_processor *m= (struct mpc_config_processor *)mpt; if(m->mpc_cpuflag&CPU_ENABLED) { printk("Processor #%d %s APIC version %d\n", m->mpc_apicid, mpc_family((m->mpc_cpufeature& CPU_FAMILY_MASK)>>8, (m->mpc_cpufeature& CPU_MODEL_MASK)>>4), m->mpc_apicver); #ifdef SMP_DEBUG if(m->mpc_featureflag&(1<<0)) printk(" Floating point unit present.\n"); if(m->mpc_featureflag&(1<<7)) printk(" Machine Exception supported.\n"); if(m->mpc_featureflag&(1<<8)) printk(" 64 bit compare & exchange supported.\n"); if(m->mpc_featureflag&(1<<9)) printk(" Internal APIC present.\n"); #endif if(m->mpc_cpuflag&CPU_BOOTPROCESSOR) { printk(" Bootup CPU\n"); boot_cpu_id=m->mpc_apicid; } else { /* Boot CPU already counted */ num_processors++; } if(m->mpc_apicid>NR_CPUS) printk("Processor #%d unused. (Max %d processors).\n",m->mpc_apicid, NR_CPUS); else { cpu_present_map|=(1<<m->mpc_apicid); apic_version[m->mpc_apicid]=m->mpc_apicver; } } mpt+=sizeof(*m); count+=sizeof(*m); break; } case MP_BUS: { struct mpc_config_bus *m= (struct mpc_config_bus *)mpt; memcpy(str,m->mpc_bustype,6); str[6]=0; printk("Bus #%d is %s\n", m->mpc_busid, str); mpt+=sizeof(*m); count+=sizeof(*m); break; } case MP_IOAPIC: { struct mpc_config_ioapic *m= (struct mpc_config_ioapic *)mpt; if(m->mpc_flags&MPC_APIC_USABLE) { apics++; printk("I/O APIC #%d Version %d at 0x%lX.\n", m->mpc_apicid,m->mpc_apicver, m->mpc_apicaddr); io_apic_addr = m->mpc_apicaddr; } mpt+=sizeof(*m); count+=sizeof(*m); break; } case MP_INTSRC: { struct mpc_config_intsrc *m= (struct mpc_config_intsrc *)mpt; mpt+=sizeof(*m); count+=sizeof(*m); break; } case MP_LINTSRC: { struct mpc_config_intlocal *m= (struct mpc_config_intlocal *)mpt; mpt+=sizeof(*m); count+=sizeof(*m); break; } } }