All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Vladimir 'φ-coder/phcoder' Serbinenko" <phcoder@gmail.com>
To: The development of GRUB 2 <grub-devel@gnu.org>
Subject: [PATCH] byte-addressable grub_pci_make_address
Date: Tue, 22 Dec 2009 15:12:09 +0100	[thread overview]
Message-ID: <4B30D3B9.2010705@gmail.com> (raw)


[-- Attachment #1.1: Type: text/plain, Size: 330 bytes --]

Hello, I noticed that grub_pci_make_address addresses register on dword
boundaries whereas some important byte registers aren't dword-aligned.
It's impossible to access such registers in opaque way which is required
when using grub-emu with PCI support. Here is a fix

-- 
Regards
Vladimir 'φ-coder/phcoder' Serbinenko


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1.2: pciclean.diff --]
[-- Type: text/x-diff; name="pciclean.diff", Size: 11999 bytes --]

=== added file 'ChangeLog.pciclean'
--- ChangeLog.pciclean	1970-01-01 00:00:00 +0000
+++ ChangeLog.pciclean	2009-12-22 14:07:47 +0000
@@ -0,0 +1,52 @@
+2009-12-22  Vladimir Serbinenko  <phcoder@gmail.com>
+
+	Byte-addressable PCI configuration space.
+
+	* bus/pci.c (grub_pci_make_address): Use byte address instead of
+	dword address.
+	(grub_pci_iterate): Use macroses GRUB_PCI_REG_PCI_ID and
+	GRUB_PCI_REG_CACHELINE.
+	* bus/usb/ohci.c (grub_ohci_pci_iter): Use macroses
+	GRUB_PCI_REG_CLASS and GRUB_PCI_REG_ADDRESS_REG0.
+	* bus/usb/uhci.c (grub_ohci_pci_iter): Use macroses
+	GRUB_PCI_REG_CLASS and GRUB_PCI_REG_ADDRESS_REG4.
+	* commands/efi/fixvideo.c (scan_card): Use macros GRUB_PCI_REG_CLASS.
+	* commands/efi/loadbios.c (enable_rom_area): Pass byte-address to
+	grub_pci_make_address.
+	(lock_rom_area): Likewise.
+	* commands/lspci.c (grub_lspci_iter): Use macroses
+	GRUB_PCI_REG_CLASS and GRUB_PCI_REG_ADDRESSES. Handle byte-addressing
+	of grub_pci_make_address.
+	* disk/ata.c (grub_ata_pciinit): Likewise.
+	* include/grub/pci.h (GRUB_PCI_REG_PCI_ID): New macro.
+	(GRUB_PCI_REG_VENDOR): Likewise.
+	(GRUB_PCI_REG_DEVICE): Likewise.
+	(GRUB_PCI_REG_COMMAND): Likewise.
+	(GRUB_PCI_REG_STATUS): Likewise.
+	(GRUB_PCI_REG_REVISION): Likewise.
+	(GRUB_PCI_REG_CLASS): Likewise.
+	(GRUB_PCI_REG_CACHELINE): Likewise.
+	(GRUB_PCI_REG_LAT_TIMER): Likewise.
+	(GRUB_PCI_REG_HEADER_TYPE): Likewise.
+	(GRUB_PCI_REG_BIST): Likewise.
+	(GRUB_PCI_REG_ADDRESSES): Likewise.
+	(GRUB_PCI_REG_ADDRESS_REG): Likewise.
+	(GRUB_PCI_REG_ADDRESS_REG): Likewise.
+	(GRUB_PCI_REG_ADDRESS_REG): Likewise.
+	(GRUB_PCI_REG_ADDRESS_REG): Likewise.
+	(GRUB_PCI_REG_ADDRESS_REG): Likewise.
+	(GRUB_PCI_REG_ADDRESS_REG): Likewise.
+	(GRUB_PCI_REG_CIS_POINTER): Likewise.
+	(GRUB_PCI_REG_SUBVENDOR): Likewise.
+	(GRUB_PCI_REG_SUBSYSTEM): Likewise.
+	(GRUB_PCI_REG_ROM_ADDRESS): Likewise.
+	(GRUB_PCI_REG_CAP_POINTER): Likewise.
+	(GRUB_PCI_REG_IRQ_LINE): Likewise.
+	(GRUB_PCI_REG_IRQ_PIN): Likewise.
+	(GRUB_PCI_REG_MIN_GNT): Likewise.
+	(GRUB_PCI_REG_MAX_LAT): Likewise.
+	* loader/i386/efi/linux.c (find_framebuf): Use GRUB_PCI_REG_CLASS.
+	* loader/i386/efi/xnu.c (find_framebuf): Likewise.
+	* video/efi_uga.c (find_framebuf): Likewise.
+	* util/pci.c (grub_pci_make_address): Use byte-addressed configuration
+	space.

