1e7818584SSudeep Holla /* SPDX-License-Identifier: GPL-2.0-only */ 2e7818584SSudeep Holla /* 3e7818584SSudeep Holla * Copyright (C) 2021 ARM Ltd. 4e7818584SSudeep Holla */ 5e7818584SSudeep Holla 6e7818584SSudeep Holla #ifndef _LINUX_ARM_FFA_H 7e7818584SSudeep Holla #define _LINUX_ARM_FFA_H 8e7818584SSudeep Holla 9e7818584SSudeep Holla #include <linux/device.h> 10e7818584SSudeep Holla #include <linux/module.h> 11e7818584SSudeep Holla #include <linux/types.h> 12e7818584SSudeep Holla #include <linux/uuid.h> 13e7818584SSudeep Holla 14e7818584SSudeep Holla /* FFA Bus/Device/Driver related */ 15e7818584SSudeep Holla struct ffa_device { 16e7818584SSudeep Holla int vm_id; 17d0c0bce8SSudeep Holla bool mode_32bit; 18e7818584SSudeep Holla uuid_t uuid; 19e7818584SSudeep Holla struct device dev; 207aa7a979SSudeep Holla const struct ffa_ops *ops; 21e7818584SSudeep Holla }; 22e7818584SSudeep Holla 23e7818584SSudeep Holla #define to_ffa_dev(d) container_of(d, struct ffa_device, dev) 24e7818584SSudeep Holla 25e7818584SSudeep Holla struct ffa_device_id { 26e7818584SSudeep Holla uuid_t uuid; 27e7818584SSudeep Holla }; 28e7818584SSudeep Holla 29e7818584SSudeep Holla struct ffa_driver { 30e7818584SSudeep Holla const char *name; 31e7818584SSudeep Holla int (*probe)(struct ffa_device *sdev); 32e7818584SSudeep Holla void (*remove)(struct ffa_device *sdev); 33e7818584SSudeep Holla const struct ffa_device_id *id_table; 34e7818584SSudeep Holla 35e7818584SSudeep Holla struct device_driver driver; 36e7818584SSudeep Holla }; 37e7818584SSudeep Holla 38e7818584SSudeep Holla #define to_ffa_driver(d) container_of(d, struct ffa_driver, driver) 39e7818584SSudeep Holla 40e7818584SSudeep Holla static inline void ffa_dev_set_drvdata(struct ffa_device *fdev, void *data) 41e7818584SSudeep Holla { 42498af8d1SSudeep Holla dev_set_drvdata(&fdev->dev, data); 43498af8d1SSudeep Holla } 44498af8d1SSudeep Holla 45498af8d1SSudeep Holla static inline void *ffa_dev_get_drvdata(struct ffa_device *fdev) 46498af8d1SSudeep Holla { 47498af8d1SSudeep Holla return dev_get_drvdata(&fdev->dev); 48e7818584SSudeep Holla } 49e7818584SSudeep Holla 50e7818584SSudeep Holla #if IS_REACHABLE(CONFIG_ARM_FFA_TRANSPORT) 51d01387fcSSudeep Holla struct ffa_device *ffa_device_register(const uuid_t *uuid, int vm_id, 527aa7a979SSudeep Holla const struct ffa_ops *ops); 53e7818584SSudeep Holla void ffa_device_unregister(struct ffa_device *ffa_dev); 54e7818584SSudeep Holla int ffa_driver_register(struct ffa_driver *driver, struct module *owner, 55e7818584SSudeep Holla const char *mod_name); 56e7818584SSudeep Holla void ffa_driver_unregister(struct ffa_driver *driver); 57e7818584SSudeep Holla bool ffa_device_is_valid(struct ffa_device *ffa_dev); 58e7818584SSudeep Holla 59e7818584SSudeep Holla #else 60e7818584SSudeep Holla static inline 61d01387fcSSudeep Holla struct ffa_device *ffa_device_register(const uuid_t *uuid, int vm_id, 627aa7a979SSudeep Holla const struct ffa_ops *ops) 63e7818584SSudeep Holla { 64e7818584SSudeep Holla return NULL; 65e7818584SSudeep Holla } 66e7818584SSudeep Holla 67e7818584SSudeep Holla static inline void ffa_device_unregister(struct ffa_device *dev) {} 68e7818584SSudeep Holla 69e7818584SSudeep Holla static inline int 70e7818584SSudeep Holla ffa_driver_register(struct ffa_driver *driver, struct module *owner, 71e7818584SSudeep Holla const char *mod_name) 72e7818584SSudeep Holla { 73e7818584SSudeep Holla return -EINVAL; 74e7818584SSudeep Holla } 75e7818584SSudeep Holla 76e7818584SSudeep Holla static inline void ffa_driver_unregister(struct ffa_driver *driver) {} 77e7818584SSudeep Holla 78e7818584SSudeep Holla static inline 79e7818584SSudeep Holla bool ffa_device_is_valid(struct ffa_device *ffa_dev) { return false; } 80e7818584SSudeep Holla 81e7818584SSudeep Holla #endif /* CONFIG_ARM_FFA_TRANSPORT */ 82e7818584SSudeep Holla 83e7818584SSudeep Holla #define ffa_register(driver) \ 84e7818584SSudeep Holla ffa_driver_register(driver, THIS_MODULE, KBUILD_MODNAME) 85e7818584SSudeep Holla #define ffa_unregister(driver) \ 86e7818584SSudeep Holla ffa_driver_unregister(driver) 87e7818584SSudeep Holla 88e7818584SSudeep Holla /** 89e7818584SSudeep Holla * module_ffa_driver() - Helper macro for registering a psa_ffa driver 90e7818584SSudeep Holla * @__ffa_driver: ffa_driver structure 91e7818584SSudeep Holla * 92e7818584SSudeep Holla * Helper macro for psa_ffa drivers to set up proper module init / exit 93e7818584SSudeep Holla * functions. Replaces module_init() and module_exit() and keeps people from 94e7818584SSudeep Holla * printing pointless things to the kernel log when their driver is loaded. 95e7818584SSudeep Holla */ 96e7818584SSudeep Holla #define module_ffa_driver(__ffa_driver) \ 97e7818584SSudeep Holla module_driver(__ffa_driver, ffa_register, ffa_unregister) 98e7818584SSudeep Holla 99d0c0bce8SSudeep Holla /* FFA transport related */ 100d0c0bce8SSudeep Holla struct ffa_partition_info { 101d0c0bce8SSudeep Holla u16 id; 102d0c0bce8SSudeep Holla u16 exec_ctxt; 103d0c0bce8SSudeep Holla /* partition supports receipt of direct requests */ 104d0c0bce8SSudeep Holla #define FFA_PARTITION_DIRECT_RECV BIT(0) 105d0c0bce8SSudeep Holla /* partition can send direct requests. */ 106d0c0bce8SSudeep Holla #define FFA_PARTITION_DIRECT_SEND BIT(1) 107d0c0bce8SSudeep Holla /* partition can send and receive indirect messages. */ 108d0c0bce8SSudeep Holla #define FFA_PARTITION_INDIRECT_MSG BIT(2) 109d0c0bce8SSudeep Holla u32 properties; 110*bb1be749SSudeep Holla u32 uuid[4]; 111d0c0bce8SSudeep Holla }; 112d0c0bce8SSudeep Holla 113d0c0bce8SSudeep Holla /* For use with FFA_MSG_SEND_DIRECT_{REQ,RESP} which pass data via registers */ 114d0c0bce8SSudeep Holla struct ffa_send_direct_data { 115d0c0bce8SSudeep Holla unsigned long data0; /* w3/x3 */ 116d0c0bce8SSudeep Holla unsigned long data1; /* w4/x4 */ 117d0c0bce8SSudeep Holla unsigned long data2; /* w5/x5 */ 118d0c0bce8SSudeep Holla unsigned long data3; /* w6/x6 */ 119d0c0bce8SSudeep Holla unsigned long data4; /* w7/x7 */ 120d0c0bce8SSudeep Holla }; 121d0c0bce8SSudeep Holla 122cc2195feSSudeep Holla struct ffa_mem_region_addr_range { 123cc2195feSSudeep Holla /* The base IPA of the constituent memory region, aligned to 4 kiB */ 124cc2195feSSudeep Holla u64 address; 125cc2195feSSudeep Holla /* The number of 4 kiB pages in the constituent memory region. */ 126cc2195feSSudeep Holla u32 pg_cnt; 127cc2195feSSudeep Holla u32 reserved; 128cc2195feSSudeep Holla }; 129cc2195feSSudeep Holla 130cc2195feSSudeep Holla struct ffa_composite_mem_region { 131cc2195feSSudeep Holla /* 132cc2195feSSudeep Holla * The total number of 4 kiB pages included in this memory region. This 133cc2195feSSudeep Holla * must be equal to the sum of page counts specified in each 134cc2195feSSudeep Holla * `struct ffa_mem_region_addr_range`. 135cc2195feSSudeep Holla */ 136cc2195feSSudeep Holla u32 total_pg_cnt; 137cc2195feSSudeep Holla /* The number of constituents included in this memory region range */ 138cc2195feSSudeep Holla u32 addr_range_cnt; 139cc2195feSSudeep Holla u64 reserved; 140cc2195feSSudeep Holla /** An array of `addr_range_cnt` memory region constituents. */ 141cc2195feSSudeep Holla struct ffa_mem_region_addr_range constituents[]; 142cc2195feSSudeep Holla }; 143cc2195feSSudeep Holla 144cc2195feSSudeep Holla struct ffa_mem_region_attributes { 145cc2195feSSudeep Holla /* The ID of the VM to which the memory is being given or shared. */ 146cc2195feSSudeep Holla u16 receiver; 147cc2195feSSudeep Holla /* 148cc2195feSSudeep Holla * The permissions with which the memory region should be mapped in the 149cc2195feSSudeep Holla * receiver's page table. 150cc2195feSSudeep Holla */ 151cc2195feSSudeep Holla #define FFA_MEM_EXEC BIT(3) 152cc2195feSSudeep Holla #define FFA_MEM_NO_EXEC BIT(2) 153cc2195feSSudeep Holla #define FFA_MEM_RW BIT(1) 154cc2195feSSudeep Holla #define FFA_MEM_RO BIT(0) 155cc2195feSSudeep Holla u8 attrs; 156cc2195feSSudeep Holla /* 157cc2195feSSudeep Holla * Flags used during FFA_MEM_RETRIEVE_REQ and FFA_MEM_RETRIEVE_RESP 158cc2195feSSudeep Holla * for memory regions with multiple borrowers. 159cc2195feSSudeep Holla */ 160cc2195feSSudeep Holla #define FFA_MEM_RETRIEVE_SELF_BORROWER BIT(0) 161cc2195feSSudeep Holla u8 flag; 162cc2195feSSudeep Holla u32 composite_off; 163cc2195feSSudeep Holla /* 164cc2195feSSudeep Holla * Offset in bytes from the start of the outer `ffa_memory_region` to 165cc2195feSSudeep Holla * an `struct ffa_mem_region_addr_range`. 166cc2195feSSudeep Holla */ 167cc2195feSSudeep Holla u64 reserved; 168cc2195feSSudeep Holla }; 169cc2195feSSudeep Holla 170cc2195feSSudeep Holla struct ffa_mem_region { 171cc2195feSSudeep Holla /* The ID of the VM/owner which originally sent the memory region */ 172cc2195feSSudeep Holla u16 sender_id; 173cc2195feSSudeep Holla #define FFA_MEM_NORMAL BIT(5) 174cc2195feSSudeep Holla #define FFA_MEM_DEVICE BIT(4) 175cc2195feSSudeep Holla 176cc2195feSSudeep Holla #define FFA_MEM_WRITE_BACK (3 << 2) 177cc2195feSSudeep Holla #define FFA_MEM_NON_CACHEABLE (1 << 2) 178cc2195feSSudeep Holla 179cc2195feSSudeep Holla #define FFA_DEV_nGnRnE (0 << 2) 180cc2195feSSudeep Holla #define FFA_DEV_nGnRE (1 << 2) 181cc2195feSSudeep Holla #define FFA_DEV_nGRE (2 << 2) 182cc2195feSSudeep Holla #define FFA_DEV_GRE (3 << 2) 183cc2195feSSudeep Holla 184cc2195feSSudeep Holla #define FFA_MEM_NON_SHAREABLE (0) 185cc2195feSSudeep Holla #define FFA_MEM_OUTER_SHAREABLE (2) 186cc2195feSSudeep Holla #define FFA_MEM_INNER_SHAREABLE (3) 187cc2195feSSudeep Holla u8 attributes; 188cc2195feSSudeep Holla u8 reserved_0; 189cc2195feSSudeep Holla /* 190cc2195feSSudeep Holla * Clear memory region contents after unmapping it from the sender and 191cc2195feSSudeep Holla * before mapping it for any receiver. 192cc2195feSSudeep Holla */ 193cc2195feSSudeep Holla #define FFA_MEM_CLEAR BIT(0) 194cc2195feSSudeep Holla /* 195cc2195feSSudeep Holla * Whether the hypervisor may time slice the memory sharing or retrieval 196cc2195feSSudeep Holla * operation. 197cc2195feSSudeep Holla */ 198cc2195feSSudeep Holla #define FFA_TIME_SLICE_ENABLE BIT(1) 199cc2195feSSudeep Holla 200cc2195feSSudeep Holla #define FFA_MEM_RETRIEVE_TYPE_IN_RESP (0 << 3) 201cc2195feSSudeep Holla #define FFA_MEM_RETRIEVE_TYPE_SHARE (1 << 3) 202cc2195feSSudeep Holla #define FFA_MEM_RETRIEVE_TYPE_LEND (2 << 3) 203cc2195feSSudeep Holla #define FFA_MEM_RETRIEVE_TYPE_DONATE (3 << 3) 204cc2195feSSudeep Holla 205cc2195feSSudeep Holla #define FFA_MEM_RETRIEVE_ADDR_ALIGN_HINT BIT(9) 206cc2195feSSudeep Holla #define FFA_MEM_RETRIEVE_ADDR_ALIGN(x) ((x) << 5) 207cc2195feSSudeep Holla /* Flags to control behaviour of the transaction. */ 208cc2195feSSudeep Holla u32 flags; 209cc2195feSSudeep Holla #define HANDLE_LOW_MASK GENMASK_ULL(31, 0) 210cc2195feSSudeep Holla #define HANDLE_HIGH_MASK GENMASK_ULL(63, 32) 211cc2195feSSudeep Holla #define HANDLE_LOW(x) ((u32)(FIELD_GET(HANDLE_LOW_MASK, (x)))) 212cc2195feSSudeep Holla #define HANDLE_HIGH(x) ((u32)(FIELD_GET(HANDLE_HIGH_MASK, (x)))) 213cc2195feSSudeep Holla 214cc2195feSSudeep Holla #define PACK_HANDLE(l, h) \ 215cc2195feSSudeep Holla (FIELD_PREP(HANDLE_LOW_MASK, (l)) | FIELD_PREP(HANDLE_HIGH_MASK, (h))) 216cc2195feSSudeep Holla /* 217cc2195feSSudeep Holla * A globally-unique ID assigned by the hypervisor for a region 218cc2195feSSudeep Holla * of memory being sent between VMs. 219cc2195feSSudeep Holla */ 220cc2195feSSudeep Holla u64 handle; 221cc2195feSSudeep Holla /* 222cc2195feSSudeep Holla * An implementation defined value associated with the receiver and the 223cc2195feSSudeep Holla * memory region. 224cc2195feSSudeep Holla */ 225cc2195feSSudeep Holla u64 tag; 226cc2195feSSudeep Holla u32 reserved_1; 227cc2195feSSudeep Holla /* 228cc2195feSSudeep Holla * The number of `ffa_mem_region_attributes` entries included in this 229cc2195feSSudeep Holla * transaction. 230cc2195feSSudeep Holla */ 231cc2195feSSudeep Holla u32 ep_count; 232cc2195feSSudeep Holla /* 233cc2195feSSudeep Holla * An array of endpoint memory access descriptors. 234cc2195feSSudeep Holla * Each one specifies a memory region offset, an endpoint and the 235cc2195feSSudeep Holla * attributes with which this memory region should be mapped in that 236cc2195feSSudeep Holla * endpoint's page table. 237cc2195feSSudeep Holla */ 238cc2195feSSudeep Holla struct ffa_mem_region_attributes ep_mem_access[]; 239cc2195feSSudeep Holla }; 240cc2195feSSudeep Holla 241cc2195feSSudeep Holla #define COMPOSITE_OFFSET(x) \ 242cc2195feSSudeep Holla (offsetof(struct ffa_mem_region, ep_mem_access[x])) 243cc2195feSSudeep Holla #define CONSTITUENTS_OFFSET(x) \ 244cc2195feSSudeep Holla (offsetof(struct ffa_composite_mem_region, constituents[x])) 245cc2195feSSudeep Holla #define COMPOSITE_CONSTITUENTS_OFFSET(x, y) \ 246cc2195feSSudeep Holla (COMPOSITE_OFFSET(x) + CONSTITUENTS_OFFSET(y)) 247cc2195feSSudeep Holla 248cc2195feSSudeep Holla struct ffa_mem_ops_args { 249cc2195feSSudeep Holla bool use_txbuf; 250cc2195feSSudeep Holla u32 nattrs; 251cc2195feSSudeep Holla u32 flags; 252cc2195feSSudeep Holla u64 tag; 253cc2195feSSudeep Holla u64 g_handle; 254cc2195feSSudeep Holla struct scatterlist *sg; 255cc2195feSSudeep Holla struct ffa_mem_region_attributes *attrs; 256cc2195feSSudeep Holla }; 257cc2195feSSudeep Holla 2587aa7a979SSudeep Holla struct ffa_ops { 259d0c0bce8SSudeep Holla u32 (*api_version_get)(void); 260d0c0bce8SSudeep Holla int (*partition_info_get)(const char *uuid_str, 261d0c0bce8SSudeep Holla struct ffa_partition_info *buffer); 262d0c0bce8SSudeep Holla void (*mode_32bit_set)(struct ffa_device *dev); 263d0c0bce8SSudeep Holla int (*sync_send_receive)(struct ffa_device *dev, 264d0c0bce8SSudeep Holla struct ffa_send_direct_data *data); 265cc2195feSSudeep Holla int (*memory_reclaim)(u64 g_handle, u32 flags); 2668c3812c8SSudeep Holla int (*memory_share)(struct ffa_mem_ops_args *args); 2678c3812c8SSudeep Holla int (*memory_lend)(struct ffa_mem_ops_args *args); 268d0c0bce8SSudeep Holla }; 269d0c0bce8SSudeep Holla 270e7818584SSudeep Holla #endif /* _LINUX_ARM_FFA_H */ 271