xref: /qemu/hw/ufs/ufs.h (revision 5e6f3db2)
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