[PATCH v4 3/3] docs/system/arm: Add a doc for zynq board

2024-06-21 Thread Sai Pavan Boddu
Added the supported device list and an example command.

Signed-off-by: Sai Pavan Boddu 
Reviewed-by: Edgar E. Iglesias 
Reviewed-by: Francisco Iglesias 
---
 MAINTAINERS   |  1 +
 docs/system/arm/xlnx-zynq.rst | 47 +++
 docs/system/target-arm.rst|  1 +
 3 files changed, 49 insertions(+)
 create mode 100644 docs/system/arm/xlnx-zynq.rst

diff --git a/MAINTAINERS b/MAINTAINERS
index 951556224a1..2f06febc676 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1033,6 +1033,7 @@ F: hw/adc/zynq-xadc.c
 F: include/hw/misc/zynq_slcr.h
 F: include/hw/adc/zynq-xadc.h
 X: hw/ssi/xilinx_*
+F: docs/system/arm/xlnx-zynq.rst
 
 Xilinx ZynqMP and Versal
 M: Alistair Francis 
diff --git a/docs/system/arm/xlnx-zynq.rst b/docs/system/arm/xlnx-zynq.rst
new file mode 100644
index 000..ade18a3fe13
--- /dev/null
+++ b/docs/system/arm/xlnx-zynq.rst
@@ -0,0 +1,47 @@
+Xilinx Zynq board (``xilinx-zynq-a9``)
+==
+The Zynq 7000 family is based on the AMD SoC architecture. These products
+integrate a feature-rich dual or single-core Arm Cortex-A9 MPCore based
+processing system (PS) and AMD programmable logic (PL) in a single device.
+
+More details here:
+https://docs.amd.com/r/en-US/ug585-zynq-7000-SoC-TRM/Zynq-7000-SoC-Technical-Reference-Manual
+
+QEMU xilinx-zynq-a9 board supports following devices:
+- A9 MPCORE
+- cortex-a9
+- GIC v1
+- Generic timer
+- wdt
+- OCM 256KB
+- SMC SRAM@0xe200 64MB
+- Zynq SLCR
+- SPI x2
+- QSPI
+- UART
+- TTC x2
+- Gigabit Ethernet Controller x2
+- SD Controller x2
+- XADC
+- Arm PrimeCell DMA Controller
+- DDR Memory
+- USB 2.0 x2
+
+Running
+"""""""
+Direct Linux boot of a generic ARM upstream Linux kernel:
+
+.. code-block:: bash
+
+  $ qemu-system-aarch64 -M xilinx-zynq-a9 \
+-dtb zynq-zc702.dtb  -serial null -serial mon:stdio \
+-display none  -m 1024 \
+-initrd rootfs.cpio.gz -kernel zImage
+
+For configuring the boot-mode provide the following on the command line:
+
+.. code-block:: bash
+
+   -machine boot-mode=qspi
+
+Supported values are jtag, sd, qspi, nor.
diff --git a/docs/system/target-arm.rst b/docs/system/target-arm.rst
index 870d30e3502..7b992722846 100644
--- a/docs/system/target-arm.rst
+++ b/docs/system/target-arm.rst
@@ -109,6 +109,7 @@ undocumented; you can get a complete list by running
arm/virt
arm/xenpvh
arm/xlnx-versal-virt
+   arm/xlnx-zynq
 
 Emulated CPU architecture support
 =
-- 
2.34.1




[PATCH v4 1/3] hw/misc/zynq_slcr: Add boot-mode property

2024-06-21 Thread Sai Pavan Boddu
boot-mode property sets user values into BOOT_MODE register, on hardware
these are derived from board switches.

Signed-off-by: Sai Pavan Boddu 
Reviewed-by: Edgar E. Iglesias 
Reviewed-by: Francisco Iglesias 
---
 hw/misc/zynq_slcr.c | 22 +-
 1 file changed, 21 insertions(+), 1 deletion(-)

diff --git a/hw/misc/zynq_slcr.c b/hw/misc/zynq_slcr.c
index 3412ff099ea..ad814c3a79b 100644
--- a/hw/misc/zynq_slcr.c
+++ b/hw/misc/zynq_slcr.c
@@ -24,6 +24,8 @@
 #include "hw/registerfields.h"
 #include "hw/qdev-clock.h"
 #include "qom/object.h"
+#include "hw/qdev-properties.h"
+#include "qapi/error.h"
 
 #ifndef ZYNQ_SLCR_ERR_DEBUG
 #define ZYNQ_SLCR_ERR_DEBUG 0
@@ -121,6 +123,7 @@ REG32(RST_REASON, 0x250)
 
 REG32(REBOOT_STATUS, 0x258)
 REG32(BOOT_MODE, 0x25c)
+FIELD(BOOT_MODE, BOOT_MODE, 0, 4)
 
 REG32(APU_CTRL, 0x300)
 REG32(WDT_CLK_SEL, 0x304)
