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