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

Offline darthnVader

  • Platinum Member (500+ Posts)
  • *****
  • Posts: 520
  • New Member
Re: G5 qemu attempts.
« Reply #75 on: October 15, 2018, 05:22:28 PM »
Code: [Select]
(gdb) break *0x203ce8
Breakpoint 1 at 0x203ce8
(gdb) target remote localhost:1234
Remote debugging using localhost:1234
0x00000000fff00100 in ?? ()
(gdb) cont
Continuing.

Breakpoint 1, 0x0000000000203ce8 in ?? ()
(gdb)  p/x $r3
$1 = 0x3fee5038
(gdb)  p/x $r4
$2 = 0x3fee5048
(gdb)  p/x $r5
$3 = 0xb8
(gdb)

Offline powermax

  • Enthusiast Member (25+ Posts)
  • ***
  • Posts: 80
  • Hobbyist programmer
Re: G5 qemu attempts.
« Reply #76 on: October 15, 2018, 06:46:46 PM »
A comparison with a working (G4 32bit) configuration could shed some light at this issue. Maybe you'll find some free time for doing such a comparison...

Under "comparison with G4", I mean "instruction-by-instruction" comparison starting with 0x203ce8. That's required to find the instruction that doesn't work as expected. You'll probably need to trace about 20-30 instructions, first on G4, then on G5:

