diff --git a/bochs/.bochsrc b/bochs/.bochsrc index a442c52dd..d8202fd44 100644 --- a/bochs/.bochsrc +++ b/bochs/.bochsrc @@ -565,7 +565,8 @@ mouse: enabled=0 # PCI chipset. These options can be specified as comma-separated values. # By default the "Bochs i440FX" chipset enables the ACPI and HPET devices, but # original i440FX doesn't support them. The options 'noacpi' and 'nohpet' make -# it possible to disable them. +# it possible to disable them. The option 'noagp' disables the incomplete AGP +# subsystem of the i440BX chipset. # # Example: # pci: enabled=1, chipset=i440fx, slot1=pcivga, slot2=ne2k, advopts=noacpi diff --git a/bochs/CHANGES b/bochs/CHANGES index 9cfcfdf3e..55aa85675 100644 --- a/bochs/CHANGES +++ b/bochs/CHANGES @@ -64,7 +64,8 @@ Detailed change log : either to disable the DDC feature or to read the monitor EDID from file. - PCI (general) - Added config parameter to set up advanced PCI options. Now it is possible - to disable ACPI or HPET in case the i440FX chipset is selected. + to disable ACPI or HPET in case the i440FX chipset is selected. For the + i440BX chipset it is possible to disable the incomplete AGP subsystem. - USB - Added keyboard emulation with most of the keys supported. - Added support for USB packet logging in PCAP format. diff --git a/bochs/bios/rombios.h b/bochs/bios/rombios.h index 61bfc31a4..ad346c5b3 100644 --- a/bochs/bios/rombios.h +++ b/bochs/bios/rombios.h @@ -257,6 +257,7 @@ #define PCI_DEVICE_ID_INTEL_82441 0x1237 #define PCI_DEVICE_ID_INTEL_82443 0x7190 #define PCI_DEVICE_ID_INTEL_82443_1 0x7191 +#define PCI_DEVICE_ID_INTEL_82443_NOAGP 0x7192 #define PCI_DEVICE_ID_INTEL_82371FB_0 0x122e #define PCI_DEVICE_ID_INTEL_82371FB_1 0x1230 #define PCI_DEVICE_ID_INTEL_82371SB_0 0x7000 diff --git a/bochs/bios/rombios32.c b/bochs/bios/rombios32.c index 5f7c3a30f..ea319978e 100644 --- a/bochs/bios/rombios32.c +++ b/bochs/bios/rombios32.c @@ -782,7 +782,8 @@ static void pci_bios_init_bridges(PCIDevice *d) } else if (device_id == PCI_DEVICE_ID_INTEL_82441 || device_id == PCI_DEVICE_ID_INTEL_82437) { /* i440FX / i430FX PCI bridge */ bios_shadow_init(d); - } else if (device_id == PCI_DEVICE_ID_INTEL_82443) { + } else if ((device_id == PCI_DEVICE_ID_INTEL_82443) || + (device_id == PCI_DEVICE_ID_INTEL_82443_NOAGP)) { /* i440BX PCI bridge */ bios_shadow_init(d); addr = find_pir_table(); @@ -795,9 +796,13 @@ static void pci_bios_init_bridges(PCIDevice *d) writeb(pir + 0x41, 0x48); // 3rd entry: 2nd slot writeb(pir + 0x51, 0x50); // 4th entry: 3rd slot writeb(pir + 0x61, 0x58); // 5th entry: 4th slot - writeb(pir + 0x70, 0x01); // 6th entry: AGP bus - writeb(pir + 0x71, 0x00); // 6th entry: AGP slot - pci_config_writeb(d, 0xb4, 0x30); /* AGP aperture size 64 MB */ + if (device_id == PCI_DEVICE_ID_INTEL_82443) { + writeb(pir + 0x70, 0x01); // 6th entry: AGP bus + writeb(pir + 0x71, 0x00); // 6th entry: AGP slot + pci_config_writeb(d, 0xb4, 0x30); /* AGP aperture size 64 MB */ + } else { + writeb(pir + 0x71, 0x60); // 6th entry: 5th slot + } } else if (device_id == PCI_DEVICE_ID_INTEL_82443_1) { /* i440BX PCI/AGP bridge */ pci_config_writew(d, 0x04, 0x0107); diff --git a/bochs/doc/docbook/user/user.dbk b/bochs/doc/docbook/user/user.dbk index 7ff71813b..d07b8a89f 100644 --- a/bochs/doc/docbook/user/user.dbk +++ b/bochs/doc/docbook/user/user.dbk @@ -4017,7 +4017,8 @@ With the advanced PCI options it is possible to control the behaviour of the PCI chipset. These options can be specified as comma-separated values. By default the "Bochs i440FX" chipset enables the ACPI and HPET devices, but original i440FX doesn't support them. The options 'noacpi' and 'nohpet' make -it possible to disable them. +it possible to disable them. The option 'noagp' disables the incomplete AGP +subsystem of the i440BX chipset. diff --git a/bochs/doc/man/bochsrc.5 b/bochs/doc/man/bochsrc.5 index 0c55ea716..1e9983d62 100644 --- a/bochs/doc/man/bochsrc.5 +++ b/bochs/doc/man/bochsrc.5 @@ -1,5 +1,5 @@ .\"Document Author: Timothy R. Butler - tbutler@uninetsolutions.com" -.TH bochsrc 5 "11 Jun 2021" "bochsrc" "The Bochs Project" +.TH bochsrc 5 "27 Jun 2021" "bochsrc" "The Bochs Project" .\"SKIP_SECTION" .SH NAME bochsrc \- Configuration file for Bochs. @@ -625,7 +625,8 @@ With the advanced PCI options it is possible to control the behaviour of the PCI chipset. These options can be specified as comma-separated values. By default the "Bochs i440FX" chipset enables the ACPI and HPET devices, but original i440FX doesn't support them. The options 'noacpi' and 'nohpet' make -it possible to disable them. +it possible to disable them. The option 'noagp' disables the incomplete AGP +subsystem of the i440BX chipset. Example: pci: enabled=1, chipset=i440fx, slot1=pcivga, slot2=ne2k, advopts=noacpi diff --git a/bochs/gui/siminterface.cc b/bochs/gui/siminterface.cc index 0dedc17da..9de68f931 100644 --- a/bochs/gui/siminterface.cc +++ b/bochs/gui/siminterface.cc @@ -799,8 +799,7 @@ bool bx_real_sim_c::is_pci_device(const char *name) bool bx_real_sim_c::is_agp_device(const char *name) { #if BX_SUPPORT_PCI - if (get_param_bool(BXPN_PCI_ENABLED)->get() && - (SIM->get_param_enum(BXPN_PCI_CHIPSET)->get() == BX_PCI_CHIPSET_I440BX)) { + if (get_param_bool(BXPN_PCI_ENABLED)->get() && DEV_agp_present()) { const char *device = SIM->get_param_enum("pci.slot.5")->get_selected(); if (!strcmp(name, device)) { return 1; diff --git a/bochs/iodev/devices.cc b/bochs/iodev/devices.cc index 1a7a39d13..ecc084377 100644 --- a/bochs/iodev/devices.cc +++ b/bochs/iodev/devices.cc @@ -192,7 +192,9 @@ void bx_devices_c::init(BX_MEM_C *newmem) if (pci.enabled) { #if BX_SUPPORT_PCI if (chipset == BX_PCI_CHIPSET_I430FX) { - pci.advopts = (BX_PCI_ADVOPT_NOHPET | BX_PCI_ADVOPT_NOACPI); + pci.advopts = (BX_PCI_ADVOPT_NOHPET | BX_PCI_ADVOPT_NOACPI | BX_PCI_ADVOPT_NOAGP); + } else if (chipset == BX_PCI_CHIPSET_I440FX) { + pci.advopts = BX_PCI_ADVOPT_NOAGP; } else { pci.advopts = 0; } @@ -207,6 +209,12 @@ void bx_devices_c::init(BX_MEM_C *newmem) } } else if (!strcmp(argv[i], "nohpet")) { pci.advopts |= BX_PCI_ADVOPT_NOHPET; + } else if (!strcmp(argv[i], "noagp")) { + if (chipset == BX_PCI_CHIPSET_I440BX) { + pci.advopts |= BX_PCI_ADVOPT_NOAGP; + } else { + BX_ERROR(("Disabling AGP not supported by PCI chipset")); + } } else { BX_ERROR(("Unknown advanced PCI option '%s'", argv[i])); } @@ -362,7 +370,7 @@ void bx_devices_c::init(BX_MEM_C *newmem) const char *device; if (pci.enabled) { - if (chipset == BX_PCI_CHIPSET_I440BX) { + if ((chipset == BX_PCI_CHIPSET_I440BX) && is_agp_present()) { device = SIM->get_param_enum("pci.slot.5")->get_selected(); if (strcmp(device, "none") && !pci.slot_used[4]) { BX_PANIC(("Unknown plugin '%s' at AGP slot", device)); @@ -1100,6 +1108,15 @@ bool bx_devices_c::is_harddrv_enabled(void) return 0; } +bool bx_devices_c::is_agp_present(void) +{ +#if BX_SUPPORT_PCI + return (pci.enabled && ((pci.advopts & BX_PCI_ADVOPT_NOAGP) == 0)); +#else + return 0; +#endif +} + void bx_devices_c::add_sound_device(void) { sound_device_count++; @@ -1358,7 +1375,8 @@ bool bx_devices_c::register_pci_handlers(bx_pci_device_c *dev, if (strcmp(name, "pci") && strcmp(name, "pci2isa") && strcmp(name, "pci_ide") && ((*devfunc & 0xf8) == 0x00)) { - if (SIM->get_param_enum(BXPN_PCI_CHIPSET)->get() == BX_PCI_CHIPSET_I440BX) { + if ((SIM->get_param_enum(BXPN_PCI_CHIPSET)->get() == BX_PCI_CHIPSET_I440BX) && + (is_agp_present())) { max_pci_slots = 4; } if (bus == 0) { diff --git a/bochs/iodev/iodev.h b/bochs/iodev/iodev.h index 79aa88434..8834b56fa 100644 --- a/bochs/iodev/iodev.h +++ b/bochs/iodev/iodev.h @@ -126,6 +126,7 @@ class cdrom_base_c; #define BX_PCI_ADVOPT_NOACPI 0x01 #define BX_PCI_ADVOPT_NOHPET 0x02 +#define BX_PCI_ADVOPT_NOAGP 0x04 typedef struct { Bit8u type; @@ -443,6 +444,7 @@ public: Bit32u *addr, Bit8u *pci_conf, unsigned size, const Bit8u *iomask, const char *name); #endif + bool is_agp_present(); static void timer_handler(void *); void timer(void); diff --git a/bochs/iodev/pci.cc b/bochs/iodev/pci.cc index 1e50e97f2..134aaaaf1 100644 --- a/bochs/iodev/pci.cc +++ b/bochs/iodev/pci.cc @@ -82,21 +82,33 @@ void bx_pci_bridge_c::init(void) if (BX_PCI_THIS chipset == BX_PCI_CHIPSET_I430FX) { init_pci_conf(0x8086, 0x0122, 0x02, 0x060000, 0x00, 0); } else if (BX_PCI_THIS chipset == BX_PCI_CHIPSET_I440BX) { - init_pci_conf(0x8086, 0x7190, 0x02, 0x060000, 0x00, 0); - BX_PCI_THIS pci_conf[0x10] = 0x08; - init_bar_mem(0, 0xf0000000, agp_ap_read_handler, agp_ap_write_handler); - BX_PCI_THIS pci_conf[0x06] = 0x10; - BX_PCI_THIS pci_conf[0x34] = 0xa0; - BX_PCI_THIS pci_conf[0xa0] = 0x02; - BX_PCI_THIS pci_conf[0xa2] = 0x10; - BX_PCI_THIS pci_conf[0xa4] = 0x03; - BX_PCI_THIS pci_conf[0xa5] = 0x02; - BX_PCI_THIS pci_conf[0xa7] = 0x1f; + if (DEV_agp_present()) { + init_pci_conf(0x8086, 0x7190, 0x02, 0x060000, 0x00, 0); + BX_PCI_THIS pci_conf[0x06] = 0x10; + BX_PCI_THIS pci_conf[0x10] = 0x08; + init_bar_mem(0, 0xf0000000, agp_ap_read_handler, agp_ap_write_handler); + BX_PCI_THIS pci_conf[0x34] = 0xa0; + BX_PCI_THIS pci_conf[0xa0] = 0x02; + BX_PCI_THIS pci_conf[0xa2] = 0x10; + BX_PCI_THIS pci_conf[0xa4] = 0x03; + BX_PCI_THIS pci_conf[0xa5] = 0x02; + BX_PCI_THIS pci_conf[0xa7] = 0x1f; + BX_PCI_THIS vbridge = new bx_pci_vbridge_c(); + BX_PCI_THIS vbridge->init(); + } else { + init_pci_conf(0x8086, 0x7192, 0x02, 0x060000, 0x00, 0); + BX_PCI_THIS pci_conf[0x7a] = 0x02; + } + // 'Intel reserved' values + BX_PCI_THIS pci_conf[0x71] = 0x1f; + BX_PCI_THIS pci_conf[0x94] = 0x04; + BX_PCI_THIS pci_conf[0x95] = 0x61; + BX_PCI_THIS pci_conf[0x99] = 0x05; + BX_PCI_THIS pci_conf[0xc8] = 0x18; + BX_PCI_THIS pci_conf[0xc9] = 0x0c; BX_PCI_THIS pci_conf[0xf3] = 0xf8; BX_PCI_THIS pci_conf[0xf8] = 0x20; BX_PCI_THIS pci_conf[0xf9] = 0x0f; - BX_PCI_THIS vbridge = new bx_pci_vbridge_c(); - BX_PCI_THIS vbridge->init(); } else { // i440FX init_pci_conf(0x8086, 0x1237, 0x00, 0x060000, 0x00, 0); } @@ -204,7 +216,9 @@ bx_pci_bridge_c::reset(unsigned type) BX_PCI_THIS pci_conf[0x06] = 0x00; BX_PCI_THIS pci_conf[0x58] = 0x00; } else if (BX_PCI_THIS chipset == BX_PCI_CHIPSET_I440BX) { - BX_PCI_THIS vbridge->reset(type); + if (BX_PCI_THIS vbridge != NULL) { + BX_PCI_THIS vbridge->reset(type); + } } else { // i440FX BX_PCI_THIS pci_conf[0x06] = 0x80; BX_PCI_THIS pci_conf[0x51] = 0x01; @@ -228,7 +242,7 @@ void bx_pci_bridge_c::register_state(void) { bx_list_c *list = new bx_list_c(SIM->get_bochs_root(), "pci_bridge", "PCI Bridge State"); register_pci_state(list); - if (BX_PCI_THIS chipset == BX_PCI_CHIPSET_I440BX) { + if (BX_PCI_THIS vbridge != NULL) { BX_PCI_THIS vbridge->register_state(); } } @@ -236,7 +250,7 @@ void bx_pci_bridge_c::register_state(void) void bx_pci_bridge_c::after_restore_state(void) { BX_PCI_THIS smram_control(BX_PCI_THIS pci_conf[0x72]); - if (BX_PCI_THIS chipset == BX_PCI_CHIPSET_I440BX) { + if (BX_PCI_THIS vbridge != NULL) { BX_PCI_THIS vbridge->after_restore_state(); } } @@ -350,6 +364,10 @@ void bx_pci_bridge_c::pci_write_handler(Bit8u address, Bit32u value, unsigned io case 0x72: smram_control(value8); // SMRAM control register break; + case 0x7a: + BX_PCI_THIS pci_conf[address+i] &= 0x0a; + BX_PCI_THIS pci_conf[address+i] |= (value8 & 0xf5); + break; case 0xb4: if (BX_PCI_THIS chipset == BX_PCI_CHIPSET_I440BX) { BX_PCI_THIS pci_conf[address+i] = value8 & 0x3f; diff --git a/bochs/plugin.h b/bochs/plugin.h index c580abc66..2d084407d 100644 --- a/bochs/plugin.h +++ b/bochs/plugin.h @@ -234,6 +234,7 @@ extern "C" { #define DEV_ide_bmdma_start_transfer(a) \ bx_devices.pluginPciIdeController->bmdma_start_transfer(a) #define DEV_acpi_generate_smi(a) bx_devices.pluginACPIController->generate_smi(a) +#define DEV_agp_present() (bx_devices.is_agp_present()) ///////// Speaker macros #define DEV_speaker_beep_on(frequency) bx_devices.pluginSpeaker->beep_on(frequency)