Luc Verhaegen has uploaded this change for review.
pci2: add read/write/mask byte/long mmio accessors
As for the mask command:
For those "embedded developers" who grew up with the awkward x86 in/out
assembly instructions with the illogical ordering it will seem alien.
As a graphics driver developer who has had to deal with thousands of
registers at a time, mostly setting a few bits at a time, i found the
increased readability and debuggability of a mask command invaluable.
Once the ati_spi code is added, it will be clear just how effective
this command is.
As for the lack of automatic rollback:
- it makes little sense to roll back every single register written.
One could imagine a scenario where this would perfectly undo the
flash being written.
- it makes little sense to roll back every mask command:
Multiple mask commands are likely to touch the same register.
- engines, even simple spi engines, are triggered by a single bit or a
single register being written. Automatic rollback would trigger engines
before the fitting registers are written.
- reading might also trigger an engine. How does one roll back those?
How, if the register is automatically read before it is written, are
we dealing with that?
Instead, by providing programmer internal save/restore functions, the
programmer gets full control over what is saved and restored, and the
order in which those happen. The fact that we automatically retain
the device match private, should make it easier to have device specific
save/restore callbacks.
Change-Id: I5c3f57e9c510337bb81be30aa6c143840a349a60
Signed-off-by: Luc Verhaegen <libv@skynet.be>
---
M pcidev.c
M programmer.h
2 files changed, 101 insertions(+), 0 deletions(-)
git pull ssh://review.coreboot.org:29418/flashrom refs/changes/80/29080/1
diff --git a/pcidev.c b/pcidev.c
index 8503e78..da4e2a3 100644
--- a/pcidev.c
+++ b/pcidev.c
@@ -535,3 +535,96 @@
return device;
}
+
+/*
+ *
+ * Accessors of mmio.
+ *
+ * It is nonsensical to roll these back automatically.
+ * Programmers are responsible for their own restauration.
+ *
+ */
+uint8_t flashrom_pci_mmio_byte_read(struct flashrom_pci_device *device,
+ off_t address)
+{
+ if (address >= device->mmio_size) {
+ errno = EFAULT;
+ return -1;
+ }
+
+ return device->mmio[address];
+}
+
+void flashrom_pci_mmio_byte_write(struct flashrom_pci_device *device,
+ off_t address, uint8_t value)
+{
+ if (address >= device->mmio_size) {
+ errno = EFAULT;
+ return;
+ }
+
+ device->mmio[address] = value;
+}
+
+void flashrom_pci_mmio_byte_mask(struct flashrom_pci_device *device,
+ off_t address, uint8_t value, uint8_t mask)
+{
+ uint8_t temp;
+
+ if (address >= device->mmio_size) {
+ errno = EFAULT;
+ return;
+ }
+
+ value &= mask;
+
+ temp = device->mmio[address] & ~mask;
+ temp |= value & mask;
+
+ device->mmio[address] = temp;
+}
+
+uint32_t flashrom_pci_mmio_long_read(struct flashrom_pci_device *device,
+ off_t address)
+{
+ volatile uint32_t *mmio = (volatile uint32_t *) &device->mmio[address];
+
+ if ((address >= device->mmio_size) || (address & 0x03)) {
+ errno = EFAULT;
+ return -1;
+ }
+
+ return mmio[0];
+}
+
+void flashrom_pci_mmio_long_write(struct flashrom_pci_device *device,
+ off_t address, uint32_t value)
+{
+ volatile uint32_t *mmio = (volatile uint32_t *) &device->mmio[address];
+
+ if ((address >= device->mmio_size) || (address & 0x03)) {
+ errno = EFAULT;
+ return;
+ }
+
+ mmio[0] = value;
+}
+
+void flashrom_pci_mmio_long_mask(struct flashrom_pci_device *device,
+ off_t address, uint32_t value, uint32_t mask)
+{
+ volatile uint32_t *mmio = (volatile uint32_t *) &device->mmio[address];
+ uint32_t temp;
+
+ if ((address >= device->mmio_size) || (address & 0x03)) {
+ errno = EFAULT;
+ return;
+ }
+
+ value &= mask;
+
+ temp = mmio[0] & ~mask;
+ temp |= value & mask;
+
+ mmio[0] = temp;
+}
diff --git a/programmer.h b/programmer.h
index d553317..1a7af7a 100644
--- a/programmer.h
+++ b/programmer.h
@@ -877,6 +877,14 @@
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);
+
+uint8_t flashrom_pci_mmio_byte_read(struct flashrom_pci_device *device, off_t address);
+void flashrom_pci_mmio_byte_write(struct flashrom_pci_device *device, off_t address, uint8_t value);
+void flashrom_pci_mmio_byte_mask(struct flashrom_pci_device *device, off_t address, uint8_t value, uint8_t mask);
+
+uint32_t flashrom_pci_mmio_long_read(struct flashrom_pci_device *device, off_t address);
+void flashrom_pci_mmio_long_write(struct flashrom_pci_device *device, off_t address, uint32_t value);
+void flashrom_pci_mmio_long_mask(struct flashrom_pci_device *device, off_t address, uint32_t value, uint32_t mask);
#endif /* NEED_PCI */
#endif /* !__PROGRAMMER_H__ */
To view, visit change 29080. To unsubscribe, or for help writing mail filters, visit settings.