Annotation of qemu/roms/seabios/src/mptable.c, revision 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.