diff options
-rw-r--r-- | lib/libvmmapi/Makefile | 2 | ||||
-rw-r--r-- | lib/libvmmapi/mptable.h | 170 | ||||
-rw-r--r-- | lib/libvmmapi/vmmapi.c | 13 | ||||
-rw-r--r-- | lib/libvmmapi/vmmapi.h | 2 | ||||
-rw-r--r-- | usr.sbin/bhyve/Makefile | 2 | ||||
-rw-r--r-- | usr.sbin/bhyve/fbsdrun.c | 17 | ||||
-rw-r--r-- | usr.sbin/bhyve/fbsdrun.h | 1 | ||||
-rw-r--r-- | usr.sbin/bhyve/mptbl.c (renamed from lib/libvmmapi/mptable.c) | 268 | ||||
-rw-r--r-- | usr.sbin/bhyve/mptbl.h | 35 | ||||
-rw-r--r-- | usr.sbin/bhyve/pci_emul.c | 202 | ||||
-rw-r--r-- | usr.sbin/bhyve/pci_emul.h | 1 |
11 files changed, 202 insertions, 511 deletions
diff --git a/lib/libvmmapi/Makefile b/lib/libvmmapi/Makefile index 82dde08..93d3c85 100644 --- a/lib/libvmmapi/Makefile +++ b/lib/libvmmapi/Makefile @@ -1,7 +1,7 @@ # $FreeBSD$ LIB= vmmapi -SRCS= vmmapi.c vmmapi_freebsd.c mptable.c +SRCS= vmmapi.c vmmapi_freebsd.c INCS= vmmapi.h WARNS?= 2 diff --git a/lib/libvmmapi/mptable.h b/lib/libvmmapi/mptable.h deleted file mode 100644 index 51c7bc1..0000000 --- a/lib/libvmmapi/mptable.h +++ /dev/null @@ -1,170 +0,0 @@ -/*- - * Copyright (c) 2011 NetApp, Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY NETAPP, INC ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL NETAPP, INC OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD$ - */ - -#ifndef _MPTABLE_h_ -#define _MPTABLE_h_ - -#define MP_SPECREV (4) // MP spec revision 1.1 - -/* - * MP Floating Pointer Structure - */ -#define MPFP_SIGNATURE "_MP_" -#define MPFP_SIGNATURE_LEN (4) -#define MPFP_FEATURE2 (0x80) // IMCR is present -struct mp_floating_pointer { - uint8_t signature[MPFP_SIGNATURE_LEN]; - uint32_t mptable_paddr; - uint8_t length; - uint8_t specrev; - uint8_t checksum; - uint8_t feature1; - uint8_t feature2; - uint8_t feature3; - uint8_t feature4; - uint8_t feature5; -}; - - -/* - * MP Configuration Table Header - */ -#define MPCH_SIGNATURE "PCMP" -#define MPCH_SIGNATURE_LEN (4) - -#define MPCH_OEMID "NETAPP " -#define MPCH_OEMID_LEN (8) -#define MPCH_PRODID "vFiler " -#define MPCH_PRODID_LEN (12) - -struct mp_config_hdr { - uint8_t signature[MPCH_SIGNATURE_LEN]; - uint16_t length; - uint8_t specrev; - uint8_t checksum; - uint8_t oemid[MPCH_OEMID_LEN]; - uint8_t prodid[MPCH_PRODID_LEN]; - uint32_t oem_ptr; - uint16_t oem_sz; - uint16_t nr_entries; - uint32_t lapic_paddr; - uint16_t ext_length; - uint8_t ext_checksum; - uint8_t reserved; -}; - -#define MP_ENTRY_PROC (0) -#define MP_ENTRY_BUS (1) -#define MP_ENTRY_IOAPIC (2) -#define MP_ENTRY_IOINT (3) -#define MP_ENTRY_LINT (4) - -/* - * MP Processor Entry - */ - -#define MPEP_FLAGS_EN (0x1) -#define MPEP_FLAGS_BSP (0x2) - -#define MPEP_SIG_FAMILY (6) -#define MPEP_SIG_MODEL (26) -#define MPEP_SIG_STEPPING (5) -#define MPEP_SIGNATURE ((MPEP_SIG_FAMILY << 8) | (MPEP_SIG_MODEL << 4) \ - | (MPEP_SIG_STEPPING)) - -#define MPEP_FEATURES (0xBFEBFBFF) // Value from Intel i7 CPUID - -struct mpe_proc { - uint8_t entry_type; - uint8_t lapic_id; - uint8_t lapic_version; - uint8_t proc_flags; - uint32_t proc_signature; - uint32_t feature_flags; - uint8_t reserved[8]; -}; - -/* - * MP Bus Entry - */ - -#define MPE_NUM_BUSES (2) -#define MPE_BUSNAME_LEN (6) -#define MPE_BUSID_ISA (0) -#define MPE_BUSID_PCI (1) -#define MPE_BUSNAME_ISA "ISA " -#define MPE_BUSNAME_PCI "PCI " -struct mpe_bus { - uint8_t entry_type; - uint8_t busid; - uint8_t busname[MPE_BUSNAME_LEN]; -}; - -/* - * MP IO APIC Entry - */ -#define MPE_IOAPIC_FLAG_EN (1) -struct mpe_ioapic { - uint8_t entry_type; - uint8_t ioapic_id; - uint8_t ioapic_version; - uint8_t ioapic_flags; - uint32_t ioapic_paddr; - -}; - -/* - * MP IO Interrupt Assignment Entry - */ -#define MPEII_INTR_INT (0) -#define MPEII_INTR_NMI (1) -#define MPEII_INTR_SMI (2) -#define MPEII_INTR_EXTINT (3) -#define MPEII_PCI_IRQ_MASK (0x0c20U) /* IRQ 5,10,11 are PCI connected */ -#define MPEII_MAX_IRQ (16) -#define MPEII_FLAGS_TRIGMODE_LEVEL (0x3) -struct mpe_ioint { - uint8_t entry_type; - uint8_t intr_type; - uint16_t intr_flags; - uint8_t src_bus_id; - uint8_t src_bus_irq; - uint8_t dst_apic_id; - uint8_t dst_apic_intin; -}; - -/* - * MP Local Interrupt Assignment Entry - */ -struct mpe_lint { - uint8_t entry_type; -}; - -int vm_build_mptable(struct vmctx *ctxt, vm_paddr_t gpa, int len, - int ncpu, int ioapic, void *oemp, int oemsz); -#endif /* _MPTABLE_h_ */ diff --git a/lib/libvmmapi/vmmapi.c b/lib/libvmmapi/vmmapi.c index fdbbbcb..cfb42d0 100644 --- a/lib/libvmmapi/vmmapi.c +++ b/lib/libvmmapi/vmmapi.c @@ -47,10 +47,6 @@ __FBSDID("$FreeBSD$"); #include <machine/vmm_dev.h> #include "vmmapi.h" -#include "mptable.h" - -#define BIOS_ROM_BASE (0xf0000) -#define BIOS_ROM_SIZE (0x10000) struct vmctx { int fd; @@ -329,15 +325,6 @@ vm_inject_event2(struct vmctx *ctx, int vcpu, enum vm_event_type type, } int -vm_build_tables(struct vmctx *ctxt, int ncpu, int ioapic, - void *oemtbl, int oemtblsz) -{ - - return (vm_build_mptable(ctxt, BIOS_ROM_BASE, BIOS_ROM_SIZE, ncpu, - ioapic, oemtbl, oemtblsz)); -} - -int vm_apicid2vcpu(struct vmctx *ctx, int apicid) { /* diff --git a/lib/libvmmapi/vmmapi.h b/lib/libvmmapi/vmmapi.h index fe5116e..de04252 100644 --- a/lib/libvmmapi/vmmapi.h +++ b/lib/libvmmapi/vmmapi.h @@ -60,8 +60,6 @@ int vm_get_pinning(struct vmctx *ctx, int vcpu, int *host_cpuid); int vm_set_pinning(struct vmctx *ctx, int vcpu, int host_cpuid); int vm_run(struct vmctx *ctx, int vcpu, uint64_t rip, struct vm_exit *ret_vmexit); -int vm_build_tables(struct vmctx *ctxt, int ncpus, int ioapic, - void *oemtbl, int oemtblsz); int vm_apicid2vcpu(struct vmctx *ctx, int apicid); int vm_inject_event(struct vmctx *ctx, int vcpu, enum vm_event_type type, int vector); diff --git a/usr.sbin/bhyve/Makefile b/usr.sbin/bhyve/Makefile index 72d60ae..3cae422 100644 --- a/usr.sbin/bhyve/Makefile +++ b/usr.sbin/bhyve/Makefile @@ -5,7 +5,7 @@ PROG= bhyve SRCS= atpic.c consport.c dbgport.c elcr.c fbsdrun.c inout.c -SRCS+= instruction_emul.c ioapic.c mem.c mevent.c +SRCS+= instruction_emul.c ioapic.c mem.c mevent.c mptbl.c SRCS+= pci_emul.c pci_hostbridge.c pci_passthru.c pci_virtio_block.c SRCS+= pci_virtio_net.c pci_uart.c pit_8254.c post.c rtc.c uart.c xmsr.c SRCS+= spinup_ap.c diff --git a/usr.sbin/bhyve/fbsdrun.c b/usr.sbin/bhyve/fbsdrun.c index d7061f9..9905f19 100644 --- a/usr.sbin/bhyve/fbsdrun.c +++ b/usr.sbin/bhyve/fbsdrun.c @@ -52,6 +52,7 @@ __FBSDID("$FreeBSD$"); #include "dbgport.h" #include "mem.h" #include "mevent.h" +#include "mptbl.h" #include "pci_emul.h" #include "xmsr.h" #include "instruction_emul.h" @@ -99,9 +100,6 @@ static const int BSP = 0; static int cpumask; -static void *oem_tbl_start; -static int oem_tbl_size; - static void vm_loop(struct vmctx *ctx, int vcpu, uint64_t rip); struct vm_exit vmexit[VM_MAXCPU]; @@ -144,7 +142,6 @@ usage(int code) " -z: guest hz (default is %d)\n" " -s: <slot,driver,configinfo> PCI slot config\n" " -S: <slot,driver,configinfo> legacy PCI slot config\n" - " -n: <slot,name> PCI slot naming\n" " -m: lowmem in MB\n" " -M: highmem in MB\n" " -x: mux vcpus to 1 hcpu\n" @@ -168,13 +165,6 @@ paddr_guest2host(uintptr_t gaddr) return (NULL); } -void -fbsdrun_add_oemtbl(void *tbl, int tblsz) -{ - oem_tbl_start = tbl; - oem_tbl_size = tblsz; -} - int fbsdrun_disable_x2apic(void) { @@ -615,9 +605,6 @@ main(int argc, char *argv[]) case 'S': pci_parse_slot(optarg, 1); break; - case 'n': - pci_parse_name(optarg); - break; case 'm': lomem_sz = strtoul(optarg, NULL, 0) * MB; break; @@ -731,7 +718,7 @@ main(int argc, char *argv[]) /* * build the guest tables, MP etc. */ - vm_build_tables(ctx, guest_ncpus, ioapic, oem_tbl_start, oem_tbl_size); + mptable_build(ctx, guest_ncpus, ioapic); /* * Add CPU 0 diff --git a/usr.sbin/bhyve/fbsdrun.h b/usr.sbin/bhyve/fbsdrun.h index 0b9fe7d..45033b8 100644 --- a/usr.sbin/bhyve/fbsdrun.h +++ b/usr.sbin/bhyve/fbsdrun.h @@ -46,7 +46,6 @@ extern u_long lomem_sz, himem_sz; void *paddr_guest2host(uintptr_t); void fbsdrun_addcpu(struct vmctx *ctx, int cpu, uint64_t rip); -void fbsdrun_add_oemtbl(void *tbl, int tblsz); int fbsdrun_muxed(void); int fbsdrun_vmexit_on_hlt(void); int fbsdrun_vmexit_on_pause(void); diff --git a/lib/libvmmapi/mptable.c b/usr.sbin/bhyve/mptbl.c index 048ea2d..03aaaee 100644 --- a/lib/libvmmapi/mptable.c +++ b/usr.sbin/bhyve/mptbl.c @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2011 NetApp, Inc. + * Copyright (c) 2012 NetApp, Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -30,108 +30,153 @@ __FBSDID("$FreeBSD$"); #include <sys/types.h> -#include <sys/mman.h> +#include <sys/errno.h> +#include <x86/mptable.h> #include <stdio.h> #include <string.h> -#include <machine/vmm.h> -#include <machine/vmm_dev.h> -#include "vmmapi.h" -#include "mptable.h" - -#define LAPIC_PADDR (0xFEE00000) -#define LAPIC_VERSION (16) - -#define IOAPIC_PADDR (0xFEC00000) -#define IOAPIC_VERSION (0x11) - -extern int errno; +#include "fbsdrun.h" +#include "mptbl.h" + +#define MPTABLE_BASE 0xF0000 + +#define LAPIC_PADDR 0xFEE00000 +#define LAPIC_VERSION 16 + +#define IOAPIC_PADDR 0xFEC00000 +#define IOAPIC_VERSION 0x11 + +#define MP_SPECREV 4 +#define MPFP_SIG "_MP_" + +/* Configuration header defines */ +#define MPCH_SIG "PCMP" +#define MPCH_OEMID "BHyVe " +#define MPCH_OEMID_LEN 8 +#define MPCH_PRODID "Hypervisor " +#define MPCH_PRODID_LEN 12 + +/* Processor entry defines */ +#define MPEP_SIG_FAMILY 6 /* XXX bhyve should supply this */ +#define MPEP_SIG_MODEL 26 +#define MPEP_SIG_STEPPING 5 +#define MPEP_SIG \ + ((MPEP_SIG_FAMILY << 8) | \ + (MPEP_SIG_MODEL << 4) | \ + (MPEP_SIG_STEPPING)) + +#define MPEP_FEATURES (0xBFEBFBFF) /* XXX Intel i7 */ + +/* Define processor entry struct since <x86/mptable.h> gets it wrong */ +typedef struct BPROCENTRY { + u_char type; + u_char apic_id; + u_char apic_version; + u_char cpu_flags; + uint32_t cpu_signature; + uint32_t feature_flags; + uint32_t reserved1; + uint32_t reserved2; +} *bproc_entry_ptr; +CTASSERT(sizeof(struct BPROCENTRY) == 20); + +/* Bus entry defines */ +#define MPE_NUM_BUSES 2 +#define MPE_BUSNAME_LEN 6 +#define MPE_BUSNAME_ISA "ISA " +#define MPE_BUSNAME_PCI "PCI " + +static void *oem_tbl_start; +static int oem_tbl_size; static uint8_t -mp_compute_checksum(void *base, size_t len) +mpt_compute_checksum(void *base, size_t len) { - uint8_t *bytes = base; - uint8_t sum = 0; - for(; len > 0; len--) { + uint8_t *bytes; + uint8_t sum; + + for(bytes = base, sum = 0; len > 0; len--) { sum += *bytes++; } - return 256 - sum; + + return (256 - sum); } static void -mp_build_mpfp(struct mp_floating_pointer *mpfp, vm_paddr_t mpfp_gpa) +mpt_build_mpfp(mpfps_t mpfp, vm_paddr_t gpa) { + memset(mpfp, 0, sizeof(*mpfp)); - memcpy(mpfp->signature, MPFP_SIGNATURE, MPFP_SIGNATURE_LEN); - mpfp->mptable_paddr = mpfp_gpa + sizeof(*mpfp); - mpfp->specrev = MP_SPECREV; - mpfp->feature2 = 0; - mpfp->checksum = mp_compute_checksum(mpfp, sizeof(*mpfp)); + memcpy(mpfp->signature, MPFP_SIG, 4); + mpfp->pap = gpa + sizeof(*mpfp); + mpfp->length = 1; + mpfp->spec_rev = MP_SPECREV; + mpfp->checksum = mpt_compute_checksum(mpfp, sizeof(*mpfp)); } static void -mp_build_mpch(struct mp_config_hdr *mpch) +mpt_build_mpch(mpcth_t mpch) { - memset(mpch, 0, sizeof(*mpch)); - mpch->specrev = MP_SPECREV; - memcpy(mpch->signature, MPCH_SIGNATURE, MPCH_SIGNATURE_LEN); - memcpy(mpch->oemid, MPCH_OEMID, MPCH_OEMID_LEN); - memcpy(mpch->prodid, MPCH_PRODID, MPCH_PRODID_LEN); - mpch->lapic_paddr = LAPIC_PADDR; - + memset(mpch, 0, sizeof(*mpch)); + memcpy(mpch->signature, MPCH_SIG, 4); + mpch->spec_rev = MP_SPECREV; + memcpy(mpch->oem_id, MPCH_OEMID, MPCH_OEMID_LEN); + memcpy(mpch->product_id, MPCH_PRODID, MPCH_PRODID_LEN); + mpch->apic_address = LAPIC_PADDR; } static void -mp_build_proc_entries(struct mpe_proc *mpep, int num_proc) +mpt_build_proc_entries(bproc_entry_ptr mpep, int ncpu) { int i; - for (i = 0; i < num_proc; i++) { + for (i = 0; i < ncpu; i++) { memset(mpep, 0, sizeof(*mpep)); - mpep->entry_type = MP_ENTRY_PROC; - mpep->lapic_id = i; // XXX - mpep->lapic_version = LAPIC_VERSION; - mpep->proc_flags = (i == 0)?MPEP_FLAGS_BSP:0; - mpep->proc_flags |= MPEP_FLAGS_EN; - mpep->proc_signature = MPEP_SIGNATURE; + mpep->type = MPCT_ENTRY_PROCESSOR; + mpep->apic_id = i; // XXX + mpep->apic_version = LAPIC_VERSION; + mpep->cpu_flags = PROCENTRY_FLAG_EN; + if (i == 0) + mpep->cpu_flags |= PROCENTRY_FLAG_BP; + mpep->cpu_signature = MPEP_SIG; mpep->feature_flags = MPEP_FEATURES; mpep++; } - } static void -mp_build_bus_entries(struct mpe_bus *mpeb) +mpt_build_bus_entries(bus_entry_ptr mpeb) { + memset(mpeb, 0, sizeof(*mpeb)); - mpeb->entry_type = MP_ENTRY_BUS; - mpeb->busid = MPE_BUSID_ISA; - memcpy(mpeb->busname, MPE_BUSNAME_ISA, MPE_BUSNAME_LEN); + mpeb->type = MPCT_ENTRY_BUS; + mpeb->bus_id = ISA; + memcpy(mpeb->bus_type, MPE_BUSNAME_ISA, MPE_BUSNAME_LEN); mpeb++; memset(mpeb, 0, sizeof(*mpeb)); - mpeb->entry_type = MP_ENTRY_BUS; - mpeb->busid = MPE_BUSID_PCI; - memcpy(mpeb->busname, MPE_BUSNAME_PCI, MPE_BUSNAME_LEN); - + mpeb->type = MPCT_ENTRY_BUS; + mpeb->bus_id = PCI; + memcpy(mpeb->bus_type, MPE_BUSNAME_PCI, MPE_BUSNAME_LEN); } static void -mp_build_ioapic_entries(struct mpe_ioapic *mpei, int id) +mpt_build_ioapic_entries(io_apic_entry_ptr mpei, int id) { + memset(mpei, 0, sizeof(*mpei)); - mpei->entry_type = MP_ENTRY_IOAPIC; - mpei->ioapic_id = id; - mpei->ioapic_version = IOAPIC_VERSION; - mpei->ioapic_flags = MPE_IOAPIC_FLAG_EN; - mpei->ioapic_paddr = IOAPIC_PADDR; + mpei->type = MPCT_ENTRY_IOAPIC; + mpei->apic_id = id; + mpei->apic_version = IOAPIC_VERSION; + mpei->apic_flags = IOAPICENTRY_FLAG_EN; + mpei->apic_address = IOAPIC_PADDR; } #ifdef notyet static void -mp_build_ioint_entries(struct mpe_ioint *mpeii, int num_pins, int id) +mpt_build_ioint_entries(struct mpe_ioint *mpeii, int num_pins, int id) { int pin; @@ -150,8 +195,8 @@ mp_build_ioint_entries(struct mpe_ioint *mpeii, int num_pins, int id) mpeii->dst_apic_id = id; /* - * All default configs route IRQs from bus 0 to the first 16 pins - * of the first I/O APIC with an APIC ID of 2. + * All default configs route IRQs from bus 0 to the first 16 + * pins of the first I/O APIC with an APIC ID of 2. */ mpeii->dst_apic_intin = pin; switch (pin) { @@ -187,7 +232,6 @@ mp_build_ioint_entries(struct mpe_ioint *mpeii, int num_pins, int id) memcpy(dest, src, bytes); \ str[bytes] = 0; - static void mptable_dump(struct mp_floating_pointer *mpfp, struct mp_config_hdr *mpch) { @@ -208,15 +252,15 @@ mptable_dump(struct mp_floating_pointer *mpfp, struct mp_config_hdr *mpch) printf(" MP Floating Pointer :\n"); COPYSTR(str, mpfp->signature, 4); - printf(" signature: %s\n", str); - printf(" mpch paddr: %x\n", mpfp->mptable_paddr); - printf(" length: %x\n", mpfp->length); - printf(" specrec: %x\n", mpfp->specrev); - printf(" checksum: %x\n", mpfp->checksum); - printf(" feature1: %x\n", mpfp->feature1); - printf(" feature2: %x\n", mpfp->feature2); - printf(" feature3: %x\n", mpfp->feature3); - printf(" feature4: %x\n", mpfp->feature4); + printf("\tsignature:\t%s\n", str); + printf("\tmpch paddr:\t%x\n", mpfp->mptable_paddr); + printf("\tlength:\t%x\n", mpfp->length); + printf("\tspecrec:\t%x\n", mpfp->specrev); + printf("\tchecksum:\t%x\n", mpfp->checksum); + printf("\tfeature1:\t%x\n", mpfp->feature1); + printf("\tfeature2:\t%x\n", mpfp->feature2); + printf("\tfeature3:\t%x\n", mpfp->feature3); + printf("\tfeature4:\t%x\n", mpfp->feature4); printf(" MP Configuration Header :\n"); COPYSTR(str, mpch->signature, 4); @@ -283,60 +327,72 @@ mptable_dump(struct mp_floating_pointer *mpfp, struct mp_config_hdr *mpch) } #endif +void +mptable_add_oemtbl(void *tbl, int tblsz) +{ + + oem_tbl_start = tbl; + oem_tbl_size = tblsz; +} + int -vm_build_mptable(struct vmctx *ctx, vm_paddr_t gpa, int len, int ncpu, - int ioapic, void *oemp, int oemsz) +mptable_build(struct vmctx *ctx, int ncpu, int ioapic) { - struct mp_config_hdr *mpch; - char *mapaddr; + mpcth_t mpch; + bus_entry_ptr mpeb; + io_apic_entry_ptr mpei; + bproc_entry_ptr mpep; + mpfps_t mpfp; + char *curraddr; char *startaddr; - int error; - mapaddr = vm_map_memory(ctx, gpa, len); - if (mapaddr == MAP_FAILED) { - printf("%s\n", strerror(errno)); - goto err; + if (paddr_guest2host(0) == NULL) { + printf("mptable requires mapped mem\n"); + return (ENOMEM); } - startaddr = mapaddr; - mp_build_mpfp((struct mp_floating_pointer*) mapaddr, gpa); - mapaddr += sizeof(struct mp_floating_pointer); + startaddr = curraddr = paddr_guest2host(MPTABLE_BASE); + + mpfp = (mpfps_t)curraddr; + mpt_build_mpfp(mpfp, MPTABLE_BASE); + curraddr += sizeof(*mpfp); - mpch = (struct mp_config_hdr*)mapaddr; - mp_build_mpch(mpch); - mapaddr += sizeof(struct mp_config_hdr); + mpch = (mpcth_t)curraddr; + mpt_build_mpch(mpch); + curraddr += sizeof(*mpch); - mp_build_proc_entries((struct mpe_proc*) mapaddr, ncpu); - mapaddr += (sizeof(struct mpe_proc)*ncpu); - mpch->nr_entries += ncpu; + mpep = (bproc_entry_ptr)curraddr; + mpt_build_proc_entries(mpep, ncpu); + curraddr += sizeof(*mpep) * ncpu; + mpch->entry_count += ncpu; - mp_build_bus_entries((struct mpe_bus*)mapaddr); - mapaddr += (sizeof(struct mpe_bus)*MPE_NUM_BUSES); - mpch->nr_entries += MPE_NUM_BUSES; + mpeb = (bus_entry_ptr) curraddr; + mpt_build_bus_entries(mpeb); + curraddr += sizeof(*mpeb) * MPE_NUM_BUSES; + mpch->entry_count += MPE_NUM_BUSES; if (ioapic) { - mp_build_ioapic_entries((struct mpe_ioapic*)mapaddr, ncpu + 1); - mapaddr += sizeof(struct mpe_ioapic); - mpch->nr_entries++; + mpei = (io_apic_entry_ptr)curraddr; + mpt_build_ioapic_entries(mpei, ncpu + 1); + curraddr += sizeof(*mpei); + mpch->entry_count++; } #ifdef notyet - mp_build_ioint_entries((struct mpe_ioint*)mapaddr, MPEII_MAX_IRQ, + mpt_build_ioint_entries((struct mpe_ioint*)curraddr, MPEII_MAX_IRQ, ncpu + 1); - mapaddr += sizeof(struct mpe_ioint)*MPEII_MAX_IRQ; - mpch->nr_entries += MPEII_MAX_IRQ; - + curraddr += sizeof(struct mpe_ioint) * MPEII_MAX_IRQ; + mpch->entry_count += MPEII_MAX_IRQ; #endif - if (oemp) { - mpch->oem_ptr = mapaddr - startaddr + gpa; - mpch->oem_sz = oemsz; - memcpy(mapaddr, oemp, oemsz); + + if (oem_tbl_start) { + mpch->oem_table_pointer = curraddr - startaddr + MPTABLE_BASE; + mpch->oem_table_size = oem_tbl_size; + memcpy(curraddr, oem_tbl_start, oem_tbl_size); } - mpch->length = (mapaddr) - ((char*) mpch); - mpch->checksum = mp_compute_checksum(mpch, sizeof(*mpch)); + mpch->base_table_length = curraddr - (char *)mpch; + mpch->checksum = mpt_compute_checksum(mpch, sizeof(*mpch)); - // mptable_dump((struct mp_floating_pointer*)startaddr, mpch); -err: - return (error); + return (0); } diff --git a/usr.sbin/bhyve/mptbl.h b/usr.sbin/bhyve/mptbl.h new file mode 100644 index 0000000..3c4c527 --- /dev/null +++ b/usr.sbin/bhyve/mptbl.h @@ -0,0 +1,35 @@ +/*- + * Copyright (c) 2012 NetApp, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY NETAPP, INC ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL NETAPP, INC OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#ifndef _MPTBL_H_ +#define _MPTBL_H_ + +int mptable_build(struct vmctx *ctx, int ncpu, int ioapic); +void mptable_add_oemtbl(void *tbl, int tblsz); + +#endif /* _MPTBL_H_ */ diff --git a/usr.sbin/bhyve/pci_emul.c b/usr.sbin/bhyve/pci_emul.c index 06fbcc8..f9d75e3 100644 --- a/usr.sbin/bhyve/pci_emul.c +++ b/usr.sbin/bhyve/pci_emul.c @@ -45,6 +45,7 @@ __FBSDID("$FreeBSD$"); #include "fbsdrun.h" #include "inout.h" #include "mem.h" +#include "mptbl.h" #include "pci_emul.h" #include "ioapic.h" @@ -69,10 +70,6 @@ static struct slotinfo { char *si_name; char *si_param; struct pci_devinst *si_devi; - int si_titled; - int si_pslot; - char si_prefix; - char si_suffix; int si_legacy; } pci_slotinfo[MAXSLOTS][MAXFUNCS]; @@ -87,37 +84,6 @@ static struct lirqinfo { struct pci_devinst *li_owner; /* XXX should be a list */ } lirq[NLIRQ]; -/* - * NetApp specific: - * struct used to build an in-core OEM table to supply device names - * to driver instances - */ -static struct mptable_pci_devnames { -#define MPT_HDR_BASE 0 -#define MPT_HDR_NAME 2 - uint16_t md_hdrtype; - uint16_t md_entries; - uint16_t md_cksum; - uint16_t md_pad; -#define MPT_NTAP_SIG \ - ((uint32_t)(('P' << 24) | ('A' << 16) | ('T' << 8) | 'N')) - uint32_t md_sig; - uint32_t md_rsvd; - struct mptable_pci_slotinfo { - uint16_t mds_type; - uint16_t mds_phys_slot; - uint8_t mds_bus; - uint8_t mds_slot; - uint8_t mds_func; - uint8_t mds_pad; - uint16_t mds_vid; - uint16_t mds_did; - uint8_t mds_suffix[4]; - uint8_t mds_prefix[4]; - uint32_t mds_rsvd[3]; - } md_slotinfo[MAXSLOTS * MAXFUNCS]; -} pci_devnames; - SET_DECLARE(pci_devemu_set, struct pci_devemu); static uint64_t pci_emul_iobase; @@ -134,7 +100,6 @@ static uint64_t pci_emul_membase64; #define PCI_EMUL_MEMLIMIT64 0xFD00000000UL static int pci_emul_devices; -static int devname_elems; /* * I/O access @@ -201,169 +166,6 @@ pci_parse_slot(char *opt, int legacy) } } -/* - * - * PCI MPTable names are of the form: - * - * <slot>[:<func>],[prefix]<digit><suffix> - * - * .. with <prefix> an alphabetic char, <digit> a 1 or 2-digit string, - * and <suffix> a single char. - * - * Examples: - * 1,e0c - * 4:0,e0P - * 4:1,e0M - * 6,43a - * 7,0f - * 10,1 - * 2,12a - * - * Note that this is NetApp-specific, but is ignored on other o/s's. - */ -static void -pci_parse_name_usage(char *aopt) -{ - printf("Invalid PCI slot name field \"%s\"\n", aopt); -} - -void -pci_parse_name(char *opt) -{ - char csnum[4]; - char *namestr; - char *slotend, *funcend, *funcstart; - char prefix, suffix; - int i; - int pslot; - int snum, fnum; - - pslot = -1; - prefix = suffix = 0; - - slotend = strchr(opt, ':'); - if (slotend != NULL) { - funcstart = slotend + 1; - funcend = strchr(funcstart, ','); - } else { - slotend = strchr(opt, ','); - funcstart = funcend = NULL; - } - - /* - * A comma must be present, and can't be the first character - * or no slot would be present. Also, the slot number can't be - * more than 2 characters. - */ - if (slotend == NULL || slotend == opt || (slotend - opt > 2)) { - pci_parse_name_usage(opt); - return; - } - - for (i = 0; i < (slotend - opt); i++) { - csnum[i] = opt[i]; - } - csnum[i] = '\0'; - - snum = atoi(csnum); - if (snum < 0 || snum >= MAXSLOTS) { - pci_parse_name_usage(opt); - return; - } - - /* - * Parse the function number (if provided) - * - * A comma must be present and can't be the first character. - * The function cannot be greater than a single character and - * must be between '0' and '7' inclusive. - */ - if (funcstart != NULL) { - if (funcend == NULL || funcend != funcstart + 1 || - *funcstart < '0' || *funcstart > '7') { - pci_parse_name_usage(opt); - return; - } - fnum = *funcstart - '0'; - } else { - fnum = 0; - } - - namestr = funcend ? funcend + 1 : slotend + 1; - - if (strlen(namestr) > 3) { - pci_parse_name_usage(opt); - return; - } - - if (isalpha(*namestr)) { - prefix = *namestr++; - } - - if (!isdigit(*namestr)) { - pci_parse_name_usage(opt); - } else { - pslot = *namestr++ - '0'; - if (isnumber(*namestr)) { - pslot = 10*pslot + *namestr++ - '0'; - - } - if (isalpha(*namestr) && *(namestr + 1) == 0) { - suffix = *namestr; - pci_slotinfo[snum][fnum].si_titled = 1; - pci_slotinfo[snum][fnum].si_pslot = pslot; - pci_slotinfo[snum][fnum].si_prefix = prefix; - pci_slotinfo[snum][fnum].si_suffix = suffix; - } else { - pci_parse_name_usage(opt); - } - } -} - -static void -pci_add_mptable_name(struct slotinfo *si) -{ - struct mptable_pci_slotinfo *ms; - - /* - * If naming information has been supplied for this slot, populate - * the next available mptable OEM entry - */ - if (si->si_titled) { - ms = &pci_devnames.md_slotinfo[devname_elems]; - - ms->mds_type = MPT_HDR_NAME; - ms->mds_phys_slot = si->si_pslot; - ms->mds_bus = si->si_devi->pi_bus; - ms->mds_slot = si->si_devi->pi_slot; - ms->mds_func = si->si_devi->pi_func; - ms->mds_vid = pci_get_cfgdata16(si->si_devi, PCIR_VENDOR); - ms->mds_did = pci_get_cfgdata16(si->si_devi, PCIR_DEVICE); - ms->mds_suffix[0] = si->si_suffix; - ms->mds_prefix[0] = si->si_prefix; - - devname_elems++; - } -} - -static void -pci_finish_mptable_names(void) -{ - int size; - - if (devname_elems) { - pci_devnames.md_hdrtype = MPT_HDR_BASE; - pci_devnames.md_entries = devname_elems; - pci_devnames.md_cksum = 0; /* XXX */ - pci_devnames.md_sig = MPT_NTAP_SIG; - - size = (uintptr_t)&pci_devnames.md_slotinfo[devname_elems] - - (uintptr_t)&pci_devnames; - - fbsdrun_add_oemtbl(&pci_devnames, size); - } -} - static int pci_emul_io_handler(struct vmctx *ctx, int vcpu, int in, int port, int bytes, uint32_t *eax, void *arg) @@ -835,12 +637,10 @@ init_pci(struct vmctx *ctx) if (pde != NULL) { pci_emul_init(ctx, pde, slot, func, si->si_param); - pci_add_mptable_name(si); } } } } - pci_finish_mptable_names(); /* * Allow ISA IRQs 5,10,11,12, and 15 to be available for diff --git a/usr.sbin/bhyve/pci_emul.h b/usr.sbin/bhyve/pci_emul.h index 79b86d1..e924475 100644 --- a/usr.sbin/bhyve/pci_emul.h +++ b/usr.sbin/bhyve/pci_emul.h @@ -168,7 +168,6 @@ int pci_lintr_request(struct pci_devinst *pi, int ivec); int pci_msi_enabled(struct pci_devinst *pi); int pci_msix_enabled(struct pci_devinst *pi); int pci_msi_msgnum(struct pci_devinst *pi); -void pci_parse_name(char *opt); void pci_parse_slot(char *opt, int legacy); void pci_populate_msicap(struct msicap *cap, int msgs, int nextptr); |