hw/ufs: minor bug fixes related to ufs-test

Minor bugs and errors related to ufs-test are resolved. Some
permissions and code implementations that are not synchronized
with the ufs spec are edited.

Signed-off-by: Yoochan Jeong <yc01.jeong@samsung.com>
Reviewed-by: Jeuk Kim <jeuk20.kim@samsung.com>
Signed-off-by: Jeuk Kim <jeuk20.kim@samsung.com>
This commit is contained in:
Yoochan Jeong 2024-08-22 17:09:50 +09:00 committed by Jeuk Kim
parent de2cc40782
commit 7c85332a2b
3 changed files with 27 additions and 9 deletions

View File

@ -1111,10 +1111,13 @@ static uint32_t ufs_read_attr_value(UfsHc *u, uint8_t idn)
return 0; 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) { switch (idn) {
case UFS_QUERY_ATTR_IDN_ACTIVE_ICC_LVL: 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; u->attributes.active_icc_level = value;
break; break;
case UFS_QUERY_ATTR_IDN_MAX_DATA_IN: case UFS_QUERY_ATTR_IDN_MAX_DATA_IN:
@ -1142,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); u->attributes.psa_data_size = cpu_to_be32(value);
break; break;
} }
return UFS_QUERY_RESULT_SUCCESS;
} }
static QueryRespCode ufs_exec_query_attr(UfsRequest *req, int op) static QueryRespCode ufs_exec_query_attr(UfsRequest *req, int op)
@ -1158,13 +1162,13 @@ static QueryRespCode ufs_exec_query_attr(UfsRequest *req, int op)
if (op == UFS_QUERY_ATTR_READ) { if (op == UFS_QUERY_ATTR_READ) {
value = ufs_read_attr_value(u, idn); value = ufs_read_attr_value(u, idn);
ret = UFS_QUERY_RESULT_SUCCESS;
} else { } else {
value = be32_to_cpu(req->req_upiu.qr.value); value = req->req_upiu.qr.value;
ufs_write_attr_value(u, idn, value); ret = ufs_write_attr_value(u, idn, value);
} }
req->rsp_upiu.qr.value = cpu_to_be32(value); req->rsp_upiu.qr.value = cpu_to_be32(value);
return UFS_QUERY_RESULT_SUCCESS; return ret;
} }
static const RpmbUnitDescriptor rpmb_unit_desc = { static const RpmbUnitDescriptor rpmb_unit_desc = {
@ -1287,9 +1291,12 @@ static QueryRespCode ufs_read_desc(UfsRequest *req)
UfsHc *u = req->hc; UfsHc *u = req->hc;
QueryRespCode status; QueryRespCode status;
uint8_t idn = req->req_upiu.qr.idn; 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); uint16_t length = be16_to_cpu(req->req_upiu.qr.length);
InterconnectDescriptor desc; InterconnectDescriptor desc;
if (selector != 0) {
return UFS_QUERY_RESULT_INVALID_SELECTOR;
}
switch (idn) { switch (idn) {
case UFS_QUERY_DESC_IDN_DEVICE: case UFS_QUERY_DESC_IDN_DEVICE:
memcpy(&req->rsp_upiu.qr.data, &u->device_desc, sizeof(u->device_desc)); memcpy(&req->rsp_upiu.qr.data, &u->device_desc, sizeof(u->device_desc));

View File

@ -763,6 +763,12 @@ typedef struct QEMU_PACKED UtpTaskReqDesc {
*/ */
#define UFS_WB_EXCEED_LIFETIME 0x0B #define UFS_WB_EXCEED_LIFETIME 0x0B
/*
* The range of valid value of Active ICC attritbute
* is from 0x00 to 0x0F.
*/
#define UFS_QUERY_ATTR_ACTIVE_ICC_MAXVALUE 0x0F
/* /*
* In UFS Spec, the Extra Header Segment (EHS) starts from byte 32 in UPIU * In UFS Spec, the Extra Header Segment (EHS) starts from byte 32 in UPIU
* request/response packet * request/response packet

View File

@ -119,6 +119,7 @@ static void ufs_send_nop_out(QUfs *ufs, uint8_t slot,
static void ufs_send_query(QUfs *ufs, uint8_t slot, uint8_t query_function, static void ufs_send_query(QUfs *ufs, uint8_t slot, uint8_t query_function,
uint8_t query_opcode, uint8_t idn, uint8_t index, uint8_t query_opcode, uint8_t idn, uint8_t index,
uint8_t selector, uint32_t attr_value,
UtpTransferReqDesc *utrd_out, UtpUpiuRsp *rsp_out) UtpTransferReqDesc *utrd_out, UtpUpiuRsp *rsp_out)
{ {
/* Build up utp transfer request descriptor */ /* Build up utp transfer request descriptor */
@ -136,13 +137,16 @@ static void ufs_send_query(QUfs *ufs, uint8_t slot, uint8_t query_function,
req_upiu.header.query_func = query_function; req_upiu.header.query_func = query_function;
req_upiu.header.task_tag = slot; req_upiu.header.task_tag = slot;
/* /*
* QEMU UFS does not currently support Write descriptor and Write attribute, * QEMU UFS does not currently support Write descriptor,
* so the value of data_segment_length is always 0. * so the value of data_segment_length is always 0.
*/ */
req_upiu.header.data_segment_length = 0; req_upiu.header.data_segment_length = 0;
req_upiu.qr.opcode = query_opcode; req_upiu.qr.opcode = query_opcode;
req_upiu.qr.idn = idn; req_upiu.qr.idn = idn;
req_upiu.qr.index = index; req_upiu.qr.index = index;
req_upiu.qr.selector = selector;
req_upiu.qr.value = attr_value;
req_upiu.qr.length = UFS_QUERY_DESC_MAX_SIZE;
qtest_memwrite(ufs->dev.bus->qts, req_upiu_addr, &req_upiu, qtest_memwrite(ufs->dev.bus->qts, req_upiu_addr, &req_upiu,
sizeof(req_upiu)); sizeof(req_upiu));
@ -344,7 +348,7 @@ static void ufs_init(QUfs *ufs, QGuestAllocator *alloc)
/* Set fDeviceInit flag via query request */ /* Set fDeviceInit flag via query request */
ufs_send_query(ufs, 0, UFS_UPIU_QUERY_FUNC_STANDARD_WRITE_REQUEST, ufs_send_query(ufs, 0, UFS_UPIU_QUERY_FUNC_STANDARD_WRITE_REQUEST,
UFS_UPIU_QUERY_OPCODE_SET_FLAG, UFS_UPIU_QUERY_OPCODE_SET_FLAG,
UFS_QUERY_FLAG_IDN_FDEVICEINIT, 0, &utrd, &rsp_upiu); UFS_QUERY_FLAG_IDN_FDEVICEINIT, 0, 0, 0, &utrd, &rsp_upiu);
g_assert_cmpuint(le32_to_cpu(utrd.header.dword_2), ==, UFS_OCS_SUCCESS); g_assert_cmpuint(le32_to_cpu(utrd.header.dword_2), ==, UFS_OCS_SUCCESS);
/* Wait for device to reset */ /* Wait for device to reset */
@ -353,7 +357,8 @@ static void ufs_init(QUfs *ufs, QGuestAllocator *alloc)
qtest_clock_step(ufs->dev.bus->qts, 100); qtest_clock_step(ufs->dev.bus->qts, 100);
ufs_send_query(ufs, 0, UFS_UPIU_QUERY_FUNC_STANDARD_READ_REQUEST, ufs_send_query(ufs, 0, UFS_UPIU_QUERY_FUNC_STANDARD_READ_REQUEST,
UFS_UPIU_QUERY_OPCODE_READ_FLAG, UFS_UPIU_QUERY_OPCODE_READ_FLAG,
UFS_QUERY_FLAG_IDN_FDEVICEINIT, 0, &utrd, &rsp_upiu); UFS_QUERY_FLAG_IDN_FDEVICEINIT, 0, 0, 0, &utrd,
&rsp_upiu);
} while (be32_to_cpu(rsp_upiu.qr.value) != 0 && } while (be32_to_cpu(rsp_upiu.qr.value) != 0 &&
g_get_monotonic_time() < end_time); g_get_monotonic_time() < end_time);
g_assert_cmpuint(be32_to_cpu(rsp_upiu.qr.value), ==, 0); g_assert_cmpuint(be32_to_cpu(rsp_upiu.qr.value), ==, 0);