PowerMac 7100 and Linux (and NetBSD)

joevt

Tinkerer
Mar 5, 2023
149
51
28
I'll try to track down the std::invalid_argument bug.
Made a fix for this bug in the last commit in my fork.
Another note: when using si it may be useful to use context auto so that it will show 68K instructions instead of showing ppc instructions from the 68K emulator.
 

joevt

Tinkerer
Mar 5, 2023
149
51
28
si is slow, especially when there are big loops. It might be better to add commands or code in DingusPPC to enter the DPPC debugger when the code at the PPC or 68K program counter matches some bytes (which you would grab from the Mac OS Loader file).

Another option would be to alter the code to enable instruction logging, and have it use get_name_OpenFirmware to detect the very first Open Firmware code being executed. See the code that handles the debug_copland option. Of course, you could just get the address of an early Open Firmware instruction (such as the address of @startvec = 0xFF808000 or real address 0x00408000 or cold-load at 0xFF80FF88 if that doesn't work) and use that with a until command.

Then dump the instruction log. Maybe there's an interesting address in the instruction log that you could use with until after rebooting. Then use si from there.

We know nothing important is happening until the hard disk is being read. So that would be another good place to stop the debugger and start logging.
 

speakers

Tinkerer
Nov 5, 2021
146
96
28
San Jose, CA
peak-weber.net
...
The first occurrence corresponds to port A (modem port) because that is first in the device tree.
The second occurrence corresponds to port B (printer port) because that is the next serial port in the device tree that has not had it's property overridden by the command line yet.
Ah, thanks. This wasn't clear from the docs and was too lazy to chase it down in the code :confused:
...
For an empty CD-ROM drive, it's probably best to not include the CD-ROM drive at all until SCSI CD-ROM emulation in DingusPPC is fixed to support empty CD-ROM drives. Use this:
--cdr_config=
That works.
...
You could try --machine pm7100 but we haven't worked on other PDM machines that much (for RAM allocation, 8100 is missing the second SCSI bus, etc.)
The pm7100 machine setting boots but only 8MB of RAM shows up. I'd like to be able to emulate my PM7600's discontiguous RAM layout

I'm currently running the original 6100/7100 ROM. My PM7100 has the later ROM. DingusPPC boots on this later ROM when --machine pm6100 is set but takes an illegal instruction trap booting System 7 with --machine pm7100:
Screenshot 2025-07-30 at 1.35.18 PM.png
I'm also not seeing the floppy drive accessible by DBOF. Booting into MacOS, an image mounts fine (after use of the ffd debugger command) but DBOF sees nothing (using boot or dir or whatever). I this a known issue?
 

joevt

Tinkerer
Mar 5, 2023
149
51
28
The pm7100 machine setting boots but only 8MB of RAM shows up. I'd like to be able to emulate my PM7600's discontiguous RAM layout

I'm currently running the original 6100/7100 ROM. My PM7100 has the later ROM. DingusPPC boots on this later ROM when --machine pm6100 is set but takes an illegal instruction trap booting System 7 with --machine pm7100:View attachment 22473
I think pm7100 requires more work. Same for pm8100. You said pm7600. Did you mean pm7100?

I'm also not seeing the floppy drive accessible by DBOF. Booting into MacOS, an image mounts fine (after use of the ffd debugger command) but DBOF sees nothing (using boot or dir or whatever). I this a known issue?
DBOF does have Open Firmware code for the floppy. I haven't tested it. Have you tried it on your Power Mac 7100?
Is the floppy formatted with HFS or HFS+? I think only FAT (little endian bytes at 0x1fe are 0xaa55) or HFS (first two big endian bytes = 0x4552) is supported. No partition map.
Try this command:
dir fd:\

Hmm, how to insert floppy while booting Copland on SCSI? I suppose it should work if the floppy isn't bootable?
You could insert the floppy after you get into DBOF using the DingusPPC debugger fdd command.
dir fd:\ gives me a READ TIMEOUT error in Open Firmware. It might be a DPPC emulation problem with Open Firmware's floppy driver.
 

speakers

Tinkerer
Nov 5, 2021
146
96
28
San Jose, CA
peak-weber.net
I think pm7100 requires more work. Same for pm8100. You said pm7600. Did you mean pm7100?
Yes, finger trouble. [I do also have a pm7600.] I see now that the code in machinepdm.cpp only has pm6100 properties defineed
DBOF does have Open Firmware code for the floppy. I haven't tested it. Have you tried it on your Power Mac 7100?
Yes. A FAT floppy is readable on my pm7100 under DBOF.
 

speakers

Tinkerer
Nov 5, 2021
146
96
28
San Jose, CA
peak-weber.net
It's been a while since I last repoted but I've made some progress. I've changed the thread title to reflect what I've been up to:

So I first tried to get an instruction trace for booting into DBOF. I captured stdout to a file but the spew was so vast that my M4 MBA ground to a standstill - paging like crazy since Terminal.app’s scrollback buffer swamped the machine (if it didn’t just die).

I modified dinguspcc adding —instruction_log option to write disassembly directly to a file. In fact, since I’m not a C++ fan, I got Claude to do this for me using Cursor. This worked .. but not at all efficiently and the emulation was so slow that it didn’t make much progress. Also, the log file gets huge — into hundreds of gigabytes!

I decided to add more specific smarts to dingusppc. Firstly, I aded a hook to drop into the debugger when the boot blocks (at sector 0) are read. Up to this point the boot sequence is the same for MacOS and Copland. For DBOF, the ROM then loads MacOSLoader rather than the System file. Tracing from here, I could identify where the page table is constructed for DBOF. It’s early in the DBOF code read from MacOSLoader resource ‘opfw’. The page table is based at real_base and it’s always 0x400000 for DBOF.

016F481C->017B381C: 80A30020 lwz r5, 0x20(r3) ; in{ r3:17135E0 } out{ r5:400000 } … 000048AC: 7C3903A6 mtsdr1 r1 ; in{ r1:4E0000 } out{ sdr1:4E0000 }

However, I couldn’t pinpoint where the 0x400000 address was coming from. It was in R5 when the PTEs were written but, although R5 had been loaded from a known memory location (0x1713600), this was in turn set by 68k code which is practically impossible to decipher from the emulating PPC stream. Note that, rather helpfully, the ROM maps the 68K emulation code at virtual addresses 68xxxxxx so it’s easy to spot legacy code being run.

Now, it turned out that by overriding R5 from the debugger by hand, I could change the physical base of the DBOF page table (at virtual 0xFF800000) and DBOF would successfully boot to the CLI! If only I could find the memory location and hence disk location for the 0x400000 to patch….

So I added code similar to the watch-point logic to enter the debugger when the location of the 0x400000 was written. That gave me the 68k code loading it and from the sequence of words being read I could tell the resource being loaded. And that turned out to be ’nkld’. From the MacNosy listing attached by @joevt earlier:

nkld_128 LINK A6,#-$680 MOVEM.L D3-D7/A2-A4,-(A7) … lab_12 MOVEA.L #KeyMap,A0 … MOVEA.L vab_29(A6),A2 MOVE.L vab_21(A6),(A2) MOVE.L vab_22(A6),4(A2) MOVE.L vab_23(A6),8(A2) MOVE.L vab_24(A6),12(A2) MOVE.L vab_25(A6),16(A2) MOVE.L vab_26(A6),20(A2) MOVE.L vab_27(A6),24(A2) MOVE.L vab_28(A6),28(A2) MOVE.L #$400000,32(A2) <<<<<<<<<<<

The physical base address of 0x400000 is a fixed value which is not computed from the memory configuration. Hence, patching it seems viable (provided it’s consistent with the machine’s actual memory config).

And, indeed, using ResEdit to patch this location in the ‘nkld’ resource of MacOSLoader produces a system that boots to DBOF at a high enough physical (real-base) address that enables my modified ofwboot.xcf loaded from floppy to boot a NetBSD kernel from a scsi disk image:

Open Firmware, 2.0 To continue booting the MacOS type: BYE<return> To continue booting from the default boot device type: BOOT<return> ok 0 > boot fd:,ofwboot.xcf scsi/@0/netbsd loading XCOFF tsize=F950 dsize=258 bsize=2750 entry=1000000 SECTIONS: .text 01000000 01000000 0000F950 00001000 .pad 0100F948 0100F948 000006B0 00010950 .data 01010000 01010000 00000258 00011000 .bss 01010258 01010258 00002750 00000000 .gnu.att 00000000 00000000 00000010 00011258 .ident 00000000 00000000 000000AF 00011268 loading .text, done.. loading .data, done.. clearing .bss, done.. >> NetBSD/macppc OpenFirmware Boot, Revision 1.13 (Tue Aug 12 20:11:41 UTC 2025) 11056036+166232 [476224+463762]=0xb999f0 start=0x100000 DEFAULT CATCH!, code=FFF00400 at %SRR0: 001001DC %SRR1: 40000030 ok

This took a machine-check exception very early and way too soon for any console or debugging output.

But by adding further code to my modified loader, I was able to patch the kernel (with “b .”s) and discover the trap occurred on return from the fist OF call from the NetBSD kernel (to find / in the device tree). Since OF entry/exit is very machine and OF dependent, and I was using the generic NetBSD 9.2 kernel, I built specifically 601 capable version instead. (I was also pruned PCI and other absent devices.) This got much further:

>> NetBSD/macppc OpenFirmware Boot, Revision 1.13 (Tue Aug 12 20:11:41 UTC 2025) 4099596+137488 [223648+213414]=0x4756d0 start=0x100000 [ 1.0000000] mem region 0 start=0 size=800000 [ 1.0000000] mem region 1 start=1000000 size=2000000 [ 1.0000000] mem region 2 start=5000000 size=2000000 [ 1.0000000] mem region 3 start=9000000 size=2000000 [ 1.0000000] mem region 4 start=d000000 size=2000000 [ 1.0000000] avail region 0 start=0x90000 size=0x70000 [ 1.0000000] avail region 1 start=0x200000 size=0x600000 [ 1.0000000] avail region 2 start=0x1013000 size=0x3ed000 [ 1.0000000] avail region 3 start=0x1500000 size=0x1b00000 [ 1.0000000] avail region 4 start=0x5000000 size=0x2000000 [ 1.0000000] avail region 5 start=0x9000000 size=0x2000000 [ 1.0000000] avail region 6 start=0xd000000 size=0x2000000

So the console has been opened, and written to, and there’s been memory discovery from the device tree. Progress .. and perhaps the first time NetBSD has seen a Nubus PPC Mac!
 

joevt

Tinkerer
Mar 5, 2023
149
51
28
Tracing from here, I could identify where the page table is constructed for DBOF. It’s early in the DBOF code read from MacOSLoader resource ‘opfw’. The page table is based at real_base and it’s always 0x400000 for DBOF.

016F481C->017B381C: 80A30020 lwz r5, 0x20(r3) ; in{ r3:17135E0 } out{ r5:400000 } … 000048AC: 7C3903A6 mtsdr1 r1 ; in{ r1:4E0000 } out{ sdr1:4E0000 }
I think these lines are disassembled in the Part1.txt output of my DumpMacRom.sh script. I think you have that dump? The lines are 441 - 477, offset 000858 to 0008E8. Subtract 0x3c (the size of the COFF header of Open Firmware) from those offsets gives 0x81C to 0x8AC which matches your virtual and physical addresses. Interesting that the code switches from virtual address 016F4*** to physical address 00004*** and that the physical address switches from 017B3*** to 00004***. I guess stuff is being copied or mirrored.
https://github.com/dingusdev/dingusppc/blob/master/zdocs/developers/openfirmware.md

The code after 000048AC initializes fields of @startvec:
Code:
stw      r1,244(r12)    ; @startvec.>htab
stw      r1,252(r12)    ; @startvec.>keepbat3?
stw      r3,128(r12)    ; @startvec.>hwinit3
stw      r4,132(r12)    ; @startvec.>hwinit4
stw      r8,136(r12)    ; @startvec.>hwinit8
stw      r9,140(r12)    ; @startvec.>hwinit9
stw      r10,40(r12)    ; @startvec.>rom-base
lwz      r3,0(r3)       ;
lwz      r0,4(r4)       ;
stw      r5,44(r12)     ; @startvec.>real_base
stw      r6,48(r12)     ; @startvec.>virt_base
stw      r3,152(r12)    ; @startvec.>ramsize = >hwinit3->ramsize
stw      r0,156(r12)    ; @startvec.>cpuclock = >hwinit4->cpuclock
lwz      r3,8(r4)       ;
lwz      r4,12(r4)      ;
stw      r3,160(r12)    ; @startvec.>busclock = >hwinit4->busclock
stw      r4,164(r12)    ; @startvec.>tbclock = >hwinit4->tbclock
stw      r13,292(r12)   ; @startvec.>r13-31
stw      r14,296(r12)   ; "
stw      r15,300(r12)   ; "
stw      r16,304(r12)   ; "
stw      r17,308(r12)   ; "
stw      r18,312(r12)   ; "
stw      r19,316(r12)   ; "
stw      r20,320(r12)   ; "
stw      r21,324(r12)   ; "
stw      r22,328(r12)   ; "
stw      r23,332(r12)   ; "
stw      r24,336(r12)   ; "
stw      r25,340(r12)   ; "
stw      r26,344(r12)   ; "
stw      r27,348(r12)   ; "
stw      r28,352(r12)   ; "
stw      r29,356(r12)   ; "
stw      r30,360(r12)   ; "
stw      r31,364(r12)   ; "
sub      r16,r1,r5      ;
add      r16,r16,r6     ;
stw      r16,172(r12)   ; @startvec.>free-top = >htab - real_base + virt_base

However, I couldn’t pinpoint where the 0x400000 address was coming from. It was in R5 when the PTEs were written but, although R5 had been loaded from a known memory location (0x1713600), this was in turn set by 68k code which is practically impossible to decipher from the emulating PPC stream. Note that, rather helpfully, the ROM maps the 68K emulation code at virtual addresses 68xxxxxx so it’s easy to spot legacy code being run.
The DingusPPC debugger has a command context auto that should help with that if you're stepping through code with si or si 100000 . The command will automatically switch to stepping through 68K when the CPU is executing the emulator. It doesn't affect the instruction log which is just PowerPC instructions. I suppose the instruction log could be improved to handle 68K.

You need to add the 68K disassembler. I use this whenever I do a rebase:
Code:
mkdir -p /Volumes/Work/Programming/dingusppc/joevt-dingusppc/build-xcode
cd       /Volumes/Work/Programming/dingusppc/joevt-dingusppc/build-xcode
cmake -DDPPC_BUILD_BENCHMARKS=ON -DDPPC_BUILD_PPC_TESTS=ON -DDPPC_68K_DEBUGGER=ON -DCAPSTONE_BUILD_CSTOOL=ON -DDPPC_SUPPORT_PPC_LE=ON -DDPPC_SUPPORT_MEM_LE=ON -G Xcode ..
# set project tabs to four spaces
perl -0777 -i -pE 'if (/^\t*mainGroup = (\w+);$/m && /^(\t*)$1 = {\n((.*\n)*?()\1)};$/m) {
	substr($_, $-[4], 0) = $1 . "\tindentWidth = 4;\n" . $1 . "\ttabWidth = 4;\n" }
