1/* 2 * Copyright (C) 2013 Imagination Technologies 3 * Author: Paul Burton <paul.burton@imgtec.com> 4 * 5 * This program is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License as published by the 7 * Free Software Foundation; either version 2 of the License, or (at your 8 * option) any later version. 9 */ 10 11#include <asm/addrspace.h> 12#include <asm/asm.h> 13#include <asm/asm-offsets.h> 14#include <asm/asmmacro.h> 15#include <asm/cacheops.h> 16#include <asm/mipsregs.h> 17 18#define GCR_CL_COHERENCE_OFS 0x2008 19 20.section .text.cps-vec 21.balign 0x1000 22.set noreorder 23 24LEAF(mips_cps_core_entry) 25 /* 26 * These first 8 bytes will be patched by cps_smp_setup to load the 27 * base address of the CM GCRs into register v1. 28 */ 29 .quad 0 30 31 /* Check whether we're here due to an NMI */ 32 mfc0 k0, CP0_STATUS 33 and k0, k0, ST0_NMI 34 beqz k0, not_nmi 35 nop 36 37 /* This is an NMI */ 38 la k0, nmi_handler 39 jr k0 40 nop 41 42not_nmi: 43 /* Setup Cause */ 44 li t0, CAUSEF_IV 45 mtc0 t0, CP0_CAUSE 46 47 /* Setup Status */ 48 li t0, ST0_CU1 | ST0_CU0 49 mtc0 t0, CP0_STATUS 50 51 /* 52 * Clear the bits used to index the caches. Note that the architecture 53 * dictates that writing to any of TagLo or TagHi selects 0 or 2 should 54 * be valid for all MIPS32 CPUs, even those for which said writes are 55 * unnecessary. 56 */ 57 mtc0 zero, CP0_TAGLO, 0 58 mtc0 zero, CP0_TAGHI, 0 59 mtc0 zero, CP0_TAGLO, 2 60 mtc0 zero, CP0_TAGHI, 2 61 ehb 62 63 /* Primary cache configuration is indicated by Config1 */ 64 mfc0 v0, CP0_CONFIG, 1 65 66 /* Detect I-cache line size */ 67 _EXT t0, v0, MIPS_CONF1_IL_SHF, MIPS_CONF1_IL_SZ 68 beqz t0, icache_done 69 li t1, 2 70 sllv t0, t1, t0 71 72 /* Detect I-cache size */ 73 _EXT t1, v0, MIPS_CONF1_IS_SHF, MIPS_CONF1_IS_SZ 74 xori t2, t1, 0x7 75 beqz t2, 1f 76 li t3, 32 77 addi t1, t1, 1 78 sllv t1, t3, t1 791: /* At this point t1 == I-cache sets per way */ 80 _EXT t2, v0, MIPS_CONF1_IA_SHF, MIPS_CONF1_IA_SZ 81 addi t2, t2, 1 82 mul t1, t1, t0 83 mul t1, t1, t2 84 85 li a0, KSEG0 86 add a1, a0, t1 871: cache Index_Store_Tag_I, 0(a0) 88 add a0, a0, t0 89 bne a0, a1, 1b 90 nop 91icache_done: 92 93 /* Detect D-cache line size */ 94 _EXT t0, v0, MIPS_CONF1_DL_SHF, MIPS_CONF1_DL_SZ 95 beqz t0, dcache_done 96 li t1, 2 97 sllv t0, t1, t0 98 99 /* Detect D-cache size */ 100 _EXT t1, v0, MIPS_CONF1_DS_SHF, MIPS_CONF1_DS_SZ 101 xori t2, t1, 0x7 102 beqz t2, 1f 103 li t3, 32 104 addi t1, t1, 1 105 sllv t1, t3, t1 1061: /* At this point t1 == D-cache sets per way */ 107 _EXT t2, v0, MIPS_CONF1_DA_SHF, MIPS_CONF1_DA_SZ 108 addi t2, t2, 1 109 mul t1, t1, t0 110 mul t1, t1, t2 111 112 li a0, KSEG0 113 addu a1, a0, t1 114 subu a1, a1, t0 1151: cache Index_Store_Tag_D, 0(a0) 116 bne a0, a1, 1b 117 add a0, a0, t0 118dcache_done: 119 120 /* Set Kseg0 cacheable, coherent, write-back, write-allocate */ 121 mfc0 t0, CP0_CONFIG 122 ori t0, 0x7 123 xori t0, 0x2 124 mtc0 t0, CP0_CONFIG 125 ehb 126 127 /* Enter the coherent domain */ 128 li t0, 0xff 129 sw t0, GCR_CL_COHERENCE_OFS(v1) 130 ehb 131 132 /* Jump to kseg0 */ 133 la t0, 1f 134 jr t0 135 nop 136 1371: /* We're up, cached & coherent */ 138 139 /* 140 * TODO: We should check the VPE number we intended to boot here, and 141 * if non-zero we should start that VPE and stop this one. For 142 * the moment this doesn't matter since CPUs are brought up 143 * sequentially and in order, but once hotplug is implemented 144 * this will need revisiting. 145 */ 146 147 /* Off we go! */ 148 la t0, mips_cps_bootcfg 149 lw t1, BOOTCFG_PC(t0) 150 lw gp, BOOTCFG_GP(t0) 151 lw sp, BOOTCFG_SP(t0) 152 jr t1 153 nop 154 END(mips_cps_core_entry) 155 156.org 0x200 157LEAF(excep_tlbfill) 158 b . 159 nop 160 END(excep_tlbfill) 161 162.org 0x280 163LEAF(excep_xtlbfill) 164 b . 165 nop 166 END(excep_xtlbfill) 167 168.org 0x300 169LEAF(excep_cache) 170 b . 171 nop 172 END(excep_cache) 173 174.org 0x380 175LEAF(excep_genex) 176 b . 177 nop 178 END(excep_genex) 179 180.org 0x400 181LEAF(excep_intex) 182 b . 183 nop 184 END(excep_intex) 185 186.org 0x480 187LEAF(excep_ejtag) 188 la k0, ejtag_debug_handler 189 jr k0 190 nop 191 END(excep_ejtag) 192