162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-or-later */ 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * ICSWX api 462306a36Sopenharmony_ci * 562306a36Sopenharmony_ci * Copyright (C) 2015 IBM Corp. 662306a36Sopenharmony_ci * 762306a36Sopenharmony_ci * This provides the Initiate Coprocessor Store Word Indexed (ICSWX) 862306a36Sopenharmony_ci * instruction. This instruction is used to communicate with PowerPC 962306a36Sopenharmony_ci * coprocessors. This also provides definitions of the structures used 1062306a36Sopenharmony_ci * to communicate with the coprocessor. 1162306a36Sopenharmony_ci * 1262306a36Sopenharmony_ci * The RFC02130: Coprocessor Architecture document is the reference for 1362306a36Sopenharmony_ci * everything in this file unless otherwise noted. 1462306a36Sopenharmony_ci */ 1562306a36Sopenharmony_ci#ifndef _ARCH_POWERPC_INCLUDE_ASM_ICSWX_H_ 1662306a36Sopenharmony_ci#define _ARCH_POWERPC_INCLUDE_ASM_ICSWX_H_ 1762306a36Sopenharmony_ci 1862306a36Sopenharmony_ci#include <asm/ppc-opcode.h> /* for PPC_ICSWX */ 1962306a36Sopenharmony_ci 2062306a36Sopenharmony_ci/* Chapter 6.5.8 Coprocessor-Completion Block (CCB) */ 2162306a36Sopenharmony_ci 2262306a36Sopenharmony_ci#define CCB_VALUE (0x3fffffffffffffff) 2362306a36Sopenharmony_ci#define CCB_ADDRESS (0xfffffffffffffff8) 2462306a36Sopenharmony_ci#define CCB_CM (0x0000000000000007) 2562306a36Sopenharmony_ci#define CCB_CM0 (0x0000000000000004) 2662306a36Sopenharmony_ci#define CCB_CM12 (0x0000000000000003) 2762306a36Sopenharmony_ci 2862306a36Sopenharmony_ci#define CCB_CM0_ALL_COMPLETIONS (0x0) 2962306a36Sopenharmony_ci#define CCB_CM0_LAST_IN_CHAIN (0x4) 3062306a36Sopenharmony_ci#define CCB_CM12_STORE (0x0) 3162306a36Sopenharmony_ci#define CCB_CM12_INTERRUPT (0x1) 3262306a36Sopenharmony_ci 3362306a36Sopenharmony_ci#define CCB_SIZE (0x10) 3462306a36Sopenharmony_ci#define CCB_ALIGN CCB_SIZE 3562306a36Sopenharmony_ci 3662306a36Sopenharmony_cistruct coprocessor_completion_block { 3762306a36Sopenharmony_ci __be64 value; 3862306a36Sopenharmony_ci __be64 address; 3962306a36Sopenharmony_ci} __packed __aligned(CCB_ALIGN); 4062306a36Sopenharmony_ci 4162306a36Sopenharmony_ci 4262306a36Sopenharmony_ci/* Chapter 6.5.7 Coprocessor-Status Block (CSB) */ 4362306a36Sopenharmony_ci 4462306a36Sopenharmony_ci#define CSB_V (0x80) 4562306a36Sopenharmony_ci#define CSB_F (0x04) 4662306a36Sopenharmony_ci#define CSB_CH (0x03) 4762306a36Sopenharmony_ci#define CSB_CE_INCOMPLETE (0x80) 4862306a36Sopenharmony_ci#define CSB_CE_TERMINATION (0x40) 4962306a36Sopenharmony_ci#define CSB_CE_TPBC (0x20) 5062306a36Sopenharmony_ci 5162306a36Sopenharmony_ci#define CSB_CC_SUCCESS (0) 5262306a36Sopenharmony_ci#define CSB_CC_INVALID_ALIGN (1) 5362306a36Sopenharmony_ci#define CSB_CC_OPERAND_OVERLAP (2) 5462306a36Sopenharmony_ci#define CSB_CC_DATA_LENGTH (3) 5562306a36Sopenharmony_ci#define CSB_CC_TRANSLATION (5) 5662306a36Sopenharmony_ci#define CSB_CC_PROTECTION (6) 5762306a36Sopenharmony_ci#define CSB_CC_RD_EXTERNAL (7) 5862306a36Sopenharmony_ci#define CSB_CC_INVALID_OPERAND (8) 5962306a36Sopenharmony_ci#define CSB_CC_PRIVILEGE (9) 6062306a36Sopenharmony_ci#define CSB_CC_INTERNAL (10) 6162306a36Sopenharmony_ci#define CSB_CC_WR_EXTERNAL (12) 6262306a36Sopenharmony_ci#define CSB_CC_NOSPC (13) 6362306a36Sopenharmony_ci#define CSB_CC_EXCESSIVE_DDE (14) 6462306a36Sopenharmony_ci#define CSB_CC_WR_TRANSLATION (15) 6562306a36Sopenharmony_ci#define CSB_CC_WR_PROTECTION (16) 6662306a36Sopenharmony_ci#define CSB_CC_UNKNOWN_CODE (17) 6762306a36Sopenharmony_ci#define CSB_CC_ABORT (18) 6862306a36Sopenharmony_ci#define CSB_CC_EXCEED_BYTE_COUNT (19) /* P9 or later */ 6962306a36Sopenharmony_ci#define CSB_CC_TRANSPORT (20) 7062306a36Sopenharmony_ci#define CSB_CC_INVALID_CRB (21) /* P9 or later */ 7162306a36Sopenharmony_ci#define CSB_CC_INVALID_DDE (30) /* P9 or later */ 7262306a36Sopenharmony_ci#define CSB_CC_SEGMENTED_DDL (31) 7362306a36Sopenharmony_ci#define CSB_CC_PROGRESS_POINT (32) 7462306a36Sopenharmony_ci#define CSB_CC_DDE_OVERFLOW (33) 7562306a36Sopenharmony_ci#define CSB_CC_SESSION (34) 7662306a36Sopenharmony_ci#define CSB_CC_PROVISION (36) 7762306a36Sopenharmony_ci#define CSB_CC_CHAIN (37) 7862306a36Sopenharmony_ci#define CSB_CC_SEQUENCE (38) 7962306a36Sopenharmony_ci#define CSB_CC_HW (39) 8062306a36Sopenharmony_ci/* P9 DD2 NX Workbook 3.2 (Table 4-36): Address translation fault */ 8162306a36Sopenharmony_ci#define CSB_CC_FAULT_ADDRESS (250) 8262306a36Sopenharmony_ci 8362306a36Sopenharmony_ci#define CSB_SIZE (0x10) 8462306a36Sopenharmony_ci#define CSB_ALIGN CSB_SIZE 8562306a36Sopenharmony_ci 8662306a36Sopenharmony_cistruct coprocessor_status_block { 8762306a36Sopenharmony_ci u8 flags; 8862306a36Sopenharmony_ci u8 cs; 8962306a36Sopenharmony_ci u8 cc; 9062306a36Sopenharmony_ci u8 ce; 9162306a36Sopenharmony_ci __be32 count; 9262306a36Sopenharmony_ci __be64 address; 9362306a36Sopenharmony_ci} __packed __aligned(CSB_ALIGN); 9462306a36Sopenharmony_ci 9562306a36Sopenharmony_ci 9662306a36Sopenharmony_ci/* Chapter 6.5.10 Data-Descriptor List (DDL) 9762306a36Sopenharmony_ci * each list contains one or more Data-Descriptor Entries (DDE) 9862306a36Sopenharmony_ci */ 9962306a36Sopenharmony_ci 10062306a36Sopenharmony_ci#define DDE_P (0x8000) 10162306a36Sopenharmony_ci 10262306a36Sopenharmony_ci#define DDE_SIZE (0x10) 10362306a36Sopenharmony_ci#define DDE_ALIGN DDE_SIZE 10462306a36Sopenharmony_ci 10562306a36Sopenharmony_cistruct data_descriptor_entry { 10662306a36Sopenharmony_ci __be16 flags; 10762306a36Sopenharmony_ci u8 count; 10862306a36Sopenharmony_ci u8 index; 10962306a36Sopenharmony_ci __be32 length; 11062306a36Sopenharmony_ci __be64 address; 11162306a36Sopenharmony_ci} __packed __aligned(DDE_ALIGN); 11262306a36Sopenharmony_ci 11362306a36Sopenharmony_ci/* 4.3.2 NX-stamped Fault CRB */ 11462306a36Sopenharmony_ci 11562306a36Sopenharmony_ci#define NX_STAMP_ALIGN (0x10) 11662306a36Sopenharmony_ci 11762306a36Sopenharmony_cistruct nx_fault_stamp { 11862306a36Sopenharmony_ci __be64 fault_storage_addr; 11962306a36Sopenharmony_ci __be16 reserved; 12062306a36Sopenharmony_ci __u8 flags; 12162306a36Sopenharmony_ci __u8 fault_status; 12262306a36Sopenharmony_ci __be32 pswid; 12362306a36Sopenharmony_ci} __packed __aligned(NX_STAMP_ALIGN); 12462306a36Sopenharmony_ci 12562306a36Sopenharmony_ci/* Chapter 6.5.2 Coprocessor-Request Block (CRB) */ 12662306a36Sopenharmony_ci 12762306a36Sopenharmony_ci#define CRB_SIZE (0x80) 12862306a36Sopenharmony_ci#define CRB_ALIGN (0x100) /* Errata: requires 256 alignment */ 12962306a36Sopenharmony_ci 13062306a36Sopenharmony_ci/* Coprocessor Status Block field 13162306a36Sopenharmony_ci * ADDRESS address of CSB 13262306a36Sopenharmony_ci * C CCB is valid 13362306a36Sopenharmony_ci * AT 0 = addrs are virtual, 1 = addrs are phys 13462306a36Sopenharmony_ci * M enable perf monitor 13562306a36Sopenharmony_ci */ 13662306a36Sopenharmony_ci#define CRB_CSB_ADDRESS (0xfffffffffffffff0) 13762306a36Sopenharmony_ci#define CRB_CSB_C (0x0000000000000008) 13862306a36Sopenharmony_ci#define CRB_CSB_AT (0x0000000000000002) 13962306a36Sopenharmony_ci#define CRB_CSB_M (0x0000000000000001) 14062306a36Sopenharmony_ci 14162306a36Sopenharmony_cistruct coprocessor_request_block { 14262306a36Sopenharmony_ci __be32 ccw; 14362306a36Sopenharmony_ci __be32 flags; 14462306a36Sopenharmony_ci __be64 csb_addr; 14562306a36Sopenharmony_ci 14662306a36Sopenharmony_ci struct data_descriptor_entry source; 14762306a36Sopenharmony_ci struct data_descriptor_entry target; 14862306a36Sopenharmony_ci 14962306a36Sopenharmony_ci struct coprocessor_completion_block ccb; 15062306a36Sopenharmony_ci 15162306a36Sopenharmony_ci union { 15262306a36Sopenharmony_ci struct nx_fault_stamp nx; 15362306a36Sopenharmony_ci u8 reserved[16]; 15462306a36Sopenharmony_ci } stamp; 15562306a36Sopenharmony_ci 15662306a36Sopenharmony_ci u8 reserved[32]; 15762306a36Sopenharmony_ci 15862306a36Sopenharmony_ci struct coprocessor_status_block csb; 15962306a36Sopenharmony_ci} __aligned(128); 16062306a36Sopenharmony_ci 16162306a36Sopenharmony_ci/* RFC02167 Initiate Coprocessor Instructions document 16262306a36Sopenharmony_ci * Chapter 8.2.1.1.1 RS 16362306a36Sopenharmony_ci * Chapter 8.2.3 Coprocessor Directive 16462306a36Sopenharmony_ci * Chapter 8.2.4 Execution 16562306a36Sopenharmony_ci * 16662306a36Sopenharmony_ci * The CCW must be converted to BE before passing to icswx() 16762306a36Sopenharmony_ci */ 16862306a36Sopenharmony_ci 16962306a36Sopenharmony_ci#define CCW_PS (0xff000000) 17062306a36Sopenharmony_ci#define CCW_CT (0x00ff0000) 17162306a36Sopenharmony_ci#define CCW_CD (0x0000ffff) 17262306a36Sopenharmony_ci#define CCW_CL (0x0000c000) 17362306a36Sopenharmony_ci 17462306a36Sopenharmony_ci 17562306a36Sopenharmony_ci/* RFC02167 Initiate Coprocessor Instructions document 17662306a36Sopenharmony_ci * Chapter 8.2.1 Initiate Coprocessor Store Word Indexed (ICSWX) 17762306a36Sopenharmony_ci * Chapter 8.2.4.1 Condition Register 0 17862306a36Sopenharmony_ci */ 17962306a36Sopenharmony_ci 18062306a36Sopenharmony_ci#define ICSWX_INITIATED (0x8) 18162306a36Sopenharmony_ci#define ICSWX_BUSY (0x4) 18262306a36Sopenharmony_ci#define ICSWX_REJECTED (0x2) 18362306a36Sopenharmony_ci#define ICSWX_XERS0 (0x1) /* undefined or set from XERSO. */ 18462306a36Sopenharmony_ci 18562306a36Sopenharmony_cistatic inline int icswx(__be32 ccw, struct coprocessor_request_block *crb) 18662306a36Sopenharmony_ci{ 18762306a36Sopenharmony_ci __be64 ccw_reg = ccw; 18862306a36Sopenharmony_ci u32 cr; 18962306a36Sopenharmony_ci 19062306a36Sopenharmony_ci /* NB: the same structures are used by VAS-NX */ 19162306a36Sopenharmony_ci BUILD_BUG_ON(sizeof(*crb) != 128); 19262306a36Sopenharmony_ci 19362306a36Sopenharmony_ci __asm__ __volatile__( 19462306a36Sopenharmony_ci PPC_ICSWX(%1,0,%2) "\n" 19562306a36Sopenharmony_ci "mfcr %0\n" 19662306a36Sopenharmony_ci : "=r" (cr) 19762306a36Sopenharmony_ci : "r" (ccw_reg), "r" (crb) 19862306a36Sopenharmony_ci : "cr0", "memory"); 19962306a36Sopenharmony_ci 20062306a36Sopenharmony_ci return (int)((cr >> 28) & 0xf); 20162306a36Sopenharmony_ci} 20262306a36Sopenharmony_ci 20362306a36Sopenharmony_ci 20462306a36Sopenharmony_ci#endif /* _ARCH_POWERPC_INCLUDE_ASM_ICSWX_H_ */ 205