http://wiki.osdev.org/IOAPIC
http://wiki.osdev.org/APIC
These two URLs provides detailed the explanation about IOAPIC, but the read/write code do not work on my CentOS machine. The IO APIC base is 0xfec00000 on my machine (index 0xfec00000; port 0xfec00010). It is a memory maped IO memory.
I use the code in both user-level program and a kernel module. The code raises an segmentation fault. After looking at the dmesg, I notice that it is because page table does not know how to translate the virtual address (i.e., 0xfec00000).
Then I use the ioremap() in the kernel module, it works.
#include <linux/module.h>
#include <linux/init.h>
#include <asm/io.h>
MODULE_LICENSE("Dual BSD/GPL");
static int hello_init(void)
{
// IO APIC base is 0xfec00000
// IO APIC index: 0xfec00000
// IO APIC data: 0xfec00010
// The redicection table of the keyboard is at index 0x12
// please see southbridge manual for redirection table
// the original value of the redirection table entry is 0x939
// We change it to 0xa39, which enables SMI triggering
//
// if you want to compile this kernel moudule,
// please also change the Makefile to hello6.o
//
// just run the script enable_kb_SMI.sh to enable the SMI
// triggering
//
unsigned int IRQ1_entry;
void * IOAPIC_BASE = ioremap(0xfec00000, 32);
iowrite8(0x12, IOAPIC_BASE);
IRQ1_entry = ioread32((unsigned char*)IOAPIC_BASE + 0x10);
printk("IRQ1 Entry Value is: %x\n", IRQ1_entry);
iowrite8(0x12, IOAPIC_BASE);
iowrite32(0xA39, (unsigned char*)IOAPIC_BASE + 0x10);
printk("Successfully enable keyboard SMI triggering\n");
return 0;
}
static void hello_exit(void)
{
printk("Goodbye, crule world\n");
}
module_init(hello_init);
module_exit(hello_exit);
No comments:
Post a Comment