Hi folks,
I'm pleased to report that as of r656, OpenBIOS now successfully executes all of the Fcode from within the Milax 0.3.2 ISO image under Qemu :) The current output from Qemu looks like this:
OpenBIOS for Sparc64 Configuration device id QEMU version 1 machine id 0 CPUs: 1 x SUNW,UltraSPARC-II UUID: 00000000-0000-0000-0000-000000000000 Welcome to OpenBIOS v1.0 built on Jan 1 2010 18:04 Type 'help' for detailed information
[sparc64] Booting file 'cdrom' with parameters '' Not a bootable ELF image Not a Linux kernel image Not a bootable a.out image Loading FCode image... Loaded 7084 bytes entry point is 0x4000 Evaluating FCode... Unhandled Exception 0xe81ac700ffdba000 PC = 0x00000000ffd12ffc NPC = 0x00000000ffd13000 Stopping execution
Stepping through with the debugger shows that it is now dying in the very last line of exec-file which reads:
" to load-base init-program" evaluate
So it looks as if we're very nearly there. My guess would be that OpenBIOS is dying somewhere within init-program. Does anyone know anything about what init-program should be doing under SPARC64? Has it ever been tested before?
ATB,
Mark.
Mark Cave-Ayland wrote:
Stepping through with the debugger shows that it is now dying in the very last line of exec-file which reads:
" to load-base init-program" evaluate
So it looks as if we're very nearly there. My guess would be that OpenBIOS is dying somewhere within init-program. Does anyone know anything about what init-program should be doing under SPARC64? Has it ever been tested before?
Hmmmm now I see what the problem is - load-base is actually a special configuration word and not a variable. Hence when the Fcode executes "to load-base" it overwrites the first part of the load-base word causing the crash.
Reading the OF specification in section 7.4.4.1 it seems that OpenBIOS violates the Fundamental Data Type property of configuration variables since they are stored in a special configuration word format. I think the only way to solve this is rework the NVRAM code so that it respects the fundamental data types when creating the configuration variables. Does everyone agree that this is the way forward?
ATB,
Mark.
On 1/1/10 8:47 PM, Mark Cave-Ayland wrote:
Mark Cave-Ayland wrote:
Stepping through with the debugger shows that it is now dying in the very last line of exec-file which reads:
" to load-base init-program" evaluate
So it looks as if we're very nearly there. My guess would be that OpenBIOS is dying somewhere within init-program. Does anyone know anything about what init-program should be doing under SPARC64? Has it ever been tested before?
Hmmmm now I see what the problem is - load-base is actually a special configuration word and not a variable. Hence when the Fcode executes "to load-base" it overwrites the first part of the load-base word causing the crash.
Reading the OF specification in section 7.4.4.1 it seems that OpenBIOS violates the Fundamental Data Type property of configuration variables since they are stored in a special configuration word format. I think the only way to solve this is rework the NVRAM code so that it respects the fundamental data types when creating the configuration variables. Does everyone agree that this is the way forward?
I don't think that's the right approach, because the code in Milax seems to be what's not standard conform here. It relies on an implementation specific detail of SUN's OFW.
IEEE 1275-1994 says:
Thus, they cannot be accessed at fixed locations, but instead must be
accessed by name. Users can access them by name using printenv and setenv.
Note there is no mentioning of any specific data type for configuration variables anywhere in 7.4.4.1. Milax assumes that load-base is a value (not a variable), hence the "to".
I suggest as a workaround for this particular bug in Milax to add something like the following code at the end of nvram.fs:
load-base value load-base
This will leave the environment variable "load-base" intact for the use in the standard conform way and create a shadow value that will be used by Milax. This shadow value will be initialized with the initial value of load-base.
Stefan
Stefan Reinauer wrote:
I don't think that's the right approach, because the code in Milax seems to be what's not standard conform here. It relies on an implementation specific detail of SUN's OFW.
IEEE 1275-1994 says:
Thus, they cannot be accessed at fixed locations, but instead must be
accessed by name. Users can access them by name using printenv and setenv.
Note there is no mentioning of any specific data type for configuration variables anywhere in 7.4.4.1. Milax assumes that load-base is a value (not a variable), hence the "to".
Alas it seems this is still present in OpenSolaris too :( I'm guessing they should be using "printenv", right?
I suggest as a workaround for this particular bug in Milax to add something like the following code at the end of nvram.fs:
load-base value load-base
This will leave the environment variable "load-base" intact for the use in the standard conform way and create a shadow value that will be used by Milax. This shadow value will be initialized with the initial value of load-base.
Nice hack ;) At least now the Fcode finishes execution, but it doesn't seem to load anything from the ramdisk.
ATB,
Mark.
On 1/2/10 12:39 PM, Mark Cave-Ayland wrote:
Stefan Reinauer wrote:
I don't think that's the right approach, because the code in Milax seems to be what's not standard conform here. It relies on an implementation specific detail of SUN's OFW.
IEEE 1275-1994 says:
Thus, they cannot be accessed at fixed locations, but instead must be
accessed by name. Users can access them by name using printenv and setenv.
Note there is no mentioning of any specific data type for configuration variables anywhere in 7.4.4.1. Milax assumes that load-base is a value (not a variable), hence the "to".
Alas it seems this is still present in OpenSolaris too :( I'm guessing they should be using "printenv", right?
Milax writes some value on the stack to "load-base". So I think they should be using something like
<# u#s u#> " load-base" " $setenv init-program" evaluate
I wonder why load-base is an environment variable at all, since it seems to be calculated on every boot anyways.
Stefan
Mark Cave-Ayland wrote:
[...] Stepping through with the debugger shows that it is now dying in the very last line of exec-file which reads:
" to load-base init-program" evaluate
So it looks as if we're very nearly there. My guess would be that OpenBIOS is dying somewhere within init-program. Does anyone know anything about what init-program should be doing under SPARC64? Has it ever been tested before?
In Sun's openboot, that's in go.fth (lives in obp/ach/sun4u/go.fth), and it does an execute-buffer on whatever's in load-base, followed by initializing the registers, trap-table and stack for the client interface. Specifically (I can include this because it has been open-sourced):
: (init-program) ( -- )
cif-64 \ 64-Bit IEEE 1275 Client Interface
init-c-stack \ Erase any previous C stack state
\ Zero all the general registers. 0w 0 to %g0 0 to %o0 0 to %l0 0 to %i0 0 to %g1 0 to %o1 0 to %l1 0 to %i1 0 to %g2 0 to %o2 0 to %l2 0 to %i2 0 to %g3 0 to %o3 0 to %l3 0 to %i3 0 to %g4 0 to %o4 0 to %l4 0 to %i4 0 to %g5 0 to %o5 0 to %l5 0 to %i5 0 to %g6 0 to %o6 0 to %l6 0 to %i6 0 to %g7 0 to %o7 0 to %l7 0 to %i7
cif-func() to %o4 \ IEEE 1275 Client Services Handler %o6@ to %o6 \ C stack pointer
trap-table to %tba \ Set trap table
h# 0 to %y h# 4 to %fprs h# 16 to %pstate h# 0d to %pil
7 to %cleanwin 0 to %otherwin 0 to %wstate 0 to %canrestore 6 to %cansave 0 to %cwp
h# 16 8 lshift to %tstate-c
load-base set-pc
[ifdef] SUN4V \ Since we are initializing a stack, make sure we clear out previous saved \ state indications. This affects ultra4v/savecpu.fth:restore-cpu-state, \ which is invoked shortly after this.
0 to full-save? [then]
sp@ saved-sp ! rp@ saved-rp ! \ Needed for later callbacks into Forth
state-valid on restartable? on true to already-go? [ifdef] Starcat? RELEASE-SLAVE-INVALID release-slaves? l! [then] ;
\ ..... other stuff ....
: init-program ( -- ) load-base file-size @ 'execute-buffer execute (init-program) ;
Tarl Neustaedter wrote:
In Sun's openboot, that's in go.fth (lives in obp/ach/sun4u/go.fth), and it does an execute-buffer on whatever's in load-base, followed by initializing the registers, trap-table and stack for the client interface. Specifically (I can include this because it has been open-sourced):
(lots cut)
With Stefan's hack in place, the Fcode finishes execution but it doesn't seem to load anything from the ramdisk. AFAICT at the moment the contents of /platform/sun4u/boot_archive is being loaded at 0x51000000, and a new node /ramdisk-root is being created with methods that seem to point into this memory space.
What I can't see at the moment is how the device switch takes place, i.e. when /ramdisk-root is used to load the kernel from the image. There are several checks for nested? in do-boot and friends which make me think that something in init-program should be calling do-boot again once the ramdisk switch has taken place...
ATB,
Mark.
Mark Cave-Ayland wrote:
What I can't see at the moment is how the device switch takes place, i.e. when /ramdisk-root is used to load the kernel from the image. There are several checks for nested? in do-boot and friends which make me think that something in init-program should be calling do-boot again once the ramdisk switch has taken place...
Well I'm not sure what *should* be happening, but it seems that I can manually boot the ramdisk by hand after the initial expection, e.g:
boot cdrom
And then when the exception is thrown, manually boot the ramdisk with:
boot /ramdisk-root
This gets things a bit further but it looks like we need a module or 2 included for SPARC64 which aren't in there already.
Tarl: is this nested boot process something that auto-boot should handle automatically based on various bootarchive properties set by the initial Fcode loader?
ATB,
Mark.
Hi all,
With the latest SVN of OpenBIOS it now looks like we are hitting another memory issue when booting Milax in that claim is failing unexpectedly. With CONFIG_DEBUG_OFMEM enabled, the complete session output looks like this:
OpenBIOS for Sparc64 OFMEM: ofmem_claim phys=0000000007e80000 size=0000000000080000 align=0000000000000000 OFMEM: ofmem_claim_virt virt=00000000ffe00000 size=0000000000080000 align=0000000000000000 OFMEM: ofmem_map_page_range 00000000ffe00000 -> 0000000007e80000 0000000000080000 mode 0000000000000076 OFMEM: ofmem_claim phys=0000000007f00000 size=0000000000080000 align=0000000000000000 OFMEM: ofmem_claim_virt virt=00000000ffe80000 size=0000000000080000 align=0000000000000000 OFMEM: ofmem_map_page_range 00000000ffe80000 -> 0000000007f00000 0000000000080000 mode 0000000000000076 OFMEM: ofmem_claim phys=0000000007f80000 size=0000000000080000 align=0000000000000000 OFMEM: ofmem_claim_virt virt=00000000fff00000 size=0000000000080000 align=0000000000000000 OFMEM: ofmem_map_page_range 00000000fff00000 -> 0000000007f80000 0000000000080000 mode 0000000000000076 OFMEM: ofmem_claim phys=000001fff0000000 size=0000000000080000 align=0000000000000000 OFMEM: ofmem_claim_virt virt=00000000ffd00000 size=0000000000080000 align=0000000000000000 OFMEM: ofmem_map_page_range 00000000ffd00000 -> 000001fff0000000 0000000000080000 mode 0000000000000074 OFMEM: ofmem_claim phys=000001fff0080000 size=0000000000080000 align=0000000000000000 OFMEM: ofmem_claim_virt virt=00000000ffd80000 size=0000000000080000 align=0000000000000000 OFMEM: ofmem_map_page_range 00000000ffd80000 -> 000001fff0080000 0000000000080000 mode 0000000000000074 OFMEM: ofmem_map_page_range 0000000000000000 -> 0000000000000000 0000000008000000 mode 0000000000000036 OFMEM: ofmem_claim phys=000001ff00800000 size=0000000000800000 align=0000000000000000 OFMEM: ofmem_claim_virt virt=00000000fe000000 size=0000000000800000 align=0000000000000000 OFMEM: ofmem_map_page_range 00000000fe000000 -> 000001ff00800000 0000000000800000 mode 0000000000000076 Configuration device id QEMU version 1 machine id 0 CPUs: 1 x SUNW,UltraSPARC-II UUID: 00000000-0000-0000-0000-000000000000 Welcome to OpenBIOS v1.0 built on Jan 2 2010 12:50 Type 'help' for detailed information
0 > boot cdrom [sparc64] Booting file 'cdrom' with parameters '' Not a bootable ELF image Not a Linux kernel image Not a bootable a.out image Loading FCode image... Loaded 7084 bytes entry point is 0x4000 Evaluating FCode... OFMEM: ofmem_claim phys=ffffffffffffffff size=0000000000002000 align=0000000000000001 OFMEM: ofmem_map_page_range 0000000000000000 -> 0000000000000000 0000000000002000 mode 0000000000000032 OFMEM: mapping mode altered virt=0000000000000000 old mode=0000000000000036 new mode=0000000000000032 OFMEM: ofmem_claim_virt virt=ffffffffffffffff size=0000000000002000 align=0000000000000001 OFMEM: ofmem_map_page_range 0000000008000000 -> 0000000000000000 0000000000002000 mode 0000000000000032 OFMEM: ofmem_claim phys=ffffffffffffffff size=0000000000002000 align=0000000000000001 OFMEM: ofmem_map_page_range 0000000000002000 -> 0000000000002000 0000000000002000 mode 0000000000000032 OFMEM: mapping mode altered virt=0000000000002000 old mode=0000000000000036 new mode=0000000000000032 OFMEM: ofmem_claim_virt virt=ffffffffffffffff size=0000000000002000 align=0000000000000001 OFMEM: ofmem_map_page_range 0000000008002000 -> 0000000000002000 0000000000002000 mode 0000000000000032 OFMEM: ofmem_claim phys=ffffffffffffffff size=0000000000002000 align=0000000000000001 OFMEM: ofmem_map_page_range 0000000000004000 -> 0000000000004000 0000000000002000 mode 0000000000000032 OFMEM: mapping mode altered virt=0000000000004000 old mode=0000000000000036 new mode=0000000000000032 OFMEM: ofmem_claim_virt virt=ffffffffffffffff size=0000000000002000 align=0000000000000001 OFMEM: ofmem_map_page_range 0000000008004000 -> 0000000000004000 0000000000002000 mode 0000000000000032 OFMEM: ofmem_claim phys=ffffffffffffffff size=0000000000002000 align=0000000000000001 OFMEM: ofmem_map_page_range 0000000000006000 -> 0000000000006000 0000000000002000 mode 0000000000000032 OFMEM: mapping mode altered virt=0000000000006000 old mode=0000000000000036 new mode=0000000000000032 OFMEM: ofmem_claim_virt virt=ffffffffffffffff size=0000000000002000 align=0000000000000001 OFMEM: ofmem_map_page_range 0000000008006000 -> 0000000000006000 0000000000002000 mode 0000000000000032 OFMEM: ofmem_claim phys=ffffffffffffffff size=000000000554e000 align=0000000000000001 OFMEM: ofmem_map_page_range 0000000000008000 -> 0000000000008000 000000000554e000 mode 0000000000000032 OFMEM: mapping mode altered virt=0000000000008000 old mode=0000000000000036 new mode=0000000000000032 OFMEM: ofmem_claim_virt virt=0000000051000000 size=000000000554e000 align=0000000000000000 OFMEM: ofmem_map_page_range 0000000051000000 -> 0000000000008000 000000000554e000 mode 0000000000000032 OFMEM: ofmem_claim phys=ffffffffffffffff size=0000000000002000 align=0000000000000001 OFMEM: ofmem_map_page_range 0000000005556000 -> 0000000005556000 0000000000002000 mode 0000000000000032 OFMEM: mapping mode altered virt=0000000005556000 old mode=0000000000000036 new mode=0000000000000032 OFMEM: ofmem_claim_virt virt=ffffffffffffffff size=0000000000002000 align=0000000000000001 OFMEM: ofmem_map_page_range 0000000008008000 -> 0000000005556000 0000000000002000 mode 0000000000000032 OFMEM: ofmem_release_virt addr=0000000008008000 size=0000000000002000 OFMEM: ofmem_release_virt not implemented byte-load: stack overflow, diff 1 ok 0 > boot /ramdisk-root [sparc64] Booting file '/ramdisk-root' with parameters '' Not a bootable ELF image Not a Linux kernel image Not a bootable a.out image Loading FCode image... Loaded 7236 bytes entry point is 0x4000 Evaluating FCode... OFMEM: ofmem_claim phys=ffffffffffffffff size=000000000000a000 align=0000000000000001 OFMEM: ofmem_map_page_range 0000000005558000 -> 0000000005558000 000000000000a000 mode 0000000000000032 OFMEM: mapping mode altered virt=0000000005558000 old mode=0000000000000036 new mode=0000000000000032 OFMEM: ofmem_claim_virt virt=ffffffffffffffff size=000000000000a000 align=0000000000000001 OFMEM: ofmem_map_page_range 000000000800a000 -> 0000000005558000 000000000000a000 mode 0000000000000032 OFMEM: ofmem_claim phys=ffffffffffffffff size=000000000016c000 align=0000000000000001 OFMEM: ofmem_map_page_range 0000000005562000 -> 0000000005562000 000000000016c000 mode 0000000000000032 OFMEM: mapping mode altered virt=0000000005562000 old mode=0000000000000036 new mode=0000000000000032 OFMEM: ofmem_claim_virt virt=0000000050000000 size=000000000016c000 align=0000000000000000 OFMEM: ofmem_map_page_range 0000000050000000 -> 0000000005562000 000000000016c000 mode 0000000000000032 OFMEM: ofmem_claim phys=ffffffffffffffff size=0000000000400000 align=0000000000400000 OFMEM: ofmem_map_page_range 0000000005800000 -> 0000000005800000 0000000000400000 mode 0000000000000032 OFMEM: mapping mode altered virt=0000000005800000 old mode=0000000000000036 new mode=0000000000000032 OFMEM: ofmem_claim_virt virt=0000000001000000 size=0000000000400000 align=0000000000000000 OFMEM: ofmem_map_page_range 0000000001000000 -> 0000000005800000 0000000000400000 mode 0000000000000032 OFMEM: mapping altered virt=0000000001000000) OFMEM: ofmem_claim phys=ffffffffffffffff size=0000000000032000 align=0000000000000001 OFMEM: ofmem_map_page_range 00000000056ce000 -> 00000000056ce000 0000000000032000 mode 0000000000000032 OFMEM: mapping mode altered virt=00000000056ce000 old mode=0000000000000036 new mode=0000000000000032 OFMEM: ofmem_claim_virt virt=0000000001402000 size=0000000000032000 align=0000000000000000 OFMEM: ofmem_map_page_range 0000000001402000 -> 00000000056ce000 0000000000032000 mode 0000000000000032 OFMEM: mapping altered virt=0000000001402000) OFMEM: ofmem_claim phys=ffffffffffffffff size=0000000000400000 align=0000000000400000 OFMEM: ofmem_map_page_range 0000000005c00000 -> 0000000005c00000 0000000000400000 mode 0000000000000032 OFMEM: mapping mode altered virt=0000000005c00000 old mode=0000000000000036 new mode=0000000000000032 OFMEM: ofmem_claim_virt virt=0000000001800000 size=0000000000400000 align=0000000000000000 OFMEM: ofmem_map_page_range 0000000001800000 -> 0000000005c00000 0000000000400000 mode 0000000000000032 OFMEM: mapping altered virt=0000000001800000) OFMEM: **** ofmem_claim failure ***! Claim failed!
byte-load: stack overflow, diff 1 ok 0 >
ATB,
Mark.
Mark Cave-Ayland wrote:
OFMEM: **** ofmem_claim failure ***! Claim failed!
byte-load: stack overflow, diff 1 ok 0 >
Some more tracing using the debugger seems to indicate something failing at this section in elf_loader_init_program:
if( ofmem_claim( phdr[i].p_vaddr, phdr[i].p_memsz, 0 ) == -1 ) { printk("Claim failed!\n"); return; }
ATB,
Mark.
On Sat, Jan 2, 2010 at 4:10 PM, Mark Cave-Ayland mark.cave-ayland@siriusit.co.uk wrote:
Mark Cave-Ayland wrote:
OFMEM: **** ofmem_claim failure ***! Claim failed!
byte-load: stack overflow, diff 1 ok 0 >
Some more tracing using the debugger seems to indicate something failing at this section in elf_loader_init_program:
if( ofmem_claim( phdr[i].p_vaddr, phdr[i].p_memsz, 0 ) == -1 ) { printk("Claim failed!\n"); return; }
Memory range which it tries to claim is already mapped. If I try to comment out this failing statement, it copies elf data to target addresses, and control is returned to prompt.
'go' reports 'go is not yet implemented'
Igor Kovalenko wrote:
Memory range which it tries to claim is already mapped. If I try to comment out this failing statement, it copies elf data to target addresses, and control is returned to prompt.
Oh that's interesting - is it a bug in the elf-loader, or do we need to change the ofmem implementation to allow multiple mappings?
'go' reports 'go is not yet implemented'
Yeah unfortunately we need someone proficient in SPARC assembler and with the relevant documentation to write the equivalent of PPC's call_elf() for SPARC :(
ATB,
Mark.
On Sun, Jan 3, 2010 at 6:42 AM, Mark Cave-Ayland mark.cave-ayland@siriusit.co.uk wrote:
Igor Kovalenko wrote:
Memory range which it tries to claim is already mapped. If I try to comment out this failing statement, it copies elf data to target addresses, and control is returned to prompt.
Oh that's interesting - is it a bug in the elf-loader, or do we need to change the ofmem implementation to allow multiple mappings?
'go' reports 'go is not yet implemented'
Yeah unfortunately we need someone proficient in SPARC assembler and with the relevant documentation to write the equivalent of PPC's call_elf() for SPARC :(
Seems to be no need to go with assembly yet. With the following change you can try executing
elf-entry @ " (go)" evaluate
like ppc implementation of 'go' does. It would start executing elf code. Unfortunately it would crash with unhandled divide by zero trap which I still cannot find a reason for.
diff --git a/arch/sparc64/openbios.c b/arch/sparc64/openbios.c index 2926212..7c8de91 100644 --- a/arch/sparc64/openbios.c +++ b/arch/sparc64/openbios.c @@ -459,6 +459,13 @@ static void debugger_breakpoint(void) printk("=== DEBUGGER BREAKPOINT ===\n"); }
+static void go( void ) +{ + ucell addr = POP(); + void (*entry)(void) = (void*) addr; + entry(); +} + static void arch_init( void ) { @@ -470,6 +477,7 @@ arch_init( void ) device_end();
bind_func("platform-boot", boot ); + bind_func("(go)", go);
}
Igor Kovalenko wrote:
Seems to be no need to go with assembly yet. With the following change you can try executing
elf-entry @ " (go)" evaluate
like ppc implementation of 'go' does. It would start executing elf code. Unfortunately it would crash with unhandled divide by zero trap which I still cannot find a reason for.
This is also assuming that you remove the ofmem_claim() call from elf_loader_init_program()?
The link that Blue sent through for the SPARC OF bindings mentions the following in section 5.1.2 for ELF executables:
The program image immediately follows the header. After recognizing this header, load allocates and maps bf_text + bf_data + bf_bss bytes of memory beginning at the address given by bf_origin, moves the program image, of size bf_text + bf_data, to that address, and zeroes bf_bss bytes of memory beginning at bf_origin + bf_text + bf_data.
This does seem to look roughly what happens in elf_loader_init_program() to my untrained eye. However the document also references various trap table/register setups required as well as interactions between the client image and OF which we may be missing.
ATB,
Mark.
[...]
Tarl: is this nested boot process something that auto-boot should handle automatically based on various bootarchive properties set by the initial Fcode loader?
Sorry about the delay, I just checked my email.
I don't believe there is anything that should be automatically handled by the boot process - when you load /boot-archive, the fcode loaded should itself at the end invoke whatever execution method is required. My recollection is that boot-archive proceeds to load an ELF file and then jumps to that - I can verify that on monday.
Have we verified that OpenBios can jump to a SPARC ELF file?
Tarl Neustaedter wrote:
Tarl: is this nested boot process something that auto-boot should handle automatically based on various bootarchive properties set by the initial Fcode loader?
Sorry about the delay, I just checked my email.
I don't believe there is anything that should be automatically handled by the boot process - when you load /boot-archive, the fcode loaded should itself at the end invoke whatever execution method is required. My recollection is that boot-archive proceeds to load an ELF file and then jumps to that - I can verify that on monday.
Yeah; the part I couldn't see was how on earth the Fcode was loaded from /ramdisk-root. However some searching on the internet gave the following URL from one of the opensolaris mailing list archives: http://markmail.org/message/sfoiqklq7xcpcrld which gives the following quote about the booter phase:
6.2 Booter phase
This phase is derived from the SPARC wanboot ramdisk process (see PSARC 2001/009), and is responsible for reading the boot archive from the root file system (or install server in wanboot's case) into a ramdisk device. It does this by:
1) opening the boot-device (which it found as the "bootpath" property in the OBP "/chosen" node)
2) using its file system specific reader to read the boot archive (by default, /platform/`uname -m`/boot_archive)
3) creating a ramdisk device in "/ramdisk"
4) creating "bootarchive" and "fstype" properties in | "/chosen" |
5) booting the archive (a ramdisk is just another type of disk, so executing the boot block area serves this purpose)
Given that init-program in OpenBIOS checks for several different payloads, I've simply added an Fcode payload detection routine that detects the version1 or startX words, skips the Fcode header and then runs the Fcode evaluator. This seems to work fine on my tests here, so I'll commit in a short while.
Have we verified that OpenBios can jump to a SPARC ELF file?
Hmmm no - looking at the PPC code for the go word it seems that we need someone who owns a copy of the IEEE-1275 bindings for SPARC and who is proficient in SPARC assembler to implement this :(
ATB,
Mark.
On Sun, Jan 3, 2010 at 3:40 AM, Mark Cave-Ayland mark.cave-ayland@siriusit.co.uk wrote:
Tarl Neustaedter wrote:
Tarl: is this nested boot process something that auto-boot should handle automatically based on various bootarchive properties set by the initial Fcode loader?
Sorry about the delay, I just checked my email.
I don't believe there is anything that should be automatically handled by the boot process - when you load /boot-archive, the fcode loaded should itself at the end invoke whatever execution method is required. My recollection is that boot-archive proceeds to load an ELF file and then jumps to that - I can verify that on monday.
Yeah; the part I couldn't see was how on earth the Fcode was loaded from /ramdisk-root. However some searching on the internet gave the following URL from one of the opensolaris mailing list archives: http://markmail.org/message/sfoiqklq7xcpcrld which gives the following quote about the booter phase:
6.2 Booter phase
This phase is derived from the SPARC wanboot ramdisk process (see PSARC 2001/009), and is responsible for reading the boot archive from the root file system (or install server in wanboot's case) into a ramdisk device. It does this by:
- opening the boot-device (which it found as the "bootpath" property in the
OBP "/chosen" node)
- using its file system specific reader to read the boot archive (by
default, /platform/`uname -m`/boot_archive)
creating a ramdisk device in "/ramdisk"
creating "bootarchive" and "fstype" properties in | "/chosen" |
booting the archive (a ramdisk is just another type of disk, so executing
the boot block area serves this purpose)
Given that init-program in OpenBIOS checks for several different payloads, I've simply added an Fcode payload detection routine that detects the version1 or startX words, skips the Fcode header and then runs the Fcode evaluator. This seems to work fine on my tests here, so I'll commit in a short while.
Have we verified that OpenBios can jump to a SPARC ELF file?
Hmmm no - looking at the PPC code for the go word it seems that we need someone who owns a copy of the IEEE-1275 bindings for SPARC and who is proficient in SPARC assembler to implement this :(
Which bindings? http://playground.sun.com/1275/home.html gives a SPARC binding but that is for V8.
Blue Swirl wrote:
Have we verified that OpenBios can jump to a SPARC ELF file?
Hmmm no - looking at the PPC code for the go word it seems that we need someone who owns a copy of the IEEE-1275 bindings for SPARC and who is proficient in SPARC assembler to implement this :(
Which bindings? http://playground.sun.com/1275/home.html gives a SPARC binding but that is for V8.
I think that will do; at least it should contain enough information to work on the saved-program-state and the interaction between the client image and OF. Alas it's quite far out of my sphere of knowledge though.
Igor has suggested a C version in his previous email, although again I don't really know enough about SPARC to know if this is valid or not.
ATB,
Mark.
On Sun, Jan 3, 2010 at 10:12 AM, Mark Cave-Ayland mark.cave-ayland@siriusit.co.uk wrote:
Blue Swirl wrote:
Have we verified that OpenBios can jump to a SPARC ELF file?
Hmmm no - looking at the PPC code for the go word it seems that we need someone who owns a copy of the IEEE-1275 bindings for SPARC and who is proficient in SPARC assembler to implement this :(
Which bindings? http://playground.sun.com/1275/home.html gives a SPARC binding but that is for V8.
I think that will do; at least it should contain enough information to work on the saved-program-state and the interaction between the client image and OF. Alas it's quite far out of my sphere of knowledge though.
Looking at SILO and Linux usage, It looks like OF entry point needs to be in %o4 and %o0 must be zero.
http://fxr.watson.org/fxr/source/arch/sparc64/kernel/head.S?v=linux-2.4.22 http://git.kernel.org/?p=linux/kernel/git/bcollins/silo.git;a=blob;f=first/u... http://fxr.watson.org/fxr/source/arch/sparc/kernel/head.S?v=linux-2.4.22
But start_client_image() already handles this, except for zero %o0.
Igor has suggested a C version in his previous email, although again I don't really know enough about SPARC to know if this is valid or not.
Looks OK, though I don't again see any difference.
On Sun, Jan 3, 2010 at 3:00 PM, Blue Swirl blauwirbel@gmail.com wrote:
On Sun, Jan 3, 2010 at 10:12 AM, Mark Cave-Ayland mark.cave-ayland@siriusit.co.uk wrote:
Blue Swirl wrote:
Have we verified that OpenBios can jump to a SPARC ELF file?
Hmmm no - looking at the PPC code for the go word it seems that we need someone who owns a copy of the IEEE-1275 bindings for SPARC and who is proficient in SPARC assembler to implement this :(
Which bindings? http://playground.sun.com/1275/home.html gives a SPARC binding but that is for V8.
I think that will do; at least it should contain enough information to work on the saved-program-state and the interaction between the client image and OF. Alas it's quite far out of my sphere of knowledge though.
Looking at SILO and Linux usage, It looks like OF entry point needs to be in %o4 and %o0 must be zero.
http://fxr.watson.org/fxr/source/arch/sparc64/kernel/head.S?v=linux-2.4.22 http://git.kernel.org/?p=linux/kernel/git/bcollins/silo.git;a=blob;f=first/u... http://fxr.watson.org/fxr/source/arch/sparc/kernel/head.S?v=linux-2.4.22
But start_client_image() already handles this, except for zero %o0.
We may want to rework implementation so go() uses start_client_image() with saved context, and boot word uses client state reset, load, init-program and go words. load would fetch image, init-program would prepare saved context. This would match a hint in of1275 document about difference between boot and load words.
Igor has suggested a C version in his previous email, although again I don't really know enough about SPARC to know if this is valid or not.
Looks OK, though I don't again see any difference.
You need to skip return for failed ofmem_claim() in elf-loader to see any difference.
Igor Kovalenko wrote:
Looking at SILO and Linux usage, It looks like OF entry point needs to be in %o4 and %o0 must be zero.
http://fxr.watson.org/fxr/source/arch/sparc64/kernel/head.S?v=linux-2.4.22 http://git.kernel.org/?p=linux/kernel/git/bcollins/silo.git;a=blob;f=first/u... http://fxr.watson.org/fxr/source/arch/sparc/kernel/head.S?v=linux-2.4.22
But start_client_image() already handles this, except for zero %o0.
We may want to rework implementation so go() uses start_client_image() with saved context, and boot word uses client state reset, load, init-program and go words. load would fetch image, init-program would prepare saved context. This would match a hint in of1275 document about difference between boot and load words.
Yeah I think you're right here - by using an intermediate client state then it would be possible to share the majority of code between the two implementations.
Another interesting thing I noticed from this document was that the alarm word is implemented using a timer interrupt. Hence this would be a good test of general timer functionality (as well as given a twirly baton during the first loading stage!). Does anyone know if the qemu SPARC64 model currently supports a timer interrupt?
Igor has suggested a C version in his previous email, although again I don't really know enough about SPARC to know if this is valid or not.
Looks OK, though I don't again see any difference.
You need to skip return for failed ofmem_claim() in elf-loader to see any difference.
I wonder if we should just ignore the return from ofmem_claim() or maybe emit a warning? I guess the clash occurs because of the addresses being hard-coded in various parts of the Fcode loader, and so this won't change with real hardware.
Or then again maybe resetting the client state (as we believe should now happen in init-program) removes some of the old MMU mappings before executing the boot-archive ramdisk and so they wouldn't exist anymore?
ATB,
Mark.
On Sun, Jan 3, 2010 at 2:57 PM, Mark Cave-Ayland mark.cave-ayland@siriusit.co.uk wrote:
Igor Kovalenko wrote:
Looking at SILO and Linux usage, It looks like OF entry point needs to be in %o4 and %o0 must be zero.
http://fxr.watson.org/fxr/source/arch/sparc64/kernel/head.S?v=linux-2.4.22
http://git.kernel.org/?p=linux/kernel/git/bcollins/silo.git;a=blob;f=first/u... http://fxr.watson.org/fxr/source/arch/sparc/kernel/head.S?v=linux-2.4.22
But start_client_image() already handles this, except for zero %o0.
We may want to rework implementation so go() uses start_client_image() with saved context, and boot word uses client state reset, load, init-program and go words. load would fetch image, init-program would prepare saved context. This would match a hint in of1275 document about difference between boot and load words.
Yeah I think you're right here - by using an intermediate client state then it would be possible to share the majority of code between the two implementations.
Another interesting thing I noticed from this document was that the alarm word is implemented using a timer interrupt. Hence this would be a good test of general timer functionality (as well as given a twirly baton during the first loading stage!). Does anyone know if the qemu SPARC64 model currently supports a timer interrupt?
I thought it does (%tick register works), but it looks like the CPU timer interrupts (%tick_cmpr register) don't work at all.
On Tue, Jan 5, 2010 at 10:44 PM, Blue Swirl blauwirbel@gmail.com wrote:
On Sun, Jan 3, 2010 at 2:57 PM, Mark Cave-Ayland mark.cave-ayland@siriusit.co.uk wrote:
Igor Kovalenko wrote:
Looking at SILO and Linux usage, It looks like OF entry point needs to be in %o4 and %o0 must be zero.
http://fxr.watson.org/fxr/source/arch/sparc64/kernel/head.S?v=linux-2.4.22
http://git.kernel.org/?p=linux/kernel/git/bcollins/silo.git;a=blob;f=first/u... http://fxr.watson.org/fxr/source/arch/sparc/kernel/head.S?v=linux-2.4.22
But start_client_image() already handles this, except for zero %o0.
We may want to rework implementation so go() uses start_client_image() with saved context, and boot word uses client state reset, load, init-program and go words. load would fetch image, init-program would prepare saved context. This would match a hint in of1275 document about difference between boot and load words.
Yeah I think you're right here - by using an intermediate client state then it would be possible to share the majority of code between the two implementations.
Another interesting thing I noticed from this document was that the alarm word is implemented using a timer interrupt. Hence this would be a good test of general timer functionality (as well as given a twirly baton during the first loading stage!). Does anyone know if the qemu SPARC64 model currently supports a timer interrupt?
I thought it does (%tick register works), but it looks like the CPU timer interrupts (%tick_cmpr register) don't work at all.
I have somewhat working %tick_cmpr on qemu part, which at least allows linux kernel to measure bogomips :) It is a few patches long, fortunately mostly on sparc64 side.
On the firmware side, interesting thing is you cannot disarm alarm. What if instance is then closed?
On 2010-1-5 3:53 PM, Igor Kovalenko wrote:
[...] On the firmware side, interesting thing is you cannot disarm alarm. What if instance is then closed?
That's bad. "xt 0 alarm" should disarm the alarm - and close should too. Why doesn't it?
In the case of console, you won't have a problem under normal operation, but other devices which use alarms might indeed cause problems.
You'll have a problem with the console if you use the "input", "output" or "io" methods to switch the input or output console devices.
Tarl Neustaedter wrote:
On 2010-1-5 3:53 PM, Igor Kovalenko wrote:
[...] On the firmware side, interesting thing is you cannot disarm alarm. What if instance is then closed?
That's bad. "xt 0 alarm" should disarm the alarm - and close should too. Why doesn't it?
In the case of console, you won't have a problem under normal operation, but other devices which use alarms might indeed cause problems.
You'll have a problem with the console if you use the "input", "output" or "io" methods to switch the input or output console devices.
I'm assuming that Igor is referring to the Qemu timer model here, since the OpenBIOS alarm word is currently defined as "2 drop" ;)
In terms of the console, OpenBIOS currently doesn't use alarm interrupts there either - it just sits in a busy-wait loop checking an I/O port or similar to determine when a new character is incoming.
ATB,
Mark.
On Wed, Jan 6, 2010 at 12:33 PM, Mark Cave-Ayland mark.cave-ayland@siriusit.co.uk wrote:
Tarl Neustaedter wrote:
On 2010-1-5 3:53 PM, Igor Kovalenko wrote:
[...] On the firmware side, interesting thing is you cannot disarm alarm. What if instance is then closed?
That's bad. "xt 0 alarm" should disarm the alarm - and close should too. Why doesn't it?
In the case of console, you won't have a problem under normal operation, but other devices which use alarms might indeed cause problems.
You'll have a problem with the console if you use the "input", "output" or "io" methods to switch the input or output console devices.
I'm assuming that Igor is referring to the Qemu timer model here, since the OpenBIOS alarm word is currently defined as "2 drop" ;)
Just looking for corner cases. Missed that disarm path is actually documented in of1275 document in "alarm" section.
In terms of the console, OpenBIOS currently doesn't use alarm interrupts there either - it just sits in a busy-wait loop checking an I/O port or similar to determine when a new character is incoming.
So we need i/o scheduler now (not critical at the moment) :)
Igor Kovalenko wrote:
Just looking for corner cases. Missed that disarm path is actually documented in of1275 document in "alarm" section.
I've seen your Qemu patches go through the list, but does this mean you have a patch for the OpenBIOS alarm word somewhere that we haven't seen yet?
In terms of the console, OpenBIOS currently doesn't use alarm interrupts there either - it just sits in a busy-wait loop checking an I/O port or similar to determine when a new character is incoming.
So we need i/o scheduler now (not critical at the moment) :)
Yeah, I can't get too excited about this. It's not as if BIOS routines are super-performance critical...
ATB,
Mark.
On Thu, Jan 7, 2010 at 1:50 AM, Mark Cave-Ayland mark.cave-ayland@siriusit.co.uk wrote:
Igor Kovalenko wrote:
Just looking for corner cases. Missed that disarm path is actually documented in of1275 document in "alarm" section.
I've seen your Qemu patches go through the list, but does this mean you have a patch for the OpenBIOS alarm word somewhere that we haven't seen yet?
Not sure I can even try this without working timers on sparc64 I think sparc (or maybe ppc as well) has good enough timer support so openbios can progress in implementing alarm word.
Do we have a test case for alarm word? Is it really useful?
In terms of the console, OpenBIOS currently doesn't use alarm interrupts there either - it just sits in a busy-wait loop checking an I/O port or similar to determine when a new character is incoming.
So we need i/o scheduler now (not critical at the moment) :)
Yeah, I can't get too excited about this. It's not as if BIOS routines are super-performance critical...
Forth profiler... not sure it is a good idea :)
Igor Kovalenko wrote:
Not sure I can even try this without working timers on sparc64 I think sparc (or maybe ppc as well) has good enough timer support so openbios can progress in implementing alarm word.
Do we have a test case for alarm word? Is it really useful?
Yes. The Milax loader tries to set up an alarm callback to display a twirly baton during the loading stage, so that would be a good test. Is it useful? Hmmm.... ;)
It just struck me that it would be a good test for SPARC64 interrupt handling in Qemu as it's something that can easily be tested from OpenBIOS.
ATB,
Mark.