4 #include "kvm/mptable.h"
8 #include <linux/kernel.h>
11 #include <asm/mpspec_def.h>
12 #include <linux/types.h>
15 * FIXME: please make sure the addresses borrowed
16 * for apic/ioapic never overlaped! We need a global
17 * tracker of system resources (including io, mmio,
21 static unsigned int mpf_checksum(unsigned char *mp, int len)
31 static unsigned int gen_cpu_flag(unsigned int cpu, unsigned int ncpu)
33 /* sets enabled/disabled | BSP/AP processor */
34 return ( (cpu < ncpu) ? CPU_ENABLED : 0) |
35 ((cpu == 0) ? CPU_BOOTPROCESSOR : 0x00);
38 #define MPTABLE_SIG_FLOATING "_MP_"
39 #define MPTABLE_OEM "KVMCPU00"
40 #define MPTABLE_PRODUCTID "0.1 "
41 #define MPTABLE_PCIBUSTYPE "PCI "
42 #define MPTABLE_ISABUSTYPE "ISA "
44 #define MPTABLE_STRNCPY(d, s) memcpy(d, s, sizeof(d))
46 /* It should be more than enough */
47 #define MPTABLE_MAX_SIZE (32 << 20)
50 * Too many cpus will require x2apic mode
51 * and rather ACPI support so we limit it
54 #define MPTABLE_MAX_CPUS 255
56 static void mptable_add_irq_src(struct mpc_intsrc *mpc_intsrc,
57 u16 srcbusid, u16 srcbusirq,
58 u16 dstapic, u16 dstirq)
60 *mpc_intsrc = (struct mpc_intsrc) {
63 .irqflag = MP_IRQDIR_DEFAULT,
65 .srcbusirq = srcbusirq,
72 * mptable_setup - create mptable and fill guest memory with it
74 int mptable__init(struct kvm *kvm)
76 unsigned long real_mpc_table, real_mpf_intel, size;
77 struct mpf_intel *mpf_intel;
78 struct mpc_table *mpc_table;
79 struct mpc_cpu *mpc_cpu;
80 struct mpc_bus *mpc_bus;
81 struct mpc_ioapic *mpc_ioapic;
82 struct mpc_intsrc *mpc_intsrc;
83 struct rb_node *pci_tree;
85 const int pcibusid = 0;
86 const int isabusid = 1;
88 unsigned int i, nentries = 0, ncpus = kvm->nrcpus;
89 unsigned int ioapicid;
92 /* That is where MP table will be in guest memory */
93 real_mpc_table = ALIGN(MB_BIOS_BEGIN + bios_rom_size, 16);
95 if (ncpus > MPTABLE_MAX_CPUS) {
96 pr_warning("Too many cpus: %d limited to %d",
97 ncpus, MPTABLE_MAX_CPUS);
98 ncpus = MPTABLE_MAX_CPUS;
101 mpc_table = calloc(1, MPTABLE_MAX_SIZE);
105 MPTABLE_STRNCPY(mpc_table->signature, MPC_SIGNATURE);
106 MPTABLE_STRNCPY(mpc_table->oem, MPTABLE_OEM);
107 MPTABLE_STRNCPY(mpc_table->productid, MPTABLE_PRODUCTID);
110 mpc_table->lapic = APIC_ADDR(0);
111 mpc_table->oemcount = ncpus; /* will be updated again at end */
114 * CPUs enumeration. Technically speaking we should
115 * ask either host or HV for apic version supported
116 * but for a while we simply put some random value
119 mpc_cpu = (void *)&mpc_table[1];
120 for (i = 0; i < ncpus; i++) {
121 mpc_cpu->type = MP_PROCESSOR;
123 mpc_cpu->apicver = KVM_APIC_VERSION;
124 mpc_cpu->cpuflag = gen_cpu_flag(i, ncpus);
125 mpc_cpu->cpufeature = 0x600; /* some default value */
126 mpc_cpu->featureflag = 0x201; /* some default value */
130 last_addr = (void *)mpc_cpu;
135 * FIXME: Some callback here to obtain real number
136 * of PCI buses present in system.
139 mpc_bus->type = MP_BUS;
140 mpc_bus->busid = pcibusid;
141 MPTABLE_STRNCPY(mpc_bus->bustype, MPTABLE_PCIBUSTYPE);
143 last_addr = (void *)&mpc_bus[1];
148 * FIXME: Same issue as for PCI bus.
151 mpc_bus->type = MP_BUS;
152 mpc_bus->busid = isabusid;
153 MPTABLE_STRNCPY(mpc_bus->bustype, MPTABLE_ISABUSTYPE);
155 last_addr = (void *)&mpc_bus[1];
161 ioapicid = ncpus + 1;
162 mpc_ioapic = last_addr;
163 mpc_ioapic->type = MP_IOAPIC;
164 mpc_ioapic->apicid = ioapicid;
165 mpc_ioapic->apicver = KVM_APIC_VERSION;
166 mpc_ioapic->flags = MPC_APIC_USABLE;
167 mpc_ioapic->apicaddr = IOAPIC_ADDR(0);
169 last_addr = (void *)&mpc_ioapic[1];
175 * FIXME: Same issue as with buses. We definitely
176 * need kind of collector routine which enumerate
177 * resources used first and pass them here.
178 * At moment we know we have only virtio block device
179 * and virtio console but this is g00berfish.
181 * Also note we use PCI irqs here, no for ISA bus yet.
184 for (pci_tree = irq__get_pci_tree(); pci_tree; pci_tree = rb_next(pci_tree)) {
185 struct pci_dev *dev = rb_entry(pci_tree, struct pci_dev, node);
186 struct irq_line *irq_line;
188 list_for_each_entry(irq_line, &dev->lines, node) {
189 unsigned char srcbusirq;
191 srcbusirq = (dev->id << 2) | (dev->pin - 1);
193 mpc_intsrc = last_addr;
195 mptable_add_irq_src(mpc_intsrc, pcibusid, srcbusirq, ioapicid, irq_line->line);
196 last_addr = (void *)&mpc_intsrc[1];
202 * Local IRQs assignment (LINT0, LINT1)
204 mpc_intsrc = last_addr;
205 mpc_intsrc->type = MP_LINTSRC;
206 mpc_intsrc->irqtype = mp_ExtINT;
207 mpc_intsrc->irqtype = mp_INT;
208 mpc_intsrc->irqflag = MP_IRQDIR_DEFAULT;
209 mpc_intsrc->srcbus = isabusid;
210 mpc_intsrc->srcbusirq = 0;
211 mpc_intsrc->dstapic = 0; /* FIXME: BSP apic */
212 mpc_intsrc->dstirq = 0; /* LINT0 */
214 last_addr = (void *)&mpc_intsrc[1];
217 mpc_intsrc = last_addr;
218 mpc_intsrc->type = MP_LINTSRC;
219 mpc_intsrc->irqtype = mp_NMI;
220 mpc_intsrc->irqflag = MP_IRQDIR_DEFAULT;
221 mpc_intsrc->srcbus = isabusid;
222 mpc_intsrc->srcbusirq = 0;
223 mpc_intsrc->dstapic = 0; /* FIXME: BSP apic */
224 mpc_intsrc->dstirq = 1; /* LINT1 */
226 last_addr = (void *)&mpc_intsrc[1];
230 * Floating MP table finally.
232 real_mpf_intel = ALIGN((unsigned long)last_addr - (unsigned long)mpc_table, 16);
233 mpf_intel = (void *)((unsigned long)mpc_table + real_mpf_intel);
235 MPTABLE_STRNCPY(mpf_intel->signature, MPTABLE_SIG_FLOATING);
236 mpf_intel->length = 1;
237 mpf_intel->specification= 4;
238 mpf_intel->physptr = (unsigned int)real_mpc_table;
239 mpf_intel->checksum = -mpf_checksum((unsigned char *)mpf_intel, sizeof(*mpf_intel));
242 * No last_addr inclrement here please, we need last
243 * active position here to compute table size.
247 * Don't forget to update header in fixed table.
249 mpc_table->oemcount = nentries;
250 mpc_table->length = last_addr - (void *)mpc_table;
251 mpc_table->checksum = -mpf_checksum((unsigned char *)mpc_table, mpc_table->length);
255 * We will copy the whole table, no need to separate
256 * floating structure and table itkvm.
258 size = (unsigned long)mpf_intel + sizeof(*mpf_intel) - (unsigned long)mpc_table;
261 * The finial check -- never get out of system bios
262 * area. Lets also check for allocated memory overrun,
263 * in real it's late but still usefull.
266 if (size > (unsigned long)(MB_BIOS_END - bios_rom_size) ||
267 size > MPTABLE_MAX_SIZE) {
269 pr_err("MP table is too big");
275 * OK, it is time to move it to guest memory.
277 memcpy(guest_flat_to_host(kvm, real_mpc_table), mpc_table, size);
283 firmware_init(mptable__init);
285 int mptable__exit(struct kvm *kvm)
289 firmware_exit(mptable__exit);