' "dingusppc.xcodeproj/project.pbxproj"
open dingusppc.xcodeproj

Now, it turned out that by overriding R5 from the debugger by hand, I could change the physical base of the DBOF page table (at virtual 0xFF800000) and DBOF would successfully boot to the CLI! If only I could find the memory location and hence disk location for the 0x400000 to patch….

So I added code similar to the watch-point logic to enter the debugger when the location of the 0x400000 was written.
You mean the #ifdef WATCH_POINT stuff in ppcexec.cpp and ppcmmu.cpp?

That gave me the 68k code loading it and from the sequence of words being read I could tell the resource being loaded. And that turned out to be ’nkld’. From the MacNosy listing attached by @joevt earlier:

nkld_128 LINK A6,#-$680 MOVEM.L D3-D7/A2-A4,-(A7) … lab_12 MOVEA.L #KeyMap,A0 … MOVEA.L vab_29(A6),A2 MOVE.L vab_21(A6),(A2) MOVE.L vab_22(A6),4(A2) MOVE.L vab_23(A6),8(A2) MOVE.L vab_24(A6),12(A2) MOVE.L vab_25(A6),16(A2) MOVE.L vab_26(A6),20(A2) MOVE.L vab_27(A6),24(A2) MOVE.L vab_28(A6),28(A2) MOVE.L #$400000,32(A2) <<<<<<<<<<<
Is A2 the same as @startvec.>hwinit3 ?

