bug-hurd
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH] New module for the Hurd.


From: Joan Lledó
Subject: [PATCH] New module for the Hurd.
Date: Sun, 3 Dec 2017 11:21:56 +0100

This new module uses Hurd's RPCs for accessing the PCI configuration space.
Direct access as in {read_write}_{8,16,32} functions is done by the old x86
module.

Some x86 function prototypes are now declared in a new header for the Hurd
module to use them, in order to duplicate as little code as possible.
---
 src/Makefile.am         |   4 +-
 src/common_init.c       |   4 +-
 src/hurd_pci.c          | 492 ++++++++++++++++++++++++++++++++++++++++++++++++
 src/pciaccess_private.h |   9 +
 src/x86_pci.c           |  54 ++----
 src/x86_pci.h           |  77 ++++++++
 6 files changed, 600 insertions(+), 40 deletions(-)
 create mode 100644 src/hurd_pci.c
 create mode 100644 src/x86_pci.h

diff --git a/src/Makefile.am b/src/Makefile.am
index 3a46a85..f222aa5 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -52,12 +52,12 @@ VGA_ARBITER = common_vgaarb_stub.c
 endif
 
 if GNU
-OS_SUPPORT = x86_pci.c
+OS_SUPPORT = hurd_pci.c x86_pci.c x86_pci.h
 VGA_ARBITER = common_vgaarb_stub.c
 endif
 
 if CYGWIN
-OS_SUPPORT = x86_pci.c
+OS_SUPPORT = x86_pci.c x86_pci.h
 VGA_ARBITER = common_vgaarb_stub.c
 endif
 
diff --git a/src/common_init.c b/src/common_init.c
index b1c0c3e..21572ee 100644
--- a/src/common_init.c
+++ b/src/common_init.c
@@ -62,7 +62,9 @@ pci_system_init( void )
     err = pci_system_openbsd_create();
 #elif defined(__sun)
     err = pci_system_solx_devfs_create();
-#elif defined(__GNU__) || defined(__CYGWIN__)
+#elif defined(__GNU__)
+    err = pci_system_hurd_create();
+#elif defined(__CYGWIN__)
     err = pci_system_x86_create();
 #else
 # error "Unsupported OS"
