[PATCH v8 2/3] backends: Initial support for SPDM socket support

2024-07-03 Thread Alistair Francis
From: Huai-Cheng Kuo 

SPDM enables authentication, attestation and key exchange to assist in
providing infrastructure security enablement. It's a standard published
by the DMTF [1].

SPDM supports multiple transports, including PCIe DOE and MCTP.
This patch adds support to QEMU to connect to an external SPDM
instance.

SPDM support can be added to any QEMU device by exposing a
TCP socket to a SPDM server. The server can then implement the SPDM
decoding/encoding support, generally using libspdm [2].

This is similar to how the current TPM implementation works and means
that the heavy lifting of setting up certificate chains, capabilities,
measurements and complex crypto can be done outside QEMU by a well
supported and tested library.

1: https://www.dmtf.org/standards/SPDM
2: https://github.com/DMTF/libspdm

Signed-off-by: Huai-Cheng Kuo 
Signed-off-by: Chris Browy 
Co-developed-by: Jonathan Cameron 
Signed-off-by: Jonathan Cameron 
[ Changes by WM
 - Bug fixes from testing
]
Signed-off-by: Wilfred Mallawa 
[ Changes by AF:
 - Convert to be more QEMU-ified
 - Move to backends as it isn't PCIe specific
]
Signed-off-by: Alistair Francis 
---
 MAINTAINERS  |   6 +
 include/sysemu/spdm-socket.h |  74 
 backends/spdm-socket.c   | 216 +++
 backends/Kconfig |   4 +
 backends/meson.build |   2 +
 5 files changed, 302 insertions(+)
 create mode 100644 include/sysemu/spdm-socket.h
 create mode 100644 backends/spdm-socket.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 6725913c8b..c76a0cfe12 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -3397,6 +3397,12 @@ F: tests/qtest/*tpm*
 F: docs/specs/tpm.rst
 T: git https://github.com/stefanberger/qemu-tpm.git tpm-next
 
+SPDM
+M: Alistair Francis 
+S: Maintained
+F: backends/spdm-socket.c
+F: include/sysemu/spdm-socket.h
+
 Checkpatch
 S: Odd Fixes
 F: scripts/checkpatch.pl
diff --git a/include/sysemu/spdm-socket.h b/include/sysemu/spdm-socket.h
new file mode 100644
index 00..5d8bd9aa4e
--- /dev/null
+++ b/include/sysemu/spdm-socket.h
@@ -0,0 +1,74 @@
+/*
+ * QEMU SPDM socket support
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to 
deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#ifndef SPDM_REQUESTER_H
+#define SPDM_REQUESTER_H
+
+/**
+ * spdm_socket_connect: connect to an external SPDM socket
+ * @port: port to connect to
+ * @errp: error object handle
+ *
+ * This will connect to an external SPDM socket server. On error
+ * it will return -1 and errp will be set. On success this function
+ * will return the socket number.
+ */
+int spdm_socket_connect(uint16_t port, Error **errp);
+
+/**
+ * spdm_socket_rsp: send and receive a message to a SPDM server
+ * @socket: socket returned from spdm_socket_connect()
+ * @transport_type: SPDM_SOCKET_TRANSPORT_TYPE_* macro
+ * @req: request buffer
+ * @req_len: request buffer length
+ * @rsp: response buffer
+ * @rsp_len: response buffer length
+ *
+ * Send platform data to a SPDM server on socket and then receive
+ * a response.
+ */
+uint32_t spdm_socket_rsp(const int socket, uint32_t transport_type,
+ void *req, uint32_t req_len,
+ void *rsp, uint32_t rsp_len);
+
+/**
+ * spdm_socket_close: send a shutdown command to the server
+ * @socket: socket returned from spdm_socket_connect()
+ * @transport_type: SPDM_SOCKET_TRANSPORT_TYPE_* macro
+ *
+ * This will issue a shutdown command to the server.
+ */
+void spdm_socket_close(const int socket, uint32_t transport_type);
+
+#define SPDM_SOCKET_COMMAND_NORMAL0x0001
+#define SPDM_SOCKET_COMMAND_OOB_ENCAP_KEY_UPDATE  0x8001
+#define SPDM_SOCKET_COMMAND_CONTINUE  0xFFFD
+#define SPDM_SOCKET_COMMAND_SHUTDOWN  0xFFFE
+#define SPDM_SOCKET_COMMAND_UNKOWN0x
+#define SPDM_SOCKET_COMMAND_TEST  0xDEAD
+
+#define SPDM_SOCKET_TRANSPORT_TYPE_MCTP

[PATCH v8 3/3] hw/nvme: Add SPDM over DOE support

2024-07-03 Thread Alistair Francis
From: Wilfred Mallawa 

Setup Data Object Exchange (DOE) as an extended capability for the NVME
controller and connect SPDM to it (CMA) to it.

Signed-off-by: Wilfred Mallawa 
Signed-off-by: Alistair Francis 
Reviewed-by: Jonathan Cameron 
Acked-by: Klaus Jensen 
---
 docs/specs/index.rst|   1 +
 docs/specs/spdm.rst | 134 
 include/hw/pci/pci_device.h |   7 ++
 include/hw/pci/pcie_doe.h   |   3 +
 hw/nvme/ctrl.c  |  62 +
 5 files changed, 207 insertions(+)
 create mode 100644 docs/specs/spdm.rst

diff --git a/docs/specs/index.rst b/docs/specs/index.rst
index 1484e3e760..e2d907959a 100644
--- a/docs/specs/index.rst
+++ b/docs/specs/index.rst
@@ -29,6 +29,7 @@ guest hardware that is specific to QEMU.
edu
ivshmem-spec
pvpanic
+   spdm
standard-vga
virt-ctlr
vmcoreinfo
diff --git a/docs/specs/spdm.rst b/docs/specs/spdm.rst
new file mode 100644
index 00..f7de080ff0
--- /dev/null
+++ b/docs/specs/spdm.rst
@@ -0,0 +1,134 @@
+==
+QEMU Security Protocols and Data Models (SPDM) Support
+==
+
+SPDM enables authentication, attestation and key exchange to assist in
+providing infrastructure security enablement. It's a standard published
+by the `DMTF`_.
+
+QEMU supports connecting to a SPDM responder implementation. This allows an
+external application to emulate the SPDM responder logic for an SPDM device.
+
+Setting up a SPDM server
+
+
+When using QEMU with SPDM devices QEMU will connect to a server which
+implements the SPDM functionality.
+
+SPDM-Utils
+--
+
+You can use `SPDM Utils`_ to emulate a responder. This is the simplest method.
+
+SPDM-Utils is a Linux applications to manage, test and develop devices
+supporting DMTF Security Protocol and Data Model (SPDM). It is written in Rust
+and utilises libspdm.
+
+To use SPDM-Utils you will need to do the following steps. Details are included
+in the SPDM-Utils README.
+
+ 1. `Build libspdm`_
+ 2. `Build SPDM Utils`_
+ 3. `Run it as a server`_
+
+spdm-emu
+
+
+You can use `spdm emu`_ to model the
+SPDM responder.
+
+.. code-block:: shell
+
+$ cd spdm-emu
+$ git submodule init; git submodule update --recursive
+$ mkdir build; cd build
+$ cmake -DARCH=x64 -DTOOLCHAIN=GCC -DTARGET=Debug -DCRYPTO=openssl ..
+$ make -j32
+$ make copy_sample_key # Build certificates, required for SPDM 
authentication.
+
+It is worth noting that the certificates should be in compliance with
+PCIe r6.1 sec 6.31.3. This means you will need to add the following to
+openssl.cnf
+
+.. code-block::
+
+subjectAltName = 
otherName:2.23.147;UTF8:Vendor=1b36:Device=0010:CC=010802:REV=02:SSVID=1af4:SSID=1100
+2.23.147 = ASN1:OID:2.23.147
+
+and then manually regenerate some certificates with:
+
+.. code-block:: shell
+
+$ openssl req -nodes -newkey ec:param.pem -keyout end_responder.key \
+-out end_responder.req -sha384 -batch \
+-subj "/CN=DMTF libspdm ECP384 responder cert"
+
+$ openssl x509 -req -in end_responder.req -out end_responder.cert \
+-CA inter.cert -CAkey inter.key -sha384 -days 3650 -set_serial 3 \
+-extensions v3_end -extfile ../openssl.cnf
+
+$ openssl asn1parse -in end_responder.cert -out end_responder.cert.der
+
+$ cat ca.cert.der inter.cert.der end_responder.cert.der > 
bundle_responder.certchain.der
+
+You can use SPDM-Utils instead as it will generate the correct certificates
+automatically.
+
+The responder can then be launched with
+
+.. code-block:: shell
+
+$ cd bin
+$ ./spdm_responder_emu --trans PCI_DOE
+
+Connecting an SPDM NVMe device
+==
+
+Once a SPDM server is running we can start QEMU and connect to the server.
+
+For an NVMe device first let's setup a block we can use
+
+.. code-block:: shell
+
+$ cd qemu-spdm/linux/image
+$ dd if=/dev/zero of=blknvme bs=1M count=2096 # 2GB NNMe Drive
+
+Then you can add this to your QEMU command line:
+
+.. code-block:: shell
+
+-drive file=blknvme,if=none,id=mynvme,format=raw \
+-device nvme,drive=mynvme,serial=deadbeef,spdm_port=2323
+
+At which point QEMU will try to connect to the SPDM server.
+
+Note that if using x64-64 you will want to use the q35 machine instead
+of the default. So the entire QEMU command might look like this
+
+.. code-block:: shell
+
+qemu-system-x86_64 -M q35 \
+--kernel bzImage \
+-drive file=rootfs.ext2,if=virtio,format=raw \
+-append "root=/dev/vda console=ttyS0" \
+-net none -nographic \
+-drive file=blknvme,if=none,id=mynvme,format=raw \
+-device nvme,drive=mynvme,serial=deadbeef,spdm_port=2323
+
+.. _DMTF:
+   https://www.dmtf.org/standards/SPDM
+
+.. _SPDM Utils:
+   https://github.com/westerndigitalcorporation/spdm-utils
+
+.. _spdm emu:

[PATCH v8 1/3] hw/pci: Add all Data Object Types defined in PCIe r6.0

2024-07-03 Thread Alistair Francis
Add all of the defined protocols/features from the PCIe-SIG r6.0
"Table 6-32 PCI-SIG defined Data Object Types (Vendor ID = 0001h)"
table.

Signed-off-by: Alistair Francis 
Reviewed-by: Jonathan Cameron 
Reviewed-by: Wilfred Mallawa 
---
 include/hw/pci/pcie_doe.h | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/include/hw/pci/pcie_doe.h b/include/hw/pci/pcie_doe.h
index 87dc17dcef..15d94661f9 100644
--- a/include/hw/pci/pcie_doe.h
+++ b/include/hw/pci/pcie_doe.h
@@ -46,6 +46,8 @@ REG32(PCI_DOE_CAP_STATUS, 0)
 
 /* PCI-SIG defined Data Object Types - r6.0 Table 6-32 */
 #define PCI_SIG_DOE_DISCOVERY   0x00
+#define PCI_SIG_DOE_CMA 0x01
+#define PCI_SIG_DOE_SECURED_CMA 0x02
 
 #define PCI_DOE_DW_SIZE_MAX (1 << 18)
 #define PCI_DOE_PROTOCOL_NUM_MAX256
-- 
2.45.2




[PATCH v8 0/3] Initial support for SPDM Responders

2024-07-03 Thread Alistair Francis
The Security Protocol and Data Model (SPDM) Specification defines
messages, data objects, and sequences for performing message exchanges
over a variety of transport and physical media.
 - 
https://www.dmtf.org/sites/default/files/standards/documents/DSP0274_1.3.0.pdf

SPDM currently supports PCIe DOE and MCTP transports, but it can be
extended to support others in the future. This series adds
support to QEMU to connect to an external SPDM instance.

SPDM support can be added to any QEMU device by exposing a
TCP socket to a SPDM server. The server can then implement the SPDM
decoding/encoding support, generally using libspdm [1].

This is similar to how the current TPM implementation works and means
that the heavy lifting of setting up certificate chains, capabilities,
measurements and complex crypto can be done outside QEMU by a well
supported and tested library.

This series implements socket support and exposes SPDM for a NVMe device.

1: https://github.com/DMTF/libspdm

v8:
 - Fixup i386 failures (thanks to Wilfred)
 - Passes CI on GitLab: 
https://gitlab.com/alistair23/qemu/-/tree/mainline/alistair/spdm-socket.next?ref_type=heads
v7:
 - Fixup checkpatch failures
 - Fixup test failures
 - Rename port name to be clearer
v6:
 - Add documentation to public functions
 - Rename socket variable to spdm_socket
 - Don't override errp
 - Correctly return false from nvme_init_pci() on error
v5:
 - Update MAINTAINERS
v4:
 - Rebase
v3:
 - Spelling fixes
 - Support for SPDM-Utils
v2:
 - Add cover letter
 - A few code fixes based on comments
 - Document SPDM-Utils
 - A few tweaks and clarifications to the documentation

Alistair Francis (1):
  hw/pci: Add all Data Object Types defined in PCIe r6.0

Huai-Cheng Kuo (1):
  backends: Initial support for SPDM socket support

Wilfred Mallawa (1):
  hw/nvme: Add SPDM over DOE support

 MAINTAINERS  |   6 +
 docs/specs/index.rst |   1 +
 docs/specs/spdm.rst  | 134 ++
 include/hw/pci/pci_device.h  |   7 ++
 include/hw/pci/pcie_doe.h|   5 +
 include/sysemu/spdm-socket.h |  74 
 backends/spdm-socket.c   | 216 +++
 hw/nvme/ctrl.c   |  62 ++
 backends/Kconfig |   4 +
 backends/meson.build |   2 +
 10 files changed, 511 insertions(+)
 create mode 100644 docs/specs/spdm.rst
 create mode 100644 include/sysemu/spdm-socket.h
 create mode 100644 backends/spdm-socket.c

-- 
2.45.2




[PATCH v7 2/3] backends: Initial support for SPDM socket support

2024-06-13 Thread Alistair Francis
From: Huai-Cheng Kuo 

SPDM enables authentication, attestation and key exchange to assist in
providing infrastructure security enablement. It's a standard published
by the DMTF [1].

SPDM supports multiple transports, including PCIe DOE and MCTP.
This patch adds support to QEMU to connect to an external SPDM
instance.

SPDM support can be added to any QEMU device by exposing a
TCP socket to a SPDM server. The server can then implement the SPDM
decoding/encoding support, generally using libspdm [2].

This is similar to how the current TPM implementation works and means
that the heavy lifting of setting up certificate chains, capabilities,
measurements and complex crypto can be done outside QEMU by a well
supported and tested library.

1: https://www.dmtf.org/standards/SPDM
2: https://github.com/DMTF/libspdm

Signed-off-by: Huai-Cheng Kuo 
Signed-off-by: Chris Browy 
Co-developed-by: Jonathan Cameron 
Signed-off-by: Jonathan Cameron 
[ Changes by WM
 - Bug fixes from testing
]
Signed-off-by: Wilfred Mallawa 
[ Changes by AF:
 - Convert to be more QEMU-ified
 - Move to backends as it isn't PCIe specific
]
Signed-off-by: Alistair Francis 
---
 MAINTAINERS  |   6 +
 include/sysemu/spdm-socket.h |  74 
 backends/spdm-socket.c   | 216 +++
 backends/Kconfig |   4 +
 backends/meson.build |   2 +
 5 files changed, 302 insertions(+)
 create mode 100644 include/sysemu/spdm-socket.h
 create mode 100644 backends/spdm-socket.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 951556224a..aeac108586 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -3394,6 +3394,12 @@ F: tests/qtest/*tpm*
 F: docs/specs/tpm.rst
 T: git https://github.com/stefanberger/qemu-tpm.git tpm-next
 
+SPDM
+M: Alistair Francis 
+S: Maintained
+F: backends/spdm-socket.c
+F: include/sysemu/spdm-socket.h
+
 Checkpatch
 S: Odd Fixes
 F: scripts/checkpatch.pl
diff --git a/include/sysemu/spdm-socket.h b/include/sysemu/spdm-socket.h
new file mode 100644
index 00..5d8bd9aa4e
--- /dev/null
+++ b/include/sysemu/spdm-socket.h
@@ -0,0 +1,74 @@
+/*
+ * QEMU SPDM socket support
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to 
deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#ifndef SPDM_REQUESTER_H
+#define SPDM_REQUESTER_H
+
+/**
+ * spdm_socket_connect: connect to an external SPDM socket
+ * @port: port to connect to
+ * @errp: error object handle
+ *
+ * This will connect to an external SPDM socket server. On error
+ * it will return -1 and errp will be set. On success this function
+ * will return the socket number.
+ */
+int spdm_socket_connect(uint16_t port, Error **errp);
+
+/**
+ * spdm_socket_rsp: send and receive a message to a SPDM server
+ * @socket: socket returned from spdm_socket_connect()
+ * @transport_type: SPDM_SOCKET_TRANSPORT_TYPE_* macro
+ * @req: request buffer
+ * @req_len: request buffer length
+ * @rsp: response buffer
+ * @rsp_len: response buffer length
+ *
+ * Send platform data to a SPDM server on socket and then receive
+ * a response.
+ */
+uint32_t spdm_socket_rsp(const int socket, uint32_t transport_type,
+ void *req, uint32_t req_len,
+ void *rsp, uint32_t rsp_len);
+
+/**
+ * spdm_socket_close: send a shutdown command to the server
+ * @socket: socket returned from spdm_socket_connect()
+ * @transport_type: SPDM_SOCKET_TRANSPORT_TYPE_* macro
+ *
+ * This will issue a shutdown command to the server.
+ */
+void spdm_socket_close(const int socket, uint32_t transport_type);
+
+#define SPDM_SOCKET_COMMAND_NORMAL0x0001
+#define SPDM_SOCKET_COMMAND_OOB_ENCAP_KEY_UPDATE  0x8001
+#define SPDM_SOCKET_COMMAND_CONTINUE  0xFFFD
+#define SPDM_SOCKET_COMMAND_SHUTDOWN  0xFFFE
+#define SPDM_SOCKET_COMMAND_UNKOWN0x
+#define SPDM_SOCKET_COMMAND_TEST  0xDEAD
+
+#define SPDM_SOCKET_TRANSPORT_TYPE_MCTP

[PATCH v7 0/3] Initial support for SPDM Responders

2024-06-13 Thread Alistair Francis
The Security Protocol and Data Model (SPDM) Specification defines
messages, data objects, and sequences for performing message exchanges
over a variety of transport and physical media.
 - 
https://www.dmtf.org/sites/default/files/standards/documents/DSP0274_1.3.0.pdf

SPDM currently supports PCIe DOE and MCTP transports, but it can be
extended to support others in the future. This series adds
support to QEMU to connect to an external SPDM instance.

SPDM support can be added to any QEMU device by exposing a
TCP socket to a SPDM server. The server can then implement the SPDM
decoding/encoding support, generally using libspdm [1].

This is similar to how the current TPM implementation works and means
that the heavy lifting of setting up certificate chains, capabilities,
measurements and complex crypto can be done outside QEMU by a well
supported and tested library.

This series implements socket support and exposes SPDM for a NVMe device.

1: https://github.com/DMTF/libspdm

v7:
 - Fixup checkpatch failures
 - Fixup test failures
 - Rename port name to be clearer
v6:
 - Add documentation to public functions
 - Rename socket variable to spdm_socket
 - Don't override errp
 - Correctly return false from nvme_init_pci() on error
v5:
 - Update MAINTAINERS
v4:
 - Rebase
v3:
 - Spelling fixes
 - Support for SPDM-Utils
v2:
 - Add cover letter
 - A few code fixes based on comments
 - Document SPDM-Utils
 - A few tweaks and clarifications to the documentation

Alistair Francis (1):
  hw/pci: Add all Data Object Types defined in PCIe r6.0

Huai-Cheng Kuo (1):
  backends: Initial support for SPDM socket support

Wilfred Mallawa (1):
  hw/nvme: Add SPDM over DOE support

 MAINTAINERS  |   6 +
 docs/specs/index.rst |   1 +
 docs/specs/spdm.rst  | 134 ++
 include/hw/pci/pci_device.h  |   7 ++
 include/hw/pci/pcie_doe.h|   5 +
 include/sysemu/spdm-socket.h |  74 
 backends/spdm-socket.c   | 216 +++
 hw/nvme/ctrl.c   |  60 ++
 backends/Kconfig |   4 +
 backends/meson.build |   2 +
 10 files changed, 509 insertions(+)
 create mode 100644 docs/specs/spdm.rst
 create mode 100644 include/sysemu/spdm-socket.h
 create mode 100644 backends/spdm-socket.c

-- 
2.45.2




[PATCH v7 1/3] hw/pci: Add all Data Object Types defined in PCIe r6.0

2024-06-13 Thread Alistair Francis
Add all of the defined protocols/features from the PCIe-SIG r6.0
"Table 6-32 PCI-SIG defined Data Object Types (Vendor ID = 0001h)"
table.

Signed-off-by: Alistair Francis 
Reviewed-by: Jonathan Cameron 
---
 include/hw/pci/pcie_doe.h | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/include/hw/pci/pcie_doe.h b/include/hw/pci/pcie_doe.h
index 87dc17dcef..15d94661f9 100644
--- a/include/hw/pci/pcie_doe.h
+++ b/include/hw/pci/pcie_doe.h
@@ -46,6 +46,8 @@ REG32(PCI_DOE_CAP_STATUS, 0)
 
 /* PCI-SIG defined Data Object Types - r6.0 Table 6-32 */
 #define PCI_SIG_DOE_DISCOVERY   0x00
+#define PCI_SIG_DOE_CMA 0x01
+#define PCI_SIG_DOE_SECURED_CMA 0x02
 
 #define PCI_DOE_DW_SIZE_MAX (1 << 18)
 #define PCI_DOE_PROTOCOL_NUM_MAX256
-- 
2.45.2




[PATCH v7 3/3] hw/nvme: Add SPDM over DOE support

2024-06-13 Thread Alistair Francis
From: Wilfred Mallawa 

Setup Data Object Exchance (DOE) as an extended capability for the NVME
controller and connect SPDM to it (CMA) to it.

Signed-off-by: Wilfred Mallawa 
Signed-off-by: Alistair Francis 
Reviewed-by: Jonathan Cameron 
Acked-by: Klaus Jensen 
---
 docs/specs/index.rst|   1 +
 docs/specs/spdm.rst | 134 
 include/hw/pci/pci_device.h |   7 ++
 include/hw/pci/pcie_doe.h   |   3 +
 hw/nvme/ctrl.c  |  60 
 5 files changed, 205 insertions(+)
 create mode 100644 docs/specs/spdm.rst

diff --git a/docs/specs/index.rst b/docs/specs/index.rst
index 1484e3e760..e2d907959a 100644
--- a/docs/specs/index.rst
+++ b/docs/specs/index.rst
@@ -29,6 +29,7 @@ guest hardware that is specific to QEMU.
edu
ivshmem-spec
pvpanic
+   spdm
standard-vga
virt-ctlr
vmcoreinfo
diff --git a/docs/specs/spdm.rst b/docs/specs/spdm.rst
new file mode 100644
index 00..f7de080ff0
--- /dev/null
+++ b/docs/specs/spdm.rst
@@ -0,0 +1,134 @@
+==
+QEMU Security Protocols and Data Models (SPDM) Support
+==
+
+SPDM enables authentication, attestation and key exchange to assist in
+providing infrastructure security enablement. It's a standard published
+by the `DMTF`_.
+
+QEMU supports connecting to a SPDM responder implementation. This allows an
+external application to emulate the SPDM responder logic for an SPDM device.
+
+Setting up a SPDM server
+
+
+When using QEMU with SPDM devices QEMU will connect to a server which
+implements the SPDM functionality.
+
+SPDM-Utils
+--
+
+You can use `SPDM Utils`_ to emulate a responder. This is the simplest method.
+
+SPDM-Utils is a Linux applications to manage, test and develop devices
+supporting DMTF Security Protocol and Data Model (SPDM). It is written in Rust
+and utilises libspdm.
+
+To use SPDM-Utils you will need to do the following steps. Details are included
+in the SPDM-Utils README.
+
+ 1. `Build libspdm`_
+ 2. `Build SPDM Utils`_
+ 3. `Run it as a server`_
+
+spdm-emu
+
+
+You can use `spdm emu`_ to model the
+SPDM responder.
+
+.. code-block:: shell
+
+$ cd spdm-emu
+$ git submodule init; git submodule update --recursive
+$ mkdir build; cd build
+$ cmake -DARCH=x64 -DTOOLCHAIN=GCC -DTARGET=Debug -DCRYPTO=openssl ..
+$ make -j32
+$ make copy_sample_key # Build certificates, required for SPDM 
authentication.
+
+It is worth noting that the certificates should be in compliance with
+PCIe r6.1 sec 6.31.3. This means you will need to add the following to
+openssl.cnf
+
+.. code-block::
+
+subjectAltName = 
otherName:2.23.147;UTF8:Vendor=1b36:Device=0010:CC=010802:REV=02:SSVID=1af4:SSID=1100
+2.23.147 = ASN1:OID:2.23.147
+
+and then manually regenerate some certificates with:
+
+.. code-block:: shell
+
+$ openssl req -nodes -newkey ec:param.pem -keyout end_responder.key \
+-out end_responder.req -sha384 -batch \
+-subj "/CN=DMTF libspdm ECP384 responder cert"
+
+$ openssl x509 -req -in end_responder.req -out end_responder.cert \
+-CA inter.cert -CAkey inter.key -sha384 -days 3650 -set_serial 3 \
+-extensions v3_end -extfile ../openssl.cnf
+
+$ openssl asn1parse -in end_responder.cert -out end_responder.cert.der
+
+$ cat ca.cert.der inter.cert.der end_responder.cert.der > 
bundle_responder.certchain.der
+
+You can use SPDM-Utils instead as it will generate the correct certificates
+automatically.
+
+The responder can then be launched with
+
+.. code-block:: shell
+
+$ cd bin
+$ ./spdm_responder_emu --trans PCI_DOE
+
+Connecting an SPDM NVMe device
+==
+
+Once a SPDM server is running we can start QEMU and connect to the server.
+
+For an NVMe device first let's setup a block we can use
+
+.. code-block:: shell
+
+$ cd qemu-spdm/linux/image
+$ dd if=/dev/zero of=blknvme bs=1M count=2096 # 2GB NNMe Drive
+
+Then you can add this to your QEMU command line:
+
+.. code-block:: shell
+
+-drive file=blknvme,if=none,id=mynvme,format=raw \
+-device nvme,drive=mynvme,serial=deadbeef,spdm_port=2323
+
+At which point QEMU will try to connect to the SPDM server.
+
+Note that if using x64-64 you will want to use the q35 machine instead
+of the default. So the entire QEMU command might look like this
+
+.. code-block:: shell
+
+qemu-system-x86_64 -M q35 \
+--kernel bzImage \
+-drive file=rootfs.ext2,if=virtio,format=raw \
+-append "root=/dev/vda console=ttyS0" \
+-net none -nographic \
+-drive file=blknvme,if=none,id=mynvme,format=raw \
+-device nvme,drive=mynvme,serial=deadbeef,spdm_port=2323
+
+.. _DMTF:
+   https://www.dmtf.org/standards/SPDM
+
+.. _SPDM Utils:
+   https://github.com/westerndigitalcorporation/spdm-utils
+
+.. _spdm emu:

[PATCH v6 2/3] backends: Initial support for SPDM socket support

2024-03-10 Thread Alistair Francis
From: Huai-Cheng Kuo 

SPDM enables authentication, attestation and key exchange to assist in
providing infrastructure security enablement. It's a standard published
by the DMTF [1].

SPDM supports multiple transports, including PCIe DOE and MCTP.
This patch adds support to QEMU to connect to an external SPDM
instance.

SPDM support can be added to any QEMU device by exposing a
TCP socket to a SPDM server. The server can then implement the SPDM
decoding/encoding support, generally using libspdm [2].

This is similar to how the current TPM implementation works and means
that the heavy lifting of setting up certificate chains, capabilities,
measurements and complex crypto can be done outside QEMU by a well
supported and tested library.

1: https://www.dmtf.org/standards/SPDM
2: https://github.com/DMTF/libspdm

Signed-off-by: Huai-Cheng Kuo 
Signed-off-by: Chris Browy 
Co-developed-by: Jonathan Cameron 
Signed-off-by: Jonathan Cameron 
[ Changes by WM
 - Bug fixes from testing
]
Signed-off-by: Wilfred Mallawa 
[ Changes by AF:
 - Convert to be more QEMU-ified
 - Move to backends as it isn't PCIe specific
]
Signed-off-by: Alistair Francis 
---
 MAINTAINERS  |   6 +
 include/sysemu/spdm-socket.h |  74 
 backends/spdm-socket.c   | 216 +++
 backends/Kconfig |   4 +
 backends/meson.build |   2 +
 5 files changed, 302 insertions(+)
 create mode 100644 include/sysemu/spdm-socket.h
 create mode 100644 backends/spdm-socket.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 4d96f855de..0a8ffa8fe0 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -3396,6 +3396,12 @@ F: tests/qtest/*tpm*
 F: docs/specs/tpm.rst
 T: git https://github.com/stefanberger/qemu-tpm.git tpm-next
 
+SPDM
+M: Alistair Francis 
+S: Maintained
+F: backends/spdm-socket.c
+F: include/sysemu/spdm-socket.h
+
 Checkpatch
 S: Odd Fixes
 F: scripts/checkpatch.pl
diff --git a/include/sysemu/spdm-socket.h b/include/sysemu/spdm-socket.h
new file mode 100644
index 00..5d8bd9aa4e
--- /dev/null
+++ b/include/sysemu/spdm-socket.h
@@ -0,0 +1,74 @@
+/*
+ * QEMU SPDM socket support
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to 
deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#ifndef SPDM_REQUESTER_H
+#define SPDM_REQUESTER_H
+
+/**
+ * spdm_socket_connect: connect to an external SPDM socket
+ * @port: port to connect to
+ * @errp: error object handle
+ *
+ * This will connect to an external SPDM socket server. On error
+ * it will return -1 and errp will be set. On success this function
+ * will return the socket number.
+ */
+int spdm_socket_connect(uint16_t port, Error **errp);
+
+/**
+ * spdm_socket_rsp: send and receive a message to a SPDM server
+ * @socket: socket returned from spdm_socket_connect()
+ * @transport_type: SPDM_SOCKET_TRANSPORT_TYPE_* macro
+ * @req: request buffer
+ * @req_len: request buffer length
+ * @rsp: response buffer
+ * @rsp_len: response buffer length
+ *
+ * Send platform data to a SPDM server on socket and then receive
+ * a response.
+ */
+uint32_t spdm_socket_rsp(const int socket, uint32_t transport_type,
+ void *req, uint32_t req_len,
+ void *rsp, uint32_t rsp_len);
+
+/**
+ * spdm_socket_close: send a shutdown command to the server
+ * @socket: socket returned from spdm_socket_connect()
+ * @transport_type: SPDM_SOCKET_TRANSPORT_TYPE_* macro
+ *
+ * This will issue a shutdown command to the server.
+ */
+void spdm_socket_close(const int socket, uint32_t transport_type);
+
+#define SPDM_SOCKET_COMMAND_NORMAL0x0001
+#define SPDM_SOCKET_COMMAND_OOB_ENCAP_KEY_UPDATE  0x8001
+#define SPDM_SOCKET_COMMAND_CONTINUE  0xFFFD
+#define SPDM_SOCKET_COMMAND_SHUTDOWN  0xFFFE
+#define SPDM_SOCKET_COMMAND_UNKOWN0x
+#define SPDM_SOCKET_COMMAND_TEST  0xDEAD
+
+#define SPDM_SOCKET_TRANSPORT_TYPE_MCTP

[PATCH v6 3/3] hw/nvme: Add SPDM over DOE support

2024-03-10 Thread Alistair Francis
From: Wilfred Mallawa 

Setup Data Object Exchance (DOE) as an extended capability for the NVME
controller and connect SPDM to it (CMA) to it.

Signed-off-by: Wilfred Mallawa 
Signed-off-by: Alistair Francis 
Reviewed-by: Jonathan Cameron 
Acked-by: Klaus Jensen 
---
 docs/specs/index.rst|   1 +
 docs/specs/spdm.rst | 122 
 include/hw/pci/pci_device.h |   5 ++
 include/hw/pci/pcie_doe.h   |   3 +
 hw/nvme/ctrl.c  |  57 +
 5 files changed, 188 insertions(+)
 create mode 100644 docs/specs/spdm.rst

diff --git a/docs/specs/index.rst b/docs/specs/index.rst
index 1484e3e760..e2d907959a 100644
--- a/docs/specs/index.rst
+++ b/docs/specs/index.rst
@@ -29,6 +29,7 @@ guest hardware that is specific to QEMU.
edu
ivshmem-spec
pvpanic
+   spdm
standard-vga
virt-ctlr
vmcoreinfo
diff --git a/docs/specs/spdm.rst b/docs/specs/spdm.rst
new file mode 100644
index 00..06b5ccac09
--- /dev/null
+++ b/docs/specs/spdm.rst
@@ -0,0 +1,122 @@
+==
+QEMU Security Protocols and Data Models (SPDM) Support
+==
+
+SPDM enables authentication, attestation and key exchange to assist in
+providing infrastructure security enablement. It's a standard published
+by the `DMTF`_.
+
+QEMU supports connecting to a SPDM responder implementation. This allows an
+external application to emulate the SPDM responder logic for an SPDM device.
+
+Setting up a SPDM server
+
+
+When using QEMU with SPDM devices QEMU will connect to a server which
+implements the SPDM functionality.
+
+SPDM-Utils
+--
+
+You can use `SPDM Utils`_ to emulate a responder. This is the simplest method.
+
+SPDM-Utils is a Linux applications to manage, test and develop devices
+supporting DMTF Security Protocol and Data Model (SPDM). It is written in Rust
+and utilises libspdm.
+
+To use SPDM-Utils you will need to do the following steps. Details are included
+in the SPDM-Utils README.
+
+ 1. `Build libspdm`_
+ 2. `Build SPDM Utils`_
+ 3. `Run it as a server`_
+
+spdm-emu
+
+
+You can use `spdm emu`_ to model the
+SPDM responder.
+
+.. code-block:: shell
+
+$ cd spdm-emu
+$ git submodule init; git submodule update --recursive
+$ mkdir build; cd build
+$ cmake -DARCH=x64 -DTOOLCHAIN=GCC -DTARGET=Debug -DCRYPTO=openssl ..
+$ make -j32
+$ make copy_sample_key # Build certificates, required for SPDM 
authentication.
+
+It is worth noting that the certificates should be in compliance with
+PCIe r6.1 sec 6.31.3. This means you will need to add the following to
+openssl.cnf
+
+.. code-block::
+
+subjectAltName = 
otherName:2.23.147;UTF8:Vendor=1b36:Device=0010:CC=010802:REV=02:SSVID=1af4:SSID=1100
+2.23.147 = ASN1:OID:2.23.147
+
+and then manually regenerate some certificates with:
+
+.. code-block:: shell
+
+$ openssl req -nodes -newkey ec:param.pem -keyout end_responder.key \
+-out end_responder.req -sha384 -batch \
+-subj "/CN=DMTF libspdm ECP384 responder cert"
+
+$ openssl x509 -req -in end_responder.req -out end_responder.cert \
+-CA inter.cert -CAkey inter.key -sha384 -days 3650 -set_serial 3 \
+-extensions v3_end -extfile ../openssl.cnf
+
+$ openssl asn1parse -in end_responder.cert -out end_responder.cert.der
+
+$ cat ca.cert.der inter.cert.der end_responder.cert.der > 
bundle_responder.certchain.der
+
+You can use SPDM-Utils instead as it will generate the correct certificates
+automatically.
+
+The responder can then be launched with
+
+.. code-block:: shell
+
+$ cd bin
+$ ./spdm_responder_emu --trans PCI_DOE
+
+Connecting an SPDM NVMe device
+==
+
+Once a SPDM server is running we can start QEMU and connect to the server.
+
+For an NVMe device first let's setup a block we can use
+
+.. code-block:: shell
+
+$ cd qemu-spdm/linux/image
+$ dd if=/dev/zero of=blknvme bs=1M count=2096 # 2GB NNMe Drive
+
+Then you can add this to your QEMU command line:
+
+.. code-block:: shell
+
+-drive file=blknvme,if=none,id=mynvme,format=raw \
+-device nvme,drive=mynvme,serial=deadbeef,spdm=2323
+
+At which point QEMU will try to connect to the SPDM server.
+
+
+.. _DMTF:
+   https://www.dmtf.org/standards/SPDM
+
+.. _SPDM Utils:
+   https://github.com/westerndigitalcorporation/spdm-utils
+
+.. _spdm emu:
+   https://github.com/dmtf/spdm-emu
+
+.. _Build libspdm:
+   
https://github.com/westerndigitalcorporation/spdm-utils?tab=readme-ov-file#build-libspdm
+
+.. _Build SPDM Utils:
+   
https://github.com/westerndigitalcorporation/spdm-utils?tab=readme-ov-file#build-the-binary
+
+.. _Run it as a server:
+   
https://github.com/westerndigitalcorporation/spdm-utils#qemu-spdm-device-emulation
diff --git a/include/hw/pci/pci_device.h b/include/hw/pci/pci_device.h
index d3dd0f64b2..b8379c78f1 100644
---

