Mac OS 9 Lives
Mac OS 9 Discussion => Mac OS 9, Hacks & Upgrades => Mac OS 9 on Unsupported Hardware => Topic started by: darthnVader on October 04, 2018, 09:49:44 AM
-
I figured I'd look at trying to boot OS 9 on the G5 970fx v3.1 in Qemu, and maybe that would tell us if it would ever be doable on a real G5 CPU.
Qemu doesn't emulate a G5 logic board, it boots a Mac99 machine, near a Sawtooth.
Linux boots with the mac99 and 970fx, but OS X hangs after Call_Kernel! from BootX. It seems to be trying to read spr 304, then make a write there, over and over. I'm looking into that.
We have some reports that using Linux on a real G5, and running Qemu with KVM and cpu host, results in mach_kernel loading, but later a KP do to the drivers expecting a G5 logicboard rather than Sawtooth hardware.
Here is what I get trying to boot OS 9:
qemu-system-ppc64 -M mac99 -m 1024 -cpu ppc64 -hda ~/os9/os9.img --nographic -net nic,model=sungem -net user -prom-env "auto-boot?=false"
>> =============================================================
>> OpenBIOS 1.1 [Aug 31 2018 11:17]
>> Configuration device id QEMU version 1 machine id 3
>> CPUs: 1
>> Memory: 1024M
>> UUID: 00000000-0000-0000-0000-000000000000
>> CPU type PowerPC,970FX
milliseconds isn't unique.
Welcome to OpenBIOS v1.1 built on Aug 31 2018 11:17
0 > boot Trying hd:,\\:tbxi...
>> switching to new context:
MacOS: unable to find a usable NVRAM partition - using offset 0x1400.
Overlap in AddMemoryRelocationEntry().
- dst = 0x00003000, dstLength = 0x00000504, entry->dst = 0x00000000, entry->dst_len = 0x0004DA68.
Overlap in AddMemoryRelocationEntry().
- dst = 0x00003F80, dstLength = 0x00000080, entry->dst = 0x00000000, entry->dst_len = 0x0004DA68.
Overlap in AddMemoryRelocationEntry().
- dst = 0x00003F40, dstLength = 0x00000040, entry->dst = 0x00000000, entry->dst_len = 0x0004DA68.
Overlap in AddMemoryRelocationEntry().
- dst = 0x00003CFC, dstLength = 0x00000204, entry->dst = 0x00000000, entry->dst_len = 0x0004DA68.
Overlap in AddMemoryRelocationEntry().
- dst = 0x00003F00, dstLength = 0x00000040, entry->dst = 0x00000000, entry->dst_len = 0x0004DA68.
Stopping at end of FCODE, due to fatal error (see above).
EXIT
0 >
ELN, nanopico, anyone offer some insight into what's going wrong here?
-
AddMemoryRelocationEntry is used to request that data structures be copied from one location to another when the system boots. It is not supposed to have multiple destinations overlapping, but that somehow happened.
I think that either the Trampoline is really confused with the device tree, or the upper 32 bits of a 64-bit address are being ignored. It's hard to tell. If you could enable the debug logging, you might be able to figure out what is going on.
There are really all sorts of problems with booting the G5. In addition to the Trampoline not knowing how to handle various devices, neither the Trampoline nor the NanoKernel are built to handle 64-bit processors. For instance, the NK does not support the 64-bit memory management architecture. The PTEs are twice as big. The bit positions are different. It will crash hard when it uses the 32-bit mmu code, assuming it doesn't crash before that.
That doesn't mean we can't do it. It just means we will have to do a lot of work.
-
How would I enable debug logging?
-
Set the "AAPL,debug" property on the device tree root node. It looks like Qemu will just let you add this command line option:
-prom-env aapl,debug=13FFF
If you can get to an Open Firmware prompt, you could enable the normal way:
dev / 13FFF encode-int " AAPL,debug" property
-
That's a lot of debug info:
qemu-system-ppc64 -M mac99 -m 1024 -cpu ppc64 -hda ~/os9/os9.img --nographic -prom-env "aapl,debug=13FFF"
>> =============================================================
>> OpenBIOS 1.1 [Aug 31 2018 11:17]
>> Configuration device id QEMU version 1 machine id 3
>> CPUs: 1
>> Memory: 1024M
>> UUID: 00000000-0000-0000-0000-000000000000
>> CPU type PowerPC,970FX
milliseconds isn't unique.
Welcome to OpenBIOS v1.1 built on Aug 31 2018 11:17
Trying hd:,\\:tbxi...
>> switching to new context:
AAPL,debug bit settings (-OR- bits together):
1 * = Print general informative messages.
2 * = Print formatted Mac OS tables (except config/universal info).
4 * = Print formatted config info table.
8 * = Dump Mac OS tables (except config/universal info).
10 * = Print node names while copying the device tree.
20 * = Print property info while copying the device tree.
40 * = Print interrupt-related info.
80 * = Print interrupt tree traversal info.
100 * = Print address resolution info.
200 * = Print NV-RAM info.
400 * = Print Mac OS "universal" info.
800 * = Print "special" node info.
1000 * = Load EtherPrintf utility via parcel for post FCode debugging.
2000 * = Print BOOTP/DHCP/BSDP information.
4000 = Allocate writable ROM aperture.
8000 = Mark Toolbox image as non-cacheable.
10000 * = Print parcel info while copying the device tree.
20000 = Print information on device tree data checksums.
1000000 = Enable the Nanokernel debugger.
2000000 = Display the Nanokernel log during boot.
10000000 = Dont attempt to unhibernate system.
40000000 = Halt after end of FCode (useful if outputting to screen).
MacOS: RTAS not found.
work area logical address = 0x3FAD8000, physical address = 0x3FAD8000.
IsKeyDown: no keys held down
Found parcel 'Mac OS ROM Parcel', type 'rom '.
Heathrow location method better get fixed.
NVRAM path: /nvram@fff04000; result = 15
NVRAM size = 0x00002000.
NVRAM partition offset=00000000, SIG=70, size=00C1, name=' system'
NVRAM partition offset=00000C10, SIG=7F, size=003F, name=' free'
NVRAM partition offset=00001000, SIG=5A, size=0100, name=' wwwwwwwwwww'
MacOS: unable to find a usable NVRAM partition - using offset 0x1400.
MacOS NVRAM partition offset = 0x13f0
Found NVRAM node: /nvram@fff04000
RAM Disk Size: 0
DR Emulator Cache Size: 0
created node 'AAPL,CodePrepare'
parcel 'CodePrepare Node Parcel': Added property 'AAPL,prepare_order'.
node '': decompressing property 'TimeManagerLib'.
parcel 'CodePrepare Node Parcel': Added property 'TimeManagerLib'.
node '': decompressing property 'NVRAMServicesLib'.
parcel 'CodePrepare Node Parcel': Added property 'NVRAMServicesLib'.
MacOS: Found a plug-in for NVRAM.
node '': decompressing property 'RTCServicesLib'.
parcel 'CodePrepare Node Parcel': Added property 'RTCServicesLib'.
MacOS: Found a plug-in for RTC.
created node 'AAPL,CodeRegister'
node '': decompressing property 'NativePowerMgrLib'.
parcel 'CodeRegister Node Parcel': Added property 'NativePowerMgrLib'.
node '': decompressing property 'AGPLib'.
parcel 'CodeRegister Node Parcel': Added property 'AGPLib'.
node '': decompressing property 'EtherPrintfLib'.
parcel 'CodeRegister Node Parcel': Added property 'EtherPrintfLib'.
node '': decompressing property 'StartLib'.
parcel 'CodeRegister Node Parcel': Added property 'StartLib'.
Copying first property 'name' stored at 0x3FB06F7C, devNode 0x3FAD800C
Found parcel 'Property Checksum', type 'psum'.
Copying peer property '#address-cells' stored at 0x3FB06FB0
Copying peer property '#size-cells' stored at 0x3FB06FDC
Copying peer property 'clock-frequency' stored at 0x3FB07008
Copying peer property 'model' stored at 0x3FB07034
Copying peer property 'compatible' stored at 0x3FB07068
Copying peer property 'device_type' stored at 0x3FB070C0
Copying peer property 'system-id' stored at 0x3FB070F0
Copying peer property 'copyright' stored at 0x3FB07128
Copying child device node 'aliases' of node at 0x3FAD800C.
Copying first property 'name' stored at 0x3FB071A0, devNode 0x3FAD8030
Copying peer property 'mac-io' stored at 0x3FB071D0
Copying peer property 'via-cuda' stored at 0x3FB07210
Copying peer property 'adb-keyboard' stored at 0x3FB07258
Copying peer property 'adb-mouse' stored at 0x3FB072B0
Copying peer property 'rtc' stored at 0x3FB07304
Copying peer property 'nvram' stored at 0x3FB07350
Copying peer property 'scca' stored at 0x3FB07380
Copying peer property 'sccb' stored at 0x3FB073CC
Copying peer property 'ide0' stored at 0x3FB07418
Copying peer property 'hd' stored at 0x3FB07468
Copying peer property 'disk' stored at 0x3FB074B8
Copying peer property 'ide1' stored at 0x3FB07508
Copying peer property 'cd' stored at 0x3FB0755C
Copying peer property 'cdrom' stored at 0x3FB075B0
Copying peer property 'keyboard' stored at 0x3FB07604
Copying peer property 'screen' stored at 0x3FB07664
Copying peer property 'kbd' stored at 0x3FB076B0
Copying device node peer 'openprom' of node at 0x3FAD8030.
Copying first property 'name' stored at 0x3FB07710, devNode 0x3FAD803C
Copying peer property 'device_type' stored at 0x3FB07744
Copying peer property 'model' stored at 0x3FB07774
Copying peer property 'relative-addressing' stored at 0x3FB077AC
Copying peer property 'supports-bootinfo' stored at 0x3FB077D4
Copying peer property 'boot-syntax' stored at 0x3FB077FC
Copying child device node 'client-services' of node at 0x3FAD803C.
Copying first property 'name' stored at 0x3FB07828, devNode 0x3FAD8048
Copying device node peer 'options' of node at 0x3FAD803C.
Copying first property 'name' stored at 0x3FB07860, devNode 0x3FAD8054
Copying peer property 'boot-args' stored at 0x3FB07890
Copying peer property 'boot-device' stored at 0x3FB078BC
Copying peer property 'use-generic?' stored at 0x3FB07910
Copying peer property 'boot-script' stored at 0x3FB07940
Copying peer property 'boot-screen' stored at 0x3FB0796C
Copying peer property 'vga-ndrv?' stored at 0x3FB07998
Copying peer property 'virt-size' stored at 0x3FB079C8
Copying peer property 'virt-base' stored at 0x3FB079F4
Copying peer property 'load-base' stored at 0x3FB07A20
Copying peer property 'real-size' stored at 0x3FB07A50
Copying peer property 'real-base' stored at 0x3FB07A7C
Copying peer property 'real-mode?' stored at 0x3FB07AA8
Copying peer property 'little-endian?' stored at 0x3FB07AD8
Copying peer property 'scroll-lock' stored at 0x3FB07B08
Copying peer property 'skip-netboot?' stored at 0x3FB07B38
Copying peer property 'default-mac-address' stored at 0x3FB07B68
Copying peer property 'pci-probe-mask' stored at 0x3FB07B98
Copying peer property 'selftest-#megs' stored at 0x3FB07BC4
Copying peer property 'screen-#rows' stored at 0x3FB07BF0
Copying peer property 'screen-#columns' stored at 0x3FB07C1C
Copying peer property 'output-device' stored at 0x3FB07C48
Copying peer property 'input-device' stored at 0x3FB07C94
Copying peer property 'use-nvramrc?' stored at 0x3FB07CE0
Copying peer property 'oem-logo?' stored at 0x3FB07D10
Copying peer property 'oem-banner' stored at 0x3FB07D40
Copying peer property 'oem-banner?' stored at 0x3FB07D6C
Copying peer property 'nvramrc' stored at 0x3FB07D9C
Copying peer property 'fcode-debug?' stored at 0x3FB07DC8
Copying peer property 'diag-switch?' stored at 0x3FB07DF8
Copying peer property 'boot-file' stored at 0x3FB07E28
Copying peer property 'boot-command' stored at 0x3FB07E54
Copying peer property 'auto-boot?' stored at 0x3FB07E84
Copying peer property 'aapl,debug' stored at 0x3FB07EB4
Copying device node peer 'chosen' of node at 0x3FAD8054.
Copying first property 'name' stored at 0x3FB07EE4, devNode 0x3FAD8060
Copying peer property 'stdin' stored at 0x3FB07F14
Copying peer property 'stdout' stored at 0x3FB07F40
Copying peer property 'nvram' stored at 0x3FB07F6C
Copying peer property 'mmu' stored at 0x3FB07F98
Copying peer property 'rtc' stored at 0x3FB07FC4
Copying peer property 'memory' stored at 0x3FB07FF0
Copying peer property 'bootargs' stored at 0x3FB0801C
Copying peer property 'bootpath' stored at 0x3FB08048
Copying device node peer 'builtin' of node at 0x3FAD8060.
Copying first property 'name' stored at 0x3FB080A4, devNode 0x3FAD806C
Copying child device node 'console' of node at 0x3FAD806C.
Copying first property 'name' stored at 0x3FB080D4, devNode 0x3FAD8078
Copying device node peer 'packages' of node at 0x3FAD806C.
Copying first property 'name' stored at 0x3FB08104, devNode 0x3FAD8084
Copying child device node 'cmdline' of node at 0x3FAD8084.
Copying first property 'name' stored at 0x3FB08138, devNode 0x3FAD8090
Copying device node peer 'disk-label' of node at 0x3FAD8090.
Copying first property 'name' stored at 0x3FB08168, devNode 0x3FAD809C
Copying device node peer 'terminal-emulator' of node at 0x3FAD809C.
Copying first property 'name' stored at 0x3FB0819C, devNode 0x3FAD80A8
Copying device node peer 'deblocker' of node at 0x3FAD80A8.
Copying first property 'name' stored at 0x3FB081D8, devNode 0x3FAD80B4
Copying device node peer 'hfsplus-files' of node at 0x3FAD80B4.
Copying first property 'name' stored at 0x3FB0820C, devNode 0x3FAD80C0
Copying device node peer 'hfs-files' of node at 0x3FAD80C0.
Copying first property 'name' stored at 0x3FB08244, devNode 0x3FAD80CC
Copying device node peer 'ext2-files' of node at 0x3FAD80CC.
Copying first property 'name' stored at 0x3FB08278, devNode 0x3FAD80D8
Copying device node peer 'iso9660-files' of node at 0x3FAD80D8.
Copying first property 'name' stored at 0x3FB082AC, devNode 0x3FAD80E4
Copying device node peer 'grubfs-files' of node at 0x3FAD80E4.
Copying first property 'name' stored at 0x3FB082E4, devNode 0x3FAD80F0
Copying device node peer 'mac-parts' of node at 0x3FAD80F0.
Copying first property 'name' stored at 0x3FB0831C, devNode 0x3FAD80FC
Copying peer property 'selected-partition-args' stored at 0x3FB08350
Copying device node peer 'pc-parts' of node at 0x3FAD80FC.
Copying first property 'name' stored at 0x3FB08384, devNode 0x3FAD8108
Copying device node peer 'xcoff-loader' of node at 0x3FAD8108.
Copying first property 'name' stored at 0x3FB083B8, devNode 0x3FAD8114
Copying device node peer 'elf-loader' of node at 0x3FAD8114.
Copying first property 'name' stored at 0x3FB083F0, devNode 0x3FAD8120
Copying device node peer 'bootinfo-loader' of node at 0x3FAD8120.
Copying first property 'name' stored at 0x3FB08424, devNode 0x3FAD812C
Copying device node peer 'cpus' of node at 0x3FAD8084.
Copying first property 'name' stored at 0x3FB0845C, devNode 0x3FAD8138
Copying peer property '#address-cells' stored at 0x3FB0848C
Copying peer property '#size-cells' stored at 0x3FB084B8
Copying child device node 'PowerPC,970FX' of node at 0x3FAD8138.
Copying first property 'name' stored at 0x3FB084E4, devNode 0x3FAD8144
Copying peer property 'device_type' stored at 0x3FB0851C
Copying peer property 'cpu-version' stored at 0x3FB08548
Copying peer property 'd-cache-size' stored at 0x3FB08574
Copying peer property 'i-cache-size' stored at 0x3FB085A0
Copying peer property 'd-cache-sets' stored at 0x3FB085CC
Copying peer property 'i-cache-sets' stored at 0x3FB085F8
Copying peer property 'd-cache-block-size' stored at 0x3FB08624
Copying peer property 'i-cache-block-size' stored at 0x3FB08650
Copying peer property 'tlb-sets' stored at 0x3FB0867C
Copying peer property 'tlb-size' stored at 0x3FB086A8
Copying peer property 'timebase-frequency' stored at 0x3FB086D4
Copying peer property 'clock-frequency' stored at 0x3FB08700
Copying peer property 'bus-frequency' stored at 0x3FB0872C
Copying peer property 'state' stored at 0x3FB08758
Copying peer property 'reservation-granule-size' stored at 0x3FB08788
Copying peer property 'reg' stored at 0x3FB087B4
Copying peer property '64-bit' stored at 0x3FB087E0
Copying peer property 'available' stored at 0x3FB08808
Copying peer property 'translations' stored at 0x3FB088A0
Copying device node peer 'memory' of node at 0x3FAD8138.
Copying first property 'name' stored at 0x3FB089D8, devNode 0x3FAD8150
Copying peer property 'device_type' stored at 0x3FB08A08
Copying peer property 'reg' stored at 0x3FB08A38
Copying peer property 'available' stored at 0x3FB08A68
Copying device node peer 'rom' of node at 0x3FAD8150.
Copying first property 'name' stored at 0x3FB08B00, devNode 0x3FAD815C
Copying peer property 'reg' stored at 0x3FB08B2C
Copying peer property '#address-cells' stored at 0x3FB08B5C
Copying peer property 'ranges' stored at 0x3FB08B88
Copying child device node 'macos' of node at 0x3FAD815C.
node name 'macos': Matched parcel 'macos', device_type ''.
Copying first property 'name' stored at 0x3FB08BBC, devNode 0x3FAD8168
Copying peer property 'AAPL,toolbox-parcels' stored at 0x3FB08BEC
node 'macos': Added property 'MacOSROMFile-version'.
Copying device node peer 'pci' of node at 0x3FAD815C.
Copying first property 'name' stored at 0x3FB08C4C, devNode 0x3FAD8174
Copying peer property 'reg' stored at 0x3FB08C78
Copying peer property 'vendor-id' stored at 0x3FB08CA8
Copying peer property 'device-id' stored at 0x3FB08CD4
Copying peer property 'revision-id' stored at 0x3FB08D00
Copying peer property 'class-code' stored at 0x3FB08D2C
Copying peer property 'min-grant' stored at 0x3FB08D58
Copying peer property 'max-latency' stored at 0x3FB08D84
Copying peer property 'devsel-speed' stored at 0x3FB08DB0
Copying peer property 'subsystem-vendor-id' stored at 0x3FB08DDC
Copying peer property 'subsystem-id' stored at 0x3FB08E08
Copying peer property 'cache-line-size' stored at 0x3FB08E34
Copying peer property 'device_type' stored at 0x3FB08E60
Copying peer property 'model' stored at 0x3FB08E8C
Copying peer property 'compatible' stored at 0x3FB08EC4
Copying peer property '#address-cells' stored at 0x3FB08EF4
Copying peer property '#size-cells' stored at 0x3FB08F20
Copying peer property '#interrupt-cells' stored at 0x3FB08F4C
Copying peer property 'ranges' stored at 0x3FB08F78
Copying peer property 'bus-range' stored at 0x3FB08FD0
Copying peer property 'available' stored at 0x3FB09000
Copying peer property 'interrupt-parent' stored at 0x3FB09050
Copying peer property 'interrupt-map' stored at 0x3FB0907C
Copying peer property 'interrupt-map-mask' stored at 0x3FB090DC
Copying child device node 'mac-io' of node at 0x3FAD8174.
matching assigned address:
Dumping 20 bytes @ 0x001125A0
001125A0: 02006010 00000000 80000000 00000000
001125B0: 00080000
HandleSpecialNode: Mac-IO base address = 0x80000000.
Copying first property 'name' stored at 0x3FB09114, devNode 0x3FAD8180
Copying peer property 'vendor-id' stored at 0x3FB09144
Copying peer property 'device-id' stored at 0x3FB09170
Copying peer property 'revision-id' stored at 0x3FB0919C
Copying peer property 'class-code' stored at 0x3FB091C8
Copying peer property 'min-grant' stored at 0x3FB091F4
Copying peer property 'max-latency' stored at 0x3FB09220
Copying peer property 'devsel-speed' stored at 0x3FB0924C
Copying peer property 'subsystem-vendor-id' stored at 0x3FB09278
Copying peer property 'subsystem-id' stored at 0x3FB092A4
Copying peer property 'cache-line-size' stored at 0x3FB092D0
Copying peer property 'device_type' stored at 0x3FB092FC
Copying peer property 'model' stored at 0x3FB0932C
Copying peer property 'compatible' stored at 0x3FB09364
Copying peer property '#address-cells' stored at 0x3FB09398
Copying peer property '#size-cells' stored at 0x3FB093C4
Copying peer property '#interrupt-cells' stored at 0x3FB093F0
Copying peer property 'assigned-addresses' stored at 0x3FB0941C
Creating property - 'AAPL,address' (size = 4)
Creating property 'AAPL,address' (size = 0x4); stored at 0x3FB09458. Belongs to devNode 0x3FAD8180
Copying peer property 'reg' stored at 0x3FB09484
Copying peer property 'ranges' stored at 0x3FB094D4
Copying peer property 'interrupt-parent' stored at 0x3FB09510
Copying child device node 'via-cuda' of node at 0x3FAD8180.
HandleSpecialNode: Cuda detected, VIA base address = 0x80016000.
compatible 'cuda': Matched parcel 'cuda', device_type 'via-cuda'.
Copying first property 'name' stored at 0x3FB0953C, devNode 0x3FAD818C
Copying peer property 'device_type' stored at 0x3FB09570
Copying peer property '#address-cells' stored at 0x3FB095A4
Copying peer property '#size-cells' stored at 0x3FB095D0
Copying peer property 'compatible' stored at 0x3FB095FC
Copying peer property 'reg' stored at 0x3FB0962C
Creating property - 'AAPL,address' (size = 4)
Creating property 'AAPL,address' (size = 0x4); stored at 0x3FB0965C. Belongs to devNode 0x3FAD818C
Copying peer property 'interrupts' stored at 0x3FB09688
---------------- Node 'via-cuda' has 1 interrupt(s). ----------------
Processing unit_interrupt_specifier:
Raw unit_int_specifier : 00000019 00000000
unit_interrupt_specifer[0] = 25
(ua_size = 0, is_size = 2) setting edge[0] to 1
OpenPIC setup: vectorIndex 0, intSource 25, level 1, sense 0, polarity 0
Copying peer property '#interrupt-cells' stored at 0x3FB09768
Copying peer property 'interrupt-parent' stored at 0x3FB09794
node 'via-cuda': Added property 'pef,AAPL,MacOS,PowerPC,register'.
node 'via-cuda': decompressing property 'pef,AAPL,MacOS,PowerPC,register'.
node 'via-cuda': Added property 'code,AAPL,MacOS,name'.
MacOS: Found a PowerPlugin.
Copying child device node 'adb' of node at 0x3FAD818C.
HandleSpecialNode: Cuda ADB detected.
Copying first property 'name' stored at 0x3FB0D3A0, devNode 0x3FAD8198
Copying peer property 'device_type' stored at 0x3FB0D3CC
Copying peer property 'compatible' stored at 0x3FB0D3F8
Copying peer property '#address-cells' stored at 0x3FB0D424
Copying peer property '#size-cells' stored at 0x3FB0D450
Copying child device node 'keyboard' of node at 0x3FAD8198.
Copying first property 'name' stored at 0x3FB0D47C, devNode 0x3FAD81A4
Copying peer property 'device_type' stored at 0x3FB0D4B0
Copying peer property 'reg' stored at 0x3FB0D4E4
Copying device node peer 'mouse' of node at 0x3FAD81A4.
Copying first property 'name' stored at 0x3FB0D510, devNode 0x3FAD81B0
Copying peer property 'device_type' stored at 0x3FB0D540
Copying peer property 'reg' stored at 0x3FB0D570
Copying peer property '#buttons' stored at 0x3FB0D59C
Copying device node peer 'rtc' of node at 0x3FAD8198.
parent name 'via-cuda': Matched parcel 'via-cuda', device_type 'rtc'.
Copying first property 'name' stored at 0x3FB0D5C8, devNode 0x3FAD81BC
Copying peer property 'device_type' stored at 0x3FB0D5F4
Copying peer property 'compatible' stored at 0x3FB0D620
node 'rtc': Added property 'driver,AAPL,MacOS,PowerPC'.
node 'rtc': decompressing property 'driver,AAPL,MacOS,PowerPC'.
Copying device node peer 'power-mgt' of node at 0x3FAD81BC.
HandleSpecialNode: Cuda Power Mgt detected.
Copying first property 'name' stored at 0x3FB0D9FC, devNode 0x3FAD81C8
Copying peer property 'device_type' stored at 0x3FB0DA30
Copying peer property 'mgt-kind' stored at 0x3FB0DA64
Copying peer property 'compatible' stored at 0x3FB0DAA4
Copying device node peer 'escc' of node at 0x3FAD818C.
Copying first property 'name' stored at 0x3FB0DAD4, devNode 0x3FAD81D4
Copying peer property '#address-cells' stored at 0x3FB0DB04
Copying peer property 'reg' stored at 0x3FB0DB30
Creating property - 'AAPL,address' (size = 4)
Creating property 'AAPL,address' (size = 0x4); stored at 0x3FB0DB60. Belongs to devNode 0x3FAD81D4
Copying peer property 'device_type' stored at 0x3FB0DB8C
Copying peer property 'compatible' stored at 0x3FB0DBBC
Copying peer property 'ranges' stored at 0x3FB0DBF4
Copying child device node 'ch-a' of node at 0x3FAD81D4.
HandleSpecialNode: ch-a slot-name detected.
Copying first property 'name' stored at 0x3FB0DC1C, devNode 0x3FAD81E0
Copying peer property 'device_type' stored at 0x3FB0DC4C
Copying peer property 'compatible' stored at 0x3FB0DC7C
Copying peer property 'reg' stored at 0x3FB0DCB0
Creating property - 'AAPL,address' (size = 20)
Creating property 'AAPL,address' (size = 0x14); stored at 0x3FB0DD00. Belongs to devNode 0x3FAD81E0
Copying peer property 'interrupts' stored at 0x3FB0DD3C
---------------- Node 'ch-a' has 3 interrupt(s). ----------------
Processing unit_interrupt_specifier:
Raw unit_int_specifier : 00000025 00000001
unit_interrupt_specifer[0] = 37
(ua_size = 0, is_size = 2) setting edge[0] to 0
Processing unit_interrupt_specifier:
Raw unit_int_specifier : 00000004 00000000
unit_interrupt_specifer[0] = 4
(ua_size = 0, is_size = 2) setting edge[1] to 1
Processing unit_interrupt_specifier:
Raw unit_int_specifier : 00000005 00000000
unit_interrupt_specifer[0] = 5
(ua_size = 0, is_size = 2) setting edge[2] to 1
OpenPIC setup: vectorIndex 1, intSource 37, level 4, sense 1, polarity 0
OpenPIC setup: vectorIndex 2, intSource 4, level 4, sense 0, polarity 0
OpenPIC setup: vectorIndex 3, intSource 5, level 4, sense 0, polarity 0
Copying peer property 'slot-names' stored at 0x3FB0DE4C
Copying peer property 'interrupt-parent' stored at 0x3FB0DE78
Copying device node peer 'ch-b' of node at 0x3FAD81E0.
HandleSpecialNode: ch-b slot-name detected.
Copying first property 'name' stored at 0x3FB0DEA4, devNode 0x3FAD81EC
Copying peer property 'device_type' stored at 0x3FB0DED4
Copying peer property 'compatible' stored at 0x3FB0DF04
Copying peer property 'reg' stored at 0x3FB0DF38
Creating property - 'AAPL,address' (size = 20)
Creating property 'AAPL,address' (size = 0x14); stored at 0x3FB0DF88. Belongs to devNode 0x3FAD81EC
Copying peer property 'interrupts' stored at 0x3FB0DFC4
---------------- Node 'ch-b' has 3 interrupt(s). ----------------
Processing unit_interrupt_specifier:
Raw unit_int_specifier : 00000024 00000001
unit_interrupt_specifer[0] = 36
(ua_size = 0, is_size = 2) setting edge[0] to 0
Processing unit_interrupt_specifier:
Raw unit_int_specifier : 00000006 00000000
unit_interrupt_specifer[0] = 6
(ua_size = 0, is_size = 2) setting edge[1] to 1
Processing unit_interrupt_specifier:
Raw unit_int_specifier : 00000007 00000000
unit_interrupt_specifer[0] = 7
(ua_size = 0, is_size = 2) setting edge[2] to 1
OpenPIC setup: vectorIndex 4, intSource 36, level 4, sense 1, polarity 0
OpenPIC setup: vectorIndex 5, intSource 6, level 4, sense 0, polarity 0
OpenPIC setup: vectorIndex 6, intSource 7, level 4, sense 0, polarity 0
Copying peer property 'slot-names' stored at 0x3FB0E0D4
Copying peer property 'interrupt-parent' stored at 0x3FB0E100
Copying device node peer 'escc-legacy' of node at 0x3FAD81D4.
HandleSpecialNode: SCC legacy base address = 0x80012000.
Copying first property 'name' stored at 0x3FB0E12C, devNode 0x3FAD81F8
Copying peer property '#address-cells' stored at 0x3FB0E160
Copying peer property 'reg' stored at 0x3FB0E18C
Creating property - 'AAPL,address' (size = 4)
Creating property 'AAPL,address' (size = 0x4); stored at 0x3FB0E1BC. Belongs to devNode 0x3FAD81F8
Copying peer property 'device_type' stored at 0x3FB0E1E8
Copying peer property 'compatible' stored at 0x3FB0E21C
Copying peer property 'ranges' stored at 0x3FB0E250
Copying child device node 'ch-a' of node at 0x3FAD81F8.
HandleSpecialNode: ch-a slot-name detected.
Copying first property 'name' stored at 0x3FB0E278, devNode 0x3FAD8204
Copying peer property 'device_type' stored at 0x3FB0E2A8
Copying peer property 'compatible' stored at 0x3FB0E2D8
Copying peer property 'reg' stored at 0x3FB0E30C
Creating property - 'AAPL,address' (size = 20)
Creating property 'AAPL,address' (size = 0x14); stored at 0x3FB0E35C. Belongs to devNode 0x3FAD8204
Copying peer property 'interrupts' stored at 0x3FB0E398
---------------- Node 'ch-a' has 3 interrupt(s). ----------------
Processing unit_interrupt_specifier:
Raw unit_int_specifier : 00000025 00000001
unit_interrupt_specifer[0] = 37
(ua_size = 0, is_size = 2) setting edge[0] to 0
Processing unit_interrupt_specifier:
Raw unit_int_specifier : 00000004 00000000
unit_interrupt_specifer[0] = 4
(ua_size = 0, is_size = 2) setting edge[1] to 1
Processing unit_interrupt_specifier:
Raw unit_int_specifier : 00000005 00000000
unit_interrupt_specifer[0] = 5
(ua_size = 0, is_size = 2) setting edge[2] to 1
OpenPIC setup: vectorIndex 1, intSource 37, level 4, sense 1, polarity 0
OpenPIC setup: vectorIndex 2, intSource 4, level 4, sense 0, polarity 0
OpenPIC setup: vectorIndex 3, intSource 5, level 4, sense 0, polarity 0
Copying peer property 'slot-names' stored at 0x3FB0E4A8
Copying peer property 'interrupt-parent' stored at 0x3FB0E4D4
Copying device node peer 'ch-b' of node at 0x3FAD8204.
HandleSpecialNode: ch-b slot-name detected.
Copying first property 'name' stored at 0x3FB0E500, devNode 0x3FAD8210
Copying peer property 'device_type' stored at 0x3FB0E530
Copying peer property 'compatible' stored at 0x3FB0E560
Copying peer property 'reg' stored at 0x3FB0E594
Creating property - 'AAPL,address' (size = 20)
Creating property 'AAPL,address' (size = 0x14); stored at 0x3FB0E5E4. Belongs to devNode 0x3FAD8210
Copying peer property 'interrupts' stored at 0x3FB0E620
---------------- Node 'ch-b' has 3 interrupt(s). ----------------
Processing unit_interrupt_specifier:
Raw unit_int_specifier : 00000024 00000001
unit_interrupt_specifer[0] = 36
(ua_size = 0, is_size = 2) setting edge[0] to 0
Processing unit_interrupt_specifier:
Raw unit_int_specifier : 00000006 00000000
unit_interrupt_specifer[0] = 6
(ua_size = 0, is_size = 2) setting edge[1] to 1
Processing unit_interrupt_specifier:
Raw unit_int_specifier : 00000007 00000000
unit_interrupt_specifer[0] = 7
(ua_size = 0, is_size = 2) setting edge[2] to 1
OpenPIC setup: vectorIndex 4, intSource 36, level 4, sense 1, polarity 0
OpenPIC setup: vectorIndex 5, intSource 6, level 4, sense 0, polarity 0
OpenPIC setup: vectorIndex 6, intSource 7, level 4, sense 0, polarity 0
Copying peer property 'slot-names' stored at 0x3FB0E730
Copying peer property 'interrupt-parent' stored at 0x3FB0E75C
Copying device node peer 'ata-3' of node at 0x3FAD81F8.
compatible 'keylargo-ata': Matched parcel 'keylargo-ata', device_type 'ata'.
Copying first property 'name' stored at 0x3FB0E788, devNode 0x3FAD821C
Copying peer property 'device_type' stored at 0x3FB0E7B8
Copying peer property '#address-cells' stored at 0x3FB0E7E4
Copying peer property '#size-cells' stored at 0x3FB0E810
Copying peer property 'compatible' stored at 0x3FB0E83C
Copying peer property 'model' stored at 0x3FB0E874
Copying peer property 'AAPL,connector' stored at 0x3FB0E8A4
Copying peer property 'AAPL,pio-timing' stored at 0x3FB0E8D0
Copying peer property 'interrupts' stored at 0x3FB0E918
---------------- Node 'ata-3' has 2 interrupt(s). ----------------
Processing unit_interrupt_specifier:
Raw unit_int_specifier : 0000000D 00000001
unit_interrupt_specifer[0] = 13
(ua_size = 0, is_size = 2) setting edge[0] to 0
Processing unit_interrupt_specifier:
Raw unit_int_specifier : 00000002 00000000
unit_interrupt_specifer[0] = 2
(ua_size = 0, is_size = 2) setting edge[1] to 1
OpenPIC setup: vectorIndex 7, intSource 13, level 2, sense 1, polarity 0
OpenPIC setup: vectorIndex 8, intSource 2, level 4, sense 0, polarity 0
Copying peer property '#interrupt-cells' stored at 0x3FB0EA10
Copying peer property 'reg' stored at 0x3FB0EA3C
Creating property - 'AAPL,address' (size = 8)
Creating property 'AAPL,address' (size = 0x8); stored at 0x3FB0EA74. Belongs to devNode 0x3FAD821C
Copying peer property 'AAPL,bus-id' stored at 0x3FB0EAA4
Copying peer property 'interrupt-parent' stored at 0x3FB0EAD0
node 'ata-3': Added property 'driver,AAPL,MacOS,PowerPC'.
node 'ata-3': decompressing property 'driver,AAPL,MacOS,PowerPC'.
Copying child device node 'disk' of node at 0x3FAD821C.
Copying first property 'name' stored at 0x3FB14868, devNode 0x3FAD8228
Copying peer property 'device_type' stored at 0x3FB14898
Copying peer property '#address-cells' stored at 0x3FB148C8
Copying peer property '#size-cells' stored at 0x3FB148F4
Copying peer property 'reg' stored at 0x3FB14920
Copying device node peer 'ata-3' of node at 0x3FAD821C.
compatible 'keylargo-ata': Matched parcel 'keylargo-ata', device_type 'ata'.
Copying first property 'name' stored at 0x3FB1494C, devNode 0x3FAD8234
Copying peer property 'device_type' stored at 0x3FB1497C
Copying peer property '#address-cells' stored at 0x3FB149A8
Copying peer property '#size-cells' stored at 0x3FB149D4
Copying peer property 'compatible' stored at 0x3FB14A00
Copying peer property 'model' stored at 0x3FB14A38
Copying peer property 'AAPL,connector' stored at 0x3FB14A68
Copying peer property 'AAPL,pio-timing' stored at 0x3FB14A94
Copying peer property 'interrupts' stored at 0x3FB14ADC
---------------- Node 'ata-3' has 2 interrupt(s). ----------------
Processing unit_interrupt_specifier:
Raw unit_int_specifier : 0000000E 00000001
unit_interrupt_specifer[0] = 14
(ua_size = 0, is_size = 2) setting edge[0] to 0
Processing unit_interrupt_specifier:
Raw unit_int_specifier : 00000003 00000000
unit_interrupt_specifer[0] = 3
(ua_size = 0, is_size = 2) setting edge[1] to 1
OpenPIC setup: vectorIndex 9, intSource 14, level 2, sense 1, polarity 0
OpenPIC setup: vectorIndex 10, intSource 3, level 4, sense 0, polarity 0
Copying peer property '#interrupt-cells' stored at 0x3FB14BD4
Copying peer property 'reg' stored at 0x3FB14C00
Creating property - 'AAPL,address' (size = 8)
Creating property 'AAPL,address' (size = 0x8); stored at 0x3FB14C38. Belongs to devNode 0x3FAD8234
Copying peer property 'AAPL,bus-id' stored at 0x3FB14C68
Copying peer property 'interrupt-parent' stored at 0x3FB14C94
node 'ata-3': Added property 'driver,AAPL,MacOS,PowerPC'.
node 'ata-3': decompressing property 'driver,AAPL,MacOS,PowerPC'.
Copying child device node 'cdrom' of node at 0x3FAD8234.
Copying first property 'name' stored at 0x3FB1AA2C, devNode 0x3FAD8240
Copying peer property 'device_type' stored at 0x3FB1AA5C
Copying peer property '#address-cells' stored at 0x3FB1AA8C
Copying peer property '#size-cells' stored at 0x3FB1AAB8
Copying peer property 'reg' stored at 0x3FB1AAE4
Copying device node peer 'interrupt-controller' of node at 0x3FAD8234.
HandleSpecialNode: Host OpenPIC has base address = 0x80040000.
Copying first property 'name' stored at 0x3FB1AB10, devNode 0x3FAD824C
Copying peer property 'device_type' stored at 0x3FB1AB50
Copying peer property 'compatible' stored at 0x3FB1AB84
Copying peer property 'built-in' stored at 0x3FB1ABBC
Copying peer property 'reg' stored at 0x3FB1ABE4
Creating property - 'AAPL,address' (size = 4)
Creating property 'AAPL,address' (size = 0x4); stored at 0x3FB1AC14. Belongs to devNode 0x3FAD824C
Copying peer property '#interrupt-cells' stored at 0x3FB1AC40
Copying peer property '#address-cells' stored at 0x3FB1AC6C
Copying peer property 'interrupt-controller' stored at 0x3FB1AC98
Copying peer property 'clock-frequency' stored at 0x3FB1ACC0
Copying device node peer 'usb' of node at 0x3FAD8180.
Copying first property 'name' stored at 0x3FB1ACEC, devNode 0x3FAD8258
Copying peer property 'vendor-id' stored at 0x3FB1AD18
Copying peer property 'device-id' stored at 0x3FB1AD44
Copying peer property 'revision-id' stored at 0x3FB1AD70
Copying peer property 'class-code' stored at 0x3FB1AD9C
Copying peer property 'interrupts' stored at 0x3FB1ADC8
---------------- Node 'usb' has 1 interrupt(s). ----------------
Processing unit_interrupt_specifier:
Raw unit_int_specifier : 00006800 00000000 00000000 00000001
Interrupt-map-mask values: 00FFF800 00000000 00000000 00000007
Comparing interrupt-map entries to this unit_interrupt_specifier:
Masked unit_int_specifier: 00006800 00000000 00000000 00000001
Interrupt-map child spec : 00006800 00000000 00000000 00000001
New unit_int_specifier : 0000001C 00000001
unit_interrupt_specifer[0] = 28
(ua_size = 0, is_size = 2) setting edge[0] to 0
OpenPIC setup: vectorIndex 11, intSource 28, level 2, sense 1, polarity 0
Copying peer property 'min-grant' stored at 0x3FB1AEA4
Copying peer property 'max-latency' stored at 0x3FB1AED0
Copying peer property 'devsel-speed' stored at 0x3FB1AEFC
Copying peer property 'subsystem-vendor-id' stored at 0x3FB1AF28
Copying peer property 'subsystem-id' stored at 0x3FB1AF54
Copying peer property 'cache-line-size' stored at 0x3FB1AF80
Copying peer property 'device_type' stored at 0x3FB1AFAC
Copying peer property 'compatible' stored at 0x3FB1AFD8
Copying peer property '#address-cells' stored at 0x3FB1B01C
Copying peer property 'assigned-addresses' stored at 0x3FB1B048
Creating property - 'AAPL,address' (size = 4)
Creating property 'AAPL,address' (size = 0x4); stored at 0x3FB1B084. Belongs to devNode 0x3FAD8258
Copying peer property 'reg' stored at 0x3FB1B0B0
Copying child device node 'keyboard' of node at 0x3FAD8258.
Copying first property 'name' stored at 0x3FB1B100, devNode 0x3FAD8264
Copying peer property 'device_type' stored at 0x3FB1B134
Copying device node peer 'QEMU,VGA' of node at 0x3FAD8258.
device_type 'display': Matched parcel 'cofb', device_type 'display'.
Copying first property 'name' stored at 0x3FB1B168, devNode 0x3FAD8270
Copying peer property 'vendor-id' stored at 0x3FB1B19C
Copying peer property 'device-id' stored at 0x3FB1B1C8
Copying peer property 'revision-id' stored at 0x3FB1B1F4
Copying peer property 'class-code' stored at 0x3FB1B220
Copying peer property 'min-grant' stored at 0x3FB1B24C
Copying peer property 'max-latency' stored at 0x3FB1B278
Copying peer property 'devsel-speed' stored at 0x3FB1B2A4
Copying peer property 'subsystem-vendor-id' stored at 0x3FB1B2D0
Copying peer property 'subsystem-id' stored at 0x3FB1B2FC
Copying peer property 'cache-line-size' stored at 0x3FB1B328
Copying peer property 'device_type' stored at 0x3FB1B354
Copying peer property 'model' stored at 0x3FB1B384
Copying peer property 'compatible' stored at 0x3FB1B3B8
Copying peer property 'assigned-addresses' stored at 0x3FB1B3E4
Creating property - 'AAPL,address' (size = 8)
Creating property 'AAPL,address' (size = 0x8); stored at 0x3FB1B434. Belongs to devNode 0x3FAD8270
Copying peer property 'reg' stored at 0x3FB1B464
Copying peer property 'width' stored at 0x3FB1B4C8
Copying peer property 'height' stored at 0x3FB1B4F4
Copying peer property 'depth' stored at 0x3FB1B520
Copying peer property 'linebytes' stored at 0x3FB1B54C
Copying peer property 'driver,AAPL,MacOS,PowerPC' stored at 0x3FB1B578
node 'QEMU,VGA': Did NOT replace property 'driver,AAPL,MacOS,PowerPC'.
node 'QEMU,VGA': Property NOT added (already loaded) 'driver,AAPL,MacOS,PowerPC'.
Copying device node peer 'NE2000' of node at 0x3FAD8270.
Copying first property 'name' stored at 0x3FB1EF44, devNode 0x3FAD827C
Copying peer property 'vendor-id' stored at 0x3FB1EF74
Copying peer property 'device-id' stored at 0x3FB1EFA0
Copying peer property 'revision-id' stored at 0x3FB1EFCC
Copying peer property 'class-code' stored at 0x3FB1EFF8
Copying peer property 'interrupts' stored at 0x3FB1F024
---------------- Node 'NE2000' has 1 interrupt(s). ----------------
Processing unit_interrupt_specifier:
Raw unit_int_specifier : 00007800 00000000 00000000 00000001
Interrupt-map-mask values: 00FFF800 00000000 00000000 00000007
Comparing interrupt-map entries to this unit_interrupt_specifier:
Masked unit_int_specifier: 00007800 00000000 00000000 00000001
Interrupt-map child spec : 00006800 00000000 00000000 00000001
Interrupt-map child spec : 00007800 00000000 00000000 00000001
New unit_int_specifier : 0000001E 00000001
unit_interrupt_specifer[0] = 30
(ua_size = 0, is_size = 2) setting edge[0] to 0
OpenPIC setup: vectorIndex 12, intSource 30, level 2, sense 1, polarity 0
Copying peer property 'min-grant' stored at 0x3FB1F100
Copying peer property 'max-latency' stored at 0x3FB1F12C
Copying peer property 'devsel-speed' stored at 0x3FB1F158
Copying peer property 'subsystem-vendor-id' stored at 0x3FB1F184
Copying peer property 'subsystem-id' stored at 0x3FB1F1B0
Copying peer property 'cache-line-size' stored at 0x3FB1F1DC
Copying peer property 'device_type' stored at 0x3FB1F208
Copying peer property 'model' stored at 0x3FB1F238
Copying peer property 'assigned-addresses' stored at 0x3FB1F26C
Creating property - 'AAPL,address' (size = 4)
Creating property 'AAPL,address' (size = 0x4); stored at 0x3FB1F2A8. Belongs to devNode 0x3FAD827C
Copying peer property 'reg' stored at 0x3FB1F2D4
Copying peer property 'network-type' stored at 0x3FB1F324
Copying peer property 'removable' stored at 0x3FB1F358
Copying peer property 'category' stored at 0x3FB1F388
Copying device node peer 'nvram' of node at 0x3FAD8174.
compatible 'nvram,flash': Matched parcel 'nvram,flash', device_type 'nvram'.
Copying first property 'name' stored at 0x3FB1F3B4, devNode 0x3FAD8288
Copying peer property '#bytes' stored at 0x3FB1F3E4
Copying peer property 'reg' stored at 0x3FB1F410
Copying peer property 'device_type' stored at 0x3FB1F440
Copying peer property 'compatible' stored at 0x3FB1F470
node 'nvram': Added property 'driver,AAPL,MacOS,PowerPC'.
node 'nvram': decompressing property 'driver,AAPL,MacOS,PowerPC'.
Copying device node peer 'uni-n' of node at 0x3FAD8288.
Copying first property 'name' stored at 0x3FB1FFA8, devNode 0x3FAD8294
Copying peer property 'device_type' stored at 0x3FB1FFD8
Copying peer property 'compatible' stored at 0x3FB20014
Copying peer property 'device-rev' stored at 0x3FB20048
Copying peer property 'reg' stored at 0x3FB20074
MacOS: found RTAS replacement plug-ins -- tossing RTAS.
Creating dynamic ProductInfo & Friends
-- Dynamic ProductInfoPtr (logical) = 3FB200A4
-- SizeOf( ProductInfo ) = 108
-- Converting UniveralInfoTableBase to 68k logical address 3FB200A4.
Initializing ProductInfo record
-- Initializing productInfoVers to 2.
Initializing static section of DecoderInfoPrivate.
Initializing DecoderTable.
-- Initializing (logical) ROMAddr (which is ALWAYS FFC00000).
-- Initializing OpenPICBaseAddr.
---- OpenPICAddr = 80040000.
-- Initializing HeathrowBaseAddr.
-- Initializing VIA1 address.
---- VIA1Addr = 80016000.
-- Initializing SCC addresses.
---- SCC base address = 80012000.
-- Initializing Mesh SCSI information.
-- Initializing ADB information.
---- ADB (of some sort) detected.
-- ASSUMPTION -- we ALWAYS have some sort of ATA.
-- Initializing Sound information.
---- No Sound (of some sort) detected!
-- Initializing extValid bits.
---- extValid bits set to 03000006.
-- Initializing extValid1 bits.
---- extValid1 bits set to 0780880E.
-- Initializing HwCfgWord bits.
---- HwCfgWord bits set to 0480.
Dynamic ProductInfo Table:
Dumping 108 bytes @ 0x3FB200A4
3FB200A4: 00000094 00000000 00000000 00000000
3FB200B4: 0480001A 00000002 0000001C 60000000
3FB200C4: 00000000 03000006 0780880E 00000000
3FB200D4: 00000000 00000000 00000000 00000000
3FB200E4: 00000000 00000000 00000000 00000000
3FB200F4: 00000000 00000000 00000000 00000000
3FB20104: 00000000 00000000 00000000
Dynamic DecoderPrivateInfo Table:
Dumping 40 bytes @ 0x3FB20110
3FB20110: 0000001C 60000000 00000000 03000006
3FB20120: 0780880E 00000000 00000000 00000000
3FB20130: 1A010000 00000000
Dynamic DecoderInfo Table:
Dumping 384 bytes @ 0x3FB20138
3FB20138: FFC00000 00000000 80016000 80012000
3FB20148: 80012000 00000000 00000000 00000000
3FB20158: 00000000 00000000 00000000 00000000
3FB20168: 00000000 00000000 00000000 00000000
3FB20178: 00000000 00000000 00000000 00000000
3FB20188: 00000000 00000000 00000000 00000000
3FB20198: 00000000 00000000 00000000 00000000
3FB201A8: 00000000 00000000 00000000 00000000
3FB201B8: 00000000 00000000 00000000 00000000
3FB201C8: 00000000 00000000 00000000 00000000
3FB201D8: 00000000 00000000 00000000 00000000
3FB201E8: 00000000 00000000 00000000 00000000
3FB201F8: 00000000 00000000 00000000 00000000
3FB20208: 00000000 00000000 00000000 00000000
3FB20218: 00000000 00000000 00000000 00000000
3FB20228: 00000000 80040000 00010100 00000000
3FB20238: 00000000 00000000 00000000 00000000
3FB20248: 00000000 00000000 00000000 00000000
3FB20258: 00000000 00000000 00000000 00000000
3FB20268: 00000000 00000000 00000000 00000000
3FB20278: 00000000 00000000 00000000 00000000
3FB20288: 00000000 00000000 00000000 00000000
3FB20298: 00000000 00000000 00000000 00000000
3FB202A8: 00000000 00000000 00000000 00000000
Interrupt masks:
Dumping 64 bytes @ 0x3FEDF000
3FEDF000: 00000000 80000000 01580000 00000000
3FEDF010: 7EA00000 00000000 00000000 00000000
3FEDF020: 00000000 00000000 00000000 00000000
3FEDF030: 00000000 00000000 00000000 00000000
Level Raw Value Bits active
0 [00..31] 00000000
[32..63] 00000000
1 [00..31] 80000000 0
[32..63] 00000000
2 [00..31] 01580000 7 9 11 12
[32..63] 00000000
3 [00..31] 00000000
[32..63] 00000000
4 [00..31] 7EA00000 1 2 3 4 5 6 8 10
[32..63] 00000000
5 [00..31] 00000000
[32..63] 00000000
6 [00..31] 00000000
[32..63] 00000000
7 [00..31] 00000000
[32..63] 00000000
Interrupt vectors:
Dumping 128 bytes @ 0x3FEDD000
3FEDD000: 00190025 00040005 00240006 0007000D
3FEDD010: 0002000E 0003001C 001EFFFF FFFFFFFF
3FEDD020: 00000000 00000000 00000000 00000000
3FEDD030: 00000000 00000000 00000000 00000000
3FEDD040: 00000000 00000000 00000000 00000000
3FEDD050: 00000000 00000000 00000000 00000000
3FEDD060: 00000000 00000000 00000000 00000000
3FEDD070: 00000000 00000000 00000000 00000000
Interrupt priorities:
Dumping 64 bytes @ 0x3FEDC000
3FEDC000: 01040404 04040402 04020402 02000000
3FEDC010: 00000000 00000000 00000000 00000000
3FEDC020: 00000000 00000000 00000000 00000000
3FEDC030: 00000000 00000000 00000000 00000000
Spurious interrupt vector = 0x40
SCSIIntVect = 2048
SCCAIntVect = 37
SCCBIntVect = 36
VIAIntVect = 25
ADBIntVect = 2048
NMIIntVect = 2048
OpenPIC @ 80040000 setup: setting interrupt source 25 to 0x00000180
OpenPIC @ 80040000 setup: setting interrupt source 37 to 0x01004480
OpenPIC @ 80040000 setup: setting interrupt source 4 to 0x02000480
OpenPIC @ 80040000 setup: setting interrupt source 5 to 0x03000480
OpenPIC @ 80040000 setup: setting interrupt source 36 to 0x04004480
OpenPIC @ 80040000 setup: setting interrupt source 6 to 0x05000480
OpenPIC @ 80040000 setup: setting interrupt source 7 to 0x06000480
OpenPIC @ 80040000 setup: setting interrupt source 13 to 0x07004280
OpenPIC @ 80040000 setup: setting interrupt source 2 to 0x08000480
OpenPIC @ 80040000 setup: setting interrupt source 14 to 0x09004280
OpenPIC @ 80040000 setup: setting interrupt source 3 to 0x0A000480
OpenPIC @ 80040000 setup: setting interrupt source 28 to 0x0B004280
OpenPIC @ 80040000 setup: setting interrupt source 30 to 0x0C004280
ToolboxImage current logical address = 0x3F400000, ToolboxImage final physical address = 0x00C00000.
ConfigInfo logical address in current ROM image = 0x3F70D000.
configinfop->ROMImageBaseOffset address = 0x00BFD000.
configinfop->Mac68KROMOffset address = 0x00BFD000.
configinfop->HWInitCodeOffset address = 0x00000000.
configinfop->DiagPEFBundleOffset address = 0x00000000.
configinfop->KernelCodeOffset address = 0x00F0D000.
configinfop->EmulatorCodeOffset address = 0x00000000.
configinfop->OpcodeTableOffset address = 0x00000000.
AddPageMapEntry: LA = 0xF0000000, count = 0x10000, PA = 0xF0000000, pageAttr = 0x003A, flags = 0x00.
Next free PageMap entry for segment 0xF is entry 0.
AddPageMapEntry: LA = 0x80000000, count = 0x0080, PA = 0x80000000, pageAttr = 0x003A, flags = 0x00.
Next free PageMap entry for segment 0x8 is entry 0.
AddPageMapEntry: LA = 0x80080000, count = 0x0001, PA = 0x80080000, pageAttr = 0x003A, flags = 0x00.
Next free PageMap entry for segment 0x8 is entry 1.
AddPageMapEntry: LA = 0x81000000, count = 0x1000, PA = 0x81000000, pageAttr = 0x0032, flags = 0x00.
Next free PageMap entry for segment 0x8 is entry 2.
AddPageMapEntry: LA = 0x82000000, count = 0x0001, PA = 0x82000000, pageAttr = 0x003A, flags = 0x00.
Next free PageMap entry for segment 0x8 is entry 3.
AddPageMapEntry: LA = 0x50000000, count = 0xFFFE, PA = 0x00000000, pageAttr = 0x0A00, flags = 0x00.
Next free PageMap entry for segment 0x5 is entry 0.
AddPageMapEntry: LA = 0x50000000, count = 0xFFFE, PA = 0x00000000, pageAttr = 0x0A00, flags = 0x00.
Next free PageMap entry for segment 0x5 is entry 1.
AddPageMapEntry: LA = 0x5FFFE000, count = 0x0001, PA = 0x00000000, pageAttr = 0x0012, flags = 0x01.
Next free PageMap entry for segment 0x5 is entry 2.
AddPageMapEntry: LA = 0x68FFF000, count = 0x0001, PA = 0x00000000, pageAttr = 0x0012, flags = 0x03.
Next free PageMap entry for segment 0x6 is entry 0.
AddPageMapEntry: LA = 0x68FFE000, count = 0x0001, PA = 0x00000000, pageAttr = 0x0011, flags = 0x02.
Next free PageMap entry for segment 0x6 is entry 1.
AddPageMapEntry: LA = 0x80060000, count = 0x0001, PA = 0x80060000, pageAttr = 0x003A, flags = 0x00.
Next free PageMap entry for segment 0x8 is entry 4.
AddPageMapEntry: LA = 0x68FEF000, count = 0x0001, PA = 0x00003000, pageAttr = 0x0013, flags = 0x00.
Next free PageMap entry for segment 0x6 is entry 2.
AddPageMapEntry: LA = 0x64000000, count = 0x0180, PA = 0x00000000, pageAttr = 0x0012, flags = 0x00.
Next free PageMap entry for segment 0x6 is entry 3.
--- Dumping PageMapStateTable ---
Segment = 0x5, LA = 0x00000000, count = 0xFFFD, PA = 0x00000000, pageAttr = 0x0A00, flags = 0x00.
Segment = 0x5, LA = 0x00000000, count = 0xFFFD, PA = 0x00000000, pageAttr = 0x0A00, flags = 0x00.
Segment = 0x5, LA = 0xFFFE0000, count = 0x0000, PA = 0x00000000, pageAttr = 0x0012, flags = 0x01.
Segment = 0x6, LA = 0x40000000, count = 0x017F, PA = 0x00000000, pageAttr = 0x0012, flags = 0x00.
Segment = 0x0, LA = 0x00000000, count = 0x0000, PA = 0x00003000, pageAttr = 0x0000, flags = 0x00.
Segment = 0x6, LA = 0x8FFE0000, count = 0x0000, PA = 0x00000000, pageAttr = 0x0011, flags = 0x02.
Segment = 0x6, LA = 0x00000000, count = 0x0000, PA = 0x00000000, pageAttr = 0x0000, flags = 0x03.
Segment = 0x0, LA = 0x00000000, count = 0x005F, PA = 0x00000000, pageAttr = 0x0000, flags = 0x00.
Segment = 0x8, LA = 0x00600000, count = 0x0000, PA = 0x80060000, pageAttr = 0x003A, flags = 0x00.
Segment = 0x0, LA = 0x00610000, count = 0xFF9E, PA = 0x00061000, pageAttr = 0x0000, flags = 0x00.
Segment = 0x0, LA = 0x00800000, count = 0x0000, PA = 0x80080000, pageAttr = 0x003A, flags = 0x00.
Segment = 0x8, LA = 0x10000000, count = 0x0FFF, PA = 0x81000000, pageAttr = 0x0032, flags = 0x00.
Segment = 0x0, LA = 0x00000000, count = 0x0000, PA = 0x00000000, pageAttr = 0x0000, flags = 0x00.
Segment = 0xF, LA = 0x00000000, count = 0xFFFF, PA = 0xF0000000, pageAttr = 0x003A, flags = 0x00.
ConfigInfo table:
Dumping 1792 bytes @ 0x3FEDB000
3FEDB000: 00000000 00000000 00000000 00000000
3FEDB010: 00000000 00000000 00000000 00000000
3FEDB020: 00000000 00000000 00BFD000 00400000
3FEDB030: 00000000 00BFD000 00300000 00000000
3FEDB040: 00000000 00000000 00000000 00F0D000
3FEDB050: 00000000 00000000 00000000 00000000
3FEDB060: 00000000 4E657757 6F726C64 2076312E
3FEDB070: 30202020 00000F00 00000100 00000070
3FEDB080: 0000E8B0 0000E8C0 00200000 FF9FFFFF
3FEDB090: 00E00000 80060000 06000000 5FFFE000
3FEDB0A0: 68FFE000 68FFF000 68080000 68060000
3FEDB0B0: 000003A0 00000012 00000180 000003AC
3FEDB0C0: 00000060 00000088 00000090 00000000
3FEDB0D0: 00000000 00000010 00100000 00000020
3FEDB0E0: 00200000 00000030 00300000 00000040
3FEDB0F0: 00400000 00000050 00500000 00000078
3FEDB100: 00600000 000000B0 00700000 000000C8
3FEDB110: 00800000 00000108 00900000 00000118
3FEDB120: 00A00000 00000128 00B00000 00000138
3FEDB130: 00C00000 00000148 00D00000 00000158
3FEDB140: 00E00000 00000168 00F00000 00000000
3FEDB150: 00000000 00000010 00100000 00000020
3FEDB160: 00200000 00000030 00300000 00000040
3FEDB170: 00400000 00000050 00500000 00000078
3FEDB180: 00600000 000000B0 00700000 000000C8
3FEDB190: 00800000 00000108 00900000 00000118
3FEDB1A0: 00A00000 00000128 00B00000 00000138
3FEDB1B0: 00C00000 00000148 00D00000 00000158
3FEDB1C0: 00E00000 00000168 00F00000 00000000
3FEDB1D0: 00000000 00000010 00100000 00000020
3FEDB1E0: 00200000 00000030 00300000 00000040
3FEDB1F0: 00400000 00000050 00500000 00000078
3FEDB200: 00600000 000000B0 00700000 000000C8
3FEDB210: 00800000 00000108 00900000 00000118
3FEDB220: 00A00000 00000128 00B00000 00000138
3FEDB230: 00C00000 00000148 00D00000 00000158
3FEDB240: 00E00000 00000168 00F00000 00000000
3FEDB250: 00000000 00000010 00100000 00000020
3FEDB260: 00200000 00000030 00300000 00000040
3FEDB270: 00400000 00000050 00500000 00000078
3FEDB280: 00600000 000000B0 00700000 000000C8
3FEDB290: 00800000 00000108 00900000 00000118
3FEDB2A0: 00A00000 00000128 00B00000 00000138
3FEDB2B0: 00C00000 00000148 00D00000 00000158
3FEDB2C0: 00E00000 00000168 00F00000 00000000
3FEDB2D0: 00000000 FFC0007F 00C00043 0000007F
3FEDB2E0: 00C00043 6800001F 00F00043 00000000
3FEDB2F0: 00000000 00000000 00000000 00000000
3FEDB300: 00000000 00000000 00000000 00000000
3FEDB310: 00000000 00000000 00000000 00000000
3FEDB320: 00000000 00000000 00000000 00000000
3FEDB330: 00000000 00000000 00000000 00000000
3FEDB340: 00000000 00000000 00000000 13FF13FF
3FEDB350: 13FF13FF F3FFF3FF 13FF13FF 00000000
3FEDB360: 00004000 00000000 00000000 00000000
3FEDB370: 00000000 00000000 01010000 00000000
3FEDB380: 00000000 00000000 00000000 00000000
3FEDB390: 00000000 00000000 00000000 00000000
3FEDB3A0: 00000004 FFC0002A 00000000 0000FFFF
3FEDB3B0: 00000A00 0000FFFF 00000A00 0000FFFF
3FEDB3C0: 00000A00 0000FFFF 00000A00 0000FFFF
3FEDB3D0: 00000A00 0000FFFF 00000A00 0000FFFF
3FEDB3E0: 00000A00 0000FFFF 00000A00 0000FFFF
3FEDB3F0: 00000A00 0000FFFF 00000A00 0000FFFD
3FEDB400: 00000A00 0000FFFD 00000A00 FFFE0000
3FEDB410: 00000012 0000FFFF 00000A00 0000FFFF
3FEDB420: 00000A00 4000017F 00000012 00000000
3FEDB430: 00003000 8FFE0000 00000011 00000000
3FEDB440: 00000000 0000FFFF 00000A01 0000FFFF
3FEDB450: 00000A01 0000FFFF 00000A00 0000FFFF
3FEDB460: 00000A01 0000FFFF 00000A01 0000FFFF
3FEDB470: 00000A00 0000005F 00000000 00600000
3FEDB480: 8006003A 0061FF9E 00061000 00800000
3FEDB490: 8008003A 10000FFF 81000032 00000000
3FEDB4A0: 00000000 0000FFFF 80000A01 0000FFFF
3FEDB4B0: 00000A00 0000FFFF 90000A01 0000FFFF
3FEDB4C0: 00000A00 0000FFFF A0000A01 0000FFFF
3FEDB4D0: 00000A00 0000FFFF B0000A01 0000FFFF
3FEDB4E0: 00000A00 0000FFFF C0000A01 0000FFFF
3FEDB4F0: 00000A00 0000FFFF D0000A01 0000FFFF
3FEDB500: 00000A00 0000FFFF E0000A01 0000FFFF
3FEDB510: 00000A00 0000FFFF F000003A 0000FFFF
3FEDB520: F0000A01 0000FFFF 00000A00 00000000
3FEDB530: 00000000 00000000 00000000 00000000
3FEDB540: 00000000 00000000 00000000 00000000
3FEDB550: 00000000 00000000 00000000 00000000
3FEDB560: 00000000 00000000 00000000 00000000
3FEDB570: 00000000 00000000 00000000 00000000
3FEDB580: 00000000 00000000 00000000 00000000
3FEDB590: 00000000 00000000 00000000 00000000
3FEDB5A0: 00000000 00000000 00000000 00000000
3FEDB5B0: 00000000 00000000 00000000 00000000
3FEDB5C0: 00000000 00000000 00000000 00000000
3FEDB5D0: 00000000 00000000 00000000 00000000
3FEDB5E0: 00000000 00000000 00000000 00000000
3FEDB5F0: 00000000 00000000 00000000 00000000
3FEDB600: 00000000 00000000 00000000 00000000
3FEDB610: 00000000 00000000 00000000 00000000
3FEDB620: 00000000 00000000 00000000 00000000
3FEDB630: 00000000 00000000 00000000 00000000
3FEDB640: 00000000 00000000 00000000 00000000
3FEDB650: 00000000 00000000 00000000 00000000
3FEDB660: 00000000 00000000 00000000 00000000
3FEDB670: 00000000 00000000 00000000 00000000
3FEDB680: 00000000 00000000 00000000 00000000
3FEDB690: 00000000 00000000 00000000 00000000
3FEDB6A0: 00000000 00000000 00000000 00000000
3FEDB6B0: 00000000 00000000 00000000 00000000
3FEDB6C0: 00000000 00000000 00000000 00000000
3FEDB6D0: 00000000 00000000 00000000 00000000
3FEDB6E0: 00000000 00000000 00000000 00000000
3FEDB6F0: 00000000 00000000 00000000 00000000
FreeBytes address: logical = 0x3FAD8000
WorkArea_target address: logical = 0x00440000
SystemInfo addresses: logical = 0x3FEE5000, physical = 0x3FEE5000
ProcessorInfo addresses: logical = 0x3FEE6000, physical = 0x3FEE6000
-
HWInfo addresses: logical = 0x3FEE4000, physical = 0x3FEE4000
HwInitInfo addresses: logical = 0x3FEE7000, physical = 0x3FEE7000
NanoKernelEntry addresses: 0x00F10000
System info:
Dumping 320 bytes @ 0x3FEE5000
3FEE5000: 00000000 00000000 00000000 00000000
3FEE5010: 00000000 00000000 00000000 00000000
3FEE5020: 00000000 00000000 00000000 00000000
3FEE5030: 00000000 00C00000 00E58000 000A7000
3FEE5040: 01000000 FF000000 00000000 00000000
3FEE5050: 00000000 00000000 00000000 00000000
3FEE5060: 00000000 00000000 00000000 00000000
3FEE5070: 00000000 00000000 00000000 00000000
3FEE5080: 00000000 00000000 00000000 00000000
3FEE5090: 00000000 00000000 00000000 00000000
3FEE50A0: 00000000 00000000 00000000 00000000
3FEE50B0: 00000000 00000000 00000000 00000000
3FEE50C0: 00000000 00000000 00000000 00000000
3FEE50D0: 00000000 00000000 00000000 00000000
3FEE50E0: 00000000 00000000 00000000 00000000
3FEE50F0: 00000000 00000000 00000000 00000000
3FEE5100: 80040000 00000000 00000000 00000000
3FEE5110: 00000000 00000000 00000000 00000000
3FEE5120: 00000000 00000000 00000035 D0000000
3FEE5130: 00000000 00000000 00000000 00000000
Processor info:
Dumping 160 bytes @ 0x3FEE6000
3FEE6000: 003C0301 35A4E900 05F5E100 05F5E100
3FEE6010: 00001000 00008000 00010000 00800020
3FEE6020: 00000080 00800080 00800080 00040002
3FEE6030: 10000010 00000000 00000000 00000000
3FEE6040: 00000000 00000000 00000000 00000000
3FEE6050: 00000000 00000000 00000000 00000000
3FEE6060: 00000000 00000000 00000000 00000000
3FEE6070: 00000000 00000000 00000000 00000000
3FEE6080: 00000000 00000000 00000000 00000000
3FEE6090: 00000000 00000000 00000000 00000000
Hardware info:
Dumping 192 bytes @ 0x3FEE4000
3FEE4000: 00C00000 6400000C 640480A4 00003000
3FEE4010: 3FEDD000 3FEDF000 80040000 00000000
3FEE4020: 00000000 00000000 00000000 00000000
3FEE4030: 00000000 00000000 00000000 00001400
3FEE4040: 00000000 00000000 00000000 00000000
3FEE4050: 00000000 00000000 00000000 00000000
3FEE4060: 00000000 00000000 00000000 00000000
3FEE4070: 486E666F 00403035 00250024 08000800
3FEE4080: 00190000 08000800 00400000 00000000
3FEE4090: 00000000 00000004 00000000 00410000
3FEE40A0: 1A05D66A 00000000 3FEDE000 00000000
3FEE40B0: 00000000 00000000 00000000 00000000
HardwareInit info:
Dumping 32 bytes @ 0x3FEE7000
3FEE7000: 3FEE5000 3FEE6000 00000000 3FEE4000
3FEE7010: 00000000 00000080 00F10000 80012000
Cascade Info:
Dumping 516 bytes @ 0x00117818
00117818: 00000000 FFFFFFFF FFFFFFFF FFFFFFFF
00117828: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF
00117838: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF
00117848: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF
00117858: FFFFFFFF 01040404 04040402 04020402
00117868: 02000000 00000000 00000000 00000000
00117878: 00000000 00000000 00000000 00000000
00117888: 00000000 00000000 00000000 00000000
00117898: 00000000 00000000 00000000 00000000
001178A8: 00000000 00000000 00000000 00000000
001178B8: 00000000 00000000 00000000 00000000
001178C8: 00000000 00000000 00000000 00000000
001178D8: 00000000 00000000 00000000 00000000
001178E8: 00000000 00000000 00000000 00000000
001178F8: 00000000 00000000 00000000 00000000
00117908: 00000000 00000000 00000000 00000000
00117918: 00000000 00000000 00000000 00000000
00117928: 00000000 00000000 00000000 00000000
00117938: 00000000 00000000 00000000 00000000
00117948: 00000000 00000000 00000000 00000000
00117958: 00000000 00000000 00000000 00000000
00117968: 00000000 00000000 00000000 00000000
00117978: 00000000 00000000 00000000 00000000
00117988: 00000000 00000000 00000000 00000000
00117998: 00000000 00000000 00000000 00000000
001179A8: 00000000 00000000 00000000 00000000
001179B8: 00000000 00000000 00000000 00000000
001179C8: 00000000 00000000 00000000 00000000
001179D8: 00000000 00000000 00000000 00000000
001179E8: 00000000 00000000 00000000 00000000
001179F8: 00000000 00000000 00000000 00000000
00117A08: 00000000 00000000 00000000 00000000
00117A18: 00000000
IsKeyDown: no keys held down
Overlap in AddMemoryRelocationEntry().
- dst = 0x00003000, dstLength = 0x0000052C, entry->dst = 0x00000000, entry->dst_len = 0x000482B8.
Overlap in AddMemoryRelocationEntry().
- dst = 0x00003F80, dstLength = 0x00000080, entry->dst = 0x00000000, entry->dst_len = 0x000482B8.
Overlap in AddMemoryRelocationEntry().
- dst = 0x00003F40, dstLength = 0x00000040, entry->dst = 0x00000000, entry->dst_len = 0x000482B8.
Overlap in AddMemoryRelocationEntry().
- dst = 0x00003CFC, dstLength = 0x00000204, entry->dst = 0x00000000, entry->dst_len = 0x000482B8.
Overlap in AddMemoryRelocationEntry().
- dst = 0x00003F00, dstLength = 0x00000040, entry->dst = 0x00000000, entry->dst_len = 0x000482B8.
Updated BusClockRateHz: 399957011
Stopping at end of FCODE, due to fatal error (see above).
EXIT
0 >
-
Seems to stop after Updated BusClockRateHz: 399957011.
Could this be an issue with not able to understand a 400Mhz bus speed?
Otherwise, it's not giving us anymore info in AddMemoryRelocationEntry.
I did try fcode-debug? true and true to ?fcode-verbose, however when loading a :tbxi it does load and go. So I can't do 1 byte-load to get verbose output to debug the fcode from a :tbxi.
-
Seems we should be seeing:
HardwareInit info:
Dumping 32 bytes @ 0x3FEE7000
3FEE7000: 3FEE5000 3FEE6000 00000000 3FEE4000
3FEE7010: 00000000 00000020 00F10000 80012000
Cascade Info:
Dumping 516 bytes @ 0x00117818
00117818: 00000000 FFFFFFFF FFFFFFFF FFFFFFFF
00117828: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF
00117838: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF
00117848: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF
00117858: FFFFFFFF 01040404 04040402 04020402
00117868: 02000000 00000000 00000000 00000000
00117878: 00000000 00000000 00000000 00000000
00117888: 00000000 00000000 00000000 00000000
00117898: 00000000 00000000 00000000 00000000
001178A8: 00000000 00000000 00000000 00000000
001178B8: 00000000 00000000 00000000 00000000
001178C8: 00000000 00000000 00000000 00000000
001178D8: 00000000 00000000 00000000 00000000
001178E8: 00000000 00000000 00000000 00000000
001178F8: 00000000 00000000 00000000 00000000
00117908: 00000000 00000000 00000000 00000000
00117918: 00000000 00000000 00000000 00000000
00117928: 00000000 00000000 00000000 00000000
00117938: 00000000 00000000 00000000 00000000
00117948: 00000000 00000000 00000000 00000000
00117958: 00000000 00000000 00000000 00000000
00117968: 00000000 00000000 00000000 00000000
00117978: 00000000 00000000 00000000 00000000
00117988: 00000000 00000000 00000000 00000000
00117998: 00000000 00000000 00000000 00000000
001179A8: 00000000 00000000 00000000 00000000
001179B8: 00000000 00000000 00000000 00000000
001179C8: 00000000 00000000 00000000 00000000
001179D8: 00000000 00000000 00000000 00000000
001179E8: 00000000 00000000 00000000 00000000
001179F8: 00000000 00000000 00000000 00000000
00117A08: 00000000 00000000 00000000 00000000
00117A18: 00000000
IsKeyDown: no keys held down
Updated BusClockRateHz: 399957011
Off to MacOS. The next (and last) call into OpenFirmware is quiesce().
AddMemoryRelocationEntry is used to request that data structures be copied from one location to another when the system boots. It is not supposed to have multiple destinations overlapping, but that somehow happened.
That seems to be the trouble, but I don't really understand it. If we can figure the overlap maybe we can get a little further?[/code]
-
This string seems to suggest the 0x00003xxx overlaps have to do with some struct at 0x68FEF000, at least according to the map from virt 0x68FEF000 to phys 0x3000. It has set up some initial values that it wants copied into that page when it boots. Some big overlapping 288k area starting at phys address 0 is getting in the way. I am not sure what struct 0x68FEF000 is supposed to be, though I know that is neither the KDP (0x68FFE000), the EDP (0x68FFF000), nor the copied device tree (0x64000000).
AddPageMapEntry: LA = 0x68FEF000, count = 0x0001, PA = 0x00003000, pageAttr = 0x0013, flags = 0x00.
-
This string seems to suggest the 0x00003xxx overlaps have to do with some struct at 0x68FEF000, at least according to the map from virt 0x68FEF000 to phys 0x3000. It has set up some initial values that it wants copied into that page when it boots. Some big overlapping 288k area starting at phys address 0 is getting in the way. I am not sure what struct 0x68FEF000 is supposed to be, though I know that is neither the KDP (0x68FFE000), the EDP (0x68FFF000), nor the copied device tree (0x64000000).
AddPageMapEntry: LA = 0x68FEF000, count = 0x0001, PA = 0x00003000, pageAttr = 0x0013, flags = 0x00.
Ok, I understand some of that, is the data being copied from the PA to the VA or vice versa?
Also, I'm not really up on :tbxi resources, but I'm assuming the Mac OS ROM has an FCode wrapper, and it copies a bunch of needed data from the device tree and ?elsewhere? then we're "Off to the Mac OS" ?nano kernel?.
I'm getting almost that far, but some of the last bits of Fcode are failing to copy over data to the correct address.
Can we look at the FCode and see what it's trying to do?
detok it?
If we can separate the wrapper( FCode ), I should be able to load it, rather than load and go, and use ?fcode=verbose to step through it to see where we are getting a ?default-catch?.
Other ideas?
-
The short forth boot script transfers control to a ELF program called the Trampoline. The Trampoline does a whole ton of init, loads the Toolbox ROM into memory, and jumps to the NanoKernel.
The virt address 0x68FEF000 corresponds with the single page at phys address 0x3000 (somewhere in RAM). The failing AddMemoryRelocationEntry() calls were supposed to transfer data from some temporary spot (unknown because logs don't list src) to locations in that page (0x3000-352B is one. 0x3F80-3FFF, 0x3F40-3F7F, 0x3CFC-3EFF, and 0x3F00-3F3F are the others).
Something else is interfering with that by already claiming as a destination 288k of the phys memory starting at address 0. I am not sure what that is, but it is probably not supposed to happen. I am guessing that the "reg" or "assigned-addresses" property of something is being mangled because the Trampoline doesn't handle 64-bit stuff. But really, who knows?
powermax is working on decompiling the Trampoline. It is very much a work in progress. If you want to, ask him to grant access to his private GitLab repo. He might also be able to help patch the Trampoline to debug more on this stuff. I am not sure what the full state of work on the Trampoline is.
-
Can we look at the FCode and see what it's trying to do? detok it?
The error message at the end of the Trampoline is a bit misleading: there is no FCode executed there at all. Everything in the Trampoline is native code, either generated from C source or hand-crafted assembly.
Seems to stop after Updated BusClockRateHz: 399957011.
Could this be an issue with not able to understand a 400Mhz bus speed?
No. Trampoline has perfectly measured the clock speed of your bus as 399957011 Hz / 1000000 = 399,96 MHz. ;D
-
Overlap in AddMemoryRelocationEntry().
- dst = 0x00003000, dstLength = 0x0000052C, entry->dst = 0x00000000, entry->dst_len = 0x000482B8.
This relocation belongs to the ConfigInfo structure.
Overlap in AddMemoryRelocationEntry().
- dst = 0x00003F80, dstLength = 0x00000080, entry->dst = 0x00000000, entry->dst_len = 0x000482B8.
This one belongs to the vector lookup table.
Overlap in AddMemoryRelocationEntry().
- dst = 0x00003F40, dstLength = 0x00000040, entry->dst = 0x00000000, entry->dst_len = 0x000482B8.
-> vector mask table
Overlap in AddMemoryRelocationEntry().
- dst = 0x00003CFC, dstLength = 0x00000204, entry->dst = 0x00000000, entry->dst_len = 0x000482B8.
-> CascadeInfo
Overlap in AddMemoryRelocationEntry().
- dst = 0x00003F00, dstLength = 0x00000040, entry->dst = 0x00000000, entry->dst_len = 0x000482B8.
-> vector priority table
All these areas overlap with the already claimed area 0x00000000...0x000482B8. For the moment being, I cannot say for sure what's supposed to be resided there because the error in AddMemoryRelocationEntry() doesn't show us the source.
My guess is that 288KB chunk is used by the flattened device tree stuffed into the "work area" in Trampoline's jargon. According to its size, it can be neither the Toolbox ROM-in-RAM (too small) nor any other structure (too big).
Anyway, the usage of the area @0 (phys) looks suspicious to me. It indicates a serious problem in Trampoline's physical memory sizing. The SystemInfo structure provides a clear evidence:
System info:
Dumping 320 bytes @ 0x3FEE5000
3FEE5000: 00000000 00000000 00000000 00000000
3FEE5010: 00000000 00000000 00000000 00000000
3FEE5020: 00000000 00000000 00000000 00000000
3FEE5030: 00000000 00C00000 00E58000 000A7000
3FEE5040: 01000000 FF000000 00000000 00000000
[...]
The first two double words - PhysicalMemorySize and UsableMemorySize - contain zeroes! In other words, the Trampoline wasn't able to find any physical memory in your machine at all. The function responsible for memory size determination is called CalcRAMSize() and is located @ 0x2025F4. It queries the OF memory node for "reg" property and then (mis)interpret its values.
Can you dump the memory/reg of your target?
-
The first two double words - PhysicalMemorySize and UsableMemorySize - contain zeroes! In other words, the Trampoline wasn't able to find any physical memory in your machine at all. The function responsible for memory size determination is called CalcRAMSize() and is located @ 0x2025F4. It queries the OF memory node for "reg" property and then (mis)interpret its values.
I must correct myself: CalcRAMSize() should report fatal error and exit if no physical memory was found. But in your precise case, the program keeps running so the problem resides somewhere else. Anyway, the above mentioned dump of the SystemInfo looks invalid and that's the point where to start any further investigation.
-
Very interesting thread people! Keep it up!
-
Thanks powermax, do I need to dump Sysinfo?
How would I go about that?
qemu-system-ppc64 boots with the same setting only amend -cpu g4 rather than the 970fx. I haven't dug through all the code to see what choosing a 64bit cpu changes. Tho on a side note one can boot OS X with 4GB of ram with the G4 emulation. Not technically 64bit address space, but shows how emulators are not subject to the physical limitations of real hardware.
I forget the reason the G4 couldn't address 4GB, I read it many years ago, something about it could, but the upper 2GB was only available for shadow memory, or some such. Someone went to the time to fix that with qemu.
In the case of the G5, I expect we could "fix" OS 9 booting, given enough time and testing, but we may end up changing some of the G5 CPU emulation in ways that breaks linux booting.
OS X doesn't boot, someone needs to implement spr 304( 0x130 ), and even if it did get mach_kernel to boot, the emulated Sawtooth and a G5 CPU are not really going to work together.
-
Thanks powermax, do I need to dump Sysinfo?
How would I go about that?
Does QEMU allow debugging of the running targets? In other words, can you set breakpoints and trace the Trampoline code in QEMU?
-
Thanks powermax, do I need to dump Sysinfo?
How would I go about that?
Does QEMU allow debugging of the running targets? In other words, can you set breakpoints and trace the Trampoline code in QEMU?
Yes, I'm pretty sure it can do that, I'll have to check the breakpoints, I don't recall right off, but I'm thinking yes.
I'm on the road right now, later this week, I'll setup the needed PPC debuging Env for Qemu, if you walk me through how to use it.
Also fun for anyone else that wants to play along. ;D
-
Thanks powermax, do I need to dump Sysinfo?
How would I go about that?
qemu-system-ppc64 boots with the same setting only amend -cpu g4 rather than the 970fx. I haven't dug through all the code to see what choosing a 64bit cpu changes. Tho on a side note one can boot OS X with 4GB of ram with the G4 emulation. Not technically 64bit address space, but shows how emulators are not subject to the physical limitations of real hardware.
I forget the reason the G4 couldn't address 4GB, I read it many years ago, something about it could, but the upper 2GB was only available for shadow memory, or some such. Someone went to the time to fix that with qemu.
In the case of the G5, I expect we could "fix" OS 9 booting, given enough time and testing, but we may end up changing some of the G5 CPU emulation in ways that breaks linux booting.
OS X doesn't boot, someone needs to implement spr 304( 0x130 ), and even if it did get mach_kernel to boot, the emulated Sawtooth and a G5 CPU are not really going to work together.
OS X works just fine with KVM on a G5, but we've already had this discussion already.
Plenty of people have/had it running, I used to run it too both with QEMU and MOL.
This is just one example of someone that have it working.
https://youtu.be/lbDj4NGEJEQ
-
Thanks powermax, do I need to dump Sysinfo?
How would I go about that?
qemu-system-ppc64 boots with the same setting only amend -cpu g4 rather than the 970fx. I haven't dug through all the code to see what choosing a 64bit cpu changes. Tho on a side note one can boot OS X with 4GB of ram with the G4 emulation. Not technically 64bit address space, but shows how emulators are not subject to the physical limitations of real hardware.
I forget the reason the G4 couldn't address 4GB, I read it many years ago, something about it could, but the upper 2GB was only available for shadow memory, or some such. Someone went to the time to fix that with qemu.
In the case of the G5, I expect we could "fix" OS 9 booting, given enough time and testing, but we may end up changing some of the G5 CPU emulation in ways that breaks linux booting.
OS X doesn't boot, someone needs to implement spr 304( 0x130 ), and even if it did get mach_kernel to boot, the emulated Sawtooth and a G5 CPU are not really going to work together.
OS X works just fine with KVM on a G5, but we've already had this discussion already.
Plenty of people have/had it running, I used to run it too both with QEMU and MOL.
This is just one example of someone that have it working.
https://youtu.be/lbDj4NGEJEQ
Qemu works with the G5 hosts with KVM, but only when passing a 32bit PPC CPU to the guest machine, and it won't boot OS 9. OS9 booting also doesn't work with KVM on 32bit PPC hosts.
-
Are we reasonably confident that the G5 is in 32-bit mode when the Trampoline gets control? I’m trying to imagine what would happen if you ran code intended for 32-bit PPC under 64-bit mode, and I can imagine it working.
Also, Max, have you yet reversed the stuff that interprets “Reg” properties?
-
KVM does not emulate the CPU at all at OSE/VSE level.
It can fake the PVR bits but that doesn't affect the emulation. (At UISA level the KVM-PR module can do some instruction emulation, but it doesn't attempt anything else as far as I know) KVM on the x86 works the same.
-
To clarify if you say -cpu 604 to qemu when using kvm that does not mean you will run as a 604, if you have a G5 a G5 is what the guest OS will get. It will however lie cause it traps the PVR bits and will return 604.
Kvm is fast because it does NOT emulate but rather passthrough the hardware as is, the very same reason QEmu without kvm is quite slow as it has to emulate things like address translation that occurs virtually all the time.
There is no way around that, an MMU on an arbitrary CPU can't be reconfigured to behave like an MMU on a totally different processor so either you passthrough and accept that or you emulate and have absolutely no benefit from KVM.
The PPC kvm is a bit different though as they have kvm-hv (pure hypervisor/passthrough as all other kvm Arch's) and kvm-pr (problem mode) kvm-pr runs code in problem mode and traps instructions it can't understand this is sort of a middle ground (this is very much what MacOnLinux used to do) however as I said it does not and can not emulate the memory management.
And back to the (non) issue about OS X on the G5,
OS X gives rat about the platform a particular CPU is on, it have absolutely no problem running a G5 with a mac99 motherboard. It's handled by different parts of the system, the platform expert just loads the drivers based on what the device tree says- if there is any CPU expectation within any of these drivers they're faulty/incorrectly written.
-
Also, Max, have you yet reversed the stuff that interprets “Reg” properties?
Yes. As for memory regions, the stuff is located in utils.c:CalcRAMSize().
Device tree walking code also interprets "reg" properties attached to various devices in order to calculate device's base address. That stuff is much more complex. It has been reversed as well but still need a cleanup.
-
And back to the (non) issue about OS X on the G5,
Let's get back on track. OS 9 Trampoline doesn't depend on a particular CPU until we'll get into RelocationEngine that reprograms BATs. But that's the last step before the Nanokernel, just after OF has been shut down.
For the moment being, we didn't get so far due to the fatal error caused by overlapping relocation regions.
The Trampoline code depends on OF and MMU. Regarding the former, OpenBIOS is not the same as Apple's proprietary OF implementation - it can behave differently and thus cause the Trampoline to fail.
It can also be an issue with 64-bit MMU. That's what we need to figure out by means of debugging.
In the case of the G5, I expect we could "fix" OS 9 booting, given enough time and testing, but we may end up changing some of the G5 CPU emulation in ways that breaks linux booting.
You're right regarding our ability to fix OS 9 boot on G5. But we aren't going to break the existing QEMU emulation, we'll fix the Trampoline instead. That's why I'm working hard on finishing its decompilation.
-
And back to the (non) issue about OS X on the G5,
Let's get back on track. OS 9 Trampoline doesn't depend on a particular CPU until we'll get into RelocationEngine that reprograms BATs. But that's the last step before the Nanokernel, just after OF has been shut down.
For the moment being, we didn't get so far due to the fatal error caused by overlapping relocation regions.
The Trampoline code depends on OF and MMU. Regarding the former, OpenBIOS is not the same as Apple's proprietary OF implementation - it can behave differently and thus cause the Trampoline to fail.
It can also be an issue with 64-bit MMU. That's what we need to figure out by means of debugging.
Absolutely, but this been discussed before and the attempt is quite futile since the 970 don't have any BATs.
The fact that the 970 can run OS 9 (ie. UISA compatibility, excluding eventual driver issues etc) is already demonstrated by the Blue box/Classic.
And yes you are right that openbios is different, but it should also be noted that the compatibility problem has been fixed enough to at least boot OS 9 with a 32 bit PPC. If the 64 bit and 32 bit use the same openbios images I don't recall however.
-
I believe that the 970 actually does have BATs. They are absent from the 970FX and 970MP.
But we could patch the kernel, or soon the Trampoline, not to use them.
-
I setup gdb-multiarch, I think it will work for what we need here, but I'm unsure what breakpoint to set?
-
I setup gdb-multiarch, I think it will work for what we need here, but I'm unsure what breakpoint to set?
I need to know your Trampoline version first. Can you tell me its MD5 checksum? Or upload your "Mac OS ROM" somewhere for me to grab?
-
Mac OS ROM 9.2.1, unmodified.
-
Mac OS ROM 9.2.1, unmodified.
I don't have this image, sorry. Fortunately, there is no big difference between Trampolines in OS 9.2.x.
IIRC, Trampoline is loaded by the Forth boot script and mapped into memory starting at 0x100000 (data sections) and 0x200000 (executable code). I hope that's correct.
You want to set a breakpoint at the subroutine @ 0x2025F4 (CalcRAMSize) and ensure that it works as expected: the first double word of SystemInfo (PPC register @r3 will point to it at exit of this function) should contain the correct size of the assigned memory (1024 MB).
I'm pretty sure that CalcRAMSize works as expected. It's meant to be a test ensuring that you can break into the Trampoline and trace its code.
-
Mac OS ROM 9.2.1, unmodified.
I don't have this image, sorry. Fortunately, there is no big difference between Trampolines in OS 9.2.x.
IIRC, Trampoline is loaded by the Forth boot script and mapped into memory starting at 0x100000 (data sections) and 0x200000 (executable code). I hope that's correct.
You want to set a breakpoint at the subroutine @ 0x2025F4 (CalcRAMSize) and ensure that it works as expected: the first double word of SystemInfo (PPC register @r3 will point to it at exit of this function) should contain the correct size of the assigned memory (1024 MB).
I'm pretty sure that CalcRAMSize works as expected. It's meant to be a test ensuring that you can break into the Trampoline and trace its code.
Ok, breakpoint not working with gdb-multiarch:
(gdb)target remote localhost:1234
(gdb)break CalcRAMSize
(gdb)continue
It just boots the Mac OS and only waits before continue.
I'm sure I'm doing something wrong here, maybe I need some PPC Libs installed, my host is X86.
-
Ok, breakpoint not working with gdb-multiarch:
(gdb)target remote localhost:1234
(gdb)break CalcRAMSize
Ugh, you need to break at memory addresses, not symbol names because the bundled Trampoline doesn't contain symbols!
(gdb)break *0x2025F4
is what you need but that will only work as soon as Trampoline code has been loaded into memory.
In order to break first time into the Trampoline, you'll need to set up a hardware breakpoint. If it works in your host, you're luck. If it doesn't work, you'll need to resort to another bag of tricks, for example, intercept the boot script or setting breakpoints at the OF client interface handler and then manually trace into the Trampoline code.
All this isn't fun at all but you've already agreed to get your hands dirty, so please go on ;)
-
Patchpef (https://github.com/elliotnunn/patchpef (https://github.com/elliotnunn/patchpef)) is a script that I hacked together to make small assembly-language patches to PEF files. Not at all pretty, but it was a big help in patching OS 9 to run on the Mac mini. It could pretty easily be adapted to insert arbitrary printfs into the Trampoline, as an alternative to debugger breakpoints.
-
Patchpef (https://github.com/elliotnunn/patchpef (https://github.com/elliotnunn/patchpef)) is a script that I hacked together to make small assembly-language patches to PEF files.
Trampoline comes as ELF binary so we'd need to teach your script how to understand ELF first.
Patching existing binaries to inject debugging code can be very cumbersome and slow. Instrumented emulators are generally much better because they allow tracing code and analyzing its behavior much quicker than statical analysis tools (disassemblers). Armed with the right tool, spotting the issue in the binary code is often a question of few minutes...
-
Ok, here is what I have so far:
Qemu-PPC
qqemu-system-ppc64 -s -S -M mac99 -m 1024 -cpu ppc64 -hda ~/os9/os9.img -prom-env "aapl,debug=13FFF" -prom-env "fcode-debug?=true" -prom-env "auto-boot?=false" --nographic
>> =============================================================
>> OpenBIOS 1.1 [Feb 22 2018 07:53]
>> Configuration device id QEMU version 1 machine id 3
>> CPUs: 1
>> Memory: 1024M
>> UUID: 00000000-0000-0000-0000-000000000000
>> CPU type PowerPC,970FX
milliseconds isn't unique.
Welcome to OpenBIOS v1.1 built on Feb 22 2018 07:53
0 > boot Trying hd:,\\:tbxi...
>> switching to new context:
AAPL,debug bit settings (-OR- bits together):
1 * = Print general informative messages.
2 * = Print formatted Mac OS tables (except config/universal info).
4 * = Print formatted config info table.
8 * = Dump Mac OS tables (except config/universal info).
10 * = Print node names while copying the device tree.
20 * = Print property info while copying the device tree.
40 * = Print interrupt-related info.
80 * = Print interrupt tree traversal info.
100 * = Print address resolution info.
200 * = Print NV-RAM info.
400 * = Print Mac OS "universal" info.
800 * = Print "special" node info.
1000 * = Load EtherPrintf utility via parcel for post FCode debugging.
2000 * = Print BOOTP/DHCP/BSDP information.
4000 = Allocate writable ROM aperture.
8000 = Mark Toolbox image as non-cacheable.
10000 * = Print parcel info while copying the device tree.
20000 = Print information on device tree data checksums.
1000000 = Enable the Nanokernel debugger.
2000000 = Display the Nanokernel log during boot.
10000000 = Dont attempt to unhibernate system.
40000000 = Halt after end of FCode (useful if outputting to screen).
MacOS: RTAS not found.
work area logical address = 0x3FAD8000, physical address = 0x3FAD8000.
IsKeyDown: no keys held down
gdb-multiarch
gdb-multiarch
GNU gdb (Debian 7.12-6) 7.12.0.20161007-git
Copyright (C) 2016 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word".
warning: scripts/qemu-gdb.py: No such file or directory
(gdb) target remote localhost:1234
Remote debugging using localhost:1234
warning: No executable has been specified and target does not support
determining executable automatically. Try using the "file" command.
0x0001f0ff00000000 in ?? ()
(gdb) break *0x2025f4
Breakpoint 1 at 0x2025f4
(gdb) continue
Continuing.
Program received signal SIGTRAP, Trace/breakpoint trap.
0xf425200000000000 in ?? ()
(gdb)
Am I getting the proper breakpoint for our test?
-
Program received signal SIGTRAP, Trace/breakpoint trap.
0xf425200000000000 in ?? ()
(gdb)
Am I getting the proper breakpoint for our test?
What does (gdb)disas $pc
say when you hit the breakpoint?
Does the following command sequence work?
(gdb)display/i $pc
(gdb)stepi
You should be able to execute instruction by instruction and see the PPC Asm of the instruction to be executed next.
-
That didn't work, gdb-multiarch must be the wrong debugger, I'll see if I can figure how to setup PPC gdb.
gdb-multiarch
GNU gdb (Debian 7.12-6) 7.12.0.20161007-git
Copyright (C) 2016 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word".
warning: scripts/qemu-gdb.py: No such file or directory
(gdb) target remote localhost:1234
Remote debugging using localhost:1234
warning: No executable has been specified and target does not support
determining executable automatically. Try using the "file" command.
0x0001f0ff00000000 in ?? ()
(gdb) break *0x2025f4
Breakpoint 1 at 0x2025f4
(gdb) continue
Continuing.
Program received signal SIGTRAP, Trace/breakpoint trap.
0xf425200000000000 in ?? ()
(gdb) disas $pc
No function contains specified address.
(gdb) disas $pc
No function contains specified address.
(gdb) display/i $pc
1: x/i $pc
=> 0xf425200000000000:
<error: Cannot access memory at address 0xf425200000000000>
(gdb) stepi
Program stopped.
0xf425200000000000 in ?? ()
1: x/i $pc
=> 0xf425200000000000:
<error: Cannot access memory at address 0xf425200000000000>
Cannot access memory at address 0xf425200000000000
(gdb)
-
I built powerpc-linux-gdb, but I'm unsure I built it correct?
(gdb) disas $pc
No function contains specified address.
(gdb) display/i $pc
1: x/i $pc
=> 0x2025f8: stmw r28,-16(r1)
(gdb) stepi
0x00000000002025fc in ?? ()
1: x/i $pc
=> 0x2025fc: stw r0,8(r1)
(gdb)
It looks like maybe it's returning ppc assembly, Am I getting warmer?
-
That didn't work, gdb-multiarch must be the wrong debugger, I'll see if I can figure how to setup PPC gdb.
Did you try to invoke qemu-system-ppc64 with the "-g" option? Quoting https://reverseengineering.stackexchange.com/questions/8829/cross-debugging-for-arm-mips-elf-with-qemu-toolchain (https://reverseengineering.stackexchange.com/questions/8829/cross-debugging-for-arm-mips-elf-with-qemu-toolchain)
In order to debug the binary with GDB, you need to launch qemu-mips so that it exposes a GDB stub, and connect from GDB.
Here another similar post: http://tinkering-is-fun.blogspot.com/2009/12/debugging-non-native-programs-with-qemu.html (http://tinkering-is-fun.blogspot.com/2009/12/debugging-non-native-programs-with-qemu.html)
-
That didn't work, gdb-multiarch must be the wrong debugger, I'll see if I can figure how to setup PPC gdb.
Did you try to invoke qemu-system-ppc64 with the "-g" option? Quoting https://reverseengineering.stackexchange.com/questions/8829/cross-debugging-for-arm-mips-elf-with-qemu-toolchain (https://reverseengineering.stackexchange.com/questions/8829/cross-debugging-for-arm-mips-elf-with-qemu-toolchain)
In order to debug the binary with GDB, you need to launch qemu-mips so that it exposes a GDB stub, and connect from GDB.
Here another similar post: http://tinkering-is-fun.blogspot.com/2009/12/debugging-non-native-programs-with-qemu.html (http://tinkering-is-fun.blogspot.com/2009/12/debugging-non-native-programs-with-qemu.html)
The -g argument is reserved for the graphics mode on the mac99 machine in qemu-system-ppc.
-
I don't know if I'm doing this correct, if if I have the debugger setup correct, however:
It seem the closest point in the trampoline I can find a breakpoint for, before we get to the memory overlap is a breakpoint 0x20dccc
Breakpoint 2, 0x000000000020dccc in ?? ()
(gdb) display/i $pc
1: x/i $pc
=> 0x20dccc: stwu r1,-80(r1)
(gdb) stepi
0x000000000020dcd0 in ?? ()
1: x/i $pc
=> 0x20dcd0: stw r6,116(r1)
(gdb)
0x000000000020dcd4 in ?? ()
1: x/i $pc
=> 0x20dcd4: stw r7,120(r1)
(gdb)
0x000000000020dcd8 in ?? ()
1: x/i $pc
=> 0x20dcd8: stw r8,124(r1)
(gdb)
0x000000000020dcdc in ?? ()
1: x/i $pc
=> 0x20dcdc: stw r9,128(r1)
(gdb)
0x000000000020dce0 in ?? ()
1: x/i $pc
=> 0x20dce0: stw r10,132(r1)
(gdb)
0x000000000020dce4 in ?? ()
1: x/i $pc
=> 0x20dce4: lwz r30,-12(r2)
(gdb)
0x000000000020dce8 in ?? ()
1: x/i $pc
=> 0x20dce8: mr r29,r5
(gdb)
0x000000000020dcec in ?? ()
1: x/i $pc
=> 0x20dcec: addi r6,r2,26808
(gdb)
0x000000000020dcf0 in ?? ()
1: x/i $pc
=> 0x20dcf0: addi r8,r29,2
(gdb)
0x000000000020dcf4 in ?? ()
1: x/i $pc
=> 0x20dcf4: stw r6,0(r30)
(gdb)
0x000000000020dcf8 in ?? ()
1: x/i $pc
=> 0x20dcf8: cmpwi r29,0
(gdb)
0x000000000020dcfc in ?? ()
1: x/i $pc
=> 0x20dcfc: stw r8,4(r30)
(gdb)
0x000000000020dd00 in ?? ()
1: x/i $pc
=> 0x20dd00: addi r31,r1,120
(gdb)
0x000000000020dd04 in ?? ()
1: x/i $pc
=> 0x20dd04: lwz r9,116(r1)
(gdb)
0x000000000020dd08 in ?? ()
1: x/i $pc
=> 0x20dd08: addi r7,r30,20
(gdb)
0x000000000020dd0c in ?? ()
1: x/i $pc
=> 0x20dd0c: addi r9,r9,1
(gdb)
0x000000000020dd10 in ?? ()
1: x/i $pc
=> 0x20dd10: stw r9,8(r30)
(gdb)
0x000000000020dd14 in ?? ()
1: x/i $pc
=> 0x20dd14: stw r3,12(r30)
(gdb)
0x000000000020dd18 in ?? ()
1: x/i $pc
=> 0x20dd18: stw r4,16(r30)
(gdb)
0x000000000020dd1c in ?? ()
1: x/i $pc
That maybe just gibberish, I don't know PPC assembly and I've only used gdb a few times to step though some C code, and never tried to debug a running target in Qemu.
Let me know if I'm barking up the wrong tree here?
The trampoline seem to hit that address a few times, so it breaks @ 0x20dccc a few times before it gets to this point:
Hardware info:
Dumping 192 bytes @ 0x3FEE4000
3FEE4000: 00C00000 6400000C 64048084 00003000
3FEE4010: 3FEDD000 3FEDF000 80040000 00000000
3FEE4020: 00000000 00000000 00000000 00000000
3FEE4030: 00000000 00000000 00000000 00001400
3FEE4040: 00000000 00000000 00000000 00000000
3FEE4050: 00000000 00000000 00000000 00000000
3FEE4060: 00000000 00000000 00000000 00000000
3FEE4070: 486E666F 00403035 00250024 08000800
3FEE4080: 00190000 08000800 00400000 00000000
3FEE4090: 00000000 00000004 00000000 00410000
3FEE40A0: 1A05D66A 00000000 3FEDE000 00000000
3FEE40B0: 00000000 00000000 00000000 00000000
HardwareInit info:
Dumping 32 bytes @ 0x3FEE7000
3FEE7000: 3FEE5000 3FEE6000 00000000 3FEE4000
3FEE7010: 00000000 00000080 00F10000 80012000
Cascade Info:
Dumping 516 bytes @ 0x00117818
00117818: 00000000 FFFFFFFF FFFFFFFF FFFFFFFF
00117828: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF
00117838: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF
00117848: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF
00117858: FFFFFFFF 01040404 04040402 04020402
00117868: 02000000 00000000 00000000 00000000
00117878: 00000000 00000000 00000000 00000000
00117888: 00000000 00000000 00000000 00000000
00117898: 00000000 00000000 00000000 00000000
001178A8: 00000000 00000000 00000000 00000000
001178B8: 00000000 00000000 00000000 00000000
001178C8: 00000000 00000000 00000000 00000000
001178D8: 00000000 00000000 00000000 00000000
001178E8: 00000000 00000000 00000000 00000000
001178F8: 00000000 00000000 00000000 00000000
00117908: 00000000 00000000 00000000 00000000
00117918: 00000000 00000000 00000000 00000000
00117928: 00000000 00000000 00000000 00000000
00117938: 00000000 00000000 00000000 00000000
00117948: 00000000 00000000 00000000 00000000
00117958: 00000000 00000000 00000000 00000000
00117968: 00000000 00000000 00000000 00000000
00117978: 00000000 00000000 00000000 00000000
00117988: 00000000 00000000 00000000 00000000
00117998: 00000000 00000000 00000000 00000000
001179A8: 00000000 00000000 00000000 00000000
001179B8: 00000000 00000000 00000000 00000000
001179C8: 00000000 00000000 00000000 00000000
001179D8: 00000000 00000000 00000000 00000000
001179E8: 00000000 00000000 00000000 00000000
001179F8: 00000000 00000000 00000000 00000000
00117A08: 00000000 00000000 00000000 00000000
00117A18: 00000000
The next continue gives:
IsKeyDown: no keys held down
Overlap in AddMemoryRelocationEntry().
- dst = 0x00003000, dstLength = 0x0000052C, entry->dst = 0x00000000, entry->dst_len = 0x00048298.
Overlap in AddMemoryRelocationEntry().
- dst = 0x00003F80, dstLength = 0x00000080, entry->dst = 0x00000000, entry->dst_len = 0x00048298.
Overlap in AddMemoryRelocationEntry().
- dst = 0x00003F40, dstLength = 0x00000040, entry->dst = 0x00000000, entry->dst_len = 0x00048298.
Overlap in AddMemoryRelocationEntry().
- dst = 0x00003CFC, dstLength = 0x00000204, entry->dst = 0x00000000, entry->dst_len = 0x00048298.
Overlap in AddMemoryRelocationEntry().
- dst = 0x00003F00, dstLength = 0x00000040, entry->dst = 0x00000000, entry->dst_len = 0x00048298.
-
I don't know if I'm doing this correct, if if I have the debugger setup correct [snip]
Congrats! It looks like you got the QEMU+GDB toolchain set up correctly. Memory addresses are big-endian now (0x000000000020dccc instead of x86's 0x20dccc0000000000) and stepping works as well.
Would you mind posting a step-by-step instructions on how to setup that toolchain? Just for the case if someone want to step in and help us out...
It seem the closest point in the trampoline I can find a breakpoint for, before we get to the memory overlap is a breakpoint 0x20dccc
I don't understand that. What command was used to set that breakpoint? Any other address doesn't work?
That maybe just gibberish, I don't know PPC assembly and I've only used gdb a few times to step though some C code, and never tried to debug a running target in Qemu.
The code looks right. 0x20dccc belongs to CallMethod() function inside the Trampoline. The function itself starts @0x20dcc0.
To be done next:
- run a disassembler on the target code and obtain a good disassembly listing
- PM me your GitLab account name. If you don't own any GitLab account, set up one first at gitlab.org. I'll grant you an access to my C source code for the Trampoline
- obtain docs on the OF client interface (google for 1275-1994.pdf)
Then having the assembly listing on the left hand side and the C code on the right hand side, you'd trace the target code and compare its behavior with the expected one. This will be a lot of fun and you'll learn the PPC assembly very quickly ;D
-
To build gdb-powerpc-linux on Linux, you'll need normal build tools such as gcc installed, I'll assume people know how to install that stuff with apt or their other package manager. Anything you don't have you need installed to build, it will likely let you know when you try to configure.
Download the GDB source code, I had trouble with the latest release, so likely people will want to use v7.9.
http://ftp.gnu.org/gnu/gdb/gdb-7.9.tar.gz
Unpack it and cd into the dir, then just:
./configure -target=powerpc-linux --enable-sim-powerpc
make && sudo make install
After that, all you need to do is launch qemu-system-ppc(64) with -s and -S, it will pause and listen on port 1234 for GDB.
Then in another terminal launch gdb:
gdb-powerpc-linux
target remote localhost:1234
continue
You'll likely want to set prom-env "auto-boot?=false" --nographic for Qemu.
Set your breakpoint in GDB, I.E.
break *0x20dccc
Then type boot in the Qemu terminal.
.
-
I don't know if I'm doing this correct, if if I have the debugger setup correct [snip]
Congrats! It looks like you got the QEMU+GDB toolchain set up correctly. Memory addresses are big-endian now (0x000000000020dccc instead of x86's 0x20dccc0000000000) and stepping works as well.
Would you mind posting a step-by-step instructions on how to setup that toolchain? Just for the case if someone want to step in and help us out...
It seem the closest point in the trampoline I can find a breakpoint for, before we get to the memory overlap is a breakpoint 0x20dccc
I don't understand that. What command was used to set that breakpoint? Any other address doesn't work?
I was just trying to find a breakpoint nearest to the code that is causing the memory overlap. CallMethod() seems to be executed a few times, once just before we get our overlap, so hopefully that will help us find the exact code that needs work.
-
I was just trying to find a breakpoint nearest to the code that is causing the memory overlap. CallMethod() seems to be executed a few times, once just before we get our overlap, so hopefully that will help us find the exact code that needs work.
I see. The problem is that CallMethod() is completely unrelated to our issue. You need to track calls to AddMemoryRelocationEntry() located @0x201DB4. This function has the following prototype:
int AddMemoryRelocationEntry(uint32_t src, uint32_t srcLength, uint32_t dst,
uint32_t dstLength, uint32_t flags);
The PowerPC ABI prescribes that the first 7 parameters will be always passed in registers starting with R3, i.e. R3 = src, R4 = srcLength, R5 = dst, R6 = dstLength, R7 = flags. Return values will be placed in R3. For further details, see reloc.c, line 75 in my code.
The destination address "dst" will be set to NULL somewhere causing AddMemoryRelocationEntry to reserve a big block of memory @0x00000000. That's wrong and the task is to determine why that actually happens.
I suppose that the faulty call to AddMemoryRelocationEntry is located in main at 0x2059f4. "dst"(R5) will probably contain NULL. This address is also calculated there based on the value in NKSystemInfo.PhysicalMemorySize that should contain zero in your precise case.
The task is also to verify if the above mentioned conditions hold true and when they do, try to find out which code sets NKSystemInfo.PhysicalMemorySize to zero.
-
I was just trying to find a breakpoint nearest to the code that is causing the memory overlap. CallMethod() seems to be executed a few times, once just before we get our overlap, so hopefully that will help us find the exact code that needs work.
I see. The problem is that CallMethod() is completely unrelated to our issue. You need to track calls to AddMemoryRelocationEntry() located @0x201DB4. This function has the following prototype:
int AddMemoryRelocationEntry(uint32_t src, uint32_t srcLength, uint32_t dst,
uint32_t dstLength, uint32_t flags);
The Power ABI prescribes that the first 7 parameters will be always passed in registers starting with R3, i.e. R3 = src, R4 = srcLength, R5 = dst, R6 = dstLength, R7 = flags. Return values will be placed in R3. For further details, see reloc.c, line 75 in my code.
The destination address "dst" will be set to NULL somewhere causing AddMemoryRelocationEntry to reserve a big block of memory @0x00000000. That's wrong and the task is to determine why that actually happens.
I suppose that the faulty call to AddMemoryRelocationEntry is located in main at 0x2059f4. "dst"(R5) will probably contain NULL. This address is also calculated there based on the value in NKSystemInfo.PhysicalMemorySize that should contain zero in your precise case.
The task is also to verify if the above mentioned conditions hold true and when they do, try to find out which code sets NKSystemInfo.PhysicalMemorySize to zero.
Thanks, I understand some of that, I'll look into it, and see if I can figure some sort of work around. I'll just have to see what goes on in Qemu with the G4 CPU and maybe that will tell me what goes wrong with the G5.
I'm sure I'll have lots of question. ;D
-
Thanks, I understand some of that, I'll look into it, and see if I can figure some sort of work around.
Let's spot the issue first by answering the following questions:
- does the call to AddMemoryRelocationEntry in the basic block at 0x2059f4 pass zero in R5? (yes/no)
- if 1. is true, does R3 at 0x2059fc contain zero as well? (yes/no)
- please dump the memory pointed to by R23 at 0x2059fc and post it here. The size of the dump is 320 bytes (i.e. sizeof(NKSystemInfo))
I'm sure I'll have lots of question. ;D
Don't hesitate to ask here :D
-
OK, I've successfully pulled the repo. It wasn't really what I was expecting, not that I'm complaining, but I was thinking it had the code to decompile the trampoline, and maybe patch and recompile it.
Like I say, not a complaint, I'm just not real sure how to use this code to patch the trampoline.
Anywho, the recol.c seems to contain the code we are tripping over:
int AddMemoryRelocationEntry(uint32_t src, uint32_t srcLength, uint32_t dst,
uint32_t dstLength, uint32_t flags)
{
int i;
uint32_t size;
MemRelocEntry *pEntry;
MemRelocList *pNewList;
if (gMemRelocList == 0) {
gMemRelocList = ClaimMem(sizeof(MemRelocList), 2);
if ((int)gMemRelocList == -1)
return 0;
gMemRelocList->cnt.nUsedEntries = 0;
gMemRelocList->cnt.nFreeEntries = 64;
}
for (i = 0; i < gMemRelocList->cnt.nUsedEntries; i++) {
pEntry = &gMemRelocList->entries[i];
if ((dst + dstLength) > pEntry->dst && (pEntry->dst + pEntry->dst_len) > dst) {
printf("Overlap in AddMemoryRelocationEntry().\r");
printf(" - dst = 0x%08X, dstLength = 0x%08X,"
" entry->dst = 0x%08X, entry->dst_len = 0x%08X.\r",
dst, dstLength, pEntry->dst, pEntry->dst_len);
gFatalErr = 1;
return 1;
}
}
for (i = 0; i < gMemRelocList->cnt.nUsedEntries; i++) {
pEntry = &gMemRelocList->entries[i];
if ((src + srcLength) > pEntry->src && (pEntry->src + pEntry->src_len) > src) {
printf("Overlap in AddMemoryRelocationEntry().\r");
printf(" - src = 0x%08X, srcLength = 0x%08X,"
" entry->src = 0x%08X, entry->src_len = 0x%08X.\r",
src, srcLength, pEntry->src, pEntry->src_len);
gFatalErr = 1;
return 1;
}
}
I'm not real sure exactly why we are failing here, or how to insert some code here to help with debugging?
-
Thanks, I understand some of that, I'll look into it, and see if I can figure some sort of work around.
Let's spot the issue first by answering the following questions:
- does the call to AddMemoryRelocationEntry in the basic block at 0x2059f4 pass zero in R5? (yes/no)
- if 1. is true, does R3 at 0x2059fc contain zero as well? (yes/no)
- please dump the memory pointed to by R23 at 0x2059fc and post it here. The size of the dump is 320 bytes (i.e. sizeof(NKSystemInfo))
I'm sure I'll have lots of question. ;D
Don't hesitate to ask here :D
I'm not real sure how to do 1, 2 , or 3, I'll need some exact examples, as well as a basic overview of the process.
-
Breakpoint 1, 0x00000000002059f4 in ?? ()
(gdb) display/i $pc
1: x/i $pc
=> 0x2059f4: lwz r23,0(r26)
(gdb) stepi
0x00000000002059f8 in ?? ()
1: x/i $pc
=> 0x2059f8: addi r6,r28,3
(gdb) stepi
0x00000000002059fc in ?? ()
1: x/i $pc
=> 0x2059fc: lwz r3,0(r23)
(gdb)
-
I'm not real sure how to do 1, 2 , or 3, I'll need some exact examples, as well as a basic overview of the process.
Well, as I already said before, you need to obtain a disassembling list for the code you're trying to debug. For that purpose, you need a disassembler. Fortunately, you have several choices: IDA Pro freeware, Hopper, Radare2...
Below the snippet of interest:
002059F4 lwz r23, 0(r26)
002059F8 addi r6, r28, 3
002059FC lwz r3, 0(r23)
00205A00 mr r4, r28 # srcLength
00205A04 li r7, 1 # flags
00205A08 divwu r5, r3, r16
00205A0C lwz r3, 724(r1) # src
00205A10 slwi r5, r5, 1
00205A14 addis r5, r5, 0x10
00205A18 clrrwi r6, r6, 2 # dstLength
00205A1C addi r5, r5, -1
00205A20 clrrwi r5, r5, 20 # dst
00205A24 bl AddMemoryRelocationEntry
Then you set a breakpoint at 0x2059f4 and executes your target until it hits that breakpoint. To obtain a memory dump, you use GDB's "x" command:
(gdb) break *0x2059f4
(gdb) cont
...
Breakpoint 1, 0x00000000002059f4 in ?? ()
(gdb) display/i $pc
(gdb) stepi
(gdb) x/80w $r23
The last command will dump 320 bytes of memory starting with $r23, formatted as 80 big-endian double words.
The next example shows how to read the value of R5 at 0x205a20 (that's the "dst" param passed to AddMemoryRelocationEntry, see the snippet above):
(gdb) break *0x205a24
(gdb) cont
(gdb) info registers
I set a breakpoint past the instruction of interest to ensure it has been executed (that's why I set a breakpoint at 0x205a20+4). Then I dump the CPU register file with "info registers" to examine the value of R3.
-
OK, I've successfully pulled the repo. It wasn't really what I was expecting, not that I'm complaining, but I was thinking it had the code to decompile the trampoline, and maybe patch and recompile it.
You expected to find the source code for a full-blown PPC decompiler there?
I wonder how you interpret the term "decompilation".
Mapping some binary code to a list of processor mnemonics (i.e. disassembly) is relatively easy. That's what a tool called "disassembler" is capable of performing automatically. Well, near automatically.
Reconstructing a high-level source code for a compiled executable program (in other words, "decompilation" as the inverse of "compilation") is, in contrast, an enormously hard task. No tool doing that ever existed and will likely never exist.
Decompilation is mostly carried out by humans using various program analysis tools. For further details, please refer to this thread: http://macos9lives.com/smforum/index.php/topic,3953.0.html
I'm just not real sure how to use this code to patch the trampoline.
My code is a translation from PPC Asm to C. You find a bug on the binary level, fix it in the C source and then recompile the whole Trampoline using a PowerPC C compiler (gcc, MPW's MrC, whatsoever). Then you bundle this new version in a custom "Mac OS ROM" file using CDG5 tools (https://github.com/elliotnunn/newworld-rom) and replace the ROM file shipped with Mac OS with your "fixed" version.
That's how it supposed to work. I call it "high-level hacking". The reality is a bit different: the decompiled code must be complete and compilable. That's what I'm currently working on.
I'm not real sure exactly why we are failing here, or how to insert some code here to help with debugging?
Until I complete Trampoline's decompilation, you'll have to resort to the "low-level hacking", that is, working on the binary/Asm level. The decompiled code should help to understand how the binary program works, which data it uses and how this data is laid out in memory. The missing mapping between the C source and its compiled form must be done in our brains. ???
-
Breakpoint 1, 0x00000000002059f4 in ?? ()
1: x/i $pc
=> 0x2059f4: lwz r23,0(r26)
(gdb) display/i $pc
2: x/i $pc
=> 0x2059f4: lwz r23,0(r26)
(gdb) stepi
0x00000000002059f8 in ?? ()
2: x/i $pc
=> 0x2059f8: addi r6,r28,3
1: x/i $pc
=> 0x2059f8: addi r6,r28,3
(gdb) x/80w $r23
0x3fec0000: 0 0 0 0
0x3fec0010: 0 0 0 0
0x3fec0020: 0 0 0 0
0x3fec0030: 0 12582912 15040512 684032
0x3fec0040: 16777216 -16777216 0 0
0x3fec0050: 0 0 0 0
0x3fec0060: 0 0 0 0
0x3fec0070: 0 0 0 0
0x3fec0080: 0 0 0 0
0x3fec0090: 0 0 0 0
0x3fec00a0: 0 0 0 0
0x3fec00b0: 0 0 0 0
0x3fec00c0: 0 0 0 0
0x3fec00d0: 0 0 0 0
0x3fec00e0: 0 0 0 0
0x3fec00f0: 0 0 0 0
0x3fec0100: -2147221504 0 0 0
0x3fec0110: 0 0 0 0
0x3fec0120: 0 0 53 -805306368
0x3fec0130: 0 0 0 0
(gdb) break *0x205a24
Breakpoint 2 at 0x205a24
(gdb) cont
Continuing.
Breakpoint 2, 0x0000000000205a24 in ?? ()
2: x/i $pc
=> 0x205a24: bl 0x201db4
1: x/i $pc
=> 0x205a24: bl 0x201db4
(gdb) info register
r0 0x2059ec 2120172
r1 0x116a28 1141288
r2 0x1001e8 1049064
r3 0x3f280000 1059586048
r4 0x48498 296088
r5 0x0 0
r6 0x48498 296088
r7 0x1 1
r8 0x0 0
r9 0x11669c 1140380
r10 0x106e84 1076868
r11 0x106e8b 1076875
r12 0x1198b8 1153208
r13 0x0 0
r14 0x100698 1050264
r15 0xa 10
r16 0x3 3
r17 0x3fee1000 1072566272
r18 0x3fee1000 1072566272
r19 0x106e48 1076808
r20 0x3fee1000 1072566272
r21 0x8 8
r22 0x117818 1144856
---Type <return> to continue, or q <return> to quit---
r23 0x3fec0000 1072431104
r24 0x8 8
r25 0x816116f9 2170623737
r26 0x117080 1142912
r27 0x1170ac 1142956
r28 0x48498 296088
r29 0x106b34 1076020
r30 0x117088 1142920
r31 0x117084 1142916
pc 0x205a24 0x205a24
msr 0x3030 12336
cr 0x22400244 574620228
lr 0x2059ec 0x2059ec
ctr 0xfff025d0 4293928400
xer 0x0 0
(gdb)
-
OK, I've successfully pulled the repo. It wasn't really what I was expecting, not that I'm complaining, but I was thinking it had the code to decompile the trampoline, and maybe patch and recompile it.
You expected to find the source code for a full-blown PPC decompiler there?
I wonder how you interpret the term "decompilation".
Mapping some binary code to a list of processor mnemonics (i.e. disassembly) is relatively easy. That's what a tool called "disassembler" is capable of performing automatically. Well, near automatically.
Reconstructing a high-level source code for a compiled executable program (in other words, "decompilation" as the inverse of "compilation") is, in contrast, an enormously hard task. No tool doing that ever existed and will likely never exist.
Decompilation is mostly carried out by humans using various program analysis tools. For further details, please refer to this thread: http://macos9lives.com/smforum/index.php/topic,3953.0.html
I'm just not real sure how to use this code to patch the trampoline.
My code is a translation from PPC Asm to C. You find a bug on the binary level, fix it in the C source and then recompile the whole Trampoline using a PowerPC C compiler (gcc, MPW's MrC, whatsoever). Then you bundle this new version in a custom "Mac OS ROM" file using CDG5 tools (https://github.com/elliotnunn/newworld-rom) and replace the ROM file shipped with Mac OS with your "fixed" version.
That's how it supposed to work. I call it "high-level hacking". The reality is a bit different: the decompiled code must be complete and compilable. That's what I'm currently working on.
I'm not real sure exactly why we are failing here, or how to insert some code here to help with debugging?
Until I complete Trampoline's decompilation, you'll have to resort to the "low-level hacking", that is, working on the binary/Asm level. The decompiled code should help to understand how the binary program works, which data it uses and how this data is laid out in memory. The missing mapping between the C source and its compiled form must be done in our brains. ???
OK, I see, I realize how hard it must have been to get the source files you have in the repo, as I've made attempts at reverse engineering binary data before. Normally I just revert to binary hacks in a hex editor, tho in this case I'm going to have to get my hands dirty and learn some new tricks. ;D
I was just kind of hoping things would be a little easer, but it's ok. I was really just hoping for a makefile and some instructions on how to build in WPM or something, but I can see it's move involved than that, as the trampoline is just one part of the Mac OS ROM.
A lot of these things are beyond my understanding, at this point, so forgive my ignorance.
-
Breakpoint 1, 0x00000000002059f4 in ?? ()
1: x/i $pc
=> 0x2059f4: lwz r23,0(r26)
(gdb) display/i $pc
2: x/i $pc
=> 0x2059f4: lwz r23,0(r26)
(gdb) stepi
0x00000000002059f8 in ?? ()
2: x/i $pc
=> 0x2059f8: addi r6,r28,3
1: x/i $pc
=> 0x2059f8: addi r6,r28,3
(gdb) x/80w $r23
0x3fec0000: 0 0 0 0
0x3fec0010: 0 0 0 0
0x3fec0020: 0 0 0 0
0x3fec0030: 0 12582912 15040512 684032
0x3fec0040: 16777216 -16777216 0 0
0x3fec0050: 0 0 0 0
0x3fec0060: 0 0 0 0
0x3fec0070: 0 0 0 0
0x3fec0080: 0 0 0 0
0x3fec0090: 0 0 0 0
0x3fec00a0: 0 0 0 0
0x3fec00b0: 0 0 0 0
0x3fec00c0: 0 0 0 0
0x3fec00d0: 0 0 0 0
0x3fec00e0: 0 0 0 0
0x3fec00f0: 0 0 0 0
0x3fec0100: -2147221504 0 0 0
0x3fec0110: 0 0 0 0
0x3fec0120: 0 0 53 -805306368
0x3fec0130: 0 0 0 0
(gdb) break *0x205a24
Breakpoint 2 at 0x205a24
(gdb) cont
Continuing.
Breakpoint 2, 0x0000000000205a24 in ?? ()
2: x/i $pc
=> 0x205a24: bl 0x201db4
1: x/i $pc
=> 0x205a24: bl 0x201db4
(gdb) info register
r0 0x2059ec 2120172
r1 0x116a28 1141288
r2 0x1001e8 1049064
r3 0x3f280000 1059586048
r4 0x48498 296088
r5 0x0 0
r6 0x48498 296088
r7 0x1 1
r8 0x0 0
r9 0x11669c 1140380
r10 0x106e84 1076868
r11 0x106e8b 1076875
r12 0x1198b8 1153208
r13 0x0 0
r14 0x100698 1050264
r15 0xa 10
r16 0x3 3
r17 0x3fee1000 1072566272
r18 0x3fee1000 1072566272
r19 0x106e48 1076808
r20 0x3fee1000 1072566272
r21 0x8 8
r22 0x117818 1144856
---Type <return> to continue, or q <return> to quit---
r23 0x3fec0000 1072431104
r24 0x8 8
r25 0x816116f9 2170623737
r26 0x117080 1142912
r27 0x1170ac 1142956
r28 0x48498 296088
r29 0x106b34 1076020
r30 0x117088 1142920
r31 0x117084 1142916
pc 0x205a24 0x205a24
msr 0x3030 12336
cr 0x22400244 574620228
lr 0x2059ec 0x2059ec
ctr 0xfff025d0 4293928400
xer 0x0 0
(gdb)
Thanks. That dumps have answered all three questions of mine. AddMemoryRelocationEntry is called with dst=0 which usually shouldn't happen. The value of dst is calculated using the following C statement:
dst = (NKSystemInfo.PhysicalMemorySize / 3 * 2 + 0xFFFFF) & 0xFFF00000;
In other words, it takes 2/3 of the available physical memory and align that amount to the 1MB boundary. This will be the physical destination address for the flattened device tree.
In your precise case, that destination address is 0x00000000 because NKSystemInfo.PhysicalMemorySize contains zero. That's the reason why the consequent calls to AddMemoryRelocationEntry fail.
Would you kindly verify which calls to AddMemoryRelocationEntry report overlapping? To achieve that, you need to set the following breakpoints (each one past a blr AddMemoryRelocationEntry):
0x205A28 (shouldn't report any error)
0x205A58
0x205A88
0x205AC8
0x205B08
0x205B48
Everytime each of these breakpoints is reached and NO error appears in the QEMU console, mark the corresponding call as "false". Otherwise, mark it as "true".
Moreover, I'd appreciate a memory dump at "src", i.e.
break *0x205A24
cont
x/32xb $r3
-
0x205A28 (shouldn't report any error)
0x205A58 false
0x205A88 true
0x205AC8 true
0x205B08 true
0x205B48 true
(gdb) break *0x205A24
Note: breakpoint 7 also set at pc 0x205a24.
Breakpoint 8 at 0x205a24
(gdb) cont
Continuing.
Breakpoint 7, 0x0000000000205a24 in ?? ()
(gdb) x/32xb $r3
0x3fad8000: 0x50 0x4d 0x52 0x26 0x42 0x47 0x73 0x54
0x3fad8008: 0x72 0x65 0x65 0x00 0x00 0x00 0x00 0x00
0x3fad8010: 0x00 0x00 0x00 0x0c 0x00 0x02 0xef 0x70
0x3fad8018: 0x00 0x00 0x00 0x0c 0x00 0x00 0x00 0x00
(gdb)
-
0x205A28 (shouldn't report any error)
0x205A58 false
0x205A88 true
0x205AC8 true
0x205B08 true
0x205B48 true
According to the error log reported earlier, 0x205A58 is expected to fail as well. Can you recheck?
0x3fad8000: 0x50 0x4d 0x52 0x26 0x42 0x47 0x73 0x54
0x3fad8008: 0x72 0x65 0x65 0x00 0x00 0x00 0x00 0x00
0x3fad8010: 0x00 0x00 0x00 0x0c 0x00 0x02 0xef 0x70
0x3fad8018: 0x00 0x00 0x00 0x0c 0x00 0x00 0x00 0x00
(gdb)
Yes, that's the beginning of the flattened device tree. ;D
-
0x205A28 (shouldn't report any error)
0x205A58 false
0x205A88 true
0x205AC8 true
0x205B08 true
0x205B48 true
According to the error log reported earlier, 0x205A58 is expected to fail as well. Can you recheck?
0x3fad8000: 0x50 0x4d 0x52 0x26 0x42 0x47 0x73 0x54
0x3fad8008: 0x72 0x65 0x65 0x00 0x00 0x00 0x00 0x00
0x3fad8010: 0x00 0x00 0x00 0x0c 0x00 0x02 0xef 0x70
0x3fad8018: 0x00 0x00 0x00 0x0c 0x00 0x00 0x00 0x00
(gdb)
Yes, that's the beginning of the flattened device tree. ;D
0x20a58 does fail.
-
It's worth trying to set R5 before AddMemoryRelocationEntry to the correct value to see if it fixes that fatal error.
(gdb) break *0x205A24
(gdb) cont
(gdb) set $r5=0x2AB00000
(gdb) cont
0x2AB00000 is calculated from the assigned physical memory, i.e. ((1024*1024*1024) / 3 * 2 + 0xFFFFF) & 0xFFF0000 = 0x2AB00000.
I'm curious what happens then...
-
It's worth trying to set R5 before AddMemoryRelocationEntry to the correct value to see if it fixes that fatal error.
(gdb) break *0x205A24
(gdb) cont
(gdb) set $r5=0x2AB00000
(gdb) cont
0x2AB00000 is calculated from the assigned physical memory, i.e. ((1024*1024*1024) / 3 * 2 + 0xFFFFF) & 0xFFF0000 = 0x2AB00000.
I'm curious what happens then...
Off to MacOS. The next (and last) call into OpenFirmware is quiesce(). ;D
Never boots tho, I removed --nographic, and tried both the 970 and the 970fx.
I'm not getting any errors, the system just stays at the OB prompt with the last line:
Off to MacOS. The next (and last) call into OpenFirmware is quiesce().
-
Off to MacOS. The next (and last) call into OpenFirmware is quiesce(). ;D
Terrific! We're on the right track ;)
Never boots tho, I removed --nographic, and tried both the 970 and the 970fx.
I'm not getting any errors, the system just stays at the OB prompt with the last line:
Off to MacOS. The next (and last) call into OpenFirmware is quiesce().
Yes, I suspect a silent crash in the RelocationEngine due to the use of unsupported BATs. We'll fix it later.
Let's figure out where and why NKSystemInfo.PhysicalMemorySize is set to zero.
Breakpoint at 0x2052F0, dword at $r26 will contain the pointer to NKSystemInfo. I need a dump of NKSystemInfo at this location.
(gdb) break *0x2052F0
(gdb) cont
(gdb) x/1xw $r26
GDB will display an address here
(gdb) x/8xw *address shown above
-
Breakpoint 1, 0x00000000002052f0 in ?? ()
(gdb) x/1xw $r26
0x117080: 0x3fee5000
(gdb) x/8xw *0x3fee5000
0x40000000: Cannot access memory at address 0x40000000
(gdb) x/8xw *0x117080
0x3fee5000: 0x40000000 0x40000000 0x00000000 0x00000000
0x3fee5010: 0x00000000 0x00000000 0x00000000 0x00000000
(gdb)
-
Breakpoint 1, 0x00000000002052f0 in ?? ()
(gdb) x/1xw $r26
0x117080: 0x3fee5000
(gdb) x/8xw *0x3fee5000
0x40000000: Cannot access memory at address 0x40000000
(gdb) x/8xw *0x117080
0x3fee5000: 0x40000000 0x40000000 0x00000000 0x00000000
0x3fee5010: 0x00000000 0x00000000 0x00000000 0x00000000
(gdb)
Thanks. The NKSystemInfo structure is located at 0x3fee5000. The first two dwords - PhysicalMemorySize and UsableMemorySize - contain the correct value of 0x40000000 (= 1024MB). The full definition of this structure is located in macosstructs.h:142.
Next step is to find out where these both fields will be set to zero. You'd need to work with watchpoints here to monitor access to 0x3fee5000 between 0x2052F0 and 0x205A24.
(gdb) break *0x2052F0
(gdb) break *0x205A24
(gdb) cont
(gdb) x/8xw *0x117080 (to verify the address for the command below)
(gdb) watch *0x3fee5000
(gdb) cont
Run this commands and record all addresses where 0x3fee5000 is accessed until the execution reaches 0x205A24. I hope this will work.
-
(gdb) break *0x2052F0
Breakpoint 1 at 0x2052f0
(gdb) break *0x205A24
Breakpoint 2 at 0x205a24
(gdb) target remote localhost:1234
A program is being debugged already. Kill it? (y or n) y
Remote debugging using localhost:1234
Program received signal SIGTRAP, Trace/breakpoint trap.
0x00000000fff00100 in ?? ()
(gdb) cont
Continuing.
Breakpoint 1, 0x00000000002052f0 in ?? ()
(gdb) x/8xw *0x117080
0x3fee5000: 0x40000000 0x40000000 0x00000000 0x00000000
0x3fee5010: 0x00000000 0x00000000 0x00000000 0x00000000
(gdb) watch *0x3fee5000
Hardware watchpoint 3: *0x3fee5000
(gdb) watch *0x3fee5010
Hardware watchpoint 4: *0x3fee5010
(gdb) cont
Continuing.
Hardware watchpoint 3: *0x3fee5000
Old value = 1073741824
New value = 0
0x000000000020fd94 in ?? ()
(gdb)
-
(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.
Hardware watchpoint 3: *0x3fee5000
Old value = 1073741824
New value = 0
0x000000000020fd94 in ?? ()
(gdb) cont
Continuing.
-
Here is what it looks like for the G4 CPU:
(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?
-
Can you please trace past the "blr" instruction at 0x20fda4 to obtain the address this subroutine returns to?
Alternatively, you just can dump the register file at the watchpoint 0x20fd94 and post the value of LR (link register) here. No need to trace anything at all...
-
Are we jumping off into nowhere on the G5?
No, I don't think so. We probably hit an exception when running the RelocationEngine on G5. At this time, because we don't have any OS running (OF has been shut down, Mac OS Nanokernel hasn't started yet), no recovering from low-level exceptions is possible so the CPU much likely enters the machine check state (that is, it hangs waiting for reset)...
-
Can you please trace past the "blr" instruction at 0x20fda4 to obtain the address this subroutine returns to?
Alternatively, you just can dump the register file at the watchpoint 0x20fd94 and post the value of LR (link register) here. No need to trace anything at all...
Not sure how to do either?
-
Not sure how to do either?
(gdb) break *0x2052F0
(gdb) cont
(gdb) watch *0x3fee5000
(gdb) cont
Old value = 1073741824
New value = 0
0x000000000020fd94 in ?? ()
(gdb) p/x $lr
-
(gdb) break *0x2052F0
Breakpoint 1 at 0x2052f0
(gdb) cont
Continuing.
Breakpoint 1, 0x00000000002052f0 in ?? ()
(gdb) watch *0x3fee5000
Hardware watchpoint 2: *0x3fee5000
(gdb) cont
Continuing.
Hardware watchpoint 2: *0x3fee5000
Old value = 1073741824
New value = 0
0x000000000020fd94 in ?? ()
(gdb) p/x $lr
$1 = 0x20fbb4
(gdb)
-
(gdb) break *0x2052F0
Breakpoint 1 at 0x2052f0
(gdb) cont
Continuing.
Breakpoint 1, 0x00000000002052f0 in ?? ()
(gdb) watch *0x3fee5000
Hardware watchpoint 2: *0x3fee5000
(gdb) cont
Continuing.
Hardware watchpoint 2: *0x3fee5000
Old value = 1073741824
New value = 0
0x000000000020fd94 in ?? ()
(gdb) p/x $lr
$1 = 0x20fbb4
(gdb)
Can you also print the value of $r12 at the same location?
-
This?
(gdb) break *0x2052F0
Breakpoint 1 at 0x2052f0
(gdb) cont
Continuing.
Breakpoint 1, 0x00000000002052f0 in ?? ()
(gdb) watch *0x3fee5000
Hardware watchpoint 2: *0x3fee5000
(gdb) cont
Continuing.
Hardware watchpoint 2: *0x3fee5000
Old value = 1073741824
New value = 0
0x000000000020fd94 in ?? ()
(gdb) p/x $lr
$1 = 0x20fbb4
(gdb) p/x $r12
$2 = 0x203cec
(gdb)
-
Old value = 1073741824
New value = 0
0x000000000020fd94 in ?? ()
(gdb) p/x $lr
$1 = 0x20fbb4
(gdb) p/x $r12
$2 = 0x203cec
(gdb)
Yes, thanks a lot! The address 0x20fd94 belongs to the function bcopy() that simply copies bytes from src to dst. So bcopy() itself isn't a problem but merely another function that calls bcopy.
$r12 contains return address to the caller of bcopy: 0x203cec belongs to MakeROMAreas() in main.c:39, originated at 0x203b88.
Could you set a breakpoint at 0x203ce8 (that's the call to bcopy), run the code until it hits that BP and tell me what do $r3, $r4 and $r5 contain there? These will contain parameters for bcopy...
-
(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)
-
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...
-
G4:
Breakpoint 1, 0x0000000000203ce8 in ?? ()
(gdb) p/x $r3
$4 = 0x3fee5038
(gdb) p/x $r4
$5 = 0x3fee5048
(gdb) p/x $r5
$6 = 0xb8
(gdb)
-
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...
-
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.
-
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):
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:
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...
-
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)
-
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.
(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...
-
Still lost:
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)
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?
-
cmplwi cr7,r5,32
This compares r5 to 32 and sets condition register 7 (cr7) to the result.
bgt cr7, 0x20fb70
This checks if the 'gt' flag in cr7 is set, and will branch to 0x20fb70 if that is the case.
mr. r0,r5
This 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 (https://www.ibm.com/developerworks/library/l-powasm3/index.html)
-
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.
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:
if (r5 > 0x20) goto 0x20fb70
-
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"...
-
cmplwi cr7,r5,32
This 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?
bgt cr7, 0x20fb70
This checks if the 'gt' flag in cr7 is set, and will branch to 0x20fb70 if that is the case.
Still don't understand.
mr. r0,r5
This 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?
-
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:
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'.
-
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:
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?
-
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?
cr6.eq = 1 if r1 == 4
cr6.lt = 1 if r1 < 4
cr6.gt = 1 if r1 > 4
-
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?
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)
-
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.
-
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?
-
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:
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'.
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?
-
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.
-
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.
(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?
-
I really have no idea what the 'so' bits are used for
SO - summary overflow. Used for implementing really big numbers...
-
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.
(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.
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.
-
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).
-
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?
(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)
-
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?
-
G4:
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:
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)
-
970:
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?
-
(gdb) p/x $r3
$5 = 0x3fee50f0
(gdb) p/x $r4
$6 = 0x3fee5100
(gdb)
-
(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:
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:
(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...
-
Looks like everything you said is correct:
(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)
-
Here is what it looks like for the G4 CPU:
(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.
-
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?
-
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...
-
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:
(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)
-
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 (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.
-
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 (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.
-
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):
void bcopy(const void *src, void *dst, size_t len)
{
memcpy(dst, src, len);
}
-
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.
-
Time for a binary patch maybe? :D
-
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?
-
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.
-
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.
-
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?
-
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?
-
dcbz will operate as expected if HID5 is set on the 970.
-
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.
* Hardware Implementation 1113 HID5 or DABR or SPR1013
Register 5
Any idea what the value should be?
-
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...
-
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.
* 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)
-
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.
-
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: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 (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.
-
Here is what HID5 looks like in Qemu's source code:
#if defined(TARGET_PPC64)
#if defined(CONFIG_USER_ONLY)
#define POWERPC970_HID5_INIT 0x00000080
#else
#define POWERPC970_HID5_INIT 0x00000000
#endif
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);
}
#define S_HID5 1013
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;
}
#define SPR_970_HID5 (0x3F6)
-
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...
-
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...
-
Here is what HID5 looks like in Qemu's source code:
#if defined(TARGET_PPC64)
#if defined(CONFIG_USER_ONLY)
#define POWERPC970_HID5_INIT 0x00000080
#else
#define POWERPC970_HID5_INIT 0x00000000
#endif
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);
}
#define S_HID5 1013
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;
}
#define SPR_970_HID5 (0x3F6)
So a dodgy hack would be something like:
#if defined(TARGET_PPC64)
#if defined(CONFIG_USER_ONLY)
#define POWERPC970_HID5_INIT 0x00000080
#else
#define POWERPC970_HID5_INIT 0x00000080
#endif
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:
(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)
-
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:
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)...
-
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:
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:
#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.
#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
/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?
-
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"...
-
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:
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
-
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.
-
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
-
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?
-
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...
-
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.
-
Am I looping?
(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)
-
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 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)?
-
[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]
(gdb) stepi
0x000000000020f0b4 in ?? ()
1: x/i $pc
=> 0x20f0b4: rfi
(gdb) p/x $r5
$1 = 0x20f0b8
(gdb)
-
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:
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:
#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?
-
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?
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 (https://wiki.alcf.anl.gov/images/f/fb/PowerPC_-_Assembly_-_IBM_Programming_Environment_2.3.pdf)
-
(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?
-
(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".
-
(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 (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?
-
Yes, on the G4 it breaks there:
gdb) target remote localhost:1234
Remote debugging using localhost:1234
0x00000000fff00100 in ?? ()
(gdb) cont
Continuing.
Breakpoint 1, 0x000000000020f0b8 in ?? ()
(gdb)
-
I recently read the 64-bit PowerPC spec. You are not supposed to use rfi on those systems. Use rfid instead. Any instruction that writes to a 64-bit register will have a "d" at the end of it.
-
I recently read the 64-bit PowerPC spec. You are not supposed to use rfi on those systems. Use rfid instead. Any instruction that writes to a 64-bit register will have a "d" at the end of it.
Thank you. That explains the issue. We don't even need BAT to shoot ourselves to the dark side of the moon :o
-
I recently read the 64-bit PowerPC spec. You are not supposed to use rfi on those systems. Use rfid instead. Any instruction that writes to a 64-bit register will have a "d" at the end of it.
Thank you. That explains the issue. We don't even need BAT to shoot ourselves to the dark side of the moon :o
I'm curious what happens when attempting to execute "rfi" on a real G5. Unfortunately, neither 970fx manual nor 970mp manual describe this case. My feeling is that "rfi" should be treated as an illegal instruction and trigger the program exception.
What QEMU does (jumping to 0x104) cannot be called a predicable behavior...
-
I recently read the 64-bit PowerPC spec. You are not supposed to use rfi on those systems. Use rfid instead. Any instruction that writes to a 64-bit register will have a "d" at the end of it.
Thank you. That explains the issue. We don't even need BAT to shoot ourselves to the dark side of the moon :o
I'm curious what happens when attempting to execute "rfi" on a real G5. Unfortunately, neither 970fx manual nor 970mp manual describe this case. My feeling is that "rfi" should be treated as an illegal instruction and trigger the program exception.
What QEMU does (jumping to 0x104) cannot be called a predicable behavior...
The PowerPC 64-bit OEA doesn't even mention rfi at all. It only talks about rfid. I guess changing this is yet another thing we have to do to get the G5 working.
-
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?
Correct, none of the "G5s" have BAT registers, nor do they follow the PowerPC specification (the absence of pseudo little endian mode is the most well known divergation)
It doesn't matter what data sheets or general PowerPC docs say, the 970 and it's siblings are not PPC compliant outside of UISA.
-
Correct, none of the "G5s" have BAT registers, nor do they follow the PowerPC specification (the absence of pseudo little endian mode is the most well known divergation)
It doesn't matter what data sheets or general PowerPC docs say, the 970 and it's siblings are not PPC compliant outside of UISA.
Well, this implies that all supervisor-level code must be redesigned for G5 and provided as switchable alternative to the existing PowerPC32 code in order to run on newer hardware. Fortunately, the amount of supervisor-level code in MacOS9 isn't large compared to the XNU kernel. The only component allowed to be executed as supervisor is the Nanokernel. All others run either under emulation or in user mode (including the emulator itself)...
-
Correct, none of the "G5s" have BAT registers, nor do they follow the PowerPC specification (the absence of pseudo little endian mode is the most well known divergation)
It doesn't matter what data sheets or general PowerPC docs say, the 970 and it's siblings are not PPC compliant outside of UISA.
Well, this implies that all supervisor-level code must be redesigned for G5 and provided as switchable alternative to the existing PowerPC32 code in order to run on newer hardware. Fortunately, the amount of supervisor-level code in MacOS9 isn't large compared to the XNU kernel. The only component allowed to be executed as supervisor is the Nanokernel. All others run either under emulation or in user mode (including the emulator itself)...
Yes. And add to that basically no peripheral would work on the G5 even if the nanokernel is fixed.
Mac OS certainly don't know how to deal with PCI-X or PCIe either so it's a long road ahead if going that path.
I think it would be more interesting doing something similar to Classic but with Linux and a nanokernel shim (but at the same time MacOnLinux is there already)
-
I stand corrected about the 970 having BATs. For some reason I though that Amit Singh had made that claim in Mac OS X Internals. Oops!
-
I think it would be more interesting doing something similar to Classic but with Linux and a nanokernel shim (but at the same time MacOnLinux is there already)
Classic have had a lot of performance and compatibility related issues. I remember not being able to use DAW software under Classic at all. I doubt we could do it better than Apple...
-
I stand corrected about the 970 having BATs. For some reason I though that Amit Singh had made that claim in Mac OS X Internals. Oops!
No worries, we all have selective memory sometimes ;D
If we want OS 9 to run on the G5 CPU we're going to have to find a way to patch 'rfi', not a small task.
Unfortunately outside my wheel house, but at least we have some understanding of what we need to do. 'rfi'>BAT patches. That's further along than we were when this thread started. I know I learned a lot, and hopefully we can come up with some ideas on how to move forward with this, maybe on day we'll get over the hump, as it were.
Thanks for everyone's input, very interesting stuff.
-
I think it would be more interesting doing something similar to Classic but with Linux and a nanokernel shim (but at the same time MacOnLinux is there already)
Classic have had a lot of performance and compatibility related issues. I remember not being able to use DAW software under Classic at all. I doubt we could do it better than Apple...
I would claim that the performance issues related to Classic was more to do with the fact Classic was a second class citizen in the Mac OS X installation- if OS X prioritized the Classic process it probably wouldn't been that bad. (as well as the rootless mode, window doublebuffering hacks etc that basically only made it usable for word processors and a like applications that basically only used Toolbox (Quickdraw/Quicktime etc especially) calls for everything, a lot of applications on OS 9 however had their own implementations of blitting routines etc and those broke on Classic because of the stupid double buffering hack Apple used- which of course was necessary to allow windows to overlap without artifacts when run in a rootless window.
As for audio etc yes, the lack of hardware access of course caused issues there- but that's something that could have been solved if Apple wanted to (QEMU, VMWare etc supported it for ages) PCI passthrough etc is not a technical impossibility even without an IOMMU on the PCI buss, it's just not secure- but anyone who cares about security wouldn't run Mac OS 9 to start with.
Compatibility would be tricky regardless of solution, especially on everything but the first G5 (PCI-X; PCI-X can run in PCI compatibility mode as far as I know- so I think it's theoretically plausible to have it work with OS 9 with some efforts... but then again I never really looked into the specification at detail so it's mostly a guess), the PCIe on the other hand that the majority of the G5s used are completely different beast however and even if someone magically would manage to get PCIe working, it's not compatible with PCI so no PCI card drivers etc would work (which means no ASIO or similar).
While the alternative would be to leverage the device layer support on another kernel such as Linux would give a lot of this "for free", In fact MacOnLinux already has higher compatibility than Classic ever had- unfortunately MacOnLinux was never ported to the G5 (and I believe the original implementation is extremely dated so it's unlikely it would even work with recent linux kernels), I know there was efforts porting MacOnLinux to use KVM instead of it's own hypervisor implementation- but I guess that essentially would leave us up to the point we are right now- with QEMU and KVM, ie. The bootstrap/nanokernel is unable to boot due to supervisor differences on the G5.
Anyway it's just my two cents, getting the kernel started and Mac OS to boot at all is of course beneficial in all scenarios, regardless of what path one may take after that.
-
FWIW, if someone can get me a Trampoline that just lumps over the line to start the NanoKernel, then I can go nuts patching the NanoKernel. Progress might be swift. Excellent work all and especially darth! (Maybe this will help if you ever want to go back to graphics drivers, or maybe the kernel?)
-
I suppose I’d better get back onto the legacy NanoKernel reversal!
-
It's a pity we can't work on all of our thousand projects at once.
-
I think it would be more interesting doing something similar to Classic but with Linux and a nanokernel shim (but at the same time MacOnLinux is there already)
Classic have had a lot of performance and compatibility related issues. I remember not being able to use DAW software under Classic at all. I doubt we could do it better than Apple...
I would claim that the performance issues related to Classic was more to do with the fact Classic was a second class citizen in the Mac OS X installation- if OS X prioritized the Classic process it probably wouldn't been that bad. (as well as the rootless mode, window doublebuffering hacks etc that basically only made it usable for word processors and a like applications that basically only used Toolbox (Quickdraw/Quicktime etc especially) calls for everything, a lot of applications on OS 9 however had their own implementations of blitting routines etc and those broke on Classic because of the stupid double buffering hack Apple used- which of course was necessary to allow windows to overlap without artifacts when run in a rootless window.
As for audio etc yes, the lack of hardware access of course caused issues there- but that's something that could have been solved if Apple wanted to (QEMU, VMWare etc supported it for ages) PCI passthrough etc is not a technical impossibility even without an IOMMU on the PCI buss, it's just not secure- but anyone who cares about security wouldn't run Mac OS 9 to start with.
Compatibility would be tricky regardless of solution, especially on everything but the first G5 (PCI-X; PCI-X can run in PCI compatibility mode as far as I know- so I think it's theoretically plausible to have it work with OS 9 with some efforts... but then again I never really looked into the specification at detail so it's mostly a guess), the PCIe on the other hand that the majority of the G5s used are completely different beast however and even if someone magically would manage to get PCIe working, it's not compatible with PCI so no PCI card drivers etc would work (which means no ASIO or similar).
While the alternative would be to leverage the device layer support on another kernel such as Linux would give a lot of this "for free", In fact MacOnLinux already has higher compatibility than Classic ever had- unfortunately MacOnLinux was never ported to the G5 (and I believe the original implementation is extremely dated so it's unlikely it would even work with recent linux kernels), I know there was efforts porting MacOnLinux to use KVM instead of it's own hypervisor implementation- but I guess that essentially would leave us up to the point we are right now- with QEMU and KVM, ie. The bootstrap/nanokernel is unable to boot due to supervisor differences on the G5.
Anyway it's just my two cents, getting the kernel started and Mac OS to boot at all is of course beneficial in all scenarios, regardless of what path one may take after that.
Thank you for this exhaustive answer. At first glance, I don't see any major software-side roadblock in updating MOL for G5 except the time constraint. Someone willing to undertake this task, will have to understand MOL's code first and that requires a lot of time.
To my knowledge, PCI cards cannot be plugged into PCIe slots. That means we cannot use pre-G5 hardware with G5 machines unless I missing something (?)
IIUC, we had a possibility to build a transition layer between legacy software and newer hardware on top of MOL, right?
I think MOL deserves a separate thread. What do you think about moving the MOL-related discussion to elsewhere? What's the right place for that? Software development?
-
To my knowledge, PCI cards cannot be plugged into PCIe slots. That means we cannot use pre-G5 hardware with G5 machines unless I missing something (?)
only the final generation of G5s used PCIe (970MP series), the others were all PCI-X.
There are actually hardware adapters which allow you to plug one into the other or vice versa, but ive no idea how well they would work on a PPC machine.
-
OS 9’s communication with the PCI bus controller is well abstracted using a pluggable module called the PCICyclesLib, which I think actually exposes part of the interface that belongs to the Expansion Bus Manager. So write a new PCICyclesLib to wang the ?K2 and we should be good.
-
To my knowledge, PCI cards cannot be plugged into PCIe slots. That means we cannot use pre-G5 hardware with G5 machines unless I missing something (?)
only the final generation of G5s used PCIe (970MP series), the others were all PCI-X.
There are actually hardware adapters which allow you to plug one into the other or vice versa, but ive no idea how well they would work on a PPC machine.
I have a PCI-E to PCI adepter, they are pretty transparent to the host, should work in just about any system.
We also used GPU's that had a PCI-E to AGP bridge, and they are transparent to the host.
Likely OS 9 would just treat PCI-E slots as PCI. I pasted a PCI Firewire card in the PCI-E adepter to Qemu-PPC and it worked fine in 9.2.2 and 10.4 with my Firewire devices.
-
I got some new hardware( G5 Quad ), so I wanted to get back to this.......
Have a look at this from KVM-pr in Qemu.
qemu-system-ppc' -enable-kvm -hda '/media/jam/d9d5c74c-a218-45c6-9d7f-8d8274228955/Tiger.img' -cpu g4 -M mac99 -m 1536 -prom-env "aapl,debug=3013FFF" -cdrom ~/OS9.iso -prom-env 'auto-boot?=false'
Am I getting the NanoKernel?
-
Yep. Nice!
-
It's amazing to see the progress you guys made with G5, QEMU and Mac OS 9. That stuff about PCI/PCIe adapters + device detection had me blown away, as well. I wouldn't have thought QEMU OS 9 would have seen the FireWire devices just like that.
Also grats on acquiring the G5 Quad, darthnvader, it's one of the loveliest machines I have ever used. But that machine and all the other G5s desperately need some native OS 9 love! I see myself using the Mac mini G4 a lot more than my Quad simply because it has OS 9. This needs to change... And you guys have made some really nice discoveries and progress to that end.
-
Just the encouragement we need! ;)
-
Good work! Please document well what your findings right now, it might open whole new world for G5 hardware. Although I try to not get involved in before January 2021 ;)
-
Been too busy to follow the Mac OS retro community for a while (and most likely will be soon again, to add to that it appears my G4 yikes had a CF card malfunction and lost basically it's entire disk...) as well as my G5 that I don't know what happened to yet.... if it's a harddrive failure or some intermittent issue- but I'm fairly sure I had OS X 10.4 installed on it... but it's also just flashing question mark when attempting to boot up now)
But long story short, I suppose there been no significant strides in either the QEMU classic macos emulation (for x86) or MacOnLinux?
-
There is always a slow trickle of progress on one thing or another, but I don't think anything is directly relevent to the G5.