Author Topic: G5 qemu attempts.  (Read 58787 times)

Offline powermax

  • Enthusiast Member
  • ***
  • Posts: 80
  • Hobbyist programmer
Re: G5 qemu attempts.
« Reply #120 on: October 18, 2018, 05:16:19 AM »
Until Open Firmware is quiesced, the "enter" client interface call can be used to drop to the command prompt. You can then inspect registers and do other stuff from OF. Maybe you could tack a little code onto the end of the Trampoline that so you can patch code to call it.

Sounds adventurous. I wonder how does OF commands look like in the case I need to halt the Trampoline at arbitrary execution point and print out GRP values.

Can you elaborate?

Offline Naiw

  • Veteran Member
  • ****
  • Posts: 126
  • new to the forums
Re: G5 qemu attempts.
« Reply #121 on: October 18, 2018, 07:50:30 AM »
dcbz will operate as expected if HID5 is set on the 970.

Offline darthnVader

  • Platinum Member
  • *****
  • Posts: 679
  • New Member
Re: G5 qemu attempts.
« Reply #122 on: October 18, 2018, 08:04:40 AM »
dcbz will operate as expected if HID5 is set on the 970.

hmmm.......

I think I can find a way to do that with Qemu/Openbios.

Quote
* Hardware Implementation  1113          HID5 or DABR or SPR1013
Register 5

Any idea what the value should be?

Offline powermax

  • Enthusiast Member
  • ***
  • Posts: 80
  • Hobbyist programmer
Re: G5 qemu attempts.
« Reply #123 on: October 18, 2018, 08:09:25 AM »
dcbz will operate as expected if HID5 is set on the 970.

That's what apparently Apple's OF does, but not OpenBIOS. To be verified on a real hardware...

Offline Naiw

  • Veteran Member
  • ****
  • Posts: 126
  • new to the forums
Re: G5 qemu attempts.
« Reply #124 on: October 18, 2018, 08:49:21 AM »
dcbz will operate as expected if HID5 is set on the 970.

hmmm.......

I think I can find a way to do that with Qemu/Openbios.

Quote
* Hardware Implementation  1113          HID5 or DABR or SPR1013
Register 5

Any idea what the value should be?

I believe it's bit 56 and/or 57. You can probably find out using CHUD on OS X (I believe Reggae or whatever the tool was called can display them)

Offline Naiw

  • Veteran Member
  • ****
  • Posts: 126
  • new to the forums
