qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: "Philippe Mathieu-Daudé" <philmd@linaro.org>
To: qemu-devel@nongnu.org
Cc: "Keoseong Park" <keosung.park@samsung.com>,
	"Jeuk Kim" <jeuk20.kim@samsung.com>,
	"Philippe Mathieu-Daudé" <philmd@linaro.org>
Subject: [PULL 31/41] hw/ufs: Add temperature event notification support
Date: Wed,  5 Mar 2025 02:21:46 +0100	[thread overview]
Message-ID: <20250305012157.96463-32-philmd@linaro.org> (raw)
In-Reply-To: <20250305012157.96463-1-philmd@linaro.org>

From: Keoseong Park <keosung.park@samsung.com>

This patch introduces temperature event notification support to the UFS
emulation. It enables the emulated UFS device to generate
temperature-related events, including high and low temperature
notifications, in compliance with the UFS specification.

With this feature, UFS drivers can now handle temperature exception events
during testing and development within the emulated environment.
This enhances validation and debugging capabilities for thermal event
handling in UFS implementations.

Signed-off-by: Keoseong Park <keosung.park@samsung.com>
Reviewed-by: Jeuk Kim <jeuk20.kim@samsung.com>
Message-ID: <20250225064146epcms2p50889cb0066e2d4734f2386de325bcdf6@epcms2p5>
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
---
 hw/ufs/ufs.h        |  2 ++
 include/block/ufs.h | 13 +++++++-
 hw/ufs/ufs.c        | 78 ++++++++++++++++++++++++++++++++++++++++++++-
 3 files changed, 91 insertions(+), 2 deletions(-)

diff --git a/hw/ufs/ufs.h b/hw/ufs/ufs.h
index 4bcc41f53a0..3799d97f30d 100644
--- a/hw/ufs/ufs.h
+++ b/hw/ufs/ufs.h
@@ -146,6 +146,8 @@ typedef struct UfsHc {
     /* MCQ properties */
     UfsSq *sq[UFS_MAX_MCQ_QNUM];
     UfsCq *cq[UFS_MAX_MCQ_QNUM];
+
+    uint8_t temperature;
 } UfsHc;
 
 static inline uint32_t ufs_mcq_sq_tail(UfsHc *u, uint32_t qid)