@@ -195,6 +198,7 @@ struct ZynqSLCRState {
 Clock *ps_clk;
 Clock *uart0_ref_clk;
 Clock *uart1_ref_clk;
+uint8_t boot_mode;
 };
 
 /*
@@ -371,7 +375,7 @@ static void zynq_slcr_reset_init(Object *obj, ResetType 
type)
 s->regs[R_FPGA_RST_CTRL]  = 0x01F33F0F;
 s->regs[R_RST_REASON] = 0x0040;
 
-s->regs[R_BOOT_MODE]  = 0x0001;
+s->regs[R_BOOT_MODE]  = s->boot_mode & R_BOOT_MODE_BOOT_MODE_MASK;
 
 /* 0x700 - 0x7D4 */
 for (i = 0; i < 54; i++) {
@@ -588,6 +592,15 @@ static const ClockPortInitArray zynq_slcr_clocks = {
 QDEV_CLOCK_END
 };
 
+static void zynq_slcr_realize(DeviceState *dev, Error **errp)
+{
+ZynqSLCRState *s = ZYNQ_SLCR(dev);
+
+if (s->boot_mode > 0xF) {
+error_setg(errp, "Invalid boot mode %d specified", s->boot_mode);
+}
+}
+
 static void zynq_slcr_init(Object *obj)
 {
 ZynqSLCRState *s = ZYNQ_SLCR(obj);
@@ -610,15 +623,22 @@ static const VMStateDescription vmstate_zynq_slcr = {
 }
 };
 
+static Property zynq_slcr_props[] = {
+DEFINE_PROP_UINT8("boot-mode", ZynqSLCRState, boot_mode, 1),
+DEFINE_PROP_END_OF_LIST(),
+};
+
 static void zynq_slcr_class_init(ObjectClass *klass, void *data)
 {
 DeviceClass *dc = DEVICE_CLASS(klass);
 ResettableClass *rc = RESETTABLE_CLASS(klass);
 
 dc->vmsd = _zynq_slcr;
+dc->realize = zynq_slcr_realize;
 rc->phases.enter = zynq_slcr_reset_init;
 rc->phases.hold  = zynq_slcr_reset_hold;
 rc->phases.exit  = zynq_slcr_reset_exit;
+device_class_set_props(dc, zynq_slcr_props);
 }
 
 static const TypeInfo zynq_slcr_info = {
-- 
2.34.1




[PATCH v4 2/3] hw/arm/xilinx_zynq: Add boot-mode property

2024-06-21 Thread Sai Pavan Boddu
Read boot-mode value as machine property and propagate that to
SLCR.BOOT_MODE register.

Signed-off-by: Sai Pavan Boddu 
Acked-by: Edgar E. Iglesias 
Reviewed-by: Francisco Iglesias 
---
 hw/arm/xilinx_zynq.c | 31 +++
 1 file changed, 31 insertions(+)

diff --git a/hw/arm/xilinx_zynq.c b/hw/arm/xilinx_zynq.c
index 7f7a3d23fbe..97b6fd8e35d 100644
--- a/hw/arm/xilinx_zynq.c
+++ b/hw/arm/xilinx_zynq.c
@@ -38,6 +38,7 @@
 #include "qom/object.h"
 #include "exec/tswap.h"
 #include "target/arm/cpu-qom.h"
+#include "qapi/visitor.h"
 
 #define TYPE_ZYNQ_MACHINE MACHINE_TYPE_NAME("xilinx-zynq-a9")
 OBJECT_DECLARE_SIMPLE_TYPE(ZynqMachineState, ZYNQ_MACHINE)
@@ -90,6 +91,7 @@ struct ZynqMachineState {
 MachineState parent;
 Clock *ps_clk;
 ARMCPU *cpu[ZYNQ_MAX_CPUS];
+uint8_t boot_mode;
 };
 
 static void zynq_write_board_setup(ARMCPU *cpu,
@@ -176,6 +178,27 @@ static inline int zynq_init_spi_flashes(uint32_t 
base_addr, qemu_irq irq,
 return unit;
 }
 
+static void zynq_set_boot_mode(Object *obj, const char *str,
+   Error **errp)
+{
+ZynqMachineState *m = ZYNQ_MACHINE(obj);
+uint8_t mode = 0;
+
+if (!strncasecmp(str, "qspi", 4)) {
+mode = 1;
+} else if (!strncasecmp(str, "sd", 2)) {
+mode = 5;
+} else if (!strncasecmp(str, "nor", 3)) {
+mode = 2;
+} else if (!strncasecmp(str, "jtag", 4)) {
+mode = 0;
+} else {
+error_setg(errp, "%s boot mode not supported", str);
+return;
+}
+m->boot_mode = mode;
+}
+
 static void zynq_init(MachineState *machine)
 {
 ZynqMachineState *zynq_machine = ZYNQ_MACHINE(machine);
@@ -241,6 +264,7 @@ static void zynq_init(MachineState *machine)
 /* Create slcr, keep a pointer to connect clocks */
 slcr = qdev_new("xilinx-zynq_slcr");
 qdev_connect_clock_in(slcr, "ps_clk", zynq_machine->ps_clk);
+qdev_prop_set_uint8(slcr, "boot-mode", zynq_machine->boot_mode);
 sysbus_realize_and_unref(SYS_BUS_DEVICE(slcr), _fatal);
 sysbus_mmio_map(SYS_BUS_DEVICE(slcr), 0, 0xF800);
 
@@ -372,6 +396,7 @@ static void zynq_machine_class_init(ObjectClass *oc, void 
*data)
 NULL
 };
 MachineClass *mc = MACHINE_CLASS(oc);
+ObjectProperty *prop;
 mc->desc = "Xilinx Zynq Platform Baseboard for Cortex-A9";
 mc->init = zynq_init;
 mc->max_cpus = ZYNQ_MAX_CPUS;
@@ -379,6 +404,12 @@ static void zynq_machine_class_init(ObjectClass *oc, void 
*data)
 mc->ignore_memory_transaction_failures = true;
 mc->valid_cpu_types = valid_cpu_types;
 mc->default_ram_id = "zynq.ext_ram";
+prop = object_class_property_add_str(oc, "boot-mode", NULL,
+ zynq_set_boot_mode);
+object_class_property_set_description(oc, "boot-mode",
+  "Supported boot modes:"
+  " jtag qspi sd nor");
+object_property_set_default_str(prop, "qspi");
 }
 
 static const TypeInfo zynq_machine_type = {
-- 
2.34.1




[PATCH v4 0/3] Add boot-mode property for zynq

2024-06-21 Thread Sai Pavan Boddu
Add a way to update the boot-mode via machine properties.

Changes for V2:
Make boot-mode property work with string,
Fixed few code style issues,
Added zynq board doc.
Changes for V3:
Mentioned about zynq doc in MAINTAINERS file,
Stick to small case for mentioning boot modes in doc,
fixed commit message to mention right property name.
Changes for V4:
Use strncasecmp,
Fix boot mode names to use small case in few other places,
Fix code indentation.

Sai Pavan Boddu (3):
  hw/misc/zynq_slcr: Add boot-mode property
  hw/arm/xilinx_zynq: Add boot-mode property
  docs/system/arm: Add a doc for zynq board

 MAINTAINERS   |  1 +
 docs/system/arm/xlnx-zynq.rst | 47 +++
 docs/system/target-arm.rst|  1 +
 hw/arm/xilinx_zynq.c  | 31 +++
 hw/misc/zynq_slcr.c   | 22 +++-
 5 files changed, 101 insertions(+), 1 deletion(-)
 create mode 100644 docs/system/arm/xlnx-zynq.rst

-- 
2.34.1




[PATCH v3 1/3] hw/misc/zynq_slcr: Add boot-mode property

2024-06-20 Thread Sai Pavan Boddu
boot-mode property sets user values into BOOT_MODE register, on hardware
these are derived from board switches.

Signed-off-by: Sai Pavan Boddu 
Reviewed-by: Edgar E. Iglesias 
---
 hw/misc/zynq_slcr.c | 22 +-
 1 file changed, 21 insertions(+), 1 deletion(-)

diff --git a/hw/misc/zynq_slcr.c b/hw/misc/zynq_slcr.c
index 3412ff099ea..ad814c3a79b 100644
--- a/hw/misc/zynq_slcr.c
+++ b/hw/misc/zynq_slcr.c
@@ -24,6 +24,8 @@
 #include "hw/registerfields.h"
 #include "hw/qdev-clock.h"
 #include "qom/object.h"
+#include "hw/qdev-properties.h"
+#include "qapi/error.h"
 
 #ifndef ZYNQ_SLCR_ERR_DEBUG
 #define ZYNQ_SLCR_ERR_DEBUG 0
@@ -121,6 +123,7 @@ REG32(RST_REASON, 0x250)
 
 REG32(REBOOT_STATUS, 0x258)
 REG32(BOOT_MODE, 0x25c)
+FIELD(BOOT_MODE, BOOT_MODE, 0, 4)
 
 REG32(APU_CTRL, 0x300)
 REG32(WDT_CLK_SEL, 0x304)
@@ -195,6 +198,7 @@ struct ZynqSLCRState {
 Clock *ps_clk;
 Clock *uart0_ref_clk;
 Clock *uart1_ref_clk;
+uint8_t boot_mode;
 };
 
 /*
@@ -371,7 +375,7 @@ static void zynq_slcr_reset_init(Object *obj, ResetType 
type)
 s->regs[R_FPGA_RST_CTRL]  = 0x01F33F0F;
 s->regs[R_RST_REASON] = 0x0040;
 
-s->regs[R_BOOT_MODE]  = 0x0001;
+s->regs[R_BOOT_MODE]  = s->boot_mode & R_BOOT_MODE_BOOT_MODE_MASK;
 
 /* 0x700 - 0x7D4 */
 for (i = 0; i < 54; i++) {
@@ -588,6 +592,15 @@ static const ClockPortInitArray zynq_slcr_clocks = {
 QDEV_CLOCK_END
 };
 
+static void zynq_slcr_realize(DeviceState *dev, Error **errp)
+{
+ZynqSLCRState *s = ZYNQ_SLCR(dev);
+
+if (s->boot_mode > 0xF) {
+error_setg(errp, "Invalid boot mode %d specified", s->boot_mode);
+}
+}
+
 static void zynq_slcr_init(Object *obj)
 {
 ZynqSLCRState *s = ZYNQ_SLCR(obj);
@@ -610,15 +623,22 @@ static const VMStateDescription vmstate_zynq_slcr = {
 }
 };
 
+static Property zynq_slcr_props[] = {
+DEFINE_PROP_UINT8("boot-mode", ZynqSLCRState, boot_mode, 1),
+DEFINE_PROP_END_OF_LIST(),
+};
+
 static void zynq_slcr_class_init(ObjectClass *klass, void *data)
 {
 DeviceClass *dc = DEVICE_CLASS(klass);
 ResettableClass *rc = RESETTABLE_CLASS(klass);
 
 dc->vmsd = _zynq_slcr;
+dc->realize = zynq_slcr_realize;
 rc->phases.enter = zynq_slcr_reset_init;
 rc->phases.hold  = zynq_slcr_reset_hold;
 rc->phases.exit  = zynq_slcr_reset_exit;
+device_class_set_props(dc, zynq_slcr_props);
 }
 
 static const TypeInfo zynq_slcr_info = {
-- 
2.34.1




[PATCH v3 3/3] docs/system/arm: Add a doc for zynq board

2024-06-20 Thread Sai Pavan Boddu
Added the supported device list and an example command.

Signed-off-by: Sai Pavan Boddu 
Reviewed-by: Edgar E. Iglesias 
---
 MAINTAINERS   |  1 +
 docs/system/arm/xlnx-zynq.rst | 47 +++
 docs/system/target-arm.rst|  1 +
 3 files changed, 49 insertions(+)
 create mode 100644 docs/system/arm/xlnx-zynq.rst

diff --git a/MAINTAINERS b/MAINTAINERS
index 951556224a1..2f06febc676 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1033,6 +1033,7 @@ F: hw/adc/zynq-xadc.c
 F: include/hw/misc/zynq_slcr.h
 F: include/hw/adc/zynq-xadc.h
 X: hw/ssi/xilinx_*
+F: docs/system/arm/xlnx-zynq.rst
 
 Xilinx ZynqMP and Versal
 M: Alistair Francis 
diff --git a/docs/system/arm/xlnx-zynq.rst b/docs/system/arm/xlnx-zynq.rst
new file mode 100644
index 000..ade18a3fe13
--- /dev/null
+++ b/docs/system/arm/xlnx-zynq.rst
@@ -0,0 +1,47 @@
+Xilinx Zynq board (``xilinx-zynq-a9``)
+==
+The Zynq 7000 family is based on the AMD SoC architecture. These products
+integrate a feature-rich dual or single-core Arm Cortex-A9 MPCore based
+processing system (PS) and AMD programmable logic (PL) in a single device.
+
+More details here:
+https://docs.amd.com/r/en-US/ug585-zynq-7000-SoC-TRM/Zynq-7000-SoC-Technical-Reference-Manual
+
+QEMU xilinx-zynq-a9 board supports following devices:
+- A9 MPCORE
+- cortex-a9
+- GIC v1
+- Generic timer
+- wdt
+- OCM 256KB
+- SMC SRAM@0xe200 64MB
+- Zynq SLCR
+- SPI x2
+- QSPI
+- UART
+- TTC x2
+- Gigabit Ethernet Controller x2
+- SD Controller x2
+- XADC
+- Arm PrimeCell DMA Controller
+- DDR Memory
+- USB 2.0 x2
+
+Running
+"""""""
+Direct Linux boot of a generic ARM upstream Linux kernel:
+
+.. code-block:: bash
+
+  $ qemu-system-aarch64 -M xilinx-zynq-a9 \
+-dtb zynq-zc702.dtb  -serial null -serial mon:stdio \
+-display none  -m 1024 \
+-initrd rootfs.cpio.gz -kernel zImage
+
+For configuring the boot-mode provide the following on the command line:
+
+.. code-block:: bash
+
+   -machine boot-mode=qspi
+
+Supported values are jtag, sd, qspi, nor.
diff --git a/docs/system/target-arm.rst b/docs/system/target-arm.rst
index 870d30e3502..7b992722846 100644
--- a/docs/system/target-arm.rst
+++ b/docs/system/target-arm.rst
@@ -109,6 +109,7 @@ undocumented; you can get a complete list by running
arm/virt
arm/xenpvh
arm/xlnx-versal-virt
+   arm/xlnx-zynq
 
 Emulated CPU architecture support
 =
-- 
2.34.1




[PATCH v3 2/3] hw/arm/xilinx_zynq: Add boot-mode property

2024-06-20 Thread Sai Pavan Boddu
Read boot-mode value as machine property and propagate that to
SLCR.BOOT_MODE register.

Signed-off-by: Sai Pavan Boddu 
Acked-by: Edgar E. Iglesias 
---
 hw/arm/xilinx_zynq.c | 31 +++
 1 file changed, 31 insertions(+)

diff --git a/hw/arm/xilinx_zynq.c b/hw/arm/xilinx_zynq.c
index 7f7a3d23fbe..39f07e6dfd8 100644
--- a/hw/arm/xilinx_zynq.c
+++ b/hw/arm/xilinx_zynq.c
@@ -38,6 +38,7 @@
 #include "qom/object.h"
 #include "exec/tswap.h"
 #include "target/arm/cpu-qom.h"
+#include "qapi/visitor.h"
 
 #define TYPE_ZYNQ_MACHINE MACHINE_TYPE_NAME("xilinx-zynq-a9")
 OBJECT_DECLARE_SIMPLE_TYPE(ZynqMachineState, ZYNQ_MACHINE)
@@ -90,6 +91,7 @@ struct ZynqMachineState {
 MachineState parent;
 Clock *ps_clk;
 ARMCPU *cpu[ZYNQ_MAX_CPUS];
+uint8_t boot_mode;
 };
 
 static void zynq_write_board_setup(ARMCPU *cpu,
@@ -176,6 +178,27 @@ static inline int zynq_init_spi_flashes(uint32_t 
base_addr, qemu_irq irq,
 return unit;
 }
 
+static void zynq_set_boot_mode(Object *obj, const char *str,
+   Error **errp)
+{
+ZynqMachineState *m = ZYNQ_MACHINE(obj);
+uint8_t mode = 0;
+
+if (!strcasecmp(str, "QSPI")) {
+mode = 1;
+} else if (!strcasecmp(str, "SD")) {
+mode = 5;
+} else if (!strcasecmp(str, "NOR")) {
+mode = 2;
+} else if (!strcasecmp(str, "JTAG")) {
+mode = 0;
+} else {
+error_setg(errp, "bootmode %s not supported", str);
+return;
+}
+m->boot_mode = mode;
+}
+
 static void zynq_init(MachineState *machine)
 {
 ZynqMachineState *zynq_machine = ZYNQ_MACHINE(machine);
@@ -241,6 +264,7 @@ static void zynq_init(MachineState *machine)
 /* Create slcr, keep a pointer to connect clocks */
 slcr = qdev_new("xilinx-zynq_slcr");
 qdev_connect_clock_in(slcr, "ps_clk", zynq_machine->ps_clk);
+qdev_prop_set_uint8(slcr, "boot-mode", zynq_machine->boot_mode);
 sysbus_realize_and_unref(SYS_BUS_DEVICE(slcr), _fatal);
 sysbus_mmio_map(SYS_BUS_DEVICE(slcr), 0, 0xF800);
 
@@ -372,6 +396,7 @@ static void zynq_machine_class_init(ObjectClass *oc, void 
*data)
 NULL
 };
 MachineClass *mc = MACHINE_CLASS(oc);
+ObjectProperty *prop;
 mc->desc = "Xilinx Zynq Platform Baseboard for Cortex-A9";
 mc->init = zynq_init;
 mc->max_cpus = ZYNQ_MAX_CPUS;
@@ -379,6 +404,12 @@ static void zynq_machine_class_init(ObjectClass *oc, void 
*data)
 mc->ignore_memory_transaction_failures = true;
 mc->valid_cpu_types = valid_cpu_types;
 mc->default_ram_id = "zynq.ext_ram";
+prop = object_class_property_add_str(oc, "boot-mode", NULL,
+  zynq_set_boot_mode);
+object_class_property_set_description(oc, "boot-mode",
+  "Supported boot modes:"
+  " JTAG QSPI SD NOR");
+object_property_set_default_str(prop, "QSPI");
 }
 
 static const TypeInfo zynq_machine_type = {
-- 
2.34.1




[PATCH v3 0/3] Add boot-mode property for zynq

2024-06-20 Thread Sai Pavan Boddu
Add a way to update the boot-mode via machine properties.

Changes for V2:
Make boot-mode property work with string
Fixed few code style issues
Added zynq board doc.
Changes for V3:
Mentioned about zynq doc in MAINTAINERS file
Stick to small case for mentioning boot modes in doc
fixed commit message to mention right property name.


Sai Pavan Boddu (3):
  hw/misc/zynq_slcr: Add boot-mode property
  hw/arm/xilinx_zynq: Add boot-mode property
  docs/system/arm: Add a doc for zynq board

 MAINTAINERS   |  1 +
 docs/system/arm/xlnx-zynq.rst | 47 +++
 docs/system/target-arm.rst|  1 +
 hw/arm/xilinx_zynq.c  | 31 +++
 hw/misc/zynq_slcr.c   | 22 +++-
 5 files changed, 101 insertions(+), 1 deletion(-)
 create mode 100644 docs/system/arm/xlnx-zynq.rst

-- 
2.34.1




[PATCH v2 0/3] Add boot-mode property for zynq

2024-06-19 Thread Sai Pavan Boddu
Add a way to update the boot-mode via machine properties.

Changes for V2:
Make boot-mode property work with string
Fixed few code style issues
Added zynq board doc.

Sai Pavan Boddu (3):
  hw/misc/zynq_slcr: Add BootMode property
  hw/arm/xilinx_zynq: Add boot-mode property
  docs/system/arm: Add a doc for zynq board

 docs/system/arm/xlnx-zynq.rst | 47 +++
 docs/system/target-arm.rst|  1 +
 hw/arm/xilinx_zynq.c  | 31 +++
 hw/misc/zynq_slcr.c   | 22 +++-
 4 files changed, 100 insertions(+), 1 deletion(-)
 create mode 100644 docs/system/arm/xlnx-zynq.rst

-- 
2.34.1




[PATCH v2 2/3] hw/arm/xilinx_zynq: Add boot-mode property

2024-06-19 Thread Sai Pavan Boddu
Read boot-mode value as machine property and propagate that to
SLCR.BOOT_MODE register.

Signed-off-by: Sai Pavan Boddu 
---
 hw/arm/xilinx_zynq.c | 31 +++
 1 file changed, 31 insertions(+)

diff --git a/hw/arm/xilinx_zynq.c b/hw/arm/xilinx_zynq.c
index 7f7a3d23fbe..39f07e6dfd8 100644
--- a/hw/arm/xilinx_zynq.c
+++ b/hw/arm/xilinx_zynq.c
@@ -38,6 +38,7 @@
 #include "qom/object.h"
 #include "exec/tswap.h"
 #include "target/arm/cpu-qom.h"
+#include "qapi/visitor.h"
 
 #define TYPE_ZYNQ_MACHINE MACHINE_TYPE_NAME("xilinx-zynq-a9")
 OBJECT_DECLARE_SIMPLE_TYPE(ZynqMachineState, ZYNQ_MACHINE)
@@ -90,6 +91,7 @@ struct ZynqMachineState {
 MachineState parent;
 Clock *ps_clk;
 ARMCPU *cpu[ZYNQ_MAX_CPUS];
+uint8_t boot_mode;
 };
 
 static void zynq_write_board_setup(ARMCPU *cpu,
@@ -176,6 +178,27 @@ static inline int zynq_init_spi_flashes(uint32_t 
base_addr, qemu_irq irq,
 return unit;
 }
 
+static void zynq_set_boot_mode(Object *obj, const char *str,
+   Error **errp)
+{
+ZynqMachineState *m = ZYNQ_MACHINE(obj);
+uint8_t mode = 0;
+
+if (!strcasecmp(str, "QSPI")) {
+mode = 1;
+} else if (!strcasecmp(str, "SD")) {
+mode = 5;
+} else if (!strcasecmp(str, "NOR")) {
+mode = 2;
+} else if (!strcasecmp(str, "JTAG")) {
+mode = 0;
+} else {
+error_setg(errp, "%s bootmode is not supported", str);
+return;
+}
+m->boot_mode = mode;
+}
+
 static void zynq_init(MachineState *machine)
 {
 ZynqMachineState *zynq_machine = ZYNQ_MACHINE(machine);
@@ -241,6 +264,7 @@ static void zynq_init(MachineState *machine)
 /* Create slcr, keep a pointer to connect clocks */
 slcr = qdev_new("xilinx-zynq_slcr");
 qdev_connect_clock_in(slcr, "ps_clk", zynq_machine->ps_clk);
+qdev_prop_set_uint8(slcr, "boot-mode", zynq_machine->boot_mode);
 sysbus_realize_and_unref(SYS_BUS_DEVICE(slcr), _fatal);
 sysbus_mmio_map(SYS_BUS_DEVICE(slcr), 0, 0xF800);
 
@@ -372,6 +396,7 @@ static void zynq_machine_class_init(ObjectClass *oc, void 
*data)
 NULL
 };
 MachineClass *mc = MACHINE_CLASS(oc);
+ObjectProperty *prop;
 mc->desc = "Xilinx Zynq Platform Baseboard for Cortex-A9";
 mc->init = zynq_init;
 mc->max_cpus = ZYNQ_MAX_CPUS;
@@ -379,6 +404,12 @@ static void zynq_machine_class_init(ObjectClass *oc, void 
*data)
 mc->ignore_memory_transaction_failures = true;
 mc->valid_cpu_types = valid_cpu_types;
 mc->default_ram_id = "zynq.ext_ram";
+prop = object_class_property_add_str(oc, "boot-mode", NULL,
+  zynq_set_boot_mode);
+object_class_property_set_description(oc, "boot-mode",
+  "Supported boot modes:"
+  " JTAG QSPI SD NOR");
+object_property_set_default_str(prop, "QSPI");
 }
 
 static const TypeInfo zynq_machine_type = {
-- 
2.34.1




[PATCH v2 3/3] docs/system/arm: Add a doc for zynq board

2024-06-19 Thread Sai Pavan Boddu
Added the supported device list and an example command.

Signed-off-by: Sai Pavan Boddu 
---
 docs/system/arm/xlnx-zynq.rst | 47 +++
 docs/system/target-arm.rst|  1 +
 2 files changed, 48 insertions(+)
 create mode 100644 docs/system/arm/xlnx-zynq.rst

diff --git a/docs/system/arm/xlnx-zynq.rst b/docs/system/arm/xlnx-zynq.rst
new file mode 100644
index 000..419cc1aec8b
--- /dev/null
+++ b/docs/system/arm/xlnx-zynq.rst
@@ -0,0 +1,47 @@
+Xilinx Zynq board (``xilinx-zynq-a9``)
+==
+The Zynq 7000 family is based on the AMD SoC architecture. These products
+integrate a feature-rich dual or single-core Arm Cortex-A9 MPCore based
+processing system (PS) and AMD programmable logic (PL) in a single device.
+
+More details here:
+https://docs.amd.com/r/en-US/ug585-zynq-7000-SoC-TRM/Zynq-7000-SoC-Technical-Reference-Manual
+
+QEMU xilinx-zynq-a9 board supports following devices:
+- A9 MPCORE
+- cortex-a9
+- GIC v1
+- Generic timer
+- wdt
+- OCM 256KB
+- SMC SRAM@0xe200 64MB
+- Zynq SLCR
+- SPI x2
+- QSPI
+- UART
+- TTC x2
+- Gigabit Ethernet Controller x2
+- SD Controller x2
+- XADC
+- Arm PrimeCell DMA Controller
+- DDR Memory
+- USB 2.0 x2
+
+Running
+"""""""
+Direct Linux boot of a generic ARM upstream Linux kernel:
+
+.. code-block:: bash
+
+  $ qemu-system-aarch64 -M xilinx-zynq-a9 \
+-dtb zynq-zc702.dtb  -serial null -serial mon:stdio \
+-display none  -m 1024 \
+-initrd rootfs.cpio.gz -kernel zImage
+
+For configuring the boot-mode provide the following on the command line:
+
+.. code-block:: bash
+
+   -machine boot-mode=qspi
+
+Supported values are JTAG, SD, QSPI, NOR.
diff --git a/docs/system/target-arm.rst b/docs/system/target-arm.rst
index 870d30e3502..7b992722846 100644
--- a/docs/system/target-arm.rst
+++ b/docs/system/target-arm.rst
@@ -109,6 +109,7 @@ undocumented; you can get a complete list by running
arm/virt
arm/xenpvh
arm/xlnx-versal-virt
+   arm/xlnx-zynq
 
 Emulated CPU architecture support
 =
-- 
2.34.1




[PATCH v2 1/3] hw/misc/zynq_slcr: Add BootMode property

2024-06-19 Thread Sai Pavan Boddu
BootMode property sets user values into BOOT_MODE register, on hardware
these are derived from board switches.

Signed-off-by: Sai Pavan Boddu 
---
 hw/misc/zynq_slcr.c | 22 +-
 1 file changed, 21 insertions(+), 1 deletion(-)

diff --git a/hw/misc/zynq_slcr.c b/hw/misc/zynq_slcr.c
index 3412ff099ea..ad814c3a79b 100644
--- a/hw/misc/zynq_slcr.c
+++ b/hw/misc/zynq_slcr.c
@@ -24,6 +24,8 @@
 #include "hw/registerfields.h"
 #include "hw/qdev-clock.h"
 #include "qom/object.h"
+#include "hw/qdev-properties.h"
+#include "qapi/error.h"
 
 #ifndef ZYNQ_SLCR_ERR_DEBUG
 #define ZYNQ_SLCR_ERR_DEBUG 0
@@ -121,6 +123,7 @@ REG32(RST_REASON, 0x250)
 
 REG32(REBOOT_STATUS, 0x258)
 REG32(BOOT_MODE, 0x25c)
+FIELD(BOOT_MODE, BOOT_MODE, 0, 4)
 
 REG32(APU_CTRL, 0x300)
 REG32(WDT_CLK_SEL, 0x304)
@@ -195,6 +198,7 @@ struct ZynqSLCRState {
 Clock *ps_clk;
 Clock *uart0_ref_clk;
 Clock *uart1_ref_clk;
+uint8_t boot_mode;
 };
 
 /*
@@ -371,7 +375,7 @@ static void zynq_slcr_reset_init(Object *obj, ResetType 
type)
 s->regs[R_FPGA_RST_CTRL]  = 0x01F33F0F;
 s->regs[R_RST_REASON] = 0x0040;
 
-s->regs[R_BOOT_MODE]  = 0x0001;
+s->regs[R_BOOT_MODE]  = s->boot_mode & R_BOOT_MODE_BOOT_MODE_MASK;
 
 /* 0x700 - 0x7D4 */
 for (i = 0; i < 54; i++) {
@@ -588,6 +592,15 @@ static const ClockPortInitArray zynq_slcr_clocks = {
 QDEV_CLOCK_END
 };
 
+static void zynq_slcr_realize(DeviceState *dev, Error **errp)
+{
+ZynqSLCRState *s = ZYNQ_SLCR(dev);
+
+if (s->boot_mode > 0xF) {
+error_setg(errp, "Invalid boot mode %d specified", s->boot_mode);
+}
+}
+
 static void zynq_slcr_init(Object *obj)
 {
 ZynqSLCRState *s = ZYNQ_SLCR(obj);
@@ -610,15 +623,22 @@ static const VMStateDescription vmstate_zynq_slcr = {
 }
 };
 
+static Property zynq_slcr_props[] = {
+DEFINE_PROP_UINT8("boot-mode", ZynqSLCRState, boot_mode, 1),
+DEFINE_PROP_END_OF_LIST(),
+};
+
 static void zynq_slcr_class_init(ObjectClass *klass, void *data)
 {
 DeviceClass *dc = DEVICE_CLASS(klass);
 ResettableClass *rc = RESETTABLE_CLASS(klass);
 
 dc->vmsd = _zynq_slcr;
+dc->realize = zynq_slcr_realize;
 rc->phases.enter = zynq_slcr_reset_init;
 rc->phases.hold  = zynq_slcr_reset_hold;
 rc->phases.exit  = zynq_slcr_reset_exit;
+device_class_set_props(dc, zynq_slcr_props);
 }
 
 static const TypeInfo zynq_slcr_info = {
-- 
2.34.1




[PATCH RFC 1/3] target/arm: Add dcc uart support

2024-06-14 Thread Sai Pavan Boddu
DCC is a debug port to transfer some data between debugger and
processor, we are using this feature to connect a chardev device.
Chardev frontends should be named as "dcc" inorder to connect
to this interface.

Signed-off-by: Sai Pavan Boddu 
---
 target/arm/cpu.h   | 11 +
 target/arm/internals.h |  4 ++
 target/arm/debug-dcc.c | 99 ++
 target/arm/helper.c|  3 ++
 target/arm/meson.build |  1 +
 5 files changed, 118 insertions(+)
 create mode 100644 target/arm/debug-dcc.c

diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index 3841359d0f..6b3cb8e70e 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -30,6 +30,8 @@
 #include "qapi/qapi-types-common.h"
 #include "target/arm/multiprocessing.h"
 #include "target/arm/gtimer.h"
+#include "chardev/char.h"
+#include "chardev/char-fe.h"
 
 #ifdef TARGET_AARCH64
 #define KVM_HAVE_MCE_INJECTION 1
@@ -523,6 +525,11 @@ typedef struct CPUArchState {
 
 /* NV2 register */
 uint64_t vncr_el2;
+/*
+ * Debug Trace regsiters
+ */
+uint32_t dbgdtr_tx;
+uint32_t dbgdtr_rx;
 } cp15;
 
 struct {
@@ -1097,6 +1104,9 @@ struct ArchCPU {
 
 /* Generic timer counter frequency, in Hz */
 uint64_t gt_cntfrq_hz;
+
+/* dcc chardev */
+CharBackend dcc;
 };
 
 typedef struct ARMCPUInfo {
@@ -2388,6 +2398,7 @@ enum arm_features {
  * CPU types added in future.
  */
 ARM_FEATURE_BACKCOMPAT_CNTFRQ, /* 62.5MHz timer default */
+ARM_FEATURE_DCC,
 };
 
 static inline int arm_feature(CPUARMState *env, int feature)
diff --git a/target/arm/internals.h b/target/arm/internals.h
index 11b5da2562..2fa797c5df 100644
--- a/target/arm/internals.h
+++ b/target/arm/internals.h
@@ -1778,4 +1778,8 @@ uint64_t gt_get_countervalue(CPUARMState *env);
  * and CNTVCT_EL0 (this will be either 0 or the value of CNTVOFF_EL2).
  */
 uint64_t gt_virt_cnt_offset(CPUARMState *env);
+/*
+ * Initialise Coresight Debug interface
+ */
+void arm_dcc_init(ARMCPU *cpu);
 #endif
diff --git a/target/arm/debug-dcc.c b/target/arm/debug-dcc.c
new file mode 100644
index 00..9144b54994
--- /dev/null
+++ b/target/arm/debug-dcc.c
@@ -0,0 +1,99 @@
+#include "qemu/osdep.h"
+#include "cpu.h"
+#include "internals.h"
+#include "cpregs.h"
+#include "chardev/char-fe.h"
+
+#define MDCCSR_EL0_RXFULL_MASK (1 << 30)
+#define MDCCSR_EL0_TXFULL_MASK (1 << 29)
+
+static void debug_dcc_write(CPUARMState *env, const ARMCPRegInfo *ri,
+uint64_t value)
+{
+ARMCPU *cpu = ri->opaque;
+env->cp15.dbgdtr_tx = value;
+
+if (qemu_chr_fe_get_driver(>dcc)) {
+/*
+ * Usually dcc is used for putc/getc calls which expect only
+ * 1 byte from external debugger.
+ * TODO: This needs to be generalized for other use-cases.
+ */
+qemu_chr_fe_write_all(>dcc, (uint8_t *)>cp15.dbgdtr_tx, 1);
+}
+}
+
+static uint64_t debug_dcc_read(CPUARMState *env, const ARMCPRegInfo *ri)
+{
+uint32_t ret = 0;
+ARMCPU *cpu = ri->opaque;
+
+if (env->cp15.mdscr_el1 & MDCCSR_EL0_RXFULL_MASK) {
+ret = env->cp15.dbgdtr_rx;
+env->cp15.dbgdtr_rx = 0;
+env->cp15.mdscr_el1 &= ~MDCCSR_EL0_RXFULL_MASK;
+qemu_chr_fe_accept_input(>dcc);
+}
+return ret;
+}
+
+static const ARMCPRegInfo dcc_cp_reginfo[] = {
+/* DBGDTRTX_EL0/DBGDTRRX_EL0 depend on direction */
+{ .name = "DBGDTR_EL0", .state = ARM_CP_STATE_AA64,
+  .opc0 = 2, .opc1 = 3, .crn = 0, .crm = 5, .opc2 = 0,
+  .access = PL0_RW, .writefn = debug_dcc_write,
+  .readfn = debug_dcc_read,
+  .type = ARM_CP_OVERRIDE, .resetvalue = 0 },
+/* DBGDTRTXint/DBGDTRRXint depend on direction */
+{ .name = "DBGDTRint", .state = ARM_CP_STATE_AA32, .cp = 14,
+  .opc1 = 0, .crn = 0, .crm = 5, .opc2 = 0,
+  .access = PL0_RW, .writefn = debug_dcc_write,
+  .readfn = debug_dcc_read,
+  .type = ARM_CP_OVERRIDE, .resetvalue = 0 },
+};
+
+
+static int dcc_chr_can_read(void *opaque)
+{
+ARMCPU *cpu = opaque;
+CPUARMState *env = >env;
+
+if (!(env->cp15.mdscr_el1 & MDCCSR_EL0_RXFULL_MASK)) {
+/*
+ * Usually dcc is used for putc/getc calls which expect only
+ * 1 byte from external debugger.
+ * TODO: This needs to be generalized for other use-cases.
+ */
+return 1;
+}
+
+return 0;
+}
+
+static void dcc_chr_read(void *opaque, const uint8_t *buf, int size)
+{
+ARMCPU *cpu = opaque;
+CPUARMState *env = >env;
+
+env->cp15.dbgdtr_rx = *buf;
+env->cp15.mdscr_el1 |= MDCCSR_EL0_RXFULL_MASK;
+}
+
+void arm_dcc_init(ARMCPU *cpu)
+{
+Chardev *chr;
+char *dcc_name;
+CPUState *p = CPU(cpu);
+
+dcc_name = g_strdup_printf("dcc%d", 

[PATCH RFC 2/3] target/arm: Enable dcc console for a53 and R5

2024-06-14 Thread Sai Pavan Boddu
This enabled DCC support.

Signed-off-by: Sai Pavan Boddu 
---
 target/arm/cpu64.c | 1 +
 target/arm/tcg/cpu32.c | 1 +
 2 files changed, 2 insertions(+)

diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
index 262a1d6c0b..e39740303b 100644
--- a/target/arm/cpu64.c
+++ b/target/arm/cpu64.c
@@ -667,6 +667,7 @@ static void aarch64_a53_initfn(Object *obj)
 set_feature(>env, ARM_FEATURE_EL2);
 set_feature(>env, ARM_FEATURE_EL3);
 set_feature(>env, ARM_FEATURE_PMU);
+set_feature(>env, ARM_FEATURE_DCC);
 cpu->kvm_target = QEMU_KVM_ARM_TARGET_CORTEX_A53;
 cpu->midr = 0x410fd034;
 cpu->revidr = 0x0100;
diff --git a/target/arm/tcg/cpu32.c b/target/arm/tcg/cpu32.c
index bdd82d912a..b0ef51a9bf 100644
--- a/target/arm/tcg/cpu32.c
+++ b/target/arm/tcg/cpu32.c
@@ -562,6 +562,7 @@ static void cortex_r5_initfn(Object *obj)
 set_feature(>env, ARM_FEATURE_V7MP);
 set_feature(>env, ARM_FEATURE_PMSA);
 set_feature(>env, ARM_FEATURE_PMU);
+set_feature(>env, ARM_FEATURE_DCC);
 cpu->midr = 0x411fc153; /* r1p3 */
 cpu->isar.id_pfr0 = 0x0131;
 cpu->isar.id_pfr1 = 0x001;
-- 
2.34.1




[PATCH RFC 3/3] target/arm/debug_helper: Add fieldoffset for MDCCSR_EL0 reg

2024-06-14 Thread Sai Pavan Boddu
MDCCSR_EL0 is aarch64 varient of DBGDSCRint, so utilize the same cpreg
offset.

Signed-off-by: Sai Pavan Boddu 
---
 target/arm/debug_helper.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/target/arm/debug_helper.c b/target/arm/debug_helper.c
index 7d856acddf..5deafa4d1f 100644
--- a/target/arm/debug_helper.c
+++ b/target/arm/debug_helper.c
@@ -970,7 +970,7 @@ static const ARMCPRegInfo debug_cp_reginfo[] = {
 { .name = "MDCCSR_EL0", .state = ARM_CP_STATE_AA64,
   .opc0 = 2, .opc1 = 3, .crn = 0, .crm = 1, .opc2 = 0,
   .access = PL0_R, .accessfn = access_tdcc,
-  .type = ARM_CP_CONST, .resetvalue = 0 },
+  .fieldoffset = offsetof(CPUARMState, cp15.mdscr_el1)}, /* Xilinx */
 /*
  * These registers belong to the Debug Communications Channel,
  * which is not implemented. However we implement RAZ/WI behaviour
-- 
2.34.1




[PATCH RFC 0/3] Add DCC uart console support

2024-06-14 Thread Sai Pavan Boddu
This patch series attaches a chardev to  arm Debug Communication channel 
registers,
As each cpu has it own DBGDTRTX/RX register just tried to hook each cpu
with chardev iff we find a chardev with id "dcc".

ex:
Below chardev switch would be connected to A53-0.

./qemu-system-aarch64 -M xlnx-zcu102 -kernel u-boot-dtb.bin
  -dtb zynqmp-zcu102-rev1.1.d -display none -m 2G
  -chardev stdio,id=dcc0


Sai Pavan Boddu (3):
  target/arm: Add dcc uart support
  target/arm: Enable dcc console for a53 and R5
  target/arm/debug_helper: Add fieldoffset for MDCCSR_EL0 reg

 target/arm/cpu.h  | 11 +
 target/arm/internals.h|  4 ++
 target/arm/cpu64.c|  1 +
 target/arm/debug-dcc.c| 99 +++
 target/arm/debug_helper.c |  2 +-
 target/arm/helper.c   |  3 ++
 target/arm/tcg/cpu32.c|  1 +
 target/arm/meson.build|  1 +
 8 files changed, 121 insertions(+), 1 deletion(-)
 create mode 100644 target/arm/debug-dcc.c

-- 
2.34.1




[PATCH 2/2] hw/arm/xilinx_zynq: Add boot-mode property

2024-06-13 Thread Sai Pavan Boddu
Read boot-mode value as machine property and propagate that to
SLCR.BOOT_MODE register.

Signed-off-by: Sai Pavan Boddu 
---
 hw/arm/xilinx_zynq.c | 22 ++
 1 file changed, 22 insertions(+)

diff --git a/hw/arm/xilinx_zynq.c b/hw/arm/xilinx_zynq.c
index 7f7a3d23fb..4dfa9184ac 100644
--- a/hw/arm/xilinx_zynq.c
+++ b/hw/arm/xilinx_zynq.c
@@ -38,6 +38,7 @@
 #include "qom/object.h"
 #include "exec/tswap.h"
 #include "target/arm/cpu-qom.h"
+#include "qapi/visitor.h"
 
 #define TYPE_ZYNQ_MACHINE MACHINE_TYPE_NAME("xilinx-zynq-a9")
 OBJECT_DECLARE_SIMPLE_TYPE(ZynqMachineState, ZYNQ_MACHINE)
@@ -90,6 +91,7 @@ struct ZynqMachineState {
 MachineState parent;
 Clock *ps_clk;
 ARMCPU *cpu[ZYNQ_MAX_CPUS];
+uint8_t BootMode;
 };
 
 static void zynq_write_board_setup(ARMCPU *cpu,
@@ -176,6 +178,19 @@ static inline int zynq_init_spi_flashes(uint32_t 
base_addr, qemu_irq irq,
 return unit;
 }
 
+static void zynq_set_boot_mode(Object *obj, Visitor *v,
+   const char *name, void *opaque,
+   Error **errp)
+{
+ZynqMachineState *m = ZYNQ_MACHINE(obj);
+uint8_t val;
+
+if (!visit_type_uint8(v, name, , errp)) {
+return;
+}
+m->BootMode = val;
+}
+
 static void zynq_init(MachineState *machine)
 {
 ZynqMachineState *zynq_machine = ZYNQ_MACHINE(machine);
@@ -241,6 +256,7 @@ static void zynq_init(MachineState *machine)
 /* Create slcr, keep a pointer to connect clocks */
 slcr = qdev_new("xilinx-zynq_slcr");
 qdev_connect_clock_in(slcr, "ps_clk", zynq_machine->ps_clk);
+qdev_prop_set_uint8(slcr, "boot-mode", zynq_machine->BootMode);
 sysbus_realize_and_unref(SYS_BUS_DEVICE(slcr), _fatal);
 sysbus_mmio_map(SYS_BUS_DEVICE(slcr), 0, 0xF800);
 
@@ -372,6 +388,7 @@ static void zynq_machine_class_init(ObjectClass *oc, void 
*data)
 NULL
 };
 MachineClass *mc = MACHINE_CLASS(oc);
+ObjectProperty *prop;
 mc->desc = "Xilinx Zynq Platform Baseboard for Cortex-A9";
 mc->init = zynq_init;
 mc->max_cpus = ZYNQ_MAX_CPUS;
@@ -379,6 +396,11 @@ static void zynq_machine_class_init(ObjectClass *oc, void 
*data)
 mc->ignore_memory_transaction_failures = true;
 mc->valid_cpu_types = valid_cpu_types;
 mc->default_ram_id = "zynq.ext_ram";
+prop = object_class_property_add(oc, "boot-mode", "uint8_t", NULL,
+  zynq_set_boot_mode, NULL, NULL);
+object_class_property_set_description(oc, "boot-mode",
+  "Update SLCR.BOOT_MODE register");
+object_property_set_default_uint(prop, 1);
 }
 
 static const TypeInfo zynq_machine_type = {
-- 
2.34.1




[PATCH 0/2] Add boot-mode property for zynq

2024-06-13 Thread Sai Pavan Boddu
Add a way to update the boot-mode via machine properties.

Sai Pavan Boddu (2):
  hw/misc/zynq_slcr: Add BootMode property
  hw/arm/xilinx_zynq: Add boot-mode property

 hw/arm/xilinx_zynq.c | 22 ++
 hw/misc/zynq_slcr.c  | 11 ++-
 2 files changed, 32 insertions(+), 1 deletion(-)

-- 
2.34.1




[PATCH 1/2] hw/misc/zynq_slcr: Add BootMode property

2024-06-13 Thread Sai Pavan Boddu
BootMode property sets user values into BOOT_MODE register, on hardware
these are derived from board switches.

Signed-off-by: Sai Pavan Boddu 
---
 hw/misc/zynq_slcr.c | 11 ++-
 1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/hw/misc/zynq_slcr.c b/hw/misc/zynq_slcr.c
index 3412ff099e..72703e92a5 100644
--- a/hw/misc/zynq_slcr.c
+++ b/hw/misc/zynq_slcr.c
@@ -24,6 +24,7 @@
 #include "hw/registerfields.h"
 #include "hw/qdev-clock.h"
 #include "qom/object.h"
+#include "hw/qdev-properties.h"
 
 #ifndef ZYNQ_SLCR_ERR_DEBUG
 #define ZYNQ_SLCR_ERR_DEBUG 0
@@ -121,6 +122,7 @@ REG32(RST_REASON, 0x250)
 
 REG32(REBOOT_STATUS, 0x258)
 REG32(BOOT_MODE, 0x25c)
+FIELD(BOOT_MODE, BOOT_MODE, 0, 4)
 
 REG32(APU_CTRL, 0x300)
 REG32(WDT_CLK_SEL, 0x304)
@@ -195,6 +197,7 @@ struct ZynqSLCRState {
 Clock *ps_clk;
 Clock *uart0_ref_clk;
 Clock *uart1_ref_clk;
+uint8_t BootMode;
 };
 
 /*
@@ -371,7 +374,7 @@ static void zynq_slcr_reset_init(Object *obj, ResetType 
type)
 s->regs[R_FPGA_RST_CTRL]  = 0x01F33F0F;
 s->regs[R_RST_REASON] = 0x0040;
 
-s->regs[R_BOOT_MODE]  = 0x0001;
+s->regs[R_BOOT_MODE]  = s->BootMode & R_BOOT_MODE_BOOT_MODE_MASK;
 
 /* 0x700 - 0x7D4 */
 for (i = 0; i < 54; i++) {
@@ -610,6 +613,11 @@ static const VMStateDescription vmstate_zynq_slcr = {
 }
 };
 
+static Property zynq_slcr_props[] = {
+DEFINE_PROP_UINT8("boot-mode", ZynqSLCRState, BootMode, 1),
+DEFINE_PROP_END_OF_LIST(),
+};
+
 static void zynq_slcr_class_init(ObjectClass *klass, void *data)
 {
 DeviceClass *dc = DEVICE_CLASS(klass);
@@ -619,6 +627,7 @@ static void zynq_slcr_class_init(ObjectClass *klass, void 
*data)
 rc->phases.enter = zynq_slcr_reset_init;
 rc->phases.hold  = zynq_slcr_reset_hold;
 rc->phases.exit  = zynq_slcr_reset_exit;
+device_class_set_props(dc, zynq_slcr_props);
 }
 
 static const TypeInfo zynq_slcr_info = {
-- 
2.34.1




[PATCH v2 0/2] OSPI updates

2024-02-20 Thread Sai Pavan Boddu
Add a new 2Gib octal flash mt35xu02gbba. Add an interface for versal
virt board to swap the default flash.

Changes for V2:
  Added type checks for provided flash part name.

Sai Pavan Boddu (2):
  block: m25p80: Add support of mt35xu02gbba
  arm: xlnx-versal-virt: Add machine property ospi-flash

 hw/block/m25p80_sfdp.h|  1 +
 hw/arm/xlnx-versal-virt.c | 44 ++-
 hw/block/m25p80.c |  3 +++
 hw/block/m25p80_sfdp.c| 36 
 4 files changed, 83 insertions(+), 1 deletion(-)

-- 
2.25.1




[PATCH v2 2/2] arm: xlnx-versal-virt: Add machine property ospi-flash

2024-02-20 Thread Sai Pavan Boddu
This property allows users to change flash model on command line as
below.

   ex: "-M xlnx-versal-virt,ospi-flash=mt35xu02gbba"

Signed-off-by: Sai Pavan Boddu 
---
 hw/arm/xlnx-versal-virt.c | 44 ++-
 1 file changed, 43 insertions(+), 1 deletion(-)

diff --git a/hw/arm/xlnx-versal-virt.c b/hw/arm/xlnx-versal-virt.c
index 94942c55df..bfaed1aebf 100644
--- a/hw/arm/xlnx-versal-virt.c
+++ b/hw/arm/xlnx-versal-virt.c
@@ -49,6 +49,7 @@ struct VersalVirt {
 struct {
 bool secure;
 } cfg;
+char *ospi_model;
 };
 
 static void fdt_create(VersalVirt *s)
@@ -638,6 +639,22 @@ static void sd_plugin_card(SDHCIState *sd, DriveInfo *di)
_fatal);
 }
 
+static char *versal_get_ospi_model(Object *obj, Error **errp)
+{
+VersalVirt *s = XLNX_VERSAL_VIRT_MACHINE(obj);
+
+return g_strdup(s->ospi_model);
+}
+
+static void versal_set_ospi_model(Object *obj, const char *value, Error **errp)
+{
+VersalVirt *s = XLNX_VERSAL_VIRT_MACHINE(obj);
+
+g_free(s->ospi_model);
+s->ospi_model = g_strdup(value);
+}
+
+
 static void versal_virt_init(MachineState *machine)
 {
 VersalVirt *s = XLNX_VERSAL_VIRT_MACHINE(machine);
@@ -732,12 +749,25 @@ static void versal_virt_init(MachineState *machine)
 for (i = 0; i < XLNX_VERSAL_NUM_OSPI_FLASH; i++) {
 BusState *spi_bus;
 DeviceState *flash_dev;
+ObjectClass *flash_klass;
 qemu_irq cs_line;
 DriveInfo *dinfo = drive_get(IF_MTD, 0, i);
 
 spi_bus = qdev_get_child_bus(DEVICE(>soc.pmc.iou.ospi), "spi0");
 
-flash_dev = qdev_new("mt35xu01g");
+if (s->ospi_model) {
+flash_klass = object_class_by_name(s->ospi_model);
+if (!flash_klass ||
+object_class_is_abstract(flash_klass) ||
+!object_class_dynamic_cast(flash_klass, "m25p80-generic")) {
+error_setg(_fatal, "'%s' is either abstract or"
+   " not a subtype of m25p80", s->ospi_model);
+return;
+}
+}
+
+flash_dev = qdev_new(s->ospi_model ? s->ospi_model : "mt35xu01g");
+
 if (dinfo) {
 qdev_prop_set_drive_err(flash_dev, "drive",
 blk_by_legacy_dinfo(dinfo), _fatal);
@@ -770,6 +800,13 @@ static void versal_virt_machine_instance_init(Object *obj)
  0);
 }
 
+static void versal_virt_machine_finalize(Object *obj)
+{
+VersalVirt *s = XLNX_VERSAL_VIRT_MACHINE(obj);
+
+g_free(s->ospi_model);
+}
+
 static void versal_virt_machine_class_init(ObjectClass *oc, void *data)
 {
 MachineClass *mc = MACHINE_CLASS(oc);
@@ -781,6 +818,10 @@ static void versal_virt_machine_class_init(ObjectClass 
*oc, void *data)
 mc->default_cpus = XLNX_VERSAL_NR_ACPUS + XLNX_VERSAL_NR_RCPUS;
 mc->no_cdrom = true;
 mc->default_ram_id = "ddr";
+object_class_property_add_str(oc, "ospi-flash", versal_get_ospi_model,
+   versal_set_ospi_model);
+object_class_property_set_description(oc, "ospi-flash",
+  "Change the OSPI Flash model");
 }
 
 static const TypeInfo versal_virt_machine_init_typeinfo = {
@@ -789,6 +830,7 @@ static const TypeInfo versal_virt_machine_init_typeinfo = {
 .class_init = versal_virt_machine_class_init,
 .instance_init = versal_virt_machine_instance_init,
 .instance_size = sizeof(VersalVirt),
+.instance_finalize = versal_virt_machine_finalize,
 };
 
 static void versal_virt_machine_init_register_types(void)
-- 
2.25.1




[PATCH v2 1/2] block: m25p80: Add support of mt35xu02gbba

2024-02-20 Thread Sai Pavan Boddu
Add Micro 2Gb OSPI flash part with sfdp data.

Signed-off-by: Sai Pavan Boddu 
Reviewed-by: Francisco Iglesias 
---
 hw/block/m25p80_sfdp.h |  1 +
 hw/block/m25p80.c  |  3 +++
 hw/block/m25p80_sfdp.c | 36 
 3 files changed, 40 insertions(+)

diff --git a/hw/block/m25p80_sfdp.h b/hw/block/m25p80_sfdp.h
index 011a880f66..1733b56950 100644
--- a/hw/block/m25p80_sfdp.h
+++ b/hw/block/m25p80_sfdp.h
@@ -16,6 +16,7 @@
 #define M25P80_SFDP_MAX_SIZE  (1 << 24)
 
 uint8_t m25p80_sfdp_n25q256a(uint32_t addr);
+uint8_t m25p80_sfdp_mt35xu02g(uint32_t addr);
 
 uint8_t m25p80_sfdp_mx25l25635e(uint32_t addr);
 uint8_t m25p80_sfdp_mx25l25635f(uint32_t addr);
diff --git a/hw/block/m25p80.c b/hw/block/m25p80.c
index 0a12030a3a..08a00a6d9b 100644
--- a/hw/block/m25p80.c
+++ b/hw/block/m25p80.c
@@ -267,6 +267,9 @@ static const FlashPartInfo known_devices[] = {
 { INFO("mt25ql512ab", 0x20ba20, 0x1044, 64 << 10, 1024, ER_4K | ER_32K) },
 { INFO_STACKED("mt35xu01g", 0x2c5b1b, 0x104100, 128 << 10, 1024,
ER_4K | ER_32K, 2) },
+{ INFO_STACKED("mt35xu02gbba", 0x2c5b1c, 0x104100, 128 << 10, 2048,
+   ER_4K | ER_32K, 4),
+   .sfdp_read = m25p80_sfdp_mt35xu02g },
 { INFO_STACKED("n25q00",0x20ba21, 0x1000, 64 << 10, 2048, ER_4K, 4) },
 { INFO_STACKED("n25q00a",   0x20bb21, 0x1000, 64 << 10, 2048, ER_4K, 4) },
 { INFO_STACKED("mt25ql01g", 0x20ba21, 0x1040, 64 << 10, 2048, ER_4K, 2) },
diff --git a/hw/block/m25p80_sfdp.c b/hw/block/m25p80_sfdp.c
index b33811a4f5..6ee2cfaf11 100644
--- a/hw/block/m25p80_sfdp.c
+++ b/hw/block/m25p80_sfdp.c
@@ -57,6 +57,42 @@ static const uint8_t sfdp_n25q256a[] = {
 };
 define_sfdp_read(n25q256a);
 
+static const uint8_t sfdp_mt35xu02g[] = {
+0x53, 0x46, 0x44, 0x50, 0x06, 0x01, 0x01, 0xff,
+0x00, 0x06, 0x01, 0x10, 0x30, 0x00, 0x00, 0xff,
+0x84, 0x00, 0x01, 0x02, 0x80, 0x00, 0x00, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xe5, 0x20, 0x8a, 0xff, 0xff, 0xff, 0xff, 0x7f,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0xee, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00,
+0xff, 0xff, 0x00, 0x00, 0x0c, 0x20, 0x11, 0xd8,
+0x0f, 0x52, 0x00, 0x00, 0x24, 0x5a, 0x99, 0x00,
+0x8b, 0x8e, 0x03, 0xe1, 0xac, 0x01, 0x27, 0x38,
+0x7a, 0x75, 0x7a, 0x75, 0xfb, 0xbd, 0xd5, 0x5c,
+0x00, 0x00, 0x70, 0xff, 0x81, 0xb0, 0x38, 0x36,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0x43, 0x0e, 0xff, 0xff, 0x21, 0xdc, 0x5c, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+};
+
+define_sfdp_read(mt35xu02g);
 
 /*
  * Matronix
-- 
2.25.1




[PATCH v2] xlnx-versal-ospi: disable reentrancy detection for iomem_dac

2024-02-19 Thread Sai Pavan Boddu
The OSPI DMA reads flash data through the OSPI linear address space (the
iomem_dac region), because of this the reentrancy guard introduced in
commit a2e1753b ("memory: prevent dma-reentracy issues") is disabled for
the memory region.

Signed-off-by: Sai Pavan Boddu 
---
Changes for V2:
Added code comments.

 hw/ssi/xlnx-versal-ospi.c | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/hw/ssi/xlnx-versal-ospi.c b/hw/ssi/xlnx-versal-ospi.c
index c7b95b1f37..c479138ec1 100644
--- a/hw/ssi/xlnx-versal-ospi.c
+++ b/hw/ssi/xlnx-versal-ospi.c
@@ -1772,6 +1772,12 @@ static void xlnx_versal_ospi_init(Object *obj)
 memory_region_init_io(>iomem_dac, obj, _dac_ops, s,
   TYPE_XILINX_VERSAL_OSPI "-dac", 0x2000);
 sysbus_init_mmio(sbd, >iomem_dac);
+/*
+ * The OSPI DMA reads flash data through the OSPI linear address space (the
+ * iomem_dac region), because of this the reentrancy guard needs to be
+ * disabled.
+ */
+s->iomem_dac.disable_reentrancy_guard = true;
 
 sysbus_init_irq(sbd, >irq);
 
-- 
2.25.1




[PATCH 1/1] xlnx-versal-ospi: disable reentrancy detection for iomem_dac

2023-12-05 Thread Sai Pavan Boddu
The OSPI DMA reads flash data through the OSPI linear address space (the
iomem_dac region), because of this the reentrancy guard introduced in
commit a2e1753b ("memory: prevent dma-reentracy issues") is disabled for
the memory region.

Signed-off-by: Sai Pavan Boddu 
---
 hw/ssi/xlnx-versal-ospi.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/hw/ssi/xlnx-versal-ospi.c b/hw/ssi/xlnx-versal-ospi.c
index 1a61679c2f..5123e7dde7 100644
--- a/hw/ssi/xlnx-versal-ospi.c
+++ b/hw/ssi/xlnx-versal-ospi.c
@@ -1772,6 +1772,7 @@ static void xlnx_versal_ospi_init(Object *obj)
 memory_region_init_io(>iomem_dac, obj, _dac_ops, s,
   TYPE_XILINX_VERSAL_OSPI "-dac", 0x2000);
 sysbus_init_mmio(sbd, >iomem_dac);
+s->iomem_dac.disable_reentrancy_guard = true;
 
 sysbus_init_irq(sbd, >irq);
 
-- 
2.25.1




[PATCH 0/1] versal-ospi fix

2023-12-05 Thread Sai Pavan Boddu
Disable reentrancy on iomem_dac memory-region.

Sai Pavan Boddu (1):
  xlnx-versal-ospi: disable reentrancy detection for iomem_dac

 hw/ssi/xlnx-versal-ospi.c | 1 +
 1 file changed, 1 insertion(+)

-- 
2.25.1




[PATCH 0/1] versal-ospi fix

2023-12-05 Thread Sai Pavan Boddu
Disable reentrancy on iomem_dac memory-region.

Sai Pavan Boddu (1):
  xlnx-versal-ospi: disable reentrancy detection for iomem_dac

 hw/ssi/xlnx-versal-ospi.c | 1 +
 1 file changed, 1 insertion(+)

-- 
2.25.1




[PATCH 1/2] block: m25p80: Add support of mt35xu02gbba

2023-12-05 Thread Sai Pavan Boddu
Add Micro 2Gb OSPI flash part with sfdp data.

Signed-off-by: Sai Pavan Boddu 
---
 hw/block/m25p80_sfdp.h |  1 +
 hw/block/m25p80.c  |  3 +++
 hw/block/m25p80_sfdp.c | 36 
 3 files changed, 40 insertions(+)

diff --git a/hw/block/m25p80_sfdp.h b/hw/block/m25p80_sfdp.h
index 011a880f66..1733b56950 100644
--- a/hw/block/m25p80_sfdp.h
+++ b/hw/block/m25p80_sfdp.h
@@ -16,6 +16,7 @@
 #define M25P80_SFDP_MAX_SIZE  (1 << 24)
 
 uint8_t m25p80_sfdp_n25q256a(uint32_t addr);
+uint8_t m25p80_sfdp_mt35xu02g(uint32_t addr);
 
 uint8_t m25p80_sfdp_mx25l25635e(uint32_t addr);
 uint8_t m25p80_sfdp_mx25l25635f(uint32_t addr);
diff --git a/hw/block/m25p80.c b/hw/block/m25p80.c
index afc3fdf4d6..c8c7f6c1c3 100644
--- a/hw/block/m25p80.c
+++ b/hw/block/m25p80.c
@@ -267,6 +267,9 @@ static const FlashPartInfo known_devices[] = {
 { INFO("mt25ql512ab", 0x20ba20, 0x1044, 64 << 10, 1024, ER_4K | ER_32K) },
 { INFO_STACKED("mt35xu01g", 0x2c5b1b, 0x104100, 128 << 10, 1024,
ER_4K | ER_32K, 2) },
+{ INFO_STACKED("mt35xu02gbba", 0x2c5b1c, 0x104100, 128 << 10, 2048,
+   ER_4K | ER_32K, 4),
+   .sfdp_read = m25p80_sfdp_mt35xu02g },
 { INFO_STACKED("n25q00",0x20ba21, 0x1000, 64 << 10, 2048, ER_4K, 4) },
 { INFO_STACKED("n25q00a",   0x20bb21, 0x1000, 64 << 10, 2048, ER_4K, 4) },
 { INFO_STACKED("mt25ql01g", 0x20ba21, 0x1040, 64 << 10, 2048, ER_4K, 2) },
diff --git a/hw/block/m25p80_sfdp.c b/hw/block/m25p80_sfdp.c
index b33811a4f5..6ee2cfaf11 100644
--- a/hw/block/m25p80_sfdp.c
+++ b/hw/block/m25p80_sfdp.c
@@ -57,6 +57,42 @@ static const uint8_t sfdp_n25q256a[] = {
 };
 define_sfdp_read(n25q256a);
 
+static const uint8_t sfdp_mt35xu02g[] = {
+0x53, 0x46, 0x44, 0x50, 0x06, 0x01, 0x01, 0xff,
+0x00, 0x06, 0x01, 0x10, 0x30, 0x00, 0x00, 0xff,
+0x84, 0x00, 0x01, 0x02, 0x80, 0x00, 0x00, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xe5, 0x20, 0x8a, 0xff, 0xff, 0xff, 0xff, 0x7f,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0xee, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00,
+0xff, 0xff, 0x00, 0x00, 0x0c, 0x20, 0x11, 0xd8,
+0x0f, 0x52, 0x00, 0x00, 0x24, 0x5a, 0x99, 0x00,
+0x8b, 0x8e, 0x03, 0xe1, 0xac, 0x01, 0x27, 0x38,
+0x7a, 0x75, 0x7a, 0x75, 0xfb, 0xbd, 0xd5, 0x5c,
+0x00, 0x00, 0x70, 0xff, 0x81, 0xb0, 0x38, 0x36,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0x43, 0x0e, 0xff, 0xff, 0x21, 0xdc, 0x5c, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+};
+
+define_sfdp_read(mt35xu02g);
 
 /*
  * Matronix
-- 
2.25.1




[PATCH 2/2] arm: xlnx-versal-virt: Add machine property ospi-flash

2023-12-05 Thread Sai Pavan Boddu
This property allows users to change flash model on command line as
below.

   ex: "-M xlnx-versal-virt,ospi-flash=mt35xu02gbba"

Signed-off-by: Sai Pavan Boddu 
---
 hw/arm/xlnx-versal-virt.c | 31 ++-
 1 file changed, 30 insertions(+), 1 deletion(-)

diff --git a/hw/arm/xlnx-versal-virt.c b/hw/arm/xlnx-versal-virt.c
index 537118224f..c57cff74d8 100644
--- a/hw/arm/xlnx-versal-virt.c
+++ b/hw/arm/xlnx-versal-virt.c
@@ -49,6 +49,7 @@ struct VersalVirt {
 struct {
 bool secure;
 } cfg;
+char *ospi_model;
 };
 
 static void fdt_create(VersalVirt *s)
@@ -637,6 +638,22 @@ static void sd_plugin_card(SDHCIState *sd, DriveInfo *di)
_fatal);
 }
 
+static char *versal_get_ospi_model(Object *obj, Error **errp)
+{
+VersalVirt *s = XLNX_VERSAL_VIRT_MACHINE(obj);
+
+return g_strdup(s->ospi_model);
+}
+
+static void versal_set_ospi_model(Object *obj, const char *value, Error **errp)
+{
+VersalVirt *s = XLNX_VERSAL_VIRT_MACHINE(obj);
+
+g_free(s->ospi_model);
+s->ospi_model = g_strdup(value);
+}
+
+
 static void versal_virt_init(MachineState *machine)
 {
 VersalVirt *s = XLNX_VERSAL_VIRT_MACHINE(machine);
@@ -736,7 +753,7 @@ static void versal_virt_init(MachineState *machine)
 
 spi_bus = qdev_get_child_bus(DEVICE(>soc.pmc.iou.ospi), "spi0");
 
-flash_dev = qdev_new("mt35xu01g");
+flash_dev = qdev_new(s->ospi_model ? s->ospi_model : "mt35xu01g");
 if (dinfo) {
 qdev_prop_set_drive_err(flash_dev, "drive",
 blk_by_legacy_dinfo(dinfo), _fatal);
@@ -769,6 +786,13 @@ static void versal_virt_machine_instance_init(Object *obj)
  0);
 }
 
+static void versal_virt_machine_finalize(Object *obj)
+{
+VersalVirt *s = XLNX_VERSAL_VIRT_MACHINE(obj);
+
+g_free(s->ospi_model);
+}
+
 static void versal_virt_machine_class_init(ObjectClass *oc, void *data)
 {
 MachineClass *mc = MACHINE_CLASS(oc);
@@ -780,6 +804,10 @@ static void versal_virt_machine_class_init(ObjectClass 
*oc, void *data)
 mc->default_cpus = XLNX_VERSAL_NR_ACPUS + XLNX_VERSAL_NR_RCPUS;
 mc->no_cdrom = true;
 mc->default_ram_id = "ddr";
+object_class_property_add_str(oc, "ospi-flash", versal_get_ospi_model,
+   versal_set_ospi_model);
+object_class_property_set_description(oc, "ospi-flash",
+  "Change the OSPI Flash model");
 }
 
 static const TypeInfo versal_virt_machine_init_typeinfo = {
@@ -788,6 +816,7 @@ static const TypeInfo versal_virt_machine_init_typeinfo = {
 .class_init = versal_virt_machine_class_init,
 .instance_init = versal_virt_machine_instance_init,
 .instance_size = sizeof(VersalVirt),
+.instance_finalize = versal_virt_machine_finalize,
 };
 
 static void versal_virt_machine_init_register_types(void)
-- 
2.25.1




[PATCH 0/2] OSPI updates

2023-12-05 Thread Sai Pavan Boddu
Add a new 2Gib octal flash mt35xu02gbba. Add an interface for versal
virt board to swap the default flash.

Sai Pavan Boddu (2):
  block: m25p80: Add support of mt35xu02gbba
  arm: xlnx-versal-virt: Add machine property ospi-flash

 hw/block/m25p80_sfdp.h|  1 +
 hw/arm/xlnx-versal-virt.c | 31 ++-
 hw/block/m25p80.c |  3 +++
 hw/block/m25p80_sfdp.c| 36 
 4 files changed, 70 insertions(+), 1 deletion(-)

-- 
2.25.1




[PATCH 1/1] xlnx-versal-ospi: disable reentrancy detection for iomem_dac

2023-12-05 Thread Sai Pavan Boddu
The OSPI DMA reads flash data through the OSPI linear address space (the
iomem_dac region), because of this the reentrancy guard introduced in
commit a2e1753b ("memory: prevent dma-reentracy issues") is disabled for
the memory region.

Signed-off-by: Sai Pavan Boddu 
---
 hw/ssi/xlnx-versal-ospi.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/hw/ssi/xlnx-versal-ospi.c b/hw/ssi/xlnx-versal-ospi.c
index 1a61679c2f..5123e7dde7 100644
--- a/hw/ssi/xlnx-versal-ospi.c
+++ b/hw/ssi/xlnx-versal-ospi.c
@@ -1772,6 +1772,7 @@ static void xlnx_versal_ospi_init(Object *obj)
 memory_region_init_io(>iomem_dac, obj, _dac_ops, s,
   TYPE_XILINX_VERSAL_OSPI "-dac", 0x2000);
 sysbus_init_mmio(sbd, >iomem_dac);
+s->iomem_dac.disable_reentrancy_guard = true;
 
 sysbus_init_irq(sbd, >irq);
 
-- 
2.25.1




RE: [PATCH v3 02/21] sd: emmc: Add support for eMMC cards

2021-03-02 Thread Sai Pavan Boddu
Hi Cedric,
> -Original Message-
> From: Cédric Le Goater 
> Sent: Monday, March 1, 2021 4:32 PM
> To: Sai Pavan Boddu ; Markus Armbruster
> ; Kevin Wolf ; Max Reitz
> ; Vladimir Sementsov-Ogievskiy
> ; Eric Blake ; Joel Stanley
> ; Vincent Palatin ; Dr. David Alan
> Gilbert ; Thomas Huth ; Stefan
> Hajnoczi ; Peter Maydell ;
> Alistair Francis ; Edgar Iglesias 
> ;
> Luc Michel ; Paolo Bonzini
> 
> Cc: qemu-bl...@nongnu.org; qemu-devel@nongnu.org; Sai Pavan Boddu
> 
> Subject: Re: [PATCH v3 02/21] sd: emmc: Add support for eMMC cards
> 
> On 2/28/21 8:33 PM, Sai Pavan Boddu wrote:
> > Add eMMC device built on top of SD card.
> >
> > Signed-off-by: Sai Pavan Boddu 
> > ---
> >  include/hw/sd/sd.h |  2 ++
> >  hw/sd/sd.c | 20 
> >  2 files changed, 22 insertions(+)
> >
> > diff --git a/include/hw/sd/sd.h b/include/hw/sd/sd.h index
> > 05ef9b7..b402dad 100644
> > --- a/include/hw/sd/sd.h
> > +++ b/include/hw/sd/sd.h
> > @@ -90,6 +90,8 @@ typedef struct {
> >  } SDRequest;
> >
> >
> > +#define TYPE_EMMC "emmc"
> > +OBJECT_DECLARE_SIMPLE_TYPE(EMMCState, EMMC)
> >  #define TYPE_SD_CARD "sd-card"
> >  OBJECT_DECLARE_TYPE(SDState, SDCardClass, SD_CARD)
> >
> > diff --git a/hw/sd/sd.c b/hw/sd/sd.c
> > index 74b9162..a23af6d 100644
> > --- a/hw/sd/sd.c
> > +++ b/hw/sd/sd.c
> > @@ -108,6 +108,7 @@ struct SDState {
> >  uint8_t spec_version;
> >  BlockBackend *blk;
> >  bool spi;
> > +bool emmc;
> >
> >  /* Runtime changeables */
> >
> > @@ -143,6 +144,10 @@ struct SDState {
> >  bool cmd_line;
> >  };
> >
> > +struct EMMCState {
> > +SDState parent;
> > +};
> > +
> >  static void sd_realize(DeviceState *dev, Error **errp);
> >
> >  static const char *sd_state_name(enum SDCardStates state) @@ -2105,6
> > +2110,13 @@ static void sd_instance_init(Object *obj)
> >  sd->ocr_power_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL,
> > sd_ocr_powerup, sd);  }
> >
> > +static void emmc_instance_init(Object *obj) {
> > +SDState *sd = SD_CARD(obj);
> > +
> > +sd->emmc = true;
> > +}
> I think field 'emmc' would fit better in SDCardClass since it is a device 
> constant.
> You should not need 'struct EMMCState'. So something like below.
> Then you can add handlers for specific emmc commands.
> 
> Thanks,
> 
> C.
> 
> 
> diff --git a/include/hw/sd/sd.h b/include/hw/sd/sd.h index
> 47360ba4ee98..80e7cd526a57 100644
> --- a/include/hw/sd/sd.h
> +++ b/include/hw/sd/sd.h
> @@ -93,6 +93,8 @@ typedef struct {
>  #define TYPE_SD_CARD "sd-card"
>  OBJECT_DECLARE_TYPE(SDState, SDCardClass, SD_CARD)
> 
> +#define TYPE_EMMC "emmc"
> +
>  struct SDCardClass {
>  /*< private >*/
>  DeviceClass parent_class;
> @@ -124,6 +126,8 @@ struct SDCardClass {
>  void (*enable)(SDState *sd, bool enable);
>  bool (*get_inserted)(SDState *sd);
>  bool (*get_readonly)(SDState *sd);
> +
> +bool emmc;
>  };
> 
>  #define TYPE_SD_BUS "sd-bus"
> diff --git a/hw/sd/sd.c b/hw/sd/sd.c
> index 660026f2a667..95608f11b36e 100644
> --- a/hw/sd/sd.c
> +++ b/hw/sd/sd.c
> @@ -2447,9 +2447,24 @@ static const TypeInfo sd_info = {
>  .instance_finalize = sd_instance_finalize,  };
> 
> +static void emmc_class_init(ObjectClass *klass, void *data) {
> +SDCardClass *sc = SD_CARD_CLASS(klass);
> +
> +sc->emmc = true;
> +}
> +
> +static const TypeInfo emmc_info = {
> +.name = TYPE_EMMC,
> +.parent = TYPE_SD_CARD,
> +.instance_size = sizeof(SDState),
> +.class_init = emmc_class_init,
> +};
> +
[Sai Pavan Boddu] Yes, I see your point. Let me try, I was preferring a simpler 
approach just to not disturb the code much but lets see how this workout.

Thanks,
Sai Pavan
>  static void sd_register_types(void)
>  {
>  type_register_static(_info);
> +type_register_static(_info);
>  }
> 
>  type_init(sd_register_types)



RE: [PATCH v3 12/21] sd: emmc: add CMD21 tuning sequence

2021-03-02 Thread Sai Pavan Boddu
Hi David,

> -Original Message-
> From: Dr. David Alan Gilbert 
> Sent: Monday, March 1, 2021 4:12 PM
> To: Sai Pavan Boddu 
> Cc: Markus Armbruster ; Kevin Wolf
> ; Max Reitz ; Vladimir Sementsov-
> Ogievskiy ; Eric Blake ;
> Joel Stanley ; Cédric Le Goater ; Vincent
> Palatin ; Thomas Huth ; Stefan
> Hajnoczi ; Peter Maydell ;
> Alistair Francis ; Edgar Iglesias 
> ;
> Luc Michel ; Paolo Bonzini
> ; qemu-bl...@nongnu.org; qemu-devel@nongnu.org;
> Sai Pavan Boddu 
> Subject: Re: [PATCH v3 12/21] sd: emmc: add CMD21 tuning sequence
> 
> * Sai Pavan Boddu (sai.pavan.bo...@xilinx.com) wrote:
> > eMMC cards support tuning sequence for entering HS200 mode.
> >
> > Signed-off-by: Sai Pavan Boddu 
> > Signed-off-by: Edgar E. Iglesias 
> > ---
> >  hw/sd/sd.c | 47 +++
> >  1 file changed, 47 insertions(+)
> >
> > diff --git a/hw/sd/sd.c b/hw/sd/sd.c
> > index bf963ec..174c28e 100644
> > --- a/hw/sd/sd.c
> > +++ b/hw/sd/sd.c
> > @@ -1386,6 +1386,14 @@ static sd_rsp_type_t
> sd_normal_command(SDState *sd, SDRequest req)
> >  }
> >  break;
> >
> > +case 21:/* CMD21: mmc SEND TUNING_BLOCK */
> > +if (sd->emmc && (sd->state == sd_transfer_state)) {
> > +sd->state = sd_sendingdata_state;
> > +sd->data_offset = 0;
> > +return sd_r1;
> > +}
> > +break;
> > +
> >  case 23:/* CMD23: SET_BLOCK_COUNT */
> >  if (sd->spec_version < SD_PHY_SPECv3_01_VERS) {
> >  break;
> > @@ -2120,6 +2128,30 @@ static const uint8_t
> sd_tuning_block_pattern[SD_TUNING_BLOCK_SIZE] = {
> >  0xbb, 0xff, 0xf7, 0xff, 0xf7, 0x7f, 0x7b, 0xde,
> >  };
> >
> > +#define EXCSD_BUS_WIDTH_OFFSET 183
> > +#define BUS_WIDTH_8_MASK0x4
> > +#define BUS_WIDTH_4_MASK0x2
> > +#define MMC_TUNING_BLOCK_SIZE   128
> > +
> > +static const uint8_t mmc_tunning_block_pattern[128] = {
> > +   0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00,
> > +   0xff, 0xff, 0xcc, 0xcc, 0xcc, 0x33, 0xcc, 0xcc,
> > +   0xcc, 0x33, 0x33, 0xcc, 0xcc, 0xcc, 0xff, 0xff,
> > +   0xff, 0xee, 0xff, 0xff, 0xff, 0xee, 0xee, 0xff,
> > +   0xff, 0xff, 0xdd, 0xff, 0xff, 0xff, 0xdd, 0xdd,
> > +   0xff, 0xff, 0xff, 0xbb, 0xff, 0xff, 0xff, 0xbb,
> > +   0xbb, 0xff, 0xff, 0xff, 0x77, 0xff, 0xff, 0xff,
> > +   0x77, 0x77, 0xff, 0x77, 0xbb, 0xdd, 0xee, 0xff,
> > +   0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00,
> > +   0x00, 0xff, 0xff, 0xcc, 0xcc, 0xcc, 0x33, 0xcc,
> > +   0xcc, 0xcc, 0x33, 0x33, 0xcc, 0xcc, 0xcc, 0xff,
> > +   0xff, 0xff, 0xee, 0xff, 0xff, 0xff, 0xee, 0xee,
> > +   0xff, 0xff, 0xff, 0xdd, 0xff, 0xff, 0xff, 0xdd,
> > +   0xdd, 0xff, 0xff, 0xff, 0xbb, 0xff, 0xff, 0xff,
> > +   0xbb, 0xbb, 0xff, 0xff, 0xff, 0x77, 0xff, 0xff,
> > +   0xff, 0x77, 0x77, 0xff, 0x77, 0xbb, 0xdd, 0xee,
> 
> Where does this magic pattern come from?  Is it part of some spec?
[Sai Pavan Boddu] Yes its part of JEDEC eMMC spec. It's the tuning sequence for 
HS200 mode.

Regards,
Sai Pavan
> 
> Dave
> 
> > +};
> > +
> >  uint8_t sd_read_byte(SDState *sd)
> >  {
> >  /* TODO: Append CRCs */
> > @@ -2213,6 +2245,21 @@ uint8_t sd_read_byte(SDState *sd)
> >  ret = sd_tuning_block_pattern[sd->data_offset++];
> >  break;
> >
> > +case 21:/* CMD21: SEND_TUNNING_BLOCK (MMC) */
> > +if (sd->data_offset >= MMC_TUNING_BLOCK_SIZE - 1) {
> > +sd->state = sd_transfer_state;
> > +}
> > +if (sd->ext_csd[EXCSD_BUS_WIDTH_OFFSET] & BUS_WIDTH_8_MASK) {
> > +ret = mmc_tunning_block_pattern[sd->data_offset++];
> > +} else {
> > +/* Return LSB Nibbles of two byte from the 8bit tuning block
> > + * for 4bit mode
> > + */
> > +ret = mmc_tunning_block_pattern[sd->data_offset++] & 0x0F;
> > +ret |= (mmc_tunning_block_pattern[sd->data_offset++] & 0x0F) 
> > << 4;
> > +}
> > +break;
> > +
> >  case 22:/* ACMD22: SEND_NUM_WR_BLOCKS */
> >  ret = sd->data[sd->data_offset ++];
> >
> > --
> > 2.7.4
> >
> --
> Dr. David Alan Gilbert / dgilb...@redhat.com / Manchester, UK




[PATCH v3 18/21] sd: sdhci: Support eMMC devices

2021-02-28 Thread Sai Pavan Boddu
Embedded device slots should be allowed as support of eMMC is available.

Signed-off-by: Sai Pavan Boddu 
---
 hw/sd/sdhci.c | 4 
 1 file changed, 4 deletions(-)

diff --git a/hw/sd/sdhci.c b/hw/sd/sdhci.c
index 8ffa539..771212a 100644
--- a/hw/sd/sdhci.c
+++ b/hw/sd/sdhci.c
@@ -99,10 +99,6 @@ static void sdhci_check_capareg(SDHCIState *s, Error **errp)
 msk = FIELD_DP64(msk, SDHC_CAPAB, ASYNC_INT, 0);
 
 val = FIELD_EX64(s->capareg, SDHC_CAPAB, SLOT_TYPE);
-if (val) {
-error_setg(errp, "slot-type not supported");
-return;
-}
 trace_sdhci_capareg("slot type", val);
 msk = FIELD_DP64(msk, SDHC_CAPAB, SLOT_TYPE, 0);
 
-- 
2.7.4




[PATCH v3 16/21] sd: emmc: Support boot area in emmc image

2021-02-28 Thread Sai Pavan Boddu
From: Joel Stanley 

This assumes a specially constructued image:

  dd if=/dev/zero of=mmc-bootarea.img count=2 bs=1M
  dd if=u-boot-spl.bin of=mmc-bootarea.img conv=notrunc
  dd if=u-boot.bin of=mmc-bootarea.img conv=notrunc count=64 bs=1K
  cat mmc-bootarea.img obmc-phosphor-image.wic > mmc.img
  truncate --size 16GB mmc.img
  truncate --size 128MB mmc-bootarea.img

Signed-off-by: Joel Stanley 
[clg: - changes on the definition names ]
Signed-off-by: Cédric Le Goater 
[spb: use data_start property to access right emmc partition,
  Clean up PARTITION_ENABLE support as incomplete,
  Fix commit message to be generic.]
Signed-off-by: Sai Pavan Boddu 
---
 hw/sd/sd.c | 40 
 1 file changed, 40 insertions(+)

diff --git a/hw/sd/sd.c b/hw/sd/sd.c
index 08b77ad..d311477 100644
--- a/hw/sd/sd.c
+++ b/hw/sd/sd.c
@@ -1044,6 +1044,34 @@ static void sd_lock_command(SDState *sd)
 sd->card_status &= ~CARD_IS_LOCKED;
 }
 
+/*
+ * This requires a disk image that has two boot partitions inserted at the
+ * beginning of it. The size of the boot partitions are configured in the
+ * ext_csd structure, which is hardcoded in qemu. They are currently set to
+ * 1MB each.
+ */
+static uint32_t sd_bootpart_offset(SDState *sd)
+{
+unsigned int access = sd->ext_csd[EXT_CSD_PART_CONFIG] &
+EXT_CSD_PART_CONFIG_ACC_MASK;
+unsigned int boot_capacity = sd->ext_csd[EXT_CSD_BOOT_MULT] << 17;
+
+if (!sd->emmc) {
+return 0;
+}
+
+switch (access) {
+case EXT_CSD_PART_CONFIG_ACC_DEFAULT:
+return boot_capacity * 2;
+case EXT_CSD_PART_CONFIG_ACC_BOOT0:
+return 0;
+case EXT_CSD_PART_CONFIG_ACC_BOOT0 + 1:
+return boot_capacity * 1;
+default:
+ g_assert_not_reached();
+}
+}
+
 static sd_rsp_type_t sd_normal_command(SDState *sd, SDRequest req)
 {
 uint32_t rca = 0x;
@@ -1359,6 +1387,9 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, 
SDRequest req)
 return sd_r1;
 }
 
+if (sd->emmc) {
+addr += sd_bootpart_offset(sd);
+}
 sd->state = sd_sendingdata_state;
 sd->data_start = addr;
 sd->data_offset = 0;
@@ -1378,6 +1409,9 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, 
SDRequest req)
 return sd_r1;
 }
 
+if (sd->emmc) {
+addr += sd_bootpart_offset(sd);
+}
 sd->state = sd_sendingdata_state;
 sd->data_start = addr;
 sd->data_offset = 0;
@@ -1434,6 +1468,9 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, 
SDRequest req)
 return sd_r1;
 }
 
+if (sd->emmc) {
+addr += sd_bootpart_offset(sd);
+}
 sd->state = sd_receivingdata_state;
 sd->data_start = addr;
 sd->data_offset = 0;
@@ -1464,6 +1501,9 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, 
SDRequest req)
 return sd_r1;
 }
 
+if (sd->emmc) {
+addr += sd_bootpart_offset(sd);
+}
 sd->state = sd_receivingdata_state;
 sd->data_start = addr;
 sd->data_offset = 0;
-- 
2.7.4




[PATCH v3 14/21] sd: emmc: Add support for emmc erase

2021-02-28 Thread Sai Pavan Boddu
Add CMD35 and CMD36 which sets the erase start and end.

Signed-off-by: Sai Pavan Boddu 
Signed-off-by: Edgar E. Iglesias 
---
 hw/sd/sd.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/hw/sd/sd.c b/hw/sd/sd.c
index 09c1222..bba0446 100644
--- a/hw/sd/sd.c
+++ b/hw/sd/sd.c
@@ -1552,6 +1552,7 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, 
SDRequest req)
 
 /* Erase commands (Class 5) */
 case 32:/* CMD32:  ERASE_WR_BLK_START */
+case 35:/* CMD35:  ERASE_GROUP_START */
 switch (sd->state) {
 case sd_transfer_state:
 sd->erase_start = req.arg;
@@ -1563,6 +1564,7 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, 
SDRequest req)
 break;
 
 case 33:/* CMD33:  ERASE_WR_BLK_END */
+case 36:/* CMD36:  ERASE_GROUP_END */
 switch (sd->state) {
 case sd_transfer_state:
 sd->erase_end = req.arg;
-- 
2.7.4




[PATCH v3 05/21] sd: emmc: Add support for EXT_CSD & CSD for eMMC

2021-02-28 Thread Sai Pavan Boddu
From: Vincent Palatin 

eMMC CSD is similar to SD with an option to refer EXT_CSD for larger
devices.

Signed-off-by: Vincent Palatin 
[clg: Add user friendly macros for EXT_CSD register]
Signed-off-by: Cédric Le Goater 
[spb: updated commit message]
Signed-off-by: Sai Pavan Boddu 
---
 hw/sd/sdmmc-internal.h | 97 ++
 hw/sd/sd.c | 61 +--
 2 files changed, 156 insertions(+), 2 deletions(-)

diff --git a/hw/sd/sdmmc-internal.h b/hw/sd/sdmmc-internal.h
index d8bf17d..7ab7b4d 100644
--- a/hw/sd/sdmmc-internal.h
+++ b/hw/sd/sdmmc-internal.h
@@ -37,4 +37,101 @@ const char *sd_cmd_name(uint8_t cmd);
  */
 const char *sd_acmd_name(uint8_t cmd);
 
+/*
+ * EXT_CSD fields
+ */
+
+#define EXT_CSD_CMDQ_MODE_EN15  /* R/W */
+#define EXT_CSD_FLUSH_CACHE   32  /* W */
+#define EXT_CSD_CACHE_CTRL33  /* R/W */
+#define EXT_CSD_POWER_OFF_NOTIFICATION  34  /* R/W */
+#define EXT_CSD_PACKED_FAILURE_INDEX  35  /* RO */
+#define EXT_CSD_PACKED_CMD_STATUS 36  /* RO */
+#define EXT_CSD_EXP_EVENTS_STATUS 54  /* RO, 2 bytes */
+#define EXT_CSD_EXP_EVENTS_CTRL   56  /* R/W, 2 bytes */
+#define EXT_CSD_DATA_SECTOR_SIZE  61  /* R */
+#define EXT_CSD_GP_SIZE_MULT143 /* R/W */
+#define EXT_CSD_PARTITION_SETTING_COMPLETED 155 /* R/W */
+#define EXT_CSD_PARTITION_ATTRIBUTE 156 /* R/W */
+#define EXT_CSD_PARTITION_SUPPORT 160 /* RO */
+#define EXT_CSD_HPI_MGMT161 /* R/W */
+#define EXT_CSD_RST_N_FUNCTION162 /* R/W */
+#define EXT_CSD_BKOPS_EN163 /* R/W */
+#define EXT_CSD_BKOPS_START   164 /* W */
+#define EXT_CSD_SANITIZE_START165 /* W */
+#define EXT_CSD_WR_REL_PARAM166 /* RO */
+#define EXT_CSD_RPMB_MULT   168 /* RO */
+#define EXT_CSD_FW_CONFIG   169 /* R/W */
+#define EXT_CSD_BOOT_WP 173 /* R/W */
+#define EXT_CSD_ERASE_GROUP_DEF   175 /* R/W */
+#define EXT_CSD_PART_CONFIG   179 /* R/W */
+#define EXT_CSD_ERASED_MEM_CONT   181 /* RO */
+#define EXT_CSD_BUS_WIDTH   183 /* R/W */
+#define EXT_CSD_STROBE_SUPPORT184 /* RO */
+#define EXT_CSD_HS_TIMING   185 /* R/W */
+#define EXT_CSD_POWER_CLASS   187 /* R/W */
+#define EXT_CSD_REV 192 /* RO */
+#define EXT_CSD_STRUCTURE   194 /* RO */
+#define EXT_CSD_CARD_TYPE   196 /* RO */
+#define EXT_CSD_DRIVER_STRENGTH   197 /* RO */
+#define EXT_CSD_OUT_OF_INTERRUPT_TIME 198 /* RO */
+#define EXT_CSD_PART_SWITCH_TIME199 /* RO */
+#define EXT_CSD_PWR_CL_52_195   200 /* RO */
+#define EXT_CSD_PWR_CL_26_195   201 /* RO */
+#define EXT_CSD_PWR_CL_52_360   202 /* RO */
+#define EXT_CSD_PWR_CL_26_360   203 /* RO */
+#define EXT_CSD_SEC_CNT 212 /* RO, 4 bytes */
+#define EXT_CSD_S_A_TIMEOUT   217 /* RO */
+#define EXT_CSD_S_C_VCCQ  219 /* RO */
+#define EXT_CSD_S_C_VCC 220 /* RO */
+#define EXT_CSD_REL_WR_SEC_C222 /* RO */
+#define EXT_CSD_HC_WP_GRP_SIZE221 /* RO */
+#define EXT_CSD_ERASE_TIMEOUT_MULT  223 /* RO */
+#define EXT_CSD_HC_ERASE_GRP_SIZE 224 /* RO */
+#define EXT_CSD_ACC_SIZE225 /* RO */
+#define EXT_CSD_BOOT_MULT   226 /* RO */
+#define EXT_CSD_BOOT_INFO   228 /* RO */
+#define EXT_CSD_SEC_TRIM_MULT   229 /* RO */
+#define EXT_CSD_SEC_ERASE_MULT230 /* RO */
+#define EXT_CSD_SEC_FEATURE_SUPPORT 231 /* RO */
+#define EXT_CSD_TRIM_MULT   232 /* RO */
+#define EXT_CSD_PWR_CL_200_195236 /* RO */
+#define EXT_CSD_PWR_CL_200_360237 /* RO */
+#define EXT_CSD_PWR_CL_DDR_52_195 238 /* RO */
+#define EXT_CSD_PWR_CL_DDR_52_360 239 /* RO */
+#define EXT_CSD_BKOPS_STATUS246 /* RO */
+#define EXT_CSD_POWER_OFF_LONG_TIME 247 /* RO */
+#define EXT_CSD_GENERIC_CMD6_TIME 248 /* RO */
+#define EXT_CSD_CACHE_SIZE249 /* RO, 4 bytes */
+#define EXT_CSD_PWR_CL_DDR_200_360  253 /* RO */
+#define EXT_CSD_FIRMWARE_VERSION  254 /* RO, 8 bytes */
+#define EXT_CSD_PRE_EOL_INFO267 /* RO */
+#define EXT_CSD_DEVICE_LIFE_TIME_EST_TYP_A  268 /* RO */
+#define EXT_CSD_DEVICE_LIFE_TIME_EST_TYP_B  269 /* RO */
+#define EXT_CSD_CMDQ_DEPTH307 /* RO */
+#define EXT_CSD_CMDQ_SUPPORT308 /* RO */
+#define EXT_CSD_SUPPORTED_MODE493 /* RO */
+#define EXT_CSD_TAG_UNIT_SIZE   498 /* RO */
+#define EXT_CSD_DATA_TAG_SUPPORT  499 /* RO */
+#define EXT_CSD_MAX_PACKED_WRITES 500 /* RO */
+#define EXT_CSD_MAX_PACKED_READS  501 /* RO */
+#define EXT_CSD_BKOPS_SUPPORT   502 /* RO */
+#define EXT_CSD_HPI_FEATURES503 /* RO */
+#define EXT_CSD_S_CMD_SET   504 /* RO */
+
+/*
+ * EXT_CSD field definitions
+ */
+
+#define EXT_CSD_WR_REL_PARAM_EN   (1 << 2)
+#define EXT_CSD_WR_REL_PARAM_EN_RPMB_REL_WR (1 << 4)
+
+#define EXT_CSD_PART_CONFIG_ACC_MASK  (0x7)
+#define EXT_CSD_PART_CONFIG_ACC_DEFAULT (0x0)
+#define EXT_CSD_PART_CONFIG_ACC_BOOT0 (0x1)
+
+#define EXT_CSD_PART_CONFIG_EN_MASK (0x7 << 3)
+#define EXT_CSD_PART_CONFIG_EN_BOOT0  (0x1 << 3)
+#define EXT_CSD_PART_CONFIG_EN_USER (0x7 << 3)
+
 #endif
diff --git a/hw/sd/sd.c b/hw/sd/sd.c
index bc9d913..a26695b 100644
--- a/hw/sd/s

[PATCH v3 17/21] sd: emmc: Subtract bootarea size from blk

2021-02-28 Thread Sai Pavan Boddu
From: Joel Stanley 

The userdata size is derived from the file the user passes on the
command line, but we must take into account the boot areas.

Signed-off-by: Joel Stanley 
Signed-off-by: Cédric Le Goater 
---
 hw/sd/sd.c | 5 +
 1 file changed, 5 insertions(+)

diff --git a/hw/sd/sd.c b/hw/sd/sd.c
index d311477..5135a64 100644
--- a/hw/sd/sd.c
+++ b/hw/sd/sd.c
@@ -657,6 +657,11 @@ static void sd_reset(DeviceState *dev)
 }
 size = sect << 9;
 
+if (sd->emmc) {
+unsigned int boot_capacity = sd->ext_csd[EXT_CSD_BOOT_MULT] << 17;
+size -= boot_capacity * 2;
+}
+
 sect = sd_addr_to_wpnum(size) + 1;
 
 sd->state = sd_idle_state;
-- 
2.7.4




[PATCH v3 04/21] sd: emmc: update OCR fields for eMMC

2021-02-28 Thread Sai Pavan Boddu
From: Vincent Palatin 

eMMC OCR register doesn't has UHS-II field and voltage fields are
different.

Signed-off-by: Vincent Palatin 
Signed-off-by: Sai Pavan Boddu 
---
 hw/sd/sd.c | 27 ---
 1 file changed, 24 insertions(+), 3 deletions(-)

diff --git a/hw/sd/sd.c b/hw/sd/sd.c
index 6de414b..bc9d913 100644
--- a/hw/sd/sd.c
+++ b/hw/sd/sd.c
@@ -287,6 +287,15 @@ FIELD(OCR, UHS_II_CARD,29,  1) /* Only 
UHS-II */
 FIELD(OCR, CARD_CAPACITY,  30,  1) /* 0:SDSC, 1:SDHC/SDXC */
 FIELD(OCR, CARD_POWER_UP,  31,  1)
 
+/*
+ * eMMC OCR register
+ */
+FIELD(EMMC_OCR, VDD_WINDOW_0,  7, 1)
+FIELD(EMMC_OCR, VDD_WINDOW_1,  8, 7)
+FIELD(EMMC_OCR, VDD_WINDOW_2, 15, 9)
+FIELD(EMMC_OCR, ACCESS_MODE,  29, 2)
+FIELD(EMMC_OCR, POWER_UP, 31, 1)
+
 #define ACMD41_ENQUIRY_MASK 0x00ff
 #define ACMD41_R3_MASK  (R_OCR_VDD_VOLTAGE_WIN_HI_MASK \
| R_OCR_ACCEPT_SWITCH_1V8_MASK \
@@ -296,8 +305,16 @@ FIELD(OCR, CARD_POWER_UP,  31,  1)
 
 static void sd_set_ocr(SDState *sd)
 {
-/* All voltages OK */
-sd->ocr = R_OCR_VDD_VOLTAGE_WIN_HI_MASK;
+if (sd->emmc) {
+/*
+ * Dual Voltage eMMC card
+ */
+sd->ocr = R_EMMC_OCR_VDD_WINDOW_0_MASK |
+  R_EMMC_OCR_VDD_WINDOW_2_MASK;
+} else {
+/* All voltages OK */
+sd->ocr = R_OCR_VDD_VOLTAGE_WIN_HI_MASK;
+}
 }
 
 static void sd_ocr_powerup(void *opaque)
@@ -525,7 +542,11 @@ static void sd_response_r1_make(SDState *sd, uint8_t 
*response)
 
 static void sd_response_r3_make(SDState *sd, uint8_t *response)
 {
-stl_be_p(response, sd->ocr & ACMD41_R3_MASK);
+if (sd->emmc) {
+stl_be_p(response, sd->ocr);
+} else {
+stl_be_p(response, sd->ocr & ACMD41_R3_MASK);
+}
 }
 
 static void sd_response_r6_make(SDState *sd, uint8_t *response)
-- 
2.7.4




[PATCH v3 19/21] arm: xlnx-versal: Add emmc to versal

2021-02-28 Thread Sai Pavan Boddu
Configuring SDHCI-0 to act as eMMC controller.

Signed-off-by: Sai Pavan Boddu 
---
 include/hw/arm/xlnx-versal.h |  1 +
 hw/arm/xlnx-versal-virt.c| 29 +
 hw/arm/xlnx-versal.c | 14 --
 3 files changed, 38 insertions(+), 6 deletions(-)

diff --git a/include/hw/arm/xlnx-versal.h b/include/hw/arm/xlnx-versal.h
index 2b76885..440f3b4 100644
--- a/include/hw/arm/xlnx-versal.h
+++ b/include/hw/arm/xlnx-versal.h
@@ -76,6 +76,7 @@ struct Versal {
 struct {
 MemoryRegion *mr_ddr;
 uint32_t psci_conduit;
+bool has_emmc;
 } cfg;
 };
 
diff --git a/hw/arm/xlnx-versal-virt.c b/hw/arm/xlnx-versal-virt.c
index 8482cd6..053a322 100644
--- a/hw/arm/xlnx-versal-virt.c
+++ b/hw/arm/xlnx-versal-virt.c
@@ -46,6 +46,7 @@ struct VersalVirt {
 
 struct {
 bool secure;
+bool has_emmc;
 } cfg;
 };
 
@@ -333,6 +334,13 @@ static void fdt_add_sd_nodes(VersalVirt *s)
 qemu_fdt_setprop_sized_cells(s->fdt, name, "reg",
  2, addr, 2, MM_PMC_SD0_SIZE);
 qemu_fdt_setprop(s->fdt, name, "compatible", compat, sizeof(compat));
+/*
+ * eMMC specific properties
+ */
+if (s->cfg.has_emmc && i == 0) {
+qemu_fdt_setprop(s->fdt, name, "non-removable", NULL, 0);
+qemu_fdt_setprop_sized_cells(s->fdt, name, "bus-width", 1, 8);
+}
 g_free(name);
 }
 }
@@ -524,11 +532,17 @@ static void sd_plugin_card(SDHCIState *sd, DriveInfo *di)
_fatal);
 }
 
+static void versal_virt_set_emmc(Object *obj, bool value, Error **errp)
+{
+VersalVirt *s = XLNX_VERSAL_VIRT_MACHINE(obj);
+
+s->cfg.has_emmc = value;
+}
+
 static void versal_virt_init(MachineState *machine)
 {
 VersalVirt *s = XLNX_VERSAL_VIRT_MACHINE(machine);
 int psci_conduit = QEMU_PSCI_CONDUIT_DISABLED;
-int i;
 
 /*
  * If the user provides an Operating System to be loaded, we expect them
@@ -560,6 +574,8 @@ static void versal_virt_init(MachineState *machine)
  _abort);
 object_property_set_int(OBJECT(>soc), "psci-conduit", psci_conduit,
 _abort);
+object_property_set_bool(OBJECT(>soc), "has-emmc", s->cfg.has_emmc,
+ _abort);
 sysbus_realize(SYS_BUS_DEVICE(>soc), _fatal);
 
 fdt_create(s);
@@ -581,10 +597,12 @@ static void versal_virt_init(MachineState *machine)
 memory_region_add_subregion_overlap(get_system_memory(),
 0, >soc.fpd.apu.mr, 0);
 
-/* Plugin SD cards.  */
-for (i = 0; i < ARRAY_SIZE(s->soc.pmc.iou.sd); i++) {
-sd_plugin_card(>soc.pmc.iou.sd[i], drive_get_next(IF_SD));
+if (!s->cfg.has_emmc) {
+sd_plugin_card(>soc.pmc.iou.sd[0],
+drive_get_next(IF_SD));
 }
+/* Plugin SD cards.  */
+sd_plugin_card(>soc.pmc.iou.sd[1], drive_get_next(IF_SD));
 
 s->binfo.ram_size = machine->ram_size;
 s->binfo.loader_start = 0x0;
@@ -621,6 +639,9 @@ static void versal_virt_machine_class_init(ObjectClass *oc, 
void *data)
 mc->default_cpus = XLNX_VERSAL_NR_ACPUS;
 mc->no_cdrom = true;
 mc->default_ram_id = "ddr";
+object_class_property_add_bool(oc, "emmc",
+NULL, versal_virt_set_emmc);
+
 }
 
 static const TypeInfo versal_virt_machine_init_typeinfo = {
diff --git a/hw/arm/xlnx-versal.c b/hw/arm/xlnx-versal.c
index 628e77e..6ca2c8f 100644
--- a/hw/arm/xlnx-versal.c
+++ b/hw/arm/xlnx-versal.c
@@ -230,6 +230,9 @@ static void versal_create_admas(Versal *s, qemu_irq *pic)
 }
 
 #define SDHCI_CAPABILITIES  0x280737ec6481 /* Same as on ZynqMP.  */
+#define SDHCI_EMMC_CAPS ((SDHCI_CAPABILITIES & ~(3 << 30)) | \
+ (1 << 30))
+
 static void versal_create_sds(Versal *s, qemu_irq *pic)
 {
 int i;
@@ -242,11 +245,17 @@ static void versal_create_sds(Versal *s, qemu_irq *pic)
 TYPE_SYSBUS_SDHCI);
 dev = DEVICE(>pmc.iou.sd[i]);
 
+dev->id = g_strdup_printf("sdhci%d", i);
 object_property_set_uint(OBJECT(dev), "sd-spec-version", 3,
  _fatal);
-object_property_set_uint(OBJECT(dev), "capareg", SDHCI_CAPABILITIES,
+object_property_set_uint(OBJECT(dev), "capareg", SDHCI_EMMC_CAPS,
  _fatal);
-object_property_set_uint(OBJECT(dev), "uhs", UHS_I, _fatal);
+/*
+ * UHS is not applicable for eMMC
+ */
+if (!s->cfg.has_emmc || i == 1) {
+object_property_set_uint(OBJECT(dev), "uhs", UHS_I, _fatal);
+}
 sysbus_realize(SYS_BUS_DEVICE(dev), _fatal);
 
 mr = sys

[PATCH v3 21/21] docs: arm: xlnx-versal-virt: Add eMMC support documentation

2021-02-28 Thread Sai Pavan Boddu
Add details of eMMC specific machine property and example for passing
eMMC device.

Signed-off-by: Sai Pavan Boddu 
---
 docs/system/arm/xlnx-versal-virt.rst | 14 ++
 1 file changed, 14 insertions(+)

diff --git a/docs/system/arm/xlnx-versal-virt.rst 
b/docs/system/arm/xlnx-versal-virt.rst
index 2602d0f..d1099fa 100644
--- a/docs/system/arm/xlnx-versal-virt.rst
+++ b/docs/system/arm/xlnx-versal-virt.rst
@@ -29,6 +29,7 @@ Implemented devices:
 - 2 GEMs (Cadence MACB Ethernet MACs)
 - 8 ADMA (Xilinx zDMA) channels
 - 2 SD Controllers
+* SDHCI0 can be configured as eMMC
 - OCM (256KB of On Chip Memory)
 - DDR memory
 
@@ -43,6 +44,19 @@ Other differences between the hardware and the QEMU model:
 - QEMU provides 8 virtio-mmio virtio transports; these start at
   address ``0xa000`` and have IRQs from 111 and upwards.
 
+Enabling eMMC
+"""""""""""""
+In order to enable eMMC pass the following machine property "emmc=on".
+ex:
+"-M xlnx-versal-virt,emmc=on"
+
+Above switch would configure SDHCI0 to accept eMMC. More details on eMMC
+emulation can be found in docs/devel/emmc.txt.
+
+Below is the command to pass eMMC device.
+"-drive file=emmc.img,if=none,id=emmc,format=raw
+ -device emmc,drive=emmc,id=emmc0,bus=/sdhci0/sd-bus"
+
 Running
 """""""
 If the user provides an Operating System to be loaded, we expect users
-- 
2.7.4




[PATCH v3 00/21] eMMC support

2021-02-28 Thread Sai Pavan Boddu
Hi,

This patch series add support for eMMC cards. This work was previosly
submitted by Vincent, rebased few changes on top.

Cedric & Joel has helped to added boot partition access support. I
expect them to make a follow-up series to use it with aspeed machines.

Present series adds eMMC support to Versal SOC.

Initial patch series version is RFC
Changes for V2:
Split Patch 1
Add comments for eMMC Erase commands
Added documentation about eMMC and Versal-virt board.
Make eMMC optional for xlnx-versal-virt machines
Changes for V3:
Revome addition of EMMC drive flag
Add TYPE_EMMC device
Add id strings for shci instances
Update versal doc with eMMC example
Fix signed-off-by lines for few patches

Cédric Le Goater (1):
  sd: sdmmc-internal: Add command string for SEND_OP_CMD

Joel Stanley (2):
  sd: emmc: Support boot area in emmc image
  sd: emmc: Subtract bootarea size from blk

Sai Pavan Boddu (14):
  sd: sd: Remove usage of tabs in the file
  sd: emmc: Add support for eMMC cards
  sd: emmc: Dont not update CARD_CAPACITY for eMMC cards
  sd: emmc: Update CMD1 definition for eMMC
  sd: emmc: support idle state in CMD2
  sd: emmc: Add mmc switch function support
  sd: emmc: add CMD21 tuning sequence
  sd: emmc: Make ACMD41 illegal for mmc
  sd: emmc: Add support for emmc erase
  sd: emmc: Update CID structure for eMMC
  sd: sdhci: Support eMMC devices
  arm: xlnx-versal: Add emmc to versal
  docs: devel: emmc: Add a doc for emmc card emulation
  docs: arm: xlnx-versal-virt: Add eMMC support documentation

Vincent Palatin (4):
  sd: emmc: Update SET_RELATIVE_ADDR command
  sd: emmc: update OCR fields for eMMC
  sd: emmc: Add support for EXT_CSD & CSD for eMMC
  sd: emmc: Update CMD8 to send EXT_CSD register

 docs/devel/emmc.txt  |  16 +
 docs/system/arm/xlnx-versal-virt.rst |  14 +
 hw/sd/sdmmc-internal.h   |  97 ++
 include/hw/arm/xlnx-versal.h |   1 +
 include/hw/sd/sd.h   |   2 +
 hw/arm/xlnx-versal-virt.c|  29 +-
 hw/arm/xlnx-versal.c |  14 +-
 hw/sd/sd.c   | 563 ++-
 hw/sd/sdhci.c|   4 -
 hw/sd/sdmmc-internal.c   |   2 +-
 10 files changed, 594 insertions(+), 148 deletions(-)
 create mode 100644 docs/devel/emmc.txt

-- 
2.7.4




[PATCH v3 10/21] sd: emmc: support idle state in CMD2

2021-02-28 Thread Sai Pavan Boddu
eMMC is expected to be in idle-state post CMD1. Ready state is an
intermediate stage which we don't come across in Device identification
mode.

Signed-off-by: Sai Pavan Boddu 
Signed-off-by: Edgar E. Iglesias 
Reviewed-by: Alistair Francis 
---
 hw/sd/sd.c | 4 
 1 file changed, 4 insertions(+)

diff --git a/hw/sd/sd.c b/hw/sd/sd.c
index 054ad1e..8a7d0de 100644
--- a/hw/sd/sd.c
+++ b/hw/sd/sd.c
@@ -1059,6 +1059,10 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, 
SDRequest req)
 if (sd->spi)
 goto bad_cmd;
 switch (sd->state) {
+case sd_idle_state:
+if (!sd->emmc) {
+break;
+}
 case sd_ready_state:
 sd->state = sd_identification_state;
 return sd_r2_i;
-- 
2.7.4




[PATCH v3 12/21] sd: emmc: add CMD21 tuning sequence

2021-02-28 Thread Sai Pavan Boddu
eMMC cards support tuning sequence for entering HS200 mode.

Signed-off-by: Sai Pavan Boddu 
Signed-off-by: Edgar E. Iglesias 
---
 hw/sd/sd.c | 47 +++
 1 file changed, 47 insertions(+)

diff --git a/hw/sd/sd.c b/hw/sd/sd.c
index bf963ec..174c28e 100644
--- a/hw/sd/sd.c
+++ b/hw/sd/sd.c
@@ -1386,6 +1386,14 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, 
SDRequest req)
 }
 break;
 
+case 21:/* CMD21: mmc SEND TUNING_BLOCK */
+if (sd->emmc && (sd->state == sd_transfer_state)) {
+sd->state = sd_sendingdata_state;
+sd->data_offset = 0;
+return sd_r1;
+}
+break;
+
 case 23:/* CMD23: SET_BLOCK_COUNT */
 if (sd->spec_version < SD_PHY_SPECv3_01_VERS) {
 break;
@@ -2120,6 +2128,30 @@ static const uint8_t 
sd_tuning_block_pattern[SD_TUNING_BLOCK_SIZE] = {
 0xbb, 0xff, 0xf7, 0xff, 0xf7, 0x7f, 0x7b, 0xde,
 };
 
+#define EXCSD_BUS_WIDTH_OFFSET 183
+#define BUS_WIDTH_8_MASK0x4
+#define BUS_WIDTH_4_MASK0x2
+#define MMC_TUNING_BLOCK_SIZE   128
+
+static const uint8_t mmc_tunning_block_pattern[128] = {
+   0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00,
+   0xff, 0xff, 0xcc, 0xcc, 0xcc, 0x33, 0xcc, 0xcc,
+   0xcc, 0x33, 0x33, 0xcc, 0xcc, 0xcc, 0xff, 0xff,
+   0xff, 0xee, 0xff, 0xff, 0xff, 0xee, 0xee, 0xff,
+   0xff, 0xff, 0xdd, 0xff, 0xff, 0xff, 0xdd, 0xdd,
+   0xff, 0xff, 0xff, 0xbb, 0xff, 0xff, 0xff, 0xbb,
+   0xbb, 0xff, 0xff, 0xff, 0x77, 0xff, 0xff, 0xff,
+   0x77, 0x77, 0xff, 0x77, 0xbb, 0xdd, 0xee, 0xff,
+   0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00,
+   0x00, 0xff, 0xff, 0xcc, 0xcc, 0xcc, 0x33, 0xcc,
+   0xcc, 0xcc, 0x33, 0x33, 0xcc, 0xcc, 0xcc, 0xff,
+   0xff, 0xff, 0xee, 0xff, 0xff, 0xff, 0xee, 0xee,
+   0xff, 0xff, 0xff, 0xdd, 0xff, 0xff, 0xff, 0xdd,
+   0xdd, 0xff, 0xff, 0xff, 0xbb, 0xff, 0xff, 0xff,
+   0xbb, 0xbb, 0xff, 0xff, 0xff, 0x77, 0xff, 0xff,
+   0xff, 0x77, 0x77, 0xff, 0x77, 0xbb, 0xdd, 0xee,
+};
+
 uint8_t sd_read_byte(SDState *sd)
 {
 /* TODO: Append CRCs */
@@ -2213,6 +2245,21 @@ uint8_t sd_read_byte(SDState *sd)
 ret = sd_tuning_block_pattern[sd->data_offset++];
 break;
 
+case 21:/* CMD21: SEND_TUNNING_BLOCK (MMC) */
+if (sd->data_offset >= MMC_TUNING_BLOCK_SIZE - 1) {
+sd->state = sd_transfer_state;
+}
+if (sd->ext_csd[EXCSD_BUS_WIDTH_OFFSET] & BUS_WIDTH_8_MASK) {
+ret = mmc_tunning_block_pattern[sd->data_offset++];
+} else {
+/* Return LSB Nibbles of two byte from the 8bit tuning block
+ * for 4bit mode
+ */
+ret = mmc_tunning_block_pattern[sd->data_offset++] & 0x0F;
+ret |= (mmc_tunning_block_pattern[sd->data_offset++] & 0x0F) << 4;
+}
+break;
+
 case 22:/* ACMD22: SEND_NUM_WR_BLOCKS */
 ret = sd->data[sd->data_offset ++];
 
-- 
2.7.4




[PATCH v3 20/21] docs: devel: emmc: Add a doc for emmc card emulation

2021-02-28 Thread Sai Pavan Boddu
Add few simple steps to create emmc card with boot and user data
partitions.

Signed-off-by: Sai Pavan Boddu 
---
 docs/devel/emmc.txt | 16 
 1 file changed, 16 insertions(+)
 create mode 100644 docs/devel/emmc.txt

diff --git a/docs/devel/emmc.txt b/docs/devel/emmc.txt
new file mode 100644
index 000..2d098fe
--- /dev/null
+++ b/docs/devel/emmc.txt
@@ -0,0 +1,16 @@
+
+eMMC block emulation
+
+
+Any eMMC devices has 3 kinds of partitions Boot, RPMB and User data. We
+are supporting Boot and User data partitions. Boot area partitions are
+expected to be 1MB size as hard coded in EXT_CSD register.
+
+Below is the example of combining two 1MB bootarea partition and
+user data partitions.
+
+  cat mmc-bootarea0.bin mmc-bootarea1.bin  image.wic > mmc.img
+  qemu-img resize mmc.img 4G
+
+Note: mmc-bootarea0/1 are just raw paritions. User data can have
+partition tables.
-- 
2.7.4




[PATCH v3 06/21] sd: emmc: Update CMD8 to send EXT_CSD register

2021-02-28 Thread Sai Pavan Boddu
From: Vincent Palatin 

Sends the EXT_CSD register as response to CMD8.

Signed-off-by: Vincent Palatin 
Signed-off-by: Sai Pavan Boddu 
---
 hw/sd/sd.c | 52 
 1 file changed, 36 insertions(+), 16 deletions(-)

diff --git a/hw/sd/sd.c b/hw/sd/sd.c
index a26695b..181e7e2 100644
--- a/hw/sd/sd.c
+++ b/hw/sd/sd.c
@@ -1141,24 +1141,37 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, 
SDRequest req)
 }
 break;
 
-case 8: /* CMD8:   SEND_IF_COND */
-if (sd->spec_version < SD_PHY_SPECv2_00_VERS) {
-break;
-}
-if (sd->state != sd_idle_state) {
-break;
-}
-sd->vhs = 0;
-
-/* No response if not exactly one VHS bit is set.  */
-if (!(req.arg >> 8) || (req.arg >> (ctz32(req.arg & ~0xff) + 1))) {
-return sd->spi ? sd_r7 : sd_r0;
-}
+case 8:/* CMD8:   SEND_IF_COND / SEND_EXT_CSD */
+if (sd->emmc) {
+switch (sd->state) {
+case sd_transfer_state:
+/* MMC : Sends the EXT_CSD register as a Block of data */
+sd->state = sd_sendingdata_state;
+memcpy(sd->data, sd->ext_csd, sizeof(sd->ext_csd));
+sd->data_start = addr;
+sd->data_offset = 0;
+return sd_r1;
+default:
+break;
+}
+} else {
+if (sd->spec_version < SD_PHY_SPECv2_00_VERS) {
+break;
+}
+if (sd->state != sd_idle_state) {
+break;
+}
+sd->vhs = 0;
 
-/* Accept.  */
-sd->vhs = req.arg;
-return sd_r7;
+/* No response if not exactly one VHS bit is set.  */
+if (!(req.arg >> 8) || (req.arg >> (ctz32(req.arg & ~0xff) + 1))) {
+return sd->spi ? sd_r7 : sd_r0;
+}
 
+/* Accept.  */
+sd->vhs = req.arg;
+return sd_r7;
+}
 case 9: /* CMD9:   SEND_CSD */
 switch (sd->state) {
 case sd_standby_state:
@@ -2081,6 +2094,13 @@ uint8_t sd_read_byte(SDState *sd)
 sd->state = sd_transfer_state;
 break;
 
+case 8: /* CMD8: SEND_EXT_CSD on MMC */
+ret = sd->data[sd->data_offset++];
+if (sd->data_offset >= sizeof(sd->ext_csd)) {
+sd->state = sd_transfer_state;
+}
+break;
+
 case 9: /* CMD9:   SEND_CSD */
 case 10:/* CMD10:  SEND_CID */
 ret = sd->data[sd->data_offset ++];
-- 
2.7.4




[PATCH v3 13/21] sd: emmc: Make ACMD41 illegal for mmc

2021-02-28 Thread Sai Pavan Boddu
ACMD41 is not applicable for eMMC.

Signed-off-by: Sai Pavan Boddu 
Signed-off-by: Edgar E. Iglesias 
---
 hw/sd/sd.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/hw/sd/sd.c b/hw/sd/sd.c
index 174c28e..09c1222 100644
--- a/hw/sd/sd.c
+++ b/hw/sd/sd.c
@@ -1737,6 +1737,9 @@ static sd_rsp_type_t sd_app_command(SDState *sd,
 break;
 
 case 41:/* ACMD41: SD_APP_OP_COND */
+if (sd->emmc) {
+break;
+}
 if (sd->spi) {
 /* SEND_OP_CMD */
 sd->state = sd_transfer_state;
-- 
2.7.4




[PATCH v3 01/21] sd: sd: Remove usage of tabs in the file

2021-02-28 Thread Sai Pavan Boddu
Set tabstop as 4 and used expandtabs

Signed-off-by: Sai Pavan Boddu 
---
 hw/sd/sd.c | 190 ++---
 1 file changed, 95 insertions(+), 95 deletions(-)

diff --git a/hw/sd/sd.c b/hw/sd/sd.c
index 8517dbc..74b9162 100644
--- a/hw/sd/sd.c
+++ b/hw/sd/sd.c
@@ -332,39 +332,39 @@ static void sd_set_scr(SDState *sd)
 sd->scr[7] = 0x00;
 }
 
-#define MID0xaa
-#define OID"XY"
-#define PNM"QEMU!"
-#define PRV0x01
-#define MDT_YR 2006
-#define MDT_MON2
+#define MID 0xaa
+#define OID "XY"
+#define PNM "QEMU!"
+#define PRV 0x01
+#define MDT_YR  2006
+#define MDT_MON 2
 
 static void sd_set_cid(SDState *sd)
 {
-sd->cid[0] = MID;  /* Fake card manufacturer ID (MID) */
-sd->cid[1] = OID[0];   /* OEM/Application ID (OID) */
+sd->cid[0] = MID;   /* Fake card manufacturer ID (MID) */
+sd->cid[1] = OID[0];/* OEM/Application ID (OID) */
 sd->cid[2] = OID[1];
-sd->cid[3] = PNM[0];   /* Fake product name (PNM) */
+sd->cid[3] = PNM[0];/* Fake product name (PNM) */
 sd->cid[4] = PNM[1];
 sd->cid[5] = PNM[2];
 sd->cid[6] = PNM[3];
 sd->cid[7] = PNM[4];
-sd->cid[8] = PRV;  /* Fake product revision (PRV) */
-sd->cid[9] = 0xde; /* Fake serial number (PSN) */
+sd->cid[8] = PRV;   /* Fake product revision (PRV) */
+sd->cid[9] = 0xde;  /* Fake serial number (PSN) */
 sd->cid[10] = 0xad;
 sd->cid[11] = 0xbe;
 sd->cid[12] = 0xef;
-sd->cid[13] = 0x00 |   /* Manufacture date (MDT) */
+sd->cid[13] = 0x00 |/* Manufacture date (MDT) */
 ((MDT_YR - 2000) / 10);
 sd->cid[14] = ((MDT_YR % 10) << 4) | MDT_MON;
 sd->cid[15] = (sd_crc7(sd->cid, 15) << 1) | 1;
 }
 
-#define HWBLOCK_SHIFT  9   /* 512 bytes */
-#define SECTOR_SHIFT   5   /* 16 kilobytes */
-#define WPGROUP_SHIFT  7   /* 2 megs */
-#define CMULT_SHIFT9   /* 512 times HWBLOCK_SIZE */
-#define WPGROUP_SIZE   (1 << (HWBLOCK_SHIFT + SECTOR_SHIFT + WPGROUP_SHIFT))
+#define HWBLOCK_SHIFT   9   /* 512 bytes */
+#define SECTOR_SHIFT5   /* 16 kilobytes */
+#define WPGROUP_SHIFT   7   /* 2 megs */
+#define CMULT_SHIFT 9   /* 512 times HWBLOCK_SIZE */
+#define WPGROUP_SIZE(1 << (HWBLOCK_SHIFT + SECTOR_SHIFT + WPGROUP_SHIFT))
 
 static const uint8_t sd_csd_rw_mask[16] = {
 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
@@ -385,31 +385,31 @@ static void sd_set_csd(SDState *sd, uint64_t size)
 csize = (size >> (CMULT_SHIFT + hwblock_shift)) - 1;
 
 if (size <= SDSC_MAX_CAPACITY) { /* Standard Capacity SD */
-sd->csd[0] = 0x00; /* CSD structure */
-sd->csd[1] = 0x26; /* Data read access-time-1 */
-sd->csd[2] = 0x00; /* Data read access-time-2 */
+sd->csd[0] = 0x00;  /* CSD structure */
+sd->csd[1] = 0x26;  /* Data read access-time-1 */
+sd->csd[2] = 0x00;  /* Data read access-time-2 */
 sd->csd[3] = 0x32;  /* Max. data transfer rate: 25 MHz */
-sd->csd[4] = 0x5f; /* Card Command Classes */
-sd->csd[5] = 0x50 |/* Max. read data block length */
+sd->csd[4] = 0x5f;  /* Card Command Classes */
+sd->csd[5] = 0x50 | /* Max. read data block length */
 hwblock_shift;
-sd->csd[6] = 0xe0 |/* Partial block for read allowed */
+sd->csd[6] = 0xe0 | /* Partial block for read allowed */
 ((csize >> 10) & 0x03);
-sd->csd[7] = 0x00 |/* Device size */
+sd->csd[7] = 0x00 | /* Device size */
 ((csize >> 2) & 0xff);
-sd->csd[8] = 0x3f |/* Max. read current */
+sd->csd[8] = 0x3f | /* Max. read current */
 ((csize << 6) & 0xc0);
-sd->csd[9] = 0xfc |/* Max. write current */
+sd->csd[9] = 0xfc | /* Max. write current */
 ((CMULT_SHIFT - 2) >> 1);
-sd->csd[10] = 0x40 |   /* Erase sector size */
+sd->csd[10] = 0x40 |/* Erase sector size */
 (((CMULT_SHIFT - 2) << 7) & 0x80) | (sectsize >> 1);
-sd->csd[11] = 0x00 |   /* Write protect group size */
+sd->csd[11] = 0x00 |/* Write protect group size */
 ((sectsize << 7) & 0x80) | wpsize;
-sd->csd[12] = 0x90 |   /* Write speed factor */
+sd->csd[12] = 0x90 |/* Write speed factor */
 (hwblock_shift >> 2);
-sd->csd[13] = 0x20 |   /* Max. write data block length */
+sd->csd[13] = 0x20 |/* Max. write data block length */
 ((hwblock_shift << 6) &am

[PATCH v3 11/21] sd: emmc: Add mmc switch function support

2021-02-28 Thread Sai Pavan Boddu
switch operation in eMMC card updates the ext_csd register to
request changes in card operations. Here we implement similar
sequence but requests are mostly dummy and make no change.

Implement SWITCH_ERROR if the write operation extends goes beyond length
of ext_csd.

Signed-off-by: Sai Pavan Boddu 
Signed-off-by: Edgar E. Iglesias 
---
 hw/sd/sd.c | 56 ++--
 1 file changed, 50 insertions(+), 6 deletions(-)

diff --git a/hw/sd/sd.c b/hw/sd/sd.c
index 8a7d0de..bf963ec 100644
--- a/hw/sd/sd.c
+++ b/hw/sd/sd.c
@@ -523,6 +523,7 @@ static void sd_set_rca(SDState *sd, uint16_t value)
 FIELD(CSR, AKE_SEQ_ERROR,   3,  1)
 FIELD(CSR, APP_CMD, 5,  1)
 FIELD(CSR, FX_EVENT,6,  1)
+FIELD(CSR, SWITCH_ERROR,7,  1)
 FIELD(CSR, READY_FOR_DATA,  8,  1)
 FIELD(CSR, CURRENT_STATE,   9,  4)
 FIELD(CSR, ERASE_RESET,13,  1)
@@ -886,6 +887,43 @@ static uint32_t sd_wpbits(SDState *sd, uint64_t addr)
 return ret;
 }
 
+enum {
+MMC_CMD6_ACCESS_COMMAND_SET = 0,
+MMC_CMD6_ACCESS_SET_BITS,
+MMC_CMD6_ACCESS_CLEAR_BITS,
+MMC_CMD6_ACCESS_WRITE_BYTE,
+};
+
+static void mmc_function_switch(SDState *sd, uint32_t arg)
+{
+uint32_t access = extract32(arg, 24, 2);
+uint32_t index = extract32(arg, 16, 8);
+uint32_t value = extract32(arg, 8, 8);
+uint8_t b = sd->ext_csd[index];
+
+switch (access) {
+case MMC_CMD6_ACCESS_COMMAND_SET:
+qemu_log_mask(LOG_UNIMP, "MMC Command set switching not supported\n");
+return;
+case MMC_CMD6_ACCESS_SET_BITS:
+b |= value;
+break;
+case MMC_CMD6_ACCESS_CLEAR_BITS:
+b &= ~value;
+break;
+case MMC_CMD6_ACCESS_WRITE_BYTE:
+b = value;
+break;
+}
+
+if (index >= 192) {
+sd->card_status |= R_CSR_SWITCH_ERROR_MASK;
+return;
+}
+
+sd->ext_csd[index] = b;
+}
+
 static void sd_function_switch(SDState *sd, uint32_t arg)
 {
 int i, mode, new_func;
@@ -1105,12 +1143,18 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, 
SDRequest req)
 case 6: /* CMD6:   SWITCH_FUNCTION */
 switch (sd->mode) {
 case sd_data_transfer_mode:
-sd_function_switch(sd, req.arg);
-sd->state = sd_sendingdata_state;
-sd->data_start = 0;
-sd->data_offset = 0;
-return sd_r1;
-
+if (sd->emmc) {
+sd->state = sd_programming_state;
+mmc_function_switch(sd, req.arg);
+sd->state = sd_transfer_state;
+return sd_r1b;
+} else {
+sd_function_switch(sd, req.arg);
+sd->state = sd_sendingdata_state;
+sd->data_start = 0;
+sd->data_offset = 0;
+return sd_r1;
+}
 default:
 break;
 }
-- 
2.7.4




[PATCH v3 03/21] sd: emmc: Update SET_RELATIVE_ADDR command

2021-02-28 Thread Sai Pavan Boddu
From: Vincent Palatin 

Change SET_RELATIVE_ADDR command to assign relative address
as requested by user.

Signed-off-by: Vincent Palatin 
Signed-off-by: Joel Stanley 
Signed-off-by: Cédric Le Goater 
[spb: Split original patch series]
Signed-off-by: Sai Pavan Boddu 
---
 hw/sd/sd.c | 12 
 1 file changed, 8 insertions(+), 4 deletions(-)

diff --git a/hw/sd/sd.c b/hw/sd/sd.c
index a23af6d..6de414b 100644
--- a/hw/sd/sd.c
+++ b/hw/sd/sd.c
@@ -436,9 +436,13 @@ static void sd_set_csd(SDState *sd, uint64_t size)
 sd->csd[15] = (sd_crc7(sd->csd, 15) << 1) | 1;
 }
 
-static void sd_set_rca(SDState *sd)
+static void sd_set_rca(SDState *sd, uint16_t value)
 {
-sd->rca += 0x4567;
+if (sd->emmc) {
+sd->rca = value;
+} else {
+sd->rca += 0x4567;
+}
 }
 
 FIELD(CSR, AKE_SEQ_ERROR,   3,  1)
@@ -984,8 +988,8 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, 
SDRequest req)
 case sd_identification_state:
 case sd_standby_state:
 sd->state = sd_standby_state;
-sd_set_rca(sd);
-return sd_r6;
+sd_set_rca(sd, req.arg >> 16);
+return sd->emmc ? sd_r1 : sd_r6;
 
 default:
 break;
-- 
2.7.4




[PATCH v3 08/21] sd: emmc: Dont not update CARD_CAPACITY for eMMC cards

2021-02-28 Thread Sai Pavan Boddu
OCR.CARD_CAPACITY field is only valid for sd cards, So skip it for eMMC.

Signed-off-by: Sai Pavan Boddu 
Signed-off-by: Edgar E. Iglesias 
Reviewed-by: Alistair Francis 
---
 hw/sd/sd.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/hw/sd/sd.c b/hw/sd/sd.c
index 181e7e2..2612135 100644
--- a/hw/sd/sd.c
+++ b/hw/sd/sd.c
@@ -328,7 +328,8 @@ static void sd_ocr_powerup(void *opaque)
 /* card power-up OK */
 sd->ocr = FIELD_DP32(sd->ocr, OCR, CARD_POWER_UP, 1);
 
-if (sd->size > SDSC_MAX_CAPACITY) {
+/* eMMC supports only Byte mode */
+if (!sd->emmc && sd->size > SDSC_MAX_CAPACITY) {
 sd->ocr = FIELD_DP32(sd->ocr, OCR, CARD_CAPACITY, 1);
 }
 }
-- 
2.7.4




[PATCH v3 15/21] sd: emmc: Update CID structure for eMMC

2021-02-28 Thread Sai Pavan Boddu
CID structure is little different for eMMC, w.r.t to product name and
manufacturing date.

Signed-off-by: Sai Pavan Boddu 
Signed-off-by: Edgar E. Iglesias 
---
 hw/sd/sd.c | 47 ++-
 1 file changed, 30 insertions(+), 17 deletions(-)

diff --git a/hw/sd/sd.c b/hw/sd/sd.c
index bba0446..08b77ad 100644
--- a/hw/sd/sd.c
+++ b/hw/sd/sd.c
@@ -365,23 +365,36 @@ static void sd_set_scr(SDState *sd)
 
 static void sd_set_cid(SDState *sd)
 {
-sd->cid[0] = MID;   /* Fake card manufacturer ID (MID) */
-sd->cid[1] = OID[0];/* OEM/Application ID (OID) */
-sd->cid[2] = OID[1];
-sd->cid[3] = PNM[0];/* Fake product name (PNM) */
-sd->cid[4] = PNM[1];
-sd->cid[5] = PNM[2];
-sd->cid[6] = PNM[3];
-sd->cid[7] = PNM[4];
-sd->cid[8] = PRV;   /* Fake product revision (PRV) */
-sd->cid[9] = 0xde;  /* Fake serial number (PSN) */
-sd->cid[10] = 0xad;
-sd->cid[11] = 0xbe;
-sd->cid[12] = 0xef;
-sd->cid[13] = 0x00 |/* Manufacture date (MDT) */
-((MDT_YR - 2000) / 10);
-sd->cid[14] = ((MDT_YR % 10) << 4) | MDT_MON;
-sd->cid[15] = (sd_crc7(sd->cid, 15) << 1) | 1;
+if (sd->emmc) {
+sd->cid[0] = MID;
+sd->cid[1] = 0x1;   /* CBX */
+sd->cid[2] = OID[0];/* OEM/Application ID (OID) */
+sd->cid[8] = 0x0;
+sd->cid[9] = PRV;/* Fake product revision (PRV) */
+sd->cid[10] = 0xde;  /* Fake serial number (PSN) */
+sd->cid[11] = 0xad;
+sd->cid[12] = 0xbe;
+sd->cid[13] = 0xef;
+sd->cid[14] = ((MDT_YR - 1997) % 0x10); /* MDT */
+} else {
+sd->cid[0] = MID;   /* Fake card manufacturer ID (MID) */
+sd->cid[1] = OID[0];/* OEM/Application ID (OID) */
+sd->cid[2] = OID[1];
+sd->cid[8] = PRV;   /* Fake product revision (PRV) */
+sd->cid[9] = 0xde;  /* Fake serial number (PSN) */
+sd->cid[10] = 0xad;
+sd->cid[11] = 0xbe;
+sd->cid[12] = 0xef;
+sd->cid[13] = 0x00 |/* Manufacture date (MDT) */
+((MDT_YR - 2000) / 10);
+sd->cid[14] = ((MDT_YR % 10) << 4) | MDT_MON;
+   }
+   sd->cid[3] = PNM[0];/* Fake product name (PNM) 48bit */
+   sd->cid[4] = PNM[1];
+   sd->cid[5] = PNM[2];
+   sd->cid[6] = PNM[3];
+   sd->cid[7] = PNM[4];
+   sd->cid[15] = (sd_crc7(sd->cid, 15) << 1) | 1;
 }
 
 #define HWBLOCK_SHIFT   9   /* 512 bytes */
-- 
2.7.4




[PATCH v3 09/21] sd: emmc: Update CMD1 definition for eMMC

2021-02-28 Thread Sai Pavan Boddu
Add support to Power up the card and send response r3 in case of eMMC.

Signed-off-by: Sai Pavan Boddu 
Signed-off-by: Edgar E. Iglesias 
Reviewed-by: Alistair Francis 
---
 hw/sd/sd.c | 10 +-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/hw/sd/sd.c b/hw/sd/sd.c
index 2612135..054ad1e 100644
--- a/hw/sd/sd.c
+++ b/hw/sd/sd.c
@@ -1041,8 +1041,16 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, 
SDRequest req)
 break;
 
 case 1: /* CMD1:   SEND_OP_CMD */
-if (!sd->spi)
+/* MMC: Powerup & send r3
+ * SD: send r1 in spi mode
+ */
+if (sd->emmc) {
+sd_ocr_powerup(sd);
+return sd->state == sd_idle_state ?
+   sd_r3 : sd_r0;
+} else if (!sd->spi) {
 goto bad_cmd;
+}
 
 sd->state = sd_transfer_state;
 return sd_r1;
-- 
2.7.4




[PATCH v3 07/21] sd: sdmmc-internal: Add command string for SEND_OP_CMD

2021-02-28 Thread Sai Pavan Boddu
From: Cédric Le Goater 

This adds extra info to trace log.

Signed-off-by: Sai Pavan Boddu 
---
 hw/sd/sdmmc-internal.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/sd/sdmmc-internal.c b/hw/sd/sdmmc-internal.c
index 2053def..8648a78 100644
--- a/hw/sd/sdmmc-internal.c
+++ b/hw/sd/sdmmc-internal.c
@@ -14,7 +14,7 @@
 const char *sd_cmd_name(uint8_t cmd)
 {
 static const char *cmd_abbrev[SDMMC_CMD_MAX] = {
- [0]= "GO_IDLE_STATE",
+ [0]= "GO_IDLE_STATE",   [1]= "SEND_OP_CMD",
  [2]= "ALL_SEND_CID",[3]= "SEND_RELATIVE_ADDR",
  [4]= "SET_DSR", [5]= "IO_SEND_OP_COND",
  [6]= "SWITCH_FUNC", [7]= "SELECT/DESELECT_CARD",
-- 
2.7.4




[PATCH v3 02/21] sd: emmc: Add support for eMMC cards

2021-02-28 Thread Sai Pavan Boddu
Add eMMC device built on top of SD card.

Signed-off-by: Sai Pavan Boddu 
---
 include/hw/sd/sd.h |  2 ++
 hw/sd/sd.c | 20 
 2 files changed, 22 insertions(+)

diff --git a/include/hw/sd/sd.h b/include/hw/sd/sd.h
index 05ef9b7..b402dad 100644
--- a/include/hw/sd/sd.h
+++ b/include/hw/sd/sd.h
@@ -90,6 +90,8 @@ typedef struct {
 } SDRequest;
 
 
+#define TYPE_EMMC "emmc"
+OBJECT_DECLARE_SIMPLE_TYPE(EMMCState, EMMC)
 #define TYPE_SD_CARD "sd-card"
 OBJECT_DECLARE_TYPE(SDState, SDCardClass, SD_CARD)
 
diff --git a/hw/sd/sd.c b/hw/sd/sd.c
index 74b9162..a23af6d 100644
--- a/hw/sd/sd.c
+++ b/hw/sd/sd.c
@@ -108,6 +108,7 @@ struct SDState {
 uint8_t spec_version;
 BlockBackend *blk;
 bool spi;
+bool emmc;
 
 /* Runtime changeables */
 
@@ -143,6 +144,10 @@ struct SDState {
 bool cmd_line;
 };
 
+struct EMMCState {
+SDState parent;
+};
+
 static void sd_realize(DeviceState *dev, Error **errp);
 
 static const char *sd_state_name(enum SDCardStates state)
@@ -2105,6 +2110,13 @@ static void sd_instance_init(Object *obj)
 sd->ocr_power_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, sd_ocr_powerup, sd);
 }
 
+static void emmc_instance_init(Object *obj)
+{
+SDState *sd = SD_CARD(obj);
+
+sd->emmc = true;
+}
+
 static void sd_instance_finalize(Object *obj)
 {
 SDState *sd = SD_CARD(obj);
@@ -2213,9 +2225,17 @@ static const TypeInfo sd_info = {
 .instance_finalize = sd_instance_finalize,
 };
 
+static const TypeInfo emmc_info = {
+.name = TYPE_EMMC,
+.parent = TYPE_SD_CARD,
+.instance_size = sizeof(EMMCState),
+.instance_init = emmc_instance_init,
+};
+
 static void sd_register_types(void)
 {
 type_register_static(_info);
+type_register_static(_info);
 }
 
 type_init(sd_register_types)
-- 
2.7.4




RE: [PATCH v2 01/22] block: add eMMC block device type

2021-02-24 Thread Sai Pavan Boddu
Hi Cedric,


> -Original Message-
> From: Cédric Le Goater 
> Sent: Wednesday, February 24, 2021 7:25 PM
> To: Stefan Hajnoczi ; Sai Pavan Boddu
> 
> Cc: Philippe Mathieu-Daudé ; Markus Armbruster
> ; Kevin Wolf ; Max Reitz
> ; Vladimir Sementsov-Ogievskiy
> ; Eric Blake ; Joel Stanley
> ; Vincent Palatin ; Dr. David Alan
> Gilbert ; Thomas Huth ; Peter
> Maydell ; Alistair Francis
> ; Edgar Iglesias ; Luc Michel
> ; Paolo Bonzini ; qemu-
> de...@nongnu.org; qemu-bl...@nongnu.org
> Subject: Re: [PATCH v2 01/22] block: add eMMC block device type
> 
> On 2/24/21 12:40 PM, Stefan Hajnoczi wrote:
> > On Tue, Feb 23, 2021 at 05:35:20PM +, Sai Pavan Boddu wrote:
> >> Hi Philippe,
> >>
> >>> -Original Message-
> >>> From: Philippe Mathieu-Daudé 
> >>> Sent: Monday, February 22, 2021 5:34 PM
> >>> To: Sai Pavan Boddu ; Markus Armbruster
> >>> ; Kevin Wolf ; Max Reitz
> >>> ; Vladimir Sementsov-Ogievskiy
> >>> ; Eric Blake ; Joel
> >>> Stanley ; Cédric Le Goater ; Vincent
> >>> Palatin ; Dr. David Alan Gilbert
> >>> ; Thomas Huth ; Stefan
> >>> Hajnoczi ; Peter Maydell
> >>> ; Alistair Francis
> >>> ; Edgar Iglesias ; Luc
> >>> Michel ; Paolo Bonzini
> >>> 
> >>> Cc: Sai Pavan Boddu ; qemu-devel@nongnu.org;
> >>> qemu- bl...@nongnu.org
> >>> Subject: Re: [PATCH v2 01/22] block: add eMMC block device type
> >>>
> >>> On 2/22/21 9:20 AM, Sai Pavan Boddu wrote:
> >>>> From: Vincent Palatin 
> >>>>
> >>>> Add new block device type.
> >>>>
> >>>> Signed-off-by: Vincent Palatin 
> >>>> [SPB: Rebased over 5.1 version]
> >>>> Signed-off-by: Sai Pavan Boddu 
> >>>> Signed-off-by: Joel Stanley 
> >>>> Signed-off-by: Cédric Le Goater 
> >>>> Reviewed-by: Alistair Francis 
> >>>> ---
> >>>>  include/sysemu/blockdev.h | 1 +
> >>>>  blockdev.c| 1 +
> >>>>  2 files changed, 2 insertions(+)
> >>>>
> >>>> diff --git a/include/sysemu/blockdev.h b/include/sysemu/blockdev.h
> >>>> index 3b5fcda..eefae9f 100644
> >>>> --- a/include/sysemu/blockdev.h
> >>>> +++ b/include/sysemu/blockdev.h
> >>>> @@ -24,6 +24,7 @@ typedef enum {
> >>>>   */
> >>>>  IF_NONE = 0,
> >>>>  IF_IDE, IF_SCSI, IF_FLOPPY, IF_PFLASH, IF_MTD, IF_SD,
> >>>> IF_VIRTIO, IF_XEN,
> >>>> +IF_EMMC,
> >>>>  IF_COUNT
> >>>>  } BlockInterfaceType;
> >>>>
> >>>> diff --git a/blockdev.c b/blockdev.c index cd438e6..390d43c 100644
> >>>> --- a/blockdev.c
> >>>> +++ b/blockdev.c
> >>>> @@ -83,6 +83,7 @@ static const char *const if_name[IF_COUNT] = {
> >>>>  [IF_SD] = "sd",
> >>>>  [IF_VIRTIO] = "virtio",
> >>>>  [IF_XEN] = "xen",
> >>>> +[IF_EMMC] = "emmc",
> >>>>  };
> >>>
> >>> We don't need to introduce support for the legacy -drive magic.
> >>>
> >>> -device should be enough for this device, right?
> >> [Sai Pavan Boddu] I was seeing to use -device for emmc. But I see we
> anyway need blockdev support for this, which would require us the use -drive.
> >>
> >> Can you give some pointers, how to approach this ?
> >
> > It is probably not necessary to add a new IF_ constant. Would this work:
> >
> >   -drive if=none,id=emmc0,file=test.img,format=raw
> >   -device emmc,...,drive=emmc0
> >
> > Or the more modern:
> >
> >   -blockdev node-name=emmc0,driver=file,filename=test.img
> >   -device emmc,...,drive=emmc0
> >
> > ?
> >
> > (The syntax might need small tweaks but is shows the general idea.)
> 
> Yes. This is better.
> 
> We could have an "emmc" device inheriting from "sd-card". The "emmc"
> property would not be necessary anymore and may be, we could cleanup up
> some parts doing :
> 
> if (sd->emmc) { /* eMMC */
> ...
> } else {
> 
> }
> 
> with SDCardClass handlers. the SWITCH_FUNCTION command is a good
> candidate, CMD8 also.
[Sai Pavan Boddu] Nice, this approach looks clean.
But we still may be depending on emmc property. Not sure!

I would get back with v3, your review on those patches would be great.

Thanks & Regards,
Sai Pavan
> 
> C.



RE: [PATCH v2 01/22] block: add eMMC block device type

2021-02-24 Thread Sai Pavan Boddu
Hi Stefan

> -Original Message-
> From: Stefan Hajnoczi 
> Sent: Wednesday, February 24, 2021 5:10 PM
> To: Sai Pavan Boddu 
> Cc: Philippe Mathieu-Daudé ; Markus Armbruster
> ; Kevin Wolf ; Max Reitz
> ; Vladimir Sementsov-Ogievskiy
> ; Eric Blake ; Joel Stanley
> ; Cédric Le Goater ; Vincent Palatin
> ; Dr. David Alan Gilbert ;
> Thomas Huth ; Peter Maydell
> ; Alistair Francis ; Edgar
> Iglesias ; Luc Michel ; Paolo
> Bonzini ; qemu-devel@nongnu.org; qemu-
> bl...@nongnu.org
> Subject: Re: [PATCH v2 01/22] block: add eMMC block device type
> 
> On Tue, Feb 23, 2021 at 05:35:20PM +, Sai Pavan Boddu wrote:
> > Hi Philippe,
> >
> > > -Original Message-
> > > From: Philippe Mathieu-Daudé 
> > > Sent: Monday, February 22, 2021 5:34 PM
> > > To: Sai Pavan Boddu ; Markus Armbruster
> > > ; Kevin Wolf ; Max Reitz
> > > ; Vladimir Sementsov-Ogievskiy
> > > ; Eric Blake ; Joel
> > > Stanley ; Cédric Le Goater ; Vincent
> > > Palatin ; Dr. David Alan Gilbert
> > > ; Thomas Huth ; Stefan
> > > Hajnoczi ; Peter Maydell
> > > ; Alistair Francis
> > > ; Edgar Iglesias ; Luc
> > > Michel ; Paolo Bonzini
> > > 
> > > Cc: Sai Pavan Boddu ; qemu-devel@nongnu.org;
> > > qemu- bl...@nongnu.org
> > > Subject: Re: [PATCH v2 01/22] block: add eMMC block device type
> > >
> > > On 2/22/21 9:20 AM, Sai Pavan Boddu wrote:
> > > > From: Vincent Palatin 
> > > >
> > > > Add new block device type.
> > > >
> > > > Signed-off-by: Vincent Palatin 
> > > > [SPB: Rebased over 5.1 version]
> > > > Signed-off-by: Sai Pavan Boddu 
> > > > Signed-off-by: Joel Stanley 
> > > > Signed-off-by: Cédric Le Goater 
> > > > Reviewed-by: Alistair Francis 
> > > > ---
> > > >  include/sysemu/blockdev.h | 1 +
> > > >  blockdev.c| 1 +
> > > >  2 files changed, 2 insertions(+)
> > > >
> > > > diff --git a/include/sysemu/blockdev.h b/include/sysemu/blockdev.h
> > > > index 3b5fcda..eefae9f 100644
> > > > --- a/include/sysemu/blockdev.h
> > > > +++ b/include/sysemu/blockdev.h
> > > > @@ -24,6 +24,7 @@ typedef enum {
> > > >   */
> > > >  IF_NONE = 0,
> > > >  IF_IDE, IF_SCSI, IF_FLOPPY, IF_PFLASH, IF_MTD, IF_SD,
> > > > IF_VIRTIO, IF_XEN,
> > > > +IF_EMMC,
> > > >  IF_COUNT
> > > >  } BlockInterfaceType;
> > > >
> > > > diff --git a/blockdev.c b/blockdev.c index cd438e6..390d43c 100644
> > > > --- a/blockdev.c
> > > > +++ b/blockdev.c
> > > > @@ -83,6 +83,7 @@ static const char *const if_name[IF_COUNT] = {
> > > >  [IF_SD] = "sd",
> > > >  [IF_VIRTIO] = "virtio",
> > > >  [IF_XEN] = "xen",
> > > > +[IF_EMMC] = "emmc",
> > > >  };
> > >
> > > We don't need to introduce support for the legacy -drive magic.
> > >
> > > -device should be enough for this device, right?
> > [Sai Pavan Boddu] I was seeing to use -device for emmc. But I see we anyway
> need blockdev support for this, which would require us the use -drive.
> >
> > Can you give some pointers, how to approach this ?
> 
> It is probably not necessary to add a new IF_ constant. Would this work:
> 
>   -drive if=none,id=emmc0,file=test.img,format=raw
>   -device emmc,...,drive=emmc0
[Sai Pavan Boddu] Great, this works for me.
> 
> Or the more modern:
> 
>   -blockdev node-name=emmc0,driver=file,filename=test.img
>   -device emmc,...,drive=emmc0
[Sai Pavan Boddu] Thanks, I would try to follow the modern approach then!

Regards,
Sai Pavan
> 
> ?
> 
> (The syntax might need small tweaks but is shows the general idea.)
> 
> Stefan



RE: [PATCH v2 01/22] block: add eMMC block device type

2021-02-23 Thread Sai Pavan Boddu
Hi Philippe,

> -Original Message-
> From: Philippe Mathieu-Daudé 
> Sent: Monday, February 22, 2021 5:34 PM
> To: Sai Pavan Boddu ; Markus Armbruster
> ; Kevin Wolf ; Max Reitz
> ; Vladimir Sementsov-Ogievskiy
> ; Eric Blake ; Joel Stanley
> ; Cédric Le Goater ; Vincent Palatin
> ; Dr. David Alan Gilbert ;
> Thomas Huth ; Stefan Hajnoczi ;
> Peter Maydell ; Alistair Francis
> ; Edgar Iglesias ; Luc Michel
> ; Paolo Bonzini 
> Cc: Sai Pavan Boddu ; qemu-devel@nongnu.org; qemu-
> bl...@nongnu.org
> Subject: Re: [PATCH v2 01/22] block: add eMMC block device type
> 
> On 2/22/21 9:20 AM, Sai Pavan Boddu wrote:
> > From: Vincent Palatin 
> >
> > Add new block device type.
> >
> > Signed-off-by: Vincent Palatin 
> > [SPB: Rebased over 5.1 version]
> > Signed-off-by: Sai Pavan Boddu 
> > Signed-off-by: Joel Stanley 
> > Signed-off-by: Cédric Le Goater 
> > Reviewed-by: Alistair Francis 
> > ---
> >  include/sysemu/blockdev.h | 1 +
> >  blockdev.c| 1 +
> >  2 files changed, 2 insertions(+)
> >
> > diff --git a/include/sysemu/blockdev.h b/include/sysemu/blockdev.h
> > index 3b5fcda..eefae9f 100644
> > --- a/include/sysemu/blockdev.h
> > +++ b/include/sysemu/blockdev.h
> > @@ -24,6 +24,7 @@ typedef enum {
> >   */
> >  IF_NONE = 0,
> >  IF_IDE, IF_SCSI, IF_FLOPPY, IF_PFLASH, IF_MTD, IF_SD, IF_VIRTIO,
> > IF_XEN,
> > +IF_EMMC,
> >  IF_COUNT
> >  } BlockInterfaceType;
> >
> > diff --git a/blockdev.c b/blockdev.c
> > index cd438e6..390d43c 100644
> > --- a/blockdev.c
> > +++ b/blockdev.c
> > @@ -83,6 +83,7 @@ static const char *const if_name[IF_COUNT] = {
> >  [IF_SD] = "sd",
> >  [IF_VIRTIO] = "virtio",
> >  [IF_XEN] = "xen",
> > +[IF_EMMC] = "emmc",
> >  };
> 
> We don't need to introduce support for the legacy -drive magic.
> 
> -device should be enough for this device, right?
[Sai Pavan Boddu] I was seeing to use -device for emmc. But I see we anyway 
need blockdev support for this, which would require us the use -drive.

Can you give some pointers, how to approach this ?

Regards,
Sai Pavan



RE: [PATCH v2 01/22] block: add eMMC block device type

2021-02-22 Thread Sai Pavan Boddu
Hi Philippe,

> -Original Message-
> From: Philippe Mathieu-Daudé 
> Sent: Monday, February 22, 2021 6:54 PM
> To: Dr. David Alan Gilbert ; Markus Armbruster
> 
> Cc: Sai Pavan Boddu ; Kevin Wolf ;
> Max Reitz ; Vladimir Sementsov-Ogievskiy
> ; Eric Blake ; Joel Stanley
> ; Cédric Le Goater ; Vincent Palatin
> ; Thomas Huth ; Stefan
> Hajnoczi ; Peter Maydell ;
> Alistair Francis ; Edgar Iglesias 
> ;
> Luc Michel ; Paolo Bonzini
> ; Sai Pavan Boddu ; qemu-
> de...@nongnu.org; qemu-bl...@nongnu.org
> Subject: Re: [PATCH v2 01/22] block: add eMMC block device type
> 
> On 2/22/21 2:16 PM, Dr. David Alan Gilbert wrote:
> > * Markus Armbruster (arm...@redhat.com) wrote:
> >> Philippe Mathieu-Daudé  writes:
> >>
> >>> On 2/22/21 9:20 AM, Sai Pavan Boddu wrote:
> >>>> From: Vincent Palatin 
> >>>>
> >>>> Add new block device type.
> >>>>
> >>>> Signed-off-by: Vincent Palatin 
> >>>> [SPB: Rebased over 5.1 version]
> >>>> Signed-off-by: Sai Pavan Boddu 
> >>>> Signed-off-by: Joel Stanley 
> >>>> Signed-off-by: Cédric Le Goater 
> >>>> Reviewed-by: Alistair Francis 
> >>>> ---
> >>>>  include/sysemu/blockdev.h | 1 +
> >>>>  blockdev.c| 1 +
> >>>>  2 files changed, 2 insertions(+)
> >>>>
> >>>> diff --git a/include/sysemu/blockdev.h b/include/sysemu/blockdev.h
> >>>> index 3b5fcda..eefae9f 100644
> >>>> --- a/include/sysemu/blockdev.h
> >>>> +++ b/include/sysemu/blockdev.h
> >>>> @@ -24,6 +24,7 @@ typedef enum {
> >>>>   */
> >>>>  IF_NONE = 0,
> >>>>  IF_IDE, IF_SCSI, IF_FLOPPY, IF_PFLASH, IF_MTD, IF_SD,
> >>>> IF_VIRTIO, IF_XEN,
> >>>> +IF_EMMC,
> >>>>  IF_COUNT
> >>>>  } BlockInterfaceType;
> >>>>
> >>>> diff --git a/blockdev.c b/blockdev.c index cd438e6..390d43c 100644
> >>>> --- a/blockdev.c
> >>>> +++ b/blockdev.c
> >>>> @@ -83,6 +83,7 @@ static const char *const if_name[IF_COUNT] = {
> >>>>  [IF_SD] = "sd",
> >>>>  [IF_VIRTIO] = "virtio",
> >>>>  [IF_XEN] = "xen",
> >>>> +[IF_EMMC] = "emmc",
> >>>>  };
> >>>
> >>> We don't need to introduce support for the legacy -drive magic.
> >>>
> >>> -device should be enough for this device, right?
> >>
> >> External interface extensions need rationale: why do we want / need it?
> >> The commit message neglects to provide one.
> >>
> >> Even more so when the interface in question is in a state like -drive
> >> is.
> >
> > I wouldn't be too nasty about -drive;  for me I still find it the
> > easiest way to start a VM.
> 
> But eMMC isn't a bus where you can plug drives, it is soldered on-board and is
> mmio mapped to a fixed address. I don't see the point of having a drive
> interface for it...
[Sai Pavan Boddu] Yeah, this makes sense but having a drive would be a simple 
implementation without disturbing much in the sd card emulation code. And its 
just easy to use, just as how sd cards are inserted.

I need to see, how easy it would be with -device.

Thanks,
Sai Pavan



RE: [PATCH v2 04/22] sd: emmc: update OCR fields for eMMC

2021-02-22 Thread Sai Pavan Boddu
Hi Cedric

> -Original Message-
> From: Cédric Le Goater 
> Sent: Monday, February 22, 2021 3:22 PM
> To: Sai Pavan Boddu ; Markus Armbruster
> ; Kevin Wolf ; Max Reitz
> ; Vladimir Sementsov-Ogievskiy
> ; Eric Blake ; Joel Stanley
> ; Vincent Palatin ; Dr. David Alan
> Gilbert ; Thomas Huth ; Stefan
> Hajnoczi ; Peter Maydell ;
> Alistair Francis ; Edgar Iglesias 
> ;
> Luc Michel ; Paolo Bonzini
> 
> Cc: qemu-bl...@nongnu.org; qemu-devel@nongnu.org; Sai Pavan Boddu
> 
> Subject: Re: [PATCH v2 04/22] sd: emmc: update OCR fields for eMMC
> 
> On 2/22/21 9:20 AM, Sai Pavan Boddu wrote:
> > From: Vincent Palatin 
> >
> > eMMC OCR register doesn't has UHS-II field and voltage fields are
> > different.
> 
> Can a patch be "From" a person without a "Signed-off-by" of the same person ?
[Sai Pavan Boddu] No I should not be like this. My mistake, I would respin the 
series with corrections. Few other patches may have this after the split I did.

Regards,
Sai Pavan
> 
> C.
> 
> > Signed-off-by: Sai Pavan Boddu 
> >
> > ---
> >  hw/sd/sd.c | 27 ---
> >  1 file changed, 24 insertions(+), 3 deletions(-)
> >
> > diff --git a/hw/sd/sd.c b/hw/sd/sd.c
> > index 42ee49c..430bea5 100644
> > --- a/hw/sd/sd.c
> > +++ b/hw/sd/sd.c
> > @@ -283,6 +283,15 @@ FIELD(OCR, UHS_II_CARD,29,  1) /* Only
> UHS-II */
> >  FIELD(OCR, CARD_CAPACITY,  30,  1) /* 0:SDSC, 1:SDHC/SDXC */
> >  FIELD(OCR, CARD_POWER_UP,  31,  1)
> >
> > +/*
> > + * eMMC OCR register
> > + */
> > +FIELD(EMMC_OCR, VDD_WINDOW_0,  7, 1)
> > +FIELD(EMMC_OCR, VDD_WINDOW_1,  8, 7)
> > +FIELD(EMMC_OCR, VDD_WINDOW_2, 15, 9)
> > +FIELD(EMMC_OCR, ACCESS_MODE,  29, 2)
> > +FIELD(EMMC_OCR, POWER_UP, 31, 1)
> > +
> >  #define ACMD41_ENQUIRY_MASK 0x00ff
> >  #define ACMD41_R3_MASK  (R_OCR_VDD_VOLTAGE_WIN_HI_MASK \
> > | R_OCR_ACCEPT_SWITCH_1V8_MASK \
> > @@ -292,8 +301,16 @@ FIELD(OCR, CARD_POWER_UP,  31,  1)
> >
> >  static void sd_set_ocr(SDState *sd)
> >  {
> > -/* All voltages OK */
> > -sd->ocr = R_OCR_VDD_VOLTAGE_WIN_HI_MASK;
> > +if (sd->emmc) {
> > +/*
> > + * Dual Voltage eMMC card
> > + */
> > +sd->ocr = R_EMMC_OCR_VDD_WINDOW_0_MASK |
> > +  R_EMMC_OCR_VDD_WINDOW_2_MASK;
> > +} else {
> > +/* All voltages OK */
> > +sd->ocr = R_OCR_VDD_VOLTAGE_WIN_HI_MASK;
> > +}
> >  }
> >
> >  static void sd_ocr_powerup(void *opaque) @@ -521,7 +538,11 @@ static
> > void sd_response_r1_make(SDState *sd, uint8_t *response)
> >
> >  static void sd_response_r3_make(SDState *sd, uint8_t *response)  {
> > -stl_be_p(response, sd->ocr & ACMD41_R3_MASK);
> > +if (sd->emmc) {
> > +stl_be_p(response, sd->ocr);
> > +} else {
> > +stl_be_p(response, sd->ocr & ACMD41_R3_MASK);
> > +}
> >  }
> >
> >  static void sd_response_r6_make(SDState *sd, uint8_t *response)
> >



[PATCH v2 19/22] sd: sdhci: Support eMMC devices

2021-02-22 Thread Sai Pavan Boddu
Embedded device slots should be allowed as support of eMMC is available.

Signed-off-by: Sai Pavan Boddu 
---
 hw/sd/sdhci.c | 4 
 1 file changed, 4 deletions(-)

diff --git a/hw/sd/sdhci.c b/hw/sd/sdhci.c
index 8ffa539..771212a 100644
--- a/hw/sd/sdhci.c
+++ b/hw/sd/sdhci.c
@@ -99,10 +99,6 @@ static void sdhci_check_capareg(SDHCIState *s, Error **errp)
 msk = FIELD_DP64(msk, SDHC_CAPAB, ASYNC_INT, 0);
 
 val = FIELD_EX64(s->capareg, SDHC_CAPAB, SLOT_TYPE);
-if (val) {
-error_setg(errp, "slot-type not supported");
-return;
-}
 trace_sdhci_capareg("slot type", val);
 msk = FIELD_DP64(msk, SDHC_CAPAB, SLOT_TYPE, 0);
 
-- 
2.7.4




[PATCH v2 14/22] sd: emmc: Add support for emmc erase

2021-02-22 Thread Sai Pavan Boddu
Add CMD35 and CMD36 which sets the erase start and end.

Signed-off-by: Sai Pavan Boddu 
Signed-off-by: Edgar E. Iglesias 
---
 hw/sd/sd.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/hw/sd/sd.c b/hw/sd/sd.c
index df82b61..6d2ef2b 100644
--- a/hw/sd/sd.c
+++ b/hw/sd/sd.c
@@ -1544,6 +1544,7 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, 
SDRequest req)
 
 /* Erase commands (Class 5) */
 case 32:/* CMD32:  ERASE_WR_BLK_START */
+case 35:/* CMD35:  ERASE_GROUP_START */
 switch (sd->state) {
 case sd_transfer_state:
 sd->erase_start = req.arg;
@@ -1555,6 +1556,7 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, 
SDRequest req)
 break;
 
 case 33:/* CMD33:  ERASE_WR_BLK_END */
+case 36:/* CMD36:  ERASE_GROUP_END */
 switch (sd->state) {
 case sd_transfer_state:
 sd->erase_end = req.arg;
-- 
2.7.4




[PATCH v2 06/22] sd: emmc: Update CMD8 to send EXT_CSD register

2021-02-22 Thread Sai Pavan Boddu
From: Vincent Palatin 

Sends the EXT_CSD register as response to CMD8.

Signed-off-by: Sai Pavan Boddu 
---
 hw/sd/sd.c | 52 
 1 file changed, 36 insertions(+), 16 deletions(-)

diff --git a/hw/sd/sd.c b/hw/sd/sd.c
index 4c211ba..a4f93b5 100644
--- a/hw/sd/sd.c
+++ b/hw/sd/sd.c
@@ -1133,24 +1133,37 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, 
SDRequest req)
 }
 break;
 
-case 8: /* CMD8:   SEND_IF_COND */
-if (sd->spec_version < SD_PHY_SPECv2_00_VERS) {
-break;
-}
-if (sd->state != sd_idle_state) {
-break;
-}
-sd->vhs = 0;
-
-/* No response if not exactly one VHS bit is set.  */
-if (!(req.arg >> 8) || (req.arg >> (ctz32(req.arg & ~0xff) + 1))) {
-return sd->spi ? sd_r7 : sd_r0;
-}
+case 8:/* CMD8:   SEND_IF_COND / SEND_EXT_CSD */
+if (sd->emmc) {
+switch (sd->state) {
+case sd_transfer_state:
+/* MMC : Sends the EXT_CSD register as a Block of data */
+sd->state = sd_sendingdata_state;
+memcpy(sd->data, sd->ext_csd, sizeof(sd->ext_csd));
+sd->data_start = addr;
+sd->data_offset = 0;
+return sd_r1;
+default:
+break;
+}
+} else {
+if (sd->spec_version < SD_PHY_SPECv2_00_VERS) {
+break;
+}
+if (sd->state != sd_idle_state) {
+break;
+}
+sd->vhs = 0;
 
-/* Accept.  */
-sd->vhs = req.arg;
-return sd_r7;
+/* No response if not exactly one VHS bit is set.  */
+if (!(req.arg >> 8) || (req.arg >> (ctz32(req.arg & ~0xff) + 1))) {
+return sd->spi ? sd_r7 : sd_r0;
+}
 
+/* Accept.  */
+sd->vhs = req.arg;
+return sd_r7;
+}
 case 9: /* CMD9:   SEND_CSD */
 switch (sd->state) {
 case sd_standby_state:
@@ -2073,6 +2086,13 @@ uint8_t sd_read_byte(SDState *sd)
 sd->state = sd_transfer_state;
 break;
 
+case 8: /* CMD8: SEND_EXT_CSD on MMC */
+ret = sd->data[sd->data_offset++];
+if (sd->data_offset >= sizeof(sd->ext_csd)) {
+sd->state = sd_transfer_state;
+}
+break;
+
 case 9: /* CMD9:   SEND_CSD */
 case 10:/* CMD10:  SEND_CID */
 ret = sd->data[sd->data_offset ++];
-- 
2.7.4




[PATCH v2 08/22] sd: emmc: Dont not update CARD_CAPACITY for eMMC cards

2021-02-22 Thread Sai Pavan Boddu
OCR.CARD_CAPACITY field is only valid for sd cards, So skip it for eMMC.

Signed-off-by: Sai Pavan Boddu 
Signed-off-by: Edgar E. Iglesias 
Reviewed-by: Alistair Francis 
---
 hw/sd/sd.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/hw/sd/sd.c b/hw/sd/sd.c
index a4f93b5..9835f52 100644
--- a/hw/sd/sd.c
+++ b/hw/sd/sd.c
@@ -324,7 +324,8 @@ static void sd_ocr_powerup(void *opaque)
 /* card power-up OK */
 sd->ocr = FIELD_DP32(sd->ocr, OCR, CARD_POWER_UP, 1);
 
-if (sd->size > SDSC_MAX_CAPACITY) {
+/* eMMC supports only Byte mode */
+if (!sd->emmc && sd->size > SDSC_MAX_CAPACITY) {
 sd->ocr = FIELD_DP32(sd->ocr, OCR, CARD_CAPACITY, 1);
 }
 }
-- 
2.7.4




[PATCH v2 21/22] docs: devel: emmc: Add a doc for emmc card emulation

2021-02-22 Thread Sai Pavan Boddu
Add few simple steps to create emmc card with boot and user data
partitions.

Signed-off-by: Sai Pavan Boddu 
---
 docs/devel/emmc.txt | 16 
 1 file changed, 16 insertions(+)
 create mode 100644 docs/devel/emmc.txt

diff --git a/docs/devel/emmc.txt b/docs/devel/emmc.txt
new file mode 100644
index 000..2d098fe
--- /dev/null
+++ b/docs/devel/emmc.txt
@@ -0,0 +1,16 @@
+
+eMMC block emulation
+
+
+Any eMMC devices has 3 kinds of partitions Boot, RPMB and User data. We
+are supporting Boot and User data partitions. Boot area partitions are
+expected to be 1MB size as hard coded in EXT_CSD register.
+
+Below is the example of combining two 1MB bootarea partition and
+user data partitions.
+
+  cat mmc-bootarea0.bin mmc-bootarea1.bin  image.wic > mmc.img
+  qemu-img resize mmc.img 4G
+
+Note: mmc-bootarea0/1 are just raw paritions. User data can have
+partition tables.
-- 
2.7.4




[PATCH v2 10/22] sd: emmc: support idle state in CMD2

2021-02-22 Thread Sai Pavan Boddu
eMMC is expected to be in idle-state post CMD1. Ready state is an
intermediate stage which we don't come across in Device identification
mode.

Signed-off-by: Sai Pavan Boddu 
Signed-off-by: Edgar E. Iglesias 
Reviewed-by: Alistair Francis 
---
 hw/sd/sd.c | 4 
 1 file changed, 4 insertions(+)

diff --git a/hw/sd/sd.c b/hw/sd/sd.c
index 8bc8d5d..ae5c5e8 100644
--- a/hw/sd/sd.c
+++ b/hw/sd/sd.c
@@ -1051,6 +1051,10 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, 
SDRequest req)
 if (sd->spi)
 goto bad_cmd;
 switch (sd->state) {
+case sd_idle_state:
+if (!sd->emmc) {
+break;
+}
 case sd_ready_state:
 sd->state = sd_identification_state;
 return sd_r2_i;
-- 
2.7.4




[PATCH v2 17/22] sd: emmc: Support boot area in emmc image

2021-02-22 Thread Sai Pavan Boddu
From: Joel Stanley 

This assumes a specially constructued image:

  dd if=/dev/zero of=mmc-bootarea.img count=2 bs=1M
  dd if=u-boot-spl.bin of=mmc-bootarea.img conv=notrunc
  dd if=u-boot.bin of=mmc-bootarea.img conv=notrunc count=64 bs=1K
  cat mmc-bootarea.img obmc-phosphor-image.wic > mmc.img
  truncate --size 16GB mmc.img
  truncate --size 128MB mmc-bootarea.img

Signed-off-by: Joel Stanley 
[clg: - changes on the definition names ]
Signed-off-by: Cédric Le Goater 
[spb: use data_start property to access right emmc partition,
  Clean up PARTITION_ENABLE support as incomplete,
  Fix commit message to be generic.]
Signed-off-by: Sai Pavan Boddu 
---
 hw/sd/sd.c | 40 
 1 file changed, 40 insertions(+)

diff --git a/hw/sd/sd.c b/hw/sd/sd.c
index 60799aa..ab29e54 100644
--- a/hw/sd/sd.c
+++ b/hw/sd/sd.c
@@ -1040,6 +1040,34 @@ static void sd_lock_command(SDState *sd)
 sd->card_status &= ~CARD_IS_LOCKED;
 }
 
+/*
+ * This requires a disk image that has two boot partitions inserted at the
+ * beginning of it. The size of the boot partitions are configured in the
+ * ext_csd structure, which is hardcoded in qemu. They are currently set to
+ * 1MB each.
+ */
+static uint32_t sd_bootpart_offset(SDState *sd)
+{
+unsigned int access = sd->ext_csd[EXT_CSD_PART_CONFIG] &
+EXT_CSD_PART_CONFIG_ACC_MASK;
+unsigned int boot_capacity = sd->ext_csd[EXT_CSD_BOOT_MULT] << 17;
+
+if (!sd->emmc) {
+return 0;
+}
+
+switch (access) {
+case EXT_CSD_PART_CONFIG_ACC_DEFAULT:
+return boot_capacity * 2;
+case EXT_CSD_PART_CONFIG_ACC_BOOT0:
+return 0;
+case EXT_CSD_PART_CONFIG_ACC_BOOT0 + 1:
+return boot_capacity * 1;
+default:
+ g_assert_not_reached();
+}
+}
+
 static sd_rsp_type_t sd_normal_command(SDState *sd, SDRequest req)
 {
 uint32_t rca = 0x;
@@ -1355,6 +1383,9 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, 
SDRequest req)
 return sd_r1;
 }
 
+if (sd->emmc) {
+addr += sd_bootpart_offset(sd);
+}
 sd->state = sd_sendingdata_state;
 sd->data_start = addr;
 sd->data_offset = 0;
@@ -1374,6 +1405,9 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, 
SDRequest req)
 return sd_r1;
 }
 
