Date: Tue, 18 May 2004 11:31:21 -0700 (PDT) From: Warner Losh <imp@FreeBSD.org> To: Perforce Change Reviews <perforce@FreeBSD.org> Subject: PERFORCE change 53000 for review Message-ID: <200405181831.i4IIVL8G084429@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=53000 Change 53000 by imp@imp_pacopaco on 2004/05/18 11:31:01 IFC @52994 Affected files ... .. //depot/projects/power/sys/Makefile#3 integrate .. //depot/projects/power/sys/alpha/alpha/elf_machdep.c#4 integrate .. //depot/projects/power/sys/alpha/include/_stdint.h#2 integrate .. //depot/projects/power/sys/amd64/acpica/madt.c#4 integrate .. //depot/projects/power/sys/amd64/amd64/apic_vector.S#4 integrate .. //depot/projects/power/sys/amd64/amd64/cpu_switch.S#5 integrate .. //depot/projects/power/sys/amd64/amd64/elf_machdep.c#4 integrate .. //depot/projects/power/sys/amd64/amd64/genassym.c#7 integrate .. //depot/projects/power/sys/amd64/amd64/intr_machdep.c#2 integrate .. //depot/projects/power/sys/amd64/amd64/io_apic.c#2 integrate .. //depot/projects/power/sys/amd64/amd64/legacy.c#3 integrate .. //depot/projects/power/sys/amd64/amd64/local_apic.c#4 integrate .. //depot/projects/power/sys/amd64/amd64/machdep.c#8 integrate .. //depot/projects/power/sys/amd64/amd64/mp_machdep.c#5 integrate .. //depot/projects/power/sys/amd64/amd64/mptable.c#3 integrate .. //depot/projects/power/sys/amd64/amd64/mptable_pci.c#2 integrate .. //depot/projects/power/sys/amd64/amd64/nexus.c#5 integrate .. //depot/projects/power/sys/amd64/amd64/pmap.c#10 integrate .. //depot/projects/power/sys/amd64/amd64/support.S#8 integrate .. //depot/projects/power/sys/amd64/conf/GENERIC#7 integrate .. //depot/projects/power/sys/amd64/conf/NOTES#2 integrate .. //depot/projects/power/sys/amd64/include/_stdint.h#3 integrate .. //depot/projects/power/sys/amd64/include/apicvar.h#2 integrate .. //depot/projects/power/sys/amd64/include/intr_machdep.h#2 integrate .. //depot/projects/power/sys/amd64/include/legacyvar.h#3 integrate .. //depot/projects/power/sys/amd64/include/pcb.h#5 integrate .. //depot/projects/power/sys/amd64/include/pmap.h#7 integrate .. //depot/projects/power/sys/amd64/include/smp.h#4 integrate .. //depot/projects/power/sys/amd64/isa/atpic.c#5 integrate .. //depot/projects/power/sys/amd64/isa/atpic_vector.S#3 integrate .. //depot/projects/power/sys/amd64/isa/clock.c#6 integrate .. //depot/projects/power/sys/amd64/isa/elcr.c#1 branch .. //depot/projects/power/sys/amd64/isa/icu.h#5 integrate .. //depot/projects/power/sys/amd64/isa/nmi.c#3 integrate .. //depot/projects/power/sys/amd64/pci/pci_bus.c#6 integrate .. //depot/projects/power/sys/arm/arm/elf_machdep.c#2 integrate .. //depot/projects/power/sys/arm/arm/support.S#2 integrate .. //depot/projects/power/sys/arm/include/_stdint.h#2 integrate .. //depot/projects/power/sys/boot/Makefile#5 integrate .. //depot/projects/power/sys/boot/common/loader.8#4 integrate .. //depot/projects/power/sys/boot/forth/loader.conf.5#3 integrate .. //depot/projects/power/sys/boot/i386/boot0/boot0.S#2 integrate .. //depot/projects/power/sys/boot/i386/boot2/boot1.S#3 integrate .. //depot/projects/power/sys/boot/i386/boot2/sio.S#3 integrate .. //depot/projects/power/sys/boot/i386/btx/btx/btx.S#3 integrate .. //depot/projects/power/sys/boot/i386/btx/btxldr/btxldr.S#3 integrate .. //depot/projects/power/sys/boot/i386/libi386/amd64_tramp.S#3 integrate .. //depot/projects/power/sys/boot/i386/pxeldr/pxeldr.S#3 integrate .. //depot/projects/power/sys/boot/pc98/boot2/serial_16550.S#3 integrate .. //depot/projects/power/sys/boot/pc98/boot2/serial_8251.S#3 integrate .. //depot/projects/power/sys/boot/pc98/btx/btx/btx.S#3 integrate .. //depot/projects/power/sys/boot/pc98/btx/btxldr/btxldr.S#3 integrate .. //depot/projects/power/sys/conf/files.alpha#3 integrate .. //depot/projects/power/sys/conf/files.amd64#7 integrate .. //depot/projects/power/sys/conf/files.arm#2 integrate .. //depot/projects/power/sys/conf/files.i386#12 integrate .. //depot/projects/power/sys/conf/files.ia64#7 integrate .. //depot/projects/power/sys/conf/files.pc98#7 integrate .. //depot/projects/power/sys/conf/kmod.mk#6 integrate .. //depot/projects/power/sys/conf/options.pc98#6 integrate .. //depot/projects/power/sys/ddb/db_elf.c#3 integrate .. //depot/projects/power/sys/dev/acpica/acpivar.h#15 integrate .. //depot/projects/power/sys/dev/ata/ata-lowlevel.c#11 integrate .. //depot/projects/power/sys/dev/ciss/ciss.c#10 integrate .. //depot/projects/power/sys/dev/ciss/cissreg.h#5 integrate .. //depot/projects/power/sys/dev/cy/cy.c#3 integrate .. //depot/projects/power/sys/dev/fdc/fdc.c#1 branch .. //depot/projects/power/sys/dev/fdc/fdcreg.h#1 branch .. //depot/projects/power/sys/dev/firewire/firewire.c#10 integrate .. //depot/projects/power/sys/dev/ichwd/ichwd.c#2 integrate .. //depot/projects/power/sys/dev/iicbus/iic.c#3 integrate .. //depot/projects/power/sys/dev/iicbus/iicbus.c#3 integrate .. //depot/projects/power/sys/dev/md/md.c#10 integrate .. //depot/projects/power/sys/dev/puc/pucdata.c#8 integrate .. //depot/projects/power/sys/dev/smbus/smb.c#3 integrate .. //depot/projects/power/sys/dev/smbus/smb.h#2 integrate .. //depot/projects/power/sys/dev/twa/twa.h#2 integrate .. //depot/projects/power/sys/dev/twa/twa_cam.c#2 integrate .. //depot/projects/power/sys/dev/twa/twa_freebsd.c#3 integrate .. //depot/projects/power/sys/dev/uart/uart_cpu_pc98.c#4 integrate .. //depot/projects/power/sys/fs/fifofs/fifo_vnops.c#5 integrate .. //depot/projects/power/sys/i386/conf/NOTES#14 integrate .. //depot/projects/power/sys/i386/i386/elf_machdep.c#4 integrate .. //depot/projects/power/sys/i386/include/_stdint.h#2 integrate .. //depot/projects/power/sys/ia64/conf/NOTES#2 integrate .. //depot/projects/power/sys/ia64/ia64/elf_machdep.c#5 integrate .. //depot/projects/power/sys/ia64/include/_stdint.h#2 integrate .. //depot/projects/power/sys/isa/fd.c#7 delete .. //depot/projects/power/sys/isa/fdreg.h#3 delete .. //depot/projects/power/sys/kern/kern_linker.c#5 integrate .. //depot/projects/power/sys/kern/kern_synch.c#6 integrate .. //depot/projects/power/sys/kern/link_elf.c#2 integrate .. //depot/projects/power/sys/kern/link_elf_obj.c#2 integrate .. //depot/projects/power/sys/kern/subr_sleepqueue.c#4 integrate .. //depot/projects/power/sys/libkern/arm/bzero.S#2 delete .. //depot/projects/power/sys/libkern/arm/memcmp.S#2 delete .. //depot/projects/power/sys/libkern/arm/memcpy.S#2 delete .. //depot/projects/power/sys/libkern/arm/memcpy_arm.S#2 delete .. //depot/projects/power/sys/libkern/arm/memcpy_xscale.S#2 delete .. //depot/projects/power/sys/libkern/arm/memset.S#2 delete .. //depot/projects/power/sys/libkern/arm/strcmp.S#2 delete .. //depot/projects/power/sys/libkern/arm/strncmp.S#2 delete .. //depot/projects/power/sys/modules/Makefile#11 integrate .. //depot/projects/power/sys/modules/fdc/Makefile#2 integrate .. //depot/projects/power/sys/netgraph/ng_ether.c#7 integrate .. //depot/projects/power/sys/pc98/conf/NOTES#10 integrate .. //depot/projects/power/sys/powerpc/include/_stdint.h#2 integrate .. //depot/projects/power/sys/powerpc/powerpc/elf_machdep.c#4 integrate .. //depot/projects/power/sys/security/mac_portacl/mac_portacl.c#3 integrate .. //depot/projects/power/sys/sparc64/include/_stdint.h#2 integrate .. //depot/projects/power/sys/sparc64/sparc64/elf_machdep.c#4 integrate .. //depot/projects/power/sys/sys/linker.h#2 integrate .. //depot/projects/power/sys/sys/mbuf.h#12 integrate .. //depot/projects/power/sys/ufs/ffs/ffs_alloc.c#5 integrate Differences ... ==== //depot/projects/power/sys/Makefile#3 (text+ko) ==== @@ -1,7 +1,9 @@ -# $FreeBSD: src/sys/Makefile,v 1.29 2004/01/17 03:28:27 ru Exp $ +# $FreeBSD: src/sys/Makefile,v 1.30 2004/05/16 00:19:12 cognet Exp $ # The boot loader +.if ${MACHINE_ARCH} != "arm" SUBDIR= boot +.endif # Loadable kernel modules .if defined(MODULES_WITH_WORLD) ==== //depot/projects/power/sys/alpha/alpha/elf_machdep.c#4 (text+ko) ==== @@ -24,7 +24,7 @@ */ #include <sys/cdefs.h> -__FBSDID("$FreeBSD: src/sys/alpha/alpha/elf_machdep.c,v 1.17 2003/12/23 02:42:38 peter Exp $"); +__FBSDID("$FreeBSD: src/sys/alpha/alpha/elf_machdep.c,v 1.18 2004/05/16 20:00:27 peter Exp $"); #include <sys/param.h> #include <sys/kernel.h> @@ -108,9 +108,9 @@ /* Process one elf relocation with addend. */ static int -elf_reloc_internal(linker_file_t lf, const void *data, int type, int local) +elf_reloc_internal(linker_file_t lf, Elf_Addr relocbase, const void *data, + int type, int local, elf_lookup_fn lookup) { - Elf_Addr relocbase = (Elf_Addr) lf->address; Elf_Addr *where; Elf_Addr addr; Elf_Addr addend; @@ -152,7 +152,7 @@ break; case R_ALPHA_REFQUAD: - addr = elf_lookup(lf, symidx, 1); + addr = lookup(lf, symidx, 1); if (addr == 0) return -1; addr += addend; @@ -161,7 +161,7 @@ break; case R_ALPHA_GLOB_DAT: - addr = elf_lookup(lf, symidx, 1); + addr = lookup(lf, symidx, 1); if (addr == 0) return -1; addr += addend; @@ -171,7 +171,7 @@ case R_ALPHA_JMP_SLOT: /* No point in lazy binding for kernel modules. */ - addr = elf_lookup(lf, symidx, 1); + addr = lookup(lf, symidx, 1); if (addr == 0) return -1; if (*where != addr) @@ -198,17 +198,19 @@ } int -elf_reloc(linker_file_t lf, const void *data, int type) +elf_reloc(linker_file_t lf, Elf_Addr relocbase, const void *data, int type, + elf_lookup_fn lookup) { - return (elf_reloc_internal(lf, data, type, 0)); + return (elf_reloc_internal(lf, relocbase, data, type, 0, lookup)); } int -elf_reloc_local(linker_file_t lf, const void *data, int type) +elf_reloc_local(linker_file_t lf, Elf_Addr relocbase, const void *data, + int type, elf_lookup_fn lookup) { - return (elf_reloc_internal(lf, data, type, 1)); + return (elf_reloc_internal(lf, relocbase, data, type, 1, lookup)); } int ==== //depot/projects/power/sys/alpha/include/_stdint.h#2 (text+ko) ==== @@ -34,7 +34,7 @@ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * - * $FreeBSD: src/sys/alpha/include/_stdint.h,v 1.1 2002/07/29 17:41:06 mike Exp $ + * $FreeBSD: src/sys/alpha/include/_stdint.h,v 1.2 2004/05/18 16:04:56 stefanf Exp $ */ #ifndef _MACHINE__STDINT_H_ @@ -160,11 +160,11 @@ /* Limits of wchar_t. */ #define WCHAR_MIN INT32_MIN #define WCHAR_MAX INT32_MAX +#endif /* Limits of wint_t. */ #define WINT_MIN INT32_MIN #define WINT_MAX INT32_MAX -#endif #endif /* !defined(__cplusplus) || defined(__STDC_LIMIT_MACROS) */ ==== //depot/projects/power/sys/amd64/acpica/madt.c#4 (text+ko) ==== @@ -28,7 +28,7 @@ */ #include <sys/cdefs.h> -__FBSDID("$FreeBSD: src/sys/amd64/acpica/madt.c,v 1.11 2004/01/30 00:24:45 peter Exp $"); +__FBSDID("$FreeBSD: src/sys/amd64/acpica/madt.c,v 1.12 2004/05/16 20:30:46 peter Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -49,6 +49,7 @@ #include <machine/specialreg.h> #include "acpi.h" +#include <contrib/dev/acpica/actables.h> #include <dev/acpica/acpivar.h> #include <dev/pci/pcivar.h> @@ -69,14 +70,15 @@ u_int la_apic_id:8; } lapics[NLAPICS + 1]; +static int madt_found_sci_override; static MULTIPLE_APIC_TABLE *madt; static vm_paddr_t madt_physaddr; static vm_offset_t madt_length; MALLOC_DEFINE(M_MADT, "MADT Table", "ACPI MADT Table Items"); -static u_char interrupt_polarity(UINT16 Polarity); -static u_char interrupt_trigger(UINT16 TriggerMode); +static enum intr_polarity interrupt_polarity(UINT16 Polarity, UINT8 Source); +static enum intr_trigger interrupt_trigger(UINT16 TriggerMode, 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); @@ -157,6 +159,7 @@ { ACPI_TABLE_HEADER *header; vm_offset_t length; + void *table; header = madt_map(pa, offset, sizeof(ACPI_TABLE_HEADER)); if (strncmp(header->Signature, sig, 4) != 0) { @@ -165,7 +168,14 @@ } length = header->Length; madt_unmap(header, sizeof(ACPI_TABLE_HEADER)); - return (madt_map(pa, offset, length)); + table = madt_map(pa, offset, length); + if (ACPI_FAILURE(AcpiTbVerifyTableChecksum(table))) { + if (bootverbose) + printf("MADT: Failed checksum for table %s\n", sig); + madt_unmap(table, length); + return (NULL); + } + return (table); } static void @@ -215,6 +225,16 @@ * Page 0 is used to map in the headers of candidate ACPI tables. */ if (rsdp->Revision >= 2) { + /* + * 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 (bootverbose) + printf("MADT: RSDP failed extended checksum\n"); + return (ENXIO); + } xsdt = madt_map_table(rsdp->XsdtPhysicalAddress, 1, XSDT_SIG); if (xsdt == NULL) { if (bootverbose) @@ -251,6 +271,16 @@ printf("MADT: Found table at 0x%jx\n", (uintmax_t)madt_physaddr); + /* + * Verify that we can map the full table and that its checksum is + * correct, etc. + */ + madt = madt_map_table(madt_physaddr, 0, APIC_SIG); + if (madt == NULL) + return (ENXIO); + madt_unmap_table(madt); + madt = NULL; + return (0); } @@ -273,7 +303,6 @@ printf("Table '%.4s' at 0x%jx\n", table->Signature, (uintmax_t)address); - /* XXX: Verify checksum? */ if (strncmp(table->Signature, APIC_SIG, 4) != 0) { madt_unmap(table, sizeof(ACPI_TABLE_HEADER)); return (0); @@ -325,6 +354,8 @@ static int madt_setup_io(void) { + void *ioapic; + u_int pin; int i; /* Try to initialize ACPI so that we can access the FADT. */ @@ -337,11 +368,30 @@ } /* First, we run through adding I/O APIC's. */ + if (madt->PCATCompat) + ioapic_enable_mixed_mode(); madt_walk_table(madt_parse_apics, NULL); /* Second, we run through the table tweaking interrupt sources. */ madt_walk_table(madt_parse_ints, NULL); + /* + * If there was not an explicit override entry for the SCI, + * 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); + else { + printf( + "MADT: Forcing active-low polarity and level trigger for SCI\n"); + ioapic_set_polarity(ioapic, pin, INTR_POLARITY_LOW); + ioapic_set_triggermode(ioapic, pin, INTR_TRIGGER_LEVEL); + } + } + /* Third, we register all the I/O APIC's. */ for (i = 0; i < NIOAPICS; i++) if (ioapics[i].io_apic != NULL) @@ -446,35 +496,44 @@ } /* - * Determine properties of an interrupt source. Note that for ACPI, - * these are only used for ISA interrupts, so we assume ISA bus values - * (Active Hi, Edge Triggered) for conforming values. + * Determine properties of an interrupt source. Note that for ACPI these + * functions are only used for ISA interrupts, so we assume ISA bus values + * (Active Hi, Edge Triggered) for conforming values except for the ACPI + * SCI for which we use Active Lo, Level Triggered. */ -static u_char -interrupt_polarity(UINT16 Polarity) +static enum intr_polarity +interrupt_polarity(UINT16 Polarity, UINT8 Source) { switch (Polarity) { case POLARITY_CONFORMS: + if (Source == AcpiGbl_FADT->SciInt) + return (INTR_POLARITY_LOW); + else + return (INTR_POLARITY_HIGH); case POLARITY_ACTIVE_HIGH: - return (1); + return (INTR_POLARITY_HIGH); case POLARITY_ACTIVE_LOW: - return (0); + return (INTR_POLARITY_LOW); default: panic("Bogus Interrupt Polarity"); } } -static u_char -interrupt_trigger(UINT16 TriggerMode) +static enum intr_trigger +interrupt_trigger(UINT16 TriggerMode, UINT8 Source) { switch (TriggerMode) { case TRIGGER_CONFORMS: + if (Source == AcpiGbl_FADT->SciInt) + return (INTR_TRIGGER_LEVEL); + else + return (INTR_TRIGGER_EDGE); case TRIGGER_EDGE: - return (1); + return (INTR_TRIGGER_EDGE); case TRIGGER_LEVEL: - return (0); + return (INTR_TRIGGER_LEVEL); default: panic("Bogus Interrupt Trigger Mode"); } @@ -532,7 +591,9 @@ { void *new_ioapic, *old_ioapic; u_int new_pin, old_pin; - int force_lo; + enum intr_trigger trig; + enum intr_polarity pol; + char buf[64]; if (bootverbose) printf("MADT: intr override: source %u, irq %u\n", @@ -546,18 +607,46 @@ } /* - * If the SCI is remapped to a non-ISA global interrupt, - * force it to level trigger and active-lo polarity. + * Lookup the appropriate trigger and polarity modes for this + * entry. + */ + trig = interrupt_trigger(intr->TriggerMode, intr->Source); + pol = interrupt_polarity(intr->Polarity, intr->Source); + + /* * If the SCI is identity mapped but has edge trigger and - * active-hi polarity, also force it to use level/lo. + * active-hi polarity or the force_sci_lo tunable is set, + * force it to use level/lo. */ - force_lo = 0; - if (intr->Source == AcpiGbl_FADT->SciInt) - if (intr->Interrupt > 15 || (intr->Interrupt == intr->Source && - intr->TriggerMode == TRIGGER_EDGE && - intr->Polarity == POLARITY_ACTIVE_HIGH)) - force_lo = 1; + if (intr->Source == AcpiGbl_FADT->SciInt) { + madt_found_sci_override = 1; + if (getenv_string("hw.acpi.sci.trigger", buf, sizeof(buf))) { + if (tolower(buf[0]) == 'e') + trig = INTR_TRIGGER_EDGE; + else if (tolower(buf[0]) == 'l') + trig = INTR_TRIGGER_LEVEL; + else + panic( + "Invalid trigger %s: must be 'edge' or 'level'", + buf); + printf("MADT: Forcing SCI to %s trigger\n", + trig == INTR_TRIGGER_EDGE ? "edge" : "level"); + } + if (getenv_string("hw.acpi.sci.polarity", buf, sizeof(buf))) { + if (tolower(buf[0]) == 'h') + pol = INTR_POLARITY_HIGH; + else if (tolower(buf[0]) == 'l') + pol = INTR_POLARITY_LOW; + else + panic( + "Invalid polarity %s: must be 'high' or 'low'", + buf); + printf("MADT: Forcing SCI to active %s polarity\n", + pol == INTR_POLARITY_HIGH ? "high" : "low"); + } + } + /* Remap the IRQ if it is mapped to a different interrupt vector. */ if (intr->Source != intr->Interrupt) { /* * If the SCI is remapped to a non-ISA global interrupt, @@ -577,18 +666,10 @@ intr->Source) ioapic_disable_pin(old_ioapic, old_pin); } - if (force_lo) { - printf( - "MADT: Forcing active-lo polarity and level trigger for IRQ %d\n", - intr->Source); - ioapic_set_polarity(new_ioapic, new_pin, 0); - ioapic_set_triggermode(new_ioapic, new_pin, 0); - } else { - ioapic_set_polarity(new_ioapic, new_pin, - interrupt_polarity(intr->Polarity)); - ioapic_set_triggermode(new_ioapic, new_pin, - interrupt_trigger(intr->TriggerMode)); - } + + /* Program the polarity and trigger mode. */ + ioapic_set_triggermode(new_ioapic, new_pin, trig); + ioapic_set_polarity(new_ioapic, new_pin, pol); } /* @@ -609,10 +690,10 @@ ioapic_set_nmi(ioapic, pin); if (nmi->TriggerMode != TRIGGER_CONFORMS) ioapic_set_triggermode(ioapic, pin, - interrupt_trigger(nmi->TriggerMode)); + interrupt_trigger(nmi->TriggerMode, 0)); if (nmi->Polarity != TRIGGER_CONFORMS) ioapic_set_polarity(ioapic, pin, - interrupt_polarity(nmi->Polarity)); + interrupt_polarity(nmi->Polarity, 0)); } /* @@ -638,10 +719,10 @@ lapic_set_lvt_mode(apic_id, pin, APIC_LVT_DM_NMI); if (nmi->TriggerMode != TRIGGER_CONFORMS) lapic_set_lvt_triggermode(apic_id, pin, - interrupt_trigger(nmi->TriggerMode)); + interrupt_trigger(nmi->TriggerMode, 0)); if (nmi->Polarity != POLARITY_CONFORMS) lapic_set_lvt_polarity(apic_id, pin, - interrupt_polarity(nmi->Polarity)); + interrupt_polarity(nmi->Polarity, 0)); } /* ==== //depot/projects/power/sys/amd64/amd64/apic_vector.S#4 (text+ko) ==== @@ -28,7 +28,7 @@ * SUCH DAMAGE. * * from: vector.s, 386BSD 0.1 unknown origin - * $FreeBSD: src/sys/amd64/amd64/apic_vector.S,v 1.97 2004/04/05 21:25:51 imp Exp $ + * $FreeBSD: src/sys/amd64/amd64/apic_vector.S,v 1.98 2004/05/16 22:11:49 peter Exp $ */ /* @@ -321,19 +321,4 @@ movl $0, LA_EOI(%rax) /* End Of Interrupt to APIC */ POP_FRAME /* Why not doreti? */ iretq - -#ifdef LAZY_SWITCH -/* - * Clean up when we lose out on the lazy context switch optimization. - * ie: when we are about to release a PTD but a cpu is still borrowing it. - */ - SUPERALIGN_TEXT -IDTVEC(lazypmap) - PUSH_FRAME - call pmap_lazyfix_action - movq lapic, %rax - movl $0, LA_EOI(%rax) /* End Of Interrupt to APIC */ - POP_FRAME /* Why not doreti? */ - iretq -#endif #endif /* SMP */ ==== //depot/projects/power/sys/amd64/amd64/cpu_switch.S#5 (text+ko) ==== @@ -30,7 +30,7 @@ * 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.148 2004/04/05 23:55:13 imp Exp $ + * $FreeBSD: src/sys/amd64/amd64/cpu_switch.S,v 1.150 2004/05/16 22:43:57 peter Exp $ */ #include <machine/asmacros.h> @@ -103,6 +103,17 @@ pushfq /* PSL */ popq PCB_RFLAGS(%r8) + 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) + movl %gs,PCB_GS(%r8) + jmp 2f +1: + /* Save userland %fs */ movl $MSR_FSBASE,%ecx rdmsr @@ -114,13 +125,8 @@ rdmsr movl %eax,PCB_GSBASE(%r8) movl %edx,PCB_GSBASE+4(%r8) +2: - /* Save segment selector numbers */ - movl %ds,PCB_DS(%r8) - movl %es,PCB_ES(%r8) - movl %fs,PCB_FS(%r8) - movl %gs,PCB_GS(%r8) - /* Test if debug registers should be saved. */ testl $PCB_DBREGS,PCB_FLAGS(%r8) jz 1f /* no, skip over */ @@ -158,10 +164,6 @@ /* switch address space */ movq PCB_CR3(%r8),%rdx -#ifdef LAZY_SWITCH - cmpq %rdx,KPML4phys /* Kernel address space? */ - je sw1 -#endif movq %cr3,%rax cmpq %rdx,%rax /* Same address space? */ je sw1 @@ -185,6 +187,9 @@ */ 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 @@ -195,6 +200,8 @@ rdmsr movl PCB_GS(%r8),%gs wrmsr + jmp 2f +1: /* Restore userland %fs */ movl $MSR_FSBASE,%ecx @@ -207,6 +214,7 @@ 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 @@ -252,7 +260,6 @@ orq %rcx,%rax movq %rax,%dr7 1: - ret /* ==== //depot/projects/power/sys/amd64/amd64/elf_machdep.c#4 (text+ko) ==== @@ -24,7 +24,7 @@ */ #include <sys/cdefs.h> -__FBSDID("$FreeBSD: src/sys/amd64/amd64/elf_machdep.c,v 1.19 2003/12/23 02:42:37 peter Exp $"); +__FBSDID("$FreeBSD: src/sys/amd64/amd64/elf_machdep.c,v 1.21 2004/05/17 21:16:49 peter Exp $"); #include <sys/param.h> #include <sys/kernel.h> @@ -104,10 +104,11 @@ /* Process one elf relocation with addend. */ static int -elf_reloc_internal(linker_file_t lf, const void *data, int type, int local) +elf_reloc_internal(linker_file_t lf, Elf_Addr relocbase, const void *data, + int type, int local, elf_lookup_fn lookup) { - Elf_Addr relocbase = (Elf_Addr) lf->address; - Elf_Addr *where; + Elf64_Addr *where, val; + Elf32_Addr *where32, val32; Elf_Addr addr; Elf_Addr addend; Elf_Word rtype, symidx; @@ -118,9 +119,18 @@ case ELF_RELOC_REL: rel = (const Elf_Rel *)data; where = (Elf_Addr *) (relocbase + rel->r_offset); - addend = *where; rtype = ELF_R_TYPE(rel->r_info); symidx = ELF_R_SYM(rel->r_info); + /* Addend is 32 bit on 32 bit relocs */ + switch (rtype) { + case R_X86_64_PC32: + case R_X86_64_32S: + addend = *(Elf32_Addr *)where; + break; + default: + addend = *where; + break; + } break; case ELF_RELOC_RELA: rela = (const Elf_Rela *)data; @@ -133,37 +143,38 @@ panic("unknown reloc type %d\n", type); } - if (local) { - if (rtype == R_X86_64_RELATIVE) { /* A + B */ - addr = relocbase + addend; - if (*where != addr) - *where = addr; - } - return (0); - } - switch (rtype) { case R_X86_64_NONE: /* none */ break; case R_X86_64_64: /* S + A */ - addr = elf_lookup(lf, symidx, 1); + addr = lookup(lf, symidx, 1); + val = addr + addend; if (addr == 0) return -1; - addr += addend; - if (*where != addr) - *where = addr; + if (*where != val) + *where = val; break; case R_X86_64_PC32: /* S + A - P */ - addr = elf_lookup(lf, symidx, 1); + addr = lookup(lf, symidx, 1); + where32 = (Elf32_Addr *)where; + val32 = (Elf32_Addr)(addr + addend - (Elf_Addr)where); + if (addr == 0) + return -1; + if (*where32 != val32) + *where32 = val32; + break; + + case R_X86_64_32S: /* S + A sign extend */ + addr = lookup(lf, symidx, 1); + val32 = (Elf32_Addr)(addr + addend); + where32 = (Elf32_Addr *)where; if (addr == 0) return -1; - addr += addend - (Elf_Addr)where; - /* XXX needs to be 32 bit *where, not 64 bit */ - if (*where != addr) - *where = addr; + if (*where32 != val32) + *where32 = val32; break; case R_X86_64_COPY: /* none */ @@ -176,7 +187,7 @@ break; case R_X86_64_GLOB_DAT: /* S */ - addr = elf_lookup(lf, symidx, 1); + addr = lookup(lf, symidx, 1); if (addr == 0) return -1; if (*where != addr) @@ -184,6 +195,10 @@ break; case R_X86_64_RELATIVE: /* B + A */ + addr = relocbase + addend; + val = addr; + if (*where != val) + *where = val; break; default: @@ -195,17 +210,19 @@ } int -elf_reloc(linker_file_t lf, const void *data, int type) +elf_reloc(linker_file_t lf, Elf_Addr relocbase, const void *data, int type, + elf_lookup_fn lookup) { - return (elf_reloc_internal(lf, data, type, 0)); + return (elf_reloc_internal(lf, relocbase, data, type, 0, lookup)); } int -elf_reloc_local(linker_file_t lf, const void *data, int type) +elf_reloc_local(linker_file_t lf, Elf_Addr relocbase, const void *data, + int type, elf_lookup_fn lookup) { - return (elf_reloc_internal(lf, data, type, 1)); + return (elf_reloc_internal(lf, relocbase, data, type, 1, lookup)); } int ==== //depot/projects/power/sys/amd64/amd64/genassym.c#7 (text+ko) ==== @@ -33,7 +33,7 @@ */ #include <sys/cdefs.h> -__FBSDID("$FreeBSD: src/sys/amd64/amd64/genassym.c,v 1.153 2004/04/05 21:25:51 imp Exp $"); +__FBSDID("$FreeBSD: src/sys/amd64/amd64/genassym.c,v 1.154 2004/05/16 22:43:57 peter Exp $"); #include "opt_compat.h" #include "opt_kstack_pages.h" @@ -138,6 +138,7 @@ ASSYM(PCB_DR6, offsetof(struct pcb, pcb_dr6)); ASSYM(PCB_DR7, offsetof(struct pcb, pcb_dr7)); ASSYM(PCB_DBREGS, PCB_DBREGS); +ASSYM(PCB_32BIT, PCB_32BIT); ASSYM(PCB_FLAGS, offsetof(struct pcb, pcb_flags)); ASSYM(PCB_FULLCTX, PCB_FULLCTX); ==== //depot/projects/power/sys/amd64/amd64/intr_machdep.c#2 (text+ko) ==== @@ -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.4 2003/11/17 06:10:14 peter Exp $ + * $FreeBSD: src/sys/amd64/amd64/intr_machdep.c,v 1.5 2004/05/16 20:30:46 peter Exp $ */ /* @@ -138,6 +138,17 @@ return (error); } +int +intr_config_intr(int vector, enum intr_trigger trig, enum intr_polarity pol) +{ + struct intsrc *isrc; + + isrc = intr_lookup_source(vector); + if (isrc == NULL) + return (EINVAL); + return (isrc->is_pic->pic_config_intr(isrc, trig, pol)); +} + void intr_execute_handlers(struct intsrc *isrc, struct intrframe *iframe) { ==== //depot/projects/power/sys/amd64/amd64/io_apic.c#2 (text+ko) ==== @@ -28,7 +28,7 @@ */ #include <sys/cdefs.h> -__FBSDID("$FreeBSD: src/sys/amd64/amd64/io_apic.c,v 1.7 2003/11/17 08:58:12 peter Exp $"); +__FBSDID("$FreeBSD: src/sys/amd64/amd64/io_apic.c,v 1.8 2004/05/16 20:30:46 peter Exp $"); #include "opt_atpic.h" #include "opt_isa.h" @@ -51,10 +51,6 @@ #include <machine/apicvar.h> #include <machine/segments.h> -#if defined(DEV_ISA) && defined(DEV_ATPIC) && !defined(NO_MIXED_MODE) -#define MIXED_MODE -#endif - #define IOAPIC_ISA_INTS 16 #define IOAPIC_MEM_REGION 32 #define IOAPIC_REDTBL_LO(i) (IOAPIC_REDTBL + (i) * 2) @@ -117,9 +113,6 @@ struct ioapic_intsrc io_pins[0]; }; -static STAILQ_HEAD(,ioapic) ioapic_list = STAILQ_HEAD_INITIALIZER(ioapic_list); -static u_int next_id, program_logical_dest; - static u_int ioapic_read(volatile ioapic_t *apic, int reg); static void ioapic_write(volatile ioapic_t *apic, int reg, u_int val); static void ioapic_enable_source(struct intsrc *isrc); @@ -128,19 +121,28 @@ static void ioapic_enable_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_program_destination(struct ioapic_intsrc *intpin); -#ifdef MIXED_MODE static void ioapic_setup_mixed_mode(struct ioapic_intsrc *intpin); -#endif +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_suspend, ioapic_resume, + ioapic_config_intr }; -static int next_ioapic_base, logical_clusters, current_cluster; +static int current_cluster, logical_clusters, next_ioapic_base; +static u_int mixed_mode_enabled, next_id, program_logical_dest; +#if defined(NO_MIXED_MODE) || !defined(DEV_ATPIC) +static int mixed_mode_active = 0; +#else +static int mixed_mode_active = 1; +#endif +TUNABLE_INT("hw.apic.mixed_mode", &mixed_mode_active); static u_int ioapic_read(volatile ioapic_t *apic, int reg) @@ -291,6 +293,41 @@ return (lapic_intr_pending(intpin->io_vector)); } +static int +ioapic_config_intr(struct intsrc *isrc, enum intr_trigger trig, + enum intr_polarity pol) +{ + struct ioapic_intsrc *intpin = (struct ioapic_intsrc *)isrc; + struct ioapic *io = (struct ioapic *)isrc->is_pic; + + KASSERT(!(trig == INTR_TRIGGER_CONFORM || pol == INTR_POLARITY_CONFORM), + ("%s: Conforming trigger or polarity\n", __func__)); + + /* + * For now we ignore any requests but do output any changes that + * would be made to the console it bootverbose is enabled. The only + * known causes of these messages so far is a bug in acpi(4) that + * causes the ISA IRQs used for PCI interrupts in PIC mode to be + * set to level/low when they aren't being used. There are possibly + * legitimate requests, so at some point when the acpi(4) driver is + * fixed this code can be changed to actually change the intpin as + * requested. + */ + if (!bootverbose) + return (0); + if (intpin->io_edgetrigger != (trig == INTR_TRIGGER_EDGE)) + printf( + "ioapic%u: Request to change trigger for pin %u to %s ignored\n", + io->io_id, intpin->io_intpin, trig == INTR_TRIGGER_EDGE ? + "edge" : "level"); + if (intpin->io_activehi != (pol == INTR_POLARITY_HIGH)) + printf( + "ioapic%u: Request to change polarity for pin %u to %s ignored\n", + io->io_id, intpin->io_intpin, pol == INTR_POLARITY_HIGH ? + "high" : "low"); + return (0); +} + static void ioapic_suspend(struct intsrc *isrc) { @@ -306,6 +343,17 @@ } /* + * APIC enumerators call this function to indicate that the 8259A AT PICs + * are available and that mixed mode can be used. + */ +void +ioapic_enable_mixed_mode(void) +{ + + mixed_mode_enabled = 1; +} + +/* * Allocate and return a logical cluster ID. Note that the first time * this is called, it returns cluster 0. ioapic_enable_intr() treats * the two cases of logical_clusters == 0 and logical_clusters == 1 the @@ -380,14 +428,17 @@ >>> TRUNCATED FOR MAIL (1000 lines) <<<
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200405181831.i4IIVL8G084429>