diff --git a/include/block/ufs.h b/include/block/ufs.h
index 57f5ea3500c..a3ee62b027a 100644
--- a/include/block/ufs.h
+++ b/include/block/ufs.h
@@ -461,7 +461,7 @@ typedef struct Attributes {
     uint8_t psa_state;
     uint32_t psa_data_size;
     uint8_t ref_clk_gating_wait_time;
-    uint8_t device_case_rough_temperaure;
+    uint8_t device_case_rough_temperature;
     uint8_t device_too_high_temp_boundary;
     uint8_t device_too_low_temp_boundary;
     uint8_t throttling_status;
@@ -1073,6 +1073,11 @@ enum health_desc_param {
     UFS_HEALTH_DESC_PARAM_LIFE_TIME_EST_B = 0x4,
 };
 
+enum {
+    UFS_DEV_HIGH_TEMP_NOTIF = BIT(4),
+    UFS_DEV_LOW_TEMP_NOTIF = BIT(5),
+};
+
 /* WriteBooster buffer mode */
 enum {
     UFS_WB_BUF_MODE_LU_DEDICATED = 0x0,
@@ -1091,6 +1096,12 @@ enum ufs_lu_wp_type {
     UFS_LU_PERM_WP = 0x02,
 };
 
+/* Exception event mask values */
+enum {
+    MASK_EE_TOO_HIGH_TEMP = BIT(3),
+    MASK_EE_TOO_LOW_TEMP = BIT(4),
+};
+
 /* UTP QUERY Transaction Specific Fields OpCode */
 enum query_opcode {
     UFS_UPIU_QUERY_OPCODE_NOP = 0x0,
diff --git a/hw/ufs/ufs.c b/hw/ufs/ufs.c
index 1ccd6f88b69..857de6e9c2c 100644
--- a/hw/ufs/ufs.c
+++ b/hw/ufs/ufs.c
@@ -34,6 +34,11 @@
 #define UFS_MAX_NUTMRS 8
 #define UFS_MCQ_QCFGPTR 2
 
+/* Each value represents the temperature in celsius as (value - 80) */
+#define UFS_TEMPERATURE 120
+#define UFS_TOO_HIGH_TEMP_BOUNDARY 160
+#define UFS_TOO_LOW_TEMP_BOUNDARY 60
+
 static void ufs_exec_req(UfsRequest *req);
 static void ufs_clear_req(UfsRequest *req);
 
@@ -838,6 +843,42 @@ static const MemoryRegionOps ufs_mmio_ops = {
     },
 };
 
+static void ufs_update_ee_status(UfsHc *u)
+{
+    uint16_t ee_status = be16_to_cpu(u->attributes.exception_event_status);
+    uint8_t high_temp_thresh = u->attributes.device_too_high_temp_boundary;
+    uint8_t low_temp_thresh = u->attributes.device_too_low_temp_boundary;
+
+    if (u->temperature >= high_temp_thresh) {
+        ee_status |= MASK_EE_TOO_HIGH_TEMP;
+    } else {
+        ee_status &= ~MASK_EE_TOO_HIGH_TEMP;
+    }
+
+    if (u->temperature <= low_temp_thresh) {
+        ee_status |= MASK_EE_TOO_LOW_TEMP;
+    } else {
+        ee_status &= ~MASK_EE_TOO_LOW_TEMP;
+    }
+
+    u->attributes.exception_event_status = cpu_to_be16(ee_status);
+}
+
+static bool ufs_check_exception_event_alert(UfsHc *u, uint8_t trans_type)
+{
+    uint16_t ee_control = be16_to_cpu(u->attributes.exception_event_control);
+    uint16_t ee_status;
+
+    if (trans_type != UFS_UPIU_TRANSACTION_RESPONSE) {
+        return false;
+    }
+
+    ufs_update_ee_status(u);
+
+    ee_status = be16_to_cpu(u->attributes.exception_event_status);
+
+    return ee_control & ee_status;
+}
 
 void ufs_build_upiu_header(UfsRequest *req, uint8_t trans_type, uint8_t flags,
                            uint8_t response, uint8_t scsi_status,
@@ -848,6 +889,8 @@ void ufs_build_upiu_header(UfsRequest *req, uint8_t trans_type, uint8_t flags,
     req->rsp_upiu.header.flags = flags;
     req->rsp_upiu.header.response = response;
     req->rsp_upiu.header.scsi_status = scsi_status;
+    req->rsp_upiu.header.device_inf =
+        ufs_check_exception_event_alert(req->hc, trans_type);
     req->rsp_upiu.header.data_segment_length = cpu_to_be16(data_segment_length);
 }
 
@@ -1042,6 +1085,25 @@ static QueryRespCode ufs_exec_query_flag(UfsRequest *req, int op)
     return UFS_QUERY_RESULT_SUCCESS;
 }
 
+static inline uint8_t ufs_read_device_temp(UfsHc *u)
+{
+    uint8_t feat_sup = u->device_desc.ufs_features_support;
+    bool high_temp_sup, low_temp_sup, high_temp_en, low_temp_en;
+    uint16_t ee_control = be16_to_cpu(u->attributes.exception_event_control);
+
+    high_temp_sup = feat_sup & UFS_DEV_HIGH_TEMP_NOTIF;
+    low_temp_sup = feat_sup & UFS_DEV_LOW_TEMP_NOTIF;
+    high_temp_en = ee_control & MASK_EE_TOO_HIGH_TEMP;
+    low_temp_en = ee_control & MASK_EE_TOO_LOW_TEMP;
+
+    if ((high_temp_sup && high_temp_en) ||
+        (low_temp_sup && low_temp_en)) {
+        return u->temperature;
+    }
+
+    return 0;
+}
+
 static uint32_t ufs_read_attr_value(UfsHc *u, uint8_t idn)
 {
     switch (idn) {
@@ -1072,6 +1134,7 @@ static uint32_t ufs_read_attr_value(UfsHc *u, uint8_t idn)
     case UFS_QUERY_ATTR_IDN_EE_CONTROL:
         return be16_to_cpu(u->attributes.exception_event_control);
     case UFS_QUERY_ATTR_IDN_EE_STATUS:
+        ufs_update_ee_status(u);
         return be16_to_cpu(u->attributes.exception_event_status);
     case UFS_QUERY_ATTR_IDN_SECONDS_PASSED:
         return be32_to_cpu(u->attributes.seconds_passed);
@@ -1086,7 +1149,8 @@ static uint32_t ufs_read_attr_value(UfsHc *u, uint8_t idn)
     case UFS_QUERY_ATTR_IDN_REF_CLK_GATING_WAIT_TIME:
         return u->attributes.ref_clk_gating_wait_time;
     case UFS_QUERY_ATTR_IDN_CASE_ROUGH_TEMP:
-        return u->attributes.device_case_rough_temperaure;
+        u->attributes.device_case_rough_temperature = ufs_read_device_temp(u);
+        return u->attributes.device_case_rough_temperature;
     case UFS_QUERY_ATTR_IDN_HIGH_TEMP_BOUND:
         return u->attributes.device_too_high_temp_boundary;
     case UFS_QUERY_ATTR_IDN_LOW_TEMP_BOUND:
@@ -1677,8 +1741,12 @@ static void ufs_init_hc(UfsHc *u)
     u->device_desc.ud_0_base_offset = 0x16;
     u->device_desc.ud_config_p_length = 0x1A;
     u->device_desc.device_rtt_cap = 0x02;
+    u->device_desc.ufs_features_support = UFS_DEV_HIGH_TEMP_NOTIF |
+        UFS_DEV_LOW_TEMP_NOTIF;
     u->device_desc.queue_depth = u->params.nutrs;
     u->device_desc.product_revision_level = 0x04;
+    u->device_desc.extended_ufs_features_support =
+        cpu_to_be32(UFS_DEV_HIGH_TEMP_NOTIF | UFS_DEV_LOW_TEMP_NOTIF);
 
     memset(&u->geometry_desc, 0, sizeof(GeometryDescriptor));
     u->geometry_desc.length = sizeof(GeometryDescriptor);
@@ -1702,9 +1770,17 @@ static void ufs_init_hc(UfsHc *u)
     /* configure descriptor is not supported */
     u->attributes.config_descr_lock = 0x01;
     u->attributes.max_num_of_rtt = 0x02;
+    u->attributes.device_too_high_temp_boundary = UFS_TOO_HIGH_TEMP_BOUNDARY;
+    u->attributes.device_too_low_temp_boundary = UFS_TOO_LOW_TEMP_BOUNDARY;
 
     memset(&u->flags, 0, sizeof(u->flags));
     u->flags.permanently_disable_fw_update = 1;
+
+    /*
+     * The temperature value is fixed to UFS_TEMPERATURE and does not change
+     * dynamically
+     */
+    u->temperature = UFS_TEMPERATURE;
 }
 
 static void ufs_realize(PCIDevice *pci_dev, Error **errp)
-- 
2.47.1



  parent reply	other threads:[~2025-03-05  1:27 UTC|newest]

Thread overview: 45+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-03-05  1:21 [PULL 00/41] Misc HW patches for 2025-03-05 Philippe Mathieu-Daudé
2025-03-05  1:21 ` [PULL 01/41] hw/intc: Remove TCG dependency on ARM_GICV3 Philippe Mathieu-Daudé
2025-03-05  1:21 ` [PULL 02/41] hw/misc/pvpanic: Add MMIO interface Philippe Mathieu-Daudé
2025-03-05  1:21 ` [PULL 03/41] hw: Add vmapple subdir Philippe Mathieu-Daudé
2025-03-05  1:21 ` [PULL 04/41] hw/vmapple/aes: Introduce aes engine Philippe Mathieu-Daudé
2025-03-05  1:21 ` [PULL 05/41] hw/vmapple/bdif: Introduce vmapple backdoor interface Philippe Mathieu-Daudé
2025-03-05  1:21 ` [PULL 06/41] hw/vmapple/cfg: Introduce vmapple cfg region Philippe Mathieu-Daudé
2025-03-05  1:21 ` [PULL 07/41] hw/vmapple/virtio-blk: Add support for apple virtio-blk Philippe Mathieu-Daudé
2025-03-05  1:21 ` [PULL 08/41] hw/usb/hcd-xhci-pci: Adds property for disabling mapping in IRQ mode Philippe Mathieu-Daudé
2025-03-05  1:21 ` [PULL 09/41] hw/vmapple/vmapple: Add vmapple machine type Philippe Mathieu-Daudé
2025-03-10  1:22   ` Philippe Mathieu-Daudé
2025-03-05  1:21 ` [PULL 10/41] hw/ppc/spapr: Restrict part of PAGE_INIT hypercall to TCG Philippe Mathieu-Daudé
2025-03-05  1:21 ` [PULL 11/41] hw/acpi/ghes: Make ghes_record_cper_errors() static Philippe Mathieu-Daudé
2025-03-06 22:36   ` Mauro Carvalho Chehab
2025-03-07 12:41     ` Philippe Mathieu-Daudé
2025-03-05  1:21 ` [PULL 12/41] hw/arm: Do not expose the virt machine on Xen-only binary Philippe Mathieu-Daudé
2025-03-05  1:21 ` [PULL 13/41] hw/xen: Link XenPVH with GPEX PCIe bridge Philippe Mathieu-Daudé
2025-03-05  1:21 ` [PULL 14/41] hw/xen/xen-pvh: Reduce included headers Philippe Mathieu-Daudé
2025-03-05  1:21 ` [PULL 15/41] hw/xen/xen-hvm: " Philippe Mathieu-Daudé
2025-03-05  1:21 ` [PULL 16/41] hw/xen/xen-bus: " Philippe Mathieu-Daudé
2025-03-05  1:21 ` [PULL 17/41] hw/xen/xen-legacy-backend: Remove unused 'net/net.h' header Philippe Mathieu-Daudé
2025-03-05  1:21 ` [PULL 18/41] hw/net/fsl_etsec: Set eTSEC device description and category Philippe Mathieu-Daudé
2025-03-05  1:21 ` [PULL 19/41] hw/char/pl011: Warn when using disabled receiver Philippe Mathieu-Daudé
2025-03-05  1:21 ` [PULL 20/41] hw/char/pl011: Simplify a bit pl011_can_receive() Philippe Mathieu-Daudé
2025-03-05  1:21 ` [PULL 21/41] hw/char/pl011: Improve RX flow tracing events Philippe Mathieu-Daudé
2025-03-05  1:21 ` [PULL 22/41] hw/char/pl011: Really use RX FIFO depth Philippe Mathieu-Daudé
2025-03-05  1:21 ` [PULL 23/41] hw/char/bcm2835_aux: " Philippe Mathieu-Daudé
2025-03-05  1:21 ` [PULL 24/41] hw/char/imx_serial: " Philippe Mathieu-Daudé
2025-03-05  1:21 ` [PULL 25/41] hw/char/mcf_uart: Use FIFO_DEPTH definition instead of magic values Philippe Mathieu-Daudé
2025-03-05  1:21 ` [PULL 26/41] hw/char/mcf_uart: Really use RX FIFO depth Philippe Mathieu-Daudé
2025-03-05  1:21 ` [PULL 27/41] hw/char/sh_serial: Return correct number of empty RX FIFO elements Philippe Mathieu-Daudé
2025-03-05  1:21 ` [PULL 28/41] hw/char/sifive_uart: Free fifo on unrealize Philippe Mathieu-Daudé
2025-03-05  1:21 ` [PULL 29/41] hw/misc/macio: Improve trace logs Philippe Mathieu-Daudé
2025-03-05  1:21 ` [PULL 30/41] hw/misc/macio/gpio: Add constants for register bits Philippe Mathieu-Daudé
2025-03-05  1:21 ` Philippe Mathieu-Daudé [this message]
2025-03-05  1:21 ` [PULL 32/41] tests/qtest/ufs-test: Add test code for the temperature feature Philippe Mathieu-Daudé
2025-03-05  1:21 ` [PULL 33/41] hw/arm/omap1: Convert raw printfs to qemu_log_mask() Philippe Mathieu-Daudé
2025-03-05  1:21 ` [PULL 34/41] hw/arm/omap1: Drop ALMDEBUG ifdeffed out code Philippe Mathieu-Daudé
2025-03-05  1:21 ` [PULL 35/41] hw/arm/omap1: Convert information printfs to tracepoints Philippe Mathieu-Daudé
2025-03-05  1:21 ` [PULL 36/41] hw/arm/omap_sx1: Remove ifdeffed out debug printf Philippe Mathieu-Daudé
2025-03-05  1:21 ` [PULL 37/41] hw/arm/versatilepb: Convert printfs to LOG_GUEST_ERROR Philippe Mathieu-Daudé
2025-03-05  1:21 ` [PULL 38/41] hw/nvram/eeprom_at24c: Use OBJECT_DECLARE_SIMPLE_TYPE Philippe Mathieu-Daudé
2025-03-05  1:21 ` [PULL 39/41] hw/nvram/eeprom_at24c: Remove ERR macro that calls fprintf to stderr Philippe Mathieu-Daudé
2025-03-05  1:21 ` [PULL 40/41] hw/nvram/eeprom_at24c: Remove memset after g_malloc0 Philippe Mathieu-Daudé
2025-03-05  1:21 ` [PULL 41/41] hw/nvram/eeprom_at24c: Reorganise init to avoid overwriting values Philippe Mathieu-Daudé

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20250305012157.96463-32-philmd@linaro.org \
    --to=philmd@linaro.org \
    --cc=jeuk20.kim@samsung.com \
    --cc=keosung.park@samsung.com \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).