+if (sd->emmc) {
+addr += sd_bootpart_offset(sd);
+}
 sd->state = sd_sendingdata_state;
 sd->data_start = addr;
 sd->data_offset = 0;
@@ -1430,6 +1464,9 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, 
SDRequest req)
 return sd_r1;
 }
 
+if (sd->emmc) {
+addr += sd_bootpart_offset(sd);
+}
 sd->state = sd_receivingdata_state;
 sd->data_start = addr;
 sd->data_offset = 0;
@@ -1460,6 +1497,9 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, 
SDRequest req)
 return sd_r1;
 }
 
+if (sd->emmc) {
+addr += sd_bootpart_offset(sd);
+}
 sd->state = sd_receivingdata_state;
 sd->data_start = addr;
 sd->data_offset = 0;
-- 
2.7.4




[PATCH v2 22/22] docs: arm: xlnx-versal-virt: Add eMMC support documentation

2021-02-22 Thread Sai Pavan Boddu
Add details of eMMC specific machine property.

Signed-off-by: Sai Pavan Boddu 
---
 docs/system/arm/xlnx-versal-virt.rst | 10 ++
 1 file changed, 10 insertions(+)

diff --git a/docs/system/arm/xlnx-versal-virt.rst 
b/docs/system/arm/xlnx-versal-virt.rst
index 2602d0f..a48a88d 100644
--- a/docs/system/arm/xlnx-versal-virt.rst
+++ b/docs/system/arm/xlnx-versal-virt.rst
@@ -29,6 +29,7 @@ Implemented devices:
 - 2 GEMs (Cadence MACB Ethernet MACs)
 - 8 ADMA (Xilinx zDMA) channels
 - 2 SD Controllers
