@@ -98,6 +98,14 @@ pci_read_long(struct pci_dev *d, int pos)
return le32_to_cpu(buf);
}
+u64
+pci_read_quad(struct pci_dev *d, int pos)
+{
+ u64 buf;
+ pci_read_data(d, &buf, pos, 8);
+ return le64_to_cpu(buf);
+}
+
int
pci_read_block(struct pci_dev *d, int pos, byte *buf, int len)
{
@@ -141,6 +149,13 @@ pci_write_long(struct pci_dev *d, int pos, u32 data)
}
int
+pci_write_quad(struct pci_dev *d, int pos, u64 data)
+{
+ u64 buf = cpu_to_le64(data);
+ return pci_write_data(d, &buf, pos, 8);
+}
+
+int
pci_write_block(struct pci_dev *d, int pos, byte *buf, int len)
{
if (pos < d->cache_len)
@@ -147,11 +147,13 @@ struct pci_dev {
u8 pci_read_byte(struct pci_dev *, int pos) PCI_ABI; /* Access to configuration space */
u16 pci_read_word(struct pci_dev *, int pos) PCI_ABI;
u32 pci_read_long(struct pci_dev *, int pos) PCI_ABI;
+u64 pci_read_quad(struct pci_dev *, int pos) PCI_ABI;
int pci_read_block(struct pci_dev *, int pos, u8 *buf, int len) PCI_ABI;
int pci_read_vpd(struct pci_dev *d, int pos, u8 *buf, int len) PCI_ABI;
int pci_write_byte(struct pci_dev *, int pos, u8 data) PCI_ABI;
int pci_write_word(struct pci_dev *, int pos, u16 data) PCI_ABI;
int pci_write_long(struct pci_dev *, int pos, u32 data) PCI_ABI;
+int pci_write_quad(struct pci_dev *, int pos, u64 data) PCI_ABI;
int pci_write_block(struct pci_dev *, int pos, u8 *buf, int len) PCI_ABI;
int pci_fill_info(struct pci_dev *, int flags) PCI_ABI; /* Fill in device information */
@@ -27,8 +27,10 @@ typedef u16 word;
#include <asm/byteorder.h>
#define cpu_to_le16 __cpu_to_le16
#define cpu_to_le32 __cpu_to_le32
+#define cpu_to_le64 __cpu_to_le64
#define le16_to_cpu __le16_to_cpu
#define le32_to_cpu __le32_to_cpu
+#define le64_to_cpu __le64_to_cpu
#else
@@ -63,8 +65,10 @@ typedef u16 word;
#if BYTE_ORDER == BIG_ENDIAN
#define cpu_to_le16 swab16
#define cpu_to_le32 swab32
+#define cpu_to_le64 swab64
#define le16_to_cpu swab16
#define le32_to_cpu swab32
+#define le64_to_cpu swab64
static inline word swab16(word w)
{
@@ -78,11 +82,25 @@ static inline u32 swab32(u32 w)
((w & 0x0000ff00) << 8) |
((w & 0x000000ff) << 24);
}
+
+static inline u64 swab64(u64 w)
+{
+ return ((w & 0xff00000000000000) >> 56) |
+ ((w & 0x00ff000000000000) >> 40) |
+ ((w & 0x0000ff0000000000) >> 24) |
+ ((w & 0x000000ff00000000) >> 8) |
+ ((w & 0x00000000ff000000) << 8) |
+ ((w & 0x0000000000ff0000) << 24) |
+ ((w & 0x000000000000ff00) << 40) |
+ ((w & 0x00000000000000ff) << 56);
+}
#else
#define cpu_to_le16(x) (x)
#define cpu_to_le32(x) (x)
+#define cpu_to_le64(x) (x)
#define le16_to_cpu(x) (x)
#define le32_to_cpu(x) (x)
+#define le64_to_cpu(x) (x)
#endif
#endif
@@ -15,24 +15,25 @@
typedef BYTE u8;
typedef WORD u16;
typedef DWORD u32;
+typedef QWORD u64;
#elif defined(PCI_HAVE_STDINT_H) || (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L)
#include <stdint.h>
typedef uint8_t u8;
typedef uint16_t u16;
typedef uint32_t u32;
+typedef uint64_t u64;
#else
typedef u_int8_t u8;
typedef u_int16_t u16;
typedef u_int32_t u32;
+typedef u_int64_t u64;
#endif
#ifdef PCI_HAVE_64BIT_ADDRESS
#include <limits.h>
#if ULONG_MAX > 0xffffffff
-typedef unsigned long u64;
#define PCI_U64_FMT "l"
#else
-typedef unsigned long long u64;
#define PCI_U64_FMT "ll"
#endif
#endif
@@ -12,6 +12,7 @@
#include <stdarg.h>
#include <unistd.h>
#include <errno.h>
+#include <inttypes.h>
#define PCIUTILS_SETPCI
#include "pciutils.h"
@@ -73,9 +74,10 @@ trace(const char *fmt, ...)
static void
exec_op(struct op *op, struct pci_dev *dev)
{
- const char * const formats[] = { NULL, " %02x", " %04x", NULL, " %08x" };
- const char * const mask_formats[] = { NULL, " %02x->(%02x:%02x)->%02x", " %04x->(%04x:%04x)->%04x", NULL, " %08x->(%08x:%08x)->%08x" };
- unsigned int i, x, y;
+ const char * const formats[] = { NULL, " %02x", " %04x", NULL, " %08x", NULL, NULL, NULL, " %016" PRIu64 "x"};
+ const char * const mask_formats[] = { NULL, " %02x->(%02x:%02x)->%02x", " %04x->(%04x:%04x)->%04x", NULL, " %08x->(%08x:%08x)->%08x", NULL, NULL, NULL, " %016" PRIu64 "x->(%016" PRIu64 "x:%016" PRIu64 "x)->%016" PRIu64 "x"};
+ unsigned int i;
+ u64 x, y;
int addr = 0;
int width = op->width;
char slot[16];
@@ -120,6 +122,9 @@ exec_op(struct op *op, struct pci_dev *dev)
case 2:
y = pci_read_word(dev, addr);
break;
+ case 8:
+ y = pci_read_quad(dev, addr);
+ break;
default:
y = pci_read_long(dev, addr);
break;
@@ -137,6 +142,9 @@ exec_op(struct op *op, struct pci_dev *dev)
case 2:
pci_write_word(dev, addr, x);
break;
+ case 8:
+ pci_write_quad(dev, addr, x);
+ break;
default:
pci_write_long(dev, addr, x);
break;
@@ -157,6 +165,9 @@ exec_op(struct op *op, struct pci_dev *dev)
case 2:
x = pci_read_word(dev, addr);
break;
+ case 8:
+ x = pci_read_quad(dev, addr);
+ break;
default:
x = pci_read_long(dev, addr);
break;
@@ -600,6 +611,8 @@ static void parse_op(char *c, struct pci_dev **selected_devices)
op->width = 2; break;
case 'L':
op->width = 4; break;
+ case 'Q':
+ op->width = 8; break;
default:
parse_err("Invalid width \"%c\"", *width);
}
Signed-off-by: Warren Turkal <turkal@google.com> --- lib/access.c | 15 +++++++++++++++ lib/pci.h | 2 ++ lib/sysdep.h | 18 ++++++++++++++++++ lib/types.h | 5 +++-- setpci.c | 19 ++++++++++++++++--- 5 files changed, 54 insertions(+), 5 deletions(-)