/* * Copyright (C) 2013 Imagination Technologies * Author: Paul Burton * * 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. */ #include #include #include #include #include #include #define GCR_CL_COHERENCE_OFS 0x2008 .section .text.cps-vec .balign 0x1000 .set noreorder LEAF(mips_cps_core_entry) /* * These first 8 bytes will be patched by cps_smp_setup to load the * base address of the CM GCRs into register v1. */ .quad 0 /* Check whether we're here due to an NMI */ mfc0 k0, CP0_STATUS and k0, k0, ST0_NMI beqz k0, not_nmi nop /* This is an NMI */ la k0, nmi_handler jr k0 nop not_nmi: /* Setup Cause */ li t0, CAUSEF_IV mtc0 t0, CP0_CAUSE /* Setup Status */ li t0, ST0_CU1 | ST0_CU0 mtc0 t0, CP0_STATUS /* * Clear the bits used to index the caches. Note that the architecture * dictates that writing to any of TagLo or TagHi selects 0 or 2 should * be valid for all MIPS32 CPUs, even those for which said writes are * unnecessary. */ mtc0 zero, CP0_TAGLO, 0 mtc0 zero, CP0_TAGHI, 0 mtc0 zero, CP0_TAGLO, 2 mtc0 zero, CP0_TAGHI, 2 ehb /* Primary cache configuration is indicated by Config1 */ mfc0 v0, CP0_CONFIG, 1 /* Detect I-cache line size */ _EXT t0, v0, MIPS_CONF1_IL_SHF, MIPS_CONF1_IL_SZ beqz t0, icache_done li t1, 2 sllv t0, t1, t0 /* Detect I-cache size */ _EXT t1, v0, MIPS_CONF1_IS_SHF, MIPS_CONF1_IS_SZ xori t2, t1, 0x7 beqz t2, 1f li t3, 32 addi t1, t1, 1 sllv t1, t3, t1 1: /* At this point t1 == I-cache sets per way */ _EXT t2, v0, MIPS_CONF1_IA_SHF, MIPS_CONF1_IA_SZ addi t2, t2, 1 mul t1, t1, t0 mul t1, t1, t2 li a0, KSEG0 add a1, a0, t1 1: cache Index_Store_Tag_I, 0(a0) add a0, a0, t0 bne a0, a1, 1b nop icache_done: /* Detect D-cache line size */ _EXT t0, v0, MIPS_CONF1_DL_SHF, MIPS_CONF1_DL_SZ beqz t0, dcache_done li t1, 2 sllv t0, t1, t0 /* Detect D-cache size */ _EXT t1, v0, MIPS_CONF1_DS_SHF, MIPS_CONF1_DS_SZ xori t2, t1, 0x7 beqz t2, 1f li t3, 32 addi t1, t1, 1 sllv t1, t3, t1 1: /* At this point t1 == D-cache sets per way */ _EXT t2, v0, MIPS_CONF1_DA_SHF, MIPS_CONF1_DA_SZ addi t2, t2, 1 mul t1, t1, t0 mul t1, t1, t2 li a0, KSEG0 addu a1, a0, t1 subu a1, a1, t0 1: cache Index_Store_Tag_D, 0(a0) bne a0, a1, 1b add a0, a0, t0 dcache_done: /* Set Kseg0 cacheable, coherent, write-back, write-allocate */ mfc0 t0, CP0_CONFIG ori t0, 0x7 xori t0, 0x2 mtc0 t0, CP0_CONFIG ehb /* Enter the coherent domain */ li t0, 0xff sw t0, GCR_CL_COHERENCE_OFS(v1) ehb /* Jump to kseg0 */ la t0, 1f jr t0 nop 1: /* We're up, cached & coherent */ /* * TODO: We should check the VPE number we intended to boot here, and * if non-zero we should start that VPE and stop this one. For * the moment this doesn't matter since CPUs are brought up * sequentially and in order, but once hotplug is implemented * this will need revisiting. */ /* Off we go! */ la t0, mips_cps_bootcfg lw t1, BOOTCFG_PC(t0) lw gp, BOOTCFG_GP(t0) lw sp, BOOTCFG_SP(t0) jr t1 nop END(mips_cps_core_entry) .org 0x200 LEAF(excep_tlbfill) b . nop END(excep_tlbfill) .org 0x280 LEAF(excep_xtlbfill) b . nop END(excep_xtlbfill) .org 0x300 LEAF(excep_cache) b . nop END(excep_cache) .org 0x380 LEAF(excep_genex) b . nop END(excep_genex) .org 0x400 LEAF(excep_intex) b . nop END(excep_intex) .org 0x480 LEAF(excep_ejtag) la k0, ejtag_debug_handler jr k0 nop END(excep_ejtag)