[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