[OpenBIOS] [PATCH] Implement new pv_align_mem_alloc romvec interface for allocating aligned memory.

Mark Cave-Ayland mark.cave-ayland at siriusit.co.uk
Tue Apr 19 00:31:34 CEST 2011


When attempting to load kadb from a Solaris 8 CD at boot, it seems that in order
for kadb to allocate enough memory to load the kernel (and its modules) the
/openprom/aligned-allocator property must be present with length zero.

This has the additional side-effect that OpenBIOS memory allocations are
redirected to a new romvec offset when this property is detected, which appears
to have a similar interface to obp_dumb_memalloc() but with an extra
alignment parameter. Hence we include a simple implementation which seems
to be enough to be able to get kadb to load and attach to the kernel.

---
 openbios-devel/arch/sparc32/call-romvec.S |    1 +
 openbios-devel/arch/sparc32/lib.c         |   28 +++++++++++++++++-----------
 openbios-devel/arch/sparc32/openprom.h    |    5 ++++-
 openbios-devel/arch/sparc32/romvec.c      |    2 ++
 openbios-devel/arch/sparc32/romvec.h      |    2 ++
 openbios-devel/arch/sparc32/tree.fs       |    3 +++
 6 files changed, 29 insertions(+), 12 deletions(-)

diff --git a/openbios-devel/arch/sparc32/call-romvec.S b/openbios-devel/arch/sparc32/call-romvec.S
index 1e8f754..2b2dfe0 100644
--- a/openbios-devel/arch/sparc32/call-romvec.S
+++ b/openbios-devel/arch/sparc32/call-romvec.S
@@ -89,4 +89,5 @@ ROMVEC_HANDLER(obp_proplen)
 ROMVEC_HANDLER(obp_getprop)
 ROMVEC_HANDLER(obp_setprop)
 ROMVEC_HANDLER(obp_nextprop)
+ROMVEC_HANDLER(obp_align_memalloc)
 
diff --git a/openbios-devel/arch/sparc32/lib.c b/openbios-devel/arch/sparc32/lib.c
index 01fa570..b975fd4 100644
--- a/openbios-devel/arch/sparc32/lib.c
+++ b/openbios-devel/arch/sparc32/lib.c
@@ -347,10 +347,25 @@ void ofmem_arch_early_map_pages(phys_addr_t phys, ucell virt, ucell size, ucell
     map_pages(phys, virt, size, mode);
 }
 
-char *obp_dumb_memalloc(char *va, unsigned int size)
+char *obp_align_memalloc(char *va, unsigned int size, unsigned int align)
 {
     phys_addr_t phys;
     ucell virt;
+
+    /* Claim physical memory */
+    phys = ofmem_claim_phys(-1, size, align);
+
+    /* Claim virtual memory */
+    virt = ofmem_claim_virt(pointer2cell(va), size, 0);
+
+    /* Map the memory */
+    ofmem_map(phys, virt, size, ofmem_arch_default_translation_mode(phys));
+
+    return cell2pointer(virt);
+}
+
+char *obp_dumb_memalloc(char *va, unsigned int size)
+{
     unsigned long align;
     int i;
     
@@ -371,16 +386,7 @@ char *obp_dumb_memalloc(char *va, unsigned int size)
         align++;
     }
 
-    /* Claim physical memory */
-    phys = ofmem_claim_phys(-1, size, align);
-
-    /* Claim virtual memory */
-    virt = ofmem_claim_virt(pointer2cell(va), size, 0);
-
-    /* Map the memory */
-    ofmem_map(phys, virt, size, ofmem_arch_default_translation_mode(phys));
-
-    return cell2pointer(virt);
+    return obp_align_memalloc(va, size, align);
 }
 
 void obp_dumb_memfree(__attribute__((unused))char *va,
diff --git a/openbios-devel/arch/sparc32/openprom.h b/openbios-devel/arch/sparc32/openprom.h
index 0a2074b..5f05014 100644
--- a/openbios-devel/arch/sparc32/openprom.h
+++ b/openbios-devel/arch/sparc32/openprom.h
@@ -135,7 +135,10 @@ struct linux_romvec {
 	struct linux_bootargs_v2 pv_v2bootargs;
 	struct linux_dev_v2_funcs pv_v2devops;
 
-	int filler[15];
+	/* Allocate memory to specified alignment */
+	char * (*pv_align_mem_alloc)(char *va, unsigned int size, unsigned int align);
+
+	int filler[11];
 
 	/* This one is sun4c/sun4 only. */
 	void (*pv_setctxt)(int ctxt, char *va, int pmeg);
diff --git a/openbios-devel/arch/sparc32/romvec.c b/openbios-devel/arch/sparc32/romvec.c
index 843b9f4..463181d 100644
--- a/openbios-devel/arch/sparc32/romvec.c
+++ b/openbios-devel/arch/sparc32/romvec.c
@@ -508,6 +508,8 @@ init_openprom(void)
     fword("open-dev");
     obp_fd_stdout = POP();
 
+    romvec0.pv_align_mem_alloc = obp_align_memalloc_handler;
+
     romvec0.v3_cpustart = obp_cpustart_handler;
     romvec0.v3_cpustop = obp_cpustop_handler;
     romvec0.v3_cpuidle = obp_cpuidle_handler;
diff --git a/openbios-devel/arch/sparc32/romvec.h b/openbios-devel/arch/sparc32/romvec.h
index d5103d1..816109c 100644
--- a/openbios-devel/arch/sparc32/romvec.h
+++ b/openbios-devel/arch/sparc32/romvec.h
@@ -74,3 +74,5 @@ int obp_setprop_handler(__attribute__((unused)) int node,
 		       __attribute__((unused)) int len);
 const char *obp_nextprop(int node, const char *name);
 const char *obp_nextprop_handler(int node, const char *name);
+char *obp_align_memalloc(char *va, unsigned int size, unsigned int align);
+char *obp_align_memalloc_handler(char *va, unsigned int size, unsigned int align);
diff --git a/openbios-devel/arch/sparc32/tree.fs b/openbios-devel/arch/sparc32/tree.fs
index c0b08bd..f9a0406 100644
--- a/openbios-devel/arch/sparc32/tree.fs
+++ b/openbios-devel/arch/sparc32/tree.fs
@@ -125,3 +125,6 @@ finish-device
 
 " /options" find-device
   " disk" encode-string " boot-from" property
+
+" /openprom" find-device
+  0 0 " aligned-allocator" property
-- 
1.7.2.5




More information about the OpenBIOS mailing list