The physical base address of 0x400000 is a fixed value which is not computed from the memory configuration. Hence, patching it seems viable (provided it’s consistent with the machine’s actual memory config).

And, indeed, using ResEdit to patch this location in the ‘nkld’ resource of MacOSLoader produces a system that boots to DBOF at a high enough physical (real-base) address that enables my modified ofwboot.xcf loaded from floppy to boot a NetBSD kernel from a scsi disk image:

Open Firmware, 2.0 To continue booting the MacOS type: BYE<return> To continue booting from the default boot device type: BOOT<return> ok 0 > boot fd:,ofwboot.xcf scsi/@0/netbsd loading XCOFF tsize=F950 dsize=258 bsize=2750 entry=1000000 SECTIONS: .text 01000000 01000000 0000F950 00001000 .pad 0100F948 0100F948 000006B0 00010950 .data 01010000 01010000 00000258 00011000 .bss 01010258 01010258 00002750 00000000 .gnu.att 00000000 00000000 00000010 00011258 .ident 00000000 00000000 000000AF 00011268 loading .text, done.. loading .data, done.. clearing .bss, done.. >> NetBSD/macppc OpenFirmware Boot, Revision 1.13 (Tue Aug 12 20:11:41 UTC 2025) 11056036+166232 [476224+463762]=0xb999f0 start=0x100000 DEFAULT CATCH!, code=FFF00400 at %SRR0: 001001DC %SRR1: 40000030 ok

