]> git.karo-electronics.de Git - karo-tx-linux.git/blob - tools/kvm/x86/mptable.c
Merge branch 'linus'
[karo-tx-linux.git] / tools / kvm / x86 / mptable.c
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"
7
8 #include <linux/kernel.h>
9 #include <string.h>
10
11 #include <asm/mpspec_def.h>
12 #include <linux/types.h>
13
14 /*
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,
18  * and friends).
19  */
20
21 static unsigned int mpf_checksum(unsigned char *mp, int len)
22 {
23         unsigned int sum = 0;
24
25         while (len--)
26                 sum += *mp++;
27
28         return sum & 0xFF;
29 }
30
31 static unsigned int gen_cpu_flag(unsigned int cpu, unsigned int ncpu)
32 {
33         /* sets enabled/disabled | BSP/AP processor */
34         return ( (cpu < ncpu) ? CPU_ENABLED       : 0) |
35                 ((cpu == 0)   ? CPU_BOOTPROCESSOR : 0x00);
36 }
37
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   "
43
44 #define MPTABLE_STRNCPY(d, s)   memcpy(d, s, sizeof(d))
45
46 /* It should be more than enough */
47 #define MPTABLE_MAX_SIZE        (32 << 20)
48
49 /*
50  * Too many cpus will require x2apic mode
51  * and rather ACPI support so we limit it
52  * here for a while.
53  */
54 #define MPTABLE_MAX_CPUS        255
55
56 static void mptable_add_irq_src(struct mpc_intsrc *mpc_intsrc,
57                                 u16 srcbusid,   u16 srcbusirq,
58                                 u16 dstapic,    u16 dstirq)
59 {
60         *mpc_intsrc = (struct mpc_intsrc) {
61                 .type           = MP_INTSRC,
62                 .irqtype        = mp_INT,
63                 .irqflag        = MP_IRQDIR_DEFAULT,
64                 .srcbus         = srcbusid,
65                 .srcbusirq      = srcbusirq,
66                 .dstapic        = dstapic,
67                 .dstirq         = dstirq
68         };
69 }
70
71 /**
72  * mptable_setup - create mptable and fill guest memory with it
73  */
74 int mptable__init(struct kvm *kvm)
75 {
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;
84
85         const int pcibusid = 0;
86         const int isabusid = 1;
87
88         unsigned int i, nentries = 0, ncpus = kvm->nrcpus;
89         unsigned int ioapicid;
90         void *last_addr;
91
92         /* That is where MP table will be in guest memory */
93         real_mpc_table = ALIGN(MB_BIOS_BEGIN + bios_rom_size, 16);
94
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;
99         }
100
101         mpc_table = calloc(1, MPTABLE_MAX_SIZE);
102         if (!mpc_table)
103                 return -ENOMEM;
104
105         MPTABLE_STRNCPY(mpc_table->signature,   MPC_SIGNATURE);
106         MPTABLE_STRNCPY(mpc_table->oem,         MPTABLE_OEM);
107         MPTABLE_STRNCPY(mpc_table->productid,   MPTABLE_PRODUCTID);
108
109         mpc_table->spec         = 4;
110         mpc_table->lapic        = APIC_ADDR(0);
111         mpc_table->oemcount     = ncpus; /* will be updated again at end */
112
113         /*
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
117          * here.
118          */
119         mpc_cpu = (void *)&mpc_table[1];
120         for (i = 0; i < ncpus; i++) {
121                 mpc_cpu->type           = MP_PROCESSOR;
122                 mpc_cpu->apicid         = i;
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 */
127                 mpc_cpu++;
128         }
129
130         last_addr = (void *)mpc_cpu;
131         nentries += ncpus;
132
133         /*
134          * PCI buses.
135          * FIXME: Some callback here to obtain real number
136          * of PCI buses present in system.
137          */
138         mpc_bus         = last_addr;
139         mpc_bus->type   = MP_BUS;
140         mpc_bus->busid  = pcibusid;
141         MPTABLE_STRNCPY(mpc_bus->bustype, MPTABLE_PCIBUSTYPE);
142
143         last_addr = (void *)&mpc_bus[1];
144         nentries++;
145
146         /*
147          * ISA bus.
148          * FIXME: Same issue as for PCI bus.
149          */
150         mpc_bus         = last_addr;
151         mpc_bus->type   = MP_BUS;
152         mpc_bus->busid  = isabusid;
153         MPTABLE_STRNCPY(mpc_bus->bustype, MPTABLE_ISABUSTYPE);
154
155         last_addr = (void *)&mpc_bus[1];
156         nentries++;
157
158         /*
159          * IO-APIC chip.
160          */
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);
168
169         last_addr = (void *)&mpc_ioapic[1];
170         nentries++;
171
172         /*
173          * IRQ sources.
174          *
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.
180          *
181          * Also note we use PCI irqs here, no for ISA bus yet.
182          */
183
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;
187
188                 list_for_each_entry(irq_line, &dev->lines, node) {
189                         unsigned char srcbusirq;
190
191                         srcbusirq = (dev->id << 2) | (dev->pin - 1);
192
193                         mpc_intsrc = last_addr;
194
195                         mptable_add_irq_src(mpc_intsrc, pcibusid, srcbusirq, ioapicid, irq_line->line);
196                         last_addr = (void *)&mpc_intsrc[1];
197                         nentries++;
198                 }
199         }
200
201         /*
202          * Local IRQs assignment (LINT0, LINT1)
203          */
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 */
213
214         last_addr = (void *)&mpc_intsrc[1];
215         nentries++;
216
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 */
225
226         last_addr = (void *)&mpc_intsrc[1];
227         nentries++;
228
229         /*
230          * Floating MP table finally.
231          */
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);
234
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));
240
241         /*
242          * No last_addr inclrement here please, we need last
243          * active position here to compute table size.
244          */
245
246         /*
247          * Don't forget to update header in fixed table.
248         */
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);
252
253
254         /*
255          * We will copy the whole table, no need to separate
256          * floating structure and table itkvm.
257          */
258         size = (unsigned long)mpf_intel + sizeof(*mpf_intel) - (unsigned long)mpc_table;
259
260         /*
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.
264          */
265
266         if (size > (unsigned long)(MB_BIOS_END - bios_rom_size) ||
267             size > MPTABLE_MAX_SIZE) {
268                 free(mpc_table);
269                 pr_err("MP table is too big");
270
271                 return -E2BIG;
272         }
273
274         /*
275          * OK, it is time to move it to guest memory.
276          */
277         memcpy(guest_flat_to_host(kvm, real_mpc_table), mpc_table, size);
278
279         free(mpc_table);
280
281         return 0;
282 }
283 firmware_init(mptable__init);
284
285 int mptable__exit(struct kvm *kvm)
286 {
287         return 0;
288 }
289 firmware_exit(mptable__exit);