summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--util/x86emu/yabel/interrupt.c58
-rw-r--r--util/x86emu/yabel/io.c32
2 files changed, 64 insertions, 26 deletions
diff --git a/util/x86emu/yabel/interrupt.c b/util/x86emu/yabel/interrupt.c
index 03614c095025..9cb0f13d5d7a 100644
--- a/util/x86emu/yabel/interrupt.c
+++ b/util/x86emu/yabel/interrupt.c
@@ -330,6 +330,7 @@ handleInt1a(void)
{
// function number in AX
u8 bus, devfn, offs;
+ struct device* dev;
switch (M.x86.R_AX) {
case 0xb101:
// Installation check
@@ -341,30 +342,46 @@ handleInt1a(void)
break;
case 0xb102:
// Find PCI Device
- // NOTE: we currently only allow the device to find itself...
- // it SHOULD be all we ever need...
// device_id in CX, vendor_id in DX
// device index in SI (i.e. if multiple devices with same vendor/device id
// are connected). We currently only support device index 0
+ //
DEBUG_PRINTF_INTR("%s(): function: %x: PCI Find Device\n",
__func__, M.x86.R_AX);
+ /* FixME: support SI != 0 */
+#if defined(CONFIG_YABEL_PCI_ACCESS_OTHER_DEVICES) && CONFIG_YABEL_PCI_ACCESS_OTHER_DEVICES==1
+#ifdef COREBOOT_V2
+ dev = dev_find_device(M.x86.R_DX, M.x86.R_CX, 0);
+#else
+ dev = dev_find_pci_device(M.x86.R_DX, M.x86.R_CX, 0);
+#endif
+ if (dev != 0) {
+ DEBUG_PRINTF_INTR
+ ("%s(): function %x: PCI Find Device --> 0x%04x\n",
+ __func__, M.x86.R_AX, M.x86.R_BX);
+
+ M.x86.R_BH = dev->bus->secondary;
+ M.x86.R_BL = dev->path.pci.devfn;
+ M.x86.R_AH = 0x00; // return code: success
+ CLEAR_FLAG(F_CF);
+#else
+ // only allow the device to find itself...
if ((M.x86.R_CX == bios_device.pci_device_id)
- && (M.x86.R_DX == bios_device.pci_vendor_id)
- // device index must be 0
- && (M.x86.R_SI == 0)) {
+ && (M.x86.R_DX == bios_device.pci_vendor_id)
+ // device index must be 0
+ && (M.x86.R_SI == 0)) {
CLEAR_FLAG(F_CF);
- M.x86.R_AH = 0x00; // return code: success
+ M.x86.R_AH = 0x00; // return code: success
M.x86.R_BH = bios_device.bus;
M.x86.R_BL = bios_device.devfn;
- DEBUG_PRINTF_INTR
- ("%s(): function %x: PCI Find Device --> 0x%04x\n",
- __func__, M.x86.R_AX, M.x86.R_BX);
+#endif
} else {
DEBUG_PRINTF_INTR
- ("%s(): function %x: invalid device/vendor/device index! (%04x/%04x/%02x expected: %04x/%04x/0) \n",
+ ("%s(): function %x: invalid device/vendor/device index! (%04x/%04x/%02x expected: %04x/%04x/00) \n",
__func__, M.x86.R_AX, M.x86.R_CX, M.x86.R_DX,
M.x86.R_SI, bios_device.pci_device_id,
bios_device.pci_vendor_id);
+
SET_FLAG(F_CF);
M.x86.R_AH = 0x86; // return code: device not found
}
@@ -375,11 +392,22 @@ handleInt1a(void)
bus = M.x86.R_BH;
devfn = M.x86.R_BL;
offs = M.x86.R_DI;
+ DEBUG_PRINTF_INTR("%s(): function: %x: PCI Config Read from device: bus: %02x, devfn: %02x, offset: %02x\n",
+ __func__, M.x86.R_AX, bus, devfn, offs);
+#if defined(CONFIG_YABEL_PCI_ACCESS_OTHER_DEVICES) && CONFIG_YABEL_PCI_ACCESS_OTHER_DEVICES==1
+ dev = dev_find_slot(bus, devfn);
+ DEBUG_PRINTF_INTR("%s(): function: %x: dev_find_slot() returned: %s\n",
+ __func__, M.x86.R_AX, dev_path(dev));
+ if (dev == 0) {
+ // fail accesses to non-existent devices...
+#else
+ dev = bios_device.dev;
if ((bus != bios_device.bus)
- || (devfn != bios_device.devfn)) {
+ || (devfn != bios_device.devfn)) {
// fail accesses to any device but ours...
+#endif
printf
- ("%s(): Config read access invalid! bus: %x (%x), devfn: %x (%x), offs: %x\n",
+ ("%s(): Config read access invalid device! bus: %02x (%02x), devfn: %02x (%02x), offs: %02x\n",
__func__, bus, bios_device.bus, devfn,
bios_device.devfn, offs);
SET_FLAG(F_CF);
@@ -391,7 +419,7 @@ handleInt1a(void)
case 0xb108:
M.x86.R_CL =
#ifdef CONFIG_PCI_OPTION_ROM_RUN_YABEL
- pci_read_config8(bios_device.dev, offs);
+ pci_read_config8(dev, offs);
#else
(u8) rtas_pci_config_read(bios_device.
puid, 1,
@@ -406,7 +434,7 @@ handleInt1a(void)
case 0xb109:
M.x86.R_CX =
#ifdef CONFIG_PCI_OPTION_ROM_RUN_YABEL
- pci_read_config16(bios_device.dev, offs);
+ pci_read_config16(dev, offs);
#else
(u16) rtas_pci_config_read(bios_device.
puid, 2,
@@ -421,7 +449,7 @@ handleInt1a(void)
case 0xb10a:
M.x86.R_ECX =
#ifdef CONFIG_PCI_OPTION_ROM_RUN_YABEL
- pci_read_config32(bios_device.dev, offs);
+ pci_read_config32(dev, offs);
#else
(u32) rtas_pci_config_read(bios_device.
puid, 4,
diff --git a/util/x86emu/yabel/io.c b/util/x86emu/yabel/io.c
index aa0b3856b207..6380ec3bc3d2 100644
--- a/util/x86emu/yabel/io.c
+++ b/util/x86emu/yabel/io.c
@@ -349,6 +349,7 @@ u32
pci_cfg_read(X86EMU_pioAddr addr, u8 size)
{
u32 rval = 0xFFFFFFFF;
+ struct device * dev;
if ((addr >= 0xCFC) && ((addr + size) <= 0xD00)) {
// PCI Configuration Mechanism 1 step 1
// write to 0xCF8, sets bus, device, function and Config Space offset
@@ -361,29 +362,38 @@ pci_cfg_read(X86EMU_pioAddr addr, u8 size)
devfn = (port_cf8_val & 0x0000FF00) >> 8;
offs = (port_cf8_val & 0x000000FF);
offs += (addr - 0xCFC); // if addr is not 0xcfc, the offset is moved accordingly
+ DEBUG_PRINTF_INTR("%s(): PCI Config Read from device: bus: %02x, devfn: %02x, offset: %02x\n",
+ __func__, bus, devfn, offs);
+#if defined(CONFIG_YABEL_PCI_ACCESS_OTHER_DEVICES) && CONFIG_YABEL_PCI_ACCESS_OTHER_DEVICES==1
+ dev = dev_find_slot(bus, devfn);
+ DEBUG_PRINTF_INTR("%s(): dev_find_slot() returned: %s\n",
+ __func__, dev_path(dev));
+ if (dev == 0) {
+ // fail accesses to non-existent devices...
+#else
+ dev = bios_device.dev;
if ((bus != bios_device.bus)
- || (devfn != bios_device.devfn)) {
+ || (devfn != bios_device.devfn)) {
// fail accesses to any device but ours...
+#endif
printf
- ("Config read access invalid! PCI device %x:%x.%x, offs: %x\n",
- bus, devfn >> 3, devfn & 7, offs);
-#ifdef CONFIG_YABEL_NO_ILLEGAL_ACCESS
+ ("%s(): Config read access invalid device! bus: %02x (%02x), devfn: %02x (%02x), offs: %02x\n",
+ __func__, bus, bios_device.bus, devfn,
+ bios_device.devfn, offs);
+ SET_FLAG(F_CF);
HALT_SYS();
+ return 0;
} else {
-#else
- }
- {
-#endif
#ifdef CONFIG_PCI_OPTION_ROM_RUN_YABEL
switch (size) {
case 1:
- rval = pci_read_config8(bios_device.dev, offs);
+ rval = pci_read_config8(dev, offs);
break;
case 2:
- rval = pci_read_config16(bios_device.dev, offs);
+ rval = pci_read_config16(dev, offs);
break;
case 4:
- rval = pci_read_config32(bios_device.dev, offs);
+ rval = pci_read_config32(dev, offs);
break;
}
#else