[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH v2 24/51] hw/loongarch/virt: Add cfi01 pflash device
From: |
Juan Quintela |
Subject: |
[PATCH v2 24/51] hw/loongarch/virt: Add cfi01 pflash device |
Date: |
Mon, 5 Dec 2022 10:52:01 +0100 |
From: Xiaojuan Yang <yangxiaojuan@loongson.cn>
Add cfi01 pflash device for LoongArch virt machine
Signed-off-by: Xiaojuan Yang <yangxiaojuan@loongson.cn>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Message-Id: <20221130100647.398565-1-yangxiaojuan@loongson.cn>
Signed-off-by: Song Gao <gaosong@loongson.cn>
---
include/hw/loongarch/virt.h | 5 +++
hw/loongarch/acpi-build.c | 18 +++++++++++
hw/loongarch/virt.c | 62 +++++++++++++++++++++++++++++++++++++
hw/loongarch/Kconfig | 1 +
4 files changed, 86 insertions(+)
diff --git a/include/hw/loongarch/virt.h b/include/hw/loongarch/virt.h
index 45c383f5a7..f5f818894e 100644
--- a/include/hw/loongarch/virt.h
+++ b/include/hw/loongarch/virt.h
@@ -12,6 +12,7 @@
#include "hw/boards.h"
#include "qemu/queue.h"
#include "hw/intc/loongarch_ipi.h"
+#include "hw/block/flash.h"
#define LOONGARCH_MAX_VCPUS 4
@@ -20,6 +21,9 @@
#define VIRT_FWCFG_BASE 0x1e020000UL
#define VIRT_BIOS_BASE 0x1c000000UL
#define VIRT_BIOS_SIZE (4 * MiB)
+#define VIRT_FLASH_SECTOR_SIZE (128 * KiB)
+#define VIRT_FLASH_BASE 0x1d000000UL
+#define VIRT_FLASH_SIZE (16 * MiB)
#define VIRT_LOWMEM_BASE 0
#define VIRT_LOWMEM_SIZE 0x10000000
@@ -48,6 +52,7 @@ struct LoongArchMachineState {
int fdt_size;
DeviceState *platform_bus_dev;
PCIBus *pci_bus;
+ PFlashCFI01 *flash;
};
#define TYPE_LOONGARCH_MACHINE MACHINE_TYPE_NAME("virt")
diff --git a/hw/loongarch/acpi-build.c b/hw/loongarch/acpi-build.c
index 7d5f5a757d..c2b237736d 100644
--- a/hw/loongarch/acpi-build.c
+++ b/hw/loongarch/acpi-build.c
@@ -279,6 +279,23 @@ static void build_pci_device_aml(Aml *scope,
LoongArchMachineState *lams)
acpi_dsdt_add_gpex(scope, &cfg);
}
+static void build_flash_aml(Aml *scope, LoongArchMachineState *lams)
+{
+ Aml *dev, *crs;
+
+ hwaddr flash_base = VIRT_FLASH_BASE;
+ hwaddr flash_size = VIRT_FLASH_SIZE;
+
+ dev = aml_device("FLS0");
+ aml_append(dev, aml_name_decl("_HID", aml_string("LNRO0015")));
+ aml_append(dev, aml_name_decl("_UID", aml_int(0)));
+
+ crs = aml_resource_template();
+ aml_append(crs, aml_memory32_fixed(flash_base, flash_size,
AML_READ_WRITE));
+ aml_append(dev, aml_name_decl("_CRS", crs));
+ aml_append(scope, dev);
+}
+
#ifdef CONFIG_TPM
static void acpi_dsdt_add_tpm(Aml *scope, LoongArchMachineState *vms)
{
@@ -328,6 +345,7 @@ build_dsdt(GArray *table_data, BIOSLinker *linker,
MachineState *machine)
build_uart_device_aml(dsdt);
build_pci_device_aml(dsdt, lams);
build_la_ged_aml(dsdt, machine);
+ build_flash_aml(dsdt, lams);
#ifdef CONFIG_TPM
acpi_dsdt_add_tpm(dsdt, lams);
#endif
diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c
index 958be74fa1..c8a495ea30 100644
--- a/hw/loongarch/virt.c
+++ b/hw/loongarch/virt.c
@@ -42,6 +42,63 @@
#include "hw/display/ramfb.h"
#include "hw/mem/pc-dimm.h"
#include "sysemu/tpm.h"
+#include "sysemu/block-backend.h"
+#include "hw/block/flash.h"
+
+static void virt_flash_create(LoongArchMachineState *lams)
+{
+ DeviceState *dev = qdev_new(TYPE_PFLASH_CFI01);
+
+ qdev_prop_set_uint64(dev, "sector-length", VIRT_FLASH_SECTOR_SIZE);
+ qdev_prop_set_uint8(dev, "width", 4);
+ qdev_prop_set_uint8(dev, "device-width", 2);
+ qdev_prop_set_bit(dev, "big-endian", false);
+ qdev_prop_set_uint16(dev, "id0", 0x89);
+ qdev_prop_set_uint16(dev, "id1", 0x18);
+ qdev_prop_set_uint16(dev, "id2", 0x00);
+ qdev_prop_set_uint16(dev, "id3", 0x00);
+ qdev_prop_set_string(dev, "name", "virt.flash");
+ object_property_add_child(OBJECT(lams), "virt.flash", OBJECT(dev));
+ object_property_add_alias(OBJECT(lams), "pflash",
+ OBJECT(dev), "drive");
+
+ lams->flash = PFLASH_CFI01(dev);
+}
+
+static void virt_flash_map(LoongArchMachineState *lams,
+ MemoryRegion *sysmem)
+{
+ PFlashCFI01 *flash = lams->flash;
+ DeviceState *dev = DEVICE(flash);
+ hwaddr base = VIRT_FLASH_BASE;
+ hwaddr size = VIRT_FLASH_SIZE;
+
+ assert(QEMU_IS_ALIGNED(size, VIRT_FLASH_SECTOR_SIZE));
+ assert(size / VIRT_FLASH_SECTOR_SIZE <= UINT32_MAX);
+
+ qdev_prop_set_uint32(dev, "num-blocks", size / VIRT_FLASH_SECTOR_SIZE);
+ sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
+ memory_region_add_subregion(sysmem, base,
+ sysbus_mmio_get_region(SYS_BUS_DEVICE(dev),
0));
+
+}
+
+static void fdt_add_flash_node(LoongArchMachineState *lams)
+{
+ MachineState *ms = MACHINE(lams);
+ char *nodename;
+
+ hwaddr flash_base = VIRT_FLASH_BASE;
+ hwaddr flash_size = VIRT_FLASH_SIZE;
+
+ nodename = g_strdup_printf("/flash@%" PRIx64, flash_base);
+ qemu_fdt_add_subnode(ms->fdt, nodename);
+ qemu_fdt_setprop_string(ms->fdt, nodename, "compatible", "cfi-flash");
+ qemu_fdt_setprop_sized_cells(ms->fdt, nodename, "reg",
+ 2, flash_base, 2, flash_size);
+ qemu_fdt_setprop_cell(ms->fdt, nodename, "bank-width", 4);
+ g_free(nodename);
+}
static void fdt_add_rtc_node(LoongArchMachineState *lams)
{
@@ -596,6 +653,9 @@ static void loongarch_firmware_init(LoongArchMachineState
*lams)
int bios_size;
lams->bios_loaded = false;
+
+ virt_flash_map(lams, get_system_memory());
+
if (filename) {
bios_name = qemu_find_file(QEMU_FILE_TYPE_BIOS, filename);
if (!bios_name) {
@@ -779,6 +839,7 @@ static void loongarch_init(MachineState *machine)
loongarch_direct_kernel_boot(lams);
}
}
+ fdt_add_flash_node(lams);
/* register reset function */
for (i = 0; i < machine->smp.cpus; i++) {
lacpu = LOONGARCH_CPU(qemu_get_cpu(i));
@@ -838,6 +899,7 @@ static void loongarch_machine_initfn(Object *obj)
lams->acpi = ON_OFF_AUTO_AUTO;
lams->oem_id = g_strndup(ACPI_BUILD_APPNAME6, 6);
lams->oem_table_id = g_strndup(ACPI_BUILD_APPNAME8, 8);
+ virt_flash_create(lams);
}
static bool memhp_type_supported(DeviceState *dev)
diff --git a/hw/loongarch/Kconfig b/hw/loongarch/Kconfig
index 17d15b6c90..eb112af990 100644
--- a/hw/loongarch/Kconfig
+++ b/hw/loongarch/Kconfig
@@ -20,3 +20,4 @@ config LOONGARCH_VIRT
select ACPI_HW_REDUCED
select FW_CFG_DMA
select DIMM
+ select PFLASH_CFI01
--
2.38.1
- [PATCH v2 15/51] hw/virtio: generalise CHR_EVENT_CLOSED handling, (continued)
- [PATCH v2 15/51] hw/virtio: generalise CHR_EVENT_CLOSED handling, Juan Quintela, 2022/12/05
- [PATCH v2 14/51] hw/virtio: add started_vu status field to vhost-user-gpio, Juan Quintela, 2022/12/05
- [PATCH v2 16/51] include/hw: VM state takes precedence in virtio_device_should_start, Juan Quintela, 2022/12/05
- [PATCH v2 17/51] hw/nvme: fix aio cancel in format, Juan Quintela, 2022/12/05
- [PATCH v2 18/51] hw/nvme: fix aio cancel in flush, Juan Quintela, 2022/12/05
- [PATCH v2 19/51] hw/nvme: fix aio cancel in zone reset, Juan Quintela, 2022/12/05
- [PATCH v2 20/51] hw/nvme: fix aio cancel in dsm, Juan Quintela, 2022/12/05
- [PATCH v2 21/51] hw/nvme: remove copy bh scheduling, Juan Quintela, 2022/12/05
- [PATCH v2 23/51] target/i386: Always completely initialize TranslateFault, Juan Quintela, 2022/12/05
- [PATCH v2 22/51] target/i386: allow MMX instructions with CR4.OSFXSR=0, Juan Quintela, 2022/12/05
- [PATCH v2 24/51] hw/loongarch/virt: Add cfi01 pflash device,
Juan Quintela <=
- [PATCH v2 25/51] tests/qtest/migration-test: Fix unlink error and memory leaks, Juan Quintela, 2022/12/05
- [PATCH v2 26/51] target/s390x/tcg: Fix and improve the SACF instruction, Juan Quintela, 2022/12/05
- [PATCH v2 27/51] hw/display/next-fb: Fix comment typo, Juan Quintela, 2022/12/05
- [PATCH v2 28/51] multifd: Create page_size fields into both MultiFD{Recv, Send}Params, Juan Quintela, 2022/12/05
- [PATCH v2 29/51] multifd: Create page_count fields into both MultiFD{Recv, Send}Params, Juan Quintela, 2022/12/05
- [PATCH v2 30/51] migration: Export ram_transferred_ram(), Juan Quintela, 2022/12/05
- [PATCH v2 31/51] migration: Export ram_release_page(), Juan Quintela, 2022/12/05
- Re: [PATCH v2 00/51] migration patches for VFIO, Juan Quintela, 2022/12/05
- [PATCH v2 32/51] migration: Take bitmap mutex when completing ram migration, Juan Quintela, 2022/12/05
- [PATCH v2 33/51] migration: Add postcopy_preempt_active(), Juan Quintela, 2022/12/05