summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--SConscript5
-rw-r--r--arch/alpha/isa_traits.hh1
-rw-r--r--dev/ide_ctrl.cc221
-rw-r--r--dev/ide_ctrl.hh36
-rw-r--r--dev/ide_disk.cc134
-rw-r--r--dev/ide_disk.hh12
-rw-r--r--dev/ns_gige.cc2
-rw-r--r--dev/ns_gige.hh2
-rw-r--r--dev/pciconfigall.cc10
-rw-r--r--dev/pcidev.cc79
-rw-r--r--dev/pcidev.hh2
-rw-r--r--dev/tsunami_io.cc142
-rw-r--r--dev/tsunami_io.hh24
-rw-r--r--dev/tsunamireg.h12
-rw-r--r--dev/uart8250.cc7
-rw-r--r--kern/freebsd/freebsd_system.cc161
-rw-r--r--kern/freebsd/freebsd_system.hh49
-rw-r--r--kern/kernel_stats.cc5
-rw-r--r--kern/kernel_stats.hh4
-rw-r--r--kern/linux/aligned.hh3
-rw-r--r--kern/linux/linux_system.cc4
-rw-r--r--kern/linux/linux_system.hh4
-rw-r--r--kern/linux/linux_threadinfo.hh2
-rw-r--r--kern/linux/printk.cc4
-rw-r--r--kern/linux/sched.hh3
-rw-r--r--kern/linux/thread_info.hh1
-rw-r--r--kern/system_events.cc5
-rw-r--r--kern/system_events.hh2
-rw-r--r--python/m5/objects/Pci.py3
-rw-r--r--python/m5/objects/Tsunami.py1
30 files changed, 697 insertions, 243 deletions
diff --git a/SConscript b/SConscript
index ddca8b057..5752d8ff0 100644
--- a/SConscript
+++ b/SConscript
@@ -265,8 +265,9 @@ full_system_sources = Split('''
dev/ns_gige.cc
dev/pciconfigall.cc
dev/pcidev.cc
+ dev/pcifake.cc
dev/pktfifo.cc
- dev/platform.cc
+ dev/platform.cc
dev/sinic.cc
dev/simple_disk.cc
dev/tsunami.cc
@@ -280,6 +281,8 @@ full_system_sources = Split('''
kern/kernel_binning.cc
kern/kernel_stats.cc
kern/system_events.cc
+ kern/freebsd/freebsd_system.cc
+ kern/freebsd/freebsd_events.cc
kern/linux/linux_events.cc
kern/linux/linux_syscalls.cc
kern/linux/linux_system.cc
diff --git a/arch/alpha/isa_traits.hh b/arch/alpha/isa_traits.hh
index 9c7709a60..6c0c09b7a 100644
--- a/arch/alpha/isa_traits.hh
+++ b/arch/alpha/isa_traits.hh
@@ -287,6 +287,7 @@ const int ReturnAddressReg = TheISA::ReturnAddressReg;
const int ReturnValueReg = TheISA::ReturnValueReg;
const int ArgumentReg0 = TheISA::ArgumentReg0;
const int ArgumentReg1 = TheISA::ArgumentReg1;
+const int ArgumentReg2 = TheISA::ArgumentReg2;
const int BranchPredAddrShiftAmt = TheISA::BranchPredAddrShiftAmt;
const int MaxAddr = (Addr)-1;
diff --git a/dev/ide_ctrl.cc b/dev/ide_ctrl.cc
index 785f18ae8..a2b27d01a 100644
--- a/dev/ide_ctrl.cc
+++ b/dev/ide_ctrl.cc
@@ -76,10 +76,10 @@ IdeController::IdeController(Params *p)
// zero out all of the registers
memset(bmi_regs, 0, sizeof(bmi_regs));
- memset(pci_regs, 0, sizeof(pci_regs));
+ memset(pci_config_regs.data, 0, sizeof(pci_config_regs.data));
// setup initial values
- *(uint32_t *)&pci_regs[IDETIM] = 0x80008000; // enable both channels
+ pci_config_regs.idetim = htoa((uint32_t)0x80008000); // enable both channels
*(uint8_t *)&bmi_regs[BMIS0] = 0x60;
*(uint8_t *)&bmi_regs[BMIS1] = 0x60;
@@ -251,93 +251,77 @@ IdeController::cacheAccess(MemReqPtr &req)
void
IdeController::ReadConfig(int offset, int size, uint8_t *data)
{
+ union {
+ uint8_t byte;
+ uint16_t word;
+ uint32_t dword;
+ };
-#if TRACING_ON
- Addr origOffset = offset;
-#endif
+ int config_offset;
if (offset < PCI_DEVICE_SPECIFIC) {
PciDev::ReadConfig(offset, size, data);
- } else {
- if (offset >= PCI_IDE_TIMING && offset < (PCI_IDE_TIMING + 4)) {
- offset -= PCI_IDE_TIMING;
- offset += IDETIM;
-
- if ((offset + size) > (IDETIM + 4))
- panic("PCI read of IDETIM with invalid size\n");
- } else if (offset == PCI_SLAVE_TIMING) {
- offset -= PCI_SLAVE_TIMING;
- offset += SIDETIM;
-
- if ((offset + size) > (SIDETIM + 1))
- panic("PCI read of SIDETIM with invalid size\n");
- } else if (offset == PCI_UDMA33_CTRL) {
- offset -= PCI_UDMA33_CTRL;
- offset += UDMACTL;
-
- if ((offset + size) > (UDMACTL + 1))
- panic("PCI read of UDMACTL with invalid size\n");
- } else if (offset >= PCI_UDMA33_TIMING &&
- offset < (PCI_UDMA33_TIMING + 2)) {
- offset -= PCI_UDMA33_TIMING;
- offset += UDMATIM;
-
- if ((offset + size) > (UDMATIM + 2))
- panic("PCI read of UDMATIM with invalid size\n");
- } else {
- panic("PCI read of unimplemented register: %x\n", offset);
+ } else if (offset >= IDE_CTRL_CONFIG_START && (offset + size) <= IDE_CTRL_CONFIG_END) {
+
+ config_offset = offset - IDE_CTRL_CONFIG_START;
+ dword = 0;
+
+ switch (size) {
+ case sizeof(uint8_t):
+ memcpy(&byte, &pci_config_regs.data[config_offset], size);
+ *data = byte;
+ break;
+ case sizeof(uint16_t):
+ memcpy(&byte, &pci_config_regs.data[config_offset], size);
+ *(uint16_t*)data = htoa(word);
+ break;
+ case sizeof(uint32_t):
+ memcpy(&byte, &pci_config_regs.data[config_offset], size);
+ *(uint32_t*)data = htoa(dword);
+ break;
+ default:
+ panic("Invalid PCI configuration read size!\n");
}
- memcpy((void *)data, (void *)&pci_regs[offset], size);
- }
+ DPRINTF(IdeCtrl, "PCI read offset: %#x size: %#x data: %#x\n",
+ offset, size, htoa(dword));
- DPRINTF(IdeCtrl, "PCI read offset: %#x (%#x) size: %#x data: %#x\n",
- origOffset, offset, size,
- (*(uint32_t *)data) & (0xffffffff >> 8 * (4 - size)));
+ } else {
+ panic("Read of unimplemented PCI config. register: %x\n", offset);
+ }
}
void
IdeController::WriteConfig(int offset, int size, uint32_t data)
{
- DPRINTF(IdeCtrl, "PCI write offset: %#x size: %#x data: %#x\n",
- offset, size, data & (0xffffffff >> 8 * (4 - size)));
+ int config_offset;
+ uint32_t write_data;
- // do standard write stuff if in standard PCI space
if (offset < PCI_DEVICE_SPECIFIC) {
PciDev::WriteConfig(offset, size, data);
- } else {
- if (offset >= PCI_IDE_TIMING && offset < (PCI_IDE_TIMING + 4)) {
- offset -= PCI_IDE_TIMING;
- offset += IDETIM;
-
- if ((offset + size) > (IDETIM + 4))
- panic("PCI write to IDETIM with invalid size\n");
- } else if (offset == PCI_SLAVE_TIMING) {
- offset -= PCI_SLAVE_TIMING;
- offset += SIDETIM;
-
- if ((offset + size) > (SIDETIM + 1))
- panic("PCI write to SIDETIM with invalid size\n");
- } else if (offset == PCI_UDMA33_CTRL) {
- offset -= PCI_UDMA33_CTRL;
- offset += UDMACTL;
-
- if ((offset + size) > (UDMACTL + 1))
- panic("PCI write to UDMACTL with invalid size\n");
- } else if (offset >= PCI_UDMA33_TIMING &&
- offset < (PCI_UDMA33_TIMING + 2)) {
- offset -= PCI_UDMA33_TIMING;
- offset += UDMATIM;
-
- if ((offset + size) > (UDMATIM + 2))
- panic("PCI write to UDMATIM with invalid size\n");
- } else {
- panic("PCI write to unimplemented register: %x\n", offset);
- }
+ } else if (offset >= IDE_CTRL_CONFIG_START && (offset + size) <= IDE_CTRL_CONFIG_END) {
- memcpy((void *)&pci_regs[offset], (void *)&data, size);
+ config_offset = offset - IDE_CTRL_CONFIG_START;
+
+ write_data = htoa(data);
+
+ switch(size) {
+ case sizeof(uint8_t):
+ case sizeof(uint16_t):
+ case sizeof(uint32_t):
+ memcpy(&pci_config_regs.data[config_offset], &write_data, size);
+ break;
+
+ default:
+ panic("Invalid PCI configuration write size!\n");
+ }
+ } else {
+ panic("Write of unimplemented PCI config. register: %x\n", offset);
}
+ DPRINTF(IdeCtrl, "PCI write offset: %#x size: %#x data: %#x\n",
+ offset, size, data);
+
// Catch the writes to specific PCI registers that have side affects
// (like updating the PIO ranges)
switch (offset) {
@@ -414,36 +398,91 @@ IdeController::read(MemReqPtr &req, uint8_t *data)
{
Addr offset;
bool primary;
- bool byte;
- bool cmdBlk;
RegType_t type;
int disk;
+
+ /* union
+ * +-- --+-- --+-- --+-- --+
+ * | 0 | 1 | 2 | 3 |
+ * +-- --+-- --+-- --+-- --+
+ * | byte | .. | .. | .. |
+ * +-- --+-- --+-- --+-- --+
+ * | word0 | word1 |
+ * +-- --+-- --+
+ * | dword |
+ * +-- --+
+ */
+ union {
+ uint8_t byte;
+ uint16_t word[2];
+ uint32_t dword;
+ };
+
+ dword = 0;
+
parseAddr(req->paddr, offset, primary, type);
- byte = (req->size == sizeof(uint8_t)) ? true : false;
- cmdBlk = (type == COMMAND_BLOCK) ? true : false;
if (!io_enabled)
return No_Fault;
- // sanity check the size (allows byte, word, or dword access)
- if (req->size != sizeof(uint8_t) && req->size != sizeof(uint16_t) &&
- req->size != sizeof(uint32_t))
- panic("IDE controller read of invalid size: %#x\n", req->size);
-
- if (type != BMI_BLOCK) {
- assert(req->size != sizeof(uint32_t));
+ switch (type) {
+ case BMI_BLOCK:
+ switch (req->size) {
+ case sizeof(uint8_t):
+ memcpy(&byte, &bmi_regs[offset], sizeof(uint8_t));
+ *data = byte;
+ break;
+ case sizeof(uint16_t):
+ memcpy(&byte, &bmi_regs[offset], sizeof(uint16_t));
+ *(uint16_t*)data = htoa(word[0]);
+ break;
+ case sizeof(uint32_t):
+ memcpy(&byte, &bmi_regs[offset], sizeof(uint32_t));
+ *(uint32_t*)data = htoa(dword);
+ break;
+ default:
+ panic("IDE read of BMI reg invalid size: %#x\n", req->size);
+ }
+ break;
+ case COMMAND_BLOCK:
+ case CONTROL_BLOCK:
disk = getDisk(primary);
- if (disks[disk])
- disks[disk]->read(offset, byte, cmdBlk, data);
- } else {
- memcpy((void *)data, &bmi_regs[offset], req->size);
+
+ if (disks[disk] == NULL)
+ break;
+
+ switch (offset) {
+ case DATA_OFFSET:
+ switch (req->size) {
+ case sizeof(uint16_t):
+ disks[disk]->read(offset, type, (uint8_t*)&word[0]);
+ *(uint16_t*)data = htoa(word[0]);
+ break;
+
+ case sizeof(uint32_t):
+ disks[disk]->read(offset, type, (uint8_t*)&word[0]);
+ disks[disk]->read(offset, type, (uint8_t*)&word[1]);
+ *(uint32_t*)data = htoa(dword);
+ break;
+
+ default:
+ panic("IDE read of data reg invalid size: %#x\n", req->size);
+ }
+ break;
+ default:
+ if (req->size == sizeof(uint8_t)) {
+ disks[disk]->read(offset, type, &byte);
+ *data = byte;
+ } else
+ panic("IDE read of command reg of invalid size: %#x\n", req->size);
+ }
+ break;
}
DPRINTF(IdeCtrl, "read from offset: %#x size: %#x data: %#x\n",
- offset, req->size,
- (*(uint32_t *)data) & (0xffffffff >> 8 * (4 - req->size)));
+ offset, req->size, htoa(dword));
return No_Fault;
}
@@ -462,7 +501,7 @@ IdeController::write(MemReqPtr &req, const uint8_t *data)
byte = (req->size == sizeof(uint8_t)) ? true : false;
cmdBlk = (type == COMMAND_BLOCK) ? true : false;
- DPRINTF(IdeCtrl, "write from offset: %#x size: %#x data: %#x\n",
+ DPRINTF(IdeCtrl, "write to offset: %#x size: %#x data: %#x\n",
offset, req->size,
(*(uint32_t *)data) & (0xffffffff >> 8 * (4 - req->size)));
@@ -620,7 +659,7 @@ IdeController::serialize(std::ostream &os)
// Serialize registers
SERIALIZE_ARRAY(bmi_regs, 16);
SERIALIZE_ARRAY(dev, 2);
- SERIALIZE_ARRAY(pci_regs, 8);
+ SERIALIZE_ARRAY(pci_config_regs.data, 22);
// Serialize internal state
SERIALIZE_SCALAR(io_enabled);
@@ -649,7 +688,7 @@ IdeController::unserialize(Checkpoint *cp, const std::string &section)
// Unserialize registers
UNSERIALIZE_ARRAY(bmi_regs, 16);
UNSERIALIZE_ARRAY(dev, 2);
- UNSERIALIZE_ARRAY(pci_regs, 8);
+ UNSERIALIZE_ARRAY(pci_config_regs.data, 22);
// Unserialize internal state
UNSERIALIZE_SCALAR(io_enabled);
diff --git a/dev/ide_ctrl.hh b/dev/ide_ctrl.hh
index 4b54c3d57..2164f2f4a 100644
--- a/dev/ide_ctrl.hh
+++ b/dev/ide_ctrl.hh
@@ -64,15 +64,9 @@
#define IDE_COMMAND_OFFSET IDE_STATUS_OFFSET
// PCI device specific register byte offsets
-#define PCI_IDE_TIMING 0x40
-#define PCI_SLAVE_TIMING 0x44
-#define PCI_UDMA33_CTRL 0x48
-#define PCI_UDMA33_TIMING 0x4a
+#define IDE_CTRL_CONFIG_START 0x40
+#define IDE_CTRL_CONFIG_END ((IDE_CTRL_CONFIG_START) + sizeof(pci_config_regs))
-#define IDETIM (0)
-#define SIDETIM (4)
-#define UDMACTL (5)
-#define UDMATIM (6)
typedef enum RegType {
COMMAND_BLOCK = 0,
@@ -119,8 +113,30 @@ class IdeController : public PciDev
uint8_t bmi_regs[16];
/** Shadows of the device select bit */
uint8_t dev[2];
- /** Registers used in PCI configuration */
- uint8_t pci_regs[8];
+ /** Registers used in device specific PCI configuration */
+ union {
+ uint8_t data[22];
+
+ struct {
+ uint32_t idetim;
+ uint8_t sidetim;
+ uint8_t reserved_45;
+ uint8_t reserved_46;
+ uint8_t reserved_47;
+ uint8_t udmactl;
+ uint8_t reserved_49;
+ uint16_t udmatim;
+ uint8_t reserved_4c;
+ uint8_t reserved_4d;
+ uint8_t reserved_4e;
+ uint8_t reserved_4f;
+ uint8_t reserved_50;
+ uint8_t reserved_51;
+ uint8_t reserved_52;
+ uint8_t reserved_53;
+ uint16_t ideconfig;
+ };
+ } pci_config_regs;
// Internal management variables
bool io_enabled;
diff --git a/dev/ide_disk.cc b/dev/ide_disk.cc
index 23d04bb5e..74d2ae6de 100644
--- a/dev/ide_disk.cc
+++ b/dev/ide_disk.cc
@@ -116,6 +116,9 @@ IdeDisk::IdeDisk(const string &name, DiskImage *img, PhysicalMemory *phys,
driveID.atap_udmamode_supp = 0x10;
// Statically set hardware config word
driveID.atap_hwreset_res = 0x4001;
+
+ //arbitrary for now...
+ driveID.atap_ata_major = WDC_VER_ATA7;
}
IdeDisk::~IdeDisk()
@@ -158,6 +161,8 @@ IdeDisk::reset(int id)
// set the device ready bit
status = STATUS_DRDY_BIT;
+
+ cmdReg.error = 0x1;
}
////
@@ -207,41 +212,58 @@ IdeDisk::bytesInDmaPage(Addr curAddr, uint32_t bytesLeft)
////
void
-IdeDisk::read(const Addr &offset, bool byte, bool cmdBlk, uint8_t *data)
+IdeDisk::read(const Addr &offset, RegType_t type, uint8_t *data)
{
DevAction_t action = ACT_NONE;
- if (cmdBlk) {
- if (offset < 0 || offset > sizeof(CommandReg_t))
- panic("Invalid disk command register offset: %#x\n", offset);
-
- if (!byte && offset != DATA_OFFSET)
- panic("Invalid 16-bit read, only allowed on data reg\n");
-
- if (!byte)
- *(uint16_t *)data = *(uint16_t *)&cmdReg.data0;
- else
- *data = ((uint8_t *)&cmdReg)[offset];
-
- // determine if an action needs to be taken on the state machine
- if (offset == STATUS_OFFSET) {
+ switch (type) {
+ case COMMAND_BLOCK:
+ if (offset == STATUS_OFFSET)
action = ACT_STAT_READ;
- *data = status; // status is in a shadow, explicity copy
- } else if (offset == DATA_OFFSET) {
- if (byte)
- action = ACT_DATA_READ_BYTE;
- else
- action = ACT_DATA_READ_SHORT;
+ else if (offset == DATA_OFFSET)
+ action = ACT_DATA_READ_SHORT;
+
+ switch (offset) {
+ // Data transfers occur 16 bits at a time
+ case DATA_OFFSET:
+ // use memcpy to preserve IDE's little-endianess
+ memcpy(data, &cmdReg.data, sizeof(uint16_t));
+ break;
+ // All other transfers are 8-bit
+ case ERROR_OFFSET:
+ *data = cmdReg.error;
+ break;
+ case NSECTOR_OFFSET:
+ *data = cmdReg.sec_count;
+ break;
+ case SECTOR_OFFSET:
+ *data = cmdReg.sec_num;
+ break;
+ case LCYL_OFFSET:
+ *data = cmdReg.cyl_low;
+ break;
+ case HCYL_OFFSET:
+ *data = cmdReg.cyl_high;
+ break;
+ case DRIVE_OFFSET:
+ *data = cmdReg.drive;
+ break;
+ case STATUS_OFFSET:
+ *data = status;
+ break;
+ default:
+ panic("Invalid IDE command register offset: %#x\n", offset);
}
+ break;
+ case CONTROL_BLOCK:
+ if (offset == ALTSTAT_OFFSET)
+ *data = status;
+ else
+ panic("Invalid IDE control register offset: %#x\n", offset);
+ break;
- } else {
- if (offset != ALTSTAT_OFFSET)
- panic("Invalid disk control register offset: %#x\n", offset);
-
- if (!byte)
- panic("Invalid 16-bit read from control block\n");
-
- *data = status;
+ default:
+ panic("Unknown register block!\n");
}
if (action != ACT_NONE)
@@ -254,16 +276,42 @@ IdeDisk::write(const Addr &offset, bool byte, bool cmdBlk, const uint8_t *data)
DevAction_t action = ACT_NONE;
if (cmdBlk) {
- if (offset < 0 || offset > sizeof(CommandReg_t))
- panic("Invalid disk command register offset: %#x\n", offset);
if (!byte && offset != DATA_OFFSET)
panic("Invalid 16-bit write, only allowed on data reg\n");
if (!byte)
- *((uint16_t *)&cmdReg.data0) = *(uint16_t *)data;
- else
- ((uint8_t *)&cmdReg)[offset] = *data;
+ *((uint16_t *)&cmdReg.data) = *(uint16_t *)data;
+ else {
+ switch (offset) {
+ case DATA_OFFSET:
+ memcpy(&cmdReg.data, data, sizeof(uint16_t));
+ break;
+ case FEATURES_OFFSET:
+ //cmdReg.features = *data;
+ break;
+ case NSECTOR_OFFSET:
+ cmdReg.sec_count = *data;
+ break;
+ case SECTOR_OFFSET:
+ cmdReg.sec_num = *data;
+ break;
+ case LCYL_OFFSET:
+ cmdReg.cyl_low = *data;
+ break;
+ case HCYL_OFFSET:
+ cmdReg.cyl_high = *data;
+ break;
+ case DRIVE_OFFSET:
+ cmdReg.drive = *data;
+ break;
+ case COMMAND_OFFSET:
+ cmdReg.command = *data;
+ break;
+ default:
+ panic("Invalid IDE command register offset: %#x\n", offset);
+ }
+ }
// determine if an action needs to be taken on the state machine
if (offset == COMMAND_OFFSET) {
@@ -273,7 +321,7 @@ IdeDisk::write(const Addr &offset, bool byte, bool cmdBlk, const uint8_t *data)
action = ACT_DATA_WRITE_BYTE;
else
action = ACT_DATA_WRITE_SHORT;
- } else if (offset == SELECT_OFFSET) {
+ } else if (offset == DRIVE_OFFSET) {
action = ACT_SELECT_WRITE;
}
@@ -744,8 +792,10 @@ IdeDisk::intrPost()
intrPending = true;
// talk to controller to set interrupt
- if (ctrl)
+ if (ctrl) {
+ ctrl->bmi_regs[BMIS0] |= IDEINTS;
ctrl->intrPost();
+ }
}
void
@@ -864,7 +914,7 @@ IdeDisk::updateState(DevAction_t action)
}
// put the first two bytes into the data register
- memcpy((void *)&cmdReg.data0, (void *)dataBuffer,
+ memcpy((void *)&cmdReg.data, (void *)dataBuffer,
sizeof(uint16_t));
if (!isIENSet()) {
@@ -893,7 +943,7 @@ IdeDisk::updateState(DevAction_t action)
// copy next short into data registers
if (drqBytesLeft)
- memcpy((void *)&cmdReg.data0,
+ memcpy((void *)&cmdReg.data,
(void *)&dataBuffer[SectorSize - drqBytesLeft],
sizeof(uint16_t));
}
@@ -966,7 +1016,7 @@ IdeDisk::updateState(DevAction_t action)
} else {
// copy the latest short into the data buffer
memcpy((void *)&dataBuffer[SectorSize - drqBytesLeft],
- (void *)&cmdReg.data0,
+ (void *)&cmdReg.data,
sizeof(uint16_t));
drqBytesLeft -= 2;
@@ -1090,8 +1140,7 @@ IdeDisk::serialize(ostream &os)
SERIALIZE_ENUM(event);
// Serialize device registers
- SERIALIZE_SCALAR(cmdReg.data0);
- SERIALIZE_SCALAR(cmdReg.data1);
+ SERIALIZE_SCALAR(cmdReg.data);
SERIALIZE_SCALAR(cmdReg.sec_count);
SERIALIZE_SCALAR(cmdReg.sec_num);
SERIALIZE_SCALAR(cmdReg.cyl_low);
@@ -1143,8 +1192,7 @@ IdeDisk::unserialize(Checkpoint *cp, const string &section)
}
// Unserialize device registers
- UNSERIALIZE_SCALAR(cmdReg.data0);
- UNSERIALIZE_SCALAR(cmdReg.data1);
+ UNSERIALIZE_SCALAR(cmdReg.data);
UNSERIALIZE_SCALAR(cmdReg.sec_count);
UNSERIALIZE_SCALAR(cmdReg.sec_num);
UNSERIALIZE_SCALAR(cmdReg.cyl_low);
diff --git a/dev/ide_disk.hh b/dev/ide_disk.hh
index 506f0c7cb..9799e2d38 100644
--- a/dev/ide_disk.hh
+++ b/dev/ide_disk.hh
@@ -35,6 +35,7 @@
#include "dev/disk_image.hh"
#include "dev/ide_atareg.h"
+#include "dev/ide_ctrl.hh"
#include "dev/ide_wdcreg.h"
#include "dev/io_device.hh"
#include "sim/eventq.hh"
@@ -83,6 +84,7 @@ class PrdTableEntry {
#define LCYL_OFFSET (4)
#define HCYL_OFFSET (5)
#define SELECT_OFFSET (6)
+#define DRIVE_OFFSET (6)
#define STATUS_OFFSET (7)
#define COMMAND_OFFSET (7)
@@ -103,12 +105,8 @@ class PrdTableEntry {
#define DEV1 (1)
typedef struct CommandReg {
- uint8_t data0;
- union {
- uint8_t data1;
- uint8_t error;
- uint8_t features;
- };
+ uint16_t data;
+ uint8_t error;
uint8_t sec_count;
uint8_t sec_num;
uint8_t cyl_low;
@@ -272,7 +270,7 @@ class IdeDisk : public SimObject
}
// Device register read/write
- void read(const Addr &offset, bool byte, bool cmdBlk, uint8_t *data);
+ void read(const Addr &offset, RegType_t type, uint8_t *data);
void write(const Addr &offset, bool byte, bool cmdBlk, const uint8_t *data);
// Start/abort functions
diff --git a/dev/ns_gige.cc b/dev/ns_gige.cc
index 4e7deba90..0d446214d 100644
--- a/dev/ns_gige.cc
+++ b/dev/ns_gige.cc
@@ -1360,7 +1360,7 @@ void
NSGigE::regsReset()
{
memset(&regs, 0, sizeof(regs));
- regs.config = CFGR_LNKSTS;
+ regs.config = (CFGR_LNKSTS | CFGR_TBI_EN | CFGR_MODE_1000);
regs.mear = 0x22;
regs.txcfg = 0x120; // set drain threshold to 1024 bytes and
// fill threshold to 32 bytes
diff --git a/dev/ns_gige.hh b/dev/ns_gige.hh
index 143460b64..67f1b7ef5 100644
--- a/dev/ns_gige.hh
+++ b/dev/ns_gige.hh
@@ -99,7 +99,7 @@ class Bus;
class PciConfigAll;
/**
- * NS DP82830 Ethernet device model
+ * NS DP83820 Ethernet device model
*/
class NSGigE : public PciDev
{
diff --git a/dev/pciconfigall.cc b/dev/pciconfigall.cc
index 7d86c3e1b..8c6657ceb 100644
--- a/dev/pciconfigall.cc
+++ b/dev/pciconfigall.cc
@@ -152,21 +152,17 @@ PciConfigAll::write(MemReqPtr &req, const uint8_t *data)
int func = (daddr >> 8) & 0x7;
int reg = daddr & 0xFF;
- union {
- uint8_t byte_value;
- uint16_t half_value;
- uint32_t word_value;
- };
+ uint32_t word_value = 0;
if (devices[device][func] == NULL)
panic("Attempting to write to config space on non-existant device\n");
else {
switch (req->size) {
case sizeof(uint8_t):
- byte_value = *(uint8_t*)data;
+ word_value = *(uint8_t*)data;
break;
case sizeof(uint16_t):
- half_value = *(uint16_t*)data;
+ word_value = *(uint16_t*)data;
break;
case sizeof(uint32_t):
word_value = *(uint32_t*)data;
diff --git a/dev/pcidev.cc b/dev/pcidev.cc
index f2bce33ca..31c44bffa 100644
--- a/dev/pcidev.cc
+++ b/dev/pcidev.cc
@@ -73,39 +73,38 @@ PciDev::PciDev(Params *p)
void
PciDev::ReadConfig(int offset, int size, uint8_t *data)
{
+ union {
+ uint8_t byte;
+ uint16_t word;
+ uint32_t dword;
+ };
+
if (offset >= PCI_DEVICE_SPECIFIC)
panic("Device specific PCI config space not implemented!\n");
+ dword = 0;
+
switch(size) {
- case sizeof(uint32_t):
- memcpy((uint8_t*)data, config.data + offset, sizeof(uint32_t));
- *(uint32_t*)data = htoa(*(uint32_t*)data);
- DPRINTF(PCIDEV,
- "read device: %#x function: %#x register: %#x %d bytes: data: %#x\n",
- params()->deviceNum, params()->functionNum, offset, size,
- *(uint32_t*)(config.data + offset));
+ case sizeof(uint8_t):
+ memcpy(&byte, &config.data[offset], size);
+ *data = byte;
break;
-
case sizeof(uint16_t):
- memcpy((uint8_t*)data, config.data + offset, sizeof(uint16_t));
- *(uint16_t*)data = htoa(*(uint16_t*)data);
- DPRINTF(PCIDEV,
- "read device: %#x function: %#x register: %#x %d bytes: data: %#x\n",
- params()->deviceNum, params()->functionNum, offset, size,
- *(uint16_t*)(config.data + offset));
+ memcpy(&byte, &config.data[offset], size);
+ *(uint16_t*)data = htoa(word);
break;
-
- case sizeof(uint8_t):
- memcpy((uint8_t*)data, config.data + offset, sizeof(uint8_t));
- DPRINTF(PCIDEV,
- "read device: %#x function: %#x register: %#x %d bytes: data: %#x\n",
- params()->deviceNum, params()->functionNum, offset, size,
- (uint16_t)(*(uint8_t*)(config.data + offset)));
+ case sizeof(uint32_t):
+ memcpy(&byte, &config.data[offset], size);
+ *(uint32_t*)data = htoa(dword);
break;
-
default:
- panic("Invalid Read Size");
+ panic("Invalid PCI configuration read size!\n");
}
+
+ DPRINTF(PCIDEV,
+ "read device: %#x function: %#x register: %#x %d bytes: data: %#x\n",
+ params()->deviceNum, params()->functionNum, offset, size,
+ htoa(dword));
}
void
@@ -116,35 +115,40 @@ PciDev::WriteConfig(int offset, int size, uint32_t data)
uint32_t barnum;
- union {
- uint8_t byte_value;
- uint16_t half_value;
- uint32_t word_value;
- };
- word_value = data;
+ uint8_t byte_value;
+ uint16_t half_value;
+ uint32_t word_value;
DPRINTF(PCIDEV,
"write device: %#x function: %#x reg: %#x size: %d data: %#x\n",
params()->deviceNum, params()->functionNum, offset, size,
- word_value);
+ data);
barnum = (offset - PCI0_BASE_ADDR0) >> 2;
switch (size) {
case sizeof(uint8_t): // 1-byte access
+ byte_value = data;
switch (offset) {
case PCI0_INTERRUPT_LINE:
case PCI_CACHE_LINE_SIZE:
case PCI_LATENCY_TIMER:
*(uint8_t *)&config.data[offset] = htoa(byte_value);
break;
-
+ /* Do nothing for these read-only registers */
+ case PCI0_INTERRUPT_PIN:
+ case PCI0_MINIMUM_GRANT:
+ case PCI0_MAXIMUM_LATENCY:
+ case PCI_CLASS_CODE:
+ case PCI_REVISION_ID:
+ break;
default:
panic("writing to a read only register");
}
break;
case sizeof(uint16_t): // 2-byte access
+ half_value = data;
switch (offset) {
case PCI_COMMAND:
case PCI_STATUS:
@@ -157,10 +161,8 @@ PciDev::WriteConfig(int offset, int size, uint32_t data)
}
break;
- case sizeof(uint16_t)+1: // 3-byte access
- panic("invalid access size");
-
case sizeof(uint32_t): // 4-byte access
+ word_value = data;
switch (offset) {
case PCI0_BASE_ADDR0:
case PCI0_BASE_ADDR1:
@@ -175,12 +177,12 @@ PciDev::WriteConfig(int offset, int size, uint32_t data)
// This is I/O Space, bottom two bits are read only
if (htoa(config.data[offset]) & 0x1) {
*(uint32_t *)&config.data[offset] = htoa(
- ~(BARSize[barnum] - 1) |
+ (~(BARSize[barnum] - 1) & ~0x3) |
(htoa(config.data[offset]) & 0x3));
} else {
// This is memory space, bottom four bits are read only
*(uint32_t *)&config.data[offset] = htoa(
- ~(BARSize[barnum] - 1) |
+ (~(BARSize[barnum] - 1) & ~0xF) |
(htoa(config.data[offset]) & 0xF));
}
} else {
@@ -192,7 +194,7 @@ PciDev::WriteConfig(int offset, int size, uint32_t data)
htoa((word_value & ~0x3) |
(htoa(config.data[offset]) & 0x3));
- if (word_value & ~0x1) {
+ if (word_value != 0x1) {
Addr base_addr = (word_value & ~0x1) + TSUNAMI_PCI0_IO;
Addr base_size = BARSize[barnum];
@@ -255,6 +257,9 @@ PciDev::WriteConfig(int offset, int size, uint32_t data)
DPRINTF(PCIDEV, "Writing to a read only register");
}
break;
+
+ default:
+ panic("invalid access size");
}
}
diff --git a/dev/pcidev.hh b/dev/pcidev.hh
index 091a365e3..31b0cab16 100644
--- a/dev/pcidev.hh
+++ b/dev/pcidev.hh
@@ -115,7 +115,7 @@ class PciDev : public DmaDevice
protected:
/** The current config space. Unlike the PciConfigData this is
- * updated during simulation while continues to refelect what was
+ * updated during simulation while continues to reflect what was
* in the config file.
*/
PCIConfig config;
diff --git a/dev/tsunami_io.cc b/dev/tsunami_io.cc
index da1062237..82fe40e0a 100644
--- a/dev/tsunami_io.cc
+++ b/dev/tsunami_io.cc
@@ -52,11 +52,14 @@ using namespace std;
#define UNIX_YEAR_OFFSET 52
+struct tm TsunamiIO::tm = { 0 };
+
// Timer Event for Periodic interrupt of RTC
TsunamiIO::RTCEvent::RTCEvent(Tsunami* t, Tick i)
: Event(&mainEventQueue), tsunami(t), interval(i)
{
DPRINTF(MC146818, "RTC Event Initilizing\n");
+ intr_count = 0;
schedule(curTick + interval);
}
@@ -67,6 +70,11 @@ TsunamiIO::RTCEvent::process()
schedule(curTick + interval);
//Actually interrupt the processor here
tsunami->cchip->postRTC();
+
+ if (intr_count == 1023)
+ tm.tm_sec = (tm.tm_sec + 1) % 60;
+
+ intr_count = (intr_count + 1) % 1024;
}
const char *
@@ -104,6 +112,11 @@ TsunamiIO::ClockEvent::ClockEvent()
DPRINTF(Tsunami, "Clock Event Initilizing\n");
mode = 0;
+
+ current_count = 0;
+ latched_count = 0;
+ latch_on = false;
+ read_byte = READ_LSB;
}
void
@@ -114,6 +127,8 @@ TsunamiIO::ClockEvent::process()
status = 0x20; // set bit that linux is looking for
else
schedule(curTick + interval);
+
+ current_count--; //decrement count
}
void
@@ -122,6 +137,8 @@ TsunamiIO::ClockEvent::Program(int count)
DPRINTF(Tsunami, "Timer set to curTick + %d\n", count * interval);
schedule(curTick + count * interval);
status = 0;
+
+ current_count = (uint16_t)count;
}
const char *
@@ -143,6 +160,51 @@ TsunamiIO::ClockEvent::Status()
}
void
+TsunamiIO::ClockEvent::LatchCount()
+{
+ // behave like a real latch
+ if(!latch_on) {
+ latch_on = true;
+ read_byte = READ_LSB;
+ latched_count = current_count;
+ }
+}
+
+uint8_t
+TsunamiIO::ClockEvent::Read()
+{
+ uint8_t result = 0;
+
+ if(latch_on) {
+ switch (read_byte) {
+ case READ_LSB:
+ read_byte = READ_MSB;
+ result = (uint8_t)latched_count;
+ break;
+ case READ_MSB:
+ read_byte = READ_LSB;
+ latch_on = false;
+ result = latched_count >> 8;
+ break;
+ }
+ } else {
+ switch (read_byte) {
+ case READ_LSB:
+ read_byte = READ_MSB;
+ result = (uint8_t)current_count;
+ break;
+ case READ_MSB:
+ read_byte = READ_LSB;
+ result = current_count >> 8;
+ break;
+ }
+ }
+
+ return result;
+}
+
+
+void
TsunamiIO::ClockEvent::serialize(std::ostream &os)
{
Tick time = scheduled() ? when() : 0;
@@ -213,6 +275,13 @@ TsunamiIO::read(MemReqPtr &req, uint8_t *data)
switch(req->size) {
case sizeof(uint8_t):
switch(daddr) {
+ // PIC1 mask read
+ case TSDEV_PIC1_MASK:
+ *(uint8_t*)data = ~mask1;
+ return No_Fault;
+ case TSDEV_PIC2_MASK:
+ *(uint8_t*)data = ~mask2;
+ return No_Fault;
case TSDEV_PIC1_ISR:
// !!! If this is modified 64bit case needs to be too
// Pal code has to do a 64 bit physical read because there is
@@ -226,6 +295,9 @@ TsunamiIO::read(MemReqPtr &req, uint8_t *data)
case TSDEV_TMR_CTL:
*(uint8_t*)data = timer2.Status();
return No_Fault;
+ case TSDEV_TMR0_DATA:
+ *(uint8_t *)data = timer0.Read();
+ return No_Fault;
case TSDEV_RTC_DATA:
switch(RTCAddress) {
case RTC_CNTRL_REGA:
@@ -243,6 +315,12 @@ TsunamiIO::read(MemReqPtr &req, uint8_t *data)
return No_Fault;
case RTC_CNTRL_REGD:
panic("RTC Control Register D not implemented");
+ case RTC_SEC_ALRM:
+ case RTC_MIN_ALRM:
+ case RTC_HR_ALRM:
+ // RTC alarm functionality is not currently implemented
+ *(uint8_t *)data = 0x00;
+ return No_Fault;
case RTC_SEC:
*(uint8_t *)data = tm.tm_sec;
return No_Fault;
@@ -257,6 +335,7 @@ TsunamiIO::read(MemReqPtr &req, uint8_t *data)
return No_Fault;
case RTC_DOM:
*(uint8_t *)data = tm.tm_mday;
+ return No_Fault;
case RTC_MON:
*(uint8_t *)data = tm.tm_mon + 1;
return No_Fault;
@@ -267,6 +346,14 @@ TsunamiIO::read(MemReqPtr &req, uint8_t *data)
panic("Unknown RTC Address\n");
}
+ /* Added for keyboard reads */
+ case TSDEV_KBD:
+ *(uint8_t *)data = 0x00;
+ return No_Fault;
+ /* Added for ATA PCI DMA */
+ case ATA_PCI_DMA:
+ *(uint8_t *)data = 0x00;
+ return No_Fault;
default:
panic("I/O Read - va%#x size %d\n", req->vaddr, req->size);
}
@@ -355,8 +442,24 @@ TsunamiIO::write(MemReqPtr &req, const uint8_t *data)
case TSDEV_TMR_CTL:
return No_Fault;
case TSDEV_TMR2_CTL:
- if ((*(uint8_t*)data & 0x30) != 0x30)
- panic("Only L/M write supported\n");
+ switch((*(uint8_t*)data >> 4) & 0x3) {
+ case 0x0:
+ switch(*(uint8_t*)data >> 6) {
+ case 0:
+ timer0.LatchCount();
+ break;
+ case 2:
+ timer2.LatchCount();
+ break;
+ default:
+ panic("Read Back Command not implemented\n");
+ }
+ break;
+ case 0x3:
+ break;
+ default:
+ panic("Only L/M write and Counter-Latch read supported\n");
+ }
switch(*(uint8_t*)data >> 6) {
case 0:
@@ -396,8 +499,41 @@ TsunamiIO::write(MemReqPtr &req, const uint8_t *data)
case TSDEV_RTC_ADDR:
RTCAddress = *(uint8_t*)data;
return No_Fault;
+ case TSDEV_KBD:
+ return No_Fault;
case TSDEV_RTC_DATA:
- panic("RTC Write not implmented (rtc.o won't work)\n");
+ switch(RTCAddress) {
+ case RTC_CNTRL_REGA:
+ return No_Fault;
+ case RTC_CNTRL_REGB:
+ return No_Fault;
+ case RTC_CNTRL_REGC:
+ return No_Fault;
+ case RTC_CNTRL_REGD:
+ return No_Fault;
+ case RTC_SEC:
+ tm.tm_sec = *(uint8_t *)data;
+ return No_Fault;
+ case RTC_MIN:
+ tm.tm_min = *(uint8_t *)data;
+ return No_Fault;
+ case RTC_HR:
+ tm.tm_hour = *(uint8_t *)data;
+ return No_Fault;
+ case RTC_DOW:
+ tm.tm_wday = *(uint8_t *)data;
+ return No_Fault;
+ case RTC_DOM:
+ tm.tm_mday = *(uint8_t *)data;
+ return No_Fault;
+ case RTC_MON:
+ tm.tm_mon = *(uint8_t *)data - 1;
+ return No_Fault;
+ case RTC_YEAR:
+ tm.tm_year = *(uint8_t *)data + UNIX_YEAR_OFFSET;
+ return No_Fault;
+ //panic("RTC Write not implmented (rtc.o won't work)\n");
+ }
default:
panic("I/O Write - va%#x size %d\n", req->vaddr, req->size);
}
diff --git a/dev/tsunami_io.hh b/dev/tsunami_io.hh
index d5d106db3..4b28635e8 100644
--- a/dev/tsunami_io.hh
+++ b/dev/tsunami_io.hh
@@ -51,7 +51,7 @@ class TsunamiIO : public PioDevice
/** The size of mappad from the above address */
static const Addr size = 0xff;
- struct tm tm;
+ static struct tm tm;
/**
* In Tsunami RTC only has two i/o ports one for data and one for
@@ -75,6 +75,14 @@ class TsunamiIO : public PioDevice
uint8_t mode;
/** The status of the PIT */
uint8_t status;
+ /** The current count of the PIT */
+ uint16_t current_count;
+ /** The latched count of the PIT */
+ uint16_t latched_count;
+ /** The state of the output latch of the PIT */
+ bool latch_on;
+ /** The next count half (byte) to read */
+ enum {READ_LSB, READ_MSB} read_byte;
public:
/**
@@ -111,6 +119,17 @@ class TsunamiIO : public PioDevice
uint8_t Status();
/**
+ * Latch the count of the PIT.
+ */
+ void LatchCount();
+
+ /**
+ * The current PIT count.
+ * @return the count of the PIT
+ */
+ uint8_t Read();
+
+ /**
* Serialize this object to the given output stream.
* @param os The stream to serialize to.
*/
@@ -135,6 +154,9 @@ class TsunamiIO : public PioDevice
Tsunami* tsunami;
Tick interval;
+ /** Count of the number of RTC interrupts that have occured */
+ uint32_t intr_count;
+
public:
/**
* RTC Event initializes the RTC event by scheduling an event
diff --git a/dev/tsunamireg.h b/dev/tsunamireg.h
index 5fbfd5c31..8b290deb1 100644
--- a/dev/tsunamireg.h
+++ b/dev/tsunamireg.h
@@ -123,6 +123,18 @@
#define TSDEV_TMR2_DATA 0x42
#define TSDEV_TMR0_DATA 0x40
+/* Added for keyboard accesses */
+#define TSDEV_KBD 0x64
+
+/* Added for ATA PCI DMA */
+#define ATA_PCI_DMA 0x00
+#define ATA_PCI_DMA2 0x02
+#define ATA_PCI_DMA3 0x16
+#define ATA_PCI_DMA4 0x17
+#define ATA_PCI_DMA5 0x1a
+#define ATA_PCI_DMA6 0x11
+#define ATA_PCI_DMA7 0x14
+
#define TSDEV_RTC_ADDR 0x70
#define TSDEV_RTC_DATA 0x71
diff --git a/dev/uart8250.cc b/dev/uart8250.cc
index 99e3bd017..ad3232686 100644
--- a/dev/uart8250.cc
+++ b/dev/uart8250.cc
@@ -146,10 +146,11 @@ Uart8250::read(MemReqPtr &req, uint8_t *data)
break;
case 0x2: // Intr Identification Register (IIR)
DPRINTF(Uart, "IIR Read, status = %#x\n", (uint32_t)status);
- if (status)
- *(uint8_t*)data = 0;
+ status &= ~TX_INT;
+ if (status & RX_INT)
+ *(uint8_t*)data = 0x4;
else
- *(uint8_t*)data = 1;
+ *(uint8_t*)data = 0x1;
break;
case 0x3: // Line Control Register (LCR)
*(uint8_t*)data = LCR;
diff --git a/kern/freebsd/freebsd_system.cc b/kern/freebsd/freebsd_system.cc
new file mode 100644
index 000000000..2eb80b8e9
--- /dev/null
+++ b/kern/freebsd/freebsd_system.cc
@@ -0,0 +1,161 @@
+/*
+ * Copyright (c) 2004-2005 The Regents of The University of Michigan
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "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 COPYRIGHT
+ * OWNER OR CONTRIBUTORS 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.
+ */
+
+/**
+ * @file
+ * Modifications for the FreeBSD kernel.
+ * Based on kern/linux/linux_system.cc.
+ * Currently only used to skip DELAY function.
+ *
+ */
+
+#include "base/loader/symtab.hh"
+#include "cpu/exec_context.hh"
+#include "kern/freebsd/freebsd_system.hh"
+#include "mem/functional/memory_control.hh"
+#include "mem/functional/physical.hh"
+#include "sim/builder.hh"
+#include "targetarch/vtophys.hh"
+
+using namespace std;
+
+FreebsdSystem::FreebsdSystem(Params *p)
+ : System(p)
+{
+ Addr addr = 0;
+
+ /**
+ * Any time DELAY is called just skip the function.
+ * Replace calibrate_clocks with function below.
+ */
+ skipDelayEvent = new SkipFuncEvent(&pcEventQueue, "DELAY");
+ if (kernelSymtab->findAddress("DELAY", addr))
+ skipDelayEvent->schedule(addr+sizeof(MachInst));
+
+ skipCalibrateClocks = new FreebsdSkipCalibrateClocksEvent(&pcEventQueue, "calibrate_clocks");
+ if (kernelSymtab->findAddress("calibrate_clocks", addr))
+ skipCalibrateClocks->schedule(addr + sizeof(MachInst) * 2);
+
+}
+
+
+FreebsdSystem::~FreebsdSystem()
+{
+ delete skipDelayEvent;
+ delete skipCalibrateClocks;
+}
+
+
+void
+FreebsdSystem::doCalibrateClocks(ExecContext *xc)
+{
+ Addr ppc_vaddr = 0;
+ Addr timer_vaddr = 0;
+ Addr ppc_paddr = 0;
+ Addr timer_paddr = 0;
+
+ ppc_vaddr = (Addr)xc->regs.intRegFile[ArgumentReg1];
+ timer_vaddr = (Addr)xc->regs.intRegFile[ArgumentReg2];
+
+ ppc_paddr = vtophys(physmem, ppc_vaddr);
+ timer_paddr = vtophys(physmem, timer_vaddr);
+
+ uint8_t *ppc = physmem->dma_addr(ppc_paddr, sizeof(uint32_t));
+ uint8_t *timer = physmem->dma_addr(timer_paddr, sizeof(uint32_t));
+
+ *(uint32_t *)ppc = htoa((uint32_t)2000000000);
+ *(uint32_t *)timer = htoa((uint32_t)1193180);
+}
+
+
+BEGIN_DECLARE_SIM_OBJECT_PARAMS(FreebsdSystem)
+
+ Param<Tick> boot_cpu_frequency;
+ SimObjectParam<MemoryController *> memctrl;
+ SimObjectParam<PhysicalMemory *> physmem;
+
+ Param<string> kernel;
+ Param<string> console;
+ Param<string> pal;
+
+ Param<string> boot_osflags;
+ Param<string> readfile;
+ Param<unsigned int> init_param;
+
+ Param<uint64_t> system_type;
+ Param<uint64_t> system_rev;
+
+ Param<bool> bin;
+ VectorParam<string> binned_fns;
+ Param<bool> bin_int;
+
+END_DECLARE_SIM_OBJECT_PARAMS(FreebsdSystem)
+
+BEGIN_INIT_SIM_OBJECT_PARAMS(FreebsdSystem)
+
+ INIT_PARAM(boot_cpu_frequency, "Frequency of the boot CPU"),
+ INIT_PARAM(memctrl, "memory controller"),
+ INIT_PARAM(physmem, "phsyical memory"),
+ INIT_PARAM(kernel, "file that contains the kernel code"),
+ INIT_PARAM(console, "file that contains the console code"),
+ INIT_PARAM(pal, "file that contains palcode"),
+ INIT_PARAM_DFLT(boot_osflags, "flags to pass to the kernel during boot",
+ "a"),
+ INIT_PARAM_DFLT(readfile, "file to read startup script from", ""),
+ INIT_PARAM_DFLT(init_param, "numerical value to pass into simulator", 0),
+ INIT_PARAM_DFLT(system_type, "Type of system we are emulating", 34),
+ INIT_PARAM_DFLT(system_rev, "Revision of system we are emulating", 1<<10),
+ INIT_PARAM_DFLT(bin, "is this system to be binned", false),
+ INIT_PARAM(binned_fns, "functions to be broken down and binned"),
+ INIT_PARAM_DFLT(bin_int, "is interrupt code binned seperately?", true)
+
+END_INIT_SIM_OBJECT_PARAMS(FreebsdSystem)
+
+CREATE_SIM_OBJECT(FreebsdSystem)
+{
+ System::Params *p = new System::Params;
+ p->name = getInstanceName();
+ p->boot_cpu_frequency = boot_cpu_frequency;
+ p->memctrl = memctrl;
+ p->physmem = physmem;
+ p->kernel_path = kernel;
+ p->console_path = console;
+ p->palcode = pal;
+ p->boot_osflags = boot_osflags;
+ p->init_param = init_param;
+ p->readfile = readfile;
+ p->system_type = system_type;
+ p->system_rev = system_rev;
+ p->bin = bin;
+ p->binned_fns = binned_fns;
+ p->bin_int = bin_int;
+ return new FreebsdSystem(p);
+}
+
+REGISTER_SIM_OBJECT("FreebsdSystem", FreebsdSystem)
+
diff --git a/kern/freebsd/freebsd_system.hh b/kern/freebsd/freebsd_system.hh
new file mode 100644
index 000000000..6b236e52e
--- /dev/null
+++ b/kern/freebsd/freebsd_system.hh
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2004-2005 The Regents of The University of Michigan
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "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 COPYRIGHT
+ * OWNER OR CONTRIBUTORS 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.
+ */
+
+#ifndef __KERN_FREEBSD_FREEBSD_SYSTEM_HH__
+#define __KERN_FREEBSD_FREEBSD_SYSTEM_HH__
+
+#include "kern/freebsd/freebsd_events.hh"
+
+class FreebsdSystem : public System
+{
+ private:
+
+ SkipFuncEvent *skipDelayEvent;
+
+ FreebsdSkipCalibrateClocksEvent *skipCalibrateClocks;
+
+ public:
+ FreebsdSystem(Params *p);
+ ~FreebsdSystem();
+ void doCalibrateClocks(ExecContext *xc);
+
+};
+
+#endif // __KERN_FREEBSD_FREEBSD_SYSTEM_HH__
diff --git a/kern/kernel_stats.cc b/kern/kernel_stats.cc
index 6e4a77f4e..3a7d12443 100644
--- a/kern/kernel_stats.cc
+++ b/kern/kernel_stats.cc
@@ -32,13 +32,8 @@
#include "arch/alpha/osfpal.hh"
#include "base/trace.hh"
-#include "base/statistics.hh"
-#include "base/stats/bin.hh"
#include "cpu/exec_context.hh"
-#include "cpu/pc_event.hh"
-#include "cpu/static_inst.hh"
#include "kern/kernel_stats.hh"
-#include "kern/linux/linux_syscalls.hh"
#include "kern/tru64/tru64_syscalls.hh"
using namespace std;
diff --git a/kern/kernel_stats.hh b/kern/kernel_stats.hh
index 66364d2d7..7b931ef79 100644
--- a/kern/kernel_stats.hh
+++ b/kern/kernel_stats.hh
@@ -34,10 +34,6 @@
#include <string>
#include <vector>
-#include "base/statistics.hh"
-#include "sim/serialize.hh"
-#include "targetarch/isa_traits.hh"
-
class BaseCPU;
class ExecContext;
class FnEvent;
diff --git a/kern/linux/aligned.hh b/kern/linux/aligned.hh
index 426299b5d..18d1b43c0 100644
--- a/kern/linux/aligned.hh
+++ b/kern/linux/aligned.hh
@@ -30,9 +30,6 @@
#define __KERN_LINUX_ALIGNED_HH__
-#include "sim/host.hh"
-#include "targetarch/isa_traits.hh"
-
/* GCC 3.3.X has a bug in which attributes+typedefs don't work. 3.2.X is fine
* as in 3.4.X, but the bug is marked will not fix in 3.3.X so here is
* the work around.
diff --git a/kern/linux/linux_system.cc b/kern/linux/linux_system.cc
index 21450e400..8c57ce29c 100644
--- a/kern/linux/linux_system.cc
+++ b/kern/linux/linux_system.cc
@@ -36,19 +36,15 @@
*/
#include "base/loader/symtab.hh"
-#include "base/trace.hh"
#include "cpu/exec_context.hh"
#include "cpu/base.hh"
#include "kern/linux/linux_events.hh"
#include "kern/linux/linux_system.hh"
-#include "kern/system_events.hh"
#include "mem/functional/memory_control.hh"
#include "mem/functional/physical.hh"
#include "sim/builder.hh"
#include "dev/platform.hh"
-#include "targetarch/isa_traits.hh"
#include "targetarch/vtophys.hh"
-#include "sim/debug.hh"
using namespace std;
diff --git a/kern/linux/linux_system.hh b/kern/linux/linux_system.hh
index f870b7744..32b92f310 100644
--- a/kern/linux/linux_system.hh
+++ b/kern/linux/linux_system.hh
@@ -29,10 +29,6 @@
#ifndef __KERN_LINUX_LINUX_SYSTEM_HH__
#define __KERN_LINUX_LINUX_SYSTEM_HH__
-#include "sim/host.hh"
-#include "sim/system.hh"
-#include "targetarch/isa_traits.hh"
-
/**
* MAGIC address where the kernel arguments should go. Defined as
* PARAM in linux kernel alpha-asm.
diff --git a/kern/linux/linux_threadinfo.hh b/kern/linux/linux_threadinfo.hh
index 92cc181db..253b122bc 100644
--- a/kern/linux/linux_threadinfo.hh
+++ b/kern/linux/linux_threadinfo.hh
@@ -30,9 +30,7 @@
#define __LINUX_TREADNIFO_HH__
-#include "targetarch/isa_traits.hh"
#include "targetarch/vptr.hh"
-#include "cpu/exec_context.hh"
#include "kern/linux/thread_info.hh"
#include "kern/linux/sched.hh"
diff --git a/kern/linux/printk.cc b/kern/linux/printk.cc
index cafc9172a..fbc8bdad1 100644
--- a/kern/linux/printk.cc
+++ b/kern/linux/printk.cc
@@ -29,12 +29,8 @@
#include <sys/types.h>
#include <algorithm>
-#include "base/cprintf.hh"
#include "base/trace.hh"
-#include "sim/host.hh"
#include "targetarch/arguments.hh"
-#include "targetarch/vtophys.hh"
-#include "kern/linux/printk.hh"
using namespace std;
diff --git a/kern/linux/sched.hh b/kern/linux/sched.hh
index e3febb298..a11fa590d 100644
--- a/kern/linux/sched.hh
+++ b/kern/linux/sched.hh
@@ -29,9 +29,6 @@
#ifndef __KERN_LINUX_SCHED_HH__
#define __KERN_LINUX_SCHED_HH__
-#include "targetarch/isa_traits.hh"
-#include "kern/linux/aligned.hh"
-
namespace Linux {
struct task_struct {
uint8_t junk1[0xf4];
diff --git a/kern/linux/thread_info.hh b/kern/linux/thread_info.hh
index c8bcc726a..cf24ef939 100644
--- a/kern/linux/thread_info.hh
+++ b/kern/linux/thread_info.hh
@@ -30,7 +30,6 @@
#define __KERN_LINUX_THREAD_INFO_H__
#include "kern/linux/hwrpb.hh"
-#include "kern/linux/aligned.hh"
namespace Linux {
struct thread_info {
diff --git a/kern/system_events.cc b/kern/system_events.cc
index 40c223b5e..d5c0d242a 100644
--- a/kern/system_events.cc
+++ b/kern/system_events.cc
@@ -26,13 +26,8 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#include "cpu/exec_context.hh"
-#include "cpu/base.hh"
-#include "encumbered/cpu/full/bpred.hh"
#include "encumbered/cpu/full/cpu.hh"
#include "kern/kernel_stats.hh"
-#include "kern/system_events.hh"
-#include "sim/system.hh"
void
SkipFuncEvent::process(ExecContext *xc)
diff --git a/kern/system_events.hh b/kern/system_events.hh
index 24aa8f154..94f6efeba 100644
--- a/kern/system_events.hh
+++ b/kern/system_events.hh
@@ -29,8 +29,6 @@
#ifndef __SYSTEM_EVENTS_HH__
#define __SYSTEM_EVENTS_HH__
-#include "cpu/pc_event.hh"
-
class System;
class SkipFuncEvent : public PCEvent
diff --git a/python/m5/objects/Pci.py b/python/m5/objects/Pci.py
index 0957e2883..defdd10a3 100644
--- a/python/m5/objects/Pci.py
+++ b/python/m5/objects/Pci.py
@@ -50,3 +50,6 @@ class PciDevice(DmaDevice):
pci_func = Param.Int("PCI function code")
configdata = Param.PciConfigData(Parent.any, "PCI Config data")
configspace = Param.PciConfigAll(Parent.any, "PCI Configspace")
+
+class PciFake(PciDevice):
+ type = 'PciFake'
diff --git a/python/m5/objects/Tsunami.py b/python/m5/objects/Tsunami.py
index c8fd94e2c..dd52bd11d 100644
--- a/python/m5/objects/Tsunami.py
+++ b/python/m5/objects/Tsunami.py
@@ -13,6 +13,7 @@ class TsunamiCChip(FooPioDevice):
class TsunamiFake(FooPioDevice):
type = 'TsunamiFake'
+ size = Param.Addr(0x8, "Size of address range")
class TsunamiIO(FooPioDevice):
type = 'TsunamiIO'