Re: [PATCH v4 1/3] hw/ufs: Initial commit for emulated Universal-Flash-Storage
On Tue, Jul 04, 2023 at 05:33:57PM +0900, Jeuk Kim wrote: > From: Jeuk Kim > > Universal Flash Storage (UFS) is a high-performance mass storage device > with a serial interface. It is primarily used as a high-performance > data storage device for embedded applications. > > This commit contains code for UFS device to be recognized > as a UFS PCI device. > Patches to handle UFS logical unit and Transfer Request will follow. > > Signed-off-by: Jeuk Kim > --- > MAINTAINERS |6 + > docs/specs/pci-ids.rst |2 + > hw/Kconfig |1 + > hw/meson.build |1 + > hw/ufs/Kconfig |4 + > hw/ufs/meson.build |1 + > hw/ufs/trace-events | 33 ++ > hw/ufs/trace.h |1 + > hw/ufs/ufs.c | 304 +++ > hw/ufs/ufs.h | 42 ++ > include/block/ufs.h | 1048 ++ > include/hw/pci/pci.h |1 + > include/hw/pci/pci_ids.h |1 + > meson.build |1 + > 14 files changed, 1446 insertions(+) > create mode 100644 hw/ufs/Kconfig > create mode 100644 hw/ufs/meson.build > create mode 100644 hw/ufs/trace-events > create mode 100644 hw/ufs/trace.h > create mode 100644 hw/ufs/ufs.c > create mode 100644 hw/ufs/ufs.h > create mode 100644 include/block/ufs.h > > diff --git a/MAINTAINERS b/MAINTAINERS > index 4feea49a6e..756aae8623 100644 > --- a/MAINTAINERS > +++ b/MAINTAINERS > @@ -2237,6 +2237,12 @@ F: tests/qtest/nvme-test.c > F: docs/system/devices/nvme.rst > T: git git://git.infradead.org/qemu-nvme.git nvme-next > > +ufs > +M: Jeuk Kim > +S: Supported > +F: hw/ufs/* > +F: include/block/ufs.h > + > megasas > M: Hannes Reinecke > L: qemu-bl...@nongnu.org > diff --git a/docs/specs/pci-ids.rst b/docs/specs/pci-ids.rst > index e302bea484..d6707fa069 100644 > --- a/docs/specs/pci-ids.rst > +++ b/docs/specs/pci-ids.rst > @@ -92,6 +92,8 @@ PCI devices (other than virtio): >PCI PVPanic device (``-device pvpanic-pci``) > 1b36:0012 >PCI ACPI ERST device (``-device acpi-erst``) > +1b36:0013 > + PCI UFS device (``-device ufs``) > > All these devices are documented in :doc:`index`. > > diff --git a/hw/Kconfig b/hw/Kconfig > index ba62ff6417..9ca7b38c31 100644 > --- a/hw/Kconfig > +++ b/hw/Kconfig > @@ -38,6 +38,7 @@ source smbios/Kconfig > source ssi/Kconfig > source timer/Kconfig > source tpm/Kconfig > +source ufs/Kconfig > source usb/Kconfig > source virtio/Kconfig > source vfio/Kconfig > diff --git a/hw/meson.build b/hw/meson.build > index c7ac7d3d75..f01fac4617 100644 > --- a/hw/meson.build > +++ b/hw/meson.build > @@ -37,6 +37,7 @@ subdir('smbios') > subdir('ssi') > subdir('timer') > subdir('tpm') > +subdir('ufs') > subdir('usb') > subdir('vfio') > subdir('virtio') > diff --git a/hw/ufs/Kconfig b/hw/ufs/Kconfig > new file mode 100644 > index 00..b7b3392e85 > --- /dev/null > +++ b/hw/ufs/Kconfig > @@ -0,0 +1,4 @@ > +config UFS_PCI > +bool > +default y if PCI_DEVICES > +depends on PCI > diff --git a/hw/ufs/meson.build b/hw/ufs/meson.build > new file mode 100644 > index 00..eb5164bde9 > --- /dev/null > +++ b/hw/ufs/meson.build > @@ -0,0 +1 @@ > +system_ss.add(when: 'CONFIG_UFS_PCI', if_true: files('ufs.c')) > diff --git a/hw/ufs/trace-events b/hw/ufs/trace-events > new file mode 100644 > index 00..17793929b1 > --- /dev/null > +++ b/hw/ufs/trace-events > @@ -0,0 +1,33 @@ > +# ufs.c > +ufs_irq_raise(void) "INTx" > +ufs_irq_lower(void) "INTx" > +ufs_mmio_read(uint64_t addr, uint64_t data, unsigned size) "addr 0x%"PRIx64" > data 0x%"PRIx64" size %d" > +ufs_mmio_write(uint64_t addr, uint64_t data, unsigned size) "addr > 0x%"PRIx64" data 0x%"PRIx64" size %d" > +ufs_process_db(uint32_t slot) "UTRLDBR slot %"PRIu32"" > +ufs_process_req(uint32_t slot) "UTRLDBR slot %"PRIu32"" > +ufs_complete_req(uint32_t slot) "UTRLDBR slot %"PRIu32"" > +ufs_sendback_req(uint32_t slot) "UTRLDBR slot %"PRIu32"" > +ufs_exec_nop_cmd(uint32_t slot) "UTRLDBR slot %"PRIu32"" > +ufs_exec_scsi_cmd(uint32_t slot, uint8_t lun, uint8_t opcode) "slot > %"PRIu32", lun 0x%"PRIx8", opcode 0x%"PRIx8"" > +ufs_exec_query_cmd(uint32_t slot, uint8_t opcode) "slot %"PRIu32", opcode > 0x%"PRIx8"" > +ufs_process_uiccmd(uint32_t uiccmd, uint32_t ucmdarg1, uint32_t ucmdarg2, > uint32_t ucmdarg3) "uiccmd 0x%"PRIx32", ucmdarg1 0x%"PRIx32", ucmdarg2 > 0x%"PRIx32", ucmdarg3 0x%"PRIx32"" > + > +# error condition > +ufs_err_memory_allocation(void) "failed to allocate memory" > +ufs_err_dma_read_utrd(uint32_t slot, uint64_t addr) "failed to read utrd. > UTRLDBR slot %"PRIu32", UTRD dma addr %"PRIu64"" > +ufs_err_dma_read_req_upiu(uint32_t slot, uint64_t addr) "failed to read req > upiu. UTRLDBR slot %"PRIu32", request upiu addr %"PRIu64"" > +ufs_err_dma_read_prdt(uint32_t slot, uint64_t addr) "failed to read prdt. > UTRLDBR slot %"PRIu32", prdt addr %"PRIu64"" > +ufs_err_dma_write_utrd(uint32_t slot, uint64_t addr) "failed to wr
[PATCH v4 1/3] hw/ufs: Initial commit for emulated Universal-Flash-Storage
From: Jeuk Kim Universal Flash Storage (UFS) is a high-performance mass storage device with a serial interface. It is primarily used as a high-performance data storage device for embedded applications. This commit contains code for UFS device to be recognized as a UFS PCI device. Patches to handle UFS logical unit and Transfer Request will follow. Signed-off-by: Jeuk Kim --- MAINTAINERS |6 + docs/specs/pci-ids.rst |2 + hw/Kconfig |1 + hw/meson.build |1 + hw/ufs/Kconfig |4 + hw/ufs/meson.build |1 + hw/ufs/trace-events | 33 ++ hw/ufs/trace.h |1 + hw/ufs/ufs.c | 304 +++ hw/ufs/ufs.h | 42 ++ include/block/ufs.h | 1048 ++ include/hw/pci/pci.h |1 + include/hw/pci/pci_ids.h |1 + meson.build |1 + 14 files changed, 1446 insertions(+) create mode 100644 hw/ufs/Kconfig create mode 100644 hw/ufs/meson.build create mode 100644 hw/ufs/trace-events create mode 100644 hw/ufs/trace.h create mode 100644 hw/ufs/ufs.c create mode 100644 hw/ufs/ufs.h create mode 100644 include/block/ufs.h diff --git a/MAINTAINERS b/MAINTAINERS index 4feea49a6e..756aae8623 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -2237,6 +2237,12 @@ F: tests/qtest/nvme-test.c F: docs/system/devices/nvme.rst T: git git://git.infradead.org/qemu-nvme.git nvme-next +ufs +M: Jeuk Kim +S: Supported +F: hw/ufs/* +F: include/block/ufs.h + megasas M: Hannes Reinecke L: qemu-bl...@nongnu.org diff --git a/docs/specs/pci-ids.rst b/docs/specs/pci-ids.rst index e302bea484..d6707fa069 100644 --- a/docs/specs/pci-ids.rst +++ b/docs/specs/pci-ids.rst @@ -92,6 +92,8 @@ PCI devices (other than virtio): PCI PVPanic device (``-device pvpanic-pci``) 1b36:0012 PCI ACPI ERST device (``-device acpi-erst``) +1b36:0013 + PCI UFS device (``-device ufs``) All these devices are documented in :doc:`index`. diff --git a/hw/Kconfig b/hw/Kconfig index ba62ff6417..9ca7b38c31 100644 --- a/hw/Kconfig +++ b/hw/Kconfig @@ -38,6 +38,7 @@ source smbios/Kconfig source ssi/Kconfig source timer/Kconfig source tpm/Kconfig +source ufs/Kconfig source usb/Kconfig source virtio/Kconfig source vfio/Kconfig diff --git a/hw/meson.build b/hw/meson.build index c7ac7d3d75..f01fac4617 100644 --- a/hw/meson.build +++ b/hw/meson.build @@ -37,6 +37,7 @@ subdir('smbios') subdir('ssi') subdir('timer') subdir('tpm') +subdir('ufs') subdir('usb') subdir('vfio') subdir('virtio') diff --git a/hw/ufs/Kconfig b/hw/ufs/Kconfig new file mode 100644 index 00..b7b3392e85 --- /dev/null +++ b/hw/ufs/Kconfig @@ -0,0 +1,4 @@ +config UFS_PCI +bool +default y if PCI_DEVICES +depends on PCI diff --git a/hw/ufs/meson.build b/hw/ufs/meson.build new file mode 100644 index 00..eb5164bde9 --- /dev/null +++ b/hw/ufs/meson.build @@ -0,0 +1 @@ +system_ss.add(when: 'CONFIG_UFS_PCI', if_true: files('ufs.c')) diff --git a/hw/ufs/trace-events b/hw/ufs/trace-events new file mode 100644 index 00..17793929b1 --- /dev/null +++ b/hw/ufs/trace-events @@ -0,0 +1,33 @@ +# ufs.c +ufs_irq_raise(void) "INTx" +ufs_irq_lower(void) "INTx" +ufs_mmio_read(uint64_t addr, uint64_t data, unsigned size) "addr 0x%"PRIx64" data 0x%"PRIx64" size %d" +ufs_mmio_write(uint64_t addr, uint64_t data, unsigned size) "addr 0x%"PRIx64" data 0x%"PRIx64" size %d" +ufs_process_db(uint32_t slot) "UTRLDBR slot %"PRIu32"" +ufs_process_req(uint32_t slot) "UTRLDBR slot %"PRIu32"" +ufs_complete_req(uint32_t slot) "UTRLDBR slot %"PRIu32"" +ufs_sendback_req(uint32_t slot) "UTRLDBR slot %"PRIu32"" +ufs_exec_nop_cmd(uint32_t slot) "UTRLDBR slot %"PRIu32"" +ufs_exec_scsi_cmd(uint32_t slot, uint8_t lun, uint8_t opcode) "slot %"PRIu32", lun 0x%"PRIx8", opcode 0x%"PRIx8"" +ufs_exec_query_cmd(uint32_t slot, uint8_t opcode) "slot %"PRIu32", opcode 0x%"PRIx8"" +ufs_process_uiccmd(uint32_t uiccmd, uint32_t ucmdarg1, uint32_t ucmdarg2, uint32_t ucmdarg3) "uiccmd 0x%"PRIx32", ucmdarg1 0x%"PRIx32", ucmdarg2 0x%"PRIx32", ucmdarg3 0x%"PRIx32"" + +# error condition +ufs_err_memory_allocation(void) "failed to allocate memory" +ufs_err_dma_read_utrd(uint32_t slot, uint64_t addr) "failed to read utrd. UTRLDBR slot %"PRIu32", UTRD dma addr %"PRIu64"" +ufs_err_dma_read_req_upiu(uint32_t slot, uint64_t addr) "failed to read req upiu. UTRLDBR slot %"PRIu32", request upiu addr %"PRIu64"" +ufs_err_dma_read_prdt(uint32_t slot, uint64_t addr) "failed to read prdt. UTRLDBR slot %"PRIu32", prdt addr %"PRIu64"" +ufs_err_dma_write_utrd(uint32_t slot, uint64_t addr) "failed to write utrd. UTRLDBR slot %"PRIu32", UTRD dma addr %"PRIu64"" +ufs_err_dma_write_rsp_upiu(uint32_t slot, uint64_t addr) "failed to write rsp upiu. UTRLDBR slot %"PRIu32", response upiu addr %"PRIu64"" +ufs_err_utrl_slot_busy(uint32_t slot) "UTRLDBR slot %"PRIu32" is busy" +ufs_err_unsupport_register_offset(uint32_t offset) "Register offset