xref: /qemu/include/block/ufs.h (revision 5db05230)
1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2 
3 #ifndef BLOCK_UFS_H
4 #define BLOCK_UFS_H
5 
6 #include "hw/registerfields.h"
7 
8 typedef struct QEMU_PACKED UfsReg {
9     uint32_t cap;
10     uint32_t rsvd0;
11     uint32_t ver;
12     uint32_t rsvd1;
13     uint32_t hcpid;
14     uint32_t hcmid;
15     uint32_t ahit;
16     uint32_t rsvd2;
17     uint32_t is;
18     uint32_t ie;
19     uint32_t rsvd3[2];
20     uint32_t hcs;
21     uint32_t hce;
22     uint32_t uecpa;
23     uint32_t uecdl;
24     uint32_t uecn;
25     uint32_t uect;
26     uint32_t uecdme;
27     uint32_t utriacr;
28     uint32_t utrlba;
29     uint32_t utrlbau;
30     uint32_t utrldbr;
31     uint32_t utrlclr;
32     uint32_t utrlrsr;
33     uint32_t utrlcnr;
34     uint32_t rsvd4[2];
35     uint32_t utmrlba;
36     uint32_t utmrlbau;
37     uint32_t utmrldbr;
38     uint32_t utmrlclr;
39     uint32_t utmrlrsr;
40     uint32_t rsvd5[3];
41     uint32_t uiccmd;
42     uint32_t ucmdarg1;
43     uint32_t ucmdarg2;
44     uint32_t ucmdarg3;
45     uint32_t rsvd6[4];
46     uint32_t rsvd7[4];
47     uint32_t rsvd8[16];
48     uint32_t ccap;
49 } UfsReg;
50 
51 REG32(CAP, offsetof(UfsReg, cap))
52     FIELD(CAP, NUTRS, 0, 5)
53     FIELD(CAP, RTT, 8, 8)
54     FIELD(CAP, NUTMRS, 16, 3)
55     FIELD(CAP, AUTOH8, 23, 1)
56     FIELD(CAP, 64AS, 24, 1)
57     FIELD(CAP, OODDS, 25, 1)
58     FIELD(CAP, UICDMETMS, 26, 1)
59     FIELD(CAP, CS, 28, 1)
60 REG32(VER, offsetof(UfsReg, ver))
61 REG32(HCPID, offsetof(UfsReg, hcpid))
62 REG32(HCMID, offsetof(UfsReg, hcmid))
63 REG32(AHIT, offsetof(UfsReg, ahit))
64 REG32(IS, offsetof(UfsReg, is))
65     FIELD(IS, UTRCS, 0, 1)
66     FIELD(IS, UDEPRI, 1, 1)
67     FIELD(IS, UE, 2, 1)
68     FIELD(IS, UTMS, 3, 1)
69     FIELD(IS, UPMS, 4, 1)
70     FIELD(IS, UHXS, 5, 1)
71     FIELD(IS, UHES, 6, 1)
72     FIELD(IS, ULLS, 7, 1)
73     FIELD(IS, ULSS, 8, 1)
74     FIELD(IS, UTMRCS, 9, 1)
75     FIELD(IS, UCCS, 10, 1)
76     FIELD(IS, DFES, 11, 1)
77     FIELD(IS, UTPES, 12, 1)
78     FIELD(IS, HCFES, 16, 1)
79     FIELD(IS, SBFES, 17, 1)
80     FIELD(IS, CEFES, 18, 1)
81 REG32(IE, offsetof(UfsReg, ie))
82     FIELD(IE, UTRCE, 0, 1)
83     FIELD(IE, UDEPRIE, 1, 1)
84     FIELD(IE, UEE, 2, 1)
85     FIELD(IE, UTMSE, 3, 1)
86     FIELD(IE, UPMSE, 4, 1)
87     FIELD(IE, UHXSE, 5, 1)
88     FIELD(IE, UHESE, 6, 1)
89     FIELD(IE, ULLSE, 7, 1)
90     FIELD(IE, ULSSE, 8, 1)
91     FIELD(IE, UTMRCE, 9, 1)
92     FIELD(IE, UCCE, 10, 1)
93     FIELD(IE, DFEE, 11, 1)
94     FIELD(IE, UTPEE, 12, 1)
95     FIELD(IE, HCFEE, 16, 1)
96     FIELD(IE, SBFEE, 17, 1)
97     FIELD(IE, CEFEE, 18, 1)
98 REG32(HCS, offsetof(UfsReg, hcs))
99     FIELD(HCS, DP, 0, 1)
100     FIELD(HCS, UTRLRDY, 1, 1)
101     FIELD(HCS, UTMRLRDY, 2, 1)
102     FIELD(HCS, UCRDY, 3, 1)
103     FIELD(HCS, UPMCRS, 8, 3)
104 REG32(HCE, offsetof(UfsReg, hce))
105     FIELD(HCE, HCE, 0, 1)
106     FIELD(HCE, CGE, 1, 1)
107 REG32(UECPA, offsetof(UfsReg, uecpa))
108 REG32(UECDL, offsetof(UfsReg, uecdl))
109 REG32(UECN, offsetof(UfsReg, uecn))
110 REG32(UECT, offsetof(UfsReg, uect))
111 REG32(UECDME, offsetof(UfsReg, uecdme))
112 REG32(UTRIACR, offsetof(UfsReg, utriacr))
113 REG32(UTRLBA, offsetof(UfsReg, utrlba))
114     FIELD(UTRLBA, UTRLBA, 10, 22)
115 REG32(UTRLBAU, offsetof(UfsReg, utrlbau))
116 REG32(UTRLDBR, offsetof(UfsReg, utrldbr))
117 REG32(UTRLCLR, offsetof(UfsReg, utrlclr))
118 REG32(UTRLRSR, offsetof(UfsReg, utrlrsr))
119 REG32(UTRLCNR, offsetof(UfsReg, utrlcnr))
120 REG32(UTMRLBA, offsetof(UfsReg, utmrlba))
121     FIELD(UTMRLBA, UTMRLBA, 10, 22)
122 REG32(UTMRLBAU, offsetof(UfsReg, utmrlbau))
123 REG32(UTMRLDBR, offsetof(UfsReg, utmrldbr))
124 REG32(UTMRLCLR, offsetof(UfsReg, utmrlclr))
125 REG32(UTMRLRSR, offsetof(UfsReg, utmrlrsr))
126 REG32(UICCMD, offsetof(UfsReg, uiccmd))
127 REG32(UCMDARG1, offsetof(UfsReg, ucmdarg1))
128 REG32(UCMDARG2, offsetof(UfsReg, ucmdarg2))
129 REG32(UCMDARG3, offsetof(UfsReg, ucmdarg3))
130 REG32(CCAP, offsetof(UfsReg, ccap))
131 
132 #define UFS_INTR_MASK                                    \
133     ((1 << R_IS_CEFES_SHIFT) | (1 << R_IS_SBFES_SHIFT) | \
134      (1 << R_IS_HCFES_SHIFT) | (1 << R_IS_UTPES_SHIFT) | \
135      (1 << R_IS_DFES_SHIFT) | (1 << R_IS_UCCS_SHIFT) |   \
136      (1 << R_IS_UTMRCS_SHIFT) | (1 << R_IS_ULSS_SHIFT) | \
137      (1 << R_IS_ULLS_SHIFT) | (1 << R_IS_UHES_SHIFT) |   \
138      (1 << R_IS_UHXS_SHIFT) | (1 << R_IS_UPMS_SHIFT) |   \
139      (1 << R_IS_UTMS_SHIFT) | (1 << R_IS_UE_SHIFT) |     \
140      (1 << R_IS_UDEPRI_SHIFT) | (1 << R_IS_UTRCS_SHIFT))
141 
142 #define UFS_UPIU_HEADER_TRANSACTION_TYPE_SHIFT 24
143 #define UFS_UPIU_HEADER_TRANSACTION_TYPE_MASK 0xff
144 #define UFS_UPIU_HEADER_TRANSACTION_TYPE(dword0)                       \
145     ((be32_to_cpu(dword0) >> UFS_UPIU_HEADER_TRANSACTION_TYPE_SHIFT) & \
146      UFS_UPIU_HEADER_TRANSACTION_TYPE_MASK)
147 
148 #define UFS_UPIU_HEADER_QUERY_FUNC_SHIFT 16
149 #define UFS_UPIU_HEADER_QUERY_FUNC_MASK 0xff
150 #define UFS_UPIU_HEADER_QUERY_FUNC(dword1)                       \
151     ((be32_to_cpu(dword1) >> UFS_UPIU_HEADER_QUERY_FUNC_SHIFT) & \
152      UFS_UPIU_HEADER_QUERY_FUNC_MASK)
153 
154 #define UFS_UPIU_HEADER_DATA_SEGMENT_LENGTH_SHIFT 0
155 #define UFS_UPIU_HEADER_DATA_SEGMENT_LENGTH_MASK 0xffff
156 #define UFS_UPIU_HEADER_DATA_SEGMENT_LENGTH(dword2)                       \
157     ((be32_to_cpu(dword2) >> UFS_UPIU_HEADER_DATA_SEGMENT_LENGTH_SHIFT) & \
158      UFS_UPIU_HEADER_DATA_SEGMENT_LENGTH_MASK)
159 
160 typedef struct QEMU_PACKED DeviceDescriptor {
161     uint8_t length;
162     uint8_t descriptor_idn;
163     uint8_t device;
164     uint8_t device_class;
165     uint8_t device_sub_class;
166     uint8_t protocol;
167     uint8_t number_lu;
168     uint8_t number_wlu;
169     uint8_t boot_enable;
170     uint8_t descr_access_en;
171     uint8_t init_power_mode;
172     uint8_t high_priority_lun;
173     uint8_t secure_removal_type;
174     uint8_t security_lu;
175     uint8_t background_ops_term_lat;
176     uint8_t init_active_icc_level;
177     uint16_t spec_version;
178     uint16_t manufacture_date;
179     uint8_t manufacturer_name;
180     uint8_t product_name;
181     uint8_t serial_number;
182     uint8_t oem_id;
183     uint16_t manufacturer_id;
184     uint8_t ud_0_base_offset;
185     uint8_t ud_config_p_length;
186     uint8_t device_rtt_cap;
187     uint16_t periodic_rtc_update;
188     uint8_t ufs_features_support;
189     uint8_t ffu_timeout;
190     uint8_t queue_depth;
191     uint16_t device_version;
192     uint8_t num_secure_wp_area;
193     uint32_t psa_max_data_size;
194     uint8_t psa_state_timeout;
195     uint8_t product_revision_level;
196     uint8_t reserved[36];
197     uint32_t extended_ufs_features_support;
198     uint8_t write_booster_buffer_preserve_user_space_en;
199     uint8_t write_booster_buffer_type;
200     uint32_t num_shared_write_booster_buffer_alloc_units;
201 } DeviceDescriptor;
202 
203 typedef struct QEMU_PACKED GeometryDescriptor {
204     uint8_t length;
205     uint8_t descriptor_idn;
206     uint8_t media_technology;
207     uint8_t reserved;
208     uint64_t total_raw_device_capacity;
209     uint8_t max_number_lu;
210     uint32_t segment_size;
211     uint8_t allocation_unit_size;
212     uint8_t min_addr_block_size;
213     uint8_t optimal_read_block_size;
214     uint8_t optimal_write_block_size;
215     uint8_t max_in_buffer_size;
216     uint8_t max_out_buffer_size;
217     uint8_t rpmb_read_write_size;
218     uint8_t dynamic_capacity_resource_policy;
219     uint8_t data_ordering;
220     uint8_t max_context_id_number;
221     uint8_t sys_data_tag_unit_size;
222     uint8_t sys_data_tag_res_size;
223     uint8_t supported_sec_r_types;
224     uint16_t supported_memory_types;
225     uint32_t system_code_max_n_alloc_u;
226     uint16_t system_code_cap_adj_fac;
227     uint32_t non_persist_max_n_alloc_u;
228     uint16_t non_persist_cap_adj_fac;
229     uint32_t enhanced_1_max_n_alloc_u;
230     uint16_t enhanced_1_cap_adj_fac;
231     uint32_t enhanced_2_max_n_alloc_u;
232     uint16_t enhanced_2_cap_adj_fac;
233     uint32_t enhanced_3_max_n_alloc_u;
234     uint16_t enhanced_3_cap_adj_fac;
235     uint32_t enhanced_4_max_n_alloc_u;
236     uint16_t enhanced_4_cap_adj_fac;
237     uint32_t optimal_logical_block_size;
238     uint8_t reserved2[7];
239     uint32_t write_booster_buffer_max_n_alloc_units;
240     uint8_t device_max_write_booster_l_us;
241     uint8_t write_booster_buffer_cap_adj_fac;
242     uint8_t supported_write_booster_buffer_user_space_reduction_types;
243     uint8_t supported_write_booster_buffer_types;
244 } GeometryDescriptor;
245 
246 #define UFS_GEOMETRY_CAPACITY_SHIFT 9
247 
248 typedef struct QEMU_PACKED UnitDescriptor {
249     uint8_t length;
250     uint8_t descriptor_idn;
251     uint8_t unit_index;
252     uint8_t lu_enable;
253     uint8_t boot_lun_id;
254     uint8_t lu_write_protect;
255     uint8_t lu_queue_depth;
256     uint8_t psa_sensitive;
257     uint8_t memory_type;
258     uint8_t data_reliability;
259     uint8_t logical_block_size;
260     uint64_t logical_block_count;
261     uint32_t erase_block_size;
262     uint8_t provisioning_type;
263     uint64_t phy_mem_resource_count;
264     uint16_t context_capabilities;
265     uint8_t large_unit_granularity_m1;
266     uint8_t reserved[6];
267     uint32_t lu_num_write_booster_buffer_alloc_units;
268 } UnitDescriptor;
269 
270 typedef struct QEMU_PACKED RpmbUnitDescriptor {
271     uint8_t length;
272     uint8_t descriptor_idn;
273     uint8_t unit_index;
274     uint8_t lu_enable;
275     uint8_t boot_lun_id;
276     uint8_t lu_write_protect;
277     uint8_t lu_queue_depth;
278     uint8_t psa_sensitive;
279     uint8_t memory_type;
280     uint8_t reserved;
281     uint8_t logical_block_size;
282     uint64_t logical_block_count;
283     uint32_t erase_block_size;
284     uint8_t provisioning_type;
285     uint64_t phy_mem_resource_count;
286     uint8_t reserved2[3];
287 } RpmbUnitDescriptor;
288 
289 typedef struct QEMU_PACKED PowerParametersDescriptor {
290     uint8_t length;
291     uint8_t descriptor_idn;
292     uint16_t active_icc_levels_vcc[16];
293     uint16_t active_icc_levels_vccq[16];
294     uint16_t active_icc_levels_vccq_2[16];
295 } PowerParametersDescriptor;
296 
297 typedef struct QEMU_PACKED InterconnectDescriptor {
298     uint8_t length;
299     uint8_t descriptor_idn;
300     uint16_t bcd_unipro_version;
301     uint16_t bcd_mphy_version;
302 } InterconnectDescriptor;
303 
304 typedef struct QEMU_PACKED StringDescriptor {
305     uint8_t length;
306     uint8_t descriptor_idn;
307     uint16_t UC[126];
308 } StringDescriptor;
309 
310 typedef struct QEMU_PACKED DeviceHealthDescriptor {
311     uint8_t length;
312     uint8_t descriptor_idn;
313     uint8_t pre_eol_info;
314     uint8_t device_life_time_est_a;
315     uint8_t device_life_time_est_b;
316     uint8_t vendor_prop_info[32];
317     uint32_t refresh_total_count;
318     uint32_t refresh_progress;
319 } DeviceHealthDescriptor;
320 
321 typedef struct QEMU_PACKED Flags {
322     uint8_t reserved;
323     uint8_t device_init;
324     uint8_t permanent_wp_en;
325     uint8_t power_on_wp_en;
326     uint8_t background_ops_en;
327     uint8_t device_life_span_mode_en;
328     uint8_t purge_enable;
329     uint8_t refresh_enable;
330     uint8_t phy_resource_removal;
331     uint8_t busy_rtc;
332     uint8_t reserved2;
333     uint8_t permanently_disable_fw_update;
334     uint8_t reserved3[2];
335     uint8_t wb_en;
336     uint8_t wb_buffer_flush_en;
337     uint8_t wb_buffer_flush_during_hibernate;
338     uint8_t reserved4[2];
339 } Flags;
340 
341 typedef struct Attributes {
342     uint8_t boot_lun_en;
343     uint8_t reserved;
344     uint8_t current_power_mode;
345     uint8_t active_icc_level;
346     uint8_t out_of_order_data_en;
347     uint8_t background_op_status;
348     uint8_t purge_status;
349     uint8_t max_data_in_size;
350     uint8_t max_data_out_size;
351     uint32_t dyn_cap_needed;
352     uint8_t ref_clk_freq;
353     uint8_t config_descr_lock;
354     uint8_t max_num_of_rtt;
355     uint16_t exception_event_control;
356     uint16_t exception_event_status;
357     uint32_t seconds_passed;
358     uint16_t context_conf;
359     uint8_t device_ffu_status;
360     uint8_t psa_state;
361     uint32_t psa_data_size;
362     uint8_t ref_clk_gating_wait_time;
363     uint8_t device_case_rough_temperaure;
364     uint8_t device_too_high_temp_boundary;
365     uint8_t device_too_low_temp_boundary;
366     uint8_t throttling_status;
367     uint8_t wb_buffer_flush_status;
368     uint8_t available_wb_buffer_size;
369     uint8_t wb_buffer_life_time_est;
370     uint32_t current_wb_buffer_size;
371     uint8_t refresh_status;
372     uint8_t refresh_freq;
373     uint8_t refresh_unit;
374     uint8_t refresh_method;
375 } Attributes;
376 
377 #define UFS_TRANSACTION_SPECIFIC_FIELD_SIZE 20
378 #define UFS_MAX_QUERY_DATA_SIZE 256
379 
380 /* Command response result code */
381 typedef enum CommandRespCode {
382     UFS_COMMAND_RESULT_SUCCESS = 0x00,
383     UFS_COMMAND_RESULT_FAIL = 0x01,
384 } CommandRespCode;
385 
386 enum {
387     UFS_UPIU_FLAG_UNDERFLOW = 0x20,
388     UFS_UPIU_FLAG_OVERFLOW = 0x40,
389 };
390 
391 typedef struct QEMU_PACKED UtpUpiuHeader {
392     uint8_t trans_type;
393     uint8_t flags;
394     uint8_t lun;
395     uint8_t task_tag;
396     uint8_t iid_cmd_set_type;
397     uint8_t query_func;
398     uint8_t response;
399     uint8_t scsi_status;
400     uint8_t ehs_len;
401     uint8_t device_inf;
402     uint16_t data_segment_length;
403 } UtpUpiuHeader;
404 
405 /*
406  * The code below is copied from the linux kernel
407  * ("include/uapi/scsi/scsi_bsg_ufs.h") and modified to fit the qemu style.
408  */
409 
410 typedef struct QEMU_PACKED UtpUpiuQuery {
411     uint8_t opcode;
412     uint8_t idn;
413     uint8_t index;
414     uint8_t selector;
415     uint16_t reserved_osf;
416     uint16_t length;
417     uint32_t value;
418     uint32_t reserved[2];
419     /* EHS length should be 0. We don't have to worry about EHS area. */
420     uint8_t data[UFS_MAX_QUERY_DATA_SIZE];
421 } UtpUpiuQuery;
422 
423 #define UFS_CDB_SIZE 16
424 
425 /*
426  * struct UtpUpiuCmd - Command UPIU structure
427  * @data_transfer_len: Data Transfer Length DW-3
428  * @cdb: Command Descriptor Block CDB DW-4 to DW-7
429  */
430 typedef struct QEMU_PACKED UtpUpiuCmd {
431     uint32_t exp_data_transfer_len;
432     uint8_t cdb[UFS_CDB_SIZE];
433 } UtpUpiuCmd;
434 
435 /*
436  * struct UtpUpiuReq - general upiu request structure
437  * @header:UPIU header structure DW-0 to DW-2
438  * @sc: fields structure for scsi command DW-3 to DW-7
439  * @qr: fields structure for query request DW-3 to DW-7
440  * @uc: use utp_upiu_query to host the 4 dwords of uic command
441  */
442 typedef struct QEMU_PACKED UtpUpiuReq {
443     UtpUpiuHeader header;
444     union {
445         UtpUpiuCmd sc;
446         UtpUpiuQuery qr;
447     };
448 } UtpUpiuReq;
449 
450 /*
451  * The code below is copied from the linux kernel ("include/ufs/ufshci.h") and
452  * modified to fit the qemu style.
453  */
454 
455 enum {
456     UFS_PWR_OK = 0x0,
457     UFS_PWR_LOCAL = 0x01,
458     UFS_PWR_REMOTE = 0x02,
459     UFS_PWR_BUSY = 0x03,
460     UFS_PWR_ERROR_CAP = 0x04,
461     UFS_PWR_FATAL_ERROR = 0x05,
462 };
463 
464 /* UIC Commands */
465 enum uic_cmd_dme {
466     UFS_UIC_CMD_DME_GET = 0x01,
467     UFS_UIC_CMD_DME_SET = 0x02,
468     UFS_UIC_CMD_DME_PEER_GET = 0x03,
469     UFS_UIC_CMD_DME_PEER_SET = 0x04,
470     UFS_UIC_CMD_DME_POWERON = 0x10,
471     UFS_UIC_CMD_DME_POWEROFF = 0x11,
472     UFS_UIC_CMD_DME_ENABLE = 0x12,
473     UFS_UIC_CMD_DME_RESET = 0x14,
474     UFS_UIC_CMD_DME_END_PT_RST = 0x15,
475     UFS_UIC_CMD_DME_LINK_STARTUP = 0x16,
476     UFS_UIC_CMD_DME_HIBER_ENTER = 0x17,
477     UFS_UIC_CMD_DME_HIBER_EXIT = 0x18,
478     UFS_UIC_CMD_DME_TEST_MODE = 0x1A,
479 };
480 
481 /* UIC Config result code / Generic error code */
482 enum {
483     UFS_UIC_CMD_RESULT_SUCCESS = 0x00,
484     UFS_UIC_CMD_RESULT_INVALID_ATTR = 0x01,
485     UFS_UIC_CMD_RESULT_FAILURE = 0x01,
486     UFS_UIC_CMD_RESULT_INVALID_ATTR_VALUE = 0x02,
487     UFS_UIC_CMD_RESULT_READ_ONLY_ATTR = 0x03,
488     UFS_UIC_CMD_RESULT_WRITE_ONLY_ATTR = 0x04,
489     UFS_UIC_CMD_RESULT_BAD_INDEX = 0x05,
490     UFS_UIC_CMD_RESULT_LOCKED_ATTR = 0x06,
491     UFS_UIC_CMD_RESULT_BAD_TEST_FEATURE_INDEX = 0x07,
492     UFS_UIC_CMD_RESULT_PEER_COMM_FAILURE = 0x08,
493     UFS_UIC_CMD_RESULT_BUSY = 0x09,
494     UFS_UIC_CMD_RESULT_DME_FAILURE = 0x0A,
495 };
496 
497 #define UFS_MASK_UIC_COMMAND_RESULT 0xFF
498 
499 /*
500  * Request Descriptor Definitions
501  */
502 
503 /* Transfer request command type */
504 enum {
505     UFS_UTP_CMD_TYPE_SCSI = 0x0,
506     UFS_UTP_CMD_TYPE_UFS = 0x1,
507     UFS_UTP_CMD_TYPE_DEV_MANAGE = 0x2,
508 };
509 
510 /* To accommodate UFS2.0 required Command type */
511 enum {
512     UFS_UTP_CMD_TYPE_UFS_STORAGE = 0x1,
513 };
514 
515 enum {
516     UFS_UTP_SCSI_COMMAND = 0x00000000,
517     UFS_UTP_NATIVE_UFS_COMMAND = 0x10000000,
518     UFS_UTP_DEVICE_MANAGEMENT_FUNCTION = 0x20000000,
519     UFS_UTP_REQ_DESC_INT_CMD = 0x01000000,
520     UFS_UTP_REQ_DESC_CRYPTO_ENABLE_CMD = 0x00800000,
521 };
522 
523 /* UTP Transfer Request Data Direction (DD) */
524 enum {
525     UFS_UTP_NO_DATA_TRANSFER = 0x00000000,
526     UFS_UTP_HOST_TO_DEVICE = 0x02000000,
527     UFS_UTP_DEVICE_TO_HOST = 0x04000000,
528 };
529 
530 /* Overall command status values */
531 enum UtpOcsCodes {
532     UFS_OCS_SUCCESS = 0x0,
533     UFS_OCS_INVALID_CMD_TABLE_ATTR = 0x1,
534     UFS_OCS_INVALID_PRDT_ATTR = 0x2,
535     UFS_OCS_MISMATCH_DATA_BUF_SIZE = 0x3,
536     UFS_OCS_MISMATCH_RESP_UPIU_SIZE = 0x4,
537     UFS_OCS_PEER_COMM_FAILURE = 0x5,
538     UFS_OCS_ABORTED = 0x6,
539     UFS_OCS_FATAL_ERROR = 0x7,
540     UFS_OCS_DEVICE_FATAL_ERROR = 0x8,
541     UFS_OCS_INVALID_CRYPTO_CONFIG = 0x9,
542     UFS_OCS_GENERAL_CRYPTO_ERROR = 0xa,
543     UFS_OCS_INVALID_COMMAND_STATUS = 0xf,
544 };
545 
546 enum {
547     UFS_MASK_OCS = 0x0F,
548 };
549 
550 /*
551  * struct UfshcdSgEntry - UFSHCI PRD Entry
552  * @addr: Physical address; DW-0 and DW-1.
553  * @reserved: Reserved for future use DW-2
554  * @size: size of physical segment DW-3
555  */
556 typedef struct QEMU_PACKED UfshcdSgEntry {
557     uint64_t addr;
558     uint32_t reserved;
559     uint32_t size;
560     /*
561      * followed by variant-specific fields if
562      * CONFIG_SCSI_UFS_VARIABLE_SG_ENTRY_SIZE has been defined.
563      */
564 } UfshcdSgEntry;
565 
566 /*
567  * struct RequestDescHeader - Descriptor Header common to both UTRD and UTMRD
568  * @dword0: Descriptor Header DW0
569  * @dword1: Descriptor Header DW1
570  * @dword2: Descriptor Header DW2
571  * @dword3: Descriptor Header DW3
572  */
573 typedef struct QEMU_PACKED RequestDescHeader {
574     uint32_t dword_0;
575     uint32_t dword_1;
576     uint32_t dword_2;
577     uint32_t dword_3;
578 } RequestDescHeader;
579 
580 /*
581  * struct UtpTransferReqDesc - UTP Transfer Request Descriptor (UTRD)
582  * @header: UTRD header DW-0 to DW-3
583  * @command_desc_base_addr_lo: UCD base address low DW-4
584  * @command_desc_base_addr_hi: UCD base address high DW-5
585  * @response_upiu_length: response UPIU length DW-6
586  * @response_upiu_offset: response UPIU offset DW-6
587  * @prd_table_length: Physical region descriptor length DW-7
588  * @prd_table_offset: Physical region descriptor offset DW-7
589  */
590 typedef struct QEMU_PACKED UtpTransferReqDesc {
591     /* DW 0-3 */
592     RequestDescHeader header;
593 
594     /* DW 4-5*/
595     uint32_t command_desc_base_addr_lo;
596     uint32_t command_desc_base_addr_hi;
597 
598     /* DW 6 */
599     uint16_t response_upiu_length;
600     uint16_t response_upiu_offset;
601 
602     /* DW 7 */
603     uint16_t prd_table_length;
604     uint16_t prd_table_offset;
605 } UtpTransferReqDesc;
606 
607 /*
608  * UTMRD structure.
609  */
610 typedef struct QEMU_PACKED UtpTaskReqDesc {
611     /* DW 0-3 */
612     RequestDescHeader header;
613 
614     /* DW 4-11 - Task request UPIU structure */
615     struct {
616         UtpUpiuHeader req_header;
617         uint32_t input_param1;
618         uint32_t input_param2;
619         uint32_t input_param3;
620         uint32_t reserved1[2];
621     } upiu_req;
622 
623     /* DW 12-19 - Task Management Response UPIU structure */
624     struct {
625         UtpUpiuHeader rsp_header;
626         uint32_t output_param1;
627         uint32_t output_param2;
628         uint32_t reserved2[3];
629     } upiu_rsp;
630 } UtpTaskReqDesc;
631 
632 /*
633  * The code below is copied from the linux kernel ("include/ufs/ufs.h") and
634  * modified to fit the qemu style.
635  */
636 
637 #define UFS_GENERAL_UPIU_REQUEST_SIZE (sizeof(UtpUpiuReq))
638 #define UFS_QUERY_DESC_MAX_SIZE 255
639 #define UFS_QUERY_DESC_MIN_SIZE 2
640 #define UFS_QUERY_DESC_HDR_SIZE 2
641 #define UFS_QUERY_OSF_SIZE (GENERAL_UPIU_REQUEST_SIZE - (sizeof(UtpUpiuHeader)))
642 #define UFS_SENSE_SIZE 18
643 
644 /*
645  * UFS device may have standard LUs and LUN id could be from 0x00 to
646  * 0x7F. Standard LUs use "Peripheral Device Addressing Format".
647  * UFS device may also have the Well Known LUs (also referred as W-LU)
648  * which again could be from 0x00 to 0x7F. For W-LUs, device only use
649  * the "Extended Addressing Format" which means the W-LUNs would be
650  * from 0xc100 (SCSI_W_LUN_BASE) onwards.
651  * This means max. LUN number reported from UFS device could be 0xC17F.
652  */
653 #define UFS_UPIU_MAX_UNIT_NUM_ID 0x7F
654 #define UFS_UPIU_WLUN_ID (1 << 7)
655 
656 /* WriteBooster buffer is available only for the logical unit from 0 to 7 */
657 #define UFS_UPIU_MAX_WB_LUN_ID 8
658 
659 /*
660  * WriteBooster buffer lifetime has a limit set by vendor.
661  * If it is over the limit, WriteBooster feature will be disabled.
662  */
663 #define UFS_WB_EXCEED_LIFETIME 0x0B
664 
665 /*
666  * In UFS Spec, the Extra Header Segment (EHS) starts from byte 32 in UPIU
667  * request/response packet
668  */
669 #define UFS_EHS_OFFSET_IN_RESPONSE 32
670 
671 /* Well known logical unit id in LUN field of UPIU */
672 enum {
673     UFS_UPIU_REPORT_LUNS_WLUN = 0x81,
674     UFS_UPIU_UFS_DEVICE_WLUN = 0xD0,
675     UFS_UPIU_BOOT_WLUN = 0xB0,
676     UFS_UPIU_RPMB_WLUN = 0xC4,
677 };
678 
679 /*
680  * UFS Protocol Information Unit related definitions
681  */
682 
683 /* Task management functions */
684 enum {
685     UFS_ABORT_TASK = 0x01,
686     UFS_ABORT_TASK_SET = 0x02,
687     UFS_CLEAR_TASK_SET = 0x04,
688     UFS_LOGICAL_RESET = 0x08,
689     UFS_QUERY_TASK = 0x80,
690     UFS_QUERY_TASK_SET = 0x81,
691 };
692 
693 /* UTP UPIU Transaction Codes Initiator to Target */
694 enum {
695     UFS_UPIU_TRANSACTION_NOP_OUT = 0x00,
696     UFS_UPIU_TRANSACTION_COMMAND = 0x01,
697     UFS_UPIU_TRANSACTION_DATA_OUT = 0x02,
698     UFS_UPIU_TRANSACTION_TASK_REQ = 0x04,
699     UFS_UPIU_TRANSACTION_QUERY_REQ = 0x16,
700 };
701 
702 /* UTP UPIU Transaction Codes Target to Initiator */
703 enum {
704     UFS_UPIU_TRANSACTION_NOP_IN = 0x20,
705     UFS_UPIU_TRANSACTION_RESPONSE = 0x21,
706     UFS_UPIU_TRANSACTION_DATA_IN = 0x22,
707     UFS_UPIU_TRANSACTION_TASK_RSP = 0x24,
708     UFS_UPIU_TRANSACTION_READY_XFER = 0x31,
709     UFS_UPIU_TRANSACTION_QUERY_RSP = 0x36,
710     UFS_UPIU_TRANSACTION_REJECT_UPIU = 0x3F,
711 };
712 
713 /* UPIU Read/Write flags */
714 enum {
715     UFS_UPIU_CMD_FLAGS_NONE = 0x00,
716     UFS_UPIU_CMD_FLAGS_WRITE = 0x20,
717     UFS_UPIU_CMD_FLAGS_READ = 0x40,
718 };
719 
720 /* UPIU Task Attributes */
721 enum {
722     UFS_UPIU_TASK_ATTR_SIMPLE = 0x00,
723     UFS_UPIU_TASK_ATTR_ORDERED = 0x01,
724     UFS_UPIU_TASK_ATTR_HEADQ = 0x02,
725     UFS_UPIU_TASK_ATTR_ACA = 0x03,
726 };
727 
728 /* UPIU Query request function */
729 enum {
730     UFS_UPIU_QUERY_FUNC_STANDARD_READ_REQUEST = 0x01,
731     UFS_UPIU_QUERY_FUNC_STANDARD_WRITE_REQUEST = 0x81,
732 };
733 
734 /* Flag idn for Query Requests*/
735 enum flag_idn {
736     UFS_QUERY_FLAG_IDN_FDEVICEINIT = 0x01,
737     UFS_QUERY_FLAG_IDN_PERMANENT_WPE = 0x02,
738     UFS_QUERY_FLAG_IDN_PWR_ON_WPE = 0x03,
739     UFS_QUERY_FLAG_IDN_BKOPS_EN = 0x04,
740     UFS_QUERY_FLAG_IDN_LIFE_SPAN_MODE_ENABLE = 0x05,
741     UFS_QUERY_FLAG_IDN_PURGE_ENABLE = 0x06,
742     UFS_QUERY_FLAG_IDN_REFRESH_ENABLE = 0x07,
743     UFS_QUERY_FLAG_IDN_FPHYRESOURCEREMOVAL = 0x08,
744     UFS_QUERY_FLAG_IDN_BUSY_RTC = 0x09,
745     UFS_QUERY_FLAG_IDN_RESERVED3 = 0x0A,
746     UFS_QUERY_FLAG_IDN_PERMANENTLY_DISABLE_FW_UPDATE = 0x0B,
747     UFS_QUERY_FLAG_IDN_WB_EN = 0x0E,
748     UFS_QUERY_FLAG_IDN_WB_BUFF_FLUSH_EN = 0x0F,
749     UFS_QUERY_FLAG_IDN_WB_BUFF_FLUSH_DURING_HIBERN8 = 0x10,
750     UFS_QUERY_FLAG_IDN_HPB_RESET = 0x11,
751     UFS_QUERY_FLAG_IDN_HPB_EN = 0x12,
752     UFS_QUERY_FLAG_IDN_COUNT,
753 };
754 
755 /* Attribute idn for Query requests */
756 enum attr_idn {
757     UFS_QUERY_ATTR_IDN_BOOT_LU_EN = 0x00,
758     UFS_QUERY_ATTR_IDN_MAX_HPB_SINGLE_CMD = 0x01,
759     UFS_QUERY_ATTR_IDN_POWER_MODE = 0x02,
760     UFS_QUERY_ATTR_IDN_ACTIVE_ICC_LVL = 0x03,
761     UFS_QUERY_ATTR_IDN_OOO_DATA_EN = 0x04,
762     UFS_QUERY_ATTR_IDN_BKOPS_STATUS = 0x05,
763     UFS_QUERY_ATTR_IDN_PURGE_STATUS = 0x06,
764     UFS_QUERY_ATTR_IDN_MAX_DATA_IN = 0x07,
765     UFS_QUERY_ATTR_IDN_MAX_DATA_OUT = 0x08,
766     UFS_QUERY_ATTR_IDN_DYN_CAP_NEEDED = 0x09,
767     UFS_QUERY_ATTR_IDN_REF_CLK_FREQ = 0x0A,
768     UFS_QUERY_ATTR_IDN_CONF_DESC_LOCK = 0x0B,
769     UFS_QUERY_ATTR_IDN_MAX_NUM_OF_RTT = 0x0C,
770     UFS_QUERY_ATTR_IDN_EE_CONTROL = 0x0D,
771     UFS_QUERY_ATTR_IDN_EE_STATUS = 0x0E,
772     UFS_QUERY_ATTR_IDN_SECONDS_PASSED = 0x0F,
773     UFS_QUERY_ATTR_IDN_CNTX_CONF = 0x10,
774     UFS_QUERY_ATTR_IDN_CORR_PRG_BLK_NUM = 0x11,
775     UFS_QUERY_ATTR_IDN_RESERVED2 = 0x12,
776     UFS_QUERY_ATTR_IDN_RESERVED3 = 0x13,
777     UFS_QUERY_ATTR_IDN_FFU_STATUS = 0x14,
778     UFS_QUERY_ATTR_IDN_PSA_STATE = 0x15,
779     UFS_QUERY_ATTR_IDN_PSA_DATA_SIZE = 0x16,
780     UFS_QUERY_ATTR_IDN_REF_CLK_GATING_WAIT_TIME = 0x17,
781     UFS_QUERY_ATTR_IDN_CASE_ROUGH_TEMP = 0x18,
782     UFS_QUERY_ATTR_IDN_HIGH_TEMP_BOUND = 0x19,
783     UFS_QUERY_ATTR_IDN_LOW_TEMP_BOUND = 0x1A,
784     UFS_QUERY_ATTR_IDN_THROTTLING_STATUS = 0x1B,
785     UFS_QUERY_ATTR_IDN_WB_FLUSH_STATUS = 0x1C,
786     UFS_QUERY_ATTR_IDN_AVAIL_WB_BUFF_SIZE = 0x1D,
787     UFS_QUERY_ATTR_IDN_WB_BUFF_LIFE_TIME_EST = 0x1E,
788     UFS_QUERY_ATTR_IDN_CURR_WB_BUFF_SIZE = 0x1F,
789     UFS_QUERY_ATTR_IDN_REFRESH_STATUS = 0x2C,
790     UFS_QUERY_ATTR_IDN_REFRESH_FREQ = 0x2D,
791     UFS_QUERY_ATTR_IDN_REFRESH_UNIT = 0x2E,
792     UFS_QUERY_ATTR_IDN_COUNT,
793 };
794 
795 /* Descriptor idn for Query requests */
796 enum desc_idn {
797     UFS_QUERY_DESC_IDN_DEVICE = 0x0,
798     UFS_QUERY_DESC_IDN_CONFIGURATION = 0x1,
799     UFS_QUERY_DESC_IDN_UNIT = 0x2,
800     UFS_QUERY_DESC_IDN_RFU_0 = 0x3,
801     UFS_QUERY_DESC_IDN_INTERCONNECT = 0x4,
802     UFS_QUERY_DESC_IDN_STRING = 0x5,
803     UFS_QUERY_DESC_IDN_RFU_1 = 0x6,
804     UFS_QUERY_DESC_IDN_GEOMETRY = 0x7,
805     UFS_QUERY_DESC_IDN_POWER = 0x8,
806     UFS_QUERY_DESC_IDN_HEALTH = 0x9,
807     UFS_QUERY_DESC_IDN_MAX,
808 };
809 
810 enum desc_header_offset {
811     UFS_QUERY_DESC_LENGTH_OFFSET = 0x00,
812     UFS_QUERY_DESC_DESC_TYPE_OFFSET = 0x01,
813 };
814 
815 /* Unit descriptor parameters offsets in bytes*/
816 enum unit_desc_param {
817     UFS_UNIT_DESC_PARAM_LEN = 0x0,
818     UFS_UNIT_DESC_PARAM_TYPE = 0x1,
819     UFS_UNIT_DESC_PARAM_UNIT_INDEX = 0x2,
820     UFS_UNIT_DESC_PARAM_LU_ENABLE = 0x3,
821     UFS_UNIT_DESC_PARAM_BOOT_LUN_ID = 0x4,
822     UFS_UNIT_DESC_PARAM_LU_WR_PROTECT = 0x5,
823     UFS_UNIT_DESC_PARAM_LU_Q_DEPTH = 0x6,
824     UFS_UNIT_DESC_PARAM_PSA_SENSITIVE = 0x7,
825     UFS_UNIT_DESC_PARAM_MEM_TYPE = 0x8,
826     UFS_UNIT_DESC_PARAM_DATA_RELIABILITY = 0x9,
827     UFS_UNIT_DESC_PARAM_LOGICAL_BLK_SIZE = 0xA,
828     UFS_UNIT_DESC_PARAM_LOGICAL_BLK_COUNT = 0xB,
829     UFS_UNIT_DESC_PARAM_ERASE_BLK_SIZE = 0x13,
830     UFS_UNIT_DESC_PARAM_PROVISIONING_TYPE = 0x17,
831     UFS_UNIT_DESC_PARAM_PHY_MEM_RSRC_CNT = 0x18,
832     UFS_UNIT_DESC_PARAM_CTX_CAPABILITIES = 0x20,
833     UFS_UNIT_DESC_PARAM_LARGE_UNIT_SIZE_M1 = 0x22,
834     UFS_UNIT_DESC_PARAM_HPB_LU_MAX_ACTIVE_RGNS = 0x23,
835     UFS_UNIT_DESC_PARAM_HPB_PIN_RGN_START_OFF = 0x25,
836     UFS_UNIT_DESC_PARAM_HPB_NUM_PIN_RGNS = 0x27,
837     UFS_UNIT_DESC_PARAM_WB_BUF_ALLOC_UNITS = 0x29,
838 };
839 
840 /* RPMB Unit descriptor parameters offsets in bytes*/
841 enum rpmb_unit_desc_param {
842     UFS_RPMB_UNIT_DESC_PARAM_LEN = 0x0,
843     UFS_RPMB_UNIT_DESC_PARAM_TYPE = 0x1,
844     UFS_RPMB_UNIT_DESC_PARAM_UNIT_INDEX = 0x2,
845     UFS_RPMB_UNIT_DESC_PARAM_LU_ENABLE = 0x3,
846     UFS_RPMB_UNIT_DESC_PARAM_BOOT_LUN_ID = 0x4,
847     UFS_RPMB_UNIT_DESC_PARAM_LU_WR_PROTECT = 0x5,
848     UFS_RPMB_UNIT_DESC_PARAM_LU_Q_DEPTH = 0x6,
849     UFS_RPMB_UNIT_DESC_PARAM_PSA_SENSITIVE = 0x7,
850     UFS_RPMB_UNIT_DESC_PARAM_MEM_TYPE = 0x8,
851     UFS_RPMB_UNIT_DESC_PARAM_REGION_EN = 0x9,
852     UFS_RPMB_UNIT_DESC_PARAM_LOGICAL_BLK_SIZE = 0xA,
853     UFS_RPMB_UNIT_DESC_PARAM_LOGICAL_BLK_COUNT = 0xB,
854     UFS_RPMB_UNIT_DESC_PARAM_REGION0_SIZE = 0x13,
855     UFS_RPMB_UNIT_DESC_PARAM_REGION1_SIZE = 0x14,
856     UFS_RPMB_UNIT_DESC_PARAM_REGION2_SIZE = 0x15,
857     UFS_RPMB_UNIT_DESC_PARAM_REGION3_SIZE = 0x16,
858     UFS_RPMB_UNIT_DESC_PARAM_PROVISIONING_TYPE = 0x17,
859     UFS_RPMB_UNIT_DESC_PARAM_PHY_MEM_RSRC_CNT = 0x18,
860 };
861 
862 /* Device descriptor parameters offsets in bytes*/
863 enum device_desc_param {
864     UFS_DEVICE_DESC_PARAM_LEN = 0x0,
865     UFS_DEVICE_DESC_PARAM_TYPE = 0x1,
866     UFS_DEVICE_DESC_PARAM_DEVICE_TYPE = 0x2,
867     UFS_DEVICE_DESC_PARAM_DEVICE_CLASS = 0x3,
868     UFS_DEVICE_DESC_PARAM_DEVICE_SUB_CLASS = 0x4,
869     UFS_DEVICE_DESC_PARAM_PRTCL = 0x5,
870     UFS_DEVICE_DESC_PARAM_NUM_LU = 0x6,
871     UFS_DEVICE_DESC_PARAM_NUM_WLU = 0x7,
872     UFS_DEVICE_DESC_PARAM_BOOT_ENBL = 0x8,
873     UFS_DEVICE_DESC_PARAM_DESC_ACCSS_ENBL = 0x9,
874     UFS_DEVICE_DESC_PARAM_INIT_PWR_MODE = 0xA,
875     UFS_DEVICE_DESC_PARAM_HIGH_PR_LUN = 0xB,
876     UFS_DEVICE_DESC_PARAM_SEC_RMV_TYPE = 0xC,
877     UFS_DEVICE_DESC_PARAM_SEC_LU = 0xD,
878     UFS_DEVICE_DESC_PARAM_BKOP_TERM_LT = 0xE,
879     UFS_DEVICE_DESC_PARAM_ACTVE_ICC_LVL = 0xF,
880     UFS_DEVICE_DESC_PARAM_SPEC_VER = 0x10,
881     UFS_DEVICE_DESC_PARAM_MANF_DATE = 0x12,
882     UFS_DEVICE_DESC_PARAM_MANF_NAME = 0x14,
883     UFS_DEVICE_DESC_PARAM_PRDCT_NAME = 0x15,
884     UFS_DEVICE_DESC_PARAM_SN = 0x16,
885     UFS_DEVICE_DESC_PARAM_OEM_ID = 0x17,
886     UFS_DEVICE_DESC_PARAM_MANF_ID = 0x18,
887     UFS_DEVICE_DESC_PARAM_UD_OFFSET = 0x1A,
888     UFS_DEVICE_DESC_PARAM_UD_LEN = 0x1B,
889     UFS_DEVICE_DESC_PARAM_RTT_CAP = 0x1C,
890     UFS_DEVICE_DESC_PARAM_FRQ_RTC = 0x1D,
891     UFS_DEVICE_DESC_PARAM_UFS_FEAT = 0x1F,
892     UFS_DEVICE_DESC_PARAM_FFU_TMT = 0x20,
893     UFS_DEVICE_DESC_PARAM_Q_DPTH = 0x21,
894     UFS_DEVICE_DESC_PARAM_DEV_VER = 0x22,
895     UFS_DEVICE_DESC_PARAM_NUM_SEC_WPA = 0x24,
896     UFS_DEVICE_DESC_PARAM_PSA_MAX_DATA = 0x25,
897     UFS_DEVICE_DESC_PARAM_PSA_TMT = 0x29,
898     UFS_DEVICE_DESC_PARAM_PRDCT_REV = 0x2A,
899     UFS_DEVICE_DESC_PARAM_HPB_VER = 0x40,
900     UFS_DEVICE_DESC_PARAM_HPB_CONTROL = 0x42,
901     UFS_DEVICE_DESC_PARAM_EXT_UFS_FEATURE_SUP = 0x4F,
902     UFS_DEVICE_DESC_PARAM_WB_PRESRV_USRSPC_EN = 0x53,
903     UFS_DEVICE_DESC_PARAM_WB_TYPE = 0x54,
904     UFS_DEVICE_DESC_PARAM_WB_SHARED_ALLOC_UNITS = 0x55,
905 };
906 
907 /* Interconnect descriptor parameters offsets in bytes*/
908 enum interconnect_desc_param {
909     UFS_INTERCONNECT_DESC_PARAM_LEN = 0x0,
910     UFS_INTERCONNECT_DESC_PARAM_TYPE = 0x1,
911     UFS_INTERCONNECT_DESC_PARAM_UNIPRO_VER = 0x2,
912     UFS_INTERCONNECT_DESC_PARAM_MPHY_VER = 0x4,
913 };
914 
915 /* Geometry descriptor parameters offsets in bytes*/
916 enum geometry_desc_param {
917     UFS_GEOMETRY_DESC_PARAM_LEN = 0x0,
918     UFS_GEOMETRY_DESC_PARAM_TYPE = 0x1,
919     UFS_GEOMETRY_DESC_PARAM_DEV_CAP = 0x4,
920     UFS_GEOMETRY_DESC_PARAM_MAX_NUM_LUN = 0xC,
921     UFS_GEOMETRY_DESC_PARAM_SEG_SIZE = 0xD,
922     UFS_GEOMETRY_DESC_PARAM_ALLOC_UNIT_SIZE = 0x11,
923     UFS_GEOMETRY_DESC_PARAM_MIN_BLK_SIZE = 0x12,
924     UFS_GEOMETRY_DESC_PARAM_OPT_RD_BLK_SIZE = 0x13,
925     UFS_GEOMETRY_DESC_PARAM_OPT_WR_BLK_SIZE = 0x14,
926     UFS_GEOMETRY_DESC_PARAM_MAX_IN_BUF_SIZE = 0x15,
927     UFS_GEOMETRY_DESC_PARAM_MAX_OUT_BUF_SIZE = 0x16,
928     UFS_GEOMETRY_DESC_PARAM_RPMB_RW_SIZE = 0x17,
929     UFS_GEOMETRY_DESC_PARAM_DYN_CAP_RSRC_PLC = 0x18,
930     UFS_GEOMETRY_DESC_PARAM_DATA_ORDER = 0x19,
931     UFS_GEOMETRY_DESC_PARAM_MAX_NUM_CTX = 0x1A,
932     UFS_GEOMETRY_DESC_PARAM_TAG_UNIT_SIZE = 0x1B,
933     UFS_GEOMETRY_DESC_PARAM_TAG_RSRC_SIZE = 0x1C,
934     UFS_GEOMETRY_DESC_PARAM_SEC_RM_TYPES = 0x1D,
935     UFS_GEOMETRY_DESC_PARAM_MEM_TYPES = 0x1E,
936     UFS_GEOMETRY_DESC_PARAM_SCM_MAX_NUM_UNITS = 0x20,
937     UFS_GEOMETRY_DESC_PARAM_SCM_CAP_ADJ_FCTR = 0x24,
938     UFS_GEOMETRY_DESC_PARAM_NPM_MAX_NUM_UNITS = 0x26,
939     UFS_GEOMETRY_DESC_PARAM_NPM_CAP_ADJ_FCTR = 0x2A,
940     UFS_GEOMETRY_DESC_PARAM_ENM1_MAX_NUM_UNITS = 0x2C,
941     UFS_GEOMETRY_DESC_PARAM_ENM1_CAP_ADJ_FCTR = 0x30,
942     UFS_GEOMETRY_DESC_PARAM_ENM2_MAX_NUM_UNITS = 0x32,
943     UFS_GEOMETRY_DESC_PARAM_ENM2_CAP_ADJ_FCTR = 0x36,
944     UFS_GEOMETRY_DESC_PARAM_ENM3_MAX_NUM_UNITS = 0x38,
945     UFS_GEOMETRY_DESC_PARAM_ENM3_CAP_ADJ_FCTR = 0x3C,
946     UFS_GEOMETRY_DESC_PARAM_ENM4_MAX_NUM_UNITS = 0x3E,
947     UFS_GEOMETRY_DESC_PARAM_ENM4_CAP_ADJ_FCTR = 0x42,
948     UFS_GEOMETRY_DESC_PARAM_OPT_LOG_BLK_SIZE = 0x44,
949     UFS_GEOMETRY_DESC_PARAM_HPB_REGION_SIZE = 0x48,
950     UFS_GEOMETRY_DESC_PARAM_HPB_NUMBER_LU = 0x49,
951     UFS_GEOMETRY_DESC_PARAM_HPB_SUBREGION_SIZE = 0x4A,
952     UFS_GEOMETRY_DESC_PARAM_HPB_MAX_ACTIVE_REGS = 0x4B,
953     UFS_GEOMETRY_DESC_PARAM_WB_MAX_ALLOC_UNITS = 0x4F,
954     UFS_GEOMETRY_DESC_PARAM_WB_MAX_WB_LUNS = 0x53,
955     UFS_GEOMETRY_DESC_PARAM_WB_BUFF_CAP_ADJ = 0x54,
956     UFS_GEOMETRY_DESC_PARAM_WB_SUP_RED_TYPE = 0x55,
957     UFS_GEOMETRY_DESC_PARAM_WB_SUP_WB_TYPE = 0x56,
958 };
959 
960 /* Health descriptor parameters offsets in bytes*/
961 enum health_desc_param {
962     UFS_HEALTH_DESC_PARAM_LEN = 0x0,
963     UFS_HEALTH_DESC_PARAM_TYPE = 0x1,
964     UFS_HEALTH_DESC_PARAM_EOL_INFO = 0x2,
965     UFS_HEALTH_DESC_PARAM_LIFE_TIME_EST_A = 0x3,
966     UFS_HEALTH_DESC_PARAM_LIFE_TIME_EST_B = 0x4,
967 };
968 
969 /* WriteBooster buffer mode */
970 enum {
971     UFS_WB_BUF_MODE_LU_DEDICATED = 0x0,
972     UFS_WB_BUF_MODE_SHARED = 0x1,
973 };
974 
975 /*
976  * Logical Unit Write Protect
977  * 00h: LU not write protected
978  * 01h: LU write protected when fPowerOnWPEn =1
979  * 02h: LU permanently write protected when fPermanentWPEn =1
980  */
981 enum ufs_lu_wp_type {
982     UFS_LU_NO_WP = 0x00,
983     UFS_LU_POWER_ON_WP = 0x01,
984     UFS_LU_PERM_WP = 0x02,
985 };
986 
987 /* UTP QUERY Transaction Specific Fields OpCode */
988 enum query_opcode {
989     UFS_UPIU_QUERY_OPCODE_NOP = 0x0,
990     UFS_UPIU_QUERY_OPCODE_READ_DESC = 0x1,
991     UFS_UPIU_QUERY_OPCODE_WRITE_DESC = 0x2,
992     UFS_UPIU_QUERY_OPCODE_READ_ATTR = 0x3,
993     UFS_UPIU_QUERY_OPCODE_WRITE_ATTR = 0x4,
994     UFS_UPIU_QUERY_OPCODE_READ_FLAG = 0x5,
995     UFS_UPIU_QUERY_OPCODE_SET_FLAG = 0x6,
996     UFS_UPIU_QUERY_OPCODE_CLEAR_FLAG = 0x7,
997     UFS_UPIU_QUERY_OPCODE_TOGGLE_FLAG = 0x8,
998 };
999 
1000 /* Query response result code */
1001 typedef enum QueryRespCode {
1002     UFS_QUERY_RESULT_SUCCESS = 0x00,
1003     UFS_QUERY_RESULT_NOT_READABLE = 0xF6,
1004     UFS_QUERY_RESULT_NOT_WRITEABLE = 0xF7,
1005     UFS_QUERY_RESULT_ALREADY_WRITTEN = 0xF8,
1006     UFS_QUERY_RESULT_INVALID_LENGTH = 0xF9,
1007     UFS_QUERY_RESULT_INVALID_VALUE = 0xFA,
1008     UFS_QUERY_RESULT_INVALID_SELECTOR = 0xFB,
1009     UFS_QUERY_RESULT_INVALID_INDEX = 0xFC,
1010     UFS_QUERY_RESULT_INVALID_IDN = 0xFD,
1011     UFS_QUERY_RESULT_INVALID_OPCODE = 0xFE,
1012     UFS_QUERY_RESULT_GENERAL_FAILURE = 0xFF,
1013 } QueryRespCode;
1014 
1015 /* UTP Transfer Request Command Type (CT) */
1016 enum {
1017     UFS_UPIU_COMMAND_SET_TYPE_SCSI = 0x0,
1018     UFS_UPIU_COMMAND_SET_TYPE_UFS = 0x1,
1019     UFS_UPIU_COMMAND_SET_TYPE_QUERY = 0x2,
1020 };
1021 
1022 /* Task management service response */
1023 enum {
1024     UFS_UPIU_TASK_MANAGEMENT_FUNC_COMPL = 0x00,
1025     UFS_UPIU_TASK_MANAGEMENT_FUNC_NOT_SUPPORTED = 0x04,
1026     UFS_UPIU_TASK_MANAGEMENT_FUNC_SUCCEEDED = 0x08,
1027     UFS_UPIU_TASK_MANAGEMENT_FUNC_FAILED = 0x05,
1028     UFS_UPIU_INCORRECT_LOGICAL_UNIT_NO = 0x09,
1029 };
1030 
1031 /* UFS device power modes */
1032 enum ufs_dev_pwr_mode {
1033     UFS_ACTIVE_PWR_MODE = 1,
1034     UFS_SLEEP_PWR_MODE = 2,
1035     UFS_POWERDOWN_PWR_MODE = 3,
1036     UFS_DEEPSLEEP_PWR_MODE = 4,
1037 };
1038 
1039 /*
1040  * struct UtpCmdRsp - Response UPIU structure
1041  * @residual_transfer_count: Residual transfer count DW-3
1042  * @reserved: Reserved double words DW-4 to DW-7
1043  * @sense_data_len: Sense data length DW-8 U16
1044  * @sense_data: Sense data field DW-8 to DW-12
1045  */
1046 typedef struct QEMU_PACKED UtpCmdRsp {
1047     uint32_t residual_transfer_count;
1048     uint32_t reserved[4];
1049     uint16_t sense_data_len;
1050     uint8_t sense_data[UFS_SENSE_SIZE];
1051 } UtpCmdRsp;
1052 
1053 /*
1054  * struct UtpUpiuRsp - general upiu response structure
1055  * @header: UPIU header structure DW-0 to DW-2
1056  * @sr: fields structure for scsi command DW-3 to DW-12
1057  * @qr: fields structure for query request DW-3 to DW-7
1058  */
1059 typedef struct QEMU_PACKED UtpUpiuRsp {
1060     UtpUpiuHeader header;
1061     union {
1062         UtpCmdRsp sr;
1063         UtpUpiuQuery qr;
1064     };
1065 } UtpUpiuRsp;
1066 
1067 static inline void _ufs_check_size(void)
1068 {
1069     QEMU_BUILD_BUG_ON(sizeof(UfsReg) != 0x104);
1070     QEMU_BUILD_BUG_ON(sizeof(DeviceDescriptor) != 89);
1071     QEMU_BUILD_BUG_ON(sizeof(GeometryDescriptor) != 87);
1072     QEMU_BUILD_BUG_ON(sizeof(UnitDescriptor) != 45);
1073     QEMU_BUILD_BUG_ON(sizeof(RpmbUnitDescriptor) != 35);
1074     QEMU_BUILD_BUG_ON(sizeof(PowerParametersDescriptor) != 98);
1075     QEMU_BUILD_BUG_ON(sizeof(InterconnectDescriptor) != 6);
1076     QEMU_BUILD_BUG_ON(sizeof(StringDescriptor) != 254);
1077     QEMU_BUILD_BUG_ON(sizeof(DeviceHealthDescriptor) != 45);
1078     QEMU_BUILD_BUG_ON(sizeof(Flags) != 0x13);
1079     QEMU_BUILD_BUG_ON(sizeof(UtpUpiuHeader) != 12);
1080     QEMU_BUILD_BUG_ON(sizeof(UtpUpiuQuery) != 276);
1081     QEMU_BUILD_BUG_ON(sizeof(UtpUpiuCmd) != 20);
1082     QEMU_BUILD_BUG_ON(sizeof(UtpUpiuReq) != 288);
1083     QEMU_BUILD_BUG_ON(sizeof(UfshcdSgEntry) != 16);
1084     QEMU_BUILD_BUG_ON(sizeof(RequestDescHeader) != 16);
1085     QEMU_BUILD_BUG_ON(sizeof(UtpTransferReqDesc) != 32);
1086     QEMU_BUILD_BUG_ON(sizeof(UtpTaskReqDesc) != 80);
1087     QEMU_BUILD_BUG_ON(sizeof(UtpCmdRsp) != 40);
1088     QEMU_BUILD_BUG_ON(sizeof(UtpUpiuRsp) != 288);
1089 }
1090 #endif
1091