trace an instruction
write down what it changes (we're interested mostly in register values)
an so on...

It's a superb tutorial on the PPC Assembly...
« Last Edit: October 16, 2018, 06:57:23 AM by powermax »

Offline darthnVader

  • Platinum Member (500+ Posts)
  • *****
  • Posts: 520
  • New Member
Re: G5 qemu attempts.
« Reply #77 on: October 16, 2018, 06:37:06 AM »
G4:

Code: [Select]
Breakpoint 1, 0x0000000000203ce8 in ?? ()
(gdb) p/x $r3
$4 = 0x3fee5038
(gdb) p/x $r4
$5 = 0x3fee5048
(gdb) p/x $r5
$6 = 0xb8
(gdb)

Offline powermax

  • Enthusiast Member (25+ Posts)
  • ***
  • Posts: 80
  • Hobbyist programmer
Re: G5 qemu attempts.
« Reply #78 on: October 16, 2018, 06:59:33 AM »
It looks like I've just mistakenly overridden my own post. Sorry  :(

A comparison with a working (G4 32bit) configuration could shed some light at this issue. Maybe you'll find some free time for doing such a comparison...

Under "comparison with G4", I mean "instruction-by-instruction" comparison starting with 0x203ce8. That's required to find the instruction that doesn't work as expected. You'll probably need to trace about 20-30 instructions, first on G4, then on G5:

trace an instruction
write down what it changes (we're interested mostly in register values)
an so on...

It's a superb tutorial on the PPC Assembly...

Offline darthnVader

  • Platinum Member (500+ Posts)
  • *****
  • Posts: 520
  • New Member
Re: G5 qemu attempts.
« Reply #79 on: October 16, 2018, 07:39:51 AM »
It looks like I've just mistakenly overridden my own post. Sorry  :(

A comparison with a working (G4 32bit) configuration could shed some light at this issue. Maybe you'll find some free time for doing such a comparison...

Under "comparison with G4", I mean "instruction-by-instruction" comparison starting with 0x203ce8. That's required to find the instruction that doesn't work as expected. You'll probably need to trace about 20-30 instructions, first on G4, then on G5:

trace an instruction
write down what it changes (we're interested mostly in register values)
an so on...

It's a superb tutorial on the PPC Assembly...

Ok I'm game, but you'll have to walk me through what I need to do, as so far I only understand some of what we are doing.


Offline powermax

  • Enthusiast Member (25+ Posts)
  • ***
  • Posts: 80
  • Hobbyist programmer
Re: G5 qemu attempts.
« Reply #80 on: October 16, 2018, 08:10:00 AM »
Ok I'm game, but you'll have to walk me through what I need to do, as so far I only understand some of what we are doing.

Ok, consider the following code (that's the beginning of bcopy):

Code: [Select]
0x20FB4C      cmplwi  cr7, r5, 0x20
0x20FB50      cmplw   cr6, r4, r3
0x20FB54      mr.     r0, r5
0x20FB58      bgt     cr7, 0x20FB70
0x20FB5C      beq     cr7, 0x20FBC4
0x20FB60      blt     cr6, 0x20FC74
0x20FB64      add     r3, r3, r5
0x20FB68      add     r4, r4, r5
0x20FB6C      b       0x20FC08

The first two instructions are unsigned comparisons, cr7 is the condition field that will be set according with the comparison result, we're going to compare r5 (copy length) with 0x20:

Code: [Select]
cr7.eq = r5 - 0x20
cr7.lt = r5 - 0x20
cr7.gt = r5 - 0x20

where "eq" denotes equality, "lt" - lower then, "gt" - greater than. In other words, if r5 == 0x20, the "eq" flag of CR7 will be set, otherwise cleared; if r5 < 0x20, "lt" is set, otherwise cleared an so on.

You'd basically start the trace on G4 at 0x203ce8 and proceed by executing every single instruction using "stepi". Then you write down updated register values, for example "add r3, r3, r5" will update $r3 so you need to write that new value down.

Regarding conditional branches: beq (branch if equal), blt (branch if lower) an so on - you'll only need to write down if a particular branch is taken or not (I'm using "+" for taken and "-" for not taken).

The PowerPC instruction reference will be very useful here...

Then you take that list and compares the results with the trace on G5. It's tedious, yes, but this way you should be able to spot the failing instruction...

Offline darthnVader

  • Platinum Member (500+ Posts)
  • *****
  • Posts: 520
  • New Member
Re: G5 qemu attempts.
« Reply #81 on: October 16, 2018, 09:15:33 AM »
You completely lost me :-\

I need to set the break point to  0x203ce8, then I'm not sure what command to use to trace, before I use stepi?

I know it's painful, but once I understand the first one, thing should go a little quicker. 8)

Offline powermax

  • Enthusiast Member (25+ Posts)
  • ***
  • Posts: 80
  • Hobbyist programmer
Re: G5 qemu attempts.
« Reply #82 on: October 16, 2018, 09:29:56 AM »
You completely lost me :-\

I need to set the break point to  0x203ce8, then I'm not sure what command to use to trace, before I use stepi?

You don't need anything else than "stepi". Just set the breakpoint, then trace with stepi.

Code: [Select]
(gdb) break *0x203ce8
(gdb) cont
(gdb) display/i $pc
(gdb) stepi (this will excute b 0x20fe70)
(gdb) stepi (this will execute b 0x20fb4c)
(gdb) stepi (this will execute cmplwi cr7, r5, 0x20)
(gdb) stepi (this will execute cmplw cr6, r4, r3)
(gdb) stepi (this will execute mr. r0, r5 after it r0 = r5, no need to track it)
(gdb) stepi (execute bgt cr7, 0x20FB70 --> conditional branch, mark it with "+" if it jumps to 0x20fb70, otherwise mark it with "-")
(gdb) stepi (beq cr7, 0x20FBC4 --> another cond branch, proceed as above)
(gdb) stepi (blt cr6, 0x20FC74 --> yet another cond branch, proceed as above)
(gdb) stepi (add  r3, r3, r5 --> changes $r3, so...)
(gdb) p/x $r3 (write down new $r3 value)

an so on...

Offline darthnVader

  • Platinum Member (500+ Posts)
  • *****
  • Posts: 520
  • New Member
Re: G5 qemu attempts.
« Reply #83 on: October 16, 2018, 10:01:49 AM »
Still lost:

Code: [Select]
Breakpoint 1, 0x0000000000203ce8 in ?? ()
(gdb) display/i $pc
1: x/i $pc
=> 0x203ce8: bl      0x20fe70
(gdb) stepi
0x000000000020fe70 in ?? ()
1: x/i $pc
=> 0x20fe70: b       0x20fb4c
(gdb) stepi
0x000000000020fb4c in ?? ()
1: x/i $pc
=> 0x20fb4c: cmplwi  cr7,r5,32
(gdb) stepi
0x000000000020fb50 in ?? ()
1: x/i $pc
=> 0x20fb50: cmplw   cr6,r4,r3
(gdb) stepi
0x000000000020fb54 in ?? ()
1: x/i $pc
=> 0x20fb54: mr.     r0,r5
(gdb) stepi
0x000000000020fb58 in ?? ()
1: x/i $pc
=> 0x20fb58: bgt     cr7,0x20fb70
(gdb) stepi
0x000000000020fb70 in ?? ()
1: x/i $pc
=> 0x20fb70: beqlr   cr6
(gdb) stepi
0x000000000020fb74 in ?? ()
1: x/i $pc
=> 0x20fb74: bltlr   
(gdb) stepi
0x000000000020fb78 in ?? ()
1: x/i $pc
=> 0x20fb78: mflr    r12
(gdb) stepi
0x000000000020fb7c in ?? ()
1: x/i $pc
=> 0x20fb7c: bge     cr6,0x20fba0
(gdb) stepi
0x000000000020fba0 in ?? ()
1: x/i $pc
=> 0x20fba0: add     r3,r3,r5
(gdb) p/x $r3
$1 = 0x3fee5038
(gdb)

Code: [Select]
1: x/i $pc
=> 0x20fb58: bgt     cr7,0x20fb70

conditional branch, but I don't understand what is being compared to what, or what is being done?

If what is greater than?


Offline Daniel

  • Gold Member (200+ Posts)
  • *****
  • Posts: 269
  • Programmer, Hacker, Thinker
Re: G5 qemu attempts.
« Reply #84 on: October 16, 2018, 01:44:09 PM »
Code: [Select]
cmplwi  cr7,r5,32This compares r5 to 32 and sets condition register 7 (cr7) to the result.
Code: [Select]
bgt cr7, 0x20fb70This checks if the 'gt' flag in cr7 is set, and will branch to 0x20fb70 if that is the case.

Code: [Select]
mr.     r0,r5This moves r5 to r0. The modifier '.' can be placed at the end of quite a few instructions. It means that the result will be compared with zero and cr0 will be set with the result.

There are 8 condition register, cr0-cr7. Instructions that begin with 'cmp' typically let you set any one of them.

For more info on PowerPC conditional stuff, check out https://www.ibm.com/developerworks/library/l-powasm3/index.html

Offline powermax

  • Enthusiast Member (25+ Posts)
  • ***
  • Posts: 80
  • Hobbyist programmer
Re: G5 qemu attempts.
« Reply #85 on: October 16, 2018, 02:05:38 PM »
Code: [Select]
1: x/i $pc
=> 0x20fb58: bgt     cr7,0x20fb70

conditional branch, but I don't understand what is being compared to what, or what is being done?

If what is greater than?

Yes, these cryptic PowerPC conditions... It works similar to x86 architecture: comparison instructions provide flags and branches (jumps in Intel's jargon) consume them. The only difference is that x86 has only one flags register but PowerPC has 8 labeled cr0...cr7 (strictly speaking, PowerPC has ONE condition register with 8 fields but, for simplicity, let's assume it has 8 condition registers).

PowerPC instructions usually looks like that: OPCODE  DST, OP1, OP2. The first operand is usually the destination, i.e. it receives the result.

Code: [Select]
cmplwi cr7, r5, 0x20
is read as "compare unsigned value in $r5 with 32 and set eq, lt and gt flags of the condition register CR7 accordingly". The corresponding branch instruction bgt cr7,0x20fb70 does examine the specified condition in CR7 and takes one of the two actions: if the condition is true, it jumps to the destination address 0x20fb70, otherwise - the next instruction right after the branch will be executed.

In our precise example, the comparison will update three flags simultaneously but the branch will only consume the single condition: gt (greater than). So the final comparison and its corresponding branch can be collapsed to the following pseudo-C code:

Code: [Select]
if (r5 > 0x20) goto 0x20fb70

Offline powermax

  • Enthusiast Member (25+ Posts)
  • ***
  • Posts: 80
  • Hobbyist programmer
Re: G5 qemu attempts.
« Reply #86 on: October 16, 2018, 02:12:28 PM »
There are 8 condition register, cr0-cr7. Instructions that begin with 'cmp' typically let you set any one of them.

Thank you, Daniel, for your great explanation. It looks like we got our answers crossed.

PowerPC can also omit the destination condition register: cmpwi r3, 0
In that case, CR0 is always assumed. Motorola docs call this "simplified mnemonics"...

Offline darthnVader

  • Platinum Member (500+ Posts)
  • *****
  • Posts: 520
  • New Member
Re: G5 qemu attempts.
« Reply #87 on: October 16, 2018, 02:56:16 PM »
Code: [Select]
cmplwi  cr7,r5,32This compares r5 to 32 and sets condition register 7 (cr7) to the result.

So it's either 32 true or false? <>=?

So cr7 could have three values  < > or = to?

Quote
Code: [Select]
bgt cr7, 0x20fb70This checks if the 'gt' flag in cr7 is set, and will branch to 0x20fb70 if that is the case.

Still don't understand.

Quote
Code: [Select]
mr.     r0,r5This moves r5 to r0. The modifier '.' can be placed at the end of quite a few instructions. It means that the result will be compared with zero and cr0 will be set with the result.

You mean the value in r5 is copied to r0?

What's a modifier?

« Last Edit: October 16, 2018, 03:23:25 PM by darthnVader »

Offline Daniel

  • Gold Member (200+ Posts)
  • *****
  • Posts: 269
  • Programmer, Hacker, Thinker
Re: G5 qemu attempts.
« Reply #88 on: October 16, 2018, 03:27:19 PM »
Sorry. I guess my explanation only makes sense if you already understand it.

Each condition field has 4 bit flags: lt, gt, eq, so. A compare instruction will assign values to all four of those flags for the condition field specified. This provides enough information to allow ==, !=, >, <, >=, <=...etc. The 'bgt' instruction only looks at the gt flag of the specified field and ignores the rest.

Here's an example:
Code: [Select]
cmplwi cr6,r1,4
blt cr6,some_address
beq cr6,another_address
bgt cr6, yet_another_address
cr6 will be set with the results of the comparison. The four bit flags will indicate the relationship between the 2 numbers compared. The code will end up at 'some_address', 'another_address', or 'yet_another_address' depending on whether r1 is <, ==, or > 4.

Yes, the 'mr. r0, r5' copies r5 to r0. r0 will likely not actually be used. The main purpose is to do a quick compare with zero. I call it a modifier because it is a controllable feature of most instructions. 'mr.' is a 'mr' instruction that also compares the destination with zero. 'add.', 'rlwinm.', and 'xor.' have have this same relation to 'add', 'rlwinm', and 'xor'.

Offline darthnVader

  • Platinum Member (500+ Posts)
  • *****
  • Posts: 520
  • New Member
Re: G5 qemu attempts.
« Reply #89 on: October 16, 2018, 04:31:36 PM »
Sorry. I guess my explanation only makes sense if you already understand it.

Each condition field has 4 bit flags: lt, gt, eq, so. A compare instruction will assign values to all four of those flags for the condition field specified. This provides enough information to allow ==, !=, >, <, >=, <=...etc. The 'bgt' instruction only looks at the gt flag of the specified field and ignores the rest.

Here's an example:
Code: [Select]
cmplwi cr6,r1,4
blt cr6,some_address
beq cr6,another_address
bgt cr6, yet_another_address
cr6 will be set with the results of the comparison. The four bit flags will indicate the relationship between the 2 numbers compared. The code will end up at 'some_address', 'another_address', or 'yet_another_address' depending on whether r1 is <, ==, or > 4.

Yes, the 'mr. r0, r5' copies r5 to r0. r0 will likely not actually be used. The main purpose is to do a quick compare with zero. I call it a modifier because it is a controllable feature of most instructions. 'mr.' is a 'mr' instruction that also compares the destination with zero. 'add.', 'rlwinm.', and 'xor.' have have this same relation to 'add', 'rlwinm', and 'xor'.

Still struggling to understand the first part:

cmplwi cr6,r1,4

cr6 is set to what if the value of r1 is equal to 4?


Offline powermax

  • Enthusiast Member (25+ Posts)
  • ***
  • Posts: 80
  • Hobbyist programmer
Re: G5 qemu attempts.
« Reply #90 on: October 16, 2018, 04:35:03 PM »
Still struggling to understand the first part:

cmplwi cr6,r1,4

cr6 is set to what if the value of r1 is equal to 4?

Code: [Select]
cr6.eq = 1 if r1 == 4
cr6.lt = 1 if r1 < 4
cr6.gt = 1 if r1 > 4

Offline darthnVader

  • Platinum Member (500+ Posts)
  • *****
  • Posts: 520
  • New Member
Re: G5 qemu attempts.
« Reply #91 on: October 16, 2018, 04:45:30 PM »
Still struggling to understand the first part:

cmplwi cr6,r1,4

cr6 is set to what if the value of r1 is equal to 4?

Code: [Select]
cr6.eq = 1 if r1 == 4
cr6.lt = 1 if r1 < 4
cr6.gt = 1 if r1 > 4

ok, I understand there are 8 condition registers cr0-cr7, but I don't understand cr6.??

If r1 = 4

cr6.eq =1 (true)
cr6.lt = 0? (false)
cr6.gt = 0? (false)




Offline powermax

  • Enthusiast Member (25+ Posts)
  • ***
  • Posts: 80
  • Hobbyist programmer
Re: G5 qemu attempts.
« Reply #92 on: October 16, 2018, 04:51:27 PM »
ok, I understand there are 8 condition registers cr0-cr7, but I don't understand cr6.??

If r1 = 4

cr6.eq =1 (true)
cr6.lt = 0? (false)
cr6.gt = 0? (false)

Yes.

Offline darthnVader

  • Platinum Member (500+ Posts)
  • *****
  • Posts: 520
  • New Member
Re: G5 qemu attempts.
« Reply #93 on: October 16, 2018, 04:53:27 PM »
ok, I understand there are 8 condition registers cr0-cr7, but I don't understand cr6.??

If r1 = 4

cr6.eq =1 (true)
cr6.lt = 0? (false)
cr6.gt = 0? (false)





Yes.

The condition registers are a 3 bit register, or they have three one bit registers?

Offline darthnVader

  • Platinum Member (500+ Posts)
  • *****
  • Posts: 520
  • New Member
Re: G5 qemu attempts.
« Reply #94 on: October 16, 2018, 05:11:49 PM »
Sorry. I guess my explanation only makes sense if you already understand it.

Each condition field has 4 bit flags: lt, gt, eq, so. A compare instruction will assign values to all four of those flags for the condition field specified. This provides enough information to allow ==, !=, >, <, >=, <=...etc. The 'bgt' instruction only looks at the gt flag of the specified field and ignores the rest.

Here's an example:
Code: [Select]
cmplwi cr6,r1,4
blt cr6,some_address
beq cr6,another_address
bgt cr6, yet_another_address
cr6 will be set with the results of the comparison. The four bit flags will indicate the relationship between the 2 numbers compared. The code will end up at 'some_address', 'another_address', or 'yet_another_address' depending on whether r1 is <, ==, or > 4.

Yes, the 'mr. r0, r5' copies r5 to r0. r0 will likely not actually be used. The main purpose is to do a quick compare with zero. I call it a modifier because it is a controllable feature of most instructions. 'mr.' is a 'mr' instruction that also compares the destination with zero. 'add.', 'rlwinm.', and 'xor.' have have this same relation to 'add', 'rlwinm', and 'xor'.

Code: [Select]
1: x/i $pc
=> 0x20fb4c: cmplwi  cr7,r5,32
(gdb) stepi
0x000000000020fb50 in ?? ()
1: x/i $pc
=> 0x20fb50: cmplw   cr6,r4,r3
(gdb) stepi
0x000000000020fb54 in ?? ()
1: x/i $pc
=> 0x20fb54: mr.     r0,r5
(gdb) stepi
0x000000000020fb58 in ?? ()
1: x/i $pc
=> 0x20fb58: bgt     cr7,0x20fb70

If the value of r5 is greater than 32 cr7.gt = 1 then brach to the address 0x20fb70?


Offline Daniel

  • Gold Member (200+ Posts)
  • *****
  • Posts: 269
  • Programmer, Hacker, Thinker
Re: G5 qemu attempts.
« Reply #95 on: October 16, 2018, 05:19:11 PM »
Yes. Branch if r5 > 32.

The condition register is a 32-bit register split up into 8 sections (cr0-cr7) of 4 bits each (I really have no idea what the 'so' bits are used for, but 'lt', 'eq', and 'gt' are pretty clear). All the mnemonics like blt are essentially macros that expand into a more general branch instruction that takes a bit index into the cr as a whole. The compare instructions are still required to operate on cr0-cr7.


Offline darthnVader

  • Platinum Member (500+ Posts)
  • *****
  • Posts: 520
  • New Member
Re: G5 qemu attempts.
« Reply #96 on: October 16, 2018, 05:25:46 PM »
Yes. Branch if r5 > 32.

The condition register is a 32-bit register split up into 8 sections (cr0-cr7) of 4 bits each (I really have no idea what the 'so' bits are used for, but 'lt', 'eq', and 'gt' are pretty clear). All the mnemonics like blt are essentially macros that expand into a more general branch instruction that takes a bit index into the cr as a whole. The compare instructions are still required to operate on cr0-cr7.

Ok, I'm starting to understand, let's see if I can apply it to what I need to do.

Code: [Select]
(gdb) stepi (execute bgt cr7, 0x20FB70 --> conditional branch, mark it with "+" if it jumps to 0x20fb70, otherwise mark it with "-")
(gdb) stepi (beq cr7, 0x20FBC4 --> another cond branch, proceed as above)
(gdb) stepi (blt cr6, 0x20FC74 --> yet another cond branch, proceed as above)

How do I check if cr7 was greater than?

Do I read the entire 32 bit cr or is there some other way of knowing if it jumped to 0x20fb70?

Offline powermax

  • Enthusiast Member (25+ Posts)
  • ***
  • Posts: 80
  • Hobbyist programmer
Re: G5 qemu attempts.
« Reply #97 on: October 16, 2018, 05:30:34 PM »
I really have no idea what the 'so' bits are used for

SO - summary overflow. Used for implementing really big numbers...

Offline Daniel

  • Gold Member (200+ Posts)
  • *****
  • Posts: 269
  • Programmer, Hacker, Thinker
Re: G5 qemu attempts.
« Reply #98 on: October 16, 2018, 05:34:04 PM »
Yes. Branch if r5 > 32.

The condition register is a 32-bit register split up into 8 sections (cr0-cr7) of 4 bits each (I really have no idea what the 'so' bits are used for, but 'lt', 'eq', and 'gt' are pretty clear). All the mnemonics like blt are essentially macros that expand into a more general branch instruction that takes a bit index into the cr as a whole. The compare instructions are still required to operate on cr0-cr7.

Ok, I'm starting to understand, let's see if I can apply it to what I need to do.

Code: [Select]
(gdb) stepi (execute bgt cr7, 0x20FB70 --> conditional branch, mark it with "+" if it jumps to 0x20fb70, otherwise mark it with "-")
(gdb) stepi (beq cr7, 0x20FBC4 --> another cond branch, proceed as above)
(gdb) stepi (blt cr6, 0x20FC74 --> yet another cond branch, proceed as above)

How do I check if cr7 was greater than?

Do I read the entire 32 bit cr or is there some other way of knowing if it jumped to 0x20fb70?
An easy way to check it is to see what address gdb reported the program counter to be at.
Code: [Select]
0x000000000020fb58 in ?? ()
1: x/i $pc
=> 0x20fb58: bgt     cr7,0x20fb70
(gdb) stepi
0x000000000020fb70 in ?? ()
1: x/i $pc
=> 0x20fb70: beqlr   cr6
It appears to have made the jump. The PC is 0x000000000020fb70 in the instruction immediately following the branch. Also, there might be some register dump command like '%cr' or something. I am not familiar with gdb, so I am not sure.

Offline powermax

  • Enthusiast Member (25+ Posts)
  • ***
  • Posts: 80
  • Hobbyist programmer
Re: G5 qemu attempts.
« Reply #99 on: October 16, 2018, 05:34:59 PM »
How do I check if cr7 was greater than?

Do I read the entire 32 bit cr or is there some other way of knowing if it jumped to 0x20fb70?

Don't bother with them at all! We don't need to decompile this function - that's already done. Just record which code instructions are executed and concentrate yourself on everything that changes general purpose registers (r0...r31).

Offline darthnVader

  • Platinum Member (500+ Posts)
  • *****
  • Posts: 520
  • New Member
Re: G5 qemu attempts.
« Reply #100 on: October 16, 2018, 05:45:07 PM »
How do I check if cr7 was greater than?

Do I read the entire 32 bit cr or is there some other way of knowing if it jumped to 0x20fb70?

Don't bother with them at all! We don't need to decompile this function - that's already done. Just record which code instructions are executed and concentrate yourself on everything that changes general purpose registers (r0...r31).

Is this useful, or are you asking for something else?

Code: [Select]
(gdb) stepi
0x000000000020fba4 in ?? ()
1: x/i $pc
=> 0x20fba4: add     r4,r4,r5
(gdb) p/x $r4
$4 = 0x3fee5048
(gdb) stepi
0x000000000020fba8 in ?? ()
1: x/i $pc
=> 0x20fba8: andi.   r0,r4,31
(gdb) p/x $r4
$5 = 0x3fee5100
(gdb) stepi
0x000000000020fbac in ?? ()
1: x/i $pc
=> 0x20fbac: bnel    0x20fc08
(gdb) stepi
0x000000000020fbb0 in ?? ()
1: x/i $pc
=> 0x20fbb0: bl      0x20fd08
(gdb) stepi
0x000000000020fd08 in ?? ()
1: x/i $pc
=> 0x20fd08: rlwinm. r11,r5,27,5,31
(gdb) p/x $r5
$6 = 0xb8
(gdb) stepi
0x000000000020fd0c in ?? ()
1: x/i $pc
=> 0x20fd0c: mtctr   r11
(gdb) stepi
0x000000000020fd10 in ?? ()
1: x/i $pc
=> 0x20fd10: beqlr   
(gdb) stepi
0x000000000020fd14 in ?? ()
1: x/i $pc
=> 0x20fd14: andi.   r0,r3,7
(gdb) p/x $r3
$7 = 0x3fee50f0
(gdb) stepi
0x000000000020fd18 in ?? ()
1: x/i $pc
=> 0x20fd18: beq     0x20fd78
(gdb) stepi
0x000000000020fd78 in ?? ()
1: x/i $pc
=> 0x20fd78: lfdu    f0,-32(r3)
(gdb) stepi
0x000000000020fd7c in ?? ()
1: x/i $pc
=> 0x20fd7c: addi    r4,r4,-32
(gdb) p/x $r4
$8 = 0x3fee5100
(gdb) stepi
0x000000000020fd80 in ?? ()
1: x/i $pc
=> 0x20fd80: lfd     f1,8(r3)
(gdb) stepi
0x000000000020fd84 in ?? ()
1: x/i $pc
=> 0x20fd84: lfd     f2,16(r3)
(gdb) stepi
0x000000000020fd88 in ?? ()
1: x/i $pc
=> 0x20fd88: lfd     f3,24(r3)
(gdb) stepi
0x000000000020fd8c in ?? ()
1: x/i $pc
=> 0x20fd8c: dcbz    0,r4
(gdb) stepi
0x000000000020fd90 in ?? ()
1: x/i $pc
=> 0x20fd90: stfd    f0,0(r4)
(gdb) stepi
0x000000000020fd94 in ?? ()
1: x/i $pc
=> 0x20fd94: stfd    f1,8(r4)
(gdb) stepi
0x000000000020fd98 in ?? ()
1: x/i $pc
=> 0x20fd98: stfd    f2,16(r4)
(gdb) stepi
0x000000000020fd9c in ?? ()
1: x/i $pc
=> 0x20fd9c: stfd    f3,24(r4)
(gdb) stepi
0x000000000020fda0 in ?? ()
1: x/i $pc
=> 0x20fda0: bdnz    0x20fd78
(gdb) stepi
0x000000000020fd78 in ?? ()
1: x/i $pc
=> 0x20fd78: lfdu    f0,-32(r3)
(gdb) stepi
0x000000000020fd7c in ?? ()
1: x/i $pc
=> 0x20fd7c: addi    r4,r4,-32
(gdb) p/x $r4
$9 = 0x3fee50e0
(gdb) stepi
0x000000000020fd80 in ?? ()
1: x/i $pc
=> 0x20fd80: lfd     f1,8(r3)
(gdb) stepi
0x000000000020fd84 in ?? ()
1: x/i $pc
=> 0x20fd84: lfd     f2,16(r3)
(gdb) stepi
0x000000000020fd88 in ?? ()
1: x/i $pc
=> 0x20fd88: lfd     f3,24(r3)
(gdb) stepi
0x000000000020fd8c in ?? ()
1: x/i $pc
=> 0x20fd8c: dcbz    0,r4
(gdb) stepi
0x000000000020fd90 in ?? ()
1: x/i $pc
=> 0x20fd90: stfd    f0,0(r4)
(gdb) stepi
0x000000000020fd94 in ?? ()
1: x/i $pc
=> 0x20fd94: stfd    f1,8(r4)
(gdb) stepi
0x000000000020fd98 in ?? ()
1: x/i $pc
=> 0x20fd98: stfd    f2,16(r4)
(gdb) stepi
0x000000000020fd9c in ?? ()
1: x/i $pc
=> 0x20fd9c: stfd    f3,24(r4)
(gdb) stepi
0x000000000020fda0 in ?? ()
1: x/i $pc
=> 0x20fda0: bdnz    0x20fd78
(gdb) stepi
0x000000000020fd78 in ?? ()
1: x/i $pc
=> 0x20fd78: lfdu    f0,-32(r3)
(gdb) stepi
0x000000000020fd7c in ?? ()
1: x/i $pc
=> 0x20fd7c: addi    r4,r4,-32
(gdb) p/x $r4
$10 = 0x3fee50c0
(gdb) stepi
0x000000000020fd80 in ?? ()
1: x/i $pc
=> 0x20fd80: lfd     f1,8(r3)
(gdb) stepi
0x000000000020fd84 in ?? ()
1: x/i $pc
=> 0x20fd84: lfd     f2,16(r3)
(gdb) stepi
0x000000000020fd88 in ?? ()
1: x/i $pc
=> 0x20fd88: lfd     f3,24(r3)
(gdb) stepi
0x000000000020fd8c in ?? ()
1: x/i $pc
=> 0x20fd8c: dcbz    0,r4
(gdb) stepi
0x000000000020fd90 in ?? ()
1: x/i $pc
=> 0x20fd90: stfd    f0,0(r4)
(gdb) stepi
0x000000000020fd94 in ?? ()
1: x/i $pc
=> 0x20fd94: stfd    f1,8(r4)
(gdb) stepi
0x000000000020fd98 in ?? ()
1: x/i $pc
=> 0x20fd98: stfd    f2,16(r4)
(gdb) stepi
0x000000000020fd9c in ?? ()
1: x/i $pc
=> 0x20fd9c: stfd    f3,24(r4)
(gdb) stepi
0x000000000020fda0 in ?? ()
1: x/i $pc
=> 0x20fda0: bdnz    0x20fd78
(gdb) stepi
0x000000000020fd78 in ?? ()
1: x/i $pc
=> 0x20fd78: lfdu    f0,-32(r3)
(gdb) stepi
0x000000000020fd7c in ?? ()
1: x/i $pc
=> 0x20fd7c: addi    r4,r4,-32
(gdb) p/x $r4
$11 = 0x3fee50a0
(gdb)

Offline powermax

  • Enthusiast Member (25+ Posts)
  • ***
  • Posts: 80
  • Hobbyist programmer
Re: G5 qemu attempts.
« Reply #101 on: October 16, 2018, 07:00:21 PM »
Code: [Select]
1: x/i $pc
=> 0x20fd08: rlwinm. r11,r5,27,5,31
(gdb) p/x $r5
$6 = 0xb8

Please pay attention to the fact that 1: x/i $pc always shows NEXT instruction. p/x $r5 will print out the value of r5 BEFORE 0x20fd08 in this case. You need to do stepi first to trace past 0x20fd08, then p/x $r11 to track the destination of rlwinm.

It's getting interesting here. I'd like to request the value of $r11 at 0x20fd10 on both G4 and G5.

Is it doable?

Offline darthnVader

  • Platinum Member (500+ Posts)
  • *****
  • Posts: 520
  • New Member
Re: G5 qemu attempts.
« Reply #102 on: October 16, 2018, 07:35:09 PM »
G4:

Code: [Select]
Breakpoint 1, 0x000000000020fd08 in ?? ()
(gdb) display/i $pc
1: x/i $pc
=> 0x20fd08: rlwinm. r11,r5,27,5,31
(gdb) p/x $r11
$1 = 0xd
(gdb) stepi
0x000000000020fd0c in ?? ()
1: x/i $pc
=> 0x20fd0c: mtctr   r11
(gdb) p/x $r11
$2 = 0x5
(gdb)

970:

Code: [Select]
Breakpoint 1, 0x000000000020fd08 in ?? ()
2: x/i $pc
=> 0x20fd08: rlwinm. r11,r5,27,5,31
1: x/i $pc
=> 0x20fd08: rlwinm. r11,r5,27,5,31
(gdb) display/i $pc
3: x/i $pc
=> 0x20fd08: rlwinm. r11,r5,27,5,31
(gdb) p/x $r11
$3 = 0xd
(gdb) stepi
0x000000000020fd0c in ?? ()
3: x/i $pc
=> 0x20fd0c: mtctr   r11
2: x/i $pc
=> 0x20fd0c: mtctr   r11
1: x/i $pc
=> 0x20fd0c: mtctr   r11
(gdb) p/x $r11
$4 = 0x5
(gdb)

Offline powermax

  • Enthusiast Member (25+ Posts)
  • ***
  • Posts: 80
  • Hobbyist programmer
Re: G5 qemu attempts.
« Reply #103 on: October 16, 2018, 11:21:42 PM »
970:

Code: [Select]
Breakpoint 1, 0x000000000020fd08 in ?? ()
2: x/i $pc
=> 0x20fd08: rlwinm. r11,r5,27,5,31
1: x/i $pc
=> 0x20fd08: rlwinm. r11,r5,27,5,31
(gdb) display/i $pc
3: x/i $pc
=> 0x20fd08: rlwinm. r11,r5,27,5,31
(gdb) p/x $r11
$3 = 0xd
(gdb) stepi
0x000000000020fd0c in ?? ()
3: x/i $pc
=> 0x20fd0c: mtctr   r11
2: x/i $pc
=> 0x20fd0c: mtctr   r11
1: x/i $pc
=> 0x20fd0c: mtctr   r11
(gdb) p/x $r11
$4 = 0x5
(gdb)

Looks correct. What do $r3 and $r4 contain at the same location on 970?

Offline darthnVader

  • Platinum Member (500+ Posts)
  • *****
  • Posts: 520
  • New Member
Re: G5 qemu attempts.
« Reply #104 on: October 17, 2018, 06:07:16 AM »
Code: [Select]
(gdb) p/x $r3
$5 = 0x3fee50f0
(gdb) p/x $r4
$6 = 0x3fee5100
(gdb)

Offline powermax

  • Enthusiast Member (25+ Posts)
  • ***
  • Posts: 80
  • Hobbyist programmer
Re: G5 qemu attempts.
« Reply #105 on: October 17, 2018, 08:24:44 AM »
Code: [Select]
(gdb) p/x $r3
$5 = 0x3fee50f0
(gdb) p/x $r4
$6 = 0x3fee5100
(gdb)

Both $r3 and $r4 contain correct values.

We narrowed down the search to a single loop. Below its full asm:

Code: [Select]
0x20FD78     lfdu    fp0, -0x20(r3)
0x20FD7C     addi    r4, r4, -0x20
0x20FD80     lfd     fp1, 8(r3)
0x20FD84     lfd     fp2, 0x10(r3)
0x20FD88     lfd     fp3, 0x18(r3)
0x20FD8C     dcbz    r0, r4
0x20FD90     stfd    fp0, 0(r4)
0x20FD94     stfd    fp1, 8(r4)
0x20FD98     stfd    fp2, 0x10(r4)
0x20FD9C     stfd    fp3, 0x18(r4)
0x20FDA0     bdnz    0x20FD78
0x20FDA4     blr

This loop driven by the bdnz instruction will be executed 5 times. Each iteration will copy 32 bytes from $r3 to $r4, then both pointers will be decremented by 32. Don't be confused by the floating-point instructions lfd/stfd used there - they perfom no FP calculations, they are used there because they are capable of reading/writng 8 bytes at once.

dcbz clears all bytes of the block pointed by $r4 to zero. It should ensure that everything written to this block before will be wiped away because we're going to write new values.

A cache block on 32-bit PPC is 32 bytes long. On 970, it's 128 bytes long. My bet is that G5's dcbz zeros more bytes than the corresponding dcbz on 32bit CPU. That could explain why everything at the address 0x3fee5000 will be wiped away.

The question is how to catch this bug. I assume that the memory corruption happens on the cache block boundary, i.e. when the address in $r4 < 0x3fee5080. This condition will be reached after the 5th loop iteration (0x3fee5100 - 32 bytes * 5 = 0x3fee5060).

To test that, I'd set a breakpoint at 0x20FD90 (right after dcbz) and monitor memory changes. Expected values of $r4 are:

1st iteration: 0x3fee50e0
2nd iteration: 0x3fee50c0
3rd iteration: 0x3fee50a0
4th iteration: 0x3fee5080
---- it's the cache block boundary ----
5th iteration: 0x3fee5060
---- end of loop ----

When our breakpoint is reached for the 5th time, r4 should contain 0x3fee5060 and dcbz is expected to zero the whole cache block 0x3fee5000...0x3fee5080(!)

You can verify that by dumping the memory block at 0x3fee5000 in the 5th iteration.

Below the same as GDB debugging program:

Code: [Select]
(gdb) break *0x203ce8
(gdb) cont
(gdb) display/i $pc
(gdb) break *0x20FD90
(gdb) cont
... we should stop after the 1st dcbz here
(gdb) p/x $r4 (should be 0x3fee50e0)
(gdb) x/8xw 0x3fee5000 (should contain non-zero values)
(gdb) cont (execute 2nd dcbz)
(gdb) cont (execute 3rd dcbz)
(gdb) cont (execute 4th dcbz)
(gdb) p/x $r4 (should be 0x3fee5080)
(gdb) x/8xw 0x3fee5000 (should contain non-zero values)
(gdb) cont (execute 5th dcbz)
(gdb) p/x $r4 (should be 0x3fee5060)
(gdb) x/8xw 0x3fee5000 (will supposedly contain all zeroes)

Could you verify that?

Sorry for the long post. I hope you can follow me...

Offline darthnVader

  • Platinum Member (500+ Posts)
  • *****
  • Posts: 520
  • New Member
Re: G5 qemu attempts.
« Reply #106 on: October 17, 2018, 09:10:46 AM »
Looks like everything you said is correct:

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
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: 0x00000000 0x00000000 0x00000000 0x00000000
0x3fee5010: 0x00000000 0x00000000 0x00000000 0x00000000
(gdb)


Offline darthnVader

  • Platinum Member (500+ Posts)
  • *****
  • Posts: 520
  • New Member
Re: G5 qemu attempts.
« Reply #107 on: October 17, 2018, 09:16:32 AM »
Here is what it looks like for the G4 CPU:

Code: [Select]
(gdb) target remote localhost:1234
Remote debugging using localhost:1234
0x00000000fff00100 in ?? ()
(gdb) cont
Continuing.
Hardware watchpoint 3: *0x3fee5000

Old value = 0
New value = 1073741824
0x000000000020271c in ?? ()
(gdb) cont
Continuing.

Breakpoint 1, 0x00000000002052f0 in ?? ()
(gdb) cont
Continuing.

Breakpoint 2, 0x0000000000205a24 in ?? ()
(gdb) cont
Continuing.
Hardware watchpoint 3: *0x3fee5000

Old value = 1073741824
New value = 1073725440
0x0000000000f105a0 in ?? ()
(gdb) cont
Continuing.

Are we jumping off into nowhere on the G5?

That's why I asked if we were jumping off into nowhere the New value should be = 1073725440 not zero.

Offline powermax

  • Enthusiast Member (25+ Posts)
  • ***
  • Posts: 80
  • Hobbyist programmer
Re: G5 qemu attempts.
« Reply #108 on: October 17, 2018, 09:21:04 AM »
Looks like everything you said is correct:

Yes, my expectations have been confirmed. The bug is also in the processor-specific bcopy() code caused by the incompatibilities between the dcbz implementations in 32bit/64bit PowerPC CPUs.

Could you verify the same piece of code on G4, just for the sake of completeness?

Offline powermax

  • Enthusiast Member (25+ Posts)
  • ***
  • Posts: 80
  • Hobbyist programmer
Re: G5 qemu attempts.
« Reply #109 on: October 17, 2018, 09:28:00 AM »
Code: [Select]
Old value = 1073741824
New value = 1073725440
0x0000000000f105a0 in ?? ()
(gdb) cont
Continuing.

Are we jumping off into nowhere on the G5?

That's why I asked if we were jumping off into nowhere the New value should be = 1073725440 not zero.

Well, the code should jump to 0xf105a0, not to 1073725440 (0x3fffc000). The latter is the amount of physical memory after exclusion of the ROM-in-RAM portion.

But on the 970, we'll get here but crash due to an exception instead...

Offline darthnVader

  • Platinum Member (500+ Posts)
  • *****
  • Posts: 520
  • New Member
Re: G5 qemu attempts.
« Reply #110 on: October 17, 2018, 09:39:09 AM »
Looks like everything you said is correct:

Yes, my expectations have been confirmed. The bug is also in the processor-specific bcopy() code caused by the incompatibilities between the dcbz implementations in 32bit/64bit PowerPC CPUs.

Could you verify the same piece of code on G4, just for the sake of completeness?

G4, everything looks the same but the last bit isn't all zero, so you're on the right track:

Code: [Select]
(gdb) target remote localhost:1234
Remote debugging using localhost:1234
0x00000000fff00100 in ?? ()
(gdb) cont
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 (25+ Posts)
  • ***
  • Posts: 80
  • Hobbyist programmer
Re: G5 qemu attempts.
« Reply #111 on: October 17, 2018, 12:50:23 PM »
G4, everything looks the same but the last bit isn't all zero, so you're on the right track...

Yes.

Let's summarize what we have found out in this thread:

  • An attempt to boot Mac OS 9.2.1 on a Mac99 machine with the unsupported 970 (G5) CPU in QEMU fails early in the Trampoline. A memory overlapping error is reported.
  • We found out that the real cause for the memory overlapping error is that the content of the NKSystemInfo structure suddenly becomes filled with zeros so the memory relocation cannot operate correctly.
  • After a long debugging session discussing a lot of low-level details, the failing code could be located and analyzed. It's a part of the bcopy() function. Its purpose is to quickly move data from one memory location to another.

    bcopy is written in assembly. It utilizes the low-level dcbz instruction that clears cache blocks to zero. Unfortunately, dcbz works differently on 32bit and 64bit implementations: due to bigger cache block size in PPC64, some important data in memory becomes corrupted.

    It's possible to fix this problem by replacing legacy Trampoline's bcopy with Darwin's implementation that supports latest CPUs, see https://opensource.apple.com/source/Libc/Libc-262/ppc/gen/bcopy.s.auto.html

For the purpose of bug localization, a debugging toolchain based on QEMU+GDB has been successfully set up. Kudos to darthnVader!

This toolchain has been proven indispensable in spotting problems with low-level OS code when running on unsupported hardware. Although the Trampoline offers a simple debugging mode that displays helpful debugging messages in the OpenFirmware console, it's often not enough to understand what exactly goes wrong without invoking a low-level debugger.

Unfortunately, such a flexible debugging instrumentation requires a running OS and, consequently, isn't available during OS boot in real PPC hardware. Fortunately, with the above mentioned toolchain, it's easy to overcome this limitation. QEMU+GDB will therefore remain our only debugging option until we'll get the lowest OS level up and running.

Offline darthnVader

  • Platinum Member (500+ Posts)
  • *****
  • Posts: 520
  • New Member
Re: G5 qemu attempts.
« Reply #112 on: October 17, 2018, 03:37:57 PM »


    It's possible to fix this problem by replacing legacy Trampoline's bcopy with Darwin's implementation that supports latest CPUs, see https://opensource.apple.com/source/Libc/Libc-262/ppc/gen/bcopy.s.auto.html
    [/li]
    [/list]



    Interesting find, do you think this version of bcopy is used in bootx?

    Somewhere I have the code for BootX I used to build a version that sends some debug info to the screen, that helped me with finding a problem with KVM on a Powerbook booting OS X in Qemu. I'll have to see if I can find bcopy in the BootX sources.

    Offline powermax

    • Enthusiast Member (25+ Posts)
    • ***
    • Posts: 80
    • Hobbyist programmer
    Re: G5 qemu attempts.
    « Reply #113 on: October 17, 2018, 03:46:20 PM »
    Interesting find, do you think this version of bcopy is used in bootx?

    Somewhere I have the code for BootX I used to build a version that sends some debug info to the screen, that helped me with finding a problem with KVM on a Powerbook booting OS X in Qemu. I'll have to see if I can find bcopy in the BootX sources.

    To my knowledge, BootX uses a CPU-independent implementation of memcpy written in C. bcopy() is just a wrapper for memcpy that changes the order of parameters (see bootx/libclite.subproj/mem.c):

    Code: [Select]
    void bcopy(const void *src, void *dst, size_t len)
    {
        memcpy(dst, src, len);
    }

    Offline Daniel

    • Gold Member (200+ Posts)
    • *****
    • Posts: 269
    • Programmer, Hacker, Thinker
    Re: G5 qemu attempts.
    « Reply #114 on: October 17, 2018, 04:48:32 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.

    I don't know if the code section is read-only by default, but you could undo that protection with a simple mmu call.

    Offline ELN

    • Gold Member (200+ Posts)
    • *****
    • Posts: 291
    • new to the forums
    Re: G5 qemu attempts.
    « Reply #115 on: October 17, 2018, 04:50:02 PM »
    Time for a binary patch maybe? :D

    Offline powermax

    • Enthusiast Member (25+ Posts)
    • ***
    • Posts: 80
    • Hobbyist programmer
    Re: G5 qemu attempts.
    « Reply #116 on: October 18, 2018, 03:37:01 AM »
    Time for a binary patch maybe? :D

    bcopy() must be definitely patched in order to run on G5. The question is what code should replace it?

    Currently, we have two options:

    • Asm-bcopy that supports latest G4/G5 CPUs.
      Pros: it's blazing fast because it uses various low-level tricks and optimizations
      Cons: processor-dependent code, requires an assembler, several corner cases, hard to debug, need intensive testing
    • generic C implementation consisting of a simply loop a lá memcpy used in BootX
      Pros: easy to write and test, processor-independent, no machine code required
      Cons: probably not very fast but it's hard to tell without speed measures

    Each optimization must be well balanced. The Trampoline calls bcopy() very often for small memory chunks (< 256 bytes). In this case, I doubt that users will be able to notice any speed difference between the generic and highly optimized versions.

    When copying large blocks (4MB, 290KB etc.) there can be a noticeable difference but the question is how much? Is it worth it spending hours and hours writing and testing highly optimized machine code in order to gain a tiny speed improvement?

    Offline darthnVader

    • Platinum Member (500+ Posts)
    • *****
    • Posts: 520
    • New Member
    Re: G5 qemu attempts.
    « Reply #117 on: October 18, 2018, 04:38:09 AM »
    Time for a binary patch maybe? :D

    bcopy() must be definitely patched in order to run on G5. The question is what code should replace it?

    Currently, we have two options:

    • Asm-bcopy that supports latest G4/G5 CPUs.
      Pros: it's blazing fast because it uses various low-level tricks and optimizations
      Cons: processor-dependent code, requires an assembler, several corner cases, hard to debug, need intensive testing
    • generic C implementation consisting of a simply loop a lá memcpy used in BootX
      Pros: easy to write and test, processor-independent, no machine code required
      Cons: probably not very fast but it's hard to tell without speed measures

    Each optimization must be well balanced. The Trampoline calls bcopy() very often for small memory chunks (< 256 bytes). In this case, I doubt that users will be able to notice any speed difference between the generic and highly optimized versions.

    When copying large blocks (4MB, 290KB etc.) there can be a noticeable difference but the question is how much? Is it worth it spending hours and hours writing and testing highly optimized machine code in order to gain a tiny speed improvement?

    I don't really think speed is that much of an issue, likely this code will only ever need to run on a G5 or an emulated G5. Most people have fast x86 cpu's, as they are fairly cheap, and the slowest G5 is 1.6Ghz.

    There is the edge case that someone will run the code on 64bit ARM, emulating a G5, so one would be a little better there. I just highly doubt running Qemu on a phone or tablet to emulate a desktop OS is ever going to be that useful.

    My vote is 2.

    Offline darthnVader

    • Platinum Member (500+ Posts)
    • *****
    • Posts: 520
    • New Member
    Re: G5 qemu attempts.
    « Reply #118 on: October 18, 2018, 05:05:08 AM »
    On a side note, I wonder how hard it would be to port GDB-Server to run in Open Firmware.

    Likely not easy, tho theoretically possible.

    It maybe necessary if we ever give a go at getting the Trampoline to run on 970fx+ Powermacs.

    Also, there is a PowerPC notebook project, last I checked I think they were planing to use Coreboot as a firmware, and Coreboot supports Openbios as a payload. So if the project ever comes to fruition I'll try and get my hands on one, and maybe we can see if we can get the Trampoline to run one that too.

    Offline powermax

    • Enthusiast Member (25+ Posts)
    • ***
    • Posts: 80
    • Hobbyist programmer
    Re: G5 qemu attempts.
    « Reply #119 on: October 18, 2018, 05:12:38 AM »
    On a side note, I wonder how hard it would be to port GDB-Server to run in Open Firmware.

    I'm afraid it has to be rewritten from scratch. OF is Fourth, GDB is C requiring OS and C libraries to work...

    Also, there is a PowerPC notebook project [...]

    Never heard anything about that. Any description?

    Offline powermax

    • Enthusiast Member (25+ Posts)
    • ***
    • 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 (100+ Posts)
    • ****
    • Posts: 116
    • 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 (500+ Posts)
    • *****
    • Posts: 520
    • 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 (25+ Posts)
    • ***
    • 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 (100+ Posts)
    • ****
    • Posts: 116
    • 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 (100+ Posts)
    • ****
    • Posts: 116
    • 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 (200+ Posts)
    • *****
    • Posts: 269
    • 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 (500+ Posts)
    • *****
    • Posts: 520
    • 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 (25+ Posts)
    • ***
    • 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 (25+ Posts)
    • ***
    • 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 (500+ Posts)
    • *****
    • Posts: 520
    • 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 (25+ Posts)
    • ***
    • 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 (500+ Posts)
    • *****
    • Posts: 520
    • 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 (25+ Posts)
    • ***
    • 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 (25+ Posts)
    • ***
    • 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 (200+ Posts)
    • *****
    • Posts: 269
    • 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 (25+ Posts)
    • ***
    • 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 (500+ Posts)
    • *****
    • Posts: 520
    • 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 (25+ Posts)
    • ***
    • 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 (100+ Posts)
    • ****
    • Posts: 116
    • 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.

    Offline darthnVader

    • Platinum Member (500+ Posts)
    • *****
    • Posts: 520
    • New Member
    Re: G5 qemu attempts.
    « Reply #140 on: October 20, 2018, 05:28:52 AM »
    Am I looping?

    Code: [Select]
    (gdb) break *0x20F0A4
    Breakpoint 1 at 0x20f0a4
    (gdb) target remote localhost:1234
    Remote debugging using localhost:1234
    0x00000000fff00100 in ?? ()
    (gdb) cont
    Continuing.

    Breakpoint 1, 0x000000000020f0a4 in ?? ()
    (gdb)  display/i $pc
    1: x/i $pc
    => 0x20f0a4: lwz     r16,28(r3)
    (gdb) stepi
    0x000000000020f0a8 in ?? ()
    1: x/i $pc
    => 0x20f0a8: mtsrr0  r5
    (gdb) stepi
    0x000000000020f0ac in ?? ()
    1: x/i $pc
    => 0x20f0ac: li      r0,12288
    (gdb) stepi
    0x000000000020f0b0 in ?? ()
    1: x/i $pc
    => 0x20f0b0: mtsrr1  r0
    (gdb) stepi
    0x000000000020f0b4 in ?? ()
    1: x/i $pc
    => 0x20f0b4: rfi
    (gdb) stepi
    0x0000000000000104 in ?? ()
    1: x/i $pc
    => 0x104: lis     r1,-32768
    (gdb) stepi
    0x0000000000000108 in ?? ()
    1: x/i $pc
    => 0x108: add.    r1,r1,r1
    (gdb) stepi
    0x000000000000010c in ?? ()
    1: x/i $pc
    => 0x10c: beq     0x11c
    (gdb) stepi
    0x0000000000000110 in ?? ()
    1: x/i $pc
    => 0x110: mfmsr   r1
    (gdb) stepi
    0x0000000000000114 in ?? ()
    1: x/i $pc
    => 0x114: clrldi  r1,r1,1
    (gdb) stepi
    0x0000000000000118 in ?? ()
    1: x/i $pc
    => 0x118: mtmsrd  r1
    (gdb) stepi
    0x000000000000011c in ?? ()
    1: x/i $pc
    => 0x11c: mflr    r3
    (gdb) stepi
    0x0000000000000120 in ?? ()
    1: x/i $pc
    => 0x120: lis     r4,-15
    (gdb) stepi
    0x0000000000000124 in ?? ()
    1: x/i $pc
    => 0x124: addi    r4,r4,-27012
    (gdb) stepi
    0x0000000000000128 in ?? ()
    1: x/i $pc
    => 0x128: mtctr   r4
    (gdb) stepi
    0x000000000000012c in ?? ()
    1: x/i $pc
    => 0x12c: bctr
    (gdb) stepi
    0x00000000fff0967c in ?? ()
    1: x/i $pc
    => 0xfff0967c: stwu    r1,-16(r1)
    (gdb) stepi
    0x00000000fff09680 in ?? ()
    1: x/i $pc
    => 0xfff09680: mr      r4,r3
    (gdb) stepi
    0x00000000fff09684 in ?? ()
    1: x/i $pc
    => 0xfff09684: lis     r3,-13
    (gdb) stepi
    0x00000000fff09688 in ?? ()
    1: x/i $pc
    => 0xfff09688: mflr    r0
    (gdb) stepi
    0x00000000fff0968c in ?? ()
    1: x/i $pc
    => 0xfff0968c: addi    r3,r3,30014
    (gdb) stepi
    0x00000000fff09690 in ?? ()
    1: x/i $pc
    => 0xfff09690: stw     r0,20(r1)
    (gdb) stepi
    0x00000000fff09694 in ?? ()
    1: x/i $pc
    => 0xfff09694: bl      0xfff08c88
    (gdb) stepi
    0x00000000fff08c88 in ?? ()
    1: x/i $pc
    => 0xfff08c88: stwu    r1,-1104(r1)
    (gdb) stepi
    0x00000000fff08c8c in ?? ()
    1: x/i $pc
    => 0xfff08c8c: mflr    r0
    (gdb) stepi
    0x00000000fff08c90 in ?? ()
    1: x/i $pc
    => 0xfff08c90: stw     r9,1072(r1)
    (gdb) stepi
    0x00000000fff08c94 in ?? ()
    1: x/i $pc
    => 0xfff08c94: li      r9,1
    (gdb) stepi
    0x00000000fff08c98 in ?? ()
    1: x/i $pc
    => 0xfff08c98: stb     r9,1032(r1)
    (gdb) stepi
    0x00000000fff08c9c in ?? ()
    1: x/i $pc
    => 0xfff08c9c: li      r9,0
    (gdb) stepi
    0x00000000fff08ca0 in ?? ()
    1: x/i $pc
    => 0xfff08ca0: stmw    r27,1084(r1)
    (gdb) stepi
    0x00000000fff08ca4 in ?? ()
    1: x/i $pc
    => 0xfff08ca4: addi    r30,r1,8
    (gdb) stepi
    0x00000000fff08ca8 in ?? ()
    1: x/i $pc
    => 0xfff08ca8: li      r31,0
    (gdb) stepi
    0x00000000fff08cac in ?? ()
    1: x/i $pc
    => 0xfff08cac: stb     r9,1033(r1)
    (gdb) stepi
    0x00000000fff08cb0 in ?? ()
    1: x/i $pc
    => 0xfff08cb0: addi    r9,r1,1112
    (gdb) stepi
    0x00000000fff08cb4 in ?? ()
    1: x/i $pc
    => 0xfff08cb4: lis     r29,-4
    (gdb) stepi
    0x00000000fff08cb8 in ?? ()
    1: x/i $pc
    => 0xfff08cb8: stw     r4,1052(r1)
    (gdb) stepi
    0x00000000fff08cbc in ?? ()
    1: x/i $pc
    => 0xfff08cbc: li      r4,1024
    (gdb) stepi
    0x00000000fff08cc0 in ?? ()
    1: x/i $pc
    => 0xfff08cc0: li      r27,0
    (gdb) stepi
    0x00000000fff08cc4 in ?? ()
    1: x/i $pc
    => 0xfff08cc4: stw     r5,1056(r1)
    (gdb) stepi
    0x00000000fff08cc8 in ?? ()
    1: x/i $pc
    => 0xfff08cc8: mr      r5,r3
    (gdb) stepi
    0x00000000fff08ccc in ?? ()
    1: x/i $pc
    => 0xfff08ccc: mr      r3,r30
    (gdb) stepi
    0x00000000fff08cd0 in ?? ()
    1: x/i $pc
    => 0xfff08cd0: stw     r6,1060(r1)
    (gdb) stepi
    0x00000000fff08cd4 in ?? ()
    1: x/i $pc
    => 0xfff08cd4: addi    r6,r1,1032
    (gdb) stepi
    0x00000000fff08cd8 in ?? ()
    1: x/i $pc
    => 0xfff08cd8: stw     r9,1036(r1)
    (gdb) stepi
    0x00000000fff08cdc in ?? ()
    1: x/i $pc
    => 0xfff08cdc: addi    r9,r1,1048
    (gdb) stepi
    0x00000000fff08ce0 in ?? ()
    1: x/i $pc
    => 0xfff08ce0: stw     r0,1108(r1)
    (gdb) stepi
    0x00000000fff08ce4 in ?? ()
    1: x/i $pc
    => 0xfff08ce4: stw     r7,1064(r1)
    (gdb) stepi
    0x00000000fff08ce8 in ?? ()
    1: x/i $pc
    => 0xfff08ce8: stw     r8,1068(r1)
    (gdb) stepi
    0x00000000fff08cec in ?? ()
    1: x/i $pc
    => 0xfff08cec: stw     r10,1076(r1)
    (gdb) stepi
    0x00000000fff08cf0 in ?? ()
    1: x/i $pc
    => 0xfff08cf0: stw     r9,1040(r1)
    (gdb) stepi
    0x00000000fff08cf4 in ?? ()
    1: x/i $pc
    => 0xfff08cf4: bl      0xfff2c92c
    (gdb) stepi
    0x00000000fff2c92c in ?? ()
    1: x/i $pc
    => 0xfff2c92c: stwu    r1,-64(r1)
    (gdb) stepi
    0x00000000fff2c930 in ?? ()
    1: x/i $pc
    => 0xfff2c930: addi    r9,r3,-1
    (gdb) stepi
    0x00000000fff2c934 in ?? ()
    1: x/i $pc
    => 0xfff2c934: mflr    r0
    (gdb) stepi
    0x00000000fff2c938 in ?? ()
    1: x/i $pc
    => 0xfff2c938: stmw    r22,24(r1)
    (gdb) stepi
    0x00000000fff2c93c in ?? ()
    1: x/i $pc
    => 0xfff2c93c: addi    r28,r4,-1
    (gdb) stepi
    0x00000000fff2c940 in ?? ()
    1: x/i $pc
    => 0xfff2c940: mr      r30,r3
    (gdb) stepi
    0x00000000fff2c944 in ?? ()
    1: x/i $pc
    => 0xfff2c944: add     r28,r3,r28
    (gdb) stepi
    0x00000000fff2c948 in ?? ()
    1: x/i $pc
    => 0xfff2c948: stw     r0,68(r1)
    (gdb) stepi
    0x00000000fff2c94c in ?? ()
    1: x/i $pc
    => 0xfff2c94c: mr      r31,r6
    (gdb) stepi
    0x00000000fff2c950 in ?? ()
    1: x/i $pc
    => 0xfff2c950: cmplw   cr7,r28,r9
    (gdb) stepi
    0x00000000fff2c954 in ?? ()
    1: x/i $pc
    => 0xfff2c954: stw     r5,8(r1)
    (gdb) stepi
    0x00000000fff2c958 in ?? ()
    1: x/i $pc
    => 0xfff2c958: mr      r23,r3
    (gdb) stepi
    0x00000000fff2c95c in ?? ()
    1: x/i $pc
    => 0xfff2c95c: mr      r27,r4
    (gdb) stepi
    0x00000000fff2c960 in ?? ()
    1: x/i $pc
    => 0xfff2c960: bge     cr7,0xfff2c96c
    (gdb) stepi
    0x00000000fff2c96c in ?? ()
    1: x/i $pc
    => 0xfff2c96c: lis     r26,-13
    (gdb) stepi
    0x00000000fff2c970 in ?? ()
    1: x/i $pc
    => 0xfff2c970: lis     r24,-12
    (gdb) stepi
    0x00000000fff2c974 in ?? ()
    1: x/i $pc
    => 0xfff2c974: addi    r26,r26,29232
    (gdb) stepi
    0x00000000fff2c978 in ?? ()
    1: x/i $pc
    => 0xfff2c978: li      r22,37
    (gdb) stepi
    0x00000000fff2c97c in ?? ()
    1: x/i $pc
    => 0xfff2c97c: li      r25,32
    (gdb) stepi
    0x00000000fff2c980 in ?? ()
    1: x/i $pc
    => 0xfff2c980: addi    r24,r24,-21720
    (gdb) stepi
    0x00000000fff2c984 in ?? ()
    1: x/i $pc
    => 0xfff2c984: b       0xfff2cd6c
    (gdb) stepi
    0x00000000fff2cd6c in ?? ()
    1: x/i $pc
    => 0xfff2cd6c: lwz     r9,8(r1)
    (gdb) stepi
    0x00000000fff2cd70 in ?? ()
    1: x/i $pc
    => 0xfff2cd70: lbz     r9,0(r9)
    (gdb) stepi
    0x00000000fff2cd74 in ?? ()
    1: x/i $pc
    => 0xfff2cd74: cmpwi   cr7,r9,0
    (gdb) stepi
    0x00000000fff2cd78 in ?? ()
    1: x/i $pc
    => 0xfff2cd78: bne     cr7,0xfff2c988
    (gdb) stepi
    0x00000000fff2c988 in ?? ()
    1: x/i $pc
    => 0xfff2c988: cmplwi  cr7,r9,37
    (gdb) stepi
    0x00000000fff2c98c in ?? ()
    1: x/i $pc
    => 0xfff2c98c: beq     cr7,0xfff2c9a4
    (gdb) stepi
    0x00000000fff2c990 in ?? ()
    1: x/i $pc
    => 0xfff2c990: cmplw   cr7,r30,r28
    (gdb) stepi
    0x00000000fff2c994 in ?? ()
    1: x/i $pc
    => 0xfff2c994: bgt     cr7,0xfff2c99c
    (gdb) stepi
    0x00000000fff2c998 in ?? ()
    1: x/i $pc
    => 0xfff2c998: stb     r9,0(r30)
    (gdb) stepi
    0x00000000fff2c99c in ?? ()
    1: x/i $pc
    => 0xfff2c99c: addi    r30,r30,1
    (gdb) stepi
    0x00000000fff2c9a0 in ?? ()
    1: x/i $pc
    => 0xfff2c9a0: b       0xfff2cd60
    (gdb) stepi
    0x00000000fff2cd60 in ?? ()
    1: x/i $pc
    => 0xfff2cd60: lwz     r9,8(r1)
    (gdb) stepi
    0x00000000fff2cd64 in ?? ()
    1: x/i $pc
    => 0xfff2cd64: addi    r9,r9,1
    (gdb) stepi
    0x00000000fff2cd68 in ?? ()
    1: x/i $pc
    => 0xfff2cd68: stw     r9,8(r1)
    (gdb) stepi
    0x00000000fff2cd6c in ?? ()
    1: x/i $pc
    => 0xfff2cd6c: lwz     r9,8(r1)
    (gdb) stepi
    0x00000000fff2cd70 in ?? ()
    1: x/i $pc
    => 0xfff2cd70: lbz     r9,0(r9)
    (gdb) stepi
    0x00000000fff2cd74 in ?? ()
    1: x/i $pc
    => 0xfff2cd74: cmpwi   cr7,r9,0
    (gdb) stepi
    0x00000000fff2cd78 in ?? ()
    1: x/i $pc
    => 0xfff2cd78: bne     cr7,0xfff2c988
    (gdb) stepi
    0x00000000fff2c988 in ?? ()
    1: x/i $pc
    => 0xfff2c988: cmplwi  cr7,r9,37
    (gdb) stepi
    0x00000000fff2c98c in ?? ()
    1: x/i $pc
    => 0xfff2c98c: beq     cr7,0xfff2c9a4
    (gdb) stepi
    0x00000000fff2c990 in ?? ()
    1: x/i $pc
    => 0xfff2c990: cmplw   cr7,r30,r28
    (gdb) stepi
    0x00000000fff2c994 in ?? ()
    1: x/i $pc
    => 0xfff2c994: bgt     cr7,0xfff2c99c
    (gdb) stepi
    0x00000000fff2c998 in ?? ()
    1: x/i $pc
    => 0xfff2c998: stb     r9,0(r30)
    (gdb) stepi
    0x00000000fff2c99c in ?? ()
    1: x/i $pc
    => 0xfff2c99c: addi    r30,r30,1
    (gdb) stepi
    0x00000000fff2c9a0 in ?? ()
    1: x/i $pc
    => 0xfff2c9a0: b       0xfff2cd60
    (gdb) stepi
    0x00000000fff2cd60 in ?? ()
    1: x/i $pc
    => 0xfff2cd60: lwz     r9,8(r1)
    (gdb) stepi
    0x00000000fff2cd64 in ?? ()
    1: x/i $pc
    => 0xfff2cd64: addi    r9,r9,1
    (gdb) stepi
    0x00000000fff2cd68 in ?? ()
    1: x/i $pc
    => 0xfff2cd68: stw     r9,8(r1)
    (gdb) stepi
    0x00000000fff2cd6c in ?? ()
    1: x/i $pc
    => 0xfff2cd6c: lwz     r9,8(r1)
    (gdb) stepi
    0x00000000fff2cd70 in ?? ()
    1: x/i $pc
    => 0xfff2cd70: lbz     r9,0(r9)
    (gdb) stepi
    0x00000000fff2cd74 in ?? ()
    1: x/i $pc
    => 0xfff2cd74: cmpwi   cr7,r9,0
    (gdb) stepi
    0x00000000fff2cd78 in ?? ()
    1: x/i $pc
    => 0xfff2cd78: bne     cr7,0xfff2c988
    (gdb) stepi
    0x00000000fff2c988 in ?? ()
    1: x/i $pc
    => 0xfff2c988: cmplwi  cr7,r9,37
    (gdb) stepi
    0x00000000fff2c98c in ?? ()
    1: x/i $pc
    => 0xfff2c98c: beq     cr7,0xfff2c9a4
    (gdb) stepi
    0x00000000fff2c990 in ?? ()
    1: x/i $pc
    => 0xfff2c990: cmplw   cr7,r30,r28
    (gdb) stepi
    0x00000000fff2c994 in ?? ()
    1: x/i $pc
    => 0xfff2c994: bgt     cr7,0xfff2c99c
    (gdb) stepi
    0x00000000fff2c998 in ?? ()
    1: x/i $pc
    => 0xfff2c998: stb     r9,0(r30)
    (gdb) stepi
    0x00000000fff2c99c in ?? ()
    1: x/i $pc
    => 0xfff2c99c: addi    r30,r30,1
    (gdb) stepi
    0x00000000fff2c9a0 in ?? ()
    1: x/i $pc
    => 0xfff2c9a0: b       0xfff2cd60
    (gdb) stepi
    0x00000000fff2cd60 in ?? ()
    1: x/i $pc
    => 0xfff2cd60: lwz     r9,8(r1)
    (gdb) stepi
    0x00000000fff2cd64 in ?? ()
    1: x/i $pc
    => 0xfff2cd64: addi    r9,r9,1
    (gdb) stepi
    0x00000000fff2cd68 in ?? ()
    1: x/i $pc
    => 0xfff2cd68: stw     r9,8(r1)
    (gdb) stepi
    0x00000000fff2cd6c in ?? ()
    1: x/i $pc
    => 0xfff2cd6c: lwz     r9,8(r1)
    (gdb) stepi
    0x00000000fff2cd70 in ?? ()
    1: x/i $pc
    => 0xfff2cd70: lbz     r9,0(r9)
    (gdb) stepi
    0x00000000fff2cd74 in ?? ()
    1: x/i $pc
    => 0xfff2cd74: cmpwi   cr7,r9,0
    (gdb) stepi
    0x00000000fff2cd78 in ?? ()
    1: x/i $pc
    => 0xfff2cd78: bne     cr7,0xfff2c988
    (gdb) stepi
    0x00000000fff2c988 in ?? ()
    1: x/i $pc
    => 0xfff2c988: cmplwi  cr7,r9,37
    (gdb) stepi
    0x00000000fff2c98c in ?? ()
    1: x/i $pc
    => 0xfff2c98c: beq     cr7,0xfff2c9a4
    (gdb) stepi
    0x00000000fff2c990 in ?? ()
    1: x/i $pc
    => 0xfff2c990: cmplw   cr7,r30,r28
    (gdb) stepi
    0x00000000fff2c994 in ?? ()
    1: x/i $pc
    => 0xfff2c994: bgt     cr7,0xfff2c99c
    (gdb) stepi
    0x00000000fff2c998 in ?? ()
    1: x/i $pc
    => 0xfff2c998: stb     r9,0(r30)
    (gdb) stepi
    0x00000000fff2c99c in ?? ()
    1: x/i $pc
    => 0xfff2c99c: addi    r30,r30,1
    (gdb) stepi
    0x00000000fff2c9a0 in ?? ()
    1: x/i $pc
    => 0xfff2c9a0: b       0xfff2cd60
    (gdb) stepi
    0x00000000fff2cd60 in ?? ()
    1: x/i $pc
    => 0xfff2cd60: lwz     r9,8(r1)
    (gdb) stepi
    0x00000000fff2cd64 in ?? ()
    1: x/i $pc
    => 0xfff2cd64: addi    r9,r9,1
    (gdb) stepi
    0x00000000fff2cd68 in ?? ()
    1: x/i $pc
    => 0xfff2cd68: stw     r9,8(r1)
    (gdb) stepi
    0x00000000fff2cd6c in ?? ()
    1: x/i $pc
    => 0xfff2cd6c: lwz     r9,8(r1)
    (gdb) stepi
    0x00000000fff2cd70 in ?? ()
    1: x/i $pc
    => 0xfff2cd70: lbz     r9,0(r9)
    (gdb) stepi
    0x00000000fff2cd74 in ?? ()
    1: x/i $pc
    => 0xfff2cd74: cmpwi   cr7,r9,0
    (gdb) stepi
    0x00000000fff2cd78 in ?? ()
    1: x/i $pc
    => 0xfff2cd78: bne     cr7,0xfff2c988
    (gdb) stepi
    0x00000000fff2c988 in ?? ()
    1: x/i $pc
    => 0xfff2c988: cmplwi  cr7,r9,37
    (gdb) stepi
    0x00000000fff2c98c in ?? ()
    1: x/i $pc
    => 0xfff2c98c: beq     cr7,0xfff2c9a4
    (gdb) stepi
    0x00000000fff2c990 in ?? ()
    1: x/i $pc
    => 0xfff2c990: cmplw   cr7,r30,r28
    (gdb) stepi
    0x00000000fff2c994 in ?? ()
    1: x/i $pc
    => 0xfff2c994: bgt     cr7,0xfff2c99c
    (gdb) stepi
    0x00000000fff2c998 in ?? ()
    1: x/i $pc
    => 0xfff2c998: stb     r9,0(r30)
    (gdb) stepi
    0x00000000fff2c99c in ?? ()
    1: x/i $pc
    => 0xfff2c99c: addi    r30,r30,1
    (gdb) stepi
    0x00000000fff2c9a0 in ?? ()
    1: x/i $pc
    => 0xfff2c9a0: b       0xfff2cd60
    (gdb) stepi
    0x00000000fff2cd60 in ?? ()
    1: x/i $pc
    => 0xfff2cd60: lwz     r9,8(r1)
    (gdb) stepi
    0x00000000fff2cd64 in ?? ()
    1: x/i $pc
    => 0xfff2cd64: addi    r9,r9,1
    (gdb) stepi
    0x00000000fff2cd68 in ?? ()
    1: x/i $pc
    => 0xfff2cd68: stw     r9,8(r1)
    (gdb) stepi
    0x00000000fff2cd6c in ?? ()
    1: x/i $pc
    => 0xfff2cd6c: lwz     r9,8(r1)
    (gdb) stepi
    0x00000000fff2cd70 in ?? ()
    1: x/i $pc
    => 0xfff2cd70: lbz     r9,0(r9)
    (gdb) stepi
    0x00000000fff2cd74 in ?? ()
    1: x/i $pc
    => 0xfff2cd74: cmpwi   cr7,r9,0
    (gdb) stepi
    0x00000000fff2cd78 in ?? ()
    1: x/i $pc
    => 0xfff2cd78: bne     cr7,0xfff2c988
    (gdb) stepi
    0x00000000fff2c988 in ?? ()
    1: x/i $pc
    => 0xfff2c988: cmplwi  cr7,r9,37
    (gdb)

    Offline darthnVader

    • Platinum Member (500+ Posts)
    • *****
    • Posts: 520
    • New Member
    Re: G5 qemu attempts.
    « Reply #141 on: October 20, 2018, 05:31:48 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.

    Neither the 970, 970fx, nor the 970mp have BAT?


    « Last Edit: October 20, 2018, 05:49:33 AM by darthnVader »

    Offline powermax

    • Enthusiast Member (25+ Posts)
    • ***
    • Posts: 80
    • Hobbyist programmer
    Re: G5 qemu attempts.
    « Reply #142 on: October 20, 2018, 06:31:06 AM »
    Code: [Select]
    [quote author=darthnVader link=topic=4600.msg33493#msg33493 date=1540038532]
    Breakpoint 1, 0x000000000020f0a4 in ?? ()
    (gdb)  display/i $pc
    1: x/i $pc
    => 0x20f0a4: lwz     r16,28(r3)
    (gdb) stepi
    0x000000000020f0a8 in ?? ()
    1: x/i $pc
    => 0x20f0a8: mtsrr0  r5
    (gdb) stepi
    0x000000000020f0ac in ?? ()
    1: x/i $pc
    => 0x20f0ac: li      r0,12288
    (gdb) stepi
    0x000000000020f0b0 in ?? ()
    1: x/i $pc
    => 0x20f0b0: mtsrr1  r0
    (gdb) stepi
    0x000000000020f0b4 in ?? ()
    1: x/i $pc
    => 0x20f0b4: rfi
    [/quote]

    Can you show me the value of R5 at 0x20f0b4 (before executing rfi)?

    Offline darthnVader

    • Platinum Member (500+ Posts)
    • *****
    • Posts: 520
    • New Member
    Re: G5 qemu attempts.
    « Reply #143 on: October 20, 2018, 07:13:41 AM »
    Code: [Select]
    [quote author=darthnVader link=topic=4600.msg33493#msg33493 date=1540038532]
    Breakpoint 1, 0x000000000020f0a4 in ?? ()
    (gdb)  display/i $pc
    1: x/i $pc
    => 0x20f0a4: lwz     r16,28(r3)
    (gdb) stepi
    0x000000000020f0a8 in ?? ()
    1: x/i $pc
    => 0x20f0a8: mtsrr0  r5
    (gdb) stepi
    0x000000000020f0ac in ?? ()
    1: x/i $pc
    => 0x20f0ac: li      r0,12288
    (gdb) stepi
    0x000000000020f0b0 in ?? ()
    1: x/i $pc
    => 0x20f0b0: mtsrr1  r0
    (gdb) stepi
    0x000000000020f0b4 in ?? ()
    1: x/i $pc
    => 0x20f0b4: rfi

    Can you show me the value of R5 at 0x20f0b4 (before executing rfi)?
    [/quote]

    Code: [Select]
    (gdb) stepi
    0x000000000020f0b4 in ?? ()
    1: x/i $pc
    => 0x20f0b4: rfi
    (gdb) p/x $r5
    $1 = 0x20f0b8
    (gdb)

    Offline darthnVader

    • Platinum Member (500+ Posts)
    • *****
    • Posts: 520
    • New Member
    Re: G5 qemu attempts.
    « Reply #144 on: October 20, 2018, 07:31:12 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

    I think this code checks if KVM is enabled:

    Code: [Select]
    #if defined(TARGET_PPC64)
    I don't have any G5 hardware to test on, do you think I should remove that if case, as I did before, it doesn't seem to change anything, but that doesn't mean it doesn't/won't?

    Offline darthnVader

    • Platinum Member (500+ Posts)
    • *****
    • Posts: 520
    • New Member
    Re: G5 qemu attempts.
    « Reply #145 on: October 20, 2018, 07:53:14 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.

    Neither the 970, 970fx, nor the 970mp have BAT?

    Quote
    1.2.6 PowerPC Memory Management Model
    The PowerPC memory management unit (MMU) specifications are provided by the PowerPC OEA. The
    primary functions of the MMU in a PowerPC processor are to translate logical (effective) addresses to phys-
    ical addresses for memory accesses and I/O accesses (most I/O accesses are assumed to be memory-
    mapped), and to provide access protection on a block or page basis.
    Note: 
    Many aspects of memory management are implementation-dependent. The description in
    Chapter 7,
    Memory Management
     describes the conceptual model of a PowerPC MMU; however, PowerPC processors
    may differ in the specific hardware used to implement the MMU model of the OEA.
    PowerPC processors require address translation for two types of transactions—instruction accesses and
    data accesses to memory (typically generated by load and store instructions).
    The memory management specification of the PowerPC OEA includes models for both 32 and 64-bit imple-
    mentations. The MMU of a 64-bit PowerPC processor provides 264 bytes of effective address space acces-sible to supervisor and user programs with support for two page sizes; a 4-Kbyte page size (212) and a large page whose size is implementation dependent (2p where 13 ≤p ≤28). PowerPC 32-bit processors also have
    a block address translation (BAT) mechanism for mapping large blocks of memory. Block sizes range from
    128 Kbyte to 256 Mbyte and are software-selectable. The MMU of 64-bit PowerPC processors uses an
    interim virtual address (between 65 and 80 bits) and hashed page tables in the generation of physical
    addresses that are ≤62 bits in length.

    https://wiki.alcf.anl.gov/images/f/fb/PowerPC_-_Assembly_-_IBM_Programming_Environment_2.3.pdf

    Offline powermax

    • Enthusiast Member (25+ Posts)
    • ***
    • Posts: 80
    • Hobbyist programmer
    Re: G5 qemu attempts.
    « Reply #146 on: October 20, 2018, 11:29:59 AM »
    Code: [Select]
    (gdb) stepi
    0x000000000020f0b4 in ?? ()
    1: x/i $pc
    => 0x20f0b4: rfi
    (gdb) p/x $r5
    $1 = 0x20f0b8
    (gdb)

    Try to set a breakpoint at 0x20f0b8, then "cont". Does execution halt there?

    Offline darthnVader

    • Platinum Member (500+ Posts)
    • *****
    • Posts: 520
    • New Member
    Re: G5 qemu attempts.
    « Reply #147 on: October 20, 2018, 02:24:34 PM »
    Code: [Select]
    (gdb) stepi
    0x000000000020f0b4 in ?? ()
    1: x/i $pc
    => 0x20f0b4: rfi
    (gdb) p/x $r5
    $1 = 0x20f0b8
    (gdb)

    Try to set a breakpoint at 0x20f0b8, then "cont". Does execution halt there?

    Doesn't break there just "continuing".

    Offline powermax

    • Enthusiast Member (25+ Posts)
    • ***
    • Posts: 80
    • Hobbyist programmer
    Re: G5 qemu attempts.
    « Reply #148 on: October 20, 2018, 02:46:16 PM »
    Code: [Select]
    (gdb) stepi
    0x000000000020f0b4 in ?? ()
    1: x/i $pc
    => 0x20f0b4: rfi
    (gdb) p/x $r5
    $1 = 0x20f0b8
    (gdb)

    Try to set a breakpoint at 0x20f0b8, then "cont". Does execution halt there?

    Doesn't break there just "continuing".

    This is bad. That means that "rfi" doesn't work as expected. RFI (return from interrupt) can be understand as an unconditional jump with MSR update and context synchronization in this precise case. We're going to arrive at 0x20f0b8 with another CPU state (MSR=0x3000, i.e. external exceptions off, floating point and machine check exceptions turned on). For this purpose, we placed the destination address 0x20f0b8 into SSR0 and the new MSR value into SRR1 and, finally, invoke "rfi" that should wait for all CPU's internal processing to be completed (just think about the superscalar architecture executing several instructions per clock cycle, see https://en.wikipedia.org/wiki/Superscalar_processor), update the MSR and transfer control to the destination address.

    If I interpret your debug output correctly, the program will never get to 0x20f0b8 but will be dropped into an exception handler at 0x104? Anyway, it looks odd...

    Can you check how the corresponding code behaves on G4? Does it arrive at 0x20f0b8 when tracing past "rfi"? Does the breakpoint at 0x20f0b8 work?

    Offline darthnVader

    • Platinum Member (500+ Posts)
    • *****
    • Posts: 520
    • New Member
    Re: G5 qemu attempts.
    « Reply #149 on: October 20, 2018, 02:51:30 PM »
    Yes, on the G4 it breaks there:

    Code: [Select]
    gdb) target remote localhost:1234
    Remote debugging using localhost:1234
    0x00000000fff00100 in ?? ()
    (gdb) cont
    Continuing.

    Breakpoint 1, 0x000000000020f0b8 in ?? ()
    (gdb)