]> git.ipfire.org Git - thirdparty/grub.git/commitdiff
Enable caches on yeeloong
authorVladimir 'phcoder' Serbinenko <phcoder@gmail.com>
Thu, 11 Mar 2010 01:47:08 +0000 (02:47 +0100)
committerVladimir 'phcoder' Serbinenko <phcoder@gmail.com>
Thu, 11 Mar 2010 01:47:08 +0000 (02:47 +0100)
include/grub/mips/loongson.h [new file with mode: 0644]
kern/mips/yeeloong/fwstart.S

diff --git a/include/grub/mips/loongson.h b/include/grub/mips/loongson.h
new file mode 100644 (file)
index 0000000..9c1ba6d
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2010  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_LOONGSON_CPU_HEADER
+#define GRUB_LOONGSON_CPU_HEADER       1
+
+#define GRUB_CPU_LOONGSON_COP0_CACHE_CONFIG $16
+#define GRUB_CPU_LOONGSON_COP0_CACHE_CONFIG_ILINESIZE 0x10
+#define GRUB_CPU_LOONGSON_COP0_CACHE_CONFIG_DLINESIZE 0x8
+#define GRUB_CPU_LOONGSON_COP0_CACHE_DSIZE_SHIFT 6
+#define GRUB_CPU_LOONGSON_COP0_CACHE_ISIZE_SHIFT 9
+#define GRUB_CPU_LOONGSON_COP0_CACHE_SIZE_MASK  0x7
+#define GRUB_CPU_LOONGSON_COP0_CACHE_SIZE_OFFSET 12
+
+#define GRUB_CPU_LOONGSON_COP0_I_INDEX_INVALIDATE 0
+#define GRUB_CPU_LOONGSON_COP0_D_INDEX_TAG_STORE  9
+#define GRUB_CPU_LOONGSON_COP0_S_INDEX_TAG_STORE  11
+
+#define GRUB_CPU_LOONGSON_COP0_I_INDEX_BIT_OFFSET 5
+#define GRUB_CPU_LOONGSON_COP0_D_INDEX_BIT_OFFSET 5
+#define GRUB_CPU_LOONGSON_COP0_S_INDEX_BIT_OFFSET 5
+
+#define GRUB_CPU_LOONGSON_CACHE_ACCELERATED 7
+#define GRUB_CPU_LOONGSON_CACHE_UNCACHED 2
+#define GRUB_CPU_LOONGSON_CACHE_CACHED 3
+#define GRUB_CPU_LOONGSON_CACHE_TYPE_MASK 7
+#define GRUB_CPU_LOONGSON_CACHE_LINE_SIZE_LOG_SMALL 4
+#define GRUB_CPU_LOONGSON_CACHE_LINE_SIZE_LOG_BIG 5
+#define GRUB_CPU_LOONGSON_CACHE_LINE_SIZE_SMALL 16
+#define GRUB_CPU_LOONGSON_CACHE_LINE_SIZE_BIG 32
+
+#define GRUB_CPU_LOONGSON_I_CACHE_LOG_WAYS 2
+#define GRUB_CPU_LOONGSON_D_CACHE_LOG_WAYS 2
+#define GRUB_CPU_LOONGSON_S_CACHE_LOG_WAYS 2
+
+/* Fixme: determine dynamically.  */
+#define GRUB_CPU_LOONGSON_SECONDARY_CACHE_LOG_SIZE 19
+
+#define GRUB_CPU_LOONGSON_COP0_CACHE_TAGLO $28
+#define GRUB_CPU_LOONGSON_COP0_CACHE_TAGHI $29
+
+#endif
index 3dccb65fd143fe4b14c651dd91f2be0d6db0b91f..dc5dabc6c758c16ce370a064a06e33a71c36ab54 100644 (file)
@@ -19,6 +19,7 @@
 #include <grub/mips/yeeloong/serial.h>
 #include <grub/mips/yeeloong/pci.h>
 #include <grub/mips/yeeloong/boot.h>
+#include <grub/mips/loongson.h>
 #include <grub/pci.h>
 #include <grub/serial.h>
 #include <grub/cs5536.h>
@@ -392,6 +393,7 @@ epc:        .asciz "\n\rEPC: "
 badvaddr:      .asciz "\n\rBadVaddr: "
 newline:       .asciz "\n\r"
 return_msg:      .asciz "\n\rReturn address: "
+caches_enabled:        .asciz "Caches enabled\n\r"
 
        .p2align 3
 
@@ -535,6 +537,79 @@ continue:
        ori     $t1, $t1, 0x100
         sd     $t1, 0x0180($t0)
 