Re: G5 qemu attempts.
« Reply #125 on: October 18, 2018, 08:53:22 AM »
If you specify a G4 or something when using kvm-pr I believe kvm will emulate dbnz (along with a bunch of uisa instructions the 970 don't have) via the executable page scanner/patching  mechanism though.

Offline Daniel

  • Gold Member
  • *****
  • Posts: 300
  • Programmer, Hacker, Thinker
Re: G5 qemu attempts.
« Reply #126 on: October 18, 2018, 02:09:37 PM »
Until Open Firmware is quiesced, the "enter" client interface call can be used to drop to the command prompt. You can then inspect registers and do other stuff from OF. Maybe you could tack a little code onto the end of the Trampoline that so you can patch code to call it.

Sounds adventurous. I wonder how does OF commands look like in the case I need to halt the Trampoline at arbitrary execution point and print out GRP values.

Can you elaborate?
Once in OF, you can use the " .registers " command to print the client program's registers. You will get something that looks like this:
Code: [Select]
Client's Fix Pt Regs:
 00 00000080 0010fcf8 deadbeef 001198c8 001198c4 00000001 0010ff34 001198c8
 08 001198d4 0010fd5c 0010fda4 0010ff65 001198b8 00000000 00104800 001047e0
 10 00000000 00104798 00000000 001170a0 9e9044d8 9e9044d8 00106b34 00218288
 18 0026f1e0 00000000 00000000 001170a4 ffffffff 00119890 001198d8 0010fd60
Special Regs:
    %IV: 00000300   %SRR0: 0020dc68   %SRR1: 00003030
    %CR: 4884204c     %LR: 0020dc68    %CTR: ff80a290    %XER: 00000000
   %DAR: 00b94000  %DSISR: 42000000   %SDR1: 1ffe0000
You can also do %r4 or %dsisr to get some of the registers that way. I don't think you can modify the regs from OF unless you do some trickery described in this post:http://macos9lives.com/smforum/index.php/topic,3884.msg27290.html#msg27290.

You could do this manually from OF once you do an "enter" call or you could use the "interpret" call to execute .registers directly.

One way to do breakpoints is to save the instruction elsewhere and stick down a bl or b in it's place. A bit of wizardry might be needed to make sure all the registers are saved, but it is doable. You would then do a "write" call to stdout or "enter" into the OF prompt.

The Trampoline code section is writable on my Pismo, but it wouldn't have mattered much if it was protected. It is so easy to change mmu state in OF.

Offline darthnVader

  • Platinum Member
  • *****
  • Posts: 679
  • New Member
Re: G5 qemu attempts.
« Reply #127 on: October 18, 2018, 11:29:59 PM »
Here is what HID5 looks like in Qemu's source code:

Code: [Select]
#if defined(TARGET_PPC64)
#if defined(CONFIG_USER_ONLY)
#define POWERPC970_HID5_INIT 0x00000080
#else
#define POWERPC970_HID5_INIT 0x00000000
#endif

Code: [Select]
static void gen_spr_970_hid(CPUPPCState *env)
{
    /* Hardware implementation registers */
    /* XXX : not implemented */
    spr_register(env, SPR_HID0, "HID0",
                 SPR_NOACCESS, SPR_NOACCESS,
                 &spr_read_generic, &spr_write_clear,
                 0x60000000);
    spr_register(env, SPR_HID1, "HID1",
                 SPR_NOACCESS, SPR_NOACCESS,
                 &spr_read_generic, &spr_write_generic,
                 0x00000000);
    spr_register(env, SPR_970_HID5, "HID5",
                 SPR_NOACCESS, SPR_NOACCESS,
                 &spr_read_generic, &spr_write_generic,
                 POWERPC970_HID5_INIT);
}

Code: [Select]
#define S_HID5 1013
Code: [Select]
void helper_dcbz(CPUPPCState *env, target_ulong addr, uint32_t opcode)
{
    target_ulong mask, dcbz_size = env->dcache_line_size;
    uint32_t i;
    void *haddr;

#if defined(TARGET_PPC64)
    /* Check for dcbz vs dcbzl on 970 */
    if (env->excp_model == POWERPC_EXCP_970 &&
        !(opcode & 0x00200000) && ((env->spr[SPR_970_HID5] >> 7) & 0x3) == 1) {
        dcbz_size = 32;
    }
#endif

    /* Align address */
    mask = ~(dcbz_size - 1);
    addr &= mask;

    /* Check reservation */
    if ((env->reserve_addr & mask) == (addr & mask))  {
        env->reserve_addr = (target_ulong)-1ULL;
    }

Code: [Select]
#define SPR_970_HID5          (0x3F6)

Offline powermax

  • Enthusiast Member
  • ***
  • Posts: 80
  • Hobbyist programmer
Re: G5 qemu attempts.
« Reply #128 on: October 19, 2018, 04:20:11 AM »
BTW, does anyone has manuals for PowerPC G5 CPUs? I'm interested in the original 970, 970mp and 970fx.

I wasn't able to locate them via web search. It looks IBM completely removed them from their support site...

Offline powermax

  • Enthusiast Member
  • ***
  • Posts: 80
  • Hobbyist programmer
Re: G5 qemu attempts.
« Reply #129 on: October 19, 2018, 04:28:17 AM »
You could do this manually from OF once you do an "enter" call or you could use the "interpret" call to execute .registers directly.

One way to do breakpoints is to save the instruction elsewhere and stick down a bl or b in it's place. A bit of wizardry might be needed to make sure all the registers are saved, but it is doable. You would then do a "write" call to stdout or "enter" into the OF prompt.

Thanks. The proposed way is indeed interesting but it would require writing a debugging stub for setting breakpoints, for saving and restoring state etc. It sounds less convenient as QEMU+GDB but can be an option when running on a real HW...
« Last Edit: October 19, 2018, 05:38:22 AM by powermax »

Offline darthnVader

  • Platinum Member
  • *****
  • Posts: 679
  • New Member
Re: G5 qemu attempts.
« Reply #130 on: October 19, 2018, 06:00:39 AM »
Here is what HID5 looks like in Qemu's source code:

Code: [Select]
#if defined(TARGET_PPC64)
#if defined(CONFIG_USER_ONLY)
#define POWERPC970_HID5_INIT 0x00000080
#else
#define POWERPC970_HID5_INIT 0x00000000
#endif

Code: [Select]
static void gen_spr_970_hid(CPUPPCState *env)
{
    /* Hardware implementation registers */
    /* XXX : not implemented */
    spr_register(env, SPR_HID0, "HID0",
                 SPR_NOACCESS, SPR_NOACCESS,
                 &spr_read_generic, &spr_write_clear,
                 0x60000000);
    spr_register(env, SPR_HID1, "HID1",
                 SPR_NOACCESS, SPR_NOACCESS,
                 &spr_read_generic, &spr_write_generic,
                 0x00000000);
    spr_register(env, SPR_970_HID5, "HID5",
                 SPR_NOACCESS, SPR_NOACCESS,
                 &spr_read_generic, &spr_write_generic,
                 POWERPC970_HID5_INIT);
}

Code: [Select]
#define S_HID5 1013
Code: [Select]
void helper_dcbz(CPUPPCState *env, target_ulong addr, uint32_t opcode)
{
    target_ulong mask, dcbz_size = env->dcache_line_size;
    uint32_t i;
    void *haddr;

#if defined(TARGET_PPC64)
    /* Check for dcbz vs dcbzl on 970 */
    if (env->excp_model == POWERPC_EXCP_970 &&
        !(opcode & 0x00200000) && ((env->spr[SPR_970_HID5] >> 7) & 0x3) == 1) {
        dcbz_size = 32;
    }
#endif

    /* Align address */
    mask = ~(dcbz_size - 1);
    addr &= mask;

    /* Check reservation */
    if ((env->reserve_addr & mask) == (addr & mask))  {
        env->reserve_addr = (target_ulong)-1ULL;
    }

Code: [Select]
#define SPR_970_HID5          (0x3F6)

So a dodgy hack would be something like:

Code: [Select]
#if defined(TARGET_PPC64)
#if defined(CONFIG_USER_ONLY)
#define POWERPC970_HID5_INIT 0x00000080
#else
#define POWERPC970_HID5_INIT 0x00000080
#endif

Code: [Select]
void helper_dcbz(CPUPPCState *env, target_ulong addr, uint32_t opcode)
{
    target_ulong mask, dcbz_size = env->dcache_line_size;
    uint32_t i;
    void *haddr;


    /* Check for dcbz vs dcbzl on 970 */
    if (env->excp_model == POWERPC_EXCP_970 &&
        !(opcode & 0x00200000) && ((env->spr[SPR_970_HID5] >> 7) & 0x3) == 1) {
        dcbz_size = 32;
    }


    /* Align address */
    mask = ~(dcbz_size - 1);
    addr &= mask;

    /* Check reservation */
    if ((env->reserve_addr & mask) == (addr & mask))  {
        env->reserve_addr = (target_ulong)-1ULL;
    }

And that seems to work, as to the memory errors, we get Off to the Mac OS, sadly we never get the Nano Kernel.........

970:

Code: [Select]
(gdb)  break *0x203ce8
Breakpoint 1 at 0x203ce8
(gdb) cont
The program is not being run.
(gdb) target remote localhost:1234
Remote debugging using localhost:1234
0x00000000fff00100 in ?? ()
(gdb) cont'
Not stopped at any breakpoint; argument ignored.
Continuing.

Breakpoint 1, 0x0000000000203ce8 in ?? ()
(gdb) display/i $pc
1: x/i $pc
=> 0x203ce8: bl      0x20fe70
(gdb)  break *0x20FD90
Breakpoint 2 at 0x20fd90
(gdb) cont
Continuing.

Breakpoint 2, 0x000000000020fd90 in ?? ()
1: x/i $pc
=> 0x20fd90: stfd    f0,0(r4)
(gdb)  p/x $r4
$1 = 0x3fee50e0
(gdb) x/8xw 0x3fee5000
0x3fee5000: 0x40000000 0x40000000 0x00000000 0x00000000
0x3fee5010: 0x00000000 0x00000000 0x00000000 0x00000000
(gdb) cont
Continuing.

Breakpoint 2, 0x000000000020fd90 in ?? ()
1: x/i $pc
=> 0x20fd90: stfd    f0,0(r4)
(gdb) cont
Continuing.

Breakpoint 2, 0x000000000020fd90 in ?? ()
1: x/i $pc
=> 0x20fd90: stfd    f0,0(r4)
(gdb) cont
Continuing.

Breakpoint 2, 0x000000000020fd90 in ?? ()
1: x/i $pc
=> 0x20fd90: stfd    f0,0(r4)
(gdb) p/x $r4
$2 = 0x3fee5080
(gdb)  x/8xw 0x3fee5000
0x3fee5000: 0x40000000 0x40000000 0x00000000 0x00000000
0x3fee5010: 0x00000000 0x00000000 0x00000000 0x00000000
(gdb) cont
Continuing.

Breakpoint 2, 0x000000000020fd90 in ?? ()
1: x/i $pc
=> 0x20fd90: stfd    f0,0(r4)
(gdb)  p/x $r4
$3 = 0x3fee5060
(gdb) x/8xw 0x3fee5000
0x3fee5000: 0x40000000 0x40000000 0x00000000 0x00000000
0x3fee5010: 0x00000000 0x00000000 0x00000000 0x00000000
(gdb)

Offline powermax

  • Enthusiast Member
  • ***
  • Posts: 80
  • Hobbyist programmer
Re: G5 qemu attempts.
« Reply #131 on: October 19, 2018, 06:17:52 AM »
And that seems to work, as to the memory errors, we get Off to the Mac OS, sadly we never get the Nano Kernel.........

To ensure that, you'd need to enable the Nanokernel debugger by adding 0x100000 and Nanokernel logging by adding 0x2000000 to AAPL,debug:
Code: [Select]
dev / 3013FFF encode-int " AAPL,debug" property
If no other message except "Off to Mac OS..." will be displayed, you got a crash in the RecolationEngine (before Nanokernel)...

Offline darthnVader

  • Platinum Member
  • *****
  • Posts: 679
  • New Member
Re: G5 qemu attempts.
« Reply #132 on: October 19, 2018, 06:34:16 AM »
And that seems to work, as to the memory errors, we get Off to the Mac OS, sadly we never get the Nano Kernel.........

To ensure that, you'd need to enable the Nanokernel debugger by adding 0x100000 and Nanokernel logging by adding 0x2000000 to AAPL,debug:
Code: [Select]
dev / 3013FFF encode-int " AAPL,debug" property
If no other message except "Off to Mac OS..." will be displayed, you got a crash in the RecolationEngine (before Nanokernel)...

Seems only this bit of code is necessary:

Code: [Select]
#if defined(TARGET_PPC64)
#if defined(CONFIG_USER_ONLY)
#define POWERPC970_HID5_INIT 0x00000080
#else
#define POWERPC970_HID5_INIT 0x00000080
#endif

That seems to set the correct bit in HID5 so dcbz is treated correctly, I don't know what the code  helper_dcbz does, but we don't seem to need it for now.

Code: [Select]
#if defined(TARGET_PPC64)
    /* Check for dcbz vs dcbzl on 970 */
    if (env->excp_model == POWERPC_EXCP_970 &&
        !(opcode & 0x00200000) && ((env->spr[SPR_970_HID5] >> 7) & 0x3) == 1) {
        dcbz_size = 32;
    }
#endif

Code: [Select]
/qemu-system-ppc64 -cpu 970 -M mac99 -m 1024 -prom-env "aapl,debug=3013FFF" -hda ~/os9/os9.img -prom-env "auto-boot?=false
We never get anything passed Off to the Mac OS, so we must be crashing in the RecolationEngine.

Any idea how to debug that?


Offline powermax

  • Enthusiast Member
  • ***
  • Posts: 80
  • Hobbyist programmer
Re: G5 qemu attempts.
« Reply #133 on: October 19, 2018, 09:11:33 AM »
We never get anything passed Off to the Mac OS, so we must be crashing in the RecolationEngine.

Any idea how to debug that?

Set a breakpoint at 0x20F0A4, then "cont" then trace that code with "stepi"...

Offline powermax

  • Enthusiast Member
  • ***
  • Posts: 80
  • Hobbyist programmer
Re: G5 qemu attempts.
« Reply #134 on: October 19, 2018, 11:47:48 AM »
I believe it's bit 56 and/or 57.

I finally got my hands on the 970FX manual.

There are actually two forms of the dcbz instruction on 970FX: dcbz and dcbzl. The opcode of the former has bit 10 always unset. Setting bit 10 to '1' turns dcbz to dcbzl on G5.
The opcode & 0x00200000 expression in the above mentioned code snippet checks for this precise form.

Bits of the HID5 related to dcbz are 56 and 57. They have the following meaning:

Code: [Select]
HID5[57] value     HID5[56] value     Meaning
--------------     --------------     -------
1                  ignored            makes dcbz an illegal instruction
0                  0                  cache block size = 128 bytes
0                  1                  cache block size = 32 bytes
« Last Edit: October 19, 2018, 12:00:20 PM by powermax »

Offline Daniel

  • Gold Member
  • *****
  • Posts: 300
  • Programmer, Hacker, Thinker
Re: G5 qemu attempts.
« Reply #135 on: October 19, 2018, 12:00:29 PM »
Unfortunately, that RTASFairyDust function in the Mac OS ROM's exception table trys to clear the BATs before jumping into the NK. Even if the RelocationEngine finishes correctly, the loaded Mac OS ROM will have crashed before a single instruction in the NK is executed.

Offline powermax

  • Enthusiast Member
  • ***
  • Posts: 80
  • Hobbyist programmer
Re: G5 qemu attempts.
« Reply #136 on: October 19, 2018, 12:08:14 PM »
Unfortunately, that RTASFairyDust function in the Mac OS ROM's exception table trys to clear the BATs before jumping into the NK. Even if the RelocationEngine finishes correctly, the loaded Mac OS ROM will have crashed before a single instruction in the NK is executed.

Yes. Moreover, the disastrously fact is that the RelocationEngine does also clear the BATs as soon as it gains control. This way, it will send itself to the dark side of the moon before a single block is relocated. ;D

Offline darthnVader

  • Platinum Member
  • *****
  • Posts: 679
  • New Member
Re: G5 qemu attempts.
« Reply #137 on: October 19, 2018, 06:07:15 PM »
Unfortunately, that RTASFairyDust function in the Mac OS ROM's exception table trys to clear the BATs before jumping into the NK. Even if the RelocationEngine finishes correctly, the loaded Mac OS ROM will have crashed before a single instruction in the NK is executed.

Is that going to be a problem on the 970, ELN stated that it does have BAT registers?

Offline powermax

  • Enthusiast Member
  • ***
  • Posts: 80
  • Hobbyist programmer
Re: G5 qemu attempts.
« Reply #138 on: October 19, 2018, 07:12:29 PM »
Is that going to be a problem on the 970, ELN stated that it does have BAT registers?

User manuals for 970FX and 970MP doesn't say anything about BAT's presence or absence. I assume these CPUs don't support block address translation (BAT) in the form it was implemented in the PPC32 architecture.

I cannot provide any confirmation that the 1st G5 version (970) does support BAT. You can try to switch QEMU to 970 CPU (PVR=0x00390202) to see if there be any progress but I doubt it will work...

Offline Naiw

  • Veteran Member
  • ****
  • Posts: 126
  • new to the forums
Re: G5 qemu attempts.
« Reply #139 on: October 20, 2018, 03:35:41 AM »
Unfortunately, that RTASFairyDust function in the Mac OS ROM's exception table trys to clear the BATs before jumping into the NK. Even if the RelocationEngine finishes correctly, the loaded Mac OS ROM will have crashed before a single instruction in the NK is executed.

Is that going to be a problem on the 970, ELN stated that it does have BAT registers?

Neither have BATs.