summary refs log tree commit diff stats
path: root/hw
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2024-09-06 15:27:43 +0100
committerPeter Maydell <peter.maydell@linaro.org>2024-09-06 15:27:43 +0100
commit1581a0bc928d61230ed6e43bcb83f2f6737d0bc0 (patch)
tree62ff86fa1a97a31cc00b894cb4f11a5df80c1b4a /hw
parentec08d9a51e6af3cd3edbdbf2ca6e97a1e2b5f0d1 (diff)
parent9fe8e2c68ad99e503a11390b868a7dad846e7a0d (diff)
downloadfocaccia-qemu-1581a0bc928d61230ed6e43bcb83f2f6737d0bc0.tar.gz
focaccia-qemu-1581a0bc928d61230ed6e43bcb83f2f6737d0bc0.zip
Merge tag 'pull-ufs-20240906' of https://gitlab.com/jeuk20.kim/qemu into staging
ufs queue

# -----BEGIN PGP SIGNATURE-----
#
# iQIzBAABCgAdFiEEUBfYMVl8eKPZB+73EuIgTA5dtgIFAmba268ACgkQEuIgTA5d
# tgLndA//T7zvQboCWE2Aw+al4/cJmpfc/BP7pKrCvrwskhAo2H5JvbJ20WZ+/I6E
# sLqXjsAQ4qPWUNi46aty/tCCmFWatBRKIyWOg1E8w1N1PCqM/aKFElENgi28iclj
# 3TlIU+++a6VJXMtKKqGb/d6cxXM9QtRgkfpGEnVTCD4sRX25WuWcWu+hwCipgzsr
# dul1Ez+mp62SfHN2QLPUd+Ft0SvyxybDA65JP9fCEJPJ+2dtLWPN9XGY+6PzW4dT
# UEfUEV2V5k3w/QHTR8yG2i5s56wWVUhtQEhazbkj1VqgUSJ8PvIvBLhQpi4Gd51G
# 62/xHJaHXPxgVrVE6Or/5QF9npo1moG7UrLgP+FYX5kto280wEyh3KxNhlan+lmI
# IGo7V3Xv6UgGudJ/ZjR4dw24atFDcaqmdnWAOOp7mwxUIAq/5xLeDw2fzvuUw78a
# cc732SF4XwTJfXwgiXkJXa/Si248fDtecvlD+lQ9wezSIJZq8Ojpe9uFREA4jPVY
# jfgXEoopvam4w4ZKFRg93/0QErgwsYaJKKIKD8wZ99pi8/zrWlq5W1ujefQuvujt
# FL4IbF/8g6i22fZgBr8AlkRn3epxx4oRGV+Rr8OXoFYjNR/E7rjKZYfbsJx/gDbO
# zEMzSImQ48Tlxl9vkIx5kkUDxw3d7MDvrXEORcTMSW53CUDXJyA=
# =U151
# -----END PGP SIGNATURE-----
# gpg: Signature made Fri 06 Sep 2024 11:38:39 BST
# gpg:                using RSA key 5017D831597C78A3D907EEF712E2204C0E5DB602
# gpg: Good signature from "Jeuk Kim <jeuk20.kim@samsung.com>" [unknown]
# gpg:                 aka "Jeuk Kim <jeuk20.kim@gmail.com>" [unknown]
# gpg: WARNING: This key is not certified with a trusted signature!
# gpg:          There is no indication that the signature belongs to the owner.
# Primary key fingerprint: 5017 D831 597C 78A3 D907  EEF7 12E2 204C 0E5D B602

* tag 'pull-ufs-20240906' of https://gitlab.com/jeuk20.kim/qemu:
  hw/ufs: ufs descriptor read test implemented
  hw/ufs: ufs attribute read/write test implemented
  hw/ufs: ufs flag read/write test implemented
  hw/ufs: minor bug fixes related to ufs-test
  hw/ufs: add basic info of query response upiu

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'hw')
-rw-r--r--hw/ufs/ufs.c32
-rw-r--r--hw/ufs/ufs.h1
2 files changed, 23 insertions, 10 deletions
diff --git a/hw/ufs/ufs.c b/hw/ufs/ufs.c
index 945a0ea127..79f786ed4e 100644
--- a/hw/ufs/ufs.c
+++ b/hw/ufs/ufs.c
@@ -851,6 +851,14 @@ void ufs_build_upiu_header(UfsRequest *req, uint8_t trans_type, uint8_t flags,
     req->rsp_upiu.header.data_segment_length = cpu_to_be16(data_segment_length);
 }
 
