The following series implements alternative approach to solve issue where qemu provides i/o and pci memory spaces within physical RAM address space, which makes low memory addresses unusable.
Instead of changing qemu to move i/o and pci spaces out of RAM space we can remap 64M of i/o and pci spaces to above 32bit accessible by client program. Then we map physical RAM at 64M offset to start of virtual memory.
A few extra changes are required. At very least we need to find where framebuffer virtual address is placed by startup code, helper change is provided.
NOTE: this approach may hide up to 128M from client allocations so I tested with 'qemu-system-sparc64 -m 256'
In my test these series are as efficient as qemu change to remap i/o and pci spaces in allowing milax032sparc.iso to not step over cmd646 registers. Currently milax loader gets a bit further and fails with
Can't open /ramdisk-root byte-load: exception caught!
---
Igor V. Kovalenko (3): sparc64: remap first 64M physical address space sparc64: claim memory mapped by startup code ofmem: helper to find first virtual address map entry
arch/sparc64/entry.S | 68 +++++++++++++++++++----------------------- arch/sparc64/ofmem_sparc64.c | 2 + arch/sparc64/openbios.c | 19 ++++++++---- include/ofmem.h | 1 + modules/ofmem_common.c | 25 +++++++++++++++ modules/video.c | 9 +++++- 6 files changed, 80 insertions(+), 44 deletions(-)
From: Igor V. Kovalenko igor.v.kovalenko@gmail.com
At the moment qemu maps i/o and pci memory spaces into low physical addresses, making first megabytes of RAM space unavalable.
Instead of changing qemu we map first 64M of physical address space at 0x1ff.00000000 and map low virtual addresses after that hole. i/o space is accessed via bypass ASI therefore no changes to drivers using i/o are required.
Issue with framebuffer mapping is solved by separate patch to find where framebuffer got mapped by startup code.
- map low 64M of physical address space at 0x1ff00000000 by startup code
- map low 64M of virtual address space after 64M of physical address space by startup code
Signed-off-by: Igor V. Kovalenko igor.v.kovalenko@gmail.com --- arch/sparc64/entry.S | 68 +++++++++++++++++++++++--------------------------- 1 files changed, 31 insertions(+), 37 deletions(-)
diff --git a/arch/sparc64/entry.S b/arch/sparc64/entry.S index d3075d8..c865a5d 100644 --- a/arch/sparc64/entry.S +++ b/arch/sparc64/entry.S @@ -18,6 +18,11 @@ #define PROM_ADDR 0x1fff0000000 #define CFG_ADDR 0x1fe02000510
+! where do we remap low 64M as a workaround +#define REMAP_VADDR 0x1ff00000000 +! where usable RAM starts after 64M hole +#define REMAP_PADDR 0x4000000 + .globl entry, _entry
.section ".text", "ax" @@ -180,39 +185,47 @@ entry: bne 1b add %l2, %g5, %l2
- ! setup VGA buffer - setx 0x1ff004a0000, %g7, %g4 - mov 2, %g6 + ! remap low 64m including VGA buffer to high memory + setx 0, %l1, %l3 ! physical address + setx REMAP_VADDR, %l1, %l4 ! virtual address + + ! 16x4M mapped + mov 16, %g6 set 48, %g7 - set 0x10000, %g5 -1: stxa %g4, [%g7] ASI_DMMU ! vaddr = 0x1ff004a0000, ctx=0 - set 0xa0000000, %g3 + set 0x400000, %g5 +1: mov %l4, %g4 + stxa %g4, [%g7] ASI_DMMU ! vaddr = 0x1ff00000000, ctx=0 + set 0xe0000000, %g3 sllx %g3, 32, %g3 - or %g3, 0x76, %g3 + or %g3, 0x76, %g3 ! valid, 4M, locked, cacheable(I/E/C), priv, writable + mov %l3, %g4 or %g4, %g3, %g3 - ! valid, 64k, locked, cacheable(I/E/C), priv, writable - ! paddr = 0x1ff004a0000 stxa %g3, [%g0] ASI_DTLB_DATA_IN - add %g4, %g5, %g4 + add %l3, %g5, %l3 + add %l4, %g5, %l4 deccc %g6 bne 1b nop
#if 1 - ! setup 0-16M - mov %g0, %g4 - mov 4, %g6 + ! setup 0-64M of virtual space after 64M of physical space + setx REMAP_PADDR, %l1, %l3 ! physical address + setx 0, %l1, %l4 ! virtual address + + ! 16x4M mapped + mov 16, %g6 set 48, %g7 set 0x400000, %g5 -1: stxa %g4, [%g7] ASI_DMMU ! vaddr = 0, ctx=0 +1: mov %l4, %g4 + stxa %g4, [%g7] ASI_DMMU ! vaddr = 0x1ff00000000, ctx=0 set 0xe0000000, %g3 sllx %g3, 32, %g3 - or %g3, 0x36, %g3 + or %g3, 0x36, %g3 ! valid, 4M, cacheable(I/E/C), priv, writable + mov %l3, %g4 or %g4, %g3, %g3 - ! valid, 4M, cacheable(I/E/C), priv, writable - ! paddr = 0 stxa %g3, [%g0] ASI_DTLB_DATA_IN - add %g4, %g5, %g4 + add %l3, %g5, %l3 + add %l4, %g5, %l4 deccc %g6 bne 1b nop @@ -242,25 +255,6 @@ entry: bne 1b add %l2, %g5, %l2
-#if 1 - ! setup 0-16M - mov %g0, %g4 - mov 4, %g6 - set 0x400000, %g5 -1: stxa %g4, [%g7] ASI_IMMU ! vaddr = 0, ctx=0 - set 0xe0000000, %g3 - sllx %g3, 32, %g3 - or %g3, 0x34, %g3 - or %g4, %g3, %g3 - ! valid, 4M, cacheable(I/E/C), priv - ! paddr = 0 - stxa %g3, [%g0] ASI_ITLB_DATA_IN - add %g4, %g5, %g4 - deccc %g6 - bne 1b - nop -#endif - flush %g4
mov %g1, %g3
From: Igor V. Kovalenko igor.v.kovalenko@gmail.com
- claim both physical and virtual address ranges while walking boot memory mappings
Signed-off-by: Igor V. Kovalenko igor.v.kovalenko@gmail.com --- arch/sparc64/ofmem_sparc64.c | 2 ++ 1 files changed, 2 insertions(+), 0 deletions(-)
diff --git a/arch/sparc64/ofmem_sparc64.c b/arch/sparc64/ofmem_sparc64.c index e69f36b..e96060c 100644 --- a/arch/sparc64/ofmem_sparc64.c +++ b/arch/sparc64/ofmem_sparc64.c @@ -83,6 +83,8 @@ extern uint64_t qemu_mem_size;
static int remap_page_range( ucell phys, ucell virt, ucell size, ucell mode ) { + ofmem_claim_phys(phys, size, 0); + ofmem_claim_virt(virt, size, 0); ofmem_map_page_range(phys, virt, size, mode); if (!(mode & SPITFIRE_TTE_LOCKED)) { OFMEM_TRACE("remap_page_range clearing translation " FMT_ucellx
On Sat, Dec 26, 2009 at 10:07 PM, Igor V. Kovalenko igor.v.kovalenko@gmail.com wrote:
From: Igor V. Kovalenko igor.v.kovalenko@gmail.com
- claim both physical and virtual address ranges
while walking boot memory mappings
With this patch applied, SILO can't find enough memory. For example: SILO Version 1.4.13 \
Welcome to Debian GNU/Linux etch!
This is a Debian installation CDROM, built on 20070407-11:37. Keep it once you have installed your system, as you can boot from it to repair the system on your hard disk if that ever becomes necessary.
WARNING: You should completely back up all of your hard disks before proceeding. The installation procedure can completely and irreversibly erase them! If you haven't made backups yet, remove the rescue CD from the drive and press L1-A to get back to the OpenBoot prompt.
Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent permitted by applicable law.
[ ENTER - Boot install ] [ Type "expert" - Boot into expert mode ] [ Type "rescue" - Boot into rescue mode ] boot: Could not find any available memory Could not find any available memory Loaded kernel version 2.6.18 Could not find any available memory
Fatal error: You do not have enough continuous available memory for such initial ramdisk. EXIT 0 >
Without the patch, I get: boot: Allocated 8 Megs of memory at 0x40000000 for kernel Loaded kernel version 2.6.18 Loading initial ramdisk (3879265 bytes at 0xC00000 phys, 0x40C00000 virt)... - Remapping the kernel... done. Booting Linux... Inconsistent console: input 5, output 5 EXIT 123 >
On Sun, Dec 27, 2009 at 12:30 PM, Blue Swirl blauwirbel@gmail.com wrote:
On Sat, Dec 26, 2009 at 10:07 PM, Igor V. Kovalenko igor.v.kovalenko@gmail.com wrote:
From: Igor V. Kovalenko igor.v.kovalenko@gmail.com
- claim both physical and virtual address ranges
while walking boot memory mappings
With this patch applied, SILO can't find enough memory. For example:
Easy to reproduce, and expected. Please try -m 256 in qemu command line, 128M default is not enough.
On Sun, Dec 27, 2009 at 11:23 AM, Igor Kovalenko igor.v.kovalenko@gmail.com wrote:
On Sun, Dec 27, 2009 at 12:30 PM, Blue Swirl blauwirbel@gmail.com wrote:
On Sat, Dec 26, 2009 at 10:07 PM, Igor V. Kovalenko igor.v.kovalenko@gmail.com wrote:
From: Igor V. Kovalenko igor.v.kovalenko@gmail.com
- claim both physical and virtual address ranges
while walking boot memory mappings
With this patch applied, SILO can't find enough memory. For example:
Easy to reproduce, and expected. Please try -m 256 in qemu command line, 128M default is not enough.
Why? Is this related to changed mapping of first 64MB? Perhaps that value should be lower, for example 16MB?
On Sun, Dec 27, 2009 at 7:02 PM, Blue Swirl blauwirbel@gmail.com wrote:
On Sun, Dec 27, 2009 at 11:23 AM, Igor Kovalenko igor.v.kovalenko@gmail.com wrote:
On Sun, Dec 27, 2009 at 12:30 PM, Blue Swirl blauwirbel@gmail.com wrote:
On Sat, Dec 26, 2009 at 10:07 PM, Igor V. Kovalenko igor.v.kovalenko@gmail.com wrote:
From: Igor V. Kovalenko igor.v.kovalenko@gmail.com
- claim both physical and virtual address ranges
while walking boot memory mappings
With this patch applied, SILO can't find enough memory. For example:
Easy to reproduce, and expected. Please try -m 256 in qemu command line, 128M default is not enough.
Why? Is this related to changed mapping of first 64MB? Perhaps that value should be lower, for example 16MB?
Relocating 16M is not enough, since we have devices at 0x1000000 and 0x2000000
Then, patched silo tries to allocate 64M (original one was 8M) Since we have to fit bss and stack into RAM as well, 128M is exhausted.
From: Igor V. Kovalenko igor.v.kovalenko@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@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 );
On Sat, Dec 26, 2009 at 10:07 PM, Igor V. Kovalenko igor.v.kovalenko@gmail.com wrote:
From: Igor V. Kovalenko igor.v.kovalenko@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
It would be nice to split the patch to two pieces so that it would be OK to apply the ofmem_find_virtual part even without the 1/3 patch or VGA/cmdline part.
--- 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;
As a side note, QEMU should store the command line in fw_cfg like PC also for Sparc.
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;
What would be the correct solution, should pci.c use physical (or virtual?) addresses for assigned addresses, or should the assigned address be translated to physical/virtual before passing to callbacks?
On Sun, Dec 27, 2009 at 1:14 PM, Blue Swirl blauwirbel@gmail.com wrote:
On Sat, Dec 26, 2009 at 10:07 PM, Igor V. Kovalenko igor.v.kovalenko@gmail.com wrote:
From: Igor V. Kovalenko igor.v.kovalenko@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
It would be nice to split the patch to two pieces so that it would be OK to apply the ofmem_find_virtual part even without the 1/3 patch or VGA/cmdline part.
Will do the split, there to be 3 pieces.
--- 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;
As a side note, QEMU should store the command line in fw_cfg like PC also for Sparc.
I'll split this out as well, so when qemu part is ready we can revert this and install proper solution.
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;
What would be the correct solution, should pci.c use physical (or virtual?) addresses for assigned addresses, or should the assigned address be translated to physical/virtual before passing to callbacks?
To my mind vga_config_cb should map the bar into virtual address space, then pass virtual address to video init routine. Video module should work with already mapped framebuffer.
I decided to postpone change to vga_config_cb to minimize churn.