This took a machine-check exception very early and way too soon for any console or debugging output.

But by adding further code to my modified loader, I was able to patch the kernel (with “b .”s) and discover the trap occurred on return from the fist OF call from the NetBSD kernel (to find / in the device tree). Since OF entry/exit is very machine and OF dependent, and I was using the generic NetBSD 9.2 kernel, I built specifically 601 capable version instead. (I was also pruned PCI and other absent devices.) This got much further:

>> NetBSD/macppc OpenFirmware Boot, Revision 1.13 (Tue Aug 12 20:11:41 UTC 2025) 4099596+137488 [223648+213414]=0x4756d0 start=0x100000 [ 1.0000000] mem region 0 start=0 size=800000 [ 1.0000000] mem region 1 start=1000000 size=2000000 [ 1.0000000] mem region 2 start=5000000 size=2000000 [ 1.0000000] mem region 3 start=9000000 size=2000000 [ 1.0000000] mem region 4 start=d000000 size=2000000 [ 1.0000000] avail region 0 start=0x90000 size=0x70000 [ 1.0000000] avail region 1 start=0x200000 size=0x600000 [ 1.0000000] avail region 2 start=0x1013000 size=0x3ed000 [ 1.0000000] avail region 3 start=0x1500000 size=0x1b00000 [ 1.0000000] avail region 4 start=0x5000000 size=0x2000000 [ 1.0000000] avail region 5 start=0x9000000 size=0x2000000 [ 1.0000000] avail region 6 start=0xd000000 size=0x2000000

