GPU/External Registers

This page describes the address range used to configure the basic GPU functionality.

Map

User VA PA Length Name Comments
0x1EF00004 0x10400004 4 ?
0x1EF00010 0x10400010 16 Memory Fill1 "PSC0" GX command 2
0x1EF00020 0x10400020 16 Memory Fill2 "PSC1" GX command 2
0x1EF00030 0x10400030 4 ?
0x1EF00034 0x10400034 4 GPU Busy Bit31 = cmd-list busy, bit27 = PSC0 busy, bit26 = PSC1 busy.
0x1EF00050 0x10400050 4 ? Writes 0x22221200 on GPU init.
0x1EF00054 0x10400054 4 ? Writes 0xFF2 on GPU init.
0x1EF00400 0x10400400 0x100 Framebuffer Setup "PDC0" (top screen)
0x1EF00500 0x10400500 0x100 Framebuffer Setup "PDC1" (bottom)
0x1EF00C00 0x10400C00 ? Transfer Engine "DMA"
0x1EF01000 0x10401000 0x4 ? Writes 0 on GPU init.
0x1EF01080 0x10401080 0x4 ? Writes 0x12345678 on GPU init.
0x1EF010C0 0x104010C0 0x4 ? Writes 0xFFFFFFF0 on GPU init.
0x1EF010D0 0x104010D0 0x4 ? Writes 1 on GPU init.
0x1EF014?? 0x104014?? 0x14 "PPF" ?
0x1EF018E0 0x104018E0 0x14 Command List "P3D"

Memory Fill

User VA Description
0x1EF000X0 Buffer start physaddr >> 3
0x1EF000X4 Buffer end physaddr >> 3
0x1EF000X8 Fill value
0x1EF000XC Control. bit0: start/busy, bit1: finished, bit8-9: fill-width (0=16bit, 1=3=24bit, 2=32bit)

Memory fills are used to initialize buffers in memory with a given value, similar to memset. A memory fill is triggered by setting bit0 in the control register. Doing so aborts any running memory fills on that filling unit. Upon completion, the hardware unsets bit0 and sets bit1 and fires interrupt PSC0.

These registers are used by GX SetMemoryFill.

LCD Source Framebuffer Setup

Offset Length Name Comments
0x5C 4 Framebuffer width & height Lower 16 bits: width, upper 16 bits: height
0x68 4 Framebuffer A first address For top screen, this is the left eye 3D framebuffer.
0x6C 4 Framebuffer A second address For top screen, this is the left eye 3D framebuffer.
0x70 4 Framebuffer format Bit0-15: framebuffer format, bit16-31: unknown
0x78 4 Framebuffer select Bit0: which framebuffer to display, bit1-7: unknown
0x90 4 Framebuffer stride Distance in bytes between the start of two framebuffer rows (must be a multiple of 8).
0x94 4 Framebuffer B first address For top screen, this is the right eye 3D framebuffer. Unused for bottom screen.
0x98 4 Framebuffer B second address For top screen, this is the right eye 3D framebuffer. Unused for bottom screen.

Framebuffer format

Bit Description
2-0 Color format
3 ?
4 Unused?
5 Set when the main screen 3D right framebuffer address is set.
6 1 = main screen, 0 = sub screen. However if bit5 is set, this bit is cleared.
7 ?
9-8 Value 1 = unknown: get rid of rainbow strip on top of screen, 3 = unknown: black screen.
15-10 Unused?

GSP module only allows the LCD stereoscopy to be enabled when bit5=1 and bit6=0 here. When GSP module updates this register, GSP module will automatically disable the stereoscopy if those bits are not set for enabling stereoscopy.

Framebuffer color formats

Value Description
0 GL_RGBA8_OES
1 GL_RGB8_OES
2 GL_RGB565_OES
3 GL_RGB5_A1_OES
4 GL_RGBA4_OES

Color components are laid out in reverse byte order, with the most significant bits used first (i.e. non-24-bit pixels are stored as a little-endian values). For instance, a raw data stream of two GL_RGB565_OES pixels looks like GGGBBBBB RRRRRGGG GGGBBBBB RRRRRGGG.

Transfer Engine

