I wanted to propose an NMI handling interface. I have attached the header file and patches to 'arch/mips/kernel/traps.c'. The user need only specify the offset address for the NMI vector code and then they can also specify their own desired NMI function. Comments?
-Steve
/* * linux/include/asm-mips/nmi.h * * NMI interface definitions * * Copyright (C) 2003 TimeSys Corp. * S. James Hill (James.Hill@timesys.com) * (sjhill@realitydiluted.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; either version 2 of the License, or (at your * option) any later version. * * THIS SOFTWARE IS PROVIDED ``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. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef _ASM_NMI_H #define _ASM_NMI_H /* * NMI vector address offset. */ extern unsigned long nmi_addr; /* * User-defined NMI function. */ extern void (*nmi_user_handler)(struct pt_regs *regs); #endif
--- traps.c.orig Tue Oct 7 15:08:43 2003 +++ traps.c Tue Oct 7 15:10:28 2003 @@ -64,6 +66,11 @@ void (*board_be_init)(void); int (*board_be_handler)(struct pt_regs *regs, int is_fixup); +#ifdef CONFIG_NMI +unsigned long nmi_addr = 0; +void (*nmi_user_handler)(struct pt_regs *regs); +#endif + int kstack_depth_to_print = 24; /* @@ -841,6 +1095,8 @@ */ void nmi_exception_handler(struct pt_regs *regs) { + if (nmi_user_handler) + nmi_user_handler(regs); printk("NMI taken!!!!\n"); die("NMI", regs); while(1) ; @@ -1009,6 +1265,14 @@ restore_fp_context = fpu_emulator_restore_context; } +#ifdef CONFIG_NMI + { + extern char except_vec_nmi; + + memcpy((void *)(KSEG0 + nmi_addr), &except_vec_nmi, 0x8); + } +#endif + flush_icache_range(KSEG0, KSEG0 + 0x400); atomic_inc(&init_mm.mm_count); /* XXX UP? */