[PATCH v6 1/3] hw/pci: Add all Data Object Types defined in PCIe r6.0

2024-03-10 Thread Alistair Francis
Add all of the defined protocols/features from the PCIe-SIG r6.0
"Table 6-32 PCI-SIG defined Data Object Types (Vendor ID = 0001h)"
table.

Signed-off-by: Alistair Francis 
Reviewed-by: Jonathan Cameron 
---
 include/hw/pci/pcie_doe.h | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/include/hw/pci/pcie_doe.h b/include/hw/pci/pcie_doe.h
index 87dc17dcef..15d94661f9 100644
--- a/include/hw/pci/pcie_doe.h
+++ b/include/hw/pci/pcie_doe.h
@@ -46,6 +46,8 @@ REG32(PCI_DOE_CAP_STATUS, 0)
 
 /* PCI-SIG defined Data Object Types - r6.0 Table 6-32 */
 #define PCI_SIG_DOE_DISCOVERY   0x00
+#define PCI_SIG_DOE_CMA 0x01
+#define PCI_SIG_DOE_SECURED_CMA 0x02
 
 #define PCI_DOE_DW_SIZE_MAX (1 << 18)
 #define PCI_DOE_PROTOCOL_NUM_MAX256
-- 
2.44.0




[PATCH v6 0/3] Initial support for SPDM Responders

2024-03-10 Thread Alistair Francis
The Security Protocol and Data Model (SPDM) Specification defines
messages, data objects, and sequences for performing message exchanges
over a variety of transport and physical media.
 - 
https://www.dmtf.org/sites/default/files/standards/documents/DSP0274_1.3.0.pdf

SPDM currently supports PCIe DOE and MCTP transports, but it can be
extended to support others in the future. This series adds
support to QEMU to connect to an external SPDM instance.

SPDM support can be added to any QEMU device by exposing a
TCP socket to a SPDM server. The server can then implement the SPDM
decoding/encoding support, generally using libspdm [1].

This is similar to how the current TPM implementation works and means
that the heavy lifting of setting up certificate chains, capabilities,
measurements and complex crypto can be done outside QEMU by a well
supported and tested library.

This series implements socket support and exposes SPDM for a NVMe device.

1: https://github.com/DMTF/libspdm

v6:
 - Add documentation to public functions
 - Rename socket variable to spdm_socket
 - Don't override errp
 - Correctly return false from nvme_init_pci() on error
v5:
 - Update MAINTAINERS
v4:
 - Rebase
v3:
 - Spelling fixes
 - Support for SPDM-Utils
v2:
 - Add cover letter
 - A few code fixes based on comments
 - Document SPDM-Utils
 - A few tweaks and clarifications to the documentation

Alistair Francis (1):
  hw/pci: Add all Data Object Types defined in PCIe r6.0

Huai-Cheng Kuo (1):
  backends: Initial support for SPDM socket support

Wilfred Mallawa (1):
  hw/nvme: Add SPDM over DOE support

 MAINTAINERS  |   6 +
 docs/specs/index.rst |   1 +
 docs/specs/spdm.rst  | 122 
 include/hw/pci/pci_device.h  |   5 +
 include/hw/pci/pcie_doe.h|   5 +
 include/sysemu/spdm-socket.h |  74 
 backends/spdm-socket.c   | 216 +++
 hw/nvme/ctrl.c   |  57 +
 backends/Kconfig |   4 +
 backends/meson.build |   2 +
 10 files changed, 492 insertions(+)
 create mode 100644 docs/specs/spdm.rst
 create mode 100644 include/sysemu/spdm-socket.h
 create mode 100644 backends/spdm-socket.c

-- 
2.44.0




[PATCH v5 3/3] hw/nvme: Add SPDM over DOE support

2024-03-06 Thread Alistair Francis
From: Wilfred Mallawa 

Setup Data Object Exchance (DOE) as an extended capability for the NVME
controller and connect SPDM to it (CMA) to it.

Signed-off-by: Wilfred Mallawa 
Signed-off-by: Alistair Francis 
Reviewed-by: Jonathan Cameron 
Acked-by: Klaus Jensen 
---
 docs/specs/index.rst|   1 +
 docs/specs/spdm.rst | 122 
 include/hw/pci/pci_device.h |   5 ++
 include/hw/pci/pcie_doe.h   |   3 +
 hw/nvme/ctrl.c  |  53 
 5 files changed, 184 insertions(+)
 create mode 100644 docs/specs/spdm.rst

diff --git a/docs/specs/index.rst b/docs/specs/index.rst
index 1484e3e760..e2d907959a 100644
--- a/docs/specs/index.rst
+++ b/docs/specs/index.rst
@@ -29,6 +29,7 @@ guest hardware that is specific to QEMU.
edu
ivshmem-spec
pvpanic
+   spdm
standard-vga
virt-ctlr
vmcoreinfo
diff --git a/docs/specs/spdm.rst b/docs/specs/spdm.rst
new file mode 100644
index 00..4d0942c1ad
--- /dev/null
+++ b/docs/specs/spdm.rst
@@ -0,0 +1,122 @@
+==
+QEMU Security Protocols and Data Models (SPDM) Support
+==
+
+SPDM enables authentication, attestation and key exchange to assist in
+providing infrastructure security enablement. It's a standard published
+by the `DMTF`_.
+
+QEMU supports connecting to a SPDM responder implementation. This allows an
+external application to emulate the SPDM responder logic for an SPDM device.
+
+Setting up a SPDM server
+
+
+When using QEMU with SPDM devices QEMU will connect to a server which
+implements the SPDM functionality.
+
+SPDM-Utils
+--
+
+You can use `SPDM Utils`_ to emulate a responder. This is the simplest method.
+
+SPDM-Utils is a Linux applications to manage, test and develop devices
+supporting DMTF Security Protocol and Data Model (SPDM). It is written in Rust
+and utilises libspdm.
+
+To use SPDM-Utils you will need to do the following steps. Details are included
+in the SPDM-Utils README.
+
+ 1. `Build libspdm`_
+ 2. `Build SPDM Utils using Cargo`_
+ 3. `Run it as a server`_
+
+spdm-emu
+
+
+You can use `spdm emu`_ to model the
+SPDM responder.
+
+.. code-block:: shell
+
+$ cd spdm-emu
+$ git submodule init; git submodule update --recursive
+$ mkdir build; cd build
+$ cmake -DARCH=x64 -DTOOLCHAIN=GCC -DTARGET=Debug -DCRYPTO=openssl ..
+$ make -j32
+$ make copy_sample_key # Build certificates, required for SPDM 
authentication.
+
+It is worth noting that the certificates should be in compliance with
+PCIe r6.1 sec 6.31.3. This means you will need to add the following to
+openssl.cnf
+
+.. code-block::
+
+subjectAltName = 
otherName:2.23.147;UTF8:Vendor=1b36:Device=0010:CC=010802:REV=02:SSVID=1af4:SSID=1100
+2.23.147 = ASN1:OID:2.23.147
+
+and then manually regenerate some certificates with:
+
+.. code-block:: shell
+
+$ openssl req -nodes -newkey ec:param.pem -keyout end_responder.key \
+-out end_responder.req -sha384 -batch \
+-subj "/CN=DMTF libspdm ECP384 responder cert"
+
+$ openssl x509 -req -in end_responder.req -out end_responder.cert \
+-CA inter.cert -CAkey inter.key -sha384 -days 3650 -set_serial 3 \
+-extensions v3_end -extfile ../openssl.cnf
+
+$ openssl asn1parse -in end_responder.cert -out end_responder.cert.der
+
+$ cat ca.cert.der inter.cert.der end_responder.cert.der > 
bundle_responder.certchain.der
+
+You can use SPDM-Utils instead as it will generate the correct certificates
+automatically.
+
+The responder can then be launched with
+
+.. code-block:: shell
+
+$ cd bin
+$ ./spdm_responder_emu --trans PCI_DOE
+
+Connecting an SPDM NVMe device
+==
+
+Once a SPDM server is running we can start QEMU and connect to the server.
+
+For an NVMe device first let's setup a block we can use
+
+.. code-block:: shell
+
+$ cd qemu-spdm/linux/image
+$ dd if=/dev/zero of=blknvme bs=1M count=2096 # 2GB NNMe Drive
+
+Then you can add this to your QEMU command line:
+
+.. code-block:: shell
+
+-drive file=blknvme,if=none,id=mynvme,format=raw \
+-device nvme,drive=mynvme,serial=deadbeef,spdm=2323
+
+At which point QEMU will try to connect to the SPDM server.
+
+
+.. _DMTF:
+   https://www.dmtf.org/standards/SPDM
+
+.. _SPDM Utils:
+   https://github.com/westerndigitalcorporation/spdm-utils
+
+.. _spdm emu:
+   https://github.com/dmtf/spdm-emu
+
+.. _Build SPDM Utils:
+   https://github.com/westerndigitalcorporation/spdm-utils#building
+
+.. _Generate the certificates:
+   
https://github.com/westerndigitalcorporation/spdm-utils#generate-mutable-certificates
+
+.. _Run it as a server:
+   
https://github.com/westerndigitalcorporation/spdm-utils#qemu-spdm-device-emulation
diff --git a/include/hw/pci/pci_device.h b/include/hw/pci/pci_device.h
index d3dd0f64b2..b8379c78f1 100644
--- a/i

[PATCH v5 2/3] backends: Initial support for SPDM socket support

2024-03-06 Thread Alistair Francis
From: Huai-Cheng Kuo 

SPDM enables authentication, attestation and key exchange to assist in
providing infrastructure security enablement. It's a standard published
by the DMTF [1].

SPDM supports multiple transports, including PCIe DOE and MCTP.
This patch adds support to QEMU to connect to an external SPDM
instance.

SPDM support can be added to any QEMU device by exposing a
TCP socket to a SPDM server. The server can then implement the SPDM
decoding/encoding support, generally using libspdm [2].

This is similar to how the current TPM implementation works and means
that the heavy lifting of setting up certificate chains, capabilities,
measurements and complex crypto can be done outside QEMU by a well
supported and tested library.

1: https://www.dmtf.org/standards/SPDM
2: https://github.com/DMTF/libspdm

