mirror of
https://review.coreboot.org/flashrom.git
synced 2025-07-02 06:23:18 +02:00
Revert MMIO space writes on shutdown as needed
Reversible MMIO space writes now use rmmio_write*(). Reversible PCI MMIO space writes now use pci_rmmio_write*(). If a MMIO value needs to be queued for restore without writing it, use rmmio_val*(). MMIO space writes which are one-shot (e.g. communication with some chip) should continue to use the permanent mmio_write* variants. Corresponding to flashrom svn r1292. Signed-off-by: Carl-Daniel Hailfinger <c-d.hailfinger.devel.2006@gmx.net> David tested it successfully on some NM10/ICH7 platforms which switch between SPI and LPC targets (x86 BIOS ROM vs. EC firmware ROM). Acked-by: David Hendricks <dhendrix@google.com>
This commit is contained in:
101
hwaccess.c
101
hwaccess.c
@ -184,3 +184,104 @@ uint32_t mmio_le_readl(void *addr)
|
||||
{
|
||||
return le_to_cpu32(mmio_readl(addr));
|
||||
}
|
||||
|
||||
enum mmio_write_type {
|
||||
mmio_write_type_b,
|
||||
mmio_write_type_w,
|
||||
mmio_write_type_l,
|
||||
};
|
||||
|
||||
struct undo_mmio_write_data {
|
||||
void *addr;
|
||||
int reg;
|
||||
enum mmio_write_type type;
|
||||
union {
|
||||
uint8_t bdata;
|
||||
uint16_t wdata;
|
||||
uint32_t ldata;
|
||||
};
|
||||
};
|
||||
|
||||
void undo_mmio_write(void *p)
|
||||
{
|
||||
struct undo_mmio_write_data *data = p;
|
||||
msg_pdbg("Restoring MMIO space at %p\n", data->addr);
|
||||
switch (data->type) {
|
||||
case mmio_write_type_b:
|
||||
mmio_writeb(data->bdata, data->addr);
|
||||
break;
|
||||
case mmio_write_type_w:
|
||||
mmio_writew(data->wdata, data->addr);
|
||||
break;
|
||||
case mmio_write_type_l:
|
||||
mmio_writel(data->ldata, data->addr);
|
||||
break;
|
||||
}
|
||||
/* p was allocated in register_undo_mmio_write. */
|
||||
free(p);
|
||||
}
|
||||
|
||||
#define register_undo_mmio_write(a, c) \
|
||||
{ \
|
||||
struct undo_mmio_write_data *undo_mmio_write_data; \
|
||||
undo_mmio_write_data = malloc(sizeof(struct undo_mmio_write_data)); \
|
||||
undo_mmio_write_data->addr = a; \
|
||||
undo_mmio_write_data->type = mmio_write_type_##c; \
|
||||
undo_mmio_write_data->c##data = mmio_read##c(a); \
|
||||
register_shutdown(undo_mmio_write, undo_mmio_write_data); \
|
||||
}
|
||||
|
||||
#define register_undo_mmio_writeb(a) register_undo_mmio_write(a, b)
|
||||
#define register_undo_mmio_writew(a) register_undo_mmio_write(a, w)
|
||||
#define register_undo_mmio_writel(a) register_undo_mmio_write(a, l)
|
||||
|
||||
void rmmio_writeb(uint8_t val, void *addr)
|
||||
{
|
||||
register_undo_mmio_writeb(addr);
|
||||
mmio_writeb(val, addr);
|
||||
}
|
||||
|
||||
void rmmio_writew(uint16_t val, void *addr)
|
||||
{
|
||||
register_undo_mmio_writew(addr);
|
||||
mmio_writew(val, addr);
|
||||
}
|
||||
|
||||
void rmmio_writel(uint32_t val, void *addr)
|
||||
{
|
||||
register_undo_mmio_writel(addr);
|
||||
mmio_writel(val, addr);
|
||||
}
|
||||
|
||||
void rmmio_le_writeb(uint8_t val, void *addr)
|
||||
{
|
||||
register_undo_mmio_writeb(addr);
|
||||
mmio_le_writeb(val, addr);
|
||||
}
|
||||
|
||||
void rmmio_le_writew(uint16_t val, void *addr)
|
||||
{
|
||||
register_undo_mmio_writew(addr);
|
||||
mmio_le_writew(val, addr);
|
||||
}
|
||||
|
||||
void rmmio_le_writel(uint32_t val, void *addr)
|
||||
{
|
||||
register_undo_mmio_writel(addr);
|
||||
mmio_le_writel(val, addr);
|
||||
}
|
||||
|
||||
void rmmio_valb(void *addr)
|
||||
{
|
||||
register_undo_mmio_writeb(addr);
|
||||
}
|
||||
|
||||
void rmmio_valw(void *addr)
|
||||
{
|
||||
register_undo_mmio_writew(addr);
|
||||
}
|
||||
|
||||
void rmmio_vall(void *addr)
|
||||
{
|
||||
register_undo_mmio_writel(addr);
|
||||
}
|
||||
|
Reference in New Issue
Block a user