Register address Description
0x1EF00C00 Input physical address>>3
0x1EF00C04 Output physical address>>3
0x1EF00C08 Output framebuffer dimensions, used with cmd3
0x1EF00C0C Input framebuffer dimensions, used with cmd3
0x1EF00C10 Flags, used with cmd3 and cmd4.
0x1EF00C14 GSP module writes value 0 here prior to writing to 0x1EF00C18, for cmd3.
0x1EF00C18 Setting bit0 starts the transfer. Upon completion, bit0 is unset and bit8 is set.
0x1EF00C20 Texture info? used with cmd4 ("Size" in GX command)
0x1EF00C24 Texture info? used with cmd4 ("Input dimensions?" in GX command)
0x1EF00C28 Texture info? used with cmd4 ("Output dimensions?" in GX command)

These registers are used by GX command 3 and 4. For cmd4, *0x1EF00C18 |= 1 is used instead of just writing value 1. The dimensions fields seem to use the same format as LCD register 0x1EF00X5C. The input framebuffer width for the main screen is normally 480.

0x1EF00C10

Bit Description
0 When set, the framebuffer data is flipped vertically.
1 When set, the input framebuffer is treated as linear and converted to tiled in the output, converts tiled->linear when unset.
2 This bit is set when the out-framebuf width/height is less than the input framebuf width/height, clear otherwise. Bit24 is normally clear when this bit is set.
3 When set, the input framebuffer data is copied as-is to the output framebuffer, without any kind of conversions. The data is truncated to the output size.
4 Not writable
5 Writable, but purpose unknown (usually zero)
7-6 Not writable
10-8 Input framebuffer color format, value0 and value1 are the same as the LCD Source Framebuffer Formats (usually zero)
11 Not writable
14-12 Output framebuffer color format
15 Not writable
16 Unknown, normally zero.
17-23 Not writable
24 Scale down the input image to its half width using a box filter.
25 Scale down the input image to its half height and half width using a box filter.
31-26 Not writable

Command List

Register address Description
0x1EF018E0 Buffer size in bytes >> 3
0x1EF018E8 Buffer physical address >> 3
0x1EF018F0 Setting bit0 to 1 enables processing GPU command execution. Upon completion, bit0 seems to be reset to 0.

These 3 registers are used by GX command 1. This is used for GPU commands.

Framebuffers

These LCD framebuffers normally contain the last rendered frames from the GPU. The framebuffers are drawn from left-to-right, instead of top-to-bottom.(Thus the beginning of the framebuffer is drawn starting at the left side of the screen)

Both of the 3D screen left/right framebuffers are displayed regardless of the 3D slider's state, however when the 3D slider is set to "off" the 3D effect is disabled. Normally when the 3D slider's state is set to "off" the left/right framebuffer addresses are set to the same physical address. When the 3D effect is disabled and the left/right framebuffers are set to separate addresses, the LCD seems to alternate between displaying the left/right framebuffer each frame.

Init Values from nngxInitialize for Top Screen

  • 0x1EF00400 = 0x1C2
  • 0x1EF00404 = 0xD1
  • 0x1EF00408 = 0x1C1
  • 0x1EF0040C = 0x1C1
  • 0x1EF00410 = 0
  • 0x1EF00414 = 0xCF
  • 0x1EF00418 = 0xD1
  • 0x1EF0041C = 0x1C501C1
  • 0x1EF00420 = 0x10000
  • 0x1EF00424 = 0x19D
  • 0x1EF00428 = 2
  • 0x1EF0042C = 0x1C2
  • 0x1EF00430 = 0x1C2
  • 0x1EF00434 = 0x1C2
  • 0x1EF00438 = 1
  • 0x1EF0043C = 2
  • 0x1EF00440 = 0x1960192
  • 0x1EF00444 = 0
  • 0x1EF00448 = 0
  • 0x1EF0045C = 0x19000F0
  • 0x1EF00460 = 0x1c100d1
  • 0x1EF00464 = 0x1920002
  • 0x1EF00470 = 0x80340
  • 0x1EF0049C = 0

More Init Values from nngxInitialize for Top Screen

  • 0x1EF00468 = 0x18300000, later changed by GSP module when updating state, framebuffer
  • 0x1EF0046C = 0x18300000, later changed by GSP module when updating state, framebuffer
  • 0x1EF00494 = 0x18300000
  • 0x1EF00498 = 0x18300000
  • 0x1EF00478 = 1, doesn't stay 1, read as 0
  • 0x1EF00474 = 0x10501