diff --git a/src/hurd_pci.c b/src/hurd_pci.c
new file mode 100644
index 0000000..10758c0
--- /dev/null
+++ b/src/hurd_pci.c
@@ -0,0 +1,492 @@
+/*
+ * Copyright (c) 2017, Joan Lledó
+ * Copyright (c) 2009, 2012 Samuel Thibault
+ * Heavily inspired from the freebsd, netbsd, and openbsd backends
+ * (C) Copyright Eric Anholt 2006
+ * (C) Copyright IBM Corporation 2006
+ * Copyright (c) 2008 Juan Romero Pardines
+ * Copyright (c) 2008 Mark Kettenis
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#define _GNU_SOURCE
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <dirent.h>
+#include <sys/mman.h>
+#include <string.h>
+#include <strings.h>
+#include <hurd.h>
+#include <hurd/pci.h>
+#include <hurd/paths.h>
+
+#include "x86_pci.h"
+#include "pciaccess.h"
+#include "pciaccess_private.h"
+
+/*
+ * Hurd PCI access using RPCs.
+ *
+ * Some functions are shared with the x86 module to avoid repeating code.
+ */
+
+/* Server path */
+#define _SERVERS_PCI_CONF      _SERVERS_BUS "/pci"
+
+/* File names */
+#define FILE_CONFIG_NAME "config"
+#define FILE_ROM_NAME "rom"
+
+/* Level in the fs tree */
+typedef enum {
+    LEVEL_NONE,
+    LEVEL_DOMAIN,
+    LEVEL_BUS,
+    LEVEL_DEV,
+    LEVEL_FUNC
+} tree_level;
+
+struct pci_system_hurd {
+    struct pci_system system;
+};
+
+static int
+pci_device_hurd_probe(struct pci_device *dev)
+{
+    uint8_t irq;
+    int err, i;
+    struct pci_bar regions[6];
+    struct pci_xrom_bar rom;
+    struct pci_device_private *d;
+    size_t size;
+    char *buf;
+
+    /* Many of the fields were filled in during initial device enumeration.
+     * At this point, we need to fill in regions, rom_size, and irq.
+     */
+
+    err = pci_device_cfg_read_u8(dev, &irq, PCI_IRQ);
+    if (err)
+        return err;
+    dev->irq = irq;
+
+    /* Get regions */
+    buf = (char *)&regions;
+    size = sizeof(regions);
+    d = (struct pci_device_private *)dev;
+    err = pci_get_dev_regions(d->device_port, &buf, &size);
+    if(err)
+        return err;
+
+    if((char*)&regions != buf)
+    {
+        /* Sanity check for bogus server.  */
+        if(size > sizeof(regions))
+        {
+            vm_deallocate(mach_task_self(), (vm_address_t) buf, size);
+            return EGRATUITOUS;
+        }
+
+        memcpy(&regions, buf, size);
+        vm_deallocate(mach_task_self(), (vm_address_t) buf, size);
+    }
+
+    for(i=0; i<6; i++)
+    {
+        if(regions[i].size == 0)
+          continue;
+
+        dev->regions[i].base_addr = regions[i].base_addr;
+        dev->regions[i].size = regions[i].size;
+        dev->regions[i].is_IO = regions[i].is_IO;
+        dev->regions[i].is_prefetchable = regions[i].base_addr;
+        dev->regions[i].is_64 = regions[i].is_64;
+    }
+
+    /* Get rom info */
+    buf = (char *)&rom;
+    size = sizeof(rom);
+    err = pci_get_dev_rom(d->device_port, &buf, &size);
+    if(err)
+        return err;
+
+    if((char*)&rom != buf)
+    {
+        /* Sanity check for bogus server.  */
+        if(size > sizeof(rom))
+        {
+            vm_deallocate(mach_task_self(), (vm_address_t) buf, size);
+            return EGRATUITOUS;
+        }
+
+        memcpy(&rom, buf, size);
+        vm_deallocate(mach_task_self(), (vm_address_t) buf, size);
+    }
+
+    d->rom_base = rom.base_addr;
+    dev->rom_size = rom.size;
+
+    return 0;
+}
+
+/*
+ * Read `nbytes' bytes from `reg' in device's configuretion space
+ * and store them in `buf'.
+ *
+ * It's assumed that `nbytes' bytes are allocated in `buf'
+ */
+static int
+pciclient_cfg_read(mach_port_t device_port, int reg, char *buf,
+                   size_t * nbytes)
+{
+    int err;
+    size_t nread;
+    char *data;
+
+    data = buf;
+    nread = *nbytes;
+    err = pci_conf_read(device_port, reg, &data, &nread, *nbytes);
+    if (err)
+        return err;
+
+    if (data != buf) {
+        if (nread > *nbytes)   /* Sanity check for bogus server.  */ {
+                vm_deallocate(mach_task_self(), (vm_address_t) data, nread);
+                return EGRATUITOUS;
+        }
+
+        memcpy(buf, data, nread);
+        vm_deallocate(mach_task_self(), (vm_address_t)data, nread);
+    }
+
+    *nbytes = nread;
+
+    return 0;
+}
+
+/* Write `nbytes' bytes from `buf' to `reg' in device's configuration space */
+static int
+pciclient_cfg_write(mach_port_t device_port, int reg, char *buf,
+                    size_t * nbytes)
+{
+    int err;
+    size_t nwrote;
+
+    err = pci_conf_write(device_port, reg, buf, *nbytes, &nwrote);
+
+    if (!err)
+        *nbytes = nwrote;
+
+    return err;
+}
+
+/*
+ * Read up to `size' bytes from `dev' configuration space to `data' starting
+ * at `offset'. Write the amount on read bytes in `bytes_read'.
+ */
+static int
+pci_device_hurd_read(struct pci_device *dev, void *data,
+    pciaddr_t offset, pciaddr_t size, pciaddr_t *bytes_read)
+{
+    int err;
+    struct pci_device_private *d;
+
+    *bytes_read = 0;
+    d = (struct pci_device_private *)dev;
+    while (size > 0) {
+        size_t toread = 1 << (ffs(0x4 + (offset & 0x03)) - 1);
+        if (toread > size)
+            toread = size;
+
+        err = pciclient_cfg_read(d->device_port, offset, (char*)data,
+                                 &toread);
+        if (err)
+            return err;
+
+        offset += toread;
+        data = (char*)data + toread;
+        size -= toread;
+        *bytes_read += toread;
+    }
+    return 0;
+}
+
+/*
+ * Write up to `size' bytes from `data' to `dev' configuration space starting
+ * at `offset'. Write the amount on written bytes in `bytes_written'.
+ */
+static int
+pci_device_hurd_write(struct pci_device *dev, const void *data,
+    pciaddr_t offset, pciaddr_t size, pciaddr_t *bytes_written)
+{
+    int err;
+    struct pci_device_private *d;
+
+    *bytes_written = 0;
+    d = (struct pci_device_private *)dev;
+    while (size > 0) {
+        size_t towrite = 4;
+        if (towrite > size)
+            towrite = size;
+        if (towrite > 4 - (offset & 0x3))
+            towrite = 4 - (offset & 0x3);
+
+        err = pciclient_cfg_write(d->device_port, offset, (char*)data,
+                                  &towrite);
+        if (err)
+            return err;
+
+        offset += towrite;
+        data = (const char*)data + towrite;
+        size -= towrite;
+        *bytes_written += towrite;
+    }
+    return 0;
+}
+
+/*
+ * Copy the device's firmware in `buffer'
+ */
+static int
+pci_device_hurd_read_rom(struct pci_device * dev, void * buffer)
+{
+    void *rom;
+    int romfd;
+    char server[NAME_MAX];
+
+    snprintf(server, NAME_MAX, "%s/%04x/%02x/%02x/%01u/%s", _SERVERS_PCI_CONF,
+             dev->domain, dev->bus, dev->dev, dev->func, FILE_ROM_NAME);
+    romfd = open(server, O_RDONLY | O_CLOEXEC);
+    if (romfd == -1)
+        return errno;
+
+    rom = mmap(NULL, dev->rom_size, PROT_READ, 0, romfd, 0);
+    if (rom == MAP_FAILED) {
+        close(romfd);
+        return errno;
+    }
+
+    memcpy(buffer, rom, dev->rom_size);
+
+    munmap(rom, dev->rom_size);
+    close(romfd);
+
+    return 0;
+}
+
+/*
+ * Each device has its own server where send RPC's to.
+ *
+ * Deallocate the port before destroying the device.
+ */
+static void
+pci_device_hurd_destroy(struct pci_device *dev)
+{
+    struct pci_device_private *d = (struct pci_device_private*) dev;
+
+    mach_port_deallocate (mach_task_self (), d->device_port);
+}
+
+/* Walk through the FS tree to see what is allowed for us */
+static int
+enum_devices(const char *parent, struct pci_device_private **device,
+                int domain, int bus, int dev, int func, tree_level lev)
+{
+    int err, ret;
+    DIR *dir;
+    struct dirent *entry;
+    char path[NAME_MAX];
+    char server[NAME_MAX];
+    uint32_t reg;
+    size_t toread;
+    mach_port_t device_port;
+
+    dir = opendir(parent);
+    if (!dir)
+        return errno;
+
+    while ((entry = readdir(dir)) != 0) {
+        snprintf(path, NAME_MAX, "%s/%s", parent, entry->d_name);
+        if (entry->d_type == DT_DIR) {
+            if (!strncmp(entry->d_name, ".", NAME_MAX)
+                || !strncmp(entry->d_name, "..", NAME_MAX))
+                continue;
+
+            errno = 0;
+            ret = strtol(entry->d_name, 0, 16);
+            if (errno)
+                return errno;
+
+            /*
+             * We found a valid directory.
+             * Update the address and switch to the next level.
+             */
+            switch (lev) {
+            case LEVEL_DOMAIN:
+                domain = ret;
+                break;
+            case LEVEL_BUS:
+                bus = ret;
+                break;
+            case LEVEL_DEV:
+                dev = ret;
+                break;
+            case LEVEL_FUNC:
+                func = ret;
+                break;
+            default:
+                return -1;
+            }
+
+            err = enum_devices(path, device, domain, bus, dev, func, lev+1);
+            if (err == EPERM)
+                continue;
+        }
+        else {
+            if (strncmp(entry->d_name, FILE_CONFIG_NAME, NAME_MAX))
+                /* We are looking for the config file */
+                continue;
+
+            /* We found an available virtual device, add it to our list */
+            snprintf(server, NAME_MAX, "%s/%04x/%02x/%02x/%01u/%s",
+                     _SERVERS_PCI_CONF, domain, bus, dev, func,
+                     entry->d_name);
+            device_port = file_name_lookup(server, 0, 0);
+            if (device_port == MACH_PORT_NULL)
+                return errno;
+
+            toread = sizeof(reg);
+            err = pciclient_cfg_read(device_port, PCI_VENDOR_ID, (char*)&reg,
+                                     &toread);
+            if (err)
+                return err;
+            if (toread != sizeof(reg))
+                return -1;
+
+            (*device)->base.domain = domain;
+            (*device)->base.bus = bus;
+            (*device)->base.dev = dev;
+            (*device)->base.func = func;
+            (*device)->base.vendor_id = PCI_VENDOR(reg);
+            (*device)->base.device_id = PCI_DEVICE(reg);
+
+            toread = sizeof(reg);
+            err = pciclient_cfg_read(device_port, PCI_CLASS, (char*)&reg,
+                                     &toread);
+            if (err)
+                return err;
+            if (toread != sizeof(reg))
+                return -1;
+
+            (*device)->base.device_class = reg >> 8;
+            (*device)->base.revision = reg & 0xFF;
+
+            toread = sizeof(reg);
+            err = pciclient_cfg_read(device_port, PCI_SUB_VENDOR_ID,
+                                     (char*)&reg, &toread);
+            if (err)
+                return err;
+            if (toread != sizeof(reg))
+                return -1;
+
+            (*device)->base.subvendor_id = PCI_VENDOR(reg);
+            (*device)->base.subdevice_id = PCI_DEVICE(reg);
+
+            (*device)->device_port = device_port;
+
+            (*device)++;
+        }
+    }
+
+    return 0;
+}
+
+static const struct pci_system_methods hurd_pci_methods = {
+    .destroy = pci_system_x86_destroy,
+    .destroy_device = pci_device_hurd_destroy,
+    .read_rom = pci_device_hurd_read_rom,
+    .probe = pci_device_hurd_probe,
+    .map_range = pci_device_x86_map_range,
+    .unmap_range = pci_device_x86_unmap_range,
+    .read = pci_device_hurd_read,
+    .write = pci_device_hurd_write,
+    .fill_capabilities = pci_fill_capabilities_generic,
+    .open_legacy_io = pci_device_x86_open_legacy_io,
+    .close_io = pci_device_x86_close_io,
+    .read32 = pci_device_x86_read32,
+    .read16 = pci_device_x86_read16,
+    .read8 = pci_device_x86_read8,
+    .write32 = pci_device_x86_write32,
+    .write16 = pci_device_x86_write16,
+    .write8 = pci_device_x86_write8,
+    .map_legacy = pci_device_x86_map_legacy,
+    .unmap_legacy = pci_device_x86_unmap_legacy,
+};
+
+_pci_hidden int
+pci_system_hurd_create(void)
+{
+    struct pci_device_private *device;
+    int err;
+    struct pci_system_hurd *pci_sys_hurd;
+    size_t ndevs;
+    mach_port_t pci_server_port;
+
+    err = x86_enable_io();
+    if (err)
+        return err;
+
+    pci_sys_hurd = calloc(1, sizeof(struct pci_system_hurd));
+    if (pci_sys_hurd == NULL) {
+        x86_disable_io();
+        return ENOMEM;
+    }
+    pci_sys = &pci_sys_hurd->system;
+
+    pci_sys->methods = &hurd_pci_methods;
+
+    pci_server_port = file_name_lookup(_SERVERS_PCI_CONF, 0, 0);
+    if (pci_server_port == MACH_PORT_NULL)
+        return errno;
+
+    /* The server gives us the number of available devices for us */
+    err = pci_get_ndevs (pci_server_port, &ndevs);
+    if (err) {
+        mach_port_deallocate (mach_task_self (), pci_server_port);
+        return err;
+    }
+    mach_port_deallocate (mach_task_self (), pci_server_port);
+
+    pci_sys->num_devices = ndevs;
+    pci_sys->devices = calloc(ndevs, sizeof(struct pci_device_private));
+    if (pci_sys->devices == NULL) {
+        x86_disable_io();
+        free(pci_sys_hurd);
+        pci_sys = NULL;
+        return ENOMEM;
+    }
+
+    device = pci_sys->devices;
+    err = enum_devices(_SERVERS_PCI_CONF, &device, -1, -1, -1, -1,
+                       LEVEL_DOMAIN);
+    if (err)
+        return err;
+
+    return 0;
+}
diff --git a/src/pciaccess_private.h b/src/pciaccess_private.h
index 2f05b29..10c9698 100644
--- a/src/pciaccess_private.h
+++ b/src/pciaccess_private.h
@@ -29,6 +29,9 @@
  * \author Ian Romanick <idr@us.ibm.com>
  */
 