So the console has been opened, and written to, and there’s been memory discovery from the device tree. Progress .. and perhaps the first time NetBSD has seen a Nubus PPC Mac!
What's “b .”s ?

This floppy -> SCSI thing is on a real NuBus PPC Mac or DingusPPC?
I know DingusPPC SCSI emulation doesn't work in DBOF but maybe floppy works. Then NetBSD might have it's own SCSI driver? Or is it still using Open Firmware at this point?

Is NetBSD little-endian or big-endian?
 

speakers

Tinkerer
Nov 5, 2021
146
96
28
San Jose, CA
peak-weber.net
I think these lines are disassembled in the Part1.txt output of my DumpMacRom.sh script. I think you have that dump? The lines are 441 - 477, offset 000858 to 0008E8. Subtract 0x3c (the size of the COFF header of Open Firmware) from those offsets gives 0x81C to 0x8AC which matches your virtual and physical addresses. Interesting that the code switches from virtual address 016F4*** to physical address 00004*** and that the physical address switches from 017B3*** to 00004***. I guess stuff is being copied or mirrored.
https://github.com/dingusdev/dingusppc/blob/master/zdocs/developers/openfirmware.md
That indeed checks out.
The code after 000048AC initializes fields of @startvec:
Code:
stw      r1,244(r12)    ; @startvec.>htab
stw      r1,252(r12)    ; @startvec.>keepbat3?
stw      r3,128(r12)    ; @startvec.>hwinit3
stw      r4,132(r12)    ; @startvec.>hwinit4
stw      r8,136(r12)    ; @startvec.>hwinit8
stw      r9,140(r12)    ; @startvec.>hwinit9
stw      r10,40(r12)    ; @startvec.>rom-base
lwz      r3,0(r3)       ;
lwz      r0,4(r4)       ;
stw      r5,44(r12)     ; @startvec.>real_base
[/QUOTE]
That R5 value gets to the expected spot!
[QUOTE="joevt, post: 39446, member: 1466"]
...

