Hi folks,
Following on from the thread "Re: [OpenBIOS] Haiku/ppc regression?", please find the attached patch for testing. Andreas, if this works, how much further does the Haiku boot get?
ATB,
Mark.
On Fri, May 21, 2010 at 2:03 PM, Mark Cave-Ayland mark.cave-ayland@siriusit.co.uk wrote:
Hi folks,
Following on from the thread "Re: [OpenBIOS] Haiku/ppc regression?", please find the attached patch for testing. Andreas, if this works, how much further does the Haiku boot get?
Looks good.
Please note that in the future we will need to change props array type from ucell to uint32_t since we will have to use encode-int on it's elements. For 32bit arch this is not an issue, since ucell has the same size as uint32_t.
Igor Kovalenko wrote:
Looks good.
Okay - I'll apply it and wait for the screams if it breaks ;)
Please note that in the future we will need to change props array type from ucell to uint32_t since we will have to use encode-int on it's elements. For 32bit arch this is not an issue, since ucell has the same size as uint32_t.
Yeah - I was thinking about this the other day and musing how difficult it would be to move SPARC32 over to ofmem. Not only would it help squash these kind of bugs, but it would also give Artyom a helping hand too.
I think I could probably do some of the work, but would struggle with the SPARC assembler for MMU entries and the I/O mapping in SPARC32. Is this something you think you'd be able to take a quick look at?
ATB,
Mark.
On Fri, May 21, 2010 at 11:03 AM, Mark Cave-Ayland mark.cave-ayland@siriusit.co.uk wrote:
Igor Kovalenko wrote:
Looks good.
Okay - I'll apply it and wait for the screams if it breaks ;)
Please note that in the future we will need to change props array type from ucell to uint32_t since we will have to use encode-int on it's elements. For 32bit arch this is not an issue, since ucell has the same size as uint32_t.
Yeah - I was thinking about this the other day and musing how difficult it would be to move SPARC32 over to ofmem. Not only would it help squash these kind of bugs, but it would also give Artyom a helping hand too.
I think I could probably do some of the work, but would struggle with the SPARC assembler for MMU entries and the I/O mapping in SPARC32. Is this something you think you'd be able to take a quick look at?
There's also romvec tables that need to be managed. They are probably the primary interface for any OS.
No need for any assembler except the macros at the end of arch/sparc32/lib.c. Sparc32 MMU is very simple, the thorough description in V8 manual is ~20 pages.
IOMMU is described in Sun4M System Architecture Manual. IOMMU maps physical pages to device virtual memory space, much like MMU maps physical pages to CPU virtual space.
Blue Swirl wrote:
I think I could probably do some of the work, but would struggle with the SPARC assembler for MMU entries and the I/O mapping in SPARC32. Is this something you think you'd be able to take a quick look at?
There's also romvec tables that need to be managed. They are probably the primary interface for any OS.
No need for any assembler except the macros at the end of arch/sparc32/lib.c. Sparc32 MMU is very simple, the thorough description in V8 manual is ~20 pages.
IOMMU is described in Sun4M System Architecture Manual. IOMMU maps physical pages to device virtual memory space, much like MMU maps physical pages to CPU virtual space.
Well maybe I'll take a break from the OpenSolaris work for a while and take a look at this to try and understand SPARC better. At the moment, I'm working on an a patchset to finish off proper load/boot support but this is currently taking longer than expected as I'm experiencing strange bugs in grubfs :(
ATB,
Mark.
Hi Mark,
Thanks,
Am 21.05.2010 um 12:03 schrieb Mark Cave-Ayland:
Andreas, if this works, how much further does the Haiku boot get?
The stock nightly CD images (http://haiku-files.org/ppc/index.php?show=all ) don't visibly get further.
Locally, with the attached patch applied to Haiku's boot loader, I avoid a memset on the memory returned by of_claim and thus get to some debug output I've enabled in arch/ppc/mmu.cpp:find_allocated_ranges (the "0: map: ..." stuff).
Comparison with Apple's OpenFirmware shows that: * Apple's of_claim returns memory at 0x00400000 (vs. 0x07f00000) * On the Mac I see an identity-mapped area at 0x00400000, length 4194304, mode 16 (vs. mode 2 and size 1048576 for 0x07f00000 from OpenBIOS)
Haiku seems to actually claim 1048576 bytes for the new page table, so I guess it uses up all available memory? Where can we bump that number? QEMU?
Regards, Andreas
Am 22.05.2010 um 15:37 schrieb Andreas Färber:
Am 21.05.2010 um 12:03 schrieb Mark Cave-Ayland:
Andreas, if this works, how much further does the Haiku boot get?
The stock nightly CD images (http://haiku-files.org/ppc/index.php?show=all ) don't visibly get further.
Locally, with the attached patch applied to Haiku's boot loader, I avoid a memset on the memory returned by of_claim and thus get to some debug output I've enabled in arch/ppc/ mmu.cpp:find_allocated_ranges (the "0: map: ..." stuff).
Forgot to state the obvious: Numbers in the debug output do look better since r772! :)
Comparison with Apple's OpenFirmware shows that:
- Apple's of_claim returns memory at 0x00400000 (vs. 0x07f00000)
- On the Mac I see an identity-mapped area at 0x00400000, length
4194304, mode 16 (vs. mode 2 and size 1048576 for 0x07f00000 from OpenBIOS)
Haiku seems to actually claim 1048576 bytes for the new page table, so I guess it uses up all available memory?
Where can we bump that number? QEMU?
Let me rephrase the question:
If I read QEMU code correctly (hw/ppc_{new,old}world.c, hw/ppc_mac.h) then OpenBIOS should be loaded at PROM_ADDR (0xfff00000) of size BIOS_SIZE (1024 * 1024), i.e. the last 1 MiB of address space. Yet I don't see a translation for that.
Neither QEMU nor OpenBIOS have 0x07f00000 hardcoded anywhere. Where is it coming from?
Andreas
Am 24.05.2010 um 11:23 schrieb Andreas Färber:
Am 22.05.2010 um 15:37 schrieb Andreas Färber:
Comparison with Apple's OpenFirmware shows that:
- Apple's of_claim returns memory at 0x00400000 (vs. 0x07f00000)
- On the Mac I see an identity-mapped area at 0x00400000, length
4194304, mode 16 (vs. mode 2 and size 1048576 for 0x07f00000 from OpenBIOS)
Haiku seems to actually claim 1048576 bytes for the new page table, [...]
If I read QEMU code correctly (hw/ppc_{new,old}world.c, hw/ ppc_mac.h) then OpenBIOS should be loaded at PROM_ADDR (0xfff00000) of size BIOS_SIZE (1024 * 1024), i.e. the last 1 MiB of address space. Yet I don't see a translation for that.
Neither QEMU nor OpenBIOS have 0x07f00000 hardcoded anywhere. Where is it coming from?
Gosh! 0x07f00000 is the RAM size (128 MiB = 0x08000000) minus the claimed size of 1048576. But that's exactly where arch/ppc/qemu/ ofmem.c:setup_mmu copies the OpenBIOS binary to from the QEMU- specified 0xfff00000 location!
So we are indeed overwriting OpenBIOS code, which explains the formerly printed invalid opcode warnings from QEMU.
With a hack such as the following, effectively using ppc's get_ram_top() as maximum, I can make a little visible progress.
diff --git a/libopenbios/ofmem_common.c b/libopenbios/ofmem_common.c index 1e797b3..2219a91 100644 --- a/libopenbios/ofmem_common.c +++ b/libopenbios/ofmem_common.c @@ -492,8 +492,8 @@ ucell ofmem_claim( ucell addr, ucell size, ucell align ) } else { if( align < 0x1000 ) align = 0x1000; - phys = ofmem_claim_phys_( addr, size, align, 0, get_ram_size(), 1 / * reverse */ ); - virt = ofmem_claim_virt_( addr, size, align, 0, get_ram_size(), 1 / * reverse */ ); + phys = ofmem_claim_phys_( addr, size, align, 0, get_ram_size() - 0x00100000 - (2 << 15) - (32 + 32 + 64) * 1024, 1 /* reverse */ ); + virt = ofmem_claim_virt_( addr, size, align, 0, get_ram_size() - 0x00100000 - (2 << 15) - (32 + 32 + 64) * 1024, 1 /* reverse */ ); if( phys == -1 || virt == -1 ) { OFMEM_TRACE("ofmem_claim failed\n"); return -1;
For http://haiku-files.org/ppc/haiku-r36919-ppc-haiku-boot-cd-ppc.zip leading to:
============================================================= OpenBIOS 1.0 [May 24 2010 13:11] Configuration device id QEMU version 1 machine id 2 CPUs: 1 Memory: 128M UUID: 00000000-0000-0000-0000-000000000000 CPU type PowerPC,750
Welcome to OpenBIOS v1.0 built on May 24 2010 13:11
checking for memory... 0: base = 0x00000000, size = 134217728 1: empty region total physical memory = 128 MB suggested page table size = 1048576 need new page table, size = 1048576!
OFMEM: ofmem_map_page_range 07d00000 -> 07d00000 00100000 mode
00000002 new table at: 0x07d00000 MSR: 0x00003030 found 4 translations found exception handlers! found page table!
Cheers,
Andreas
On 5/24/10 4:18 PM, Andreas Färber wrote:
phys = ofmem_claim_phys_( addr, size, align, 0,
get_ram_size() - 0x00100000 - (2 << 15) - (32 + 32 + 64) * 1024, 1 /* reverse */ );
virt = ofmem_claim_virt_( addr, size, align, 0,
get_ram_size() - 0x00100000 - (2 << 15) - (32 + 32 + 64) * 1024, 1 /* reverse */ );
This kind of yells for a comment explaining what those numbers are.
Stefan
Am 24.05.2010 um 16:22 schrieb Stefan Reinauer:
On 5/24/10 4:18 PM, Andreas Färber wrote:
phys = ofmem_claim_phys_( addr, size, align, 0,
get_ram_size() - 0x00100000 - (2 << 15) - (32 + 32 + 64) * 1024, 1 /* reverse */ );
virt = ofmem_claim_virt_( addr, size, align, 0,
get_ram_size() - 0x00100000 - (2 << 15) - (32 + 32 + 64) * 1024, 1 /* reverse */ );
This kind of yells for a comment explaining what those numbers are.
These are ppc-specific magic numbers in common code where they have no business being - please don't apply!
The question is, why does claim overwrite the 0x07ed0000 identity map of length 1245184, that I see no in my debug output now, with a 0x07f00000 map when using the vanilla OpenBIOS code? And do we need to supply platform-specific functions arch_get_ram_top and arch_get_ram_bottom, or is my approach just working around the problem?
Andreas
2010/5/24 Andreas Färber andreas.faerber@web.de:
Am 24.05.2010 um 16:22 schrieb Stefan Reinauer:
On 5/24/10 4:18 PM, Andreas Färber wrote:
- phys = ofmem_claim_phys_( addr, size, align, 0,
get_ram_size() - 0x00100000 - (2 << 15) - (32 + 32 + 64) * 1024, 1 /* reverse */ );
- virt = ofmem_claim_virt_( addr, size, align, 0,
get_ram_size() - 0x00100000 - (2 << 15) - (32 + 32 + 64) * 1024, 1 /* reverse */ );
This kind of yells for a comment explaining what those numbers are.
These are ppc-specific magic numbers in common code where they have no business being - please don't apply!
The question is, why does claim overwrite the 0x07ed0000 identity map of length 1245184, that I see no in my debug output now, with a 0x07f00000 map when using the vanilla OpenBIOS code? And do we need to supply platform-specific functions arch_get_ram_top and arch_get_ram_bottom, or is my approach just working around the problem?
Not sure if it's a platform-specific problem: on sparc32 with a similar patch Solaris boot gets a bit further.
Am 24.05.2010 um 17:21 schrieb Artyom Tarasenko:
2010/5/24 Andreas Färber andreas.faerber@web.de:
Am 24.05.2010 um 16:22 schrieb Stefan Reinauer:
On 5/24/10 4:18 PM, Andreas Färber wrote:
phys = ofmem_claim_phys_( addr, size, align, 0,
get_ram_size() - 0x00100000 - (2 << 15) - (32 + 32 + 64) * 1024, 1 /* reverse */ );
virt = ofmem_claim_virt_( addr, size, align, 0,
get_ram_size() - 0x00100000 - (2 << 15) - (32 + 32 + 64) * 1024, 1 /* reverse */ );
The question is, why does claim overwrite the 0x07ed0000 identity map of length 1245184, that I see no in my debug output now, with a 0x07f00000 map when using the vanilla OpenBIOS code? And do we need to supply platform-specific functions arch_get_ram_top and arch_get_ram_bottom, or is my approach just working around the problem?
Not sure if it's a platform-specific problem: on sparc32 with a similar patch Solaris boot gets a bit further.
I've dropped the above patch in favor of a more readable ppc-only one:
diff --git a/arch/ppc/qemu/ofmem.c b/arch/ppc/qemu/ofmem.c index 7631a1c..2a5eca2 100644 --- a/arch/ppc/qemu/ofmem.c +++ b/arch/ppc/qemu/ofmem.c @@ -431,4 +431,5 @@ ofmem_init( void )
ofmem_map( 0, 0, get_ram_bottom(), 0 ); ofmem_map( get_ram_top(), get_ram_top(), ofmem->ramsize - get_ram_top(), 0); + ofmem_claim(get_ram_top(), ofmem->ramsize - get_ram_top(), 0); }
ofmem_common.c:is_free considers 0x07f00000 free because it only sees one range in ofmem->phys_range, 0x80000000 size 962560. Thus, I simply claim the reserved part of RAM - no idea what side effects this may have...
On sparc64, instead of ofmem_map, opmem_map_page_range is called, but no ofmem_claim either.
Either way Haiku then hangs while trying to set the first segment register (mtsrin): http://dev.haiku-os.org/browser/haiku/trunk/src/system/boot/platform/openfir...
Andreas
Andreas Färber wrote:
I've dropped the above patch in favor of a more readable ppc-only one:
diff --git a/arch/ppc/qemu/ofmem.c b/arch/ppc/qemu/ofmem.c index 7631a1c..2a5eca2 100644 --- a/arch/ppc/qemu/ofmem.c +++ b/arch/ppc/qemu/ofmem.c @@ -431,4 +431,5 @@ ofmem_init( void )
ofmem_map( 0, 0, get_ram_bottom(), 0 ); ofmem_map( get_ram_top(), get_ram_top(), ofmem->ramsize -
get_ram_top(), 0);
- ofmem_claim(get_ram_top(), ofmem->ramsize - get_ram_top(), 0);
}
ofmem_common.c:is_free considers 0x07f00000 free because it only sees one range in ofmem->phys_range, 0x80000000 size 962560. Thus, I simply claim the reserved part of RAM - no idea what side effects this may have...
On sparc64, instead of ofmem_map, opmem_map_page_range is called, but no ofmem_claim either.
On SPARC64 I think ofmem_walk_boot_map/ofmem_map_page_range are used to set up the translations to cover the regions of memory used to hold OpenBIOS and beyond. According to the spec, a standard claim should NOT automatically generate a mapping IIRC as I had to fix this to get SPARC64 to boot further under OpenSolaris.
Either way Haiku then hangs while trying to set the first segment register (mtsrin): http://dev.haiku-os.org/browser/haiku/trunk/src/system/boot/platform/openfir...
Interesting. It's great to see you making progress with this :)
ATB,
Mark.
On Mon, May 24, 2010 at 9:02 PM, Mark Cave-Ayland mark.cave-ayland@siriusit.co.uk wrote:
Andreas Färber wrote:
I've dropped the above patch in favor of a more readable ppc-only one:
diff --git a/arch/ppc/qemu/ofmem.c b/arch/ppc/qemu/ofmem.c index 7631a1c..2a5eca2 100644 --- a/arch/ppc/qemu/ofmem.c +++ b/arch/ppc/qemu/ofmem.c @@ -431,4 +431,5 @@ ofmem_init( void )
ofmem_map( 0, 0, get_ram_bottom(), 0 ); ofmem_map( get_ram_top(), get_ram_top(), ofmem->ramsize - get_ram_top(), 0);
- ofmem_claim(get_ram_top(), ofmem->ramsize - get_ram_top(), 0);
}
ofmem_common.c:is_free considers 0x07f00000 free because it only sees one range in ofmem->phys_range, 0x80000000 size 962560. Thus, I simply claim the reserved part of RAM - no idea what side effects this may have...
On sparc64, instead of ofmem_map, opmem_map_page_range is called, but no ofmem_claim either.
On SPARC64 I think ofmem_walk_boot_map/ofmem_map_page_range are used to set up the translations to cover the regions of memory used to hold OpenBIOS and beyond. According to the spec, a standard claim should NOT automatically generate a mapping IIRC as I had to fix this to get SPARC64 to boot further under OpenSolaris.
Right. For sparc64 we copy mappings from hardware tables set up by asm bootstrap code using a walk over hardware translations. Most of bootstrap mappings are locked into tlb so we do not really need to handle translations for them. Instead we use bootstrap mappings to keep client from allocating memory in those spaces. For other architectures I think we can do the same in arch-specific way (probably walk code can be reused?)
BTW I checked the code using ppc gentoo installation and have not seen a regression when ofmem changes went in.
Either way Haiku then hangs while trying to set the first segment register (mtsrin):
http://dev.haiku-os.org/browser/haiku/trunk/src/system/boot/platform/openfir...
Interesting. It's great to see you making progress with this :)
Igor Kovalenko wrote:
Right. For sparc64 we copy mappings from hardware tables set up by asm bootstrap code using a walk over hardware translations. Most of bootstrap mappings are locked into tlb so we do not really need to handle translations for them. Instead we use bootstrap mappings to keep client from allocating memory in those spaces. For other architectures I think we can do the same in arch-specific way (probably walk code can be reused?)
Yeah. One of the frustrations I have found (resulting in the recent cleanup) was that each arch was taken from a set of core routines and then customised in order to make it boot. Sadly this has resulted in fixes being fragmented across the code base and a lot of very-similar-but-not-quite code duplication :(
I would say that looking to the future, we should focus on enhancing and defining the arch-specific APIs and make the changes benefit everyone rather than just one specific arch.
ATB,
Mark.
On Tue, May 25, 2010 at 4:47 PM, Mark Cave-Ayland mark.cave-ayland@siriusit.co.uk wrote:
Igor Kovalenko wrote:
Right. For sparc64 we copy mappings from hardware tables set up by asm bootstrap code using a walk over hardware translations. Most of bootstrap mappings are locked into tlb so we do not really need to handle translations for them. Instead we use bootstrap mappings to keep client from allocating memory in those spaces. For other architectures I think we can do the same in arch-specific way (probably walk code can be reused?)
Yeah. One of the frustrations I have found (resulting in the recent cleanup) was that each arch was taken from a set of core routines and then customised in order to make it boot. Sadly this has resulted in fixes being fragmented across the code base and a lot of very-similar-but-not-quite code duplication :(
Well, the ofmem consolidation was done exactly to eliminate duplication and fix a few bugs in memory management for all arch implementations :)
I would say that looking to the future, we should focus on enhancing and defining the arch-specific APIs and make the changes benefit everyone rather than just one specific arch.
Igor Kovalenko wrote:
Well, the ofmem consolidation was done exactly to eliminate duplication and fix a few bugs in memory management for all arch implementations :)
Exactly :) What I'm trying to say is that we should be more careful reviewing patches in future to ensure that we don't end up in the same situation once again.
ATB,
Mark.
Andreas Färber wrote:
These are ppc-specific magic numbers in common code where they have no business being - please don't apply!
The question is, why does claim overwrite the 0x07ed0000 identity map of length 1245184, that I see no in my debug output now, with a 0x07f00000 map when using the vanilla OpenBIOS code?
What is the identity map? Is it something used in general for PPC or is it specific to Haiku?
Also if you enable DEBUG_CIF in libopenbios/client.c, do you see any more useful information?
ATB,
Mark.
Am 24.05.2010 um 18:57 schrieb Mark Cave-Ayland:
Andreas Färber wrote:
The question is, why does claim overwrite the 0x07ed0000 identity map of length 1245184, that I see [...] in my debug output now, with a 0x07f00000 map when using the vanilla OpenBIOS code?
What is the identity map? Is it something used in general for PPC or is it specific to Haiku?
Maybe I misworded, I meant an identity-mapped memory translation, i.e. physical and virtual address identical. Nothing ppc or Haiku specific.
Map before claim (vanilla): ... 0x07ed0000 -> 0x07ed0000 (1245184) ...
Map after claim (vanilla): ... [0x07ed0000..0x07f00000 no longer mapped!] 0x07f00000 -> 0x07f00000 (1048576) ...
Expected map after claim: ... 0x07d00000 -> 0x07d00000 (1048576) -- or wherever it fits [0x07ed0000..0x07f00000 possibly mapped] 0x07f00000 -> 0x07f00000 (1048576) -- OpenBIOS ...
Two bugs IMO: a) The map is shortened. b) OpenBIOS memory is reused. The latter made Haiku/OpenBIOS hang.
Also if you enable DEBUG_CIF in libopenbios/client.c, do you see any more useful information?
I enabled CONFIG_DEBUG_OFMEM; the Haiku code will be calling ofmem_claim(NULL, 1048576, 1048576) in case of default -m 128. Whatever exactly the problem is, it must be between the ofmem implementation and its users inside OpenBIOS.
Andreas