-
-
Notifications
You must be signed in to change notification settings - Fork 1
ARM940T
The GP2X contains a second CPU, an ARM940T. This is very similar to the main ARM940T core, but with 4k caches instead of 16k, and a PU instead of full MMU. In gp2x-examples, you'll find a secondcpu
example which demonstrates the use of the second CPU (and an appropriate project layout / Makefile
for building an o2x).
As the ARM920T and ARM940T sit on the same address bus, they have visibility of all the same memory and peripherals. However, the address space of the ARM940T is configured to start at a 16M boundary, which means 0x0 will be at a different location in physical memory on the ARM940T. This means you need to decide how to split up the 64M RAM when using the ARM940T depending on how much RAM it needs to access - its address space can start at 0x1000000
(16M), 0x2000000
(32M) or 0x3000000
(48M) which allows it access to 48M, 32M or 16M of RAM respectively.
The ARM920T can always see all memory, even if it is used by the ARM940T.
The two CPUs run entirely independently of each other, but sit on the same bus. One will be blocked if the other is accessing RAM at the same time, so you'll get the best performance if your code/data fits within their caches. This does not apply if one CPU is trying to access RAM, and the other is accessing an MMSP2 peripheral at the same time, which includes the 32 registers intended for data interchange (exposed in orcus as arm920data
and arm940data
) - make use of them if you're passing small data back and forth, or implementing barriers/mutexes/semaphores etc!
Since the start of the physical address space for each CPU is different (0x0 for the ARM920T, configurable for the ARM940T), a pointer on one won't refer to the same location on the other. Orcus provides the functions exportPointer
and importPointer
to assist with this. You don't need to use both in tandem, as exportPointer
returns an address from a pointer which will be visible from the other CPU (with the caveat that if you use this on a pointer which refers to an area which is only visible from the ARM920T it won't be visible on the ARM940T whatever you do). Similarly, importPointer
takes an address from the perspective of the other CPU and translates it into a pointer which can be used on whichever CPU you call it from.
With this in mind, shared memory regions are probably best allocated on the ARM940T, to ensure they are visible from both.
Also, MMSP2 peripherals always take the physical address, so if calling Orcus functions which pass addresses to the hardware from the ARM940T, you'll need to export the pointers before passing them into the function. The secondcpu
example demonstrates this with the framebuffer, but it is equally applicable to DMA, audio, 2D accelerator etc.