Rewrite of the PCI base address (BAR) handling to reduce code duplication.

- Added new structure bx_pci_bar_t that contains all parameters related to the
  PCI BARs (type, size, address and r/w handlers).
- Added new methods init_bar_io() and init_bar_mem() to set up the new structure
  in the pci device init code.
- Added new method pci_write_handler_common() to handle writes to the normal
  BARs and the ROM BAR. Writes to other registers are forwarded to the device
  specific PCI write handlers. Removed BAR and ROM BAR handling from the
  specific code.
- Added new method pci_bar_change_notify() to execute specific code after BAR
  update (vga, ne2k).
- Moved normal BAR handling to method after_restore_pci_state().
- Store pointer to PCI device name in bx_pci_device_c and use it for i/o setup.
This commit is contained in:
Volker Ruppert 2018-02-04 09:41:50 +00:00
parent c4a86cbee0
commit 87145baf61
17 changed files with 223 additions and 561 deletions

View File

@ -2,7 +2,7 @@
// $Id$
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2002-2017 The Bochs Project
// Copyright (C) 2002-2018 The Bochs Project
//
// I/O port handlers API Copyright (C) 2003 by Frank Cornelis
//
@ -503,7 +503,7 @@ void bx_devices_c::write(Bit32u address, Bit32u value, unsigned io_len)
Bit32u handle = BX_DEV_THIS pci.handler_id[devfunc];
if ((io_len <= 4) && (handle < BX_MAX_PCI_DEVICES)) {
if (((regnum>=4) && (regnum<=7)) || (regnum==12) || (regnum==13) || (regnum>14)) {
BX_DEV_THIS pci.pci_handler[handle].handler->pci_write_handler(regnum, value, io_len);
BX_DEV_THIS pci.pci_handler[handle].handler->pci_write_handler_common(regnum, value, io_len);
}
else
BX_DEBUG(("read only register, write ignored"));
@ -1218,6 +1218,7 @@ bx_bool bx_devices_c::register_pci_handlers(bx_pci_device_c *dev,
pci.handler_id[*devfunc] = handle;
BX_INFO(("%s present at device %d, function %d", descr, *devfunc >> 3,
*devfunc & 0x07));
dev->set_name(descr);
return 1; // device/function mapped successfully
} else {
return 0; // device/function not available, return false.
@ -1310,6 +1311,30 @@ void bx_pci_device_c::init_pci_conf(Bit16u vid, Bit16u did, Bit8u rev, Bit32u cl
pci_conf[0x0e] = headt;
}
void bx_pci_device_c::init_bar_io(Bit8u num, Bit16u size, bx_read_handler_t rh,
bx_write_handler_t wh, const Bit8u *mask)
{
if (num < 6) {
pci_bar[num].type = BX_PCI_BAR_TYPE_IO;
pci_bar[num].size = size;
pci_bar[num].io.rh = rh;
pci_bar[num].io.wh = wh;
pci_bar[num].io.mask = mask;
pci_conf[0x10 + num * 4] = 0x01;
}
}
void bx_pci_device_c::init_bar_mem(Bit8u num, Bit32u size, memory_handler_t rh,
memory_handler_t wh)
{
if (num < 6) {
pci_bar[num].type = BX_PCI_BAR_TYPE_MEM;
pci_bar[num].size = size;
pci_bar[num].mem.rh = rh;
pci_bar[num].mem.wh = wh;
}
}
void bx_pci_device_c::register_pci_state(bx_list_c *list)
{
new bx_shadow_data_c(list, "pci_conf", pci_conf, 256, 1);
@ -1317,6 +1342,23 @@ void bx_pci_device_c::register_pci_state(bx_list_c *list)
void bx_pci_device_c::after_restore_pci_state(memory_handler_t mem_read_handler)
{
for (int i = 0; i < 6; i++) {
if (pci_bar[i].type == BX_PCI_BAR_TYPE_MEM) {
if (DEV_pci_set_base_mem(this, pci_bar[i].mem.rh, pci_bar[i].mem.wh,
&pci_bar[i].addr, &pci_conf[0x10 + i * 4],
pci_bar[i].size)) {
BX_INFO(("BAR #%d: mem base address = 0x%08x", i, pci_bar[i].addr));
pci_bar_change_notify();
}
} else if (pci_bar[i].type == BX_PCI_BAR_TYPE_IO) {
if (DEV_pci_set_base_io(this, pci_bar[i].io.rh, pci_bar[i].io.wh,
&pci_bar[i].addr, &pci_conf[0x10 + i * 4],
pci_bar[i].size, pci_bar[i].io.mask, pci_name)) {
BX_INFO(("BAR #%d: i/o base address = 0x%04x", i, pci_bar[i].addr));
pci_bar_change_notify();
}
}
}
if (pci_rom_size > 0) {
if (DEV_pci_set_base_mem(this, mem_read_handler, NULL, &pci_rom_address,
&pci_conf[0x30], pci_rom_size)) {
@ -1382,6 +1424,66 @@ void bx_pci_device_c::load_pci_rom(const char *path)
BX_INFO(("loaded PCI ROM '%s' (size=%u / PCI=%uk)", path, (unsigned) stat_buf.st_size, pci_rom_size >> 10));
}
// pci configuration space write callback handler (common)
void bx_pci_device_c::pci_write_handler_common(Bit8u address, Bit32u value, unsigned io_len)
{
Bit8u bnum, value8, oldval;
bx_bool bar_change = 0, rom_change = 0;
if ((address >= 0x10) && (address < 0x28)) {
bnum = ((address - 0x10) >> 2);
if (pci_bar[bnum].type != BX_PCI_BAR_TYPE_NONE) {
for (unsigned i=0; i<io_len; i++) {
value8 = (value >> (i*8)) & 0xff;
oldval = pci_conf[address+i];
if (((address+i) & 0x03) == 0) {
if (pci_bar[bnum].type == BX_PCI_BAR_TYPE_IO) {
value8 = (value8 & 0xfc) | 0x01;
} else {
value8 = (value8 & 0xf0) | (oldval & 0x0f);
}
}
bar_change |= (value8 != oldval);
pci_conf[address+i] = value8;
}
if (bar_change) {
if (pci_bar[bnum].type == BX_PCI_BAR_TYPE_IO) {
if (DEV_pci_set_base_io(this, pci_bar[bnum].io.rh, pci_bar[bnum].io.wh,
&pci_bar[bnum].addr, &pci_conf[0x10 + bnum * 4],
pci_bar[bnum].size, pci_bar[bnum].io.mask, pci_name)) {
BX_INFO(("BAR #%d: i/o base address = 0x%04x", bnum, pci_bar[bnum].addr));
pci_bar_change_notify();
}
} else {
if (DEV_pci_set_base_mem(this, pci_bar[bnum].mem.rh, pci_bar[bnum].mem.wh,
&pci_bar[bnum].addr, &pci_conf[0x10 + bnum * 4],
pci_bar[bnum].size)) {
BX_INFO(("BAR #%d: mem base address = 0x%08x", bnum, pci_bar[bnum].addr));
pci_bar_change_notify();
}
}
}
}
} else if ((address & 0xfc) == 0x30) {
value &= (0xfffffc01 >> ((address & 0x03) * 8));
for (unsigned i=0; i<io_len; i++) {
value8 = (value >> (i*8)) & 0xff;
oldval = pci_conf[address+i];
rom_change |= (value8 != oldval);
pci_conf[address+i] = value8;
}
if (rom_change) {
if (DEV_pci_set_base_mem(this, pci_rom_read_handler, NULL,
&pci_rom_address, &pci_conf[0x30],
pci_rom_size)) {
BX_INFO(("new ROM address = 0x%08x", pci_rom_address));
}
}
} else {
pci_write_handler(address, value, io_len);
}
}
// pci configuration space read callback handler
Bit32u bx_pci_device_c::pci_read_handler(Bit8u address, unsigned io_len)
{

View File

@ -142,10 +142,11 @@ void bx_banshee_c::init_model(void)
pci_conf[0x14] = 0x08;
pci_conf[0x18] = 0x01;
pci_conf[0x3d] = BX_PCI_INTA;
pci_base_address[0] = 0;
pci_base_address[1] = 0;
pci_base_address[2] = 0;
init_bar_mem(0, 0x2000000, mem_read_handler, mem_write_handler);
init_bar_mem(1, 0x2000000, mem_read_handler, mem_write_handler);
init_bar_io(2, 256, read_handler, write_handler, &banshee_iomask[0]);
pci_rom_address = 0;
pci_rom_read_handler = mem_read_handler;
load_pci_rom(SIM->get_param_string(BXPN_VGA_ROM_PATH)->getptr());
}
@ -249,24 +250,6 @@ void bx_banshee_c::register_state(void)
void bx_banshee_c::after_restore_state(void)
{
bx_pci_device_c::after_restore_pci_state(mem_read_handler);
if (DEV_pci_set_base_mem(BX_VOODOO_THIS_PTR, mem_read_handler, mem_write_handler,
&pci_base_address[0],
&pci_conf[0x10],
0x2000000)) {
BX_INFO(("new mem base address: 0x%08x", pci_base_address[0]));
}
if (DEV_pci_set_base_mem(BX_VOODOO_THIS_PTR, mem_read_handler, mem_write_handler,
&pci_base_address[1],
&pci_conf[0x14],
0x2000000)) {
BX_INFO(("new lfb base address: 0x%08x", pci_base_address[1]));
}
if (DEV_pci_set_base_io(BX_VOODOO_THIS_PTR, read_handler, write_handler,
&pci_base_address[2],
&pci_conf[0x18],
256, &banshee_iomask[0], "banshee")) {
BX_INFO(("new i/o base address: 0x%04x", pci_base_address[2]));
}
if ((v->banshee.io[io_vidProcCfg] & 0x01) && (theVoodooVga != NULL)) {
update_timing();
theVoodooVga->banshee_update_mode();
@ -428,8 +411,6 @@ void bx_banshee_c::reg_write(Bit32u reg, Bit32u value)
void bx_banshee_c::pci_write_handler(Bit8u address, Bit32u value, unsigned io_len)
{
Bit8u value8, oldval;
bx_bool baseaddr0_change = 0, baseaddr1_change = 0, baseaddr2_change = 0;
bx_bool romaddr_change = 0;
if ((address >= 0x1c) && (address < 0x2c))
return;
@ -446,40 +427,6 @@ void bx_banshee_c::pci_write_handler(Bit8u address, Bit32u value, unsigned io_le
BX_INFO(("new irq line = %d", value8));
}
break;
case 0x10:
value8 = (value8 & 0xf0) | (oldval & 0x0f);
case 0x11:
case 0x12:
case 0x13:
baseaddr0_change |= (value8 != oldval);
break;
case 0x14:
value8 = (value8 & 0xf0) | (oldval & 0x0f);
case 0x15:
case 0x16:
case 0x17:
baseaddr1_change |= (value8 != oldval);
break;
case 0x18:
value8 = (value8 & 0xf0) | (oldval & 0x0f);
case 0x19:
case 0x1a:
case 0x1b:
baseaddr2_change |= (value8 != oldval);
break;
case 0x30:
case 0x31:
case 0x32:
case 0x33:
if (pci_rom_size > 0) {
if ((address+i) == 0x30) {
value8 &= 0x01;
} else if ((address+i) == 0x31) {
value8 &= 0xfc;
}
romaddr_change = 1;
}
break;
case 0x2c:
case 0x2d:
case 0x2e:
@ -495,38 +442,6 @@ void bx_banshee_c::pci_write_handler(Bit8u address, Bit32u value, unsigned io_le
}
pci_conf[address+i] = value8;
}
if (baseaddr0_change) {
if (DEV_pci_set_base_mem(BX_VOODOO_THIS_PTR, mem_read_handler, mem_write_handler,
&pci_base_address[0],
&pci_conf[0x10],
0x2000000)) {
BX_INFO(("new mem base address: 0x%08x", pci_base_address[0]));
}
}
if (baseaddr1_change) {
if (DEV_pci_set_base_mem(BX_VOODOO_THIS_PTR, mem_read_handler, mem_write_handler,
&pci_base_address[1],
&pci_conf[0x14],
0x2000000)) {
BX_INFO(("new lfb base address: 0x%08x", pci_base_address[1]));
}
}
if (baseaddr2_change) {
if (DEV_pci_set_base_io(BX_VOODOO_THIS_PTR, read_handler, write_handler,
&pci_base_address[2],
&pci_conf[0x18],
256, &banshee_iomask[0], "banshee")) {
BX_INFO(("new i/o base address: 0x%04x", pci_base_address[2]));
}
}
if (romaddr_change) {
if (DEV_pci_set_base_mem(BX_VOODOO_THIS_PTR, mem_read_handler, NULL,
&pci_rom_address,
&pci_conf[0x30],
pci_rom_size)) {
BX_INFO(("new ROM address: 0x%08x", pci_rom_address));
}
}
if (io_len == 1)
BX_DEBUG(("write PCI register 0x%02x value 0x%02x", address, value));
@ -821,7 +736,7 @@ void bx_banshee_c::mem_read(bx_phy_address addr, unsigned len, void *data)
return;
}
}
if ((addr & ~0x1ffffff) == pci_base_address[0]) {
if ((addr & ~0x1ffffff) == pci_bar[0].addr) {
if (offset < 0x80000) {
value = read(offset, len);
} else if (offset < 0x100000) {
@ -840,7 +755,7 @@ void bx_banshee_c::mem_read(bx_phy_address addr, unsigned len, void *data)
value = lfb_r((offset & v->fbi.mask) >> 2);
v->fbi.lfb_stride = temp;
}
} else if ((addr & ~0x1ffffff) == pci_base_address[1]) {
} else if ((addr & ~0x1ffffff) == pci_bar[1].addr) {
if (offset >= v->fbi.lfb_base) {
offset -= v->fbi.lfb_base;
pitch *= 128;
@ -862,7 +777,7 @@ void bx_banshee_c::mem_write(bx_phy_address addr, unsigned len, void *data)
Bit32u value = *(Bit32u*)data;
Bit32u mask = 0xffffffff;
if ((addr & ~0x1ffffff) == pci_base_address[0]) {
if ((addr & ~0x1ffffff) == pci_bar[0].addr) {
if (offset < 0x80000) {
write(offset, value, len);
} else if (offset < 0x100000) {
@ -890,7 +805,7 @@ void bx_banshee_c::mem_write(bx_phy_address addr, unsigned len, void *data)
lfb_w((offset & v->fbi.mask) >> 2, value, mask);
v->fbi.lfb_stride = temp;
}
} else if ((addr & ~0x1ffffff) == pci_base_address[1]) {
} else if ((addr & ~0x1ffffff) == pci_bar[1].addr) {
if (v->fbi.cmdfifo[0].enabled && (offset >= v->fbi.cmdfifo[0].base) &&
(offset < v->fbi.cmdfifo[0].end)) {
cmdfifo_w(&v->fbi.cmdfifo[0], offset, value);

View File

@ -410,20 +410,6 @@ void bx_svga_cirrus_c::after_restore_state(void)
#if BX_SUPPORT_PCI
if (BX_CIRRUS_THIS pci_enabled) {
bx_pci_device_c::after_restore_pci_state(cirrus_mem_read_handler);
if (DEV_pci_set_base_mem(BX_CIRRUS_THIS_PTR, cirrus_mem_read_handler,
cirrus_mem_write_handler,
&BX_CIRRUS_THIS pci_base_address[0],
&BX_CIRRUS_THIS pci_conf[0x10],
0x2000000)) {
BX_INFO(("new pci_memaddr: 0x%04x", BX_CIRRUS_THIS pci_base_address[0]));
}
if (DEV_pci_set_base_mem(BX_CIRRUS_THIS_PTR, cirrus_mem_read_handler,
cirrus_mem_write_handler,
&BX_CIRRUS_THIS pci_base_address[1],
&BX_CIRRUS_THIS pci_conf[0x14],
CIRRUS_PNPMMIO_SIZE)) {
BX_INFO(("new pci_mmioaddr = 0x%08x", BX_CIRRUS_THIS pci_base_address[1]));
}
}
#endif
if ((BX_CIRRUS_THIS sequencer.reg[0x07] & 0x01) == CIRRUS_SR7_BPP_VGA) {
@ -554,8 +540,8 @@ Bit8u bx_svga_cirrus_c::mem_read(bx_phy_address addr)
#if BX_SUPPORT_PCI
if (BX_CIRRUS_THIS pci_enabled) {
if ((addr >= BX_CIRRUS_THIS pci_base_address[0]) &&
(addr < (BX_CIRRUS_THIS pci_base_address[0] + CIRRUS_PNPMEM_SIZE))) {
if ((addr >= BX_CIRRUS_THIS pci_bar[0].addr) &&
(addr < (BX_CIRRUS_THIS pci_bar[0].addr + CIRRUS_PNPMEM_SIZE))) {
Bit8u *ptr;
Bit32u offset = addr & BX_CIRRUS_THIS memsize_mask;
@ -586,8 +572,8 @@ Bit8u bx_svga_cirrus_c::mem_read(bx_phy_address addr)
}
offset &= BX_CIRRUS_THIS memsize_mask;
return *(ptr + offset);
} else if ((addr >= BX_CIRRUS_THIS pci_base_address[1]) &&
(addr < (BX_CIRRUS_THIS pci_base_address[1] + CIRRUS_PNPMMIO_SIZE))) {
} else if ((addr >= BX_CIRRUS_THIS pci_bar[1].addr) &&
(addr < (BX_CIRRUS_THIS pci_bar[1].addr + CIRRUS_PNPMMIO_SIZE))) {
Bit32u offset = addr & (CIRRUS_PNPMMIO_SIZE - 1);
if (offset >= 0x100) {
@ -681,8 +667,8 @@ void bx_svga_cirrus_c::mem_write(bx_phy_address addr, Bit8u value)
#if BX_SUPPORT_PCI
if (BX_CIRRUS_THIS pci_enabled) {
if ((addr >= BX_CIRRUS_THIS pci_base_address[0]) &&
(addr < (BX_CIRRUS_THIS pci_base_address[0] + CIRRUS_PNPMEM_SIZE))) {
if ((addr >= BX_CIRRUS_THIS pci_bar[0].addr) &&
(addr < (BX_CIRRUS_THIS pci_bar[0].addr + CIRRUS_PNPMEM_SIZE))) {
Bit32u offset = addr & BX_CIRRUS_THIS memsize_mask;
if ((offset >= (BX_CIRRUS_THIS s.memsize - 256)) &&
@ -721,8 +707,8 @@ void bx_svga_cirrus_c::mem_write(bx_phy_address addr, Bit8u value)
SET_TILE_UPDATED(BX_CIRRUS_THIS, ((offset % BX_CIRRUS_THIS svga_pitch) / (BX_CIRRUS_THIS svga_bpp / 8)) / X_TILESIZE,
(offset / BX_CIRRUS_THIS svga_pitch) / Y_TILESIZE, 1);
return;
} else if ((addr >= BX_CIRRUS_THIS pci_base_address[1]) &&
(addr < (BX_CIRRUS_THIS pci_base_address[1] + CIRRUS_PNPMMIO_SIZE))) {
} else if ((addr >= BX_CIRRUS_THIS pci_bar[1].addr) &&
(addr < (BX_CIRRUS_THIS pci_bar[1].addr + CIRRUS_PNPMMIO_SIZE))) {
// memory-mapped I/O.
// BX_DEBUG(("write mmio 0x%08x",addr));
@ -2335,9 +2321,12 @@ void bx_svga_cirrus_c::svga_init_pcihandlers(void)
BX_CIRRUS_THIS pci_conf[0x14] =
(PCI_MAP_MEM | PCI_MAP_MEMFLAGS_32BIT);
BX_CIRRUS_THIS pci_base_address[0] = 0;
BX_CIRRUS_THIS pci_base_address[1] = 0;
BX_CIRRUS_THIS init_bar_mem(0, 0x2000000, cirrus_mem_read_handler,
cirrus_mem_write_handler);
BX_CIRRUS_THIS init_bar_mem(1, CIRRUS_PNPMMIO_SIZE, cirrus_mem_read_handler,
cirrus_mem_write_handler);
BX_CIRRUS_THIS pci_rom_address = 0;
BX_CIRRUS_THIS pci_rom_read_handler = cirrus_mem_read_handler;
BX_CIRRUS_THIS load_pci_rom(SIM->get_param_string(BXPN_VGA_ROM_PATH)->getptr());
}
@ -2346,9 +2335,6 @@ void bx_svga_cirrus_c::pci_write_handler(Bit8u address, Bit32u value, unsigned i
unsigned i;
unsigned write_addr;
Bit8u new_value, old_value;
bx_bool baseaddr0_change = 0;
bx_bool baseaddr1_change = 0;
bx_bool romaddr_change = 0;
BX_DEBUG(("pci_write: address 0x%02x, io_len 0x%02x, value 0x%x",
(unsigned)address, (unsigned)io_len, (unsigned)value));
@ -2356,11 +2342,6 @@ void bx_svga_cirrus_c::pci_write_handler(Bit8u address, Bit32u value, unsigned i
if ((address > 0x17) && (address < 0x30))
return;
if (address == 0x30) {
value = value & 0xfffffc01;
romaddr_change = 1;
}
for (i = 0; i < io_len; i++) {
write_addr = address + i;
old_value = BX_CIRRUS_THIS pci_conf[write_addr];
@ -2379,16 +2360,6 @@ void bx_svga_cirrus_c::pci_write_handler(Bit8u address, Bit32u value, unsigned i
case 0x07: // status bit8-15
new_value = old_value & (~new_value);
break;
case 0x10: // base address #0
new_value = (new_value & 0xf0) | (old_value & 0x0f);
case 0x11: case 0x12: case 0x13:
baseaddr0_change |= (old_value != new_value);
break;
case 0x14: // base address #1
new_value = (new_value & 0xf0) | (old_value & 0x0f);
case 0x15: case 0x16: case 0x17:
baseaddr1_change |= (old_value != new_value);
break;
// read-only.
case 0x00: case 0x01: // vendor
@ -2405,32 +2376,6 @@ void bx_svga_cirrus_c::pci_write_handler(Bit8u address, Bit32u value, unsigned i
BX_CIRRUS_THIS pci_conf[write_addr] = new_value;
value >>= 8;
}
if (baseaddr0_change) {
if (DEV_pci_set_base_mem(BX_CIRRUS_THIS_PTR, cirrus_mem_read_handler,
cirrus_mem_write_handler,
&BX_CIRRUS_THIS pci_base_address[0],
&BX_CIRRUS_THIS pci_conf[0x10],
0x2000000)) {
BX_INFO(("new pci_memaddr: 0x%04x", BX_CIRRUS_THIS pci_base_address[0]));
}
}
if (baseaddr1_change) {
if (DEV_pci_set_base_mem(BX_CIRRUS_THIS_PTR, cirrus_mem_read_handler,
cirrus_mem_write_handler,
&BX_CIRRUS_THIS pci_base_address[1],
&BX_CIRRUS_THIS pci_conf[0x14],
CIRRUS_PNPMMIO_SIZE)) {
BX_INFO(("new pci_mmioaddr = 0x%08x", BX_CIRRUS_THIS pci_base_address[1]));
}
}
if (romaddr_change) {
if (DEV_pci_set_base_mem(BX_CIRRUS_THIS_PTR, cirrus_mem_read_handler, NULL,
&BX_CIRRUS_THIS pci_rom_address,
&BX_CIRRUS_THIS pci_conf[0x30],
BX_CIRRUS_THIS pci_rom_size)) {
BX_INFO(("new ROM address: 0x%08x", BX_CIRRUS_THIS pci_rom_address));
}
}
}
#endif // BX_SUPPORT_PCI

View File

@ -154,9 +154,11 @@ bx_bool bx_vga_c::init_vga_extension(void)
if (BX_VGA_THIS vbe_present) {
BX_VGA_THIS pci_conf[0x10] = 0x08;
BX_VGA_THIS pci_base_address[0] = 0;
BX_VGA_THIS init_bar_mem(0, VBE_DISPI_TOTAL_VIDEO_MEMORY_BYTES,
mem_read_handler, mem_write_handler);
}
BX_VGA_THIS pci_rom_address = 0;
BX_VGA_THIS pci_rom_read_handler = mem_read_handler;
BX_VGA_THIS load_pci_rom(SIM->get_param_string(BXPN_VGA_ROM_PATH)->getptr());
}
#endif
@ -224,12 +226,6 @@ void bx_vga_c::after_restore_state(void)
#if BX_SUPPORT_PCI
if (BX_VGA_THIS pci_enabled) {
bx_pci_device_c::after_restore_pci_state(mem_read_handler);
if (BX_VGA_THIS vbe_present) {
if (BX_VGA_THIS vbe_set_base_addr(&BX_VGA_THIS pci_base_address[0],
&BX_VGA_THIS pci_conf[0x10])) {
BX_INFO(("new base address: 0x%08x", BX_VGA_THIS pci_base_address[0]));
}
}
}
#endif
if (BX_VGA_THIS vbe.enabled) {
@ -743,15 +739,9 @@ void bx_vga_c::redraw_area(unsigned x0, unsigned y0, unsigned width,
}
#if BX_SUPPORT_PCI
bx_bool bx_vga_c::vbe_set_base_addr(Bit32u *addr, Bit8u *pci_conf)
void bx_vga_c::pci_bar_change_notify(void)
{
if (DEV_pci_set_base_mem(BX_VGA_THIS_PTR, mem_read_handler,
mem_write_handler,
addr, pci_conf, VBE_DISPI_TOTAL_VIDEO_MEMORY_BYTES)) {
BX_VGA_THIS vbe.base_address = *addr;
return 1;
}
return 0;
BX_VGA_THIS vbe.base_address = pci_bar[0].addr;
}
#endif
@ -1304,8 +1294,6 @@ Bit32u bx_vga_c::vbe_write(Bit32u address, Bit32u value, unsigned io_len)
// static pci configuration space write callback handler
void bx_vga_c::pci_write_handler(Bit8u address, Bit32u value, unsigned io_len)
{
bx_bool baseaddr_change = 0, romaddr_change = 0;
if (io_len == 1)
BX_DEBUG(("write PCI register 0x%02x value 0x%02x", address, value));
else if (io_len == 2)
@ -1316,11 +1304,6 @@ void bx_vga_c::pci_write_handler(Bit8u address, Bit32u value, unsigned io_len)
if ((address >= 0x14) && (address < 0x30))
return;
if (address == 0x30) {
value = value & 0xfffffc01;
romaddr_change = 1;
}
for (unsigned i = 0; i < io_len; i++) {
unsigned write_addr = address + i;
Bit8u old_value = BX_VGA_THIS pci_conf[write_addr];
@ -1329,34 +1312,12 @@ void bx_vga_c::pci_write_handler(Bit8u address, Bit32u value, unsigned io_len)
case 0x04: // disallowing write to command
case 0x06: // disallowing write to status lo-byte (is that expected?)
break;
case 0x10: // base address #0
new_value = (new_value & 0xf0) | (old_value & 0x0f);
case 0x11: case 0x12: case 0x13:
if (BX_VGA_THIS vbe_present) {
baseaddr_change |= (old_value != new_value);
} else {
break;
}
default:
BX_VGA_THIS pci_conf[write_addr] = new_value;
}
value >>= 8;
}
if (baseaddr_change) {
if (BX_VGA_THIS vbe_set_base_addr(&BX_VGA_THIS pci_base_address[0],
&BX_VGA_THIS pci_conf[0x10])) {
BX_INFO(("new base address: 0x%08x", BX_VGA_THIS pci_base_address[0]));
}
}
if (romaddr_change) {
if (DEV_pci_set_base_mem(this, mem_read_handler, NULL,
&BX_VGA_THIS pci_rom_address,
&BX_VGA_THIS pci_conf[0x30],
BX_VGA_THIS pci_rom_size)) {
BX_INFO(("new ROM address: 0x%08x", BX_VGA_THIS pci_rom_address));
}
}
}
#endif

View File

@ -109,6 +109,7 @@ public:
#if BX_SUPPORT_PCI
virtual void pci_write_handler(Bit8u address, Bit32u value, unsigned io_len);
virtual void pci_bar_change_notify(void);
#endif
#if BX_DEBUGGER
virtual void debug_dump(int argc, char **argv);
@ -124,10 +125,6 @@ protected:
virtual void update(void);
// Bochs VBE section
#if BX_SUPPORT_PCI
virtual bx_bool vbe_set_base_addr(Bit32u *addr, Bit8u *pci_conf);
#endif
BX_VGA_SMF Bit8u vbe_mem_read(bx_phy_address addr) BX_CPP_AttrRegparmN(1);
BX_VGA_SMF void vbe_mem_write(bx_phy_address addr, Bit8u value) BX_CPP_AttrRegparmN(2);

View File

@ -851,7 +851,7 @@ void bx_voodoo_1_2_c::init_model(void)
pci_conf[0x10] = 0x08;
}
pci_conf[0x3d] = BX_PCI_INTA;
pci_base_address[0] = 0;
init_bar_mem(0, 0x1000000, mem_read_handler, mem_write_handler);
s.vdraw.clock_enabled = 1;
s.vdraw.output_on = 0;
s.vdraw.override_on = 0;
@ -913,12 +913,7 @@ void bx_voodoo_1_2_c::register_state(void)
void bx_voodoo_1_2_c::after_restore_state(void)
{
if (DEV_pci_set_base_mem(BX_VOODOO_THIS_PTR, mem_read_handler, mem_write_handler,
&pci_base_address[0],
&pci_conf[0x10],
0x1000000)) {
BX_INFO(("new mem base address: 0x%08x", pci_base_address[0]));
}
bx_pci_device_c::after_restore_pci_state(NULL);
if (s.vdraw.override_on) {
// force update
v->fbi.video_changed = 1;
@ -1065,7 +1060,6 @@ void bx_voodoo_1_2_c::update_screen_start(void)
void bx_voodoo_1_2_c::pci_write_handler(Bit8u address, Bit32u value, unsigned io_len)
{
Bit8u value8, oldval;
bx_bool baseaddr_change = 0;
if ((address >= 0x14) && (address < 0x34))
return;
@ -1082,13 +1076,6 @@ void bx_voodoo_1_2_c::pci_write_handler(Bit8u address, Bit32u value, unsigned io
BX_INFO(("new irq line = %d", value8));
}
break;
case 0x10:
value8 = (value8 & 0xf0) | (oldval & 0x0f);
case 0x11:
case 0x12:
case 0x13:
baseaddr_change |= (value8 != oldval);
break;
case 0x40:
case 0x41:
case 0x42:
@ -1120,14 +1107,6 @@ void bx_voodoo_1_2_c::pci_write_handler(Bit8u address, Bit32u value, unsigned io
}
pci_conf[address+i] = value8;
}
if (baseaddr_change) {
if (DEV_pci_set_base_mem(BX_VOODOO_THIS_PTR, mem_read_handler, mem_write_handler,
&pci_base_address[0],
&pci_conf[0x10],
0x1000000)) {
BX_INFO(("new mem base address: 0x%08x", pci_base_address[0]));
}
}
if (io_len == 1)
BX_DEBUG(("write PCI register 0x%02x value 0x%02x", address, value));

View File

@ -2,7 +2,7 @@
// $Id$
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001-2017 The Bochs Project
// Copyright (C) 2001-2018 The Bochs Project
//
// I/O port handlers API Copyright (C) 2003 by Frank Cornelis
//
@ -87,27 +87,61 @@ class cdrom_base_c;
//////////////////////////////////////////////////////////////////////
#if BX_SUPPORT_PCI
#define BX_PCI_BAR_TYPE_NONE 0
#define BX_PCI_BAR_TYPE_MEM 1
#define BX_PCI_BAR_TYPE_IO 2
typedef struct {
Bit8u type;
Bit32u size;
Bit32u addr;
union {
struct {
memory_handler_t rh;
memory_handler_t wh;
const Bit8u *dummy;
} mem;
struct {
bx_read_handler_t rh;
bx_write_handler_t wh;
const Bit8u *mask;
} io;
};
} bx_pci_bar_t;
class BOCHSAPI bx_pci_device_c : public bx_devmodel_c {
public:
bx_pci_device_c(): pci_rom(NULL), pci_rom_size(0) {}
bx_pci_device_c(): pci_rom(NULL), pci_rom_size(0) {
for (int i = 0; i < 6; i++) pci_bar[i].type = BX_PCI_BAR_TYPE_NONE;
}
virtual ~bx_pci_device_c() {
if (pci_rom != NULL) delete [] pci_rom;
}
virtual Bit32u pci_read_handler(Bit8u address, unsigned io_len);
void pci_write_handler_common(Bit8u address, Bit32u value, unsigned io_len);
virtual void pci_write_handler(Bit8u address, Bit32u value, unsigned io_len) {}
virtual void pci_bar_change_notify(void) {}
void init_pci_conf(Bit16u vid, Bit16u did, Bit8u rev, Bit32u classc, Bit8u headt);
void init_bar_io(Bit8u num, Bit16u size, bx_read_handler_t rh,
bx_write_handler_t wh, const Bit8u *mask);
void init_bar_mem(Bit8u num, Bit32u size, memory_handler_t rh, memory_handler_t wh);
void register_pci_state(bx_list_c *list);
void after_restore_pci_state(memory_handler_t mem_read_handler);
void load_pci_rom(const char *path);
void set_name(const char *name) {pci_name = name;}
protected:
const char *pci_name;
Bit8u pci_conf[256];
Bit32u pci_base_address[6];
bx_pci_bar_t pci_bar[6];
Bit8u *pci_rom;
Bit32u pci_rom_address;
Bit32u pci_rom_size;
memory_handler_t pci_rom_read_handler;
};
#endif

View File

@ -12,7 +12,7 @@
// Copyright (c) 2007 Dan Aloni
// Copyright (c) 2004 Antony T Curtis
//
// Copyright (C) 2011-2017 The Bochs Project
// Copyright (C) 2011-2018 The Bochs Project
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@ -463,9 +463,10 @@ void bx_e1000_c::init(void)
init_pci_conf(0x8086, 0x100e, 0x03, 0x020000, 0x00);
BX_E1000_THIS pci_conf[0x3d] = BX_PCI_INTA;
BX_E1000_THIS pci_base_address[0] = 0;
BX_E1000_THIS pci_base_address[1] = 0;
BX_E1000_THIS init_bar_mem(0, 0x20000, mem_read_handler, mem_write_handler);
BX_E1000_THIS init_bar_io(1, 64, read_handler, write_handler, &e1000_iomask[0]);
BX_E1000_THIS pci_rom_address = 0;
BX_E1000_THIS pci_rom_read_handler = mem_read_handler;
bootrom = SIM->get_param_string("bootrom", base);
if (!bootrom->isempty()) {
BX_E1000_THIS load_pci_rom(bootrom->getptr());
@ -596,18 +597,6 @@ void bx_e1000_c::register_state(void)
void bx_e1000_c::after_restore_state(void)
{
bx_pci_device_c::after_restore_pci_state(mem_read_handler);
if (DEV_pci_set_base_mem(BX_E1000_THIS_PTR, mem_read_handler, mem_write_handler,
&BX_E1000_THIS pci_base_address[0],
&BX_E1000_THIS pci_conf[0x10],
0x20000)) {
BX_INFO(("new mem base address: 0x%08x", BX_E1000_THIS pci_base_address[0]));
}
if (DEV_pci_set_base_io(BX_E1000_THIS_PTR, read_handler, write_handler,
&BX_E1000_THIS pci_base_address[1],
&BX_E1000_THIS pci_conf[0x14],
64, &e1000_iomask[0], "e1000")) {
BX_INFO(("new i/o base address: 0x%04x", BX_E1000_THIS pci_base_address[1]));
}
}
bx_bool bx_e1000_c::mem_read_handler(bx_phy_address addr, unsigned len,
@ -826,7 +815,7 @@ Bit32u bx_e1000_c::read(Bit32u address, unsigned io_len)
#endif // !BX_USE_E1000_SMF
Bit8u offset;
offset = address - BX_E1000_THIS pci_base_address[1];
offset = address - BX_E1000_THIS pci_bar[1].addr;
BX_ERROR(("register read from offset 0x%02x returns 0", offset));
@ -851,7 +840,7 @@ void bx_e1000_c::write(Bit32u address, Bit32u value, unsigned io_len)
#endif // !BX_USE_E1000_SMF
Bit8u offset;
offset = address - BX_E1000_THIS pci_base_address[1];
offset = address - BX_E1000_THIS pci_bar[1].addr;
BX_ERROR(("register write to offset 0x%02x ignored - value = 0x%08x", offset, value));
}
@ -1464,9 +1453,6 @@ void bx_e1000_c::rx_frame(const void *buf, unsigned buf_size)
void bx_e1000_c::pci_write_handler(Bit8u address, Bit32u value, unsigned io_len)
{
Bit8u value8, oldval;
bx_bool baseaddr0_change = 0;
bx_bool baseaddr1_change = 0;
bx_bool romaddr_change = 0;
if ((address >= 0x18) && (address < 0x30))
return;
@ -1483,62 +1469,11 @@ void bx_e1000_c::pci_write_handler(Bit8u address, Bit32u value, unsigned io_len)
BX_INFO(("new irq line = %d", value8));
}
break;
case 0x10:
value8 = (value8 & 0xf0) | (oldval & 0x0f);
case 0x11:
case 0x12:
case 0x13:
baseaddr0_change |= (value8 != oldval);
break;
case 0x14:
value8 = (value8 & 0xf0) | (oldval & 0x0f);
case 0x15:
case 0x16:
case 0x17:
baseaddr1_change |= (value8 != oldval);
break;
case 0x30:
case 0x31:
case 0x32:
case 0x33:
if (BX_E1000_THIS pci_rom_size > 0) {
if ((address+i) == 0x30) {
value8 &= 0x01;
} else if ((address+i) == 0x31) {
value8 &= 0xfc;
}
romaddr_change = 1;
break;
}
default:
value8 = oldval;
}
BX_E1000_THIS pci_conf[address+i] = value8;
}
if (baseaddr0_change) {
if (DEV_pci_set_base_mem(BX_E1000_THIS_PTR, mem_read_handler, mem_write_handler,
&BX_E1000_THIS pci_base_address[0],
&BX_E1000_THIS pci_conf[0x10],
0x20000)) {
BX_INFO(("new mem base address: 0x%08x", BX_E1000_THIS pci_base_address[0]));
}
}
if (baseaddr1_change) {
if (DEV_pci_set_base_io(BX_E1000_THIS_PTR, read_handler, write_handler,
&BX_E1000_THIS pci_base_address[1],
&BX_E1000_THIS pci_conf[0x14],
64, &e1000_iomask[0], "e1000")) {
BX_INFO(("new i/o base address: 0x%04x", BX_E1000_THIS pci_base_address[1]));
}
}
if (romaddr_change) {
if (DEV_pci_set_base_mem(BX_E1000_THIS_PTR, mem_read_handler, NULL,
&BX_E1000_THIS pci_rom_address,
&BX_E1000_THIS pci_conf[0x30],
BX_E1000_THIS pci_rom_size)) {
BX_INFO(("new ROM address: 0x%08x", BX_E1000_THIS pci_rom_address));
}
}
if (io_len == 1)
BX_DEBUG(("write PCI register 0x%02x value 0x%02x", address, value));

View File

@ -204,8 +204,10 @@ void bx_ne2k_c::init(void)
BX_NE2K_THIS pci_conf[0x07] = 0x02;
BX_NE2K_THIS pci_conf[0x10] = 0x01;
BX_NE2K_THIS pci_conf[0x3d] = BX_PCI_INTA;
init_bar_io(0, 32, read_handler, write_handler, &ne2k_iomask[0]);
BX_NE2K_THIS s.base_address = 0x0;
BX_NE2K_THIS pci_rom_address = 0;
BX_NE2K_THIS pci_rom_read_handler = mem_read_handler;
bootrom = SIM->get_param_string("bootrom", base);
if (!bootrom->isempty()) {
BX_NE2K_THIS load_pci_rom(bootrom->getptr());
@ -441,12 +443,6 @@ void bx_ne2k_c::after_restore_state(void)
{
if (BX_NE2K_THIS s.pci_enabled) {
bx_pci_device_c::after_restore_pci_state(mem_read_handler);
if (DEV_pci_set_base_io(BX_NE2K_THIS_PTR, read_handler, write_handler,
&BX_NE2K_THIS s.base_address,
&BX_NE2K_THIS pci_conf[0x10],
32, &ne2k_iomask[0], "NE2000 PCI NIC")) {
BX_INFO(("new base address: 0x%04x", BX_NE2K_THIS s.base_address));
}
}
}
#endif
@ -1694,8 +1690,6 @@ void bx_ne2k_c::set_irq_level(bx_bool level)
void bx_ne2k_c::pci_write_handler(Bit8u address, Bit32u value, unsigned io_len)
{
Bit8u value8, oldval;
bx_bool baseaddr_change = 0;
bx_bool romaddr_change = 0;
if ((address > 0x13) && (address < 0x30))
return;
@ -1712,47 +1706,11 @@ void bx_ne2k_c::pci_write_handler(Bit8u address, Bit32u value, unsigned io_len)
BX_INFO(("new irq line = %d", value8));
}
break;
case 0x10:
value8 = (value8 & 0xfc) | 0x01;
case 0x11:
case 0x12:
case 0x13:
baseaddr_change |= (value8 != oldval);
break;
case 0x30:
case 0x31:
case 0x32:
case 0x33:
if (BX_NE2K_THIS pci_rom_size > 0) {
if ((address+i) == 0x30) {
value8 &= 0x01;
} else if ((address+i) == 0x31) {
value8 &= 0xfc;
}
romaddr_change = 1;
break;
}
default:
value8 = oldval;
}
BX_NE2K_THIS pci_conf[address+i] = value8;
}
if (baseaddr_change) {
if (DEV_pci_set_base_io(BX_NE2K_THIS_PTR, read_handler, write_handler,
&BX_NE2K_THIS s.base_address,
&BX_NE2K_THIS pci_conf[0x10],
32, &ne2k_iomask[0], "NE2000 PCI NIC")) {
BX_INFO(("new base address: 0x%04x", BX_NE2K_THIS s.base_address));
}
}
if (romaddr_change) {
if (DEV_pci_set_base_mem(BX_NE2K_THIS_PTR, mem_read_handler, NULL,
&BX_NE2K_THIS pci_rom_address,
&BX_NE2K_THIS pci_conf[0x30],
BX_NE2K_THIS pci_rom_size)) {
BX_INFO(("new ROM address: 0x%08x", BX_NE2K_THIS pci_rom_address));
}
}
if (io_len == 1)
BX_DEBUG(("write PCI register 0x%02x value 0x%02x", address, value));
@ -1761,6 +1719,11 @@ void bx_ne2k_c::pci_write_handler(Bit8u address, Bit32u value, unsigned io_len)
else if (io_len == 4)
BX_DEBUG(("write PCI register 0x%02x value 0x%08x", address, value));
}
void bx_ne2k_c::pci_bar_change_notify(void)
{
BX_NE2K_THIS s.base_address = pci_bar[0].addr;
}
#endif /* BX_SUPPORT_PCI */
#if BX_DEBUGGER

View File

@ -2,7 +2,7 @@
// $Id$
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001-2017 The Bochs Project
// Copyright (C) 2001-2018 The Bochs Project
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@ -218,7 +218,8 @@ public:
#endif
#if BX_SUPPORT_PCI
virtual void pci_write_handler(Bit8u address, Bit32u value, unsigned io_len);
virtual void pci_write_handler(Bit8u address, Bit32u value, unsigned io_len);
virtual void pci_bar_change_notify(void);
#endif
private:

View File

@ -3,7 +3,7 @@
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2003 Fen Systems Ltd. (http://www.fensystems.co.uk/)
// Copyright (C) 2003-2017 The Bochs Project
// Copyright (C) 2003-2018 The Bochs Project
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@ -164,8 +164,9 @@ void bx_pcipnic_c::init(void)
// Attach to the selected ethernet module
BX_PNIC_THIS ethdev = DEV_net_init_module(base, rx_handler, rx_status_handler, this);
BX_PNIC_THIS pci_base_address[4] = 0;
BX_PNIC_THIS init_bar_io(4, 16, read_handler, write_handler, &pnic_iomask[0]);
BX_PNIC_THIS pci_rom_address = 0;
BX_PNIC_THIS pci_rom_read_handler = mem_read_handler;
bootrom = SIM->get_param_string("bootrom", base);
if (!bootrom->isempty()) {
BX_PNIC_THIS load_pci_rom(bootrom->getptr());
@ -235,12 +236,6 @@ void bx_pcipnic_c::register_state(void)
void bx_pcipnic_c::after_restore_state(void)
{
bx_pci_device_c::after_restore_pci_state(mem_read_handler);
if (DEV_pci_set_base_io(BX_PNIC_THIS_PTR, read_handler, write_handler,
&BX_PNIC_THIS pci_base_address[4],
&BX_PNIC_THIS pci_conf[0x20],
16, &pnic_iomask[0], "PNIC")) {
BX_INFO(("new base address: 0x%04x", BX_PNIC_THIS pci_base_address[4]));
}
}
void bx_pcipnic_c::set_irq_level(bx_bool level)
@ -295,7 +290,7 @@ Bit32u bx_pcipnic_c::read(Bit32u address, unsigned io_len)
BX_DEBUG(("register read from address 0x%04x - ", (unsigned) address));
offset = address - BX_PNIC_THIS pci_base_address[4];
offset = address - BX_PNIC_THIS pci_bar[4].addr;
switch (offset) {
case PNIC_REG_STAT:
@ -344,7 +339,7 @@ void bx_pcipnic_c::write(Bit32u address, Bit32u value, unsigned io_len)
BX_DEBUG(("register write to address 0x%04x - ", (unsigned) address));
offset = address - BX_PNIC_THIS pci_base_address[4];
offset = address - BX_PNIC_THIS pci_bar[4].addr;
switch (offset) {
case PNIC_REG_CMD:
@ -390,8 +385,6 @@ void bx_pcipnic_c::pnic_timer(void)
void bx_pcipnic_c::pci_write_handler(Bit8u address, Bit32u value, unsigned io_len)
{
Bit8u value8, oldval;
bx_bool baseaddr_change = 0;
bx_bool romaddr_change = 0;
if (((address >= 0x10) && (address < 0x20)) ||
((address > 0x23) && (address < 0x30)))
@ -409,47 +402,11 @@ void bx_pcipnic_c::pci_write_handler(Bit8u address, Bit32u value, unsigned io_le
BX_INFO(("new irq line = %d", value8));
}
break;
case 0x20:
value8 = (value8 & 0xfc) | 0x01;
case 0x21:
case 0x22:
case 0x23:
baseaddr_change = (value8 != oldval);
break;
case 0x30:
case 0x31:
case 0x32:
case 0x33:
if (BX_PNIC_THIS pci_rom_size > 0) {
if ((address+i) == 0x30) {
value8 &= 0x01;
} else if ((address+i) == 0x31) {
value8 &= 0xfc;
}
romaddr_change = 1;
break;
}
default:
value8 = oldval;
}
BX_PNIC_THIS pci_conf[address+i] = value8;
}
if (baseaddr_change) {
if (DEV_pci_set_base_io(BX_PNIC_THIS_PTR, read_handler, write_handler,
&BX_PNIC_THIS pci_base_address[4],
&BX_PNIC_THIS pci_conf[0x20],
16, &pnic_iomask[0], "PNIC")) {
BX_INFO(("new base address: 0x%04x", BX_PNIC_THIS pci_base_address[4]));
}
}
if (romaddr_change) {
if (DEV_pci_set_base_mem(BX_PNIC_THIS_PTR, mem_read_handler, NULL,
&BX_PNIC_THIS pci_rom_address,
&BX_PNIC_THIS pci_conf[0x30],
BX_PNIC_THIS pci_rom_size)) {
BX_INFO(("new ROM address: 0x%08x", BX_PNIC_THIS pci_rom_address));
}
}
if (io_len == 1)
BX_DEBUG(("write PCI register 0x%02x value 0x%02x", address, value));

View File

@ -2,7 +2,7 @@
// $Id$
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2004-2017 The Bochs Project
// Copyright (C) 2004-2018 The Bochs Project
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@ -101,8 +101,7 @@ void bx_pci_ide_c::init(void)
} else {
init_pci_conf(0x8086, 0x1230, 0x00, 0x010180, 0x00);
}
BX_PIDE_THIS pci_conf[0x20] = 0x01;
BX_PIDE_THIS pci_base_address[4] = 0;
BX_PIDE_THIS init_bar_io(4, 16, read_handler, write_handler, &bmdma_iomask[0]);
}
void bx_pci_ide_c::reset(unsigned type)
@ -161,12 +160,7 @@ void bx_pci_ide_c::register_state(void)
void bx_pci_ide_c::after_restore_state(void)
{
if (DEV_pci_set_base_io(BX_PIDE_THIS_PTR, read_handler, write_handler,
&BX_PIDE_THIS pci_base_address[4], &BX_PIDE_THIS pci_conf[0x20],
16, &bmdma_iomask[0], "PIIX3 PCI IDE controller"))
{
BX_INFO(("new BM-DMA address: 0x%04x", BX_PIDE_THIS pci_base_address[4]));
}
bx_pci_device_c::after_restore_pci_state(NULL);
}
Bit64s bx_pci_ide_c::param_save_handler(void *devptr, bx_param_c *param)
@ -214,7 +208,7 @@ void bx_pci_ide_c::param_restore(bx_param_c *param, Bit64s val)
bx_bool bx_pci_ide_c::bmdma_present(void)
{
return (BX_PIDE_THIS pci_base_address[4] > 0);
return (BX_PIDE_THIS pci_bar[4].addr > 0);
}
void bx_pci_ide_c::bmdma_start_transfer(Bit8u channel)
@ -343,7 +337,7 @@ Bit32u bx_pci_ide_c::read(Bit32u address, unsigned io_len)
Bit8u offset, channel;
Bit32u value = 0xffffffff;
offset = address - BX_PIDE_THIS pci_base_address[4];
offset = address - BX_PIDE_THIS pci_bar[4].addr;
channel = (offset >> 3);
offset &= 0x07;
switch (offset) {
@ -384,7 +378,7 @@ void bx_pci_ide_c::write(Bit32u address, Bit32u value, unsigned io_len)
#endif // !BX_USE_PIDE_SMF
Bit8u offset, channel;
offset = address - BX_PIDE_THIS pci_base_address[4];
offset = address - BX_PIDE_THIS pci_bar[4].addr;
channel = (offset >> 3);
offset &= 0x07;
switch (offset) {
@ -422,7 +416,6 @@ void bx_pci_ide_c::write(Bit32u address, Bit32u value, unsigned io_len)
void bx_pci_ide_c::pci_write_handler(Bit8u address, Bit32u value, unsigned io_len)
{
Bit8u value8, oldval;
bx_bool bmdma_change = 0;
if (((address >= 0x10) && (address < 0x20)) ||
((address > 0x23) && (address < 0x40)))
@ -437,25 +430,12 @@ void bx_pci_ide_c::pci_write_handler(Bit8u address, Bit32u value, unsigned io_le
case 0x04:
BX_PIDE_THIS pci_conf[address+i] = value8 & 0x05;
break;
case 0x20:
value8 = (value8 & 0xfc) | 0x01;
case 0x21:
case 0x22:
case 0x23:
bmdma_change |= (value8 != oldval);
default:
BX_PIDE_THIS pci_conf[address+i] = value8;
BX_DEBUG(("PIIX3 PCI IDE write register 0x%02x value 0x%02x", address+i,
value8));
}
}
if (bmdma_change) {
if (DEV_pci_set_base_io(BX_PIDE_THIS_PTR, read_handler, write_handler,
&BX_PIDE_THIS pci_base_address[4], &BX_PIDE_THIS pci_conf[0x20],
16, &bmdma_iomask[0], "PIIX3 PCI IDE controller")) {
BX_INFO(("new BM-DMA address: 0x%04x", BX_PIDE_THIS pci_base_address[4]));
}
}
}
#endif /* BX_SUPPORT_PCI */

View File

@ -5,7 +5,7 @@
// ES1370 soundcard support (ported from QEMU)
//
// Copyright (c) 2005 Vassili Karpov (malc)
// Copyright (C) 2011-2017 The Bochs Project
// Copyright (C) 2011-2018 The Bochs Project
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
@ -256,7 +256,7 @@ void bx_es1370_c::init(void)
init_pci_conf(0x1274, 0x5000, 0x00, 0x040100, 0x00);
BX_ES1370_THIS pci_conf[0x3d] = BX_PCI_INTA;
BX_ES1370_THIS pci_base_address[0] = 0;
BX_ES1370_THIS init_bar_io(0, 64, read_handler, write_handler, &es1370_iomask[0]);
BX_ES1370_THIS wavemode = SIM->get_param_enum("wavemode", base)->get();
BX_ES1370_THIS midimode = SIM->get_param_enum("midimode", base)->get();
@ -420,12 +420,7 @@ void bx_es1370_c::register_state(void)
void bx_es1370_c::after_restore_state(void)
{
if (DEV_pci_set_base_io(BX_ES1370_THIS_PTR, read_handler, write_handler,
&BX_ES1370_THIS pci_base_address[0],
&BX_ES1370_THIS pci_conf[0x10],
64, &es1370_iomask[0], "ES1370")) {
BX_INFO(("new base address: 0x%04x", BX_ES1370_THIS pci_base_address[0]));
}
bx_pci_device_c::after_restore_pci_state(NULL);
BX_ES1370_THIS check_lower_irq(BX_ES1370_THIS s.sctl);
BX_ES1370_THIS s.adc_inputinit = 0;
BX_ES1370_THIS s.dac_nr_active = -1;
@ -496,7 +491,7 @@ Bit32u bx_es1370_c::read(Bit32u address, unsigned io_len)
BX_DEBUG(("register read from address 0x%04x - ", address));
offset = address - BX_ES1370_THIS pci_base_address[0];
offset = address - BX_ES1370_THIS pci_bar[0].addr;
if (offset >= 0x30) {
offset |= (BX_ES1370_THIS s.mempage << 8);
}
@ -608,7 +603,7 @@ void bx_es1370_c::write(Bit32u address, Bit32u value, unsigned io_len)
BX_DEBUG(("register write to address 0x%04x - value = 0x%08x", address, value));
offset = address - BX_ES1370_THIS pci_base_address[0];
offset = address - BX_ES1370_THIS pci_bar[0].addr;
if (offset >= 0x30) {
offset |= (BX_ES1370_THIS s.mempage << 8);
}
@ -1092,7 +1087,6 @@ void bx_es1370_c::closemidioutput()
void bx_es1370_c::pci_write_handler(Bit8u address, Bit32u value, unsigned io_len)
{
Bit8u value8, oldval;
bx_bool baseaddr_change = 0;
if ((address >= 0x14) && (address < 0x34))
return;
@ -1118,24 +1112,10 @@ void bx_es1370_c::pci_write_handler(Bit8u address, Bit32u value, unsigned io_len
BX_ES1370_THIS pci_conf[address+i] = value8;
}
break;
case 0x10:
value8 = (value8 & 0xfc) | 0x01;
case 0x11:
case 0x12:
case 0x13:
baseaddr_change |= (value8 != oldval);
default:
BX_ES1370_THIS pci_conf[address+i] = value8;
}
}
if (baseaddr_change) {
if (DEV_pci_set_base_io(BX_ES1370_THIS_PTR, read_handler, write_handler,
&BX_ES1370_THIS pci_base_address[0],
&BX_ES1370_THIS pci_conf[0x10],
64, &es1370_iomask[0], "ES1370")) {
BX_INFO(("new base address: 0x%04x", BX_ES1370_THIS pci_base_address[0]));
}
}
if (io_len == 1)
BX_DEBUG(("write PCI register 0x%02x value 0x%02x", address, value));

View File

@ -3,7 +3,7 @@
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2009-2017 Benjamin D Lunt (fys [at] fysnet [dot] net)
// 2009-2017 The Bochs Project
// 2009-2018 The Bochs Project
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@ -87,7 +87,7 @@ void bx_uhci_core_c::init_uhci(Bit8u devfunc, Bit16u devid, Bit8u headt, Bit8u i
// initialize readonly registers
init_pci_conf(0x8086, devid, 0x01, 0x0c0300, headt);
pci_conf[0x3d] = intp;
pci_base_address[4] = 0x0;
init_bar_io(4, 32, read_handler, write_handler, &uhci_iomask[0]);
for (int i=0; i<USB_UHCI_PORTS; i++) {
hub.usb_port[i].device = NULL;
@ -227,13 +227,7 @@ void bx_uhci_core_c::register_state(bx_list_c *parent)
void bx_uhci_core_c::after_restore_state(void)
{
if (DEV_pci_set_base_io(this, read_handler, write_handler,
&pci_base_address[4],
&pci_conf[0x20],
32, &uhci_iomask[0], "USB UHCI Hub"))
{
BX_INFO(("new base address: 0x%04x", pci_base_address[4]));
}
bx_pci_device_c::after_restore_pci_state(NULL);
for (int j=0; j<USB_UHCI_PORTS; j++) {
if (hub.usb_port[j].device != NULL) {
hub.usb_port[j].device->after_restore_state();
@ -272,7 +266,7 @@ Bit32u bx_uhci_core_c::read(Bit32u address, unsigned io_len)
Bit32u val = 0x0;
Bit8u offset,port;
offset = address - pci_base_address[4];
offset = address - pci_bar[4].addr;
switch (offset) {
case 0x00: // command register (16-bit)
@ -368,7 +362,7 @@ void bx_uhci_core_c::write(Bit32u address, Bit32u value, unsigned io_len)
BX_DEBUG(("register write to address 0x%04X: 0x%08X (%2i bits)", (unsigned) address, (unsigned) value, io_len * 8));
offset = address - pci_base_address[4];
offset = address - pci_bar[4].addr;
switch (offset) {
case 0x00: // command register (16-bit) (R/W)
@ -900,7 +894,6 @@ void bx_uhci_core_c::set_status(struct TD *td, bx_bool stalled, bx_bool data_buf
void bx_uhci_core_c::pci_write_handler(Bit8u address, Bit32u value, unsigned io_len)
{
Bit8u value8, oldval;
bx_bool baseaddr_change = 0;
if (((address >= 0x10) && (address < 0x20)) ||
((address > 0x23) && (address < 0x34)))
@ -926,24 +919,10 @@ void bx_uhci_core_c::pci_write_handler(Bit8u address, Bit32u value, unsigned io_
pci_conf[address+i] = value8;
}
break;
case 0x20:
value8 = (value8 & 0xfc) | 0x01;
case 0x21:
case 0x22:
case 0x23:
baseaddr_change |= (value8 != oldval);
default:
pci_conf[address+i] = value8;
}
}
if (baseaddr_change) {
if (DEV_pci_set_base_io(this, read_handler, write_handler,
&pci_base_address[4],
&pci_conf[0x20],
32, &uhci_iomask[0], "USB UHCI Hub")) {
BX_INFO(("new base address: 0x%04x", pci_base_address[4]));
}
}
if (io_len == 1)
BX_DEBUG(("write PCI register 0x%02x value 0x%02x", address, value));

View File

@ -4,7 +4,7 @@
//
// Experimental USB EHCI adapter (partly ported from Qemu)
//
// Copyright (C) 2015-2017 The Bochs Project
// Copyright (C) 2015-2018 The Bochs Project
//
// Copyright(c) 2008 Emutex Ltd. (address@hidden)
// Copyright(c) 2011-2012 Red Hat, Inc.
@ -248,7 +248,7 @@ void bx_usb_ehci_c::init(void)
init_pci_conf(0x8086, 0x24cd, 0x10, 0x0c0320, 0x00);
BX_EHCI_THIS pci_conf[0x3d] = BX_PCI_INTD;
BX_EHCI_THIS pci_conf[0x60] = 0x20;
BX_EHCI_THIS pci_base_address[0] = 0x0;
BX_EHCI_THIS init_bar_mem(0, IO_SPACE_SIZE, read_handler, write_handler);
for (i = 0; i < 3; i++) {
BX_EHCI_THIS uhci[i] = new bx_uhci_core_c();
@ -431,12 +431,7 @@ void bx_usb_ehci_c::after_restore_state(void)
{
int i;
if (DEV_pci_set_base_mem(BX_EHCI_THIS_PTR, read_handler, write_handler,
&BX_EHCI_THIS pci_base_address[0],
&BX_EHCI_THIS pci_conf[0x10],
256)) {
BX_INFO(("new base address: 0x%04X", BX_EHCI_THIS pci_base_address[0]));
}
bx_pci_device_c::after_restore_pci_state(NULL);
for (i=0; i<USB_EHCI_PORTS; i++) {
if (BX_EHCI_THIS hub.usb_port[i].device != NULL) {
BX_EHCI_THIS hub.usb_port[i].device->after_restore_state();
@ -650,7 +645,7 @@ bx_bool bx_usb_ehci_c::read_handler(bx_phy_address addr, unsigned len, void *dat
{
Bit32u val = 0, val_hi = 0;
int port;
const Bit32u offset = (Bit32u) (addr - BX_EHCI_THIS pci_base_address[0]);
const Bit32u offset = (Bit32u) (addr - BX_EHCI_THIS pci_bar[0].addr);
if (offset < OPS_REGS_OFFSET) {
switch (offset) {
@ -756,7 +751,7 @@ bx_bool bx_usb_ehci_c::write_handler(bx_phy_address addr, unsigned len, void *da
Bit32u value_hi = *((Bit32u *) ((Bit8u *) data + 4));
bx_bool oldcfg, oldpo, oldpr, oldfpr;
int i, port;
const Bit32u offset = (Bit32u) (addr - BX_EHCI_THIS pci_base_address[0]);
const Bit32u offset = (Bit32u) (addr - BX_EHCI_THIS pci_bar[0].addr);
// modify val and val_hi per len of data to write
switch (len) {
@ -2242,7 +2237,6 @@ void bx_usb_ehci_c::runtime_config(void)
void bx_usb_ehci_c::pci_write_handler(Bit8u address, Bit32u value, unsigned io_len)
{
Bit8u value8, oldval;
bx_bool baseaddr_change = 0;
if (((address >= 0x14) && (address <= 0x3b)) || (address > 0x80))
return;
@ -2269,14 +2263,6 @@ void bx_usb_ehci_c::pci_write_handler(Bit8u address, Bit32u value, unsigned io_l
BX_EHCI_THIS pci_conf[address+i] = value8;
}
break;
case 0x10: // low 8 bits of BAR are R/O
value8 = 0x00;
case 0x11:
case 0x12:
case 0x13:
baseaddr_change |= (value8 != oldval);
BX_EHCI_THIS pci_conf[address+i] = value8;
break;
case 0x2c:
case 0x2d:
case 0x2e:
@ -2291,14 +2277,6 @@ void bx_usb_ehci_c::pci_write_handler(Bit8u address, Bit32u value, unsigned io_l
BX_EHCI_THIS pci_conf[address+i] = value8;
}
}
if (baseaddr_change) {
if (DEV_pci_set_base_mem(BX_EHCI_THIS_PTR, read_handler, write_handler,
&BX_EHCI_THIS pci_base_address[0],
&BX_EHCI_THIS pci_conf[0x10],
IO_SPACE_SIZE)) {
BX_INFO(("new base address: 0x%08x", BX_EHCI_THIS pci_base_address[0]));
}
}
if (io_len == 1)
BX_DEBUG(("write PCI register 0x%02X value 0x%02X (len=1)", address, value));

View File

@ -3,7 +3,7 @@
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2009-2016 Benjamin D Lunt (fys [at] fysnet [dot] net)
// 2009-2017 The Bochs Project
// 2009-2018 The Bochs Project
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@ -183,7 +183,7 @@ void bx_usb_ohci_c::init(void)
// initialize readonly registers
init_pci_conf(0x11c1, 0x5803, 0x11, 0x0c0310, 0x00);
BX_OHCI_THIS pci_base_address[0] = 0x0;
BX_OHCI_THIS init_bar_mem(0, 4096, read_handler, write_handler);
BX_OHCI_THIS hub.ohci_done_count = 7;
BX_OHCI_THIS hub.use_control_head = 0;
BX_OHCI_THIS hub.use_bulk_head = 0;
@ -476,12 +476,7 @@ void bx_usb_ohci_c::register_state(void)
void bx_usb_ohci_c::after_restore_state(void)
{
if (DEV_pci_set_base_mem(BX_OHCI_THIS_PTR, read_handler, write_handler,
&BX_OHCI_THIS pci_base_address[0],
&BX_OHCI_THIS pci_conf[0x10],
4096)) {
BX_INFO(("new base address: 0x%04x", BX_OHCI_THIS pci_base_address[0]));
}
bx_pci_device_c::after_restore_pci_state(NULL);
for (int j=0; j<USB_OHCI_PORTS; j++) {
if (BX_OHCI_THIS hub.usb_port[j].device != NULL) {
BX_OHCI_THIS hub.usb_port[j].device->after_restore_state();
@ -551,7 +546,7 @@ bx_bool bx_usb_ohci_c::read_handler(bx_phy_address addr, unsigned len, void *dat
return 1;
}
Bit32u offset = (Bit32u)(addr - BX_OHCI_THIS pci_base_address[0]);
Bit32u offset = (Bit32u)(addr - BX_OHCI_THIS pci_bar[0].addr);
switch (offset) {
case 0x00: // HcRevision
val = BX_OHCI_THIS hub.op_regs.HcRevision;
@ -721,7 +716,7 @@ bx_bool bx_usb_ohci_c::read_handler(bx_phy_address addr, unsigned len, void *dat
bx_bool bx_usb_ohci_c::write_handler(bx_phy_address addr, unsigned len, void *data, void *param)
{
Bit32u value = *((Bit32u *) data);
Bit32u offset = (Bit32u)addr - BX_OHCI_THIS pci_base_address[0];
Bit32u offset = (Bit32u)addr - BX_OHCI_THIS pci_bar[0].addr;
int p, org_state;
int name = offset >> 2;
@ -1441,7 +1436,6 @@ void bx_usb_ohci_c::runtime_config(void)
void bx_usb_ohci_c::pci_write_handler(Bit8u address, Bit32u value, unsigned io_len)
{
Bit8u value8, oldval;
bx_bool baseaddr_change = 0;
if (((address >= 0x14) && (address <= 0x34)))
return;
@ -1466,25 +1460,10 @@ void bx_usb_ohci_c::pci_write_handler(Bit8u address, Bit32u value, unsigned io_l
BX_OHCI_THIS pci_conf[address+i] = value8;
}
break;
case 0x10: // low 12 bits of BAR are R/O
value8 = 0x00;
case 0x11: // low 12 bits of BAR are R/O
value8 &= 0xF0;
case 0x12:
case 0x13:
baseaddr_change |= (value8 != oldval);
default:
BX_OHCI_THIS pci_conf[address+i] = value8;
}
}
if (baseaddr_change) {
if (DEV_pci_set_base_mem(BX_OHCI_THIS_PTR, read_handler, write_handler,
&BX_OHCI_THIS pci_base_address[0],
&BX_OHCI_THIS pci_conf[0x10],
4096)) {
BX_INFO(("new base address: 0x%04x", BX_OHCI_THIS pci_base_address[0]));
}
}
if (io_len == 1)
BX_DEBUG(("write PCI register 0x%02x value 0x%02x", address, value));

View File

@ -3,7 +3,7 @@
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2010-2017 Benjamin D Lunt (fys [at] fysnet [dot] net)
// 2011-2017 The Bochs Project
// 2011-2018 The Bochs Project
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@ -269,7 +269,7 @@ void bx_usb_xhci_c::init(void)
// revision number (0x03 = uPD720201, 0x02 = uPD720202)
init_pci_conf(0x1912, 0x0015, 0x02, 0x0c0330, 0x00);
BX_XHCI_THIS pci_conf[0x3d] = BX_PCI_INTD;
BX_XHCI_THIS pci_base_address[0] = 0x0;
BX_XHCI_THIS init_bar_mem(0, IO_SPACE_SIZE, read_handler, write_handler);
// initialize capability registers
BX_XHCI_THIS hub.cap_regs.HcCapLength = (VERSION_MAJOR << 24) | (VERSION_MINOR << 16) | OPS_REGS_OFFSET;
@ -969,12 +969,7 @@ void bx_usb_xhci_c::register_state(void)
void bx_usb_xhci_c::after_restore_state(void)
{
if (DEV_pci_set_base_mem(BX_XHCI_THIS_PTR, read_handler, write_handler,
&BX_XHCI_THIS pci_base_address[0],
&BX_XHCI_THIS pci_conf[0x10],
4096)) {
BX_INFO(("new base address: 0x%04X", BX_XHCI_THIS pci_base_address[0]));
}
bx_pci_device_c::after_restore_pci_state(NULL);
for (int j=0; j<USB_XHCI_PORTS; j++) {
if (BX_XHCI_THIS hub.usb_port[j].device != NULL) {
BX_XHCI_THIS hub.usb_port[j].device->after_restore_state();
@ -1029,7 +1024,7 @@ bx_bool bx_usb_xhci_c::read_handler(bx_phy_address addr, unsigned len, void *dat
Bit32u val = 0, val_hi = 0;
int i, speed = 0;
const Bit32u offset = (Bit32u) (addr - BX_XHCI_THIS pci_base_address[0]);
const Bit32u offset = (Bit32u) (addr - BX_XHCI_THIS pci_bar[0].addr);
// Even though the controller allows reads other than 32-bits & on odd boundaries,
// we are going to ASSUME dword reads and writes unless specified below
@ -1386,7 +1381,7 @@ bx_bool bx_usb_xhci_c::write_handler(bx_phy_address addr, unsigned len, void *da
{
Bit32u value = *((Bit32u *) data);
Bit32u value_hi = *((Bit32u *) ((Bit8u *) data + 4));
const Bit32u offset = (Bit32u) (addr - BX_XHCI_THIS pci_base_address[0]);
const Bit32u offset = (Bit32u) (addr - BX_XHCI_THIS pci_bar[0].addr);
Bit32u temp;
int i;
@ -3113,7 +3108,6 @@ void bx_usb_xhci_c::runtime_config(void)
void bx_usb_xhci_c::pci_write_handler(Bit8u address, Bit32u value, unsigned io_len)
{
Bit8u value8, oldval;
bx_bool baseaddr_change = 0;
if (((address >= 0x14) && (address <= 0x34)))
return;
@ -3138,15 +3132,6 @@ void bx_usb_xhci_c::pci_write_handler(Bit8u address, Bit32u value, unsigned io_l
BX_XHCI_THIS pci_conf[address+i] = value8;
}
break;
case 0x10: // low 12 bits of BAR are R/O
value8 = 0x00;
case 0x11: // low 12 bits of BAR are R/O
value8 &= 0xF0;
case 0x12:
case 0x13:
baseaddr_change |= (value8 != oldval);
BX_XHCI_THIS pci_conf[address+i] = value8;
break;
case 0x54:
if ((((value8 & 0x03) == 0x03) && ((BX_XHCI_THIS pci_conf[address+i] & 0x03) == 0x00)) &&
(BX_XHCI_THIS hub.op_regs.HcCommand.rs || !BX_XHCI_THIS hub.op_regs.HcStatus.hch))
@ -3162,14 +3147,6 @@ void bx_usb_xhci_c::pci_write_handler(Bit8u address, Bit32u value, unsigned io_l
BX_XHCI_THIS pci_conf[address+i] = value8;
}
}
if (baseaddr_change) {
if (DEV_pci_set_base_mem(BX_XHCI_THIS_PTR, read_handler, write_handler,
&BX_XHCI_THIS pci_base_address[0],
&BX_XHCI_THIS pci_conf[0x10],
IO_SPACE_SIZE)) {
BX_INFO(("new base address: 0x%04X", BX_XHCI_THIS pci_base_address[0]));
}
}
if (io_len == 1)
BX_DEBUG(("write PCI register 0x%02X value 0x%02X (len=1)", address, value));
@ -3274,7 +3251,7 @@ const char *bx_usb_xhci_c::usb_param_handler(bx_param_string_c *param, int set,
void bx_usb_xhci_c::dump_xhci_core(const int slots, const int eps)
{
bx_phy_address addr = BX_XHCI_THIS pci_base_address[0];
bx_phy_address addr = BX_XHCI_THIS pci_bar[0].addr;
Bit32u dword;
Bit64u qword, slot_addr;
int p, i;