Annotation of qemu/roms/seabios/src/mptable.c, revision 1.1.1.1

1.1       root        1: // MPTable generation (on emulators)
                      2: //
                      3: // Copyright (C) 2008,2009  Kevin O'Connor <[email protected]>
                      4: // Copyright (C) 2006 Fabrice Bellard
                      5: //
                      6: // This file may be distributed under the terms of the GNU LGPLv3 license.
                      7: 
                      8: #include "util.h" // dprintf
                      9: #include "config.h" // CONFIG_*
                     10: #include "mptable.h" // MPTABLE_SIGNATURE
                     11: #include "paravirt.h" // qemu_cfg_irq0_override
                     12: 
                     13: void
                     14: mptable_init(void)
                     15: {
                     16:     if (! CONFIG_MPTABLE)
                     17:         return;
                     18: 
                     19:     dprintf(3, "init MPTable\n");
                     20: 
                     21:     // Allocate memory
                     22:     int length = (sizeof(struct mptable_config_s)
                     23:                   + sizeof(struct mpt_cpu) * MaxCountCPUs
                     24:                   + sizeof(struct mpt_bus)
                     25:                   + sizeof(struct mpt_ioapic)
                     26:                   + sizeof(struct mpt_intsrc) * 18);
                     27:     struct mptable_config_s *config = malloc_fseg(length);
                     28:     struct mptable_floating_s *floating = malloc_fseg(sizeof(*floating));
                     29:     if (!config || !floating) {
                     30:         dprintf(1, "No room for MPTABLE!\n");
                     31:         free(config);
                     32:         free(floating);
                     33:         return;
                     34:     }
                     35: 
                     36:     /* floating pointer structure */
                     37:     memset(floating, 0, sizeof(*floating));
                     38:     floating->signature = MPTABLE_SIGNATURE;
                     39:     floating->physaddr = (u32)config;
                     40:     floating->length = 1;
                     41:     floating->spec_rev = 4;
                     42:     floating->checksum -= checksum(floating, sizeof(*floating));
                     43: 
                     44:     // Config structure.
                     45:     memset(config, 0, sizeof(*config));
                     46:     config->signature = MPCONFIG_SIGNATURE;
                     47:     config->spec = 4;
                     48:     memcpy(config->oemid, CONFIG_CPUNAME8, sizeof(config->oemid));
                     49:     memcpy(config->productid, "0.1         ", sizeof(config->productid));
                     50:     config->lapic = BUILD_APIC_ADDR;
                     51: 
                     52:     // Detect cpu info
                     53:     u32 cpuid_signature, ebx, ecx, cpuid_features;
                     54:     cpuid(1, &cpuid_signature, &ebx, &ecx, &cpuid_features);
                     55:     int pkgcpus = 1;
                     56:     if (cpuid_features & (1 << 28)) {
                     57:         /* Only populate the MPS tables with the first logical CPU in
                     58:            each package */
                     59:         pkgcpus = (ebx >> 16) & 0xff;
                     60:         pkgcpus = 1 << (__fls(pkgcpus - 1) + 1); /* round up to power of 2 */
                     61:     }
                     62: 
                     63:     // CPU definitions.
                     64:     struct mpt_cpu *cpus = (void*)&config[1], *cpu = cpus;
                     65:     int i;
                     66:     for (i = 0; i < MaxCountCPUs; i+=pkgcpus) {
                     67:         memset(cpu, 0, sizeof(*cpu));
                     68:         cpu->type = MPT_TYPE_CPU;
                     69:         cpu->apicid = i;
                     70:         cpu->apicver = 0x11;
                     71:         /* cpu flags: enabled, bootstrap cpu */
                     72:         cpu->cpuflag = (i < CountCPUs) | ((i == 0) << 1);
                     73:         if (cpuid_signature) {
                     74:             cpu->cpusignature = cpuid_signature;
                     75:             cpu->featureflag = cpuid_features;
                     76:         } else {
                     77:             cpu->cpusignature = 0x600;
                     78:             cpu->featureflag = 0x201;
                     79:         }
                     80:         cpu++;
                     81:     }
                     82:     int entrycount = cpu - cpus;
                     83: 
                     84:     /* isa bus */
                     85:     struct mpt_bus *bus = (void*)cpu;
                     86:     memset(bus, 0, sizeof(*bus));
                     87:     bus->type = MPT_TYPE_BUS;
                     88:     memcpy(bus->bustype, "ISA   ", sizeof(bus->bustype));
                     89:     entrycount++;
                     90: 
                     91:     /* ioapic */
                     92:     u8 ioapic_id = CountCPUs;
                     93:     struct mpt_ioapic *ioapic = (void*)&bus[1];
                     94:     memset(ioapic, 0, sizeof(*ioapic));
                     95:     ioapic->type = MPT_TYPE_IOAPIC;
                     96:     ioapic->apicid = ioapic_id;
                     97:     ioapic->apicver = 0x11;
                     98:     ioapic->flags = 1; // enable
                     99:     ioapic->apicaddr = BUILD_IOAPIC_ADDR;
                    100:     entrycount++;
                    101: 
                    102:     /* irqs */
                    103:     struct mpt_intsrc *intsrcs = (void*)&ioapic[1], *intsrc = intsrcs;
                    104:     for (i = 0; i < 16; i++) {
                    105:         memset(intsrc, 0, sizeof(*intsrc));
                    106:         intsrc->type = MPT_TYPE_INTSRC;
                    107:         intsrc->srcbusirq = i;
                    108:         intsrc->dstapic = ioapic_id;
                    109:         intsrc->dstirq = i;
                    110:         if (qemu_cfg_irq0_override()) {
                    111:             /* Destination 2 is covered by irq0->inti2 override (i ==
                    112:                0). Source IRQ 2 is unused */
                    113:             if (i == 0)
                    114:                 intsrc->dstirq = 2;
                    115:             else if (i == 2)
                    116:                 intsrc--;
                    117:         }
                    118:         intsrc++;
                    119:     }
                    120:     entrycount += intsrc - intsrcs;
                    121: 
                    122:     /* Local interrupt assignment */
                    123:     intsrc->type = MPT_TYPE_LOCAL_INT;
                    124:     intsrc->irqtype = 3; /* ExtINT */
                    125:     intsrc->irqflag = 0; /* PO, EL default */
                    126:     intsrc->srcbus = 0;
                    127:     intsrc->srcbusirq = 0;
                    128:     intsrc->dstapic = 0; /* BSP == APIC #0 */
                    129:     intsrc->dstirq = 0; /* LINTIN0 */
                    130:     intsrc++;
                    131:     entrycount++;
                    132: 
                    133:     intsrc->type = MPT_TYPE_LOCAL_INT;
                    134:     intsrc->irqtype = 1; /* NMI */
                    135:     intsrc->irqflag = 0; /* PO, EL default */
                    136:     intsrc->srcbus = 0;
                    137:     intsrc->srcbusirq = 0;
                    138:     intsrc->dstapic = 0; /* BSP == APIC #0 */
                    139:     intsrc->dstirq = 1; /* LINTIN1 */
                    140:     intsrc++;
                    141:     entrycount++;
                    142: 
                    143:     // Finalize config structure.
                    144:     config->entrycount = entrycount;
                    145:     config->length = (void*)intsrc - (void*)config;
                    146:     config->checksum -= checksum(config, config->length);
                    147: 
                    148:     dprintf(1, "MP table addr=%p MPC table addr=%p size=%d\n",
                    149:             floating, config, config->length);
                    150: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.