Added advanced PCI option 'noagp' for the i440BX chipset.

Since AGP support is incomplete, it may be useful to disable this subsystem.
This commit is contained in:
Volker Ruppert 2021-06-27 14:50:26 +00:00
parent d9dd62e42f
commit caf52aacac
11 changed files with 77 additions and 29 deletions

View File

@ -565,7 +565,8 @@ mouse: enabled=0
# PCI chipset. These options can be specified as comma-separated values. # PCI chipset. These options can be specified as comma-separated values.
# By default the "Bochs i440FX" chipset enables the ACPI and HPET devices, but # 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 # 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: # Example:
# pci: enabled=1, chipset=i440fx, slot1=pcivga, slot2=ne2k, advopts=noacpi # pci: enabled=1, chipset=i440fx, slot1=pcivga, slot2=ne2k, advopts=noacpi

View File

@ -64,7 +64,8 @@ Detailed change log :
either to disable the DDC feature or to read the monitor EDID from file. either to disable the DDC feature or to read the monitor EDID from file.
- PCI (general) - PCI (general)
- Added config parameter to set up advanced PCI options. Now it is possible - 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 - USB
- Added keyboard emulation with most of the keys supported. - Added keyboard emulation with most of the keys supported.
- Added support for USB packet logging in PCAP format. - Added support for USB packet logging in PCAP format.

View File

@ -257,6 +257,7 @@
#define PCI_DEVICE_ID_INTEL_82441 0x1237 #define PCI_DEVICE_ID_INTEL_82441 0x1237
#define PCI_DEVICE_ID_INTEL_82443 0x7190 #define PCI_DEVICE_ID_INTEL_82443 0x7190
#define PCI_DEVICE_ID_INTEL_82443_1 0x7191 #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_0 0x122e
#define PCI_DEVICE_ID_INTEL_82371FB_1 0x1230 #define PCI_DEVICE_ID_INTEL_82371FB_1 0x1230
#define PCI_DEVICE_ID_INTEL_82371SB_0 0x7000 #define PCI_DEVICE_ID_INTEL_82371SB_0 0x7000

View File