+* SDHCI0 can be configured as eMMC
 - OCM (256KB of On Chip Memory)
 - DDR memory
 
@@ -43,6 +44,15 @@ Other differences between the hardware and the QEMU model:
 - QEMU provides 8 virtio-mmio virtio transports; these start at
   address ``0xa000`` and have IRQs from 111 and upwards.
 
+Enabling eMMC
+"""""""""""""
+In order to enable eMMC pass the following machine property "emmc=on".
+ex:
+"-M xlnx-versal-virt,emmc=on"
+
+Above switch would configure SDHCI0 to accept eMMC card. More details on eMMC
+emulation can be found in docs/devel/emmc.txt.
+
 Running
 """""""
 If the user provides an Operating System to be loaded, we expect users
-- 
2.7.4




[PATCH v2 16/22] sd: emmc: Add Extended CSD register definitions

2021-02-22 Thread Sai Pavan Boddu
From: Cédric Le Goater 

Add user friendly macros for EXT_CSD register.

Signed-off-by: Cédric Le Goater 
[spb: Rebased over versal emmc series,
  updated commit message]
Signed-off-by: Sai Pavan Boddu 
---
 hw/sd/sdmmc-internal.h | 97 ++
 hw/sd/sd.c | 54 +++-
 2 files changed, 126 insertions(+), 25 deletions(-)

