mirror of
https://review.coreboot.org/flashrom.git
synced 2025-04-27 23:22:37 +02:00
Abstract mapping/unmapping of flash regions
Flash mapping/unmapping was performed without an abstraction layer, so even the dummy flasher caused memory mappings to be set up. Add map/unmap functions to the external flasher abstraction. Fix a possible scribble-over-low-memory corner case which fortunately never triggered so far. With this patch, --programmer dummy works fine as non-root. Corresponding to flashrom svn r493. Signed-off-by: Carl-Daniel Hailfinger <c-d.hailfinger.devel.2006@gmx.net> Acked-by: Uwe Hermann <uwe@hermann-uwe.de>
This commit is contained in:
parent
d0fc9469fd
commit
1455b2baea
@ -40,6 +40,19 @@ int dummy_shutdown(void)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void *dummy_map(const char *descr, unsigned long phys_addr, size_t len)
|
||||||
|
{
|
||||||
|
printf("%s: Mapping %s, 0x%lx bytes at 0x%08lx\n",
|
||||||
|
__func__, descr, (unsigned long)len, phys_addr);
|
||||||
|
return (void *)phys_addr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void dummy_unmap(void *virt_addr, size_t len)
|
||||||
|
{
|
||||||
|
printf("%s: Unmapping 0x%lx bytes at %p\n",
|
||||||
|
__func__, (unsigned long)len, virt_addr);
|
||||||
|
}
|
||||||
|
|
||||||
void dummy_chip_writeb(uint8_t val, volatile void *addr)
|
void dummy_chip_writeb(uint8_t val, volatile void *addr)
|
||||||
{
|
{
|
||||||
printf("%s: addr=%p, val=0x%02x\n", __func__, addr, val);
|
printf("%s: addr=%p, val=0x%02x\n", __func__, addr, val);
|
||||||
|
15
flash.h
15
flash.h
@ -87,6 +87,9 @@ struct programmer_entry {
|
|||||||
int (*init) (void);
|
int (*init) (void);
|
||||||
int (*shutdown) (void);
|
int (*shutdown) (void);
|
||||||
|
|
||||||
|
void * (*map_flash_region) (const char *descr, unsigned long phys_addr, size_t len);
|
||||||
|
void (*unmap_flash_region) (void *virt_addr, size_t len);
|
||||||
|
|
||||||
void (*chip_writeb) (uint8_t val, volatile void *addr);
|
void (*chip_writeb) (uint8_t val, volatile void *addr);
|
||||||
void (*chip_writew) (uint16_t val, volatile void *addr);
|
void (*chip_writew) (uint16_t val, volatile void *addr);
|
||||||
void (*chip_writel) (uint32_t val, volatile void *addr);
|
void (*chip_writel) (uint32_t val, volatile void *addr);
|
||||||
@ -107,6 +110,16 @@ static inline int programmer_shutdown(void)
|
|||||||
return programmer_table[programmer].shutdown();
|
return programmer_table[programmer].shutdown();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline void *programmer_map_flash_region(const char *descr, unsigned long phys_addr, size_t len)
|
||||||
|
{
|
||||||
|
return programmer_table[programmer].map_flash_region(descr, phys_addr, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void programmer_unmap_flash_region(void *virt_addr, size_t len)
|
||||||
|
{
|
||||||
|
programmer_table[programmer].unmap_flash_region(virt_addr, len);
|
||||||
|
}
|
||||||
|
|
||||||
static inline void chip_writeb(uint8_t val, volatile void *addr)
|
static inline void chip_writeb(uint8_t val, volatile void *addr)
|
||||||
{
|
{
|
||||||
programmer_table[programmer].chip_writeb(val, addr);
|
programmer_table[programmer].chip_writeb(val, addr);
|
||||||
@ -579,6 +592,8 @@ uint32_t internal_chip_readl(const volatile void *addr);
|
|||||||
/* dummyflasher.c */
|
/* dummyflasher.c */
|
||||||
int dummy_init(void);
|
int dummy_init(void);
|
||||||
int dummy_shutdown(void);
|
int dummy_shutdown(void);
|
||||||
|
void *dummy_map(const char *descr, unsigned long phys_addr, size_t len);
|
||||||
|
void dummy_unmap(void *virt_addr, size_t len);
|
||||||
void dummy_chip_writeb(uint8_t val, volatile void *addr);
|
void dummy_chip_writeb(uint8_t val, volatile void *addr);
|
||||||
void dummy_chip_writew(uint16_t val, volatile void *addr);
|
void dummy_chip_writew(uint16_t val, volatile void *addr);
|
||||||
void dummy_chip_writel(uint32_t val, volatile void *addr);
|
void dummy_chip_writel(uint32_t val, volatile void *addr);
|
||||||
|
26
flashrom.c
26
flashrom.c
@ -40,6 +40,8 @@ const struct programmer_entry programmer_table[] = {
|
|||||||
{
|
{
|
||||||
.init = internal_init,
|
.init = internal_init,
|
||||||
.shutdown = internal_shutdown,
|
.shutdown = internal_shutdown,
|
||||||
|
.map_flash_region = physmap,
|
||||||
|
.unmap_flash_region = physunmap,
|
||||||
.chip_readb = internal_chip_readb,
|
.chip_readb = internal_chip_readb,
|
||||||
.chip_readw = internal_chip_readw,
|
.chip_readw = internal_chip_readw,
|
||||||
.chip_readl = internal_chip_readl,
|
.chip_readl = internal_chip_readl,
|
||||||
@ -51,6 +53,8 @@ const struct programmer_entry programmer_table[] = {
|
|||||||
{
|
{
|
||||||
.init = dummy_init,
|
.init = dummy_init,
|
||||||
.shutdown = dummy_shutdown,
|
.shutdown = dummy_shutdown,
|
||||||
|
.map_flash_region = dummy_map,
|
||||||
|
.unmap_flash_region = dummy_unmap,
|
||||||
.chip_readb = dummy_chip_readb,
|
.chip_readb = dummy_chip_readb,
|
||||||
.chip_readw = dummy_chip_readw,
|
.chip_readw = dummy_chip_readw,
|
||||||
.chip_readl = dummy_chip_readl,
|
.chip_readl = dummy_chip_readl,
|
||||||
@ -66,7 +70,7 @@ void map_flash_registers(struct flashchip *flash)
|
|||||||
{
|
{
|
||||||
size_t size = flash->total_size * 1024;
|
size_t size = flash->total_size * 1024;
|
||||||
/* Flash registers live 4 MByte below the flash. */
|
/* Flash registers live 4 MByte below the flash. */
|
||||||
flash->virtual_registers = physmap("flash chip registers", (0xFFFFFFFF - 0x400000 - size + 1), size);
|
flash->virtual_registers = programmer_map_flash_region("flash chip registers", (0xFFFFFFFF - 0x400000 - size + 1), size);
|
||||||
}
|
}
|
||||||
|
|
||||||
int read_memmapped(struct flashchip *flash, uint8_t *buf)
|
int read_memmapped(struct flashchip *flash, uint8_t *buf)
|
||||||
@ -98,23 +102,8 @@ struct flashchip *probe_flash(struct flashchip *first_flash, int force)
|
|||||||
|
|
||||||
size = flash->total_size * 1024;
|
size = flash->total_size * 1024;
|
||||||
|
|
||||||
/* If getpagesize() > size ->
|
|
||||||
* "Can't mmap memory using /dev/mem: Invalid argument"
|
|
||||||
* This should never happen as we don't support any flash chips
|
|
||||||
* smaller than 4k or 8k (yet).
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (getpagesize() > size) {
|
|
||||||
/*
|
|
||||||
* if a flash size of 0 is mapped, we map a single page
|
|
||||||
* so we can probe in that area whether we know the
|
|
||||||
* vendor at least.
|
|
||||||
*/
|
|
||||||
size = getpagesize();
|
|
||||||
}
|
|
||||||
|
|
||||||
base = flashbase ? flashbase : (0xffffffff - size + 1);
|
base = flashbase ? flashbase : (0xffffffff - size + 1);
|
||||||
flash->virtual_memory = physmap("flash chip", base, size);
|
flash->virtual_memory = programmer_map_flash_region("flash chip", base, size);
|
||||||
|
|
||||||
if (force)
|
if (force)
|
||||||
break;
|
break;
|
||||||
@ -127,7 +116,8 @@ struct flashchip *probe_flash(struct flashchip *first_flash, int force)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
notfound:
|
notfound:
|
||||||
physunmap((void *)flash->virtual_memory, size);
|
/* The intermediate cast to unsigned long works around a gcc warning bug. */
|
||||||
|
programmer_unmap_flash_region((void *)(unsigned long)flash->virtual_memory, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!flash || !flash->name)
|
if (!flash || !flash->name)
|
||||||
|
21
physmap.c
21
physmap.c
@ -69,12 +69,33 @@ void *sys_physmap(unsigned long phys_addr, size_t len)
|
|||||||
|
|
||||||
void physunmap(void *virt_addr, size_t len)
|
void physunmap(void *virt_addr, size_t len)
|
||||||
{
|
{
|
||||||
|
if (len == 0) {
|
||||||
|
printf_debug("Not unmapping zero size at %p\n", virt_addr);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
munmap(virt_addr, len);
|
munmap(virt_addr, len);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void *physmap(const char *descr, unsigned long phys_addr, size_t len)
|
void *physmap(const char *descr, unsigned long phys_addr, size_t len)
|
||||||
{
|
{
|
||||||
|
if (len == 0) {
|
||||||
|
printf_debug("Not mapping %s, zero size at 0x%08lx\n",
|
||||||
|
descr, phys_addr);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((getpagesize() - 1) & len) {
|
||||||
|
fprintf(stderr, "Mapping %s at 0x%08lx, unaligned size 0x%lx\n",
|
||||||
|
descr, phys_addr, (unsigned long)len);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((getpagesize() - 1) & phys_addr) {
|
||||||
|
fprintf(stderr, "Mapping %s, 0x%lx bytes at unaligned 0x%08lx\n",
|
||||||
|
descr, (unsigned long)len, phys_addr);
|
||||||
|
}
|
||||||
|
|
||||||
void *virt_addr = sys_physmap(phys_addr, len);
|
void *virt_addr = sys_physmap(phys_addr, len);
|
||||||
|
|
||||||
if (NULL == virt_addr) {
|
if (NULL == virt_addr) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user