I'm trying to get the sparc32 OpenBIOS to load an fcode rom, but it's not working. After byte-load, it reports out of memory.
Here's the steps I'm using to setup a simple rom which just sets the device name to "QEMU,test", and then trying to run it: fd000000 1000 l! 00000020 1004 l! 12095145 1008 l! 4d552c74 100c l! 65737401 1010 l! 1412046e 1014 l! 616d6501 1018 l! 10000000 101c l! cd /iommu/sbus " /iommu/sbus" select-dev new-device 1000 1 byte-load
Here, OpenBIOS will report out of memory.
Bob
On 27/06/11 18:24, Bob Breuer wrote:
I'm trying to get the sparc32 OpenBIOS to load an fcode rom, but it's not working. After byte-load, it reports out of memory.
Here's the steps I'm using to setup a simple rom which just sets the device name to "QEMU,test", and then trying to run it: fd000000 1000 l! 00000020 1004 l! 12095145 1008 l! 4d552c74 100c l! 65737401 1010 l! 1412046e 1014 l! 616d6501 1018 l! 10000000 101c l! cd /iommu/sbus " /iommu/sbus" select-dev new-device 1000 1 byte-load
Here, OpenBIOS will report out of memory.
Hmmm that's interesting - I'm not sure that anyone has played with Fcode on SPARC32 before (goes and looks...).
Looks as if there isn't enough memory within Forth to initialise the Fcode tables on SPARC32:
0 > debug alloc-fcode-table Stepper keys: <space>/<enter> Up Down Trace Rstack Forth ok 0 > alloc-fcode-table : alloc-fcode-table ( Empty ) ffd29320: (lit) ( 4096 ) ffd29328: cells ( 10258 ) ffd2932c: alloc-mem out of memory. 0 >
Wow - 0x10258 is 66Kbytes which is more than enough to saturate the Forth memory. You may be able to get things further by increasing MEMORY_SIZE in arch/sparc32/openbios.c, but you'll probably hit the 2M limit for the ELF image size before you get there :(
Does anyone else have a better idea as to how we could better allocate the memory or reduce the memory requirement for the Fcode table? Could we allocate a region of memory using the OFMEM API rather than internal Forth memory for instance?
ATB,
Mark.
Mark Cave-Ayland wrote:
On 27/06/11 18:24, Bob Breuer wrote:
I'm trying to get the sparc32 OpenBIOS to load an fcode rom, but it's not working. After byte-load, it reports out of memory.
Here's the steps I'm using to setup a simple rom which just sets the device name to "QEMU,test", and then trying to run it: fd000000 1000 l! 00000020 1004 l! 12095145 1008 l! 4d552c74 100c l! 65737401 1010 l! 1412046e 1014 l! 616d6501 1018 l! 10000000 101c l! cd /iommu/sbus " /iommu/sbus" select-dev new-device 1000 1 byte-load
Here, OpenBIOS will report out of memory.
Hmmm that's interesting - I'm not sure that anyone has played with Fcode on SPARC32 before (goes and looks...).
Looks as if there isn't enough memory within Forth to initialise the Fcode tables on SPARC32:
0 > debug alloc-fcode-table Stepper keys: <space>/<enter> Up Down Trace Rstack Forth ok 0 > alloc-fcode-table : alloc-fcode-table ( Empty ) ffd29320: (lit) ( 4096 ) ffd29328: cells ( 10258 ) ffd2932c: alloc-mem out of memory. 0 >
Wow - 0x10258 is 66Kbytes which is more than enough to saturate the Forth memory. You may be able to get things further by increasing MEMORY_SIZE in arch/sparc32/openbios.c, but you'll probably hit the 2M limit for the ELF image size before you get there :(
Does anyone else have a better idea as to how we could better allocate the memory or reduce the memory requirement for the Fcode table? Could we allocate a region of memory using the OFMEM API rather than internal Forth memory for instance?
Just missed your reply, see my other email for my analysis. The 16k limit seems awfully small.
I've tried bumping the memory size in openbios.c from 16k to 160k, but then I think I ran into the 256k limit. Unless there's some power-of-2 size restriction.
I could run some more tests on an SS-20 if seeing what OBP does will help in any way.
Bob
On 28/06/11 15:02, Bob Breuer wrote:
Just missed your reply, see my other email for my analysis. The 16k limit seems awfully small.
I've tried bumping the memory size in openbios.c from 16k to 160k, but then I think I ran into the 256k limit. Unless there's some power-of-2 size restriction.
I could run some more tests on an SS-20 if seeing what OBP does will help in any way.
I think in actual fact your test here proves it:
ok 400000 alloc-mem ok .s fe7fdff8
Obviously there is no way that amount of memory can be allocated between 0xffd00000 and 0xffffffff and so it must be using sections of memory outside of the ROM space.
I think that the way forward would be to remove the Forth implementations of alloc-mem and instead use the OFMEM API to grab sections of memory. There are two slight hurdles to this though:
- Not all architectures implement the OFMEM API (it is missing for ia64, amd64 and x86)
- Some of the Forth purists may dislike removing Forth and using C instead
My personal perspective is that I don't see there is much gain in trying to rework OFMEM in Forth and I see very few volunteers to do this so realistically this is a non-argument.
In terms of supporting other architectures, I think this wouldn't be too hard either - simply write the OFMEM functions so that they use the internal malloc()/free() functions which will use internal address space in the same was as alloc-mem does now. This basic stub implementation could then be copied to the remaining 3 architectures leaving the existing functionality in place until someone wants to come and write proper MMU-aware OFMEM handlers.
Once this is in place, switching alloc-mem over to use OFMEM is a really trivial exercise which would then permanently solve the memory space issue. I'd also be happy to help advise/work on any patches you have in this area, even if you just put forward an experimental SPARC32-only alloc-mem rewrite in C using OFMEM to help get you further along the way.
ATB,
Mark.
Mark Cave-Ayland wrote:
On 28/06/11 15:02, Bob Breuer wrote:
Just missed your reply, see my other email for my analysis. The 16k limit seems awfully small.
I've tried bumping the memory size in openbios.c from 16k to 160k, but then I think I ran into the 256k limit. Unless there's some power-of-2 size restriction.
I could run some more tests on an SS-20 if seeing what OBP does will help in any way.
I think in actual fact your test here proves it:
ok 400000 alloc-mem ok .s fe7fdff8
Obviously there is no way that amount of memory can be allocated between 0xffd00000 and 0xffffffff and so it must be using sections of memory outside of the ROM space.
I think that the way forward would be to remove the Forth implementations of alloc-mem and instead use the OFMEM API to grab sections of memory. There are two slight hurdles to this though:
- Not all architectures implement the OFMEM API (it is missing for ia64,
amd64 and x86)
- Some of the Forth purists may dislike removing Forth and using C instead
My personal perspective is that I don't see there is much gain in trying to rework OFMEM in Forth and I see very few volunteers to do this so realistically this is a non-argument.
In terms of supporting other architectures, I think this wouldn't be too hard either - simply write the OFMEM functions so that they use the internal malloc()/free() functions which will use internal address space in the same was as alloc-mem does now. This basic stub implementation could then be copied to the remaining 3 architectures leaving the existing functionality in place until someone wants to come and write proper MMU-aware OFMEM handlers.
Once this is in place, switching alloc-mem over to use OFMEM is a really trivial exercise which would then permanently solve the memory space issue. I'd also be happy to help advise/work on any patches you have in this area, even if you just put forward an experimental SPARC32-only alloc-mem rewrite in C using OFMEM to help get you further along the way.
Maybe the 4096 in hex is a mistake, and it was intended to be 4096 decimal. For now, this patch (probably mangled by my mailer) seems to work:
Index: arch/sparc32/openbios.c =================================================================== --- arch/sparc32/openbios.c (revision 1044) +++ arch/sparc32/openbios.c (working copy) @@ -27,7 +27,7 @@ #include "arch/common/fw_cfg.h" #include "libopenbios/ofmem.h"
-#define MEMORY_SIZE (16*1024) /* 16K ram for hosted system */ +#define MEMORY_SIZE (128*1024) /* 128K ram for hosted system */ #define UUID_FMT "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x" #define FW_CFG_SUN4M_DEPTH (FW_CFG_ARCH_LOCAL + 0x00)
Index: arch/sparc32/ofmem_sparc32.c =================================================================== --- arch/sparc32/ofmem_sparc32.c (revision 1044) +++ arch/sparc32/ofmem_sparc32.c (working copy) @@ -21,7 +21,7 @@
#define OF_MALLOC_BASE ((char*)OFMEM + ALIGN_SIZE(sizeof(ofmem_t), 8))
-#define MEMSIZE (256 * 1024) +#define MEMSIZE (512 * 1024) static union { char memory[MEMSIZE]; ofmem_t ofmem;
I'll take another look at this after shaking out a few more possible bugs.
Next up is my-address and my-space. Under OBP on an SS-20, I can do this: ok " /iommu/sbus" select-dev ok new-device ok 0 0 " 1,abc" set-args ok my-address . my-space . abc 1 With OpenBIOS, I just get zeros for both my-address and my-space.
While skimming the IEEE-1275 spec, I found begin-package, which under OpenBIOS does set my-address and my-space correctly. Am I just missing something, or could there be a bug in either set-args or new-device?
Bob
On 30/06/11 19:40, Bob Breuer wrote:
Maybe the 4096 in hex is a mistake, and it was intended to be 4096 decimal. For now, this patch (probably mangled by my mailer) seems to work:
Index: arch/sparc32/openbios.c
--- arch/sparc32/openbios.c (revision 1044) +++ arch/sparc32/openbios.c (working copy) @@ -27,7 +27,7 @@ #include "arch/common/fw_cfg.h" #include "libopenbios/ofmem.h"
-#define MEMORY_SIZE (16*1024) /* 16K ram for hosted system */ +#define MEMORY_SIZE (128*1024) /* 128K ram for hosted system */ #define UUID_FMT "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x" #define FW_CFG_SUN4M_DEPTH (FW_CFG_ARCH_LOCAL + 0x00)
Index: arch/sparc32/ofmem_sparc32.c
--- arch/sparc32/ofmem_sparc32.c (revision 1044) +++ arch/sparc32/ofmem_sparc32.c (working copy) @@ -21,7 +21,7 @@
#define OF_MALLOC_BASE ((char*)OFMEM + ALIGN_SIZE(sizeof(ofmem_t), 8))
-#define MEMSIZE (256 * 1024) +#define MEMSIZE (512 * 1024) static union { char memory[MEMSIZE]; ofmem_t ofmem;
I'll take another look at this after shaking out a few more possible bugs.
Ooooh so you can get away with re-arranging the internal memory space to find enough space for the fcode tables after all - nice one :)
Next up is my-address and my-space. Under OBP on an SS-20, I can do this: ok " /iommu/sbus" select-dev ok new-device ok 0 0 " 1,abc" set-args ok my-address . my-space . abc 1 With OpenBIOS, I just get zeros for both my-address and my-space.
While skimming the IEEE-1275 spec, I found begin-package, which under OpenBIOS does set my-address and my-space correctly. Am I just missing something, or could there be a bug in either set-args or new-device?
Possibly. Bear in mind that OpenBIOS now has a source debugger so you can try something like:
" /iommu/sbus" select-dev new-device 0 0 " 1,abc" debug set-args set-args
...and off you go.
HTH,
Mark.
Mark Cave-Ayland wrote: [ snip ]
Next up is my-address and my-space. Under OBP on an SS-20, I can do this: ok " /iommu/sbus" select-dev ok new-device ok 0 0 " 1,abc" set-args ok my-address . my-space . abc 1 With OpenBIOS, I just get zeros for both my-address and my-space.
While skimming the IEEE-1275 spec, I found begin-package, which under OpenBIOS does set my-address and my-space correctly. Am I just missing something, or could there be a bug in either set-args or new-device?
Possibly. Bear in mind that OpenBIOS now has a source debugger so you can try something like:
" /iommu/sbus" select-dev new-device 0 0 " 1,abc" debug set-args set-args
...and off you go.
I've found the cause - my-self was still 0 when calling new-device, so the $call-parent in set-args was failing. OpenBIOS treats select-dev and open-dev as the same, but they are not, see the of1275 errata for section H.8. Most importantly, open-dev does not set my-self, while select-dev does.
OBP uses select-dev to make begin-package almost trivial, as in : begin-package ( ... ) select-dev new-device set-args ;
Any objection to simplifying the OpenBIOS version of begin-package to match the OBP version, and moving the extra logic from begin-package into select-dev?
Bob
On 13/07/11 16:24, Bob Breuer wrote:
I've found the cause - my-self was still 0 when calling new-device, so the $call-parent in set-args was failing. OpenBIOS treats select-dev and open-dev as the same, but they are not, see the of1275 errata for section H.8. Most importantly, open-dev does not set my-self, while select-dev does.
OBP uses select-dev to make begin-package almost trivial, as in : begin-package ( ... ) select-dev new-device set-args ;
Any objection to simplifying the OpenBIOS version of begin-package to match the OBP version, and moving the extra logic from begin-package into select-dev?
That sounds sensible, so none from this end. If you post a patch, I'll test it on my various CD images and make sure it doesn't cause any Fcode regressions there.
ATB,
Mark.
On 30/06/11 19:40, Bob Breuer wrote:
Maybe the 4096 in hex is a mistake, and it was intended to be 4096 decimal. For now, this patch (probably mangled by my mailer) seems to work:
Hmmm that patch doesn't work for me as it exceeds the QEMU image size :( However it does seem to work okay if you drop the memory from 512K to 384K. Can you confirm that the patch below works for you? If so, I'll tidy it up and commit.
diff --git a/openbios-devel/arch/sparc32/ofmem_sparc32.c b/openbios-devel/arch/sparc32/ofmem_sparc32.c index 671d11b..bd52538 100644 --- a/openbios-devel/arch/sparc32/ofmem_sparc32.c +++ b/openbios-devel/arch/sparc32/ofmem_sparc32.c @@ -21,7 +21,7 @@
#define OF_MALLOC_BASE ((char*)OFMEM + ALIGN_SIZE(sizeof(ofmem_t), 8))
-#define MEMSIZE (256 * 1024) +#define MEMSIZE (384 * 1024) static union { char memory[MEMSIZE]; ofmem_t ofmem; diff --git a/openbios-devel/arch/sparc32/openbios.c b/openbios-devel/arch/sparc32/openbios.c index 6915486..d5d453d 100644 --- a/openbios-devel/arch/sparc32/openbios.c +++ b/openbios-devel/arch/sparc32/openbios.c @@ -27,7 +27,7 @@ #include "arch/common/fw_cfg.h" #include "libopenbios/ofmem.h"
-#define MEMORY_SIZE (16*1024) /* 16K ram for hosted system */ +#define MEMORY_SIZE (128*1024) /* 128K ram for hosted system */ #define UUID_FMT "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x" #define FW_CFG_SUN4M_DEPTH (FW_CFG_ARCH_LOCAL + 0x00)
ATB,
Mark.
Mark Cave-Ayland wrote:
On 30/06/11 19:40, Bob Breuer wrote:
Maybe the 4096 in hex is a mistake, and it was intended to be 4096 decimal. For now, this patch (probably mangled by my mailer) seems to work:
Hmmm that patch doesn't work for me as it exceeds the QEMU image size :( However it does seem to work okay if you drop the memory from 512K to 384K. Can you confirm that the patch below works for you? If so, I'll tidy it up and commit.
Yes, 384K works for me. Seems that I had used the stripped openbios, but I do see a failure with 512K and an unstripped openbios. I guess the debug symbols pushed it past some QEMU limit.
Acked-by: Bob Breuer breuerr@mc.net
diff --git a/openbios-devel/arch/sparc32/ofmem_sparc32.c b/openbios-devel/arch/sparc32/ofmem_sparc32.c index 671d11b..bd52538 100644 --- a/openbios-devel/arch/sparc32/ofmem_sparc32.c +++ b/openbios-devel/arch/sparc32/ofmem_sparc32.c @@ -21,7 +21,7 @@
#define OF_MALLOC_BASE ((char*)OFMEM + ALIGN_SIZE(sizeof(ofmem_t), 8))
-#define MEMSIZE (256 * 1024) +#define MEMSIZE (384 * 1024) static union { char memory[MEMSIZE]; ofmem_t ofmem; diff --git a/openbios-devel/arch/sparc32/openbios.c b/openbios-devel/arch/sparc32/openbios.c index 6915486..d5d453d 100644 --- a/openbios-devel/arch/sparc32/openbios.c +++ b/openbios-devel/arch/sparc32/openbios.c @@ -27,7 +27,7 @@ #include "arch/common/fw_cfg.h" #include "libopenbios/ofmem.h"
-#define MEMORY_SIZE (16*1024) /* 16K ram for hosted system */ +#define MEMORY_SIZE (128*1024) /* 128K ram for hosted system */ #define UUID_FMT "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x" #define FW_CFG_SUN4M_DEPTH (FW_CFG_ARCH_LOCAL + 0x00)
ATB,
Mark.
On 09/07/11 07:08, Bob Breuer wrote:
Yes, 384K works for me. Seems that I had used the stripped openbios, but I do see a failure with 512K and an unstripped openbios. I guess the debug symbols pushed it past some QEMU limit.
Acked-by: Bob Breuerbreuerr@mc.net
Thanks a lot - committed. It's always worth doing a full debug build before submitting a patch as it's a good way of finding any memory overflow errors that may have accidentally crept in.
ATB,
Mark.
Bob Breuer wrote:
I'm trying to get the sparc32 OpenBIOS to load an fcode rom, but it's not working. After byte-load, it reports out of memory.
Here's the steps I'm using to setup a simple rom which just sets the device name to "QEMU,test", and then trying to run it: fd000000 1000 l! 00000020 1004 l! 12095145 1008 l! 4d552c74 100c l! 65737401 1010 l! 1412046e 1014 l! 616d6501 1018 l! 10000000 101c l! cd /iommu/sbus " /iommu/sbus" select-dev new-device 1000 1 byte-load
Here, OpenBIOS will report out of memory.
Turns out you don't even need any fcode to trigger this, as it does the failing allocation in alloc-fcode-table: 4096 cells alloc-mem to fcode-table Which looks like it tries to allocate 64k.
In arch/sparc32/openbios.c, MEMORY_SIZE is defined to 16k, which I think will limit the malloc size. There's another define of 256k in arch/sparc32/ofmem_sparc32.c that may also affect this.
On an SS-20, I can allocate at least 4M without problem: ok 400000 alloc-mem ok .s fe7fdff8
Are there any known problems with bumping up the size for both the 16k and 256k limits?
Bob