diff --git a/hw/sd/sdmmc-internal.h b/hw/sd/sdmmc-internal.h
index d8bf17d..7ab7b4d 100644
--- a/hw/sd/sdmmc-internal.h
+++ b/hw/sd/sdmmc-internal.h
@@ -37,4 +37,101 @@ const char *sd_cmd_name(uint8_t cmd);
  */
 const char *sd_acmd_name(uint8_t cmd);
 
+/*
+ * EXT_CSD fields
+ */
+
+#define EXT_CSD_CMDQ_MODE_EN15  /* R/W */
+#define EXT_CSD_FLUSH_CACHE   32  /* W */
+#define EXT_CSD_CACHE_CTRL33  /* R/W */
+#define EXT_CSD_POWER_OFF_NOTIFICATION  34  /* R/W */
+#define EXT_CSD_PACKED_FAILURE_INDEX  35  /* RO */
+#define EXT_CSD_PACKED_CMD_STATUS 36  /* RO */
+#define EXT_CSD_EXP_EVENTS_STATUS 54  /* RO, 2 bytes */
+#define EXT_CSD_EXP_EVENTS_CTRL   56  /* R/W, 2 bytes */
+#define EXT_CSD_DATA_SECTOR_SIZE  61  /* R */
+#define EXT_CSD_GP_SIZE_MULT143 /* R/W */
+#define EXT_CSD_PARTITION_SETTING_COMPLETED 155 /* R/W */
+#define EXT_CSD_PARTITION_ATTRIBUTE 156 /* R/W */
+#define EXT_CSD_PARTITION_SUPPORT 160 /* RO */
+#define EXT_CSD_HPI_MGMT161 /* R/W */
+#define EXT_CSD_RST_N_FUNCTION162 /* R/W */
+#define EXT_CSD_BKOPS_EN163 /* R/W */
+#define EXT_CSD_BKOPS_START   164 /* W */
+#define EXT_CSD_SANITIZE_START165 /* W */
+#define EXT_CSD_WR_REL_PARAM166 /* RO */
+#define EXT_CSD_RPMB_MULT   168 /* RO */
+#define EXT_CSD_FW_CONFIG   169 /* R/W */
+#define EXT_CSD_BOOT_WP 173 /* R/W */
+#define EXT_CSD_ERASE_GROUP_DEF   175 /* R/W */
+#define EXT_CSD_PART_CONFIG   179 /* R/W */
+#define EXT_CSD_ERASED_MEM_CONT   181 /* RO */
+#define EXT_CSD_BUS_WIDTH   183 /* R/W */
+#define EXT_CSD_STROBE_SUPPORT184 /* RO */
+#define EXT_CSD_HS_TIMING   185 /* R/W */
+#define EXT_CSD_POWER_CLASS   187 /* R/W */
+#define EXT_CSD_REV 192 /* RO */
+#define EXT_CSD_STRUCTURE   194 /* RO */
+#define EXT_CSD_CARD_TYPE   196 /* RO */
+#define EXT_CSD_DRIVER_STRENGTH   197 /* RO */
+#define EXT_CSD_OUT_OF_INTERRUPT_TIME 198 /* RO */
+#define EXT_CSD_PART_SWITCH_TIME199 /* RO */
+#define EXT_CSD_PWR_CL_52_195   200 /* RO */
+#define EXT_CSD_PWR_CL_26_195   201 /* RO */
+#define EXT_CSD_PWR_CL_52_360   202 /* RO */
+#define EXT_CSD_PWR_CL_26_360   203 /* RO */
+#define EXT_CSD_SEC_CNT 212 /* RO, 4 bytes */
+#define EXT_CSD_S_A_TIMEOUT   217 /* RO */
+#define EXT_CSD_S_C_VCCQ  219 /* RO */
+#define EXT_CSD_S_C_VCC 220 /* RO */
+#define EXT_CSD_REL_WR_SEC_C222 /* RO */
+#define EXT_CSD_HC_WP_GRP_SIZE221 /* RO */
+#define EXT_CSD_ERASE_TIMEOUT_MULT  223 /* RO */
+#define EXT_CSD_HC_ERASE_GRP_SIZE 224 /* RO */
+#define EXT_CSD_ACC_SIZE225 /* RO */
+#define EXT_CSD_BOOT_MULT   226 /* RO */
+#define EXT_CSD_BOOT_INFO   228 /* RO */
+#define EXT_CSD_SEC_TRIM_MULT   229 /* RO */
+#define EXT_CSD_SEC_ERASE_MULT230 /* RO */
+#define EXT_CSD_SEC_FEATURE_SUPPORT 231 /* RO */
+#define EXT_CSD_TRIM_MULT   232 /* RO */
+#define EXT_CSD_PWR_CL_200_195236 /* RO */
+#define EXT_CSD_PWR_CL_200_360237 /* RO */
+#define EXT_CSD_PWR_CL_DDR_52_195 238 /* RO */
+#define EXT_CSD_PWR_CL_DDR_52_360 239 /* RO */
+#define EXT_CSD_BKOPS_STATUS246 /* RO */
+#define EXT_CSD_POWER_OFF_LONG_TIME 247 /* RO */
+#define EXT_CSD_GENERIC_CMD6_TIME 248 /* RO */
+#define EXT_CSD_CACHE_SIZE249 /* RO, 4 bytes */
+#define EXT_CSD_PWR_CL_DDR_200_360  253 /* RO */
+#define EXT_CSD_FIRMWARE_VERSION  254 /* RO, 8 bytes */
+#define EXT_CSD_PRE_EOL_INFO267 /* RO */
+#define EXT_CSD_DEVICE_LIFE_TIME_EST_TYP_A  268 /* RO */
+#define EXT_CSD_DEVICE_LIFE_TIME_EST_TYP_B  269 /* RO */
+#define EXT_CSD_CMDQ_DEPTH307 /* RO */
+#define EXT_CSD_CMDQ_SUPPORT308 /* RO */
+#define EXT_CSD_SUPPORTED_MODE493 /* RO */
+#define EXT_CSD_TAG_UNIT_SIZE   498 /* RO */
+#define EXT_CSD_DATA_TAG_SUPPORT  499 /* RO */
+#define EXT_CSD_MAX_PACKED_WRITES 500 /* RO */
+#define EXT_CSD_MAX_PACKED_READS  501 /* RO */
+#define EXT_CSD_BKOPS_SUPPORT   502 /* RO */
+#define EXT_CSD_HPI_FEATURES503 /* RO */
+#define EXT_CSD_S_CMD_SET   504 /* RO */
+
+/*
+ * EXT_CSD field definitions
+ */
+
+#define EXT_CSD_WR_REL_PARAM_EN   (1 << 2)
+#define EXT_CSD_WR_REL_PARAM_EN_RPMB_REL_WR (1 << 4)
+
+#define EXT_CSD_PART_CONFIG_ACC_MASK  (0x7)
+#define EXT_CSD_PART_CONFIG_ACC_DEFAULT (0x0)
+#define EXT_CSD_PART_CONFIG_ACC_BOOT0 (0x1)
+
+#define EXT_CSD_PART_CONFIG_EN_MASK (0x7 << 3)
+#define EXT_CSD_PART_CONFIG_EN_BOOT0  (0x1 << 3)
+#define EXT_CSD_PART_CONFIG_EN_USER (0x7 << 3)
+
 #endif
