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