Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753907AbYH2GSW (ORCPT ); Fri, 29 Aug 2008 02:18:22 -0400 Received: (majordomo@vger.kernel.org) by vger.kernel.org id S1752716AbYH2GPf (ORCPT ); Fri, 29 Aug 2008 02:15:35 -0400 Received: from 166-70-238-42.ip.xmission.com ([166.70.238.42]:59512 "EHLO ns1.wolfmountaingroup.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751498AbYH2GP1 (ORCPT ); Fri, 29 Aug 2008 02:15:27 -0400 Date: Thu, 28 Aug 2008 23:47:41 -0600 From: jmerkey@wolfmountaingroup.com Message-Id: <200808290547.m7T5lfkx016123@wolfmountaingroup.com> To: linux-kernel@vger.kernel.org Subject: [PATCH 2.6.27-rc5 8/29] mdb: add mdb-ia32-apic.c Intel x86 architecure functions Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 7949 Lines: 299 add mdb-ia32-apic.c Intel x86 architecure functions. add support to dump local APIC and IOAPIC registers. Instrument support for remote read of local apic registers. Add support for hardware NMI assertion for debugging a hard hung processor. Signed-off-by: Jeffrey Vernon Merkey (jmerkey@wolfmountaingroup.com) --- a/debug/mdb/mdb-ia32-apic.c 1969-12-31 17:00:00.000000000 -0700 +++ b/debug/mdb/mdb-ia32-apic.c 2008-08-28 14:20:04.000000000 -0600 @@ -0,0 +1,280 @@ + +/*************************************************************************** +* +* Copyright (c) 2008 Jeff V. Merkey All Rights Reserved. +* 1058 East 50 South +* Lindon, Utah 84042 +* jmerkey@wolfmountaingroup.com +* +* This program is free software; you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by the +* Free Software Foundation, version 2. +* +* This program is distributed in the hope that it will be useful, but +* WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* General Public License for more details. +* +* You are free to modify and re-distribute this program in accordance +* with the terms specified in the GNU Public License. The copyright +* contained in this code is required to be present in any derivative +* works and you are required to provide the source code for this +* program as part of any commercial or non-commercial distribution. +* You are required to respect the rights of the Copyright holders +* named within this code. +* +* jmerkey@wolfmountaingroup.com is the official maintainer of +* this code. You are encouraged to report any bugs, problems, fixes, +* suggestions, and comments about this software. +* +* AUTHOR : Jeff V. Merkey +* DESCRIP : Merkey's Linux Debugger +* +***************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef CONFIG_SMP +#include +#include +#endif + +#define __KERNEL_SYSCALLS__ +#include +#include + +#include "mdb.h" +#include "mdb-ia32.h" +#include "mdb-list.h" +#include "mdb-ia32-proc.h" +#include "mdb-base.h" +#include "mdb-proc.h" +#include "mdb-os.h" +#include "mdb-keyboard.h" + +#if defined(CONFIG_SMP) + +extern unsigned int io_apic_read(unsigned int apic, unsigned int reg); +extern int nr_ioapics; + +unsigned long apic_directed_nmi(unsigned long cpu) +{ + send_IPI_mask(cpumask_of_cpu(cpu), + APIC_DM_NMI | APIC_INT_LEVELTRIG | APIC_INT_ASSERT); + send_IPI_mask(cpumask_of_cpu(cpu), + APIC_DM_NMI | APIC_INT_LEVELTRIG); + return 0; +} + +void dump_ioapic(unsigned long num) +{ + unsigned long i, val; + + if (num < nr_ioapics) + { + DBGPrint("io_apic registers\n"); + for (i = 0; i <= 0x2F; i++) + { + if ((i & 3) == 0) + DBGPrint("%08X: ", i); + + val = io_apic_read(num, i * 4); + DBGPrint("%08X ", val); + + if ((i & 3) == 3) + DBGPrint("\n"); + } + } + return; +} + +void dump_local_apic(void) +{ + unsigned long i, val; + + DBGPrint("local apic registers\n"); + for (i = 0; i <= 0x3F; i++) + { + if ((i & 3) == 0) + DBGPrint("%08X: ", i); + + val = apic_read(i * 4); + DBGPrint("%08X ", val); + + if ((i & 3) == 3) + DBGPrint("\n"); + } + +} + +void dump_remote_apic(unsigned long cpu) +{ + register unsigned long i, timeout, apicid; + register unsigned long val; + + DBGPrint("remote apic registers processor(%d)\n", cpu); + for (i = 0; i <= 0x3F; i++) + { + if ((i & 3) == 0) + DBGPrint("%08X: ", i); + + apicid = cpu_present_to_apicid(cpu); + if (apicid == BAD_APICID) + { + DBGPrint("BADAPICX "); + continue; + } + + timeout = 0; + while (apic_read(APIC_ICR) & APIC_ICR_BUSY) + { + udelay(100); + if (timeout++ >= 1000) + break; + cpu_relax(); + touch_nmi_watchdog(); + } + + if (timeout >= 1000) + { + DBGPrint("???????? "); + continue; + } + + apic_write(APIC_ICR2, SET_APIC_DEST_FIELD(apicid)); + apic_write(APIC_ICR, i | APIC_DEST_LOGICAL | APIC_DM_REMRD); + + timeout = 0; + while ((apic_read(APIC_ICR) & APIC_ICR_RR_MASK) == APIC_ICR_RR_INPROG) + { + udelay(100); + if (timeout++ >= 1000) + break; + + cpu_relax(); + touch_nmi_watchdog(); + } + + if (timeout >= 1000) + { + DBGPrint("???????? "); + continue; + } + + if ((apic_read(APIC_ICR) & APIC_ICR_RR_MASK) == APIC_ICR_RR_VALID) + { + val = apic_read(APIC_RRR); + DBGPrint("%08X ", val); + } + else + { + DBGPrint("???????? "); + } + + if ((i & 3) == 3) + DBGPrint("\n"); + } + +} + +unsigned long displayAPICHelp(unsigned char *commandLine, DEBUGGER_PARSER *parser) +{ + DBGPrint("apic - display local apic regs\n"); + DBGPrint("apic [p#] - display remote apic regs\n"); + return 1; +} + +/* APIC */ + +unsigned long displayAPICInfo(unsigned char *cmd, + StackFrame *stackFrame, unsigned long Exception, + DEBUGGER_PARSER *parser) +{ + register unsigned long value; + unsigned long valid; + + cmd = &cmd[parser->debugCommandNameLength]; + while (*cmd && *cmd == ' ') + cmd++; + + value = EvaluateExpression(stackFrame, &cmd, &valid); + if (valid && ((value >= MAX_PROCESSORS) || !cpu_online(value))) + { + DBGPrint("processor not found\n"); + return 1; + } + if (valid && (value != get_processor_id())) + dump_remote_apic(value); + else + dump_local_apic(); + return 1; +} + +unsigned long displayIOAPICHelp(unsigned char *commandLine, DEBUGGER_PARSER *parser) +{ + DBGPrint("ioapic [#] - display specified ioapic [#] regs\n"); + return 1; +} + +/* IOAPIC */ + +unsigned long displayIOAPICInfo(unsigned char *cmd, + StackFrame *stackFrame, unsigned long Exception, + DEBUGGER_PARSER *parser) +{ + register unsigned long value; + unsigned long valid; + + cmd = &cmd[parser->debugCommandNameLength]; + while (*cmd && *cmd == ' ') + cmd++; + + value = EvaluateExpression(stackFrame, &cmd, &valid); + if (valid && !(value < nr_ioapics)) + { + DBGPrint("ioapic not found\n"); + return 1; + } + if (valid) + dump_ioapic(value); + else + dump_ioapic(0); + return 1; + +} + +#endif /* CONFIG_SMP */ -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/