Chipset Name

Radeon 200M (RS480)

PCI Express card, using 128M of sideport memory. (No)


I've gotten the IGPGART programmed and working using the info from the mmio-traces I took, code in my drm tree. However the 3D driver causes that card to lockup on initial access which isn't too good, but we can get CP acceleration now at least.. - airlied

The card appears to have a PCI GART but attempts to use this have failed on my system - airlied. I've attempted to move the CP into the last 8MBs of the pre-allocated framebuffer and move all the buffer mappings in there as well. This seemed to work for getting CP acceleration for the 2D driver. However attempts to make the 3D driver run failed miserably, it may be a simple problem with the buffer mappings for the r300 memory manager code, but I think it is probably a bit deeper, accessing the framebuffer while the CP is running has sometimes been known to be flaky on other radeons. I'm trying to access it via main RAM so it should work, but doesn't... - airlied

I've ran mmio-trace on the fglrx kernel module and gotten a bunch of indirect register access at 0x168, 0x16c, the 0x2c write looked like an address, and there looks to be a GART table at that address, so perhaps with AGP_BASE + MC_AGP_LOCATION programmed, it will use this GART table. It writes some other registers in this indirect area as well... so that needs some work... I've annotated some of the cpu parsed log at - airlied 19/02/07

In the current git tree, if DRM is enabled, the X server will hang upon startup. This is because it is waiting for the CP to initialize. The driver submits some commands, and the X server loops infinitely waiting for the CP to become idle. This is probably a bug.. the Xserver should probably wait some reasonable amount of time and then exit (rather than infinitely consuming a whole bunch of CPU.)

In my local tree, if I set MC_AGP_LOCATION to match that of fglrx driver & force PCIE express mode, the X server at least comes up. There is no stipple and the xserver hangs after moving the cursor around.

Open Issues

The memory map is different between the 8.23.5 fglrx driver and the Xorg driver.

I don't know if this is a problem.


[34] 0  0       0xc01203b0 - 0xc01203bb (0xc) IS[B]
[35] 0  0       0xc01203c0 - 0xc01203df (0x20) IS[B]

Opensource driver:

[33] 0  0       0x000003b0 - 0x000003bb (0xc) IS[B]
[34] 0  0       0x000003c0 - 0x000003df (0x20) IS[B]

Look how the addresses are different.

This should provide me more info about what these mean:

The stipple pattern never appears on the screen.

When DRI is enabled, the CP does not appear to be working. The indirect buffer is never executed.. Infact, I don't even think that the ring buffer is working properly. (Because the CP_IB_BASE is set to 0x00000000)

The CP configuration for the fglrx 8.32.5 driver is as follows:

----------------- CP registers ------------------

and the values for my current hacked radeon drivers are:

----------------- CP registers ------------------

Here are some interesting differences:

  • The AGP_BASE for the fglrx is set to 0x58000000 (same as the CP_RB_BASE). For the radeon driver, the AGP_BASE is set to 0x00000000.
  • The CP_RB_RPTR_ADDR is set to 0x00000000 for fglrx, and to 0x3471e000 for the radeon driver. Maybe the 0x00000 indicates some magic offset where the ring buffer should be stored.
  • The CP read and write pointers have advanced for the fglrx, so the CP is working for the fglrx.
  • For the radeon driver, look at how the RADEON_CP_IB_BASE is 0, so the CP (I think) never received the command to execute an indirect buffer.

After a few second of mouse movement, the box hangs.

  • I suspect that this is related to the improper command processor setup.


I don't know how the GART is setup for this card. None of the RADEON_PCIE registers are called in the trace of 8.32.5.

All attemps to dump this areas when fglrx is running return 0.

Something funny is going on..

UPDATE: I looks like Dave got a step further in understanding this. Using kmmio to trap the different accesses going on in kernel space, it appears that the 0x168 and 0x16C registers are indirect registers for configuring the memory controller.

Also, the accesses to 0x168/0x16C seem to have the following pattern:

  • Write to 0x168 (setup the index) (Where 0x100 indicates a write..)
  • Read/Write to/from 0x16C
  • Write 7f to 0x168 (Maybe a commit or something?)

I turned on PC recording in kmmio. It reveals some interesting things about what those indirect memory accesses are doing. First, all of the calls to the 168/16C registers are in: MCIL_ModifyRegister (So it looks like this is the Memory Controller that it is accessing.)

Next, I recorded the address of the function which called MCIL_ModifyRegister:

  read[18] -> 0x00001000 _ZN9GartRS48023InitializeGartRegistersEv
write[118] <- 0x00001000 _ZN9GartRS48023InitializeGartRegistersEv
write[138] <- 0x00000005 _ZN9GartRS48023InitializeGartRegistersEv
  read[2b] -> 0x00000000 _ZN9GartRS48023InitializeGartRegistersEv
