[Midnightbsd-cvs] src: sys/amd64:

laffer1 at midnightbsd.org laffer1 at midnightbsd.org
Sun Sep 21 11:21:13 EDT 2008


Log Message:
-----------


Modified Files:
--------------
    src/sys/amd64:
        Makefile (r1.1.1.1 -> r1.2)
    src/sys/amd64/acpica:
        OsdEnvironment.c (r1.1.1.1 -> r1.2)
        acpi_machdep.c (r1.1.1.1 -> r1.2)
        acpi_wakeup.c (r1.1.1.1 -> r1.2)
        madt.c (r1.1.1.1 -> r1.2)
    src/sys/amd64/amd64:
        apic_vector.S (r1.1.1.1 -> r1.2)
        bios.c (r1.1.1.1 -> r1.2)
        busdma_machdep.c (r1.2 -> r1.3)
        cpu_switch.S (r1.1.1.1 -> r1.2)
        db_disasm.c (r1.1.1.1 -> r1.2)
        db_trace.c (r1.2 -> r1.3)
        dump_machdep.c (r1.1.1.1 -> r1.2)
        elf_machdep.c (r1.1.1.2 -> r1.2)
        fpu.c (r1.2 -> r1.3)
        gdb_machdep.c (r1.1.1.1 -> r1.2)
        genassym.c (r1.1.1.1 -> r1.2)
        identcpu.c (r1.3 -> r1.4)
        initcpu.c (r1.2 -> r1.3)
        intr_machdep.c (r1.2 -> r1.3)
        io.c (r1.1.1.1 -> r1.2)
        io_apic.c (r1.2 -> r1.3)
        legacy.c (r1.1.1.1 -> r1.2)
        local_apic.c (r1.2 -> r1.3)
        machdep.c (r1.2 -> r1.3)
        mp_machdep.c (r1.2 -> r1.3)
        mp_watchdog.c (r1.1.1.1 -> r1.2)
        mptable.c (r1.1.1.1 -> r1.2)
        mptable_pci.c (r1.1.1.1 -> r1.2)
        nexus.c (r1.1.1.1 -> r1.2)
        pmap.c (r1.1.1.1 -> r1.2)
        prof_machdep.c (r1.1.1.1 -> r1.2)
        support.S (r1.1.1.1 -> r1.2)
        trap.c (r1.1.1.1 -> r1.2)
        tsc.c (r1.1.1.1 -> r1.2)
        uma_machdep.c (r1.1.1.1 -> r1.2)
        vm_machdep.c (r1.1.1.1 -> r1.2)
    src/sys/amd64/ia32:
        ia32_exception.S (r1.1.1.1 -> r1.2)
        ia32_reg.c (r1.1.1.2 -> r1.2)
        ia32_signal.c (r1.1.1.1 -> r1.2)
        ia32_sigtramp.S (r1.1.1.1 -> r1.2)
        ia32_syscall.c (r1.1.1.1 -> r1.2)
    src/sys/amd64/include:
        _limits.h (r1.1.1.1 -> r1.2)
        _types.h (r1.1.1.1 -> r1.2)
        acpica_machdep.h (r1.1.1.2 -> r1.2)
        apicvar.h (r1.2 -> r1.3)
        asm.h (r1.1.1.1 -> r1.2)
        asmacros.h (r1.1.1.1 -> r1.2)
        atomic.h (r1.1.1.1 -> r1.2)
        bus.h (r1.1.1.1 -> r1.2)
        bus_dma.h (r1.1.1.1 -> r1.2)
        clock.h (r1.1.1.1 -> r1.2)
        cpu.h (r1.1.1.1 -> r1.2)
        elf.h (r1.1.1.1 -> r1.2)
        frame.h (r1.1.1.1 -> r1.2)
        gdb_machdep.h (r1.1.1.1 -> r1.2)
        intr_machdep.h (r1.2 -> r1.3)
        kdb.h (r1.1.1.1 -> r1.2)
        legacyvar.h (r1.1.1.1 -> r1.2)
        md_var.h (r1.2 -> r1.3)
        mptable.h (r1.2 -> r1.3)
        mutex.h (r1.1.1.2 -> r1.2)
        param.h (r1.1.1.1 -> r1.2)
        pcb.h (r1.1.1.1 -> r1.2)
        pci_cfgreg.h (r1.1.1.1 -> r1.2)
        pcpu.h (r1.1.1.1 -> r1.2)
        pmap.h (r1.1.1.1 -> r1.2)
        profile.h (r1.1.1.1 -> r1.2)
        reg.h (r1.1.1.1 -> r1.2)
        segments.h (r1.1.1.1 -> r1.2)
        setjmp.h (r1.1.1.1 -> r1.2)
        signal.h (r1.1.1.1 -> r1.2)
        smp.h (r1.1.1.1 -> r1.2)
        specialreg.h (r1.2 -> r1.3)
        stdarg.h (r1.2 -> r1.3)
        trap.h (r1.1.1.1 -> r1.2)
        vmparam.h (r1.1.1.1 -> r1.2)
    src/sys/amd64/include/pc:
        bios.h (r1.1.1.1 -> r1.2)
    src/sys/amd64/isa:
        atpic.c (r1.2 -> r1.3)
        atpic_vector.S (r1.1.1.1 -> r1.2)
        clock.c (r1.1.1.1 -> r1.2)
        icu.h (r1.1.1.1 -> r1.2)
        isa.c (r1.1.1.1 -> r1.2)
    src/sys/amd64/linux32:
        linux.h (r1.1.1.1 -> r1.2)
        linux32_dummy.c (r1.1.1.1 -> r1.2)
        linux32_locore.s (r1.1.1.1 -> r1.2)
        linux32_machdep.c (r1.1.1.1 -> r1.2)
        linux32_proto.h (r1.1.1.1 -> r1.2)
        linux32_syscall.h (r1.1.1.1 -> r1.2)
        linux32_sysent.c (r1.1.1.1 -> r1.2)
        linux32_sysvec.c (r1.1.1.2 -> r1.2)
        syscalls.conf (r1.1.1.1 -> r1.2)
        syscalls.master (r1.1.1.1 -> r1.2)
    src/sys/amd64/pci:
        pci_bus.c (r1.1.1.1 -> r1.2)
        pci_cfgreg.c (r1.1.1.1 -> r1.2)

Added Files:
-----------
    src/sys/amd64/amd64:
        bpf_jit_machdep.c (r1.1)
        bpf_jit_machdep.h (r1.1)
        minidump_machdep.c (r1.1)
        msi.c (r1.1)
    src/sys/amd64/include:
        minidump.h (r1.1)
    src/sys/amd64/linux32:
        linux32_support.s (r1.1)

-------------- next part --------------
Index: madt.c
===================================================================
RCS file: /home/cvs/src/sys/amd64/acpica/madt.c,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L sys/amd64/acpica/madt.c -L sys/amd64/acpica/madt.c -u -r1.1.1.1 -r1.2
--- sys/amd64/acpica/madt.c
+++ sys/amd64/acpica/madt.c
@@ -28,7 +28,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/amd64/acpica/madt.c,v 1.16.2.1 2005/11/07 09:53:24 obrien Exp $");
+__FBSDID("$FreeBSD: src/sys/amd64/acpica/madt.c,v 1.24 2007/05/08 22:01:02 jhb Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -53,43 +53,43 @@
 #include <dev/acpica/acpivar.h>
 #include <dev/pci/pcivar.h>
 
-#define	NIOAPICS		32	/* Max number of I/O APICs */
-#define	NLAPICS			32	/* Max number of local APICs */
-
-typedef	void madt_entry_handler(APIC_HEADER *entry, void *arg);
+typedef	void madt_entry_handler(ACPI_SUBTABLE_HEADER *entry, void *arg);
 
 /* These two arrays are indexed by APIC IDs. */
 struct ioapic_info {
 	void *io_apic;
 	UINT32 io_vector;
-} ioapics[NIOAPICS];
+} ioapics[MAX_APIC_ID + 1];
 
 struct lapic_info {
 	u_int la_enabled:1;
 	u_int la_acpi_id:8;
-} lapics[NLAPICS];
+} lapics[MAX_APIC_ID + 1];
 
 static int madt_found_sci_override;
-static MULTIPLE_APIC_TABLE *madt;
+static ACPI_TABLE_MADT *madt;
 static vm_paddr_t madt_physaddr;
 static vm_offset_t madt_length;
 
-MALLOC_DEFINE(M_MADT, "MADT Table", "ACPI MADT Table Items");
+MALLOC_DEFINE(M_MADT, "madt_table", "ACPI MADT Table Items");
 
-static enum intr_polarity interrupt_polarity(UINT16 Polarity, UINT8 Source);
-static enum intr_trigger interrupt_trigger(UINT16 TriggerMode, UINT8 Source);
+static enum intr_polarity interrupt_polarity(UINT16 IntiFlags, UINT8 Source);
+static enum intr_trigger interrupt_trigger(UINT16 IntiFlags, UINT8 Source);
 static int	madt_find_cpu(u_int acpi_id, u_int *apic_id);
 static int	madt_find_interrupt(int intr, void **apic, u_int *pin);
 static void	*madt_map(vm_paddr_t pa, int offset, vm_offset_t length);
 static void	*madt_map_table(vm_paddr_t pa, int offset, const char *sig);
-static void	madt_parse_apics(APIC_HEADER *entry, void *arg);
-static void	madt_parse_interrupt_override(MADT_INTERRUPT_OVERRIDE *intr);
-static void	madt_parse_ints(APIC_HEADER *entry, void *arg __unused);
-static void	madt_parse_local_nmi(MADT_LOCAL_APIC_NMI *nmi);
-static void	madt_parse_nmi(MADT_NMI_SOURCE *nmi);
+static void	madt_parse_apics(ACPI_SUBTABLE_HEADER *entry, void *arg);
+static void	madt_parse_interrupt_override(
+		    ACPI_MADT_INTERRUPT_OVERRIDE *intr);
+static void	madt_parse_ints(ACPI_SUBTABLE_HEADER *entry,
+		    void *arg __unused);
+static void	madt_parse_local_nmi(ACPI_MADT_LOCAL_APIC_NMI *nmi);
+static void	madt_parse_nmi(ACPI_MADT_NMI_SOURCE *nmi);
 static int	madt_probe(void);
 static int	madt_probe_cpus(void);
-static void	madt_probe_cpus_handler(APIC_HEADER *entry, void *arg __unused);
+static void	madt_probe_cpus_handler(ACPI_SUBTABLE_HEADER *entry,
+		    void *arg __unused);
 static int	madt_probe_table(vm_paddr_t address);
 static void	madt_register(void *dummy);
 static int	madt_setup_local(void);
@@ -161,14 +161,14 @@
 	void *table;
 
 	header = madt_map(pa, offset, sizeof(ACPI_TABLE_HEADER));
-	if (strncmp(header->Signature, sig, 4) != 0) {
+	if (strncmp(header->Signature, sig, ACPI_NAME_SIZE) != 0) {
 		madt_unmap(header, sizeof(ACPI_TABLE_HEADER));
 		return (NULL);
 	}
 	length = header->Length;
 	madt_unmap(header, sizeof(ACPI_TABLE_HEADER));
 	table = madt_map(pa, offset, length);
-	if (ACPI_FAILURE(AcpiTbVerifyTableChecksum(table))) {
+	if (ACPI_FAILURE(AcpiTbChecksum(table, length))) {
 		if (bootverbose)
 			printf("MADT: Failed checksum for table %s\n", sig);
 		madt_unmap(table, length);
@@ -192,10 +192,10 @@
 static int
 madt_probe(void)
 {
-	ACPI_POINTER rsdp_ptr;
-	RSDP_DESCRIPTOR *rsdp;
-	RSDT_DESCRIPTOR *rsdt;
-	XSDT_DESCRIPTOR *xsdt;
+	ACPI_PHYSICAL_ADDRESS rsdp_ptr;
+	ACPI_TABLE_RSDP *rsdp;
+	ACPI_TABLE_RSDT *rsdt;
+	ACPI_TABLE_XSDT *xsdt;
 	int i, count;
 
 	if (resource_disabled("acpi", 0))
@@ -203,15 +203,12 @@
 
 	/*
 	 * Map in the RSDP.  Since ACPI uses AcpiOsMapMemory() which in turn
-	 * calls pmap_mapdev() to find the RSDP, we assume that we can use
-	 * pmap_mapdev() to map the RSDP.
+	 * calls pmap_mapbios() to find the RSDP, we assume that we can use
+	 * pmap_mapbios() to map the RSDP.
 	 */
-	if (AcpiOsGetRootPointer(ACPI_LOGICAL_ADDRESSING, &rsdp_ptr) != AE_OK)
+	if ((rsdp_ptr = AcpiOsGetRootPointer()) == 0)
 		return (ENXIO);
-#ifdef __i386__
-	KASSERT(rsdp_ptr.Pointer.Physical < KERNLOAD, ("RSDP too high"));
-#endif
-	rsdp = pmap_mapdev(rsdp_ptr.Pointer.Physical, sizeof(RSDP_DESCRIPTOR));
+	rsdp = pmap_mapbios(rsdp_ptr, sizeof(ACPI_TABLE_RSDP));
 	if (rsdp == NULL) {
 		if (bootverbose)
 			printf("MADT: Failed to map RSDP\n");
@@ -219,48 +216,51 @@
 	}
 
 	/*
-	 * For ACPI < 2.0, use the RSDT.  For ACPI >= 2.0, use the XSDT.
-	 * We map the XSDT and RSDT at page 1 in the crashdump area.
-	 * Page 0 is used to map in the headers of candidate ACPI tables.
+	 * For ACPI >= 2.0, use the XSDT if it is available.
+	 * Otherwise, use the RSDT.  We map the XSDT or RSDT at page 1
+	 * in the crashdump area.  Page 0 is used to map in the
+	 * headers of candidate ACPI tables.
 	 */
-	if (rsdp->Revision >= 2) {
+	if (rsdp->Revision >= 2 && rsdp->XsdtPhysicalAddress != 0) {
 		/*
 		 * AcpiOsGetRootPointer only verifies the checksum for
 		 * the version 1.0 portion of the RSDP.  Version 2.0 has
 		 * an additional checksum that we verify first.
 		 */
-		if (AcpiTbChecksum(rsdp, ACPI_RSDP_XCHECKSUM_LENGTH) != 0) {
+		if (AcpiTbChecksum((UINT8 *)rsdp, ACPI_RSDP_XCHECKSUM_LENGTH)) {
 			if (bootverbose)
 				printf("MADT: RSDP failed extended checksum\n");
 			return (ENXIO);
 		}
-		xsdt = madt_map_table(rsdp->XsdtPhysicalAddress, 1, XSDT_SIG);
+		xsdt = madt_map_table(rsdp->XsdtPhysicalAddress, 1,
+		    ACPI_SIG_XSDT);
 		if (xsdt == NULL) {
 			if (bootverbose)
 				printf("MADT: Failed to map XSDT\n");
 			return (ENXIO);
 		}
-		count = (xsdt->Length - sizeof(ACPI_TABLE_HEADER)) /
+		count = (xsdt->Header.Length - sizeof(ACPI_TABLE_HEADER)) /
 		    sizeof(UINT64);
 		for (i = 0; i < count; i++)
 			if (madt_probe_table(xsdt->TableOffsetEntry[i]))
 				break;
 		madt_unmap_table(xsdt);
 	} else {
-		rsdt = madt_map_table(rsdp->RsdtPhysicalAddress, 1, RSDT_SIG);
+		rsdt = madt_map_table(rsdp->RsdtPhysicalAddress, 1,
+		    ACPI_SIG_RSDT);
 		if (rsdt == NULL) {
 			if (bootverbose)
 				printf("MADT: Failed to map RSDT\n");
 			return (ENXIO);
 		}
-		count = (rsdt->Length - sizeof(ACPI_TABLE_HEADER)) /
+		count = (rsdt->Header.Length - sizeof(ACPI_TABLE_HEADER)) /
 		    sizeof(UINT32);
 		for (i = 0; i < count; i++)
 			if (madt_probe_table(rsdt->TableOffsetEntry[i]))
 				break;
 		madt_unmap_table(rsdt);
 	}
-	pmap_unmapdev((vm_offset_t)rsdp, sizeof(RSDP_DESCRIPTOR));
+	pmap_unmapbios((vm_offset_t)rsdp, sizeof(ACPI_TABLE_RSDP));
 	if (madt_physaddr == 0) {
 		if (bootverbose)
 			printf("MADT: No MADT table found\n");
@@ -274,7 +274,7 @@
 	 * Verify that we can map the full table and that its checksum is
 	 * correct, etc.
 	 */
-	madt = madt_map_table(madt_physaddr, 0, APIC_SIG);
+	madt = madt_map_table(madt_physaddr, 0, ACPI_SIG_MADT);
 	if (madt == NULL)
 		return (ENXIO);
 	madt_unmap_table(madt);
@@ -302,7 +302,7 @@
 		printf("Table '%.4s' at 0x%jx\n", table->Signature,
 		    (uintmax_t)address);
 
-	if (strncmp(table->Signature, APIC_SIG, 4) != 0) {
+	if (strncmp(table->Signature, ACPI_SIG_MADT, ACPI_NAME_SIZE) != 0) {
 		madt_unmap(table, sizeof(ACPI_TABLE_HEADER));
 		return (0);
 	}
@@ -319,7 +319,7 @@
 madt_probe_cpus(void)
 {
 
-	madt = madt_map_table(madt_physaddr, 0, APIC_SIG);
+	madt = madt_map_table(madt_physaddr, 0, ACPI_SIG_MADT);
 	KASSERT(madt != NULL, ("Unable to re-map MADT"));
 	madt_walk_table(madt_probe_cpus_handler, NULL);
 	madt_unmap_table(madt);
@@ -334,11 +334,11 @@
 madt_setup_local(void)
 {
 
-	madt = pmap_mapdev(madt_physaddr, madt_length);
-	lapic_init((uintptr_t)madt->LocalApicAddress);
+	madt = pmap_mapbios(madt_physaddr, madt_length);
+	lapic_init(madt->Address);
 	printf("ACPI APIC Table: <%.*s %.*s>\n",
-	    (int)sizeof(madt->OemId), madt->OemId,
-	    (int)sizeof(madt->OemTableId), madt->OemTableId);
+	    (int)sizeof(madt->Header.OemId), madt->Header.OemId,
+	    (int)sizeof(madt->Header.OemTableId), madt->Header.OemTableId);
 
 	/*
 	 * We ignore 64-bit local APIC override entries.  Should we
@@ -377,10 +377,10 @@
 	 * force it to use level trigger and active-low polarity.
 	 */
 	if (!madt_found_sci_override) {
-		if (madt_find_interrupt(AcpiGbl_FADT->SciInt, &ioapic, &pin)
-		    != 0)
-			printf("MADT: Could not find APIC for SCI IRQ %d\n",
-			    AcpiGbl_FADT->SciInt);
+		if (madt_find_interrupt(AcpiGbl_FADT.SciInterrupt, &ioapic,
+		    &pin) != 0)
+			printf("MADT: Could not find APIC for SCI IRQ %u\n",
+			    AcpiGbl_FADT.SciInterrupt);
 		else {
 			printf(
 	"MADT: Forcing active-low polarity and level trigger for SCI\n");
@@ -390,7 +390,7 @@
 	}
 
 	/* Third, we register all the I/O APIC's. */
-	for (i = 0; i < NIOAPICS; i++)
+	for (i = 0; i <= MAX_APIC_ID; i++)
 		if (ioapics[i].io_apic != NULL)
 			ioapic_register(ioapics[i].io_apic);
 
@@ -415,46 +415,46 @@
 static void
 madt_walk_table(madt_entry_handler *handler, void *arg)
 {
-	APIC_HEADER *entry;
+	ACPI_SUBTABLE_HEADER *entry;
 	u_char *p, *end;
 
-	end = (u_char *)(madt) + madt->Length;
+	end = (u_char *)(madt) + madt->Header.Length;
 	for (p = (u_char *)(madt + 1); p < end; ) {
-		entry = (APIC_HEADER *)p;
+		entry = (ACPI_SUBTABLE_HEADER *)p;
 		handler(entry, arg);
 		p += entry->Length;
 	}
 }
 
 static void
-madt_probe_cpus_handler(APIC_HEADER *entry, void *arg)
+madt_probe_cpus_handler(ACPI_SUBTABLE_HEADER *entry, void *arg)
 {
-	MADT_PROCESSOR_APIC *proc;
+	ACPI_MADT_LOCAL_APIC *proc;
 	struct lapic_info *la;
 
 	switch (entry->Type) {
-	case APIC_PROCESSOR:
+	case ACPI_MADT_TYPE_LOCAL_APIC:
 		/*
 		 * The MADT does not include a BSP flag, so we have to
 		 * let the MP code figure out which CPU is the BSP on
 		 * its own.
 		 */
-		proc = (MADT_PROCESSOR_APIC *)entry;
+		proc = (ACPI_MADT_LOCAL_APIC *)entry;
 		if (bootverbose)
-			printf("MADT: Found CPU APIC ID %d ACPI ID %d: %s\n",
-			    proc->LocalApicId, proc->ProcessorId,
-			    proc->ProcessorEnabled ? "enabled" : "disabled");
-		if (!proc->ProcessorEnabled)
+			printf("MADT: Found CPU APIC ID %u ACPI ID %u: %s\n",
+			    proc->Id, proc->ProcessorId,
+			    (proc->LapicFlags & ACPI_MADT_ENABLED) ?
+			    "enabled" : "disabled");
+		if (!(proc->LapicFlags & ACPI_MADT_ENABLED))
 			break;
-		if (proc->LocalApicId >= NLAPICS)
-			panic("%s: CPU ID %d too high", __func__,
-			    proc->LocalApicId);
-		la = &lapics[proc->LocalApicId];
+		if (proc->Id > MAX_APIC_ID)
+			panic("%s: CPU ID %u too high", __func__, proc->Id);
+		la = &lapics[proc->Id];
 		KASSERT(la->la_enabled == 0,
-		    ("Duplicate local APIC ID %d", proc->LocalApicId));
+		    ("Duplicate local APIC ID %u", proc->Id));
 		la->la_enabled = 1;
 		la->la_acpi_id = proc->ProcessorId;
-		lapic_create(proc->LocalApicId, 0);
+		lapic_create(proc->Id, 0);
 		break;
 	}
 }
@@ -464,27 +464,26 @@
  * Add an I/O APIC from an entry in the table.
  */
 static void
-madt_parse_apics(APIC_HEADER *entry, void *arg __unused)
+madt_parse_apics(ACPI_SUBTABLE_HEADER *entry, void *arg __unused)
 {
-	MADT_IO_APIC *apic;
+	ACPI_MADT_IO_APIC *apic;
 
 	switch (entry->Type) {
-	case APIC_IO:
-		apic = (MADT_IO_APIC *)entry;
+	case ACPI_MADT_TYPE_IO_APIC:
+		apic = (ACPI_MADT_IO_APIC *)entry;
 		if (bootverbose)
-			printf("MADT: Found IO APIC ID %d, Interrupt %d at %p\n",
-			    apic->IoApicId, apic->Interrupt,
+			printf(
+			    "MADT: Found IO APIC ID %u, Interrupt %u at %p\n",
+			    apic->Id, apic->GlobalIrqBase,
 			    (void *)(uintptr_t)apic->Address);
-		if (apic->IoApicId >= NIOAPICS)
-			panic("%s: I/O APIC ID %d too high", __func__,
-			    apic->IoApicId);
-		if (ioapics[apic->IoApicId].io_apic != NULL)
-			panic("%s: Double APIC ID %d", __func__,
-			    apic->IoApicId);
-		ioapics[apic->IoApicId].io_apic = ioapic_create(
-			(uintptr_t)apic->Address, apic->IoApicId,
-			    apic->Interrupt);
-		ioapics[apic->IoApicId].io_vector = apic->Interrupt;
+		if (apic->Id > MAX_APIC_ID)
+			panic("%s: I/O APIC ID %u too high", __func__,
+			    apic->Id);
+		if (ioapics[apic->Id].io_apic != NULL)
+			panic("%s: Double APIC ID %u", __func__, apic->Id);
+		ioapics[apic->Id].io_apic = ioapic_create(apic->Address,
+		    apic->Id, apic->GlobalIrqBase);
+		ioapics[apic->Id].io_vector = apic->GlobalIrqBase;
 		break;
 	default:
 		break;
@@ -498,18 +497,18 @@
  * SCI for which we use Active Lo, Level Triggered.
  */
 static enum intr_polarity
-interrupt_polarity(UINT16 Polarity, UINT8 Source)
+interrupt_polarity(UINT16 IntiFlags, UINT8 Source)
 {
 
-	switch (Polarity) {
-	case POLARITY_CONFORMS:
-		if (Source == AcpiGbl_FADT->SciInt)
+	switch (IntiFlags & ACPI_MADT_POLARITY_MASK) {
+	case ACPI_MADT_POLARITY_CONFORMS:
+		if (Source == AcpiGbl_FADT.SciInterrupt)
 			return (INTR_POLARITY_LOW);
 		else
 			return (INTR_POLARITY_HIGH);
-	case POLARITY_ACTIVE_HIGH:
+	case ACPI_MADT_POLARITY_ACTIVE_HIGH:
 		return (INTR_POLARITY_HIGH);
-	case POLARITY_ACTIVE_LOW:
+	case ACPI_MADT_POLARITY_ACTIVE_LOW:
 		return (INTR_POLARITY_LOW);
 	default:
 		panic("Bogus Interrupt Polarity");
@@ -517,18 +516,18 @@
 }
 
 static enum intr_trigger
-interrupt_trigger(UINT16 TriggerMode, UINT8 Source)
+interrupt_trigger(UINT16 IntiFlags, UINT8 Source)
 {
 
-	switch (TriggerMode) {
-	case TRIGGER_CONFORMS:
-		if (Source == AcpiGbl_FADT->SciInt)
+	switch (IntiFlags & ACPI_MADT_TRIGGER_MASK) {
+	case ACPI_MADT_TRIGGER_CONFORMS:
+		if (Source == AcpiGbl_FADT.SciInterrupt)
 			return (INTR_TRIGGER_LEVEL);
 		else
 			return (INTR_TRIGGER_EDGE);
-	case TRIGGER_EDGE:
+	case ACPI_MADT_TRIGGER_EDGE:
 		return (INTR_TRIGGER_EDGE);
-	case TRIGGER_LEVEL:
+	case ACPI_MADT_TRIGGER_LEVEL:
 		return (INTR_TRIGGER_LEVEL);
 	default:
 		panic("Bogus Interrupt Trigger Mode");
@@ -543,7 +542,7 @@
 {
 	int i;
 
-	for (i = 0; i < NLAPICS; i++) {
+	for (i = 0; i <= MAX_APIC_ID; i++) {
 		if (!lapics[i].la_enabled)
 			continue;
 		if (lapics[i].la_acpi_id != acpi_id)
@@ -564,7 +563,7 @@
 	int i, best;
 
 	best = -1;
-	for (i = 0; i < NIOAPICS; i++) {
+	for (i = 0; i <= MAX_APIC_ID; i++) {
 		if (ioapics[i].io_apic == NULL ||
 		    ioapics[i].io_vector > intr)
 			continue;
@@ -586,7 +585,7 @@
  * Parse an interrupt source override for an ISA interrupt.
  */
 static void
-madt_parse_interrupt_override(MADT_INTERRUPT_OVERRIDE *intr)
+madt_parse_interrupt_override(ACPI_MADT_INTERRUPT_OVERRIDE *intr)
 {
 	void *new_ioapic, *old_ioapic;
 	u_int new_pin, old_pin;
@@ -594,20 +593,19 @@
 	enum intr_polarity pol;
 	char buf[64];
 
-	if (acpi_quirks & ACPI_Q_MADT_IRQ0 && intr->Source == 0 &&
-	    intr->Interrupt == 2) {
+	if (acpi_quirks & ACPI_Q_MADT_IRQ0 && intr->SourceIrq == 0 &&
+	    intr->GlobalIrq == 2) {
 		if (bootverbose)
 			printf("MADT: Skipping timer override\n");
 		return;
 	}
 	if (bootverbose)
 		printf("MADT: Interrupt override: source %u, irq %u\n",
-		    intr->Source, intr->Interrupt);
+		    intr->SourceIrq, intr->GlobalIrq);
 	KASSERT(intr->Bus == 0, ("bus for interrupt overrides must be zero"));
-	if (madt_find_interrupt(intr->Interrupt, &new_ioapic,
-	    &new_pin) != 0) {
-		printf("MADT: Could not find APIC for vector %d (IRQ %d)\n",
-		    intr->Interrupt, intr->Source);
+	if (madt_find_interrupt(intr->GlobalIrq, &new_ioapic, &new_pin) != 0) {
+		printf("MADT: Could not find APIC for vector %u (IRQ %u)\n",
+		    intr->GlobalIrq, intr->SourceIrq);
 		return;
 	}
 
@@ -615,15 +613,15 @@
 	 * Lookup the appropriate trigger and polarity modes for this
 	 * entry.
 	 */
-	trig = interrupt_trigger(intr->TriggerMode, intr->Source);
-	pol = interrupt_polarity(intr->Polarity, intr->Source);
+	trig = interrupt_trigger(intr->IntiFlags, intr->SourceIrq);
+	pol = interrupt_polarity(intr->IntiFlags, intr->SourceIrq);
 	
 	/*
 	 * If the SCI is identity mapped but has edge trigger and
 	 * active-hi polarity or the force_sci_lo tunable is set,
 	 * force it to use level/lo.
 	 */
-	if (intr->Source == AcpiGbl_FADT->SciInt) {
+	if (intr->SourceIrq == AcpiGbl_FADT.SciInterrupt) {
 		madt_found_sci_override = 1;
 		if (getenv_string("hw.acpi.sci.trigger", buf, sizeof(buf))) {
 			if (tolower(buf[0]) == 'e')
@@ -652,23 +650,24 @@
 	}
 
 	/* Remap the IRQ if it is mapped to a different interrupt vector. */
-	if (intr->Source != intr->Interrupt) {
+	if (intr->SourceIrq != intr->GlobalIrq) {
 		/*
 		 * If the SCI is remapped to a non-ISA global interrupt,
 		 * then override the vector we use to setup and allocate
 		 * the interrupt.
 		 */
-		if (intr->Interrupt > 15 &&
-		    intr->Source == AcpiGbl_FADT->SciInt)
-			acpi_OverrideInterruptLevel(intr->Interrupt);
+		if (intr->GlobalIrq > 15 &&
+		    intr->SourceIrq == AcpiGbl_FADT.SciInterrupt)
+			acpi_OverrideInterruptLevel(intr->GlobalIrq);
 		else
-			ioapic_remap_vector(new_ioapic, new_pin, intr->Source);
-		if (madt_find_interrupt(intr->Source, &old_ioapic,
+			ioapic_remap_vector(new_ioapic, new_pin,
+			    intr->SourceIrq);
+		if (madt_find_interrupt(intr->SourceIrq, &old_ioapic,
 		    &old_pin) != 0)
-			printf("MADT: Could not find APIC for source IRQ %d\n",
-			    intr->Source);
+			printf("MADT: Could not find APIC for source IRQ %u\n",
+			    intr->SourceIrq);
 		else if (ioapic_get_vector(old_ioapic, old_pin) ==
-		    intr->Source)
+		    intr->SourceIrq)
 			ioapic_disable_pin(old_ioapic, old_pin);
 	}
 
@@ -681,31 +680,31 @@
  * Parse an entry for an NMI routed to an IO APIC.
  */
 static void
-madt_parse_nmi(MADT_NMI_SOURCE *nmi)
+madt_parse_nmi(ACPI_MADT_NMI_SOURCE *nmi)
 {
 	void *ioapic;
 	u_int pin;
 
-	if (madt_find_interrupt(nmi->Interrupt, &ioapic, &pin) != 0) {
-		printf("MADT: Could not find APIC for vector %d\n",
-		    nmi->Interrupt);
+	if (madt_find_interrupt(nmi->GlobalIrq, &ioapic, &pin) != 0) {
+		printf("MADT: Could not find APIC for vector %u\n",
+		    nmi->GlobalIrq);
 		return;
 	}
 
 	ioapic_set_nmi(ioapic, pin);
-	if (nmi->TriggerMode != TRIGGER_CONFORMS)
+	if (!(nmi->IntiFlags & ACPI_MADT_TRIGGER_CONFORMS))
 		ioapic_set_triggermode(ioapic, pin,
-		    interrupt_trigger(nmi->TriggerMode, 0));
-	if (nmi->Polarity != TRIGGER_CONFORMS)
+		    interrupt_trigger(nmi->IntiFlags, 0));
+	if (!(nmi->IntiFlags & ACPI_MADT_TRIGGER_CONFORMS))
 		ioapic_set_polarity(ioapic, pin,
-		    interrupt_polarity(nmi->Polarity, 0));
+		    interrupt_polarity(nmi->IntiFlags, 0));
 }
 
 /*
  * Parse an entry for an NMI routed to a local APIC LVT pin.
  */
 static void
-madt_parse_local_nmi(MADT_LOCAL_APIC_NMI *nmi)
+madt_parse_local_nmi(ACPI_MADT_LOCAL_APIC_NMI *nmi)
 {
 	u_int apic_id, pin;
 
@@ -713,8 +712,8 @@
 		apic_id = APIC_ID_ALL;
 	else if (madt_find_cpu(nmi->ProcessorId, &apic_id) != 0) {
 		if (bootverbose)
-			printf("MADT: Ignoring local NMI routed to ACPI CPU %u\n",
-			    nmi->ProcessorId);
+			printf("MADT: Ignoring local NMI routed to "
+			    "ACPI CPU %u\n", nmi->ProcessorId);
 		return;
 	}
 	if (nmi->Lint == 0)
@@ -722,31 +721,31 @@
 	else
 		pin = LVT_LINT1;
 	lapic_set_lvt_mode(apic_id, pin, APIC_LVT_DM_NMI);
-	if (nmi->TriggerMode != TRIGGER_CONFORMS)
+	if (!(nmi->IntiFlags & ACPI_MADT_TRIGGER_CONFORMS))
 		lapic_set_lvt_triggermode(apic_id, pin,
-		    interrupt_trigger(nmi->TriggerMode, 0));
-	if (nmi->Polarity != POLARITY_CONFORMS)
+		    interrupt_trigger(nmi->IntiFlags, 0));
+	if (!(nmi->IntiFlags & ACPI_MADT_POLARITY_CONFORMS))
 		lapic_set_lvt_polarity(apic_id, pin,
-		    interrupt_polarity(nmi->Polarity, 0));
+		    interrupt_polarity(nmi->IntiFlags, 0));
 }
 
 /*
  * Parse interrupt entries.
  */
 static void
-madt_parse_ints(APIC_HEADER *entry, void *arg __unused)
+madt_parse_ints(ACPI_SUBTABLE_HEADER *entry, void *arg __unused)
 {
 
 	switch (entry->Type) {
-	case APIC_XRUPT_OVERRIDE:
+	case ACPI_MADT_TYPE_INTERRUPT_OVERRIDE:
 		madt_parse_interrupt_override(
-			(MADT_INTERRUPT_OVERRIDE *)entry);
+			(ACPI_MADT_INTERRUPT_OVERRIDE *)entry);
 		break;
-	case APIC_NMI:
-		madt_parse_nmi((MADT_NMI_SOURCE *)entry);
+	case ACPI_MADT_TYPE_NMI_SOURCE:
+		madt_parse_nmi((ACPI_MADT_NMI_SOURCE *)entry);
 		break;
-	case APIC_LOCAL_NMI:
-		madt_parse_local_nmi((MADT_LOCAL_APIC_NMI *)entry);
+	case ACPI_MADT_TYPE_LOCAL_APIC_NMI:
+		madt_parse_local_nmi((ACPI_MADT_LOCAL_APIC_NMI *)entry);
 		break;
 	}
 }
@@ -767,7 +766,7 @@
 		if (CPU_ABSENT(i))
 			continue;
 		pc = pcpu_find(i);
-		KASSERT(pc != NULL, ("no pcpu data for CPU %d", i));
+		KASSERT(pc != NULL, ("no pcpu data for CPU %u", i));
 		la = &lapics[pc->pc_apic_id];
 		if (!la->la_enabled)
 			panic("APIC: CPU with APIC ID %u is not enabled",
Index: acpi_wakeup.c
===================================================================
RCS file: /home/cvs/src/sys/amd64/acpica/acpi_wakeup.c,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L sys/amd64/acpica/acpi_wakeup.c -L sys/amd64/acpica/acpi_wakeup.c -u -r1.1.1.1 -r1.2
--- sys/amd64/acpica/acpi_wakeup.c
+++ sys/amd64/acpica/acpi_wakeup.c
@@ -26,7 +26,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/amd64/acpica/acpi_wakeup.c,v 1.21.10.1 2005/11/07 09:53:24 obrien Exp $");
+__FBSDID("$FreeBSD: src/sys/amd64/acpica/acpi_wakeup.c,v 1.22 2005/09/11 18:39:00 obrien Exp $");
 
 #include <sys/param.h>
 #include <sys/bus.h>
Index: OsdEnvironment.c
===================================================================
RCS file: /home/cvs/src/sys/amd64/acpica/OsdEnvironment.c,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L sys/amd64/acpica/OsdEnvironment.c -L sys/amd64/acpica/OsdEnvironment.c -u -r1.1.1.1 -r1.2
--- sys/amd64/acpica/OsdEnvironment.c
+++ sys/amd64/acpica/OsdEnvironment.c
@@ -26,16 +26,18 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/amd64/acpica/OsdEnvironment.c,v 1.12.8.1 2005/11/07 09:53:24 obrien Exp $");
+__FBSDID("$FreeBSD: src/sys/amd64/acpica/OsdEnvironment.c,v 1.14 2007/03/22 18:16:38 jkim Exp $");
 
 /*
  * 6.1 : Environmental support
  */
 #include <sys/types.h>
+#include <sys/bus.h>
 #include <sys/linker_set.h>
 #include <sys/sysctl.h>
 
 #include <contrib/dev/acpica/acpi.h>
+#include <contrib/dev/acpica/actables.h>
 
 static u_long amd64_acpi_root;
 
@@ -54,25 +56,16 @@
 	return(0);
 }
 
-ACPI_STATUS
-AcpiOsGetRootPointer(UINT32 Flags, ACPI_POINTER *RsdpPhysicalAddress)
+ACPI_PHYSICAL_ADDRESS
+AcpiOsGetRootPointer(void)
 {
-	ACPI_POINTER ptr;
-	ACPI_STATUS status;
+	u_long	ptr;
+
+	if (amd64_acpi_root == 0 &&
+	    (resource_long_value("acpi", 0, "rsdp", (long *)&ptr) == 0 ||
+	    AcpiFindRootPointer((ACPI_NATIVE_UINT *)&ptr) == AE_OK) &&
+	    ptr != 0)
+		amd64_acpi_root = ptr;
 
-	if (amd64_acpi_root == 0) {
-		/*
-		 * The loader passes the physical address at which it found the
-		 * RSDP in a hint.  We could recover this rather than searching
-		 * manually here.
-		 */
-		status = AcpiFindRootPointer(Flags, &ptr);
-		if (status == AE_OK)
-			amd64_acpi_root = ptr.Pointer.Physical;
-	} else
-		status = AE_OK;
-
-	RsdpPhysicalAddress->PointerType = ACPI_PHYSICAL_POINTER;
-	RsdpPhysicalAddress->Pointer.Physical = amd64_acpi_root;
-	return (status);
+	return (amd64_acpi_root);
 }
Index: acpi_machdep.c
===================================================================
RCS file: /home/cvs/src/sys/amd64/acpica/acpi_machdep.c,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L sys/amd64/acpica/acpi_machdep.c -L sys/amd64/acpica/acpi_machdep.c -u -r1.1.1.1 -r1.2
--- sys/amd64/acpica/acpi_machdep.c
+++ sys/amd64/acpica/acpi_machdep.c
@@ -25,7 +25,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/amd64/acpica/acpi_machdep.c,v 1.16.2.1 2005/11/07 09:53:24 obrien Exp $");
+__FBSDID("$FreeBSD: src/sys/amd64/acpica/acpi_machdep.c,v 1.17 2005/09/11 18:39:00 obrien Exp $");
 
 #include <sys/param.h>
 #include <sys/bus.h>
Index: intr_machdep.c
===================================================================
RCS file: /home/cvs/src/sys/amd64/amd64/intr_machdep.c,v
retrieving revision 1.2
retrieving revision 1.3
diff -L sys/amd64/amd64/intr_machdep.c -L sys/amd64/amd64/intr_machdep.c -u -r1.2 -r1.3
--- sys/amd64/amd64/intr_machdep.c
+++ sys/amd64/amd64/intr_machdep.c
@@ -26,7 +26,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD: src/sys/amd64/amd64/intr_machdep.c,v 1.15.2.2 2006/03/10 19:37:30 jhb Exp $
+ * $FreeBSD: src/sys/amd64/amd64/intr_machdep.c,v 1.34.2.1 2007/11/26 15:06:49 scottl Exp $
  */
 
 /*
@@ -37,31 +37,50 @@
  * that source.
  */
 
+#include "opt_atpic.h"
 #include "opt_ddb.h"
 
 #include <sys/param.h>
 #include <sys/bus.h>
 #include <sys/interrupt.h>
-#include <sys/lock.h>
 #include <sys/ktr.h>
 #include <sys/kernel.h>
+#include <sys/lock.h>
 #include <sys/mutex.h>
 #include <sys/proc.h>
 #include <sys/syslog.h>
 #include <sys/systm.h>
+#include <sys/sx.h>
 #include <machine/clock.h>
 #include <machine/intr_machdep.h>
+#include <machine/smp.h>
 #ifdef DDB
 #include <ddb/ddb.h>
 #endif
 
+#ifndef DEV_ATPIC
+#include <machine/segments.h>
+#include <machine/frame.h>
+#include <dev/ic/i8259.h>
+#include <amd64/isa/icu.h>
+#include <amd64/isa/isa.h>
+#endif
+
 #define	MAX_STRAY_LOG	5
 
 typedef void (*mask_fn)(void *);
 
 static int intrcnt_index;
 static struct intsrc *interrupt_sources[NUM_IO_INTS];
-static struct mtx intr_table_lock;
+static struct sx intr_table_lock;
+static struct mtx intrcnt_lock;
+static STAILQ_HEAD(, pic) pics;
+
+#ifdef INTR_FILTER
+static void intr_eoi_src(void *arg);
+static void intr_disab_eoi_src(void *arg);
+static void intr_event_stray(void *cookie);
+#endif
 
 #ifdef SMP
 static int assign_cpu;
@@ -70,10 +89,45 @@
 #endif
 
 static void	intr_init(void *__dummy);
+static int	intr_pic_registered(struct pic *pic);
 static void	intrcnt_setname(const char *name, int index);
 static void	intrcnt_updatename(struct intsrc *is);
 static void	intrcnt_register(struct intsrc *is);
 
+static int
+intr_pic_registered(struct pic *pic)
+{
+	struct pic *p;
+
+	STAILQ_FOREACH(p, &pics, pics) {
+		if (p == pic)
+			return (1);
+	}
+	return (0);
+}
+
+/*
+ * Register a new interrupt controller (PIC).  This is to support suspend
+ * and resume where we suspend/resume controllers rather than individual
+ * sources.  This also allows controllers with no active sources (such as
+ * 8259As in a system using the APICs) to participate in suspend and resume.
+ */
+int
+intr_register_pic(struct pic *pic)
+{
+	int error;
+
+	sx_xlock(&intr_table_lock);
+	if (intr_pic_registered(pic))
+		error = EBUSY;
+	else {
+		STAILQ_INSERT_TAIL(&pics, pic, pics);
+		error = 0;
+	}
+	sx_xunlock(&intr_table_lock);
+	return (error);
+}
+
 /*
  * Register a new interrupt source with the global interrupt system.
  * The global interrupts need to be disabled when this function is
@@ -84,23 +138,30 @@
 {
 	int error, vector;
 
+	KASSERT(intr_pic_registered(isrc->is_pic), ("unregistered PIC"));
 	vector = isrc->is_pic->pic_vector(isrc);
 	if (interrupt_sources[vector] != NULL)
 		return (EEXIST);
+#ifdef INTR_FILTER
+	error = intr_event_create(&isrc->is_event, isrc, 0,
+	    (mask_fn)isrc->is_pic->pic_enable_source,
+	    intr_eoi_src, intr_disab_eoi_src, "irq%d:", vector);
+#else
 	error = intr_event_create(&isrc->is_event, isrc, 0,
 	    (mask_fn)isrc->is_pic->pic_enable_source, "irq%d:", vector);
+#endif
 	if (error)
 		return (error);
-	mtx_lock_spin(&intr_table_lock);
+	sx_xlock(&intr_table_lock);
 	if (interrupt_sources[vector] != NULL) {
-		mtx_unlock_spin(&intr_table_lock);
+		sx_xunlock(&intr_table_lock);
 		intr_event_destroy(isrc->is_event);
 		return (EEXIST);
 	}
 	intrcnt_register(isrc);
 	interrupt_sources[vector] = isrc;
-	isrc->is_enabled = 0;
-	mtx_unlock_spin(&intr_table_lock);
+	isrc->is_handlers = 0;
+	sx_xunlock(&intr_table_lock);
 	return (0);
 }
 
@@ -112,8 +173,8 @@
 }
 
 int
-intr_add_handler(const char *name, int vector, driver_intr_t handler,
-    void *arg, enum intr_type flags, void **cookiep)
+intr_add_handler(const char *name, int vector, driver_filter_t filter, 
+    driver_intr_t handler, void *arg, enum intr_type flags, void **cookiep)    
 {
 	struct intsrc *isrc;
 	int error;
@@ -121,22 +182,21 @@
 	isrc = intr_lookup_source(vector);
 	if (isrc == NULL)
 		return (EINVAL);
-	error = intr_event_add_handler(isrc->is_event, name, handler, arg,
-	    intr_priority(flags), flags, cookiep);
+	error = intr_event_add_handler(isrc->is_event, name, filter, handler,
+	    arg, intr_priority(flags), flags, cookiep);
 	if (error == 0) {
+		sx_xlock(&intr_table_lock);
 		intrcnt_updatename(isrc);
-		mtx_lock_spin(&intr_table_lock);
-		if (!isrc->is_enabled) {
-			isrc->is_enabled = 1;
+		isrc->is_handlers++;
+		if (isrc->is_handlers == 1) {
 #ifdef SMP
 			if (assign_cpu)
 				intr_assign_next_cpu(isrc);
 #endif
-			mtx_unlock_spin(&intr_table_lock);
 			isrc->is_pic->pic_enable_intr(isrc);
-		} else
-			mtx_unlock_spin(&intr_table_lock);
-		isrc->is_pic->pic_enable_source(isrc);
+			isrc->is_pic->pic_enable_source(isrc);
+		}
+		sx_xunlock(&intr_table_lock);
 	}
 	return (error);
 }
@@ -144,13 +204,21 @@
 int
 intr_remove_handler(void *cookie)
 {
+	struct intsrc *isrc;
 	int error;
 
+	isrc = intr_handler_source(cookie);
 	error = intr_event_remove_handler(cookie);
-#ifdef XXX
-	if (error == 0)
-		intrcnt_updatename(/* XXX */);
-#endif
+	if (error == 0) {
+		sx_xlock(&intr_table_lock);
+		isrc->is_handlers--;
+		if (isrc->is_handlers == 0) {
+			isrc->is_pic->pic_disable_source(isrc, PIC_NO_EOI);
+			isrc->is_pic->pic_disable_intr(isrc);
+		}
+		intrcnt_updatename(isrc);
+		sx_xunlock(&intr_table_lock);
+	}
 	return (error);
 }
 
@@ -165,13 +233,84 @@
 	return (isrc->is_pic->pic_config_intr(isrc, trig, pol));
 }
 
+#ifdef INTR_FILTER
 void
-intr_execute_handlers(struct intsrc *isrc, struct intrframe *iframe)
+intr_execute_handlers(struct intsrc *isrc, struct trapframe *frame)
+{
+	struct thread *td;
+	struct intr_event *ie;
+	int vector;
+
+	td = curthread;
+
+	/*
+	 * We count software interrupts when we process them.  The
+	 * code here follows previous practice, but there's an
+	 * argument for counting hardware interrupts when they're
+	 * processed too.
+	 */
+	(*isrc->is_count)++;
+	PCPU_INC(cnt.v_intr);
+
+	ie = isrc->is_event;
+
+	/*
+	 * XXX: We assume that IRQ 0 is only used for the ISA timer
+	 * device (clk).
+	 */
+	vector = isrc->is_pic->pic_vector(isrc);
+	if (vector == 0)
+		clkintr_pending = 1;
+
+	if (intr_event_handle(ie, frame) != 0)
+		intr_event_stray(isrc);
+}
+
+static void
+intr_event_stray(void *cookie)
+{
+	struct intsrc *isrc;
+
+	isrc = cookie;
+	/*
+	 * For stray interrupts, mask and EOI the source, bump the
+	 * stray count, and log the condition.
+	 */
+	isrc->is_pic->pic_disable_source(isrc, PIC_EOI);
+	(*isrc->is_straycount)++;
+	if (*isrc->is_straycount < MAX_STRAY_LOG)
+		log(LOG_ERR, "stray irq%d\n", isrc->is_pic->pic_vector(isrc));
+	else if (*isrc->is_straycount == MAX_STRAY_LOG)
+		log(LOG_CRIT,
+		    "too many stray irq %d's: not logging anymore\n",
+		    isrc->is_pic->pic_vector(isrc));
+}
+
+static void
+intr_eoi_src(void *arg)
+{
+	struct intsrc *isrc;
+
+	isrc = arg;
+	isrc->is_pic->pic_eoi_source(isrc);
+}
+
+static void
+intr_disab_eoi_src(void *arg)
+{
+	struct intsrc *isrc;
+
+	isrc = arg;
+	isrc->is_pic->pic_disable_source(isrc, PIC_EOI);
+}
+#else
+void
+intr_execute_handlers(struct intsrc *isrc, struct trapframe *frame)
 {
 	struct thread *td;
 	struct intr_event *ie;
 	struct intr_handler *ih;
-	int error, vector, thread;
+	int error, vector, thread, ret;
 
 	td = curthread;
 
@@ -182,7 +321,7 @@
 	 * processed too.
 	 */
 	(*isrc->is_count)++;
-	PCPU_LAZY_INC(cnt.v_intr);
+	PCPU_INC(cnt.v_intr);
 
 	ie = isrc->is_event;
 
@@ -214,23 +353,32 @@
 	 * Execute fast interrupt handlers directly.
 	 * To support clock handlers, if a handler registers
 	 * with a NULL argument, then we pass it a pointer to
-	 * an intrframe as its argument.
+	 * a trapframe as its argument.
 	 */
 	td->td_intr_nesting_level++;
+	ret = 0;
 	thread = 0;
 	critical_enter();
 	TAILQ_FOREACH(ih, &ie->ie_handlers, ih_next) {
-		if (!(ih->ih_flags & IH_FAST)) {
+		if (ih->ih_filter == NULL) {
 			thread = 1;
 			continue;
 		}
 		CTR4(KTR_INTR, "%s: exec %p(%p) for %s", __func__,
-		    ih->ih_handler, ih->ih_argument == NULL ? iframe :
+		    ih->ih_filter, ih->ih_argument == NULL ? frame :
 		    ih->ih_argument, ih->ih_name);
 		if (ih->ih_argument == NULL)
-			ih->ih_handler(iframe);
+			ret = ih->ih_filter(frame);
 		else
-			ih->ih_handler(ih->ih_argument);
+			ret = ih->ih_filter(ih->ih_argument);
+		/*
+		 * Wrapper handler special case: see
+		 * i386/intr_machdep.c::intr_execute_handlers()
+		 */
+		if (!thread) {
+			if (ret == FILTER_SCHEDULE_THREAD)
+				thread = 1;
+		}
 	}
 
 	/*
@@ -242,40 +390,44 @@
 		isrc->is_pic->pic_disable_source(isrc, PIC_EOI);
 	else
 		isrc->is_pic->pic_eoi_source(isrc);
-	critical_exit();
 
 	/* Schedule the ithread if needed. */
 	if (thread) {
 		error = intr_event_schedule_thread(ie);
 		KASSERT(error == 0, ("bad stray interrupt"));
 	}
+	critical_exit();
 	td->td_intr_nesting_level--;
 }
+#endif
 
 void
 intr_resume(void)
 {
-	struct intsrc **isrc;
-	int i;
+	struct pic *pic;
 
-	mtx_lock_spin(&intr_table_lock);
-	for (i = 0, isrc = interrupt_sources; i < NUM_IO_INTS; i++, isrc++)
-		if (*isrc != NULL && (*isrc)->is_pic->pic_resume != NULL)
-			(*isrc)->is_pic->pic_resume(*isrc);
-	mtx_unlock_spin(&intr_table_lock);
+#ifndef DEV_ATPIC
+	atpic_reset();
+#endif
+	sx_xlock(&intr_table_lock);
+	STAILQ_FOREACH(pic, &pics, pics) {
+		if (pic->pic_resume != NULL)
+			pic->pic_resume(pic);
+	}
+	sx_xunlock(&intr_table_lock);
 }
 
 void
 intr_suspend(void)
 {
-	struct intsrc **isrc;
-	int i;
+	struct pic *pic;
 
-	mtx_lock_spin(&intr_table_lock);
-	for (i = 0, isrc = interrupt_sources; i < NUM_IO_INTS; i++, isrc++)
-		if (*isrc != NULL && (*isrc)->is_pic->pic_suspend != NULL)
-			(*isrc)->is_pic->pic_suspend(*isrc);
-	mtx_unlock_spin(&intr_table_lock);
+	sx_xlock(&intr_table_lock);
+	STAILQ_FOREACH(pic, &pics, pics) {
+		if (pic->pic_suspend != NULL)
+			pic->pic_suspend(pic);
+	}
+	sx_xunlock(&intr_table_lock);
 }
 
 static void
@@ -298,8 +450,8 @@
 {
 	char straystr[MAXCOMLEN + 1];
 
-	/* mtx_assert(&intr_table_lock, MA_OWNED); */
 	KASSERT(is->is_event != NULL, ("%s: isrc with no event", __func__));
+	mtx_lock_spin(&intrcnt_lock);
 	is->is_index = intrcnt_index;
 	intrcnt_index += 2;
 	snprintf(straystr, MAXCOMLEN + 1, "stray irq%d",
@@ -308,17 +460,18 @@
 	is->is_count = &intrcnt[is->is_index];
 	intrcnt_setname(straystr, is->is_index + 1);
 	is->is_straycount = &intrcnt[is->is_index + 1];
+	mtx_unlock_spin(&intrcnt_lock);
 }
 
 void
 intrcnt_add(const char *name, u_long **countp)
 {
 
-	mtx_lock_spin(&intr_table_lock);
+	mtx_lock_spin(&intrcnt_lock);
 	*countp = &intrcnt[intrcnt_index];
 	intrcnt_setname(name, intrcnt_index);
 	intrcnt_index++;
-	mtx_unlock_spin(&intr_table_lock);
+	mtx_unlock_spin(&intrcnt_lock);
 }
 
 static void
@@ -327,10 +480,34 @@
 
 	intrcnt_setname("???", 0);
 	intrcnt_index = 1;
-	mtx_init(&intr_table_lock, "intr table", NULL, MTX_SPIN);
+	STAILQ_INIT(&pics);
+	sx_init(&intr_table_lock, "intr sources");
+	mtx_init(&intrcnt_lock, "intrcnt", NULL, MTX_SPIN);
 }
 SYSINIT(intr_init, SI_SUB_INTR, SI_ORDER_FIRST, intr_init, NULL)
 
+#ifndef DEV_ATPIC
+/* Initialize the two 8259A's to a known-good shutdown state. */
+void
+atpic_reset(void)
+{
+
+	outb(IO_ICU1, ICW1_RESET | ICW1_IC4);
+	outb(IO_ICU1 + ICU_IMR_OFFSET, IDT_IO_INTS);
+	outb(IO_ICU1 + ICU_IMR_OFFSET, 1 << 2);
+	outb(IO_ICU1 + ICU_IMR_OFFSET, ICW4_8086);
+	outb(IO_ICU1 + ICU_IMR_OFFSET, 0xff);
+	outb(IO_ICU1, OCW3_SEL | OCW3_RR);
+
+	outb(IO_ICU2, ICW1_RESET | ICW1_IC4);
+	outb(IO_ICU2 + ICU_IMR_OFFSET, IDT_IO_INTS + 8);
+	outb(IO_ICU2 + ICU_IMR_OFFSET, 2);
+	outb(IO_ICU2 + ICU_IMR_OFFSET, ICW4_8086);
+	outb(IO_ICU2 + ICU_IMR_OFFSET, 0xff);
+	outb(IO_ICU2, OCW3_SEL | OCW3_RR);
+}
+#endif
+
 #ifdef DDB
 /*
  * Dump data about interrupt handlers
@@ -338,16 +515,14 @@
 DB_SHOW_COMMAND(irqs, db_show_irqs)
 {
 	struct intsrc **isrc;
-	int i, quit, verbose;
+	int i, verbose;
 
-	quit = 0;
 	if (strcmp(modif, "v") == 0)
 		verbose = 1;
 	else
 		verbose = 0;
 	isrc = interrupt_sources;
-	db_setup_paging(db_simple_pager, &quit, db_lines_per_page);
-	for (i = 0; i < NUM_IO_INTS && !quit; i++, isrc++)
+	for (i = 0; i < NUM_IO_INTS && !db_pager_quit; i++, isrc++)
 		if (*isrc != NULL)
 			db_dump_intr_event((*isrc)->is_event, verbose);
 }
@@ -359,8 +534,9 @@
  * allocate CPUs round-robin.
  */
 
-static u_int cpu_apic_ids[MAXCPU];
-static int current_cpu, num_cpus;
+/* The BSP is always a valid target. */
+static cpumask_t intr_cpus = (1 << 0);
+static int current_cpu, num_cpus = 1;
 
 static void
 intr_assign_next_cpu(struct intsrc *isrc)
@@ -373,29 +549,29 @@
 	 */
 	pic = isrc->is_pic;
 	apic_id = cpu_apic_ids[current_cpu];
-	current_cpu++;
-	if (current_cpu >= num_cpus)
-		current_cpu = 0;
-	if (bootverbose) {
-		printf("INTR: Assigning IRQ %d", pic->pic_vector(isrc));
-		printf(" to local APIC %u\n", apic_id);
-	}
 	pic->pic_assign_cpu(isrc, apic_id);
+	do {
+		current_cpu++;
+		if (current_cpu >= num_cpus)
+			current_cpu = 0;
+	} while (!(intr_cpus & (1 << current_cpu)));
 }
 
 /*
- * Add a local APIC ID to our list of valid local APIC IDs that can
- * be destinations of interrupts.
+ * Add a CPU to our mask of valid CPUs that can be destinations of
+ * interrupts.
  */
 void
-intr_add_cpu(u_int apic_id)
+intr_add_cpu(u_int cpu)
 {
 
+	if (cpu >= MAXCPU)
+		panic("%s: Invalid CPU ID", __func__);
 	if (bootverbose)
-		printf("INTR: Adding local APIC %d as a target\n", apic_id);
-	if (num_cpus >= MAXCPU)
-		panic("WARNING: Local APIC IDs exhausted!");
-	cpu_apic_ids[num_cpus] = apic_id;
+		printf("INTR: Adding local APIC %d as a target\n",
+		    cpu_apic_ids[cpu]);
+
+	intr_cpus |= (1 << cpu);
 	num_cpus++;
 }
 
@@ -413,15 +589,15 @@
 	if (num_cpus <= 1)
 		return;
 
-	/* Round-robin assign each enabled source a CPU. */
-	mtx_lock_spin(&intr_table_lock);
+	/* Round-robin assign a CPU to each enabled source. */
+	sx_xlock(&intr_table_lock);
 	assign_cpu = 1;
 	for (i = 0; i < NUM_IO_INTS; i++) {
 		isrc = interrupt_sources[i];
-		if (isrc != NULL && isrc->is_enabled)
+		if (isrc != NULL && isrc->is_handlers > 0)
 			intr_assign_next_cpu(isrc);
 	}
-	mtx_unlock_spin(&intr_table_lock);
+	sx_xunlock(&intr_table_lock);
 }
 SYSINIT(intr_shuffle_irqs, SI_SUB_SMP, SI_ORDER_SECOND, intr_shuffle_irqs, NULL)
 #endif
Index: db_disasm.c
===================================================================
RCS file: /home/cvs/src/sys/amd64/amd64/db_disasm.c,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L sys/amd64/amd64/db_disasm.c -L sys/amd64/amd64/db_disasm.c -u -r1.1.1.1 -r1.2
--- sys/amd64/amd64/db_disasm.c
+++ sys/amd64/amd64/db_disasm.c
@@ -25,7 +25,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/amd64/amd64/db_disasm.c,v 1.30 2005/03/30 22:57:41 peter Exp $");
+__FBSDID("$FreeBSD: src/sys/amd64/amd64/db_disasm.c,v 1.31 2006/11/13 21:14:54 jhb Exp $");
 
 /*
  * Instruction disassembler.
@@ -84,6 +84,7 @@
 #define	Ib	21			/* byte immediate, unsigned */
 #define	Ibs	22			/* byte immediate, signed */
 #define	Iw	23			/* word immediate, unsigned */
+#define	Ilq	24			/* long/quad immediate, unsigned */
 #define	O	25			/* direct address */
 #define	Db	26			/* byte displacement from EIP */
 #define	Dl	27			/* long displacement from EIP */
@@ -351,7 +352,6 @@
 	0,
 	0,
 	0,
-	0,
 	db_inst_0f8x,
 	db_inst_0f9x,
 	db_inst_0fax,
@@ -752,14 +752,14 @@
 /*b6*/	{ "mov",   FALSE, BYTE,  op2(I, Ri),  0 },
 /*b7*/	{ "mov",   FALSE, BYTE,  op2(I, Ri),  0 },
 
-/*b8*/	{ "mov",   FALSE, LONG,  op2(I, Ri),  0 },
-/*b9*/	{ "mov",   FALSE, LONG,  op2(I, Ri),  0 },
-/*ba*/	{ "mov",   FALSE, LONG,  op2(I, Ri),  0 },
-/*bb*/	{ "mov",   FALSE, LONG,  op2(I, Ri),  0 },
-/*bc*/	{ "mov",   FALSE, LONG,  op2(I, Ri),  0 },
-/*bd*/	{ "mov",   FALSE, LONG,  op2(I, Ri),  0 },
-/*be*/	{ "mov",   FALSE, LONG,  op2(I, Ri),  0 },
-/*bf*/	{ "mov",   FALSE, LONG,  op2(I, Ri),  0 },
+/*b8*/	{ "mov",   FALSE, LONG,  op2(Ilq, Ri),  0 },
+/*b9*/	{ "mov",   FALSE, LONG,  op2(Ilq, Ri),  0 },
+/*ba*/	{ "mov",   FALSE, LONG,  op2(Ilq, Ri),  0 },
+/*bb*/	{ "mov",   FALSE, LONG,  op2(Ilq, Ri),  0 },
+/*bc*/	{ "mov",   FALSE, LONG,  op2(Ilq, Ri),  0 },
+/*bd*/	{ "mov",   FALSE, LONG,  op2(Ilq, Ri),  0 },
+/*be*/	{ "mov",   FALSE, LONG,  op2(Ilq, Ri),  0 },
+/*bf*/	{ "mov",   FALSE, LONG,  op2(Ilq, Ri),  0 },
 
 /*c0*/	{ "",	   TRUE,  BYTE,  op2(Ib, E),  db_Grp2 },
 /*c1*/	{ "",	   TRUE,  LONG,  op2(Ib, E),  db_Grp2 },
@@ -854,17 +854,6 @@
 	int		ss;
 };
 
-static const char * const db_index_reg_16[8] = {
-	"%bx,%si",
-	"%bx,%di",
-	"%bp,%si",
-	"%bp,%di",
-	"%si",
-	"%di",
-	"%bp",
-	"%bx"
-};
-
 static const char * const db_reg[2][4][16] = {
 
 	{{"%al",  "%cl",  "%dl",  "%bl",  "%ah",  "%ch",  "%dh",  "%bh",
@@ -927,7 +916,7 @@
 	int		regmodrm;
 	struct i_addr *	addrp;		/* out */
 {
-	int		mod, rm, sib, index, disp;
+	int		mod, rm, sib, index, disp, size, have_sib;
 
 	mod = f_mod(rex, regmodrm);
 	rm  = f_rm(rex, regmodrm);
@@ -940,68 +929,49 @@
 	addrp->is_reg = FALSE;
 	addrp->index = 0;
 
-	if (short_addr) {
-	    addrp->index = 0;
-	    addrp->ss = 0;
-	    switch (mod) {
-		case 0:
-		    if (rm == 6) {
-			get_value_inc(disp, loc, 2, FALSE);
-			addrp->disp = disp;
-			addrp->base = 0;
-		    }
-		    else {
-			addrp->disp = 0;
-			addrp->base = db_index_reg_16[rm];
-		    }
-		    break;
-		case 1:
-		    get_value_inc(disp, loc, 1, TRUE);
-		    disp &= 0xFFFF;
-		    addrp->disp = disp;
-		    addrp->base = db_index_reg_16[rm];
-		    break;
-		case 2:
-		    get_value_inc(disp, loc, 2, FALSE);
-		    addrp->disp = disp;
-		    addrp->base = db_index_reg_16[rm];
-		    break;
-	    }
-	}
-	else {
-	    if (mod != 3 && rm == 4) {
-		get_value_inc(sib, loc, 1, FALSE);
-		rm = sib_base(rex, sib);
-		index = sib_index(rex, sib);
-		if (index != 4)
-		    addrp->index = db_reg[1][QUAD][index];
-		addrp->ss = sib_ss(rex, sib);
-	    }
+	if (short_addr)
+	    size = LONG;
+	else
+	    size = QUAD;
 
-	    switch (mod) {
-		case 0:
-		    if (rm == 5) {
-			get_value_inc(addrp->disp, loc, 4, FALSE);
+	if ((rm & 0x7) == 4) {
+	    get_value_inc(sib, loc, 1, FALSE);
+	    rm = sib_base(rex, sib);
+	    index = sib_index(rex, sib);
+	    if (index != 4)
+		addrp->index = db_reg[1][size][index];
+	    addrp->ss = sib_ss(rex, sib);
+	    have_sib = 1;
+	} else
+	    have_sib = 0;
+
+	switch (mod) {
+	    case 0:
+		if (rm == 5) {
+		    get_value_inc(addrp->disp, loc, 4, FALSE);
+		    if (have_sib)
 			addrp->base = 0;
-		    }
-		    else {
-			addrp->disp = 0;
-			addrp->base = db_reg[1][QUAD][rm];
-		    }
-		    break;
-
-		case 1:
-		    get_value_inc(disp, loc, 1, TRUE);
-		    addrp->disp = disp;
-		    addrp->base = db_reg[1][QUAD][rm];
-		    break;
-
-		case 2:
-		    get_value_inc(disp, loc, 4, FALSE);
-		    addrp->disp = disp;
-		    addrp->base = db_reg[1][QUAD][rm];
-		    break;
-	    }
+		    else if (short_addr)
+			addrp->base = "%eip";
+		    else
+			addrp->base = "%rip";
+		} else {
+		    addrp->disp = 0;
+		    addrp->base = db_reg[1][size][rm];
+		}
+		break;
+
+	    case 1:
+		get_value_inc(disp, loc, 1, TRUE);
+		addrp->disp = disp;
+		addrp->base = db_reg[1][size][rm];
+		break;
+
+	    case 2:
+		get_value_inc(disp, loc, 4, FALSE);
+		addrp->disp = disp;
+		addrp->base = db_reg[1][size][rm];
+		break;
 	}
 	return (loc);
 }
@@ -1022,7 +992,8 @@
 	    db_printf("%s:", seg);
 	}
 
-	db_printsym((db_addr_t)addrp->disp, DB_STGY_ANY);
+	if (addrp->disp != 0 || (addrp->base == 0 && addrp->index == 0))
+		db_printsym((db_addr_t)addrp->disp, DB_STGY_ANY);
 	if (addrp->base != 0 || addrp->index != 0) {
 	    db_printf("(");
 	    if (addrp->base)
@@ -1154,6 +1125,7 @@
 	int	prefix;
 	int	imm;
 	int	imm2;
+	long	imm64;
 	int	len;
 	struct i_addr	address;
 
@@ -1426,6 +1398,12 @@
 		    db_printf("$%#r", imm);
 		    break;
 
+		case Ilq:
+		    len = db_lengths[rex & REX_W ? QUAD : LONG];
+		    get_value_inc(imm64, loc, len, FALSE);
+		    db_printf("$%#lr", imm64);
+		    break;
+
 		case O:
 		    len = (short_addr ? 2 : 4);
 		    get_value_inc(displ, loc, len, FALSE);
Index: db_trace.c
===================================================================
RCS file: /home/cvs/src/sys/amd64/amd64/db_trace.c,v
retrieving revision 1.2
retrieving revision 1.3
diff -L sys/amd64/amd64/db_trace.c -L sys/amd64/amd64/db_trace.c -u -r1.2 -r1.3
--- sys/amd64/amd64/db_trace.c
+++ sys/amd64/amd64/db_trace.c
@@ -25,7 +25,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/amd64/amd64/db_trace.c,v 1.66.2.2 2006/03/13 03:03:51 jeff Exp $");
+__FBSDID("$FreeBSD: src/sys/amd64/amd64/db_trace.c,v 1.80.2.1 2007/11/21 16:38:54 jhb Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -91,6 +91,7 @@
 	{ "r15",	DB_OFFSET(tf_r15),	db_frame },
 	{ "rip",	DB_OFFSET(tf_rip),	db_frame },
 	{ "rflags",	DB_OFFSET(tf_rflags),	db_frame },
+#define	DB_N_SHOW_REGS	20	/* Don't show registers after here. */
 	{ "dr0",	NULL,			db_dr0 },
 	{ "dr1",	NULL,			db_dr1 },
 	{ "dr2",	NULL,			db_dr2 },
@@ -100,7 +101,7 @@
 	{ "dr6",	NULL,			db_dr6 },
 	{ "dr7",	NULL,			db_dr7 },
 };
-struct db_variable *db_eregs = db_regs + sizeof(db_regs)/sizeof(db_regs[0]);
+struct db_variable *db_eregs = db_regs + DB_N_SHOW_REGS;
 
 #define DB_DRX_FUNC(reg)		\
 static int				\
@@ -192,19 +193,17 @@
 #define	TRAP		1
 #define	INTERRUPT	2
 #define	SYSCALL		3
+#define	TRAP_INTERRUPT	5
 
 static void db_nextframe(struct amd64_frame **, db_addr_t *, struct thread *);
 static int db_numargs(struct amd64_frame *);
 static void db_print_stack_entry(const char *, int, char **, long *, db_addr_t);
 static void decode_syscall(int, struct thread *);
 
-static char * watchtype_str(int type);
-int  amd64_set_watch(int watchnum, unsigned int watchaddr, int size, int access,
-		    struct dbreg * d);
-int  amd64_clr_watch(int watchnum, struct dbreg * d);
-int  db_md_set_watchpoint(db_expr_t addr, db_expr_t size);
-int  db_md_clr_watchpoint(db_expr_t addr, db_expr_t size);
-void db_md_list_watchpoints(void);
+static const char * watchtype_str(int type);
+int  amd64_set_watch(int watchnum, unsigned long watchaddr, int size,
+		    int access, struct dbreg *d);
+int  amd64_clr_watch(int watchnum, struct dbreg *d);
 
 /*
  * Figure out how many arguments were passed into the frame at "fp".
@@ -318,14 +317,24 @@
 	if (name != NULL) {
 		if (strcmp(name, "calltrap") == 0 ||
 		    strcmp(name, "fork_trampoline") == 0 ||
-		    strcmp(name, "nmi_calltrap") == 0)
+		    strcmp(name, "nmi_calltrap") == 0 ||
+		    strcmp(name, "Xdblfault") == 0)
 			frame_type = TRAP;
 		else if (strncmp(name, "Xatpic_intr", 11) == 0 ||
-		    strncmp(name, "Xatpic_fastintr", 15) == 0 ||
-		    strncmp(name, "Xapic_isr", 9) == 0)
+		    strncmp(name, "Xapic_isr", 9) == 0 ||
+		    strcmp(name, "Xtimerint") == 0 ||
+		    strcmp(name, "Xipi_intr_bitmap_handler") == 0 ||
+		    strcmp(name, "Xcpustop") == 0 ||
+		    strcmp(name, "Xrendezvous") == 0)
 			frame_type = INTERRUPT;
 		else if (strcmp(name, "Xfast_syscall") == 0)
 			frame_type = SYSCALL;
+		/* XXX: These are interrupts with trap frames. */
+		else if (strcmp(name, "Xtimerint") == 0 ||
+		    strcmp(name, "Xcpustop") == 0 ||
+		    strcmp(name, "Xrendezvous") == 0 ||
+		    strcmp(name, "Xipi_intr_bitmap_handler") == 0)
+			frame_type = TRAP_INTERRUPT;
 	}
 
 	/*
@@ -357,6 +366,7 @@
 			db_printf("--- syscall");
 			decode_syscall(tf->tf_rax, td);
 			break;
+		case TRAP_INTERRUPT:
 		case INTERRUPT:
 			db_printf("--- interrupt");
 			break;
@@ -382,16 +392,14 @@
 	long *argp;
 	db_expr_t offset;
 	c_db_sym_t sym;
-	int narg, quit;
+	int narg;
 	boolean_t first;
 
 	if (count == -1)
 		count = 1024;
 
 	first = TRUE;
-	quit = 0;
-	db_setup_paging(db_simple_pager, &quit, db_lines_per_page);
-	while (count-- && !quit) {
+	while (count-- && !db_pager_quit) {
 		sym = db_search_symbol(pc, DB_STGY_ANY, &offset);
 		db_symbol_values(sym, &name, NULL);
 
@@ -526,24 +534,23 @@
 int
 amd64_set_watch(watchnum, watchaddr, size, access, d)
 	int watchnum;
-	unsigned int watchaddr;
+	unsigned long watchaddr;
 	int size;
 	int access;
-	struct dbreg * d;
+	struct dbreg *d;
 {
-	int i;
-	unsigned int mask;
-	
+	int i, len;
+
 	if (watchnum == -1) {
-		for (i = 0, mask = 0x3; i < 4; i++, mask <<= 2)
-			if ((d->dr[7] & mask) == 0)
+		for (i = 0; i < 4; i++)
+			if (!DBREG_DR7_ENABLED(d->dr[7], i))
 				break;
 		if (i < 4)
 			watchnum = i;
 		else
 			return (-1);
 	}
-	
+
 	switch (access) {
 	case DBREG_DR7_EXEC:
 		size = 1; /* size must be 1 for an execution breakpoint */
@@ -551,29 +558,39 @@
 	case DBREG_DR7_WRONLY:
 	case DBREG_DR7_RDWR:
 		break;
-	default : return (-1);
+	default:
+		return (-1);
 	}
-	
+
 	/*
-	 * we can watch a 1, 2, or 4 byte sized location
+	 * we can watch a 1, 2, 4, or 8 byte sized location
 	 */
 	switch (size) {
-	case 1	: mask = 0x00; break;
-	case 2	: mask = 0x01 << 2; break;
-	case 4	: mask = 0x03 << 2; break;
-	default : return (-1);
+	case 1:
+		len = DBREG_DR7_LEN_1;
+		break;
+	case 2:
+		len = DBREG_DR7_LEN_2;
+		break;
+	case 4:
+		len = DBREG_DR7_LEN_4;
+		break;
+	case 8:
+		len = DBREG_DR7_LEN_8;
+		break;
+	default:
+		return (-1);
 	}
 
-	mask |= access;
-
 	/* clear the bits we are about to affect */
-	d->dr[7] &= ~((0x3 << (watchnum*2)) | (0x0f << (watchnum*4+16)));
+	d->dr[7] &= ~DBREG_DR7_MASK(watchnum);
 
 	/* set drN register to the address, N=watchnum */
-	DBREG_DRX(d,watchnum) = watchaddr;
+	DBREG_DRX(d, watchnum) = watchaddr;
 
 	/* enable the watchpoint */
-	d->dr[7] |= (0x2 << (watchnum*2)) | (mask << (watchnum*4+16));
+	d->dr[7] |= DBREG_DR7_SET(watchnum, len, access,
+	    DBREG_DR7_GLOBAL_ENABLE);
 
 	return (watchnum);
 }
@@ -582,15 +599,15 @@
 int
 amd64_clr_watch(watchnum, d)
 	int watchnum;
-	struct dbreg * d;
+	struct dbreg *d;
 {
 
 	if (watchnum < 0 || watchnum >= 4)
 		return (-1);
-	
-	d->dr[7] = d->dr[7] & ~((0x3 << (watchnum*2)) | (0x0f << (watchnum*4+16)));
-	DBREG_DRX(d,watchnum) = 0;
-	
+
+	d->dr[7] &= ~DBREG_DR7_MASK(watchnum);
+	DBREG_DRX(d, watchnum) = 0;
+
 	return (0);
 }
 
@@ -600,38 +617,38 @@
 	db_expr_t addr;
 	db_expr_t size;
 {
-	int avail, wsize;
-	int i;
 	struct dbreg d;
-	
+	int avail, i, wsize;
+
 	fill_dbregs(NULL, &d);
-	
+
 	avail = 0;
-	for(i=0; i<4; i++) {
-		if ((d.dr[7] & (3 << (i*2))) == 0)
+	for(i = 0; i < 4; i++) {
+		if (!DBREG_DR7_ENABLED(d.dr[7], i))
 			avail++;
 	}
-	
-	if (avail*4 < size)
+
+	if (avail * 8 < size)
 		return (-1);
-	
-	for (i=0; i<4 && (size != 0); i++) {
-		if ((d.dr[7] & (3<<(i*2))) == 0) {
-			if (size > 4)
+
+	for (i = 0; i < 4 && (size > 0); i++) {
+		if (!DBREG_DR7_ENABLED(d.dr[7], i)) {
+			if (size >= 8 || (avail == 1 && size > 4))
+				wsize = 8;
+			else if (size > 2)
 				wsize = 4;
 			else
 				wsize = size;
-			if (wsize == 3)
-				wsize++;
-			amd64_set_watch(i, addr, wsize, 
+			amd64_set_watch(i, addr, wsize,
 				       DBREG_DR7_WRONLY, &d);
 			addr += wsize;
 			size -= wsize;
+			avail--;
 		}
 	}
-	
+
 	set_dbregs(NULL, &d);
-	
+
 	return(0);
 }
 
@@ -641,28 +658,27 @@
 	db_expr_t addr;
 	db_expr_t size;
 {
-	int i;
 	struct dbreg d;
+	int i;
 
 	fill_dbregs(NULL, &d);
 
-	for(i=0; i<4; i++) {
-		if (d.dr[7] & (3 << (i*2))) {
-			if ((DBREG_DRX((&d), i) >= addr) && 
+	for(i = 0; i < 4; i++) {
+		if (DBREG_DR7_ENABLED(d.dr[7], i)) {
+			if ((DBREG_DRX((&d), i) >= addr) &&
 			    (DBREG_DRX((&d), i) < addr+size))
 				amd64_clr_watch(i, &d);
-			
+
 		}
 	}
-	
+
 	set_dbregs(NULL, &d);
-	
+
 	return(0);
 }
 
 
-static 
-char *
+static const char *
 watchtype_str(type)
 	int type;
 {
@@ -678,30 +694,33 @@
 void
 db_md_list_watchpoints()
 {
-	int i;
 	struct dbreg d;
+	int i, len, type;
 
 	fill_dbregs(NULL, &d);
 
 	db_printf("\nhardware watchpoints:\n");
-	db_printf("  watch    status        type  len     address\n");
-	db_printf("  -----  --------  ----------  ---  ----------\n");
-	for (i=0; i<4; i++) {
-		if (d.dr[7] & (0x03 << (i*2))) {
-			unsigned type, len;
-			type = (d.dr[7] >> (16+(i*4))) & 3;
-			len =  (d.dr[7] >> (16+(i*4)+2)) & 3;
-			db_printf("  %-5d  %-8s  %10s  %3d  0x%016lx\n",
-				  i, "enabled", watchtype_str(type), 
-				  len + 1, DBREG_DRX((&d), i));
-		}
-		else {
+	db_printf("  watch    status        type  len             address\n");
+	db_printf("  -----  --------  ----------  ---  ------------------\n");
+	for (i = 0; i < 4; i++) {
+		if (DBREG_DR7_ENABLED(d.dr[7], i)) {
+			type = DBREG_DR7_ACCESS(d.dr[7], i);
+			len = DBREG_DR7_LEN(d.dr[7], i);
+			if (len == DBREG_DR7_LEN_8)
+				len = 8;
+			else
+				len++;
+			db_printf("  %-5d  %-8s  %10s  %3d  ",
+			    i, "enabled", watchtype_str(type), len);
+			db_printsym((db_addr_t)DBREG_DRX((&d), i), DB_STGY_ANY);
+			db_printf("\n");
+		} else {
 			db_printf("  %-5d  disabled\n", i);
 		}
 	}
-	
+
 	db_printf("\ndebug register values:\n");
-	for (i=0; i<8; i++) {
+	for (i = 0; i < 8; i++) {
 		db_printf("  dr%d 0x%016lx\n", i, DBREG_DRX((&d), i));
 	}
 	db_printf("\n");
Index: mp_watchdog.c
===================================================================
RCS file: /home/cvs/src/sys/amd64/amd64/mp_watchdog.c,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L sys/amd64/amd64/mp_watchdog.c -L sys/amd64/amd64/mp_watchdog.c -u -r1.1.1.1 -r1.2
--- sys/amd64/amd64/mp_watchdog.c
+++ sys/amd64/amd64/mp_watchdog.c
@@ -23,7 +23,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD: src/sys/amd64/amd64/mp_watchdog.c,v 1.4 2005/02/28 08:55:53 pjd Exp $
+ * $FreeBSD: src/sys/amd64/amd64/mp_watchdog.c,v 1.5 2007/06/04 23:56:33 jeff Exp $
  */
 
 #include "opt_mp_watchdog.h"
@@ -105,9 +105,7 @@
 	 * locks to make sure.  Then reset the timer.
 	 */
 	mtx_lock(&Giant);
-	mtx_lock_spin(&sched_lock);
 	watchdog_timer = WATCHDOG_THRESHOLD;
-	mtx_unlock_spin(&sched_lock);
 	mtx_unlock(&Giant);
 	callout_reset(&watchdog_callout, 1 * hz, watchdog_function, NULL);
 }
@@ -156,34 +154,6 @@
     sysctl_watchdog, "I", "");
 
 /*
- * A badly behaved sysctl that leaks the sched lock when written to.  Then
- * spin holding it just to make matters worse.  This can be used to test the
- * effectiveness of the watchdog by generating a fairly hard and nast hang.
- * Note that Giant is also held in the current world order when we get here.
- */
-static int
-sysctl_leak_schedlock(SYSCTL_HANDLER_ARGS)
-{
-	int error, temp;
-
-	temp = 0;
-	error = sysctl_handle_int(oidp, &temp, 0, req);
-	if (error)
-		return (error);
-
-	if (req->newptr != NULL) {
-		if (temp) {
-			printf("Leaking the sched lock...\n");
-			mtx_lock_spin(&sched_lock);
-			while (1);
-		}
-	}
-	return (0);
-}
-SYSCTL_PROC(_debug, OID_AUTO, leak_schedlock, CTLTYPE_INT|CTLFLAG_RW, 0, 0,
-    sysctl_leak_schedlock, "IU", "");
-
-/*
  * Drop into the debugger by sending an IPI NMI to the boot processor.
  */
 static void
Index: mp_machdep.c
===================================================================
RCS file: /home/cvs/src/sys/amd64/amd64/mp_machdep.c,v
retrieving revision 1.2
retrieving revision 1.3
diff -L sys/amd64/amd64/mp_machdep.c -L sys/amd64/amd64/mp_machdep.c -u -r1.2 -r1.3
--- sys/amd64/amd64/mp_machdep.c
+++ sys/amd64/amd64/mp_machdep.c
@@ -25,10 +25,9 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/amd64/amd64/mp_machdep.c,v 1.260.2.5.2.1 2006/04/28 06:54:33 cperciva Exp $");
+__FBSDID("$FreeBSD: src/sys/amd64/amd64/mp_machdep.c,v 1.287.2.2 2007/11/28 23:24:06 cperciva Exp $");
 
 #include "opt_cpu.h"
-#include "opt_kdb.h"
 #include "opt_kstack_pages.h"
 #include "opt_mp_watchdog.h"
 #include "opt_sched.h"
@@ -47,6 +46,7 @@
 #include <sys/mutex.h>
 #include <sys/pcpu.h>
 #include <sys/proc.h>
+#include <sys/sched.h>
 #include <sys/smp.h>
 #include <sys/sysctl.h>
 
@@ -57,7 +57,6 @@
 #include <vm/vm_extern.h>
 
 #include <machine/apicreg.h>
-#include <machine/clock.h>
 #include <machine/md_var.h>
 #include <machine/mp_watchdog.h>
 #include <machine/pcb.h>
@@ -82,6 +81,8 @@
 int	boot_cpu_id = -1;	/* designated BSP */
 extern	int nkpt;
 
+extern  struct pcpu __pcpu[];
+
 /*
  * CPU topology map datastructures for HTT.
  */
@@ -95,6 +96,9 @@
 /* Free these after use */
 void *bootstacks[MAXCPU];
 
+/* Temporary holder for double fault stack */
+char *doublefault_stack;
+
 /* Hotwire a 0->4MB V==P mapping */
 extern pt_entry_t *KPTphys;
 
@@ -110,10 +114,30 @@
 
 extern inthand_t IDTVEC(fast_syscall), IDTVEC(fast_syscall32);
 
+#ifdef STOP_NMI
+volatile cpumask_t ipi_nmi_pending;
+
+static void	ipi_nmi_selected(u_int32_t cpus);
+#endif 
+
 /*
  * Local data and functions.
  */
 
+#ifdef STOP_NMI
+/* 
+ * Provide an alternate method of stopping other CPUs. If another CPU has
+ * disabled interrupts the conventional STOP IPI will be blocked. This 
+ * NMI-based stop should get through in that case.
+ */
+static int stop_cpus_with_nmi = 1;
+SYSCTL_INT(_debug, OID_AUTO, stop_cpus_with_nmi, CTLTYPE_INT | CTLFLAG_RW,
+    &stop_cpus_with_nmi, 0, "");
+TUNABLE_INT("debug.stop_cpus_with_nmi", &stop_cpus_with_nmi);
+#else
+#define	stop_cpus_with_nmi	0
+#endif
+
 static u_int logical_cpus;
 
 /* used to hold the AP's until we are ready to release them */
@@ -130,14 +154,15 @@
 	int	cpu_present:1;
 	int	cpu_bsp:1;
 	int	cpu_disabled:1;
-} static cpu_info[MAXCPU];
-static int cpu_apic_ids[MAXCPU];
+} static cpu_info[MAX_APIC_ID + 1];
+int cpu_apic_ids[MAXCPU];
 
 /* Holds pending bitmap based IPIs per CPU */
 static volatile u_int cpu_ipi_pending[MAXCPU];
 
 static u_int boot_address;
 
+static void	assign_cpu_ids(void);
 static void	set_interrupt_apic_ids(void);
 static int	start_all_aps(void);
 static int	start_ap(int apic_id);
@@ -146,7 +171,7 @@
 static int	hlt_logical_cpus;
 static u_int	hyperthreading_cpus;
 static cpumask_t	hyperthreading_cpus_mask;
-static int	hyperthreading_allowed;
+static int	hyperthreading_allowed = 1;
 static struct	sysctl_ctx_list logical_cpu_clist;
 static u_int	bootMP_size;
 
@@ -161,28 +186,25 @@
 mp_topology(void)
 {
 	struct cpu_group *group;
-	int logical_cpus;
 	int apic_id;
 	int groups;
 	int cpu;
 
 	/* Build the smp_topology map. */
 	/* 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)
+	if (hyperthreading_cpus <= 1)
 		return;
 	group = &mp_groups[0];
 	groups = 1;
-	for (cpu = 0, apic_id = 0; apic_id < MAXCPU; apic_id++) {
+	for (cpu = 0, apic_id = 0; apic_id <= MAX_APIC_ID; apic_id++) {
 		if (!cpu_info[apic_id].cpu_present)
 			continue;
 		/*
 		 * If the current group has members and we're not a logical
 		 * cpu, create a new group.
 		 */
-		if (group->cg_count != 0 && (apic_id % logical_cpus) == 0) {
+		if (group->cg_count != 0 &&
+		    (apic_id % hyperthreading_cpus) == 0) {
 			group++;
 			groups++;
 		}
@@ -196,11 +218,6 @@
 	smp_topology = &mp_top;
 }
 
-
-#ifdef KDB_STOP_NMI
-volatile cpumask_t ipi_nmi_pending;
-#endif 
-
 /*
  * Calculate usable address in base memory for AP trampoline code.
  */
@@ -222,9 +239,8 @@
 cpu_add(u_int apic_id, char boot_cpu)
 {
 
-	if (apic_id >= MAXCPU) {
-		printf("SMP: CPU %d exceeds maximum CPU %d, ignoring\n",
-		    apic_id, MAXCPU - 1);
+	if (apic_id > MAX_APIC_ID) {
+		panic("SMP: APIC ID %d too high", apic_id);
 		return;
 	}
 	KASSERT(cpu_info[apic_id].cpu_present == 0, ("CPU %d added twice",
@@ -237,13 +253,13 @@
 		boot_cpu_id = apic_id;
 		cpu_info[apic_id].cpu_bsp = 1;
 	}
-	mp_ncpus++;
-	if (apic_id > mp_maxid)
-		mp_maxid = apic_id;
+	if (mp_ncpus < MAXCPU) {
+		mp_ncpus++;
+		mp_maxid = mp_ncpus -1;
+	}
 	if (bootverbose)
 		printf("SMP: Added CPU %d (%s)\n", apic_id, boot_cpu ? "BSP" :
 		    "AP");
-	
 }
 
 void
@@ -262,8 +278,7 @@
 	else
 		KASSERT(mp_maxid >= mp_ncpus - 1,
 		    ("%s: counters out of sync: max %d, count %d", __func__,
-			mp_maxid, mp_ncpus));
-		
+			mp_maxid, mp_ncpus));		
 }
 
 int
@@ -318,7 +333,10 @@
 	setidt(IPI_INVLTLB, IDTVEC(invltlb), SDT_SYSIGT, SEL_KPL, 0);
 	setidt(IPI_INVLPG, IDTVEC(invlpg), SDT_SYSIGT, SEL_KPL, 0);
 	setidt(IPI_INVLRNG, IDTVEC(invlrng), SDT_SYSIGT, SEL_KPL, 0);
-	
+
+	/* Install an inter-CPU IPI for cache invalidation. */
+	setidt(IPI_INVLCACHE, IDTVEC(invlcache), SDT_SYSIGT, SEL_KPL, 0);
+
 	/* Install an inter-CPU IPI for all-CPU rendezvous */
 	setidt(IPI_RENDEZVOUS, IDTVEC(rendezvous), SDT_SYSIGT, SEL_KPL, 0);
 
@@ -338,6 +356,8 @@
 		    ("BSP's APIC ID doesn't match boot_cpu_id"));
 	cpu_apic_ids[0] = boot_cpu_id;
 
+	assign_cpu_ids();
+
 	/* Start each Application Processor */
 	start_all_aps();
 
@@ -389,6 +409,9 @@
 	}
 
 	set_interrupt_apic_ids();
+
+	/* Last, setup the cpu topology now that we have probed CPUs */
+	mp_topology();
 }
 
 
@@ -402,7 +425,7 @@
 
 	/* List CPUs */
 	printf(" cpu0 (BSP): APIC ID: %2d\n", boot_cpu_id);
-	for (i = 1, x = 0; x < MAXCPU; x++) {
+	for (i = 1, x = 0; x <= MAX_APIC_ID; x++) {
 		if (!cpu_info[x].cpu_present || cpu_info[x].cpu_bsp)
 			continue;
 		if (cpu_info[x].cpu_disabled)
@@ -432,6 +455,7 @@
 	common_tss[cpu] = common_tss[0];
 	common_tss[cpu].tss_rsp0 = 0;   /* not used until after switch */
 	common_tss[cpu].tss_iobase = sizeof(struct amd64tss);
+	common_tss[cpu].tss_ist1 = (long)&doublefault_stack[PAGE_SIZE];
 
 	gdt_segs[GPROC0_SEL].ssd_base = (long) &common_tss[cpu];
 	ssdtosyssd(&gdt_segs[GPROC0_SEL],
@@ -488,6 +512,9 @@
 	while (!aps_ready)
 		ia32_pause();
 
+	/* Initialize the PAT MSR. */
+	pmap_init_pat();
+
 	/* set up CPU registers and state */
 	cpu_setregs();
 
@@ -512,7 +539,7 @@
 	mtx_lock_spin(&ap_boot_mtx);
 
 	/* Init local apic for irq's */
-	lapic_setup();
+	lapic_setup(1);
 
 	/* Set memory range attributes for this CPU to match the BSP */
 	mem_range_AP_init();
@@ -556,25 +583,7 @@
 	while (smp_started == 0)
 		ia32_pause();
 
-	/* ok, now grab sched_lock and enter the scheduler */
-	mtx_lock_spin(&sched_lock);
-
-	/*
-	 * Correct spinlock nesting.  The idle thread context that we are
-	 * borrowing was created so that it would start out with a single
-	 * spin lock (sched_lock) held in fork_trampoline().  Since we've
-	 * explicitly acquired locks in this function, the nesting count
-	 * is now 2 rather than 1.  Since we are nested, calling
-	 * spinlock_exit() will simply adjust the counts without allowing
-	 * spin lock using code to interrupt us.
-	 */
-	spinlock_exit();
-	KASSERT(curthread->td_md.md_spinlock_count == 1, ("invalid count"));
-
-	binuptime(PCPU_PTR(switchtime));
-	PCPU_SET(switchticks, ticks);
-
-	cpu_throw(NULL, choosethread());	/* doesn't return */
+	sched_throw(NULL);
 
 	panic("scheduler returned us to %s", __func__);
 	/* NOTREACHED */
@@ -594,24 +603,69 @@
 static void
 set_interrupt_apic_ids(void)
 {
-	u_int apic_id;
+	u_int i, apic_id;
 
-	for (apic_id = 0; apic_id < MAXCPU; apic_id++) {
-		if (!cpu_info[apic_id].cpu_present)
+	for (i = 0; i < MAXCPU; i++) {
+		apic_id = cpu_apic_ids[i];
+		if (apic_id == -1)
 			continue;
 		if (cpu_info[apic_id].cpu_bsp)
 			continue;
+		if (cpu_info[apic_id].cpu_disabled)
+			continue;
 
 		/* Don't let hyperthreads service interrupts. */
 		if (hyperthreading_cpus > 1 &&
 		    apic_id % hyperthreading_cpus != 0)
 			continue;
 
-		intr_add_cpu(apic_id);
+		intr_add_cpu(i);
 	}
 }
 
 /*
+ * Assign logical CPU IDs to local APICs.
+ */
+static void
+assign_cpu_ids(void)
+{
+	u_int i;
+
+	/* Check for explicitly disabled CPUs. */
+	for (i = 0; i <= MAX_APIC_ID; i++) {
+		if (!cpu_info[i].cpu_present || cpu_info[i].cpu_bsp)
+			continue;
+
+		/* Don't use this CPU if it has been disabled by a tunable. */
+		if (resource_disabled("lapic", i)) {
+			cpu_info[i].cpu_disabled = 1;
+			continue;
+		}
+	}
+
+	/*
+	 * Assign CPU IDs to local APIC IDs and disable any CPUs
+	 * beyond MAXCPU.  CPU 0 has already been assigned to the BSP,
+	 * so we only have to assign IDs for APs.
+	 */
+	mp_ncpus = 1;
+	for (i = 0; i <= MAX_APIC_ID; i++) {
+		if (!cpu_info[i].cpu_present || cpu_info[i].cpu_bsp ||
+		    cpu_info[i].cpu_disabled)
+			continue;
+
+		if (mp_ncpus < MAXCPU) {
+			cpu_apic_ids[mp_ncpus] = i;
+			mp_ncpus++;
+		} else
+			cpu_info[i].cpu_disabled = 1;
+	}
+	KASSERT(mp_maxid >= mp_ncpus - 1,
+	    ("%s: counters out of sync: max %d, count %d", __func__, mp_maxid,
+	    mp_ncpus));		
+}
+
+/*
  * start each AP in our list
  */
 static int
@@ -662,27 +716,12 @@
 	outb(CMOS_DATA, BIOS_WARM);	/* 'warm-start' */
 
 	/* start each AP */
-	for (cpu = 0, apic_id = 0; apic_id < MAXCPU; apic_id++) {
-
-		/* Ignore non-existent CPUs and the BSP. */
-		if (!cpu_info[apic_id].cpu_present ||
-		    cpu_info[apic_id].cpu_bsp)
-			continue;
-
-		/* Don't use this CPU if it has been disabled by a tunable. */
-		if (resource_disabled("lapic", apic_id)) {
-			cpu_info[apic_id].cpu_disabled = 1;
-			mp_ncpus--;
-			continue;
-		}
-
-		cpu++;
-
-		/* save APIC ID for this logical ID */
-		cpu_apic_ids[cpu] = apic_id;
+	for (cpu = 1; cpu < mp_ncpus; cpu++) {
+		apic_id = cpu_apic_ids[cpu];
 
 		/* allocate and set up an idle stack data page */
-		bootstacks[cpu] = (char *)kmem_alloc(kernel_map, KSTACK_PAGES * PAGE_SIZE);
+		bootstacks[cpu] = (void *)kmem_alloc(kernel_map, KSTACK_PAGES * PAGE_SIZE);
+		doublefault_stack = (char *)kmem_alloc(kernel_map, PAGE_SIZE);
 
 		bootSTK = (char *)bootstacks[cpu] + KSTACK_PAGES * PAGE_SIZE - 8;
 		bootAP = cpu;
@@ -801,13 +840,16 @@
 	ncpu = mp_ncpus - 1;	/* does not shootdown self */
 	if (ncpu < 1)
 		return;		/* no other cpus */
-	mtx_assert(&smp_ipi_mtx, MA_OWNED);
+	if (!(read_rflags() & PSL_I))
+		panic("%s: interrupts disabled", __func__);
+	mtx_lock_spin(&smp_ipi_mtx);
 	smp_tlb_addr1 = addr1;
 	smp_tlb_addr2 = addr2;
 	atomic_store_rel_int(&smp_tlb_wait, 0);
 	ipi_all_but_self(vector);
 	while (smp_tlb_wait < ncpu)
 		ia32_pause();
+	mtx_unlock_spin(&smp_ipi_mtx);
 }
 
 static void
@@ -835,7 +877,9 @@
 		if (ncpu < 1)
 			return;
 	}
-	mtx_assert(&smp_ipi_mtx, MA_OWNED);
+	if (!(read_rflags() & PSL_I))
+		panic("%s: interrupts disabled", __func__);
+	mtx_lock_spin(&smp_ipi_mtx);
 	smp_tlb_addr1 = addr1;
 	smp_tlb_addr2 = addr2;
 	atomic_store_rel_int(&smp_tlb_wait, 0);
@@ -845,6 +889,15 @@
 		ipi_selected(mask, vector);
 	while (smp_tlb_wait < ncpu)
 		ia32_pause();
+	mtx_unlock_spin(&smp_ipi_mtx);
+}
+
+void
+smp_cache_flush(void)
+{
+
+	if (smp_started)
+		smp_tlb_shootdown(IPI_INVLCACHE, 0, 0);
 }
 
 void
@@ -900,29 +953,23 @@
 	}
 }
 
-
 void
-ipi_bitmap_handler(struct clockframe frame)
+ipi_bitmap_handler(struct trapframe frame)
 {
 	int cpu = PCPU_GET(cpuid);
 	u_int ipi_bitmap;
 
 	ipi_bitmap = atomic_readandclear_int(&cpu_ipi_pending[cpu]);
 
-#ifdef IPI_PREEMPTION
-	if (ipi_bitmap & IPI_PREEMPT) {
-		mtx_lock_spin(&sched_lock);
-		/* Don't preempt the idle thread */
-		if (curthread->td_priority <  PRI_MIN_IDLE) {
-			struct thread *running_thread = curthread;
-			if (running_thread->td_critnest > 1) 
-				running_thread->td_owepreempt = 1;
-			else 		
-				mi_switch(SW_INVOL | SW_PREEMPT, NULL);
-		}
-		mtx_unlock_spin(&sched_lock);
+	if (ipi_bitmap & (1 << IPI_PREEMPT)) {
+		struct thread *running_thread = curthread;
+		thread_lock(running_thread);
+		if (running_thread->td_critnest > 1) 
+			running_thread->td_owepreempt = 1;
+		else 		
+			mi_switch(SW_INVOL | SW_PREEMPT, NULL);
+		thread_unlock(running_thread);
 	}
-#endif
 
 	/* Nothing to do for AST */
 }
@@ -943,6 +990,12 @@
 		ipi = IPI_BITMAP_VECTOR;
 	}
 
+#ifdef STOP_NMI
+	if (ipi == IPI_STOP && stop_cpus_with_nmi) {
+		ipi_nmi_selected(cpus);
+		return;
+	}
+#endif
 	CTR3(KTR_SMP, "%s: cpus: %x ipi: %x", __func__, cpus, ipi);
 	while ((cpu = ffs(cpus)) != 0) {
 		cpu--;
@@ -973,6 +1026,10 @@
 ipi_all(u_int ipi)
 {
 
+	if (IPI_IS_BITMAPED(ipi) || (ipi == IPI_STOP && stop_cpus_with_nmi)) {
+		ipi_selected(all_cpus, ipi);
+		return;
+	}
 	CTR2(KTR_SMP, "%s: ipi: %x", __func__, ipi);
 	lapic_ipi_vectored(ipi, APIC_IPI_DEST_ALL);
 }
@@ -984,6 +1041,10 @@
 ipi_all_but_self(u_int ipi)
 {
 
+	if (IPI_IS_BITMAPED(ipi) || (ipi == IPI_STOP && stop_cpus_with_nmi)) {
+		ipi_selected(PCPU_GET(other_cpus), ipi);
+		return;
+	}
 	CTR2(KTR_SMP, "%s: ipi: %x", __func__, ipi);
 	lapic_ipi_vectored(ipi, APIC_IPI_DEST_OTHERS);
 }
@@ -995,11 +1056,15 @@
 ipi_self(u_int ipi)
 {
 
+	if (IPI_IS_BITMAPED(ipi) || (ipi == IPI_STOP && stop_cpus_with_nmi)) {
+		ipi_selected(PCPU_GET(cpumask), ipi);
+		return;
+	}
 	CTR2(KTR_SMP, "%s: ipi: %x", __func__, ipi);
 	lapic_ipi_vectored(ipi, APIC_IPI_DEST_SELF);
 }
 
-#ifdef KDB_STOP_NMI
+#ifdef STOP_NMI
 /*
  * send NMI IPI to selected CPUs
  */
@@ -1009,7 +1074,6 @@
 void
 ipi_nmi_selected(u_int32_t cpus)
 {
-
 	int cpu;
 	register_t icrlo;
 
@@ -1018,10 +1082,8 @@
 	
 	CTR2(KTR_SMP, "%s: cpus: %x nmi", __func__, cpus);
 
-
 	atomic_set_int(&ipi_nmi_pending, cpus);
 
-
 	while ((cpu = ffs(cpus)) != 0) {
 		cpu--;
 		cpus &= ~(1 << cpu);
@@ -1033,41 +1095,52 @@
 		if (!lapic_ipi_wait(BEFORE_SPIN))
 			panic("ipi_nmi_selected: previous IPI has not cleared");
 
-		lapic_ipi_raw(icrlo,cpu_apic_ids[cpu]);
+		lapic_ipi_raw(icrlo, cpu_apic_ids[cpu]);
 	}
 }
 
-
 int
-ipi_nmi_handler()
+ipi_nmi_handler(void)
 {
-	int cpu  = PCPU_GET(cpuid);
+	int cpumask = PCPU_GET(cpumask);
 
-	if(!(atomic_load_acq_int(&ipi_nmi_pending) & (1 << cpu)))
+	if (!(ipi_nmi_pending & cpumask))
 		return 1;
 
-	atomic_clear_int(&ipi_nmi_pending,1 << cpu);
+	atomic_clear_int(&ipi_nmi_pending, cpumask);
+	cpustop_handler();
+	return 0;
+}
+     
+#endif /* STOP_NMI */
+
+/*
+ * Handle an IPI_STOP by saving our current context and spinning until we
+ * are resumed.
+ */
+void
+cpustop_handler(void)
+{
+	int cpu = PCPU_GET(cpuid);
+	int cpumask = PCPU_GET(cpumask);
 
 	savectx(&stoppcbs[cpu]);
 
 	/* Indicate that we are stopped */
-	atomic_set_int(&stopped_cpus,1 << cpu);
-
+	atomic_set_int(&stopped_cpus, cpumask);
 
 	/* Wait for restart */
-	while(!(atomic_load_acq_int(&started_cpus) & (1 << cpu)))
+	while (!(started_cpus & cpumask))
 	    ia32_pause();
 
-	atomic_clear_int(&started_cpus,1 << cpu);
-	atomic_clear_int(&stopped_cpus,1 << cpu);
+	atomic_clear_int(&started_cpus, cpumask);
+	atomic_clear_int(&stopped_cpus, cpumask);
 
-	if(cpu == 0 && cpustop_restartfunc != NULL)
+	if (cpu == 0 && cpustop_restartfunc != NULL) {
 		cpustop_restartfunc();
-
-	return 0;
+		cpustop_restartfunc = NULL;
+	}
 }
-     
-#endif /* KDB_STOP_NMI */
 
 /*
  * This is called once the rest of the system is up and running and we're
@@ -1079,11 +1152,9 @@
 
 	if (mp_ncpus == 1) 
 		return;
-	mtx_lock_spin(&sched_lock);
 	atomic_store_rel_int(&aps_ready, 1);
 	while (smp_started == 0)
 		ia32_pause();
-	mtx_unlock_spin(&sched_lock);
 }
 SYSINIT(start_aps, SI_SUB_SMP, SI_ORDER_FIRST, release_aps, NULL);
 
Index: io_apic.c
===================================================================
RCS file: /home/cvs/src/sys/amd64/amd64/io_apic.c,v
retrieving revision 1.2
retrieving revision 1.3
diff -L sys/amd64/amd64/io_apic.c -L sys/amd64/amd64/io_apic.c -u -r1.2 -r1.3
--- sys/amd64/amd64/io_apic.c
+++ sys/amd64/amd64/io_apic.c
@@ -28,20 +28,23 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/amd64/amd64/io_apic.c,v 1.15.2.4 2006/03/07 18:33:20 jhb Exp $");
+__FBSDID("$FreeBSD: src/sys/amd64/amd64/io_apic.c,v 1.31 2007/06/05 18:57:48 jhb Exp $");
 
-#include "opt_atpic.h"
 #include "opt_isa.h"
 
 #include <sys/param.h>
 #include <sys/systm.h>
 #include <sys/bus.h>
 #include <sys/kernel.h>
-#include <sys/malloc.h>
 #include <sys/lock.h>
+#include <sys/malloc.h>
+#include <sys/module.h>
 #include <sys/mutex.h>
 #include <sys/sysctl.h>
 
+#include <dev/pci/pcireg.h>
+#include <dev/pci/pcivar.h>
+
 #include <vm/vm.h>
 #include <vm/pmap.h>
 
@@ -49,6 +52,7 @@
 #include <machine/frame.h>
 #include <machine/intr_machdep.h>
 #include <machine/apicvar.h>
+#include <machine/resource.h>
 #include <machine/segments.h>
 
 #define IOAPIC_ISA_INTS		16
@@ -61,9 +65,7 @@
 #define	IRQ_SMI			(NUM_IO_INTS + 3)
 #define	IRQ_DISABLED		(NUM_IO_INTS + 4)
 
-#define	TODO		printf("%s: not implemented!\n", __func__)
-
-static MALLOC_DEFINE(M_IOAPIC, "I/O APIC", "I/O APIC structures");
+static MALLOC_DEFINE(M_IOAPIC, "io_apic", "I/O APIC structures");
 
 /*
  * I/O APIC interrupt source driver.  Each pin is assigned an IRQ cookie
@@ -73,6 +75,10 @@
  * IRQs behave as PCI IRQs by default.  We also assume that the pin for
  * IRQ 0 is actually an ExtINT pin.  The apic enumerators override the
  * configuration of individual pins as indicated by their tables.
+ *
+ * Documentation for the I/O APIC: "82093AA I/O Advanced Programmable
+ * Interrupt Controller (IOAPIC)", May 1996, Intel Corp.
+ * ftp://download.intel.com/design/chipsets/datashts/29056601.pdf
  */
 
 struct ioapic_intsrc {
@@ -85,6 +91,7 @@
 	u_int io_edgetrigger:1;
 	u_int io_masked:1;
 	int io_bus:4;
+	uint32_t io_lowreg;
 };
 
 struct ioapic {
@@ -94,6 +101,7 @@
 	u_int io_intbase:8;		/* System Interrupt base */
 	u_int io_numintr:8;
 	volatile ioapic_t *io_addr;	/* XXX: should use bus_space */
+	vm_paddr_t io_paddr;
 	STAILQ_ENTRY(ioapic) io_next;
 	struct ioapic_intsrc io_pins[0];
 };
@@ -106,20 +114,20 @@
 static void	ioapic_disable_source(struct intsrc *isrc, int eoi);
 static void	ioapic_eoi_source(struct intsrc *isrc);
 static void	ioapic_enable_intr(struct intsrc *isrc);
+static void	ioapic_disable_intr(struct intsrc *isrc);
 static int	ioapic_vector(struct intsrc *isrc);
 static int	ioapic_source_pending(struct intsrc *isrc);
 static int	ioapic_config_intr(struct intsrc *isrc, enum intr_trigger trig,
 		    enum intr_polarity pol);
-static void	ioapic_suspend(struct intsrc *isrc);
-static void	ioapic_resume(struct intsrc *isrc);
+static void	ioapic_resume(struct pic *pic);
 static void	ioapic_assign_cpu(struct intsrc *isrc, u_int apic_id);
 static void	ioapic_program_intpin(struct ioapic_intsrc *intpin);
 
 static STAILQ_HEAD(,ioapic) ioapic_list = STAILQ_HEAD_INITIALIZER(ioapic_list);
 struct pic ioapic_template = { ioapic_enable_source, ioapic_disable_source,
 			       ioapic_eoi_source, ioapic_enable_intr,
-			       ioapic_vector, ioapic_source_pending,
-			       ioapic_suspend, ioapic_resume,
+			       ioapic_disable_intr, ioapic_vector,
+			       ioapic_source_pending, NULL, ioapic_resume,
 			       ioapic_config_intr, ioapic_assign_cpu };
 
 static int next_ioapic_base;
@@ -203,9 +211,7 @@
 
 	mtx_lock_spin(&icu_lock);
 	if (intpin->io_masked) {
-		flags = ioapic_read(io->io_addr,
-		    IOAPIC_REDTBL_LO(intpin->io_intpin));
-		flags &= ~(IOART_INTMASK);
+		flags = intpin->io_lowreg & ~IOART_INTMASK;
 		ioapic_write(io->io_addr, IOAPIC_REDTBL_LO(intpin->io_intpin),
 		    flags);
 		intpin->io_masked = 0;
@@ -222,9 +228,7 @@
 
 	mtx_lock_spin(&icu_lock);
 	if (!intpin->io_masked && !intpin->io_edgetrigger) {
-		flags = ioapic_read(io->io_addr,
-		    IOAPIC_REDTBL_LO(intpin->io_intpin));
-		flags |= IOART_INTMSET;
+		flags = intpin->io_lowreg | IOART_INTMSET;
 		ioapic_write(io->io_addr, IOAPIC_REDTBL_LO(intpin->io_intpin),
 		    flags);
 		intpin->io_masked = 1;
@@ -309,6 +313,7 @@
 
 	/* Write the values to the APIC. */
 	mtx_lock_spin(&icu_lock);
+	intpin->io_lowreg = low;
 	ioapic_write(io->io_addr, IOAPIC_REDTBL_LO(intpin->io_intpin), low);
 	value = ioapic_read(io->io_addr, IOAPIC_REDTBL_HI(intpin->io_intpin));
 	value &= ~IOART_DEST;
@@ -355,6 +360,23 @@
 	}
 }
 
+static void
+ioapic_disable_intr(struct intsrc *isrc)
+{
+	struct ioapic_intsrc *intpin = (struct ioapic_intsrc *)isrc;
+	u_int vector;
+
+	if (intpin->io_vector != 0) {
+		/* Mask this interrupt pin and free its APIC vector. */
+		vector = intpin->io_vector;
+		apic_disable_vector(vector);
+		intpin->io_masked = 1;
+		intpin->io_vector = 0;
+		ioapic_program_intpin(intpin);
+		apic_free_vector(vector, intpin->io_irq);
+	}
+}
+
 static int
 ioapic_vector(struct intsrc *isrc)
 {
@@ -417,24 +439,20 @@
 }
 
 static void
-ioapic_suspend(struct intsrc *isrc)
-{
-
-	TODO;
-}
-
-static void
-ioapic_resume(struct intsrc *isrc)
+ioapic_resume(struct pic *pic)
 {
+	struct ioapic *io = (struct ioapic *)pic;
+	int i;
 
-	ioapic_program_intpin((struct ioapic_intsrc *)isrc);
+	for (i = 0; i < io->io_numintr; i++)
+		ioapic_program_intpin(&io->io_pins[i]);
 }
 
 /*
  * Create a plain I/O APIC object.
  */
 void *
-ioapic_create(uintptr_t addr, int32_t apic_id, int intbase)
+ioapic_create(vm_paddr_t addr, int32_t apic_id, int intbase)
 {
 	struct ioapic *io;
 	struct ioapic_intsrc *intpin;
@@ -443,7 +461,7 @@
 	uint32_t value;
 
 	/* Map the register window so we can access the device. */
-	apic = (ioapic_t *)pmap_mapdev(addr, IOAPIC_MEM_REGION);
+	apic = pmap_mapdev(addr, IOAPIC_MEM_REGION);
 	mtx_lock_spin(&icu_lock);
 	value = ioapic_read(apic, IOAPIC_VER);
 	mtx_unlock_spin(&icu_lock);
@@ -474,13 +492,14 @@
 		intbase = next_ioapic_base;
 		printf("ioapic%u: Assuming intbase of %d\n", io->io_id,
 		    intbase);
-	} else if (intbase != next_ioapic_base)
+	} else if (intbase != next_ioapic_base && bootverbose)
 		printf("ioapic%u: WARNING: intbase %d != expected base %d\n",
 		    io->io_id, intbase, next_ioapic_base);
 	io->io_intbase = intbase;
 	next_ioapic_base = intbase + numintr;
 	io->io_numintr = numintr;
 	io->io_addr = apic;
+	io->io_paddr = addr;
 
 	/*
 	 * Initialize pins.  Start off with interrupts disabled.  Default
@@ -518,13 +537,6 @@
 		 * be routed to other CPUs later after they are enabled.
 		 */
 		intpin->io_cpu = PCPU_GET(apic_id);
-		if (bootverbose && intpin->io_irq != IRQ_DISABLED) {
-			printf("ioapic%u: intpin %d -> ",  io->io_id, i);
-			ioapic_print_irq(intpin);
-			printf(" (%s, %s)\n", intpin->io_edgetrigger ?
-			    "edge" : "level", intpin->io_activehi ? "high" :
-			    "low");
-		}
 		value = ioapic_read(apic, IOAPIC_REDTBL_LO(i));
 		ioapic_write(apic, IOAPIC_REDTBL_LO(i), value | IOART_INTMSET);
 	}
@@ -589,6 +601,8 @@
 		return (EINVAL);
 	if (io->io_pins[pin].io_irq >= NUM_IO_INTS)
 		return (EINVAL);
+	if (io->io_pins[pin].io_bus == bus_type)
+		return (0);
 	io->io_pins[pin].io_bus = bus_type;
 	if (bootverbose)
 		printf("ioapic%u: intpin %d bus %s\n", io->io_id, pin,
@@ -672,13 +686,17 @@
 ioapic_set_polarity(void *cookie, u_int pin, enum intr_polarity pol)
 {
 	struct ioapic *io;
+	int activehi;
 
 	io = (struct ioapic *)cookie;
 	if (pin >= io->io_numintr || pol == INTR_POLARITY_CONFORM)
 		return (EINVAL);
 	if (io->io_pins[pin].io_irq >= NUM_IO_INTS)
 		return (EINVAL);
-	io->io_pins[pin].io_activehi = (pol == INTR_POLARITY_HIGH);
+	activehi = (pol == INTR_POLARITY_HIGH);
+	if (io->io_pins[pin].io_activehi == activehi)
+		return (0);
+	io->io_pins[pin].io_activehi = activehi;
 	if (bootverbose)
 		printf("ioapic%u: intpin %d polarity: %s\n", io->io_id, pin,
 		    pol == INTR_POLARITY_HIGH ? "high" : "low");
@@ -689,13 +707,17 @@
 ioapic_set_triggermode(void *cookie, u_int pin, enum intr_trigger trigger)
 {
 	struct ioapic *io;
+	int edgetrigger;
 
 	io = (struct ioapic *)cookie;
 	if (pin >= io->io_numintr || trigger == INTR_TRIGGER_CONFORM)
 		return (EINVAL);
 	if (io->io_pins[pin].io_irq >= NUM_IO_INTS)
-		return (EINVAL);
-	io->io_pins[pin].io_edgetrigger = (trigger == INTR_TRIGGER_EDGE);
+		return (EINVAL);	
+	edgetrigger = (trigger == INTR_TRIGGER_EDGE);
+	if (io->io_pins[pin].io_edgetrigger == edgetrigger)
+		return (0);
+	io->io_pins[pin].io_edgetrigger = edgetrigger;
 	if (bootverbose)
 		printf("ioapic%u: intpin %d trigger: %s\n", io->io_id, pin,
 		    trigger == INTR_TRIGGER_EDGE ? "edge" : "level");
@@ -725,7 +747,121 @@
 	    io->io_intbase + io->io_numintr - 1);
 
 	/* Register valid pins as interrupt sources. */
+	intr_register_pic(&io->io_pic);
 	for (i = 0, pin = io->io_pins; i < io->io_numintr; i++, pin++)
 		if (pin->io_irq < NUM_IO_INTS)
 			intr_register_source(&pin->io_intsrc);
 }
+
+/* A simple new-bus driver to consume PCI I/O APIC devices. */
+static int
+ioapic_pci_probe(device_t dev)
+{
+
+	if (pci_get_class(dev) == PCIC_BASEPERIPH &&
+	    pci_get_subclass(dev) == PCIS_BASEPERIPH_PIC) {
+		switch (pci_get_progif(dev)) {
+		case PCIP_BASEPERIPH_PIC_IO_APIC:
+			device_set_desc(dev, "IO APIC");
+			break;
+		case PCIP_BASEPERIPH_PIC_IOX_APIC:
+			device_set_desc(dev, "IO(x) APIC");
+			break;
+		default:
+			return (ENXIO);
+		}
+		device_quiet(dev);
+		return (-10000);
+	}
+	return (ENXIO);
+}
+
+static int
+ioapic_pci_attach(device_t dev)
+{
+
+	return (0);
+}
+
+static device_method_t ioapic_pci_methods[] = {
+	/* Device interface */
+	DEVMETHOD(device_probe,		ioapic_pci_probe),
+	DEVMETHOD(device_attach,	ioapic_pci_attach),
+
+	{ 0, 0 }
+};
+
+DEFINE_CLASS_0(ioapic, ioapic_pci_driver, ioapic_pci_methods, 0);
+
+static devclass_t ioapic_devclass;
+DRIVER_MODULE(ioapic, pci, ioapic_pci_driver, ioapic_devclass, 0, 0);
+
+/*
+ * A new-bus driver to consume the memory resources associated with
+ * the APICs in the system.  On some systems ACPI or PnPBIOS system
+ * resource devices may already claim these resources.  To keep from
+ * breaking those devices, we attach ourself to the nexus device after
+ * legacy0 and acpi0 and ignore any allocation failures.
+ */
+static void
+apic_identify(driver_t *driver, device_t parent)
+{
+
+	/*
+	 * Add at order 12.  acpi0 is probed at order 10 and legacy0
+	 * is probed at order 11.
+	 */
+	if (lapic_paddr != 0)
+		BUS_ADD_CHILD(parent, 12, "apic", 0);
+}
+
+static int
+apic_probe(device_t dev)
+{
+
+	device_set_desc(dev, "APIC resources");
+	device_quiet(dev);
+	return (0);
+}
+
+static void
+apic_add_resource(device_t dev, int rid, vm_paddr_t base, size_t length)
+{
+	int error;
+
+	error = bus_set_resource(dev, SYS_RES_MEMORY, rid, base, length);
+	if (error)
+		panic("apic_add_resource: resource %d failed set with %d", rid,
+		    error);
+	bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, 0);
+}
+
+static int
+apic_attach(device_t dev)
+{
+	struct ioapic *io;
+	int i;
+
+	/* Reserve the local APIC. */
+	apic_add_resource(dev, 0, lapic_paddr, sizeof(lapic_t));
+	i = 1;
+	STAILQ_FOREACH(io, &ioapic_list, io_next) {
+		apic_add_resource(dev, i, io->io_paddr, IOAPIC_MEM_REGION);
+		i++;
+	}
+	return (0);
+}
+
+static device_method_t apic_methods[] = {
+	/* Device interface */
+	DEVMETHOD(device_identify,	apic_identify),
+	DEVMETHOD(device_probe,		apic_probe),
+	DEVMETHOD(device_attach,	apic_attach),
+
+	{ 0, 0 }
+};
+
+DEFINE_CLASS_0(apic, apic_driver, apic_methods, 0);
+
+static devclass_t apic_devclass;
+DRIVER_MODULE(apic, nexus, apic_driver, apic_devclass, 0, 0);
Index: cpu_switch.S
===================================================================
RCS file: /home/cvs/src/sys/amd64/amd64/cpu_switch.S,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L sys/amd64/amd64/cpu_switch.S -L sys/amd64/amd64/cpu_switch.S -u -r1.1.1.1 -r1.2
--- sys/amd64/amd64/cpu_switch.S
+++ sys/amd64/amd64/cpu_switch.S
@@ -30,13 +30,14 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD: src/sys/amd64/amd64/cpu_switch.S,v 1.151.8.2 2005/11/15 00:25:59 peter Exp $
+ * $FreeBSD: src/sys/amd64/amd64/cpu_switch.S,v 1.160 2007/08/22 05:06:14 jkoshy Exp $
  */
 
 #include <machine/asmacros.h>
 #include <machine/specialreg.h>
 
 #include "assym.s"
+#include "opt_sched.h"
 
 /*****************************************************************************/
 /* Scheduling                                                                */
@@ -50,6 +51,12 @@
 #define LK
 #endif
 
+#if defined(SCHED_ULE) && defined(SMP)
+#define	SETLK	xchgq
+#else
+#define	SETLK	movq
+#endif
+
 /*
  * cpu_throw()
  *
@@ -73,19 +80,17 @@
 	movq	TD_PCB(%rsi),%rdx		/* newtd->td_proc */
 	movq	PCB_CR3(%rdx),%rdx
 	movq	%rdx,%cr3			/* new address space */
-	/* set bit in new pm_active */
-	movq	TD_PROC(%rsi),%rdx
-	movq	P_VMSPACE(%rdx), %rdx
-	LK btsl	%eax, VM_PMAP+PM_ACTIVE(%rdx)	/* set new */
-	jmp	sw1
+	jmp	swact
+END(cpu_throw)
 
 /*
- * cpu_switch(old, new)
+ * cpu_switch(old, new, mtx)
  *
  * Save the current thread state, then select the next thread to run
  * and load its state.
  * %rdi = oldtd
  * %rsi = newtd
+ * %rdx = mtx
  */
 ENTRY(cpu_switch)
 	/* Switch to new thread.  First, save context. */
@@ -104,11 +109,12 @@
 	testl	$PCB_32BIT,PCB_FLAGS(%r8)
 	jz	1f				/* no, skip over */
 
-	/* Save segment selector numbers */
-	movl	%ds,PCB_DS(%r8)
-	movl	%es,PCB_ES(%r8)
-	movl	%fs,PCB_FS(%r8)
+	/* Save userland %gs */
 	movl	%gs,PCB_GS(%r8)
+	movq	PCB_GS32P(%r8),%rax
+	movq	(%rax),%rax
+	movq	%rax,PCB_GS32SD(%r8)
+
 1:
 	/* Test if debug registers should be saved. */
 	testl	$PCB_DBREGS,PCB_FLAGS(%r8)
@@ -138,7 +144,7 @@
 	smsw	%ax
 	orb	$CR0_TS,%al
 	lmsw	%ax
-	xorq	%rax,%rax
+	xorl	%eax,%eax
 	movq	%rax,PCPU(FPCURTHREAD)
 1:
 
@@ -146,46 +152,43 @@
 	movq	TD_PCB(%rsi),%r8
 
 	/* switch address space */
-	movq	PCB_CR3(%r8),%rdx
+	movq	PCB_CR3(%r8),%rcx
 	movq	%cr3,%rax
-	cmpq	%rdx,%rax			/* Same address space? */
-	je	sw1
-	movq	%rdx,%cr3			/* new address space */
-
+	cmpq	%rcx,%rax			/* Same address space? */
+	jne	swinact
+	SETLK	%rdx, TD_LOCK(%rdi)		/* Release the old thread */
+	jmp	sw1
+swinact:
+	movq	%rcx,%cr3			/* new address space */
 	movl	PCPU(CPUID), %eax
 	/* Release bit from old pmap->pm_active */
-	movq	TD_PROC(%rdi), %rdx		/* oldproc */
-	movq	P_VMSPACE(%rdx), %rdx
-	LK btrl	%eax, VM_PMAP+PM_ACTIVE(%rdx)	/* clear old */
-
+	movq	TD_PROC(%rdi), %rcx		/* oldproc */
+	movq	P_VMSPACE(%rcx), %rcx
+	LK btrl	%eax, VM_PMAP+PM_ACTIVE(%rcx)	/* clear old */
+	SETLK	%rdx, TD_LOCK(%rdi)		/* Release the old thread */
+swact:
 	/* Set bit in new pmap->pm_active */
 	movq	TD_PROC(%rsi),%rdx		/* newproc */
 	movq	P_VMSPACE(%rdx), %rdx
 	LK btsl	%eax, VM_PMAP+PM_ACTIVE(%rdx)	/* set new */
 
 sw1:
+#if defined(SCHED_ULE) && defined(SMP)
+	/* Wait for the new thread to become unblocked */
+	movq	$blocked_lock, %rdx
+1:
+	movq	TD_LOCK(%rsi),%rcx
+	cmpq	%rcx, %rdx
+	pause
+	je	1b
+	lfence
+#endif
 	/*
 	 * At this point, we've switched address spaces and are ready
 	 * to load up the rest of the next context.
 	 */
 	movq	TD_PCB(%rsi),%r8
 
-	testl	$PCB_32BIT,PCB_FLAGS(%r8)
-	jz	1f				/* no, skip over */
-
-	/* Restore segment selector numbers */
-	movl	PCB_DS(%r8),%ds
-	movl	PCB_ES(%r8),%es
-	movl	PCB_FS(%r8),%fs
-
-	/* Restore userland %gs while preserving kernel gsbase */
-	movl	$MSR_GSBASE,%ecx
-	rdmsr
-	movl	PCB_GS(%r8),%gs
-	wrmsr
-	jmp	2f
-1:
-
 	/* Restore userland %fs */
 	movl	$MSR_FSBASE,%ecx
 	movl	PCB_FSBASE(%r8),%eax
@@ -197,7 +200,6 @@
 	movl	PCB_GSBASE(%r8),%eax
 	movl	PCB_GSBASE+4(%r8),%edx
 	wrmsr
-2:
 
 	/* Update the TSS_RSP0 pointer for the next interrupt */
 	movq	PCPU(TSSP), %rax
@@ -206,6 +208,22 @@
 	movq	%rbx, (%rax)
 	movq	%rbx, PCPU(RSP0)
 
+	movq	%r8, PCPU(CURPCB)
+	movq	%rsi, PCPU(CURTHREAD)		/* into next thread */
+
+	testl	$PCB_32BIT,PCB_FLAGS(%r8)
+	jz	1f				/* no, skip over */
+
+	/* Restore userland %gs while preserving kernel gsbase */
+	movq	PCB_GS32P(%r8),%rax
+	movq	PCB_GS32SD(%r8),%rbx
+	movq	%rbx,(%rax)
+	movl	$MSR_GSBASE,%ecx
+	rdmsr
+	movl	PCB_GS(%r8),%gs
+	wrmsr
+
+1:
 	/* Restore context. */
 	movq	PCB_RBX(%r8),%rbx
 	movq	PCB_RSP(%r8),%rsp
@@ -217,9 +235,6 @@
 	movq	PCB_RIP(%r8),%rax
 	movq	%rax,(%rsp)
 
-	movq	%r8, PCPU(CURPCB)
-	movq	%rsi, PCPU(CURTHREAD)		/* into next thread */
-
 	/* Test if debug registers should be restored. */
 	testl	$PCB_DBREGS,PCB_FLAGS(%r8)
 	jz	1f
@@ -242,7 +257,8 @@
 	movq	%rax,%dr7
 1:
 	ret
-
+END(cpu_switch)
+	
 /*
  * savectx(pcb)
  * Update pcb, saving current processor state.
@@ -300,3 +316,4 @@
 	popfq
 
 	ret
+END(savectx)
Index: trap.c
===================================================================
RCS file: /home/cvs/src/sys/amd64/amd64/trap.c,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L sys/amd64/amd64/trap.c -L sys/amd64/amd64/trap.c -u -r1.1.1.1 -r1.2
--- sys/amd64/amd64/trap.c
+++ sys/amd64/amd64/trap.c
@@ -38,7 +38,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/amd64/amd64/trap.c,v 1.289.2.3 2005/11/28 20:03:03 jhb Exp $");
+__FBSDID("$FreeBSD: src/sys/amd64/amd64/trap.c,v 1.319.2.2 2007/12/06 14:20:25 kib Exp $");
 
 /*
  * AMD64 Trap and System call handling
@@ -75,6 +75,7 @@
 #ifdef HWPMC_HOOKS
 #include <sys/pmckern.h>
 #endif
+#include <security/audit/audit.h>
 
 #include <vm/vm.h>
 #include <vm/vm_param.h>
@@ -93,12 +94,12 @@
 #endif
 #include <machine/tss.h>
 
-extern void trap(struct trapframe frame);
-extern void syscall(struct trapframe frame);
+extern void trap(struct trapframe *frame);
+extern void syscall(struct trapframe *frame);
+void dblfault_handler(struct trapframe *frame);
 
 static int trap_pfault(struct trapframe *, int);
 static void trap_fatal(struct trapframe *, vm_offset_t);
-void dblfault_handler(void);
 
 #define MAX_TRAP_MSG		30
 static char *trap_msg[] = {
@@ -143,10 +144,11 @@
 static int panic_on_nmi = 1;
 SYSCTL_INT(_machdep, OID_AUTO, panic_on_nmi, CTLFLAG_RW,
 	&panic_on_nmi, 0, "Panic on NMI");
+static int prot_fault_translation = 0;
+SYSCTL_INT(_machdep, OID_AUTO, prot_fault_translation, CTLFLAG_RW,
+	&prot_fault_translation, 0, "Select signal to deliver on protection fault");
 
-#ifdef WITNESS
 extern char *syscallnames[];
-#endif
 
 /*
  * Exception, fault, and trap interface to the FreeBSD kernel.
@@ -156,24 +158,27 @@
  */
 
 void
-trap(frame)
-	struct trapframe frame;
+trap(struct trapframe *frame)
 {
 	struct thread *td = curthread;
 	struct proc *p = td->td_proc;
-	u_int sticks = 0;
-	int i = 0, ucode = 0, type, code;
+	int i = 0, ucode = 0, code;
+	u_int type;
+	register_t addr = 0;
+	ksiginfo_t ksi;
 
-	PCPU_LAZY_INC(cnt.v_trap);
-	type = frame.tf_trapno;
+	PCPU_INC(cnt.v_trap);
+	type = frame->tf_trapno;
 
-#ifdef KDB_STOP_NMI
-	/* Handler for NMI IPIs used for debugging */
+#ifdef SMP
+#ifdef STOP_NMI
+	/* Handler for NMI IPIs used for stopping CPUs. */
 	if (type == T_NMI) {
 	         if (ipi_nmi_handler() == 0)
 	                   goto out;
 	}
-#endif /* KDB_STOP_NMI */
+#endif /* STOP_NMI */
+#endif /* SMP */
 
 #ifdef KDB
 	if (kdb_active) {
@@ -190,12 +195,12 @@
 	 * the NMI was handled by it and we can return immediately.
 	 */
 	if (type == T_NMI && pmc_intr &&
-	    (*pmc_intr)(PCPU_GET(cpuid), (uintptr_t) frame.tf_rip,
-		TRAPF_USERMODE(&frame)))
+	    (*pmc_intr)(PCPU_GET(cpuid), (uintptr_t) frame->tf_rip,
+		TRAPF_USERMODE(frame)))
 		goto out;
 #endif
 
-	if ((frame.tf_rflags & PSL_I) == 0) {
+	if ((frame->tf_rflags & PSL_I) == 0) {
 		/*
 		 * Buggy application or kernel code has disabled
 		 * interrupts and then trapped.  Enabling interrupts
@@ -203,7 +208,7 @@
 		 * interrupts disabled until they are accidentally
 		 * enabled later.
 		 */
-		if (ISPL(frame.tf_cs) == SEL_UPL)
+		if (ISPL(frame->tf_cs) == SEL_UPL)
 			printf(
 			    "pid %ld (%s): trap %d with interrupts disabled\n",
 			    (long)curproc->p_pid, curproc->p_comm, type);
@@ -216,15 +221,15 @@
 			printf("kernel trap %d with interrupts disabled\n",
 			    type);
 			/*
-			 * We shouldn't enable interrupts while in a critical
-			 * section.
+			 * We shouldn't enable interrupts while holding a
+			 * spin lock or servicing an NMI.
 			 */
-			if (td->td_critnest == 0)
+			if (type != T_NMI && td->td_md.md_spinlock_count == 0)
 				enable_intr();
 		}
 	}
 
-	code = frame.tf_err;
+	code = frame->tf_err;
 	if (type == T_PAGEFLT) {
 		/*
 		 * If we get a page fault while in a critical section, then
@@ -233,30 +238,40 @@
 		 * do the VM lookup, so just consider it a fatal trap so the
 		 * kernel can print out a useful trap message and even get
 		 * to the debugger.
+		 *
+		 * If we get a page fault while holding a non-sleepable
+		 * lock, then it is most likely a fatal kernel page fault.
+		 * If WITNESS is enabled, then it's going to whine about
+		 * bogus LORs with various VM locks, so just skip to the
+		 * fatal trap handling directly.
 		 */
-		if (td->td_critnest != 0)
-			trap_fatal(&frame, frame.tf_addr);
+		if (td->td_critnest != 0 ||
+		    WITNESS_CHECK(WARN_SLEEPOK | WARN_GIANTOK, NULL,
+		    "Kernel page fault") != 0)
+			trap_fatal(frame, frame->tf_addr);
 	}
 
-        if (ISPL(frame.tf_cs) == SEL_UPL) {
+        if (ISPL(frame->tf_cs) == SEL_UPL) {
 		/* user trap */
 
-		sticks = td->td_sticks;
-		td->td_frame = &frame;
+		td->td_pticks = 0;
+		td->td_frame = frame;
+		addr = frame->tf_rip;
 		if (td->td_ucred != p->p_ucred) 
 			cred_update_thread(td);
 
 		switch (type) {
 		case T_PRIVINFLT:	/* privileged instruction fault */
-			ucode = type;
 			i = SIGILL;
+			ucode = ILL_PRVOPC;
 			break;
 
 		case T_BPTFLT:		/* bpt instruction fault */
 		case T_TRCTRAP:		/* trace trap */
 			enable_intr();
-			frame.tf_rflags &= ~PSL_T;
+			frame->tf_rflags &= ~PSL_T;
 			i = SIGTRAP;
+			ucode = (type == T_TRCTRAP ? TRAP_TRACE : TRAP_BRKPT);
 			break;
 
 		case T_ARITHTRAP:	/* arithmetic trap */
@@ -267,25 +282,66 @@
 			break;
 
 		case T_PROTFLT:		/* general protection fault */
+			i = SIGBUS;
+			ucode = BUS_OBJERR;
+			break;
 		case T_STKFLT:		/* stack fault */
 		case T_SEGNPFLT:	/* segment not present fault */
+			i = SIGBUS;
+			ucode = BUS_ADRERR;
+			break;
 		case T_TSSFLT:		/* invalid TSS fault */
+			i = SIGBUS;
+			ucode = BUS_OBJERR;
+			break;
 		case T_DOUBLEFLT:	/* double fault */
 		default:
-			ucode = code + BUS_SEGM_FAULT ;
 			i = SIGBUS;
+			ucode = BUS_OBJERR;
 			break;
 
 		case T_PAGEFLT:		/* page fault */
+			addr = frame->tf_addr;
+#ifdef KSE
 			if (td->td_pflags & TDP_SA)
 				thread_user_enter(td);
-			i = trap_pfault(&frame, TRUE);
+#endif
+			i = trap_pfault(frame, TRUE);
 			if (i == -1)
 				goto userout;
 			if (i == 0)
 				goto user;
 
-			ucode = T_PAGEFLT;
+			if (i == SIGSEGV)
+				ucode = SEGV_MAPERR;
+			else {
+				if (prot_fault_translation == 0) {
+					/*
+					 * Autodetect.
+					 * This check also covers the images
+					 * without the ABI-tag ELF note.
+					 */
+					if (p->p_osrel >= 700004) {
+						i = SIGSEGV;
+						ucode = SEGV_ACCERR;
+					} else {
+						i = SIGBUS;
+						ucode = BUS_PAGE_FAULT;
+					}
+				} else if (prot_fault_translation == 1) {
+					/*
+					 * Always compat mode.
+					 */
+					i = SIGBUS;
+					ucode = BUS_PAGE_FAULT;
+				} else {
+					/*
+					 * Always SIGSEGV mode.
+					 */
+					i = SIGSEGV;
+					ucode = SEGV_ACCERR;
+				}
+			}
 			break;
 
 		case T_DIVIDE:		/* integer divide fault */
@@ -305,7 +361,7 @@
 				 */
 				if (kdb_on_nmi) {
 					printf ("NMI ... going to debugger\n");
-					kdb_trap(type, 0, &frame);
+					kdb_trap(type, 0, frame);
 				}
 #endif /* KDB */
 				goto userout;
@@ -328,12 +384,14 @@
 			/* transparent fault (due to context switch "late") */
 			if (fpudna())
 				goto userout;
-			i = SIGFPE;
-			ucode = FPE_FPU_NP_TRAP;
+			printf("pid %d killed due to lack of floating point\n",
+				p->p_pid);
+			i = SIGKILL;
+			ucode = 0;
 			break;
 
 		case T_FPOPFLT:		/* FPU operand fetch fault */
-			ucode = T_FPOPFLT;
+			ucode = ILL_COPROC;
 			i = SIGILL;
 			break;
 
@@ -349,7 +407,7 @@
 		    ("kernel trap doesn't have ucred"));
 		switch (type) {
 		case T_PAGEFLT:			/* page fault */
-			(void) trap_pfault(&frame, FALSE);
+			(void) trap_pfault(frame, FALSE);
 			goto out;
 
 		case T_DNA:
@@ -382,12 +440,12 @@
 			 * selectors and pointers when the user changes
 			 * them.
 			 */
-			if (frame.tf_rip == (long)doreti_iret) {
-				frame.tf_rip = (long)doreti_iret_fault;
+			if (frame->tf_rip == (long)doreti_iret) {
+				frame->tf_rip = (long)doreti_iret_fault;
 				goto out;
 			}
 			if (PCPU_GET(curpcb)->pcb_onfault != NULL) {
-				frame.tf_rip =
+				frame->tf_rip =
 				    (long)PCPU_GET(curpcb)->pcb_onfault;
 				goto out;
 			}
@@ -403,8 +461,8 @@
 			 * problem here and not every time the kernel is
 			 * entered.
 			 */
-			if (frame.tf_rflags & PSL_NT) {
-				frame.tf_rflags &= ~PSL_NT;
+			if (frame->tf_rflags & PSL_NT) {
+				frame->tf_rflags &= ~PSL_NT;
 				goto out;
 			}
 			break;
@@ -438,8 +496,7 @@
 			 * Otherwise, debugger traps "can't happen".
 			 */
 #ifdef KDB
-			/* XXX Giant */
-			if (kdb_trap(type, 0, &frame))
+			if (kdb_trap(type, 0, frame))
 				goto out;
 #endif
 			break;
@@ -456,7 +513,7 @@
 				 */
 				if (kdb_on_nmi) {
 					printf ("NMI ... going to debugger\n");
-					kdb_trap(type, 0, &frame);
+					kdb_trap(type, 0, frame);
 				}
 #endif /* KDB */
 				goto out;
@@ -466,7 +523,7 @@
 #endif /* DEV_ISA */
 		}
 
-		trap_fatal(&frame, 0);
+		trap_fatal(frame, 0);
 		goto out;
 	}
 
@@ -474,20 +531,25 @@
 	if (*p->p_sysent->sv_transtrap)
 		i = (*p->p_sysent->sv_transtrap)(i, type);
 
-	trapsignal(td, i, ucode);
+	ksiginfo_init_trap(&ksi);
+	ksi.ksi_signo = i;
+	ksi.ksi_code = ucode;
+	ksi.ksi_trapno = type;
+	ksi.ksi_addr = (void *)addr;
+	trapsignal(td, &ksi);
 
 #ifdef DEBUG
 	if (type <= MAX_TRAP_MSG) {
 		uprintf("fatal process exception: %s",
 			trap_msg[type]);
 		if ((type == T_PAGEFLT) || (type == T_PROTFLT))
-			uprintf(", fault VA = 0x%lx", frame.tf_addr);
+			uprintf(", fault VA = 0x%lx", frame->tf_addr);
 		uprintf("\n");
 	}
 #endif
 
 user:
-	userret(td, &frame, sticks);
+	userret(td, frame);
 	mtx_assert(&Giant, MA_NOTOWNED);
 userout:
 out:
@@ -501,7 +563,7 @@
 {
 	vm_offset_t va;
 	struct vmspace *vm = NULL;
-	vm_map_t map = 0;
+	vm_map_t map;
 	int rv = 0;
 	vm_prot_t ftype;
 	struct thread *td = curthread;
@@ -532,8 +594,14 @@
 		map = &vm->vm_map;
 	}
 
+	/*
+	 * PGEX_I is defined only if the execute disable bit capability is
+	 * supported and enabled.
+	 */
 	if (frame->tf_err & PGEX_W)
 		ftype = VM_PROT_WRITE;
+	else if ((frame->tf_err & PGEX_I) && pg_nx != 0)
+		ftype = VM_PROT_EXECUTE;
 	else
 		ftype = VM_PROT_READ;
 
@@ -582,7 +650,8 @@
 	struct trapframe *frame;
 	vm_offset_t eva;
 {
-	int code, type, ss;
+	int code, ss;
+	u_int type;
 	long esp;
 	struct soft_segment_descriptor softseg;
 	char *msg;
@@ -604,9 +673,10 @@
 #endif
 	if (type == T_PAGEFLT) {
 		printf("fault virtual address	= 0x%lx\n", eva);
-		printf("fault code		= %s %s, %s\n",
+		printf("fault code		= %s %s %s, %s\n",
 			code & PGEX_U ? "user" : "supervisor",
 			code & PGEX_W ? "write" : "read",
+			code & PGEX_I ? "instruction" : "data",
 			code & PGEX_P ? "protection violation" : "page not present");
 	}
 	printf("instruction pointer	= 0x%lx:0x%lx\n",
@@ -645,15 +715,9 @@
 	}
 
 #ifdef KDB
-	if (debugger_on_panic || kdb_active) {
-		register_t rflags;
-		rflags = intr_disable();
-		if (kdb_trap(type, 0, frame)) {
-			intr_restore(rflags);
+	if (debugger_on_panic || kdb_active)
+		if (kdb_trap(type, 0, frame))
 			return;
-		}
-		intr_restore(rflags);
-	}
 #endif
 	printf("trap number		= %d\n", type);
 	if (type <= MAX_TRAP_MSG)
@@ -669,9 +733,12 @@
  * for example).
  */
 void
-dblfault_handler()
+dblfault_handler(struct trapframe *frame)
 {
 	printf("\nFatal double fault\n");
+	printf("rip = 0x%lx\n", frame->tf_rip);
+	printf("rsp = 0x%lx\n", frame->tf_rsp);
+	printf("rbp = 0x%lx\n", frame->tf_rbp);
 #ifdef SMP
 	/* two separate prints in case of a trap on an unmapped page */
 	printf("cpuid = %d; ", PCPU_GET(cpuid));
@@ -686,57 +753,52 @@
  *	A system call is essentially treated as a trap.
  */
 void
-syscall(frame)
-	struct trapframe frame;
+syscall(struct trapframe *frame)
 {
 	caddr_t params;
 	struct sysent *callp;
 	struct thread *td = curthread;
 	struct proc *p = td->td_proc;
 	register_t orig_tf_rflags;
-	u_int sticks;
 	int error;
 	int narg;
 	register_t args[8];
 	register_t *argp;
 	u_int code;
 	int reg, regcnt;
+	ksiginfo_t ksi;
 
-	/*
-	 * note: PCPU_LAZY_INC() can only be used if we can afford
-	 * occassional inaccuracy in the count.
-	 */
-	PCPU_LAZY_INC(cnt.v_syscall);
+	PCPU_INC(cnt.v_syscall);
 
 #ifdef DIAGNOSTIC
-	if (ISPL(frame.tf_cs) != SEL_UPL) {
-		mtx_lock(&Giant);	/* try to stabilize the system XXX */
+	if (ISPL(frame->tf_cs) != SEL_UPL) {
 		panic("syscall");
 		/* NOT REACHED */
-		mtx_unlock(&Giant);
 	}
 #endif
 
 	reg = 0;
 	regcnt = 6;
-	sticks = td->td_sticks;
-	td->td_frame = &frame;
+	td->td_pticks = 0;
+	td->td_frame = frame;
 	if (td->td_ucred != p->p_ucred) 
 		cred_update_thread(td);
+#ifdef KSE
 	if (p->p_flag & P_SA)
 		thread_user_enter(td);
-	params = (caddr_t)frame.tf_rsp + sizeof(register_t);
-	code = frame.tf_rax;
-	orig_tf_rflags = frame.tf_rflags;
+#endif
+	params = (caddr_t)frame->tf_rsp + sizeof(register_t);
+	code = frame->tf_rax;
+	orig_tf_rflags = frame->tf_rflags;
 
 	if (p->p_sysent->sv_prepsyscall) {
 		/*
 		 * The prep code is MP aware.
 		 */
-		(*p->p_sysent->sv_prepsyscall)(&frame, (int *)args, &code, &params);
+		(*p->p_sysent->sv_prepsyscall)(frame, (int *)args, &code, &params);
 	} else {
 		if (code == SYS_syscall || code == SYS___syscall) {
-			code = frame.tf_rdi;
+			code = frame->tf_rdi;
 			reg++;
 			regcnt--;
 		}
@@ -750,7 +812,7 @@
   	else
  		callp = &p->p_sysent->sv_table[code];
 
-	narg = callp->sy_narg & SYF_ARGMASK;
+	narg = callp->sy_narg;
 
 	/*
 	 * copyin and the ktrsyscall()/ktrsysret() code is MP-aware
@@ -758,7 +820,7 @@
 	KASSERT(narg <= sizeof(args) / sizeof(args[0]),
 	    ("Too many syscall arguments!"));
 	error = 0;
-	argp = &frame.tf_rdi;
+	argp = &frame->tf_rdi;
 	argp += reg;
 	bcopy(argp, args, sizeof(args[0]) * regcnt);
 	if (narg > regcnt) {
@@ -776,27 +838,26 @@
 	CTR4(KTR_SYSC, "syscall enter thread %p pid %d proc %s code %d", td,
 	    td->td_proc->p_pid, td->td_proc->p_comm, code);
 
+	td->td_syscalls++;
+
 	if (error == 0) {
 		td->td_retval[0] = 0;
-		td->td_retval[1] = frame.tf_rdx;
+		td->td_retval[1] = frame->tf_rdx;
 
 		STOPEVENT(p, S_SCE, narg);
 
 		PTRACESTOP_SC(p, td, S_PT_SCE);
 
-		if ((callp->sy_narg & SYF_MPSAFE) == 0) {
-			mtx_lock(&Giant);
-			error = (*callp->sy_call)(td, argp);
-			mtx_unlock(&Giant);
-		} else
-			error = (*callp->sy_call)(td, argp);
+		AUDIT_SYSCALL_ENTER(code, td);
+		error = (*callp->sy_call)(td, argp);
+		AUDIT_SYSCALL_EXIT(error, td);
 	}
 
 	switch (error) {
 	case 0:
-		frame.tf_rax = td->td_retval[0];
-		frame.tf_rdx = td->td_retval[1];
-		frame.tf_rflags &= ~PSL_C;
+		frame->tf_rax = td->td_retval[0];
+		frame->tf_rdx = td->td_retval[1];
+		frame->tf_rflags &= ~PSL_C;
 		break;
 
 	case ERESTART:
@@ -806,8 +867,8 @@
 		 * (which was holding the value of %rcx) is restored for
 		 * the next iteration.
 		 */
-		frame.tf_rip -= frame.tf_err;
-		frame.tf_r10 = frame.tf_rcx;
+		frame->tf_rip -= frame->tf_err;
+		frame->tf_r10 = frame->tf_rcx;
 		td->td_pcb->pcb_flags |= PCB_FULLCTX;
 		break;
 
@@ -821,8 +882,8 @@
    			else
   				error = p->p_sysent->sv_errtbl[error];
 		}
-		frame.tf_rax = error;
-		frame.tf_rflags |= PSL_C;
+		frame->tf_rax = error;
+		frame->tf_rflags |= PSL_C;
 		break;
 	}
 
@@ -830,14 +891,31 @@
 	 * Traced syscall.
 	 */
 	if (orig_tf_rflags & PSL_T) {
-		frame.tf_rflags &= ~PSL_T;
-		trapsignal(td, SIGTRAP, 0);
+		frame->tf_rflags &= ~PSL_T;
+		ksiginfo_init_trap(&ksi);
+		ksi.ksi_signo = SIGTRAP;
+		ksi.ksi_code = TRAP_TRACE;
+		ksi.ksi_addr = (void *)frame->tf_rip;
+		trapsignal(td, &ksi);
 	}
 
 	/*
+	 * Check for misbehavior.
+	 */
+	WITNESS_WARN(WARN_PANIC, NULL, "System call %s returning",
+	    (code >= 0 && code < SYS_MAXSYSCALL) ? syscallnames[code] : "???");
+	KASSERT(td->td_critnest == 0,
+	    ("System call %s returning in a critical section",
+	    (code >= 0 && code < SYS_MAXSYSCALL) ? syscallnames[code] : "???"));
+	KASSERT(td->td_locks == 0,
+	    ("System call %s returning with %d locks held",
+	    (code >= 0 && code < SYS_MAXSYSCALL) ? syscallnames[code] : "???",
+	    td->td_locks));
+
+	/*
 	 * Handle reschedule and other end-of-syscall issues
 	 */
-	userret(td, &frame, sticks);
+	userret(td, frame);
 
 	CTR4(KTR_SYSC, "syscall exit thread %p pid %d proc %s code %d", td,
 	    td->td_proc->p_pid, td->td_proc->p_comm, code);
@@ -855,9 +933,4 @@
 	STOPEVENT(p, S_SCX, code);
 
 	PTRACESTOP_SC(p, td, S_PT_SCX);
-
-	WITNESS_WARN(WARN_PANIC, NULL, "System call %s returning",
-	    (code >= 0 && code < SYS_MAXSYSCALL) ? syscallnames[code] : "???");
-	mtx_assert(&sched_lock, MA_NOTOWNED);
-	mtx_assert(&Giant, MA_NOTOWNED);
 }
Index: apic_vector.S
===================================================================
RCS file: /home/cvs/src/sys/amd64/amd64/apic_vector.S,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L sys/amd64/amd64/apic_vector.S -L sys/amd64/amd64/apic_vector.S -u -r1.1.1.1 -r1.2
--- sys/amd64/amd64/apic_vector.S
+++ sys/amd64/amd64/apic_vector.S
@@ -28,7 +28,7 @@
  * SUCH DAMAGE.
  *
  *	from: vector.s, 386BSD 0.1 unknown origin
- * $FreeBSD: src/sys/amd64/amd64/apic_vector.S,v 1.103 2005/06/30 05:33:26 peter Exp $
+ * $FreeBSD: src/sys/amd64/amd64/apic_vector.S,v 1.110 2006/12/17 06:48:39 kmacy Exp $
  */
 
 /*
@@ -42,53 +42,6 @@
 #include "assym.s"
 
 /*
- * Macros to create and destroy a trap frame.
- */
-#define PUSH_FRAME							\
-	subq	$TF_RIP,%rsp ;	/* skip dummy tf_err and tf_trapno */	\
-	testb	$SEL_RPL_MASK,TF_CS(%rsp) ; /* come from kernel? */	\
-	jz	1f ;		/* Yes, dont swapgs again */		\
-	swapgs ;							\
-1:	movq	%rdi,TF_RDI(%rsp) ;					\
-	movq	%rsi,TF_RSI(%rsp) ;					\
-	movq	%rdx,TF_RDX(%rsp) ;					\
-	movq	%rcx,TF_RCX(%rsp) ;					\
-	movq	%r8,TF_R8(%rsp) ;					\
-	movq	%r9,TF_R9(%rsp) ;					\
-	movq	%rax,TF_RAX(%rsp) ;					\
-	movq	%rbx,TF_RBX(%rsp) ;					\
-	movq	%rbp,TF_RBP(%rsp) ;					\
-	movq	%r10,TF_R10(%rsp) ;					\
-	movq	%r11,TF_R11(%rsp) ;					\
-	movq	%r12,TF_R12(%rsp) ;					\
-	movq	%r13,TF_R13(%rsp) ;					\
-	movq	%r14,TF_R14(%rsp) ;					\
-	movq	%r15,TF_R15(%rsp)
-
-#define POP_FRAME							\
-	movq	TF_RDI(%rsp),%rdi ;					\
-	movq	TF_RSI(%rsp),%rsi ;					\
-	movq	TF_RDX(%rsp),%rdx ;					\
-	movq	TF_RCX(%rsp),%rcx ;					\
-	movq	TF_R8(%rsp),%r8 ;					\
-	movq	TF_R9(%rsp),%r9 ;					\
-	movq	TF_RAX(%rsp),%rax ;					\
-	movq	TF_RBX(%rsp),%rbx ;					\
-	movq	TF_RBP(%rsp),%rbp ;					\
-	movq	TF_R10(%rsp),%r10 ;					\
-	movq	TF_R11(%rsp),%r11 ;					\
-	movq	TF_R12(%rsp),%r12 ;					\
-	movq	TF_R13(%rsp),%r13 ;					\
-	movq	TF_R14(%rsp),%r14 ;					\
-	movq	TF_R15(%rsp),%r15 ;					\
-	testb	$SEL_RPL_MASK,TF_CS(%rsp) ; /* come from kernel? */	\
-	jz	1f ;		/* keep kernel GS.base */		\
-	cli ;								\
-	swapgs ;							\
-1:	addq	$TF_RIP,%rsp	/* skip over tf_err, tf_trapno */
-
-
-/*
  * I/O Interrupt Entry Point.  Rather than having one entry point for
  * each interrupt source, we use one entry point for each 32-bit word
  * in the ISR.  The handler determines the highest bit set in the ISR,
@@ -107,7 +60,8 @@
 	jz	2f ;							\
 	addl	$(32 * index),%eax ;					\
 1: ;									\
-	movq	%rax, %rdi ;	/* pass the IRQ */			\
+	movq	%rsp, %rsi	;                                       \
+	movl	%eax, %edi ;	/* pass the IRQ */			\
 	call	lapic_handle_intr ;					\
 	MEXITCOUNT ;							\
 	jmp	doreti ;						\
@@ -144,12 +98,8 @@
 	SUPERALIGN_TEXT
 IDTVEC(timerint)
 	PUSH_FRAME
-
-	movq	lapic, %rdx
-	movl	$0, LA_EOI(%rdx)	/* End Of Interrupt to APIC */
-
 	FAKE_MCOUNT(TF_RIP(%rsp))
-
+	movq	%rsp, %rdi
 	call	lapic_handle_timer
 	MEXITCOUNT
 	jmp	doreti
@@ -222,51 +172,43 @@
 	iretq
 
 /*
- * Forward hardclock to another CPU.  Pushes a clockframe and calls
- * forwarded_hardclock().
+ * Invalidate cache.
  */
 	.text
 	SUPERALIGN_TEXT
-IDTVEC(ipi_intr_bitmap_handler)	
-	
-	PUSH_FRAME
+IDTVEC(invlcache)
+	pushq	%rax
 
-	movq	lapic, %rdx
-	movl	$0, LA_EOI(%rdx)	/* End Of Interrupt to APIC */
-	
-	FAKE_MCOUNT(TF_RIP(%rsp))
+	wbinvd
 
-	call	ipi_bitmap_handler
-	MEXITCOUNT
-	jmp	doreti
+	movq	lapic, %rax
+	movl	$0, LA_EOI(%rax)	/* End Of Interrupt to APIC */
+
+	lock
+	incl	smp_tlb_wait
+
+	popq	%rax
+	iretq
 
 /*
- * Executed by a CPU when it receives an Xcpuast IPI from another CPU,
- *
- * The other CPU has already executed aston() or need_resched() on our
- * current process, so we simply need to ack the interrupt and return
- * via doreti to run ast().
+ * Handler for IPIs sent via the per-cpu IPI bitmap.
  */
-
 	.text
 	SUPERALIGN_TEXT
-IDTVEC(cpuast)
+IDTVEC(ipi_intr_bitmap_handler)		
 	PUSH_FRAME
 
 	movq	lapic, %rdx
 	movl	$0, LA_EOI(%rdx)	/* End Of Interrupt to APIC */
-
+	
 	FAKE_MCOUNT(TF_RIP(%rsp))
 
+	call	ipi_bitmap_handler
 	MEXITCOUNT
 	jmp	doreti
 
 /*
- * Executed by a CPU when it receives an Xcpustop IPI from another CPU,
- *
- *  - Signals its receipt.
- *  - Waits for permission to restart.
- *  - Signals its restart.
+ * Executed by a CPU when it receives an IPI_STOP from another CPU.
  */
 	.text
 	SUPERALIGN_TEXT
@@ -276,34 +218,8 @@
 	movq	lapic, %rax
 	movl	$0, LA_EOI(%rax)	/* End Of Interrupt to APIC */
 
-	movl	PCPU(CPUID), %eax
-	imull	$PCB_SIZE, %eax
-	leaq	stoppcbs(%rax), %rdi
-	call	savectx			/* Save process context */
-		
-	movl	PCPU(CPUID), %eax
-
-	lock
-	btsl	%eax, stopped_cpus	/* stopped_cpus |= (1<<id) */
-1:
-	btl	%eax, started_cpus	/* while (!(started_cpus & (1<<id))) */
-	jnc	1b
-
-	lock
-	btrl	%eax, started_cpus	/* started_cpus &= ~(1<<id) */
-	lock
-	btrl	%eax, stopped_cpus	/* stopped_cpus &= ~(1<<id) */
-
-	test	%eax, %eax
-	jnz	2f
-
-	movq	cpustop_restartfunc, %rax
-	testq	%rax, %rax
-	jz	2f
-	movq	$0, cpustop_restartfunc	/* One-shot */
+	call	cpustop_handler
 
-	call	*%rax
-2:
 	POP_FRAME
 	iretq
 
Index: elf_machdep.c
===================================================================
RCS file: /home/cvs/src/sys/amd64/amd64/elf_machdep.c,v
retrieving revision 1.1.1.2
retrieving revision 1.2
diff -L sys/amd64/amd64/elf_machdep.c -L sys/amd64/amd64/elf_machdep.c -u -r1.1.1.2 -r1.2
--- sys/amd64/amd64/elf_machdep.c
+++ sys/amd64/amd64/elf_machdep.c
@@ -24,7 +24,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/amd64/amd64/elf_machdep.c,v 1.22.8.1 2005/12/30 22:13:57 marcel Exp $");
+__FBSDID("$FreeBSD: src/sys/amd64/amd64/elf_machdep.c,v 1.26 2007/05/22 02:22:57 kan Exp $");
 
 #include <sys/param.h>
 #include <sys/kernel.h>
@@ -82,6 +82,7 @@
 						"/libexec/ld-elf.so.1",
 						&elf64_freebsd_sysvec,
 						NULL,
+						BI_CAN_EXEC_DYN,
 					  };
 
 SYSINIT(elf64, SI_SUB_EXEC, SI_ORDER_ANY,
@@ -96,6 +97,7 @@
 						"/usr/libexec/ld-elf.so.1",
 						&elf64_freebsd_sysvec,
 						NULL,
+						BI_CAN_EXEC_DYN,
 					  };
 
 SYSINIT(oelf64, SI_SUB_EXEC, SI_ORDER_ANY,
@@ -195,6 +197,7 @@
 			break;
 
 		case R_X86_64_GLOB_DAT:	/* S */
+		case R_X86_64_JMP_SLOT:	/* XXX need addend + offset */
 			addr = lookup(lf, symidx, 1);
 			if (addr == 0)
 				return -1;
Index: gdb_machdep.c
===================================================================
RCS file: /home/cvs/src/sys/amd64/amd64/gdb_machdep.c,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L sys/amd64/amd64/gdb_machdep.c -L sys/amd64/amd64/gdb_machdep.c -u -r1.1.1.1 -r1.2
--- sys/amd64/amd64/gdb_machdep.c
+++ sys/amd64/amd64/gdb_machdep.c
@@ -25,7 +25,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/amd64/amd64/gdb_machdep.c,v 1.4.2.1 2005/11/15 00:25:59 peter Exp $");
+__FBSDID("$FreeBSD: src/sys/amd64/amd64/gdb_machdep.c,v 1.6 2006/04/04 03:00:20 marcel Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -91,3 +91,27 @@
 			kdb_frame->tf_rip = *(register_t *)val;
 	}
 }
+
+int
+gdb_cpu_signal(int type, int code)
+{
+
+	switch (type & ~T_USER) {
+	case 0: return (SIGFPE);	/* Divide by zero. */
+	case 1: return (SIGTRAP);	/* Debug exception. */
+	case 3: return (SIGTRAP);	/* Breakpoint. */
+	case 4: return (SIGSEGV);	/* into instr. (overflow). */
+	case 5: return (SIGURG);	/* bound instruction. */
+	case 6: return (SIGILL);	/* Invalid opcode. */
+	case 7: return (SIGFPE);	/* Coprocessor not present. */
+	case 8: return (SIGEMT);	/* Double fault. */
+	case 9: return (SIGSEGV);	/* Coprocessor segment overrun. */
+	case 10: return (SIGTRAP);	/* Invalid TSS (also single-step). */
+	case 11: return (SIGSEGV);	/* Segment not present. */
+	case 12: return (SIGSEGV);	/* Stack exception. */
+	case 13: return (SIGSEGV);	/* General protection. */
+	case 14: return (SIGSEGV);	/* Page fault. */
+	case 16: return (SIGEMT);	/* Coprocessor error. */
+	}
+	return (SIGEMT);
+}
Index: busdma_machdep.c
===================================================================
RCS file: /home/cvs/src/sys/amd64/amd64/busdma_machdep.c,v
retrieving revision 1.2
retrieving revision 1.3
diff -L sys/amd64/amd64/busdma_machdep.c -L sys/amd64/amd64/busdma_machdep.c -u -r1.2 -r1.3
--- sys/amd64/amd64/busdma_machdep.c
+++ sys/amd64/amd64/busdma_machdep.c
@@ -25,7 +25,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/amd64/amd64/busdma_machdep.c,v 1.70.2.3 2006/03/28 06:28:37 delphij Exp $");
+__FBSDID("$FreeBSD: src/sys/amd64/amd64/busdma_machdep.c,v 1.83 2007/06/17 04:21:58 mjacob Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -48,6 +48,7 @@
 #include <machine/atomic.h>
 #include <machine/bus.h>
 #include <machine/md_var.h>
+#include <machine/specialreg.h>
 
 #define MAX_BPAGES 8192
 
@@ -219,6 +220,10 @@
 	if (boundary != 0 && boundary < maxsegsz)
 		maxsegsz = boundary;
 
+	if (maxsegsz == 0) {
+		return (EINVAL);
+	}
+
 	/* Return a NULL tag on failure */
 	*dmat = NULL;
 
@@ -492,7 +497,16 @@
 		}
 	}
 
+	/* 
+	 * XXX:
+	 * (dmat->alignment < dmat->maxsize) is just a quick hack; the exact
+	 * alignment guarantees of malloc need to be nailed down, and the
+	 * code below should be rewritten to take that into account.
+	 *
+	 * In the meantime, we'll warn the user if malloc gets it wrong.
+	 */
 	if ((dmat->maxsize <= PAGE_SIZE) &&
+	   (dmat->alignment < dmat->maxsize) &&
 	    dmat->lowaddr >= ptoa((vm_paddr_t)Maxmem)) {
 		*vaddr = malloc(dmat->maxsize, M_DEVBUF, mflags);
 	} else {
@@ -510,7 +524,12 @@
 		CTR4(KTR_BUSDMA, "%s: tag %p tag flags 0x%x error %d",
 		    __func__, dmat, dmat->flags, ENOMEM);
 		return (ENOMEM);
+	} else if ((uintptr_t)*vaddr & (dmat->alignment - 1)) {
+		printf("bus_dmamem_alloc failed to align memory properly.\n");
 	}
+	if (flags & BUS_DMA_NOCACHE)
+		pmap_change_attr((vm_offset_t)*vaddr, dmat->maxsize,
+		    PAT_UNCACHEABLE);
 	CTR4(KTR_BUSDMA, "%s: tag %p tag flags 0x%x error %d",
 	    __func__, dmat, dmat->flags, ENOMEM);
 	return (0);
@@ -529,8 +548,10 @@
 	 */
 	if (map != NULL)
 		panic("bus_dmamem_free: Invalid map freed\n");
-	if ((dmat->maxsize <= PAGE_SIZE)
-	 && dmat->lowaddr >= ptoa((vm_paddr_t)Maxmem))
+	pmap_change_attr((vm_offset_t)vaddr, dmat->maxsize, PAT_WRITE_BACK);
+	if ((dmat->maxsize <= PAGE_SIZE) &&
+	   (dmat->alignment < dmat->maxsize) &&
+	    dmat->lowaddr >= ptoa((vm_paddr_t)Maxmem))
 		free(vaddr, M_DEVBUF);
 	else {
 		contigfree(vaddr, dmat->maxsize, M_DEVBUF);
@@ -632,6 +653,8 @@
 		 * Compute the segment size, and adjust counts.
 		 */
 		sgsize = PAGE_SIZE - ((u_long)curaddr & PAGE_MASK);
+		if (sgsize > dmat->maxsegsz)
+			sgsize = dmat->maxsegsz;
 		if (buflen < sgsize)
 			sgsize = buflen;
 
@@ -703,9 +726,10 @@
 	error = _bus_dmamap_load_buffer(dmat, map, buf, buflen, NULL, flags,
 	     &lastaddr, dmat->segments, &nsegs, 1);
 
+	CTR5(KTR_BUSDMA, "%s: tag %p tag flags 0x%x error %d nsegs %d",
+	    __func__, dmat, dmat->flags, error, nsegs + 1);
+
 	if (error == EINPROGRESS) {
-		CTR4(KTR_BUSDMA, "%s: tag %p tag flags 0x%x error %d",
-		    __func__, dmat, dmat->flags, error);
 		return (error);
 	}
 
@@ -714,8 +738,13 @@
 	else
 		(*callback)(callback_arg, dmat->segments, nsegs + 1, 0);
 
-	CTR4(KTR_BUSDMA, "%s: tag %p tag flags 0x%x error 0 nsegs %d",
-	    __func__, dmat, dmat->flags, nsegs + 1);
+	/*
+	 * Return ENOMEM to the caller so that it can pass it up the stack.
+	 * This error only happens when NOWAIT is set, so deferal is disabled.
+	 */
+	if (error == ENOMEM)
+		return (error);
+
 	return (0);
 }
 
@@ -812,7 +841,7 @@
 		    bus_dmamap_callback2_t *callback, void *callback_arg,
 		    int flags)
 {
-	bus_addr_t lastaddr;
+	bus_addr_t lastaddr = 0;
 	int nsegs, error, first, i;
 	bus_size_t resid;
 	struct iovec *iov;
@@ -888,7 +917,6 @@
 		 * want to add support for invalidating
 		 * the caches on broken hardware
 		 */
-		dmat->bounce_zone->total_bounced++;
 		CTR4(KTR_BUSDMA, "%s: tag %p tag flags 0x%x op 0x%x "
 		    "performing bounce", __func__, op, dmat, dmat->flags);
 
@@ -899,6 +927,7 @@
 				      bpage->datacount);
 				bpage = STAILQ_NEXT(bpage, links);
 			}
+			dmat->bounce_zone->total_bounced++;
 		}
 
 		if (op & BUS_DMASYNC_POSTREAD) {
@@ -908,6 +937,7 @@
 				      bpage->datacount);
 				bpage = STAILQ_NEXT(bpage, links);
 			}
+			dmat->bounce_zone->total_bounced++;
 		}
 	}
 }
Index: vm_machdep.c
===================================================================
RCS file: /home/cvs/src/sys/amd64/amd64/vm_machdep.c,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L sys/amd64/amd64/vm_machdep.c -L sys/amd64/amd64/vm_machdep.c -u -r1.1.1.1 -r1.2
--- sys/amd64/amd64/vm_machdep.c
+++ sys/amd64/amd64/vm_machdep.c
@@ -41,10 +41,11 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/amd64/amd64/vm_machdep.c,v 1.248.2.1 2005/11/15 00:25:59 peter Exp $");
+__FBSDID("$FreeBSD: src/sys/amd64/amd64/vm_machdep.c,v 1.255 2007/06/04 23:57:29 jeff Exp $");
 
 #include "opt_isa.h"
 #include "opt_cpu.h"
+#include "opt_compat.h"
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -69,6 +70,7 @@
 #include <machine/cpu.h>
 #include <machine/md_var.h>
 #include <machine/pcb.h>
+#include <machine/specialreg.h>
 
 #include <vm/vm.h>
 #include <vm/vm_extern.h>
@@ -79,6 +81,12 @@
 
 #include <amd64/isa/isa.h>
 
+#ifdef COMPAT_IA32
+
+extern struct sysentvec ia32_freebsd_sysvec;
+
+#endif
+
 static void	cpu_reset_real(void);
 #ifdef SMP
 static void	cpu_reset_proxy(void);
@@ -162,7 +170,7 @@
 	 * pcb2->pcb_[fg]sbase:	cloned above
 	 */
 
-	/* Setup to release sched_lock in fork_exit(). */
+	/* Setup to release spin count in fork_exit(). */
 	td2->td_md.md_spinlock_count = 1;
 	td2->td_md.md_saved_flags = PSL_KERNEL | PSL_I;
 
@@ -296,7 +304,7 @@
 	 * pcb2->pcb_[fg]sbase: cloned above
 	 */
 
-	/* Setup to release sched_lock in fork_exit(). */
+	/* Setup to release spin count in fork_exit(). */
 	td->td_md.md_spinlock_count = 1;
 	td->td_md.md_saved_flags = PSL_KERNEL | PSL_I;
 }
@@ -320,6 +328,28 @@
 	 */
 	cpu_thread_clean(td);
 
+#ifdef COMPAT_IA32
+	if (td->td_proc->p_sysent == &ia32_freebsd_sysvec) {
+		/*
+	 	 * Set the trap frame to point at the beginning of the uts
+		 * function.
+		 */
+		td->td_frame->tf_rbp = 0;
+		td->td_frame->tf_rsp =
+		   (((uintptr_t)stack->ss_sp + stack->ss_size - 4) & ~0x0f) - 4;
+		td->td_frame->tf_rip = (uintptr_t)entry;
+
+		/*
+		 * Pass the address of the mailbox for this kse to the uts
+		 * function as a parameter on the stack.
+		 */
+		suword32((void *)(td->td_frame->tf_rsp + sizeof(int32_t)),
+		    (uint32_t)(uintptr_t)arg);
+
+		return;
+	}
+#endif
+
 	/*
 	 * Set the trap frame to point at the beginning of the uts
 	 * function.
@@ -328,7 +358,6 @@
 	td->td_frame->tf_rsp =
 	    ((register_t)stack->ss_sp + stack->ss_size) & ~0x0f;
 	td->td_frame->tf_rsp -= 8;
-	td->td_frame->tf_rbp = 0;
 	td->td_frame->tf_rip = (register_t)entry;
 
 	/*
@@ -345,6 +374,19 @@
 	if ((u_int64_t)tls_base >= VM_MAXUSER_ADDRESS)
 		return (EINVAL);
 
+#ifdef COMPAT_IA32
+	if (td->td_proc->p_sysent == &ia32_freebsd_sysvec) {
+		if (td == curthread) {
+			critical_enter();
+			td->td_pcb->pcb_gsbase = (register_t)tls_base;
+			wrmsr(MSR_KGSBASE, td->td_pcb->pcb_gsbase);
+			critical_exit();
+		} else {
+			td->td_pcb->pcb_gsbase = (register_t)tls_base;
+		}
+		return (0);
+	}
+#endif
 	if (td == curthread) {
 		critical_enter();
 		td->td_pcb->pcb_fsbase = (register_t)tls_base;
@@ -389,7 +431,9 @@
 			cpustop_restartfunc = cpu_reset_proxy;
 			cpu_reset_proxy_active = 0;
 			printf("cpu_reset: Restarting BSP\n");
-			started_cpus = (1<<0);		/* Restart CPU #0 */
+
+			/* Restart CPU #0. */
+			atomic_store_rel_int(&started_cpus, 1 << 0);
 
 			cnt = 0;
 			while (cpu_reset_proxy_active == 0 && cnt < 10000000)
@@ -413,6 +457,10 @@
 static void
 cpu_reset_real()
 {
+	struct region_descriptor null_idt;
+	int b;
+
+	disable_intr();
 
 	/*
 	 * Attempt to do a CPU reset via the keyboard controller,
@@ -421,14 +469,44 @@
 	 */
 	outb(IO_KBD + 4, 0xFE);
 	DELAY(500000);	/* wait 0.5 sec to see if that did it */
-	printf("Keyboard reset did not work, attempting CPU shutdown\n");
+
+	/*
+	 * Attempt to force a reset via the Reset Control register at
+	 * I/O port 0xcf9.  Bit 2 forces a system reset when it is
+	 * written as 1.  Bit 1 selects the type of reset to attempt:
+	 * 0 selects a "soft" reset, and 1 selects a "hard" reset.  We
+	 * try to do a "soft" reset first, and then a "hard" reset.
+	 */
+	outb(0xcf9, 0x2);
+	outb(0xcf9, 0x6);
+	DELAY(500000);  /* wait 0.5 sec to see if that did it */
+
+	/*
+	 * Attempt to force a reset via the Fast A20 and Init register
+	 * at I/O port 0x92.  Bit 1 serves as an alternate A20 gate.
+	 * Bit 0 asserts INIT# when set to 1.  We are careful to only
+	 * preserve bit 1 while setting bit 0.  We also must clear bit
+	 * 0 before setting it if it isn't already clear.
+	 */
+	b = inb(0x92);
+	if (b != 0xff) {
+		if ((b & 0x1) != 0)
+			outb(0x92, b & 0xfe);
+		outb(0x92, b | 0x1);
+		DELAY(500000);  /* wait 0.5 sec to see if that did it */
+	}
+
+	printf("No known reset method worked, attempting CPU shutdown\n");
 	DELAY(1000000);	/* wait 1 sec for printf to complete */
 
-	/* Force a shutdown by unmapping entire address space. */
-	bzero((caddr_t)PML4map, PAGE_SIZE);
+	/* Wipe the IDT. */
+	null_idt.rd_limit = 0;
+	null_idt.rd_base = 0;
+	lidt(&null_idt);
 
 	/* "good night, sweet prince .... <THUNK!>" */
-	invltlb();
+	breakpoint();
+
 	/* NOTREACHED */
 	while(1);
 }
Index: mptable.c
===================================================================
RCS file: /home/cvs/src/sys/amd64/amd64/mptable.c,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L sys/amd64/amd64/mptable.c -L sys/amd64/amd64/mptable.c -u -r1.1.1.1 -r1.2
--- sys/amd64/amd64/mptable.c
+++ sys/amd64/amd64/mptable.c
@@ -25,7 +25,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/amd64/amd64/mptable.c,v 1.236 2005/04/15 18:44:53 peter Exp $");
+__FBSDID("$FreeBSD: src/sys/amd64/amd64/mptable.c,v 1.240 2007/05/08 22:01:02 jhb Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -50,7 +50,7 @@
 /* string defined by the Intel MP Spec as identifying the MP table */
 #define	MP_SIG			0x5f504d5f	/* _MP_ */
 
-#define	NAPICID			32	/* Max number of APIC's */
+#define	MAX_LAPIC_ID		63	/* Max local APIC ID for HTT fixup */
 
 #define BIOS_BASE		(0xf0000)
 #define BIOS_SIZE		(0x10000)
@@ -136,12 +136,12 @@
 
 static mpfps_t mpfps;
 static mpcth_t mpct;
-static void *ioapics[NAPICID];
+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, "MP Table", "MP Table Items");
+static MALLOC_DEFINE(M_MPTABLE, "mptable", "MP Table Items");
 
 static enum intr_polarity conforming_polarity(u_char src_bus,
 	    u_char src_bus_irq);
@@ -152,7 +152,7 @@
 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_int id_mask);
+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,
@@ -294,7 +294,7 @@
 static int
 mptable_probe_cpus(void)
 {
-	u_int cpu_mask;
+	u_long cpu_mask;
 
 	/* Is this a pre-defined config? */
 	if (mpfps->config_type != 0) {
@@ -316,18 +316,20 @@
 static int
 mptable_setup_local(void)
 {
+	vm_paddr_t addr;
 
 	/* Is this a pre-defined config? */
 	printf("MPTable: <");
 	if (mpfps->config_type != 0) {
-		lapic_init(DEFAULT_APIC_BASE);
+		addr = DEFAULT_APIC_BASE;
 		printf("Default Configuration %d", mpfps->config_type);
 	} else {
-		lapic_init((uintptr_t)mpct->apic_address);
+		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);
 }
 
@@ -354,7 +356,7 @@
 	mptable_parse_ints();
 
 	/* Fourth, we register all the I/O APIC's. */
-	for (i = 0; i < NAPICID; i++)
+	for (i = 0; i <= MAX_APIC_ID; i++)
 		if (ioapics[i] != NULL)
 			ioapic_register(ioapics[i]);
 
@@ -412,7 +414,7 @@
 mptable_probe_cpus_handler(u_char *entry, void *arg)
 {
 	proc_entry_ptr proc;
-	u_int *cpu_mask;
+	u_long *cpu_mask;
 
 	switch (*entry) {
 	case MPCT_ENTRY_PROCESSOR:
@@ -420,8 +422,10 @@
 		if (proc->cpu_flags & PROCENTRY_FLAG_EN) {
 			lapic_create(proc->apic_id, proc->cpu_flags &
 			    PROCENTRY_FLAG_BP);
-			cpu_mask = (u_int *)arg;
-			*cpu_mask |= (1 << proc->apic_id);
+			if (proc->apic_id < MAX_LAPIC_ID) {
+				cpu_mask = (u_long *)arg;
+				*cpu_mask |= (1ul << proc->apic_id);
+			}
 		}
 		break;
 	}
@@ -508,14 +512,14 @@
 		apic = (io_apic_entry_ptr)entry;
 		if (!(apic->apic_flags & IOAPICENTRY_FLAG_EN))
 			break;
-		if (apic->apic_id >= NAPICID)
+		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(
-			(uintptr_t)apic->apic_address, apic->apic_id, -1);
+		ioapics[apic->apic_id] = ioapic_create(apic->apic_address,
+		    apic->apic_id, -1);
 		break;
 	default:
 		break;
@@ -653,7 +657,7 @@
 			return;
 		}
 	}
-	if (apic_id >= NAPICID) {
+	if (apic_id > MAX_APIC_ID) {
 		printf("MPTable: Ignoring interrupt entry for ioapic%d\n",
 		    intr->dst_apic_id);
 		return;
@@ -866,7 +870,7 @@
  * with the number of logical CPU's in the processor.
  */
 static void
-mptable_hyperthread_fixup(u_int id_mask)
+mptable_hyperthread_fixup(u_long id_mask)
 {
 	u_int i, id, logical_cpus;
 
@@ -883,7 +887,7 @@
 	 * physical processor.  If any of those ID's are
 	 * already in the table, then kill the fixup.
 	 */
-	for (id = 0; id < NAPICID; id++) {
+	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. */
@@ -898,7 +902,7 @@
 	 * Ok, the ID's checked out, so perform the fixup by
 	 * adding the logical CPUs.
 	 */
-	while ((id = ffs(id_mask)) != 0) {
+	while ((id = ffsl(id_mask)) != 0) {
 		id--;
 		for (i = id + 1; i < id + logical_cpus; i++) {
 			if (bootverbose)
Index: support.S
===================================================================
RCS file: /home/cvs/src/sys/amd64/amd64/support.S,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L sys/amd64/amd64/support.S -L sys/amd64/amd64/support.S -u -r1.1.1.1 -r1.2
--- sys/amd64/amd64/support.S
+++ sys/amd64/amd64/support.S
@@ -27,7 +27,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD: src/sys/amd64/amd64/support.S,v 1.115 2005/06/24 00:45:01 peter Exp $
+ * $FreeBSD: src/sys/amd64/amd64/support.S,v 1.128 2007/08/22 05:06:14 jkoshy Exp $
  */
 
 #include "opt_ddb.h"
@@ -59,7 +59,7 @@
 /* done */
 ENTRY(bzero)
 	movq	%rsi,%rcx
-	xorq	%rax,%rax
+	xorl	%eax,%eax
 	shrq	$3,%rcx
 	cld
 	rep
@@ -69,12 +69,13 @@
 	rep
 	stosb
 	ret
-
+END(bzero)
+	
 /* Address: %rdi */
 ENTRY(pagezero)
 	movq	$-PAGE_SIZE,%rdx
 	subq	%rdx,%rdi
-	xorq	%rax,%rax
+	xorl	%eax,%eax
 1:
 	movnti	%rax,(%rdi,%rdx)
 	movnti	%rax,8(%rdi,%rdx)
@@ -84,6 +85,7 @@
 	jne	1b
 	sfence
 	ret
+END(pagezero)
 
 ENTRY(bcmp)
 	movq	%rdx,%rcx
@@ -101,6 +103,7 @@
 	setne	%al
 	movsbl	%al,%eax
 	ret
+END(bcmp)
 
 /*
  * bcopy(src, dst, cnt)
@@ -144,7 +147,8 @@
 	movsq
 	cld
 	ret
-
+END(bcopy)
+	
 /*
  * Note: memcpy does not support overlapping copies
  */
@@ -159,6 +163,7 @@
 	rep
 	movsb
 	ret
+END(memcpy)
 
 /*
  * pagecopy(%rdi=from, %rsi=to)
@@ -185,6 +190,7 @@
 	jne	2b
 	sfence
 	ret
+END(pagecopy)
 
 /* fillw(pat, base, cnt) */  
 /*       %rdi,%rsi, %rdx */
@@ -196,6 +202,7 @@
 	rep
 	stosw
 	ret
+END(fillw)
 
 /*****************************************************************************/
 /* copyout and fubyte family                                                 */
@@ -242,7 +249,7 @@
 	cmpq	%rcx,%rax
 	ja	copyout_fault
 
-	xchgq	%rdi, %rsi
+	xchgq	%rdi,%rsi
 	/* bcopy(%rsi, %rdi, %rdx) */
 	movq	%rdx,%rcx
 
@@ -256,7 +263,7 @@
 	movsb
 
 done_copyout:
-	xorq	%rax,%rax
+	xorl	%eax,%eax
 	movq	PCPU(CURPCB),%rdx
 	movq	%rax,PCB_ONFAULT(%rdx)
 	ret
@@ -267,6 +274,7 @@
 	movq	$0,PCB_ONFAULT(%rdx)
 	movq	$EFAULT,%rax
 	ret
+END(copyout)
 
 /*
  * copyin(from_user, to_kernel, len) - MP SAFE
@@ -288,8 +296,8 @@
 	cmpq	%rcx,%rax
 	ja	copyin_fault
 
-	xchgq	%rdi, %rsi
-	movq	%rdx, %rcx
+	xchgq	%rdi,%rsi
+	movq	%rdx,%rcx
 	movb	%cl,%al
 	shrq	$3,%rcx				/* copy longword-wise */
 	cld
@@ -301,7 +309,7 @@
 	movsb
 
 done_copyin:
-	xorq	%rax,%rax
+	xorl	%eax,%eax
 	movq	PCPU(CURPCB),%rdx
 	movq	%rax,PCB_ONFAULT(%rdx)
 	ret
@@ -312,12 +320,13 @@
 	movq	$0,PCB_ONFAULT(%rdx)
 	movq	$EFAULT,%rax
 	ret
+END(copyin)
 
 /*
- * casuptr.  Compare and set user pointer.  Returns -1 or the current value.
+ * casuword32.  Compare and set user integer.  Returns -1 or the current value.
  *        dst = %rdi, old = %rsi, new = %rdx
  */
-ENTRY(casuptr)
+ENTRY(casuword32)
 	movq	PCPU(CURPCB),%rcx
 	movq	$fusufault,PCB_ONFAULT(%rcx)
 
@@ -325,11 +334,40 @@
 	cmpq	%rax,%rdi			/* verify address is valid */
 	ja	fusufault
 
-	movq	%rsi, %rax			/* old */
+	movl	%esi,%eax			/* old */
 #ifdef SMP
 	lock
 #endif
-	cmpxchgq %rdx, (%rdi)			/* new = %rdx */
+	cmpxchgl %edx,(%rdi)			/* new = %edx */
+
+	/*
+	 * The old value is in %eax.  If the store succeeded it will be the
+	 * value we expected (old) from before the store, otherwise it will
+	 * be the current value.
+	 */
+
+	movq	PCPU(CURPCB),%rcx
+	movq	$0,PCB_ONFAULT(%rcx)
+	ret
+END(casuword32)
+
+/*
+ * casuword.  Compare and set user word.  Returns -1 or the current value.
+ *        dst = %rdi, old = %rsi, new = %rdx
+ */
+ENTRY(casuword)
+	movq	PCPU(CURPCB),%rcx
+	movq	$fusufault,PCB_ONFAULT(%rcx)
+
+	movq	$VM_MAXUSER_ADDRESS-4,%rax
+	cmpq	%rax,%rdi			/* verify address is valid */
+	ja	fusufault
+
+	movq	%rsi,%rax			/* old */
+#ifdef SMP
+	lock
+#endif
+	cmpxchgq %rdx,(%rdi)			/* new = %rdx */
 
 	/*
 	 * The old value is in %eax.  If the store succeeded it will be the
@@ -341,6 +379,7 @@
 	movq	$fusufault,PCB_ONFAULT(%rcx)
 	movq	$0,PCB_ONFAULT(%rcx)
 	ret
+END(casuword)
 
 /*
  * Fetch (load) a 64-bit word, a 32-bit word, a 16-bit word, or an 8-bit
@@ -360,6 +399,8 @@
 	movq	(%rdi),%rax
 	movq	$0,PCB_ONFAULT(%rcx)
 	ret
+END(fuword64)	
+END(fuword)
 
 ENTRY(fuword32)
 	movq	PCPU(CURPCB),%rcx
@@ -372,6 +413,7 @@
 	movl	(%rdi),%eax
 	movq	$0,PCB_ONFAULT(%rcx)
 	ret
+END(fuword32)
 
 /*
  * fuswintr() and suswintr() are specialized variants of fuword16() and
@@ -384,6 +426,8 @@
 ENTRY(fuswintr)
 	movq	$-1,%rax
 	ret
+END(suswintr)
+END(fuswintr)
 
 ENTRY(fuword16)
 	movq	PCPU(CURPCB),%rcx
@@ -396,6 +440,7 @@
 	movzwl	(%rdi),%eax
 	movq	$0,PCB_ONFAULT(%rcx)
 	ret
+END(fuword16)
 
 ENTRY(fubyte)
 	movq	PCPU(CURPCB),%rcx
@@ -408,11 +453,12 @@
 	movzbl	(%rdi),%eax
 	movq	$0,PCB_ONFAULT(%rcx)
 	ret
+END(fubyte)
 
 	ALIGN_TEXT
 fusufault:
 	movq	PCPU(CURPCB),%rcx
-	xorq	%rax,%rax
+	xorl	%eax,%eax
 	movq	%rax,PCB_ONFAULT(%rcx)
 	decq	%rax
 	ret
@@ -432,10 +478,12 @@
 	ja	fusufault
 
 	movq	%rsi,(%rdi)
-	xorq	%rax,%rax
+	xorl	%eax,%eax
 	movq	PCPU(CURPCB),%rcx
 	movq	%rax,PCB_ONFAULT(%rcx)
 	ret
+END(suword64)
+END(suword)
 
 ENTRY(suword32)
 	movq	PCPU(CURPCB),%rcx
@@ -446,10 +494,11 @@
 	ja	fusufault
 
 	movl	%esi,(%rdi)
-	xorq	%rax,%rax
+	xorl	%eax,%eax
 	movq	PCPU(CURPCB),%rcx
 	movq	%rax,PCB_ONFAULT(%rcx)
 	ret
+END(suword32)
 
 ENTRY(suword16)
 	movq	PCPU(CURPCB),%rcx
@@ -460,10 +509,11 @@
 	ja	fusufault
 
 	movw	%si,(%rdi)
-	xorq	%rax,%rax
+	xorl	%eax,%eax
 	movq	PCPU(CURPCB),%rcx		/* restore trashed register */
 	movq	%rax,PCB_ONFAULT(%rcx)
 	ret
+END(suword16)
 
 ENTRY(subyte)
 	movq	PCPU(CURPCB),%rcx
@@ -473,12 +523,13 @@
 	cmpq	%rax,%rdi			/* verify address validity */
 	ja	fusufault
 
-	movl	%esi, %eax
+	movl	%esi,%eax
 	movb	%al,(%rdi)
-	xorq	%rax,%rax
+	xorl	%eax,%eax
 	movq	PCPU(CURPCB),%rcx		/* restore trashed register */
 	movq	%rax,PCB_ONFAULT(%rcx)
 	ret
+END(subyte)
 
 /*
  * copyinstr(from, to, maxlen, int *lencopied) - MP SAFE
@@ -490,9 +541,9 @@
  *	return the actual length in *lencopied.
  */
 ENTRY(copyinstr)
-	movq	%rdx, %r8			/* %r8 = maxlen */
-	movq	%rcx, %r9			/* %r9 = *len */
-	xchgq	%rdi, %rsi			/* %rdi = from, %rsi = to */
+	movq	%rdx,%r8			/* %r8 = maxlen */
+	movq	%rcx,%r9			/* %r9 = *len */
+	xchgq	%rdi,%rsi			/* %rdi = from, %rsi = to */
 	movq	PCPU(CURPCB),%rcx
 	movq	$cpystrflt,PCB_ONFAULT(%rcx)
 
@@ -522,7 +573,7 @@
 
 	/* Success -- 0 byte reached */
 	decq	%rdx
-	xorq	%rax,%rax
+	xorl	%eax,%eax
 	jmp	cpystrflt_x
 3:
 	/* rdx is zero - return ENAMETOOLONG or EFAULT */
@@ -547,16 +598,16 @@
 	movq	%r8,(%r9)
 1:
 	ret
-
+END(copyinstr)
 
 /*
  * copystr(from, to, maxlen, int *lencopied) - MP SAFE
  *         %rdi, %rsi, %rdx, %rcx
  */
 ENTRY(copystr)
-	movq	%rdx, %r8			/* %r8 = maxlen */
+	movq	%rdx,%r8			/* %r8 = maxlen */
 
-	xchgq	%rdi, %rsi
+	xchgq	%rdi,%rsi
 	incq	%rdx
 	cld
 1:
@@ -569,7 +620,7 @@
 
 	/* Success -- 0 byte reached */
 	decq	%rdx
-	xorq	%rax,%rax
+	xorl	%eax,%eax
 	jmp	6f
 4:
 	/* rdx is zero -- return ENAMETOOLONG */
@@ -577,13 +628,14 @@
 
 6:
 
-	testq	%rcx, %rcx
+	testq	%rcx,%rcx
 	jz	7f
 	/* set *lencopied and return %rax */
-	subq	%rdx, %r8
-	movq	%r8, (%rcx)
+	subq	%rdx,%r8
+	movq	%r8,(%rcx)
 7:
 	ret
+END(copystr)
 
 /*
  * Handling of special amd64 registers and descriptor tables etc
@@ -598,7 +650,7 @@
 	jmp	1f
 	nop
 1:
-	movl	$KDSEL, %eax
+	movl	$KDSEL,%eax
 	movl	%eax,%ds
 	movl	%eax,%es
 	movl	%eax,%fs	/* Beware, use wrmsr to set 64 bit base */
@@ -611,6 +663,7 @@
 	pushq	%rax
 	MEXITCOUNT
 	lretq
+END(lgdt)
 
 /*****************************************************************************/
 /* setjump, longjump                                                         */
@@ -628,6 +681,7 @@
 	movq	%rdx,56(%rdi)			/* save rip */
 	xorl	%eax,%eax			/* return(0); */
 	ret
+END(setjmp)
 
 ENTRY(longjmp)
 	movq	0(%rdi),%rbx			/* restore rbx */
@@ -642,6 +696,7 @@
 	xorl	%eax,%eax			/* return(1); */
 	incl	%eax
 	ret
+END(longjmp)
 
 /*
  * Support for BB-profiling (gcc -a).  The kernbb program will extract
Index: local_apic.c
===================================================================
RCS file: /home/cvs/src/sys/amd64/amd64/local_apic.c,v
retrieving revision 1.2
retrieving revision 1.3
diff -L sys/amd64/amd64/local_apic.c -L sys/amd64/amd64/local_apic.c -u -r1.2 -r1.3
--- sys/amd64/amd64/local_apic.c
+++ sys/amd64/amd64/local_apic.c
@@ -32,7 +32,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/amd64/amd64/local_apic.c,v 1.17.2.6 2006/03/10 19:37:30 jhb Exp $");
+__FBSDID("$FreeBSD: src/sys/amd64/amd64/local_apic.c,v 1.42.2.1 2007/11/08 20:09:15 jhb Exp $");
 
 #include "opt_hwpmc_hooks.h"
 
@@ -46,12 +46,12 @@
 #include <sys/mutex.h>
 #include <sys/pcpu.h>
 #include <sys/smp.h>
-#include <sys/proc.h>
 
 #include <vm/vm.h>
 #include <vm/pmap.h>
 
 #include <machine/apicreg.h>
+#include <machine/cpu.h>
 #include <machine/cputypes.h>
 #include <machine/frame.h>
 #include <machine/intr_machdep.h>
@@ -65,13 +65,6 @@
 #include <ddb/ddb.h>
 #endif
 
-/*
- * We can handle up to 60 APICs via our logical cluster IDs, but currently
- * the physical IDs on Intel processors up to the Pentium 4 are limited to
- * 16.
- */
-#define	MAX_APICID	16
-
 /* Sanity checks on IDT vectors. */
 CTASSERT(APIC_IO_INTS + APIC_NUM_IOINTS == APIC_TIMER_INT);
 CTASSERT(APIC_TIMER_INT < APIC_LOCAL_INTS);
@@ -114,7 +107,7 @@
 	u_long la_hard_ticks;
 	u_long la_stat_ticks;
 	u_long la_prof_ticks;
-} static lapics[MAX_APICID];
+} static lapics[MAX_APIC_ID + 1];
 
 /* XXX: should thermal be an NMI? */
 
@@ -147,16 +140,22 @@
 	APIC_TDCR_32, APIC_TDCR_64, APIC_TDCR_128
 };
 
+extern inthand_t IDTVEC(rsvd);
+
 volatile lapic_t *lapic;
+vm_paddr_t lapic_paddr;
 static u_long lapic_timer_divisor, lapic_timer_period, lapic_timer_hz;
 
 static void	lapic_enable(void);
+static void	lapic_resume(struct pic *pic);
 static void	lapic_timer_enable_intr(void);
 static void	lapic_timer_oneshot(u_int count);
 static void	lapic_timer_periodic(u_int count);
 static void	lapic_timer_set_divisor(u_int divisor);
 static uint32_t	lvt_mode(struct lapic *la, u_int pin, uint32_t value);
 
+struct pic lapic_pic = { .pic_resume = lapic_resume };
+
 static uint32_t
 lvt_mode(struct lapic *la, u_int pin, uint32_t value)
 {
@@ -202,13 +201,14 @@
  * Map the local APIC and setup necessary interrupt vectors.
  */
 void
-lapic_init(uintptr_t addr)
+lapic_init(vm_paddr_t addr)
 {
 
 	/* Map the local APIC and setup the spurious interrupt handler. */
 	KASSERT(trunc_page(addr) == addr,
 	    ("local APIC not aligned on a page boundary"));
-	lapic = (lapic_t *)pmap_mapdev(addr, sizeof(lapic_t));
+	lapic = pmap_mapdev(addr, sizeof(lapic_t));
+	lapic_paddr = addr;
 	setidt(APIC_SPURIOUS_INT, IDTVEC(spuriousint), SDT_SYSIGT, SEL_KPL, 0);
 
 	/* Perform basic initialization of the BSP's local APIC. */
@@ -217,7 +217,6 @@
 
 	/* Set BSP's per-CPU local APIC ID. */
 	PCPU_SET(apic_id, lapic_id());
-	intr_add_cpu(PCPU_GET(apic_id));
 
 	/* Local APIC timer interrupt. */
 	setidt(APIC_TIMER_INT, IDTVEC(timerint), SDT_SYSIGT, SEL_KPL, 0);
@@ -234,7 +233,7 @@
 {
 	int i;
 
-	if (apic_id >= MAX_APICID) {
+	if (apic_id > MAX_APIC_ID) {
 		printf("APIC: Ignoring local APIC with ID %d\n", apic_id);
 		if (boot_cpu)
 			panic("Can't ignore BSP");
@@ -277,7 +276,7 @@
 }
 
 void
-lapic_setup(void)
+lapic_setup(int boot)
 {
 	struct lapic *la;
 	u_int32_t maxlvt;
@@ -306,9 +305,13 @@
 
 	/* Program timer LVT and setup handler. */
 	lapic->lvt_timer = lvt_mode(la, LVT_TIMER, lapic->lvt_timer);
-	snprintf(buf, sizeof(buf), "cpu%d: timer", PCPU_GET(cpuid));
-	intrcnt_add(buf, &la->la_timer_count);
-	if (PCPU_GET(cpuid) != 0) {
+	if (boot) {
+		snprintf(buf, sizeof(buf), "cpu%d: timer", PCPU_GET(cpuid));
+		intrcnt_add(buf, &la->la_timer_count);
+	}
+
+	/* We don't setup the timer during boot on the BSP until later. */
+	if (!(boot && PCPU_GET(cpuid) == 0)) {
 		KASSERT(lapic_timer_period != 0, ("lapic%u: zero divisor",
 		    lapic_id()));
 		lapic_timer_set_divisor(lapic_timer_divisor);
@@ -318,6 +321,29 @@
 
 	/* XXX: Error and thermal LVTs */
 
+	if (strcmp(cpu_vendor, "AuthenticAMD") == 0) {
+		/*
+		 * Detect the presence of C1E capability mostly on latest
+		 * dual-cores (or future) k8 family.  This feature renders
+		 * the local APIC timer dead, so we disable it by reading
+		 * the Interrupt Pending Message register and clearing both
+		 * C1eOnCmpHalt (bit 28) and SmiOnCmpHalt (bit 27).
+		 * 
+		 * Reference:
+		 *   "BIOS and Kernel Developer's Guide for AMD NPT
+		 *    Family 0Fh Processors"
+		 *   #32559 revision 3.00
+		 */
+		if ((cpu_id & 0x00000f00) == 0x00000f00 &&
+		    (cpu_id & 0x0fff0000) >=  0x00040000) {
+			uint64_t msr;
+
+			msr = rdmsr(0xc0010055);
+			if (msr & 0x18000000)
+				wrmsr(0xc0010055, msr & ~0x18000000ULL);
+		}
+	}
+
 	intr_restore(eflags);
 }
 
@@ -398,6 +424,14 @@
 	lapic->svr = value;
 }
 
+/* Reset the local APIC on the BSP during resume. */
+static void
+lapic_resume(struct pic *pic)
+{
+
+	lapic_setup(0);
+}
+
 int
 lapic_id(void)
 {
@@ -595,22 +629,41 @@
 }
 
 void
-lapic_handle_intr(void *cookie, struct intrframe frame)
+lapic_handle_intr(int vector, struct trapframe *frame)
 {
 	struct intsrc *isrc;
-	int vec = (uintptr_t)cookie;
 
-	if (vec == -1)
+	if (vector == -1)
 		panic("Couldn't get vector from ISR!");
-	isrc = intr_lookup_source(apic_idt_to_irq(vec));
-	intr_execute_handlers(isrc, &frame);
+	isrc = intr_lookup_source(apic_idt_to_irq(vector));
+	intr_execute_handlers(isrc, frame);
 }
 
 void
-lapic_handle_timer(struct clockframe frame)
+lapic_handle_timer(struct trapframe *frame)
 {
 	struct lapic *la;
 
+	/* Send EOI first thing. */
+	lapic_eoi();
+
+#if defined(SMP) && !defined(SCHED_ULE)
+	/*
+	 * Don't do any accounting for the disabled HTT cores, since it
+	 * will provide misleading numbers for the userland.
+	 *
+	 * No locking is necessary here, since even if we loose the race
+	 * when hlt_cpus_mask changes it is not a big deal, really.
+	 *
+	 * Don't do that for ULE, since ULE doesn't consider hlt_cpus_mask
+	 * and unlike other schedulers it actually schedules threads to
+	 * those CPUs.
+	 */
+	if ((hlt_cpus_mask & (1 << PCPU_GET(cpuid))) != 0)
+		return;
+#endif
+
+	/* Look up our local APIC structure for the tick counters. */
 	la = &lapics[PCPU_GET(apic_id)];
 	(*la->la_timer_count)++;
 	critical_enter();
@@ -620,16 +673,16 @@
 	if (la->la_hard_ticks >= lapic_timer_hz) {
 		la->la_hard_ticks -= lapic_timer_hz;
 		if (PCPU_GET(cpuid) == 0)
-			hardclock(&frame);
+			hardclock(TRAPF_USERMODE(frame), TRAPF_PC(frame));
 		else
-			hardclock_process(&frame);
+			hardclock_cpu(TRAPF_USERMODE(frame));
 	}
 
 	/* Fire statclock at stathz. */
 	la->la_stat_ticks += stathz;
 	if (la->la_stat_ticks >= lapic_timer_hz) {
 		la->la_stat_ticks -= lapic_timer_hz;
-		statclock(&frame);
+		statclock(TRAPF_USERMODE(frame));
 	}
 
 	/* Fire profclock at profhz, but only when needed. */
@@ -637,7 +690,7 @@
 	if (la->la_prof_ticks >= lapic_timer_hz) {
 		la->la_prof_ticks -= lapic_timer_hz;
 		if (profprocs != 0)
-			profclock(&frame);
+			profclock(TRAPF_USERMODE(frame), TRAPF_PC(frame));
 	}
 	critical_exit();
 }
@@ -710,6 +763,65 @@
 	panic("Couldn't find an APIC vector for IRQ %u", irq);
 }
 
+/*
+ * Request 'count' free contiguous IDT vectors to be used by 'count'
+ * IRQs.  'count' must be a power of two and the vectors will be
+ * aligned on a boundary of 'align'.  If the request cannot be
+ * satisfied, 0 is returned.
+ */
+u_int
+apic_alloc_vectors(u_int *irqs, u_int count, u_int align)
+{
+	u_int first, run, vector;
+
+	KASSERT(powerof2(count), ("bad count"));
+	KASSERT(powerof2(align), ("bad align"));
+	KASSERT(align >= count, ("align < count"));
+#ifdef INVARIANTS
+	for (run = 0; run < count; run++)
+		KASSERT(irqs[run] < NUM_IO_INTS, ("Invalid IRQ %u at index %u",
+		    irqs[run], run));
+#endif
+
+	/*
+	 * Search for 'count' free vectors.  As with apic_alloc_vector(),
+	 * this just uses a simple first fit algorithm.
+	 */
+	run = 0;
+	first = 0;
+	mtx_lock_spin(&icu_lock);
+	for (vector = 0; vector < APIC_NUM_IOINTS; vector++) {
+
+		/* Vector is in use, end run. */
+		if (ioint_irqs[vector] != 0) {
+			run = 0;
+			first = 0;
+			continue;
+		}
+
+		/* Start a new run if run == 0 and vector is aligned. */
+		if (run == 0) {
+			if ((vector & (align - 1)) != 0)
+				continue;
+			first = vector;
+		}
+		run++;
+
+		/* Keep looping if the run isn't long enough yet. */
+		if (run < count)
+			continue;
+
+		/* Found a run, assign IRQs and return the first vector. */
+		for (vector = 0; vector < count; vector++)
+			ioint_irqs[first + vector] = irqs[vector];
+		mtx_unlock_spin(&icu_lock);
+		return (first + APIC_IO_INTS);
+	}
+	mtx_unlock_spin(&icu_lock);
+	printf("APIC: Couldn't find APIC vectors for %u IRQs\n", count);
+	return (0);
+}
+
 void
 apic_enable_vector(u_int vector)
 {
@@ -720,6 +832,16 @@
 	setidt(vector, ioint_handlers[vector / 32], SDT_SYSIGT, SEL_KPL, 0);
 }
 
+void
+apic_disable_vector(u_int vector)
+{
+
+	KASSERT(vector != IDT_SYSCALL, ("Attempt to overwrite syscall entry"));
+	KASSERT(ioint_handlers[vector / 32] != NULL,
+	    ("No ISR handler for vector %u", vector));
+	setidt(vector, &IDTVEC(rsvd), SDT_SYSIGT, SEL_KPL, 0);
+}
+
 /* Release an APIC vector when it's no longer in use. */
 void
 apic_free_vector(u_int vector, u_int irq)
@@ -752,18 +874,16 @@
 DB_SHOW_COMMAND(apic, db_show_apic)
 {
 	struct intsrc *isrc;
-	int quit, i, verbose;
+	int i, verbose;
 	u_int irq;
 
-	quit = 0;
 	if (strcmp(modif, "vv") == 0)
 		verbose = 2;
 	else if (strcmp(modif, "v") == 0)
 		verbose = 1;
 	else
 		verbose = 0;
-	db_setup_paging(db_simple_pager, &quit, db_lines_per_page);
-	for (i = 0; i < APIC_NUM_IOINTS + 1 && !quit; i++) {
+	for (i = 0; i < APIC_NUM_IOINTS + 1 && !db_pager_quit; i++) {
 		irq = ioint_irqs[i];
 		if (irq != 0 && irq != IRQ_SYSCALL) {
 			db_printf("vec 0x%2x -> ", i + APIC_IO_INTS);
@@ -781,6 +901,76 @@
 		}
 	}
 }
+
+static void
+dump_mask(const char *prefix, uint32_t v, int base)
+{
+	int i, first;
+
+	first = 1;
+	for (i = 0; i < 32; i++)
+		if (v & (1 << i)) {
+			if (first) {
+				db_printf("%s:", prefix);
+				first = 0;
+			}
+			db_printf(" %02x", base + i);
+		}
+	if (!first)
+		db_printf("\n");
+}
+
+/* Show info from the lapic regs for this CPU. */
+DB_SHOW_COMMAND(lapic, db_show_lapic)
+{
+	uint32_t v;
+
+	db_printf("lapic ID = %d\n", lapic_id());
+	v = lapic->version;
+	db_printf("version  = %d.%d\n", (v & APIC_VER_VERSION) >> 4,
+	    v & 0xf);
+	db_printf("max LVT  = %d\n", (v & APIC_VER_MAXLVT) >> MAXLVTSHIFT);
+	v = lapic->svr;
+	db_printf("SVR      = %02x (%s)\n", v & APIC_SVR_VECTOR,
+	    v & APIC_SVR_ENABLE ? "enabled" : "disabled");
+	db_printf("TPR      = %02x\n", lapic->tpr);
+
+#define dump_field(prefix, index)					\
+	dump_mask(__XSTRING(prefix ## index), lapic->prefix ## index,	\
+	    index * 32)
+
+	db_printf("In-service Interrupts:\n");
+	dump_field(isr, 0);
+	dump_field(isr, 1);
+	dump_field(isr, 2);
+	dump_field(isr, 3);
+	dump_field(isr, 4);
+	dump_field(isr, 5);
+	dump_field(isr, 6);
+	dump_field(isr, 7);
+
+	db_printf("TMR Interrupts:\n");
+	dump_field(tmr, 0);
+	dump_field(tmr, 1);
+	dump_field(tmr, 2);
+	dump_field(tmr, 3);
+	dump_field(tmr, 4);
+	dump_field(tmr, 5);
+	dump_field(tmr, 6);
+	dump_field(tmr, 7);
+
+	db_printf("IRR Interrupts:\n");
+	dump_field(irr, 0);
+	dump_field(irr, 1);
+	dump_field(irr, 2);
+	dump_field(irr, 3);
+	dump_field(irr, 4);
+	dump_field(irr, 5);
+	dump_field(irr, 6);
+	dump_field(irr, 7);
+
+#undef dump_field
+}
 #endif
 
 /*
@@ -817,10 +1007,6 @@
 	struct apic_enumerator *enumerator;
 	int retval, best;
 
-	/* We only support built in local APICs. */
-	if (!(cpu_feature & CPUID_APIC))
-		return;
-
 	/* Don't probe if APIC mode is disabled. */
 	if (resource_disabled("apic", 0))
 		return;
@@ -870,12 +1056,8 @@
 	if (retval != 0)
 		printf("%s: Failed to setup the local APIC: returned %d\n",
 		    best_enum->apic_name, retval);
-#ifdef SMP
-	/* Last, setup the cpu topology now that we have probed CPUs */
-	mp_topology();
-#endif
 }
-SYSINIT(apic_setup_local, SI_SUB_CPU, SI_ORDER_FIRST, apic_setup_local, NULL)
+SYSINIT(apic_setup_local, SI_SUB_CPU, SI_ORDER_SECOND, apic_setup_local, NULL)
 
 /*
  * Setup the I/O APICs.
@@ -896,9 +1078,13 @@
 	 * Finish setting up the local APIC on the BSP once we know how to
 	 * properly program the LINT pins.
 	 */
-	lapic_setup();
+	lapic_setup(1);
+	intr_register_pic(&lapic_pic);
 	if (bootverbose)
 		lapic_dump("BSP");
+
+	/* Enable the MSI "pic". */
+	msi_init();
 }
 SYSINIT(apic_setup_io, SI_SUB_INTR, SI_ORDER_SECOND, apic_setup_io, NULL)
 
--- /dev/null
+++ sys/amd64/amd64/bpf_jit_machdep.c
@@ -0,0 +1,494 @@
+/*-
+ * Copyright (c) 2002 - 2003 NetGroup, Politecnico di Torino (Italy)
+ * Copyright (c) 2005 Jung-uk Kim <jkim at 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 Politecnico di Torino nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT
+ * OWNER 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: src/sys/amd64/amd64/bpf_jit_machdep.c,v 1.4 2006/01/03 20:26:02 jkim Exp $");
+
+#include "opt_bpf.h"
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/malloc.h>
+
+#include <net/if.h>
+#include <net/bpf.h>
+#include <net/bpf_jitter.h>
+
+#include <amd64/amd64/bpf_jit_machdep.h>
+
+bpf_filter_func	bpf_jit_compile(struct bpf_insn *, u_int, int *);
+
+/*
+ * emit routine to update the jump table
+ */
+static void
+emit_length(bpf_bin_stream *stream, u_int value, u_int len)
+{
+
+	(stream->refs)[stream->bpf_pc] += len;
+	stream->cur_ip += len;
+}
+
+/*
+ * emit routine to output the actual binary code
+ */
+static void
+emit_code(bpf_bin_stream *stream, u_int value, u_int len)
+{
+
+	switch (len) {
+	case 1:
+		stream->ibuf[stream->cur_ip] = (u_char)value;
+		stream->cur_ip++;
+		break;
+
+	case 2:
+		*((u_short *)(stream->ibuf + stream->cur_ip)) = (u_short)value;
+		stream->cur_ip += 2;
+		break;
+
+	case 4:
+		*((u_int *)(stream->ibuf + stream->cur_ip)) = value;
+		stream->cur_ip += 4;
+		break;
+	}
+
+	return;
+}
+
+/*
+ * Function that does the real stuff
+ */
+bpf_filter_func
+bpf_jit_compile(struct bpf_insn *prog, u_int nins, int *mem)
+{
+	struct bpf_insn *ins;
+	u_int i, pass;
+	bpf_bin_stream stream;
+
+	/*
+	 * NOTE: do not modify the name of this variable, as it's used by
+	 * the macros to emit code.
+	 */
+	emit_func emitm;
+
+	/* Do not compile an empty filter. */
+	if (nins == 0)
+		return NULL;
+
+	/* Allocate the reference table for the jumps */
+	stream.refs = (u_int *)malloc((nins + 1) * sizeof(u_int),
+	    M_BPFJIT, M_NOWAIT);
+	if (stream.refs == NULL)
+		return NULL;
+
+	/* Reset the reference table */
+	for (i = 0; i < nins + 1; i++)
+		stream.refs[i] = 0;
+
+	stream.cur_ip = 0;
+	stream.bpf_pc = 0;
+
+	/*
+	 * the first pass will emit the lengths of the instructions
+	 * to create the reference table
+	 */
+	emitm = emit_length;
+
+	pass = 0;
+	for (;;) {
+		ins = prog;
+
+		/* create the procedure header */
+		PUSH(RBP);
+		MOVrq(RBP, RSP);
+		MOVoqd(RBP, -8, ESI);
+		MOVoqd(RBP, -12, EDX);
+		PUSH(RBX);
+		MOVrq(RBX, RDI);
+
+		for (i = 0; i < nins; i++) {
+			stream.bpf_pc++;
+
+			switch (ins->code) {
+			default:
+				return NULL;
+
+			case BPF_RET|BPF_K:
+				MOVid(EAX, ins->k);
+				POP(RBX);
+				LEAVE_RET();
+				break;
+
+			case BPF_RET|BPF_A:
+				POP(RBX);
+				LEAVE_RET();
+				break;
+
+			case BPF_LD|BPF_W|BPF_ABS:
+				MOVid(ECX, ins->k);
+				MOVrd(ESI, ECX);
+				ADDib(ECX, sizeof(int));
+				CMPodd(ECX, RBP, -12);
+				JLEb(5);
+				ZERO_EAX();
+				POP(RBX);
+				LEAVE_RET();
+				MOVobd(EAX, RBX, RSI);
+				BSWAP(EAX);
+				break;
+
+			case BPF_LD|BPF_H|BPF_ABS:
+				ZERO_EAX();
+				MOVid(ECX, ins->k);
+				MOVrd(ESI, ECX);
+				ADDib(ECX, sizeof(short));
+				CMPodd(ECX, RBP, -12);
+				JLEb(3);
+				POP(RBX);
+				LEAVE_RET();
+				MOVobw(AX, RBX, RSI);
+				SWAP_AX();
+				break;
+
+			case BPF_LD|BPF_B|BPF_ABS:
+				ZERO_EAX();
+				MOVid(ECX, ins->k);
+				CMPodd(ECX, RBP, -12);
+				JLEb(3);
+				POP(RBX);
+				LEAVE_RET();
+				MOVobb(AL, RBX, RCX);
+				break;
+
+			case BPF_LD|BPF_W|BPF_LEN:
+				MOVodd(EAX, RBP, -8);
+				break;
+
+			case BPF_LDX|BPF_W|BPF_LEN:
+				MOVodd(EDX, RBP, -8);
+				break;
+
+			case BPF_LD|BPF_W|BPF_IND:
+				MOVid(ECX, ins->k);
+				ADDrd(ECX, EDX);
+				MOVrd(ESI, ECX);
+				ADDib(ECX, sizeof(int));
+				CMPodd(ECX, RBP, -12);
+				JLEb(5);
+				ZERO_EAX();
+				POP(RBX);
+				LEAVE_RET();
+				MOVobd(EAX, RBX, RSI);
+				BSWAP(EAX);
+				break;
+
+			case BPF_LD|BPF_H|BPF_IND:
+				ZERO_EAX();
+				MOVid(ECX, ins->k);
+				ADDrd(ECX, EDX);
+				MOVrd(ESI, ECX);
+				ADDib(ECX, sizeof(short));
+				CMPodd(ECX, RBP, -12);
+				JLEb(3);
+				POP(RBX);
+				LEAVE_RET();
+				MOVobw(AX, RBX, RSI);
+				SWAP_AX();
+				break;
+
+			case BPF_LD|BPF_B|BPF_IND:
+				ZERO_EAX();
+				MOVid(ECX, ins->k);
+				ADDrd(ECX, EDX);
+				CMPodd(ECX, RBP, -12);
+				JLEb(3);
+				POP(RBX);
+				LEAVE_RET();
+				MOVobb(AL, RBX, RCX);
+				break;
+
+			case BPF_LDX|BPF_MSH|BPF_B:
+				MOVid(ECX, ins->k);
+				CMPodd(ECX, RBP, -12);
+				JLEb(5);
+				ZERO_EAX();
+				POP(RBX);
+				LEAVE_RET();
+				ZERO_EDX();
+				MOVobb(DL, RBX, RCX);
+				ANDib(DL, 0xf);
+				SHLib(EDX, 2);
+				break;
+
+			case BPF_LD|BPF_IMM:
+				MOVid(EAX, ins->k);
+				break;
+
+			case BPF_LDX|BPF_IMM:
+				MOVid(EDX, ins->k);
+				break;
+
+			case BPF_LD|BPF_MEM:
+				MOViq(RCX, (uintptr_t)mem);
+				MOVid(ESI, ins->k * 4);
+				MOVobd(EAX, RCX, RSI);
+				break;
+
+			case BPF_LDX|BPF_MEM:
+				MOViq(RCX, (uintptr_t)mem);
+				MOVid(ESI, ins->k * 4);
+				MOVobd(EDX, RCX, RSI);
+				break;
+
+			case BPF_ST:
+				/*
+				 * XXX this command and the following could
+				 * be optimized if the previous instruction
+				 * was already of this type
+				 */
+				MOViq(RCX, (uintptr_t)mem);
+				MOVid(ESI, ins->k * 4);
+				MOVomd(RCX, RSI, EAX);
+				break;
+
+			case BPF_STX:
+				MOViq(RCX, (uintptr_t)mem);
+				MOVid(ESI, ins->k * 4);
+				MOVomd(RCX, RSI, EDX);
+				break;
+
+			case BPF_JMP|BPF_JA:
+				JMP(stream.refs[stream.bpf_pc + ins->k] -
+				    stream.refs[stream.bpf_pc]);
+				break;
+
+			case BPF_JMP|BPF_JGT|BPF_K:
+				CMPid(EAX, ins->k);
+				/* 5 is the size of the following JMP */
+				JG(stream.refs[stream.bpf_pc + ins->jt] -
+				    stream.refs[stream.bpf_pc] + 5 );
+				JMP(stream.refs[stream.bpf_pc + ins->jf] -
+				    stream.refs[stream.bpf_pc]);
+				break;
+
+			case BPF_JMP|BPF_JGE|BPF_K:
+				CMPid(EAX, ins->k);
+				JGE(stream.refs[stream.bpf_pc + ins->jt] -
+				    stream.refs[stream.bpf_pc] + 5);
+				JMP(stream.refs[stream.bpf_pc + ins->jf] -
+				    stream.refs[stream.bpf_pc]);
+				break;
+
+			case BPF_JMP|BPF_JEQ|BPF_K:
+				CMPid(EAX, ins->k);
+				JE(stream.refs[stream.bpf_pc + ins->jt] -
+				    stream.refs[stream.bpf_pc] + 5);
+				JMP(stream.refs[stream.bpf_pc + ins->jf] -
+				    stream.refs[stream.bpf_pc]);
+				break;
+
+			case BPF_JMP|BPF_JSET|BPF_K:
+				MOVrd(ECX, EAX);
+				ANDid(ECX, ins->k);
+				JE(stream.refs[stream.bpf_pc + ins->jf] -
+				    stream.refs[stream.bpf_pc] + 5);
+				JMP(stream.refs[stream.bpf_pc + ins->jt] -
+				    stream.refs[stream.bpf_pc]);
+				break;
+
+			case BPF_JMP|BPF_JGT|BPF_X:
+				CMPrd(EAX, EDX);
+				JA(stream.refs[stream.bpf_pc + ins->jt] -
+				    stream.refs[stream.bpf_pc] + 5);
+				JMP(stream.refs[stream.bpf_pc + ins->jf] -
+				    stream.refs[stream.bpf_pc]);
+				break;
+
+			case BPF_JMP|BPF_JGE|BPF_X:
+				CMPrd(EAX, EDX);
+				JAE(stream.refs[stream.bpf_pc + ins->jt] -
+				    stream.refs[stream.bpf_pc] + 5);
+				JMP(stream.refs[stream.bpf_pc + ins->jf] -
+				    stream.refs[stream.bpf_pc]);
+				break;
+
+			case BPF_JMP|BPF_JEQ|BPF_X:
+				CMPrd(EAX, EDX);
+				JE(stream.refs[stream.bpf_pc + ins->jt] -
+				    stream.refs[stream.bpf_pc] + 5);
+				JMP(stream.refs[stream.bpf_pc + ins->jf] -
+				    stream.refs[stream.bpf_pc]);
+				break;
+
+			case BPF_JMP|BPF_JSET|BPF_X:
+				MOVrd(ECX, EAX);
+				ANDrd(ECX, EDX);
+				JE(stream.refs[stream.bpf_pc + ins->jf] -
+				    stream.refs[stream.bpf_pc] + 5);
+				JMP(stream.refs[stream.bpf_pc + ins->jt] -
+				    stream.refs[stream.bpf_pc]);
+				break;
+
+			case BPF_ALU|BPF_ADD|BPF_X:
+				ADDrd(EAX, EDX);
+				break;
+
+			case BPF_ALU|BPF_SUB|BPF_X:
+				SUBrd(EAX, EDX);
+				break;
+
+			case BPF_ALU|BPF_MUL|BPF_X:
+				MOVrd(ECX, EDX);
+				MULrd(EDX);
+				MOVrd(EDX, ECX);
+				break;
+
+			case BPF_ALU|BPF_DIV|BPF_X:
+				CMPid(EDX, 0);
+				JNEb(5);
+				ZERO_EAX();
+				POP(RBX);
+				LEAVE_RET();
+				MOVrd(ECX, EDX);
+				ZERO_EDX();
+				DIVrd(ECX);
+				MOVrd(EDX, ECX);
+				break;
+
+			case BPF_ALU|BPF_AND|BPF_X:
+				ANDrd(EAX, EDX);
+				break;
+
+			case BPF_ALU|BPF_OR|BPF_X:
+				ORrd(EAX, EDX);
+				break;
+
+			case BPF_ALU|BPF_LSH|BPF_X:
+				MOVrd(ECX, EDX);
+				SHL_CLrb(EAX);
+				break;
+
+			case BPF_ALU|BPF_RSH|BPF_X:
+				MOVrd(ECX, EDX);
+				SHR_CLrb(EAX);
+				break;
+
+			case BPF_ALU|BPF_ADD|BPF_K:
+				ADD_EAXi(ins->k);
+				break;
+
+			case BPF_ALU|BPF_SUB|BPF_K:
+				SUB_EAXi(ins->k);
+				break;
+
+			case BPF_ALU|BPF_MUL|BPF_K:
+				MOVrd(ECX, EDX);
+				MOVid(EDX, ins->k);
+				MULrd(EDX);
+				MOVrd(EDX, ECX);
+				break;
+
+			case BPF_ALU|BPF_DIV|BPF_K:
+				MOVrd(ECX, EDX);
+				ZERO_EDX();
+				MOVid(ESI, ins->k);
+				DIVrd(ESI);
+				MOVrd(EDX, ECX);
+				break;
+
+			case BPF_ALU|BPF_AND|BPF_K:
+				ANDid(EAX, ins->k);
+				break;
+
+			case BPF_ALU|BPF_OR|BPF_K:
+				ORid(EAX, ins->k);
+				break;
+
+			case BPF_ALU|BPF_LSH|BPF_K:
+				SHLib(EAX, (ins->k) & 255);
+				break;
+
+			case BPF_ALU|BPF_RSH|BPF_K:
+				SHRib(EAX, (ins->k) & 255);
+				break;
+
+			case BPF_ALU|BPF_NEG:
+				NEGd(EAX);
+				break;
+
+			case BPF_MISC|BPF_TAX:
+				MOVrd(EDX, EAX);
+				break;
+
+			case BPF_MISC|BPF_TXA:
+				MOVrd(EAX, EDX);
+				break;
+			}
+			ins++;
+		}
+
+		pass++;
+		if (pass == 2)
+			break;
+
+		stream.ibuf = (char *)malloc(stream.cur_ip, M_BPFJIT, M_NOWAIT);
+		if (stream.ibuf == NULL) {
+			free(stream.refs, M_BPFJIT);
+			return NULL;
+		}
+
+		/*
+		 * modify the reference table to contain the offsets and
+		 * not the lengths of the instructions
+		 */
+		for (i = 1; i < nins + 1; i++)
+			stream.refs[i] += stream.refs[i - 1];
+
+		/* Reset the counters */
+		stream.cur_ip = 0;
+		stream.bpf_pc = 0;
+
+		/* the second pass creates the actual code */
+		emitm = emit_code;
+	}
+
+	/*
+	 * the reference table is needed only during compilation,
+	 * now we can free it
+	 */
+	free(stream.refs, M_BPFJIT);
+
+	return (bpf_filter_func)stream.ibuf;
+}
Index: identcpu.c
===================================================================
RCS file: /home/cvs/src/sys/amd64/amd64/identcpu.c,v
retrieving revision 1.3
retrieving revision 1.4
diff -L sys/amd64/amd64/identcpu.c -L sys/amd64/amd64/identcpu.c -u -r1.3 -r1.4
--- sys/amd64/amd64/identcpu.c
+++ sys/amd64/amd64/identcpu.c
@@ -39,12 +39,14 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/amd64/amd64/identcpu.c,v 1.136.2.3 2006/04/24 18:21:54 jkim Exp $");
+__FBSDID("$FreeBSD: src/sys/amd64/amd64/identcpu.c,v 1.154 2007/05/30 14:23:26 des Exp $");
 
 #include "opt_cpu.h"
 
 #include <sys/param.h>
 #include <sys/bus.h>
+#include <sys/cpu.h>
+#include <sys/eventhandler.h>
 #include <sys/systm.h>
 #include <sys/kernel.h>
 #include <sys/sysctl.h>
@@ -69,6 +71,8 @@
 
 static void print_AMD_info(void);
 static void print_AMD_assoc(int i);
+void setPQL2(int *const size, int *const ways);
+static void setPQL2_AMD(int *const size, int *const ways);
 
 int	cpu_class;
 char machine[] = "amd64";
@@ -93,6 +97,9 @@
 	{ "Sledgehammer",	CPUCLASS_K8 },		/* CPU_SLEDGEHAMMER */
 };
 
+extern int pq_l2size;
+extern int pq_l2nways;
+
 void
 printcpuinfo(void)
 {
@@ -350,7 +357,8 @@
 			else if (strcmp(cpu_vendor, "GenuineIntel") == 0 &&
 			    (cpu_high >= 4)) {
 				cpuid_count(4, 0, regs);
-				cmp = ((regs[0] & 0xfc000000) >> 26) + 1;
+				if ((regs[0] & 0x1f) != 0)
+					cmp = ((regs[0] >> 26) & 0x3f) + 1;
 			}
 			if (cmp > 1)
 				printf("\n  Cores per package: %d", cmp);
@@ -393,6 +401,21 @@
 }
 
 
+/* Update TSC freq with the value indicated by the caller. */
+static void
+tsc_freq_changed(void *arg, const struct cf_level *level, int status)
+{
+	/* If there was an error during the transition, don't do anything. */
+	if (status != 0)
+		return;
+
+	/* Total setting for this level gives the new frequency in MHz. */
+	hw_clockrate = level->total_set.freq;
+}
+
+EVENTHANDLER_DEFINE(cpufreq_post_change, tsc_freq_changed, NULL,
+    EVENTHANDLER_PRI_ANY);
+
 /*
  * Final stage of CPU identification. -- Should I check TI?
  */
@@ -521,3 +544,30 @@
 		print_AMD_l2_assoc((regs[2] >> 12) & 0x0f);	
 	}
 }
+
+static void             
+setPQL2_AMD(int *const size, int *const ways)
+{
+	if (cpu_exthigh >= 0x80000006) {
+		u_int regs[4];
+
+		do_cpuid(0x80000006, regs);
+		*size = regs[2] >> 16;
+		*ways = (regs[2] >> 12) & 0x0f;
+		switch (*ways) {
+		case 0:				/* disabled/not present */
+		case 15:			/* fully associative */
+		default: *ways = 1; break;	/* reserved configuration */
+		case 4: *ways = 4; break;
+		case 6: *ways = 8; break;
+		case 8: *ways = 16; break;
+		}
+	}
+}
+
+void
+setPQL2(int *const size, int *const ways)
+{
+	if (strcmp(cpu_vendor, "AuthenticAMD") == 0)
+		setPQL2_AMD(size, ways);
+}
Index: tsc.c
===================================================================
RCS file: /home/cvs/src/sys/amd64/amd64/tsc.c,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L sys/amd64/amd64/tsc.c -L sys/amd64/amd64/tsc.c -u -r1.1.1.1 -r1.2
--- sys/amd64/amd64/tsc.c
+++ sys/amd64/amd64/tsc.c
@@ -25,11 +25,14 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/amd64/amd64/tsc.c,v 1.205 2003/11/17 08:58:13 peter Exp $");
+__FBSDID("$FreeBSD: src/sys/amd64/amd64/tsc.c,v 1.208 2007/06/04 18:25:01 dwmalone Exp $");
 
 #include "opt_clock.h"
 
 #include <sys/param.h>
+#include <sys/bus.h>
+#include <sys/cpu.h>
+#include <sys/malloc.h>
 #include <sys/systm.h>
 #include <sys/sysctl.h>
 #include <sys/time.h>
@@ -41,8 +44,11 @@
 #include <machine/md_var.h>
 #include <machine/specialreg.h>
 
+#include "cpufreq_if.h"
+
 uint64_t	tsc_freq;
 int		tsc_is_broken;
+static eventhandler_tag tsc_levels_tag, tsc_pre_tag, tsc_post_tag;
 
 #ifdef SMP
 static int	smp_tsc;
@@ -51,14 +57,19 @@
 TUNABLE_INT("kern.timecounter.smp_tsc", &smp_tsc);
 #endif
 
+static void tsc_freq_changed(void *arg, const struct cf_level *level,
+    int status);
+static void tsc_freq_changing(void *arg, const struct cf_level *level,
+    int *status);
 static	unsigned tsc_get_timecount(struct timecounter *tc);
+static void tsc_levels_changed(void *arg, int unit);
 
 static struct timecounter tsc_timecounter = {
 	tsc_get_timecount,	/* get_timecount */
 	0,			/* no poll_pps */
- 	~0u,			/* counter_mask */
+	~0u,			/* counter_mask */
 	0,			/* frequency */
-	 "TSC",			/* name */
+	"TSC",			/* name */
 	800,			/* quality (adjusted in code) */
 };
 
@@ -77,8 +88,23 @@
 	tsc_freq = tscval[1] - tscval[0];
 	if (bootverbose)
 		printf("TSC clock: %lu Hz\n", tsc_freq);
-}
 
+	/*
+	 * Inform CPU accounting about our boot-time clock rate.  Once the
+	 * system is finished booting, we will get the real max clock rate
+	 * via tsc_freq_max().  This also will be updated if someone loads
+	 * a cpufreq driver after boot that discovers a new max frequency.
+	 */
+	set_cputicker(rdtsc, tsc_freq, 1);
+
+	/* Register to find out about changes in CPU frequency. */
+	tsc_pre_tag = EVENTHANDLER_REGISTER(cpufreq_pre_change,
+	    tsc_freq_changing, NULL, EVENTHANDLER_PRI_FIRST);
+	tsc_post_tag = EVENTHANDLER_REGISTER(cpufreq_post_change,
+	    tsc_freq_changed, NULL, EVENTHANDLER_PRI_FIRST);
+	tsc_levels_tag = EVENTHANDLER_REGISTER(cpufreq_levels_changed,
+	    tsc_levels_changed, NULL, EVENTHANDLER_PRI_ANY);
+}
 
 void
 init_TSC_tc(void)
@@ -103,6 +129,72 @@
 	}
 }
 
+/*
+ * When cpufreq levels change, find out about the (new) max frequency.  We
+ * use this to update CPU accounting in case it got a lower estimate at boot.
+ */
+static void
+tsc_levels_changed(void *arg, int unit)
+{
+	device_t cf_dev;
+	struct cf_level *levels;
+	int count, error;
+	uint64_t max_freq;
+
+	/* Only use values from the first CPU, assuming all are equal. */
+	if (unit != 0)
+		return;
+
+	/* Find the appropriate cpufreq device instance. */
+	cf_dev = devclass_get_device(devclass_find("cpufreq"), unit);
+	if (cf_dev == NULL) {
+		printf("tsc_levels_changed() called but no cpufreq device?\n");
+		return;
+	}
+
+	/* Get settings from the device and find the max frequency. */
+	count = 64;
+	levels = malloc(count * sizeof(*levels), M_TEMP, M_NOWAIT);
+	if (levels == NULL)
+		return;
+	error = CPUFREQ_LEVELS(cf_dev, levels, &count);
+	if (error == 0 && count != 0) {
+		max_freq = (uint64_t)levels[0].total_set.freq * 1000000;
+		set_cputicker(rdtsc, max_freq, 1);
+	} else
+		printf("tsc_levels_changed: no max freq found\n");
+	free(levels, M_TEMP);
+}
+
+/*
+ * If the TSC timecounter is in use, veto the pending change.  It may be
+ * possible in the future to handle a dynamically-changing timecounter rate.
+ */
+static void
+tsc_freq_changing(void *arg, const struct cf_level *level, int *status)
+{
+
+	if (*status != 0 || timecounter != &tsc_timecounter)
+		return;
+
+	printf("timecounter TSC must not be in use when "
+	     "changing frequencies; change denied\n");
+	*status = EBUSY;
+}
+
+/* Update TSC freq with the value indicated by the caller. */
+static void
+tsc_freq_changed(void *arg, const struct cf_level *level, int status)
+{
+	/* If there was an error during the transition, don't do anything. */
+	if (status != 0)
+		return;
+
+	/* Total setting for this level gives the new frequency in MHz. */
+	tsc_freq = (uint64_t)level->total_set.freq * 1000000;
+	tsc_timecounter.tc_frequency = tsc_freq;
+}
+
 static int
 sysctl_machdep_tsc_freq(SYSCTL_HANDLER_ARGS)
 {
@@ -112,7 +204,7 @@
 	if (tsc_timecounter.tc_frequency == 0)
 		return (EOPNOTSUPP);
 	freq = tsc_freq;
-	error = sysctl_handle_int(oidp, &freq, sizeof(freq), req);
+	error = sysctl_handle_quad(oidp, &freq, 0, req);
 	if (error == 0 && req->newptr != NULL) {
 		tsc_freq = freq;
 		tsc_timecounter.tc_frequency = tsc_freq;
@@ -120,8 +212,8 @@
 	return (error);
 }
 
-SYSCTL_PROC(_machdep, OID_AUTO, tsc_freq, CTLTYPE_LONG | CTLFLAG_RW,
-    0, sizeof(u_int), sysctl_machdep_tsc_freq, "IU", "");
+SYSCTL_PROC(_machdep, OID_AUTO, tsc_freq, CTLTYPE_QUAD | CTLFLAG_RW,
+    0, sizeof(u_int), sysctl_machdep_tsc_freq, "QU", "");
 
 static unsigned
 tsc_get_timecount(struct timecounter *tc)
Index: initcpu.c
===================================================================
RCS file: /home/cvs/src/sys/amd64/amd64/initcpu.c,v
retrieving revision 1.2
retrieving revision 1.3
diff -L sys/amd64/amd64/initcpu.c -L sys/amd64/amd64/initcpu.c -u -r1.2 -r1.3
--- sys/amd64/amd64/initcpu.c
+++ sys/amd64/amd64/initcpu.c
@@ -28,7 +28,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/amd64/amd64/initcpu.c,v 1.48.8.2 2006/07/01 09:06:40 davidxu Exp $");
+__FBSDID("$FreeBSD: src/sys/amd64/amd64/initcpu.c,v 1.50 2006/06/19 22:59:28 davidxu Exp $");
 
 #include "opt_cpu.h"
 
Index: bios.c
===================================================================
RCS file: /home/cvs/src/sys/amd64/amd64/bios.c,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L sys/amd64/amd64/bios.c -L sys/amd64/amd64/bios.c -u -r1.1.1.1 -r1.2
--- sys/amd64/amd64/bios.c
+++ sys/amd64/amd64/bios.c
@@ -26,7 +26,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/amd64/amd64/bios.c,v 1.72 2004/09/24 01:08:34 peter Exp $");
+__FBSDID("$FreeBSD: src/sys/amd64/amd64/bios.c,v 1.73 2005/07/21 09:48:36 phk Exp $");
 
 /*
  * Subset of the i386 bios support code.  We cannot make bios16 nor bios32
@@ -93,18 +93,3 @@
     }
     return(0);
 }
-
-const u_char *
-bios_string(u_int from, u_int to, const u_char *string, int len)
-{
-	const char *t, *te;
-
-	if (len == 0)
-		len = strlen(string);
-	t = (const char *)(KERNBASE + from);
-	te = (const char *)(KERNBASE + to);
-	for (; t <= te; t++)
-		if (!memcmp(string, t, len))
-			return (t);
-	return (NULL);
-}
Index: legacy.c
===================================================================
RCS file: /home/cvs/src/sys/amd64/amd64/legacy.c,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L sys/amd64/amd64/legacy.c -L sys/amd64/amd64/legacy.c -u -r1.1.1.1 -r1.2
--- sys/amd64/amd64/legacy.c
+++ sys/amd64/amd64/legacy.c
@@ -28,7 +28,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/amd64/amd64/legacy.c,v 1.59 2005/02/15 07:26:28 njl Exp $");
+__FBSDID("$FreeBSD: src/sys/amd64/amd64/legacy.c,v 1.61 2007/09/30 11:05:13 marius Exp $");
 
 /*
  * This code implements a system driver for legacy systems that do not
@@ -105,10 +105,10 @@
 {
 
 	/*
-	 * Add child device with order of 1 so it gets probed
-	 * after ACPI (which is at order 0.
+	 * Add child device with order of 11 so it gets probed
+	 * after ACPI (which is at order 10).
 	 */
-	if (BUS_ADD_CHILD(parent, 1, "legacy", 0) == NULL)
+	if (BUS_ADD_CHILD(parent, 11, "legacy", 0) == NULL)
 		panic("legacy: could not attach");
 }
 
@@ -207,6 +207,9 @@
 	struct legacy_device *atdev = DEVTOAT(child);
 
 	switch (which) {
+	case LEGACY_IVAR_PCIDOMAIN:
+		*result = 0;
+		break;
 	case LEGACY_IVAR_PCIBUS:
 		*result = atdev->lg_pcibus;
 		break;
@@ -223,6 +226,8 @@
 	struct legacy_device *atdev = DEVTOAT(child);
 
 	switch (which) {
+	case LEGACY_IVAR_PCIDOMAIN:
+		return EINVAL;
 	case LEGACY_IVAR_PCIBUS:
 		atdev->lg_pcibus = value;
 		break;
Index: machdep.c
===================================================================
RCS file: /home/cvs/src/sys/amd64/amd64/machdep.c,v
retrieving revision 1.2
retrieving revision 1.3
diff -L sys/amd64/amd64/machdep.c -L sys/amd64/amd64/machdep.c -u -r1.2 -r1.3
--- sys/amd64/amd64/machdep.c
+++ sys/amd64/amd64/machdep.c
@@ -39,7 +39,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/amd64/amd64/machdep.c,v 1.638.2.6 2006/03/20 19:56:43 jhb Exp $");
+__FBSDID("$FreeBSD: src/sys/amd64/amd64/machdep.c,v 1.675.2.2.2.1 2008/01/19 18:15:01 kib Exp $");
 
 #include "opt_atalk.h"
 #include "opt_atpic.h"
@@ -61,6 +61,7 @@
 #include <sys/buf.h>
 #include <sys/bus.h>
 #include <sys/callout.h>
+#include <sys/clock.h>
 #include <sys/cons.h>
 #include <sys/cpu.h>
 #include <sys/eventhandler.h>
@@ -124,9 +125,11 @@
 #include <machine/smp.h>
 #endif
 
-#include <dev/ic/i8259.h>
+#ifdef DEV_ATPIC
 #include <amd64/isa/icu.h>
+#else
 #include <machine/apicvar.h>
+#endif
 
 #include <isa/isareg.h>
 #include <isa/rtc.h>
@@ -135,7 +138,6 @@
 CTASSERT(offsetof(struct pcpu, pc_curthread) == 0);
 
 extern u_int64_t hammer_time(u_int64_t, u_int64_t);
-extern void dblfault_handler(void);
 
 extern void printcpuinfo(void);	/* XXX header file */
 extern void identify_cpu(void);
@@ -153,6 +155,10 @@
 extern vm_offset_t ksym_start, ksym_end;
 #endif
 
+/* Intel ICH registers */
+#define ICH_PMBASE	0x400
+#define ICH_SMI_EN	ICH_PMBASE + 0x30
+
 int	_udatasel, _ucodesel, _ucode32sel;
 
 int cold = 1;
@@ -160,8 +166,16 @@
 long Maxmem = 0;
 long realmem = 0;
 
-vm_paddr_t phys_avail[20];
-vm_paddr_t dump_avail[20];
+/*
+ * The number of PHYSMAP entries must be one less than the number of
+ * PHYSSEG entries because the PHYSMAP entry that spans the largest
+ * physical address that is accessible by ISA DMA is split into two
+ * PHYSSEG entries.
+ */
+#define	PHYSMAP_SIZE	(2 * (VM_PHYSSEG_MAX - 1))
+
+vm_paddr_t phys_avail[PHYSMAP_SIZE + 2];
+vm_paddr_t dump_avail[PHYSMAP_SIZE + 2];
 
 /* must be 2 less so 0 0 can signal end of chunks */
 #define PHYS_AVAIL_ARRAY_END ((sizeof(phys_avail) / sizeof(phys_avail[0])) - 2)
@@ -182,6 +196,27 @@
 cpu_startup(dummy)
 	void *dummy;
 {
+	char *sysenv;
+
+	/*
+	 * On MacBooks, we need to disallow the legacy USB circuit to
+	 * generate an SMI# because this can cause several problems,
+	 * namely: incorrect CPU frequency detection and failure to
+	 * start the APs.
+	 * We do this by disabling a bit in the SMI_EN (SMI Control and
+	 * Enable register) of the Intel ICH LPC Interface Bridge. 
+	 */
+	sysenv = getenv("smbios.system.product");
+	if (sysenv != NULL) {
+		if (strncmp(sysenv, "MacBook", 7) == 0) {
+			if (bootverbose)
+				printf("Disabling LEGACY_USB_EN bit on "
+				    "Intel ICH.\n");
+			outl(ICH_SMI_EN, inl(ICH_SMI_EN) & ~0x8);
+		}
+		freeenv(sysenv);
+	}
+
 	/*
 	 * Good {morning,afternoon,evening,night}.
 	 */
@@ -191,8 +226,8 @@
 #ifdef PERFMON
 	perfmon_init();
 #endif
-	printf("real memory  = %ju (%ju MB)\n", ptoa((uintmax_t)Maxmem),
-	    ptoa((uintmax_t)Maxmem) / 1048576);
+	printf("usable memory = %ju (%ju MB)\n", ptoa((uintmax_t)physmem),
+	    ptoa((uintmax_t)physmem) / 1048576);
 	realmem = Maxmem;
 	/*
 	 * Display any holes after the first chunk of extended memory.
@@ -215,7 +250,7 @@
 
 	vm_ksubmap_init(&kmi);
 
-	printf("avail memory = %ju (%ju MB)\n",
+	printf("avail memory  = %ju (%ju MB)\n",
 	    ptoa((uintmax_t)cnt.v_free_count),
 	    ptoa((uintmax_t)cnt.v_free_count) / 1048576);
 
@@ -239,11 +274,7 @@
  * specified pc, psl.
  */
 void
-sendsig(catcher, sig, mask, code)
-	sig_t catcher;
-	int sig;
-	sigset_t *mask;
-	u_long code;
+sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask)
 {
 	struct sigframe sf, *sfp;
 	struct proc *p;
@@ -251,11 +282,13 @@
 	struct sigacts *psp;
 	char *sp;
 	struct trapframe *regs;
+	int sig;
 	int oonstack;
 
 	td = curthread;
 	p = td->td_proc;
 	PROC_LOCK_ASSERT(p, MA_OWNED);
+	sig = ksi->ksi_signo;
 	psp = p->p_sigacts;
 	mtx_assert(&psp->ps_mtx, MA_OWNED);
 	regs = td->td_frame;
@@ -299,13 +332,13 @@
 		sf.sf_ahu.sf_action = (__siginfohandler_t *)catcher;
 
 		/* Fill in POSIX parts */
-		sf.sf_si.si_signo = sig;
-		sf.sf_si.si_code = code;
-		regs->tf_rcx = regs->tf_addr;	/* arg 4 in %rcx */
+		sf.sf_si = ksi->ksi_info;
+		sf.sf_si.si_signo = sig; /* maybe a translated signal */
+		regs->tf_rcx = (register_t)ksi->ksi_addr; /* arg 4 in %rcx */
 	} else {
 		/* Old FreeBSD-style arguments. */
-		regs->tf_rsi = code;		/* arg 2 in %rsi */
-		regs->tf_rcx = regs->tf_addr;	/* arg 4 in %rcx */
+		regs->tf_rsi = ksi->ksi_code;	/* arg 2 in %rsi */
+		regs->tf_rcx = (register_t)ksi->ksi_addr; /* arg 4 in %rcx */
 		sf.sf_ahu.sf_handler = catcher;
 	}
 	mtx_unlock(&psp->ps_mtx);
@@ -331,28 +364,6 @@
 }
 
 /*
- * Build siginfo_t for SA thread
- */
-void
-cpu_thread_siginfo(int sig, u_long code, siginfo_t *si)
-{
-	struct proc *p;
-	struct thread *td;
-	struct trapframe *regs;
-
-	td = curthread;
-	p = td->td_proc;
-	regs = td->td_frame;
-	PROC_LOCK_ASSERT(p, MA_OWNED);
-
-	bzero(si, sizeof(*si));
-	si->si_signo = sig;
-	si->si_code = code;
-	si->si_addr = (void *)regs->tf_addr;
-	/* XXXKSE fill other fields */
-}
-
-/*
  * System call to cleanup state after a signal
  * has been taken.  Reset signal mask and
  * stack state from context left by sendsig (above).
@@ -367,7 +378,7 @@
 sigreturn(td, uap)
 	struct thread *td;
 	struct sigreturn_args /* {
-		const __ucontext *sigcntxp;
+		const struct __ucontext *sigcntxp;
 	} */ *uap;
 {
 	ucontext_t uc;
@@ -376,6 +387,7 @@
 	const ucontext_t *ucp;
 	long rflags;
 	int cs, error, ret;
+	ksiginfo_t ksi;
 
 	error = copyin(uap->sigcntxp, &uc, sizeof(uc));
 	if (error != 0)
@@ -409,7 +421,12 @@
 	cs = ucp->uc_mcontext.mc_cs;
 	if (!CS_SECURE(cs)) {
 		printf("sigreturn: cs = 0x%x\n", cs);
-		trapsignal(td, SIGBUS, T_PROTFLT);
+		ksiginfo_init_trap(&ksi);
+		ksi.ksi_signo = SIGBUS;
+		ksi.ksi_code = BUS_OBJERR;
+		ksi.ksi_trapno = T_PROTFLT;
+		ksi.ksi_addr = (void *)regs->tf_rip;
+		trapsignal(td, &ksi);
 		return (EINVAL);
 	}
 
@@ -473,9 +490,9 @@
 
 #ifdef SMP
 	/* Schedule ourselves on the indicated cpu. */
-	mtx_lock_spin(&sched_lock);
+	thread_lock(curthread);
 	sched_bind(curthread, cpu_id);
-	mtx_unlock_spin(&sched_lock);
+	thread_unlock(curthread);
 #endif
 
 	/* Calibrate by measuring a short delay. */
@@ -486,9 +503,9 @@
 	intr_restore(reg);
 
 #ifdef SMP
-	mtx_lock_spin(&sched_lock);
+	thread_lock(curthread);
 	sched_unbind(curthread);
-	mtx_unlock_spin(&sched_lock);
+	thread_unlock(curthread);
 #endif
 
 	/*
@@ -527,6 +544,7 @@
  * help lock contention somewhat, and this is critical for HTT. -Peter
  */
 static int	cpu_idle_hlt = 1;
+TUNABLE_INT("machdep.cpu_idle_hlt", &cpu_idle_hlt);
 SYSCTL_INT(_machdep, OID_AUTO, cpu_idle_hlt, CTLFLAG_RW,
     &cpu_idle_hlt, 0, "Idle loop HLT enable");
 
@@ -646,26 +664,6 @@
 	load_cr0(cr0);
 }
 
-static int
-sysctl_machdep_adjkerntz(SYSCTL_HANDLER_ARGS)
-{
-	int error;
-	error = sysctl_handle_int(oidp, oidp->oid_arg1, oidp->oid_arg2,
-		req);
-	if (!error && req->newptr)
-		resettodr();
-	return (error);
-}
-
-SYSCTL_PROC(_machdep, CPU_ADJKERNTZ, adjkerntz, CTLTYPE_INT|CTLFLAG_RW,
-	&adjkerntz, 0, sysctl_machdep_adjkerntz, "I", "");
-
-SYSCTL_INT(_machdep, CPU_DISRTCSET, disable_rtc_set,
-	CTLFLAG_RW, &disable_rtc_set, 0, "");
-
-SYSCTL_INT(_machdep, CPU_WALLCLOCK, wall_cmos_clock,
-	CTLFLAG_RW, &wall_cmos_clock, 0, "");
-
 /*
  * Initialize amd64 and configure to run kernel
  */
@@ -757,6 +755,15 @@
 	0,			/* long */
 	0,			/* default 32 vs 16 bit size */
 	0  			/* limit granularity (byte/page units)*/ },
+/* GUGS32_SEL	8 32 bit GS Descriptor for user */
+{	0x0,			/* segment base address  */
+	0xfffff,		/* length - all address space */
+	SDT_MEMRWA,		/* segment type */
+	SEL_UPL,		/* segment descriptor priority level */
+	1,			/* segment descriptor present */
+	0,			/* long */
+	1,			/* default 32 vs 16 bit size */
+	1  			/* limit granularity (byte/page units)*/ },
 };
 
 void
@@ -780,8 +787,6 @@
 	ip->gd_hioffset = ((uintptr_t)func)>>16 ;
 }
 
-#define	IDTVEC(name)	__CONCAT(X,name)
-
 extern inthand_t
 	IDTVEC(div), IDTVEC(dbg), IDTVEC(nmi), IDTVEC(bpt), IDTVEC(ofl),
 	IDTVEC(bnd), IDTVEC(ill), IDTVEC(dna), IDTVEC(fpusegm),
@@ -850,8 +855,6 @@
 }
 #endif
 
-#define PHYSMAP_SIZE	(2 * 20)
-
 u_int basemem;
 
 /*
@@ -870,7 +873,7 @@
 static void
 getmemsize(caddr_t kmdp, u_int64_t first)
 {
-	int i, physmap_idx, pa_indx, da_indx;
+	int i, off, physmap_idx, pa_indx, da_indx;
 	vm_paddr_t pa, physmap[PHYSMAP_SIZE];
 	u_long physmem_tunable;
 	pt_entry_t *pte;
@@ -912,7 +915,7 @@
 			if (smap->base < physmap[i + 1]) {
 				if (boothowto & RB_VERBOSE)
 					printf(
-	"Overlapping or non-montonic memory region, ignoring second region\n");
+	"Overlapping or non-monotonic memory region, ignoring second region\n");
 				continue;
 			}
 		}
@@ -965,17 +968,17 @@
 	if (TUNABLE_ULONG_FETCH("hw.physmem", &physmem_tunable))
 		Maxmem = atop(physmem_tunable);
 
+	/*
+	 * Don't allow MAXMEM or hw.physmem to extend the amount of memory
+	 * in the system.
+	 */
+	if (Maxmem > atop(physmap[physmap_idx + 1]))
+		Maxmem = atop(physmap[physmap_idx + 1]);
+
 	if (atop(physmap[physmap_idx + 1]) != Maxmem &&
 	    (boothowto & RB_VERBOSE))
 		printf("Physical memory use set to %ldK\n", Maxmem * 4);
 
-	/*
-	 * If Maxmem has been increased beyond what the system has detected,
-	 * extend the last memory segment to the new limit.
-	 */
-	if (atop(physmap[physmap_idx + 1]) < Maxmem)
-		physmap[physmap_idx + 1] = ptoa((vm_paddr_t)Maxmem);
-
 	/* call pmap initialization to make new kernel address space */
 	pmap_bootstrap(&first);
 
@@ -1133,14 +1136,17 @@
 	/* Trim off space for the message buffer. */
 	phys_avail[pa_indx] -= round_page(MSGBUF_SIZE);
 
-	avail_end = phys_avail[pa_indx];
+	/* Map the message buffer. */
+	for (off = 0; off < round_page(MSGBUF_SIZE); off += PAGE_SIZE)
+		pmap_kenter((vm_offset_t)msgbufp + off, phys_avail[pa_indx] +
+		    off);
 }
 
 u_int64_t
 hammer_time(u_int64_t modulep, u_int64_t physfree)
 {
 	caddr_t kmdp;
-	int gsel_tss, off, x;
+	int gsel_tss, x;
 	struct pcpu *pc;
 	u_int64_t msr;
 	char *env;
@@ -1155,7 +1161,7 @@
  	 * This may be done better later if it gets more high level
  	 * components in it. If so just link td->td_proc here.
 	 */
-	proc_linkup(&proc0, &ksegrp0, &thread0);
+	proc_linkup0(&proc0, &thread0);
 
 	preload_metadata = (caddr_t)(uintptr_t)(modulep + KERNBASE);
 	preload_bootstrap_relocate(KERNBASE);
@@ -1208,7 +1214,6 @@
 	 *	     under witness.
 	 */
 	mutex_init();
-	mtx_init(&clock_lock, "clk", NULL, MTX_SPIN);
 	mtx_init(&icu_lock, "icu", NULL, MTX_SPIN | MTX_NOWITNESS);
 
 	/* exceptions */
@@ -1216,7 +1221,7 @@
 		setidt(x, &IDTVEC(rsvd), SDT_SYSIGT, SEL_KPL, 0);
 	setidt(IDT_DE, &IDTVEC(div),  SDT_SYSIGT, SEL_KPL, 0);
 	setidt(IDT_DB, &IDTVEC(dbg),  SDT_SYSIGT, SEL_KPL, 0);
-	setidt(IDT_NMI, &IDTVEC(nmi),  SDT_SYSIGT, SEL_KPL, 0);
+	setidt(IDT_NMI, &IDTVEC(nmi),  SDT_SYSIGT, SEL_KPL, 1);
  	setidt(IDT_BP, &IDTVEC(bpt),  SDT_SYSIGT, SEL_UPL, 0);
 	setidt(IDT_OF, &IDTVEC(ofl),  SDT_SYSIGT, SEL_KPL, 0);
 	setidt(IDT_BR, &IDTVEC(bnd),  SDT_SYSIGT, SEL_KPL, 0);
@@ -1239,6 +1244,12 @@
 	lidt(&r_idt);
 
 	/*
+	 * Initialize the i8254 before the console so that console
+	 * initialization can use DELAY().
+	 */
+	i8254_init();
+
+	/*
 	 * Initialize the console before we print anything out.
 	 */
 	cninit();
@@ -1249,19 +1260,7 @@
 	atpic_startup();
 #else
 	/* Reset and mask the atpics and leave them shut down. */
-	outb(IO_ICU1, ICW1_RESET | ICW1_IC4);
-	outb(IO_ICU1 + ICU_IMR_OFFSET, IDT_IO_INTS);
-	outb(IO_ICU1 + ICU_IMR_OFFSET, 1 << 2);
-	outb(IO_ICU1 + ICU_IMR_OFFSET, ICW4_8086);
-	outb(IO_ICU1 + ICU_IMR_OFFSET, 0xff);
-	outb(IO_ICU1, OCW3_SEL | OCW3_RR);
-
-	outb(IO_ICU2, ICW1_RESET | ICW1_IC4);
-	outb(IO_ICU2 + ICU_IMR_OFFSET, IDT_IO_INTS + 8);
-	outb(IO_ICU2 + ICU_IMR_OFFSET, 2);
-	outb(IO_ICU2 + ICU_IMR_OFFSET, ICW4_8086);
-	outb(IO_ICU2 + ICU_IMR_OFFSET, 0xff);
-	outb(IO_ICU2, OCW3_SEL | OCW3_RR);
+	atpic_reset();
 
 	/*
 	 * Point the ICU spurious interrupt vectors at the APIC spurious
@@ -1315,10 +1314,6 @@
 
 	/* now running on new page tables, configured,and u/iom is accessible */
 
-	/* Map the message buffer. */
-	for (off = 0; off < round_page(MSGBUF_SIZE); off += PAGE_SIZE)
-		pmap_kenter((vm_offset_t)msgbufp + off, avail_end + off);
-
 	msgbufinit(msgbufp, MSGBUF_SIZE);
 	fpuinit();
 
@@ -1525,7 +1520,7 @@
 	penv_xmm->en_rip = penv_fpreg->en_rip;
 	penv_xmm->en_rdp = penv_fpreg->en_rdp;
 	penv_xmm->en_mxcsr = penv_fpreg->en_mxcsr;
-	penv_xmm->en_mxcsr_mask = penv_fpreg->en_mxcsr_mask;
+	penv_xmm->en_mxcsr_mask = penv_fpreg->en_mxcsr_mask & cpu_mxcsr_mask;
 
 	/* FPU registers */
 	for (i = 0; i < 8; ++i)
@@ -1652,6 +1647,7 @@
 static int
 set_fpcontext(struct thread *td, const mcontext_t *mcp)
 {
+	struct savefpu *fpstate;
 
 	if (mcp->mc_fpformat == _MC_FPFMT_NODEV)
 		return (0);
@@ -1667,7 +1663,9 @@
 		 * be called with interrupts disabled.
 		 * XXX obsolete on trap-16 systems?
 		 */
-		fpusetregs(td, (struct savefpu *)&mcp->mc_fpstate);
+		fpstate = (struct savefpu *)&mcp->mc_fpstate;
+		fpstate->sv_env.en_mxcsr &= cpu_mxcsr_mask;
+		fpusetregs(td, fpstate);
 	} else
 		return (EINVAL);
 	return (0);
@@ -1734,7 +1732,6 @@
 {
 	struct pcb *pcb;
 	int i;
-	u_int64_t mask1, mask2;
 
 	if (td == NULL) {
 		load_dr0(dbregs->dr[0]);
@@ -1751,10 +1748,13 @@
 		 * TRCTRAP or a general protection fault right here.
 		 * Upper bits of dr6 and dr7 must not be set
 		 */
-		for (i = 0, mask1 = 0x3<<16, mask2 = 0x2<<16; i < 8;
-		     i++, mask1 <<= 2, mask2 <<= 2)
-			if ((dbregs->dr[7] & mask1) == mask2)
+		for (i = 0; i < 4; i++) {
+			if (DBREG_DR7_ACCESS(dbregs->dr[7], i) == 0x02)
+				return (EINVAL);
+			if (td->td_frame->tf_cs == _ucode32sel &&
+			    DBREG_DR7_LEN(dbregs->dr[7], i) == DBREG_DR7_LEN_8)
 				return (EINVAL);
+		}
 		if ((dbregs->dr[6] & 0xffffffff00000000ul) != 0 ||
 		    (dbregs->dr[7] & 0xffffffff00000000ul) != 0)
 			return (EINVAL);
@@ -1775,22 +1775,22 @@
 		 * from within kernel mode?
 		 */
 
-		if (dbregs->dr[7] & 0x3) {
+		if (DBREG_DR7_ENABLED(dbregs->dr[7], 0)) {
 			/* dr0 is enabled */
 			if (dbregs->dr[0] >= VM_MAXUSER_ADDRESS)
 				return (EINVAL);
 		}
-		if (dbregs->dr[7] & 0x3<<2) {
+		if (DBREG_DR7_ENABLED(dbregs->dr[7], 1)) {
 			/* dr1 is enabled */
 			if (dbregs->dr[1] >= VM_MAXUSER_ADDRESS)
 				return (EINVAL);
 		}
-		if (dbregs->dr[7] & 0x3<<4) {
+		if (DBREG_DR7_ENABLED(dbregs->dr[7], 2)) {
 			/* dr2 is enabled */
 			if (dbregs->dr[2] >= VM_MAXUSER_ADDRESS)
 				return (EINVAL);
 		}
-		if (dbregs->dr[7] & 0x3<<6) {
+		if (DBREG_DR7_ENABLED(dbregs->dr[7], 3)) {
 			/* dr3 is enabled */
 			if (dbregs->dr[3] >= VM_MAXUSER_ADDRESS)
 				return (EINVAL);
@@ -1874,9 +1874,8 @@
                 addr[nbp++] = (caddr_t)rdr3();
         }
 
-        for (i=0; i<nbp; i++) {
-                if (addr[i] <
-                    (caddr_t)VM_MAXUSER_ADDRESS) {
+        for (i = 0; i < nbp; i++) {
+                if (addr[i] < (caddr_t)VM_MAXUSER_ADDRESS) {
                         /*
                          * addr[i] is in user space
                          */
Index: pmap.c
===================================================================
RCS file: /home/cvs/src/sys/amd64/amd64/pmap.c,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L sys/amd64/amd64/pmap.c -L sys/amd64/amd64/pmap.c -u -r1.1.1.1 -r1.2
--- sys/amd64/amd64/pmap.c
+++ sys/amd64/amd64/pmap.c
@@ -77,7 +77,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/amd64/amd64/pmap.c,v 1.516.2.4 2005/11/19 20:31:30 alc Exp $");
+__FBSDID("$FreeBSD: src/sys/amd64/amd64/pmap.c,v 1.590.2.3.2.1 2008/01/19 18:15:01 kib Exp $");
 
 /*
  *	Manages physical address maps.
@@ -106,6 +106,7 @@
  */
 
 #include "opt_msgbuf.h"
+#include "opt_pmap.h"
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -153,15 +154,20 @@
 #endif
 
 #if !defined(PMAP_DIAGNOSTIC)
-#define PMAP_INLINE __inline
+#define PMAP_INLINE	__gnu89_inline
 #else
 #define PMAP_INLINE
 #endif
 
+#define PV_STATS
+#ifdef PV_STATS
+#define PV_STAT(x)	do { x ; } while (0)
+#else
+#define PV_STAT(x)	do { } while (0)
+#endif
+
 struct pmap kernel_pmap_store;
 
-vm_paddr_t avail_start;		/* PA of first available physical page */
-vm_paddr_t avail_end;		/* PA of last available physical page */
 vm_offset_t virtual_avail;	/* VA of first avail page (after kernel bss) */
 vm_offset_t virtual_end;	/* VA of last avail page (end of kernel AS) */
 
@@ -173,7 +179,7 @@
 
 static u_int64_t	KPTphys;	/* phys addr of kernel level 1 */
 static u_int64_t	KPDphys;	/* phys addr of kernel level 2 */
-static u_int64_t	KPDPphys;	/* phys addr of kernel level 3 */
+u_int64_t		KPDPphys;	/* phys addr of kernel level 3 */
 u_int64_t		KPML4phys;	/* phys addr of kernel level 4 */
 
 static u_int64_t	DMPDphys;	/* phys addr of direct mapped level 2 */
@@ -182,10 +188,8 @@
 /*
  * Data for the pv entry allocation mechanism
  */
-static uma_zone_t pvzone;
-static struct vm_object pvzone_obj;
 static int pv_entry_count = 0, pv_entry_max = 0, pv_entry_high_water = 0;
-int pmap_pagedaemon_waken;
+static int shpgperproc = PMAP_SHPGPERPROC;
 
 /*
  * All those kernel PT submaps that BSD is so fond of
@@ -199,23 +203,28 @@
  */
 static caddr_t crashdumpmap;
 
-static PMAP_INLINE void	free_pv_entry(pv_entry_t pv);
-static pv_entry_t get_pv_entry(void);
-static void	pmap_clear_ptes(vm_page_t m, long bit);
+static void	free_pv_entry(pmap_t pmap, pv_entry_t pv);
+static pv_entry_t get_pv_entry(pmap_t locked_pmap, int try);
 
+static vm_page_t pmap_enter_quick_locked(pmap_t pmap, vm_offset_t va,
+    vm_page_t m, vm_prot_t prot, vm_page_t mpte);
 static int pmap_remove_pte(pmap_t pmap, pt_entry_t *ptq,
-		vm_offset_t sva, pd_entry_t ptepde);
-static void pmap_remove_page(pmap_t pmap, vm_offset_t va, pd_entry_t *pde);
+		vm_offset_t sva, pd_entry_t ptepde, vm_page_t *free);
+static void pmap_remove_page(pmap_t pmap, vm_offset_t va, pd_entry_t *pde,
+    vm_page_t *free);
 static void pmap_remove_entry(struct pmap *pmap, vm_page_t m,
 		vm_offset_t va);
 static void pmap_insert_entry(pmap_t pmap, vm_offset_t va, vm_page_t m);
+static boolean_t pmap_try_insert_pv_entry(pmap_t pmap, vm_offset_t va,
+    vm_page_t m);
 
 static vm_page_t pmap_allocpde(pmap_t pmap, vm_offset_t va, int flags);
 static vm_page_t pmap_allocpte(pmap_t pmap, vm_offset_t va, int flags);
 
 static vm_page_t _pmap_allocpte(pmap_t pmap, vm_pindex_t ptepindex, int flags);
-static int _pmap_unwire_pte_hold(pmap_t pmap, vm_offset_t va, vm_page_t m);
-static int pmap_unuse_pt(pmap_t, vm_offset_t, pd_entry_t);
+static int _pmap_unwire_pte_hold(pmap_t pmap, vm_offset_t va, vm_page_t m,
+                vm_page_t* free);
+static int pmap_unuse_pt(pmap_t, vm_offset_t, pd_entry_t, vm_page_t *);
 static vm_offset_t pmap_kmem_choose(vm_offset_t addr);
 
 CTASSERT(1 << PDESHIFT == sizeof(pd_entry_t));
@@ -388,38 +397,38 @@
 }
 
 static u_int64_t
-allocpages(int n)
+allocpages(vm_paddr_t *firstaddr, int n)
 {
 	u_int64_t ret;
 
-	ret = avail_start;
+	ret = *firstaddr;
 	bzero((void *)ret, n * PAGE_SIZE);
-	avail_start += n * PAGE_SIZE;
+	*firstaddr += n * PAGE_SIZE;
 	return (ret);
 }
 
 static void
-create_pagetables(void)
+create_pagetables(vm_paddr_t *firstaddr)
 {
 	int i;
 
 	/* Allocate pages */
-	KPTphys = allocpages(NKPT);
-	KPML4phys = allocpages(1);
-	KPDPphys = allocpages(NKPML4E);
-	KPDphys = allocpages(NKPDPE);
+	KPTphys = allocpages(firstaddr, NKPT);
+	KPML4phys = allocpages(firstaddr, 1);
+	KPDPphys = allocpages(firstaddr, NKPML4E);
+	KPDphys = allocpages(firstaddr, NKPDPE);
 
 	ndmpdp = (ptoa(Maxmem) + NBPDP - 1) >> PDPSHIFT;
 	if (ndmpdp < 4)		/* Minimum 4GB of dirmap */
 		ndmpdp = 4;
-	DMPDPphys = allocpages(NDMPML4E);
-	DMPDphys = allocpages(ndmpdp);
+	DMPDPphys = allocpages(firstaddr, NDMPML4E);
+	DMPDphys = allocpages(firstaddr, ndmpdp);
 	dmaplimit = (vm_paddr_t)ndmpdp << PDPSHIFT;
 
 	/* Fill in the underlying page table pages */
 	/* Read-only from zero to physfree */
 	/* XXX not fully used, underneath 2M pages */
-	for (i = 0; (i << PAGE_SHIFT) < avail_start; i++) {
+	for (i = 0; (i << PAGE_SHIFT) < *firstaddr; i++) {
 		((pt_entry_t *)KPTphys)[i] = i << PAGE_SHIFT;
 		((pt_entry_t *)KPTphys)[i] |= PG_RW | PG_V | PG_G;
 	}
@@ -432,7 +441,7 @@
 
 	/* Map from zero to end of allocations under 2M pages */
 	/* This replaces some of the KPTphys entries above */
-	for (i = 0; (i << PDRSHIFT) < avail_start; i++) {
+	for (i = 0; (i << PDRSHIFT) < *firstaddr; i++) {
 		((pd_entry_t *)KPDphys)[i] = i << PDRSHIFT;
 		((pd_entry_t *)KPDphys)[i] |= PG_RW | PG_V | PG_PS | PG_G;
 	}
@@ -480,21 +489,17 @@
  *	(physical) address starting relative to 0]
  */
 void
-pmap_bootstrap(firstaddr)
-	vm_paddr_t *firstaddr;
+pmap_bootstrap(vm_paddr_t *firstaddr)
 {
 	vm_offset_t va;
 	pt_entry_t *pte, *unused;
 
-	avail_start = *firstaddr;
-
 	/*
 	 * Create an initial set of page tables to run the kernel in.
 	 */
-	create_pagetables();
-	*firstaddr = avail_start;
+	create_pagetables(firstaddr);
 
-	virtual_avail = (vm_offset_t) KERNBASE + avail_start;
+	virtual_avail = (vm_offset_t) KERNBASE + *firstaddr;
 	virtual_avail = pmap_kmem_choose(virtual_avail);
 
 	virtual_end = VM_MAX_KERNEL_ADDRESS;
@@ -510,7 +515,7 @@
 	PMAP_LOCK_INIT(kernel_pmap);
 	kernel_pmap->pm_pml4 = (pdp_entry_t *) (KERNBASE + KPML4phys);
 	kernel_pmap->pm_active = -1;	/* don't allow deactivation */
-	TAILQ_INIT(&kernel_pmap->pm_pvlist);
+	TAILQ_INIT(&kernel_pmap->pm_pvchunk);
 	nkpt = NKPT;
 
 	/*
@@ -543,6 +548,51 @@
 	*CMAP1 = 0;
 
 	invltlb();
+
+	/* Initialize the PAT MSR. */
+	pmap_init_pat();
+}
+
+/*
+ * Setup the PAT MSR.
+ */
+void
+pmap_init_pat(void)
+{
+	uint64_t pat_msr;
+
+	/* Bail if this CPU doesn't implement PAT. */
+	if (!(cpu_feature & CPUID_PAT))
+		panic("no PAT??");
+
+#ifdef PAT_WORKS
+	/*
+	 * Leave the indices 0-3 at the default of WB, WT, UC, and UC-.
+	 * Program 4 and 5 as WP and WC.
+	 * Leave 6 and 7 as UC and UC-.
+	 */
+	pat_msr = rdmsr(MSR_PAT);
+	pat_msr &= ~(PAT_MASK(4) | PAT_MASK(5));
+	pat_msr |= PAT_VALUE(4, PAT_WRITE_PROTECTED) |
+	    PAT_VALUE(5, PAT_WRITE_COMBINING);
+#else
+	/*
+	 * Due to some Intel errata, we can only safely use the lower 4
+	 * PAT entries.  Thus, just replace PAT Index 2 with WC instead
+	 * of UC-.
+	 *
+	 *   Intel Pentium III Processor Specification Update
+	 * Errata E.27 (Upper Four PAT Entries Not Usable With Mode B
+	 * or Mode C Paging)
+	 *
+	 *   Intel Pentium IV  Processor Specification Update
+	 * Errata N46 (PAT Index MSB May Be Calculated Incorrectly)
+	 */
+	pat_msr = rdmsr(MSR_PAT);
+	pat_msr &= ~PAT_MASK(2);
+	pat_msr |= PAT_VALUE(2, PAT_WRITE_COMBINING);
+#endif
+	wrmsr(MSR_PAT, pat_msr);
 }
 
 /*
@@ -564,69 +614,151 @@
 void
 pmap_init(void)
 {
-	int shpgperproc = PMAP_SHPGPERPROC;
 
 	/*
 	 * Initialize the address space (zone) for the pv entries.  Set a
 	 * high water mark so that the system can recover from excessive
 	 * numbers of pv entries.
 	 */
-	pvzone = uma_zcreate("PV ENTRY", sizeof(struct pv_entry), NULL, NULL, 
-	    NULL, NULL, UMA_ALIGN_PTR, UMA_ZONE_VM | UMA_ZONE_NOFREE);
 	TUNABLE_INT_FETCH("vm.pmap.shpgperproc", &shpgperproc);
 	pv_entry_max = shpgperproc * maxproc + cnt.v_page_count;
 	TUNABLE_INT_FETCH("vm.pmap.pv_entries", &pv_entry_max);
 	pv_entry_high_water = 9 * (pv_entry_max / 10);
-	uma_zone_set_obj(pvzone, &pvzone_obj, pv_entry_max);
 }
 
-void
-pmap_init2()
+SYSCTL_NODE(_vm, OID_AUTO, pmap, CTLFLAG_RD, 0, "VM/pmap parameters");
+static int
+pmap_pventry_proc(SYSCTL_HANDLER_ARGS)
+{
+	int error;
+
+	error = sysctl_handle_int(oidp, oidp->oid_arg1, oidp->oid_arg2, req);
+	if (error == 0 && req->newptr) {
+		shpgperproc = (pv_entry_max - cnt.v_page_count) / maxproc;
+		pv_entry_high_water = 9 * (pv_entry_max / 10);
+	}
+	return (error);
+}
+SYSCTL_PROC(_vm_pmap, OID_AUTO, pv_entry_max, CTLTYPE_INT|CTLFLAG_RW, 
+    &pv_entry_max, 0, pmap_pventry_proc, "IU", "Max number of PV entries");
+
+static int
+pmap_shpgperproc_proc(SYSCTL_HANDLER_ARGS)
 {
+	int error;
+
+	error = sysctl_handle_int(oidp, oidp->oid_arg1, oidp->oid_arg2, req);
+	if (error == 0 && req->newptr) {
+		pv_entry_max = shpgperproc * maxproc + cnt.v_page_count;
+		pv_entry_high_water = 9 * (pv_entry_max / 10);
+	}
+	return (error);
 }
+SYSCTL_PROC(_vm_pmap, OID_AUTO, shpgperproc, CTLTYPE_INT|CTLFLAG_RW, 
+    &shpgperproc, 0, pmap_shpgperproc_proc, "IU", "Page share factor per proc");
 
 
 /***************************************************
  * Low level helper routines.....
  ***************************************************/
 
-#if defined(PMAP_DIAGNOSTIC)
-
 /*
- * This code checks for non-writeable/modified pages.
- * This should be an invalid condition.
+ * Determine the appropriate bits to set in a PTE or PDE for a specified
+ * caching mode.
  */
 static int
-pmap_nw_modified(pt_entry_t ptea)
+pmap_cache_bits(int mode, boolean_t is_pde)
 {
-	int pte;
+	int pat_flag, pat_index, cache_bits;
 
-	pte = (int) ptea;
+	/* The PAT bit is different for PTE's and PDE's. */
+	pat_flag = is_pde ? PG_PDE_PAT : PG_PTE_PAT;
 
-	if ((pte & (PG_M|PG_RW)) == PG_M)
-		return 1;
-	else
-		return 0;
-}
+	/* If we don't support PAT, map extended modes to older ones. */
+	if (!(cpu_feature & CPUID_PAT)) {
+		switch (mode) {
+		case PAT_UNCACHEABLE:
+		case PAT_WRITE_THROUGH:
+		case PAT_WRITE_BACK:
+			break;
+		case PAT_UNCACHED:
+		case PAT_WRITE_COMBINING:
+		case PAT_WRITE_PROTECTED:
+			mode = PAT_UNCACHEABLE;
+			break;
+		}
+	}
+	
+	/* Map the caching mode to a PAT index. */
+	switch (mode) {
+#ifdef PAT_WORKS
+	case PAT_UNCACHEABLE:
+		pat_index = 3;
+		break;
+	case PAT_WRITE_THROUGH:
+		pat_index = 1;
+		break;
+	case PAT_WRITE_BACK:
+		pat_index = 0;
+		break;
+	case PAT_UNCACHED:
+		pat_index = 2;
+		break;
+	case PAT_WRITE_COMBINING:
+		pat_index = 5;
+		break;
+	case PAT_WRITE_PROTECTED:
+		pat_index = 4;
+		break;
+#else
+	case PAT_UNCACHED:
+	case PAT_UNCACHEABLE:
+	case PAT_WRITE_PROTECTED:
+		pat_index = 3;
+		break;
+	case PAT_WRITE_THROUGH:
+		pat_index = 1;
+		break;
+	case PAT_WRITE_BACK:
+		pat_index = 0;
+		break;
+	case PAT_WRITE_COMBINING:
+		pat_index = 2;
+		break;
 #endif
-
-
-/*
- * this routine defines the region(s) of memory that should
- * not be tested for the modified bit.
- */
-static PMAP_INLINE int
-pmap_track_modified(vm_offset_t va)
-{
-	if ((va < kmi.clean_sva) || (va >= kmi.clean_eva)) 
-		return 1;
-	else
-		return 0;
+	default:
+		panic("Unknown caching mode %d\n", mode);
+	}	
+
+	/* Map the 3-bit index value into the PAT, PCD, and PWT bits. */
+	cache_bits = 0;
+	if (pat_index & 0x4)
+		cache_bits |= pat_flag;
+	if (pat_index & 0x2)
+		cache_bits |= PG_NC_PCD;
+	if (pat_index & 0x1)
+		cache_bits |= PG_NC_PWT;
+	return (cache_bits);
 }
-
 #ifdef SMP
 /*
  * For SMP, these functions have to use the IPI mechanism for coherence.
+ *
+ * N.B.: Before calling any of the following TLB invalidation functions,
+ * the calling processor must ensure that all stores updating a non-
+ * kernel page table are globally performed.  Otherwise, another
+ * processor could cache an old, pre-update entry without being
+ * invalidated.  This can happen one of two ways: (1) The pmap becomes
+ * active on another processor after its pm_active field is checked by
+ * one of the following functions but before a store updating the page
+ * table is globally performed. (2) The pmap becomes active on another
+ * processor before its pm_active field is checked but due to
+ * speculative loads one of the following functions stills reads the
+ * pmap as inactive on the other processor.
+ * 
+ * The kernel page table is exempt because its pm_active field is
+ * immutable.  The kernel page table is always active on every
+ * processor.
  */
 void
 pmap_invalidate_page(pmap_t pmap, vm_offset_t va)
@@ -634,18 +766,7 @@
 	u_int cpumask;
 	u_int other_cpus;
 
-	if (smp_started) {
-		if (!(read_rflags() & PSL_I))
-			panic("%s: interrupts disabled", __func__);
-		mtx_lock_spin(&smp_ipi_mtx);
-	} else
-		critical_enter();
-	/*
-	 * We need to disable interrupt preemption but MUST NOT have
-	 * interrupts disabled here.
-	 * XXX we may need to hold schedlock to get a coherent pm_active
-	 * XXX critical sections disable interrupts again
-	 */
+	sched_pin();
 	if (pmap == kernel_pmap || pmap->pm_active == all_cpus) {
 		invlpg(va);
 		smp_invlpg(va);
@@ -657,10 +778,7 @@
 		if (pmap->pm_active & other_cpus)
 			smp_masked_invlpg(pmap->pm_active & other_cpus, va);
 	}
-	if (smp_started)
-		mtx_unlock_spin(&smp_ipi_mtx);
-	else
-		critical_exit();
+	sched_unpin();
 }
 
 void
@@ -670,18 +788,7 @@
 	u_int other_cpus;
 	vm_offset_t addr;
 
-	if (smp_started) {
-		if (!(read_rflags() & PSL_I))
-			panic("%s: interrupts disabled", __func__);
-		mtx_lock_spin(&smp_ipi_mtx);
-	} else
-		critical_enter();
-	/*
-	 * We need to disable interrupt preemption but MUST NOT have
-	 * interrupts disabled here.
-	 * XXX we may need to hold schedlock to get a coherent pm_active
-	 * XXX critical sections disable interrupts again
-	 */
+	sched_pin();
 	if (pmap == kernel_pmap || pmap->pm_active == all_cpus) {
 		for (addr = sva; addr < eva; addr += PAGE_SIZE)
 			invlpg(addr);
@@ -696,10 +803,7 @@
 			smp_masked_invlpg_range(pmap->pm_active & other_cpus,
 			    sva, eva);
 	}
-	if (smp_started)
-		mtx_unlock_spin(&smp_ipi_mtx);
-	else
-		critical_exit();
+	sched_unpin();
 }
 
 void
@@ -708,18 +812,7 @@
 	u_int cpumask;
 	u_int other_cpus;
 
-	if (smp_started) {
-		if (!(read_rflags() & PSL_I))
-			panic("%s: interrupts disabled", __func__);
-		mtx_lock_spin(&smp_ipi_mtx);
-	} else
-		critical_enter();
-	/*
-	 * We need to disable interrupt preemption but MUST NOT have
-	 * interrupts disabled here.
-	 * XXX we may need to hold schedlock to get a coherent pm_active
-	 * XXX critical sections disable interrupts again
-	 */
+	sched_pin();
 	if (pmap == kernel_pmap || pmap->pm_active == all_cpus) {
 		invltlb();
 		smp_invltlb();
@@ -731,10 +824,17 @@
 		if (pmap->pm_active & other_cpus)
 			smp_masked_invltlb(pmap->pm_active & other_cpus);
 	}
-	if (smp_started)
-		mtx_unlock_spin(&smp_ipi_mtx);
-	else
-		critical_exit();
+	sched_unpin();
+}
+
+void
+pmap_invalidate_cache(void)
+{
+
+	sched_pin();
+	wbinvd();
+	smp_cache_flush();
+	sched_unpin();
 }
 #else /* !SMP */
 /*
@@ -766,6 +866,13 @@
 	if (pmap == kernel_pmap || pmap->pm_active)
 		invltlb();
 }
+
+PMAP_INLINE void
+pmap_invalidate_cache(void)
+{
+
+	wbinvd();
+}
 #endif /* !SMP */
 
 /*
@@ -798,9 +905,7 @@
 		pde = *pdep;
 		if (pde) {
 			if ((pde & PG_PS) != 0) {
-				KASSERT((pde & PG_FRAME & PDRMASK) == 0,
-				    ("pmap_extract: bad pde"));
-				rtval = (pde & PG_FRAME) | (va & PDRMASK);
+				rtval = (pde & PG_PS_FRAME) | (va & PDRMASK);
 				PMAP_UNLOCK(pmap);
 				return rtval;
 			}
@@ -833,9 +938,7 @@
 	if (pdep != NULL && (pde = *pdep)) {
 		if (pde & PG_PS) {
 			if ((pde & PG_RW) || (prot & VM_PROT_WRITE) == 0) {
-				KASSERT((pde & PG_FRAME & PDRMASK) == 0,
-				    ("pmap_extract_and_hold: bad pde"));
-				m = PHYS_TO_VM_PAGE((pde & PG_FRAME) |
+				m = PHYS_TO_VM_PAGE((pde & PG_PS_FRAME) |
 				    (va & PDRMASK));
 				vm_page_hold(m);
 			}
@@ -864,7 +967,7 @@
 	} else {
 		pde = vtopde(va);
 		if (*pde & PG_PS) {
-			pa = (*pde & ~(NBPDR - 1)) | (va & (NBPDR - 1));
+			pa = (*pde & PG_PS_FRAME) | (va & PDRMASK);
 		} else {
 			pa = *vtopte(va);
 			pa = (pa & PG_FRAME) | (va & PAGE_MASK);
@@ -890,6 +993,15 @@
 	pte_store(pte, pa | PG_RW | PG_V | PG_G);
 }
 
+PMAP_INLINE void 
+pmap_kenter_attr(vm_offset_t va, vm_paddr_t pa, int mode)
+{
+	pt_entry_t *pte;
+
+	pte = vtopte(va);
+	pte_store(pte, pa | PG_RW | PG_V | PG_G | pmap_cache_bits(mode, 0));
+}
+
 /*
  * Remove a page from the kernel pagetables.
  * Note: not SMP coherent.
@@ -932,17 +1044,22 @@
  * Note: SMP coherent.  Uses a ranged shootdown IPI.
  */
 void
-pmap_qenter(vm_offset_t sva, vm_page_t *m, int count)
+pmap_qenter(vm_offset_t sva, vm_page_t *ma, int count)
 {
-	vm_offset_t va;
+	pt_entry_t *endpte, oldpte, *pte;
 
-	va = sva;
-	while (count-- > 0) {
-		pmap_kenter(va, VM_PAGE_TO_PHYS(*m));
-		va += PAGE_SIZE;
-		m++;
-	}
-	pmap_invalidate_range(kernel_pmap, sva, va);
+	oldpte = 0;
+	pte = vtopte(sva);
+	endpte = pte + count;
+	while (pte < endpte) {
+		oldpte |= *pte;
+		pte_store(pte, VM_PAGE_TO_PHYS(*ma) | PG_G | PG_RW | PG_V);
+		pte++;
+		ma++;
+	}
+	if ((oldpte & PG_V) != 0)
+		pmap_invalidate_range(kernel_pmap, sva, sva + count *
+		    PAGE_SIZE);
 }
 
 /*
@@ -966,24 +1083,36 @@
 /***************************************************
  * Page table page management routines.....
  ***************************************************/
+static __inline void
+pmap_free_zero_pages(vm_page_t free)
+{
+	vm_page_t m;
+
+	while (free != NULL) {
+		m = free;
+		free = m->right;
+		vm_page_free_zero(m);
+	}
+}
 
 /*
  * This routine unholds page table pages, and if the hold count
  * drops to zero, then it decrements the wire count.
  */
-static PMAP_INLINE int
-pmap_unwire_pte_hold(pmap_t pmap, vm_offset_t va, vm_page_t m)
+static __inline int
+pmap_unwire_pte_hold(pmap_t pmap, vm_offset_t va, vm_page_t m, vm_page_t *free)
 {
 
 	--m->wire_count;
 	if (m->wire_count == 0)
-		return _pmap_unwire_pte_hold(pmap, va, m);
+		return _pmap_unwire_pte_hold(pmap, va, m, free);
 	else
 		return 0;
 }
 
 static int 
-_pmap_unwire_pte_hold(pmap_t pmap, vm_offset_t va, vm_page_t m)
+_pmap_unwire_pte_hold(pmap_t pmap, vm_offset_t va, vm_page_t m, 
+    vm_page_t *free)
 {
 	vm_offset_t pteva;
 
@@ -1015,24 +1144,36 @@
 		vm_page_t pdpg;
 
 		pdpg = PHYS_TO_VM_PAGE(*pmap_pdpe(pmap, va) & PG_FRAME);
-		pmap_unwire_pte_hold(pmap, va, pdpg);
+		pmap_unwire_pte_hold(pmap, va, pdpg, free);
 	}
 	if (m->pindex >= NUPDE && m->pindex < (NUPDE + NUPDPE)) {
 		/* We just released a PD, unhold the matching PDP */
 		vm_page_t pdppg;
 
 		pdppg = PHYS_TO_VM_PAGE(*pmap_pml4e(pmap, va) & PG_FRAME);
-		pmap_unwire_pte_hold(pmap, va, pdppg);
+		pmap_unwire_pte_hold(pmap, va, pdppg, free);
 	}
 
 	/*
+	 * This is a release store so that the ordinary store unmapping
+	 * the page table page is globally performed before TLB shoot-
+	 * down is begun.
+	 */
+	atomic_subtract_rel_int(&cnt.v_wire_count, 1);
+
+	/*
 	 * Do an invltlb to make the invalidated mapping
 	 * take effect immediately.
 	 */
 	pmap_invalidate_page(pmap, pteva);
 
-	vm_page_free_zero(m);
-	atomic_subtract_int(&cnt.v_wire_count, 1);
+	/* 
+	 * Put page on a list so that it is released after
+	 * *ALL* TLB shootdown is done
+	 */
+	m->right = *free;
+	*free = m;
+	
 	return 1;
 }
 
@@ -1041,7 +1182,7 @@
  * conditionally free the page, and manage the hold/wire counts.
  */
 static int
-pmap_unuse_pt(pmap_t pmap, vm_offset_t va, pd_entry_t ptepde)
+pmap_unuse_pt(pmap_t pmap, vm_offset_t va, pd_entry_t ptepde, vm_page_t *free)
 {
 	vm_page_t mpte;
 
@@ -1049,18 +1190,17 @@
 		return 0;
 	KASSERT(ptepde != 0, ("pmap_unuse_pt: ptepde != 0"));
 	mpte = PHYS_TO_VM_PAGE(ptepde & PG_FRAME);
-	return pmap_unwire_pte_hold(pmap, va, mpte);
+	return pmap_unwire_pte_hold(pmap, va, mpte, free);
 }
 
 void
-pmap_pinit0(pmap)
-	struct pmap *pmap;
+pmap_pinit0(pmap_t pmap)
 {
 
 	PMAP_LOCK_INIT(pmap);
 	pmap->pm_pml4 = (pml4_entry_t *)(KERNBASE + KPML4phys);
 	pmap->pm_active = 0;
-	TAILQ_INIT(&pmap->pm_pvlist);
+	TAILQ_INIT(&pmap->pm_pvchunk);
 	bzero(&pmap->pm_stats, sizeof pmap->pm_stats);
 }
 
@@ -1068,9 +1208,8 @@
  * Initialize a preallocated and zeroed pmap structure,
  * such as one in a vmspace structure.
  */
-void
-pmap_pinit(pmap)
-	register struct pmap *pmap;
+int
+pmap_pinit(pmap_t pmap)
 {
 	vm_page_t pml4pg;
 	static vm_pindex_t color;
@@ -1097,8 +1236,10 @@
 	pmap->pm_pml4[PML4PML4I] = VM_PAGE_TO_PHYS(pml4pg) | PG_V | PG_RW | PG_A | PG_M;
 
 	pmap->pm_active = 0;
-	TAILQ_INIT(&pmap->pm_pvlist);
+	TAILQ_INIT(&pmap->pm_pvchunk);
 	bzero(&pmap->pm_stats, sizeof pmap->pm_stats);
+
+	return (1);
 }
 
 /*
@@ -1269,7 +1410,7 @@
 {
 	vm_pindex_t ptepindex;
 	pd_entry_t *pd;
-	vm_page_t m;
+	vm_page_t m, free;
 
 	KASSERT((flags & (M_NOWAIT | M_WAITOK)) == M_NOWAIT ||
 	    (flags & (M_NOWAIT | M_WAITOK)) == M_WAITOK,
@@ -1293,8 +1434,10 @@
 		*pd = 0;
 		pd = 0;
 		pmap->pm_stats.resident_count -= NBPDR / PAGE_SIZE;
-		pmap_unuse_pt(pmap, va, *pmap_pdpe(pmap, va));
+		free = NULL;
+		pmap_unuse_pt(pmap, va, *pmap_pdpe(pmap, va), &free);
 		pmap_invalidate_all(kernel_pmap);
+		pmap_free_zero_pages(free);
 	}
 
 	/*
@@ -1341,11 +1484,9 @@
 	pmap->pm_pml4[DMPML4I] = 0;	/* Direct Map */
 	pmap->pm_pml4[PML4PML4I] = 0;	/* Recursive Mapping */
 
-	vm_page_lock_queues();
 	m->wire_count--;
 	atomic_subtract_int(&cnt.v_wire_count, 1);
 	vm_page_free_zero(m);
-	vm_page_unlock_queues();
 	PMAP_LOCK_DESTROY(pmap);
 }
 

@@ -1357,7 +1498,7 @@
 	return sysctl_handle_long(oidp, &ksize, 0, req);
 }
 SYSCTL_PROC(_vm, OID_AUTO, kvm_size, CTLTYPE_LONG|CTLFLAG_RD, 
-    0, 0, kvm_size, "IU", "Size of KVM");
+    0, 0, kvm_size, "LU", "Size of KVM");
 
 static int
 kvm_free(SYSCTL_HANDLER_ARGS)
@@ -1367,7 +1508,7 @@
 	return sysctl_handle_long(oidp, &kfree, 0, req);
 }
 SYSCTL_PROC(_vm, OID_AUTO, kvm_free, CTLTYPE_LONG|CTLFLAG_RD, 
-    0, 0, kvm_free, "IU", "Amount of KVM free");
+    0, 0, kvm_free, "LU", "Amount of KVM free");
 
 /*
  * grow the number of kernel page table entries, if needed
@@ -1387,9 +1528,15 @@
 		while ((*pmap_pde(kernel_pmap, kernel_vm_end) & PG_V) != 0) {
 			kernel_vm_end = (kernel_vm_end + PAGE_SIZE * NPTEPG) & ~(PAGE_SIZE * NPTEPG - 1);
 			nkpt++;
+			if (kernel_vm_end - 1 >= kernel_map->max_offset) {
+				kernel_vm_end = kernel_map->max_offset;
+				break;                       
+			}
 		}
 	}
 	addr = roundup2(addr, PAGE_SIZE * NPTEPG);
+	if (addr - 1 >= kernel_map->max_offset)
+		addr = kernel_map->max_offset;
 	while (kernel_vm_end < addr) {
 		pde = pmap_pde(kernel_pmap, kernel_vm_end);
 		if (pde == NULL) {
@@ -1407,6 +1554,10 @@
 		}
 		if ((*pde & PG_V) != 0) {
 			kernel_vm_end = (kernel_vm_end + PAGE_SIZE * NPTEPG) & ~(PAGE_SIZE * NPTEPG - 1);
+			if (kernel_vm_end - 1 >= kernel_map->max_offset) {
+				kernel_vm_end = kernel_map->max_offset;
+				break;                       
+			}
 			continue;
 		}
 
@@ -1426,6 +1577,10 @@
 		*pmap_pde(kernel_pmap, kernel_vm_end) = newpdir;
 
 		kernel_vm_end = (kernel_vm_end + PAGE_SIZE * NPTEPG) & ~(PAGE_SIZE * NPTEPG - 1);
+		if (kernel_vm_end - 1 >= kernel_map->max_offset) {
+			kernel_vm_end = kernel_map->max_offset;
+			break;                       
+		}
 	}
 }
 
@@ -1434,35 +1589,239 @@
  * page management routines.
  ***************************************************/
 
+CTASSERT(sizeof(struct pv_chunk) == PAGE_SIZE);
+CTASSERT(_NPCM == 3);
+CTASSERT(_NPCPV == 168);
+
+static __inline struct pv_chunk *
+pv_to_chunk(pv_entry_t pv)
+{
+
+	return (struct pv_chunk *)((uintptr_t)pv & ~(uintptr_t)PAGE_MASK);
+}
+
+#define PV_PMAP(pv) (pv_to_chunk(pv)->pc_pmap)
+
+#define	PC_FREE0	0xfffffffffffffffful
+#define	PC_FREE1	0xfffffffffffffffful
+#define	PC_FREE2	0x000000fffffffffful
+
+static uint64_t pc_freemask[_NPCM] = { PC_FREE0, PC_FREE1, PC_FREE2 };
+
+SYSCTL_INT(_vm_pmap, OID_AUTO, pv_entry_count, CTLFLAG_RD, &pv_entry_count, 0,
+	"Current number of pv entries");
+
+#ifdef PV_STATS
+static int pc_chunk_count, pc_chunk_allocs, pc_chunk_frees, pc_chunk_tryfail;
+
+SYSCTL_INT(_vm_pmap, OID_AUTO, pc_chunk_count, CTLFLAG_RD, &pc_chunk_count, 0,
+	"Current number of pv entry chunks");
+SYSCTL_INT(_vm_pmap, OID_AUTO, pc_chunk_allocs, CTLFLAG_RD, &pc_chunk_allocs, 0,
+	"Current number of pv entry chunks allocated");
+SYSCTL_INT(_vm_pmap, OID_AUTO, pc_chunk_frees, CTLFLAG_RD, &pc_chunk_frees, 0,
+	"Current number of pv entry chunks frees");
+SYSCTL_INT(_vm_pmap, OID_AUTO, pc_chunk_tryfail, CTLFLAG_RD, &pc_chunk_tryfail, 0,
+	"Number of times tried to get a chunk page but failed.");
+
+static long pv_entry_frees, pv_entry_allocs;
+static int pv_entry_spare;
+
+SYSCTL_LONG(_vm_pmap, OID_AUTO, pv_entry_frees, CTLFLAG_RD, &pv_entry_frees, 0,
+	"Current number of pv entry frees");
+SYSCTL_LONG(_vm_pmap, OID_AUTO, pv_entry_allocs, CTLFLAG_RD, &pv_entry_allocs, 0,
+	"Current number of pv entry allocs");
+SYSCTL_INT(_vm_pmap, OID_AUTO, pv_entry_spare, CTLFLAG_RD, &pv_entry_spare, 0,
+	"Current number of spare pv entries");
+
+static int pmap_collect_inactive, pmap_collect_active;
+
+SYSCTL_INT(_vm_pmap, OID_AUTO, pmap_collect_inactive, CTLFLAG_RD, &pmap_collect_inactive, 0,
+	"Current number times pmap_collect called on inactive queue");
+SYSCTL_INT(_vm_pmap, OID_AUTO, pmap_collect_active, CTLFLAG_RD, &pmap_collect_active, 0,
+	"Current number times pmap_collect called on active queue");
+#endif
+
+/*
+ * We are in a serious low memory condition.  Resort to
+ * drastic measures to free some pages so we can allocate
+ * another pv entry chunk.  This is normally called to
+ * unmap inactive pages, and if necessary, active pages.
+ */
+static void
+pmap_collect(pmap_t locked_pmap, struct vpgqueues *vpq)
+{
+	pd_entry_t ptepde;
+	pmap_t pmap;
+	pt_entry_t *pte, tpte;
+	pv_entry_t next_pv, pv;
+	vm_offset_t va;
+	vm_page_t m, free;
+
+	TAILQ_FOREACH(m, &vpq->pl, pageq) {
+		if (m->hold_count || m->busy)
+			continue;
+		TAILQ_FOREACH_SAFE(pv, &m->md.pv_list, pv_list, next_pv) {
+			va = pv->pv_va;
+			pmap = PV_PMAP(pv);
+			/* Avoid deadlock and lock recursion. */
+			if (pmap > locked_pmap)
+				PMAP_LOCK(pmap);
+			else if (pmap != locked_pmap && !PMAP_TRYLOCK(pmap))
+				continue;
+			pmap->pm_stats.resident_count--;
+			pte = pmap_pte_pde(pmap, va, &ptepde);
+			if (pte == NULL) {
+				panic("null pte in pmap_collect");
+			}
+			tpte = pte_load_clear(pte);
+			KASSERT((tpte & PG_W) == 0,
+			    ("pmap_collect: wired pte %#lx", tpte));
+			if (tpte & PG_A)
+				vm_page_flag_set(m, PG_REFERENCED);
+			if (tpte & PG_M) {
+				KASSERT((tpte & PG_RW),
+	("pmap_collect: modified page not writable: va: %#lx, pte: %#lx",
+				    va, tpte));
+				vm_page_dirty(m);
+			}
+			free = NULL;
+			pmap_unuse_pt(pmap, va, ptepde, &free);
+			pmap_invalidate_page(pmap, va);
+			pmap_free_zero_pages(free);
+			TAILQ_REMOVE(&m->md.pv_list, pv, pv_list);
+			if (TAILQ_EMPTY(&m->md.pv_list))
+				vm_page_flag_clear(m, PG_WRITEABLE);
+			m->md.pv_list_count--;
+			free_pv_entry(pmap, pv);
+			if (pmap != locked_pmap)
+				PMAP_UNLOCK(pmap);
+		}
+	}
+}
+
+
 /*
  * free the pv_entry back to the free list
  */
-static PMAP_INLINE void
-free_pv_entry(pv_entry_t pv)
+static void
+free_pv_entry(pmap_t pmap, pv_entry_t pv)
 {
+	vm_page_t m;
+	struct pv_chunk *pc;
+	int idx, field, bit;
+
+	mtx_assert(&vm_page_queue_mtx, MA_OWNED);
+	PMAP_LOCK_ASSERT(pmap, MA_OWNED);
+	PV_STAT(pv_entry_frees++);
+	PV_STAT(pv_entry_spare++);
 	pv_entry_count--;
-	uma_zfree(pvzone, pv);
+	pc = pv_to_chunk(pv);
+	idx = pv - &pc->pc_pventry[0];
+	field = idx / 64;
+	bit = idx % 64;
+	pc->pc_map[field] |= 1ul << bit;
+	/* move to head of list */
+	TAILQ_REMOVE(&pmap->pm_pvchunk, pc, pc_list);
+	TAILQ_INSERT_HEAD(&pmap->pm_pvchunk, pc, pc_list);
+	if (pc->pc_map[0] != PC_FREE0 || pc->pc_map[1] != PC_FREE1 ||
+	    pc->pc_map[2] != PC_FREE2)
+		return;
+	PV_STAT(pv_entry_spare -= _NPCPV);
+	PV_STAT(pc_chunk_count--);
+	PV_STAT(pc_chunk_frees++);
+	/* entire chunk is free, return it */
+	TAILQ_REMOVE(&pmap->pm_pvchunk, pc, pc_list);
+	m = PHYS_TO_VM_PAGE(DMAP_TO_PHYS((vm_offset_t)pc));
+	dump_drop_page(m->phys_addr);
+	vm_page_free(m);
 }
 
 /*
  * get a new pv_entry, allocating a block from the system
  * when needed.
- * the memory allocation is performed bypassing the malloc code
- * because of the possibility of allocations at interrupt time.
  */
 static pv_entry_t
-get_pv_entry(void)
+get_pv_entry(pmap_t pmap, int try)
 {
+	static const struct timeval printinterval = { 60, 0 };
+	static struct timeval lastprint;
+	static vm_pindex_t colour;
+	int bit, field;
+	pv_entry_t pv;
+	struct pv_chunk *pc;
+	vm_page_t m;
+
+	PMAP_LOCK_ASSERT(pmap, MA_OWNED);
+	mtx_assert(&vm_page_queue_mtx, MA_OWNED);
+	PV_STAT(pv_entry_allocs++);
 	pv_entry_count++;
-	if ((pv_entry_count > pv_entry_high_water) &&
-		(pmap_pagedaemon_waken == 0)) {
-		pmap_pagedaemon_waken = 1;
-		wakeup (&vm_pages_needed);
+	if (pv_entry_count > pv_entry_high_water)
+		if (ratecheck(&lastprint, &printinterval))
+			printf("Approaching the limit on PV entries, consider "
+			    "increasing either the vm.pmap.shpgperproc or the "
+			    "vm.pmap.pv_entry_max sysctl.\n");
+	pc = TAILQ_FIRST(&pmap->pm_pvchunk);
+	if (pc != NULL) {
+		for (field = 0; field < _NPCM; field++) {
+			if (pc->pc_map[field]) {
+				bit = bsfq(pc->pc_map[field]);
+				break;
+			}
+		}
+		if (field < _NPCM) {
+			pv = &pc->pc_pventry[field * 64 + bit];
+			pc->pc_map[field] &= ~(1ul << bit);
+			/* If this was the last item, move it to tail */
+			if (pc->pc_map[0] == 0 && pc->pc_map[1] == 0 &&
+			    pc->pc_map[2] == 0) {
+				TAILQ_REMOVE(&pmap->pm_pvchunk, pc, pc_list);
+				TAILQ_INSERT_TAIL(&pmap->pm_pvchunk, pc, pc_list);
+			}
+			PV_STAT(pv_entry_spare--);
+			return (pv);
+		}
 	}
-	return uma_zalloc(pvzone, M_NOWAIT);
+	/* No free items, allocate another chunk */
+	m = vm_page_alloc(NULL, colour, VM_ALLOC_NORMAL | VM_ALLOC_NOOBJ);
+	if (m == NULL) {
+		if (try) {
+			pv_entry_count--;
+			PV_STAT(pc_chunk_tryfail++);
+			return (NULL);
+		}
+		/*
+		 * Reclaim pv entries: At first, destroy mappings to inactive
+		 * pages.  After that, if a pv chunk entry is still needed,
+		 * destroy mappings to active pages.
+		 */
+		PV_STAT(pmap_collect_inactive++);
+		pmap_collect(pmap, &vm_page_queues[PQ_INACTIVE]);
+		m = vm_page_alloc(NULL, colour,
+		    VM_ALLOC_NORMAL | VM_ALLOC_NOOBJ);
+		if (m == NULL) {
+			PV_STAT(pmap_collect_active++);
+			pmap_collect(pmap, &vm_page_queues[PQ_ACTIVE]);
+			m = vm_page_alloc(NULL, colour,
+			    VM_ALLOC_SYSTEM | VM_ALLOC_NOOBJ);
+			if (m == NULL)
+				panic("get_pv_entry: increase vm.pmap.shpgperproc");
+		}
+	}
+	PV_STAT(pc_chunk_count++);
+	PV_STAT(pc_chunk_allocs++);
+	colour++;
+	dump_add_page(m->phys_addr);
+	pc = (void *)PHYS_TO_DMAP(m->phys_addr);
+	pc->pc_pmap = pmap;
+	pc->pc_map[0] = PC_FREE0 & ~1ul;	/* preallocated bit 0 */
+	pc->pc_map[1] = PC_FREE1;
+	pc->pc_map[2] = PC_FREE2;
+	pv = &pc->pc_pventry[0];
+	TAILQ_INSERT_HEAD(&pmap->pm_pvchunk, pc, pc_list);
+	PV_STAT(pv_entry_spare += _NPCPV - 1);
+	return (pv);
 }
 
-
 static void
 pmap_remove_entry(pmap_t pmap, vm_page_t m, vm_offset_t va)
 {
@@ -1470,24 +1829,16 @@
 
 	PMAP_LOCK_ASSERT(pmap, MA_OWNED);
 	mtx_assert(&vm_page_queue_mtx, MA_OWNED);
-	if (m->md.pv_list_count < pmap->pm_stats.resident_count) {
-		TAILQ_FOREACH(pv, &m->md.pv_list, pv_list) {
-			if (pmap == pv->pv_pmap && va == pv->pv_va) 
-				break;
-		}
-	} else {
-		TAILQ_FOREACH(pv, &pmap->pm_pvlist, pv_plist) {
-			if (va == pv->pv_va) 
-				break;
-		}
+	TAILQ_FOREACH(pv, &m->md.pv_list, pv_list) {
+		if (pmap == PV_PMAP(pv) && va == pv->pv_va) 
+			break;
 	}
 	KASSERT(pv != NULL, ("pmap_remove_entry: pv not found"));
 	TAILQ_REMOVE(&m->md.pv_list, pv, pv_list);
 	m->md.pv_list_count--;
 	if (TAILQ_EMPTY(&m->md.pv_list))
 		vm_page_flag_clear(m, PG_WRITEABLE);
-	TAILQ_REMOVE(&pmap->pm_pvlist, pv, pv_plist);
-	free_pv_entry(pv);
+	free_pv_entry(pmap, pv);
 }
 
 /*
@@ -1499,24 +1850,40 @@
 {
 	pv_entry_t pv;
 
-	pv = get_pv_entry();
-	if (pv == NULL)
-		panic("no pv entries: increase vm.pmap.shpgperproc");
-	pv->pv_va = va;
-	pv->pv_pmap = pmap;
-
 	PMAP_LOCK_ASSERT(pmap, MA_OWNED);
 	mtx_assert(&vm_page_queue_mtx, MA_OWNED);
-	TAILQ_INSERT_TAIL(&pmap->pm_pvlist, pv, pv_plist);
+	pv = get_pv_entry(pmap, FALSE);
+	pv->pv_va = va;
 	TAILQ_INSERT_TAIL(&m->md.pv_list, pv, pv_list);
 	m->md.pv_list_count++;
 }
 
 /*
+ * Conditionally create a pv entry.
+ */
+static boolean_t
+pmap_try_insert_pv_entry(pmap_t pmap, vm_offset_t va, vm_page_t m)
+{
+	pv_entry_t pv;
+
+	PMAP_LOCK_ASSERT(pmap, MA_OWNED);
+	mtx_assert(&vm_page_queue_mtx, MA_OWNED);
+	if (pv_entry_count < pv_entry_high_water && 
+	    (pv = get_pv_entry(pmap, TRUE)) != NULL) {
+		pv->pv_va = va;
+		TAILQ_INSERT_TAIL(&m->md.pv_list, pv, pv_list);
+		m->md.pv_list_count++;
+		return (TRUE);
+	} else
+		return (FALSE);
+}
+
+/*
  * pmap_remove_pte: do the things to unmap a page in a process
  */
 static int
-pmap_remove_pte(pmap_t pmap, pt_entry_t *ptq, vm_offset_t va, pd_entry_t ptepde)
+pmap_remove_pte(pmap_t pmap, pt_entry_t *ptq, vm_offset_t va, 
+    pd_entry_t ptepde, vm_page_t *free)
 {
 	pt_entry_t oldpte;
 	vm_page_t m;
@@ -1535,28 +1902,23 @@
 	if (oldpte & PG_MANAGED) {
 		m = PHYS_TO_VM_PAGE(oldpte & PG_FRAME);
 		if (oldpte & PG_M) {
-#if defined(PMAP_DIAGNOSTIC)
-			if (pmap_nw_modified((pt_entry_t) oldpte)) {
-				printf(
-	"pmap_remove: modified page not writable: va: 0x%lx, pte: 0x%lx\n",
-				    va, oldpte);
-			}
-#endif
-			if (pmap_track_modified(va))
-				vm_page_dirty(m);
+			KASSERT((oldpte & PG_RW),
+	("pmap_remove_pte: modified page not writable: va: %#lx, pte: %#lx",
+			    va, oldpte));
+			vm_page_dirty(m);
 		}
 		if (oldpte & PG_A)
 			vm_page_flag_set(m, PG_REFERENCED);
 		pmap_remove_entry(pmap, m, va);
 	}
-	return (pmap_unuse_pt(pmap, va, ptepde));
+	return (pmap_unuse_pt(pmap, va, ptepde, free));
 }
 
 /*
  * Remove a single page from a process address space
  */
 static void
-pmap_remove_page(pmap_t pmap, vm_offset_t va, pd_entry_t *pde)
+pmap_remove_page(pmap_t pmap, vm_offset_t va, pd_entry_t *pde, vm_page_t *free)
 {
 	pt_entry_t *pte;
 
@@ -1566,7 +1928,7 @@
 	pte = pmap_pde_to_pte(pde, va);
 	if ((*pte & PG_V) == 0)
 		return;
-	pmap_remove_pte(pmap, pte, va, *pde);
+	pmap_remove_pte(pmap, pte, va, *pde, free);
 	pmap_invalidate_page(pmap, va);
 }
 
@@ -1584,6 +1946,7 @@
 	pdp_entry_t *pdpe;
 	pd_entry_t ptpaddr, *pde;
 	pt_entry_t *pte;
+	vm_page_t free = NULL;
 	int anyvalid;
 
 	/*
@@ -1605,7 +1968,7 @@
 	if (sva + PAGE_SIZE == eva) {
 		pde = pmap_pde(pmap, sva);
 		if (pde && (*pde & PG_PS) == 0) {
-			pmap_remove_page(pmap, sva, pde);
+			pmap_remove_page(pmap, sva, pde, &free);
 			goto out;
 		}
 	}
@@ -1647,7 +2010,7 @@
 		if ((ptpaddr & PG_PS) != 0) {
 			*pde = 0;
 			pmap->pm_stats.resident_count -= NBPDR / PAGE_SIZE;
-			pmap_unuse_pt(pmap, sva, *pdpe);
+			pmap_unuse_pt(pmap, sva, *pdpe, &free);
 			anyvalid = 1;
 			continue;
 		}
@@ -1664,16 +2027,23 @@
 		    sva += PAGE_SIZE) {
 			if (*pte == 0)
 				continue;
-			anyvalid = 1;
-			if (pmap_remove_pte(pmap, pte, sva, ptpaddr))
+
+			/*
+			 * The TLB entry for a PG_G mapping is invalidated
+			 * by pmap_remove_pte().
+			 */
+			if ((*pte & PG_G) == 0)
+				anyvalid = 1;
+			if (pmap_remove_pte(pmap, pte, sva, ptpaddr, &free))
 				break;
 		}
 	}
 out:
-	vm_page_unlock_queues();
 	if (anyvalid)
 		pmap_invalidate_all(pmap);
+	vm_page_unlock_queues();	
 	PMAP_UNLOCK(pmap);
+	pmap_free_zero_pages(free);
 }
 
 /*
@@ -1692,9 +2062,11 @@
 void
 pmap_remove_all(vm_page_t m)
 {
-	register pv_entry_t pv;
+	pv_entry_t pv;
+	pmap_t pmap;
 	pt_entry_t *pte, tpte;
 	pd_entry_t ptepde;
+	vm_page_t free;
 
 #if defined(PMAP_DIAGNOSTIC)
 	/*
@@ -1707,12 +2079,16 @@
 #endif
 	mtx_assert(&vm_page_queue_mtx, MA_OWNED);
 	while ((pv = TAILQ_FIRST(&m->md.pv_list)) != NULL) {
-		PMAP_LOCK(pv->pv_pmap);
-		pv->pv_pmap->pm_stats.resident_count--;
-		pte = pmap_pte_pde(pv->pv_pmap, pv->pv_va, &ptepde);
+		pmap = PV_PMAP(pv);
+		PMAP_LOCK(pmap);
+		pmap->pm_stats.resident_count--;
+		pte = pmap_pte_pde(pmap, pv->pv_va, &ptepde);
+		if (pte == NULL) {
+			panic("null pte in pmap_remove_all");
+		}
 		tpte = pte_load_clear(pte);
 		if (tpte & PG_W)
-			pv->pv_pmap->pm_stats.wired_count--;
+			pmap->pm_stats.wired_count--;
 		if (tpte & PG_A)
 			vm_page_flag_set(m, PG_REFERENCED);
 
@@ -1720,23 +2096,19 @@
 		 * Update the vm_page_t clean and reference bits.
 		 */
 		if (tpte & PG_M) {
-#if defined(PMAP_DIAGNOSTIC)
-			if (pmap_nw_modified((pt_entry_t) tpte)) {
-				printf(
-	"pmap_remove_all: modified page not writable: va: 0x%lx, pte: 0x%lx\n",
-				    pv->pv_va, tpte);
-			}
-#endif
-			if (pmap_track_modified(pv->pv_va))
-				vm_page_dirty(m);
+			KASSERT((tpte & PG_RW),
+	("pmap_remove_all: modified page not writable: va: %#lx, pte: %#lx",
+			    pv->pv_va, tpte));
+			vm_page_dirty(m);
 		}
-		pmap_invalidate_page(pv->pv_pmap, pv->pv_va);
-		TAILQ_REMOVE(&pv->pv_pmap->pm_pvlist, pv, pv_plist);
+		free = NULL;
+		pmap_unuse_pt(pmap, pv->pv_va, ptepde, &free);
+		pmap_invalidate_page(pmap, pv->pv_va);
+		pmap_free_zero_pages(free);
 		TAILQ_REMOVE(&m->md.pv_list, pv, pv_list);
 		m->md.pv_list_count--;
-		pmap_unuse_pt(pv->pv_pmap, pv->pv_va, ptepde);
-		PMAP_UNLOCK(pv->pv_pmap);
-		free_pv_entry(pv);
+		free_pv_entry(pmap, pv);
+		PMAP_UNLOCK(pmap);
 	}
 	vm_page_flag_clear(m, PG_WRITEABLE);
 }
@@ -1760,7 +2132,8 @@
 		return;
 	}
 
-	if (prot & VM_PROT_WRITE)
+	if ((prot & (VM_PROT_WRITE|VM_PROT_EXECUTE)) ==
+	    (VM_PROT_WRITE|VM_PROT_EXECUTE))
 		return;
 
 	anychanged = 0;
@@ -1796,7 +2169,10 @@
 		 * Check for large page.
 		 */
 		if ((ptpaddr & PG_PS) != 0) {
-			*pde &= ~(PG_M|PG_RW);
+			if ((prot & VM_PROT_WRITE) == 0)
+				*pde &= ~(PG_M|PG_RW);
+			if ((prot & VM_PROT_EXECUTE) == 0)
+				*pde |= pg_nx;
 			anychanged = 1;
 			continue;
 		}
@@ -1811,6 +2187,8 @@
 
 retry:
 			obits = pbits = *pte;
+			if ((pbits & PG_V) == 0)
+				continue;
 			if (pbits & PG_MANAGED) {
 				m = NULL;
 				if (pbits & PG_A) {
@@ -1818,8 +2196,7 @@
 					vm_page_flag_set(m, PG_REFERENCED);
 					pbits &= ~PG_A;
 				}
-				if ((pbits & PG_M) != 0 &&
-				    pmap_track_modified(sva)) {
+				if ((pbits & PG_M) != 0) {
 					if (m == NULL)
 						m = PHYS_TO_VM_PAGE(pbits &
 						    PG_FRAME);
@@ -1827,7 +2204,10 @@
 				}
 			}
 
-			pbits &= ~(PG_RW | PG_M);
+			if ((prot & VM_PROT_WRITE) == 0)
+				pbits &= ~(PG_RW | PG_M);
+			if ((prot & VM_PROT_EXECUTE) == 0)
+				pbits |= pg_nx;
 
 			if (pbits != obits) {
 				if (!atomic_cmpset_long(pte, obits, pbits))
@@ -1839,9 +2219,9 @@
 			}
 		}
 	}
-	vm_page_unlock_queues();
 	if (anychanged)
 		pmap_invalidate_all(pmap);
+	vm_page_unlock_queues();
 	PMAP_UNLOCK(pmap);
 }
 
@@ -1862,7 +2242,8 @@
 	   boolean_t wired)
 {
 	vm_paddr_t pa;
-	register pt_entry_t *pte;
+	pd_entry_t *pde;
+	pt_entry_t *pte;
 	vm_paddr_t opa;
 	pt_entry_t origpte, newpte;
 	vm_page_t mpte, om;
@@ -1899,7 +2280,13 @@
 	}
 #endif
 
-	pte = pmap_pte(pmap, va);
+	pde = pmap_pde(pmap, va);
+	if (pde != NULL) {
+		if ((*pde & PG_PS) != 0)
+			panic("pmap_enter: attempted pmap_enter on 2MB page");
+		pte = pmap_pde_to_pte(pde, va);
+	} else
+		pte = NULL;
 
 	/*
 	 * Page Directory table entry not valid, we need a new PT page
@@ -1912,9 +2299,6 @@
 	origpte = *pte;
 	opa = origpte & PG_FRAME;
 
-	if (origpte & PG_PS)
-		panic("pmap_enter: attempted pmap_enter on 2MB page");
-
 	/*
 	 * Mapping has not changed, must be protection or wiring change.
 	 */
@@ -1970,6 +2354,8 @@
 	 * Enter on the PV list if part of our managed memory.
 	 */
 	if ((m->flags & (PG_FICTITIOUS | PG_UNMANAGED)) == 0) {
+		KASSERT(va < kmi.clean_sva || va >= kmi.clean_eva,
+		    ("pmap_enter: managed mapping within the clean submap"));
 		pmap_insert_entry(pmap, va, m);
 		pa |= PG_MANAGED;
 	}
@@ -1985,8 +2371,10 @@
 	 * Now validate mapping with desired protection/wiring.
 	 */
 	newpte = (pt_entry_t)(pa | PG_V);
-	if ((prot & VM_PROT_WRITE) != 0)
+	if ((prot & VM_PROT_WRITE) != 0) {
 		newpte |= PG_RW;
+		vm_page_flag_set(m, PG_WRITEABLE);
+	}
 	if ((prot & VM_PROT_EXECUTE) == 0)
 		newpte |= pg_nx;
 	if (wired)
@@ -2013,10 +2401,9 @@
 			}
 			if (origpte & PG_M) {
 				KASSERT((origpte & PG_RW),
-				    ("pmap_enter: modified page not writable:"
-				     " va: 0x%lx, pte: 0x%lx", va, origpte));
-				if ((origpte & PG_MANAGED) &&
-				    pmap_track_modified(va))
+	("pmap_enter: modified page not writable: va: %#lx, pte: %#lx",
+				    va, origpte));
+				if ((origpte & PG_MANAGED) != 0)
 					vm_page_dirty(om);
 				if ((newpte & PG_RW) == 0)
 					invlva = TRUE;
@@ -2031,6 +2418,38 @@
 }
 
 /*
+ * Maps a sequence of resident pages belonging to the same object.
+ * The sequence begins with the given page m_start.  This page is
+ * mapped at the given virtual address start.  Each subsequent page is
+ * mapped at a virtual address that is offset from start by the same
+ * amount as the page is offset from m_start within the object.  The
+ * last page in the sequence is the page with the largest offset from
+ * m_start that can be mapped at a virtual address less than the given
+ * virtual address end.  Not every virtual page between start and end
+ * is mapped; only those for which a resident page exists with the
+ * corresponding offset from m_start are mapped.
+ */
+void
+pmap_enter_object(pmap_t pmap, vm_offset_t start, vm_offset_t end,
+    vm_page_t m_start, vm_prot_t prot)
+{
+	vm_page_t m, mpte;
+	vm_pindex_t diff, psize;
+
+	VM_OBJECT_LOCK_ASSERT(m_start->object, MA_OWNED);
+	psize = atop(end - start);
+	mpte = NULL;
+	m = m_start;
+	PMAP_LOCK(pmap);
+	while (m != NULL && (diff = m->pindex - m_start->pindex) < psize) {
+		mpte = pmap_enter_quick_locked(pmap, start + ptoa(diff), m,
+		    prot, mpte);
+		m = TAILQ_NEXT(m, listq);
+	}
+ 	PMAP_UNLOCK(pmap);
+}
+
+/*
  * this code makes some *MAJOR* assumptions:
  * 1. Current pmap & pmap exists.
  * 2. Not wired.
@@ -2039,16 +2458,28 @@
  * but is *MUCH* faster than pmap_enter...
  */
 
-vm_page_t
-pmap_enter_quick(pmap_t pmap, vm_offset_t va, vm_page_t m, vm_prot_t prot,
-    vm_page_t mpte)
+void
+pmap_enter_quick(pmap_t pmap, vm_offset_t va, vm_page_t m, vm_prot_t prot)
 {
+
+	PMAP_LOCK(pmap);
+	(void) pmap_enter_quick_locked(pmap, va, m, prot, NULL);
+	PMAP_UNLOCK(pmap);
+}
+
+static vm_page_t
+pmap_enter_quick_locked(pmap_t pmap, vm_offset_t va, vm_page_t m,
+    vm_prot_t prot, vm_page_t mpte)
+{
+	vm_page_t free;
 	pt_entry_t *pte;
 	vm_paddr_t pa;
 
+	KASSERT(va < kmi.clean_sva || va >= kmi.clean_eva ||
+	    (m->flags & (PG_FICTITIOUS | PG_UNMANAGED)) != 0,
+	    ("pmap_enter_quick_locked: managed mapping within the clean submap"));
 	mtx_assert(&vm_page_queue_mtx, MA_OWNED);
-	VM_OBJECT_LOCK_ASSERT(m->object, MA_OWNED);
-	PMAP_LOCK(pmap);
+	PMAP_LOCK_ASSERT(pmap, MA_OWNED);
 
 	/*
 	 * In the case that a page table page is not
@@ -2065,7 +2496,6 @@
 		if (mpte && (mpte->pindex == ptepindex)) {
 			mpte->wire_count++;
 		} else {
-	retry:
 			/*
 			 * Get the page directory entry
 			 */
@@ -2083,18 +2513,8 @@
 			} else {
 				mpte = _pmap_allocpte(pmap, ptepindex,
 				    M_NOWAIT);
-				if (mpte == NULL) {
-					PMAP_UNLOCK(pmap);
-					vm_page_busy(m);
-					vm_page_unlock_queues();
-					VM_OBJECT_UNLOCK(m->object);
-					VM_WAIT;
-					VM_OBJECT_LOCK(m->object);
-					vm_page_lock_queues();
-					vm_page_wakeup(m);
-					PMAP_LOCK(pmap);
-					goto retry;
-				}
+				if (mpte == NULL)
+					return (mpte);
 			}
 		}
 	} else {
@@ -2110,19 +2530,27 @@
 	pte = vtopte(va);
 	if (*pte) {
 		if (mpte != NULL) {
-			pmap_unwire_pte_hold(pmap, va, mpte);
+			mpte->wire_count--;
 			mpte = NULL;
 		}
-		goto out;
+		return (mpte);
 	}
 
 	/*
-	 * Enter on the PV list if part of our managed memory. Note that we
-	 * raise IPL while manipulating pv_table since pmap_enter can be
-	 * called at interrupt time.
+	 * Enter on the PV list if part of our managed memory.
 	 */
-	if ((m->flags & (PG_FICTITIOUS|PG_UNMANAGED)) == 0)
-		pmap_insert_entry(pmap, va, m);
+	if ((m->flags & (PG_FICTITIOUS | PG_UNMANAGED)) == 0 &&
+	    !pmap_try_insert_pv_entry(pmap, va, m)) {
+		if (mpte != NULL) {
+			free = NULL;
+			if (pmap_unwire_pte_hold(pmap, va, mpte, &free)) {
+				pmap_invalidate_page(pmap, va);
+				pmap_free_zero_pages(free);
+			}
+			mpte = NULL;
+		}
+		return (mpte);
+	}
 
 	/*
 	 * Increment counters
@@ -2140,8 +2568,6 @@
 		pte_store(pte, pa | PG_V | PG_U);
 	else
 		pte_store(pte, pa | PG_V | PG_U | PG_MANAGED);
-out:
-	PMAP_UNLOCK(pmap);
 	return mpte;
 }
 
@@ -2188,7 +2614,6 @@
 retry:
 		p = vm_page_lookup(object, pindex);
 		if (p != NULL) {
-			vm_page_lock_queues();
 			if (vm_page_sleep_if_busy(p, FALSE, "init4p"))
 				goto retry;
 		} else {
@@ -2207,8 +2632,8 @@
 			p = vm_page_lookup(object, pindex);
 			vm_page_lock_queues();
 			vm_page_wakeup(p);
+			vm_page_unlock_queues();
 		}
-		vm_page_unlock_queues();
 
 		ptepa = VM_PAGE_TO_PHYS(p);
 		if (ptepa & (NBPDR - 1))
@@ -2261,12 +2686,9 @@
  *			The mapping must already exist in the pmap.
  */
 void
-pmap_change_wiring(pmap, va, wired)
-	register pmap_t pmap;
-	vm_offset_t va;
-	boolean_t wired;
+pmap_change_wiring(pmap_t pmap, vm_offset_t va, boolean_t wired)
 {
-	register pt_entry_t *pte;
+	pt_entry_t *pte;
 
 	/*
 	 * Wiring is not a hardware characteristic so there is no need to
@@ -2298,10 +2720,10 @@
 pmap_copy(pmap_t dst_pmap, pmap_t src_pmap, vm_offset_t dst_addr, vm_size_t len,
 	  vm_offset_t src_addr)
 {
+	vm_page_t   free;
 	vm_offset_t addr;
 	vm_offset_t end_addr = src_addr + len;
 	vm_offset_t va_next;
-	vm_page_t m;
 
 	if (dst_addr != src_addr)
 		return;
@@ -2327,15 +2749,6 @@
 		if (addr >= UPT_MIN_ADDRESS)
 			panic("pmap_copy: invalid to pmap_copy page tables");
 
-		/*
-		 * Don't let optional prefaulting of pages make us go
-		 * way below the low water mark of free pages or way
-		 * above high water mark of used pv entries.
-		 */
-		if (cnt.v_free_count < cnt.v_free_reserved ||
-		    pv_entry_count > pv_entry_high_water)
-			break;
-		
 		pml4e = pmap_pml4e(src_pmap, addr);
 		if ((*pml4e & PG_V) == 0) {
 			va_next = (addr + NBPML4) & ~PML4MASK;
@@ -2363,11 +2776,11 @@
 			    PHYS_TO_DMAP(VM_PAGE_TO_PHYS(dstmpde));
 			pde = &pde[pmap_pde_index(addr)];
 			if (*pde == 0) {
-				*pde = srcptepaddr;
+				*pde = srcptepaddr & ~PG_W;
 				dst_pmap->pm_stats.resident_count +=
 				    NBPDR / PAGE_SIZE;
 			} else
-				pmap_unwire_pte_hold(dst_pmap, addr, dstmpde);
+				dstmpde->wire_count--;
 			continue;
 		}
 
@@ -2386,11 +2799,6 @@
 			 * we only virtual copy managed pages
 			 */
 			if ((ptetemp & PG_MANAGED) != 0) {
-				/*
-				 * We have to check after allocpte for the
-				 * pte still being around...  allocpte can
-				 * block.
-				 */
 				dstmpte = pmap_allocpte(dst_pmap, addr,
 				    M_NOWAIT);
 				if (dstmpte == NULL)
@@ -2398,18 +2806,26 @@
 				dst_pte = (pt_entry_t *)
 				    PHYS_TO_DMAP(VM_PAGE_TO_PHYS(dstmpte));
 				dst_pte = &dst_pte[pmap_pte_index(addr)];
-				if (*dst_pte == 0) {
+				if (*dst_pte == 0 &&
+				    pmap_try_insert_pv_entry(dst_pmap, addr,
+				    PHYS_TO_VM_PAGE(ptetemp & PG_FRAME))) {
 					/*
-					 * Clear the modified and
+					 * Clear the wired, modified, and
 					 * accessed (referenced) bits
 					 * during the copy.
 					 */
-					m = PHYS_TO_VM_PAGE(ptetemp & PG_FRAME);
-					*dst_pte = ptetemp & ~(PG_M | PG_A);
+					*dst_pte = ptetemp & ~(PG_W | PG_M |
+					    PG_A);
 					dst_pmap->pm_stats.resident_count++;
-					pmap_insert_entry(dst_pmap, addr, m);
-	 			} else
-					pmap_unwire_pte_hold(dst_pmap, addr, dstmpte);
+	 			} else {
+					free = NULL;
+					if (pmap_unwire_pte_hold(dst_pmap,
+					    addr, dstmpte, &free)) {
+					    	pmap_invalidate_page(dst_pmap,
+					 	    addr);
+				    	    	pmap_free_zero_pages(free);
+					}
+				}
 				if (dstmpte->wire_count >= srcmpte->wire_count)
 					break;
 			}
@@ -2488,9 +2904,7 @@
  * subset of pmaps for proper page aging.
  */
 boolean_t
-pmap_page_exists_quick(pmap, m)
-	pmap_t pmap;
-	vm_page_t m;
+pmap_page_exists_quick(pmap_t pmap, vm_page_t m)
 {
 	pv_entry_t pv;
 	int loops = 0;
@@ -2500,7 +2914,7 @@
 
 	mtx_assert(&vm_page_queue_mtx, MA_OWNED);
 	TAILQ_FOREACH(pv, &m->md.pv_list, pv_list) {
-		if (pv->pv_pmap == pmap) {
+		if (PV_PMAP(pv) == pmap) {
 			return TRUE;
 		}
 		loops++;
@@ -2510,7 +2924,6 @@
 	return (FALSE);
 }
 
-#define PMAP_REMOVE_PAGES_CURPROC_ONLY
 /*
  * Remove all pages from specified address space
  * this aids process exit speeds.  Also, this code
@@ -2520,83 +2933,99 @@
  * in the case of running down an entire address space.
  */
 void
-pmap_remove_pages(pmap, sva, eva)
-	pmap_t pmap;
-	vm_offset_t sva, eva;
+pmap_remove_pages(pmap_t pmap)
 {
 	pt_entry_t *pte, tpte;
-	vm_page_t m;
-	pv_entry_t pv, npv;
+	vm_page_t m, free = NULL;
+	pv_entry_t pv;
+	struct pv_chunk *pc, *npc;
+	int field, idx;
+	int64_t bit;
+	uint64_t inuse, bitmask;
+	int allfree;
 
-#ifdef PMAP_REMOVE_PAGES_CURPROC_ONLY
 	if (pmap != vmspace_pmap(curthread->td_proc->p_vmspace)) {
 		printf("warning: pmap_remove_pages called with non-current pmap\n");
 		return;
 	}
-#endif
 	vm_page_lock_queues();
 	PMAP_LOCK(pmap);
-	for (pv = TAILQ_FIRST(&pmap->pm_pvlist); pv; pv = npv) {
-
-		if (pv->pv_va >= eva || pv->pv_va < sva) {
-			npv = TAILQ_NEXT(pv, pv_plist);
-			continue;
-		}
-
-#ifdef PMAP_REMOVE_PAGES_CURPROC_ONLY
-		pte = vtopte(pv->pv_va);
-#else
-		pte = pmap_pte(pmap, pv->pv_va);
-#endif
-		tpte = *pte;
-
-		if (tpte == 0) {
-			printf("TPTE at %p  IS ZERO @ VA %08lx\n",
-							pte, pv->pv_va);
-			panic("bad pte");
-		}
+	TAILQ_FOREACH_SAFE(pc, &pmap->pm_pvchunk, pc_list, npc) {
+		allfree = 1;
+		for (field = 0; field < _NPCM; field++) {
+			inuse = (~(pc->pc_map[field])) & pc_freemask[field];
+			while (inuse != 0) {
+				bit = bsfq(inuse);
+				bitmask = 1UL << bit;
+				idx = field * 64 + bit;
+				pv = &pc->pc_pventry[idx];
+				inuse &= ~bitmask;
+
+				pte = vtopte(pv->pv_va);
+				tpte = *pte;
+
+				if (tpte == 0) {
+					printf(
+					    "TPTE at %p  IS ZERO @ VA %08lx\n",
+					    pte, pv->pv_va);
+					panic("bad pte");
+				}
 
 /*
  * We cannot remove wired pages from a process' mapping at this time
  */
-		if (tpte & PG_W) {
-			npv = TAILQ_NEXT(pv, pv_plist);
-			continue;
-		}
+				if (tpte & PG_W) {
+					allfree = 0;
+					continue;
+				}
 
-		m = PHYS_TO_VM_PAGE(tpte & PG_FRAME);
-		KASSERT(m->phys_addr == (tpte & PG_FRAME),
-		    ("vm_page_t %p phys_addr mismatch %016jx %016jx",
-		    m, (uintmax_t)m->phys_addr, (uintmax_t)tpte));
+				m = PHYS_TO_VM_PAGE(tpte & PG_FRAME);
+				KASSERT(m->phys_addr == (tpte & PG_FRAME),
+				    ("vm_page_t %p phys_addr mismatch %016jx %016jx",
+				    m, (uintmax_t)m->phys_addr,
+				    (uintmax_t)tpte));
+
+				KASSERT(m < &vm_page_array[vm_page_array_size],
+					("pmap_remove_pages: bad tpte %#jx",
+					(uintmax_t)tpte));
 
-		KASSERT(m < &vm_page_array[vm_page_array_size],
-			("pmap_remove_pages: bad tpte %#jx", (uintmax_t)tpte));
+				pmap->pm_stats.resident_count--;
 
-		pmap->pm_stats.resident_count--;
+				pte_clear(pte);
 
-		pte_clear(pte);
+				/*
+				 * Update the vm_page_t clean/reference bits.
+				 */
+				if (tpte & PG_M)
+					vm_page_dirty(m);
 
-		/*
-		 * Update the vm_page_t clean and reference bits.
-		 */
-		if (tpte & PG_M) {
-			vm_page_dirty(m);
+				/* Mark free */
+				PV_STAT(pv_entry_frees++);
+				PV_STAT(pv_entry_spare++);
+				pv_entry_count--;
+				pc->pc_map[field] |= bitmask;
+				m->md.pv_list_count--;
+				TAILQ_REMOVE(&m->md.pv_list, pv, pv_list);
+				if (TAILQ_EMPTY(&m->md.pv_list))
+					vm_page_flag_clear(m, PG_WRITEABLE);
+				pmap_unuse_pt(pmap, pv->pv_va,
+				    *vtopde(pv->pv_va), &free);
+			}
+		}
+		if (allfree) {
+			PV_STAT(pv_entry_spare -= _NPCPV);
+			PV_STAT(pc_chunk_count--);
+			PV_STAT(pc_chunk_frees++);
+			TAILQ_REMOVE(&pmap->pm_pvchunk, pc, pc_list);
+			m = PHYS_TO_VM_PAGE(DMAP_TO_PHYS((vm_offset_t)pc));
+			dump_drop_page(m->phys_addr);
+			vm_page_free(m);
 		}
-
-		npv = TAILQ_NEXT(pv, pv_plist);
-		TAILQ_REMOVE(&pmap->pm_pvlist, pv, pv_plist);
-
-		m->md.pv_list_count--;
-		TAILQ_REMOVE(&m->md.pv_list, pv, pv_list);
-		if (TAILQ_EMPTY(&m->md.pv_list))
-			vm_page_flag_clear(m, PG_WRITEABLE);
-
-		pmap_unuse_pt(pmap, pv->pv_va, *vtopde(pv->pv_va));
-		free_pv_entry(pv);
 	}
 	pmap_invalidate_all(pmap);
-	PMAP_UNLOCK(pmap);
 	vm_page_unlock_queues();
+	PMAP_UNLOCK(pmap);
+	pmap_free_zero_pages(free);
 }
 
 /*
@@ -2610,6 +3039,7 @@
 {
 	pv_entry_t pv;
 	pt_entry_t *pte;
+	pmap_t pmap;
 	boolean_t rv;
 
 	rv = FALSE;
@@ -2618,17 +3048,11 @@
 
 	mtx_assert(&vm_page_queue_mtx, MA_OWNED);
 	TAILQ_FOREACH(pv, &m->md.pv_list, pv_list) {
-		/*
-		 * if the bit being tested is the modified bit, then
-		 * mark clean_map and ptes as never
-		 * modified.
-		 */
-		if (!pmap_track_modified(pv->pv_va))
-			continue;
-		PMAP_LOCK(pv->pv_pmap);
-		pte = pmap_pte(pv->pv_pmap, pv->pv_va);
+		pmap = PV_PMAP(pv);
+		PMAP_LOCK(pmap);
+		pte = pmap_pte(pmap, pv->pv_va);
 		rv = (*pte & PG_M) != 0;
-		PMAP_UNLOCK(pv->pv_pmap);
+		PMAP_UNLOCK(pmap);
 		if (rv)
 			break;
 	}
@@ -2660,70 +3084,36 @@
 }
 
 /*
- *	Clear the given bit in each of the given page's ptes.
+ * Clear the write and modified bits in each of the given page's mappings.
  */
-static __inline void
-pmap_clear_ptes(vm_page_t m, long bit)
+void
+pmap_remove_write(vm_page_t m)
 {
-	register pv_entry_t pv;
-	pt_entry_t pbits, *pte;
+	pv_entry_t pv;
+	pmap_t pmap;
+	pt_entry_t oldpte, *pte;
 
-	if ((m->flags & PG_FICTITIOUS) ||
-	    (bit == PG_RW && (m->flags & PG_WRITEABLE) == 0))
+	if ((m->flags & PG_FICTITIOUS) != 0 ||
+	    (m->flags & PG_WRITEABLE) == 0)
 		return;
-
 	mtx_assert(&vm_page_queue_mtx, MA_OWNED);
-	/*
-	 * Loop over all current mappings setting/clearing as appropos If
-	 * setting RO do we need to clear the VAC?
-	 */
 	TAILQ_FOREACH(pv, &m->md.pv_list, pv_list) {
-		/*
-		 * don't write protect pager mappings
-		 */
-		if (bit == PG_RW) {
-			if (!pmap_track_modified(pv->pv_va))
-				continue;
-		}
-
-		PMAP_LOCK(pv->pv_pmap);
-		pte = pmap_pte(pv->pv_pmap, pv->pv_va);
+		pmap = PV_PMAP(pv);
+		PMAP_LOCK(pmap);
+		pte = pmap_pte(pmap, pv->pv_va);
 retry:
-		pbits = *pte;
-		if (pbits & bit) {
-			if (bit == PG_RW) {
-				if (!atomic_cmpset_long(pte, pbits,
-				    pbits & ~(PG_RW | PG_M)))
-					goto retry;
-				if (pbits & PG_M) {
-					vm_page_dirty(m);
-				}
-			} else {
-				atomic_clear_long(pte, bit);
-			}
-			pmap_invalidate_page(pv->pv_pmap, pv->pv_va);
-		}
-		PMAP_UNLOCK(pv->pv_pmap);
-	}
-	if (bit == PG_RW)
-		vm_page_flag_clear(m, PG_WRITEABLE);
-}
-
-/*
- *      pmap_page_protect:
- *
- *      Lower the permission for all mappings to a given page.
- */
-void
-pmap_page_protect(vm_page_t m, vm_prot_t prot)
-{
-	if ((prot & VM_PROT_WRITE) == 0) {
-		if (prot & (VM_PROT_READ | VM_PROT_EXECUTE)) {
-			pmap_clear_ptes(m, PG_RW);
-		} else {
-			pmap_remove_all(m);
+		oldpte = *pte;
+		if (oldpte & PG_RW) {
+			if (!atomic_cmpset_long(pte, oldpte, oldpte &
+			    ~(PG_RW | PG_M)))
+				goto retry;
+			if ((oldpte & PG_M) != 0)
+				vm_page_dirty(m);
+			pmap_invalidate_page(pmap, pv->pv_va);
 		}
+		PMAP_UNLOCK(pmap);
 	}
+	vm_page_flag_clear(m, PG_WRITEABLE);
 }
 
 /*
@@ -2741,46 +3131,33 @@
 int
 pmap_ts_referenced(vm_page_t m)
 {
-	register pv_entry_t pv, pvf, pvn;
+	pv_entry_t pv, pvf, pvn;
+	pmap_t pmap;
 	pt_entry_t *pte;
-	pt_entry_t v;
 	int rtval = 0;
 
 	if (m->flags & PG_FICTITIOUS)
 		return (rtval);
-
 	mtx_assert(&vm_page_queue_mtx, MA_OWNED);
 	if ((pv = TAILQ_FIRST(&m->md.pv_list)) != NULL) {
-
 		pvf = pv;
-
 		do {
 			pvn = TAILQ_NEXT(pv, pv_list);
-
 			TAILQ_REMOVE(&m->md.pv_list, pv, pv_list);
-
 			TAILQ_INSERT_TAIL(&m->md.pv_list, pv, pv_list);
-
-			if (!pmap_track_modified(pv->pv_va))
-				continue;
-
-			PMAP_LOCK(pv->pv_pmap);
-			pte = pmap_pte(pv->pv_pmap, pv->pv_va);
-
-			if (pte && ((v = pte_load(pte)) & PG_A) != 0) {
+			pmap = PV_PMAP(pv);
+			PMAP_LOCK(pmap);
+			pte = pmap_pte(pmap, pv->pv_va);
+			if ((*pte & PG_A) != 0) {
 				atomic_clear_long(pte, PG_A);
-				pmap_invalidate_page(pv->pv_pmap, pv->pv_va);
-
+				pmap_invalidate_page(pmap, pv->pv_va);
 				rtval++;
-				if (rtval > 4) {
-					PMAP_UNLOCK(pv->pv_pmap);
-					break;
-				}
+				if (rtval > 4)
+					pvn = NULL;
 			}
-			PMAP_UNLOCK(pv->pv_pmap);
+			PMAP_UNLOCK(pmap);
 		} while ((pv = pvn) != NULL && pv != pvf);
 	}
-
 	return (rtval);
 }
 
@@ -2790,7 +3167,23 @@
 void
 pmap_clear_modify(vm_page_t m)
 {
-	pmap_clear_ptes(m, PG_M);
+	pv_entry_t pv;
+	pmap_t pmap;
+	pt_entry_t *pte;
+
+	if ((m->flags & PG_FICTITIOUS) != 0)
+		return;
+	mtx_assert(&vm_page_queue_mtx, MA_OWNED);
+	TAILQ_FOREACH(pv, &m->md.pv_list, pv_list) {
+		pmap = PV_PMAP(pv);
+		PMAP_LOCK(pmap);
+		pte = pmap_pte(pmap, pv->pv_va);
+		if (*pte & PG_M) {
+			atomic_clear_long(pte, PG_M);
+			pmap_invalidate_page(pmap, pv->pv_va);
+		}
+		PMAP_UNLOCK(pmap);
+	}
 }
 
 /*
@@ -2801,13 +3194,69 @@
 void
 pmap_clear_reference(vm_page_t m)
 {
-	pmap_clear_ptes(m, PG_A);
+	pv_entry_t pv;
+	pmap_t pmap;
+	pt_entry_t *pte;
+
+	if ((m->flags & PG_FICTITIOUS) != 0)
+		return;
+	mtx_assert(&vm_page_queue_mtx, MA_OWNED);
+	TAILQ_FOREACH(pv, &m->md.pv_list, pv_list) {
+		pmap = PV_PMAP(pv);
+		PMAP_LOCK(pmap);
+		pte = pmap_pte(pmap, pv->pv_va);
+		if (*pte & PG_A) {
+			atomic_clear_long(pte, PG_A);
+			pmap_invalidate_page(pmap, pv->pv_va);
+		}
+		PMAP_UNLOCK(pmap);
+	}
 }
 
 /*
  * Miscellaneous support routines follow
  */
 
+/* Adjust the cache mode for a 4KB page mapped via a PTE. */
+static __inline void
+pmap_pte_attr(vm_offset_t va, int mode)
+{
+	pt_entry_t *pte;
+	u_int opte, npte;
+
+	pte = vtopte(va);
+
+	/*
+	 * The cache mode bits are all in the low 32-bits of the
+	 * PTE, so we can just spin on updating the low 32-bits.
+	 */
+	do {
+		opte = *(u_int *)pte;
+		npte = opte & ~(PG_PTE_PAT | PG_NC_PCD | PG_NC_PWT);
+		npte |= pmap_cache_bits(mode, 0);
+	} while (npte != opte && !atomic_cmpset_int((u_int *)pte, opte, npte));
+}
+
+/* Adjust the cache mode for a 2MB page mapped via a PDE. */
+static __inline void
+pmap_pde_attr(vm_offset_t va, int mode)
+{
+	pd_entry_t *pde;
+	u_int opde, npde;
+
+	pde = pmap_pde(kernel_pmap, va);
+
+	/*
+	 * The cache mode bits are all in the low 32-bits of the
+	 * PDE, so we can just spin on updating the low 32-bits.
+	 */
+	do {
+		opde = *(u_int *)pde;
+		npde = opde & ~(PG_PDE_PAT | PG_NC_PCD | PG_NC_PWT);
+		npde |= pmap_cache_bits(mode, 1);
+	} while (npde != opde && !atomic_cmpset_int((u_int *)pde, opde, npde));
+}
+
 /*
  * Map a set of physical memory pages into the kernel virtual
  * address space. Return a pointer to where it is mapped. This
@@ -2815,14 +3264,15 @@
  * NOT real memory.
  */
 void *
-pmap_mapdev(pa, size)
-	vm_paddr_t pa;
-	vm_size_t size;
+pmap_mapdev_attr(vm_paddr_t pa, vm_size_t size, int mode)
 {
 	vm_offset_t va, tmpva, offset;
 
-	/* If this fits within the direct map window, use it */
-	if (pa < dmaplimit && (pa + size) < dmaplimit)
+	/*
+	 * If this fits within the direct map window and use WB caching
+	 * mode, use the direct map.
+	 */
+	if (pa < dmaplimit && (pa + size) < dmaplimit && mode == PAT_WRITE_BACK)
 		return ((void *)PHYS_TO_DMAP(pa));
 	offset = pa & PAGE_MASK;
 	size = roundup(offset + size, PAGE_SIZE);
@@ -2831,19 +3281,32 @@
 		panic("pmap_mapdev: Couldn't alloc kernel virtual memory");
 	pa = trunc_page(pa);
 	for (tmpva = va; size > 0; ) {
-		pmap_kenter(tmpva, pa);
+		pmap_kenter_attr(tmpva, pa, mode);
 		size -= PAGE_SIZE;
 		tmpva += PAGE_SIZE;
 		pa += PAGE_SIZE;
 	}
 	pmap_invalidate_range(kernel_pmap, va, tmpva);
+	pmap_invalidate_cache();
 	return ((void *)(va + offset));
 }
 
+void *
+pmap_mapdev(vm_paddr_t pa, vm_size_t size)
+{
+
+	return (pmap_mapdev_attr(pa, size, PAT_UNCACHEABLE));
+}
+
+void *
+pmap_mapbios(vm_paddr_t pa, vm_size_t size)
+{
+
+	return (pmap_mapdev_attr(pa, size, PAT_WRITE_BACK));
+}
+
 void
-pmap_unmapdev(va, size)
-	vm_offset_t va;
-	vm_size_t size;
+pmap_unmapdev(vm_offset_t va, vm_size_t size)
 {
 	vm_offset_t base, offset, tmpva;
 
@@ -2859,13 +3322,78 @@
 	kmem_free(kernel_map, base, size);
 }
 
+int
+pmap_change_attr(va, size, mode)
+	vm_offset_t va;
+	vm_size_t size;
+	int mode;
+{
+	vm_offset_t base, offset, tmpva;
+	pd_entry_t *pde;
+	pt_entry_t *pte;
+
+	base = trunc_page(va);
+	offset = va & PAGE_MASK;
+	size = roundup(offset + size, PAGE_SIZE);
+
+	/* Only supported on kernel virtual addresses. */
+	if (base <= VM_MAXUSER_ADDRESS)
+		return (EINVAL);
+
+	/*
+	 * XXX: We have to support tearing 2MB pages down into 4k pages if
+	 * needed here.
+	 */
+	/* Pages that aren't mapped aren't supported. */
+	for (tmpva = base; tmpva < (base + size); ) {
+		pde = pmap_pde(kernel_pmap, tmpva);
+		if (*pde == 0)
+			return (EINVAL);
+		if (*pde & PG_PS) {
+			/* Handle 2MB pages that are completely contained. */
+			if (size >= NBPDR) {
+				tmpva += NBPDR;
+				continue;
+			}
+			return (EINVAL);
+		}
+		pte = vtopte(va);
+		if (*pte == 0)
+			return (EINVAL);
+		tmpva += PAGE_SIZE;
+	}
+
+	/*
+	 * Ok, all the pages exist, so run through them updating their
+	 * cache mode.
+	 */
+	for (tmpva = base; size > 0; ) {
+		pde = pmap_pde(kernel_pmap, tmpva);
+		if (*pde & PG_PS) {
+			pmap_pde_attr(tmpva, mode);
+			tmpva += NBPDR;
+			size -= NBPDR;
+		} else {
+			pmap_pte_attr(tmpva, mode);
+			tmpva += PAGE_SIZE;
+			size -= PAGE_SIZE;
+		}
+	}
+
+	/*
+	 * Flush CPU caches to make sure any data isn't cached that shouldn't
+	 * be, etc.
+	 */    
+	pmap_invalidate_range(kernel_pmap, base, tmpva);
+	pmap_invalidate_cache();
+	return (0);
+}
+
 /*
  * perform the pmap work for mincore
  */
 int
-pmap_mincore(pmap, addr)
-	pmap_t pmap;
-	vm_offset_t addr;
+pmap_mincore(pmap_t pmap, vm_offset_t addr)
 {
 	pt_entry_t *ptep, pte;
 	vm_page_t m;
@@ -2925,7 +3453,6 @@
 void
 pmap_activate(struct thread *td)
 {
-	struct proc *p = td->td_proc;
 	pmap_t	pmap, oldpmap;
 	u_int64_t  cr3;
 
@@ -2942,18 +3469,7 @@
 	pmap->pm_active |= PCPU_GET(cpumask);
 #endif
 	cr3 = vtophys(pmap->pm_pml4);
-	/* XXXKSE this is wrong.
-	 * pmap_activate is for the current thread on the current cpu
-	 */
-	if (p->p_flag & P_SA) {
-		/* Make sure all other cr3 entries are updated. */
-		/* what if they are running?  XXXKSE (maybe abort them) */
-		FOREACH_THREAD_IN_PROC(p, td) {
-			td->td_pcb->pcb_cr3 = cr3;
-		}
-	} else {
-		td->td_pcb->pcb_cr3 = cr3;
-	}
+	td->td_pcb->pcb_cr3 = cr3;
 	load_cr3(cr3);
 	critical_exit();
 }
Index: io.c
===================================================================
RCS file: /home/cvs/src/sys/amd64/amd64/io.c,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L sys/amd64/amd64/io.c -L sys/amd64/amd64/io.c -u -r1.1.1.1 -r1.2
--- sys/amd64/amd64/io.c
+++ sys/amd64/amd64/io.c
@@ -25,7 +25,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/amd64/amd64/io.c,v 1.1 2004/08/01 11:40:50 markm Exp $");
+__FBSDID("$FreeBSD: src/sys/amd64/amd64/io.c,v 1.2 2006/11/06 13:41:49 rwatson Exp $");
 
 #include <sys/param.h>
 #include <sys/conf.h>
@@ -33,6 +33,7 @@
 #include <sys/lock.h>
 #include <sys/malloc.h>
 #include <sys/mutex.h>
+#include <sys/priv.h>
 #include <sys/proc.h>
 #include <sys/signalvar.h>
 #include <sys/systm.h>
@@ -54,7 +55,7 @@
 {
 	int error;
 
-	error = suser(td);
+	error = priv_check(td, PRIV_IO);
 	if (error != 0)
 		return (error);
 	error = securelevel_gt(td->td_ucred, 0);
Index: nexus.c
===================================================================
RCS file: /home/cvs/src/sys/amd64/amd64/nexus.c,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L sys/amd64/amd64/nexus.c -L sys/amd64/amd64/nexus.c -u -r1.1.1.1 -r1.2
--- sys/amd64/amd64/nexus.c
+++ sys/amd64/amd64/nexus.c
@@ -28,7 +28,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/amd64/amd64/nexus.c,v 1.66 2005/03/18 11:57:43 phk Exp $");
+__FBSDID("$FreeBSD: src/sys/amd64/amd64/nexus.c,v 1.77 2007/05/08 21:29:13 jhb Exp $");
 
 /*
  * This code implements a `root nexus' for Intel Architecture
@@ -41,13 +41,13 @@
  * and I/O memory address space.
  */
 
-#define __RMAN_RESOURCE_VISIBLE
 #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,7 +60,11 @@
 #include <vm/pmap.h>
 #include <machine/pmap.h>
 
+#include <machine/metadata.h>
 #include <machine/resource.h>
+#include <machine/pc/bios.h>
+
+#include "pcib_if.h"
 
 #ifdef DEV_ISA
 #include <isa/isavar.h>
@@ -94,13 +98,19 @@
 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,
-			     void (*)(void *), void *, void **);
+			     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 */
@@ -126,6 +136,13 @@
 	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 }
 };
 
@@ -141,7 +158,7 @@
 static int
 nexus_probe(device_t dev)
 {
-	int irq, last;
+	int irq;
 
 	device_quiet(dev);	/* suppress attach message for neatness */
 
@@ -174,18 +191,10 @@
 	 * We search for regions of existing IRQs and add those to the IRQ
 	 * resource manager.
 	 */
-	last = -1;
 	for (irq = 0; irq < NUM_IO_INTS; irq++)
-		if (intr_lookup_source(irq) != NULL) {
-			if (last == -1)
-				last = irq;
-		} else if (last != -1) {
-			if (rman_manage_region(&irq_rman, last, irq - 1) != 0)
+		if (intr_lookup_source(irq) != NULL)
+			if (rman_manage_region(&irq_rman, irq, irq) != 0)
 				panic("nexus_probe irq_rman add");
-			last = -1;
-		}
-	if (last != -1 && rman_manage_region(&irq_rman, last, irq - 1) != 0)
-		panic("nexus_probe irq_rman add");
 
 	/*
 	 * ISA DMA on PCI systems is implemented in the ISA part of each
@@ -341,13 +350,7 @@
 	rv = rman_reserve_resource(rm, start, end, count, flags, child);
 	if (rv == 0)
 		return 0;
-
-	if (type == SYS_RES_MEMORY) {
-		rman_set_bustag(rv, AMD64_BUS_SPACE_MEM);
-	} else if (type == SYS_RES_IOPORT) {
-		rman_set_bustag(rv, AMD64_BUS_SPACE_IO);
-		rman_set_bushandle(rv, rman_get_start(rv));
-	}
+	rman_set_rid(rv, *rid);
 
 	if (needactivate) {
 		if (bus_activate_resource(child, type, *rid, rv)) {
@@ -367,27 +370,16 @@
 	/*
 	 * If this is a memory resource, map it into the kernel.
 	 */
-	if (rman_get_bustag(r) == AMD64_BUS_SPACE_MEM) {
-		caddr_t vaddr = 0;
-
-		if (rman_get_end(r) < 1024 * 1024) {
-			/*
-			 * The first 1Mb is mapped at KERNBASE.
-			 */
-			vaddr = (caddr_t)(uintptr_t)(KERNBASE + rman_get_start(r));
-		} else {
-			u_int64_t paddr;
-			u_int64_t psize;
-			u_int32_t poffs;
-
-			paddr = rman_get_start(r);
-			psize = rman_get_size(r);
+	if (type == SYS_RES_MEMORY) {
+		void *vaddr;
 
-			poffs = paddr - trunc_page(paddr);
-			vaddr = (caddr_t) pmap_mapdev(paddr-poffs, psize+poffs) + poffs;
-		}
+		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));
 }
@@ -399,12 +391,9 @@
 	/*
 	 * If this is a memory resource, unmap it.
 	 */
-	if ((rman_get_bustag(r) == AMD64_BUS_SPACE_MEM) &&
-	    (rman_get_end(r) >= 1024 * 1024)) {
-		u_int32_t psize;
-
-		psize = rman_get_size(r);
-		pmap_unmapdev((vm_offset_t)rman_get_virtual(r), psize);
+	if (type == SYS_RES_MEMORY) {
+		pmap_unmapdev((vm_offset_t)rman_get_virtual(r),
+		    rman_get_size(r));
 	}
 		
 	return (rman_deactivate_resource(r));
@@ -430,7 +419,8 @@
  */
 static int
 nexus_setup_intr(device_t bus, device_t child, struct resource *irq,
-		 int flags, void (*ihand)(void *), void *arg, void **cookiep)
+		 int flags, driver_filter_t filter, void (*ihand)(void *), 
+		 void *arg, void **cookiep)
 {
 	int		error;
 
@@ -450,7 +440,7 @@
 		return (error);
 
 	error = intr_add_handler(device_get_nameunit(child),
-	    rman_get_start(irq), ihand, arg, flags, cookiep);
+	    rman_get_start(irq), filter, ihand, arg, flags, cookiep);
 
 	return (error);
 }
@@ -513,6 +503,123 @@
 	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 != 0x01 || 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 
Index: fpu.c
===================================================================
RCS file: /home/cvs/src/sys/amd64/amd64/fpu.c,v
retrieving revision 1.2
retrieving revision 1.3
diff -L sys/amd64/amd64/fpu.c -L sys/amd64/amd64/fpu.c -u -r1.2 -r1.3
--- sys/amd64/amd64/fpu.c
+++ sys/amd64/amd64/fpu.c
@@ -31,7 +31,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/amd64/amd64/fpu.c,v 1.157 2005/03/11 22:16:09 peter Exp $");
+__FBSDID("$FreeBSD: src/sys/amd64/amd64/fpu.c,v 1.159 2006/06/19 22:36:01 davidxu Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -125,6 +125,10 @@
 	mxcsr = __INITIAL_MXCSR__;
 	ldmxcsr(mxcsr);
 	fxsave(&fpu_cleanstate);
+	if (fpu_cleanstate.sv_env.en_mxcsr_mask)
+		cpu_mxcsr_mask = fpu_cleanstate.sv_env.en_mxcsr_mask;
+	else
+		cpu_mxcsr_mask = 0xFFBF;
 	start_emulating();
 	bzero(fpu_cleanstate.sv_fp, sizeof(fpu_cleanstate.sv_fp));
 	bzero(fpu_cleanstate.sv_xmm, sizeof(fpu_cleanstate.sv_xmm));
Index: genassym.c
===================================================================
RCS file: /home/cvs/src/sys/amd64/amd64/genassym.c,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L sys/amd64/amd64/genassym.c -L sys/amd64/amd64/genassym.c -u -r1.1.1.1 -r1.2
--- sys/amd64/amd64/genassym.c
+++ sys/amd64/amd64/genassym.c
@@ -33,7 +33,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/amd64/amd64/genassym.c,v 1.155.2.2 2005/11/15 00:25:59 peter Exp $");
+__FBSDID("$FreeBSD: src/sys/amd64/amd64/genassym.c,v 1.165 2007/09/17 21:55:28 peter Exp $");
 
 #include "opt_compat.h"
 #include "opt_kstack_pages.h"
@@ -74,11 +74,12 @@
 ASSYM(P_VMSPACE, offsetof(struct proc, p_vmspace));
 ASSYM(VM_PMAP, offsetof(struct vmspace, vm_pmap));
 ASSYM(PM_ACTIVE, offsetof(struct pmap, pm_active));
-ASSYM(P_SFLAG, offsetof(struct proc, p_sflag));
 
+ASSYM(TD_LOCK, offsetof(struct thread, td_lock));
 ASSYM(TD_FLAGS, offsetof(struct thread, td_flags));
 ASSYM(TD_PCB, offsetof(struct thread, td_pcb));
 ASSYM(TD_PROC, offsetof(struct thread, td_proc));
+ASSYM(TD_TID, offsetof(struct thread, td_tid));
 
 ASSYM(TDF_ASTPENDING, TDF_ASTPENDING);
 ASSYM(TDF_NEEDRESCHED, TDF_NEEDRESCHED);
@@ -135,12 +136,14 @@
 ASSYM(PCB_DR7, offsetof(struct pcb, pcb_dr7));
 ASSYM(PCB_DBREGS, PCB_DBREGS);
 ASSYM(PCB_32BIT, PCB_32BIT);
+ASSYM(PCB_FULLCTX, PCB_FULLCTX);
 
 ASSYM(PCB_FLAGS, offsetof(struct pcb, pcb_flags));
-ASSYM(PCB_FULLCTX, PCB_FULLCTX);
 ASSYM(PCB_SAVEFPU, offsetof(struct pcb, pcb_save));
 ASSYM(PCB_SAVEFPU_SIZE, sizeof(struct savefpu));
 ASSYM(PCB_ONFAULT, offsetof(struct pcb, pcb_onfault));
+ASSYM(PCB_GS32P, offsetof(struct pcb, pcb_gs32p));
+ASSYM(PCB_GS32SD, offsetof(struct pcb, pcb_gs32sd));
 
 ASSYM(PCB_SIZE, sizeof(struct pcb));
 
@@ -177,6 +180,7 @@
 ASSYM(ENOENT, ENOENT);
 ASSYM(EFAULT, EFAULT);
 ASSYM(ENAMETOOLONG, ENAMETOOLONG);
+ASSYM(MAXCPU, MAXCPU);
 ASSYM(MAXCOMLEN, MAXCOMLEN);
 ASSYM(MAXPATHLEN, MAXPATHLEN);
 ASSYM(PC_SIZEOF, sizeof(struct pcpu));
--- /dev/null
+++ sys/amd64/amd64/minidump_machdep.c
@@ -0,0 +1,420 @@
+/*-
+ * Copyright (c) 2006 Peter Wemm
+ * 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: src/sys/amd64/amd64/minidump_machdep.c,v 1.2.4.1 2008/01/30 21:21:50 ru Exp $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/conf.h>
+#include <sys/cons.h>
+#include <sys/kernel.h>
+#include <sys/kerneldump.h>
+#include <sys/msgbuf.h>
+#include <vm/vm.h>
+#include <vm/pmap.h>
+#include <machine/atomic.h>
+#include <machine/elf.h>
+#include <machine/md_var.h>
+#include <machine/vmparam.h>
+#include <machine/minidump.h>
+
+CTASSERT(sizeof(struct kerneldumpheader) == 512);
+
+/*
+ * 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))
+
+extern uint64_t KPDPphys;
+
+uint64_t *vm_page_dump;
+int vm_page_dump_size;
+
+static struct kerneldumpheader kdh;
+static off_t dumplo;
+
+/* Handle chunked writes. */
+static size_t fragsz;
+static void *dump_va;
+static size_t counter, progress;
+
+CTASSERT(sizeof(*vm_page_dump) == 8);
+
+static int
+is_dumpable(vm_paddr_t pa)
+{
+	int i;
+
+	for (i = 0; dump_avail[i] != 0 || dump_avail[i + 1] != 0; i += 2) {
+		if (pa >= dump_avail[i] && pa < dump_avail[i + 1])
+			return (1);
+	}
+	return (0);
+}
+
+/* XXX should be MI */
+static void
+mkdumpheader(struct kerneldumpheader *kdh, uint32_t archver, uint64_t dumplen,
+    uint32_t blksz)
+{
+
+	bzero(kdh, sizeof(*kdh));
+	strncpy(kdh->magic, KERNELDUMPMAGIC, sizeof(kdh->magic));
+	strncpy(kdh->architecture, MACHINE_ARCH, sizeof(kdh->architecture));
+	kdh->version = htod32(KERNELDUMPVERSION);
+	kdh->architectureversion = htod32(archver);
+	kdh->dumplength = htod64(dumplen);
+	kdh->dumptime = htod64(time_second);
+	kdh->blocksize = htod32(blksz);
+	strncpy(kdh->hostname, hostname, sizeof(kdh->hostname));
+	strncpy(kdh->versionstring, version, sizeof(kdh->versionstring));
+	if (panicstr != NULL)
+		strncpy(kdh->panicstring, panicstr, sizeof(kdh->panicstring));
+	kdh->parity = kerneldump_parity(kdh);
+}
+
+#define PG2MB(pgs) (((pgs) + (1 << 8) - 1) >> 8)
+
+static int
+blk_flush(struct dumperinfo *di)
+{
+	int error;
+
+	if (fragsz == 0)
+		return (0);
+
+	error = dump_write(di, dump_va, 0, dumplo, fragsz);
+	dumplo += fragsz;
+	fragsz = 0;
+	return (error);
+}
+
+static int
+blk_write(struct dumperinfo *di, char *ptr, vm_paddr_t pa, size_t sz)
+{
+	size_t len;
+	int error, i, c;
+
+	error = 0;
+	if ((sz % PAGE_SIZE) != 0) {
+		printf("size not page aligned\n");
+		return (EINVAL);
+	}
+	if (ptr != NULL && pa != 0) {
+		printf("cant have both va and pa!\n");
+		return (EINVAL);
+	}
+	if (pa != 0 && (((uintptr_t)ptr) % PAGE_SIZE) != 0) {
+		printf("address not page aligned\n");
+		return (EINVAL);
+	}
+	if (ptr != NULL) {
+		/* If we're doing a virtual dump, flush any pre-existing pa pages */
+		error = blk_flush(di);
+		if (error)
+			return (error);
+	}
+	while (sz) {
+		len = (MAXDUMPPGS * PAGE_SIZE) - fragsz;
+		if (len > sz)
+			len = sz;
+		counter += len;
+		progress -= len;
+		if (counter >> 24) {
+			printf(" %ld", PG2MB(progress >> PAGE_SHIFT));
+			counter &= (1<<24) - 1;
+		}
+		if (ptr) {
+			error = dump_write(di, ptr, 0, dumplo, len);
+			if (error)
+				return (error);
+			dumplo += len;
+			ptr += len;
+			sz -= len;
+		} else {
+			for (i = 0; i < len; i += PAGE_SIZE)
+				dump_va = pmap_kenter_temporary(pa + i, (i + fragsz) >> PAGE_SHIFT);
+			fragsz += len;
+			pa += len;
+			sz -= len;
+			if (fragsz == (MAXDUMPPGS * PAGE_SIZE)) {
+				error = blk_flush(di);
+				if (error)
+					return (error);
+			}
+		}
+
+		/* Check for user abort. */
+		c = cncheckc();
+		if (c == 0x03)
+			return (ECANCELED);
+		if (c != -1)
+			printf(" (CTRL-C to abort) ");
+	}
+
+	return (0);
+}
+
+/* A fake page table page, to avoid having to handle both 4K and 2M pages */
+static pt_entry_t fakept[NPTEPG];
+
+void
+minidumpsys(struct dumperinfo *di)
+{
+	uint64_t dumpsize;
+	uint32_t ptesize;
+	vm_offset_t va;
+	int error;
+	uint64_t bits;
+	uint64_t *pdp, *pd, *pt, pa;
+	int i, j, k, bit;
+	struct minidumphdr mdhdr;
+
+	counter = 0;
+	/* Walk page table pages, set bits in vm_page_dump */
+	ptesize = 0;
+	pdp = (uint64_t *)PHYS_TO_DMAP(KPDPphys);
+	for (va = KERNBASE; va < kernel_vm_end; va += NBPDR) {
+		i = (va >> PDPSHIFT) & ((1ul << NPDPEPGSHIFT) - 1);
+		/*
+		 * We always write a page, even if it is zero. Each
+		 * page written corresponds to 2MB of space
+		 */
+		ptesize += PAGE_SIZE;
+		if ((pdp[i] & PG_V) == 0)
+			continue;
+		pd = (uint64_t *)PHYS_TO_DMAP(pdp[i] & PG_FRAME);
+		j = ((va >> PDRSHIFT) & ((1ul << NPDEPGSHIFT) - 1));
+		if ((pd[j] & (PG_PS | PG_V)) == (PG_PS | PG_V))  {
+			/* This is an entire 2M page. */
+			pa = pd[j] & PG_PS_FRAME;
+			for (k = 0; k < NPTEPG; k++) {
+				if (is_dumpable(pa))
+					dump_add_page(pa);
+				pa += PAGE_SIZE;
+			}
+			continue;
+		}
+		if ((pd[j] & PG_V) == PG_V) {
+			/* set bit for each valid page in this 2MB block */
+			pt = (uint64_t *)PHYS_TO_DMAP(pd[j] & PG_FRAME);
+			for (k = 0; k < NPTEPG; k++) {
+				if ((pt[k] & PG_V) == PG_V) {
+					pa = pt[k] & PG_FRAME;
+					if (is_dumpable(pa))
+						dump_add_page(pa);
+				}
+			}
+		} else {
+			/* nothing, we're going to dump a null page */
+		}
+	}
+
+	/* Calculate dump size. */
+	dumpsize = ptesize;
+	dumpsize += round_page(msgbufp->msg_size);
+	dumpsize += round_page(vm_page_dump_size);
+	for (i = 0; i < vm_page_dump_size / sizeof(*vm_page_dump); i++) {
+		bits = vm_page_dump[i];
+		while (bits) {
+			bit = bsfq(bits);
+			pa = (((uint64_t)i * sizeof(*vm_page_dump) * NBBY) + bit) * PAGE_SIZE;
+			/* Clear out undumpable pages now if needed */
+			if (is_dumpable(pa)) {
+				dumpsize += PAGE_SIZE;
+			} else {
+				dump_drop_page(pa);
+			}
+			bits &= ~(1ul << bit);
+		}
+	}
+	dumpsize += PAGE_SIZE;
+
+	/* 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;
+	progress = dumpsize;
+
+	/* Initialize mdhdr */
+	bzero(&mdhdr, sizeof(mdhdr));
+	strcpy(mdhdr.magic, MINIDUMP_MAGIC);
+	mdhdr.version = MINIDUMP_VERSION;
+	mdhdr.msgbufsize = msgbufp->msg_size;
+	mdhdr.bitmapsize = vm_page_dump_size;
+	mdhdr.ptesize = ptesize;
+	mdhdr.kernbase = KERNBASE;
+	mdhdr.dmapbase = DMAP_MIN_ADDRESS;
+	mdhdr.dmapend = DMAP_MAX_ADDRESS;
+
+	mkdumpheader(&kdh, KERNELDUMP_AMD64_VERSION, dumpsize, di->blocksize);
+
+	printf("Physical memory: %ju MB\n", ptoa((uintmax_t)physmem) / 1048576);
+	printf("Dumping %llu MB:", (long long)dumpsize >> 20);
+
+	/* Dump leader */
+	error = dump_write(di, &kdh, 0, dumplo, sizeof(kdh));
+	if (error)
+		goto fail;
+	dumplo += sizeof(kdh);
+
+	/* Dump my header */
+	bzero(&fakept, sizeof(fakept));
+	bcopy(&mdhdr, &fakept, sizeof(mdhdr));
+	error = blk_write(di, (char *)&fakept, 0, PAGE_SIZE);
+	if (error)
+		goto fail;
+
+	/* Dump msgbuf up front */
+	error = blk_write(di, (char *)msgbufp->msg_ptr, 0, round_page(msgbufp->msg_size));
+	if (error)
+		goto fail;
+
+	/* Dump bitmap */
+	error = blk_write(di, (char *)vm_page_dump, 0, round_page(vm_page_dump_size));
+	if (error)
+		goto fail;
+
+	/* Dump kernel page table pages */
+	pdp = (uint64_t *)PHYS_TO_DMAP(KPDPphys);
+	for (va = KERNBASE; va < kernel_vm_end; va += NBPDR) {
+		i = (va >> PDPSHIFT) & ((1ul << NPDPEPGSHIFT) - 1);
+		/* We always write a page, even if it is zero */
+		if ((pdp[i] & PG_V) == 0) {
+			bzero(fakept, sizeof(fakept));
+			error = blk_write(di, (char *)&fakept, 0, PAGE_SIZE);
+			if (error)
+				goto fail;
+			/* flush, in case we reuse fakept in the same block */
+			error = blk_flush(di);
+			if (error)
+				goto fail;
+			continue;
+		}
+		pd = (uint64_t *)PHYS_TO_DMAP(pdp[i] & PG_FRAME);
+		j = ((va >> PDRSHIFT) & ((1ul << NPDEPGSHIFT) - 1));
+		if ((pd[j] & (PG_PS | PG_V)) == (PG_PS | PG_V))  {
+			/* This is a single 2M block. Generate a fake PTP */
+			pa = pd[j] & PG_PS_FRAME;
+			for (k = 0; k < NPTEPG; k++) {
+				fakept[k] = (pa + (k * PAGE_SIZE)) | PG_V | PG_RW | PG_A | PG_M;
+			}
+			error = blk_write(di, (char *)&fakept, 0, PAGE_SIZE);
+			if (error)
+				goto fail;
+			/* flush, in case we reuse fakept in the same block */
+			error = blk_flush(di);
+			if (error)
+				goto fail;
+			continue;
+		}
+		if ((pd[j] & PG_V) == PG_V) {
+			pt = (uint64_t *)PHYS_TO_DMAP(pd[j] & PG_FRAME);
+			error = blk_write(di, (char *)pt, 0, PAGE_SIZE);
+			if (error)
+				goto fail;
+		} else {
+			bzero(fakept, sizeof(fakept));
+			error = blk_write(di, (char *)&fakept, 0, PAGE_SIZE);
+			if (error)
+				goto fail;
+			/* flush, in case we reuse fakept in the same block */
+			error = blk_flush(di);
+			if (error)
+				goto fail;
+		}
+	}
+
+	/* Dump memory chunks */
+	/* XXX cluster it up and use blk_dump() */
+	for (i = 0; i < vm_page_dump_size / sizeof(*vm_page_dump); i++) {
+		bits = vm_page_dump[i];
+		while (bits) {
+			bit = bsfq(bits);
+			pa = (((uint64_t)i * sizeof(*vm_page_dump) * NBBY) + bit) * PAGE_SIZE;
+			error = blk_write(di, 0, pa, PAGE_SIZE);
+			if (error)
+				goto fail;
+			bits &= ~(1ul << bit);
+		}
+	}
+
+	error = blk_flush(di);
+	if (error)
+		goto fail;
+
+	/* Dump trailer */
+	error = dump_write(di, &kdh, 0, dumplo, sizeof(kdh));
+	if (error)
+		goto fail;
+	dumplo += sizeof(kdh);
+
+	/* 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);
+}
+
+void
+dump_add_page(vm_paddr_t pa)
+{
+	int idx, bit;
+
+	pa >>= PAGE_SHIFT;
+	idx = pa >> 6;		/* 2^6 = 64 */
+	bit = pa & 63;
+	atomic_set_long(&vm_page_dump[idx], 1ul << bit);
+}
+
+void
+dump_drop_page(vm_paddr_t pa)
+{
+	int idx, bit;
+
+	pa >>= PAGE_SHIFT;
+	idx = pa >> 6;		/* 2^6 = 64 */
+	bit = pa & 63;
+	atomic_clear_long(&vm_page_dump[idx], 1ul << bit);
+}
Index: prof_machdep.c
===================================================================
RCS file: /home/cvs/src/sys/amd64/amd64/prof_machdep.c,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L sys/amd64/amd64/prof_machdep.c -L sys/amd64/amd64/prof_machdep.c -u -r1.1.1.1 -r1.2
--- sys/amd64/amd64/prof_machdep.c
+++ sys/amd64/amd64/prof_machdep.c
@@ -25,7 +25,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/amd64/amd64/prof_machdep.c,v 1.24 2005/05/14 09:10:00 nyan Exp $");
+__FBSDID("$FreeBSD: src/sys/amd64/amd64/prof_machdep.c,v 1.29 2007/03/26 18:03:29 njl Exp $");
 
 #ifdef GUPROF
 #if 0
@@ -35,22 +35,20 @@
 
 #include <sys/param.h>
 #include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/cpu.h>
+#include <sys/eventhandler.h>
 #include <sys/gmon.h>
 #include <sys/kernel.h>
+#include <sys/smp.h>
 #include <sys/sysctl.h>
 
 #include <machine/clock.h>
 #if 0
 #include <machine/perfmon.h>
 #endif
-#include <machine/profile.h>
-#undef MCOUNT
-#endif
-
-#include <machine/asmacros.h>
 #include <machine/timerreg.h>
 
-#ifdef GUPROF
 #define	CPUTIME_CLOCK_UNINITIALIZED	0
 #define	CPUTIME_CLOCK_I8254		1
 #define	CPUTIME_CLOCK_TSC		2
@@ -60,11 +58,14 @@
 int	cputime_bias = 1;	/* initialize for locality of reference */
 
 static int	cputime_clock = CPUTIME_CLOCK_UNINITIALIZED;
-#ifdef I586_PMC_GUPROF
+#if defined(PERFMON) && defined(I586_PMC_GUPROF)
 static u_int	cputime_clock_pmc_conf = I586_PMC_GUPROF;
 static int	cputime_clock_pmc_init;
 static struct gmonparam saved_gmp;
 #endif
+#if defined(I586_CPU) || defined(I686_CPU)
+static int	cputime_prof_active;
+#endif
 #endif /* GUPROF */
 
 #ifdef __GNUCLIKE_ASM
@@ -80,7 +81,7 @@
 	#							\n\
 	# Check that we are profiling.  Do it early for speed.	\n\
 	#							\n\
-	cmpl	$GMON_PROF_OFF," __XSTRING(CNAME(_gmonparam)) "+GM_STATE \n\
+	cmpl	$GMON_PROF_OFF,_gmonparam+GM_STATE		\n\
  	je	.mcount_exit					\n\
  	#							\n\
  	# __mcount is the same as [.]mcount except the caller	\n\
@@ -98,11 +99,11 @@
  	jmp	.got_frompc					\n\
  								\n\
  	.p2align 4,0x90						\n\
- 	.globl	" __XSTRING(HIDENAME(mcount)) "			\n\
-" __XSTRING(HIDENAME(mcount)) ":				\n\
+ 	.globl	.mcount						\n\
+.mcount:							\n\
  	.globl	__cyg_profile_func_enter			\n\
 __cyg_profile_func_enter:					\n\
-	cmpl	$GMON_PROF_OFF," __XSTRING(CNAME(_gmonparam)) "+GM_STATE \n\
+	cmpl	$GMON_PROF_OFF,_gmonparam+GM_STATE		\n\
 	je	.mcount_exit					\n\
 	#							\n\
 	# The caller's stack frame has already been built, so	\n\
@@ -126,7 +127,7 @@
 								\n\
 	pushfq							\n\
 	cli							\n\
-	call	" __XSTRING(CNAME(mcount)) "			\n\
+	call	mcount						\n\
 	popfq							\n\
 	popq	%r9						\n\
 	popq	%r8						\n\
@@ -139,7 +140,7 @@
 	ret							\n\
 ");
 #else /* !__GNUCLIKE_ASM */
-#error this file needs to be ported to your compiler
+#error "this file needs to be ported to your compiler"
 #endif /* __GNUCLIKE_ASM */
 
 #ifdef GUPROF
@@ -164,11 +165,11 @@
 GMON_PROF_HIRES	=	4					\n\
 								\n\
 	.p2align 4,0x90						\n\
-	.globl	" __XSTRING(HIDENAME(mexitcount)) "		\n\
-" __XSTRING(HIDENAME(mexitcount)) ":				\n\
+	.globl	.mexitcount					\n\
+.mexitcount:							\n\
  	.globl	__cyg_profile_func_exit				\n\
 __cyg_profile_func_exit:					\n\
-	cmpl	$GMON_PROF_HIRES," __XSTRING(CNAME(_gmonparam)) "+GM_STATE \n\
+	cmpl	$GMON_PROF_HIRES,_gmonparam+GM_STATE		\n\
 	jne	.mexitcount_exit				\n\
 	pushq	%rax						\n\
 	pushq	%rdx						\n\
@@ -180,7 +181,7 @@
 	movq	7*8(%rsp),%rdi					\n\
 	pushfq							\n\
 	cli							\n\
-	call	" __XSTRING(CNAME(mexitcount)) "		\n\
+	call	mexitcount					\n\
 	popfq							\n\
 	popq	%r9						\n\
 	popq	%r8						\n\
@@ -192,8 +193,6 @@
 .mexitcount_exit:						\n\
 	ret							\n\
 ");
-#else /* !__GNUCLIKE_ASM */
-#error this file needs to be ported to your compiler
 #endif /* __GNUCLIKE_ASM */
 
 /*
@@ -212,7 +211,7 @@
 	u_char high, low;
 	static u_int prev_count;
 
-#ifndef SMP
+#if defined(I586_CPU) || defined(I686_CPU)
 	if (cputime_clock == CPUTIME_CLOCK_TSC) {
 		/*
 		 * Scale the TSC a little to make cputime()'s frequency
@@ -226,7 +225,7 @@
 		prev_count = count;
 		return (delta);
 	}
-#if defined(PERFMON) && defined(I586_PMC_GUPROF)
+#if defined(PERFMON) && defined(I586_PMC_GUPROF) && !defined(SMP)
 	if (cputime_clock == CPUTIME_CLOCK_I586_PMC) {
 		/*
 		 * XXX permon_read() should be inlined so that the
@@ -240,8 +239,8 @@
 		prev_count = count;
 		return (delta);
 	}
-#endif /* PERFMON && I586_PMC_GUPROF */
-#endif /* !SMP */
+#endif /* PERFMON && I586_PMC_GUPROF && !SMP */
+#endif /* I586_CPU || I686_CPU */
 
 	/*
 	 * Read the current value of the 8254 timer counter 0.
@@ -323,15 +322,17 @@
 {
 	if (cputime_clock == CPUTIME_CLOCK_UNINITIALIZED) {
 		cputime_clock = CPUTIME_CLOCK_I8254;
-#ifndef SMP
-		if (tsc_freq != 0)
+#if defined(I586_CPU) || defined(I686_CPU)
+		if (tsc_freq != 0 && !tsc_is_broken && mp_ncpus == 1)
 			cputime_clock = CPUTIME_CLOCK_TSC;
 #endif
 	}
 	gp->profrate = timer_freq << CPUTIME_CLOCK_I8254_SHIFT;
-#ifndef SMP
-	if (cputime_clock == CPUTIME_CLOCK_TSC)
+#if defined(I586_CPU) || defined(I686_CPU)
+	if (cputime_clock == CPUTIME_CLOCK_TSC) {
 		gp->profrate = tsc_freq >> 1;
+		cputime_prof_active = 1;
+	}
 #if defined(PERFMON) && defined(I586_PMC_GUPROF)
 	else if (cputime_clock == CPUTIME_CLOCK_I586_PMC) {
 		if (perfmon_avail() &&
@@ -358,7 +359,7 @@
 		}
 	}
 #endif /* PERFMON && I586_PMC_GUPROF */
-#endif /* !SMP */
+#endif /* I586_CPU || I686_CPU */
 	cputime_bias = 0;
 	cputime();
 }
@@ -374,18 +375,27 @@
 		cputime_clock_pmc_init = FALSE;
 	}
 #endif
+#if defined(I586_CPU) || defined(I686_CPU)
+	if (cputime_clock == CPUTIME_CLOCK_TSC)
+		cputime_prof_active = 0;
+#endif
 }
 
-#else /* !GUPROF */
-#ifdef __GNUCLIKE_ASM
-__asm("								\n\
-	.text							\n\
-	.p2align 4,0x90						\n\
-	.globl	" __XSTRING(HIDENAME(mexitcount)) "		\n\
-" __XSTRING(HIDENAME(mexitcount)) ":				\n\
-	ret							\n\
-");
-#else /* !__GNUCLIKE_ASM */
-#error this file needs to be ported to your compiler
-#endif /* __GNUCLIKE_ASM */
+#if defined(I586_CPU) || defined(I686_CPU)
+/* If the cpu frequency changed while profiling, report a warning. */
+static void
+tsc_freq_changed(void *arg, const struct cf_level *level, int status)
+{
+
+	/* If there was an error during the transition, don't do anything. */
+	if (status != 0)
+		return;
+	if (cputime_prof_active && cputime_clock == CPUTIME_CLOCK_TSC)
+		printf("warning: cpu freq changed while profiling active\n");
+}
+
+EVENTHANDLER_DEFINE(cpufreq_post_change, tsc_freq_changed, NULL,
+    EVENTHANDLER_PRI_ANY);
+#endif /* I586_CPU || I686_CPU */
+
 #endif /* GUPROF */
--- /dev/null
+++ sys/amd64/amd64/bpf_jit_machdep.h
@@ -0,0 +1,437 @@
+/*-
+ * Copyright (c) 2002 - 2003 NetGroup, Politecnico di Torino (Italy)
+ * Copyright (c) 2005 Jung-uk Kim <jkim at 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 Politecnico di Torino nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT
+ * OWNER 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: src/sys/amd64/amd64/bpf_jit_machdep.h,v 1.3 2005/12/06 20:11:07 jkim Exp $
+ */
+
+#ifndef _BPF_JIT_MACHDEP_H_
+#define _BPF_JIT_MACHDEP_H_
+
+/*
+ * Registers
+ */
+#define RAX	0
+#define RCX	1
+#define RDX	2
+#define RBX	3
+#define RSP	4
+#define RBP	5
+#define RSI	6
+#define RDI	7
+
+#define EAX	0
+#define ECX	1
+#define EDX	2
+#define EBX	3
+#define ESP	4
+#define EBP	5
+#define ESI	6
+#define EDI	7
+
+#define AX	0
+#define CX	1
+#define DX	2
+#define BX	3
+#define SP	4
+#define BP	5
+#define SI	6
+#define DI	7
+
+#define AL	0
+#define CL	1
+#define DL	2
+#define BL	3
+
+/* A stream of native binary code.*/
+typedef struct bpf_bin_stream {
+	/* Current native instruction pointer. */
+	int		cur_ip;
+
+	/*
+	 * Current BPF instruction pointer, i.e. position in
+	 * the BPF program reached by the jitter.
+	 */
+	int		bpf_pc;
+
+	/* Instruction buffer, contains the generated native code. */
+	char		*ibuf;
+
+	/* Jumps reference table. */
+	u_int		*refs;
+} bpf_bin_stream;
+
+/*
+ * Prototype of the emit functions.
+ *
+ * Different emit functions are used to create the reference table and
+ * to generate the actual filtering code. This allows to have simpler
+ * instruction macros.
+ * The first parameter is the stream that will receive the data.
+ * The second one is a variable containing the data.
+ * The third one is the length, that can be 1, 2, or 4 since it is possible
+ * to emit a byte, a short, or a word at a time.
+ */
+typedef void (*emit_func)(bpf_bin_stream *stream, u_int value, u_int n);
+
+/*
+ * native Instruction Macros
+ */
+
+/* mov r32,i32 */
+#define MOVid(r32, i32) do {						\
+	emitm(&stream, (11 << 4) | (1 << 3) | (r32 & 0x7), 1);		\
+	emitm(&stream, i32, 4);						\
+} while (0)
+
+/* mov r64,i64 */
+#define MOViq(r64, i64) do {						\
+	emitm(&stream, 0x48, 1);					\
+	emitm(&stream, (11 << 4) | (1 << 3) | (r64 & 0x7), 1);		\
+	emitm(&stream, i64, 4);						\
+	emitm(&stream, (i64 >> 32), 4);					\
+} while (0)
+
+/* mov dr32,sr32 */
+#define MOVrd(dr32, sr32) do {						\
+	emitm(&stream, (8 << 4) | 3 | (1 << 3), 1);			\
+	emitm(&stream,							\
+	    (3 << 6) | ((dr32 & 0x7) << 3) | (sr32 & 0x7), 1);		\
+} while (0)
+
+/* mov dr64,sr64 */
+#define MOVrq(dr64, sr64) do {						\
+	emitm(&stream, 0x48, 1);					\
+	emitm(&stream, (8 << 4) | 3 | (1 << 3), 1);			\
+	emitm(&stream,							\
+	    (3 << 6) | ((dr64 & 0x7) << 3) | (sr64 & 0x7), 1);		\
+} while (0)
+
+/* mov dr32,sr64[off] */
+#define MOVodd(dr32, sr64, off) do {					\
+	emitm(&stream, (8 << 4) | 3 | (1 << 3), 1);			\
+	emitm(&stream,							\
+	    (1 << 6) | ((dr32 & 0x7) << 3) | (sr64 & 0x7), 1);		\
+	emitm(&stream, off, 1);						\
+} while (0)
+
+/* mov dr64[off],sr32 */
+#define MOVoqd(dr64, off, sr32) do {					\
+	emitm(&stream, (8 << 4) | 1 | (1 << 3), 1);			\
+	emitm(&stream,							\
+	    (1 << 6) | ((sr32 & 0x7) << 3) | (dr64 & 0x7), 1);		\
+	emitm(&stream, off, 1);						\
+} while (0)
+
+/* mov dr32,sr64[or64] */
+#define MOVobd(dr32, sr64, or64) do {					\
+	emitm(&stream, (8 << 4) | 3 | (1 << 3), 1);			\
+	emitm(&stream, ((dr32 & 0x7) << 3) | 4, 1);			\
+	emitm(&stream, ((or64 & 0x7) << 3) | (sr64 & 0x7), 1);		\
+} while (0)
+
+/* mov dr16,sr64[or64] */
+#define MOVobw(dr32, sr64, or64) do {					\
+	emitm(&stream, 0x66, 1);					\
+	emitm(&stream, (8 << 4) | 3 | (1 << 3), 1);			\
+	emitm(&stream, ((dr32 & 0x7) << 3) | 4, 1);			\
+	emitm(&stream, ((or64 & 0x7) << 3) | (sr64 & 0x7), 1);		\
+} while (0)
+
+/* mov dr8,sr64[or64] */
+#define MOVobb(dr8, sr64, or64) do {					\
+	emitm(&stream, 0x8a, 1);					\
+	emitm(&stream, ((dr8 & 0x7) << 3) | 4, 1);			\
+	emitm(&stream, ((or64 & 0x7) << 3) | (sr64 & 0x7), 1);		\
+} while (0)
+
+/* mov [dr64][or64],sr32 */
+#define MOVomd(dr64, or64, sr32) do {					\
+	emitm(&stream, 0x89, 1);					\
+	emitm(&stream, ((sr32 & 0x7) << 3) | 4, 1);			\
+	emitm(&stream, ((or64 & 0x7) << 3) | (dr64 & 0x7), 1);		\
+} while (0)
+
+/* bswap dr32 */
+#define BSWAP(dr32) do {						\
+	emitm(&stream, 0xf, 1);						\
+	emitm(&stream, (0x19 << 3) | dr32, 1);				\
+} while (0)
+
+/* xchg al,ah */
+#define SWAP_AX() do {							\
+	emitm(&stream, 0x86, 1);					\
+	emitm(&stream, 0xc4, 1);					\
+} while (0)
+
+/* push r64 */
+#define PUSH(r64) do {							\
+	emitm(&stream, (5 << 4) | (0 << 3) | (r64 & 0x7), 1);		\
+} while (0)
+
+/* pop r64 */
+#define POP(r64) do {							\
+	emitm(&stream, (5 << 4) | (1 << 3) | (r64 & 0x7), 1);		\
+} while (0)
+
+/* leave/ret */
+#define LEAVE_RET() do {						\
+	emitm(&stream, 0xc9, 1);					\
+	emitm(&stream, 0xc3, 1);					\
+} while (0)
+
+/* add dr32,sr32 */
+#define ADDrd(dr32, sr32) do {						\
+	emitm(&stream, 0x03, 1);					\
+	emitm(&stream,							\
+	    (3 << 6) | ((dr32 & 0x7) << 3) | (sr32 & 0x7), 1);	\
+} while (0)
+
+/* add eax,i32 */
+#define ADD_EAXi(i32) do {						\
+	emitm(&stream, 0x05, 1);					\
+	emitm(&stream, i32, 4);						\
+} while (0)
+
+/* add r32,i32 */
+#define ADDid(r32, i32) do {						\
+	emitm(&stream, 0x81, 1);					\
+	emitm(&stream, (24 << 3) | r32, 1);				\
+	emitm(&stream, i32, 4);						\
+} while (0)
+
+/* add r32,i8 */
+#define ADDib(r32, i8) do {						\
+	emitm(&stream, 0x83, 1);					\
+	emitm(&stream, (24 << 3) | r32, 1);				\
+	emitm(&stream, i8, 1);						\
+} while (0)
+
+/* sub dr32,sr32 */
+#define SUBrd(dr32, sr32) do {						\
+	emitm(&stream, 0x2b, 1);					\
+	emitm(&stream,							\
+	    (3 << 6) | ((dr32 & 0x7) << 3) | (sr32 & 0x7), 1);		\
+} while (0)
+
+/* sub eax,i32 */
+#define SUB_EAXi(i32) do {						\
+	emitm(&stream, 0x2d, 1);					\
+	emitm(&stream, i32, 4);						\
+} while (0)
+
+/* mul r32 */
+#define MULrd(r32) do {							\
+	emitm(&stream, 0xf7, 1);					\
+	emitm(&stream, (7 << 5) | (r32 & 0x7), 1);			\
+} while (0)
+
+/* div r32 */
+#define DIVrd(r32) do {							\
+	emitm(&stream, 0xf7, 1);					\
+	emitm(&stream, (15 << 4) | (r32 & 0x7), 1);			\
+} while (0)
+
+/* and r8,i8 */
+#define ANDib(r8, i8) do {						\
+	emitm(&stream, 0x80, 1);					\
+	emitm(&stream, (7 << 5) | r8, 1);				\
+	emitm(&stream, i8, 1);						\
+} while (0)
+
+/* and r32,i32 */
+#define ANDid(r32, i32) do {						\
+	if (r32 == EAX) {						\
+		emitm(&stream, 0x25, 1);				\
+		emitm(&stream, i32, 4);					\
+	} else {							\
+		emitm(&stream, 0x81, 1);				\
+		emitm(&stream, (7 << 5) | r32, 1);			\
+		emitm(&stream, i32, 4);					\
+	}								\
+} while (0)
+
+/* and dr32,sr32 */
+#define ANDrd(dr32, sr32) do {						\
+	emitm(&stream, 0x23, 1);					\
+	emitm(&stream,							\
+	    (3 << 6) | ((dr32 & 0x7) << 3) | (sr32 & 0x7), 1);		\
+} while (0)
+
+/* or dr32,sr32 */
+#define ORrd(dr32, sr32) do {						\
+	emitm(&stream, 0x0b, 1);					\
+	emitm(&stream,							\
+	    (3 << 6) | ((dr32 & 0x7) << 3) | (sr32 & 0x7), 1);		\
+} while (0)
+
+/* or r32,i32 */
+#define ORid(r32, i32) do {						\
+	if (r32 == EAX) {						\
+		emitm(&stream, 0x0d, 1);				\
+		emitm(&stream, i32, 4);					\
+	} else {							\
+		emitm(&stream, 0x81, 1);				\
+		emitm(&stream, (25 << 3) | r32, 1);			\
+		emitm(&stream, i32, 4);					\
+	}								\
+} while (0)
+
+/* shl r32,i8 */
+#define SHLib(r32, i8) do {						\
+	emitm(&stream, 0xc1, 1);					\
+	emitm(&stream, (7 << 5) | (r32 & 0x7), 1);			\
+	emitm(&stream, i8, 1);						\
+} while (0)
+
+/* shl dr32,cl */
+#define SHL_CLrb(dr32) do {						\
+	emitm(&stream, 0xd3, 1);					\
+	emitm(&stream, (7 << 5) | (dr32 & 0x7), 1);			\
+} while (0)
+
+/* shr r32,i8 */
+#define SHRib(r32, i8) do {						\
+	emitm(&stream, 0xc1, 1);					\
+	emitm(&stream, (29 << 3) | (r32 & 0x7), 1);			\
+	emitm(&stream, i8, 1);						\
+} while (0)
+
+/* shr dr32,cl */
+#define SHR_CLrb(dr32) do {						\
+	emitm(&stream, 0xd3, 1);					\
+	emitm(&stream, (29 << 3) | (dr32 & 0x7), 1);			\
+} while (0)
+
+/* neg r32 */
+#define NEGd(r32) do {							\
+	emitm(&stream, 0xf7, 1);					\
+	emitm(&stream, (27 << 3) | (r32 & 0x7), 1);			\
+} while (0)
+
+/* cmp dr32,sr64[off] */
+#define CMPodd(dr32, sr64, off) do {					\
+	emitm(&stream, (3 << 4) | 3 | (1 << 3), 1);			\
+	emitm(&stream,							\
+	    (1 << 6) | ((dr32 & 0x7) << 3) | (sr64 & 0x7), 1);		\
+	emitm(&stream, off, 1);						\
+} while (0)
+
+/* cmp dr32,sr32 */
+#define CMPrd(dr32, sr32) do {						\
+	emitm(&stream, 0x3b, 1);					\
+	emitm(&stream,							\
+	    (3 << 6) | ((dr32 & 0x7) << 3) | (sr32 & 0x7), 1);		\
+} while (0)
+
+/* cmp dr32,i32 */
+#define CMPid(dr32, i32) do {						\
+	if (dr32 == EAX){						\
+		emitm(&stream, 0x3d, 1);				\
+		emitm(&stream, i32, 4);					\
+	} else {							\
+		emitm(&stream, 0x81, 1);				\
+		emitm(&stream, (0x1f << 3) | (dr32 & 0x7), 1);		\
+		emitm(&stream, i32, 4);					\
+	}								\
+} while (0)
+
+/* jne off32 */
+#define JNEb(off8) do {							\
+	emitm(&stream, 0x75, 1);					\
+	emitm(&stream, off8, 1);					\
+} while (0)
+
+/* je off32 */
+#define JE(off32) do {							\
+	emitm(&stream, 0x0f, 1);					\
+	emitm(&stream, 0x84, 1);					\
+	emitm(&stream, off32, 4);					\
+} while (0)
+
+/* jle off32 */
+#define JLE(off32) do {							\
+	emitm(&stream, 0x0f, 1);					\
+	emitm(&stream, 0x8e, 1);					\
+	emitm(&stream, off32, 4);					\
+} while (0)
+
+/* jle off8 */
+#define JLEb(off8) do {							\
+	emitm(&stream, 0x7e, 1);					\
+	emitm(&stream, off8, 1);					\
+} while (0)
+
+/* ja off32 */
+#define JA(off32) do {							\
+	emitm(&stream, 0x0f, 1);					\
+	emitm(&stream, 0x87, 1);					\
+	emitm(&stream, off32, 4);					\
+} while (0)
+
+/* jae off32 */
+#define JAE(off32) do {							\
+	emitm(&stream, 0x0f, 1);					\
+	emitm(&stream, 0x83, 1);					\
+	emitm(&stream, off32, 4);					\
+} while (0)
+
+/* jg off32 */
+#define JG(off32) do {							\
+	emitm(&stream, 0x0f, 1);					\
+	emitm(&stream, 0x8f, 1);					\
+	emitm(&stream, off32, 4);					\
+} while (0)
+
+/* jge off32 */
+#define JGE(off32) do {							\
+	emitm(&stream, 0x0f, 1);					\
+	emitm(&stream, 0x8d, 1);					\
+	emitm(&stream, off32, 4);					\
+} while (0)
+
+/* jmp off32 */
+#define JMP(off32) do {							\
+	emitm(&stream, 0xe9, 1);					\
+	emitm(&stream, off32, 4);					\
+} while (0)
+
+/* xor eax,eax */
+#define ZERO_EAX() do {							\
+	emitm(&stream, 0x31, 1);					\
+	emitm(&stream, 0xc0, 1);					\
+} while (0)
+
+/* xor edx,edx */
+#define ZERO_EDX() do {							\
+	emitm(&stream, 0x31, 1);					\
+	emitm(&stream, 0xd2, 1);					\
+} while (0)
+
+#endif	/* _BPF_JIT_MACHDEP_H_ */
--- /dev/null
+++ sys/amd64/amd64/msi.c
@@ -0,0 +1,506 @@
+/*-
+ * Copyright (c) 2006 Yahoo!, Inc.
+ * All rights reserved.
+ * Written by: John Baldwin <jhb at FreeBSD.org>
+ *
+ * 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.
+ */
+
+/*
+ * Support for PCI Message Signalled Interrupts (MSI).  MSI interrupts on
+ * x86 are basically APIC messages that the northbridge delivers directly
+ * to the local APICs as if they had come from an I/O APIC.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: src/sys/amd64/amd64/msi.c,v 1.6.2.1 2007/10/30 18:00:55 jhb Exp $");
+
+#include <sys/param.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/lock.h>
+#include <sys/malloc.h>
+#include <sys/mutex.h>
+#include <sys/sx.h>
+#include <sys/systm.h>
+#include <machine/apicreg.h>
+#include <machine/md_var.h>
+#include <machine/frame.h>
+#include <machine/intr_machdep.h>
+#include <machine/apicvar.h>
+#include <dev/pci/pcivar.h>
+
+/* Fields in address for Intel MSI messages. */
+#define	MSI_INTEL_ADDR_DEST		0x000ff000
+#define	MSI_INTEL_ADDR_RH		0x00000008
+# define MSI_INTEL_ADDR_RH_ON		0x00000008
+# define MSI_INTEL_ADDR_RH_OFF		0x00000000
+#define	MSI_INTEL_ADDR_DM		0x00000004
+# define MSI_INTEL_ADDR_DM_PHYSICAL	0x00000000
+# define MSI_INTEL_ADDR_DM_LOGICAL	0x00000004
+
+/* Fields in data for Intel MSI messages. */
+#define	MSI_INTEL_DATA_TRGRMOD		IOART_TRGRMOD	/* Trigger mode. */
+# define MSI_INTEL_DATA_TRGREDG		IOART_TRGREDG
+# define MSI_INTEL_DATA_TRGRLVL		IOART_TRGRLVL
+#define	MSI_INTEL_DATA_LEVEL		0x00004000	/* Polarity. */
+# define MSI_INTEL_DATA_DEASSERT	0x00000000
+# define MSI_INTEL_DATA_ASSERT		0x00004000
+#define	MSI_INTEL_DATA_DELMOD		IOART_DELMOD	/* Delivery mode. */
+# define MSI_INTEL_DATA_DELFIXED	IOART_DELFIXED
+# define MSI_INTEL_DATA_DELLOPRI	IOART_DELLOPRI
+# define MSI_INTEL_DATA_DELSMI		IOART_DELSMI
+# define MSI_INTEL_DATA_DELNMI		IOART_DELNMI
+# define MSI_INTEL_DATA_DELINIT		IOART_DELINIT
+# define MSI_INTEL_DATA_DELEXINT	IOART_DELEXINT
+#define	MSI_INTEL_DATA_INTVEC		IOART_INTVEC	/* Interrupt vector. */
+
+/*
+ * Build Intel MSI message and data values from a source.  AMD64 systems
+ * seem to be compatible, so we use the same function for both.
+ */
+#define	INTEL_ADDR(msi)							\
+	(MSI_INTEL_ADDR_BASE | (msi)->msi_cpu << 12 |			\
+	    MSI_INTEL_ADDR_RH_OFF | MSI_INTEL_ADDR_DM_PHYSICAL)
+#define	INTEL_DATA(msi)							\
+	(MSI_INTEL_DATA_TRGREDG | MSI_INTEL_DATA_DELFIXED | (msi)->msi_vector)
+
+static MALLOC_DEFINE(M_MSI, "msi", "PCI MSI");
+
+/*
+ * MSI sources are bunched into groups.  This is because MSI forces
+ * all of the messages to share the address and data registers and
+ * thus certain properties (such as the local APIC ID target on x86).
+ * Each group has a 'first' source that contains information global to
+ * the group.  These fields are marked with (g) below.
+ *
+ * Note that local APIC ID is kind of special.  Each message will be
+ * assigned an ID by the system; however, a group will use the ID from
+ * the first message.
+ *
+ * For MSI-X, each message is isolated.
+ */
+struct msi_intsrc {
+	struct intsrc msi_intsrc;
+	device_t msi_dev;		/* Owning device. (g) */
+	struct msi_intsrc *msi_first;	/* First source in group. */
+	u_int msi_irq;			/* IRQ cookie. */
+	u_int msi_msix;			/* MSI-X message. */
+	u_int msi_vector:8;		/* IDT vector. */
+	u_int msi_cpu:8;		/* Local APIC ID. (g) */
+	u_int msi_count:8;		/* Messages in this group. (g) */
+};
+
+static void	msi_create_source(void);
+static void	msi_enable_source(struct intsrc *isrc);
+static void	msi_disable_source(struct intsrc *isrc, int eoi);
+static void	msi_eoi_source(struct intsrc *isrc);
+static void	msi_enable_intr(struct intsrc *isrc);
+static void	msi_disable_intr(struct intsrc *isrc);
+static int	msi_vector(struct intsrc *isrc);
+static int	msi_source_pending(struct intsrc *isrc);
+static int	msi_config_intr(struct intsrc *isrc, enum intr_trigger trig,
+		    enum intr_polarity pol);
+static void	msi_assign_cpu(struct intsrc *isrc, u_int apic_id);
+
+struct pic msi_pic = { msi_enable_source, msi_disable_source, msi_eoi_source,
+		       msi_enable_intr, msi_disable_intr, msi_vector,
+		       msi_source_pending, NULL, NULL, msi_config_intr,
+		       msi_assign_cpu };
+
+static int msi_enabled;
+static int msi_last_irq;
+static struct mtx msi_lock;
+
+static void
+msi_enable_source(struct intsrc *isrc)
+{
+}
+
+static void
+msi_disable_source(struct intsrc *isrc, int eoi)
+{
+
+	if (eoi == PIC_EOI)
+		lapic_eoi();
+}
+
+static void
+msi_eoi_source(struct intsrc *isrc)
+{
+
+	lapic_eoi();
+}
+
+static void
+msi_enable_intr(struct intsrc *isrc)
+{
+	struct msi_intsrc *msi = (struct msi_intsrc *)isrc;
+
+	apic_enable_vector(msi->msi_vector);
+}
+
+static void
+msi_disable_intr(struct intsrc *isrc)
+{
+	struct msi_intsrc *msi = (struct msi_intsrc *)isrc;
+
+	apic_disable_vector(msi->msi_vector);
+}
+
+static int
+msi_vector(struct intsrc *isrc)
+{
+	struct msi_intsrc *msi = (struct msi_intsrc *)isrc;
+
+	return (msi->msi_irq);
+}
+
+static int
+msi_source_pending(struct intsrc *isrc)
+{
+
+	return (0);
+}
+
+static int
+msi_config_intr(struct intsrc *isrc, enum intr_trigger trig,
+    enum intr_polarity pol)
+{
+
+	return (ENODEV);
+}
+
+static void
+msi_assign_cpu(struct intsrc *isrc, u_int apic_id)
+{
+	struct msi_intsrc *msi = (struct msi_intsrc *)isrc;
+
+	msi->msi_cpu = apic_id;
+	if (bootverbose)
+		printf("msi: Assigning %s IRQ %d to local APIC %u\n",
+		    msi->msi_msix ? "MSI-X" : "MSI", msi->msi_irq,
+		    msi->msi_cpu);	
+	pci_remap_msi_irq(msi->msi_dev, msi->msi_irq);
+}
+
+void
+msi_init(void)
+{
+
+	/* Check if we have a supported CPU. */
+	if (!(strcmp(cpu_vendor, "GenuineIntel") == 0 ||
+	      strcmp(cpu_vendor, "AuthenticAMD") == 0))
+		return;
+
+	msi_enabled = 1;
+	intr_register_pic(&msi_pic);
+	mtx_init(&msi_lock, "msi", NULL, MTX_DEF);
+}
+
+void
+msi_create_source(void)
+{
+	struct msi_intsrc *msi;
+	u_int irq;
+
+	mtx_lock(&msi_lock);
+	if (msi_last_irq >= NUM_MSI_INTS) {
+		mtx_unlock(&msi_lock);
+		return;
+	}
+	irq = msi_last_irq + FIRST_MSI_INT;
+	msi_last_irq++;
+	mtx_unlock(&msi_lock);
+
+	msi = malloc(sizeof(struct msi_intsrc), M_MSI, M_WAITOK | M_ZERO);	
+	msi->msi_intsrc.is_pic = &msi_pic;
+	msi->msi_irq = irq;
+	intr_register_source(&msi->msi_intsrc);
+	nexus_add_irq(irq);
+}
+
+/*
+ * Try to allocate 'count' interrupt sources with contiguous IDT values.  If
+ * we allocate any new sources, then their IRQ values will be at the end of
+ * the irqs[] array, with *newirq being the index of the first new IRQ value
+ * and *newcount being the number of new IRQ values added.
+ */
+int
+msi_alloc(device_t dev, int count, int maxcount, int *irqs)
+{
+	struct msi_intsrc *msi, *fsrc;
+	int cnt, i, vector;
+
+	if (!msi_enabled)
+		return (ENXIO);
+
+again:
+	mtx_lock(&msi_lock);
+
+	/* Try to find 'count' free IRQs. */
+	cnt = 0;
+	for (i = FIRST_MSI_INT; i < FIRST_MSI_INT + NUM_MSI_INTS; i++) {
+		msi = (struct msi_intsrc *)intr_lookup_source(i);
+
+		/* End of allocated sources, so break. */
+		if (msi == NULL)
+			break;
+
+		/* If this is a free one, save its IRQ in the array. */
+		if (msi->msi_dev == NULL) {
+			irqs[cnt] = i;
+			cnt++;
+			if (cnt == count)
+				break;
+		}
+	}
+
+	/* Do we need to create some new sources? */
+	if (cnt < count) {
+		/* If we would exceed the max, give up. */
+		if (i + (count - cnt) > FIRST_MSI_INT + NUM_MSI_INTS) {
+			mtx_unlock(&msi_lock);
+			return (ENXIO);
+		}
+		mtx_unlock(&msi_lock);
+
+		/* We need count - cnt more sources. */
+		while (cnt < count) {
+			msi_create_source();
+			cnt++;
+		}
+		goto again;
+	}
+
+	/* Ok, we now have the IRQs allocated. */
+	KASSERT(cnt == count, ("count mismatch"));
+
+	/* Allocate 'count' IDT vectors. */
+	vector = apic_alloc_vectors(irqs, count, maxcount);
+	if (vector == 0) {
+		mtx_unlock(&msi_lock);
+		return (ENOSPC);
+	}
+
+	/* Assign IDT vectors and make these messages owned by 'dev'. */
+	fsrc = (struct msi_intsrc *)intr_lookup_source(irqs[0]);
+	for (i = 0; i < count; i++) {
+		msi = (struct msi_intsrc *)intr_lookup_source(irqs[i]);
+		msi->msi_dev = dev;
+		msi->msi_vector = vector + i;
+		if (bootverbose)
+			printf("msi: routing MSI IRQ %d to vector %u\n",
+			    msi->msi_irq, msi->msi_vector);
+		msi->msi_first = fsrc;
+		KASSERT(msi->msi_intsrc.is_handlers == 0,
+		    ("dead MSI has handlers"));
+	}
+	fsrc->msi_count = count;
+	mtx_unlock(&msi_lock);
+
+	return (0);
+}
+
+int
+msi_release(int *irqs, int count)
+{
+	struct msi_intsrc *msi, *first;
+	int i;
+
+	mtx_lock(&msi_lock);
+	first = (struct msi_intsrc *)intr_lookup_source(irqs[0]);
+	if (first == NULL) {
+		mtx_unlock(&msi_lock);
+		return (ENOENT);
+	}
+
+	/* Make sure this isn't an MSI-X message. */
+	if (first->msi_msix) {
+		mtx_unlock(&msi_lock);
+		return (EINVAL);
+	}
+
+	/* Make sure this message is allocated to a group. */
+	if (first->msi_first == NULL) {
+		mtx_unlock(&msi_lock);
+		return (ENXIO);
+	}
+
+	/*
+	 * Make sure this is the start of a group and that we are releasing
+	 * the entire group.
+	 */
+	if (first->msi_first != first || first->msi_count != count) {
+		mtx_unlock(&msi_lock);
+		return (EINVAL);
+	}
+	KASSERT(first->msi_dev != NULL, ("unowned group"));
+
+	/* Clear all the extra messages in the group. */
+	for (i = 1; i < count; i++) {
+		msi = (struct msi_intsrc *)intr_lookup_source(irqs[i]);
+		KASSERT(msi->msi_first == first, ("message not in group"));
+		KASSERT(msi->msi_dev == first->msi_dev, ("owner mismatch"));
+		msi->msi_first = NULL;
+		msi->msi_dev = NULL;
+		apic_free_vector(msi->msi_vector, msi->msi_irq);
+		msi->msi_vector = 0;
+	}
+
+	/* Clear out the first message. */
+	first->msi_first = NULL;
+	first->msi_dev = NULL;
+	apic_free_vector(first->msi_vector, first->msi_irq);
+	first->msi_vector = 0;
+	first->msi_count = 0;
+
+	mtx_unlock(&msi_lock);
+	return (0);
+}
+
+int
+msi_map(int irq, uint64_t *addr, uint32_t *data)
+{
+	struct msi_intsrc *msi;
+
+	mtx_lock(&msi_lock);
+	msi = (struct msi_intsrc *)intr_lookup_source(irq);
+	if (msi == NULL) {
+		mtx_unlock(&msi_lock);
+		return (ENOENT);
+	}
+
+	/* Make sure this message is allocated to a device. */
+	if (msi->msi_dev == NULL) {
+		mtx_unlock(&msi_lock);
+		return (ENXIO);
+	}
+
+	/*
+	 * If this message isn't an MSI-X message, make sure it's part
+	 * of a group, and switch to the first message in the
+	 * group.
+	 */
+	if (!msi->msi_msix) {
+		if (msi->msi_first == NULL) {
+			mtx_unlock(&msi_lock);
+			return (ENXIO);
+		}
+		msi = msi->msi_first;
+	}
+
+	*addr = INTEL_ADDR(msi);
+	*data = INTEL_DATA(msi);
+	mtx_unlock(&msi_lock);
+	return (0);
+}
+
+int
+msix_alloc(device_t dev, int *irq)
+{
+	struct msi_intsrc *msi;
+	int i, vector;
+
+	if (!msi_enabled)
+		return (ENXIO);
+
+again:
+	mtx_lock(&msi_lock);
+
+	/* Find a free IRQ. */
+	for (i = FIRST_MSI_INT; i < FIRST_MSI_INT + NUM_MSI_INTS; i++) {
+		msi = (struct msi_intsrc *)intr_lookup_source(i);
+
+		/* End of allocated sources, so break. */
+		if (msi == NULL)
+			break;
+
+		/* Stop at the first free source. */
+		if (msi->msi_dev == NULL)
+			break;
+	}
+
+	/* Do we need to create a new source? */
+	if (msi == NULL) {
+		/* If we would exceed the max, give up. */
+		if (i + 1 > FIRST_MSI_INT + NUM_MSI_INTS) {
+			mtx_unlock(&msi_lock);
+			return (ENXIO);
+		}
+		mtx_unlock(&msi_lock);
+
+		/* Create a new source. */
+		msi_create_source();
+		goto again;
+	}
+
+	/* Allocate an IDT vector. */
+	vector = apic_alloc_vector(i);
+	if (bootverbose)
+		printf("msi: routing MSI-X IRQ %d to vector %u\n", msi->msi_irq,
+		    vector);
+
+	/* Setup source. */
+	msi->msi_dev = dev;
+	msi->msi_vector = vector;
+	msi->msi_msix = 1;
+
+	KASSERT(msi->msi_intsrc.is_handlers == 0, ("dead MSI-X has handlers"));
+	mtx_unlock(&msi_lock);
+
+	*irq = i;
+	return (0);
+}
+
+int
+msix_release(int irq)
+{
+	struct msi_intsrc *msi;
+
+	mtx_lock(&msi_lock);
+	msi = (struct msi_intsrc *)intr_lookup_source(irq);
+	if (msi == NULL) {
+		mtx_unlock(&msi_lock);
+		return (ENOENT);
+	}
+
+	/* Make sure this is an MSI-X message. */
+	if (!msi->msi_msix) {
+		mtx_unlock(&msi_lock);
+		return (EINVAL);
+	}
+
+	KASSERT(msi->msi_dev != NULL, ("unowned message"));
+
+	/* Clear out the message. */
+	msi->msi_dev = NULL;
+	apic_free_vector(msi->msi_vector, msi->msi_irq);
+	msi->msi_vector = 0;
+	msi->msi_msix = 0;
+
+	mtx_unlock(&msi_lock);
+	return (0);
+}
Index: uma_machdep.c
===================================================================
RCS file: /home/cvs/src/sys/amd64/amd64/uma_machdep.c,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L sys/amd64/amd64/uma_machdep.c -L sys/amd64/amd64/uma_machdep.c -u -r1.1.1.1 -r1.2
--- sys/amd64/amd64/uma_machdep.c
+++ sys/amd64/amd64/uma_machdep.c
@@ -25,7 +25,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/amd64/amd64/uma_machdep.c,v 1.1 2003/10/14 05:51:31 alc Exp $");
+__FBSDID("$FreeBSD: src/sys/amd64/amd64/uma_machdep.c,v 1.4 2007/09/15 18:47:01 alc Exp $");
 
 #include <sys/param.h>
 #include <sys/lock.h>
@@ -44,14 +44,15 @@
 {
 	static vm_pindex_t colour;
 	vm_page_t m;
+	vm_paddr_t pa;
 	void *va;
 	int pflags;
 
 	*flags = UMA_SLAB_PRIV;
 	if ((wait & (M_NOWAIT|M_USE_RESERVE)) == M_NOWAIT)
-		pflags = VM_ALLOC_INTERRUPT;
+		pflags = VM_ALLOC_INTERRUPT | VM_ALLOC_WIRED;
 	else
-		pflags = VM_ALLOC_SYSTEM;
+		pflags = VM_ALLOC_SYSTEM | VM_ALLOC_WIRED;
 	if (wait & M_ZERO)
 		pflags |= VM_ALLOC_ZERO;
 	for (;;) {
@@ -64,7 +65,9 @@
 		} else
 			break;
 	}
-	va = (void *)PHYS_TO_DMAP(m->phys_addr);
+	pa = m->phys_addr;
+	dump_add_page(pa);
+	va = (void *)PHYS_TO_DMAP(pa);
 	if ((wait & M_ZERO) && (m->flags & PG_ZERO) == 0)
 		pagezero(va);
 	return (va);
@@ -74,9 +77,12 @@
 uma_small_free(void *mem, int size, u_int8_t flags)
 {
 	vm_page_t m;
+	vm_paddr_t pa;
 
-	m = PHYS_TO_VM_PAGE(DMAP_TO_PHYS((vm_offset_t)mem));
-	vm_page_lock_queues();
+	pa = DMAP_TO_PHYS((vm_offset_t)mem);
+	dump_drop_page(pa);
+	m = PHYS_TO_VM_PAGE(pa);
+	m->wire_count--;
 	vm_page_free(m);
-	vm_page_unlock_queues();
+	atomic_subtract_int(&cnt.v_wire_count, 1);
 }
Index: dump_machdep.c
===================================================================
RCS file: /home/cvs/src/sys/amd64/amd64/dump_machdep.c,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L sys/amd64/amd64/dump_machdep.c -L sys/amd64/amd64/dump_machdep.c -u -r1.1.1.1 -r1.2
--- sys/amd64/amd64/dump_machdep.c
+++ sys/amd64/amd64/dump_machdep.c
@@ -25,12 +25,13 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/amd64/amd64/dump_machdep.c,v 1.11 2005/07/02 19:57:30 marcel Exp $");
+__FBSDID("$FreeBSD: src/sys/amd64/amd64/dump_machdep.c,v 1.12.4.1 2008/01/30 21:21:50 ru Exp $");
 
 #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>
@@ -40,6 +41,11 @@
 
 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.
@@ -134,7 +140,7 @@
 		ptr += len;
 		sz -= len;
 		if (fragsz == DEV_BSIZE) {
-			error = di->dumper(di->priv, buffer, 0, dumplo,
+			error = dump_write(di, buffer, 0, dumplo,
 			    DEV_BSIZE);
 			if (error)
 				return error;
@@ -154,7 +160,7 @@
 	if (fragsz == 0)
 		return (0);
 
-	error = di->dumper(di->priv, buffer, 0, dumplo, DEV_BSIZE);
+	error = dump_write(di, buffer, 0, dumplo, DEV_BSIZE);
 	dumplo += DEV_BSIZE;
 	fragsz = 0;
 	return (error);
@@ -195,7 +201,7 @@
 			a = pa + i * PAGE_SIZE;
 			va = pmap_kenter_temporary(trunc_page(a), i);
 		}
-		error = di->dumper(di->priv, va, 0, dumplo, sz);
+		error = dump_write(di, va, 0, dumplo, sz);
 		if (error)
 			break;
 		dumplo += sz;
@@ -272,6 +278,10 @@
 	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;
@@ -317,7 +327,7 @@
 	    ehdr.e_phnum);
 
 	/* Dump leader */
-	error = di->dumper(di->priv, &kdh, 0, dumplo, sizeof(kdh));
+	error = dump_write(di, &kdh, 0, dumplo, sizeof(kdh));
 	if (error)
 		goto fail;
 	dumplo += sizeof(kdh);
@@ -348,12 +358,12 @@
 		goto fail;
 
 	/* Dump trailer */
-	error = di->dumper(di->priv, &kdh, 0, dumplo, sizeof(kdh));
+	error = dump_write(di, &kdh, 0, dumplo, sizeof(kdh));
 	if (error)
 		goto fail;
 
 	/* Signal completion, signoff and exit stage left. */
-	di->dumper(di->priv, NULL, 0, 0, 0);
+	dump_write(di, NULL, 0, 0, 0);
 	printf("\nDump complete\n");
 	return;
 
Index: mptable_pci.c
===================================================================
RCS file: /home/cvs/src/sys/amd64/amd64/mptable_pci.c,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L sys/amd64/amd64/mptable_pci.c -L sys/amd64/amd64/mptable_pci.c -u -r1.1.1.1 -r1.2
--- sys/amd64/amd64/mptable_pci.c
+++ sys/amd64/amd64/mptable_pci.c
@@ -33,7 +33,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/amd64/amd64/mptable_pci.c,v 1.2.8.1 2005/09/18 02:55:09 imp Exp $");
+__FBSDID("$FreeBSD: src/sys/amd64/amd64/mptable_pci.c,v 1.8 2007/05/02 17:50:34 jhb Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -72,6 +72,37 @@
 	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),
@@ -96,17 +127,19 @@
 	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 driver_t mptable_hostb_driver = {
-	"pcib",
-	mptable_hostb_methods,
-	1,
-};
+static devclass_t hostb_devclass;
 
-DRIVER_MODULE(mptable_pcib, legacy, mptable_hostb_driver, pcib_devclass, 0, 0);
+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. */
 
@@ -151,15 +184,17 @@
 	DEVMETHOD(pcib_read_config,	pcib_read_config),
 	DEVMETHOD(pcib_write_config,	pcib_write_config),
 	DEVMETHOD(pcib_route_interrupt,	mptable_pci_route_interrupt),
+	DEVMETHOD(pcib_alloc_msi,	pcib_alloc_msi),
+	DEVMETHOD(pcib_release_msi,	pcib_release_msi),
+	DEVMETHOD(pcib_alloc_msix,	pcib_alloc_msix),
+	DEVMETHOD(pcib_release_msix,	pcib_release_msix),
+	DEVMETHOD(pcib_map_msi,		pcib_map_msi),
 
 	{0, 0}
 };
 
-static driver_t mptable_pcib_driver = {
-	"pcib",
-	mptable_pcib_pci_methods,
-	sizeof(struct pcib_softc),
-};
+static devclass_t pcib_devclass;
 
+DEFINE_CLASS_0(pcib, mptable_pcib_driver, mptable_pcib_pci_methods,
+    sizeof(struct pcib_softc));
 DRIVER_MODULE(mptable_pcib, pci, mptable_pcib_driver, pcib_devclass, 0, 0);
-
Index: syscalls.master
===================================================================
RCS file: /home/cvs/src/sys/amd64/linux32/syscalls.master,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L sys/amd64/linux32/syscalls.master -L sys/amd64/linux32/syscalls.master -u -r1.1.1.1 -r1.2
--- sys/amd64/linux32/syscalls.master
+++ sys/amd64/linux32/syscalls.master
@@ -1,17 +1,17 @@
- $FreeBSD: src/sys/amd64/linux32/syscalls.master,v 1.4.2.1 2005/07/20 17:42:14 jhb Exp $
+ $FreeBSD: src/sys/amd64/linux32/syscalls.master,v 1.30 2007/09/18 19:50:32 dwmalone Exp $
 
 ;	@(#)syscalls.master	8.1 (Berkeley) 7/19/93
 ; System call name/number master file (or rather, slave, from LINUX).
 ; Processed to create linux_sysent.c, linux_proto.h and linux_syscall.h.
 
-; Columns: number type nargs name alt{name,tag,rtyp}/comments
+; Columns: number audit type nargs name alt{name,tag,rtyp}/comments
 ;	number	system call number, must be in order
 ;	audit	the audit event associated with the system call
 ;		A value of AUE_NULL means no auditing, but it also means that
 ;		there is no audit event for the call at this time. For the
 ;		case where the event exists, but we don't want auditing, the
 ;		event should be #defined to AUE_NULL in audit_kevents.h.
-;	type	one of STD, OBSOL, UNIMPL, COMPAT
+;	type	one of STD, OBSOL, UNIMPL
 ;	name	psuedo-prototype of syscall routine
 ;		If one of the following alts is different, then all appear:
 ;	altname	name of system call if different
@@ -21,8 +21,6 @@
 
 ; types:
 ;	STD	always included
-;	COMPAT	included on COMPAT #ifdef
-;	LIBCOMPAT included on COMPAT #ifdef, and placed in syscall.h
 ;	OBSOL	obsolete, not included in system, only specifies name
 ;	UNIMPL	not implemented, placeholder only
 
@@ -40,395 +38,446 @@
 ; #ifdef's, etc. may be included, and are copied to the output files.
 
 0	AUE_NULL	UNIMPL	setup
-1	AUE_NULL	MNOPROTO { void sys_exit(int rval); } exit \
+1	AUE_EXIT	NOPROTO	{ void sys_exit(int rval); } exit \
 				    sys_exit_args void
-2	AUE_NULL	MSTD	{ int linux_fork(void); }
-3	AUE_NULL	MNOPROTO { int read(int fd, char *buf, \
+2	AUE_FORK	STD	{ int linux_fork(void); }
+3	AUE_NULL	NOPROTO	{ int read(int fd, char *buf, \
 				    u_int nbyte); }
-4	AUE_NULL	MNOPROTO { int write(int fd, char *buf, \
+4	AUE_NULL	NOPROTO	{ int write(int fd, char *buf, \
 				    u_int nbyte); }
-5	AUE_NULL	MSTD	{ int linux_open(char *path, l_int flags, \
+5	AUE_OPEN_RWTC	STD	{ int linux_open(char *path, l_int flags, \
 				    l_int mode); }
-6	AUE_NULL	MNOPROTO { int close(int fd); }
-7	AUE_NULL	MSTD	{ int linux_waitpid(l_pid_t pid, \
+6	AUE_CLOSE	NOPROTO	{ int close(int fd); }
+7	AUE_WAIT4	STD	{ int linux_waitpid(l_pid_t pid, \
 				    l_int *status, l_int options); }
-8	AUE_NULL	MSTD	{ int linux_creat(char *path, l_int mode); }
-9	AUE_NULL	MSTD	{ int linux_link(char *path, char *to); }
-10	AUE_NULL	MSTD	{ int linux_unlink(char *path); }
-11	AUE_NULL	MSTD	{ int linux_execve(char *path, char **argp, \
+8	AUE_CREAT	STD	{ int linux_creat(char *path, \
+				    l_int mode); }
+9	AUE_LINK	STD	{ int linux_link(char *path, char *to); }
+10	AUE_UNLINK	STD	{ int linux_unlink(char *path); }
+11	AUE_EXECVE	STD	{ int linux_execve(char *path, char **argp, \
 				    char **envp); }
-12	AUE_NULL	MSTD	{ int linux_chdir(char *path); }
-13	AUE_NULL	MSTD	{ int linux_time(l_time_t *tm); }
-14	AUE_NULL	MSTD	{ int linux_mknod(char *path, l_int mode, \
+12	AUE_CHDIR	STD	{ int linux_chdir(char *path); }
+13	AUE_NULL	STD	{ int linux_time(l_time_t *tm); }
+14	AUE_MKNOD	STD	{ int linux_mknod(char *path, l_int mode, \
 				    l_dev_t dev); }
-15	AUE_NULL	MSTD	{ int linux_chmod(char *path, \
+15	AUE_CHMOD	STD	{ int linux_chmod(char *path, \
 				    l_mode_t mode); }
-16	AUE_NULL	MSTD	{ int linux_lchown16(char *path, \
+16	AUE_LCHOWN	STD	{ int linux_lchown16(char *path, \
 				    l_uid16_t uid, l_gid16_t gid); }
 17	AUE_NULL	UNIMPL	break
-18	AUE_NULL	UNIMPL	stat
-19	AUE_NULL	MSTD	{ int linux_lseek(l_uint fdes, l_off_t off, \
+18	AUE_STAT	STD	{ int linux_stat(char *path, \
+				    struct linux_stat *up); }
+19	AUE_LSEEK	STD	{ int linux_lseek(l_uint fdes, l_off_t off, \
 				    l_int whence); }
-20	AUE_NULL	MSTD	{ int linux_getpid(void); }
-21	AUE_NULL	STD	{ int linux_mount(char *specialfile, \
+20	AUE_GETPID	STD	{ int linux_getpid(void); }
+21	AUE_MOUNT	STD	{ int linux_mount(char *specialfile, \
 				    char *dir, char *filesystemtype, \
 				    l_ulong rwflag, void *data); }
-22	AUE_NULL	STD	{ int linux_oldumount(char *path); }
-23	AUE_NULL	MSTD	{ int linux_setuid16(l_uid16_t uid); }
-24	AUE_NULL	MSTD	{ int linux_getuid16(void); }
-25	AUE_NULL	MSTD	{ int linux_stime(void); }
-26	AUE_NULL	MSTD	{ int linux_ptrace(l_long req, l_long pid, \
+22	AUE_UMOUNT	STD	{ int linux_oldumount(char *path); }
+23	AUE_SETUID	STD	{ int linux_setuid16(l_uid16_t uid); }
+24	AUE_GETUID	STD	{ int linux_getuid16(void); }
+25	AUE_SETTIMEOFDAY	STD	{ int linux_stime(void); }
+26	AUE_PTRACE	STD	{ int linux_ptrace(l_long req, l_long pid, \
 				    l_long addr, l_long data); }
-27	AUE_NULL	MSTD	{ int linux_alarm(l_uint secs); }
-28	AUE_NULL	UNIMPL	fstat
-29	AUE_NULL	MSTD	{ int linux_pause(void); }
-30	AUE_NULL	MSTD	{ int linux_utime(char *fname, \
+27	AUE_NULL	STD	{ int linux_alarm(l_uint secs); }
+28	AUE_FSTAT	UNIMPL	fstat
+29	AUE_NULL	STD	{ int linux_pause(void); }
+30	AUE_UTIME	STD	{ int linux_utime(char *fname, \
 				    struct l_utimbuf *times); }
 31	AUE_NULL	UNIMPL	stty
 32	AUE_NULL	UNIMPL	gtty
-33	AUE_NULL	MSTD	{ int linux_access(char *path, l_int flags); }
-34	AUE_NULL	MSTD	{ int linux_nice(l_int inc); }
+33	AUE_ACCESS	STD	{ int linux_access(char *path, l_int flags); }
+34	AUE_NICE	STD	{ int linux_nice(l_int inc); }
 35	AUE_NULL	UNIMPL	ftime
-36	AUE_NULL	MNOPROTO	{ int sync(void); }
-37	AUE_NULL	MSTD	{ int linux_kill(l_int pid, l_int signum); }
-38	AUE_NULL	MSTD	{ int linux_rename(char *from, char *to); }
-39	AUE_NULL	MSTD	{ int linux_mkdir(char *path, l_int mode); }
-40	AUE_NULL	MSTD	{ int linux_rmdir(char *path); }
-41	AUE_NULL	MNOPROTO { int dup(u_int fd); }
-42	AUE_NULL	MSTD	{ int linux_pipe(l_ulong *pipefds); }
-43	AUE_NULL	MSTD	{ int linux_times(struct l_times_argv *buf); }
+36	AUE_SYNC	NOPROTO	{ int sync(void); }
+37	AUE_KILL	STD	{ int linux_kill(l_int pid, l_int signum); }
+38	AUE_RENAME	STD	{ int linux_rename(char *from, char *to); }
+39	AUE_MKDIR	STD	{ int linux_mkdir(char *path, l_int mode); }
+40	AUE_RMDIR	STD	{ int linux_rmdir(char *path); }
+41	AUE_DUP		NOPROTO	{ int dup(u_int fd); }
+42	AUE_PIPE	STD	{ int linux_pipe(l_ulong *pipefds); }
+43	AUE_NULL	STD	{ int linux_times(struct l_times_argv *buf); }
 44	AUE_NULL	UNIMPL	prof
 45	AUE_NULL	STD	{ int linux_brk(l_ulong dsend); }
-46	AUE_NULL	MSTD	{ int linux_setgid16(l_gid16_t gid); }
-47	AUE_NULL	MSTD	{ int linux_getgid16(void); }
-48	AUE_NULL	MSTD	{ int linux_signal(l_int sig, \
+46	AUE_SETGID	STD	{ int linux_setgid16(l_gid16_t gid); }
+47	AUE_GETGID	STD	{ int linux_getgid16(void); }
+48	AUE_NULL	STD	{ int linux_signal(l_int sig, \
 				    l_handler_t handler); }
-49	AUE_NULL	MSTD	{ int linux_geteuid16(void); }
-50	AUE_NULL	MSTD	{ int linux_getegid16(void); }
-51	AUE_NULL	MNOPROTO { int acct(char *path); }
-52	AUE_NULL	STD	{ int linux_umount(char *path, l_int flags); }
+49	AUE_GETEUID	STD	{ int linux_geteuid16(void); }
+50	AUE_GETEGID	STD	{ int linux_getegid16(void); }
+51	AUE_ACCT	NOPROTO	{ int acct(char *path); }
+52	AUE_UMOUNT	STD	{ int linux_umount(char *path, l_int flags); }
 53	AUE_NULL	UNIMPL	lock
-54	AUE_NULL	STD	{ int linux_ioctl(l_uint fd, l_uint cmd, \
+54	AUE_IOCTL	STD	{ int linux_ioctl(l_uint fd, l_uint cmd, \
 				    uintptr_t arg); }
-55	AUE_NULL	MSTD	{ int linux_fcntl(l_uint fd, l_uint cmd, \
+55	AUE_FCNTL	STD	{ int linux_fcntl(l_uint fd, l_uint cmd, \
 				    uintptr_t arg); }
 56	AUE_NULL	UNIMPL	mpx
-57	AUE_NULL	MNOPROTO { int setpgid(int pid, int pgid); }
+57	AUE_SETPGRP	NOPROTO	{ int setpgid(int pid, int pgid); }
 58	AUE_NULL	UNIMPL	ulimit
-59	AUE_NULL	MSTD	{ int linux_olduname(void); }
-60	AUE_NULL	MNOPROTO { int umask(int newmask); }
-61	AUE_NULL	MNOPROTO	{ int chroot(char *path); }
-62	AUE_NULL	MSTD	{ int linux_ustat(l_dev_t dev, \
+59	AUE_NULL	STD	{ int linux_olduname(void); }
+60	AUE_UMASK	NOPROTO	{ int umask(int newmask); }
+61	AUE_CHROOT	NOPROTO	{ int chroot(char *path); }
+62	AUE_NULL	STD	{ int linux_ustat(l_dev_t dev, \
 				    struct l_ustat *ubuf); }
-63	AUE_NULL	MNOPROTO { int dup2(u_int from, u_int to); }
-64	AUE_NULL	MNOPROTO { int getppid(void); }
-65	AUE_NULL	MNOPROTO { int getpgrp(void); }
-66	AUE_NULL	MNOPROTO { int setsid(void); }
-67	AUE_NULL	MSTD	{ int linux_sigaction(l_int sig, \
+63	AUE_DUP2	NOPROTO	{ int dup2(u_int from, u_int to); }
+64	AUE_GETPPID	STD	{ int linux_getppid(void); }
+65	AUE_GETPGRP	NOPROTO	{ int getpgrp(void); }
+66	AUE_SETSID	NOPROTO	{ int setsid(void); }
+67	AUE_NULL	STD	{ int linux_sigaction(l_int sig, \
 				    l_osigaction_t *nsa, \
 				    l_osigaction_t *osa); }
-68	AUE_NULL	MSTD	{ int linux_sgetmask(void); }
-69	AUE_NULL	MSTD	{ int linux_ssetmask(l_osigset_t mask); }
-70	AUE_NULL	MSTD	{ int linux_setreuid16(l_uid16_t ruid, \
+68	AUE_NULL	STD	{ int linux_sgetmask(void); }
+69	AUE_NULL	STD	{ int linux_ssetmask(l_osigset_t mask); }
+70	AUE_SETREUID	STD	{ int linux_setreuid16(l_uid16_t ruid, \
 				    l_uid16_t euid); }
-71	AUE_NULL	MSTD	{ int linux_setregid16(l_gid16_t rgid, \
+71	AUE_SETREGID	STD	{ int linux_setregid16(l_gid16_t rgid, \
 				    l_gid16_t egid); }
-72	AUE_NULL	MSTD	{ int linux_sigsuspend(l_int hist0, \
+72	AUE_NULL	STD	{ int linux_sigsuspend(l_int hist0, \
 				    l_int hist1, l_osigset_t mask); }
-73	AUE_NULL	MSTD	{ int linux_sigpending(l_osigset_t *mask); }
-74	AUE_NULL	MNOPROTO { int osethostname(char *hostname, \
-				    u_int len); } osethostname \
-				    sethostname_args int
-75	AUE_NULL	MSTD	{ int linux_setrlimit(l_uint resource, \
+73	AUE_NULL	STD	{ int linux_sigpending(l_osigset_t *mask); }
+74	AUE_SYSCTL	STD	{ int linux_sethostname(char *hostname, \
+				    u_int len); }
+75	AUE_SETRLIMIT	STD	{ int linux_setrlimit(l_uint resource, \
 				    struct l_rlimit *rlim); }
-76	AUE_NULL	MSTD	{ int linux_old_getrlimit(l_uint resource, \
+76	AUE_GETRLIMIT	STD	{ int linux_old_getrlimit(l_uint resource, \
 				    struct l_rlimit *rlim); }
-77	AUE_NULL	MSTD	{ int linux_getrusage(int who, \
+77	AUE_GETRUSAGE	STD	{ int linux_getrusage(int who, \
 				    struct l_rusage *rusage); }
-78	AUE_NULL	MSTD	{ int linux_gettimeofday( \
+78	AUE_NULL	STD	{ int linux_gettimeofday( \
 				    struct l_timeval *tp, \
 				    struct timezone *tzp); }
-79	AUE_NULL	MSTD	{ int linux_settimeofday( \
+79	AUE_SETTIMEOFDAY STD	{ int linux_settimeofday( \
 				    struct l_timeval *tp, \
 				    struct timezone *tzp); }
-80	AUE_NULL	MSTD	{ int linux_getgroups16(l_uint gidsetsize, \
+80	AUE_GETGROUPS	STD	{ int linux_getgroups16(l_uint gidsetsize, \
 				    l_gid16_t *gidset); }
-81	AUE_NULL	MSTD	{ int linux_setgroups16(l_uint gidsetsize, \
+81	AUE_SETGROUPS	STD	{ int linux_setgroups16(l_uint gidsetsize, \
 				    l_gid16_t *gidset); }
-82	AUE_NULL	MSTD	{ int linux_old_select( \
+82	AUE_SELECT	STD	{ int linux_old_select( \
 				    struct l_old_select_argv *ptr); }
-83	AUE_NULL	MSTD	{ int linux_symlink(char *path, \
-				    char *to); }
-84	AUE_NULL	UNIMPL	ostat
-85	AUE_NULL	MSTD	{ int linux_readlink(char *name, \
-				    char *buf, l_int count); }
-86	AUE_NULL	UNIMPL	linux_uselib
-87	AUE_NULL	MNOPROTO	{ int swapon(char *name); }
-88	AUE_NULL	MSTD	{ int linux_reboot(l_int magic1, \
-				    l_int magic2, l_uint cmd, \
-				void *arg); }
-89	AUE_NULL	STD	{ int linux_readdir(l_uint fd, \
+83	AUE_SYMLINK	STD	{ int linux_symlink(char *path, char *to); }
+84	AUE_LSTAT	STD	{ int linux_lstat(char *path, struct linux_lstat *up); }
+85	AUE_READLINK	STD	{ int linux_readlink(char *name, char *buf, \
+				    l_int count); }
+86	AUE_USELIB	UNIMPL	linux_uselib
+87	AUE_SWAPON	NOPROTO	{ int swapon(char *name); }
+88	AUE_REBOOT	STD	{ int linux_reboot(l_int magic1, \
+				    l_int magic2, l_uint cmd, void *arg); }
+89	AUE_GETDIRENTRIES	STD { int linux_readdir(l_uint fd, \
 				    struct l_dirent *dent, l_uint count); }
-90	AUE_NULL	MSTD	{ int linux_mmap(struct l_mmap_argv *ptr); }
-91	AUE_NULL	MNOPROTO	{ int munmap(caddr_t addr, int len); }
-92	AUE_NULL	MSTD	{ int linux_truncate(char *path, \
+90	AUE_MMAP	STD	{ int linux_mmap(struct l_mmap_argv *ptr); }
+91	AUE_MUNMAP	NOPROTO	{ int munmap(caddr_t addr, int len); }
+92	AUE_TRUNCATE	STD	{ int linux_truncate(char *path, \
 				    l_ulong length); }
-93	AUE_NULL	MNOPROTO	{ int oftruncate(int fd, long length); }
-94	AUE_NULL	MNOPROTO	{ int fchmod(int fd, int mode); }
-95	AUE_NULL	MNOPROTO	{ int fchown(int fd, int uid, int gid); }
-96	AUE_NULL	MSTD	{ int linux_getpriority(int which, int who); }
-97	AUE_NULL	MNOPROTO { int setpriority(int which, int who, \
+93	AUE_FTRUNCATE	STD	{ int linux_ftruncate(int fd, long length); }
+94	AUE_FCHMOD	NOPROTO	{ int fchmod(int fd, int mode); }
+95	AUE_FCHOWN	NOPROTO	{ int fchown(int fd, int uid, int gid); }
+96	AUE_GETPRIORITY	STD	{ int linux_getpriority(int which, int who); }
+97	AUE_SETPRIORITY	NOPROTO	{ int setpriority(int which, int who, \
 				    int prio); }
-98	AUE_NULL	UNIMPL	profil
-99	AUE_NULL	MSTD	{ int linux_statfs(char *path, \
+98	AUE_PROFILE	UNIMPL	profil
+99	AUE_STATFS	STD	{ int linux_statfs(char *path, \
 				    struct l_statfs_buf *buf); }
-100	AUE_NULL	MSTD	{ int linux_fstatfs(l_uint fd, \
+100	AUE_FSTATFS	STD	{ int linux_fstatfs(l_uint fd, \
 				    struct l_statfs_buf *buf); }
 101	AUE_NULL	UNIMPL	ioperm
-102	AUE_NULL	MSTD	{ int linux_socketcall(l_int what, \
+102	AUE_NULL	STD	{ int linux_socketcall(l_int what, \
 				    l_ulong args); }
-103	AUE_NULL	MSTD	{ int linux_syslog(l_int type, char *buf, \
+103	AUE_NULL	STD	{ int linux_syslog(l_int type, char *buf, \
 				    l_int len); }
-104	AUE_NULL	MSTD	{ int linux_setitimer(l_int which, \
+104	AUE_SETITIMER	STD	{ int linux_setitimer(l_int which, \
 				    struct l_itimerval *itv, \
 				    struct l_itimerval *oitv); }
-105	AUE_NULL	MSTD	{ int linux_getitimer(l_int which, \
+105	AUE_GETITIMER	STD	{ int linux_getitimer(l_int which, \
 				    struct l_itimerval *itv); }
-106	AUE_NULL	MSTD	{ int linux_newstat(char *path, \
+106	AUE_STAT	STD	{ int linux_newstat(char *path, \
 				    struct l_newstat *buf); }
-107	AUE_NULL	MSTD	{ int linux_newlstat(char *path, \
+107	AUE_LSTAT	STD	{ int linux_newlstat(char *path, \
 				    struct l_newstat *buf); }
-108	AUE_NULL	MSTD	{ int linux_newfstat(l_uint fd, \
+108	AUE_FSTAT	STD	{ int linux_newfstat(l_uint fd, \
 				    struct l_newstat *buf); }
-109	AUE_NULL	MSTD	{ int linux_uname(void); }
-110	AUE_NULL	UNIMPL	iopl
-111	AUE_NULL	MSTD	{ int linux_vhangup(void); }
+109	AUE_NULL	STD	{ int linux_uname(void); }
+110	AUE_NULL	STD	{ int linux_iopl(l_ulong level); }
+111	AUE_NULL	STD	{ int linux_vhangup(void); }
 112	AUE_NULL	UNIMPL	idle
 113	AUE_NULL	UNIMPL	vm86old
-114	AUE_NULL	MSTD	{ int linux_wait4(l_pid_t pid, \
+114	AUE_WAIT4	STD	{ int linux_wait4(l_pid_t pid, \
 				    l_uint *status, l_int options, \
 				    struct l_rusage *rusage); }
-115	AUE_NULL	MSTD	{ int linux_swapoff(void); }
-116	AUE_NULL	MSTD	{ int linux_sysinfo(struct l_sysinfo *info); }
+115	AUE_SWAPOFF	STD	{ int linux_swapoff(void); }
+116	AUE_NULL	STD	{ int linux_sysinfo(struct l_sysinfo *info); }
 117	AUE_NULL	STD	{ int linux_ipc(l_uint what, l_int arg1, \
 				    l_int arg2, l_int arg3, void *ptr, \
 				    l_long arg5); }
-118	AUE_NULL	MNOPROTO	{ int fsync(int fd); }
-119	AUE_NULL	MSTD	{ int linux_sigreturn( \
+118	AUE_FSYNC	NOPROTO	{ int fsync(int fd); }
+119	AUE_SIGRETURN	STD	{ int linux_sigreturn( \
 				    struct l_sigframe *sfp); }
-120	AUE_NULL	MSTD	{ int linux_clone(l_int flags, \
-				    void *stack); }
-121	AUE_NULL	MNOPROTO { int setdomainname(char *name, int len); }
-122	AUE_NULL	MSTD	{ int linux_newuname( \
+; linux uses some strange calling convention here so we have to use the dummy arg
+120	AUE_RFORK	STD	{ int linux_clone(l_int flags, void *stack, \
+				    void *parent_tidptr, int dummy, void * child_tidptr); }
+121	AUE_SYSCTL	NOPROTO	{ int setdomainname(char *name, \
+				    int len); }
+122	AUE_NULL	STD	{ int linux_newuname( \
 				    struct l_new_utsname *buf); }
 123	AUE_NULL	UNIMPL	modify_ldt
-124	AUE_NULL	MSTD	{ int linux_adjtimex(void); }
-125	AUE_NULL	MSTD	{ int linux_mprotect(caddr_t addr, int len, \
+124	AUE_ADJTIME	STD	{ int linux_adjtimex(void); }
+125	AUE_MPROTECT	STD	{ int linux_mprotect(caddr_t addr, int len, \
 				    int prot); }
-126	AUE_NULL	MSTD	{ int linux_sigprocmask(l_int how, \
+126	AUE_SIGPROCMASK	STD	{ int linux_sigprocmask(l_int how, \
 				    l_osigset_t *mask, l_osigset_t *omask); }
-127	AUE_NULL	MSTD	{ int linux_create_module(void); }
-128	AUE_NULL	MSTD	{ int linux_init_module(void); }
-129	AUE_NULL	MSTD	{ int linux_delete_module(void); }
-130	AUE_NULL	MSTD	{ int linux_get_kernel_syms(void); }
-131	AUE_NULL	MSTD	{ int linux_quotactl(void); }
-132	AUE_NULL	MNOPROTO	{ int getpgid(int pid); }
-133	AUE_NULL	MNOPROTO	{ int fchdir(int fd); }
-134	AUE_NULL	MSTD	{ int linux_bdflush(void); }
-135	AUE_NULL	MSTD	{ int linux_sysfs(l_int option, \
+127	AUE_NULL	STD	{ int linux_create_module(void); }
+128	AUE_NULL	STD	{ int linux_init_module(void); }
+129	AUE_NULL	STD	{ int linux_delete_module(void); }
+130	AUE_NULL	STD	{ int linux_get_kernel_syms(void); }
+131	AUE_QUOTACTL	STD	{ int linux_quotactl(void); }
+132	AUE_GETPGID	NOPROTO	{ int getpgid(int pid); }
+133	AUE_FCHDIR	NOPROTO	{ int fchdir(int fd); }
+134	AUE_BDFLUSH	STD	{ int linux_bdflush(void); }
+135	AUE_NULL	STD	{ int linux_sysfs(l_int option, \
 				    l_ulong arg1, l_ulong arg2); }
-136	AUE_NULL	MSTD	{ int linux_personality(l_ulong per); }
+136	AUE_PERSONALITY	STD	{ int linux_personality(l_ulong per); }
 137	AUE_NULL	UNIMPL	afs_syscall
-138	AUE_NULL	MSTD	{ int linux_setfsuid16(l_uid16_t uid); }
-139	AUE_NULL	MSTD	{ int linux_setfsgid16(l_gid16_t gid); }
-140	AUE_NULL	MSTD	{ int linux_llseek(l_int fd, l_ulong ohigh, \
+138	AUE_SETFSUID	STD	{ int linux_setfsuid16(l_uid16_t uid); }
+139	AUE_SETFSGID	STD	{ int linux_setfsgid16(l_gid16_t gid); }
+140	AUE_LSEEK	STD	{ int linux_llseek(l_int fd, l_ulong ohigh, \
 				    l_ulong olow, l_loff_t *res, \
 				    l_uint whence); }
-141	AUE_NULL	STD	{ int linux_getdents(l_uint fd, void *dent, \
+141	AUE_GETDIRENTRIES	STD { int linux_getdents(l_uint fd, void *dent, \
 				    l_uint count); }
-142	AUE_NULL	MSTD	{ int linux_select(l_int nfds, \
+142	AUE_SELECT	STD	{ int linux_select(l_int nfds, \
 				    l_fd_set *readfds, l_fd_set *writefds, \
 				    l_fd_set *exceptfds, \
 				    struct l_timeval *timeout); }
-143	AUE_NULL	MNOPROTO	{ int flock(int fd, int how); }
-144	AUE_NULL	MSTD	{ int linux_msync(l_ulong addr, \
+143	AUE_FLOCK	NOPROTO	{ int flock(int fd, int how); }
+144	AUE_MSYNC	STD	{ int linux_msync(l_ulong addr, \
 				    l_size_t len, l_int fl); }
-145	AUE_NULL	MSTD	{ int linux_readv(int fd, \
-				    struct iovec32 *iovp, u_int iovcnt); }
-146	AUE_NULL	MSTD	{ int linux_writev(int fd, \
-				    struct iovec32 *iovp, u_int iovcnt); }
-147	AUE_NULL	MSTD	{ int linux_getsid(l_pid_t pid); }
-148	AUE_NULL	MSTD	{ int linux_fdatasync(l_uint fd); }
-149	AUE_NULL	MSTD	{ int linux_sysctl( \
+145	AUE_READV	STD { int linux_readv(int fd, struct iovec32 *iovp, \
+				    u_int iovcnt); }
+146	AUE_WRITEV	STD { int linux_writev(int fd, struct iovec32 *iovp, \
+				    u_int iovcnt); }
+147	AUE_GETSID	STD	{ int linux_getsid(l_pid_t pid); }
+148	AUE_NULL	STD	{ int linux_fdatasync(l_uint fd); }
+149	AUE_SYSCTL	STD	{ int linux_sysctl( \
 				    struct l___sysctl_args *args); }
-150	AUE_NULL	MNOPROTO { int mlock(const void *addr, size_t len); }
-151	AUE_NULL	MNOPROTO { int munlock(const void *addr, \
-				    size_t len); }
-152	AUE_NULL	MNOPROTO { int mlockall(int how); }
-153	AUE_NULL	MNOPROTO { int munlockall(void); }
-154	AUE_NULL	MNOPROTO { int sched_setparam(pid_t pid, \
+150	AUE_MLOCK	NOPROTO	{ int mlock(const void *addr, size_t len); }
+151	AUE_MUNLOCK	NOPROTO	{ int munlock(const void *addr, size_t len); }
+152	AUE_MLOCKALL	NOPROTO	{ int mlockall(int how); }
+153	AUE_MUNLOCKALL	NOPROTO	{ int munlockall(void); }
+154	AUE_SCHED_SETPARAM	NOPROTO	{ int sched_setparam(pid_t pid, \
 				    const struct sched_param *param); }
-155	AUE_NULL	MNOPROTO { int sched_getparam(pid_t pid, \
+155	AUE_SCHED_GETPARAM	NOPROTO	{ int sched_getparam(pid_t pid, \
 				    struct sched_param *param); }
-156	AUE_NULL	MSTD	{ int linux_sched_setscheduler(l_pid_t pid, \
-				    l_int policy, \
+156	AUE_SCHED_SETSCHEDULER	STD { int linux_sched_setscheduler( \
+				    l_pid_t pid, l_int policy, \
 				    struct l_sched_param *param); }
-157	AUE_NULL	MSTD	{ int linux_sched_getscheduler(l_pid_t pid); }
-158	AUE_NULL	MNOPROTO	{ int sched_yield(void); }
-159	AUE_NULL	MSTD	{ int linux_sched_get_priority_max( \
+157	AUE_SCHED_GETSCHEDULER	STD { int linux_sched_getscheduler( \
+				    l_pid_t pid); }
+158	AUE_NULL	NOPROTO	{ int sched_yield(void); }
+159	AUE_SCHED_GET_PRIORITY_MAX	STD { int linux_sched_get_priority_max( \
 				    l_int policy); }
-160	AUE_NULL	MSTD	{ int linux_sched_get_priority_min( \
+160	AUE_SCHED_GET_PRIORITY_MIN	STD { int linux_sched_get_priority_min( \
 				    l_int policy); }
-161	AUE_NULL	MSTD	{ int linux_sched_rr_get_interval( \
-				    l_pid_t pid, \
+161	AUE_SCHED_RR_GET_INTERVAL	STD { int linux_sched_rr_get_interval(l_pid_t pid, \
 				    struct l_timespec *interval); }
-162	AUE_NULL	MSTD	{ int linux_nanosleep( \
+162	AUE_NULL	STD	{ int linux_nanosleep( \
 				    const struct l_timespec *rqtp, \
 				    struct l_timespec *rmtp); }
-163	AUE_NULL	MSTD	{ int linux_mremap(l_ulong addr, \
+163	AUE_NULL	STD	{ int linux_mremap(l_ulong addr, \
 				    l_ulong old_len, l_ulong new_len, \
 				    l_ulong flags, l_ulong new_addr); }
-164	AUE_NULL	MSTD	{ int linux_setresuid16(l_uid16_t ruid, \
+164	AUE_SETRESUID	STD	{ int linux_setresuid16(l_uid16_t ruid, \
 				    l_uid16_t euid, l_uid16_t suid); }
-165	AUE_NULL	MSTD	{ int linux_getresuid16(l_uid16_t *ruid, \
+165	AUE_GETRESUID	STD	{ int linux_getresuid16(l_uid16_t *ruid, \
 				    l_uid16_t *euid, l_uid16_t *suid); }
 166	AUE_NULL	UNIMPL	vm86
-167	AUE_NULL	MSTD	{ int linux_query_module(void); }
-168	AUE_NULL	MNOPROTO	{ int poll(struct pollfd*, \
+167	AUE_NULL	STD	{ int linux_query_module(void); }
+168	AUE_POLL	NOPROTO	{ int poll(struct pollfd*, \
 				    unsigned int nfds, int timeout); }
-169	AUE_NULL	MSTD	{ int linux_nfsservctl(void); }
-170	AUE_NULL	MSTD	{ int linux_setresgid16(l_gid16_t rgid, \
+169	AUE_NULL	STD	{ int linux_nfsservctl(void); }
+170	AUE_SETRESGID	STD	{ int linux_setresgid16(l_gid16_t rgid, \
 				    l_gid16_t egid, l_gid16_t sgid); }
-171	AUE_NULL	MSTD	{ int linux_getresgid16(l_gid16_t *rgid, \
+171	AUE_GETRESGID	STD	{ int linux_getresgid16(l_gid16_t *rgid, \
 				    l_gid16_t *egid, l_gid16_t *sgid); }
-172	AUE_NULL	MSTD	{ int linux_prctl(void); }
-173	AUE_NULL	MSTD	{ int linux_rt_sigreturn( \
+172	AUE_PRCTL	STD	{ int linux_prctl(l_int option, l_int arg2, l_int arg3, \
+				    l_int arg4, l_int arg5); }
+173	AUE_NULL	STD	{ int linux_rt_sigreturn( \
 				    struct l_ucontext *ucp); }
-174	AUE_NULL	MSTD	{ int linux_rt_sigaction(l_int sig, \
+174	AUE_NULL	STD	{ int linux_rt_sigaction(l_int sig, \
 				    l_sigaction_t *act, l_sigaction_t *oact, \
 				    l_size_t sigsetsize); }
-175	AUE_NULL	MSTD	{ int linux_rt_sigprocmask(l_int how, \
+175	AUE_NULL	STD	{ int linux_rt_sigprocmask(l_int how, \
 				    l_sigset_t *mask, l_sigset_t *omask, \
 				    l_size_t sigsetsize); }
-176	AUE_NULL	MSTD	{ int linux_rt_sigpending(void); }
-177	AUE_NULL	MSTD	{ int linux_rt_sigtimedwait(void); }
-178	AUE_NULL	MSTD	{ int linux_rt_sigqueueinfo(void); }
-179	AUE_NULL	MSTD	{ int linux_rt_sigsuspend( \
+176	AUE_NULL	STD	{ int linux_rt_sigpending(l_sigset_t *set, \
+				    l_size_t sigsetsize); }
+177	AUE_NULL	STD	{ int linux_rt_sigtimedwait(l_sigset_t *mask, \
+				    l_siginfo_t *ptr, \
+				    struct l_timeval *timeout, \
+				    l_size_t sigsetsize); }
+178	AUE_NULL	STD	{ int linux_rt_sigqueueinfo(void); }
+179	AUE_NULL	STD	{ int linux_rt_sigsuspend( \
 				    l_sigset_t *newset, \
 				    l_size_t sigsetsize); }
-180	AUE_NULL	MSTD	{ int linux_pread(l_uint fd, char *buf, \
+180	AUE_PREAD	STD	{ int linux_pread(l_uint fd, char *buf, \
 				    l_size_t nbyte, l_loff_t offset); }
-181	AUE_NULL	MSTD	{ int linux_pwrite(l_uint fd, char *buf, \
+181	AUE_PWRITE	STD	{ int linux_pwrite(l_uint fd, char *buf, \
 				    l_size_t nbyte, l_loff_t offset); }
-182	AUE_NULL	MSTD	{ int linux_chown16(char *path, \
+182	AUE_CHOWN	STD	{ int linux_chown16(char *path, \
 				    l_uid16_t uid, l_gid16_t gid); }
-183	AUE_NULL	MSTD	{ int linux_getcwd(char *buf, \
+183	AUE_GETCWD	STD	{ int linux_getcwd(char *buf, \
 				    l_ulong bufsize); }
-184	AUE_NULL	MSTD	{ int linux_capget(void); }
-185	AUE_NULL	MSTD	{ int linux_capset(void); }
-186	AUE_NULL	MSTD	{ int linux_sigaltstack(l_stack_t *uss, \
+184	AUE_CAPGET	STD	{ int linux_capget(void); }
+185	AUE_CAPSET	STD	{ int linux_capset(void); }
+186	AUE_NULL	STD	{ int linux_sigaltstack(l_stack_t *uss, \
 				    l_stack_t *uoss); }
-187	AUE_NULL	MSTD	{ int linux_sendfile(void); }
-188	AUE_NULL	UNIMPL	getpmsg
-189	AUE_NULL	UNIMPL	putpmsg
-190	AUE_NULL	MSTD	{ int linux_vfork(void); }
-191	AUE_NULL	MSTD	{ int linux_getrlimit(l_uint resource, \
+187	AUE_SENDFILE	STD	{ int linux_sendfile(void); }
+188	AUE_GETPMSG	UNIMPL	getpmsg
+189	AUE_PUTPMSG	UNIMPL	putpmsg
+190	AUE_VFORK	STD	{ int linux_vfork(void); }
+191	AUE_GETRLIMIT	STD	{ int linux_getrlimit(l_uint resource, \
 				    struct l_rlimit *rlim); }
-192	AUE_NULL	MSTD	{ int linux_mmap2(l_ulong addr, l_ulong len, \
+192	AUE_MMAP	STD	{ int linux_mmap2(l_ulong addr, l_ulong len, \
 				    l_ulong prot, l_ulong flags, l_ulong fd, \
 				    l_ulong pgoff); }
-193	AUE_NULL	MSTD	{ int linux_truncate64(char *path, \
+193	AUE_TRUNCATE	STD	{ int linux_truncate64(char *path, \
 				    l_loff_t length); }
-194	AUE_NULL	MSTD	{ int linux_ftruncate64(l_uint fd, \
+194	AUE_FTRUNCATE	STD	{ int linux_ftruncate64(l_uint fd, \
 				    l_loff_t length); }
-195	AUE_NULL	MSTD	{ int linux_stat64(char *filename, \
+195	AUE_STAT	STD	{ int linux_stat64(char *filename, \
 				    struct l_stat64 *statbuf, l_long flags); }
-196	AUE_NULL	MSTD	{ int linux_lstat64(char *filename, \
+196	AUE_LSTAT	STD	{ int linux_lstat64(char *filename, \
 				    struct l_stat64 *statbuf, l_long flags); }
-197	AUE_NULL	MSTD	{ int linux_fstat64(l_ulong fd, \
+197	AUE_FSTAT	STD	{ int linux_fstat64(l_ulong fd, \
 				    struct l_stat64 *statbuf, l_long flags); }
-198	AUE_NULL	MSTD	{ int linux_lchown(char *path, l_uid_t uid, \
+198	AUE_LCHOWN	STD	{ int linux_lchown(char *path, l_uid_t uid, \
 				    l_gid_t gid); }
-199	AUE_NULL	MSTD	{ int linux_getuid(void); }
-200	AUE_NULL	MSTD	{ int linux_getgid(void); }
-201	AUE_NULL	MNOPROTO { int geteuid(void); }
-202	AUE_NULL	MNOPROTO { int getegid(void); }
-203	AUE_NULL	MNOPROTO { int setreuid(uid_t ruid, uid_t euid); }
-204	AUE_NULL	MNOPROTO { int setregid(gid_t rgid, gid_t egid); }
-205	AUE_NULL	MSTD	{ int linux_getgroups(l_int gidsetsize, \
+199	AUE_GETUID	STD	{ int linux_getuid(void); }
+200	AUE_GETGID	STD	{ int linux_getgid(void); }
+201	AUE_GETEUID	NOPROTO	{ int geteuid(void); }
+202	AUE_GETEGID	NOPROTO	{ int getegid(void); }
+203	AUE_SETREUID	NOPROTO	{ int setreuid(uid_t ruid, uid_t euid); }
+204	AUE_SETREGID	NOPROTO	{ int setregid(gid_t rgid, gid_t egid); }
+205	AUE_GETGROUPS	STD	{ int linux_getgroups(l_int gidsetsize, \
 				    l_gid_t *grouplist); }
-206	AUE_NULL	MSTD	{ int linux_setgroups(l_int gidsetsize, \
+206	AUE_SETGROUPS	STD	{ int linux_setgroups(l_int gidsetsize, \
 				    l_gid_t *grouplist); }
-207	AUE_NULL	NODEF	fchown fchown fchown_args int
-208	AUE_NULL	MNOPROTO { int setresuid(uid_t ruid, uid_t euid, \
+207	AUE_FCHOWN	NODEF	fchown fchown fchown_args int
+208	AUE_SETRESUID	NOPROTO	{ int setresuid(uid_t ruid, uid_t euid, \
 				    uid_t suid); }
-209	AUE_NULL	MNOPROTO { int getresuid(uid_t *ruid, uid_t *euid, \
+209	AUE_GETRESUID	NOPROTO	{ int getresuid(uid_t *ruid, uid_t *euid, \
 				    uid_t *suid); }
-210	AUE_NULL	MNOPROTO { int setresgid(gid_t rgid, gid_t egid, \
+210	AUE_SETRESGID	NOPROTO	{ int setresgid(gid_t rgid, gid_t egid, \
 				    gid_t sgid); }
-211	AUE_NULL	MNOPROTO { int getresgid(gid_t *rgid, gid_t *egid, \
+211	AUE_GETRESGID	NOPROTO	{ int getresgid(gid_t *rgid, gid_t *egid, \
 				    gid_t *sgid); }
-212	AUE_NULL	MSTD	{ int linux_chown(char *path, l_uid_t uid, \
+212	AUE_CHOWN	STD	{ int linux_chown(char *path, l_uid_t uid, \
 				    l_gid_t gid); }
-213	AUE_NULL	MNOPROTO { int setuid(uid_t uid); }
-214	AUE_NULL	MNOPROTO { int setgid(gid_t gid); }
-215	AUE_NULL	MSTD	{ int linux_setfsuid(l_uid_t uid); }
-216	AUE_NULL	MSTD	{ int linux_setfsgid(l_gid_t gid); }
-217	AUE_NULL	MSTD	{ int linux_pivot_root(char *new_root, \
+213	AUE_SETUID	NOPROTO	{ int setuid(uid_t uid); }
+214	AUE_SETGID	NOPROTO	{ int setgid(gid_t gid); }
+215	AUE_SETFSUID	STD	{ int linux_setfsuid(l_uid_t uid); }
+216	AUE_SETFSGID	STD	{ int linux_setfsgid(l_gid_t gid); }
+217	AUE_PIVOT_ROOT	STD	{ int linux_pivot_root(char *new_root, \
 				    char *put_old); }
-218	AUE_NULL	MSTD	{ int linux_mincore(l_ulong start, \
+218	AUE_MINCORE	STD	{ int linux_mincore(l_ulong start, \
 				    l_size_t len, u_char *vec); }
-219	AUE_NULL	MNOPROTO { int madvise(void *addr, size_t len, \
+219	AUE_MADVISE	NOPROTO	{ int madvise(void *addr, size_t len, \
 				    int behav); }
-220	AUE_NULL	STD	{ int linux_getdents64(l_uint fd, \
+220	AUE_GETDIRENTRIES	STD { int linux_getdents64(l_uint fd, \
 				    void *dirent, l_uint count); }
-221	AUE_NULL	MSTD	{ int linux_fcntl64(l_uint fd, l_uint cmd, \
+221	AUE_FCNTL	STD	{ int linux_fcntl64(l_uint fd, l_uint cmd, \
 				    uintptr_t arg); }
 222	AUE_NULL	UNIMPL
 223	AUE_NULL	UNIMPL
-224	AUE_NULL	MNOPROTO { int linux_getpid(void); } gettid \
-				    linux_getpid_args void
+224	AUE_NULL	STD	{ long linux_gettid(void); }
 225	AUE_NULL	UNIMPL	linux_readahead
-226	AUE_NULL	MSTD	{ int linux_setxattr(void); }
-227	AUE_NULL	MSTD	{ int linux_lsetxattr(void); }
-228	AUE_NULL	MSTD	{ int linux_fsetxattr(void); }
-229	AUE_NULL	MSTD	{ int linux_getxattr(void); }
-230	AUE_NULL	MSTD	{ int linux_lgetxattr(void); }
-231	AUE_NULL	MSTD	{ int linux_fgetxattr(void); }
-232	AUE_NULL	MSTD	{ int linux_listxattr(void); }
-233	AUE_NULL	MSTD	{ int linux_llistxattr(void); }
-234	AUE_NULL	MSTD	{ int linux_flistxattr(void); }
-235	AUE_NULL	MSTD	{ int linux_removexattr(void); }
-236	AUE_NULL	MSTD	{ int linux_lremovexattr(void); }
-237	AUE_NULL	MSTD	{ int linux_fremovexattr(void); }
-238	AUE_NULL	UNIMPL	linux_tkill
-239	AUE_NULL	UNIMPL	linux_sendfile64
-240	AUE_NULL	UNIMPL	linux_futex
+226	AUE_NULL	STD	{ int linux_setxattr(void); }
+227	AUE_NULL	STD	{ int linux_lsetxattr(void); }
+228	AUE_NULL	STD	{ int linux_fsetxattr(void); }
+229	AUE_NULL	STD	{ int linux_getxattr(void); }
+230	AUE_NULL	STD	{ int linux_lgetxattr(void); }
+231	AUE_NULL	STD	{ int linux_fgetxattr(void); }
+232	AUE_NULL	STD	{ int linux_listxattr(void); }
+233	AUE_NULL	STD	{ int linux_llistxattr(void); }
+234	AUE_NULL	STD	{ int linux_flistxattr(void); }
+235	AUE_NULL	STD	{ int linux_removexattr(void); }
+236	AUE_NULL	STD	{ int linux_lremovexattr(void); }
+237	AUE_NULL	STD	{ int linux_fremovexattr(void); }
+238	AUE_NULL	STD	{ int linux_tkill(int tid, int sig); }
+239	AUE_SENDFILE	UNIMPL	linux_sendfile64
+240	AUE_NULL	STD	{ int linux_sys_futex(void *uaddr, int op, int val, \
+					struct l_timespec *timeout, void *uaddr2, int val3); }
 241	AUE_NULL	UNIMPL	linux_sched_setaffinity
-242	AUE_NULL	UNIMPL	linux_sched_getaffinity
-243	AUE_NULL	UNIMPL	linux_set_thread_area
+242	AUE_NULL	STD	{ int linux_sched_getaffinity(l_pid_t pid, l_uint len, \
+					l_ulong *user_mask_ptr); }
+243	AUE_NULL	STD	{ int linux_set_thread_area(struct l_user_desc *desc); }
 244	AUE_NULL	UNIMPL	linux_get_thread_area
 245	AUE_NULL	UNIMPL	linux_io_setup
 246	AUE_NULL	UNIMPL	linux_io_destroy
 247	AUE_NULL	UNIMPL	linux_io_getevents
-248	AUE_NULL	UNIMPL	linux_io_submit
+248	AUE_NULL	UNIMPL	inux_io_submit
 249	AUE_NULL	UNIMPL	linux_io_cancel
-250	AUE_NULL	MSTD	{ int linux_fadvise64(void); }
+250	AUE_NULL	STD	{ int linux_fadvise64(void); }
 251	AUE_NULL	UNIMPL
-252	AUE_NULL	MNOPROTO { void sys_exit(int rval); } exit_group \
-				    sys_exit_args void
-253	AUE_NULL	UNIMPL	linux_lookup_dcookie
-254	AUE_NULL	UNIMPL	linux_epoll_create
-255	AUE_NULL	UNIMPL	linux_epoll_ctl
-256	AUE_NULL	UNIMPL	linux_epoll_wait
-257	AUE_NULL	UNIMPL	linux_remap_file_pages
-258	AUE_NULL	UNIMPL	linux_set_tid_address
-259	AUE_NULL	UNIMPL	linux_timer_create
-260	AUE_NULL	UNIMPL	linux_timer_settime
-261	AUE_NULL	UNIMPL	linux_timer_gettime
-262	AUE_NULL	UNIMPL	linux_timer_getoverrun
-263	AUE_NULL	UNIMPL	linux_timer_delete
-264	AUE_NULL	UNIMPL	linux_clock_settime
-265	AUE_NULL	UNIMPL	linux_clock_gettime
-266	AUE_NULL	UNIMPL	linux_clock_getres
-267	AUE_NULL	UNIMPL	linux_clock_nanosleep
+252	AUE_EXIT	STD	{ int linux_exit_group(int error_code); }
+253	AUE_NULL	STD	{ int linux_lookup_dcookie(void); }
+254	AUE_NULL	STD	{ int linux_epoll_create(void); }
+255	AUE_NULL	STD	{ int linux_epoll_ctl(void); }
+256	AUE_NULL	STD	{ int linux_epoll_wait(void); }
+257	AUE_NULL	STD	{ int linux_remap_file_pages(void); }
+258	AUE_NULL	STD	{ int linux_set_tid_address(int *tidptr); }
+259	AUE_NULL	STD	{ int linux_timer_create(void); }
+260	AUE_NULL	STD	{ int linux_timer_settime(void); }
+261	AUE_NULL	STD	{ int linux_timer_gettime(void); }
+262	AUE_NULL	STD	{ int linux_timer_getoverrun(void); }
+263	AUE_NULL	STD	{ int linux_timer_delete(void); }
+264	AUE_CLOCK_SETTIME	STD	{ int linux_clock_settime(clockid_t which, struct l_timespec *tp); }
+265	AUE_NULL	STD	{ int linux_clock_gettime(clockid_t which, struct l_timespec *tp); }
+266	AUE_NULL	STD	{ int linux_clock_getres(clockid_t which, struct l_timespec *tp); }
+267	AUE_NULL	STD	{ int linux_clock_nanosleep(clockid_t which, int flags, \
+					struct l_timespec *rqtp, struct l_timespec *rmtp); }
+268	AUE_STATFS	STD	{ int linux_statfs64(char *path, size_t bufsize, struct l_statfs64_buf *buf); }
+269	AUE_FSTATFS	STD	{ int linux_fstatfs64(void); }
+270	AUE_NULL	STD	{ int linux_tgkill(int tgid, int pid, int sig); }
+271	AUE_UTIMES	STD	{ int linux_utimes(char *fname, \
+					struct l_timeval *tptr); }
+272	AUE_NULL	STD	{ int linux_fadvise64_64(void); }
+273	AUE_NULL	UNIMPL
+274	AUE_NULL	STD	{ int linux_mbind(void); }
+275	AUE_NULL	STD	{ int linux_get_mempolicy(void); }
+276	AUE_NULL	STD	{ int linux_set_mempolicy(void); }
+277	AUE_NULL	STD	{ int linux_mq_open(void); }
+278	AUE_NULL	STD	{ int linux_mq_unlink(void); }
+279	AUE_NULL	STD	{ int linux_mq_timedsend(void); }
+280	AUE_NULL	STD	{ int linux_mq_timedreceive(void); }
+281	AUE_NULL	STD	{ int linux_mq_notify(void); }
+282	AUE_NULL	STD	{ int linux_mq_getsetattr(void); }
+283	AUE_NULL	STD	{ int linux_kexec_load(void); }
+284	AUE_NULL	STD	{ int linux_waitid(void); }
+285	AUE_NULL	UNIMPL
+286	AUE_NULL	STD	{ int linux_add_key(void); }
+287	AUE_NULL	STD	{ int linux_request_key(void); }
+288	AUE_NULL	STD	{ int linux_keyctl(void); }
+289	AUE_NULL	STD	{ int linux_ioprio_set(void); }
+290	AUE_NULL	STD	{ int linux_ioprio_get(void); }
+291	AUE_NULL	STD	{ int linux_inotify_init(void); }
+292	AUE_NULL	STD	{ int linux_inotify_add_watch(void); }
+293	AUE_NULL	STD	{ int linux_inotify_rm_watch(void); }
+294	AUE_NULL	STD	{ int linux_migrate_pages(void); }
+295	AUE_OPEN_RWTC	STD	{ int linux_openat(l_int dfd, char *filename, \
+					l_int flags, l_int mode); }
+296	AUE_NULL	STD	{ int linux_mkdirat(void); }
+297	AUE_NULL	STD	{ int linux_mknodat(void); }
+298	AUE_NULL	STD	{ int linux_fchownat(void); }
+299	AUE_NULL	STD	{ int linux_futimesat(void); }
+300	AUE_NULL	STD	{ int linux_fstatat64(void); }
+301	AUE_NULL	STD	{ int linux_unlinkat(void); }
+302	AUE_NULL	STD	{ int linux_renameat(void); }
+303	AUE_NULL	STD	{ int linux_linkat(void); }
+304	AUE_NULL	STD	{ int linux_symlinkat(void); }
+305	AUE_NULL	STD	{ int linux_readlinkat(void); }
+306	AUE_NULL	STD	{ int linux_fchmodat(void); }
+307	AUE_NULL	STD	{ int linux_faccessat(void); }
+308	AUE_NULL	STD	{ int linux_pselect6(void); }
+309	AUE_NULL	STD	{ int linux_ppoll(void); }
+310	AUE_NULL	STD	{ int linux_unshare(void); }
Index: syscalls.conf
===================================================================
RCS file: /home/cvs/src/sys/amd64/linux32/syscalls.conf,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L sys/amd64/linux32/syscalls.conf -L sys/amd64/linux32/syscalls.conf -u -r1.1.1.1 -r1.2
--- sys/amd64/linux32/syscalls.conf
+++ sys/amd64/linux32/syscalls.conf
@@ -1,4 +1,4 @@
-# $FreeBSD: src/sys/amd64/linux32/syscalls.conf,v 1.1 2004/08/16 07:55:06 tjr Exp $
+# $FreeBSD: src/sys/amd64/linux32/syscalls.conf,v 1.2 2006/08/15 17:25:54 jhb Exp $
 sysnames="/dev/null"
 sysproto="linux32_proto.h"
 sysproto_h=_LINUX_SYSPROTO_H_
@@ -8,4 +8,4 @@
 syscallprefix="LINUX_SYS_"
 switchname="linux_sysent"
 namesname="linux_syscallnames"
-sysvec="\n"
+systrace="/dev/null"
Index: linux32_sysent.c
===================================================================
RCS file: /home/cvs/src/sys/amd64/linux32/linux32_sysent.c,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L sys/amd64/linux32/linux32_sysent.c -L sys/amd64/linux32/linux32_sysent.c -u -r1.1.1.1 -r1.2
--- sys/amd64/linux32/linux32_sysent.c
+++ sys/amd64/linux32/linux32_sysent.c
@@ -2,8 +2,8 @@
  * System call switch table.
  *
  * DO NOT EDIT-- this file is automatically generated.
- * $FreeBSD: src/sys/amd64/linux32/linux32_sysent.c,v 1.5.2.1 2005/07/20 17:43:52 jhb Exp $
- * created from FreeBSD: src/sys/amd64/linux32/syscalls.master,v 1.4.2.1 2005/07/20 17:42:14 jhb Exp 
+ * $FreeBSD: src/sys/amd64/linux32/linux32_sysent.c,v 1.33 2007/09/18 19:50:32 dwmalone Exp $
+ * created from FreeBSD: src/sys/amd64/linux32/syscalls.master,v 1.29 2007/08/28 12:26:34 kib Exp 
  */
 
 #include <bsm/audit_kevents.h>
@@ -20,272 +20,315 @@
 /* The casts are bogus but will do for now. */
 struct sysent linux_sysent[] = {
 #define	nosys	linux_nosys
-	{ 0, (sy_call_t *)nosys, AUE_NULL },			/* 0 = setup */
-	{ SYF_MPSAFE | AS(sys_exit_args), (sy_call_t *)sys_exit, AUE_NULL },	/* 1 = exit */
-	{ SYF_MPSAFE | 0, (sy_call_t *)linux_fork, AUE_NULL },	/* 2 = linux_fork */
-	{ SYF_MPSAFE | AS(read_args), (sy_call_t *)read, AUE_NULL },	/* 3 = read */
-	{ SYF_MPSAFE | AS(write_args), (sy_call_t *)write, AUE_NULL },	/* 4 = write */
-	{ SYF_MPSAFE | AS(linux_open_args), (sy_call_t *)linux_open, AUE_NULL },	/* 5 = linux_open */
-	{ SYF_MPSAFE | AS(close_args), (sy_call_t *)close, AUE_NULL },	/* 6 = close */
-	{ SYF_MPSAFE | AS(linux_waitpid_args), (sy_call_t *)linux_waitpid, AUE_NULL },	/* 7 = linux_waitpid */
-	{ SYF_MPSAFE | AS(linux_creat_args), (sy_call_t *)linux_creat, AUE_NULL },	/* 8 = linux_creat */
-	{ SYF_MPSAFE | AS(linux_link_args), (sy_call_t *)linux_link, AUE_NULL },	/* 9 = linux_link */
-	{ SYF_MPSAFE | AS(linux_unlink_args), (sy_call_t *)linux_unlink, AUE_NULL },	/* 10 = linux_unlink */
-	{ SYF_MPSAFE | AS(linux_execve_args), (sy_call_t *)linux_execve, AUE_NULL },	/* 11 = linux_execve */
-	{ SYF_MPSAFE | AS(linux_chdir_args), (sy_call_t *)linux_chdir, AUE_NULL },	/* 12 = linux_chdir */
-	{ SYF_MPSAFE | AS(linux_time_args), (sy_call_t *)linux_time, AUE_NULL },	/* 13 = linux_time */
-	{ SYF_MPSAFE | AS(linux_mknod_args), (sy_call_t *)linux_mknod, AUE_NULL },	/* 14 = linux_mknod */
-	{ SYF_MPSAFE | AS(linux_chmod_args), (sy_call_t *)linux_chmod, AUE_NULL },	/* 15 = linux_chmod */
-	{ SYF_MPSAFE | AS(linux_lchown16_args), (sy_call_t *)linux_lchown16, AUE_NULL },	/* 16 = linux_lchown16 */
-	{ 0, (sy_call_t *)nosys, AUE_NULL },			/* 17 = break */
-	{ 0, (sy_call_t *)nosys, AUE_NULL },			/* 18 = stat */
-	{ SYF_MPSAFE | AS(linux_lseek_args), (sy_call_t *)linux_lseek, AUE_NULL },	/* 19 = linux_lseek */
-	{ SYF_MPSAFE | 0, (sy_call_t *)linux_getpid, AUE_NULL },	/* 20 = linux_getpid */
-	{ AS(linux_mount_args), (sy_call_t *)linux_mount, AUE_NULL },	/* 21 = linux_mount */
-	{ AS(linux_oldumount_args), (sy_call_t *)linux_oldumount, AUE_NULL },	/* 22 = linux_oldumount */
-	{ SYF_MPSAFE | AS(linux_setuid16_args), (sy_call_t *)linux_setuid16, AUE_NULL },	/* 23 = linux_setuid16 */
-	{ SYF_MPSAFE | 0, (sy_call_t *)linux_getuid16, AUE_NULL },	/* 24 = linux_getuid16 */
-	{ SYF_MPSAFE | 0, (sy_call_t *)linux_stime, AUE_NULL },	/* 25 = linux_stime */
-	{ SYF_MPSAFE | AS(linux_ptrace_args), (sy_call_t *)linux_ptrace, AUE_NULL },	/* 26 = linux_ptrace */
-	{ SYF_MPSAFE | AS(linux_alarm_args), (sy_call_t *)linux_alarm, AUE_NULL },	/* 27 = linux_alarm */
-	{ 0, (sy_call_t *)nosys, AUE_NULL },			/* 28 = fstat */
-	{ SYF_MPSAFE | 0, (sy_call_t *)linux_pause, AUE_NULL },	/* 29 = linux_pause */
-	{ SYF_MPSAFE | AS(linux_utime_args), (sy_call_t *)linux_utime, AUE_NULL },	/* 30 = linux_utime */
-	{ 0, (sy_call_t *)nosys, AUE_NULL },			/* 31 = stty */
-	{ 0, (sy_call_t *)nosys, AUE_NULL },			/* 32 = gtty */
-	{ SYF_MPSAFE | AS(linux_access_args), (sy_call_t *)linux_access, AUE_NULL },	/* 33 = linux_access */
-	{ SYF_MPSAFE | AS(linux_nice_args), (sy_call_t *)linux_nice, AUE_NULL },	/* 34 = linux_nice */
-	{ 0, (sy_call_t *)nosys, AUE_NULL },			/* 35 = ftime */
-	{ SYF_MPSAFE | 0, (sy_call_t *)sync, AUE_NULL },	/* 36 = sync */
-	{ SYF_MPSAFE | AS(linux_kill_args), (sy_call_t *)linux_kill, AUE_NULL },	/* 37 = linux_kill */
-	{ SYF_MPSAFE | AS(linux_rename_args), (sy_call_t *)linux_rename, AUE_NULL },	/* 38 = linux_rename */
-	{ SYF_MPSAFE | AS(linux_mkdir_args), (sy_call_t *)linux_mkdir, AUE_NULL },	/* 39 = linux_mkdir */
-	{ SYF_MPSAFE | AS(linux_rmdir_args), (sy_call_t *)linux_rmdir, AUE_NULL },	/* 40 = linux_rmdir */
-	{ SYF_MPSAFE | AS(dup_args), (sy_call_t *)dup, AUE_NULL },	/* 41 = dup */
-	{ SYF_MPSAFE | AS(linux_pipe_args), (sy_call_t *)linux_pipe, AUE_NULL },	/* 42 = linux_pipe */
-	{ SYF_MPSAFE | AS(linux_times_args), (sy_call_t *)linux_times, AUE_NULL },	/* 43 = linux_times */
-	{ 0, (sy_call_t *)nosys, AUE_NULL },			/* 44 = prof */
-	{ AS(linux_brk_args), (sy_call_t *)linux_brk, AUE_NULL },	/* 45 = linux_brk */
-	{ SYF_MPSAFE | AS(linux_setgid16_args), (sy_call_t *)linux_setgid16, AUE_NULL },	/* 46 = linux_setgid16 */
-	{ SYF_MPSAFE | 0, (sy_call_t *)linux_getgid16, AUE_NULL },	/* 47 = linux_getgid16 */
-	{ SYF_MPSAFE | AS(linux_signal_args), (sy_call_t *)linux_signal, AUE_NULL },	/* 48 = linux_signal */
-	{ SYF_MPSAFE | 0, (sy_call_t *)linux_geteuid16, AUE_NULL },	/* 49 = linux_geteuid16 */
-	{ SYF_MPSAFE | 0, (sy_call_t *)linux_getegid16, AUE_NULL },	/* 50 = linux_getegid16 */
-	{ SYF_MPSAFE | AS(acct_args), (sy_call_t *)acct, AUE_NULL },	/* 51 = acct */
-	{ AS(linux_umount_args), (sy_call_t *)linux_umount, AUE_NULL },	/* 52 = linux_umount */
-	{ 0, (sy_call_t *)nosys, AUE_NULL },			/* 53 = lock */
-	{ AS(linux_ioctl_args), (sy_call_t *)linux_ioctl, AUE_NULL },	/* 54 = linux_ioctl */
-	{ SYF_MPSAFE | AS(linux_fcntl_args), (sy_call_t *)linux_fcntl, AUE_NULL },	/* 55 = linux_fcntl */
-	{ 0, (sy_call_t *)nosys, AUE_NULL },			/* 56 = mpx */
-	{ SYF_MPSAFE | AS(setpgid_args), (sy_call_t *)setpgid, AUE_NULL },	/* 57 = setpgid */
-	{ 0, (sy_call_t *)nosys, AUE_NULL },			/* 58 = ulimit */
-	{ SYF_MPSAFE | 0, (sy_call_t *)linux_olduname, AUE_NULL },	/* 59 = linux_olduname */
-	{ SYF_MPSAFE | AS(umask_args), (sy_call_t *)umask, AUE_NULL },	/* 60 = umask */
-	{ SYF_MPSAFE | AS(chroot_args), (sy_call_t *)chroot, AUE_NULL },	/* 61 = chroot */
-	{ SYF_MPSAFE | AS(linux_ustat_args), (sy_call_t *)linux_ustat, AUE_NULL },	/* 62 = linux_ustat */
-	{ SYF_MPSAFE | AS(dup2_args), (sy_call_t *)dup2, AUE_NULL },	/* 63 = dup2 */
-	{ SYF_MPSAFE | 0, (sy_call_t *)getppid, AUE_NULL },	/* 64 = getppid */
-	{ SYF_MPSAFE | 0, (sy_call_t *)getpgrp, AUE_NULL },	/* 65 = getpgrp */
-	{ SYF_MPSAFE | 0, (sy_call_t *)setsid, AUE_NULL },	/* 66 = setsid */
-	{ SYF_MPSAFE | AS(linux_sigaction_args), (sy_call_t *)linux_sigaction, AUE_NULL },	/* 67 = linux_sigaction */
-	{ SYF_MPSAFE | 0, (sy_call_t *)linux_sgetmask, AUE_NULL },	/* 68 = linux_sgetmask */
-	{ SYF_MPSAFE | AS(linux_ssetmask_args), (sy_call_t *)linux_ssetmask, AUE_NULL },	/* 69 = linux_ssetmask */
-	{ SYF_MPSAFE | AS(linux_setreuid16_args), (sy_call_t *)linux_setreuid16, AUE_NULL },	/* 70 = linux_setreuid16 */
-	{ SYF_MPSAFE | AS(linux_setregid16_args), (sy_call_t *)linux_setregid16, AUE_NULL },	/* 71 = linux_setregid16 */
-	{ SYF_MPSAFE | AS(linux_sigsuspend_args), (sy_call_t *)linux_sigsuspend, AUE_NULL },	/* 72 = linux_sigsuspend */
-	{ SYF_MPSAFE | AS(linux_sigpending_args), (sy_call_t *)linux_sigpending, AUE_NULL },	/* 73 = linux_sigpending */
-	{ SYF_MPSAFE | AS(sethostname_args), (sy_call_t *)osethostname, AUE_NULL },	/* 74 = osethostname */
-	{ SYF_MPSAFE | AS(linux_setrlimit_args), (sy_call_t *)linux_setrlimit, AUE_NULL },	/* 75 = linux_setrlimit */
-	{ SYF_MPSAFE | AS(linux_old_getrlimit_args), (sy_call_t *)linux_old_getrlimit, AUE_NULL },	/* 76 = linux_old_getrlimit */
-	{ SYF_MPSAFE | AS(linux_getrusage_args), (sy_call_t *)linux_getrusage, AUE_NULL },	/* 77 = linux_getrusage */
-	{ SYF_MPSAFE | AS(linux_gettimeofday_args), (sy_call_t *)linux_gettimeofday, AUE_NULL },	/* 78 = linux_gettimeofday */
-	{ SYF_MPSAFE | AS(linux_settimeofday_args), (sy_call_t *)linux_settimeofday, AUE_NULL },	/* 79 = linux_settimeofday */
-	{ SYF_MPSAFE | AS(linux_getgroups16_args), (sy_call_t *)linux_getgroups16, AUE_NULL },	/* 80 = linux_getgroups16 */
-	{ SYF_MPSAFE | AS(linux_setgroups16_args), (sy_call_t *)linux_setgroups16, AUE_NULL },	/* 81 = linux_setgroups16 */
-	{ SYF_MPSAFE | AS(linux_old_select_args), (sy_call_t *)linux_old_select, AUE_NULL },	/* 82 = linux_old_select */
-	{ SYF_MPSAFE | AS(linux_symlink_args), (sy_call_t *)linux_symlink, AUE_NULL },	/* 83 = linux_symlink */
-	{ 0, (sy_call_t *)nosys, AUE_NULL },			/* 84 = ostat */
-	{ SYF_MPSAFE | AS(linux_readlink_args), (sy_call_t *)linux_readlink, AUE_NULL },	/* 85 = linux_readlink */
-	{ 0, (sy_call_t *)nosys, AUE_NULL },			/* 86 = linux_uselib */
-	{ SYF_MPSAFE | AS(swapon_args), (sy_call_t *)swapon, AUE_NULL },	/* 87 = swapon */
-	{ SYF_MPSAFE | AS(linux_reboot_args), (sy_call_t *)linux_reboot, AUE_NULL },	/* 88 = linux_reboot */
-	{ AS(linux_readdir_args), (sy_call_t *)linux_readdir, AUE_NULL },	/* 89 = linux_readdir */
-	{ SYF_MPSAFE | AS(linux_mmap_args), (sy_call_t *)linux_mmap, AUE_NULL },	/* 90 = linux_mmap */
-	{ SYF_MPSAFE | AS(munmap_args), (sy_call_t *)munmap, AUE_NULL },	/* 91 = munmap */
-	{ SYF_MPSAFE | AS(linux_truncate_args), (sy_call_t *)linux_truncate, AUE_NULL },	/* 92 = linux_truncate */
-	{ SYF_MPSAFE | AS(oftruncate_args), (sy_call_t *)oftruncate, AUE_NULL },	/* 93 = oftruncate */
-	{ SYF_MPSAFE | AS(fchmod_args), (sy_call_t *)fchmod, AUE_NULL },	/* 94 = fchmod */
-	{ SYF_MPSAFE | AS(fchown_args), (sy_call_t *)fchown, AUE_NULL },	/* 95 = fchown */
-	{ SYF_MPSAFE | AS(linux_getpriority_args), (sy_call_t *)linux_getpriority, AUE_NULL },	/* 96 = linux_getpriority */
-	{ SYF_MPSAFE | AS(setpriority_args), (sy_call_t *)setpriority, AUE_NULL },	/* 97 = setpriority */
-	{ 0, (sy_call_t *)nosys, AUE_NULL },			/* 98 = profil */
-	{ SYF_MPSAFE | AS(linux_statfs_args), (sy_call_t *)linux_statfs, AUE_NULL },	/* 99 = linux_statfs */
-	{ SYF_MPSAFE | AS(linux_fstatfs_args), (sy_call_t *)linux_fstatfs, AUE_NULL },	/* 100 = linux_fstatfs */
-	{ 0, (sy_call_t *)nosys, AUE_NULL },			/* 101 = ioperm */
-	{ SYF_MPSAFE | AS(linux_socketcall_args), (sy_call_t *)linux_socketcall, AUE_NULL },	/* 102 = linux_socketcall */
-	{ SYF_MPSAFE | AS(linux_syslog_args), (sy_call_t *)linux_syslog, AUE_NULL },	/* 103 = linux_syslog */
-	{ SYF_MPSAFE | AS(linux_setitimer_args), (sy_call_t *)linux_setitimer, AUE_NULL },	/* 104 = linux_setitimer */
-	{ SYF_MPSAFE | AS(linux_getitimer_args), (sy_call_t *)linux_getitimer, AUE_NULL },	/* 105 = linux_getitimer */
-	{ SYF_MPSAFE | AS(linux_newstat_args), (sy_call_t *)linux_newstat, AUE_NULL },	/* 106 = linux_newstat */
-	{ SYF_MPSAFE | AS(linux_newlstat_args), (sy_call_t *)linux_newlstat, AUE_NULL },	/* 107 = linux_newlstat */
-	{ SYF_MPSAFE | AS(linux_newfstat_args), (sy_call_t *)linux_newfstat, AUE_NULL },	/* 108 = linux_newfstat */
-	{ SYF_MPSAFE | 0, (sy_call_t *)linux_uname, AUE_NULL },	/* 109 = linux_uname */
-	{ 0, (sy_call_t *)nosys, AUE_NULL },			/* 110 = iopl */
-	{ SYF_MPSAFE | 0, (sy_call_t *)linux_vhangup, AUE_NULL },	/* 111 = linux_vhangup */
-	{ 0, (sy_call_t *)nosys, AUE_NULL },			/* 112 = idle */
-	{ 0, (sy_call_t *)nosys, AUE_NULL },			/* 113 = vm86old */
-	{ SYF_MPSAFE | AS(linux_wait4_args), (sy_call_t *)linux_wait4, AUE_NULL },	/* 114 = linux_wait4 */
-	{ SYF_MPSAFE | 0, (sy_call_t *)linux_swapoff, AUE_NULL },	/* 115 = linux_swapoff */
-	{ SYF_MPSAFE | AS(linux_sysinfo_args), (sy_call_t *)linux_sysinfo, AUE_NULL },	/* 116 = linux_sysinfo */
-	{ AS(linux_ipc_args), (sy_call_t *)linux_ipc, AUE_NULL },	/* 117 = linux_ipc */
-	{ SYF_MPSAFE | AS(fsync_args), (sy_call_t *)fsync, AUE_NULL },	/* 118 = fsync */
-	{ SYF_MPSAFE | AS(linux_sigreturn_args), (sy_call_t *)linux_sigreturn, AUE_NULL },	/* 119 = linux_sigreturn */
-	{ SYF_MPSAFE | AS(linux_clone_args), (sy_call_t *)linux_clone, AUE_NULL },	/* 120 = linux_clone */
-	{ SYF_MPSAFE | AS(setdomainname_args), (sy_call_t *)setdomainname, AUE_NULL },	/* 121 = setdomainname */
-	{ SYF_MPSAFE | AS(linux_newuname_args), (sy_call_t *)linux_newuname, AUE_NULL },	/* 122 = linux_newuname */
-	{ 0, (sy_call_t *)nosys, AUE_NULL },			/* 123 = modify_ldt */
-	{ SYF_MPSAFE | 0, (sy_call_t *)linux_adjtimex, AUE_NULL },	/* 124 = linux_adjtimex */
-	{ SYF_MPSAFE | AS(linux_mprotect_args), (sy_call_t *)linux_mprotect, AUE_NULL },	/* 125 = linux_mprotect */
-	{ SYF_MPSAFE | AS(linux_sigprocmask_args), (sy_call_t *)linux_sigprocmask, AUE_NULL },	/* 126 = linux_sigprocmask */
-	{ SYF_MPSAFE | 0, (sy_call_t *)linux_create_module, AUE_NULL },	/* 127 = linux_create_module */
-	{ SYF_MPSAFE | 0, (sy_call_t *)linux_init_module, AUE_NULL },	/* 128 = linux_init_module */
-	{ SYF_MPSAFE | 0, (sy_call_t *)linux_delete_module, AUE_NULL },	/* 129 = linux_delete_module */
-	{ SYF_MPSAFE | 0, (sy_call_t *)linux_get_kernel_syms, AUE_NULL },	/* 130 = linux_get_kernel_syms */
-	{ SYF_MPSAFE | 0, (sy_call_t *)linux_quotactl, AUE_NULL },	/* 131 = linux_quotactl */
-	{ SYF_MPSAFE | AS(getpgid_args), (sy_call_t *)getpgid, AUE_NULL },	/* 132 = getpgid */
-	{ SYF_MPSAFE | AS(fchdir_args), (sy_call_t *)fchdir, AUE_NULL },	/* 133 = fchdir */
-	{ SYF_MPSAFE | 0, (sy_call_t *)linux_bdflush, AUE_NULL },	/* 134 = linux_bdflush */
-	{ SYF_MPSAFE | AS(linux_sysfs_args), (sy_call_t *)linux_sysfs, AUE_NULL },	/* 135 = linux_sysfs */
-	{ SYF_MPSAFE | AS(linux_personality_args), (sy_call_t *)linux_personality, AUE_NULL },	/* 136 = linux_personality */
-	{ 0, (sy_call_t *)nosys, AUE_NULL },			/* 137 = afs_syscall */
-	{ SYF_MPSAFE | AS(linux_setfsuid16_args), (sy_call_t *)linux_setfsuid16, AUE_NULL },	/* 138 = linux_setfsuid16 */
-	{ SYF_MPSAFE | AS(linux_setfsgid16_args), (sy_call_t *)linux_setfsgid16, AUE_NULL },	/* 139 = linux_setfsgid16 */
-	{ SYF_MPSAFE | AS(linux_llseek_args), (sy_call_t *)linux_llseek, AUE_NULL },	/* 140 = linux_llseek */
-	{ AS(linux_getdents_args), (sy_call_t *)linux_getdents, AUE_NULL },	/* 141 = linux_getdents */
-	{ SYF_MPSAFE | AS(linux_select_args), (sy_call_t *)linux_select, AUE_NULL },	/* 142 = linux_select */
-	{ SYF_MPSAFE | AS(flock_args), (sy_call_t *)flock, AUE_NULL },	/* 143 = flock */
-	{ SYF_MPSAFE | AS(linux_msync_args), (sy_call_t *)linux_msync, AUE_NULL },	/* 144 = linux_msync */
-	{ SYF_MPSAFE | AS(linux_readv_args), (sy_call_t *)linux_readv, AUE_NULL },	/* 145 = linux_readv */
-	{ SYF_MPSAFE | AS(linux_writev_args), (sy_call_t *)linux_writev, AUE_NULL },	/* 146 = linux_writev */
-	{ SYF_MPSAFE | AS(linux_getsid_args), (sy_call_t *)linux_getsid, AUE_NULL },	/* 147 = linux_getsid */
-	{ SYF_MPSAFE | AS(linux_fdatasync_args), (sy_call_t *)linux_fdatasync, AUE_NULL },	/* 148 = linux_fdatasync */
-	{ SYF_MPSAFE | AS(linux_sysctl_args), (sy_call_t *)linux_sysctl, AUE_NULL },	/* 149 = linux_sysctl */
-	{ SYF_MPSAFE | AS(mlock_args), (sy_call_t *)mlock, AUE_NULL },	/* 150 = mlock */
-	{ SYF_MPSAFE | AS(munlock_args), (sy_call_t *)munlock, AUE_NULL },	/* 151 = munlock */
-	{ SYF_MPSAFE | AS(mlockall_args), (sy_call_t *)mlockall, AUE_NULL },	/* 152 = mlockall */
-	{ SYF_MPSAFE | 0, (sy_call_t *)munlockall, AUE_NULL },	/* 153 = munlockall */
-	{ SYF_MPSAFE | AS(sched_setparam_args), (sy_call_t *)sched_setparam, AUE_NULL },	/* 154 = sched_setparam */
-	{ SYF_MPSAFE | AS(sched_getparam_args), (sy_call_t *)sched_getparam, AUE_NULL },	/* 155 = sched_getparam */
-	{ SYF_MPSAFE | AS(linux_sched_setscheduler_args), (sy_call_t *)linux_sched_setscheduler, AUE_NULL },	/* 156 = linux_sched_setscheduler */
-	{ SYF_MPSAFE | AS(linux_sched_getscheduler_args), (sy_call_t *)linux_sched_getscheduler, AUE_NULL },	/* 157 = linux_sched_getscheduler */
-	{ SYF_MPSAFE | 0, (sy_call_t *)sched_yield, AUE_NULL },	/* 158 = sched_yield */
-	{ SYF_MPSAFE | AS(linux_sched_get_priority_max_args), (sy_call_t *)linux_sched_get_priority_max, AUE_NULL },	/* 159 = linux_sched_get_priority_max */
-	{ SYF_MPSAFE | AS(linux_sched_get_priority_min_args), (sy_call_t *)linux_sched_get_priority_min, AUE_NULL },	/* 160 = linux_sched_get_priority_min */
-	{ SYF_MPSAFE | AS(linux_sched_rr_get_interval_args), (sy_call_t *)linux_sched_rr_get_interval, AUE_NULL },	/* 161 = linux_sched_rr_get_interval */
-	{ SYF_MPSAFE | AS(linux_nanosleep_args), (sy_call_t *)linux_nanosleep, AUE_NULL },	/* 162 = linux_nanosleep */
-	{ SYF_MPSAFE | AS(linux_mremap_args), (sy_call_t *)linux_mremap, AUE_NULL },	/* 163 = linux_mremap */
-	{ SYF_MPSAFE | AS(linux_setresuid16_args), (sy_call_t *)linux_setresuid16, AUE_NULL },	/* 164 = linux_setresuid16 */
-	{ SYF_MPSAFE | AS(linux_getresuid16_args), (sy_call_t *)linux_getresuid16, AUE_NULL },	/* 165 = linux_getresuid16 */
-	{ 0, (sy_call_t *)nosys, AUE_NULL },			/* 166 = vm86 */
-	{ SYF_MPSAFE | 0, (sy_call_t *)linux_query_module, AUE_NULL },	/* 167 = linux_query_module */
-	{ SYF_MPSAFE | AS(poll_args), (sy_call_t *)poll, AUE_NULL },	/* 168 = poll */
-	{ SYF_MPSAFE | 0, (sy_call_t *)linux_nfsservctl, AUE_NULL },	/* 169 = linux_nfsservctl */
-	{ SYF_MPSAFE | AS(linux_setresgid16_args), (sy_call_t *)linux_setresgid16, AUE_NULL },	/* 170 = linux_setresgid16 */
-	{ SYF_MPSAFE | AS(linux_getresgid16_args), (sy_call_t *)linux_getresgid16, AUE_NULL },	/* 171 = linux_getresgid16 */
-	{ SYF_MPSAFE | 0, (sy_call_t *)linux_prctl, AUE_NULL },	/* 172 = linux_prctl */
-	{ SYF_MPSAFE | AS(linux_rt_sigreturn_args), (sy_call_t *)linux_rt_sigreturn, AUE_NULL },	/* 173 = linux_rt_sigreturn */
-	{ SYF_MPSAFE | AS(linux_rt_sigaction_args), (sy_call_t *)linux_rt_sigaction, AUE_NULL },	/* 174 = linux_rt_sigaction */
-	{ SYF_MPSAFE | AS(linux_rt_sigprocmask_args), (sy_call_t *)linux_rt_sigprocmask, AUE_NULL },	/* 175 = linux_rt_sigprocmask */
-	{ SYF_MPSAFE | 0, (sy_call_t *)linux_rt_sigpending, AUE_NULL },	/* 176 = linux_rt_sigpending */
-	{ SYF_MPSAFE | 0, (sy_call_t *)linux_rt_sigtimedwait, AUE_NULL },	/* 177 = linux_rt_sigtimedwait */
-	{ SYF_MPSAFE | 0, (sy_call_t *)linux_rt_sigqueueinfo, AUE_NULL },	/* 178 = linux_rt_sigqueueinfo */
-	{ SYF_MPSAFE | AS(linux_rt_sigsuspend_args), (sy_call_t *)linux_rt_sigsuspend, AUE_NULL },	/* 179 = linux_rt_sigsuspend */
-	{ SYF_MPSAFE | AS(linux_pread_args), (sy_call_t *)linux_pread, AUE_NULL },	/* 180 = linux_pread */
-	{ SYF_MPSAFE | AS(linux_pwrite_args), (sy_call_t *)linux_pwrite, AUE_NULL },	/* 181 = linux_pwrite */
-	{ SYF_MPSAFE | AS(linux_chown16_args), (sy_call_t *)linux_chown16, AUE_NULL },	/* 182 = linux_chown16 */
-	{ SYF_MPSAFE | AS(linux_getcwd_args), (sy_call_t *)linux_getcwd, AUE_NULL },	/* 183 = linux_getcwd */
-	{ SYF_MPSAFE | 0, (sy_call_t *)linux_capget, AUE_NULL },	/* 184 = linux_capget */
-	{ SYF_MPSAFE | 0, (sy_call_t *)linux_capset, AUE_NULL },	/* 185 = linux_capset */
-	{ SYF_MPSAFE | AS(linux_sigaltstack_args), (sy_call_t *)linux_sigaltstack, AUE_NULL },	/* 186 = linux_sigaltstack */
-	{ SYF_MPSAFE | 0, (sy_call_t *)linux_sendfile, AUE_NULL },	/* 187 = linux_sendfile */
-	{ 0, (sy_call_t *)nosys, AUE_NULL },			/* 188 = getpmsg */
-	{ 0, (sy_call_t *)nosys, AUE_NULL },			/* 189 = putpmsg */
-	{ SYF_MPSAFE | 0, (sy_call_t *)linux_vfork, AUE_NULL },	/* 190 = linux_vfork */
-	{ SYF_MPSAFE | AS(linux_getrlimit_args), (sy_call_t *)linux_getrlimit, AUE_NULL },	/* 191 = linux_getrlimit */
-	{ SYF_MPSAFE | AS(linux_mmap2_args), (sy_call_t *)linux_mmap2, AUE_NULL },	/* 192 = linux_mmap2 */
-	{ SYF_MPSAFE | AS(linux_truncate64_args), (sy_call_t *)linux_truncate64, AUE_NULL },	/* 193 = linux_truncate64 */
-	{ SYF_MPSAFE | AS(linux_ftruncate64_args), (sy_call_t *)linux_ftruncate64, AUE_NULL },	/* 194 = linux_ftruncate64 */
-	{ SYF_MPSAFE | AS(linux_stat64_args), (sy_call_t *)linux_stat64, AUE_NULL },	/* 195 = linux_stat64 */
-	{ SYF_MPSAFE | AS(linux_lstat64_args), (sy_call_t *)linux_lstat64, AUE_NULL },	/* 196 = linux_lstat64 */
-	{ SYF_MPSAFE | AS(linux_fstat64_args), (sy_call_t *)linux_fstat64, AUE_NULL },	/* 197 = linux_fstat64 */
-	{ SYF_MPSAFE | AS(linux_lchown_args), (sy_call_t *)linux_lchown, AUE_NULL },	/* 198 = linux_lchown */
-	{ SYF_MPSAFE | 0, (sy_call_t *)linux_getuid, AUE_NULL },	/* 199 = linux_getuid */
-	{ SYF_MPSAFE | 0, (sy_call_t *)linux_getgid, AUE_NULL },	/* 200 = linux_getgid */
-	{ SYF_MPSAFE | 0, (sy_call_t *)geteuid, AUE_NULL },	/* 201 = geteuid */
-	{ SYF_MPSAFE | 0, (sy_call_t *)getegid, AUE_NULL },	/* 202 = getegid */
-	{ SYF_MPSAFE | AS(setreuid_args), (sy_call_t *)setreuid, AUE_NULL },	/* 203 = setreuid */
-	{ SYF_MPSAFE | AS(setregid_args), (sy_call_t *)setregid, AUE_NULL },	/* 204 = setregid */
-	{ SYF_MPSAFE | AS(linux_getgroups_args), (sy_call_t *)linux_getgroups, AUE_NULL },	/* 205 = linux_getgroups */
-	{ SYF_MPSAFE | AS(linux_setgroups_args), (sy_call_t *)linux_setgroups, AUE_NULL },	/* 206 = linux_setgroups */
-	{ AS(fchown_args), (sy_call_t *)fchown, AUE_NULL },	/* 207 = fchown */
-	{ SYF_MPSAFE | AS(setresuid_args), (sy_call_t *)setresuid, AUE_NULL },	/* 208 = setresuid */
-	{ SYF_MPSAFE | AS(getresuid_args), (sy_call_t *)getresuid, AUE_NULL },	/* 209 = getresuid */
-	{ SYF_MPSAFE | AS(setresgid_args), (sy_call_t *)setresgid, AUE_NULL },	/* 210 = setresgid */
-	{ SYF_MPSAFE | AS(getresgid_args), (sy_call_t *)getresgid, AUE_NULL },	/* 211 = getresgid */
-	{ SYF_MPSAFE | AS(linux_chown_args), (sy_call_t *)linux_chown, AUE_NULL },	/* 212 = linux_chown */
-	{ SYF_MPSAFE | AS(setuid_args), (sy_call_t *)setuid, AUE_NULL },	/* 213 = setuid */
-	{ SYF_MPSAFE | AS(setgid_args), (sy_call_t *)setgid, AUE_NULL },	/* 214 = setgid */
-	{ SYF_MPSAFE | AS(linux_setfsuid_args), (sy_call_t *)linux_setfsuid, AUE_NULL },	/* 215 = linux_setfsuid */
-	{ SYF_MPSAFE | AS(linux_setfsgid_args), (sy_call_t *)linux_setfsgid, AUE_NULL },	/* 216 = linux_setfsgid */
-	{ SYF_MPSAFE | AS(linux_pivot_root_args), (sy_call_t *)linux_pivot_root, AUE_NULL },	/* 217 = linux_pivot_root */
-	{ SYF_MPSAFE | AS(linux_mincore_args), (sy_call_t *)linux_mincore, AUE_NULL },	/* 218 = linux_mincore */
-	{ SYF_MPSAFE | AS(madvise_args), (sy_call_t *)madvise, AUE_NULL },	/* 219 = madvise */
-	{ AS(linux_getdents64_args), (sy_call_t *)linux_getdents64, AUE_NULL },	/* 220 = linux_getdents64 */
-	{ SYF_MPSAFE | AS(linux_fcntl64_args), (sy_call_t *)linux_fcntl64, AUE_NULL },	/* 221 = linux_fcntl64 */
-	{ 0, (sy_call_t *)nosys, AUE_NULL },			/* 222 =  */
-	{ 0, (sy_call_t *)nosys, AUE_NULL },			/* 223 =  */
-	{ SYF_MPSAFE | 0, (sy_call_t *)linux_getpid, AUE_NULL },	/* 224 = gettid */
-	{ 0, (sy_call_t *)nosys, AUE_NULL },			/* 225 = linux_readahead */
-	{ SYF_MPSAFE | 0, (sy_call_t *)linux_setxattr, AUE_NULL },	/* 226 = linux_setxattr */
-	{ SYF_MPSAFE | 0, (sy_call_t *)linux_lsetxattr, AUE_NULL },	/* 227 = linux_lsetxattr */
-	{ SYF_MPSAFE | 0, (sy_call_t *)linux_fsetxattr, AUE_NULL },	/* 228 = linux_fsetxattr */
-	{ SYF_MPSAFE | 0, (sy_call_t *)linux_getxattr, AUE_NULL },	/* 229 = linux_getxattr */
-	{ SYF_MPSAFE | 0, (sy_call_t *)linux_lgetxattr, AUE_NULL },	/* 230 = linux_lgetxattr */
-	{ SYF_MPSAFE | 0, (sy_call_t *)linux_fgetxattr, AUE_NULL },	/* 231 = linux_fgetxattr */
-	{ SYF_MPSAFE | 0, (sy_call_t *)linux_listxattr, AUE_NULL },	/* 232 = linux_listxattr */
-	{ SYF_MPSAFE | 0, (sy_call_t *)linux_llistxattr, AUE_NULL },	/* 233 = linux_llistxattr */
-	{ SYF_MPSAFE | 0, (sy_call_t *)linux_flistxattr, AUE_NULL },	/* 234 = linux_flistxattr */
-	{ SYF_MPSAFE | 0, (sy_call_t *)linux_removexattr, AUE_NULL },	/* 235 = linux_removexattr */
-	{ SYF_MPSAFE | 0, (sy_call_t *)linux_lremovexattr, AUE_NULL },	/* 236 = linux_lremovexattr */
-	{ SYF_MPSAFE | 0, (sy_call_t *)linux_fremovexattr, AUE_NULL },	/* 237 = linux_fremovexattr */
-	{ 0, (sy_call_t *)nosys, AUE_NULL },			/* 238 = linux_tkill */
-	{ 0, (sy_call_t *)nosys, AUE_NULL },			/* 239 = linux_sendfile64 */
-	{ 0, (sy_call_t *)nosys, AUE_NULL },			/* 240 = linux_futex */
-	{ 0, (sy_call_t *)nosys, AUE_NULL },			/* 241 = linux_sched_setaffinity */
-	{ 0, (sy_call_t *)nosys, AUE_NULL },			/* 242 = linux_sched_getaffinity */
-	{ 0, (sy_call_t *)nosys, AUE_NULL },			/* 243 = linux_set_thread_area */
-	{ 0, (sy_call_t *)nosys, AUE_NULL },			/* 244 = linux_get_thread_area */
-	{ 0, (sy_call_t *)nosys, AUE_NULL },			/* 245 = linux_io_setup */
-	{ 0, (sy_call_t *)nosys, AUE_NULL },			/* 246 = linux_io_destroy */
-	{ 0, (sy_call_t *)nosys, AUE_NULL },			/* 247 = linux_io_getevents */
-	{ 0, (sy_call_t *)nosys, AUE_NULL },			/* 248 = linux_io_submit */
-	{ 0, (sy_call_t *)nosys, AUE_NULL },			/* 249 = linux_io_cancel */
-	{ SYF_MPSAFE | 0, (sy_call_t *)linux_fadvise64, AUE_NULL },	/* 250 = linux_fadvise64 */
-	{ 0, (sy_call_t *)nosys, AUE_NULL },			/* 251 =  */
-	{ SYF_MPSAFE | AS(sys_exit_args), (sy_call_t *)sys_exit, AUE_NULL },	/* 252 = exit_group */
-	{ 0, (sy_call_t *)nosys, AUE_NULL },			/* 253 = linux_lookup_dcookie */
-	{ 0, (sy_call_t *)nosys, AUE_NULL },			/* 254 = linux_epoll_create */
-	{ 0, (sy_call_t *)nosys, AUE_NULL },			/* 255 = linux_epoll_ctl */
-	{ 0, (sy_call_t *)nosys, AUE_NULL },			/* 256 = linux_epoll_wait */
-	{ 0, (sy_call_t *)nosys, AUE_NULL },			/* 257 = linux_remap_file_pages */
-	{ 0, (sy_call_t *)nosys, AUE_NULL },			/* 258 = linux_set_tid_address */
-	{ 0, (sy_call_t *)nosys, AUE_NULL },			/* 259 = linux_timer_create */
-	{ 0, (sy_call_t *)nosys, AUE_NULL },			/* 260 = linux_timer_settime */
-	{ 0, (sy_call_t *)nosys, AUE_NULL },			/* 261 = linux_timer_gettime */
-	{ 0, (sy_call_t *)nosys, AUE_NULL },			/* 262 = linux_timer_getoverrun */
-	{ 0, (sy_call_t *)nosys, AUE_NULL },			/* 263 = linux_timer_delete */
-	{ 0, (sy_call_t *)nosys, AUE_NULL },			/* 264 = linux_clock_settime */
-	{ 0, (sy_call_t *)nosys, AUE_NULL },			/* 265 = linux_clock_gettime */
-	{ 0, (sy_call_t *)nosys, AUE_NULL },			/* 266 = linux_clock_getres */
-	{ 0, (sy_call_t *)nosys, AUE_NULL },			/* 267 = linux_clock_nanosleep */
+	{ 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0 },			/* 0 = setup */
+	{ AS(sys_exit_args), (sy_call_t *)sys_exit, AUE_EXIT, NULL, 0, 0 },	/* 1 = exit */
+	{ 0, (sy_call_t *)linux_fork, AUE_FORK, NULL, 0, 0 },		/* 2 = linux_fork */
+	{ AS(read_args), (sy_call_t *)read, AUE_NULL, NULL, 0, 0 },	/* 3 = read */
+	{ AS(write_args), (sy_call_t *)write, AUE_NULL, NULL, 0, 0 },	/* 4 = write */
+	{ AS(linux_open_args), (sy_call_t *)linux_open, AUE_OPEN_RWTC, NULL, 0, 0 },	/* 5 = linux_open */
+	{ AS(close_args), (sy_call_t *)close, AUE_CLOSE, NULL, 0, 0 },	/* 6 = close */
+	{ AS(linux_waitpid_args), (sy_call_t *)linux_waitpid, AUE_WAIT4, NULL, 0, 0 },	/* 7 = linux_waitpid */
+	{ AS(linux_creat_args), (sy_call_t *)linux_creat, AUE_CREAT, NULL, 0, 0 },	/* 8 = linux_creat */
+	{ AS(linux_link_args), (sy_call_t *)linux_link, AUE_LINK, NULL, 0, 0 },	/* 9 = linux_link */
+	{ AS(linux_unlink_args), (sy_call_t *)linux_unlink, AUE_UNLINK, NULL, 0, 0 },	/* 10 = linux_unlink */
+	{ AS(linux_execve_args), (sy_call_t *)linux_execve, AUE_EXECVE, NULL, 0, 0 },	/* 11 = linux_execve */
+	{ AS(linux_chdir_args), (sy_call_t *)linux_chdir, AUE_CHDIR, NULL, 0, 0 },	/* 12 = linux_chdir */
+	{ AS(linux_time_args), (sy_call_t *)linux_time, AUE_NULL, NULL, 0, 0 },	/* 13 = linux_time */
+	{ AS(linux_mknod_args), (sy_call_t *)linux_mknod, AUE_MKNOD, NULL, 0, 0 },	/* 14 = linux_mknod */
+	{ AS(linux_chmod_args), (sy_call_t *)linux_chmod, AUE_CHMOD, NULL, 0, 0 },	/* 15 = linux_chmod */
+	{ AS(linux_lchown16_args), (sy_call_t *)linux_lchown16, AUE_LCHOWN, NULL, 0, 0 },	/* 16 = linux_lchown16 */
+	{ 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0 },			/* 17 = break */
+	{ AS(linux_stat_args), (sy_call_t *)linux_stat, AUE_STAT, NULL, 0, 0 },	/* 18 = linux_stat */
+	{ AS(linux_lseek_args), (sy_call_t *)linux_lseek, AUE_LSEEK, NULL, 0, 0 },	/* 19 = linux_lseek */
+	{ 0, (sy_call_t *)linux_getpid, AUE_GETPID, NULL, 0, 0 },	/* 20 = linux_getpid */
+	{ AS(linux_mount_args), (sy_call_t *)linux_mount, AUE_MOUNT, NULL, 0, 0 },	/* 21 = linux_mount */
+	{ AS(linux_oldumount_args), (sy_call_t *)linux_oldumount, AUE_UMOUNT, NULL, 0, 0 },	/* 22 = linux_oldumount */
+	{ AS(linux_setuid16_args), (sy_call_t *)linux_setuid16, AUE_SETUID, NULL, 0, 0 },	/* 23 = linux_setuid16 */
+	{ 0, (sy_call_t *)linux_getuid16, AUE_GETUID, NULL, 0, 0 },	/* 24 = linux_getuid16 */
+	{ 0, (sy_call_t *)linux_stime, AUE_SETTIMEOFDAY, NULL, 0, 0 },	/* 25 = linux_stime */
+	{ AS(linux_ptrace_args), (sy_call_t *)linux_ptrace, AUE_PTRACE, NULL, 0, 0 },	/* 26 = linux_ptrace */
+	{ AS(linux_alarm_args), (sy_call_t *)linux_alarm, AUE_NULL, NULL, 0, 0 },	/* 27 = linux_alarm */
+	{ 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0 },			/* 28 = fstat */
+	{ 0, (sy_call_t *)linux_pause, AUE_NULL, NULL, 0, 0 },	/* 29 = linux_pause */
+	{ AS(linux_utime_args), (sy_call_t *)linux_utime, AUE_UTIME, NULL, 0, 0 },	/* 30 = linux_utime */
+	{ 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0 },			/* 31 = stty */
+	{ 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0 },			/* 32 = gtty */
+	{ AS(linux_access_args), (sy_call_t *)linux_access, AUE_ACCESS, NULL, 0, 0 },	/* 33 = linux_access */
+	{ AS(linux_nice_args), (sy_call_t *)linux_nice, AUE_NICE, NULL, 0, 0 },	/* 34 = linux_nice */
+	{ 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0 },			/* 35 = ftime */
+	{ 0, (sy_call_t *)sync, AUE_SYNC, NULL, 0, 0 },		/* 36 = sync */
+	{ AS(linux_kill_args), (sy_call_t *)linux_kill, AUE_KILL, NULL, 0, 0 },	/* 37 = linux_kill */
+	{ AS(linux_rename_args), (sy_call_t *)linux_rename, AUE_RENAME, NULL, 0, 0 },	/* 38 = linux_rename */
+	{ AS(linux_mkdir_args), (sy_call_t *)linux_mkdir, AUE_MKDIR, NULL, 0, 0 },	/* 39 = linux_mkdir */
+	{ AS(linux_rmdir_args), (sy_call_t *)linux_rmdir, AUE_RMDIR, NULL, 0, 0 },	/* 40 = linux_rmdir */
+	{ AS(dup_args), (sy_call_t *)dup, AUE_DUP, NULL, 0, 0 },	/* 41 = dup */
+	{ AS(linux_pipe_args), (sy_call_t *)linux_pipe, AUE_PIPE, NULL, 0, 0 },	/* 42 = linux_pipe */
+	{ AS(linux_times_args), (sy_call_t *)linux_times, AUE_NULL, NULL, 0, 0 },	/* 43 = linux_times */
+	{ 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0 },			/* 44 = prof */
+	{ AS(linux_brk_args), (sy_call_t *)linux_brk, AUE_NULL, NULL, 0, 0 },	/* 45 = linux_brk */
+	{ AS(linux_setgid16_args), (sy_call_t *)linux_setgid16, AUE_SETGID, NULL, 0, 0 },	/* 46 = linux_setgid16 */
+	{ 0, (sy_call_t *)linux_getgid16, AUE_GETGID, NULL, 0, 0 },	/* 47 = linux_getgid16 */
+	{ AS(linux_signal_args), (sy_call_t *)linux_signal, AUE_NULL, NULL, 0, 0 },	/* 48 = linux_signal */
+	{ 0, (sy_call_t *)linux_geteuid16, AUE_GETEUID, NULL, 0, 0 },	/* 49 = linux_geteuid16 */
+	{ 0, (sy_call_t *)linux_getegid16, AUE_GETEGID, NULL, 0, 0 },	/* 50 = linux_getegid16 */
+	{ AS(acct_args), (sy_call_t *)acct, AUE_ACCT, NULL, 0, 0 },	/* 51 = acct */
+	{ AS(linux_umount_args), (sy_call_t *)linux_umount, AUE_UMOUNT, NULL, 0, 0 },	/* 52 = linux_umount */
+	{ 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0 },			/* 53 = lock */
+	{ AS(linux_ioctl_args), (sy_call_t *)linux_ioctl, AUE_IOCTL, NULL, 0, 0 },	/* 54 = linux_ioctl */
+	{ AS(linux_fcntl_args), (sy_call_t *)linux_fcntl, AUE_FCNTL, NULL, 0, 0 },	/* 55 = linux_fcntl */
+	{ 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0 },			/* 56 = mpx */
+	{ AS(setpgid_args), (sy_call_t *)setpgid, AUE_SETPGRP, NULL, 0, 0 },	/* 57 = setpgid */
+	{ 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0 },			/* 58 = ulimit */
+	{ 0, (sy_call_t *)linux_olduname, AUE_NULL, NULL, 0, 0 },	/* 59 = linux_olduname */
+	{ AS(umask_args), (sy_call_t *)umask, AUE_UMASK, NULL, 0, 0 },	/* 60 = umask */
+	{ AS(chroot_args), (sy_call_t *)chroot, AUE_CHROOT, NULL, 0, 0 },	/* 61 = chroot */
+	{ AS(linux_ustat_args), (sy_call_t *)linux_ustat, AUE_NULL, NULL, 0, 0 },	/* 62 = linux_ustat */
+	{ AS(dup2_args), (sy_call_t *)dup2, AUE_DUP2, NULL, 0, 0 },	/* 63 = dup2 */
+	{ 0, (sy_call_t *)linux_getppid, AUE_GETPPID, NULL, 0, 0 },	/* 64 = linux_getppid */
+	{ 0, (sy_call_t *)getpgrp, AUE_GETPGRP, NULL, 0, 0 },		/* 65 = getpgrp */
+	{ 0, (sy_call_t *)setsid, AUE_SETSID, NULL, 0, 0 },		/* 66 = setsid */
+	{ AS(linux_sigaction_args), (sy_call_t *)linux_sigaction, AUE_NULL, NULL, 0, 0 },	/* 67 = linux_sigaction */
+	{ 0, (sy_call_t *)linux_sgetmask, AUE_NULL, NULL, 0, 0 },	/* 68 = linux_sgetmask */
+	{ AS(linux_ssetmask_args), (sy_call_t *)linux_ssetmask, AUE_NULL, NULL, 0, 0 },	/* 69 = linux_ssetmask */
+	{ AS(linux_setreuid16_args), (sy_call_t *)linux_setreuid16, AUE_SETREUID, NULL, 0, 0 },	/* 70 = linux_setreuid16 */
+	{ AS(linux_setregid16_args), (sy_call_t *)linux_setregid16, AUE_SETREGID, NULL, 0, 0 },	/* 71 = linux_setregid16 */
+	{ AS(linux_sigsuspend_args), (sy_call_t *)linux_sigsuspend, AUE_NULL, NULL, 0, 0 },	/* 72 = linux_sigsuspend */
+	{ AS(linux_sigpending_args), (sy_call_t *)linux_sigpending, AUE_NULL, NULL, 0, 0 },	/* 73 = linux_sigpending */
+	{ AS(linux_sethostname_args), (sy_call_t *)linux_sethostname, AUE_SYSCTL, NULL, 0, 0 },	/* 74 = linux_sethostname */
+	{ AS(linux_setrlimit_args), (sy_call_t *)linux_setrlimit, AUE_SETRLIMIT, NULL, 0, 0 },	/* 75 = linux_setrlimit */
+	{ AS(linux_old_getrlimit_args), (sy_call_t *)linux_old_getrlimit, AUE_GETRLIMIT, NULL, 0, 0 },	/* 76 = linux_old_getrlimit */
+	{ AS(linux_getrusage_args), (sy_call_t *)linux_getrusage, AUE_GETRUSAGE, NULL, 0, 0 },	/* 77 = linux_getrusage */
+	{ AS(linux_gettimeofday_args), (sy_call_t *)linux_gettimeofday, AUE_NULL, NULL, 0, 0 },	/* 78 = linux_gettimeofday */
+	{ AS(linux_settimeofday_args), (sy_call_t *)linux_settimeofday, AUE_SETTIMEOFDAY, NULL, 0, 0 },	/* 79 = linux_settimeofday */
+	{ AS(linux_getgroups16_args), (sy_call_t *)linux_getgroups16, AUE_GETGROUPS, NULL, 0, 0 },	/* 80 = linux_getgroups16 */
+	{ AS(linux_setgroups16_args), (sy_call_t *)linux_setgroups16, AUE_SETGROUPS, NULL, 0, 0 },	/* 81 = linux_setgroups16 */
+	{ AS(linux_old_select_args), (sy_call_t *)linux_old_select, AUE_SELECT, NULL, 0, 0 },	/* 82 = linux_old_select */
+	{ AS(linux_symlink_args), (sy_call_t *)linux_symlink, AUE_SYMLINK, NULL, 0, 0 },	/* 83 = linux_symlink */
+	{ AS(linux_lstat_args), (sy_call_t *)linux_lstat, AUE_LSTAT, NULL, 0, 0 },	/* 84 = linux_lstat */
+	{ AS(linux_readlink_args), (sy_call_t *)linux_readlink, AUE_READLINK, NULL, 0, 0 },	/* 85 = linux_readlink */
+	{ 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0 },			/* 86 = linux_uselib */
+	{ AS(swapon_args), (sy_call_t *)swapon, AUE_SWAPON, NULL, 0, 0 },	/* 87 = swapon */
+	{ AS(linux_reboot_args), (sy_call_t *)linux_reboot, AUE_REBOOT, NULL, 0, 0 },	/* 88 = linux_reboot */
+	{ AS(linux_readdir_args), (sy_call_t *)linux_readdir, AUE_GETDIRENTRIES, NULL, 0, 0 },	/* 89 = linux_readdir */
+	{ AS(linux_mmap_args), (sy_call_t *)linux_mmap, AUE_MMAP, NULL, 0, 0 },	/* 90 = linux_mmap */
+	{ AS(munmap_args), (sy_call_t *)munmap, AUE_MUNMAP, NULL, 0, 0 },	/* 91 = munmap */
+	{ AS(linux_truncate_args), (sy_call_t *)linux_truncate, AUE_TRUNCATE, NULL, 0, 0 },	/* 92 = linux_truncate */
+	{ AS(linux_ftruncate_args), (sy_call_t *)linux_ftruncate, AUE_FTRUNCATE, NULL, 0, 0 },	/* 93 = linux_ftruncate */
+	{ AS(fchmod_args), (sy_call_t *)fchmod, AUE_FCHMOD, NULL, 0, 0 },	/* 94 = fchmod */
+	{ AS(fchown_args), (sy_call_t *)fchown, AUE_FCHOWN, NULL, 0, 0 },	/* 95 = fchown */
+	{ AS(linux_getpriority_args), (sy_call_t *)linux_getpriority, AUE_GETPRIORITY, NULL, 0, 0 },	/* 96 = linux_getpriority */
+	{ AS(setpriority_args), (sy_call_t *)setpriority, AUE_SETPRIORITY, NULL, 0, 0 },	/* 97 = setpriority */
+	{ 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0 },			/* 98 = profil */
+	{ AS(linux_statfs_args), (sy_call_t *)linux_statfs, AUE_STATFS, NULL, 0, 0 },	/* 99 = linux_statfs */
+	{ AS(linux_fstatfs_args), (sy_call_t *)linux_fstatfs, AUE_FSTATFS, NULL, 0, 0 },	/* 100 = linux_fstatfs */
+	{ 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0 },			/* 101 = ioperm */
+	{ AS(linux_socketcall_args), (sy_call_t *)linux_socketcall, AUE_NULL, NULL, 0, 0 },	/* 102 = linux_socketcall */
+	{ AS(linux_syslog_args), (sy_call_t *)linux_syslog, AUE_NULL, NULL, 0, 0 },	/* 103 = linux_syslog */
+	{ AS(linux_setitimer_args), (sy_call_t *)linux_setitimer, AUE_SETITIMER, NULL, 0, 0 },	/* 104 = linux_setitimer */
+	{ AS(linux_getitimer_args), (sy_call_t *)linux_getitimer, AUE_GETITIMER, NULL, 0, 0 },	/* 105 = linux_getitimer */
+	{ AS(linux_newstat_args), (sy_call_t *)linux_newstat, AUE_STAT, NULL, 0, 0 },	/* 106 = linux_newstat */
+	{ AS(linux_newlstat_args), (sy_call_t *)linux_newlstat, AUE_LSTAT, NULL, 0, 0 },	/* 107 = linux_newlstat */
+	{ AS(linux_newfstat_args), (sy_call_t *)linux_newfstat, AUE_FSTAT, NULL, 0, 0 },	/* 108 = linux_newfstat */
+	{ 0, (sy_call_t *)linux_uname, AUE_NULL, NULL, 0, 0 },	/* 109 = linux_uname */
+	{ AS(linux_iopl_args), (sy_call_t *)linux_iopl, AUE_NULL, NULL, 0, 0 },	/* 110 = linux_iopl */
+	{ 0, (sy_call_t *)linux_vhangup, AUE_NULL, NULL, 0, 0 },	/* 111 = linux_vhangup */
+	{ 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0 },			/* 112 = idle */
+	{ 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0 },			/* 113 = vm86old */
+	{ AS(linux_wait4_args), (sy_call_t *)linux_wait4, AUE_WAIT4, NULL, 0, 0 },	/* 114 = linux_wait4 */
+	{ 0, (sy_call_t *)linux_swapoff, AUE_SWAPOFF, NULL, 0, 0 },	/* 115 = linux_swapoff */
+	{ AS(linux_sysinfo_args), (sy_call_t *)linux_sysinfo, AUE_NULL, NULL, 0, 0 },	/* 116 = linux_sysinfo */
+	{ AS(linux_ipc_args), (sy_call_t *)linux_ipc, AUE_NULL, NULL, 0, 0 },	/* 117 = linux_ipc */
+	{ AS(fsync_args), (sy_call_t *)fsync, AUE_FSYNC, NULL, 0, 0 },	/* 118 = fsync */
+	{ AS(linux_sigreturn_args), (sy_call_t *)linux_sigreturn, AUE_SIGRETURN, NULL, 0, 0 },	/* 119 = linux_sigreturn */
+	{ AS(linux_clone_args), (sy_call_t *)linux_clone, AUE_RFORK, NULL, 0, 0 },	/* 120 = linux_clone */
+	{ AS(setdomainname_args), (sy_call_t *)setdomainname, AUE_SYSCTL, NULL, 0, 0 },	/* 121 = setdomainname */
+	{ AS(linux_newuname_args), (sy_call_t *)linux_newuname, AUE_NULL, NULL, 0, 0 },	/* 122 = linux_newuname */
+	{ 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0 },			/* 123 = modify_ldt */
+	{ 0, (sy_call_t *)linux_adjtimex, AUE_ADJTIME, NULL, 0, 0 },	/* 124 = linux_adjtimex */
+	{ AS(linux_mprotect_args), (sy_call_t *)linux_mprotect, AUE_MPROTECT, NULL, 0, 0 },	/* 125 = linux_mprotect */
+	{ AS(linux_sigprocmask_args), (sy_call_t *)linux_sigprocmask, AUE_SIGPROCMASK, NULL, 0, 0 },	/* 126 = linux_sigprocmask */
+	{ 0, (sy_call_t *)linux_create_module, AUE_NULL, NULL, 0, 0 },	/* 127 = linux_create_module */
+	{ 0, (sy_call_t *)linux_init_module, AUE_NULL, NULL, 0, 0 },	/* 128 = linux_init_module */
+	{ 0, (sy_call_t *)linux_delete_module, AUE_NULL, NULL, 0, 0 },	/* 129 = linux_delete_module */
+	{ 0, (sy_call_t *)linux_get_kernel_syms, AUE_NULL, NULL, 0, 0 },	/* 130 = linux_get_kernel_syms */
+	{ 0, (sy_call_t *)linux_quotactl, AUE_QUOTACTL, NULL, 0, 0 },	/* 131 = linux_quotactl */
+	{ AS(getpgid_args), (sy_call_t *)getpgid, AUE_GETPGID, NULL, 0, 0 },	/* 132 = getpgid */
+	{ AS(fchdir_args), (sy_call_t *)fchdir, AUE_FCHDIR, NULL, 0, 0 },	/* 133 = fchdir */
+	{ 0, (sy_call_t *)linux_bdflush, AUE_BDFLUSH, NULL, 0, 0 },	/* 134 = linux_bdflush */
+	{ AS(linux_sysfs_args), (sy_call_t *)linux_sysfs, AUE_NULL, NULL, 0, 0 },	/* 135 = linux_sysfs */
+	{ AS(linux_personality_args), (sy_call_t *)linux_personality, AUE_PERSONALITY, NULL, 0, 0 },	/* 136 = linux_personality */
+	{ 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0 },			/* 137 = afs_syscall */
+	{ AS(linux_setfsuid16_args), (sy_call_t *)linux_setfsuid16, AUE_SETFSUID, NULL, 0, 0 },	/* 138 = linux_setfsuid16 */
+	{ AS(linux_setfsgid16_args), (sy_call_t *)linux_setfsgid16, AUE_SETFSGID, NULL, 0, 0 },	/* 139 = linux_setfsgid16 */
+	{ AS(linux_llseek_args), (sy_call_t *)linux_llseek, AUE_LSEEK, NULL, 0, 0 },	/* 140 = linux_llseek */
+	{ AS(linux_getdents_args), (sy_call_t *)linux_getdents, AUE_GETDIRENTRIES, NULL, 0, 0 },	/* 141 = linux_getdents */
+	{ AS(linux_select_args), (sy_call_t *)linux_select, AUE_SELECT, NULL, 0, 0 },	/* 142 = linux_select */
+	{ AS(flock_args), (sy_call_t *)flock, AUE_FLOCK, NULL, 0, 0 },	/* 143 = flock */
+	{ AS(linux_msync_args), (sy_call_t *)linux_msync, AUE_MSYNC, NULL, 0, 0 },	/* 144 = linux_msync */
+	{ AS(linux_readv_args), (sy_call_t *)linux_readv, AUE_READV, NULL, 0, 0 },	/* 145 = linux_readv */
+	{ AS(linux_writev_args), (sy_call_t *)linux_writev, AUE_WRITEV, NULL, 0, 0 },	/* 146 = linux_writev */
+	{ AS(linux_getsid_args), (sy_call_t *)linux_getsid, AUE_GETSID, NULL, 0, 0 },	/* 147 = linux_getsid */
+	{ AS(linux_fdatasync_args), (sy_call_t *)linux_fdatasync, AUE_NULL, NULL, 0, 0 },	/* 148 = linux_fdatasync */
+	{ AS(linux_sysctl_args), (sy_call_t *)linux_sysctl, AUE_SYSCTL, NULL, 0, 0 },	/* 149 = linux_sysctl */
+	{ AS(mlock_args), (sy_call_t *)mlock, AUE_MLOCK, NULL, 0, 0 },	/* 150 = mlock */
+	{ AS(munlock_args), (sy_call_t *)munlock, AUE_MUNLOCK, NULL, 0, 0 },	/* 151 = munlock */
+	{ AS(mlockall_args), (sy_call_t *)mlockall, AUE_MLOCKALL, NULL, 0, 0 },	/* 152 = mlockall */
+	{ 0, (sy_call_t *)munlockall, AUE_MUNLOCKALL, NULL, 0, 0 },	/* 153 = munlockall */
+	{ AS(sched_setparam_args), (sy_call_t *)sched_setparam, AUE_SCHED_SETPARAM, NULL, 0, 0 },	/* 154 = sched_setparam */
+	{ AS(sched_getparam_args), (sy_call_t *)sched_getparam, AUE_SCHED_GETPARAM, NULL, 0, 0 },	/* 155 = sched_getparam */
+	{ AS(linux_sched_setscheduler_args), (sy_call_t *)linux_sched_setscheduler, AUE_SCHED_SETSCHEDULER, NULL, 0, 0 },	/* 156 = linux_sched_setscheduler */
+	{ AS(linux_sched_getscheduler_args), (sy_call_t *)linux_sched_getscheduler, AUE_SCHED_GETSCHEDULER, NULL, 0, 0 },	/* 157 = linux_sched_getscheduler */
+	{ 0, (sy_call_t *)sched_yield, AUE_NULL, NULL, 0, 0 },	/* 158 = sched_yield */
+	{ AS(linux_sched_get_priority_max_args), (sy_call_t *)linux_sched_get_priority_max, AUE_SCHED_GET_PRIORITY_MAX, NULL, 0, 0 },	/* 159 = linux_sched_get_priority_max */
+	{ AS(linux_sched_get_priority_min_args), (sy_call_t *)linux_sched_get_priority_min, AUE_SCHED_GET_PRIORITY_MIN, NULL, 0, 0 },	/* 160 = linux_sched_get_priority_min */
+	{ AS(linux_sched_rr_get_interval_args), (sy_call_t *)linux_sched_rr_get_interval, AUE_SCHED_RR_GET_INTERVAL, NULL, 0, 0 },	/* 161 = linux_sched_rr_get_interval */
+	{ AS(linux_nanosleep_args), (sy_call_t *)linux_nanosleep, AUE_NULL, NULL, 0, 0 },	/* 162 = linux_nanosleep */
+	{ AS(linux_mremap_args), (sy_call_t *)linux_mremap, AUE_NULL, NULL, 0, 0 },	/* 163 = linux_mremap */
+	{ AS(linux_setresuid16_args), (sy_call_t *)linux_setresuid16, AUE_SETRESUID, NULL, 0, 0 },	/* 164 = linux_setresuid16 */
+	{ AS(linux_getresuid16_args), (sy_call_t *)linux_getresuid16, AUE_GETRESUID, NULL, 0, 0 },	/* 165 = linux_getresuid16 */
+	{ 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0 },			/* 166 = vm86 */
+	{ 0, (sy_call_t *)linux_query_module, AUE_NULL, NULL, 0, 0 },	/* 167 = linux_query_module */
+	{ AS(poll_args), (sy_call_t *)poll, AUE_POLL, NULL, 0, 0 },	/* 168 = poll */
+	{ 0, (sy_call_t *)linux_nfsservctl, AUE_NULL, NULL, 0, 0 },	/* 169 = linux_nfsservctl */
+	{ AS(linux_setresgid16_args), (sy_call_t *)linux_setresgid16, AUE_SETRESGID, NULL, 0, 0 },	/* 170 = linux_setresgid16 */
+	{ AS(linux_getresgid16_args), (sy_call_t *)linux_getresgid16, AUE_GETRESGID, NULL, 0, 0 },	/* 171 = linux_getresgid16 */
+	{ AS(linux_prctl_args), (sy_call_t *)linux_prctl, AUE_PRCTL, NULL, 0, 0 },	/* 172 = linux_prctl */
+	{ AS(linux_rt_sigreturn_args), (sy_call_t *)linux_rt_sigreturn, AUE_NULL, NULL, 0, 0 },	/* 173 = linux_rt_sigreturn */
+	{ AS(linux_rt_sigaction_args), (sy_call_t *)linux_rt_sigaction, AUE_NULL, NULL, 0, 0 },	/* 174 = linux_rt_sigaction */
+	{ AS(linux_rt_sigprocmask_args), (sy_call_t *)linux_rt_sigprocmask, AUE_NULL, NULL, 0, 0 },	/* 175 = linux_rt_sigprocmask */
+	{ AS(linux_rt_sigpending_args), (sy_call_t *)linux_rt_sigpending, AUE_NULL, NULL, 0, 0 },	/* 176 = linux_rt_sigpending */
+	{ AS(linux_rt_sigtimedwait_args), (sy_call_t *)linux_rt_sigtimedwait, AUE_NULL, NULL, 0, 0 },	/* 177 = linux_rt_sigtimedwait */
+	{ 0, (sy_call_t *)linux_rt_sigqueueinfo, AUE_NULL, NULL, 0, 0 },	/* 178 = linux_rt_sigqueueinfo */
+	{ AS(linux_rt_sigsuspend_args), (sy_call_t *)linux_rt_sigsuspend, AUE_NULL, NULL, 0, 0 },	/* 179 = linux_rt_sigsuspend */
+	{ AS(linux_pread_args), (sy_call_t *)linux_pread, AUE_PREAD, NULL, 0, 0 },	/* 180 = linux_pread */
+	{ AS(linux_pwrite_args), (sy_call_t *)linux_pwrite, AUE_PWRITE, NULL, 0, 0 },	/* 181 = linux_pwrite */
+	{ AS(linux_chown16_args), (sy_call_t *)linux_chown16, AUE_CHOWN, NULL, 0, 0 },	/* 182 = linux_chown16 */
+	{ AS(linux_getcwd_args), (sy_call_t *)linux_getcwd, AUE_GETCWD, NULL, 0, 0 },	/* 183 = linux_getcwd */
+	{ 0, (sy_call_t *)linux_capget, AUE_CAPGET, NULL, 0, 0 },	/* 184 = linux_capget */
+	{ 0, (sy_call_t *)linux_capset, AUE_CAPSET, NULL, 0, 0 },	/* 185 = linux_capset */
+	{ AS(linux_sigaltstack_args), (sy_call_t *)linux_sigaltstack, AUE_NULL, NULL, 0, 0 },	/* 186 = linux_sigaltstack */
+	{ 0, (sy_call_t *)linux_sendfile, AUE_SENDFILE, NULL, 0, 0 },	/* 187 = linux_sendfile */
+	{ 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0 },			/* 188 = getpmsg */
+	{ 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0 },			/* 189 = putpmsg */
+	{ 0, (sy_call_t *)linux_vfork, AUE_VFORK, NULL, 0, 0 },	/* 190 = linux_vfork */
+	{ AS(linux_getrlimit_args), (sy_call_t *)linux_getrlimit, AUE_GETRLIMIT, NULL, 0, 0 },	/* 191 = linux_getrlimit */
+	{ AS(linux_mmap2_args), (sy_call_t *)linux_mmap2, AUE_MMAP, NULL, 0, 0 },	/* 192 = linux_mmap2 */
+	{ AS(linux_truncate64_args), (sy_call_t *)linux_truncate64, AUE_TRUNCATE, NULL, 0, 0 },	/* 193 = linux_truncate64 */
+	{ AS(linux_ftruncate64_args), (sy_call_t *)linux_ftruncate64, AUE_FTRUNCATE, NULL, 0, 0 },	/* 194 = linux_ftruncate64 */
+	{ AS(linux_stat64_args), (sy_call_t *)linux_stat64, AUE_STAT, NULL, 0, 0 },	/* 195 = linux_stat64 */
+	{ AS(linux_lstat64_args), (sy_call_t *)linux_lstat64, AUE_LSTAT, NULL, 0, 0 },	/* 196 = linux_lstat64 */
+	{ AS(linux_fstat64_args), (sy_call_t *)linux_fstat64, AUE_FSTAT, NULL, 0, 0 },	/* 197 = linux_fstat64 */
+	{ AS(linux_lchown_args), (sy_call_t *)linux_lchown, AUE_LCHOWN, NULL, 0, 0 },	/* 198 = linux_lchown */
+	{ 0, (sy_call_t *)linux_getuid, AUE_GETUID, NULL, 0, 0 },	/* 199 = linux_getuid */
+	{ 0, (sy_call_t *)linux_getgid, AUE_GETGID, NULL, 0, 0 },	/* 200 = linux_getgid */
+	{ 0, (sy_call_t *)geteuid, AUE_GETEUID, NULL, 0, 0 },		/* 201 = geteuid */
+	{ 0, (sy_call_t *)getegid, AUE_GETEGID, NULL, 0, 0 },		/* 202 = getegid */
+	{ AS(setreuid_args), (sy_call_t *)setreuid, AUE_SETREUID, NULL, 0, 0 },	/* 203 = setreuid */
+	{ AS(setregid_args), (sy_call_t *)setregid, AUE_SETREGID, NULL, 0, 0 },	/* 204 = setregid */
+	{ AS(linux_getgroups_args), (sy_call_t *)linux_getgroups, AUE_GETGROUPS, NULL, 0, 0 },	/* 205 = linux_getgroups */
+	{ AS(linux_setgroups_args), (sy_call_t *)linux_setgroups, AUE_SETGROUPS, NULL, 0, 0 },	/* 206 = linux_setgroups */
+	{ AS(fchown_args), (sy_call_t *)fchown, AUE_NULL, NULL, 0, 0 },	/* 207 = fchown */
+	{ AS(setresuid_args), (sy_call_t *)setresuid, AUE_SETRESUID, NULL, 0, 0 },	/* 208 = setresuid */
+	{ AS(getresuid_args), (sy_call_t *)getresuid, AUE_GETRESUID, NULL, 0, 0 },	/* 209 = getresuid */
+	{ AS(setresgid_args), (sy_call_t *)setresgid, AUE_SETRESGID, NULL, 0, 0 },	/* 210 = setresgid */
+	{ AS(getresgid_args), (sy_call_t *)getresgid, AUE_GETRESGID, NULL, 0, 0 },	/* 211 = getresgid */
+	{ AS(linux_chown_args), (sy_call_t *)linux_chown, AUE_CHOWN, NULL, 0, 0 },	/* 212 = linux_chown */
+	{ AS(setuid_args), (sy_call_t *)setuid, AUE_SETUID, NULL, 0, 0 },	/* 213 = setuid */
+	{ AS(setgid_args), (sy_call_t *)setgid, AUE_SETGID, NULL, 0, 0 },	/* 214 = setgid */
+	{ AS(linux_setfsuid_args), (sy_call_t *)linux_setfsuid, AUE_SETFSUID, NULL, 0, 0 },	/* 215 = linux_setfsuid */
+	{ AS(linux_setfsgid_args), (sy_call_t *)linux_setfsgid, AUE_SETFSGID, NULL, 0, 0 },	/* 216 = linux_setfsgid */
+	{ AS(linux_pivot_root_args), (sy_call_t *)linux_pivot_root, AUE_PIVOT_ROOT, NULL, 0, 0 },	/* 217 = linux_pivot_root */
+	{ AS(linux_mincore_args), (sy_call_t *)linux_mincore, AUE_MINCORE, NULL, 0, 0 },	/* 218 = linux_mincore */
+	{ AS(madvise_args), (sy_call_t *)madvise, AUE_MADVISE, NULL, 0, 0 },	/* 219 = madvise */
+	{ AS(linux_getdents64_args), (sy_call_t *)linux_getdents64, AUE_GETDIRENTRIES, NULL, 0, 0 },	/* 220 = linux_getdents64 */
+	{ AS(linux_fcntl64_args), (sy_call_t *)linux_fcntl64, AUE_FCNTL, NULL, 0, 0 },	/* 221 = linux_fcntl64 */
+	{ 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0 },			/* 222 =  */
+	{ 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0 },			/* 223 =  */
+	{ 0, (sy_call_t *)linux_gettid, AUE_NULL, NULL, 0, 0 },	/* 224 = linux_gettid */
+	{ 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0 },			/* 225 = linux_readahead */
+	{ 0, (sy_call_t *)linux_setxattr, AUE_NULL, NULL, 0, 0 },	/* 226 = linux_setxattr */
+	{ 0, (sy_call_t *)linux_lsetxattr, AUE_NULL, NULL, 0, 0 },	/* 227 = linux_lsetxattr */
+	{ 0, (sy_call_t *)linux_fsetxattr, AUE_NULL, NULL, 0, 0 },	/* 228 = linux_fsetxattr */
+	{ 0, (sy_call_t *)linux_getxattr, AUE_NULL, NULL, 0, 0 },	/* 229 = linux_getxattr */
+	{ 0, (sy_call_t *)linux_lgetxattr, AUE_NULL, NULL, 0, 0 },	/* 230 = linux_lgetxattr */
+	{ 0, (sy_call_t *)linux_fgetxattr, AUE_NULL, NULL, 0, 0 },	/* 231 = linux_fgetxattr */
+	{ 0, (sy_call_t *)linux_listxattr, AUE_NULL, NULL, 0, 0 },	/* 232 = linux_listxattr */
+	{ 0, (sy_call_t *)linux_llistxattr, AUE_NULL, NULL, 0, 0 },	/* 233 = linux_llistxattr */
+	{ 0, (sy_call_t *)linux_flistxattr, AUE_NULL, NULL, 0, 0 },	/* 234 = linux_flistxattr */
+	{ 0, (sy_call_t *)linux_removexattr, AUE_NULL, NULL, 0, 0 },	/* 235 = linux_removexattr */
+	{ 0, (sy_call_t *)linux_lremovexattr, AUE_NULL, NULL, 0, 0 },	/* 236 = linux_lremovexattr */
+	{ 0, (sy_call_t *)linux_fremovexattr, AUE_NULL, NULL, 0, 0 },	/* 237 = linux_fremovexattr */
+	{ AS(linux_tkill_args), (sy_call_t *)linux_tkill, AUE_NULL, NULL, 0, 0 },	/* 238 = linux_tkill */
+	{ 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0 },			/* 239 = linux_sendfile64 */
+	{ AS(linux_sys_futex_args), (sy_call_t *)linux_sys_futex, AUE_NULL, NULL, 0, 0 },	/* 240 = linux_sys_futex */
+	{ 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0 },			/* 241 = linux_sched_setaffinity */
+	{ AS(linux_sched_getaffinity_args), (sy_call_t *)linux_sched_getaffinity, AUE_NULL, NULL, 0, 0 },	/* 242 = linux_sched_getaffinity */
+	{ AS(linux_set_thread_area_args), (sy_call_t *)linux_set_thread_area, AUE_NULL, NULL, 0, 0 },	/* 243 = linux_set_thread_area */
+	{ 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0 },			/* 244 = linux_get_thread_area */
+	{ 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0 },			/* 245 = linux_io_setup */
+	{ 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0 },			/* 246 = linux_io_destroy */
+	{ 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0 },			/* 247 = linux_io_getevents */
+	{ 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0 },			/* 248 = inux_io_submit */
+	{ 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0 },			/* 249 = linux_io_cancel */
+	{ 0, (sy_call_t *)linux_fadvise64, AUE_NULL, NULL, 0, 0 },	/* 250 = linux_fadvise64 */
+	{ 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0 },			/* 251 =  */
+	{ AS(linux_exit_group_args), (sy_call_t *)linux_exit_group, AUE_EXIT, NULL, 0, 0 },	/* 252 = linux_exit_group */
+	{ 0, (sy_call_t *)linux_lookup_dcookie, AUE_NULL, NULL, 0, 0 },	/* 253 = linux_lookup_dcookie */
+	{ 0, (sy_call_t *)linux_epoll_create, AUE_NULL, NULL, 0, 0 },	/* 254 = linux_epoll_create */
+	{ 0, (sy_call_t *)linux_epoll_ctl, AUE_NULL, NULL, 0, 0 },	/* 255 = linux_epoll_ctl */
+	{ 0, (sy_call_t *)linux_epoll_wait, AUE_NULL, NULL, 0, 0 },	/* 256 = linux_epoll_wait */
+	{ 0, (sy_call_t *)linux_remap_file_pages, AUE_NULL, NULL, 0, 0 },	/* 257 = linux_remap_file_pages */
+	{ AS(linux_set_tid_address_args), (sy_call_t *)linux_set_tid_address, AUE_NULL, NULL, 0, 0 },	/* 258 = linux_set_tid_address */
+	{ 0, (sy_call_t *)linux_timer_create, AUE_NULL, NULL, 0, 0 },	/* 259 = linux_timer_create */
+	{ 0, (sy_call_t *)linux_timer_settime, AUE_NULL, NULL, 0, 0 },	/* 260 = linux_timer_settime */
+	{ 0, (sy_call_t *)linux_timer_gettime, AUE_NULL, NULL, 0, 0 },	/* 261 = linux_timer_gettime */
+	{ 0, (sy_call_t *)linux_timer_getoverrun, AUE_NULL, NULL, 0, 0 },	/* 262 = linux_timer_getoverrun */
+	{ 0, (sy_call_t *)linux_timer_delete, AUE_NULL, NULL, 0, 0 },	/* 263 = linux_timer_delete */
+	{ AS(linux_clock_settime_args), (sy_call_t *)linux_clock_settime, AUE_CLOCK_SETTIME, NULL, 0, 0 },	/* 264 = linux_clock_settime */
+	{ AS(linux_clock_gettime_args), (sy_call_t *)linux_clock_gettime, AUE_NULL, NULL, 0, 0 },	/* 265 = linux_clock_gettime */
+	{ AS(linux_clock_getres_args), (sy_call_t *)linux_clock_getres, AUE_NULL, NULL, 0, 0 },	/* 266 = linux_clock_getres */
+	{ AS(linux_clock_nanosleep_args), (sy_call_t *)linux_clock_nanosleep, AUE_NULL, NULL, 0, 0 },	/* 267 = linux_clock_nanosleep */
+	{ AS(linux_statfs64_args), (sy_call_t *)linux_statfs64, AUE_STATFS, NULL, 0, 0 },	/* 268 = linux_statfs64 */
+	{ 0, (sy_call_t *)linux_fstatfs64, AUE_FSTATFS, NULL, 0, 0 },	/* 269 = linux_fstatfs64 */
+	{ AS(linux_tgkill_args), (sy_call_t *)linux_tgkill, AUE_NULL, NULL, 0, 0 },	/* 270 = linux_tgkill */
+	{ AS(linux_utimes_args), (sy_call_t *)linux_utimes, AUE_UTIMES, NULL, 0, 0 },	/* 271 = linux_utimes */
+	{ 0, (sy_call_t *)linux_fadvise64_64, AUE_NULL, NULL, 0, 0 },	/* 272 = linux_fadvise64_64 */
+	{ 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0 },			/* 273 =  */
+	{ 0, (sy_call_t *)linux_mbind, AUE_NULL, NULL, 0, 0 },	/* 274 = linux_mbind */
+	{ 0, (sy_call_t *)linux_get_mempolicy, AUE_NULL, NULL, 0, 0 },	/* 275 = linux_get_mempolicy */
+	{ 0, (sy_call_t *)linux_set_mempolicy, AUE_NULL, NULL, 0, 0 },	/* 276 = linux_set_mempolicy */
+	{ 0, (sy_call_t *)linux_mq_open, AUE_NULL, NULL, 0, 0 },	/* 277 = linux_mq_open */
+	{ 0, (sy_call_t *)linux_mq_unlink, AUE_NULL, NULL, 0, 0 },	/* 278 = linux_mq_unlink */
+	{ 0, (sy_call_t *)linux_mq_timedsend, AUE_NULL, NULL, 0, 0 },	/* 279 = linux_mq_timedsend */
+	{ 0, (sy_call_t *)linux_mq_timedreceive, AUE_NULL, NULL, 0, 0 },	/* 280 = linux_mq_timedreceive */
+	{ 0, (sy_call_t *)linux_mq_notify, AUE_NULL, NULL, 0, 0 },	/* 281 = linux_mq_notify */
+	{ 0, (sy_call_t *)linux_mq_getsetattr, AUE_NULL, NULL, 0, 0 },	/* 282 = linux_mq_getsetattr */
+	{ 0, (sy_call_t *)linux_kexec_load, AUE_NULL, NULL, 0, 0 },	/* 283 = linux_kexec_load */
+	{ 0, (sy_call_t *)linux_waitid, AUE_NULL, NULL, 0, 0 },	/* 284 = linux_waitid */
+	{ 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0 },			/* 285 =  */
+	{ 0, (sy_call_t *)linux_add_key, AUE_NULL, NULL, 0, 0 },	/* 286 = linux_add_key */
+	{ 0, (sy_call_t *)linux_request_key, AUE_NULL, NULL, 0, 0 },	/* 287 = linux_request_key */
+	{ 0, (sy_call_t *)linux_keyctl, AUE_NULL, NULL, 0, 0 },	/* 288 = linux_keyctl */
+	{ 0, (sy_call_t *)linux_ioprio_set, AUE_NULL, NULL, 0, 0 },	/* 289 = linux_ioprio_set */
+	{ 0, (sy_call_t *)linux_ioprio_get, AUE_NULL, NULL, 0, 0 },	/* 290 = linux_ioprio_get */
+	{ 0, (sy_call_t *)linux_inotify_init, AUE_NULL, NULL, 0, 0 },	/* 291 = linux_inotify_init */
+	{ 0, (sy_call_t *)linux_inotify_add_watch, AUE_NULL, NULL, 0, 0 },	/* 292 = linux_inotify_add_watch */
+	{ 0, (sy_call_t *)linux_inotify_rm_watch, AUE_NULL, NULL, 0, 0 },	/* 293 = linux_inotify_rm_watch */
+	{ 0, (sy_call_t *)linux_migrate_pages, AUE_NULL, NULL, 0, 0 },	/* 294 = linux_migrate_pages */
+	{ AS(linux_openat_args), (sy_call_t *)linux_openat, AUE_OPEN_RWTC, NULL, 0, 0 },	/* 295 = linux_openat */
+	{ 0, (sy_call_t *)linux_mkdirat, AUE_NULL, NULL, 0, 0 },	/* 296 = linux_mkdirat */
+	{ 0, (sy_call_t *)linux_mknodat, AUE_NULL, NULL, 0, 0 },	/* 297 = linux_mknodat */
+	{ 0, (sy_call_t *)linux_fchownat, AUE_NULL, NULL, 0, 0 },	/* 298 = linux_fchownat */
+	{ 0, (sy_call_t *)linux_futimesat, AUE_NULL, NULL, 0, 0 },	/* 299 = linux_futimesat */
+	{ 0, (sy_call_t *)linux_fstatat64, AUE_NULL, NULL, 0, 0 },	/* 300 = linux_fstatat64 */
+	{ 0, (sy_call_t *)linux_unlinkat, AUE_NULL, NULL, 0, 0 },	/* 301 = linux_unlinkat */
+	{ 0, (sy_call_t *)linux_renameat, AUE_NULL, NULL, 0, 0 },	/* 302 = linux_renameat */
+	{ 0, (sy_call_t *)linux_linkat, AUE_NULL, NULL, 0, 0 },	/* 303 = linux_linkat */
+	{ 0, (sy_call_t *)linux_symlinkat, AUE_NULL, NULL, 0, 0 },	/* 304 = linux_symlinkat */
+	{ 0, (sy_call_t *)linux_readlinkat, AUE_NULL, NULL, 0, 0 },	/* 305 = linux_readlinkat */
+	{ 0, (sy_call_t *)linux_fchmodat, AUE_NULL, NULL, 0, 0 },	/* 306 = linux_fchmodat */
+	{ 0, (sy_call_t *)linux_faccessat, AUE_NULL, NULL, 0, 0 },	/* 307 = linux_faccessat */
+	{ 0, (sy_call_t *)linux_pselect6, AUE_NULL, NULL, 0, 0 },	/* 308 = linux_pselect6 */
+	{ 0, (sy_call_t *)linux_ppoll, AUE_NULL, NULL, 0, 0 },	/* 309 = linux_ppoll */
+	{ 0, (sy_call_t *)linux_unshare, AUE_NULL, NULL, 0, 0 },	/* 310 = linux_unshare */
 };
--- /dev/null
+++ sys/amd64/linux32/linux32_support.s
@@ -0,0 +1,124 @@
+/*-
+ * Copyright (c) 2007 Konstantin Belousov
+ * 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.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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: src/sys/amd64/linux32/linux32_support.s,v 1.1 2007/05/23 08:33:05 kib Exp $
+ */
+
+#include "linux32_assym.h"		/* system definitions */
+#include <machine/asmacros.h>		/* miscellaneous asm macros */
+
+#include "assym.s"
+
+futex_fault:
+	movq	$0,PCB_ONFAULT(%r8)
+	movl	$-EFAULT,%eax
+	ret
+
+ENTRY(futex_xchgl)
+	movq	PCPU(CURPCB),%r8
+	movq	$futex_fault,PCB_ONFAULT(%r8)
+	movq	$VM_MAXUSER_ADDRESS-4,%rax
+	cmpq	%rax,%rsi
+	ja	futex_fault
+	xchgl	%edi,(%rsi)
+	movl	%edi,(%rdx)
+	xorl	%eax,%eax
+	movq	%rax,PCB_ONFAULT(%r8)
+	ret
+
+ENTRY(futex_addl)
+	movq	PCPU(CURPCB),%r8
+	movq	$futex_fault,PCB_ONFAULT(%r8)
+	movq	$VM_MAXUSER_ADDRESS-4,%rax
+	cmpq	%rax,%rsi
+	ja	futex_fault
+#ifdef SMP
+	lock
+#endif
+	xaddl	%edi,(%rsi)
+	movl	%edi,(%rdx)
+	xorl	%eax,%eax
+	movq	%rax,PCB_ONFAULT(%r8)
+	ret
+
+ENTRY(futex_orl)
+	movq	PCPU(CURPCB),%r8
+	movq	$futex_fault,PCB_ONFAULT(%r8)
+	movq	$VM_MAXUSER_ADDRESS-4,%rax
+	cmpq	%rax,%rsi
+	ja	futex_fault
+	movl	(%rsi),%eax
+1:	movl	%eax,%ecx
+	orl	%edi,%ecx
+#ifdef SMP
+	lock
+#endif
+	cmpxchgl %ecx,(%rsi)
+	jnz	1b
+	movl	%eax,(%rdx)
+	xorl	%eax,%eax
+	movq	%rax,PCB_ONFAULT(%r8)
+	ret
+
+ENTRY(futex_andl)
+	movq	PCPU(CURPCB),%r8
+	movq	$futex_fault,PCB_ONFAULT(%r8)
+	movq	$VM_MAXUSER_ADDRESS-4,%rax
+	cmpq	%rax,%rsi
+	ja	futex_fault
+	movl	(%rsi),%eax
+1:	movl	%eax,%ecx
+	andl	%edi,%ecx
+#ifdef SMP
+	lock
+#endif
+	cmpxchgl %ecx,(%rsi)
+	jnz	1b
+	movl	%eax,(%rdx)
+	xorl	%eax,%eax
+	movq	%rax,PCB_ONFAULT(%r8)
+	ret
+
+ENTRY(futex_xorl)
+	movq	PCPU(CURPCB),%r8
+	movq	$futex_fault,PCB_ONFAULT(%r8)
+	movq	$VM_MAXUSER_ADDRESS-4,%rax
+	cmpq	%rax,%rsi
+	ja	futex_fault
+	movl	(%rsi),%eax
+1:	movl	%eax,%ecx
+	xorl	%edi,%ecx
+#ifdef SMP
+	lock
+#endif
+	cmpxchgl %ecx,(%rsi)
+	jnz	1b
+	movl	%eax,(%rdx)
+	xorl	%eax,%eax
+	movq	%rax,PCB_ONFAULT(%r8)
+	ret
Index: linux32_machdep.c
===================================================================
RCS file: /home/cvs/src/sys/amd64/linux32/linux32_machdep.c,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L sys/amd64/linux32/linux32_machdep.c -L sys/amd64/linux32/linux32_machdep.c -u -r1.1.1.1 -r1.2
--- sys/amd64/linux32/linux32_machdep.c
+++ sys/amd64/linux32/linux32_machdep.c
@@ -29,24 +29,34 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/amd64/linux32/linux32_machdep.c,v 1.10 2005/06/24 17:41:27 jhb Exp $");
+__FBSDID("$FreeBSD: src/sys/amd64/linux32/linux32_machdep.c,v 1.45 2007/07/04 23:06:43 peter Exp $");
 
 #include <sys/param.h>
 #include <sys/kernel.h>
 #include <sys/systm.h>
+#include <sys/file.h>
+#include <sys/fcntl.h>
+#include <sys/clock.h>
 #include <sys/imgact.h>
+#include <sys/limits.h>
 #include <sys/lock.h>
 #include <sys/malloc.h>
 #include <sys/mman.h>
 #include <sys/mutex.h>
+#include <sys/priv.h>
 #include <sys/proc.h>
 #include <sys/resource.h>
 #include <sys/resourcevar.h>
+#include <sys/sched.h>
 #include <sys/syscallsubr.h>
 #include <sys/sysproto.h>
 #include <sys/unistd.h>
 
 #include <machine/frame.h>
+#include <machine/pcb.h>
+#include <machine/psl.h>
+#include <machine/segments.h>
+#include <machine/specialreg.h>
 
 #include <vm/vm.h>
 #include <vm/pmap.h>
@@ -59,6 +69,7 @@
 #include <compat/linux/linux_ipc.h>
 #include <compat/linux/linux_signal.h>
 #include <compat/linux/linux_util.h>
+#include <compat/linux/linux_emul.h>
 
 struct l_old_select_argv {
 	l_int		nfds;
@@ -113,7 +124,7 @@
 	 * Allocate temporary demand zeroed space for argument and
 	 *	environment strings
 	 */
-	args->buf = (char *) kmem_alloc_wait(exec_map,
+	args->buf = (char *)kmem_alloc_wait(exec_map,
 	    PATH_MAX + ARG_MAX + MAXSHELLCMDLEN);
 	if (args->buf == NULL)
 		return (ENOMEM);
@@ -130,7 +141,7 @@
 	    copystr(fname, args->fname, PATH_MAX, &length) :
 	    copyinstr(fname, args->fname, PATH_MAX, &length);
 	if (error != 0)
-		return (error);
+		goto err_exit;
 
 	/*
 	 * extract arguments first
@@ -139,22 +150,22 @@
 	for (;;) {
 		error = copyin(p32++, &arg, sizeof(arg));
 		if (error)
-			return (error);
+			goto err_exit;
 		if (arg == 0)
 			break;
 		argp = PTRIN(arg);
 		error = copyinstr(argp, args->endp, args->stringspace, &length);
 		if (error) {
 			if (error == ENAMETOOLONG)
-				return (E2BIG);
-			else
-				return (error);
+				error = E2BIG;
+
+			goto err_exit;
 		}
 		args->stringspace -= length;
 		args->endp += length;
 		args->argc++;
 	}
-			
+
 	args->begin_envv = args->endp;
 
 	/*
@@ -165,7 +176,7 @@
 		for (;;) {
 			error = copyin(p32++, &arg, sizeof(arg));
 			if (error)
-				return (error);
+				goto err_exit;
 			if (arg == 0)
 				break;
 			envp = PTRIN(arg);
@@ -173,9 +184,8 @@
 			    &length);
 			if (error) {
 				if (error == ENAMETOOLONG)
-					return (E2BIG);
-				else
-					return (error);
+					error = E2BIG;
+				goto err_exit;
 			}
 			args->stringspace -= length;
 			args->endp += length;
@@ -184,6 +194,12 @@
 	}
 
 	return (0);
+
+err_exit:
+	kmem_free_wakeup(exec_map, (vm_offset_t)args->buf,
+	    PATH_MAX + ARG_MAX + MAXSHELLCMDLEN);
+	args->buf = NULL;
+	return (error);
 }
 
 int
@@ -205,7 +221,14 @@
 	free(path, M_TEMP);
 	if (error == 0)
 		error = kern_execve(td, &eargs, NULL);
-	exec_free_args(&eargs);
+	if (error == 0)
+		/* Linux process can execute FreeBSD one, do not attempt
+		 * to create emuldata for such process using
+		 * linux_proc_init, this leads to a panic on KASSERT
+		 * because such process has p->p_emuldata == NULL.
+		 */
+	   	if (td->td_proc->p_sysent == &elf_linux_sysvec)
+			error = linux_proc_init(td, 0, 0);
 	return (error);
 }
 
@@ -229,7 +252,7 @@
 	if (iovcnt > UIO_MAXIOV)
 		return (EINVAL);
 	iovlen = iovcnt * sizeof(struct iovec);
-	uio = malloc(iovlen + sizeof *uio, M_IOV, M_WAITOK);
+	uio = malloc(iovlen + sizeof(*uio), M_IOV, M_WAITOK);
 	iov = (struct iovec *)(uio + 1);
 	for (i = 0; i < iovcnt; i++) {
 		error = copyin(&iovp[i], &iov32, sizeof(struct iovec32));
@@ -436,17 +459,38 @@
 linux_fork(struct thread *td, struct linux_fork_args *args)
 {
 	int error;
+	struct proc *p2;
+	struct thread *td2;
 
 #ifdef DEBUG
 	if (ldebug(fork))
 		printf(ARGS(fork, ""));
 #endif
 
-	if ((error = fork(td, (struct fork_args *)args)) != 0)
+	if ((error = fork1(td, RFFDG | RFPROC | RFSTOPPED, 0, &p2)) != 0)
 		return (error);
 
+	if (error == 0) {
+		td->td_retval[0] = p2->p_pid;
+		td->td_retval[1] = 0;
+	}
+
 	if (td->td_retval[1] == 1)
 		td->td_retval[0] = 0;
+	error = linux_proc_init(td, td->td_retval[0], 0);
+	if (error)
+		return (error);
+
+	td2 = FIRST_THREAD_IN_PROC(p2);
+
+	/*
+	 * Make this runnable after we are finished with it.
+	 */
+	thread_lock(td2);
+	TD_SET_CAN_RUN(td2);
+	sched_add(td2, SRQ_BORING);
+	thread_unlock(td2);
+
 	return (0);
 }
 
@@ -454,26 +498,51 @@
 linux_vfork(struct thread *td, struct linux_vfork_args *args)
 {
 	int error;
+	struct proc *p2;
+	struct thread *td2;
 
 #ifdef DEBUG
 	if (ldebug(vfork))
 		printf(ARGS(vfork, ""));
 #endif
 
-	if ((error = vfork(td, (struct vfork_args *)args)) != 0)
+	/* Exclude RFPPWAIT */
+	if ((error = fork1(td, RFFDG | RFPROC | RFMEM | RFSTOPPED, 0, &p2)) != 0)
 		return (error);
+	if (error == 0) {
+	   	td->td_retval[0] = p2->p_pid;
+		td->td_retval[1] = 0;
+	}
 	/* Are we the child? */
 	if (td->td_retval[1] == 1)
 		td->td_retval[0] = 0;
+	error = linux_proc_init(td, td->td_retval[0], 0);
+	if (error)
+		return (error);
+
+	PROC_LOCK(p2);
+	p2->p_flag |= P_PPWAIT;
+	PROC_UNLOCK(p2);
+
+	td2 = FIRST_THREAD_IN_PROC(p2);
+
+	/*
+	 * Make this runnable after we are finished with it.
+	 */
+	thread_lock(td2);
+	TD_SET_CAN_RUN(td2);
+	sched_add(td2, SRQ_BORING);
+	thread_unlock(td2);
+
+	/* wait for the children to exit, ie. emulate vfork */
+	PROC_LOCK(p2);
+	while (p2->p_flag & P_PPWAIT)
+	   	msleep(td->td_proc, &p2->p_mtx, PWAIT, "ppwait", 0);
+	PROC_UNLOCK(p2);
+
 	return (0);
 }
 
-#define CLONE_VM	0x100
-#define CLONE_FS	0x200
-#define CLONE_FILES	0x400
-#define CLONE_SIGHAND	0x800
-#define CLONE_PID	0x1000
-
 int
 linux_clone(struct thread *td, struct linux_clone_args *args)
 {
@@ -481,74 +550,190 @@
 	struct proc *p2;
 	struct thread *td2;
 	int exit_signal;
+	struct linux_emuldata *em;
 
 #ifdef DEBUG
 	if (ldebug(clone)) {
-		printf(ARGS(clone, "flags %x, stack %x"),
-		    (unsigned int)(uintptr_t)args->flags,
-		    (unsigned int)(uintptr_t)args->stack);
-		if (args->flags & CLONE_PID)
-			printf(LMSG("CLONE_PID not yet supported"));
+		printf(ARGS(clone, "flags %x, stack %p, parent tid: %p, "
+		    "child tid: %p"), (unsigned)args->flags,
+		    args->stack, args->parent_tidptr, args->child_tidptr);
 	}
 #endif
 
-	if (!args->stack)
-		return (EINVAL);
-
 	exit_signal = args->flags & 0x000000ff;
-	if (exit_signal >= LINUX_NSIG)
+	if (LINUX_SIG_VALID(exit_signal)) {
+		if (exit_signal <= LINUX_SIGTBLSZ)
+			exit_signal =
+			    linux_to_bsd_signal[_SIG_IDX(exit_signal)];
+	} else if (exit_signal != 0)
 		return (EINVAL);
 
-	if (exit_signal <= LINUX_SIGTBLSZ)
-		exit_signal = linux_to_bsd_signal[_SIG_IDX(exit_signal)];
-
-	if (args->flags & CLONE_VM)
+	if (args->flags & LINUX_CLONE_VM)
 		ff |= RFMEM;
-	if (args->flags & CLONE_SIGHAND)
+	if (args->flags & LINUX_CLONE_SIGHAND)
 		ff |= RFSIGSHARE;
-	if (!(args->flags & CLONE_FILES))
+	/*
+	 * XXX: In Linux, sharing of fs info (chroot/cwd/umask)
+	 * and open files is independant.  In FreeBSD, its in one
+	 * structure but in reality it does not cause any problems
+	 * because both of these flags are usually set together.
+	 */
+	if (!(args->flags & (LINUX_CLONE_FILES | LINUX_CLONE_FS)))
 		ff |= RFFDG;
 
+	/*
+	 * Attempt to detect when linux_clone(2) is used for creating
+	 * kernel threads. Unfortunately despite the existence of the
+	 * CLONE_THREAD flag, version of linuxthreads package used in
+	 * most popular distros as of beginning of 2005 doesn't make
+	 * any use of it. Therefore, this detection relies on
+	 * empirical observation that linuxthreads sets certain
+	 * combination of flags, so that we can make more or less
+	 * precise detection and notify the FreeBSD kernel that several
+	 * processes are in fact part of the same threading group, so
+	 * that special treatment is necessary for signal delivery
+	 * between those processes and fd locking.
+	 */
+	if ((args->flags & 0xffffff00) == LINUX_THREADING_FLAGS)
+		ff |= RFTHREAD;
+
+	if (args->flags & LINUX_CLONE_PARENT_SETTID)
+		if (args->parent_tidptr == NULL)
+			return (EINVAL);
+
 	error = fork1(td, ff, 0, &p2);
 	if (error)
 		return (error);
-	
+
+	if (args->flags & (LINUX_CLONE_PARENT | LINUX_CLONE_THREAD)) {
+	   	sx_xlock(&proctree_lock);
+		PROC_LOCK(p2);
+		proc_reparent(p2, td->td_proc->p_pptr);
+		PROC_UNLOCK(p2);
+		sx_xunlock(&proctree_lock);
+	}
+
+	/* create the emuldata */
+	error = linux_proc_init(td, p2->p_pid, args->flags);
+	/* reference it - no need to check this */
+	em = em_find(p2, EMUL_DOLOCK);
+	KASSERT(em != NULL, ("clone: emuldata not found.\n"));
+	/* and adjust it */
+
+	if (args->flags & LINUX_CLONE_THREAD) {
+#ifdef notyet
+	   	PROC_LOCK(p2);
+	   	p2->p_pgrp = td->td_proc->p_pgrp;
+	   	PROC_UNLOCK(p2);
+#endif
+		exit_signal = 0;
+	}
+
+	if (args->flags & LINUX_CLONE_CHILD_SETTID)
+		em->child_set_tid = args->child_tidptr;
+	else
+	   	em->child_set_tid = NULL;
+
+	if (args->flags & LINUX_CLONE_CHILD_CLEARTID)
+		em->child_clear_tid = args->child_tidptr;
+	else
+	   	em->child_clear_tid = NULL;
+
+	EMUL_UNLOCK(&emul_lock);
+
+	if (args->flags & LINUX_CLONE_PARENT_SETTID) {
+		error = copyout(&p2->p_pid, args->parent_tidptr,
+		    sizeof(p2->p_pid));
+		if (error)
+			printf(LMSG("copyout failed!"));
+	}
 
 	PROC_LOCK(p2);
 	p2->p_sigparent = exit_signal;
 	PROC_UNLOCK(p2);
 	td2 = FIRST_THREAD_IN_PROC(p2);
-	td2->td_frame->tf_rsp = PTROUT(args->stack);
+	/*
+	 * In a case of stack = NULL, we are supposed to COW calling process
+	 * stack. This is what normal fork() does, so we just keep tf_rsp arg
+	 * intact.
+	 */
+	if (args->stack)
+		td2->td_frame->tf_rsp = PTROUT(args->stack);
+
+	if (args->flags & LINUX_CLONE_SETTLS) {
+		struct user_segment_descriptor sd;
+		struct l_user_desc info;
+		int a[2];
+
+		error = copyin((void *)td->td_frame->tf_rsi, &info,
+		    sizeof(struct l_user_desc));
+		if (error) {
+			printf(LMSG("copyin failed!"));
+		} else {
+			/* We might copy out the entry_number as GUGS32_SEL. */
+			info.entry_number = GUGS32_SEL;
+			error = copyout(&info, (void *)td->td_frame->tf_rsi,
+			    sizeof(struct l_user_desc));
+			if (error)
+				printf(LMSG("copyout failed!"));
+
+			a[0] = LINUX_LDT_entry_a(&info);
+			a[1] = LINUX_LDT_entry_b(&info);
+
+			memcpy(&sd, &a, sizeof(a));
+#ifdef DEBUG
+			if (ldebug(clone))
+				printf("Segment created in clone with "
+				    "CLONE_SETTLS: lobase: %x, hibase: %x, "
+				    "lolimit: %x, hilimit: %x, type: %i, "
+				    "dpl: %i, p: %i, xx: %i, long: %i, "
+				    "def32: %i, gran: %i\n", sd.sd_lobase,
+				    sd.sd_hibase, sd.sd_lolimit, sd.sd_hilimit,
+				    sd.sd_type, sd.sd_dpl, sd.sd_p, sd.sd_xx,
+				    sd.sd_long, sd.sd_def32, sd.sd_gran);
+#endif
+			td2->td_pcb->pcb_gsbase = (register_t)info.base_addr;
+			td2->td_pcb->pcb_gs32sd = sd;
+			td2->td_pcb->pcb_gs32p = &gdt[GUGS32_SEL];
+			td2->td_pcb->pcb_gs = GSEL(GUGS32_SEL, SEL_UPL);
+			td2->td_pcb->pcb_flags |= PCB_32BIT;
+		}
+	}
 
 #ifdef DEBUG
 	if (ldebug(clone))
-		printf(LMSG("clone: successful rfork to %ld, stack %p sig = %d"),
-		    (long)p2->p_pid, args->stack, exit_signal);
+		printf(LMSG("clone: successful rfork to %d, "
+		    "stack %p sig = %d"), (int)p2->p_pid, args->stack,
+		    exit_signal);
 #endif
+	if (args->flags & LINUX_CLONE_VFORK) {
+	   	PROC_LOCK(p2);
+	   	p2->p_flag |= P_PPWAIT;
+	   	PROC_UNLOCK(p2);
+	}
 
 	/*
 	 * Make this runnable after we are finished with it.
 	 */
-	mtx_lock_spin(&sched_lock);
+	thread_lock(td2);
 	TD_SET_CAN_RUN(td2);
-	setrunqueue(td2, SRQ_BORING);
-	mtx_unlock_spin(&sched_lock);
+	sched_add(td2, SRQ_BORING);
+	thread_unlock(td2);
 
 	td->td_retval[0] = p2->p_pid;
 	td->td_retval[1] = 0;
+
+	if (args->flags & LINUX_CLONE_VFORK) {
+		/* wait for the children to exit, ie. emulate vfork */
+		PROC_LOCK(p2);
+		while (p2->p_flag & P_PPWAIT)
+			msleep(td->td_proc, &p2->p_mtx, PWAIT, "ppwait", 0);
+		PROC_UNLOCK(p2);
+	}
+
 	return (0);
 }
 
-/* XXX move */
-struct l_mmap_argv {
-	l_ulong		addr;
-	l_ulong		len;
-	l_ulong		prot;
-	l_ulong		flags;
-	l_ulong		fd;
-	l_ulong		pgoff;
-};
-
 #define STACK_SIZE  (2 * 1024 * 1024)
 #define GUARD_SIZE  (4 * PAGE_SIZE)
 
@@ -561,8 +746,8 @@
 
 #ifdef DEBUG
 	if (ldebug(mmap2))
-		printf(ARGS(mmap2, "%p, %d, %d, 0x%08x, %d, %d"),
-		    (void *)(intptr_t)args->addr, args->len, args->prot,
+		printf(ARGS(mmap2, "0x%08x, %d, %d, 0x%08x, %d, %d"),
+		    args->addr, args->len, args->prot,
 		    args->flags, args->fd, args->pgoff);
 #endif
 
@@ -588,10 +773,9 @@
 
 #ifdef DEBUG
 	if (ldebug(mmap))
-		printf(ARGS(mmap, "%p, %d, %d, 0x%08x, %d, %d"),
-		    (void *)(intptr_t)linux_args.addr, linux_args.len,
-		    linux_args.prot, linux_args.flags, linux_args.fd,
-		    linux_args.pgoff);
+		printf(ARGS(mmap, "0x%08x, %d, %d, 0x%08x, %d, %d"),
+		    linux_args.addr, linux_args.len, linux_args.prot,
+		    linux_args.flags, linux_args.fd, linux_args.pgoff);
 #endif
 	if ((linux_args.pgoff % PAGE_SIZE) != 0)
 		return (EINVAL);
@@ -614,9 +798,20 @@
 		off_t pos;
 	} */ bsd_args;
 	int error;
+	struct file *fp;
 
 	error = 0;
 	bsd_args.flags = 0;
+	fp = NULL;
+
+	/*
+	 * Linux mmap(2):
+	 * You must specify exactly one of MAP_SHARED and MAP_PRIVATE
+	 */
+	if (! ((linux_args->flags & LINUX_MAP_SHARED) ^
+	    (linux_args->flags & LINUX_MAP_PRIVATE)))
+		return (EINVAL);
+
 	if (linux_args->flags & LINUX_MAP_SHARED)
 		bsd_args.flags |= MAP_SHARED;
 	if (linux_args->flags & LINUX_MAP_PRIVATE)
@@ -627,23 +822,60 @@
 		bsd_args.flags |= MAP_ANON;
 	else
 		bsd_args.flags |= MAP_NOSYNC;
-	if (linux_args->flags & LINUX_MAP_GROWSDOWN) {
+	if (linux_args->flags & LINUX_MAP_GROWSDOWN)
 		bsd_args.flags |= MAP_STACK;
 
-		/* The linux MAP_GROWSDOWN option does not limit auto
+	/*
+	 * PROT_READ, PROT_WRITE, or PROT_EXEC implies PROT_READ and PROT_EXEC
+	 * on Linux/i386. We do this to ensure maximum compatibility.
+	 * Linux/ia64 does the same in i386 emulation mode.
+	 */
+	bsd_args.prot = linux_args->prot;
+	if (bsd_args.prot & (PROT_READ | PROT_WRITE | PROT_EXEC))
+		bsd_args.prot |= PROT_READ | PROT_EXEC;
+
+	/* Linux does not check file descriptor when MAP_ANONYMOUS is set. */
+	bsd_args.fd = (bsd_args.flags & MAP_ANON) ? -1 : linux_args->fd;
+	if (bsd_args.fd != -1) {
+		/*
+		 * Linux follows Solaris mmap(2) description:
+		 * The file descriptor fildes is opened with
+		 * read permission, regardless of the
+		 * protection options specified.
+		 */
+
+		if ((error = fget(td, bsd_args.fd, &fp)) != 0)
+			return (error);
+		if (fp->f_type != DTYPE_VNODE) {
+			fdrop(fp, td);
+			return (EINVAL);
+		}
+
+		/* Linux mmap() just fails for O_WRONLY files */
+		if (!(fp->f_flag & FREAD)) {
+			fdrop(fp, td);
+			return (EACCES);
+		}
+
+		fdrop(fp, td);
+	}
+
+	if (linux_args->flags & LINUX_MAP_GROWSDOWN) {
+		/*
+		 * The Linux MAP_GROWSDOWN option does not limit auto
 		 * growth of the region.  Linux mmap with this option
 		 * takes as addr the inital BOS, and as len, the initial
 		 * region size.  It can then grow down from addr without
-		 * limit.  However, linux threads has an implicit internal
+		 * limit.  However, Linux threads has an implicit internal
 		 * limit to stack size of STACK_SIZE.  Its just not
-		 * enforced explicitly in linux.  But, here we impose
+		 * enforced explicitly in Linux.  But, here we impose
 		 * a limit of (STACK_SIZE - GUARD_SIZE) on the stack
 		 * region, since we can do this with our mmap.
 		 *
 		 * Our mmap with MAP_STACK takes addr as the maximum
 		 * downsize limit on BOS, and as len the max size of
-		 * the region.  It them maps the top SGROWSIZ bytes,
-		 * and autgrows the region down, up to the limit
+		 * the region.  It then maps the top SGROWSIZ bytes,
+		 * and auto grows the region down, up to the limit
 		 * in addr.
 		 *
 		 * If we don't use the MAP_STACK option, the effect
@@ -651,13 +883,10 @@
 		 * fixed size of (STACK_SIZE - GUARD_SIZE).
 		 */
 
-		/* This gives us TOS */
-		bsd_args.addr = (caddr_t)PTRIN(linux_args->addr) +
-		    linux_args->len;
-
-		if ((caddr_t)PTRIN(bsd_args.addr) >
+		if ((caddr_t)PTRIN(linux_args->addr) + linux_args->len >
 		    p->p_vmspace->vm_maxsaddr) {
-			/* Some linux apps will attempt to mmap
+			/*
+			 * Some Linux apps will attempt to mmap
 			 * thread stacks near the top of their
 			 * address space.  If their TOS is greater
 			 * than vm_maxsaddr, vm_map_growstack()
@@ -673,8 +902,7 @@
 			 * mmap's return value.
 			 */
 			PROC_LOCK(p);
-			p->p_vmspace->vm_maxsaddr =
-			    (char *)LINUX32_USRSTACK -
+			p->p_vmspace->vm_maxsaddr = (char *)LINUX32_USRSTACK -
 			    lim_cur(p, RLIMIT_STACK);
 			PROC_UNLOCK(p);
 		}
@@ -685,30 +913,20 @@
 		else
 			bsd_args.len  = STACK_SIZE - GUARD_SIZE;
 
-		/* This gives us a new BOS.  If we're using VM_STACK, then
+		/*
+		 * This gives us a new BOS.  If we're using VM_STACK, then
 		 * mmap will just map the top SGROWSIZ bytes, and let
 		 * the stack grow down to the limit at BOS.  If we're
 		 * not using VM_STACK we map the full stack, since we
 		 * don't have a way to autogrow it.
 		 */
-		bsd_args.addr -= bsd_args.len;
+		bsd_args.addr = (caddr_t)PTRIN(linux_args->addr) -
+		    bsd_args.len;
 	} else {
 		bsd_args.addr = (caddr_t)PTRIN(linux_args->addr);
 		bsd_args.len  = linux_args->len;
 	}
-	/*
-	 * XXX i386 Linux always emulator forces PROT_READ on (why?)
-	 * so we do the same. We add PROT_EXEC to work around buggy
-	 * applications (e.g. Java) that take advantage of the fact
-	 * that execute permissions are not enforced by x86 CPUs.
-	 */
-	bsd_args.prot = linux_args->prot | PROT_EXEC | PROT_READ;
-	if (linux_args->flags & LINUX_MAP_ANON)
-		bsd_args.fd = -1;
-	else
-		bsd_args.fd = linux_args->fd;
 	bsd_args.pos = (off_t)linux_args->pgoff * PAGE_SIZE;
-	bsd_args.pad = 0;
 
 #ifdef DEBUG
 	if (ldebug(mmap))
@@ -727,6 +945,36 @@
 }
 
 int
+linux_mprotect(struct thread *td, struct linux_mprotect_args *uap)
+{
+	struct mprotect_args bsd_args;
+
+	bsd_args.addr = uap->addr;
+	bsd_args.len = uap->len;
+	bsd_args.prot = uap->prot;
+	if (bsd_args.prot & (PROT_READ | PROT_WRITE | PROT_EXEC))
+		bsd_args.prot |= PROT_READ | PROT_EXEC;
+	return (mprotect(td, &bsd_args));
+}
+
+int
+linux_iopl(struct thread *td, struct linux_iopl_args *args)
+{
+	int error;
+
+	if (args->level < 0 || args->level > 3)
+		return (EINVAL);
+	if ((error = priv_check(td, PRIV_IO)) != 0)
+		return (error);
+	if ((error = securelevel_gt(td->td_ucred, 0)) != 0)
+		return (error);
+	td->td_frame->tf_rflags = (td->td_frame->tf_rflags & ~PSL_IOPL) |
+	    (args->level * (PSL_IOPL / 3));
+
+	return (0);
+}
+
+int
 linux_pipe(struct thread *td, struct linux_pipe_args *args)
 {
 	int pip[2];
@@ -797,7 +1045,7 @@
 }
 
 /*
- * Linux has two extra args, restart and oldmask.  We dont use these,
+ * Linux has two extra args, restart and oldmask.  We don't use these,
  * but it seems that "restart" is actually a context pointer that
  * enables the signal to happen with a different register set.
  */
@@ -904,7 +1152,6 @@
 #endif
 
 	sa.fd = args->fd;
-	sa.pad = 0;
 	sa.length = args->length;
 	return ftruncate(td, &sa);
 }
@@ -921,35 +1168,41 @@
 		microtime(&atv);
 		atv32.tv_sec = atv.tv_sec;
 		atv32.tv_usec = atv.tv_usec;
-		error = copyout(&atv32, uap->tp, sizeof (atv32));
+		error = copyout(&atv32, uap->tp, sizeof(atv32));
 	}
 	if (error == 0 && uap->tzp != NULL) {
 		rtz.tz_minuteswest = tz_minuteswest;
 		rtz.tz_dsttime = tz_dsttime;
-		error = copyout(&rtz, uap->tzp, sizeof (rtz));
+		error = copyout(&rtz, uap->tzp, sizeof(rtz));
 	}
 	return (error);
 }
 
 int
-linux_nanosleep(struct thread *td, struct linux_nanosleep_args *uap)
+linux_settimeofday(struct thread *td, struct linux_settimeofday_args *uap)
 {
-	struct timespec rqt, rmt;
-	struct l_timespec ats32;
+	l_timeval atv32;
+	struct timeval atv, *tvp;
+	struct timezone atz, *tzp;
 	int error;
 
-	error = copyin(uap->rqtp, &ats32, sizeof(ats32));
-	if (error != 0)
-		return (error);
-	rqt.tv_sec = ats32.tv_sec;
-	rqt.tv_nsec = ats32.tv_nsec;
-	error = kern_nanosleep(td, &rqt, &rmt);
-	if (uap->rmtp != NULL) {
-		ats32.tv_sec = rmt.tv_sec;
-		ats32.tv_nsec = rmt.tv_nsec;
-		error = copyout(&ats32, uap->rmtp, sizeof(ats32));
-	}
-	return (error);
+	if (uap->tp) {
+		error = copyin(uap->tp, &atv32, sizeof(atv32));
+		if (error)
+			return (error);
+		atv.tv_sec = atv32.tv_sec;
+		atv.tv_usec = atv32.tv_usec;
+		tvp = &atv;
+	} else
+		tvp = NULL;
+	if (uap->tzp) {
+		error = copyin(uap->tzp, &atz, sizeof(atz));
+		if (error)
+			return (error);
+		tzp = &atz;
+	} else
+		tzp = NULL;
+	return (kern_settimeofday(td, tvp, tzp));
 }
 
 int
@@ -1003,15 +1256,106 @@
 }
 
 int
-linux_mprotect(struct thread *td, struct linux_mprotect_args *uap)
+linux_set_thread_area(struct thread *td,
+    struct linux_set_thread_area_args *args)
 {
-	struct mprotect_args bsd_args;
+	struct l_user_desc info;
+	struct user_segment_descriptor sd;
+	int a[2];
+	int error;
 
-	bsd_args.addr = uap->addr;
-	bsd_args.len = uap->len;
-	bsd_args.prot = uap->prot;
-	/* XXX PROT_READ implies PROT_EXEC; see linux_mmap_common(). */
-	if ((bsd_args.prot & PROT_READ) != 0)
-		bsd_args.prot |= PROT_EXEC;
-	return (mprotect(td, &bsd_args));
+	error = copyin(args->desc, &info, sizeof(struct l_user_desc));
+	if (error)
+		return (error);
+
+#ifdef DEBUG
+	if (ldebug(set_thread_area))
+		printf(ARGS(set_thread_area, "%i, %x, %x, %i, %i, %i, "
+		    "%i, %i, %i"), info.entry_number, info.base_addr,
+		    info.limit, info.seg_32bit, info.contents,
+		    info.read_exec_only, info.limit_in_pages,
+		    info.seg_not_present, info.useable);
+#endif
+
+	/*
+	 * Semantics of Linux version: every thread in the system has array
+	 * of three TLS descriptors. 1st is GLIBC TLS, 2nd is WINE, 3rd unknown.
+	 * This syscall loads one of the selected TLS decriptors with a value
+	 * and also loads GDT descriptors 6, 7 and 8 with the content of
+	 * the per-thread descriptors.
+	 *
+	 * Semantics of FreeBSD version: I think we can ignore that Linux has
+	 * three per-thread descriptors and use just the first one.
+	 * The tls_array[] is used only in [gs]et_thread_area() syscalls and
+	 * for loading the GDT descriptors. We use just one GDT descriptor
+	 * for TLS, so we will load just one.
+	 *
+	 * XXX: This doesn't work when a user space process tries to use more
+	 * than one TLS segment. Comment in the Linux source says wine might
+	 * do this.
+	 */
+
+	/*
+	 * GLIBC reads current %gs and call set_thread_area() with it.
+	 * We should let GUDATA_SEL and GUGS32_SEL proceed as well because
+	 * we use these segments.
+	 */
+	switch (info.entry_number) {
+	case GUGS32_SEL:
+	case GUDATA_SEL:
+	case 6:
+	case -1:
+		info.entry_number = GUGS32_SEL;
+		break;
+	default:
+		return (EINVAL);
+	}
+
+	/*
+	 * We have to copy out the GDT entry we use.
+	 *
+	 * XXX: What if a user space program does not check the return value
+	 * and tries to use 6, 7 or 8?
+	 */
+	error = copyout(&info, args->desc, sizeof(struct l_user_desc));
+	if (error)
+		return (error);
+
+	if (LINUX_LDT_empty(&info)) {
+		a[0] = 0;
+		a[1] = 0;
+	} else {
+		a[0] = LINUX_LDT_entry_a(&info);
+		a[1] = LINUX_LDT_entry_b(&info);
+	}
+
+	memcpy(&sd, &a, sizeof(a));
+#ifdef DEBUG
+	if (ldebug(set_thread_area))
+		printf("Segment created in set_thread_area: "
+		    "lobase: %x, hibase: %x, lolimit: %x, hilimit: %x, "
+		    "type: %i, dpl: %i, p: %i, xx: %i, long: %i, "
+		    "def32: %i, gran: %i\n",
+		    sd.sd_lobase,
+		    sd.sd_hibase,
+		    sd.sd_lolimit,
+		    sd.sd_hilimit,
+		    sd.sd_type,
+		    sd.sd_dpl,
+		    sd.sd_p,
+		    sd.sd_xx,
+		    sd.sd_long,
+		    sd.sd_def32,
+		    sd.sd_gran);
+#endif
+
+	critical_enter();
+	td->td_pcb->pcb_gsbase = (register_t)info.base_addr;
+	td->td_pcb->pcb_gs32sd = gdt[GUGS32_SEL] = sd;
+	td->td_pcb->pcb_gs32p = &gdt[GUGS32_SEL];
+	td->td_pcb->pcb_flags |= PCB_32BIT;
+	wrmsr(MSR_KGSBASE, td->td_pcb->pcb_gsbase);
+	critical_exit();
+
+	return (0);
 }
Index: linux32_dummy.c
===================================================================
RCS file: /home/cvs/src/sys/amd64/linux32/linux32_dummy.c,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L sys/amd64/linux32/linux32_dummy.c -L sys/amd64/linux32/linux32_dummy.c -u -r1.1.1.1 -r1.2
--- sys/amd64/linux32/linux32_dummy.c
+++ sys/amd64/linux32/linux32_dummy.c
@@ -27,7 +27,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/amd64/linux32/linux32_dummy.c,v 1.1 2004/08/16 07:55:06 tjr Exp $");
+__FBSDID("$FreeBSD: src/sys/amd64/linux32/linux32_dummy.c,v 1.9 2007/04/18 18:08:12 jkim Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -53,9 +53,6 @@
 DUMMY(sysfs);
 DUMMY(query_module);
 DUMMY(nfsservctl);
-DUMMY(prctl);
-DUMMY(rt_sigpending);
-DUMMY(rt_sigtimedwait);
 DUMMY(rt_sigqueueinfo);
 DUMMY(capget);
 DUMMY(capset);
@@ -67,7 +64,53 @@
 DUMMY(mincore);
 DUMMY(fadvise64);
 DUMMY(ptrace);
-DUMMY(settimeofday);
+DUMMY(lookup_dcookie);
+DUMMY(epoll_create);
+DUMMY(epoll_ctl);
+DUMMY(epoll_wait);
+DUMMY(remap_file_pages);
+DUMMY(timer_create);
+DUMMY(timer_settime);
+DUMMY(timer_gettime);
+DUMMY(timer_getoverrun);
+DUMMY(timer_delete);
+DUMMY(fstatfs64);
+DUMMY(fadvise64_64);
+DUMMY(mbind);
+DUMMY(get_mempolicy);
+DUMMY(set_mempolicy);
+DUMMY(mq_open);
+DUMMY(mq_unlink);
+DUMMY(mq_timedsend);
+DUMMY(mq_timedreceive);
+DUMMY(mq_notify);
+DUMMY(mq_getsetattr);
+DUMMY(kexec_load);
+DUMMY(waitid);
+DUMMY(add_key);
+DUMMY(request_key);
+DUMMY(keyctl);
+DUMMY(ioprio_set);
+DUMMY(ioprio_get);
+DUMMY(inotify_init);
+DUMMY(inotify_add_watch);
+DUMMY(inotify_rm_watch);
+DUMMY(migrate_pages);
+DUMMY(mkdirat);
+DUMMY(mknodat);
+DUMMY(fchownat);
+DUMMY(futimesat);
+DUMMY(fstatat64);
+DUMMY(unlinkat);
+DUMMY(renameat);
+DUMMY(linkat);
+DUMMY(symlinkat);
+DUMMY(readlinkat);
+DUMMY(fchmodat);
+DUMMY(faccessat);
+DUMMY(pselect6);
+DUMMY(ppoll);
+DUMMY(unshare);
 
 #define DUMMY_XATTR(s)						\
 int								\
Index: linux32_locore.s
===================================================================
RCS file: /home/cvs/src/sys/amd64/linux32/linux32_locore.s,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L sys/amd64/linux32/linux32_locore.s -L sys/amd64/linux32/linux32_locore.s -u -r1.1.1.1 -r1.2
--- sys/amd64/linux32/linux32_locore.s
+++ sys/amd64/linux32/linux32_locore.s
@@ -1,4 +1,4 @@
-/* $FreeBSD: src/sys/amd64/linux32/linux32_locore.s,v 1.1 2004/08/16 07:55:06 tjr Exp $ */
+/* $FreeBSD: src/sys/amd64/linux32/linux32_locore.s,v 1.2 2007/03/30 00:06:21 jkim Exp $ */
 
 #include "linux32_assym.h"			/* system definitions */
 #include <machine/asmacros.h>			/* miscellaneous asm macros */
@@ -11,8 +11,6 @@
 NON_GPROF_ENTRY(linux_sigcode)
 	call	*LINUX_SIGF_HANDLER(%esp)
 	leal	LINUX_SIGF_SC(%esp),%ebx	/* linux scp */
-	movl	LINUX_SC_GS(%ebx),%gs
-	movl	LINUX_SC_FS(%ebx),%fs
 	movl	LINUX_SC_ES(%ebx),%es
 	movl	LINUX_SC_DS(%ebx),%ds
 	movl	%esp, %ebx			/* pass sigframe */
@@ -25,8 +23,6 @@
 linux_rt_sigcode:
 	call	*LINUX_RT_SIGF_HANDLER(%esp)
 	leal	LINUX_RT_SIGF_UC(%esp),%ebx	/* linux ucp */
-	movl	LINUX_SC_GS(%ebx),%gs
-	movl	LINUX_SC_FS(%ebx),%fs
 	movl	LINUX_SC_ES(%ebx),%es
 	movl	LINUX_SC_DS(%ebx),%ds
 	push	%eax				/* fake ret addr */
Index: linux32_syscall.h
===================================================================
RCS file: /home/cvs/src/sys/amd64/linux32/linux32_syscall.h,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L sys/amd64/linux32/linux32_syscall.h -L sys/amd64/linux32/linux32_syscall.h -u -r1.1.1.1 -r1.2
--- sys/amd64/linux32/linux32_syscall.h
+++ sys/amd64/linux32/linux32_syscall.h
@@ -2,8 +2,8 @@
  * System call numbers.
  *
  * DO NOT EDIT-- this file is automatically generated.
- * $FreeBSD: src/sys/amd64/linux32/linux32_syscall.h,v 1.5.2.1 2005/07/20 17:43:52 jhb Exp $
- * created from FreeBSD: src/sys/amd64/linux32/syscalls.master,v 1.4.2.1 2005/07/20 17:42:14 jhb Exp 
+ * $FreeBSD: src/sys/amd64/linux32/linux32_syscall.h,v 1.33 2007/09/18 19:50:32 dwmalone Exp $
+ * created from FreeBSD: src/sys/amd64/linux32/syscalls.master,v 1.29 2007/08/28 12:26:34 kib Exp 
  */
 
 #define	LINUX_SYS_exit	1
@@ -22,6 +22,7 @@
 #define	LINUX_SYS_linux_mknod	14
 #define	LINUX_SYS_linux_chmod	15
 #define	LINUX_SYS_linux_lchown16	16
+#define	LINUX_SYS_linux_stat	18
 #define	LINUX_SYS_linux_lseek	19
 #define	LINUX_SYS_linux_getpid	20
 #define	LINUX_SYS_linux_mount	21
@@ -59,7 +60,7 @@
 #define	LINUX_SYS_chroot	61
 #define	LINUX_SYS_linux_ustat	62
 #define	LINUX_SYS_dup2	63
-#define	LINUX_SYS_getppid	64
+#define	LINUX_SYS_linux_getppid	64
 #define	LINUX_SYS_getpgrp	65
 #define	LINUX_SYS_setsid	66
 #define	LINUX_SYS_linux_sigaction	67
@@ -69,7 +70,7 @@
 #define	LINUX_SYS_linux_setregid16	71
 #define	LINUX_SYS_linux_sigsuspend	72
 #define	LINUX_SYS_linux_sigpending	73
-#define	LINUX_SYS_osethostname	74
+#define	LINUX_SYS_linux_sethostname	74
 #define	LINUX_SYS_linux_setrlimit	75
 #define	LINUX_SYS_linux_old_getrlimit	76
 #define	LINUX_SYS_linux_getrusage	77
@@ -79,6 +80,7 @@
 #define	LINUX_SYS_linux_setgroups16	81
 #define	LINUX_SYS_linux_old_select	82
 #define	LINUX_SYS_linux_symlink	83
+#define	LINUX_SYS_linux_lstat	84
 #define	LINUX_SYS_linux_readlink	85
 #define	LINUX_SYS_swapon	87
 #define	LINUX_SYS_linux_reboot	88
@@ -86,7 +88,7 @@
 #define	LINUX_SYS_linux_mmap	90
 #define	LINUX_SYS_munmap	91
 #define	LINUX_SYS_linux_truncate	92
-#define	LINUX_SYS_oftruncate	93
+#define	LINUX_SYS_linux_ftruncate	93
 #define	LINUX_SYS_fchmod	94
 #define	LINUX_SYS_fchown	95
 #define	LINUX_SYS_linux_getpriority	96
@@ -101,6 +103,7 @@
 #define	LINUX_SYS_linux_newlstat	107
 #define	LINUX_SYS_linux_newfstat	108
 #define	LINUX_SYS_linux_uname	109
+#define	LINUX_SYS_linux_iopl	110
 #define	LINUX_SYS_linux_vhangup	111
 #define	LINUX_SYS_linux_wait4	114
 #define	LINUX_SYS_linux_swapoff	115
@@ -204,7 +207,7 @@
 #define	LINUX_SYS_madvise	219
 #define	LINUX_SYS_linux_getdents64	220
 #define	LINUX_SYS_linux_fcntl64	221
-#define	LINUX_SYS_gettid	224
+#define	LINUX_SYS_linux_gettid	224
 #define	LINUX_SYS_linux_setxattr	226
 #define	LINUX_SYS_linux_lsetxattr	227
 #define	LINUX_SYS_linux_fsetxattr	228
@@ -217,6 +220,66 @@
 #define	LINUX_SYS_linux_removexattr	235
 #define	LINUX_SYS_linux_lremovexattr	236
 #define	LINUX_SYS_linux_fremovexattr	237
+#define	LINUX_SYS_linux_tkill	238
+#define	LINUX_SYS_linux_sys_futex	240
+#define	LINUX_SYS_linux_sched_getaffinity	242
+#define	LINUX_SYS_linux_set_thread_area	243
 #define	LINUX_SYS_linux_fadvise64	250
-#define	LINUX_SYS_exit_group	252
-#define	LINUX_SYS_MAXSYSCALL	268
+#define	LINUX_SYS_linux_exit_group	252
+#define	LINUX_SYS_linux_lookup_dcookie	253
+#define	LINUX_SYS_linux_epoll_create	254
+#define	LINUX_SYS_linux_epoll_ctl	255
+#define	LINUX_SYS_linux_epoll_wait	256
+#define	LINUX_SYS_linux_remap_file_pages	257
+#define	LINUX_SYS_linux_set_tid_address	258
+#define	LINUX_SYS_linux_timer_create	259
+#define	LINUX_SYS_linux_timer_settime	260
+#define	LINUX_SYS_linux_timer_gettime	261
+#define	LINUX_SYS_linux_timer_getoverrun	262
+#define	LINUX_SYS_linux_timer_delete	263
+#define	LINUX_SYS_linux_clock_settime	264
+#define	LINUX_SYS_linux_clock_gettime	265
+#define	LINUX_SYS_linux_clock_getres	266
+#define	LINUX_SYS_linux_clock_nanosleep	267
+#define	LINUX_SYS_linux_statfs64	268
+#define	LINUX_SYS_linux_fstatfs64	269
+#define	LINUX_SYS_linux_tgkill	270
+#define	LINUX_SYS_linux_utimes	271
+#define	LINUX_SYS_linux_fadvise64_64	272
+#define	LINUX_SYS_linux_mbind	274
+#define	LINUX_SYS_linux_get_mempolicy	275
+#define	LINUX_SYS_linux_set_mempolicy	276
+#define	LINUX_SYS_linux_mq_open	277
+#define	LINUX_SYS_linux_mq_unlink	278
+#define	LINUX_SYS_linux_mq_timedsend	279
+#define	LINUX_SYS_linux_mq_timedreceive	280
+#define	LINUX_SYS_linux_mq_notify	281
+#define	LINUX_SYS_linux_mq_getsetattr	282
+#define	LINUX_SYS_linux_kexec_load	283
+#define	LINUX_SYS_linux_waitid	284
+#define	LINUX_SYS_linux_add_key	286
+#define	LINUX_SYS_linux_request_key	287
+#define	LINUX_SYS_linux_keyctl	288
+#define	LINUX_SYS_linux_ioprio_set	289
+#define	LINUX_SYS_linux_ioprio_get	290
+#define	LINUX_SYS_linux_inotify_init	291
+#define	LINUX_SYS_linux_inotify_add_watch	292
+#define	LINUX_SYS_linux_inotify_rm_watch	293
+#define	LINUX_SYS_linux_migrate_pages	294
+#define	LINUX_SYS_linux_openat	295
+#define	LINUX_SYS_linux_mkdirat	296
+#define	LINUX_SYS_linux_mknodat	297
+#define	LINUX_SYS_linux_fchownat	298
+#define	LINUX_SYS_linux_futimesat	299
+#define	LINUX_SYS_linux_fstatat64	300
+#define	LINUX_SYS_linux_unlinkat	301
+#define	LINUX_SYS_linux_renameat	302
+#define	LINUX_SYS_linux_linkat	303
+#define	LINUX_SYS_linux_symlinkat	304
+#define	LINUX_SYS_linux_readlinkat	305
+#define	LINUX_SYS_linux_fchmodat	306
+#define	LINUX_SYS_linux_faccessat	307
+#define	LINUX_SYS_linux_pselect6	308
+#define	LINUX_SYS_linux_ppoll	309
+#define	LINUX_SYS_linux_unshare	310
+#define	LINUX_SYS_MAXSYSCALL	311
Index: linux32_sysvec.c
===================================================================
RCS file: /home/cvs/src/sys/amd64/linux32/linux32_sysvec.c,v
retrieving revision 1.1.1.2
retrieving revision 1.2
diff -L sys/amd64/linux32/linux32_sysvec.c -L sys/amd64/linux32/linux32_sysvec.c -u -r1.1.1.2 -r1.2
--- sys/amd64/linux32/linux32_sysvec.c
+++ sys/amd64/linux32/linux32_sysvec.c
@@ -31,14 +31,9 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/amd64/linux32/linux32_sysvec.c,v 1.7.2.2 2005/12/22 21:25:19 jhb Exp $");
-
-/* XXX we use functions that might not exist. */
+__FBSDID("$FreeBSD: src/sys/amd64/linux32/linux32_sysvec.c,v 1.31 2007/09/20 13:46:26 kib Exp $");
 #include "opt_compat.h"
 
-#ifndef COMPAT_43
-#error "Unable to compile Linux-emulator due to missing COMPAT_43 option!"
-#endif
 #ifndef COMPAT_IA32
 #error "Unable to compile Linux-emulator due to missing COMPAT_IA32 option!"
 #endif
@@ -63,6 +58,7 @@
 #include <sys/sysent.h>
 #include <sys/sysproto.h>
 #include <sys/vnode.h>
+#include <sys/eventhandler.h>
 
 #include <vm/vm.h>
 #include <vm/pmap.h>
@@ -79,14 +75,12 @@
 
 #include <amd64/linux32/linux.h>
 #include <amd64/linux32/linux32_proto.h>
+#include <compat/linux/linux_emul.h>
 #include <compat/linux/linux_mib.h>
 #include <compat/linux/linux_signal.h>
 #include <compat/linux/linux_util.h>
 
 MODULE_VERSION(linux, 1);
-MODULE_DEPEND(linux, sysvmsg, 1, 1, 1);
-MODULE_DEPEND(linux, sysvsem, 1, 1, 1);
-MODULE_DEPEND(linux, sysvshm, 1, 1, 1);
 
 MALLOC_DEFINE(M_LINUX, "linux", "Linux mode structures");
 
@@ -117,20 +111,31 @@
 extern struct sysent linux_sysent[LINUX_SYS_MAXSYSCALL];
 
 SET_DECLARE(linux_ioctl_handler_set, struct linux_ioctl_handler);
+SET_DECLARE(linux_device_handler_set, struct linux_device_handler);
 
 static int	elf_linux_fixup(register_t **stack_base,
 		    struct image_params *iparams);
 static register_t *linux_copyout_strings(struct image_params *imgp);
 static void	linux_prepsyscall(struct trapframe *tf, int *args, u_int *code,
 		    caddr_t *params);
-static void     linux_sendsig(sig_t catcher, int sig, sigset_t *mask,
-		    u_long code);
+static void     linux_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask);
 static void	exec_linux_setregs(struct thread *td, u_long entry,
 				   u_long stack, u_long ps_strings);
-static void	linux32_fixlimits(struct image_params *imgp);
+static void	linux32_fixlimit(struct rlimit *rl, int which);
+
+extern LIST_HEAD(futex_list, futex) futex_list;
+extern struct sx futex_sx;
+
+static eventhandler_tag linux_exit_tag;
+static eventhandler_tag linux_schedtail_tag;
+static eventhandler_tag linux_exec_tag;
 
 /*
  * Linux syscalls return negative errno's, we do positive and map them
+ * Reference:
+ *   FreeBSD: src/sys/sys/errno.h
+ *   Linux:   linux-2.6.17.8/include/asm-generic/errno-base.h
+ *            linux-2.6.17.8/include/asm-generic/errno.h
  */
 static int bsd_to_linux_errno[ELAST + 1] = {
 	-0,  -1,  -2,  -3,  -4,  -5,  -6,  -7,  -8,  -9,
@@ -141,7 +146,8 @@
 	-100,-101,-102,-103,-104,-105,-106,-107,-108,-109,
 	-110,-111, -40, -36,-112,-113, -39, -11, -87,-122,
 	-116, -66,  -6,  -6,  -6,  -6,  -6, -37, -38,  -9,
-	-6, -6, -43, -42, -75, -6, -84
+	  -6,  -6, -43, -42, -75,-125, -84, -95, -16, -74,
+	 -72, -67, -71
 };
 
 int bsd_to_linux_signal[LINUX_SIGTBLSZ] = {
@@ -278,7 +284,7 @@
 extern unsigned long linux_sznonrtsigcode;
 
 static void
-linux_rt_sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
+linux_rt_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask)
 {
 	struct thread *td = curthread;
 	struct proc *p = td->td_proc;
@@ -286,7 +292,11 @@
 	struct trapframe *regs;
 	struct l_rt_sigframe *fp, frame;
 	int oonstack;
-
+	int sig;
+	int code;
+	
+	sig = ksi->ksi_signo;
+	code = ksi->ksi_code;
 	PROC_LOCK_ASSERT(p, MA_OWNED);
 	psp = p->p_sigacts;
 	mtx_assert(&psp->ps_mtx, MA_OWNED);
@@ -295,7 +305,7 @@
 
 #ifdef DEBUG
 	if (ldebug(rt_sendsig))
-		printf(ARGS(rt_sendsig, "%p, %d, %p, %lu"),
+		printf(ARGS(rt_sendsig, "%p, %d, %p, %u"),
 		    catcher, sig, (void*)mask, code);
 #endif
 	/*
@@ -326,7 +336,7 @@
 	/* Fill in POSIX parts */
 	frame.sf_si.lsi_signo = sig;
 	frame.sf_si.lsi_code = code;
-	frame.sf_si.lsi_addr = PTROUT(regs->tf_err);
+	frame.sf_si.lsi_addr = PTROUT(ksi->ksi_addr);
 
 	/*
 	 * Build the signal context to be used by sigreturn.
@@ -362,6 +372,7 @@
 	frame.sf_sc.uc_mcontext.sc_esp_at_signal = regs->tf_rsp;
 	frame.sf_sc.uc_mcontext.sc_ss     = regs->tf_ss;
 	frame.sf_sc.uc_mcontext.sc_err    = regs->tf_err;
+	frame.sf_sc.uc_mcontext.sc_cr2    = (u_int32_t)(uintptr_t)ksi->ksi_addr;
 	frame.sf_sc.uc_mcontext.sc_trapno = bsd_to_linux_trapcode(code);
 
 #ifdef DEBUG
@@ -398,6 +409,7 @@
 	td->td_pcb->pcb_ds = _udatasel;
 	load_es(_udatasel);
 	td->td_pcb->pcb_es = _udatasel;
+	/* leave user %fs and %gs untouched */
 	PROC_LOCK(p);
 	mtx_lock(&psp->ps_mtx);
 }
@@ -414,7 +426,7 @@
  * specified pc, psl.
  */
 static void
-linux_sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
+linux_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask)
 {
 	struct thread *td = curthread;
 	struct proc *p = td->td_proc;
@@ -423,13 +435,16 @@
 	struct l_sigframe *fp, frame;
 	l_sigset_t lmask;
 	int oonstack, i;
+	int sig, code;
 
+	sig = ksi->ksi_signo;
+	code = ksi->ksi_code;
 	PROC_LOCK_ASSERT(p, MA_OWNED);
 	psp = p->p_sigacts;
 	mtx_assert(&psp->ps_mtx, MA_OWNED);
 	if (SIGISMEMBER(psp->ps_siginfo, sig)) {
 		/* Signal handler installed with SA_SIGINFO. */
-		linux_rt_sendsig(catcher, sig, mask, code);
+		linux_rt_sendsig(catcher, ksi, mask);
 		return;
 	}
 
@@ -438,7 +453,7 @@
 
 #ifdef DEBUG
 	if (ldebug(sendsig))
-		printf(ARGS(sendsig, "%p, %d, %p, %lu"),
+		printf(ARGS(sendsig, "%p, %d, %p, %u"),
 		    catcher, sig, (void*)mask, code);
 #endif
 
@@ -489,6 +504,7 @@
 	frame.sf_sc.sc_esp_at_signal = regs->tf_rsp;
 	frame.sf_sc.sc_ss     = regs->tf_ss;
 	frame.sf_sc.sc_err    = regs->tf_err;
+	frame.sf_sc.sc_cr2    = (u_int32_t)(uintptr_t)ksi->ksi_addr;
 	frame.sf_sc.sc_trapno = bsd_to_linux_trapcode(code);
 
 	for (i = 0; i < (LINUX_NSIG_WORDS-1); i++)
@@ -515,6 +531,7 @@
 	td->td_pcb->pcb_ds = _udatasel;
 	load_es(_udatasel);
 	td->td_pcb->pcb_es = _udatasel;
+	/* leave user %fs and %gs untouched */
 	PROC_LOCK(p);
 	mtx_lock(&psp->ps_mtx);
 }
@@ -537,6 +554,7 @@
 	struct trapframe *regs;
 	l_sigset_t lmask;
 	int eflags, i;
+	ksiginfo_t ksi;
 
 	regs = td->td_frame;
 
@@ -577,7 +595,12 @@
 	 */
 #define	CS_SECURE(cs)	(ISPL(cs) == SEL_UPL)
 	if (!CS_SECURE(frame.sf_sc.sc_cs)) {
-		trapsignal(td, SIGBUS, T_PROTFLT);
+		ksiginfo_init_trap(&ksi);
+		ksi.ksi_signo = SIGBUS;
+		ksi.ksi_code = BUS_OBJERR;
+		ksi.ksi_trapno = T_PROTFLT;
+		ksi.ksi_addr = (void *)regs->tf_rip;
+		trapsignal(td, &ksi);
 		return(EINVAL);
 	}
 
@@ -630,6 +653,7 @@
 	stack_t ss;
 	struct trapframe *regs;
 	int eflags;
+	ksiginfo_t ksi;
 
 	regs = td->td_frame;
 
@@ -672,7 +696,12 @@
 	 */
 #define	CS_SECURE(cs)	(ISPL(cs) == SEL_UPL)
 	if (!CS_SECURE(context->sc_cs)) {
-		trapsignal(td, SIGBUS, T_PROTFLT);
+		ksiginfo_init_trap(&ksi);
+		ksi.ksi_signo = SIGBUS;
+		ksi.ksi_code = BUS_OBJERR;
+		ksi.ksi_trapno = T_PROTFLT;
+		ksi.ksi_addr = (void *)regs->tf_rip;
+		trapsignal(td, &ksi);
 		return(EINVAL);
 	}
 
@@ -788,18 +817,20 @@
 	struct trapframe *regs = td->td_frame;
 	struct pcb *pcb = td->td_pcb;
 
+	critical_enter();
 	wrmsr(MSR_FSBASE, 0);
 	wrmsr(MSR_KGSBASE, 0);	/* User value while we're in the kernel */
 	pcb->pcb_fsbase = 0;
 	pcb->pcb_gsbase = 0;
+	critical_exit();
 	load_ds(_udatasel);
 	load_es(_udatasel);
 	load_fs(_udatasel);
-	load_gs(0);
+	load_gs(_udatasel);
 	pcb->pcb_ds = _udatasel;
 	pcb->pcb_es = _udatasel;
 	pcb->pcb_fs = _udatasel;
-	pcb->pcb_gs = 0;
+	pcb->pcb_gs = _udatasel;
 
 	bzero((char *)regs, sizeof(struct trapframe));
 	regs->tf_rip = entry;
@@ -843,7 +874,7 @@
 	 */
 	if (sigcodesz)
 		copyout(imgp->proc->p_sysent->sv_sigcode,
-			((caddr_t)arginfo - sigcodesz), szsigcode);
+			((caddr_t)arginfo - sigcodesz), sigcodesz);
 
 	/*
 	 * If we have a valid auxargs ptr, prepare some room
@@ -936,49 +967,42 @@
 SYSCTL_ULONG(_compat_linux32, OID_AUTO, maxvmem, CTLFLAG_RW,
     &linux32_maxvmem, 0, "");
 
-/*
- * XXX copied from ia32_sysvec.c.
- */
 static void
-linux32_fixlimits(struct image_params *imgp)
+linux32_fixlimit(struct rlimit *rl, int which)
 {
-	struct proc *p = imgp->proc;
-	struct plimit *oldlim, *newlim;
 
-	if (linux32_maxdsiz == 0 && linux32_maxssiz == 0 &&
-	    linux32_maxvmem == 0)
-		return;
-	newlim = lim_alloc();
-	PROC_LOCK(p);
-	oldlim = p->p_limit;
-	lim_copy(newlim, oldlim);
-	if (linux32_maxdsiz != 0) {
-		if (newlim->pl_rlimit[RLIMIT_DATA].rlim_cur > linux32_maxdsiz)
-		    newlim->pl_rlimit[RLIMIT_DATA].rlim_cur = linux32_maxdsiz;
-		if (newlim->pl_rlimit[RLIMIT_DATA].rlim_max > linux32_maxdsiz)
-		    newlim->pl_rlimit[RLIMIT_DATA].rlim_max = linux32_maxdsiz;
-	}
-	if (linux32_maxssiz != 0) {
-		if (newlim->pl_rlimit[RLIMIT_STACK].rlim_cur > linux32_maxssiz)
-		    newlim->pl_rlimit[RLIMIT_STACK].rlim_cur = linux32_maxssiz;
-		if (newlim->pl_rlimit[RLIMIT_STACK].rlim_max > linux32_maxssiz)
-		    newlim->pl_rlimit[RLIMIT_STACK].rlim_max = linux32_maxssiz;
-	}
-	if (linux32_maxvmem != 0) {
-		if (newlim->pl_rlimit[RLIMIT_VMEM].rlim_cur > linux32_maxvmem)
-		    newlim->pl_rlimit[RLIMIT_VMEM].rlim_cur = linux32_maxvmem;
-		if (newlim->pl_rlimit[RLIMIT_VMEM].rlim_max > linux32_maxvmem)
-		    newlim->pl_rlimit[RLIMIT_VMEM].rlim_max = linux32_maxvmem;
+	switch (which) {
+	case RLIMIT_DATA:
+		if (linux32_maxdsiz != 0) {			
+			if (rl->rlim_cur > linux32_maxdsiz)
+				rl->rlim_cur = linux32_maxdsiz;
+			if (rl->rlim_max > linux32_maxdsiz)
+				rl->rlim_max = linux32_maxdsiz;
+		}
+		break;
+	case RLIMIT_STACK:
+		if (linux32_maxssiz != 0) {
+			if (rl->rlim_cur > linux32_maxssiz)
+				rl->rlim_cur = linux32_maxssiz;
+			if (rl->rlim_max > linux32_maxssiz)
+				rl->rlim_max = linux32_maxssiz;
+		}
+		break;
+	case RLIMIT_VMEM:
+		if (linux32_maxvmem != 0) {
+			if (rl->rlim_cur > linux32_maxvmem)
+				rl->rlim_cur = linux32_maxvmem;
+			if (rl->rlim_max > linux32_maxvmem)
+				rl->rlim_max = linux32_maxvmem;
+		}
+		break;
 	}
-	p->p_limit = newlim;
-	PROC_UNLOCK(p);
-	lim_free(oldlim);
 }
 
 struct sysentvec elf_linux_sysvec = {
 	LINUX_SYS_MAXSYSCALL,
 	linux_sysent,
-	0xff,
+	0,
 	LINUX_SIGTBLSZ,
 	bsd_to_linux_signal,
 	ELAST + 1,
@@ -1001,7 +1025,8 @@
 	VM_PROT_ALL,
 	linux_copyout_strings,
 	exec_linux_setregs,
-	linux32_fixlimits
+	linux32_fixlimit,
+	&linux32_maxssiz,
 };
 
 static Elf32_Brandinfo linux_brand = {
@@ -1012,6 +1037,7 @@
 					"/lib/ld-linux.so.1",
 					&elf_linux_sysvec,
 					NULL,
+					BI_CAN_EXEC_DYN,
 				 };
 
 static Elf32_Brandinfo linux_glibc2brand = {
@@ -1022,6 +1048,7 @@
 					"/lib/ld-linux.so.2",
 					&elf_linux_sysvec,
 					NULL,
+					BI_CAN_EXEC_DYN,
 				 };
 
 Elf32_Brandinfo *linux_brandlist[] = {
@@ -1036,6 +1063,7 @@
 	Elf32_Brandinfo **brandinfo;
 	int error;
 	struct linux_ioctl_handler **lihp;
+	struct linux_device_handler **ldhp;
 
 	error = 0;
 
@@ -1048,6 +1076,18 @@
 		if (error == 0) {
 			SET_FOREACH(lihp, linux_ioctl_handler_set)
 				linux_ioctl_register_handler(*lihp);
+			SET_FOREACH(ldhp, linux_device_handler_set)
+				linux_device_register_handler(*ldhp);
+			mtx_init(&emul_lock, "emuldata lock", NULL, MTX_DEF);
+			sx_init(&emul_shared_lock, "emuldata->shared lock");
+			LIST_INIT(&futex_list);
+			sx_init(&futex_sx, "futex protection lock");
+			linux_exit_tag = EVENTHANDLER_REGISTER(process_exit, linux_proc_exit,
+			      NULL, 1000);
+			linux_schedtail_tag = EVENTHANDLER_REGISTER(schedtail, linux_schedtail,
+			      NULL, 1000);
+			linux_exec_tag = EVENTHANDLER_REGISTER(process_exec, linux_proc_exec,
+			      NULL, 1000);
 			if (bootverbose)
 				printf("Linux ELF exec handler installed\n");
 		} else
@@ -1067,13 +1107,21 @@
 		if (error == 0) {
 			SET_FOREACH(lihp, linux_ioctl_handler_set)
 				linux_ioctl_unregister_handler(*lihp);
+			SET_FOREACH(ldhp, linux_device_handler_set)
+				linux_device_unregister_handler(*ldhp);
+			mtx_destroy(&emul_lock);
+			sx_destroy(&emul_shared_lock);
+			sx_destroy(&futex_sx);
+			EVENTHANDLER_DEREGISTER(process_exit, linux_exit_tag);
+			EVENTHANDLER_DEREGISTER(schedtail, linux_schedtail_tag);
+			EVENTHANDLER_DEREGISTER(process_exec, linux_exec_tag);
 			if (bootverbose)
 				printf("Linux ELF exec handler removed\n");
 		} else
 			printf("Could not deinstall ELF interpreter entry\n");
 		break;
 	default:
-		break;
+		return EOPNOTSUPP;
 	}
 	return error;
 }
Index: linux.h
===================================================================
RCS file: /home/cvs/src/sys/amd64/linux32/linux.h,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L sys/amd64/linux32/linux.h -L sys/amd64/linux32/linux.h -u -r1.1.1.1 -r1.2
--- sys/amd64/linux32/linux.h
+++ sys/amd64/linux32/linux.h
@@ -8,7 +8,7 @@
  * 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 
+ *    notice, this list of conditions and the following disclaimer
  *    in this position and unchanged.
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
@@ -27,13 +27,11 @@
  * (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: src/sys/amd64/linux32/linux.h,v 1.1 2004/08/16 07:55:06 tjr Exp $
+ * $FreeBSD: src/sys/amd64/linux32/linux.h,v 1.16 2007/09/18 19:50:32 dwmalone Exp $
  */
 
-#ifndef _AMD64_LINUX_LINUX_H_
-#define	_AMD64_LINUX_LINUX_H_
-
-#include <sys/signal.h> /* for sigval union */
+#ifndef _AMD64_LINUX_H_
+#define	_AMD64_LINUX_H_
 
 #include <amd64/linux32/linux32_syscall.h>
 
@@ -41,20 +39,20 @@
  * debugging support
  */
 extern u_char linux_debug_map[];
-#define ldebug(name)	isclr(linux_debug_map, LINUX_SYS_linux_ ## name)
-#define ARGS(nm, fmt)	"linux(%ld): "#nm"("fmt")\n", (long)td->td_proc->p_pid
-#define LMSG(fmt)	"linux(%ld): "fmt"\n", (long)td->td_proc->p_pid
+#define	ldebug(name)	isclr(linux_debug_map, LINUX_SYS_linux_ ## name)
+#define	ARGS(nm, fmt)	"linux(%ld): "#nm"("fmt")\n", (long)td->td_proc->p_pid
+#define	LMSG(fmt)	"linux(%ld): "fmt"\n", (long)td->td_proc->p_pid
 
 #ifdef MALLOC_DECLARE
 MALLOC_DECLARE(M_LINUX);
 #endif
 
-#define LINUX32_USRSTACK	((1ul << 32) - PAGE_SIZE)
+#define	LINUX32_USRSTACK	((1ul << 32) - PAGE_SIZE)
 /* XXX 16 = sizeof(linux32_ps_strings) */
-#define LINUX32_PS_STRINGS	(LINUX32_USRSTACK - 16)
-#define LINUX32_MAXDSIZ		(512*1024*1024)	 	/* 512MB */
-#define LINUX32_MAXSSIZ		(64*1024*1024)		/* 64MB */
-#define LINUX32_MAXVMEM		0			/* Unlimited */
+#define	LINUX32_PS_STRINGS	(LINUX32_USRSTACK - 16)
+#define	LINUX32_MAXDSIZ		(512 * 1024 * 1024)	/* 512MB */
+#define	LINUX32_MAXSSIZ		(64 * 1024 * 1024)	/* 64MB */
+#define	LINUX32_MAXVMEM		0			/* Unlimited */
 
 #define	PTRIN(v)	(void *)(uintptr_t)(v)
 #define	PTROUT(v)	(l_uintptr_t)(uintptr_t)(v)
@@ -134,7 +132,7 @@
 #define	LINUX_RLIMIT_NPROC	6
 #define	LINUX_RLIMIT_NOFILE	7
 #define	LINUX_RLIMIT_MEMLOCK	8
-#define	LINUX_RLIMIT_AS		9       /* address space limit */
+#define	LINUX_RLIMIT_AS		9	/* Address space limit */
 
 #define	LINUX_RLIM_NLIMITS	10
 
@@ -169,12 +167,21 @@
 #define	LINUX_MAP_ANON		0x0020
 #define	LINUX_MAP_GROWSDOWN	0x0100
 
+struct l_mmap_argv {
+	l_uintptr_t	addr;
+	l_size_t	len;
+	l_int		prot;
+	l_int		flags;
+	l_int		fd;
+	l_off_t		pgoff;
+} __packed;
+
 /*
  * stat family of syscalls
  */
 struct l_timespec {
-	l_ulong		tv_sec;
-	l_ulong		tv_nsec;
+	l_time_t	tv_sec;
+	l_long		tv_nsec;
 } __packed;
 
 struct l_newstat {
@@ -197,6 +204,24 @@
 	l_ulong		__unused5;
 } __packed;
 
+struct l_stat {
+	l_ushort	st_dev;
+	l_ulong		st_ino;
+	l_ushort	st_mode;
+	l_ushort	st_nlink;
+	l_ushort	st_uid;
+	l_ushort	st_gid;
+	l_ushort	st_rdev;
+	l_long		st_size;
+	struct l_timespec	st_atimespec;
+	struct l_timespec	st_mtimespec;
+	struct l_timespec	st_ctimespec;
+	l_long		st_blksize;
+	l_long		st_blocks;
+	l_ulong		st_flags;
+	l_ulong		st_gen;
+};
+
 struct l_stat64 {
 	l_ushort	st_dev;
 	u_char		__pad0[10];
@@ -217,6 +242,19 @@
 	l_ulonglong	st_ino;
 } __packed;
 
+struct l_statfs64 { 
+        l_int           f_type; 
+        l_int           f_bsize; 
+        uint64_t        f_blocks; 
+        uint64_t        f_bfree; 
+        uint64_t        f_bavail; 
+        uint64_t        f_files; 
+        uint64_t        f_ffree; 
+        l_fsid_t        f_fsid;
+        l_int           f_namelen;
+        l_int           f_spare[6];
+} __packed;
+
 struct l_new_utsname {
 	char	sysname[LINUX_MAX_UTSNAME];
 	char	nodename[LINUX_MAX_UTSNAME];
@@ -290,9 +328,9 @@
 #define	LINUX_SIGADDSET(set, sig)	SIGADDSET(set, sig)
 
 /* sigaltstack */
-#define LINUX_MINSIGSTKSZ	2048
-#define LINUX_SS_ONSTACK	1
-#define LINUX_SS_DISABLE	2
+#define	LINUX_MINSIGSTKSZ	2048
+#define	LINUX_SS_ONSTACK	1
+#define	LINUX_SS_DISABLE	2
 
 int linux_to_bsd_sigaltstack(int lsa);
 int bsd_to_linux_sigaltstack(int bsa);
@@ -355,11 +393,16 @@
 	l_uintptr_t	uc_link;
 	l_stack_t	uc_stack;
 	struct l_sigcontext	uc_mcontext;
-        l_sigset_t	uc_sigmask;
+	l_sigset_t	uc_sigmask;
 } __packed;
 
-#define LINUX_SI_MAX_SIZE     128
-#define LINUX_SI_PAD_SIZE     ((LINUX_SI_MAX_SIZE/sizeof(l_int)) - 3)
+#define	LINUX_SI_MAX_SIZE	128
+#define	LINUX_SI_PAD_SIZE	((LINUX_SI_MAX_SIZE/sizeof(l_int)) - 3)
+
+union l_sigval {
+	l_int		sival_int;
+	l_uintptr_t	sival_ptr;
+};
 
 typedef struct l_siginfo {
 	l_int		lsi_signo;
@@ -381,7 +424,7 @@
 		struct {
 			l_pid_t		_pid;		/* sender's pid */
 			l_uid16_t	_uid;		/* sender's uid */
-			union sigval _sigval;
+			union l_sigval _sigval;
 		} __packed _rt;
 
 		struct {
@@ -393,41 +436,41 @@
 		} __packed _sigchld;
 
 		struct {
-			l_uintptr_t	_addr; /* faulting insn/memory ref. */
+			l_uintptr_t	_addr;	/* Faulting insn/memory ref. */
 		} __packed _sigfault;
 
 		struct {
-			l_int		_band;  /* POLL_IN,POLL_OUT,POLL_MSG */
+			l_int		_band;	/* POLL_IN,POLL_OUT,POLL_MSG */
 			l_int		_fd;
 		} __packed _sigpoll;
 	} _sifields;
 } __packed l_siginfo_t;
 
-#define lsi_pid          _sifields._kill._pid
-#define lsi_uid          _sifields._kill._uid
-#define lsi_status       _sifields._sigchld._status
-#define lsi_utime        _sifields._sigchld._utime
-#define lsi_stime        _sifields._sigchld._stime
-#define lsi_value        _sifields._rt._sigval
-#define lsi_int          _sifields._rt._sigval.sival_int
-#define lsi_ptr          _sifields._rt._sigval.sival_ptr
-#define lsi_addr         _sifields._sigfault._addr
-#define lsi_band         _sifields._sigpoll._band
-#define lsi_fd           _sifields._sigpoll._fd
+#define	lsi_pid		_sifields._kill._pid
+#define	lsi_uid		_sifields._kill._uid
+#define	lsi_status	_sifields._sigchld._status
+#define	lsi_utime	_sifields._sigchld._utime
+#define	lsi_stime	_sifields._sigchld._stime
+#define	lsi_value	_sifields._rt._sigval
+#define	lsi_int		_sifields._rt._sigval.sival_int
+#define	lsi_ptr		_sifields._rt._sigval.sival_ptr
+#define	lsi_addr	_sifields._sigfault._addr
+#define	lsi_band	_sifields._sigpoll._band
+#define	lsi_fd		_sifields._sigpoll._fd
 
 struct l_fpreg {
-	u_int16_t significand[4];
-	u_int16_t exponent;
+	u_int16_t	significand[4];
+	u_int16_t	exponent;
 } __packed;
 
 struct l_fpxreg {
-	u_int16_t significand[4];
-	u_int16_t exponent;
-	u_int16_t padding[3];
+	u_int16_t	significand[4];
+	u_int16_t	exponent;
+	u_int16_t	padding[3];
 } __packed;
 
 struct l_xmmreg {
-	u_int32_t element[4];
+	u_int32_t	element[4];
 } __packed;
 
 struct l_fpstate {
@@ -441,13 +484,13 @@
 	u_int32_t		datasel;
 	struct l_fpreg		_st[8];
 	u_int16_t		status;
-	u_int16_t		magic;  /* 0xffff = regular FPU data */
+	u_int16_t		magic;		/* 0xffff = regular FPU data */
 
 	/* FXSR FPU environment */
-	u_int32_t		_fxsr_env[6]; /* env is ignored */
+	u_int32_t		_fxsr_env[6];	/* env is ignored. */
 	u_int32_t		mxcsr;
 	u_int32_t		reserved;
-	struct l_fpxreg		_fxsr_st[8];  /* reg data is ignored */
+	struct l_fpxreg		_fxsr_st[8];	/* reg data is ignored. */
 	struct l_xmmreg		_xmm[8];
 	u_int32_t		padding[56];
 } __packed;
@@ -477,6 +520,7 @@
 
 extern int bsd_to_linux_signal[];
 extern int linux_to_bsd_signal[];
+extern struct sysentvec elf_linux_sysvec;
 
 /*
  * Pluggable ioctl handlers
@@ -497,18 +541,24 @@
 /*
  * open/fcntl flags
  */
-#define	LINUX_O_RDONLY		00
-#define	LINUX_O_WRONLY		01
-#define	LINUX_O_RDWR		02
-#define	LINUX_O_CREAT		0100
-#define	LINUX_O_EXCL		0200
-#define	LINUX_O_NOCTTY		0400
-#define	LINUX_O_TRUNC		01000
-#define	LINUX_O_APPEND		02000
-#define	LINUX_O_NONBLOCK	04000
+#define	LINUX_O_RDONLY		00000000
+#define	LINUX_O_WRONLY		00000001
+#define	LINUX_O_RDWR		00000002
+#define	LINUX_O_ACCMODE		00000003
+#define	LINUX_O_CREAT		00000100
+#define	LINUX_O_EXCL		00000200
+#define	LINUX_O_NOCTTY		00000400
+#define	LINUX_O_TRUNC		00001000
+#define	LINUX_O_APPEND		00002000
+#define	LINUX_O_NONBLOCK	00004000
 #define	LINUX_O_NDELAY		LINUX_O_NONBLOCK
-#define	LINUX_O_SYNC		010000
-#define	LINUX_FASYNC		020000
+#define	LINUX_O_SYNC		00010000
+#define	LINUX_FASYNC		00020000
+#define	LINUX_O_DIRECT		00040000	/* Direct disk access hint */
+#define	LINUX_O_LARGEFILE	00100000
+#define	LINUX_O_DIRECTORY	00200000	/* Must be a directory */
+#define	LINUX_O_NOFOLLOW	00400000	/* Do not follow links */
+#define	LINUX_O_NOATIME		01000000
 
 #define	LINUX_F_DUPFD		0
 #define	LINUX_F_GETFD		1
@@ -529,15 +579,17 @@
 #define	LINUX_F_WRLCK		1
 #define	LINUX_F_UNLCK		2
 
+#define	LINUX_AT_FDCWD		-100
+
 /*
  * mount flags
  */
-#define LINUX_MS_RDONLY         0x0001
-#define LINUX_MS_NOSUID         0x0002
-#define LINUX_MS_NODEV          0x0004
-#define LINUX_MS_NOEXEC         0x0008
-#define LINUX_MS_REMOUNT        0x0020
-        
+#define	LINUX_MS_RDONLY		0x0001
+#define	LINUX_MS_NOSUID		0x0002
+#define	LINUX_MS_NODEV		0x0004
+#define	LINUX_MS_NOEXEC		0x0008
+#define	LINUX_MS_REMOUNT	0x0020
+
 /*
  * SystemV IPC defines
  */
@@ -635,6 +687,13 @@
 #define	LINUX_SO_NO_CHECK	11
 #define	LINUX_SO_PRIORITY	12
 #define	LINUX_SO_LINGER		13
+#define	LINUX_SO_PEERCRED	17
+#define	LINUX_SO_RCVLOWAT	18
+#define	LINUX_SO_SNDLOWAT	19
+#define	LINUX_SO_RCVTIMEO	20
+#define	LINUX_SO_SNDTIMEO	21
+#define	LINUX_SO_TIMESTAMP	29
+#define	LINUX_SO_ACCEPTCONN	30
 
 #define	LINUX_IP_TOS		1
 #define	LINUX_IP_TTL		2
@@ -684,7 +743,7 @@
 	} ifr_ifru;
 } __packed;
 
-#define	ifr_name	ifr_ifrn.ifrn_name	/* interface name */
+#define	ifr_name	ifr_ifrn.ifrn_name	/* Interface name */
 #define	ifr_hwaddr	ifr_ifru.ifru_hwaddr	/* MAC address */
 
 struct l_ifconf {
@@ -719,4 +778,108 @@
 	l_short		revents;
 } __packed;
 
-#endif /* !_AMD64_LINUX_LINUX_H_ */
+struct l_user_desc {
+	l_uint		entry_number;
+	l_uint		base_addr;
+	l_uint		limit;
+	l_uint		seg_32bit:1;
+	l_uint		contents:2;
+	l_uint		read_exec_only:1;
+	l_uint		limit_in_pages:1;
+	l_uint		seg_not_present:1;
+	l_uint		useable:1;
+};
+
+#define	LINUX_LOWERWORD	0x0000ffff
+
+/*
+ * Macros which does the same thing as those in Linux include/asm-um/ldt-i386.h.
+ * These convert Linux user space descriptor to machine one.
+ */
+#define	LINUX_LDT_entry_a(info)					\
+	((((info)->base_addr & LINUX_LOWERWORD) << 16) |	\
+	((info)->limit & LINUX_LOWERWORD))
+
+#define	LINUX_ENTRY_B_READ_EXEC_ONLY	9
+#define	LINUX_ENTRY_B_CONTENTS		10
+#define	LINUX_ENTRY_B_SEG_NOT_PRESENT	15
+#define	LINUX_ENTRY_B_BASE_ADDR		16
+#define	LINUX_ENTRY_B_USEABLE		20
+#define	LINUX_ENTRY_B_SEG32BIT		22
+#define	LINUX_ENTRY_B_LIMIT		23
+
+#define	LINUX_LDT_entry_b(info)							\
+	(((info)->base_addr & 0xff000000) |					\
+	((info)->limit & 0xf0000) |						\
+	((info)->contents << LINUX_ENTRY_B_CONTENTS) |				\
+	(((info)->seg_not_present == 0) << LINUX_ENTRY_B_SEG_NOT_PRESENT) |	\
+	(((info)->base_addr & 0x00ff0000) >> LINUX_ENTRY_B_BASE_ADDR) |		\
+	(((info)->read_exec_only == 0) << LINUX_ENTRY_B_READ_EXEC_ONLY) |	\
+	((info)->seg_32bit << LINUX_ENTRY_B_SEG32BIT) |				\
+	((info)->useable << LINUX_ENTRY_B_USEABLE) |				\
+	((info)->limit_in_pages << LINUX_ENTRY_B_LIMIT) | 0x7000)
+
+#define	LINUX_LDT_empty(info)		\
+	((info)->base_addr == 0 &&	\
+	(info)->limit == 0 &&		\
+	(info)->contents == 0 &&	\
+	(info)->seg_not_present == 1 &&	\
+	(info)->read_exec_only == 1 &&	\
+	(info)->seg_32bit == 0 &&	\
+	(info)->limit_in_pages == 0 &&	\
+	(info)->useable == 0)
+
+/*
+ * Macros for converting segments.
+ * They do the same as those in arch/i386/kernel/process.c in Linux.
+ */
+#define	LINUX_GET_BASE(desc)				\
+	((((desc)->a >> 16) & LINUX_LOWERWORD) |	\
+	(((desc)->b << 16) & 0x00ff0000) |		\
+	((desc)->b & 0xff000000))
+
+#define	LINUX_GET_LIMIT(desc)			\
+	(((desc)->a & LINUX_LOWERWORD) |	\
+	((desc)->b & 0xf0000))
+
+#define	LINUX_GET_32BIT(desc)		\
+	(((desc)->b >> LINUX_ENTRY_B_SEG32BIT) & 1)
+#define	LINUX_GET_CONTENTS(desc)	\
+	(((desc)->b >> LINUX_ENTRY_B_CONTENTS) & 3)
+#define	LINUX_GET_WRITABLE(desc)	\
+	(((desc)->b >> LINUX_ENTRY_B_READ_EXEC_ONLY) & 1)
+#define	LINUX_GET_LIMIT_PAGES(desc)	\
+	(((desc)->b >> LINUX_ENTRY_B_LIMIT) & 1)
+#define	LINUX_GET_PRESENT(desc)		\
+	(((desc)->b >> LINUX_ENTRY_B_SEG_NOT_PRESENT) & 1)
+#define	LINUX_GET_USEABLE(desc)		\
+	(((desc)->b >> LINUX_ENTRY_B_USEABLE) & 1)
+
+#define	LINUX_CLOCK_REALTIME		0
+#define	LINUX_CLOCK_MONOTONIC		1
+#define	LINUX_CLOCK_PROCESS_CPUTIME_ID	2
+#define	LINUX_CLOCK_THREAD_CPUTIME_ID	3
+#define	LINUX_CLOCK_REALTIME_HR		4
+#define	LINUX_CLOCK_MONOTONIC_HR	5
+
+typedef int l_timer_t;
+typedef int l_mqd_t;
+
+#define	LINUX_CLONE_VM			0x00000100
+#define	LINUX_CLONE_FS			0x00000200
+#define	LINUX_CLONE_FILES		0x00000400
+#define	LINUX_CLONE_SIGHAND		0x00000800
+#define	LINUX_CLONE_PID			0x00001000	/* No longer exist in Linux */
+#define	LINUX_CLONE_VFORK		0x00004000
+#define	LINUX_CLONE_PARENT		0x00008000
+#define	LINUX_CLONE_THREAD		0x00010000
+#define	LINUX_CLONE_SETTLS		0x00080000
+#define	LINUX_CLONE_PARENT_SETTID	0x00100000
+#define	LINUX_CLONE_CHILD_CLEARTID	0x00200000
+#define	LINUX_CLONE_CHILD_SETTID	0x01000000
+
+#define	LINUX_THREADING_FLAGS					\
+	(LINUX_CLONE_VM | LINUX_CLONE_FS | LINUX_CLONE_FILES |	\
+	LINUX_CLONE_SIGHAND | LINUX_CLONE_THREAD)
+
+#endif /* !_AMD64_LINUX_H_ */
Index: linux32_proto.h
===================================================================
RCS file: /home/cvs/src/sys/amd64/linux32/linux32_proto.h,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L sys/amd64/linux32/linux32_proto.h -L sys/amd64/linux32/linux32_proto.h -u -r1.1.1.1 -r1.2
--- sys/amd64/linux32/linux32_proto.h
+++ sys/amd64/linux32/linux32_proto.h
@@ -2,8 +2,8 @@
  * System call prototypes.
  *
  * DO NOT EDIT-- this file is automatically generated.
- * $FreeBSD: src/sys/amd64/linux32/linux32_proto.h,v 1.5.2.1 2005/07/20 17:43:52 jhb Exp $
- * created from FreeBSD: src/sys/amd64/linux32/syscalls.master,v 1.4.2.1 2005/07/20 17:42:14 jhb Exp 
+ * $FreeBSD: src/sys/amd64/linux32/linux32_proto.h,v 1.33 2007/09/18 19:50:32 dwmalone Exp $
+ * created from FreeBSD: src/sys/amd64/linux32/syscalls.master,v 1.29 2007/08/28 12:26:34 kib Exp 
  */
 
 #ifndef _LINUX_SYSPROTO_H_
@@ -11,12 +11,11 @@
 
 #include <sys/signal.h>
 #include <sys/acl.h>
-#include <sys/thr.h>
-#include <sys/umtx.h>
-#include <posix4/_semaphore.h>
-
+#include <sys/_semaphore.h>
 #include <sys/ucontext.h>
 
+#include <bsm/audit_kevents.h>
+
 struct proc;
 
 struct thread;
@@ -82,6 +81,10 @@
 	char uid_l_[PADL_(l_uid16_t)]; l_uid16_t uid; char uid_r_[PADR_(l_uid16_t)];
 	char gid_l_[PADL_(l_gid16_t)]; l_gid16_t gid; char gid_r_[PADR_(l_gid16_t)];
 };
+struct linux_stat_args {
+	char path_l_[PADL_(char *)]; char * path; char path_r_[PADR_(char *)];
+	char up_l_[PADL_(struct linux_stat *)]; struct linux_stat * up; char up_r_[PADR_(struct linux_stat *)];
+};
 struct linux_lseek_args {
 	char fdes_l_[PADL_(l_uint)]; l_uint fdes; char fdes_r_[PADR_(l_uint)];
 	char off_l_[PADL_(l_off_t)]; l_off_t off; char off_r_[PADR_(l_off_t)];
@@ -193,6 +196,9 @@
 	char dev_l_[PADL_(l_dev_t)]; l_dev_t dev; char dev_r_[PADR_(l_dev_t)];
 	char ubuf_l_[PADL_(struct l_ustat *)]; struct l_ustat * ubuf; char ubuf_r_[PADR_(struct l_ustat *)];
 };
+struct linux_getppid_args {
+	register_t dummy;
+};
 struct linux_sigaction_args {
 	char sig_l_[PADL_(l_int)]; l_int sig; char sig_r_[PADR_(l_int)];
 	char nsa_l_[PADL_(l_osigaction_t *)]; l_osigaction_t * nsa; char nsa_r_[PADR_(l_osigaction_t *)];
@@ -220,6 +226,10 @@
 struct linux_sigpending_args {
 	char mask_l_[PADL_(l_osigset_t *)]; l_osigset_t * mask; char mask_r_[PADR_(l_osigset_t *)];
 };
+struct linux_sethostname_args {
+	char hostname_l_[PADL_(char *)]; char * hostname; char hostname_r_[PADR_(char *)];
+	char len_l_[PADL_(u_int)]; u_int len; char len_r_[PADR_(u_int)];
+};
 struct linux_setrlimit_args {
 	char resource_l_[PADL_(l_uint)]; l_uint resource; char resource_r_[PADR_(l_uint)];
 	char rlim_l_[PADL_(struct l_rlimit *)]; struct l_rlimit * rlim; char rlim_r_[PADR_(struct l_rlimit *)];
@@ -255,6 +265,10 @@
 	char path_l_[PADL_(char *)]; char * path; char path_r_[PADR_(char *)];
 	char to_l_[PADL_(char *)]; char * to; char to_r_[PADR_(char *)];
 };
+struct linux_lstat_args {
+	char path_l_[PADL_(char *)]; char * path; char path_r_[PADR_(char *)];
+	char up_l_[PADL_(struct linux_lstat *)]; struct linux_lstat * up; char up_r_[PADR_(struct linux_lstat *)];
+};
 struct linux_readlink_args {
 	char name_l_[PADL_(char *)]; char * name; char name_r_[PADR_(char *)];
 	char buf_l_[PADL_(char *)]; char * buf; char buf_r_[PADR_(char *)];
@@ -278,6 +292,10 @@
 	char path_l_[PADL_(char *)]; char * path; char path_r_[PADR_(char *)];
 	char length_l_[PADL_(l_ulong)]; l_ulong length; char length_r_[PADR_(l_ulong)];
 };
+struct linux_ftruncate_args {
+	char fd_l_[PADL_(int)]; int fd; char fd_r_[PADR_(int)];
+	char length_l_[PADL_(long)]; long length; char length_r_[PADR_(long)];
+};
 struct linux_getpriority_args {
 	char which_l_[PADL_(int)]; int which; char which_r_[PADR_(int)];
 	char who_l_[PADL_(int)]; int who; char who_r_[PADR_(int)];
@@ -323,6 +341,9 @@
 struct linux_uname_args {
 	register_t dummy;
 };
+struct linux_iopl_args {
+	char level_l_[PADL_(l_ulong)]; l_ulong level; char level_r_[PADR_(l_ulong)];
+};
 struct linux_vhangup_args {
 	register_t dummy;
 };
@@ -352,6 +373,9 @@
 struct linux_clone_args {
 	char flags_l_[PADL_(l_int)]; l_int flags; char flags_r_[PADR_(l_int)];
 	char stack_l_[PADL_(void *)]; void * stack; char stack_r_[PADR_(void *)];
+	char parent_tidptr_l_[PADL_(void *)]; void * parent_tidptr; char parent_tidptr_r_[PADR_(void *)];
+	char dummy_l_[PADL_(int)]; int dummy; char dummy_r_[PADR_(int)];
+	char child_tidptr_l_[PADL_(void *)]; void * child_tidptr; char child_tidptr_r_[PADR_(void *)];
 };
 struct linux_newuname_args {
 	char buf_l_[PADL_(struct l_new_utsname *)]; struct l_new_utsname * buf; char buf_r_[PADR_(struct l_new_utsname *)];
@@ -500,7 +524,11 @@
 	char sgid_l_[PADL_(l_gid16_t *)]; l_gid16_t * sgid; char sgid_r_[PADR_(l_gid16_t *)];
 };
 struct linux_prctl_args {
-	register_t dummy;
+	char option_l_[PADL_(l_int)]; l_int option; char option_r_[PADR_(l_int)];
+	char arg2_l_[PADL_(l_int)]; l_int arg2; char arg2_r_[PADR_(l_int)];
+	char arg3_l_[PADL_(l_int)]; l_int arg3; char arg3_r_[PADR_(l_int)];
+	char arg4_l_[PADL_(l_int)]; l_int arg4; char arg4_r_[PADR_(l_int)];
+	char arg5_l_[PADL_(l_int)]; l_int arg5; char arg5_r_[PADR_(l_int)];
 };
 struct linux_rt_sigreturn_args {
 	char ucp_l_[PADL_(struct l_ucontext *)]; struct l_ucontext * ucp; char ucp_r_[PADR_(struct l_ucontext *)];
@@ -518,10 +546,14 @@
 	char sigsetsize_l_[PADL_(l_size_t)]; l_size_t sigsetsize; char sigsetsize_r_[PADR_(l_size_t)];
 };
 struct linux_rt_sigpending_args {
-	register_t dummy;
+	char set_l_[PADL_(l_sigset_t *)]; l_sigset_t * set; char set_r_[PADR_(l_sigset_t *)];
+	char sigsetsize_l_[PADL_(l_size_t)]; l_size_t sigsetsize; char sigsetsize_r_[PADR_(l_size_t)];
 };
 struct linux_rt_sigtimedwait_args {
-	register_t dummy;
+	char mask_l_[PADL_(l_sigset_t *)]; l_sigset_t * mask; char mask_r_[PADR_(l_sigset_t *)];
+	char ptr_l_[PADL_(l_siginfo_t *)]; l_siginfo_t * ptr; char ptr_r_[PADR_(l_siginfo_t *)];
+	char timeout_l_[PADL_(struct l_timeval *)]; struct l_timeval * timeout; char timeout_r_[PADR_(struct l_timeval *)];
+	char sigsetsize_l_[PADL_(l_size_t)]; l_size_t sigsetsize; char sigsetsize_r_[PADR_(l_size_t)];
 };
 struct linux_rt_sigqueueinfo_args {
 	register_t dummy;
@@ -651,6 +683,9 @@
 	char cmd_l_[PADL_(l_uint)]; l_uint cmd; char cmd_r_[PADR_(l_uint)];
 	char arg_l_[PADL_(uintptr_t)]; uintptr_t arg; char arg_r_[PADR_(uintptr_t)];
 };
+struct linux_gettid_args {
+	register_t dummy;
+};
 struct linux_setxattr_args {
 	register_t dummy;
 };
@@ -687,9 +722,214 @@
 struct linux_fremovexattr_args {
 	register_t dummy;
 };
+struct linux_tkill_args {
+	char tid_l_[PADL_(int)]; int tid; char tid_r_[PADR_(int)];
+	char sig_l_[PADL_(int)]; int sig; char sig_r_[PADR_(int)];
+};
+struct linux_sys_futex_args {
+	char uaddr_l_[PADL_(void *)]; void * uaddr; char uaddr_r_[PADR_(void *)];
+	char op_l_[PADL_(int)]; int op; char op_r_[PADR_(int)];
+	char val_l_[PADL_(int)]; int val; char val_r_[PADR_(int)];
+	char timeout_l_[PADL_(struct l_timespec *)]; struct l_timespec * timeout; char timeout_r_[PADR_(struct l_timespec *)];
+	char uaddr2_l_[PADL_(void *)]; void * uaddr2; char uaddr2_r_[PADR_(void *)];
+	char val3_l_[PADL_(int)]; int val3; char val3_r_[PADR_(int)];
+};
+struct linux_sched_getaffinity_args {
+	char pid_l_[PADL_(l_pid_t)]; l_pid_t pid; char pid_r_[PADR_(l_pid_t)];
+	char len_l_[PADL_(l_uint)]; l_uint len; char len_r_[PADR_(l_uint)];
+	char user_mask_ptr_l_[PADL_(l_ulong *)]; l_ulong * user_mask_ptr; char user_mask_ptr_r_[PADR_(l_ulong *)];
+};
+struct linux_set_thread_area_args {
+	char desc_l_[PADL_(struct l_user_desc *)]; struct l_user_desc * desc; char desc_r_[PADR_(struct l_user_desc *)];
+};
 struct linux_fadvise64_args {
 	register_t dummy;
 };
+struct linux_exit_group_args {
+	char error_code_l_[PADL_(int)]; int error_code; char error_code_r_[PADR_(int)];
+};
+struct linux_lookup_dcookie_args {
+	register_t dummy;
+};
+struct linux_epoll_create_args {
+	register_t dummy;
+};
+struct linux_epoll_ctl_args {
+	register_t dummy;
+};
+struct linux_epoll_wait_args {
+	register_t dummy;
+};
+struct linux_remap_file_pages_args {
+	register_t dummy;
+};
+struct linux_set_tid_address_args {
+	char tidptr_l_[PADL_(int *)]; int * tidptr; char tidptr_r_[PADR_(int *)];
+};
+struct linux_timer_create_args {
+	register_t dummy;
+};
+struct linux_timer_settime_args {
+	register_t dummy;
+};
+struct linux_timer_gettime_args {
+	register_t dummy;
+};
+struct linux_timer_getoverrun_args {
+	register_t dummy;
+};
+struct linux_timer_delete_args {
+	register_t dummy;
+};
+struct linux_clock_settime_args {
+	char which_l_[PADL_(clockid_t)]; clockid_t which; char which_r_[PADR_(clockid_t)];
+	char tp_l_[PADL_(struct l_timespec *)]; struct l_timespec * tp; char tp_r_[PADR_(struct l_timespec *)];
+};
+struct linux_clock_gettime_args {
+	char which_l_[PADL_(clockid_t)]; clockid_t which; char which_r_[PADR_(clockid_t)];
+	char tp_l_[PADL_(struct l_timespec *)]; struct l_timespec * tp; char tp_r_[PADR_(struct l_timespec *)];
+};
+struct linux_clock_getres_args {
+	char which_l_[PADL_(clockid_t)]; clockid_t which; char which_r_[PADR_(clockid_t)];
+	char tp_l_[PADL_(struct l_timespec *)]; struct l_timespec * tp; char tp_r_[PADR_(struct l_timespec *)];
+};
+struct linux_clock_nanosleep_args {
+	char which_l_[PADL_(clockid_t)]; clockid_t which; char which_r_[PADR_(clockid_t)];
+	char flags_l_[PADL_(int)]; int flags; char flags_r_[PADR_(int)];
+	char rqtp_l_[PADL_(struct l_timespec *)]; struct l_timespec * rqtp; char rqtp_r_[PADR_(struct l_timespec *)];
+	char rmtp_l_[PADL_(struct l_timespec *)]; struct l_timespec * rmtp; char rmtp_r_[PADR_(struct l_timespec *)];
+};
+struct linux_statfs64_args {
+	char path_l_[PADL_(char *)]; char * path; char path_r_[PADR_(char *)];
+	char bufsize_l_[PADL_(size_t)]; size_t bufsize; char bufsize_r_[PADR_(size_t)];
+	char buf_l_[PADL_(struct l_statfs64_buf *)]; struct l_statfs64_buf * buf; char buf_r_[PADR_(struct l_statfs64_buf *)];
+};
+struct linux_fstatfs64_args {
+	register_t dummy;
+};
+struct linux_tgkill_args {
+	char tgid_l_[PADL_(int)]; int tgid; char tgid_r_[PADR_(int)];
+	char pid_l_[PADL_(int)]; int pid; char pid_r_[PADR_(int)];
+	char sig_l_[PADL_(int)]; int sig; char sig_r_[PADR_(int)];
+};
+struct linux_utimes_args {
+	char fname_l_[PADL_(char *)]; char * fname; char fname_r_[PADR_(char *)];
+	char tptr_l_[PADL_(struct l_timeval *)]; struct l_timeval * tptr; char tptr_r_[PADR_(struct l_timeval *)];
+};
+struct linux_fadvise64_64_args {
+	register_t dummy;
+};
+struct linux_mbind_args {
+	register_t dummy;
+};
+struct linux_get_mempolicy_args {
+	register_t dummy;
+};
+struct linux_set_mempolicy_args {
+	register_t dummy;
+};
+struct linux_mq_open_args {
+	register_t dummy;
+};
+struct linux_mq_unlink_args {
+	register_t dummy;
+};
+struct linux_mq_timedsend_args {
+	register_t dummy;
+};
+struct linux_mq_timedreceive_args {
+	register_t dummy;
+};
+struct linux_mq_notify_args {
+	register_t dummy;
+};
+struct linux_mq_getsetattr_args {
+	register_t dummy;
+};
+struct linux_kexec_load_args {
+	register_t dummy;
+};
+struct linux_waitid_args {
+	register_t dummy;
+};
+struct linux_add_key_args {
+	register_t dummy;
+};
+struct linux_request_key_args {
+	register_t dummy;
+};
+struct linux_keyctl_args {
+	register_t dummy;
+};
+struct linux_ioprio_set_args {
+	register_t dummy;
+};
+struct linux_ioprio_get_args {
+	register_t dummy;
+};
+struct linux_inotify_init_args {
+	register_t dummy;
+};
+struct linux_inotify_add_watch_args {
+	register_t dummy;
+};
+struct linux_inotify_rm_watch_args {
+	register_t dummy;
+};
+struct linux_migrate_pages_args {
+	register_t dummy;
+};
+struct linux_openat_args {
+	char dfd_l_[PADL_(l_int)]; l_int dfd; char dfd_r_[PADR_(l_int)];
+	char filename_l_[PADL_(char *)]; char * filename; char filename_r_[PADR_(char *)];
+	char flags_l_[PADL_(l_int)]; l_int flags; char flags_r_[PADR_(l_int)];
+	char mode_l_[PADL_(l_int)]; l_int mode; char mode_r_[PADR_(l_int)];
+};
+struct linux_mkdirat_args {
+	register_t dummy;
+};
+struct linux_mknodat_args {
+	register_t dummy;
+};
+struct linux_fchownat_args {
+	register_t dummy;
+};
+struct linux_futimesat_args {
+	register_t dummy;
+};
+struct linux_fstatat64_args {
+	register_t dummy;
+};
+struct linux_unlinkat_args {
+	register_t dummy;
+};
+struct linux_renameat_args {
+	register_t dummy;
+};
+struct linux_linkat_args {
+	register_t dummy;
+};
+struct linux_symlinkat_args {
+	register_t dummy;
+};
+struct linux_readlinkat_args {
+	register_t dummy;
+};
+struct linux_fchmodat_args {
+	register_t dummy;
+};
+struct linux_faccessat_args {
+	register_t dummy;
+};
+struct linux_pselect6_args {
+	register_t dummy;
+};
+struct linux_ppoll_args {
+	register_t dummy;
+};
+struct linux_unshare_args {
+	register_t dummy;
+};
 #define	nosys	linux_nosys
 int	linux_fork(struct thread *, struct linux_fork_args *);
 int	linux_open(struct thread *, struct linux_open_args *);
@@ -703,6 +943,7 @@
 int	linux_mknod(struct thread *, struct linux_mknod_args *);
 int	linux_chmod(struct thread *, struct linux_chmod_args *);
 int	linux_lchown16(struct thread *, struct linux_lchown16_args *);
+int	linux_stat(struct thread *, struct linux_stat_args *);
 int	linux_lseek(struct thread *, struct linux_lseek_args *);
 int	linux_getpid(struct thread *, struct linux_getpid_args *);
 int	linux_mount(struct thread *, struct linux_mount_args *);
@@ -733,6 +974,7 @@
 int	linux_fcntl(struct thread *, struct linux_fcntl_args *);
 int	linux_olduname(struct thread *, struct linux_olduname_args *);
 int	linux_ustat(struct thread *, struct linux_ustat_args *);
+int	linux_getppid(struct thread *, struct linux_getppid_args *);
 int	linux_sigaction(struct thread *, struct linux_sigaction_args *);
 int	linux_sgetmask(struct thread *, struct linux_sgetmask_args *);
 int	linux_ssetmask(struct thread *, struct linux_ssetmask_args *);
@@ -740,6 +982,7 @@
 int	linux_setregid16(struct thread *, struct linux_setregid16_args *);
 int	linux_sigsuspend(struct thread *, struct linux_sigsuspend_args *);
 int	linux_sigpending(struct thread *, struct linux_sigpending_args *);
+int	linux_sethostname(struct thread *, struct linux_sethostname_args *);
 int	linux_setrlimit(struct thread *, struct linux_setrlimit_args *);
 int	linux_old_getrlimit(struct thread *, struct linux_old_getrlimit_args *);
 int	linux_getrusage(struct thread *, struct linux_getrusage_args *);
@@ -749,11 +992,13 @@
 int	linux_setgroups16(struct thread *, struct linux_setgroups16_args *);
 int	linux_old_select(struct thread *, struct linux_old_select_args *);
 int	linux_symlink(struct thread *, struct linux_symlink_args *);
+int	linux_lstat(struct thread *, struct linux_lstat_args *);
 int	linux_readlink(struct thread *, struct linux_readlink_args *);
 int	linux_reboot(struct thread *, struct linux_reboot_args *);
 int	linux_readdir(struct thread *, struct linux_readdir_args *);
 int	linux_mmap(struct thread *, struct linux_mmap_args *);
 int	linux_truncate(struct thread *, struct linux_truncate_args *);
+int	linux_ftruncate(struct thread *, struct linux_ftruncate_args *);
 int	linux_getpriority(struct thread *, struct linux_getpriority_args *);
 int	linux_statfs(struct thread *, struct linux_statfs_args *);
 int	linux_fstatfs(struct thread *, struct linux_fstatfs_args *);
@@ -765,6 +1010,7 @@
 int	linux_newlstat(struct thread *, struct linux_newlstat_args *);
 int	linux_newfstat(struct thread *, struct linux_newfstat_args *);
 int	linux_uname(struct thread *, struct linux_uname_args *);
+int	linux_iopl(struct thread *, struct linux_iopl_args *);
 int	linux_vhangup(struct thread *, struct linux_vhangup_args *);
 int	linux_wait4(struct thread *, struct linux_wait4_args *);
 int	linux_swapoff(struct thread *, struct linux_swapoff_args *);
@@ -844,6 +1090,7 @@
 int	linux_mincore(struct thread *, struct linux_mincore_args *);
 int	linux_getdents64(struct thread *, struct linux_getdents64_args *);
 int	linux_fcntl64(struct thread *, struct linux_fcntl64_args *);
+int	linux_gettid(struct thread *, struct linux_gettid_args *);
 int	linux_setxattr(struct thread *, struct linux_setxattr_args *);
 int	linux_lsetxattr(struct thread *, struct linux_lsetxattr_args *);
 int	linux_fsetxattr(struct thread *, struct linux_fsetxattr_args *);
@@ -856,7 +1103,68 @@
 int	linux_removexattr(struct thread *, struct linux_removexattr_args *);
 int	linux_lremovexattr(struct thread *, struct linux_lremovexattr_args *);
 int	linux_fremovexattr(struct thread *, struct linux_fremovexattr_args *);
+int	linux_tkill(struct thread *, struct linux_tkill_args *);
+int	linux_sys_futex(struct thread *, struct linux_sys_futex_args *);
+int	linux_sched_getaffinity(struct thread *, struct linux_sched_getaffinity_args *);
+int	linux_set_thread_area(struct thread *, struct linux_set_thread_area_args *);
 int	linux_fadvise64(struct thread *, struct linux_fadvise64_args *);
+int	linux_exit_group(struct thread *, struct linux_exit_group_args *);
+int	linux_lookup_dcookie(struct thread *, struct linux_lookup_dcookie_args *);
+int	linux_epoll_create(struct thread *, struct linux_epoll_create_args *);
+int	linux_epoll_ctl(struct thread *, struct linux_epoll_ctl_args *);
+int	linux_epoll_wait(struct thread *, struct linux_epoll_wait_args *);
+int	linux_remap_file_pages(struct thread *, struct linux_remap_file_pages_args *);
+int	linux_set_tid_address(struct thread *, struct linux_set_tid_address_args *);
+int	linux_timer_create(struct thread *, struct linux_timer_create_args *);
+int	linux_timer_settime(struct thread *, struct linux_timer_settime_args *);
+int	linux_timer_gettime(struct thread *, struct linux_timer_gettime_args *);
+int	linux_timer_getoverrun(struct thread *, struct linux_timer_getoverrun_args *);
+int	linux_timer_delete(struct thread *, struct linux_timer_delete_args *);
+int	linux_clock_settime(struct thread *, struct linux_clock_settime_args *);
+int	linux_clock_gettime(struct thread *, struct linux_clock_gettime_args *);
+int	linux_clock_getres(struct thread *, struct linux_clock_getres_args *);
+int	linux_clock_nanosleep(struct thread *, struct linux_clock_nanosleep_args *);
+int	linux_statfs64(struct thread *, struct linux_statfs64_args *);
+int	linux_fstatfs64(struct thread *, struct linux_fstatfs64_args *);
+int	linux_tgkill(struct thread *, struct linux_tgkill_args *);
+int	linux_utimes(struct thread *, struct linux_utimes_args *);
+int	linux_fadvise64_64(struct thread *, struct linux_fadvise64_64_args *);
+int	linux_mbind(struct thread *, struct linux_mbind_args *);
+int	linux_get_mempolicy(struct thread *, struct linux_get_mempolicy_args *);
+int	linux_set_mempolicy(struct thread *, struct linux_set_mempolicy_args *);
+int	linux_mq_open(struct thread *, struct linux_mq_open_args *);
+int	linux_mq_unlink(struct thread *, struct linux_mq_unlink_args *);
+int	linux_mq_timedsend(struct thread *, struct linux_mq_timedsend_args *);
+int	linux_mq_timedreceive(struct thread *, struct linux_mq_timedreceive_args *);
+int	linux_mq_notify(struct thread *, struct linux_mq_notify_args *);
+int	linux_mq_getsetattr(struct thread *, struct linux_mq_getsetattr_args *);
+int	linux_kexec_load(struct thread *, struct linux_kexec_load_args *);
+int	linux_waitid(struct thread *, struct linux_waitid_args *);
+int	linux_add_key(struct thread *, struct linux_add_key_args *);
+int	linux_request_key(struct thread *, struct linux_request_key_args *);
+int	linux_keyctl(struct thread *, struct linux_keyctl_args *);
+int	linux_ioprio_set(struct thread *, struct linux_ioprio_set_args *);
+int	linux_ioprio_get(struct thread *, struct linux_ioprio_get_args *);
+int	linux_inotify_init(struct thread *, struct linux_inotify_init_args *);
+int	linux_inotify_add_watch(struct thread *, struct linux_inotify_add_watch_args *);
+int	linux_inotify_rm_watch(struct thread *, struct linux_inotify_rm_watch_args *);
+int	linux_migrate_pages(struct thread *, struct linux_migrate_pages_args *);
+int	linux_openat(struct thread *, struct linux_openat_args *);
+int	linux_mkdirat(struct thread *, struct linux_mkdirat_args *);
+int	linux_mknodat(struct thread *, struct linux_mknodat_args *);
+int	linux_fchownat(struct thread *, struct linux_fchownat_args *);
+int	linux_futimesat(struct thread *, struct linux_futimesat_args *);
+int	linux_fstatat64(struct thread *, struct linux_fstatat64_args *);
+int	linux_unlinkat(struct thread *, struct linux_unlinkat_args *);
+int	linux_renameat(struct thread *, struct linux_renameat_args *);
+int	linux_linkat(struct thread *, struct linux_linkat_args *);
+int	linux_symlinkat(struct thread *, struct linux_symlinkat_args *);
+int	linux_readlinkat(struct thread *, struct linux_readlinkat_args *);
+int	linux_fchmodat(struct thread *, struct linux_fchmodat_args *);
+int	linux_faccessat(struct thread *, struct linux_faccessat_args *);
+int	linux_pselect6(struct thread *, struct linux_pselect6_args *);
+int	linux_ppoll(struct thread *, struct linux_ppoll_args *);
+int	linux_unshare(struct thread *, struct linux_unshare_args *);
 
 #ifdef COMPAT_43
 
@@ -871,6 +1179,248 @@
 
 #endif /* COMPAT_FREEBSD4 */
 
+
+#ifdef COMPAT_FREEBSD6
+
+#define	nosys	linux_nosys
+
+#endif /* COMPAT_FREEBSD6 */
+
+#define	LINUX_SYS_AUE_linux_fork	AUE_FORK
+#define	LINUX_SYS_AUE_linux_open	AUE_OPEN_RWTC
+#define	LINUX_SYS_AUE_linux_waitpid	AUE_WAIT4
+#define	LINUX_SYS_AUE_linux_creat	AUE_CREAT
+#define	LINUX_SYS_AUE_linux_link	AUE_LINK
+#define	LINUX_SYS_AUE_linux_unlink	AUE_UNLINK
+#define	LINUX_SYS_AUE_linux_execve	AUE_EXECVE
+#define	LINUX_SYS_AUE_linux_chdir	AUE_CHDIR
+#define	LINUX_SYS_AUE_linux_time	AUE_NULL
+#define	LINUX_SYS_AUE_linux_mknod	AUE_MKNOD
+#define	LINUX_SYS_AUE_linux_chmod	AUE_CHMOD
+#define	LINUX_SYS_AUE_linux_lchown16	AUE_LCHOWN
+#define	LINUX_SYS_AUE_linux_stat	AUE_STAT
+#define	LINUX_SYS_AUE_linux_lseek	AUE_LSEEK
+#define	LINUX_SYS_AUE_linux_getpid	AUE_GETPID
+#define	LINUX_SYS_AUE_linux_mount	AUE_MOUNT
+#define	LINUX_SYS_AUE_linux_oldumount	AUE_UMOUNT
+#define	LINUX_SYS_AUE_linux_setuid16	AUE_SETUID
+#define	LINUX_SYS_AUE_linux_getuid16	AUE_GETUID
+#define	LINUX_SYS_AUE_linux_stime	AUE_SETTIMEOFDAY
+#define	LINUX_SYS_AUE_linux_ptrace	AUE_PTRACE
+#define	LINUX_SYS_AUE_linux_alarm	AUE_NULL
+#define	LINUX_SYS_AUE_linux_pause	AUE_NULL
+#define	LINUX_SYS_AUE_linux_utime	AUE_UTIME
+#define	LINUX_SYS_AUE_linux_access	AUE_ACCESS
+#define	LINUX_SYS_AUE_linux_nice	AUE_NICE
+#define	LINUX_SYS_AUE_linux_kill	AUE_KILL
+#define	LINUX_SYS_AUE_linux_rename	AUE_RENAME
+#define	LINUX_SYS_AUE_linux_mkdir	AUE_MKDIR
+#define	LINUX_SYS_AUE_linux_rmdir	AUE_RMDIR
+#define	LINUX_SYS_AUE_linux_pipe	AUE_PIPE
+#define	LINUX_SYS_AUE_linux_times	AUE_NULL
+#define	LINUX_SYS_AUE_linux_brk	AUE_NULL
+#define	LINUX_SYS_AUE_linux_setgid16	AUE_SETGID
+#define	LINUX_SYS_AUE_linux_getgid16	AUE_GETGID
+#define	LINUX_SYS_AUE_linux_signal	AUE_NULL
+#define	LINUX_SYS_AUE_linux_geteuid16	AUE_GETEUID
+#define	LINUX_SYS_AUE_linux_getegid16	AUE_GETEGID
+#define	LINUX_SYS_AUE_linux_umount	AUE_UMOUNT
+#define	LINUX_SYS_AUE_linux_ioctl	AUE_IOCTL
+#define	LINUX_SYS_AUE_linux_fcntl	AUE_FCNTL
+#define	LINUX_SYS_AUE_linux_olduname	AUE_NULL
+#define	LINUX_SYS_AUE_linux_ustat	AUE_NULL
+#define	LINUX_SYS_AUE_linux_getppid	AUE_GETPPID
+#define	LINUX_SYS_AUE_linux_sigaction	AUE_NULL
+#define	LINUX_SYS_AUE_linux_sgetmask	AUE_NULL
+#define	LINUX_SYS_AUE_linux_ssetmask	AUE_NULL
+#define	LINUX_SYS_AUE_linux_setreuid16	AUE_SETREUID
+#define	LINUX_SYS_AUE_linux_setregid16	AUE_SETREGID
+#define	LINUX_SYS_AUE_linux_sigsuspend	AUE_NULL
+#define	LINUX_SYS_AUE_linux_sigpending	AUE_NULL
+#define	LINUX_SYS_AUE_linux_sethostname	AUE_SYSCTL
+#define	LINUX_SYS_AUE_linux_setrlimit	AUE_SETRLIMIT
+#define	LINUX_SYS_AUE_linux_old_getrlimit	AUE_GETRLIMIT
+#define	LINUX_SYS_AUE_linux_getrusage	AUE_GETRUSAGE
+#define	LINUX_SYS_AUE_linux_gettimeofday	AUE_NULL
+#define	LINUX_SYS_AUE_linux_settimeofday	AUE_SETTIMEOFDAY
+#define	LINUX_SYS_AUE_linux_getgroups16	AUE_GETGROUPS
+#define	LINUX_SYS_AUE_linux_setgroups16	AUE_SETGROUPS
+#define	LINUX_SYS_AUE_linux_old_select	AUE_SELECT
+#define	LINUX_SYS_AUE_linux_symlink	AUE_SYMLINK
+#define	LINUX_SYS_AUE_linux_lstat	AUE_LSTAT
+#define	LINUX_SYS_AUE_linux_readlink	AUE_READLINK
+#define	LINUX_SYS_AUE_linux_reboot	AUE_REBOOT
+#define	LINUX_SYS_AUE_linux_readdir	AUE_GETDIRENTRIES
+#define	LINUX_SYS_AUE_linux_mmap	AUE_MMAP
+#define	LINUX_SYS_AUE_linux_truncate	AUE_TRUNCATE
+#define	LINUX_SYS_AUE_linux_ftruncate	AUE_FTRUNCATE
+#define	LINUX_SYS_AUE_linux_getpriority	AUE_GETPRIORITY
+#define	LINUX_SYS_AUE_linux_statfs	AUE_STATFS
+#define	LINUX_SYS_AUE_linux_fstatfs	AUE_FSTATFS
+#define	LINUX_SYS_AUE_linux_socketcall	AUE_NULL
+#define	LINUX_SYS_AUE_linux_syslog	AUE_NULL
+#define	LINUX_SYS_AUE_linux_setitimer	AUE_SETITIMER
+#define	LINUX_SYS_AUE_linux_getitimer	AUE_GETITIMER
+#define	LINUX_SYS_AUE_linux_newstat	AUE_STAT
+#define	LINUX_SYS_AUE_linux_newlstat	AUE_LSTAT
+#define	LINUX_SYS_AUE_linux_newfstat	AUE_FSTAT
+#define	LINUX_SYS_AUE_linux_uname	AUE_NULL
+#define	LINUX_SYS_AUE_linux_iopl	AUE_NULL
+#define	LINUX_SYS_AUE_linux_vhangup	AUE_NULL
+#define	LINUX_SYS_AUE_linux_wait4	AUE_WAIT4
+#define	LINUX_SYS_AUE_linux_swapoff	AUE_SWAPOFF
+#define	LINUX_SYS_AUE_linux_sysinfo	AUE_NULL
+#define	LINUX_SYS_AUE_linux_ipc	AUE_NULL
+#define	LINUX_SYS_AUE_linux_sigreturn	AUE_SIGRETURN
+#define	LINUX_SYS_AUE_linux_clone	AUE_RFORK
+#define	LINUX_SYS_AUE_linux_newuname	AUE_NULL
+#define	LINUX_SYS_AUE_linux_adjtimex	AUE_ADJTIME
+#define	LINUX_SYS_AUE_linux_mprotect	AUE_MPROTECT
+#define	LINUX_SYS_AUE_linux_sigprocmask	AUE_SIGPROCMASK
+#define	LINUX_SYS_AUE_linux_create_module	AUE_NULL
+#define	LINUX_SYS_AUE_linux_init_module	AUE_NULL
+#define	LINUX_SYS_AUE_linux_delete_module	AUE_NULL
+#define	LINUX_SYS_AUE_linux_get_kernel_syms	AUE_NULL
+#define	LINUX_SYS_AUE_linux_quotactl	AUE_QUOTACTL
+#define	LINUX_SYS_AUE_linux_bdflush	AUE_BDFLUSH
+#define	LINUX_SYS_AUE_linux_sysfs	AUE_NULL
+#define	LINUX_SYS_AUE_linux_personality	AUE_PERSONALITY
+#define	LINUX_SYS_AUE_linux_setfsuid16	AUE_SETFSUID
+#define	LINUX_SYS_AUE_linux_setfsgid16	AUE_SETFSGID
+#define	LINUX_SYS_AUE_linux_llseek	AUE_LSEEK
+#define	LINUX_SYS_AUE_linux_getdents	AUE_GETDIRENTRIES
+#define	LINUX_SYS_AUE_linux_select	AUE_SELECT
+#define	LINUX_SYS_AUE_linux_msync	AUE_MSYNC
+#define	LINUX_SYS_AUE_linux_readv	AUE_READV
+#define	LINUX_SYS_AUE_linux_writev	AUE_WRITEV
+#define	LINUX_SYS_AUE_linux_getsid	AUE_GETSID
+#define	LINUX_SYS_AUE_linux_fdatasync	AUE_NULL
+#define	LINUX_SYS_AUE_linux_sysctl	AUE_SYSCTL
+#define	LINUX_SYS_AUE_linux_sched_setscheduler	AUE_SCHED_SETSCHEDULER
+#define	LINUX_SYS_AUE_linux_sched_getscheduler	AUE_SCHED_GETSCHEDULER
+#define	LINUX_SYS_AUE_linux_sched_get_priority_max	AUE_SCHED_GET_PRIORITY_MAX
+#define	LINUX_SYS_AUE_linux_sched_get_priority_min	AUE_SCHED_GET_PRIORITY_MIN
+#define	LINUX_SYS_AUE_linux_sched_rr_get_interval	AUE_SCHED_RR_GET_INTERVAL
+#define	LINUX_SYS_AUE_linux_nanosleep	AUE_NULL
+#define	LINUX_SYS_AUE_linux_mremap	AUE_NULL
+#define	LINUX_SYS_AUE_linux_setresuid16	AUE_SETRESUID
+#define	LINUX_SYS_AUE_linux_getresuid16	AUE_GETRESUID
+#define	LINUX_SYS_AUE_linux_query_module	AUE_NULL
+#define	LINUX_SYS_AUE_linux_nfsservctl	AUE_NULL
+#define	LINUX_SYS_AUE_linux_setresgid16	AUE_SETRESGID
+#define	LINUX_SYS_AUE_linux_getresgid16	AUE_GETRESGID
+#define	LINUX_SYS_AUE_linux_prctl	AUE_PRCTL
+#define	LINUX_SYS_AUE_linux_rt_sigreturn	AUE_NULL
+#define	LINUX_SYS_AUE_linux_rt_sigaction	AUE_NULL
+#define	LINUX_SYS_AUE_linux_rt_sigprocmask	AUE_NULL
+#define	LINUX_SYS_AUE_linux_rt_sigpending	AUE_NULL
+#define	LINUX_SYS_AUE_linux_rt_sigtimedwait	AUE_NULL
+#define	LINUX_SYS_AUE_linux_rt_sigqueueinfo	AUE_NULL
+#define	LINUX_SYS_AUE_linux_rt_sigsuspend	AUE_NULL
+#define	LINUX_SYS_AUE_linux_pread	AUE_PREAD
+#define	LINUX_SYS_AUE_linux_pwrite	AUE_PWRITE
+#define	LINUX_SYS_AUE_linux_chown16	AUE_CHOWN
+#define	LINUX_SYS_AUE_linux_getcwd	AUE_GETCWD
+#define	LINUX_SYS_AUE_linux_capget	AUE_CAPGET
+#define	LINUX_SYS_AUE_linux_capset	AUE_CAPSET
+#define	LINUX_SYS_AUE_linux_sigaltstack	AUE_NULL
+#define	LINUX_SYS_AUE_linux_sendfile	AUE_SENDFILE
+#define	LINUX_SYS_AUE_linux_vfork	AUE_VFORK
+#define	LINUX_SYS_AUE_linux_getrlimit	AUE_GETRLIMIT
+#define	LINUX_SYS_AUE_linux_mmap2	AUE_MMAP
+#define	LINUX_SYS_AUE_linux_truncate64	AUE_TRUNCATE
+#define	LINUX_SYS_AUE_linux_ftruncate64	AUE_FTRUNCATE
+#define	LINUX_SYS_AUE_linux_stat64	AUE_STAT
+#define	LINUX_SYS_AUE_linux_lstat64	AUE_LSTAT
+#define	LINUX_SYS_AUE_linux_fstat64	AUE_FSTAT
+#define	LINUX_SYS_AUE_linux_lchown	AUE_LCHOWN
+#define	LINUX_SYS_AUE_linux_getuid	AUE_GETUID
+#define	LINUX_SYS_AUE_linux_getgid	AUE_GETGID
+#define	LINUX_SYS_AUE_linux_getgroups	AUE_GETGROUPS
+#define	LINUX_SYS_AUE_linux_setgroups	AUE_SETGROUPS
+#define	LINUX_SYS_AUE_linux_chown	AUE_CHOWN
+#define	LINUX_SYS_AUE_linux_setfsuid	AUE_SETFSUID
+#define	LINUX_SYS_AUE_linux_setfsgid	AUE_SETFSGID
+#define	LINUX_SYS_AUE_linux_pivot_root	AUE_PIVOT_ROOT
+#define	LINUX_SYS_AUE_linux_mincore	AUE_MINCORE
+#define	LINUX_SYS_AUE_linux_getdents64	AUE_GETDIRENTRIES
+#define	LINUX_SYS_AUE_linux_fcntl64	AUE_FCNTL
+#define	LINUX_SYS_AUE_linux_gettid	AUE_NULL
+#define	LINUX_SYS_AUE_linux_setxattr	AUE_NULL
+#define	LINUX_SYS_AUE_linux_lsetxattr	AUE_NULL
+#define	LINUX_SYS_AUE_linux_fsetxattr	AUE_NULL
+#define	LINUX_SYS_AUE_linux_getxattr	AUE_NULL
+#define	LINUX_SYS_AUE_linux_lgetxattr	AUE_NULL
+#define	LINUX_SYS_AUE_linux_fgetxattr	AUE_NULL
+#define	LINUX_SYS_AUE_linux_listxattr	AUE_NULL
+#define	LINUX_SYS_AUE_linux_llistxattr	AUE_NULL
+#define	LINUX_SYS_AUE_linux_flistxattr	AUE_NULL
+#define	LINUX_SYS_AUE_linux_removexattr	AUE_NULL
+#define	LINUX_SYS_AUE_linux_lremovexattr	AUE_NULL
+#define	LINUX_SYS_AUE_linux_fremovexattr	AUE_NULL
+#define	LINUX_SYS_AUE_linux_tkill	AUE_NULL
+#define	LINUX_SYS_AUE_linux_sys_futex	AUE_NULL
+#define	LINUX_SYS_AUE_linux_sched_getaffinity	AUE_NULL
+#define	LINUX_SYS_AUE_linux_set_thread_area	AUE_NULL
+#define	LINUX_SYS_AUE_linux_fadvise64	AUE_NULL
+#define	LINUX_SYS_AUE_linux_exit_group	AUE_EXIT
+#define	LINUX_SYS_AUE_linux_lookup_dcookie	AUE_NULL
+#define	LINUX_SYS_AUE_linux_epoll_create	AUE_NULL
+#define	LINUX_SYS_AUE_linux_epoll_ctl	AUE_NULL
+#define	LINUX_SYS_AUE_linux_epoll_wait	AUE_NULL
+#define	LINUX_SYS_AUE_linux_remap_file_pages	AUE_NULL
+#define	LINUX_SYS_AUE_linux_set_tid_address	AUE_NULL
+#define	LINUX_SYS_AUE_linux_timer_create	AUE_NULL
+#define	LINUX_SYS_AUE_linux_timer_settime	AUE_NULL
+#define	LINUX_SYS_AUE_linux_timer_gettime	AUE_NULL
+#define	LINUX_SYS_AUE_linux_timer_getoverrun	AUE_NULL
+#define	LINUX_SYS_AUE_linux_timer_delete	AUE_NULL
+#define	LINUX_SYS_AUE_linux_clock_settime	AUE_CLOCK_SETTIME
+#define	LINUX_SYS_AUE_linux_clock_gettime	AUE_NULL
+#define	LINUX_SYS_AUE_linux_clock_getres	AUE_NULL
+#define	LINUX_SYS_AUE_linux_clock_nanosleep	AUE_NULL
+#define	LINUX_SYS_AUE_linux_statfs64	AUE_STATFS
+#define	LINUX_SYS_AUE_linux_fstatfs64	AUE_FSTATFS
+#define	LINUX_SYS_AUE_linux_tgkill	AUE_NULL
+#define	LINUX_SYS_AUE_linux_utimes	AUE_UTIMES
+#define	LINUX_SYS_AUE_linux_fadvise64_64	AUE_NULL
+#define	LINUX_SYS_AUE_linux_mbind	AUE_NULL
+#define	LINUX_SYS_AUE_linux_get_mempolicy	AUE_NULL
+#define	LINUX_SYS_AUE_linux_set_mempolicy	AUE_NULL
+#define	LINUX_SYS_AUE_linux_mq_open	AUE_NULL
+#define	LINUX_SYS_AUE_linux_mq_unlink	AUE_NULL
+#define	LINUX_SYS_AUE_linux_mq_timedsend	AUE_NULL
+#define	LINUX_SYS_AUE_linux_mq_timedreceive	AUE_NULL
+#define	LINUX_SYS_AUE_linux_mq_notify	AUE_NULL
+#define	LINUX_SYS_AUE_linux_mq_getsetattr	AUE_NULL
+#define	LINUX_SYS_AUE_linux_kexec_load	AUE_NULL
+#define	LINUX_SYS_AUE_linux_waitid	AUE_NULL
+#define	LINUX_SYS_AUE_linux_add_key	AUE_NULL
+#define	LINUX_SYS_AUE_linux_request_key	AUE_NULL
+#define	LINUX_SYS_AUE_linux_keyctl	AUE_NULL
+#define	LINUX_SYS_AUE_linux_ioprio_set	AUE_NULL
+#define	LINUX_SYS_AUE_linux_ioprio_get	AUE_NULL
+#define	LINUX_SYS_AUE_linux_inotify_init	AUE_NULL
+#define	LINUX_SYS_AUE_linux_inotify_add_watch	AUE_NULL
+#define	LINUX_SYS_AUE_linux_inotify_rm_watch	AUE_NULL
+#define	LINUX_SYS_AUE_linux_migrate_pages	AUE_NULL
+#define	LINUX_SYS_AUE_linux_openat	AUE_OPEN_RWTC
+#define	LINUX_SYS_AUE_linux_mkdirat	AUE_NULL
+#define	LINUX_SYS_AUE_linux_mknodat	AUE_NULL
+#define	LINUX_SYS_AUE_linux_fchownat	AUE_NULL
+#define	LINUX_SYS_AUE_linux_futimesat	AUE_NULL
+#define	LINUX_SYS_AUE_linux_fstatat64	AUE_NULL
+#define	LINUX_SYS_AUE_linux_unlinkat	AUE_NULL
+#define	LINUX_SYS_AUE_linux_renameat	AUE_NULL
+#define	LINUX_SYS_AUE_linux_linkat	AUE_NULL
+#define	LINUX_SYS_AUE_linux_symlinkat	AUE_NULL
+#define	LINUX_SYS_AUE_linux_readlinkat	AUE_NULL
+#define	LINUX_SYS_AUE_linux_fchmodat	AUE_NULL
+#define	LINUX_SYS_AUE_linux_faccessat	AUE_NULL
+#define	LINUX_SYS_AUE_linux_pselect6	AUE_NULL
+#define	LINUX_SYS_AUE_linux_ppoll	AUE_NULL
+#define	LINUX_SYS_AUE_linux_unshare	AUE_NULL
+
 #undef PAD_
 #undef PADL_
 #undef PADR_
Index: Makefile
===================================================================
RCS file: /home/cvs/src/sys/amd64/Makefile,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L sys/amd64/Makefile -L sys/amd64/Makefile -u -r1.1.1.1 -r1.2
--- sys/amd64/Makefile
+++ sys/amd64/Makefile
@@ -1,3 +1,4 @@
+# $MidnightBSD$
 # $FreeBSD: src/sys/amd64/Makefile,v 1.11 2002/06/21 06:18:02 mckusick Exp $
 #	@(#)Makefile	8.1 (Berkeley) 6/11/93
 
Index: specialreg.h
===================================================================
RCS file: /home/cvs/src/sys/amd64/include/specialreg.h,v
retrieving revision 1.2
retrieving revision 1.3
diff -L sys/amd64/include/specialreg.h -L sys/amd64/include/specialreg.h -u -r1.2 -r1.3
--- sys/amd64/include/specialreg.h
+++ sys/amd64/include/specialreg.h
@@ -27,7 +27,7 @@
  * SUCH DAMAGE.
  *
  *	from: @(#)specialreg.h	7.1 (Berkeley) 5/9/91
- * $FreeBSD: src/sys/amd64/include/specialreg.h,v 1.30.8.1 2006/04/24 18:21:54 jkim Exp $
+ * $FreeBSD: src/sys/amd64/include/specialreg.h,v 1.40 2007/08/15 19:26:01 des Exp $
  */
 
 #ifndef _MACHINE_SPECIALREG_H_
@@ -109,33 +109,42 @@
 #define	CPUID_SS	0x08000000
 #define	CPUID_HTT	0x10000000
 #define	CPUID_TM	0x20000000
-#define	CPUID_B30	0x40000000
+#define	CPUID_IA64	0x40000000
 #define	CPUID_PBE	0x80000000
 
-#define CPUID2_SSE3	0x00000001
-#define CPUID2_MON	0x00000008
-#define CPUID2_DS_CPL	0x00000010
-#define CPUID2_EST	0x00000080
-#define CPUID2_TM2	0x00000100
-#define CPUID2_CNTXID	0x00000400
-#define CPUID2_CX16	0x00002000
+#define	CPUID2_SSE3	0x00000001
+#define	CPUID2_MON	0x00000008
+#define	CPUID2_DS_CPL	0x00000010
+#define	CPUID2_VMX	0x00000020
+#define	CPUID2_SMX	0x00000040
+#define	CPUID2_EST	0x00000080
+#define	CPUID2_TM2	0x00000100
+#define	CPUID2_SSSE3	0x00000200
+#define	CPUID2_CNXTID	0x00000400
+#define	CPUID2_CX16	0x00002000
+#define	CPUID2_XTPR	0x00004000
+#define	CPUID2_PDCM	0x00008000
+#define	CPUID2_DCA	0x00040000
 
 /*
  * Important bits in the AMD extended cpuid flags
  */
-#define AMDID_SYSCALL	0x00000800
-#define AMDID_MP	0x00080000
-#define AMDID_NX	0x00100000
-#define AMDID_EXT_MMX	0x00400000
-#define AMDID_FFXSR	0x01000000
-#define AMDID_RDTSCP	0x08000000
-#define AMDID_LM	0x20000000
-#define AMDID_EXT_3DNOW	0x40000000
-#define AMDID_3DNOW	0x80000000
-
-#define AMDID2_LAHF	0x00000001
-#define AMDID2_CMP	0x00000002
-#define AMDID2_CR8	0x00000010
+#define	AMDID_SYSCALL	0x00000800
+#define	AMDID_MP	0x00080000
+#define	AMDID_NX	0x00100000
+#define	AMDID_EXT_MMX	0x00400000
+#define	AMDID_FFXSR	0x01000000
+#define	AMDID_RDTSCP	0x08000000
+#define	AMDID_LM	0x20000000
+#define	AMDID_EXT_3DNOW	0x40000000
+#define	AMDID_3DNOW	0x80000000
+
+#define	AMDID2_LAHF	0x00000001
+#define	AMDID2_CMP	0x00000002
+#define	AMDID2_SVM	0x00000004
+#define	AMDID2_EXT_APIC	0x00000008
+#define	AMDID2_CR8	0x00000010
+#define	AMDID2_PREFETCH	0x00000100
 
 /*
  * CPUID instruction 1 ebx info
@@ -148,29 +157,30 @@
 /*
  * AMD extended function 8000_0008h ecx info
  */
-#define AMDID_CMP_CORES		0x000000ff
+#define	AMDID_CMP_CORES		0x000000ff
 
 /*
  * Model-specific registers for the i386 family
  */
-#define MSR_P5_MC_ADDR		0x000
-#define MSR_P5_MC_TYPE		0x001
-#define MSR_TSC			0x010
+#define	MSR_P5_MC_ADDR		0x000
+#define	MSR_P5_MC_TYPE		0x001
+#define	MSR_TSC			0x010
 #define	MSR_P5_CESR		0x011
 #define	MSR_P5_CTR0		0x012
 #define	MSR_P5_CTR1		0x013
 #define	MSR_IA32_PLATFORM_ID	0x017
-#define MSR_APICBASE		0x01b
-#define MSR_EBL_CR_POWERON	0x02a
+#define	MSR_APICBASE		0x01b
+#define	MSR_EBL_CR_POWERON	0x02a
 #define	MSR_TEST_CTL		0x033
-#define MSR_BIOS_UPDT_TRIG	0x079
+#define	MSR_BIOS_UPDT_TRIG	0x079
 #define	MSR_BBL_CR_D0		0x088
 #define	MSR_BBL_CR_D1		0x089
 #define	MSR_BBL_CR_D2		0x08a
-#define MSR_BIOS_SIGN		0x08b
-#define MSR_PERFCTR0		0x0c1
-#define MSR_PERFCTR1		0x0c2
-#define MSR_MTRRcap		0x0fe
+#define	MSR_BIOS_SIGN		0x08b
+#define	MSR_PERFCTR0		0x0c1
+#define	MSR_PERFCTR1		0x0c2
+#define	MSR_IA32_EXT_CONFIG	0x0ee	/* Undocumented. Core Solo/Duo only */
+#define	MSR_MTRRcap		0x0fe
 #define	MSR_BBL_CR_ADDR		0x116
 #define	MSR_BBL_CR_DECC		0x118
 #define	MSR_BBL_CR_CTL		0x119
@@ -180,46 +190,47 @@
 #define	MSR_SYSENTER_CS_MSR	0x174
 #define	MSR_SYSENTER_ESP_MSR	0x175
 #define	MSR_SYSENTER_EIP_MSR	0x176
-#define MSR_MCG_CAP		0x179
-#define MSR_MCG_STATUS		0x17a
-#define MSR_MCG_CTL		0x17b
-#define MSR_EVNTSEL0		0x186
-#define MSR_EVNTSEL1		0x187
-#define MSR_THERM_CONTROL	0x19a
-#define MSR_THERM_INTERRUPT	0x19b
-#define MSR_THERM_STATUS	0x19c
-#define MSR_DEBUGCTLMSR		0x1d9
-#define MSR_LASTBRANCHFROMIP	0x1db
-#define MSR_LASTBRANCHTOIP	0x1dc
-#define MSR_LASTINTFROMIP	0x1dd
-#define MSR_LASTINTTOIP		0x1de
-#define MSR_ROB_CR_BKUPTMPDR6	0x1e0
-#define MSR_MTRRVarBase		0x200
-#define MSR_MTRR64kBase		0x250
-#define MSR_MTRR16kBase		0x258
-#define MSR_MTRR4kBase		0x268
-#define MSR_PAT			0x277
-#define MSR_MTRRdefType		0x2ff
-#define MSR_MC0_CTL		0x400
-#define MSR_MC0_STATUS		0x401
-#define MSR_MC0_ADDR		0x402
-#define MSR_MC0_MISC		0x403
-#define MSR_MC1_CTL		0x404
-#define MSR_MC1_STATUS		0x405
-#define MSR_MC1_ADDR		0x406
-#define MSR_MC1_MISC		0x407
-#define MSR_MC2_CTL		0x408
-#define MSR_MC2_STATUS		0x409
-#define MSR_MC2_ADDR		0x40a
-#define MSR_MC2_MISC		0x40b
-#define MSR_MC3_CTL		0x40c
-#define MSR_MC3_STATUS		0x40d
-#define MSR_MC3_ADDR		0x40e
-#define MSR_MC3_MISC		0x40f
-#define MSR_MC4_CTL		0x410
-#define MSR_MC4_STATUS		0x411
-#define MSR_MC4_ADDR		0x412
-#define MSR_MC4_MISC		0x413
+#define	MSR_MCG_CAP		0x179
+#define	MSR_MCG_STATUS		0x17a
+#define	MSR_MCG_CTL		0x17b
+#define	MSR_EVNTSEL0		0x186
+#define	MSR_EVNTSEL1		0x187
+#define	MSR_THERM_CONTROL	0x19a
+#define	MSR_THERM_INTERRUPT	0x19b
+#define	MSR_THERM_STATUS	0x19c
+#define	MSR_IA32_MISC_ENABLE	0x1a0
+#define	MSR_DEBUGCTLMSR		0x1d9
+#define	MSR_LASTBRANCHFROMIP	0x1db
+#define	MSR_LASTBRANCHTOIP	0x1dc
+#define	MSR_LASTINTFROMIP	0x1dd
+#define	MSR_LASTINTTOIP		0x1de
+#define	MSR_ROB_CR_BKUPTMPDR6	0x1e0
+#define	MSR_MTRRVarBase		0x200
+#define	MSR_MTRR64kBase		0x250
+#define	MSR_MTRR16kBase		0x258
+#define	MSR_MTRR4kBase		0x268
+#define	MSR_PAT			0x277
+#define	MSR_MTRRdefType		0x2ff
+#define	MSR_MC0_CTL		0x400
+#define	MSR_MC0_STATUS		0x401
+#define	MSR_MC0_ADDR		0x402
+#define	MSR_MC0_MISC		0x403
+#define	MSR_MC1_CTL		0x404
+#define	MSR_MC1_STATUS		0x405
+#define	MSR_MC1_ADDR		0x406
+#define	MSR_MC1_MISC		0x407
+#define	MSR_MC2_CTL		0x408
+#define	MSR_MC2_STATUS		0x409
+#define	MSR_MC2_ADDR		0x40a
+#define	MSR_MC2_MISC		0x40b
+#define	MSR_MC3_CTL		0x40c
+#define	MSR_MC3_STATUS		0x40d
+#define	MSR_MC3_ADDR		0x40e
+#define	MSR_MC3_MISC		0x40f
+#define	MSR_MC4_CTL		0x410
+#define	MSR_MC4_STATUS		0x411
+#define	MSR_MC4_ADDR		0x412
+#define	MSR_MC4_MISC		0x413
 
 /*
  * Constants related to MSR's.
@@ -230,11 +241,23 @@
 #define	APICBASE_ADDRESS	0xfffff000
 
 /*
+ * PAT modes.
+ */
+#define	PAT_UNCACHEABLE		0x00
+#define	PAT_WRITE_COMBINING	0x01
+#define	PAT_WRITE_THROUGH	0x04
+#define	PAT_WRITE_PROTECTED	0x05
+#define	PAT_WRITE_BACK		0x06
+#define	PAT_UNCACHED		0x07
+#define	PAT_VALUE(i, m)		((long)(m) << (8 * (i)))
+#define	PAT_MASK(i)		PAT_VALUE(i, 0xff)
+
+/*
  * Constants related to MTRRs
  */
-#define MTRR_N64K		8	/* numbers of fixed-size entries */
-#define MTRR_N16K		16
-#define MTRR_N4K		64
+#define	MTRR_N64K		8	/* numbers of fixed-size entries */
+#define	MTRR_N16K		16
+#define	MTRR_N4K		64
 
 /* Performance Control Register (5x86 only). */
 #define	PCR0			0x20
@@ -331,11 +354,11 @@
 #define	RCR6	0xe2
 #define	RCR7	0xe3
 
-#define RCR_RCD	0x01	/* Disables caching for ARRx (x = 0-6). */
-#define RCR_RCE	0x01	/* Enables caching for ARR7. */
-#define RCR_WWO	0x02	/* Weak write ordering. */
+#define	RCR_RCD	0x01	/* Disables caching for ARRx (x = 0-6). */
+#define	RCR_RCE	0x01	/* Enables caching for ARR7. */
+#define	RCR_WWO	0x02	/* Weak write ordering. */
 #define	RCR_WL	0x04	/* Weak locking. */
-#define RCR_WG	0x08	/* Write gathering. */
+#define	RCR_WG	0x08	/* Write gathering. */
 #define	RCR_WT	0x10	/* Write-through. */
 #define	RCR_NLB	0x20	/* LBA# pin is not asserted. */
 
@@ -344,7 +367,7 @@
 #define	AMD_WT_ALLOC_PRE	0x20000	/* programmable range enable */
 #define	AMD_WT_ALLOC_FRE	0x10000	/* fixed (A0000-FFFFF) range enable */
 
-/* X86-64 MSR's */
+/* AMD64 MSR's */
 #define	MSR_EFER	0xc0000080	/* extended features */
 #define	MSR_STAR	0xc0000081	/* legacy mode SYSCALL target/cs/ss */
 #define	MSR_LSTAR	0xc0000082	/* long mode SYSCALL target rip */
Index: signal.h
===================================================================
RCS file: /home/cvs/src/sys/amd64/include/signal.h,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L sys/amd64/include/signal.h -L sys/amd64/include/signal.h -u -r1.1.1.1 -r1.2
--- sys/amd64/include/signal.h
+++ sys/amd64/include/signal.h
@@ -28,7 +28,7 @@
  * SUCH DAMAGE.
  *
  *	@(#)signal.h	8.1 (Berkeley) 6/11/93
- * $FreeBSD: src/sys/amd64/include/signal.h,v 1.28 2005/01/05 20:17:20 imp Exp $
+ * $FreeBSD: src/sys/amd64/include/signal.h,v 1.29 2005/08/20 16:44:40 stefanf Exp $
  */
 
 #ifndef _MACHINE_SIGNAL_H_
@@ -43,14 +43,6 @@
 
 typedef long sig_atomic_t;
 
-#if __XSI_VISIBLE
-/*
- * Minimum signal stack size. The current signal frame
- * for i386 is 408 bytes large.
- */
-#define	MINSIGSTKSZ	(512 * 4)
-#endif
-
 #if __BSD_VISIBLE
 #include <machine/trap.h>	/* codes for SIGILL, SIGFPE */
 
Index: cpu.h
===================================================================
RCS file: /home/cvs/src/sys/amd64/include/cpu.h,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L sys/amd64/include/cpu.h -L sys/amd64/include/cpu.h -u -r1.1.1.1 -r1.2
--- sys/amd64/include/cpu.h
+++ sys/amd64/include/cpu.h
@@ -30,7 +30,7 @@
  * SUCH DAMAGE.
  *
  *	from: @(#)cpu.h	5.4 (Berkeley) 5/9/91
- * $FreeBSD: src/sys/amd64/include/cpu.h,v 1.74 2004/08/03 18:44:26 mux Exp $
+ * $FreeBSD: src/sys/amd64/include/cpu.h,v 1.76 2006/05/11 17:29:24 phk Exp $
  */
 
 #ifndef _MACHINE_CPU_H_
@@ -59,19 +59,6 @@
 	(ISPL((framep)->tf_cs) == SEL_UPL)
 #define	TRAPF_PC(framep)	((framep)->tf_rip)
 
-#define	CLKF_USERMODE(framep) \
-	(ISPL((framep)->cf_cs) == SEL_UPL)
-#define	CLKF_PC(framep)		((framep)->cf_rip)
-
-/*
- * CTL_MACHDEP definitions.
- */
-#define CPU_CONSDEV		1	/* dev_t: console terminal device */
-#define	CPU_ADJKERNTZ		2	/* int:	timezone offset	(seconds) */
-#define	CPU_DISRTCSET		3	/* int: disable resettodr() call */
-#define	CPU_WALLCLOCK		5	/* int:	indicates wall CMOS clock */
-#define	CPU_MAXID		6	/* number of valid machdep ids */
-
 #ifdef _KERNEL
 extern char	btext[];
 extern char	etext[];
Index: setjmp.h
===================================================================
RCS file: /home/cvs/src/sys/amd64/include/setjmp.h,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L sys/amd64/include/setjmp.h -L sys/amd64/include/setjmp.h -u -r1.1.1.1 -r1.2
--- sys/amd64/include/setjmp.h
+++ sys/amd64/include/setjmp.h
@@ -10,10 +10,7 @@
  * 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. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *	This product includes software developed by John Birrell.
- * 4. Neither the name of the author nor the names of any co-contributors
+ * 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.
  *
@@ -29,7 +26,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD: src/sys/amd64/include/setjmp.h,v 1.9 2003/06/02 21:49:35 peter Exp $
+ * $FreeBSD: src/sys/amd64/include/setjmp.h,v 1.10 2007/01/12 07:24:06 imp Exp $
  */
 
 #ifndef _MACHINE_SETJMP_H_
Index: intr_machdep.h
===================================================================
RCS file: /home/cvs/src/sys/amd64/include/intr_machdep.h,v
retrieving revision 1.2
retrieving revision 1.3
diff -L sys/amd64/include/intr_machdep.h -L sys/amd64/include/intr_machdep.h -u -r1.2 -r1.3
--- sys/amd64/include/intr_machdep.h
+++ sys/amd64/include/intr_machdep.h
@@ -23,7 +23,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD: src/sys/amd64/include/intr_machdep.h,v 1.5.2.3 2006/03/10 19:37:31 jhb Exp $
+ * $FreeBSD: src/sys/amd64/include/intr_machdep.h,v 1.18 2007/05/08 21:29:13 jhb Exp $
  */
 
 #ifndef __MACHINE_INTR_MACHDEP_H__
@@ -43,11 +43,18 @@
  * 191 and still be safe since only interrupt sources in actual use will
  * allocate IDT vectors.
  *
- * For now we stick with 255 as ISA IRQs and PCI intline IRQs only allow
- * for IRQs in the range 0 - 254.  When MSI support is added this number
- * will likely increase.
+ * The first 255 IRQs (0 - 254) are reserved for ISA IRQs and PCI intline IRQs.
+ * IRQ values beyond 256 are used by MSI.  We leave 255 unused to avoid
+ * confusion since 255 is used in PCI to indicate an invalid IRQ.
  */
-#define	NUM_IO_INTS	255
+#define	NUM_MSI_INTS	128
+#define	FIRST_MSI_INT	256
+#define	NUM_IO_INTS	(FIRST_MSI_INT + NUM_MSI_INTS)
+
+/*
+ * Default base address for MSI messages on x86 platforms.
+ */
+#define	MSI_INTEL_ADDR_BASE		0xfee00000
 
 /*
  * - 1 ??? dummy counter.
@@ -56,9 +63,9 @@
  * - 7 counters for each CPU for IPI counters for SMP.
  */
 #ifdef SMP
-#define	INTRCNT_COUNT	(1 + NUM_IO_INTS * 2 + 1)
-#else
 #define	INTRCNT_COUNT	(1 + NUM_IO_INTS * 2 + (1 + 7) * MAXCPU)
+#else
+#define	INTRCNT_COUNT	(1 + NUM_IO_INTS * 2 + 1)
 #endif
 
 #ifndef LOCORE
@@ -79,13 +86,15 @@
 	void (*pic_disable_source)(struct intsrc *, int);
 	void (*pic_eoi_source)(struct intsrc *);
 	void (*pic_enable_intr)(struct intsrc *);
+	void (*pic_disable_intr)(struct intsrc *);
 	int (*pic_vector)(struct intsrc *);
 	int (*pic_source_pending)(struct intsrc *);
-	void (*pic_suspend)(struct intsrc *);
-	void (*pic_resume)(struct intsrc *);
+	void (*pic_suspend)(struct pic *);
+	void (*pic_resume)(struct pic *);
 	int (*pic_config_intr)(struct intsrc *, enum intr_trigger,
 	    enum intr_polarity);
 	void (*pic_assign_cpu)(struct intsrc *, u_int apic_id);
+	STAILQ_ENTRY(pic) pics;
 };
 
 /* Flags for pic_disable_source() */
@@ -106,35 +115,45 @@
 	u_long *is_count;
 	u_long *is_straycount;
 	u_int is_index;
-	u_int is_enabled:1;
+	u_int is_handlers;
 };
 
-struct intrframe;
+struct trapframe;
 
 extern struct mtx icu_lock;
 extern int elcr_found;
 
+#ifndef DEV_ATPIC
+void	atpic_reset(void);
+#endif
 /* XXX: The elcr_* prototypes probably belong somewhere else. */
 int	elcr_probe(void);
 enum intr_trigger elcr_read_trigger(u_int irq);
 void	elcr_resume(void);
 void	elcr_write_trigger(u_int irq, enum intr_trigger trigger);
 #ifdef SMP
-void	intr_add_cpu(u_int apic_id);
-#else
-#define	intr_add_cpu(apic_id)
+void	intr_add_cpu(u_int cpu);
 #endif
-int	intr_add_handler(const char *name, int vector, driver_intr_t handler,
-    void *arg, enum intr_type flags, void **cookiep);
+int	intr_add_handler(const char *name, int vector, driver_filter_t filter, 
+			 driver_intr_t handler, void *arg, enum intr_type flags, 
+			 void **cookiep);    
 int	intr_config_intr(int vector, enum intr_trigger trig,
     enum intr_polarity pol);
-void	intr_execute_handlers(struct intsrc *isrc, struct intrframe *iframe);
+void	intr_execute_handlers(struct intsrc *isrc, struct trapframe *frame);
 struct intsrc *intr_lookup_source(int vector);
+int	intr_register_pic(struct pic *pic);
 int	intr_register_source(struct intsrc *isrc);
 int	intr_remove_handler(void *cookie);
 void	intr_resume(void);
 void	intr_suspend(void);
 void	intrcnt_add(const char *name, u_long **countp);
+void	nexus_add_irq(u_long irq);
+int	msi_alloc(device_t dev, int count, int maxcount, int *irqs);
+void	msi_init(void);
+int	msi_map(int irq, uint64_t *addr, uint32_t *data);
+int	msi_release(int *irqs, int count);
+int	msix_alloc(device_t dev, int *irq);
+int	msix_release(int irq);
 
 #endif	/* !LOCORE */
 #endif	/* _KERNEL */
Index: bus.h
===================================================================
RCS file: /home/cvs/src/sys/amd64/include/bus.h,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L sys/amd64/include/bus.h -L sys/amd64/include/bus.h -u -r1.1.1.1 -r1.2
--- sys/amd64/include/bus.h
+++ sys/amd64/include/bus.h
@@ -28,7 +28,7 @@
  * (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: src/sys/amd64/include/bus.h,v 1.16 2005/05/29 04:42:15 nyan Exp $
+ * $FreeBSD: src/sys/amd64/include/bus.h,v 1.17 2006/03/14 00:01:56 peter Exp $
  */
 
 /*	$NetBSD: bus.h,v 1.12 1997/10/01 08:25:15 fvdl Exp $	*/
@@ -1004,6 +1004,17 @@
 #endif
 }
 
+#ifdef BUS_SPACE_NO_LEGACY
+#undef inb
+#undef outb
+#define inb(a) compiler_error
+#define inw(a) compiler_error
+#define inl(a) compiler_error
+#define outb(a, b) compiler_error
+#define outw(a, b) compiler_error
+#define outl(a, b) compiler_error
+#endif
+
 #include <machine/bus_dma.h>
 
 /*
Index: _limits.h
===================================================================
RCS file: /home/cvs/src/sys/amd64/include/_limits.h,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L sys/amd64/include/_limits.h -L sys/amd64/include/_limits.h -u -r1.1.1.1 -r1.2
--- sys/amd64/include/_limits.h
+++ sys/amd64/include/_limits.h
@@ -27,7 +27,7 @@
  * SUCH DAMAGE.
  *
  *	@(#)limits.h	8.3 (Berkeley) 1/4/94
- * $FreeBSD: src/sys/amd64/include/_limits.h,v 1.10 2005/01/05 20:17:20 imp Exp $
+ * $FreeBSD: src/sys/amd64/include/_limits.h,v 1.11 2005/08/20 16:44:40 stefanf Exp $
  */
 
 #ifndef	_MACHINE__LIMITS_H_
@@ -83,4 +83,10 @@
 #define	__LONG_BIT	64
 #define	__WORD_BIT	32
 
+/*
+ * Minimum signal stack size. The current signal frame
+ * for i386 is 408 bytes large.
+ */
+#define	__MINSIGSTKSZ	(512 * 4)
+
 #endif /* !_MACHINE__LIMITS_H_ */
Index: gdb_machdep.h
===================================================================
RCS file: /home/cvs/src/sys/amd64/include/gdb_machdep.h,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L sys/amd64/include/gdb_machdep.h -L sys/amd64/include/gdb_machdep.h -u -r1.1.1.1 -r1.2
--- sys/amd64/include/gdb_machdep.h
+++ sys/amd64/include/gdb_machdep.h
@@ -23,15 +23,15 @@
  * (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: src/sys/amd64/include/gdb_machdep.h,v 1.3 2005/01/05 20:17:20 imp Exp $
+ * $FreeBSD: src/sys/amd64/include/gdb_machdep.h,v 1.6 2007/02/05 21:48:32 jhb Exp $
  */
 
 #ifndef _MACHINE_GDB_MACHDEP_H_
 #define	_MACHINE_GDB_MACHDEP_H_
 
-#define	GDB_BUFSZ	500
+#define	GDB_BUFSZ	(GDB_NREGS * 16)
 #define	GDB_NREGS	56
-#define	GDB_REG_PC	18
+#define	GDB_REG_PC	16
 
 static __inline size_t
 gdb_cpu_regsz(int regnum)
@@ -40,12 +40,6 @@
 }
 
 static __inline int
-gdb_cpu_signal(int type, int code __unused)
-{
-	return (type);
-}
-
-static __inline int
 gdb_cpu_query(void)
 {
 	return (0);
@@ -53,5 +47,6 @@
 
 void *gdb_cpu_getreg(int, size_t *);
 void gdb_cpu_setreg(int, void *);
+int gdb_cpu_signal(int, int);
 
 #endif /* !_MACHINE_GDB_MACHDEP_H_ */
Index: bus_dma.h
===================================================================
RCS file: /home/cvs/src/sys/amd64/include/bus_dma.h,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L sys/amd64/include/bus_dma.h -L sys/amd64/include/bus_dma.h -u -r1.1.1.1 -r1.2
--- sys/amd64/include/bus_dma.h
+++ sys/amd64/include/bus_dma.h
@@ -22,8 +22,9 @@
  * 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: src/sys/amd64/include/bus_dma.h,v 1.30 2005/07/22 04:03:25 obrien Exp $
  */
-/* $FreeBSD: src/sys/amd64/include/bus_dma.h,v 1.29 2005/03/14 16:46:27 scottl Exp $ */
 
 #ifndef _AMD64_BUS_DMA_H_
 #define _AMD64_BUS_DMA_H_
Index: asmacros.h
===================================================================
RCS file: /home/cvs/src/sys/amd64/include/asmacros.h,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L sys/amd64/include/asmacros.h -L sys/amd64/include/asmacros.h -u -r1.1.1.1 -r1.2
--- sys/amd64/include/asmacros.h
+++ sys/amd64/include/asmacros.h
@@ -26,7 +26,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD: src/sys/amd64/include/asmacros.h,v 1.28 2004/04/05 21:25:51 imp Exp $
+ * $FreeBSD: src/sys/amd64/include/asmacros.h,v 1.33 2007/08/22 04:26:07 jkoshy Exp $
  */
 
 #ifndef _MACHINE_ASMACROS_H_
@@ -37,14 +37,12 @@
 /* XXX too much duplication in various asm*.h's. */
 
 /*
- * CNAME and HIDENAME manage the relationship between symbol names in C
+ * CNAME is used to manage the relationship between symbol names in C
  * and the equivalent assembly language names.  CNAME is given a name as
  * it would be used in a C program.  It expands to the equivalent assembly
- * language name.  HIDENAME is given an assembly-language name, and expands
- * to a possibly-modified form that will be invisible to C programs.
+ * language name.
  */
 #define CNAME(csym)		csym
-#define HIDENAME(asmsym)	.asmsym
 
 #define ALIGN_DATA	.p2align 3	/* 8 byte alignment, zero filled */
 #ifdef GPROF
@@ -59,11 +57,7 @@
 #define NON_GPROF_ENTRY(name)	GEN_ENTRY(name)
 #define NON_GPROF_RET		.byte 0xc3	/* opcode for `ret' */
 
-#ifdef LOCORE
-#define	PCPU(member)	%gs:PC_ ## member
-#define	PCPU_ADDR(member, reg)	movq %gs:PC_PRVSPACE,reg; \
-			addq $PC_ ## member,reg
-#endif
+#define	END(name)		.size name, . - name
 
 #ifdef GPROF
 /*
@@ -114,8 +108,12 @@
 #define FAKE_MCOUNT(caller)	pushq caller ; call __mcount ; popq %rcx
 #define MCOUNT			call __mcount
 #define MCOUNT_LABEL(name)	GEN_ENTRY(name) ; nop ; ALIGN_TEXT
-#define MEXITCOUNT		call HIDENAME(mexitcount)
+#ifdef GUPROF
+#define MEXITCOUNT		call .mexitcount
 #define ret			MEXITCOUNT ; NON_GPROF_RET
+#else
+#define MEXITCOUNT
+#endif
 
 #else /* !GPROF */
 /*
@@ -136,11 +134,65 @@
 
 #ifdef LOCORE
 /*
- * Convenience macros for declaring interrupt entry points.
+ * Convenience macro for declaring interrupt entry points.
  */
 #define	IDTVEC(name)	ALIGN_TEXT; .globl __CONCAT(X,name); \
 			.type __CONCAT(X,name), at function; __CONCAT(X,name):
 
+/*
+ * Macros to create and destroy a trap frame.
+ */
+#define PUSH_FRAME							\
+	subq	$TF_RIP,%rsp ;	/* skip dummy tf_err and tf_trapno */	\
+	testb	$SEL_RPL_MASK,TF_CS(%rsp) ; /* come from kernel? */	\
+	jz	1f ;		/* Yes, dont swapgs again */		\
+	swapgs ;							\
+1:	movq	%rdi,TF_RDI(%rsp) ;					\
+	movq	%rsi,TF_RSI(%rsp) ;					\
+	movq	%rdx,TF_RDX(%rsp) ;					\
+	movq	%rcx,TF_RCX(%rsp) ;					\
+	movq	%r8,TF_R8(%rsp) ;					\
+	movq	%r9,TF_R9(%rsp) ;					\
+	movq	%rax,TF_RAX(%rsp) ;					\
+	movq	%rbx,TF_RBX(%rsp) ;					\
+	movq	%rbp,TF_RBP(%rsp) ;					\
+	movq	%r10,TF_R10(%rsp) ;					\
+	movq	%r11,TF_R11(%rsp) ;					\
+	movq	%r12,TF_R12(%rsp) ;					\
+	movq	%r13,TF_R13(%rsp) ;					\
+	movq	%r14,TF_R14(%rsp) ;					\
+	movq	%r15,TF_R15(%rsp)
+
+#define POP_FRAME							\
+	movq	TF_RDI(%rsp),%rdi ;					\
+	movq	TF_RSI(%rsp),%rsi ;					\
+	movq	TF_RDX(%rsp),%rdx ;					\
+	movq	TF_RCX(%rsp),%rcx ;					\
+	movq	TF_R8(%rsp),%r8 ;					\
+	movq	TF_R9(%rsp),%r9 ;					\
+	movq	TF_RAX(%rsp),%rax ;					\
+	movq	TF_RBX(%rsp),%rbx ;					\
+	movq	TF_RBP(%rsp),%rbp ;					\
+	movq	TF_R10(%rsp),%r10 ;					\
+	movq	TF_R11(%rsp),%r11 ;					\
+	movq	TF_R12(%rsp),%r12 ;					\
+	movq	TF_R13(%rsp),%r13 ;					\
+	movq	TF_R14(%rsp),%r14 ;					\
+	movq	TF_R15(%rsp),%r15 ;					\
+	testb	$SEL_RPL_MASK,TF_CS(%rsp) ; /* come from kernel? */	\
+	jz	1f ;		/* keep kernel GS.base */		\
+	cli ;								\
+	swapgs ;							\
+1:	addq	$TF_RIP,%rsp	/* skip over tf_err, tf_trapno */
+
+/*
+ * Access per-CPU data.
+ */
+#define	PCPU(member)	%gs:PC_ ## member
+#define	PCPU_ADDR(member, reg)					\
+	movq %gs:PC_PRVSPACE, reg ;				\
+	addq $PC_ ## member, reg
+
 #endif /* LOCORE */
 
 #endif /* !_MACHINE_ASMACROS_H_ */
Index: acpica_machdep.h
===================================================================
RCS file: /home/cvs/src/sys/amd64/include/acpica_machdep.h,v
retrieving revision 1.1.1.2
retrieving revision 1.2
diff -L sys/amd64/include/acpica_machdep.h -L sys/amd64/include/acpica_machdep.h -u -r1.1.1.2 -r1.2
--- sys/amd64/include/acpica_machdep.h
+++ sys/amd64/include/acpica_machdep.h
@@ -23,7 +23,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD: src/sys/amd64/include/acpica_machdep.h,v 1.6 2004/10/11 05:39:15 njl Exp $
+ * $FreeBSD: src/sys/amd64/include/acpica_machdep.h,v 1.7 2007/03/22 18:16:39 jkim Exp $
  */
 
 /******************************************************************************
@@ -34,7 +34,7 @@
  *****************************************************************************/
 
 #ifndef __ACPICA_MACHDEP_H__
-#define __ACPICA_MACHDEP_H__
+#define	__ACPICA_MACHDEP_H__
 
 #ifdef _KERNEL
 /*
@@ -45,33 +45,35 @@
  * ACPI_INTERNAL_XFACE      - Internal ACPI interfaces
  * ACPI_INTERNAL_VAR_XFACE  - Internal variable-parameter list interfaces
  */
-#define ACPI_SYSTEM_XFACE
-#define ACPI_EXTERNAL_XFACE
-#define ACPI_INTERNAL_XFACE
-#define ACPI_INTERNAL_VAR_XFACE
+#define	ACPI_SYSTEM_XFACE
+#define	ACPI_EXTERNAL_XFACE
+#define	ACPI_INTERNAL_XFACE
+#define	ACPI_INTERNAL_VAR_XFACE
 
 /* Asm macros */
 
-#define ACPI_ASM_MACROS
-#define BREAKPOINT3
-#define ACPI_DISABLE_IRQS() disable_intr()
-#define ACPI_ENABLE_IRQS()  enable_intr()
+#define	ACPI_ASM_MACROS
+#define	BREAKPOINT3
+#define	ACPI_DISABLE_IRQS() disable_intr()
+#define	ACPI_ENABLE_IRQS()  enable_intr()
 
-#define ACPI_FLUSH_CPU_CACHE()	wbinvd()
+#define	ACPI_FLUSH_CPU_CACHE()	wbinvd()
 
 /* Section 5.2.9.1:  global lock acquire/release functions */
 extern int	acpi_acquire_global_lock(uint32_t *lock);
 extern int	acpi_release_global_lock(uint32_t *lock);
-#define ACPI_ACQUIRE_GLOBAL_LOCK(GLptr, Acq) \
-		((Acq) = acpi_acquire_global_lock(GLptr))
-#define ACPI_RELEASE_GLOBAL_LOCK(GLptr, Acq) \
-		((Acq) = acpi_release_global_lock(GLptr))
+#define	ACPI_ACQUIRE_GLOBAL_LOCK(GLptr, Acq)	do {			\
+	(Acq) = acpi_acquire_global_lock(&((GLptr)->GlobalLock));	\
+} while (0)
+#define	ACPI_RELEASE_GLOBAL_LOCK(GLptr, Acq)	do {			\
+	(Acq) = acpi_release_global_lock(&((GLptr)->GlobalLock));	\
+} while (0)
  
 #endif /* _KERNEL */
 
-#define ACPI_MACHINE_WIDTH             64
-#define COMPILER_DEPENDENT_INT64       long
-#define COMPILER_DEPENDENT_UINT64      unsigned long
+#define	ACPI_MACHINE_WIDTH             64
+#define	COMPILER_DEPENDENT_INT64       long
+#define	COMPILER_DEPENDENT_UINT64      unsigned long
 
 void	acpi_SetDefaultIntrModel(int model);
 void	acpi_cpu_c1(void);
Index: stdarg.h
===================================================================
RCS file: /home/cvs/src/sys/amd64/include/stdarg.h,v
retrieving revision 1.2
retrieving revision 1.3
diff -L sys/amd64/include/stdarg.h -L sys/amd64/include/stdarg.h -u -r1.2 -r1.3
--- sys/amd64/include/stdarg.h
+++ sys/amd64/include/stdarg.h
@@ -1,5 +1,4 @@
 /*-
- * Copyright (c) 2008 Lucas Holt.  All rights reserved.
  * Copyright (c) 2002 David E. O'Brien.  All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -26,8 +25,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD: src/sys/amd64/include/stdarg.h,v 1.8 2005/03/11 22:16:09 peter Exp $
- * $MidnightBSD$
+ * $FreeBSD: src/sys/amd64/include/stdarg.h,v 1.9 2006/09/21 01:37:01 kan Exp $
  */
 
 #ifndef _MACHINE_STDARG_H_
@@ -44,7 +42,7 @@
 #ifdef __GNUCLIKE_BUILTIN_STDARG
 
 #define	va_start(ap, last) \
-	__builtin_stdarg_start((ap), (last))
+	__builtin_va_start((ap), (last))
 
 #define	va_arg(ap, type) \
 	__builtin_va_arg((ap), type)
@@ -70,17 +68,6 @@
 	(*(type *)((ap) += __va_size(type), (ap) - __va_size(type)))
 #define	va_end(ap)
 
-#elif defined(__PCC__) /* !__GNUCLIKE_BUILTIN_STDARG */
-
-#define va_start(ap, last) \
-        __builtin_stdarg_start((ap), last)
-#define va_arg(ap, type) \
-        __builtin_va_arg((ap), type)
-#define va_end(ap) \
-        __builtin_va_end((ap))
-#define __va_copy(dest, src) \
-        __builtin_va_copy((dest), (src))
-
 #else
 #error this file needs to be ported to your compiler
 #endif
Index: smp.h
===================================================================
RCS file: /home/cvs/src/sys/amd64/include/smp.h,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L sys/amd64/include/smp.h -L sys/amd64/include/smp.h -u -r1.1.1.1 -r1.2
--- sys/amd64/include/smp.h
+++ sys/amd64/include/smp.h
@@ -6,7 +6,7 @@
  * this stuff is worth it, you can buy me a beer in return.   Poul-Henning Kamp
  * ----------------------------------------------------------------------------
  *
- * $FreeBSD: src/sys/amd64/include/smp.h,v 1.84 2005/04/30 20:00:58 dwhite Exp $
+ * $FreeBSD: src/sys/amd64/include/smp.h,v 1.91 2007/09/20 20:38:43 attilio Exp $
  *
  */
 
@@ -23,6 +23,7 @@
 #include <machine/frame.h>
 #include <machine/intr_machdep.h>
 #include <machine/apicvar.h>
+#include <machine/pcb.h>
 
 /* global symbols in mpboot.S */
 extern char			mptramp_start[];
@@ -33,28 +34,31 @@
 extern int			mp_naps;
 extern int			boot_cpu_id;
 extern struct pcb		stoppcbs[];
-extern struct mtx		smp_tlb_mtx;
+extern int			cpu_apic_ids[];
 
 /* IPI handlers */
 inthand_t
 	IDTVEC(invltlb),	/* TLB shootdowns - global */
 	IDTVEC(invlpg),		/* TLB shootdowns - 1 page */
 	IDTVEC(invlrng),	/* TLB shootdowns - page range */
+	IDTVEC(invlcache),	/* Write back and invalidate cache */
 	IDTVEC(ipi_intr_bitmap_handler), /* Bitmap based IPIs */ 
 	IDTVEC(cpustop),	/* CPU stops & waits to be restarted */
 	IDTVEC(rendezvous);	/* handle CPU rendezvous */
 
 /* functions in mp_machdep.c */
 void	cpu_add(u_int apic_id, char boot_cpu);
+void	cpustop_handler(void);
 void	init_secondary(void);
 void	ipi_selected(u_int cpus, u_int ipi);
 void	ipi_all(u_int ipi);
 void	ipi_all_but_self(u_int ipi);
 void	ipi_self(u_int ipi);
-void 	ipi_bitmap_handler(struct clockframe frame);
+void 	ipi_bitmap_handler(struct trapframe frame);
 u_int	mp_bootaddress(u_int);
 int	mp_grab_cpu_hlt(void);
 void	mp_topology(void);
+void	smp_cache_flush(void);
 void	smp_invlpg(vm_offset_t addr);
 void	smp_masked_invlpg(u_int mask, vm_offset_t addr);
 void	smp_invlpg_range(vm_offset_t startva, vm_offset_t endva);
@@ -63,9 +67,8 @@
 void	smp_invltlb(void);
 void	smp_masked_invltlb(u_int mask);
 
-#ifdef KDB_STOP_NMI
-int ipi_nmi_handler(void);
-void ipi_nmi_selected(u_int32_t cpus);
+#ifdef STOP_NMI
+int	ipi_nmi_handler(void);
 #endif
 
 #endif /* !LOCORE */
Index: param.h
===================================================================
RCS file: /home/cvs/src/sys/amd64/include/param.h,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L sys/amd64/include/param.h -L sys/amd64/include/param.h -u -r1.1.1.1 -r1.2
--- sys/amd64/include/param.h
+++ sys/amd64/include/param.h
@@ -36,7 +36,7 @@
  * SUCH DAMAGE.
  *
  *	@(#)param.h	8.1 (Berkeley) 6/10/93
- * $FreeBSD: src/sys/amd64/include/param.h,v 1.18 2005/06/29 15:13:25 jhb Exp $
+ * $FreeBSD: src/sys/amd64/include/param.h,v 1.20 2006/01/09 06:05:56 imp Exp $
  */
 
 /*
@@ -64,15 +64,11 @@
 #define	_ALIGNED_POINTER(p,t)	((((u_long)(p)) & (sizeof(t)-1)) == 0)
 #endif
 
-#ifndef _MACHINE
-#define	_MACHINE	amd64
-#endif
-#ifndef _MACHINE_ARCH
-#define	_MACHINE_ARCH	amd64
-#endif
-
 #ifndef _NO_NAMESPACE_POLLUTION
 
+#define __HAVE_ACPI
+#define __PCI_REROUTE_INTERRUPT
+
 #ifndef _MACHINE_PARAM_H_
 #define	_MACHINE_PARAM_H_
 
Index: trap.h
===================================================================
RCS file: /home/cvs/src/sys/amd64/include/trap.h,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L sys/amd64/include/trap.h -L sys/amd64/include/trap.h -u -r1.1.1.1 -r1.2
--- sys/amd64/include/trap.h
+++ sys/amd64/include/trap.h
@@ -30,7 +30,7 @@
  * SUCH DAMAGE.
  *
  *	from: @(#)trap.h	5.4 (Berkeley) 5/9/91
- * $FreeBSD: src/sys/amd64/include/trap.h,v 1.14 2004/04/05 21:25:51 imp Exp $
+ * $FreeBSD: src/sys/amd64/include/trap.h,v 1.15 2006/03/14 00:01:22 peter Exp $
  */
 
 #ifndef _MACHINE_TRAP_H_
@@ -72,16 +72,6 @@
 #define	    ILL_ALIGN_FAULT	T_ALIGNFLT
 #define	    ILL_FPOP_FAULT	T_FPOPFLT	/* coprocessor operand fault */
 
-/* portable macros for SIGFPE/ARITHTRAP */
-#define FPE_INTOVF	1	/* integer overflow */
-#define FPE_INTDIV	2	/* integer divide by zero */
-#define FPE_FLTDIV	3	/* floating point divide by zero */
-#define FPE_FLTOVF	4	/* floating point overflow */
-#define FPE_FLTUND	5	/* floating point underflow */
-#define FPE_FLTRES	6	/* floating point inexact result */
-#define FPE_FLTINV	7	/* invalid floating point operation */
-#define FPE_FLTSUB	8	/* subscript out of range */
-
 /* old FreeBSD macros, deprecated */
 #define	FPE_INTOVF_TRAP	0x1	/* integer overflow */
 #define	FPE_INTDIV_TRAP	0x2	/* integer divide by zero */
Index: asm.h
===================================================================
RCS file: /home/cvs/src/sys/amd64/include/asm.h,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L sys/amd64/include/asm.h -L sys/amd64/include/asm.h -u -r1.1.1.1 -r1.2
--- sys/amd64/include/asm.h
+++ sys/amd64/include/asm.h
@@ -30,7 +30,7 @@
  * SUCH DAMAGE.
  *
  *	from: @(#)DEFS.h	5.1 (Berkeley) 4/23/90
- * $FreeBSD: src/sys/amd64/include/asm.h,v 1.17 2005/04/10 20:49:21 alc Exp $
+ * $FreeBSD: src/sys/amd64/include/asm.h,v 1.18 2007/08/22 04:26:07 jkoshy Exp $
  */
 
 #ifndef _MACHINE_ASM_H_
@@ -77,6 +77,8 @@
 #define	ENTRY(x)	_ENTRY(x)
 #endif
 
+#define	END(x)		.size x, . - x
+
 #define RCSID(x)	.text; .asciz x
 
 #undef __FBSDID
Index: reg.h
===================================================================
RCS file: /home/cvs/src/sys/amd64/include/reg.h,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L sys/amd64/include/reg.h -L sys/amd64/include/reg.h -u -r1.1.1.1 -r1.2
--- sys/amd64/include/reg.h
+++ sys/amd64/include/reg.h
@@ -31,7 +31,7 @@
  * SUCH DAMAGE.
  *
  *	from: @(#)reg.h	5.5 (Berkeley) 1/18/91
- * $FreeBSD: src/sys/amd64/include/reg.h,v 1.35 2004/04/05 23:55:14 imp Exp $
+ * $FreeBSD: src/sys/amd64/include/reg.h,v 1.38 2006/11/17 20:27:01 jhb Exp $
  */
 
 #ifndef _MACHINE_REG_H_
@@ -92,11 +92,26 @@
 				/* Index 8-15: reserved */
 };
 
-#define DBREG_DR7_EXEC      0x00      /* break on execute       */
-#define DBREG_DR7_WRONLY    0x01      /* break on write         */
-#define DBREG_DR7_RDWR      0x03      /* break on read or write */
-#define DBREG_DRX(d,x) ((d)->dr[(x)]) /* reference dr0 - dr15 by
-                                         register number */
+#define	DBREG_DR7_LOCAL_ENABLE	0x01
+#define	DBREG_DR7_GLOBAL_ENABLE	0x02
+#define	DBREG_DR7_LEN_1		0x00	/* 1 byte length          */
+#define	DBREG_DR7_LEN_2		0x01
+#define	DBREG_DR7_LEN_4		0x03
+#define	DBREG_DR7_LEN_8		0x02
+#define	DBREG_DR7_EXEC		0x00	/* break on execute       */
+#define	DBREG_DR7_WRONLY	0x01	/* break on write         */
+#define	DBREG_DR7_RDWR		0x03	/* break on read or write */
+#define	DBREG_DR7_MASK(i)	((u_long)0xf << ((i) * 4 + 16) | 0x3 << (i) * 2)
+#define	DBREG_DR7_SET(i, len, access, enable)				\
+	((u_long)((len) << 2 | (access)) << ((i) * 4 + 16) | (enable) << (i) * 2)
+#define	DBREG_DR7_GD		0x2000
+#define	DBREG_DR7_ENABLED(d, i)	(((d) & 0x3 << (i) * 2) != 0)
+#define	DBREG_DR7_ACCESS(d, i)	((d) >> ((i) * 4 + 16) & 0x3)
+#define	DBREG_DR7_LEN(d, i)	((d) >> ((i) * 4 + 18) & 0x3)
+
+#define	DBREG_DRX(d,x)	((d)->dr[(x)])	/* reference dr0 - dr15 by
+					   register number */
+
 #ifdef _KERNEL
 /*
  * XXX these interfaces are MI, so they should be declared in a MI place.
Index: pci_cfgreg.h
===================================================================
RCS file: /home/cvs/src/sys/amd64/include/pci_cfgreg.h,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L sys/amd64/include/pci_cfgreg.h -L sys/amd64/include/pci_cfgreg.h -u -r1.1.1.1 -r1.2
--- sys/amd64/include/pci_cfgreg.h
+++ sys/amd64/include/pci_cfgreg.h
@@ -23,7 +23,7 @@
  * (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: src/sys/amd64/include/pci_cfgreg.h,v 1.13 2005/01/05 20:17:20 imp Exp $
+ * $FreeBSD: src/sys/amd64/include/pci_cfgreg.h,v 1.13.10.1 2007/12/06 08:25:43 jhb Exp $
  *
  */
 
@@ -37,11 +37,6 @@
 #define CONF1_ENABLE_MSK1  0x80000001ul
 #define CONF1_ENABLE_RES1  0x80000000ul
 
-#define CONF2_ENABLE_PORT  0x0cf8
-#define CONF2_FORWARD_PORT 0x0cfa
-#define CONF2_ENABLE_CHK   0x0e
-#define CONF2_ENABLE_RES   0x0e
-
 int		pci_cfgregopen(void);
 u_int32_t	pci_cfgregread(int bus, int slot, int func, int reg, int bytes);
 void		pci_cfgregwrite(int bus, int slot, int func, int reg, u_int32_t data, int bytes);
Index: segments.h
===================================================================
RCS file: /home/cvs/src/sys/amd64/include/segments.h,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L sys/amd64/include/segments.h -L sys/amd64/include/segments.h -u -r1.1.1.1 -r1.2
--- sys/amd64/include/segments.h
+++ sys/amd64/include/segments.h
@@ -31,7 +31,7 @@
  * SUCH DAMAGE.
  *
  *	from: @(#)segments.h	7.1 (Berkeley) 5/9/91
- * $FreeBSD: src/sys/amd64/include/segments.h,v 1.38 2004/04/05 21:25:51 imp Exp $
+ * $FreeBSD: src/sys/amd64/include/segments.h,v 1.39 2007/03/30 00:06:21 jkim Exp $
  */
 
 #ifndef _MACHINE_SEGMENTS_H_
@@ -200,9 +200,10 @@
 #define	GUCODE32_SEL	3	/* User 32 bit code Descriptor */
 #define	GUDATA_SEL	4	/* User 32/64 bit Data Descriptor */
 #define	GUCODE_SEL	5	/* User 64 bit Code Descriptor */
-#define	GPROC0_SEL	6	/* TSS for entering kernel etc  */
+#define	GPROC0_SEL	6	/* TSS for entering kernel etc */
 /* slot 6 is second half of GPROC0_SEL */
-#define	NGDT 		8
+#define	GUGS32_SEL	8	/* User 32 bit GS Descriptor */
+#define	NGDT 		9
 
 #ifdef _KERNEL
 extern struct user_segment_descriptor gdt[];
Index: mptable.h
===================================================================
RCS file: /home/cvs/src/sys/amd64/include/mptable.h,v
retrieving revision 1.2
retrieving revision 1.3
diff -L sys/amd64/include/mptable.h -L sys/amd64/include/mptable.h -u -r1.2 -r1.3
--- sys/amd64/include/mptable.h
+++ sys/amd64/include/mptable.h
@@ -22,7 +22,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD: src/sys/amd64/include/mptable.h,v 1.222.2.1 2006/03/01 06:02:42 sam Exp $
+ * $FreeBSD: src/sys/amd64/include/mptable.h,v 1.223 2006/03/01 05:59:56 sam Exp $
  */
 
 #ifndef __MACHINE_MPTABLE_H__
Index: md_var.h
===================================================================
RCS file: /home/cvs/src/sys/amd64/include/md_var.h,v
retrieving revision 1.2
retrieving revision 1.3
diff -L sys/amd64/include/md_var.h -L sys/amd64/include/md_var.h -u -r1.2 -r1.3
--- sys/amd64/include/md_var.h
+++ sys/amd64/include/md_var.h
@@ -26,7 +26,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD: src/sys/amd64/include/md_var.h,v 1.75.8.3 2006/07/24 23:28:08 peter Exp $
+ * $FreeBSD: src/sys/amd64/include/md_var.h,v 1.81 2007/05/19 05:03:59 kan Exp $
  */
 
 #ifndef _MACHINE_MD_VAR_H_
@@ -57,8 +57,6 @@
 extern	uint64_t *vm_page_dump;
 extern	int	vm_page_dump_size;
 
-extern	struct pcpu __pcpu[];
-
 typedef void alias_for_inthand_t(u_int cs, u_int ef, u_int esp, u_int ss);
 struct	thread;
 struct	reg;
Index: _types.h
===================================================================
RCS file: /home/cvs/src/sys/amd64/include/_types.h,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L sys/amd64/include/_types.h -L sys/amd64/include/_types.h -u -r1.1.1.1 -r1.2
--- sys/amd64/include/_types.h
+++ sys/amd64/include/_types.h
@@ -33,7 +33,7 @@
  *
  *	From: @(#)ansi.h	8.2 (Berkeley) 1/4/94
  *	From: @(#)types.h	8.3 (Berkeley) 1/5/94
- * $FreeBSD: src/sys/amd64/include/_types.h,v 1.9 2005/07/02 23:13:30 thompsa Exp $
+ * $FreeBSD: src/sys/amd64/include/_types.h,v 1.11 2006/01/09 06:05:56 imp Exp $
  */
 
 #ifndef _MACHINE__TYPES_H_
Index: kdb.h
===================================================================
RCS file: /home/cvs/src/sys/amd64/include/kdb.h,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L sys/amd64/include/kdb.h -L sys/amd64/include/kdb.h -u -r1.1.1.1 -r1.2
--- sys/amd64/include/kdb.h
+++ sys/amd64/include/kdb.h
@@ -23,7 +23,7 @@
  * (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: src/sys/amd64/include/kdb.h,v 1.2 2005/01/05 20:17:20 imp Exp $
+ * $FreeBSD: src/sys/amd64/include/kdb.h,v 1.4 2007/06/09 21:55:16 marcel Exp $
  */
 
 #ifndef _MACHINE_KDB_H_
@@ -32,6 +32,8 @@
 #include <machine/frame.h>
 #include <machine/psl.h>
 
+#define	KDB_STOPPEDPCB(pc)	&stoppcbs[pc->pc_cpuid]
+
 static __inline void
 kdb_cpu_clear_singlestep(void)
 {
@@ -45,6 +47,11 @@
 }
 
 static __inline void
+kdb_cpu_sync_icache(unsigned char *addr, size_t size)
+{
+}
+
+static __inline void
 kdb_cpu_trap(int type, int code)
 {
 }
Index: legacyvar.h
===================================================================
RCS file: /home/cvs/src/sys/amd64/include/legacyvar.h,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L sys/amd64/include/legacyvar.h -L sys/amd64/include/legacyvar.h -u -r1.1.1.1 -r1.2
--- sys/amd64/include/legacyvar.h
+++ sys/amd64/include/legacyvar.h
@@ -23,19 +23,21 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD: src/sys/amd64/include/legacyvar.h,v 1.6.2.1 2005/09/18 02:55:10 imp Exp $
+ * $FreeBSD: src/sys/amd64/include/legacyvar.h,v 1.8 2007/09/30 11:05:13 marius Exp $
  */
 
 #ifndef _MACHINE_LEGACYVAR_H_
 #define	_MACHINE_LEGACYVAR_H_
 
 enum legacy_device_ivars {
+	LEGACY_IVAR_PCIDOMAIN,
 	LEGACY_IVAR_PCIBUS
 };
 
 #define LEGACY_ACCESSOR(var, ivar, type)				\
     __BUS_ACCESSOR(legacy, var, LEGACY, ivar, type)
 
+LEGACY_ACCESSOR(pcidomain,		PCIDOMAIN,	uint32_t)
 LEGACY_ACCESSOR(pcibus,			PCIBUS,		uint32_t)
 
 #undef LEGACY_ACCESSOR
Index: pmap.h
===================================================================
RCS file: /home/cvs/src/sys/amd64/include/pmap.h,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L sys/amd64/include/pmap.h -L sys/amd64/include/pmap.h -u -r1.1.1.1 -r1.2
--- sys/amd64/include/pmap.h
+++ sys/amd64/include/pmap.h
@@ -39,14 +39,14 @@
  *
  *	from: hp300: @(#)pmap.h	7.2 (Berkeley) 12/16/90
  *	from: @(#)pmap.h	7.4 (Berkeley) 5/12/91
- * $FreeBSD: src/sys/amd64/include/pmap.h,v 1.127 2005/06/29 22:28:45 peter Exp $
+ * $FreeBSD: src/sys/amd64/include/pmap.h,v 1.138 2006/12/05 11:31:33 ru Exp $
  */
 
 #ifndef _MACHINE_PMAP_H_
 #define	_MACHINE_PMAP_H_
 
 /*
- * Page-directory and page-table entires follow this format, with a few
+ * Page-directory and page-table entries follow this format, with a few
  * of the fields not present here and there, depending on a lot of things.
  */
 				/* ---- Intel Nomenclature ---- */
@@ -58,10 +58,12 @@
 #define PG_A		0x020	/* A	Accessed		*/
 #define	PG_M		0x040	/* D	Dirty			*/
 #define	PG_PS		0x080	/* PS	Page size (0=4k,1=4M)	*/
+#define	PG_PTE_PAT	0x080	/* PAT	PAT index		*/
 #define	PG_G		0x100	/* G	Global			*/
 #define	PG_AVAIL1	0x200	/*    /	Available for system	*/
 #define	PG_AVAIL2	0x400	/*   <	programmers use		*/
 #define	PG_AVAIL3	0x800	/*    \				*/
+#define	PG_PDE_PAT	0x1000	/* PAT	PAT index		*/
 #define	PG_NX		(1ul<<63) /* No-execute */
 
 
@@ -69,6 +71,7 @@
 #define PG_W		PG_AVAIL1	/* "Wired" pseudoflag */
 #define	PG_MANAGED	PG_AVAIL2
 #define	PG_FRAME	(0x000ffffffffff000ul)
+#define	PG_PS_FRAME	(0x000fffffffe00000ul)
 #define	PG_PROT		(PG_RW|PG_U)	/* all protection bits . */
 #define PG_N		(PG_NC_PWT|PG_NC_PCD)	/* Non-cacheable */
 
@@ -79,6 +82,8 @@
 #define PGEX_P		0x01	/* Protection violation vs. not present */
 #define PGEX_W		0x02	/* during a Write cycle */
 #define PGEX_U		0x04	/* access from User mode (UPL) */
+#define PGEX_RSV	0x08	/* reserved PTE field is non-zero */
+#define PGEX_I		0x10	/* during an instruction fetch */
 
 /*
  * Pte related macros.  This is complicated by having to deal with
@@ -97,9 +102,10 @@
 	((unsigned long)(l2) << PDRSHIFT) | \
 	((unsigned long)(l1) << PAGE_SHIFT))
 
-/* Initial number of kernel page tables */
+/* Initial number of kernel page tables. */
 #ifndef NKPT
-#define	NKPT		240	/* Enough for 16GB (2MB page tables) */
+/* 240 page tables needed to map 16G (120B "struct vm_page", 2M page tables). */
+#define	NKPT		240
 #endif
 
 #define NKPML4E		1		/* number of kernel PML4 slots */
@@ -171,13 +177,11 @@
 #ifdef _KERNEL
 /*
  * virtual address to page table entry and
- * to physical address. Likewise for alternate address space.
+ * to physical address.
  * Note: these work recursively, thus vtopte of a pte will give
  * the corresponding pde that in turn maps it.
  */
 pt_entry_t *vtopte(vm_offset_t);
-vm_paddr_t pmap_kextract(vm_offset_t);
-
 #define	vtophys(va)	pmap_kextract(((vm_offset_t) (va)))
 
 static __inline pt_entry_t
@@ -224,6 +228,7 @@
  * Pmap stuff
  */
 struct	pv_entry;
+struct	pv_chunk;
 
 struct md_page {
 	int pv_list_count;
@@ -233,7 +238,7 @@
 struct pmap {
 	struct mtx		pm_mtx;
 	pml4_entry_t		*pm_pml4;	/* KVA of level 4 page table */
-	TAILQ_HEAD(,pv_entry)	pm_pvlist;	/* list of mappings in pmap */
+	TAILQ_HEAD(,pv_chunk)	pm_pvchunk;	/* list of mappings in pmap */
 	u_int			pm_active;	/* active on cpus */
 	/* spare u_int here due to padding */
 	struct pmap_statistics	pm_stats;	/* pmap statistics */
@@ -259,15 +264,27 @@
 
 /*
  * For each vm_page_t, there is a list of all currently valid virtual
- * mappings of that page.  An entry is a pv_entry_t, the list is pv_table.
+ * mappings of that page.  An entry is a pv_entry_t, the list is pv_list.
  */
 typedef struct pv_entry {
-	pmap_t		pv_pmap;	/* pmap where mapping lies */
 	vm_offset_t	pv_va;		/* virtual address for mapping */
 	TAILQ_ENTRY(pv_entry)	pv_list;
-	TAILQ_ENTRY(pv_entry)	pv_plist;
 } *pv_entry_t;
 
+/*
+ * pv_entries are allocated in chunks per-process.  This avoids the
+ * need to track per-pmap assignments.
+ */
+#define	_NPCM	3
+#define	_NPCPV	168
+struct pv_chunk {
+	pmap_t			pc_pmap;
+	TAILQ_ENTRY(pv_chunk)	pc_list;
+	uint64_t		pc_map[_NPCM];	/* bitmap; 1 = free */
+	uint64_t		pc_spare[2];
+	struct pv_entry		pc_pventry[_NPCPV];
+};
+
 #ifdef	_KERNEL
 
 #define NPPROVMTRR		8
@@ -280,23 +297,30 @@
 
 extern caddr_t	CADDR1;
 extern pt_entry_t *CMAP1;
-extern vm_paddr_t avail_end;
 extern vm_paddr_t phys_avail[];
 extern vm_paddr_t dump_avail[];
 extern vm_offset_t virtual_avail;
 extern vm_offset_t virtual_end;
 
 #define	pmap_page_is_mapped(m)	(!TAILQ_EMPTY(&(m)->md.pv_list))
+#define	pmap_unmapbios(va, sz)	pmap_unmapdev((va), (sz))
 
 void	pmap_bootstrap(vm_paddr_t *);
+int	pmap_change_attr(vm_offset_t, vm_size_t, int);
+void	pmap_init_pat(void);
 void	pmap_kenter(vm_offset_t va, vm_paddr_t pa);
+void	pmap_kenter_attr(vm_offset_t va, vm_paddr_t pa, int mode);
 void	*pmap_kenter_temporary(vm_paddr_t pa, int i);
+vm_paddr_t pmap_kextract(vm_offset_t);
 void	pmap_kremove(vm_offset_t);
+void	*pmap_mapbios(vm_paddr_t, vm_size_t);
 void	*pmap_mapdev(vm_paddr_t, vm_size_t);
+void	*pmap_mapdev_attr(vm_paddr_t, vm_size_t, int);
 void	pmap_unmapdev(vm_offset_t, vm_size_t);
 void	pmap_invalidate_page(pmap_t, vm_offset_t);
 void	pmap_invalidate_range(pmap_t, vm_offset_t, vm_offset_t);
 void	pmap_invalidate_all(pmap_t);
+void	pmap_invalidate_cache(void);
 
 #endif /* _KERNEL */
 
Index: pcpu.h
===================================================================
RCS file: /home/cvs/src/sys/amd64/include/pcpu.h,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L sys/amd64/include/pcpu.h -L sys/amd64/include/pcpu.h -u -r1.1.1.1 -r1.2
--- sys/amd64/include/pcpu.h
+++ sys/amd64/include/pcpu.h
@@ -23,14 +23,14 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD: src/sys/amd64/include/pcpu.h,v 1.44 2005/03/11 22:16:09 peter Exp $
+ * $FreeBSD: src/sys/amd64/include/pcpu.h,v 1.48 2007/06/04 21:38:45 attilio Exp $
  */
 
 #ifndef _MACHINE_PCPU_H_
-#define _MACHINE_PCPU_H_
+#define	_MACHINE_PCPU_H_
 
 #ifndef _SYS_CDEFS_H_
-#error this file needs sys/cdefs.h as a prerequisite
+#error "sys/cdefs.h is a prerequisite for this file"
 #endif
 
 #ifdef _KERNEL
@@ -51,16 +51,17 @@
 	u_int	pc_apic_id;						\
 	u_int   pc_acpi_id		/* ACPI CPU id */
 
-#if defined(lint)
- 
+#ifdef lint
+
 extern struct pcpu *pcpup;
- 
-#define PCPU_GET(member)        (pcpup->pc_ ## member)
-#define PCPU_PTR(member)        (&pcpup->pc_ ## member)
-#define PCPU_SET(member,value)  (pcpup->pc_ ## member = (value))
- 
-#elif defined(__GNUCLIKE_ASM) && defined(__GNUCLIKE___TYPEOF) \
-    && defined(__GNUCLIKE___OFFSETOF)
+
+#define	PCPU_GET(member)	(pcpup->pc_ ## member)
+#define	PCPU_ADD(member, val)	(pcpup->pc_ ## member += (val))
+#define	PCPU_INC(member)	PCPU_ADD(member, 1)
+#define	PCPU_PTR(member)	(&pcpup->pc_ ## member)
+#define	PCPU_SET(member, val)	(pcpup->pc_ ## member = (val))
+
+#elif defined(__GNUCLIKE_ASM) && defined(__GNUCLIKE___TYPEOF)
 
 /*
  * Evaluates to the byte offset of the per-cpu variable name.
@@ -92,75 +93,96 @@
  * Evaluates to the value of the per-cpu variable name.
  */
 #define	__PCPU_GET(name) __extension__ ({				\
-	__pcpu_type(name) __result;					\
+	__pcpu_type(name) __res;					\
+	struct __s {							\
+		u_char	__b[MIN(sizeof(__pcpu_type(name)), 8)];		\
+	} __s;								\
 									\
-	if (sizeof(__result) == 1) {					\
-		u_char __b;						\
-		__asm __volatile("movb %%gs:%1,%0"			\
-		    : "=r" (__b)					\
-		    : "m" (*(u_char *)(__pcpu_offset(name))));		\
-		__result = *(__pcpu_type(name) *)&__b;			\
-	} else if (sizeof(__result) == 2) {				\
-		u_short __w;						\
-		__asm __volatile("movw %%gs:%1,%0"			\
-		    : "=r" (__w)					\
-		    : "m" (*(u_short *)(__pcpu_offset(name))));		\
-		__result = *(__pcpu_type(name) *)&__w;			\
-	} else if (sizeof(__result) == 4) {				\
-		u_int __i;						\
-		__asm __volatile("movl %%gs:%1,%0"			\
-		    : "=r" (__i)					\
-		    : "m" (*(u_int *)(__pcpu_offset(name))));		\
-		__result = *(__pcpu_type(name) *)&__i;			\
-	} else if (sizeof(__result) == 8) {				\
-		u_long __l;						\
-		__asm __volatile("movq %%gs:%1,%0"			\
-		    : "=r" (__l)					\
-		    : "m" (*(u_long *)(__pcpu_offset(name))));		\
-		__result = *(__pcpu_type(name) *)&__l;			\
+	if (sizeof(__res) == 1 || sizeof(__res) == 2 ||			\
+	    sizeof(__res) == 4 || sizeof(__res) == 8) {			\
+		__asm __volatile("mov %%gs:%1,%0"			\
+		    : "=r" (__s)					\
+		    : "m" (*(struct __s *)(__pcpu_offset(name))));	\
+		*(struct __s *)(void *)&__res = __s;			\
 	} else {							\
-		__result = *__PCPU_PTR(name);				\
+		__res = *__PCPU_PTR(name);				\
 	}								\
-									\
-	__result;							\
+	__res;								\
 })
 
 /*
+ * Adds the value to the per-cpu counter name.  The implementation
+ * must be atomic with respect to interrupts.
+ */
+#define	__PCPU_ADD(name, val) do {					\
+	__pcpu_type(name) __val;					\
+	struct __s {							\
+		u_char	__b[MIN(sizeof(__pcpu_type(name)), 8)];		\
+	} __s;								\
+									\
+	__val = (val);							\
+	if (sizeof(__val) == 1 || sizeof(__val) == 2 ||			\
+	    sizeof(__val) == 4 || sizeof(__val) == 8) {			\
+		__s = *(struct __s *)(void *)&__val;			\
+		__asm __volatile("add %1,%%gs:%0"			\
+		    : "=m" (*(struct __s *)(__pcpu_offset(name)))	\
+		    : "r" (__s));					\
+	} else								\
+		*__PCPU_PTR(name) += __val;				\
+} while (0)
+
+/*
+ * Increments the value of the per-cpu counter name.  The implementation
+ * must be atomic with respect to interrupts.
+ */
+#define	__PCPU_INC(name) do {						\
+	CTASSERT(sizeof(__pcpu_type(name)) == 1 ||			\
+	    sizeof(__pcpu_type(name)) == 2 ||				\
+	    sizeof(__pcpu_type(name)) == 4 ||				\
+	    sizeof(__pcpu_type(name)) == 8);				\
+	if (sizeof(__pcpu_type(name)) == 1) {				\
+		__asm __volatile("incb %%gs:%0"				\
+		    : "=m" (*(__pcpu_type(name) *)(__pcpu_offset(name)))\
+		    : "m" (*(__pcpu_type(name) *)(__pcpu_offset(name))));\
+	} else if (sizeof(__pcpu_type(name)) == 2) {			\
+		__asm __volatile("incw %%gs:%0"				\
+		    : "=m" (*(__pcpu_type(name) *)(__pcpu_offset(name)))\
+		    : "m" (*(__pcpu_type(name) *)(__pcpu_offset(name))));\
+	} else if (sizeof(__pcpu_type(name)) == 4) {			\
+		__asm __volatile("incl %%gs:%0"				\
+		    : "=m" (*(__pcpu_type(name) *)(__pcpu_offset(name)))\
+		    : "m" (*(__pcpu_type(name) *)(__pcpu_offset(name))));\
+	} else if (sizeof(__pcpu_type(name)) == 8) {			\
+		__asm __volatile("incq %%gs:%0"				\
+		    : "=m" (*(__pcpu_type(name) *)(__pcpu_offset(name)))\
+		    : "m" (*(__pcpu_type(name) *)(__pcpu_offset(name))));\
+	}								\
+} while (0)
+
+/*
  * Sets the value of the per-cpu variable name to value val.
  */
 #define	__PCPU_SET(name, val) {						\
-	__pcpu_type(name) __val = (val);				\
+	__pcpu_type(name) __val;					\
+	struct __s {							\
+		u_char	__b[MIN(sizeof(__pcpu_type(name)), 8)];		\
+	} __s;								\
 									\
-	if (sizeof(__val) == 1) {					\
-		u_char __b;						\
-		__b = *(u_char *)&__val;				\
-		__asm __volatile("movb %1,%%gs:%0"			\
-		    : "=m" (*(u_char *)(__pcpu_offset(name)))		\
-		    : "r" (__b));					\
-	} else if (sizeof(__val) == 2) {				\
-		u_short __w;						\
-		__w = *(u_short *)&__val;				\
-		__asm __volatile("movw %1,%%gs:%0"			\
-		    : "=m" (*(u_short *)(__pcpu_offset(name)))		\
-		    : "r" (__w));					\
-	} else if (sizeof(__val) == 4) {				\
-		u_int __i;						\
-		__i = *(u_int *)&__val;					\
-		__asm __volatile("movl %1,%%gs:%0"			\
-		    : "=m" (*(u_int *)(__pcpu_offset(name)))		\
-		    : "r" (__i));					\
-	} else if (sizeof(__val) == 8) {				\
-		u_long __l;						\
-		__l = *(u_long *)&__val;				\
-		__asm __volatile("movq %1,%%gs:%0"			\
-		    : "=m" (*(u_long *)(__pcpu_offset(name)))		\
-		    : "r" (__l));					\
+	__val = (val);							\
+	if (sizeof(__val) == 1 || sizeof(__val) == 2 ||			\
+	    sizeof(__val) == 4 || sizeof(__val) == 8) {			\
+		__s = *(struct __s *)(void *)&__val;			\
+		__asm __volatile("mov %1,%%gs:%0"			\
+		    : "=m" (*(struct __s *)(__pcpu_offset(name)))	\
+		    : "r" (__s));					\
 	} else {							\
 		*__PCPU_PTR(name) = __val;				\
 	}								\
 }
 
 #define	PCPU_GET(member)	__PCPU_GET(pc_ ## member)
+#define	PCPU_ADD(member, val)	__PCPU_ADD(pc_ ## member, val)
+#define	PCPU_INC(member)	__PCPU_INC(pc_ ## member)
 #define	PCPU_PTR(member)	__PCPU_PTR(pc_ ## member)
 #define	PCPU_SET(member, val)	__PCPU_SET(pc_ ## member, val)
 
@@ -172,12 +194,14 @@
 	__asm __volatile("movq %%gs:0,%0" : "=r" (td));
 	return (td);
 }
-#define	curthread (__curthread())
+#define	curthread		(__curthread())
 
-#else
-#error this file needs to be ported to your compiler
-#endif
+#else /* !lint || defined(__GNUCLIKE_ASM) && defined(__GNUCLIKE___TYPEOF) */
+
+#error "this file needs to be ported to your compiler"
+
+#endif /* lint, etc. */
 
-#endif	/* _KERNEL */
+#endif /* _KERNEL */
 
-#endif	/* ! _MACHINE_PCPU_H_ */
+#endif /* !_MACHINE_PCPU_H_ */
Index: elf.h
===================================================================
RCS file: /home/cvs/src/sys/amd64/include/elf.h,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L sys/amd64/include/elf.h -L sys/amd64/include/elf.h -u -r1.1.1.1 -r1.2
--- sys/amd64/include/elf.h
+++ sys/amd64/include/elf.h
@@ -23,7 +23,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD: src/sys/amd64/include/elf.h,v 1.18 2004/08/03 08:21:48 dfr Exp $
+ * $FreeBSD: src/sys/amd64/include/elf.h,v 1.19 2006/10/04 21:37:09 jb Exp $
  */
 
 #ifndef _MACHINE_ELF_H_
@@ -108,31 +108,6 @@
  * Relocation types.
  */
 
-#define	R_X86_64_NONE	0	/* No relocation. */
-#define	R_X86_64_64	1	/* Add 64 bit symbol value. */
-#define	R_X86_64_PC32	2	/* PC-relative 32 bit signed sym value. */
-#define	R_X86_64_GOT32	3	/* PC-relative 32 bit GOT offset. */
-#define	R_X86_64_PLT32	4	/* PC-relative 32 bit PLT offset. */
-#define	R_X86_64_COPY	5	/* Copy data from shared object. */
-#define	R_X86_64_GLOB_DAT 6	/* Set GOT entry to data address. */
-#define	R_X86_64_JMP_SLOT 7	/* Set GOT entry to code address. */
-#define	R_X86_64_RELATIVE 8	/* Add load address of shared object. */
-#define	R_X86_64_GOTPCREL 9	/* Add 32 bit signed pcrel offset to GOT. */
-#define	R_X86_64_32	10	/* Add 32 bit zero extended symbol value */
-#define	R_X86_64_32S	11	/* Add 32 bit sign extended symbol value */
-#define	R_X86_64_16	12	/* Add 16 bit zero extended symbol value */
-#define	R_X86_64_PC16	13	/* Add 16 bit signed extended pc relative symbol value */
-#define	R_X86_64_8	14	/* Add 8 bit zero extended symbol value */
-#define	R_X86_64_PC8	15	/* Add 8 bit signed extended pc relative symbol value */
-#define	R_X86_64_DTPMOD64 16	/* ID of module containing symbol */
-#define	R_X86_64_DTPOFF64 17	/* Offset in TLS block */
-#define	R_X86_64_TPOFF64 18	/* Offset in static TLS block */
-#define	R_X86_64_TLSGD	19	/* PC relative offset to GD GOT entry */
-#define	R_X86_64_TLSLD	20	/* PC relative offset to LD GOT entry */
-#define	R_X86_64_DTPOFF32 21	/* Offset in TLS block */
-#define	R_X86_64_GOTTPOFF 22	/* PC relative offset to IE GOT entry */
-#define	R_X86_64_TPOFF32 23	/* Offset in static TLS block */
-
 #define	R_X86_64_COUNT	24	/* Count of defined relocation types. */
 
 /* Define "machine" characteristics */
Index: vmparam.h
===================================================================
RCS file: /home/cvs/src/sys/amd64/include/vmparam.h,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L sys/amd64/include/vmparam.h -L sys/amd64/include/vmparam.h -u -r1.1.1.1 -r1.2
--- sys/amd64/include/vmparam.h
+++ sys/amd64/include/vmparam.h
@@ -38,7 +38,7 @@
  * SUCH DAMAGE.
  *
  *	from: @(#)vmparam.h	5.9 (Berkeley) 5/12/91
- * $FreeBSD: src/sys/amd64/include/vmparam.h,v 1.45 2004/10/27 17:21:15 peter Exp $
+ * $FreeBSD: src/sys/amd64/include/vmparam.h,v 1.49 2007/09/25 06:25:04 alc Exp $
  */
 
 
@@ -88,6 +88,50 @@
 #define	UMA_MD_SMALL_ALLOC
 
 /*
+ * The physical address space is densely populated.
+ */
+#define	VM_PHYSSEG_DENSE
+
+/*
+ * The number of PHYSSEG entries must be one greater than the number
+ * of phys_avail entries because the phys_avail entry that spans the
+ * largest physical address that is accessible by ISA DMA is split
+ * into two PHYSSEG entries. 
+ */
+#define	VM_PHYSSEG_MAX		31
+
+/*
+ * Create three free page pools: VM_FREEPOOL_DEFAULT is the default pool
+ * from which physical pages are allocated and VM_FREEPOOL_DIRECT is
+ * the pool from which physical pages for page tables and small UMA
+ * objects are allocated.
+ */
+#define	VM_NFREEPOOL		3
+#define	VM_FREEPOOL_CACHE	2
+#define	VM_FREEPOOL_DEFAULT	0
+#define	VM_FREEPOOL_DIRECT	1
+
+/*
+ * Create two free page lists: VM_FREELIST_DEFAULT is for physical
+ * pages that are above the largest physical address that is
+ * accessible by ISA DMA and VM_FREELIST_ISADMA is for physical pages
+ * that are below that address.
+ */
+#define	VM_NFREELIST		2
+#define	VM_FREELIST_DEFAULT	0
+#define	VM_FREELIST_ISADMA	1
+
+/*
+ * An allocation size of 16MB is supported in order to optimize the
+ * use of the direct map by UMA.  Specifically, a cache line contains
+ * at most 8 PDEs, collectively mapping 16MB of physical memory.  By
+ * reducing the number of distinct 16MB "pages" that are used by UMA,
+ * the physical memory allocator reduces the likelihood of both 2MB
+ * page TLB misses and cache misses caused by 2MB page TLB misses.
+ */
+#define	VM_NFREEORDER		13
+
+/*
  * Virtual addresses of things.  Derived from the page directory and
  * page table indexes from pmap.h for precision.
  * Because of the page that is both a PD and PT, it looks a little
@@ -122,7 +166,8 @@
 
 /*
  * How many physical pages per KVA page allocated.
- * min(max(VM_KMEM_SIZE, Physical memory/VM_KMEM_SIZE_SCALE), VM_KMEM_SIZE_MAX)
+ * min(max(max(VM_KMEM_SIZE, Physical memory/VM_KMEM_SIZE_SCALE),
+ *     VM_KMEM_SIZE_MIN), VM_KMEM_SIZE_MAX)
  * is the total KVA space allocated for kmem_map.
  */
 #ifndef VM_KMEM_SIZE_SCALE
Index: apicvar.h
===================================================================
RCS file: /home/cvs/src/sys/amd64/include/apicvar.h,v
retrieving revision 1.2
retrieving revision 1.3
diff -L sys/amd64/include/apicvar.h -L sys/amd64/include/apicvar.h -u -r1.2 -r1.3
--- sys/amd64/include/apicvar.h
+++ sys/amd64/include/apicvar.h
@@ -26,7 +26,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD: src/sys/amd64/include/apicvar.h,v 1.13.2.2 2006/03/07 18:33:20 jhb Exp $
+ * $FreeBSD: src/sys/amd64/include/apicvar.h,v 1.25 2007/05/08 22:01:03 jhb Exp $
  */
 
 #ifndef _MACHINE_APICVAR_H_
@@ -79,6 +79,7 @@
  * I/O device!
  */
 
+#define	MAX_APIC_ID	0xfe
 #define	APIC_ID_ALL	0xff
 
 /* I/O Interrupts are used for external devices such as ISA, PCI, etc. */
@@ -118,8 +119,9 @@
 #define	IPI_INVLTLB	(APIC_IPI_INTS + 1)	/* TLB Shootdown IPIs */
 #define	IPI_INVLPG	(APIC_IPI_INTS + 2)
 #define	IPI_INVLRNG	(APIC_IPI_INTS + 3)
+#define	IPI_INVLCACHE	(APIC_IPI_INTS + 4)
 /* Vector to handle bitmap based IPIs */
-#define	IPI_BITMAP_VECTOR	(APIC_IPI_INTS + 5) 
+#define	IPI_BITMAP_VECTOR	(APIC_IPI_INTS + 6) 
 
 /* IPIs handled by IPI_BITMAPED_VECTOR  (XXX ups is there a better place?) */
 #define	IPI_AST		0 	/* Generate software trap. */
@@ -127,7 +129,7 @@
 #define IPI_BITMAP_LAST IPI_PREEMPT
 #define IPI_IS_BITMAPED(x) ((x) <= IPI_BITMAP_LAST)
 
-#define	IPI_STOP	(APIC_IPI_INTS + 6)	/* Stop CPU until restarted. */
+#define	IPI_STOP	(APIC_IPI_INTS + 7)	/* Stop CPU until restarted. */
 
 /*
  * The spurious interrupt can share the priority class with the IPIs since
@@ -173,12 +175,16 @@
 	IDTVEC(apic_isr4), IDTVEC(apic_isr5), IDTVEC(apic_isr6),
 	IDTVEC(apic_isr7), IDTVEC(spuriousint), IDTVEC(timerint);
 
+extern vm_paddr_t lapic_paddr;
+
 u_int	apic_alloc_vector(u_int irq);
+u_int	apic_alloc_vectors(u_int *irqs, u_int count, u_int align);
+void	apic_disable_vector(u_int vector);
 void	apic_enable_vector(u_int vector);
 void	apic_free_vector(u_int vector, u_int irq);
 u_int	apic_idt_to_irq(u_int vector);
 void	apic_register_enumerator(struct apic_enumerator *enumerator);
-void	*ioapic_create(uintptr_t addr, int32_t id, int intbase);
+void	*ioapic_create(vm_paddr_t addr, int32_t apic_id, int intbase);
 int	ioapic_disable_pin(void *cookie, u_int pin);
 int	ioapic_get_vector(void *cookie, u_int pin);
 void	ioapic_register(void *cookie);
@@ -195,13 +201,13 @@
 void	lapic_dump(const char *str);
 void	lapic_eoi(void);
 int	lapic_id(void);
-void	lapic_init(uintptr_t addr);
+void	lapic_init(vm_paddr_t addr);
 int	lapic_intr_pending(u_int vector);
 void	lapic_ipi_raw(register_t icrlo, u_int dest);
 void	lapic_ipi_vectored(u_int vector, int dest);
 int	lapic_ipi_wait(int delay);
-void	lapic_handle_intr(void *cookie, struct intrframe frame);
-void	lapic_handle_timer(struct clockframe frame);
+void	lapic_handle_intr(int vector, struct trapframe *frame);
+void	lapic_handle_timer(struct trapframe *frame);
 void	lapic_set_logical_id(u_int apic_id, u_int cluster, u_int cluster_id);
 int	lapic_set_lvt_mask(u_int apic_id, u_int lvt, u_char masked);
 int	lapic_set_lvt_mode(u_int apic_id, u_int lvt, u_int32_t mode);
@@ -210,7 +216,7 @@
 int	lapic_set_lvt_triggermode(u_int apic_id, u_int lvt,
 	    enum intr_trigger trigger);
 void	lapic_set_tpr(u_int vector);
-void	lapic_setup(void);
+void	lapic_setup(int boot);
 int	lapic_setup_clock(void);
 
 #endif /* !LOCORE */
Index: clock.h
===================================================================
RCS file: /home/cvs/src/sys/amd64/include/clock.h,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L sys/amd64/include/clock.h -L sys/amd64/include/clock.h -u -r1.1.1.1 -r1.2
--- sys/amd64/include/clock.h
+++ sys/amd64/include/clock.h
@@ -3,7 +3,7 @@
  * Garrett Wollman, September 1994.
  * This file is in the public domain.
  *
- * $FreeBSD: src/sys/amd64/include/clock.h,v 1.50 2005/01/05 20:17:20 imp Exp $
+ * $FreeBSD: src/sys/amd64/include/clock.h,v 1.54.2.1 2007/10/29 22:26:33 peter Exp $
  */
 
 #ifndef _MACHINE_CLOCK_H_
@@ -14,9 +14,7 @@
  * i386 to clock driver interface.
  * XXX large parts of the driver and its interface are misplaced.
  */
-extern int	adjkerntz;
 extern int	clkintr_pending;
-extern int	disable_rtc_set;
 extern int	pscnt;
 extern int	psdiv;
 extern int	statclock_disable;
@@ -24,16 +22,17 @@
 extern int	timer0_max_count;
 extern uint64_t	tsc_freq;
 extern int	tsc_is_broken;
-extern int	wall_cmos_clock;
+
+void	i8254_init(void);
 
 /*
  * Driver to clock driver interface.
  */
-struct clockframe;
 
 int	acquire_timer2(int mode);
 int	release_timer2(void);
-int	rtcin(int val);
+int	rtcin(int reg);
+void	writertc(int reg, unsigned char val);
 int	sysbeep(int pitch, int period);
 void	init_TSC(void);
 void	init_TSC_tc(void);
Index: pcb.h
===================================================================
RCS file: /home/cvs/src/sys/amd64/include/pcb.h,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L sys/amd64/include/pcb.h -L sys/amd64/include/pcb.h -u -r1.1.1.1 -r1.2
--- sys/amd64/include/pcb.h
+++ sys/amd64/include/pcb.h
@@ -31,7 +31,7 @@
  * SUCH DAMAGE.
  *
  *	from: @(#)pcb.h	5.10 (Berkeley) 5/12/91
- * $FreeBSD: src/sys/amd64/include/pcb.h,v 1.60.8.1 2005/11/15 00:26:00 peter Exp $
+ * $FreeBSD: src/sys/amd64/include/pcb.h,v 1.63 2007/03/30 00:06:21 jkim Exp $
  */
 
 #ifndef _AMD64_PCB_H_
@@ -41,9 +41,9 @@
  * AMD64 process control block
  */
 #include <machine/fpu.h>
+#include <machine/segments.h>
 
 struct pcb {
-	register_t	__pad0[8];	/* Spare */
 	register_t	pcb_cr3;
 	register_t	pcb_r15;
 	register_t	pcb_r14;
@@ -53,7 +53,6 @@
 	register_t	pcb_rsp;
 	register_t	pcb_rbx;
 	register_t	pcb_rip;
-	register_t	__pad1;		/* Spare */
 	register_t	pcb_fsbase;
 	register_t	pcb_gsbase;
 	u_int32_t	pcb_ds;
@@ -75,6 +74,10 @@
 #define	PCB_FULLCTX	0x80	/* full context restore on sysret */
 
 	caddr_t	pcb_onfault;	/* copyin/out fault recovery */
+
+	/* 32-bit segment descriptor */
+	struct user_segment_descriptor	*pcb_gs32p;
+	struct user_segment_descriptor	pcb_gs32sd;
 };
 
 #ifdef _KERNEL
--- /dev/null
+++ sys/amd64/include/minidump.h
@@ -0,0 +1,46 @@
+/*-
+ * Copyright (c) 2006 Peter Wemm
+ * 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.
+ *
+ * $FreeBSD: src/sys/amd64/include/minidump.h,v 1.1 2006/04/21 04:24:50 peter Exp $
+ */
+
+#ifndef	_MACHINE_MINIDUMP_H_
+#define	_MACHINE_MINIDUMP_H_ 1
+
+#define	MINIDUMP_MAGIC		"minidump FreeBSD/amd64"
+#define	MINIDUMP_VERSION	1
+
+struct minidumphdr {
+	char magic[24];
+	uint32_t version;
+	uint32_t msgbufsize;
+	uint32_t bitmapsize;
+	uint32_t ptesize;
+	uint64_t kernbase;
+	uint64_t dmapbase;
+	uint64_t dmapend;
+};
+
+#endif /* _MACHINE_MINIDUMP_H_ */
Index: frame.h
===================================================================
RCS file: /home/cvs/src/sys/amd64/include/frame.h,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L sys/amd64/include/frame.h -L sys/amd64/include/frame.h -u -r1.1.1.1 -r1.2
--- sys/amd64/include/frame.h
+++ sys/amd64/include/frame.h
@@ -31,7 +31,7 @@
  * SUCH DAMAGE.
  *
  *	from: @(#)frame.h	5.2 (Berkeley) 1/18/91
- * $FreeBSD: src/sys/amd64/include/frame.h,v 1.28 2004/07/10 22:39:56 marcel Exp $
+ * $FreeBSD: src/sys/amd64/include/frame.h,v 1.30 2005/12/22 22:16:05 jhb Exp $
  */
 
 #ifndef _MACHINE_FRAME_H_
@@ -76,64 +76,4 @@
 	register_t	tf_ss;
 };
 
-/* Interrupt stack frame */
-
-struct intrframe {
-	register_t	if_rdi;
-	register_t	if_rsi;
-	register_t	if_rdx;
-	register_t	if_rcx;
-	register_t	if_r8;
-	register_t	if_r9;
-	register_t	if_rax;
-	register_t	if_rbx;
-	register_t	if_rbp;
-	register_t	if_r10;
-	register_t	if_r11;
-	register_t	if_r12;
-	register_t	if_r13;
-	register_t	if_r14;
-	register_t	if_r15;
-	register_t	:64;		/* compat with trap frame - trapno */
-	register_t	:64;		/* compat with trap frame - addr */
-	register_t	:64;		/* compat with trap frame - flags */
-	register_t	:64;		/* compat with trap frame - err */
-	/* below portion defined in hardware */
-	register_t	if_rip;
-	register_t	if_cs;
-	register_t	if_rflags;
-	register_t	if_rsp;
-	register_t	if_ss;
-};
-
-/* frame of clock (same as interrupt frame) */
-
-struct clockframe {
-	register_t	cf_rdi;
-	register_t	cf_rsi;
-	register_t	cf_rdx;
-	register_t	cf_rcx;
-	register_t	cf_r8;
-	register_t	cf_r9;
-	register_t	cf_rax;
-	register_t	cf_rbx;
-	register_t	cf_rbp;
-	register_t	cf_r10;
-	register_t	cf_r11;
-	register_t	cf_r12;
-	register_t	cf_r13;
-	register_t	cf_r14;
-	register_t	cf_r15;
-	register_t	:64;		/* compat with trap frame - trapno */
-	register_t	:64;		/* compat with trap frame - addr */
-	register_t	:64;		/* compat with trap frame - flags */
-	register_t	:64;		/* compat with trap frame - err */
-	/* below portion defined in hardware */
-	register_t	cf_rip;
-	register_t	cf_cs;
-	register_t	cf_rflags;
-	register_t	cf_rsp;
-	register_t	cf_ss;
-};
-
 #endif /* _MACHINE_FRAME_H_ */
Index: atomic.h
===================================================================
RCS file: /home/cvs/src/sys/amd64/include/atomic.h,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L sys/amd64/include/atomic.h -L sys/amd64/include/atomic.h -u -r1.1.1.1 -r1.2
--- sys/amd64/include/atomic.h
+++ sys/amd64/include/atomic.h
@@ -23,7 +23,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD: src/sys/amd64/include/atomic.h,v 1.34.2.4 2005/10/06 18:12:05 jhb Exp $
+ * $FreeBSD: src/sys/amd64/include/atomic.h,v 1.44 2006/12/29 15:29:49 bde Exp $
  */
 #ifndef _MACHINE_ATOMIC_H_
 #define	_MACHINE_ATOMIC_H_
@@ -33,30 +33,30 @@
 #endif
 
 /*
- * Various simple arithmetic on memory which is atomic in the presence
- * of interrupts and multiple processors.
+ * Various simple operations on memory, each of which is atomic in the
+ * presence of interrupts and multiple processors.
  *
- * atomic_set_char(P, V)	(*(u_char*)(P) |= (V))
- * atomic_clear_char(P, V)	(*(u_char*)(P) &= ~(V))
- * atomic_add_char(P, V)	(*(u_char*)(P) += (V))
- * atomic_subtract_char(P, V)	(*(u_char*)(P) -= (V))
+ * atomic_set_char(P, V)	(*(u_char *)(P) |= (V))
+ * atomic_clear_char(P, V)	(*(u_char *)(P) &= ~(V))
+ * atomic_add_char(P, V)	(*(u_char *)(P) += (V))
+ * atomic_subtract_char(P, V)	(*(u_char *)(P) -= (V))
  *
- * atomic_set_short(P, V)	(*(u_short*)(P) |= (V))
- * atomic_clear_short(P, V)	(*(u_short*)(P) &= ~(V))
- * atomic_add_short(P, V)	(*(u_short*)(P) += (V))
- * atomic_subtract_short(P, V)	(*(u_short*)(P) -= (V))
+ * atomic_set_short(P, V)	(*(u_short *)(P) |= (V))
+ * atomic_clear_short(P, V)	(*(u_short *)(P) &= ~(V))
+ * atomic_add_short(P, V)	(*(u_short *)(P) += (V))
+ * atomic_subtract_short(P, V)	(*(u_short *)(P) -= (V))
  *
- * atomic_set_int(P, V)		(*(u_int*)(P) |= (V))
- * atomic_clear_int(P, V)	(*(u_int*)(P) &= ~(V))
- * atomic_add_int(P, V)		(*(u_int*)(P) += (V))
- * atomic_subtract_int(P, V)	(*(u_int*)(P) -= (V))
- * atomic_readandclear_int(P)	(return  *(u_int*)P; *(u_int*)P = 0;)
+ * atomic_set_int(P, V)		(*(u_int *)(P) |= (V))
+ * atomic_clear_int(P, V)	(*(u_int *)(P) &= ~(V))
+ * atomic_add_int(P, V)		(*(u_int *)(P) += (V))
+ * atomic_subtract_int(P, V)	(*(u_int *)(P) -= (V))
+ * atomic_readandclear_int(P)	(return (*(u_int *)(P)); *(u_int *)(P) = 0;)
  *
- * atomic_set_long(P, V)	(*(u_long*)(P) |= (V))
- * atomic_clear_long(P, V)	(*(u_long*)(P) &= ~(V))
- * atomic_add_long(P, V)	(*(u_long*)(P) += (V))
- * atomic_subtract_long(P, V)	(*(u_long*)(P) -= (V))
- * atomic_readandclear_long(P)	(return  *(u_long*)P; *(u_long*)P = 0;)
+ * atomic_set_long(P, V)	(*(u_long *)(P) |= (V))
+ * atomic_clear_long(P, V)	(*(u_long *)(P) &= ~(V))
+ * atomic_add_long(P, V)	(*(u_long *)(P) += (V))
+ * atomic_subtract_long(P, V)	(*(u_long *)(P) -= (V))
+ * atomic_readandclear_long(P)	(return (*(u_long *)(P)); *(u_long *)(P) = 0;)
  */
 
 /*
@@ -67,26 +67,26 @@
  * Kernel modules call real functions which are built into the kernel.
  * This allows kernel modules to be portable between UP and SMP systems.
  */
-#if defined(KLD_MODULE) || !(defined(__GNUCLIKE_ASM) && defined(__CC_SUPPORTS___INLINE))
+#if defined(KLD_MODULE) || !defined(__GNUCLIKE_ASM)
 #define	ATOMIC_ASM(NAME, TYPE, OP, CONS, V)			\
 void atomic_##NAME##_##TYPE(volatile u_##TYPE *p, u_##TYPE v)
 
-int atomic_cmpset_int(volatile u_int *dst, u_int exp, u_int src);
-int atomic_cmpset_long(volatile u_long *dst, u_long exp, u_long src);
-u_int atomic_fetchadd_int(volatile u_int *p, u_int v);
+int	atomic_cmpset_int(volatile u_int *dst, u_int exp, u_int src);
+int	atomic_cmpset_long(volatile u_long *dst, u_long exp, u_long src);
+u_int	atomic_fetchadd_int(volatile u_int *p, u_int v);
 
 #define	ATOMIC_STORE_LOAD(TYPE, LOP, SOP)			\
 u_##TYPE	atomic_load_acq_##TYPE(volatile u_##TYPE *p);	\
 void		atomic_store_rel_##TYPE(volatile u_##TYPE *p, u_##TYPE v)
 
-#else /* !KLD_MODULE && __GNUCLIKE_ASM && __CC_SUPPORTS___INLINE */
+#else /* !KLD_MODULE && __GNUCLIKE_ASM */
 
 /*
- * For userland, assume the SMP case and use lock prefixes so that
- * the binaries will run on both types of systems.
+ * For userland, always use lock prefixes so that the binaries will run
+ * on both SMP and !SMP systems.
  */
 #if defined(SMP) || !defined(_KERNEL)
-#define	MPLOCKED	lock ;
+#define	MPLOCKED	"lock ; "
 #else
 #define	MPLOCKED
 #endif
@@ -99,9 +99,9 @@
 static __inline void					\
 atomic_##NAME##_##TYPE(volatile u_##TYPE *p, u_##TYPE v)\
 {							\
-	__asm __volatile(__XSTRING(MPLOCKED) OP		\
-			 : "=m" (*p)			\
-			 : CONS (V), "m" (*p));		\
+	__asm __volatile(MPLOCKED OP			\
+	: "=m" (*p)					\
+	: CONS (V), "m" (*p));				\
 }							\
 struct __hack
 
@@ -116,19 +116,19 @@
 static __inline int
 atomic_cmpset_int(volatile u_int *dst, u_int exp, u_int src)
 {
-	int res = exp;
+	u_char res;
 
-	__asm __volatile (
-	"	" __XSTRING(MPLOCKED) "	"
+	__asm __volatile(
+	"	" MPLOCKED "		"
 	"	cmpxchgl %2,%1 ;	"
-	"       setz	%%al ;		"
-	"	movzbl	%%al,%0 ;	"
+	"       sete	%0 ;		"
 	"1:				"
 	"# atomic_cmpset_int"
-	: "+a" (res), 			/* 0 (result) */
+	: "=a" (res),			/* 0 */
 	  "=m" (*dst)			/* 1 */
 	: "r" (src),			/* 2 */
-	  "m" (*dst)			/* 3 */
+	  "a" (exp),			/* 3 */
+	  "m" (*dst)			/* 4 */
 	: "memory");
 
 	return (res);
@@ -137,19 +137,19 @@
 static __inline int
 atomic_cmpset_long(volatile u_long *dst, u_long exp, u_long src)
 {
-	long res = exp;
+	u_char res;
 
-	__asm __volatile (
-	"	" __XSTRING(MPLOCKED) "	"
+	__asm __volatile(
+	"	" MPLOCKED "		"
 	"	cmpxchgq %2,%1 ;	"
-	"       setz	%%al ;		"
-	"	movzbq	%%al,%0 ;	"
+	"       sete	%0 ;		"
 	"1:				"
 	"# atomic_cmpset_long"
-	: "+a" (res),			/* 0 (result) */
+	: "=a" (res),			/* 0 */
 	  "=m" (*dst)			/* 1 */
 	: "r" (src),			/* 2 */
-	  "m" (*dst)			/* 3 */
+	  "a" (exp),			/* 3 */
+	  "m" (*dst)			/* 4 */
 	: "memory");
 
 	return (res);
@@ -163,8 +163,8 @@
 atomic_fetchadd_int(volatile u_int *p, u_int v)
 {
 
-	__asm __volatile (
-	"	" __XSTRING(MPLOCKED) "	"
+	__asm __volatile(
+	"	" MPLOCKED "		"
 	"	xaddl	%0, %1 ;	"
 	"# atomic_fetchadd_int"
 	: "+r" (v),			/* 0 (result) */
@@ -174,17 +174,42 @@
 	return (v);
 }
 
+#if defined(_KERNEL) && !defined(SMP)
+
+/*
+ * We assume that a = b will do atomic loads and stores.  However, on a
+ * PentiumPro or higher, reads may pass writes, so for that case we have
+ * to use a serializing instruction (i.e. with LOCK) to do the load in
+ * SMP kernels.  For UP kernels, however, the cache of the single processor
+ * is always consistent, so we don't need any memory barriers.
+ */
+#define	ATOMIC_STORE_LOAD(TYPE, LOP, SOP)		\
+static __inline u_##TYPE				\
+atomic_load_acq_##TYPE(volatile u_##TYPE *p)		\
+{							\
+	return (*p);					\
+}							\
+							\
+static __inline void					\
+atomic_store_rel_##TYPE(volatile u_##TYPE *p, u_##TYPE v)\
+{							\
+	*p = v;						\
+}							\
+struct __hack
+
+#else /* !(_KERNEL && !SMP) */
+
 #define	ATOMIC_STORE_LOAD(TYPE, LOP, SOP)		\
 static __inline u_##TYPE				\
 atomic_load_acq_##TYPE(volatile u_##TYPE *p)		\
 {							\
 	u_##TYPE res;					\
 							\
-	__asm __volatile(__XSTRING(MPLOCKED) LOP	\
-	: "=a" (res),			/* 0 (result) */\
+	__asm __volatile(MPLOCKED LOP			\
+	: "=a" (res),			/* 0 */		\
 	  "=m" (*p)			/* 1 */		\
 	: "m" (*p)			/* 2 */		\
-	: "memory");				 	\
+	: "memory");					\
 							\
 	return (res);					\
 }							\
@@ -202,7 +227,9 @@
 }							\
 struct __hack
 
-#endif /* KLD_MODULE || !(__GNUCLIKE_ASM && __CC_SUPPORTS___INLINE) */
+#endif /* _KERNEL && !SMP */
+
+#endif /* KLD_MODULE || !__GNUCLIKE_ASM */
 
 ATOMIC_ASM(set,	     char,  "orb %b1,%0",  "iq",  v);
 ATOMIC_ASM(clear,    char,  "andb %b1,%0", "iq", ~v);
@@ -232,49 +259,49 @@
 #undef ATOMIC_ASM
 #undef ATOMIC_STORE_LOAD
 
-#if !defined(WANT_FUNCTIONS)
+#ifndef WANT_FUNCTIONS
 
 /* Read the current value and store a zero in the destination. */
-#if defined(__GNUCLIKE_ASM) && defined(__CC_SUPPORTS___INLINE)
+#ifdef __GNUCLIKE_ASM
 
 static __inline u_int
 atomic_readandclear_int(volatile u_int *addr)
 {
-	u_int result;
+	u_int res;
 
-	result = 0;
-	__asm __volatile (
+	res = 0;
+	__asm __volatile(
 	"	xchgl	%1,%0 ;		"
 	"# atomic_readandclear_int"
-	: "+r" (result),		/* 0 (result) */
-	  "=m" (*addr)			/* 1 (addr) */
+	: "+r" (res),			/* 0 */
+	  "=m" (*addr)			/* 1 */
 	: "m" (*addr));
 
-	return (result);
+	return (res);
 }
 
 static __inline u_long
 atomic_readandclear_long(volatile u_long *addr)
 {
-	u_long result;
+	u_long res;
 
-	result = 0;
-	__asm __volatile (
+	res = 0;
+	__asm __volatile(
 	"	xchgq	%1,%0 ;		"
 	"# atomic_readandclear_long"
-	: "+r" (result),		/* 0 (result) */
-	  "=m" (*addr)			/* 1 (addr) */
+	: "+r" (res),			/* 0 */
+	  "=m" (*addr)			/* 1 */
 	: "m" (*addr));
 
-	return (result);
+	return (res);
 }
 
-#else /* !(__GNUCLIKE_ASM && __CC_SUPPORTS___INLINE) */
+#else /* !__GNUCLIKE_ASM */
 
-u_int	atomic_readandclear_int(volatile u_int *);
-u_long	atomic_readandclear_long(volatile u_long *);
+u_int	atomic_readandclear_int(volatile u_int *addr);
+u_long	atomic_readandclear_long(volatile u_long *addr);
 
-#endif /* __GNUCLIKE_ASM && __CC_SUPPORTS___INLINE */
+#endif /* __GNUCLIKE_ASM */
 
 /* Acquire and release variants are identical to the normal ones. */
 #define	atomic_set_acq_char		atomic_set_char
@@ -410,5 +437,6 @@
 #define	atomic_cmpset_rel_ptr	atomic_cmpset_rel_long
 #define	atomic_readandclear_ptr	atomic_readandclear_long
 
-#endif	/* !defined(WANT_FUNCTIONS) */
-#endif /* ! _MACHINE_ATOMIC_H_ */
+#endif /* !WANT_FUNCTIONS */
+
+#endif /* !_MACHINE_ATOMIC_H_ */
Index: mutex.h
===================================================================
RCS file: /home/cvs/src/sys/amd64/include/mutex.h,v
retrieving revision 1.1.1.2
retrieving revision 1.2
diff -L sys/amd64/include/mutex.h -L sys/amd64/include/mutex.h -u -r1.1.1.2 -r1.2
--- sys/amd64/include/mutex.h
+++ sys/amd64/include/mutex.h
@@ -26,19 +26,10 @@
  * SUCH DAMAGE.
  *
  *	from BSDI $Id: mutex.h,v 2.7.2.35 2000/04/27 03:10:26 cp Exp $
- * $FreeBSD: src/sys/amd64/include/mutex.h,v 1.38 2003/12/06 23:17:18 peter Exp $
+ * $FreeBSD: src/sys/amd64/include/mutex.h,v 1.39 2006/05/19 18:53:50 sobomax Exp $
  */
 
 #ifndef _MACHINE_MUTEX_H_
 #define _MACHINE_MUTEX_H_
 
-#ifndef LOCORE
-#ifdef _KERNEL
-
-/* Global locks */
-extern struct mtx	clock_lock;
-
-#endif	/* _KERNEL */
-
-#endif	/* !LOCORE */
 #endif	/* __MACHINE_MUTEX_H */
Index: profile.h
===================================================================
RCS file: /home/cvs/src/sys/amd64/include/profile.h,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L sys/amd64/include/profile.h -L sys/amd64/include/profile.h -u -r1.1.1.1 -r1.2
--- sys/amd64/include/profile.h
+++ sys/amd64/include/profile.h
@@ -27,7 +27,7 @@
  * SUCH DAMAGE.
  *
  *	@(#)profile.h	8.1 (Berkeley) 6/11/93
- * $FreeBSD: src/sys/amd64/include/profile.h,v 1.45 2005/03/11 22:16:09 peter Exp $
+ * $FreeBSD: src/sys/amd64/include/profile.h,v 1.48 2006/10/28 13:12:06 bde Exp $
  */
 
 #ifndef _MACHINE_PROFILE_H_
@@ -61,7 +61,7 @@
 #define	MCOUNT_OVERHEAD(label)						\
 	__asm __volatile("pushq %0; call __mcount; popq %%rcx"		\
 			 :						\
-			 : "i" (profil)					\
+			 : "i" (label)					\
 			 : "ax", "dx", "cx", "di", "si", "r8", "r9", "memory")
 #define	MEXITCOUNT_OVERHEAD()						\
 	__asm __volatile("call .mexitcount; 1:"				\
@@ -114,11 +114,11 @@
 
 #ifdef __GNUCLIKE_ASM
 #define	MCOUNT __asm("			\n\
+	.text				\n\
+	.p2align 4,0x90			\n\
 	.globl	.mcount			\n\
-	.type	.mcount @function	\n\
+	.type	.mcount, at function	\n\
 .mcount:				\n\
-	pushq	%rbp			\n\
-	movq	%rsp,%rbp		\n\
 	pushq	%rdi			\n\
 	pushq	%rsi			\n\
 	pushq	%rdx			\n\
@@ -126,9 +126,8 @@
 	pushq	%r8			\n\
 	pushq	%r9			\n\
 	pushq	%rax			\n\
-	movq	8(%rbp),%rsi		\n\
-	movq	(%rbp),%rdi		\n\
-	movq	8(%rdi),%rdi		\n\
+	movq	8(%rbp),%rdi		\n\
+	movq	7*8(%rsp),%rsi		\n\
 	call	_mcount			\n\
 	popq	%rax			\n\
 	popq	%r9			\n\
@@ -137,7 +136,6 @@
 	popq	%rdx			\n\
 	popq	%rsi			\n\
 	popq	%rdi			\n\
-	leave				\n\
 	ret				\n\
 	.size	.mcount, . - .mcount");
 #if 0
@@ -171,11 +169,7 @@
 }
 #endif
 #else /* !__GNUCLIKE_ASM */
-#define	MCOUNT								\
-void									\
-mcount()								\
-{									\
-}
+#define	MCOUNT
 #endif /* __GNUCLIKE_ASM */
 
 typedef	u_long	uintfptr_t;
Index: icu.h
===================================================================
RCS file: /home/cvs/src/sys/amd64/isa/icu.h,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L sys/amd64/isa/icu.h -L sys/amd64/isa/icu.h -u -r1.1.1.1 -r1.2
--- sys/amd64/isa/icu.h
+++ sys/amd64/isa/icu.h
@@ -30,7 +30,7 @@
  * SUCH DAMAGE.
  *
  *	from: @(#)icu.h	5.6 (Berkeley) 5/9/91
- * $FreeBSD: src/sys/amd64/isa/icu.h,v 1.34 2004/05/16 20:30:47 peter Exp $
+ * $FreeBSD: src/sys/amd64/isa/icu.h,v 1.36 2006/12/17 21:51:44 kmacy Exp $
  */
 
 /*
@@ -43,7 +43,7 @@
 
 #define	ICU_IMR_OFFSET	1
 
-void	atpic_handle_intr(void *cookie, struct intrframe iframe);
+void	atpic_handle_intr(u_int vector, struct trapframe *frame);
 void	atpic_startup(void);
 
 #endif /* !_AMD64_ISA_ICU_H_ */
Index: atpic_vector.S
===================================================================
RCS file: /home/cvs/src/sys/amd64/isa/atpic_vector.S,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L sys/amd64/isa/atpic_vector.S -L sys/amd64/isa/atpic_vector.S -u -r1.1.1.1 -r1.2
--- sys/amd64/isa/atpic_vector.S
+++ sys/amd64/isa/atpic_vector.S
@@ -28,7 +28,7 @@
  * SUCH DAMAGE.
  *
  *	from: vector.s, 386BSD 0.1 unknown origin
- * $FreeBSD: src/sys/amd64/isa/atpic_vector.S,v 1.45 2004/05/24 12:08:56 bde Exp $
+ * $FreeBSD: src/sys/amd64/isa/atpic_vector.S,v 1.48 2006/12/17 06:48:40 kmacy Exp $
  */
 
 /*
@@ -41,33 +41,16 @@
 #include "assym.s"
 
 /*
- * Macros for interrupt interrupt entry, call to handler, and exit.
+ * Macros for interrupt entry, call to handler, and exit.
  */
 #define	INTR(irq_num, vec_name) \
 	.text ;								\
 	SUPERALIGN_TEXT ;						\
 IDTVEC(vec_name) ;							\
-	subq	$TF_RIP,%rsp ;	/* skip dummy tf_err and tf_trapno */	\
-	testb	$SEL_RPL_MASK,TF_CS(%rsp) ; /* come from kernel? */	\
-	jz	1f ;		/* Yes, dont swapgs again */		\
-	swapgs ;							\
-1:	movq	%rdi,TF_RDI(%rsp) ;					\
-	movq	%rsi,TF_RSI(%rsp) ;					\
-	movq	%rdx,TF_RDX(%rsp) ;					\
-	movq	%rcx,TF_RCX(%rsp) ;					\
-	movq	%r8,TF_R8(%rsp) ;					\
-	movq	%r9,TF_R9(%rsp) ;					\
-	movq	%rax,TF_RAX(%rsp) ;					\
-	movq	%rbx,TF_RBX(%rsp) ;					\
-	movq	%rbp,TF_RBP(%rsp) ;					\
-	movq	%r10,TF_R10(%rsp) ;					\
-	movq	%r11,TF_R11(%rsp) ;					\
-	movq	%r12,TF_R12(%rsp) ;					\
-	movq	%r13,TF_R13(%rsp) ;					\
-	movq	%r14,TF_R14(%rsp) ;					\
-	movq	%r15,TF_R15(%rsp) ;					\
+	PUSH_FRAME ;							\
 	FAKE_MCOUNT(TF_RIP(%rsp)) ;					\
-	movq	$irq_num, %rdi; 	/* pass the IRQ */		\
+	movq	%rsp, %rsi	;                                       \
+	movl	$irq_num, %edi; 	/* pass the IRQ */		\
 	call	atpic_handle_intr ;					\
 	MEXITCOUNT ;							\
 	jmp	doreti
Index: atpic.c
===================================================================
RCS file: /home/cvs/src/sys/amd64/isa/atpic.c,v
retrieving revision 1.2
retrieving revision 1.3
diff -L sys/amd64/isa/atpic.c -L sys/amd64/isa/atpic.c -u -r1.2 -r1.3
--- sys/amd64/isa/atpic.c
+++ sys/amd64/isa/atpic.c
@@ -32,7 +32,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/amd64/isa/atpic.c,v 1.15.2.3 2006/03/10 19:37:31 jhb Exp $");
+__FBSDID("$FreeBSD: src/sys/amd64/isa/atpic.c,v 1.22 2007/05/08 21:29:13 jhb Exp $");
 
 #include "opt_auto_eoi.h"
 #include "opt_isa.h"
@@ -45,7 +45,6 @@
 #include <sys/lock.h>
 #include <sys/module.h>
 #include <sys/mutex.h>
-#include <sys/proc.h>
 
 #include <machine/cpufunc.h>
 #include <machine/frame.h>
@@ -108,9 +107,10 @@
 
 #define	ATPIC(io, base, eoi, imenptr)					\
      	{ { atpic_enable_source, atpic_disable_source, (eoi),		\
-	    atpic_enable_intr, atpic_vector, atpic_source_pending, NULL, \
-	    atpic_resume, atpic_config_intr, atpic_assign_cpu }, (io),  \
-	    (base), IDT_IO_INTS + (base), (imenptr) }
+	    atpic_enable_intr, atpic_disable_intr, atpic_vector,	\
+	    atpic_source_pending, NULL,	atpic_resume, atpic_config_intr,\
+	    atpic_assign_cpu }, (io), (base), IDT_IO_INTS + (base),	\
+	    (imenptr) }
 
 #define	INTSRC(irq)							\
 	{ { &atpics[(irq) / 8].at_pic }, IDTVEC(atpic_intr ## irq ),	\
@@ -138,8 +138,9 @@
 static void atpic_eoi_master(struct intsrc *isrc);
 static void atpic_eoi_slave(struct intsrc *isrc);
 static void atpic_enable_intr(struct intsrc *isrc);
+static void atpic_disable_intr(struct intsrc *isrc);
 static int atpic_vector(struct intsrc *isrc);
-static void atpic_resume(struct intsrc *isrc);
+static void atpic_resume(struct pic *pic);
 static int atpic_source_pending(struct intsrc *isrc);
 static int atpic_config_intr(struct intsrc *isrc, enum intr_trigger trig,
     enum intr_polarity pol);
@@ -267,6 +268,12 @@
 {
 }
 
+static void
+atpic_disable_intr(struct intsrc *isrc)
+{
+}
+
+
 static int
 atpic_vector(struct intsrc *isrc)
 {
@@ -286,16 +293,13 @@
 }
 
 static void
-atpic_resume(struct intsrc *isrc)
+atpic_resume(struct pic *pic)
 {
-	struct atpic_intsrc *ai = (struct atpic_intsrc *)isrc;
-	struct atpic *ap = (struct atpic *)isrc->is_pic;
+	struct atpic *ap = (struct atpic *)pic;
 
-	if (ai->at_irq == 0) {
-		i8259_init(ap, ap == &atpics[SLAVE]);
-		if (ap == &atpics[SLAVE] && elcr_found)
-			elcr_resume();
-	}
+	i8259_init(ap, ap == &atpics[SLAVE]);
+	if (ap == &atpics[SLAVE] && elcr_found)
+		elcr_resume();
 }
 
 static int
@@ -466,6 +470,14 @@
 	int i;
 
 	/*
+	 * Register our PICs, even if we aren't going to use any of their
+	 * pins so that they are suspended and resumed.
+	 */
+	if (intr_register_pic(&atpics[0].at_pic) != 0 ||
+	    intr_register_pic(&atpics[1].at_pic) != 0)
+		panic("Unable to register ATPICs");
+
+	/*
 	 * If any of the ISA IRQs have an interrupt source already, then
 	 * assume that the APICs are being used and don't register any
 	 * of our interrupt sources.  This makes sure we don't accidentally
@@ -490,19 +502,18 @@
 SYSINIT(atpic_init, SI_SUB_INTR, SI_ORDER_SECOND + 1, atpic_init, NULL)
 
 void
-atpic_handle_intr(void *cookie, struct intrframe iframe)
+atpic_handle_intr(u_int vector, struct trapframe *frame)
 {
 	struct intsrc *isrc;
-	int vec = (uintptr_t)cookie;
 
-	KASSERT(vec < NUM_ISA_IRQS, ("unknown int %d\n", vec));
-	isrc = &atintrs[vec].at_intsrc;
+	KASSERT(vector < NUM_ISA_IRQS, ("unknown int %u\n", vector));
+	isrc = &atintrs[vector].at_intsrc;
 
 	/*
 	 * If we don't have an event, see if this is a spurious
 	 * interrupt.
 	 */
-	if (isrc->is_event == NULL && (vec == 7 || vec == 15)) {
+	if (isrc->is_event == NULL && (vector == 7 || vector == 15)) {
 		int port, isr;
 
 		/*
@@ -518,7 +529,7 @@
 		if ((isr & IRQ_MASK(7)) == 0)
 			return;
 	}
-	intr_execute_handlers(isrc, &iframe);
+	intr_execute_handlers(isrc, frame);
 }
 
 #ifdef DEV_ISA
Index: isa.c
===================================================================
RCS file: /home/cvs/src/sys/amd64/isa/isa.c,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L sys/amd64/isa/isa.c -L sys/amd64/isa/isa.c -u -r1.1.1.1 -r1.2
--- sys/amd64/isa/isa.c
+++ sys/amd64/isa/isa.c
@@ -25,7 +25,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/amd64/isa/isa.c,v 1.148 2005/01/21 05:56:41 peter Exp $");
+__FBSDID("$FreeBSD: src/sys/amd64/isa/isa.c,v 1.149 2007/02/23 12:18:26 piso Exp $");
 
 /*-
  * Modifications for Intel architecture by Garrett A. Wollman.
@@ -147,10 +147,11 @@
  */
 int
 isa_setup_intr(device_t bus, device_t child, struct resource *r, int flags,
-	       void (*ihand)(void *), void *arg, void **cookiep)
+	       driver_filter_t *filter, void (*ihand)(void *), void *arg, 
+	       void **cookiep)
 {
 	return (BUS_SETUP_INTR(device_get_parent(bus), child, r, flags,
-			       ihand, arg, cookiep));
+			       filter, ihand, arg, cookiep));
 }
 
 int
Index: clock.c
===================================================================
RCS file: /home/cvs/src/sys/amd64/isa/clock.c,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L sys/amd64/isa/clock.c -L sys/amd64/isa/clock.c -u -r1.1.1.1 -r1.2
--- sys/amd64/isa/clock.c
+++ sys/amd64/isa/clock.c
@@ -33,7 +33,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/amd64/isa/clock.c,v 1.221.2.1 2005/07/18 19:52:04 jhb Exp $");
+__FBSDID("$FreeBSD: src/sys/amd64/isa/clock.c,v 1.234.2.1 2007/10/29 22:26:34 peter Exp $");
 
 /*
  * Routines to handle clock hardware.
@@ -52,20 +52,26 @@
 #include <sys/param.h>
 #include <sys/systm.h>
 #include <sys/bus.h>
+#include <sys/clock.h>
+#include <sys/conf.h>
+#include <sys/fcntl.h>
 #include <sys/lock.h>
 #include <sys/kdb.h>
 #include <sys/mutex.h>
 #include <sys/proc.h>
 #include <sys/time.h>
 #include <sys/timetc.h>
+#include <sys/uio.h>
 #include <sys/kernel.h>
 #include <sys/limits.h>
 #include <sys/module.h>
+#include <sys/sched.h>
 #include <sys/sysctl.h>
 #include <sys/cons.h>
 #include <sys/power.h>
 
 #include <machine/clock.h>
+#include <machine/cpu.h>
 #include <machine/frame.h>
 #include <machine/intr_machdep.h>
 #include <machine/md_var.h>
@@ -90,9 +96,7 @@
 
 #define	TIMER_DIV(x) ((timer_freq + (x) / 2) / (x))
 
-int	adjkerntz;		/* local offset from GMT in seconds */
 int	clkintr_pending;
-int	disable_rtc_set;	/* disable resettodr() if != 0 */
 int	pscnt = 1;
 int	psdiv = 1;
 int	statclock_disable;
@@ -102,12 +106,11 @@
 u_int	timer_freq = TIMER_FREQ;
 int	timer0_max_count;
 int	timer0_real_max_count;
-int	wall_cmos_clock;	/* wall CMOS clock assumed if != 0 */
-struct mtx clock_lock;
 #define	RTC_LOCK	mtx_lock_spin(&clock_lock)
 #define	RTC_UNLOCK	mtx_unlock_spin(&clock_lock)
 
 static	int	beeping = 0;
+static	struct mtx clock_lock;
 static	const u_char daysinmonth[] = {31,28,31,30,31,30,31,31,30,31,30,31};
 static	struct intsrc *i8254_intsrc;
 static	u_int32_t i8254_lastcount;
@@ -115,6 +118,7 @@
 static	int	(*i8254_pending)(struct intsrc *);
 static	int	i8254_ticked;
 static	int	using_lapic_timer;
+static	int	rtc_reg = -1;
 static	u_char	rtc_statusa = RTCSA_DIVIDER | RTCSA_NOPROF;
 static	u_char	rtc_statusb = RTCSB_24HR;
 
@@ -139,8 +143,8 @@
 	0			/* quality */
 };
 
-static void
-clkintr(struct clockframe *frame)
+static int
+clkintr(struct trapframe *frame)
 {
 
 	if (timecounter->tc_get_timecount == i8254_get_timecount) {
@@ -154,8 +158,9 @@
 		clkintr_pending = 0;
 		mtx_unlock_spin(&clock_lock);
 	}
-	if (!using_lapic_timer)
-		hardclock(frame);
+	KASSERT(!using_lapic_timer, ("clk interrupt enabled with lapic timer"));
+	hardclock(TRAPF_USERMODE(frame), TRAPF_PC(frame));
+	return (FILTER_HANDLED);
 }
 
 int
@@ -210,19 +215,22 @@
  * Stat clock ticks can still be lost, causing minor loss of accuracy
  * in the statistics, but the stat clock will no longer stop.
  */
-static void
-rtcintr(struct clockframe *frame)
+static int
+rtcintr(struct trapframe *frame)
 {
+	int flag = 0;
 
 	while (rtcin(RTC_INTR) & RTCIR_PERIOD) {
+		flag = 1;
 		if (profprocs != 0) {
 			if (--pscnt == 0)
 				pscnt = psdiv;
-			profclock(frame);
+			profclock(TRAPF_USERMODE(frame), TRAPF_PC(frame));
 		}
 		if (pscnt == psdiv)
-			statclock(frame);
+			statclock(TRAPF_USERMODE(frame));
 	}
+	return(flag ? FILTER_HANDLED : FILTER_STRAY);
 }
 
 #include "opt_ddb.h"
@@ -269,7 +277,21 @@
 	int getit_calls = 1;
 	int n1;
 	static int state = 0;
+#endif
+
+	if (tsc_freq != 0 && !tsc_is_broken) {
+		uint64_t start, end, now;
 
+		sched_pin();
+		start = rdtsc();
+		end = start + (tsc_freq * n) / 1000000;
+		do {
+			now = rdtsc();
+		} while (now < end || (now > start && end < start));
+		sched_unpin();
+		return;
+	}
+#ifdef DELAYDEBUG
 	if (state == 0) {
 		state = 1;
 		for (n1 = 1; n1 <= 10000000; n1 *= 10)
@@ -280,13 +302,6 @@
 		printf("DELAY(%d)...", n);
 #endif
 	/*
-	 * Guard against the timer being uninitialized if we are called
-	 * early for console i/o.
-	 */
-	if (timer0_max_count == 0)
-		set_timer_freq(timer_freq, hz);
-
-	/*
 	 * Read the counter first, so that the rest of the setup overhead is
 	 * counted.  Guess the initial overhead is 20 usec (on most systems it
 	 * takes about 1.5 usec for each of the i/o's in getit().  The loop
@@ -407,24 +422,30 @@
 	u_char val;
 
 	RTC_LOCK;
-	outb(IO_RTC, reg);
-	inb(0x84);
+	if (rtc_reg != reg) {
+		inb(0x84);
+		outb(IO_RTC, reg);
+		rtc_reg = reg;
+		inb(0x84);
+	}
 	val = inb(IO_RTC + 1);
-	inb(0x84);
 	RTC_UNLOCK;
 	return (val);
 }
 
-static __inline void
-writertc(u_char reg, u_char val)
+void
+writertc(int reg, u_char val)
 {
 
 	RTC_LOCK;
-	inb(0x84);
-	outb(IO_RTC, reg);
-	inb(0x84);
+	if (rtc_reg != reg) {
+		inb(0x84);
+		outb(IO_RTC, reg);
+		rtc_reg = reg;
+		inb(0x84);
+	}
 	outb(IO_RTC + 1, val);
-	inb(0x84);		/* XXX work around wrong order in rtcin() */
+	inb(0x84);
 	RTC_UNLOCK;
 }
 
@@ -539,10 +560,15 @@
 	mtx_unlock_spin(&clock_lock);
 }
 
-/*
- * Initialize 8254 timer 0 early so that it can be used in DELAY().
- * XXX initialization of other timers is unintentionally left blank.
- */
+/* This is separate from startrtclock() so that it can be called early. */
+void
+i8254_init(void)
+{
+
+	mtx_init(&clock_lock, "clk", NULL, MTX_SPIN | MTX_NOPROFILE);
+	set_timer_freq(timer_freq, hz);
+}
+
 void
 startrtclock()
 {
@@ -551,7 +577,6 @@
 	writertc(RTC_STATUSA, rtc_statusa);
 	writertc(RTC_STATUSB, RTCSB_24HR);
 
-	set_timer_freq(timer_freq, hz);
 	freq = calibrate_clocks();
 #ifdef CLK_CALIBRATION_LOOP
 	if (bootverbose) {
@@ -648,7 +673,7 @@
 	/* sec now contains the number of seconds, since Jan 1 1970,
 	   in the local time zone */
 
-	sec += tz_minuteswest * 60 + (wall_cmos_clock ? adjkerntz : 0);
+	sec += utc_offset();
 
 	y = time_second - sec;
 	if (y <= -2 || y >= 2) {
@@ -661,8 +686,7 @@
 	return;
 
 wrong_time:
-	printf("Invalid time in real time clock.\n");
-	printf("Check and reset the date immediately!\n");
+	printf("Invalid time in clock: check and reset the date!\n");
 }
 
 /*
@@ -686,7 +710,7 @@
 
 	/* Calculate local time to put in RTC */
 
-	tm -= tz_minuteswest * 60 + (wall_cmos_clock ? adjkerntz : 0);
+	tm -= utc_offset();
 
 	writertc(RTC_SEC, bin2bcd(tm%60)); tm /= 60;	/* Write back Seconds */
 	writertc(RTC_MIN, bin2bcd(tm%60)); tm /= 60;	/* Write back Minutes */
@@ -740,8 +764,8 @@
 	 * timecounter to user a simpler algorithm.
 	 */
 	if (!using_lapic_timer) {
-		intr_add_handler("clk", 0, (driver_intr_t *)clkintr, NULL,
-		    INTR_TYPE_CLK | INTR_FAST, NULL);
+		intr_add_handler("clk", 0, (driver_filter_t *)clkintr, NULL, NULL,
+		    INTR_TYPE_CLK, NULL);
 		i8254_intsrc = intr_lookup_source(0);
 		if (i8254_intsrc != NULL)
 			i8254_pending =
@@ -774,8 +798,8 @@
 
 		/* Enable periodic interrupts from the RTC. */
 		rtc_statusb |= RTCSB_PINTR;
-		intr_add_handler("rtc", 8, (driver_intr_t *)rtcintr, NULL,
-		    INTR_TYPE_CLK | INTR_FAST, NULL);
+		intr_add_handler("rtc", 8, (driver_filter_t *)rtcintr, NULL, NULL,
+		    INTR_TYPE_CLK, NULL);
 
 		writertc(RTC_STATUSB, rtc_statusb);
 		rtcin(RTC_INTR);
@@ -817,7 +841,7 @@
 	 * is is too generic.  Should use it everywhere.
 	 */
 	freq = timer_freq;
-	error = sysctl_handle_int(oidp, &freq, sizeof(freq), req);
+	error = sysctl_handle_int(oidp, &freq, 0, req);
 	if (error == 0 && req->newptr != NULL)
 		set_timer_freq(freq, hz);
 	return (error);
@@ -909,4 +933,5 @@
 
 DRIVER_MODULE(attimer, isa, attimer_driver, attimer_devclass, 0, 0);
 DRIVER_MODULE(attimer, acpi, attimer_driver, attimer_devclass, 0, 0);
+
 #endif /* DEV_ISA */
Index: ia32_syscall.c
===================================================================
RCS file: /home/cvs/src/sys/amd64/ia32/ia32_syscall.c,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L sys/amd64/ia32/ia32_syscall.c -L sys/amd64/ia32/ia32_syscall.c -u -r1.1.1.1 -r1.2
--- sys/amd64/ia32/ia32_syscall.c
+++ sys/amd64/ia32/ia32_syscall.c
@@ -36,7 +36,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/amd64/ia32/ia32_syscall.c,v 1.8 2005/04/12 23:18:53 jhb Exp $");
+__FBSDID("$FreeBSD: src/sys/amd64/ia32/ia32_syscall.c,v 1.19 2007/06/10 21:59:12 attilio Exp $");
 
 /*
  * 386 Trap and System call handling
@@ -56,6 +56,7 @@
 #include <sys/ktr.h>
 #include <sys/lock.h>
 #include <sys/mutex.h>
+#include <sys/ptrace.h>
 #include <sys/resourcevar.h>
 #include <sys/signalvar.h>
 #include <sys/syscall.h>
@@ -66,6 +67,7 @@
 #ifdef KTRACE
 #include <sys/ktrace.h>
 #endif
+#include <security/audit/audit.h>
 
 #include <vm/vm.h>
 #include <vm/vm_param.h>
@@ -84,10 +86,10 @@
 extern inthand_t IDTVEC(int0x80_syscall), IDTVEC(rsvd);
 extern const char *freebsd32_syscallnames[];
 
-void ia32_syscall(struct trapframe frame);	/* Called from asm code */
+void ia32_syscall(struct trapframe *frame);	/* Called from asm code */
 
 void
-ia32_syscall(struct trapframe frame)
+ia32_syscall(struct trapframe *frame)
 {
 	caddr_t params;
 	int i;
@@ -95,32 +97,27 @@
 	struct thread *td = curthread;
 	struct proc *p = td->td_proc;
 	register_t orig_tf_rflags;
-	u_int sticks;
 	int error;
 	int narg;
 	u_int32_t args[8];
 	u_int64_t args64[8];
 	u_int code;
+	ksiginfo_t ksi;
 
-	/*
-	 * note: PCPU_LAZY_INC() can only be used if we can afford
-	 * occassional inaccuracy in the count.
-	 */
-	PCPU_LAZY_INC(cnt.v_syscall);
-
-	sticks = td->td_sticks;
-	td->td_frame = &frame;
+	PCPU_INC(cnt.v_syscall);
+	td->td_pticks = 0;
+	td->td_frame = frame;
 	if (td->td_ucred != p->p_ucred) 
 		cred_update_thread(td);
-	params = (caddr_t)frame.tf_rsp + sizeof(u_int32_t);
-	code = frame.tf_rax;
-	orig_tf_rflags = frame.tf_rflags;
+	params = (caddr_t)frame->tf_rsp + sizeof(u_int32_t);
+	code = frame->tf_rax;
+	orig_tf_rflags = frame->tf_rflags;
 
 	if (p->p_sysent->sv_prepsyscall) {
 		/*
 		 * The prep code is MP aware.
 		 */
-		(*p->p_sysent->sv_prepsyscall)(&frame, args, &code, &params);
+		(*p->p_sysent->sv_prepsyscall)(frame, args, &code, &params);
 	} else {
 		/*
 		 * Need to check if this is a 32 bit or 64 bit syscall.
@@ -152,7 +149,7 @@
   	else
  		callp = &p->p_sysent->sv_table[code];
 
-	narg = callp->sy_narg & SYF_ARGMASK;
+	narg = callp->sy_narg;
 
 	/*
 	 * copyin and the ktrsyscall()/ktrsysret() code is MP-aware
@@ -170,27 +167,27 @@
 	if (KTRPOINT(td, KTR_SYSCALL))
 		ktrsyscall(code, narg, args64);
 #endif
-	/*
-	 * Try to run the syscall without Giant if the syscall
-	 * is MP safe.
-	 */
-	if ((callp->sy_narg & SYF_MPSAFE) == 0)
-		mtx_lock(&Giant);
+	CTR4(KTR_SYSC, "syscall enter thread %p pid %d proc %s code %d", td,
+	    td->td_proc->p_pid, td->td_proc->p_comm, code);
 
 	if (error == 0) {
 		td->td_retval[0] = 0;
-		td->td_retval[1] = frame.tf_rdx;
+		td->td_retval[1] = frame->tf_rdx;
 
 		STOPEVENT(p, S_SCE, narg);
 
+		PTRACESTOP_SC(p, td, S_PT_SCE);
+
+		AUDIT_SYSCALL_ENTER(code, td);
 		error = (*callp->sy_call)(td, args64);
+		AUDIT_SYSCALL_EXIT(error, td);
 	}
 
 	switch (error) {
 	case 0:
-		frame.tf_rax = td->td_retval[0];
-		frame.tf_rdx = td->td_retval[1];
-		frame.tf_rflags &= ~PSL_C;
+		frame->tf_rax = td->td_retval[0];
+		frame->tf_rdx = td->td_retval[1];
+		frame->tf_rflags &= ~PSL_C;
 		break;
 
 	case ERESTART:
@@ -198,7 +195,7 @@
 		 * Reconstruct pc, assuming lcall $X,y is 7 bytes,
 		 * int 0x80 is 2 bytes. We saved this in tf_err.
 		 */
-		frame.tf_rip -= frame.tf_err;
+		frame->tf_rip -= frame->tf_err;
 		break;
 
 	case EJUSTRETURN:
@@ -211,30 +208,43 @@
    			else
   				error = p->p_sysent->sv_errtbl[error];
 		}
-		frame.tf_rax = error;
-		frame.tf_rflags |= PSL_C;
+		frame->tf_rax = error;
+		frame->tf_rflags |= PSL_C;
 		break;
 	}
 
 	/*
-	 * Release Giant if we previously set it.
-	 */
-	if ((callp->sy_narg & SYF_MPSAFE) == 0)
-		mtx_unlock(&Giant);
-
-	/*
 	 * Traced syscall.
 	 */
 	if (orig_tf_rflags & PSL_T) {
-		frame.tf_rflags &= ~PSL_T;
-		trapsignal(td, SIGTRAP, 0);
+		frame->tf_rflags &= ~PSL_T;
+		ksiginfo_init_trap(&ksi);
+		ksi.ksi_signo = SIGTRAP;
+		ksi.ksi_code = TRAP_TRACE;
+		ksi.ksi_addr = (void *)frame->tf_rip;
+		trapsignal(td, &ksi);
 	}
 
 	/*
+	 * Check for misbehavior.
+	 */
+	WITNESS_WARN(WARN_PANIC, NULL, "System call %s returning",
+	    (code >= 0 && code < SYS_MAXSYSCALL) ? freebsd32_syscallnames[code] : "???");
+	KASSERT(td->td_critnest == 0,
+	    ("System call %s returning in a critical section",
+	    (code >= 0 && code < SYS_MAXSYSCALL) ? freebsd32_syscallnames[code] : "???"));
+	KASSERT(td->td_locks == 0,
+	    ("System call %s returning with %d locks held",
+	    (code >= 0 && code < SYS_MAXSYSCALL) ? freebsd32_syscallnames[code] : "???",
+	    td->td_locks));
+
+	/*
 	 * Handle reschedule and other end-of-syscall issues
 	 */
-	userret(td, &frame, sticks);
+	userret(td, frame);
 
+	CTR4(KTR_SYSC, "syscall exit thread %p pid %d proc %s code %d", td,
+	    td->td_proc->p_pid, td->td_proc->p_comm, code);
 #ifdef KTRACE
 	if (KTRPOINT(td, KTR_SYSRET))
 		ktrsysret(code, error, td->td_retval[0]);
@@ -246,11 +256,8 @@
 	 * is not the case, this code will need to be revisited.
 	 */
 	STOPEVENT(p, S_SCX, code);
-
-	WITNESS_WARN(WARN_PANIC, NULL, "System call %s returning",
-	    (code >= 0 && code < SYS_MAXSYSCALL) ? freebsd32_syscallnames[code] : "???");
-	mtx_assert(&sched_lock, MA_NOTOWNED);
-	mtx_assert(&Giant, MA_NOTOWNED);
+ 
+	PTRACESTOP_SC(p, td, S_PT_SCX);
 }
 
 
Index: ia32_sigtramp.S
===================================================================
RCS file: /home/cvs/src/sys/amd64/ia32/ia32_sigtramp.S,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L sys/amd64/ia32/ia32_sigtramp.S -L sys/amd64/ia32/ia32_sigtramp.S -u -r1.1.1.1 -r1.2
--- sys/amd64/ia32/ia32_sigtramp.S
+++ sys/amd64/ia32/ia32_sigtramp.S
@@ -23,7 +23,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD: src/sys/amd64/ia32/ia32_sigtramp.S,v 1.2 2003/08/22 23:19:02 peter Exp $
+ * $FreeBSD: src/sys/amd64/ia32/ia32_sigtramp.S,v 1.3 2006/09/23 13:42:09 davidxu Exp $
  */
 
 #include "opt_compat.h"
@@ -45,8 +45,6 @@
 	calll	*IA32_SIGF_HANDLER(%esp)
 	leal	IA32_SIGF_UC(%esp),%eax	/* get ucontext */
 	pushl	%eax
-	movl	IA32_UC_GS(%eax),%gs	/* restore %gs */
-	movl	IA32_UC_FS(%eax),%fs	/* restore %fs */
 	movl	IA32_UC_ES(%eax),%es	/* restore %es */
 	movl	IA32_UC_DS(%eax),%ds	/* restore %ds */
 	movl	$SYS_sigreturn,%eax
@@ -62,8 +60,6 @@
 	calll	*IA32_SIGF_HANDLER(%esp)
 	leal	IA32_SIGF_UC4(%esp),%eax/* get ucontext */
 	pushl	%eax
-	movl	IA32_UC4_GS(%eax),%gs	/* restore %gs */
-	movl	IA32_UC4_FS(%eax),%fs	/* restore %fs */
 	movl	IA32_UC4_ES(%eax),%es	/* restore %es */
 	movl	IA32_UC4_DS(%eax),%ds	/* restore %ds */
 	movl	$344,%eax		/* 4.x SYS_sigreturn */
Index: ia32_reg.c
===================================================================
RCS file: /home/cvs/src/sys/amd64/ia32/ia32_reg.c,v
retrieving revision 1.1.1.2
retrieving revision 1.2
diff -L sys/amd64/ia32/ia32_reg.c -L sys/amd64/ia32/ia32_reg.c -u -r1.1.1.2 -r1.2
--- sys/amd64/ia32/ia32_reg.c
+++ sys/amd64/ia32/ia32_reg.c
@@ -23,11 +23,11 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD: src/sys/amd64/ia32/ia32_reg.c,v 1.1.2.2 2005/12/28 19:30:40 ps Exp $
+ * $FreeBSD: src/sys/amd64/ia32/ia32_reg.c,v 1.3 2005/10/24 00:00:00 ps Exp $
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/amd64/ia32/ia32_reg.c,v 1.1.2.2 2005/12/28 19:30:40 ps Exp $");
+__FBSDID("$FreeBSD: src/sys/amd64/ia32/ia32_reg.c,v 1.3 2005/10/24 00:00:00 ps Exp $");
 
 #include "opt_compat.h"
 
@@ -46,7 +46,6 @@
 #include <sys/procfs.h>
 #include <sys/resourcevar.h>
 #include <sys/systm.h>
-#include <sys/signal.h>
 #include <sys/signalvar.h>
 #include <sys/stat.h>
 #include <sys/sx.h>
Index: ia32_exception.S
===================================================================
RCS file: /home/cvs/src/sys/amd64/ia32/ia32_exception.S,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L sys/amd64/ia32/ia32_exception.S -L sys/amd64/ia32/ia32_exception.S -u -r1.1.1.1 -r1.2
--- sys/amd64/ia32/ia32_exception.S
+++ sys/amd64/ia32/ia32_exception.S
@@ -23,7 +23,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD: src/sys/amd64/ia32/ia32_exception.S,v 1.4 2004/05/24 11:28:11 bde Exp $
+ * $FreeBSD: src/sys/amd64/ia32/ia32_exception.S,v 1.5 2006/12/17 06:48:39 kmacy Exp $
  */
 
 #include <machine/asmacros.h>
@@ -61,6 +61,7 @@
 	movq	%r14,TF_R14(%rsp)
 	movq	%r15,TF_R15(%rsp)
 	FAKE_MCOUNT(TF_RIP(%rsp))
+	movq	%rsp, %rdi
 	call	ia32_syscall
 	MEXITCOUNT
 	jmp	doreti
Index: ia32_signal.c
===================================================================
RCS file: /home/cvs/src/sys/amd64/ia32/ia32_signal.c,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L sys/amd64/ia32/ia32_signal.c -L sys/amd64/ia32/ia32_signal.c -u -r1.1.1.1 -r1.2
--- sys/amd64/ia32/ia32_signal.c
+++ sys/amd64/ia32/ia32_signal.c
@@ -32,7 +32,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/amd64/ia32/ia32_signal.c,v 1.10 2004/04/05 23:55:14 imp Exp $");
+__FBSDID("$FreeBSD: src/sys/amd64/ia32/ia32_signal.c,v 1.15 2006/10/05 01:56:10 davidxu Exp $");
 
 #include "opt_compat.h"
 
@@ -67,6 +67,7 @@
 #include <vm/vm_object.h>
 #include <vm/vm_extern.h>
 
+#include <compat/freebsd32/freebsd32_signal.h>
 #include <compat/freebsd32/freebsd32_util.h>
 #include <compat/freebsd32/freebsd32_proto.h>
 #include <compat/ia32/ia32_signal.h>
@@ -79,7 +80,7 @@
 #include <machine/cpufunc.h>
 
 #ifdef COMPAT_FREEBSD4
-static void freebsd4_ia32_sendsig(sig_t, int, sigset_t *, u_long);
+static void freebsd4_ia32_sendsig(sig_t, ksiginfo_t *, sigset_t *);
 #endif
 static void ia32_get_fpcontext(struct thread *td, struct ia32_mcontext *mcp);
 static int ia32_set_fpcontext(struct thread *td, const struct ia32_mcontext *mcp);
@@ -92,38 +93,14 @@
 static void
 ia32_get_fpcontext(struct thread *td, struct ia32_mcontext *mcp)
 {
-	struct savefpu *addr;
 
-	/*
-	 * XXX mc_fpstate might be misaligned, since its declaration is not
-	 * unportabilized using __attribute__((aligned(16))) like the
-	 * declaration of struct savemm, and anyway, alignment doesn't work
-	 * for auto variables since we don't use gcc's pessimal stack
-	 * alignment.  Work around this by abusing the spare fields after
-	 * mcp->mc_fpstate.
-	 *
-	 * XXX unpessimize most cases by only aligning when fxsave might be
-	 * called, although this requires knowing too much about
-	 * fpugetregs()'s internals.
-	 */
-	addr = (struct savefpu *)&mcp->mc_fpstate;
-	if (td == PCPU_GET(fpcurthread) && ((uintptr_t)(void *)addr & 0xF)) {
-		do
-			addr = (void *)((char *)addr + 4);
-		while ((uintptr_t)(void *)addr & 0xF);
-	}
-	mcp->mc_ownedfp = fpugetregs(td, addr);
-	if (addr != (struct savefpu *)&mcp->mc_fpstate) {
-		bcopy(addr, &mcp->mc_fpstate, sizeof(mcp->mc_fpstate));
-		bzero(&mcp->mc_spare2, sizeof(mcp->mc_spare2));
-	}
+	mcp->mc_ownedfp = fpugetregs(td, (struct savefpu *)&mcp->mc_fpstate);
 	mcp->mc_fpformat = fpuformat();
 }
 
 static int
 ia32_set_fpcontext(struct thread *td, const struct ia32_mcontext *mcp)
 {
-	struct savefpu *addr;
 
 	if (mcp->mc_fpformat == _MC_FPFMT_NODEV)
 		return (0);
@@ -134,31 +111,180 @@
 		fpstate_drop(td);
 	else if (mcp->mc_ownedfp == _MC_FPOWNED_FPU ||
 	    mcp->mc_ownedfp == _MC_FPOWNED_PCB) {
-		/* XXX align as above. */
-		addr = (struct savefpu *)&mcp->mc_fpstate;
-		if (td == PCPU_GET(fpcurthread) &&
-		    ((uintptr_t)(void *)addr & 0xF)) {
-			do
-				addr = (void *)((char *)addr + 4);
-			while ((uintptr_t)(void *)addr & 0xF);
-			bcopy(&mcp->mc_fpstate, addr, sizeof(mcp->mc_fpstate));
-		}
 		/*
 		 * XXX we violate the dubious requirement that fpusetregs()
 		 * be called with interrupts disabled.
 		 */
-		fpusetregs(td, addr);
-		/*
-		 * Don't bother putting things back where they were in the
-		 * misaligned case, since we know that the caller won't use
-		 * them again.
-		 */
+		fpusetregs(td, (struct savefpu *)&mcp->mc_fpstate);
 	} else
 		return (EINVAL);
 	return (0);
 }
 
 /*
+ * Get machine context.
+ */
+static int
+ia32_get_mcontext(struct thread *td, struct ia32_mcontext *mcp, int flags)
+{
+	struct trapframe *tp;
+
+	tp = td->td_frame;
+
+	PROC_LOCK(curthread->td_proc);
+	mcp->mc_onstack = sigonstack(tp->tf_rsp);
+	PROC_UNLOCK(curthread->td_proc);
+	mcp->mc_gs = td->td_pcb->pcb_gs;
+	mcp->mc_fs = td->td_pcb->pcb_fs;
+	mcp->mc_es = td->td_pcb->pcb_es;
+	mcp->mc_ds = td->td_pcb->pcb_ds;
+	mcp->mc_edi = tp->tf_rdi;
+	mcp->mc_esi = tp->tf_rsi;
+	mcp->mc_ebp = tp->tf_rbp;
+	mcp->mc_isp = tp->tf_rsp;
+	if (flags & GET_MC_CLEAR_RET) {
+		mcp->mc_eax = 0;
+		mcp->mc_edx = 0;
+	} else {
+		mcp->mc_eax = tp->tf_rax;
+		mcp->mc_edx = tp->tf_rdx;
+	}
+	mcp->mc_ebx = tp->tf_rbx;
+	mcp->mc_ecx = tp->tf_rcx;
+	mcp->mc_eip = tp->tf_rip;
+	mcp->mc_cs = tp->tf_cs;
+	mcp->mc_eflags = tp->tf_rflags;
+	mcp->mc_esp = tp->tf_rsp;
+	mcp->mc_ss = tp->tf_ss;
+	mcp->mc_len = sizeof(*mcp);
+	ia32_get_fpcontext(td, mcp);
+	return (0);
+}
+
+/*
+ * Set machine context.
+ *
+ * However, we don't set any but the user modifiable flags, and we won't
+ * touch the cs selector.
+ */
+static int
+ia32_set_mcontext(struct thread *td, const struct ia32_mcontext *mcp)
+{
+	struct trapframe *tp;
+	long rflags;
+	int ret;
+
+	tp = td->td_frame;
+	if (mcp->mc_len != sizeof(*mcp))
+		return (EINVAL);
+	rflags = (mcp->mc_eflags & PSL_USERCHANGE) |
+	    (tp->tf_rflags & ~PSL_USERCHANGE);
+	ret = ia32_set_fpcontext(td, mcp);
+	if (ret != 0)
+		return (ret);
+#if 0	/* XXX deal with load_fs() and friends */
+	tp->tf_fs = mcp->mc_fs;
+	tp->tf_es = mcp->mc_es;
+	tp->tf_ds = mcp->mc_ds;
+#endif
+	tp->tf_rdi = mcp->mc_edi;
+	tp->tf_rsi = mcp->mc_esi;
+	tp->tf_rbp = mcp->mc_ebp;
+	tp->tf_rbx = mcp->mc_ebx;
+	tp->tf_rdx = mcp->mc_edx;
+	tp->tf_rcx = mcp->mc_ecx;
+	tp->tf_rax = mcp->mc_eax;
+	/* trapno, err */
+	tp->tf_rip = mcp->mc_eip;
+	tp->tf_rflags = rflags;
+	tp->tf_rsp = mcp->mc_esp;
+	tp->tf_ss = mcp->mc_ss;
+#if 0	/* XXX deal with load_gs() and friends */
+	td->td_pcb->pcb_gs = mcp->mc_gs;
+#endif
+	td->td_pcb->pcb_flags |= PCB_FULLCTX;
+	return (0);
+}
+
+/*
+ * The first two fields of a ucontext_t are the signal mask and
+ * the machine context.  The next field is uc_link; we want to
+ * avoid destroying the link when copying out contexts.
+ */
+#define	UC_COPY_SIZE	offsetof(struct ia32_ucontext, uc_link)
+
+int
+freebsd32_getcontext(struct thread *td, struct freebsd32_getcontext_args *uap)
+{
+	struct ia32_ucontext uc;
+	int ret;
+
+	if (uap->ucp == NULL)
+		ret = EINVAL;
+	else {
+		ia32_get_mcontext(td, &uc.uc_mcontext, GET_MC_CLEAR_RET);
+		PROC_LOCK(td->td_proc);
+		uc.uc_sigmask = td->td_sigmask;
+		PROC_UNLOCK(td->td_proc);
+		ret = copyout(&uc, uap->ucp, UC_COPY_SIZE);
+	}
+	return (ret);
+}
+
+int
+freebsd32_setcontext(struct thread *td, struct freebsd32_setcontext_args *uap)
+{
+	struct ia32_ucontext uc;
+	int ret;	
+
+	if (uap->ucp == NULL)
+		ret = EINVAL;
+	else {
+		ret = copyin(uap->ucp, &uc, UC_COPY_SIZE);
+		if (ret == 0) {
+			ret = ia32_set_mcontext(td, &uc.uc_mcontext);
+			if (ret == 0) {
+				SIG_CANTMASK(uc.uc_sigmask);
+				PROC_LOCK(td->td_proc);
+				td->td_sigmask = uc.uc_sigmask;
+				PROC_UNLOCK(td->td_proc);
+			}
+		}
+	}
+	return (ret == 0 ? EJUSTRETURN : ret);
+}
+
+int
+freebsd32_swapcontext(struct thread *td, struct freebsd32_swapcontext_args *uap)
+{
+	struct ia32_ucontext uc;
+	int ret;	
+
+	if (uap->oucp == NULL || uap->ucp == NULL)
+		ret = EINVAL;
+	else {
+		ia32_get_mcontext(td, &uc.uc_mcontext, GET_MC_CLEAR_RET);
+		PROC_LOCK(td->td_proc);
+		uc.uc_sigmask = td->td_sigmask;
+		PROC_UNLOCK(td->td_proc);
+		ret = copyout(&uc, uap->oucp, UC_COPY_SIZE);
+		if (ret == 0) {
+			ret = copyin(uap->ucp, &uc, UC_COPY_SIZE);
+			if (ret == 0) {
+				ret = ia32_set_mcontext(td, &uc.uc_mcontext);
+				if (ret == 0) {
+					SIG_CANTMASK(uc.uc_sigmask);
+					PROC_LOCK(td->td_proc);
+					td->td_sigmask = uc.uc_sigmask;
+					PROC_UNLOCK(td->td_proc);
+				}
+			}
+		}
+	}
+	return (ret == 0 ? EJUSTRETURN : ret);
+}
+
+/*
  * Send an interrupt to process.
  *
  * Stack is set up to allow sigcode stored
@@ -170,18 +296,23 @@
  */
 #ifdef COMPAT_FREEBSD4
 static void
-freebsd4_ia32_sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
+freebsd4_ia32_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask)
 {
 	struct ia32_sigframe4 sf, *sfp;
+	struct siginfo32 siginfo;
 	struct proc *p;
 	struct thread *td;
 	struct sigacts *psp;
 	struct trapframe *regs;
 	int oonstack;
+	int sig;
 
 	td = curthread;
 	p = td->td_proc;
+	siginfo_to_siginfo32(&ksi->ksi_info, &siginfo);
+
 	PROC_LOCK_ASSERT(p, MA_OWNED);
+	sig = siginfo.si_signo;
 	psp = p->p_sigacts;
 	mtx_assert(&psp->ps_mtx, MA_OWNED);
 	regs = td->td_frame;
@@ -237,13 +368,12 @@
 		sf.sf_ah = (u_int32_t)(uintptr_t)catcher;
 
 		/* Fill in POSIX parts */
+		sf.sf_si = siginfo;
 		sf.sf_si.si_signo = sig;
-		sf.sf_si.si_code = code;
-		sf.sf_si.si_addr = regs->tf_addr;
 	} else {
 		/* Old FreeBSD-style arguments. */
-		sf.sf_siginfo = code;
-		sf.sf_addr = regs->tf_addr;
+		sf.sf_siginfo = siginfo.si_code;
+		sf.sf_addr = (u_int32_t)siginfo.si_addr;
 		sf.sf_ah = (u_int32_t)(uintptr_t)catcher;
 	}
 	mtx_unlock(&psp->ps_mtx);
@@ -275,23 +405,27 @@
 #endif	/* COMPAT_FREEBSD4 */
 
 void
-ia32_sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
+ia32_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask)
 {
 	struct ia32_sigframe sf, *sfp;
+	struct siginfo32 siginfo;
 	struct proc *p;
 	struct thread *td;
 	struct sigacts *psp;
 	char *sp;
 	struct trapframe *regs;
 	int oonstack;
+	int sig;
 
+	siginfo_to_siginfo32(&ksi->ksi_info, &siginfo);
 	td = curthread;
 	p = td->td_proc;
 	PROC_LOCK_ASSERT(p, MA_OWNED);
+	sig = siginfo.si_signo;
 	psp = p->p_sigacts;
 #ifdef COMPAT_FREEBSD4
 	if (SIGISMEMBER(psp->ps_freebsd4, sig)) {
-		freebsd4_ia32_sendsig(catcher, sig, mask, code);
+		freebsd4_ia32_sendsig(catcher, ksi, mask);
 		return;
 	}
 #endif
@@ -354,13 +488,12 @@
 		sf.sf_ah = (u_int32_t)(uintptr_t)catcher;
 
 		/* Fill in POSIX parts */
+		sf.sf_si = siginfo;
 		sf.sf_si.si_signo = sig;
-		sf.sf_si.si_code = code;
-		sf.sf_si.si_addr = regs->tf_addr;
 	} else {
 		/* Old FreeBSD-style arguments. */
-		sf.sf_siginfo = code;
-		sf.sf_addr = regs->tf_addr;
+		sf.sf_siginfo = siginfo.si_code;
+		sf.sf_addr = (u_int32_t)siginfo.si_addr;
 		sf.sf_ah = (u_int32_t)(uintptr_t)catcher;
 	}
 	mtx_unlock(&psp->ps_mtx);
@@ -415,6 +548,7 @@
 	struct trapframe *regs;
 	const struct ia32_ucontext4 *ucp;
 	int cs, eflags, error;
+	ksiginfo_t ksi;
 
 	error = copyin(uap->sigcntxp, &uc, sizeof(uc));
 	if (error != 0)
@@ -448,7 +582,12 @@
 	cs = ucp->uc_mcontext.mc_cs;
 	if (!CS_SECURE(cs)) {
 		printf("freebsd4_sigreturn: cs = 0x%x\n", cs);
-		trapsignal(td, SIGBUS, T_PROTFLT);
+		ksiginfo_init_trap(&ksi);
+		ksi.ksi_signo = SIGBUS;
+		ksi.ksi_code = BUS_OBJERR;
+		ksi.ksi_trapno = T_PROTFLT;
+		ksi.ksi_addr = (void *)regs->tf_rip;
+		trapsignal(td, &ksi);
 		return (EINVAL);
 	}
 
@@ -492,6 +631,7 @@
 	struct trapframe *regs;
 	const struct ia32_ucontext *ucp;
 	int cs, eflags, error, ret;
+	ksiginfo_t ksi;
 
 	error = copyin(uap->sigcntxp, &uc, sizeof(uc));
 	if (error != 0)
@@ -525,7 +665,12 @@
 	cs = ucp->uc_mcontext.mc_cs;
 	if (!CS_SECURE(cs)) {
 		printf("sigreturn: cs = 0x%x\n", cs);
-		trapsignal(td, SIGBUS, T_PROTFLT);
+		ksiginfo_init_trap(&ksi);
+		ksi.ksi_signo = SIGBUS;
+		ksi.ksi_code = BUS_OBJERR;
+		ksi.ksi_trapno = T_PROTFLT;
+		ksi.ksi_addr = (void *)regs->tf_rip;
+		trapsignal(td, &ksi);
 		return (EINVAL);
 	}
 
Index: bios.h
===================================================================
RCS file: /home/cvs/src/sys/amd64/include/pc/bios.h,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L sys/amd64/include/pc/bios.h -L sys/amd64/include/pc/bios.h -u -r1.1.1.1 -r1.2
--- sys/amd64/include/pc/bios.h
+++ sys/amd64/include/pc/bios.h
@@ -24,7 +24,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD: src/sys/amd64/include/pc/bios.h,v 1.18 2004/09/24 00:42:36 peter Exp $
+ * $FreeBSD: src/sys/amd64/include/pc/bios.h,v 1.19 2005/07/21 09:48:36 phk Exp $
  */
 
 #ifndef _MACHINE_PC_BIOS_H_
@@ -48,7 +48,22 @@
     u_int32_t	type;
 } __packed;
 
-const u_char *bios_string(u_int from, u_int to, const u_char *string, int len);
+struct bios_oem_signature {
+	char * anchor;		/* search anchor string in BIOS memory */
+	size_t offset;		/* offset from anchor (may be negative) */
+	size_t totlen;		/* total length of BIOS string to copy */
+} __packed;
+struct bios_oem_range {
+	u_int from;		/* shouldn't be below 0xe0000 */
+	u_int to;		/* shouldn't be above 0xfffff */
+} __packed;
+struct bios_oem {
+	struct bios_oem_range range;
+	struct bios_oem_signature signature[];
+} __packed;
+
+extern int
+bios_oem_strings(struct bios_oem *oem, u_char *buffer, size_t maxlen);
 
 
 #endif /* _MACHINE_PC_BIOS_H_ */
Index: pci_bus.c
===================================================================
RCS file: /home/cvs/src/sys/amd64/pci/pci_bus.c,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L sys/amd64/pci/pci_bus.c -L sys/amd64/pci/pci_bus.c -u -r1.1.1.1 -r1.2
--- sys/amd64/pci/pci_bus.c
+++ sys/amd64/pci/pci_bus.c
@@ -25,7 +25,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/amd64/pci/pci_bus.c,v 1.113.2.1 2005/09/18 02:55:10 imp Exp $");
+__FBSDID("$FreeBSD: src/sys/amd64/pci/pci_bus.c,v 1.122 2007/09/30 11:05:13 marius Exp $");
 
 #include "opt_cpu.h"
 
@@ -81,6 +81,38 @@
 	return (PCI_INVALID_IRQ);
 }
 
+/* Pass MSI requests up to the nexus. */
+
+static int
+legacy_pcib_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
+legacy_pcib_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
+legacy_pcib_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 const char *
 legacy_pcib_is_host_bridge(int bus, int slot, int func,
 			  uint32_t id, uint8_t class, uint8_t subclass,
@@ -244,6 +276,9 @@
 {
 
 	switch (which) {
+	case  PCIB_IVAR_DOMAIN:
+		*result = 0;
+		return 0;
 	case  PCIB_IVAR_BUS:
 		*result = legacy_get_pcibus(dev);
 		return 0;
@@ -257,6 +292,8 @@
 {
 
 	switch (which) {
+	case  PCIB_IVAR_DOMAIN:
+		return EINVAL;
 	case  PCIB_IVAR_BUS:
 		legacy_set_pcibus(dev, value);
 		return 0;
@@ -322,75 +359,19 @@
 	DEVMETHOD(pcib_read_config,	legacy_pcib_read_config),
 	DEVMETHOD(pcib_write_config,	legacy_pcib_write_config),
 	DEVMETHOD(pcib_route_interrupt,	legacy_pcib_route_interrupt),
+	DEVMETHOD(pcib_alloc_msi,	legacy_pcib_alloc_msi),
+	DEVMETHOD(pcib_release_msi,	pcib_release_msi),
+	DEVMETHOD(pcib_alloc_msix,	legacy_pcib_alloc_msix),
+	DEVMETHOD(pcib_release_msix,	pcib_release_msix),
+	DEVMETHOD(pcib_map_msi,		legacy_pcib_map_msi),
 
 	{ 0, 0 }
 };
 
-static driver_t legacy_pcib_driver = {
-	"pcib",
-	legacy_pcib_methods,
-	1,
-};
+static devclass_t hostb_devclass;
 
-DRIVER_MODULE(pcib, legacy, legacy_pcib_driver, pcib_devclass, 0, 0);
-
-
-/*
- * Provide a device to "eat" the host->pci bridges that we dug up above
- * and stop them showing up twice on the probes.  This also stops them
- * showing up as 'none' in pciconf -l.
- */
-static int
-pci_hostb_probe(device_t dev)
-{
-	u_int32_t id;
-
-	id = pci_get_devid(dev);
-
-	switch (id) {
-
-	/* VIA VT82C596 Power Managment Function */
-	case 0x30501106:
-		return ENXIO;
-
-	default:
-		break;
-	}
-
-	if (pci_get_class(dev) == PCIC_BRIDGE &&
-	    pci_get_subclass(dev) == PCIS_BRIDGE_HOST) {
-		device_set_desc(dev, "Host to PCI bridge");
-		device_quiet(dev);
-		return -10000;
-	}
-	return ENXIO;
-}
-
-static int
-pci_hostb_attach(device_t dev)
-{
-
-	return 0;
-}
-
-static device_method_t pci_hostb_methods[] = {
-	/* Device interface */
-	DEVMETHOD(device_probe,		pci_hostb_probe),
-	DEVMETHOD(device_attach,	pci_hostb_attach),
-	DEVMETHOD(device_shutdown,	bus_generic_shutdown),
-	DEVMETHOD(device_suspend,	bus_generic_suspend),
-	DEVMETHOD(device_resume,	bus_generic_resume),
-
-	{ 0, 0 }
-};
-static driver_t pci_hostb_driver = {
-	"hostb",
-	pci_hostb_methods,
-	1,
-};
-static devclass_t pci_hostb_devclass;
-
-DRIVER_MODULE(hostb, pci, pci_hostb_driver, pci_hostb_devclass, 0, 0);
+DEFINE_CLASS_0(pcib, legacy_pcib_driver, legacy_pcib_methods, 1);
+DRIVER_MODULE(pcib, legacy, legacy_pcib_driver, hostb_devclass, 0, 0);
 
 
 /*
@@ -435,12 +416,7 @@
 	{ 0, 0 }
 };
 
-static driver_t pcibus_pnp_driver = {
-	"pcibus_pnp",
-	pcibus_pnp_methods,
-	1,		/* no softc */
-};
-
 static devclass_t pcibus_pnp_devclass;
 
+DEFINE_CLASS_0(pcibus_pnp, pcibus_pnp_driver, pcibus_pnp_methods, 1);
 DRIVER_MODULE(pcibus_pnp, isa, pcibus_pnp_driver, pcibus_pnp_devclass, 0, 0);
Index: pci_cfgreg.c
===================================================================
RCS file: /home/cvs/src/sys/amd64/pci/pci_cfgreg.c,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L sys/amd64/pci/pci_cfgreg.c -L sys/amd64/pci/pci_cfgreg.c -u -r1.1.1.1 -r1.2
--- sys/amd64/pci/pci_cfgreg.c
+++ sys/amd64/pci/pci_cfgreg.c
@@ -27,7 +27,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/amd64/pci/pci_cfgreg.c,v 1.108 2005/01/21 05:56:41 peter Exp $");
+__FBSDID("$FreeBSD: src/sys/amd64/pci/pci_cfgreg.c,v 1.109.2.1 2007/12/06 08:25:43 jhb Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -38,12 +38,8 @@
 #include <dev/pci/pcireg.h>
 #include <machine/pci_cfgreg.h>
 
-static int cfgmech;
-static int devmax;
-
 static int	pcireg_cfgread(int bus, int slot, int func, int reg, int bytes);
 static void	pcireg_cfgwrite(int bus, int slot, int func, int reg, int data, int bytes);
-static int	pcireg_cfgopen(void);
 
 static struct mtx pcicfg_mtx;
 
@@ -57,8 +53,6 @@
 
 	if (opened)
 		return (1);
-	if (pcireg_cfgopen() == 0)
-		return (0);
 	mtx_init(&pcicfg_mtx, "pcicfg", NULL, MTX_SPIN);
 	opened = 1;
 	return (1);
@@ -109,26 +103,12 @@
 {
 	int dataport = 0;
 
-	if (bus <= PCI_BUSMAX
-	    && slot < devmax
-	    && func <= PCI_FUNCMAX
-	    && reg <= PCI_REGMAX
-	    && bytes != 3
-	    && (unsigned) bytes <= 4
-	    && (reg & (bytes - 1)) == 0) {
-		switch (cfgmech) {
-		case 1:
-			outl(CONF1_ADDR_PORT, (1 << 31)
-			    | (bus << 16) | (slot << 11) 
-			    | (func << 8) | (reg & ~0x03));
-			dataport = CONF1_DATA_PORT + (reg & 0x03);
-			break;
-		case 2:
-			outb(CONF2_ENABLE_PORT, 0xf0 | (func << 1));
-			outb(CONF2_FORWARD_PORT, bus);
-			dataport = 0xc000 | (slot << 8) | reg;
-			break;
-		}
+	if (bus <= PCI_BUSMAX && slot < 32 && func <= PCI_FUNCMAX &&
+	    reg <= PCI_REGMAX && bytes != 3 && (unsigned) bytes <= 4 &&
+	    (reg & (bytes - 1)) == 0) {
+		outl(CONF1_ADDR_PORT, (1 << 31) | (bus << 16) | (slot << 11) 
+		    | (func << 8) | (reg & ~0x03));
+		dataport = CONF1_DATA_PORT + (reg & 0x03);
 	}
 	return (dataport);
 }
@@ -137,15 +117,11 @@
 static void
 pci_cfgdisable(void)
 {
-	switch (cfgmech) {
-	case 1:
-		outl(CONF1_ADDR_PORT, 0);
-		break;
-	case 2:
-		outb(CONF2_ENABLE_PORT, 0);
-		outb(CONF2_FORWARD_PORT, 0);
-		break;
-	}
+
+	/*
+	 * Do nothing.  Writing a 0 to the address port can apparently
+	 * confuse some bridges and cause spurious access failures.
+	 */
 }
 
 static int
@@ -197,131 +173,3 @@
 	}
 	mtx_unlock_spin(&pcicfg_mtx);
 }
-
-/* check whether the configuration mechanism has been correctly identified */
-static int
-pci_cfgcheck(int maxdev)
-{
-	uint32_t id, class;
-	uint8_t header;
-	uint8_t device;
-	int port;
-
-	if (bootverbose) 
-		printf("pci_cfgcheck:\tdevice ");
-
-	for (device = 0; device < maxdev; device++) {
-		if (bootverbose) 
-			printf("%d ", device);
-
-		port = pci_cfgenable(0, device, 0, 0, 4);
-		id = inl(port);
-		if (id == 0 || id == 0xffffffff)
-			continue;
-
-		port = pci_cfgenable(0, device, 0, 8, 4);
-		class = inl(port) >> 8;
-		if (bootverbose)
-			printf("[class=%06x] ", class);
-		if (class == 0 || (class & 0xf870ff) != 0)
-			continue;
-
-		port = pci_cfgenable(0, device, 0, 14, 1);
-		header = inb(port);
-		if (bootverbose)
-			printf("[hdr=%02x] ", header);
-		if ((header & 0x7e) != 0)
-			continue;
-
-		if (bootverbose)
-			printf("is there (id=%08x)\n", id);
-
-		pci_cfgdisable();
-		return (1);
-	}
-	if (bootverbose) 
-		printf("-- nothing found\n");
-
-	pci_cfgdisable();
-	return (0);
-}
-
-static int
-pcireg_cfgopen(void)
-{
-	uint32_t mode1res, oldval1;
-	uint8_t mode2res, oldval2;
-
-	oldval1 = inl(CONF1_ADDR_PORT);
-
-	if (bootverbose) {
-		printf("pci_open(1):\tmode 1 addr port (0x0cf8) is 0x%08x\n",
-		    oldval1);
-	}
-
-	if ((oldval1 & CONF1_ENABLE_MSK) == 0) {
-
-		cfgmech = 1;
-		devmax = 32;
-
-		outl(CONF1_ADDR_PORT, CONF1_ENABLE_CHK);
-		DELAY(1);
-		mode1res = inl(CONF1_ADDR_PORT);
-		outl(CONF1_ADDR_PORT, oldval1);
-
-		if (bootverbose)
-			printf("pci_open(1a):\tmode1res=0x%08x (0x%08lx)\n", 
-			    mode1res, CONF1_ENABLE_CHK);
-
-		if (mode1res) {
-			if (pci_cfgcheck(32)) 
-				return (cfgmech);
-		}
-
-		outl(CONF1_ADDR_PORT, CONF1_ENABLE_CHK1);
-		mode1res = inl(CONF1_ADDR_PORT);
-		outl(CONF1_ADDR_PORT, oldval1);
-
-		if (bootverbose)
-			printf("pci_open(1b):\tmode1res=0x%08x (0x%08lx)\n", 
-			    mode1res, CONF1_ENABLE_CHK1);
-
-		if ((mode1res & CONF1_ENABLE_MSK1) == CONF1_ENABLE_RES1) {
-			if (pci_cfgcheck(32)) 
-				return (cfgmech);
-		}
-	}
-
-	oldval2 = inb(CONF2_ENABLE_PORT);
-
-	if (bootverbose) {
-		printf("pci_open(2):\tmode 2 enable port (0x0cf8) is 0x%02x\n",
-		    oldval2);
-	}
-
-	if ((oldval2 & 0xf0) == 0) {
-
-		cfgmech = 2;
-		devmax = 16;
-
-		outb(CONF2_ENABLE_PORT, CONF2_ENABLE_CHK);
-		mode2res = inb(CONF2_ENABLE_PORT);
-		outb(CONF2_ENABLE_PORT, oldval2);
-
-		if (bootverbose)
-			printf("pci_open(2a):\tmode2res=0x%02x (0x%02x)\n", 
-			    mode2res, CONF2_ENABLE_CHK);
-
-		if (mode2res == CONF2_ENABLE_RES) {
-			if (bootverbose)
-				printf("pci_open(2a):\tnow trying mechanism 2\n");
-
-			if (pci_cfgcheck(16)) 
-				return (cfgmech);
-		}
-	}
-
-	cfgmech = 0;
-	devmax = 0;
-	return (cfgmech);
-}


More information about the Midnightbsd-cvs mailing list