It's me again.
Further down in the 82801{er | dbm} LPC initialization code, there is a block that configures NMI handling:
static void lpc_init(struct device *dev) { ...
/* Set up NMI on errors */ byte = pci_read_config8(dev, 0x61); byte |= (1 << 3); /* IOCHK# NMI Enable */ byte |= (1 << 6); /* PCI SERR# Enable */ pci_write_config8(dev, 0x61, byte); byte = pci_read_config8(dev, 0x70); nmi_option = NMI_OFF; get_option(&nmi_option, "nmi"); if (nmi_option) { byte |= (1 << 7); /* set NMI */ pci_write_config8(dev, 0x70, byte); }
... }
From the ICH-5 ('ER) documentation, it looks to me like this is meant to
be accessing NMI_SC and NMI_EN, the NMI Status and Control and NMI Enable registers, which are at 0x61 and 0x70 in processor I/O space, not PCI configuration space. So inb()/outb() should be used instead of pci_read_config8()/pci_write_config8().
If these are the correct registers, SERR# enable is controlled by bit 2, not bit 6.
Also it looks like the code does the opposite of what was intended, enabling NMIs when it should be disabling them, and vice versa. This is because Intel defines the NMI bits used above with reverse polarity...set to 1 to DISable, 0 to ENable.
So the code should read instead as:
#include <arch/io.h>
static void lpc_init(struct device *dev) { ...
/* Set up NMI on errors */ byte = inb(0x61); byte &= ~(1 << 3); /* IOCHK# NMI Enable */ byte &= ~(1 << 2); /* PCI SERR# Enable */ outb(0x61, byte); byte = inb(0x70); nmi_option = NMI_OFF; get_option(&nmi_option, "nmi"); if (nmi_option) { byte &= ~(1 << 7); /* set NMI */ outb(0x70, byte); }
... }
It this looks right, I'm willing to attempt folding this change into the source (never used arch before...), but I have no way to test that it does anything other than compile.
Regards, Steve Magnani Digital Design Corporation www.digidescorp.com