grr... too quick on the send button... here are the patch files...

Patty

On Wed, Mar 18, 2009 at 4:18 PM, Pattrick Hueper <[email protected]> wrote:
> Hi,
>
> Joseph and Stefan have had some fun using yabel on devices with
> (intel?) onboard graphics cards. We found that those devices want to
> read config space of other devices than the one yabel is running for.
> This was previously impossible.
>
> These patches introduce a yabel option
> CONFIG_YABEL_ACCESS_OTHER_DEVICES that when set to 1/true allows
> Option ROMs to find and access (read-only) other devices' config
> space. Both through INT1A functions and cf8/cfc IO ports.
>
> This allows the mentioned onboard graphics cards to be initialized by yabel.
>
> The two 0001 patches add the corresponding Option to
> Kconfig/Options.lb for v3/v2, the 0002 patch adds the functionality to
> yabel.
>
> Signed-off-by: Pattrick Hueper <[email protected]>
>
> Patty
>
From 9db4c97378a7a7cf655f322bc3ce5364e0cbcf42 Mon Sep 17 00:00:00 2001
From: Pattrick Hueper <[email protected]>
Date: Mon, 16 Mar 2009 10:04:22 +0100
Subject: [PATCH] add YABEL flag to options to decide wether access to devices other than the one yabel is running for is possible

Signed-off-by: Pattrick Hueper <[email protected]>
---
 src/config/Options.lb |    7 +++++++
 1 files changed, 7 insertions(+), 0 deletions(-)

diff --git a/src/config/Options.lb b/src/config/Options.lb
index 4bc20c6..9a2101f 100644
--- a/src/config/Options.lb
+++ b/src/config/Options.lb
@@ -1093,6 +1093,13 @@ define CONFIG_YABEL_DEBUG_FLAGS
 	comment "YABEL debug flags, for possible values, see util/x86emu/yabel/debug.h"
 end
 
+define CONFIG_YABEL_PCI_ACCESS_OTHER_DEVICES
+	default 0
+	export used
+	comment "Allow Option ROMs executed by YABEL to access the config space of devices other than the one YABEL is running for. This may be needed by some onboard Graphics cards ROMs."
+
+end
+
 define CONFIG_PCI_OPTION_ROM_RUN_VM86
 	default 0
 	export used
-- 
1.6.2

From 940cc8fa4dfbdb519e5602e958aa4a30da558f2b Mon Sep 17 00:00:00 2001
From: Pattrick Hueper <[email protected]>
Date: Mon, 16 Mar 2009 10:14:50 +0100
Subject: [PATCH 1/2] add YABEL flag to options to decide wether access to devices other than the one yabel is running for is possible

Signed-off-by: Pattrick Hueper <[email protected]>
---
 device/Kconfig |    8 ++++++++
 1 files changed, 8 insertions(+), 0 deletions(-)

diff --git a/device/Kconfig b/device/Kconfig
index ac37cdc..2fa9927 100644
--- a/device/Kconfig
+++ b/device/Kconfig
@@ -111,6 +111,14 @@ menu "Advanced YABEL Settings"
 		help
 		  Set YABEL debug flags, for possible values, see util/x86emu/yabel/debug.h
 
+	config YABEL_PCI_ACCESS_OTHER_DEVICES
+		bool "Allow PCI Config Access to other devices"
+		default n
+		help
+		  Allow Option ROMs executed by YABEL to access the config
+		  space of devices other than the one YABEL is running for.
+		  This may be needed by some onboard Graphics cards ROMs.
+
 endmenu
 
 # TODO: This should probably become a CMOS option.
-- 
1.6.2

From f84b9145116669b0539a78d6f4fef72944e0b510 Mon Sep 17 00:00:00 2001
From: Pattrick Hueper <[email protected]>
Date: Sat, 14 Mar 2009 00:42:26 +0100
Subject: [PATCH 2/2] "other device" support for YABEL PCI Config Space Accesses

This patch makes it possible for Option ROMs to access devices
other than the one YABEL is running for. This is needed for some
onboard Graphics Cards Option ROMs.

Signed-off-by: Pattrick Hueper <[email protected]>
---
 util/x86emu/yabel/interrupt.c |   58 ++++++++++++++++++++++++++++++----------
 util/x86emu/yabel/io.c        |   32 +++++++++++++++--------
 2 files changed, 64 insertions(+), 26 deletions(-)

diff --git a/util/x86emu/yabel/interrupt.c b/util/x86emu/yabel/interrupt.c
index 03614c0..9cb0f13 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 aa0b385..6380ec3 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
-- 
1.6.2

-- 
coreboot mailing list: [email protected]
http://www.coreboot.org/mailman/listinfo/coreboot

Reply via email to