write[12b] <- 0x42040800 _ZN9GartRS48023InitializeGartRegistersEv
write[12c] <- 0x33b00000 _ZN9GartRS48023InitializeGartRegistersEv
  read[39] -> 0x01400000 _ZN9GartRS48023InitializeGartRegistersEv
write[139] <- 0x01400000 _ZN9GartRS48023InitializeGartRegistersEv

  read[38] -> 0x00000005 _ZN9GartRS48010EnableGartEv
write[138] <- 0x00000005 _ZN9GartRS48010EnableGartEv

  read[2e] -> 0x00000000 _ZN9GartRS48012flushGartTLBEv
write[12e] <- 0x00000001 _ZN9GartRS48012flushGartTLBEv
  read[2e] -> 0x00000000 _ZN9GartRS48012flushGartTLBEv
write[12e] <- 0x00000000 _ZN9GartRS48012flushGartTLBEv

  read[2e] -> 0x00000000 _ZN9GartRS48012flushGartTLBEv
write[12e] <- 0x00000001 _ZN9GartRS48012flushGartTLBEv
  read[2e] -> 0x00000000 _ZN9GartRS48012flushGartTLBEv
write[12e] <- 0x00000000 _ZN9GartRS48012flushGartTLBEv

So, some interesting things come out of this: I think that:

  • 38/138 turns on the GART. (Write 0x5)
  • 2e/12e flushs the Gart TLB (Write 0x1 and then 0x0)
  • 2c/12c The address of the GART table (Write the physical address of the GART table)
  • 2b/12b (?) (Write 0x42040800)
  • 18/118 (?) (Read and then write 0x00001000)
  • 39/139 (?) (Read and then write 0x01400000) Comment by Slice: "Chips R200-RV280 use reg 1d8 for address of PCI Gart table Chips R300-RV420 use res ab0 - Lo 32 bits, ab4 - Hi 32 bits of Gart table address reg 1d0 has bit 0 for PCI_GART_ENABLE in both cases"

HW Config

Radeon 200M (RS480) PCI Express 128 M sideport memory (UMA/system memory usage disabled.)

01:05.0 VGA compatible controller: ATI Technologies Inc ATI Radeon XPRESS 200M 5955 (PCIE) (prog-if 00 [VGA])
        Subsystem: Hewlett-Packard Company Unknown device 30a4
        Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B-
        Status: Cap+ 66MHz+ UDF- FastB2B+ ParErr- DEVSEL=medium >TAbort- <TAbort- <MAbort- >SERR- <PERR-
        Latency: 66 (2000ns min), Cache Line Size 08
        Interrupt: pin A routed to IRQ 7
        Region 0: Memory at c0000000 (32-bit, prefetchable) [size=256M]
        Region 1: I/O ports at 9000 [size=256]
        Region 2: Memory at b0100000 (32-bit, non-prefetchable) [size=64K]
        [virtual] Expansion ROM at b0120000 [disabled] [size=128K]
        Capabilities: [50] Power Management version 2
                Flags: PMEClk- DSI- D1+ D2+ AuxCurrent=0mA PME(D0-,D1-,D2-,D3hot-,D3cold-)
                Status: D0 PME-Enable- DSel=0 DScale=0 PME-

NOTE: The firegl 8.32.5 driver works with this card ONLY if I use 128M of sideport. (No UMA) NOTE2: The 8.24.5 fglrx driver works if I have 128M UMA + 128M of sideport.



(Coming soon)


Some of these are of the Radeon200, but they basically apply:


ATI's 200M page:

White paper about hypermemory:

Another man's OpenGL problems with the 200M under windows:

Handy Facts for Radeon Reverse engineers

  • It seems that the commands issued to the CP are just register,value pairs... You could issue these directly using MMIOs, but when you hand it to the CP, it will do the work for you. (If someone know better, please tell me..)
  • The Radeon Xserver uses DRI to draw the stipple pattern, so if you see it on the screen, the CP is at least partially working..
  • Here's a pretty good explanation about how the radeon deals with memory (bus view vs. card view):

Tracing MMIOs

One way to figure out how the driver interacts with the card is either to:

Dump the registers

This contains a link to a generic MMIO register dumper: (In particular, an (untried) windows version is at:

Radeon Dump:

RADEON tool:;a=summary

Trace the register accesses

Trace userspace MMIOs:

Trace kernelspace MMIOs: git://

Decoding accesses

Here's some code to convert register names/values to human readable text:

I'm currently working on a config file for the radeon_RS480, but I imagine much of the R300 family is similar.

Radeon Registers

NOTE: It is unclear what all of the registers do, so there seems to be a smattering of different places which define this.


Radeon Xorg Driver: (FIXME)

Mplayer's list: