Deleted Added
full compact
mptbl.c (262350) mptbl.c (267393)
1/*-
2 * Copyright (c) 2012 NetApp, Inc.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright

--- 9 unchanged lines hidden (view full) ---

18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 *
1/*-
2 * Copyright (c) 2012 NetApp, Inc.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright

--- 9 unchanged lines hidden (view full) ---

18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 *
26 * $FreeBSD: stable/10/usr.sbin/bhyve/mptbl.c 262350 2014-02-23 00:46:05Z jhb $
26 * $FreeBSD: stable/10/usr.sbin/bhyve/mptbl.c 267393 2014-06-12 13:13:15Z jhb $
27 */
28
29#include <sys/cdefs.h>
27 */
28
29#include <sys/cdefs.h>
30__FBSDID("$FreeBSD: stable/10/usr.sbin/bhyve/mptbl.c 262350 2014-02-23 00:46:05Z jhb $");
30__FBSDID("$FreeBSD: stable/10/usr.sbin/bhyve/mptbl.c 267393 2014-06-12 13:13:15Z jhb $");
31
32#include <sys/types.h>
33#include <sys/errno.h>
34#include <x86/mptable.h>
35
36#include <stdio.h>
37#include <string.h>
38
39#include "acpi.h"
40#include "bhyverun.h"
41#include "mptbl.h"
31
32#include <sys/types.h>
33#include <sys/errno.h>
34#include <x86/mptable.h>
35
36#include <stdio.h>
37#include <string.h>
38
39#include "acpi.h"
40#include "bhyverun.h"
41#include "mptbl.h"
42#include "pci_emul.h"
42
43#define MPTABLE_BASE 0xF0000
44
45/* floating pointer length + maximum length of configuration table */
46#define MPTABLE_MAX_LENGTH (65536 + 16)
47
48#define LAPIC_PADDR 0xFEE00000
49#define LAPIC_VERSION 16

--- 20 unchanged lines hidden (view full) ---

70 (MPEP_SIG_MODEL << 4) | \
71 (MPEP_SIG_STEPPING))
72
73#define MPEP_FEATURES (0xBFEBFBFF) /* XXX Intel i7 */
74
75/* Number of local intr entries */
76#define MPEII_NUM_LOCAL_IRQ 2
77
43
44#define MPTABLE_BASE 0xF0000
45
46/* floating pointer length + maximum length of configuration table */
47#define MPTABLE_MAX_LENGTH (65536 + 16)
48
49#define LAPIC_PADDR 0xFEE00000
50#define LAPIC_VERSION 16

--- 20 unchanged lines hidden (view full) ---

71 (MPEP_SIG_MODEL << 4) | \
72 (MPEP_SIG_STEPPING))
73
74#define MPEP_FEATURES (0xBFEBFBFF) /* XXX Intel i7 */
75
76/* Number of local intr entries */
77#define MPEII_NUM_LOCAL_IRQ 2
78
78/* Number of i/o intr entries */
79#define MPEII_MAX_IRQ 24
80
81/* Bus entry defines */
82#define MPE_NUM_BUSES 2
83#define MPE_BUSNAME_LEN 6
84#define MPE_BUSNAME_ISA "ISA "
85#define MPE_BUSNAME_PCI "PCI "
86
87static void *oem_tbl_start;
88static int oem_tbl_size;

--- 101 unchanged lines hidden (view full) ---

190 memset(mpei, 0, sizeof(*mpei));
191 mpei->type = MPCT_ENTRY_IOAPIC;
192 mpei->apic_id = id;
193 mpei->apic_version = IOAPIC_VERSION;
194 mpei->apic_flags = IOAPICENTRY_FLAG_EN;
195 mpei->apic_address = IOAPIC_PADDR;
196}
197
79/* Bus entry defines */
80#define MPE_NUM_BUSES 2
81#define MPE_BUSNAME_LEN 6
82#define MPE_BUSNAME_ISA "ISA "
83#define MPE_BUSNAME_PCI "PCI "
84
85static void *oem_tbl_start;
86static int oem_tbl_size;

--- 101 unchanged lines hidden (view full) ---

188 memset(mpei, 0, sizeof(*mpei));
189 mpei->type = MPCT_ENTRY_IOAPIC;
190 mpei->apic_id = id;
191 mpei->apic_version = IOAPIC_VERSION;
192 mpei->apic_flags = IOAPICENTRY_FLAG_EN;
193 mpei->apic_address = IOAPIC_PADDR;
194}
195
196static int
197mpt_count_ioint_entries(void)
198{
199
200 /*
201 * Always include entries for the first 16 pins along with a entry
202 * for each active PCI INTx pin.
203 */
204 return (16 + pci_count_lintr());
205}
206
198static void
207static void
199mpt_build_ioint_entries(int_entry_ptr mpie, int num_pins, int id)
208mpt_generate_pci_int(int slot, int pin, int ioapic_irq, void *arg)
200{
209{
210 int_entry_ptr *mpiep, mpie;
211
212 mpiep = arg;
213 mpie = *mpiep;
214 memset(mpie, 0, sizeof(*mpie));
215
216 /*
217 * This is always after another I/O interrupt entry, so cheat
218 * and fetch the I/O APIC ID from the prior entry.
219 */
220 mpie->type = MPCT_ENTRY_INT;
221 mpie->int_type = INTENTRY_TYPE_INT;
222 mpie->src_bus_id = 0;
223 mpie->src_bus_irq = slot << 2 | (pin - 1);
224 mpie->dst_apic_id = mpie[-1].dst_apic_id;
225 mpie->dst_apic_int = ioapic_irq;
226
227 *mpiep = mpie + 1;
228}
229
230static void
231mpt_build_ioint_entries(int_entry_ptr mpie, int id)
232{
201 int pin;
202
203 /*
204 * The following config is taken from kernel mptable.c
205 * mptable_parse_default_config_ints(...), for now
206 * just use the default config, tweek later if needed.
207 */
208
233 int pin;
234
235 /*
236 * The following config is taken from kernel mptable.c
237 * mptable_parse_default_config_ints(...), for now
238 * just use the default config, tweek later if needed.
239 */
240
209 /* Run through all 16 pins. */
210 for (pin = 0; pin < num_pins; pin++) {
241 /* First, generate the first 16 pins. */
242 for (pin = 0; pin < 16; pin++) {
211 memset(mpie, 0, sizeof(*mpie));
212 mpie->type = MPCT_ENTRY_INT;
213 mpie->src_bus_id = 1;
214 mpie->dst_apic_id = id;
215
216 /*
217 * All default configs route IRQs from bus 0 to the first 16
218 * pins of the first I/O APIC with an APIC ID of 2.

--- 11 unchanged lines hidden (view full) ---

230 break;
231 case SCI_INT:
232 /* ACPI SCI is level triggered and active-lo. */
233 mpie->int_flags = INTENTRY_FLAGS_POLARITY_ACTIVELO |
234 INTENTRY_FLAGS_TRIGGER_LEVEL;
235 mpie->int_type = INTENTRY_TYPE_INT;
236 mpie->src_bus_irq = SCI_INT;
237 break;
243 memset(mpie, 0, sizeof(*mpie));
244 mpie->type = MPCT_ENTRY_INT;
245 mpie->src_bus_id = 1;
246 mpie->dst_apic_id = id;
247
248 /*
249 * All default configs route IRQs from bus 0 to the first 16
250 * pins of the first I/O APIC with an APIC ID of 2.

--- 11 unchanged lines hidden (view full) ---

262 break;
263 case SCI_INT:
264 /* ACPI SCI is level triggered and active-lo. */
265 mpie->int_flags = INTENTRY_FLAGS_POLARITY_ACTIVELO |
266 INTENTRY_FLAGS_TRIGGER_LEVEL;
267 mpie->int_type = INTENTRY_TYPE_INT;
268 mpie->src_bus_irq = SCI_INT;
269 break;
238 case 5:
239 case 10:
240 case 11:
241 /*
242 * PCI Irqs set to level triggered and active-lo.
243 */
244 mpie->int_flags = INTENTRY_FLAGS_POLARITY_ACTIVELO |
245 INTENTRY_FLAGS_TRIGGER_LEVEL;
246 mpie->src_bus_id = 0;
247 /* fall through.. */
248 default:
249 /* All other pins are identity mapped. */
250 mpie->int_type = INTENTRY_TYPE_INT;
251 mpie->src_bus_irq = pin;
252 break;
253 }
254 mpie++;
255 }
256
270 default:
271 /* All other pins are identity mapped. */
272 mpie->int_type = INTENTRY_TYPE_INT;
273 mpie->src_bus_irq = pin;
274 break;
275 }
276 mpie++;
277 }
278
279 /* Next, generate entries for any PCI INTx interrupts. */
280 pci_walk_lintr(mpt_generate_pci_int, &mpie);
257}
258
259void
260mptable_add_oemtbl(void *tbl, int tblsz)
261{
262
263 oem_tbl_start = tbl;
264 oem_tbl_size = tblsz;
265}
266
267int
268mptable_build(struct vmctx *ctx, int ncpu)
269{
270 mpcth_t mpch;
271 bus_entry_ptr mpeb;
272 io_apic_entry_ptr mpei;
273 proc_entry_ptr mpep;
274 mpfps_t mpfp;
275 int_entry_ptr mpie;
281}
282
283void
284mptable_add_oemtbl(void *tbl, int tblsz)
285{
286
287 oem_tbl_start = tbl;
288 oem_tbl_size = tblsz;
289}
290
291int
292mptable_build(struct vmctx *ctx, int ncpu)
293{
294 mpcth_t mpch;
295 bus_entry_ptr mpeb;
296 io_apic_entry_ptr mpei;
297 proc_entry_ptr mpep;
298 mpfps_t mpfp;
299 int_entry_ptr mpie;
300 int ioints;
276 char *curraddr;
277 char *startaddr;
278
279 startaddr = paddr_guest2host(ctx, MPTABLE_BASE, MPTABLE_MAX_LENGTH);
280 if (startaddr == NULL) {
281 printf("mptable requires mapped mem\n");
282 return (ENOMEM);
283 }

--- 18 unchanged lines hidden (view full) ---

302 mpch->entry_count += MPE_NUM_BUSES;
303
304 mpei = (io_apic_entry_ptr)curraddr;
305 mpt_build_ioapic_entries(mpei, 0);
306 curraddr += sizeof(*mpei);
307 mpch->entry_count++;
308
309 mpie = (int_entry_ptr) curraddr;
301 char *curraddr;
302 char *startaddr;
303
304 startaddr = paddr_guest2host(ctx, MPTABLE_BASE, MPTABLE_MAX_LENGTH);
305 if (startaddr == NULL) {
306 printf("mptable requires mapped mem\n");
307 return (ENOMEM);
308 }

--- 18 unchanged lines hidden (view full) ---

327 mpch->entry_count += MPE_NUM_BUSES;
328
329 mpei = (io_apic_entry_ptr)curraddr;
330 mpt_build_ioapic_entries(mpei, 0);
331 curraddr += sizeof(*mpei);
332 mpch->entry_count++;
333
334 mpie = (int_entry_ptr) curraddr;
310 mpt_build_ioint_entries(mpie, MPEII_MAX_IRQ, 0);
311 curraddr += sizeof(*mpie) * MPEII_MAX_IRQ;
312 mpch->entry_count += MPEII_MAX_IRQ;
335 ioints = mpt_count_ioint_entries();
336 mpt_build_ioint_entries(mpie, 0);
337 curraddr += sizeof(*mpie) * ioints;
338 mpch->entry_count += ioints;
313
314 mpie = (int_entry_ptr)curraddr;
315 mpt_build_localint_entries(mpie);
316 curraddr += sizeof(*mpie) * MPEII_NUM_LOCAL_IRQ;
317 mpch->entry_count += MPEII_NUM_LOCAL_IRQ;
318
319 if (oem_tbl_start) {
320 mpch->oem_table_pointer = curraddr - startaddr + MPTABLE_BASE;
321 mpch->oem_table_size = oem_tbl_size;
322 memcpy(curraddr, oem_tbl_start, oem_tbl_size);
323 }
324
325 mpch->base_table_length = curraddr - (char *)mpch;
326 mpch->checksum = mpt_compute_checksum(mpch, mpch->base_table_length);
327
328 return (0);
329}
339
340 mpie = (int_entry_ptr)curraddr;
341 mpt_build_localint_entries(mpie);
342 curraddr += sizeof(*mpie) * MPEII_NUM_LOCAL_IRQ;
343 mpch->entry_count += MPEII_NUM_LOCAL_IRQ;
344
345 if (oem_tbl_start) {
346 mpch->oem_table_pointer = curraddr - startaddr + MPTABLE_BASE;
347 mpch->oem_table_size = oem_tbl_size;
348 memcpy(curraddr, oem_tbl_start, oem_tbl_size);
349 }
350
351 mpch->base_table_length = curraddr - (char *)mpch;
352 mpch->checksum = mpt_compute_checksum(mpch, mpch->base_table_length);
353
354 return (0);
355}