1*b880a800SSuzuki K Poulose /* SPDX-License-Identifier: GPL-2.0-only */ 2*b880a800SSuzuki K Poulose /* 3*b880a800SSuzuki K Poulose * Copyright (C) 2023 ARM Ltd. 4*b880a800SSuzuki K Poulose */ 5*b880a800SSuzuki K Poulose 6*b880a800SSuzuki K Poulose #ifndef __ASM_RSI_CMDS_H 7*b880a800SSuzuki K Poulose #define __ASM_RSI_CMDS_H 8*b880a800SSuzuki K Poulose 9*b880a800SSuzuki K Poulose #include <linux/arm-smccc.h> 10*b880a800SSuzuki K Poulose 11*b880a800SSuzuki K Poulose #include <asm/rsi_smc.h> 12*b880a800SSuzuki K Poulose 13*b880a800SSuzuki K Poulose #define RSI_GRANULE_SHIFT 12 14*b880a800SSuzuki K Poulose #define RSI_GRANULE_SIZE (_AC(1, UL) << RSI_GRANULE_SHIFT) 15*b880a800SSuzuki K Poulose 16*b880a800SSuzuki K Poulose enum ripas { 17*b880a800SSuzuki K Poulose RSI_RIPAS_EMPTY = 0, 18*b880a800SSuzuki K Poulose RSI_RIPAS_RAM = 1, 19*b880a800SSuzuki K Poulose RSI_RIPAS_DESTROYED = 2, 20*b880a800SSuzuki K Poulose RSI_RIPAS_DEV = 3, 21*b880a800SSuzuki K Poulose }; 22*b880a800SSuzuki K Poulose 23*b880a800SSuzuki K Poulose static inline unsigned long rsi_request_version(unsigned long req, 24*b880a800SSuzuki K Poulose unsigned long *out_lower, 25*b880a800SSuzuki K Poulose unsigned long *out_higher) 26*b880a800SSuzuki K Poulose { 27*b880a800SSuzuki K Poulose struct arm_smccc_res res; 28*b880a800SSuzuki K Poulose 29*b880a800SSuzuki K Poulose arm_smccc_smc(SMC_RSI_ABI_VERSION, req, 0, 0, 0, 0, 0, 0, &res); 30*b880a800SSuzuki K Poulose 31*b880a800SSuzuki K Poulose if (out_lower) 32*b880a800SSuzuki K Poulose *out_lower = res.a1; 33*b880a800SSuzuki K Poulose if (out_higher) 34*b880a800SSuzuki K Poulose *out_higher = res.a2; 35*b880a800SSuzuki K Poulose 36*b880a800SSuzuki K Poulose return res.a0; 37*b880a800SSuzuki K Poulose } 38*b880a800SSuzuki K Poulose 39*b880a800SSuzuki K Poulose static inline unsigned long rsi_get_realm_config(struct realm_config *cfg) 40*b880a800SSuzuki K Poulose { 41*b880a800SSuzuki K Poulose struct arm_smccc_res res; 42*b880a800SSuzuki K Poulose 43*b880a800SSuzuki K Poulose arm_smccc_smc(SMC_RSI_REALM_CONFIG, virt_to_phys(cfg), 44*b880a800SSuzuki K Poulose 0, 0, 0, 0, 0, 0, &res); 45*b880a800SSuzuki K Poulose return res.a0; 46*b880a800SSuzuki K Poulose } 47*b880a800SSuzuki K Poulose 48*b880a800SSuzuki K Poulose static inline long rsi_set_addr_range_state(phys_addr_t start, 49*b880a800SSuzuki K Poulose phys_addr_t end, 50*b880a800SSuzuki K Poulose enum ripas state, 51*b880a800SSuzuki K Poulose unsigned long flags, 52*b880a800SSuzuki K Poulose phys_addr_t *top) 53*b880a800SSuzuki K Poulose { 54*b880a800SSuzuki K Poulose struct arm_smccc_res res; 55*b880a800SSuzuki K Poulose 56*b880a800SSuzuki K Poulose arm_smccc_smc(SMC_RSI_IPA_STATE_SET, start, end, state, 57*b880a800SSuzuki K Poulose flags, 0, 0, 0, &res); 58*b880a800SSuzuki K Poulose 59*b880a800SSuzuki K Poulose if (top) 60*b880a800SSuzuki K Poulose *top = res.a1; 61*b880a800SSuzuki K Poulose 62*b880a800SSuzuki K Poulose if (res.a2 != RSI_ACCEPT) 63*b880a800SSuzuki K Poulose return -EPERM; 64*b880a800SSuzuki K Poulose 65*b880a800SSuzuki K Poulose return res.a0; 66*b880a800SSuzuki K Poulose } 67*b880a800SSuzuki K Poulose 68*b880a800SSuzuki K Poulose /** 69*b880a800SSuzuki K Poulose * rsi_attestation_token_init - Initialise the operation to retrieve an 70*b880a800SSuzuki K Poulose * attestation token. 71*b880a800SSuzuki K Poulose * 72*b880a800SSuzuki K Poulose * @challenge: The challenge data to be used in the attestation token 73*b880a800SSuzuki K Poulose * generation. 74*b880a800SSuzuki K Poulose * @size: Size of the challenge data in bytes. 75*b880a800SSuzuki K Poulose * 76*b880a800SSuzuki K Poulose * Initialises the attestation token generation and returns an upper bound 77*b880a800SSuzuki K Poulose * on the attestation token size that can be used to allocate an adequate 78*b880a800SSuzuki K Poulose * buffer. The caller is expected to subsequently call 79*b880a800SSuzuki K Poulose * rsi_attestation_token_continue() to retrieve the attestation token data on 80*b880a800SSuzuki K Poulose * the same CPU. 81*b880a800SSuzuki K Poulose * 82*b880a800SSuzuki K Poulose * Returns: 83*b880a800SSuzuki K Poulose * On success, returns the upper limit of the attestation report size. 84*b880a800SSuzuki K Poulose * Otherwise, -EINVAL 85*b880a800SSuzuki K Poulose */ 86*b880a800SSuzuki K Poulose static inline long 87*b880a800SSuzuki K Poulose rsi_attestation_token_init(const u8 *challenge, unsigned long size) 88*b880a800SSuzuki K Poulose { 89*b880a800SSuzuki K Poulose struct arm_smccc_1_2_regs regs = { 0 }; 90*b880a800SSuzuki K Poulose 91*b880a800SSuzuki K Poulose /* The challenge must be at least 32bytes and at most 64bytes */ 92*b880a800SSuzuki K Poulose if (!challenge || size < 32 || size > 64) 93*b880a800SSuzuki K Poulose return -EINVAL; 94*b880a800SSuzuki K Poulose 95*b880a800SSuzuki K Poulose regs.a0 = SMC_RSI_ATTESTATION_TOKEN_INIT; 96*b880a800SSuzuki K Poulose memcpy(®s.a1, challenge, size); 97*b880a800SSuzuki K Poulose arm_smccc_1_2_smc(®s, ®s); 98*b880a800SSuzuki K Poulose 99*b880a800SSuzuki K Poulose if (regs.a0 == RSI_SUCCESS) 100*b880a800SSuzuki K Poulose return regs.a1; 101*b880a800SSuzuki K Poulose 102*b880a800SSuzuki K Poulose return -EINVAL; 103*b880a800SSuzuki K Poulose } 104*b880a800SSuzuki K Poulose 105*b880a800SSuzuki K Poulose /** 106*b880a800SSuzuki K Poulose * rsi_attestation_token_continue - Continue the operation to retrieve an 107*b880a800SSuzuki K Poulose * attestation token. 108*b880a800SSuzuki K Poulose * 109*b880a800SSuzuki K Poulose * @granule: {I}PA of the Granule to which the token will be written. 110*b880a800SSuzuki K Poulose * @offset: Offset within Granule to start of buffer in bytes. 111*b880a800SSuzuki K Poulose * @size: The size of the buffer. 112*b880a800SSuzuki K Poulose * @len: The number of bytes written to the buffer. 113*b880a800SSuzuki K Poulose * 114*b880a800SSuzuki K Poulose * Retrieves up to a RSI_GRANULE_SIZE worth of token data per call. The caller 115*b880a800SSuzuki K Poulose * is expected to call rsi_attestation_token_init() before calling this 116*b880a800SSuzuki K Poulose * function to retrieve the attestation token. 117*b880a800SSuzuki K Poulose * 118*b880a800SSuzuki K Poulose * Return: 119*b880a800SSuzuki K Poulose * * %RSI_SUCCESS - Attestation token retrieved successfully. 120*b880a800SSuzuki K Poulose * * %RSI_INCOMPLETE - Token generation is not complete. 121*b880a800SSuzuki K Poulose * * %RSI_ERROR_INPUT - A parameter was not valid. 122*b880a800SSuzuki K Poulose * * %RSI_ERROR_STATE - Attestation not in progress. 123*b880a800SSuzuki K Poulose */ 124*b880a800SSuzuki K Poulose static inline unsigned long rsi_attestation_token_continue(phys_addr_t granule, 125*b880a800SSuzuki K Poulose unsigned long offset, 126*b880a800SSuzuki K Poulose unsigned long size, 127*b880a800SSuzuki K Poulose unsigned long *len) 128*b880a800SSuzuki K Poulose { 129*b880a800SSuzuki K Poulose struct arm_smccc_res res; 130*b880a800SSuzuki K Poulose 131*b880a800SSuzuki K Poulose arm_smccc_1_1_invoke(SMC_RSI_ATTESTATION_TOKEN_CONTINUE, 132*b880a800SSuzuki K Poulose granule, offset, size, 0, &res); 133*b880a800SSuzuki K Poulose 134*b880a800SSuzuki K Poulose if (len) 135*b880a800SSuzuki K Poulose *len = res.a1; 136*b880a800SSuzuki K Poulose return res.a0; 137*b880a800SSuzuki K Poulose } 138*b880a800SSuzuki K Poulose 139*b880a800SSuzuki K Poulose #endif /* __ASM_RSI_CMDS_H */ 140