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 --]
next 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.