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 <[EMAIL PROTECTED]>
 *
 * 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

-- 
linuxbios mailing list
[email protected]
http://www.linuxbios.org/mailman/listinfo/linuxbios

Reply via email to