- added PCI ROM support to bx_pci_device_stub_c and use it in the pcivga device (based on a patch by
Sebastian Herbszt). TODO list: - modify LGPL'd VGABIOS to make it work with SeaBIOS - modify Bochs BIOS to set up the legacy address 0xc0000 - implement PCI ROM support in the cirrus device - move load_ROM calls to the display adapter code to handle the ISA case
This commit is contained in:
parent
5ef9f8acf8
commit
deef94eb12
@ -1183,3 +1183,58 @@ void bx_pci_device_stub_c::register_pci_state(bx_list_c *list)
|
||||
new bx_shadow_num_c(pci, name, &pci_conf[i], BASE_HEX);
|
||||
}
|
||||
}
|
||||
|
||||
void bx_pci_device_stub_c::load_pci_rom(const char *path)
|
||||
{
|
||||
struct stat stat_buf;
|
||||
int fd, ret;
|
||||
unsigned long size, max_size;
|
||||
|
||||
if (*path == '\0') {
|
||||
BX_PANIC(("PCI ROM image undefined"));
|
||||
return;
|
||||
}
|
||||
// read in PCI ROM image file
|
||||
fd = open(path, O_RDONLY
|
||||
#ifdef O_BINARY
|
||||
| O_BINARY
|
||||
#endif
|
||||
);
|
||||
if (fd < 0) {
|
||||
BX_PANIC(("couldn't open PCI ROM image file '%s'.", path));
|
||||
return;
|
||||
}
|
||||
ret = fstat(fd, &stat_buf);
|
||||
if (ret) {
|
||||
BX_PANIC(("couldn't stat PCI ROM image file '%s'.", path));
|
||||
return;
|
||||
}
|
||||
|
||||
max_size = 0x10000;
|
||||
size = (unsigned long)stat_buf.st_size;
|
||||
if (size > max_size) {
|
||||
close(fd);
|
||||
BX_PANIC(("PCI ROM image too large"));
|
||||
return;
|
||||
}
|
||||
if ((size % 512) != 0) {
|
||||
close(fd);
|
||||
BX_PANIC(("PCI ROM image size must be multiple of 512 (size = %ld)", size));
|
||||
return;
|
||||
}
|
||||
while ((size - 1) < max_size) {
|
||||
max_size >>= 1;
|
||||
}
|
||||
pci_rom_size = (max_size << 1);
|
||||
|
||||
while (size > 0) {
|
||||
ret = read(fd, (bx_ptr_t) pci_rom, size);
|
||||
if (ret <= 0) {
|
||||
BX_PANIC(("read failed on PCI ROM image: '%s'", path));
|
||||
}
|
||||
size -= ret;
|
||||
}
|
||||
close(fd);
|
||||
|
||||
BX_INFO(("loaded PCI ROM '%s' (size=%u)", path, (unsigned) stat_buf.st_size));
|
||||
}
|
||||
|
@ -96,9 +96,14 @@ public:
|
||||
|
||||
void register_pci_state(bx_list_c *list);
|
||||
|
||||
void load_pci_rom(const char *path);
|
||||
|
||||
protected:
|
||||
Bit8u pci_conf[256];
|
||||
Bit32u pci_base_address[6];
|
||||
Bit8u pci_rom[65536];
|
||||
Bit32u pci_rom_address;
|
||||
Bit32u pci_rom_size;
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
@ -102,6 +102,8 @@ void bx_pcivga_c::init(void)
|
||||
WriteHostDWordToLittleEndian(&BX_PCIVGA_THIS pci_conf[0x10], 0x08);
|
||||
BX_PCIVGA_THIS pci_base_address[0] = 0;
|
||||
}
|
||||
BX_PCIVGA_THIS pci_rom_address = 0;
|
||||
BX_PCIVGA_THIS load_pci_rom(SIM->get_param_string(BXPN_VGA_ROM_PATH)->getptr());
|
||||
}
|
||||
|
||||
void bx_pcivga_c::reset(unsigned type)
|
||||
@ -132,6 +134,45 @@ void bx_pcivga_c::after_restore_state(void)
|
||||
BX_INFO(("new base address: 0x%08x", BX_PCIVGA_THIS pci_base_address[0]));
|
||||
}
|
||||
}
|
||||
if (DEV_pci_set_base_mem(this, mem_read_handler, mem_write_handler,
|
||||
&BX_PCIVGA_THIS pci_rom_address,
|
||||
&BX_PCIVGA_THIS pci_conf[0x30],
|
||||
BX_PCIVGA_THIS pci_rom_size)) {
|
||||
BX_INFO(("new ROM address: 0x%08x", BX_PCIVGA_THIS pci_rom_address));
|
||||
}
|
||||
}
|
||||
|
||||
bx_bool bx_pcivga_c::mem_read_handler(bx_phy_address addr, unsigned len, void *data, void *param)
|
||||
{
|
||||
Bit8u *data_ptr;
|
||||
|
||||
#ifdef BX_LITTLE_ENDIAN
|
||||
data_ptr = (Bit8u *) data;
|
||||
#else
|
||||
data_ptr = (Bit8u *) data + (len - 1);
|
||||
#endif
|
||||
|
||||
for (unsigned i = 0; i < len; i++) {
|
||||
if (BX_PCIVGA_THIS pci_conf[0x30] & 0x01) {
|
||||
*data_ptr = BX_PCIVGA_THIS pci_rom[addr - BX_PCIVGA_THIS pci_rom_address];
|
||||
} else {
|
||||
*data_ptr = 0xff;
|
||||
}
|
||||
addr++;
|
||||
#ifdef BX_LITTLE_ENDIAN
|
||||
data_ptr++;
|
||||
#else
|
||||
data_ptr--;
|
||||
#endif
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
bx_bool bx_pcivga_c::mem_write_handler(bx_phy_address addr, unsigned len, void *data, void *param)
|
||||
{
|
||||
BX_INFO(("write to ROM ignored (addr=0x%08x len=%d)", (Bit32u)addr, len));
|
||||
return 1;
|
||||
}
|
||||
|
||||
// pci configuration space read callback handler
|
||||
@ -157,7 +198,7 @@ Bit32u bx_pcivga_c::pci_read_handler(Bit8u address, unsigned io_len)
|
||||
// static pci configuration space write callback handler
|
||||
void bx_pcivga_c::pci_write_handler(Bit8u address, Bit32u value, unsigned io_len)
|
||||
{
|
||||
bx_bool baseaddr_change = 0;
|
||||
bx_bool baseaddr_change = 0, romaddr_change = 0;
|
||||
|
||||
if (io_len == 1)
|
||||
BX_DEBUG(("write PCI register 0x%02x value 0x%02x", address, value));
|
||||
@ -166,9 +207,14 @@ void bx_pcivga_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));
|
||||
|
||||
if ((address >= 0x14) && (address < 0x34))
|
||||
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_PCIVGA_THIS pci_conf[write_addr];
|
||||
@ -197,6 +243,14 @@ void bx_pcivga_c::pci_write_handler(Bit8u address, Bit32u value, unsigned io_len
|
||||
BX_INFO(("new base address: 0x%08x", BX_PCIVGA_THIS pci_base_address[0]));
|
||||
}
|
||||
}
|
||||
if (romaddr_change) {
|
||||
if (DEV_pci_set_base_mem(this, mem_read_handler, mem_write_handler,
|
||||
&BX_PCIVGA_THIS pci_rom_address,
|
||||
&BX_PCIVGA_THIS pci_conf[0x30],
|
||||
BX_PCIVGA_THIS pci_rom_size)) {
|
||||
BX_INFO(("new ROM address: 0x%08x", BX_PCIVGA_THIS pci_rom_address));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif // BX_SUPPORT_PCI
|
||||
|
@ -23,8 +23,10 @@
|
||||
|
||||
#if BX_USE_PCIVGA_SMF
|
||||
# define BX_PCIVGA_THIS thePciVgaAdapter->
|
||||
# define BX_PCIVGA_SMF static
|
||||
#else
|
||||
# define BX_PCIVGA_THIS this->
|
||||
# define BX_PCIVGA_SMF
|
||||
#endif
|
||||
|
||||
class bx_pcivga_c : public bx_devmodel_c, public bx_pci_device_stub_c {
|
||||
@ -36,6 +38,9 @@ public:
|
||||
virtual void register_state(void);
|
||||
virtual void after_restore_state(void);
|
||||
|
||||
BX_PCIVGA_SMF bx_bool mem_read_handler(bx_phy_address addr, unsigned len, void *data, void *param);
|
||||
BX_PCIVGA_SMF bx_bool mem_write_handler(bx_phy_address addr, unsigned len, void *data, void *param);
|
||||
|
||||
virtual Bit32u pci_read_handler(Bit8u address, unsigned io_len);
|
||||
virtual void pci_write_handler(Bit8u address, Bit32u value, unsigned io_len);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user