Difference between revisions of "ARM7 Registers"
WulfyStylez (talk | contribs) (more registers) |
|||
(19 intermediate revisions by 8 users not shown) | |||
Line 1: | Line 1: | ||
− | The 3DS utilizes an onboard ARM7 core to handle TWL_FIRM and AGB_FIRM's ARM7 requirements. This is due to the fact that much of the hardware used by both ARM7 and ARM9 is (evidently) not physically hooked up to ARM11. Thus, ARM11 cannot simply emulate ARM7. | + | The 3DS utilizes an onboard ARM7 core to handle <code>TWL_FIRM</code> and <code>AGB_FIRM</code>'s ARM7 requirements. This is due to the fact that much of the hardware used by both ARM7 and ARM9 is (evidently) not physically hooked up to ARM11. Thus, ARM11 cannot simply emulate ARM7. |
− | ARM7 has the | + | ARM7 has the GBA BIOS implemented in hardware. The BIOS is completely identical to the original GBA BIOS. The system is booted silently by calling <code>SWI 0x1</code> (a.k.a. <code>RegisterRamReset</code>), followed by jumping to the code that does <code>SWI 0x0</code> (a.k.a. <code>SoftReset</code>) to finish booting. The boot splash is still in BIOS, however, and can be seen by calling or replacing one of the previous interrupts with <code>SWI 0x26</code> (a.k.a. <code>HardReset</code>). |
− | = Registers = | + | |
+ | ==Registers== | ||
ARM9 interfaces with the ARM7 through the following registers: | ARM9 interfaces with the ARM7 through the following registers: | ||
− | {| class="wikitable" | + | |
+ | {| class="wikitable" | ||
+ | |- | ||
+ | ! Type | ||
+ | ! Address | ||
+ | ! Name | ||
+ | ! Size (bytes) | ||
+ | |- | ||
+ | | <code>u8</code> | ||
+ | | <code>0x10018000</code> | ||
+ | | <code>ARM7_CNT</code> | ||
+ | | 1 | ||
|- | |- | ||
− | + | | Code | |
− | | | + | | <code>0x10018080</code> |
− | + | | <code>ARM7_CODE</code> | |
+ | | 32 | ||
|- | |- | ||
− | | | + | | <code>u16</code> |
− | | | + | | <code>0x10018100</code> |
− | | | + | | <code>ARM7_SAVE_MODE</code> |
+ | | 2 | ||
|- | |- | ||
− | | | + | | <code>u16</code> |
− | | | + | | <code>0x10018104</code> |
− | | | + | | <code>ARM7_SAVE_MEMORY_CNT</code> |
+ | | 2 | ||
|- | |- | ||
− | | | + | | <code>u16</code> |
− | | | + | | <code>0x10018108</code> |
− | | | + | | <code>ARM7_RTC_CNT</code> |
+ | | 2 | ||
|- | |- | ||
− | | | + | | <code>u32</code> |
− | | | + | | <code>0x10018110</code> |
− | | | + | | <code>ARM7_RTC_VAL_DATE</code> |
+ | | 4 | ||
|- | |- | ||
− | | | + | | <code>u32</code> |
− | | | + | | <code>0x10018114</code> |
− | | | + | | <code>ARM7_RTC_VAL_TIME</code> |
+ | | 4 | ||
|- | |- | ||
− | | | + | | <code>u32</code> |
− | | | + | | <code>0x10018118</code> |
− | | | + | | <code>ARM7_RTC_VAL_SETTINGS</code> |
+ | | 4 | ||
|- | |- | ||
− | | | + | | <code>u32</code> |
− | | | + | | <code>0x1001811C</code> |
− | | | + | | <code>ARM7_RTC_VAL_ADJUST</code> |
+ | | 4 | ||
|- | |- | ||
− | | | + | | <code>u32</code> |
− | | | + | | <code>0x10018120</code> |
− | | | + | | <code>ARM7_SAVE_FLASH_CHIP_ERASE_CYCLES</code> |
+ | | 4 | ||
+ | |- | ||
+ | | <code>u32</code> | ||
+ | | <code>0x10018124</code> | ||
+ | | <code>ARM7_SAVE_FLASH_SECTOR_ERASE_CYCLES</code> | ||
+ | | 4 | ||
+ | |- | ||
+ | | <code>u32</code> | ||
+ | | <code>0x10018128</code> | ||
+ | | <code>ARM7_SAVE_FLASH_PROGRAM_CYCLES</code> | ||
+ | | 4 | ||
+ | |- | ||
+ | | <code>u32</code> | ||
+ | | <code>0x1001812C</code> | ||
+ | | <code>ARM7_SAVE_EEPROM_WRITE_CYCLES</code> | ||
+ | | 4 | ||
|} | |} | ||
− | == ARM7_CNT == | + | ===ARM7_CNT=== |
− | This | + | This seems to control the mode of the ARM7. 1 = TWL, 2 = GBA. |
+ | |||
+ | ===ARM7_CODE=== | ||
+ | This region is an arm7 bootrom overlay, over the vector table at address 0. Once the ARM7 is taken out of reset by <code>TwlProcess9</code>, the reset vector will be jumped to, beginning execution. <code>TwlProcess9</code> uses this to put ARM7 in a loop (TWL), and to set the <code>POSTFLG</code> and branch to more copied code (GBA). Execution is started by writing <code>0x8001</code> to [[PDN_Registers#LGY_MODE|LGY_MODE]] after setting the mode via <code>ARM7_CNT</code>. Later, this overlay is disabled by the ARM7 via the "biosprot" register (0x04000308). | ||
+ | |||
+ | Reading uninitialized data in this 32-byte region leads to both screens displaying solid green (exception), and the CPU locking up. | ||
+ | |||
+ | ===ARM7_SAVE_MODE=== | ||
+ | This tells the save storage emulation hardware which device type to emulate (64k EEPROM, a 512k Flash chip model, and SRAM are all that have been used officially; several other 512k Flash chip models, two 1 Mbit Flash chip models and 4k EEPROM are also supported). This comes directly from the [[3DS_Virtual_Console#Footer|ROM footer]]. | ||
+ | |||
+ | ===ARM7_SAVE_MEMORY_CNT=== | ||
+ | This register controls whether the GBA save memory region located at <code>0x08080000</code> is accessible to ARM9 or to the ARM7 (via the emulated save chip). When it's set to 0x0 ARM7 has access, while ARM9 has access when it's set to 0x1. | ||
+ | |||
+ | ===ARM7_RTC_CNT=== | ||
+ | This register controls the emulated RTC hardware and access to some of its registers. | ||
+ | To set or read the data from ARM7_RTC_VAL_SETTINGS or ARM7_RTC_VAL_ADJUST, first <code>ARM7_RTC_CNT</code>'s bit 15 is waited on. Next <code>ARM7_RTC_CNT</code> is set to zero. | ||
+ | |||
+ | For a write: the two registers are written, a 1 is written to <code>ARM7_RTC_CNT</code>, and it is waited on the same as before. Afterwards if bit 14 is not set in <code>ARM7_RTC_CNT</code>, the value was set successfully. This also starts the emulated RTC. | ||
+ | |||
+ | For a read: a 2 is written to <code>ARM7_RTC_CNT</code>, it's waited on again. Afterwards, if bit 14 is not set, the aforementioned registers can be read. Presumably the hardware can be re-enabled by writing a zero to <code>ARM7_RTC_CNT</code> at this point, but <code>AGB_FIRM</code> does not. | ||
+ | |||
+ | ===ARM7_RTC_VAL_DATE / ARM7_RTC_VAL_TIME=== | ||
+ | These registers are set to the current LgyP9 date+time before the other RTC-related registers are used. | ||
+ | They contain the following structure, set up on the stack then both u32 registers are written one after the other: | ||
+ | |||
+ | s8 year_since_2000_bcd; | ||
+ | s8 month_bcd; | ||
+ | s8 day_bcd; | ||
+ | s8 day_of_week; | ||
+ | s8 hour_bcd; | ||
+ | s8 minute_bcd; | ||
+ | s8 second_bcd; | ||
+ | |||
+ | ===ARM7_RTC_VAL_SETTINGS=== | ||
+ | This register appears to contain the emulated RTC chip's configuration (accessible via the "control" register on real hardware), containing settings like 12/24-hour mode. Access is controlled by <code>ARM7_RTC_CNT</code> (see above). | ||
+ | |||
+ | ===ARM7_RTC_VAL_ADJUST=== | ||
+ | This register appears to contain the emulated RTC chip's time difference, relative to <code>ARM7_RTC_VAL_DATE</code> / <code>ARM7_RTC_VAL TIME</code>, in seconds. Access is controlled by <code>ARM7_RTC_CNT</code> (see above). | ||
+ | |||
+ | ===ARM7_SAVE_FLASH_CHIP_ERASE_CYCLES=== | ||
+ | This register seems to configure the emulated Flash chip to take a specified amount of time to complete a chip erase operation (relative to the DS' ARM7/bus speed). Two variations exist in officially released games, one meant for 512k Flash chips and one for 1 Mbit Flash chips. It is copied from from rom footer + <code>0x10</code>. | ||
+ | |||
+ | ===ARM7_SAVE_FLASH_SECTOR_ERASE_CYCLES=== | ||
+ | This register seems to configure the emulated Flash chip to take a specified amount of time to complete a sector erase operation (relative to the DS' ARM7/bus speed). Two variations exist in officially released games, one meant for 512k Flash chips and one for 1 Mbit Flash chips. It is copied from from rom footer + <code>0x14</code>. | ||
+ | |||
+ | ===ARM7_SAVE_FLASH_PROGRAM_CYCLES=== | ||
+ | This register seems to configure the emulated Flash chip to take a specified amount of time to complete a program operation (relative to the DS' ARM7/bus speed). Two variations exist in officially released games, one meant for 512k Flash chips and one for 1 Mbit Flash chips. It is copied from from rom footer + <code>0x18</code>. | ||
− | == | + | ===ARM7_SAVE_EEPROM_WRITE_CYCLES=== |
− | This | + | This register seems to configure the emulated EEPROM chip to take a specified amount of time to complete a write operation (relative to the DS' ARM7/bus speed). Two variations exist in officially released games, one meant for 64k EEPROM chips and one for 4k EEPROM chips. It is copied from from rom footer + <code>0x1C</code>. |
− | == | + | ==Memory map== |
− | The | + | The virtual memory mapping for the ARM7 is the same as for the [[Memory_layout#TWL_FIRM_Userland_Memory|other core]]. However, it has additional internal memory mapped to it. Interestingly enough, much of this memory seems to lie within ARM9's own internal memory. |
− | + | * <code>0x08060000</code> → <code>0x03800000</code>, ARM7 WRAM (64KiB) | |
− | + | * <code>0x080B0000</code> → <code>0x03000000</code>, GBA IWRAM (32KiB) | |
− | *0x08060000 | + | * <code>0x08080000</code> → EEPROM/SRAM/Flash 512k/Flash 1Mbit (the 2 512k banks are contiguous in memory). Access is controlled by <code>ARM7_SAVE_MEMORY_CNT</code> (see above). <code>0x080C0000</code> holds a mirror which is used by LgyP9 on boot to read the SD savedata before the mode switch, the data is then copied. |
− | *0x080B0000 | + | * <code>0x01FFC000</code> → <code>0x01000000</code>, ARM9 ITCM under TWL (16KiB) |
− | *0x080C0000 | ||
− | *0x01FFC000 |
Latest revision as of 12:39, 12 April 2021
The 3DS utilizes an onboard ARM7 core to handle TWL_FIRM
and AGB_FIRM
's ARM7 requirements. This is due to the fact that much of the hardware used by both ARM7 and ARM9 is (evidently) not physically hooked up to ARM11. Thus, ARM11 cannot simply emulate ARM7.
ARM7 has the GBA BIOS implemented in hardware. The BIOS is completely identical to the original GBA BIOS. The system is booted silently by calling SWI 0x1
(a.k.a. RegisterRamReset
), followed by jumping to the code that does SWI 0x0
(a.k.a. SoftReset
) to finish booting. The boot splash is still in BIOS, however, and can be seen by calling or replacing one of the previous interrupts with SWI 0x26
(a.k.a. HardReset
).
Registers[edit]
ARM9 interfaces with the ARM7 through the following registers:
Type | Address | Name | Size (bytes) |
---|---|---|---|
u8
|
0x10018000
|
ARM7_CNT
|
1 |
Code | 0x10018080
|
ARM7_CODE
|
32 |
u16
|
0x10018100
|
ARM7_SAVE_MODE
|
2 |
u16
|
0x10018104
|
ARM7_SAVE_MEMORY_CNT
|
2 |
u16
|
0x10018108
|
ARM7_RTC_CNT
|
2 |
u32
|
0x10018110
|
ARM7_RTC_VAL_DATE
|
4 |
u32
|
0x10018114
|
ARM7_RTC_VAL_TIME
|
4 |
u32
|
0x10018118
|
ARM7_RTC_VAL_SETTINGS
|
4 |
u32
|
0x1001811C
|
ARM7_RTC_VAL_ADJUST
|
4 |
u32
|
0x10018120
|
ARM7_SAVE_FLASH_CHIP_ERASE_CYCLES
|
4 |
u32
|
0x10018124
|
ARM7_SAVE_FLASH_SECTOR_ERASE_CYCLES
|
4 |
u32
|
0x10018128
|
ARM7_SAVE_FLASH_PROGRAM_CYCLES
|
4 |
u32
|
0x1001812C
|
ARM7_SAVE_EEPROM_WRITE_CYCLES
|
4 |
ARM7_CNT[edit]
This seems to control the mode of the ARM7. 1 = TWL, 2 = GBA.
ARM7_CODE[edit]
This region is an arm7 bootrom overlay, over the vector table at address 0. Once the ARM7 is taken out of reset by TwlProcess9
, the reset vector will be jumped to, beginning execution. TwlProcess9
uses this to put ARM7 in a loop (TWL), and to set the POSTFLG
and branch to more copied code (GBA). Execution is started by writing 0x8001
to LGY_MODE after setting the mode via ARM7_CNT
. Later, this overlay is disabled by the ARM7 via the "biosprot" register (0x04000308).
Reading uninitialized data in this 32-byte region leads to both screens displaying solid green (exception), and the CPU locking up.
ARM7_SAVE_MODE[edit]
This tells the save storage emulation hardware which device type to emulate (64k EEPROM, a 512k Flash chip model, and SRAM are all that have been used officially; several other 512k Flash chip models, two 1 Mbit Flash chip models and 4k EEPROM are also supported). This comes directly from the ROM footer.
ARM7_SAVE_MEMORY_CNT[edit]
This register controls whether the GBA save memory region located at 0x08080000
is accessible to ARM9 or to the ARM7 (via the emulated save chip). When it's set to 0x0 ARM7 has access, while ARM9 has access when it's set to 0x1.
ARM7_RTC_CNT[edit]
This register controls the emulated RTC hardware and access to some of its registers.
To set or read the data from ARM7_RTC_VAL_SETTINGS or ARM7_RTC_VAL_ADJUST, first ARM7_RTC_CNT
's bit 15 is waited on. Next ARM7_RTC_CNT
is set to zero.
For a write: the two registers are written, a 1 is written to ARM7_RTC_CNT
, and it is waited on the same as before. Afterwards if bit 14 is not set in ARM7_RTC_CNT
, the value was set successfully. This also starts the emulated RTC.
For a read: a 2 is written to ARM7_RTC_CNT
, it's waited on again. Afterwards, if bit 14 is not set, the aforementioned registers can be read. Presumably the hardware can be re-enabled by writing a zero to ARM7_RTC_CNT
at this point, but AGB_FIRM
does not.
ARM7_RTC_VAL_DATE / ARM7_RTC_VAL_TIME[edit]
These registers are set to the current LgyP9 date+time before the other RTC-related registers are used. They contain the following structure, set up on the stack then both u32 registers are written one after the other:
s8 year_since_2000_bcd; s8 month_bcd; s8 day_bcd; s8 day_of_week; s8 hour_bcd; s8 minute_bcd; s8 second_bcd;
ARM7_RTC_VAL_SETTINGS[edit]
This register appears to contain the emulated RTC chip's configuration (accessible via the "control" register on real hardware), containing settings like 12/24-hour mode. Access is controlled by ARM7_RTC_CNT
(see above).
ARM7_RTC_VAL_ADJUST[edit]
This register appears to contain the emulated RTC chip's time difference, relative to ARM7_RTC_VAL_DATE
/ ARM7_RTC_VAL TIME
, in seconds. Access is controlled by ARM7_RTC_CNT
(see above).
ARM7_SAVE_FLASH_CHIP_ERASE_CYCLES[edit]
This register seems to configure the emulated Flash chip to take a specified amount of time to complete a chip erase operation (relative to the DS' ARM7/bus speed). Two variations exist in officially released games, one meant for 512k Flash chips and one for 1 Mbit Flash chips. It is copied from from rom footer + 0x10
.
ARM7_SAVE_FLASH_SECTOR_ERASE_CYCLES[edit]
This register seems to configure the emulated Flash chip to take a specified amount of time to complete a sector erase operation (relative to the DS' ARM7/bus speed). Two variations exist in officially released games, one meant for 512k Flash chips and one for 1 Mbit Flash chips. It is copied from from rom footer + 0x14
.
ARM7_SAVE_FLASH_PROGRAM_CYCLES[edit]
This register seems to configure the emulated Flash chip to take a specified amount of time to complete a program operation (relative to the DS' ARM7/bus speed). Two variations exist in officially released games, one meant for 512k Flash chips and one for 1 Mbit Flash chips. It is copied from from rom footer + 0x18
.
ARM7_SAVE_EEPROM_WRITE_CYCLES[edit]
This register seems to configure the emulated EEPROM chip to take a specified amount of time to complete a write operation (relative to the DS' ARM7/bus speed). Two variations exist in officially released games, one meant for 64k EEPROM chips and one for 4k EEPROM chips. It is copied from from rom footer + 0x1C
.
Memory map[edit]
The virtual memory mapping for the ARM7 is the same as for the other core. However, it has additional internal memory mapped to it. Interestingly enough, much of this memory seems to lie within ARM9's own internal memory.
0x08060000
→0x03800000
, ARM7 WRAM (64KiB)0x080B0000
→0x03000000
, GBA IWRAM (32KiB)0x08080000
→ EEPROM/SRAM/Flash 512k/Flash 1Mbit (the 2 512k banks are contiguous in memory). Access is controlled byARM7_SAVE_MEMORY_CNT
(see above).0x080C0000
holds a mirror which is used by LgyP9 on boot to read the SD savedata before the mode switch, the data is then copied.0x01FFC000
→0x01000000
, ARM9 ITCM under TWL (16KiB)