+#ifndef PCIACCESS_PRIVATE_H
+#define PCIACCESS_PRIVATE_H
+
 #if defined(__GNUC__) && (__GNUC__ >= 4)
 # define _pci_hidden      __attribute__((visibility("hidden")))
 #elif defined(__SUNPRO_C) && (__SUNPRO_C >= 0x550)
@@ -150,6 +153,9 @@ struct pci_device_private {
 #ifdef __sun
     int is_primary;
 #endif
+#ifdef __GNU__
+    unsigned long device_port;
+#endif
 };
 
 
@@ -189,5 +195,8 @@ extern int pci_system_netbsd_create( void );
 extern int pci_system_openbsd_create( void );
 extern void pci_system_openbsd_init_dev_mem( int );
 extern int pci_system_solx_devfs_create( void );
+extern int pci_system_hurd_create( void );
 extern int pci_system_x86_create( void );
 extern void pci_io_cleanup( void );
+
+#endif /* PCIACCESS_PRIVATE_H */
diff --git a/src/x86_pci.c b/src/x86_pci.c
index 49c1cab..9adb5e7 100644
--- a/src/x86_pci.c
+++ b/src/x86_pci.c
@@ -20,6 +20,8 @@
  */
 
 #define _GNU_SOURCE
+#include "x86_pci.h"
+
 #include <unistd.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -36,7 +38,7 @@
 
 #include <sys/io.h>
 
