mirror of
				https://review.coreboot.org/flashrom.git
				synced 2025-10-31 05:10:41 +01: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:
		| @@ -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) { | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Carl-Daniel Hailfinger
					Carl-Daniel Hailfinger