3DS reverse engineering
Re: 3DS reverse engineering
I suspect the "ghosting" might have something to do with frame blending. Some games rely on the GBA's LCD being slower than a CRT or modern TN LCD for transparency effects or to improve perceived fill rate in software texture mapping.
Re: 3DS reverse engineering
Yes, might be something like that. Or scanline interleave, or RGB color bleeding. I don't know. There seems to be a whole hacking scene for gba footers and ghosting, they do probably know how ghosting looks like. but I don't know if they are able to describe the effect. If anyone can do: Please say something!!! Help is needed!!!
For the GBA footer, the basic outline seems to be:Well, that's probably both wrong.
But, when merging the yml & 3dbrew data, and doing lots of bold guesses - without ever having seen any of those footers - I think that the footer is 360h bytes, appended at the end of the .code file (after the ROM-image), and that it might be meant to contain these values:
Problem: 3dbrew says that the first descriptor must have type=01h... or more specifically, it allows type=00h as 1st descriptor... but only if next descriptor does ALSO have type=00h... which would mean that none could have type<>00h ???
Would be cool if somebody could help on finding one of those footers!
Even if it's a homebrew footer, there seems to be a homebrew tool for creating footers.
For the GBA footer, the basic outline seems to be:
Code: Select all
3dbrew suggests ".CAA" in first 16 bytes of 360h-byte footer
yml suggests ".CAA" in last 12 bytes of 35Ch-byte footer
But, when merging the yml & 3dbrew data, and doing lots of bold guesses - without ever having seen any of those footers - I think that the footer is 360h bytes, appended at the end of the .code file (after the ROM-image), and that it might be meant to contain these values:
Code: Select all
Config Data:
000h 4 Unknown (guess: maybe contains a 32bit value...?)
004h 4 ROM Size (probably same as Romsize)
008h 4 Cartridge Type (Port 10018100h, ARM7_SAVE_TYPE)
00Ch 4 Unknown (reportedly 0000FFFFh) (wild guess: savedata fillvalue?)
010h 4 Unknown (Port 10018120h, reportedly 1561662 or 2607238) ;\maybe
014h 4 Unknown (Port 10018124h, reportedly 156166 or 577077 ) ; write
018h 4 Unknown (Port 10018128h, reportedly 134 or 388 ) ; erase
01Ch 4 Unknown (Port 1001812Ch, reportedly 187667 or 201072 ) ;/timings?
020h 4 LCD Ghosting (01h..FFh) (uh, what is that?)
024h 300h LCD Video LUT (guess: maybe for Port 10400484h/10400584h or so?)
324h 0Ch Unknown (guess: Maybe ALL bytes just Padding, probably zero)
1st Descriptor:
330h 4 Unknown (guess: Type 00h=ROM-Image)
334h 4 Unknown (guess: ROM-image Offset, probably usually 0)
338h 4 Unknown (guess: ROM-image Size, probably usually Romsize)
33Ch 4 Unknown (guess: Padding, probably zero)
2nd Descriptor:
340h 4 Unknown (guess: Type 01h=Config Data)
344h 4 Unknown (guess: Config Offset, probably usually Romsize+0)
348h 4 Unknown (guess: Config Size, probably usually 324h or 330h or so)
34Ch 4 Unknown (guess: Padding, probably zero)
Footer Entrypoint (guess: probably in last 10h-byte of .code file):
350h 4 GBA Footer ID (".CAA")
354h 4 Maybe Version (must be 1)
358h 4 Descriptor List Offset (probably usually Romsize+330h)
35Ch 4 Descriptor List Size (probably usually 20h) (N*10h)
Would be cool if somebody could help on finding one of those footers!
Even if it's a homebrew footer, there seems to be a homebrew tool for creating footers.
Last edited by nocash on Wed Mar 25, 2020 2:16 pm, edited 1 time in total.
Re: 3DS reverse engineering
Here are some findings about the "ARM7" registers.
They are actually ARM9 registers that control GBA mode, so it might be best to rename them from ARM7_xxx to GBA_xxx or so. The first some registers do also affect NDS mode though.
Then there is something for the GBA cartridge type (ROM size versus savedata and RTC present flag).
The RTC is the craziest that I've seen so far. One should think that RTCs are simple pieces of hardware. But this one seems to have built-in dividers for converting "Days since 1st Jan 2000" to "BCD day, month, year" (and perhaps vice-versa, too). There's also some weird support for negative HH:MM:SS values. It's just crazy ; )
And, the memory map for 3DS memory that gets remapped to GBA side:
At first glance, the ROM address shuffle seems works as
or maybe there's some more shuffling going on, I have used only code in WRAM so far.
Not sure what that shuffle is about, as copy protection... it would be a bit lame.
I am wondering if the .code files (those with the footer) are containing the ROM-image in shuffled form, too.
Btw. where are those GBA titles stored? And 3DS shop titles in general?
Dsiware titles are stored on the internal eMMC partition.
But GBA and 3DS titles... there seem to be no internal eMMC folders for them... or are they always stored on external SD card?
Code: Select all
10018000h 1 ARM7_CNT
10018080h 20h ARM7_BOOTCODE
10018100h 2 ARM7_SAVE_TYPE
10018104h 2 ARM7_SAVE_CNT
10018108h 2 ARM7_RTC_CNT
10018110h 4 ARM7_RTC_BCD_DATE
10018114h 4 ARM7_RTC_BCD_TIME
10018118h 4 ARM7_RTC_HEX_TIME
1001811Ch 4 ARM7_RTC_HEX_DATE
10018120h 4 ARM7_SAVE_CFG_?
10018124h 4 ARM7_SAVE_CFG_?
10018128h 4 ARM7_SAVE_CFG_?
1001812Ch 4 ARM7_SAVE_CFG_?
Code: Select all
10018000h - ARM7_CNT (R/W)
0-1 Console Mode (0=3DS, 1=NDS/DSi, 2=GBA, 3=Auto-replaced by 0) (R/W)
2-31 Unused (0)
To apply the mode value, write [10141100h].bit15=1 (CFG11_TWLMODE_0).
GBA/NDS/DSi mode will start ARM7, executing the ARM7_BOOTCODE. NDS/DSi mode
changes the ARM9 memory map (ARM9 should execute ITCM code during the mode
change). GBA mode does keep ARM9 in 3DS mode. ARM11 is always kept running in
3DS mode.
10018080h..1001809Fh - ARM7_BOOTCODE (32 bytes) (R/W)
These 32 bytes do overlay the exception vectors at 00000000h..0000001Fh in GBA
BIOS ROM (and maybe also NDS7 BIOS ROM?). The opcode(s) are executed after
setting ARM7_CNT, and then setting CFG11_TWLMODE_0.bit15.
Unknown if there is a way to DISABLE the overlay... writing the original BIOS
values might work... if the memory is still write-able once when ARM7 starts
running?... or otherwise one could change only the reset vector (eg. to MOV
PC,3000000h, and set the other vectors to original BIOS values).
Code: Select all
10018100h - ARM7_SAVE_TYPE (R/W)
0-3 GBA Cartridge Type (00h-0Fh, see below) (R/W)
4-15 Unused (0)
Type values (same as used in the footer of the GBA ROM-image):
00h = ROM 16.0Mbyte, EEPROM 0.5Kbyte (in upper 16Mbyte of ROM area)
01h = ROM 31.9Mbyte, EEPROM 0.5Kbyte (in upper 100h byte of ROM area)
02h = ROM 16.0Mbyte, EEPROM 8Kbyte (in upper 16Mbyte of ROM area)
03h = ROM 31.9Mbyte, EEPROM 8Kbyte (in upper 100h byte of ROM area)
04h = ROM 32Mbyte, FLASH 64Kbyte, RTC ;\(FLASH ID=3D1Fh, Atmel)
05h = ROM 32Mbyte, FLASH 64Kbyte ;/
06h = ROM 32Mbyte, FLASH 64Kbyte, RTC ;\(FLASH ID=D4BFh, SST)
07h = ROM 32Mbyte, FLASH 64Kbyte ;/
08h = ROM 32Mbyte, FLASH 64Kbyte, RTC ;\(FLASH ID=1B32h, Panasonic)
09h = ROM 32Mbyte, FLASH 64Kbyte ;/
0Ah = ROM 32Mbyte, FLASH 128Kbyte, RTC ;\(FLASH ID=09C2h, Macronix)
0Bh = ROM 32Mbyte, FLASH 128Kbyte ;/
0Ch = ROM 32Mbyte, FLASH 128Kbyte, RTC ;\(FLASH ID=1362h, Sanyo)
0Dh = ROM 32Mbyte, FLASH 128Kbyte ;/
0Eh = ROM 32Mbyte, SRAM 32Kbyte ;-SRAM
0Fh = ROM 32Mbyte ;-Raw ROM
10018104h - ARM7_SAVE_CNT (R/W)
0 Savedata mapping (0=GBA:0E000000h, 1=3DS:08080000h) (R/W)
1-15 Unused (0)
10018120h - ARM7_SAVE_CFG_? - R/W mask 00FFFFFFh (reset=007FD000h=8376320)
10018124h - ARM7_SAVE_CFG_? - R/W mask 00FFFFFFh (reset=007FD000h=8376320)
10018128h - ARM7_SAVE_CFG_? - R/W mask 000FFFFFh (reset=000000E0h=224)
1001812Ch - ARM7_SAVE_CFG_? - R/W mask 000FFFFFh (reset=00051000h=331776)
Maybe write/erase timings, or so? See GBA footer description in previous post for some sample values.
Code: Select all
10018108h - ARM7_RTC_CNT (W and R)
0 Write (0=No change, 1=Apply RTC_HEX) (W)
1 Read (0=No change, 1=Latch RTC_BCD and RTC_HEX) (W)
2-13 Unused (0)
14 Write Error Flag (0=Okay, 1=Error, invalid data) (R)
15 Write/Read Busy Flag (0=Ready, 1=Busy) (R)
To get the current time:
Set Read flag, wait until busy=0, then read RTC_HEX or RTC_BCD registers
To set the current time:
Write RTC_HEX registers, then set Write flag, then wait until busy=0
(this does also set BCD registers, the hardware auto-converts HEX to BCD)
The initial time on power-up in 01 Jan 2000, 00:00:00. The actual battery
backed time can be obtained from MCU[30h..36h].
The GBA software can access the RTC via port 080000C4h, 080000C6h, 080000C8h.
10018110h - ARM7_RTC_BCD_DATE (R)
0-7 Year BCD (00h..99h)
8-15 Month BCD (01h..12h)
16-23 Day BCD (01h..31h)
24-31 Day of Week (00h..06h) (WHAT=Monday?)
10018114h - ARM7_RTC_BCD_TIME (R)
0-7 Hour BCD (00h..23h) (always 24-hours, even in AM/PM mode)
8-15 Minute BCD (00h..59h)
16-23 Second BCD (00h..59h)
24-31 Zero (00h)
10018118h - ARM7_RTC_HEX_TIME (R=Latched Read value, W=Written value)
0-6 Second (signed -40h..+3Fh, usually 00h..3Bh)
7 Force Reset (0=Normal, 1=Force 1st Jan 2000, 00:00:00)
8-14 Minute (signed -40h..+3Fh, usually 00h..3Bh)
15 12/24-hour (0=12 hour, 1=24 hour) (for GBA side, both with AM/PM flag)
16-21 Hour (signed -20h..+1Fh, usually 00h..17h)
22-23 Unused (0)
24-27 Day of Week (signed -08h..+07h, usually 00h..06h) (WHAT=Monday?)
28-30 Unknown (can be 0..7)
31 Error (0=Normal, 1=Triggers error)
1001811Ch - ARM7_RTC_HEX_DATE (R=Latched Read value, W=Written value)
0-15 Days since 1st Jan 2000 (0000h..8EACh=100 years, Bigger=Triggers error)
16-31 Unknown (can be 0000h..FFFFh)
Code: Select all
Memory map
3DS --> GBA
08080000h --> 0E000000h, GBA Cart FLASH/SRAM/EEPROM (max 128Kbyte)
080A0000h --> 06000000h, GBA 2D-Engine VRAM (64K+32Kbyte)
080B8000h --> 03000000h, GBA Fast WRAM (32Kbyte)
080C0000h --> 02000000h, GBA Slow WRAM (256Kbyte)
20000000h --> 08000000h, GBA Cart ROM (with address shuffle!) (32Mbyte max?)
When in GBA mode, ARM9 seems to be no longer able to access the remapped ARM9
memory blocks (ARM9 only sees 00h's)? And, ARM9/ARM11 seem to HANG (without any
exception) when trying to access Main RAM at 20000000h?
Code: Select all
addr = (addr AND FFFF800h) + ((addr+20h) AND 7FFh)
Not sure what that shuffle is about, as copy protection... it would be a bit lame.
I am wondering if the .code files (those with the footer) are containing the ROM-image in shuffled form, too.
Btw. where are those GBA titles stored? And 3DS shop titles in general?
Dsiware titles are stored on the internal eMMC partition.
But GBA and 3DS titles... there seem to be no internal eMMC folders for them... or are they always stored on external SD card?
Re: 3DS reverse engineering
To me these seem to be hardware fixes for some games that rely and break on hardware bugs (Such as the Pokémon Berry Glitch). And since GBA SDK RTC methods target the RTC IO map, these allow to run "pure 3DS mode" or "GBA mode", but it's just a wild guess as always.nocash wrote: ↑Wed Mar 25, 2020 6:41 am The RTC is the craziest that I've seen so far. One should think that RTCs are simple pieces of hardware. But this one seems to have built-in dividers for converting "Days since 1st Jan 2000" to "BCD day, month, year" (and perhaps vice-versa, too). There's also some weird support for negative HH:MM:SS values. It's just crazy ; )Code: Select all
10018108h - ARM7_RTC_CNT (W and R) 0 Write (0=No change, 1=Apply RTC_HEX) (W) 1 Read (0=No change, 1=Latch RTC_BCD and RTC_HEX) (W) 2-13 Unused (0) 14 Write Error Flag (0=Okay, 1=Error, invalid data) (R) 15 Write/Read Busy Flag (0=Ready, 1=Busy) (R) To get the current time: Set Read flag, wait until busy=0, then read RTC_HEX or RTC_BCD registers To set the current time: Write RTC_HEX registers, then set Write flag, then wait until busy=0 (this does also set BCD registers, the hardware auto-converts HEX to BCD) The initial time on power-up in 01 Jan 2000, 00:00:00. The actual battery backed time can be obtained from MCU[30h..36h]. The GBA software can access the RTC via port 080000C4h, 080000C6h, 080000C8h. 10018110h - ARM7_RTC_BCD_DATE (R) 0-7 Year BCD (00h..99h) 8-15 Month BCD (01h..12h) 16-23 Day BCD (01h..31h) 24-31 Day of Week (00h..06h) (WHAT=Monday?) 10018114h - ARM7_RTC_BCD_TIME (R) 0-7 Hour BCD (00h..23h) (always 24-hours, even in AM/PM mode) 8-15 Minute BCD (00h..59h) 16-23 Second BCD (00h..59h) 24-31 Zero (00h) 10018118h - ARM7_RTC_HEX_TIME (R=Latched Read value, W=Written value) 0-6 Second (signed -40h..+3Fh, usually 00h..3Bh) 7 Force Reset (0=Normal, 1=Force 1st Jan 2000, 00:00:00) 8-14 Minute (signed -40h..+3Fh, usually 00h..3Bh) 15 12/24-hour (0=12 hour, 1=24 hour) (for GBA side, both with AM/PM flag) 16-21 Hour (signed -20h..+1Fh, usually 00h..17h) 22-23 Unused (0) 24-27 Day of Week (signed -08h..+07h, usually 00h..06h) (WHAT=Monday?) 28-30 Unknown (can be 0..7) 31 Error (0=Normal, 1=Triggers error) 1001811Ch - ARM7_RTC_HEX_DATE (R=Latched Read value, W=Written value) 0-15 Days since 1st Jan 2000 (0000h..8EACh=100 years, Bigger=Triggers error) 16-31 Unknown (can be 0000h..FFFFh)
Re: 3DS reverse engineering
Like this...
The thing that looks crazy to me is that the RTC seems to contain a built-in microprocessor with division functions for converting "days since 1/1/2000" into three BCD counter values; they could have as well used raw hardware counters, and handled the initialization maths on ARM11 side.
The support for negative seconds, minutes, and hours is also a bit weird, even if it's related to some kind of inner workings, it's odd to see that feature in the user write-able registers.
And the extra craziness is that the RTC's for GBA and NDS are almost identical, but the 3DS seems to use entirely different implementations for emulating them. I guess they have two different people for doing almost the same thing.
The other RTC with the bitswapped bytes (for NDS) is almost even weirder (but at least it's offloading the bitswapping to ARM11 side, without needing another bult-in microprocessor for that).
"Replaced battery When the supply of power from the battery is interrupted, the RTC is reset to January 1, 2000. As with the Berry glitch , this reset causes all scheduled calendar-based events to be frozen until the RTC reaches the expected value, which may take many years."?Well, maybe, but I think 1st January 2000 is just the begin of the century, not a game-specific hardware fix.
The thing that looks crazy to me is that the RTC seems to contain a built-in microprocessor with division functions for converting "days since 1/1/2000" into three BCD counter values; they could have as well used raw hardware counters, and handled the initialization maths on ARM11 side.
The support for negative seconds, minutes, and hours is also a bit weird, even if it's related to some kind of inner workings, it's odd to see that feature in the user write-able registers.
And the extra craziness is that the RTC's for GBA and NDS are almost identical, but the 3DS seems to use entirely different implementations for emulating them. I guess they have two different people for doing almost the same thing.
The other RTC with the bitswapped bytes (for NDS) is almost even weirder (but at least it's offloading the bitswapping to ARM11 side, without needing another bult-in microprocessor for that).
Re: 3DS reverse engineering
I have asked Sono at gbatemp for help, and got some useful info: The FIFOs are at 10310000h/10311000h, but they can be read via CDMA only.
I didn't wanted to believe the CDMA part because all other FIFOs work with CPU reads... but it's true, with CDMA it did work on first try (after countless failed attempts with CPU reads).
And I also got some more info on the Scaling registers from Sono: The 8x6 word arrays are for scaling up to 8 output pixels, each from 6 input pixels. And, one must use value 400h for full brightness (I had tried 7FFh, which apparently caused some weird multiply overflow, causing white to get converted to dark gray).
I couldn't grasp why the registers where named MTX_xxx and KRN_xxx, so I have renamed everything back to the LGYFB_xxx (Legacy Framebuffer). MTX and KRN did only remind me about 3D/maths and OS/kernels, but hardly about bitmap scaling. And "screen width" versus "array/pattern width" did also confuse me, so I have changed the latter from "width" to "length". Anyways, the new names are...
The registers are almost fully known now (except one bit in LGYFB_CNT.bit16, and four bits in LGYFB_UNKNOWN).
And, the scaling registers...
And, the default values for scaling by 1.5 and 1.25 (as used by Nintendo):
LCD ghosting remains a mystery for now.
But well, the name implies that it must be something that couldn't be explained.
I didn't wanted to believe the CDMA part because all other FIFOs work with CPU reads... but it's true, with CDMA it did work on first try (after countless failed attempts with CPU reads).
And I also got some more info on the Scaling registers from Sono: The 8x6 word arrays are for scaling up to 8 output pixels, each from 6 input pixels. And, one must use value 400h for full brightness (I had tried 7FFh, which apparently caused some weird multiply overflow, causing white to get converted to dark gray).
I couldn't grasp why the registers where named MTX_xxx and KRN_xxx, so I have renamed everything back to the LGYFB_xxx (Legacy Framebuffer). MTX and KRN did only remind me about 3D/maths and OS/kernels, but hardly about bitmap scaling. And "screen width" versus "array/pattern width" did also confuse me, so I have changed the latter from "width" to "length". Anyways, the new names are...
Code: Select all
3DS Video LGY Registers (Legacy GBA/NDS Video to Framebuffer)
-------------------------------------------------------------
The LGYFB units are for forwarding GBA/NDS/DSi video to 3DS screens with
optional scaling. The input comes directly from the GBA/NDS video controller,
the output must be DMAed to memory.
That is, ARM11 must handle that memory transfers in background while running
GBA/NDS/DSi software on ARM7/ARM9 side.
10110000h - LGYFB0 (Legacy Framebuffer 0) (NDS bottom screen) (and GBA)
10111000h - LGYFB1 (Legacy Framebuffer 1) (NDS top screen) (and GBA)
10110000h/10111000h 4 LGYFB_CNT R/W mask:00019f37h ;\
10110004h/10111004h 4 LGYFB_SIZE R/W mask:01ff01ffh ; Control
10110008h/10111008h 4 LGYFB_IRQ_STAT R/ack mask:01f80007h ; Status
1011000Ch/1011100Ch 4 LGYFB_IRQ_ENABLE R/W mask:0007h ;/
10110020h/10111020h 4 LGYFB_ALPHA R/W mask:000000ffh ;-Alpha
101100F0h/101110F0h 4 LGYFB_UNKNOWN R/W mask:0000000fh ;-Unknown?
10110100h/10111100h 4 LGYFB_DITHER0 R/W mask:0000cccch ;\
10110108h/10111108h 4 LGYFB_DITHER1 R/W mask:0000cccch ; Dither
10110110h/10111110h 4 LGYFB_DITHER2 R/W mask:0000cccch ;
10110118h/10111118h 4 LGYFB_DITHER3 R/W mask:0000cccch ;/
10110200h/10111200h 4 LGYFB_V_LEN R/W mask:00000007h ;\Vertical
10110204h/10111204h 4 LGYFB_V_PATTERN R/W mask:000000ffh ; Scaling
10110240h/10111240h 4x30h LGYFB_V_ARRAY R/W mask:0000fff0h ;/
10110300h/10111300h 4 LGYFB_H_LEN R/W mask:00000007h ;\Horizontal
10110304h/10111304h 4 LGYFB_H_PATTERN R/W mask:000000ffh ; Scaling
10110340h/10111340h 4x30h LGYFB_H_ARRAY R/W mask:0000fff0h ;/
10310000h/10311000h 1000h LGYFB_FIFO R CDMA only ;-Output
Code: Select all
10110000h/10111000h - LGYFB_CNT (R/W)
0 Start/Enable (0=Stop, 1=Start) (R/W)
1 Enable Vertical Scaling (0=Disable, 1=Enable) (R/W)
2 Enable Horizontal Scaling (0=Disable, 1=Enable) (R/W)
3 Unused (0)
4 Brightness Dither Enable (0=No, 1=Use Y2R_DITHER0-3) (R/W)
5 Brightness Dither, too? (as above, no Y2R-style Pulsation) (R/W)
6-7 Unused (0)
8-9 Output Format RGBA (0=8888, 1=8880, 2=5551, 3=5650) (R/W)
10-11 Output Clockwise Rotate (0=None, 1=90', 2=180', 3=270') (R/W)
12 Output Swizzle (0=LinearFramebuf, 1=MortonSwizzleTexture)(R/W)
13-14 Unused (0)
15 Enable DMA (0=Off, 1=Enable CDMA 0Dh/0Eh) (R/W)
16 Unknown... seems to have no effect on GBA (maybe for NDS?) (R/W)
17-31 Unused (0)
Once when started, the transfer does auto-repeat each frame (although, that may
hang with some/wrong settings; in that case it can help to toggle CNT.bit0
after DMAing the last block of each frame).
10110004h/10111004h - LGYFB_SIZE (R/W)
0-8 Output Width (after scaling), minus 1 (0..1FFh = 1..512 pixels) (R/W)
9-15 Unused (0)
16-24 Output Height (after scaling), minus 1 (0..1FFh = 1..512 pixels) (R/W)
25-31 Unused (0)
Caution: Must be written via 32bit STR (trying to use 16bit STRH will set BOTH
halfwords to the same value).
10110008h/10111008h - LGYFB_IRQ_STAT (R/ack)
0 First 8-Line Output Block (0=No, 1=Yes/IRQ) (write 1 to clear) (R/ack)
1 Next 8-Line Output Block (0=No, 1=Yes/IRQ) (write 1 to clear) (R/ack)
2 Last Input? Line (0=No, 1=Yes/IRQ) (write 1 to clear) (R/ack)
3-15 Unused (0)
16-24 Output Block Line Number for IRQ bit0/1 (step 8) (R)
25-31 Unused (0)
The Output Block Line Number can be used to compute destination address for IRQ
bit0/1. The initial line number upon reset is random/garbage (but gets valid
after setting LGYFB_CNT.bit0).
Overrun can occur when not reading the output FIFO fast enough. After overrun,
bit1 triggers only on each 2nd block, and bit2 won't trigger at all.
1011000Ch/1011100Ch - LGYFB_IRQ_ENABLE - ? (R/W)
0 First 8-Line Output Block (0=Off, 1=Enable IRQ 4Ch/4Dh) (R/W)
1 8-Line Output Blocks (0=Off, 1=Enable IRQ 4Ch/4Dh) (R/W)
2 Last Input? Line (0=Off, 1=Enable IRQ 4Ch/4Dh?) (R/W)
3-31 Unused (0)
IRQ enable does also require LGYFB_CNT.bit0=1 and CFG11_TWLMODE_0.bit15=1.
The end of frame irq occurs only if the blocks were actually transferred (via
CDMA).
10110020h/10111020h - LGYFB_ALPHA - (R/W)
0-7 Alpha value for all pixels (00h..FFh = Transparent..Solid)
8-31 Unused (0)
Used as alpha for output format 8888 and 5551 (the latter uses only bit7 of the
8bit value).
101100F0h/101110F0h - LGYFB_UNKNOWN (R/W)
0-3 Unknown (initially 0Fh on reset)
4-31 Unused (0)
Unknown. IRQ and DMA requests won't occur when using too small values. Without
scaling values 01h..0Fh are working, with 2x vertical scaling only values
06h..0Fh are working.
10110100h/10111100h - LGYFB_DITHER0 (R/W)
10110108h/10111108h - LGYFB_DITHER1 (R/W)
10110110h/10111110h - LGYFB_DITHER2 (R/W)
10110118h/10111118h - LGYFB_DITHER3 (R/W)
0-31 Dither alike Y2R, R/W-mask 0000CCCCh
10310000h/10311000h - LGYFB_FIFO (R)
Caution: This FIFO works via CDMA only (unlike most or all other FIFOs, it does
trigger data abort when trying to read via CPU LDR opcodes; even if there is
data in the FIFO).
0-31 Output FIFO (contains 8 output lines per DMA request)
Use DMAWFP opcode (Wait for Peripheral) before reading an 8-line block. Or,
wait for LGYFB_IRQ_STAT bit0/1, and then manually start the DMA for one 8-line
block (the latter can be useful for transfers with clockwise rotate; where one
may need to patch the destination address for each block).
Code: Select all
10110200h/10111200h - LGYFB_V_LEN - Vertical scaling (R/W)
10110300h/10111300h - LGYFB_H_LEN - Horizontal scaling (R/W)
0-2 Batch size-1 (0..7 = 1..8 dst pixels) (using (1..8)*6 array entries)
3-31 Unused (0)
Selects the number of pattern bits and array entries to be used (before
repeating the scaling pattern).
10110204h/10111204h - LGYFB_V_PATTERN - Vertical scaling (R/W)
10110304h/10111304h - LGYFB_H_PATTERN - Horizontal scaling (R/W)
0-7 Read a new src pixel before computing 1st..8th dst pixel (0=No, 1=Yes)
8-31 Unused (0)
"The amount of set bits determine how many pixels are read each batch."
"Any bit indexes past LGYFB_x_LEN are ignored."
"This value is 8 bits, but it has to be written with a 32bit write."
Example values:
Len Pattern Effect
1 xxxxxxx1b No scaling (1 input pixels --> 1 output pixels)
8 11111111b No scaling (8 input pixels --> 8 output pixels)
5 xxx01111b Scale by 1.25 (4 input pixels --> 5 output pixels) ;NDS/DSi
4 xxxx0111b Scale by 1.33 (3 input pixels --> 4 output pixels)
3 xxxxx011b Scale by 1.5 (2 input pixels --> 3 output pixels)
6 xx011011b Scale by 1.5 (4 input pixels --> 6 output pixels) ;GBA
3 xxxxx001b Scale by 3 (1 input pixels --> 3 output pixels)
2 xxxxxx01b Scale by 2 (1 input pixels --> 2 output pixels)
8 01010101b Scale by 2 (4 input pixels --> 8 output pixels)
GBA (240x160) scale by 1.5 = 3DS top screen (360x240)
GBA (240x160) scale by 1.33 = 3DS bottom screen (320x213)
NDS (256x192) scale by 1.25 = 3DS either screen (320x240)
10110240h/10111240h - LGYFB_V_ARRAY - Vertical scaling, 6x8 words (R/W)
10110340h/10111340h - LGYFB_H_ARRAY - Horizontal scaling, 6x8 words (R/W)
This array contains 6x8 words, used to compute up to 8 output pixels, with
brightness multipliers for 6 input pixels each.
0-3 Unused (0) (Nintendo writes 16bit to bit0-15, but bit0-3 are ignored)
4-15 Brightness per source pixel (signed, -800h..+7FFh; 400h=full/max)
16-31 Unused (0)
The sum of six input values should be 400h (the hardware does automatically
clip results to min/max brightness; clipping can happen when mixing positive
and negative values; with some of them getting multiplied with dark input
pixels).
Note: Multipliers bigger than 400h are glitchy (value 7FFh somehow converts
white pixels to dark gray).
Code: Select all
Default Array for GBA screen (scale by 1.5) (240x160 to 360x240)
This is using Pattern=011011b and Length=6 (minus 1). The array entries are
straight ahead, using pixels with full brightness, and merged pixels with half
brightness:
0000h,0000h,0000h,0000h,0000h,0000h, N/A , N/A <-- for 1st input pixel
0000h,0000h,0000h,0000h,0000h,0000h, N/A , N/A <-- for 2nd input pixel
0000h,2000h,4000h,0000h,2000h,4000h, N/A , N/A <-- for 3rd input pixel
4000h,2000h,0000h,4000h,2000h,0000h, N/A , N/A <-- for 4th input pixel
0000h,0000h,0000h,0000h,0000h,0000h, N/A , N/A <-- for 5th input pixel
0000h,0000h,0000h,0000h,0000h,0000h, N/A , N/A <-- for 6th input pixel
| | | | | |
| '-----------------> to 6th output pixel
'-----------------------------------------------> to 1st output pixel
For whatever reason, this is scaling by 6:4 with 6 output pixels (instead of
3:2 with 3 output pixels). Unknown if it's faster that way, or if there's some
other advantage.
Default Array for NDS/DSi screens (scale by 1.25) (256x192 to 320x240)
This is using Pattern=01111b and Length=5 (minus 1). The array entries contain
positive and negative values, which might raise contrast between bright/dark
pixels:
0000h,004Eh,011Dh,01E3h,01C1h, N/A , N/A , N/A <-- for 1st input pixel
0000h,FCA5h,F8D0h,F69Dh,F873h, N/A , N/A , N/A <-- for 2nd input pixel
0000h,0D47h,1E35h,2F08h,3B6Fh, N/A , N/A , N/A <-- for 3rd input pixel
4000h,3B6Fh,2F08h,1E35h,0D47h, N/A , N/A , N/A <-- for 4th input pixel
0000h,F873h,F69Dh,F8D0h,FCA5h, N/A , N/A , N/A <-- for 5th input pixel
0000h,01C1h,01E3h,011Dh,004Eh, N/A , N/A , N/A <-- for 6th input pixel
| | | | |
| '-----------------------> to 5th output pixel
'-----------------------------------------------> to 1st output pixel
Weirdly, the values for 2nd-5th output pixel values sum up to 3FDDh/3FAAh
(actually less, because the lower 4bit are ignored), making them a bit darker
than 1st output pixel.
But well, the name implies that it must be something that couldn't be explained.
Re: 3DS reverse engineering
GBA Mode is mostly working. I can run code in RAM without problems, and also run the GBA BIOS intro, display GBA video via above LGYFB registers, and managed to enable GBA sound. The sound requires two settings in CODEC_SNDEXCNT (Port 10145000h), bit6-11 is GBA volume, and bit15 enables GBA sound (maybe these bits are for NDS/DSi volume, too).
But GBA Cartridge ROM is unstable.
In lack of a real GBA cartridge slot, the ROM is emulated by storing the ROM-image in 3DS FCRAM, and that memory gets mapped to the ROM space once when in GBA mode (with the odd 20h-byte shuffle mentioned a few days ago).
I am using Magic Floor for testing. Sometimes it's working, sometimes it does crash, and sometimes it won't even show an intact Nintendo logo.
To see what is wrong, I have mapped two copies of the 5.5Kbyte game, one in ROM space, and one in RAM space, and then used a memory compare function on ARM7. That shows about 1-5 words with mismatching data. Repeating the memory compare (without rewriting the memory) does again show around 1-5 errors, but at different addresses.
So, the reading is unreliable, either some timing issue, or maybe collisions with some kind of external memory refresh? Is there anything known about configuring FCRAM?
3dbrew mentions a MB81EDS516545 datasheet for (parts of) the memory chip, which shows some configuration registers, but they can be accessed only by manipulating /RAS and /CAS and some other signals. The datasheet does say that they must be initialized after power-up, but I don't know if or the 3DS could do that... it might do so automatically, or have some write-config feature, or some enter-config-mode feature (then allowing to write config data to FCRAM memory space)?
Apart from the FCRAM's built-in registers, there might be more config stuff in the 3DS itself, I've tried to toggle various unknown bits (and, no, I don't have data cache's enabled). The NDS does set a Async memory mode bit in EXMENCNT before entering GBA mode, maybe something similar must be done on 3DS, too. Or, maybe one must actually first switch to NDS mode and initialize that EXMENCNT register on NDS side - instead of directly switching from 3DS to GBA mode.
I am running out of ideas what to try next.
Would be very interesting if anybody ever came across something that looked like FCRAM configuration!
Or, of course, any GBA-mode specific config details.
But GBA Cartridge ROM is unstable.
In lack of a real GBA cartridge slot, the ROM is emulated by storing the ROM-image in 3DS FCRAM, and that memory gets mapped to the ROM space once when in GBA mode (with the odd 20h-byte shuffle mentioned a few days ago).
I am using Magic Floor for testing. Sometimes it's working, sometimes it does crash, and sometimes it won't even show an intact Nintendo logo.
To see what is wrong, I have mapped two copies of the 5.5Kbyte game, one in ROM space, and one in RAM space, and then used a memory compare function on ARM7. That shows about 1-5 words with mismatching data. Repeating the memory compare (without rewriting the memory) does again show around 1-5 errors, but at different addresses.
So, the reading is unreliable, either some timing issue, or maybe collisions with some kind of external memory refresh? Is there anything known about configuring FCRAM?
3dbrew mentions a MB81EDS516545 datasheet for (parts of) the memory chip, which shows some configuration registers, but they can be accessed only by manipulating /RAS and /CAS and some other signals. The datasheet does say that they must be initialized after power-up, but I don't know if or the 3DS could do that... it might do so automatically, or have some write-config feature, or some enter-config-mode feature (then allowing to write config data to FCRAM memory space)?
Apart from the FCRAM's built-in registers, there might be more config stuff in the 3DS itself, I've tried to toggle various unknown bits (and, no, I don't have data cache's enabled). The NDS does set a Async memory mode bit in EXMENCNT before entering GBA mode, maybe something similar must be done on 3DS, too. Or, maybe one must actually first switch to NDS mode and initialize that EXMENCNT register on NDS side - instead of directly switching from 3DS to GBA mode.
I am running out of ideas what to try next.
Would be very interesting if anybody ever came across something that looked like FCRAM configuration!
Or, of course, any GBA-mode specific config details.
Re: 3DS reverse engineering
This doesn't help on the unstable FCRAM issue, but I've had a look at the "AXI Registers" registers.
Here's the overall Register Map.
There are registers for "Quality of Service" (whatever that is):
And registers for Arbitration (whatever that is):
And some read-only ID registers:
I have dumped the Arbitration registers on New3DS (in both Old3DS and New3DS mode):
If Master really means CPU/DMA, and Slave means Memory... here are some guesses what they might be (in no specific order):
I have used the "DDI0422D_hpm_pl301_r1p2_ts.pdf" datasheet as reference, which does match the ID values found on New3DS.
For whatever reason, 3dbrew suggests using an older r1p0 datasheet, which might hint on r1p0 being used in Old3DS(?)
And a summary: Most of the registers are read-only. The only things that can be changed are:
- One can change the 2 QoS registers for MI=0.
- One can change the 34 priority settings for MI=0.
And, switching between Old3DS and New3DS mode does somewhat indirectly change some fixed settings.
I don't know if the firmware is changing the power up default settings.
(or if there are any positive/negative effects at all when changing any of those settings)
Here's the overall Register Map.
Code: Select all
PrimeCell High-Performance AXI Bus Matrix (HPM) (PL301) Revision: r1p2
This is something for configuring interactions between Master Interfaces (MIs)
and Slave Interfaces (SIs). The datasheet contains only meaningless blurb in a
too-big-too-fail language. Guessing between the lines, Master does probably
refer to CPUs and DMA controllers, and Slave might refer to Memory Chips.
1020F000h-3FCh Unused (0) (-)
1020F400h+MI*20h QoS Tidemark for Master MI=00h (R/W)
1020F404h+MI*20h QoS Access Control for Master MI=00h (R/W)
1020F408h+MI*20h AR Channel Arbitration value for MI=00h..NumMI-1 (R/W)
1020F40Ch+MI*20h AW Channel Arbitration value for MI=00h..NumMI-1 (R/W)
1020F800h-FBCh Reserved (0) (-)
1020FFC0h PrimeCell Configuration Register 0 NumSI's (07h/0Ah) (R)
1020FFC4h PrimeCell Configuration Register 1 NumMI's (11h/16h) (R)
1020FFC8h PrimeCell Configuration Register 2 Zero (00h) (R)
1020FFCCh PrimeCell Configuration Register 3 Zero (00h) (R)
1020FFD0h-FDCh Reserved (0) (-)
1020FFE0h-FECh PrimeCell Peripheral Register 0,1,2,3 (01h,13h,x4h,00h) (R)
1020FFF0h-FFCh PrimeCell ID Register 0,1,2,3 (0Dh,F0h,05h,B1h) (R)
These registers allow to read some fixed settings, and to change a few variable
settings (there must be a lot more fixed internal settings assigned at
manufacturing time, but one cannot read or change them).
The 3DS seems to support 1020F400h/1020F404h for Master 0 only.
Whilst 1020F408h/1020F40Ch are supported for Master 0 and up.
Code: Select all
1020F400h+MI*20h - QoS Tidemark for Master MI=00h (R/W)
0-6 Max number of outstanding transactions before activating QoS (0..7Fh)
7-31 Unused (0)
A value of 00h does completely disable QoS (instead of instantly triggering it
upon 0 outstanding transactions). QoS is short for Quality of Service (whatever
than means).
1020F404h+MI*20h - QoS Access Control for Master MI=00h (R/W)
0-6 Permit Slave 0-6 to use reserved slots (1=Yes) ;\Old3DS mode
7-31 Unused (0) ;/
0-9 Permit Slave 0-9 to use reserved slots (1=Yes) ;\New3DS mode
10-31 Unused (0) ;/
Code: Select all
1020F408h+MI*20h AR Channel Arbitration value for MI=00h..NumMI-1 (R/W)
1020F40Ch+MI*20h AW Channel Arbitration value for MI=00h..NumMI-1 (R/W)
Arbitration for AXI read (AR) and AXI write (AW) address channel signals.
The meaning of these register depends on the chip-configuration. There are
three possible modes for each MI (of which, the 3DS uses LRG for MI=00h, and
Fixed RR for MI=01h and up).
Programmable Least Recently Granted (LRG) arbitration (3DS: used for MI=00h)
Write ii00pp00h ;set priority for interface ;-write
Write FF0000iih ;select interface for reading ;\read
Read 0000ppiih ;read priority for previously selected interface ;/
Fixed Round-robin (RR) arbitration scheme (3DS: used for MI=01h..NumMI-1)
Write xxxxxxxxh ;ignored (values are fixed) ;-write
Write FF0000ssh ;select slot for reading ;\read
Read 000000iih ;read interface for previously selected slot ;/
Programmable Round-robin (RR) arbitration scheme (3DS: not used)
Write ss0000iih ;set interface for slot ;-write
Write FF0000ssh ;select slot for reading ;\read
Read 000000iih ;read interface for previously selected slot ;/
Whereas, the parameter bits are:
pp = Priority (00h..FFh; 00h=Highest, FFh=Lowest) ;for LRG
ss = Slot number (00h..unknown max value) ;for RR
ii = Slave interface number (00h..NumSI-1)
FF = Fixed code for reading (FFh)
00 = Unused/reserved (00h)
Code: Select all
1020FFC0h PrimeCell Configuration Register 0 Num SIs (R)
1020FFC4h PrimeCell Configuration Register 1 Num MIs (R)
0-7 Number of Master/Slave Interfaces (MIs/SIs) (01h..20h)
8-31 -
The values here change depending on whether running in Old3DS or New3DS mode.
Old3DS Mode: NumMI=11h, NumSI=07h
New3DS Mode: NumMI=16h, NumSI=0Ah
1020FFC8h PrimeCell Configuration Register 2 Zero (R)
1020FFCCh PrimeCell Configuration Register 3 Zero (R)
0-31 Zero
1020FFE0h-FECh - PrimeCell Peripheral Register 0-3 (R)
This region contains four 32bit registers (01h,13h,x4h,00h). One is supposed to
extract the lower 8bit of these 32bit values, and then to merge them into a
"conceptual-32bit-value" (00x41301h). And then interprete it as so:
0-11 Part number (301h=HPM)
12-19 Designer (41h=ARM)
20-23 Revision (1=r1p0, 2=r1p1, 3=r1p2)
24-31 Reserved (undef)
This value is fixed=00341301h on New3DS (ie. r1p2, no matter if running in
Old3DS or New3DS mode).
The value on actual Old3DS is unknown (although, some consoles are reportedly
using r1p0?).
1020FFF0h-FFCh - PrimeCell ID Register 0-3 (R)
This region contains four 32bit registers (0Dh,F0h,05h,B1h). One is supposed to
extract the lower 8bit of these 32bit values, and then to merge them into a
"conceptual-32bit-value" (B105F00Dh). And then interprete it as so:
0-31 Component ID (B105F00Dh) (same ID as for Corelink DMA controller)
Code: Select all
The following settings exist on New3DS (the fixed values are same for AR+AW):
Master Old3DS Mode New3DS Mode
MI=00h pp pp pp pp pp pp pp -- -- -- -- pp pp pp pp pp pp pp pp pp pp --
MI=01h -- 01 02 03 04 05 06 -- -- -- -- -- 01 02 03 04 05 06 07 08 09 --
MI=02h 01 02 05 06 -- -- -- -- -- -- -- 01 02 05 06 08 09 -- -- -- -- --
MI=03h 01 02 04 05 06 -- -- -- -- -- -- 01 02 04 05 06 08 09 -- -- -- --
MI=04h 01 02 04 -- -- -- -- -- -- -- -- 01 02 04 08 -- -- -- -- -- -- --
MI=05h 01 02 04 -- -- -- -- -- -- -- -- 01 02 04 08 -- -- -- -- -- -- --
MI=06h 01 02 04 -- -- -- -- -- -- -- -- 01 02 04 08 -- -- -- -- -- -- --
MI=07h 01 02 -- -- -- -- -- -- -- -- -- 01 02 08 -- -- -- -- -- -- -- --
MI=08h 01 02 -- -- -- -- -- -- -- -- -- 01 02 08 -- -- -- -- -- -- -- --
MI=09h 01 02 -- -- -- -- -- -- -- -- -- 01 02 08 -- -- -- -- -- -- -- --
MI=0Ah 01 02 05 -- -- -- -- -- -- -- -- 01 02 05 08 -- -- -- -- -- -- --
MI=0Bh -- -- -- -- -- -- -- -- -- -- -- 02 08 -- -- -- -- -- -- -- -- --
MI=0Ch -- -- -- -- -- -- -- -- -- -- -- 08 02 -- -- -- -- -- -- -- -- --
MI=0Dh -- -- -- -- -- -- -- -- -- -- -- 01 08 -- -- -- -- -- -- -- -- --
MI=0Eh -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
MI=0Fh -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
MI=10h -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
MI=11h -- -- -- -- -- -- -- -- -- -- -- 01 08 -- -- -- -- -- -- -- -- --
MI=12h -- -- -- -- -- -- -- -- -- -- -- 01 08 -- -- -- -- -- -- -- -- --
MI=13h -- -- -- -- -- -- -- -- -- -- -- 01 08 -- -- -- -- -- -- -- -- --
MI=14h -- -- -- -- -- -- -- -- -- -- -- -- 01 02 03 04 05 06 07 08 09 --
MI=15h -- -- -- -- -- -- -- -- -- -- -- -- 01 02 03 04 05 06 07 08 09 --
Entries with value "01..09" are fixed (and have same values for AR and AW).
Entries marked "--" are reading as zero (but there seems to be no way to
distinguish between SI=00h and SI=None).
The priority values (pp) for MI=00h are ininitally 00h, but can be changed,
New3DS has 34 priority values in total (7+7 for AR+AW in Old3DS mode, and
another 10+10 for AR+AW in New3DS mode).
Code: Select all
Guesses on possible Master Interfaces (MIs)
Old3DS = 11h MI's
1xARM11 (with 2 CPU cores)
1xCDMA (with 8 channels)
1xCSND (with 32+2 sound+capture channels)
1xGPU (internal rendering, external to 2 LCD's, and memcopy/memfill)
1xDSP
1xARM9 ;\
1xXDMA (with 4 channels) ; ARM9
1xNDMA (with 8 channels) ;
1xDMA (with 4 channels) ;/
1xARM7 ;\
1xNDMA (with 4 channels) ; ARM7
1xDMA (with 4 channels) ; (can't really share ARM11 bus though)
1xNDS/GBA GPU (2x 2D and 1x 3D) ;
1xNDS/GBA Sound (with 15+2 channels) ;/
New3DS = 16h MIs (five more than Old3DS)
0xNewARM11 (but with 2 more CPU cores)
1xNewCDMA (with 8 channels)
1xMVD
1xLevel 2 Cache Controller
Guesses on possible Slave Interfaces (SIs)
Old3DS = 07h SI's
FCRAM
VRAM
ARM9 RAM
DSP RAM
AXI RAM
BIOS ROM(s)
I/O Area(s)
New3DS = 0Ah SIs (three more than Old3DS)
Extended VRAM? aka QTM?
Extended ARM9 RAM
Extended FCRAM
For whatever reason, 3dbrew suggests using an older r1p0 datasheet, which might hint on r1p0 being used in Old3DS(?)
And a summary: Most of the registers are read-only. The only things that can be changed are:
- One can change the 2 QoS registers for MI=0.
- One can change the 34 priority settings for MI=0.
And, switching between Old3DS and New3DS mode does somewhat indirectly change some fixed settings.
I don't know if the firmware is changing the power up default settings.
(or if there are any positive/negative effects at all when changing any of those settings)
Re: 3DS reverse engineering
Have you tried first switching to NDS/DSi mode before switching to GBA mode? It sounds as though you're switching from 3DS to GBA mode directly, and I don't know if the 3DS is designed to do that. It might help to look at what AGB_FIRM does for initializing the various magic registers as well.
Re: 3DS reverse engineering
Yes, my mode switch is done directly from 3DS mode to GBA mode. Can you already emulate GBA FIRM well enough to see what it is writing to the ARM7_CNT register? Or can somebody see how it is done in the GBA FIRM disassembly? It should be either...
The latter seems to be 99% working (the only issue is the unstable FCRAM), so I would almost bet that the FCRAM issue could be fixed on ARM11 side, without needing to go through NDS/DSi mode. But I may be wrong there.
I am currently working on running code in NDS/DSi mode, once when that's working I can try to switch from DSi to GBA mode. Or first switch from DSi to NDS mode before switching to GBA mode. Or maybe it will turn out that DSi mode is suffering the same issues with FCRAM.
Going by first test results, one must enable Main RAM in NDS/DSi EXMEMCNT register before seeing FCRAM at 02000000h, and then... it seems that DSi mode does only use the lower 16bit of the 64bit FCRAM databus... and there might be some more address shuffling going on.
For FCRAM init, there is that Port 10141210h CFG11_GPU_FCRAM_CNT register. I don't know if that's related to GPU and/or FCRAM, and if some settings in that register could switch FCRAM to a GBA-compatible mode.
Is there any possibly FCRAM init in the offical FIRM's? The NATIVE FIRM should theoretically initialize FCRAM before using FCRAM. And NDS/GBA FIRM's might reinitialize FCRAM before switching to GBA/NDS mode. If there is any such code, it should probably look like this...
Code: Select all
[10018000h]=1 ;ARM7_CNT switched to DSi mode instead of directly switching to GBA mode
or
[10018000h]=2 ;ARM7_CNT switched to GBA mode directly
I am currently working on running code in NDS/DSi mode, once when that's working I can try to switch from DSi to GBA mode. Or first switch from DSi to NDS mode before switching to GBA mode. Or maybe it will turn out that DSi mode is suffering the same issues with FCRAM.
Going by first test results, one must enable Main RAM in NDS/DSi EXMEMCNT register before seeing FCRAM at 02000000h, and then... it seems that DSi mode does only use the lower 16bit of the 64bit FCRAM databus... and there might be some more address shuffling going on.
For FCRAM init, there is that Port 10141210h CFG11_GPU_FCRAM_CNT register. I don't know if that's related to GPU and/or FCRAM, and if some settings in that register could switch FCRAM to a GBA-compatible mode.
Is there any possibly FCRAM init in the offical FIRM's? The NATIVE FIRM should theoretically initialize FCRAM before using FCRAM. And NDS/GBA FIRM's might reinitialize FCRAM before switching to GBA/NDS mode. If there is any such code, it should probably look like this...
Code: Select all
[io_port] = fcram_config_setting
or
[io_port] = fcram_config_enable
[fcram_area] = fcram_config_setting
[io_port] = fcram_config_disable
Re: 3DS reverse engineering
nocash wrote: ↑Fri Apr 03, 2020 4:34 am Yes, my mode switch is done directly from 3DS mode to GBA mode. Can you already emulate GBA FIRM well enough to see what it is writing to the ARM7_CNT register? Or can somebody see how it is done in the GBA FIRM disassembly? It should be either...The latter seems to be 99% working (the only issue is the unstable FCRAM), so I would almost bet that the FCRAM issue could be fixed on ARM11 side, without needing to go through NDS/DSi mode. But I may be wrong there.Code: Select all
[10018000h]=1 ;ARM7_CNT switched to DSi mode instead of directly switching to GBA mode or [10018000h]=2 ;ARM7_CNT switched to GBA mode directly
I am currently working on running code in NDS/DSi mode, once when that's working I can try to switch from DSi to GBA mode. Or first switch from DSi to NDS mode before switching to GBA mode. Or maybe it will turn out that DSi mode is suffering the same issues with FCRAM.
Going by first test results, one must enable Main RAM in NDS/DSi EXMEMCNT register before seeing FCRAM at 02000000h, and then... it seems that DSi mode does only use the lower 16bit of the 64bit FCRAM databus... and there might be some more address shuffling going on.
For FCRAM init, there is that Port 10141210h CFG11_GPU_FCRAM_CNT register. I don't know if that's related to GPU and/or FCRAM, and if some settings in that register could switch FCRAM to a GBA-compatible mode.
Is there any possibly FCRAM init in the offical FIRM's? The NATIVE FIRM should theoretically initialize FCRAM before using FCRAM. And NDS/GBA FIRM's might reinitialize FCRAM before switching to GBA/NDS mode. If there is any such code, it should probably look like this...Code: Select all
[io_port] = fcram_config_setting or [io_port] = fcram_config_enable [fcram_area] = fcram_config_setting [io_port] = fcram_config_disable
While researching MMU emulation a year ago I found it allocates and deallocate pages randomly out a given physical memory source.
This is called page translation in ARM nomenclature: http://infocenter.arm.com/help/index.js ... bhigi.html
Also, normally known as page is called Page Table Entry in ARM nomenclature. (for the page itself and its contents)
MMU emulation behaves pretty much like a malloc / free operation (in POSIX C environment), where it allocates and deallocate pages
(input: physical memory which may/will be shuffled -- output coherent/linear virtual memory),
and will re-arrange pages as desired (example: fragmentation occurs, a fragmented chunk of pages has enough memory for a giant page request, thus
all fragmented chunk of pages is re-arranged to a new area (updating the internal physical address), and freeing up the older chunk of pages, of which is assigned to
the new incoming giant page.
MPU emulation does not need to track the internal physical address except by a simple Co-op register because the protected ranges are linear and the co processor raises exceptions directly, also it lacks the page table registers
Somebody else documented the ARM MMU while extending its use to Linux:
https://elinux.org/Tims_Notes_on_ARM_memory_allocation
Also IIRC ARM uses AHB/AXI bus protocol commands to handle master / slave AHB/AXI controllers (because that's what they are, and controllers are wired between them, thus, the registers exposed are meant to setup the master interface, like you guessed)
Controllers have data packet transfer commands such as HBURST, which hardcodes how many words may a Master send (or Slave can receive) when the packet size is known, which can be useful sometimes (when using DMA, which will abuse sequential (ARM Nomenclature: SEQ) rather than initial (ARM Nomenclature: NONSEQ) memory accesses)
Other commands: HMASTLOCK: used by slaves with multiple ports, and HPROT: Protected Access
It is important to understand these older AHB commands because the AXI commands are an improvement of these. Think of the base for AXI protocol.
Since I have no experience with AXI, here's a useful post by Neil Parris:
https://community.arm.com/developer/ip- ... ith-axi-id
Huh, there seems to be an ARM feature called "Outstanding Request", which runs off the QoS.
Hope it helps!
Re: 3DS reverse engineering
I've got code running in NDS/DSi mode. And dumped the Memory map for NDS/DSi Mode.
Most of that memory is initially disabled. Main RAM needs enable in EXMEMCNT, Main RAM uses only the lower 16bit of the 64bit FCRAM data bus (ie. only each 4th halfword is used). OAM/Palette need enable in POWCNT1. VRAM needs enable in VRAMCNT. New Shared WRAM needs enable in MBK.
The ARM9 KEYCNT register doesn't seem to be forwarded to ARM11 side, so I had to output ARM9 text messages from ARM9 to ARM7 via IPCFIFO, and then via KEYCNT from ARM7 to ARM11.
Setting ARM7 Port 4700000h.bit0=1 does disable the patched ARM7 exception vectors, and enables the original GBA/NDS/DSi bootrom vectors. The register is write-only, and can be only changed from 0-to-1, but not back to 0.
FCRAM is working stable in NDS/DSi mode. I haven't yet tried switching from NDS to GBA mode.
The NDS bootrom contains this code for main ram config:
The DSi stage 2 bootcode contains something similar (there using port 2FFFFFEh instead of 27FFFFEh).
The 3DS should theoretically have something similar, too. The RAM enable does reportedly occur when disabling the upper 32K of the bootroms - which is done at the very end of the bootrom code. So the RAM configuration should be done at the begin of the native firm code... giving it a quick glance, I can't see anything like that there though.
Code: Select all
3DS --> NDS/DSi
08000000h --> 06800000h, NDS VRAM A (128Kbyte)
08020000h --> 06820000h, NDS VRAM B (128Kbyte)
08040000h --> 06840000h, NDS VRAM C (128Kbyte)
08060000h --> 03xx0000h, NDS ARM7 WRAM (64Kbyte) (ARM7 only)
08070000h --> 06898000h, NDS VRAM H (32Kbyte)
08078000h --> 068A0000h, NDS VRAM I (16Kbyte)
08080000h --> 06860000h, NDS VRAM D (128Kbyte)
080A0000h --> 06880000h, NDS VRAM E (64Kbyte)
080B0000h --> 06890000h, NDS VRAM F (16Kbyte)
080B4000h --> 06894000h, NDS VRAM G (16Kbyte)
080B8000h --> 03000000h, NDS Shared RAM (32Kbyte) (initially mapped to ARM9)
080C0000h --> 03xxxxxxh, DSi New Shared WRAM A (256Kbyte) (Misc)
1FF00000h --> 03xxxxxxh, DSi New Shared WRAM B (256Kbyte) (DSP Code)
1FF40000h --> 03xxxxxxh, DSi New Shared WRAM C (256Kbyte) (DSP Data)
20000000h --> 02000000h, NDS Main RAM (max 16MByte) ;\only each 4th
20000000h --> 0C000000h, DSi Main RAM (max 32Mbyte) ;/halfword used
ITCM/DTCM --> ITCM/DTCM, NDS ITCM/DTCM (32K+16K, same mapping as in 3DS mode)
FF-filled --> 08000000h, GBA Cart ROM/SRAM (32MB+64K) (empty, FFh-filled)
The ARM9 KEYCNT register doesn't seem to be forwarded to ARM11 side, so I had to output ARM9 text messages from ARM9 to ARM7 via IPCFIFO, and then via KEYCNT from ARM7 to ARM11.
Setting ARM7 Port 4700000h.bit0=1 does disable the patched ARM7 exception vectors, and enables the original GBA/NDS/DSi bootrom vectors. The register is write-only, and can be only changed from 0-to-1, but not back to 0.
FCRAM is working stable in NDS/DSi mode. I haven't yet tried switching from NDS to GBA mode.
The NDS bootrom contains this code for main ram config:
Code: Select all
STRH 2000h,[4000204h] ;EXMEMCNT, enable RAM, async mode
LDRH R0,[27FFFFEh]
STRH R0,[27FFFFEh]
STRH R0,[27FFFFEh]
STRH FFDFh,[27FFFFEh]
STRH E732h,[27FFFFEh]
LDRH R0,[27E57FEh]
STRH 6000h,[4000204h] ;EXMEMCNT, enable RAM, normal mode
The 3DS should theoretically have something similar, too. The RAM enable does reportedly occur when disabling the upper 32K of the bootroms - which is done at the very end of the bootrom code. So the RAM configuration should be done at the begin of the native firm code... giving it a quick glance, I can't see anything like that there though.
Re: 3DS reverse engineering
Here comes the Level 2 Cache controller, that's probably the last major register block that wasn't yet documented in homebrew 3DS specs. So, well, I don't think that more than 0 people will ever read that documention... but, anyways, now it is documented. Alongsides, there's one more solved unknown interrupt source: Interrupt 76h is for the Level 2 Cache.
There are restrictions on accessing the above registers by Secure and Non-secure accesses (S and NS).
That is probably very important...
But what the fuck is a "Secure access"???
ARM CPUs do have a "privileged mode", which is probably not the same as secure access. As far as I know, secure accesses don't exist at all (or only for later ARMv7 models). The ARM11mpcore specs and ARMv6 reference don't seem to mention any "secure" feature. Am I missing something?
The Corelink DMA stuff does also have something called Secure state (where Secure seems to result in "restricted permission", ie. somewhat the opposite of privileged). For the Level 2 Cache debug registers, they are writeable only by Secure accesses (which would imply the opposite meaning).
Code: Select all
L2C-310 r3p3, Level 2 Cache Controller (New3DS only)
Cache ID and Cache Type (NS and S)
17E10000h L2C_CACHE_ID R 410000C9h ;\
17E10004h L2C_CACHE_TYPE R 9E440440h ;/
Control (Write S, Read NS and S)
17E10100h L2C_CONTROL RW 00000000h ;\
17E10104h L2C_AUX_CONTROL RW 02090000h ;
17E10108h L2C_TAG_RAM_CONTROL RW 00000111h ;
17E1010Ch L2C_DATA_RAM_CONTROL RW 00000221h ;/
Interrupt and Counter Control (NS and S)
17E10200h L2C_EV_COUNTER_CTRL RW 00000000h ;\
17E10204h L2C_EV_COUNTER1_CFG RW 00000000h ;
17E10208h L2C_EV_COUNTER0_CFG RW 00000000h ;
17E1020Ch L2C_EV_COUNTER1 RW 00000000h ;
17E10210h L2C_EV_COUNTER0 RW 00000000h ;
17E10214h L2C_INT_MASK RW 00000000h ; ;\
17E10218h L2C_INT_STATUS_MASKED R 00000000h ; ; Interrupts
17E1021Ch L2C_INT_STATUS_RAW R 00000000h ; ;
17E10220h L2C_INT_CLEAR W 00000000h ;/ ;/
Cache Maintenance Operations (Secure bit of access affects operation)
17E10730h L2C_CACHE_SYNC RW 00000000h ;\
17E10770h L2C_INV_PA RW 00000000h ;
17E1077Ch L2C_INV_WAY RW 00000000h ;
17E107B0h L2C_CLEAN_PA RW 00000000h ;
17E107B8h L2C_CLEAN_INDEX RW 00000000h ;
17E107BCh L2C_CLEAN_WAY RW 00000000h ;
17E107F0h L2C_CLEAN_INV_PA RW 00000000h ;
17E107F8h L2C_CLEAN_INV_INDEX RW 00000000h ;
17E107FCh L2C_CLEAN_INV_WAY RW 00000000h ;/
Cache Lockdown (Secure bit of access affects operation)
17E10900h+N*8 L2C_D_LOCKDOWN_0..7 RW 00000000h ;\
17E10904h+N*8 L2C_I_LOCKDOWN_0..7 RW 00000000h ;
17E10950h L2C_LOCK_LINE_EN RW 00000000h ;
17E10954h L2C_UNLOCK_WAY RW 00000000h ;/
Address Filtering (Write S, Read NS and S)
17E10C00h L2C_ADDR_FILTERING_START RW 00000000h ;\
17E10C04h L2C_ADDR_FILTERING_END RW 00000000h ;/
Debug, Prefetch and Power (Write S, Read NS and S)
17E10F40h L2C_DEBUG_CTRL RW 00000004h ;\
17E10F60h L2C_PREFETCH_CTRL RW 04000000h ;
17E10F80h L2C_POWER_CTRL RW 00000000h ;/
Caution: L2C registers can be read via LDR only (LDRB/LDRH cause data abort).
Official specs: DDI0246H_l2c310_r3p3_trm.pdf
_____________________ Cache ID and Cache Type (NS and S) _____________________
17E10000h - L2C_CACHE_ID - Cache ID Register (410000C9h) (R)
0-5 RTL release (9=r3p3)
6-9 Part number (3=L2C-310)
10-15 CACHEID pins (reads as 0 on New3DS)
16-23 Reserved (0)
24-31 Implementer (41h=ARM)
17E10004h - L2C_CACHE_TYPE - Cache Type Register (9E440440h) (R)
0-1 L2 cache line length (0=32 bytes) ;\
2-5 Reserved (0) ;
6 L2 associativity (from L2C_AUX_CONTROL.bit16) ; instruction
7 Reserved (0) ;
8-10 Isize L2 cache way size (from L2C_AUX_CONTROL.bit19-17) ;
11 Reserved (0) ;/
12-13 L2 cache line length (0=32 bytes) ;\
14-17 Reserved (0) ;
18 L2 associativity (from L2C_AUX_CONTROL.bit16) ; data
19 Reserved (0) ;
20-22 Dsize L2 cache way size (from L2C_AUX_CONTROL.bit19-17) ;
23 Reserved (0) ;/
24 Harvard (0=Unified, 1=Harvard) ;-harvard
25 Lockdown by Line option (0=Off, 1=On) ;\
26 Lockdown by Master option (0=Off, 1=On) ; ctype
27-28 Fixed (always 3) ;/
29-30 Reserved (0)
31 Data banking (0=Not implemented, 1=Implemented)
______________________ Control (Write S, Read NS and S) ______________________
17E10100h - L2C_CONTROL - Control Register (R/W)
0 L2 Cache enable (0=Disable, 1=Enable)
1-31 Reserved (0)
Caution: The cache seems to contain garbage on power-up. Set L2C_INV_WAY=FFFFh,
then wait for L2C_INV_WAY=0 before enabling L2C_CONTROL.
17E10104h - L2C_AUX_CONTROL - Auxiliary Control Register (02090000h) (R/W)
0 Full Line of Write Zero Enable (0=Disable, 1=Enable)
1-9 Reserved (0)
10 Priority for Strongly Ordered and Device Reads Enable (0=Low, 1=High)
11 Limit (0=Device writes can use all slots, 1=Ensure one Memory slot)
12 Exclusive cache configuration (0=Disable, 1=Enable)
13 Shared Attribute Invalidate Enable (0=Disable, 1=Enable if no override)
14-15 Reserved (0)
16 Associativity (0=8-way, 1=16-way)
17-19 Way-size (1=16K, 2=32K, 3=64K, 4=128K, 5=256K, 6=512K, 0/7=Same as 1/6)
20 Event monitor bus enable (0=Disable, 1=Enable)
21 Parity enable (0=Disable, 1=Enable)
22 Shared attribute override (0=No, 1=Ignore Shared Attrubute)
23-24 Force write allocate (0=Use WA, 1=ForceWA=0, 2=ForceWA=1, 3=Same as 0?)
25 Cache Replacement Policy (0=Pseudo-random/LFSR, 1=Round-robin)
26 Lockdown Register Writes (0=Secure only, 1=Allow non-secure)
27 Interrupt MASK/CLEAR Access (0=Secure only, 1=Allow non-secure)
28 Data Prefetch Enable (0=Disable, 1=Enable)
29 Instruction Prefetch Enable (0=Disable, 1=Enable)
30 Early BRESP Enable (0=Disable, 1=Enable, Early write response)
31 Reserved (0)
Note: R/W mask is FFFFFF7Fh (ie. most of the "Reserved" bits are write-able).
Cache size is reportedly "2MB" on New3DS, which is probably meant to be
2Mbyte, ie. 16 ways of 128Kbyte each, and that shared for both code and data
caching?
17E10108h - L2C_TAG_RAM_CONTROL - Tag RAM Latency Control (00000111h) (R/W)
17E1010Ch - L2C_DATA_RAM_CONTROL - Data RAM Latency Control (00000221h) (R/W)
0-2 RAM setup latency (0-7 = 1..8 cycles of latency)
3 Reserved (0)
4-6 RAM read access latency (0-7 = 1..8 cycles of latency)
7 Reserved (0)
8-10 RAM write access latency (0-7 = 1..8 cycles of latency)
11-31 Reserved (0)
Uh, is that the latency of the Cache Memory (ie. not the external "cached"
memory)?
__________________ Interrupt and Counter Control (NS and S) __________________
17E10200h - L2C_EV_COUNTER_CTRL - Event Counter Control (R/W)
0 Event Counting Enable (0=Disable, 1=Enable) (R/W)
1 Event Counter 0 Reset (0=No change, 1=Reset) (W)
2 Event Counter 1 Reset (0=No change, 1=Reset) (W)
3-31 Reserved (0)
17E10204h - L2C_EV_COUNTER1_CFG - Event Counter 1 Configuration (R/W)
17E10208h - L2C_EV_COUNTER0_CFG - Event Counter 0 Configuration (R/W)
0-1 Event counter interrupt generation (00h-03h, see below)
2-5 Counter event source (00h-0Fh, see below)
6-31 Reserved (0)
Event counter interrupt generation:
00h Disabled ;count, without irq
01h Enabled: Increment condition ;count, with irq on any increment
02h Enabled: Overflow condition ;count, with irq on overflow
03h Interrupt generation is disabled ;count, without irq (same as 0?)
Counter event source:
00h - Counter Disabled
01h CO Eviction, CastOUT, of a line from the L2 cache
02h DRHIT Data read hit in the L2 cache
03h DRREQ Data read lookup to the L2 cache
04h DWHIT Data write hit in the L2 cache
05h DWREQ Data write lookup to the L2 cache
06h DWTREQ Data write lookup to the L2 cache with Write-Through attribute
07h IRHIT Instruction read hit in the L2 cache
08h IRREQ Instruction read lookup to the L2 cache
09h WA Allocation into the L2 cache caused by a write, with
Write-Allocate attribute, miss
0Ah IPFALLOC Allocation of a prefetch generated by L2C-310 into the L2 cache
0Bh EPFHIT Prefetch hint hits in the L2 cache
0Ch EPFALLOC Prefetch hint allocated into the L2 cache
0Dh SRRCVD Speculative read received by slave port(s)
0Eh SRCONF Speculative read confirmed in slave port(s)
0Fh EPFRCVD Prefetch hint received by slave port(s)
Note: All REQ lookups will subsequently result in a hit or miss.
17E1020Ch - L2C_EV_COUNTER1 - Event counter 1 value (R/W)
17E10210h - L2C_EV_COUNTER0 - Event counter 0 value (R/W)
0-31 Counter value, incremented on selected event
If a counter reaches its maximum value, it saturates at that value until it is
reset.
17E10214h - L2C_INT_MASK - Interrupt Mask (0=Disable, 1=Enable) (R/W)
17E10218h - L2C_INT_STATUS_MASKED - Masked Interrupt Status Register (R)
17E1021Ch - L2C_INT_STATUS_RAW - Raw Interrupt Status (1=IRQ) (R)
17E10220h - L2C_INT_CLEAR - Interrupt Clear (0=No change, 1=Clear) (W)
0 ECNTR: Event Counter 0 and 1 Overflow/Increment
1 PARRT: Parity Error on L2 tag RAM, Read
2 PARRD: Parity Error on L2 data RAM, Read
3 ERRWT: Error on L2 tag RAM, Write
4 ERRWD: Error on L2 data RAM, Write
5 ERRRT: Error on L2 tag RAM, Read
6 ERRRD: Error on L2 data RAM, Read
7 SLVERR: SLVERR from L3
8 DECERR: DECERR from L3
9-31 Reserved (0)
Note: STATUS_MASKED is same as STATUS_RAW, but ANDed with MASK.
The IRQ triggers interrupt 76h.
________________________ Cache Maintenance Operations ________________________
17E10730h - L2C_CACHE_SYNC - Cache Maintenance Operations (R and W)
0 C, When writing: Must be 0 (trigger cache sync...?)
0 C, When reading: Background/Way operation is in progress (0=No, 1=Yes)
1-31 Reserved (0)
17E10770h - L2C_INV_PA - Invalidate by Physical Address (R/W)
17E107B0h - L2C_CLEAN_PA - Clean by Physical Address (R/W)
17E107F0h - L2C_CLEAN_INV_PA - Clean+Invalidate by Physical Address (R/W)
0 C (uh, is that same meaning as in L2C_CACHE_SYNC.bit0?) (R?)
1-4 Reserved (0)
5-xx Index (W?)
xx-31 Tag (W?)
17E1077Ch - L2C_INV_WAY - Invalidate by Way (R/W)
17E107BCh - L2C_CLEAN_WAY - Clean by Way (R/W)
17E107FCh - L2C_CLEAN_INV_WAY - Clean+Invalidate by Way (R/W)
0-15 Way bits (for way 0..15) (1=Trigger/busy?) (R/W)
16-31 Reserved (0)
17E107B8h - L2C_CLEAN_INDEX - Clean by Index (R/W)
17E107F8h - L2C_CLEAN_INV_INDEX - Clean+Invalidate by Index (R/W)
0 C (uh, is that same meaning as in L2C_CACHE_SYNC.bit0?) (R?)
1-4 Reserved (0)
5-xx Index (W?)
xx-xx Reserved (0)
28-31 Way number (0..15) (W?)
_______________________________ Cache Lockdown _______________________________
17E10900h+N*8 - L2C_D_LOCKDOWN_0..7 - Data Cache lockdown 0-7 (R/W)
17E10904h+N*8 - L2C_I_LOCKDOWN_0..7 - Instruction Cache lockdown 0-7 (R/W)
0-15 DATALOCK/INSTRLOCK 000..111 (use when AyUSERSx[7:5]=000b..111b) ;way?
16-31 Reserved (0)
17E10950h - L2C_LOCK_LINE_EN - Lockdown by Line Enable (R/W)
0 Lockdown by Line Enable (0=Disable, 1=Enable)
1-31 Reserved (0)
17E10954h - L2C_UNLOCK_WAY - Unlock all Lines by Way (R/W)
0-15 Unlock all Lines by Way operation (0=No/off, 1=Unlock/busy?) ;way0-15
16-31 Reserved (0)
_________________ Address Filtering (Write S, Read NS and S) _________________
17E10C00h - L2C_ADDR_FILTERING_START - Address filtering Start (R/W)
17E10C04h - L2C_ADDR_FILTERING_END - Address filtering End (R/W)
Not implemented, always zero in New3DS. Allows to redirect a whole address
range to master 1 (when two masters are implemented).
0 Address Filtering Enable (0=Disable, 1=Enable) ;<-- in Start register
0 Reserved (0) ;<-- in End register
1-19 Reserved (0)
20-31 Address Filtering Start/End Address bit31-20
_____________ Debug, Prefetch and Power (Write S, Read NS and S) _____________
17E10F40h - L2C_DEBUG_CTRL - Debug Register (00000004h) (R/W)
0 Disable cache linefill (0=Enable, 1=Disable cache linefills) (R/W)
1 Disable write-back (0=Write-back, 1=Force Write-through) (R/W)
2 Secure Privileged Non-Invasive Debug Enable SPNIDEN option (1=on?) (R)
3-31 Reserved (0)
This is write-able only if code cache is disabled in cp15?
17E10F60h - L2C_PREFETCH_CTRL - Prefetch Control Register (04000000h) (R/W)
0-4 Prefetch Offset (must be 0-7, 15, 23, or 31) (other=Unsupported)
5-20 Reserved (0)
21 Not same AXI ID on exclusive sequence enable (0=Same ID, 1=Not same)
22 Reserved (0)
23 Incr Double Linefill enable (allow 8x64bit) (0=Disable, 1=Allow)
24 Prefetch drop, Discard prefetch reads to L3 (0=Disable, 1=Enable)
25 Reserved (0)
26 Speculative Read Synthesis Option (read-only) (0=On, 1=Off) (R)
27 Double linefill on WRAP read disable (0=Enable, 1=Disable)
28 Data prefetch enable (0=Disable, 1=Enable)
29 Instruction prefetch enable (0=Disable, 1=Enable)
30 Double Linefill, Read bursts to L3 on L2 miss (0=4x64bit, 1=8x64bit)
31 Reserved (0)
This is write-able only if code cache is disabled in cp15?
Writing value FFE0001Fh is possible (ie. with reserved bit22,25,31 set)?
17E10F80h - L2C_POWER_CTRL - Power Control Register (R/W)
0 Standby mode enable (0=Disable, 1=Enable)
1 Dynamic clock gating enable (0=Disable, 1=Enable)
2-31 Reserved (0)
This is write-able only if code cache is disabled in cp15?
Writing value 00000007h is possible (ie. with reserved bit2 set)?
That is probably very important...
But what the fuck is a "Secure access"???
ARM CPUs do have a "privileged mode", which is probably not the same as secure access. As far as I know, secure accesses don't exist at all (or only for later ARMv7 models). The ARM11mpcore specs and ARMv6 reference don't seem to mention any "secure" feature. Am I missing something?
The Corelink DMA stuff does also have something called Secure state (where Secure seems to result in "restricted permission", ie. somewhat the opposite of privileged). For the Level 2 Cache debug registers, they are writeable only by Secure accesses (which would imply the opposite meaning).
Re: 3DS reverse engineering
It appears to have something to do with "TrustZone", introduced sometime during the ARM11 cycle. See ARM1176JZF-S Technical Reference Manual. (ARM1176 is the version of ARM11 just before mpcore was introduced.)
Re: 3DS reverse engineering
Yeah, looks so, thanks!
If I get it right, that TrustZone thing is the ARMv6Z security extension of ARMv6.
And presence of the security extension would be indicated in "Processor Feature Register 1" bit4-7 (which is zero on 3DS, so apparently it doesn't exist there).
If I get it right, that TrustZone thing is the ARMv6Z security extension of ARMv6.
And presence of the security extension would be indicated in "Processor Feature Register 1" bit4-7 (which is zero on 3DS, so apparently it doesn't exist there).