[LinuxBIOS] Setup CAR on Geode GX1 processor
Juergen Beisert
juergen127 at kreuzholzen.de
Sun May 27 19:19:18 CEST 2007
Hi,
find below my CAR implementation for the Geode GX1 processor. Tested on my
Geode GX1 system. Comments are welcome.
Juergen
/*
* Copyright (C) 2007 Juergen Beisert <juergen at kreuzholzen.de>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
/**
* This function pins the cache to a fixed address, to be used as an SRAM
* until system memory is available. It will be done with the help of the
* cache debug and test registers tr3, tr4 and tr5
*
* Your hardware must fulfil these qualifications:
* - support of the tr3, tr4 and tr5 registers
* - size of one cache line must be 16 bytes
* - your CAR area must be pinned to an address space where it
* also would work in a regular way (do not pin it to an I/O space)
*
* Mapping of the cache happens from _sstage0_1 as startaddress up to
* (_sstage0_1 + _car_size) as endaddress
*
* Note: This function uses some symbols created by the linker withing the
* linker script file. This ensures future compatibility and keeps all layout
* configuring into the linker script file.
*
* _sstage0_1:
* contains the physical start address of the CAR area
* _car_size:
* size of the whole CAR area (in bytes) -> means cache size
*/
.code32
.section ".bright_side", "ax"
.extern pre_c_stage
.extern _sstage0_1
.extern _car_size
.globl CacheAsRam
CacheAsRam:
/* Save the BIST value */
movl %eax, %ebp
movl $_sstage0_1, %edi
movl $_car_size, %ecx
next_cache_line:
movl $0xdeadbeef, %eax /* value for each byte in the CAR */
/* Fill up cache fill buffer (one cache line = 16 bytes) */
xorl %ebx, %ebx /* entry 0 */
movl %ebx, %tr5
movl %eax, %tr3 /* value for entry 0 */
addl $0x04, %ebx /* entry 1 (at offset 4) */
movl %ebx, %tr5
movl %eax, %tr3 /* value for entry 1 */
addl $0x04, %ebx /* entry 2 (at offset 8) */
movl %ebx, %tr5
movl %eax, %tr3 /* value for entry 2 */
addl $0x04, %ebx /* entry 3 (at offset 12) */
movl %ebx, %tr5
movl %eax, %tr3 /* value for entry 3 */
/* pin this cache line to a fixed address */
movl %edi, %eax
andl $0xFFFFF000, %eax /* upper 20 bit of the physical address */
orl $0x00000400, %eax /* mark this entry valid */
movl %eax, %tr4
/* setup correct cache set and cache line */
movl %edi, %eax
andl $0x00000FF0, %eax /* calculate cache line from physical address bit [11:4] */
movl %edi, %ebx
andl $0x00003000, %ebx /* calculate cache set from physical address bit [13:12] */
shrl $0xA, %ebx
orl %ebx, %eax
orl $0x01, %eax /* add write buffer command */
movl %eax, %tr5 /* do it */
/* loop until full cache is mapped */
addl $0x10, %edi
subl $0x10, %ecx
jnz next_cache_line
/* Restore the BIST value to %eax */
movl %ebp, %eax
/* prepare to run C code */
jmp pre_c_stage
More information about the coreboot
mailing list