Message ID | 20230127112932.38045-4-steven.price@arm.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | arm64: Support for Arm CCA in KVM | expand |
On Fri, 27 Jan 2023 11:29:07 +0000 Steven Price <steven.price@arm.com> wrote: > The wrappers make the call sites easier to read and deal with the > boiler plate of handling the error codes from the RMM. > > Signed-off-by: Steven Price <steven.price@arm.com> > --- > arch/arm64/include/asm/rmi_cmds.h | 259 ++++++++++++++++++++++++++++++ > 1 file changed, 259 insertions(+) > create mode 100644 arch/arm64/include/asm/rmi_cmds.h > > diff --git a/arch/arm64/include/asm/rmi_cmds.h b/arch/arm64/include/asm/rmi_cmds.h > new file mode 100644 > index 000000000000..d5468ee46f35 > --- /dev/null > +++ b/arch/arm64/include/asm/rmi_cmds.h > @@ -0,0 +1,259 @@ > +/* SPDX-License-Identifier: GPL-2.0 */ > +/* > + * Copyright (C) 2023 ARM Ltd. > + */ > + > +#ifndef __ASM_RMI_CMDS_H > +#define __ASM_RMI_CMDS_H > + > +#include <linux/arm-smccc.h> > + > +#include <asm/rmi_smc.h> > + > +struct rtt_entry { > + unsigned long walk_level; > + unsigned long desc; > + int state; > + bool ripas; > +}; > + It would be nice to have some information of the follwoing wrappers. E.g. meaning of the return value. They will be quite helpful in the later patch review. > +static inline int rmi_data_create(unsigned long data, unsigned long rd, > + unsigned long map_addr, unsigned long src, > + unsigned long flags) > +{ > + struct arm_smccc_res res; > + > + arm_smccc_1_1_invoke(SMC_RMI_DATA_CREATE, data, rd, map_addr, src, > + flags, &res); > + > + return res.a0; > +} > + > +static inline int rmi_data_create_unknown(unsigned long data, > + unsigned long rd, > + unsigned long map_addr) > +{ > + struct arm_smccc_res res; > + > + arm_smccc_1_1_invoke(SMC_RMI_DATA_CREATE_UNKNOWN, data, rd, map_addr, > + &res); > + > + return res.a0; > +} > + > +static inline int rmi_data_destroy(unsigned long rd, unsigned long map_addr) > +{ > + struct arm_smccc_res res; > + > + arm_smccc_1_1_invoke(SMC_RMI_DATA_DESTROY, rd, map_addr, &res); > + > + return res.a0; > +} > + > +static inline int rmi_features(unsigned long index, unsigned long *out) > +{ > + struct arm_smccc_res res; > + > + arm_smccc_1_1_invoke(SMC_RMI_FEATURES, index, &res); > + > + *out = res.a1; > + return res.a0; > +} > + > +static inline int rmi_granule_delegate(unsigned long phys) > +{ > + struct arm_smccc_res res; > + > + arm_smccc_1_1_invoke(SMC_RMI_GRANULE_DELEGATE, phys, &res); > + > + return res.a0; > +} > + > +static inline int rmi_granule_undelegate(unsigned long phys) > +{ > + struct arm_smccc_res res; > + > + arm_smccc_1_1_invoke(SMC_RMI_GRANULE_UNDELEGATE, phys, &res); > + > + return res.a0; > +} > + > +static inline int rmi_psci_complete(unsigned long calling_rec, > + unsigned long target_rec) > +{ > + struct arm_smccc_res res; > + > + arm_smccc_1_1_invoke(SMC_RMI_PSCI_COMPLETE, calling_rec, target_rec, > + &res); > + > + return res.a0; > +} > + > +static inline int rmi_realm_activate(unsigned long rd) > +{ > + struct arm_smccc_res res; > + > + arm_smccc_1_1_invoke(SMC_RMI_REALM_ACTIVATE, rd, &res); > + > + return res.a0; > +} > + > +static inline int rmi_realm_create(unsigned long rd, unsigned long params_ptr) > +{ > + struct arm_smccc_res res; > + > + arm_smccc_1_1_invoke(SMC_RMI_REALM_CREATE, rd, params_ptr, &res); > + > + return res.a0; > +} > + > +static inline int rmi_realm_destroy(unsigned long rd) > +{ > + struct arm_smccc_res res; > + > + arm_smccc_1_1_invoke(SMC_RMI_REALM_DESTROY, rd, &res); > + > + return res.a0; > +} > + > +static inline int rmi_rec_aux_count(unsigned long rd, unsigned long *aux_count) > +{ > + struct arm_smccc_res res; > + > + arm_smccc_1_1_invoke(SMC_RMI_REC_AUX_COUNT, rd, &res); > + > + *aux_count = res.a1; > + return res.a0; > +} > + > +static inline int rmi_rec_create(unsigned long rec, unsigned long rd, > + unsigned long params_ptr) > +{ > + struct arm_smccc_res res; > + > + arm_smccc_1_1_invoke(SMC_RMI_REC_CREATE, rec, rd, params_ptr, &res); > + > + return res.a0; > +} > + > +static inline int rmi_rec_destroy(unsigned long rec) > +{ > + struct arm_smccc_res res; > + > + arm_smccc_1_1_invoke(SMC_RMI_REC_DESTROY, rec, &res); > + > + return res.a0; > +} > + > +static inline int rmi_rec_enter(unsigned long rec, unsigned long run_ptr) > +{ > + struct arm_smccc_res res; > + > + arm_smccc_1_1_invoke(SMC_RMI_REC_ENTER, rec, run_ptr, &res); > + > + return res.a0; > +} > + > +static inline int rmi_rtt_create(unsigned long rtt, unsigned long rd, > + unsigned long map_addr, unsigned long level) > +{ > + struct arm_smccc_res res; > + > + arm_smccc_1_1_invoke(SMC_RMI_RTT_CREATE, rtt, rd, map_addr, level, > + &res); > + > + return res.a0; > +} > + > +static inline int rmi_rtt_destroy(unsigned long rtt, unsigned long rd, > + unsigned long map_addr, unsigned long level) > +{ > + struct arm_smccc_res res; > + > + arm_smccc_1_1_invoke(SMC_RMI_RTT_DESTROY, rtt, rd, map_addr, level, > + &res); > + > + return res.a0; > +} > + > +static inline int rmi_rtt_fold(unsigned long rtt, unsigned long rd, > + unsigned long map_addr, unsigned long level) > +{ > + struct arm_smccc_res res; > + > + arm_smccc_1_1_invoke(SMC_RMI_RTT_FOLD, rtt, rd, map_addr, level, &res); > + > + return res.a0; > +} > + > +static inline int rmi_rtt_init_ripas(unsigned long rd, unsigned long map_addr, > + unsigned long level) > +{ > + struct arm_smccc_res res; > + > + arm_smccc_1_1_invoke(SMC_RMI_RTT_INIT_RIPAS, rd, map_addr, level, &res); > + > + return res.a0; > +} > + > +static inline int rmi_rtt_map_unprotected(unsigned long rd, > + unsigned long map_addr, > + unsigned long level, > + unsigned long desc) > +{ > + struct arm_smccc_res res; > + > + arm_smccc_1_1_invoke(SMC_RMI_RTT_MAP_UNPROTECTED, rd, map_addr, level, > + desc, &res); > + > + return res.a0; > +} > + > +static inline int rmi_rtt_read_entry(unsigned long rd, unsigned long map_addr, > + unsigned long level, struct rtt_entry *rtt) > +{ > + struct arm_smccc_1_2_regs regs = { > + SMC_RMI_RTT_READ_ENTRY, > + rd, map_addr, level > + }; > + > + arm_smccc_1_2_smc(®s, ®s); > + > + rtt->walk_level = regs.a1; > + rtt->state = regs.a2 & 0xFF; > + rtt->desc = regs.a3; > + rtt->ripas = regs.a4 & 1; > + > + return regs.a0; > +} > + > +static inline int rmi_rtt_set_ripas(unsigned long rd, unsigned long rec, > + unsigned long map_addr, unsigned long level, > + unsigned long ripas) > +{ > + struct arm_smccc_res res; > + > + arm_smccc_1_1_invoke(SMC_RMI_RTT_SET_RIPAS, rd, rec, map_addr, level, > + ripas, &res); > + > + return res.a0; > +} > + > +static inline int rmi_rtt_unmap_unprotected(unsigned long rd, > + unsigned long map_addr, > + unsigned long level) > +{ > + struct arm_smccc_res res; > + > + arm_smccc_1_1_invoke(SMC_RMI_RTT_UNMAP_UNPROTECTED, rd, map_addr, > + level, &res); > + > + return res.a0; > +} > + > +static inline phys_addr_t rmi_rtt_get_phys(struct rtt_entry *rtt) > +{ > + return rtt->desc & GENMASK(47, 12); > +} > + > +#endif
Hi Steven, On 27-01-2023 04:59 pm, Steven Price wrote: > The wrappers make the call sites easier to read and deal with the > boiler plate of handling the error codes from the RMM. > > Signed-off-by: Steven Price <steven.price@arm.com> > --- > arch/arm64/include/asm/rmi_cmds.h | 259 ++++++++++++++++++++++++++++++ > 1 file changed, 259 insertions(+) > create mode 100644 arch/arm64/include/asm/rmi_cmds.h > > diff --git a/arch/arm64/include/asm/rmi_cmds.h b/arch/arm64/include/asm/rmi_cmds.h > new file mode 100644 > index 000000000000..d5468ee46f35 > --- /dev/null > +++ b/arch/arm64/include/asm/rmi_cmds.h > @@ -0,0 +1,259 @@ > +/* SPDX-License-Identifier: GPL-2.0 */ > +/* > + * Copyright (C) 2023 ARM Ltd. > + */ > + > +#ifndef __ASM_RMI_CMDS_H > +#define __ASM_RMI_CMDS_H > + > +#include <linux/arm-smccc.h> > + > +#include <asm/rmi_smc.h> > + > +struct rtt_entry { > + unsigned long walk_level; > + unsigned long desc; > + int state; > + bool ripas; > +}; > + > +static inline int rmi_data_create(unsigned long data, unsigned long rd, > + unsigned long map_addr, unsigned long src, > + unsigned long flags) > +{ > + struct arm_smccc_res res; > + > + arm_smccc_1_1_invoke(SMC_RMI_DATA_CREATE, data, rd, map_addr, src, > + flags, &res); > + > + return res.a0; > +} > + > +static inline int rmi_data_create_unknown(unsigned long data, > + unsigned long rd, > + unsigned long map_addr) > +{ > + struct arm_smccc_res res; > + > + arm_smccc_1_1_invoke(SMC_RMI_DATA_CREATE_UNKNOWN, data, rd, map_addr, > + &res); > + > + return res.a0; > +} > + > +static inline int rmi_data_destroy(unsigned long rd, unsigned long map_addr) > +{ > + struct arm_smccc_res res; > + > + arm_smccc_1_1_invoke(SMC_RMI_DATA_DESTROY, rd, map_addr, &res); > + > + return res.a0; > +} > + > +static inline int rmi_features(unsigned long index, unsigned long *out) > +{ > + struct arm_smccc_res res; > + > + arm_smccc_1_1_invoke(SMC_RMI_FEATURES, index, &res); > + > + *out = res.a1; > + return res.a0; > +} > + > +static inline int rmi_granule_delegate(unsigned long phys) > +{ > + struct arm_smccc_res res; > + > + arm_smccc_1_1_invoke(SMC_RMI_GRANULE_DELEGATE, phys, &res); > + > + return res.a0; > +} > + > +static inline int rmi_granule_undelegate(unsigned long phys) > +{ > + struct arm_smccc_res res; > + > + arm_smccc_1_1_invoke(SMC_RMI_GRANULE_UNDELEGATE, phys, &res); > + > + return res.a0; > +} > + > +static inline int rmi_psci_complete(unsigned long calling_rec, > + unsigned long target_rec) > +{ > + struct arm_smccc_res res; > + > + arm_smccc_1_1_invoke(SMC_RMI_PSCI_COMPLETE, calling_rec, target_rec, > + &res); > + > + return res.a0; > +} > + > +static inline int rmi_realm_activate(unsigned long rd) > +{ > + struct arm_smccc_res res; > + > + arm_smccc_1_1_invoke(SMC_RMI_REALM_ACTIVATE, rd, &res); > + > + return res.a0; > +} > + > +static inline int rmi_realm_create(unsigned long rd, unsigned long params_ptr) > +{ > + struct arm_smccc_res res; > + > + arm_smccc_1_1_invoke(SMC_RMI_REALM_CREATE, rd, params_ptr, &res); > + > + return res.a0; > +} > + > +static inline int rmi_realm_destroy(unsigned long rd) > +{ > + struct arm_smccc_res res; > + > + arm_smccc_1_1_invoke(SMC_RMI_REALM_DESTROY, rd, &res); > + > + return res.a0; > +} > + > +static inline int rmi_rec_aux_count(unsigned long rd, unsigned long *aux_count) > +{ > + struct arm_smccc_res res; > + > + arm_smccc_1_1_invoke(SMC_RMI_REC_AUX_COUNT, rd, &res); > + > + *aux_count = res.a1; > + return res.a0; > +} > + > +static inline int rmi_rec_create(unsigned long rec, unsigned long rd, > + unsigned long params_ptr) > +{ > + struct arm_smccc_res res; > + > + arm_smccc_1_1_invoke(SMC_RMI_REC_CREATE, rec, rd, params_ptr, &res); > + > + return res.a0; > +} > + > +static inline int rmi_rec_destroy(unsigned long rec) > +{ > + struct arm_smccc_res res; > + > + arm_smccc_1_1_invoke(SMC_RMI_REC_DESTROY, rec, &res); > + > + return res.a0; > +} > + > +static inline int rmi_rec_enter(unsigned long rec, unsigned long run_ptr) > +{ > + struct arm_smccc_res res; > + > + arm_smccc_1_1_invoke(SMC_RMI_REC_ENTER, rec, run_ptr, &res); > + > + return res.a0; > +} > + > +static inline int rmi_rtt_create(unsigned long rtt, unsigned long rd, > + unsigned long map_addr, unsigned long level) > +{ > + struct arm_smccc_res res; > + > + arm_smccc_1_1_invoke(SMC_RMI_RTT_CREATE, rtt, rd, map_addr, level, > + &res); > + > + return res.a0; > +} > + > +static inline int rmi_rtt_destroy(unsigned long rtt, unsigned long rd, > + unsigned long map_addr, unsigned long level) > +{ > + struct arm_smccc_res res; > + > + arm_smccc_1_1_invoke(SMC_RMI_RTT_DESTROY, rtt, rd, map_addr, level, > + &res); > + > + return res.a0; > +} > + > +static inline int rmi_rtt_fold(unsigned long rtt, unsigned long rd, > + unsigned long map_addr, unsigned long level) > +{ > + struct arm_smccc_res res; > + > + arm_smccc_1_1_invoke(SMC_RMI_RTT_FOLD, rtt, rd, map_addr, level, &res); > + > + return res.a0; > +} > + > +static inline int rmi_rtt_init_ripas(unsigned long rd, unsigned long map_addr, > + unsigned long level) > +{ > + struct arm_smccc_res res; > + > + arm_smccc_1_1_invoke(SMC_RMI_RTT_INIT_RIPAS, rd, map_addr, level, &res); > + > + return res.a0; > +} > + > +static inline int rmi_rtt_map_unprotected(unsigned long rd, > + unsigned long map_addr, > + unsigned long level, > + unsigned long desc) > +{ > + struct arm_smccc_res res; > + > + arm_smccc_1_1_invoke(SMC_RMI_RTT_MAP_UNPROTECTED, rd, map_addr, level, > + desc, &res); > + > + return res.a0; > +} > + > +static inline int rmi_rtt_read_entry(unsigned long rd, unsigned long map_addr, > + unsigned long level, struct rtt_entry *rtt) > +{ > + struct arm_smccc_1_2_regs regs = { > + SMC_RMI_RTT_READ_ENTRY, > + rd, map_addr, level > + }; > + > + arm_smccc_1_2_smc(®s, ®s); > + > + rtt->walk_level = regs.a1; > + rtt->state = regs.a2 & 0xFF; > + rtt->desc = regs.a3; > + rtt->ripas = regs.a4 & 1; > + > + return regs.a0; > +} > + > +static inline int rmi_rtt_set_ripas(unsigned long rd, unsigned long rec, > + unsigned long map_addr, unsigned long level, > + unsigned long ripas) > +{ > + struct arm_smccc_res res; > + > + arm_smccc_1_1_invoke(SMC_RMI_RTT_SET_RIPAS, rd, rec, map_addr, level, > + ripas, &res); > + > + return res.a0; > +} > + > +static inline int rmi_rtt_unmap_unprotected(unsigned long rd, > + unsigned long map_addr, > + unsigned long level) > +{ > + struct arm_smccc_res res; > + > + arm_smccc_1_1_invoke(SMC_RMI_RTT_UNMAP_UNPROTECTED, rd, map_addr, > + level, &res); > + > + return res.a0; > +} > + > +static inline phys_addr_t rmi_rtt_get_phys(struct rtt_entry *rtt) > +{ > + return rtt->desc & GENMASK(47, 12); > +} > + > +#endif Can we please replace all occurrence of "unsigned long" with u64? Also as per spec, RTT level is Int64, can we change accordingly? Please CC me in future cca patch-sets. gankulkarni@os.amperecomputing.com Thanks, Ganapat
On 18/03/2024 07:03, Ganapatrao Kulkarni wrote: > > Hi Steven, > > On 27-01-2023 04:59 pm, Steven Price wrote: >> The wrappers make the call sites easier to read and deal with the >> boiler plate of handling the error codes from the RMM. >> >> Signed-off-by: Steven Price <steven.price@arm.com> >> --- >> arch/arm64/include/asm/rmi_cmds.h | 259 ++++++++++++++++++++++++++++++ >> 1 file changed, 259 insertions(+) >> create mode 100644 arch/arm64/include/asm/rmi_cmds.h >> >> diff --git a/arch/arm64/include/asm/rmi_cmds.h >> b/arch/arm64/include/asm/rmi_cmds.h >> new file mode 100644 >> index 000000000000..d5468ee46f35 >> --- /dev/null >> +++ b/arch/arm64/include/asm/rmi_cmds.h [...] >> +static inline int rmi_rtt_read_entry(unsigned long rd, unsigned long >> map_addr, >> + unsigned long level, struct rtt_entry *rtt) >> +{ >> + struct arm_smccc_1_2_regs regs = { >> + SMC_RMI_RTT_READ_ENTRY, >> + rd, map_addr, level >> + }; >> + >> + arm_smccc_1_2_smc(®s, ®s); >> + >> + rtt->walk_level = regs.a1; >> + rtt->state = regs.a2 & 0xFF; >> + rtt->desc = regs.a3; >> + rtt->ripas = regs.a4 & 1; >> + >> + return regs.a0; >> +} >> + >> +static inline int rmi_rtt_set_ripas(unsigned long rd, unsigned long rec, >> + unsigned long map_addr, unsigned long level, >> + unsigned long ripas) >> +{ >> + struct arm_smccc_res res; >> + >> + arm_smccc_1_1_invoke(SMC_RMI_RTT_SET_RIPAS, rd, rec, map_addr, >> level, >> + ripas, &res); >> + >> + return res.a0; >> +} >> + >> +static inline int rmi_rtt_unmap_unprotected(unsigned long rd, >> + unsigned long map_addr, >> + unsigned long level) >> +{ >> + struct arm_smccc_res res; >> + >> + arm_smccc_1_1_invoke(SMC_RMI_RTT_UNMAP_UNPROTECTED, rd, map_addr, >> + level, &res); >> + >> + return res.a0; >> +} >> + >> +static inline phys_addr_t rmi_rtt_get_phys(struct rtt_entry *rtt) >> +{ >> + return rtt->desc & GENMASK(47, 12); >> +} >> + >> +#endif > > Can we please replace all occurrence of "unsigned long" with u64? I'm conflicted here. On the one hand I agree with you - it would be better to use types that are sized according to the RMM spec. However, this file is a thin wrapper around the low-level SMC calls, and the SMCCC interface is a bunch of "unsigned longs" (e.g. look at struct arm_smccc_1_2_regs). In particular it could be broken to use smaller types (e.g. char/u8) as it would potentially permit the compiler to leave 'junk' in the top part of the register. So the question becomes whether to stick with the SMCCC interface sizes (unsigned long) or use our knowledge that it must be a 64 bit platform (RMM isn't support for 32 bit) and therefore use u64. My (mild) preference is for unsigned long because it makes it obvious how this relates to the SMCCC interface it's using. It also seems like it would ease compatibility if (/when?) 128 bit registers become a thing. > Also as per spec, RTT level is Int64, can we change accordingly? Here, however, I agree you've definitely got a point. level should be signed as (at least in theory) it could be negative. > Please CC me in future cca patch-sets. > gankulkarni@os.amperecomputing.com I will do, thanks for the review. Steve
diff --git a/arch/arm64/include/asm/rmi_cmds.h b/arch/arm64/include/asm/rmi_cmds.h new file mode 100644 index 000000000000..d5468ee46f35 --- /dev/null +++ b/arch/arm64/include/asm/rmi_cmds.h @@ -0,0 +1,259 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (C) 2023 ARM Ltd. + */ + +#ifndef __ASM_RMI_CMDS_H +#define __ASM_RMI_CMDS_H + +#include <linux/arm-smccc.h> + +#include <asm/rmi_smc.h> + +struct rtt_entry { + unsigned long walk_level; + unsigned long desc; + int state; + bool ripas; +}; + +static inline int rmi_data_create(unsigned long data, unsigned long rd, + unsigned long map_addr, unsigned long src, + unsigned long flags) +{ + struct arm_smccc_res res; + + arm_smccc_1_1_invoke(SMC_RMI_DATA_CREATE, data, rd, map_addr, src, + flags, &res); + + return res.a0; +} + +static inline int rmi_data_create_unknown(unsigned long data, + unsigned long rd, + unsigned long map_addr) +{ + struct arm_smccc_res res; + + arm_smccc_1_1_invoke(SMC_RMI_DATA_CREATE_UNKNOWN, data, rd, map_addr, + &res); + + return res.a0; +} + +static inline int rmi_data_destroy(unsigned long rd, unsigned long map_addr) +{ + struct arm_smccc_res res; + + arm_smccc_1_1_invoke(SMC_RMI_DATA_DESTROY, rd, map_addr, &res); + + return res.a0; +} + +static inline int rmi_features(unsigned long index, unsigned long *out) +{ + struct arm_smccc_res res; + + arm_smccc_1_1_invoke(SMC_RMI_FEATURES, index, &res); + + *out = res.a1; + return res.a0; +} + +static inline int rmi_granule_delegate(unsigned long phys) +{ + struct arm_smccc_res res; + + arm_smccc_1_1_invoke(SMC_RMI_GRANULE_DELEGATE, phys, &res); + + return res.a0; +} + +static inline int rmi_granule_undelegate(unsigned long phys) +{ + struct arm_smccc_res res; + + arm_smccc_1_1_invoke(SMC_RMI_GRANULE_UNDELEGATE, phys, &res); + + return res.a0; +} + +static inline int rmi_psci_complete(unsigned long calling_rec, + unsigned long target_rec) +{ + struct arm_smccc_res res; + + arm_smccc_1_1_invoke(SMC_RMI_PSCI_COMPLETE, calling_rec, target_rec, + &res); + + return res.a0; +} + +static inline int rmi_realm_activate(unsigned long rd) +{ + struct arm_smccc_res res; + + arm_smccc_1_1_invoke(SMC_RMI_REALM_ACTIVATE, rd, &res); + + return res.a0; +} + +static inline int rmi_realm_create(unsigned long rd, unsigned long params_ptr) +{ + struct arm_smccc_res res; + + arm_smccc_1_1_invoke(SMC_RMI_REALM_CREATE, rd, params_ptr, &res); + + return res.a0; +} + +static inline int rmi_realm_destroy(unsigned long rd) +{ + struct arm_smccc_res res; + + arm_smccc_1_1_invoke(SMC_RMI_REALM_DESTROY, rd, &res); + + return res.a0; +} + +static inline int rmi_rec_aux_count(unsigned long rd, unsigned long *aux_count) +{ + struct arm_smccc_res res; + + arm_smccc_1_1_invoke(SMC_RMI_REC_AUX_COUNT, rd, &res); + + *aux_count = res.a1; + return res.a0; +} + +static inline int rmi_rec_create(unsigned long rec, unsigned long rd, + unsigned long params_ptr) +{ + struct arm_smccc_res res; + + arm_smccc_1_1_invoke(SMC_RMI_REC_CREATE, rec, rd, params_ptr, &res); + + return res.a0; +} + +static inline int rmi_rec_destroy(unsigned long rec) +{ + struct arm_smccc_res res; + + arm_smccc_1_1_invoke(SMC_RMI_REC_DESTROY, rec, &res); + + return res.a0; +} + +static inline int rmi_rec_enter(unsigned long rec, unsigned long run_ptr) +{ + struct arm_smccc_res res; + + arm_smccc_1_1_invoke(SMC_RMI_REC_ENTER, rec, run_ptr, &res); + + return res.a0; +} + +static inline int rmi_rtt_create(unsigned long rtt, unsigned long rd, + unsigned long map_addr, unsigned long level) +{ + struct arm_smccc_res res; + + arm_smccc_1_1_invoke(SMC_RMI_RTT_CREATE, rtt, rd, map_addr, level, + &res); + + return res.a0; +} + +static inline int rmi_rtt_destroy(unsigned long rtt, unsigned long rd, + unsigned long map_addr, unsigned long level) +{ + struct arm_smccc_res res; + + arm_smccc_1_1_invoke(SMC_RMI_RTT_DESTROY, rtt, rd, map_addr, level, + &res); + + return res.a0; +} + +static inline int rmi_rtt_fold(unsigned long rtt, unsigned long rd, + unsigned long map_addr, unsigned long level) +{ + struct arm_smccc_res res; + + arm_smccc_1_1_invoke(SMC_RMI_RTT_FOLD, rtt, rd, map_addr, level, &res); + + return res.a0; +} + +static inline int rmi_rtt_init_ripas(unsigned long rd, unsigned long map_addr, + unsigned long level) +{ + struct arm_smccc_res res; + + arm_smccc_1_1_invoke(SMC_RMI_RTT_INIT_RIPAS, rd, map_addr, level, &res); + + return res.a0; +} + +static inline int rmi_rtt_map_unprotected(unsigned long rd, + unsigned long map_addr, + unsigned long level, + unsigned long desc) +{ + struct arm_smccc_res res; + + arm_smccc_1_1_invoke(SMC_RMI_RTT_MAP_UNPROTECTED, rd, map_addr, level, + desc, &res); + + return res.a0; +} + +static inline int rmi_rtt_read_entry(unsigned long rd, unsigned long map_addr, + unsigned long level, struct rtt_entry *rtt) +{ + struct arm_smccc_1_2_regs regs = { + SMC_RMI_RTT_READ_ENTRY, + rd, map_addr, level + }; + + arm_smccc_1_2_smc(®s, ®s); + + rtt->walk_level = regs.a1; + rtt->state = regs.a2 & 0xFF; + rtt->desc = regs.a3; + rtt->ripas = regs.a4 & 1; + + return regs.a0; +} + +static inline int rmi_rtt_set_ripas(unsigned long rd, unsigned long rec, + unsigned long map_addr, unsigned long level, + unsigned long ripas) +{ + struct arm_smccc_res res; + + arm_smccc_1_1_invoke(SMC_RMI_RTT_SET_RIPAS, rd, rec, map_addr, level, + ripas, &res); + + return res.a0; +} + +static inline int rmi_rtt_unmap_unprotected(unsigned long rd, + unsigned long map_addr, + unsigned long level) +{ + struct arm_smccc_res res; + + arm_smccc_1_1_invoke(SMC_RMI_RTT_UNMAP_UNPROTECTED, rd, map_addr, + level, &res); + + return res.a0; +} + +static inline phys_addr_t rmi_rtt_get_phys(struct rtt_entry *rtt) +{ + return rtt->desc & GENMASK(47, 12); +} + +#endif
The wrappers make the call sites easier to read and deal with the boiler plate of handling the error codes from the RMM. Signed-off-by: Steven Price <steven.price@arm.com> --- arch/arm64/include/asm/rmi_cmds.h | 259 ++++++++++++++++++++++++++++++ 1 file changed, 259 insertions(+) create mode 100644 arch/arm64/include/asm/rmi_cmds.h