Hi Carl-Daniel,
On Sonntag, 13. Juli 2008, Carl-Daniel Hailfinger wrote:
On 13.07.2008 21:37, Juergen Beisert wrote:
On Sonntag, 13. Juli 2008, Uwe Hermann wrote:
On Fri, Jul 11, 2008 at 11:17:53PM +0200, Carl-Daniel Hailfinger wrote:
Does CAR work for the GX1?
Not yet, but it's possible to do. I think Juergen Beisert (CC'd) wrote something for GX1 in v3 a while ago (?) Juergen, do you still have that code and will it work for v3 (and even better, also for v2)? If so, please post it with a Signed-off-by so we can get it into svn.
The code still exists. But I have no idea how I should add it to v2. I do not know how CAR in v2 works.
Can you just post the code to the list? Then we can review it and commit.
Regards, Carl-Daniel
Its not adapted to v2 nor v3. Its only an example, how to do it for CPUs with these special cache test registers (like older i486 and the Geode GX1).
After running this program, you have (a very fast) RAM at physical address __car_data_dst up to (__car_data_dst + __car_size). These two symbols are generated by my linker script. I'm using this code in my current u-boot-v2 development for ia32.
Note: This code must run with *disabled* cache and this piece of RAM only exists and is useable, _until_you_enable_the_cache_! Note also: You should locate this CAR area in the regular SDRAM area, because when you enable the cache (after SDRAM controller initialisation), the cache unit will flush its content to the SDRAM. It will fail badly if at the same physical address is no real memory to write/flush to.
/** * This maps the cache with the help of the cache debug and test registers * * Mapping of the cache happens from __car_data_dst as startaddress * up to (__car_data_dst + __car_size) as endaddress * * __car_data_dst contains *target's* physical CAR start address of * the CAR area, __car_size the size of the whole CAR area (in bytes) */ .code32 .section ".flat_mode", "ax" .extern pre_c_stage .extern __car_data_dst .extern __car_size .globl cache_as_ram
cache_as_ram: movl %eax, %ebp /* Save the BIST value */
movl $__car_data_dst, %edi movl $__car_size, %ecx
next_cache_line: movl $0xdeadbeef, %eax
/* Fill up cache fill buffer (one cache line = 16 bytes) */ movl %ebx, %ebx movl %ebx, %tr5 /* entry 0 */ movl %eax, %tr3
addb $0x04, %bl movl %ebx, %tr5 /* entry 1 */ movl %eax, %tr3
addb $0x04, %bl movl %ebx, %tr5 /* entry 2 */ movl %eax, %tr3
addb $0x04, %bl movl %ebx, %tr5 /* entry 3 */ movl %eax, %tr3
/* map this line to a fixed address */ movl %edi, %eax andl $0xFFFFF000, %eax orb $0x04, %ah movl %eax, %tr4
/* select correct set and line now */
/* calculate cache line from physical address bit [11:4] */ movl %edi, %eax andl $0x00000FF0, %eax
/* calculate cache set from physical address bit [13:12] */ movl %edi, %ebx andl $0x00003000, %ebx shrl $0xA, %ebx
orl %ebx, %eax orb $0x01, %al /* write buffer command */
movl %eax, %tr5 /* do it */
/* loop until full cache is mapped */ addl $0x10, %edi subl $0x10, %ecx jnz next_cache_line
movl %ebp, %eax /* Restore the BIST value */
jmp pre_c_stage /* prepare to run C code */
/* * When the standard system RAM is up and running we can switch the cache into * its native mode. There is nothing special to do here, as the cache is * currently fully initialised. Each line has its dirty bit set, so regular * use of cache can start immediately. */ .globl disable_cache_as_ram
disable_cache_as_ram: movl %cr0, %eax andl $0x9fffffff,%eax movl %eax, %cr0 ret
Regards Juergen