mirror of
https://github.com/qemu/qemu.git
synced 2024-11-30 23:33:51 +08:00
hw/loongarch/virt: Add cfi01 pflash device
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>
This commit is contained in:
parent
c4ffd91aba
commit
14dccc8ea6
@ -20,3 +20,4 @@ config LOONGARCH_VIRT
|
|||||||
select ACPI_HW_REDUCED
|
select ACPI_HW_REDUCED
|
||||||
select FW_CFG_DMA
|
select FW_CFG_DMA
|
||||||
select DIMM
|
select DIMM
|
||||||
|
select PFLASH_CFI01
|
||||||
|
@ -279,6 +279,23 @@ static void build_pci_device_aml(Aml *scope, LoongArchMachineState *lams)
|
|||||||
acpi_dsdt_add_gpex(scope, &cfg);
|
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
|
#ifdef CONFIG_TPM
|
||||||
static void acpi_dsdt_add_tpm(Aml *scope, LoongArchMachineState *vms)
|
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_uart_device_aml(dsdt);
|
||||||
build_pci_device_aml(dsdt, lams);
|
build_pci_device_aml(dsdt, lams);
|
||||||
build_la_ged_aml(dsdt, machine);
|
build_la_ged_aml(dsdt, machine);
|
||||||
|
build_flash_aml(dsdt, lams);
|
||||||
#ifdef CONFIG_TPM
|
#ifdef CONFIG_TPM
|
||||||
acpi_dsdt_add_tpm(dsdt, lams);
|
acpi_dsdt_add_tpm(dsdt, lams);
|
||||||
#endif
|
#endif
|
||||||
|
@ -42,6 +42,63 @@
|
|||||||
#include "hw/display/ramfb.h"
|
#include "hw/display/ramfb.h"
|
||||||
#include "hw/mem/pc-dimm.h"
|
#include "hw/mem/pc-dimm.h"
|
||||||
#include "sysemu/tpm.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)
|
static void fdt_add_rtc_node(LoongArchMachineState *lams)
|
||||||
{
|
{
|
||||||
@ -596,6 +653,9 @@ static void loongarch_firmware_init(LoongArchMachineState *lams)
|
|||||||
int bios_size;
|
int bios_size;
|
||||||
|
|
||||||
lams->bios_loaded = false;
|
lams->bios_loaded = false;
|
||||||
|
|
||||||
|
virt_flash_map(lams, get_system_memory());
|
||||||
|
|
||||||
if (filename) {
|
if (filename) {
|
||||||
bios_name = qemu_find_file(QEMU_FILE_TYPE_BIOS, filename);
|
bios_name = qemu_find_file(QEMU_FILE_TYPE_BIOS, filename);
|
||||||
if (!bios_name) {
|
if (!bios_name) {
|
||||||
@ -779,6 +839,7 @@ static void loongarch_init(MachineState *machine)
|
|||||||
loongarch_direct_kernel_boot(lams);
|
loongarch_direct_kernel_boot(lams);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
fdt_add_flash_node(lams);
|
||||||
/* register reset function */
|
/* register reset function */
|
||||||
for (i = 0; i < machine->smp.cpus; i++) {
|
for (i = 0; i < machine->smp.cpus; i++) {
|
||||||
lacpu = LOONGARCH_CPU(qemu_get_cpu(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->acpi = ON_OFF_AUTO_AUTO;
|
||||||
lams->oem_id = g_strndup(ACPI_BUILD_APPNAME6, 6);
|
lams->oem_id = g_strndup(ACPI_BUILD_APPNAME6, 6);
|
||||||
lams->oem_table_id = g_strndup(ACPI_BUILD_APPNAME8, 8);
|
lams->oem_table_id = g_strndup(ACPI_BUILD_APPNAME8, 8);
|
||||||
|
virt_flash_create(lams);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool memhp_type_supported(DeviceState *dev)
|
static bool memhp_type_supported(DeviceState *dev)
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
#include "hw/boards.h"
|
#include "hw/boards.h"
|
||||||
#include "qemu/queue.h"
|
#include "qemu/queue.h"
|
||||||
#include "hw/intc/loongarch_ipi.h"
|
#include "hw/intc/loongarch_ipi.h"
|
||||||
|
#include "hw/block/flash.h"
|
||||||
|
|
||||||
#define LOONGARCH_MAX_VCPUS 4
|
#define LOONGARCH_MAX_VCPUS 4
|
||||||
|
|
||||||
@ -20,6 +21,9 @@
|
|||||||
#define VIRT_FWCFG_BASE 0x1e020000UL
|
#define VIRT_FWCFG_BASE 0x1e020000UL
|
||||||
#define VIRT_BIOS_BASE 0x1c000000UL
|
#define VIRT_BIOS_BASE 0x1c000000UL
|
||||||
#define VIRT_BIOS_SIZE (4 * MiB)
|
#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_BASE 0
|
||||||
#define VIRT_LOWMEM_SIZE 0x10000000
|
#define VIRT_LOWMEM_SIZE 0x10000000
|
||||||
@ -48,6 +52,7 @@ struct LoongArchMachineState {
|
|||||||
int fdt_size;
|
int fdt_size;
|
||||||
DeviceState *platform_bus_dev;
|
DeviceState *platform_bus_dev;
|
||||||
PCIBus *pci_bus;
|
PCIBus *pci_bus;
|
||||||
|
PFlashCFI01 *flash;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define TYPE_LOONGARCH_MACHINE MACHINE_TYPE_NAME("virt")
|
#define TYPE_LOONGARCH_MACHINE MACHINE_TYPE_NAME("virt")
|
||||||
|
Loading…
Reference in New Issue
Block a user