diff --git a/hw/sd/sd.c b/hw/sd/sd.c
index 3c24810..60799aa 100644
--- a/hw/sd/sd.c
+++ b/hw/sd/sd.c
@@ -409,41 +409,45 @@ static void mmc_set_ext_

[PATCH v2 05/22] sd: emmc: Add support for EXT_CSD & CSD for eMMC

2021-02-22 Thread Sai Pavan Boddu
From: Vincent Palatin 

eMMC CSD is similar to SD with an option to refer EXT_CSD for larger
devices.

Signed-off-by: Sai Pavan Boddu 
---
 hw/sd/sd.c | 57 +++--
 1 file changed, 55 insertions(+), 2 deletions(-)

diff --git a/hw/sd/sd.c b/hw/sd/sd.c
index 430bea5..4c211ba 100644
--- a/hw/sd/sd.c
+++ b/hw/sd/sd.c
@@ -135,6 +135,7 @@ struct SDState {
 uint64_t data_start;
 uint32_t data_offset;
 uint8_t data[512];
+uint8_t ext_csd[512];
 qemu_irq readonly_cb;
 qemu_irq inserted_cb;
 QEMUTimer *ocr_power_timer;
@@ -389,6 +390,51 @@ static const uint8_t sd_csd_rw_mask[16] = {
 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xfe,
 };
 
+static void mmc_set_ext_csd(SDState *sd, uint64_t size)
+{
+uint32_t sectcount = size >> HWBLOCK_SHIFT;
+
+memset(sd->ext_csd, 0, sizeof(sd->ext_csd));
+sd->ext_csd[504] = 0x1; /* supported command sets */
+sd->ext_csd[503] = 0x1; /* HPI features  */
+sd->ext_csd[502] = 0x1; /* Background operations support */
+sd->ext_csd[241] = 0xA; /* 1st initialization time after partitioning */
+sd->ext_csd[232] = 0x1; /* Trim multiplier */
+sd->ext_csd[231] = 0x15; /* Secure feature support */
+sd->ext_csd[230] = 0x96; /* Secure erase support */
+sd->ext_csd[229] = 0x96; /* Secure TRIM multiplier */
+sd->ext_csd[228] = 0x7; /* Boot information */
+sd->ext_csd[226] = 0x8; /* Boot partition size */
+sd->ext_csd[225] = 0x6; /* Access size */
+sd->ext_csd[224] = 0x4; /* HC Erase unit size */
+sd->ext_csd[223] = 0x1; /* HC erase timeout */
+sd->ext_csd[222] = 0x1; /* Reliable write sector count */
+sd->ext_csd[221] = 0x4; /* HC write protect group size */
+sd->ext_csd[220] = 0x8; /* Sleep current VCC  */
+sd->ext_csd[219] = 0x7; /* Sleep current VCCQ */
+sd->ext_csd[217] = 0x11; /* Sleep/Awake timeout */
+sd->ext_csd[215] = (sectcount >> 24) & 0xff; /* Sector count */
+sd->ext_csd[214] = (sectcount >> 16) & 0xff; /* ... */
+sd->ext_csd[213] = (sectcount >> 8) & 0xff;  /* ... */
+sd->ext_csd[212] = (sectcount & 0xff);   /* ... */
+sd->ext_csd[210] = 0xa; /* Min write perf for 8bit@52Mhz */
+sd->ext_csd[209] = 0xa; /* Min read perf for 8bit@52Mhz  */
+sd->ext_csd[208] = 0xa; /* Min write perf for 4bit@52Mhz */
+sd->ext_csd[207] = 0xa; /* Min read perf for 4bit@52Mhz */
+sd->ext_csd[206] = 0xa; /* Min write perf for 4bit@26Mhz */
+sd->ext_csd[205] = 0xa; /* Min read perf for 4bit@26Mhz */
+sd->ext_csd[199] = 0x1; /* Partition switching timing */
+sd->ext_csd[198] = 0x1; /* Out-of-interrupt busy timing */
+sd->ext_csd[196] = 0xFF; /* Card type */
+sd->ext_csd[194] = 0x2; /* CSD Structure version */
+sd->ext_csd[192] = 0x5; /* Extended CSD revision */
+sd->ext_csd[168] = 0x1; /* RPMB size */
+sd->ext_csd[160] = 0x3; /* Partinioning support */
+sd->ext_csd[159] = 0x00; /* Max enhanced area size */
+sd->ext_csd[158] = 0x00; /* ... */
+sd->ext_csd[157] = 0xEC; /* ... */
+}
+
 static void sd_set_csd(SDState *sd, uint64_t size)
 {
 int hwblock_shift = HWBLOCK_SHIFT;
@@ -402,8 +448,11 @@ static void sd_set_csd(SDState *sd, uint64_t size)
 }
 csize = (size >> (CMULT_SHIFT + hwblock_shift)) - 1;
 
-if (size <= SDSC_MAX_CAPACITY) { /* Standard Capacity SD */
-sd->csd[0] = 0x00;  /* CSD structure */
+if (size <= SDSC_MAX_CAPACITY || sd->emmc) { /* Standard Capacity SD */
+if (sd->emmc && size >= SDSC_MAX_CAPACITY) {
+csize = 0xfff;
+}
+sd->csd[0] = sd->emmc ? 0xd0 : 0x00;  /* CSD structure */
 sd->csd[1] = 0x26;  /* Data read access-time-1 */
 sd->csd[2] = 0x00;  /* Data read access-time-2 */
 sd->csd[3] = 0x32;  /* Max. data transfer rate: 25 MHz */
@@ -447,6 +496,10 @@ static void sd_set_csd(SDState *sd, uint64_t size)
 sd->csd[14] = 0x00;
 }
 sd->csd[15] = (sd_crc7(sd->csd, 15) << 1) | 1;
+
+if (sd->emmc) {
+mmc_set_ext_csd(sd, size);
+}
 }
 
 static void sd_set_rca(SDState *sd, uint16_t value)
-- 
2.7.4




[PATCH v2 11/22] sd: emmc: Add mmc switch function support

2021-02-22 Thread Sai Pavan Boddu
switch operation in eMMC card updates the ext_csd register to
request changes in card operations. Here we implement similar
sequence but requests are mostly dummy and make no change.

Implement SWITCH_ERROR if the write operation extends goes beyond length
of ext_csd.

Signed-off-by: Sai Pavan Boddu 
Signed-off-by: Edgar E. Iglesias 
---
 hw/sd/sd.c | 56 ++--
 1 file changed, 50 insertions(+), 6 deletions(-)

diff --git a/hw/sd/sd.c b/hw/sd/sd.c
index ae5c5e8..e50d40b 100644
--- a/hw/sd/sd.c
+++ b/hw/sd/sd.c
@@ -515,6 +515,7 @@ static void sd_set_rca(SDState *sd, uint16_t value)
 FIELD(CSR, AKE_SEQ_ERROR,   3,  1)
 FIELD(CSR, APP_CMD, 5,  1)
 FIELD(CSR, FX_EVENT,6,  1)
+FIELD(CSR, SWITCH_ERROR,7,  1)
 FIELD(CSR, READY_FOR_DATA,  8,  1)
 FIELD(CSR, CURRENT_STATE,   9,  4)
 FIELD(CSR, ERASE_RESET,13,  1)
@@ -878,6 +879,43 @@ static uint32_t sd_wpbits(SDState *sd, uint64_t addr)
 return ret;
 }
 
+enum {
+MMC_CMD6_ACCESS_COMMAND_SET = 0,
+MMC_CMD6_ACCESS_SET_BITS,
+MMC_CMD6_ACCESS_CLEAR_BITS,
+MMC_CMD6_ACCESS_WRITE_BYTE,
+};
+
+static void mmc_function_switch(SDState *sd, uint32_t arg)
+{
+uint32_t access = extract32(arg, 24, 2);
+uint32_t index = extract32(arg, 16, 8);
+uint32_t value = extract32(arg, 8, 8);
+uint8_t b = sd->ext_csd[index];
+
+switch (access) {
+case MMC_CMD6_ACCESS_COMMAND_SET:
+qemu_log_mask(LOG_UNIMP, "MMC Command set switching not supported\n");
+return;
+case MMC_CMD6_ACCESS_SET_BITS:
+b |= value;
+break;
+case MMC_CMD6_ACCESS_CLEAR_BITS:
+b &= ~value;
+break;
+case MMC_CMD6_ACCESS_WRITE_BYTE:
+b = value;
+break;
+}
+
+if (index >= 192) {
+sd->card_status |= R_CSR_SWITCH_ERROR_MASK;
+return;
+}
+
+sd->ext_csd[index] = b;
+}
+
 static void sd_function_switch(SDState *sd, uint32_t arg)
 {
 int i, mode, new_func;
@@ -1097,12 +1135,18 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, 
SDRequest req)
 case 6: /* CMD6:   SWITCH_FUNCTION */
 switch (sd->mode) {
 case sd_data_transfer_mode:
-sd_function_switch(sd, req.arg);
-sd->state = sd_sendingdata_state;
-sd->data_start = 0;
-sd->data_offset = 0;
-return sd_r1;
-
+if (sd->emmc) {
+sd->state = sd_programming_state;
+mmc_function_switch(sd, req.arg);
+sd->state = sd_transfer_state;
+return sd_r1b;
+} else {
+sd_function_switch(sd, req.arg);
+sd->state = sd_sendingdata_state;
+sd->data_start = 0;
+sd->data_offset = 0;
+return sd_r1;
+}
 default:
 break;
 }
-- 
2.7.4




[PATCH v2 07/22] sd: sdmmc-internal: Add command string for SEND_OP_CMD

2021-02-22 Thread Sai Pavan Boddu
From: Cédric Le Goater 

This adds extra info to trace log.

Signed-off-by: Sai Pavan Boddu 
---
 hw/sd/sdmmc-internal.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/sd/sdmmc-internal.c b/hw/sd/sdmmc-internal.c
index 2053def..8648a78 100644
--- a/hw/sd/sdmmc-internal.c
+++ b/hw/sd/sdmmc-internal.c
@@ -14,7 +14,7 @@
 const char *sd_cmd_name(uint8_t cmd)
 {
 static const char *cmd_abbrev[SDMMC_CMD_MAX] = {
- [0]= "GO_IDLE_STATE",
+ [0]= "GO_IDLE_STATE",   [1]= "SEND_OP_CMD",
  [2]= "ALL_SEND_CID",[3]= "SEND_RELATIVE_ADDR",
  [4]= "SET_DSR", [5]= "IO_SEND_OP_COND",
  [6]= "SWITCH_FUNC", [7]= "SELECT/DESELECT_CARD",
-- 
2.7.4




[PATCH v2 01/22] block: add eMMC block device type

2021-02-22 Thread Sai Pavan Boddu
From: Vincent Palatin 

Add new block device type.

Signed-off-by: Vincent Palatin 
[SPB: Rebased over 5.1 version]
Signed-off-by: Sai Pavan Boddu 
Signed-off-by: Joel Stanley 
Signed-off-by: Cédric Le Goater 
Reviewed-by: Alistair Francis 
---
 include/sysemu/blockdev.h | 1 +
 blockdev.c| 1 +
 2 files changed, 2 insertions(+)

diff --git a/include/sysemu/blockdev.h b/include/sysemu/blockdev.h
index 3b5fcda..eefae9f 100644
--- a/include/sysemu/blockdev.h
+++ b/include/sysemu/blockdev.h
@@ -24,6 +24,7 @@ typedef enum {
  */
 IF_NONE = 0,
 IF_IDE, IF_SCSI, IF_FLOPPY, IF_PFLASH, IF_MTD, IF_SD, IF_VIRTIO, IF_XEN,
+IF_EMMC,
 IF_COUNT
 } BlockInterfaceType;
 
diff --git a/blockdev.c b/blockdev.c
index cd438e6..390d43c 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -83,6 +83,7 @@ static const char *const if_name[IF_COUNT] = {
 [IF_SD] = "sd",
 [IF_VIRTIO] = "virtio",
 [IF_XEN] = "xen",
+[IF_EMMC] = "emmc",
 };
 
 static int if_max_devs[IF_COUNT] = {
-- 
2.7.4




[PATCH v2 12/22] sd: emmc: add CMD21 tuning sequence

2021-02-22 Thread Sai Pavan Boddu
eMMC cards support tuning sequence for entering HS200 mode.

Signed-off-by: Sai Pavan Boddu 
Signed-off-by: Edgar E. Iglesias 
---
 hw/sd/sd.c | 47 +++
 1 file changed, 47 insertions(+)

diff --git a/hw/sd/sd.c b/hw/sd/sd.c
index e50d40b..d702027 100644
--- a/hw/sd/sd.c
+++ b/hw/sd/sd.c
@@ -1378,6 +1378,14 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, 
SDRequest req)
 }
 break;
 
+case 21:/* CMD21: mmc SEND TUNING_BLOCK */
+if (sd->emmc && (sd->state == sd_transfer_state)) {
+sd->state = sd_sendingdata_state;
+sd->data_offset = 0;
+return sd_r1;
+}
+break;
+
 case 23:/* CMD23: SET_BLOCK_COUNT */
 if (sd->spec_version < SD_PHY_SPECv3_01_VERS) {
 break;
@@ -2112,6 +2120,30 @@ static const uint8_t 
sd_tuning_block_pattern[SD_TUNING_BLOCK_SIZE] = {
 0xbb, 0xff, 0xf7, 0xff, 0xf7, 0x7f, 0x7b, 0xde,
 };
 
+#define EXCSD_BUS_WIDTH_OFFSET 183
+#define BUS_WIDTH_8_MASK0x4
+#define BUS_WIDTH_4_MASK0x2
+#define MMC_TUNING_BLOCK_SIZE   128
+
+static const uint8_t mmc_tunning_block_pattern[128] = {
+   0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00,
+   0xff, 0xff, 0xcc, 0xcc, 0xcc, 0x33, 0xcc, 0xcc,
+   0xcc, 0x33, 0x33, 0xcc, 0xcc, 0xcc, 0xff, 0xff,
+   0xff, 0xee, 0xff, 0xff, 0xff, 0xee, 0xee, 0xff,
+   0xff, 0xff, 0xdd, 0xff, 0xff, 0xff, 0xdd, 0xdd,
+   0xff, 0xff, 0xff, 0xbb, 0xff, 0xff, 0xff, 0xbb,
+   0xbb, 0xff, 0xff, 0xff, 0x77, 0xff, 0xff, 0xff,
+   0x77, 0x77, 0xff, 0x77, 0xbb, 0xdd, 0xee, 0xff,
+   0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00,
+   0x00, 0xff, 0xff, 0xcc, 0xcc, 0xcc, 0x33, 0xcc,
+   0xcc, 0xcc, 0x33, 0x33, 0xcc, 0xcc, 0xcc, 0xff,
+   0xff, 0xff, 0xee, 0xff, 0xff, 0xff, 0xee, 0xee,
+   0xff, 0xff, 0xff, 0xdd, 0xff, 0xff, 0xff, 0xdd,
+   0xdd, 0xff, 0xff, 0xff, 0xbb, 0xff, 0xff, 0xff,
+   0xbb, 0xbb, 0xff, 0xff, 0xff, 0x77, 0xff, 0xff,
+   0xff, 0x77, 0x77, 0xff, 0x77, 0xbb, 0xdd, 0xee,
+};
+
 uint8_t sd_read_byte(SDState *sd)
 {
 /* TODO: Append CRCs */
@@ -2205,6 +2237,21 @@ uint8_t sd_read_byte(SDState *sd)
 ret = sd_tuning_block_pattern[sd->data_offset++];
 break;
 
+case 21:/* CMD21: SEND_TUNNING_BLOCK (MMC) */
+if (sd->data_offset >= MMC_TUNING_BLOCK_SIZE - 1) {
+sd->state = sd_transfer_state;
+}
+if (sd->ext_csd[EXCSD_BUS_WIDTH_OFFSET] & BUS_WIDTH_8_MASK) {
+ret = mmc_tunning_block_pattern[sd->data_offset++];
+} else {
+/* Return LSB Nibbles of two byte from the 8bit tuning block
+ * for 4bit mode
+ */
+ret = mmc_tunning_block_pattern[sd->data_offset++] & 0x0F;
+ret |= (mmc_tunning_block_pattern[sd->data_offset++] & 0x0F) << 4;
+}
+break;
+
 case 22:/* ACMD22: SEND_NUM_WR_BLOCKS */
 ret = sd->data[sd->data_offset ++];
 
-- 
2.7.4




[PATCH v2 13/22] sd: emmc: Make ACMD41 illegal for mmc

2021-02-22 Thread Sai Pavan Boddu
ACMD41 is not applicable for eMMC.

Signed-off-by: Sai Pavan Boddu 
Signed-off-by: Edgar E. Iglesias 
---
 hw/sd/sd.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/hw/sd/sd.c b/hw/sd/sd.c
index d702027..df82b61 100644
--- a/hw/sd/sd.c
+++ b/hw/sd/sd.c
@@ -1729,6 +1729,9 @@ static sd_rsp_type_t sd_app_command(SDState *sd,
 break;
 
 case 41:/* ACMD41: SD_APP_OP_COND */
+if (sd->emmc) {
+break;
+}
 if (sd->spi) {
 /* SEND_OP_CMD */
 sd->state = sd_transfer_state;
-- 
2.7.4




[PATCH v2 15/22] sd: emmc: Update CID structure for eMMC

2021-02-22 Thread Sai Pavan Boddu
CID structure is little different for eMMC, w.r.t to product name and
manufacturing date.

Signed-off-by: Sai Pavan Boddu 
Signed-off-by: Edgar E. Iglesias 
---
 hw/sd/sd.c | 47 ++-
 1 file changed, 30 insertions(+), 17 deletions(-)

diff --git a/hw/sd/sd.c b/hw/sd/sd.c
index 6d2ef2b..3c24810 100644
--- a/hw/sd/sd.c
+++ b/hw/sd/sd.c
@@ -361,23 +361,36 @@ static void sd_set_scr(SDState *sd)
 
 static void sd_set_cid(SDState *sd)
 {
-sd->cid[0] = MID;   /* Fake card manufacturer ID (MID) */
-sd->cid[1] = OID[0];/* OEM/Application ID (OID) */
-sd->cid[2] = OID[1];
-sd->cid[3] = PNM[0];/* Fake product name (PNM) */
-sd->cid[4] = PNM[1];
-sd->cid[5] = PNM[2];
-sd->cid[6] = PNM[3];
-sd->cid[7] = PNM[4];
-sd->cid[8] = PRV;   /* Fake product revision (PRV) */
-sd->cid[9] = 0xde;  /* Fake serial number (PSN) */
-sd->cid[10] = 0xad;
-sd->cid[11] = 0xbe;
-sd->cid[12] = 0xef;
-sd->cid[13] = 0x00 |/* Manufacture date (MDT) */
-((MDT_YR - 2000) / 10);
-sd->cid[14] = ((MDT_YR % 10) << 4) | MDT_MON;
-sd->cid[15] = (sd_crc7(sd->cid, 15) << 1) | 1;
+if (sd->emmc) {
+sd->cid[0] = MID;
+sd->cid[1] = 0x1;   /* CBX */
+sd->cid[2] = OID[0];/* OEM/Application ID (OID) */
+sd->cid[8] = 0x0;
+sd->cid[9] = PRV;/* Fake product revision (PRV) */
+sd->cid[10] = 0xde;  /* Fake serial number (PSN) */
+sd->cid[11] = 0xad;
+sd->cid[12] = 0xbe;
+sd->cid[13] = 0xef;
+sd->cid[14] = ((MDT_YR - 1997) % 0x10); /* MDT */
+} else {
+sd->cid[0] = MID;   /* Fake card manufacturer ID (MID) */
+sd->cid[1] = OID[0];/* OEM/Application ID (OID) */
+sd->cid[2] = OID[1];
+sd->cid[8] = PRV;   /* Fake product revision (PRV) */
+sd->cid[9] = 0xde;  /* Fake serial number (PSN) */
+sd->cid[10] = 0xad;
+sd->cid[11] = 0xbe;
+sd->cid[12] = 0xef;
+sd->cid[13] = 0x00 |/* Manufacture date (MDT) */
+((MDT_YR - 2000) / 10);
+sd->cid[14] = ((MDT_YR % 10) << 4) | MDT_MON;
+   }
+   sd->cid[3] = PNM[0];/* Fake product name (PNM) 48bit */
+   sd->cid[4] = PNM[1];
+   sd->cid[5] = PNM[2];
+   sd->cid[6] = PNM[3];
+   sd->cid[7] = PNM[4];
+   sd->cid[15] = (sd_crc7(sd->cid, 15) << 1) | 1;
 }
 
 #define HWBLOCK_SHIFT   9   /* 512 bytes */
-- 
2.7.4




[PATCH v2 20/22] arm: xlnx-versal: Add emmc to versal

2021-02-22 Thread Sai Pavan Boddu
Configuring SDHCI-0 to act as eMMC controller.

Signed-off-by: Sai Pavan Boddu 
---
 include/hw/arm/xlnx-versal.h |  1 +
 hw/arm/xlnx-versal-virt.c| 30 +-
 hw/arm/xlnx-versal.c | 13 +++--
 3 files changed, 37 insertions(+), 7 deletions(-)

diff --git a/include/hw/arm/xlnx-versal.h b/include/hw/arm/xlnx-versal.h
index 2b76885..440f3b4 100644
--- a/include/hw/arm/xlnx-versal.h
+++ b/include/hw/arm/xlnx-versal.h
@@ -76,6 +76,7 @@ struct Versal {
 struct {
 MemoryRegion *mr_ddr;
 uint32_t psci_conduit;
+bool has_emmc;
 } cfg;
 };
 
diff --git a/hw/arm/xlnx-versal-virt.c b/hw/arm/xlnx-versal-virt.c
index 8482cd6..273e0c7 100644
--- a/hw/arm/xlnx-versal-virt.c
+++ b/hw/arm/xlnx-versal-virt.c
@@ -46,6 +46,7 @@ struct VersalVirt {
 
 struct {
 bool secure;
+bool has_emmc;
 } cfg;
 };
 
@@ -333,6 +334,13 @@ static void fdt_add_sd_nodes(VersalVirt *s)
 qemu_fdt_setprop_sized_cells(s->fdt, name, "reg",
  2, addr, 2, MM_PMC_SD0_SIZE);
 qemu_fdt_setprop(s->fdt, name, "compatible", compat, sizeof(compat));
+/*
+ * eMMC specific properties
+ */
+if (s->cfg.has_emmc && i == 0) {
+qemu_fdt_setprop(s->fdt, name, "non-removable", NULL, 0);
+qemu_fdt_setprop_sized_cells(s->fdt, name, "bus-width", 1, 8);
+}
 g_free(name);
 }
 }
@@ -512,7 +520,7 @@ static void create_virtio_regions(VersalVirt *s)
 }
 }
 
-static void sd_plugin_card(SDHCIState *sd, DriveInfo *di)
+static void sd_plugin_card(SDHCIState *sd, DriveInfo *di, bool emmc)
 {
 BlockBackend *blk = di ? blk_by_legacy_dinfo(di) : NULL;
 DeviceState *card;
@@ -520,15 +528,22 @@ static void sd_plugin_card(SDHCIState *sd, DriveInfo *di)
 card = qdev_new(TYPE_SD_CARD);
 object_property_add_child(OBJECT(sd), "card[*]", OBJECT(card));
 qdev_prop_set_drive_err(card, "drive", blk, _fatal);
+object_property_set_bool(OBJECT(card), "emmc", emmc, _fatal);
 qdev_realize_and_unref(card, qdev_get_child_bus(DEVICE(sd), "sd-bus"),
_fatal);
 }
 
+static void versal_virt_set_emmc(Object *obj, bool value, Error **errp)
+{
+VersalVirt *s = XLNX_VERSAL_VIRT_MACHINE(obj);
+
+s->cfg.has_emmc = value;
+}
+
 static void versal_virt_init(MachineState *machine)
 {
 VersalVirt *s = XLNX_VERSAL_VIRT_MACHINE(machine);
 int psci_conduit = QEMU_PSCI_CONDUIT_DISABLED;
-int i;
 
 /*
  * If the user provides an Operating System to be loaded, we expect them
@@ -560,6 +575,8 @@ static void versal_virt_init(MachineState *machine)
  _abort);
 object_property_set_int(OBJECT(>soc), "psci-conduit", psci_conduit,
 _abort);
+object_property_set_bool(OBJECT(>soc), "has-emmc", s->cfg.has_emmc,
+ _abort);
 sysbus_realize(SYS_BUS_DEVICE(>soc), _fatal);
 
 fdt_create(s);
@@ -581,10 +598,10 @@ static void versal_virt_init(MachineState *machine)
 memory_region_add_subregion_overlap(get_system_memory(),
 0, >soc.fpd.apu.mr, 0);
 
+sd_plugin_card(>soc.pmc.iou.sd[0],
+drive_get_next(s->cfg.has_emmc ? IF_EMMC : IF_SD), s->cfg.has_emmc);
 /* Plugin SD cards.  */
-for (i = 0; i < ARRAY_SIZE(s->soc.pmc.iou.sd); i++) {
-sd_plugin_card(>soc.pmc.iou.sd[i], drive_get_next(IF_SD));
-}
+sd_plugin_card(>soc.pmc.iou.sd[1], drive_get_next(IF_SD), false);
 
 s->binfo.ram_size = machine->ram_size;
 s->binfo.loader_start = 0x0;
@@ -621,6 +638,9 @@ static void versal_virt_machine_class_init(ObjectClass *oc, 
void *data)
 mc->default_cpus = XLNX_VERSAL_NR_ACPUS;
 mc->no_cdrom = true;
 mc->default_ram_id = "ddr";
+object_class_property_add_bool(oc, "emmc",
+NULL, versal_virt_set_emmc);
+
 }
 
 static const TypeInfo versal_virt_machine_init_typeinfo = {
diff --git a/hw/arm/xlnx-versal.c b/hw/arm/xlnx-versal.c
index 628e77e..67ed1af 100644
--- a/hw/arm/xlnx-versal.c
+++ b/hw/arm/xlnx-versal.c
@@ -230,6 +230,9 @@ static void versal_create_admas(Versal *s, qemu_irq *pic)
 }
 
 #define SDHCI_CAPABILITIES  0x280737ec6481 /* Same as on ZynqMP.  */
+#define SDHCI_EMMC_CAPS ((SDHCI_CAPABILITIES & ~(3 << 30)) | \
+ (1 << 30))
+
 static void versal_create_sds(Versal *s, qemu_irq *pic)
 {
 int i;
@@ -244,9 +247,14 @@ static void versal_create_sds(Versal *s, qemu_irq *pic)
 
 object_property_set_uint(OBJECT(dev), "sd-spec-version", 3,
  _fatal);
-object_property_set_uint(OBJECT(dev), "capareg", SDHCI_CAPABILITIES,
+ 

[PATCH v2 09/22] sd: emmc: Update CMD1 definition for eMMC

2021-02-22 Thread Sai Pavan Boddu
Add support to Power up the card and send response r3 in case of eMMC.

Signed-off-by: Sai Pavan Boddu 
Signed-off-by: Edgar E. Iglesias 
Reviewed-by: Alistair Francis 
---
 hw/sd/sd.c | 10 +-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/hw/sd/sd.c b/hw/sd/sd.c
index 9835f52..8bc8d5d 100644
--- a/hw/sd/sd.c
+++ b/hw/sd/sd.c
@@ -1033,8 +1033,16 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, 
SDRequest req)
 break;
 
 case 1: /* CMD1:   SEND_OP_CMD */
-if (!sd->spi)
+/* MMC: Powerup & send r3
+ * SD: send r1 in spi mode
+ */
+if (sd->emmc) {
+sd_ocr_powerup(sd);
+return sd->state == sd_idle_state ?
+   sd_r3 : sd_r0;
+} else if (!sd->spi) {
 goto bad_cmd;
+}
 
 sd->state = sd_transfer_state;
 return sd_r1;
-- 
2.7.4




[PATCH v2 03/22] sd: emmc: Add support for eMMC cards

2021-02-22 Thread Sai Pavan Boddu
From: Vincent Palatin 

This patch adds support for eMMC cards, change SET_RELATIVE_ADDR
command to assign relative address as requested by user.

Signed-off-by: Vincent Palatin 
Signed-off-by: Joel Stanley 
Signed-off-by: Cédric Le Goater 
[spb: Split original patch series]
Signed-off-by: Sai Pavan Boddu 
---
 hw/sd/sd.c | 14 ++
 1 file changed, 10 insertions(+), 4 deletions(-)

diff --git a/hw/sd/sd.c b/hw/sd/sd.c
index 74b9162..42ee49c 100644
--- a/hw/sd/sd.c
+++ b/hw/sd/sd.c
@@ -108,6 +108,7 @@ struct SDState {
 uint8_t spec_version;
 BlockBackend *blk;
 bool spi;
+bool emmc;
 
 /* Runtime changeables */
 
@@ -431,9 +432,13 @@ static void sd_set_csd(SDState *sd, uint64_t size)
 sd->csd[15] = (sd_crc7(sd->csd, 15) << 1) | 1;
 }
 
-static void sd_set_rca(SDState *sd)
+static void sd_set_rca(SDState *sd, uint16_t value)
 {
-sd->rca += 0x4567;
+if (sd->emmc) {
+sd->rca = value;
+} else {
+sd->rca += 0x4567;
+}
 }
 
 FIELD(CSR, AKE_SEQ_ERROR,   3,  1)
@@ -979,8 +984,8 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, 
SDRequest req)
 case sd_identification_state:
 case sd_standby_state:
 sd->state = sd_standby_state;
