[flashrom] [PATCH] automatically round address ranges requested from physmap_common to page boundaries

Stefan Tauner stefan.tauner at student.tuwien.ac.at
Mon May 30 02:45:44 CEST 2011


this patch also changes the display width of all addresses in physmap.c to 16 hex characters.

FIXME: what about unmappings?
munmap is safe.
djgpp's __dpmi_free_physical_address_mapping: unknown.
DirectHW's unmap_physical: unknown.

FIXME: jakllsch suggested using PRIx64 instead of x, because it's more portable

Signed-off-by: Stefan Tauner <stefan.tauner at student.tuwien.ac.at>
---
 physmap.c |   46 +++++++++++++++++++++++++++++++---------------
 1 files changed, 31 insertions(+), 15 deletions(-)

diff --git a/physmap.c b/physmap.c
index cb035a5..3dbe387 100644
--- a/physmap.c
+++ b/physmap.c
@@ -99,7 +99,8 @@ void physunmap(void *virt_addr, size_t len)
 	/* There is no known way to unmap the first 1 MB. The DPMI server will
 	 * do this for us on exit.
 	 */
-	if ((virt_addr >= realmem_map) && ((virt_addr + len) <= (realmem_map + (1024 * 1024)))) {
+	if ((virt_addr >= realmem_map) &&
+	    ((virt_addr + len) <= (realmem_map + (1024 * 1024)))) {
 		return;
 	}
 
@@ -195,7 +196,8 @@ static void *sys_physmap_ro_cached(unsigned long phys_addr, size_t len)
 	if (-1 == fd_mem_cached) {
 		/* Open the memory device CACHED. */
 		if (-1 == (fd_mem_cached = open(MEM_DEV, O_RDWR))) {
-			msg_perr("Critical error: open(" MEM_DEV "): %s", strerror(errno));
+			msg_perr("Critical error: open(" MEM_DEV "): %s",
+				 strerror(errno));
 			exit(2);
 		}
 	}
@@ -221,26 +223,39 @@ void physunmap(void *virt_addr, size_t len)
 #define PHYSMAP_RW	0
 #define PHYSMAP_RO	1
 
+/* Round start to nearest page boundary below and set len so that the resulting
+ * address range ends at the lowest possible page boundary where the original
+ * address range is still entirely contained. It returns the difference between
+ * the rounded start address and the original start address. */
+static unsigned long round_to_page_boundaries(unsigned long *start, size_t *len)
+{
+	unsigned long page_size = getpagesize();
+	unsigned long page_mask = ~(page_size-1);
+	unsigned long end = *start + *len;
+	unsigned long old_start = *start;
+	msg_gspew("page_size=%lu\n", page_size);
+	msg_gspew("start=0x%016lx, len=0x%08lx, end=0x%016lx\n",
+		  *start, *len, end);
+	*start = *start & page_mask;
+	end = (end & page_mask) + (((end & page_mask) != end) ? page_size : 0);
+	*len = end - *start;
+	msg_gspew("start=0x%016lx, len=0x%08lx, end=0x%016lx\n",
+		  *start, *len, *start + *len);
+	return old_start - *start;
+}
+
 static void *physmap_common(const char *descr, unsigned long phys_addr, size_t len, int mayfail, int readonly)
 {
 	void *virt_addr;
+	unsigned long  diff;
 
 	if (len == 0) {
-		msg_pspew("Not mapping %s, zero size at 0x%08lx.\n",
+		msg_pspew("Not mapping %s, zero size at 0x%016lx.\n",
 			     descr, phys_addr);
 		return ERROR_PTR;
 	}
-		
-	if ((getpagesize() - 1) & len) {
-		msg_perr("Mapping %s at 0x%08lx, unaligned size 0x%lx.\n",
-			descr, phys_addr, (unsigned long)len);
-	}
-
-	if ((getpagesize() - 1) & phys_addr) {
-		msg_perr("Mapping %s, 0x%lx bytes at unaligned 0x%08lx.\n",
-			descr, (unsigned long)len, phys_addr);
-	}
 
+	diff = round_to_page_boundaries(&phys_addr, &len);
 	if (readonly) {
 		virt_addr = sys_physmap_ro_cached(phys_addr, len);
 	} else {
@@ -250,7 +265,8 @@ static void *physmap_common(const char *descr, unsigned long phys_addr, size_t l
 	if (ERROR_PTR == virt_addr) {
 		if (NULL == descr)
 			descr = "memory";
-		msg_perr("Error accessing %s, 0x%lx bytes at 0x%08lx\n", descr, (unsigned long)len, phys_addr);
+		msg_perr("Error accessing %s, 0x%lx bytes at 0x%016lx\n", descr,
+			 (unsigned long)len, phys_addr);
 		perror(MEM_DEV " mmap failed");
 #ifdef __linux__
 		if (EINVAL == errno) {
@@ -269,7 +285,7 @@ static void *physmap_common(const char *descr, unsigned long phys_addr, size_t l
 			exit(3);
 	}
 
-	return virt_addr;
+	return virt_addr + diff;
 }
 
 void *physmap(const char *descr, unsigned long phys_addr, size_t len)
-- 
1.7.1





More information about the flashrom mailing list