The DingusPPC debugger has a command [icode]context auto[/icode] that should help with that if you're stepping through code with [icode]si[/icode] or  [icode]si 100000[/icode] . 
[/QUOTE]
The PPC step I needed was 100000000 and more!
[QUOTE="joevt, post: 39446, member: 1466"]
The command will automatically switch to stepping through 68K when the CPU is executing the emulator. 
[/QUOTE]
Thanks. I'll try that next time.
[QUOTE="joevt, post: 39446, member: 1466"]

You mean the [icode]#ifdef WATCH_POINT[/icode] stuff in ppcexec.cpp and ppcmmu.cpp?
[/QUOTE]
Yup.
[QUOTE="joevt, post: 39446, member: 1466"]
Is A2 the same as [icode]@startvec.>hwinit3[/icode] ?
[/QUOTE]
I don't know. I'll see if I can determine.
[QUOTE="joevt, post: 39446, member: 1466"]

What's  “b .”s ?
[/QUOTE]
Branch dot. A trivial spin. Machine code 48 00 00 00.
[QUOTE="joevt, post: 39446, member: 1466"]


This floppy -> SCSI thing is on a real NuBus PPC Mac or DingusPPC?
[/QUOTE]
Yes.
[QUOTE="joevt, post: 39446, member: 1466"]

I know DingusPPC SCSI emulation doesn't work in DBOF but maybe floppy works. Then NetBSD might have it's own SCSI driver? Or is it still using Open Firmware at this point?
[/QUOTE]
DingusPPC floppy doesn't work. NetBSD has it's own SCSI driver but the loader is using DBOF at this stage.
[QUOTE="joevt, post: 39446, member: 1466"]

Is NetBSD little-endian or big-endian?
[/QUOTE]
Could be either in general but it's big-endian for PPC.
 

joevt

Tinkerer
Mar 5, 2023
149
51
28
Your post is missing a [ / code ]

The PPC step I needed was 100000000 and more!
Right. I do 1000000 steps at a time usually. Sometimes 10000000. If you know where the code you want starts, then the until command works. Otherwise, you add some extra temporary watch point type code to the emulator itself to enter the debugger when something interesting happens.

I don't know. I'll see if I can determine.
I think @startvec >hwinit3 @ . will output the value. Then you can compare. Or use the dump-fields command from #25 to dump all the fields.

Branch dot. A trivial spin. Machine code 48 00 00 00.
That's a branch to self = infinite loop?

DingusPPC floppy doesn't work.
One more thing to fix.