=== modified file 'bus/pci.c'
--- bus/pci.c	2009-10-14 08:11:59 +0000
+++ bus/pci.c	2009-12-22 12:02:51 +0000
@@ -24,7 +24,7 @@
 grub_pci_make_address (grub_pci_device_t dev, int reg)
 {
   return (1 << 31) | (dev.bus << 16) | (dev.device << 11)
-    | (dev.function << 8) | (reg << 2);
+    | (dev.function << 8) | reg;
 }
 
 void
@@ -41,7 +41,7 @@
 	{
 	  for (dev.function = 0; dev.function < 8; dev.function++)
 	    {
-	      addr = grub_pci_make_address (dev, 0);
+	      addr = grub_pci_make_address (dev, GRUB_PCI_REG_PCI_ID);
 	      id = grub_pci_read (addr);
 
 	      /* Check if there is a device present.  */
@@ -54,7 +54,7 @@
 	      /* Probe only func = 0 if the device if not multifunction */
 	      if (dev.function == 0)
 		{
-		  addr = grub_pci_make_address (dev, 3);
+		  addr = grub_pci_make_address (dev, GRUB_PCI_REG_CACHELINE);
 		  hdr = grub_pci_read (addr);
 		  if (!(hdr & 0x800000))
 		    break;

=== modified file 'bus/usb/ohci.c'
--- bus/usb/ohci.c	2009-10-14 08:11:59 +0000
+++ bus/usb/ohci.c	2009-12-22 11:52:59 +0000
@@ -126,7 +126,7 @@
   grub_uint32_t revision;
   grub_uint32_t frame_interval;
 
-  addr = grub_pci_make_address (dev, 2);
+  addr = grub_pci_make_address (dev, GRUB_PCI_REG_CLASS);
   class_code = grub_pci_read (addr) >> 8;
 
   interf = class_code & 0xFF;
@@ -138,7 +138,7 @@
     return 0;
 
   /* Determine IO base address.  */
-  addr = grub_pci_make_address (dev, 4);
+  addr = grub_pci_make_address (dev, GRUB_PCI_REG_ADDRESS_REG0);
   base = grub_pci_read (addr);
 
 #if 0

=== modified file 'bus/usb/uhci.c'
--- bus/usb/uhci.c	2009-12-22 09:15:59 +0000
+++ bus/usb/uhci.c	2009-12-22 11:51:58 +0000
@@ -150,7 +150,7 @@
   struct grub_uhci *u;
   int i;
 
-  addr = grub_pci_make_address (dev, 2);
+  addr = grub_pci_make_address (dev, GRUB_PCI_REG_CLASS);
   class_code = grub_pci_read (addr) >> 8;
 
   interf = class_code & 0xFF;
@@ -162,7 +162,7 @@
     return 0;
 
   /* Determine IO base address.  */
-  addr = grub_pci_make_address (dev, 8);
+  addr = grub_pci_make_address (dev, GRUB_PCI_REG_ADDRESS_REG4);
   base = grub_pci_read (addr);
   /* Stop if there is no IO space base address defined.  */
   if (! (base & 1))

=== modified file 'commands/efi/fixvideo.c'
--- commands/efi/fixvideo.c	2009-11-30 18:09:11 +0000
+++ commands/efi/fixvideo.c	2009-12-22 11:54:44 +0000
@@ -42,7 +42,7 @@
 {
   grub_pci_address_t addr;
 
-  addr = grub_pci_make_address (dev, 2);
+  addr = grub_pci_make_address (dev, GRUB_PCI_REG_CLASS);
   if (grub_pci_read_byte (addr + 3) == 0x3)
     {
       struct grub_video_patch *p = video_patches;

=== modified file 'commands/efi/loadbios.c'
--- commands/efi/loadbios.c	2009-12-21 22:06:04 +0000
+++ commands/efi/loadbios.c	2009-12-22 12:03:12 +0000
@@ -50,7 +50,7 @@
       return 0;
     }
 
-  addr = grub_pci_make_address (dev, 36);
+  addr = grub_pci_make_address (dev, 144);
   grub_pci_write_byte (addr++, 0x30);
   grub_pci_write_byte (addr++, 0x33);
   grub_pci_write_byte (addr++, 0x33);
@@ -76,7 +76,7 @@
   grub_pci_address_t addr;
   grub_pci_device_t dev = { .bus = 0, .device = 0, .function = 0};
 
-  addr = grub_pci_make_address (dev, 36);
+  addr = grub_pci_make_address (dev, 144);
   grub_pci_write_byte (addr++, 0x10);
   grub_pci_write_byte (addr++, 0x11);
   grub_pci_write_byte (addr++, 0x11);

=== modified file 'commands/lspci.c'
--- commands/lspci.c	2009-12-22 09:41:53 +0000
+++ commands/lspci.c	2009-12-22 11:59:48 +0000
@@ -134,7 +134,7 @@
   grub_printf ("%02x:%02x.%x %04x:%04x", grub_pci_get_bus (dev),
 	       grub_pci_get_device (dev), grub_pci_get_function (dev),
 	       pciid & 0xFFFF, pciid >> 16);
-  addr = grub_pci_make_address (dev, 2);
+  addr = grub_pci_make_address (dev, GRUB_PCI_REG_CLASS);
   class = grub_pci_read (addr);
 
   /* Lookup the class name, if there isn't a specific one,
@@ -155,14 +155,14 @@
 
   if (iospace)
     {
-      reg = 4;
-      while (reg < 10)
+      reg = GRUB_PCI_REG_ADDRESSES;
+      while (reg < GRUB_PCI_REG_CIS_POINTER)
 	{
 	  grub_uint64_t space;
 	  addr = grub_pci_make_address (dev, reg);
 	  space = grub_pci_read (addr);
 
-	  reg++;
+	  reg += sizeof (grub_uint32_t);
 	  
 	  if (space == 0)
 	    continue;
@@ -170,7 +170,9 @@
 	  switch (space & GRUB_PCI_ADDR_SPACE_MASK)
 	    {
 	    case GRUB_PCI_ADDR_SPACE_IO:
-	      grub_printf ("\tIO space %d at 0x%llx\n", (reg - 1) - 4,
+	      grub_printf ("\tIO space %d at 0x%llx\n",
+			   ((reg - GRUB_PCI_REG_ADDRESSES)
+			    / sizeof (grub_uint32_t)) - 1,
 			   (unsigned long long)
 			   (space & GRUB_PCI_ADDR_IO_MASK));
 	      break;
@@ -180,9 +182,11 @@
 		{
 		  addr = grub_pci_make_address (dev, reg);
 		  space |= ((grub_uint64_t) grub_pci_read (addr)) << 32;
-		  reg++;
+		  reg += sizeof (grub_uint32_t);
 		  grub_printf ("\t64-bit memory space %d at 0x%016llx [%s]\n",
-			       (reg - 2) - 4, (unsigned long long)
+			       ((reg - GRUB_PCI_REG_ADDRESSES)
+				/ sizeof (grub_uint32_t)) - 2,
+			       (unsigned long long)
 			       (space & GRUB_PCI_ADDR_MEM_MASK),
 			       space & GRUB_PCI_ADDR_MEM_PREFETCH
 			       ? "prefetchable" : "non-prefetchable");
@@ -190,7 +194,9 @@
 		}
 	      else
 		grub_printf ("\t32-bit memory space %d at 0x%016llx [%s]\n",
-			     (reg - 1) - 4, (unsigned long long) 
+			     ((reg - GRUB_PCI_REG_ADDRESSES)
+			      / sizeof (grub_uint32_t)) - 1,
+			     (unsigned long long) 
 			     (space & GRUB_PCI_ADDR_MEM_MASK),
 			     space & GRUB_PCI_ADDR_MEM_PREFETCH
 			     ? "prefetchable" : "non-prefetchable");

=== modified file 'disk/ata.c'
--- disk/ata.c	2009-11-23 10:15:24 +0000
+++ disk/ata.c	2009-12-22 12:01:23 +0000
@@ -402,7 +402,7 @@
   static int controller = 0;
 
   /* Read class.  */
-  addr = grub_pci_make_address (dev, 2);
+  addr = grub_pci_make_address (dev, GRUB_PCI_REG_CLASS);
   class = grub_pci_read (addr);
 
   /* Check if this class ID matches that of a PCI IDE Controller.  */
@@ -429,9 +429,12 @@
 	{
 	  /* Read the BARs, which either contain a mmapped IO address
 	     or the IO port address.  */
-	  addr = grub_pci_make_address (dev, 4 + 2 * i);
+	  addr = grub_pci_make_address (dev, GRUB_PCI_REG_ADDRESSES
+					+ sizeof (grub_uint64_t) * i);
 	  bar1 = grub_pci_read (addr);
-	  addr = grub_pci_make_address (dev, 5 + 2 * i);
+	  addr = grub_pci_make_address (dev, GRUB_PCI_REG_ADDRESSES
+					+ sizeof (grub_uint64_t) * i
+					+ sizeof (grub_uint32_t));
 	  bar2 = grub_pci_read (addr);
 
 	  /* Check if the BARs describe an IO region.  */

=== modified file 'include/grub/pci.h'
--- include/grub/pci.h	2009-10-14 08:11:59 +0000
+++ include/grub/pci.h	2009-12-22 14:04:55 +0000
@@ -35,6 +35,37 @@
 #define  GRUB_PCI_ADDR_MEM_MASK		~0xf
 #define  GRUB_PCI_ADDR_IO_MASK		~0x03
 
+#define  GRUB_PCI_REG_PCI_ID       0x00
+#define  GRUB_PCI_REG_VENDOR       0x00
+#define  GRUB_PCI_REG_DEVICE       0x02
+#define  GRUB_PCI_REG_COMMAND      0x04
+#define  GRUB_PCI_REG_STATUS       0x06
+#define  GRUB_PCI_REG_REVISION     0x08
+#define  GRUB_PCI_REG_CLASS        0x08
+#define  GRUB_PCI_REG_CACHELINE    0x0c
+#define  GRUB_PCI_REG_LAT_TIMER    0x0d
+#define  GRUB_PCI_REG_HEADER_TYPE  0x0e
+#define  GRUB_PCI_REG_BIST         0x0f
+#define  GRUB_PCI_REG_ADDRESSES    0x10
+
+/* Beware that 64-bit address takes 2 registers.  */
+#define  GRUB_PCI_REG_ADDRESS_REG0 0x10
+#define  GRUB_PCI_REG_ADDRESS_REG1 0x14
+#define  GRUB_PCI_REG_ADDRESS_REG2 0x18
+#define  GRUB_PCI_REG_ADDRESS_REG3 0x1c
+#define  GRUB_PCI_REG_ADDRESS_REG4 0x20
+#define  GRUB_PCI_REG_ADDRESS_REG5 0x24
+
+#define  GRUB_PCI_REG_CIS_POINTER  0x28
+#define  GRUB_PCI_REG_SUBVENDOR    0x2c
+#define  GRUB_PCI_REG_SUBSYSTEM    0x2e
+#define  GRUB_PCI_REG_ROM_ADDRESS  0x30
+#define  GRUB_PCI_REG_CAP_POINTER  0x34
+#define  GRUB_PCI_REG_IRQ_LINE     0x3c
+#define  GRUB_PCI_REG_IRQ_PIN      0x3d
+#define  GRUB_PCI_REG_MIN_GNT      0x3e
+#define  GRUB_PCI_REG_MAX_LAT      0x3f
+
 typedef grub_uint32_t grub_pci_id_t;
 
 #ifdef GRUB_UTIL

=== modified file 'loader/i386/efi/linux.c'
--- loader/i386/efi/linux.c	2009-11-30 18:09:11 +0000
+++ loader/i386/efi/linux.c	2009-12-22 12:01:48 +0000
@@ -477,7 +477,7 @@
     {
       grub_pci_address_t addr;
 
-      addr = grub_pci_make_address (dev, 2);
+      addr = grub_pci_make_address (dev, GRUB_PCI_REG_CLASS);
       if (grub_pci_read (addr) >> 24 == 0x3)
 	{
 	  int i;

=== modified file 'loader/i386/efi/xnu.c'
--- loader/i386/efi/xnu.c	2009-11-30 18:09:11 +0000
+++ loader/i386/efi/xnu.c	2009-12-22 12:02:02 +0000
@@ -79,7 +79,7 @@
     {
       grub_pci_address_t addr;
 
-      addr = grub_pci_make_address (dev, 2);
+      addr = grub_pci_make_address (dev, GRUB_PCI_REG_CLASS);
       if (grub_pci_read (addr) >> 24 == 0x3)
 	{
 	  int i;

=== modified file 'util/pci.c'
--- util/pci.c	2009-12-11 21:12:57 +0000
+++ util/pci.c	2009-12-22 12:02:33 +0000
@@ -26,7 +26,7 @@
 {
   grub_pci_address_t ret;
   ret.dev = dev;
-  ret.pos = reg << 2;
+  ret.pos = reg;
   return ret;
 }
 

=== modified file 'video/efi_uga.c'
--- video/efi_uga.c	2009-11-30 18:09:11 +0000
+++ video/efi_uga.c	2009-12-22 12:02:17 +0000
@@ -92,7 +92,7 @@
     {
       grub_pci_address_t addr;
 
-      addr = grub_pci_make_address (dev, 2);
+      addr = grub_pci_make_address (dev, GRUB_PCI_REG_CLASS);
       if (grub_pci_read (addr) >> 24 == 0x3)
 	{
 	  int i;


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 293 bytes --]

             reply	other threads:[~2009-12-22 14:12 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-12-22 14:12 Vladimir 'φ-coder/phcoder' Serbinenko [this message]
2009-12-24 21:50 ` [PATCH] byte-addressable grub_pci_make_address Robert Millan
2009-12-24 22:16   ` Seth Goldberg

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=4B30D3B9.2010705@gmail.com \
    --to=phcoder@gmail.com \
    --cc=grub-devel@gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.