[OpenBIOS] [PATCH 3/3] ofmem: helper to find first virtual address map entry

Igor V. Kovalenko igor.v.kovalenko at gmail.com
Sat Dec 26 23:07:16 CET 2009


From: Igor V. Kovalenko <igor.v.kovalenko at gmail.com>

A few places in sparc64 code may need to know where
specific physical address range is mapped to access
memory locations. Create helper to find first suitable
mapping and return virtual address.

- ofmem_find_virtual: new method; use it to find
  where physical memory address is mapped

- arch_nvram_get call ofmem_find_virtual to access
  kernel command line parameters from qemu

- vga_config_cb call ofmem_find_virtual to access
  framebuffer on sparc64

Signed-off-by: Igor V. Kovalenko <igor.v.kovalenko at gmail.com>
---
 arch/sparc64/openbios.c |   19 +++++++++++++------
 include/ofmem.h         |    1 +
 modules/ofmem_common.c  |   25 +++++++++++++++++++++++++
 modules/video.c         |    9 ++++++++-
 4 files changed, 47 insertions(+), 7 deletions(-)

diff --git a/arch/sparc64/openbios.c b/arch/sparc64/openbios.c
index 03993b5..dd6151f 100644
--- a/arch/sparc64/openbios.c
+++ b/arch/sparc64/openbios.c
@@ -281,6 +281,7 @@ void arch_nvram_get(char *data)
     uint16_t machine_id;
     const char *stdin_path, *stdout_path;
     const char *kernel_cmdline;
+    ucell kernel_cmdline_addr;
 
     fw_cfg_init();
 
@@ -302,12 +303,18 @@ void arch_nvram_get(char *data)
     kernel_size = fw_cfg_read_i32(FW_CFG_KERNEL_SIZE);
     if (kernel_size)
         kernel_image = fw_cfg_read_i64(FW_CFG_KERNEL_ADDR);
-    kernel_cmdline = (const char *) fw_cfg_read_i64(FW_CFG_KERNEL_CMDLINE);
-    if (kernel_cmdline) {
-        size = strlen(kernel_cmdline);
-        if (size > OBIO_CMDLINE_MAX - 1)
-            size = OBIO_CMDLINE_MAX - 1;
-        memcpy(&obio_cmdline, kernel_cmdline, size);
+    /* first read physical address of command line parameters */
+    kernel_cmdline_addr = fw_cfg_read_i64(FW_CFG_KERNEL_CMDLINE);
+    if (kernel_cmdline_addr) {
+        /* find virtual address, expect it to be mapped by entry.S */
+        kernel_cmdline_addr = ofmem_find_virtual(kernel_cmdline_addr);
+        if (kernel_cmdline_addr != (ucell)-1) {
+            kernel_cmdline = (const char*) kernel_cmdline_addr;
+            size = strlen(kernel_cmdline);
+            if (size > OBIO_CMDLINE_MAX - 1)
+                size = OBIO_CMDLINE_MAX - 1;
+            memcpy(&obio_cmdline, kernel_cmdline, size);
+        }
     }
     obio_cmdline[size] = '\0';
     qemu_cmdline = (uint64_t)obio_cmdline;
diff --git a/include/ofmem.h b/include/ofmem.h
index 37f9e3b..eaa5082 100644
--- a/include/ofmem.h
+++ b/include/ofmem.h
@@ -92,6 +92,7 @@ extern int   ofmem_unmap( ucell virt, ucell size );
 extern void  ofmem_release_phys( ucell phys, ucell size );
 extern void  ofmem_release_virt( ucell virt, ucell size );
 extern ucell ofmem_translate( ucell virt, ucell *ret_mode );
+extern ucell ofmem_find_virtual( ucell phys );
 
 #ifdef CONFIG_PPC
 #define PAGE_SHIFT   12
diff --git a/modules/ofmem_common.c b/modules/ofmem_common.c
index 760823d..fedcaa1 100644
--- a/modules/ofmem_common.c
+++ b/modules/ofmem_common.c
@@ -694,6 +694,31 @@ ucell ofmem_translate( ucell virt, ucell *mode )
 	return -1;
 }
 
+/* physical -> virtual.
+   return first found translation
+ */
+ucell ofmem_find_virtual( ucell phys )
+{
+    ofmem_t *ofmem = ofmem_arch_get_private();
+    translation_t *t;
+
+    OFMEM_TRACE("ofmem_find_virtual: searching virtual address of "
+            FMT_ucellx "\n", phys);
+
+    for( t=ofmem->trans; t ; t=t->next ) {
+        ucell offs;
+        if( t->phys <= phys && t->phys + t->size - 1 >= phys ) {
+            offs = phys - t->phys;
+            return t->virt + offs;
+        }
+    }
+
+    OFMEM_TRACE("ofmem_find_virtual: no translation defined (" FMT_ucellx ")\n",
+            phys);
+
+    return -1;
+}
+
 /* release memory allocated by ofmem_claim_phys */
 void ofmem_release_phys( ucell phys, ucell size )
 {
diff --git a/modules/video.c b/modules/video.c
index fe8f1a2..83a39b4 100644
--- a/modules/video.c
+++ b/modules/video.c
@@ -309,7 +309,6 @@ init_video( unsigned long fb,  int width, int height, int depth, int rb )
 	int i, s, size;
 	phandle_t ph=0;
 
-	video.fb.mphys = fb;
 	video.fb.w = width;
 	video.fb.h = height;
 	video.fb.depth = depth;
@@ -333,6 +332,14 @@ init_video( unsigned long fb,  int width, int height, int depth, int rb )
 	ofmem_claim_virt( video.fb.mphys, size, 0 );
 	ofmem_map( video.fb.mphys, video.fb.mphys, size, -1 );
 #endif
+#if defined(CONFIG_SPARC64)
+    // TODO: use full 64bit physical address of framebuffer
+	// The issue here is that fb is passed value of bar address
+	// which is an offset from pci memory space
+	fb = ofmem_find_virtual(fb);
+#endif
+
+	video.fb.mphys = fb;
 
 	for( i=0; i<256; i++ )
 		set_color( i, i * 0x010101 );




More information about the OpenBIOS mailing list