diff mbox series

[v42,72/98] hw/sd/sdcard: Add sd_acmd_SD_APP_OP_COND handler (ACMD41)

Message ID 20240628070216.92609-73-philmd@linaro.org
State Superseded
Headers show
Series hw/sd/sdcard: Add eMMC support | expand

Commit Message

Philippe Mathieu-Daudé June 28, 2024, 7:01 a.m. UTC
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
---
 hw/sd/sd.c | 82 ++++++++++++++++++++++++++++++------------------------
 1 file changed, 45 insertions(+), 37 deletions(-)

Comments

Cédric Le Goater June 28, 2024, 8:03 a.m. UTC | #1
On 6/28/24 9:01 AM, Philippe Mathieu-Daudé wrote:
> Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>


Reviewed-by: Cédric Le Goater <clg@redhat.com>

Thanks,

C.


> ---
>   hw/sd/sd.c | 82 ++++++++++++++++++++++++++++++------------------------
>   1 file changed, 45 insertions(+), 37 deletions(-)
> 
> diff --git a/hw/sd/sd.c b/hw/sd/sd.c
> index cd207a3090..167e1c517a 100644
> --- a/hw/sd/sd.c
> +++ b/hw/sd/sd.c
> @@ -1704,6 +1704,50 @@ static sd_rsp_type_t sd_acmd_SET_WR_BLK_ERASE_COUNT(SDState *sd, SDRequest req)
>       return sd_r1;
>   }
>   
> +/* ACMD41 */
> +static sd_rsp_type_t sd_acmd_SD_APP_OP_COND(SDState *sd, SDRequest req)
> +{
> +    if (sd->state != sd_idle_state) {
> +        return sd_invalid_state_for_cmd(sd, req);
> +    }
> +
> +    /*
> +     * If it's the first ACMD41 since reset, we need to decide
> +     * whether to power up. If this is not an enquiry ACMD41,
> +     * we immediately report power on and proceed below to the
> +     * ready state, but if it is, we set a timer to model a
> +     * delay for power up. This works around a bug in EDK2
> +     * UEFI, which sends an initial enquiry ACMD41, but
> +     * assumes that the card is in ready state as soon as it
> +     * sees the power up bit set.
> +     */
> +    if (!FIELD_EX32(sd->ocr, OCR, CARD_POWER_UP)) {
> +        if ((req.arg & ACMD41_ENQUIRY_MASK) != 0) {
> +            timer_del(sd->ocr_power_timer);
> +            sd_ocr_powerup(sd);
> +        } else {
> +            trace_sdcard_inquiry_cmd41();
> +            if (!timer_pending(sd->ocr_power_timer)) {
> +                timer_mod_ns(sd->ocr_power_timer,
> +                             (qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL)
> +                              + OCR_POWER_DELAY_NS));
> +            }
> +        }
> +    }
> +
> +    if (FIELD_EX32(sd->ocr & req.arg, OCR, VDD_VOLTAGE_WINDOW)) {
> +        /*
> +         * We accept any voltage.  10000 V is nothing.
> +         *
> +         * Once we're powered up, we advance straight to ready state
> +         * unless it's an enquiry ACMD41 (bits 23:0 == 0).
> +         */
> +        sd->state = sd_ready_state;
> +    }
> +
> +    return sd_r3;
> +}
> +
>   static sd_rsp_type_t sd_normal_command(SDState *sd, SDRequest req)
>   {
>       uint64_t addr;
> @@ -1812,43 +1856,6 @@ static sd_rsp_type_t sd_app_command(SDState *sd,
>       }
>   
>       switch (req.cmd) {
> -    case 41:  /* ACMD41: SD_APP_OP_COND */
> -        if (sd->state != sd_idle_state) {
> -            break;
> -        }
> -        /* If it's the first ACMD41 since reset, we need to decide
> -         * whether to power up. If this is not an enquiry ACMD41,
> -         * we immediately report power on and proceed below to the
> -         * ready state, but if it is, we set a timer to model a
> -         * delay for power up. This works around a bug in EDK2
> -         * UEFI, which sends an initial enquiry ACMD41, but
> -         * assumes that the card is in ready state as soon as it
> -         * sees the power up bit set. */
> -        if (!FIELD_EX32(sd->ocr, OCR, CARD_POWER_UP)) {
> -            if ((req.arg & ACMD41_ENQUIRY_MASK) != 0) {
> -                timer_del(sd->ocr_power_timer);
> -                sd_ocr_powerup(sd);
> -            } else {
> -                trace_sdcard_inquiry_cmd41();
> -                if (!timer_pending(sd->ocr_power_timer)) {
> -                    timer_mod_ns(sd->ocr_power_timer,
> -                                 (qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL)
> -                                  + OCR_POWER_DELAY_NS));
> -                }
> -            }
> -        }
> -
> -        if (FIELD_EX32(sd->ocr & req.arg, OCR, VDD_VOLTAGE_WINDOW)) {
> -            /* We accept any voltage.  10000 V is nothing.
> -             *
> -             * Once we're powered up, we advance straight to ready state
> -             * unless it's an enquiry ACMD41 (bits 23:0 == 0).
> -             */
> -            sd->state = sd_ready_state;
> -        }
> -
> -        return sd_r3;
> -
>       case 42:  /* ACMD42: SET_CLR_CARD_DETECT */
>           switch (sd->state) {
>           case sd_transfer_state:
> @@ -2379,6 +2386,7 @@ static const SDProto sd_proto_sd = {
>           [13] = {8,  sd_adtc, "SD_STATUS", sd_acmd_SD_STATUS},
>           [22] = {8,  sd_adtc, "SEND_NUM_WR_BLOCKS", sd_acmd_SEND_NUM_WR_BLOCKS},
>           [23] = {8,  sd_ac,   "SET_WR_BLK_ERASE_COUNT", sd_acmd_SET_WR_BLK_ERASE_COUNT},
> +        [41] = {8,  sd_bcr,  "SD_APP_OP_COND", sd_acmd_SD_APP_OP_COND},
>       },
>   };
>
diff mbox series

Patch

diff --git a/hw/sd/sd.c b/hw/sd/sd.c
index cd207a3090..167e1c517a 100644
--- a/hw/sd/sd.c
+++ b/hw/sd/sd.c
@@ -1704,6 +1704,50 @@  static sd_rsp_type_t sd_acmd_SET_WR_BLK_ERASE_COUNT(SDState *sd, SDRequest req)
     return sd_r1;
 }
 
