18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */ 28c2ecf20Sopenharmony_ci#ifndef _SPARC_TRAP_BLOCK_H 38c2ecf20Sopenharmony_ci#define _SPARC_TRAP_BLOCK_H 48c2ecf20Sopenharmony_ci 58c2ecf20Sopenharmony_ci#include <linux/threads.h> 68c2ecf20Sopenharmony_ci 78c2ecf20Sopenharmony_ci#include <asm/hypervisor.h> 88c2ecf20Sopenharmony_ci#include <asm/asi.h> 98c2ecf20Sopenharmony_ci 108c2ecf20Sopenharmony_ci#ifndef __ASSEMBLY__ 118c2ecf20Sopenharmony_ci 128c2ecf20Sopenharmony_ci/* Trap handling code needs to get at a few critical values upon 138c2ecf20Sopenharmony_ci * trap entry and to process TSB misses. These cannot be in the 148c2ecf20Sopenharmony_ci * per_cpu() area as we really need to lock them into the TLB and 158c2ecf20Sopenharmony_ci * thus make them part of the main kernel image. As a result we 168c2ecf20Sopenharmony_ci * try to make this as small as possible. 178c2ecf20Sopenharmony_ci * 188c2ecf20Sopenharmony_ci * This is padded out and aligned to 64-bytes to avoid false sharing 198c2ecf20Sopenharmony_ci * on SMP. 208c2ecf20Sopenharmony_ci */ 218c2ecf20Sopenharmony_ci 228c2ecf20Sopenharmony_ci/* If you modify the size of this structure, please update 238c2ecf20Sopenharmony_ci * TRAP_BLOCK_SZ_SHIFT below. 248c2ecf20Sopenharmony_ci */ 258c2ecf20Sopenharmony_cistruct thread_info; 268c2ecf20Sopenharmony_cistruct trap_per_cpu { 278c2ecf20Sopenharmony_ci/* D-cache line 1: Basic thread information, cpu and device mondo queues */ 288c2ecf20Sopenharmony_ci struct thread_info *thread; 298c2ecf20Sopenharmony_ci unsigned long pgd_paddr; 308c2ecf20Sopenharmony_ci unsigned long cpu_mondo_pa; 318c2ecf20Sopenharmony_ci unsigned long dev_mondo_pa; 328c2ecf20Sopenharmony_ci 338c2ecf20Sopenharmony_ci/* D-cache line 2: Error Mondo Queue and kernel buffer pointers */ 348c2ecf20Sopenharmony_ci unsigned long resum_mondo_pa; 358c2ecf20Sopenharmony_ci unsigned long resum_kernel_buf_pa; 368c2ecf20Sopenharmony_ci unsigned long nonresum_mondo_pa; 378c2ecf20Sopenharmony_ci unsigned long nonresum_kernel_buf_pa; 388c2ecf20Sopenharmony_ci 398c2ecf20Sopenharmony_ci/* Dcache lines 3, 4, 5, and 6: Hypervisor Fault Status */ 408c2ecf20Sopenharmony_ci struct hv_fault_status fault_info; 418c2ecf20Sopenharmony_ci 428c2ecf20Sopenharmony_ci/* Dcache line 7: Physical addresses of CPU send mondo block and CPU list. */ 438c2ecf20Sopenharmony_ci unsigned long cpu_mondo_block_pa; 448c2ecf20Sopenharmony_ci unsigned long cpu_list_pa; 458c2ecf20Sopenharmony_ci unsigned long tsb_huge; 468c2ecf20Sopenharmony_ci unsigned long tsb_huge_temp; 478c2ecf20Sopenharmony_ci 488c2ecf20Sopenharmony_ci/* Dcache line 8: IRQ work list, and keep trap_block a power-of-2 in size. */ 498c2ecf20Sopenharmony_ci unsigned long irq_worklist_pa; 508c2ecf20Sopenharmony_ci unsigned int cpu_mondo_qmask; 518c2ecf20Sopenharmony_ci unsigned int dev_mondo_qmask; 528c2ecf20Sopenharmony_ci unsigned int resum_qmask; 538c2ecf20Sopenharmony_ci unsigned int nonresum_qmask; 548c2ecf20Sopenharmony_ci unsigned long __per_cpu_base; 558c2ecf20Sopenharmony_ci} __attribute__((aligned(64))); 568c2ecf20Sopenharmony_ciextern struct trap_per_cpu trap_block[NR_CPUS]; 578c2ecf20Sopenharmony_civoid init_cur_cpu_trap(struct thread_info *); 588c2ecf20Sopenharmony_civoid setup_tba(void); 598c2ecf20Sopenharmony_ciextern int ncpus_probed; 608c2ecf20Sopenharmony_ciextern u64 cpu_mondo_counter[NR_CPUS]; 618c2ecf20Sopenharmony_ci 628c2ecf20Sopenharmony_ciunsigned long real_hard_smp_processor_id(void); 638c2ecf20Sopenharmony_ci 648c2ecf20Sopenharmony_cistruct cpuid_patch_entry { 658c2ecf20Sopenharmony_ci unsigned int addr; 668c2ecf20Sopenharmony_ci unsigned int cheetah_safari[4]; 678c2ecf20Sopenharmony_ci unsigned int cheetah_jbus[4]; 688c2ecf20Sopenharmony_ci unsigned int starfire[4]; 698c2ecf20Sopenharmony_ci unsigned int sun4v[4]; 708c2ecf20Sopenharmony_ci}; 718c2ecf20Sopenharmony_ciextern struct cpuid_patch_entry __cpuid_patch, __cpuid_patch_end; 728c2ecf20Sopenharmony_ci 738c2ecf20Sopenharmony_cistruct sun4v_1insn_patch_entry { 748c2ecf20Sopenharmony_ci unsigned int addr; 758c2ecf20Sopenharmony_ci unsigned int insn; 768c2ecf20Sopenharmony_ci}; 778c2ecf20Sopenharmony_ciextern struct sun4v_1insn_patch_entry __sun4v_1insn_patch, 788c2ecf20Sopenharmony_ci __sun4v_1insn_patch_end; 798c2ecf20Sopenharmony_ciextern struct sun4v_1insn_patch_entry __fast_win_ctrl_1insn_patch, 808c2ecf20Sopenharmony_ci __fast_win_ctrl_1insn_patch_end; 818c2ecf20Sopenharmony_ciextern struct sun4v_1insn_patch_entry __sun_m7_1insn_patch, 828c2ecf20Sopenharmony_ci __sun_m7_1insn_patch_end; 838c2ecf20Sopenharmony_ci 848c2ecf20Sopenharmony_cistruct sun4v_2insn_patch_entry { 858c2ecf20Sopenharmony_ci unsigned int addr; 868c2ecf20Sopenharmony_ci unsigned int insns[2]; 878c2ecf20Sopenharmony_ci}; 888c2ecf20Sopenharmony_ciextern struct sun4v_2insn_patch_entry __sun4v_2insn_patch, 898c2ecf20Sopenharmony_ci __sun4v_2insn_patch_end; 908c2ecf20Sopenharmony_ciextern struct sun4v_2insn_patch_entry __sun_m7_2insn_patch, 918c2ecf20Sopenharmony_ci __sun_m7_2insn_patch_end; 928c2ecf20Sopenharmony_ci 938c2ecf20Sopenharmony_ci 948c2ecf20Sopenharmony_ci#endif /* !(__ASSEMBLY__) */ 958c2ecf20Sopenharmony_ci 968c2ecf20Sopenharmony_ci#define TRAP_PER_CPU_THREAD 0x00 978c2ecf20Sopenharmony_ci#define TRAP_PER_CPU_PGD_PADDR 0x08 988c2ecf20Sopenharmony_ci#define TRAP_PER_CPU_CPU_MONDO_PA 0x10 998c2ecf20Sopenharmony_ci#define TRAP_PER_CPU_DEV_MONDO_PA 0x18 1008c2ecf20Sopenharmony_ci#define TRAP_PER_CPU_RESUM_MONDO_PA 0x20 1018c2ecf20Sopenharmony_ci#define TRAP_PER_CPU_RESUM_KBUF_PA 0x28 1028c2ecf20Sopenharmony_ci#define TRAP_PER_CPU_NONRESUM_MONDO_PA 0x30 1038c2ecf20Sopenharmony_ci#define TRAP_PER_CPU_NONRESUM_KBUF_PA 0x38 1048c2ecf20Sopenharmony_ci#define TRAP_PER_CPU_FAULT_INFO 0x40 1058c2ecf20Sopenharmony_ci#define TRAP_PER_CPU_CPU_MONDO_BLOCK_PA 0xc0 1068c2ecf20Sopenharmony_ci#define TRAP_PER_CPU_CPU_LIST_PA 0xc8 1078c2ecf20Sopenharmony_ci#define TRAP_PER_CPU_TSB_HUGE 0xd0 1088c2ecf20Sopenharmony_ci#define TRAP_PER_CPU_TSB_HUGE_TEMP 0xd8 1098c2ecf20Sopenharmony_ci#define TRAP_PER_CPU_IRQ_WORKLIST_PA 0xe0 1108c2ecf20Sopenharmony_ci#define TRAP_PER_CPU_CPU_MONDO_QMASK 0xe8 1118c2ecf20Sopenharmony_ci#define TRAP_PER_CPU_DEV_MONDO_QMASK 0xec 1128c2ecf20Sopenharmony_ci#define TRAP_PER_CPU_RESUM_QMASK 0xf0 1138c2ecf20Sopenharmony_ci#define TRAP_PER_CPU_NONRESUM_QMASK 0xf4 1148c2ecf20Sopenharmony_ci#define TRAP_PER_CPU_PER_CPU_BASE 0xf8 1158c2ecf20Sopenharmony_ci 1168c2ecf20Sopenharmony_ci#define TRAP_BLOCK_SZ_SHIFT 8 1178c2ecf20Sopenharmony_ci 1188c2ecf20Sopenharmony_ci#include <asm/scratchpad.h> 1198c2ecf20Sopenharmony_ci 1208c2ecf20Sopenharmony_ci#define __GET_CPUID(REG) \ 1218c2ecf20Sopenharmony_ci /* Spitfire implementation (default). */ \ 1228c2ecf20Sopenharmony_ci661: ldxa [%g0] ASI_UPA_CONFIG, REG; \ 1238c2ecf20Sopenharmony_ci srlx REG, 17, REG; \ 1248c2ecf20Sopenharmony_ci and REG, 0x1f, REG; \ 1258c2ecf20Sopenharmony_ci nop; \ 1268c2ecf20Sopenharmony_ci .section .cpuid_patch, "ax"; \ 1278c2ecf20Sopenharmony_ci /* Instruction location. */ \ 1288c2ecf20Sopenharmony_ci .word 661b; \ 1298c2ecf20Sopenharmony_ci /* Cheetah Safari implementation. */ \ 1308c2ecf20Sopenharmony_ci ldxa [%g0] ASI_SAFARI_CONFIG, REG; \ 1318c2ecf20Sopenharmony_ci srlx REG, 17, REG; \ 1328c2ecf20Sopenharmony_ci and REG, 0x3ff, REG; \ 1338c2ecf20Sopenharmony_ci nop; \ 1348c2ecf20Sopenharmony_ci /* Cheetah JBUS implementation. */ \ 1358c2ecf20Sopenharmony_ci ldxa [%g0] ASI_JBUS_CONFIG, REG; \ 1368c2ecf20Sopenharmony_ci srlx REG, 17, REG; \ 1378c2ecf20Sopenharmony_ci and REG, 0x1f, REG; \ 1388c2ecf20Sopenharmony_ci nop; \ 1398c2ecf20Sopenharmony_ci /* Starfire implementation. */ \ 1408c2ecf20Sopenharmony_ci sethi %hi(0x1fff40000d0 >> 9), REG; \ 1418c2ecf20Sopenharmony_ci sllx REG, 9, REG; \ 1428c2ecf20Sopenharmony_ci or REG, 0xd0, REG; \ 1438c2ecf20Sopenharmony_ci lduwa [REG] ASI_PHYS_BYPASS_EC_E, REG;\ 1448c2ecf20Sopenharmony_ci /* sun4v implementation. */ \ 1458c2ecf20Sopenharmony_ci mov SCRATCHPAD_CPUID, REG; \ 1468c2ecf20Sopenharmony_ci ldxa [REG] ASI_SCRATCHPAD, REG; \ 1478c2ecf20Sopenharmony_ci nop; \ 1488c2ecf20Sopenharmony_ci nop; \ 1498c2ecf20Sopenharmony_ci .previous; 1508c2ecf20Sopenharmony_ci 1518c2ecf20Sopenharmony_ci#ifdef CONFIG_SMP 1528c2ecf20Sopenharmony_ci 1538c2ecf20Sopenharmony_ci#define TRAP_LOAD_TRAP_BLOCK(DEST, TMP) \ 1548c2ecf20Sopenharmony_ci __GET_CPUID(TMP) \ 1558c2ecf20Sopenharmony_ci sethi %hi(trap_block), DEST; \ 1568c2ecf20Sopenharmony_ci sllx TMP, TRAP_BLOCK_SZ_SHIFT, TMP; \ 1578c2ecf20Sopenharmony_ci or DEST, %lo(trap_block), DEST; \ 1588c2ecf20Sopenharmony_ci add DEST, TMP, DEST; \ 1598c2ecf20Sopenharmony_ci 1608c2ecf20Sopenharmony_ci/* Clobbers TMP, current address space PGD phys address into DEST. */ 1618c2ecf20Sopenharmony_ci#define TRAP_LOAD_PGD_PHYS(DEST, TMP) \ 1628c2ecf20Sopenharmony_ci TRAP_LOAD_TRAP_BLOCK(DEST, TMP) \ 1638c2ecf20Sopenharmony_ci ldx [DEST + TRAP_PER_CPU_PGD_PADDR], DEST; 1648c2ecf20Sopenharmony_ci 1658c2ecf20Sopenharmony_ci/* Clobbers TMP, loads local processor's IRQ work area into DEST. */ 1668c2ecf20Sopenharmony_ci#define TRAP_LOAD_IRQ_WORK_PA(DEST, TMP) \ 1678c2ecf20Sopenharmony_ci TRAP_LOAD_TRAP_BLOCK(DEST, TMP) \ 1688c2ecf20Sopenharmony_ci add DEST, TRAP_PER_CPU_IRQ_WORKLIST_PA, DEST; 1698c2ecf20Sopenharmony_ci 1708c2ecf20Sopenharmony_ci/* Clobbers TMP, loads DEST with current thread info pointer. */ 1718c2ecf20Sopenharmony_ci#define TRAP_LOAD_THREAD_REG(DEST, TMP) \ 1728c2ecf20Sopenharmony_ci TRAP_LOAD_TRAP_BLOCK(DEST, TMP) \ 1738c2ecf20Sopenharmony_ci ldx [DEST + TRAP_PER_CPU_THREAD], DEST; 1748c2ecf20Sopenharmony_ci 1758c2ecf20Sopenharmony_ci/* Given the current thread info pointer in THR, load the per-cpu 1768c2ecf20Sopenharmony_ci * area base of the current processor into DEST. REG1, REG2, and REG3 are 1778c2ecf20Sopenharmony_ci * clobbered. 1788c2ecf20Sopenharmony_ci * 1798c2ecf20Sopenharmony_ci * You absolutely cannot use DEST as a temporary in this code. The 1808c2ecf20Sopenharmony_ci * reason is that traps can happen during execution, and return from 1818c2ecf20Sopenharmony_ci * trap will load the fully resolved DEST per-cpu base. This can corrupt 1828c2ecf20Sopenharmony_ci * the calculations done by the macro mid-stream. 1838c2ecf20Sopenharmony_ci */ 1848c2ecf20Sopenharmony_ci#define LOAD_PER_CPU_BASE(DEST, THR, REG1, REG2, REG3) \ 1858c2ecf20Sopenharmony_ci lduh [THR + TI_CPU], REG1; \ 1868c2ecf20Sopenharmony_ci sethi %hi(trap_block), REG2; \ 1878c2ecf20Sopenharmony_ci sllx REG1, TRAP_BLOCK_SZ_SHIFT, REG1; \ 1888c2ecf20Sopenharmony_ci or REG2, %lo(trap_block), REG2; \ 1898c2ecf20Sopenharmony_ci add REG2, REG1, REG2; \ 1908c2ecf20Sopenharmony_ci ldx [REG2 + TRAP_PER_CPU_PER_CPU_BASE], DEST; 1918c2ecf20Sopenharmony_ci 1928c2ecf20Sopenharmony_ci#else 1938c2ecf20Sopenharmony_ci 1948c2ecf20Sopenharmony_ci#define TRAP_LOAD_TRAP_BLOCK(DEST, TMP) \ 1958c2ecf20Sopenharmony_ci sethi %hi(trap_block), DEST; \ 1968c2ecf20Sopenharmony_ci or DEST, %lo(trap_block), DEST; \ 1978c2ecf20Sopenharmony_ci 1988c2ecf20Sopenharmony_ci/* Uniprocessor versions, we know the cpuid is zero. */ 1998c2ecf20Sopenharmony_ci#define TRAP_LOAD_PGD_PHYS(DEST, TMP) \ 2008c2ecf20Sopenharmony_ci TRAP_LOAD_TRAP_BLOCK(DEST, TMP) \ 2018c2ecf20Sopenharmony_ci ldx [DEST + TRAP_PER_CPU_PGD_PADDR], DEST; 2028c2ecf20Sopenharmony_ci 2038c2ecf20Sopenharmony_ci/* Clobbers TMP, loads local processor's IRQ work area into DEST. */ 2048c2ecf20Sopenharmony_ci#define TRAP_LOAD_IRQ_WORK_PA(DEST, TMP) \ 2058c2ecf20Sopenharmony_ci TRAP_LOAD_TRAP_BLOCK(DEST, TMP) \ 2068c2ecf20Sopenharmony_ci add DEST, TRAP_PER_CPU_IRQ_WORKLIST_PA, DEST; 2078c2ecf20Sopenharmony_ci 2088c2ecf20Sopenharmony_ci#define TRAP_LOAD_THREAD_REG(DEST, TMP) \ 2098c2ecf20Sopenharmony_ci TRAP_LOAD_TRAP_BLOCK(DEST, TMP) \ 2108c2ecf20Sopenharmony_ci ldx [DEST + TRAP_PER_CPU_THREAD], DEST; 2118c2ecf20Sopenharmony_ci 2128c2ecf20Sopenharmony_ci/* No per-cpu areas on uniprocessor, so no need to load DEST. */ 2138c2ecf20Sopenharmony_ci#define LOAD_PER_CPU_BASE(DEST, THR, REG1, REG2, REG3) 2148c2ecf20Sopenharmony_ci 2158c2ecf20Sopenharmony_ci#endif /* !(CONFIG_SMP) */ 2168c2ecf20Sopenharmony_ci 2178c2ecf20Sopenharmony_ci#endif /* _SPARC_TRAP_BLOCK_H */ 218