Signed-off-by: Huai-Cheng Kuo 
Signed-off-by: Chris Browy 
Co-developed-by: Jonathan Cameron 
Signed-off-by: Jonathan Cameron 
[ Changes by WM
 - Bug fixes from testing
]
Signed-off-by: Wilfred Mallawa 
[ Changes by AF:
 - Convert to be more QEMU-ified
 - Move to backends as it isn't PCIe specific
]
Signed-off-by: Alistair Francis 
---
 MAINTAINERS  |   6 +
 include/sysemu/spdm-socket.h |  44 +++
 backends/spdm-socket.c   | 216 +++
 backends/Kconfig |   4 +
 backends/meson.build |   2 +
 5 files changed, 272 insertions(+)
 create mode 100644 include/sysemu/spdm-socket.h
 create mode 100644 backends/spdm-socket.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 4183f2f3ab..a07706c225 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -3395,6 +3395,12 @@ F: tests/qtest/*tpm*
 F: docs/specs/tpm.rst
 T: git https://github.com/stefanberger/qemu-tpm.git tpm-next
 
+SPDM
+M: Alistair Francis 
+S: Maintained
+F: backends/spdm-socket.c
+F: include/sysemu/spdm-socket.h
+
 Checkpatch
 S: Odd Fixes
 F: scripts/checkpatch.pl
diff --git a/include/sysemu/spdm-socket.h b/include/sysemu/spdm-socket.h
new file mode 100644
index 00..24e6fccb83
--- /dev/null
+++ b/include/sysemu/spdm-socket.h
@@ -0,0 +1,44 @@
+/*
+ * QEMU SPDM socket support
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to 
deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#ifndef SPDM_REQUESTER_H
+#define SPDM_REQUESTER_H
+
+int spdm_socket_connect(uint16_t port, Error **errp);
+uint32_t spdm_socket_rsp(const int socket, uint32_t transport_type,
+ void *req, uint32_t req_len,
+ void *rsp, uint32_t rsp_len);
+void spdm_socket_close(const int socket, uint32_t transport_type);
+
+#define SPDM_SOCKET_COMMAND_NORMAL0x0001
+#define SPDM_SOCKET_COMMAND_OOB_ENCAP_KEY_UPDATE  0x8001
+#define SPDM_SOCKET_COMMAND_CONTINUE  0xFFFD
+#define SPDM_SOCKET_COMMAND_SHUTDOWN  0xFFFE
+#define SPDM_SOCKET_COMMAND_UNKOWN0x
+#define SPDM_SOCKET_COMMAND_TEST  0xDEAD
+
+#define SPDM_SOCKET_TRANSPORT_TYPE_MCTP   0x01
+#define SPDM_SOCKET_TRANSPORT_TYPE_PCI_DOE0x02
+
+#define SPDM_SOCKET_MAX_MESSAGE_BUFFER_SIZE   0x1200
+
+#endif
diff --git a/backends/spdm-socket.c b/backends/spdm-socket.c
new file mode 100644
index 00..d0663d696c
--- /dev/null
+++ b/backends/spdm-socket.c
@@ -0,0 +1,216 @@
+/* SPDX-License-Identifier: BSD-3-Clause */
+/*
+ * QEMU SPDM socket support
+ *
+ * This is based on:
+ * 
https://github.com/DMTF/spdm-emu/blob/07c0a838bcc1c6207c656ac75885c0603e344b6f/spdm_emu/spdm_emu_common/command.c
+ * but has been re-written to match QEMU style
+ *
+ * Copyright (c) 2021, DMTF. All rights reserved.
+ * Copyright (c) 2023. Western Digital Corporation or its affiliates.
+ */
+
+#include "qemu/osdep.h"
+#include "sysemu/spdm-socket.h"
+#include "qapi/error.h"
+
+static bool read_bytes(const int socket, uint8_t *buffer,
+   size_t number_of_bytes)
+{
+ssize_t number_received = 0;

[PATCH v5 1/3] hw/pci: Add all Data Object Types defined in PCIe r6.0

2024-03-06 Thread Alistair Francis
Add all of the defined protocols/features from the PCIe-SIG r6.0
"Table 6-32 PCI-SIG defined Data Object Types (Vendor ID = 0001h)"
table.

Signed-off-by: Alistair Francis 
Reviewed-by: Jonathan Cameron 
---
 include/hw/pci/pcie_doe.h | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/include/hw/pci/pcie_doe.h b/include/hw/pci/pcie_doe.h
index 87dc17dcef..15d94661f9 100644
--- a/include/hw/pci/pcie_doe.h
+++ b/include/hw/pci/pcie_doe.h
@@ -46,6 +46,8 @@ REG32(PCI_DOE_CAP_STATUS, 0)
 
 /* PCI-SIG defined Data Object Types - r6.0 Table 6-32 */
 #define PCI_SIG_DOE_DISCOVERY   0x00
+#define PCI_SIG_DOE_CMA 0x01
+#define PCI_SIG_DOE_SECURED_CMA 0x02
 
 #define PCI_DOE_DW_SIZE_MAX (1 << 18)
 #define PCI_DOE_PROTOCOL_NUM_MAX256
-- 
2.44.0




[PATCH v5 0/3] Initial support for SPDM Responders

2024-03-06 Thread Alistair Francis
The Security Protocol and Data Model (SPDM) Specification defines
messages, data objects, and sequences for performing message exchanges
over a variety of transport and physical media.
 - 
https://www.dmtf.org/sites/default/files/standards/documents/DSP0274_1.3.0.pdf

SPDM currently supports PCIe DOE and MCTP transports, but it can be
extended to support others in the future. This series adds
support to QEMU to connect to an external SPDM instance.

SPDM support can be added to any QEMU device by exposing a
TCP socket to a SPDM server. The server can then implement the SPDM
decoding/encoding support, generally using libspdm [1].

This is similar to how the current TPM implementation works and means
that the heavy lifting of setting up certificate chains, capabilities,
measurements and complex crypto can be done outside QEMU by a well
supported and tested library.

This series implements socket support and exposes SPDM for a NVMe device.

1: https://github.com/DMTF/libspdm

v5:
 - Update MAINTAINERS
v4:
 - Rebase
v3:
 - Spelling fixes
 - Support for SPDM-Utils
v2:
 - Add cover letter
 - A few code fixes based on comments
 - Document SPDM-Utils
 - A few tweaks and clarifications to the documentation

Alistair Francis (1):
  hw/pci: Add all Data Object Types defined in PCIe r6.0

Huai-Cheng Kuo (1):
  backends: Initial support for SPDM socket support

Wilfred Mallawa (1):
  hw/nvme: Add SPDM over DOE support

 MAINTAINERS  |   6 +
 docs/specs/index.rst |   1 +
 docs/specs/spdm.rst  | 122 
 include/hw/pci/pci_device.h  |   5 +
 include/hw/pci/pcie_doe.h|   5 +
 include/sysemu/spdm-socket.h |  44 +++
 backends/spdm-socket.c   | 216 +++
 hw/nvme/ctrl.c   |  53 +
 backends/Kconfig |   4 +
 backends/meson.build |   2 +
 10 files changed, 458 insertions(+)
 create mode 100644 docs/specs/spdm.rst
 create mode 100644 include/sysemu/spdm-socket.h
 create mode 100644 backends/spdm-socket.c

-- 
2.44.0




Re: [PATCH v4 0/3] Initial support for SPDM Responders

2024-02-16 Thread Alistair Francis
On Fri, Feb 16, 2024 at 6:52 PM Klaus Jensen  wrote:
>
> On Feb 15 14:44, Jonathan Cameron wrote:
> > On Tue, 13 Feb 2024 12:44:00 +1000
> > Alistair Francis  wrote:
> >
> > Hi All,
> >
> > Just wanted to add that back in v2 Klaus Jensen stated:
> >
> > "I have no problem with picking this up for nvme, but I'd rather not take
> >  the full series through my tree without reviews/acks from the pci
> >  maintainers."
> >
> > So I'd like to add my request that Michael and/or Marcell takes a look
> > when they have time.
> >
> > I've been carrying more or less the first 2 patches in my CXL staging
> > tree for a couple of years (the initial Linux Kernel support that Lukas
> > Wunner is now handling was developed against this) and I would love
> > to see this upstream. Along with PCI and CXL and NVME usecases this
> > is a major part of the Confidential Compute device assignment story
> > via PCI/TDISP and CXL equivalent.
> >
> > It's not changed in significant ways since v2 back in October last year.
> >
>
> Would someone be willing to sign up to maintain the spdm_socket backend?

I'm happy to and should have already edited MAINTAINERS to indicate
that. I'll fix that up in the next version

Alistair



[PATCH v4 3/3] hw/nvme: Add SPDM over DOE support

2024-02-12 Thread Alistair Francis
From: Wilfred Mallawa 

Setup Data Object Exchance (DOE) as an extended capability for the NVME
controller and connect SPDM to it (CMA) to it.

Signed-off-by: Wilfred Mallawa 
Signed-off-by: Alistair Francis 
Reviewed-by: Jonathan Cameron 
Acked-by: Klaus Jensen 
---
 docs/specs/index.rst|   1 +
 docs/specs/spdm.rst | 122 
 include/hw/pci/pci_device.h |   5 ++
 include/hw/pci/pcie_doe.h   |   3 +
 hw/nvme/ctrl.c  |  53 
 5 files changed, 184 insertions(+)
 create mode 100644 docs/specs/spdm.rst

diff --git a/docs/specs/index.rst b/docs/specs/index.rst
index 1484e3e760..e2d907959a 100644
--- a/docs/specs/index.rst
+++ b/docs/specs/index.rst
@@ -29,6 +29,7 @@ guest hardware that is specific to QEMU.
edu
ivshmem-spec
pvpanic
+   spdm
standard-vga
virt-ctlr
vmcoreinfo
diff --git a/docs/specs/spdm.rst b/docs/specs/spdm.rst
new file mode 100644
index 00..4d0942c1ad
--- /dev/null
+++ b/docs/specs/spdm.rst
@@ -0,0 +1,122 @@
+==
+QEMU Security Protocols and Data Models (SPDM) Support
+==
+
+SPDM enables authentication, attestation and key exchange to assist in
+providing infrastructure security enablement. It's a standard published
+by the `DMTF`_.
+
+QEMU supports connecting to a SPDM responder implementation. This allows an
+external application to emulate the SPDM responder logic for an SPDM device.
+
+Setting up a SPDM server
+
+
+When using QEMU with SPDM devices QEMU will connect to a server which
+implements the SPDM functionality.
+
+SPDM-Utils
+--
+
+You can use `SPDM Utils`_ to emulate a responder. This is the simplest method.
+
+SPDM-Utils is a Linux applications to manage, test and develop devices
+supporting DMTF Security Protocol and Data Model (SPDM). It is written in Rust
+and utilises libspdm.
+
+To use SPDM-Utils you will need to do the following steps. Details are included
+in the SPDM-Utils README.
+
+ 1. `Build libspdm`_
+ 2. `Build SPDM Utils using Cargo`_
+ 3. `Run it as a server`_
+
+spdm-emu
+
+
+You can use `spdm emu`_ to model the
+SPDM responder.
+
+.. code-block:: shell
+
+$ cd spdm-emu
+$ git submodule init; git submodule update --recursive
+$ mkdir build; cd build
+$ cmake -DARCH=x64 -DTOOLCHAIN=GCC -DTARGET=Debug -DCRYPTO=openssl ..
+$ make -j32
+$ make copy_sample_key # Build certificates, required for SPDM 
authentication.
+
+It is worth noting that the certificates should be in compliance with
+PCIe r6.1 sec 6.31.3. This means you will need to add the following to
+openssl.cnf
+
+.. code-block::
+
+subjectAltName = 
otherName:2.23.147;UTF8:Vendor=1b36:Device=0010:CC=010802:REV=02:SSVID=1af4:SSID=1100
+2.23.147 = ASN1:OID:2.23.147
+
+and then manually regenerate some certificates with:
+
+.. code-block:: shell
+
+$ openssl req -nodes -newkey ec:param.pem -keyout end_responder.key \
+-out end_responder.req -sha384 -batch \
+-subj "/CN=DMTF libspdm ECP384 responder cert"
+
+$ openssl x509 -req -in end_responder.req -out end_responder.cert \
+-CA inter.cert -CAkey inter.key -sha384 -days 3650 -set_serial 3 \
+-extensions v3_end -extfile ../openssl.cnf
+
+$ openssl asn1parse -in end_responder.cert -out end_responder.cert.der
+
+$ cat ca.cert.der inter.cert.der end_responder.cert.der > 
bundle_responder.certchain.der
+
+You can use SPDM-Utils instead as it will generate the correct certificates
+automatically.
+
+The responder can then be launched with
+
+.. code-block:: shell
+
+$ cd bin
+$ ./spdm_responder_emu --trans PCI_DOE
+
+Connecting an SPDM NVMe device
+==
+
+Once a SPDM server is running we can start QEMU and connect to the server.
+
+For an NVMe device first let's setup a block we can use
+
+.. code-block:: shell
+
+$ cd qemu-spdm/linux/image
+$ dd if=/dev/zero of=blknvme bs=1M count=2096 # 2GB NNMe Drive
+
+Then you can add this to your QEMU command line:
+
+.. code-block:: shell
+
+-drive file=blknvme,if=none,id=mynvme,format=raw \
+-device nvme,drive=mynvme,serial=deadbeef,spdm=2323
+
+At which point QEMU will try to connect to the SPDM server.
+
+
+.. _DMTF:
+   https://www.dmtf.org/standards/SPDM
+
+.. _SPDM Utils:
+   https://github.com/westerndigitalcorporation/spdm-utils
+
+.. _spdm emu:
+   https://github.com/dmtf/spdm-emu
+
+.. _Build SPDM Utils:
+   https://github.com/westerndigitalcorporation/spdm-utils#building
+
+.. _Generate the certificates:
+   
https://github.com/westerndigitalcorporation/spdm-utils#generate-mutable-certificates
+
+.. _Run it as a server:
+   
https://github.com/westerndigitalcorporation/spdm-utils#qemu-spdm-device-emulation
diff --git a/include/hw/pci/pci_device.h b/include/hw/pci/pci_device.h
index d3dd0f64b2..b8379c78f1 100644
--- a/i

[PATCH v4 2/3] backends: Initial support for SPDM socket support

2024-02-12 Thread Alistair Francis
From: Huai-Cheng Kuo 

SPDM enables authentication, attestation and key exchange to assist in
providing infrastructure security enablement. It's a standard published
by the DMTF [1].

SPDM supports multiple transports, including PCIe DOE and MCTP.
This patch adds support to QEMU to connect to an external SPDM
instance.

SPDM support can be added to any QEMU device by exposing a
TCP socket to a SPDM server. The server can then implement the SPDM
decoding/encoding support, generally using libspdm [2].

This is similar to how the current TPM implementation works and means
that the heavy lifting of setting up certificate chains, capabilities,
measurements and complex crypto can be done outside QEMU by a well
supported and tested library.

1: https://www.dmtf.org/standards/SPDM
2: https://github.com/DMTF/libspdm

Signed-off-by: Huai-Cheng Kuo 
Signed-off-by: Chris Browy 
Co-developed-by: Jonathan Cameron 
Signed-off-by: Jonathan Cameron 
[ Changes by WM
 - Bug fixes from testing
]
Signed-off-by: Wilfred Mallawa 
[ Changes by AF:
 - Convert to be more QEMU-ified
 - Move to backends as it isn't PCIe specific
]
Signed-off-by: Alistair Francis 
---
 include/sysemu/spdm-socket.h |  44 +++
 backends/spdm-socket.c   | 216 +++
 backends/Kconfig |   4 +
 backends/meson.build |   2 +
 4 files changed, 266 insertions(+)
 create mode 100644 include/sysemu/spdm-socket.h
 create mode 100644 backends/spdm-socket.c

diff --git a/include/sysemu/spdm-socket.h b/include/sysemu/spdm-socket.h
new file mode 100644
index 00..24e6fccb83
--- /dev/null
+++ b/include/sysemu/spdm-socket.h
@@ -0,0 +1,44 @@
+/*
+ * QEMU SPDM socket support
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to 
deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#ifndef SPDM_REQUESTER_H
+#define SPDM_REQUESTER_H
+
+int spdm_socket_connect(uint16_t port, Error **errp);
+uint32_t spdm_socket_rsp(const int socket, uint32_t transport_type,
+ void *req, uint32_t req_len,
+ void *rsp, uint32_t rsp_len);
+void spdm_socket_close(const int socket, uint32_t transport_type);
+
+#define SPDM_SOCKET_COMMAND_NORMAL0x0001
+#define SPDM_SOCKET_COMMAND_OOB_ENCAP_KEY_UPDATE  0x8001
+#define SPDM_SOCKET_COMMAND_CONTINUE  0xFFFD
+#define SPDM_SOCKET_COMMAND_SHUTDOWN  0xFFFE
+#define SPDM_SOCKET_COMMAND_UNKOWN0x
+#define SPDM_SOCKET_COMMAND_TEST  0xDEAD
+
+#define SPDM_SOCKET_TRANSPORT_TYPE_MCTP   0x01
+#define SPDM_SOCKET_TRANSPORT_TYPE_PCI_DOE0x02
+
+#define SPDM_SOCKET_MAX_MESSAGE_BUFFER_SIZE   0x1200
+
+#endif
diff --git a/backends/spdm-socket.c b/backends/spdm-socket.c
new file mode 100644
index 00..d0663d696c
--- /dev/null
+++ b/backends/spdm-socket.c
@@ -0,0 +1,216 @@
+/* SPDX-License-Identifier: BSD-3-Clause */
+/*
+ * QEMU SPDM socket support
+ *
+ * This is based on:
+ * 
https://github.com/DMTF/spdm-emu/blob/07c0a838bcc1c6207c656ac75885c0603e344b6f/spdm_emu/spdm_emu_common/command.c
+ * but has been re-written to match QEMU style
+ *
+ * Copyright (c) 2021, DMTF. All rights reserved.
+ * Copyright (c) 2023. Western Digital Corporation or its affiliates.
+ */
+
+#include "qemu/osdep.h"
+#include "sysemu/spdm-socket.h"
+#include "qapi/error.h"
+
+static bool read_bytes(const int socket, uint8_t *buffer,
+   size_t number_of_bytes)
+{
+ssize_t number_received = 0;
+ssize_t result;
+
+while (number_received < number_of_bytes) {
+result = recv(socket, buffer + number_received,
+  number_of_bytes - number_received, 0);
+if (result <= 0) {
+return false;
+}
+number_received += result;
+}
+return true;
+}
+
+static bool read_data32(const int socket, uint32_t *data)
+{
+bool result;
+
+result = read_bytes(sock

[PATCH v4 0/3] Initial support for SPDM Responders

2024-02-12 Thread Alistair Francis
The Security Protocol and Data Model (SPDM) Specification defines
messages, data objects, and sequences for performing message exchanges
over a variety of transport and physical media.
 - 
https://www.dmtf.org/sites/default/files/standards/documents/DSP0274_1.3.0.pdf

SPDM currently supports PCIe DOE and MCTP transports, but it can be
extended to support others in the future. This series adds
support to QEMU to connect to an external SPDM instance.

SPDM support can be added to any QEMU device by exposing a
TCP socket to a SPDM server. The server can then implement the SPDM
decoding/encoding support, generally using libspdm [1].

This is similar to how the current TPM implementation works and means
that the heavy lifting of setting up certificate chains, capabilities,
measurements and complex crypto can be done outside QEMU by a well
supported and tested library.

This series implements socket support and exposes SPDM for a NVMe device.

1: https://github.com/DMTF/libspdm

v4:
 - Rebase
v3:
 - Spelling fixes
 - Support for SPDM-Utils
v2:
 - Add cover letter
 - A few code fixes based on comments
 - Document SPDM-Utils
 - A few tweaks and clarifications to the documentation

Alistair Francis (1):
  hw/pci: Add all Data Object Types defined in PCIe r6.0

Huai-Cheng Kuo (1):
  backends: Initial support for SPDM socket support

Wilfred Mallawa (1):
  hw/nvme: Add SPDM over DOE support

 docs/specs/index.rst |   1 +
 docs/specs/spdm.rst  | 122 
 include/hw/pci/pci_device.h  |   5 +
 include/hw/pci/pcie_doe.h|   5 +
 include/sysemu/spdm-socket.h |  44 +++
 backends/spdm-socket.c   | 216 +++
 hw/nvme/ctrl.c   |  53 +
 backends/Kconfig |   4 +
 backends/meson.build |   2 +
 9 files changed, 452 insertions(+)
 create mode 100644 docs/specs/spdm.rst
 create mode 100644 include/sysemu/spdm-socket.h
 create mode 100644 backends/spdm-socket.c

-- 
2.43.0




[PATCH v4 1/3] hw/pci: Add all Data Object Types defined in PCIe r6.0

2024-02-12 Thread Alistair Francis
Add all of the defined protocols/features from the PCIe-SIG r6.0
"Table 6-32 PCI-SIG defined Data Object Types (Vendor ID = 0001h)"
table.

Signed-off-by: Alistair Francis 
Reviewed-by: Jonathan Cameron 
---
 include/hw/pci/pcie_doe.h | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/include/hw/pci/pcie_doe.h b/include/hw/pci/pcie_doe.h
index 87dc17dcef..15d94661f9 100644
--- a/include/hw/pci/pcie_doe.h
+++ b/include/hw/pci/pcie_doe.h
@@ -46,6 +46,8 @@ REG32(PCI_DOE_CAP_STATUS, 0)
 
 /* PCI-SIG defined Data Object Types - r6.0 Table 6-32 */
 #define PCI_SIG_DOE_DISCOVERY   0x00
+#define PCI_SIG_DOE_CMA 0x01
+#define PCI_SIG_DOE_SECURED_CMA 0x02
 
 #define PCI_DOE_DW_SIZE_MAX (1 << 18)
 #define PCI_DOE_PROTOCOL_NUM_MAX256
-- 
2.43.0




[PATCH v3 1/3] hw/pci: Add all Data Object Types defined in PCIe r6.0

2023-11-22 Thread Alistair Francis
Add all of the defined protocols/features from the PCIe-SIG r6.0
"Table 6-32 PCI-SIG defined Data Object Types (Vendor ID = 0001h)"
table.

Signed-off-by: Alistair Francis 
Reviewed-by: Jonathan Cameron 
---
 include/hw/pci/pcie_doe.h | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/include/hw/pci/pcie_doe.h b/include/hw/pci/pcie_doe.h
index 87dc17dcef..15d94661f9 100644
--- a/include/hw/pci/pcie_doe.h
+++ b/include/hw/pci/pcie_doe.h
@@ -46,6 +46,8 @@ REG32(PCI_DOE_CAP_STATUS, 0)
 
 /* PCI-SIG defined Data Object Types - r6.0 Table 6-32 */
 #define PCI_SIG_DOE_DISCOVERY   0x00
+#define PCI_SIG_DOE_CMA 0x01
+#define PCI_SIG_DOE_SECURED_CMA 0x02
 
 #define PCI_DOE_DW_SIZE_MAX (1 << 18)
 #define PCI_DOE_PROTOCOL_NUM_MAX256
-- 
2.42.0




[PATCH v3 0/3] Initial support for SPDM Responders

2023-11-22 Thread Alistair Francis
The Security Protocol and Data Model (SPDM) Specification defines
messages, data objects, and sequences for performing message exchanges
over a variety of transport and physical media.
 - 
https://www.dmtf.org/sites/default/files/standards/documents/DSP0274_1.3.0.pdf

SPDM currently supports PCIe DOE and MCTP transports, but it can be
extended to support others in the future. This series adds
support to QEMU to connect to an external SPDM instance.

SPDM support can be added to any QEMU device by exposing a
TCP socket to a SPDM server. The server can then implement the SPDM
decoding/encoding support, generally using libspdm [1].

This is similar to how the current TPM implementation works and means
that the heavy lifting of setting up certificate chains, capabilities,
measurements and complex crypto can be done outside QEMU by a well
supported and tested library.

This series implements socket support and exposes SPDM for a NVMe device.

1: https://github.com/DMTF/libspdm

v3:
 - Spelling fixes
 - Support for SPDM-Utils
v2:
 - Add cover letter
 - A few code fixes based on comments
 - Document SPDM-Utils
 - A few tweaks and clarifications to the documentation

Alistair Francis (1):
  hw/pci: Add all Data Object Types defined in PCIe r6.0

Huai-Cheng Kuo (1):
  backends: Initial support for SPDM socket support

Wilfred Mallawa (1):
  hw/nvme: Add SPDM over DOE support

 docs/specs/index.rst |   1 +
 docs/specs/spdm.rst  | 121 
 include/hw/pci/pci_device.h  |   5 +
 include/hw/pci/pcie_doe.h|   5 +
 include/sysemu/spdm-socket.h |  44 +++
 backends/spdm-socket.c   | 216 +++
 hw/nvme/ctrl.c   |  53 +
 backends/Kconfig |   4 +
 backends/meson.build |   2 +
 9 files changed, 451 insertions(+)
 create mode 100644 docs/specs/spdm.rst
 create mode 100644 include/sysemu/spdm-socket.h
 create mode 100644 backends/spdm-socket.c

-- 
2.42.0




[PATCH v3 3/3] hw/nvme: Add SPDM over DOE support

2023-11-22 Thread Alistair Francis
From: Wilfred Mallawa 

Setup Data Object Exchance (DOE) as an extended capability for the NVME
controller and connect SPDM to it (CMA) to it.

Signed-off-by: Wilfred Mallawa 
Signed-off-by: Alistair Francis 
Reviewed-by: Jonathan Cameron 
Acked-by: Klaus Jensen 
---
 docs/specs/index.rst|   1 +
 docs/specs/spdm.rst | 121 
 include/hw/pci/pci_device.h |   5 ++
 include/hw/pci/pcie_doe.h   |   3 +
 hw/nvme/ctrl.c  |  53 
 5 files changed, 183 insertions(+)
 create mode 100644 docs/specs/spdm.rst

diff --git a/docs/specs/index.rst b/docs/specs/index.rst
index b3f482b0aa..fbbb702c7d 100644
--- a/docs/specs/index.rst
+++ b/docs/specs/index.rst
@@ -28,6 +28,7 @@ guest hardware that is specific to QEMU.
edu
ivshmem-spec
pvpanic
+   spdm
standard-vga
virt-ctlr
vmcoreinfo
diff --git a/docs/specs/spdm.rst b/docs/specs/spdm.rst
new file mode 100644
index 00..a592181c7e
--- /dev/null
+++ b/docs/specs/spdm.rst
@@ -0,0 +1,121 @@
+==
+QEMU Security Protocols and Data Models (SPDM) Support
+==
+
+SPDM enables authentication, attestation and key exchange to assist in
+providing infrastructure security enablement. It's a standard published
+by the `DMTF`_.
+
+QEMU supports connecting to a SPDM responder implementation. This allows an
+external application to emulate the SPDM responder logic for an SPDM device.
+
+Setting up a SPDM server
+
+
+When using QEMU with SPDM devices QEMU will connect to a server which
+implements the SPDM functionality.
+
+SPDM-Utils
+--
+
+You can use `SPDM Utils`_ to emulate a responder.
+
+SPDM-Utils is a Linux applications to manage, test and develop devices
+supporting DMTF Security Protocol and Data Model (SPDM). It is written in Rust
+and utilises libspdm.
+
+To use SPDM-Utils you will need to do the following:
+
+ 1. `Build SPDM Utils`_
+ 2. `Generate the certificates`_
+ 3. `Run it as a server`_
+
+spdm-emu
+
+
+You can use `spdm emu`_ to model the
+SPDM responder.
+
+.. code-block:: shell
+
+$ cd spdm-emu
+$ git submodule init; git submodule update --recursive
+$ mkdir build; cd build
+$ cmake -DARCH=x64 -DTOOLCHAIN=GCC -DTARGET=Debug -DCRYPTO=openssl ..
+$ make -j32
+$ make copy_sample_key # Build certificates, required for SPDM 
authentication.
+
+It is worth noting that the certificates should be in compliance with
+PCIe r6.1 sec 6.31.3. This means you will need to add the following to
+openssl.cnf
+
+.. code-block::
+
+subjectAltName = 
otherName:2.23.147;UTF8:Vendor=1b36:Device=0010:CC=010802:REV=02:SSVID=1af4:SSID=1100
+2.23.147 = ASN1:OID:2.23.147
+
+and then manually regenerate some certificates with:
+
+.. code-block:: shell
+
+$ openssl req -nodes -newkey ec:param.pem -keyout end_responder.key \
+-out end_responder.req -sha384 -batch \
+-subj "/CN=DMTF libspdm ECP384 responder cert"
+
+$ openssl x509 -req -in end_responder.req -out end_responder.cert \
+-CA inter.cert -CAkey inter.key -sha384 -days 3650 -set_serial 3 \
+-extensions v3_end -extfile ../openssl.cnf
+
+$ openssl asn1parse -in end_responder.cert -out end_responder.cert.der
+
+$ cat ca.cert.der inter.cert.der end_responder.cert.der > 
bundle_responder.certchain.der
+
+You can use SPDM-Utils instead as it will generate the correct certificates
+automatically.
+
+The responder can then be launched with
+
+.. code-block:: shell
+
+$ cd bin
+$ ./spdm_responder_emu --trans PCI_DOE
+
+Connecting an SPDM NVMe device
+==
+
+Once a SPDM server is running we can start QEMU and connect to the server.
+
+For an NVMe device first let's setup a block we can use
+
+.. code-block:: shell
+
+$ cd qemu-spdm/linux/image
+$ dd if=/dev/zero of=blknvme bs=1M count=2096 # 2GB NNMe Drive
+
+Then you can add this to your QEMU command line:
+
+.. code-block:: shell
+
+-drive file=blknvme,if=none,id=mynvme,format=raw \
+-device nvme,drive=mynvme,serial=deadbeef,spdm=2323
+
+At which point QEMU will try to connect to the SPDM server.
+
+
+.. _DMTF:
+   https://www.dmtf.org/standards/SPDM
+
+.. _SPDM Utils:
+   https://github.com/westerndigitalcorporation/spdm-utils
+
+.. _spdm emu:
+   https://github.com/dmtf/spdm-emu
+
+.. _Build SPDM Utils:
+   https://github.com/westerndigitalcorporation/spdm-utils#building
+
+.. _Generate the certificates:
+   
https://github.com/westerndigitalcorporation/spdm-utils#generate-mutable-certificates
+
+.. _Run it as a server:
+   
https://github.com/westerndigitalcorporation/spdm-utils#qemu-spdm-device-emulation
diff --git a/include/hw/pci/pci_device.h b/include/hw/pci/pci_device.h
index d3dd0f64b2..b8379c78f1 100644
--- a/include/hw/pci/pci_device.h
+++ b/include/hw/pci/pci_device.h
@@ -3,6 +3,7 @@
 
 #include 

[PATCH v3 2/3] backends: Initial support for SPDM socket support

2023-11-22 Thread Alistair Francis
From: Huai-Cheng Kuo 

SPDM enables authentication, attestation and key exchange to assist in
providing infrastructure security enablement. It's a standard published
by the DMTF [1].

SPDM supports multiple transports, including PCIe DOE and MCTP.
This patch adds support to QEMU to connect to an external SPDM
instance.

SPDM support can be added to any QEMU device by exposing a
TCP socket to a SPDM server. The server can then implement the SPDM
decoding/encoding support, generally using libspdm [2].

This is similar to how the current TPM implementation works and means
that the heavy lifting of setting up certificate chains, capabilities,
measurements and complex crypto can be done outside QEMU by a well
supported and tested library.

1: https://www.dmtf.org/standards/SPDM
2: https://github.com/DMTF/libspdm

Signed-off-by: Huai-Cheng Kuo 
Signed-off-by: Chris Browy 
Co-developed-by: Jonathan Cameron 
Signed-off-by: Jonathan Cameron 
[ Changes by WM
 - Bug fixes from testing
]
Signed-off-by: Wilfred Mallawa 
[ Changes by AF:
 - Convert to be more QEMU-ified
 - Move to backends as it isn't PCIe specific
]
Signed-off-by: Alistair Francis 
---
 include/sysemu/spdm-socket.h |  44 +++
 backends/spdm-socket.c   | 216 +++
 backends/Kconfig |   4 +
 backends/meson.build |   2 +
 4 files changed, 266 insertions(+)
 create mode 100644 include/sysemu/spdm-socket.h
 create mode 100644 backends/spdm-socket.c

diff --git a/include/sysemu/spdm-socket.h b/include/sysemu/spdm-socket.h
new file mode 100644
index 00..24e6fccb83
--- /dev/null
+++ b/include/sysemu/spdm-socket.h
@@ -0,0 +1,44 @@
+/*
+ * QEMU SPDM socket support
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to 
deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#ifndef SPDM_REQUESTER_H
+#define SPDM_REQUESTER_H
+
+int spdm_socket_connect(uint16_t port, Error **errp);
+uint32_t spdm_socket_rsp(const int socket, uint32_t transport_type,
+ void *req, uint32_t req_len,
+ void *rsp, uint32_t rsp_len);
+void spdm_socket_close(const int socket, uint32_t transport_type);
+
+#define SPDM_SOCKET_COMMAND_NORMAL0x0001
+#define SPDM_SOCKET_COMMAND_OOB_ENCAP_KEY_UPDATE  0x8001
+#define SPDM_SOCKET_COMMAND_CONTINUE  0xFFFD
+#define SPDM_SOCKET_COMMAND_SHUTDOWN  0xFFFE
+#define SPDM_SOCKET_COMMAND_UNKOWN0x
+#define SPDM_SOCKET_COMMAND_TEST  0xDEAD
+
+#define SPDM_SOCKET_TRANSPORT_TYPE_MCTP   0x01
+#define SPDM_SOCKET_TRANSPORT_TYPE_PCI_DOE0x02
+
+#define SPDM_SOCKET_MAX_MESSAGE_BUFFER_SIZE   0x1200
+
+#endif
diff --git a/backends/spdm-socket.c b/backends/spdm-socket.c
new file mode 100644
index 00..d0663d696c
--- /dev/null
+++ b/backends/spdm-socket.c
@@ -0,0 +1,216 @@
+/* SPDX-License-Identifier: BSD-3-Clause */
+/*
+ * QEMU SPDM socket support
+ *
+ * This is based on:
+ * 
https://github.com/DMTF/spdm-emu/blob/07c0a838bcc1c6207c656ac75885c0603e344b6f/spdm_emu/spdm_emu_common/command.c
+ * but has been re-written to match QEMU style
+ *
+ * Copyright (c) 2021, DMTF. All rights reserved.
+ * Copyright (c) 2023. Western Digital Corporation or its affiliates.
+ */
+
+#include "qemu/osdep.h"
+#include "sysemu/spdm-socket.h"
+#include "qapi/error.h"
+
+static bool read_bytes(const int socket, uint8_t *buffer,
+   size_t number_of_bytes)
+{
+ssize_t number_received = 0;
+ssize_t result;
+
+while (number_received < number_of_bytes) {
+result = recv(socket, buffer + number_received,
+  number_of_bytes - number_received, 0);
+if (result <= 0) {
+return false;
+}
+number_received += result;
+}
+return true;
+}
+
+static bool read_data32(const int socket, uint32_t *data)
+{
+bool result;
+
+result = read_bytes(sock

[PATCH v2 3/3] hw/nvme: Add SPDM over DOE support

2023-10-16 Thread Alistair Francis
From: Wilfred Mallawa 

Setup Data Object Exchance (DOE) as an extended capability for the NVME
controller and connect SPDM to it (CMA) to it.

Signed-off-by: Wilfred Mallawa 
Signed-off-by: Alistair Francis 
---
 docs/specs/index.rst|   1 +
 docs/specs/spdm.rst | 114 
 include/hw/pci/pci_device.h |   5 ++
 include/hw/pci/pcie_doe.h   |   3 +
 hw/nvme/ctrl.c  |  53 +
 5 files changed, 176 insertions(+)
 create mode 100644 docs/specs/spdm.rst

diff --git a/docs/specs/index.rst b/docs/specs/index.rst
index e58be38c41..c398541388 100644
--- a/docs/specs/index.rst
+++ b/docs/specs/index.rst
@@ -24,3 +24,4 @@ guest hardware that is specific to QEMU.
acpi_erst
sev-guest-firmware
fw_cfg
+   spdm
diff --git a/docs/specs/spdm.rst b/docs/specs/spdm.rst
new file mode 100644
index 00..dfdc3cbb4d
--- /dev/null
+++ b/docs/specs/spdm.rst
@@ -0,0 +1,114 @@
+==
+QEMU Security Protocols and Data Models (SPDM) Support
+==
+
+SPDM enables authentication, attestation and key exchange to assist in
+providing infrastructure security enablement. It's a standard published
+by the `DMTF`_.
+
+QEMU supports connecting to a SPDM Responder implementation. This allows an
+external application to emulate the SPDM Responder logic for an SPDM device.
+
+Setting up a SPDM server
+
+
+When using QEMU with SPDM devices QEMU will connect to a server which
+implements the SPDM functionality.
+
+SPDM-Utils
+--
+
+You can use `SPDM Utils`_ to emulate a Responder.
+
+SPDM-Utils is a Linux applications to manage, test and develop devices
+supporting DMTF Security Protocol and Data Model (SPDM). It is written in Rust
+and utilises libspdm.
+
+To use SPDM-Utils you will need to do the followoing:
+
+ 1. `Build SPDM Utils`_
+ 2. `Generate the certificates`_
+ 3. `Run it as a server`_
+
+spdm-emu
+
+
+You can use `spdm emu`_ to model the
+SPDM responder.
+
+.. code-block:: shell
+
+$ cd spdm-emu
+$ git submodule init; git submodule update --recursive
+$ mkdir build; cd build
+$ cmake -DARCH=x64 -DTOOLCHAIN=GCC -DTARGET=Debug -DCRYPTO=openssl ..
+$ make -j32
+$ make copy_sample_key # Build certificates, required for SPDM 
authentication.
+
+It is worth noting that the certificates should be in compliance with
+PCIe r6.1 sec 6.31.3. This means you will need to add the following to
+openssl.cnf
+
+.. code-block::
+
+subjectAltName = 
otherName:2.23.147;UTF8:Vendor=1b36:Device=0010:CC=010802:REV=02:SSVID=1af4:SSID=1100
+2.23.147 = ASN1:OID:2.23.147
+
+and then manually regenerate some certificates with:
+
+.. code-block:: shell
+
+openssl req -nodes -newkey ec:param.pem -keyout end_responder.key -out 
end_responder.req -sha384 -batch -subj "/CN=DMTF libspdm ECP384 responder cert"
+openssl x509 -req -in end_responder.req -out end_responder.cert -CA 
inter.cert -CAkey inter.key -sha384 -days 3650 -set_serial 3 -extensions v3_end 
-extfile ../openssl.cnf
+openssl asn1parse -in end_responder.cert -out end_responder.cert.der
+cat ca.cert.der inter.cert.der end_responder.cert.der > 
bundle_responder.certchain.der
+
+You can use SPDM-Utils instead as it will generate the correct certificates
+automatically.
+
+The responder can then be launched with
+
+.. code-block:: shell
+
+$ cd bin
+$ ./spdm_responder_emu --trans PCI_DOE
+
+Connecting an SPDM NVMe device
+==
+
+Once a SPDM server is running we can start QEMU and connect to the server.
+
+For an NVMe device first let's setup a block we can use
+
+.. code-block:: shell
+
+$ cd qemu-spdm/linux/image
+$ dd if=/dev/zero of=blknvme bs=1M count=2096 # 2GB NNMe Drive
+
+Then you can add this to your QEMU command line:
+
+.. code-block:: shell
+
+-drive file=blknvme,if=none,id=mynvme,format=raw \
+-device nvme,drive=mynvme,serial=deadbeef,spdm=2323
+
+At which point QEMU will try to connect to the SPDM server.
+
+
+.. _DMTF:
+   https://www.dmtf.org/standards/SPDM
+
+.. _SPDM Utils:
+   https://github.com/westerndigitalcorporation/spdm-utils
+
+.. _spdm emu:
+   https://github.com/dmtf/spdm-emu
+
+.. _Build SPDM Utils:
+   https://github.com/westerndigitalcorporation/spdm-utils#building
+
+.. _Generate the certificates:
+   
https://github.com/westerndigitalcorporation/spdm-utils#generate-mutable-certificates
+
+.. _Run it as a server:
+   
https://github.com/westerndigitalcorporation/spdm-utils#qemu-spdm-device-emulation
diff --git a/include/hw/pci/pci_device.h b/include/hw/pci/pci_device.h
index d3dd0f64b2..b8379c78f1 100644
--- a/include/hw/pci/pci_device.h
+++ b/include/hw/pci/pci_device.h
@@ -3,6 +3,7 @@
 
 #include "hw/pci/pci.h"
 #include "hw/pci/pcie.h"
+#include "hw/pci/pcie_doe.h"
 
 #define TYPE_PCI_DEVICE "pci-devic

[PATCH v2 0/3] Initial support for SPDM Responders

2023-10-16 Thread Alistair Francis
The Security Protocol and Data Model (SPDM) Specification defines
messages, data objects, and sequences for performing message exchanges
over a variety of transport and physical media.
 - 
https://www.dmtf.org/sites/default/files/standards/documents/DSP0274_1.3.0.pdf

SPDM currently supports PCIe DOE and MCTP transports, but it can be
extended to support others in the future. This series adds
support to QEMU to connect to an external SPDM instance.

SPDM support can be added to any QEMU device by exposing a
TCP socket to a SPDM server. The server can then implement the SPDM
decoding/encoding support, generally using libspdm [2].

This is similar to how the current TPM implementation works and means
that the heavy lifting of setting up certificate chains, capabilities,
measurements and complex crypto can be done outside QEMU by a well
supported and tested library.

This series implements socket support and exposes SPDM for a NVMe device.

2: https://github.com/DMTF/libspdm

v2:
 - Add cover letter
 - A few code fixes based on comments
 - Document SPDM-Utils
 - A few tweaks and clarifications to the documentation

Alistair Francis (1):
  hw/pci: Add all Data Object Types defined in PCIe r6.0

Huai-Cheng Kuo (1):
  backends: Initial support for SPDM socket support

Wilfred Mallawa (1):
  hw/nvme: Add SPDM over DOE support

 docs/specs/index.rst |   1 +
 docs/specs/spdm.rst  | 114 ++
 include/hw/pci/pci_device.h  |   5 +
 include/hw/pci/pcie_doe.h|   5 +
 include/sysemu/spdm-socket.h |  44 +++
 backends/spdm-socket.c   | 216 +++
 hw/nvme/ctrl.c   |  53 +
 backends/Kconfig |   4 +
 backends/meson.build |   2 +
 9 files changed, 444 insertions(+)
 create mode 100644 docs/specs/spdm.rst
 create mode 100644 include/sysemu/spdm-socket.h
 create mode 100644 backends/spdm-socket.c

-- 
2.41.0




[PATCH v2 2/3] backends: Initial support for SPDM socket support

2023-10-16 Thread Alistair Francis
From: Huai-Cheng Kuo 

SPDM enables authentication, attestation and key exchange to assist in
providing infrastructure security enablement. It's a standard published
by the DMTF [1].

SPDM supports multiple transports, including PCIe DOE and MCTP.
This patch adds support to QEMU to connect to an external SPDM
instance.

SPDM support can be added to any QEMU device by exposing a
TCP socket to a SPDM server. The server can then implement the SPDM
decoding/encoding support, generally using libspdm [2].

This is similar to how the current TPM implementation works and means
that the heavy lifting of setting up certificate chains, capabilities,
measurements and complex crypto can be done outside QEMU by a well
supported and tested library.

1: https://www.dmtf.org/standards/SPDM
2: https://github.com/DMTF/libspdm

Signed-off-by: Huai-Cheng Kuo 
Signed-off-by: Chris Browy 
Co-developed-by: Jonathan Cameron 
Signed-off-by: Jonathan Cameron 
[ Changes by WM
 - Bug fixes from testing
]
Signed-off-by: Wilfred Mallawa 
[ Changes by AF:
 - Convert to be more QEMU-ified
 - Move to backends as it isn't PCIe specific
]
Signed-off-by: Alistair Francis 
---
 include/sysemu/spdm-socket.h |  44 +++
 backends/spdm-socket.c   | 216 +++
 backends/Kconfig |   4 +
 backends/meson.build |   2 +
 4 files changed, 266 insertions(+)
 create mode 100644 include/sysemu/spdm-socket.h
 create mode 100644 backends/spdm-socket.c

diff --git a/include/sysemu/spdm-socket.h b/include/sysemu/spdm-socket.h
new file mode 100644
index 00..24e6fccb83
--- /dev/null
+++ b/include/sysemu/spdm-socket.h
@@ -0,0 +1,44 @@
+/*
+ * QEMU SPDM socket support
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to 
deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#ifndef SPDM_REQUESTER_H
+#define SPDM_REQUESTER_H
+
+int spdm_socket_connect(uint16_t port, Error **errp);
+uint32_t spdm_socket_rsp(const int socket, uint32_t transport_type,
+ void *req, uint32_t req_len,
+ void *rsp, uint32_t rsp_len);
+void spdm_socket_close(const int socket, uint32_t transport_type);
+
+#define SPDM_SOCKET_COMMAND_NORMAL0x0001
+#define SPDM_SOCKET_COMMAND_OOB_ENCAP_KEY_UPDATE  0x8001
+#define SPDM_SOCKET_COMMAND_CONTINUE  0xFFFD
+#define SPDM_SOCKET_COMMAND_SHUTDOWN  0xFFFE
+#define SPDM_SOCKET_COMMAND_UNKOWN0x
+#define SPDM_SOCKET_COMMAND_TEST  0xDEAD
+
+#define SPDM_SOCKET_TRANSPORT_TYPE_MCTP   0x01
+#define SPDM_SOCKET_TRANSPORT_TYPE_PCI_DOE0x02
+
+#define SPDM_SOCKET_MAX_MESSAGE_BUFFER_SIZE   0x1200
+
+#endif
diff --git a/backends/spdm-socket.c b/backends/spdm-socket.c
new file mode 100644
index 00..d0663d696c
--- /dev/null
+++ b/backends/spdm-socket.c
@@ -0,0 +1,216 @@
+/* SPDX-License-Identifier: BSD-3-Clause */
+/*
+ * QEMU SPDM socket support
+ *
+ * This is based on:
+ * 
https://github.com/DMTF/spdm-emu/blob/07c0a838bcc1c6207c656ac75885c0603e344b6f/spdm_emu/spdm_emu_common/command.c
+ * but has been re-written to match QEMU style
+ *
+ * Copyright (c) 2021, DMTF. All rights reserved.
+ * Copyright (c) 2023. Western Digital Corporation or its affiliates.
+ */
+
+#include "qemu/osdep.h"
+#include "sysemu/spdm-socket.h"
+#include "qapi/error.h"
+
+static bool read_bytes(const int socket, uint8_t *buffer,
+   size_t number_of_bytes)
+{
+ssize_t number_received = 0;
+ssize_t result;
+
+while (number_received < number_of_bytes) {
+result = recv(socket, buffer + number_received,
+  number_of_bytes - number_received, 0);
+if (result <= 0) {
+return false;
+}
+number_received += result;
+}
+return true;
+}
+
+static bool read_data32(const int socket, uint32_t *data)
+{
+bool result;
+
+result = read_bytes(sock

[PATCH v2 1/3] hw/pci: Add all Data Object Types defined in PCIe r6.0

2023-10-16 Thread Alistair Francis
Add all of the defined protocols/features from the PCIe-SIG r6.0
"Table 6-32 PCI-SIG defined Data Object Types (Vendor ID = 0001h)"
table.

Signed-off-by: Alistair Francis 
---
 include/hw/pci/pcie_doe.h | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/include/hw/pci/pcie_doe.h b/include/hw/pci/pcie_doe.h
index 87dc17dcef..15d94661f9 100644
--- a/include/hw/pci/pcie_doe.h
+++ b/include/hw/pci/pcie_doe.h
@@ -46,6 +46,8 @@ REG32(PCI_DOE_CAP_STATUS, 0)
 
 /* PCI-SIG defined Data Object Types - r6.0 Table 6-32 */
 #define PCI_SIG_DOE_DISCOVERY   0x00
+#define PCI_SIG_DOE_CMA 0x01
+#define PCI_SIG_DOE_SECURED_CMA 0x02
 
 #define PCI_DOE_DW_SIZE_MAX (1 << 18)
 #define PCI_DOE_PROTOCOL_NUM_MAX256
-- 
2.41.0




Re: [PATCH 2/3] backends: Initial support for SPDM socket support

2023-09-21 Thread Alistair Francis
On Mon, Sep 18, 2023 at 8:28 PM Jonathan Cameron
 wrote:
>
> On Mon, 18 Sep 2023 13:16:01 +1000
> Alistair Francis  wrote:
>
> > On Sat, Sep 16, 2023 at 1:19 AM Jonathan Cameron
> >  wrote:
> > >
> > > On Fri, 15 Sep 2023 21:27:22 +1000
> > > Alistair Francis  wrote:
> > >
> > > > From: Huai-Cheng Kuo 
> > >
> > > Great to see you taking this forwards!
> > >
> > >
> > > >
> > > > SPDM enables authentication, attestation and key exchange to assist in
> > > > providing infrastructure security enablement. It's a standard published
> > > > by the DMTF [1].
> > > >
> > > > SPDM currently supports PCIe DOE and MCTP transports, but it can be
> > > > extended to support others in the future. This patch adds
> > > > support to QEMU to connect to an external SPDM instance.
> > >
> > > It supports way more that that these days.  I'd just say 'multiple'
> > > transports.
> > >
> > > >
> > > > SPDM support can be added to any QEMU device by exposing a
> > > > TCP socket to a SPDM server. The server can then implement the SPDM
> > > > decoding/encoding support, generally using libspdm [2].
> > > >
> > > > This is similar to how the current TPM implementation works and means
> > > > that the heavy lifting of setting up certificate chains, capabilities,
> > > > measurements and complex crypto can be done outside QEMU by a well
> > > > supported and tested library.
> > >
> > > Is this sufficient for usecases beyond initial attestation flows?
> >
> > I believe so.
> >
> > The SPDM responder would be in charge of doing all of this. For the
> > rest of the discussion the responder is the software on the other end
> > of the QEMU socket.
> >
> > > How does measurement work for example?  We need settings from the
> >
> > In a basic case the responder can generate measurement data. For
> > example the responder can return digests of the firmware. Now there
> > won't actually be "firmware", but the responder can still return
> > measurement data.
> >
> > if you are trying to test an existing product, you could fake it and
> > return the same values as a real device. Otherwise you could return
> > example data.
> >
> > > emulated device to squirt into the SPDM agent so that it can be
> > > encrypted and signed etc.
> > >
> > > Measurement reports often need to include the status of various config
> > > space registers + any device specific additional stuff - not sure
> > > what is defined for NVME but I suspect the list will grow, particularly
> > > when tdisp is included.  There are some things called out in the PCIe
> > > state as must haves, like any debug features must be reported.
> >
> > So this is probably the hard part. How can the responder measurements
> > change based on configuration values set by the host.
> >
> > Just for completeness, the idea would be the host would set some state
> > in the NVMe controller for example. Then we would expect the
> > measurement values to change.
> >
> > That's trickier, but we could extend the socket to communicate state
> > like that. So when a measurement state changes in the QEMU model, we
> > relay that to the responder. Which then changes the measurements
> >
> > > Also we need a way to mess with firmware revisions reported
> > > as those are likely to be checked.
> >
> > That seems like something you can do via command line arguments or
> > configuration settings to the responder. This is separate to QEMU
> I'm not convinced it is because QEMU is emulating the firmware behavior
> and that may well change with version.  Still it's just more metadata
> to push out from QEMU to the SPDM instance.
>
> My gut feeling is you'd just add an interface for the whole measurement
> record coming from QEMU.  No need to be clever with sending only small
> subsets of info and building the measurement.

That also works. libspdm delegates the measurement work anyway, so
it's easy to handle either in the external socket wrapper or in QEMU.

>
> >
> > >
> > > I'm not sure that model will work with the spdm-emu approach.
> >
> > I don't think there is anything specifically in the socket approach
> > that limits this from working. It comes down to passing information
> > from the QEMU emulated device to the SPDM responder. That needs to be
> > done either w

Re: [PATCH 2/3] backends: Initial support for SPDM socket support

2023-09-17 Thread Alistair Francis
On Sat, Sep 16, 2023 at 1:19 AM Jonathan Cameron
 wrote:
>
> On Fri, 15 Sep 2023 21:27:22 +1000
> Alistair Francis  wrote:
>
> > From: Huai-Cheng Kuo 
>
> Great to see you taking this forwards!
>
>
> >
> > SPDM enables authentication, attestation and key exchange to assist in
> > providing infrastructure security enablement. It's a standard published
> > by the DMTF [1].
> >
> > SPDM currently supports PCIe DOE and MCTP transports, but it can be
> > extended to support others in the future. This patch adds
> > support to QEMU to connect to an external SPDM instance.
>
> It supports way more that that these days.  I'd just say 'multiple'
> transports.
>
> >
> > SPDM support can be added to any QEMU device by exposing a
> > TCP socket to a SPDM server. The server can then implement the SPDM
> > decoding/encoding support, generally using libspdm [2].
> >
> > This is similar to how the current TPM implementation works and means
> > that the heavy lifting of setting up certificate chains, capabilities,
> > measurements and complex crypto can be done outside QEMU by a well
> > supported and tested library.
>
> Is this sufficient for usecases beyond initial attestation flows?

I believe so.

The SPDM responder would be in charge of doing all of this. For the
rest of the discussion the responder is the software on the other end
of the QEMU socket.

> How does measurement work for example?  We need settings from the

In a basic case the responder can generate measurement data. For
example the responder can return digests of the firmware. Now there
won't actually be "firmware", but the responder can still return
measurement data.

if you are trying to test an existing product, you could fake it and
return the same values as a real device. Otherwise you could return
example data.

> emulated device to squirt into the SPDM agent so that it can be
> encrypted and signed etc.
>
> Measurement reports often need to include the status of various config
> space registers + any device specific additional stuff - not sure
> what is defined for NVME but I suspect the list will grow, particularly
> when tdisp is included.  There are some things called out in the PCIe
> state as must haves, like any debug features must be reported.

So this is probably the hard part. How can the responder measurements
change based on configuration values set by the host.

Just for completeness, the idea would be the host would set some state
in the NVMe controller for example. Then we would expect the
measurement values to change.

That's trickier, but we could extend the socket to communicate state
like that. So when a measurement state changes in the QEMU model, we
relay that to the responder. Which then changes the measurements

> Also we need a way to mess with firmware revisions reported
> as those are likely to be checked.

That seems like something you can do via command line arguments or
configuration settings to the responder. This is separate to QEMU

>
> I'm not sure that model will work with the spdm-emu approach.

I don't think there is anything specifically in the socket approach
that limits this from working. It comes down to passing information
from the QEMU emulated device to the SPDM responder. That needs to be
done either way. It probably is simpler to do if libspdm is included
as part of QEMU, but that brings along other complexities.

As you pointed out in my original RFC, the complexity of configuration
a responder via the QEMU command line will be very difficult. I think
it's simpler to keep the responder outside and QEMU and just pass any
relevant data to the responder as required.

>
> Anyhow, I think we need to have gotten a little further figuring that
> out before we merge a solution.  I've been carrying this on the CXL
> staging tree for a long time because I couldn't figure out a good solution
> to the amount of information that needs to go between them.
>
> For those not familiar with the fun of libSPDM it is a pain to work with
> which is why Huai-Cheng instead connected with the demo app.
>
> Any more luck getting a reliable build to work?

Yes!

libspdm is now packaged in buildroot:
https://github.com/buildroot/buildroot/blob/master/package/libspdm/libspdm.mk

You can now build libspdm with openSSL provided by your distro as you
don't need to access any private openSSL APIs any more.

The hope is we can continue to march towards including libspdm as a
standard library in distros, which should make the entire process
easier.

>
> >
> > 1: https://www.dmtf.org/standards/SPDM
> > 2: https://github.com/DMTF/libspdm
> >
> > Signed-off-by: Huai-Cheng Kuo 
> > Signed-off-by: Chris Browy 
> > Co-developed-by: Jonathan Cameron 
> > Si

[PATCH 1/3] hw/pci: Add all Data Object Types

2023-09-15 Thread Alistair Francis
Add all of the defined protocols/features from the PCIe-SIG
"Table 6-32 PCI-SIG defined Data Object Types (Vendor ID = 0001h)"
table.

Signed-off-by: Alistair Francis 
---
 include/hw/pci/pcie_doe.h | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/include/hw/pci/pcie_doe.h b/include/hw/pci/pcie_doe.h
index 87dc17dcef..15d94661f9 100644
--- a/include/hw/pci/pcie_doe.h
+++ b/include/hw/pci/pcie_doe.h
@@ -46,6 +46,8 @@ REG32(PCI_DOE_CAP_STATUS, 0)
 
 /* PCI-SIG defined Data Object Types - r6.0 Table 6-32 */
 #define PCI_SIG_DOE_DISCOVERY   0x00
+#define PCI_SIG_DOE_CMA 0x01
+#define PCI_SIG_DOE_SECURED_CMA 0x02
 
 #define PCI_DOE_DW_SIZE_MAX (1 << 18)
 #define PCI_DOE_PROTOCOL_NUM_MAX256
-- 
2.41.0




[PATCH 3/3] hw/nvme: Add SPDM over DOE support

2023-09-15 Thread Alistair Francis
From: Wilfred Mallawa 

Setup Data Object Exchance (DOE) as an extended capability for the NVME
controller and connect SPDM to it (CMA) to it.

Signed-off-by: Wilfred Mallawa 
Signed-off-by: Alistair Francis 
---
 docs/specs/index.rst|  1 +
 docs/specs/spdm.rst | 56 +
 include/hw/pci/pci_device.h |  5 
 include/hw/pci/pcie_doe.h   |  3 ++
 hw/nvme/ctrl.c  | 52 ++
 hw/nvme/trace-events|  1 +
 6 files changed, 118 insertions(+)
 create mode 100644 docs/specs/spdm.rst

diff --git a/docs/specs/index.rst b/docs/specs/index.rst
index e58be38c41..c398541388 100644
--- a/docs/specs/index.rst
+++ b/docs/specs/index.rst
@@ -24,3 +24,4 @@ guest hardware that is specific to QEMU.
acpi_erst
sev-guest-firmware
fw_cfg
+   spdm
diff --git a/docs/specs/spdm.rst b/docs/specs/spdm.rst
new file mode 100644
index 00..0f96d618ef
--- /dev/null
+++ b/docs/specs/spdm.rst
@@ -0,0 +1,56 @@
+==
+QEMU Security Protocols and Data Models (SPDM) Support
+==
+
+SPDM enables authentication, attestation and key exchange to assist in
+providing infrastructure security enablement. It's a standard published
+by the DMTF https://www.dmtf.org/standards/SPDM.
+
+Setting up a SPDM server
+
+
+When using QEMU with SPDM devices QEMU will connect to a server which
+implements the SPDM functionality.
+
+spdm-emu
+
+
+You can use spdm-emu https://github.com/dmtf/spdm-emu to model the
+SPDM responder.
+
+.. code-block:: shell
+
+$ cd spdm-emu
+$ git submodule init; git submodule update --recursive
+$ mkdir build; cd build
+$ cmake -DARCH=x64 -DTOOLCHAIN=GCC -DTARGET=Debug -DCRYPTO=openssl ..
+$ make -j32
+$ make copy_sample_key # Build certificates, required for SPDM 
authentication.
+
+The responder can then be launched with
+
+.. code-block:: shell
+
+$ cd bin
+$ ./spdm_responder_emu --trans PCI_DOE
+
+Connecting an SPDM NVMe device
+==
+
+Once a SPDM server is running we can start QEMU and connect to the server.
+
+For an NVMe device first let's setup a block we can use
+
+.. code-block:: shell
+
+$ cd qemu-spdm/linux/image
+$ dd if=/dev/zero of=blknvme bs=1M count=2096 # 2GB NNMe Drive
+
+Then you can add this to your QEMU command line:
+
+.. code-block:: shell
+
+-drive file=blknvme,if=none,id=mynvme,format=raw \
+-device nvme,drive=mynvme,serial=deadbeef,spdm=2323
+
+At which point QEMU will connect to the SPDM server.
diff --git a/include/hw/pci/pci_device.h b/include/hw/pci/pci_device.h
index d3dd0f64b2..b8379c78f1 100644
--- a/include/hw/pci/pci_device.h
+++ b/include/hw/pci/pci_device.h
@@ -3,6 +3,7 @@
 
 #include "hw/pci/pci.h"
 #include "hw/pci/pcie.h"
+#include "hw/pci/pcie_doe.h"
 
 #define TYPE_PCI_DEVICE "pci-device"
 typedef struct PCIDeviceClass PCIDeviceClass;
@@ -157,6 +158,10 @@ struct PCIDevice {
 MSIVectorReleaseNotifier msix_vector_release_notifier;
 MSIVectorPollNotifier msix_vector_poll_notifier;
 
+/* DOE */
+DOECap doe_spdm;
+uint16_t spdm_port;
+
 /* ID of standby device in net_failover pair */
 char *failover_pair_id;
 uint32_t acpi_index;
diff --git a/include/hw/pci/pcie_doe.h b/include/hw/pci/pcie_doe.h
index 15d94661f9..eb8f4e393d 100644
--- a/include/hw/pci/pcie_doe.h
+++ b/include/hw/pci/pcie_doe.h
@@ -108,6 +108,9 @@ struct DOECap {
 /* Protocols and its callback response */
 DOEProtocol *protocols;
 uint16_t protocol_num;
+
+/* Used for spdm-socket */
+int socket;
 };
 
 void pcie_doe_init(PCIDevice *pdev, DOECap *doe_cap, uint16_t offset,
diff --git a/hw/nvme/ctrl.c b/hw/nvme/ctrl.c
index 90687b168a..1ff30a9ad4 100644
--- a/hw/nvme/ctrl.c
+++ b/hw/nvme/ctrl.c
@@ -203,6 +203,7 @@
 #include "sysemu/hostmem.h"
 #include "hw/pci/msix.h"
 #include "hw/pci/pcie_sriov.h"
+#include "sysemu/spdm-socket.h"
 #include "migration/vmstate.h"
 
 #include "nvme.h"
@@ -8077,6 +8078,28 @@ static int nvme_add_pm_capability(PCIDevice *pci_dev, 
uint8_t offset)
 return 0;
 }
 
+static bool pcie_doe_spdm_rsp(DOECap *doe_cap)
+{
+void *req = pcie_doe_get_write_mbox_ptr(doe_cap);
+uint32_t req_len = pcie_doe_get_obj_len(req) * 4;
+void *rsp = doe_cap->read_mbox;
+uint32_t rsp_len = SPDM_SOCKET_MAX_MESSAGE_BUFFER_SIZE;
+uint32_t recvd;
+
+recvd = spdm_socket_rsp(doe_cap->socket,
+ SPDM_SOCKET_TRANSPORT_TYPE_PCI_DOE,
+ req, req_len, rsp, rsp_len);
+doe_cap->read_mbox_len += DIV_ROUND_UP(recvd, 4);
+
+return (recvd == 0) ? false : true;
+}
+
+static DOEProtocol doe_spdm_prot[] = {
+{ PCI_VENDOR_ID_PCI_SIG, PCI_SIG_DOE_CMA, pcie_doe_spdm_rsp },
+{ P

[PATCH 2/3] backends: Initial support for SPDM socket support

2023-09-15 Thread Alistair Francis
From: Huai-Cheng Kuo 

SPDM enables authentication, attestation and key exchange to assist in
providing infrastructure security enablement. It's a standard published
by the DMTF [1].

SPDM currently supports PCIe DOE and MCTP transports, but it can be
extended to support others in the future. This patch adds
support to QEMU to connect to an external SPDM instance.

SPDM support can be added to any QEMU device by exposing a
TCP socket to a SPDM server. The server can then implement the SPDM
decoding/encoding support, generally using libspdm [2].

This is similar to how the current TPM implementation works and means
that the heavy lifting of setting up certificate chains, capabilities,
measurements and complex crypto can be done outside QEMU by a well
supported and tested library.

1: https://www.dmtf.org/standards/SPDM
2: https://github.com/DMTF/libspdm

Signed-off-by: Huai-Cheng Kuo 
Signed-off-by: Chris Browy 
Co-developed-by: Jonathan Cameron 
Signed-off-by: Jonathan Cameron 
[ Changes by AF:
 - Convert to be more QEMU-ified
 - Move to backends as it isn't PCIe specific
]
Signed-off-by: Alistair Francis 
Signed-off-by: Wilfred Mallawa 
---
 include/sysemu/spdm-socket.h |  44 +++
 backends/spdm-socket.c   | 215 +++
 backends/Kconfig |   4 +
 backends/meson.build |   2 +
 4 files changed, 265 insertions(+)
 create mode 100644 include/sysemu/spdm-socket.h
 create mode 100644 backends/spdm-socket.c

diff --git a/include/sysemu/spdm-socket.h b/include/sysemu/spdm-socket.h
new file mode 100644
index 00..24e6fccb83
--- /dev/null
+++ b/include/sysemu/spdm-socket.h
@@ -0,0 +1,44 @@
+/*
+ * QEMU SPDM socket support
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to 
deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#ifndef SPDM_REQUESTER_H
+#define SPDM_REQUESTER_H
+
+int spdm_socket_connect(uint16_t port, Error **errp);
+uint32_t spdm_socket_rsp(const int socket, uint32_t transport_type,
+ void *req, uint32_t req_len,
+ void *rsp, uint32_t rsp_len);
+void spdm_socket_close(const int socket, uint32_t transport_type);
+
+#define SPDM_SOCKET_COMMAND_NORMAL0x0001
+#define SPDM_SOCKET_COMMAND_OOB_ENCAP_KEY_UPDATE  0x8001
+#define SPDM_SOCKET_COMMAND_CONTINUE  0xFFFD
+#define SPDM_SOCKET_COMMAND_SHUTDOWN  0xFFFE
+#define SPDM_SOCKET_COMMAND_UNKOWN0x
+#define SPDM_SOCKET_COMMAND_TEST  0xDEAD
+
+#define SPDM_SOCKET_TRANSPORT_TYPE_MCTP   0x01
+#define SPDM_SOCKET_TRANSPORT_TYPE_PCI_DOE0x02
+
+#define SPDM_SOCKET_MAX_MESSAGE_BUFFER_SIZE   0x1200
+
+#endif
diff --git a/backends/spdm-socket.c b/backends/spdm-socket.c
new file mode 100644
index 00..2f31ba80ba
--- /dev/null
+++ b/backends/spdm-socket.c
@@ -0,0 +1,215 @@
+/* SPDX-License-Identifier: BSD-3-Clause */
+/*
+ * QEMU SPDM socket support
+ *
+ * This is based on:
+ * 
https://github.com/DMTF/spdm-emu/blob/07c0a838bcc1c6207c656ac75885c0603e344b6f/spdm_emu/spdm_emu_common/command.c
+ * but has been re-written to match QEMU style
+ *
+ * Copyright (c) 2021, DMTF. All rights reserved.
+ * Copyright (c) 2023. Western Digital Corporation or its affiliates.
+ */
+
+#include "qemu/osdep.h"
+#include "sysemu/spdm-socket.h"
+#include "qapi/error.h"
+
+static bool read_bytes(const int socket, uint8_t *buffer,
+   size_t number_of_bytes)
+{
+ssize_t number_received = 0;
+ssize_t result;
+
+while (number_received < number_of_bytes) {
+result = recv(socket, buffer + number_received,
+  number_of_bytes - number_received, 0);
+if (result <= 0) {
+return false;
+}
+number_received += result;
+}
+return true;
+}
+
+static bool read_data32(const int socket, uint32_t *data)
+{
+bool result;
+
+result = read_bytes(sock

Re: [PATCH v4 13/19] riscv: Clean up includes

2023-01-19 Thread Alistair Francis
On Thu, Jan 19, 2023 at 5:10 PM Markus Armbruster  wrote:
>
> Clean up includes so that osdep.h is included first and headers
> which it implies are not included manually.
>
> This commit was created with scripts/clean-includes.
>
> Signed-off-by: Markus Armbruster 

Reviewed-by: Alistair Francis 

Alistair

> ---
>  target/riscv/pmu.h | 1 -
>  1 file changed, 1 deletion(-)
>
> diff --git a/target/riscv/pmu.h b/target/riscv/pmu.h
> index 3004ce37b6..0c819ca983 100644
> --- a/target/riscv/pmu.h
> +++ b/target/riscv/pmu.h
> @@ -16,7 +16,6 @@
>   * this program.  If not, see <http://www.gnu.org/licenses/>.
>   */
>
> -#include "qemu/osdep.h"
>  #include "qemu/log.h"
>  #include "cpu.h"
>  #include "qemu/main-loop.h"
> --
> 2.39.0
>
>



Re: completion timeouts with pin-based interrupts in QEMU hw/nvme

2023-01-18 Thread Alistair Francis
On Thu, Jan 19, 2023 at 12:44 PM Keith Busch  wrote:
>
> On Thu, Jan 19, 2023 at 10:41:42AM +1000, Alistair Francis wrote:
> > On Thu, Jan 19, 2023 at 9:07 AM Keith Busch  wrote:
> > > ---
> > > diff --git a/hw/intc/sifive_plic.c b/hw/intc/sifive_plic.c
> > > index c2dfacf028..f8f7af08dc 100644
> > > --- a/hw/intc/sifive_plic.c
> > > +++ b/hw/intc/sifive_plic.c
> > > @@ -157,7 +157,6 @@ static uint64_t sifive_plic_read(void *opaque, hwaddr 
> > > addr, unsigned size)
> > >  uint32_t max_irq = sifive_plic_claimed(plic, addrid);
> > >
> > >  if (max_irq) {
> > > -sifive_plic_set_pending(plic, max_irq, false);
> > >  sifive_plic_set_claimed(plic, max_irq, true);
> > >  }
> > >
> >
> > This change isn't correct. The PLIC spec
> > (https://github.com/riscv/riscv-plic-spec/releases/download/1.0.0_rc5/riscv-plic-1.0.0_rc5.pdf)
> > states:
> >
> > """
> > On receiving a claim message, the PLIC core will atomically determine
> > the ID of the highest-priority pending interrupt for the target and
> > then clear down the corresponding source’s IP bit
> > """
> >
> > which is what we are doing here. We are clearing the pending interrupt
> > inside the PLIC
>
> Thanks for the link. That's very helpful.
>
> If you're familiar with this area, could you possibly clear up this part
> of that spec?
>
> "
> On receiving an interrupt completion message, if the interrupt is
> level-triggered and the interrupt is still asserted, a new interrupt
> request will be forwarded to the PLIC core.
> "
>
> Further up, it says the "interrupt gateway" is responsible for
> forwarding new interrupt requests while the level remains asserted, but
> it doesn't look like anything is handling that, which essentially turns
> this into an edge interrupt. Am I missing something, or is this really
> not being handled?

Yeah, that wouldn't be handled. In QEMU the PLIC relies on QEMUs
internal GPIO lines to trigger an interrupt. So with the current setup
we only support edge triggered interrupts.

It looks like we also drop the pending bit if the original interrupt
de-asserts, which appears to be incorrect as well.

Alistair



Re: completion timeouts with pin-based interrupts in QEMU hw/nvme

2023-01-18 Thread Alistair Francis
On Thu, Jan 19, 2023 at 9:07 AM Keith Busch  wrote:
>
> On Wed, Jan 18, 2023 at 09:33:05AM -0700, Keith Busch wrote:
> > On Wed, Jan 18, 2023 at 03:04:06PM +, Peter Maydell wrote:
> > > On Tue, 17 Jan 2023 at 19:21, Guenter Roeck  wrote:
> > > > Anyway - any idea what to do to help figuring out what is happening ?
> > > > Add tracing support to pci interrupt handling, maybe ?
> > >
> > > For intermittent bugs, I like recording the QEMU session under
> > > rr (using its chaos mode to provoke the failure if necessary) to
> > > get a recording that I can debug and re-debug at leisure. Usually
> > > you want to turn on/add tracing to help with this, and if the
> > > failure doesn't hit early in bootup then you might need to
> > > do a QEMU snapshot just before point-of-failure so you can
> > > run rr only on the short snapshot-to-failure segment.
> > >
> > > https://translatedcode.wordpress.com/2015/05/30/tricks-for-debugging-qemu-rr/
> > > https://translatedcode.wordpress.com/2015/07/06/tricks-for-debugging-qemu-savevm-snapshots/
> > >
> > > This gives you a debugging session from the QEMU side's perspective,
> > > of course -- assuming you know what the hardware is supposed to do
> > > you hopefully wind up with either "the guest software did X,Y,Z
> > > and we incorrectly did A" or else "the guest software did X,Y,Z,
> > > the spec says A is the right/a permitted thing but the guest got 
> > > confused".
> > > If it's the latter then you have to look at the guest as a separate
> > > code analysis/debug problem.
> >
> > Here's what I got, though I'm way out of my depth here.
> >
> > It looks like Linux kernel's fasteoi for RISC-V's PLIC claims the
> > interrupt after its first handling, which I think is expected. After
> > claiming, QEMU masks the pending interrupt, lowering the level, though
> > the device that raised it never deasserted.
>
> I'm not sure if this is correct, but this is what I'm coming up with and
> appears to fix the problem on my setup. The hardware that sets the
> pending interrupt is going clear it, so I don't see why the interrupt
> controller is automatically clearing it when the host claims it.
>
> ---
> diff --git a/hw/intc/sifive_plic.c b/hw/intc/sifive_plic.c
> index c2dfacf028..f8f7af08dc 100644
> --- a/hw/intc/sifive_plic.c
> +++ b/hw/intc/sifive_plic.c
> @@ -157,7 +157,6 @@ static uint64_t sifive_plic_read(void *opaque, hwaddr 
> addr, unsigned size)
>  uint32_t max_irq = sifive_plic_claimed(plic, addrid);
>
>  if (max_irq) {
> -sifive_plic_set_pending(plic, max_irq, false);
>  sifive_plic_set_claimed(plic, max_irq, true);
>  }
>

This change isn't correct. The PLIC spec
(https://github.com/riscv/riscv-plic-spec/releases/download/1.0.0_rc5/riscv-plic-1.0.0_rc5.pdf)
states:

"""
On receiving a claim message, the PLIC core will atomically determine
the ID of the highest-priority pending interrupt for the target and
then clear down the corresponding source’s IP bit
"""

which is what we are doing here. We are clearing the pending interrupt
inside the PLIC

Alistair



Re: [PATCH v2] hw/misc/sifive_u_otp: Remove the deprecated OTP config with '-drive if=none'

2023-01-12 Thread Alistair Francis
On Thu, Jan 12, 2023 at 6:40 PM Thomas Huth  wrote:
>
> '-drive if=none' is meant for configuring back-end devices only, so this
> got marked as deprecated in QEMU 6.2. Users should now only use the new
> way with '-drive if=pflash' instead.
>
> Signed-off-by: Thomas Huth 

Reviewed-by: Alistair Francis 

Alistair

> ---
>  docs/about/deprecated.rst   | 6 --
>  docs/about/removed-features.rst | 7 +++
>  hw/misc/sifive_u_otp.c  | 7 ---
>  3 files changed, 7 insertions(+), 13 deletions(-)
>
> diff --git a/docs/about/deprecated.rst b/docs/about/deprecated.rst
> index 68d29642d7..bfe8148490 100644
> --- a/docs/about/deprecated.rst
> +++ b/docs/about/deprecated.rst
> @@ -87,12 +87,6 @@ as short-form boolean values, and passed to plugins as 
> ``arg_name=on``.
>  However, short-form booleans are deprecated and full explicit ``arg_name=on``
>  form is preferred.
>
> -``-drive if=none`` for the sifive_u OTP device (since 6.2)
> -''
> -
> -Using ``-drive if=none`` to configure the OTP device of the sifive_u
> -RISC-V machine is deprecated. Use ``-drive if=pflash`` instead.
> -
>  ``-no-hpet`` (since 8.0)
>  
>
> diff --git a/docs/about/removed-features.rst b/docs/about/removed-features.rst
> index c918cabd1a..6bd0a2b4e4 100644
> --- a/docs/about/removed-features.rst
> +++ b/docs/about/removed-features.rst
> @@ -422,6 +422,13 @@ the value is hexadecimal.  That is, '0x20M' should be 
> written either as
>  ``tty`` and ``parport`` used to be aliases for ``serial`` and ``parallel``
>  respectively. The actual backend names should be used instead.
>
> +``-drive if=none`` for the sifive_u OTP device (removed in 8.0)
> +'''
> +
> +Use ``-drive if=pflash`` to configure the OTP device of the sifive_u
> +RISC-V machine instead.
> +
> +
>  QEMU Machine Protocol (QMP) commands
>  
>
> diff --git a/hw/misc/sifive_u_otp.c b/hw/misc/sifive_u_otp.c
> index 6d7fdb040a..8965f5c22a 100644
> --- a/hw/misc/sifive_u_otp.c
> +++ b/hw/misc/sifive_u_otp.c
> @@ -210,13 +210,6 @@ static void sifive_u_otp_realize(DeviceState *dev, Error 
> **errp)
>  sysbus_init_mmio(SYS_BUS_DEVICE(dev), >mmio);
>
>  dinfo = drive_get(IF_PFLASH, 0, 0);
> -if (!dinfo) {
> -dinfo = drive_get(IF_NONE, 0, 0);
> -if (dinfo) {
> -warn_report("using \"-drive if=none\" for the OTP is deprecated, 
> "
> -"use \"-drive if=pflash\" instead.");
> -}
> -}
>  if (dinfo) {
>  int ret;
>  uint64_t perm;
> --
> 2.31.1
>
>



Re: [PATCH v2] m25p80: Improve error when the backend file size does not match the device

2022-11-15 Thread Alistair Francis
On Wed, Nov 16, 2022 at 1:13 AM Cédric Le Goater  wrote:
>
> Currently, when a block backend is attached to a m25p80 device and the
> associated file size does not match the flash model, QEMU complains
> with the error message "failed to read the initial flash content".
> This is confusing for the user.
>
> Use blk_check_size_and_read_all() instead of blk_pread() to improve
> the reported error.
>
> Signed-off-by: Cédric Le Goater 

Reviewed-by: Alistair Francis 

Alistair

> ---
>  hw/block/m25p80.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/hw/block/m25p80.c b/hw/block/m25p80.c
> index 02adc87527..68a757abf3 100644
> --- a/hw/block/m25p80.c
> +++ b/hw/block/m25p80.c
> @@ -24,6 +24,7 @@
>  #include "qemu/osdep.h"
>  #include "qemu/units.h"
>  #include "sysemu/block-backend.h"
> +#include "hw/block/block.h"
>  #include "hw/qdev-properties.h"
>  #include "hw/qdev-properties-system.h"
>  #include "hw/ssi/ssi.h"
> @@ -1614,8 +1615,7 @@ static void m25p80_realize(SSIPeripheral *ss, Error 
> **errp)
>  trace_m25p80_binding(s);
>  s->storage = blk_blockalign(s->blk, s->size);
>
> -if (blk_pread(s->blk, 0, s->size, s->storage, 0) < 0) {
> -error_setg(errp, "failed to read the initial flash content");
> +if (!blk_check_size_and_read_all(s->blk, s->storage, s->size, errp)) 
> {
>  return;
>  }
>  } else {
> --
> 2.38.1
>
>



Re: [PATCH 1/9] hw/riscv/sifive_e: Fix inheritance of SiFiveEState

2022-09-19 Thread Alistair Francis
On Tue, Sep 20, 2022 at 9:18 AM Bernhard Beschow  wrote:
>
> SiFiveEState inherits from SysBusDevice while it's TypeInfo claims it to
> inherit from TYPE_MACHINE. This is an inconsistency which can cause
> undefined behavior such as memory corruption.
>
> Change SiFiveEState to inherit from MachineState since it is registered
> as a machine.
>
> Signed-off-by: Bernhard Beschow 

Reviewed-by: Alistair Francis 

Alistair

> ---
>  include/hw/riscv/sifive_e.h | 3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)
>
> diff --git a/include/hw/riscv/sifive_e.h b/include/hw/riscv/sifive_e.h
> index 83604da805..d738745925 100644
> --- a/include/hw/riscv/sifive_e.h
> +++ b/include/hw/riscv/sifive_e.h
> @@ -22,6 +22,7 @@
>  #include "hw/riscv/riscv_hart.h"
>  #include "hw/riscv/sifive_cpu.h"
>  #include "hw/gpio/sifive_gpio.h"
> +#include "hw/boards.h"
>
>  #define TYPE_RISCV_E_SOC "riscv.sifive.e.soc"
>  #define RISCV_E_SOC(obj) \
> @@ -41,7 +42,7 @@ typedef struct SiFiveESoCState {
>
>  typedef struct SiFiveEState {
>  /*< private >*/
> -SysBusDevice parent_obj;
> +MachineState parent_obj;
>
>  /*< public >*/
>  SiFiveESoCState soc;
> --
> 2.37.3
>
>



Re: [RFC] hw/block/m25p80: implement Octal SPI commands

2022-08-14 Thread Alistair Francis
On Sat, Aug 13, 2022 at 10:01 PM Anton Kochkov  wrote:
>
> * Implement Octal SPI commands based on Micron MT35X series
> * Fix Micron 0x2C-based ID handling (incompatible with Numonyx)
> * Fix Micron configuration registers handling
>
> Signed-off-by: Anton Kochkov 
> Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1148
> Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1149

+Edgar and Francisco, who are some of the Xilinx QEMU developers

Alistair

> ---
>  hw/block/m25p80.c | 173 +-
>  1 file changed, 141 insertions(+), 32 deletions(-)
>
> diff --git a/hw/block/m25p80.c b/hw/block/m25p80.c
> index a8d2519141..9342a3fe69 100644
> --- a/hw/block/m25p80.c
> +++ b/hw/block/m25p80.c
> @@ -127,6 +127,7 @@ typedef struct FlashPartInfo {
>  .die_cnt = _die_cnt
>
>  #define JEDEC_NUMONYX 0x20
> +#define JEDEC_MICRON 0x2C
>  #define JEDEC_WINBOND 0xEF
>  #define JEDEC_SPANSION 0x01
>
> @@ -149,6 +150,9 @@ typedef struct FlashPartInfo {
>  #define NVCFG_4BYTE_ADDR_MASK (1 << 0)
>  #define NVCFG_LOWER_SEGMENT_MASK (1 << 1)
>
> +/* Micron configuration register macros */
> +#define NVCFG_OCTAL_IO_MASK (1 << 5)
> +
>  /* Numonyx (Micron) Flag Status Register macros */
>  #define FSR_4BYTE_ADDR_MODE_ENABLED 0x1
>  #define FSR_FLASH_READY (1 << 7)
> @@ -360,6 +364,9 @@ typedef enum {
>  READ4 = 0x13,
>  FAST_READ = 0x0b,
>  FAST_READ4 = 0x0c,
> +O_FAST_READ = 0x9d,
> +O_FAST_READ4 = 0xfc,
> +OIOR_DDR = 0xfd,
>  DOR = 0x3b,
>  DOR4 = 0x3c,
>  QOR = 0x6b,
> @@ -368,6 +375,11 @@ typedef enum {
>  DIOR4 = 0xbc,
>  QIOR = 0xeb,
>  QIOR4 = 0xec,
> +OOR = 0x8b,
> +OOR4 = 0x8c,
> +OOR4_MT35X = 0x7c, /* according mt35x datasheet */
> +OIOR = 0xcb,
> +OIOR4 = 0xcc,
>
>  PP = 0x02,
>  PP4 = 0x12,
> @@ -378,6 +390,8 @@ typedef enum {
>  RDID_90 = 0x90,
>  RDID_AB = 0xab,
>  AAI_WP = 0xad,
> +OPP = 0x82,
> +OPP4 = 0x84,
>
>  ERASE_4K = 0x20,
>  ERASE4_4K = 0x21,
> @@ -427,6 +441,7 @@ typedef enum {
>  MAN_SPANSION,
>  MAN_MACRONIX,
>  MAN_NUMONYX,
> +MAN_MICRON,
>  MAN_WINBOND,
>  MAN_SST,
>  MAN_ISSI,
> @@ -462,6 +477,9 @@ struct Flash {
>  /* Configuration register for Macronix */
>  uint32_t volatile_cfg;
>  uint32_t enh_volatile_cfg;
> +/* Configuration register arrays for Micron */
> +uint32_t micron_volatile_cfg[8];
> +uint32_t micron_nonvolatile_cfg[8];
>  /* Spansion cfg registers. */
>  uint8_t spansion_cr1nv;
>  uint8_t spansion_cr2nv;
> @@ -476,6 +494,7 @@ struct Flash {
>  bool four_bytes_address_mode;
>  bool reset_enable;
>  bool quad_enable;
> +bool octal_enable;
>  bool aai_enable;
>  bool block_protect0;
>  bool block_protect1;
> @@ -504,6 +523,8 @@ static inline Manufacturer get_man(Flash *s)
>  switch (s->pi->id[0]) {
>  case 0x20:
>  return MAN_NUMONYX;
> +case 0x2C:
> +return MAN_MICRON;
>  case 0xEF:
>  return MAN_WINBOND;
>  case 0x01:
> @@ -684,12 +705,17 @@ static inline int get_addr_length(Flash *s)
> case QPP_4:
> case READ4:
> case QIOR4:
> +   case OIOR4:
> case ERASE4_4K:
> case ERASE4_32K:
> case ERASE4_SECTOR:
> case FAST_READ4:
> +   case O_FAST_READ4:
> +   case OIOR_DDR:
> case DOR4:
> case QOR4:
> +   case OOR4:
> +   case OOR4_MT35X:
> case DIOR4:
> return 4;
> default:
> @@ -719,9 +745,10 @@ static void complete_collecting_data(Flash *s)
>  case DPP:
>  case QPP:
>  case QPP_4:
> +case OPP:
>  case PP:
> +case OPP4:
>  case PP4:
> -case PP4_4:
>  s->state = STATE_PAGE_PROGRAM;
>  break;
>  case AAI_WP:
> @@ -732,15 +759,23 @@ static void complete_collecting_data(Flash *s)
>  case READ:
>  case READ4:
>  case FAST_READ:
> -case FAST_READ4:
> +case O_FAST_READ:
>  case DOR:
> -case DOR4:
>  case QOR:
> -case QOR4:
> +case OOR:
>  case DIOR:
> -case DIOR4:
>  case QIOR:
> +case OIOR:
> +case FAST_READ4:
> +case O_FAST_READ4:
> +case OIOR_DDR:
> +case DOR4:
> +case QOR4:
> +case OOR4:
> +case OOR4_MT35X:
> +case DIOR4:
>  case QIOR4:
> +case OIOR4:
>  s->state = STATE_READ;
>  break;
>  case ERASE_4K:
> @@ -785,15 +820,40 @@ static void complete_collecting_data(Flash *s)
>  s->write_enable = false;
>  }
>  break;
> -case BRWR:
>  case EXTEND_ADDR_WRITE:
>  s->ear = s->data[0];
>  break;
> +case RNVCR:
> +g_assert(get_man(s) == MAN_MICRON);
> +s->data[0] = s->micron_volatile_cfg[s->cur_addr & 0xFF];
> +s->pos = 0;
> +s->len = 1;
> +s->state = STATE_READING_DATA;
> +s->data_read_loop = true;
> +break;
> +case RVCR:
> +g_assert(get_man(s) == MAN_MICRON);
> +

Re: [PATCH v2 01/13] hw/sd/ssi-sd: Do not create SD card within controller's realize

2021-11-19 Thread Alistair Francis
On Thu, Nov 18, 2021 at 2:35 AM Markus Armbruster  wrote:
>
> ssi_sd_realize() creates an "sd-card" device.  This is inappropriate,
> and marked FIXME.
>
> Move it to the boards that create these devices.  Prior art: commit
> eb4f566bbb for device "generic-sdhci", and commit 26c607b86b for
> device "pl181".
>
> The device remains not user-creatable, because its users should (and
> do) wire up its GPIO chip-select line.
>
> Cc: Peter Maydell 
> Cc: Alistair Francis 
> Cc: Bin Meng 
> Cc: Palmer Dabbelt 
> Cc: "Philippe Mathieu-Daudé" 
> Cc: qemu-...@nongnu.org
> Cc: qemu-ri...@nongnu.org
> Signed-off-by: Markus Armbruster 

Reviewed-by: Alistair Francis 

Alistair

> ---
>  hw/arm/stellaris.c  | 15 ++-
>  hw/riscv/sifive_u.c | 13 -
>  hw/sd/ssi-sd.c  | 29 +
>  3 files changed, 27 insertions(+), 30 deletions(-)
>
> diff --git a/hw/arm/stellaris.c b/hw/arm/stellaris.c
> index 78827ace6b..b6c8a5d609 100644
> --- a/hw/arm/stellaris.c
> +++ b/hw/arm/stellaris.c
> @@ -10,6 +10,7 @@
>  #include "qemu/osdep.h"
>  #include "qapi/error.h"
>  #include "hw/sysbus.h"
> +#include "hw/sd/sd.h"
>  #include "hw/ssi/ssi.h"
>  #include "hw/arm/boot.h"
>  #include "qemu/timer.h"
> @@ -1157,6 +1158,9 @@ static void stellaris_init(MachineState *ms, 
> stellaris_board_info *board)
>  void *bus;
>  DeviceState *sddev;
>  DeviceState *ssddev;
> +DriveInfo *dinfo;
> +DeviceState *carddev;
> +BlockBackend *blk;
>
>  /*
>   * Some boards have both an OLED controller and SD card 
> connected to
> @@ -1221,8 +1225,17 @@ static void stellaris_init(MachineState *ms, 
> stellaris_board_info *board)
>   *  - Make the ssd0323 OLED controller chipselect active-low
>   */
>  bus = qdev_get_child_bus(dev, "ssi");
> -
>  sddev = ssi_create_peripheral(bus, "ssi-sd");
> +
> +dinfo = drive_get(IF_SD, 0, 0);
> +blk = dinfo ? blk_by_legacy_dinfo(dinfo) : NULL;
> +carddev = qdev_new(TYPE_SD_CARD);
> +qdev_prop_set_drive_err(carddev, "drive", blk, _fatal);
> +qdev_prop_set_bit(carddev, "spi", true);
> +qdev_realize_and_unref(carddev,
> +   qdev_get_child_bus(sddev, "sd-bus"),
> +   _fatal);
> +
>  ssddev = ssi_create_peripheral(bus, "ssd0323");
>  gpio_out[GPIO_D][0] = qemu_irq_split(
>  qdev_get_gpio_in_named(sddev, SSI_GPIO_CS, 0),
> diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
> index 589ae72a59..a4ecadaf12 100644
> --- a/hw/riscv/sifive_u.c
> +++ b/hw/riscv/sifive_u.c
> @@ -46,6 +46,7 @@
>  #include "hw/char/serial.h"
>  #include "hw/cpu/cluster.h"
>  #include "hw/misc/unimp.h"
> +#include "hw/sd/sd.h"
>  #include "hw/ssi/ssi.h"
>  #include "target/riscv/cpu.h"
>  #include "hw/riscv/riscv_hart.h"
> @@ -536,7 +537,8 @@ static void sifive_u_machine_init(MachineState *machine)
>  uint32_t fdt_load_addr;
>  uint64_t kernel_entry;
>  DriveInfo *dinfo;
> -DeviceState *flash_dev, *sd_dev;
> +BlockBackend *blk;
> +DeviceState *flash_dev, *sd_dev, *card_dev;
>  qemu_irq flash_cs, sd_cs;
>
>  /* Initialize SoC */
> @@ -686,6 +688,15 @@ static void sifive_u_machine_init(MachineState *machine)
>
>  sd_cs = qdev_get_gpio_in_named(sd_dev, SSI_GPIO_CS, 0);
>  sysbus_connect_irq(SYS_BUS_DEVICE(>soc.spi2), 1, sd_cs);
> +
> +dinfo = drive_get(IF_SD, 0, 0);
> +blk = dinfo ? blk_by_legacy_dinfo(dinfo) : NULL;
> +card_dev = qdev_new(TYPE_SD_CARD);
> +qdev_prop_set_drive_err(card_dev, "drive", blk, _fatal);
> +qdev_prop_set_bit(card_dev, "spi", true);
> +qdev_realize_and_unref(card_dev,
> +   qdev_get_child_bus(sd_dev, "sd-bus"),
> +   _fatal);
>  }
>
>  static bool sifive_u_machine_get_start_in_flash(Object *obj, Error **errp)
> diff --git a/hw/sd/ssi-sd.c b/hw/sd/ssi-sd.c
> index e60854eeef..167c03b780 100644
> --- a/hw/sd/ssi-sd.c
> +++ b/hw/sd/ssi-sd.c
> @@ -368,36 +368,9 @@ static const VMStateDescription vmstate_ssi_sd = {
>
>  static void ssi_sd_realize(SSIPeripheral *d, Error **errp)
>  {
> -ERRP_GUARD();
>  ssi_sd_state *s = SSI_SD(d);
> -  

Re: [PATCH v2 02/13] hw: Replace trivial drive_get_next() by drive_get()

2021-11-19 Thread Alistair Francis
On Thu, Nov 18, 2021 at 2:42 AM Markus Armbruster  wrote:
>
> drive_get_next() is basically a bad idea.  It returns the "next" block
> backend of a certain interface type.  "Next" means bus=0,unit=N, where
> subsequent calls count N up from zero, per interface type.
>
> This lets you define unit numbers implicitly by execution order.  If the
> order changes, or new calls appear "in the middle", unit numbers change.
> ABI break.  Hard to spot in review.
>
> A number of machines connect just one backend with drive_get_next().
> Change them to use drive_get() directly.  This makes the (zero) unit
> number explicit in the code.
>
> Cc: Beniamino Galvani 
> Cc: Peter Maydell 
> Cc: Subbaraya Sundeep 
> Cc: Niek Linnenbank 
> Cc: Andrew Baumann 
> Cc: "Philippe Mathieu-Daudé" 
> Cc: Jean-Christophe Dubois 
> Cc: Alistair Francis 
> Cc: Bin Meng 
> Cc: Palmer Dabbelt 
> Cc: Artyom Tarasenko 
> Cc: Mark Cave-Ayland 
> Cc: Michael Tokarev 
> Cc: Laurent Vivier 
> Cc: qemu-...@nongnu.org
> Cc: qemu-ri...@nongnu.org
> Signed-off-by: Markus Armbruster 

Reviewed-by: Alistair Francis 

Alistair

> ---
>  hw/arm/cubieboard.c| 2 +-
>  hw/arm/integratorcp.c  | 2 +-
>  hw/arm/msf2-som.c  | 2 +-
>  hw/arm/orangepi.c  | 2 +-
>  hw/arm/raspi.c | 2 +-
>  hw/arm/realview.c  | 2 +-
>  hw/arm/sabrelite.c | 2 +-
>  hw/misc/sifive_u_otp.c | 2 +-
>  hw/riscv/microchip_pfsoc.c | 2 +-
>  hw/riscv/sifive_u.c| 2 +-
>  hw/sparc64/niagara.c   | 2 +-
>  11 files changed, 11 insertions(+), 11 deletions(-)
>
> diff --git a/hw/arm/cubieboard.c b/hw/arm/cubieboard.c
> index 294ba5de6e..5e3372a3c7 100644
> --- a/hw/arm/cubieboard.c
> +++ b/hw/arm/cubieboard.c
> @@ -81,7 +81,7 @@ static void cubieboard_init(MachineState *machine)
>  }
>
>  /* Retrieve SD bus */
> -di = drive_get_next(IF_SD);
> +di = drive_get(IF_SD, 0, 0);
>  blk = di ? blk_by_legacy_dinfo(di) : NULL;
>  bus = qdev_get_child_bus(DEVICE(a10), "sd-bus");
>
> diff --git a/hw/arm/integratorcp.c b/hw/arm/integratorcp.c
> index 16e8985953..b109ece3ae 100644
> --- a/hw/arm/integratorcp.c
> +++ b/hw/arm/integratorcp.c
> @@ -649,7 +649,7 @@ static void integratorcp_init(MachineState *machine)
>qdev_get_gpio_in_named(icp, ICP_GPIO_MMC_WPROT, 
> 0));
>  qdev_connect_gpio_out_named(dev, "card-inserted", 0,
>qdev_get_gpio_in_named(icp, ICP_GPIO_MMC_CARDIN, 
> 0));
> -dinfo = drive_get_next(IF_SD);
> +dinfo = drive_get(IF_SD, 0, 0);
>  if (dinfo) {
>  DeviceState *card;
>
> diff --git a/hw/arm/msf2-som.c b/hw/arm/msf2-som.c
> index 396e8b9913..d9f881690e 100644
> --- a/hw/arm/msf2-som.c
> +++ b/hw/arm/msf2-som.c
> @@ -45,7 +45,7 @@ static void emcraft_sf2_s2s010_init(MachineState *machine)
>  DeviceState *spi_flash;
>  MSF2State *soc;
>  MachineClass *mc = MACHINE_GET_CLASS(machine);
> -DriveInfo *dinfo = drive_get_next(IF_MTD);
> +DriveInfo *dinfo = drive_get(IF_MTD, 0, 0);
>  qemu_irq cs_line;
>  BusState *spi_bus;
>  MemoryRegion *sysmem = get_system_memory();
> diff --git a/hw/arm/orangepi.c b/hw/arm/orangepi.c
> index 0cf9895ce7..e796382236 100644
> --- a/hw/arm/orangepi.c
> +++ b/hw/arm/orangepi.c
> @@ -85,7 +85,7 @@ static void orangepi_init(MachineState *machine)
>  qdev_realize(DEVICE(h3), NULL, _abort);
>
>  /* Retrieve SD bus */
> -di = drive_get_next(IF_SD);
> +di = drive_get(IF_SD, 0, 0);
>  blk = di ? blk_by_legacy_dinfo(di) : NULL;
>  bus = qdev_get_child_bus(DEVICE(h3), "sd-bus");
>
> diff --git a/hw/arm/raspi.c b/hw/arm/raspi.c
> index 146d35382b..b4dd6c1e99 100644
> --- a/hw/arm/raspi.c
> +++ b/hw/arm/raspi.c
> @@ -284,7 +284,7 @@ static void raspi_machine_init(MachineState *machine)
>  qdev_realize(DEVICE(>soc), NULL, _fatal);
>
>  /* Create and plug in the SD cards */
> -di = drive_get_next(IF_SD);
> +di = drive_get(IF_SD, 0, 0);
>  blk = di ? blk_by_legacy_dinfo(di) : NULL;
>  bus = qdev_get_child_bus(DEVICE(>soc), "sd-bus");
>  if (bus == NULL) {
> diff --git a/hw/arm/realview.c b/hw/arm/realview.c
> index 1c54316ba3..ddc70b54a5 100644
> --- a/hw/arm/realview.c
> +++ b/hw/arm/realview.c
> @@ -237,7 +237,7 @@ static void realview_init(MachineState *machine,
>  qemu_irq_invert(qdev_get_gpio_in(gpio2, 0)));
>  qdev_connect_gpio_out_named(dev, "card-read-only", 0, mmc_irq[0]);
>  qdev_connect_gpio_out_named(dev, "card-inserted", 0, mmc_

Re: does drive_get_next(IF_NONE) make sense?

2021-11-18 Thread Alistair Francis
On Tue, Nov 16, 2021 at 2:10 AM Thomas Huth  wrote:
>
> On 15/11/2021 08.12, Alistair Francis wrote:
> > On Mon, Nov 15, 2021 at 3:32 PM Markus Armbruster  wrote:
> >>
> >> Peter Maydell  writes:
> >>
> >>> On Fri, 12 Nov 2021 at 13:34, Markus Armbruster  wrote:
> >>>>
> >>>> Thomas Huth  writes:
> >>>>
> >>>>> On 03/11/2021 09.41, Markus Armbruster wrote:
> >>>>>> Peter Maydell  writes:
> >>>>>>
> >>>>>>> Does it make sense for a device/board to do drive_get_next(IF_NONE) ?
> >>>>>> Short answer: hell, no!  ;)
> >>>>>
> >>>>> Would it make sense to add an "assert(type != IF_NONE)" to drive_get()
> >>>>> to avoid such mistakes in the future?
> >>>>
> >>>> Worth a try.
> >>>
> >>> You need to fix the sifive_u_otp device first :-)
> >>
> >> And for that, we may want Hao Wu's "[PATCH v4 5/7] blockdev: Add a new
> >> IF type IF_OTHER" first.
> >
> > I can fixup sifive_u_otp, just let me know what the prefered solution is
>
> What kind of device is that OTP exactly? If it is some kind of non-serial
> flash device, maybe you could simply use IF_PFLASH instead?

It just says "one time programmable memory". I'm guessing it's
sometype of eFuse.

Alistair

>
>   Thomas
>



Re: does drive_get_next(IF_NONE) make sense?

2021-11-14 Thread Alistair Francis
On Mon, Nov 15, 2021 at 3:32 PM Markus Armbruster  wrote:
>
> Peter Maydell  writes:
>
> > On Fri, 12 Nov 2021 at 13:34, Markus Armbruster  wrote:
> >>
> >> Thomas Huth  writes:
> >>
> >> > On 03/11/2021 09.41, Markus Armbruster wrote:
> >> >> Peter Maydell  writes:
> >> >>
> >> >>> Does it make sense for a device/board to do drive_get_next(IF_NONE) ?
> >> >> Short answer: hell, no!  ;)
> >> >
> >> > Would it make sense to add an "assert(type != IF_NONE)" to drive_get()
> >> > to avoid such mistakes in the future?
> >>
> >> Worth a try.
> >
> > You need to fix the sifive_u_otp device first :-)
>
> And for that, we may want Hao Wu's "[PATCH v4 5/7] blockdev: Add a new
> IF type IF_OTHER" first.

I can fixup sifive_u_otp, just let me know what the prefered solution is

Alistair



Re: [PATCH 0/9] hw/block: m25p80: Fix the mess of dummy bytes needed for fast read commands

2021-04-26 Thread Alistair Francis
to keep the buggy
> > > > > > implementation forever? I think that's why
> > > > > > qemu/docs/system/deprecated.rst was created for deprecating such
> > > > > > feature.
> > > > >
> > > > > With the RFC I posted all commands in m25p80 are working for both the 
> > > > > case 1
> > > > > controller (using a txfifo) and the case 2 controller (no txfifo, as 
> > > > > GQSPI).
> > > > > Because of this, I, with all respect, will have to disagree that this 
> > > > > is buggy.
> > > >
> > > > Well, the existing m25p80 implementation that uses dummy cycle
> > > > accuracy for those flashes prevents all SPI controllers that use tx
> > > > fifo to work with those flashes. Hence it is buggy.
> > > >
> > > > >
> > > > > >
> > > > > > > >
> > > > > > > > > >
> > > > > > > > > > > don't think it is fair to call them 'seriously broken' 
> > > > > > > > > > > (and else we should
> > > > > > > > > > > probably let the maintainers know about it). Most likely 
> > > > > > > > > > > the lack of support
> > > > > > > > > >
> > > > > > > > > > I called it "seriously broken" because current 
> > > > > > > > > > implementation only
> > > > > > > > > > considered one type of SPI controllers while completely 
> > > > > > > > > > ignoring the
> > > > > > > > > > other type.
> > > > > > > > >
> > > > > > > > > If we change view and see this from the perspective of 
> > > > > > > > > m25p80, it models the
> > > > > > > > > commands a certain way and provides an API that the SPI 
> > > > > > > > > controllers need to
> > > > > > > > > implement for interacting with it. It is true that there are 
> > > > > > > > > SPI controllers
> > > > > > > > > referred to above that do not support the portion of that API 
> > > > > > > > > that corresponds
> > > > > > > > > to commands with dummy clock cycles, but I don't think it is 
> > > > > > > > > true that this is
> > > > > > > > > broken since there is also one SPI controller that has a 
> > > > > > > > > working implementation
> > > > > > > > > of m25p80's full API also when transfering through a tx fifo 
> > > > > > > > > (use case 1). But
> > > > > > > > > as mentioned above, by doing a minor extension and 
> > > > > > > > > improvement to m25p80's API
> > > > > > > > > and allow for toggling the accuracy from dummy clock cycles 
> > > > > > > > > to dummy bytes [1]
> > > > > > > > > will still be honored as in the same time making it possible 
> > > > > > > > > to have full
> > > > > > > > > support for the API in the SPI controllers that currently do 
> > > > > > > > > not (please reread
> > > > > > > > > the proposal in my previous reply that attempts to do this). 
> > > > > > > > > I myself see this
> > > > > > > > > as win/win situation, also because no controller should need 
> > > > > > > > > modifications.
> > > > > > > > >
> > > > > > > >
> > > > > > > > I am afraid your proposal does not work. Your proposed new 
> > > > > > > > device
> > > > > > > > property 'model_dummy_bytes' to select to convert the accurate 
> > > > > > > > dummy
> > > > > > > > clock cycle count to dummy bytes inside m25p80, is hard to 
> > > > > > > > justify as
> > > > > > > > a property to the flash itself, as the behavior is tightly 
> > > > > > > > coupled to
> > > > > > > > how the SPI controller works.
> > > > > > >
> > > > > > > I agree on above. I decided though that instead of posting sample 
> > > > > > > code in here
> > > > > > > I'll post an RFC with hopefully an improved proposal. I'll cc 
> > > > > > > you. About below,
> > > > > > > Xilinx ZynqMP GQSPI should not need any modication in a first 
> > > > > > > step.
> > > > > > >
> > > > > >
> > > > > > Wait, (see below)
> > > > > >
> > > > > > > >
> > > > > > > > Please take a look at the Xilinx GQSPI controller, which 
> > > > > > > > supports both
> > > > > > > > use cases, that the dummy cycles can be transferred via tx 
> > > > > > > > fifo, or
> > > > > > > > generated by the controller automatically. Please read the 
> > > > > > > > example
> > > > > > > > given in:
> > > > > > > >
> > > > > > > > table 24‐22, an example of Generic FIFO Contents for Quad 
> > > > > > > > I/O Read
> > > > > > > > Command (EBh)
> > > > > > > >
> > > > > > > > in 
> > > > > > > > https://www.xilinx.com/support/documentation/user_guides/ug1085-zynq-ultrascale-trm.pdf
> > > > > > > >
> > > > > > > > If you choose to set the m25p80 device property 
> > > > > > > > 'model_dummy_bytes' to
> > > > > > > > true when working with the Xilinx GQSPI controller, you are 
> > > > > > > > bound to
> > > > > > > > only allow guest software to use tx fifo to transfer the dummy 
> > > > > > > > cycles,
> > > > > > > > and this is wrong.
> > > > > > > >
> > > > > >
> > > > > > You missed this part. I looked at your RFC, and as I mentioned above
> > > > > > your proposal cannot support the complicated controller like Xilinx
> > > > > > GQSPI. Please read the example of table 24-22. With your RFC, you
> > > > > > mandate guest software's GQSPI driver to only use hardware dummy 
> > > > > > cycle
> > > > > > generation, which is wrong.
> > > > > >
> > > > >
> > > > > First, thank you very much for looking into the RFC series, very much
> > > > > appreciated. Secondly, about above, the GQSPI model in QEMU transfers 
> > > > > from 2
> > > > > locations in the file, in 1 location the transfer referred to above 
> > > > > is done, in
> > > > > another location the transfer through the txfifo is done. The 
> > > > > location where
> > > > > transfer referred to above is done will not need any modifications 
> > > > > (and will
> > > > > thus work equally well as it does currently).
> > > >
> > > > Please explain this a little bit. How does your RFC series handle
> > > > cases as described in table 24-22, where the 6 dummy cycles are split
> > > > into 2 transfers, with one transfer using tx fifo, and the other one
> > > > using hardware dummy cycle generation?
> > >
> > > Sorry, I missunderstod. You are right, that won't work.
> >
> > +Edgar E. Iglesias
> >
> > So it looks by far the only way to implement dummy cycles correctly to
> > work with all SPI controller models is what I proposed here in this
> > patch series.
> >
> > Maintainers are quite silent, so I would like to hear your thoughts.
> >
> > @Alistair Francis @Philippe Mathieu-Daudé @Peter Maydell would you
> > please share your thoughts since you are the one who reviewed the
> > existing dummy implementation (based on commits history)

I agree with Edgar, in that Francisco and Bin know this better than me
and that modelling things in cycles is a pain.

As Bin points out it seems like currently we should be modelling bytes
(from the variable name) so it makes sense to keep it in bytes. I
would be in favour of this series in that case. Do we know what use
cases this will break? I know it's hard to answer but I don't think
there are too many SSI users in QEMU so it might not be too hard to
test most of the possible use cases.

Alistair

>
> Hello maintainers,
>
> We apparently missed the 6.0 window to address this mess of the m25p80
> model. Please provide your inputs on this before I start working on
> the v2.
>
> Regards,
> Bin
>



Re: [PATCH v2] hw/block: m25p80: Support fast read for SST flashes

2021-03-22 Thread Alistair Francis
On Sat, Mar 6, 2021 at 1:02 AM Bin Meng  wrote:
>
> From: Bin Meng 
>
> Per SST25VF016B datasheet [1], SST flash requires a dummy byte after
> the address bytes. Note only SPI mode is supported by SST flashes.
>
> [1] http://ww1.microchip.com/downloads/en/devicedoc/s71271_04.pdf
>
> Signed-off-by: Bin Meng 
> Acked-by: Alistair Francis 

Thanks!

Applied to riscv-to-apply.next

Alistair

>
> ---
>
> Changes in v2:
> - rebase on qemu/master
>
>  hw/block/m25p80.c | 3 +++
>  1 file changed, 3 insertions(+)
>
> diff --git a/hw/block/m25p80.c b/hw/block/m25p80.c
> index 5f9471d83c..183d3f44c2 100644
> --- a/hw/block/m25p80.c
> +++ b/hw/block/m25p80.c
> @@ -895,6 +895,9 @@ static void decode_fast_read_cmd(Flash *s)
>  s->needed_bytes = get_addr_length(s);
>  switch (get_man(s)) {
>  /* Dummy cycles - modeled with bytes writes instead of bits */
> +case MAN_SST:
> +s->needed_bytes += 1;
> +break;
>  case MAN_WINBOND:
>  s->needed_bytes += 8;
>  break;
> --
> 2.25.1
>
>



Re: [PATCH v2 2/2] memory: Drop "qemu:" prefix from QOM memory region type names

2021-03-04 Thread Alistair Francis
On Thu, Mar 4, 2021 at 9:03 AM Markus Armbruster  wrote:
>
> Almost all QOM type names consist only of letters, digits, '-', '_',
> and '.'.  Just two contain ':': "qemu:memory-region" and
> "qemu:iommu-memory-region".  Neither can be plugged with -object.
> Rename them to "memory-region" and "iommu-memory-region".
>
> Signed-off-by: Markus Armbruster 

Reviewed-by: Alistair Francis 

Alistair

> ---
>  include/exec/memory.h | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/include/exec/memory.h b/include/exec/memory.h
> index c6fb714e49..3c95d7831a 100644
> --- a/include/exec/memory.h
> +++ b/include/exec/memory.h
> @@ -33,11 +33,11 @@
>  #define MAX_PHYS_ADDR_SPACE_BITS 62
>  #define MAX_PHYS_ADDR(((hwaddr)1 << MAX_PHYS_ADDR_SPACE_BITS) - 
> 1)
>
> -#define TYPE_MEMORY_REGION "qemu:memory-region"
> +#define TYPE_MEMORY_REGION "memory-region"
>  DECLARE_INSTANCE_CHECKER(MemoryRegion, MEMORY_REGION,
>   TYPE_MEMORY_REGION)
>
> -#define TYPE_IOMMU_MEMORY_REGION "qemu:iommu-memory-region"
> +#define TYPE_IOMMU_MEMORY_REGION "iommu-memory-region"
>  typedef struct IOMMUMemoryRegionClass IOMMUMemoryRegionClass;
>  DECLARE_OBJ_CHECKERS(IOMMUMemoryRegion, IOMMUMemoryRegionClass,
>   IOMMU_MEMORY_REGION, TYPE_IOMMU_MEMORY_REGION)
> --
> 2.26.2
>
>



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

2021-02-12 Thread Alistair Francis
On Thu, Feb 11, 2021 at 12:15 AM Sai Pavan Boddu
 wrote:
>
> 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

Could we document this somewhere user accessible?

Alistair

>
> 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
>
>



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

2021-02-12 Thread Alistair Francis
On Thu, Feb 11, 2021 at 12:34 AM Sai Pavan Boddu
 wrote:
>
> Embedded device slots should be allowed as support of eMMC is available.
>
> Signed-off-by: Sai Pavan Boddu 

Reviewed-by: Alistair Francis 

Alistair

> ---
>  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
>
>



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

2021-02-12 Thread Alistair Francis
On Thu, Feb 11, 2021 at 12:25 AM Sai Pavan Boddu
 wrote:
>
> 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 

Acked-by: Alistair Francis 

Alistair

> ---
>  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
>
>



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

2021-02-12 Thread Alistair Francis
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.

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-12 Thread Alistair Francis
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?

>  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
>
>



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

2021-02-12 Thread Alistair Francis
On Thu, Feb 11, 2021 at 12:18 AM Sai Pavan Boddu
 wrote:
>
> 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 

Acked-by: Alistair Francis 

Alistair

> ---
>  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
>
>



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

2021-02-12 Thread Alistair Francis
On Thu, Feb 11, 2021 at 12:17 AM Sai Pavan Boddu
 wrote:
>
> 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 

Acked-by: Alistair Francis 

Alistair

> ---
>  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
>
>



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

2021-02-12 Thread Alistair Francis
On Thu, Feb 11, 2021 at 12:36 AM Sai Pavan Boddu
 wrote:
>
> Configuring SDHCI-0 to act as eMMC controller.
>
> Signed-off-by: Sai Pavan Boddu 

Reviewed-by: Alistair Francis 

Alistair

> ---
>  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
>
>



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

2021-02-12 Thread Alistair Francis
On Thu, Feb 11, 2021 at 12:22 AM Sai Pavan Boddu
 wrote:
>
> 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 

Alistair

> ---
>  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
>
>



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

2021-02-12 Thread Alistair Francis
On Thu, Feb 11, 2021 at 12:15 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 

Alistair

> ---
>  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
>
>



Re: [PATCH] hw/sd: sdhci: Do not transfer any data when command fails

2021-02-10 Thread Alistair Francis
On Tue, Feb 9, 2021 at 2:55 AM Bin Meng  wrote:
>
> At the end of sdhci_send_command(), it starts a data transfer if
> the command register indicates a data is associated. However the
> data transfer should only be initiated when the command execution
> has succeeded.
>
> Cc: qemu-sta...@nongnu.org
> Fixes: CVE-2020-17380
> Fixes: CVE-2020-25085
> Reported-by: Alexander Bulekov 
> Reported-by: Sergej Schumilo (Ruhr-University Bochum)
> Reported-by: Cornelius Aschermann (Ruhr-University Bochum)
> Reported-by: Simon Wrner (Ruhr-University Bochum)
> Buglink: https://bugs.launchpad.net/qemu/+bug/1892960

Isn't this already fixed?

> Signed-off-by: Bin Meng 

Acked-by: Alistair Francis 

Alistair

> ---
>
>  hw/sd/sdhci.c | 4 +++-
>  1 file changed, 3 insertions(+), 1 deletion(-)
>
> diff --git a/hw/sd/sdhci.c b/hw/sd/sdhci.c
> index 8ffa539..0450110 100644
> --- a/hw/sd/sdhci.c
> +++ b/hw/sd/sdhci.c
> @@ -326,6 +326,7 @@ static void sdhci_send_command(SDHCIState *s)
>  SDRequest request;
>  uint8_t response[16];
>  int rlen;
> +bool cmd_failure = false;
>
>  s->errintsts = 0;
>  s->acmd12errsts = 0;
> @@ -349,6 +350,7 @@ static void sdhci_send_command(SDHCIState *s)
>  trace_sdhci_response16(s->rspreg[3], s->rspreg[2],
> s->rspreg[1], s->rspreg[0]);
>  } else {
> +cmd_failure = true;
>  trace_sdhci_error("timeout waiting for command response");
>  if (s->errintstsen & SDHC_EISEN_CMDTIMEOUT) {
>  s->errintsts |= SDHC_EIS_CMDTIMEOUT;
> @@ -369,7 +371,7 @@ static void sdhci_send_command(SDHCIState *s)
>
>  sdhci_update_irq(s);
>
> -if (s->blksize && (s->cmdreg & SDHC_CMD_DATA_PRESENT)) {
> +if (!cmd_failure && s->blksize && (s->cmdreg & SDHC_CMD_DATA_PRESENT)) {
>  s->data_count = 0;
>  sdhci_data_transfer(s);
>  }
> --
> 2.7.4
>
>



Re: [PATCH 2/9] tests/qtest: Restrict xlnx-can-test to TCG builds

2021-02-05 Thread Alistair Francis
On Fri, Feb 5, 2021 at 6:45 AM Philippe Mathieu-Daudé  wrote:
>
> The Xilinx CAN controller test is uses the ZCU102 board which is
> based on a ZynqMP SoC. In the default configuration - used by this
> test - this SoC creates 2 Cortex R5F cores. Such cores are not
> v8A archicture, thus can not be run under KVM. Therefore restrict
> this test to TCG.
>
> Signed-off-by: Philippe Mathieu-Daudé 

Reviewed-by: Alistair Francis 

Alistair

> ---
> Cc: Alistair Francis 
> Cc: "Edgar E. Iglesias" 
> Cc: Vikram Garhwal 
> ---
>  tests/qtest/meson.build | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/tests/qtest/meson.build b/tests/qtest/meson.build
> index c83bc211b6a..d8ebd5bf98e 100644
> --- a/tests/qtest/meson.build
> +++ b/tests/qtest/meson.build
> @@ -159,10 +159,10 @@
>(cpu != 'arm' ? ['bios-tables-test'] : []) +   
>\
>(config_all_devices.has_key('CONFIG_TPM_TIS_SYSBUS') ? 
> ['tpm-tis-device-test'] : []) +\
>(config_all_devices.has_key('CONFIG_TPM_TIS_SYSBUS') ? 
> ['tpm-tis-device-swtpm-test'] : []) +  \
> +  (config_all.has_key('CONFIG_TCG') ? ['xlnx-can-test'] : []) +  \
>['arm-cpu-features',
> 'numa-test',
> 'boot-serial-test',
> -   'xlnx-can-test',
> 'migration-test']
>
>  qtests_s390x = \
> --
> 2.26.2
>
>



Re: [PATCH 09/10] target: Move ARM_COMPATIBLE_SEMIHOSTING feature to target Kconfig

2021-02-01 Thread Alistair Francis
On Sun, Jan 31, 2021 at 3:14 AM Philippe Mathieu-Daudé  wrote:
>
> ARM_COMPATIBLE_SEMIHOSTING is an architecture feature, move its
> declaration to each target/ARCH/.
>
> Note, we do not modify the linux-user targets, as user-mode builds
> don't use Kconfig.
>
> Signed-off-by: Philippe Mathieu-Daudé 

Reviewed-by: Alistair Francis 

Alistair

> ---
>  default-configs/devices/arm-softmmu.mak | 1 -
>  default-configs/devices/riscv32-softmmu.mak | 1 -
>  default-configs/devices/riscv64-softmmu.mak | 1 -
>  target/arm/Kconfig  | 1 +
>  target/riscv/Kconfig| 2 ++
>  5 files changed, 3 insertions(+), 3 deletions(-)
>
> diff --git a/default-configs/devices/arm-softmmu.mak 
> b/default-configs/devices/arm-softmmu.mak
> index 341d439de6f..0824e9be795 100644
> --- a/default-configs/devices/arm-softmmu.mak
> +++ b/default-configs/devices/arm-softmmu.mak
> @@ -41,5 +41,4 @@ CONFIG_MICROBIT=y
>  CONFIG_FSL_IMX25=y
>  CONFIG_FSL_IMX7=y
>  CONFIG_FSL_IMX6UL=y
> -CONFIG_ARM_COMPATIBLE_SEMIHOSTING=y
>  CONFIG_ALLWINNER_H3=y
> diff --git a/default-configs/devices/riscv32-softmmu.mak 
> b/default-configs/devices/riscv32-softmmu.mak
> index 5c9ad2590ef..94a236c9c25 100644
> --- a/default-configs/devices/riscv32-softmmu.mak
> +++ b/default-configs/devices/riscv32-softmmu.mak
> @@ -3,7 +3,6 @@
>  # Uncomment the following lines to disable these optional devices:
>  #
>  #CONFIG_PCI_DEVICES=n
> -CONFIG_ARM_COMPATIBLE_SEMIHOSTING=y
>
>  # Boards:
>  #
> diff --git a/default-configs/devices/riscv64-softmmu.mak 
> b/default-configs/devices/riscv64-softmmu.mak
> index d5b2e25b6df..76b61956489 100644
> --- a/default-configs/devices/riscv64-softmmu.mak
> +++ b/default-configs/devices/riscv64-softmmu.mak
> @@ -3,7 +3,6 @@
>  # Uncomment the following lines to disable these optional devices:
>  #
>  #CONFIG_PCI_DEVICES=n
> -CONFIG_ARM_COMPATIBLE_SEMIHOSTING=y
>
>  # Boards:
>  #
> diff --git a/target/arm/Kconfig b/target/arm/Kconfig
> index 1f05de47ca6..ae89d05c7e5 100644
> --- a/target/arm/Kconfig
> +++ b/target/arm/Kconfig
> @@ -1,5 +1,6 @@
>  config ARM
>  bool
> +select ARM_COMPATIBLE_SEMIHOSTING
>
>  config AARCH64
>  bool
> diff --git a/target/riscv/Kconfig b/target/riscv/Kconfig
> index b9e5932f13f..c3b9d8a1cf1 100644
> --- a/target/riscv/Kconfig
> +++ b/target/riscv/Kconfig
> @@ -1,5 +1,7 @@
>  config RISCV32
>  bool
> +select ARM_COMPATIBLE_SEMIHOSTING
>
>  config RISCV64
>  bool
> +select ARM_COMPATIBLE_SEMIHOSTING
> --
> 2.26.2
>
>



Re: [PATCH 08/10] default-configs: Remove unnecessary SEMIHOSTING selection

2021-02-01 Thread Alistair Francis
On Sun, Jan 31, 2021 at 3:24 AM Philippe Mathieu-Daudé  wrote:
>
> Commit 56b5170c87e ("semihosting: Move ARM semihosting code to
> shared directories") selected ARM_COMPATIBLE_SEMIHOSTING which
> already selects SEMIHOSTING. No need to select it again.
>
> Signed-off-by: Philippe Mathieu-Daudé 

Reviewed-by: Alistair Francis 

Alistair

> ---
>  default-configs/devices/arm-softmmu.mak | 1 -
>  default-configs/devices/riscv32-softmmu.mak | 1 -
>  default-configs/devices/riscv64-softmmu.mak | 1 -
>  3 files changed, 3 deletions(-)
>
> diff --git a/default-configs/devices/arm-softmmu.mak 
> b/default-configs/devices/arm-softmmu.mak
> index 0500156a0c7..341d439de6f 100644
> --- a/default-configs/devices/arm-softmmu.mak
> +++ b/default-configs/devices/arm-softmmu.mak
> @@ -41,6 +41,5 @@ CONFIG_MICROBIT=y
>  CONFIG_FSL_IMX25=y
>  CONFIG_FSL_IMX7=y
>  CONFIG_FSL_IMX6UL=y
> -CONFIG_SEMIHOSTING=y
>  CONFIG_ARM_COMPATIBLE_SEMIHOSTING=y
>  CONFIG_ALLWINNER_H3=y
> diff --git a/default-configs/devices/riscv32-softmmu.mak 
> b/default-configs/devices/riscv32-softmmu.mak
> index d847bd5692e..5c9ad2590ef 100644
> --- a/default-configs/devices/riscv32-softmmu.mak
> +++ b/default-configs/devices/riscv32-softmmu.mak
> @@ -3,7 +3,6 @@
>  # Uncomment the following lines to disable these optional devices:
>  #
>  #CONFIG_PCI_DEVICES=n
> -CONFIG_SEMIHOSTING=y
>  CONFIG_ARM_COMPATIBLE_SEMIHOSTING=y
>
>  # Boards:
> diff --git a/default-configs/devices/riscv64-softmmu.mak 
> b/default-configs/devices/riscv64-softmmu.mak
> index d5eec75f05e..d5b2e25b6df 100644
> --- a/default-configs/devices/riscv64-softmmu.mak
> +++ b/default-configs/devices/riscv64-softmmu.mak
> @@ -3,7 +3,6 @@
>  # Uncomment the following lines to disable these optional devices:
>  #
>  #CONFIG_PCI_DEVICES=n
> -CONFIG_SEMIHOSTING=y
>  CONFIG_ARM_COMPATIBLE_SEMIHOSTING=y
>
>  # Boards:
> --
> 2.26.2
>
>



Re: [PATCH 06/22] util: Add CRC16 (CCITT) calculation routines

2021-01-14 Thread Alistair Francis
On Thu, Dec 31, 2020 at 3:35 AM Bin Meng  wrote:
>
> From: Bin Meng 
>
> Import CRC16 calculation routines from Linux kernel v5.10:
>
>   include/linux/crc-ccitt.h
>   lib/crc-ccitt.c
>
> to QEMU:
>
>   include/qemu/crc-ccitt.h
>   util/crc-ccitt.c
>
> Signed-off-by: Bin Meng 

Acked-by: Alistair Francis 

Alistair

> ---
>
>  include/qemu/crc-ccitt.h |  33 ++
>  util/crc-ccitt.c | 127 +++
>  util/meson.build |   1 +
>  3 files changed, 161 insertions(+)
>  create mode 100644 include/qemu/crc-ccitt.h
>  create mode 100644 util/crc-ccitt.c
>
> diff --git a/include/qemu/crc-ccitt.h b/include/qemu/crc-ccitt.h
> new file mode 100644
> index 00..c017a8157e
> --- /dev/null
> +++ b/include/qemu/crc-ccitt.h
> @@ -0,0 +1,33 @@
> +/*
> + * CRC16 (CCITT) Checksum Algorithm
> + *
> + * Copyright (c) 2020 Wind River Systems, Inc.
> + *
> + * Author:
> + *   Bin Meng 
> + *
> + * From Linux kernel v5.10 include/linux/crc-ccitt.h
> + *
> + * SPDX-License-Identifier: GPL-2.0
> + */
> +
> +#ifndef _CRC_CCITT_H
> +#define _CRC_CCITT_H
> +
> +extern uint16_t const crc_ccitt_table[256];
> +extern uint16_t const crc_ccitt_false_table[256];
> +
> +extern uint16_t crc_ccitt(uint16_t crc, const uint8_t *buffer, size_t len);
> +extern uint16_t crc_ccitt_false(uint16_t crc, const uint8_t *buffer, size_t 
> len);
> +
> +static inline uint16_t crc_ccitt_byte(uint16_t crc, const uint8_t c)
> +{
> +return (crc >> 8) ^ crc_ccitt_table[(crc ^ c) & 0xff];
> +}
> +
> +static inline uint16_t crc_ccitt_false_byte(uint16_t crc, const uint8_t c)
> +{
> +return (crc << 8) ^ crc_ccitt_false_table[(crc >> 8) ^ c];
> +}
> +
> +#endif /* _CRC_CCITT_H */
> diff --git a/util/crc-ccitt.c b/util/crc-ccitt.c
> new file mode 100644
> index 00..481e45c380
> --- /dev/null
> +++ b/util/crc-ccitt.c
> @@ -0,0 +1,127 @@
> +/*
> + * CRC16 (CCITT) Checksum Algorithm
> + *
> + * Copyright (c) 2020 Wind River Systems, Inc.
> + *
> + * Author:
> + *   Bin Meng 
> + *
> + * From Linux kernel v5.10 lib/crc-ccitt.c
> + *
> + * SPDX-License-Identifier: GPL-2.0-only
> + */
> +
> +#include "qemu/osdep.h"
> +#include "qemu/crc-ccitt.h"
> +
> +/*
> + * This mysterious table is just the CRC of each possible byte. It can be
> + * computed using the standard bit-at-a-time methods. The polynomial can
> + * be seen in entry 128, 0x8408. This corresponds to x^0 + x^5 + x^12.
> + * Add the implicit x^16, and you have the standard CRC-CCITT.
> + */
> +uint16_t const crc_ccitt_table[256] = {
> +0x, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf,
> +0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7,
> +0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e,
> +0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876,
> +0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd,
> +0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5,
> +0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c,
> +0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974,
> +0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb,
> +0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3,
> +0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a,
> +0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72,
> +0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9,
> +0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1,
> +0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738,
> +0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70,
> +0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7,
> +0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff,
> +0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036,
> +0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e,
> +0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5,
> +0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd,
> +0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134,
> +0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c,
> +0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3,
> +0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb,
> +0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232,
> +0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a,
> +0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0

Re: [PATCH 22/22] docs/system: riscv: Add documentation for sifive_u machine

2021-01-13 Thread Alistair Francis
On Thu, Dec 31, 2020 at 3:42 AM Bin Meng  wrote:
>
> From: Bin Meng 
>
> This adds detailed documentation for RISC-V `sifive_u` machine,
> including the following information:
>
> - Supported devices
> - Hardware configuration information
> - Boot options
> - Machine-specific options
> - Running Linux kernel
> - Running VxWorks kernel
> - Running U-Boot, and with an alternate configuration
>
> Signed-off-by: Bin Meng 

Reviewed-by: Alistair Francis 

Alistair

>
> ---
>
>  docs/system/riscv/sifive_u.rst | 336 +
>  docs/system/target-riscv.rst   |  10 +
>  2 files changed, 346 insertions(+)
>  create mode 100644 docs/system/riscv/sifive_u.rst
>
> diff --git a/docs/system/riscv/sifive_u.rst b/docs/system/riscv/sifive_u.rst
> new file mode 100644
> index 00..7e133d8ff3
> --- /dev/null
> +++ b/docs/system/riscv/sifive_u.rst
> @@ -0,0 +1,336 @@
> +SiFive HiFive Unleashed (``sifive_u``)
> +==
> +
> +SiFive HiFive Unleashed Development Board is the ultimate RISC‑V development
> +board featuring the Freedom U540 multi-core RISC‑V processor.
> +
> +Supported devices
> +-
> +
> +The ``sifive_u`` machine supports the following devices:
> +
> + * 1 E51 / E31 core
> + * Up to 4 U54 / U34 cores
> + * Core Level Interruptor (CLINT)
> + * Platform-Level Interrupt Controller (PLIC)
> + * Power, Reset, Clock, Interrupt (PRCI)
> + * L2 Loosely Integrated Memory (L2-LIM)
> + * DDR memory controller
> + * 2 UARTs
> + * 1 GEM ethernet controller
> + * 1 GPIO controller
> + * 1 One-Time Programmable (OTP) memory with stored serial number
> + * 1 DMA controller
> + * 2 QSPI controllers
> + * 1 ISSI 25WP256 flash
> + * 1 SD card in SPI mode
> +
> +Please note the real world HiFive Unleashed board has a fixed configuration 
> of
> +1 E51 core and 4 U54 core combination and the RISC-V core boots in 64-bit 
> mode.
> +With QEMU, one can create a machine with 1 E51 core and up to 4 U54 cores. It
> +is also possible to create a 32-bit variant with the same peripherals execpt
> +that the RISC-V cores are replaced by the 32-bit ones (E31 and U34), to help
> +testing of 32-bit guest software.
> +
> +Hardware configuration information
> +--
> +
> +The ``sifive_u`` machine automatically generates a device tree blob ("dtb")
> +which it passes to the guest. This provides information about the addresses,
> +interrupt lines and other configuration of the various devices in the system.
> +Guest software should discover the devices that are present in the generated
> +DTB instead of using a DTB for the real hardware, as some of the devices are
> +not modeled by QEMU and trying to access these devices may cause unexpected
> +behavior.
> +
> +Boot options
> +
> +
> +The ``sifive_u`` machine can start using the standard -kernel functionality
> +for loading a Linux kernel, a VxWorks kernel, a modified U-Boot bootloader
> +(S-mode) or ELF executable with the default OpenSBI firmware image as the
> +-bios. It also supports booting the unmodified U-Boot bootloader using the
> +standard -bios functionality.
> +
> +Machine-specific options
> +
> +
> +The following machine-specific options are supported:
> +
> +- serial=nnn
> +
> +  The board serial number. When not given, the default serial number 1 is 
> used.
> +
> +  SiFive reserves the first 1 KiB of the 16 KiB OTP memory for internal use.
> +  The current usage is only used to store the serial number of the board at
> +  offset 0xfc. U-Boot reads the serial number from the OTP memory, and uses
> +  it to generate a unique MAC address to be programmed to the on-chip GEM
> +  ethernet controller. When multiple QEMU ``sifive_u`` machines are created
> +  and connected to the same subnet, they all have the same MAC address hence
> +  it creates a unusable network. In such scenario, user should give different
> +  values to serial= when creating different ``sifive_u`` machines.
> +
> +- start-in-flash
> +
> +  When given, QEMU's ROM codes jump to QSPI memory-mapped flash directly.
> +  Otherwise QEMU will jump to DRAM or L2LIM depending on the msel= value.
> +  When not given, it defaults to direct DRAM booting.
> +
> +- msel=[6|11]
> +
> +  Mode Select (MSEL[3:0]) pins value, used to control where to boot from.
> +
> +  The FU540 SoC supports booting from several sources, which are controlled
> +  using the Mode Select pins on the chip. Typically, the boot process runs
> +  through several stages before it begins execution of user-provided 
> programs.
> +  These stages typically in

Re: [PATCH 21/22] docs/system: Add RISC-V documentation

2021-01-13 Thread Alistair Francis
On Thu, Dec 31, 2020 at 3:53 AM Bin Meng  wrote:
>
> From: Bin Meng 
>
> Add RISC-V system emulator documentation for generic information.
> `Board-specific documentation` and `RISC-V CPU features` are only
> a placeholder and will be added in the future.
>
> Signed-off-by: Bin Meng 

This is great! Thanks!

Reviewed-by: Alistair Francis 

Alistair

> ---
>
>  docs/system/target-riscv.rst | 62 
>  docs/system/targets.rst  |  1 +
>  2 files changed, 63 insertions(+)
>  create mode 100644 docs/system/target-riscv.rst
>
> diff --git a/docs/system/target-riscv.rst b/docs/system/target-riscv.rst
> new file mode 100644
> index 00..978b96cbdb
> --- /dev/null
> +++ b/docs/system/target-riscv.rst
> @@ -0,0 +1,62 @@
> +.. _RISC-V-System-emulator:
> +
> +RISC-V System emulator
> +==
> +
> +QEMU can emulate both 32-bit and 64-bit RISC-V CPUs. Use the
> +``qemu-system-riscv64`` executable to simulate a 64-bit RISC-V machine,
> +``qemu-system-riscv32`` executable to simulate a 32-bit RISC-V machine.
> +
> +QEMU has generally good support for RISC-V guests. It has support for
> +several different machines. The reason we support so many is that
> +RISC-V hardware is much more widely varying than x86 hardware. RISC-V
> +CPUs are generally built into "system-on-chip" (SoC) designs created by
> +many different companies with different devices, and these SoCs are
> +then built into machines which can vary still further even if they use
> +the same SoC.
> +
> +For most boards the CPU type is fixed (matching what the hardware has),
> +so typically you don't need to specify the CPU type by hand, except for
> +special cases like the ``virt`` board.
> +
> +Choosing a board model
> +--
> +
> +For QEMU's RISC-V system emulation, you must specify which board
> +model you want to use with the ``-M`` or ``--machine`` option;
> +there is no default.
> +
> +Because RISC-V systems differ so much and in fundamental ways, typically
> +operating system or firmware images intended to run on one machine
> +will not run at all on any other. This is often surprising for new
> +users who are used to the x86 world where every system looks like a
> +standard PC. (Once the kernel has booted, most userspace software
> +cares much less about the detail of the hardware.)
> +
> +If you already have a system image or a kernel that works on hardware
> +and you want to boot with QEMU, check whether QEMU lists that machine
> +in its ``-machine help`` output. If it is listed, then you can probably
> +use that board model. If it is not listed, then unfortunately your image
> +will almost certainly not boot on QEMU. (You might be able to
> +extract the filesystem and use that with a different kernel which
> +boots on a system that QEMU does emulate.)
> +
> +If you don't care about reproducing the idiosyncrasies of a particular
> +bit of hardware, such as small amount of RAM, no PCI or other hard
> +disk, etc., and just want to run Linux, the best option is to use the
> +``virt`` board. This is a platform which doesn't correspond to any
> +real hardware and is designed for use in virtual machines. You'll
> +need to compile Linux with a suitable configuration for running on
> +the ``virt`` board. ``virt`` supports PCI, virtio, recent CPUs and
> +large amounts of RAM. It also supports 64-bit CPUs.
> +
> +Board-specific documentation
> +
> +
> +Unfortunately many of the RISC-V boards QEMU supports are currently
> +undocumented; you can get a complete list by running
> +``qemu-system-riscv64 --machine help``, or
> +``qemu-system-riscv32 --machine help``.
> +
> +RISC-V CPU features
> +---
> diff --git a/docs/system/targets.rst b/docs/system/targets.rst
> index 564cea9a9b..75ed1087fd 100644
> --- a/docs/system/targets.rst
> +++ b/docs/system/targets.rst
> @@ -19,6 +19,7 @@ Contents:
> target-m68k
> target-mips
> target-ppc
> +   target-riscv
> target-rx
> target-s390x
> target-sparc
> --
> 2.25.1
>
>



Re: [PATCH 20/22] docs/system: Sort targets in alphabetical order

2021-01-13 Thread Alistair Francis
On Thu, Dec 31, 2020 at 3:50 AM Bin Meng  wrote:
>
> From: Bin Meng 
>
> Signed-off-by: Bin Meng 

Reviewed-by: Alistair Francis 

Alistair

> ---
>
>  docs/system/targets.rst | 19 ---
>  1 file changed, 12 insertions(+), 7 deletions(-)
>
> diff --git a/docs/system/targets.rst b/docs/system/targets.rst
> index 560783644d..564cea9a9b 100644
> --- a/docs/system/targets.rst
> +++ b/docs/system/targets.rst
> @@ -7,16 +7,21 @@ various targets are mentioned in the following sections.
>
>  Contents:
>
> +..
> +   This table of contents should be kept sorted alphabetically
> +   by the title text of each file, which isn't the same ordering
> +   as an alphabetical sort by filename.
> +
>  .. toctree::
>
> -   target-i386
> +   target-arm
> +   target-avr
> +   target-m68k
> +   target-mips
> target-ppc
> +   target-rx
> +   target-s390x
> target-sparc
> target-sparc64
> -   target-mips
> -   target-arm
> -   target-m68k
> +   target-i386
> target-xtensa
> -   target-s390x
> -   target-rx
> -   target-avr
> --
> 2.25.1
>
>



Re: [PATCH 19/22] hw/riscv: sifive_u: Change SIFIVE_U_GEM_IRQ to decimal value

2021-01-13 Thread Alistair Francis
On Thu, Dec 31, 2020 at 3:38 AM Bin Meng  wrote:
>
> From: Bin Meng 
>
> All other peripherals' IRQs are in the format of decimal value.
> Change SIFIVE_U_GEM_IRQ to be consistent.
>
> Signed-off-by: Bin Meng 

Reviewed-by: Alistair Francis 

Alistair

> ---
>
>  include/hw/riscv/sifive_u.h | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/include/hw/riscv/sifive_u.h b/include/hw/riscv/sifive_u.h
> index de1464a2ce..2656b39808 100644
> --- a/include/hw/riscv/sifive_u.h
> +++ b/include/hw/riscv/sifive_u.h
> @@ -127,7 +127,7 @@ enum {
>  SIFIVE_U_PDMA_IRQ6 = 29,
>  SIFIVE_U_PDMA_IRQ7 = 30,
>  SIFIVE_U_QSPI0_IRQ = 51,
> -SIFIVE_U_GEM_IRQ = 0x35
> +SIFIVE_U_GEM_IRQ = 53
>  };
>
>  enum {
> --
> 2.25.1
>
>



Re: [PATCH 18/22] hw/riscv: sifive_u: Add QSPI2 controller and connect an SD card

2021-01-13 Thread Alistair Francis
On Thu, Dec 31, 2020 at 3:45 AM Bin Meng  wrote:
>
> From: Bin Meng 
>
> This adds the QSPI2 controller to the SoC, and connnects an SD
> card to it. The generation of corresponding device tree source
> fragment is also added.
>
> Specify machine property `msel` to 11 to boot the same upstream
> U-Boot SPL and payload image for the SiFive HiFive Unleashed board.
> Note subsequent payload is stored in the SD card image.
>
> $ qemu-system-riscv64 -nographic -M sifive_u,msel=11 -smp 5 -m 8G \
> -bios u-boot-spl.bin -drive file=sdcard.img,if=sd
>
> Signed-off-by: Bin Meng 

Reviewed-by: Alistair Francis 

Alistair

> ---
>
>  include/hw/riscv/sifive_u.h |  3 +++
>  hw/riscv/sifive_u.c | 43 +++--
>  hw/riscv/Kconfig|  1 +
>  3 files changed, 45 insertions(+), 2 deletions(-)
>
> diff --git a/include/hw/riscv/sifive_u.h b/include/hw/riscv/sifive_u.h
> index 8824b7c031..de1464a2ce 100644
> --- a/include/hw/riscv/sifive_u.h
> +++ b/include/hw/riscv/sifive_u.h
> @@ -47,6 +47,7 @@ typedef struct SiFiveUSoCState {
>  SiFiveUOTPState otp;
>  SiFivePDMAState dma;
>  SiFiveSPIState spi0;
> +SiFiveSPIState spi2;
>  CadenceGEMState gem;
>
>  uint32_t serial;
> @@ -85,6 +86,7 @@ enum {
>  SIFIVE_U_DEV_UART1,
>  SIFIVE_U_DEV_GPIO,
>  SIFIVE_U_DEV_QSPI0,
> +SIFIVE_U_DEV_QSPI2,
>  SIFIVE_U_DEV_OTP,
>  SIFIVE_U_DEV_DMC,
>  SIFIVE_U_DEV_FLASH0,
> @@ -99,6 +101,7 @@ enum {
>  SIFIVE_U_L2CC_IRQ2 = 3,
>  SIFIVE_U_UART0_IRQ = 4,
>  SIFIVE_U_UART1_IRQ = 5,
> +SIFIVE_U_QSPI2_IRQ = 6,
>  SIFIVE_U_GPIO_IRQ0 = 7,
>  SIFIVE_U_GPIO_IRQ1 = 8,
>  SIFIVE_U_GPIO_IRQ2 = 9,
> diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
> index acac4feef1..d59333d18d 100644
> --- a/hw/riscv/sifive_u.c
> +++ b/hw/riscv/sifive_u.c
> @@ -16,6 +16,7 @@
>   * 6) GEM (Gigabit Ethernet Controller) and management block
>   * 7) DMA (Direct Memory Access Controller)
>   * 8) SPI0 connected to an SPI flash
> + * 9) SPI2 connected to an SD card
>   *
>   * This board currently generates devicetree dynamically that indicates at 
> least
>   * two harts and up to five harts.
> @@ -77,6 +78,7 @@ static const struct MemmapEntry {
>  [SIFIVE_U_DEV_UART0] ={ 0x1001, 0x1000 },
>  [SIFIVE_U_DEV_UART1] ={ 0x10011000, 0x1000 },
>  [SIFIVE_U_DEV_QSPI0] ={ 0x1004, 0x1000 },
> +[SIFIVE_U_DEV_QSPI2] ={ 0x1005, 0x1000 },
>  [SIFIVE_U_DEV_GPIO] = { 0x1006, 0x1000 },
>  [SIFIVE_U_DEV_OTP] =  { 0x1007, 0x1000 },
>  [SIFIVE_U_DEV_GEM] =  { 0x1009, 0x2000 },
> @@ -345,6 +347,31 @@ static void create_fdt(SiFiveUState *s, const struct 
> MemmapEntry *memmap,
>  "sifive,fu540-c000-ccache");
>  g_free(nodename);
>
> +nodename = g_strdup_printf("/soc/spi@%lx",
> +(long)memmap[SIFIVE_U_DEV_QSPI2].base);
> +qemu_fdt_add_subnode(fdt, nodename);
> +qemu_fdt_setprop_cell(fdt, nodename, "#size-cells", 0);
> +qemu_fdt_setprop_cell(fdt, nodename, "#address-cells", 1);
> +qemu_fdt_setprop_cells(fdt, nodename, "clocks",
> +prci_phandle, PRCI_CLK_TLCLK);
> +qemu_fdt_setprop_cell(fdt, nodename, "interrupts", SIFIVE_U_QSPI2_IRQ);
> +qemu_fdt_setprop_cell(fdt, nodename, "interrupt-parent", plic_phandle);
> +qemu_fdt_setprop_cells(fdt, nodename, "reg",
> +0x0, memmap[SIFIVE_U_DEV_QSPI2].base,
> +0x0, memmap[SIFIVE_U_DEV_QSPI2].size);
> +qemu_fdt_setprop_string(fdt, nodename, "compatible", "sifive,spi0");
> +g_free(nodename);
> +
> +nodename = g_strdup_printf("/soc/spi@%lx/mmc@0",
> +(long)memmap[SIFIVE_U_DEV_QSPI2].base);
> +qemu_fdt_add_subnode(fdt, nodename);
> +qemu_fdt_setprop(fdt, nodename, "disable-wp", NULL, 0);
> +qemu_fdt_setprop_cells(fdt, nodename, "voltage-ranges", 3300, 3300);
> +qemu_fdt_setprop_cell(fdt, nodename, "spi-max-frequency", 2000);
> +qemu_fdt_setprop_cell(fdt, nodename, "reg", 0);
> +qemu_fdt_setprop_string(fdt, nodename, "compatible", "mmc-spi-slot");
> +g_free(nodename);
> +
>  nodename = g_strdup_printf("/soc/spi@%lx",
>  (long)memmap[SIFIVE_U_DEV_QSPI0].base);
>  qemu_fdt_add_subnode(fdt, nodename);
> @@ -469,8 +496,8 @@ static void sifive_u_machine_init(MachineState *machine)
>  uint32_t fdt_load_addr;
>  uint64_t kernel_entry;
>  DriveInfo *dinfo;
> -Devi

Re: [PATCH 17/22] hw/riscv: sifive_u: Add QSPI0 controller and connect a flash

2021-01-13 Thread Alistair Francis
On Thu, Dec 31, 2020 at 3:51 AM Bin Meng  wrote:
>
> From: Bin Meng 
>
> This adds the QSPI0 controller to the SoC, and connnects an ISSI
> 25WP256 flash to it. The generation of corresponding device tree
> source fragment is also added.
>
> With this commit, upstream U-Boot for the SiFive HiFive Unleashed
> board can boot on QEMU 'sifive_u' out of the box. This allows users
> to develop and test the recommended RISC-V boot flow with a real
> world use case: ZSBL (in QEMU) loads U-Boot SPL from SPI flash to
> L2LIM, then U-Boot SPL loads the payload from SPI flash that is
> combined with OpenSBI fw_dynamic firmware and U-Boot proper.
>
> Specify machine property `msel` to 6 to allow booting from the SPI
> flash. U-Boot spl is directly loaded via `-bios`, and subsequent
> payload is stored in the SPI flash image. Example command line:
>
> $ qemu-system-riscv64 -nographic -M sifive_u,msel=6 -smp 5 -m 8G \
> -bios u-boot-spl.bin -drive file=spi-nor.img,if=mtd
>
> Signed-off-by: Bin Meng 

Reviewed-by: Alistair Francis 

Alistair

> ---
>
>  include/hw/riscv/sifive_u.h |  4 +++
>  hw/riscv/sifive_u.c | 52 +
>  hw/riscv/Kconfig|  2 ++
>  3 files changed, 58 insertions(+)
>
> diff --git a/include/hw/riscv/sifive_u.h b/include/hw/riscv/sifive_u.h
> index a9f7b4a084..8824b7c031 100644
> --- a/include/hw/riscv/sifive_u.h
> +++ b/include/hw/riscv/sifive_u.h
> @@ -26,6 +26,7 @@
>  #include "hw/gpio/sifive_gpio.h"
>  #include "hw/misc/sifive_u_otp.h"
>  #include "hw/misc/sifive_u_prci.h"
> +#include "hw/ssi/sifive_spi.h"
>
>  #define TYPE_RISCV_U_SOC "riscv.sifive.u.soc"
>  #define RISCV_U_SOC(obj) \
> @@ -45,6 +46,7 @@ typedef struct SiFiveUSoCState {
>  SIFIVEGPIOState gpio;
>  SiFiveUOTPState otp;
>  SiFivePDMAState dma;
> +SiFiveSPIState spi0;
>  CadenceGEMState gem;
>
>  uint32_t serial;
> @@ -82,6 +84,7 @@ enum {
>  SIFIVE_U_DEV_UART0,
>  SIFIVE_U_DEV_UART1,
>  SIFIVE_U_DEV_GPIO,
> +SIFIVE_U_DEV_QSPI0,
>  SIFIVE_U_DEV_OTP,
>  SIFIVE_U_DEV_DMC,
>  SIFIVE_U_DEV_FLASH0,
> @@ -120,6 +123,7 @@ enum {
>  SIFIVE_U_PDMA_IRQ5 = 28,
>  SIFIVE_U_PDMA_IRQ6 = 29,
>  SIFIVE_U_PDMA_IRQ7 = 30,
> +SIFIVE_U_QSPI0_IRQ = 51,
>  SIFIVE_U_GEM_IRQ = 0x35
>  };
>
> diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
> index f5c400dd44..acac4feef1 100644
> --- a/hw/riscv/sifive_u.c
> +++ b/hw/riscv/sifive_u.c
> @@ -15,6 +15,7 @@
>   * 5) OTP (One-Time Programmable) memory with stored serial number
>   * 6) GEM (Gigabit Ethernet Controller) and management block
>   * 7) DMA (Direct Memory Access Controller)
> + * 8) SPI0 connected to an SPI flash
>   *
>   * This board currently generates devicetree dynamically that indicates at 
> least
>   * two harts and up to five harts.
> @@ -44,6 +45,7 @@
>  #include "hw/char/serial.h"
>  #include "hw/cpu/cluster.h"
>  #include "hw/misc/unimp.h"
> +#include "hw/ssi/ssi.h"
>  #include "target/riscv/cpu.h"
>  #include "hw/riscv/riscv_hart.h"
>  #include "hw/riscv/sifive_u.h"
> @@ -74,6 +76,7 @@ static const struct MemmapEntry {
>  [SIFIVE_U_DEV_PRCI] = { 0x1000, 0x1000 },
>  [SIFIVE_U_DEV_UART0] ={ 0x1001, 0x1000 },
>  [SIFIVE_U_DEV_UART1] ={ 0x10011000, 0x1000 },
> +[SIFIVE_U_DEV_QSPI0] ={ 0x1004, 0x1000 },
>  [SIFIVE_U_DEV_GPIO] = { 0x1006, 0x1000 },
>  [SIFIVE_U_DEV_OTP] =  { 0x1007, 0x1000 },
>  [SIFIVE_U_DEV_GEM] =  { 0x1009, 0x2000 },
> @@ -342,6 +345,32 @@ static void create_fdt(SiFiveUState *s, const struct 
> MemmapEntry *memmap,
>  "sifive,fu540-c000-ccache");
>  g_free(nodename);
>
> +nodename = g_strdup_printf("/soc/spi@%lx",
> +(long)memmap[SIFIVE_U_DEV_QSPI0].base);
> +qemu_fdt_add_subnode(fdt, nodename);
> +qemu_fdt_setprop_cell(fdt, nodename, "#size-cells", 0);
> +qemu_fdt_setprop_cell(fdt, nodename, "#address-cells", 1);
> +qemu_fdt_setprop_cells(fdt, nodename, "clocks",
> +prci_phandle, PRCI_CLK_TLCLK);
> +qemu_fdt_setprop_cell(fdt, nodename, "interrupts", SIFIVE_U_QSPI0_IRQ);
> +qemu_fdt_setprop_cell(fdt, nodename, "interrupt-parent", plic_phandle);
> +qemu_fdt_setprop_cells(fdt, nodename, "reg",
> +0x0, memmap[SIFIVE_U_DEV_QSPI0].base,
> +0x0, memmap[SIFIVE_U_DEV_QSPI0].size);
> +qemu_fdt_setprop_string(fdt, nodenam

Re: [PATCH 16/22] hw/ssi: Add SiFive SPI controller support

2021-01-13 Thread Alistair Francis
On Thu, Dec 31, 2020 at 3:36 AM Bin Meng  wrote:
>
> From: Bin Meng 
>
> This adds the SiFive SPI controller model for the FU540 SoC.
> The direct memory-mapped SPI flash mode is unsupported.
>
> Signed-off-by: Bin Meng 
> ---
>
>  include/hw/ssi/sifive_spi.h |  47 ++
>  hw/ssi/sifive_spi.c | 290 
>  hw/ssi/Kconfig  |   4 +
>  hw/ssi/meson.build  |   1 +
>  4 files changed, 342 insertions(+)
>  create mode 100644 include/hw/ssi/sifive_spi.h
>  create mode 100644 hw/ssi/sifive_spi.c
>
> diff --git a/include/hw/ssi/sifive_spi.h b/include/hw/ssi/sifive_spi.h
> new file mode 100644
> index 00..dc29d9e3a9
> --- /dev/null
> +++ b/include/hw/ssi/sifive_spi.h
> @@ -0,0 +1,47 @@
> +/*
> + * QEMU model of the SiFive SPI Controller
> + *
> + * Copyright (c) 2020 Wind River Systems, Inc.
> + *
> + * Author:
> + *   Bin Meng 
> + *
> + * This program is free software; you can redistribute it and/or modify it
> + * under the terms and conditions of the GNU General Public License,
> + * version 2 or later, as published by the Free Software Foundation.
> + *
> + * This program is distributed in the hope it will be useful, but WITHOUT
> + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
> + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
> + * more details.
> + *
> + * You should have received a copy of the GNU General Public License along 
> with
> + * this program.  If not, see .
> + */
> +
> +#ifndef HW_SIFIVE_SPI_H
> +#define HW_SIFIVE_SPI_H
> +
> +#define SIFIVE_SPI_REG_NUM  (0x78 / 4)
> +
> +#define TYPE_SIFIVE_SPI "sifive.spi"
> +#define SIFIVE_SPI(obj) OBJECT_CHECK(SiFiveSPIState, (obj), TYPE_SIFIVE_SPI)
> +
> +typedef struct SiFiveSPIState {
> +SysBusDevice parent_obj;
> +
> +MemoryRegion mmio;
> +qemu_irq irq;
> +
> +uint32_t num_cs;
> +qemu_irq *cs_lines;
> +
> +SSIBus *spi;
> +
> +Fifo8 tx_fifo;
> +Fifo8 rx_fifo;
> +
> +uint32_t regs[SIFIVE_SPI_REG_NUM];
> +} SiFiveSPIState;
> +
> +#endif /* HW_SIFIVE_SPI_H */
> diff --git a/hw/ssi/sifive_spi.c b/hw/ssi/sifive_spi.c
> new file mode 100644
> index 00..e1caaf8ade
> --- /dev/null
> +++ b/hw/ssi/sifive_spi.c
> @@ -0,0 +1,290 @@
> +/*
> + * QEMU model of the SiFive SPI Controller
> + *
> + * Copyright (c) 2020 Wind River Systems, Inc.
> + *
> + * Author:
> + *   Bin Meng 
> + *
> + * This program is free software; you can redistribute it and/or modify it
> + * under the terms and conditions of the GNU General Public License,
> + * version 2 or later, as published by the Free Software Foundation.
> + *
> + * This program is distributed in the hope it will be useful, but WITHOUT
> + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
> + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
> + * more details.
> + *
> + * You should have received a copy of the GNU General Public License along 
> with
> + * this program.  If not, see .
> + */
> +
> +#include "qemu/osdep.h"
> +#include "hw/irq.h"
> +#include "hw/qdev-properties.h"
> +#include "hw/sysbus.h"
> +#include "hw/ssi/ssi.h"
> +#include "sysemu/sysemu.h"
> +#include "qemu/fifo8.h"
> +#include "qemu/log.h"
> +#include "qemu/module.h"
> +#include "hw/ssi/sifive_spi.h"
> +
> +#define R_SCKDIV(0x00 / 4)
> +#define R_SCKMODE   (0x04 / 4)
> +#define R_CSID  (0x10 / 4)
> +#define R_CSDEF (0x14 / 4)
> +#define R_CSMODE(0x18 / 4)
> +#define R_DELAY0(0x28 / 4)
> +#define R_DELAY1(0x2C / 4)
> +#define R_FMT   (0x40 / 4)
> +#define R_TXDATA(0x48 / 4)
> +#define R_RXDATA(0x4C / 4)
> +#define R_TXMARK(0x50 / 4)
> +#define R_RXMARK(0x54 / 4)
> +#define R_FCTRL (0x60 / 4)
> +#define R_FFMT  (0x64 / 4)
> +#define R_IE(0x70 / 4)
> +#define R_IP(0x74 / 4)
> +
> +#define TXDATA_FULL (1 << 31)
> +#define RXDATA_EMPTY(1 << 31)
> +
> +#define IE_TXWM (1 << 0)
> +#define IE_RXWM (1 << 1)
> +
> +#define IP_TXWM (1 << 0)
> +#define IP_RXWM (1 << 1)
> +
> +#define FIFO_CAPACITY   8
> +
> +static void sifive_spi_txfifo_reset(SiFiveSPIState *s)
> +{
> +fifo8_reset(>tx_fifo);
> +
> +s->regs[R_TXDATA] &= ~TXDATA_FULL;
> +s->regs[R_IP] &= ~IP_TXWM;
> +}
> +
> +static void sifive_spi_rxfifo_reset(SiFiveSPIState *s)
> +{
> +fifo8_reset(>rx_fifo);
> +
> +s->regs[R_RXDATA] |= RXDATA_EMPTY;
> +s->regs[R_IP] &= ~IP_RXWM;
> +}
> +
> +static void sifive_spi_update_cs(SiFiveSPIState *s)
> +{
> +int i;
> +
> +for (i = 0; i < s->num_cs; i++) {
> +if (s->regs[R_CSDEF] & (1 << i)) {
> +qemu_set_irq(s->cs_lines[i], !(s->regs[R_CSMODE]));
> +}
> +}
> +}
> +
> +static void sifive_spi_update_irq(SiFiveSPIState *s)
> +{
> +int level;
> +
> +if 

Re: [PATCH 15/22] hw/sd: ssi-sd: Support multiple block write

2021-01-13 Thread Alistair Francis
On Thu, Dec 31, 2020 at 3:47 AM Bin Meng  wrote:
>
> From: Bin Meng 
>
> For a multiple block write operation, each block begins with a multi
> write start token. Unlike the SD mode that the multiple block write
> ends when receiving a STOP_TRAN command (CMD12), a special stop tran
> tocken is used to signal the card.
>
> Emulating this by manually sending a CMD12 to the SD card core, to
> bring it out of the receiving data state.
>
> Signed-off-by: Bin Meng 

Acked-by: Alistair Francis 

Alistair

> ---
>
>  hw/sd/ssi-sd.c | 26 --
>  1 file changed, 24 insertions(+), 2 deletions(-)
>
> diff --git a/hw/sd/ssi-sd.c b/hw/sd/ssi-sd.c
> index 21a96e91f0..6cf5d749c7 100644
> --- a/hw/sd/ssi-sd.c
> +++ b/hw/sd/ssi-sd.c
> @@ -99,6 +99,8 @@ OBJECT_DECLARE_SIMPLE_TYPE(ssi_sd_state, SSI_SD)
>  static uint32_t ssi_sd_transfer(SSIPeripheral *dev, uint32_t val)
>  {
>  ssi_sd_state *s = SSI_SD(dev);
> +SDRequest request;
> +uint8_t longresp[16];
>
>  /* Special case: allow CMD12 (STOP TRANSMISSION) while reading data.  */
>  if (s->mode == SSI_SD_DATA_READ && val == 0x4c) {
> @@ -115,9 +117,31 @@ static uint32_t ssi_sd_transfer(SSIPeripheral *dev, 
> uint32_t val)
>  return SSI_DUMMY;
>  break;
>  case SSI_TOKEN_SINGLE:
> +case SSI_TOKEN_MULTI_WRITE:
>  DPRINTF("Start write block\n");
>  s->mode = SSI_SD_DATA_WRITE;
>  return SSI_DUMMY;
> +case SSI_TOKEN_STOP_TRAN:
> +DPRINTF("Stop multiple write\n");
> +
> +/* manually issue cmd12 to stop the transfer */
> +request.cmd = 12;
> +request.arg = 0;
> +s->arglen = sdbus_do_command(>sdbus, , longresp);
> +if (s->arglen <= 0) {
> +s->arglen = 1;
> +/* a zero value indicates the card is busy */
> +s->response[0] = 0;
> +DPRINTF("SD card busy\n");
> +} else {
> +s->arglen = 1;
> +/* a non-zero value indicates the card is ready */
> +s->response[0] = SSI_DUMMY;
> +}
> +
> +s->mode = SSI_SD_RESPONSE;
> +s->response_pos = 0;
> +return SSI_DUMMY;
>  }
>
>  s->cmd = val & 0x3f;
> @@ -126,8 +150,6 @@ static uint32_t ssi_sd_transfer(SSIPeripheral *dev, 
> uint32_t val)
>  return SSI_DUMMY;
>  case SSI_SD_CMDARG:
>  if (s->arglen == 4) {
> -SDRequest request;
> -uint8_t longresp[16];
>  /* FIXME: Check CRC.  */
>  request.cmd = s->cmd;
>  request.arg = ldl_be_p(s->cmdarg);
> --
> 2.25.1
>
>



Re: [PATCH 12/22] hw/sd: sd.h: Cosmetic change of using spaces

2021-01-13 Thread Alistair Francis
On Thu, Dec 31, 2020 at 3:46 AM Bin Meng  wrote:
>
> From: Bin Meng 
>
> QEMU conding convention prefers spaces over tabs.
>
> Signed-off-by: Bin Meng 

Reviewed-by: Alistair Francis 

Alistair

> ---
>
>  include/hw/sd/sd.h | 42 +-
>  1 file changed, 21 insertions(+), 21 deletions(-)
>
> diff --git a/include/hw/sd/sd.h b/include/hw/sd/sd.h
> index 59d108d453..05ef9b73e5 100644
> --- a/include/hw/sd/sd.h
> +++ b/include/hw/sd/sd.h
> @@ -33,27 +33,27 @@
>  #include "hw/qdev-core.h"
>  #include "qom/object.h"
>
> -#define OUT_OF_RANGE   (1 << 31)
> -#define ADDRESS_ERROR  (1 << 30)
> -#define BLOCK_LEN_ERROR(1 << 29)
> -#define ERASE_SEQ_ERROR(1 << 28)
> -#define ERASE_PARAM(1 << 27)
> -#define WP_VIOLATION   (1 << 26)
> -#define CARD_IS_LOCKED (1 << 25)
> -#define LOCK_UNLOCK_FAILED (1 << 24)
> -#define COM_CRC_ERROR  (1 << 23)
> -#define ILLEGAL_COMMAND(1 << 22)
> -#define CARD_ECC_FAILED(1 << 21)
> -#define CC_ERROR   (1 << 20)
> -#define SD_ERROR   (1 << 19)
> -#define CID_CSD_OVERWRITE  (1 << 16)
> -#define WP_ERASE_SKIP  (1 << 15)
> -#define CARD_ECC_DISABLED  (1 << 14)
> -#define ERASE_RESET(1 << 13)
> -#define CURRENT_STATE  (7 << 9)
> -#define READY_FOR_DATA (1 << 8)
> -#define APP_CMD(1 << 5)
> -#define AKE_SEQ_ERROR  (1 << 3)
> +#define OUT_OF_RANGE(1 << 31)
> +#define ADDRESS_ERROR   (1 << 30)
> +#define BLOCK_LEN_ERROR (1 << 29)
> +#define ERASE_SEQ_ERROR (1 << 28)
> +#define ERASE_PARAM (1 << 27)
> +#define WP_VIOLATION(1 << 26)
> +#define CARD_IS_LOCKED  (1 << 25)
> +#define LOCK_UNLOCK_FAILED  (1 << 24)
> +#define COM_CRC_ERROR   (1 << 23)
> +#define ILLEGAL_COMMAND (1 << 22)
> +#define CARD_ECC_FAILED (1 << 21)
> +#define CC_ERROR(1 << 20)
> +#define SD_ERROR(1 << 19)
> +#define CID_CSD_OVERWRITE   (1 << 16)
> +#define WP_ERASE_SKIP   (1 << 15)
> +#define CARD_ECC_DISABLED   (1 << 14)
> +#define ERASE_RESET (1 << 13)
> +#define CURRENT_STATE   (7 << 9)
> +#define READY_FOR_DATA  (1 << 8)
> +#define APP_CMD (1 << 5)
> +#define AKE_SEQ_ERROR   (1 << 3)
>
>  enum SDPhySpecificationVersion {
>  SD_PHY_SPECv1_10_VERS = 1,
> --
> 2.25.1
>
>



Re: [PATCH 14/22] hw/sd: ssi-sd: Support single block write

2021-01-13 Thread Alistair Francis
On Thu, Dec 31, 2020 at 3:43 AM Bin Meng  wrote:
>
> From: Bin Meng 
>
> Add 2 more states for the block write operation. The SPI host needs
> to send a data start tocken to start the transfer, and the data block
> written to the card will be acknowledged by a data response tocken.
>
> Signed-off-by: Bin Meng 

Acked-by: Alistair Francis 

Alistair

> ---
>
>  hw/sd/ssi-sd.c | 37 -
>  1 file changed, 36 insertions(+), 1 deletion(-)
>
> diff --git a/hw/sd/ssi-sd.c b/hw/sd/ssi-sd.c
> index 8eb48550cf..21a96e91f0 100644
> --- a/hw/sd/ssi-sd.c
> +++ b/hw/sd/ssi-sd.c
> @@ -42,6 +42,8 @@ typedef enum {
>  SSI_SD_DATA_START,
>  SSI_SD_DATA_READ,
>  SSI_SD_DATA_CRC16,
> +SSI_SD_DATA_WRITE,
> +SSI_SD_SKIP_CRC16,
>  } ssi_sd_mode;
>
>  struct ssi_sd_state {
> @@ -52,6 +54,7 @@ struct ssi_sd_state {
>  uint8_t response[5];
>  uint16_t crc16;
>  int32_t read_bytes;
> +int32_t write_bytes;
>  int32_t arglen;
>  int32_t response_pos;
>  int32_t stopping;
> @@ -90,6 +93,9 @@ OBJECT_DECLARE_SIMPLE_TYPE(ssi_sd_state, SSI_SD)
>  /* dummy value - don't care */
>  #define SSI_DUMMY   0xff
>
> +/* data accepted */
> +#define DATA_RESPONSE_ACCEPTED  0x05
> +
>  static uint32_t ssi_sd_transfer(SSIPeripheral *dev, uint32_t val)
>  {
>  ssi_sd_state *s = SSI_SD(dev);
> @@ -103,10 +109,17 @@ static uint32_t ssi_sd_transfer(SSIPeripheral *dev, 
> uint32_t val)
>
>  switch (s->mode) {
>  case SSI_SD_CMD:
> -if (val == SSI_DUMMY) {
> +switch (val) {
> +case SSI_DUMMY:
>  DPRINTF("NULL command\n");
>  return SSI_DUMMY;
> +break;
> +case SSI_TOKEN_SINGLE:
> +DPRINTF("Start write block\n");
> +s->mode = SSI_SD_DATA_WRITE;
> +return SSI_DUMMY;
>  }
> +
>  s->cmd = val & 0x3f;
>  s->mode = SSI_SD_CMDARG;
>  s->arglen = 0;
> @@ -235,6 +248,27 @@ static uint32_t ssi_sd_transfer(SSIPeripheral *dev, 
> uint32_t val)
>  s->response_pos = 0;
>  }
>  return val;
> +case SSI_SD_DATA_WRITE:
> +sdbus_write_byte(>sdbus, val);
> +s->write_bytes++;
> +if (!sdbus_receive_ready(>sdbus) || s->write_bytes == 512) {
> +DPRINTF("Data write end\n");
> +s->mode = SSI_SD_SKIP_CRC16;
> +s->response_pos = 0;
> +}
> +return val;
> +case SSI_SD_SKIP_CRC16:
> +/* we don't verify the crc16 */
> +s->response_pos++;
> +if (s->response_pos == 2) {
> +DPRINTF("CRC16 receive end\n");
> +s->mode = SSI_SD_RESPONSE;
> +s->write_bytes = 0;
> +s->arglen = 1;
> +s->response[0] = DATA_RESPONSE_ACCEPTED;
> +s->response_pos = 0;
> +}
> +return SSI_DUMMY;
>  }
>  /* Should never happen.  */
>  return SSI_DUMMY;
> @@ -325,6 +359,7 @@ static void ssi_sd_reset(DeviceState *dev)
>  memset(s->response, 0, sizeof(s->response));
>  s->crc16 = 0;
>  s->read_bytes = 0;
> +s->write_bytes = 0;
>  s->arglen = 0;
>  s->response_pos = 0;
>  s->stopping = 0;
> --
> 2.25.1
>
>



Re: [PATCH 13/22] hw/sd: Introduce receive_ready() callback

2021-01-13 Thread Alistair Francis
On Thu, Dec 31, 2020 at 3:44 AM Bin Meng  wrote:
>
> From: Bin Meng 
>
> At present there is a data_ready() callback for the SD data read
> path. Let's add a receive_ready() for the SD data write path.
>
> Signed-off-by: Bin Meng 

Acked-by: Alistair Francis 

Alistair

> ---
>
>  include/hw/sd/sd.h |  2 ++
>  hw/sd/core.c   | 13 +
>  hw/sd/sd.c |  6 ++
>  3 files changed, 21 insertions(+)
>
> diff --git a/include/hw/sd/sd.h b/include/hw/sd/sd.h
> index 05ef9b73e5..47360ba4ee 100644
> --- a/include/hw/sd/sd.h
> +++ b/include/hw/sd/sd.h
> @@ -116,6 +116,7 @@ struct SDCardClass {
>   * Return: byte value read
>   */
>  uint8_t (*read_byte)(SDState *sd);
> +bool (*receive_ready)(SDState *sd);
>  bool (*data_ready)(SDState *sd);
>  void (*set_voltage)(SDState *sd, uint16_t millivolts);
>  uint8_t (*get_dat_lines)(SDState *sd);
> @@ -187,6 +188,7 @@ void sdbus_write_data(SDBus *sdbus, const void *buf, 
> size_t length);
>   * Read multiple bytes of data on the data lines of a SD bus.
>   */
>  void sdbus_read_data(SDBus *sdbus, void *buf, size_t length);
> +bool sdbus_receive_ready(SDBus *sd);
>  bool sdbus_data_ready(SDBus *sd);
>  bool sdbus_get_inserted(SDBus *sd);
>  bool sdbus_get_readonly(SDBus *sd);
> diff --git a/hw/sd/core.c b/hw/sd/core.c
> index 08c93b5903..30ee62c510 100644
> --- a/hw/sd/core.c
> +++ b/hw/sd/core.c
> @@ -160,6 +160,19 @@ void sdbus_read_data(SDBus *sdbus, void *buf, size_t 
> length)
>  }
>  }
>
> +bool sdbus_receive_ready(SDBus *sdbus)
> +{
> +SDState *card = get_card(sdbus);
> +
> +if (card) {
> +SDCardClass *sc = SD_CARD_GET_CLASS(card);
> +
> +return sc->receive_ready(card);
> +}
> +
> +return false;
> +}
> +
>  bool sdbus_data_ready(SDBus *sdbus)
>  {
>  SDState *card = get_card(sdbus);
> diff --git a/hw/sd/sd.c b/hw/sd/sd.c
> index 67e5f7c05d..f19e38625a 100644
> --- a/hw/sd/sd.c
> +++ b/hw/sd/sd.c
> @@ -2036,6 +2036,11 @@ uint8_t sd_read_byte(SDState *sd)
>  return ret;
>  }
>
> +static bool sd_receive_ready(SDState *sd)
> +{
> +return sd->state == sd_receivingdata_state;
> +}
> +
>  static bool sd_data_ready(SDState *sd)
>  {
>  return sd->state == sd_sendingdata_state;
> @@ -2147,6 +2152,7 @@ static void sd_class_init(ObjectClass *klass, void 
> *data)
>  sc->do_command = sd_do_command;
>  sc->write_byte = sd_write_byte;
>  sc->read_byte = sd_read_byte;
> +sc->receive_ready = sd_receive_ready;
>  sc->data_ready = sd_data_ready;
>  sc->enable = sd_enable;
>  sc->get_inserted = sd_get_inserted;
> --
> 2.25.1
>
>



Re: [PATCH 07/22] hw/sd: ssi-sd: Suffix a data block with CRC16

2021-01-13 Thread Alistair Francis
On Thu, Dec 31, 2020 at 3:38 AM Bin Meng  wrote:
>
> From: Bin Meng 
>
> Per the SD spec, a valid data block is suffixed with a 16-bit CRC
> generated by the standard CCITT polynomial x16+x12+x5+1. This part
> is currently missing in the ssi-sd state machine. Without it, all
> data block transfer fails in guest software because the expected
> CRC16 is missing on the data out line.
>
> Fixes: 775616c3ae8c ("Partial SD card SPI mode support")
> Signed-off-by: Bin Meng 

Acked-by: Alistair Francis 

Alistair

> ---
>
>  hw/sd/ssi-sd.c | 17 +
>  1 file changed, 17 insertions(+)
>
> diff --git a/hw/sd/ssi-sd.c b/hw/sd/ssi-sd.c
> index 228ce4ddc7..10b0ac2eaf 100644
> --- a/hw/sd/ssi-sd.c
> +++ b/hw/sd/ssi-sd.c
> @@ -17,6 +17,7 @@
>  #include "hw/qdev-properties.h"
>  #include "hw/sd/sd.h"
>  #include "qapi/error.h"
> +#include "qemu/crc-ccitt.h"
>  #include "qemu/module.h"
>  #include "qom/object.h"
>
> @@ -40,6 +41,7 @@ typedef enum {
>  SSI_SD_RESPONSE,
>  SSI_SD_DATA_START,
>  SSI_SD_DATA_READ,
> +SSI_SD_DATA_CRC16,
>  } ssi_sd_mode;
>
>  struct ssi_sd_state {
> @@ -48,6 +50,7 @@ struct ssi_sd_state {
>  int cmd;
>  uint8_t cmdarg[4];
>  uint8_t response[5];
> +uint16_t crc16;
>  int32_t arglen;
>  int32_t response_pos;
>  int32_t stopping;
> @@ -193,12 +196,24 @@ static uint32_t ssi_sd_transfer(SSIPeripheral *dev, 
> uint32_t val)
>  case SSI_SD_DATA_START:
>  DPRINTF("Start read block\n");
>  s->mode = SSI_SD_DATA_READ;
> +s->response_pos = 0;
>  return 0xfe;
>  case SSI_SD_DATA_READ:
>  val = sdbus_read_byte(>sdbus);
> +s->crc16 = crc_ccitt_false(s->crc16, (uint8_t *), 1);
>  if (!sdbus_data_ready(>sdbus)) {
>  DPRINTF("Data read end\n");
> +s->mode = SSI_SD_DATA_CRC16;
> +}
> +return val;
> +case SSI_SD_DATA_CRC16:
> +val = (s->crc16 & 0xff00) >> 8;
> +s->crc16 <<= 8;
> +s->response_pos++;
> +if (s->response_pos == 2) {
> +DPRINTF("CRC16 read end\n");
>  s->mode = SSI_SD_CMD;
> +s->response_pos = 0;
>  }
>  return val;
>  }
> @@ -236,6 +251,7 @@ static const VMStateDescription vmstate_ssi_sd = {
>  VMSTATE_INT32(cmd, ssi_sd_state),
>  VMSTATE_UINT8_ARRAY(cmdarg, ssi_sd_state, 4),
>  VMSTATE_UINT8_ARRAY(response, ssi_sd_state, 5),
> +VMSTATE_UINT16(crc16, ssi_sd_state),
>  VMSTATE_INT32(arglen, ssi_sd_state),
>  VMSTATE_INT32(response_pos, ssi_sd_state),
>  VMSTATE_INT32(stopping, ssi_sd_state),
> @@ -287,6 +303,7 @@ static void ssi_sd_reset(DeviceState *dev)
>  s->cmd = 0;
>  memset(s->cmdarg, 0, sizeof(s->cmdarg));
>  memset(s->response, 0, sizeof(s->response));
> +s->crc16 = 0;
>  s->arglen = 0;
>  s->response_pos = 0;
>  s->stopping = 0;
> --
> 2.25.1
>
>



Re: [PATCH 11/22] hw/sd: sd: Allow single/multiple block write for SPI mode

2021-01-13 Thread Alistair Francis
On Thu, Dec 31, 2020 at 3:42 AM Bin Meng  wrote:
>
> From: Bin Meng 
>
> At present the single/multiple block write in SPI mode is blocked
> by sd_normal_command(). Remove the limitation.
>
> Signed-off-by: Bin Meng 

Acked-by: Alistair Francis 

Alistair

> ---
>
>  hw/sd/sd.c | 3 ---
>  1 file changed, 3 deletions(-)
>
> diff --git a/hw/sd/sd.c b/hw/sd/sd.c
> index 1ada616e1e..67e5f7c05d 100644
> --- a/hw/sd/sd.c
> +++ b/hw/sd/sd.c
> @@ -1229,9 +1229,6 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, 
> SDRequest req)
>  case 25:   /* CMD25:  WRITE_MULTIPLE_BLOCK */
>  switch (sd->state) {
>  case sd_transfer_state:
> -/* Writing in SPI mode not implemented.  */
> -if (sd->spi)
> -break;
>
>  if (addr + sd->blk_len > sd->size) {
>  sd->card_status |= ADDRESS_ERROR;
> --
> 2.25.1
>
>



Re: [PATCH 09/22] hw/sd: ssi-sd: Use macros for the dummy value and tokens in the transfer

2021-01-13 Thread Alistair Francis
On Thu, Dec 31, 2020 at 3:38 AM Bin Meng  wrote:
>
> From: Bin Meng 
>
> At present the codes use hardcoded numbers (0xff/0xfe) for the dummy
> value and block start token. Replace them with macros, and add more
> tokens for multiple block write.
>
> Signed-off-by: Bin Meng 

Reviewed-by: Alistair Francis 

Alistair

> ---
>
>  hw/sd/ssi-sd.c | 30 +-
>  1 file changed, 21 insertions(+), 9 deletions(-)
>
> diff --git a/hw/sd/ssi-sd.c b/hw/sd/ssi-sd.c
> index 889260bd8f..8eb48550cf 100644
> --- a/hw/sd/ssi-sd.c
> +++ b/hw/sd/ssi-sd.c
> @@ -78,6 +78,18 @@ OBJECT_DECLARE_SIMPLE_TYPE(ssi_sd_state, SSI_SD)
>  #define SSI_SDR_ADDRESS_ERROR   0x2000
>  #define SSI_SDR_PARAMETER_ERROR 0x4000
>
> +/* reading and writing blocks start with these tokens and end with crc16 */
> +
> +/* multiple block write */
> +#define SSI_TOKEN_MULTI_WRITE   0xfc
> +/* terminate multiple block write */
> +#define SSI_TOKEN_STOP_TRAN 0xfd
> +/* single block read/write, multiple block read */
> +#define SSI_TOKEN_SINGLE0xfe
> +
> +/* dummy value - don't care */
> +#define SSI_DUMMY   0xff
> +
>  static uint32_t ssi_sd_transfer(SSIPeripheral *dev, uint32_t val)
>  {
>  ssi_sd_state *s = SSI_SD(dev);
> @@ -91,14 +103,14 @@ static uint32_t ssi_sd_transfer(SSIPeripheral *dev, 
> uint32_t val)
>
>  switch (s->mode) {
>  case SSI_SD_CMD:
> -if (val == 0xff) {
> +if (val == SSI_DUMMY) {
>  DPRINTF("NULL command\n");
> -return 0xff;
> +return SSI_DUMMY;
>  }
>  s->cmd = val & 0x3f;
>  s->mode = SSI_SD_CMDARG;
>  s->arglen = 0;
> -return 0xff;
> +return SSI_DUMMY;
>  case SSI_SD_CMDARG:
>  if (s->arglen == 4) {
>  SDRequest request;
> @@ -173,14 +185,14 @@ static uint32_t ssi_sd_transfer(SSIPeripheral *dev, 
> uint32_t val)
>  } else {
>  s->cmdarg[s->arglen++] = val;
>  }
> -return 0xff;
> +return SSI_DUMMY;
>  case SSI_SD_PREP_RESP:
>  s->mode = SSI_SD_RESPONSE;
> -return 0xff;
> +return SSI_DUMMY;
>  case SSI_SD_RESPONSE:
>  if (s->stopping) {
>  s->stopping = 0;
> -return 0xff;
> +return SSI_DUMMY;
>  }
>  if (s->response_pos < s->arglen) {
>  DPRINTF("Response 0x%02x\n", s->response[s->response_pos]);
> @@ -193,12 +205,12 @@ static uint32_t ssi_sd_transfer(SSIPeripheral *dev, 
> uint32_t val)
>  DPRINTF("End of command\n");
>  s->mode = SSI_SD_CMD;
>  }
> -return 0xff;
> +return SSI_DUMMY;
>  case SSI_SD_DATA_START:
>  DPRINTF("Start read block\n");
>  s->mode = SSI_SD_DATA_READ;
>  s->response_pos = 0;
> -return 0xfe;
> +return SSI_TOKEN_SINGLE;
>  case SSI_SD_DATA_READ:
>  val = sdbus_read_byte(>sdbus);
>  s->read_bytes++;
> @@ -225,7 +237,7 @@ static uint32_t ssi_sd_transfer(SSIPeripheral *dev, 
> uint32_t val)
>  return val;
>  }
>  /* Should never happen.  */
> -return 0xff;
> +return SSI_DUMMY;
>  }
>
>  static int ssi_sd_post_load(void *opaque, int version_id)
> --
> 2.25.1
>
>



Re: [PATCH 10/22] hw/sd: sd: Remove duplicated codes in single/multiple block read/write

2021-01-13 Thread Alistair Francis
On Thu, Dec 31, 2020 at 3:42 AM Bin Meng  wrote:
>
> From: Bin Meng 
>
> The single block read (CMD17) codes are the same as the multiple
> block read (CMD18). Merge them into one. The same applies to single
> block write (CMD24) and multiple block write (CMD25).
>
> Signed-off-by: Bin Meng 

Acked-by: Alistair Francis 

Alistair

> ---
>
>  hw/sd/sd.c | 47 ---
>  1 file changed, 47 deletions(-)
>
> diff --git a/hw/sd/sd.c b/hw/sd/sd.c
> index 52c7217fe1..1ada616e1e 100644
> --- a/hw/sd/sd.c
> +++ b/hw/sd/sd.c
> @@ -1180,24 +1180,6 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, 
> SDRequest req)
>  break;
>
>  case 17:   /* CMD17:  READ_SINGLE_BLOCK */
> -switch (sd->state) {
> -case sd_transfer_state:
> -
> -if (addr + sd->blk_len > sd->size) {
> -sd->card_status |= ADDRESS_ERROR;
> -return sd_r1;
> -}
> -
> -sd->state = sd_sendingdata_state;
> -sd->data_start = addr;
> -sd->data_offset = 0;
> -return sd_r1;
> -
> -default:
> -break;
> -}
> -break;
> -
>  case 18:   /* CMD18:  READ_MULTIPLE_BLOCK */
>  switch (sd->state) {
>  case sd_transfer_state:
> @@ -1244,35 +1226,6 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, 
> SDRequest req)
>
>  /* Block write commands (Class 4) */
>  case 24:   /* CMD24:  WRITE_SINGLE_BLOCK */
> -switch (sd->state) {
> -case sd_transfer_state:
> -/* Writing in SPI mode not implemented.  */
> -if (sd->spi)
> -break;
> -
> -if (addr + sd->blk_len > sd->size) {
> -sd->card_status |= ADDRESS_ERROR;
> -return sd_r1;
> -}
> -
> -sd->state = sd_receivingdata_state;
> -sd->data_start = addr;
> -sd->data_offset = 0;
> -sd->blk_written = 0;
> -
> -if (sd_wp_addr(sd, sd->data_start)) {
> -sd->card_status |= WP_VIOLATION;
> -}
> -if (sd->csd[14] & 0x30) {
> -sd->card_status |= WP_VIOLATION;
> -}
> -return sd_r1;
> -
> -default:
> -break;
> -}
> -break;
> -
>  case 25:   /* CMD25:  WRITE_MULTIPLE_BLOCK */
>  switch (sd->state) {
>  case sd_transfer_state:
> --
> 2.25.1
>
>



Re: [PATCH 08/22] hw/sd: ssi-sd: Support multiple block read (CMD18)

2021-01-13 Thread Alistair Francis
On Thu, Dec 31, 2020 at 3:41 AM Bin Meng  wrote:
>
> From: Bin Meng 
>
> In the case of a multiple block read operation every transfered
> block has its suffix of CRC16. Update the state machine logic to
> handle multiple block read.
>
> This also fixed the wrong command index for STOP_TRANSMISSION,
> the required command to interupt the multiple block read command,
> in the old codes. It should be CMD12 (0x4c), not CMD13 (0x4d).
>
> Signed-off-by: Bin Meng 

Acked-by: Alistair Francis 

Alistair

> ---
>
>  hw/sd/ssi-sd.c | 15 ---
>  1 file changed, 12 insertions(+), 3 deletions(-)
>
> diff --git a/hw/sd/ssi-sd.c b/hw/sd/ssi-sd.c
> index 10b0ac2eaf..889260bd8f 100644
> --- a/hw/sd/ssi-sd.c
> +++ b/hw/sd/ssi-sd.c
> @@ -51,6 +51,7 @@ struct ssi_sd_state {
>  uint8_t cmdarg[4];
>  uint8_t response[5];
>  uint16_t crc16;
> +int32_t read_bytes;
>  int32_t arglen;
>  int32_t response_pos;
>  int32_t stopping;
> @@ -82,7 +83,7 @@ static uint32_t ssi_sd_transfer(SSIPeripheral *dev, 
> uint32_t val)
>  ssi_sd_state *s = SSI_SD(dev);
>
>  /* Special case: allow CMD12 (STOP TRANSMISSION) while reading data.  */
> -if (s->mode == SSI_SD_DATA_READ && val == 0x4d) {
> +if (s->mode == SSI_SD_DATA_READ && val == 0x4c) {
>  s->mode = SSI_SD_CMD;
>  /* There must be at least one byte delay before the card responds.  
> */
>  s->stopping = 1;
> @@ -200,8 +201,9 @@ static uint32_t ssi_sd_transfer(SSIPeripheral *dev, 
> uint32_t val)
>  return 0xfe;
>  case SSI_SD_DATA_READ:
>  val = sdbus_read_byte(>sdbus);
> +s->read_bytes++;
>  s->crc16 = crc_ccitt_false(s->crc16, (uint8_t *), 1);
> -if (!sdbus_data_ready(>sdbus)) {
> +if (!sdbus_data_ready(>sdbus) || s->read_bytes == 512) {
>  DPRINTF("Data read end\n");
>  s->mode = SSI_SD_DATA_CRC16;
>  }
> @@ -212,7 +214,12 @@ static uint32_t ssi_sd_transfer(SSIPeripheral *dev, 
> uint32_t val)
>  s->response_pos++;
>  if (s->response_pos == 2) {
>  DPRINTF("CRC16 read end\n");
> -s->mode = SSI_SD_CMD;
> +if (s->read_bytes == 512 && s->cmd != 17) {
> +s->mode = SSI_SD_DATA_START;
> +} else {
> +s->mode = SSI_SD_CMD;
> +}
> +s->read_bytes = 0;
>  s->response_pos = 0;
>  }
>  return val;
> @@ -252,6 +259,7 @@ static const VMStateDescription vmstate_ssi_sd = {
>  VMSTATE_UINT8_ARRAY(cmdarg, ssi_sd_state, 4),
>  VMSTATE_UINT8_ARRAY(response, ssi_sd_state, 5),
>  VMSTATE_UINT16(crc16, ssi_sd_state),
> +VMSTATE_INT32(read_bytes, ssi_sd_state),
>  VMSTATE_INT32(arglen, ssi_sd_state),
>  VMSTATE_INT32(response_pos, ssi_sd_state),
>  VMSTATE_INT32(stopping, ssi_sd_state),
> @@ -304,6 +312,7 @@ static void ssi_sd_reset(DeviceState *dev)
>  memset(s->cmdarg, 0, sizeof(s->cmdarg));
>  memset(s->response, 0, sizeof(s->response));
>  s->crc16 = 0;
> +s->read_bytes = 0;
>  s->arglen = 0;
>  s->response_pos = 0;
>  s->stopping = 0;
> --
> 2.25.1
>
>



Re: [PATCH 02/22] hw/block: m25p80: Add various ISSI flash information

2021-01-05 Thread Alistair Francis
On Thu, Dec 31, 2020 at 3:32 AM Bin Meng  wrote:
>
> From: Bin Meng 
>
> This updates the flash information table to include various ISSI
> flashes that are supported by upstream U-Boot and Linux kernel.
>
> Signed-off-by: Bin Meng 

Acked-by: Alistair Francis 

Alistair

> ---
>
>  hw/block/m25p80.c | 13 +
>  1 file changed, 13 insertions(+)
>
> diff --git a/hw/block/m25p80.c b/hw/block/m25p80.c
> index 8a62bc4bc4..e82deb41c6 100644
> --- a/hw/block/m25p80.c
> +++ b/hw/block/m25p80.c
> @@ -209,6 +209,19 @@ static const FlashPartInfo known_devices[] = {
>  { INFO("640s33b", 0x898913,  0,  64 << 10, 128, 0) },
>  { INFO("n25q064", 0x20ba17,  0,  64 << 10, 128, 0) },
>
> +/* ISSI */
> +{ INFO("is25lq040b",  0x9d4013,  0,  64 << 10,   8, ER_4K) },
> +{ INFO("is25lp080d",  0x9d6014,  0,  64 << 10,  16, ER_4K) },
> +{ INFO("is25lp016d",  0x9d6015,  0,  64 << 10,  32, ER_4K) },
> +{ INFO("is25lp032",   0x9d6016,  0,  64 << 10,  64, ER_4K) },
> +{ INFO("is25lp064",   0x9d6017,  0,  64 << 10, 128, ER_4K) },
> +{ INFO("is25lp128",   0x9d6018,  0,  64 << 10, 256, ER_4K) },
> +{ INFO("is25lp256",   0x9d6019,  0,  64 << 10, 512, ER_4K) },
> +{ INFO("is25wp032",   0x9d7016,  0,  64 << 10,  64, ER_4K) },
> +{ INFO("is25wp064",   0x9d7017,  0,  64 << 10, 128, ER_4K) },
> +{ INFO("is25wp128",   0x9d7018,  0,  64 << 10, 256, ER_4K) },
> +{ INFO("is25wp256",   0x9d7019,  0,  64 << 10, 512, ER_4K) },
> +
>  /* Macronix */
>  { INFO("mx25l2005a",  0xc22012,  0,  64 << 10,   4, ER_4K) },
>  { INFO("mx25l4005a",  0xc22013,  0,  64 << 10,   8, ER_4K) },
> --
> 2.25.1
>
>



Re: [PATCH v5 1/2] hw/block: m25p80: Don't write to flash if write is disabled

2021-01-05 Thread Alistair Francis
On Mon, Jan 4, 2021 at 7:50 PM Bin Meng  wrote:
>
> On Wed, Dec 23, 2020 at 10:00 AM Bin Meng  wrote:
> >
> > From: Bin Meng 
> >
> > When write is disabled, the write to flash should be avoided
> > in flash_write8().
> >
> > Fixes: 82a2499011a7 ("m25p80: Initial implementation of SPI flash device")
> > Signed-off-by: Bin Meng 
> > Reviewed-by: Philippe Mathieu-Daudé 
> > Reviewed-by: Francisco Iglesias 
> >
> > ---
> >
> > (no changes since v2)
> >
> > Changes in v2:
> > - new patch: honor write enable flag in flash write
> >
> >  hw/block/m25p80.c | 1 +
> >  1 file changed, 1 insertion(+)
> >
>
> Ping?

Thanks!

Applied to riscv-to-apply.next

Alistair

>



Re: [PATCH] hw/block: m25p80: Fix fast read for SST flashes

2020-12-02 Thread Alistair Francis
On Wed, Dec 2, 2020 at 3:09 PM Bin Meng  wrote:
>
> Hi Alistair,
>
> On Thu, Dec 3, 2020 at 3:52 AM Alistair Francis  wrote:
> >
> > On Sun, Nov 29, 2020 at 6:55 PM Bin Meng  wrote:
> > >
> > > From: Bin Meng 
> > >
> > > SST flashes require a dummy byte after the address bits.
> > >
> > > Signed-off-by: Bin Meng 
> >
> > I couldn't find a datasheet that says this... But the actual code
> > change looks fine, so:
> >
>
> Please find the SST25VF016B datasheet at
> http://ww1.microchip.com/downloads/en/devicedoc/s71271_04.pdf. The
> fast read sequence is on page 11.

Ah cool. I thought it would be somewhere, I just couldn't find it.

Alistair

>
> > Acked-by: Alistair Francis 
> >
>
> Thanks!
>
> Regards,
> Bin



Re: [PATCH] hw/block: m25p80: Fix fast read for SST flashes

2020-12-02 Thread Alistair Francis
On Sun, Nov 29, 2020 at 6:55 PM Bin Meng  wrote:
>
> From: Bin Meng 
>
> SST flashes require a dummy byte after the address bits.
>
> Signed-off-by: Bin Meng 

I couldn't find a datasheet that says this... But the actual code
change looks fine, so:

Acked-by: Alistair Francis 

Alistair

> ---
>
>  hw/block/m25p80.c | 3 +++
>  1 file changed, 3 insertions(+)
>
> diff --git a/hw/block/m25p80.c b/hw/block/m25p80.c
> index 483925f..9b36762 100644
> --- a/hw/block/m25p80.c
> +++ b/hw/block/m25p80.c
> @@ -825,6 +825,9 @@ static void decode_fast_read_cmd(Flash *s)
>  s->needed_bytes = get_addr_length(s);
>  switch (get_man(s)) {
>  /* Dummy cycles - modeled with bytes writes instead of bits */
> +case MAN_SST:
> +s->needed_bytes += 1;
> +break;
>  case MAN_WINBOND:
>  s->needed_bytes += 8;
>  break;
> --
> 2.7.4
>
>



Re: [PATCH v2 1/2] util/hexdump: Convert to take a void pointer argument

2020-08-25 Thread Alistair Francis
On Sat, Aug 22, 2020 at 11:10 AM Philippe Mathieu-Daudé  wrote:
>
> Most uses of qemu_hexdump() do not take an array of char
> as input, forcing use of cast. Since we can use this
> helper to dump any kind of buffer, use a pointer to void
> argument instead.
>
> Signed-off-by: Philippe Mathieu-Daudé 

Reviewed-by: Alistair Francis 

Alistair

> ---
> Since v1:
> - renamed argument 'bufptr' (Peter Maydell)
> ---
>  include/qemu-common.h|  3 ++-
>  hw/dma/xlnx_dpdma.c  |  2 +-
>  hw/net/fsl_etsec/etsec.c |  2 +-
>  hw/sd/sd.c   |  2 +-
>  hw/usb/redirect.c|  2 +-
>  net/colo-compare.c   | 12 ++--
>  net/net.c|  2 +-
>  util/hexdump.c   |  4 +++-
>  8 files changed, 16 insertions(+), 13 deletions(-)
>
> diff --git a/include/qemu-common.h b/include/qemu-common.h
> index bb9496bd80f..6834883822f 100644
> --- a/include/qemu-common.h
> +++ b/include/qemu-common.h
> @@ -138,7 +138,8 @@ int os_parse_cmd_args(int index, const char *optarg);
>   * Hexdump a buffer to a file. An optional string prefix is added to every 
> line
>   */
>
> -void qemu_hexdump(const char *buf, FILE *fp, const char *prefix, size_t 
> size);
> +void qemu_hexdump(const void *bufptr, FILE *fp,
> +  const char *prefix, size_t size);
>
>  /*
>   * helper to parse debug environment variables
> diff --git a/hw/dma/xlnx_dpdma.c b/hw/dma/xlnx_dpdma.c
> index b40c897de2c..d75a8069426 100644
> --- a/hw/dma/xlnx_dpdma.c
> +++ b/hw/dma/xlnx_dpdma.c
> @@ -388,7 +388,7 @@ static void xlnx_dpdma_dump_descriptor(DPDMADescriptor 
> *desc)
>  {
>  if (DEBUG_DPDMA) {
>  qemu_log("DUMP DESCRIPTOR:\n");
> -qemu_hexdump((char *)desc, stdout, "", sizeof(DPDMADescriptor));
> +qemu_hexdump(desc, stdout, "", sizeof(DPDMADescriptor));
>  }
>  }
>
> diff --git a/hw/net/fsl_etsec/etsec.c b/hw/net/fsl_etsec/etsec.c
> index 7035cf4eb97..c817a28decd 100644
> --- a/hw/net/fsl_etsec/etsec.c
> +++ b/hw/net/fsl_etsec/etsec.c
> @@ -357,7 +357,7 @@ static ssize_t etsec_receive(NetClientState *nc,
>
>  #if defined(HEX_DUMP)
>  fprintf(stderr, "%s receive size:%zd\n", nc->name, size);
> -qemu_hexdump((void *)buf, stderr, "", size);
> +qemu_hexdump(buf, stderr, "", size);
>  #endif
>  /* Flush is unnecessary as are already in receiving path */
>  etsec->need_flush = false;
> diff --git a/hw/sd/sd.c b/hw/sd/sd.c
> index fad9cf1ee7a..190e4cf1232 100644
> --- a/hw/sd/sd.c
> +++ b/hw/sd/sd.c
> @@ -1781,7 +1781,7 @@ send_response:
>  }
>
>  #ifdef DEBUG_SD
> -qemu_hexdump((const char *)response, stderr, "Response", rsplen);
> +qemu_hexdump(response, stderr, "Response", rsplen);
>  #endif
>
>  return rsplen;
> diff --git a/hw/usb/redirect.c b/hw/usb/redirect.c
> index 417a60a2e68..09edb0d81c0 100644
> --- a/hw/usb/redirect.c
> +++ b/hw/usb/redirect.c
> @@ -240,7 +240,7 @@ static void usbredir_log_data(USBRedirDevice *dev, const 
> char *desc,
>  if (dev->debug < usbredirparser_debug_data) {
>  return;
>  }
> -qemu_hexdump((char *)data, stderr, desc, len);
> +qemu_hexdump(data, stderr, desc, len);
>  }
>
>  /*
> diff --git a/net/colo-compare.c b/net/colo-compare.c
> index 2c20de1537d..550272b3baa 100644
> --- a/net/colo-compare.c
> +++ b/net/colo-compare.c
> @@ -494,9 +494,9 @@ sec:
>  g_queue_push_head(>secondary_list, spkt);
>
>  if (trace_event_get_state_backends(TRACE_COLO_COMPARE_MISCOMPARE)) {
> -qemu_hexdump((char *)ppkt->data, stderr,
> +qemu_hexdump(ppkt->data, stderr,
>  "colo-compare ppkt", ppkt->size);
> -qemu_hexdump((char *)spkt->data, stderr,
> +qemu_hexdump(spkt->data, stderr,
>  "colo-compare spkt", spkt->size);
>  }
>
> @@ -535,9 +535,9 @@ static int colo_packet_compare_udp(Packet *spkt, Packet 
> *ppkt)
>  trace_colo_compare_udp_miscompare("primary pkt size", ppkt->size);
>  trace_colo_compare_udp_miscompare("Secondary pkt size", spkt->size);
>  if (trace_event_get_state_backends(TRACE_COLO_COMPARE_MISCOMPARE)) {
> -qemu_hexdump((char *)ppkt->data, stderr, "colo-compare pri pkt",
> +qemu_hexdump(ppkt->data, stderr, "colo-compare pri pkt",
>   ppkt->size);
> -qemu_hexdump((char *)spkt->data, stderr, "colo-compare sec pkt",
> +qemu_hexdump(spkt-

Re: Suspicious QOM types without instance/class size

2020-08-21 Thread Alistair Francis
On Thu, Aug 20, 2020 at 2:56 PM Eduardo Habkost  wrote:
>
> While trying to convert TypeInfo declarations to the new
> OBJECT_DECLARE* macros, I've stumbled on a few suspicious cases
> where instance_size or class_size is not set, despite having type
> checker macros that use a specific type.
>
> The ones with "WARNING" are abstract types (maybe not serious if
> subclasses set the appropriate sizes).  The ones with "ERROR"
> don't seem to be abstract types.
>

> ERROR: hw/core/register.c:328:1: instance_size should be set to 
> sizeof(RegisterInfo)?

I'll send a patch out for this one today.

If you are fixing all of these as part of a series I'm also happy to
just let you do that.

Alistair

>
> --
> Eduardo
>
>



Re: [PATCH 00/18] hw/riscv: Add Microchip PolarFire SoC Icicle Kit board support

2020-08-17 Thread Alistair Francis
On Mon, Aug 17, 2020 at 11:12 AM via  wrote:
>
> Hi Anup,
>
> On 8/17/20 11:30 AM, Bin Meng wrote:
> > EXTERNAL EMAIL: Do not click links or open attachments unless you know the 
> > content is safe
> >
> > Hi Anup,
> >
> > On Sat, Aug 15, 2020 at 1:44 AM Anup Patel  wrote:
> >> On Fri, Aug 14, 2020 at 10:12 PM Bin Meng  wrote:
> >>> From: Bin Meng 
> >>>
> >>> This adds support for Microchip PolarFire SoC Icicle Kit board.
> >>> The Icicle Kit board integrates a PolarFire SoC, with one SiFive's
> >>> E51 plus four U54 cores and many on-chip peripherals and an FPGA.
> >> Nice Work !!! This is very helpful.
> > Thanks!
> >
> >> The Microchip HSS is quite convoluted. It has:
> >> 1. DDR Init
> >> 2. Boot device support
> >> 3. SBI support using OpenSBI as library
> >> 4. Simple TEE support
> >>
> >> I think point 1) and 2) above should be part of U-Boot SPL.
> >> The point 3) can be OpenSBI FW_DYNAMIC.
> >>
> >> Lastly,for point 4), we are working on a new OpenSBI feature using
> >> which we can run independent Secure OS and Non-Secure OS using
> >> U-Boot_SPL+OpenSBI (for both SiFive Unleashed and Microchip
> >> PolarFire).
> >>
> >> Do you have plans for adding U-Boot SPL support for this board ??
> > + Cyril Jean from Microchip
> >
> > I will have to leave this question to Cyril to comment.
> >
> I currently do not have a plan to support U-Boot SPL. The idea of the
> HSS is to contain all the silicon specific initialization and
> configuration code within the HSS before jumping to U-Boot S-mode. I
> would rather keep all this within the HSS for the time being. I would
> wait until we reach production silicon before attempting to move this to
> U-Boot SPL as the HSS is likely to contain some opaque silicon related
> changes for another while.

That is unfortunate, a lot of work has gone into making the boot flow
simple and easy to use.

QEMU now includes OpenSBI by default to make it easy for users to boot
Linux. The Icicle Kit board is now the most difficult QEMU board to
boot Linux on. Not to mention it makes it hard to impossible to
support it in standard tool flows such as meta-riscv.

Alistair

>
>
> Regards,
>
> Cyril.
>



Re: [PATCH 2/2] scsi-generic: Fix HM-zoned device scan

2020-08-17 Thread Alistair Francis
On Tue, Aug 11, 2020 at 3:52 PM Dmitry Fomichev  wrote:
>
> Several important steps during device scan depend on SCSI type of the
> device. For example, max_transfer property is only determined and
> assigned if the device has the type of TYPE_DISK.
>
> Host-managed ZBC disks retain most of the properties of regular SCSI
> drives, but they have their own SCSI device type, 0x14. This prevents
> the proper assignment of max_transfer property for HM-zoned devices in
> scsi-generic driver leading to I/O errors if the maximum i/o size
> calculated at the guest exceeds the host value.
>
> To fix this, define TYPE_ZBC to have the standard value from SCSI ZBC
> standard spec. Several scan steps that were previously done only for
> TYPE_DISK devices, are now performed for the SCSI devices having
> TYPE_ZBC too.
>
> Reported-by: Johannes Thumshirn 
> Signed-off-by: Dmitry Fomichev 

Reviewed-by: Alistair Francis 

Alistair

> ---
>  hw/scsi/scsi-generic.c   | 10 ++
>  include/scsi/constants.h |  1 +
>  2 files changed, 7 insertions(+), 4 deletions(-)
>
> diff --git a/hw/scsi/scsi-generic.c b/hw/scsi/scsi-generic.c
> index 86ed0a3822..2cb23ca891 100644
> --- a/hw/scsi/scsi-generic.c
> +++ b/hw/scsi/scsi-generic.c
> @@ -162,7 +162,8 @@ static void scsi_handle_inquiry_reply(SCSIGenericReq *r, 
> SCSIDevice *s)
>  }
>  }
>
> -if (s->type == TYPE_DISK && (r->req.cmd.buf[1] & 0x01)) {
> +if ((s->type == TYPE_DISK || s->type == TYPE_ZBC) &&
> +(r->req.cmd.buf[1] & 0x01)) {
>  page = r->req.cmd.buf[2];
>  if (page == 0xb0) {
>  uint32_t max_transfer =
> @@ -299,10 +300,11 @@ static void scsi_read_complete(void * opaque, int ret)
>  }
>  blk_set_guest_block_size(s->conf.blk, s->blocksize);
>
> -/* Patch MODE SENSE device specific parameters if the BDS is opened
> +/*
> + * Patch MODE SENSE device specific parameters if the BDS is opened
>   * readonly.
>   */
> -if ((s->type == TYPE_DISK || s->type == TYPE_TAPE) &&
> +if ((s->type == TYPE_DISK || s->type == TYPE_TAPE || s->type == 
> TYPE_ZBC) &&
>  blk_is_read_only(s->conf.blk) &&
>  (r->req.cmd.buf[0] == MODE_SENSE ||
>   r->req.cmd.buf[0] == MODE_SENSE_10) &&
> @@ -617,7 +619,7 @@ static void 
> scsi_generic_read_device_identification(SCSIDevice *s)
>  void scsi_generic_read_device_inquiry(SCSIDevice *s)
>  {
>  scsi_generic_read_device_identification(s);
> -if (s->type == TYPE_DISK) {
> +if (s->type == TYPE_DISK || s->type == TYPE_ZBC) {
>  scsi_generic_set_vpd_bl_emulation(s);
>  } else {
>  s->needs_vpd_bl_emulation = false;
> diff --git a/include/scsi/constants.h b/include/scsi/constants.h
> index 874176019e..2a32c08b5e 100644
> --- a/include/scsi/constants.h
> +++ b/include/scsi/constants.h
> @@ -218,6 +218,7 @@
>  #define TYPE_ENCLOSURE  0x0d/* Enclosure Services Device */
>  #define TYPE_RBC0x0e/* Simplified Direct-Access Device */
>  #define TYPE_OSD0x11/* Object-storage Device */
> +#define TYPE_ZBC0x14/* Host-managed Zoned SCSI Device */
>  #define TYPE_WLUN   0x1e/* Well known LUN */
>  #define TYPE_NOT_PRESENT0x1f
>  #define TYPE_INACTIVE   0x20
> --
> 2.21.0
>
>



Re: [PATCH v2 7/9] hw/sd/sdcard: Do not allow invalid SD card sizes

2020-07-13 Thread Alistair Francis
On Mon, Jul 13, 2020 at 11:33 AM Philippe Mathieu-Daudé  wrote:
>
> QEMU allows to create SD card with unrealistic sizes. This could
> work, but some guests (at least Linux) consider sizes that are not
> a power of 2 as a firmware bug and fix the card size to the next
> power of 2.
>
> While the possibility to use small SD card images has been seen as
> a feature, it became a bug with CVE-2020-13253, where the guest is
> able to do OOB read/write accesses past the image size end.
>
> In a pair of commits we will fix CVE-2020-13253 as:
>
> Read command is rejected if BLOCK_LEN_ERROR or ADDRESS_ERROR
> occurred and no data transfer is performed.
>
> Write command is rejected if BLOCK_LEN_ERROR or ADDRESS_ERROR
> occurred and no data transfer is performed.
>
> WP_VIOLATION errors are not modified: the error bit is set, we
> stay in receive-data state, wait for a stop command. All further
> data transfer is ignored. See the check on sd->card_status at the
> beginning of sd_read_data() and sd_write_data().
>
> While this is the correct behavior, in case QEMU create smaller SD
> cards, guests still try to access past the image size end, and QEMU
> considers this is an invalid address, thus "all further data transfer
> is ignored". This is wrong and make the guest looping until
> eventually timeouts.
>
> Fix by not allowing invalid SD card sizes (suggesting the expected
> size as a hint):
>
>   $ qemu-system-arm -M orangepi-pc -drive file=rootfs.ext2,if=sd,format=raw
>   qemu-system-arm: Invalid SD card size: 60 MiB
>   SD card size has to be a power of 2, e.g. 64 MiB.
>   You can resize disk images with 'qemu-img resize  '
>   (note that this will lose data if you make the image smaller than it 
> currently is).
>
> Signed-off-by: Philippe Mathieu-Daudé 

Reviewed-by: Alistair Francis 

Alistair

> ---
> Since v1:
>   Addressed Alistair & Peter comments (error_append_hint message)
> ---
>  hw/sd/sd.c | 25 +
>  1 file changed, 25 insertions(+)
>
> diff --git a/hw/sd/sd.c b/hw/sd/sd.c
> index edd60a09c0..5ab945dade 100644
> --- a/hw/sd/sd.c
> +++ b/hw/sd/sd.c
> @@ -32,6 +32,7 @@
>
>  #include "qemu/osdep.h"
>  #include "qemu/units.h"
> +#include "qemu/cutils.h"
>  #include "hw/irq.h"
>  #include "hw/registerfields.h"
>  #include "sysemu/block-backend.h"
> @@ -2106,11 +2107,35 @@ static void sd_realize(DeviceState *dev, Error **errp)
>  }
>
>  if (sd->blk) {
> +int64_t blk_size;
> +
>  if (blk_is_read_only(sd->blk)) {
>  error_setg(errp, "Cannot use read-only drive as SD card");
>  return;
>  }
>
> +blk_size = blk_getlength(sd->blk);
> +if (blk_size > 0 && !is_power_of_2(blk_size)) {
> +int64_t blk_size_aligned = pow2ceil(blk_size);
> +char *blk_size_str;
> +
> +blk_size_str = size_to_str(blk_size);
> +error_setg(errp, "Invalid SD card size: %s", blk_size_str);
> +g_free(blk_size_str);
> +
> +blk_size_str = size_to_str(blk_size_aligned);
> +error_append_hint(errp,
> +  "SD card size has to be a power of 2, e.g. 
> %s.\n"
> +  "You can resize disk images with "
> +  "'qemu-img resize  '\n"
> +  "(note that this will lose data if you make 
> the "
> +  "image smaller than it currently is).\n",
> +  blk_size_str);
> +g_free(blk_size_str);
> +
> +return;
> +}
> +
>  ret = blk_set_perm(sd->blk, BLK_PERM_CONSISTENT_READ | 
> BLK_PERM_WRITE,
> BLK_PERM_ALL, errp);
>  if (ret < 0) {
> --
> 2.21.3
>
>



Re: [PATCH v2 4/9] tests/acceptance/boot_linux: Expand SD card image to power of 2

2020-07-13 Thread Alistair Francis
On Mon, Jul 13, 2020 at 11:34 AM Philippe Mathieu-Daudé  wrote:
>
> In few commits we won't allow SD card images with invalid size
> (not aligned to a power of 2). Prepare the tests: add the
> pow2ceil() and image_pow2ceil_expand() methods and resize the
> images (expanding) of the tests using SD cards.
>
> Signed-off-by: Philippe Mathieu-Daudé 

Reviewed-by: Alistair Francis 

Alistair

> ---
> Since v1: Addressed review comments
> - truncate -> expand reword (Alistair Francis)
> - expand after uncompress (Niek Linnenbank)
> ---
>  tests/acceptance/boot_linux_console.py | 27 +-
>  1 file changed, 18 insertions(+), 9 deletions(-)
>
> diff --git a/tests/acceptance/boot_linux_console.py 
> b/tests/acceptance/boot_linux_console.py
> index b7e8858c2d..8f2a6aa8a4 100644
> --- a/tests/acceptance/boot_linux_console.py
> +++ b/tests/acceptance/boot_linux_console.py
> @@ -28,6 +28,18 @@
>  except CmdNotFoundError:
>  P7ZIP_AVAILABLE = False
>
> +# round up to next power of 2
> +def pow2ceil(x):
> +return 1 if x == 0 else 2**(x - 1).bit_length()
> +
> +# expand file size to next power of 2
> +def image_pow2ceil_expand(path):
> +size = os.path.getsize(path)
> +size_aligned = pow2ceil(size)
> +if size != size_aligned:
> +with open(path, 'ab+') as fd:
> +fd.truncate(size_aligned)
> +
>  class LinuxKernelTest(Test):
>  KERNEL_COMMON_COMMAND_LINE = 'printk.time=0 '
>
> @@ -636,6 +648,7 @@ def test_arm_orangepi_sd(self):
>  rootfs_path_xz = self.fetch_asset(rootfs_url, asset_hash=rootfs_hash)
>  rootfs_path = os.path.join(self.workdir, 'rootfs.cpio')
>  archive.lzma_uncompress(rootfs_path_xz, rootfs_path)
> +image_pow2ceil_expand(rootfs_path)
>
>  self.vm.set_console()
>  kernel_command_line = (self.KERNEL_COMMON_COMMAND_LINE +
> @@ -673,7 +686,7 @@ def test_arm_orangepi_bionic(self):
>  :avocado: tags=device:sd
>  """
>
> -# This test download a 196MB compressed image and expand it to 
> 932MB...
> +# This test download a 196MB compressed image and expand it to 1GB
>  image_url = ('https://dl.armbian.com/orangepipc/archive/'
>   'Armbian_19.11.3_Orangepipc_bionic_current_5.3.9.7z')
>  image_hash = '196a8ffb72b0123d92cea4a070894813d305c71e'
> @@ -681,6 +694,7 @@ def test_arm_orangepi_bionic(self):
>  image_name = 'Armbian_19.11.3_Orangepipc_bionic_current_5.3.9.img'
>  image_path = os.path.join(self.workdir, image_name)
>  process.run("7z e -o%s %s" % (self.workdir, image_path_7z))
> +image_pow2ceil_expand(image_path)
>
>  self.vm.set_console()
>  self.vm.add_args('-drive', 'file=' + image_path + 
> ',if=sd,format=raw',
> @@ -714,7 +728,7 @@ def test_arm_orangepi_uboot_netbsd9(self):
>  :avocado: tags=machine:orangepi-pc
>  :avocado: tags=device:sd
>  """
> -# This test download a 304MB compressed image and expand it to 
> 1.3GB...
> +# This test download a 304MB compressed image and expand it to 2GB
>  deb_url = ('http://snapshot.debian.org/archive/debian/'
> '20200108T145233Z/pool/main/u/u-boot/'
> 'u-boot-sunxi_2020.01%2Bdfsg-1_armhf.deb')
> @@ -731,8 +745,9 @@ def test_arm_orangepi_uboot_netbsd9(self):
>  image_hash = '2babb29d36d8360adcb39c09e31060945259917a'
>  image_path_gz = self.fetch_asset(image_url, asset_hash=image_hash)
>  image_path = os.path.join(self.workdir, 'armv7.img')
> -image_drive_args = 'if=sd,format=raw,snapshot=on,file=' + image_path
>  archive.gzip_uncompress(image_path_gz, image_path)
> +image_pow2ceil_expand(image_path)
> +image_drive_args = 'if=sd,format=raw,snapshot=on,file=' + image_path
>
>  # dd if=u-boot-sunxi-with-spl.bin of=armv7.img bs=1K seek=8 
> conv=notrunc
>  with open(uboot_path, 'rb') as f_in:
> @@ -740,12 +755,6 @@ def test_arm_orangepi_uboot_netbsd9(self):
>  f_out.seek(8 * 1024)
>  shutil.copyfileobj(f_in, f_out)
>
> -# Extend image, to avoid that NetBSD thinks the partition
> -# inside the image is larger than device size itself
> -f_out.seek(0, 2)
> -f_out.seek(64 * 1024 * 1024, 1)
> -f_out.write(bytearray([0x00]))
> -
>  self.vm.set_console()
>  self.vm.add_args('-nic', 'user',
>   '-drive', image_drive_args,
> --
> 2.21.3
>
>



Re: [PATCH v2 2/9] docs/orangepi: Add instructions for resizing SD image to power of two

2020-07-13 Thread Alistair Francis
On Mon, Jul 13, 2020 at 11:32 AM Philippe Mathieu-Daudé  wrote:
>
> From: Niek Linnenbank 
>
> SD cards need to have a size of a power of two.
> Update the Orange Pi machine documentation to include
> instructions for resizing downloaded images using the
> qemu-img command.
>
> Signed-off-by: Niek Linnenbank 
> Reviewed-by: Philippe Mathieu-Daudé 
> Message-Id: <20200712183708.15450-1-nieklinnenb...@gmail.com>
> Signed-off-by: Philippe Mathieu-Daudé 

Reviewed-by: Alistair Francis 

Alistair

> ---
>  docs/system/arm/orangepi.rst | 16 +---
>  1 file changed, 13 insertions(+), 3 deletions(-)
>
> diff --git a/docs/system/arm/orangepi.rst b/docs/system/arm/orangepi.rst
> index c41adad488..6f23907fb6 100644
> --- a/docs/system/arm/orangepi.rst
> +++ b/docs/system/arm/orangepi.rst
> @@ -127,6 +127,16 @@ can be downloaded from:
>  Alternatively, you can also choose to build you own image with buildroot
>  using the orangepi_pc_defconfig. Also see https://buildroot.org for more 
> information.
>
> +When using an image as an SD card, it must be resized to a power of two. 
> This can be
> +done with the qemu-img command. It is recommended to only increase the image 
> size
> +instead of shrinking it to a power of two, to avoid loss of data. For 
> example,
> +to prepare a downloaded Armbian image, first extract it and then increase
> +its size to one gigabyte as follows:
> +
> +.. code-block:: bash
> +
> +  $ qemu-img resize Armbian_19.11.3_Orangepipc_bionic_current_5.3.9.img 1G
> +
>  You can choose to attach the selected image either as an SD card or as USB 
> mass storage.
>  For example, to boot using the Orange Pi PC Debian image on SD card, simply 
> add the -sd
>  argument and provide the proper root= kernel parameter:
> @@ -213,12 +223,12 @@ Next, unzip the NetBSD image and write the U-Boot 
> binary including SPL using:
>$ dd if=/path/to/u-boot-sunxi-with-spl.bin of=armv7.img bs=1024 seek=8 
> conv=notrunc
>
>  Finally, before starting the machine the SD image must be extended such
> -that the NetBSD kernel will not conclude the NetBSD partition is larger than
> -the emulated SD card:
> +that the size of the SD image is a power of two and that the NetBSD kernel
> +will not conclude the NetBSD partition is larger than the emulated SD card:
>
>  .. code-block:: bash
>
> -  $ dd if=/dev/zero bs=1M count=64 >> armv7.img
> +  $ qemu-img resize armv7.img 2G
>
>  Start the machine using the following command:
>
> --
> 2.21.3
>
>



Re: [PATCH v2 3/9] tests/acceptance/boot_linux: Tag tests using a SD card with 'device:sd'

2020-07-13 Thread Alistair Francis
On Mon, Jul 13, 2020 at 11:34 AM Philippe Mathieu-Daudé  wrote:
>
> Avocado tags are handy to automatically select tests matching
> the tags. Since these tests use a SD card, tag them.
>
> We can run all the tests using a SD card at once with:
>
>   $ avocado --show=app run -t u-boot tests/acceptance/
>   $ AVOCADO_ALLOW_LARGE_STORAGE=ok \
> avocado --show=app \
>   run -t device:sd tests/acceptance/
>   Fetching asset from 
> tests/acceptance/boot_linux_console.py:BootLinuxConsole.test_arm_orangepi_sd
>   Fetching asset from 
> tests/acceptance/boot_linux_console.py:BootLinuxConsole.test_arm_orangepi_bionic
>   Fetching asset from 
> tests/acceptance/boot_linux_console.py:BootLinuxConsole.test_arm_orangepi_uboot_netbsd9
>(1/3) 
> tests/acceptance/boot_linux_console.py:BootLinuxConsole.test_arm_orangepi_sd: 
> PASS (19.56 s)
>(2/3) 
> tests/acceptance/boot_linux_console.py:BootLinuxConsole.test_arm_orangepi_bionic:
>  PASS (49.97 s)
>(3/3) 
> tests/acceptance/boot_linux_console.py:BootLinuxConsole.test_arm_orangepi_uboot_netbsd9:
>  PASS (20.06 s)
>   RESULTS: PASS 3 | ERROR 0 | FAIL 0 | SKIP 0 | WARN 0 | INTERRUPT 0 | 
> CANCEL 0
>   JOB TIME   : 90.02 s
>
> Signed-off-by: Philippe Mathieu-Daudé 

Reviewed-by: Alistair Francis 

Alistair

> ---
>  tests/acceptance/boot_linux_console.py | 3 +++
>  1 file changed, 3 insertions(+)
>
> diff --git a/tests/acceptance/boot_linux_console.py 
> b/tests/acceptance/boot_linux_console.py
> index 3d02519660..b7e8858c2d 100644
> --- a/tests/acceptance/boot_linux_console.py
> +++ b/tests/acceptance/boot_linux_console.py
> @@ -620,6 +620,7 @@ def test_arm_orangepi_sd(self):
>  """
>  :avocado: tags=arch:arm
>  :avocado: tags=machine:orangepi-pc
> +:avocado: tags=device:sd
>  """
>  deb_url = ('https://apt.armbian.com/pool/main/l/'
> 'linux-4.20.7-sunxi/linux-image-dev-sunxi_5.75_armhf.deb')
> @@ -669,6 +670,7 @@ def test_arm_orangepi_bionic(self):
>  """
>  :avocado: tags=arch:arm
>  :avocado: tags=machine:orangepi-pc
> +:avocado: tags=device:sd
>  """
>
>  # This test download a 196MB compressed image and expand it to 
> 932MB...
> @@ -710,6 +712,7 @@ def test_arm_orangepi_uboot_netbsd9(self):
>  """
>  :avocado: tags=arch:arm
>  :avocado: tags=machine:orangepi-pc
> +:avocado: tags=device:sd
>  """
>  # This test download a 304MB compressed image and expand it to 
> 1.3GB...
>  deb_url = ('http://snapshot.debian.org/archive/debian/'
> --
> 2.21.3
>
>



Re: [PATCH 2/2] hw/sd/sdcard: Do not allow invalid SD card sizes

2020-07-09 Thread Alistair Francis
On Thu, Jul 9, 2020 at 7:35 AM Philippe Mathieu-Daudé  wrote:
>
> On 7/9/20 4:15 PM, Peter Maydell wrote:
> > On Thu, 9 Jul 2020 at 14:56, Philippe Mathieu-Daudé  wrote:
> >>
> >> On 7/7/20 10:29 PM, Niek Linnenbank wrote:
> >>> So I manually copy & pasted the change into hw/sd/sd.c to test it.
> >>> It looks like the check works, but my concern is that with this change,
> >>> we will be getting this error on 'off-the-shelf' images as well.
> >>> For example, the latest Raspbian image size also isn't a power of two:
> >>>
> >>> $ ./arm-softmmu/qemu-system-arm -M raspi2 -sd
> >>> ~/Downloads/2020-05-27-raspios-buster-lite-armhf.img -nographic
> >>> WARNING: Image format was not specified for
> >>> '/home/me/Downloads/2020-05-27-raspios-buster-lite-armhf.img' and
> >>> probing guessed raw.
> >>>  Automatically detecting the format is dangerous for raw images,
> >>> write operations on block 0 will be restricted.
> >>>  Specify the 'raw' format explicitly to remove the restrictions.
> >>> qemu-system-arm: Invalid SD card size: 1.73 GiB (expecting at least 2 GiB)
> >>>
> >>> If we do decide that the change is needed, I would like to propose that
> >>> we also give the user some instructions
> >>> on how to fix it, maybe some 'dd' command?
> >>
> >> On POSIX we can suggest to use 'truncate -s 2G' from coreutils.
> >> This is not in the default Darwin packages.
> >> On Windows I have no clue.
> >
> > dd/truncate etc won't work if the image file is not raw (eg if
> > it's qcow2).
>
> Good catch...
>
> > The only chance you have of something that's actually
> > generic would probably involve "qemu-img resize". But I'm a bit
> > wary of having an error message that recommends that, because
> > what if we got it wrong?
>
> I am not sure what to recommend then.
>
> Would that work as hint?
>
>   qemu-system-arm -M raspi2 -sd ./buster-lite-armhf.img
>   qemu-system-arm: Invalid SD card size: 1.73 GiB
>   SD card size has to be a power of 2, e.g. 2GiB.

That sounds good to me. That's enough for a user to figure out the next step.

If you want you could also add: "qemu-img might be able to help." or
something like that.

Alistair



Re: [PATCH 2/2] hw/sd/sdcard: Do not allow invalid SD card sizes

2020-07-07 Thread Alistair Francis
On Tue, Jul 7, 2020 at 6:22 AM Philippe Mathieu-Daudé  wrote:
>
> QEMU allows to create SD card with unrealistic sizes. This could work,
> but some guests (at least Linux) consider sizes that are not a power
> of 2 as a firmware bug and fix the card size to the next power of 2.
>
> Before CVE-2020-13253 fix, this would allow OOB read/write accesses
> past the image size end.
>
> CVE-2020-13253 has been fixed as:
>
> Read command is rejected if BLOCK_LEN_ERROR or ADDRESS_ERROR
> occurred and no data transfer is performed.
>
> Write command is rejected if BLOCK_LEN_ERROR or ADDRESS_ERROR
> occurred and no data transfer is performed.
>
> WP_VIOLATION errors are not modified: the error bit is set, we
> stay in receive-data state, wait for a stop command. All further
> data transfer is ignored. See the check on sd->card_status at the
> beginning of sd_read_data() and sd_write_data().
>
> While this is the correct behavior, in case QEMU create smaller SD
> cards, guests still try to access past the image size end, and QEMU
> considers this is an invalid address, thus "all further data transfer
> is ignored". This is wrong and make the guest looping until
> eventually timeouts.
>
> Fix by not allowing invalid SD card sizes.  Suggesting the expected
> size as a hint:
>
>   $ qemu-system-arm -M orangepi-pc -drive file=rootfs.ext2,if=sd,format=raw
>   qemu-system-arm: Invalid SD card size: 60 MiB (expecting at least 64 MiB)
>
> Signed-off-by: Philippe Mathieu-Daudé 
> ---
>  hw/sd/sd.c | 16 
>  1 file changed, 16 insertions(+)
>
> diff --git a/hw/sd/sd.c b/hw/sd/sd.c
> index cb81487e5c..c45106b78e 100644
> --- a/hw/sd/sd.c
> +++ b/hw/sd/sd.c
> @@ -32,6 +32,7 @@
>
>  #include "qemu/osdep.h"
>  #include "qemu/units.h"
> +#include "qemu/cutils.h"
>  #include "hw/irq.h"
>  #include "hw/registerfields.h"
>  #include "sysemu/block-backend.h"
> @@ -2130,11 +2131,26 @@ static void sd_realize(DeviceState *dev, Error **errp)
>  }
>
>  if (sd->blk) {
> +int64_t blk_size;
> +
>  if (blk_is_read_only(sd->blk)) {
>  error_setg(errp, "Cannot use read-only drive as SD card");
>  return;
>  }
>
> +blk_size = blk_getlength(sd->blk);
> +if (blk_size > 0 && !is_power_of_2(blk_size)) {
> +int64_t blk_size_aligned = pow2ceil(blk_size);
> +char *blk_size_str = size_to_str(blk_size);
> +char *blk_size_aligned_str = size_to_str(blk_size_aligned);
> +
> +error_setg(errp, "Invalid SD card size: %s (expecting at least 
> %s)",
> +   blk_size_str, blk_size_aligned_str);

Should we print that we expect a power of 2? This isn't always obvious
from the message.

Alistair

> +g_free(blk_size_str);
> +g_free(blk_size_aligned_str);
> +return;
> +}
> +
>  ret = blk_set_perm(sd->blk, BLK_PERM_CONSISTENT_READ | 
> BLK_PERM_WRITE,
> BLK_PERM_ALL, errp);
>  if (ret < 0) {
> --
> 2.21.3
>
>



Re: [PATCH 1/2] tests/acceptance/boot_linux: Truncate SD card image to power of 2

2020-07-07 Thread Alistair Francis
n Tue, Jul 7, 2020 at 6:21 AM Philippe Mathieu-Daudé  wrote:
>
> In the next commit we won't allow SD card images with invalid
> size (not aligned to a power of 2). Prepare the tests: add the
> pow2ceil() and image_pow2ceil_truncate() methods and truncate
> the images of the tests using SD cards.
>
> Signed-off-by: Philippe Mathieu-Daudé 
> ---
>  tests/acceptance/boot_linux_console.py | 15 +++
>  1 file changed, 15 insertions(+)
>
> diff --git a/tests/acceptance/boot_linux_console.py 
> b/tests/acceptance/boot_linux_console.py
> index 3d02519660..f4d4e3635f 100644
> --- a/tests/acceptance/boot_linux_console.py
> +++ b/tests/acceptance/boot_linux_console.py
> @@ -28,6 +28,18 @@
>  except CmdNotFoundError:
>  P7ZIP_AVAILABLE = False
>
> +# round up to next power of 2
> +def pow2ceil(x):
> +return 1 if x == 0 else 2**(x - 1).bit_length()
> +
> +# truncate file size to next power of 2
> +def image_pow2ceil_truncate(path):
> +size = os.path.getsize(path)
> +size_aligned = pow2ceil(size)
> +if size != size_aligned:
> +with open(path, 'ab+') as fd:
> +fd.truncate(size_aligned)

Why truncate the image, can't we expand it instead?

Alistair

> +
>  class LinuxKernelTest(Test):
>  KERNEL_COMMON_COMMAND_LINE = 'printk.time=0 '
>
> @@ -635,6 +647,7 @@ def test_arm_orangepi_sd(self):
>  rootfs_path_xz = self.fetch_asset(rootfs_url, asset_hash=rootfs_hash)
>  rootfs_path = os.path.join(self.workdir, 'rootfs.cpio')
>  archive.lzma_uncompress(rootfs_path_xz, rootfs_path)
> +image_pow2ceil_truncate(rootfs_path)
>
>  self.vm.set_console()
>  kernel_command_line = (self.KERNEL_COMMON_COMMAND_LINE +
> @@ -679,6 +692,7 @@ def test_arm_orangepi_bionic(self):
>  image_name = 'Armbian_19.11.3_Orangepipc_bionic_current_5.3.9.img'
>  image_path = os.path.join(self.workdir, image_name)
>  process.run("7z e -o%s %s" % (self.workdir, image_path_7z))
> +image_pow2ceil_truncate(image_path)
>
>  self.vm.set_console()
>  self.vm.add_args('-drive', 'file=' + image_path + 
> ',if=sd,format=raw',
> @@ -728,6 +742,7 @@ def test_arm_orangepi_uboot_netbsd9(self):
>  image_hash = '2babb29d36d8360adcb39c09e31060945259917a'
>  image_path_gz = self.fetch_asset(image_url, asset_hash=image_hash)
>  image_path = os.path.join(self.workdir, 'armv7.img')
> +image_pow2ceil_truncate(image_path)
>  image_drive_args = 'if=sd,format=raw,snapshot=on,file=' + image_path
>  archive.gzip_uncompress(image_path_gz, image_path)
>
> --
> 2.21.3
>
>



Re: [PATCH v7 17/17] hw/sd/sdcard: Simplify realize() a bit

2020-07-06 Thread Alistair Francis
On Tue, Jun 30, 2020 at 6:46 AM Philippe Mathieu-Daudé  wrote:
>
> We don't need to check if sd->blk is set twice.
>
> Reviewed-by: Peter Maydell 
> Signed-off-by: Philippe Mathieu-Daudé 

Reviewed-by: Alistair Francis 

Alistair

> ---
>  hw/sd/sd.c | 10 +-
>  1 file changed, 5 insertions(+), 5 deletions(-)
>
> diff --git a/hw/sd/sd.c b/hw/sd/sd.c
> index 304fa4143a..8ef6715665 100644
> --- a/hw/sd/sd.c
> +++ b/hw/sd/sd.c
> @@ -2154,12 +2154,12 @@ static void sd_realize(DeviceState *dev, Error **errp)
>  return;
>  }
>
> -if (sd->blk && blk_is_read_only(sd->blk)) {
> -error_setg(errp, "Cannot use read-only drive as SD card");
> -return;
> -}
> -
>  if (sd->blk) {
> +if (blk_is_read_only(sd->blk)) {
> +error_setg(errp, "Cannot use read-only drive as SD card");
> +return;
> +}
> +
>  ret = blk_set_perm(sd->blk, BLK_PERM_CONSISTENT_READ | 
> BLK_PERM_WRITE,
> BLK_PERM_ALL, errp);
>  if (ret < 0) {
> --
> 2.21.3
>
>



Re: [PATCH v7 16/17] hw/sd/sdcard: Display offset in read/write_data() trace events

2020-07-06 Thread Alistair Francis
On Tue, Jun 30, 2020 at 6:44 AM Philippe Mathieu-Daudé  wrote:
>
> Having 'base address' and 'relative offset' displayed
> separately is more helpful than the absolute address.
>
> Reviewed-by: Peter Maydell 
> Signed-off-by: Philippe Mathieu-Daudé 

Reviewed-by: Alistair Francis 

Alistair

> ---
>  hw/sd/sd.c | 8 
>  hw/sd/trace-events | 4 ++--
>  2 files changed, 6 insertions(+), 6 deletions(-)
>
> diff --git a/hw/sd/sd.c b/hw/sd/sd.c
> index eb549a52e1..304fa4143a 100644
> --- a/hw/sd/sd.c
> +++ b/hw/sd/sd.c
> @@ -1855,8 +1855,8 @@ void sd_write_data(SDState *sd, uint8_t value)
>  return;
>
>  trace_sdcard_write_data(sd->proto_name,
> -sd_current_cmd_name(sd),
> -sd->current_cmd, value);
> +sd_current_cmd_name(sd), sd->current_cmd,
> +sd->data_start, sd->data_offset, value);
>  switch (sd->current_cmd) {
>  case 24:   /* CMD24:  WRITE_SINGLE_BLOCK */
>  sd->data[sd->data_offset ++] = value;
> @@ -2009,8 +2009,8 @@ uint8_t sd_read_data(SDState *sd)
>  io_len = (sd->ocr & (1 << 30)) ? HWBLOCK_SIZE : sd->blk_len;
>
>  trace_sdcard_read_data(sd->proto_name,
> -   sd_current_cmd_name(sd),
> -   sd->current_cmd, io_len);
> +   sd_current_cmd_name(sd), sd->current_cmd,
> +   sd->data_start, sd->data_offset, io_len);
>  switch (sd->current_cmd) {
>  case 6:/* CMD6:   SWITCH_FUNCTION */
>  ret = sd->data[sd->data_offset ++];
> diff --git a/hw/sd/trace-events b/hw/sd/trace-events
> index d0cd7c6ec4..946923223b 100644
> --- a/hw/sd/trace-events
> +++ b/hw/sd/trace-events
> @@ -51,8 +51,8 @@ sdcard_lock(void) ""
>  sdcard_unlock(void) ""
>  sdcard_read_block(uint64_t addr, uint32_t len) "addr 0x%" PRIx64 " size 0x%x"
>  sdcard_write_block(uint64_t addr, uint32_t len) "addr 0x%" PRIx64 " size 
> 0x%x"
> -sdcard_write_data(const char *proto, const char *cmd_desc, uint8_t cmd, 
> uint8_t value) "%s %20s/ CMD%02d value 0x%02x"
> -sdcard_read_data(const char *proto, const char *cmd_desc, uint8_t cmd, 
> uint32_t length) "%s %20s/ CMD%02d len %" PRIu32
> +sdcard_write_data(const char *proto, const char *cmd_desc, uint8_t cmd, 
> uint64_t address, uint32_t offset, uint8_t value) "%s %20s/ CMD%02d addr 0x%" 
> PRIx64 " ofs 0x%" PRIx32 " val 0x%02x"
> +sdcard_read_data(const char *proto, const char *cmd_desc, uint8_t cmd, 
> uint64_t address, uint32_t offset, uint32_t length) "%s %20s/ CMD%02d addr 
> 0x%" PRIx64 " ofs 0x%" PRIx32 " len %" PRIu32
>  sdcard_set_voltage(uint16_t millivolts) "%u mV"
>
>  # milkymist-memcard.c
> --
> 2.21.3
>
>



Re: [PATCH v3 00/11] hw/sd/sdcard: Fix CVE-2020-13253 & cleanups

2020-07-06 Thread Alistair Francis
On Mon, Jun 8, 2020 at 10:48 AM Philippe Mathieu-Daudé
 wrote:
>
> Hi Alistair,
>
> On 6/5/20 12:22 PM, Philippe Mathieu-Daudé wrote:
> > Patches 2 & 3 fix CVE-2020-13253.
> > The rest are (accumulated) cleanups.
> >
> > Supersedes: <20200604182502.24228-1-f4...@amsat.org>
> >
> > Philippe Mathieu-Daudé (11):
> >   MAINTAINERS: Cc qemu-block mailing list
> >   hw/sd/sdcard: Update coding style to make checkpatch.pl happy
> >   hw/sd/sdcard: Do not switch to ReceivingData if address is invalid
> >   hw/sd/sdcard: Restrict Class 6 commands to SCSD cards
> >   hw/sd/sdcard: Update the SDState documentation
> >   hw/sd/sdcard: Simplify cmd_valid_while_locked()
> >   hw/sd/sdcard: Constify sd_crc*()'s message argument
> >   hw/sd/sdcard: Make iolen unsigned
> >   hw/sd/sdcard: Correctly display the command name in trace events
> >   hw/sd/sdcard: Display offset in read/write_data() trace events
> >   hw/sd/sdcard: Simplify realize() a bit
>
> I forgot to Cc you.
>
> Since you already reviewed a bunch of SD patches in the
> past, do you mind having a look a this series? It should
> be quite trivial.

Hey,

Sorry I took so long but I have reviewed a few. Let me know if there
are anymore you want reviewed.

Alistair

>
> Thanks!
>
> Phil.
>
>



Re: [PATCH v7 14/17] hw/sd/sdcard: Make iolen unsigned

2020-07-06 Thread Alistair Francis
On Tue, Jun 30, 2020 at 6:51 AM Philippe Mathieu-Daudé  wrote:
>
> From: Philippe Mathieu-Daudé 
>
> I/O request length can not be negative.
>
> Signed-off-by: Philippe Mathieu-Daudé 

Reviewed-by: Alistair Francis 

Alistair

> ---
> v4: Use uint32_t (pm215)
> ---
>  hw/sd/sd.c | 2 +-
>  hw/sd/trace-events | 2 +-
>  2 files changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/hw/sd/sd.c b/hw/sd/sd.c
> index 364a6d1fcd..3e9faa8add 100644
> --- a/hw/sd/sd.c
> +++ b/hw/sd/sd.c
> @@ -1981,7 +1981,7 @@ uint8_t sd_read_data(SDState *sd)
>  {
>  /* TODO: Append CRCs */
>  uint8_t ret;
> -int io_len;
> +uint32_t io_len;
>
>  if (!sd->blk || !blk_is_inserted(sd->blk) || !sd->enable)
>  return 0x00;
> diff --git a/hw/sd/trace-events b/hw/sd/trace-events
> index 5f09d32eb2..d0cd7c6ec4 100644
> --- a/hw/sd/trace-events
> +++ b/hw/sd/trace-events
> @@ -52,7 +52,7 @@ sdcard_unlock(void) ""
>  sdcard_read_block(uint64_t addr, uint32_t len) "addr 0x%" PRIx64 " size 0x%x"
>  sdcard_write_block(uint64_t addr, uint32_t len) "addr 0x%" PRIx64 " size 
> 0x%x"
>  sdcard_write_data(const char *proto, const char *cmd_desc, uint8_t cmd, 
> uint8_t value) "%s %20s/ CMD%02d value 0x%02x"
> -sdcard_read_data(const char *proto, const char *cmd_desc, uint8_t cmd, int 
> length) "%s %20s/ CMD%02d len %d"
> +sdcard_read_data(const char *proto, const char *cmd_desc, uint8_t cmd, 
> uint32_t length) "%s %20s/ CMD%02d len %" PRIu32
>  sdcard_set_voltage(uint16_t millivolts) "%u mV"
>
>  # milkymist-memcard.c
> --
> 2.21.3
>
>



Re: [PATCH v7 12/17] hw/sd/sdcard: Simplify cmd_valid_while_locked()

2020-07-06 Thread Alistair Francis
On Tue, Jun 30, 2020 at 6:44 AM Philippe Mathieu-Daudé  wrote:
>
> cmd_valid_while_locked() only needs to read SDRequest->cmd,
> pass it directly and make it const.
>
> Reviewed-by: Peter Maydell 
> Signed-off-by: Philippe Mathieu-Daudé 

Reviewed-by: Alistair Francis 

Alistair

> ---
>  hw/sd/sd.c | 11 +--
>  1 file changed, 5 insertions(+), 6 deletions(-)
>
> diff --git a/hw/sd/sd.c b/hw/sd/sd.c
> index 723e66bbf2..2946fe3040 100644
> --- a/hw/sd/sd.c
> +++ b/hw/sd/sd.c
> @@ -1678,7 +1678,7 @@ static sd_rsp_type_t sd_app_command(SDState *sd,
>  return sd_illegal;
>  }
>
> -static int cmd_valid_while_locked(SDState *sd, SDRequest *req)
> +static int cmd_valid_while_locked(SDState *sd, const uint8_t cmd)
>  {
>  /* Valid commands in locked state:
>   * basic class (0)
> @@ -1689,13 +1689,12 @@ static int cmd_valid_while_locked(SDState *sd, 
> SDRequest *req)
>   * Anything else provokes an "illegal command" response.
>   */
>  if (sd->expecting_acmd) {
> -return req->cmd == 41 || req->cmd == 42;
> +return cmd == 41 || cmd == 42;
>  }
> -if (req->cmd == 16 || req->cmd == 55) {
> +if (cmd == 16 || cmd == 55) {
>  return 1;
>  }
> -return sd_cmd_class[req->cmd] == 0
> -|| sd_cmd_class[req->cmd] == 7;
> +return sd_cmd_class[cmd] == 0 || sd_cmd_class[cmd] == 7;
>  }
>
>  int sd_do_command(SDState *sd, SDRequest *req,
> @@ -1721,7 +1720,7 @@ int sd_do_command(SDState *sd, SDRequest *req,
>  }
>
>  if (sd->card_status & CARD_IS_LOCKED) {
> -if (!cmd_valid_while_locked(sd, req)) {
> +if (!cmd_valid_while_locked(sd, req->cmd)) {
>  sd->card_status |= ILLEGAL_COMMAND;
>  sd->expecting_acmd = false;
>  qemu_log_mask(LOG_GUEST_ERROR, "SD: Card is locked\n");
> --
> 2.21.3
>
>



Re: [PATCH v7 11/17] hw/sd/sdcard: Update the SDState documentation

2020-07-06 Thread Alistair Francis
On Tue, Jun 30, 2020 at 6:45 AM Philippe Mathieu-Daudé  wrote:
>
> Add more descriptive comments to keep a clear separation
> between static property vs runtime changeable.
>
> Suggested-by: Peter Maydell 
> Reviewed-by: Peter Maydell 
> Signed-off-by: Philippe Mathieu-Daudé 

Reviewed-by: Alistair Francis 

Alistair

> ---
>  hw/sd/sd.c | 5 -
>  1 file changed, 4 insertions(+), 1 deletion(-)
>
> diff --git a/hw/sd/sd.c b/hw/sd/sd.c
> index 5d1b314a32..723e66bbf2 100644
> --- a/hw/sd/sd.c
> +++ b/hw/sd/sd.c
> @@ -103,11 +103,14 @@ struct SDState {
>  uint32_t card_status;
>  uint8_t sd_status[64];
>
> -/* Configurable properties */
> +/* Static properties */
> +
>  uint8_t spec_version;
>  BlockBackend *blk;
>  bool spi;
>
> +/* Runtime changeables */
> +
>  uint32_t mode;/* current card mode, one of SDCardModes */
>  int32_t state;/* current card state, one of SDCardStates */
>  uint32_t vhs;
> --
> 2.21.3
>
>



  1   2   3   >