@ -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) { } else if (device_id == PCI_DEVICE_ID_INTEL_82441 || device_id == PCI_DEVICE_ID_INTEL_82437) {
/* i440FX / i430FX PCI bridge */ /* i440FX / i430FX PCI bridge */
bios_shadow_init(d); 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 */ /* i440BX PCI bridge */
bios_shadow_init(d); bios_shadow_init(d);
addr = find_pir_table(); 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 + 0x41, 0x48); // 3rd entry: 2nd slot
writeb(pir + 0x51, 0x50); // 4th entry: 3rd slot writeb(pir + 0x51, 0x50); // 4th entry: 3rd slot
writeb(pir + 0x61, 0x58); // 5th entry: 4th slot writeb(pir + 0x61, 0x58); // 5th entry: 4th slot
writeb(pir + 0x70, 0x01); // 6th entry: AGP bus if (device_id == PCI_DEVICE_ID_INTEL_82443) {
writeb(pir + 0x71, 0x00); // 6th entry: AGP slot writeb(pir + 0x70, 0x01); // 6th entry: AGP bus
pci_config_writeb(d, 0xb4, 0x30); /* AGP aperture size 64 MB */ 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) { } else if (device_id == PCI_DEVICE_ID_INTEL_82443_1) {
/* i440BX PCI/AGP bridge */ /* i440BX PCI/AGP bridge */
pci_config_writew(d, 0x04, 0x0107); pci_config_writew(d, 0x04, 0x0107);

View File

@ -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. PCI chipset. These options can be specified as comma-separated values.
By default the "Bochs i440FX" chipset enables the ACPI and HPET devices, but 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 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.
</para> </para>
</section> </section>

View File

@ -1,5 +1,5 @@
.\"Document Author: Timothy R. Butler - tbutler@uninetsolutions.com" .\"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" .\"SKIP_SECTION"
.SH NAME .SH NAME
bochsrc \- Configuration file for Bochs. 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. PCI chipset. These options can be specified as comma-separated values.
By default the "Bochs i440FX" chipset enables the ACPI and HPET devices, but 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 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: Example:
pci: enabled=1, chipset=i440fx, slot1=pcivga, slot2=ne2k, advopts=noacpi pci: enabled=1, chipset=i440fx, slot1=pcivga, slot2=ne2k, advopts=noacpi

View File

@ -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) bool bx_real_sim_c::is_agp_device(const char *name)
{ {
#if BX_SUPPORT_PCI #if BX_SUPPORT_PCI
if (get_param_bool(BXPN_PCI_ENABLED)->get() && if (get_param_bool(BXPN_PCI_ENABLED)->get() && DEV_agp_present()) {
(SIM->get_param_enum(BXPN_PCI_CHIPSET)->get() == BX_PCI_CHIPSET_I440BX)) {
const char *device = SIM->get_param_enum("pci.slot.5")->get_selected(); const char *device = SIM->get_param_enum("pci.slot.5")->get_selected();
if (!strcmp(name, device)) { if (!strcmp(name, device)) {
return 1; return 1;

View File

@ -192,7 +192,9 @@ void bx_devices_c::init(BX_MEM_C *newmem)
if (pci.enabled) { if (pci.enabled) {
#if BX_SUPPORT_PCI #if BX_SUPPORT_PCI
if (chipset == BX_PCI_CHIPSET_I430FX) { 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 { } else {
pci.advopts = 0; pci.advopts = 0;
} }
@ -207,6 +209,12 @@ void bx_devices_c::init(BX_MEM_C *newmem)
} }
} else if (!strcmp(argv[i], "nohpet")) { } else if (!strcmp(argv[i], "nohpet")) {
pci.advopts |= BX_PCI_ADVOPT_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 { } else {
BX_ERROR(("Unknown advanced PCI option '%s'", argv[i])); 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; const char *device;
if (pci.enabled) { 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(); device = SIM->get_param_enum("pci.slot.5")->get_selected();
if (strcmp(device, "none") && !pci.slot_used[4]) { if (strcmp(device, "none") && !pci.slot_used[4]) {
BX_PANIC(("Unknown plugin '%s' at AGP slot", device)); BX_PANIC(("Unknown plugin '%s' at AGP slot", device));
@ -1100,6 +1108,15 @@ bool bx_devices_c::is_harddrv_enabled(void)
return 0; 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) void bx_devices_c::add_sound_device(void)
{ {
sound_device_count++; 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") if (strcmp(name, "pci") && strcmp(name, "pci2isa") && strcmp(name, "pci_ide")
&& ((*devfunc & 0xf8) == 0x00)) { && ((*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; max_pci_slots = 4;
} }
if (bus == 0) { if (bus == 0) {

View File

@ -126,6 +126,7 @@ class cdrom_base_c;
#define BX_PCI_ADVOPT_NOACPI 0x01 #define BX_PCI_ADVOPT_NOACPI 0x01
#define BX_PCI_ADVOPT_NOHPET 0x02 #define BX_PCI_ADVOPT_NOHPET 0x02
#define BX_PCI_ADVOPT_NOAGP 0x04
typedef struct { typedef struct {
Bit8u type; Bit8u type;
@ -443,6 +444,7 @@ public:
Bit32u *addr, Bit8u *pci_conf, unsigned size, Bit32u *addr, Bit8u *pci_conf, unsigned size,
const Bit8u *iomask, const char *name); const Bit8u *iomask, const char *name);
#endif #endif
bool is_agp_present();
static void timer_handler(void *); static void timer_handler(void *);
void timer(void); void timer(void);

View File

@ -82,21 +82,33 @@ void bx_pci_bridge_c::init(void)
if (BX_PCI_THIS chipset == BX_PCI_CHIPSET_I430FX) { if (BX_PCI_THIS chipset == BX_PCI_CHIPSET_I430FX) {
init_pci_conf(0x8086, 0x0122, 0x02, 0x060000, 0x00, 0); init_pci_conf(0x8086, 0x0122, 0x02, 0x060000, 0x00, 0);
} else if (BX_PCI_THIS chipset == BX_PCI_CHIPSET_I440BX) { } else if (BX_PCI_THIS chipset == BX_PCI_CHIPSET_I440BX) {
init_pci_conf(0x8086, 0x7190, 0x02, 0x060000, 0x00, 0); if (DEV_agp_present()) {
BX_PCI_THIS pci_conf[0x10] = 0x08; init_pci_conf(0x8086, 0x7190, 0x02, 0x060000, 0x00, 0);
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[0x06] = 0x10; BX_PCI_THIS pci_conf[0x10] = 0x08;
BX_PCI_THIS pci_conf[0x34] = 0xa0; init_bar_mem(0, 0xf0000000, agp_ap_read_handler, agp_ap_write_handler);
BX_PCI_THIS pci_conf[0xa0] = 0x02; BX_PCI_THIS pci_conf[0x34] = 0xa0;
BX_PCI_THIS pci_conf[0xa2] = 0x10; BX_PCI_THIS pci_conf[0xa0] = 0x02;
BX_PCI_THIS pci_conf[0xa4] = 0x03; BX_PCI_THIS pci_conf[0xa2] = 0x10;
BX_PCI_THIS pci_conf[0xa5] = 0x02; BX_PCI_THIS pci_conf[0xa4] = 0x03;
BX_PCI_THIS pci_conf[0xa7] = 0x1f; 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[0xf3] = 0xf8;
BX_PCI_THIS pci_conf[0xf8] = 0x20; BX_PCI_THIS pci_conf[0xf8] = 0x20;
BX_PCI_THIS pci_conf[0xf9] = 0x0f; BX_PCI_THIS pci_conf[0xf9] = 0x0f;
BX_PCI_THIS vbridge = new bx_pci_vbridge_c();
BX_PCI_THIS vbridge->init();
} else { // i440FX } else { // i440FX
init_pci_conf(0x8086, 0x1237, 0x00, 0x060000, 0x00, 0); 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[0x06] = 0x00;
BX_PCI_THIS pci_conf[0x58] = 0x00; BX_PCI_THIS pci_conf[0x58] = 0x00;
} else if (BX_PCI_THIS chipset == BX_PCI_CHIPSET_I440BX) { } 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 } else { // i440FX
BX_PCI_THIS pci_conf[0x06] = 0x80; BX_PCI_THIS pci_conf[0x06] = 0x80;
BX_PCI_THIS pci_conf[0x51] = 0x01; 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"); bx_list_c *list = new bx_list_c(SIM->get_bochs_root(), "pci_bridge", "PCI Bridge State");
register_pci_state(list); 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(); 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) void bx_pci_bridge_c::after_restore_state(void)
{ {
BX_PCI_THIS smram_control(BX_PCI_THIS pci_conf[0x72]); 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(); 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: case 0x72:
smram_control(value8); // SMRAM control register smram_control(value8); // SMRAM control register
break; break;
case 0x7a:
BX_PCI_THIS pci_conf[address+i] &= 0x0a;
BX_PCI_THIS pci_conf[address+i] |= (value8 & 0xf5);
break;
case 0xb4: case 0xb4:
if (BX_PCI_THIS chipset == BX_PCI_CHIPSET_I440BX) { if (BX_PCI_THIS chipset == BX_PCI_CHIPSET_I440BX) {
BX_PCI_THIS pci_conf[address+i] = value8 & 0x3f; BX_PCI_THIS pci_conf[address+i] = value8 & 0x3f;

View File

@ -234,6 +234,7 @@ extern "C" {
#define DEV_ide_bmdma_start_transfer(a) \ #define DEV_ide_bmdma_start_transfer(a) \
bx_devices.pluginPciIdeController->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_acpi_generate_smi(a) bx_devices.pluginACPIController->generate_smi(a)
#define DEV_agp_present() (bx_devices.is_agp_present())
///////// Speaker macros ///////// Speaker macros
#define DEV_speaker_beep_on(frequency) bx_devices.pluginSpeaker->beep_on(frequency) #define DEV_speaker_beep_on(frequency) bx_devices.pluginSpeaker->beep_on(frequency)