Hello,
In arch/ppc/qemu/ofmem.c, ofmem appears to be located at OFMEM == 0x05400000 == 84 MiB, with OF_MALLOC_BASE at OFMEM + sizeof(ofmem_t) 4- byte aligned. The upper limit from libopenbios/ofmem_common.c seems to be ofmem_arch_get_heap_top() == "hash base minus fixed value" though, with the hash base being relative to top of RAM.
This means, the malloc zone has a fixed lower limit and grows absolutely with the amount of RAM assigned to QEMU. Is this really intended? The code comment in ofmem.c rather looks like the fixed OFMEM value was taken from a 96 MB memory layout, where it would seem relative to top of RAM with fixed size.
Even worse, like any other memory on ppc this hugeish part of memory is never claimed...
I tried to move ofmem to RAM size - 0x100000 - 64 * 1024 - (32 + 64 + 64) * 1024 - 0x200000, but OpenBIOS just busy-looped and never reached the banner. Has anyone looked into this before? Any ideas what might be going wrong? I tried carefully not to include a call to ofmem_arch_get_private() inside setup_mmu().
Regards, Andreas
Am 10.10.2010 um 15:38 schrieb Andreas Färber:
In arch/ppc/qemu/ofmem.c, ofmem appears to be located at OFMEM == 0x05400000 == 84 MiB, with OF_MALLOC_BASE at OFMEM + sizeof(ofmem_t) 4-byte aligned. The upper limit from libopenbios/ofmem_common.c seems to be ofmem_arch_get_heap_top() == "hash base minus fixed value" though, with the hash base being relative to top of RAM.
[...]
I tried to move ofmem to RAM size - 0x100000 - 64 * 1024 - (32 + 64
- 1024 - 0x200000, but OpenBIOS just busy-looped and never
reached the banner.
Ahh... found that some functions made wrong assumptions about the hash base. It is not at get_rom_base() - HASH_SIZE, since it gets rounded down for alignment. And differently for ppc and ppc64. ;)
I've reordered some code for this to work and will send some patches later.
Andreas
This will simplify moving OpenBIOS around in memory.
Signed-off-by: Andreas Färber andreas.faerber@web.de --- arch/ppc/qemu/ofmem.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/arch/ppc/qemu/ofmem.c b/arch/ppc/qemu/ofmem.c index b06cb7e..7d0959b 100644 --- a/arch/ppc/qemu/ofmem.c +++ b/arch/ppc/qemu/ofmem.c @@ -415,7 +415,7 @@ setup_mmu( unsigned long ramsize ) asm volatile("mtsrin %0,%1" :: "r" (sr_base + i), "r" (j) ); }
- memcpy((void *)get_rom_base(), (void *)0xfff00000, 0x00100000); + memcpy((void *)get_rom_base(), (void *)OF_CODE_START, 0x00100000);
/* Enable MMU */
ofmem_free() has no return value and neither does free().
Signed-off-by: Andreas Färber andreas.faerber@web.de --- arch/ppc/qemu/ofmem.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/arch/ppc/qemu/ofmem.c b/arch/ppc/qemu/ofmem.c index 7d0959b..3ec25c3 100644 --- a/arch/ppc/qemu/ofmem.c +++ b/arch/ppc/qemu/ofmem.c @@ -178,7 +178,7 @@ malloc( int size ) void free( void *ptr ) { - return ofmem_free(ptr); + ofmem_free(ptr); }
void *
The hash base is not get_rom_base() - HASH_SIZE. It gets rounded down, depending on the PVR, so read its true value from SDR1.
According to the illustration in start.S, the stack is supposed to be 64 KiB.
Signed-off-by: Andreas Färber andreas.faerber@web.de --- arch/ppc/qemu/ofmem.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/arch/ppc/qemu/ofmem.c b/arch/ppc/qemu/ofmem.c index 3ec25c3..500752b 100644 --- a/arch/ppc/qemu/ofmem.c +++ b/arch/ppc/qemu/ofmem.c @@ -86,7 +86,7 @@ get_rom_base( void ) unsigned long get_ram_top( void ) { - return get_rom_base() - HASH_SIZE - (32 + 32 + 64) * 1024; + return get_hash_base() - (32 + 64 + 64) * 1024; }
unsigned long
ofmem was fixed at 0x05400000, followed by the malloc zone. The latter was bounded by the stack, relative to the top of RAM. An increase of RAM would therefore only enlarge the malloc zone.
Move the malloc zone below the stack, with a fixed size of 2 MiB. The size is derived from the memory map depicted in ofmem.c; having a fixed size leaves room for memory claim'ed by clients and by OpenBIOS.
Cc: Alexander Graf agraf@suse.de Signed-off-by: Andreas Färber andreas.faerber@web.de --- arch/ppc/qemu/ofmem.c | 19 +++++++++---------- arch/ppc/qemu/start.S | 4 ++++ 2 files changed, 13 insertions(+), 10 deletions(-)
diff --git a/arch/ppc/qemu/ofmem.c b/arch/ppc/qemu/ofmem.c index 500752b..711ed01 100644 --- a/arch/ppc/qemu/ofmem.c +++ b/arch/ppc/qemu/ofmem.c @@ -47,11 +47,9 @@ extern void setup_mmu( unsigned long code_base ); #define FREE_BASE 0x00004000 #define OF_CODE_START 0xfff00000UL #define IO_BASE 0x80000000 -#define OFMEM ((ofmem_t*)0x05400000) - -#define OF_MALLOC_BASE ((char*)OFMEM + ((sizeof(ofmem_t) + 3) & ~3))
#define HASH_SIZE (2 << 15) +#define OFMEM_SIZE (2 * 1024 * 1024)
#define SEGR_USER BIT(2) #define SEGR_BASE 0x0400 @@ -86,7 +84,7 @@ get_rom_base( void ) unsigned long get_ram_top( void ) { - return get_hash_base() - (32 + 64 + 64) * 1024; + return get_hash_base() - (32 + 64 + 64) * 1024 - OFMEM_SIZE; }
unsigned long @@ -107,12 +105,12 @@ static inline size_t ALIGN_SIZE(size_t x, size_t a)
ofmem_t* ofmem_arch_get_private(void) { - return OFMEM; + return (ofmem_t*)(get_heap_top() - OFMEM_SIZE); }
void* ofmem_arch_get_malloc_base(void) { - return OF_MALLOC_BASE; + return (char*)ofmem_arch_get_private() + ALIGN_SIZE(sizeof(ofmem_t), 4); }
ucell ofmem_arch_get_heap_top(void) @@ -388,15 +386,12 @@ isi_exception( void ) void setup_mmu( unsigned long ramsize ) { - ofmem_t *ofmem = OFMEM; + ofmem_t *ofmem; unsigned long sdr1, sr_base, msr; unsigned long hash_base; unsigned long hash_mask = 0xffff0000; int i;
- memset(ofmem, 0, sizeof(ofmem_t)); - ofmem->ramsize = ramsize; - /* SDR1: Storage Description Register 1 */
if(is_ppc64()) @@ -415,6 +410,10 @@ setup_mmu( unsigned long ramsize ) asm volatile("mtsrin %0,%1" :: "r" (sr_base + i), "r" (j) ); }
+ ofmem = ofmem_arch_get_private(); + memset(ofmem, 0, sizeof(ofmem_t)); + ofmem->ramsize = ramsize; + memcpy((void *)get_rom_base(), (void *)OF_CODE_START, 0x00100000);
/* Enable MMU */ diff --git a/arch/ppc/qemu/start.S b/arch/ppc/qemu/start.S index d74fb9c..9417098 100644 --- a/arch/ppc/qemu/start.S +++ b/arch/ppc/qemu/start.S @@ -321,6 +321,10 @@ GLOBL(_entry): * | | * +-------------------------+ * | | + * | Malloc Zone (2 MiB) | + * | | + * +-------------------------+ + * | | * | Client Stack (64 kB) | * | | * +-------------------------+
OpenBIOS kept getting overwritten in RAM by clients such as Haiku.
Make sure memory used by OpenBIOS cannot accidentally be claimed by someone else. This also sets up the "available" property as expected.
Signed-off-by: Andreas Färber andreas.faerber@web.de --- arch/ppc/qemu/ofmem.c | 4 ++++ 1 files changed, 4 insertions(+), 0 deletions(-)
diff --git a/arch/ppc/qemu/ofmem.c b/arch/ppc/qemu/ofmem.c index 711ed01..67fc1fe 100644 --- a/arch/ppc/qemu/ofmem.c +++ b/arch/ppc/qemu/ofmem.c @@ -428,6 +428,10 @@ ofmem_init( void ) { ofmem_t *ofmem = ofmem_arch_get_private();
+ ofmem_claim_phys(0, get_ram_bottom(), 0); + ofmem_claim_virt(0, get_ram_bottom(), 0); ofmem_map( 0, 0, get_ram_bottom(), 0 ); + ofmem_claim_phys(get_ram_top(), ofmem->ramsize - get_ram_top(), 0); + ofmem_claim_virt(get_ram_top(), ofmem->ramsize - get_ram_top(), 0); ofmem_map( get_ram_top(), get_ram_top(), ofmem->ramsize - get_ram_top(), 0); }
The exception stack was always set up 64 KiB below the ROM, ignoring hash table alignment. Align the stack pointer based on the PVR value.
Cc: Alexander Graf agraf@suse.de Signed-off-by: Andreas Färber andreas.faerber@web.de --- arch/ppc/qemu/start.S | 20 +++++++++++++++++++- 1 files changed, 19 insertions(+), 1 deletions(-)
diff --git a/arch/ppc/qemu/start.S b/arch/ppc/qemu/start.S index 9417098..ac1c0a3 100644 --- a/arch/ppc/qemu/start.S +++ b/arch/ppc/qemu/start.S @@ -334,9 +334,27 @@ GLOBL(_entry):
addis r1, r3, -16 /* ramsize - 1MB */
- /* setup exception stack */ + /* setup hash table */
addis r1, r1, -1 /* - 64 kB */ + + mfpvr r14 /* check if ppc64 */ + li r15, 4 + srw r14, r14, r15 /* >> 4 */ + cmplwi r14, 0x33 + blt 1f + cmplwi r14, 0x7033 + bge 1f + /* ppc64 */ + clrrdi r1, r1, 5 /* & 0xfffffffffff00000 */ + b 2f +1: + /* ppc */ + clrrwi r1, r1, 4 /* & 0xffff0000 */ +2: + + /* setup exception stack */ + mtsprg0 r1
/* setup stack */
- mfpvr r14 /* check if ppc64 */
- li r15, 4
- srw r14, r14, r15 /* >> 4 */
srwi 14,14,4
but you actually want to shift 16, not 4.
- cmplwi r14, 0x33
- blt 1f
- cmplwi r14, 0x7033
- bge 1f
This is too simplistic. Here's something that detects whether the CPU is currently in 64-bit mode, without using 64-bit-only instructions:
lis 3,0x4000 add 3,3,3 addc 3,3,3 adde 3,3,3 cmplwi 3,0 beq 64bit bne 32bit
Anyway, can't you always align to 128 bytes, and create one frame for the 64-bit ABI? Or do you really want to save those few bytes...
Segher
Am 11.10.2010 um 04:53 schrieb Segher Boessenkool:
- mfpvr r14 /* check if ppc64 */
- li r15, 4
- srw r14, r14, r15 /* >> 4 */
srwi 14,14,4
but you actually want to shift 16, not 4.
Oops!
- cmplwi r14, 0x33
- blt 1f
- cmplwi r14, 0x7033
- bge 1f
This is too simplistic.
Are you saying the original is_ppc64() function I transformed into assembler code is wrong, too?
static int is_ppc64(void) { unsigned int pvr; asm volatile("mfspr %0, 0x11f" : "=r" (pvr) );
return ((pvr >= 0x330000) && (pvr < 0x70330000)); }
Here's something that detects whether the CPU is currently in 64-bit mode, without using 64-bit-only instructions:
lis 3,0x4000 add 3,3,3 addc 3,3,3 adde 3,3,3 cmplwi 3,0 beq 64bit bne 32bit
Thanks! I'll give it a try.
Anyway, can't you always align to 128 bytes, and create one frame for the 64-bit ABI? Or do you really want to save those few bytes...
As for "those few bytes", I guess I mixed up bits and hexadecimal digits once again. An example:
-m 1024
RAM 0..0x40000000 OpenBIOS @ 0x3ff00000 Hash table @ 0x3fef0000 vs. 0x3fe00000
We'd be wasting 960 KiB. If that's acceptable, it'll simplify the code a little of course.
Andreas
Andreas Färber wrote:
Am 11.10.2010 um 04:53 schrieb Segher Boessenkool:
- mfpvr r14 /* check if ppc64 */
- li r15, 4
- srw r14, r14, r15 /* >> 4 */
srwi 14,14,4
but you actually want to shift 16, not 4.
Oops!
- cmplwi r14, 0x33
- blt 1f
- cmplwi r14, 0x7033
- bge 1f
This is too simplistic.
Are you saying the original is_ppc64() function I transformed into assembler code is wrong, too?
static int is_ppc64(void) { unsigned int pvr; asm volatile("mfspr %0, 0x11f" : "=r" (pvr) );
return ((pvr >= 0x330000) && (pvr < 0x70330000));
}
In here we don't know if SF=1 because we forcefully disable it always.
Here's something that detects whether the CPU is currently in 64-bit mode, without using 64-bit-only instructions:
lis 3,0x4000 add 3,3,3 addc 3,3,3 adde 3,3,3 cmplwi 3,0 beq 64bit bne 32bit
Thanks! I'll give it a try.
Anyway, can't you always align to 128 bytes, and create one frame for the 64-bit ABI? Or do you really want to save those few bytes...
As for "those few bytes", I guess I mixed up bits and hexadecimal digits once again. An example:
-m 1024
RAM 0..0x40000000 OpenBIOS @ 0x3ff00000 Hash table @ 0x3fef0000 vs. 0x3fe00000
We'd be wasting 960 KiB. If that's acceptable, it'll simplify the code a little of course.
I'd personally say go for simplicity.
Alex
Am 11.10.2010 um 11:16 schrieb Alexander Graf:
Andreas Färber wrote:
Am 11.10.2010 um 04:53 schrieb Segher Boessenkool:
- mfpvr r14 /* check if ppc64 */
- li r15, 4
- srw r14, r14, r15 /* >> 4 */
srwi 14,14,4
but you actually want to shift 16, not 4.
Oops!
- cmplwi r14, 0x33
- blt 1f
- cmplwi r14, 0x7033
- bge 1f
This is too simplistic.
Are you saying the original is_ppc64() function I transformed into assembler code is wrong, too?
static int is_ppc64(void) { unsigned int pvr; asm volatile("mfspr %0, 0x11f" : "=r" (pvr) );
return ((pvr >= 0x330000) && (pvr < 0x70330000)); }
In here we don't know if SF=1 because we forcefully disable it always.
Ah! You mean this?
li r0, 0 mtmsr r0
That would mean I don't need a 64-bit RTAS unless AIX sets SF=1. :)
Here's something that detects whether the CPU is currently in 64-bit mode, without using 64-bit-only instructions:
lis 3,0x4000 add 3,3,3 addc 3,3,3 adde 3,3,3 cmplwi 3,0 beq 64bit bne 32bit
Thanks! I'll give it a try.
Anyway, can't you always align to 128 bytes, and create one frame for the 64-bit ABI? Or do you really want to save those few bytes...
As for "those few bytes", I guess I mixed up bits and hexadecimal digits once again. An example:
-m 1024
RAM 0..0x40000000 OpenBIOS @ 0x3ff00000 Hash table @ 0x3fef0000 vs. 0x3fe00000
We'd be wasting 960 KiB. If that's acceptable, it'll simplify the code a little of course.
I'd personally say go for simplicity.
On second thoughts, unfortunately I don't think 32-bit CPUs can handle clrrdi, so we'd still need the distinction here since we're subtracting from RAM size.
Or better, we'd need a distinction at the original setup of r1, so that it fits into the low 32 or 31 bits in the first place. Currently everything over -m 2048 would overlap with ISA and at some point PCI and fw_cfg. Memory would probably have to become non-contiguous then, breaking some more assumptions...
Andreas
This will simplify moving OpenBIOS around in memory.
Signed-off-by: Andreas Färber andreas.faerber@web.de --- arch/ppc/qemu/ofmem.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/arch/ppc/qemu/ofmem.c b/arch/ppc/qemu/ofmem.c index b06cb7e..7d0959b 100644 --- a/arch/ppc/qemu/ofmem.c +++ b/arch/ppc/qemu/ofmem.c @@ -415,7 +415,7 @@ setup_mmu( unsigned long ramsize ) asm volatile("mtsrin %0,%1" :: "r" (sr_base + i), "r" (j) ); }
- memcpy((void *)get_rom_base(), (void *)0xfff00000, 0x00100000); + memcpy((void *)get_rom_base(), (void *)OF_CODE_START, 0x00100000);
/* Enable MMU */
ofmem_free() has no return value and neither does free().
Signed-off-by: Andreas Färber andreas.faerber@web.de --- arch/ppc/qemu/ofmem.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/arch/ppc/qemu/ofmem.c b/arch/ppc/qemu/ofmem.c index 7d0959b..3ec25c3 100644 --- a/arch/ppc/qemu/ofmem.c +++ b/arch/ppc/qemu/ofmem.c @@ -178,7 +178,7 @@ malloc( int size ) void free( void *ptr ) { - return ofmem_free(ptr); + ofmem_free(ptr); }
void *
According to the illustration in start.S, the stack size is supposed to be 64 KiB.
v2: * Split up.
Signed-off-by: Andreas Färber andreas.faerber@web.de --- arch/ppc/qemu/ofmem.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/arch/ppc/qemu/ofmem.c b/arch/ppc/qemu/ofmem.c index 3ec25c3..f181c77 100644 --- a/arch/ppc/qemu/ofmem.c +++ b/arch/ppc/qemu/ofmem.c @@ -86,7 +86,7 @@ get_rom_base( void ) unsigned long get_ram_top( void ) { - return get_rom_base() - HASH_SIZE - (32 + 32 + 64) * 1024; + return get_rom_base() - HASH_SIZE - (32 + 64 + 64) * 1024; }
unsigned long
The hash base is not get_rom_base() - HASH_SIZE. It gets rounded down, depending on the PVR, so read its true value from SDR1.
v2: * Split up.
Signed-off-by: Andreas Färber andreas.faerber@web.de --- arch/ppc/qemu/ofmem.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/arch/ppc/qemu/ofmem.c b/arch/ppc/qemu/ofmem.c index f181c77..500752b 100644 --- a/arch/ppc/qemu/ofmem.c +++ b/arch/ppc/qemu/ofmem.c @@ -86,7 +86,7 @@ get_rom_base( void ) unsigned long get_ram_top( void ) { - return get_rom_base() - HASH_SIZE - (32 + 64 + 64) * 1024; + return get_hash_base() - (32 + 64 + 64) * 1024; }
unsigned long
Don't let the client stack and the heap overlap.
v2: * Initial.
Signed-off-by: Andreas Färber andreas.faerber@web.de --- arch/ppc/qemu/ofmem.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/arch/ppc/qemu/ofmem.c b/arch/ppc/qemu/ofmem.c index 500752b..a45c96c 100644 --- a/arch/ppc/qemu/ofmem.c +++ b/arch/ppc/qemu/ofmem.c @@ -97,7 +97,7 @@ get_ram_bottom( void )
static ucell get_heap_top( void ) { - return get_hash_base() - (32 + 64) * 1024; + return get_hash_base() - (32 + 64 + 64) * 1024; }
static inline size_t ALIGN_SIZE(size_t x, size_t a)
OpenBIOS kept getting overwritten in RAM by clients such as Haiku.
Make sure memory used by OpenBIOS cannot accidentally be claimed by someone else. This also sets up the "available" property as expected.
Note that we avoid ofmem_claim() as it would map the pages using a default mode, followed by a remap with the desired mode.
v2: * Reordered. * Added spacing.
Signed-off-by: Andreas Färber andreas.faerber@web.de --- arch/ppc/qemu/ofmem.c | 5 +++++ 1 files changed, 5 insertions(+), 0 deletions(-)
diff --git a/arch/ppc/qemu/ofmem.c b/arch/ppc/qemu/ofmem.c index a45c96c..4c813a0 100644 --- a/arch/ppc/qemu/ofmem.c +++ b/arch/ppc/qemu/ofmem.c @@ -429,6 +429,11 @@ ofmem_init( void ) { ofmem_t *ofmem = ofmem_arch_get_private();
+ ofmem_claim_phys(0, get_ram_bottom(), 0); + ofmem_claim_virt(0, get_ram_bottom(), 0); ofmem_map( 0, 0, get_ram_bottom(), 0 ); + + ofmem_claim_phys(get_ram_top(), ofmem->ramsize - get_ram_top(), 0); + ofmem_claim_virt(get_ram_top(), ofmem->ramsize - get_ram_top(), 0); ofmem_map( get_ram_top(), get_ram_top(), ofmem->ramsize - get_ram_top(), 0); }
ofmem was fixed at 0x05400000, followed by the malloc zone. The latter was bounded by the stack (now client stack), relative to the top of RAM. An increase of RAM would therefore only enlarge the malloc zone.
Move the malloc zone below the client stack, with a fixed size of 2 MiB. The size is derived from the memory map depicted in ofmem.c; having a fixed size leaves room for memory claim'ed by clients and by OpenBIOS.
v2: * Through the preceding patch the malloc zone goes below the client stack rather than below the stack. Adjust and prettify the illustration.
Cc: Alexander Graf agraf@suse.de Signed-off-by: Andreas Färber andreas.faerber@web.de --- arch/ppc/qemu/ofmem.c | 19 +++++++++---------- arch/ppc/qemu/start.S | 8 ++++++-- 2 files changed, 15 insertions(+), 12 deletions(-)
diff --git a/arch/ppc/qemu/ofmem.c b/arch/ppc/qemu/ofmem.c index 4c813a0..afd5808 100644 --- a/arch/ppc/qemu/ofmem.c +++ b/arch/ppc/qemu/ofmem.c @@ -47,11 +47,9 @@ extern void setup_mmu( unsigned long code_base ); #define FREE_BASE 0x00004000 #define OF_CODE_START 0xfff00000UL #define IO_BASE 0x80000000 -#define OFMEM ((ofmem_t*)0x05400000) - -#define OF_MALLOC_BASE ((char*)OFMEM + ((sizeof(ofmem_t) + 3) & ~3))
#define HASH_SIZE (2 << 15) +#define OFMEM_SIZE (2 * 1024 * 1024)
#define SEGR_USER BIT(2) #define SEGR_BASE 0x0400 @@ -86,7 +84,7 @@ get_rom_base( void ) unsigned long get_ram_top( void ) { - return get_hash_base() - (32 + 64 + 64) * 1024; + return get_hash_base() - (32 + 64 + 64) * 1024 - OFMEM_SIZE; }
unsigned long @@ -107,12 +105,12 @@ static inline size_t ALIGN_SIZE(size_t x, size_t a)
ofmem_t* ofmem_arch_get_private(void) { - return OFMEM; + return (ofmem_t*)(get_heap_top() - OFMEM_SIZE); }
void* ofmem_arch_get_malloc_base(void) { - return OF_MALLOC_BASE; + return (char*)ofmem_arch_get_private() + ALIGN_SIZE(sizeof(ofmem_t), 4); }
ucell ofmem_arch_get_heap_top(void) @@ -388,15 +386,12 @@ isi_exception( void ) void setup_mmu( unsigned long ramsize ) { - ofmem_t *ofmem = OFMEM; + ofmem_t *ofmem; unsigned long sdr1, sr_base, msr; unsigned long hash_base; unsigned long hash_mask = 0xffff0000; int i;
- memset(ofmem, 0, sizeof(ofmem_t)); - ofmem->ramsize = ramsize; - /* SDR1: Storage Description Register 1 */
if(is_ppc64()) @@ -415,6 +410,10 @@ setup_mmu( unsigned long ramsize ) asm volatile("mtsrin %0,%1" :: "r" (sr_base + i), "r" (j) ); }
+ ofmem = ofmem_arch_get_private(); + memset(ofmem, 0, sizeof(ofmem_t)); + ofmem->ramsize = ramsize; + memcpy((void *)get_rom_base(), (void *)OF_CODE_START, 0x00100000);
/* Enable MMU */ diff --git a/arch/ppc/qemu/start.S b/arch/ppc/qemu/start.S index d74fb9c..d0d51b5 100644 --- a/arch/ppc/qemu/start.S +++ b/arch/ppc/qemu/start.S @@ -313,17 +313,21 @@ GLOBL(_entry): * | | * +-------------------------+ * | | - * | Exception Stack (32 kB) + * | Exception Stack (32 kB) | * | | * +-------------------------+ * | | - * | Stack (64 kB) + * | Stack (64 kB) | * | | * +-------------------------+ * | | * | Client Stack (64 kB) | * | | * +-------------------------+ + * | | + * | Malloc Zone (2 MiB) | + * | | + * +-------------------------+ * : : * Bottom */
To avoid complications with ppc64, always use the ppc64 alignment.
v2: * Initial. Suggested by Segher Boessenkool.
Cc: Segher Boessenkool segher@kernel.crashing.org Cc: Alexander Graf agraf@suse.de Signed-off-by: Andreas Färber andreas.faerber@web.de --- arch/ppc/qemu/ofmem.c | 5 +---- 1 files changed, 1 insertions(+), 4 deletions(-)
diff --git a/arch/ppc/qemu/ofmem.c b/arch/ppc/qemu/ofmem.c index afd5808..189dae3 100644 --- a/arch/ppc/qemu/ofmem.c +++ b/arch/ppc/qemu/ofmem.c @@ -389,14 +389,11 @@ setup_mmu( unsigned long ramsize ) ofmem_t *ofmem; unsigned long sdr1, sr_base, msr; unsigned long hash_base; - unsigned long hash_mask = 0xffff0000; + unsigned long hash_mask = 0xfff00000; /* alignment for ppc64 */ int i;
/* SDR1: Storage Description Register 1 */
- if(is_ppc64()) - hash_mask = 0xfff00000; - hash_base = (ramsize - 0x00100000 - HASH_SIZE) & hash_mask; memset((void *)hash_base, 0, HASH_SIZE); sdr1 = hash_base | ((HASH_SIZE-1) >> 16);
The exception stack was always set up 64 KiB below the ROM, ignoring hash table alignment. Align the stack pointer appropriately.
v2: * Drop buggy distinction based on PVR value since the previous patch unifies alignment. Suggested by Segher Boessenkool.
Cc: Alexander Graf agraf@suse.de Cc: Segher Boessenkool segher@kernel.crashing.org Signed-off-by: Andreas Färber andreas.faerber@web.de --- arch/ppc/qemu/start.S | 6 +++++- 1 files changed, 5 insertions(+), 1 deletions(-)
diff --git a/arch/ppc/qemu/start.S b/arch/ppc/qemu/start.S index d0d51b5..0775536 100644 --- a/arch/ppc/qemu/start.S +++ b/arch/ppc/qemu/start.S @@ -334,9 +334,13 @@ GLOBL(_entry):
addis r1, r3, -16 /* ramsize - 1MB */
- /* setup exception stack */ + /* setup hash table */
addis r1, r1, -1 /* - 64 kB */ + clrrwi r1, r1, 5*4 /* & ~0xfffff */ + + /* setup exception stack */ + mtsprg0 r1
/* setup stack */
The client stack was set up 96 * 64 KiB below the hash table. Should be 96 KiB instead.
v2: * Initial.
Cc: Alexander Graf agraf@suse.de Signed-off-by: Andreas Färber andreas.faerber@web.de --- arch/ppc/qemu/start.S | 3 ++- 1 files changed, 2 insertions(+), 1 deletions(-)
diff --git a/arch/ppc/qemu/start.S b/arch/ppc/qemu/start.S index 0775536..c995581 100644 --- a/arch/ppc/qemu/start.S +++ b/arch/ppc/qemu/start.S @@ -379,7 +379,8 @@ GLOBL(call_elf): addi r8,r8,LO(saved_stack) // save our stack pointer stw r1,0(r8) mfsdr1 r1 - addis r1, r1, -96 + addi r1, r1, -32768 /* - 32 KiB exception stack */ + addis r1, r1, -1 /* - 64 KiB stack */ lis r5,HA(of_client_callback) addi r5,r5,LO(of_client_callback) // r5 = callback li r6,0 // r6 = address of client program arguments (unused)
Thanks, applied all 10.
On Mon, Oct 11, 2010 at 12:47 PM, Andreas Färber andreas.faerber@web.de wrote:
The client stack was set up 96 * 64 KiB below the hash table. Should be 96 KiB instead.
v2:
- Initial.
Cc: Alexander Graf agraf@suse.de Signed-off-by: Andreas Färber andreas.faerber@web.de
arch/ppc/qemu/start.S | 3 ++- 1 files changed, 2 insertions(+), 1 deletions(-)
diff --git a/arch/ppc/qemu/start.S b/arch/ppc/qemu/start.S index 0775536..c995581 100644 --- a/arch/ppc/qemu/start.S +++ b/arch/ppc/qemu/start.S @@ -379,7 +379,8 @@ GLOBL(call_elf): addi r8,r8,LO(saved_stack) // save our stack pointer stw r1,0(r8) mfsdr1 r1
- addis r1, r1, -96
- addi r1, r1, -32768 /* - 32 KiB exception stack */
- addis r1, r1, -1 /* - 64 KiB stack */
lis r5,HA(of_client_callback) addi r5,r5,LO(of_client_callback) // r5 = callback li r6,0 // r6 = address of client program arguments (unused) -- 1.7.3
-- OpenBIOS http://openbios.org/ Mailinglist: http://lists.openbios.org/mailman/listinfo Free your System - May the Forth be with you
Am 11.10.2010 um 00:54 schrieb Andreas Färber:
ofmem was fixed at 0x05400000, followed by the malloc zone. The latter was bounded by the stack, relative to the top of RAM. An increase of RAM would therefore only enlarge the malloc zone.
Move the malloc zone below the stack, with a fixed size of 2 MiB. The size is derived from the memory map depicted in ofmem.c; having a fixed size leaves room for memory claim'ed by clients and by OpenBIOS.
Cc: Alexander Graf agraf@suse.de Signed-off-by: Andreas Färber andreas.faerber@web.de
Patch is flawed wrt the client stack. Previous calculation had an overlap between malloc zone and client stack that needs to be fixed. Thus, the malloc zone better goes below the client stack than below the stack. The addis r1, r1, -96 in start.S still looks wrong.
Andreas