-static int
+int
 x86_enable_io(void)
 {
     if (!ioperm(0, 0xffff, 1))
@@ -44,7 +46,7 @@ x86_enable_io(void)
     return errno;
 }
 
-static int
+int
 x86_disable_io(void)
 {
     if (!ioperm(0, 0xffff, 0))
@@ -205,28 +207,6 @@ outl(uint32_t value, uint16_t port)
 
 #endif
 
-#define PCI_VENDOR(reg)                ((reg) & 0xFFFF)
-#define PCI_VENDOR_INVALID     0xFFFF
-
-#define PCI_VENDOR_ID          0x00
-#define PCI_SUB_VENDOR_ID      0x2c
-#define PCI_VENDOR_ID_COMPAQ           0x0e11
-#define PCI_VENDOR_ID_INTEL            0x8086
-
-#define PCI_DEVICE(reg)                (((reg) >> 16) & 0xFFFF)
-#define PCI_DEVICE_INVALID     0xFFFF
-
-#define PCI_CLASS              0x08
-#define PCI_CLASS_DEVICE       0x0a
-#define PCI_CLASS_DISPLAY_VGA          0x0300
-#define PCI_CLASS_BRIDGE_HOST          0x0600
-
-#define        PCIC_DISPLAY    0x03
-#define        PCIS_DISPLAY_VGA        0x00
-
-#define PCI_HDRTYPE    0x0E
-#define PCI_IRQ                0x3C
-
 struct pci_system_x86 {
     struct pci_system system;
     int (*read)(unsigned bus, unsigned dev, unsigned func, pciaddr_t reg, void 
*data, unsigned size);
@@ -633,7 +613,7 @@ pci_device_x86_unmap_range(struct pci_device *dev,
 
 #else
 
-static int
+int
 pci_device_x86_map_range(struct pci_device *dev,
     struct pci_device_mapping *map)
 {
@@ -654,7 +634,7 @@ pci_device_x86_map_range(struct pci_device *dev,
     return 0;
 }
 
-static int
+int
 pci_device_x86_unmap_range(struct pci_device *dev,
     struct pci_device_mapping *map)
 {
@@ -715,13 +695,13 @@ pci_device_x86_write(struct pci_device *dev, const void 
*data,
     return 0;
 }
 
-static void
+void
 pci_system_x86_destroy(void)
 {
     x86_disable_io();
 }
 
-static struct pci_io_handle *
+struct pci_io_handle *
 pci_device_x86_open_legacy_io(struct pci_io_handle *ret,
     struct pci_device *dev, pciaddr_t base, pciaddr_t size)
 {
@@ -734,7 +714,7 @@ pci_device_x86_open_legacy_io(struct pci_io_handle *ret,
     return ret;
 }
 
-static void
+void
 pci_device_x86_close_io(struct pci_device *dev, struct pci_io_handle *handle)
 {
     /* Like in the Linux case, do not disable I/O, as it may be opened several
@@ -742,46 +722,46 @@ pci_device_x86_close_io(struct pci_device *dev, struct 
pci_io_handle *handle)
     /* x86_disable_io(); */
 }
 
-static uint32_t
+uint32_t
 pci_device_x86_read32(struct pci_io_handle *handle, uint32_t reg)
 {
     return inl(reg + handle->base);
 }
 
-static uint16_t
+uint16_t
 pci_device_x86_read16(struct pci_io_handle *handle, uint32_t reg)
 {
     return inw(reg + handle->base);
 }
 
-static uint8_t
+uint8_t
 pci_device_x86_read8(struct pci_io_handle *handle, uint32_t reg)
 {
     return inb(reg + handle->base);
 }
 
-static void
+void
 pci_device_x86_write32(struct pci_io_handle *handle, uint32_t reg,
                       uint32_t data)
 {
     outl(data, reg + handle->base);
 }
 
-static void
+void
 pci_device_x86_write16(struct pci_io_handle *handle, uint32_t reg,
                       uint16_t data)
 {
     outw(data, reg + handle->base);
 }
 
-static void
+void
 pci_device_x86_write8(struct pci_io_handle *handle, uint32_t reg,
                      uint8_t data)
 {
     outb(data, reg + handle->base);
 }
 
-static int
+int
 pci_device_x86_map_legacy(struct pci_device *dev, pciaddr_t base,
     pciaddr_t size, unsigned map_flags, void **addr)
 {
@@ -797,7 +777,7 @@ pci_device_x86_map_legacy(struct pci_device *dev, pciaddr_t 
base,
     return err;
 }
 
-static int
+int
 pci_device_x86_unmap_legacy(struct pci_device *dev, void *addr,
     pciaddr_t size)
 {
diff --git a/src/x86_pci.h b/src/x86_pci.h
new file mode 100644
index 0000000..2e00ba6
--- /dev/null
+++ b/src/x86_pci.h
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2009, 2012 Samuel Thibault
+ * Heavily inspired from the freebsd, netbsd, and openbsd backends
+ * (C) Copyright Eric Anholt 2006
+ * (C) Copyright IBM Corporation 2006
+ * Copyright (c) 2008 Juan Romero Pardines
+ * Copyright (c) 2008 Mark Kettenis
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* Macros and declarations used by both x86 and Hurd modules. */
+
+#ifndef X86_PCI_H
+#define X86_PCI_H
+
+#include "pciaccess.h"
+#include "pciaccess_private.h"
+
+#define PCI_VENDOR(reg)                ((reg) & 0xFFFF)
+#define PCI_VENDOR_INVALID     0xFFFF
+
+#define PCI_VENDOR_ID          0x00
+#define PCI_SUB_VENDOR_ID      0x2c
+#define PCI_VENDOR_ID_COMPAQ           0x0e11
+#define PCI_VENDOR_ID_INTEL            0x8086
+
+#define PCI_DEVICE(reg)                (((reg) >> 16) & 0xFFFF)
+#define PCI_DEVICE_INVALID     0xFFFF
+
+#define PCI_CLASS              0x08
+#define PCI_CLASS_DEVICE       0x0a
+#define PCI_CLASS_DISPLAY_VGA          0x0300
+#define PCI_CLASS_BRIDGE_HOST          0x0600
+
+#define        PCIC_DISPLAY    0x03
+#define        PCIS_DISPLAY_VGA        0x00
+
+#define PCI_HDRTYPE    0x0E
+#define PCI_IRQ                0x3C
+
+int x86_enable_io(void);
+int x86_disable_io(void);
+void pci_system_x86_destroy(void);
+int pci_device_x86_map_range(struct pci_device *dev,
+    struct pci_device_mapping *map);
+int pci_device_x86_unmap_range(struct pci_device *dev,
+    struct pci_device_mapping *map);
+struct pci_io_handle *pci_device_x86_open_legacy_io(struct pci_io_handle *ret,
+    struct pci_device *dev, pciaddr_t base, pciaddr_t size);
+void pci_device_x86_close_io(struct pci_device *dev,
+    struct pci_io_handle *handle);
+uint32_t pci_device_x86_read32(struct pci_io_handle *handle, uint32_t reg);
+uint16_t pci_device_x86_read16(struct pci_io_handle *handle, uint32_t reg);
+uint8_t pci_device_x86_read8(struct pci_io_handle *handle, uint32_t reg);
+void pci_device_x86_write32(struct pci_io_handle *handle, uint32_t reg,
+                      uint32_t data);
+void pci_device_x86_write16(struct pci_io_handle *handle, uint32_t reg,
+                      uint16_t data);
+void pci_device_x86_write8(struct pci_io_handle *handle, uint32_t reg,
+                      uint8_t data);
+int pci_device_x86_map_legacy(struct pci_device *dev, pciaddr_t base,
+    pciaddr_t size, unsigned map_flags, void **addr);
+int pci_device_x86_unmap_legacy(struct pci_device *dev, void *addr,
+    pciaddr_t size);
+
+#endif /* X86_PCI_H */
-- 
2.14.0




reply via email to

[Prev in Thread] Current Thread [Next in Thread]