From owner-svn-src-stable@FreeBSD.ORG Wed Apr 14 15:01:49 2010 Return-Path: Delivered-To: svn-src-stable@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id AA483106564A; Wed, 14 Apr 2010 15:01:49 +0000 (UTC) (envelope-from jhb@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 974EB8FC08; Wed, 14 Apr 2010 15:01:49 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id o3EF1nus005086; Wed, 14 Apr 2010 15:01:49 GMT (envelope-from jhb@svn.freebsd.org) Received: (from jhb@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id o3EF1nnd005076; Wed, 14 Apr 2010 15:01:49 GMT (envelope-from jhb@svn.freebsd.org) Message-Id: <201004141501.o3EF1nnd005076@svn.freebsd.org> From: John Baldwin Date: Wed, 14 Apr 2010 15:01:49 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-7@freebsd.org X-SVN-Group: stable-7 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r206599 - in stable/7/sys: amd64/amd64 amd64/include i386/i386 i386/include X-BeenThere: svn-src-stable@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: SVN commit messages for all the -stable branches of the src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 14 Apr 2010 15:01:49 -0000 Author: jhb Date: Wed Apr 14 15:01:49 2010 New Revision: 206599 URL: http://svn.freebsd.org/changeset/base/206599 Log: MFC 185933,205851: - Add constants for fields in the local APIC error status register. - Add a handler for the local APIC error interrupt. For now it just prints out the current value of the local APIC error register when the interrupt fires. Modified: stable/7/sys/amd64/amd64/apic_vector.S stable/7/sys/amd64/amd64/local_apic.c stable/7/sys/amd64/include/apicreg.h stable/7/sys/amd64/include/apicvar.h stable/7/sys/i386/i386/apic_vector.s stable/7/sys/i386/i386/local_apic.c stable/7/sys/i386/include/apicreg.h stable/7/sys/i386/include/apicvar.h Directory Properties: stable/7/sys/ (props changed) stable/7/sys/cddl/contrib/opensolaris/ (props changed) stable/7/sys/contrib/dev/acpica/ (props changed) stable/7/sys/contrib/pf/ (props changed) Modified: stable/7/sys/amd64/amd64/apic_vector.S ============================================================================== --- stable/7/sys/amd64/amd64/apic_vector.S Wed Apr 14 15:00:46 2010 (r206598) +++ stable/7/sys/amd64/amd64/apic_vector.S Wed Apr 14 15:01:49 2010 (r206599) @@ -104,6 +104,18 @@ IDTVEC(timerint) MEXITCOUNT jmp doreti +/* + * Local APIC error interrupt handler. + */ + .text + SUPERALIGN_TEXT +IDTVEC(errorint) + PUSH_FRAME + FAKE_MCOUNT(TF_RIP(%rsp)) + call lapic_handle_error + MEXITCOUNT + jmp doreti + #ifdef SMP /* * Global address space TLB shootdown. Modified: stable/7/sys/amd64/amd64/local_apic.c ============================================================================== --- stable/7/sys/amd64/amd64/local_apic.c Wed Apr 14 15:00:46 2010 (r206598) +++ stable/7/sys/amd64/amd64/local_apic.c Wed Apr 14 15:01:49 2010 (r206599) @@ -111,14 +111,12 @@ struct lapic { u_long la_prof_ticks; } static lapics[MAX_APIC_ID + 1]; -/* XXX: should thermal be an NMI? */ - /* Global defaults for local APIC LVT entries. */ static struct lvt lvts[LVT_MAX + 1] = { { 1, 1, 1, 1, APIC_LVT_DM_EXTINT, 0 }, /* LINT0: masked ExtINT */ { 1, 1, 0, 1, APIC_LVT_DM_NMI, 0 }, /* LINT1: NMI */ { 1, 1, 1, 1, APIC_LVT_DM_FIXED, APIC_TIMER_INT }, /* Timer */ - { 1, 1, 1, 1, APIC_LVT_DM_FIXED, APIC_ERROR_INT }, /* Error */ + { 1, 1, 0, 1, APIC_LVT_DM_FIXED, APIC_ERROR_INT }, /* Error */ { 1, 1, 1, 1, APIC_LVT_DM_NMI, 0 }, /* PMC */ { 1, 1, 1, 1, APIC_LVT_DM_FIXED, APIC_THERMAL_INT }, /* Thermal */ }; @@ -224,7 +222,10 @@ lapic_init(vm_paddr_t addr) setidt(APIC_TIMER_INT, IDTVEC(timerint), SDT_SYSIGT, SEL_KPL, 0); ioint_irqs[APIC_TIMER_INT - APIC_IO_INTS] = IRQ_TIMER; - /* XXX: error/thermal interrupts */ + /* Local APIC error interrupt. */ + setidt(APIC_ERROR_INT, IDTVEC(errorint), SDT_SYSIGT, SEL_KPL, 0); + + /* XXX: Thermal interrupt */ } /* @@ -272,7 +273,7 @@ lapic_dump(const char* str) lapic->id, lapic->version, lapic->ldr, lapic->dfr); printf(" lint0: 0x%08x lint1: 0x%08x TPR: 0x%08x SVR: 0x%08x\n", lapic->lvt_lint0, lapic->lvt_lint1, lapic->tpr, lapic->svr); - printf(" timer: 0x%08x therm: 0x%08x err: 0x%08x pcm: 0x%08x\n", + printf(" timer: 0x%08x therm: 0x%08x err: 0x%08x pmc: 0x%08x\n", lapic->lvt_timer, lapic->lvt_thermal, lapic->lvt_error, lapic->lvt_pcint); } @@ -299,6 +300,7 @@ lapic_setup(int boot) /* Program LINT[01] LVT entries. */ lapic->lvt_lint0 = lvt_mode(la, LVT_LINT0, lapic->lvt_lint0); lapic->lvt_lint1 = lvt_mode(la, LVT_LINT1, lapic->lvt_lint1); + /* Program the PMC LVT entry if present. */ if (maxlvt >= LVT_PMC) lapic->lvt_pcint = lvt_mode(la, LVT_PMC, lapic->lvt_pcint); @@ -319,7 +321,11 @@ lapic_setup(int boot) lapic_timer_enable_intr(); } - /* XXX: Error and thermal LVTs */ + /* Program error LVT and clear any existing errors. */ + lapic->lvt_error = lvt_mode(la, LVT_ERROR, lapic->lvt_error); + lapic->esr = 0; + + /* XXX: Thermal LVT */ if (cpu_vendor_id == CPU_VENDOR_AMD) { /* @@ -846,6 +852,24 @@ lapic_timer_enable_intr(void) lapic->lvt_timer = value; } +void +lapic_handle_error(void) +{ + u_int32_t esr; + + /* + * Read the contents of the error status register. Write to + * the register first before reading from it to force the APIC + * to update its value to indicate any errors that have + * occurred since the previous write to the register. + */ + lapic->esr = 0; + esr = lapic->esr; + + printf("CPU%d: local APIC error 0x%x\n", PCPU_GET(cpuid), esr); + lapic_eoi(); +} + /* Request a free IDT vector to be used by the specified IRQ. */ u_int apic_alloc_vector(u_int irq) Modified: stable/7/sys/amd64/include/apicreg.h ============================================================================== --- stable/7/sys/amd64/include/apicreg.h Wed Apr 14 15:00:46 2010 (r206598) +++ stable/7/sys/amd64/include/apicreg.h Wed Apr 14 15:01:49 2010 (r206599) @@ -260,6 +260,14 @@ typedef struct IOAPIC ioapic_t; # define APIC_TPR_INT 0x000000f0 # define APIC_TPR_SUB 0x0000000f +/* fields in ESR */ +#define APIC_ESR_SEND_CS_ERROR 0x00000001 +#define APIC_ESR_RECEIVE_CS_ERROR 0x00000002 +#define APIC_ESR_SEND_ACCEPT 0x00000004 +#define APIC_ESR_RECEIVE_ACCEPT 0x00000008 +#define APIC_ESR_SEND_ILLEGAL_VECTOR 0x00000020 +#define APIC_ESR_RECEIVE_ILLEGAL_VECTOR 0x00000040 +#define APIC_ESR_ILLEGAL_REGISTER 0x00000080 /* fields in ICR_LOW */ #define APIC_VECTOR_MASK 0x000000ff Modified: stable/7/sys/amd64/include/apicvar.h ============================================================================== --- stable/7/sys/amd64/include/apicvar.h Wed Apr 14 15:00:46 2010 (r206598) +++ stable/7/sys/amd64/include/apicvar.h Wed Apr 14 15:01:49 2010 (r206599) @@ -173,7 +173,8 @@ struct apic_enumerator { inthand_t IDTVEC(apic_isr1), IDTVEC(apic_isr2), IDTVEC(apic_isr3), IDTVEC(apic_isr4), IDTVEC(apic_isr5), IDTVEC(apic_isr6), - IDTVEC(apic_isr7), IDTVEC(spuriousint), IDTVEC(timerint); + IDTVEC(apic_isr7), IDTVEC(errorint), IDTVEC(spuriousint), + IDTVEC(timerint); extern vm_paddr_t lapic_paddr; @@ -208,6 +209,7 @@ 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_error(void); void lapic_handle_intr(int vector, struct trapframe *frame); void lapic_handle_timer(struct trapframe *frame); void lapic_reenable_pmc(void); Modified: stable/7/sys/i386/i386/apic_vector.s ============================================================================== --- stable/7/sys/i386/i386/apic_vector.s Wed Apr 14 15:00:46 2010 (r206598) +++ stable/7/sys/i386/i386/apic_vector.s Wed Apr 14 15:01:49 2010 (r206599) @@ -110,6 +110,19 @@ IDTVEC(timerint) MEXITCOUNT jmp doreti +/* + * Local APIC error interrupt handler. + */ + .text + SUPERALIGN_TEXT +IDTVEC(errorint) + PUSH_FRAME + SET_KERNEL_SREGS + FAKE_MCOUNT(TF_EIP(%esp)) + call lapic_handle_error + MEXITCOUNT + jmp doreti + #ifdef SMP /* * Global address space TLB shootdown. Modified: stable/7/sys/i386/i386/local_apic.c ============================================================================== --- stable/7/sys/i386/i386/local_apic.c Wed Apr 14 15:00:46 2010 (r206598) +++ stable/7/sys/i386/i386/local_apic.c Wed Apr 14 15:01:49 2010 (r206599) @@ -111,14 +111,12 @@ struct lapic { u_long la_prof_ticks; } static lapics[MAX_APIC_ID + 1]; -/* XXX: should thermal be an NMI? */ - /* Global defaults for local APIC LVT entries. */ static struct lvt lvts[LVT_MAX + 1] = { { 1, 1, 1, 1, APIC_LVT_DM_EXTINT, 0 }, /* LINT0: masked ExtINT */ { 1, 1, 0, 1, APIC_LVT_DM_NMI, 0 }, /* LINT1: NMI */ { 1, 1, 1, 1, APIC_LVT_DM_FIXED, APIC_TIMER_INT }, /* Timer */ - { 1, 1, 1, 1, APIC_LVT_DM_FIXED, APIC_ERROR_INT }, /* Error */ + { 1, 1, 0, 1, APIC_LVT_DM_FIXED, APIC_ERROR_INT }, /* Error */ { 1, 1, 1, 1, APIC_LVT_DM_NMI, 0 }, /* PMC */ { 1, 1, 1, 1, APIC_LVT_DM_FIXED, APIC_THERMAL_INT }, /* Thermal */ }; @@ -226,7 +224,11 @@ lapic_init(vm_paddr_t addr) GSEL(GCODE_SEL, SEL_KPL)); ioint_irqs[APIC_TIMER_INT - APIC_IO_INTS] = IRQ_TIMER; - /* XXX: error/thermal interrupts */ + /* Local APIC error interrupt. */ + setidt(APIC_ERROR_INT, IDTVEC(errorint), SDT_SYS386IGT, SEL_KPL, + GSEL(GCODE_SEL, SEL_KPL)); + + /* XXX: Thermal interrupt */ } /* @@ -274,7 +276,7 @@ lapic_dump(const char* str) lapic->id, lapic->version, lapic->ldr, lapic->dfr); printf(" lint0: 0x%08x lint1: 0x%08x TPR: 0x%08x SVR: 0x%08x\n", lapic->lvt_lint0, lapic->lvt_lint1, lapic->tpr, lapic->svr); - printf(" timer: 0x%08x therm: 0x%08x err: 0x%08x pcm: 0x%08x\n", + printf(" timer: 0x%08x therm: 0x%08x err: 0x%08x pmc: 0x%08x\n", lapic->lvt_timer, lapic->lvt_thermal, lapic->lvt_error, lapic->lvt_pcint); } @@ -301,6 +303,7 @@ lapic_setup(int boot) /* Program LINT[01] LVT entries. */ lapic->lvt_lint0 = lvt_mode(la, LVT_LINT0, lapic->lvt_lint0); lapic->lvt_lint1 = lvt_mode(la, LVT_LINT1, lapic->lvt_lint1); + /* Program the PMC LVT entry if present. */ if (maxlvt >= LVT_PMC) lapic->lvt_pcint = lvt_mode(la, LVT_PMC, lapic->lvt_pcint); @@ -321,7 +324,11 @@ lapic_setup(int boot) lapic_timer_enable_intr(); } - /* XXX: Error and thermal LVTs */ + /* Program error LVT and clear any existing errors. */ + lapic->lvt_error = lvt_mode(la, LVT_ERROR, lapic->lvt_error); + lapic->esr = 0; + + /* XXX: Thermal LVT */ if (cpu_vendor_id == CPU_VENDOR_AMD) { /* @@ -848,6 +855,24 @@ lapic_timer_enable_intr(void) lapic->lvt_timer = value; } +void +lapic_handle_error(void) +{ + u_int32_t esr; + + /* + * Read the contents of the error status register. Write to + * the register first before reading from it to force the APIC + * to update its value to indicate any errors that have + * occurred since the previous write to the register. + */ + lapic->esr = 0; + esr = lapic->esr; + + printf("CPU%d: local APIC error 0x%x\n", PCPU_GET(cpuid), esr); + lapic_eoi(); +} + /* Request a free IDT vector to be used by the specified IRQ. */ u_int apic_alloc_vector(u_int irq) Modified: stable/7/sys/i386/include/apicreg.h ============================================================================== --- stable/7/sys/i386/include/apicreg.h Wed Apr 14 15:00:46 2010 (r206598) +++ stable/7/sys/i386/include/apicreg.h Wed Apr 14 15:01:49 2010 (r206599) @@ -260,6 +260,14 @@ typedef struct IOAPIC ioapic_t; # define APIC_TPR_INT 0x000000f0 # define APIC_TPR_SUB 0x0000000f +/* fields in ESR */ +#define APIC_ESR_SEND_CS_ERROR 0x00000001 +#define APIC_ESR_RECEIVE_CS_ERROR 0x00000002 +#define APIC_ESR_SEND_ACCEPT 0x00000004 +#define APIC_ESR_RECEIVE_ACCEPT 0x00000008 +#define APIC_ESR_SEND_ILLEGAL_VECTOR 0x00000020 +#define APIC_ESR_RECEIVE_ILLEGAL_VECTOR 0x00000040 +#define APIC_ESR_ILLEGAL_REGISTER 0x00000080 /* fields in ICR_LOW */ #define APIC_VECTOR_MASK 0x000000ff Modified: stable/7/sys/i386/include/apicvar.h ============================================================================== --- stable/7/sys/i386/include/apicvar.h Wed Apr 14 15:00:46 2010 (r206598) +++ stable/7/sys/i386/include/apicvar.h Wed Apr 14 15:01:49 2010 (r206599) @@ -172,7 +172,8 @@ struct apic_enumerator { inthand_t IDTVEC(apic_isr1), IDTVEC(apic_isr2), IDTVEC(apic_isr3), IDTVEC(apic_isr4), IDTVEC(apic_isr5), IDTVEC(apic_isr6), - IDTVEC(apic_isr7), IDTVEC(spuriousint), IDTVEC(timerint); + IDTVEC(apic_isr7), IDTVEC(errorint), IDTVEC(spuriousint), + IDTVEC(timerint); extern vm_paddr_t lapic_paddr; @@ -207,6 +208,7 @@ 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_error(void); void lapic_handle_intr(int vector, struct trapframe *frame); void lapic_handle_timer(struct trapframe *frame); void lapic_reenable_pmc(void);