-sd_set_rca(sd);
-return sd_r6;
+sd_set_rca(sd, req.arg >> 16);
+return sd->emmc ? sd_r1 : sd_r6;
 
 default:
 break;
@@ -2176,6 +2181,7 @@ static Property sd_properties[] = {
  * board to ensure that ssi transfers only occur when the chip select
  * is asserted.  */
 DEFINE_PROP_BOOL("spi", SDState, spi, false),
+DEFINE_PROP_BOOL("emmc", SDState, emmc, false),
 DEFINE_PROP_END_OF_LIST()
 };
 
-- 
2.7.4




[PATCH v2 02/22] sd: sd: Remove usage of tabs in the file

2021-02-22 Thread Sai Pavan Boddu
Set tabstop as 4 and used expandtabs

Signed-off-by: Sai Pavan Boddu 
---
 hw/sd/sd.c | 190 ++---
 1 file changed, 95 insertions(+), 95 deletions(-)

diff --git a/hw/sd/sd.c b/hw/sd/sd.c
index 8517dbc..74b9162 100644
--- a/hw/sd/sd.c
+++ b/hw/sd/sd.c
@@ -332,39 +332,39 @@ static void sd_set_scr(SDState *sd)
 sd->scr[7] = 0x00;
 }
 
-#define MID0xaa
-#define OID"XY"
-#define PNM"QEMU!"
-#define PRV0x01
-#define MDT_YR 2006
-#define MDT_MON2
+#define MID 0xaa
+#define OID "XY"
+#define PNM "QEMU!"
+#define PRV 0x01
+#define MDT_YR  2006
+#define MDT_MON 2
 
 static void sd_set_cid(SDState *sd)
 {
-sd->cid[0] = MID;  /* Fake card manufacturer ID (MID) */
-sd->cid[1] = OID[0];   /* OEM/Application ID (OID) */
+sd->cid[0] = MID;   /* Fake card manufacturer ID (MID) */
+sd->cid[1] = OID[0];/* OEM/Application ID (OID) */
 sd->cid[2] = OID[1];
-sd->cid[3] = PNM[0];   /* Fake product name (PNM) */
+sd->cid[3] = PNM[0];/* Fake product name (PNM) */
 sd->cid[4] = PNM[1];
 sd->cid[5] = PNM[2];
 sd->cid[6] = PNM[3];
 sd->cid[7] = PNM[4];
-sd->cid[8] = PRV;  /* Fake product revision (PRV) */
-sd->cid[9] = 0xde; /* Fake serial number (PSN) */
+sd->cid[8] = PRV;   /* Fake product revision (PRV) */
+sd->cid[9] = 0xde;  /* Fake serial number (PSN) */
 sd->cid[10] = 0xad;
 sd->cid[11] = 0xbe;
 sd->cid[12] = 0xef;
-sd->cid[13] = 0x00 |   /* Manufacture date (MDT) */
+sd->cid[13] = 0x00 |/* Manufacture date (MDT) */
 ((MDT_YR - 2000) / 10);
 sd->cid[14] = ((MDT_YR % 10) << 4) | MDT_MON;
 sd->cid[15] = (sd_crc7(sd->cid, 15) << 1) | 1;
 }
 
-#define HWBLOCK_SHIFT  9   /* 512 bytes */
-#define SECTOR_SHIFT   5   /* 16 kilobytes */
-#define WPGROUP_SHIFT  7   /* 2 megs */
-#define CMULT_SHIFT9   /* 512 times HWBLOCK_SIZE */
-#define WPGROUP_SIZE   (1 << (HWBLOCK_SHIFT + SECTOR_SHIFT + WPGROUP_SHIFT))
+#define HWBLOCK_SHIFT   9   /* 512 bytes */
+#define SECTOR_SHIFT5   /* 16 kilobytes */
+#define WPGROUP_SHIFT   7   /* 2 megs */
+#define CMULT_SHIFT 9   /* 512 times HWBLOCK_SIZE */
+#define WPGROUP_SIZE(1 << (HWBLOCK_SHIFT + SECTOR_SHIFT + WPGROUP_SHIFT))
 
 static const uint8_t sd_csd_rw_mask[16] = {
 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
@@ -385,31 +385,31 @@ static void sd_set_csd(SDState *sd, uint64_t size)
 csize = (size >> (CMULT_SHIFT + hwblock_shift)) - 1;
 
 if (size <= SDSC_MAX_CAPACITY) { /* Standard Capacity SD */
-sd->csd[0] = 0x00; /* CSD structure */
-sd->csd[1] = 0x26; /* Data read access-time-1 */
-sd->csd[2] = 0x00; /* Data read access-time-2 */
+sd->csd[0] = 0x00;  /* CSD structure */
+sd->csd[1] = 0x26;  /* Data read access-time-1 */
+sd->csd[2] = 0x00;  /* Data read access-time-2 */
 sd->csd[3] = 0x32;  /* Max. data transfer rate: 25 MHz */
-sd->csd[4] = 0x5f; /* Card Command Classes */
-sd->csd[5] = 0x50 |/* Max. read data block length */
+sd->csd[4] = 0x5f;  /* Card Command Classes */
+sd->csd[5] = 0x50 | /* Max. read data block length */
 hwblock_shift;
-sd->csd[6] = 0xe0 |/* Partial block for read allowed */
+sd->csd[6] = 0xe0 | /* Partial block for read allowed */
 ((csize >> 10) & 0x03);
-sd->csd[7] = 0x00 |/* Device size */
+sd->csd[7] = 0x00 | /* Device size */
 ((csize >> 2) & 0xff);
-sd->csd[8] = 0x3f |/* Max. read current */
+sd->csd[8] = 0x3f | /* Max. read current */
 ((csize << 6) & 0xc0);
-sd->csd[9] = 0xfc |/* Max. write current */
+sd->csd[9] = 0xfc | /* Max. write current */
 ((CMULT_SHIFT - 2) >> 1);
-sd->csd[10] = 0x40 |   /* Erase sector size */
+sd->csd[10] = 0x40 |/* Erase sector size */
 (((CMULT_SHIFT - 2) << 7) & 0x80) | (sectsize >> 1);
-sd->csd[11] = 0x00 |   /* Write protect group size */
+sd->csd[11] = 0x00 |/* Write protect group size */
 ((sectsize << 7) & 0x80) | wpsize;
-sd->csd[12] = 0x90 |   /* Write speed factor */
+sd->csd[12] = 0x90 |/* Write speed factor */
 (hwblock_shift >> 2);
-sd->csd[13] = 0x20 |   /* Max. write data block length */
+sd->csd[13] = 0x20 |/* Max. write data block length */
 ((hwblock_shift << 6) &am

[PATCH v2 18/22] sd: emmc: Subtract bootarea size from blk

2021-02-22 Thread Sai Pavan Boddu
From: Joel Stanley 

The userdata size is derived from the file the user passes on the
command line, but we must take into account the boot areas.

Signed-off-by: Joel Stanley 
Signed-off-by: Cédric Le Goater 
---
 hw/sd/sd.c | 5 +
 1 file changed, 5 insertions(+)

diff --git a/hw/sd/sd.c b/hw/sd/sd.c
index ab29e54..a0b4507 100644
--- a/hw/sd/sd.c
+++ b/hw/sd/sd.c
@@ -653,6 +653,11 @@ static void sd_reset(DeviceState *dev)
 }
 size = sect << 9;
 
+if (sd->emmc) {
+unsigned int boot_capacity = sd->ext_csd[EXT_CSD_BOOT_MULT] << 17;
+size -= boot_capacity * 2;
+}
+
 sect = sd_addr_to_wpnum(size) + 1;
 
 sd->state = sd_idle_state;
-- 
2.7.4




[PATCH v2 04/22] sd: emmc: update OCR fields for eMMC

2021-02-22 Thread Sai Pavan Boddu
From: Vincent Palatin 

eMMC OCR register doesn't has UHS-II field and voltage fields are
different.

Signed-off-by: Sai Pavan Boddu 
---
 hw/sd/sd.c | 27 ---
 1 file changed, 24 insertions(+), 3 deletions(-)

diff --git a/hw/sd/sd.c b/hw/sd/sd.c
index 42ee49c..430bea5 100644
--- a/hw/sd/sd.c
+++ b/hw/sd/sd.c
@@ -283,6 +283,15 @@ FIELD(OCR, UHS_II_CARD,29,  1) /* Only 
UHS-II */
 FIELD(OCR, CARD_CAPACITY,  30,  1) /* 0:SDSC, 1:SDHC/SDXC */
 FIELD(OCR, CARD_POWER_UP,  31,  1)
 
+/*
+ * eMMC OCR register
+ */
+FIELD(EMMC_OCR, VDD_WINDOW_0,  7, 1)
+FIELD(EMMC_OCR, VDD_WINDOW_1,  8, 7)
+FIELD(EMMC_OCR, VDD_WINDOW_2, 15, 9)
+FIELD(EMMC_OCR, ACCESS_MODE,  29, 2)
+FIELD(EMMC_OCR, POWER_UP, 31, 1)
+
 #define ACMD41_ENQUIRY_MASK 0x00ff
 #define ACMD41_R3_MASK  (R_OCR_VDD_VOLTAGE_WIN_HI_MASK \
| R_OCR_ACCEPT_SWITCH_1V8_MASK \
@@ -292,8 +301,16 @@ FIELD(OCR, CARD_POWER_UP,  31,  1)
 
 static void sd_set_ocr(SDState *sd)
 {
-/* All voltages OK */
-sd->ocr = R_OCR_VDD_VOLTAGE_WIN_HI_MASK;
+if (sd->emmc) {
+/*
+ * Dual Voltage eMMC card
+ */
+sd->ocr = R_EMMC_OCR_VDD_WINDOW_0_MASK |
+  R_EMMC_OCR_VDD_WINDOW_2_MASK;
+} else {
+/* All voltages OK */
+sd->ocr = R_OCR_VDD_VOLTAGE_WIN_HI_MASK;
+}
 }
 
 static void sd_ocr_powerup(void *opaque)
@@ -521,7 +538,11 @@ static void sd_response_r1_make(SDState *sd, uint8_t 
*response)
 
 static void sd_response_r3_make(SDState *sd, uint8_t *response)
 {
-stl_be_p(response, sd->ocr & ACMD41_R3_MASK);
+if (sd->emmc) {
+stl_be_p(response, sd->ocr);
+} else {
+stl_be_p(response, sd->ocr & ACMD41_R3_MASK);
+}
 }
 
 static void sd_response_r6_make(SDState *sd, uint8_t *response)
-- 
2.7.4




[PATCH v2 00/22] eMMC support

2021-02-22 Thread Sai Pavan Boddu
Hi,

This patch series add support for eMMC cards. This work was previosly
submitted by Vincent, rebased few changes on top.

Cedric & Joel has helped to added boot partition access support. I
expect them to make a follow-up series to use it with aspeed machines.

Present series adds eMMC support to Versal SOC.

Initial patch series version is RFC
Changes for V2:
Split Patch 1
Add comments for eMMC Erase commands
Added documentation about eMMC and Versal-virt board.
Make eMMC optional for xlnx-versal-virt machines

Regards,
Sai Pavan

Cédric Le Goater (2):
  sd: sdmmc-internal: Add command string for SEND_OP_CMD
  sd: emmc: Add Extended CSD register definitions

Joel Stanley (2):
  sd: emmc: Support boot area in emmc image
  sd: emmc: Subtract bootarea size from blk

Sai Pavan Boddu (13):
  sd: sd: Remove usage of tabs in the file
  sd: emmc: Dont not update CARD_CAPACITY for eMMC cards
  sd: emmc: Update CMD1 definition for eMMC
  sd: emmc: support idle state in CMD2
  sd: emmc: Add mmc switch function support
  sd: emmc: add CMD21 tuning sequence
  sd: emmc: Make ACMD41 illegal for mmc
  sd: emmc: Add support for emmc erase
  sd: emmc: Update CID structure for eMMC
  sd: sdhci: Support eMMC devices
  arm: xlnx-versal: Add emmc to versal
  docs: devel: emmc: Add a doc for emmc card emulation
  docs: arm: xlnx-versal-virt: Add eMMC support documentation

Vincent Palatin (5):
  block: add eMMC block device type
  sd: emmc: Add support for eMMC cards
  sd: emmc: update OCR fields for eMMC
  sd: emmc: Add support for EXT_CSD & CSD for eMMC
  sd: emmc: Update CMD8 to send EXT_CSD register

 docs/devel/emmc.txt  |  16 +
 docs/system/arm/xlnx-versal-virt.rst |  10 +
 hw/sd/sdmmc-internal.h   |  97 +++
 include/hw/arm/xlnx-versal.h |   1 +
 include/sysemu/blockdev.h|   1 +
 blockdev.c   |   1 +
 hw/arm/xlnx-versal-virt.c|  30 +-
 hw/arm/xlnx-versal.c |  13 +-
 hw/sd/sd.c   | 545 ++-
 hw/sd/sdhci.c|   4 -
 hw/sd/sdmmc-internal.c   |   2 +-
 11 files changed, 571 insertions(+), 149 deletions(-)
 create mode 100644 docs/devel/emmc.txt

-- 
2.7.4




RE: [RFC PATCH 11/15] sd: emmc: Add Extended CSD register definitions

2021-02-16 Thread Sai Pavan Boddu
Hi Luc,
> -Original Message-
> From: Luc Michel 
> Sent: Saturday, February 13, 2021 6:26 PM
> To: Sai Pavan Boddu ; Markus Armbruster
> ; Kevin Wolf ; Max Reitz
> ; Vladimir Sementsov-Ogievskiy
> ; Eric Blake ; Joel Stanley
> ; Cédric Le Goater ; Vincent Palatin
> ; Dr. David Alan Gilbert ;
> Thomas Huth ; Stefan Hajnoczi ;
> Peter Maydell ; Alistair Francis
> ; Edgar Iglesias ; Paolo Bonzini
> 
> Cc: qemu-bl...@nongnu.org; qemu-devel@nongnu.org; Sai Pavan Boddu
> 
> Subject: Re: [RFC PATCH 11/15] sd: emmc: Add Extended CSD register
> definitions
> 
> On 2/11/21 9:17 AM, Sai Pavan Boddu wrote:
> > From: Cédric Le Goater 
> >
> > Add user friendly macros for EXT_CSD register. >
> > Signed-off-by: Cédric Le Goater 
> > [spb: Rebased over versal emmc series,
> >updated commit message]
> > Signed-off-by: Sai Pavan Boddu 
> 
> Hi,
> 
> If Cédric agrees, maybe you can squash this commit into patch 2, and add the
> missing register definitions?
[Sai Pavan Boddu] Yeah, that would be nice. I will leave @Cédric Le Goater 
comment here.
> 
> Also, can you set diff.orderFile = script/git.orderfile in your git config 
> for your
> QEMU repo? It makes the review process a bit easier.
[Sai Pavan Boddu] Ok, I would configure this. Thanks !

Regards,
Sai Pavan
> 
> Thanks!
> 
> --
> Luc
> 
> > ---
> >   hw/sd/sd.c | 54 +++-
> >   hw/sd/sdmmc-internal.h | 97
> ++
> >   2 files changed, 126 insertions(+), 25 deletions(-)
> >
> > diff --git a/hw/sd/sd.c b/hw/sd/sd.c
> > index 45311fa..54fba7b 100644
> > --- a/hw/sd/sd.c
> > +++ b/hw/sd/sd.c
> > @@ -398,41 +398,45 @@ static void mmc_set_ext_csd(SDState *sd, uint64_t
> size)
> >   uint32_t sectcount = size >> HWBLOCK_SHIFT;
> >
> >   memset(sd->ext_csd, 0, 512);
> > -sd->ext_csd[504] = 0x1; /* supported command sets */
> > -sd->ext_csd[503] = 0x1; /* HPI features  */
> > -sd->ext_csd[502] = 0x1; /* Background operations support */
> > +sd->ext_csd[EXT_CSD_S_CMD_SET] = 0x1; /* supported command sets */
> > +sd->ext_csd[EXT_CSD_HPI_FEATURES] = 0x3; /* HPI features  */
> > +sd->ext_csd[EXT_CSD_BKOPS_SUPPORT] = 0x1; /* Background operations
> > + support */
> >   sd->ext_csd[241] = 0xA; /* 1st initialization time after partitioning 
> > */
> > -sd->ext_csd[232] = 0x1; /* Trim multiplier */
> > -sd->ext_csd[231] = 0x15; /* Secure feature support */
> > -sd->ext_csd[230] = 0x96; /* Secure erase support */
> > -sd->ext_csd[229] = 0x96; /* Secure TRIM multiplier */
> > -sd->ext_csd[228] = 0x7; /* Boot information */
> > -sd->ext_csd[226] = 0x8; /* Boot partition size */
> > -sd->ext_csd[225] = 0x6; /* Access size */
> > -sd->ext_csd[224] = 0x4; /* HC Erase unit size */
> > -sd->ext_csd[223] = 0x1; /* HC erase timeout */
> > -sd->ext_csd[222] = 0x1; /* Reliable write sector count */
> > -sd->ext_csd[221] = 0x4; /* HC write protect group size */
> > -sd->ext_csd[220] = 0x8; /* Sleep current VCC  */
> > -sd->ext_csd[219] = 0x7; /* Sleep current VCCQ */
> > -sd->ext_csd[217] = 0x11; /* Sleep/Awake timeout */
> > +sd->ext_csd[EXT_CSD_TRIM_MULT] = 0x1; /* Trim multiplier */
> > +sd->ext_csd[EXT_CSD_SEC_FEATURE_SUPPORT] = 0x15; /* Secure feature
> > +support */
> > +sd->ext_csd[EXT_CSD_SEC_ERASE_MULT] = 0x96; /* Secure erase support
> */
> > +sd->ext_csd[EXT_CSD_SEC_TRIM_MULT] = 0x96; /* Secure TRIM
> multiplier */
> > +sd->ext_csd[EXT_CSD_BOOT_INFO] = 0x7; /* Boot information */
> > +sd->ext_csd[EXT_CSD_BOOT_MULT] = 0x8; /* Boot partition size. 128KB
> unit */
> > +sd->ext_csd[EXT_CSD_ACC_SIZE] = 0x6; /* Access size */
> > +sd->ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE] = 0x4; /* HC Erase unit size
> */
> > +sd->ext_csd[EXT_CSD_ERASE_TIMEOUT_MULT] = 0x1; /* HC erase
> timeout */
> > +sd->ext_csd[EXT_CSD_REL_WR_SEC_C] = 0x1; /* Reliable write sector
> count */
> > +sd->ext_csd[EXT_CSD_HC_WP_GRP_SIZE] = 0x4; /* HC write protect
> group size */
> > +sd->ext_csd[EXT_CSD_S_C_VCC] = 0x8; /* Sleep current VCC  */
> > +sd->ext_csd[EXT_CSD_S_C_VCCQ] = 0x7; /* Sleep current VCCQ */
> > +sd->ext_csd[EXT_CSD_S_A_TIMEOUT] = 0x11; /* Sleep/Awake timeout
> > + */
> >

RE: [RFC PATCH 10/15] sd: emmc: Update CID structure for eMMC

2021-02-16 Thread Sai Pavan Boddu
Hi Alistair
> -Original Message-
> From: Alistair Francis 
> Sent: Saturday, February 13, 2021 3:41 AM
> To: Sai Pavan Boddu 
> Cc: Markus Armbruster ; Kevin Wolf
> ; Max Reitz ; Vladimir Sementsov-
> Ogievskiy ; Eric Blake ;
> Joel Stanley ; Cédric Le Goater ; Vincent
> Palatin ; Dr. David Alan Gilbert
> ; Thomas Huth ; Stefan Hajnoczi
> ; Peter Maydell ; Alistair
> Francis ; Edgar Iglesias ; Luc
> Michel ; Paolo Bonzini ;
> Sai Pavan Boddu ; qemu-devel@nongnu.org Developers
> ; Qemu-block 
> Subject: Re: [RFC PATCH 10/15] sd: emmc: Update CID structure for eMMC
> 
> On Thu, Feb 11, 2021 at 12:30 AM Sai Pavan Boddu
>  wrote:
> >
> > CID structure is little different for eMMC, w.r.t to product name and
> > manufacturing date.
> >
> > Signed-off-by: Sai Pavan Boddu 
> > Signed-off-by: Edgar E. Iglesias 
> > ---
> >  hw/sd/sd.c | 52 +++-
> >  1 file changed, 35 insertions(+), 17 deletions(-)
> >
> > diff --git a/hw/sd/sd.c b/hw/sd/sd.c
> > index 7aab647..45311fa 100644
> > --- a/hw/sd/sd.c
> > +++ b/hw/sd/sd.c
> > @@ -345,23 +345,41 @@ static void sd_set_scr(SDState *sd)
> >
> >  static void sd_set_cid(SDState *sd)
> >  {
> > -sd->cid[0] = MID;  /* Fake card manufacturer ID (MID) */
> > -sd->cid[1] = OID[0];   /* OEM/Application ID (OID) */
> > -sd->cid[2] = OID[1];
> > -sd->cid[3] = PNM[0];   /* Fake product name (PNM) */
> > -sd->cid[4] = PNM[1];
> > -sd->cid[5] = PNM[2];
> > -sd->cid[6] = PNM[3];
> > -sd->cid[7] = PNM[4];
> > -sd->cid[8] = PRV;  /* Fake product revision (PRV) */
> > -sd->cid[9] = 0xde; /* Fake serial number (PSN) */
> > -sd->cid[10] = 0xad;
> > -sd->cid[11] = 0xbe;
> > -sd->cid[12] = 0xef;
> > -sd->cid[13] = 0x00 |   /* Manufacture date (MDT) */
> > -((MDT_YR - 2000) / 10);
> > -sd->cid[14] = ((MDT_YR % 10) << 4) | MDT_MON;
> > -sd->cid[15] = (sd_crc7(sd->cid, 15) << 1) | 1;
> > +if (sd->emmc) {
> > +sd->cid[0] = MID;
> > +sd->cid[1] = 0x1;   /* CBX */
> > +sd->cid[2] = OID[0];    /* OEM/Application ID (OID) */
> > +sd->cid[3] = PNM[0];/* Fake product name (PNM) 48bit */
> > +sd->cid[4] = PNM[1];
> > +sd->cid[5] = PNM[2];
> > +sd->cid[6] = PNM[3];
> > +sd->cid[7] = PNM[4];
> 
> Aren't the majority of these the same between the two cases? It's probably
> cleaner to split them out then.
[Sai Pavan Boddu] Yes, I would try to re-order. If I see only the PNM fields 
are same, rest all fields kind of moved a byte below.

Regards,
Sai Pavan
> 
> Alistair
> 
> > +sd->cid[8] = 0x0;
> > +sd->cid[9] = PRV;/* Fake product revision (PRV) */
> > +sd->cid[10] = 0xde;  /* Fake serial number (PSN) */
> > +sd->cid[11] = 0xad;
> > +sd->cid[12] = 0xbe;
> > +sd->cid[13] = 0xef;
> > +sd->cid[14] = ((MDT_YR - 1997) % 0x10); /* MDT */
> > +} else {
> > +sd->cid[0] = MID;   /* Fake card manufacturer ID (MID) */
> > +sd->cid[1] = OID[0];/* OEM/Application ID (OID) */
> > +sd->cid[2] = OID[1];
> > +sd->cid[3] = PNM[0];/* Fake product name (PNM) 40bit */
> > +sd->cid[4] = PNM[1];
> > +sd->cid[5] = PNM[2];
> > +sd->cid[6] = PNM[3];
> > +sd->cid[7] = PNM[4];
> > +sd->cid[8] = PRV;   /* Fake product revision (PRV) */
> > +sd->cid[9] = 0xde;  /* Fake serial number (PSN) */
> > +sd->cid[10] = 0xad;
> > +sd->cid[11] = 0xbe;
> > +sd->cid[12] = 0xef;
> > +sd->cid[13] = 0x00 |/* Manufacture date (MDT) */
> > +((MDT_YR - 2000) / 10);
> > +sd->cid[14] = ((MDT_YR % 10) << 4) | MDT_MON;
> > +   }
> > +   sd->cid[15] = (sd_crc7(sd->cid, 15) << 1) | 1;
> >  }
> >
> >  #define HWBLOCK_SHIFT  9   /* 512 bytes */
> > --
> > 2.7.4
> >
> >


RE: [RFC PATCH 09/15] sd: emmc: Add support for emmc erase

2021-02-16 Thread Sai Pavan Boddu
Hi Alistair,
> -Original Message-
> From: Alistair Francis 
> Sent: Saturday, February 13, 2021 3:38 AM
> To: Sai Pavan Boddu 
> Cc: Markus Armbruster ; Kevin Wolf
> ; Max Reitz ; Vladimir Sementsov-
> Ogievskiy ; Eric Blake ;
> Joel Stanley ; Cédric Le Goater ; Vincent
> Palatin ; Dr. David Alan Gilbert
> ; Thomas Huth ; Stefan Hajnoczi
> ; Peter Maydell ; Alistair
> Francis ; Edgar Iglesias ; Luc
> Michel ; Paolo Bonzini ;
> Sai Pavan Boddu ; qemu-devel@nongnu.org Developers
> ; Qemu-block 
> Subject: Re: [RFC PATCH 09/15] sd: emmc: Add support for emmc erase
> 
> On Thu, Feb 11, 2021 at 12:19 AM Sai Pavan Boddu
>  wrote:
> >
> > Add CMD35 and CMD36 which sets the erase start and end.
> >
> > Signed-off-by: Sai Pavan Boddu 
> > Signed-off-by: Edgar E. Iglesias 
> > ---
> >  hw/sd/sd.c | 2 ++
> >  1 file changed, 2 insertions(+)
> >
> > diff --git a/hw/sd/sd.c b/hw/sd/sd.c
> > index 236f2b8..7aab647 100644
> > --- a/hw/sd/sd.c
> > +++ b/hw/sd/sd.c
> > @@ -1544,6 +1544,7 @@ static sd_rsp_type_t sd_normal_command(SDState
> > *sd, SDRequest req)
> >
> >  /* Erase commands (Class 5) */
> >  case 32:   /* CMD32:  ERASE_WR_BLK_START */
> > +case 35:
> 
> Can you comment the CMD here?
[Sai Pavan Boddu] Sure I will update this.

Regards,
Sai Pavan
> 
> >  switch (sd->state) {
> >  case sd_transfer_state:
> >  sd->erase_start = req.arg; @@ -1555,6 +1556,7 @@ static
> > sd_rsp_type_t sd_normal_command(SDState *sd, SDRequest req)
> >  break;
> >
> >  case 33:   /* CMD33:  ERASE_WR_BLK_END */
> > +case 36:
> 
> and here?
> 
> Alistair
> 
> >  switch (sd->state) {
> >  case sd_transfer_state:
> >  sd->erase_end = req.arg;
> > --
> > 2.7.4
> >
> >


[RFC PATCH 15/15] arm: xlnx-versal: Add emmc to versal

2021-02-11 Thread Sai Pavan Boddu
Configuring SDHCI-0 to act as eMMC controller.

Signed-off-by: Sai Pavan Boddu 
---
 hw/arm/xlnx-versal-virt.c | 16 +++-
 hw/arm/xlnx-versal.c  | 14 --
 2 files changed, 23 insertions(+), 7 deletions(-)

diff --git a/hw/arm/xlnx-versal-virt.c b/hw/arm/xlnx-versal-virt.c
index 8482cd6..18489e4 100644
--- a/hw/arm/xlnx-versal-virt.c
+++ b/hw/arm/xlnx-versal-virt.c
@@ -333,6 +333,13 @@ static void fdt_add_sd_nodes(VersalVirt *s)
 qemu_fdt_setprop_sized_cells(s->fdt, name, "reg",
  2, addr, 2, MM_PMC_SD0_SIZE);
 qemu_fdt_setprop(s->fdt, name, "compatible", compat, sizeof(compat));
+/*
+ * eMMC specific properties
+ */
+if (i == 0) {
+qemu_fdt_setprop(s->fdt, name, "non-removable", NULL, 0);
+qemu_fdt_setprop_sized_cells(s->fdt, name, "bus-width", 1, 8);
+}
 g_free(name);
 }
 }
@@ -512,7 +519,7 @@ static void create_virtio_regions(VersalVirt *s)
 }
 }
 
-static void sd_plugin_card(SDHCIState *sd, DriveInfo *di)
+static void sd_plugin_card(SDHCIState *sd, DriveInfo *di, bool emmc)
 {
 BlockBackend *blk = di ? blk_by_legacy_dinfo(di) : NULL;
 DeviceState *card;
@@ -520,6 +527,7 @@ static void sd_plugin_card(SDHCIState *sd, DriveInfo *di)
 card = qdev_new(TYPE_SD_CARD);
 object_property_add_child(OBJECT(sd), "card[*]", OBJECT(card));
 qdev_prop_set_drive_err(card, "drive", blk, _fatal);
+object_property_set_bool(OBJECT(card), "emmc", emmc, _fatal);
 qdev_realize_and_unref(card, qdev_get_child_bus(DEVICE(sd), "sd-bus"),
_fatal);
 }
@@ -528,7 +536,6 @@ static void versal_virt_init(MachineState *machine)
 {
 VersalVirt *s = XLNX_VERSAL_VIRT_MACHINE(machine);
 int psci_conduit = QEMU_PSCI_CONDUIT_DISABLED;
-int i;
 
 /*
  * If the user provides an Operating System to be loaded, we expect them
@@ -581,10 +588,9 @@ static void versal_virt_init(MachineState *machine)
 memory_region_add_subregion_overlap(get_system_memory(),
 0, >soc.fpd.apu.mr, 0);
 
+sd_plugin_card(>soc.pmc.iou.sd[0], drive_get_next(IF_EMMC), true);
 /* Plugin SD cards.  */
-for (i = 0; i < ARRAY_SIZE(s->soc.pmc.iou.sd); i++) {
-sd_plugin_card(>soc.pmc.iou.sd[i], drive_get_next(IF_SD));
-}
+sd_plugin_card(>soc.pmc.iou.sd[1], drive_get_next(IF_SD), false);
 
 s->binfo.ram_size = machine->ram_size;
 s->binfo.loader_start = 0x0;
diff --git a/hw/arm/xlnx-versal.c b/hw/arm/xlnx-versal.c
index b077716..3498dd9 100644
--- a/hw/arm/xlnx-versal.c
+++ b/hw/arm/xlnx-versal.c
@@ -230,9 +230,14 @@ static void versal_create_admas(Versal *s, qemu_irq *pic)
 }
 
 #define SDHCI_CAPABILITIES  0x280737ec6481 /* Same as on ZynqMP.  */
