1 /* 2 * QEMU UFS 3 * 4 * Copyright (c) 2023 Samsung Electronics Co., Ltd. All rights reserved. 5 * 6 * Written by Jeuk Kim <jeuk20.kim@samsung.com> 7 * 8 * SPDX-License-Identifier: GPL-2.0-or-later 9 */ 10 11 #ifndef HW_UFS_UFS_H 12 #define HW_UFS_UFS_H 13 14 #include "hw/pci/pci_device.h" 15 #include "hw/scsi/scsi.h" 16 #include "block/ufs.h" 17 18 #define UFS_MAX_LUS 32 19 #define UFS_BLOCK_SIZE 4096 20 21 typedef struct UfsBusClass { 22 BusClass parent_class; 23 bool (*parent_check_address)(BusState *bus, DeviceState *dev, Error **errp); 24 } UfsBusClass; 25 26 typedef struct UfsBus { 27 SCSIBus parent_bus; 28 } UfsBus; 29 30 #define TYPE_UFS_BUS "ufs-bus" 31 DECLARE_OBJ_CHECKERS(UfsBus, UfsBusClass, UFS_BUS, TYPE_UFS_BUS) 32 33 typedef enum UfsRequestState { 34 UFS_REQUEST_IDLE = 0, 35 UFS_REQUEST_READY = 1, 36 UFS_REQUEST_RUNNING = 2, 37 UFS_REQUEST_COMPLETE = 3, 38 UFS_REQUEST_ERROR = 4, 39 } UfsRequestState; 40 41 typedef enum UfsReqResult { 42 UFS_REQUEST_SUCCESS = 0, 43 UFS_REQUEST_FAIL = 1, 44 UFS_REQUEST_NO_COMPLETE = 2, 45 } UfsReqResult; 46 47 typedef struct UfsRequest { 48 struct UfsHc *hc; 49 UfsRequestState state; 50 int slot; 51 52 UtpTransferReqDesc utrd; 53 UtpUpiuReq req_upiu; 54 UtpUpiuRsp rsp_upiu; 55 56 /* for scsi command */ 57 QEMUSGList *sg; 58 } UfsRequest; 59 60 typedef struct UfsLu { 61 SCSIDevice qdev; 62 uint8_t lun; 63 UnitDescriptor unit_desc; 64 } UfsLu; 65 66 typedef struct UfsWLu { 67 SCSIDevice qdev; 68 uint8_t lun; 69 } UfsWLu; 70 71 typedef struct UfsParams { 72 char *serial; 73 uint8_t nutrs; /* Number of UTP Transfer Request Slots */ 74 uint8_t nutmrs; /* Number of UTP Task Management Request Slots */ 75 } UfsParams; 76 77 typedef struct UfsHc { 78 PCIDevice parent_obj; 79 UfsBus bus; 80 MemoryRegion iomem; 81 UfsReg reg; 82 UfsParams params; 83 uint32_t reg_size; 84 UfsRequest *req_list; 85 86 UfsLu *lus[UFS_MAX_LUS]; 87 UfsWLu *report_wlu; 88 UfsWLu *dev_wlu; 89 UfsWLu *boot_wlu; 90 UfsWLu *rpmb_wlu; 91 DeviceDescriptor device_desc; 92 GeometryDescriptor geometry_desc; 93 Attributes attributes; 94 Flags flags; 95 96 qemu_irq irq; 97 QEMUBH *doorbell_bh; 98 QEMUBH *complete_bh; 99 } UfsHc; 100 101 #define TYPE_UFS "ufs" 102 #define UFS(obj) OBJECT_CHECK(UfsHc, (obj), TYPE_UFS) 103 104 #define TYPE_UFS_LU "ufs-lu" 105 #define UFSLU(obj) OBJECT_CHECK(UfsLu, (obj), TYPE_UFS_LU) 106 107 #define TYPE_UFS_WLU "ufs-wlu" 108 #define UFSWLU(obj) OBJECT_CHECK(UfsWLu, (obj), TYPE_UFS_WLU) 109 110 typedef enum UfsQueryFlagPerm { 111 UFS_QUERY_FLAG_NONE = 0x0, 112 UFS_QUERY_FLAG_READ = 0x1, 113 UFS_QUERY_FLAG_SET = 0x2, 114 UFS_QUERY_FLAG_CLEAR = 0x4, 115 UFS_QUERY_FLAG_TOGGLE = 0x8, 116 } UfsQueryFlagPerm; 117 118 typedef enum UfsQueryAttrPerm { 119 UFS_QUERY_ATTR_NONE = 0x0, 120 UFS_QUERY_ATTR_READ = 0x1, 121 UFS_QUERY_ATTR_WRITE = 0x2, 122 } UfsQueryAttrPerm; 123 124 static inline bool is_wlun(uint8_t lun) 125 { 126 return (lun == UFS_UPIU_REPORT_LUNS_WLUN || 127 lun == UFS_UPIU_UFS_DEVICE_WLUN || lun == UFS_UPIU_BOOT_WLUN || 128 lun == UFS_UPIU_RPMB_WLUN); 129 } 130 131 #endif /* HW_UFS_UFS_H */ 132