[OpenBIOS] [RFC 3/3] ppc: RTAS WIP

Andreas Färber andreas.faerber at web.de
Fri Oct 15 20:18:49 CEST 2010


Am 15.10.2010 um 00:38 schrieb Alexander Graf:

> Am 15.10.2010 um 00:17 schrieb Andreas Färber  
> <andreas.faerber at web.de>:
>
>> diff --git a/arch/ppc/qemu/init.c b/arch/ppc/qemu/init.c
>> index 2b0b891..6d72386 100644
>> --- a/arch/ppc/qemu/init.c
>> +++ b/arch/ppc/qemu/init.c

>> @@ -745,10 +749,11 @@ arch_of_init( void )
>>       printk("Warning: No /rtas node\n");
>>   else {
>>       unsigned long size = 0x1000;
>> -        while( size < (unsigned long)of_rtas_end - (unsigned  
>> long)of_rtas_start )
>> +        while ( size < rtas_size )
>>           size *= 2;
>>       set_property( ph, "rtas-size", (char*)&size, sizeof(size) );
>>       set_int_property(ph, "rtas-version", 1);
>
> Didn't you just set this to 0x41?

No. My Mac has it as 0x41 (or 41?). The JS20 tree and the spec has it  
as 1.

Locally I'm using ARCH_CHRP_U3 for differentiation, setting up the / 
rtas node for chrp only, for instance. The machine enum needs to the  
sync'ed with QEMU though. Would a patch adding just the enum member  
(i.e., reserving the value 4) have anything chance of being applied  
without accompanying fully-complete-and-reviewed machine? My chrp  
machine is just a stripped-down version of mac99 for now, some memory  
locations would need to change once we have OpenBIOS/ppc64 compiling  
and some devices like mac-io would need to be exchanged. Blue?

>> diff --git a/arch/ppc/qemu/rtas-tokens.c b/arch/ppc/qemu/rtas- 
>> tokens.c
>> new file mode 100644
>> index 0000000..f251716
>> --- /dev/null
>> +++ b/arch/ppc/qemu/rtas-tokens.c
>> @@ -0,0 +1,63 @@
>> +/*
>> + * Copyright (c) 2010 Andreas Färber <andreas.faerber at web.de>
>> + */
>
> This is missing a copyleft license.

Yeah, and an SoB. Not yet ready for committing.

>> +#define RTAS_MAX_ARGS    10
>> +
>> +typedef struct rtas_args {
>> +    unsigned long    token;
>> +    long            nargs;
>> +    long            nret;
>> +    unsigned long    args[RTAS_MAX_ARGS];
>> +} rtas_args_t;
>> +
>> +void rtas_interface(rtas_args_t*, void*);
>> +
>> +/* drivers/escc.h */
>> +#define IO_ESCC_OFFSET  0x00013000
>> +/* drivers/escc.c */
>> +#define CTRL(addr) (*(volatile unsigned char *)(addr))
>> +#define DATA(addr) (*(volatile unsigned char *)(addr + 16))
>> +#define Tx_BUF_EMP      0x4     /* Tx Buffer empty */
>> +
>> +/*static void uart_putchar(int port, unsigned char c)
>> +{
>> +    while (!(CTRL(port) & Tx_BUF_EMP))
>> +        ;
>> +    DATA(port) = c;
>> +}*/
>> +
>> +/*void serial_putchar(char);*/
>> +
>> +static void serial_putchar(char c)
>> +{
>> +    unsigned long addr = 0x80800000;
>
> Phew - how is this done for the normal escc case?

In OpenBIOS, the address is passed in from PCI code.

In /rtas, there's a "display-device" property that specifies the  
phandle to be used for display-character. We would have to read this  
and pass any addresses to RTAS as part of instantiate-rtas.

> We should at least share the constants here.

As documented above, most #defines were in the source file and would  
need to be moved to a header file for sharing.

Here, I just wanted a quick way to trace whether my code was being  
called. OpenBIOS' escc code is very OF-specific, and the JS20 doesn't  
have a mac-io/cuda/escc device anyway. We might be able to split some  
core I/O functions like these off.

>> +GLOBL(_entry):
>> +    /*
>> +     * r3 = arguments
>> +     * r4 = private memory
>> +     */
>> +    stw r1, 0(r4)
>> +    stw r2, 4(r4)
>> +
>> +    stwu r1, -12(r1)
>
> Is the os guaranteed to give you r4 and r1 for free scribbling over?

r4 is a pointer to the memory it claimed for us. My reservation of  
0x1000 initial bytes in rtas_initialize() leaves some space for saving  
state and passing in the shared struct you suggested.

>> +    stw r4, 8(r1)
>> +    mflr r0
>> +    stw r0, 4(r1)
>> +
>
> /* saving non-volatile registers */
>
>> +    stw r13,  8(r4)
>
> I would recommend multiplying here:
>
> stw r13, (3 * 4)(r4)
>
> That makes it more readable.

I actually adapted this from start.S for the client interface.

stwu x, 4(y) on a volatile register would be ever better imo. It was a  
nightly proof of concept! ;)

Question: The CIF does irritating things with r1 and r4 and  
saved_stack - why? Would it be better to save everything on the stack  
here?

>> +    bl rtas_interface
>
> So rtas_interface gets the os given r3 as first parameter. Please  
> make sure that struct is packed then.

Good catch.

>> +
>> +    lwz r0, 4(r1)
>> +    mtlr r0
>> +    lwz    r4, 8(r1)
>> +//    lwz    r1, 0(r1)
>> +
>> +    lwz r2, 84(r4)
>> +    mtcr r2
>
> If the abi is similar to the normal C one, cr is volatile.

It definitely isn't. I believe the CIF preserves it, too.

Andreas


More information about the OpenBIOS mailing list