+#define SDHCI0_CAPS ((SDHCI_CAPABILITIES & ~(3 << 30)) | \
+ (1 << 30))
+#define SDHCI1_CAPS SDHCI_CAPABILITIES
+
 static void versal_create_sds(Versal *s, qemu_irq *pic)
 {
 int i;
+uint64_t caps[] = {SDHCI0_CAPS, SDHCI1_CAPS};
 
 for (i = 0; i < ARRAY_SIZE(s->pmc.iou.sd); i++) {
 DeviceState *dev;
@@ -244,9 +249,14 @@ static void versal_create_sds(Versal *s, qemu_irq *pic)
 
 object_property_set_uint(OBJECT(dev), "sd-spec-version", 3,
  _fatal);
-object_property_set_uint(OBJECT(dev), "capareg", SDHCI_CAPABILITIES,
+object_property_set_uint(OBJECT(dev), "capareg", caps[i],
  _fatal);
-object_property_set_uint(OBJECT(dev), "uhs", UHS_I, _fatal);
+/*
+ * UHS is not applicable for eMMC
+ */
+if (i == 1) {
+object_property_set_uint(OBJECT(dev), "uhs", UHS_I, _fatal);
+}
 sysbus_realize(SYS_BUS_DEVICE(dev), _fatal);
 
 mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(dev), 0);
-- 
2.7.4




[RFC PATCH 14/15] sd: sdhci: Support eMMC devices

2021-02-11 Thread Sai Pavan Boddu
Embedded device slots should be allowed as support of eMMC is available.

Signed-off-by: Sai Pavan Boddu 
---
 hw/sd/sdhci.c | 4 
 1 file changed, 4 deletions(-)

diff --git a/hw/sd/sdhci.c b/hw/sd/sdhci.c
index 8ffa539..771212a 100644
--- a/hw/sd/sdhci.c
+++ b/hw/sd/sdhci.c
@@ -99,10 +99,6 @@ static void sdhci_check_capareg(SDHCIState *s, Error **errp)
 msk = FIELD_DP64(msk, SDHC_CAPAB, ASYNC_INT, 0);
 
 val = FIELD_EX64(s->capareg, SDHC_CAPAB, SLOT_TYPE);
-if (val) {
-error_setg(errp, "slot-type not supported");
-return;
-}
 trace_sdhci_capareg("slot type", val);
 msk = FIELD_DP64(msk, SDHC_CAPAB, SLOT_TYPE, 0);
 
-- 
2.7.4




[RFC PATCH 11/15] sd: emmc: Add Extended CSD register definitions

2021-02-11 Thread Sai Pavan Boddu
From: Cédric Le Goater 

Add user friendly macros for EXT_CSD register.

Signed-off-by: Cédric Le Goater 
[spb: Rebased over versal emmc series,
  updated commit message]
Signed-off-by: Sai Pavan Boddu 
---
 hw/sd/sd.c | 54 +++-
 hw/sd/sdmmc-internal.h | 97 ++
 2 files changed, 126 insertions(+), 25 deletions(-)

diff --git a/hw/sd/sd.c b/hw/sd/sd.c
index 45311fa..54fba7b 100644
--- a/hw/sd/sd.c
+++ b/hw/sd/sd.c
@@ -398,41 +398,45 @@ static void mmc_set_ext_csd(SDState *sd, uint64_t size)
 uint32_t sectcount = size >> HWBLOCK_SHIFT;
 
 memset(sd->ext_csd, 0, 512);
-sd->ext_csd[504] = 0x1; /* supported command sets */
-sd->ext_csd[503] = 0x1; /* HPI features  */
-sd->ext_csd[502] = 0x1; /* Background operations support */
+sd->ext_csd[EXT_CSD_S_CMD_SET] = 0x1; /* supported command sets */
+sd->ext_csd[EXT_CSD_HPI_FEATURES] = 0x3; /* HPI features  */
+sd->ext_csd[EXT_CSD_BKOPS_SUPPORT] = 0x1; /* Background operations
+ support */
 sd->ext_csd[241] = 0xA; /* 1st initialization time after partitioning */
-sd->ext_csd[232] = 0x1; /* Trim multiplier */
-sd->ext_csd[231] = 0x15; /* Secure feature support */
-sd->ext_csd[230] = 0x96; /* Secure erase support */
-sd->ext_csd[229] = 0x96; /* Secure TRIM multiplier */
-sd->ext_csd[228] = 0x7; /* Boot information */
-sd->ext_csd[226] = 0x8; /* Boot partition size */
-sd->ext_csd[225] = 0x6; /* Access size */
-sd->ext_csd[224] = 0x4; /* HC Erase unit size */
-sd->ext_csd[223] = 0x1; /* HC erase timeout */
-sd->ext_csd[222] = 0x1; /* Reliable write sector count */
-sd->ext_csd[221] = 0x4; /* HC write protect group size */
-sd->ext_csd[220] = 0x8; /* Sleep current VCC  */
-sd->ext_csd[219] = 0x7; /* Sleep current VCCQ */
-sd->ext_csd[217] = 0x11; /* Sleep/Awake timeout */
+sd->ext_csd[EXT_CSD_TRIM_MULT] = 0x1; /* Trim multiplier */
+sd->ext_csd[EXT_CSD_SEC_FEATURE_SUPPORT] = 0x15; /* Secure feature
+support */
+sd->ext_csd[EXT_CSD_SEC_ERASE_MULT] = 0x96; /* Secure erase support */
+sd->ext_csd[EXT_CSD_SEC_TRIM_MULT] = 0x96; /* Secure TRIM multiplier */
+sd->ext_csd[EXT_CSD_BOOT_INFO] = 0x7; /* Boot information */
+sd->ext_csd[EXT_CSD_BOOT_MULT] = 0x8; /* Boot partition size. 128KB unit */
+sd->ext_csd[EXT_CSD_ACC_SIZE] = 0x6; /* Access size */
+sd->ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE] = 0x4; /* HC Erase unit size */
+sd->ext_csd[EXT_CSD_ERASE_TIMEOUT_MULT] = 0x1; /* HC erase timeout */
+sd->ext_csd[EXT_CSD_REL_WR_SEC_C] = 0x1; /* Reliable write sector count */
+sd->ext_csd[EXT_CSD_HC_WP_GRP_SIZE] = 0x4; /* HC write protect group size 
*/
+sd->ext_csd[EXT_CSD_S_C_VCC] = 0x8; /* Sleep current VCC  */
+sd->ext_csd[EXT_CSD_S_C_VCCQ] = 0x7; /* Sleep current VCCQ */
+sd->ext_csd[EXT_CSD_S_A_TIMEOUT] = 0x11; /* Sleep/Awake timeout */
 sd->ext_csd[215] = (sectcount >> 24) & 0xff; /* Sector count */
 sd->ext_csd[214] = (sectcount >> 16) & 0xff; /* ... */
 sd->ext_csd[213] = (sectcount >> 8) & 0xff;  /* ... */
-sd->ext_csd[212] = (sectcount & 0xff);   /* ... */
+sd->ext_csd[EXT_CSD_SEC_CNT] = (sectcount & 0xff);   /* ... */
 sd->ext_csd[210] = 0xa; /* Min write perf for 8bit@52Mhz */
 sd->ext_csd[209] = 0xa; /* Min read perf for 8bit@52Mhz  */
 sd->ext_csd[208] = 0xa; /* Min write perf for 4bit@52Mhz */
 sd->ext_csd[207] = 0xa; /* Min read perf for 4bit@52Mhz */
 sd->ext_csd[206] = 0xa; /* Min write perf for 4bit@26Mhz */
 sd->ext_csd[205] = 0xa; /* Min read perf for 4bit@26Mhz */
-sd->ext_csd[199] = 0x1; /* Partition switching timing */
-sd->ext_csd[198] = 0x1; /* Out-of-interrupt busy timing */
-sd->ext_csd[196] = 0xFF; /* Card type */
-sd->ext_csd[194] = 0x2; /* CSD Structure version */
-sd->ext_csd[192] = 0x5; /* Extended CSD revision */
-sd->ext_csd[168] = 0x1; /* RPMB size */
-sd->ext_csd[160] = 0x3; /* Partinioning support */
+sd->ext_csd[EXT_CSD_PART_SWITCH_TIME] = 0x1; /* Partition switching
+timing */
+sd->ext_csd[EXT_CSD_OUT_OF_INTERRUPT_TIME] = 0x1; /* Out-of-interrupt busy
+ timing */
+sd->ext_csd[EXT_CSD_CARD_TYPE] = 0xFF; /* Card type */
+sd->ext_csd[EXT_CSD_STRUCTURE] = 0x2; /* CSD Structure version */
+sd->ext_csd[EXT_CSD_REV] = 0x5; /* Extended CSD revision */
+sd->ext_csd[EXT_CSD_RPMB_MULT] = 0x1; /* RPMB size */
+sd->ext_csd[EXT_CSD_PARTITION_SUPPORT] = 0x3; /* Partinioning support */
  

[RFC PATCH 10/15] sd: emmc: Update CID structure for eMMC

2021-02-11 Thread Sai Pavan Boddu
CID structure is little different for eMMC, w.r.t to product name and
manufacturing date.

Signed-off-by: Sai Pavan Boddu 
Signed-off-by: Edgar E. Iglesias 
---
 hw/sd/sd.c | 52 +++-
 1 file changed, 35 insertions(+), 17 deletions(-)

diff --git a/hw/sd/sd.c b/hw/sd/sd.c
index 7aab647..45311fa 100644
--- a/hw/sd/sd.c
+++ b/hw/sd/sd.c
@@ -345,23 +345,41 @@ static void sd_set_scr(SDState *sd)
 
 static void sd_set_cid(SDState *sd)
 {
-sd->cid[0] = MID;  /* Fake card manufacturer ID (MID) */
-sd->cid[1] = OID[0];   /* OEM/Application ID (OID) */
-sd->cid[2] = OID[1];
-sd->cid[3] = PNM[0];   /* Fake product name (PNM) */
-sd->cid[4] = PNM[1];
-sd->cid[5] = PNM[2];
-sd->cid[6] = PNM[3];
-sd->cid[7] = PNM[4];
-sd->cid[8] = PRV;  /* Fake product revision (PRV) */
-sd->cid[9] = 0xde; /* Fake serial number (PSN) */
-sd->cid[10] = 0xad;
-sd->cid[11] = 0xbe;
-sd->cid[12] = 0xef;
-sd->cid[13] = 0x00 |   /* Manufacture date (MDT) */
-((MDT_YR - 2000) / 10);
-sd->cid[14] = ((MDT_YR % 10) << 4) | MDT_MON;
-sd->cid[15] = (sd_crc7(sd->cid, 15) << 1) | 1;
+if (sd->emmc) {
+sd->cid[0] = MID;
+sd->cid[1] = 0x1;   /* CBX */
+sd->cid[2] = OID[0];/* OEM/Application ID (OID) */
+sd->cid[3] = PNM[0];/* Fake product name (PNM) 48bit */
+sd->cid[4] = PNM[1];
+sd->cid[5] = PNM[2];
+sd->cid[6] = PNM[3];
+sd->cid[7] = PNM[4];
+sd->cid[8] = 0x0;
+sd->cid[9] = PRV;/* Fake product revision (PRV) */
+sd->cid[10] = 0xde;  /* Fake serial number (PSN) */
+sd->cid[11] = 0xad;
+sd->cid[12] = 0xbe;
+sd->cid[13] = 0xef;
+sd->cid[14] = ((MDT_YR - 1997) % 0x10); /* MDT */
+} else {
+sd->cid[0] = MID;   /* Fake card manufacturer ID (MID) */
+sd->cid[1] = OID[0];/* OEM/Application ID (OID) */
+sd->cid[2] = OID[1];
+sd->cid[3] = PNM[0];/* Fake product name (PNM) 40bit */
+sd->cid[4] = PNM[1];
+sd->cid[5] = PNM[2];
+sd->cid[6] = PNM[3];
+sd->cid[7] = PNM[4];
+sd->cid[8] = PRV;   /* Fake product revision (PRV) */
+sd->cid[9] = 0xde;  /* Fake serial number (PSN) */
+sd->cid[10] = 0xad;
+sd->cid[11] = 0xbe;
+sd->cid[12] = 0xef;
+sd->cid[13] = 0x00 |/* Manufacture date (MDT) */
+((MDT_YR - 2000) / 10);
+sd->cid[14] = ((MDT_YR % 10) << 4) | MDT_MON;
+   }
+   sd->cid[15] = (sd_crc7(sd->cid, 15) << 1) | 1;
 }
 
 #define HWBLOCK_SHIFT  9   /* 512 bytes */
-- 
2.7.4




[RFC PATCH 07/15] sd: emmc: add CMD21 tuning sequence

2021-02-11 Thread Sai Pavan Boddu
eMMC cards support tuning sequence for entering HS200 mode.

Signed-off-by: Sai Pavan Boddu 
Signed-off-by: Edgar E. Iglesias 
---
 hw/sd/sd.c | 47 +++
 1 file changed, 47 insertions(+)

diff --git a/hw/sd/sd.c b/hw/sd/sd.c
index 7925174..90359f6 100644
--- a/hw/sd/sd.c
+++ b/hw/sd/sd.c
@@ -1378,6 +1378,14 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, 
SDRequest req)
 }
 break;
 
+case 21:/* CMD21: mmc SEND TUNING_BLOCK */
+if (sd->emmc && (sd->state == sd_transfer_state)) {
+sd->state = sd_sendingdata_state;
+sd->data_offset = 0;
+return sd_r1;
+}
+break;
+
 case 23:/* CMD23: SET_BLOCK_COUNT */
 if (sd->spec_version < SD_PHY_SPECv3_01_VERS) {
 break;
@@ -2112,6 +2120,30 @@ static const uint8_t 
sd_tuning_block_pattern[SD_TUNING_BLOCK_SIZE] = {
 0xbb, 0xff, 0xf7, 0xff, 0xf7, 0x7f, 0x7b, 0xde,
 };
 
+#define EXCSD_BUS_WIDTH_OFFSET 183
+#define BUS_WIDTH_8_MASK0x4
+#define BUS_WIDTH_4_MASK0x2
+#define MMC_TUNING_BLOCK_SIZE   128
+
+static const uint8_t mmc_tunning_block_pattern[128] = {
+   0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00,
+   0xff, 0xff, 0xcc, 0xcc, 0xcc, 0x33, 0xcc, 0xcc,
+   0xcc, 0x33, 0x33, 0xcc, 0xcc, 0xcc, 0xff, 0xff,
+   0xff, 0xee, 0xff, 0xff, 0xff, 0xee, 0xee, 0xff,
+   0xff, 0xff, 0xdd, 0xff, 0xff, 0xff, 0xdd, 0xdd,
+   0xff, 0xff, 0xff, 0xbb, 0xff, 0xff, 0xff, 0xbb,
+   0xbb, 0xff, 0xff, 0xff, 0x77, 0xff, 0xff, 0xff,
+   0x77, 0x77, 0xff, 0x77, 0xbb, 0xdd, 0xee, 0xff,
+   0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00,
+   0x00, 0xff, 0xff, 0xcc, 0xcc, 0xcc, 0x33, 0xcc,
+   0xcc, 0xcc, 0x33, 0x33, 0xcc, 0xcc, 0xcc, 0xff,
+   0xff, 0xff, 0xee, 0xff, 0xff, 0xff, 0xee, 0xee,
+   0xff, 0xff, 0xff, 0xdd, 0xff, 0xff, 0xff, 0xdd,
+   0xdd, 0xff, 0xff, 0xff, 0xbb, 0xff, 0xff, 0xff,
+   0xbb, 0xbb, 0xff, 0xff, 0xff, 0x77, 0xff, 0xff,
+   0xff, 0x77, 0x77, 0xff, 0x77, 0xbb, 0xdd, 0xee,
+};
+
 uint8_t sd_read_byte(SDState *sd)
 {
 /* TODO: Append CRCs */
@@ -2204,6 +2236,21 @@ uint8_t sd_read_byte(SDState *sd)
 ret = sd_tuning_block_pattern[sd->data_offset++];
 break;
 
+case 21:/* CMD21: SEND_TUNNING_BLOCK (MMC) */
+if (sd->data_offset >= MMC_TUNING_BLOCK_SIZE - 1) {
+sd->state = sd_transfer_state;
+}
+if (sd->ext_csd[EXCSD_BUS_WIDTH_OFFSET] & BUS_WIDTH_8_MASK) {
+ret = mmc_tunning_block_pattern[sd->data_offset++];
+} else {
+/* Return LSB Nibbles of two byte from the 8bit tuning block
+ * for 4bit mode
+ */
+ret = mmc_tunning_block_pattern[sd->data_offset++] & 0x0F;
+ret |= (mmc_tunning_block_pattern[sd->data_offset++] & 0x0F) << 4;
+}
+break;
+
 case 22:   /* ACMD22: SEND_NUM_WR_BLOCKS */
 ret = sd->data[sd->data_offset ++];
 
-- 
2.7.4




[RFC PATCH 13/15] sd: emmc: Subtract bootarea size from blk

2021-02-11 Thread Sai Pavan Boddu
From: Joel Stanley 

The userdata size is derived from the file the user passes on the
command line, but we must take into account the boot areas.

Signed-off-by: Joel Stanley 
Signed-off-by: Cédric Le Goater 
---
 hw/sd/sd.c | 5 +
 1 file changed, 5 insertions(+)

diff --git a/hw/sd/sd.c b/hw/sd/sd.c
index 55c1104..a2f39c9 100644
--- a/hw/sd/sd.c
+++ b/hw/sd/sd.c
@@ -658,6 +658,11 @@ static void sd_reset(DeviceState *dev)
 }
 size = sect << 9;
 
+if (sd->emmc) {
+unsigned int boot_capacity = sd->ext_csd[EXT_CSD_BOOT_MULT] << 17;
+size -= boot_capacity * 2;
+}
+
 sect = sd_addr_to_wpnum(size) + 1;
 
 sd->state = sd_idle_state;
-- 
2.7.4




[RFC PATCH 03/15] sd: emmc: Dont not update CARD_CAPACITY for eMMC cards

2021-02-11 Thread Sai Pavan Boddu
OCR.CARD_CAPACITY field is only valid for sd cards, So skip it for eMMC.

Signed-off-by: Sai Pavan Boddu 
Signed-off-by: Edgar E. Iglesias 
---
 hw/sd/sd.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/hw/sd/sd.c b/hw/sd/sd.c
index a75fa1c..57fff89 100644
--- a/hw/sd/sd.c
+++ b/hw/sd/sd.c
@@ -308,7 +308,8 @@ static void sd_ocr_powerup(void *opaque)
 /* card power-up OK */
 sd->ocr = FIELD_DP32(sd->ocr, OCR, CARD_POWER_UP, 1);
 
-if (sd->size > SDSC_MAX_CAPACITY) {
+/* eMMC supports only Byte mode */
+if (!sd->emmc && sd->size > SDSC_MAX_CAPACITY) {
 sd->ocr = FIELD_DP32(sd->ocr, OCR, CARD_CAPACITY, 1);
 }
 }
-- 
2.7.4




[RFC PATCH 08/15] sd: emmc: Make ACMD41 illegal for mmc

2021-02-11 Thread Sai Pavan Boddu
ACMD41 is not applicable for eMMC.

Signed-off-by: Sai Pavan Boddu 
Signed-off-by: Edgar E. Iglesias 
---
 hw/sd/sd.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/hw/sd/sd.c b/hw/sd/sd.c
index 90359f6..236f2b8 100644
--- a/hw/sd/sd.c
+++ b/hw/sd/sd.c
@@ -1729,6 +1729,9 @@ static sd_rsp_type_t sd_app_command(SDState *sd,
 break;
 
 case 41:   /* ACMD41: SD_APP_OP_COND */
+if (sd->emmc) {
+break;
+}
 if (sd->spi) {
 /* SEND_OP_CMD */
 sd->state = sd_transfer_state;
-- 
2.7.4




[RFC PATCH 09/15] sd: emmc: Add support for emmc erase

2021-02-11 Thread Sai Pavan Boddu
Add CMD35 and CMD36 which sets the erase start and end.

Signed-off-by: Sai Pavan Boddu 
Signed-off-by: Edgar E. Iglesias 
---
 hw/sd/sd.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/hw/sd/sd.c b/hw/sd/sd.c
index 236f2b8..7aab647 100644
--- a/hw/sd/sd.c
+++ b/hw/sd/sd.c
@@ -1544,6 +1544,7 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, 
SDRequest req)
 
 /* Erase commands (Class 5) */
 case 32:   /* CMD32:  ERASE_WR_BLK_START */
+case 35:
 switch (sd->state) {
 case sd_transfer_state:
 sd->erase_start = req.arg;
@@ -1555,6 +1556,7 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, 
SDRequest req)
 break;
 
 case 33:   /* CMD33:  ERASE_WR_BLK_END */
+case 36:
 switch (sd->state) {
 case sd_transfer_state:
 sd->erase_end = req.arg;
-- 
2.7.4




[RFC PATCH 06/15] sd: emmc: Add mmc switch function support

2021-02-11 Thread Sai Pavan Boddu
switch operation in eMMC card updates the ext_csd register to
request changes in card operations. Here we implement similar
sequence but requests are mostly dummy and make no change.

Implement SWITCH_ERROR if the write operation extends goes beyond length
of ext_csd.

Signed-off-by: Sai Pavan Boddu 
Signed-off-by: Edgar E. Iglesias 
---
 hw/sd/sd.c | 56 ++--
 1 file changed, 50 insertions(+), 6 deletions(-)

diff --git a/hw/sd/sd.c b/hw/sd/sd.c
index 69289e0..7925174 100644
--- a/hw/sd/sd.c
+++ b/hw/sd/sd.c
@@ -519,6 +519,7 @@ static void sd_set_rca(SDState *sd, uint16_t value)
 FIELD(CSR, AKE_SEQ_ERROR,   3,  1)
 FIELD(CSR, APP_CMD, 5,  1)
 FIELD(CSR, FX_EVENT,6,  1)
+FIELD(CSR, SWITCH_ERROR,7,  1)
 FIELD(CSR, READY_FOR_DATA,  8,  1)
 FIELD(CSR, CURRENT_STATE,   9,  4)
 FIELD(CSR, ERASE_RESET,13,  1)
@@ -878,6 +879,43 @@ static uint32_t sd_wpbits(SDState *sd, uint64_t addr)
 return ret;
 }
 
+enum {
+MMC_CMD6_ACCESS_COMMAND_SET = 0,
+MMC_CMD6_ACCESS_SET_BITS,
+MMC_CMD6_ACCESS_CLEAR_BITS,
+MMC_CMD6_ACCESS_WRITE_BYTE,
+};
+
+static void mmc_function_switch(SDState *sd, uint32_t arg)
+{
+uint32_t access = extract32(arg, 24, 2);
+uint32_t index = extract32(arg, 16, 8);
+uint32_t value = extract32(arg, 8, 8);
+uint8_t b = sd->ext_csd[index];
+
+switch (access) {
+case MMC_CMD6_ACCESS_COMMAND_SET:
+qemu_log_mask(LOG_UNIMP, "MMC Command set switching not supported\n");
+return;
+case MMC_CMD6_ACCESS_SET_BITS:
+b |= value;
+break;
+case MMC_CMD6_ACCESS_CLEAR_BITS:
+b &= ~value;
+break;
+case MMC_CMD6_ACCESS_WRITE_BYTE:
+b = value;
+break;
+}
+
+if (index >= 192) {
+sd->card_status |= R_CSR_SWITCH_ERROR_MASK;
+return;
+}
+
+sd->ext_csd[index] = b;
+}
+
 static void sd_function_switch(SDState *sd, uint32_t arg)
 {
 int i, mode, new_func;
@@ -1097,12 +1135,18 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, 
SDRequest req)
 case 6:/* CMD6:   SWITCH_FUNCTION */
 switch (sd->mode) {
 case sd_data_transfer_mode:
-sd_function_switch(sd, req.arg);
-sd->state = sd_sendingdata_state;
-sd->data_start = 0;
-sd->data_offset = 0;
-return sd_r1;
-
+if (sd->emmc) {
+sd->state = sd_programming_state;
+mmc_function_switch(sd, req.arg);
+sd->state = sd_transfer_state;
+return sd_r1b;
+} else {
+sd_function_switch(sd, req.arg);
+sd->state = sd_sendingdata_state;
+sd->data_start = 0;
+sd->data_offset = 0;
+return sd_r1;
+}
 default:
 break;
 }
-- 
2.7.4




[RFC PATCH 02/15] sd: add eMMC support

2021-02-11 Thread Sai Pavan Boddu
From: Vincent Palatin 

The parameters mimick a real 4GB eMMC, but it can be set to various
sizes.

Signed-off-by: Vincent Palatin 
[SPB: Rebased the patch over qemu 5.1,
  Mark eMMC to support all timing modes]
Signed-off-by: Sai Pavan Boddu 
Signed-off-by: Joel Stanley 
Signed-off-by: Cédric Le Goater 
---
 hw/sd/sd.c | 143 +
 hw/sd/sdmmc-internal.c |   2 +-
 2 files changed, 122 insertions(+), 23 deletions(-)

diff --git a/hw/sd/sd.c b/hw/sd/sd.c
index 8517dbc..a75fa1c 100644
--- a/hw/sd/sd.c
+++ b/hw/sd/sd.c
@@ -108,6 +108,7 @@ struct SDState {
 uint8_t spec_version;
 BlockBackend *blk;
 bool spi;
+bool emmc;
 
 /* Runtime changeables */
 
@@ -134,6 +135,7 @@ struct SDState {
 uint64_t data_start;
 uint32_t data_offset;
 uint8_t data[512];
+uint8_t ext_csd[512];
 qemu_irq readonly_cb;
 qemu_irq inserted_cb;
 QEMUTimer *ocr_power_timer;
@@ -287,7 +289,8 @@ FIELD(OCR, CARD_POWER_UP,  31,  1)
| R_OCR_ACCEPT_SWITCH_1V8_MASK \
| R_OCR_UHS_II_CARD_MASK \
| R_OCR_CARD_CAPACITY_MASK \
-   | R_OCR_CARD_POWER_UP_MASK)
+   | R_OCR_CARD_POWER_UP_MASK \
+   | R_OCR_DUAL_VOLTAGE_CARD_MASK)
 
 static void sd_set_ocr(SDState *sd)
 {
@@ -371,6 +374,51 @@ static const uint8_t sd_csd_rw_mask[16] = {
 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xfe,
 };
 
+static void mmc_set_ext_csd(SDState *sd, uint64_t size)
+{
+uint32_t sectcount = size >> HWBLOCK_SHIFT;
+
+memset(sd->ext_csd, 0, 512);
+sd->ext_csd[504] = 0x1; /* supported command sets */
+sd->ext_csd[503] = 0x1; /* HPI features  */
+sd->ext_csd[502] = 0x1; /* Background operations support */
+sd->ext_csd[241] = 0xA; /* 1st initialization time after partitioning */
+sd->ext_csd[232] = 0x1; /* Trim multiplier */
+sd->ext_csd[231] = 0x15; /* Secure feature support */
+sd->ext_csd[230] = 0x96; /* Secure erase support */
+sd->ext_csd[229] = 0x96; /* Secure TRIM multiplier */
+sd->ext_csd[228] = 0x7; /* Boot information */
+sd->ext_csd[226] = 0x8; /* Boot partition size */
+sd->ext_csd[225] = 0x6; /* Access size */
+sd->ext_csd[224] = 0x4; /* HC Erase unit size */
+sd->ext_csd[223] = 0x1; /* HC erase timeout */
+sd->ext_csd[222] = 0x1; /* Reliable write sector count */
+sd->ext_csd[221] = 0x4; /* HC write protect group size */
+sd->ext_csd[220] = 0x8; /* Sleep current VCC  */
+sd->ext_csd[219] = 0x7; /* Sleep current VCCQ */
+sd->ext_csd[217] = 0x11; /* Sleep/Awake timeout */
+sd->ext_csd[215] = (sectcount >> 24) & 0xff; /* Sector count */
+sd->ext_csd[214] = (sectcount >> 16) & 0xff; /* ... */
+sd->ext_csd[213] = (sectcount >> 8) & 0xff;  /* ... */
+sd->ext_csd[212] = (sectcount & 0xff);   /* ... */
+sd->ext_csd[210] = 0xa; /* Min write perf for 8bit@52Mhz */
+sd->ext_csd[209] = 0xa; /* Min read perf for 8bit@52Mhz  */
+sd->ext_csd[208] = 0xa; /* Min write perf for 4bit@52Mhz */
+sd->ext_csd[207] = 0xa; /* Min read perf for 4bit@52Mhz */
+sd->ext_csd[206] = 0xa; /* Min write perf for 4bit@26Mhz */
+sd->ext_csd[205] = 0xa; /* Min read perf for 4bit@26Mhz */
+sd->ext_csd[199] = 0x1; /* Partition switching timing */
+sd->ext_csd[198] = 0x1; /* Out-of-interrupt busy timing */
+sd->ext_csd[196] = 0xFF; /* Card type */
+sd->ext_csd[194] = 0x2; /* CSD Structure version */
+sd->ext_csd[192] = 0x5; /* Extended CSD revision */
+sd->ext_csd[168] = 0x1; /* RPMB size */
+sd->ext_csd[160] = 0x3; /* Partinioning support */
+sd->ext_csd[159] = 0x00; /* Max enhanced area size */
+sd->ext_csd[158] = 0x00; /* ... */
+sd->ext_csd[157] = 0xEC; /* ... */
+}
+
 static void sd_set_csd(SDState *sd, uint64_t size)
 {
 int hwblock_shift = HWBLOCK_SHIFT;
@@ -384,7 +432,34 @@ static void sd_set_csd(SDState *sd, uint64_t size)
 }
 csize = (size >> (CMULT_SHIFT + hwblock_shift)) - 1;
 
-if (size <= SDSC_MAX_CAPACITY) { /* Standard Capacity SD */
+if (sd->emmc) { /* eMMC */
+sd->csd[0] = 0xd0;
+sd->csd[1] = 0x0f;
+sd->csd[2] = 0x00;
+sd->csd[3] = 0x32;
+sd->csd[4] = 0x0f;
+if (size <= 0x8000ULL) {
+/* use 1k blocks */
+uint32_t csize1k = (size >> (CMULT_SHIFT + 10)) - 1;
+sd->csd[5] = 0x5a;
+sd->csd[6] = 0x80 | ((csize1k >> 10) & 0xf);
+sd->csd[7] = (csize1k >> 2) & 0xff;
+} else { /* >= 2GB : size stored in ext CSD, block addressing */
+sd->csd[5] = 0x59;
+ 

[RFC PATCH 05/15] sd: emmc: support idle state in CMD2

2021-02-11 Thread Sai Pavan Boddu
eMMC is expected to be in idle-state post CMD1. Ready state is an
intermediate stage which we don't come across in Device identification
mode.

Signed-off-by: Sai Pavan Boddu 
Signed-off-by: Edgar E. Iglesias 
---
 hw/sd/sd.c | 4 
 1 file changed, 4 insertions(+)

diff --git a/hw/sd/sd.c b/hw/sd/sd.c
index e3738b2..69289e0 100644
--- a/hw/sd/sd.c
+++ b/hw/sd/sd.c
@@ -1051,6 +1051,10 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, 
SDRequest req)
 if (sd->spi)
 goto bad_cmd;
 switch (sd->state) {
+case sd_idle_state:
+if (!sd->emmc) {
+break;
+}
 case sd_ready_state:
 sd->state = sd_identification_state;
 return sd_r2_i;
-- 
2.7.4




[RFC PATCH 04/15] sd: emmc: Update CMD1 definition for eMMC

2021-02-11 Thread Sai Pavan Boddu
Add support to Power up the card and send response r3 in case of eMMC.

Signed-off-by: Sai Pavan Boddu 
Signed-off-by: Edgar E. Iglesias 
---
 hw/sd/sd.c | 10 +-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/hw/sd/sd.c b/hw/sd/sd.c
index 57fff89..e3738b2 100644
--- a/hw/sd/sd.c
+++ b/hw/sd/sd.c
@@ -1033,8 +1033,16 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, 
SDRequest req)
 break;
 
 case 1:/* CMD1:   SEND_OP_CMD */
-if (!sd->spi)
+/* MMC: Powerup & send r3
+ * SD: send r1 in spi mode
+ */
+if (sd->emmc) {
+sd_ocr_powerup(sd);
+return sd->state == sd_idle_state ?
+   sd_r3 : sd_r0;
+} else if (!sd->spi) {
 goto bad_cmd;
+}
 
 sd->state = sd_transfer_state;
 return sd_r1;
-- 
2.7.4




[RFC PATCH 12/15] sd: emmc: Support boot area in emmc image

2021-02-11 Thread Sai Pavan Boddu
From: Joel Stanley 

This assumes a specially constructued image:

  dd if=/dev/zero of=mmc-bootarea.img count=2 bs=1M
  dd if=u-boot-spl.bin of=mmc-bootarea.img conv=notrunc
  dd if=u-boot.bin of=mmc-bootarea.img conv=notrunc count=64 bs=1K
  cat mmc-bootarea.img obmc-phosphor-image.wic > mmc.img
  truncate --size 16GB mmc.img
  truncate --size 128MB mmc-bootarea.img

Signed-off-by: Joel Stanley 
[clg: - changes on the definition names ]
Signed-off-by: Cédric Le Goater 
[spb: use data_start property to access right emmc partition,
  Clean up PARTITION_ENABLE support as incomplete,
  Fix commit message to be generic.]
Signed-off-by: Sai Pavan Boddu 
---
 hw/sd/sd.c | 40 
 1 file changed, 40 insertions(+)

diff --git a/hw/sd/sd.c b/hw/sd/sd.c
index 54fba7b..55c1104 100644
--- a/hw/sd/sd.c
+++ b/hw/sd/sd.c
@@ -1045,6 +1045,34 @@ static void sd_lock_command(SDState *sd)
 sd->card_status &= ~CARD_IS_LOCKED;
 }
 
+/*
+ * This requires a disk image that has two boot partitions inserted at the
+ * beginning of it. The size of the boot partitions are configured in the
+ * ext_csd structure, which is hardcoded in qemu. They are currently set to
+ * 1MB each.
+ */
+static uint32_t sd_bootpart_offset(SDState *sd)
+{
+unsigned int access = sd->ext_csd[EXT_CSD_PART_CONFIG] &
+EXT_CSD_PART_CONFIG_ACC_MASK;
+unsigned int boot_capacity = sd->ext_csd[EXT_CSD_BOOT_MULT] << 17;
+
+if (!sd->emmc) {
+return 0;
+}
+
+switch (access) {
+case EXT_CSD_PART_CONFIG_ACC_DEFAULT:
+return boot_capacity * 2;
+case EXT_CSD_PART_CONFIG_ACC_BOOT0:
+return 0;
+case EXT_CSD_PART_CONFIG_ACC_BOOT0 + 1:
+return boot_capacity * 1;
+default:
+ g_assert_not_reached();
+}
+}
+
 static sd_rsp_type_t sd_normal_command(SDState *sd, SDRequest req)
 {
 uint32_t rca = 0x;
@@ -1360,6 +1388,9 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, 
SDRequest req)
 return sd_r1;
 }
 
+if (sd->emmc) {
+addr += sd_bootpart_offset(sd);
+}
 sd->state = sd_sendingdata_state;
 sd->data_start = addr;
 sd->data_offset = 0;
@@ -1379,6 +1410,9 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, 
SDRequest req)
 return sd_r1;
 }
 
+if (sd->emmc) {
+addr += sd_bootpart_offset(sd);
+}
 sd->state = sd_sendingdata_state;
 sd->data_start = addr;
 sd->data_offset = 0;
@@ -1435,6 +1469,9 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, 
SDRequest req)
 return sd_r1;
 }
 
+if (sd->emmc) {
+addr += sd_bootpart_offset(sd);
+}
 sd->state = sd_receivingdata_state;
 sd->data_start = addr;
 sd->data_offset = 0;
@@ -1465,6 +1502,9 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, 
SDRequest req)
 return sd_r1;
 }
 
+if (sd->emmc) {
+addr += sd_bootpart_offset(sd);
+}
 sd->state = sd_receivingdata_state;
 sd->data_start = addr;
 sd->data_offset = 0;
-- 
2.7.4




[RFC PATCH 01/15] block: add eMMC block device type

2021-02-11 Thread Sai Pavan Boddu
From: Vincent Palatin 

Add new block device type.

Signed-off-by: Vincent Palatin 
[SPB: Rebased over 5.1 version]
Signed-off-by: Sai Pavan Boddu 
Signed-off-by: Joel Stanley 
Signed-off-by: Cédric Le Goater 
---
 blockdev.c| 1 +
 include/sysemu/blockdev.h | 1 +
 2 files changed, 2 insertions(+)

diff --git a/blockdev.c b/blockdev.c
index b250b9b..593ce44 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -83,6 +83,7 @@ static const char *const if_name[IF_COUNT] = {
 [IF_SD] = "sd",
 [IF_VIRTIO] = "virtio",
 [IF_XEN] = "xen",
+[IF_EMMC] = "emmc",
 };
 
 static int if_max_devs[IF_COUNT] = {
diff --git a/include/sysemu/blockdev.h b/include/sysemu/blockdev.h
index 3b5fcda..eefae9f 100644
--- a/include/sysemu/blockdev.h
+++ b/include/sysemu/blockdev.h
@@ -24,6 +24,7 @@ typedef enum {
  */
 IF_NONE = 0,
 IF_IDE, IF_SCSI, IF_FLOPPY, IF_PFLASH, IF_MTD, IF_SD, IF_VIRTIO, IF_XEN,
+IF_EMMC,
 IF_COUNT
 } BlockInterfaceType;
 
-- 
2.7.4




  1   2   3   4   5   >