+void ufs_build_query_response(UfsRequest *req)
+{
+    req->rsp_upiu.qr.opcode = req->req_upiu.qr.opcode;
+    req->rsp_upiu.qr.idn = req->req_upiu.qr.idn;
+    req->rsp_upiu.qr.index = req->req_upiu.qr.index;
+    req->rsp_upiu.qr.selector = req->req_upiu.qr.selector;
+}
+
 static UfsReqResult ufs_exec_scsi_cmd(UfsRequest *req)
 {
     UfsHc *u = req->hc;
@@ -1103,10 +1111,13 @@ static uint32_t ufs_read_attr_value(UfsHc *u, uint8_t idn)
     return 0;
 }
 
-static void ufs_write_attr_value(UfsHc *u, uint8_t idn, uint32_t value)
+static QueryRespCode ufs_write_attr_value(UfsHc *u, uint8_t idn, uint32_t value)
 {
     switch (idn) {
     case UFS_QUERY_ATTR_IDN_ACTIVE_ICC_LVL:
+        if (value > UFS_QUERY_ATTR_ACTIVE_ICC_MAXVALUE) {
+            return UFS_QUERY_RESULT_INVALID_VALUE;
+        }
         u->attributes.active_icc_level = value;
         break;
     case UFS_QUERY_ATTR_IDN_MAX_DATA_IN:
@@ -1134,6 +1145,7 @@ static void ufs_write_attr_value(UfsHc *u, uint8_t idn, uint32_t value)
         u->attributes.psa_data_size = cpu_to_be32(value);
         break;
     }
+    return UFS_QUERY_RESULT_SUCCESS;
 }
 
 static QueryRespCode ufs_exec_query_attr(UfsRequest *req, int op)
@@ -1150,13 +1162,13 @@ static QueryRespCode ufs_exec_query_attr(UfsRequest *req, int op)
 
     if (op == UFS_QUERY_ATTR_READ) {
         value = ufs_read_attr_value(u, idn);
+        ret = UFS_QUERY_RESULT_SUCCESS;
     } else {
-        value = be32_to_cpu(req->req_upiu.qr.value);
-        ufs_write_attr_value(u, idn, value);
+        value = req->req_upiu.qr.value;
+        ret = ufs_write_attr_value(u, idn, value);
     }
-
     req->rsp_upiu.qr.value = cpu_to_be32(value);
-    return UFS_QUERY_RESULT_SUCCESS;
+    return ret;
 }
 
 static const RpmbUnitDescriptor rpmb_unit_desc = {
@@ -1279,9 +1291,12 @@ static QueryRespCode ufs_read_desc(UfsRequest *req)
     UfsHc *u = req->hc;
     QueryRespCode status;
     uint8_t idn = req->req_upiu.qr.idn;
+    uint8_t selector = req->req_upiu.qr.selector;
     uint16_t length = be16_to_cpu(req->req_upiu.qr.length);
     InterconnectDescriptor desc;
-
+    if (selector != 0) {
+        return UFS_QUERY_RESULT_INVALID_SELECTOR;
+    }
     switch (idn) {
     case UFS_QUERY_DESC_IDN_DEVICE:
         memcpy(&req->rsp_upiu.qr.data, &u->device_desc, sizeof(u->device_desc));
@@ -1327,10 +1342,6 @@ static QueryRespCode ufs_read_desc(UfsRequest *req)
     if (length > req->rsp_upiu.qr.data[0]) {
         length = req->rsp_upiu.qr.data[0];
     }
-    req->rsp_upiu.qr.opcode = req->req_upiu.qr.opcode;
-    req->rsp_upiu.qr.idn = req->req_upiu.qr.idn;
-    req->rsp_upiu.qr.index = req->req_upiu.qr.index;
-    req->rsp_upiu.qr.selector = req->req_upiu.qr.selector;
     req->rsp_upiu.qr.length = cpu_to_be16(length);
 
     return status;
@@ -1411,6 +1422,7 @@ static UfsReqResult ufs_exec_query_cmd(UfsRequest *req)
     data_segment_length = be16_to_cpu(req->rsp_upiu.qr.length);
     ufs_build_upiu_header(req, UFS_UPIU_TRANSACTION_QUERY_RSP, 0, status, 0,
                           data_segment_length);
+    ufs_build_query_response(req);
 
     if (status != UFS_QUERY_RESULT_SUCCESS) {
         return UFS_REQUEST_FAIL;
diff --git a/hw/ufs/ufs.h b/hw/ufs/ufs.h
index 6c9382cbc4..4bcc41f53a 100644
--- a/hw/ufs/ufs.h
+++ b/hw/ufs/ufs.h
@@ -228,6 +228,7 @@ static inline bool is_wlun(uint8_t lun)
 void ufs_build_upiu_header(UfsRequest *req, uint8_t trans_type, uint8_t flags,
                            uint8_t response, uint8_t scsi_status,
                            uint16_t data_segment_length);
+void ufs_build_query_response(UfsRequest *req);
 void ufs_complete_req(UfsRequest *req, UfsReqResult req_result);
 void ufs_init_wlu(UfsLu *wlu, uint8_t wlun);
 #endif /* HW_UFS_UFS_H */