+       /* Enable cache.  */
+       mfc0    $t0, GRUB_CPU_LOONGSON_COP0_CACHE_CONFIG
+       addiu   $t1, $zero, ~GRUB_CPU_LOONGSON_CACHE_TYPE_MASK
+       and     $t0, $t1, $t1
+       /* Set line size to 32 bytes and disabled cache.  */
+       ori     $t0, $t0, (GRUB_CPU_LOONGSON_COP0_CACHE_CONFIG_ILINESIZE \
+                          | GRUB_CPU_LOONGSON_COP0_CACHE_CONFIG_DLINESIZE \
+                          | GRUB_CPU_LOONGSON_CACHE_ACCELERATED)
+       mtc0    $t0, GRUB_CPU_LOONGSON_COP0_CACHE_CONFIG
+
+       /* Invalidate all I-cache entries.  */
+       srl $t1, $t0, GRUB_CPU_LOONGSON_COP0_CACHE_ISIZE_SHIFT
+       andi $t1, $t1, GRUB_CPU_LOONGSON_COP0_CACHE_SIZE_MASK
+       ori $t2, $zero, (1 << (GRUB_CPU_LOONGSON_COP0_CACHE_SIZE_OFFSET \
+                              - GRUB_CPU_LOONGSON_CACHE_LINE_SIZE_LOG_BIG \
+                              - GRUB_CPU_LOONGSON_I_CACHE_LOG_WAYS))
+       sll $t1, $t2, $t1
+       lui $t2, 0x8000
+
+1:     
+       cache GRUB_CPU_LOONGSON_COP0_I_INDEX_INVALIDATE, 0($t2)
+       addiu $t1, $t1, -1
+       bne $t1, $zero, 1b
+        addiu $t2, $t2, (1 << GRUB_CPU_LOONGSON_COP0_I_INDEX_BIT_OFFSET)
+
+       /* Invalidate all D-cache entries.  */
+       srl $t1, $t0, GRUB_CPU_LOONGSON_COP0_CACHE_DSIZE_SHIFT
+       andi $t1, $t1, GRUB_CPU_LOONGSON_COP0_CACHE_SIZE_MASK
+       ori $t2, $zero, (1 << (GRUB_CPU_LOONGSON_COP0_CACHE_SIZE_OFFSET \
+                              - GRUB_CPU_LOONGSON_CACHE_LINE_SIZE_LOG_BIG \
+                              - GRUB_CPU_LOONGSON_D_CACHE_LOG_WAYS))
+       sll $t1, $t2, $t1
+       lui $t2, 0x8000
+       mtc0 $zero, GRUB_CPU_LOONGSON_COP0_CACHE_TAGLO
+       mtc0 $zero, GRUB_CPU_LOONGSON_COP0_CACHE_TAGHI
+1:
+       /* All four ways.  */
+       cache GRUB_CPU_LOONGSON_COP0_D_INDEX_TAG_STORE, 0($t2)
+       cache GRUB_CPU_LOONGSON_COP0_D_INDEX_TAG_STORE, 1($t2)
+       cache GRUB_CPU_LOONGSON_COP0_D_INDEX_TAG_STORE, 2($t2)
+       cache GRUB_CPU_LOONGSON_COP0_D_INDEX_TAG_STORE, 3($t2)
+       addiu $t1, $t1, -1
+       bne $t1, $zero, 1b
+        addiu $t2, $t2, (1 << GRUB_CPU_LOONGSON_COP0_D_INDEX_BIT_OFFSET)
+
+       /* Invalidate all S-cache entries.  */
+       ori $t1, $zero, (1 << (GRUB_CPU_LOONGSON_SECONDARY_CACHE_LOG_SIZE \
+                              - GRUB_CPU_LOONGSON_CACHE_LINE_SIZE_LOG_BIG \
+                              - GRUB_CPU_LOONGSON_S_CACHE_LOG_WAYS))
+       lui $t2, 0x8000
+       mtc0 $zero, GRUB_CPU_LOONGSON_COP0_CACHE_TAGLO
+       mtc0 $zero, GRUB_CPU_LOONGSON_COP0_CACHE_TAGHI
+1:
+       /* All four ways.  */
+       cache GRUB_CPU_LOONGSON_COP0_S_INDEX_TAG_STORE, 0($t2)
+       cache GRUB_CPU_LOONGSON_COP0_S_INDEX_TAG_STORE, 1($t2)
+       cache GRUB_CPU_LOONGSON_COP0_S_INDEX_TAG_STORE, 2($t2)
+       cache GRUB_CPU_LOONGSON_COP0_S_INDEX_TAG_STORE, 3($t2)
+       addiu $t1, $t1, -1
+       bne $t1, $zero, 1b
+        addiu $t2, $t2, (1 << GRUB_CPU_LOONGSON_COP0_D_INDEX_BIT_OFFSET)
+       
+       /* Finally enable cache.  */
+       mfc0    $t0, GRUB_CPU_LOONGSON_COP0_CACHE_CONFIG
+       addiu   $t1, $zero, ~GRUB_CPU_LOONGSON_CACHE_TYPE_MASK
+       and     $t0, $t1, $t1
+       ori     $t0, $t0, GRUB_CPU_LOONGSON_CACHE_CACHED
+       mtc0    $t0, GRUB_CPU_LOONGSON_COP0_CACHE_CONFIG
+
+       lui $a0, %hi(caches_enabled)
+       bal message
+         addiu $a0, $a0, %lo(caches_enabled)
+       
        addiu $a0, $zero, -1
        addiu $a1, $zero, -1
        addiu $a2, $zero, -1