summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
Diffstat (limited to 'sys')
-rw-r--r--sys/amd64/acpica/acpi_wakeup.c4
-rw-r--r--sys/amd64/acpica/madt.c2
-rw-r--r--sys/amd64/amd64/amd64_mem.c38
-rw-r--r--sys/amd64/amd64/apic_vector.S2
-rw-r--r--sys/amd64/amd64/genassym.c2
-rw-r--r--sys/amd64/amd64/intr_machdep.c2
-rw-r--r--sys/amd64/amd64/machdep.c2
-rw-r--r--sys/amd64/amd64/mp_machdep.c4
-rw-r--r--sys/amd64/amd64/mp_watchdog.c2
-rw-r--r--sys/amd64/amd64/mptable.c1042
-rw-r--r--sys/amd64/amd64/nexus.c704
-rw-r--r--sys/amd64/amd64/pmap.c62
-rw-r--r--sys/amd64/amd64/trap.c2
-rw-r--r--sys/amd64/include/pmap.h1
-rw-r--r--sys/arm/arm/elf_trampoline.c6
-rw-r--r--sys/boot/ofw/common/main.c46
-rw-r--r--sys/boot/ofw/libofw/ofw_memory.c14
-rw-r--r--sys/boot/ofw/libofw/ofw_net.c3
-rw-r--r--sys/boot/ofw/libofw/openfirm.c9
-rw-r--r--sys/boot/sparc64/loader/main.c8
-rw-r--r--sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu.c10
-rw-r--r--sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c20
-rw-r--r--sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zil.c4
-rw-r--r--sys/conf/files.amd648
-rw-r--r--sys/conf/files.i3868
-rw-r--r--sys/conf/files.pc988
-rw-r--r--sys/conf/files.powerpc1
-rw-r--r--sys/conf/kern.post.mk7
-rw-r--r--sys/conf/kmod.mk7
-rw-r--r--sys/conf/options.amd641
-rw-r--r--sys/conf/options.powerpc4
-rw-r--r--sys/dev/acpica/acpi.c106
-rw-r--r--sys/dev/agp/agp.c34
-rw-r--r--sys/dev/agp/agp_apple.c302
-rw-r--r--sys/dev/alc/if_alc.c2
-rw-r--r--sys/dev/bge/if_bge.c317
-rw-r--r--sys/dev/bge/if_bgereg.h42
-rw-r--r--sys/dev/e1000/e1000_82571.c7
-rw-r--r--sys/dev/e1000/if_em.c368
-rw-r--r--sys/dev/e1000/if_em.h27
-rw-r--r--sys/dev/e1000/if_lem.c228
-rw-r--r--sys/dev/e1000/if_lem.h18
-rw-r--r--sys/dev/mii/brgphy.c5
-rw-r--r--sys/dev/mii/e1000phy.c2
-rw-r--r--sys/dev/mii/mii_physubr.c85
-rw-r--r--sys/dev/mii/miidevs2
-rw-r--r--sys/dev/mii/miivar.h2
-rw-r--r--sys/dev/usb/usb_device.c50
-rw-r--r--sys/dev/usb/usb_hub.c6
-rw-r--r--sys/dev/usb/usbdi.h3
-rw-r--r--sys/dev/xen/blkback/blkback.c7
-rw-r--r--sys/fs/nfs/nfsclstate.h1
-rw-r--r--sys/fs/nfsclient/nfs_clnode.c9
-rw-r--r--sys/fs/nfsclient/nfs_clstate.c45
-rw-r--r--sys/fs/nfsclient/nfs_clvnops.c86
-rw-r--r--sys/i386/acpica/acpi_wakeup.c2
-rw-r--r--sys/i386/acpica/madt.c2
-rw-r--r--sys/i386/i386/apic_vector.s2
-rw-r--r--sys/i386/i386/dump_machdep.c363
-rw-r--r--sys/i386/i386/genassym.c2
-rw-r--r--sys/i386/i386/intr_machdep.c2
-rw-r--r--sys/i386/i386/machdep.c2
-rw-r--r--sys/i386/i386/mp_machdep.c4
-rw-r--r--sys/i386/i386/mp_watchdog.c2
-rw-r--r--sys/i386/i386/mpboot.s2
-rw-r--r--sys/i386/i386/mptable_pci.c177
-rw-r--r--sys/i386/i386/trap.c2
-rw-r--r--sys/i386/include/apicreg.h445
-rw-r--r--sys/i386/include/mca.h56
-rw-r--r--sys/i386/xen/mp_machdep.c2
-rw-r--r--sys/i386/xen/mptable.c2
-rw-r--r--sys/kern/init_main.c12
-rw-r--r--sys/kern/kern_cpuset.c4
-rw-r--r--sys/kern/kern_timeout.c3
-rw-r--r--sys/kern/sched_ule.c2
-rw-r--r--sys/kern/subr_acl_nfs4.c2
-rw-r--r--sys/kern/vfs_cache.c2
-rw-r--r--sys/modules/Makefile1
-rw-r--r--sys/modules/agp/Makefile5
-rw-r--r--sys/net/bpf.h137
-rw-r--r--sys/netinet/if_ether.c4
-rw-r--r--sys/netipsec/ipsec.c5
-rw-r--r--sys/nfsclient/nfs_vfsops.c8
-rw-r--r--sys/pc98/include/apicreg.h6
-rw-r--r--sys/pc98/include/bus.h4
-rw-r--r--sys/pc98/include/mca.h6
-rw-r--r--sys/pc98/pc98/busiosubr.c16
-rw-r--r--sys/pc98/pc98/machdep.c2
-rw-r--r--sys/powerpc/aim/copyinout.c35
-rw-r--r--sys/powerpc/aim/mmu_oea.c17
-rw-r--r--sys/powerpc/aim/mmu_oea64.c15
-rw-r--r--sys/powerpc/aim/slb.c14
-rw-r--r--sys/powerpc/aim/swtch32.S2
-rw-r--r--sys/powerpc/aim/swtch64.S20
-rw-r--r--sys/powerpc/aim/trap.c10
-rw-r--r--sys/powerpc/aim/trap_subr32.S11
-rw-r--r--sys/powerpc/aim/trap_subr64.S2
-rw-r--r--sys/powerpc/aim/vm_machdep.c1
-rw-r--r--sys/powerpc/conf/GENERIC1
-rw-r--r--sys/powerpc/conf/GENERIC641
-rw-r--r--sys/powerpc/conf/NOTES1
-rw-r--r--sys/powerpc/include/pcb.h1
-rw-r--r--sys/powerpc/include/slb.h7
-rw-r--r--sys/powerpc/include/sr.h4
-rw-r--r--sys/powerpc/powermac/cpcht.c23
-rw-r--r--sys/powerpc/powerpc/exec_machdep.c1
-rw-r--r--sys/powerpc/powerpc/genassym.c5
-rw-r--r--sys/sparc64/sparc64/pmap.c11
-rw-r--r--sys/sparc64/sparc64/tick.c216
-rw-r--r--sys/ufs/ufs/ufs_dirhash.c6
-rw-r--r--sys/vm/vm_phys.c4
-rw-r--r--sys/vm/vm_reserv.c2
-rw-r--r--sys/x86/include/apicreg.h (renamed from sys/amd64/include/apicreg.h)6
-rw-r--r--sys/x86/include/mca.h (renamed from sys/amd64/include/mca.h)6
-rw-r--r--sys/x86/x86/dump_machdep.c (renamed from sys/amd64/amd64/dump_machdep.c)18
-rw-r--r--sys/x86/x86/io_apic.c2
-rw-r--r--sys/x86/x86/local_apic.c4
-rw-r--r--sys/x86/x86/mca.c2
-rw-r--r--sys/x86/x86/mptable.c (renamed from sys/i386/i386/mptable.c)6
-rw-r--r--sys/x86/x86/mptable_pci.c (renamed from sys/amd64/amd64/mptable_pci.c)0
-rw-r--r--sys/x86/x86/msi.c2
-rw-r--r--sys/x86/x86/nexus.c (renamed from sys/i386/i386/nexus.c)57
122 files changed, 2002 insertions, 3584 deletions
diff --git a/sys/amd64/acpica/acpi_wakeup.c b/sys/amd64/acpica/acpi_wakeup.c
index 9afb36c..c25d802 100644
--- a/sys/amd64/acpica/acpi_wakeup.c
+++ b/sys/amd64/acpica/acpi_wakeup.c
@@ -41,13 +41,13 @@ __FBSDID("$FreeBSD$");
#include <vm/pmap.h>
#include <machine/intr_machdep.h>
-#include <machine/mca.h>
+#include <x86/mca.h>
#include <machine/pcb.h>
#include <machine/pmap.h>
#include <machine/specialreg.h>
#ifdef SMP
-#include <machine/apicreg.h>
+#include <x86/apicreg.h>
#include <machine/smp.h>
#include <machine/vmparam.h>
#endif
diff --git a/sys/amd64/acpica/madt.c b/sys/amd64/acpica/madt.c
index 90ffd64..84bc831 100644
--- a/sys/amd64/acpica/madt.c
+++ b/sys/amd64/acpica/madt.c
@@ -39,7 +39,7 @@ __FBSDID("$FreeBSD$");
#include <vm/vm.h>
#include <vm/pmap.h>
-#include <machine/apicreg.h>
+#include <x86/apicreg.h>
#include <machine/intr_machdep.h>
#include <machine/apicvar.h>
diff --git a/sys/amd64/amd64/amd64_mem.c b/sys/amd64/amd64/amd64_mem.c
index e50d3e7..0f7bc25 100644
--- a/sys/amd64/amd64/amd64_mem.c
+++ b/sys/amd64/amd64/amd64_mem.c
@@ -35,6 +35,10 @@ __FBSDID("$FreeBSD$");
#include <sys/smp.h>
#include <sys/sysctl.h>
+#include <vm/vm.h>
+#include <vm/vm_param.h>
+#include <vm/pmap.h>
+
#include <machine/cputypes.h>
#include <machine/md_var.h>
#include <machine/specialreg.h>
@@ -527,9 +531,9 @@ static int
amd64_mrset(struct mem_range_softc *sc, struct mem_range_desc *mrd, int *arg)
{
struct mem_range_desc *targ;
- int error = 0;
+ int error, i;
- switch(*arg) {
+ switch (*arg) {
case MEMRANGE_SET_UPDATE:
/*
* Make sure that what's being asked for is even
@@ -568,6 +572,21 @@ amd64_mrset(struct mem_range_softc *sc, struct mem_range_desc *mrd, int *arg)
return (EOPNOTSUPP);
}
+ /*
+ * Ensure that the direct map region does not contain any mappings
+ * that span MTRRs of different types. However, the fixed MTRRs can
+ * be ignored, because a large page mapping the first 1 MB of physical
+ * memory is a special case that the processor handles. The entire
+ * TLB will be invalidated by amd64_mrstore(), so pmap_demote_DMAP()
+ * needn't do it.
+ */
+ i = (sc->mr_cap & MR686_FIXMTRR) ? MTRR_N64K + MTRR_N16K + MTRR_N4K : 0;
+ mrd = sc->mr_desc + i;
+ for (; i < sc->mr_ndesc; i++, mrd++) {
+ if (mrd->mr_flags & MDF_ACTIVE)
+ pmap_demote_DMAP(mrd->mr_base, mrd->mr_len, FALSE);
+ }
+
/* Update the hardware. */
amd64_mrstore(sc);
@@ -657,6 +676,21 @@ amd64_mrinit(struct mem_range_softc *sc)
if (mrd->mr_flags & MDF_ACTIVE)
mrd->mr_flags |= MDF_FIRMWARE;
}
+
+ /*
+ * Ensure that the direct map region does not contain any mappings
+ * that span MTRRs of different types. However, the fixed MTRRs can
+ * be ignored, because a large page mapping the first 1 MB of physical
+ * memory is a special case that the processor handles. Invalidate
+ * any old TLB entries that might hold inconsistent memory type
+ * information.
+ */
+ i = (sc->mr_cap & MR686_FIXMTRR) ? MTRR_N64K + MTRR_N16K + MTRR_N4K : 0;
+ mrd = sc->mr_desc + i;
+ for (; i < sc->mr_ndesc; i++, mrd++) {
+ if (mrd->mr_flags & MDF_ACTIVE)
+ pmap_demote_DMAP(mrd->mr_base, mrd->mr_len, TRUE);
+ }
}
/*
diff --git a/sys/amd64/amd64/apic_vector.S b/sys/amd64/amd64/apic_vector.S
index 73a0eab..e4c4ddf 100644
--- a/sys/amd64/amd64/apic_vector.S
+++ b/sys/amd64/amd64/apic_vector.S
@@ -39,7 +39,7 @@
#include "opt_smp.h"
#include <machine/asmacros.h>
-#include <machine/apicreg.h>
+#include <x86/apicreg.h>
#include "assym.s"
diff --git a/sys/amd64/amd64/genassym.c b/sys/amd64/amd64/genassym.c
index d6ebec5..613bce5 100644
--- a/sys/amd64/amd64/genassym.c
+++ b/sys/amd64/amd64/genassym.c
@@ -66,7 +66,7 @@ __FBSDID("$FreeBSD$");
#include <nfs/nfsproto.h>
#include <nfsclient/nfs.h>
#include <nfsclient/nfsdiskless.h>
-#include <machine/apicreg.h>
+#include <x86/apicreg.h>
#include <machine/cpu.h>
#include <machine/pcb.h>
#include <machine/sigframe.h>
diff --git a/sys/amd64/amd64/intr_machdep.c b/sys/amd64/amd64/intr_machdep.c
index 3cdc69f..4edef81 100644
--- a/sys/amd64/amd64/intr_machdep.c
+++ b/sys/amd64/amd64/intr_machdep.c
@@ -458,7 +458,7 @@ intr_next_cpu(void)
/* Leave all interrupts on the BSP during boot. */
if (!assign_cpu)
- return (cpu_apic_ids[0]);
+ return (PCPU_GET(apic_id));
mtx_lock_spin(&icu_lock);
apic_id = cpu_apic_ids[current_cpu];
diff --git a/sys/amd64/amd64/machdep.c b/sys/amd64/amd64/machdep.c
index 61a2cf8..eba788f 100644
--- a/sys/amd64/amd64/machdep.c
+++ b/sys/amd64/amd64/machdep.c
@@ -112,7 +112,7 @@ __FBSDID("$FreeBSD$");
#include <machine/cpu.h>
#include <machine/cputypes.h>
#include <machine/intr_machdep.h>
-#include <machine/mca.h>
+#include <x86/mca.h>
#include <machine/md_var.h>
#include <machine/metadata.h>
#include <machine/pc/bios.h>
diff --git a/sys/amd64/amd64/mp_machdep.c b/sys/amd64/amd64/mp_machdep.c
index c509b67..3868428 100644
--- a/sys/amd64/amd64/mp_machdep.c
+++ b/sys/amd64/amd64/mp_machdep.c
@@ -57,11 +57,11 @@ __FBSDID("$FreeBSD$");
#include <vm/vm_kern.h>
#include <vm/vm_extern.h>
-#include <machine/apicreg.h>
+#include <x86/apicreg.h>
#include <machine/clock.h>
#include <machine/cputypes.h>
#include <machine/cpufunc.h>
-#include <machine/mca.h>
+#include <x86/mca.h>
#include <machine/md_var.h>
#include <machine/mp_watchdog.h>
#include <machine/pcb.h>
diff --git a/sys/amd64/amd64/mp_watchdog.c b/sys/amd64/amd64/mp_watchdog.c
index 1803270..5cbd649 100644
--- a/sys/amd64/amd64/mp_watchdog.c
+++ b/sys/amd64/amd64/mp_watchdog.c
@@ -44,7 +44,7 @@
#include <sys/systm.h>
#include <machine/smp.h>
-#include <machine/apicreg.h>
+#include <x86/apicreg.h>
#include <machine/apicvar.h>
#include <machine/mp_watchdog.h>
diff --git a/sys/amd64/amd64/mptable.c b/sys/amd64/amd64/mptable.c
deleted file mode 100644
index 01cb093..0000000
--- a/sys/amd64/amd64/mptable.c
+++ /dev/null
@@ -1,1042 +0,0 @@
-/*-
- * Copyright (c) 2003 John Baldwin <jhb@FreeBSD.org>
- * Copyright (c) 1996, by Steve Passe
- * 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. The name of the developer may NOT be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``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 THE AUTHOR 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.
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/bus.h>
-#include <sys/kernel.h>
-#include <sys/malloc.h>
-
-#include <vm/vm.h>
-#include <vm/vm_param.h>
-#include <vm/pmap.h>
-
-#include <machine/apicreg.h>
-#include <machine/frame.h>
-#include <machine/intr_machdep.h>
-#include <machine/apicvar.h>
-#include <machine/md_var.h>
-#include <machine/mptable.h>
-#include <machine/specialreg.h>
-
-#include <dev/pci/pcivar.h>
-
-/* string defined by the Intel MP Spec as identifying the MP table */
-#define MP_SIG 0x5f504d5f /* _MP_ */
-
-#define MAX_LAPIC_ID 63 /* Max local APIC ID for HTT fixup */
-
-#define BIOS_BASE (0xf0000)
-#define BIOS_SIZE (0x10000)
-#define BIOS_COUNT (BIOS_SIZE/4)
-
-typedef void mptable_entry_handler(u_char *entry, void *arg);
-
-static basetable_entry basetable_entry_types[] =
-{
- {0, 20, "Processor"},
- {1, 8, "Bus"},
- {2, 8, "I/O APIC"},
- {3, 8, "I/O INT"},
- {4, 8, "Local INT"}
-};
-
-typedef struct BUSDATA {
- u_char bus_id;
- enum busTypes bus_type;
-} bus_datum;
-
-typedef struct INTDATA {
- u_char int_type;
- u_short int_flags;
- u_char src_bus_id;
- u_char src_bus_irq;
- u_char dst_apic_id;
- u_char dst_apic_int;
- u_char int_vector;
-} io_int, local_int;
-
-typedef struct BUSTYPENAME {
- u_char type;
- char name[7];
-} bus_type_name;
-
-/* From MP spec v1.4, table 4-8. */
-static bus_type_name bus_type_table[] =
-{
- {UNKNOWN_BUSTYPE, "CBUS "},
- {UNKNOWN_BUSTYPE, "CBUSII"},
- {EISA, "EISA "},
- {UNKNOWN_BUSTYPE, "FUTURE"},
- {UNKNOWN_BUSTYPE, "INTERN"},
- {ISA, "ISA "},
- {UNKNOWN_BUSTYPE, "MBI "},
- {UNKNOWN_BUSTYPE, "MBII "},
- {MCA, "MCA "},
- {UNKNOWN_BUSTYPE, "MPI "},
- {UNKNOWN_BUSTYPE, "MPSA "},
- {UNKNOWN_BUSTYPE, "NUBUS "},
- {PCI, "PCI "},
- {UNKNOWN_BUSTYPE, "PCMCIA"},
- {UNKNOWN_BUSTYPE, "TC "},
- {UNKNOWN_BUSTYPE, "VL "},
- {UNKNOWN_BUSTYPE, "VME "},
- {UNKNOWN_BUSTYPE, "XPRESS"}
-};
-
-/* From MP spec v1.4, table 5-1. */
-static int default_data[7][5] =
-{
-/* nbus, id0, type0, id1, type1 */
- {1, 0, ISA, 255, NOBUS},
- {1, 0, EISA, 255, NOBUS},
- {1, 0, EISA, 255, NOBUS},
- {1, 0, MCA, 255, NOBUS},
- {2, 0, ISA, 1, PCI},
- {2, 0, EISA, 1, PCI},
- {2, 0, MCA, 1, PCI}
-};
-
-struct pci_probe_table_args {
- u_char bus;
- u_char found;
-};
-
-struct pci_route_interrupt_args {
- u_char bus; /* Source bus. */
- u_char irq; /* Source slot:pin. */
- int vector; /* Return value. */
-};
-
-static mpfps_t mpfps;
-static mpcth_t mpct;
-static void *ioapics[MAX_APIC_ID + 1];
-static bus_datum *busses;
-static int mptable_nioapics, mptable_nbusses, mptable_maxbusid;
-static int pci0 = -1;
-
-static MALLOC_DEFINE(M_MPTABLE, "mptable", "MP Table Items");
-
-static enum intr_polarity conforming_polarity(u_char src_bus,
- u_char src_bus_irq);
-static enum intr_trigger conforming_trigger(u_char src_bus, u_char src_bus_irq);
-static enum intr_polarity intentry_polarity(int_entry_ptr intr);
-static enum intr_trigger intentry_trigger(int_entry_ptr intr);
-static int lookup_bus_type(char *name);
-static void mptable_count_items(void);
-static void mptable_count_items_handler(u_char *entry, void *arg);
-#ifdef MPTABLE_FORCE_HTT
-static void mptable_hyperthread_fixup(u_long id_mask);
-#endif
-static void mptable_parse_apics_and_busses(void);
-static void mptable_parse_apics_and_busses_handler(u_char *entry,
- void *arg);
-static void mptable_parse_default_config_ints(void);
-static void mptable_parse_ints(void);
-static void mptable_parse_ints_handler(u_char *entry, void *arg);
-static void mptable_parse_io_int(int_entry_ptr intr);
-static void mptable_parse_local_int(int_entry_ptr intr);
-static void mptable_pci_probe_table_handler(u_char *entry, void *arg);
-static void mptable_pci_route_interrupt_handler(u_char *entry, void *arg);
-static void mptable_pci_setup(void);
-static int mptable_probe(void);
-static int mptable_probe_cpus(void);
-static void mptable_probe_cpus_handler(u_char *entry, void *arg __unused);
-static void mptable_register(void *dummy);
-static int mptable_setup_local(void);
-static int mptable_setup_io(void);
-static void mptable_walk_table(mptable_entry_handler *handler, void *arg);
-static int search_for_sig(u_int32_t target, int count);
-
-static struct apic_enumerator mptable_enumerator = {
- "MPTable",
- mptable_probe,
- mptable_probe_cpus,
- mptable_setup_local,
- mptable_setup_io
-};
-
-/*
- * look for the MP spec signature
- */
-
-static int
-search_for_sig(u_int32_t target, int count)
-{
- int x;
- u_int32_t *addr = (u_int32_t *) (KERNBASE + target);
-
- for (x = 0; x < count; x += 4)
- if (addr[x] == MP_SIG)
- /* make array index a byte index */
- return (target + (x * sizeof(u_int32_t)));
- return (-1);
-}
-
-static int
-lookup_bus_type(char *name)
-{
- int x;
-
- for (x = 0; x < MAX_BUSTYPE; ++x)
- if (strncmp(bus_type_table[x].name, name, 6) == 0)
- return (bus_type_table[x].type);
-
- return (UNKNOWN_BUSTYPE);
-}
-
-/*
- * Look for an Intel MP spec table (ie, SMP capable hardware).
- */
-static int
-mptable_probe(void)
-{
- int x;
- u_int32_t segment;
- u_int32_t target;
-
- /* see if EBDA exists */
- segment = (u_int32_t) *(u_short *)(KERNBASE + 0x40e);
- if (segment != 0) {
- /* search first 1K of EBDA */
- target = (u_int32_t) (segment << 4);
- if ((x = search_for_sig(target, 1024 / 4)) >= 0)
- goto found;
- } else {
- /* last 1K of base memory, effective 'top of base' passed in */
- target = (u_int32_t) ((basemem * 1024) - 0x400);
- if ((x = search_for_sig(target, 1024 / 4)) >= 0)
- goto found;
- }
-
- /* search the BIOS */
- target = (u_int32_t) BIOS_BASE;
- if ((x = search_for_sig(target, BIOS_COUNT)) >= 0)
- goto found;
-
- /* nothing found */
- return (ENXIO);
-
-found:
- mpfps = (mpfps_t)(KERNBASE + x);
-
- /* Map in the configuration table if it exists. */
- if (mpfps->config_type != 0) {
- if (bootverbose)
- printf(
- "MP Table version 1.%d found using Default Configuration %d\n",
- mpfps->spec_rev, mpfps->config_type);
- if (mpfps->config_type != 5 && mpfps->config_type != 6) {
- printf(
- "MP Table Default Configuration %d is unsupported\n",
- mpfps->config_type);
- return (ENXIO);
- }
- mpct = NULL;
- } else {
- if ((uintptr_t)mpfps->pap >= 1024 * 1024) {
- printf("%s: Unable to map MP Configuration Table\n",
- __func__);
- return (ENXIO);
- }
- mpct = (mpcth_t)(KERNBASE + (uintptr_t)mpfps->pap);
- if (mpct->base_table_length + (uintptr_t)mpfps->pap >=
- 1024 * 1024) {
- printf("%s: Unable to map end of MP Config Table\n",
- __func__);
- return (ENXIO);
- }
- if (mpct->signature[0] != 'P' || mpct->signature[1] != 'C' ||
- mpct->signature[2] != 'M' || mpct->signature[3] != 'P') {
- printf("%s: MP Config Table has bad signature: %c%c%c%c\n",
- __func__, mpct->signature[0], mpct->signature[1],
- mpct->signature[2], mpct->signature[3]);
- return (ENXIO);
- }
- if (bootverbose)
- printf(
- "MP Configuration Table version 1.%d found at %p\n",
- mpct->spec_rev, mpct);
- }
-
- return (-100);
-}
-
-/*
- * Run through the MP table enumerating CPUs.
- */
-static int
-mptable_probe_cpus(void)
-{
- u_long cpu_mask;
-
- /* Is this a pre-defined config? */
- if (mpfps->config_type != 0) {
- lapic_create(0, 1);
- lapic_create(1, 0);
- } else {
- cpu_mask = 0;
- mptable_walk_table(mptable_probe_cpus_handler, &cpu_mask);
-#ifdef MPTABLE_FORCE_HTT
- mptable_hyperthread_fixup(cpu_mask);
-#endif
- }
- return (0);
-}
-
-/*
- * Initialize the local APIC on the BSP.
- */
-static int
-mptable_setup_local(void)
-{
- vm_paddr_t addr;
-
- /* Is this a pre-defined config? */
- printf("MPTable: <");
- if (mpfps->config_type != 0) {
- addr = DEFAULT_APIC_BASE;
- printf("Default Configuration %d", mpfps->config_type);
- } else {
- addr = mpct->apic_address;
- printf("%.*s %.*s", (int)sizeof(mpct->oem_id), mpct->oem_id,
- (int)sizeof(mpct->product_id), mpct->product_id);
- }
- printf(">\n");
- lapic_init(addr);
- return (0);
-}
-
-/*
- * Run through the MP table enumerating I/O APICs.
- */
-static int
-mptable_setup_io(void)
-{
- int i;
- u_char byte;
-
- /* First, we count individual items and allocate arrays. */
- mptable_count_items();
- busses = malloc((mptable_maxbusid + 1) * sizeof(bus_datum), M_MPTABLE,
- M_WAITOK);
- for (i = 0; i <= mptable_maxbusid; i++)
- busses[i].bus_type = NOBUS;
-
- /* Second, we run through adding I/O APIC's and busses. */
- mptable_parse_apics_and_busses();
-
- /* Third, we run through the table tweaking interrupt sources. */
- mptable_parse_ints();
-
- /* Fourth, we register all the I/O APIC's. */
- for (i = 0; i <= MAX_APIC_ID; i++)
- if (ioapics[i] != NULL)
- ioapic_register(ioapics[i]);
-
- /* Fifth, we setup data structures to handle PCI interrupt routing. */
- mptable_pci_setup();
-
- /* Finally, we throw the switch to enable the I/O APIC's. */
- if (mpfps->mpfb2 & MPFB2_IMCR_PRESENT) {
- outb(0x22, 0x70); /* select IMCR */
- byte = inb(0x23); /* current contents */
- byte |= 0x01; /* mask external INTR */
- outb(0x23, byte); /* disconnect 8259s/NMI */
- }
-
- return (0);
-}
-
-static void
-mptable_register(void *dummy __unused)
-{
-
- apic_register_enumerator(&mptable_enumerator);
-}
-SYSINIT(mptable_register, SI_SUB_TUNABLES - 1, SI_ORDER_FIRST,
- mptable_register, NULL);
-
-/*
- * Call the handler routine for each entry in the MP config table.
- */
-static void
-mptable_walk_table(mptable_entry_handler *handler, void *arg)
-{
- u_int i;
- u_char *entry;
-
- entry = (u_char *)(mpct + 1);
- for (i = 0; i < mpct->entry_count; i++) {
- switch (*entry) {
- case MPCT_ENTRY_PROCESSOR:
- case MPCT_ENTRY_IOAPIC:
- case MPCT_ENTRY_BUS:
- case MPCT_ENTRY_INT:
- case MPCT_ENTRY_LOCAL_INT:
- break;
- default:
- panic("%s: Unknown MP Config Entry %d\n", __func__,
- (int)*entry);
- }
- handler(entry, arg);
- entry += basetable_entry_types[*entry].length;
- }
-}
-
-static void
-mptable_probe_cpus_handler(u_char *entry, void *arg)
-{
- proc_entry_ptr proc;
- u_long *cpu_mask;
-
- switch (*entry) {
- case MPCT_ENTRY_PROCESSOR:
- proc = (proc_entry_ptr)entry;
- if (proc->cpu_flags & PROCENTRY_FLAG_EN) {
- lapic_create(proc->apic_id, proc->cpu_flags &
- PROCENTRY_FLAG_BP);
- if (proc->apic_id < MAX_LAPIC_ID) {
- cpu_mask = (u_long *)arg;
- *cpu_mask |= (1ul << proc->apic_id);
- }
- }
- break;
- }
-}
-
-static void
-mptable_count_items_handler(u_char *entry, void *arg __unused)
-{
- io_apic_entry_ptr apic;
- bus_entry_ptr bus;
-
- switch (*entry) {
- case MPCT_ENTRY_BUS:
- bus = (bus_entry_ptr)entry;
- mptable_nbusses++;
- if (bus->bus_id > mptable_maxbusid)
- mptable_maxbusid = bus->bus_id;
- break;
- case MPCT_ENTRY_IOAPIC:
- apic = (io_apic_entry_ptr)entry;
- if (apic->apic_flags & IOAPICENTRY_FLAG_EN)
- mptable_nioapics++;
- break;
- }
-}
-
-/*
- * Count items in the table.
- */
-static void
-mptable_count_items(void)
-{
-
- /* Is this a pre-defined config? */
- if (mpfps->config_type != 0) {
- mptable_nioapics = 1;
- switch (mpfps->config_type) {
- case 1:
- case 2:
- case 3:
- case 4:
- mptable_nbusses = 1;
- break;
- case 5:
- case 6:
- case 7:
- mptable_nbusses = 2;
- break;
- default:
- panic("Unknown pre-defined MP Table config type %d",
- mpfps->config_type);
- }
- mptable_maxbusid = mptable_nbusses - 1;
- } else
- mptable_walk_table(mptable_count_items_handler, NULL);
-}
-
-/*
- * Add a bus or I/O APIC from an entry in the table.
- */
-static void
-mptable_parse_apics_and_busses_handler(u_char *entry, void *arg __unused)
-{
- io_apic_entry_ptr apic;
- bus_entry_ptr bus;
- enum busTypes bus_type;
- int i;
-
-
- switch (*entry) {
- case MPCT_ENTRY_BUS:
- bus = (bus_entry_ptr)entry;
- bus_type = lookup_bus_type(bus->bus_type);
- if (bus_type == UNKNOWN_BUSTYPE) {
- printf("MPTable: Unknown bus %d type \"", bus->bus_id);
- for (i = 0; i < 6; i++)
- printf("%c", bus->bus_type[i]);
- printf("\"\n");
- }
- busses[bus->bus_id].bus_id = bus->bus_id;
- busses[bus->bus_id].bus_type = bus_type;
- break;
- case MPCT_ENTRY_IOAPIC:
- apic = (io_apic_entry_ptr)entry;
- if (!(apic->apic_flags & IOAPICENTRY_FLAG_EN))
- break;
- if (apic->apic_id > MAX_APIC_ID)
- panic("%s: I/O APIC ID %d too high", __func__,
- apic->apic_id);
- if (ioapics[apic->apic_id] != NULL)
- panic("%s: Double APIC ID %d", __func__,
- apic->apic_id);
- ioapics[apic->apic_id] = ioapic_create(apic->apic_address,
- apic->apic_id, -1);
- break;
- default:
- break;
- }
-}
-
-/*
- * Enumerate I/O APIC's and busses.
- */
-static void
-mptable_parse_apics_and_busses(void)
-{
-
- /* Is this a pre-defined config? */
- if (mpfps->config_type != 0) {
- ioapics[2] = ioapic_create(DEFAULT_IO_APIC_BASE, 2, 0);
- busses[0].bus_id = 0;
- busses[0].bus_type = default_data[mpfps->config_type - 1][2];
- if (mptable_nbusses > 1) {
- busses[1].bus_id = 1;
- busses[1].bus_type =
- default_data[mpfps->config_type - 1][4];
- }
- } else
- mptable_walk_table(mptable_parse_apics_and_busses_handler,
- NULL);
-}
-
-/*
- * Determine conforming polarity for a given bus type.
- */
-static enum intr_polarity
-conforming_polarity(u_char src_bus, u_char src_bus_irq)
-{
-
- KASSERT(src_bus <= mptable_maxbusid, ("bus id %d too large", src_bus));
- switch (busses[src_bus].bus_type) {
- case ISA:
- case EISA:
- return (INTR_POLARITY_HIGH);
- case PCI:
- return (INTR_POLARITY_LOW);
- default:
- panic("%s: unknown bus type %d", __func__,
- busses[src_bus].bus_type);
- }
-}
-
-/*
- * Determine conforming trigger for a given bus type.
- */
-static enum intr_trigger
-conforming_trigger(u_char src_bus, u_char src_bus_irq)
-{
-
- KASSERT(src_bus <= mptable_maxbusid, ("bus id %d too large", src_bus));
- switch (busses[src_bus].bus_type) {
- case ISA:
- if (elcr_found)
- return (elcr_read_trigger(src_bus_irq));
- else
- return (INTR_TRIGGER_EDGE);
- case PCI:
- return (INTR_TRIGGER_LEVEL);
- case EISA:
- KASSERT(src_bus_irq < 16, ("Invalid EISA IRQ %d", src_bus_irq));
- KASSERT(elcr_found, ("Missing ELCR"));
- return (elcr_read_trigger(src_bus_irq));
- default:
- panic("%s: unknown bus type %d", __func__,
- busses[src_bus].bus_type);
- }
-}
-
-static enum intr_polarity
-intentry_polarity(int_entry_ptr intr)
-{
-
- switch (intr->int_flags & INTENTRY_FLAGS_POLARITY) {
- case INTENTRY_FLAGS_POLARITY_CONFORM:
- return (conforming_polarity(intr->src_bus_id,
- intr->src_bus_irq));
- case INTENTRY_FLAGS_POLARITY_ACTIVEHI:
- return (INTR_POLARITY_HIGH);
- case INTENTRY_FLAGS_POLARITY_ACTIVELO:
- return (INTR_POLARITY_LOW);
- default:
- panic("Bogus interrupt flags");
- }
-}
-
-static enum intr_trigger
-intentry_trigger(int_entry_ptr intr)
-{
-
- switch (intr->int_flags & INTENTRY_FLAGS_TRIGGER) {
- case INTENTRY_FLAGS_TRIGGER_CONFORM:
- return (conforming_trigger(intr->src_bus_id,
- intr->src_bus_irq));
- case INTENTRY_FLAGS_TRIGGER_EDGE:
- return (INTR_TRIGGER_EDGE);
- case INTENTRY_FLAGS_TRIGGER_LEVEL:
- return (INTR_TRIGGER_LEVEL);
- default:
- panic("Bogus interrupt flags");
- }
-}
-
-/*
- * Parse an interrupt entry for an I/O interrupt routed to a pin on an I/O APIC.
- */
-static void
-mptable_parse_io_int(int_entry_ptr intr)
-{
- void *ioapic;
- u_int pin, apic_id;
-
- apic_id = intr->dst_apic_id;
- if (intr->dst_apic_id == 0xff) {
- /*
- * An APIC ID of 0xff means that the interrupt is connected
- * to the specified pin on all I/O APICs in the system. If
- * there is only one I/O APIC, then use that APIC to route
- * the interrupts. If there is more than one I/O APIC, then
- * punt.
- */
- if (mptable_nioapics == 1) {
- apic_id = 0;
- while (ioapics[apic_id] == NULL)
- apic_id++;
- } else {
- printf(
- "MPTable: Ignoring global interrupt entry for pin %d\n",
- intr->dst_apic_int);
- return;
- }
- }
- if (apic_id > MAX_APIC_ID) {
- printf("MPTable: Ignoring interrupt entry for ioapic%d\n",
- intr->dst_apic_id);
- return;
- }
- ioapic = ioapics[apic_id];
- if (ioapic == NULL) {
- printf(
- "MPTable: Ignoring interrupt entry for missing ioapic%d\n",
- apic_id);
- return;
- }
- pin = intr->dst_apic_int;
- switch (intr->int_type) {
- case INTENTRY_TYPE_INT:
- switch (busses[intr->src_bus_id].bus_type) {
- case NOBUS:
- panic("interrupt from missing bus");
- case ISA:
- case EISA:
- if (busses[intr->src_bus_id].bus_type == ISA)
- ioapic_set_bus(ioapic, pin, APIC_BUS_ISA);
- else
- ioapic_set_bus(ioapic, pin, APIC_BUS_EISA);
- if (intr->src_bus_irq == pin)
- break;
- ioapic_remap_vector(ioapic, pin, intr->src_bus_irq);
- if (ioapic_get_vector(ioapic, intr->src_bus_irq) ==
- intr->src_bus_irq)
- ioapic_disable_pin(ioapic, intr->src_bus_irq);
- break;
- case PCI:
- ioapic_set_bus(ioapic, pin, APIC_BUS_PCI);
- break;
- default:
- ioapic_set_bus(ioapic, pin, APIC_BUS_UNKNOWN);
- break;
- }
- break;
- case INTENTRY_TYPE_NMI:
- ioapic_set_nmi(ioapic, pin);
- break;
- case INTENTRY_TYPE_SMI:
- ioapic_set_smi(ioapic, pin);
- break;
- case INTENTRY_TYPE_EXTINT:
- ioapic_set_extint(ioapic, pin);
- break;
- default:
- panic("%s: invalid interrupt entry type %d\n", __func__,
- intr->int_type);
- }
- if (intr->int_type == INTENTRY_TYPE_INT ||
- (intr->int_flags & INTENTRY_FLAGS_TRIGGER) !=
- INTENTRY_FLAGS_TRIGGER_CONFORM)
- ioapic_set_triggermode(ioapic, pin, intentry_trigger(intr));
- if (intr->int_type == INTENTRY_TYPE_INT ||
- (intr->int_flags & INTENTRY_FLAGS_POLARITY) !=
- INTENTRY_FLAGS_POLARITY_CONFORM)
- ioapic_set_polarity(ioapic, pin, intentry_polarity(intr));
-}
-
-/*
- * Parse an interrupt entry for a local APIC LVT pin.
- */
-static void
-mptable_parse_local_int(int_entry_ptr intr)
-{
- u_int apic_id, pin;
-
- if (intr->dst_apic_id == 0xff)
- apic_id = APIC_ID_ALL;
- else
- apic_id = intr->dst_apic_id;
- if (intr->dst_apic_int == 0)
- pin = LVT_LINT0;
- else
- pin = LVT_LINT1;
- switch (intr->int_type) {
- case INTENTRY_TYPE_INT:
-#if 1
- printf(
- "MPTable: Ignoring vectored local interrupt for LINTIN%d vector %d\n",
- intr->dst_apic_int, intr->src_bus_irq);
- return;
-#else
- lapic_set_lvt_mode(apic_id, pin, APIC_LVT_DM_FIXED);
- break;
-#endif
- case INTENTRY_TYPE_NMI:
- lapic_set_lvt_mode(apic_id, pin, APIC_LVT_DM_NMI);
- break;
- case INTENTRY_TYPE_SMI:
- lapic_set_lvt_mode(apic_id, pin, APIC_LVT_DM_SMI);
- break;
- case INTENTRY_TYPE_EXTINT:
- lapic_set_lvt_mode(apic_id, pin, APIC_LVT_DM_EXTINT);
- break;
- default:
- panic("%s: invalid interrupt entry type %d\n", __func__,
- intr->int_type);
- }
- if ((intr->int_flags & INTENTRY_FLAGS_TRIGGER) !=
- INTENTRY_FLAGS_TRIGGER_CONFORM)
- lapic_set_lvt_triggermode(apic_id, pin,
- intentry_trigger(intr));
- if ((intr->int_flags & INTENTRY_FLAGS_POLARITY) !=
- INTENTRY_FLAGS_POLARITY_CONFORM)
- lapic_set_lvt_polarity(apic_id, pin, intentry_polarity(intr));
-}
-
-/*
- * Parse interrupt entries.
- */
-static void
-mptable_parse_ints_handler(u_char *entry, void *arg __unused)
-{
- int_entry_ptr intr;
-
- intr = (int_entry_ptr)entry;
- switch (*entry) {
- case MPCT_ENTRY_INT:
- mptable_parse_io_int(intr);
- break;
- case MPCT_ENTRY_LOCAL_INT:
- mptable_parse_local_int(intr);
- break;
- }
-}
-
-/*
- * Configure interrupt pins for a default configuration. For details see
- * Table 5-2 in Section 5 of the MP Table specification.
- */
-static void
-mptable_parse_default_config_ints(void)
-{
- struct INTENTRY entry;
- int pin;
-
- /*
- * 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.
- */
- entry.type = MPCT_ENTRY_INT;
- entry.int_flags = INTENTRY_FLAGS_POLARITY_CONFORM |
- INTENTRY_FLAGS_TRIGGER_CONFORM;
- entry.src_bus_id = 0;
- entry.dst_apic_id = 2;
-
- /* Run through all 16 pins. */
- for (pin = 0; pin < 16; pin++) {
- entry.dst_apic_int = pin;
- switch (pin) {
- case 0:
- /* Pin 0 is an ExtINT pin. */
- entry.int_type = INTENTRY_TYPE_EXTINT;
- break;
- case 2:
- /* IRQ 0 is routed to pin 2. */
- entry.int_type = INTENTRY_TYPE_INT;
- entry.src_bus_irq = 0;
- break;
- default:
- /* All other pins are identity mapped. */
- entry.int_type = INTENTRY_TYPE_INT;
- entry.src_bus_irq = pin;
- break;
- }
- mptable_parse_io_int(&entry);
- }
-
- /* Certain configs disable certain pins. */
- if (mpfps->config_type == 7)
- ioapic_disable_pin(ioapics[2], 0);
- if (mpfps->config_type == 2) {
- ioapic_disable_pin(ioapics[2], 2);
- ioapic_disable_pin(ioapics[2], 13);
- }
-}
-
-/*
- * Configure the interrupt pins
- */
-static void
-mptable_parse_ints(void)
-{
-
- /* Is this a pre-defined config? */
- if (mpfps->config_type != 0) {
- /* Configure LINT pins. */
- lapic_set_lvt_mode(APIC_ID_ALL, LVT_LINT0, APIC_LVT_DM_EXTINT);
- lapic_set_lvt_mode(APIC_ID_ALL, LVT_LINT1, APIC_LVT_DM_NMI);
-
- /* Configure I/O APIC pins. */
- mptable_parse_default_config_ints();
- } else
- mptable_walk_table(mptable_parse_ints_handler, NULL);
-}
-
-#ifdef MPTABLE_FORCE_HTT
-/*
- * Perform a hyperthreading "fix-up" to enumerate any logical CPU's
- * that aren't already listed in the table.
- *
- * XXX: We assume that all of the physical CPUs in the
- * system have the same number of logical CPUs.
- *
- * XXX: We assume that APIC ID's are allocated such that
- * the APIC ID's for a physical processor are aligned
- * with the number of logical CPU's in the processor.
- */
-static void
-mptable_hyperthread_fixup(u_long id_mask)
-{
- u_int i, id, logical_cpus;
-
- /* Nothing to do if there is no HTT support. */
- if ((cpu_feature & CPUID_HTT) == 0)
- return;
- logical_cpus = (cpu_procinfo & CPUID_HTT_CORES) >> 16;
- if (logical_cpus <= 1)
- return;
-
- /*
- * For each APIC ID of a CPU that is set in the mask,
- * scan the other candidate APIC ID's for this
- * physical processor. If any of those ID's are
- * already in the table, then kill the fixup.
- */
- for (id = 0; id <= MAX_LAPIC_ID; id++) {
- if ((id_mask & 1 << id) == 0)
- continue;
- /* First, make sure we are on a logical_cpus boundary. */
- if (id % logical_cpus != 0)
- return;
- for (i = id + 1; i < id + logical_cpus; i++)
- if ((id_mask & 1 << i) != 0)
- return;
- }
-
- /*
- * Ok, the ID's checked out, so perform the fixup by
- * adding the logical CPUs.
- */
- while ((id = ffsl(id_mask)) != 0) {
- id--;
- for (i = id + 1; i < id + logical_cpus; i++) {
- if (bootverbose)
- printf(
- "MPTable: Adding logical CPU %d from main CPU %d\n",
- i, id);
- lapic_create(i, 0);
- }
- id_mask &= ~(1 << id);
- }
-}
-#endif /* MPTABLE_FORCE_HTT */
-
-/*
- * Support code for routing PCI interrupts using the MP Table.
- */
-static void
-mptable_pci_setup(void)
-{
- int i;
-
- /*
- * Find the first pci bus and call it 0. Panic if pci0 is not
- * bus zero and there are multiple PCI busses.
- */
- for (i = 0; i <= mptable_maxbusid; i++)
- if (busses[i].bus_type == PCI) {
- if (pci0 == -1)
- pci0 = i;
- else if (pci0 != 0)
- panic(
- "MPTable contains multiple PCI busses but no PCI bus 0");
- }
-}
-
-static void
-mptable_pci_probe_table_handler(u_char *entry, void *arg)
-{
- struct pci_probe_table_args *args;
- int_entry_ptr intr;
-
- if (*entry != MPCT_ENTRY_INT)
- return;
- intr = (int_entry_ptr)entry;
- args = (struct pci_probe_table_args *)arg;
- KASSERT(args->bus <= mptable_maxbusid,
- ("bus %d is too big", args->bus));
- KASSERT(busses[args->bus].bus_type == PCI, ("probing for non-PCI bus"));
- if (intr->src_bus_id == args->bus)
- args->found = 1;
-}
-
-int
-mptable_pci_probe_table(int bus)
-{
- struct pci_probe_table_args args;
-
- if (bus < 0)
- return (EINVAL);
- if (mpct == NULL || pci0 == -1 || pci0 + bus > mptable_maxbusid)
- return (ENXIO);
- if (busses[pci0 + bus].bus_type != PCI)
- return (ENXIO);
- args.bus = pci0 + bus;
- args.found = 0;
- mptable_walk_table(mptable_pci_probe_table_handler, &args);
- if (args.found == 0)
- return (ENXIO);
- return (0);
-}
-
-static void
-mptable_pci_route_interrupt_handler(u_char *entry, void *arg)
-{
- struct pci_route_interrupt_args *args;
- int_entry_ptr intr;
- int vector;
-
- if (*entry != MPCT_ENTRY_INT)
- return;
- intr = (int_entry_ptr)entry;
- args = (struct pci_route_interrupt_args *)arg;
- if (intr->src_bus_id != args->bus || intr->src_bus_irq != args->irq)
- return;
-
- /* Make sure the APIC maps to a known APIC. */
- KASSERT(ioapics[intr->dst_apic_id] != NULL,
- ("No I/O APIC %d to route interrupt to", intr->dst_apic_id));
-
- /*
- * Look up the vector for this APIC / pin combination. If we
- * have previously matched an entry for this PCI IRQ but it
- * has the same vector as this entry, just return. Otherwise,
- * we use the vector for this APIC / pin combination.
- */
- vector = ioapic_get_vector(ioapics[intr->dst_apic_id],
- intr->dst_apic_int);
- if (args->vector == vector)
- return;
- KASSERT(args->vector == -1,
- ("Multiple IRQs for PCI interrupt %d.%d.INT%c: %d and %d\n",
- args->bus, args->irq >> 2, 'A' + (args->irq & 0x3), args->vector,
- vector));
- args->vector = vector;
-}
-
-int
-mptable_pci_route_interrupt(device_t pcib, device_t dev, int pin)
-{
- struct pci_route_interrupt_args args;
- int slot;
-
- /* Like ACPI, pin numbers are 0-3, not 1-4. */
- pin--;
- KASSERT(pci0 != -1, ("do not know how to route PCI interrupts"));
- args.bus = pci_get_bus(dev) + pci0;
- slot = pci_get_slot(dev);
-
- /*
- * PCI interrupt entries in the MP Table encode both the slot and
- * pin into the IRQ with the pin being the two least significant
- * bits, the slot being the next five bits, and the most significant
- * bit being reserved.
- */
- args.irq = slot << 2 | pin;
- args.vector = -1;
- mptable_walk_table(mptable_pci_route_interrupt_handler, &args);
- if (args.vector < 0) {
- device_printf(pcib, "unable to route slot %d INT%c\n", slot,
- 'A' + pin);
- return (PCI_INVALID_IRQ);
- }
- if (bootverbose)
- device_printf(pcib, "slot %d INT%c routed to irq %d\n", slot,
- 'A' + pin, args.vector);
- return (args.vector);
-}
diff --git a/sys/amd64/amd64/nexus.c b/sys/amd64/amd64/nexus.c
deleted file mode 100644
index 037d4ac..0000000
--- a/sys/amd64/amd64/nexus.c
+++ /dev/null
@@ -1,704 +0,0 @@
-/*-
- * Copyright 1998 Massachusetts Institute of Technology
- *
- * Permission to use, copy, modify, and distribute this software and
- * its documentation for any purpose and without fee is hereby
- * granted, provided that both the above copyright notice and this
- * permission notice appear in all copies, that both the above
- * copyright notice and this permission notice appear in all
- * supporting documentation, and that the name of M.I.T. not be used
- * in advertising or publicity pertaining to distribution of the
- * software without specific, written prior permission. M.I.T. makes
- * no representations about the suitability of this software for any
- * purpose. It is provided "as is" without express or implied
- * warranty.
- *
- * THIS SOFTWARE IS PROVIDED BY M.I.T. ``AS IS''. M.I.T. DISCLAIMS
- * ALL EXPRESS OR IMPLIED WARRANTIES WITH REGARD TO THIS SOFTWARE,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT
- * SHALL M.I.T. 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.
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-/*
- * This code implements a `root nexus' for Intel Architecture
- * machines. The function of the root nexus is to serve as an
- * attachment point for both processors and buses, and to manage
- * resources which are common to all of them. In particular,
- * this code implements the core resource managers for interrupt
- * requests, DMA requests (which rightfully should be a part of the
- * ISA code but it's easier to do it here for now), I/O port addresses,
- * and I/O memory address space.
- */
-
-#include "opt_isa.h"
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/bus.h>
-#include <sys/kernel.h>
-#include <sys/linker.h>
-#include <sys/malloc.h>
-#include <sys/module.h>
-#include <machine/bus.h>
-#include <machine/intr_machdep.h>
-#include <sys/rman.h>
-#include <sys/interrupt.h>
-
-#include <machine/vmparam.h>
-#include <vm/vm.h>
-#include <vm/pmap.h>
-#include <machine/pmap.h>
-
-#include <machine/metadata.h>
-#include <machine/nexusvar.h>
-#include <machine/resource.h>
-#include <machine/pc/bios.h>
-
-#include "pcib_if.h"
-
-#ifdef DEV_ISA
-#include <isa/isavar.h>
-#include <x86/isa/isa.h>
-#endif
-#include <sys/rtprio.h>
-
-static MALLOC_DEFINE(M_NEXUSDEV, "nexusdev", "Nexus device");
-
-#define DEVTONX(dev) ((struct nexus_device *)device_get_ivars(dev))
-
-struct rman irq_rman, drq_rman, port_rman, mem_rman;
-
-static int nexus_probe(device_t);
-static int nexus_attach(device_t);
-static int nexus_print_all_resources(device_t dev);
-static int nexus_print_child(device_t, device_t);
-static device_t nexus_add_child(device_t bus, u_int order, const char *name,
- int unit);
-static struct resource *nexus_alloc_resource(device_t, device_t, int, int *,
- u_long, u_long, u_long, u_int);
-#ifdef SMP
-static int nexus_bind_intr(device_t, device_t, struct resource *, int);
-#endif
-static int nexus_config_intr(device_t, int, enum intr_trigger,
- enum intr_polarity);
-static int nexus_describe_intr(device_t dev, device_t child,
- struct resource *irq, void *cookie,
- const char *descr);
-static int nexus_activate_resource(device_t, device_t, int, int,
- struct resource *);
-static int nexus_deactivate_resource(device_t, device_t, int, int,
- struct resource *);
-static int nexus_release_resource(device_t, device_t, int, int,
- struct resource *);
-static int nexus_setup_intr(device_t, device_t, struct resource *, int flags,
- driver_filter_t filter, void (*)(void *), void *,
- void **);
-static int nexus_teardown_intr(device_t, device_t, struct resource *,
- void *);
-static struct resource_list *nexus_get_reslist(device_t dev, device_t child);
-static int nexus_set_resource(device_t, device_t, int, int, u_long, u_long);
-static int nexus_get_resource(device_t, device_t, int, int, u_long *, u_long *);
-static void nexus_delete_resource(device_t, device_t, int, int);
-static int nexus_alloc_msi(device_t pcib, device_t dev, int count, int maxcount, int *irqs);
-static int nexus_release_msi(device_t pcib, device_t dev, int count, int *irqs);
-static int nexus_alloc_msix(device_t pcib, device_t dev, int *irq);
-static int nexus_release_msix(device_t pcib, device_t dev, int irq);
-static int nexus_map_msi(device_t pcib, device_t dev, int irq, uint64_t *addr, uint32_t *data);
-
-static device_method_t nexus_methods[] = {
- /* Device interface */
- DEVMETHOD(device_probe, nexus_probe),
- DEVMETHOD(device_attach, nexus_attach),
- DEVMETHOD(device_detach, bus_generic_detach),
- DEVMETHOD(device_shutdown, bus_generic_shutdown),
- DEVMETHOD(device_suspend, bus_generic_suspend),
- DEVMETHOD(device_resume, bus_generic_resume),
-
- /* Bus interface */
- DEVMETHOD(bus_print_child, nexus_print_child),
- DEVMETHOD(bus_add_child, nexus_add_child),
- DEVMETHOD(bus_alloc_resource, nexus_alloc_resource),
- DEVMETHOD(bus_release_resource, nexus_release_resource),
- DEVMETHOD(bus_activate_resource, nexus_activate_resource),
- DEVMETHOD(bus_deactivate_resource, nexus_deactivate_resource),
- DEVMETHOD(bus_setup_intr, nexus_setup_intr),
- DEVMETHOD(bus_teardown_intr, nexus_teardown_intr),
-#ifdef SMP
- DEVMETHOD(bus_bind_intr, nexus_bind_intr),
-#endif
- DEVMETHOD(bus_config_intr, nexus_config_intr),
- DEVMETHOD(bus_describe_intr, nexus_describe_intr),
- DEVMETHOD(bus_get_resource_list, nexus_get_reslist),
- DEVMETHOD(bus_set_resource, nexus_set_resource),
- DEVMETHOD(bus_get_resource, nexus_get_resource),
- DEVMETHOD(bus_delete_resource, nexus_delete_resource),
-
- /* pcib interface */
- DEVMETHOD(pcib_alloc_msi, nexus_alloc_msi),
- DEVMETHOD(pcib_release_msi, nexus_release_msi),
- DEVMETHOD(pcib_alloc_msix, nexus_alloc_msix),
- DEVMETHOD(pcib_release_msix, nexus_release_msix),
- DEVMETHOD(pcib_map_msi, nexus_map_msi),
-
- { 0, 0 }
-};
-
-DEFINE_CLASS_0(nexus, nexus_driver, nexus_methods, 1);
-static devclass_t nexus_devclass;
-
-DRIVER_MODULE(nexus, root, nexus_driver, nexus_devclass, 0, 0);
-
-static int
-nexus_probe(device_t dev)
-{
-
- device_quiet(dev); /* suppress attach message for neatness */
- return (BUS_PROBE_GENERIC);
-}
-
-void
-nexus_init_resources(void)
-{
- int irq;
-
- /*
- * XXX working notes:
- *
- * - IRQ resource creation should be moved to the PIC/APIC driver.
- * - DRQ resource creation should be moved to the DMAC driver.
- * - The above should be sorted to probe earlier than any child busses.
- *
- * - Leave I/O and memory creation here, as child probes may need them.
- * (especially eg. ACPI)
- */
-
- /*
- * IRQ's are on the mainboard on old systems, but on the ISA part
- * of PCI->ISA bridges. There would be multiple sets of IRQs on
- * multi-ISA-bus systems. PCI interrupts are routed to the ISA
- * component, so in a way, PCI can be a partial child of an ISA bus(!).
- * APIC interrupts are global though.
- */
- irq_rman.rm_start = 0;
- irq_rman.rm_type = RMAN_ARRAY;
- irq_rman.rm_descr = "Interrupt request lines";
- irq_rman.rm_end = NUM_IO_INTS - 1;
- if (rman_init(&irq_rman))
- panic("nexus_init_resources irq_rman");
-
- /*
- * We search for regions of existing IRQs and add those to the IRQ
- * resource manager.
- */
- for (irq = 0; irq < NUM_IO_INTS; irq++)
- if (intr_lookup_source(irq) != NULL)
- if (rman_manage_region(&irq_rman, irq, irq) != 0)
- panic("nexus_init_resources irq_rman add");
-
- /*
- * ISA DMA on PCI systems is implemented in the ISA part of each
- * PCI->ISA bridge and the channels can be duplicated if there are
- * multiple bridges. (eg: laptops with docking stations)
- */
- drq_rman.rm_start = 0;
- drq_rman.rm_end = 7;
- drq_rman.rm_type = RMAN_ARRAY;
- drq_rman.rm_descr = "DMA request lines";
- /* XXX drq 0 not available on some machines */
- if (rman_init(&drq_rman)
- || rman_manage_region(&drq_rman,
- drq_rman.rm_start, drq_rman.rm_end))
- panic("nexus_init_resources drq_rman");
-
- /*
- * However, IO ports and Memory truely are global at this level,
- * as are APIC interrupts (however many IO APICS there turn out
- * to be on large systems..)
- */
- port_rman.rm_start = 0;
- port_rman.rm_end = 0xffff;
- port_rman.rm_type = RMAN_ARRAY;
- port_rman.rm_descr = "I/O ports";
- if (rman_init(&port_rman)
- || rman_manage_region(&port_rman, 0, 0xffff))
- panic("nexus_init_resources port_rman");
-
- mem_rman.rm_start = 0;
- mem_rman.rm_end = ~0u;
- mem_rman.rm_type = RMAN_ARRAY;
- mem_rman.rm_descr = "I/O memory addresses";
- if (rman_init(&mem_rman)
- || rman_manage_region(&mem_rman, 0, ~0))
- panic("nexus_init_resources mem_rman");
-}
-
-static int
-nexus_attach(device_t dev)
-{
-
- nexus_init_resources();
- bus_generic_probe(dev);
-
- /*
- * Explicitly add the legacy0 device here. Other platform
- * types (such as ACPI), use their own nexus(4) subclass
- * driver to override this routine and add their own root bus.
- */
- if (BUS_ADD_CHILD(dev, 10, "legacy", 0) == NULL)
- panic("legacy: could not attach");
- bus_generic_attach(dev);
- return 0;
-}
-
-static int
-nexus_print_all_resources(device_t dev)
-{
- struct nexus_device *ndev = DEVTONX(dev);
- struct resource_list *rl = &ndev->nx_resources;
- int retval = 0;
-
- if (STAILQ_FIRST(rl))
- retval += printf(" at");
-
- retval += resource_list_print_type(rl, "port", SYS_RES_IOPORT, "%#lx");
- retval += resource_list_print_type(rl, "iomem", SYS_RES_MEMORY, "%#lx");
- retval += resource_list_print_type(rl, "irq", SYS_RES_IRQ, "%ld");
-
- return retval;
-}
-
-static int
-nexus_print_child(device_t bus, device_t child)
-{
- int retval = 0;
-
- retval += bus_print_child_header(bus, child);
- retval += nexus_print_all_resources(child);
- if (device_get_flags(child))
- retval += printf(" flags %#x", device_get_flags(child));
- retval += printf(" on motherboard\n"); /* XXX "motherboard", ick */
-
- return (retval);
-}
-
-static device_t
-nexus_add_child(device_t bus, u_int order, const char *name, int unit)
-{
- device_t child;
- struct nexus_device *ndev;
-
- ndev = malloc(sizeof(struct nexus_device), M_NEXUSDEV, M_NOWAIT|M_ZERO);
- if (!ndev)
- return(0);
- resource_list_init(&ndev->nx_resources);
-
- child = device_add_child_ordered(bus, order, name, unit);
-
- /* should we free this in nexus_child_detached? */
- device_set_ivars(child, ndev);
-
- return(child);
-}
-
-/*
- * Allocate a resource on behalf of child. NB: child is usually going to be a
- * child of one of our descendants, not a direct child of nexus0.
- */
-static struct resource *
-nexus_alloc_resource(device_t bus, device_t child, int type, int *rid,
- u_long start, u_long end, u_long count, u_int flags)
-{
- struct nexus_device *ndev = DEVTONX(child);
- struct resource *rv;
- struct resource_list_entry *rle;
- struct rman *rm;
- int needactivate = flags & RF_ACTIVE;
-
- /*
- * If this is an allocation of the "default" range for a given RID, and
- * we know what the resources for this device are (ie. they aren't maintained
- * by a child bus), then work out the start/end values.
- */
- if ((start == 0UL) && (end == ~0UL) && (count == 1)) {
- if (ndev == NULL)
- return(NULL);
- rle = resource_list_find(&ndev->nx_resources, type, *rid);
- if (rle == NULL)
- return(NULL);
- start = rle->start;
- end = rle->end;
- count = rle->count;
- }
-
- flags &= ~RF_ACTIVE;
-
- switch (type) {
- case SYS_RES_IRQ:
- rm = &irq_rman;
- break;
-
- case SYS_RES_DRQ:
- rm = &drq_rman;
- break;
-
- case SYS_RES_IOPORT:
- rm = &port_rman;
- break;
-
- case SYS_RES_MEMORY:
- rm = &mem_rman;
- break;
-
- default:
- return 0;
- }
-
- rv = rman_reserve_resource(rm, start, end, count, flags, child);
- if (rv == 0)
- return 0;
- rman_set_rid(rv, *rid);
-
- if (needactivate) {
- if (bus_activate_resource(child, type, *rid, rv)) {
- rman_release_resource(rv);
- return 0;
- }
- }
-
- return rv;
-}
-
-static int
-nexus_activate_resource(device_t bus, device_t child, int type, int rid,
- struct resource *r)
-{
-
- /*
- * If this is a memory resource, map it into the kernel.
- */
- if (type == SYS_RES_MEMORY) {
- void *vaddr;
-
- vaddr = pmap_mapdev(rman_get_start(r), rman_get_size(r));
- rman_set_virtual(r, vaddr);
- rman_set_bustag(r, AMD64_BUS_SPACE_MEM);
- rman_set_bushandle(r, (bus_space_handle_t) vaddr);
- } else if (type == SYS_RES_IOPORT) {
- rman_set_bustag(r, AMD64_BUS_SPACE_IO);
- rman_set_bushandle(r, rman_get_start(r));
- }
- return (rman_activate_resource(r));
-}
-
-static int
-nexus_deactivate_resource(device_t bus, device_t child, int type, int rid,
- struct resource *r)
-{
- /*
- * If this is a memory resource, unmap it.
- */
- if (type == SYS_RES_MEMORY) {
- pmap_unmapdev((vm_offset_t)rman_get_virtual(r),
- rman_get_size(r));
- }
-
- return (rman_deactivate_resource(r));
-}
-
-static int
-nexus_release_resource(device_t bus, device_t child, int type, int rid,
- struct resource *r)
-{
- if (rman_get_flags(r) & RF_ACTIVE) {
- int error = bus_deactivate_resource(child, type, rid, r);
- if (error)
- return error;
- }
- return (rman_release_resource(r));
-}
-
-/*
- * Currently this uses the really grody interface from kern/kern_intr.c
- * (which really doesn't belong in kern/anything.c). Eventually, all of
- * the code in kern_intr.c and machdep_intr.c should get moved here, since
- * this is going to be the official interface.
- */
-static int
-nexus_setup_intr(device_t bus, device_t child, struct resource *irq,
- int flags, driver_filter_t filter, void (*ihand)(void *),
- void *arg, void **cookiep)
-{
- int error;
-
- /* somebody tried to setup an irq that failed to allocate! */
- if (irq == NULL)
- panic("nexus_setup_intr: NULL irq resource!");
-
- *cookiep = 0;
- if ((rman_get_flags(irq) & RF_SHAREABLE) == 0)
- flags |= INTR_EXCL;
-
- /*
- * We depend here on rman_activate_resource() being idempotent.
- */
- error = rman_activate_resource(irq);
- if (error)
- return (error);
-
- error = intr_add_handler(device_get_nameunit(child),
- rman_get_start(irq), filter, ihand, arg, flags, cookiep);
-
- return (error);
-}
-
-static int
-nexus_teardown_intr(device_t dev, device_t child, struct resource *r, void *ih)
-{
- return (intr_remove_handler(ih));
-}
-
-#ifdef SMP
-static int
-nexus_bind_intr(device_t dev, device_t child, struct resource *irq, int cpu)
-{
- return (intr_bind(rman_get_start(irq), cpu));
-}
-#endif
-
-static int
-nexus_config_intr(device_t dev, int irq, enum intr_trigger trig,
- enum intr_polarity pol)
-{
- return (intr_config_intr(irq, trig, pol));
-}
-
-static int
-nexus_describe_intr(device_t dev, device_t child, struct resource *irq,
- void *cookie, const char *descr)
-{
-
- return (intr_describe(rman_get_start(irq), cookie, descr));
-}
-
-static struct resource_list *
-nexus_get_reslist(device_t dev, device_t child)
-{
- struct nexus_device *ndev = DEVTONX(child);
-
- return (&ndev->nx_resources);
-}
-
-static int
-nexus_set_resource(device_t dev, device_t child, int type, int rid, u_long start, u_long count)
-{
- struct nexus_device *ndev = DEVTONX(child);
- struct resource_list *rl = &ndev->nx_resources;
-
- /* XXX this should return a success/failure indicator */
- resource_list_add(rl, type, rid, start, start + count - 1, count);
- return(0);
-}
-
-static int
-nexus_get_resource(device_t dev, device_t child, int type, int rid, u_long *startp, u_long *countp)
-{
- struct nexus_device *ndev = DEVTONX(child);
- struct resource_list *rl = &ndev->nx_resources;
- struct resource_list_entry *rle;
-
- rle = resource_list_find(rl, type, rid);
- if (!rle)
- return(ENOENT);
- if (startp)
- *startp = rle->start;
- if (countp)
- *countp = rle->count;
- return(0);
-}
-
-static void
-nexus_delete_resource(device_t dev, device_t child, int type, int rid)
-{
- struct nexus_device *ndev = DEVTONX(child);
- struct resource_list *rl = &ndev->nx_resources;
-
- resource_list_delete(rl, type, rid);
-}
-
-/* Called from the MSI code to add new IRQs to the IRQ rman. */
-void
-nexus_add_irq(u_long irq)
-{
-
- if (rman_manage_region(&irq_rman, irq, irq) != 0)
- panic("%s: failed", __func__);
-}
-
-static int
-nexus_alloc_msix(device_t pcib, device_t dev, int *irq)
-{
-
- return (msix_alloc(dev, irq));
-}
-
-static int
-nexus_release_msix(device_t pcib, device_t dev, int irq)
-{
-
- return (msix_release(irq));
-}
-
-static int
-nexus_alloc_msi(device_t pcib, device_t dev, int count, int maxcount, int *irqs)
-{
-
- return (msi_alloc(dev, count, maxcount, irqs));
-}
-
-static int
-nexus_release_msi(device_t pcib, device_t dev, int count, int *irqs)
-{
-
- return (msi_release(irqs, count));
-}
-
-static int
-nexus_map_msi(device_t pcib, device_t dev, int irq, uint64_t *addr, uint32_t *data)
-{
-
- return (msi_map(irq, addr, data));
-}
-
-/* Placeholder for system RAM. */
-static void
-ram_identify(driver_t *driver, device_t parent)
-{
-
- if (resource_disabled("ram", 0))
- return;
- if (BUS_ADD_CHILD(parent, 0, "ram", 0) == NULL)
- panic("ram_identify");
-}
-
-static int
-ram_probe(device_t dev)
-{
-
- device_quiet(dev);
- device_set_desc(dev, "System RAM");
- return (0);
-}
-
-static int
-ram_attach(device_t dev)
-{
- struct bios_smap *smapbase, *smap, *smapend;
- struct resource *res;
- caddr_t kmdp;
- uint32_t smapsize;
- int error, rid;
-
- /* Retrieve the system memory map from the loader. */
- kmdp = preload_search_by_type("elf kernel");
- if (kmdp == NULL)
- kmdp = preload_search_by_type("elf64 kernel");
- smapbase = (struct bios_smap *)preload_search_info(kmdp,
- MODINFO_METADATA | MODINFOMD_SMAP);
- smapsize = *((u_int32_t *)smapbase - 1);
- smapend = (struct bios_smap *)((uintptr_t)smapbase + smapsize);
-
- rid = 0;
- for (smap = smapbase; smap < smapend; smap++) {
- if (smap->type != SMAP_TYPE_MEMORY || smap->length == 0)
- continue;
- error = bus_set_resource(dev, SYS_RES_MEMORY, rid, smap->base,
- smap->length);
- if (error)
- panic("ram_attach: resource %d failed set with %d", rid,
- error);
- res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, 0);
- if (res == NULL)
- panic("ram_attach: resource %d failed to attach", rid);
- rid++;
- }
- return (0);
-}
-
-static device_method_t ram_methods[] = {
- /* Device interface */
- DEVMETHOD(device_identify, ram_identify),
- DEVMETHOD(device_probe, ram_probe),
- DEVMETHOD(device_attach, ram_attach),
- { 0, 0 }
-};
-
-static driver_t ram_driver = {
- "ram",
- ram_methods,
- 1, /* no softc */
-};
-
-static devclass_t ram_devclass;
-
-DRIVER_MODULE(ram, nexus, ram_driver, ram_devclass, 0, 0);
-
-#ifdef DEV_ISA
-/*
- * Placeholder which claims PnP 'devices' which describe system
- * resources.
- */
-static struct isa_pnp_id sysresource_ids[] = {
- { 0x010cd041 /* PNP0c01 */, "System Memory" },
- { 0x020cd041 /* PNP0c02 */, "System Resource" },
- { 0 }
-};
-
-static int
-sysresource_probe(device_t dev)
-{
- int result;
-
- if ((result = ISA_PNP_PROBE(device_get_parent(dev), dev, sysresource_ids)) <= 0) {
- device_quiet(dev);
- }
- return(result);
-}
-
-static int
-sysresource_attach(device_t dev)
-{
- return(0);
-}
-
-static device_method_t sysresource_methods[] = {
- /* Device interface */
- DEVMETHOD(device_probe, sysresource_probe),
- DEVMETHOD(device_attach, sysresource_attach),
- DEVMETHOD(device_detach, bus_generic_detach),
- DEVMETHOD(device_shutdown, bus_generic_shutdown),
- DEVMETHOD(device_suspend, bus_generic_suspend),
- DEVMETHOD(device_resume, bus_generic_resume),
- { 0, 0 }
-};
-
-static driver_t sysresource_driver = {
- "sysresource",
- sysresource_methods,
- 1, /* no softc */
-};
-
-static devclass_t sysresource_devclass;
-
-DRIVER_MODULE(sysresource, isa, sysresource_driver, sysresource_devclass, 0, 0);
-#endif /* DEV_ISA */
diff --git a/sys/amd64/amd64/pmap.c b/sys/amd64/amd64/pmap.c
index 0203917..aa20133 100644
--- a/sys/amd64/amd64/pmap.c
+++ b/sys/amd64/amd64/pmap.c
@@ -462,7 +462,7 @@ create_pagetables(vm_paddr_t *firstaddr)
if (ndmpdp < 4) /* Minimum 4GB of dirmap */
ndmpdp = 4;
DMPDPphys = allocpages(firstaddr, NDMPML4E);
- if (TRUE || (amd_feature & AMDID_PAGE1GB) == 0)
+ if ((amd_feature & AMDID_PAGE1GB) == 0)
DMPDphys = allocpages(firstaddr, ndmpdp);
dmaplimit = (vm_paddr_t)ndmpdp << PDPSHIFT;
@@ -494,11 +494,16 @@ create_pagetables(vm_paddr_t *firstaddr)
((pdp_entry_t *)KPDPphys)[i + KPDPI] |= PG_RW | PG_V | PG_U;
}
- /* Now set up the direct map space using either 2MB or 1GB pages */
- /* Preset PG_M and PG_A because demotion expects it */
- if (TRUE || (amd_feature & AMDID_PAGE1GB) == 0) {
+ /*
+ * Now, set up the direct map region using either 2MB or 1GB pages.
+ * Later, if pmap_mapdev{_attr}() uses the direct map for non-write-
+ * back memory, pmap_change_attr() will demote any 2MB or 1GB page
+ * mappings that are partially used.
+ */
+ if ((amd_feature & AMDID_PAGE1GB) == 0) {
for (i = 0; i < NPDEPG * ndmpdp; i++) {
((pd_entry_t *)DMPDphys)[i] = (vm_paddr_t)i << PDRSHIFT;
+ /* Preset PG_M and PG_A because demotion expects it. */
((pd_entry_t *)DMPDphys)[i] |= PG_RW | PG_V | PG_PS |
PG_G | PG_M | PG_A;
}
@@ -512,6 +517,7 @@ create_pagetables(vm_paddr_t *firstaddr)
for (i = 0; i < ndmpdp; i++) {
((pdp_entry_t *)DMPDPphys)[i] =
(vm_paddr_t)i << PDPSHIFT;
+ /* Preset PG_M and PG_A because demotion expects it. */
((pdp_entry_t *)DMPDPphys)[i] |= PG_RW | PG_V | PG_PS |
PG_G | PG_M | PG_A;
}
@@ -4948,6 +4954,54 @@ pmap_change_attr_locked(vm_offset_t va, vm_size_t size, int mode)
}
/*
+ * Demotes any mapping within the direct map region that covers more than the
+ * specified range of physical addresses. This range's size must be a power
+ * of two and its starting address must be a multiple of its size. Since the
+ * demotion does not change any attributes of the mapping, a TLB invalidation
+ * is not mandatory. The caller may, however, request a TLB invalidation.
+ */
+void
+pmap_demote_DMAP(vm_paddr_t base, vm_size_t len, boolean_t invalidate)
+{
+ pdp_entry_t *pdpe;
+ pd_entry_t *pde;
+ vm_offset_t va;
+ boolean_t changed;
+
+ if (len == 0)
+ return;
+ KASSERT(powerof2(len), ("pmap_demote_DMAP: len is not a power of 2"));
+ KASSERT((base & (len - 1)) == 0,
+ ("pmap_demote_DMAP: base is not a multiple of len"));
+ if (len < NBPDP && base < dmaplimit) {
+ va = PHYS_TO_DMAP(base);
+ changed = FALSE;
+ PMAP_LOCK(kernel_pmap);
+ pdpe = pmap_pdpe(kernel_pmap, va);
+ if ((*pdpe & PG_V) == 0)
+ panic("pmap_demote_DMAP: invalid PDPE");
+ if ((*pdpe & PG_PS) != 0) {
+ if (!pmap_demote_pdpe(kernel_pmap, pdpe, va))
+ panic("pmap_demote_DMAP: PDPE failed");
+ changed = TRUE;
+ }
+ if (len < NBPDR) {
+ pde = pmap_pdpe_to_pde(pdpe, va);
+ if ((*pde & PG_V) == 0)
+ panic("pmap_demote_DMAP: invalid PDE");
+ if ((*pde & PG_PS) != 0) {
+ if (!pmap_demote_pde(kernel_pmap, pde, va))
+ panic("pmap_demote_DMAP: PDE failed");
+ changed = TRUE;
+ }
+ }
+ if (changed && invalidate)
+ pmap_invalidate_page(kernel_pmap, va);
+ PMAP_UNLOCK(kernel_pmap);
+ }
+}
+
+/*
* perform the pmap work for mincore
*/
int
diff --git a/sys/amd64/amd64/trap.c b/sys/amd64/amd64/trap.c
index 69e94d9..786d8ec 100644
--- a/sys/amd64/amd64/trap.c
+++ b/sys/amd64/amd64/trap.c
@@ -83,7 +83,7 @@ __FBSDID("$FreeBSD$");
#include <machine/cpu.h>
#include <machine/intr_machdep.h>
-#include <machine/mca.h>
+#include <x86/mca.h>
#include <machine/md_var.h>
#include <machine/pcb.h>
#ifdef SMP
diff --git a/sys/amd64/include/pmap.h b/sys/amd64/include/pmap.h
index 53a4d63..45ccc64 100644
--- a/sys/amd64/include/pmap.h
+++ b/sys/amd64/include/pmap.h
@@ -307,6 +307,7 @@ extern vm_offset_t virtual_end;
void pmap_bootstrap(vm_paddr_t *);
int pmap_change_attr(vm_offset_t, vm_size_t, int);
+void pmap_demote_DMAP(vm_paddr_t base, vm_size_t len, boolean_t invalidate);
void pmap_init_pat(void);
void pmap_kenter(vm_offset_t va, vm_paddr_t pa);
void *pmap_kenter_temporary(vm_paddr_t pa, int i);
diff --git a/sys/arm/arm/elf_trampoline.c b/sys/arm/arm/elf_trampoline.c
index 0f725c8..4adb025 100644
--- a/sys/arm/arm/elf_trampoline.c
+++ b/sys/arm/arm/elf_trampoline.c
@@ -159,7 +159,7 @@ _startC(void)
#if defined(FLASHADDR) && defined(LOADERRAMADDR)
unsigned int pc;
- __asm __volatile("adr %0, _start\n"
+ __asm __volatile("mov %0, pc\n"
: "=r" (pc));
if ((FLASHADDR > LOADERRAMADDR && pc >= FLASHADDR) ||
(FLASHADDR < LOADERRAMADDR && pc < LOADERRAMADDR)) {
@@ -173,11 +173,13 @@ _startC(void)
*/
unsigned int target_addr;
unsigned int tmp_sp;
+ uint32_t src_addr = (uint32_t)&_start - PHYSADDR + FLASHADDR
+ + (pc - FLASHADDR - ((uint32_t)&_startC - PHYSADDR)) & 0xfffff000;
target_addr = (unsigned int)&_start - PHYSADDR + LOADERRAMADDR;
tmp_sp = target_addr + 0x100000 +
(unsigned int)&_end - (unsigned int)&_start;
- memcpy((char *)target_addr, (char *)pc,
+ memcpy((char *)target_addr, (char *)src_addr,
(unsigned int)&_end - (unsigned int)&_start);
/* Temporary set the sp and jump to the new location. */
__asm __volatile(
diff --git a/sys/boot/ofw/common/main.c b/sys/boot/ofw/common/main.c
index 1a03e9b..52e69199 100644
--- a/sys/boot/ofw/common/main.c
+++ b/sys/boot/ofw/common/main.c
@@ -41,19 +41,23 @@ extern char bootprog_rev[];
extern char bootprog_date[];
extern char bootprog_maker[];
-u_int32_t acells;
+u_int32_t acells, scells;
static char bootargs[128];
#define HEAP_SIZE 0x80000
+#define OF_puts(fd, text) OF_write(fd, text, strlen(text))
+
void
init_heap(void)
{
void *base;
+ ihandle_t stdout;
if ((base = ofw_alloc_heap(HEAP_SIZE)) == (void *)0xffffffff) {
- printf("Heap memory claim failed!\n");
+ OF_getprop(chosen, "stdout", &stdout, sizeof(stdout));
+ OF_puts(stdout, "Heap memory claim failed!\n");
OF_enter();
}
@@ -64,25 +68,20 @@ uint64_t
memsize(void)
{
phandle_t memoryp;
- struct ofw_reg reg[4];
- struct ofw_reg2 reg2[8];
- int i;
- u_int64_t sz, memsz;
+ cell_t reg[24];
+ int i, sz;
+ u_int64_t memsz;
+ memsz = 0;
memoryp = OF_instance_to_package(memory);
- if (acells == 1) {
- sz = OF_getprop(memoryp, "reg", &reg, sizeof(reg));
- sz /= sizeof(struct ofw_reg);
+ sz = OF_getprop(memoryp, "reg", &reg, sizeof(reg));
+ sz /= sizeof(reg[0]);
- for (i = 0, memsz = 0; i < sz; i++)
- memsz += reg[i].size;
- } else if (acells == 2) {
- sz = OF_getprop(memoryp, "reg", &reg2, sizeof(reg2));
- sz /= sizeof(struct ofw_reg2);
-
- for (i = 0, memsz = 0; i < sz; i++)
- memsz += reg2[i].size;
+ for (i = 0; i < sz; i += (acells + scells)) {
+ if (scells > 1)
+ memsz += (uint64_t)reg[i + acells] << 32;
+ memsz += reg[i + acells + scells - 1];
}
return (memsz);
@@ -105,13 +104,9 @@ main(int (*openfirm)(void *))
root = OF_finddevice("/");
- acells = 1;
+ scells = acells = 1;
OF_getprop(root, "#address-cells", &acells, sizeof(acells));
-
- /*
- * Set up console.
- */
- cons_probe();
+ OF_getprop(root, "#size-cells", &scells, sizeof(scells));
/*
* Initialise the heap as early as possible. Once this is done,
@@ -121,6 +116,11 @@ main(int (*openfirm)(void *))
init_heap();
/*
+ * Set up console.
+ */
+ cons_probe();
+
+ /*
* March through the device switch probing for things.
*/
for (i = 0; devsw[i] != NULL; i++)
diff --git a/sys/boot/ofw/libofw/ofw_memory.c b/sys/boot/ofw/libofw/ofw_memory.c
index ebf01af..60cc904 100644
--- a/sys/boot/ofw/libofw/ofw_memory.c
+++ b/sys/boot/ofw/libofw/ofw_memory.c
@@ -118,13 +118,19 @@ ofw_memmap(int acells)
void *
ofw_alloc_heap(unsigned int size)
{
- phandle_t memoryp;
- struct ofw_reg available;
+ phandle_t memoryp, root;
+ cell_t available[4];
+ cell_t acells;
+
+ root = OF_finddevice("/");
+ acells = 1;
+ OF_getprop(root, "#address-cells", &acells, sizeof(acells));
memoryp = OF_instance_to_package(memory);
- OF_getprop(memoryp, "available", &available, sizeof(available));
+ OF_getprop(memoryp, "available", available, sizeof(available));
- heap_base = OF_claim((void *)available.base, size, sizeof(register_t));
+ heap_base = OF_claim((void *)available[acells-1], size,
+ sizeof(register_t));
if (heap_base != (void *)-1) {
heap_size = size;
diff --git a/sys/boot/ofw/libofw/ofw_net.c b/sys/boot/ofw/libofw/ofw_net.c
index 17e1125..830fcda 100644
--- a/sys/boot/ofw/libofw/ofw_net.c
+++ b/sys/boot/ofw/libofw/ofw_net.c
@@ -230,7 +230,10 @@ punt:
static void
ofwn_end(struct netif *nif)
{
+#ifdef BROKEN
+ /* dma-free freezes at least some Apple ethernet controllers */
OF_call_method("dma-free", netinstance, 2, 0, dmabuf, MAXPHYS);
+#endif
OF_close(netinstance);
}
diff --git a/sys/boot/ofw/libofw/openfirm.c b/sys/boot/ofw/libofw/openfirm.c
index 8786d5d..4b84fa1 100644
--- a/sys/boot/ofw/libofw/openfirm.c
+++ b/sys/boot/ofw/libofw/openfirm.c
@@ -80,8 +80,13 @@ OF_init(int (*openfirm)(void *))
if ((chosen = OF_finddevice("/chosen")) == -1)
OF_exit();
- if (OF_getprop(chosen, "memory", &memory, sizeof(memory)) == -1)
- OF_exit();
+ if (OF_getprop(chosen, "memory", &memory, sizeof(memory)) == -1) {
+ memory = OF_open("/memory");
+ if (memory == -1)
+ memory = OF_open("/memory@0");
+ if (memory == -1)
+ OF_exit();
+ }
if (OF_getprop(chosen, "mmu", &mmu, sizeof(mmu)) == -1)
OF_exit();
}
diff --git a/sys/boot/sparc64/loader/main.c b/sys/boot/sparc64/loader/main.c
index b3e7908..97f566c 100644
--- a/sys/boot/sparc64/loader/main.c
+++ b/sys/boot/sparc64/loader/main.c
@@ -811,15 +811,15 @@ main(int (*openfirm)(void *))
archsw.arch_autoload = sparc64_autoload;
archsw.arch_maphint = sparc64_maphint;
+ if (init_heap() == (vm_offset_t)-1)
+ OF_exit();
+ setheap((void *)heapva, (void *)(heapva + HEAPSZ));
+
/*
* Probe for a console.
*/
cons_probe();
- if (init_heap() == (vm_offset_t)-1)
- panic("%s: can't claim heap", __func__);
- setheap((void *)heapva, (void *)(heapva + HEAPSZ));
-
if ((root = OF_peer(0)) == -1)
panic("%s: can't get root phandle", __func__);
OF_getprop(root, "compatible", compatible, sizeof(compatible));
diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu.c
index 133343b..26b4e5f 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu.c
+++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu.c
@@ -192,7 +192,7 @@ dmu_buf_hold_array_by_dnode(dnode_t *dn, uint64_t offset, uint64_t length,
ASSERT(length <= DMU_MAX_ACCESS);
- dbuf_flags = DB_RF_CANFAIL | DB_RF_NEVERWAIT;
+ dbuf_flags = DB_RF_CANFAIL | DB_RF_NEVERWAIT | DB_RF_HAVESTRUCT;
if (flags & DMU_READ_NO_PREFETCH || length > zfetch_array_rd_sz)
dbuf_flags |= DB_RF_NOPREFETCH;
@@ -209,6 +209,7 @@ dmu_buf_hold_array_by_dnode(dnode_t *dn, uint64_t offset, uint64_t length,
os_dsl_dataset->ds_object,
(longlong_t)dn->dn_object, dn->dn_datablksz,
(longlong_t)offset, (longlong_t)length);
+ rw_exit(&dn->dn_struct_rwlock);
return (EIO);
}
nblks = 1;
@@ -231,9 +232,7 @@ dmu_buf_hold_array_by_dnode(dnode_t *dn, uint64_t offset, uint64_t length,
}
/* initiate async i/o */
if (read) {
- rw_exit(&dn->dn_struct_rwlock);
(void) dbuf_read(db, zio, dbuf_flags);
- rw_enter(&dn->dn_struct_rwlock, RW_READER);
}
dbp[i] = &db->db;
}
@@ -540,7 +539,7 @@ dmu_read(objset_t *os, uint64_t object, uint64_t offset, uint64_t size,
{
dnode_t *dn;
dmu_buf_t **dbp;
- int numbufs, i, err;
+ int numbufs, err;
err = dnode_hold(os->os, object, FTAG, &dn);
if (err)
@@ -551,7 +550,7 @@ dmu_read(objset_t *os, uint64_t object, uint64_t offset, uint64_t size,
* block. If we ever do the tail block optimization, we will need to
* handle that here as well.
*/
- if (dn->dn_datablkshift == 0) {
+ if (dn->dn_maxblkid == 0) {
int newsz = offset > dn->dn_datablksz ? 0 :
MIN(size, dn->dn_datablksz - offset);
bzero((char *)buf + newsz, size - newsz);
@@ -560,6 +559,7 @@ dmu_read(objset_t *os, uint64_t object, uint64_t offset, uint64_t size,
while (size > 0) {
uint64_t mylen = MIN(size, DMU_MAX_ACCESS / 2);
+ int i;
/*
* NB: we could do this block-at-a-time, but it's nice
diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c
index bcbe514..ba0f0eb 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c
+++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c
@@ -1031,6 +1031,10 @@ zfs_get_done(dmu_buf_t *db, void *vzgd)
VFS_UNLOCK_GIANT(vfslocked);
}
+#ifdef DEBUG
+static int zil_fault_io = 0;
+#endif
+
/*
* Get data to generate a TX_WRITE intent log record.
*/
@@ -1112,7 +1116,21 @@ zfs_get_data(void *arg, lr_write_t *lr, char *buf, zio_t *zio)
zgd->zgd_rl = rl;
zgd->zgd_zilog = zfsvfs->z_log;
zgd->zgd_bp = &lr->lr_blkptr;
- VERIFY(0 == dmu_buf_hold(os, lr->lr_foid, boff, zgd, &db));
+#ifdef DEBUG
+ if (zil_fault_io) {
+ error = EIO;
+ zil_fault_io = 0;
+ } else {
+ error = dmu_buf_hold(os, lr->lr_foid, boff, zgd, &db);
+ }
+#else
+ error = dmu_buf_hold(os, lr->lr_foid, boff, zgd, &db);
+#endif
+ if (error != 0) {
+ kmem_free(zgd, sizeof (zgd_t));
+ goto out;
+ }
+
ASSERT(boff == db->db_offset);
lr->lr_blkoff = off - boff;
error = dmu_sync(zio, db, &lr->lr_blkptr,
diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zil.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zil.c
index 1dd8ea0..490e50f 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zil.c
+++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zil.c
@@ -933,6 +933,10 @@ zil_lwb_commit(zilog_t *zilog, itx_t *itx, lwb_t *lwb)
}
error = zilog->zl_get_data(
itx->itx_private, lr, dbuf, lwb->lwb_zio);
+ if (error == EIO) {
+ txg_wait_synced(zilog->zl_dmu_pool, txg);
+ return (lwb);
+ }
if (error) {
ASSERT(error == ENOENT || error == EEXIST ||
error == EALREADY);
diff --git a/sys/conf/files.amd64 b/sys/conf/files.amd64
index a3b113b..fb4bc2f 100644
--- a/sys/conf/files.amd64
+++ b/sys/conf/files.amd64
@@ -104,7 +104,6 @@ amd64/amd64/cpu_switch.S standard
amd64/amd64/db_disasm.c optional ddb
amd64/amd64/db_interface.c optional ddb
amd64/amd64/db_trace.c optional ddb
-amd64/amd64/dump_machdep.c standard
amd64/amd64/elf_machdep.c standard
amd64/amd64/exception.S standard
amd64/amd64/fpu.c standard
@@ -122,9 +121,6 @@ amd64/amd64/minidump_machdep.c standard
amd64/amd64/mp_machdep.c optional smp
amd64/amd64/mp_watchdog.c optional mp_watchdog smp
amd64/amd64/mpboot.S optional smp
-amd64/amd64/mptable.c optional mptable
-amd64/amd64/mptable_pci.c optional mptable pci
-amd64/amd64/nexus.c standard
amd64/amd64/pmap.c standard
amd64/amd64/prof_machdep.c optional profiling-routine
amd64/amd64/sigtramp.S standard
@@ -321,7 +317,11 @@ x86/isa/isa_dma.c standard
x86/isa/nmi.c standard
x86/isa/orm.c optional isa
x86/pci/qpi.c standard
+x86/x86/dump_machdep.c standard
x86/x86/io_apic.c standard
x86/x86/local_apic.c standard
x86/x86/mca.c standard
+x86/x86/mptable.c optional mptable
+x86/x86/mptable_pci.c optional mptable pci
x86/x86/msi.c optional pci
+x86/x86/nexus.c standard
diff --git a/sys/conf/files.i386 b/sys/conf/files.i386
index f10a234..cb05bec 100644
--- a/sys/conf/files.i386
+++ b/sys/conf/files.i386
@@ -263,7 +263,6 @@ i386/i386/busdma_machdep.c standard
i386/i386/db_disasm.c optional ddb
i386/i386/db_interface.c optional ddb
i386/i386/db_trace.c optional ddb
-i386/i386/dump_machdep.c standard
i386/i386/elan-mmcr.c optional cpu_elan | cpu_soekris
i386/i386/elf_machdep.c standard
i386/i386/exception.s optional native
@@ -290,10 +289,7 @@ i386/i386/mp_machdep.c optional native smp
i386/xen/mp_machdep.c optional xen smp
i386/i386/mp_watchdog.c optional mp_watchdog smp
i386/i386/mpboot.s optional smp native
-i386/i386/mptable.c optional apic native
i386/xen/mptable.c optional apic xen
-i386/i386/mptable_pci.c optional apic pci
-i386/i386/nexus.c standard
i386/i386/perfmon.c optional perfmon
i386/i386/pmap.c optional native
i386/xen/pmap.c optional xen
@@ -395,7 +391,11 @@ x86/isa/isa_dma.c optional isa
x86/isa/nmi.c standard
x86/isa/orm.c optional isa
x86/pci/qpi.c standard
+x86/x86/dump_machdep.c standard
x86/x86/io_apic.c optional apic
x86/x86/local_apic.c optional apic
x86/x86/mca.c standard
+x86/x86/mptable.c optional apic native
+x86/x86/mptable_pci.c optional apic pci
x86/x86/msi.c optional apic pci
+x86/x86/nexus.c standard
diff --git a/sys/conf/files.pc98 b/sys/conf/files.pc98
index 7f90e9f..ab88e22 100644
--- a/sys/conf/files.pc98
+++ b/sys/conf/files.pc98
@@ -138,7 +138,6 @@ i386/i386/busdma_machdep.c standard
i386/i386/db_disasm.c optional ddb
i386/i386/db_interface.c optional ddb
i386/i386/db_trace.c optional ddb
-i386/i386/dump_machdep.c standard
i386/i386/elf_machdep.c standard
i386/i386/exception.s standard
i386/i386/gdb_machdep.c optional gdb
@@ -157,9 +156,6 @@ i386/i386/mp_clock.c optional smp
i386/i386/mp_machdep.c optional smp
i386/i386/mp_watchdog.c optional mp_watchdog smp
i386/i386/mpboot.s optional smp
-i386/i386/mptable.c optional apic
-i386/i386/mptable_pci.c optional apic pci
-i386/i386/nexus.c standard
i386/i386/perfmon.c optional perfmon
i386/i386/pmap.c standard
i386/i386/ptrace_machdep.c standard
@@ -255,7 +251,11 @@ pc98/pc98/pc98_machdep.c standard
x86/isa/atpic.c optional atpic
x86/isa/clock.c standard
x86/isa/isa.c optional isa
+x86/x86/dump_machdep.c standard
x86/x86/io_apic.c optional apic
x86/x86/local_apic.c optional apic
x86/x86/mca.c standard
+x86/x86/mptable.c optional apic
+x86/x86/mptable_pci.c optional apic pci
x86/x86/msi.c optional apic pci
+x86/x86/nexus.c standard
diff --git a/sys/conf/files.powerpc b/sys/conf/files.powerpc
index 0dfe031..021c51d 100644
--- a/sys/conf/files.powerpc
+++ b/sys/conf/files.powerpc
@@ -22,6 +22,7 @@ dev/adb/adb_kbd.c optional adb
dev/adb/adb_mouse.c optional adb
dev/adb/adb_hb_if.m optional adb
dev/adb/adb_if.m optional adb
+dev/agp/agp_apple.c optional agp powermac
dev/cfi/cfi_bus_fdt.c optional cfi fdt
dev/fb/fb.c optional sc
dev/fdt/fdt_powerpc.c optional fdt
diff --git a/sys/conf/kern.post.mk b/sys/conf/kern.post.mk
index c7e6281..80b1bc2 100644
--- a/sys/conf/kern.post.mk
+++ b/sys/conf/kern.post.mk
@@ -169,6 +169,9 @@ _ILINKS= machine
.if ${MACHINE} != ${MACHINE_CPUARCH}
_ILINKS+= ${MACHINE_CPUARCH}
.endif
+.if ${MACHINE_CPUARCH} == "i386" || ${MACHINE_CPUARCH} == "amd64"
+_ILINKS+= x86
+.endif
# Ensure that the link exists without depending on it when it exists.
.for _link in ${_ILINKS}
@@ -181,8 +184,8 @@ ${_ILINKS}:
@case ${.TARGET} in \
machine) \
path=${S}/${MACHINE}/include ;; \
- ${MACHINE_CPUARCH}) \
- path=${S}/${MACHINE_CPUARCH}/include ;; \
+ *) \
+ path=${S}/${.TARGET}/include ;; \
esac ; \
${ECHO} ${.TARGET} "->" $$path ; \
ln -s $$path ${.TARGET}
diff --git a/sys/conf/kmod.mk b/sys/conf/kmod.mk
index de4ba36..2239d66 100644
--- a/sys/conf/kmod.mk
+++ b/sys/conf/kmod.mk
@@ -238,6 +238,9 @@ _ILINKS=@ machine
.if ${MACHINE} != ${MACHINE_CPUARCH}
_ILINKS+=${MACHINE_CPUARCH}
.endif
+.if ${MACHINE_CPUARCH} == "i386" || ${MACHINE_CPUARCH} == "amd64"
+_ILINKS+=x86
+.endif
all: objwarn ${PROG}
@@ -263,12 +266,12 @@ SYSDIR= ${_dir}
${_ILINKS}:
@case ${.TARGET} in \
- ${MACHINE_CPUARCH}) \
- path=${SYSDIR}/${MACHINE_CPUARCH}/include ;; \
machine) \
path=${SYSDIR}/${MACHINE}/include ;; \
@) \
path=${SYSDIR} ;; \
+ *) \
+ path=${SYSDIR}/${.TARGET}/include ;; \
esac ; \
path=`(cd $$path && /bin/pwd)` ; \
${ECHO} ${.TARGET} "->" $$path ; \
diff --git a/sys/conf/options.amd64 b/sys/conf/options.amd64
index 78660e2..1bb60fe 100644
--- a/sys/conf/options.amd64
+++ b/sys/conf/options.amd64
@@ -8,6 +8,7 @@ COUNT_IPIS opt_smp.h
MAXMEM
PERFMON
PMAP_SHPGPERPROC opt_pmap.h
+MPTABLE_FORCE_HTT
MP_WATCHDOG
# Options for emulators. These should only be used at config time, so
diff --git a/sys/conf/options.powerpc b/sys/conf/options.powerpc
index 82a8ffa..b7b3dbb 100644
--- a/sys/conf/options.powerpc
+++ b/sys/conf/options.powerpc
@@ -23,3 +23,7 @@ PSIM
SC_OFWFB opt_ofwfb.h
OFWCONS_POLL_HZ opt_ofw.h
+
+# AGP debugging support
+AGP_DEBUG opt_agp.h
+
diff --git a/sys/dev/acpica/acpi.c b/sys/dev/acpica/acpi.c
index 24982fe..c0f17f6 100644
--- a/sys/dev/acpica/acpi.c
+++ b/sys/dev/acpica/acpi.c
@@ -86,6 +86,11 @@ static struct cdevsw acpi_cdevsw = {
.d_name = "acpi",
};
+struct acpi_interface {
+ ACPI_STRING *data;
+ int num;
+};
+
/* Global mutex for locking access to the ACPI subsystem. */
struct mtx acpi_mutex;
@@ -163,6 +168,7 @@ static void acpi_enable_pcie(void);
#endif
static void acpi_hint_device_unit(device_t acdev, device_t child,
const char *name, int *unitp);
+static void acpi_reset_interfaces(device_t dev);
static device_method_t acpi_methods[] = {
/* Device interface */
@@ -232,6 +238,16 @@ SYSCTL_STRING(_debug_acpi, OID_AUTO, acpi_ca_version, CTLFLAG_RD,
acpi_ca_version, 0, "Version of Intel ACPI-CA");
/*
+ * Allow overriding _OSI methods.
+ */
+static char acpi_install_interface[256];
+TUNABLE_STR("hw.acpi.install_interface", acpi_install_interface,
+ sizeof(acpi_install_interface));
+static char acpi_remove_interface[256];
+TUNABLE_STR("hw.acpi.remove_interface", acpi_remove_interface,
+ sizeof(acpi_remove_interface));
+
+/*
* Allow override of whether methods execute in parallel or not.
* Enable this for serial behavior, which fixes "AE_ALREADY_EXISTS"
* errors for AML that really can't handle parallel method execution.
@@ -467,6 +483,9 @@ acpi_attach(device_t dev)
goto out;
}
+ /* Override OS interfaces if the user requested. */
+ acpi_reset_interfaces(dev);
+
/* Load ACPI name space. */
status = AcpiLoadTables();
if (ACPI_FAILURE(status)) {
@@ -3473,6 +3492,93 @@ acpi_debug_objects_sysctl(SYSCTL_HANDLER_ARGS)
}
static int
+acpi_parse_interfaces(char *str, struct acpi_interface *iface)
+{
+ char *p;
+ size_t len;
+ int i, j;
+
+ p = str;
+ while (isspace(*p) || *p == ',')
+ p++;
+ len = strlen(p);
+ if (len == 0)
+ return (0);
+ p = strdup(p, M_TEMP);
+ for (i = 0; i < len; i++)
+ if (p[i] == ',')
+ p[i] = '\0';
+ i = j = 0;
+ while (i < len)
+ if (isspace(p[i]) || p[i] == '\0')
+ i++;
+ else {
+ i += strlen(p + i) + 1;
+ j++;
+ }
+ if (j == 0) {
+ free(p, M_TEMP);
+ return (0);
+ }
+ iface->data = malloc(sizeof(*iface->data) * j, M_TEMP, M_WAITOK);
+ iface->num = j;
+ i = j = 0;
+ while (i < len)
+ if (isspace(p[i]) || p[i] == '\0')
+ i++;
+ else {
+ iface->data[j] = p + i;
+ i += strlen(p + i) + 1;
+ j++;
+ }
+
+ return (j);
+}
+
+static void
+acpi_free_interfaces(struct acpi_interface *iface)
+{
+
+ free(iface->data[0], M_TEMP);
+ free(iface->data, M_TEMP);
+}
+
+static void
+acpi_reset_interfaces(device_t dev)
+{
+ struct acpi_interface list;
+ ACPI_STATUS status;
+ int i;
+
+ if (acpi_parse_interfaces(acpi_install_interface, &list) > 0) {
+ for (i = 0; i < list.num; i++) {
+ status = AcpiInstallInterface(list.data[i]);
+ if (ACPI_FAILURE(status))
+ device_printf(dev,
+ "failed to install _OSI(\"%s\"): %s\n",
+ list.data[i], AcpiFormatException(status));
+ else if (bootverbose)
+ device_printf(dev, "installed _OSI(\"%s\")\n",
+ list.data[i]);
+ }
+ acpi_free_interfaces(&list);
+ }
+ if (acpi_parse_interfaces(acpi_remove_interface, &list) > 0) {
+ for (i = 0; i < list.num; i++) {
+ status = AcpiRemoveInterface(list.data[i]);
+ if (ACPI_FAILURE(status))
+ device_printf(dev,
+ "failed to remove _OSI(\"%s\"): %s\n",
+ list.data[i], AcpiFormatException(status));
+ else if (bootverbose)
+ device_printf(dev, "removed _OSI(\"%s\")\n",
+ list.data[i]);
+ }
+ acpi_free_interfaces(&list);
+ }
+}
+
+static int
acpi_pm_func(u_long cmd, void *arg, ...)
{
int state, acpi_state;
diff --git a/sys/dev/agp/agp.c b/sys/dev/agp/agp.c
index ab48085..09e2848 100644
--- a/sys/dev/agp/agp.c
+++ b/sys/dev/agp/agp.c
@@ -219,13 +219,16 @@ agp_generic_attach(device_t dev)
* Find and map the aperture, RF_SHAREABLE for DRM but not RF_ACTIVE
* because the kernel doesn't need to map it.
*/
- if (sc->as_aperture_rid == 0)
- sc->as_aperture_rid = AGP_APBASE;
- sc->as_aperture = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
- &sc->as_aperture_rid, RF_SHAREABLE);
- if (!sc->as_aperture)
- return ENOMEM;
+ if (sc->as_aperture_rid != -1) {
+ if (sc->as_aperture_rid == 0)
+ sc->as_aperture_rid = AGP_APBASE;
+
+ sc->as_aperture = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
+ &sc->as_aperture_rid, RF_SHAREABLE);
+ if (!sc->as_aperture)
+ return ENOMEM;
+ }
/*
* Work out an upper bound for agp memory allocation. This
@@ -272,8 +275,9 @@ agp_free_res(device_t dev)
{
struct agp_softc *sc = device_get_softc(dev);
- bus_release_resource(dev, SYS_RES_MEMORY, sc->as_aperture_rid,
- sc->as_aperture);
+ if (sc->as_aperture != NULL)
+ bus_release_resource(dev, SYS_RES_MEMORY, sc->as_aperture_rid,
+ sc->as_aperture);
mtx_destroy(&sc->as_lock);
agp_flush_cache();
}
@@ -729,7 +733,10 @@ agp_info_user(device_t dev, agp_info *info)
info->bridge_id = pci_get_devid(dev);
info->agp_mode =
pci_read_config(dev, agp_find_caps(dev) + AGP_STATUS, 4);
- info->aper_base = rman_get_start(sc->as_aperture);
+ if (sc->as_aperture)
+ info->aper_base = rman_get_start(sc->as_aperture);
+ else
+ info->aper_base = 0;
info->aper_size = AGP_GET_APERTURE(dev) >> 20;
info->pg_total = info->pg_system = sc->as_maxmem >> AGP_PAGE_SHIFT;
info->pg_used = sc->as_allocated >> AGP_PAGE_SHIFT;
@@ -876,6 +883,8 @@ agp_mmap(struct cdev *kdev, vm_ooffset_t offset, vm_paddr_t *paddr,
if (offset > AGP_GET_APERTURE(dev))
return -1;
+ if (sc->as_aperture == NULL)
+ return -1;
*paddr = rman_get_start(sc->as_aperture) + offset;
return 0;
}
@@ -917,8 +926,11 @@ agp_get_info(device_t dev, struct agp_info *info)
info->ai_mode =
pci_read_config(dev, agp_find_caps(dev) + AGP_STATUS, 4);
- info->ai_aperture_base = rman_get_start(sc->as_aperture);
- info->ai_aperture_size = rman_get_size(sc->as_aperture);
+ if (sc->as_aperture != NULL)
+ info->ai_aperture_base = rman_get_start(sc->as_aperture);
+ else
+ info->ai_aperture_base = 0;
+ info->ai_aperture_size = AGP_GET_APERTURE(dev);
info->ai_memory_allowed = sc->as_maxmem;
info->ai_memory_used = sc->as_allocated;
}
diff --git a/sys/dev/agp/agp_apple.c b/sys/dev/agp/agp_apple.c
new file mode 100644
index 0000000..e16e114
--- /dev/null
+++ b/sys/dev/agp/agp_apple.c
@@ -0,0 +1,302 @@
+/*-
+ * Copyright (c) 2010 Nathan Whitehorn
+ * 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 THE AUTHOR AND CONTRIBUTORS ``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 THE AUTHOR 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.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include "opt_bus.h"
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/malloc.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/bus.h>
+#include <sys/lock.h>
+#include <sys/mutex.h>
+#include <sys/proc.h>
+
+#include <machine/resource.h>
+
+#include <dev/agp/agppriv.h>
+#include <dev/agp/agpreg.h>
+#include <dev/pci/pcivar.h>
+#include <dev/pci/pcireg.h>
+
+#include <vm/vm.h>
+#include <vm/vm_object.h>
+#include <vm/pmap.h>
+
+#define UNIN_AGP_GART_BASE 0x8c
+#define UNIN_AGP_BASE_ADDR 0x90
+#define UNIN_AGP_GART_CONTROL 0x94
+
+#define UNIN_AGP_GART_INVAL 0x00000001
+#define UNIN_AGP_GART_ENABLE 0x00000100
+#define UNIN_AGP_GART_2XRESET 0x00010000
+#define UNIN_AGP_U3_GART_PERFRD 0x00080000
+
+struct agp_apple_softc {
+ struct agp_softc agp;
+ uint32_t aperture;
+ struct agp_gatt *gatt;
+ int u3;
+ int needs_2x_reset;
+};
+
+static int
+agp_apple_probe(device_t dev)
+{
+
+ if (resource_disabled("agp", device_get_unit(dev)))
+ return (ENXIO);
+
+ if (pci_get_class(dev) != PCIC_BRIDGE
+ || pci_get_subclass(dev) != PCIS_BRIDGE_HOST)
+ return (ENXIO);
+
+ if (agp_find_caps(dev) == 0)
+ return (ENXIO);
+
+ if (pci_get_class(dev) != PCIC_BRIDGE
+ || pci_get_subclass(dev) != PCIS_BRIDGE_HOST)
+ return (ENXIO);
+
+ switch (pci_get_devid(dev)) {
+ case 0x0020106b:
+ case 0x0027106b:
+ device_set_desc(dev, "Apple UniNorth AGP Bridge");
+ return (BUS_PROBE_DEFAULT);
+ case 0x002d106b:
+ device_set_desc(dev, "Apple UniNorth 1.5 AGP Bridge");
+ return (BUS_PROBE_DEFAULT);
+ case 0x0034106b:
+ device_set_desc(dev, "Apple UniNorth 2 AGP Bridge");
+ return (BUS_PROBE_DEFAULT);
+ case 0x004b106b:
+ case 0x0058106b:
+ case 0x0059106b:
+ device_set_desc(dev, "Apple U3 AGP Bridge");
+ return (BUS_PROBE_DEFAULT);
+ case 0x0066106b:
+ device_set_desc(dev, "Apple Intrepid AGP Bridge");
+ return (BUS_PROBE_DEFAULT);
+ }
+
+ return (ENXIO);
+}
+
+static int
+agp_apple_attach(device_t dev)
+{
+ struct agp_apple_softc *sc = device_get_softc(dev);
+ int error;
+
+ /* Record quirks */
+ sc->needs_2x_reset = 0;
+ sc->u3 = 0;
+ switch (pci_get_devid(dev)) {
+ case 0x0020106b:
+ case 0x0027106b:
+ sc->needs_2x_reset = 1;
+ break;
+ case 0x004b106b:
+ case 0x0058106b:
+ case 0x0059106b:
+ sc->u3 = 1;
+ break;
+ }
+
+ /* Set the aperture bus address base (must be 0) */
+ pci_write_config(dev, UNIN_AGP_BASE_ADDR, 0, 4);
+ agp_set_aperture_resource(dev, -1);
+
+ error = agp_generic_attach(dev);
+ if (error)
+ return (error);
+
+ sc->aperture = 256*1024*1024;
+
+ for (sc->aperture = 256*1024*1024; sc->aperture >= 4*1024*1024;
+ sc->aperture /= 2) {
+ sc->gatt = agp_alloc_gatt(dev);
+ if (sc->gatt)
+ break;
+ }
+ if (sc->aperture < 4*1024*1024) {
+ agp_generic_detach(dev);
+ return ENOMEM;
+ }
+
+ /* Install the gatt. */
+ AGP_SET_APERTURE(dev, sc->aperture);
+
+ /* XXX: U3 scratch page? */
+
+ /* Enable the aperture and TLB. */
+ AGP_FLUSH_TLB(dev);
+
+ return (0);
+}
+
+static int
+agp_apple_detach(device_t dev)
+{
+ struct agp_apple_softc *sc = device_get_softc(dev);
+
+ agp_free_cdev(dev);
+
+ /* Disable the aperture and TLB */
+ pci_write_config(dev, UNIN_AGP_GART_CONTROL, UNIN_AGP_GART_INVAL, 4);
+ pci_write_config(dev, UNIN_AGP_GART_CONTROL, 0, 4);
+
+ if (sc->needs_2x_reset) {
+ pci_write_config(dev, UNIN_AGP_GART_CONTROL,
+ UNIN_AGP_GART_2XRESET, 4);
+ pci_write_config(dev, UNIN_AGP_GART_CONTROL, 0, 4);
+ }
+
+ AGP_SET_APERTURE(dev, 0);
+
+ agp_free_gatt(sc->gatt);
+ agp_free_res(dev);
+ return 0;
+}
+
+static uint32_t
+agp_apple_get_aperture(device_t dev)
+{
+ struct agp_apple_softc *sc = device_get_softc(dev);
+
+ return (sc->aperture);
+}
+
+static int
+agp_apple_set_aperture(device_t dev, uint32_t aperture)
+{
+ struct agp_apple_softc *sc = device_get_softc(dev);
+
+ /*
+ * Check for a multiple of 4 MB and make sure it is within the
+ * programmable range.
+ */
+ if (aperture % (4*1024*1024)
+ || aperture < 4*1024*1024
+ || aperture > ((sc->u3) ? 512 : 256)*1024*1024)
+ return EINVAL;
+
+ /* The aperture value is a multiple of 4 MB */
+ aperture /= (4*1024*1024);
+
+ pci_write_config(dev, UNIN_AGP_GART_BASE,
+ (sc->gatt->ag_physical & 0xfffff000) | aperture, 4);
+
+ return (0);
+}
+
+static int
+agp_apple_bind_page(device_t dev, vm_offset_t offset, vm_offset_t physical)
+{
+ struct agp_apple_softc *sc = device_get_softc(dev);
+
+ if (offset >= (sc->gatt->ag_entries << AGP_PAGE_SHIFT))
+ return EINVAL;
+
+ sc->gatt->ag_virtual[offset >> AGP_PAGE_SHIFT] = physical;
+ __asm __volatile("dcbst 0,%0; sync" ::
+ "r"(&sc->gatt->ag_virtual[offset >> AGP_PAGE_SHIFT]) : "memory");
+ return (0);
+}
+
+static int
+agp_apple_unbind_page(device_t dev, vm_offset_t offset)
+{
+ struct agp_apple_softc *sc = device_get_softc(dev);
+
+ if (offset >= (sc->gatt->ag_entries << AGP_PAGE_SHIFT))
+ return EINVAL;
+
+ sc->gatt->ag_virtual[offset >> AGP_PAGE_SHIFT] = 0;
+ __asm __volatile("dcbst 0,%0; sync" ::
+ "r"(&sc->gatt->ag_virtual[offset >> AGP_PAGE_SHIFT]) : "memory");
+ return (0);
+}
+
+static void
+agp_apple_flush_tlb(device_t dev)
+{
+ struct agp_apple_softc *sc = device_get_softc(dev);
+ uint32_t cntrl = UNIN_AGP_GART_ENABLE;
+
+ if (sc->u3)
+ cntrl |= UNIN_AGP_U3_GART_PERFRD;
+
+ pci_write_config(dev, UNIN_AGP_GART_CONTROL,
+ cntrl | UNIN_AGP_GART_INVAL, 4);
+ pci_write_config(dev, UNIN_AGP_GART_CONTROL, cntrl, 4);
+
+ if (sc->needs_2x_reset) {
+ pci_write_config(dev, UNIN_AGP_GART_CONTROL,
+ cntrl | UNIN_AGP_GART_2XRESET, 4);
+ pci_write_config(dev, UNIN_AGP_GART_CONTROL, cntrl, 4);
+ }
+}
+
+static device_method_t agp_apple_methods[] = {
+ /* Device interface */
+ DEVMETHOD(device_probe, agp_apple_probe),
+ DEVMETHOD(device_attach, agp_apple_attach),
+ DEVMETHOD(device_detach, agp_apple_detach),
+ DEVMETHOD(device_shutdown, bus_generic_shutdown),
+ DEVMETHOD(device_suspend, bus_generic_suspend),
+ DEVMETHOD(device_resume, bus_generic_resume),
+
+ /* AGP interface */
+ DEVMETHOD(agp_get_aperture, agp_apple_get_aperture),
+ DEVMETHOD(agp_set_aperture, agp_apple_set_aperture),
+ DEVMETHOD(agp_bind_page, agp_apple_bind_page),
+ DEVMETHOD(agp_unbind_page, agp_apple_unbind_page),
+ DEVMETHOD(agp_flush_tlb, agp_apple_flush_tlb),
+ DEVMETHOD(agp_enable, agp_generic_enable),
+ DEVMETHOD(agp_alloc_memory, agp_generic_alloc_memory),
+ DEVMETHOD(agp_free_memory, agp_generic_free_memory),
+ DEVMETHOD(agp_bind_memory, agp_generic_bind_memory),
+ DEVMETHOD(agp_unbind_memory, agp_generic_unbind_memory),
+
+ { 0, 0 }
+};
+
+static driver_t agp_apple_driver = {
+ "agp",
+ agp_apple_methods,
+ sizeof(struct agp_apple_softc),
+};
+
+static devclass_t agp_devclass;
+
+DRIVER_MODULE(agp_apple, hostb, agp_apple_driver, agp_devclass, 0, 0);
+MODULE_DEPEND(agp_apple, agp, 1, 1, 1);
+MODULE_DEPEND(agp_apple, pci, 1, 1, 1);
diff --git a/sys/dev/alc/if_alc.c b/sys/dev/alc/if_alc.c
index 5f0f7ec..aee0e10 100644
--- a/sys/dev/alc/if_alc.c
+++ b/sys/dev/alc/if_alc.c
@@ -331,8 +331,8 @@ alc_miibus_statchg(device_t dev)
reg = CSR_READ_4(sc, ALC_MAC_CFG);
reg |= MAC_CFG_TX_ENB | MAC_CFG_RX_ENB;
CSR_WRITE_4(sc, ALC_MAC_CFG, reg);
+ alc_aspm(sc, IFM_SUBTYPE(mii->mii_media_active));
}
- alc_aspm(sc, IFM_SUBTYPE(mii->mii_media_active));
}
static void
diff --git a/sys/dev/bge/if_bge.c b/sys/dev/bge/if_bge.c
index 63c4c5d..59ce673 100644
--- a/sys/dev/bge/if_bge.c
+++ b/sys/dev/bge/if_bge.c
@@ -169,6 +169,8 @@ static const struct bge_type {
{ BCOM_VENDORID, BCOM_DEVICEID_BCM5714S },
{ BCOM_VENDORID, BCOM_DEVICEID_BCM5715 },
{ BCOM_VENDORID, BCOM_DEVICEID_BCM5715S },
+ { BCOM_VENDORID, BCOM_DEVICEID_BCM5717 },
+ { BCOM_VENDORID, BCOM_DEVICEID_BCM5718 },
{ BCOM_VENDORID, BCOM_DEVICEID_BCM5720 },
{ BCOM_VENDORID, BCOM_DEVICEID_BCM5721 },
{ BCOM_VENDORID, BCOM_DEVICEID_BCM5722 },
@@ -289,6 +291,8 @@ static const struct bge_revision {
{ BGE_CHIPID_BCM5715_A0, "BCM5715 A0" },
{ BGE_CHIPID_BCM5715_A1, "BCM5715 A1" },
{ BGE_CHIPID_BCM5715_A3, "BCM5715 A3" },
+ { BGE_CHIPID_BCM5717_A0, "BCM5717 A0" },
+ { BGE_CHIPID_BCM5717_B0, "BCM5717 B0" },
{ BGE_CHIPID_BCM5755_A0, "BCM5755 A0" },
{ BGE_CHIPID_BCM5755_A1, "BCM5755 A1" },
{ BGE_CHIPID_BCM5755_A2, "BCM5755 A2" },
@@ -332,6 +336,7 @@ static const struct bge_revision bge_majorrevs[] = {
{ BGE_ASICREV_BCM5787, "unknown BCM5754/5787" },
{ BGE_ASICREV_BCM5906, "unknown BCM5906" },
{ BGE_ASICREV_BCM57780, "unknown BCM57780" },
+ { BGE_ASICREV_BCM5717, "unknown BCM5717" },
{ 0, NULL }
};
@@ -342,6 +347,7 @@ static const struct bge_revision bge_majorrevs[] = {
#define BGE_IS_5714_FAMILY(sc) ((sc)->bge_flags & BGE_FLAG_5714_FAMILY)
#define BGE_IS_575X_PLUS(sc) ((sc)->bge_flags & BGE_FLAG_575X_PLUS)
#define BGE_IS_5755_PLUS(sc) ((sc)->bge_flags & BGE_FLAG_5755_PLUS)
+#define BGE_IS_5717_PLUS(sc) ((sc)->bge_flags & BGE_FLAG_5717_PLUS)
const struct bge_revision * bge_lookup_rev(uint32_t);
const struct bge_vendor * bge_lookup_vendor(uint16_t);
@@ -367,6 +373,7 @@ static int bge_get_eaddr_eeprom(struct bge_softc *, uint8_t[]);
static int bge_get_eaddr(struct bge_softc *, uint8_t[]);
static void bge_txeof(struct bge_softc *, uint16_t);
+static void bge_rxcsum(struct bge_softc *, struct bge_rx_bd *, struct mbuf *);
static int bge_rxeof(struct bge_softc *, uint16_t, int);
static void bge_asf_driver_up (struct bge_softc *);
@@ -376,7 +383,7 @@ static void bge_stats_update(struct bge_softc *);
static void bge_stats_update_regs(struct bge_softc *);
static struct mbuf *bge_check_short_dma(struct mbuf *);
static struct mbuf *bge_setup_tso(struct bge_softc *, struct mbuf *,
- uint16_t *);
+ uint16_t *, uint16_t *);
static int bge_encap(struct bge_softc *, struct mbuf **, uint32_t *);
static void bge_intr(void *);
@@ -1349,12 +1356,15 @@ bge_stop_fw(struct bge_softc *sc)
static int
bge_chipinit(struct bge_softc *sc)
{
- uint32_t dma_rw_ctl;
+ uint32_t dma_rw_ctl, misc_ctl;
uint16_t val;
int i;
/* Set endianness before we access any non-PCI registers. */
- pci_write_config(sc->bge_dev, BGE_PCI_MISC_CTL, BGE_INIT, 4);
+ misc_ctl = BGE_INIT;
+ if (sc->bge_flags & BGE_FLAG_TAGGED_STATUS)
+ misc_ctl |= BGE_PCIMISCCTL_TAGGED_STATUS;
+ pci_write_config(sc->bge_dev, BGE_PCI_MISC_CTL, misc_ctl, 4);
/* Clear the MAC control register */
CSR_WRITE_4(sc, BGE_MAC_MODE, 0);
@@ -1446,6 +1456,8 @@ bge_chipinit(struct bge_softc *sc)
if (sc->bge_asicrev == BGE_ASICREV_BCM5703 ||
sc->bge_asicrev == BGE_ASICREV_BCM5704)
dma_rw_ctl &= ~BGE_PCIDMARWCTL_MINDMA;
+ if (BGE_IS_5717_PLUS(sc))
+ dma_rw_ctl &= ~BGE_PCIDMARWCTL_DIS_CACHE_ALIGNMENT;
pci_write_config(sc->bge_dev, BGE_PCI_DMA_RW_CTL, dma_rw_ctl, 4);
/*
@@ -1529,7 +1541,16 @@ bge_blockinit(struct bge_softc *sc)
}
/* Configure mbuf pool watermarks */
- if (!BGE_IS_5705_PLUS(sc)) {
+ if (sc->bge_asicrev == BGE_ASICREV_BCM5717) {
+ CSR_WRITE_4(sc, BGE_BMAN_MBUFPOOL_READDMA_LOWAT, 0x0);
+ if (sc->bge_ifp->if_mtu > ETHERMTU) {
+ CSR_WRITE_4(sc, BGE_BMAN_MBUFPOOL_MACRX_LOWAT, 0x7e);
+ CSR_WRITE_4(sc, BGE_BMAN_MBUFPOOL_HIWAT, 0xea);
+ } else {
+ CSR_WRITE_4(sc, BGE_BMAN_MBUFPOOL_MACRX_LOWAT, 0x2a);
+ CSR_WRITE_4(sc, BGE_BMAN_MBUFPOOL_HIWAT, 0xa0);
+ }
+ } else if (!BGE_IS_5705_PLUS(sc)) {
CSR_WRITE_4(sc, BGE_BMAN_MBUFPOOL_READDMA_LOWAT, 0x50);
CSR_WRITE_4(sc, BGE_BMAN_MBUFPOOL_MACRX_LOWAT, 0x20);
CSR_WRITE_4(sc, BGE_BMAN_MBUFPOOL_HIWAT, 0x60);
@@ -1621,7 +1642,16 @@ bge_blockinit(struct bge_softc *sc)
BGE_ADDR_HI(sc->bge_ldata.bge_rx_std_ring_paddr);
bus_dmamap_sync(sc->bge_cdata.bge_rx_std_ring_tag,
sc->bge_cdata.bge_rx_std_ring_map, BUS_DMASYNC_PREREAD);
- if (BGE_IS_5705_PLUS(sc)) {
+ if (BGE_IS_5717_PLUS(sc)) {
+ /*
+ * Bits 31-16: Programmable ring size (2048, 1024, 512, .., 32)
+ * Bits 15-2 : Maximum RX frame size
+ * Bit 1 : 1 = Ring Disabled, 0 = Ring ENabled
+ * Bit 0 : Reserved
+ */
+ rcb->bge_maxlen_flags =
+ BGE_RCB_MAXLEN_FLAGS(512, BGE_MAX_FRAMELEN << 2);
+ } else if (BGE_IS_5705_PLUS(sc)) {
/*
* Bits 31-16: Programmable ring size (512, 256, 128, 64, 32)
* Bits 15-2 : Reserved (should be 0)
@@ -1640,7 +1670,10 @@ bge_blockinit(struct bge_softc *sc)
rcb->bge_maxlen_flags =
BGE_RCB_MAXLEN_FLAGS(BGE_MAX_FRAMELEN, 0);
}
- rcb->bge_nicaddr = BGE_STD_RX_RINGS;
+ if (sc->bge_asicrev == BGE_ASICREV_BCM5717)
+ rcb->bge_nicaddr = BGE_STD_RX_RINGS_5717;
+ else
+ rcb->bge_nicaddr = BGE_STD_RX_RINGS;
/* Write the standard receive producer ring control block. */
CSR_WRITE_4(sc, BGE_RX_STD_RCB_HADDR_HI, rcb->bge_hostaddr.bge_addr_hi);
CSR_WRITE_4(sc, BGE_RX_STD_RCB_HADDR_LO, rcb->bge_hostaddr.bge_addr_lo);
@@ -1669,7 +1702,10 @@ bge_blockinit(struct bge_softc *sc)
BUS_DMASYNC_PREREAD);
rcb->bge_maxlen_flags = BGE_RCB_MAXLEN_FLAGS(0,
BGE_RCB_FLAG_USE_EXT_RX_BD | BGE_RCB_FLAG_RING_DISABLED);
- rcb->bge_nicaddr = BGE_JUMBO_RX_RINGS;
+ if (sc->bge_asicrev == BGE_ASICREV_BCM5717)
+ rcb->bge_nicaddr = BGE_JUMBO_RX_RINGS_5717;
+ else
+ rcb->bge_nicaddr = BGE_JUMBO_RX_RINGS;
CSR_WRITE_4(sc, BGE_RX_JUMBO_RCB_HADDR_HI,
rcb->bge_hostaddr.bge_addr_hi);
CSR_WRITE_4(sc, BGE_RX_JUMBO_RCB_HADDR_LO,
@@ -1726,6 +1762,10 @@ bge_blockinit(struct bge_softc *sc)
if (BGE_IS_JUMBO_CAPABLE(sc))
CSR_WRITE_4(sc, BGE_RBDI_JUMBO_REPL_THRESH,
BGE_JUMBO_RX_RING_CNT/8);
+ if (BGE_IS_5717_PLUS(sc)) {
+ CSR_WRITE_4(sc, BGE_STD_REPLENISH_LWM, 32);
+ CSR_WRITE_4(sc, BGE_JMB_REPLENISH_LWM, 16);
+ }
/*
* Disable all send rings by setting the 'ring disabled' bit
@@ -1750,8 +1790,11 @@ bge_blockinit(struct bge_softc *sc)
BGE_HOSTADDR(taddr, sc->bge_ldata.bge_tx_ring_paddr);
RCB_WRITE_4(sc, vrcb, bge_hostaddr.bge_addr_hi, taddr.bge_addr_hi);
RCB_WRITE_4(sc, vrcb, bge_hostaddr.bge_addr_lo, taddr.bge_addr_lo);
- RCB_WRITE_4(sc, vrcb, bge_nicaddr,
- BGE_NIC_TXRING_ADDR(0, BGE_TX_RING_CNT));
+ if (sc->bge_asicrev == BGE_ASICREV_BCM5717)
+ RCB_WRITE_4(sc, vrcb, bge_nicaddr, BGE_SEND_RING_5717);
+ else
+ RCB_WRITE_4(sc, vrcb, bge_nicaddr,
+ BGE_NIC_TXRING_ADDR(0, BGE_TX_RING_CNT));
RCB_WRITE_4(sc, vrcb, bge_maxlen_flags,
BGE_RCB_MAXLEN_FLAGS(BGE_TX_RING_CNT, 0));
@@ -1760,7 +1803,10 @@ bge_blockinit(struct bge_softc *sc)
* 'ring diabled' bit in the flags field of all the receive
* return ring control blocks, located in NIC memory.
*/
- if (!BGE_IS_5705_PLUS(sc))
+ if (sc->bge_asicrev == BGE_ASICREV_BCM5717) {
+ /* Should be 17, use 16 until we get an SRAM map. */
+ limit = 16;
+ } else if (!BGE_IS_5705_PLUS(sc))
limit = BGE_RX_RINGS_MAX;
else if (sc->bge_asicrev == BGE_ASICREV_BCM5755)
limit = 4;
@@ -1936,6 +1982,10 @@ bge_blockinit(struct bge_softc *sc)
/* Turn on read DMA state machine */
val = BGE_RDMAMODE_ENABLE | BGE_RDMAMODE_ALL_ATTNS;
+
+ if (sc->bge_asicrev == BGE_ASICREV_BCM5717)
+ val |= BGE_RDMAMODE_MULT_DMA_RD_DIS;
+
if (sc->bge_asicrev == BGE_ASICREV_BCM5784 ||
sc->bge_asicrev == BGE_ASICREV_BCM5785 ||
sc->bge_asicrev == BGE_ASICREV_BCM57780)
@@ -1944,16 +1994,18 @@ bge_blockinit(struct bge_softc *sc)
BGE_RDMAMODE_MBUF_SBD_CRPT_ATTN;
if (sc->bge_flags & BGE_FLAG_PCIE)
val |= BGE_RDMAMODE_FIFO_LONG_BURST;
- if (sc->bge_flags & BGE_FLAG_TSO) {
+ if (sc->bge_flags & (BGE_FLAG_TSO | BGE_FLAG_TSO3)) {
val |= BGE_RDMAMODE_TSO4_ENABLE;
- if (sc->bge_asicrev == BGE_ASICREV_BCM5785 ||
+ if (sc->bge_flags & BGE_FLAG_TSO3 ||
+ sc->bge_asicrev == BGE_ASICREV_BCM5785 ||
sc->bge_asicrev == BGE_ASICREV_BCM57780)
val |= BGE_RDMAMODE_TSO6_ENABLE;
}
if (sc->bge_asicrev == BGE_ASICREV_BCM5761 ||
sc->bge_asicrev == BGE_ASICREV_BCM5784 ||
sc->bge_asicrev == BGE_ASICREV_BCM5785 ||
- sc->bge_asicrev == BGE_ASICREV_BCM57780) {
+ sc->bge_asicrev == BGE_ASICREV_BCM57780 ||
+ BGE_IS_5717_PLUS(sc)) {
/*
* Enable fix for read DMA FIFO overruns.
* The fix is to limit the number of RX BDs
@@ -1989,8 +2041,9 @@ bge_blockinit(struct bge_softc *sc)
CSR_WRITE_4(sc, BGE_SDC_MODE, val);
/* Turn on send data initiator state machine */
- if (sc->bge_flags & BGE_FLAG_TSO)
- CSR_WRITE_4(sc, BGE_SDI_MODE, BGE_SDIMODE_ENABLE | 0x08);
+ if (sc->bge_flags & (BGE_FLAG_TSO | BGE_FLAG_TSO3))
+ CSR_WRITE_4(sc, BGE_SDI_MODE, BGE_SDIMODE_ENABLE |
+ BGE_SDIMODE_HW_LSO_PRE_DMA);
else
CSR_WRITE_4(sc, BGE_SDI_MODE, BGE_SDIMODE_ENABLE);
@@ -2104,9 +2157,22 @@ bge_probe(device_t dev)
id = pci_read_config(dev, BGE_PCI_MISC_CTL, 4) >>
BGE_PCIMISCCTL_ASICREV_SHIFT;
- if (BGE_ASICREV(id) == BGE_ASICREV_USE_PRODID_REG)
- id = pci_read_config(dev,
- BGE_PCI_PRODID_ASICREV, 4);
+ if (BGE_ASICREV(id) == BGE_ASICREV_USE_PRODID_REG) {
+ /*
+ * Find the ASCI revision. Different chips
+ * use different registers.
+ */
+ switch (pci_get_device(dev)) {
+ case BCOM_DEVICEID_BCM5717:
+ case BCOM_DEVICEID_BCM5718:
+ id = pci_read_config(dev,
+ BGE_PCI_GEN2_PRODID_ASICREV, 4);
+ break;
+ default:
+ id = pci_read_config(dev,
+ BGE_PCI_PRODID_ASICREV, 4);
+ }
+ }
br = bge_lookup_rev(id);
v = bge_lookup_vendor(vid);
{
@@ -2423,7 +2489,7 @@ bge_dma_alloc(struct bge_softc *sc)
return (ENOMEM);
}
/* Create tag for Tx mbufs. */
- if (sc->bge_flags & BGE_FLAG_TSO) {
+ if (sc->bge_flags & (BGE_FLAG_TSO | BGE_FLAG_TSO3)) {
txsegsz = BGE_TSOSEG_SZ;
txmaxsegsz = 65535 + sizeof(struct ether_vlan_header);
} else {
@@ -2539,6 +2605,10 @@ bge_can_use_msi(struct bge_softc *sc)
{
int can_use_msi = 0;
+ /* Disable MSI for polling(4). */
+#ifdef DEVICE_POLLING
+ return (0);
+#endif
switch (sc->bge_asicrev) {
case BGE_ASICREV_BCM5714_A0:
case BGE_ASICREV_BCM5714:
@@ -2568,7 +2638,7 @@ bge_attach(device_t dev)
struct bge_softc *sc;
uint32_t hwcfg = 0, misccfg;
u_char eaddr[ETHER_ADDR_LEN];
- int error, msicount, phy_addr, reg, rid, trys;
+ int error, f, msicount, phy_addr, reg, rid, trys;
sc = device_get_softc(dev);
sc->bge_dev = dev;
@@ -2594,14 +2664,55 @@ bge_attach(device_t dev)
sc->bge_chipid =
pci_read_config(dev, BGE_PCI_MISC_CTL, 4) >>
BGE_PCIMISCCTL_ASICREV_SHIFT;
- if (BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_USE_PRODID_REG)
- sc->bge_chipid = pci_read_config(dev, BGE_PCI_PRODID_ASICREV,
- 4);
+ if (BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_USE_PRODID_REG) {
+ /*
+ * Find the ASCI revision. Different chips use different
+ * registers.
+ */
+ switch (pci_get_device(dev)) {
+ case BCOM_DEVICEID_BCM5717:
+ case BCOM_DEVICEID_BCM5718:
+ sc->bge_chipid = pci_read_config(dev,
+ BGE_PCI_GEN2_PRODID_ASICREV, 4);
+ break;
+ default:
+ sc->bge_chipid = pci_read_config(dev,
+ BGE_PCI_PRODID_ASICREV, 4);
+ }
+ }
sc->bge_asicrev = BGE_ASICREV(sc->bge_chipid);
sc->bge_chiprev = BGE_CHIPREV(sc->bge_chipid);
/* Set default PHY address. */
phy_addr = 1;
+ /*
+ * PHY address mapping for various devices.
+ *
+ * | F0 Cu | F0 Sr | F1 Cu | F1 Sr |
+ * ---------+-------+-------+-------+-------+
+ * BCM57XX | 1 | X | X | X |
+ * BCM5704 | 1 | X | 1 | X |
+ * BCM5717 | 1 | 8 | 2 | 9 |
+ *
+ * Other addresses may respond but they are not
+ * IEEE compliant PHYs and should be ignored.
+ */
+ if (sc->bge_asicrev == BGE_ASICREV_BCM5717) {
+ f = pci_get_function(dev);
+ if (sc->bge_chipid == BGE_CHIPID_BCM5717_A0) {
+ if (CSR_READ_4(sc, BGE_SGDIG_STS) &
+ BGE_SGDIGSTS_IS_SERDES)
+ phy_addr = f + 8;
+ else
+ phy_addr = f + 1;
+ } else if (sc->bge_chipid == BGE_CHIPID_BCM5717_B0) {
+ if (CSR_READ_4(sc, BGE_CPMU_PHY_STRAP) &
+ BGE_CPMU_PHY_STRAP_IS_SERDES)
+ phy_addr = f + 8;
+ else
+ phy_addr = f + 1;
+ }
+ }
/*
* Don't enable Ethernet@WireSpeed for the 5700, 5906, or the
@@ -2610,7 +2721,8 @@ bge_attach(device_t dev)
if (sc->bge_asicrev != BGE_ASICREV_BCM5700 &&
sc->bge_asicrev != BGE_ASICREV_BCM5906 &&
sc->bge_chipid != BGE_CHIPID_BCM5705_A0 &&
- sc->bge_chipid != BGE_CHIPID_BCM5705_A1)
+ sc->bge_chipid != BGE_CHIPID_BCM5705_A1 &&
+ !BGE_IS_5717_PLUS(sc))
sc->bge_phy_flags |= BGE_PHY_WIRESPEED;
if (bge_has_eaddr(sc))
@@ -2618,6 +2730,11 @@ bge_attach(device_t dev)
/* Save chipset family. */
switch (sc->bge_asicrev) {
+ case BGE_ASICREV_BCM5717:
+ sc->bge_flags |= BGE_FLAG_5717_PLUS | BGE_FLAG_5755_PLUS |
+ BGE_FLAG_575X_PLUS | BGE_FLAG_5705_PLUS | BGE_FLAG_JUMBO |
+ BGE_FLAG_SHORT_DMA_BUG | BGE_FLAG_JUMBO_FRAME;
+ break;
case BGE_ASICREV_BCM5755:
case BGE_ASICREV_BCM5761:
case BGE_ASICREV_BCM5784:
@@ -2663,6 +2780,7 @@ bge_attach(device_t dev)
sc->bge_phy_flags |= BGE_PHY_NO_3LED;
if ((BGE_IS_5705_PLUS(sc)) &&
sc->bge_asicrev != BGE_ASICREV_BCM5906 &&
+ sc->bge_asicrev != BGE_ASICREV_BCM5717 &&
sc->bge_asicrev != BGE_ASICREV_BCM5785 &&
sc->bge_asicrev != BGE_ASICREV_BCM57780) {
if (sc->bge_asicrev == BGE_ASICREV_BCM5755 ||
@@ -2679,7 +2797,8 @@ bge_attach(device_t dev)
}
/* Identify the chips that use an CPMU. */
- if (sc->bge_asicrev == BGE_ASICREV_BCM5784 ||
+ if (BGE_IS_5717_PLUS(sc) ||
+ sc->bge_asicrev == BGE_ASICREV_BCM5784 ||
sc->bge_asicrev == BGE_ASICREV_BCM5761 ||
sc->bge_asicrev == BGE_ASICREV_BCM5785 ||
sc->bge_asicrev == BGE_ASICREV_BCM57780)
@@ -2722,7 +2841,10 @@ bge_attach(device_t dev)
* the TSO to the controllers that are not affected TSO issues
* (e.g. 5755 or higher).
*/
- if (BGE_IS_5755_PLUS(sc)) {
+ if (BGE_IS_5717_PLUS(sc)) {
+ /* BCM5717 requires different TSO configuration. */
+ sc->bge_flags |= BGE_FLAG_TSO3;
+ } else if (BGE_IS_5755_PLUS(sc)) {
/*
* BCM5754 and BCM5787 shares the same ASIC id so
* explicit device id check is required.
@@ -2785,6 +2907,16 @@ bge_attach(device_t dev)
}
}
+ /*
+ * All controllers except BCM5700 supports tagged status but
+ * we use tagged status only for MSI case on BCM5717. Otherwise
+ * MSI on BCM5717 does not work.
+ */
+#ifndef DEVICE_POLLING
+ if (sc->bge_flags & BGE_FLAG_MSI && BGE_IS_5717_PLUS(sc))
+ sc->bge_flags |= BGE_FLAG_TAGGED_STATUS;
+#endif
+
sc->bge_irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
RF_SHAREABLE | RF_ACTIVE);
@@ -2848,7 +2980,9 @@ bge_attach(device_t dev)
}
/* 5705 limits RX return ring to 512 entries. */
- if (BGE_IS_5705_PLUS(sc))
+ if (BGE_IS_5717_PLUS(sc))
+ sc->bge_return_ring_cnt = BGE_RETURN_RING_CNT;
+ else if (BGE_IS_5705_PLUS(sc))
sc->bge_return_ring_cnt = BGE_RETURN_RING_CNT_5705;
else
sc->bge_return_ring_cnt = BGE_RETURN_RING_CNT;
@@ -2893,7 +3027,7 @@ bge_attach(device_t dev)
ifp->if_hwassist = sc->bge_csum_features;
ifp->if_capabilities = IFCAP_HWCSUM | IFCAP_VLAN_HWTAGGING |
IFCAP_VLAN_MTU;
- if ((sc->bge_flags & BGE_FLAG_TSO) != 0) {
+ if ((sc->bge_flags & (BGE_FLAG_TSO | BGE_FLAG_TSO3)) != 0) {
ifp->if_hwassist |= CSUM_TSO;
ifp->if_capabilities |= IFCAP_TSO4 | IFCAP_VLAN_HWTSO;
}
@@ -3340,6 +3474,7 @@ bge_reset(struct bge_softc *sc)
/* XXX: Broadcom Linux driver. */
if (sc->bge_flags & BGE_FLAG_PCIE &&
+ sc->bge_asicrev != BGE_ASICREV_BCM5717 &&
sc->bge_chipid != BGE_CHIPID_BCM5750_A0 &&
sc->bge_asicrev != BGE_ASICREV_BCM5785) {
/* Enable Data FIFO protection. */
@@ -3480,20 +3615,8 @@ bge_rxeof(struct bge_softc *sc, uint16_t rx_prod, int holdlck)
m->m_pkthdr.len = m->m_len = cur_rx->bge_len - ETHER_CRC_LEN;
m->m_pkthdr.rcvif = ifp;
- if (ifp->if_capenable & IFCAP_RXCSUM) {
- if (cur_rx->bge_flags & BGE_RXBDFLAG_IP_CSUM) {
- m->m_pkthdr.csum_flags |= CSUM_IP_CHECKED;
- if ((cur_rx->bge_ip_csum ^ 0xFFFF) == 0)
- m->m_pkthdr.csum_flags |= CSUM_IP_VALID;
- }
- if (cur_rx->bge_flags & BGE_RXBDFLAG_TCP_UDP_CSUM &&
- m->m_pkthdr.len >= ETHER_MIN_NOPAD) {
- m->m_pkthdr.csum_data =
- cur_rx->bge_tcp_udp_csum;
- m->m_pkthdr.csum_flags |=
- CSUM_DATA_VALID | CSUM_PSEUDO_HDR;
- }
- }
+ if (ifp->if_capenable & IFCAP_RXCSUM)
+ bge_rxcsum(sc, cur_rx, m);
/*
* If we received a packet with a vlan tag,
@@ -3552,6 +3675,41 @@ bge_rxeof(struct bge_softc *sc, uint16_t rx_prod, int holdlck)
}
static void
+bge_rxcsum(struct bge_softc *sc, struct bge_rx_bd *cur_rx, struct mbuf *m)
+{
+
+ if (BGE_IS_5717_PLUS(sc)) {
+ if ((cur_rx->bge_flags & BGE_RXBDFLAG_IPV6) == 0) {
+ if (cur_rx->bge_flags & BGE_RXBDFLAG_IP_CSUM) {
+ m->m_pkthdr.csum_flags |= CSUM_IP_CHECKED;
+ if ((cur_rx->bge_error_flag &
+ BGE_RXERRFLAG_IP_CSUM_NOK) == 0)
+ m->m_pkthdr.csum_flags |= CSUM_IP_VALID;
+ }
+ if (cur_rx->bge_flags & BGE_RXBDFLAG_TCP_UDP_CSUM) {
+ m->m_pkthdr.csum_data =
+ cur_rx->bge_tcp_udp_csum;
+ m->m_pkthdr.csum_flags |= CSUM_DATA_VALID |
+ CSUM_PSEUDO_HDR;
+ }
+ }
+ } else {
+ if (cur_rx->bge_flags & BGE_RXBDFLAG_IP_CSUM) {
+ m->m_pkthdr.csum_flags |= CSUM_IP_CHECKED;
+ if ((cur_rx->bge_ip_csum ^ 0xFFFF) == 0)
+ m->m_pkthdr.csum_flags |= CSUM_IP_VALID;
+ }
+ if (cur_rx->bge_flags & BGE_RXBDFLAG_TCP_UDP_CSUM &&
+ m->m_pkthdr.len >= ETHER_MIN_NOPAD) {
+ m->m_pkthdr.csum_data =
+ cur_rx->bge_tcp_udp_csum;
+ m->m_pkthdr.csum_flags |= CSUM_DATA_VALID |
+ CSUM_PSEUDO_HDR;
+ }
+ }
+}
+
+static void
bge_txeof(struct bge_softc *sc, uint16_t tx_cons)
{
struct bge_tx_bd *cur_tx;
@@ -3668,7 +3826,7 @@ bge_intr_task(void *arg, int pending)
{
struct bge_softc *sc;
struct ifnet *ifp;
- uint32_t status;
+ uint32_t status, status_tag;
uint16_t rx_prod, tx_cons;
sc = (struct bge_softc *)arg;
@@ -3689,16 +3847,19 @@ bge_intr_task(void *arg, int pending)
rx_prod = sc->bge_ldata.bge_status_block->bge_idx[0].bge_rx_prod_idx;
tx_cons = sc->bge_ldata.bge_status_block->bge_idx[0].bge_tx_cons_idx;
status = sc->bge_ldata.bge_status_block->bge_status;
+ status_tag = sc->bge_ldata.bge_status_block->bge_status_tag << 24;
sc->bge_ldata.bge_status_block->bge_status = 0;
bus_dmamap_sync(sc->bge_cdata.bge_status_tag,
sc->bge_cdata.bge_status_map,
BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
+ if ((sc->bge_flags & BGE_FLAG_TAGGED_STATUS) == 0)
+ status_tag = 0;
if ((status & BGE_STATFLAG_LINKSTATE_CHANGED) != 0)
bge_link_upd(sc);
/* Let controller work. */
- bge_writembx(sc, BGE_MBX_IRQ0_LO, 0);
+ bge_writembx(sc, BGE_MBX_IRQ0_LO, status_tag);
if (ifp->if_drv_flags & IFF_DRV_RUNNING &&
sc->bge_rx_saved_considx != rx_prod) {
@@ -4104,7 +4265,8 @@ bge_check_short_dma(struct mbuf *m)
}
static struct mbuf *
-bge_setup_tso(struct bge_softc *sc, struct mbuf *m, uint16_t *mss)
+bge_setup_tso(struct bge_softc *sc, struct mbuf *m, uint16_t *mss,
+ uint16_t *flags)
{
struct ip *ip;
struct tcphdr *tcp;
@@ -4147,14 +4309,30 @@ bge_setup_tso(struct bge_softc *sc, struct mbuf *m, uint16_t *mss)
* Broadcom controllers uses different descriptor format for
* TSO depending on ASIC revision. Due to TSO-capable firmware
* license issue and lower performance of firmware based TSO
- * we only support hardware based TSO which is applicable for
- * BCM5755 or newer controllers. Hardware based TSO uses 11
- * bits to store MSS and upper 5 bits are used to store IP/TCP
- * header length(including IP/TCP options). The header length
- * is expressed as 32 bits unit.
+ * we only support hardware based TSO.
*/
+ /* Calculate header length, incl. TCP/IP options, in 32 bit units. */
hlen = ((ip->ip_hl << 2) + (tcp->th_off << 2)) >> 2;
- *mss |= (hlen << 11);
+ if (sc->bge_flags & BGE_FLAG_TSO3) {
+ /*
+ * For BCM5717 and newer controllers, hardware based TSO
+ * uses the 14 lower bits of the bge_mss field to store the
+ * MSS and the upper 2 bits to store the lowest 2 bits of
+ * the IP/TCP header length. The upper 6 bits of the header
+ * length are stored in the bge_flags[14:10,4] field. Jumbo
+ * frames are supported.
+ */
+ *mss |= ((hlen & 0x3) << 14);
+ *flags |= ((hlen & 0xF8) << 7) | ((hlen & 0x4) << 2);
+ } else {
+ /*
+ * For BCM5755 and newer controllers, hardware based TSO uses
+ * the lower 11 bits to store the MSS and the upper 5 bits to
+ * store the IP/TCP header length. Jumbo frames are not
+ * supported.
+ */
+ *mss |= (hlen << 11);
+ }
return (m);
}
@@ -4184,7 +4362,7 @@ bge_encap(struct bge_softc *sc, struct mbuf **m_head, uint32_t *txidx)
m = *m_head;
}
if ((m->m_pkthdr.csum_flags & CSUM_TSO) != 0) {
- *m_head = m = bge_setup_tso(sc, m, &mss);
+ *m_head = m = bge_setup_tso(sc, m, &mss, &csum_flags);
if (*m_head == NULL)
return (ENOBUFS);
csum_flags |= BGE_TXBDFLAG_CPU_PRE_DMA |
@@ -4207,21 +4385,26 @@ bge_encap(struct bge_softc *sc, struct mbuf **m_head, uint32_t *txidx)
csum_flags |= BGE_TXBDFLAG_IP_FRAG;
}
- if ((m->m_pkthdr.csum_flags & CSUM_TSO) == 0 &&
- sc->bge_forced_collapse > 0 &&
- (sc->bge_flags & BGE_FLAG_PCIE) != 0 && m->m_next != NULL) {
- /*
- * Forcedly collapse mbuf chains to overcome hardware
- * limitation which only support a single outstanding
- * DMA read operation.
- */
- if (sc->bge_forced_collapse == 1)
- m = m_defrag(m, M_DONTWAIT);
- else
- m = m_collapse(m, M_DONTWAIT, sc->bge_forced_collapse);
- if (m == NULL)
- m = *m_head;
- *m_head = m;
+ if ((m->m_pkthdr.csum_flags & CSUM_TSO) == 0) {
+ if (sc->bge_flags & BGE_FLAG_JUMBO_FRAME &&
+ m->m_pkthdr.len > ETHER_MAX_LEN)
+ csum_flags |= BGE_TXBDFLAG_JUMBO_FRAME;
+ if (sc->bge_forced_collapse > 0 &&
+ (sc->bge_flags & BGE_FLAG_PCIE) != 0 && m->m_next != NULL) {
+ /*
+ * Forcedly collapse mbuf chains to overcome hardware
+ * limitation which only support a single outstanding
+ * DMA read operation.
+ */
+ if (sc->bge_forced_collapse == 1)
+ m = m_defrag(m, M_DONTWAIT);
+ else
+ m = m_collapse(m, M_DONTWAIT,
+ sc->bge_forced_collapse);
+ if (m == NULL)
+ m = *m_head;
+ *m_head = m;
+ }
}
map = sc->bge_cdata.bge_tx_dmamap[idx];
diff --git a/sys/dev/bge/if_bgereg.h b/sys/dev/bge/if_bgereg.h
index a50bf59..6a9c2e8 100644
--- a/sys/dev/bge/if_bgereg.h
+++ b/sys/dev/bge/if_bgereg.h
@@ -82,6 +82,7 @@
#define BGE_UNMAPPED_END 0x00001FFF
#define BGE_DMA_DESCRIPTORS 0x00002000
#define BGE_DMA_DESCRIPTORS_END 0x00003FFF
+#define BGE_SEND_RING_5717 0x00004000
#define BGE_SEND_RING_1_TO_4 0x00004000
#define BGE_SEND_RING_1_TO_4_END 0x00005FFF
@@ -100,6 +101,8 @@
#define BGE_BUFFPOOL_2_END 0x00017FFF
#define BGE_BUFFPOOL_3 0x00018000 /* or expansion ROM */
#define BGE_BUFFPOOL_3_END 0x0001FFFF
+#define BGE_STD_RX_RINGS_5717 0x00040000
+#define BGE_JUMBO_RX_RINGS_5717 0x00044400
/* Mappings for external SSRAM configurations */
#define BGE_SEND_RING_5_TO_6 0x00006000
@@ -219,6 +222,7 @@
#define BGE_PCI_ISR_MBX_HI 0xB0
#define BGE_PCI_ISR_MBX_LO 0xB4
#define BGE_PCI_PRODID_ASICREV 0xBC
+#define BGE_PCI_GEN2_PRODID_ASICREV 0xF4
/* PCI Misc. Host control register */
#define BGE_PCIMISCCTL_CLEAR_INTA 0x00000001
@@ -229,6 +233,7 @@
#define BGE_PCIMISCCTL_CLOCKCTL_RW 0x00000020
#define BGE_PCIMISCCTL_REG_WORDSWAP 0x00000040
#define BGE_PCIMISCCTL_INDIRECT_ACCESS 0x00000080
+#define BGE_PCIMISCCTL_TAGGED_STATUS 0x00000200
#define BGE_PCIMISCCTL_ASICREV 0xFFFF0000
#define BGE_PCIMISCCTL_ASICREV_SHIFT 16
@@ -311,6 +316,8 @@
#define BGE_CHIPID_BCM5906_A2 0xc002
#define BGE_CHIPID_BCM57780_A0 0x57780000
#define BGE_CHIPID_BCM57780_A1 0x57780001
+#define BGE_CHIPID_BCM5717_A0 0x05717000
+#define BGE_CHIPID_BCM5717_B0 0x05717100
/* shorthand one */
#define BGE_ASICREV(x) ((x) >> 12)
@@ -331,6 +338,7 @@
/* Should consult BGE_PCI_PRODID_ASICREV for ChipID */
#define BGE_ASICREV_USE_PRODID_REG 0x0f
/* BGE_PCI_PRODID_ASICREV ASIC rev. identifiers. */
+#define BGE_ASICREV_BCM5717 0x5717
#define BGE_ASICREV_BCM5761 0x5761
#define BGE_ASICREV_BCM5784 0x5784
#define BGE_ASICREV_BCM5785 0x5785
@@ -348,11 +356,14 @@
#define BGE_CHIPREV_5750_AX 0x40
#define BGE_CHIPREV_5750_BX 0x41
/* BGE_PCI_PRODID_ASICREV chip rev. identifiers. */
+#define BGE_CHIPREV_5717_AX 0x57170
+#define BGE_CHIPREV_5717_BX 0x57171
#define BGE_CHIPREV_5761_AX 0x57611
#define BGE_CHIPREV_5784_AX 0x57841
/* PCI DMA Read/Write Control register */
#define BGE_PCIDMARWCTL_MINDMA 0x000000FF
+#define BGE_PCIDMARWCTL_DIS_CACHE_ALIGNMENT 0x00000001
#define BGE_PCIDMARWCTL_RDADRR_BNDRY 0x00000700
#define BGE_PCIDMARWCTL_WRADDR_BNDRY 0x00003800
#define BGE_PCIDMARWCTL_ONEDMA_ATONCE 0x0000C000
@@ -566,6 +577,7 @@
#define BGE_TX_RINGS_MAX 4
#define BGE_TX_RINGS_EXTSSRAM_MAX 16
#define BGE_RX_RINGS_MAX 16
+#define BGE_RX_RINGS_MAX_5717 17
/* Ethernet MAC control registers */
#define BGE_MAC_MODE 0x0400
@@ -843,9 +855,10 @@
#define BGE_SGDIGCFG_AUTO 0x80000000
/* SGDIG status (not documented) */
+#define BGE_SGDIGSTS_DONE 0x00000002
+#define BGE_SGDIGSTS_IS_SERDES 0x00000100
#define BGE_SGDIGSTS_PAUSE_CAP 0x00080000
#define BGE_SGDIGSTS_ASYM_PAUSE 0x00100000
-#define BGE_SGDIGSTS_DONE 0x00000002
/* MI communication register */
@@ -911,6 +924,7 @@
#define BGE_SDIMODE_RESET 0x00000001
#define BGE_SDIMODE_ENABLE 0x00000002
#define BGE_SDIMODE_STATS_OFLOW_ATTN 0x00000004
+#define BGE_SDIMODE_HW_LSO_PRE_DMA 0x00000008
/* Send Data Initiator stats register */
#define BGE_SDISTAT_STATS_OFLOW_ATTN 0x00000004
@@ -1188,6 +1202,9 @@
#define BGE_RBDI_STD_REPL_THRESH 0x2C18
#define BGE_RBDI_JUMBO_REPL_THRESH 0x2C1C
+#define BGE_STD_REPLENISH_LWM 0x2D00
+#define BGE_JMB_REPLENISH_LWM 0x2D04
+
/* Receive BD Initiator Mode register */
#define BGE_RBDIMODE_RESET 0x00000001
#define BGE_RBDIMODE_ENABLE 0x00000002
@@ -1501,6 +1518,7 @@
#define BGE_RDMAMODE_MBUF_SBD_CRPT_ATTN 0x00002000
#define BGE_RDMAMODE_FIFO_SIZE_128 0x00020000
#define BGE_RDMAMODE_FIFO_LONG_BURST 0x00030000
+#define BGE_RDMAMODE_MULT_DMA_RD_DIS 0x01000000
#define BGE_RDMAMODE_TSO4_ENABLE 0x08000000
#define BGE_RDMAMODE_TSO6_ENABLE 0x10000000
@@ -2068,15 +2086,27 @@ struct bge_tx_bd {
#define BGE_TXBDFLAG_IP_CSUM 0x0002
#define BGE_TXBDFLAG_END 0x0004
#define BGE_TXBDFLAG_IP_FRAG 0x0008
+#define BGE_TXBDFLAG_JUMBO_FRAME 0x0008 /* 5717 */
#define BGE_TXBDFLAG_IP_FRAG_END 0x0010
+#define BGE_TXBDFLAG_HDRLEN_BIT2 0x0010 /* 5717 */
+#define BGE_TXBDFLAG_SNAP 0x0020 /* 5717 */
#define BGE_TXBDFLAG_VLAN_TAG 0x0040
#define BGE_TXBDFLAG_COAL_NOW 0x0080
#define BGE_TXBDFLAG_CPU_PRE_DMA 0x0100
#define BGE_TXBDFLAG_CPU_POST_DMA 0x0200
+#define BGE_TXBDFLAG_HDRLEN_BIT3 0x0400 /* 5717 */
+#define BGE_TXBDFLAG_HDRLEN_BIT4 0x0800 /* 5717 */
#define BGE_TXBDFLAG_INSERT_SRC_ADDR 0x1000
+#define BGE_TXBDFLAG_HDRLEN_BIT5 0x1000 /* 5717 */
+#define BGE_TXBDFLAG_HDRLEN_BIT6 0x2000 /* 5717 */
+#define BGE_TXBDFLAG_HDRLEN_BIT7 0x4000 /* 5717 */
#define BGE_TXBDFLAG_CHOOSE_SRC_ADDR 0x6000
#define BGE_TXBDFLAG_NO_CRC 0x8000
+#define BGE_TXBDFLAG_MSS_SIZE_MASK 0x3FFF /* 5717 */
+/* Bits [1:0] of the MSS header length. */
+#define BGE_TXBDFLAG_MSS_HDRLEN_MASK 0xC000 /* 5717 */
+
#define BGE_NIC_TXRING_ADDR(ringno, size) \
BGE_SEND_RING_1_TO_4 + \
((ringno * sizeof(struct bge_tx_bd) * size) / 4)
@@ -2153,6 +2183,7 @@ struct bge_extrx_bd {
#define BGE_RXBDFLAG_IP_CSUM 0x1000
#define BGE_RXBDFLAG_TCP_UDP_CSUM 0x2000
#define BGE_RXBDFLAG_TCP_UDP_IS_TCP 0x4000
+#define BGE_RXBDFLAG_IPV6 0x8000
#define BGE_RXERRFLAG_BAD_CRC 0x0001
#define BGE_RXERRFLAG_COLL_DETECT 0x0002
@@ -2162,6 +2193,7 @@ struct bge_extrx_bd {
#define BGE_RXERRFLAG_RUNT 0x0020
#define BGE_RXERRFLAG_TRUNC_NO_RSRCS 0x0040
#define BGE_RXERRFLAG_GIANT 0x0080
+#define BGE_RXERRFLAG_IP_CSUM_NOK 0x1000 /* 5717 */
struct bge_sts_idx {
#if BYTE_ORDER == LITTLE_ENDIAN
@@ -2175,7 +2207,7 @@ struct bge_sts_idx {
struct bge_status_block {
uint32_t bge_status;
- uint32_t bge_rsvd0;
+ uint32_t bge_status_tag;
#if BYTE_ORDER == LITTLE_ENDIAN
uint16_t bge_rx_jumbo_cons_idx;
uint16_t bge_rx_std_cons_idx;
@@ -2221,6 +2253,8 @@ struct bge_status_block {
#define BCOM_DEVICEID_BCM5714S 0x1669
#define BCOM_DEVICEID_BCM5715 0x1678
#define BCOM_DEVICEID_BCM5715S 0x1679
+#define BCOM_DEVICEID_BCM5717 0x1655
+#define BCOM_DEVICEID_BCM5718 0x1656
#define BCOM_DEVICEID_BCM5720 0x1658
#define BCOM_DEVICEID_BCM5721 0x1659
#define BCOM_DEVICEID_BCM5722 0x165A
@@ -2717,16 +2751,20 @@ struct bge_softc {
#define BGE_FLAG_EADDR 0x00000008
#define BGE_FLAG_MII_SERDES 0x00000010
#define BGE_FLAG_CPMU_PRESENT 0x00000020
+#define BGE_FLAG_TAGGED_STATUS 0x00000040
#define BGE_FLAG_MSI 0x00000100
#define BGE_FLAG_PCIX 0x00000200
#define BGE_FLAG_PCIE 0x00000400
#define BGE_FLAG_TSO 0x00000800
+#define BGE_FLAG_TSO3 0x00001000
+#define BGE_FLAG_JUMBO_FRAME 0x00002000
#define BGE_FLAG_5700_FAMILY 0x00010000
#define BGE_FLAG_5705_PLUS 0x00020000
#define BGE_FLAG_5714_FAMILY 0x00040000
#define BGE_FLAG_575X_PLUS 0x00080000
#define BGE_FLAG_5755_PLUS 0x00100000
#define BGE_FLAG_5788 0x00200000
+#define BGE_FLAG_5717_PLUS 0x00400000
#define BGE_FLAG_40BIT_BUG 0x01000000
#define BGE_FLAG_4G_BNDRY_BUG 0x02000000
#define BGE_FLAG_RX_ALIGNBUG 0x04000000
diff --git a/sys/dev/e1000/e1000_82571.c b/sys/dev/e1000/e1000_82571.c
index 3554dbe..5e12c49 100644
--- a/sys/dev/e1000/e1000_82571.c
+++ b/sys/dev/e1000/e1000_82571.c
@@ -666,10 +666,15 @@ static void e1000_put_hw_semaphore_82573(struct e1000_hw *hw)
**/
static s32 e1000_get_hw_semaphore_82574(struct e1000_hw *hw)
{
+ s32 ret_val;
+
DEBUGFUNC("e1000_get_hw_semaphore_82574");
E1000_MUTEX_LOCK(&hw->dev_spec._82571.swflag_mutex);
- return e1000_get_hw_semaphore_82573(hw);
+ ret_val = e1000_get_hw_semaphore_82573(hw);
+ if (ret_val)
+ E1000_MUTEX_UNLOCK(&hw->dev_spec._82571.swflag_mutex);
+ return ret_val;
}
/**
diff --git a/sys/dev/e1000/if_em.c b/sys/dev/e1000/if_em.c
index af6100a..c41e144 100644
--- a/sys/dev/e1000/if_em.c
+++ b/sys/dev/e1000/if_em.c
@@ -93,8 +93,7 @@ int em_display_debug_stats = 0;
/*********************************************************************
* Driver version:
*********************************************************************/
-char em_driver_version[] = "7.0.8";
-
+char em_driver_version[] = "7.1.7";
/*********************************************************************
* PCI Device ID Table
@@ -170,6 +169,8 @@ static em_vendor_info_t em_vendor_info_array[] =
{ 0x8086, E1000_DEV_ID_PCH_M_HV_LC, PCI_ANY_ID, PCI_ANY_ID, 0},
{ 0x8086, E1000_DEV_ID_PCH_D_HV_DM, PCI_ANY_ID, PCI_ANY_ID, 0},
{ 0x8086, E1000_DEV_ID_PCH_D_HV_DC, PCI_ANY_ID, PCI_ANY_ID, 0},
+ { 0x8086, E1000_DEV_ID_PCH2_LV_LM, PCI_ANY_ID, PCI_ANY_ID, 0},
+ { 0x8086, E1000_DEV_ID_PCH2_LV_V, PCI_ANY_ID, PCI_ANY_ID, 0},
/* required last entry */
{ 0, 0, 0, 0, 0}
};
@@ -256,6 +257,8 @@ static int em_dma_malloc(struct adapter *, bus_size_t,
static void em_dma_free(struct adapter *, struct em_dma_alloc *);
static int em_sysctl_nvm_info(SYSCTL_HANDLER_ARGS);
static void em_print_nvm_info(struct adapter *);
+static int em_sysctl_debug_info(SYSCTL_HANDLER_ARGS);
+static void em_print_debug_info(struct adapter *);
static int em_is_valid_ether_addr(u8 *);
static int em_sysctl_int_delay(SYSCTL_HANDLER_ARGS);
static void em_add_int_delay_sysctl(struct adapter *, const char *,
@@ -282,6 +285,8 @@ static void em_handle_link(void *context, int pending);
static void em_add_rx_process_limit(struct adapter *, const char *,
const char *, int *, int);
+static void em_set_flow_cntrl(struct adapter *, const char *,
+ const char *, int *, int);
static __inline void em_rx_discard(struct rx_ring *, int);
@@ -359,14 +364,6 @@ TUNABLE_INT("hw.em.rx_process_limit", &em_rx_process_limit);
static int em_fc_setting = e1000_fc_full;
TUNABLE_INT("hw.em.fc_setting", &em_fc_setting);
-/*
-** Shadow VFTA table, this is needed because
-** the real vlan filter table gets cleared during
-** a soft reset and the driver needs to be able
-** to repopulate it.
-*/
-static u32 em_shadow_vfta[EM_VFTA_SIZE];
-
/* Global used in WOL setup with multiport cards */
static int global_quad_port_a = 0;
@@ -449,6 +446,11 @@ em_attach(device_t dev)
OID_AUTO, "nvm", CTLTYPE_INT|CTLFLAG_RW, adapter, 0,
em_sysctl_nvm_info, "I", "NVM Information");
+ SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev),
+ SYSCTL_CHILDREN(device_get_sysctl_tree(dev)),
+ OID_AUTO, "debug", CTLTYPE_INT|CTLFLAG_RW, adapter, 0,
+ em_sysctl_debug_info, "I", "Debug Information");
+
callout_init_mtx(&adapter->timer, &adapter->core_mtx, 0);
/* Determine hardware and mac info */
@@ -468,9 +470,10 @@ em_attach(device_t dev)
** identified
*/
if ((adapter->hw.mac.type == e1000_ich8lan) ||
- (adapter->hw.mac.type == e1000_pchlan) ||
(adapter->hw.mac.type == e1000_ich9lan) ||
- (adapter->hw.mac.type == e1000_ich10lan)) {
+ (adapter->hw.mac.type == e1000_ich10lan) ||
+ (adapter->hw.mac.type == e1000_pchlan) ||
+ (adapter->hw.mac.type == e1000_pch2lan)) {
int rid = EM_BAR_TYPE_FLASH;
adapter->flash = bus_alloc_resource_any(dev,
SYS_RES_MEMORY, &rid, RF_ACTIVE);
@@ -514,11 +517,16 @@ em_attach(device_t dev)
E1000_REGISTER(&adapter->hw, E1000_TADV),
em_tx_abs_int_delay_dflt);
- /* Sysctls for limiting the amount of work done in the taskqueue */
+ /* Sysctl for limiting the amount of work done in the taskqueue */
em_add_rx_process_limit(adapter, "rx_processing_limit",
"max number of rx packets to process", &adapter->rx_process_limit,
em_rx_process_limit);
+ /* Sysctl for setting the interface flow control */
+ em_set_flow_cntrl(adapter, "flow_control",
+ "max number of rx packets to process",
+ &adapter->fc_setting, em_fc_setting);
+
/*
* Validate number of transmit and receive descriptors. It
* must not exceed hardware maximum, and must be multiple
@@ -581,6 +589,11 @@ em_attach(device_t dev)
goto err_late;
}
+ /* Check SOL/IDER usage */
+ if (e1000_check_reset_block(&adapter->hw))
+ device_printf(dev, "PHY reset is blocked"
+ " due to SOL/IDER session.\n");
+
/*
** Start from a known state, this is
** important in reading the nvm and
@@ -644,11 +657,6 @@ em_attach(device_t dev)
adapter->hw.mac.get_link_status = 1;
em_update_link_status(adapter);
- /* Indicate SOL/IDER usage */
- if (e1000_check_reset_block(&adapter->hw))
- device_printf(dev,
- "PHY reset is blocked due to SOL/IDER session.\n");
-
/* Register for VLAN events */
adapter->vlan_attach = EVENTHANDLER_REGISTER(vlan_config,
em_register_vlan, adapter, EVENTHANDLER_PRI_FIRST);
@@ -857,7 +865,7 @@ em_mq_start_locked(struct ifnet *ifp, struct tx_ring *txr, struct mbuf *m)
if (enq > 0) {
/* Set the watchdog */
- txr->watchdog_check = TRUE;
+ txr->queue_status = EM_QUEUE_WORKING;
txr->watchdog_time = ticks;
}
return (err);
@@ -870,14 +878,8 @@ static int
em_mq_start(struct ifnet *ifp, struct mbuf *m)
{
struct adapter *adapter = ifp->if_softc;
- struct tx_ring *txr;
- int i = 0, error = 0;
-
- /* Which queue to use */
- if ((m->m_flags & M_FLOWID) != 0)
- i = m->m_pkthdr.flowid % adapter->num_queues;
-
- txr = &adapter->tx_rings[i];
+ struct tx_ring *txr = adapter->tx_rings;
+ int error;
if (EM_TX_TRYLOCK(txr)) {
error = em_mq_start_locked(ifp, txr, m);
@@ -953,7 +955,7 @@ em_start_locked(struct ifnet *ifp, struct tx_ring *txr)
/* Set timeout in case hardware has problems transmitting. */
txr->watchdog_time = ticks;
- txr->watchdog_check = TRUE;
+ txr->queue_status = EM_QUEUE_WORKING;
}
return;
@@ -1029,6 +1031,7 @@ em_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
case e1000_82572:
case e1000_ich9lan:
case e1000_ich10lan:
+ case e1000_pch2lan:
case e1000_82574:
case e1000_80003es2lan: /* 9K Jumbo Frame size */
max_frame_size = 9234;
@@ -1092,6 +1095,11 @@ em_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
}
break;
case SIOCSIFMEDIA:
+ /*
+ ** As the speed/duplex settings are being
+ ** changed, we need to reset the PHY.
+ */
+ adapter->hw.phy.reset_disable = FALSE;
/* Check SOL/IDER usage */
EM_CORE_LOCK(adapter);
if (e1000_check_reset_block(&adapter->hw)) {
@@ -1101,6 +1109,7 @@ em_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
break;
}
EM_CORE_UNLOCK(adapter);
+ /* falls thru */
case SIOCGIFMEDIA:
IOCTL_DEBUGOUT("ioctl rcv'd: \
SIOCxIFMEDIA (Get/Set Interface Media)");
@@ -1215,13 +1224,16 @@ em_init_locked(struct adapter *adapter)
case e1000_82583:
pba = E1000_PBA_20K; /* 20K for Rx, 20K for Tx */
break;
+ case e1000_ich8lan:
+ pba = E1000_PBA_8K;
+ break;
case e1000_ich9lan:
case e1000_ich10lan:
case e1000_pchlan:
pba = E1000_PBA_10K;
break;
- case e1000_ich8lan:
- pba = E1000_PBA_8K;
+ case e1000_pch2lan:
+ pba = E1000_PBA_26K;
break;
default:
if (adapter->max_frame_size > 8192)
@@ -1259,19 +1271,6 @@ em_init_locked(struct adapter *adapter)
/* Setup VLAN support, basic and offload if available */
E1000_WRITE_REG(&adapter->hw, E1000_VET, ETHERTYPE_VLAN);
- /* Use real VLAN Filter support? */
- if (ifp->if_capenable & IFCAP_VLAN_HWTAGGING) {
- if (ifp->if_capenable & IFCAP_VLAN_HWFILTER)
- /* Use real VLAN Filter support */
- em_setup_vlan_hw_support(adapter);
- else {
- u32 ctrl;
- ctrl = E1000_READ_REG(&adapter->hw, E1000_CTRL);
- ctrl |= E1000_CTRL_VME;
- E1000_WRITE_REG(&adapter->hw, E1000_CTRL, ctrl);
- }
- }
-
/* Set hardware offload abilities */
ifp->if_hwassist = 0;
if (ifp->if_capenable & IFCAP_TXCSUM)
@@ -1289,6 +1288,17 @@ em_init_locked(struct adapter *adapter)
/* Setup Multicast table */
em_set_multi(adapter);
+ /*
+ ** Figure out the desired mbuf
+ ** pool for doing jumbos
+ */
+ if (adapter->max_frame_size <= 2048)
+ adapter->rx_mbuf_sz = MCLBYTES;
+ else if (adapter->max_frame_size <= 4096)
+ adapter->rx_mbuf_sz = MJUMPAGESIZE;
+ else
+ adapter->rx_mbuf_sz = MJUM9BYTES;
+
/* Prepare receive descriptors and buffers */
if (em_setup_receive_structures(adapter)) {
device_printf(dev, "Could not setup receive structures\n");
@@ -1297,6 +1307,19 @@ em_init_locked(struct adapter *adapter)
}
em_initialize_receive_unit(adapter);
+ /* Use real VLAN Filter support? */
+ if (ifp->if_capenable & IFCAP_VLAN_HWTAGGING) {
+ if (ifp->if_capenable & IFCAP_VLAN_HWFILTER)
+ /* Use real VLAN Filter support */
+ em_setup_vlan_hw_support(adapter);
+ else {
+ u32 ctrl;
+ ctrl = E1000_READ_REG(&adapter->hw, E1000_CTRL);
+ ctrl |= E1000_CTRL_VME;
+ E1000_WRITE_REG(&adapter->hw, E1000_CTRL, ctrl);
+ }
+ }
+
/* Don't lose promiscuous settings */
em_set_promisc(adapter);
@@ -1707,11 +1730,6 @@ em_media_change(struct ifnet *ifp)
device_printf(adapter->dev, "Unsupported media type\n");
}
- /* As the speed/duplex settings my have changed we need to
- * reset the PHY.
- */
- adapter->hw.phy.reset_disable = FALSE;
-
em_init_locked(adapter);
EM_CORE_UNLOCK(adapter);
@@ -1748,19 +1766,6 @@ em_xmit(struct tx_ring *txr, struct mbuf **m_headp)
ip_off = poff = 0;
/*
- ** When doing checksum offload, it is critical to
- ** make sure the first mbuf has more than header,
- ** because that routine expects data to be present.
- */
- if ((m_head->m_pkthdr.csum_flags & CSUM_OFFLOAD) &&
- (m_head->m_len < ETHER_HDR_LEN + sizeof(struct ip))) {
- m_head = m_pullup(m_head, ETHER_HDR_LEN + sizeof(struct ip));
- *m_headp = m_head;
- if (m_head == NULL)
- return (ENOBUFS);
- }
-
- /*
* Intel recommends entire IP/TCP header length reside in a single
* buffer. If multiple descriptors are used to describe the IP and
* TCP header, each descriptor should describe one or more
@@ -1830,6 +1835,7 @@ em_xmit(struct tx_ring *txr, struct mbuf **m_headp)
*m_headp = NULL;
return (ENOBUFS);
}
+ ip = (struct ip *)(mtod(m_head, char *) + ip_off);
ip->ip_len = 0;
ip->ip_sum = 0;
/*
@@ -1838,6 +1844,7 @@ em_xmit(struct tx_ring *txr, struct mbuf **m_headp)
* what hardware expect to see. This is adherence of
* Microsoft's Large Send specification.
*/
+ tp = (struct tcphdr *)(mtod(m_head, char *) + poff);
tp->th_sum = in_pseudo(ip->ip_src.s_addr,
ip->ip_dst.s_addr, htons(IPPROTO_TCP));
} else if (m_head->m_pkthdr.csum_flags & CSUM_TCP) {
@@ -1847,12 +1854,15 @@ em_xmit(struct tx_ring *txr, struct mbuf **m_headp)
*m_headp = NULL;
return (ENOBUFS);
}
+ ip = (struct ip *)(mtod(m_head, char *) + ip_off);
+ tp = (struct tcphdr *)(mtod(m_head, char *) + poff);
} else if (m_head->m_pkthdr.csum_flags & CSUM_UDP) {
m_head = m_pullup(m_head, poff + sizeof(struct udphdr));
if (m_head == NULL) {
*m_headp = NULL;
return (ENOBUFS);
}
+ ip = (struct ip *)(mtod(m_head, char *) + ip_off);
}
*m_headp = m_head;
}
@@ -1929,15 +1939,12 @@ em_xmit(struct tx_ring *txr, struct mbuf **m_headp)
m_head = *m_headp;
/* Do hardware assists */
-#if __FreeBSD_version >= 700000
if (m_head->m_pkthdr.csum_flags & CSUM_TSO) {
- em_tso_setup(txr, m_head, ip_off, ip, tp, &txd_upper,
- &txd_lower);
+ em_tso_setup(txr, m_head, ip_off, ip, tp,
+ &txd_upper, &txd_lower);
/* we need to make a final sentinel transmit desc */
tso_desc = TRUE;
- } else
-#endif
- if (m_head->m_pkthdr.csum_flags & CSUM_OFFLOAD)
+ } else if (m_head->m_pkthdr.csum_flags & CSUM_OFFLOAD)
em_transmit_checksum_setup(txr, m_head,
ip_off, ip, &txd_upper, &txd_lower);
@@ -2164,34 +2171,30 @@ em_local_timer(void *arg)
em_update_stats_counters(adapter);
/* Reset LAA into RAR[0] on 82571 */
- if (e1000_get_laa_state_82571(&adapter->hw) == TRUE)
+ if ((adapter->hw.mac.type == e1000_82571) &&
+ e1000_get_laa_state_82571(&adapter->hw))
e1000_rar_set(&adapter->hw, adapter->hw.mac.addr, 0);
/*
- ** If flow control has paused us since last checking
- ** it invalidates the watchdog timing, so dont run it.
+ ** Don't do TX watchdog check if we've been paused
*/
if (adapter->pause_frames) {
adapter->pause_frames = 0;
goto out;
}
/*
- ** Check for time since any descriptor was cleaned
+ ** Check on the state of the TX queue(s), this
+ ** can be done without the lock because its RO
+ ** and the HUNG state will be static if set.
*/
- for (int i = 0; i < adapter->num_queues; i++, txr++) {
- EM_TX_LOCK(txr);
- if (txr->watchdog_check == FALSE) {
- EM_TX_UNLOCK(txr);
- continue;
- }
- if ((ticks - txr->watchdog_time) > EM_WATCHDOG)
+ for (int i = 0; i < adapter->num_queues; i++, txr++)
+ if (txr->queue_status == EM_QUEUE_HUNG)
goto hung;
- EM_TX_UNLOCK(txr);
- }
out:
callout_reset(&adapter->timer, hz, em_local_timer, adapter);
return;
hung:
+ /* Looks like we're hung */
device_printf(adapter->dev, "Watchdog timeout -- resetting\n");
device_printf(adapter->dev,
"Queue(%d) tdh = %d, hw tdt = %d\n", txr->me,
@@ -2272,7 +2275,7 @@ em_update_link_status(struct adapter *adapter)
adapter->link_active = 0;
/* Link down, disable watchdog */
for (int i = 0; i < adapter->num_queues; i++, txr++)
- txr->watchdog_check = FALSE;
+ txr->queue_status = EM_QUEUE_IDLE;
if_link_state_change(ifp, LINK_STATE_DOWN);
}
}
@@ -2306,7 +2309,7 @@ em_stop(void *arg)
/* Unarm watchdog timer. */
for (int i = 0; i < adapter->num_queues; i++, txr++) {
EM_TX_LOCK(txr);
- txr->watchdog_check = FALSE;
+ txr->queue_status = EM_QUEUE_IDLE;
EM_TX_UNLOCK(txr);
}
@@ -2571,6 +2574,9 @@ em_free_pci_resources(struct adapter *adapter)
for (int i = 0; i < adapter->num_queues; i++) {
txr = &adapter->tx_rings[i];
rxr = &adapter->rx_rings[i];
+ /* an early abort? */
+ if ((txr == NULL) || (rxr == NULL))
+ break;
rid = txr->msix +1;
if (txr->tag != NULL) {
bus_teardown_intr(dev, txr->res, txr->tag);
@@ -2689,6 +2695,7 @@ static void
em_reset(struct adapter *adapter)
{
device_t dev = adapter->dev;
+ struct ifnet *ifp = adapter->ifp;
struct e1000_hw *hw = &adapter->hw;
u16 rx_buffer_size;
@@ -2733,15 +2740,25 @@ em_reset(struct adapter *adapter)
hw->fc.send_xon = TRUE;
/* Set Flow control, use the tunable location if sane */
- if ((em_fc_setting >= 0) || (em_fc_setting < 4))
- hw->fc.requested_mode = em_fc_setting;
- else
- hw->fc.requested_mode = e1000_fc_none;
+ hw->fc.requested_mode = adapter->fc_setting;
- /* Override - workaround for PCHLAN issue */
+ /* Workaround: no TX flow ctrl for PCH */
if (hw->mac.type == e1000_pchlan)
hw->fc.requested_mode = e1000_fc_rx_pause;
+ /* Override - settings for PCH2LAN, ya its magic :) */
+ if (hw->mac.type == e1000_pch2lan) {
+ hw->fc.high_water = 0x5C20;
+ hw->fc.low_water = 0x5048;
+ hw->fc.pause_time = 0x0650;
+ hw->fc.refresh_time = 0x0400;
+ /* Jumbos need adjusted PBA */
+ if (ifp->if_mtu > ETHERMTU)
+ E1000_WRITE_REG(hw, E1000_PBA, 12);
+ else
+ E1000_WRITE_REG(hw, E1000_PBA, 26);
+ }
+
/* Issue a global reset */
e1000_reset_hw(hw);
E1000_WRITE_REG(hw, E1000_WUC, 0);
@@ -3173,6 +3190,7 @@ em_setup_transmit_ring(struct tx_ring *txr)
/* Set number of descriptors available */
txr->tx_avail = adapter->num_tx_desc;
+ txr->queue_status = EM_QUEUE_IDLE;
/* Clear checksum offload context. */
txr->last_hw_offload = 0;
@@ -3233,7 +3251,7 @@ em_initialize_transmit_unit(struct adapter *adapter)
E1000_READ_REG(&adapter->hw, E1000_TDBAL(i)),
E1000_READ_REG(&adapter->hw, E1000_TDLEN(i)));
- txr->watchdog_check = FALSE;
+ txr->queue_status = EM_QUEUE_IDLE;
}
/* Set the default values for the Tx Inter Packet Gap timer */
@@ -3610,16 +3628,20 @@ static bool
em_txeof(struct tx_ring *txr)
{
struct adapter *adapter = txr->adapter;
- int first, last, done;
+ int first, last, done, processed;
struct em_buffer *tx_buffer;
struct e1000_tx_desc *tx_desc, *eop_desc;
struct ifnet *ifp = adapter->ifp;
EM_TX_LOCK_ASSERT(txr);
- if (txr->tx_avail == adapter->num_tx_desc)
+ /* No work, make sure watchdog is off */
+ if (txr->tx_avail == adapter->num_tx_desc) {
+ txr->queue_status = EM_QUEUE_IDLE;
return (FALSE);
+ }
+ processed = 0;
first = txr->next_to_clean;
tx_desc = &txr->tx_base[first];
tx_buffer = &txr->tx_buffers[first];
@@ -3646,6 +3668,7 @@ em_txeof(struct tx_ring *txr)
tx_desc->lower.data = 0;
tx_desc->buffer_addr = 0;
++txr->tx_avail;
+ ++processed;
if (tx_buffer->m_head) {
bus_dmamap_sync(txr->txtag,
@@ -3681,6 +3704,16 @@ em_txeof(struct tx_ring *txr)
txr->next_to_clean = first;
+ /*
+ ** Watchdog calculation, we know there's
+ ** work outstanding or the first return
+ ** would have been taken, so none processed
+ ** for too long indicates a hang. local timer
+ ** will examine this and do a reset if needed.
+ */
+ if ((!processed) && ((ticks - txr->watchdog_time) > EM_WATCHDOG))
+ txr->queue_status = EM_QUEUE_HUNG;
+
/*
* If we have enough room, clear IFF_DRV_OACTIVE
* to tell the stack that it is OK to send packets.
@@ -3689,7 +3722,7 @@ em_txeof(struct tx_ring *txr)
ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
/* Disable watchdog if all clean */
if (txr->tx_avail == adapter->num_tx_desc) {
- txr->watchdog_check = FALSE;
+ txr->queue_status = EM_QUEUE_IDLE;
return (FALSE);
}
}
@@ -3723,7 +3756,8 @@ em_refresh_mbufs(struct rx_ring *rxr, int limit)
*/
if (rxbuf->m_head != NULL)
goto reuse;
- m = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR);
+ m = m_getjcl(M_DONTWAIT, MT_DATA,
+ M_PKTHDR, adapter->rx_mbuf_sz);
/*
** If we have a temporary resource shortage
** that causes a failure, just abort refresh
@@ -3732,10 +3766,7 @@ em_refresh_mbufs(struct rx_ring *rxr, int limit)
*/
if (m == NULL)
goto update;
- m->m_len = m->m_pkthdr.len = MCLBYTES;
-
- if (adapter->max_frame_size <= (MCLBYTES - ETHER_ALIGN))
- m_adj(m, ETHER_ALIGN);
+ m->m_len = m->m_pkthdr.len = adapter->rx_mbuf_sz;
/* Use bus_dma machinery to setup the memory mapping */
error = bus_dmamap_load_mbuf_sg(rxr->rxtag, rxbuf->map,
@@ -3801,9 +3832,9 @@ em_allocate_receive_buffers(struct rx_ring *rxr)
BUS_SPACE_MAXADDR, /* lowaddr */
BUS_SPACE_MAXADDR, /* highaddr */
NULL, NULL, /* filter, filterarg */
- MCLBYTES, /* maxsize */
+ MJUM9BYTES, /* maxsize */
1, /* nsegments */
- MCLBYTES, /* maxsegsize */
+ MJUM9BYTES, /* maxsegsize */
0, /* flags */
NULL, /* lockfunc */
NULL, /* lockarg */
@@ -3871,12 +3902,13 @@ em_setup_receive_ring(struct rx_ring *rxr)
for (int j = 0; j != adapter->num_rx_desc; ++j) {
rxbuf = &rxr->rx_buffers[j];
- rxbuf->m_head = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR);
+ rxbuf->m_head = m_getjcl(M_DONTWAIT, MT_DATA,
+ M_PKTHDR, adapter->rx_mbuf_sz);
if (rxbuf->m_head == NULL)
return (ENOBUFS);
- rxbuf->m_head->m_len = MCLBYTES;
+ rxbuf->m_head->m_len = adapter->rx_mbuf_sz;
rxbuf->m_head->m_flags &= ~M_HASFCS; /* we strip it */
- rxbuf->m_head->m_pkthdr.len = MCLBYTES;
+ rxbuf->m_head->m_pkthdr.len = adapter->rx_mbuf_sz;
/* Get the memory mapping */
error = bus_dmamap_load_mbuf_sg(rxr->rxtag,
@@ -4082,6 +4114,23 @@ em_initialize_receive_unit(struct adapter *adapter)
E1000_WRITE_REG(hw, E1000_RDT(i), adapter->num_rx_desc - 1);
}
+ /* Set early receive threshold on appropriate hw */
+ if (((adapter->hw.mac.type == e1000_ich9lan) ||
+ (adapter->hw.mac.type == e1000_pch2lan) ||
+ (adapter->hw.mac.type == e1000_ich10lan)) &&
+ (ifp->if_mtu > ETHERMTU)) {
+ u32 rxdctl = E1000_READ_REG(hw, E1000_RXDCTL(0));
+ E1000_WRITE_REG(hw, E1000_RXDCTL(0), rxdctl | 3);
+ E1000_WRITE_REG(hw, E1000_ERT, 0x100 | (1 << 13));
+ }
+
+ if (adapter->hw.mac.type == e1000_pch2lan) {
+ if (ifp->if_mtu > ETHERMTU)
+ e1000_lv_jumbo_workaround_ich8lan(hw, TRUE);
+ else
+ e1000_lv_jumbo_workaround_ich8lan(hw, FALSE);
+ }
+
/* Setup the Receive Control Register */
rctl &= ~(3 << E1000_RCTL_MO_SHIFT);
rctl |= E1000_RCTL_EN | E1000_RCTL_BAM |
@@ -4094,7 +4143,14 @@ em_initialize_receive_unit(struct adapter *adapter)
/* Make sure VLAN Filters are off */
rctl &= ~E1000_RCTL_VFE;
rctl &= ~E1000_RCTL_SBP;
- rctl |= E1000_RCTL_SZ_2048;
+
+ if (adapter->rx_mbuf_sz == MCLBYTES)
+ rctl |= E1000_RCTL_SZ_2048;
+ else if (adapter->rx_mbuf_sz == MJUMPAGESIZE)
+ rctl |= E1000_RCTL_SZ_4096 | E1000_RCTL_BSEX;
+ else if (adapter->rx_mbuf_sz > MJUMPAGESIZE)
+ rctl |= E1000_RCTL_SZ_8192 | E1000_RCTL_BSEX;
+
if (ifp->if_mtu > ETHERMTU)
rctl |= E1000_RCTL_LPE;
else
@@ -4190,7 +4246,7 @@ em_rxeof(struct rx_ring *rxr, int count, int *done)
rxr->fmp->m_flags |= M_VLANTAG;
}
#ifdef EM_MULTIQUEUE
- rxr->fmp->m_pkthdr.flowid = curcpu;
+ rxr->fmp->m_pkthdr.flowid = rxr->msix;
rxr->fmp->m_flags |= M_FLOWID;
#endif
#ifndef __NO_STRICT_ALIGNMENT
@@ -4253,6 +4309,7 @@ skip:
static __inline void
em_rx_discard(struct rx_ring *rxr, int i)
{
+ struct adapter *adapter = rxr->adapter;
struct em_buffer *rbuf;
struct mbuf *m;
@@ -4267,7 +4324,7 @@ em_rx_discard(struct rx_ring *rxr, int i)
/* Reset state, keep loaded DMA map and reuse */
m = rbuf->m_head;
- m->m_len = m->m_pkthdr.len = MCLBYTES;
+ m->m_len = m->m_pkthdr.len = adapter->rx_mbuf_sz;
m->m_flags |= M_PKTHDR;
m->m_data = m->m_ext.ext_buf;
m->m_next = NULL;
@@ -4378,12 +4435,15 @@ em_register_vlan(void *arg, struct ifnet *ifp, u16 vtag)
if ((vtag == 0) || (vtag > 4095)) /* Invalid ID */
return;
+ EM_CORE_LOCK(adapter);
index = (vtag >> 5) & 0x7F;
bit = vtag & 0x1F;
- em_shadow_vfta[index] |= (1 << bit);
+ adapter->shadow_vfta[index] |= (1 << bit);
++adapter->num_vlans;
/* Re-init to load the changes */
- em_init(adapter);
+ if (ifp->if_capenable & IFCAP_VLAN_HWFILTER)
+ em_init_locked(adapter);
+ EM_CORE_UNLOCK(adapter);
}
/*
@@ -4402,12 +4462,15 @@ em_unregister_vlan(void *arg, struct ifnet *ifp, u16 vtag)
if ((vtag == 0) || (vtag > 4095)) /* Invalid */
return;
+ EM_CORE_LOCK(adapter);
index = (vtag >> 5) & 0x7F;
bit = vtag & 0x1F;
- em_shadow_vfta[index] &= ~(1 << bit);
+ adapter->shadow_vfta[index] &= ~(1 << bit);
--adapter->num_vlans;
/* Re-init to load the changes */
- em_init(adapter);
+ if (ifp->if_capenable & IFCAP_VLAN_HWFILTER)
+ em_init_locked(adapter);
+ EM_CORE_UNLOCK(adapter);
}
static void
@@ -4430,9 +4493,9 @@ em_setup_vlan_hw_support(struct adapter *adapter)
** we need to repopulate it now.
*/
for (int i = 0; i < EM_VFTA_SIZE; i++)
- if (em_shadow_vfta[i] != 0)
+ if (adapter->shadow_vfta[i] != 0)
E1000_WRITE_REG_ARRAY(hw, E1000_VFTA,
- i, em_shadow_vfta[i]);
+ i, adapter->shadow_vfta[i]);
reg = E1000_READ_REG(hw, E1000_CTRL);
reg |= E1000_CTRL_VME;
@@ -4443,10 +4506,6 @@ em_setup_vlan_hw_support(struct adapter *adapter)
reg &= ~E1000_RCTL_CFIEN;
reg |= E1000_RCTL_VFE;
E1000_WRITE_REG(hw, E1000_RCTL, reg);
-
- /* Update the frame size */
- E1000_WRITE_REG(&adapter->hw, E1000_RLPML,
- adapter->max_frame_size + VLAN_TAG_SIZE);
}
static void
@@ -4615,6 +4674,7 @@ em_get_wakeup(device_t dev)
case e1000_ich9lan:
case e1000_ich10lan:
case e1000_pchlan:
+ case e1000_pch2lan:
apme_mask = E1000_WUC_APME;
adapter->has_amt = TRUE;
eeprom_data = E1000_READ_REG(&adapter->hw, E1000_WUC);
@@ -4706,7 +4766,8 @@ em_enable_wakeup(device_t dev)
E1000_WRITE_REG(&adapter->hw, E1000_RCTL, rctl);
}
- if (adapter->hw.mac.type == e1000_pchlan) {
+ if ((adapter->hw.mac.type == e1000_pchlan) ||
+ (adapter->hw.mac.type == e1000_pch2lan)) {
if (em_enable_phy_wakeup(adapter))
return;
} else {
@@ -4739,16 +4800,7 @@ em_enable_phy_wakeup(struct adapter *adapter)
u16 preg;
/* copy MAC RARs to PHY RARs */
- for (int i = 0; i < adapter->hw.mac.rar_entry_count; i++) {
- mreg = E1000_READ_REG(hw, E1000_RAL(i));
- e1000_write_phy_reg(hw, BM_RAR_L(i), (u16)(mreg & 0xFFFF));
- e1000_write_phy_reg(hw, BM_RAR_M(i),
- (u16)((mreg >> 16) & 0xFFFF));
- mreg = E1000_READ_REG(hw, E1000_RAH(i));
- e1000_write_phy_reg(hw, BM_RAR_H(i), (u16)(mreg & 0xFFFF));
- e1000_write_phy_reg(hw, BM_RAR_CTRL(i),
- (u16)((mreg >> 16) & 0xFFFF));
- }
+ e1000_copy_rx_addrs_to_phy_ich8lan(hw);
/* copy MAC MTA to PHY MTA */
for (int i = 0; i < adapter->hw.mac.mta_reg_count; i++) {
@@ -5359,4 +5411,70 @@ em_add_rx_process_limit(struct adapter *adapter, const char *name,
OID_AUTO, name, CTLTYPE_INT|CTLFLAG_RW, limit, value, description);
}
+static void
+em_set_flow_cntrl(struct adapter *adapter, const char *name,
+ const char *description, int *limit, int value)
+{
+ *limit = value;
+ SYSCTL_ADD_INT(device_get_sysctl_ctx(adapter->dev),
+ SYSCTL_CHILDREN(device_get_sysctl_tree(adapter->dev)),
+ OID_AUTO, name, CTLTYPE_INT|CTLFLAG_RW, limit, value, description);
+}
+
+static int
+em_sysctl_debug_info(SYSCTL_HANDLER_ARGS)
+{
+ struct adapter *adapter;
+ int error;
+ int result;
+
+ result = -1;
+ error = sysctl_handle_int(oidp, &result, 0, req);
+
+ if (error || !req->newptr)
+ return (error);
+
+ if (result == 1) {
+ adapter = (struct adapter *)arg1;
+ em_print_debug_info(adapter);
+ }
+
+ return (error);
+}
+
+/*
+** This routine is meant to be fluid, add whatever is
+** needed for debugging a problem. -jfv
+*/
+static void
+em_print_debug_info(struct adapter *adapter)
+{
+ device_t dev = adapter->dev;
+ struct tx_ring *txr = adapter->tx_rings;
+ struct rx_ring *rxr = adapter->rx_rings;
+ if (adapter->ifp->if_drv_flags & IFF_DRV_RUNNING)
+ printf("Interface is RUNNING ");
+ else
+ printf("Interface is NOT RUNNING\n");
+ if (adapter->ifp->if_drv_flags & IFF_DRV_OACTIVE)
+ printf("and ACTIVE\n");
+ else
+ printf("and INACTIVE\n");
+
+ device_printf(dev, "hw tdh = %d, hw tdt = %d\n",
+ E1000_READ_REG(&adapter->hw, E1000_TDH(0)),
+ E1000_READ_REG(&adapter->hw, E1000_TDT(0)));
+ device_printf(dev, "hw rdh = %d, hw rdt = %d\n",
+ E1000_READ_REG(&adapter->hw, E1000_RDH(0)),
+ E1000_READ_REG(&adapter->hw, E1000_RDT(0)));
+ device_printf(dev, "Tx Queue Status = %d\n", txr->queue_status);
+ device_printf(dev, "TX descriptors avail = %d\n",
+ txr->tx_avail);
+ device_printf(dev, "Tx Descriptors avail failure = %ld\n",
+ txr->no_desc_avail);
+ device_printf(dev, "RX discarded packets = %ld\n",
+ rxr->rx_discarded);
+ device_printf(dev, "RX Next to Check = %d\n", rxr->next_to_check);
+ device_printf(dev, "RX Next to Refresh = %d\n", rxr->next_to_refresh);
+}
diff --git a/sys/dev/e1000/if_em.h b/sys/dev/e1000/if_em.h
index fec34ac..8bfd600 100644
--- a/sys/dev/e1000/if_em.h
+++ b/sys/dev/e1000/if_em.h
@@ -188,6 +188,10 @@
#define EM_EEPROM_APME 0x400;
#define EM_82544_APME 0x0004;
+#define EM_QUEUE_IDLE 0
+#define EM_QUEUE_WORKING 1
+#define EM_QUEUE_HUNG 2
+
/*
* TDBA/RDBA should be aligned on 16 byte boundary. But TDLEN/RDLEN should be
* multiple of 128 bytes. So we align TDBA/RDBA on 128 byte boundary. This will
@@ -272,7 +276,7 @@ struct tx_ring {
u32 me;
u32 msix;
u32 ims;
- bool watchdog_check;
+ int queue_status;
int watchdog_time;
struct em_dma_alloc txdma;
struct e1000_tx_desc *tx_base;
@@ -391,6 +395,7 @@ struct adapter {
struct rx_ring *rx_rings;
int num_rx_desc;
u32 rx_process_limit;
+ u32 rx_mbuf_sz;
/* Management and WOL features */
u32 wol;
@@ -400,11 +405,21 @@ struct adapter {
/* Multicast array memory */
u8 *mta;
- /* Info about the board itself */
- uint8_t link_active;
- uint16_t link_speed;
- uint16_t link_duplex;
- uint32_t smartspeed;
+ /*
+ ** Shadow VFTA table, this is needed because
+ ** the real vlan filter table gets cleared during
+ ** a soft reset and the driver needs to be able
+ ** to repopulate it.
+ */
+ u32 shadow_vfta[EM_VFTA_SIZE];
+
+ /* Info about the interface */
+ u8 link_active;
+ u16 link_speed;
+ u16 link_duplex;
+ u32 smartspeed;
+ u32 fc_setting;
+
struct em_int_delay_info tx_int_delay;
struct em_int_delay_info tx_abs_int_delay;
struct em_int_delay_info rx_int_delay;
diff --git a/sys/dev/e1000/if_lem.c b/sys/dev/e1000/if_lem.c
index 846d6bf..21686e6 100644
--- a/sys/dev/e1000/if_lem.c
+++ b/sys/dev/e1000/if_lem.c
@@ -51,9 +51,7 @@
#include <sys/sockio.h>
#include <sys/sysctl.h>
#include <sys/taskqueue.h>
-#if __FreeBSD_version >= 700029
#include <sys/eventhandler.h>
-#endif
#include <machine/bus.h>
#include <machine/resource.h>
@@ -86,8 +84,7 @@
/*********************************************************************
* Legacy Em Driver version:
*********************************************************************/
-char lem_driver_version[] = "1.0.2";
-
+char lem_driver_version[] = "1.0.3";
/*********************************************************************
* PCI Device ID Table
@@ -209,11 +206,9 @@ static void lem_disable_promisc(struct adapter *);
static void lem_set_multi(struct adapter *);
static void lem_update_link_status(struct adapter *);
static int lem_get_buf(struct adapter *, int);
-#if __FreeBSD_version >= 700029
static void lem_register_vlan(void *, struct ifnet *, u16);
static void lem_unregister_vlan(void *, struct ifnet *, u16);
static void lem_setup_vlan_hw_support(struct adapter *);
-#endif
static int lem_xmit(struct adapter *, struct mbuf **);
static void lem_smartspeed(struct adapter *);
static int lem_82547_fifo_workaround(struct adapter *, int);
@@ -231,6 +226,8 @@ static u32 lem_fill_descriptors (bus_addr_t address, u32 length,
static int lem_sysctl_int_delay(SYSCTL_HANDLER_ARGS);
static void lem_add_int_delay_sysctl(struct adapter *, const char *,
const char *, struct em_int_delay_info *, int, int);
+static void lem_set_flow_cntrl(struct adapter *, const char *,
+ const char *, int *, int);
/* Management and WOL Support */
static void lem_init_manageability(struct adapter *);
static void lem_release_manageability(struct adapter *);
@@ -244,11 +241,7 @@ static void lem_led_func(void *, int);
#ifdef EM_LEGACY_IRQ
static void lem_intr(void *);
#else /* FAST IRQ */
-#if __FreeBSD_version < 700000
-static void lem_irq_fast(void *);
-#else
static int lem_irq_fast(void *);
-#endif
static void lem_handle_rxtx(void *context, int pending);
static void lem_handle_link(void *context, int pending);
static void lem_add_rx_process_limit(struct adapter *, const char *,
@@ -320,14 +313,6 @@ TUNABLE_INT("hw.em.rx_process_limit", &lem_rx_process_limit);
static int lem_fc_setting = e1000_fc_full;
TUNABLE_INT("hw.em.fc_setting", &lem_fc_setting);
-/*
-** Shadow VFTA table, this is needed because
-** the real vlan filter table gets cleared during
-** a soft reset and the driver needs to be able
-** to repopulate it.
-*/
-static u32 lem_shadow_vfta[EM_VFTA_SIZE];
-
/* Global used in WOL setup with multiport cards */
static int global_quad_port_a = 0;
@@ -462,6 +447,11 @@ lem_attach(device_t dev)
lem_rx_process_limit);
#endif
+ /* Sysctl for setting the interface flow control */
+ lem_set_flow_cntrl(adapter, "flow_control",
+ "max number of rx packets to process",
+ &adapter->fc_setting, lem_fc_setting);
+
/*
* Validate number of transmit and receive descriptors. It
* must not exceed hardware maximum, and must be multiple
@@ -638,13 +628,11 @@ lem_attach(device_t dev)
else
adapter->pcix_82544 = FALSE;
-#if __FreeBSD_version >= 700029
/* Register for VLAN events */
adapter->vlan_attach = EVENTHANDLER_REGISTER(vlan_config,
lem_register_vlan, adapter, EVENTHANDLER_PRI_FIRST);
adapter->vlan_detach = EVENTHANDLER_REGISTER(vlan_unconfig,
lem_unregister_vlan, adapter, EVENTHANDLER_PRI_FIRST);
-#endif
lem_add_hw_stats(adapter);
@@ -702,11 +690,7 @@ lem_detach(device_t dev)
INIT_DEBUGOUT("em_detach: begin");
/* Make sure VLANS are not using driver */
-#if __FreeBSD_version >= 700000
if (adapter->ifp->if_vlantrunk != NULL) {
-#else
- if (adapter->ifp->if_nvlans != 0) {
-#endif
device_printf(dev,"Vlan in use, detach first\n");
return (EBUSY);
}
@@ -730,13 +714,11 @@ lem_detach(device_t dev)
EM_TX_UNLOCK(adapter);
EM_CORE_UNLOCK(adapter);
-#if __FreeBSD_version >= 700029
/* Unregister VLAN events */
if (adapter->vlan_attach != NULL)
EVENTHANDLER_DEREGISTER(vlan_config, adapter->vlan_attach);
if (adapter->vlan_detach != NULL)
EVENTHANDLER_DEREGISTER(vlan_unconfig, adapter->vlan_detach);
-#endif
ether_ifdetach(adapter->ifp);
callout_drain(&adapter->timer);
@@ -831,6 +813,19 @@ lem_start_locked(struct ifnet *ifp)
if (!adapter->link_active)
return;
+ /*
+ * Force a cleanup if number of TX descriptors
+ * available hits the threshold
+ */
+ if (adapter->num_tx_desc_avail <= EM_TX_CLEANUP_THRESHOLD) {
+ lem_txeof(adapter);
+ /* Now do we at least have a minimal? */
+ if (adapter->num_tx_desc_avail <= EM_TX_OP_THRESHOLD) {
+ adapter->no_tx_desc_avail1++;
+ return;
+ }
+ }
+
while (!IFQ_DRV_IS_EMPTY(&ifp->if_snd)) {
IFQ_DRV_DEQUEUE(&ifp->if_snd, m_head);
@@ -1043,9 +1038,7 @@ lem_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
}
if (reinit && (ifp->if_drv_flags & IFF_DRV_RUNNING))
lem_init(adapter);
-#if __FreeBSD_version >= 700000
VLAN_CAPABILITIES(ifp);
-#endif
break;
}
@@ -1135,17 +1128,8 @@ lem_init_locked(struct adapter *adapter)
/* Setup VLAN support, basic and offload if available */
E1000_WRITE_REG(&adapter->hw, E1000_VET, ETHERTYPE_VLAN);
-#if __FreeBSD_version < 700029
- if (ifp->if_capenable & IFCAP_VLAN_HWTAGGING) {
- u32 ctrl;
- ctrl = E1000_READ_REG(&adapter->hw, E1000_CTRL);
- ctrl |= E1000_CTRL_VME;
- E1000_WRITE_REG(&adapter->hw, E1000_CTRL, ctrl);
- }
-#else
/* Use real VLAN Filter support */
lem_setup_vlan_hw_support(adapter);
-#endif
/* Set hardware offload abilities */
ifp->if_hwassist = 0;
@@ -1174,6 +1158,19 @@ lem_init_locked(struct adapter *adapter)
}
lem_initialize_receive_unit(adapter);
+ /* Use real VLAN Filter support? */
+ if (ifp->if_capenable & IFCAP_VLAN_HWTAGGING) {
+ if (ifp->if_capenable & IFCAP_VLAN_HWFILTER)
+ /* Use real VLAN Filter support */
+ lem_setup_vlan_hw_support(adapter);
+ else {
+ u32 ctrl;
+ ctrl = E1000_READ_REG(&adapter->hw, E1000_CTRL);
+ ctrl |= E1000_CTRL_VME;
+ E1000_WRITE_REG(&adapter->hw, E1000_CTRL, ctrl);
+ }
+ }
+
/* Don't lose promiscuous settings */
lem_set_promisc(adapter);
@@ -1276,7 +1273,6 @@ lem_poll(struct ifnet *ifp, enum poll_cmd cmd, int count)
* Legacy Interrupt Service routine
*
*********************************************************************/
-
static void
lem_intr(void *arg)
{
@@ -1311,7 +1307,6 @@ lem_intr(void *arg)
}
EM_TX_LOCK(adapter);
- lem_txeof(adapter);
lem_rxeof(adapter, -1, NULL);
lem_txeof(adapter);
if (ifp->if_drv_flags & IFF_DRV_RUNNING &&
@@ -1354,8 +1349,7 @@ lem_handle_rxtx(void *context, int pending)
if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
- if (lem_rxeof(adapter, adapter->rx_process_limit, NULL) != 0)
- taskqueue_enqueue(adapter->tq, &adapter->rxtx_task);
+ lem_rxeof(adapter, adapter->rx_process_limit, NULL);
EM_TX_LOCK(adapter);
lem_txeof(adapter);
if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd))
@@ -1363,7 +1357,8 @@ lem_handle_rxtx(void *context, int pending)
EM_TX_UNLOCK(adapter);
}
- lem_enable_intr(adapter);
+ if (ifp->if_drv_flags & IFF_DRV_RUNNING)
+ lem_enable_intr(adapter);
}
/*********************************************************************
@@ -1371,13 +1366,7 @@ lem_handle_rxtx(void *context, int pending)
* Fast Legacy/MSI Combined Interrupt Service routine
*
*********************************************************************/
-#if __FreeBSD_version < 700000
-#define FILTER_STRAY
-#define FILTER_HANDLED
-static void
-#else
static int
-#endif
lem_irq_fast(void *arg)
{
struct adapter *adapter = arg;
@@ -1550,25 +1539,10 @@ lem_xmit(struct adapter *adapter, struct mbuf **m_headp)
struct mbuf *m_head;
u32 txd_upper, txd_lower, txd_used, txd_saved;
int error, nsegs, i, j, first, last = 0;
-#if __FreeBSD_version < 700000
- struct m_tag *mtag;
-#endif
+
m_head = *m_headp;
txd_upper = txd_lower = txd_used = txd_saved = 0;
- /*
- * Force a cleanup if number of TX descriptors
- * available hits the threshold
- */
- if (adapter->num_tx_desc_avail <= EM_TX_CLEANUP_THRESHOLD) {
- lem_txeof(adapter);
- /* Now do we at least have a minimal? */
- if (adapter->num_tx_desc_avail <= EM_TX_OP_THRESHOLD) {
- adapter->no_tx_desc_avail1++;
- return (ENOBUFS);
- }
- }
-
/*
** When doing checksum offload, it is critical to
** make sure the first mbuf has more than header,
@@ -1712,20 +1686,6 @@ lem_xmit(struct adapter *adapter, struct mbuf **m_headp)
else
adapter->num_tx_desc_avail -= nsegs;
- /*
- ** Handle VLAN tag, this is the
- ** biggest difference between
- ** 6.x and 7
- */
-#if __FreeBSD_version < 700000
- /* Find out if we are in vlan mode. */
- mtag = VLAN_OUTPUT_TAG(ifp, m_head);
- if (mtag != NULL) {
- ctxd->upper.fields.special =
- htole16(VLAN_TAG_VALUE(mtag));
- ctxd->lower.data |= htole32(E1000_TXD_CMD_VLE);
- }
-#else /* FreeBSD 7 */
if (m_head->m_flags & M_VLANTAG) {
/* Set the vlan id. */
ctxd->upper.fields.special =
@@ -1733,7 +1693,6 @@ lem_xmit(struct adapter *adapter, struct mbuf **m_headp)
/* Tell hardware to add tag */
ctxd->lower.data |= htole32(E1000_TXD_CMD_VLE);
}
-#endif
tx_buffer->m_head = m_head;
tx_buffer_mapped->map = tx_buffer->map;
@@ -2249,11 +2208,7 @@ lem_allocate_irq(struct adapter *adapter)
#ifdef EM_LEGACY_IRQ
/* We do Legacy setup */
if ((error = bus_setup_intr(dev, adapter->res[0],
-#if __FreeBSD_version > 700000
INTR_TYPE_NET | INTR_MPSAFE, NULL, lem_intr, adapter,
-#else /* 6.X */
- INTR_TYPE_NET | INTR_MPSAFE, lem_intr, adapter,
-#endif
&adapter->tag[0])) != 0) {
device_printf(dev, "Failed to register interrupt handler");
return (error);
@@ -2270,13 +2225,8 @@ lem_allocate_irq(struct adapter *adapter)
taskqueue_thread_enqueue, &adapter->tq);
taskqueue_start_threads(&adapter->tq, 1, PI_NET, "%s taskq",
device_get_nameunit(adapter->dev));
-#if __FreeBSD_version < 700000
- if ((error = bus_setup_intr(dev, adapter->res[0],
- INTR_TYPE_NET | INTR_FAST, lem_irq_fast, adapter,
-#else
if ((error = bus_setup_intr(dev, adapter->res[0],
INTR_TYPE_NET, lem_irq_fast, NULL, adapter,
-#endif
&adapter->tag[0])) != 0) {
device_printf(dev, "Failed to register fast interrupt "
"handler: %d\n", error);
@@ -2362,7 +2312,7 @@ lem_hardware_init(struct adapter *adapter)
adapter->hw.fc.send_xon = TRUE;
/* Set Flow control, use the tunable location if sane */
- if ((lem_fc_setting >= 0) || (lem_fc_setting < 4))
+ if ((lem_fc_setting >= 0) && (lem_fc_setting < 4))
adapter->hw.fc.requested_mode = lem_fc_setting;
else
adapter->hw.fc.requested_mode = e1000_fc_none;
@@ -2410,14 +2360,8 @@ lem_setup_interface(device_t dev, struct adapter *adapter)
ifp->if_capabilities = ifp->if_capenable = 0;
if (adapter->hw.mac.type >= e1000_82543) {
- int version_cap;
-#if __FreeBSD_version < 700000
- version_cap = IFCAP_HWCSUM;
-#else
- version_cap = IFCAP_HWCSUM | IFCAP_VLAN_HWCSUM;
-#endif
- ifp->if_capabilities |= version_cap;
- ifp->if_capenable |= version_cap;
+ ifp->if_capabilities |= IFCAP_HWCSUM | IFCAP_VLAN_HWCSUM;
+ ifp->if_capenable |= IFCAP_HWCSUM | IFCAP_VLAN_HWCSUM;
}
/*
@@ -2427,6 +2371,16 @@ lem_setup_interface(device_t dev, struct adapter *adapter)
ifp->if_capabilities |= IFCAP_VLAN_HWTAGGING | IFCAP_VLAN_MTU;
ifp->if_capenable |= IFCAP_VLAN_HWTAGGING | IFCAP_VLAN_MTU;
+ /*
+ ** Dont turn this on by default, if vlans are
+ ** created on another pseudo device (eg. lagg)
+ ** then vlan events are not passed thru, breaking
+ ** operation, but with HW FILTER off it works. If
+ ** using vlans directly on the em driver you can
+ ** enable this and get full hardware tag filtering.
+ */
+ ifp->if_capabilities |= IFCAP_VLAN_HWFILTER;
+
#ifdef DEVICE_POLLING
ifp->if_capabilities |= IFCAP_POLLING;
#endif
@@ -2551,11 +2505,7 @@ lem_dma_malloc(struct adapter *adapter, bus_size_t size,
{
int error;
-#if __FreeBSD_version >= 700000
error = bus_dma_tag_create(bus_get_dma_tag(adapter->dev), /* parent */
-#else
- error = bus_dma_tag_create(NULL, /* parent */
-#endif
EM_DBA_ALIGN, 0, /* alignment, bounds */
BUS_SPACE_MAXADDR, /* lowaddr */
BUS_SPACE_MAXADDR, /* highaddr */
@@ -2640,21 +2590,17 @@ lem_allocate_transmit_structures(struct adapter *adapter)
/*
* Create DMA tags for tx descriptors
*/
-#if __FreeBSD_version >= 700000
if ((error = bus_dma_tag_create(bus_get_dma_tag(dev), /* parent */
-#else
- if ((error = bus_dma_tag_create(NULL, /* parent */
-#endif
1, 0, /* alignment, bounds */
BUS_SPACE_MAXADDR, /* lowaddr */
BUS_SPACE_MAXADDR, /* highaddr */
NULL, NULL, /* filter, filterarg */
- EM_TSO_SIZE, /* maxsize */
+ MCLBYTES * EM_MAX_SCATTER, /* maxsize */
EM_MAX_SCATTER, /* nsegments */
- EM_TSO_SEG_SIZE, /* maxsegsize */
+ MCLBYTES, /* maxsegsize */
0, /* flags */
- NULL, /* lockfunc */
- NULL, /* lockarg */
+ NULL, /* lockfunc */
+ NULL, /* lockarg */
&adapter->txtag)) != 0) {
device_printf(dev, "Unable to allocate TX DMA tag\n");
goto fail;
@@ -3072,23 +3018,20 @@ lem_txeof(struct adapter *adapter)
BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
adapter->next_tx_to_clean = first;
+ adapter->num_tx_desc_avail = num_avail;
/*
* If we have enough room, clear IFF_DRV_OACTIVE to
* tell the stack that it is OK to send packets.
* If there are no pending descriptors, clear the watchdog.
*/
- if (num_avail > EM_TX_CLEANUP_THRESHOLD) {
+ if (adapter->num_tx_desc_avail > EM_TX_CLEANUP_THRESHOLD) {
ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
- if (num_avail == adapter->num_tx_desc) {
+ if (adapter->num_tx_desc_avail == adapter->num_tx_desc) {
adapter->watchdog_check = FALSE;
- adapter->num_tx_desc_avail = num_avail;
return;
}
}
-
- adapter->num_tx_desc_avail = num_avail;
- return;
}
/*********************************************************************
@@ -3185,11 +3128,7 @@ lem_allocate_receive_structures(struct adapter *adapter)
return (ENOMEM);
}
-#if __FreeBSD_version >= 700000
error = bus_dma_tag_create(bus_get_dma_tag(dev), /* parent */
-#else
- error = bus_dma_tag_create(NULL, /* parent */
-#endif
1, 0, /* alignment, bounds */
BUS_SPACE_MAXADDR, /* lowaddr */
BUS_SPACE_MAXADDR, /* highaddr */
@@ -3459,7 +3398,7 @@ lem_rxeof(struct adapter *adapter, int count, int *done)
{
struct ifnet *ifp = adapter->ifp;;
struct mbuf *mp;
- u8 status, accept_frame = 0, eop = 0;
+ u8 status = 0, accept_frame = 0, eop = 0;
u16 len, desc_len, prev_len_adj;
int i, rx_sent = 0;
struct e1000_rx_desc *current_desc;
@@ -3477,11 +3416,13 @@ lem_rxeof(struct adapter *adapter, int count, int *done)
return (FALSE);
}
- while ((current_desc->status & E1000_RXD_STAT_DD) &&
- (count != 0) &&
- (ifp->if_drv_flags & IFF_DRV_RUNNING)) {
+ while (count != 0 && ifp->if_drv_flags & IFF_DRV_RUNNING) {
struct mbuf *m = NULL;
+ status = current_desc->status;
+ if ((status & E1000_RXD_STAT_DD) == 0)
+ break;
+
mp = adapter->rx_buffer_area[i].m_head;
/*
* Can't defer bus_dmamap_sync(9) because TBI_ACCEPT
@@ -3493,7 +3434,6 @@ lem_rxeof(struct adapter *adapter, int count, int *done)
accept_frame = 1;
prev_len_adj = 0;
desc_len = le16toh(current_desc->length);
- status = current_desc->status;
if (status & E1000_RXD_STAT_EOP) {
count--;
eop = 1;
@@ -3571,16 +3511,10 @@ lem_rxeof(struct adapter *adapter, int count, int *done)
goto skip;
#endif
if (status & E1000_RXD_STAT_VP) {
-#if __FreeBSD_version < 700000
- VLAN_INPUT_TAG_NEW(ifp, adapter->fmp,
- (le16toh(current_desc->special) &
- E1000_RXD_SPC_VLAN_MASK));
-#else
adapter->fmp->m_pkthdr.ether_vtag =
(le16toh(current_desc->special) &
E1000_RXD_SPC_VLAN_MASK);
adapter->fmp->m_flags |= M_VLANTAG;
-#endif
}
#ifndef __NO_STRICT_ALIGNMENT
skip:
@@ -3636,7 +3570,7 @@ discard:
if (done != NULL)
*done = rx_sent;
EM_RX_UNLOCK(adapter);
- return (current_desc->status & E1000_RXD_STAT_DD);
+ return ((status & E1000_RXD_STAT_DD) ? TRUE : FALSE);
}
#ifndef __NO_STRICT_ALIGNMENT
@@ -3728,7 +3662,6 @@ lem_receive_checksum(struct adapter *adapter,
}
}
-#if __FreeBSD_version >= 700029
/*
* This routine is run via an vlan
* config EVENT
@@ -3745,12 +3678,15 @@ lem_register_vlan(void *arg, struct ifnet *ifp, u16 vtag)
if ((vtag == 0) || (vtag > 4095)) /* Invalid ID */
return;
+ EM_CORE_LOCK(adapter);
index = (vtag >> 5) & 0x7F;
bit = vtag & 0x1F;
- lem_shadow_vfta[index] |= (1 << bit);
+ adapter->shadow_vfta[index] |= (1 << bit);
++adapter->num_vlans;
/* Re-init to load the changes */
- lem_init(adapter);
+ if (ifp->if_capenable & IFCAP_VLAN_HWFILTER)
+ lem_init_locked(adapter);
+ EM_CORE_UNLOCK(adapter);
}
/*
@@ -3769,12 +3705,15 @@ lem_unregister_vlan(void *arg, struct ifnet *ifp, u16 vtag)
if ((vtag == 0) || (vtag > 4095)) /* Invalid */
return;
+ EM_CORE_LOCK(adapter);
index = (vtag >> 5) & 0x7F;
bit = vtag & 0x1F;
- lem_shadow_vfta[index] &= ~(1 << bit);
+ adapter->shadow_vfta[index] &= ~(1 << bit);
--adapter->num_vlans;
/* Re-init to load the changes */
- lem_init(adapter);
+ if (ifp->if_capenable & IFCAP_VLAN_HWFILTER)
+ lem_init_locked(adapter);
+ EM_CORE_UNLOCK(adapter);
}
static void
@@ -3797,9 +3736,9 @@ lem_setup_vlan_hw_support(struct adapter *adapter)
** we need to repopulate it now.
*/
for (int i = 0; i < EM_VFTA_SIZE; i++)
- if (lem_shadow_vfta[i] != 0)
+ if (adapter->shadow_vfta[i] != 0)
E1000_WRITE_REG_ARRAY(hw, E1000_VFTA,
- i, lem_shadow_vfta[i]);
+ i, adapter->shadow_vfta[i]);
reg = E1000_READ_REG(hw, E1000_CTRL);
reg |= E1000_CTRL_VME;
@@ -3815,7 +3754,6 @@ lem_setup_vlan_hw_support(struct adapter *adapter)
E1000_WRITE_REG(&adapter->hw, E1000_RLPML,
adapter->max_frame_size + VLAN_TAG_SIZE);
}
-#endif
static void
lem_enable_intr(struct adapter *adapter)
@@ -4661,6 +4599,16 @@ lem_add_int_delay_sysctl(struct adapter *adapter, const char *name,
info, 0, lem_sysctl_int_delay, "I", description);
}
+static void
+lem_set_flow_cntrl(struct adapter *adapter, const char *name,
+ const char *description, int *limit, int value)
+{
+ *limit = value;
+ SYSCTL_ADD_INT(device_get_sysctl_ctx(adapter->dev),
+ SYSCTL_CHILDREN(device_get_sysctl_tree(adapter->dev)),
+ OID_AUTO, name, CTLTYPE_INT|CTLFLAG_RW, limit, value, description);
+}
+
#ifndef EM_LEGACY_IRQ
static void
lem_add_rx_process_limit(struct adapter *adapter, const char *name,
@@ -4672,5 +4620,3 @@ lem_add_rx_process_limit(struct adapter *adapter, const char *name,
OID_AUTO, name, CTLTYPE_INT|CTLFLAG_RW, limit, value, description);
}
#endif
-
-
diff --git a/sys/dev/e1000/if_lem.h b/sys/dev/e1000/if_lem.h
index 2f76aa8..e866d07e 100644
--- a/sys/dev/e1000/if_lem.h
+++ b/sys/dev/e1000/if_lem.h
@@ -328,11 +328,9 @@ struct adapter {
struct task tx_task;
struct taskqueue *tq; /* private task queue */
-#if __FreeBSD_version >= 700029
eventhandler_tag vlan_attach;
eventhandler_tag vlan_detach;
u32 num_vlans;
-#endif
/* Management and WOL features */
u32 wol;
@@ -341,11 +339,22 @@ struct adapter {
/* Multicast array memory */
u8 *mta;
- /* Info about the board itself */
+
+ /*
+ ** Shadow VFTA table, this is needed because
+ ** the real vlan filter table gets cleared during
+ ** a soft reset and the driver needs to be able
+ ** to repopulate it.
+ */
+ u32 shadow_vfta[EM_VFTA_SIZE];
+
+ /* Info about the interface */
uint8_t link_active;
uint16_t link_speed;
uint16_t link_duplex;
uint32_t smartspeed;
+ uint32_t fc_setting;
+
struct em_int_delay_info tx_int_delay;
struct em_int_delay_info tx_abs_int_delay;
struct em_int_delay_info rx_int_delay;
@@ -407,6 +416,9 @@ struct adapter {
unsigned long no_tx_dma_setup;
unsigned long watchdog_events;
unsigned long rx_overruns;
+ unsigned long rx_irq;
+ unsigned long tx_irq;
+ unsigned long link_irq;
/* 82547 workaround */
uint32_t tx_fifo_size;
diff --git a/sys/dev/mii/brgphy.c b/sys/dev/mii/brgphy.c
index 9f915df..454ee22 100644
--- a/sys/dev/mii/brgphy.c
+++ b/sys/dev/mii/brgphy.c
@@ -141,6 +141,7 @@ static const struct mii_phydesc brgphys[] = {
MII_PHY_DESC(xxBROADCOM_ALT1, BCM5709C),
MII_PHY_DESC(xxBROADCOM_ALT1, BCM5761),
MII_PHY_DESC(xxBROADCOM_ALT1, BCM5709S),
+ MII_PHY_DESC(xxBROADCOM_ALT2, BCM5717C),
MII_PHY_DESC(BROADCOM2, BCM5906),
MII_PHY_END
};
@@ -253,6 +254,9 @@ brgphy_attach(device_t dev)
break;
}
break;
+ case MII_OUI_xxBROADCOM_ALT2:
+ /* No special handling yet. */
+ break;
default:
device_printf(dev, "Unrecognized OUI for PHY!\n");
}
@@ -1011,6 +1015,7 @@ brgphy_reset(struct mii_softc *sc)
}
break;
case MII_OUI_xxBROADCOM_ALT1:
+ case MII_OUI_xxBROADCOM_ALT2:
break;
}
diff --git a/sys/dev/mii/e1000phy.c b/sys/dev/mii/e1000phy.c
index e763c21..f49f7c4 100644
--- a/sys/dev/mii/e1000phy.c
+++ b/sys/dev/mii/e1000phy.c
@@ -206,7 +206,7 @@ e1000phy_reset(struct mii_softc *sc)
reg &= ~E1000_SCR_MODE_MASK;
reg |= E1000_SCR_MODE_1000BX;
PHY_WRITE(sc, E1000_SCR, reg);
- if ((sc->mii_flags & MIIF_MACPRIV0) != 0) {
+ if ((sc->mii_flags & MIIF_PHYPRIV0) != 0) {
/* Set SIGDET polarity low for SFP module. */
PHY_WRITE(sc, E1000_EADR, 1);
reg = PHY_READ(sc, E1000_SCR);
diff --git a/sys/dev/mii/mii_physubr.c b/sys/dev/mii/mii_physubr.c
index 015d53c..d1cc4f5 100644
--- a/sys/dev/mii/mii_physubr.c
+++ b/sys/dev/mii/mii_physubr.c
@@ -107,8 +107,8 @@ mii_phy_setmedia(struct mii_softc *sc)
if (IFM_SUBTYPE(ife->ifm_media) == IFM_AUTO) {
if ((PHY_READ(sc, MII_BMCR) & BMCR_AUTOEN) == 0 ||
- (sc->mii_flags & MIIF_FORCEANEG))
- (void) mii_phy_auto(sc);
+ (sc->mii_flags & MIIF_FORCEANEG) != 0)
+ (void)mii_phy_auto(sc);
return;
}
@@ -124,64 +124,59 @@ mii_phy_setmedia(struct mii_softc *sc)
bmcr = mii_media_table[ife->ifm_data].mm_bmcr;
gtcr = mii_media_table[ife->ifm_data].mm_gtcr;
- if (mii->mii_media.ifm_media & IFM_ETH_MASTER) {
+ if ((mii->mii_media.ifm_media & IFM_ETH_MASTER) != 0) {
switch (IFM_SUBTYPE(ife->ifm_media)) {
case IFM_1000_T:
- gtcr |= GTCR_MAN_MS|GTCR_ADV_MS;
+ gtcr |= GTCR_MAN_MS | GTCR_ADV_MS;
break;
default:
- panic("mii_phy_setmedia: MASTER on wrong media");
+ printf("mii_phy_setmedia: MASTER on wrong media\n");
}
}
- if (ife->ifm_media & IFM_LOOP)
+ if ((ife->ifm_media & IFM_LOOP) != 0)
bmcr |= BMCR_LOOP;
PHY_WRITE(sc, MII_ANAR, anar);
PHY_WRITE(sc, MII_BMCR, bmcr);
- if (sc->mii_flags & MIIF_HAVE_GTCR)
+ if ((sc->mii_flags & MIIF_HAVE_GTCR) != 0)
PHY_WRITE(sc, MII_100T2CR, gtcr);
}
int
mii_phy_auto(struct mii_softc *sc)
{
+ int anar, gtcr;
/*
* Check for 1000BASE-X. Autonegotiation is a bit
* different on such devices.
*/
- if (sc->mii_flags & MIIF_IS_1000X) {
- uint16_t anar = 0;
-
- if (sc->mii_extcapabilities & EXTSR_1000XFDX)
+ if ((sc->mii_flags & MIIF_IS_1000X) != 0) {
+ anar = 0;
+ if ((sc->mii_extcapabilities & EXTSR_1000XFDX) != 0)
anar |= ANAR_X_FD;
- if (sc->mii_extcapabilities & EXTSR_1000XHDX)
+ if ((sc->mii_extcapabilities & EXTSR_1000XHDX) != 0)
anar |= ANAR_X_HD;
- if (sc->mii_flags & MIIF_DOPAUSE) {
+ if ((sc->mii_flags & MIIF_DOPAUSE) != 0) {
/* XXX Asymmetric vs. symmetric? */
anar |= ANLPAR_X_PAUSE_TOWARDS;
}
-
PHY_WRITE(sc, MII_ANAR, anar);
} else {
- uint16_t anar;
-
anar = BMSR_MEDIA_TO_ANAR(sc->mii_capabilities) |
ANAR_CSMA;
- if (sc->mii_flags & MIIF_DOPAUSE)
+ if ((sc->mii_flags & MIIF_DOPAUSE) != 0)
anar |= ANAR_FC;
PHY_WRITE(sc, MII_ANAR, anar);
- if (sc->mii_flags & MIIF_HAVE_GTCR) {
- uint16_t gtcr = 0;
-
- if (sc->mii_extcapabilities & EXTSR_1000TFDX)
+ if ((sc->mii_flags & MIIF_HAVE_GTCR) != 0) {
+ gtcr = 0;
+ if ((sc->mii_extcapabilities & EXTSR_1000TFDX) != 0)
gtcr |= GTCR_ADV_1000TFDX;
- if (sc->mii_extcapabilities & EXTSR_1000THDX)
+ if ((sc->mii_extcapabilities & EXTSR_1000THDX) != 0)
gtcr |= GTCR_ADV_1000THDX;
-
PHY_WRITE(sc, MII_100T2CR, gtcr);
}
}
@@ -213,7 +208,7 @@ mii_phy_tick(struct mii_softc *sc)
/* Read the status register twice; BMSR_LINK is latch-low. */
reg = PHY_READ(sc, MII_BMSR) | PHY_READ(sc, MII_BMSR);
- if (reg & BMSR_LINK) {
+ if ((reg & BMSR_LINK) != 0) {
sc->mii_ticks = 0; /* reset autonegotiation timer. */
/* See above. */
return (0);
@@ -243,7 +238,7 @@ mii_phy_reset(struct mii_softc *sc)
struct ifmedia_entry *ife = sc->mii_pdata->mii_media.ifm_cur;
int reg, i;
- if (sc->mii_flags & MIIF_NOISOLATE)
+ if ((sc->mii_flags & MIIF_NOISOLATE) != 0)
reg = BMCR_RESET;
else
reg = BMCR_RESET | BMCR_ISO;
@@ -303,7 +298,10 @@ mii_phy_add_media(struct mii_softc *sc)
return;
}
- /* Set aneg timer for 10/100 media. Gigabit media handled below. */
+ /*
+ * Set the autonegotiation timer for 10/100 media. Gigabit media is
+ * handled below.
+ */
sc->mii_anegticks = MII_ANEGTICKS;
#define ADD(m, c) ifmedia_add(&mii->mii_media, (m), (c), NULL)
@@ -318,55 +316,54 @@ mii_phy_add_media(struct mii_softc *sc)
* HomePNA PHYs. And there is really only one media type
* that is supported.
*/
- if (sc->mii_flags & MIIF_IS_HPNA) {
- if (sc->mii_capabilities & BMSR_10THDX) {
+ if ((sc->mii_flags & MIIF_IS_HPNA) != 0) {
+ if ((sc->mii_capabilities & BMSR_10THDX) != 0) {
ADD(IFM_MAKEWORD(IFM_ETHER, IFM_HPNA_1, 0,
- sc->mii_inst),
- MII_MEDIA_10_T);
+ sc->mii_inst), MII_MEDIA_10_T);
PRINT("HomePNA1");
}
return;
}
- if (sc->mii_capabilities & BMSR_10THDX) {
+ if ((sc->mii_capabilities & BMSR_10THDX) != 0) {
ADD(IFM_MAKEWORD(IFM_ETHER, IFM_10_T, 0, sc->mii_inst),
MII_MEDIA_10_T);
PRINT("10baseT");
}
- if (sc->mii_capabilities & BMSR_10TFDX) {
+ if ((sc->mii_capabilities & BMSR_10TFDX) != 0) {
ADD(IFM_MAKEWORD(IFM_ETHER, IFM_10_T, IFM_FDX, sc->mii_inst),
MII_MEDIA_10_T_FDX);
PRINT("10baseT-FDX");
}
- if (sc->mii_capabilities & BMSR_100TXHDX) {
+ if ((sc->mii_capabilities & BMSR_100TXHDX) != 0) {
ADD(IFM_MAKEWORD(IFM_ETHER, IFM_100_TX, 0, sc->mii_inst),
MII_MEDIA_100_TX);
PRINT("100baseTX");
}
- if (sc->mii_capabilities & BMSR_100TXFDX) {
+ if ((sc->mii_capabilities & BMSR_100TXFDX) != 0) {
ADD(IFM_MAKEWORD(IFM_ETHER, IFM_100_TX, IFM_FDX, sc->mii_inst),
MII_MEDIA_100_TX_FDX);
PRINT("100baseTX-FDX");
}
- if (sc->mii_capabilities & BMSR_100T4) {
+ if ((sc->mii_capabilities & BMSR_100T4) != 0) {
ADD(IFM_MAKEWORD(IFM_ETHER, IFM_100_T4, 0, sc->mii_inst),
MII_MEDIA_100_T4);
PRINT("100baseT4");
}
- if (sc->mii_extcapabilities & EXTSR_MEDIAMASK) {
+ if ((sc->mii_extcapabilities & EXTSR_MEDIAMASK) != 0) {
/*
* XXX Right now only handle 1000SX and 1000TX. Need
- * XXX to handle 1000LX and 1000CX some how.
+ * XXX to handle 1000LX and 1000CX somehow.
*/
- if (sc->mii_extcapabilities & EXTSR_1000XHDX) {
+ if ((sc->mii_extcapabilities & EXTSR_1000XHDX) != 0) {
sc->mii_anegticks = MII_ANEGTICKS_GIGE;
sc->mii_flags |= MIIF_IS_1000X;
ADD(IFM_MAKEWORD(IFM_ETHER, IFM_1000_SX, 0,
sc->mii_inst), MII_MEDIA_1000_X);
PRINT("1000baseSX");
}
- if (sc->mii_extcapabilities & EXTSR_1000XFDX) {
+ if ((sc->mii_extcapabilities & EXTSR_1000XFDX) != 0) {
sc->mii_anegticks = MII_ANEGTICKS_GIGE;
sc->mii_flags |= MIIF_IS_1000X;
ADD(IFM_MAKEWORD(IFM_ETHER, IFM_1000_SX, IFM_FDX,
@@ -382,7 +379,7 @@ mii_phy_add_media(struct mii_softc *sc)
*
* All 1000baseT PHYs have a 1000baseT control register.
*/
- if (sc->mii_extcapabilities & EXTSR_1000THDX) {
+ if ((sc->mii_extcapabilities & EXTSR_1000THDX) != 0) {
sc->mii_anegticks = MII_ANEGTICKS_GIGE;
sc->mii_flags |= MIIF_HAVE_GTCR;
mii->mii_media.ifm_mask |= IFM_ETH_MASTER;
@@ -390,7 +387,7 @@ mii_phy_add_media(struct mii_softc *sc)
sc->mii_inst), MII_MEDIA_1000_T);
PRINT("1000baseT");
}
- if (sc->mii_extcapabilities & EXTSR_1000TFDX) {
+ if ((sc->mii_extcapabilities & EXTSR_1000TFDX) != 0) {
sc->mii_anegticks = MII_ANEGTICKS_GIGE;
sc->mii_flags |= MIIF_HAVE_GTCR;
mii->mii_media.ifm_mask |= IFM_ETH_MASTER;
@@ -400,7 +397,7 @@ mii_phy_add_media(struct mii_softc *sc)
}
}
- if (sc->mii_capabilities & BMSR_ANEG) {
+ if ((sc->mii_capabilities & BMSR_ANEG) != 0) {
ADD(IFM_MAKEWORD(IFM_ETHER, IFM_AUTO, 0, sc->mii_inst),
MII_NMEDIA); /* intentionally invalid index */
PRINT("auto");
@@ -418,8 +415,7 @@ mii_phy_detach(device_t dev)
mii_phy_down(sc);
sc->mii_dev = NULL;
LIST_REMOVE(sc, mii_list);
-
- return(0);
+ return (0);
}
const struct mii_phydesc *
@@ -452,6 +448,5 @@ mii_phy_dev_probe(device_t dev, const struct mii_phydesc *mpd, int mrv)
device_set_desc(dev, mpd->mpd_name);
return (mrv);
}
-
return (ENXIO);
}
diff --git a/sys/dev/mii/miidevs b/sys/dev/mii/miidevs
index e0ea555..34c5f94 100644
--- a/sys/dev/mii/miidevs
+++ b/sys/dev/mii/miidevs
@@ -81,6 +81,7 @@ oui xxINTEL 0x00f800 Intel
oui xxALTIMA 0x000895 Altima Communications
oui xxBROADCOM 0x000818 Broadcom Corporation
oui xxBROADCOM_ALT1 0x0050ef Broadcom Corporation
+oui xxBROADCOM_ALT2 0x00d897 Broadcom Corporation
oui xxICS 0x00057d Integrated Circuit Systems
oui xxSEEQ 0x0005be Seeq
oui xxSIS 0x000760 Silicon Integrated Systems
@@ -153,6 +154,7 @@ model xxBROADCOM_ALT1 BCM5784 0x003a BCM5784 10/100/1000baseTX PHY
model xxBROADCOM_ALT1 BCM5709C 0x003c BCM5709C 10/100/1000baseTX PHY
model xxBROADCOM_ALT1 BCM5761 0x003d BCM5761 10/100/1000baseTX PHY
model xxBROADCOM_ALT1 BCM5709S 0x003f BCM5709S 1000/2500baseSX PHY
+model xxBROADCOM_ALT2 BCM5717C 0x0020 BCM5717C 10/100/1000baseTX PHY
model BROADCOM2 BCM5906 0x0004 BCM5906 10/100baseTX PHY
/* Cicada Semiconductor PHYs (now owned by Vitesse?) */
diff --git a/sys/dev/mii/miivar.h b/sys/dev/mii/miivar.h
index 15a3f3f..6783cf5 100644
--- a/sys/dev/mii/miivar.h
+++ b/sys/dev/mii/miivar.h
@@ -148,7 +148,7 @@ typedef struct mii_softc mii_softc_t;
/*
* Special `locators' passed to mii_attach(). If one of these is not
* an `any' value, we look for *that* PHY and configure it. If both
- * are not `any', that is an error, and mii_attach() will panic.
+ * are not `any', that is an error, and mii_attach() will fail.
*/
#define MII_OFFSET_ANY -1
#define MII_PHY_ANY -1
diff --git a/sys/dev/usb/usb_device.c b/sys/dev/usb/usb_device.c
index 8887fc1..495bd82 100644
--- a/sys/dev/usb/usb_device.c
+++ b/sys/dev/usb/usb_device.c
@@ -88,7 +88,7 @@ static void usb_init_endpoint(struct usb_device *, uint8_t,
struct usb_endpoint *);
static void usb_unconfigure(struct usb_device *, uint8_t);
static void usb_detach_device_sub(struct usb_device *, device_t *,
- uint8_t);
+ char **, uint8_t);
static uint8_t usb_probe_and_attach_sub(struct usb_device *,
struct usb_attach_arg *);
static void usb_init_attach_arg(struct usb_device *,
@@ -1035,9 +1035,10 @@ usb_reset_iface_endpoints(struct usb_device *udev, uint8_t iface_index)
*------------------------------------------------------------------------*/
static void
usb_detach_device_sub(struct usb_device *udev, device_t *ppdev,
- uint8_t flag)
+ char **ppnpinfo, uint8_t flag)
{
device_t dev;
+ char *pnpinfo;
int err;
dev = *ppdev;
@@ -1069,11 +1070,17 @@ usb_detach_device_sub(struct usb_device *udev, device_t *ppdev,
goto error;
}
}
+
+ pnpinfo = *ppnpinfo;
+ if (pnpinfo != NULL) {
+ *ppnpinfo = NULL;
+ free(pnpinfo, M_USBDEV);
+ }
return;
error:
/* Detach is not allowed to fail in the USB world */
- panic("A USB driver would not detach\n");
+ panic("usb_detach_device_sub: A USB driver would not detach\n");
}
/*------------------------------------------------------------------------*
@@ -1122,7 +1129,8 @@ usb_detach_device(struct usb_device *udev, uint8_t iface_index,
/* looks like the end of the USB interfaces */
break;
}
- usb_detach_device_sub(udev, &iface->subdev, flag);
+ usb_detach_device_sub(udev, &iface->subdev,
+ &iface->pnpinfo, flag);
}
}
@@ -2714,3 +2722,37 @@ usbd_enum_is_locked(struct usb_device *udev)
{
return (sx_xlocked(&udev->enum_sx));
}
+
+/*
+ * The following function is used to set the per-interface specific
+ * plug and play information. The string referred to by the pnpinfo
+ * argument can safely be freed after calling this function. The
+ * pnpinfo of an interface will be reset at device detach or when
+ * passing a NULL argument to this function. This function
+ * returns zero on success, else a USB_ERR_XXX failure code.
+ */
+
+usb_error_t
+usbd_set_pnpinfo(struct usb_device *udev, uint8_t iface_index, const char *pnpinfo)
+{
+ struct usb_interface *iface;
+
+ iface = usbd_get_iface(udev, iface_index);
+ if (iface == NULL)
+ return (USB_ERR_INVAL);
+
+ if (iface->pnpinfo != NULL) {
+ free(iface->pnpinfo, M_USBDEV);
+ iface->pnpinfo = NULL;
+ }
+
+ if (pnpinfo == NULL || pnpinfo[0] == 0)
+ return (0); /* success */
+
+ iface->pnpinfo = strdup(pnpinfo, M_USBDEV);
+ if (iface->pnpinfo == NULL)
+ return (USB_ERR_NOMEM);
+
+ return (0); /* success */
+}
+
diff --git a/sys/dev/usb/usb_hub.c b/sys/dev/usb/usb_hub.c
index afeadaa..b2870a3 100644
--- a/sys/dev/usb/usb_hub.c
+++ b/sys/dev/usb/usb_hub.c
@@ -1330,7 +1330,7 @@ uhub_child_pnpinfo_string(device_t parent, device_t child,
"devclass=0x%02x devsubclass=0x%02x "
"sernum=\"%s\" "
"release=0x%04x "
- "intclass=0x%02x intsubclass=0x%02x",
+ "intclass=0x%02x intsubclass=0x%02x" "%s%s",
UGETW(res.udev->ddesc.idVendor),
UGETW(res.udev->ddesc.idProduct),
res.udev->ddesc.bDeviceClass,
@@ -1338,7 +1338,9 @@ uhub_child_pnpinfo_string(device_t parent, device_t child,
usb_get_serial(res.udev),
UGETW(res.udev->ddesc.bcdDevice),
iface->idesc->bInterfaceClass,
- iface->idesc->bInterfaceSubClass);
+ iface->idesc->bInterfaceSubClass,
+ iface->pnpinfo ? " " : "",
+ iface->pnpinfo ? iface->pnpinfo : "");
} else {
if (buflen) {
buf[0] = '\0';
diff --git a/sys/dev/usb/usbdi.h b/sys/dev/usb/usbdi.h
index 1c2d412..6d4a911 100644
--- a/sys/dev/usb/usbdi.h
+++ b/sys/dev/usb/usbdi.h
@@ -171,6 +171,7 @@ struct usb_interface {
struct usb_host_interface *cur_altsetting;
struct usb_device *linux_udev;
void *bsd_priv_sc; /* device specific information */
+ char *pnpinfo; /* additional PnP-info for this interface */
uint8_t num_altsetting; /* number of alternate settings */
uint8_t bsd_iface_index;
};
@@ -444,6 +445,8 @@ enum usb_hc_mode usbd_get_mode(struct usb_device *udev);
enum usb_dev_speed usbd_get_speed(struct usb_device *udev);
void device_set_usb_desc(device_t dev);
void usb_pause_mtx(struct mtx *mtx, int _ticks);
+usb_error_t usbd_set_pnpinfo(struct usb_device *udev,
+ uint8_t iface_index, const char *pnpinfo);
const struct usb_device_id *usbd_lookup_id_by_info(
const struct usb_device_id *id, usb_size_t sizeof_id,
diff --git a/sys/dev/xen/blkback/blkback.c b/sys/dev/xen/blkback/blkback.c
index 72087f5..458149d 100644
--- a/sys/dev/xen/blkback/blkback.c
+++ b/sys/dev/xen/blkback/blkback.c
@@ -2827,8 +2827,11 @@ xbb_detach(device_t dev)
DPRINTF("\n");
- taskqueue_free(xbb->io_taskqueue);
- devstat_remove_entry(xbb->xbb_stats);
+ if (xbb->io_taskqueue != NULL)
+ taskqueue_free(xbb->io_taskqueue);
+
+ if (xbb->xbb_stats != NULL)
+ devstat_remove_entry(xbb->xbb_stats);
xbb_close_backend(xbb);
xbb_free_communication_mem(xbb);
diff --git a/sys/fs/nfs/nfsclstate.h b/sys/fs/nfs/nfsclstate.h
index 72d8eeb..bb46220 100644
--- a/sys/fs/nfs/nfsclstate.h
+++ b/sys/fs/nfs/nfsclstate.h
@@ -118,6 +118,7 @@ struct nfscldeleg {
#define NFSCLDL_NEEDRECLAIM 0x08
#define NFSCLDL_ZAPPED 0x10
#define NFSCLDL_MODTIMESET 0x20
+#define NFSCLDL_DELEGRET 0x40
/*
* MALLOC'd to the correct length to accommodate the file handle.
diff --git a/sys/fs/nfsclient/nfs_clnode.c b/sys/fs/nfsclient/nfs_clnode.c
index 8ca1c43..430b494 100644
--- a/sys/fs/nfsclient/nfs_clnode.c
+++ b/sys/fs/nfsclient/nfs_clnode.c
@@ -236,6 +236,15 @@ ncl_reclaim(struct vop_reclaim_args *ap)
if (prtactive && vrefcnt(vp) != 0)
vprint("ncl_reclaim: pushing active", vp);
+ if (NFS_ISV4(vp) && vp->v_type == VREG)
+ /*
+ * Since mmap()'d files do I/O after VOP_CLOSE(), the NFSv4
+ * Close operations are delayed until ncl_inactive().
+ * However, since VOP_INACTIVE() is not guaranteed to be
+ * called, we need to do it again here.
+ */
+ (void) nfsrpc_close(vp, 1, ap->a_td);
+
/*
* If the NLM is running, give it a chance to abort pending
* locks.
diff --git a/sys/fs/nfsclient/nfs_clstate.c b/sys/fs/nfsclient/nfs_clstate.c
index b6fad20..2281f32 100644
--- a/sys/fs/nfsclient/nfs_clstate.c
+++ b/sys/fs/nfsclient/nfs_clstate.c
@@ -929,8 +929,10 @@ nfscl_getbytelock(vnode_t vp, u_int64_t off, u_int64_t len,
ldp = dp = nfscl_finddeleg(clp, np->n_fhp->nfh_fh,
np->n_fhp->nfh_len);
/* Just sanity check for correct type of delegation */
- if (dp != NULL && ((dp->nfsdl_flags & NFSCLDL_RECALL) ||
- (type == F_WRLCK && !(dp->nfsdl_flags & NFSCLDL_WRITE))))
+ if (dp != NULL && ((dp->nfsdl_flags &
+ (NFSCLDL_RECALL | NFSCLDL_DELEGRET)) != 0 ||
+ (type == F_WRLCK &&
+ (dp->nfsdl_flags & NFSCLDL_WRITE) == 0)))
dp = NULL;
}
if (dp != NULL) {
@@ -2495,8 +2497,8 @@ tryagain:
if (dp->nfsdl_rwlock.nfslock_usecnt == 0 &&
dp->nfsdl_rwlock.nfslock_lock == 0 &&
dp->nfsdl_timestamp < NFSD_MONOSEC &&
- !(dp->nfsdl_flags & (NFSCLDL_RECALL | NFSCLDL_ZAPPED |
- NFSCLDL_NEEDRECLAIM))) {
+ (dp->nfsdl_flags & (NFSCLDL_RECALL | NFSCLDL_ZAPPED |
+ NFSCLDL_NEEDRECLAIM | NFSCLDL_DELEGRET)) == 0) {
clearok = 1;
LIST_FOREACH(owp, &dp->nfsdl_owner, nfsow_list) {
op = LIST_FIRST(&owp->nfsow_open);
@@ -3086,7 +3088,8 @@ nfscl_docb(struct nfsrv_descript *nd, NFSPROC_T *p)
if (clp != NULL) {
dp = nfscl_finddeleg(clp, nfhp->nfh_fh,
nfhp->nfh_len);
- if (dp != NULL) {
+ if (dp != NULL && (dp->nfsdl_flags &
+ NFSCLDL_DELEGRET) == 0) {
dp->nfsdl_flags |=
NFSCLDL_RECALL;
wakeup((caddr_t)clp);
@@ -3338,7 +3341,6 @@ nfscl_recalldeleg(struct nfsclclient *clp, struct nfsmount *nmp,
np = VTONFS(vp);
}
dp->nfsdl_flags &= ~NFSCLDL_MODTIMESET;
- NFSINVALATTRCACHE(np);
/*
* Ok, if it's a write delegation, flush data to the server, so
@@ -3347,21 +3349,14 @@ nfscl_recalldeleg(struct nfsclclient *clp, struct nfsmount *nmp,
ret = 0;
NFSLOCKNODE(np);
if ((dp->nfsdl_flags & NFSCLDL_WRITE) && (np->n_flag & NMODIFIED)) {
-#ifdef APPLE
- OSBitOrAtomic((u_int32_t)NDELEGRECALL, (UInt32 *)&np->n_flag);
-#else
np->n_flag |= NDELEGRECALL;
-#endif
NFSUNLOCKNODE(np);
ret = ncl_flush(vp, MNT_WAIT, cred, p, 1,
called_from_renewthread);
NFSLOCKNODE(np);
-#ifdef APPLE
- OSBitAndAtomic((int32_t)~(NMODIFIED | NDELEGRECALL), (UInt32 *)&np->n_flag);
-#else
- np->n_flag &= ~(NMODIFIED | NDELEGRECALL);
-#endif
+ np->n_flag &= ~NDELEGRECALL;
}
+ NFSINVALATTRCACHE(np);
NFSUNLOCKNODE(np);
if (ret == EIO && called_from_renewthread != 0) {
/*
@@ -3534,8 +3529,10 @@ nfscl_totalrecall(struct nfsclclient *clp)
{
struct nfscldeleg *dp;
- TAILQ_FOREACH(dp, &clp->nfsc_deleg, nfsdl_list)
- dp->nfsdl_flags |= NFSCLDL_RECALL;
+ TAILQ_FOREACH(dp, &clp->nfsc_deleg, nfsdl_list) {
+ if ((dp->nfsdl_flags & NFSCLDL_DELEGRET) == 0)
+ dp->nfsdl_flags |= NFSCLDL_RECALL;
+ }
}
/*
@@ -3754,8 +3751,9 @@ nfscl_mustflush(vnode_t vp)
return (1);
}
dp = nfscl_finddeleg(clp, np->n_fhp->nfh_fh, np->n_fhp->nfh_len);
- if (dp != NULL && (dp->nfsdl_flags & (NFSCLDL_WRITE | NFSCLDL_RECALL))
- == NFSCLDL_WRITE &&
+ if (dp != NULL && (dp->nfsdl_flags &
+ (NFSCLDL_WRITE | NFSCLDL_RECALL | NFSCLDL_DELEGRET)) ==
+ NFSCLDL_WRITE &&
(dp->nfsdl_sizelimit >= np->n_size ||
!NFSHASSTRICT3530(nmp))) {
NFSUNLOCKCLSTATE();
@@ -3787,9 +3785,10 @@ nfscl_nodeleg(vnode_t vp, int writedeleg)
return (1);
}
dp = nfscl_finddeleg(clp, np->n_fhp->nfh_fh, np->n_fhp->nfh_len);
- if (dp != NULL && (dp->nfsdl_flags & NFSCLDL_RECALL) == 0 &&
- (writedeleg == 0 || (dp->nfsdl_flags & NFSCLDL_WRITE)
- == NFSCLDL_WRITE)) {
+ if (dp != NULL &&
+ (dp->nfsdl_flags & (NFSCLDL_RECALL | NFSCLDL_DELEGRET)) == 0 &&
+ (writedeleg == 0 || (dp->nfsdl_flags & NFSCLDL_WRITE) ==
+ NFSCLDL_WRITE)) {
NFSUNLOCKCLSTATE();
return (0);
}
@@ -3860,6 +3859,7 @@ nfscl_removedeleg(vnode_t vp, NFSPROC_T *p, nfsv4stateid_t *stp)
}
}
if (needsrecall && !triedrecall) {
+ dp->nfsdl_flags |= NFSCLDL_DELEGRET;
islept = 0;
while (!igotlock) {
igotlock = nfsv4_lock(&clp->nfsc_lock, 1,
@@ -3958,6 +3958,7 @@ nfscl_renamedeleg(vnode_t fvp, nfsv4stateid_t *fstp, int *gotfdp, vnode_t tvp,
}
}
if (needsrecall && !triedrecall) {
+ dp->nfsdl_flags |= NFSCLDL_DELEGRET;
islept = 0;
while (!igotlock) {
igotlock = nfsv4_lock(&clp->nfsc_lock, 1,
diff --git a/sys/fs/nfsclient/nfs_clvnops.c b/sys/fs/nfsclient/nfs_clvnops.c
index b02c4bf..e32f397 100644
--- a/sys/fs/nfsclient/nfs_clvnops.c
+++ b/sys/fs/nfsclient/nfs_clvnops.c
@@ -494,24 +494,46 @@ nfs_open(struct vop_open_args *ap)
* Now, if this Open will be doing reading, re-validate/flush the
* cache, so that Close/Open coherency is maintained.
*/
- if ((fmode & FREAD) != 0 &&
- (!NFS_ISV4(vp) || nfscl_mustflush(vp) != 0)) {
+ mtx_lock(&np->n_mtx);
+ if (np->n_flag & NMODIFIED) {
+ mtx_unlock(&np->n_mtx);
+ error = ncl_vinvalbuf(vp, V_SAVE, ap->a_td, 1);
+ if (error == EINTR || error == EIO) {
+ if (NFS_ISV4(vp))
+ (void) nfsrpc_close(vp, 0, ap->a_td);
+ return (error);
+ }
mtx_lock(&np->n_mtx);
- if (np->n_flag & NMODIFIED) {
- mtx_unlock(&np->n_mtx);
- error = ncl_vinvalbuf(vp, V_SAVE, ap->a_td, 1);
- if (error == EINTR || error == EIO) {
- if (NFS_ISV4(vp))
- (void) nfsrpc_close(vp, 0, ap->a_td);
- return (error);
- }
- mtx_lock(&np->n_mtx);
- np->n_attrstamp = 0;
+ np->n_attrstamp = 0;
+ if (vp->v_type == VDIR)
+ np->n_direofoffset = 0;
+ mtx_unlock(&np->n_mtx);
+ error = VOP_GETATTR(vp, &vattr, ap->a_cred);
+ if (error) {
+ if (NFS_ISV4(vp))
+ (void) nfsrpc_close(vp, 0, ap->a_td);
+ return (error);
+ }
+ mtx_lock(&np->n_mtx);
+ np->n_mtime = vattr.va_mtime;
+ if (NFS_ISV4(vp))
+ np->n_change = vattr.va_filerev;
+ } else {
+ mtx_unlock(&np->n_mtx);
+ error = VOP_GETATTR(vp, &vattr, ap->a_cred);
+ if (error) {
+ if (NFS_ISV4(vp))
+ (void) nfsrpc_close(vp, 0, ap->a_td);
+ return (error);
+ }
+ mtx_lock(&np->n_mtx);
+ if ((NFS_ISV4(vp) && np->n_change != vattr.va_filerev) ||
+ NFS_TIMESPEC_COMPARE(&np->n_mtime, &vattr.va_mtime)) {
if (vp->v_type == VDIR)
np->n_direofoffset = 0;
mtx_unlock(&np->n_mtx);
- error = VOP_GETATTR(vp, &vattr, ap->a_cred);
- if (error) {
+ error = ncl_vinvalbuf(vp, V_SAVE, ap->a_td, 1);
+ if (error == EINTR || error == EIO) {
if (NFS_ISV4(vp))
(void) nfsrpc_close(vp, 0, ap->a_td);
return (error);
@@ -520,42 +542,16 @@ nfs_open(struct vop_open_args *ap)
np->n_mtime = vattr.va_mtime;
if (NFS_ISV4(vp))
np->n_change = vattr.va_filerev;
- mtx_unlock(&np->n_mtx);
- } else {
- mtx_unlock(&np->n_mtx);
- error = VOP_GETATTR(vp, &vattr, ap->a_cred);
- if (error) {
- if (NFS_ISV4(vp))
- (void) nfsrpc_close(vp, 0, ap->a_td);
- return (error);
- }
- mtx_lock(&np->n_mtx);
- if ((NFS_ISV4(vp) && np->n_change != vattr.va_filerev) ||
- NFS_TIMESPEC_COMPARE(&np->n_mtime, &vattr.va_mtime)) {
- if (vp->v_type == VDIR)
- np->n_direofoffset = 0;
- mtx_unlock(&np->n_mtx);
- error = ncl_vinvalbuf(vp, V_SAVE, ap->a_td, 1);
- if (error == EINTR || error == EIO) {
- if (NFS_ISV4(vp))
- (void) nfsrpc_close(vp, 0,
- ap->a_td);
- return (error);
- }
- mtx_lock(&np->n_mtx);
- np->n_mtime = vattr.va_mtime;
- if (NFS_ISV4(vp))
- np->n_change = vattr.va_filerev;
- }
- mtx_unlock(&np->n_mtx);
}
}
/*
* If the object has >= 1 O_DIRECT active opens, we disable caching.
*/
- if (newnfs_directio_enable && (fmode & O_DIRECT) && (vp->v_type == VREG)) {
+ if (newnfs_directio_enable && (fmode & O_DIRECT) &&
+ (vp->v_type == VREG)) {
if (np->n_directio_opens == 0) {
+ mtx_unlock(&np->n_mtx);
error = ncl_vinvalbuf(vp, V_SAVE, ap->a_td, 1);
if (error) {
if (NFS_ISV4(vp))
@@ -564,12 +560,10 @@ nfs_open(struct vop_open_args *ap)
}
mtx_lock(&np->n_mtx);
np->n_flag |= NNONCACHE;
- } else {
- mtx_lock(&np->n_mtx);
}
np->n_directio_opens++;
- mtx_unlock(&np->n_mtx);
}
+ mtx_unlock(&np->n_mtx);
vnode_create_vobject(vp, vattr.va_size, ap->a_td);
return (0);
}
diff --git a/sys/i386/acpica/acpi_wakeup.c b/sys/i386/acpica/acpi_wakeup.c
index 60bc31f..2397d80 100644
--- a/sys/i386/acpica/acpi_wakeup.c
+++ b/sys/i386/acpica/acpi_wakeup.c
@@ -45,7 +45,7 @@ __FBSDID("$FreeBSD$");
#include <machine/bus.h>
#include <machine/cpufunc.h>
#include <machine/intr_machdep.h>
-#include <machine/mca.h>
+#include <x86/mca.h>
#include <machine/segments.h>
#include <contrib/dev/acpica/include/acpi.h>
diff --git a/sys/i386/acpica/madt.c b/sys/i386/acpica/madt.c
index 5013c21..f153696 100644
--- a/sys/i386/acpica/madt.c
+++ b/sys/i386/acpica/madt.c
@@ -39,7 +39,7 @@ __FBSDID("$FreeBSD$");
#include <vm/vm.h>
#include <vm/pmap.h>
-#include <machine/apicreg.h>
+#include <x86/apicreg.h>
#include <machine/intr_machdep.h>
#include <machine/apicvar.h>
diff --git a/sys/i386/i386/apic_vector.s b/sys/i386/i386/apic_vector.s
index cbe3871..100ce90 100644
--- a/sys/i386/i386/apic_vector.s
+++ b/sys/i386/i386/apic_vector.s
@@ -39,7 +39,7 @@
#include "opt_smp.h"
#include <machine/asmacros.h>
-#include <machine/apicreg.h>
+#include <x86/apicreg.h>
#include "assym.s"
diff --git a/sys/i386/i386/dump_machdep.c b/sys/i386/i386/dump_machdep.c
deleted file mode 100644
index d0c6ba7..0000000
--- a/sys/i386/i386/dump_machdep.c
+++ /dev/null
@@ -1,363 +0,0 @@
-/*-
- * Copyright (c) 2002 Marcel Moolenaar
- * 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 THE AUTHOR ``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 THE AUTHOR 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.
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/conf.h>
-#include <sys/cons.h>
-#include <sys/sysctl.h>
-#include <sys/kernel.h>
-#include <sys/kerneldump.h>
-#include <vm/vm.h>
-#include <vm/pmap.h>
-#include <machine/elf.h>
-#include <machine/md_var.h>
-
-CTASSERT(sizeof(struct kerneldumpheader) == 512);
-
-int do_minidump = 1;
-TUNABLE_INT("debug.minidump", &do_minidump);
-SYSCTL_INT(_debug, OID_AUTO, minidump, CTLFLAG_RW, &do_minidump, 0,
- "Enable mini crash dumps");
-
-/*
- * Don't touch the first SIZEOF_METADATA bytes on the dump device. This
- * is to protect us from metadata and to protect metadata from us.
- */
-#define SIZEOF_METADATA (64*1024)
-
-#define MD_ALIGN(x) (((off_t)(x) + PAGE_MASK) & ~PAGE_MASK)
-#define DEV_ALIGN(x) (((off_t)(x) + (DEV_BSIZE-1)) & ~(DEV_BSIZE-1))
-
-struct md_pa {
- vm_paddr_t md_start;
- vm_paddr_t md_size;
-};
-
-typedef int callback_t(struct md_pa *, int, void *);
-
-static struct kerneldumpheader kdh;
-static off_t dumplo, fileofs;
-
-/* Handle buffered writes. */
-static char buffer[DEV_BSIZE];
-static size_t fragsz;
-
-/* 20 phys_avail entry pairs correspond to 10 md_pa's */
-static struct md_pa dump_map[10];
-
-static void
-md_pa_init(void)
-{
- int n, idx;
-
- bzero(dump_map, sizeof(dump_map));
- for (n = 0; n < sizeof(dump_map) / sizeof(dump_map[0]); n++) {
- idx = n * 2;
- if (dump_avail[idx] == 0 && dump_avail[idx + 1] == 0)
- break;
- dump_map[n].md_start = dump_avail[idx];
- dump_map[n].md_size = dump_avail[idx + 1] - dump_avail[idx];
- }
-}
-
-static struct md_pa *
-md_pa_first(void)
-{
-
- return (&dump_map[0]);
-}
-
-static struct md_pa *
-md_pa_next(struct md_pa *mdp)
-{
-
- mdp++;
- if (mdp->md_size == 0)
- mdp = NULL;
- return (mdp);
-}
-
-static int
-buf_write(struct dumperinfo *di, char *ptr, size_t sz)
-{
- size_t len;
- int error;
-
- while (sz) {
- len = DEV_BSIZE - fragsz;
- if (len > sz)
- len = sz;
- bcopy(ptr, buffer + fragsz, len);
- fragsz += len;
- ptr += len;
- sz -= len;
- if (fragsz == DEV_BSIZE) {
- error = dump_write(di, buffer, 0, dumplo,
- DEV_BSIZE);
- if (error)
- return error;
- dumplo += DEV_BSIZE;
- fragsz = 0;
- }
- }
-
- return (0);
-}
-
-static int
-buf_flush(struct dumperinfo *di)
-{
- int error;
-
- if (fragsz == 0)
- return (0);
-
- error = dump_write(di, buffer, 0, dumplo, DEV_BSIZE);
- dumplo += DEV_BSIZE;
- fragsz = 0;
- return (error);
-}
-
-#define PG2MB(pgs) ((pgs + (1 << 8) - 1) >> 8)
-
-static int
-cb_dumpdata(struct md_pa *mdp, int seqnr, void *arg)
-{
- struct dumperinfo *di = (struct dumperinfo*)arg;
- vm_paddr_t a, pa;
- void *va;
- uint64_t pgs;
- size_t counter, sz, chunk;
- int i, c, error, twiddle;
- u_int maxdumppgs;
-
- error = 0; /* catch case in which chunk size is 0 */
- counter = 0; /* Update twiddle every 16MB */
- twiddle = 0;
- va = 0;
- pgs = mdp->md_size / PAGE_SIZE;
- pa = mdp->md_start;
- maxdumppgs = min(di->maxiosize / PAGE_SIZE, MAXDUMPPGS);
- if (maxdumppgs == 0) /* seatbelt */
- maxdumppgs = 1;
-
- printf(" chunk %d: %lldMB (%lld pages)", seqnr, PG2MB(pgs), pgs);
-
- while (pgs) {
- chunk = pgs;
- if (chunk > maxdumppgs)
- chunk = maxdumppgs;
- sz = chunk << PAGE_SHIFT;
- counter += sz;
- if (counter >> 24) {
- printf(" %lld", PG2MB(pgs));
- counter &= (1<<24) - 1;
- }
- for (i = 0; i < chunk; i++) {
- a = pa + i * PAGE_SIZE;
- va = pmap_kenter_temporary(trunc_page(a), i);
- }
- error = dump_write(di, va, 0, dumplo, sz);
- if (error)
- break;
- dumplo += sz;
- pgs -= chunk;
- pa += sz;
-
- /* Check for user abort. */
- c = cncheckc();
- if (c == 0x03)
- return (ECANCELED);
- if (c != -1)
- printf(" (CTRL-C to abort) ");
- }
- printf(" ... %s\n", (error) ? "fail" : "ok");
- return (error);
-}
-
-static int
-cb_dumphdr(struct md_pa *mdp, int seqnr, void *arg)
-{
- struct dumperinfo *di = (struct dumperinfo*)arg;
- Elf_Phdr phdr;
- uint64_t size;
- int error;
-
- size = mdp->md_size;
- bzero(&phdr, sizeof(phdr));
- phdr.p_type = PT_LOAD;
- phdr.p_flags = PF_R; /* XXX */
- phdr.p_offset = fileofs;
- phdr.p_vaddr = mdp->md_start;
- phdr.p_paddr = mdp->md_start;
- phdr.p_filesz = size;
- phdr.p_memsz = size;
- phdr.p_align = PAGE_SIZE;
-
- error = buf_write(di, (char*)&phdr, sizeof(phdr));
- fileofs += phdr.p_filesz;
- return (error);
-}
-
-static int
-cb_size(struct md_pa *mdp, int seqnr, void *arg)
-{
- uint64_t *sz = (uint64_t*)arg;
-
- *sz += (uint64_t)mdp->md_size;
- return (0);
-}
-
-static int
-foreach_chunk(callback_t cb, void *arg)
-{
- struct md_pa *mdp;
- int error, seqnr;
-
- seqnr = 0;
- mdp = md_pa_first();
- while (mdp != NULL) {
- error = (*cb)(mdp, seqnr++, arg);
- if (error)
- return (-error);
- mdp = md_pa_next(mdp);
- }
- return (seqnr);
-}
-
-void
-dumpsys(struct dumperinfo *di)
-{
- Elf_Ehdr ehdr;
- uint64_t dumpsize;
- off_t hdrgap;
- size_t hdrsz;
- int error;
-
- if (do_minidump) {
- minidumpsys(di);
- return;
- }
- bzero(&ehdr, sizeof(ehdr));
- ehdr.e_ident[EI_MAG0] = ELFMAG0;
- ehdr.e_ident[EI_MAG1] = ELFMAG1;
- ehdr.e_ident[EI_MAG2] = ELFMAG2;
- ehdr.e_ident[EI_MAG3] = ELFMAG3;
- ehdr.e_ident[EI_CLASS] = ELF_CLASS;
-#if BYTE_ORDER == LITTLE_ENDIAN
- ehdr.e_ident[EI_DATA] = ELFDATA2LSB;
-#else
- ehdr.e_ident[EI_DATA] = ELFDATA2MSB;
-#endif
- ehdr.e_ident[EI_VERSION] = EV_CURRENT;
- ehdr.e_ident[EI_OSABI] = ELFOSABI_STANDALONE; /* XXX big picture? */
- ehdr.e_type = ET_CORE;
- ehdr.e_machine = EM_386;
- ehdr.e_phoff = sizeof(ehdr);
- ehdr.e_flags = 0;
- ehdr.e_ehsize = sizeof(ehdr);
- ehdr.e_phentsize = sizeof(Elf_Phdr);
- ehdr.e_shentsize = sizeof(Elf_Shdr);
-
- md_pa_init();
-
- /* Calculate dump size. */
- dumpsize = 0L;
- ehdr.e_phnum = foreach_chunk(cb_size, &dumpsize);
- hdrsz = ehdr.e_phoff + ehdr.e_phnum * ehdr.e_phentsize;
- fileofs = MD_ALIGN(hdrsz);
- dumpsize += fileofs;
- hdrgap = fileofs - DEV_ALIGN(hdrsz);
-
- /* Determine dump offset on device. */
- if (di->mediasize < SIZEOF_METADATA + dumpsize + sizeof(kdh) * 2) {
- error = ENOSPC;
- goto fail;
- }
- dumplo = di->mediaoffset + di->mediasize - dumpsize;
- dumplo -= sizeof(kdh) * 2;
-
- mkdumpheader(&kdh, KERNELDUMPMAGIC, KERNELDUMP_I386_VERSION, dumpsize, di->blocksize);
-
- printf("Dumping %llu MB (%d chunks)\n", (long long)dumpsize >> 20,
- ehdr.e_phnum);
-
- /* Dump leader */
- error = dump_write(di, &kdh, 0, dumplo, sizeof(kdh));
- if (error)
- goto fail;
- dumplo += sizeof(kdh);
-
- /* Dump ELF header */
- error = buf_write(di, (char*)&ehdr, sizeof(ehdr));
- if (error)
- goto fail;
-
- /* Dump program headers */
- error = foreach_chunk(cb_dumphdr, di);
- if (error < 0)
- goto fail;
- buf_flush(di);
-
- /*
- * All headers are written using blocked I/O, so we know the
- * current offset is (still) block aligned. Skip the alignement
- * in the file to have the segment contents aligned at page
- * boundary. We cannot use MD_ALIGN on dumplo, because we don't
- * care and may very well be unaligned within the dump device.
- */
- dumplo += hdrgap;
-
- /* Dump memory chunks (updates dumplo) */
- error = foreach_chunk(cb_dumpdata, di);
- if (error < 0)
- goto fail;
-
- /* Dump trailer */
- error = dump_write(di, &kdh, 0, dumplo, sizeof(kdh));
- if (error)
- goto fail;
-
- /* Signal completion, signoff and exit stage left. */
- dump_write(di, NULL, 0, 0, 0);
- printf("\nDump complete\n");
- return;
-
- fail:
- if (error < 0)
- error = -error;
-
- if (error == ECANCELED)
- printf("\nDump aborted\n");
- else if (error == ENOSPC)
- printf("\nDump failed. Partition too small.\n");
- else
- printf("\n** DUMP FAILED (ERROR %d) **\n", error);
-}
diff --git a/sys/i386/i386/genassym.c b/sys/i386/i386/genassym.c
index fae7833..523b194 100644
--- a/sys/i386/i386/genassym.c
+++ b/sys/i386/i386/genassym.c
@@ -70,7 +70,7 @@ __FBSDID("$FreeBSD$");
#include <nfsclient/nfs.h>
#include <nfsclient/nfsdiskless.h>
#ifdef DEV_APIC
-#include <machine/apicreg.h>
+#include <x86/apicreg.h>
#endif
#include <machine/cpu.h>
#include <machine/pcb.h>
diff --git a/sys/i386/i386/intr_machdep.c b/sys/i386/i386/intr_machdep.c
index 35179fa..77b8004 100644
--- a/sys/i386/i386/intr_machdep.c
+++ b/sys/i386/i386/intr_machdep.c
@@ -424,7 +424,7 @@ intr_next_cpu(void)
/* Leave all interrupts on the BSP during boot. */
if (!assign_cpu)
- return (cpu_apic_ids[0]);
+ return (PCPU_GET(apic_id));
mtx_lock_spin(&icu_lock);
apic_id = cpu_apic_ids[current_cpu];
diff --git a/sys/i386/i386/machdep.c b/sys/i386/i386/machdep.c
index 5c0b7ff..255bec6 100644
--- a/sys/i386/i386/machdep.c
+++ b/sys/i386/i386/machdep.c
@@ -115,7 +115,7 @@ __FBSDID("$FreeBSD$");
#include <machine/cpu.h>
#include <machine/cputypes.h>
#include <machine/intr_machdep.h>
-#include <machine/mca.h>
+#include <x86/mca.h>
#include <machine/md_var.h>
#include <machine/metadata.h>
#include <machine/pc/bios.h>
diff --git a/sys/i386/i386/mp_machdep.c b/sys/i386/i386/mp_machdep.c
index c69f6f9..b99c19c 100644
--- a/sys/i386/i386/mp_machdep.c
+++ b/sys/i386/i386/mp_machdep.c
@@ -72,10 +72,10 @@ __FBSDID("$FreeBSD$");
#include <vm/vm_kern.h>
#include <vm/vm_extern.h>
-#include <machine/apicreg.h>
+#include <x86/apicreg.h>
#include <machine/clock.h>
#include <machine/cputypes.h>
-#include <machine/mca.h>
+#include <x86/mca.h>
#include <machine/md_var.h>
#include <machine/mp_watchdog.h>
#include <machine/pcb.h>
diff --git a/sys/i386/i386/mp_watchdog.c b/sys/i386/i386/mp_watchdog.c
index 1803270..5cbd649 100644
--- a/sys/i386/i386/mp_watchdog.c
+++ b/sys/i386/i386/mp_watchdog.c
@@ -44,7 +44,7 @@
#include <sys/systm.h>
#include <machine/smp.h>
-#include <machine/apicreg.h>
+#include <x86/apicreg.h>
#include <machine/apicvar.h>
#include <machine/mp_watchdog.h>
diff --git a/sys/i386/i386/mpboot.s b/sys/i386/i386/mpboot.s
index 8870858..a3ef283 100644
--- a/sys/i386/i386/mpboot.s
+++ b/sys/i386/i386/mpboot.s
@@ -32,7 +32,7 @@
#include "opt_pmap.h"
#include <machine/asmacros.h> /* miscellaneous asm macros */
-#include <machine/apicreg.h>
+#include <x86/apicreg.h>
#include <machine/specialreg.h>
#include "assym.s"
diff --git a/sys/i386/i386/mptable_pci.c b/sys/i386/i386/mptable_pci.c
deleted file mode 100644
index 47a666d..0000000
--- a/sys/i386/i386/mptable_pci.c
+++ /dev/null
@@ -1,177 +0,0 @@
-/*-
- * Copyright (c) 2003 John Baldwin <jhb@FreeBSD.org>
- * 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.
- * 3. Neither the name of the author nor the names of any co-contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``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 THE AUTHOR 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.
- */
-
-/*
- * Host to PCI and PCI to PCI bridge drivers that use the MP Table to route
- * interrupts from PCI devices to I/O APICs.
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/bus.h>
-#include <sys/kernel.h>
-#include <sys/module.h>
-
-#include <dev/pci/pcireg.h>
-#include <dev/pci/pcivar.h>
-#include <dev/pci/pcib_private.h>
-#include <machine/legacyvar.h>
-#include <machine/mptable.h>
-#include <machine/pci_cfgreg.h>
-
-#include "pcib_if.h"
-
-/* Host to PCI bridge driver. */
-
-static int
-mptable_hostb_probe(device_t dev)
-{
-
- if (pci_cfgregopen() == 0)
- return (ENXIO);
- if (mptable_pci_probe_table(pcib_get_bus(dev)) != 0)
- return (ENXIO);
- device_set_desc(dev, "MPTable Host-PCI bridge");
- return (0);
-}
-
-static int
-mptable_hostb_attach(device_t dev)
-{
-
- device_add_child(dev, "pci", pcib_get_bus(dev));
- return (bus_generic_attach(dev));
-}
-
-/* Pass MSI requests up to the nexus. */
-static int
-mptable_hostb_alloc_msi(device_t pcib, device_t dev, int count, int maxcount,
- int *irqs)
-{
- device_t bus;
-
- bus = device_get_parent(pcib);
- return (PCIB_ALLOC_MSI(device_get_parent(bus), dev, count, maxcount,
- irqs));
-}
-
-static int
-mptable_hostb_alloc_msix(device_t pcib, device_t dev, int *irq)
-{
- device_t bus;
-
- bus = device_get_parent(pcib);
- return (PCIB_ALLOC_MSIX(device_get_parent(bus), dev, irq));
-}
-
-static int
-mptable_hostb_map_msi(device_t pcib, device_t dev, int irq, uint64_t *addr,
- uint32_t *data)
-{
- device_t bus;
-
- bus = device_get_parent(pcib);
- return (PCIB_MAP_MSI(device_get_parent(bus), dev, irq, addr, data));
-}
-
-static device_method_t mptable_hostb_methods[] = {
- /* Device interface */
- DEVMETHOD(device_probe, mptable_hostb_probe),
- DEVMETHOD(device_attach, mptable_hostb_attach),
- DEVMETHOD(device_shutdown, bus_generic_shutdown),
- DEVMETHOD(device_suspend, bus_generic_suspend),
- DEVMETHOD(device_resume, bus_generic_resume),
-
- /* Bus interface */
- DEVMETHOD(bus_print_child, bus_generic_print_child),
- DEVMETHOD(bus_read_ivar, legacy_pcib_read_ivar),
- DEVMETHOD(bus_write_ivar, legacy_pcib_write_ivar),
- DEVMETHOD(bus_alloc_resource, legacy_pcib_alloc_resource),
- DEVMETHOD(bus_release_resource, bus_generic_release_resource),
- DEVMETHOD(bus_activate_resource, bus_generic_activate_resource),
- DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource),
- DEVMETHOD(bus_setup_intr, bus_generic_setup_intr),
- DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr),
-
- /* pcib interface */
- DEVMETHOD(pcib_maxslots, legacy_pcib_maxslots),
- DEVMETHOD(pcib_read_config, legacy_pcib_read_config),
- DEVMETHOD(pcib_write_config, legacy_pcib_write_config),
- DEVMETHOD(pcib_route_interrupt, mptable_pci_route_interrupt),
- DEVMETHOD(pcib_alloc_msi, mptable_hostb_alloc_msi),
- DEVMETHOD(pcib_release_msi, pcib_release_msi),
- DEVMETHOD(pcib_alloc_msix, mptable_hostb_alloc_msix),
- DEVMETHOD(pcib_release_msix, pcib_release_msix),
- DEVMETHOD(pcib_map_msi, mptable_hostb_map_msi),
-
- { 0, 0 }
-};
-
-static devclass_t hostb_devclass;
-
-DEFINE_CLASS_0(pcib, mptable_hostb_driver, mptable_hostb_methods, 1);
-DRIVER_MODULE(mptable_pcib, legacy, mptable_hostb_driver, hostb_devclass, 0, 0);
-
-/* PCI to PCI bridge driver. */
-
-static int
-mptable_pcib_probe(device_t dev)
-{
- int bus;
-
- if ((pci_get_class(dev) != PCIC_BRIDGE) ||
- (pci_get_subclass(dev) != PCIS_BRIDGE_PCI))
- return (ENXIO);
- bus = pci_read_config(dev, PCIR_SECBUS_1, 1);
- if (bus == 0)
- return (ENXIO);
- if (mptable_pci_probe_table(bus) != 0)
- return (ENXIO);
- device_set_desc(dev, "MPTable PCI-PCI bridge");
- return (-1000);
-}
-
-static device_method_t mptable_pcib_pci_methods[] = {
- /* Device interface */
- DEVMETHOD(device_probe, mptable_pcib_probe),
-
- /* pcib interface */
- DEVMETHOD(pcib_route_interrupt, mptable_pci_route_interrupt),
-
- {0, 0}
-};
-
-static devclass_t pcib_devclass;
-
-DEFINE_CLASS_1(pcib, mptable_pcib_driver, mptable_pcib_pci_methods,
- sizeof(struct pcib_softc), pcib_driver);
-DRIVER_MODULE(mptable_pcib, pci, mptable_pcib_driver, pcib_devclass, 0, 0);
diff --git a/sys/i386/i386/trap.c b/sys/i386/i386/trap.c
index 7b7bdc4..dc10559 100644
--- a/sys/i386/i386/trap.c
+++ b/sys/i386/i386/trap.c
@@ -86,7 +86,7 @@ __FBSDID("$FreeBSD$");
#include <machine/cpu.h>
#include <machine/intr_machdep.h>
-#include <machine/mca.h>
+#include <x86/mca.h>
#include <machine/md_var.h>
#include <machine/pcb.h>
#ifdef SMP
diff --git a/sys/i386/include/apicreg.h b/sys/i386/include/apicreg.h
deleted file mode 100644
index fee629b..0000000
--- a/sys/i386/include/apicreg.h
+++ /dev/null
@@ -1,445 +0,0 @@
-/*-
- * Copyright (c) 1996, by Peter Wemm and Steve Passe
- * 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. The name of the developer may NOT be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``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 THE AUTHOR 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 _MACHINE_APICREG_H_
-#define _MACHINE_APICREG_H_
-
-/*
- * Local && I/O APIC definitions.
- */
-
-/*
- * Pentium P54C+ Built-in APIC
- * (Advanced programmable Interrupt Controller)
- *
- * Base Address of Built-in APIC in memory location
- * is 0xfee00000.
- *
- * Map of APIC Registers:
- *
- * Offset (hex) Description Read/Write state
- * 000 Reserved
- * 010 Reserved
- * 020 ID Local APIC ID R/W
- * 030 VER Local APIC Version R
- * 040 Reserved
- * 050 Reserved
- * 060 Reserved
- * 070 Reserved
- * 080 Task Priority Register R/W
- * 090 Arbitration Priority Register R
- * 0A0 Processor Priority Register R
- * 0B0 EOI Register W
- * 0C0 RRR Remote read R
- * 0D0 Logical Destination R/W
- * 0E0 Destination Format Register 0..27 R; 28..31 R/W
- * 0F0 SVR Spurious Interrupt Vector Reg. 0..3 R; 4..9 R/W
- * 100 ISR 000-031 R
- * 110 ISR 032-063 R
- * 120 ISR 064-095 R
- * 130 ISR 095-128 R
- * 140 ISR 128-159 R
- * 150 ISR 160-191 R
- * 160 ISR 192-223 R
- * 170 ISR 224-255 R
- * 180 TMR 000-031 R
- * 190 TMR 032-063 R
- * 1A0 TMR 064-095 R
- * 1B0 TMR 095-128 R
- * 1C0 TMR 128-159 R
- * 1D0 TMR 160-191 R
- * 1E0 TMR 192-223 R
- * 1F0 TMR 224-255 R
- * 200 IRR 000-031 R
- * 210 IRR 032-063 R
- * 220 IRR 064-095 R
- * 230 IRR 095-128 R
- * 240 IRR 128-159 R
- * 250 IRR 160-191 R
- * 260 IRR 192-223 R
- * 270 IRR 224-255 R
- * 280 Error Status Register R
- * 290 Reserved
- * 2A0 Reserved
- * 2B0 Reserved
- * 2C0 Reserved
- * 2D0 Reserved
- * 2E0 Reserved
- * 2F0 Local Vector Table (CMCI) R/W
- * 300 ICR_LOW Interrupt Command Reg. (0-31) R/W
- * 310 ICR_HI Interrupt Command Reg. (32-63) R/W
- * 320 Local Vector Table (Timer) R/W
- * 330 Local Vector Table (Thermal) R/W (PIV+)
- * 340 Local Vector Table (Performance) R/W (P6+)
- * 350 LVT1 Local Vector Table (LINT0) R/W
- * 360 LVT2 Local Vector Table (LINT1) R/W
- * 370 LVT3 Local Vector Table (ERROR) R/W
- * 380 Initial Count Reg. for Timer R/W
- * 390 Current Count of Timer R
- * 3A0 Reserved
- * 3B0 Reserved
- * 3C0 Reserved
- * 3D0 Reserved
- * 3E0 Timer Divide Configuration Reg. R/W
- * 3F0 Reserved
- */
-
-
-/******************************************************************************
- * global defines, etc.
- */
-
-
-/******************************************************************************
- * LOCAL APIC structure
- */
-
-#ifndef LOCORE
-#include <sys/types.h>
-
-#define PAD3 int : 32; int : 32; int : 32
-#define PAD4 int : 32; int : 32; int : 32; int : 32
-
-struct LAPIC {
- /* reserved */ PAD4;
- /* reserved */ PAD4;
- u_int32_t id; PAD3;
- u_int32_t version; PAD3;
- /* reserved */ PAD4;
- /* reserved */ PAD4;
- /* reserved */ PAD4;
- /* reserved */ PAD4;
- u_int32_t tpr; PAD3;
- u_int32_t apr; PAD3;
- u_int32_t ppr; PAD3;
- u_int32_t eoi; PAD3;
- /* reserved */ PAD4;
- u_int32_t ldr; PAD3;
- u_int32_t dfr; PAD3;
- u_int32_t svr; PAD3;
- u_int32_t isr0; PAD3;
- u_int32_t isr1; PAD3;
- u_int32_t isr2; PAD3;
- u_int32_t isr3; PAD3;
- u_int32_t isr4; PAD3;
- u_int32_t isr5; PAD3;
- u_int32_t isr6; PAD3;
- u_int32_t isr7; PAD3;
- u_int32_t tmr0; PAD3;
- u_int32_t tmr1; PAD3;
- u_int32_t tmr2; PAD3;
- u_int32_t tmr3; PAD3;
- u_int32_t tmr4; PAD3;
- u_int32_t tmr5; PAD3;
- u_int32_t tmr6; PAD3;
- u_int32_t tmr7; PAD3;
- u_int32_t irr0; PAD3;
- u_int32_t irr1; PAD3;
- u_int32_t irr2; PAD3;
- u_int32_t irr3; PAD3;
- u_int32_t irr4; PAD3;
- u_int32_t irr5; PAD3;
- u_int32_t irr6; PAD3;
- u_int32_t irr7; PAD3;
- u_int32_t esr; PAD3;
- /* reserved */ PAD4;
- /* reserved */ PAD4;
- /* reserved */ PAD4;
- /* reserved */ PAD4;
- /* reserved */ PAD4;
- /* reserved */ PAD4;
- u_int32_t lvt_cmci; PAD3;
- u_int32_t icr_lo; PAD3;
- u_int32_t icr_hi; PAD3;
- u_int32_t lvt_timer; PAD3;
- u_int32_t lvt_thermal; PAD3;
- u_int32_t lvt_pcint; PAD3;
- u_int32_t lvt_lint0; PAD3;
- u_int32_t lvt_lint1; PAD3;
- u_int32_t lvt_error; PAD3;
- u_int32_t icr_timer; PAD3;
- u_int32_t ccr_timer; PAD3;
- /* reserved */ PAD4;
- /* reserved */ PAD4;
- /* reserved */ PAD4;
- /* reserved */ PAD4;
- u_int32_t dcr_timer; PAD3;
- /* reserved */ PAD4;
-};
-
-typedef struct LAPIC lapic_t;
-
-/******************************************************************************
- * I/O APIC structure
- */
-
-struct IOAPIC {
- u_int32_t ioregsel; PAD3;
- u_int32_t iowin; PAD3;
-};
-
-typedef struct IOAPIC ioapic_t;
-
-#undef PAD4
-#undef PAD3
-
-#endif /* !LOCORE */
-
-
-/******************************************************************************
- * various code 'logical' values
- */
-
-/******************************************************************************
- * LOCAL APIC defines
- */
-
-/* default physical locations of LOCAL (CPU) APICs */
-#define DEFAULT_APIC_BASE 0xfee00000
-
-/* constants relating to APIC ID registers */
-#define APIC_ID_MASK 0xff000000
-#define APIC_ID_SHIFT 24
-#define APIC_ID_CLUSTER 0xf0
-#define APIC_ID_CLUSTER_ID 0x0f
-#define APIC_MAX_CLUSTER 0xe
-#define APIC_MAX_INTRACLUSTER_ID 3
-#define APIC_ID_CLUSTER_SHIFT 4
-
-/* fields in VER */
-#define APIC_VER_VERSION 0x000000ff
-#define APIC_VER_MAXLVT 0x00ff0000
-#define MAXLVTSHIFT 16
-#define APIC_VER_EOI_SUPPRESSION 0x01000000
-
-/* fields in LDR */
-#define APIC_LDR_RESERVED 0x00ffffff
-
-/* fields in DFR */
-#define APIC_DFR_RESERVED 0x0fffffff
-#define APIC_DFR_MODEL_MASK 0xf0000000
-#define APIC_DFR_MODEL_FLAT 0xf0000000
-#define APIC_DFR_MODEL_CLUSTER 0x00000000
-
-/* fields in SVR */
-#define APIC_SVR_VECTOR 0x000000ff
-#define APIC_SVR_VEC_PROG 0x000000f0
-#define APIC_SVR_VEC_FIX 0x0000000f
-#define APIC_SVR_ENABLE 0x00000100
-# define APIC_SVR_SWDIS 0x00000000
-# define APIC_SVR_SWEN 0x00000100
-#define APIC_SVR_FOCUS 0x00000200
-# define APIC_SVR_FEN 0x00000000
-# define APIC_SVR_FDIS 0x00000200
-#define APIC_SVR_EOI_SUPPRESSION 0x00001000
-
-/* fields in TPR */
-#define APIC_TPR_PRIO 0x000000ff
-# define APIC_TPR_INT 0x000000f0
-# define APIC_TPR_SUB 0x0000000f
-
-/* fields in ESR */
-#define APIC_ESR_SEND_CS_ERROR 0x00000001
-#define APIC_ESR_RECEIVE_CS_ERROR 0x00000002
-#define APIC_ESR_SEND_ACCEPT 0x00000004
-#define APIC_ESR_RECEIVE_ACCEPT 0x00000008
-#define APIC_ESR_SEND_ILLEGAL_VECTOR 0x00000020
-#define APIC_ESR_RECEIVE_ILLEGAL_VECTOR 0x00000040
-#define APIC_ESR_ILLEGAL_REGISTER 0x00000080
-
-/* fields in ICR_LOW */
-#define APIC_VECTOR_MASK 0x000000ff
-
-#define APIC_DELMODE_MASK 0x00000700
-# define APIC_DELMODE_FIXED 0x00000000
-# define APIC_DELMODE_LOWPRIO 0x00000100
-# define APIC_DELMODE_SMI 0x00000200
-# define APIC_DELMODE_RR 0x00000300
-# define APIC_DELMODE_NMI 0x00000400
-# define APIC_DELMODE_INIT 0x00000500
-# define APIC_DELMODE_STARTUP 0x00000600
-# define APIC_DELMODE_RESV 0x00000700
-
-#define APIC_DESTMODE_MASK 0x00000800
-# define APIC_DESTMODE_PHY 0x00000000
-# define APIC_DESTMODE_LOG 0x00000800
-
-#define APIC_DELSTAT_MASK 0x00001000
-# define APIC_DELSTAT_IDLE 0x00000000
-# define APIC_DELSTAT_PEND 0x00001000
-
-#define APIC_RESV1_MASK 0x00002000
-
-#define APIC_LEVEL_MASK 0x00004000
-# define APIC_LEVEL_DEASSERT 0x00000000
-# define APIC_LEVEL_ASSERT 0x00004000
-
-#define APIC_TRIGMOD_MASK 0x00008000
-# define APIC_TRIGMOD_EDGE 0x00000000
-# define APIC_TRIGMOD_LEVEL 0x00008000
-
-#define APIC_RRSTAT_MASK 0x00030000
-# define APIC_RRSTAT_INVALID 0x00000000
-# define APIC_RRSTAT_INPROG 0x00010000
-# define APIC_RRSTAT_VALID 0x00020000
-# define APIC_RRSTAT_RESV 0x00030000
-
-#define APIC_DEST_MASK 0x000c0000
-# define APIC_DEST_DESTFLD 0x00000000
-# define APIC_DEST_SELF 0x00040000
-# define APIC_DEST_ALLISELF 0x00080000
-# define APIC_DEST_ALLESELF 0x000c0000
-
-#define APIC_RESV2_MASK 0xfff00000
-
-#define APIC_ICRLO_RESV_MASK (APIC_RESV1_MASK | APIC_RESV2_MASK)
-
-/* fields in LVT1/2 */
-#define APIC_LVT_VECTOR 0x000000ff
-#define APIC_LVT_DM 0x00000700
-# define APIC_LVT_DM_FIXED 0x00000000
-# define APIC_LVT_DM_SMI 0x00000200
-# define APIC_LVT_DM_NMI 0x00000400
-# define APIC_LVT_DM_INIT 0x00000500
-# define APIC_LVT_DM_EXTINT 0x00000700
-#define APIC_LVT_DS 0x00001000
-#define APIC_LVT_IIPP 0x00002000
-#define APIC_LVT_IIPP_INTALO 0x00002000
-#define APIC_LVT_IIPP_INTAHI 0x00000000
-#define APIC_LVT_RIRR 0x00004000
-#define APIC_LVT_TM 0x00008000
-#define APIC_LVT_M 0x00010000
-
-
-/* fields in LVT Timer */
-#define APIC_LVTT_VECTOR 0x000000ff
-#define APIC_LVTT_DS 0x00001000
-#define APIC_LVTT_M 0x00010000
-#define APIC_LVTT_TM 0x00020000
-# define APIC_LVTT_TM_ONE_SHOT 0x00000000
-# define APIC_LVTT_TM_PERIODIC 0x00020000
-
-
-/* APIC timer current count */
-#define APIC_TIMER_MAX_COUNT 0xffffffff
-
-/* fields in TDCR */
-#define APIC_TDCR_2 0x00
-#define APIC_TDCR_4 0x01
-#define APIC_TDCR_8 0x02
-#define APIC_TDCR_16 0x03
-#define APIC_TDCR_32 0x08
-#define APIC_TDCR_64 0x09
-#define APIC_TDCR_128 0x0a
-#define APIC_TDCR_1 0x0b
-
-/******************************************************************************
- * I/O APIC defines
- */
-
-/* default physical locations of an IO APIC */
-#define DEFAULT_IO_APIC_BASE 0xfec00000
-
-/* window register offset */
-#define IOAPIC_WINDOW 0x10
-#define IOAPIC_EOIR 0x40
-
-/* indexes into IO APIC */
-#define IOAPIC_ID 0x00
-#define IOAPIC_VER 0x01
-#define IOAPIC_ARB 0x02
-#define IOAPIC_REDTBL 0x10
-#define IOAPIC_REDTBL0 IOAPIC_REDTBL
-#define IOAPIC_REDTBL1 (IOAPIC_REDTBL+0x02)
-#define IOAPIC_REDTBL2 (IOAPIC_REDTBL+0x04)
-#define IOAPIC_REDTBL3 (IOAPIC_REDTBL+0x06)
-#define IOAPIC_REDTBL4 (IOAPIC_REDTBL+0x08)
-#define IOAPIC_REDTBL5 (IOAPIC_REDTBL+0x0a)
-#define IOAPIC_REDTBL6 (IOAPIC_REDTBL+0x0c)
-#define IOAPIC_REDTBL7 (IOAPIC_REDTBL+0x0e)
-#define IOAPIC_REDTBL8 (IOAPIC_REDTBL+0x10)
-#define IOAPIC_REDTBL9 (IOAPIC_REDTBL+0x12)
-#define IOAPIC_REDTBL10 (IOAPIC_REDTBL+0x14)
-#define IOAPIC_REDTBL11 (IOAPIC_REDTBL+0x16)
-#define IOAPIC_REDTBL12 (IOAPIC_REDTBL+0x18)
-#define IOAPIC_REDTBL13 (IOAPIC_REDTBL+0x1a)
-#define IOAPIC_REDTBL14 (IOAPIC_REDTBL+0x1c)
-#define IOAPIC_REDTBL15 (IOAPIC_REDTBL+0x1e)
-#define IOAPIC_REDTBL16 (IOAPIC_REDTBL+0x20)
-#define IOAPIC_REDTBL17 (IOAPIC_REDTBL+0x22)
-#define IOAPIC_REDTBL18 (IOAPIC_REDTBL+0x24)
-#define IOAPIC_REDTBL19 (IOAPIC_REDTBL+0x26)
-#define IOAPIC_REDTBL20 (IOAPIC_REDTBL+0x28)
-#define IOAPIC_REDTBL21 (IOAPIC_REDTBL+0x2a)
-#define IOAPIC_REDTBL22 (IOAPIC_REDTBL+0x2c)
-#define IOAPIC_REDTBL23 (IOAPIC_REDTBL+0x2e)
-
-/* fields in VER */
-#define IOART_VER_VERSION 0x000000ff
-#define IOART_VER_MAXREDIR 0x00ff0000
-#define MAXREDIRSHIFT 16
-
-/*
- * fields in the IO APIC's redirection table entries
- */
-#define IOART_DEST APIC_ID_MASK /* broadcast addr: all APICs */
-
-#define IOART_RESV 0x00fe0000 /* reserved */
-
-#define IOART_INTMASK 0x00010000 /* R/W: INTerrupt mask */
-# define IOART_INTMCLR 0x00000000 /* clear, allow INTs */
-# define IOART_INTMSET 0x00010000 /* set, inhibit INTs */
-
-#define IOART_TRGRMOD 0x00008000 /* R/W: trigger mode */
-# define IOART_TRGREDG 0x00000000 /* edge */
-# define IOART_TRGRLVL 0x00008000 /* level */
-
-#define IOART_REM_IRR 0x00004000 /* RO: remote IRR */
-
-#define IOART_INTPOL 0x00002000 /* R/W: INT input pin polarity */
-# define IOART_INTAHI 0x00000000 /* active high */
-# define IOART_INTALO 0x00002000 /* active low */
-
-#define IOART_DELIVS 0x00001000 /* RO: delivery status */
-
-#define IOART_DESTMOD 0x00000800 /* R/W: destination mode */
-# define IOART_DESTPHY 0x00000000 /* physical */
-# define IOART_DESTLOG 0x00000800 /* logical */
-
-#define IOART_DELMOD 0x00000700 /* R/W: delivery mode */
-# define IOART_DELFIXED 0x00000000 /* fixed */
-# define IOART_DELLOPRI 0x00000100 /* lowest priority */
-# define IOART_DELSMI 0x00000200 /* System Management INT */
-# define IOART_DELRSV1 0x00000300 /* reserved */
-# define IOART_DELNMI 0x00000400 /* NMI signal */
-# define IOART_DELINIT 0x00000500 /* INIT signal */
-# define IOART_DELRSV2 0x00000600 /* reserved */
-# define IOART_DELEXINT 0x00000700 /* External INTerrupt */
-
-#define IOART_INTVEC 0x000000ff /* R/W: INTerrupt vector field */
-
-#endif /* _MACHINE_APICREG_H_ */
diff --git a/sys/i386/include/mca.h b/sys/i386/include/mca.h
deleted file mode 100644
index dd6e69c..0000000
--- a/sys/i386/include/mca.h
+++ /dev/null
@@ -1,56 +0,0 @@
-/*-
- * Copyright (c) 2009 Advanced Computing Technologies LLC
- * Written by: John H. Baldwin <jhb@FreeBSD.org>
- * 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 THE AUTHOR AND CONTRIBUTORS ``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 THE AUTHOR 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 __MACHINE_MCA_H__
-#define __MACHINE_MCA_H__
-
-struct mca_record {
- uint64_t mr_status;
- uint64_t mr_addr;
- uint64_t mr_misc;
- uint64_t mr_tsc;
- int mr_apic_id;
- int mr_bank;
- uint64_t mr_mcg_cap;
- uint64_t mr_mcg_status;
- int mr_cpu_id;
- int mr_cpu_vendor_id;
- int mr_cpu;
-};
-
-#ifdef _KERNEL
-
-void cmc_intr(void);
-void mca_init(void);
-int mca_intr(void);
-void mca_resume(void);
-
-#endif
-
-#endif /* !__MACHINE_MCA_H__ */
diff --git a/sys/i386/xen/mp_machdep.c b/sys/i386/xen/mp_machdep.c
index 43a82ab..60165cb 100644
--- a/sys/i386/xen/mp_machdep.c
+++ b/sys/i386/xen/mp_machdep.c
@@ -74,7 +74,7 @@ __FBSDID("$FreeBSD$");
#include <vm/vm_extern.h>
#include <vm/vm_page.h>
-#include <machine/apicreg.h>
+#include <x86/apicreg.h>
#include <machine/md_var.h>
#include <machine/mp_watchdog.h>
#include <machine/pcb.h>
diff --git a/sys/i386/xen/mptable.c b/sys/i386/xen/mptable.c
index c6c7d53..fe01cd5 100644
--- a/sys/i386/xen/mptable.c
+++ b/sys/i386/xen/mptable.c
@@ -37,7 +37,7 @@ __FBSDID("$FreeBSD$");
#include <vm/vm_param.h>
#include <vm/pmap.h>
-#include <machine/apicreg.h>
+#include <x86/apicreg.h>
#include <machine/frame.h>
#include <machine/intr_machdep.h>
#include <machine/apicvar.h>
diff --git a/sys/kern/init_main.c b/sys/kern/init_main.c
index d697689..b86ea91 100644
--- a/sys/kern/init_main.c
+++ b/sys/kern/init_main.c
@@ -180,6 +180,9 @@ mi_startup(void)
int verbose;
#endif
+ if (boothowto & RB_VERBOSE)
+ bootverbose++;
+
if (sysinit == NULL) {
sysinit = SET_BEGIN(sysinit_set);
sysinit_end = SET_LIMIT(sysinit_set);
@@ -327,15 +330,6 @@ SYSINIT(diagwarn2, SI_SUB_RUN_SCHEDULER, SI_ORDER_THIRD + 2,
print_caddr_t, diag_warn);
#endif
-static void
-set_boot_verbose(void *data __unused)
-{
-
- if (boothowto & RB_VERBOSE)
- bootverbose++;
-}
-SYSINIT(boot_verbose, SI_SUB_TUNABLES, SI_ORDER_ANY, set_boot_verbose, NULL);
-
static int
null_fetch_syscall_args(struct thread *td __unused,
struct syscall_args *sa __unused)
diff --git a/sys/kern/kern_cpuset.c b/sys/kern/kern_cpuset.c
index 23aa9df..c5eb659 100644
--- a/sys/kern/kern_cpuset.c
+++ b/sys/kern/kern_cpuset.c
@@ -107,6 +107,10 @@ static struct setlist cpuset_ids;
static struct unrhdr *cpuset_unr;
static struct cpuset *cpuset_zero;
+/* Return the size of cpuset_t at the kernel level */
+SYSCTL_INT(_kern_sched, OID_AUTO, cpusetsize, CTLFLAG_RD,
+ 0, sizeof(cpuset_t), "sizeof(cpuset_t)");
+
cpuset_t *cpuset_root;
/*
diff --git a/sys/kern/kern_timeout.c b/sys/kern/kern_timeout.c
index 98f55da..f60af40 100644
--- a/sys/kern/kern_timeout.c
+++ b/sys/kern/kern_timeout.c
@@ -295,8 +295,7 @@ callout_tickstofirst(int limit)
sc = &cc->cc_callwheel[ (curticks+skip) & callwheelmask ];
/* search scanning ticks */
TAILQ_FOREACH( c, sc, c_links.tqe ){
- if (c && (c->c_time <= curticks + ncallout)
- && (c->c_time > 0))
+ if (c->c_time - curticks <= ncallout)
goto out;
}
skip++;
diff --git a/sys/kern/sched_ule.c b/sys/kern/sched_ule.c
index 4765c1c..0005968 100644
--- a/sys/kern/sched_ule.c
+++ b/sys/kern/sched_ule.c
@@ -2712,6 +2712,7 @@ sysctl_kern_sched_topology_spec(SYSCTL_HANDLER_ARGS)
sbuf_delete(topo);
return (err);
}
+
#endif
SYSCTL_NODE(_kern, OID_AUTO, sched, CTLFLAG_RW, 0, "Scheduler");
@@ -2748,6 +2749,7 @@ SYSCTL_INT(_kern_sched, OID_AUTO, steal_thresh, CTLFLAG_RW, &steal_thresh, 0,
SYSCTL_PROC(_kern_sched, OID_AUTO, topology_spec, CTLTYPE_STRING |
CTLFLAG_RD, NULL, 0, sysctl_kern_sched_topology_spec, "A",
"XML dump of detected CPU topology");
+
#endif
/* ps compat. All cpu percentages from ULE are weighted. */
diff --git a/sys/kern/subr_acl_nfs4.c b/sys/kern/subr_acl_nfs4.c
index cf664bf..767f04b 100644
--- a/sys/kern/subr_acl_nfs4.c
+++ b/sys/kern/subr_acl_nfs4.c
@@ -162,7 +162,7 @@ vaccess_acl_nfs4(enum vtype type, uid_t file_uid, gid_t file_gid,
accmode_t priv_granted = 0;
int denied, explicitly_denied, access_mask, is_directory,
must_be_owner = 0;
- mode_t file_mode;
+ mode_t file_mode = 0;
KASSERT((accmode & ~(VEXEC | VWRITE | VREAD | VADMIN | VAPPEND |
VEXPLICIT_DENY | VREAD_NAMED_ATTRS | VWRITE_NAMED_ATTRS |
diff --git a/sys/kern/vfs_cache.c b/sys/kern/vfs_cache.c
index 5a48a67..0efdbc1 100644
--- a/sys/kern/vfs_cache.c
+++ b/sys/kern/vfs_cache.c
@@ -129,8 +129,6 @@ static u_long nchash; /* size of hash table */
SYSCTL_ULONG(_debug, OID_AUTO, nchash, CTLFLAG_RD, &nchash, 0,
"Size of namecache hash table");
static u_long ncnegfactor = 16; /* ratio of negative entries */
-/* _debug sysctl left for backward compatibility */
-SYSCTL_ULONG(_debug, OID_AUTO, ncnegfactor, CTLFLAG_RW, &ncnegfactor, 0, "");
SYSCTL_ULONG(_vfs, OID_AUTO, ncnegfactor, CTLFLAG_RW, &ncnegfactor, 0,
"Ratio of negative namecache entries");
static u_long numneg; /* number of negative entries allocated */
diff --git a/sys/modules/Makefile b/sys/modules/Makefile
index 452cc8f..a5ce22c 100644
--- a/sys/modules/Makefile
+++ b/sys/modules/Makefile
@@ -631,6 +631,7 @@ _xe= xe
.endif
.if ${MACHINE_CPUARCH} == "powerpc"
+_agp= agp
_an= an
_bm= bm
_cpufreq= cpufreq
diff --git a/sys/modules/agp/Makefile b/sys/modules/agp/Makefile
index f77e38c..9e28657 100644
--- a/sys/modules/agp/Makefile
+++ b/sys/modules/agp/Makefile
@@ -11,9 +11,12 @@ SRCS+= agp_i810.c agp_intel.c agp_via.c agp_sis.c agp_ali.c agp_amd.c \
.if ${MACHINE} == "i386"
SRCS+= agp_amd64.c
.endif
-.if ${MACHINE_CPUARCH} == "amd64"
+.if ${MACHINE_CPUARCH} == "amd64"
SRCS+= agp_amd64.c agp_i810.c agp_via.c
.endif
+.if ${MACHINE_CPUARCH} == "powerpc"
+SRCS+= agp_apple.c
+.endif
SRCS+= device_if.h bus_if.h agp_if.h pci_if.h
SRCS+= opt_agp.h opt_bus.h
MFILES= kern/device_if.m kern/bus_if.m dev/agp/agp_if.m dev/pci/pci_if.m
diff --git a/sys/net/bpf.h b/sys/net/bpf.h
index b1aad51..d4c369d 100644
--- a/sys/net/bpf.h
+++ b/sys/net/bpf.h
@@ -844,6 +844,143 @@ struct bpf_zbuf_header {
*/
#define DLT_IEEE802_15_4_NONASK_PHY 215
+/*
+ * David Gibson <david@gibson.dropbear.id.au> requested this for
+ * captures from the Linux kernel /dev/input/eventN devices. This
+ * is used to communicate keystrokes and mouse movements from the
+ * Linux kernel to display systems, such as Xorg.
+ */
+#define DLT_LINUX_EVDEV 216
+
+/*
+ * GSM Um and Abis interfaces, preceded by a "gsmtap" header.
+ *
+ * Requested by Harald Welte <laforge@gnumonks.org>.
+ */
+#define DLT_GSMTAP_UM 217
+#define DLT_GSMTAP_ABIS 218
+
+/*
+ * MPLS, with an MPLS label as the link-layer header.
+ * Requested by Michele Marchetto <michele@openbsd.org> on behalf
+ * of OpenBSD.
+ */
+#define DLT_MPLS 219
+
+/*
+ * USB packets, beginning with a Linux USB header, with the USB header
+ * padded to 64 bytes; required for memory-mapped access.
+ */
+#define DLT_USB_LINUX_MMAPPED 220
+
+/*
+ * DECT packets, with a pseudo-header; requested by
+ * Matthias Wenzel <tcpdump@mazzoo.de>.
+ */
+#define DLT_DECT 221
+/*
+ * From: "Lidwa, Eric (GSFC-582.0)[SGT INC]" <eric.lidwa-1@nasa.gov>
+ * Date: Mon, 11 May 2009 11:18:30 -0500
+ *
+ * DLT_AOS. We need it for AOS Space Data Link Protocol.
+ * I have already written dissectors for but need an OK from
+ * legal before I can submit a patch.
+ *
+ */
+#define DLT_AOS 222
+
+/*
+ * Wireless HART (Highway Addressable Remote Transducer)
+ * From the HART Communication Foundation
+ * IES/PAS 62591
+ *
+ * Requested by Sam Roberts <vieuxtech@gmail.com>.
+ */
+#define DLT_WIHART 223
+
+/*
+ * Fibre Channel FC-2 frames, beginning with a Frame_Header.
+ * Requested by Kahou Lei <kahou82@gmail.com>.
+ */
+#define DLT_FC_2 224
+
+/*
+ * Fibre Channel FC-2 frames, beginning with an encoding of the
+ * SOF, and ending with an encoding of the EOF.
+ *
+ * The encodings represent the frame delimiters as 4-byte sequences
+ * representing the corresponding ordered sets, with K28.5
+ * represented as 0xBC, and the D symbols as the corresponding
+ * byte values; for example, SOFi2, which is K28.5 - D21.5 - D1.2 - D21.2,
+ * is represented as 0xBC 0xB5 0x55 0x55.
+ *
+ * Requested by Kahou Lei <kahou82@gmail.com>.
+ */
+#define DLT_FC_2_WITH_FRAME_DELIMS 225
+/*
+ * Solaris ipnet pseudo-header; requested by Darren Reed <Darren.Reed@Sun.COM>.
+ *
+ * The pseudo-header starts with a one-byte version number; for version 2,
+ * the pseudo-header is:
+ *
+ * struct dl_ipnetinfo {
+ * u_int8_t dli_version;
+ * u_int8_t dli_family;
+ * u_int16_t dli_htype;
+ * u_int32_t dli_pktlen;
+ * u_int32_t dli_ifindex;
+ * u_int32_t dli_grifindex;
+ * u_int32_t dli_zsrc;
+ * u_int32_t dli_zdst;
+ * };
+ *
+ * dli_version is 2 for the current version of the pseudo-header.
+ *
+ * dli_family is a Solaris address family value, so it's 2 for IPv4
+ * and 26 for IPv6.
+ *
+ * dli_htype is a "hook type" - 0 for incoming packets, 1 for outgoing
+ * packets, and 2 for packets arriving from another zone on the same
+ * machine.
+ *
+ * dli_pktlen is the length of the packet data following the pseudo-header
+ * (so the captured length minus dli_pktlen is the length of the
+ * pseudo-header, assuming the entire pseudo-header was captured).
+ *
+ * dli_ifindex is the interface index of the interface on which the
+ * packet arrived.
+ *
+ * dli_grifindex is the group interface index number (for IPMP interfaces).
+ *
+ * dli_zsrc is the zone identifier for the source of the packet.
+ *
+ * dli_zdst is the zone identifier for the destination of the packet.
+ *
+ * A zone number of 0 is the global zone; a zone number of 0xffffffff
+ * means that the packet arrived from another host on the network, not
+ * from another zone on the same machine.
+ *
+ * An IPv4 or IPv6 datagram follows the pseudo-header; dli_family indicates
+ * which of those it is.
+ */
+#define DLT_IPNET 226
+
+/*
+ * CAN (Controller Area Network) frames, with a pseudo-header as supplied
+ * by Linux SocketCAN. See Documentation/networking/can.txt in the Linux
+ * source.
+ *
+ * Requested by Felix Obenhuber <felix@obenhuber.de>.
+ */
+#define DLT_CAN_SOCKETCAN 227
+
+/*
+ * Raw IPv4/IPv6; different from DLT_RAW in that the DLT_ value specifies
+ * whether it's v4 or v6. Requested by Darren Reed <Darren.Reed@Sun.COM>.
+ */
+#define DLT_IPV4 228
+#define DLT_IPV6 229
+
/*
* DLT and savefile link type values are split into a class and
* a member of that class. A class value of 0 indicates a regular
diff --git a/sys/netinet/if_ether.c b/sys/netinet/if_ether.c
index a6ea36e..f18236f 100644
--- a/sys/netinet/if_ether.c
+++ b/sys/netinet/if_ether.c
@@ -291,8 +291,6 @@ arpresolve(struct ifnet *ifp, struct rtentry *rt0, struct mbuf *m,
return (0);
}
}
- /* XXXXX
- */
retry:
IF_AFDATA_RLOCK(ifp);
la = lla_lookup(LLTABLE(ifp), flags, dst);
@@ -381,7 +379,7 @@ retry:
int canceled;
LLE_ADDREF(la);
- la->la_expire = time_second + V_arpt_down;
+ la->la_expire = time_second;
canceled = callout_reset(&la->la_timer, hz * V_arpt_down,
arptimer, la);
if (canceled)
diff --git a/sys/netipsec/ipsec.c b/sys/netipsec/ipsec.c
index 1f48dd6..712040f 100644
--- a/sys/netipsec/ipsec.c
+++ b/sys/netipsec/ipsec.c
@@ -126,6 +126,11 @@ VNET_DEFINE(int, ip4_esp_randpad) = -1;
*/
VNET_DEFINE(int, crypto_support) = CRYPTOCAP_F_HARDWARE | CRYPTOCAP_F_SOFTWARE;
+FEATURE(ipsec, "Internet Protocol Security (IPsec)");
+#ifdef IPSEC_NAT_T
+FEATURE(ipsec_natt, "UDP Encapsulation of IPsec ESP Packets ('NAT-T')");
+#endif
+
SYSCTL_DECL(_net_inet_ipsec);
/* net.inet.ipsec */
diff --git a/sys/nfsclient/nfs_vfsops.c b/sys/nfsclient/nfs_vfsops.c
index fd50ca8..52f5bfc 100644
--- a/sys/nfsclient/nfs_vfsops.c
+++ b/sys/nfsclient/nfs_vfsops.c
@@ -779,10 +779,10 @@ static const char *nfs_opts[] = { "from", "nfs_args",
"noatime", "noexec", "suiddir", "nosuid", "nosymfollow", "union",
"noclusterr", "noclusterw", "multilabel", "acls", "force", "update",
"async", "dumbtimer", "noconn", "nolockd", "intr", "rdirplus", "resvport",
- "readdirsize", "soft", "hard", "mntudp", "tcp", "udp", "wsize", "rsize",
- "retrans", "acregmin", "acregmax", "acdirmin", "acdirmax",
- "deadthresh", "hostname", "timeout", "addr", "fh", "nfsv3", "sec",
- "maxgroups", "principal", "negnametimeo",
+ "readahead", "readdirsize", "soft", "hard", "mntudp", "tcp", "udp",
+ "wsize", "rsize", "retrans", "acregmin", "acregmax", "acdirmin",
+ "acdirmax", "deadthresh", "hostname", "timeout", "addr", "fh", "nfsv3",
+ "sec", "maxgroups", "principal", "negnametimeo",
NULL };
/*
diff --git a/sys/pc98/include/apicreg.h b/sys/pc98/include/apicreg.h
deleted file mode 100644
index a9766d5..0000000
--- a/sys/pc98/include/apicreg.h
+++ /dev/null
@@ -1,6 +0,0 @@
-/*-
- * This file is in the public domain.
- */
-/* $FreeBSD$ */
-
-#include <i386/apicreg.h>
diff --git a/sys/pc98/include/bus.h b/sys/pc98/include/bus.h
index 07b7ea3..b12845c 100644
--- a/sys/pc98/include/bus.h
+++ b/sys/pc98/include/bus.h
@@ -158,8 +158,8 @@ struct bus_space_access_methods {
* Access methods for bus resources and address space.
*/
struct bus_space_tag {
-#define BUS_SPACE_IO 0
-#define BUS_SPACE_MEM 1
+#define BUS_SPACE_TAG_IO 0
+#define BUS_SPACE_TAG_MEM 1
u_int bs_tag; /* bus space flags */
struct bus_space_access_methods bs_da; /* direct access */
diff --git a/sys/pc98/include/mca.h b/sys/pc98/include/mca.h
deleted file mode 100644
index a047f87..0000000
--- a/sys/pc98/include/mca.h
+++ /dev/null
@@ -1,6 +0,0 @@
-/*-
- * This file is in the public domain.
- */
-/* $FreeBSD$ */
-
-#include <i386/mca.h>
diff --git a/sys/pc98/pc98/busiosubr.c b/sys/pc98/pc98/busiosubr.c
index dffe5ff..926c1ce 100644
--- a/sys/pc98/pc98/busiosubr.c
+++ b/sys/pc98/pc98/busiosubr.c
@@ -63,7 +63,7 @@ _BUS_SPACE_CALL_FUNCS_PROTO(SBUS_RA_mem,u_int16_t,2)
_BUS_SPACE_CALL_FUNCS_PROTO(SBUS_RA_mem,u_int32_t,4)
struct bus_space_tag SBUS_io_space_tag = {
- BUS_SPACE_IO,
+ BUS_SPACE_TAG_IO,
/* direct bus access methods */
{
@@ -81,7 +81,7 @@ struct bus_space_tag SBUS_io_space_tag = {
};
struct bus_space_tag SBUS_mem_space_tag = {
- BUS_SPACE_MEM,
+ BUS_SPACE_TAG_MEM,
/* direct bus access methods */
{
@@ -109,7 +109,7 @@ _BUS_SPACE_CALL_FUNCS_PROTO(NEPC_RA_io,u_int16_t,2)
_BUS_SPACE_CALL_FUNCS_PROTO(NEPC_RA_io,u_int32_t,4)
struct bus_space_tag NEPC_io_space_tag = {
- BUS_SPACE_IO,
+ BUS_SPACE_TAG_IO,
/* direct bus access methods */
{
@@ -127,7 +127,7 @@ struct bus_space_tag NEPC_io_space_tag = {
};
struct bus_space_tag NEPC_mem_space_tag = {
- BUS_SPACE_MEM,
+ BUS_SPACE_TAG_MEM,
/* direct bus access methods */
{
@@ -256,7 +256,7 @@ i386_memio_subregion(bus_space_tag_t t, bus_space_handle_t pbsh,
pbase = pbsh->bsh_base + offset;
switch (t->bs_tag) {
- case BUS_SPACE_IO:
+ case BUS_SPACE_TAG_IO:
if (pbsh->bsh_iatsz > 0) {
if (offset >= pbsh->bsh_iatsz ||
offset + size > pbsh->bsh_iatsz)
@@ -265,7 +265,7 @@ i386_memio_subregion(bus_space_tag_t t, bus_space_handle_t pbsh,
}
break;
- case BUS_SPACE_MEM:
+ case BUS_SPACE_TAG_MEM:
if (pbsh->bsh_iatsz > 0)
return EINVAL;
if (offset > pbsh->bsh_sz || offset + size > pbsh->bsh_sz)
@@ -282,7 +282,7 @@ i386_memio_subregion(bus_space_tag_t t, bus_space_handle_t pbsh,
return error;
switch (t->bs_tag) {
- case BUS_SPACE_IO:
+ case BUS_SPACE_TAG_IO:
if (pbsh->bsh_iatsz > 0) {
for (i = 0; i < size; i ++)
bsh->bsh_iat[i] = pbsh->bsh_iat[i + offset];
@@ -295,7 +295,7 @@ i386_memio_subregion(bus_space_tag_t t, bus_space_handle_t pbsh,
}
break;
- case BUS_SPACE_MEM:
+ case BUS_SPACE_TAG_MEM:
break;
}
diff --git a/sys/pc98/pc98/machdep.c b/sys/pc98/pc98/machdep.c
index 32328c5..e01ef68 100644
--- a/sys/pc98/pc98/machdep.c
+++ b/sys/pc98/pc98/machdep.c
@@ -112,7 +112,7 @@ __FBSDID("$FreeBSD$");
#include <machine/cpu.h>
#include <machine/cputypes.h>
#include <machine/intr_machdep.h>
-#include <machine/mca.h>
+#include <x86/mca.h>
#include <machine/md_var.h>
#include <machine/pc/bios.h>
#include <machine/pcb.h>
diff --git a/sys/powerpc/aim/copyinout.c b/sys/powerpc/aim/copyinout.c
index ab2d1f32..15623ed 100644
--- a/sys/powerpc/aim/copyinout.c
+++ b/sys/powerpc/aim/copyinout.c
@@ -81,9 +81,7 @@ static __inline void
set_user_sr(pmap_t pm, const void *addr)
{
struct slb *slb;
- register_t esid, vsid, slb1, slb2;
-
- esid = USER_ADDR >> ADDR_SR_SHFT;
+ register_t slbv;
/* Try lockless look-up first */
slb = user_va_to_slb_entry(pm, (vm_offset_t)addr);
@@ -91,20 +89,24 @@ set_user_sr(pmap_t pm, const void *addr)
if (slb == NULL) {
/* If it isn't there, we need to pre-fault the VSID */
PMAP_LOCK(pm);
- vsid = va_to_vsid(pm, (vm_offset_t)addr);
+ slbv = va_to_vsid(pm, (vm_offset_t)addr) << SLBV_VSID_SHIFT;
PMAP_UNLOCK(pm);
} else {
- vsid = slb->slbv >> SLBV_VSID_SHIFT;
+ slbv = slb->slbv;
}
- slb1 = vsid << SLBV_VSID_SHIFT;
- slb2 = (esid << SLBE_ESID_SHIFT) | SLBE_VALID | USER_SR;
+ /* Mark segment no-execute */
+ slbv |= SLBV_N;
+
+ /* If we have already set this VSID, we can just return */
+ if (curthread->td_pcb->pcb_cpu.aim.usr_vsid == slbv)
+ return;
+ __asm __volatile ("isync; slbie %0; slbmte %1, %2; isync" ::
+ "r"(USER_ADDR), "r"(slbv), "r"(USER_SLB_SLBE));
curthread->td_pcb->pcb_cpu.aim.usr_segm =
(uintptr_t)addr >> ADDR_SR_SHFT;
- __asm __volatile ("slbie %0; slbmte %1, %2" :: "r"(esid << 28),
- "r"(slb1), "r"(slb2));
- isync();
+ curthread->td_pcb->pcb_cpu.aim.usr_vsid = slbv;
}
#else
static __inline void
@@ -114,9 +116,16 @@ set_user_sr(pmap_t pm, const void *addr)
vsid = va_to_vsid(pm, (vm_offset_t)addr);
- isync();
- __asm __volatile ("mtsr %0,%1" :: "n"(USER_SR), "r"(vsid));
- isync();
+ /* If we have already set this VSID, we can just return */
+ if (curthread->td_pcb->pcb_cpu.aim.usr_vsid == vsid)
+ return;
+
+ /* Mark segment no-execute */
+ vsid |= SR_N;
+
+ __asm __volatile("isync");
+ curthread->td_pcb->pcb_cpu.aim.usr_vsid = vsid;
+ __asm __volatile("mtsr %0,%1; isync" :: "n"(USER_SR), "r"(vsid));
}
#endif
diff --git a/sys/powerpc/aim/mmu_oea.c b/sys/powerpc/aim/mmu_oea.c
index 27d4ef3..5ba029c 100644
--- a/sys/powerpc/aim/mmu_oea.c
+++ b/sys/powerpc/aim/mmu_oea.c
@@ -304,6 +304,7 @@ vm_paddr_t moea_extract(mmu_t, pmap_t, vm_offset_t);
vm_page_t moea_extract_and_hold(mmu_t, pmap_t, vm_offset_t, vm_prot_t);
void moea_init(mmu_t);
boolean_t moea_is_modified(mmu_t, vm_page_t);
+boolean_t moea_is_prefaultable(mmu_t, pmap_t, vm_offset_t);
boolean_t moea_is_referenced(mmu_t, vm_page_t);
boolean_t moea_ts_referenced(mmu_t, vm_page_t);
vm_offset_t moea_map(mmu_t, vm_offset_t *, vm_offset_t, vm_offset_t, int);
@@ -347,6 +348,7 @@ static mmu_method_t moea_methods[] = {
MMUMETHOD(mmu_extract_and_hold, moea_extract_and_hold),
MMUMETHOD(mmu_init, moea_init),
MMUMETHOD(mmu_is_modified, moea_is_modified),
+ MMUMETHOD(mmu_is_prefaultable, moea_is_prefaultable),
MMUMETHOD(mmu_is_referenced, moea_is_referenced),
MMUMETHOD(mmu_ts_referenced, moea_ts_referenced),
MMUMETHOD(mmu_map, moea_map),
@@ -1324,6 +1326,19 @@ moea_is_modified(mmu_t mmu, vm_page_t m)
return (moea_query_bit(m, PTE_CHG));
}
+boolean_t
+moea_is_prefaultable(mmu_t mmu, pmap_t pmap, vm_offset_t va)
+{
+ struct pvo_entry *pvo;
+ boolean_t rv;
+
+ PMAP_LOCK(pmap);
+ pvo = moea_pvo_find_va(pmap, va & ~ADDR_POFF, NULL);
+ rv = pvo == NULL || (pvo->pvo_pte.pte.pte_hi & PTE_VALID) == 0;
+ PMAP_UNLOCK(pmap);
+ return (rv);
+}
+
void
moea_clear_reference(mmu_t mmu, vm_page_t m)
{
@@ -2430,7 +2445,7 @@ moea_bat_mapped(int idx, vm_offset_t pa, vm_size_t size)
/*
* Return immediately if not a valid mapping
*/
- if (!battable[idx].batu & BAT_Vs)
+ if (!(battable[idx].batu & BAT_Vs))
return (EINVAL);
/*
diff --git a/sys/powerpc/aim/mmu_oea64.c b/sys/powerpc/aim/mmu_oea64.c
index 5e74a13..cfb822e 100644
--- a/sys/powerpc/aim/mmu_oea64.c
+++ b/sys/powerpc/aim/mmu_oea64.c
@@ -400,6 +400,7 @@ vm_paddr_t moea64_extract(mmu_t, pmap_t, vm_offset_t);
vm_page_t moea64_extract_and_hold(mmu_t, pmap_t, vm_offset_t, vm_prot_t);
void moea64_init(mmu_t);
boolean_t moea64_is_modified(mmu_t, vm_page_t);
+boolean_t moea64_is_prefaultable(mmu_t, pmap_t, vm_offset_t);
boolean_t moea64_is_referenced(mmu_t, vm_page_t);
boolean_t moea64_ts_referenced(mmu_t, vm_page_t);
vm_offset_t moea64_map(mmu_t, vm_offset_t *, vm_offset_t, vm_offset_t, int);
@@ -441,6 +442,7 @@ static mmu_method_t moea64_methods[] = {
MMUMETHOD(mmu_extract_and_hold, moea64_extract_and_hold),
MMUMETHOD(mmu_init, moea64_init),
MMUMETHOD(mmu_is_modified, moea64_is_modified),
+ MMUMETHOD(mmu_is_prefaultable, moea64_is_prefaultable),
MMUMETHOD(mmu_is_referenced, moea64_is_referenced),
MMUMETHOD(mmu_ts_referenced, moea64_ts_referenced),
MMUMETHOD(mmu_map, moea64_map),
@@ -1786,6 +1788,19 @@ moea64_is_modified(mmu_t mmu, vm_page_t m)
return (moea64_query_bit(m, LPTE_CHG));
}
+boolean_t
+moea64_is_prefaultable(mmu_t mmu, pmap_t pmap, vm_offset_t va)
+{
+ struct pvo_entry *pvo;
+ boolean_t rv;
+
+ PMAP_LOCK(pmap);
+ pvo = moea64_pvo_find_va(pmap, va & ~ADDR_POFF);
+ rv = pvo == NULL || (pvo->pvo_pte.lpte.pte_hi & LPTE_VALID) == 0;
+ PMAP_UNLOCK(pmap);
+ return (rv);
+}
+
void
moea64_clear_reference(mmu_t mmu, vm_page_t m)
{
diff --git a/sys/powerpc/aim/slb.c b/sys/powerpc/aim/slb.c
index e7bdaf8..9d8828a 100644
--- a/sys/powerpc/aim/slb.c
+++ b/sys/powerpc/aim/slb.c
@@ -200,7 +200,7 @@ kernel_va_to_slbv(vm_offset_t va)
esid = (uintptr_t)va >> ADDR_SR_SHFT;
/* Set kernel VSID to deterministic value */
- slbv = va_to_vsid(kernel_pmap, va) << SLBV_VSID_SHIFT;
+ slbv = (KERNEL_VSID((uintptr_t)va >> ADDR_SR_SHFT)) << SLBV_VSID_SHIFT;
/* Figure out if this is a large-page mapping */
if (hw_direct_map && va < VM_MIN_KERNEL_ADDRESS) {
@@ -421,19 +421,19 @@ slb_insert_kernel(uint64_t slbe, uint64_t slbv)
slbcache = PCPU_GET(slb);
- /* Check for an unused slot, abusing the USER_SR slot as a full flag */
- if (slbcache[USER_SR].slbe == 0) {
- for (i = 0; i < USER_SR; i++) {
+ /* Check for an unused slot, abusing the user slot as a full flag */
+ if (slbcache[USER_SLB_SLOT].slbe == 0) {
+ for (i = 0; i < USER_SLB_SLOT; i++) {
if (!(slbcache[i].slbe & SLBE_VALID))
goto fillkernslb;
}
- if (i == USER_SR)
- slbcache[USER_SR].slbe = 1;
+ if (i == USER_SLB_SLOT)
+ slbcache[USER_SLB_SLOT].slbe = 1;
}
for (i = mftb() % 64, j = 0; j < 64; j++, i = (i+1) % 64) {
- if (i == USER_SR)
+ if (i == USER_SLB_SLOT)
continue;
if (SLB_SPILLABLE(slbcache[i].slbe))
diff --git a/sys/powerpc/aim/swtch32.S b/sys/powerpc/aim/swtch32.S
index f5dba2a..3b608f8 100644
--- a/sys/powerpc/aim/swtch32.S
+++ b/sys/powerpc/aim/swtch32.S
@@ -89,7 +89,6 @@ ENTRY(cpu_switch)
mflr %r16 /* Save the link register */
stw %r16,PCB_LR(%r6)
mfsr %r16,USER_SR /* Save USER_SR for copyin/out */
- isync
stw %r16,PCB_AIM_USR_VSID(%r6)
stw %r1,PCB_SP(%r6) /* Save the stack pointer */
stw %r2,PCB_TOC(%r6) /* Save the TOC pointer */
@@ -162,6 +161,7 @@ blocked_loop:
lwz %r5,PCB_LR(%r3) /* Load the link register */
mtlr %r5
lwz %r5,PCB_AIM_USR_VSID(%r3) /* Load the USER_SR segment reg */
+ isync
mtsr USER_SR,%r5
isync
lwz %r1,PCB_SP(%r3) /* Load the stack pointer */
diff --git a/sys/powerpc/aim/swtch64.S b/sys/powerpc/aim/swtch64.S
index 6ba9843..f1af24e 100644
--- a/sys/powerpc/aim/swtch64.S
+++ b/sys/powerpc/aim/swtch64.S
@@ -110,13 +110,9 @@ ENTRY(cpu_switch)
std %r1,PCB_SP(%r6) /* Save the stack pointer */
std %r2,PCB_TOC(%r6) /* Save the TOC pointer */
- li %r14,0 /* Save USER_SR for copyin/out */
- li %r15,0
- li %r16,USER_SR
- slbmfee %r14, %r16
+ li %r15,0 /* Save user segment for copyin/out */
+ li %r16,USER_SLB_SLOT
slbmfev %r15, %r16
- isync
- std %r14,PCB_AIM_USR_ESID(%r6)
std %r15,PCB_AIM_USR_VSID(%r6)
mr %r14,%r3 /* Copy the old thread ptr... */
@@ -221,17 +217,21 @@ blocked_loop:
ld %r1,PCB_SP(%r3) /* Load the stack pointer */
ld %r2,PCB_TOC(%r3) /* Load the TOC pointer */
- lis %r5,USER_ADDR@highesta /* Load the USER_SR segment reg */
+ lis %r5,USER_ADDR@highesta /* Load the copyin/out segment reg */
ori %r5,%r5,USER_ADDR@highera
sldi %r5,%r5,32
oris %r5,%r5,USER_ADDR@ha
+ isync
slbie %r5
+ lis %r6,USER_SLB_SLBE@highesta
+ ori %r6,%r6,USER_SLB_SLBE@highera
+ sldi %r6,%r6,32
+ oris %r6,%r6,USER_SLB_SLBE@ha
+ ori %r6,%r6,USER_SLB_SLBE@l
ld %r5,PCB_AIM_USR_VSID(%r3)
- ld %r6,PCB_AIM_USR_ESID(%r3)
- ori %r6,%r6,USER_SR
slbmte %r5,%r6
-
isync
+
/*
* Perform a dummy stdcx. to clear any reservations we may have
* inherited from the previous thread. It doesn't matter if the
diff --git a/sys/powerpc/aim/trap.c b/sys/powerpc/aim/trap.c
index db48e7b..22f55a7 100644
--- a/sys/powerpc/aim/trap.c
+++ b/sys/powerpc/aim/trap.c
@@ -249,8 +249,16 @@ trap(struct trapframe *frame)
return;
break;
#ifdef __powerpc64__
- case EXC_ISE:
case EXC_DSE:
+ if ((frame->cpu.aim.dar & SEGMENT_MASK) == USER_ADDR) {
+ __asm __volatile ("slbmte %0, %1" ::
+ "r"(td->td_pcb->pcb_cpu.aim.usr_vsid),
+ "r"(USER_SLB_SLBE));
+ return;
+ }
+
+ /* FALLTHROUGH */
+ case EXC_ISE:
if (handle_slb_spill(kernel_pmap,
(type == EXC_ISE) ? frame->srr0 :
frame->cpu.aim.dar) != 0)
diff --git a/sys/powerpc/aim/trap_subr32.S b/sys/powerpc/aim/trap_subr32.S
index 6482553..1cefc28 100644
--- a/sys/powerpc/aim/trap_subr32.S
+++ b/sys/powerpc/aim/trap_subr32.S
@@ -54,7 +54,7 @@
lwz sr,9*4(pmap); mtsr 9,sr; \
lwz sr,10*4(pmap); mtsr 10,sr; \
lwz sr,11*4(pmap); mtsr 11,sr; \
- lwz sr,12*4(pmap); mtsr 12,sr; \
+ /* Skip segment 12 (USER_SR), which is restored differently */ \
lwz sr,13*4(pmap); mtsr 13,sr; \
lwz sr,14*4(pmap); mtsr 14,sr; \
lwz sr,15*4(pmap); mtsr 15,sr; isync;
@@ -66,7 +66,9 @@
GET_CPUINFO(pmap); \
lwz pmap,PC_CURPMAP(pmap); \
lwzu sr,PM_SR(pmap); \
- RESTORE_SRS(pmap,sr)
+ RESTORE_SRS(pmap,sr) \
+ /* Restore SR 12 */ \
+ lwz sr,12*4(pmap); mtsr 12,sr
/*
* Kernel SRs are loaded directly from kernel_pmap_
@@ -537,6 +539,11 @@ u_trap:
*/
k_trap:
FRAME_SETUP(PC_TEMPSAVE)
+ /* Restore USER_SR */
+ GET_CPUINFO(%r30)
+ lwz %r30,PC_CURPCB(%r30)
+ lwz %r30,PCB_AIM_USR_VSID(%r30)
+ mtsr USER_SR,%r30; sync; isync
/* Call C interrupt dispatcher: */
trapagain:
addi %r3,%r1,8
diff --git a/sys/powerpc/aim/trap_subr64.S b/sys/powerpc/aim/trap_subr64.S
index e0dae3c..db54d4b 100644
--- a/sys/powerpc/aim/trap_subr64.S
+++ b/sys/powerpc/aim/trap_subr64.S
@@ -99,7 +99,7 @@ instkernslb:
addi %r28, %r28, 16; /* Advance pointer */
addi %r29, %r29, 1;
- cmpli 0, %r29, USER_SR; /* Repeat if we are not at the end */
+ cmpli 0, %r29, USER_SLB_SLOT; /* Repeat if we are not at the end */
blt instkernslb;
blr;
diff --git a/sys/powerpc/aim/vm_machdep.c b/sys/powerpc/aim/vm_machdep.c
index d1d569f..7bd0fb7 100644
--- a/sys/powerpc/aim/vm_machdep.c
+++ b/sys/powerpc/aim/vm_machdep.c
@@ -197,7 +197,6 @@ cpu_fork(struct thread *td1, struct proc *p2, struct thread *td2, int flags)
pcb->pcb_lr = (register_t)fork_trampoline;
#endif
pcb->pcb_cpu.aim.usr_vsid = 0;
- pcb->pcb_cpu.aim.usr_esid = 0;
/* Setup to release spin count in fork_exit(). */
td2->td_md.md_spinlock_count = 1;
diff --git a/sys/powerpc/conf/GENERIC b/sys/powerpc/conf/GENERIC
index c23e9ac..2d1a0ca 100644
--- a/sys/powerpc/conf/GENERIC
+++ b/sys/powerpc/conf/GENERIC
@@ -84,6 +84,7 @@ device cpufreq
# Standard busses
device pci
+device agp
# ATA and ATAPI devices
device ata
diff --git a/sys/powerpc/conf/GENERIC64 b/sys/powerpc/conf/GENERIC64
index b861e51..b18dee9 100644
--- a/sys/powerpc/conf/GENERIC64
+++ b/sys/powerpc/conf/GENERIC64
@@ -83,6 +83,7 @@ device cpufreq
# Standard busses
device pci
+device agp
# ATA and ATAPI devices
device ata
diff --git a/sys/powerpc/conf/NOTES b/sys/powerpc/conf/NOTES
index 7248eab..a9a620a 100644
--- a/sys/powerpc/conf/NOTES
+++ b/sys/powerpc/conf/NOTES
@@ -30,6 +30,7 @@ device cpufreq
# Standard busses
device pci
+device agp
device bm # Apple BMAC (Big Mac Ethernet)
device kiic # Apple Keywest I2C Controller
diff --git a/sys/powerpc/include/pcb.h b/sys/powerpc/include/pcb.h
index a037276..ede7644 100644
--- a/sys/powerpc/include/pcb.h
+++ b/sys/powerpc/include/pcb.h
@@ -67,7 +67,6 @@ struct pcb {
union {
struct {
vm_offset_t usr_segm; /* Base address */
- register_t usr_esid; /* USER_SR segment */
register_t usr_vsid; /* USER_SR segment */
} aim;
struct {
diff --git a/sys/powerpc/include/slb.h b/sys/powerpc/include/slb.h
index 0d650b3..f675e15 100644
--- a/sys/powerpc/include/slb.h
+++ b/sys/powerpc/include/slb.h
@@ -62,6 +62,13 @@
#define SLBE_ESID_MASK 0xfffffffff0000000UL /* Effective segment ID mask */
#define SLBE_ESID_SHIFT 28
+/*
+ * User segment for copyin/out
+ */
+#define USER_SLB_SLOT 63
+#define USER_SLB_SLBE (((USER_ADDR >> ADDR_SR_SHFT) << SLBE_ESID_SHIFT) | \
+ SLBE_VALID | USER_SLB_SLOT)
+
struct slb {
uint64_t slbv;
uint64_t slbe;
diff --git a/sys/powerpc/include/sr.h b/sys/powerpc/include/sr.h
index ed9801a..ae66314 100644
--- a/sys/powerpc/include/sr.h
+++ b/sys/powerpc/include/sr.h
@@ -42,11 +42,7 @@
#define SR_VSID_MASK 0x00ffffff /* Virtual Segment ID mask */
/* Kernel segment register usage */
-#ifdef __powerpc64__
-#define USER_SR 63
-#else
#define USER_SR 12
-#endif
#define KERNEL_SR 13
#define KERNEL2_SR 14
#define KERNEL3_SR 15
diff --git a/sys/powerpc/powermac/cpcht.c b/sys/powerpc/powermac/cpcht.c
index 3af4d60..ab5c870 100644
--- a/sys/powerpc/powermac/cpcht.c
+++ b/sys/powerpc/powermac/cpcht.c
@@ -162,6 +162,7 @@ struct cpcht_softc {
vm_offset_t sc_data;
uint64_t sc_populated_slots;
struct rman sc_mem_rman;
+ struct rman sc_io_rman;
struct cpcht_irq htirq_map[128];
struct mtx htirq_mtx;
@@ -177,6 +178,9 @@ static devclass_t cpcht_devclass;
DRIVER_MODULE(cpcht, nexus, cpcht_driver, cpcht_devclass, 0, 0);
+#define CPCHT_IOPORT_BASE 0xf4000000UL /* Hardwired */
+#define CPCHT_IOPORT_SIZE 0x00400000UL
+
#define HTAPIC_REQUEST_EOI 0x20
#define HTAPIC_TRIGGER_LEVEL 0x02
#define HTAPIC_MASK 0x01
@@ -236,7 +240,14 @@ cpcht_attach(device_t dev)
sc->sc_mem_rman.rm_type = RMAN_ARRAY;
sc->sc_mem_rman.rm_descr = "CPCHT Device Memory";
error = rman_init(&sc->sc_mem_rman);
+ if (error) {
+ device_printf(dev, "rman_init() failed. error = %d\n", error);
+ return (error);
+ }
+ sc->sc_io_rman.rm_type = RMAN_ARRAY;
+ sc->sc_io_rman.rm_descr = "CPCHT I/O Memory";
+ error = rman_init(&sc->sc_io_rman);
if (error) {
device_printf(dev, "rman_init() failed. error = %d\n", error);
return (error);
@@ -248,6 +259,9 @@ cpcht_attach(device_t dev)
* where we get the HT interrupts properties.
*/
+ /* I/O port mappings are usually not in the device tree */
+ rman_manage_region(&sc->sc_io_rman, 0, CPCHT_IOPORT_SIZE - 1);
+
bzero(sc->htirq_map, sizeof(sc->htirq_map));
mtx_init(&sc->htirq_mtx, "cpcht irq", NULL, MTX_DEF);
for (i = 0; i < 8; i++)
@@ -299,6 +313,9 @@ cpcht_configure_htbridge(device_t dev, phandle_t child)
case OFW_PCI_PHYS_HI_SPACE_CONFIG:
break;
case OFW_PCI_PHYS_HI_SPACE_IO:
+ rman_manage_region(&sc->sc_io_rman, rp->pci_lo,
+ rp->pci_lo + rp->size_lo - 1);
+ break;
case OFW_PCI_PHYS_HI_SPACE_MEM32:
rman_manage_region(&sc->sc_mem_rman, rp->pci_lo,
rp->pci_lo + rp->size_lo - 1);
@@ -507,8 +524,9 @@ cpcht_alloc_resource(device_t bus, device_t child, int type, int *rid,
switch (type) {
case SYS_RES_IOPORT:
end = min(end, start + count);
+ rm = &sc->sc_io_rman;
+ break;
- /* FALLTHROUGH */
case SYS_RES_MEMORY:
rm = &sc->sc_mem_rman;
break;
@@ -562,6 +580,9 @@ cpcht_activate_resource(device_t bus, device_t child, int type, int rid,
start = (vm_offset_t)rman_get_start(res);
+ if (type == SYS_RES_IOPORT)
+ start += CPCHT_IOPORT_BASE;
+
if (bootverbose)
printf("cpcht mapdev: start %zx, len %ld\n", start,
rman_get_size(res));
diff --git a/sys/powerpc/powerpc/exec_machdep.c b/sys/powerpc/powerpc/exec_machdep.c
index a4e397d..efcd805 100644
--- a/sys/powerpc/powerpc/exec_machdep.c
+++ b/sys/powerpc/powerpc/exec_machdep.c
@@ -986,7 +986,6 @@ cpu_set_upcall(struct thread *td, struct thread *td0)
pcb2->pcb_lr = (register_t)fork_trampoline;
#endif
pcb2->pcb_cpu.aim.usr_vsid = 0;
- pcb2->pcb_cpu.aim.usr_esid = 0;
/* Setup to release spin count in fork_exit(). */
td->td_md.md_spinlock_count = 1;
diff --git a/sys/powerpc/powerpc/genassym.c b/sys/powerpc/powerpc/genassym.c
index 3437ca0..9f59498 100644
--- a/sys/powerpc/powerpc/genassym.c
+++ b/sys/powerpc/powerpc/genassym.c
@@ -103,13 +103,15 @@ ASSYM(TLBSAVE_BOOKE_R31, TLBSAVE_BOOKE_R31*sizeof(register_t));
ASSYM(MTX_LOCK, offsetof(struct mtx, mtx_lock));
#if defined(AIM)
-ASSYM(USER_SR, USER_SR);
ASSYM(USER_ADDR, USER_ADDR);
#ifdef __powerpc64__
ASSYM(PC_KERNSLB, offsetof(struct pcpu, pc_slb));
ASSYM(PC_USERSLB, offsetof(struct pcpu, pc_userslb));
+ASSYM(USER_SLB_SLOT, USER_SLB_SLOT);
+ASSYM(USER_SLB_SLBE, USER_SLB_SLBE);
#else
ASSYM(PM_SR, offsetof(struct pmap, pm_sr));
+ASSYM(USER_SR, USER_SR);
#endif
#elif defined(E500)
ASSYM(PM_PDIR, offsetof(struct pmap, pm_pdir));
@@ -187,7 +189,6 @@ ASSYM(PCB_FLAGS, offsetof(struct pcb, pcb_flags));
ASSYM(PCB_FPU, PCB_FPU);
ASSYM(PCB_VEC, PCB_VEC);
-ASSYM(PCB_AIM_USR_ESID, offsetof(struct pcb, pcb_cpu.aim.usr_esid));
ASSYM(PCB_AIM_USR_VSID, offsetof(struct pcb, pcb_cpu.aim.usr_vsid));
ASSYM(PCB_BOOKE_CTR, offsetof(struct pcb, pcb_cpu.booke.ctr));
ASSYM(PCB_BOOKE_XER, offsetof(struct pcb, pcb_cpu.booke.xer));
diff --git a/sys/sparc64/sparc64/pmap.c b/sys/sparc64/sparc64/pmap.c
index b34a07f..d12e110 100644
--- a/sys/sparc64/sparc64/pmap.c
+++ b/sys/sparc64/sparc64/pmap.c
@@ -1065,7 +1065,7 @@ pmap_pinit0(pmap_t pm)
PMAP_LOCK_INIT(pm);
for (i = 0; i < MAXCPU; i++)
- pm->pm_context[i] = 0;
+ pm->pm_context[i] = TLB_CTX_KERNEL;
pm->pm_active = 0;
pm->pm_tsb = NULL;
pm->pm_tsb_obj = NULL;
@@ -1103,6 +1103,12 @@ pmap_pinit(pmap_t pm)
if (pm->pm_tsb_obj == NULL)
pm->pm_tsb_obj = vm_object_allocate(OBJT_PHYS, TSB_PAGES);
+ mtx_lock_spin(&sched_lock);
+ for (i = 0; i < MAXCPU; i++)
+ pm->pm_context[i] = -1;
+ pm->pm_active = 0;
+ mtx_unlock_spin(&sched_lock);
+
VM_OBJECT_LOCK(pm->pm_tsb_obj);
for (i = 0; i < TSB_PAGES; i++) {
m = vm_page_grab(pm->pm_tsb_obj, i, VM_ALLOC_NOBUSY |
@@ -1114,9 +1120,6 @@ pmap_pinit(pmap_t pm)
VM_OBJECT_UNLOCK(pm->pm_tsb_obj);
pmap_qenter((vm_offset_t)pm->pm_tsb, ma, TSB_PAGES);
- for (i = 0; i < MAXCPU; i++)
- pm->pm_context[i] = -1;
- pm->pm_active = 0;
bzero(&pm->pm_stats, sizeof(pm->pm_stats));
return (1);
}
diff --git a/sys/sparc64/sparc64/tick.c b/sys/sparc64/sparc64/tick.c
index 82c24a5..84879d1 100644
--- a/sys/sparc64/sparc64/tick.c
+++ b/sys/sparc64/sparc64/tick.c
@@ -78,28 +78,69 @@ u_int tick_et_use_stick = 0;
SYSCTL_INT(_machdep_tick, OID_AUTO, tick_et_use_stick, CTLFLAG_RD,
&tick_et_use_stick, 0, "tick event timer uses STICK instead of TICK");
+typedef uint64_t rd_tick_t(void);
+static rd_tick_t *rd_tick;
+typedef void wr_tick_cmpr_t(uint64_t);
+static wr_tick_cmpr_t *wr_tick_cmpr;
+
static struct timecounter stick_tc;
-static struct timecounter tick_tc;
static struct eventtimer tick_et;
+static struct timecounter tick_tc;
-static uint64_t tick_cputicks(void);
-static timecounter_get_t stick_get_timecount_up;
#ifdef SMP
static timecounter_get_t stick_get_timecount_mp;
#endif
-static timecounter_get_t tick_get_timecount_up;
+static timecounter_get_t stick_get_timecount_up;
+static rd_tick_t stick_rd;
+static wr_tick_cmpr_t stick_wr_cmpr;
+static int tick_et_start(struct eventtimer *et, struct bintime *first,
+ struct bintime *period);
+static int tick_et_stop(struct eventtimer *et);
#ifdef SMP
static timecounter_get_t tick_get_timecount_mp;
#endif
-static int tick_et_start(struct eventtimer *et,
- struct bintime *first, struct bintime *period);
-static int tick_et_stop(struct eventtimer *et);
+static timecounter_get_t tick_get_timecount_up;
static void tick_intr(struct trapframe *tf);
-static void tick_intr_bbwar(struct trapframe *tf);
static inline void tick_process(struct trapframe *tf);
-static inline void tick_process_periodic(struct trapframe *tf, u_long tick,
- u_long tick_increment, u_long adj);
-static void stick_intr(struct trapframe *tf);
+static rd_tick_t tick_rd;
+static wr_tick_cmpr_t tick_wr_cmpr;
+static wr_tick_cmpr_t tick_wr_cmpr_bbwar;
+static uint64_t tick_cputicks(void);
+
+static uint64_t
+stick_rd(void)
+{
+
+ return (rdstick());
+}
+
+static void
+stick_wr_cmpr(uint64_t tick)
+{
+
+ wrstickcmpr(tick, 0);
+}
+
+static uint64_t
+tick_rd(void)
+{
+
+ return (rd(tick));
+}
+
+static void
+tick_wr_cmpr(uint64_t tick_cmpr)
+{
+
+ wr(tick_cmpr, tick_cmpr, 0);
+}
+
+static void
+tick_wr_cmpr_bbwar(uint64_t tick_cmpr)
+{
+
+ wrtickcmpr(tick_cmpr, 0);
+}
static uint64_t
tick_cputicks(void)
@@ -128,17 +169,22 @@ cpu_initclocks(void)
* frequencies they shouldn't be used except when really necessary.
*/
if (tick_et_use_stick != 0) {
- intr_setup(PIL_TICK, stick_intr, -1, NULL, NULL);
+ rd_tick = stick_rd;
+ wr_tick_cmpr = stick_wr_cmpr;
/*
* We don't provide a CPU ticker as long as the frequency
* supplied isn't actually used per-CPU.
*/
} else {
- intr_setup(PIL_TICK, PCPU_GET(impl) >= CPU_IMPL_ULTRASPARCI &&
- PCPU_GET(impl) < CPU_IMPL_ULTRASPARCIII ?
- tick_intr_bbwar : tick_intr, -1, NULL, NULL);
+ rd_tick = tick_rd;
+ if (PCPU_GET(impl) >= CPU_IMPL_ULTRASPARCI &&
+ PCPU_GET(impl) < CPU_IMPL_ULTRASPARCIII)
+ wr_tick_cmpr = tick_wr_cmpr_bbwar;
+ else
+ wr_tick_cmpr = tick_wr_cmpr;
set_cputicker(tick_cputicks, clock, 0);
}
+ intr_setup(PIL_TICK, tick_intr, -1, NULL, NULL);
/*
* Initialize the (S)TICK-based timecounter(s).
@@ -214,106 +260,56 @@ tick_process(struct trapframe *tf)
critical_exit();
}
-/*
- * NB: the sequence of reading the (S)TICK register, calculating the value
- * of the next tick and writing it to the (S)TICK_COMPARE register must not
- * be interrupted, not even by an IPI, otherwise a value that is in the past
- * could be written in the worst case, causing the periodic timer to stop.
- */
-
static void
tick_intr(struct trapframe *tf)
{
- u_long adj, tick, tick_increment;
- register_t s;
-
- s = intr_disable();
- tick_increment = PCPU_GET(tickincrement);
- if (tick_increment != 0) {
- adj = PCPU_GET(tickadj);
- tick = rd(tick);
- wr(tick_cmpr, tick + tick_increment - adj, 0);
- intr_restore(s);
- tick_process_periodic(tf, tick, tick_increment, adj);
- } else {
- intr_restore(s);
- tick_process(tf);
- }
-}
-
-static void
-tick_intr_bbwar(struct trapframe *tf)
-{
- u_long adj, tick, tick_increment;
- register_t s;
-
- s = intr_disable();
- tick_increment = PCPU_GET(tickincrement);
- if (tick_increment != 0) {
- adj = PCPU_GET(tickadj);
- tick = rd(tick);
- wrtickcmpr(tick + tick_increment - adj, 0);
- intr_restore(s);
- tick_process_periodic(tf, tick, tick_increment, adj);
- } else {
- intr_restore(s);
- tick_process(tf);
- }
-}
-
-static void
-stick_intr(struct trapframe *tf)
-{
- u_long adj, stick, tick_increment;
+ u_long adj, ref, tick, tick_increment;
+ long delta;
register_t s;
+ int count;
- s = intr_disable();
tick_increment = PCPU_GET(tickincrement);
if (tick_increment != 0) {
+ /*
+ * NB: the sequence of reading the (S)TICK register,
+ * calculating the value of the next tick and writing it to
+ * the (S)TICK_COMPARE register must not be interrupted, not
+ * even by an IPI, otherwise a value that is in the past could
+ * be written in the worst case and thus causing the periodic
+ * timer to stop.
+ */
+ s = intr_disable();
adj = PCPU_GET(tickadj);
- stick = rdstick();
- wrstickcmpr(stick + tick_increment - adj, 0);
+ tick = rd_tick();
+ wr_tick_cmpr(tick + tick_increment - adj);
intr_restore(s);
- tick_process_periodic(tf, stick, tick_increment, adj);
- } else {
- intr_restore(s);
- tick_process(tf);
- }
-}
-
-static inline void
-tick_process_periodic(struct trapframe *tf, u_long tick,
- u_long tick_increment, u_long adj)
-{
- u_long ref;
- long delta;
- int count;
-
- ref = PCPU_GET(tickref);
- delta = tick - ref;
- count = 0;
- while (delta >= tick_increment) {
- tick_process(tf);
- delta -= tick_increment;
- ref += tick_increment;
- if (adj != 0)
- adjust_ticks++;
- count++;
- }
- if (count > 0) {
- adjust_missed += count - 1;
- if (delta > (tick_increment >> 3)) {
- if (adj == 0)
- adjust_edges++;
- adj = tick_increment >> 4;
- } else
+ ref = PCPU_GET(tickref);
+ delta = tick - ref;
+ count = 0;
+ while (delta >= tick_increment) {
+ tick_process(tf);
+ delta -= tick_increment;
+ ref += tick_increment;
+ if (adj != 0)
+ adjust_ticks++;
+ count++;
+ }
+ if (count > 0) {
+ adjust_missed += count - 1;
+ if (delta > (tick_increment >> 3)) {
+ if (adj == 0)
+ adjust_edges++;
+ adj = tick_increment >> 4;
+ } else
+ adj = 0;
+ } else {
adj = 0;
- } else {
- adj = 0;
- adjust_excess++;
- }
- PCPU_SET(tickref, ref);
- PCPU_SET(tickadj, adj);
+ adjust_excess++;
+ }
+ PCPU_SET(tickref, ref);
+ PCPU_SET(tickadj, adj);
+ } else
+ tick_process(tf);
}
static u_int
@@ -387,19 +383,13 @@ tick_et_start(struct eventtimer *et, struct bintime *first,
* out one tick to make sure that it is not missed.
*/
s = intr_disable();
- if (tick_et_use_stick != 0)
- base = rdstick();
- else
- base = rd(tick);
+ base = rd_tick();
if (div != 0) {
PCPU_SET(tickadj, 0);
base = roundup(base, div);
}
PCPU_SET(tickref, base);
- if (tick_et_use_stick != 0)
- wrstickcmpr(base + fdiv, 0);
- else
- wrtickcmpr(base + fdiv, 0);
+ wr_tick_cmpr(base + fdiv);
intr_restore(s);
return (0);
}
diff --git a/sys/ufs/ufs/ufs_dirhash.c b/sys/ufs/ufs/ufs_dirhash.c
index d7c1d0d..9c89689 100644
--- a/sys/ufs/ufs/ufs_dirhash.c
+++ b/sys/ufs/ufs/ufs_dirhash.c
@@ -72,7 +72,8 @@ static int ufs_mindirhashsize = DIRBLKSIZ * 5;
SYSCTL_INT(_vfs_ufs, OID_AUTO, dirhash_minsize, CTLFLAG_RW,
&ufs_mindirhashsize,
0, "minimum directory size in bytes for which to use hashed lookup");
-static int ufs_dirhashmaxmem = 2 * 1024 * 1024;
+static int ufs_dirhashmaxmem = 2 * 1024 * 1024; /* NOTE: initial value. It is
+ tuned in ufsdirhash_init() */
SYSCTL_INT(_vfs_ufs, OID_AUTO, dirhash_maxmem, CTLFLAG_RW, &ufs_dirhashmaxmem,
0, "maximum allowed dirhash memory usage");
static int ufs_dirhashmem;
@@ -1290,6 +1291,9 @@ ufsdirhash_lowmem()
void
ufsdirhash_init()
{
+ ufs_dirhashmaxmem = lmax(roundup(hibufspace / 64, PAGE_SIZE),
+ 2 * 1024 * 1024);
+
ufsdirhash_zone = uma_zcreate("DIRHASH", DH_NBLKOFF * sizeof(doff_t),
NULL, NULL, NULL, NULL, UMA_ALIGN_PTR, 0);
mtx_init(&ufsdirhash_mtx, "dirhash list", NULL, MTX_DEF);
diff --git a/sys/vm/vm_phys.c b/sys/vm/vm_phys.c
index 26e4981..16b6747 100644
--- a/sys/vm/vm_phys.c
+++ b/sys/vm/vm_phys.c
@@ -137,11 +137,11 @@ sysctl_vm_phys_free(SYSCTL_HANDLER_ARGS)
sbuf_printf(&sbuf, "-- -- ");
sbuf_printf(&sbuf, "--\n");
for (oind = VM_NFREEORDER - 1; oind >= 0; oind--) {
- sbuf_printf(&sbuf, " %2.2d (%6.6dK)", oind,
+ sbuf_printf(&sbuf, " %2d (%6dK)", oind,
1 << (PAGE_SHIFT - 10 + oind));
for (pind = 0; pind < VM_NFREEPOOL; pind++) {
fl = vm_phys_free_queues[flind][pind];
- sbuf_printf(&sbuf, " | %6.6d", fl[oind].lcnt);
+ sbuf_printf(&sbuf, " | %6d", fl[oind].lcnt);
}
sbuf_printf(&sbuf, "\n");
}
diff --git a/sys/vm/vm_reserv.c b/sys/vm/vm_reserv.c
index aa8e80f..423bb31 100644
--- a/sys/vm/vm_reserv.c
+++ b/sys/vm/vm_reserv.c
@@ -193,7 +193,7 @@ sysctl_vm_reserv_partpopq(SYSCTL_HANDLER_ARGS)
unused_pages += VM_LEVEL_0_NPAGES - rv->popcnt;
}
mtx_unlock(&vm_page_queue_free_mtx);
- sbuf_printf(&sbuf, "%5.5d: %6.6dK, %6.6d\n", level,
+ sbuf_printf(&sbuf, "%5d: %6dK, %6d\n", level,
unused_pages * (PAGE_SIZE / 1024), counter);
}
error = sbuf_finish(&sbuf);
diff --git a/sys/amd64/include/apicreg.h b/sys/x86/include/apicreg.h
index fee629b..00cb571 100644
--- a/sys/amd64/include/apicreg.h
+++ b/sys/x86/include/apicreg.h
@@ -25,8 +25,8 @@
* $FreeBSD$
*/
-#ifndef _MACHINE_APICREG_H_
-#define _MACHINE_APICREG_H_
+#ifndef _X86_APICREG_H_
+#define _X86_APICREG_H_
/*
* Local && I/O APIC definitions.
@@ -442,4 +442,4 @@ typedef struct IOAPIC ioapic_t;
#define IOART_INTVEC 0x000000ff /* R/W: INTerrupt vector field */
-#endif /* _MACHINE_APICREG_H_ */
+#endif /* _X86_APICREG_H_ */
diff --git a/sys/amd64/include/mca.h b/sys/x86/include/mca.h
index dd6e69c..9322737 100644
--- a/sys/amd64/include/mca.h
+++ b/sys/x86/include/mca.h
@@ -27,8 +27,8 @@
* $FreeBSD$
*/
-#ifndef __MACHINE_MCA_H__
-#define __MACHINE_MCA_H__
+#ifndef __X86_MCA_H__
+#define __X86_MCA_H__
struct mca_record {
uint64_t mr_status;
@@ -53,4 +53,4 @@ void mca_resume(void);
#endif
-#endif /* !__MACHINE_MCA_H__ */
+#endif /* !__X86_MCA_H__ */
diff --git a/sys/amd64/amd64/dump_machdep.c b/sys/x86/x86/dump_machdep.c
index a62f1e4..d0a7612 100644
--- a/sys/amd64/amd64/dump_machdep.c
+++ b/sys/x86/x86/dump_machdep.c
@@ -39,6 +39,14 @@ __FBSDID("$FreeBSD$");
#include <machine/elf.h>
#include <machine/md_var.h>
+#ifdef __amd64__
+#define KERNELDUMP_VERSION KERNELDUMP_AMD64_VERSION
+#define EM_VALUE EM_X86_64
+#else
+#define KERNELDUMP_VERSION KERNELDUMP_I386_VERSION
+#define EM_VALUE EM_386
+#endif
+
CTASSERT(sizeof(struct kerneldumpheader) == 512);
int do_minidump = 1;
@@ -168,7 +176,8 @@ cb_dumpdata(struct md_pa *mdp, int seqnr, void *arg)
if (maxdumppgs == 0) /* seatbelt */
maxdumppgs = 1;
- printf(" chunk %d: %ldMB (%ld pages)", seqnr, PG2MB(pgs), pgs);
+ printf(" chunk %d: %juMB (%ju pages)", seqnr, (uintmax_t)PG2MB(pgs),
+ (uintmax_t)pgs);
while (pgs) {
chunk = pgs;
@@ -177,7 +186,7 @@ cb_dumpdata(struct md_pa *mdp, int seqnr, void *arg)
sz = chunk << PAGE_SHIFT;
counter += sz;
if (counter >> 24) {
- printf(" %ld", PG2MB(pgs));
+ printf(" %ju", (uintmax_t)PG2MB(pgs));
counter &= (1<<24) - 1;
}
for (i = 0; i < chunk; i++) {
@@ -279,7 +288,7 @@ dumpsys(struct dumperinfo *di)
ehdr.e_ident[EI_VERSION] = EV_CURRENT;
ehdr.e_ident[EI_OSABI] = ELFOSABI_STANDALONE; /* XXX big picture? */
ehdr.e_type = ET_CORE;
- ehdr.e_machine = EM_X86_64;
+ ehdr.e_machine = EM_VALUE;
ehdr.e_phoff = sizeof(ehdr);
ehdr.e_flags = 0;
ehdr.e_ehsize = sizeof(ehdr);
@@ -304,7 +313,8 @@ dumpsys(struct dumperinfo *di)
dumplo = di->mediaoffset + di->mediasize - dumpsize;
dumplo -= sizeof(kdh) * 2;
- mkdumpheader(&kdh, KERNELDUMPMAGIC, KERNELDUMP_AMD64_VERSION, dumpsize, di->blocksize);
+ mkdumpheader(&kdh, KERNELDUMPMAGIC, KERNELDUMP_VERSION, dumpsize,
+ di->blocksize);
printf("Dumping %llu MB (%d chunks)\n", (long long)dumpsize >> 20,
ehdr.e_phnum);
diff --git a/sys/x86/x86/io_apic.c b/sys/x86/x86/io_apic.c
index 4468486..da97def 100644
--- a/sys/x86/x86/io_apic.c
+++ b/sys/x86/x86/io_apic.c
@@ -48,7 +48,7 @@ __FBSDID("$FreeBSD$");
#include <vm/vm.h>
#include <vm/pmap.h>
-#include <machine/apicreg.h>
+#include <x86/apicreg.h>
#include <machine/frame.h>
#include <machine/intr_machdep.h>
#include <machine/apicvar.h>
diff --git a/sys/x86/x86/local_apic.c b/sys/x86/x86/local_apic.c
index 6c72d28..63a6843 100644
--- a/sys/x86/x86/local_apic.c
+++ b/sys/x86/x86/local_apic.c
@@ -54,13 +54,13 @@ __FBSDID("$FreeBSD$");
#include <vm/vm.h>
#include <vm/pmap.h>
-#include <machine/apicreg.h>
+#include <x86/apicreg.h>
#include <machine/cpu.h>
#include <machine/cputypes.h>
#include <machine/frame.h>
#include <machine/intr_machdep.h>
#include <machine/apicvar.h>
-#include <machine/mca.h>
+#include <x86/mca.h>
#include <machine/md_var.h>
#include <machine/smp.h>
#include <machine/specialreg.h>
diff --git a/sys/x86/x86/mca.c b/sys/x86/x86/mca.c
index a5567e0..5ee090b 100644
--- a/sys/x86/x86/mca.c
+++ b/sys/x86/x86/mca.c
@@ -54,7 +54,7 @@ __FBSDID("$FreeBSD$");
#include <machine/intr_machdep.h>
#include <machine/apicvar.h>
#include <machine/cputypes.h>
-#include <machine/mca.h>
+#include <x86/mca.h>
#include <machine/md_var.h>
#include <machine/specialreg.h>
diff --git a/sys/i386/i386/mptable.c b/sys/x86/x86/mptable.c
index dccb64b..cad83a2 100644
--- a/sys/i386/i386/mptable.c
+++ b/sys/x86/x86/mptable.c
@@ -38,7 +38,7 @@ __FBSDID("$FreeBSD$");
#include <vm/vm_param.h>
#include <vm/pmap.h>
-#include <machine/apicreg.h>
+#include <x86/apicreg.h>
#include <machine/frame.h>
#include <machine/intr_machdep.h>
#include <machine/apicvar.h>
@@ -51,7 +51,11 @@ __FBSDID("$FreeBSD$");
/* string defined by the Intel MP Spec as identifying the MP table */
#define MP_SIG 0x5f504d5f /* _MP_ */
+#ifdef __amd64__
+#define MAX_LAPIC_ID 63 /* Max local APIC ID for HTT fixup */
+#else
#define MAX_LAPIC_ID 31 /* Max local APIC ID for HTT fixup */
+#endif
#ifdef PC98
#define BIOS_BASE (0xe8000)
diff --git a/sys/amd64/amd64/mptable_pci.c b/sys/x86/x86/mptable_pci.c
index 47a666d..47a666d 100644
--- a/sys/amd64/amd64/mptable_pci.c
+++ b/sys/x86/x86/mptable_pci.c
diff --git a/sys/x86/x86/msi.c b/sys/x86/x86/msi.c
index 428894e..381f097 100644
--- a/sys/x86/x86/msi.c
+++ b/sys/x86/x86/msi.c
@@ -45,7 +45,7 @@ __FBSDID("$FreeBSD$");
#include <sys/mutex.h>
#include <sys/sx.h>
#include <sys/systm.h>
-#include <machine/apicreg.h>
+#include <x86/apicreg.h>
#include <machine/cputypes.h>
#include <machine/md_var.h>
#include <machine/frame.h>
diff --git a/sys/i386/i386/nexus.c b/sys/x86/x86/nexus.c
index ec87528..c343730 100644
--- a/sys/i386/i386/nexus.c
+++ b/sys/x86/x86/nexus.c
@@ -41,13 +41,18 @@ __FBSDID("$FreeBSD$");
* and I/O memory address space.
*/
+#ifdef __amd64__
+#define DEV_APIC
+#else
#include "opt_apic.h"
+#endif
#include "opt_isa.h"
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/bus.h>
#include <sys/kernel.h>
+#include <sys/linker.h>
#include <sys/malloc.h>
#include <sys/module.h>
#include <machine/bus.h>
@@ -60,8 +65,10 @@ __FBSDID("$FreeBSD$");
#include <vm/pmap.h>
#include <machine/pmap.h>
+#include <machine/metadata.h>
#include <machine/nexusvar.h>
#include <machine/resource.h>
+#include <machine/pc/bios.h>
#ifdef DEV_APIC
#include "pcib_if.h"
@@ -77,6 +84,16 @@ __FBSDID("$FreeBSD$");
#endif
#include <sys/rtprio.h>
+#ifdef __amd64__
+#define BUS_SPACE_IO AMD64_BUS_SPACE_IO
+#define BUS_SPACE_MEM AMD64_BUS_SPACE_MEM
+#else
+#define BUS_SPACE_IO I386_BUS_SPACE_IO
+#define BUS_SPACE_MEM I386_BUS_SPACE_MEM
+#endif
+
+#define ELF_KERN_STR ("elf"__XSTRING(__ELF_WORD_SIZE)" kernel")
+
static MALLOC_DEFINE(M_NEXUSDEV, "nexusdev", "Nexus device");
#define DEVTONX(dev) ((struct nexus_device *)device_get_ivars(dev))
@@ -416,7 +433,7 @@ nexus_activate_resource(device_t bus, device_t child, int type, int rid,
#else
rman_set_bushandle(r, rman_get_start(r));
#endif
- rman_set_bustag(r, I386_BUS_SPACE_IO);
+ rman_set_bustag(r, BUS_SPACE_IO);
break;
case SYS_RES_MEMORY:
#ifdef PC98
@@ -427,7 +444,7 @@ nexus_activate_resource(device_t bus, device_t child, int type, int rid,
#endif
vaddr = pmap_mapdev(rman_get_start(r), rman_get_size(r));
rman_set_virtual(r, vaddr);
- rman_set_bustag(r, I386_BUS_SPACE_MEM);
+ rman_set_bustag(r, BUS_SPACE_MEM);
#ifdef PC98
/* PC-98: the type of bus_space_handle_t is the structure. */
bh->bsh_base = (bus_addr_t) vaddr;
@@ -652,10 +669,46 @@ ram_probe(device_t dev)
static int
ram_attach(device_t dev)
{
+ struct bios_smap *smapbase, *smap, *smapend;
struct resource *res;
vm_paddr_t *p;
+ caddr_t kmdp;
+ uint32_t smapsize;
int error, i, rid;
+ /* Retrieve the system memory map from the loader. */
+ kmdp = preload_search_by_type("elf kernel");
+ if (kmdp == NULL)
+ kmdp = preload_search_by_type(ELF_KERN_STR);
+ if (kmdp != NULL)
+ smapbase = (struct bios_smap *)preload_search_info(kmdp,
+ MODINFO_METADATA | MODINFOMD_SMAP);
+ else
+ smapbase = NULL;
+ if (smapbase != NULL) {
+ smapsize = *((u_int32_t *)smapbase - 1);
+ smapend = (struct bios_smap *)((uintptr_t)smapbase + smapsize);
+
+ rid = 0;
+ for (smap = smapbase; smap < smapend; smap++) {
+ if (smap->type != SMAP_TYPE_MEMORY ||
+ smap->length == 0)
+ continue;
+ error = bus_set_resource(dev, SYS_RES_MEMORY, rid,
+ smap->base, smap->length);
+ if (error)
+ panic("ram_attach: resource %d failed set with %d",
+ rid, error);
+ res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
+ 0);
+ if (res == NULL)
+ panic("ram_attach: resource %d failed to attach",
+ rid);
+ rid++;
+ }
+ return (0);
+ }
+
/*
* We use the dump_avail[] array rather than phys_avail[] for
* the memory map as phys_avail[] contains holes for kernel
OpenPOWER on IntegriCloud