Luc Verhaegen has uploaded this change for review.

View Change

pci2: add mmio bar map/unmap

This works through linux sysfs and opens /sys/bus/pci/devices/.../resource%d
and maps that to neatly circumvent /dev/mem security limitations and
we do not need to figure out BAR address and size ourselves.

Change-Id: I1c67d51d853f751d13271bf83316ee2118c1c476
Signed-off-by: Luc Verhaegen <libv@skynet.be>
---
M pcidev.c
M programmer.h
2 files changed, 75 insertions(+), 0 deletions(-)

git pull ssh://review.coreboot.org:29418/flashrom refs/changes/79/29079/1
diff --git a/pcidev.c b/pcidev.c
index 837b028..8503e78 100644
--- a/pcidev.c
+++ b/pcidev.c
@@ -18,6 +18,11 @@

#include <stdlib.h>
#include <string.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <sys/mman.h>
+#include <unistd.h>
+
#include "flash.h"
#include "programmer.h"
#include "hwaccess.h"
@@ -352,6 +357,69 @@
/*
*
*/
+int
+flashrom_pci_mmio_map(struct flashrom_pci_device *device, int bar)
+{
+ char filename[1024];
+ int fd;
+
+ if ((bar < 0) || (bar > 5)) {
+ msg_perr("%s: Invalid BAR provided: %d\n", __func__, bar);
+ return EINVAL;
+ }
+
+ if (device->mmio) {
+ if (device->pci->size[bar] != device->mmio_size) {
+ msg_perr("%s: already mapped bar: 0x%lXbytes @ %p)\n",
+ __func__, device->mmio_size, device->mmio);
+ return EALREADY;
+ } else
+ return 0;
+ }
+
+ snprintf(filename, sizeof(filename) - 1,
+ "%sresource%d", device->sysfs_path, bar);
+
+ fd = open(filename, O_RDWR);
+ if (fd == -1) {
+ msg_perr("%s: failed to open %s: %s\n",
+ __func__, filename, strerror(errno));
+ return errno;
+ }
+
+ device->mmio_size = device->pci->size[bar];
+
+ device->mmio = mmap(NULL, device->mmio_size, PROT_WRITE | PROT_READ,
+ MAP_SHARED, fd, 0);
+ if (device->mmio == MAP_FAILED) {
+ msg_perr("%s: mapping %s failed: %s\n",
+ __func__, filename, strerror(errno));
+ close(fd);
+ device->mmio_size = 0;
+ return errno;
+ }
+
+ close(fd);
+
+ return 0;
+}
+
+/*
+ *
+ */
+void
+flashrom_pci_mmio_unmap(struct flashrom_pci_device *device)
+{
+ if (device->mmio && device->mmio_size &&
+ (device->mmio != MAP_FAILED))
+ munmap((void *) device->mmio, device->mmio_size);
+ device->mmio = NULL;
+ device->mmio_size = 0;
+}
+
+/*
+ *
+ */
static int
flashrom_pci_device_shutdown(void *data)
{
@@ -363,6 +431,8 @@
return 1;
}

+ flashrom_pci_mmio_unmap(device);
+
free(device->sysfs_path);
device->sysfs_path = NULL;

diff --git a/programmer.h b/programmer.h
index 0a445fa..d553317 100644
--- a/programmer.h
+++ b/programmer.h
@@ -868,10 +868,15 @@

char *sysfs_path; /* linux only, of course */

+ volatile uint8_t *mmio; /* mapped io memory */
+ size_t mmio_size;
+
const void *private; /* programmer specific hook */
};

struct flashrom_pci_device *flashrom_pci_init(const struct flashrom_pci_match *matches);
+int flashrom_pci_mmio_map(struct flashrom_pci_device *device, int bar);
+void flashrom_pci_mmio_unmap(struct flashrom_pci_device *device);
#endif /* NEED_PCI */

#endif /* !__PROGRAMMER_H__ */

To view, visit change 29079. To unsubscribe, or for help writing mail filters, visit settings.

Gerrit-Project: flashrom
Gerrit-Branch: master
Gerrit-MessageType: newchange
Gerrit-Change-Id: I1c67d51d853f751d13271bf83316ee2118c1c476
Gerrit-Change-Number: 29079
Gerrit-PatchSet: 1
Gerrit-Owner: Luc Verhaegen <libv@skynet.be>