* [PATCH] byte-addressable grub_pci_make_address
@ 2009-12-22 14:12 Vladimir 'φ-coder/phcoder' Serbinenko
2009-12-24 21:50 ` Robert Millan
0 siblings, 1 reply; 3+ messages in thread
From: Vladimir 'φ-coder/phcoder' Serbinenko @ 2009-12-22 14:12 UTC (permalink / raw)
To: The development of GRUB 2
[-- 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 --]
^ permalink raw reply [flat|nested] 3+ messages in thread* Re: [PATCH] byte-addressable grub_pci_make_address
2009-12-22 14:12 [PATCH] byte-addressable grub_pci_make_address Vladimir 'φ-coder/phcoder' Serbinenko
@ 2009-12-24 21:50 ` Robert Millan
2009-12-24 22:16 ` Seth Goldberg
0 siblings, 1 reply; 3+ messages in thread
From: Robert Millan @ 2009-12-24 21:50 UTC (permalink / raw)
To: The development of GNU GRUB
On Tue, Dec 22, 2009 at 03:12:09PM +0100, Vladimir 'φ-coder/phcoder' Serbinenko wrote:
> === 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);
These look like black magic. Could they be macroified instead?
--
Robert Millan
"Be the change you want to see in the world" -- Gandhi
^ permalink raw reply [flat|nested] 3+ messages in thread* Re: [PATCH] byte-addressable grub_pci_make_address
2009-12-24 21:50 ` Robert Millan
@ 2009-12-24 22:16 ` Seth Goldberg
0 siblings, 0 replies; 3+ messages in thread
From: Seth Goldberg @ 2009-12-24 22:16 UTC (permalink / raw)
To: The development of GNU GRUB
[-- Attachment #1: Type: TEXT/PLAIN, Size: 1355 bytes --]
What's the basis for these writes, btw? I askesd a while ago but no one
seemed to know. Feel free to point me to a chipset datasheet, but right now
this code truly a black box :).
--S
Quoting Robert Millan, who wrote the following on Thu, 24 Dec 2009:
> On Tue, Dec 22, 2009 at 03:12:09PM +0100, Vladimir 'φ-coder/phcoder' Serbinenko wrote:
>> === 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);
>
> These look like black magic. Could they be macroified instead?
>
> --
> Robert Millan
>
> "Be the change you want to see in the world" -- Gandhi
>
>
> _______________________________________________
> Grub-devel mailing list
> Grub-devel@gnu.org
> http://lists.gnu.org/mailman/listinfo/grub-devel
>
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2009-12-24 22:19 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-12-22 14:12 [PATCH] byte-addressable grub_pci_make_address Vladimir 'φ-coder/phcoder' Serbinenko
2009-12-24 21:50 ` Robert Millan
2009-12-24 22:16 ` Seth Goldberg
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.