+/* ACMD41 */
+static sd_rsp_type_t sd_acmd_SD_APP_OP_COND(SDState *sd, SDRequest req)
+{
+    if (sd->state != sd_idle_state) {
+        return sd_invalid_state_for_cmd(sd, req);
+    }
+
+    /*
+     * If it's the first ACMD41 since reset, we need to decide
+     * whether to power up. If this is not an enquiry ACMD41,
+     * we immediately report power on and proceed below to the
+     * ready state, but if it is, we set a timer to model a
+     * delay for power up. This works around a bug in EDK2
+     * UEFI, which sends an initial enquiry ACMD41, but
+     * assumes that the card is in ready state as soon as it
+     * sees the power up bit set.
+     */
+    if (!FIELD_EX32(sd->ocr, OCR, CARD_POWER_UP)) {
+        if ((req.arg & ACMD41_ENQUIRY_MASK) != 0) {
+            timer_del(sd->ocr_power_timer);
+            sd_ocr_powerup(sd);
+        } else {
+            trace_sdcard_inquiry_cmd41();
+            if (!timer_pending(sd->ocr_power_timer)) {
+                timer_mod_ns(sd->ocr_power_timer,
+                             (qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL)
+                              + OCR_POWER_DELAY_NS));
+            }
+        }
+    }
+
+    if (FIELD_EX32(sd->ocr & req.arg, OCR, VDD_VOLTAGE_WINDOW)) {
+        /*
+         * We accept any voltage.  10000 V is nothing.
+         *
+         * Once we're powered up, we advance straight to ready state
+         * unless it's an enquiry ACMD41 (bits 23:0 == 0).
+         */
+        sd->state = sd_ready_state;
+    }
+
+    return sd_r3;
+}
+
 static sd_rsp_type_t sd_normal_command(SDState *sd, SDRequest req)
 {
     uint64_t addr;
@@ -1812,43 +1856,6 @@  static sd_rsp_type_t sd_app_command(SDState *sd,
     }
 
     switch (req.cmd) {
-    case 41:  /* ACMD41: SD_APP_OP_COND */
-        if (sd->state != sd_idle_state) {
-            break;
-        }
-        /* If it's the first ACMD41 since reset, we need to decide
-         * whether to power up. If this is not an enquiry ACMD41,
-         * we immediately report power on and proceed below to the
-         * ready state, but if it is, we set a timer to model a
-         * delay for power up. This works around a bug in EDK2
-         * UEFI, which sends an initial enquiry ACMD41, but
-         * assumes that the card is in ready state as soon as it
-         * sees the power up bit set. */
-        if (!FIELD_EX32(sd->ocr, OCR, CARD_POWER_UP)) {
-            if ((req.arg & ACMD41_ENQUIRY_MASK) != 0) {
-                timer_del(sd->ocr_power_timer);
-                sd_ocr_powerup(sd);
-            } else {
-                trace_sdcard_inquiry_cmd41();
-                if (!timer_pending(sd->ocr_power_timer)) {
-                    timer_mod_ns(sd->ocr_power_timer,
-                                 (qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL)
-                                  + OCR_POWER_DELAY_NS));
-                }
-            }
-        }
-
-        if (FIELD_EX32(sd->ocr & req.arg, OCR, VDD_VOLTAGE_WINDOW)) {
-            /* We accept any voltage.  10000 V is nothing.
-             *
-             * Once we're powered up, we advance straight to ready state
-             * unless it's an enquiry ACMD41 (bits 23:0 == 0).
-             */
-            sd->state = sd_ready_state;
-        }
-
-        return sd_r3;
-
     case 42:  /* ACMD42: SET_CLR_CARD_DETECT */
         switch (sd->state) {
         case sd_transfer_state:
@@ -2379,6 +2386,7 @@  static const SDProto sd_proto_sd = {
         [13] = {8,  sd_adtc, "SD_STATUS", sd_acmd_SD_STATUS},
         [22] = {8,  sd_adtc, "SEND_NUM_WR_BLOCKS", sd_acmd_SEND_NUM_WR_BLOCKS},
         [23] = {8,  sd_ac,   "SET_WR_BLK_ERASE_COUNT", sd_acmd_SET_WR_BLK_ERASE_COUNT},
+        [41] = {8,  sd_bcr,  "SD_APP_OP_COND", sd_acmd_SD_APP_OP_COND},
     },
 };