kvm tools, setup: Create private directory
[linux-2.6/next.git] / tools / kvm / mptable.c
blobcfc7d7954ed314d116676f567382cce0d986d424
1 #include "kvm/kvm.h"
2 #include "kvm/bios.h"
3 #include "kvm/apic.h"
4 #include "kvm/mptable.h"
5 #include "kvm/util.h"
6 #include "kvm/irq.h"
8 #include <linux/kernel.h>
9 #include <string.h>
12 * If kernel is not configured yet this macro
13 * might not be defined, fix it by own definition
15 #ifndef NR_CPUS
16 #define NR_CPUS KVM_NR_CPUS
17 #endif
19 #include <asm/mpspec_def.h>
20 #include <linux/types.h>
23 * FIXME: please make sure the addresses borrowed
24 * for apic/ioapic never overlaped! We need a global
25 * tracker of system resources (including io, mmio,
26 * and friends).
29 static unsigned int mpf_checksum(unsigned char *mp, int len)
31 unsigned int sum = 0;
33 while (len--)
34 sum += *mp++;
36 return sum & 0xFF;
39 static unsigned int gen_cpu_flag(unsigned int cpu, unsigned int ncpu)
41 /* sets enabled/disabled | BSP/AP processor */
42 return ( (cpu < ncpu) ? CPU_ENABLED : 0) |
43 ((cpu == 0) ? CPU_BOOTPROCESSOR : 0x00);
46 #define MPTABLE_SIG_FLOATING "_MP_"
47 #define MPTABLE_OEM "KVMCPU00"
48 #define MPTABLE_PRODUCTID "0.1 "
49 #define MPTABLE_PCIBUSTYPE "PCI "
50 #define MPTABLE_ISABUSTYPE "ISA "
52 #define MPTABLE_STRNCPY(d, s) memcpy(d, s, sizeof(d))
54 /* It should be more than enough */
55 #define MPTABLE_MAX_SIZE (32 << 20)
58 * Too many cpus will require x2apic mode
59 * and rather ACPI support so we limit it
60 * here for a while.
62 #define MPTABLE_MAX_CPUS 255
64 static void mptable_add_irq_src(struct mpc_intsrc *mpc_intsrc,
65 u16 srcbusid, u16 srcbusirq,
66 u16 dstapic, u16 dstirq)
68 *mpc_intsrc = (struct mpc_intsrc) {
69 .type = MP_INTSRC,
70 .irqtype = mp_INT,
71 .irqflag = MP_IRQDIR_DEFAULT,
72 .srcbus = srcbusid,
73 .srcbusirq = srcbusirq,
74 .dstapic = dstapic,
75 .dstirq = dstirq
79 /**
80 * mptable_setup - create mptable and fill guest memory with it
82 void mptable_setup(struct kvm *kvm, unsigned int ncpus)
84 unsigned long real_mpc_table, real_mpf_intel, size;
85 struct mpf_intel *mpf_intel;
86 struct mpc_table *mpc_table;
87 struct mpc_cpu *mpc_cpu;
88 struct mpc_bus *mpc_bus;
89 struct mpc_ioapic *mpc_ioapic;
90 struct mpc_intsrc *mpc_intsrc;
91 struct rb_node *pci_tree;
93 const int pcibusid = 0;
94 const int isabusid = 1;
96 unsigned int i, nentries = 0;
97 unsigned int ioapicid;
98 void *last_addr;
100 /* That is where MP table will be in guest memory */
101 real_mpc_table = ALIGN(MB_BIOS_BEGIN + bios_rom_size, 16);
103 if (ncpus > MPTABLE_MAX_CPUS) {
104 pr_warning("Too many cpus: %d limited to %d",
105 ncpus, MPTABLE_MAX_CPUS);
106 ncpus = MPTABLE_MAX_CPUS;
109 mpc_table = calloc(1, MPTABLE_MAX_SIZE);
110 if (!mpc_table)
111 die("Out of memory");
113 MPTABLE_STRNCPY(mpc_table->signature, MPC_SIGNATURE);
114 MPTABLE_STRNCPY(mpc_table->oem, MPTABLE_OEM);
115 MPTABLE_STRNCPY(mpc_table->productid, MPTABLE_PRODUCTID);
117 mpc_table->spec = 4;
118 mpc_table->lapic = APIC_ADDR(0);
119 mpc_table->oemcount = ncpus; /* will be updated again at end */
122 * CPUs enumeration. Technically speaking we should
123 * ask either host or HV for apic version supported
124 * but for a while we simply put some random value
125 * here.
127 mpc_cpu = (void *)&mpc_table[1];
128 for (i = 0; i < ncpus; i++) {
129 mpc_cpu->type = MP_PROCESSOR;
130 mpc_cpu->apicid = i;
131 mpc_cpu->apicver = KVM_APIC_VERSION;
132 mpc_cpu->cpuflag = gen_cpu_flag(i, ncpus);
133 mpc_cpu->cpufeature = 0x600; /* some default value */
134 mpc_cpu->featureflag = 0x201; /* some default value */
135 mpc_cpu++;
138 last_addr = (void *)mpc_cpu;
139 nentries += ncpus;
142 * PCI buses.
143 * FIXME: Some callback here to obtain real number
144 * of PCI buses present in system.
146 mpc_bus = last_addr;
147 mpc_bus->type = MP_BUS;
148 mpc_bus->busid = pcibusid;
149 MPTABLE_STRNCPY(mpc_bus->bustype, MPTABLE_PCIBUSTYPE);
151 last_addr = (void *)&mpc_bus[1];
152 nentries++;
155 * ISA bus.
156 * FIXME: Same issue as for PCI bus.
158 mpc_bus = last_addr;
159 mpc_bus->type = MP_BUS;
160 mpc_bus->busid = isabusid;
161 MPTABLE_STRNCPY(mpc_bus->bustype, MPTABLE_ISABUSTYPE);
163 last_addr = (void *)&mpc_bus[1];
164 nentries++;
167 * IO-APIC chip.
169 ioapicid = ncpus + 1;
170 mpc_ioapic = last_addr;
171 mpc_ioapic->type = MP_IOAPIC;
172 mpc_ioapic->apicid = ioapicid;
173 mpc_ioapic->apicver = KVM_APIC_VERSION;
174 mpc_ioapic->flags = MPC_APIC_USABLE;
175 mpc_ioapic->apicaddr = IOAPIC_ADDR(0);
177 last_addr = (void *)&mpc_ioapic[1];
178 nentries++;
181 * IRQ sources.
183 * FIXME: Same issue as with buses. We definitely
184 * need kind of collector routine which enumerate
185 * resources used first and pass them here.
186 * At moment we know we have only virtio block device
187 * and virtio console but this is g00berfish.
189 * Also note we use PCI irqs here, no for ISA bus yet.
192 for (pci_tree = irq__get_pci_tree(); pci_tree; pci_tree = rb_next(pci_tree)) {
193 struct pci_dev *dev = rb_entry(pci_tree, struct pci_dev, node);
194 struct irq_line *irq_line;
196 list_for_each_entry(irq_line, &dev->lines, node) {
197 unsigned char srcbusirq;
199 srcbusirq = (dev->id << 2) | (dev->pin - 1);
201 mpc_intsrc = last_addr;
203 mptable_add_irq_src(mpc_intsrc, pcibusid, srcbusirq, ioapicid, irq_line->line);
204 last_addr = (void *)&mpc_intsrc[1];
205 nentries++;
210 * Local IRQs assignment (LINT0, LINT1)
212 mpc_intsrc = last_addr;
213 mpc_intsrc->type = MP_LINTSRC;
214 mpc_intsrc->irqtype = mp_ExtINT;
215 mpc_intsrc->irqtype = mp_INT;
216 mpc_intsrc->irqflag = MP_IRQDIR_DEFAULT;
217 mpc_intsrc->srcbus = isabusid;
218 mpc_intsrc->srcbusirq = 0;
219 mpc_intsrc->dstapic = 0; /* FIXME: BSP apic */
220 mpc_intsrc->dstirq = 0; /* LINT0 */
222 last_addr = (void *)&mpc_intsrc[1];
223 nentries++;
225 mpc_intsrc = last_addr;
226 mpc_intsrc->type = MP_LINTSRC;
227 mpc_intsrc->irqtype = mp_NMI;
228 mpc_intsrc->irqflag = MP_IRQDIR_DEFAULT;
229 mpc_intsrc->srcbus = isabusid;
230 mpc_intsrc->srcbusirq = 0;
231 mpc_intsrc->dstapic = 0; /* FIXME: BSP apic */
232 mpc_intsrc->dstirq = 1; /* LINT1 */
234 last_addr = (void *)&mpc_intsrc[1];
235 nentries++;
238 * Floating MP table finally.
240 real_mpf_intel = ALIGN((unsigned long)last_addr - (unsigned long)mpc_table, 16);
241 mpf_intel = (void *)((unsigned long)mpc_table + real_mpf_intel);
243 MPTABLE_STRNCPY(mpf_intel->signature, MPTABLE_SIG_FLOATING);
244 mpf_intel->length = 1;
245 mpf_intel->specification= 4;
246 mpf_intel->physptr = (unsigned int)real_mpc_table;
247 mpf_intel->checksum = -mpf_checksum((unsigned char *)mpf_intel, sizeof(*mpf_intel));
250 * No last_addr inclrement here please, we need last
251 * active position here to compute table size.
255 * Don't forget to update header in fixed table.
257 mpc_table->oemcount = nentries;
258 mpc_table->length = last_addr - (void *)mpc_table;
259 mpc_table->checksum = -mpf_checksum((unsigned char *)mpc_table, mpc_table->length);
263 * We will copy the whole table, no need to separate
264 * floating structure and table itkvm.
266 size = (unsigned long)mpf_intel + sizeof(*mpf_intel) - (unsigned long)mpc_table;
269 * The finial check -- never get out of system bios
270 * area. Lets also check for allocated memory overrun,
271 * in real it's late but still usefull.
274 if (size > (unsigned long)(MB_BIOS_END - bios_rom_size) ||
275 size > MPTABLE_MAX_SIZE)
276 die("MP table is too big");
279 * OK, it is time to move it to guest memory.
281 memcpy(guest_flat_to_host(kvm, real_mpc_table), mpc_table, size);
283 free(mpc_table);