1*54fd6939SJiyong Park/* 2*54fd6939SJiyong Park * Copyright (c) 2020, Arm Limited. All rights reserved. 3*54fd6939SJiyong Park * 4*54fd6939SJiyong Park * SPDX-License-Identifier: BSD-3-Clause 5*54fd6939SJiyong Park */ 6*54fd6939SJiyong Park 7*54fd6939SJiyong Park#include <arch.h> 8*54fd6939SJiyong Park#include <asm_macros.S> 9*54fd6939SJiyong Park#include <context.h> 10*54fd6939SJiyong Park#include <cpu_macros.S> 11*54fd6939SJiyong Park#include <cpuamu.h> 12*54fd6939SJiyong Park#include <rainier.h> 13*54fd6939SJiyong Park 14*54fd6939SJiyong Park/* Hardware handled coherency */ 15*54fd6939SJiyong Park#if HW_ASSISTED_COHERENCY == 0 16*54fd6939SJiyong Park#error "Rainier CPU must be compiled with HW_ASSISTED_COHERENCY enabled" 17*54fd6939SJiyong Park#endif 18*54fd6939SJiyong Park 19*54fd6939SJiyong Park/* 64-bit only core */ 20*54fd6939SJiyong Park#if CTX_INCLUDE_AARCH32_REGS == 1 21*54fd6939SJiyong Park#error "Rainier CPU supports only AArch64. Compile with CTX_INCLUDE_AARCH32_REGS=0" 22*54fd6939SJiyong Park#endif 23*54fd6939SJiyong Park 24*54fd6939SJiyong Park/* -------------------------------------------------- 25*54fd6939SJiyong Park * Disable speculative loads if Rainier supports 26*54fd6939SJiyong Park * SSBS. 27*54fd6939SJiyong Park * 28*54fd6939SJiyong Park * Shall clobber: x0. 29*54fd6939SJiyong Park * -------------------------------------------------- 30*54fd6939SJiyong Park */ 31*54fd6939SJiyong Parkfunc rainier_disable_speculative_loads 32*54fd6939SJiyong Park /* Check if the PE implements SSBS */ 33*54fd6939SJiyong Park mrs x0, id_aa64pfr1_el1 34*54fd6939SJiyong Park tst x0, #(ID_AA64PFR1_EL1_SSBS_MASK << ID_AA64PFR1_EL1_SSBS_SHIFT) 35*54fd6939SJiyong Park b.eq 1f 36*54fd6939SJiyong Park 37*54fd6939SJiyong Park /* Disable speculative loads */ 38*54fd6939SJiyong Park msr SSBS, xzr 39*54fd6939SJiyong Park 40*54fd6939SJiyong Park1: 41*54fd6939SJiyong Park ret 42*54fd6939SJiyong Parkendfunc rainier_disable_speculative_loads 43*54fd6939SJiyong Park 44*54fd6939SJiyong Parkfunc rainier_reset_func 45*54fd6939SJiyong Park mov x19, x30 46*54fd6939SJiyong Park 47*54fd6939SJiyong Park bl rainier_disable_speculative_loads 48*54fd6939SJiyong Park 49*54fd6939SJiyong Park /* Forces all cacheable atomic instructions to be near */ 50*54fd6939SJiyong Park mrs x0, RAINIER_CPUACTLR2_EL1 51*54fd6939SJiyong Park orr x0, x0, #RAINIER_CPUACTLR2_EL1_BIT_2 52*54fd6939SJiyong Park msr RAINIER_CPUACTLR2_EL1, x0 53*54fd6939SJiyong Park isb 54*54fd6939SJiyong Park 55*54fd6939SJiyong Park bl cpu_get_rev_var 56*54fd6939SJiyong Park mov x18, x0 57*54fd6939SJiyong Park 58*54fd6939SJiyong Park#if ENABLE_AMU 59*54fd6939SJiyong Park /* Make sure accesses from EL0/EL1 and EL2 are not trapped to EL3 */ 60*54fd6939SJiyong Park mrs x0, actlr_el3 61*54fd6939SJiyong Park orr x0, x0, #RAINIER_ACTLR_AMEN_BIT 62*54fd6939SJiyong Park msr actlr_el3, x0 63*54fd6939SJiyong Park 64*54fd6939SJiyong Park /* Make sure accesses from EL0/EL1 are not trapped to EL2 */ 65*54fd6939SJiyong Park mrs x0, actlr_el2 66*54fd6939SJiyong Park orr x0, x0, #RAINIER_ACTLR_AMEN_BIT 67*54fd6939SJiyong Park msr actlr_el2, x0 68*54fd6939SJiyong Park 69*54fd6939SJiyong Park /* Enable group0 counters */ 70*54fd6939SJiyong Park mov x0, #RAINIER_AMU_GROUP0_MASK 71*54fd6939SJiyong Park msr CPUAMCNTENSET_EL0, x0 72*54fd6939SJiyong Park#endif 73*54fd6939SJiyong Park 74*54fd6939SJiyong Park isb 75*54fd6939SJiyong Park ret x19 76*54fd6939SJiyong Parkendfunc rainier_reset_func 77*54fd6939SJiyong Park 78*54fd6939SJiyong Park /* --------------------------------------------- 79*54fd6939SJiyong Park * HW will do the cache maintenance while powering down 80*54fd6939SJiyong Park * --------------------------------------------- 81*54fd6939SJiyong Park */ 82*54fd6939SJiyong Parkfunc rainier_core_pwr_dwn 83*54fd6939SJiyong Park /* --------------------------------------------- 84*54fd6939SJiyong Park * Enable CPU power down bit in power control register 85*54fd6939SJiyong Park * --------------------------------------------- 86*54fd6939SJiyong Park */ 87*54fd6939SJiyong Park mrs x0, RAINIER_CPUPWRCTLR_EL1 88*54fd6939SJiyong Park orr x0, x0, #RAINIER_CORE_PWRDN_EN_MASK 89*54fd6939SJiyong Park msr RAINIER_CPUPWRCTLR_EL1, x0 90*54fd6939SJiyong Park isb 91*54fd6939SJiyong Park ret 92*54fd6939SJiyong Parkendfunc rainier_core_pwr_dwn 93*54fd6939SJiyong Park 94*54fd6939SJiyong Park#if REPORT_ERRATA 95*54fd6939SJiyong Park/* 96*54fd6939SJiyong Park * Errata printing function for Rainier. Must follow AAPCS. 97*54fd6939SJiyong Park */ 98*54fd6939SJiyong Parkfunc rainier_errata_report 99*54fd6939SJiyong Park stp x8, x30, [sp, #-16]! 100*54fd6939SJiyong Park 101*54fd6939SJiyong Park bl cpu_get_rev_var 102*54fd6939SJiyong Park mov x8, x0 103*54fd6939SJiyong Park 104*54fd6939SJiyong Park ldp x8, x30, [sp], #16 105*54fd6939SJiyong Park ret 106*54fd6939SJiyong Parkendfunc rainier_errata_report 107*54fd6939SJiyong Park#endif 108*54fd6939SJiyong Park 109*54fd6939SJiyong Park /* --------------------------------------------- 110*54fd6939SJiyong Park * This function provides Rainier specific 111*54fd6939SJiyong Park * register information for crash reporting. 112*54fd6939SJiyong Park * It needs to return with x6 pointing to 113*54fd6939SJiyong Park * a list of register names in ascii and 114*54fd6939SJiyong Park * x8 - x15 having values of registers to be 115*54fd6939SJiyong Park * reported. 116*54fd6939SJiyong Park * --------------------------------------------- 117*54fd6939SJiyong Park */ 118*54fd6939SJiyong Park.section .rodata.rainier_regs, "aS" 119*54fd6939SJiyong Parkrainier_regs: /* The ascii list of register names to be reported */ 120*54fd6939SJiyong Park .asciz "cpuectlr_el1", "" 121*54fd6939SJiyong Park 122*54fd6939SJiyong Parkfunc rainier_cpu_reg_dump 123*54fd6939SJiyong Park adr x6, rainier_regs 124*54fd6939SJiyong Park mrs x8, RAINIER_CPUECTLR_EL1 125*54fd6939SJiyong Park ret 126*54fd6939SJiyong Parkendfunc rainier_cpu_reg_dump 127*54fd6939SJiyong Park 128*54fd6939SJiyong Parkdeclare_cpu_ops rainier, RAINIER_MIDR, \ 129*54fd6939SJiyong Park rainier_reset_func, \ 130*54fd6939SJiyong Park rainier_core_pwr_dwn 131