Views: 1,609,345 | Main | Rules/FAQ | Memberlist | Active users | Last posts | Calendar | Stats | Online users | Search | 11-21-24 03:53 PM |
Guest: |
0 users reading DSP reverse engineering | 1 bot |
Main - Reverse-engineering - DSP reverse engineering | Hide post layouts | New reply |
StapleButter |
| ||
Member blarg Level: 30 Posts: 28/184 EXP: 151361 Next: 14508 Since: 10-27-14 From: France Last post: 2648 days ago Last view: 2558 days ago |
I wanted to start by the basics and determine how the DSP memory is mapped, and what is what on the DSP side.
DSP RAM goes from 1FF00000 to 1FF7FFFF. So far we have: 1FF00000 - 1FF3FFFF? -> program RAM (DSP exception vectors at 1FF00000+) 1FF40000 - 1FF5FFFF -> data RAM region 1 (1FF50000-1FF5FFFF exposed read-only to ARM11 userland) 1FF60000 - 1FF7FFFF -> data RAM region 2 (1FF70000-1FF7FFFF exposed read-only to ARM11 userland) Does the program RAM end at 1FF3FFFF or 1FF1FFFF? (if then, what's in the leftover space?) The DSP can only address 65536 words without switching banks or something in the like. That is, 128K. Assuming the two data RAM regions map to X-RAM and Y-RAM, and the program RAM goes from 1FF00000 to 1FF1FFFF, what would be in the leftover space? DSP-side I/O? Well uh, clearly this DSP is able to address more than 128K of memory. There has to be a way to select which chunk of memory is being accessed, like on the SNES where they have DBR and PBR to specify which banks the CPU will access. The docs mention movp and movd instructions, moving from/to data/program RAM. But nothing precises if the regular mov instructions access program RAM or data RAM. ____________________ blargSNES -- SNES emu for 3DS More cool stuff |
yuriks |
| ||
Newcomer Normal user Level: 7 Posts: 1/8 EXP: 1371 Next: 77 Since: 10-30-14 From: Brazil Last post: 3282 days ago Last view: 3264 days ago |
One thing I noticed while helping neobrain with FIRM REing is that the NATIVE_FIRM ARM11 initial processes are actually loaded into this 0x1FF00000-0x1FF7FFFF memory region. Do they later get relocated at some point in the boot process or is there some funny memory remapping going on? |
StapleButter |
| ||
Member blarg Level: 30 Posts: 32/184 EXP: 151361 Next: 14508 Since: 10-27-14 From: France Last post: 2648 days ago Last view: 2558 days ago |
Dunno. I'm not really on that either.
Anyway, have more shiz. Binary loading process Binary is verified and segments are written to their appropriate locations in DSP RAM. As far as I can see, they're written directly, there is no fancy specific transfer mechanism involved. At this point it seems that the DSP isn't running. Bits are set in some registers that control DSP RAM mapping (0x1EC40000, 0x1EC40008). pdn:d command 0x100C0 sent 3 times: 1. params = 0, 1, 0 2. params = 1, 1, 0 3. params = 1, 1, 1 If bit 0 in 0x1ED03008 is zero, sets it to 1 and waits 0x60 cycles Waits until bit 2 in 0x1ED0300C becomes zero If bit 0 in 0x1ED03008 is nonzero: clear bits 9-11 in 0x1ED03008, set 0x1ED03010 to 0, set 0x1ED03018 to 0xFFFF, wait 0x60 cycles, issue reads from 0x1ED03024, 0x1ED0302C and 0x1ED03034 (read values ignored), wait 0x60 cycles Set some bit (val unknown, maybe comes from DSP binary?) in 0x1ED03008, wait 0x60 cycles Clear bit 0 in 0x1ED03008, wait 0x60 cycles Set 0x1ED03014 (semaphore mask) based on that same unknown value, wait 0x60 cycles If some bit is cleared: read DSP reply from command slot 0, wait 0x60 cycles; repeat until reply is 1 Repeat above for command slots 1 and 2 Write shit to 0x1ED03008 and 0x1ED03014, origins not quite known Bit 11 in 0x1ED03008 is set to one then zero. Simultaneously, bit 15 in 0x1ED03014 is set to zero then one. *(vu16*)0x1ED03008 |= 0x0800;
*(vu16*)0x1ED03014 &= ~0x8000; *(vu16*)0x1ED03008 &= ~0x0800; *(vu16*)0x1ED03014 |= 0x8000; Do those registers really match what is documented in NO$GBA's help text? The bits that are toggled here would be interrupt enable bits; makes little sense to toggle them if that's what they are. My guess is that they play a role in resetting the DSP? This seems to also be done when unloading the DSP binary, so not quite sure. Then there are two commands sent to cdc:DSP cmdbuf[0] = 0x70040 (byte) cmdbuf[1] = 1 cmdbuf[0] = 0x80040 (byte) cmdbuf[1] = 1 Binary unloading (and turning the DSP off) Same shit as above with 0x1ED03008 and 0x1ED03014. Then it waits for bit 15 in 0x1ED0300C to become zero. Writes 0x8000 to 0x1ED03030 and does some wait loop (0x60 cycles). -> sends command 0x8000 via command slot 2 then waits for bit 12 in 0x1ED0300C to become one. Reads reply from 0x1ED03034. Reply is ignored. Waits for bit 0 in 0x1ED03008 to become zero. Sets that bit to one, waits 0x60 cycles. Waits for bit 2 in 0x1ED0300C to become zero. Sends pdn:d command 0x100C0. cmdbuf[0] = 0x100C0 (byte) cmdbuf[1] = 1 (byte) cmdbuf[2] = 1 (byte) cmdbuf[3] = 0 Sends same command with params 0, 1, 0 Sends commands to cdc:DSP cmdbuf[0] = 0x70040 (byte) cmdbuf[1] = 0 cmdbuf[0] = 0x80040 (byte) cmdbuf[1] = 1 ____________________ blargSNES -- SNES emu for 3DS More cool stuff |
StapleButter |
| ||
Member blarg Level: 30 Posts: 33/184 EXP: 151361 Next: 14508 Since: 10-27-14 From: France Last post: 2648 days ago Last view: 2558 days ago |
Ugh. Apparently it doesn't like it if a usermode app tries to use pdn:d or cdc:DSP, even if they're in the exheader. ____________________ blargSNES -- SNES emu for 3DS More cool stuff |
ichfly |
| ||
Newcomer Normal user Level: 4 Posts: 1/2 EXP: 170 Next: 109 Since: 12-14-14 Last post: 3592 days ago Last view: 3513 days ago |
booting dsp module
sending pdn:d command 0x000100C0 2 times but the handle for pdn is not set yet so 0 is used yet so nothing happens 1. params = 1, 1, 1 2. params = 0, 0, 0 svcBindInterrupt: numb:0x4a prio:4 ManualClear check the bit(0) in 0x1ec40000 to 0x1ec40010 (access perm? (just a guess)) |
StapleButter |
| ||
Member blarg Level: 30 Posts: 47/184 EXP: 151361 Next: 14508 Since: 10-27-14 From: France Last post: 2648 days ago Last view: 2558 days ago |
What, it's trying to access the service without having loaded it prior? Hah.
smea's post about ninjhax inspired me, there might be a way to launch unsigned DSP binaries with something similar, but this is theory. ____________________ blargSNES -- SNES emu for 3DS More cool stuff |
ichfly |
| ||
Newcomer Normal user Level: 4 Posts: 2/2 EXP: 170 Next: 109 Since: 12-14-14 Last post: 3592 days ago Last view: 3513 days ago |
the GetServiceSessionHandle happens after the calls
ADD: That reversing is from v2048 so I don't know if they fixed it now. |
nocash |
| ||
Normal user Level: 20 Posts: 10/77 EXP: 38997 Next: 3442 Since: 10-09-15 Last post: 2098 days ago Last view: 2013 days ago |
Posted by StapleButter Don't know if that questions do still apply, but anyways: The DSi uses "MBK" registers http://problemkaputt.de/gbatek.htm#dsinewsharedwramforarm7arm9dsp for mapping WRAM either to DSP or ARM memory at 3000000h-3FFFFFFh. I would assume that the 3DS has some similar "MBK" mapping mechanism (but mapping to 1FF00000h-1FF7FFFFh instead of 3000000h-3FFFFFFh). Or is there no such mapping stuff on 3DS, and the ARM can access the memory even when the DSP is running? Yes, Teaklite 1 did support on 16bit addresses. And the (undocumented) Teaklite 2 seems to have been expanded to at least 18bit addresses. The 16bit br/call/bkrep opcodes are using two formerly unused bits to gain 18bit range (except bkrep with imm8, which is still restricted to 16bit). Don't know if/how call+ret are managing 18bit return addresses though. Mov opcodes must be in fact use some extra "bank" register. Maybe set via the new "load imm2,movpd" opcode, the "PD" might stand for "DataPage" or so. There are some new "movp" ocodes, allowing to use "(Ax)" (instead of 16bit "(Axl)") for program memory addressing, so there would be no "ProgramPage" required in that case. Normal "mov" opcodes should be always accessing data ram (else executing the opcode fetch and data access in one clock cycle wouldn't work out). The movd/movp opcodes are: movp = move FROM PROGRAM RAM (to data ram, or to register) movd = move TO PROGRAM RAM (from data ram) They could be used for manipulating program code (probably rarely done), or loading constants from program memory (might be done more often, but loading constants from data ram would be ways faster). --- For the DSi, I have found some teak code in a file called "aac.a" (inside of the NITRO filesystem of the DSi Sound utility). It seems to using COFF format, containing binary and symbolic labels, which would very useful for debugging. Are there any read-for-use utilities for extracting symbols from COFF files? |
Dazzozo |
| ||
Member Dev of "the best software that almost nobody will ever use" Level: 9 Posts: 3/13 EXP: 2761 Next: 401 Since: 05-21-15 Last post: 3160 days ago Last view: 2993 days ago |
Posted by nocash Yes, the same mechanism exists: http://3dbrew.org/wiki/PDN_Registers#PDN_SHAREDWRAM_32K_DATA |
Main - Reverse-engineering - DSP reverse engineering | Hide post layouts | New reply |
Page rendered in 0.034 seconds. (2048KB of memory used) MySQL - queries: 28, rows: 81/81, time: 0.009 seconds. Acmlmboard 2.064 (2018-07-20) © 2005-2008 Acmlm, Xkeeper, blackhole89 et al. |