Adding a device to gem5 is lightly documented in the ASPLOS tutorial and gem5 wiki. I would suggest starting with the tutorial, and read about the memory system as well.
Devices are located in gem5/src/dev/ subtree, with architecture-specific files located in subdirectories. The IsaFake device, which I found before the ASPLOS tutorial, was useful for starting. To create a simple device, I copied isa_fake.[cc|hh] to mydev.[cc|hh], and copied BadDevice.py to MyDevice.py. Then I copied the parameters for IsaFake from Device.py into the parameters of MyDevice.py, and added mydev.cc and MyDevice.py to the SConscript. After renaming (search-replace IsaFake/BadDevice with MyDevice, isa_fake with mydev, etc), I needed to add the device to the system. I'm working with x86, so I attached it in the x86/Pc.py file, with:
from MyDevice import MyDevice
...
my_device = MyDevice(pio_addr=x86IOAddress(0xe000), pio_size=8)
...
self.fake_floppy.pio = bus.master
self.my_device.pio = bus.master
self.pciconfig.pio = bus.default
...
After compiling and running gem5 the device is listed in the m5out/config.ini file.
Accessing the device requires a device driver. To learn about writing drivers, read a good book. For this driver, a simple kernel module will do.
#include <linux kernel.h> #include <linux module.h> #include <linux errno.h> #include <linux ioport.h> #include <asm io.h> #define BASE 0xe000 #define SIZE 0x08 int init_module(void) { int t1; if ( ! request_region(BASE, SIZE, "mydev") ) { printk( KERN_INFO "unable to get io port at 0x%8X\n", BASE ); return -ENODEV; } /* a little test */ t1 = inl(BASE); printk( KERN_INFO "read %d\n", t1 ); outl(0, BASE); t1 = inl(BASE); printk( KERN_INFO "read %d\n", t1 ); return 0; } void cleanup_module(void) { release_region(BASE, SIZE); }
Compile the module against the Linux kernel, boot gem5, get the module into the simulated system (e.g. with m5 readfile), and insert the module. With the default parameters from the IsaFake device, the write is ignored and the device returns -1 whenever it is read.
I did not get I/O memory working, but for now I/O ports are fine for me.