Add ATY,RockHopper2 driver

This removes the need for darthnVader's heroically patched ATI
Extensions.
This commit is contained in:
Elliot Nunn 2019-10-07 19:21:12 +08:00
parent 1efd8ef07e
commit ed6c44d99a
2 changed files with 88 additions and 0 deletions

Binary file not shown.

View File

@ -1,12 +1,16 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
import patch_common import patch_common
import cfmtool
from ppcasm import assemble
from os import path from os import path
import shutil import shutil
import os import os
import struct import struct
import fnmatch import fnmatch
import tempfile
from ast import literal_eval as eval
src, cleanup = patch_common.get_src(desc=''' src, cleanup = patch_common.get_src(desc='''
@ -16,6 +20,8 @@ First, patches the boot script to (a) add PowerMac10,1/2 to the COMPATIBLE tag,
PMU device. Second, patches the NanoKernel to prevent the CPU Plugin from PMU device. Second, patches the NanoKernel to prevent the CPU Plugin from
hanging when a THRM register access silently fails. Third, if necessary, patches hanging when a THRM register access silently fails. Third, if necessary, patches
the Kauai ATA driver into old ROMs (pre-9.1). the Kauai ATA driver into old ROMs (pre-9.1).
Fourth, patches and inserts a native driver parcel for the ATI Radeon 9200
(ATY,RockHopper2), to enable acceleration with the c.2005 ATI Extensions.
''') ''')
@ -328,6 +334,74 @@ def patch_booter(text):
return text return text
def patch_rockhopper_ndrv(src, dest=None):
with tempfile.TemporaryDirectory() as tmp:
cfmtool.dump(src, tmp)
glue_file = eval(open(path.join(tmp, 'locations', 'glue.txt')).read())
glue_info = next(d for d in glue_file if d['function'] == 'ExpMgrConfigReadLong')
code_path = path.join(tmp, glue_info['file'])
code = bytearray(open(code_path, 'rb').read())
while len(code) % 4: code.append(0) # align just in case
# All calls to ExpMgrConfigReadLong go through this "cross-TOC glue" function...
glue_offset = glue_info['offset']
glue_toc, = struct.unpack_from('>h', code, glue_offset + 2)
print('ATY,RockHopper2 patch: catching %s to change device 0x5962 to 0x5961' % glue_info['function'])
# ...So replace it with a branch to the end of the code
code[glue_offset:glue_offset+4] = assemble('b %d' % (len(code) - glue_offset))
for i in range(glue_offset+4, glue_offset+24, 4): code[i:i+4] = assemble('nop')
code.extend(assemble(f"""
mflr r0 # Standard stack setup
stw r0, 8(r1)
stwu r1, -0x40(r1)
stw r4, 0x38(r1) # Make the call,
stw r5, 0x3c(r1) # but save the args first
bl ExpMgrConfigReadLong
cmpwi cr0, r3, 0 # If call failed, punt
bne cr0, _return
lwz r4, 0x38(r1) # If wrong address, punt
cmpwi cr0, r4, 0
bne cr0, _return
lwz r5, 0x3c(r1) # If wrong returned value, punt
lwz r8, 0(r5)
lis r7, 0x1002
ori r7, r7, 0x5962
cmpw cr0, r7, r8
bne cr0, _return
lis r8, 0x1002 # Save the new returned value
ori r8, r8, 0x5961
stw r8, 0(r5)
_return: # Stack teardown
lwz r1, 0(r1)
lwz r0, 8(r1)
mtlr r0
blr
# r3=opaqueNRptr, r4=config_addr, r5=result_ptr
ExpMgrConfigReadLong:
lwz r12, {glue_toc}(r2)
stw r2, 0x14(r1)
lwz r0, 0(r12)
lwz r2, 4(r12)
mtctr r0
bctr
"""))
open(code_path, 'wb').write(code)
return cfmtool.build(tmp, dest)
for (parent, folders, files) in os.walk(src): for (parent, folders, files) in os.walk(src):
folders.sort(); files.sort() # make it kinda deterministic folders.sort(); files.sort() # make it kinda deterministic
for filename in files: for filename in files:
@ -353,6 +427,20 @@ for (parent, folders, files) in os.walk(src):
f.write('prop flags=0x0000c a=kauai-ata b=ata\n') f.write('prop flags=0x0000c a=kauai-ata b=ata\n')
f.write('\tndrv flags=0x00006 name=driver,AAPL,MacOS,PowerPC src=kauai-ata.pef.lzss\n\n') f.write('\tndrv flags=0x00006 name=driver,AAPL,MacOS,PowerPC src=kauai-ata.pef.lzss\n\n')
if not any(fnmatch.fnmatch(fn, 'ATY,RockHopper2*.pef') for fn in os.listdir(parent)):
print('ROM lacks ATY,RockHopper2 driver, patching it in')
ndrv1 = path.join(path.dirname(__file__), 'ATY,RockHopper2-1.0.1f63-20040916.133447.pef')
ndrv2 = path.join(parent, path.basename(ndrv1))
shutil.copy(ndrv1, ndrv2)
patch_rockhopper_ndrv(ndrv2, ndrv2)
# compatible w/ ATY,RockHopper2 and device_type=display, override existing
with open(full, 'a') as f:
f.write('prop flags=0x0000c a=ATY,RockHopper2 b=display\n')
f.write('\tndrv flags=0x00004 name=driver,AAPL,MacOS,PowerPC src=%s\n\n' % path.basename(ndrv2))
if path.exists(path.join(parent, 'MotherBoardHAL.pef')): if path.exists(path.join(parent, 'MotherBoardHAL.pef')):
print('ROM has MotherBoardHAL (< ROM 6.7), therefore unlikely to work') print('ROM has MotherBoardHAL (< ROM 6.7), therefore unlikely to work')