[PATCH v2] sh: Take into account the base of System RAM in virt_to_phys()
Simon Horman
horms at verge.net.au
Sun Oct 2 21:05:18 EDT 2011
Previously virt_to_phys() assumed that physical memory always started
at address 0. This is not always the case.
Tested on an sh7757lcr (32bit system) whose only System RAM region is
40000000-4effffff and an ecovec24 (29bit system).
Signed-off-by: Simon Horman <horms at verge.net.au>
---
kexec/arch/sh/kexec-sh.c | 45 ++++++++++++++++++++++++++++++++++++++++++++-
1 files changed, 44 insertions(+), 1 deletions(-)
v2
* Only use the base of System RAM as an offset into physical memory
if 32bit addressing is in use.
diff --git a/kexec/arch/sh/kexec-sh.c b/kexec/arch/sh/kexec-sh.c
index 4b21ee8..94ebbc7 100644
--- a/kexec/arch/sh/kexec-sh.c
+++ b/kexec/arch/sh/kexec-sh.c
@@ -185,13 +185,56 @@ void kexec_sh_setup_zero_page(char *zero_page_buf, size_t zero_page_size,
}
}
+static int is_32bit(void)
+{
+ const char *cpuinfo = "/proc/cpuinfo";
+ char line[MAX_LINE], key[MAX_LINE], value[MAX_LINE];
+ FILE *fp;
+ int count;
+ int status = 0;
+
+ fp = fopen(cpuinfo, "r");
+ if (!fp)
+ die("Cannot open %s\n", cpuinfo);
+
+ while(fgets(line, sizeof(line), fp) != 0) {
+ count = sscanf(line, "%s : %s", key, value);
+ if (count != 2)
+ continue;
+ if (!strcmp(key, "address sizes")) {
+ if (!strcmp(value, "32 bits physical"))
+ status = 1;
+ break;
+ }
+ }
+
+ fclose(fp);
+
+ return status;
+}
+
unsigned long virt_to_phys(unsigned long addr)
{
unsigned long seg = addr & 0xe0000000;
+ unsigned long long start = 0;
+
if (seg != 0x80000000 && seg != 0xc0000000)
die("Virtual address %p is not in P1 or P2\n", (void *)addr);
- return addr - seg;
+ /* If 32bit addressing is used then the base of system RAM
+ * is an offset into physical memory. */
+ if (is_32bit()) {
+ unsigned long long end;
+ int ret;
+
+ /* Assume there is only one "System RAM" region */
+ ret = parse_iomem_single("System RAM\n", &start, &end);
+ if (ret)
+ die("Could not parse System RAM region "
+ "in /proc/iomem\n");
+ }
+
+ return addr - seg + start;
}
/*
--
1.7.5.4
More information about the kexec
mailing list