Re: [PULL 02/17] hw/loongarch: Add load initrd
在 2024/4/29 上午2:59, Richard Henderson 写道: On 4/28/24 01:51, Song Gao wrote: we load initrd ramdisk after kernel_high address Signed-off-by: Song Gao Reviewed-by: Bibo Mao Message-Id: <20240426091551.2397867-3-gaos...@loongson.cn> --- hw/loongarch/boot.c | 29 - 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/hw/loongarch/boot.c b/hw/loongarch/boot.c index 9feed17db3..a9522d6912 100644 --- a/hw/loongarch/boot.c +++ b/hw/loongarch/boot.c @@ -22,7 +22,8 @@ static uint64_t cpu_loongarch_virt_to_phys(void *opaque, uint64_t addr) static int64_t load_kernel_info(struct loongarch_boot_info *info) { - uint64_t kernel_entry, kernel_low, kernel_high; + uint64_t kernel_entry, kernel_low, kernel_high, initrd_size; + ram_addr_t initrd_offset; ssize_t kernel_size; kernel_size = load_elf(info->kernel_filename, NULL, @@ -37,6 +38,32 @@ static int64_t load_kernel_info(struct loongarch_boot_info *info) load_elf_strerror(kernel_size)); exit(1); } + + if (info->initrd_filename) { + initrd_size = get_image_size(info->initrd_filename); + if (initrd_size > 0) { + initrd_offset = ROUND_UP(kernel_high + 4 * kernel_size, 64 * KiB); + + if (initrd_offset + initrd_size > info->ram_size) { + error_report("memory too small for initial ram disk '%s'", + info->initrd_filename); + exit(1); + } + + initrd_size = load_image_targphys(info->initrd_filename, initrd_offset, + info->ram_size - initrd_offset); + } + + if (initrd_size == (target_ulong)-1) { + error_report("could not load initial ram disk '%s'", + info->initrd_filename); + exit(1); + } + } else { + error_report("Need initrd!"); + exit(1); + } + return kernel_entry; } This doesn't simply allow initrd, it requires an initrd. This causes make check-tcg to fail: TEST interrupt on loongarch64 qemu-system-loongarch64: Need initrd! https://gitlab.com/qemu-project/qemu/-/jobs/6733983794 I'm sorry I missed this test. I will send v2 fix this problem and the job [1] failed [1] https://gitlab.com/qemu-project/qemu/-/jobs/6733983763 Thanks. Song gao
Re: [PATCH v7 06/17] hw/loongarch: Init efi_boot_memmap table
在 2024/4/28 上午9:34, maobibo 写道: On 2024/4/26 下午5:15, Song Gao wrote: Message test is also missing there :( Signed-off-by: Song Gao Message-Id: <20240307164835.300412-7-gaos...@loongson.cn> --- include/hw/loongarch/boot.h | 27 + include/hw/loongarch/virt.h | 10 ++ hw/loongarch/boot.c | 40 + hw/loongarch/virt.c | 11 ++ 4 files changed, 79 insertions(+), 9 deletions(-) diff --git a/include/hw/loongarch/boot.h b/include/hw/loongarch/boot.h index cf0e4d4f91..76622af2e2 100644 --- a/include/hw/loongarch/boot.h +++ b/include/hw/loongarch/boot.h @@ -21,6 +21,15 @@ typedef struct { uint8_t b[16]; } efi_guid_t QEMU_ALIGNED(8); +#define EFI_GUID(a, b, c, d...) (efi_guid_t){ { \ + (a) & 0xff, ((a) >> 8) & 0xff, ((a) >> 16) & 0xff, ((a) >> 24) & 0xff, \ + (b) & 0xff, ((b) >> 8) & 0xff, \ + (c) & 0xff, ((c) >> 8) & 0xff, d } } + +#define LINUX_EFI_BOOT_MEMMAP_GUID \ + EFI_GUID(0x800f683f, 0xd08b, 0x423a, 0xa2, 0x93, \ + 0x96, 0x5c, 0x3c, 0x6f, 0xe2, 0xb4) + struct efi_config_table { efi_guid_t guid; uint64_t *ptr; @@ -56,6 +65,24 @@ struct efi_system_table { struct efi_configuration_table *tables; }; +typedef struct { + uint32_t type; + uint32_t pad; + uint64_t phys_addr; + uint64_t virt_addr; + uint64_t num_pages; + uint64_t attribute; +} efi_memory_desc_t; + +struct efi_boot_memmap { + uint64_t map_size; + uint64_t desc_size; + uint32_t desc_ver; + uint64_t map_key; + uint64_t buff_size; + efi_memory_desc_t map[32]; +}; + struct loongarch_boot_info { uint64_t ram_size; const char *kernel_filename; diff --git a/include/hw/loongarch/virt.h b/include/hw/loongarch/virt.h index d7a074d69f..8a9fe4053d 100644 --- a/include/hw/loongarch/virt.h +++ b/include/hw/loongarch/virt.h @@ -35,6 +35,16 @@ #define COMMAND_LINE_SIZE 512 +extern struct memmap_entry *memmap_table; +extern unsigned memmap_entries; + +struct memmap_entry { + uint64_t address; + uint64_t length; + uint32_t type; + uint32_t reserved; +}; + struct LoongArchMachineState { /*< private >*/ MachineState parent_obj; diff --git a/hw/loongarch/boot.c b/hw/loongarch/boot.c index 46a241a04c..18aae3434d 100644 --- a/hw/loongarch/boot.c +++ b/hw/loongarch/boot.c @@ -63,8 +63,41 @@ static const unsigned int slave_boot_code[] = { 0x4c20, /* jirl $zero, $ra,0 */ }; +static inline void *guidcpy(void *dst, const void *src) +{ + return memcpy(dst, src, sizeof(efi_guid_t)); +} + +static void init_efi_boot_memmap(struct efi_system_table *systab, + void *p, void *start) +{ + unsigned i; + struct efi_boot_memmap *boot_memmap = p; + efi_guid_t tbl_guid = LINUX_EFI_BOOT_MEMMAP_GUID; + + /* efi_configuration_table 1 */ + guidcpy(>tables[0].guid, _guid); + systab->tables[0].table = (struct efi_configuration_table *)(p - start); + systab->nr_tables = 1; + + boot_memmap->desc_size = sizeof(efi_memory_desc_t); + boot_memmap->desc_ver = 1; + boot_memmap->map_size = 0; + + efi_memory_desc_t *map = p + sizeof(struct efi_boot_memmap); + for (i = 0; i < memmap_entries; i++) { + map = (void *)boot_memmap + sizeof(*map); + map[i].type = memmap_table[i].type; + map[i].phys_addr = ROUND_UP(memmap_table[i].address, 64 * KiB); + map[i].num_pages = ROUND_DOWN(memmap_table[i].address + + memmap_table[i].length - map[i].phys_addr, 64 * KiB); + p += sizeof(efi_memory_desc_t); + } +} Do you verify that memory size of VM is the same with qemu command line setting? I am ok if the test result is the same. Yes. e.g 4G [ 4.061717] Run /sbin/init as init process / # free -h total used free shared buff/cache available Mem: 3.9G 61.3M 3.8G 0 11.4M 3.5G Swap: 0 0 0 Reviewed-by: Bibo Mao + static void init_systab(struct loongarch_boot_info *info, void *p, void *start) { + void *bp_tables_start; struct efi_system_table *systab = p; info->a2 = (uint64_t)p - (uint64_t)start; @@ -80,6 +113,13 @@ static void init_systab(struct loongarch_boot_info *info, void *p, void *start) p += ROUND_UP(sizeof(struct efi_system_table), 64 * KiB); systab->tables = p; + bp_tables_start = p; + + init_efi_boot_memmap(systab, p, start); + p += ROUND_UP(sizeof(struct efi_boot_memmap) + + sizeof(efi_memory_desc_t) * memmap_entries, 64 * KiB); + + systab->tables = (struct efi_configuration_table *)(bp_tables_start - start); } static void init_cmdline(struct loongarch_boot_info *info, void *p, void *start) diff --git a/hw/loongarch/virt.c
Re: [PATCH v7 03/17] hw/loongarch: Add slave cpu boot_code
在 2024/4/28 上午9:15, maobibo 写道: On 2024/4/26 下午5:15, Song Gao wrote: Message text is missing here :( Signed-off-by: Song Gao Message-Id: <20240307164835.300412-4-gaos...@loongson.cn> It is strange that there is "Message-Id:" string. Is it required here? Message_ID helps to find the original email and see more comments. Here we can not add it, but it is required in QEMU PR. Thanks. Song Gao The others look good to me, especially when bootrom for AP is put at BIOS flash area. Regards Bibo Mao --- hw/loongarch/boot.c | 62 - 1 file changed, 61 insertions(+), 1 deletion(-) diff --git a/hw/loongarch/boot.c b/hw/loongarch/boot.c index a9522d6912..d1a8434127 100644 --- a/hw/loongarch/boot.c +++ b/hw/loongarch/boot.c @@ -15,6 +15,54 @@ #include "sysemu/reset.h" #include "sysemu/qtest.h" +static const unsigned int slave_boot_code[] = { + /* Configure reset ebase. */ + 0x0400302c, /* csrwr $t0, LOONGARCH_CSR_EENTRY */ + + /* Disable interrupt. */ + 0x0380100c, /* ori $t0, $zero,0x4 */ + 0x04000180, /* csrxchg $zero, $t0, LOONGARCH_CSR_CRMD */ + + /* Clear mailbox. */ + 0x142d, /* lu12i.w $t1, 1(0x1) */ + 0x038081ad, /* ori $t1, $t1, CORE_BUF_20 */ + 0x06481da0, /* iocsrwr.d $zero, $t1 */ + + /* Enable IPI interrupt. */ + 0x142c, /* lu12i.w $t0, 1(0x1) */ + 0x0400118c, /* csrxchg $t0, $t0, LOONGARCH_CSR_ECFG */ + 0x02fffc0c, /* addi.d $t0, $r0,-1(0xfff) */ + 0x142d, /* lu12i.w $t1, 1(0x1) */ + 0x038011ad, /* ori $t1, $t1, CORE_EN_OFF */ + 0x064819ac, /* iocsrwr.w $t0, $t1 */ + 0x142d, /* lu12i.w $t1, 1(0x1) */ + 0x038081ad, /* ori $t1, $t1, CORE_BUF_20 */ + + /* Wait for wakeup <.L11>: */ + 0x06488000, /* idle 0x0 */ + 0x0340, /* andi $zero, $zero, 0x0 */ + 0x064809ac, /* iocsrrd.w $t0, $t1 */ + 0x43fff59f, /* beqz $t0, -12(0x74) # 48 <.L11> */ + + /* Read and clear IPI interrupt. */ + 0x142d, /* lu12i.w $t1, 1(0x1) */ + 0x064809ac, /* iocsrrd.w $t0, $t1 */ + 0x142d, /* lu12i.w $t1, 1(0x1) */ + 0x038031ad, /* ori $t1, $t1, CORE_CLEAR_OFF */ + 0x064819ac, /* iocsrwr.w $t0, $t1 */ + + /* Disable IPI interrupt. */ + 0x142c, /* lu12i.w $t0, 1(0x1) */ + 0x04001180, /* csrxchg $zero, $t0, LOONGARCH_CSR_ECFG */ + + /* Read mail buf and jump to specified entry */ + 0x142d, /* lu12i.w $t1, 1(0x1) */ + 0x038081ad, /* ori $t1, $t1, CORE_BUF_20 */ + 0x06480dac, /* iocsrrd.d $t0, $t1 */ + 0x00150181, /* move $ra, $t0 */ + 0x4c20, /* jirl $zero, $ra,0 */ +}; + static uint64_t cpu_loongarch_virt_to_phys(void *opaque, uint64_t addr) { return addr & MAKE_64BIT_MASK(0, TARGET_PHYS_ADDR_SPACE_BITS); @@ -126,11 +174,23 @@ static void loongarch_direct_kernel_boot(struct loongarch_boot_info *info) } } + /* Load slave boot code at pflash0 . */ + void *boot_code = g_malloc0(VIRT_FLASH0_SIZE); + memcpy(boot_code, _boot_code, sizeof(slave_boot_code)); + rom_add_blob_fixed("boot_code", boot_code, VIRT_FLASH0_SIZE, VIRT_FLASH0_BASE); + CPU_FOREACH(cs) { lacpu = LOONGARCH_CPU(cs); lacpu->env.load_elf = true; - lacpu->env.elf_address = kernel_addr; + if (cs == first_cpu) { + lacpu->env.elf_address = kernel_addr; + } else { + lacpu->env.elf_address = VIRT_FLASH0_BASE; + } + lacpu->env.boot_info = info; } + + g_free(boot_code); } void loongarch_load_kernel(MachineState *ms, struct loongarch_boot_info *info)
Re: [PULL 1/1] target/loongarch: Fix qemu-system-loongarch64 assert failed with the option '-d int'
Cc: qemu-sta...@nongnu.org 在 2024/3/22 下午10:58, Michael Tokarev 写道: 22.03.2024 13:03, Song Gao : qemu-system-loongarch64 assert failed with the option '-d int', the helper_idle() raise an exception EXCP_HLT, but the exception name is undefined. Signed-off-by: Song Gao Reviewed-by: Philippe Mathieu-Daudé Message-Id: <20240321123606.1704900-1-gaos...@loongson.cn> Is this another qemu-stable material? You Cc'd it to me but I'm not sure what should I do with it. For patches suitable for -stable, please Cc: qemu-sta...@nongnu.org. Thanks, /mjt
Re: [PULL 3/3] target/loongarch: Fix qemu-loongarch64 hang when executing 'll.d $t0, $t0, 0'
在 2024/3/22 上午1:13, Michael Tokarev 写道: 20.03.2024 05:40, Song Gao : On gen_ll, if a->imm is zero, make_address_x return src1, but the load to destination may clobber src1. We use a new destination to fix this problem. Fixes: c5af6628f4be (target/loongarch: Extract make_address_i() helper) Reviewed-by: Richard Henderson Suggested-by: Richard Henderson Signed-off-by: Song Gao Message-Id: <20240320013955.1561311-1-gaos...@loongson.cn> Is it a stable-8.2 material? Yes. Thanks. Song Gao Thanks, /mjt
Re: [PATCH v1] target/loongarch: Fix qemu-system-loongarch64 assert failed with the option '-d int'
在 2024/3/21 上午10:50, Richard Henderson 写道: On 3/20/24 16:11, Song Gao wrote: qemu-system-loongarch64 assert failed with the option '-d int', the helper_idle() raise an exception EXCP_HLT, but the exception name is undefined. Signed-off-by: Song Gao --- target/loongarch/cpu.c | 75 ++ 1 file changed, 46 insertions(+), 29 deletions(-) diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c index f6ffb3aadb..17a923de02 100644 --- a/target/loongarch/cpu.c +++ b/target/loongarch/cpu.c @@ -45,33 +45,46 @@ const char * const fregnames[32] = { "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31", }; -static const char * const excp_names[] = { - [EXCCODE_INT] = "Interrupt", - [EXCCODE_PIL] = "Page invalid exception for load", - [EXCCODE_PIS] = "Page invalid exception for store", - [EXCCODE_PIF] = "Page invalid exception for fetch", - [EXCCODE_PME] = "Page modified exception", - [EXCCODE_PNR] = "Page Not Readable exception", - [EXCCODE_PNX] = "Page Not Executable exception", - [EXCCODE_PPI] = "Page Privilege error", - [EXCCODE_ADEF] = "Address error for instruction fetch", - [EXCCODE_ADEM] = "Address error for Memory access", - [EXCCODE_SYS] = "Syscall", - [EXCCODE_BRK] = "Break", - [EXCCODE_INE] = "Instruction Non-Existent", - [EXCCODE_IPE] = "Instruction privilege error", - [EXCCODE_FPD] = "Floating Point Disabled", - [EXCCODE_FPE] = "Floating Point Exception", - [EXCCODE_DBP] = "Debug breakpoint", - [EXCCODE_BCE] = "Bound Check Exception", - [EXCCODE_SXD] = "128 bit vector instructions Disable exception", - [EXCCODE_ASXD] = "256 bit vector instructions Disable exception", +struct TypeExcp { + int32_t exccode; + const char *name; +}; + +static const struct TypeExcp excp_names[] = { + {EXCCODE_INT, "Interrupt"}, + {EXCCODE_PIL, "Page invalid exception for load"}, + {EXCCODE_PIS, "Page invalid exception for store"}, + {EXCCODE_PIF, "Page invalid exception for fetch"}, + {EXCCODE_PME, "Page modified exception"}, + {EXCCODE_PNR, "Page Not Readable exception"}, + {EXCCODE_PNX, "Page Not Executable exception"}, + {EXCCODE_PPI, "Page Privilege error"}, + {EXCCODE_ADEF, "Address error for instruction fetch"}, + {EXCCODE_ADEM, "Address error for Memory access"}, + {EXCCODE_SYS, "Syscall"}, + {EXCCODE_BRK, "Break"}, + {EXCCODE_INE, "Instruction Non-Existent"}, + {EXCCODE_IPE, "Instruction privilege error"}, + {EXCCODE_FPD, "Floating Point Disabled"}, + {EXCCODE_FPE, "Floating Point Exception"}, + {EXCCODE_DBP, "Debug breakpoint"}, + {EXCCODE_BCE, "Bound Check Exception"}, + {EXCCODE_SXD, "128 bit vector instructions Disable exception"}, + {EXCCODE_ASXD, "256 bit vector instructions Disable exception"}, }; const char *loongarch_exception_name(int32_t exception) { - assert(excp_names[exception]); - return excp_names[exception]; + int i; + const char *name = "unknown"; + + for (i = 0; i < ARRAY_SIZE(excp_names); i++) { + if (excp_names[i].exccode == exception) { + name = excp_names[i].name; + break; + } + } + return name; } I think you should return null for unknown, and then... void G_NORETURN do_raise_exception(CPULoongArchState *env, @@ -79,11 +92,17 @@ void G_NORETURN do_raise_exception(CPULoongArchState *env, uintptr_t pc) { CPUState *cs = env_cpu(env); + const char *name; + if (exception == EXCP_HLT) { + name = "EXCP_HLT"; + } else { + name = loongarch_exception_name(exception); + } qemu_log_mask(CPU_LOG_INT, "%s: %d (%s)\n", __func__, exception, - loongarch_exception_name(exception)); + name); ... use two different printfs, one of which prints the exception number. Why would you special case HLT here instead of putting it in the table? Hmm, put HLT in the table no problem. I will correct it. I considered HLT not a real exception to the LoongAarh architecture, so I didn't put it in the table. Thanks. Song Gao r~
Re: [PATCH] hw/intc/loongarch_extioi: Fix interrupt routing update
在 2024/3/13 下午5:39, Bibo Mao 写道: Interrupt number in loop sentence should be base irq plus loop index, it is missing on checking whether the irq is pending. Fixes: 428a6ef4396 ("Add vmstate post_load support") Signed-off-by: Bibo Mao --- hw/intc/loongarch_extioi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) Reviewed-by: Song Gao Thanks. Song Gao diff --git a/hw/intc/loongarch_extioi.c b/hw/intc/loongarch_extioi.c index bdfa3b481e..0b358548eb 100644 --- a/hw/intc/loongarch_extioi.c +++ b/hw/intc/loongarch_extioi.c @@ -151,7 +151,7 @@ static inline void extioi_update_sw_coremap(LoongArchExtIOI *s, int irq, continue; } -if (notify && test_bit(irq, (unsigned long *)s->isr)) { +if (notify && test_bit(irq + i, (unsigned long *)s->isr)) { /* * lower irq at old cpu and raise irq at new cpu */
Re: [PATCH v6 03/17] hw/loongarch: Add slave cpu boot_code
在 2024/3/14 10:28, chen huacai 写道: Song, On Fri, Mar 8, 2024 at 12:51 AM Song Gao wrote: Signed-off-by: Song Gao Message-Id: <20240301093839.663947-4-gaos...@loongson.cn> --- hw/loongarch/boot.c | 70 - 1 file changed, 69 insertions(+), 1 deletion(-) diff --git a/hw/loongarch/boot.c b/hw/loongarch/boot.c index 149deb2e01..e560ac178a 100644 --- a/hw/loongarch/boot.c +++ b/hw/loongarch/boot.c @@ -15,6 +15,54 @@ #include "sysemu/reset.h" #include "sysemu/qtest.h" +static const unsigned int slave_boot_code[] = { + /* Configure reset ebase. */ +0x0400302c, /* csrwr $r12,0xc*/ Use reg-names may be a little better than reg-nums. Got it. Thanks. Song Gao Huacai + + /* Disable interrupt. */ +0x0380100c, /* ori$r12,$r0,0x4*/ +0x04000180, /* csrxchg$r0,$r12,0x0*/ + + /* Clear mailbox. */ +0x142d, /* lu12i.w$r13,1(0x1) */ +0x038081ad, /* ori$r13,$r13,0x20 */ +0x06481da0, /* iocsrwr.d $r0,$r13*/ + + /* Enable IPI interrupt. */ +0x142c, /* lu12i.w$r12,1(0x1) */ +0x0400118c, /* csrxchg$r12,$r12,0x4 */ +0x02fffc0c, /* addi.d $r12,$r0,-1(0xfff) */ +0x142d, /* lu12i.w$r13,1(0x1) */ +0x038011ad, /* ori$r13,$r13,0x4 */ +0x064819ac, /* iocsrwr.w $r12,$r13 */ +0x142d, /* lu12i.w$r13,1(0x1) */ +0x038081ad, /* ori$r13,$r13,0x20 */ + + /* Wait for wakeup <.L11>: */ +0x06488000, /* idle 0x0 */ +0x0340, /* andi $r0,$r0,0x0 */ +0x064809ac, /* iocsrrd.w $r12,$r13 */ +0x43fff59f, /* beqz $r12,-12(0x74) # 48 <.L11> */ + + /* Read and clear IPI interrupt. */ +0x142d, /* lu12i.w$r13,1(0x1) */ +0x064809ac, /* iocsrrd.w $r12,$r13 */ +0x142d, /* lu12i.w$r13,1(0x1) */ +0x038031ad, /* ori$r13,$r13,0xc */ +0x064819ac, /* iocsrwr.w $r12,$r13 */ + + /* Disable IPI interrupt.*/ +0x142c, /* lu12i.w$r12,1(0x1) */ +0x04001180, /* csrxchg$r0,$r12,0x4*/ + + /* Read mail buf and jump to specified entry */ +0x142d, /* lu12i.w$r13,1(0x1) */ +0x038081ad, /* ori$r13,$r13,0x20 */ +0x06480dac, /* iocsrrd.d $r12,$r13 */ +0x00150181, /* move $r1,$r12*/ +0x4c20, /* jirl $r0,$r1,0 */ +}; + static uint64_t cpu_loongarch_virt_to_phys(void *opaque, uint64_t addr) { return addr & MAKE_64BIT_MASK(0, TARGET_PHYS_ADDR_SPACE_BITS); @@ -111,8 +159,15 @@ static void loongarch_firmware_boot(LoongArchMachineState *lams, fw_cfg_add_kernel_info(info, lams->fw_cfg); } +static void init_boot_rom(struct loongarch_boot_info *info, void *p) +{ +memcpy(p, _boot_code, sizeof(slave_boot_code)); +p += sizeof(slave_boot_code); +} + static void loongarch_direct_kernel_boot(struct loongarch_boot_info *info) { +void *p, *bp; int64_t kernel_addr = 0; LoongArchCPU *lacpu; CPUState *cs; @@ -126,11 +181,24 @@ static void loongarch_direct_kernel_boot(struct loongarch_boot_info *info) } } +/* Load 'boot_rom' at [0 - 1MiB] */ +p = g_malloc0(1 * MiB); +bp = p; +init_boot_rom(info, p); +rom_add_blob_fixed("boot_rom", bp, 1 * MiB, 0); + CPU_FOREACH(cs) { lacpu = LOONGARCH_CPU(cs); lacpu->env.load_elf = true; -lacpu->env.elf_address = kernel_addr; +if (cs == first_cpu) { +lacpu->env.elf_address = kernel_addr; +} else { +lacpu->env.elf_address = 0; +} +lacpu->env.boot_info = info; } + +g_free(bp); } void loongarch_load_kernel(MachineState *ms, struct loongarch_boot_info *info) -- 2.34.1
Re: [PATCH v6 03/17] hw/loongarch: Add slave cpu boot_code
在 2024/3/14 9:31, maobibo 写道: On 2024/3/11 下午2:50, maobibo wrote: On 2024/3/8 下午5:36, gaosong wrote: 在 2024/3/8 16:27, maobibo 写道: On 2024/3/8 上午12:48, Song Gao wrote: Signed-off-by: Song Gao Message-Id: <20240301093839.663947-4-gaos...@loongson.cn> --- hw/loongarch/boot.c | 70 - 1 file changed, 69 insertions(+), 1 deletion(-) diff --git a/hw/loongarch/boot.c b/hw/loongarch/boot.c index 149deb2e01..e560ac178a 100644 --- a/hw/loongarch/boot.c +++ b/hw/loongarch/boot.c @@ -15,6 +15,54 @@ #include "sysemu/reset.h" #include "sysemu/qtest.h" +static const unsigned int slave_boot_code[] = { + /* Configure reset ebase. */ + 0x0400302c, /* csrwr $r12,0xc */ + + /* Disable interrupt. */ + 0x0380100c, /* ori $r12,$r0,0x4 */ + 0x04000180, /* csrxchg $r0,$r12,0x0 */ + + /* Clear mailbox. */ + 0x142d, /* lu12i.w $r13,1(0x1) */ + 0x038081ad, /* ori $r13,$r13,0x20 */ + 0x06481da0, /* iocsrwr.d $r0,$r13 */ + + /* Enable IPI interrupt. */ + 0x142c, /* lu12i.w $r12,1(0x1) */ + 0x0400118c, /* csrxchg $r12,$r12,0x4 */ + 0x02fffc0c, /* addi.d $r12,$r0,-1(0xfff) */ + 0x142d, /* lu12i.w $r13,1(0x1) */ + 0x038011ad, /* ori $r13,$r13,0x4 */ + 0x064819ac, /* iocsrwr.w $r12,$r13 */ + 0x142d, /* lu12i.w $r13,1(0x1) */ + 0x038081ad, /* ori $r13,$r13,0x20 */ + + /* Wait for wakeup <.L11>: */ + 0x06488000, /* idle 0x0 */ + 0x0340, /* andi $r0,$r0,0x0 */ + 0x064809ac, /* iocsrrd.w $r12,$r13 */ + 0x43fff59f, /* beqz $r12,-12(0x74) # 48 <.L11> */ + + /* Read and clear IPI interrupt. */ + 0x142d, /* lu12i.w $r13,1(0x1) */ + 0x064809ac, /* iocsrrd.w $r12,$r13 */ + 0x142d, /* lu12i.w $r13,1(0x1) */ + 0x038031ad, /* ori $r13,$r13,0xc */ + 0x064819ac, /* iocsrwr.w $r12,$r13 */ + + /* Disable IPI interrupt. */ + 0x142c, /* lu12i.w $r12,1(0x1) */ + 0x04001180, /* csrxchg $r0,$r12,0x4 */ + + /* Read mail buf and jump to specified entry */ + 0x142d, /* lu12i.w $r13,1(0x1) */ + 0x038081ad, /* ori $r13,$r13,0x20 */ + 0x06480dac, /* iocsrrd.d $r12,$r13 */ + 0x00150181, /* move $r1,$r12 */ + 0x4c20, /* jirl $r0,$r1,0 */ +}; + static uint64_t cpu_loongarch_virt_to_phys(void *opaque, uint64_t addr) { return addr & MAKE_64BIT_MASK(0, TARGET_PHYS_ADDR_SPACE_BITS); @@ -111,8 +159,15 @@ static void loongarch_firmware_boot(LoongArchMachineState *lams, fw_cfg_add_kernel_info(info, lams->fw_cfg); } +static void init_boot_rom(struct loongarch_boot_info *info, void *p) +{ + memcpy(p, _boot_code, sizeof(slave_boot_code)); + p += sizeof(slave_boot_code); +} + static void loongarch_direct_kernel_boot(struct loongarch_boot_info *info) { + void *p, *bp; int64_t kernel_addr = 0; LoongArchCPU *lacpu; CPUState *cs; @@ -126,11 +181,24 @@ static void loongarch_direct_kernel_boot(struct loongarch_boot_info *info) } } + /* Load 'boot_rom' at [0 - 1MiB] */ + p = g_malloc0(1 * MiB); + bp = p; + init_boot_rom(info, p); + rom_add_blob_fixed("boot_rom", bp, 1 * MiB, 0); + The secondary cpu waiting on the bootrom located memory address 0x0-0x10. Is it possible that primary cpu clears the memory located at bootrom and then wakeup the secondary cpu? I think it impossible,0-1M is ROM。 I am not sure whether it is ok if area between 0-1M is ROM. For the memory map table, low memory area (0 - 256M) is still ddr ram. And it is passed to kernel with fdt system table, rather than area(1-256M). Is that right? There are some lines like this: /* Node0 memory */ memmap_add_entry(VIRT_LOWMEM_BASE, VIRT_LOWMEM_SIZE, 1); Song, Can the base memory address of bootrom for secondary cpus be set as base address of flash like bios, such as VIRT_FLASH0_BASE/VIRT_FLASH1_BASE? > And ddr memory map area is kept unchanged. Good suggestions, I wil do this on v7. Thanks. Song Gao Regards Bibo Mao Regards Bibo Mao Thanks. Song Gao Regards Bibo Mao CPU_FOREACH(cs) { lacpu = LOONGARCH_CPU(cs); lacpu->env.load_elf = true; - lacpu->env.elf_address = kernel_addr; + if (cs == first_cpu) { + lacpu->env.elf_address = kernel_addr; + } else { + l
Re: [PATCH v6 06/17] hw/loongarch: Init efi_boot_memmap table
在 2024/3/8 16:37, maobibo 写道: On 2024/3/8 上午12:48, Song Gao wrote: Signed-off-by: Song Gao Message-Id: <20240301093839.663947-7-gaos...@loongson.cn> --- hw/loongarch/boot.c | 39 + hw/loongarch/virt.c | 11 ++- include/hw/loongarch/boot.h | 27 + include/hw/loongarch/virt.h | 10 ++ 4 files changed, 78 insertions(+), 9 deletions(-) diff --git a/hw/loongarch/boot.c b/hw/loongarch/boot.c index 1e31e2a59f..2896c1ea40 100644 --- a/hw/loongarch/boot.c +++ b/hw/loongarch/boot.c @@ -63,8 +63,40 @@ static const unsigned int slave_boot_code[] = { 0x4c20, /* jirl $r0,$r1,0 */ }; +static inline void *guidcpy(void *dst, const void *src) +{ + return memcpy(dst, src, sizeof(efi_guid_t)); +} + +static void init_efi_boot_memmap(struct efi_system_table *systab, + void *p, void *start) +{ + unsigned i; + struct efi_boot_memmap *boot_memmap = p; + efi_guid_t tbl_guid = LINUX_EFI_BOOT_MEMMAP_GUID; + + /* efi_configuration_table 1 */ + guidcpy(>tables[0].guid, _guid); + systab->tables[0].table = (struct efi_configuration_table *)(p - start); + systab->nr_tables = 1; + + boot_memmap->desc_size = sizeof(efi_memory_desc_t); + boot_memmap->desc_ver = 1; + boot_memmap->map_size = 0; + + efi_memory_desc_t *map = p + sizeof(struct efi_boot_memmap); + for (i = 0; i < memmap_entries; i++) { + map = (void *)boot_memmap + sizeof(*map); + map[i].type = memmap_table[i].type; + map[i].phys_addr = memmap_table[i].address; + map[i].num_pages = memmap_table[i].length >> 16; /* 64KB align*/ 64KB aligned or 64KB page size? In generic page size is 4K by EFI spec IIRC. Thank you for pointing it out., I will correct it on v7. Regards Bibo Mao + p += sizeof(efi_memory_desc_t); + } +} + static void init_systab(struct loongarch_boot_info *info, void *p, void *start) { + void *bp_tables_start; struct efi_system_table *systab = p; info->a2 = (uint64_t)p - (uint64_t)start; @@ -80,6 +112,13 @@ static void init_systab(struct loongarch_boot_info *info, void *p, void *start) p += ROUND_UP(sizeof(struct efi_system_table), 64); systab->tables = p; + bp_tables_start = p; + + init_efi_boot_memmap(systab, p, start); + p += ROUND_UP(sizeof(struct efi_boot_memmap) + + sizeof(efi_memory_desc_t) * memmap_entries, 64); + + systab->tables = (struct efi_configuration_table *)(bp_tables_start - start); } static void init_cmdline(struct loongarch_boot_info *info, void *p, void *start) diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c index bbd5cc1d4d..8981b57b12 100644 --- a/hw/loongarch/virt.c +++ b/hw/loongarch/virt.c @@ -377,15 +377,8 @@ static void virt_powerdown_req(Notifier *notifier, void *opaque) acpi_send_event(s->acpi_ged, ACPI_POWER_DOWN_STATUS); } -struct memmap_entry { - uint64_t address; - uint64_t length; - uint32_t type; - uint32_t reserved; -}; - -static struct memmap_entry *memmap_table; -static unsigned memmap_entries; +struct memmap_entry *memmap_table; +unsigned memmap_entries; static void memmap_add_entry(uint64_t address, uint64_t length, uint32_t type) { diff --git a/include/hw/loongarch/boot.h b/include/hw/loongarch/boot.h index 65ad406f02..f71c693f43 100644 --- a/include/hw/loongarch/boot.h +++ b/include/hw/loongarch/boot.h @@ -21,6 +21,15 @@ typedef struct { uint8_t b[16]; } efi_guid_t __attribute__((aligned(8))); +#define EFI_GUID(a, b, c, d...) (efi_guid_t){ { \ + (a) & 0xff, ((a) >> 8) & 0xff, ((a) >> 16) & 0xff, ((a) >> 24) & 0xff, \ + (b) & 0xff, ((b) >> 8) & 0xff, \ + (c) & 0xff, ((c) >> 8) & 0xff, d } } + +#define LINUX_EFI_BOOT_MEMMAP_GUID \ + EFI_GUID(0x800f683f, 0xd08b, 0x423a, 0xa2, 0x93, \ + 0x96, 0x5c, 0x3c, 0x6f, 0xe2, 0xb4) + struct efi_config_table { efi_guid_t guid; uint64_t *ptr; @@ -56,6 +65,24 @@ struct efi_system_table { struct efi_configuration_table *tables; }; +typedef struct { + uint32_t type; + uint32_t pad; + uint64_t phys_addr; + uint64_t virt_addr; + uint64_t num_pages; + uint64_t attribute; +} efi_memory_desc_t; + +struct efi_boot_memmap { + uint64_t map_size; + uint64_t desc_size; + uint32_t desc_ver; + uint64_t map_key; + uint64_t buff_size; + efi_memory_desc_t map[32]; +}; + struct loongarch_boot_info { uint64_t ram_size; const char *kernel_filename; diff --git a/include/hw/loongarch/virt.h b/include/hw/loongarch/virt.h index d7a074d69f..8a9fe4053d 100644 --- a/include/hw/loongarch/virt.h +++ b/include/hw/loongarch/virt.h @@ -35,6 +35,16 @@ #define COMMAND_LINE_SIZE 512 +extern struct memmap_entry *memmap_table; +extern unsigned memmap_entries; +
Re: [PATCH v6 03/17] hw/loongarch: Add slave cpu boot_code
在 2024/3/8 16:27, maobibo 写道: On 2024/3/8 上午12:48, Song Gao wrote: Signed-off-by: Song Gao Message-Id: <20240301093839.663947-4-gaos...@loongson.cn> --- hw/loongarch/boot.c | 70 - 1 file changed, 69 insertions(+), 1 deletion(-) diff --git a/hw/loongarch/boot.c b/hw/loongarch/boot.c index 149deb2e01..e560ac178a 100644 --- a/hw/loongarch/boot.c +++ b/hw/loongarch/boot.c @@ -15,6 +15,54 @@ #include "sysemu/reset.h" #include "sysemu/qtest.h" +static const unsigned int slave_boot_code[] = { + /* Configure reset ebase. */ + 0x0400302c, /* csrwr $r12,0xc */ + + /* Disable interrupt. */ + 0x0380100c, /* ori $r12,$r0,0x4 */ + 0x04000180, /* csrxchg $r0,$r12,0x0 */ + + /* Clear mailbox. */ + 0x142d, /* lu12i.w $r13,1(0x1) */ + 0x038081ad, /* ori $r13,$r13,0x20 */ + 0x06481da0, /* iocsrwr.d $r0,$r13 */ + + /* Enable IPI interrupt. */ + 0x142c, /* lu12i.w $r12,1(0x1) */ + 0x0400118c, /* csrxchg $r12,$r12,0x4 */ + 0x02fffc0c, /* addi.d $r12,$r0,-1(0xfff) */ + 0x142d, /* lu12i.w $r13,1(0x1) */ + 0x038011ad, /* ori $r13,$r13,0x4 */ + 0x064819ac, /* iocsrwr.w $r12,$r13 */ + 0x142d, /* lu12i.w $r13,1(0x1) */ + 0x038081ad, /* ori $r13,$r13,0x20 */ + + /* Wait for wakeup <.L11>: */ + 0x06488000, /* idle 0x0 */ + 0x0340, /* andi $r0,$r0,0x0 */ + 0x064809ac, /* iocsrrd.w $r12,$r13 */ + 0x43fff59f, /* beqz $r12,-12(0x74) # 48 <.L11> */ + + /* Read and clear IPI interrupt. */ + 0x142d, /* lu12i.w $r13,1(0x1) */ + 0x064809ac, /* iocsrrd.w $r12,$r13 */ + 0x142d, /* lu12i.w $r13,1(0x1) */ + 0x038031ad, /* ori $r13,$r13,0xc */ + 0x064819ac, /* iocsrwr.w $r12,$r13 */ + + /* Disable IPI interrupt. */ + 0x142c, /* lu12i.w $r12,1(0x1) */ + 0x04001180, /* csrxchg $r0,$r12,0x4 */ + + /* Read mail buf and jump to specified entry */ + 0x142d, /* lu12i.w $r13,1(0x1) */ + 0x038081ad, /* ori $r13,$r13,0x20 */ + 0x06480dac, /* iocsrrd.d $r12,$r13 */ + 0x00150181, /* move $r1,$r12 */ + 0x4c20, /* jirl $r0,$r1,0 */ +}; + static uint64_t cpu_loongarch_virt_to_phys(void *opaque, uint64_t addr) { return addr & MAKE_64BIT_MASK(0, TARGET_PHYS_ADDR_SPACE_BITS); @@ -111,8 +159,15 @@ static void loongarch_firmware_boot(LoongArchMachineState *lams, fw_cfg_add_kernel_info(info, lams->fw_cfg); } +static void init_boot_rom(struct loongarch_boot_info *info, void *p) +{ + memcpy(p, _boot_code, sizeof(slave_boot_code)); + p += sizeof(slave_boot_code); +} + static void loongarch_direct_kernel_boot(struct loongarch_boot_info *info) { + void *p, *bp; int64_t kernel_addr = 0; LoongArchCPU *lacpu; CPUState *cs; @@ -126,11 +181,24 @@ static void loongarch_direct_kernel_boot(struct loongarch_boot_info *info) } } + /* Load 'boot_rom' at [0 - 1MiB] */ + p = g_malloc0(1 * MiB); + bp = p; + init_boot_rom(info, p); + rom_add_blob_fixed("boot_rom", bp, 1 * MiB, 0); + The secondary cpu waiting on the bootrom located memory address 0x0-0x10. Is it possible that primary cpu clears the memory located at bootrom and then wakeup the secondary cpu? I think it impossible,0-1M is ROM。 Thanks. Song Gao Regards Bibo Mao CPU_FOREACH(cs) { lacpu = LOONGARCH_CPU(cs); lacpu->env.load_elf = true; - lacpu->env.elf_address = kernel_addr; + if (cs == first_cpu) { + lacpu->env.elf_address = kernel_addr; + } else { + lacpu->env.elf_address = 0; + } + lacpu->env.boot_info = info; } + + g_free(bp); } void loongarch_load_kernel(MachineState *ms, struct loongarch_boot_info *info)
Re: [PATCH v6 07/17] hw/loongarch: Init efi_initrd table
在 2024/3/8 16:36, Philippe Mathieu-Daudé 写道: Hi Song, On 7/3/24 17:48, Song Gao wrote: Signed-off-by: Song Gao Message-Id: <20240301093839.663947-8-gaos...@loongson.cn> --- hw/loongarch/boot.c | 23 +-- include/hw/loongarch/boot.h | 9 + 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/hw/loongarch/boot.c b/hw/loongarch/boot.c index 2896c1ea40..6126a37858 100644 --- a/hw/loongarch/boot.c +++ b/hw/loongarch/boot.c @@ -15,6 +15,9 @@ #include "sysemu/reset.h" #include "sysemu/qtest.h" +ram_addr_t initrd_offset; +uint64_t initrd_size; Where is that used? patch1 load_kernel_info() and patch7 init_efi_initrd_table() Thanks. Song Gao static const unsigned int slave_boot_code[] = { /* Configure reset ebase. */ 0x0400302c, /* csrwr $r12,0xc */ @@ -94,6 +97,21 @@ static void init_efi_boot_memmap(struct efi_system_table *systab, } } +static void init_efi_initrd_table(struct efi_system_table *systab, + void *p, void *start) +{ + efi_guid_t tbl_guid = LINUX_EFI_INITRD_MEDIA_GUID; + struct efi_initrd *initrd_table = p; + + /* efi_configuration_table 2 */ + guidcpy(>tables[1].guid, _guid); + systab->tables[1].table = (struct efi_configuration_table *)(p - start); + systab->nr_tables = 2; + + initrd_table->base = initrd_offset; + initrd_table->size = initrd_size; +} + static void init_systab(struct loongarch_boot_info *info, void *p, void *start) { void *bp_tables_start; @@ -117,6 +135,8 @@ static void init_systab(struct loongarch_boot_info *info, void *p, void *start) init_efi_boot_memmap(systab, p, start); p += ROUND_UP(sizeof(struct efi_boot_memmap) + sizeof(efi_memory_desc_t) * memmap_entries, 64); + init_efi_initrd_table(systab, p, start); + p += ROUND_UP(sizeof(struct efi_initrd), 64); systab->tables = (struct efi_configuration_table *)(bp_tables_start - start); } @@ -138,8 +158,7 @@ static uint64_t cpu_loongarch_virt_to_phys(void *opaque, uint64_t addr) static int64_t load_kernel_info(struct loongarch_boot_info *info) { - uint64_t kernel_entry, kernel_low, kernel_high, initrd_size; - ram_addr_t initrd_offset; + uint64_t kernel_entry, kernel_low, kernel_high; ssize_t kernel_size; kernel_size = load_elf(info->kernel_filename, NULL, diff --git a/include/hw/loongarch/boot.h b/include/hw/loongarch/boot.h index f71c693f43..ddcb279874 100644 --- a/include/hw/loongarch/boot.h +++ b/include/hw/loongarch/boot.h @@ -30,6 +30,10 @@ typedef struct { EFI_GUID(0x800f683f, 0xd08b, 0x423a, 0xa2, 0x93, \ 0x96, 0x5c, 0x3c, 0x6f, 0xe2, 0xb4) +#define LINUX_EFI_INITRD_MEDIA_GUID \ + EFI_GUID(0x5568e427, 0x68fc, 0x4f3d, 0xac, 0x74, \ + 0xca, 0x55, 0x52, 0x31, 0xcc, 0x68) + struct efi_config_table { efi_guid_t guid; uint64_t *ptr; @@ -83,6 +87,11 @@ struct efi_boot_memmap { efi_memory_desc_t map[32]; }; +struct efi_initrd { + uint64_t base; + uint64_t size; +}; + struct loongarch_boot_info { uint64_t ram_size; const char *kernel_filename;
Re: [PULL v2 00/17] loongarch-to-apply queue
在 2024/3/7 23:37, Peter Maydell 写道: On Thu, 7 Mar 2024 at 15:28, Song Gao wrote: The following changes since commit 8f6330a807f2642dc2a3cdf33347aa28a4c00a87: Merge tag 'pull-maintainer-updates-060324-1' of https://gitlab.com/stsquad/qemu into staging (2024-03-06 16:56:20 +) are available in the Git repository at: https://gitlab.com/gaosong/qemu.git tags/pull-loongarch-20240307 for you to fetch changes up to 4dc2edfd6f8abfc38f0ba110502790aa5051b1b5: hw/loongarch: Add cells missing from rtc node (2024-03-07 21:58:00 +0800) pull-loongarch-20240307 Song Gao (17): hw/loongarch: Move boot fucntions to boot.c hw/loongarch: Add load initrd hw/loongarch: Add slave cpu boot_code hw/loongarch: Add init_cmdline hw/loongarch: Init efi_system_table hw/loongarch: Init efi_boot_memmap table hw/loongarch: Init efi_initrd table hw/loongarch: Init efi_fdt table hw/loongarch: Fix fdt memory node wrong 'reg' hw/loongarch: fdt adds cpu interrupt controller node hw/loongarch: fdt adds Extend I/O Interrupt Controller hw/loongarch: fdt adds pch_pic Controller hw/loongarch: fdt adds pch_msi Controller hw/loongarch: fdt adds pcie irq_map node hw/loongarch: fdt remove unused irqchip node hw/loongarch: Add cells missing from uart node hw/loongarch: Add cells missing from rtc node Looks like our emails crossed, but see my remarks on v1 about test/compilation failures. Ah, I'll fix these issues. Also I have just noticed that none of these patches have Reviewed-by: tags. Please make sure patches are code reviewed before submitting them in pull requests. OK. and BiBo, Could you help review the v6 series? Thanks. Song Gao thanks -- PMM
Re: [PULL 00/17] loongarch-to-apply queue
Hi, Missing patch16.,17, please see v2 version Thanks. Song Gao 在 2024/3/7 22:51, Song Gao 写道: The following changes since commit 8f6330a807f2642dc2a3cdf33347aa28a4c00a87: Merge tag 'pull-maintainer-updates-060324-1' of https://gitlab.com/stsquad/qemu into staging (2024-03-06 16:56:20 +) are available in the Git repository at: https://gitlab.com/gaosong/qemu.git tags/pull-loongarch-20240307 for you to fetch changes up to 4dc2edfd6f8abfc38f0ba110502790aa5051b1b5: hw/loongarch: Add cells missing from rtc node (2024-03-07 21:58:00 +0800) pull-loongarch-20240307 Song Gao (17): hw/loongarch: Move boot fucntions to boot.c hw/loongarch: Add load initrd hw/loongarch: Add slave cpu boot_code hw/loongarch: Add init_cmdline hw/loongarch: Init efi_system_table hw/loongarch: Init efi_boot_memmap table hw/loongarch: Init efi_initrd table hw/loongarch: Init efi_fdt table hw/loongarch: Fix fdt memory node wrong 'reg' hw/loongarch: fdt adds cpu interrupt controller node hw/loongarch: fdt adds Extend I/O Interrupt Controller hw/loongarch: fdt adds pch_pic Controller hw/loongarch: fdt adds pch_msi Controller hw/loongarch: fdt adds pcie irq_map node hw/loongarch: fdt remove unused irqchip node hw/loongarch: Add cells missing from uart node hw/loongarch: Add cells missing from rtc node hw/loongarch/boot.c| 330 + hw/loongarch/meson.build | 1 + hw/loongarch/virt.c| 363 + include/hw/intc/loongarch_extioi.h | 1 + include/hw/loongarch/boot.h| 109 +++ include/hw/loongarch/virt.h| 14 ++ include/hw/pci-host/ls7a.h | 2 + target/loongarch/cpu.h | 2 + 8 files changed, 662 insertions(+), 160 deletions(-) create mode 100644 hw/loongarch/boot.c create mode 100644 include/hw/loongarch/boot.h
Re: [PATCH v2 3/5] hw/loongarch: Add compat machine for 9.0
在 2024/2/27 10:30, Bibo Mao 写道: Since migration test case requires compat machine type support, compat machine is added for qemu 9.0 here. Signed-off-by: Bibo Mao --- hw/loongarch/virt.c | 60 +++-- 1 file changed, 47 insertions(+), 13 deletions(-) Reviewed-by: Song Gao Thanks. Song Gao diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c index 3bc35c58c9..f37f642ede 100644 --- a/hw/loongarch/virt.c +++ b/hw/loongarch/virt.c @@ -46,6 +46,32 @@ #include "hw/block/flash.h" #include "qemu/error-report.h" +#define DEFINE_VIRT_MACHINE_LATEST(major, minor, latest) \ +static void virt_##major##_##minor##_class_init(ObjectClass *oc, \ +void *data) \ +{ \ +MachineClass *mc = MACHINE_CLASS(oc); \ +virt_machine_##major##_##minor##_options(mc); \ +mc->desc = "QEMU " # major "." # minor " ARM Virtual Machine"; \ +if (latest) { \ +mc->alias = "virt"; \ +} \ +} \ +static const TypeInfo machvirt_##major##_##minor##_info = { \ +.name = MACHINE_TYPE_NAME("virt-" # major "." # minor), \ +.parent = TYPE_VIRT_MACHINE, \ +.class_init = virt_##major##_##minor##_class_init, \ +}; \ +static void machvirt_machine_##major##_##minor##_init(void) \ +{ \ +type_register_static(_##major##_##minor##_info); \ +} \ +type_init(machvirt_machine_##major##_##minor##_init); + +#define DEFINE_VIRT_MACHINE_AS_LATEST(major, minor) \ +DEFINE_VIRT_MACHINE_LATEST(major, minor, true) +#define DEFINE_VIRT_MACHINE(major, minor) \ +DEFINE_VIRT_MACHINE_LATEST(major, minor, false) struct loaderparams { uint64_t ram_size; @@ -1200,18 +1226,26 @@ static void virt_class_init(ObjectClass *oc, void *data) #endif } -static const TypeInfo virt_machine_types[] = { -{ -.name = TYPE_VIRT_MACHINE, -.parent = TYPE_MACHINE, -.instance_size = sizeof(VirtMachineState), -.class_init = virt_class_init, -.instance_init = virt_machine_initfn, -.interfaces = (InterfaceInfo[]) { - { TYPE_HOTPLUG_HANDLER }, - { } -}, -} +static const TypeInfo virt_machine_info = { +.name = TYPE_VIRT_MACHINE, +.parent = TYPE_MACHINE, +.abstract = true, +.instance_size = sizeof(VirtMachineState), +.class_init = virt_class_init, +.instance_init = virt_machine_initfn, +.interfaces = (InterfaceInfo[]) { +{ TYPE_HOTPLUG_HANDLER }, +{ } +}, }; -DEFINE_TYPES(virt_machine_types) +static void machvirt_machine_init(void) +{ +type_register_static(_machine_info); +} +type_init(machvirt_machine_init); + +static void virt_machine_9_0_options(MachineClass *mc) +{ +} +DEFINE_VIRT_MACHINE_AS_LATEST(9, 0)
Re: [PATCH v2 4/5] hw/loongarch: Set minimium memory size as 256M
在 2024/2/27 10:30, Bibo Mao 写道: The minimum memory size for LoongArch UEFI bios is 256M, also some test cases such as migration and qos use 256M memory by default. Here set minimum memory size for Loongarch VirtMachine with 256M rather than 1G, so that test cases with 256M memory can pass to run. Signed-off-by: Bibo Mao --- hw/loongarch/virt.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) Reviewed-by: Song Gao Thanks. Song Gao diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c index f37f642ede..1dadb8e299 100644 --- a/hw/loongarch/virt.c +++ b/hw/loongarch/virt.c @@ -864,8 +864,8 @@ static void virt_init(MachineState *machine) cpu_model = LOONGARCH_CPU_TYPE_NAME("la464"); } -if (ram_size < 1 * GiB) { -error_report("ram_size must be greater than 1G."); +if (ram_size < 256 * MiB) { +error_report("ram_size must be greater than 256M."); exit(1); } create_fdt(vms);
Re: [PATCH 3/5] hw/loongarch: Add compat machine for 9.0
在 2024/2/20 20:41, Bibo Mao 写道: Since migration test case requires compat machine type support, compat machine is added for qemu 9.0 here. Signed-off-by: Bibo Mao --- hw/loongarch/virt.c | 60 +++-- 1 file changed, 47 insertions(+), 13 deletions(-) Reviewed-by: Song Gao Thanks. Song Gao diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c index d0827aafab..a7d700497d 100644 --- a/hw/loongarch/virt.c +++ b/hw/loongarch/virt.c @@ -46,6 +46,32 @@ #include "hw/block/flash.h" #include "qemu/error-report.h" +#define DEFINE_VIRT_MACHINE_LATEST(major, minor, latest) \ +static void virt_##major##_##minor##_class_init(ObjectClass *oc, \ +void *data) \ +{ \ +MachineClass *mc = MACHINE_CLASS(oc); \ +virt_machine_##major##_##minor##_options(mc); \ +mc->desc = "QEMU " # major "." # minor " ARM Virtual Machine"; \ +if (latest) { \ +mc->alias = "virt"; \ +} \ +} \ +static const TypeInfo machvirt_##major##_##minor##_info = { \ +.name = MACHINE_TYPE_NAME("virt-" # major "." # minor), \ +.parent = TYPE_VIRT_MACHINE, \ +.class_init = virt_##major##_##minor##_class_init, \ +}; \ +static void machvirt_machine_##major##_##minor##_init(void) \ +{ \ +type_register_static(_##major##_##minor##_info); \ +} \ +type_init(machvirt_machine_##major##_##minor##_init); + +#define DEFINE_VIRT_MACHINE_AS_LATEST(major, minor) \ +DEFINE_VIRT_MACHINE_LATEST(major, minor, true) +#define DEFINE_VIRT_MACHINE(major, minor) \ +DEFINE_VIRT_MACHINE_LATEST(major, minor, false) struct loaderparams { uint64_t ram_size; @@ -1151,18 +1177,26 @@ static void virt_class_init(ObjectClass *oc, void *data) #endif } -static const TypeInfo virt_machine_types[] = { -{ -.name = TYPE_VIRT_MACHINE, -.parent = TYPE_MACHINE, -.instance_size = sizeof(VirtMachineState), -.class_init = virt_class_init, -.instance_init = virt_machine_initfn, -.interfaces = (InterfaceInfo[]) { - { TYPE_HOTPLUG_HANDLER }, - { } -}, -} +static const TypeInfo virt_machine_info = { +.name = TYPE_VIRT_MACHINE, +.parent = TYPE_MACHINE, +.abstract = true, +.instance_size = sizeof(VirtMachineState), +.class_init = virt_class_init, +.instance_init = virt_machine_initfn, +.interfaces = (InterfaceInfo[]) { +{ TYPE_HOTPLUG_HANDLER }, +{ } +}, }; -DEFINE_TYPES(virt_machine_types) +static void machvirt_machine_init(void) +{ +type_register_static(_machine_info); +} +type_init(machvirt_machine_init); + +static void virt_machine_9_0_options(MachineClass *mc) +{ +} +DEFINE_VIRT_MACHINE_AS_LATEST(9, 0)
Re: [PATCH v2] target/loongarch: Add TCG macro in structure CPUArchState
在 2024/3/4 10:18, Bibo Mao 写道: In structure CPUArchState some struct elements are only used in TCG mode, and it is not used in KVM mode. Macro CONFIG_TCG is added to make it simpiler in KVM mode, also there is the same modification in c code when these struct elements are used. When VM runs in KVM mode, TLB entries are not used and do not need migrate. It is only useful when it runs in TCG mode. Signed-off-by: Bibo Mao Change-Id: Id30d663f5d7bc3436520638f606f99d93926eb2e --- v1 --> v2: - Add field needed in structure vmstate_tlb, dynamically judge whether tlb should be migrated, since mostly qemu-system-loongarch64 is compiled with both kvm and tcg accl enabled. --- target/loongarch/cpu.c| 14 +++--- target/loongarch/cpu.h| 16 ++-- target/loongarch/cpu_helper.c | 9 + target/loongarch/machine.c| 34 +- 4 files changed, 59 insertions(+), 14 deletions(-) Reviewed-by: Song Gao Thanks. Song Gao diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c index bc2684179f..35db8e244d 100644 --- a/target/loongarch/cpu.c +++ b/target/loongarch/cpu.c @@ -517,7 +517,9 @@ static void loongarch_cpu_reset_hold(Object *obj) lacc->parent_phases.hold(obj); } +#ifdef CONFIG_TCG env->fcsr0_mask = FCSR0_M1 | FCSR0_M2 | FCSR0_M3; +#endif env->fcsr0 = 0x0; int n; @@ -562,7 +564,9 @@ static void loongarch_cpu_reset_hold(Object *obj) #ifndef CONFIG_USER_ONLY env->pc = 0x1c00; +#ifdef CONFIG_TCG memset(env->tlb, 0, sizeof(env->tlb)); +#endif if (kvm_enabled()) { kvm_arch_reset_vcpu(env); } @@ -696,11 +700,15 @@ void loongarch_cpu_dump_state(CPUState *cs, FILE *f, int flags) { LoongArchCPU *cpu = LOONGARCH_CPU(cs); CPULoongArchState *env = >env; -int i; +int i, fp_status; +#ifdef CONFIG_TCG +fp_status = get_float_exception_flags(>fp_status); +#else +fp_status = 0; +#endif qemu_fprintf(f, " PC=%016" PRIx64 " ", env->pc); -qemu_fprintf(f, " FCSR0 0x%08x fp_status 0x%02x\n", env->fcsr0, - get_float_exception_flags(>fp_status)); +qemu_fprintf(f, " FCSR0 0x%08x fp_status 0x%02x\n", env->fcsr0, fp_status); /* gpr */ for (i = 0; i < 32; i++) { diff --git a/target/loongarch/cpu.h b/target/loongarch/cpu.h index ec37579fd6..c25ad112b1 100644 --- a/target/loongarch/cpu.h +++ b/target/loongarch/cpu.h @@ -272,6 +272,7 @@ union fpr_t { VReg vreg; }; +#ifdef CONFIG_TCG struct LoongArchTLB { uint64_t tlb_misc; /* Fields corresponding to CSR_TLBELO0/1 */ @@ -279,23 +280,18 @@ struct LoongArchTLB { uint64_t tlb_entry1; }; typedef struct LoongArchTLB LoongArchTLB; +#endif typedef struct CPUArchState { uint64_t gpr[32]; uint64_t pc; fpr_t fpr[32]; -float_status fp_status; bool cf[8]; - uint32_t fcsr0; -uint32_t fcsr0_mask; uint32_t cpucfg[21]; -uint64_t lladdr; /* LL virtual address compared against SC */ -uint64_t llval; - /* LoongArch CSRs */ uint64_t CSR_CRMD; uint64_t CSR_PRMD; @@ -352,8 +348,16 @@ typedef struct CPUArchState { uint64_t CSR_DERA; uint64_t CSR_DSAVE; +#ifdef CONFIG_TCG +float_status fp_status; +uint32_t fcsr0_mask; +uint64_t lladdr; /* LL virtual address compared against SC */ +uint64_t llval; +#endif #ifndef CONFIG_USER_ONLY +#ifdef CONFIG_TCG LoongArchTLB tlb[LOONGARCH_TLB_MAX]; +#endif AddressSpace *address_space_iocsr; bool load_elf; diff --git a/target/loongarch/cpu_helper.c b/target/loongarch/cpu_helper.c index 45f821d086..d1cdbe30ba 100644 --- a/target/loongarch/cpu_helper.c +++ b/target/loongarch/cpu_helper.c @@ -11,6 +11,7 @@ #include "internals.h" #include "cpu-csr.h" +#ifdef CONFIG_TCG static int loongarch_map_tlb_entry(CPULoongArchState *env, hwaddr *physical, int *prot, target_ulong address, int access_type, int index, int mmu_idx) @@ -154,6 +155,14 @@ static int loongarch_map_address(CPULoongArchState *env, hwaddr *physical, return TLBRET_NOMATCH; } +#else +static int loongarch_map_address(CPULoongArchState *env, hwaddr *physical, + int *prot, target_ulong address, + MMUAccessType access_type, int mmu_idx) +{ +return TLBRET_NOMATCH; +} +#endif static hwaddr dmw_va2pa(CPULoongArchState *env, target_ulong va, target_ulong dmw) diff --git a/target/loongarch/machine.c b/target/loongarch/machine.c index c7029fb9b4..77890f07cc 100644 --- a/target/loongarch/machine.c +++ b/target/loongarch/machine.c @@ -8,6 +8,7 @@ #include "qemu/osdep.h" #include "cpu.h" #include "migration/cpu.h" +#include "sysemu/kvm.h" #include "vec.h" static const VMStateDescription vmstate_fpu_reg = {
Re: [PATCH] Fixed tlb huge page loading issue
Hi, Title 'target/loongarch: ' ... Thanks. Song Gao 在 2024/2/28 14:55, Xianglai Li 写道: The lddir and ldpte instruction emulation has a problem with the use of large page processing above level 2. The page size is not correctly calculated, resulting in the wrong page size of the table entry found by tlb. Signed-off-by: Xianglai Li --- target/loongarch/cpu.h| 1 + target/loongarch/tcg/tlb_helper.c | 21 - 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/target/loongarch/cpu.h b/target/loongarch/cpu.h index ec37579fd6..eab3e41c71 100644 --- a/target/loongarch/cpu.h +++ b/target/loongarch/cpu.h @@ -292,6 +292,7 @@ typedef struct CPUArchState { uint32_t fcsr0_mask; uint32_t cpucfg[21]; +uint32_t lddir_ps; uint64_t lladdr; /* LL virtual address compared against SC */ uint64_t llval; diff --git a/target/loongarch/tcg/tlb_helper.c b/target/loongarch/tcg/tlb_helper.c index a08c08b05a..3594c800b3 100644 --- a/target/loongarch/tcg/tlb_helper.c +++ b/target/loongarch/tcg/tlb_helper.c @@ -38,6 +38,7 @@ static void raise_mmu_exception(CPULoongArchState *env, target_ulong address, cs->exception_index = EXCCODE_PIF; } env->CSR_TLBRERA = FIELD_DP64(env->CSR_TLBRERA, CSR_TLBRERA, ISTLBR, 1); +env->lddir_ps = 0; break; case TLBRET_INVALID: /* TLB match with no valid bit */ @@ -488,13 +489,6 @@ target_ulong helper_lddir(CPULoongArchState *env, target_ulong base, uint64_t dir_base, dir_width; bool huge = (base >> LOONGARCH_PAGE_HUGE_SHIFT) & 0x1; -badvaddr = env->CSR_TLBRBADV; -base = base & TARGET_PHYS_MASK; - -/* 0:64bit, 1:128bit, 2:192bit, 3:256bit */ -shift = FIELD_EX64(env->CSR_PWCL, CSR_PWCL, PTEWIDTH); -shift = (shift + 1) * 3; - if (huge) { return base; } @@ -519,9 +513,18 @@ target_ulong helper_lddir(CPULoongArchState *env, target_ulong base, do_raise_exception(env, EXCCODE_INE, GETPC()); return 0; } + +/* 0:64bit, 1:128bit, 2:192bit, 3:256bit */ +shift = FIELD_EX64(env->CSR_PWCL, CSR_PWCL, PTEWIDTH); +shift = (shift + 1) * 3; +badvaddr = env->CSR_TLBRBADV; +base = base & TARGET_PHYS_MASK; index = (badvaddr >> dir_base) & ((1 << dir_width) - 1); phys = base | index << shift; ret = ldq_phys(cs->as, phys) & TARGET_PHYS_MASK; +if (ret & BIT_ULL(LOONGARCH_PAGE_HUGE_SHIFT)) { +env->lddir_ps = dir_base; +} return ret; } @@ -538,13 +541,13 @@ void helper_ldpte(CPULoongArchState *env, target_ulong base, target_ulong odd, base = base & TARGET_PHYS_MASK; if (huge) { -/* Huge Page. base is paddr */ tmp0 = base ^ (1 << LOONGARCH_PAGE_HUGE_SHIFT); /* Move Global bit */ tmp0 = ((tmp0 & (1 << LOONGARCH_HGLOBAL_SHIFT)) >> LOONGARCH_HGLOBAL_SHIFT) << R_TLBENTRY_G_SHIFT | (tmp0 & (~(1 << LOONGARCH_HGLOBAL_SHIFT))); -ps = ptbase + ptwidth - 1; + +ps = env->lddir_ps - 1; if (odd) { tmp0 += MAKE_64BIT_MASK(ps, 1); }
Re: [PATCH v5 00/17] Add boot LoongArch elf kernel with FDT
Hi, If there are no new comments, I'll add this series to the loongarch-next branch next week. Thanks. Song Gao 在 2024/3/1 下午5:38, Song Gao 写道: Hi, All We already support boot efi kernel with bios, but not support boot elf kernel. This series adds boot elf kernel with FDT. 'LoongArch supports ACPI and FDT. The information that needs to be passed to the kernel includes the memmap, the initrd, the command line, optionally the ACPI/FDT tables, and so on' see [1]. Patch 2-8 : Create efi system table, and three efi configuration table boot_memmap, initd, FDT. Patch 9-17 : Fixes FDT problems. Test: - Start kernel See [2] start_kernel.sh - Start qcow2 See [2] start_qcow2.sh V5: - Rebase; V4: - patch 3 change slave_boot_code[] to const, and 'static void *p ' to 'void *p'; - patch 4 fixes build error; - patch 10-13, add project and commit link. V3: - Load initrd at kernel_high + 4 * kernel_size; - Load 'boot_rom' at [0 - 1M], the 'boot_rom' includes slave_boot_code, cmdline_buf and systab_tables; - R-b and rebase. V2: - FDT pcie node adds cells 'msi-map'; [1]: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/arch/loongarch/booting.rst?h=v6.7-rc4 [2]: https://github.com/gaosong-loongson/loongarch-binary/releases Please review! Thanks. Song Gao Song Gao (17): hw/loongarch: Move boot fucntions to boot.c hw/loongarch: Add load initrd hw/loongarch: Add slave cpu boot_code hw/loongarch: Add init_cmdline hw/loongarch: Init efi_system_table hw/loongarch: Init efi_boot_memmap table hw/loongarch: Init efi_initrd table hw/loongarch: Init efi_fdt table hw/loongarch: Fix fdt memory node wrong 'reg' hw/loongarch: fdt adds cpu interrupt controller node hw/loongarch: fdt adds Extend I/O Interrupt Controller hw/loongarch: fdt adds pch_pic Controller hw/loongarch: fdt adds pch_msi Controller hw/loongarch: fdt adds pcie irq_map node hw/loongarch: fdt remove unused irqchip node hw/loongarch: Add cells missing from uart node hw/loongarch: Add cells missing from rtc node include/hw/intc/loongarch_extioi.h | 1 + include/hw/loongarch/boot.h| 109 + include/hw/loongarch/virt.h| 14 ++ include/hw/pci-host/ls7a.h | 2 + target/loongarch/cpu.h | 2 + hw/loongarch/boot.c| 330 ++ hw/loongarch/virt.c| 364 - hw/loongarch/meson.build | 1 + 8 files changed, 661 insertions(+), 162 deletions(-) create mode 100644 include/hw/loongarch/boot.h create mode 100644 hw/loongarch/boot.c
Re: [PATCH 1/3] linux-user/loongarch64: Remove TARGET_FORCE_SHMLBA
在 2024/2/23 上午11:03, Richard Henderson 写道: The upstream linux kernel does not define __ARCH_FORCE_SHMLBA. Cc: Song Gao Signed-off-by: Richard Henderson --- Did this definition come from the port before it was merged upstream? Yes, The patch [1] dropped it . [1] https://patchew.org/linux/20240106145501.3370364-1-chenhua...@loongson.cn/ Reviewed-by: Song Gao Thanks. Song Gao Or was it incorrectly copied from MIPS? --- linux-user/loongarch64/target_syscall.h | 7 --- 1 file changed, 7 deletions(-) diff --git a/linux-user/loongarch64/target_syscall.h b/linux-user/loongarch64/target_syscall.h index 8b5de52124..39f229bb9c 100644 --- a/linux-user/loongarch64/target_syscall.h +++ b/linux-user/loongarch64/target_syscall.h @@ -38,11 +38,4 @@ struct target_pt_regs { #define TARGET_MCL_FUTURE 2 #define TARGET_MCL_ONFAULT 4 -#define TARGET_FORCE_SHMLBA - -static inline abi_ulong target_shmlba(CPULoongArchState *env) -{ -return 64 * KiB; -} - #endif
Re: [PULL 0/1] loongarch-to-apply queue
在 2024/2/22 下午8:42, Peter Maydell 写道: On Wed, 21 Feb 2024 at 09:11, Song Gao wrote: The following changes since commit 760b4dcdddba4a40b9fa0eb78fdfc7eda7cb83d0: Merge tag 'for-upstream' of https://gitlab.com/bonzini/qemu into staging (2024-02-20 10:11:08 +) are available in the Git repository at: https://gitlab.com/gaosong/qemu.git tags/pull-loongarch-20240221 for you to fetch changes up to be57fd1e526e70fd55f1e87b0b70fab3c6baf089: loongarch: Change the UEFI loading mode to loongarch (2024-02-21 17:06:23 +0800) pull-loongarch-20240221 Xianglai Li (1): loongarch: Change the UEFI loading mode to loongarch Hi; this fails to build for mipsel: https://gitlab.com/qemu-project/qemu/-/jobs/6232698129 ../hw/loongarch/acpi-build.c: In function ‘build_flash_aml’: ../hw/loongarch/acpi-build.c:327:19: error: incompatible types when assigning to type ‘hwaddr’ {aka ‘long long unsigned int’} from type ‘Int128’ 327 | flash0_size = flash_mem->size; | ^ ../hw/loongarch/acpi-build.c:331:19: error: incompatible types when assigning to type ‘hwaddr’ {aka ‘long long unsigned int’} from type ‘Int128’ 331 | flash1_size = flash_mem->size; | ^ ../hw/loongarch/virt.c: In function ‘fdt_add_flash_node’: ../hw/loongarch/virt.c:131:19: error: incompatible types when assigning to type ‘hwaddr’ {aka ‘long long unsigned int’} from type ‘Int128’ 131 | flash0_size = flash_mem->size; | ^ ../hw/loongarch/virt.c:135:19: error: incompatible types when assigning to type ‘hwaddr’ {aka ‘long long unsigned int’} from type ‘Int128’ 135 | flash1_size = flash_mem->size; | ^ The value you get back from pflash_cfi01_get_memory() is a MemoryRegion -- this should be an opaque struct to you, not something you can reach in and get the 'size' field from. (The 'size' field is an Int128, which is not necessarily an integer type known to the compiler -- on some platforms it is a struct -- which is why this doesn't compile here.) Your board code created these memory regions so typically it should already know how big they are. If you really do need to get the size of a MemoryRegion, the function to use is memory_region_size( Got it , I will correct it. Thanks. Song Gao thanks -- PMM
Re: [PATCH V2 1/1] loongarch: Change the UEFI loading mode to loongarch
在 2024/2/19 下午6:34, Xianglai Li 写道: The UEFI loading mode in loongarch is very different from that in other architectures:loongarch's UEFI code is in rom, while other architectures' UEFI code is in flash. loongarch UEFI can be loaded as follows: -machine virt,pflash=pflash0-format -bios ./QEMU_EFI.fd Other architectures load UEFI using the following methods: -machine virt,pflash0=pflash0-format,pflash1=pflash1-format loongarch's UEFI loading method makes qemu and libvirt incompatible when using NVRAM, and the cost of loongarch's current loading method far outweighs the benefits, so we decided to use the same UEFI loading scheme as other architectures. Cc: Andrea Bolognani Cc: maob...@loongson.cn Cc: Philippe Mathieu-Daudé Cc: Song Gao Cc: zhaotian...@loongson.cn Signed-off-by: Xianglai Li Tested-by: Andrea Bolognani --- hw/loongarch/acpi-build.c | 29 +-- hw/loongarch/virt.c | 101 ++-- include/hw/loongarch/virt.h | 10 ++-- 3 files changed, 107 insertions(+), 33 deletions(-) Reviewed-by: Song Gao Thanks. Song Gao diff --git a/hw/loongarch/acpi-build.c b/hw/loongarch/acpi-build.c index a1c4198741..6c75f216ea 100644 --- a/hw/loongarch/acpi-build.c +++ b/hw/loongarch/acpi-build.c @@ -314,16 +314,39 @@ static void build_pci_device_aml(Aml *scope, LoongArchMachineState *lams) static void build_flash_aml(Aml *scope, LoongArchMachineState *lams) { Aml *dev, *crs; +MemoryRegion *flash_mem; -hwaddr flash_base = VIRT_FLASH_BASE; -hwaddr flash_size = VIRT_FLASH_SIZE; +hwaddr flash0_base; +hwaddr flash0_size; + +hwaddr flash1_base; +hwaddr flash1_size; + +flash_mem = pflash_cfi01_get_memory(lams->flash[0]); +flash0_base = flash_mem->addr; +flash0_size = flash_mem->size; + +flash_mem = pflash_cfi01_get_memory(lams->flash[1]); +flash1_base = flash_mem->addr; +flash1_size = flash_mem->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(crs, aml_memory32_fixed(flash0_base, flash0_size, + AML_READ_WRITE)); +aml_append(dev, aml_name_decl("_CRS", crs)); +aml_append(scope, dev); + +dev = aml_device("FLS1"); +aml_append(dev, aml_name_decl("_HID", aml_string("LNRO0015"))); +aml_append(dev, aml_name_decl("_UID", aml_int(1))); + +crs = aml_resource_template(); +aml_append(crs, aml_memory32_fixed(flash1_base, flash1_size, + AML_READ_WRITE)); aml_append(dev, aml_name_decl("_CRS", crs)); aml_append(scope, dev); } diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c index 0ad7d8c887..a7b9199e70 100644 --- a/hw/loongarch/virt.c +++ b/hw/loongarch/virt.c @@ -54,7 +54,9 @@ struct loaderparams { const char *initrd_filename; }; -static void virt_flash_create(LoongArchMachineState *lams) +static PFlashCFI01 *virt_flash_create1(LoongArchMachineState *lams, + const char *name, + const char *alias_prop_name) { DeviceState *dev = qdev_new(TYPE_PFLASH_CFI01); @@ -66,45 +68,78 @@ static void virt_flash_create(LoongArchMachineState *lams) 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", +qdev_prop_set_string(dev, "name", name); +object_property_add_child(OBJECT(lams), name, OBJECT(dev)); +object_property_add_alias(OBJECT(lams), alias_prop_name, OBJECT(dev), "drive"); +return PFLASH_CFI01(dev); +} -lams->flash = PFLASH_CFI01(dev); +static void virt_flash_create(LoongArchMachineState *lams) +{ +lams->flash[0] = virt_flash_create1(lams, "virt.flash0", "pflash0"); +lams->flash[1] = virt_flash_create1(lams, "virt.flash1", "pflash1"); } -static void virt_flash_map(LoongArchMachineState *lams, - MemoryRegion *sysmem) +static void virt_flash_map1(PFlashCFI01 *flash, +hwaddr base, hwaddr size, +MemoryRegion *sysmem) { -PFlashCFI01 *flash = lams->flash; DeviceState *dev = DEVICE(flash); -hwaddr base = VIRT_FLASH_BASE; -hwaddr size = VIRT_FLASH_SIZE; +BlockBackend *blk; +hwaddr real_size = size; + +blk = pflash_cfi01_get_blk(flash); +if (blk) { +real_size = blk_getlength(blk); +assert(real_size && real_size <= size); +} -assert(QEMU_IS_ALIGNED(size,
Re: [RESEND PATCH v4 00/17] Add boot LoongArch elf kernel with FDT
Ping ! 在 2024/1/18 下午7:31, Song Gao 写道: Hi, All We already support boot efi kernel with bios, but not support boot elf kernel. This series adds boot elf kernel with FDT. 'LoongArch supports ACPI and FDT. The information that needs to be passed to the kernel includes the memmap, the initrd, the command line, optionally the ACPI/FDT tables, and so on' see [1]. Patch 2-8 : Create efi system table, and three efi configuration table boot_memmap, initd, FDT. Patch 9-17 : Fixes FDT problems. Test: - Start kernel See [2] start_kernel.sh - Start qcow2 See [2] start_qcow2.sh V4: - patch 3 change slave_boot_code[] to const, and 'static void *p ' to 'void *p'; - patch 4 fixes build error; - patch 10-13, add project and commit link. V3: - Load initrd at kernel_high + 4 * kernel_size; - Load 'boot_rom' at [0 - 1M], the 'boot_rom' includes slave_boot_code, cmdline_buf and systab_tables; - R-b and rebase. V2: - FDT pcie node adds cells 'msi-map'; [1]: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/arch/loongarch/booting.rst?h=v6.7-rc4 [2]: https://github.com/gaosong-loongson/loongarch-binary/releases Please review! Thanks. Song Gao Song Gao (17): hw/loongarch: Move boot fucntions to boot.c hw/loongarch: Add load initrd hw/loongarch: Add slave cpu boot_code hw/loongarch: Add init_cmdline hw/loongarch: Init efi_system_table hw/loongarch: Init efi_boot_memmap table hw/loongarch: Init efi_initrd table hw/loongarch: Init efi_fdt table hw/loongarch: Fix fdt memory node wrong 'reg' hw/loongarch: fdt adds cpu interrupt controller node hw/loongarch: fdt adds Extend I/O Interrupt Controller hw/loongarch: fdt adds pch_pic Controller hw/loongarch: fdt adds pch_msi Controller hw/loongarch: fdt adds pcie irq_map node hw/loongarch: fdt remove unused irqchip node hw/loongarch: Add cells missing from uart node hw/loongarch: Add cells missing from rtc node include/hw/intc/loongarch_extioi.h | 1 + include/hw/loongarch/boot.h| 109 + include/hw/loongarch/virt.h| 14 ++ include/hw/pci-host/ls7a.h | 2 + target/loongarch/cpu.h | 2 + hw/loongarch/boot.c| 330 ++ hw/loongarch/virt.c| 364 - hw/loongarch/meson.build | 1 + 8 files changed, 661 insertions(+), 162 deletions(-) create mode 100644 include/hw/loongarch/boot.h create mode 100644 hw/loongarch/boot.c
Re: [PATCH] tcg/loongarch64: Set vector registers call clobbered
在 2024/2/2 上午7:34, Richard Henderson 写道: Because there are more call clobbered registers than call saved registers, we begin with all registers as call clobbered and then reset those that are saved. This was missed when we introduced the LSX support. Cc: qemu-sta...@nongnu.org Fixes: 16288ded944 ("tcg/loongarch64: Lower basic tcg vec ops to LSX") Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2136 Signed-off-by: Richard Henderson --- tcg/loongarch64/tcg-target.c.inc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) Thank you ! Reviewed-by: Song Gao Thanks. Song Gao diff --git a/tcg/loongarch64/tcg-target.c.inc b/tcg/loongarch64/tcg-target.c.inc index bab0a173a3..dcf0205458 100644 --- a/tcg/loongarch64/tcg-target.c.inc +++ b/tcg/loongarch64/tcg-target.c.inc @@ -2327,7 +2327,7 @@ static void tcg_target_init(TCGContext *s) tcg_target_available_regs[TCG_TYPE_I32] = ALL_GENERAL_REGS; tcg_target_available_regs[TCG_TYPE_I64] = ALL_GENERAL_REGS; -tcg_target_call_clobber_regs = ALL_GENERAL_REGS; +tcg_target_call_clobber_regs = ALL_GENERAL_REGS | ALL_VECTOR_REGS; tcg_regset_reset_reg(tcg_target_call_clobber_regs, TCG_REG_S0); tcg_regset_reset_reg(tcg_target_call_clobber_regs, TCG_REG_S1); tcg_regset_reset_reg(tcg_target_call_clobber_regs, TCG_REG_S2);
Re: [PATCH] tcg: Fixes set const_args[i] wrong value when instructions imm is 0
在 2024/2/1 上午5:16, Richard Henderson 写道: On 1/31/24 17:27, Song Gao wrote: It seems that tcg_reg_alloc_op() set const_args[i] wrong value when instructions imm is 0. The LoongArch tcg_out_vec_op() cmp_vec use the wrong const_args[2]. e.g The wrong const_args[2] is 0. IN: vslti.w v5, v4, 0x0 OUT: vslt.w v1, v1, v0 The right const_args[2] is 1. IN: vslti.w v5, v4, 0x0 OUT: vslti.w v1, v1, 0x0 Fixes: https://gitlab.com/qemu-project/qemu/-/issues/2136 Signed-off-by: Song Gao --- tcg/tcg.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tcg/tcg.c b/tcg/tcg.c index e2c38f6d11..5b290123bc 100644 --- a/tcg/tcg.c +++ b/tcg/tcg.c @@ -4808,7 +4808,7 @@ static void tcg_reg_alloc_op(TCGContext *s, const TCGOp *op) arg_ct = >args_ct[i]; ts = arg_temp(arg); - if (ts->val_type == TEMP_VAL_CONST + if ((ts->val_type == TEMP_VAL_CONST || ts->kind == TEMP_CONST) && tcg_target_const_match(ts->val, ts->type, arg_ct->ct, TCGOP_VECE(op))) { /* constant is OK for instruction */ const_args[i] = 1; This is wrong. I strongly suspect that the TEMP_CONST value 0 has been loaded into a register for use in another operation, and the register allocator sees that it is still there. Ah, I'm not familiar with this piece of code, I just try to fix the bug, and thanks for your suggestion. Thanks. Song Gao r~
Re: [NOTFORMERGE PATCH 2/2] gitlab: Add Loongarch64 KVM-only build
Hi, 在 2024/1/11 下午7:26, Philippe Mathieu-Daudé 写道: On 11/1/24 10:51, gaosong wrote: 在 2024/1/11 下午5:04, Thomas Huth 写道: On 11/01/2024 09.50, gaosong wrote: 在 2024/1/11 下午4:20, Thomas Huth 写道: On 11/01/2024 08.37, gaosong wrote: LoongArch no support these cmds or some problems . - "gva2gpa 0", - "memsave 0 4096 \"/dev/null\"", - "x /8i 0x100", - "xp /16x 0", Could we disable these 4 cmds or the test_temp check? After we fix the cmds problems, we can enable them. Even if loongarch does not support one of these commands, it should not crash QEMU. So please fix the crashes first before considering to enable the KVM-only test in the CI. Sure, we will fix the cmds problems first. The issue might be missing get_phys_page_attrs_debug() implementation. We use '--enable-kvm --disable-tcg ', the get_phys_page_debug() is NULL, so the test-hmp failed. target/loongarch/cpu.c ... #ifndef CONFIG_USER_ONLY #include "hw/core/sysemu-cpu-ops.h" static const struct SysemuCPUOps loongarch_sysemu_ops = { #ifdef CONFIG_TCG .get_phys_page_debug = loongarch_cpu_get_phys_page_debug, #endif }; ... I see the other architectures only implement get_phys_page_attrs_debug() or get_phys_page_debug() and not only build these functions on tcg mode. Should we need implement get_phys_page_attrs_debug() ? or just use get_phys_page_debug() Thanks. Song Gao
Re: [PATCH] target/loongarch: Set cpuid CSR register only once with kvm mode
在 2024/1/15 下午4:51, Bibo Mao 写道: CSR cpuid register is used for routing irq to different vcpus, its value is kept unchanged since poweron. So it is not necessary to set CSR cpuid register after system resets, and it is only set at vm creation stage. Signed-off-by: Bibo Mao --- target/loongarch/kvm/kvm.c | 9 ++--- 1 file changed, 6 insertions(+), 3 deletions(-) Reviewed-by: Song Gao Thanks. Song Gao diff --git a/target/loongarch/kvm/kvm.c b/target/loongarch/kvm/kvm.c index 84bcdf5f86..2230f029d0 100644 --- a/target/loongarch/kvm/kvm.c +++ b/target/loongarch/kvm/kvm.c @@ -250,7 +250,7 @@ static int kvm_loongarch_get_csr(CPUState *cs) return ret; } -static int kvm_loongarch_put_csr(CPUState *cs) +static int kvm_loongarch_put_csr(CPUState *cs, int level) { int ret = 0; LoongArchCPU *cpu = LOONGARCH_CPU(cs); @@ -322,8 +322,11 @@ static int kvm_loongarch_put_csr(CPUState *cs) ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_RVACFG), >CSR_RVACFG); -ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_CPUID), +/* CPUID is constant after poweron, it should be set only once */ +if (level >= KVM_PUT_FULL_STATE) { +ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_CPUID), >CSR_CPUID); +} ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_PRCFG1), >CSR_PRCFG1); @@ -598,7 +601,7 @@ int kvm_arch_put_registers(CPUState *cs, int level) return ret; } -ret = kvm_loongarch_put_csr(cs); +ret = kvm_loongarch_put_csr(cs, level); if (ret) { return ret; } base-commit: 977542ded7e6b28d2bc077bcda24568c716e393c
Re: [PATCH 1/1] target/loongarch/kvm: Enable LSX/LASX extension
在 2024/1/22 下午3:12, maobibo 写道: On 2024/1/22 下午2:09, Song Gao wrote: The kernel had already support LSX and LASX [1], but QEMU is disable LSX/LASX for kvm. This patch adds kvm_check_cpucfg to check CPUCFG2. [1]: https://lore.kernel.org/all/cabgobfzhrf7e_7jk4uprmsyxty3eiuuywhc35jqncnl9s-z...@mail.gmail.com/ Signed-off-by: Song Gao --- linux-headers/asm-loongarch/kvm.h | 1 + target/loongarch/kvm/kvm.c | 35 --- 2 files changed, 29 insertions(+), 7 deletions(-) diff --git a/linux-headers/asm-loongarch/kvm.h b/linux-headers/asm-loongarch/kvm.h index c6ad2ee610..923d0bd382 100644 --- a/linux-headers/asm-loongarch/kvm.h +++ b/linux-headers/asm-loongarch/kvm.h @@ -79,6 +79,7 @@ struct kvm_fpu { #define LOONGARCH_REG_64(TYPE, REG) (TYPE | KVM_REG_SIZE_U64 | (REG << LOONGARCH_REG_SHIFT)) #define KVM_IOC_CSRID(REG) LOONGARCH_REG_64(KVM_REG_LOONGARCH_CSR, REG) #define KVM_IOC_CPUCFG(REG) LOONGARCH_REG_64(KVM_REG_LOONGARCH_CPUCFG, REG) +#define KVM_LOONGARCH_VCPU_CPUCFG 0 struct kvm_debug_exit_arch { }; diff --git a/target/loongarch/kvm/kvm.c b/target/loongarch/kvm/kvm.c index 84bcdf5f86..41b6947c7b 100644 --- a/target/loongarch/kvm/kvm.c +++ b/target/loongarch/kvm/kvm.c @@ -537,6 +537,28 @@ static int kvm_loongarch_get_cpucfg(CPUState *cs) return ret; } +static int kvm_check_cpucfg(int id, CPUState *cs) +{ + int ret; + uint64_t val; + struct kvm_device_attr attr = { + .group = KVM_LOONGARCH_VCPU_CPUCFG, + .attr = id, + .addr = (uint64_t), + }; + LoongArchCPU *cpu = LOONGARCH_CPU(cs); + CPULoongArchState *env = >env; + + ret = kvm_vcpu_ioctl(cs, KVM_HAS_DEVICE_ATTR, ); + + if (!ret) { + kvm_vcpu_ioctl(cs, KVM_GET_DEVICE_ATTR, ); + env->cpucfg[id] &= val; With feature bit represents supported or disabled, it is ok to use logic of qemu feature bitmap and kvm supported feature bitmap. However about feature version, there will be problem with "and logic". Can we use minimal version here? Yes, we can, I will correct it on v2. Thanks. Song Gao Regards Bibo Mao + } + + return ret; +} + static int kvm_loongarch_put_cpucfg(CPUState *cs) { int i, ret = 0; @@ -545,14 +567,13 @@ static int kvm_loongarch_put_cpucfg(CPUState *cs) uint64_t val; for (i = 0; i < 21; i++) { + if (i == 2) { + ret = kvm_check_cpucfg(i, cs); + if (ret) { + return ret; + } + } val = env->cpucfg[i]; - /* LSX and LASX and LBT are not supported in kvm now */ - if (i == 2) { - val &= ~(BIT(R_CPUCFG2_LSX_SHIFT) | BIT(R_CPUCFG2_LASX_SHIFT)); - val &= ~(BIT(R_CPUCFG2_LBT_X86_SHIFT) | - BIT(R_CPUCFG2_LBT_ARM_SHIFT) | - BIT(R_CPUCFG2_LBT_MIPS_SHIFT)); - } ret = kvm_set_one_reg(cs, KVM_IOC_CPUCFG(i), ); if (ret < 0) { trace_kvm_failed_put_cpucfg(strerror(errno));
Re: [PATCH v4 00/17] Add boot LoongArch elf kernel with FDT
Please ignore this, I will resend it. 在 2024/1/18 下午7:18, Song Gao 写道: Hi, All We already support boot efi kernel with bios, but not support boot elf kernel. This series adds boot elf kernel with FDT. 'LoongArch supports ACPI and FDT. The information that needs to be passed to the kernel includes the memmap, the initrd, the command line, optionally the ACPI/FDT tables, and so on' see [1]. Patch 2-8 : Create efi system table, and three efi configuration table boot_memmap, initd, FDT. Patch 9-17 : Fixes FDT problems. Test: - Start kernel See [2] start_kernel.sh - Start qcow2 See [2] start_qcow2.sh V4: - patch 3 change slave_boot_code[] to const, and 'static void *p ' to 'void *p'; - patch 4 fixes build error; - patch 10-13, add project and commit link. V3: - Load initrd at kernel_high + 4 * kernel_size; - Load 'boot_rom' at [0 - 1M], the 'boot_rom' includes V3: - Load initrd at kernel_high + 4 * kernel_size; - Load 'boot_rom' at [0 - 1M], the 'boot_rom' includes slave_boot_code, cmdline_buf and systab_tables; - R-b and rebase. V2: - FDT pcie node adds cells 'msi-map'; [1]: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/arch/loongarch/booting.rst?h=v6.7-rc4 [2]: https://github.com/gaosong-loongson/loongarch-binary/releases Please review! Thanks. Song Gao Song Gao (17): hw/loongarch: Move boot fucntions to boot.c hw/loongarch: Add load initrd hw/loongarch: Add slave cpu boot_code hw/loongarch: Add init_cmdline hw/loongarch: Init efi_system_table hw/loongarch: Init efi_boot_memmap table hw/loongarch: Init efi_initrd table hw/loongarch: Init efi_fdt table hw/loongarch: Fix fdt memory node wrong 'reg' hw/loongarch: fdt adds cpu interrupt controller node hw/loongarch: fdt adds Extend I/O Interrupt Controller hw/loongarch: fdt adds pch_pic Controller hw/loongarch: fdt adds pch_msi Controller hw/loongarch: fdt adds pcie irq_map node hw/loongarch: fdt remove unused irqchip node hw/loongarch: Add cells missing from uart node hw/loongarch: Add cells missing from rtc node include/hw/intc/loongarch_extioi.h | 1 + include/hw/loongarch/boot.h| 109 + include/hw/loongarch/virt.h| 14 ++ include/hw/pci-host/ls7a.h | 2 + target/loongarch/cpu.h | 2 + hw/loongarch/boot.c| 330 ++ hw/loongarch/virt.c| 364 - hw/loongarch/meson.build | 1 + 8 files changed, 661 insertions(+), 162 deletions(-) create mode 100644 include/hw/loongarch/boot.h create mode 100644 hw/loongarch/boot.c
Re: [PATCH 1/2] gitlab: Introduce Loongarch64 runner
在 2024/1/12 下午5:52, gaosong 写道: 在 2024/1/11 下午4:26, Thomas Huth 写道: On 11/01/2024 08.25, gaosong wrote: Hi, 在 2024/1/11 下午3:08, Thomas Huth 写道: On 02/01/2024 18.22, Philippe Mathieu-Daudé wrote: Full build config to run CI tests on a Loongarch64 host. Forks might enable this by setting LOONGARCH64_RUNNER_AVAILABLE in their CI namespace settings, see: https://www.qemu.org/docs/master/devel/ci.html#maintainer-controlled-job-variables Signed-off-by: Philippe Mathieu-Daudé --- docs/devel/ci-jobs.rst.inc | 6 ++ .gitlab-ci.d/custom-runners.yml | 1 + .../openeuler-22.03-loongarch64.yml | 21 +++ 3 files changed, 28 insertions(+) create mode 100644 .gitlab-ci.d/custom-runners/openeuler-22.03-loongarch64.yml ... diff --git a/.gitlab-ci.d/custom-runners.yml b/.gitlab-ci.d/custom-runners.yml index 8e5b9500f4..152ace4492 100644 --- a/.gitlab-ci.d/custom-runners.yml +++ b/.gitlab-ci.d/custom-runners.yml @@ -32,3 +32,4 @@ include: - local: '/.gitlab-ci.d/custom-runners/ubuntu-22.04-aarch64.yml' - local: '/.gitlab-ci.d/custom-runners/ubuntu-22.04-aarch32.yml' - local: '/.gitlab-ci.d/custom-runners/centos-stream-8-x86_64.yml' + - local: '/.gitlab-ci.d/custom-runners/openeuler-22.03-loongarch64.yml' diff --git a/.gitlab-ci.d/custom-runners/openeuler-22.03-loongarch64.yml b/.gitlab-ci.d/custom-runners/openeuler-22.03-loongarch64.yml new file mode 100644 index 00..86d18f820e --- /dev/null +++ b/.gitlab-ci.d/custom-runners/openeuler-22.03-loongarch64.yml @@ -0,0 +1,21 @@ +openeuler-22.03-loongarch64-all: + extends: .custom_runner_template :-) + needs: [] + stage: build + tags: + - oe2203 + - loongarch64 + rules: + - if: '$CI_PROJECT_NAMESPACE == "qemu-project" && $CI_COMMIT_BRANCH =~ /^staging/' + when: manual + allow_failure: true + - if: "$LOONGARCH64_RUNNER_AVAILABLE" + when: manual + allow_failure: true + script: + - mkdir build + - cd build + - ../configure + || { cat config.log meson-logs/meson-log.txt; exit 1; } + - make --output-sync -j`nproc --ignore=40` + - make --output-sync -j`nproc --ignore=40` check Does this system really have more than 40 CPU threads? Or is this a copy-n-past from one of the other scripts? In the latter case, I'd suggest to adjust the --ignore=40 to a more reasonable value. Thomas No, only 32. I think it should be --ignore=32 or 16. --ignore=32 then also does not make much sense, that would still be the same as simply omitting the -j parameter. I guess --ignore=16 should be fine. I create a same runner on this machine, and I find some check error. but I am not sure how to fix it. :-) See: https://gitlab.com/gaosong/qemu/-/jobs/5906269934 Seems to be related to RAM backing... for example, the erst-test is failing, which is doing something like: setup_vm_cmd(, "-object memory-backend-file," "mem-path=acpi-erst.XX," "size=64K," Hi, We tested this on LoongArch host with the 5.10 kernel, (openEuler 22.03), x86_64 host with 5.10 kernel, (openEuler 22.03) x86_64 host with 5.15kernel , (Ubuntu 20.04.3 LTS) and didn't get any error. but the CI machine use the 6.7_rc4 kernel. we didn't update the x86_64 host kernel to tested this. Is it possible that the new kernel is causing the problem? Hi, The kernel adds the patch[1] can fix this problem. [1] https://patchew.org/linux/20240106145501.3370364-1-chenhua...@loongson.cn/ So Tested-by: Song Gao Reviewed-by: Song Gao Thanks. Song Gao "share=on," "id=nvram " "-device acpi-erst," "memdev=nvram"); So it seems like -object memory-backend-file" is not correctly working in your gitlab runner? Is there some setup missing? Thomas
Re: [PATCH 1/2] gitlab: Introduce Loongarch64 runner
在 2024/1/11 下午4:26, Thomas Huth 写道: On 11/01/2024 08.25, gaosong wrote: Hi, 在 2024/1/11 下午3:08, Thomas Huth 写道: On 02/01/2024 18.22, Philippe Mathieu-Daudé wrote: Full build config to run CI tests on a Loongarch64 host. Forks might enable this by setting LOONGARCH64_RUNNER_AVAILABLE in their CI namespace settings, see: https://www.qemu.org/docs/master/devel/ci.html#maintainer-controlled-job-variables Signed-off-by: Philippe Mathieu-Daudé --- docs/devel/ci-jobs.rst.inc | 6 ++ .gitlab-ci.d/custom-runners.yml | 1 + .../openeuler-22.03-loongarch64.yml | 21 +++ 3 files changed, 28 insertions(+) create mode 100644 .gitlab-ci.d/custom-runners/openeuler-22.03-loongarch64.yml ... diff --git a/.gitlab-ci.d/custom-runners.yml b/.gitlab-ci.d/custom-runners.yml index 8e5b9500f4..152ace4492 100644 --- a/.gitlab-ci.d/custom-runners.yml +++ b/.gitlab-ci.d/custom-runners.yml @@ -32,3 +32,4 @@ include: - local: '/.gitlab-ci.d/custom-runners/ubuntu-22.04-aarch64.yml' - local: '/.gitlab-ci.d/custom-runners/ubuntu-22.04-aarch32.yml' - local: '/.gitlab-ci.d/custom-runners/centos-stream-8-x86_64.yml' + - local: '/.gitlab-ci.d/custom-runners/openeuler-22.03-loongarch64.yml' diff --git a/.gitlab-ci.d/custom-runners/openeuler-22.03-loongarch64.yml b/.gitlab-ci.d/custom-runners/openeuler-22.03-loongarch64.yml new file mode 100644 index 00..86d18f820e --- /dev/null +++ b/.gitlab-ci.d/custom-runners/openeuler-22.03-loongarch64.yml @@ -0,0 +1,21 @@ +openeuler-22.03-loongarch64-all: + extends: .custom_runner_template :-) + needs: [] + stage: build + tags: + - oe2203 + - loongarch64 + rules: + - if: '$CI_PROJECT_NAMESPACE == "qemu-project" && $CI_COMMIT_BRANCH =~ /^staging/' + when: manual + allow_failure: true + - if: "$LOONGARCH64_RUNNER_AVAILABLE" + when: manual + allow_failure: true + script: + - mkdir build + - cd build + - ../configure + || { cat config.log meson-logs/meson-log.txt; exit 1; } + - make --output-sync -j`nproc --ignore=40` + - make --output-sync -j`nproc --ignore=40` check Does this system really have more than 40 CPU threads? Or is this a copy-n-past from one of the other scripts? In the latter case, I'd suggest to adjust the --ignore=40 to a more reasonable value. Thomas No, only 32. I think it should be --ignore=32 or 16. --ignore=32 then also does not make much sense, that would still be the same as simply omitting the -j parameter. I guess --ignore=16 should be fine. I create a same runner on this machine, and I find some check error. but I am not sure how to fix it. :-) See: https://gitlab.com/gaosong/qemu/-/jobs/5906269934 Seems to be related to RAM backing... for example, the erst-test is failing, which is doing something like: setup_vm_cmd(, "-object memory-backend-file," "mem-path=acpi-erst.XX," "size=64K," Hi, We tested this on LoongArch host with the 5.10 kernel, (openEuler 22.03), x86_64 host with 5.10 kernel, (openEuler 22.03) x86_64 host with 5.15kernel , (Ubuntu 20.04.3 LTS) and didn't get any error. but the CI machine use the 6.7_rc4 kernel. we didn't update the x86_64 host kernel to tested this. Is it possible that the new kernel is causing the problem? "share=on," "id=nvram " "-device acpi-erst," "memdev=nvram"); So it seems like -object memory-backend-file" is not correctly working in your gitlab runner? Is there some setup missing? Thomas
Re: [PATCH 1/2] gitlab: Introduce Loongarch64 runner
在 2024/1/11 下午4:26, Thomas Huth 写道: On 11/01/2024 08.25, gaosong wrote: Hi, 在 2024/1/11 下午3:08, Thomas Huth 写道: On 02/01/2024 18.22, Philippe Mathieu-Daudé wrote: Full build config to run CI tests on a Loongarch64 host. Forks might enable this by setting LOONGARCH64_RUNNER_AVAILABLE in their CI namespace settings, see: https://www.qemu.org/docs/master/devel/ci.html#maintainer-controlled-job-variables Signed-off-by: Philippe Mathieu-Daudé --- docs/devel/ci-jobs.rst.inc | 6 ++ .gitlab-ci.d/custom-runners.yml | 1 + .../openeuler-22.03-loongarch64.yml | 21 +++ 3 files changed, 28 insertions(+) create mode 100644 .gitlab-ci.d/custom-runners/openeuler-22.03-loongarch64.yml ... diff --git a/.gitlab-ci.d/custom-runners.yml b/.gitlab-ci.d/custom-runners.yml index 8e5b9500f4..152ace4492 100644 --- a/.gitlab-ci.d/custom-runners.yml +++ b/.gitlab-ci.d/custom-runners.yml @@ -32,3 +32,4 @@ include: - local: '/.gitlab-ci.d/custom-runners/ubuntu-22.04-aarch64.yml' - local: '/.gitlab-ci.d/custom-runners/ubuntu-22.04-aarch32.yml' - local: '/.gitlab-ci.d/custom-runners/centos-stream-8-x86_64.yml' + - local: '/.gitlab-ci.d/custom-runners/openeuler-22.03-loongarch64.yml' diff --git a/.gitlab-ci.d/custom-runners/openeuler-22.03-loongarch64.yml b/.gitlab-ci.d/custom-runners/openeuler-22.03-loongarch64.yml new file mode 100644 index 00..86d18f820e --- /dev/null +++ b/.gitlab-ci.d/custom-runners/openeuler-22.03-loongarch64.yml @@ -0,0 +1,21 @@ +openeuler-22.03-loongarch64-all: + extends: .custom_runner_template :-) + needs: [] + stage: build + tags: + - oe2203 + - loongarch64 + rules: + - if: '$CI_PROJECT_NAMESPACE == "qemu-project" && $CI_COMMIT_BRANCH =~ /^staging/' + when: manual + allow_failure: true + - if: "$LOONGARCH64_RUNNER_AVAILABLE" + when: manual + allow_failure: true + script: + - mkdir build + - cd build + - ../configure + || { cat config.log meson-logs/meson-log.txt; exit 1; } + - make --output-sync -j`nproc --ignore=40` + - make --output-sync -j`nproc --ignore=40` check Does this system really have more than 40 CPU threads? Or is this a copy-n-past from one of the other scripts? In the latter case, I'd suggest to adjust the --ignore=40 to a more reasonable value. Thomas No, only 32. I think it should be --ignore=32 or 16. --ignore=32 then also does not make much sense, that would still be the same as simply omitting the -j parameter. I guess --ignore=16 should be fine. I create a same runner on this machine, and I find some check error. but I am not sure how to fix it. :-) See: https://gitlab.com/gaosong/qemu/-/jobs/5906269934 Seems to be related to RAM backing... for example, the erst-test is failing, which is doing something like: setup_vm_cmd(, "-object memory-backend-file," "mem-path=acpi-erst.XX," "size=64K," "share=on," "id=nvram " "-device acpi-erst," "memdev=nvram"); So it seems like -object memory-backend-file" is not correctly working in your gitlab runner? Is there some setup missing? Thomas This is my runner config. concurrent = 32 check_interval = 0 shutdown_timeout = 0 [session_server] session_timeout = 1800 ... [[runners]] name = "loongarch64" request_concurrency = 24 url = "https://gitlab.com; id = 31426483 token = "glrt-bGugocYrR2yqcu3ma7ka" token_obtained_at = 2024-01-10T08:31:29Z token_expires_at = 0001-01-01T00:00:00Z executor = "shell" builds_dir = "/data/gitlab-runner/builds" cache_dir = "/data/gitlab-runner/cache" [runners.cache] MaxUploadedArchiveSize = 0 I create a project runner 'loongarch64' for my branch ci-master. Do we need some special configuration? and I just './configure --target-list="x86_64-softmmu" --enable-debug' on LoongArch host. make , make check. I got the same error. [7/361] qemu:qtest+qtest-x86_64 / qtest-x86_64/qos-test 2928s 60 subtests passed ^CWARNING: Received SIGTERM, exiting 7/361 qemu:qtest+qtest-x86_64 / qtest-x86_64/qos-test INTERRUPT 4671.32s killed by signal 11 SIGSEGV >>> PYTHON=/home/gs/gitlab/qemu/build/pyvenv/bin/python3 G_TEST_DBUS_DAEMON=/home/gs/gitlab/qemu/tests/dbus-vmstate-daemon.sh MALLOC_PERTURB_=198 QTEST_QEMU_IMG=./qemu-img QTEST_QEMU_BINARY=./qemu-system-x86_64 QTEST_QEMU_STORAGE_DAEMON_BINARY=./storage-daemon/qemu-storage-daemon /home/gs/gitlab/qemu/build/tests/qtest/qos-test --tap -k ― ✀ ―
Re: [NOTFORMERGE PATCH 2/2] gitlab: Add Loongarch64 KVM-only build
在 2024/1/11 下午7:26, Philippe Mathieu-Daudé 写道: On 11/1/24 10:51, gaosong wrote: 在 2024/1/11 下午5:04, Thomas Huth 写道: On 11/01/2024 09.50, gaosong wrote: 在 2024/1/11 下午4:20, Thomas Huth 写道: On 11/01/2024 08.37, gaosong wrote: LoongArch no support these cmds or some problems . - "gva2gpa 0", - "memsave 0 4096 \"/dev/null\"", - "x /8i 0x100", - "xp /16x 0", Could we disable these 4 cmds or the test_temp check? After we fix the cmds problems, we can enable them. Even if loongarch does not support one of these commands, it should not crash QEMU. So please fix the crashes first before considering to enable the KVM-only test in the CI. Sure, we will fix the cmds problems first. The issue might be missing get_phys_page_attrs_debug() implementation. yes, I see, from hmp_gva2gpa(). I think we need implement it. Thanks. Song Gao
Re: [NOTFORMERGE PATCH 2/2] gitlab: Add Loongarch64 KVM-only build
在 2024/1/11 下午5:04, Thomas Huth 写道: On 11/01/2024 09.50, gaosong wrote: 在 2024/1/11 下午4:20, Thomas Huth 写道: On 11/01/2024 08.37, gaosong wrote: Hi, 在 2024/1/11 下午3:10, Thomas Huth 写道: On 02/01/2024 18.22, Philippe Mathieu-Daudé wrote: Signed-off-by: Philippe Mathieu-Daudé --- Used to test https://lore.kernel.org/qemu-devel/20231228084051.3235354-1-zhaotian...@loongson.cn/ So why is it NOTFORMERGE ? Don't we want to test KVM-only builds for loongarch in the long run? Thomas I think we can drop this title. I tested this job by the latest loongarch kvm patches. buf I find a test-hmp check error. Can you recreate the error manually? i.e. compile with configure --disable-tcg and then run: V=2 QTEST_QEMU_BINARY=./qemu-system-loongarch64 tests/qtest/test-hmp That should likely provide you with a hint where it is crashing Thomas Thank you, LoongArch no support these cmds or some problems . - "gva2gpa 0", - "memsave 0 4096 \"/dev/null\"", - "x /8i 0x100", - "xp /16x 0", Could we disable these 4 cmds or the test_temp check? After we fix the cmds problems, we can enable them. Even if loongarch does not support one of these commands, it should not crash QEMU. So please fix the crashes first before considering to enable the KVM-only test in the CI. Sure, we will fix the cmds problems first. Thanks. Song Gao
Re: [NOTFORMERGE PATCH 2/2] gitlab: Add Loongarch64 KVM-only build
在 2024/1/11 下午4:20, Thomas Huth 写道: On 11/01/2024 08.37, gaosong wrote: Hi, 在 2024/1/11 下午3:10, Thomas Huth 写道: On 02/01/2024 18.22, Philippe Mathieu-Daudé wrote: Signed-off-by: Philippe Mathieu-Daudé --- Used to test https://lore.kernel.org/qemu-devel/20231228084051.3235354-1-zhaotian...@loongson.cn/ So why is it NOTFORMERGE ? Don't we want to test KVM-only builds for loongarch in the long run? Thomas I think we can drop this title. I tested this job by the latest loongarch kvm patches. buf I find a test-hmp check error. Can you recreate the error manually? i.e. compile with configure --disable-tcg and then run: V=2 QTEST_QEMU_BINARY=./qemu-system-loongarch64 tests/qtest/test-hmp That should likely provide you with a hint where it is crashing Thomas Thank you, LoongArch no support these cmds or some problems . - "gva2gpa 0", - "memsave 0 4096 \"/dev/null\"", - "x /8i 0x100", - "xp /16x 0", Could we disable these 4 cmds or the test_temp check? After we fix the cmds problems, we can enable them. Thanks. Song gao
Re: [NOTFORMERGE PATCH 2/2] gitlab: Add Loongarch64 KVM-only build
Hi, 在 2024/1/11 下午3:10, Thomas Huth 写道: On 02/01/2024 18.22, Philippe Mathieu-Daudé wrote: Signed-off-by: Philippe Mathieu-Daudé --- Used to test https://lore.kernel.org/qemu-devel/20231228084051.3235354-1-zhaotian...@loongson.cn/ So why is it NOTFORMERGE ? Don't we want to test KVM-only builds for loongarch in the long run? Thomas I think we can drop this title. I tested this job by the latest loongarch kvm patches. buf I find a test-hmp check error. See: https://gitlab.com/gaosong/qemu/-/jobs/5906385234 If you want to log in to this machine, we can create an account for you. Thanks. Song Gao --- .../openeuler-22.03-loongarch64.yml | 22 +++ 1 file changed, 22 insertions(+) diff --git a/.gitlab-ci.d/custom-runners/openeuler-22.03-loongarch64.yml b/.gitlab-ci.d/custom-runners/openeuler-22.03-loongarch64.yml index 86d18f820e..60674b8d0f 100644 --- a/.gitlab-ci.d/custom-runners/openeuler-22.03-loongarch64.yml +++ b/.gitlab-ci.d/custom-runners/openeuler-22.03-loongarch64.yml @@ -19,3 +19,25 @@ openeuler-22.03-loongarch64-all: || { cat config.log meson-logs/meson-log.txt; exit 1; } - make --output-sync -j`nproc --ignore=40` - make --output-sync -j`nproc --ignore=40` check + +openeuler-22.03-loongarch64-kvm: + extends: .custom_runner_template + needs: [] + stage: build + tags: + - oe2203 + - loongarch64 + rules: + - if: '$CI_PROJECT_NAMESPACE == "qemu-project" && $CI_COMMIT_BRANCH =~ /^staging/' + when: manual + allow_failure: true + - if: "$LOONGARCH64_RUNNER_AVAILABLE" + when: manual + allow_failure: true + script: + - mkdir build + - cd build + - ../configure --enable-kvm --disable-tcg + || { cat config.log meson-logs/meson-log.txt; exit 1; } + - make --output-sync -j`nproc --ignore=40` + - make --output-sync -j`nproc --ignore=40` check
Re: [PATCH 1/2] gitlab: Introduce Loongarch64 runner
Hi, 在 2024/1/11 下午3:08, Thomas Huth 写道: On 02/01/2024 18.22, Philippe Mathieu-Daudé wrote: Full build config to run CI tests on a Loongarch64 host. Forks might enable this by setting LOONGARCH64_RUNNER_AVAILABLE in their CI namespace settings, see: https://www.qemu.org/docs/master/devel/ci.html#maintainer-controlled-job-variables Signed-off-by: Philippe Mathieu-Daudé --- docs/devel/ci-jobs.rst.inc | 6 ++ .gitlab-ci.d/custom-runners.yml | 1 + .../openeuler-22.03-loongarch64.yml | 21 +++ 3 files changed, 28 insertions(+) create mode 100644 .gitlab-ci.d/custom-runners/openeuler-22.03-loongarch64.yml ... diff --git a/.gitlab-ci.d/custom-runners.yml b/.gitlab-ci.d/custom-runners.yml index 8e5b9500f4..152ace4492 100644 --- a/.gitlab-ci.d/custom-runners.yml +++ b/.gitlab-ci.d/custom-runners.yml @@ -32,3 +32,4 @@ include: - local: '/.gitlab-ci.d/custom-runners/ubuntu-22.04-aarch64.yml' - local: '/.gitlab-ci.d/custom-runners/ubuntu-22.04-aarch32.yml' - local: '/.gitlab-ci.d/custom-runners/centos-stream-8-x86_64.yml' + - local: '/.gitlab-ci.d/custom-runners/openeuler-22.03-loongarch64.yml' diff --git a/.gitlab-ci.d/custom-runners/openeuler-22.03-loongarch64.yml b/.gitlab-ci.d/custom-runners/openeuler-22.03-loongarch64.yml new file mode 100644 index 00..86d18f820e --- /dev/null +++ b/.gitlab-ci.d/custom-runners/openeuler-22.03-loongarch64.yml @@ -0,0 +1,21 @@ +openeuler-22.03-loongarch64-all: + extends: .custom_runner_template :-) + needs: [] + stage: build + tags: + - oe2203 + - loongarch64 + rules: + - if: '$CI_PROJECT_NAMESPACE == "qemu-project" && $CI_COMMIT_BRANCH =~ /^staging/' + when: manual + allow_failure: true + - if: "$LOONGARCH64_RUNNER_AVAILABLE" + when: manual + allow_failure: true + script: + - mkdir build + - cd build + - ../configure + || { cat config.log meson-logs/meson-log.txt; exit 1; } + - make --output-sync -j`nproc --ignore=40` + - make --output-sync -j`nproc --ignore=40` check Does this system really have more than 40 CPU threads? Or is this a copy-n-past from one of the other scripts? In the latter case, I'd suggest to adjust the --ignore=40 to a more reasonable value. Thomas No, only 32. I think it should be --ignore=32 or 16. I create a same runner on this machine, and I find some check error. but I am not sure how to fix it. :-) See: https://gitlab.com/gaosong/qemu/-/jobs/5906269934 Thanks. Song Gao
Re: [PATCH v4 8/9b] target/loongarch: Implement set vcpu intr for kvm
Hi, 在 2024/1/10 下午5:41, Philippe Mathieu-Daudé 写道: From: Tianrui Zhao Implement loongarch kvm set vcpu interrupt interface, when a irq is set in vcpu, we use the KVM_INTERRUPT ioctl to set intr into kvm. Signed-off-by: Tianrui Zhao Signed-off-by: xianglai li Reviewed-by: Song Gao Message-ID: <20240105075804.1228596-9-zhaotian...@loongson.cn> [PMD: Split from bigger patch, part 2] Signed-off-by: Philippe Mathieu-Daudé --- target/loongarch/kvm/kvm_loongarch.h | 16 target/loongarch/cpu.c | 9 - target/loongarch/kvm/kvm.c | 15 +++ target/loongarch/trace-events| 1 + 4 files changed, 40 insertions(+), 1 deletion(-) create mode 100644 target/loongarch/kvm/kvm_loongarch.h diff --git a/target/loongarch/kvm/kvm_loongarch.h b/target/loongarch/kvm/kvm_loongarch.h new file mode 100644 index 00..d945b6bb82 --- /dev/null +++ b/target/loongarch/kvm/kvm_loongarch.h @@ -0,0 +1,16 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * QEMU LoongArch kvm interface + * + * Copyright (c) 2023 Loongson Technology Corporation Limited + */ + +#include "cpu.h" + +#ifndef QEMU_KVM_LOONGARCH_H +#define QEMU_KVM_LOONGARCH_H + +int kvm_loongarch_set_interrupt(LoongArchCPU *cpu, int irq, int level); +void kvm_arch_reset_vcpu(CPULoongArchState *env); + +#endif diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c index d9f8661cfd..d3a8a2f521 100644 --- a/target/loongarch/cpu.c +++ b/target/loongarch/cpu.c @@ -12,6 +12,7 @@ #include "qemu/module.h" #include "sysemu/qtest.h" #include "sysemu/tcg.h" +#include "sysemu/kvm.h" #include "exec/exec-all.h" #include "cpu.h" #include "internals.h" @@ -21,6 +22,10 @@ #include "sysemu/reset.h" #endif #include "vec.h" +#ifdef CONFIG_KVM +#include "kvm/kvm_loongarch.h" This broken tcg 'loongarch64-softmmu' build on X86 host, :-[ ../target/loongarch/cpu.c: In function ‘loongarch_cpu_set_irq’: ../target/loongarch/cpu.c:122:9: error: implicit declaration of function ‘kvm_loongarch_set_interrupt’ [-Werror=implicit-function-declaration] 122 | kvm_loongarch_set_interrupt(cpu, irq, level); | ^~~ ../target/loongarch/cpu.c:122:9: error: nested extern declaration of ‘kvm_loongarch_set_interrupt’ [-Werror=nested-externs] ../target/loongarch/cpu.c: In function ‘loongarch_cpu_reset_hold’: ../target/loongarch/cpu.c:557:9: error: implicit declaration of function ‘kvm_arch_reset_vcpu’; did you mean ‘kvm_arch_init_vcpu’? [-Werror=implicit-function-declaration] 557 | kvm_arch_reset_vcpu(env); | ^~~ | kvm_arch_init_vcpu ../target/loongarch/cpu.c:557:9: error: nested extern declaration of ‘kvm_arch_reset_vcpu’ [-Werror=nested-externs] cc1: all warnings being treated as errors I will move it out of '#ifdef CONFIG_KVM' Thanks. Song Gao +#include +#endif #ifdef CONFIG_TCG #include "exec/cpu_ldst.h" #include "tcg/tcg.h" @@ -113,7 +118,9 @@ void loongarch_cpu_set_irq(void *opaque, int irq, int level) return; } -if (tcg_enabled()) { +if (kvm_enabled()) { +kvm_loongarch_set_interrupt(cpu, irq, level); +} else if (tcg_enabled()) { env->CSR_ESTAT = deposit64(env->CSR_ESTAT, irq, 1, level != 0); if (FIELD_EX64(env->CSR_ESTAT, CSR_ESTAT, IS)) { cpu_interrupt(cs, CPU_INTERRUPT_HARD); diff --git a/target/loongarch/kvm/kvm.c b/target/loongarch/kvm/kvm.c index d2dab3fef4..bd33ec2114 100644 --- a/target/loongarch/kvm/kvm.c +++ b/target/loongarch/kvm/kvm.c @@ -748,6 +748,21 @@ int kvm_arch_handle_exit(CPUState *cs, struct kvm_run *run) return ret; } +int kvm_loongarch_set_interrupt(LoongArchCPU *cpu, int irq, int level) +{ +struct kvm_interrupt intr; +CPUState *cs = CPU(cpu); + +if (level) { +intr.irq = irq; +} else { +intr.irq = -irq; +} + +trace_kvm_set_intr(irq, level); +return kvm_vcpu_ioctl(cs, KVM_INTERRUPT, ); +} + void kvm_arch_accel_class_init(ObjectClass *oc) { } diff --git a/target/loongarch/trace-events b/target/loongarch/trace-events index 021839880e..dea11edc0f 100644 --- a/target/loongarch/trace-events +++ b/target/loongarch/trace-events @@ -12,3 +12,4 @@ kvm_failed_put_counter(const char *msg) "Failed to put counter into KVM: %s" kvm_failed_get_cpucfg(const char *msg) "Failed to get cpucfg from KVM: %s" kvm_failed_put_cpucfg(const char *msg) "Failed to put cpucfg into KVM: %s" kvm_arch_handle_exit(int num) "kvm arch handle exit, the reason number: %d" +kvm_set_intr(int irq, int level) "kvm set interrupt, irq num: %d, level: %d"
Re: [PATCH v4 0/9] Add loongarch kvm accel support
在 2024/1/10 下午5:42, Philippe Mathieu-Daudé 写道: Hi Song, On 10/1/24 03:46, gaosong wrote: 在 2024/1/5 下午3:57, Tianrui Zhao 写道: This series add loongarch kvm support, mainly implement some interfaces used by kvm, such as kvm_arch_get/set_regs, kvm_arch_handle_exit, kvm_loongarch_set_interrupt, etc. Tianrui Zhao (9): linux-headers: Synchronize linux headers from linux v6.7.0-rc8 target/loongarch: Define some kvm_arch interfaces target/loongarch: Supplement vcpu env initial when vcpu reset target/loongarch: Implement kvm get/set registers target/loongarch: Implement kvm_arch_init function target/loongarch: Implement kvm_arch_init_vcpu target/loongarch: Implement kvm_arch_handle_exit target/loongarch: Implement set vcpu intr for kvm target/loongarch: Add loongarch kvm into meson build Applied to loongarch-next. Sorry it took me some time to test this on a loongarch64 host. I made minor changes to patch #8, please consider the alternative: https://lore.kernel.org/qemu-devel/20240110094152.52138-1-phi...@linaro.org/ and https://lore.kernel.org/qemu-devel/20240110094152.52138-2-phi...@linaro.org/ Thank you , I wll apply them to loongarch-next. if no new problem with this series, I think we can merge it on this week. Thanks. Song Gao
Re: [PATCH v2 0/4] hw/loongarch/virt: Set iocsr address space per-board rather percpu
在 2023/12/15 下午6:03, Bibo Mao 写道: On LoongArch system, there is iocsr address space simliar system io address space on x86. And each cpu has its separate iocsr address space now, with this patch, iocsr address space is changed with per-board, and MemTxAttrs.requester_id is used to differentiate cpu cores. --- Changes in v2: 1. Add num-cpu property for extioi interrupt controller 2. Add post_load support for extioi vmstate to calculate sw_ipmap/sw_coremap info --- Bibo Mao (4): hw/intc/loongarch_ipi: Use MemTxAttrs interface for ipi ops hw/loongarch/virt: Set iocsr address space per-board rather than percpu hw/intc/loongarch_extioi: Add dynamic cpu number support hw/intc/loongarch_extioi: Add vmstate post_load support hw/intc/loongarch_extioi.c | 230 ++--- hw/intc/loongarch_ipi.c| 191 +++- hw/loongarch/virt.c| 94 include/hw/intc/loongarch_extioi.h | 12 +- include/hw/intc/loongarch_ipi.h| 3 +- include/hw/loongarch/virt.h| 3 + target/loongarch/cpu.c | 48 -- target/loongarch/cpu.h | 4 +- target/loongarch/iocsr_helper.c| 16 +- 9 files changed, 358 insertions(+), 243 deletions(-) Applied to loongarch-next. Thanks. Song Gao
Re: [PATCH v4 0/9] Add loongarch kvm accel support
在 2024/1/5 下午3:57, Tianrui Zhao 写道: The linux headers in this patch synchronized from linux kernel v6.7.0-rc8, and the loongarch kvm part of this patch series based on the header files. And the linux kernel has added the loongarch kvm support in master branch. This series add loongarch kvm support, mainly implement some interfaces used by kvm, such as kvm_arch_get/set_regs, kvm_arch_handle_exit, kvm_loongarch_set_interrupt, etc. Currently, we are able to boot LoongArch KVM Linux Guests. In loongarch VM, mmio devices and iocsr devices are emulated in user space such as APIC, IPI, pci devices, etc, other hardwares such as MMU, timer and csr are emulated in kernel. The running environment of LoongArch virt machine: 1. Get the Linux KVM environment of LoongArch in Linux mainline. make ARCH=loongarch CROSS_COMPILE=loongarch64-unknown-linux-gnu- loongson3_defconfig make ARCH=loongarch CROSS_COMPILE=loongarch64-unknown-linux-gnu- 2. Get the qemu source: https://github.com/loongson/qemu git checkout kvm-loongarch ./configure --target-list="loongarch64-softmmu" --enable-kvm make 3. Get uefi bios of LoongArch virt machine: Link: https://github.com/tianocore/edk2-platforms/tree/master/Platform/Loongson/LoongArchQemuPkg#readme 4. Also you can access the binary files we have already built: https://github.com/yangxiaojuan-loongson/qemu-binary The command to boot loongarch virt machine: $ qemu-system-loongarch64 -machine virt -m 4G -cpu la464 \ -smp 1 -bios QEMU_EFI.fd -kernel vmlinuz.efi -initrd ramdisk \ -serial stdio -monitor telnet:localhost:4495,server,nowait \ -append "root=/dev/ram rdinit=/sbin/init console=ttyS0,115200" \ --nographic Changes for v4: 1. Synchronize linux headers from linux v6.7.0-rc8. 2. Move kvm.c and kvm_loongarch.h into target/loongarch/kvm/ directory. 3. Add "#ifndef CONFIG_USER_ONLY" before loongarch_cpu_do_interrupt to fix compiling issue. 4. Remove "#ifdef CONFIG_TCG" before "#include "exec/cpu_ldst.h"" in fpu_helper.c, As it has been changed in other patches. Changes for v3: 1. Synchronize linux headers from linux v6.7.0-rc7. 2. Fix compiling error when config enable-kvm and disable-tcg at one time. Changes for v2: 1. Synchronize linux headers from linux v6.7.0-rc6. 2. Remove the stub function: kvm_loongarch_set_interrupt, as kvm_enabled 3. Move the kvm function such as kvm_arch_reset_vcpu from cpu.h to loongarch_kvm.h, and supplement "#include " in loongarch_kvm.h. Changes for v1: 1. Synchronous KVM headers about LoongArch KVM form linux kernel, as the LoongArch KVM patch series have been accepted by linux kernel. 2. Remove the KVM_GET/SET_ONE_UREG64 macro in target/loongarch, and use the common interface kvm_get/set_one_reg to replace it. 3. Resolve the compiling errors when LoongArch is built by other archs. Tianrui Zhao (9): linux-headers: Synchronize linux headers from linux v6.7.0-rc8 target/loongarch: Define some kvm_arch interfaces target/loongarch: Supplement vcpu env initial when vcpu reset target/loongarch: Implement kvm get/set registers target/loongarch: Implement kvm_arch_init function target/loongarch: Implement kvm_arch_init_vcpu target/loongarch: Implement kvm_arch_handle_exit target/loongarch: Implement set vcpu intr for kvm target/loongarch: Add loongarch kvm into meson build include/standard-headers/drm/drm_fourcc.h | 2 + include/standard-headers/linux/fuse.h | 10 +- include/standard-headers/linux/pci_regs.h | 24 +- include/standard-headers/linux/vhost_types.h | 7 + .../standard-headers/linux/virtio_config.h| 5 + include/standard-headers/linux/virtio_pci.h | 11 + linux-headers/asm-arm64/kvm.h | 32 + linux-headers/asm-generic/unistd.h| 14 +- linux-headers/asm-loongarch/bitsperlong.h | 1 + linux-headers/asm-loongarch/kvm.h | 108 +++ linux-headers/asm-loongarch/mman.h| 1 + linux-headers/asm-loongarch/unistd.h | 5 + linux-headers/asm-mips/unistd_n32.h | 4 + linux-headers/asm-mips/unistd_n64.h | 4 + linux-headers/asm-mips/unistd_o32.h | 4 + linux-headers/asm-powerpc/unistd_32.h | 4 + linux-headers/asm-powerpc/unistd_64.h | 4 + linux-headers/asm-riscv/kvm.h | 12 + linux-headers/asm-s390/unistd_32.h| 4 + linux-headers/asm-s390/unistd_64.h| 4 + linux-headers/asm-x86/unistd_32.h | 4 + linux-headers/asm-x86/unistd_64.h | 3 + linux-headers/asm-x86/unistd_x32.h| 3 + linux-headers/linux/iommufd.h | 180 +++- linux-headers/linux/kvm.h | 11 + linux-headers/linux/psp-sev.h | 1 + linux-headers/linux/stddef.h | 9 +- linux-headers/linux/userfaultfd.h | 9 +- linux-headers/linux/vfio.h
Re: [PATCH v4 9/9] target/loongarch: Add loongarch kvm into meson build
在 2024/1/5 下午3:58, Tianrui Zhao 写道: Add kvm.c into meson.build to compile it when kvm is configed. Meanwhile in meson.build, we set the kvm_targets to loongarch64-softmmu when the cpu is loongarch. And fix the compiling error when config is enable-kvm,disable-tcg. Signed-off-by: Tianrui Zhao Signed-off-by: xianglai li Reviewed-by: Richard Henderson --- meson.build | 2 ++ target/loongarch/kvm/meson.build | 1 + target/loongarch/meson.build | 1 + 3 files changed, 4 insertions(+) create mode 100644 target/loongarch/kvm/meson.build Reviewed-by: Song Gao Thanks. Song Gao diff --git a/meson.build b/meson.build index 445f2b7c2b..0c62b4156d 100644 --- a/meson.build +++ b/meson.build @@ -114,6 +114,8 @@ elif cpu in ['riscv32'] kvm_targets = ['riscv32-softmmu'] elif cpu in ['riscv64'] kvm_targets = ['riscv64-softmmu'] +elif cpu in ['loongarch64']Reviewed-by: Song Gao + kvm_targets = ['loongarch64-softmmu'] else kvm_targets = [] endif diff --git a/target/loongarch/kvm/meson.build b/target/loongarch/kvm/meson.build new file mode 100644 index 00..2266de6ca9 --- /dev/null +++ b/target/loongarch/kvm/meson.build @@ -0,0 +1 @@ +loongarch_ss.add(when: 'CONFIG_KVM', if_true: files('kvm.c')) diff --git a/target/loongarch/meson.build b/target/loongarch/meson.build index 18e8191e2b..7f86caf373 100644 --- a/target/loongarch/meson.build +++ b/target/loongarch/meson.build @@ -31,3 +31,4 @@ loongarch_ss.add_all(when: 'CONFIG_TCG', if_true: [loongarch_tcg_ss]) target_arch += {'loongarch': loongarch_ss} target_system_arch += {'loongarch': loongarch_system_ss} +subdir('kvm')
Re: [PATCH v2 4/4] hw/intc/loongarch_extioi: Add vmstate post_load support
在 2023/12/15 下午6:03, Bibo Mao 写道: There are elements sw_ipmap and sw_coremap, which is usd to speed up irq injection flow. They are saved and restored in vmstate during migration, indeed they can calculated from hw registers. Here post_load is added for get sw_ipmap and sw_coremap from extioi hw state. Signed-off-by: Bibo Mao --- hw/intc/loongarch_extioi.c | 120 +++-- 1 file changed, 76 insertions(+), 44 deletions(-) Reviewed-by: Song Gao Thanks. Song Gao diff --git a/hw/intc/loongarch_extioi.c b/hw/intc/loongarch_extioi.c index d9d5066c3f..e0fd57f962 100644 --- a/hw/intc/loongarch_extioi.c +++ b/hw/intc/loongarch_extioi.c @@ -130,12 +130,66 @@ static inline void extioi_enable_irq(LoongArchExtIOI *s, int index,\ } } +static inline void extioi_update_sw_coremap(LoongArchExtIOI *s, int irq, +uint64_t val, bool notify) +{ +int i, cpu; + +/* + * loongarch only support little endian, + * so we paresd the value with little endian. + */ +val = cpu_to_le64(val); + +for (i = 0; i < 4; i++) { +cpu = val & 0xff; +cpu = ctz32(cpu); +cpu = (cpu >= 4) ? 0 : cpu; +val = val >> 8; + +if (s->sw_coremap[irq + i] == cpu) { +continue; +} + +if (notify && test_bit(irq, (unsigned long *)s->isr)) { +/* + * lower irq at old cpu and raise irq at new cpu + */ +extioi_update_irq(s, irq + i, 0); +s->sw_coremap[irq + i] = cpu; +extioi_update_irq(s, irq + i, 1); +} else { +s->sw_coremap[irq + i] = cpu; +} +} +} + +static inline void extioi_update_sw_ipmap(LoongArchExtIOI *s, int index, + uint64_t val) +{ +int i; +uint8_t ipnum; + +/* + * loongarch only support little endian, + * so we paresd the value with little endian. + */ +val = cpu_to_le64(val); +for (i = 0; i < 4; i++) { +ipnum = val & 0xff; +ipnum = ctz32(ipnum); +ipnum = (ipnum >= 4) ? 0 : ipnum; +s->sw_ipmap[index * 4 + i] = ipnum; +val = val >> 8; +} +} + static MemTxResult extioi_writew(void *opaque, hwaddr addr, uint64_t val, unsigned size, MemTxAttrs attrs) { LoongArchExtIOI *s = LOONGARCH_EXTIOI(opaque); -int i, cpu, index, old_data, irq; +int cpu, index, old_data, irq; uint32_t offset; trace_loongarch_extioi_writew(addr, val); @@ -153,20 +207,7 @@ static MemTxResult extioi_writew(void *opaque, hwaddr addr, */ index = (offset - EXTIOI_IPMAP_START) >> 2; s->ipmap[index] = val; -/* - * loongarch only support little endian, - * so we paresd the value with little endian. - */ -val = cpu_to_le64(val); -for (i = 0; i < 4; i++) { -uint8_t ipnum; -ipnum = val & 0xff; -ipnum = ctz32(ipnum); -ipnum = (ipnum >= 4) ? 0 : ipnum; -s->sw_ipmap[index * 4 + i] = ipnum; -val = val >> 8; -} - +extioi_update_sw_ipmap(s, index, val); break; case EXTIOI_ENABLE_START ... EXTIOI_ENABLE_END - 1: index = (offset - EXTIOI_ENABLE_START) >> 2; @@ -205,33 +246,8 @@ static MemTxResult extioi_writew(void *opaque, hwaddr addr, irq = offset - EXTIOI_COREMAP_START; index = irq / 4; s->coremap[index] = val; -/* - * loongarch only support little endian, - * so we paresd the value with little endian. - */ -val = cpu_to_le64(val); - -for (i = 0; i < 4; i++) { -cpu = val & 0xff; -cpu = ctz32(cpu); -cpu = (cpu >= 4) ? 0 : cpu; -val = val >> 8; - -if (s->sw_coremap[irq + i] == cpu) { -continue; -} - -if (test_bit(irq, (unsigned long *)s->isr)) { -/* - * lower irq at old cpu and raise irq at new cpu - */ -extioi_update_irq(s, irq + i, 0); -s->sw_coremap[irq + i] = cpu; -extioi_update_irq(s, irq + i, 1); -} else { -s->sw_coremap[irq + i] = cpu; -} -} + +extioi_update_sw_coremap(s, irq, val, true); break; default: break; @@ -288,6 +304,23 @@ static void loongarch_extioi_finalize(Object *obj) g_free(s->cpu); } +static int vmstate_extioi_post_load(void *opaque, int version_id) +{ +LoongArchExtIOI *s = LOONGARCH_EXTIOI(opaque); +int i, start_irq; + +for (i = 0; i < (EXTIOI_IRQS / 4); i++) { +start_irq = i * 4; +extioi_update_sw_coremap(s, start_irq, s->coremap[i], false); +} + +for (i = 0; i < (EXTIOI_IRQS_IPMAP_SIZE / 4); i++) { +
Re: [PATCH v2 3/4] hw/intc/loongarch_extioi: Add dynamic cpu number support
在 2023/12/15 下午6:03, Bibo Mao 写道: On LoongArch physical machine, one extioi interrupt controller only supports 4 cpus. With processor more than 4 cpus, there are multiple extioi interrupt controllers; if interrupts need to be routed to other cpus, they are forwarded from extioi node0 to other extioi nodes. On virt machine model, there is simple extioi interrupt device model. All cpus can access register of extioi interrupt controller, however interrupt can only be route to 4 vcpu for compatible with old kernel. This patch adds dynamic cpu number support about extioi interrupt. With old kernel legacy extioi model is used, however kernel can detect and choose new route method in future, so that interrupt can be routed to all vcpus. Signed-off-by: Bibo Mao --- hw/intc/loongarch_extioi.c | 107 +++-- hw/loongarch/virt.c| 3 +- include/hw/intc/loongarch_extioi.h | 11 ++- 3 files changed, 81 insertions(+), 40 deletions(-) Reviewed-by: Song Gao Thanks. Song Gao diff --git a/hw/intc/loongarch_extioi.c b/hw/intc/loongarch_extioi.c index 77b4776958..d9d5066c3f 100644 --- a/hw/intc/loongarch_extioi.c +++ b/hw/intc/loongarch_extioi.c @@ -8,6 +8,7 @@ #include "qemu/osdep.h" #include "qemu/module.h" #include "qemu/log.h" +#include "qapi/error.h" #include "hw/irq.h" #include "hw/sysbus.h" #include "hw/loongarch/virt.h" @@ -32,23 +33,23 @@ static void extioi_update_irq(LoongArchExtIOI *s, int irq, int level) if (((s->enable[irq_index]) & irq_mask) == 0) { return; } -s->coreisr[cpu][irq_index] |= irq_mask; -found = find_first_bit(s->sw_isr[cpu][ipnum], EXTIOI_IRQS); -set_bit(irq, s->sw_isr[cpu][ipnum]); +s->cpu[cpu].coreisr[irq_index] |= irq_mask; +found = find_first_bit(s->cpu[cpu].sw_isr[ipnum], EXTIOI_IRQS); +set_bit(irq, s->cpu[cpu].sw_isr[ipnum]); if (found < EXTIOI_IRQS) { /* other irq is handling, need not update parent irq level */ return; } } else { -s->coreisr[cpu][irq_index] &= ~irq_mask; -clear_bit(irq, s->sw_isr[cpu][ipnum]); -found = find_first_bit(s->sw_isr[cpu][ipnum], EXTIOI_IRQS); +s->cpu[cpu].coreisr[irq_index] &= ~irq_mask; +clear_bit(irq, s->cpu[cpu].sw_isr[ipnum]); +found = find_first_bit(s->cpu[cpu].sw_isr[ipnum], EXTIOI_IRQS); if (found < EXTIOI_IRQS) { /* other irq is handling, need not update parent irq level */ return; } } -qemu_set_irq(s->parent_irq[cpu][ipnum], level); +qemu_set_irq(s->cpu[cpu].parent_irq[ipnum], level); } static void extioi_setirq(void *opaque, int irq, int level) @@ -96,7 +97,7 @@ static MemTxResult extioi_readw(void *opaque, hwaddr addr, uint64_t *data, index = (offset - EXTIOI_COREISR_START) >> 2; /* using attrs to get current cpu index */ cpu = attrs.requester_id; -*data = s->coreisr[cpu][index]; +*data = s->cpu[cpu].coreisr[index]; break; case EXTIOI_COREMAP_START ... EXTIOI_COREMAP_END - 1: index = (offset - EXTIOI_COREMAP_START) >> 2; @@ -189,8 +190,8 @@ static MemTxResult extioi_writew(void *opaque, hwaddr addr, index = (offset - EXTIOI_COREISR_START) >> 2; /* using attrs to get current cpu index */ cpu = attrs.requester_id; -old_data = s->coreisr[cpu][index]; -s->coreisr[cpu][index] = old_data & ~val; +old_data = s->cpu[cpu].coreisr[index]; +s->cpu[cpu].coreisr[index] = old_data & ~val; /* write 1 to clear interrupt */ old_data &= val; irq = ctz32(old_data); @@ -248,14 +249,61 @@ static const MemoryRegionOps extioi_ops = { .endianness = DEVICE_LITTLE_ENDIAN, }; -static const VMStateDescription vmstate_loongarch_extioi = { -.name = TYPE_LOONGARCH_EXTIOI, +static void loongarch_extioi_realize(DeviceState *dev, Error **errp) +{ +LoongArchExtIOI *s = LOONGARCH_EXTIOI(dev); +SysBusDevice *sbd = SYS_BUS_DEVICE(dev); +int i, pin; + +if (s->num_cpu == 0) { +error_setg(errp, "num-cpu must be at least 1"); +return; +} + +for (i = 0; i < EXTIOI_IRQS; i++) { +sysbus_init_irq(sbd, >irq[i]); +} + +qdev_init_gpio_in(dev, extioi_setirq, EXTIOI_IRQS); +memory_region_init_io(>extioi_system_mem, OBJECT(s), _ops, + s, "extioi_system_mem", 0x900); +sysbus_init_mmio(sbd, >extioi_system_mem); +s->cpu = g_new0(ExtIOICore, s->num_cpu); +if (s->cpu == NULL) { +error_setg(errp, "Memory allocation for ExtIOICore faile"); +return; +} + +for (i = 0; i < s->num_cpu; i++) { +for (pin = 0; pin < LS3A_INTC_IP; pin++) { +qdev_init_gpio_out(dev, >cpu[i].parent_irq[pin], 1); +} +} +} + +static void loongarch_extioi_finalize(Object *obj) +{ +
Re: [PATCH v2 2/4] hw/loongarch/virt: Set iocsr address space per-board rather than percpu
在 2023/12/15 下午6:03, Bibo Mao 写道: LoongArch system has iocsr address space, most iocsr registers are per-board, however some iocsr register spaces banked for percpu such as ipi mailbox and extioi interrupt status. For banked iocsr space, each cpu has the same iocsr space, but separate data. This patch changes iocsr address space per-board rather percpu, for iocsr registers specified for cpu, MemTxAttrs.requester_id can be parsed for the cpu. With this patches, the total address space on board will be simple, only iocsr address space and system memory, rather than the number of cpu and system memory. Signed-off-by: Bibo Mao --- hw/intc/loongarch_extioi.c | 3 - hw/intc/loongarch_ipi.c| 61 +++- hw/loongarch/virt.c| 91 ++ include/hw/intc/loongarch_extioi.h | 1 - include/hw/intc/loongarch_ipi.h| 3 +- include/hw/loongarch/virt.h| 3 + target/loongarch/cpu.c | 48 target/loongarch/cpu.h | 4 +- target/loongarch/iocsr_helper.c| 16 +++--- 9 files changed, 127 insertions(+), 103 deletions(-) Reviewed-by: Song Gao Thanks. Song Gao diff --git a/hw/intc/loongarch_extioi.c b/hw/intc/loongarch_extioi.c index 24fb3af8cc..77b4776958 100644 --- a/hw/intc/loongarch_extioi.c +++ b/hw/intc/loongarch_extioi.c @@ -282,9 +282,6 @@ static void loongarch_extioi_instance_init(Object *obj) qdev_init_gpio_in(DEVICE(obj), extioi_setirq, EXTIOI_IRQS); for (cpu = 0; cpu < EXTIOI_CPUS; cpu++) { -memory_region_init_io(>extioi_iocsr_mem[cpu], OBJECT(s), _ops, - s, "extioi_iocsr", 0x900); -sysbus_init_mmio(dev, >extioi_iocsr_mem[cpu]); for (pin = 0; pin < LS3A_INTC_IP; pin++) { qdev_init_gpio_out(DEVICE(obj), >parent_irq[cpu][pin], 1); } diff --git a/hw/intc/loongarch_ipi.c b/hw/intc/loongarch_ipi.c index 1d3449e77d..bca01c88f6 100644 --- a/hw/intc/loongarch_ipi.c +++ b/hw/intc/loongarch_ipi.c @@ -9,6 +9,7 @@ #include "hw/sysbus.h" #include "hw/intc/loongarch_ipi.h" #include "hw/irq.h" +#include "hw/qdev-properties.h" #include "qapi/error.h" #include "qemu/log.h" #include "exec/address-spaces.h" @@ -26,7 +27,7 @@ static MemTxResult loongarch_ipi_readl(void *opaque, hwaddr addr, uint64_t ret = 0; int index = 0; -s = >ipi_core; +s = >cpu[attrs.requester_id]; addr &= 0xff; switch (addr) { case CORE_STATUS_OFF: @@ -65,7 +66,7 @@ static void send_ipi_data(CPULoongArchState *env, uint64_t val, hwaddr addr, * if the mask is 0, we need not to do anything. */ if ((val >> 27) & 0xf) { -data = address_space_ldl(>address_space_iocsr, addr, +data = address_space_ldl(env->address_space_iocsr, addr, attrs, NULL); for (i = 0; i < 4; i++) { /* get mask for byte writing */ @@ -77,7 +78,7 @@ static void send_ipi_data(CPULoongArchState *env, uint64_t val, hwaddr addr, data &= mask; data |= (val >> 32) & ~mask; -address_space_stl(>address_space_iocsr, addr, +address_space_stl(env->address_space_iocsr, addr, data, attrs, NULL); } @@ -172,7 +173,7 @@ static MemTxResult loongarch_ipi_writel(void *opaque, hwaddr addr, uint64_t val, uint8_t vector; CPUState *cs; -s = >ipi_core; +s = >cpu[attrs.requester_id]; addr &= 0xff;loongarch_ipi_finalize trace_loongarch_ipi_write(size, (uint64_t)addr, val); switch (addr) { @@ -214,7 +215,6 @@ static MemTxResult loongarch_ipi_writel(void *opaque, hwaddr addr, uint64_t val, /* override requester_id */ attrs.requester_id = cs->cpu_index; -ipi = LOONGARCH_IPI(LOONGARCH_CPU(cs)->env.ipistate); loongarch_ipi_writel(ipi, CORE_SET_OFF, BIT(vector), 4, attrs); break; default: @@ -265,12 +265,18 @@ static const MemoryRegionOps loongarch_ipi64_ops = { .endianness = DEVICE_LITTLE_ENDIAN, }; -static void loongarch_ipi_init(Object *obj) +static void loongarch_ipi_realize(DeviceState *dev, Error **errp) { -LoongArchIPI *s = LOONGARCH_IPI(obj); -SysBusDevice *sbd = SYS_BUS_DEVICE(obj); +LoongArchIPI *s = LOONGARCH_IPI(dev); +SysBusDevice *sbd = SYS_BUS_DEVICE(dev); +int i; + +if (s->num_cpu == 0) { +error_setg(errp, "num-cpu must be at least 1"); +return; +} -memory_region_init_io(>ipi_iocsr_mem, obj, _ipi_ops, +memory_region_init_io(>ipi_iocsr_mem, OBJECT(dev), _ipi_ops, s, "loongarch_ipi_iocsr", 0x48); /* loongarch_ipi_iocsr performs re-entrant IO through ipi_send */ @@ -278,10 +284,20 @@ static void loongarch_ipi_init(Object *obj) sysbus_init_mmio(sbd, >ipi_iocsr_mem); -memory_region_init_io(>ipi64_iocsr_mem, obj, _ipi64_ops, +
Re: [PATCH v2 1/4] hw/intc/loongarch_ipi: Use MemTxAttrs interface for ipi ops
在 2023/12/15 下午6:03, Bibo Mao 写道: There are two interface pairs for MemoryRegionOps, read/write and read_with_attrs/write_with_attrs. The later is better for ipi device emulation since initial cpu can be parsed from attrs.requester_id. And requester_id can be overrided for IOCSR_IPI_SEND and mail_send function when it is to forward message to another vcpu. Signed-off-by: Bibo Mao --- hw/intc/loongarch_ipi.c | 136 +++- 1 file changed, 77 insertions(+), 59 deletions(-) Reviewed-by: Song Gao Thanks. Song Gao diff --git a/hw/intc/loongarch_ipi.c b/hw/intc/loongarch_ipi.c index 67858b521c..1d3449e77d 100644 --- a/hw/intc/loongarch_ipi.c +++ b/hw/intc/loongarch_ipi.c @@ -17,14 +17,16 @@ #include "target/loongarch/internals.h" #include "trace.h" -static void loongarch_ipi_writel(void *, hwaddr, uint64_t, unsigned); - -static uint64_t loongarch_ipi_readl(void *opaque, hwaddr addr, unsigned size) +static MemTxResult loongarch_ipi_readl(void *opaque, hwaddr addr, + uint64_t *data, + unsigned size, MemTxAttrs attrs) { -IPICore *s = opaque; +IPICore *s; +LoongArchIPI *ipi = opaque; uint64_t ret = 0; int index = 0; +s = >ipi_core; addr &= 0xff; switch (addr) { case CORE_STATUS_OFF: @@ -49,10 +51,12 @@ static uint64_t loongarch_ipi_readl(void *opaque, hwaddr addr, unsigned size) } trace_loongarch_ipi_read(size, (uint64_t)addr, ret); -return ret; +*data = ret; +return MEMTX_OK; } -static void send_ipi_data(CPULoongArchState *env, uint64_t val, hwaddr addr) +static void send_ipi_data(CPULoongArchState *env, uint64_t val, hwaddr addr, + MemTxAttrs attrs) { int i, mask = 0, data = 0; @@ -62,7 +66,7 @@ static void send_ipi_data(CPULoongArchState *env, uint64_t val, hwaddr addr) */ if ((val >> 27) & 0xf) { data = address_space_ldl(>address_space_iocsr, addr, - MEMTXATTRS_UNSPECIFIED, NULL); + attrs, NULL); for (i = 0; i < 4; i++) { /* get mask for byte writing */ if (val & (0x1 << (27 + i))) { @@ -74,7 +78,7 @@ static void send_ipi_data(CPULoongArchState *env, uint64_t val, hwaddr addr) data &= mask; data |= (val >> 32) & ~mask; address_space_stl(>address_space_iocsr, addr, - data, MEMTXATTRS_UNSPECIFIED, NULL); + data, attrs, NULL); } static int archid_cmp(const void *a, const void *b) @@ -103,80 +107,72 @@ static CPUState *ipi_getcpu(int arch_id) CPUArchId *archid; archid = find_cpu_by_archid(machine, arch_id); -return CPU(archid->cpu); -} - -static void ipi_send(uint64_t val) -{ -uint32_t cpuid; -uint8_t vector; -CPUState *cs; -LoongArchCPU *cpu; -LoongArchIPI *s; - -cpuid = extract32(val, 16, 10); -if (cpuid >= LOONGARCH_MAX_CPUS) { -trace_loongarch_ipi_unsupported_cpuid("IOCSR_IPI_SEND", cpuid); -return; +if (archid) { +return CPU(archid->cpu); } -/* IPI status vector */ -vector = extract8(val, 0, 5); - -cs = ipi_getcpu(cpuid); -cpu = LOONGARCH_CPU(cs); -s = LOONGARCH_IPI(cpu->env.ipistate); -loongarch_ipi_writel(>ipi_core, CORE_SET_OFF, BIT(vector), 4); +return NULL; } -static void mail_send(uint64_t val) +static MemTxResult mail_send(uint64_t val, MemTxAttrs attrs) { uint32_t cpuid; hwaddr addr; -CPULoongArchState *env; CPUState *cs; -LoongArchCPU *cpu; cpuid = extract32(val, 16, 10); if (cpuid >= LOONGARCH_MAX_CPUS) { trace_loongarch_ipi_unsupported_cpuid("IOCSR_MAIL_SEND", cpuid); -return; +return MEMTX_DECODE_ERROR; } -addr = 0x1020 + (val & 0x1c); cs = ipi_getcpu(cpuid); -cpu = LOONGARCH_CPU(cs); -env = >env; -send_ipi_data(env, val, addr); +if (cs == NULL) { +return MEMTX_DECODE_ERROR; +} + +/* override requester_id */ +addr = SMP_IPI_MAILBOX + CORE_BUF_20 + (val & 0x1c); +attrs.requester_id = cs->cpu_index; +send_ipi_data(_CPU(cs)->env, val, addr, attrs); +return MEMTX_OK; } -static void any_send(uint64_t val) +static MemTxResult any_send(uint64_t val, MemTxAttrs attrs) { uint32_t cpuid; hwaddr addr; -CPULoongArchState *env; CPUState *cs; -LoongArchCPU *cpu; cpuid = extract32(val, 16, 10); if (cpuid >= LOONGARCH_MAX_CPUS) { trace_loongarch_ipi_unsupported_cpuid("IOCSR_ANY_SEND", cpuid); -return; +return MEMTX_DECODE_ERROR; } -addr = val & 0x; cs = ipi_getcpu(cpuid); -cpu = LOONGARCH_CPU(cs); -env = >env; -send_ipi_data(env, val, addr); +if (cs == NULL) { +return MEMTX_DECODE_ERROR; +} + +
Re: [PATCH v3 11/46] hw/loongarch: use pci_init_nic_devices()
在 2024/1/9 上午4:26, David Woodhouse 写道: From: David Woodhouse Signed-off-by: David Woodhouse --- hw/loongarch/virt.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) Reviewed-by: Song Gao Thanks. Song Gao diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c index 4b7dc67a2d..c48804ac38 100644 --- a/hw/loongarch/virt.c +++ b/hw/loongarch/virt.c @@ -504,9 +504,7 @@ static void loongarch_devices_init(DeviceState *pch_pic, LoongArchMachineState * fdt_add_uart_node(lams); /* Network init */ -for (i = 0; i < nb_nics; i++) { -pci_nic_init_nofail(_table[i], pci_bus, mc->default_nic, NULL); -} +pci_init_nic_devices(pci_bus, mc->default_nic); /* * There are some invalid guest memory access.
Re: [PULL 0/2] loongarch-to-apply queue
在 2024/1/5 下午9:34, Peter Maydell 写道: On Fri, 5 Jan 2024 at 01:30, Song Gao wrote: The following changes since commit d328fef93ae757a0dd65ed786a4086e27952eef3: Merge tag 'pull-20231230' of https://gitlab.com/rth7680/qemu into staging (2024-01-04 10:23:34 +) are available in the Git repository at: https://gitlab.com/gaosong/qemu.git tags/pull-loongarch-20240105 for you to fetch changes up to 0cd8b379081fa71c23836052feb65da4685f8ec7: target/loongarch: move translate modules to tcg/ (2024-01-05 09:31:05 +0800) pull-loongarch-20240105 Song Gao (2): target/loongarch/meson: move gdbstub.c to loongarch.ss target/loongarch: move translate modules to tcg/ Hi; this fails to build, with ../target/loongarch/tcg/meson.build:1:3: ERROR: Unknown variable "config_all". (eg https://gitlab.com/qemu-project/qemu/-/jobs/5868662017) I think your pullreq has unfortunately got a conflict with the meson cleanup patches that I just applied from Paolo. Could you have a look at this and respin the pullreq, please? Sure, I will. Thanks. Song Gao.
Re: [PATCH v3 7/9] target/loongarch: Implement kvm_arch_handle_exit
在 2023/12/28 下午4:40, Tianrui Zhao 写道: Implement kvm_arch_handle_exit for loongarch. In this function, the KVM_EXIT_LOONGARCH_IOCSR is handled, we read or write the iocsr address space by the addr, length and is_write argument in kvm_run. Signed-off-by: Tianrui Zhao Signed-off-by: xianglai li Reviewed-by: Richard Henderson --- target/loongarch/kvm.c| 24 +++- target/loongarch/trace-events | 1 + 2 files changed, 24 insertions(+), 1 deletion(-) Reviewed-by: Song Gao Thanks. Song Gao diff --git a/target/loongarch/kvm.c b/target/loongarch/kvm.c index 85e7aeb083..d2dab3fef4 100644 --- a/target/loongarch/kvm.c +++ b/target/loongarch/kvm.c @@ -723,7 +723,29 @@ bool kvm_arch_cpu_check_are_resettable(void) int kvm_arch_handle_exit(CPUState *cs, struct kvm_run *run) { -return 0; +int ret = 0; +LoongArchCPU *cpu = LOONGARCH_CPU(cs); +CPULoongArchState *env = >env; +MemTxAttrs attrs = {}; + +attrs.requester_id = env_cpu(env)->cpu_index; + +trace_kvm_arch_handle_exit(run->exit_reason); +switch (run->exit_reason) { +case KVM_EXIT_LOONGARCH_IOCSR: +address_space_rw(>address_space_iocsr, + run->iocsr_io.phys_addr, + attrs, + run->iocsr_io.data, + run->iocsr_io.len, + run->iocsr_io.is_write); +break; +default: +ret = -1; +warn_report("KVM: unknown exit reason %d", run->exit_reason); +break; +} +return ret; } void kvm_arch_accel_class_init(ObjectClass *oc) diff --git a/target/loongarch/trace-events b/target/loongarch/trace-events index 937c3c7c0c..021839880e 100644 --- a/target/loongarch/trace-events +++ b/target/loongarch/trace-events @@ -11,3 +11,4 @@ kvm_failed_get_counter(const char *msg) "Failed to get counter from KVM: %s" kvm_failed_put_counter(const char *msg) "Failed to put counter into KVM: %s" kvm_failed_get_cpucfg(const char *msg) "Failed to get cpucfg from KVM: %s" kvm_failed_put_cpucfg(const char *msg) "Failed to put cpucfg into KVM: %s" +kvm_arch_handle_exit(int num) "kvm arch handle exit, the reason number: %d"
Re: [PATCH v3 4/9] target/loongarch: Implement kvm get/set registers
在 2023/12/28 下午4:40, Tianrui Zhao 写道: +static int kvm_loongarch_get_regs_fp(CPUState *cs) +{ +int ret, i; +struct kvm_fpu fpu; + +LoongArchCPU *cpu = LOONGARCH_CPU(cs); +CPULoongArchState *env = >env; + +ret = kvm_vcpu_ioctl(cs, KVM_GET_FPU, ); +if (ret < 0) { +trace_kvm_failed_get_fpu(strerror(errno)); +return ret; +} + +env->fcsr0 = fpu.fcsr; +for (i = 0; i < 32; i++) { +env->fpr[i].vreg.UD[0] = fpu.fpr[i].val64[0]; +} +for (i = 0; i < 8; i++) { +env->cf[i] = fpu.fcc & 0xFF; +fpu.fcc = fpu.fcc >> 8; +} + Use write_fcc(env, fpu.fcc) +return ret; +} + +static int kvm_loongarch_put_regs_fp(CPUState *cs) +{ +int ret, i; +struct kvm_fpu fpu; + +LoongArchCPU *cpu = LOONGARCH_CPU(cs); +CPULoongArchState *env = >env; + +fpu.fcsr = env->fcsr0; +fpu.fcc = 0; +for (i = 0; i < 32; i++) { +fpu.fpr[i].val64[0] = env->fpr[i].vreg.UD[0]; +} + +for (i = 0; i < 8; i++) { +fpu.fcc |= env->cf[i] << (8 * i); +} + Use fpu.fcc = read_fcc(env) +ret = kvm_vcpu_ioctl(cs, KVM_SET_FPU, ); +if (ret < 0) { +trace_kvm_failed_put_fpu(strerror(errno)); +} + +return ret; +}
Re: [PATCH v3 6/9] target/loongarch: Implement kvm_arch_init_vcpu
在 2023/12/28 下午4:40, Tianrui Zhao 写道: Implement kvm_arch_init_vcpu interface for loongarch, in this function, we register VM change state handler. And when VM state changes to running, the counter value should be put into kvm to keep consistent with kvm, and when state change to stop, counter value should be refreshed from kvm. Signed-off-by: Tianrui Zhao Signed-off-by: xianglai li --- target/loongarch/cpu.h| 2 ++ target/loongarch/kvm.c| 23 +++ target/loongarch/trace-events | 2 ++ 3 files changed, 27 insertions(+) Reviewed-by: Song Gao Thanks. Song Gao diff --git a/target/loongarch/cpu.h b/target/loongarch/cpu.h index f4a89bd626..8ebd6fa1a7 100644 --- a/target/loongarch/cpu.h +++ b/target/loongarch/cpu.h @@ -381,6 +381,8 @@ struct ArchCPU { /* 'compatible' string for this CPU for Linux device trees */ const char *dtb_compatible; +/* used by KVM_REG_LOONGARCH_COUNTER ioctl to access guest time counters */ +uint64_t kvm_state_counter; }; /** diff --git a/target/loongarch/kvm.c b/target/loongarch/kvm.c index 29944b9ef8..85e7aeb083 100644 --- a/target/loongarch/kvm.c +++ b/target/loongarch/kvm.c @@ -617,8 +617,31 @@ int kvm_arch_put_registers(CPUState *cs, int level) return ret; } +static void kvm_loongarch_vm_stage_change(void *opaque, bool running, + RunState state) +{ +int ret; +CPUState *cs = opaque; +LoongArchCPU *cpu = LOONGARCH_CPU(cs); + +if (running) { +ret = kvm_set_one_reg(cs, KVM_REG_LOONGARCH_COUNTER, + >kvm_state_counter); +if (ret < 0) { +trace_kvm_failed_put_counter(strerror(errno)); +} +} else { +ret = kvm_get_one_reg(cs, KVM_REG_LOONGARCH_COUNTER, + >kvm_state_counter); +if (ret < 0) { +trace_kvm_failed_get_counter(strerror(errno)); +} +} +} + int kvm_arch_init_vcpu(CPUState *cs) { +qemu_add_vm_change_state_handler(kvm_loongarch_vm_stage_change, cs); return 0; } diff --git a/target/loongarch/trace-events b/target/loongarch/trace-events index 6827ab566a..937c3c7c0c 100644 --- a/target/loongarch/trace-events +++ b/target/loongarch/trace-events @@ -7,5 +7,7 @@ kvm_failed_get_fpu(const char *msg) "Failed to get fpu from KVM: %s" kvm_failed_put_fpu(const char *msg) "Failed to put fpu into KVM: %s" kvm_failed_get_mpstate(const char *msg) "Failed to get mp_state from KVM: %s" kvm_failed_put_mpstate(const char *msg) "Failed to put mp_state into KVM: %s" +kvm_failed_get_counter(const char *msg) "Failed to get counter from KVM: %s" +kvm_failed_put_counter(const char *msg) "Failed to put counter into KVM: %s" kvm_failed_get_cpucfg(const char *msg) "Failed to get cpucfg from KVM: %s" kvm_failed_put_cpucfg(const char *msg) "Failed to put cpucfg into KVM: %s"
Re: [PATCH v3 5/9] target/loongarch: Implement kvm_arch_init function
在 2023/12/28 下午4:40, Tianrui Zhao 写道: Implement the kvm_arch_init of loongarch, in the function, the KVM_CAP_MP_STATE cap is checked by kvm ioctl. Signed-off-by: Tianrui Zhao Signed-off-by: xianglai li Reviewed-by: Richard Henderson --- target/loongarch/kvm.c | 1 + 1 file changed, 1 insertion(+) Reviewed-by: Song Gao Thanks. Song Gao diff --git a/target/loongarch/kvm.c b/target/loongarch/kvm.c index e7c9ef830c..29944b9ef8 100644 --- a/target/loongarch/kvm.c +++ b/target/loongarch/kvm.c @@ -665,6 +665,7 @@ int kvm_arch_get_default_type(MachineState *ms) int kvm_arch_init(MachineState *ms, KVMState *s) { +cap_has_mp_state = kvm_check_extension(s, KVM_CAP_MP_STATE); return 0; }
Re: [PATCH v3 4/9] target/loongarch: Implement kvm get/set registers
在 2023/12/28 下午4:40, Tianrui Zhao 写道: Implement kvm_arch_get/set_registers interfaces, many regs can be get/set in the function, such as core regs, csr regs, fpu regs, mp state, etc. Signed-off-by: Tianrui Zhao Signed-off-by: xianglai li --- meson.build | 1 + target/loongarch/cpu.c| 3 + target/loongarch/cpu.h| 1 + target/loongarch/fpu_helper.c | 2 + target/loongarch/internals.h | 5 +- target/loongarch/kvm.c| 580 +- target/loongarch/trace-events | 11 + target/loongarch/trace.h | 1 + 8 files changed, 601 insertions(+), 3 deletions(-) create mode 100644 target/loongarch/trace-events create mode 100644 target/loongarch/trace.h Reviewed-by: Song Gao Thanks. Song Gao diff --git a/meson.build b/meson.build index 6c77d9687d..445f2b7c2b 100644 --- a/meson.build +++ b/meson.build @@ -3358,6 +3358,7 @@ if have_system or have_user 'target/hppa', 'target/i386', 'target/i386/kvm', +'target/loongarch', 'target/mips/tcg', 'target/nios2', 'target/ppc', diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c index 4432a0081d..83899c673f 100644 --- a/target/loongarch/cpu.c +++ b/target/loongarch/cpu.c @@ -555,6 +555,9 @@ static void loongarch_cpu_reset_hold(Object *obj) #ifndef CONFIG_USER_ONLY env->pc = 0x1c00; memset(env->tlb, 0, sizeof(env->tlb)); +if (kvm_enabled()) { +kvm_arch_reset_vcpu(env); +} #endif restore_fp_status(env); diff --git a/target/loongarch/cpu.h b/target/loongarch/cpu.h index f6d5ef0852..f4a89bd626 100644 --- a/target/loongarch/cpu.h +++ b/target/loongarch/cpu.h @@ -360,6 +360,7 @@ typedef struct CPUArchState { MemoryRegion iocsr_mem; bool load_elf; uint64_t elf_address; +uint32_t mp_state; /* Store ipistate to access from this struct */ DeviceState *ipistate; #endif diff --git a/target/loongarch/fpu_helper.c b/target/loongarch/fpu_helper.c index f6753c5875..1b71ea46d3 100644 --- a/target/loongarch/fpu_helper.c +++ b/target/loongarch/fpu_helper.c @@ -9,7 +9,9 @@ #include "cpu.h" #include "exec/helper-proto.h" #include "exec/exec-all.h" +#ifdef CONFIG_TCG #include "exec/cpu_ldst.h" +#endif #include "fpu/softfloat.h" #include "internals.h" diff --git a/target/loongarch/internals.h b/target/loongarch/internals.h index c492863cc5..0beb034748 100644 --- a/target/loongarch/internals.h +++ b/target/loongarch/internals.h @@ -31,8 +31,10 @@ void G_NORETURN do_raise_exception(CPULoongArchState *env, const char *loongarch_exception_name(int32_t exception); +#ifdef CONFIG_TCG int ieee_ex_to_loongarch(int xcpt); void restore_fp_status(CPULoongArchState *env); +#endif #ifndef CONFIG_USER_ONLY extern const VMStateDescription vmstate_loongarch_cpu; @@ -44,12 +46,13 @@ uint64_t cpu_loongarch_get_constant_timer_counter(LoongArchCPU *cpu); uint64_t cpu_loongarch_get_constant_timer_ticks(LoongArchCPU *cpu); void cpu_loongarch_store_constant_timer_config(LoongArchCPU *cpu, uint64_t value); - +#ifdef CONFIG_TCG bool loongarch_cpu_tlb_fill(CPUState *cs, vaddr address, int size, MMUAccessType access_type, int mmu_idx, bool probe, uintptr_t retaddr); hwaddr loongarch_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr); +#endif #endif /* !CONFIG_USER_ONLY */ uint64_t read_fcc(CPULoongArchState *env); diff --git a/target/loongarch/kvm.c b/target/loongarch/kvm.c index 0d67322fd9..e7c9ef830c 100644 --- a/target/loongarch/kvm.c +++ b/target/loongarch/kvm.c @@ -26,19 +26,595 @@ #include "sysemu/runstate.h" #include "cpu-csr.h" #include "kvm_loongarch.h" +#include "trace.h" static bool cap_has_mp_state; const KVMCapabilityInfo kvm_arch_required_capabilities[] = { KVM_CAP_LAST_INFO }; +static int kvm_loongarch_get_regs_core(CPUState *cs) +{ +int ret = 0; +int i; +struct kvm_regs regs; +LoongArchCPU *cpu = LOONGARCH_CPU(cs); +CPULoongArchState *env = >env; + +/* Get the current register set as KVM seems it */ +ret = kvm_vcpu_ioctl(cs, KVM_GET_REGS, ); +if (ret < 0) { +trace_kvm_failed_get_regs_core(strerror(errno)); +return ret; +} +/* gpr[0] value is always 0 */ +env->gpr[0] = 0; +for (i = 1; i < 32; i++) { +env->gpr[i] = regs.gpr[i]; +} + +env->pc = regs.pc; +return ret; +} + +static int kvm_loongarch_put_regs_core(CPUState *cs) +{ +int ret = 0; +int i; +struct kvm_regs regs; +LoongArchCPU *cpu = LOONGARCH_CPU(cs); +CPULoongArchState *env = >env; + +/* Set the registers based on QEMU's view of things */ +for (i = 0; i < 32; i++) { +regs.gpr[i] = env->gpr[i]; +} + +regs.pc = env->pc; +ret = kvm_vcpu_ioctl(cs, KVM_SET_REGS, ); +if (ret < 0) { +
Re: [PATCH v3 2/9] target/loongarch: Define some kvm_arch interfaces
在 2023/12/28 下午4:40, Tianrui Zhao 写道: Define some functions in target/loongarch/kvm.c, such as kvm_arch_put_registers, kvm_arch_get_registers and kvm_arch_handle_exit, etc. which are needed by kvm/kvm-all.c. Now the most functions has no content and they will be implemented in the next patches. Signed-off-by: Tianrui Zhao Signed-off-by: xianglai li Reviewed-by: Richard Henderson --- target/loongarch/kvm.c | 131 + 1 file changed, 131 insertions(+) create mode 100644 target/loongarch/kvm.c Reviewed-by: Song Gao Thanks. Song Gao diff --git a/target/loongarch/kvm.c b/target/loongarch/kvm.c new file mode 100644 index 00..0d67322fd9 --- /dev/null +++ b/target/loongarch/kvm.c @@ -0,0 +1,131 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * QEMU LoongArch KVM + * + * Copyright (c) 2023 Loongson Technology Corporation Limited + */ + +#include "qemu/osdep.h" +#include +#include + +#include "qemu/timer.h" +#include "qemu/error-report.h" +#include "qemu/main-loop.h" +#include "sysemu/sysemu.h" +#include "sysemu/kvm.h" +#include "sysemu/kvm_int.h" +#include "hw/pci/pci.h" +#include "exec/memattrs.h" +#include "exec/address-spaces.h" +#include "hw/boards.h" +#include "hw/irq.h" +#include "qemu/log.h" +#include "hw/loader.h" +#include "migration/migration.h" +#include "sysemu/runstate.h" +#include "cpu-csr.h" +#include "kvm_loongarch.h" + +static bool cap_has_mp_state; +const KVMCapabilityInfo kvm_arch_required_capabilities[] = { +KVM_CAP_LAST_INFO +}; + +int kvm_arch_get_registers(CPUState *cs) +{ +return 0; +} +int kvm_arch_put_registers(CPUState *cs, int level) +{ +return 0; +} + +int kvm_arch_init_vcpu(CPUState *cs) +{ +return 0; +} + +int kvm_arch_destroy_vcpu(CPUState *cs) +{ +return 0; +} + +unsigned long kvm_arch_vcpu_id(CPUState *cs) +{ +return cs->cpu_index; +} + +int kvm_arch_release_virq_post(int virq) +{ +return 0; +} + +int kvm_arch_msi_data_to_gsi(uint32_t data) +{ +abort(); +} + +int kvm_arch_fixup_msi_route(struct kvm_irq_routing_entry *route, + uint64_t address, uint32_t data, PCIDevice *dev) +{ +return 0; +} + +int kvm_arch_add_msi_route_post(struct kvm_irq_routing_entry *route, +int vector, PCIDevice *dev) +{ +return 0; +} + +void kvm_arch_init_irq_routing(KVMState *s) +{ +} + +int kvm_arch_get_default_type(MachineState *ms) +{ +return 0; +} + +int kvm_arch_init(MachineState *ms, KVMState *s) +{ +return 0; +} + +int kvm_arch_irqchip_create(KVMState *s) +{ +return 0; +} + +void kvm_arch_pre_run(CPUState *cs, struct kvm_run *run) +{ +} + +MemTxAttrs kvm_arch_post_run(CPUState *cs, struct kvm_run *run) +{ +return MEMTXATTRS_UNSPECIFIED; +} + +int kvm_arch_process_async_events(CPUState *cs) +{ +return cs->halted; +} + +bool kvm_arch_stop_on_emulation_error(CPUState *cs) +{ +return true; +} + +bool kvm_arch_cpu_check_are_resettable(void) +{ +return true; +} + +int kvm_arch_handle_exit(CPUState *cs, struct kvm_run *run) +{ +return 0; +} + +void kvm_arch_accel_class_init(ObjectClass *oc) +{ +}
Re: [PATCH v3 3/9] target/loongarch: Supplement vcpu env initial when vcpu reset
在 2023/12/28 下午4:40, Tianrui Zhao 写道: Supplement vcpu env initial when vcpu reset, including init vcpu CSR_CPUID,CSR_TID to cpu->cpu_index. The two regs will be used in kvm_get/set_csr_ioctl. Signed-off-by: Tianrui Zhao Signed-off-by: xianglai li --- target/loongarch/cpu.c | 2 ++ target/loongarch/cpu.h | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) Reviewed-by: Song Gao Thanks. Song Gao diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c index b26187dfde..4432a0081d 100644 --- a/target/loongarch/cpu.c +++ b/target/loongarch/cpu.c @@ -533,10 +533,12 @@ static void loongarch_cpu_reset_hold(Object *obj) env->CSR_ESTAT = env->CSR_ESTAT & (~MAKE_64BIT_MASK(0, 2)); env->CSR_RVACFG = FIELD_DP64(env->CSR_RVACFG, CSR_RVACFG, RBITS, 0); +env->CSR_CPUID = cs->cpu_index; env->CSR_TCFG = FIELD_DP64(env->CSR_TCFG, CSR_TCFG, EN, 0); env->CSR_LLBCTL = FIELD_DP64(env->CSR_LLBCTL, CSR_LLBCTL, KLO, 0); env->CSR_TLBRERA = FIELD_DP64(env->CSR_TLBRERA, CSR_TLBRERA, ISTLBR, 0); env->CSR_MERRCTL = FIELD_DP64(env->CSR_MERRCTL, CSR_MERRCTL, ISMERR, 0); +env->CSR_TID = cs->cpu_index; env->CSR_PRCFG3 = FIELD_DP64(env->CSR_PRCFG3, CSR_PRCFG3, TLB_TYPE, 2); env->CSR_PRCFG3 = FIELD_DP64(env->CSR_PRCFG3, CSR_PRCFG3, MTLB_ENTRY, 63); diff --git a/target/loongarch/cpu.h b/target/loongarch/cpu.h index 00d1fba597..f6d5ef0852 100644 --- a/target/loongarch/cpu.h +++ b/target/loongarch/cpu.h @@ -319,6 +319,7 @@ typedef struct CPUArchState { uint64_t CSR_PWCH; uint64_t CSR_STLBPS; uint64_t CSR_RVACFG; +uint64_t CSR_CPUID; uint64_t CSR_PRCFG1; uint64_t CSR_PRCFG2; uint64_t CSR_PRCFG3; @@ -350,7 +351,6 @@ typedef struct CPUArchState { uint64_t CSR_DBG; uint64_t CSR_DERA; uint64_t CSR_DSAVE; -uint64_t CSR_CPUID; #ifndef CONFIG_USER_ONLY LoongArchTLB tlb[LOONGARCH_TLB_MAX];
Re: [PATCH v3 1/9] linux-headers: Synchronize linux headers from linux v6.7.0-rc7
在 2023/12/28 下午4:40, Tianrui Zhao 写道: Use the scripts/update-linux-headers.sh to synchronize linux headers from linux v6.7.0-rc7. We mainly want to add the loongarch linux headers and then add the loongarch kvm support based on it. Signed-off-by: Tianrui Zhao --- include/standard-headers/drm/drm_fourcc.h | 2 + include/standard-headers/linux/fuse.h | 10 +- include/standard-headers/linux/pci_regs.h | 24 ++- include/standard-headers/linux/vhost_types.h | 7 + .../standard-headers/linux/virtio_config.h| 5 + include/standard-headers/linux/virtio_pci.h | 11 ++ linux-headers/asm-arm64/kvm.h | 32 linux-headers/asm-generic/unistd.h| 14 +- linux-headers/asm-loongarch/bitsperlong.h | 1 + linux-headers/asm-loongarch/kvm.h | 108 +++ linux-headers/asm-loongarch/mman.h| 1 + linux-headers/asm-loongarch/unistd.h | 5 + linux-headers/asm-mips/unistd_n32.h | 4 + linux-headers/asm-mips/unistd_n64.h | 4 + linux-headers/asm-mips/unistd_o32.h | 4 + linux-headers/asm-powerpc/unistd_32.h | 4 + linux-headers/asm-powerpc/unistd_64.h | 4 + linux-headers/asm-riscv/kvm.h | 12 ++ linux-headers/asm-s390/unistd_32.h| 4 + linux-headers/asm-s390/unistd_64.h| 4 + linux-headers/asm-x86/unistd_32.h | 4 + linux-headers/asm-x86/unistd_64.h | 3 + linux-headers/asm-x86/unistd_x32.h| 3 + linux-headers/linux/iommufd.h | 180 +- linux-headers/linux/kvm.h | 11 ++ linux-headers/linux/psp-sev.h | 1 + linux-headers/linux/stddef.h | 9 +- linux-headers/linux/userfaultfd.h | 9 +- linux-headers/linux/vfio.h| 47 +++-- linux-headers/linux/vhost.h | 8 + 30 files changed, 504 insertions(+), 31 deletions(-) create mode 100644 linux-headers/asm-loongarch/bitsperlong.h create mode 100644 linux-headers/asm-loongarch/kvm.h create mode 100644 linux-headers/asm-loongarch/mman.h create mode 100644 linux-headers/asm-loongarch/unistd.h Acked-by: Song Gao Thanks. Song Gao diff --git a/include/standard-headers/drm/drm_fourcc.h b/include/standard-headers/drm/drm_fourcc.h index 72279f4d25..3afb70160f 100644 --- a/include/standard-headers/drm/drm_fourcc.h +++ b/include/standard-headers/drm/drm_fourcc.h @@ -322,6 +322,8 @@ extern "C" { * index 1 = Cr:Cb plane, [39:0] Cr1:Cb1:Cr0:Cb0 little endian */ #define DRM_FORMAT_NV15 fourcc_code('N', 'V', '1', '5') /* 2x2 subsampled Cr:Cb plane */ +#define DRM_FORMAT_NV20fourcc_code('N', 'V', '2', '0') /* 2x1 subsampled Cr:Cb plane */ +#define DRM_FORMAT_NV30fourcc_code('N', 'V', '3', '0') /* non-subsampled Cr:Cb plane */ /* * 2 plane YCbCr MSB aligned diff --git a/include/standard-headers/linux/fuse.h b/include/standard-headers/linux/fuse.h index 6b9793842c..fc0dcd10ae 100644 --- a/include/standard-headers/linux/fuse.h +++ b/include/standard-headers/linux/fuse.h @@ -209,7 +209,7 @@ * - add FUSE_HAS_EXPIRE_ONLY * * 7.39 - * - add FUSE_DIRECT_IO_RELAX + * - add FUSE_DIRECT_IO_ALLOW_MMAP * - add FUSE_STATX and related structures */ @@ -405,8 +405,7 @@ struct fuse_file_lock { * FUSE_CREATE_SUPP_GROUP: add supplementary group info to create, mkdir, *symlink and mknod (single group that matches parent) * FUSE_HAS_EXPIRE_ONLY: kernel supports expiry-only entry invalidation - * FUSE_DIRECT_IO_RELAX: relax restrictions in FOPEN_DIRECT_IO mode, for now - * allow shared mmap + * FUSE_DIRECT_IO_ALLOW_MMAP: allow shared mmap in FOPEN_DIRECT_IO mode. */ #define FUSE_ASYNC_READ (1 << 0) #define FUSE_POSIX_LOCKS (1 << 1) @@ -445,7 +444,10 @@ struct fuse_file_lock { #define FUSE_HAS_INODE_DAX(1ULL << 33) #define FUSE_CREATE_SUPP_GROUP(1ULL << 34) #define FUSE_HAS_EXPIRE_ONLY (1ULL << 35) -#define FUSE_DIRECT_IO_RELAX (1ULL << 36) +#define FUSE_DIRECT_IO_ALLOW_MMAP (1ULL << 36) + +/* Obsolete alias for FUSE_DIRECT_IO_ALLOW_MMAP */ +#define FUSE_DIRECT_IO_RELAX FUSE_DIRECT_IO_ALLOW_MMAP /** * CUSE INIT request/reply flags diff --git a/include/standard-headers/linux/pci_regs.h b/include/standard-headers/linux/pci_regs.h index e5f558d964..a39193213f 100644 --- a/include/standard-headers/linux/pci_regs.h +++ b/include/standard-headers/linux/pci_regs.h @@ -80,6 +80,7 @@ #define PCI_HEADER_TYPE_NORMAL 0 #define PCI_HEADER_TYPE_BRIDGE 1 #define PCI_HEADER_TYPE_CARDBUS 2 +#define PCI_HEADER_TYPE_MFD 0x80/* Multi-Function Device (possible) */ #define PCI_BIST 0x0f /* 8 bits */ #define PCI_BIST_CODE_MASK 0x0f/* Return
Re: [PATCH v2 1/2] target/loongarch/meson: move gdbstub.c to loongarch.ss
在 2024/1/2 下午5:46, Philippe Mathieu-Daudé 写道: On 2/1/24 03:01, Song Gao wrote: gdbstub.c is not specific to TCG and can be used by other accelerators, such as KVM accelerator Suggested-by: Philippe Mathieu-Daudé I didn't really suggested the change but the split ;) Ah, I can drop it for pull request. Thanks. Song Gao. Reviewed-by: Philippe Mathieu-Daudé Signed-off-by: Song Gao --- target/loongarch/meson.build | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
Re: [PATCH v3 8/9] target/loongarch: Implement set vcpu intr for kvm
This patch also broken 'loongarch64-linux-user' build 在 2023/12/28 下午4:40, Tianrui Zhao 写道: Implement loongarch kvm set vcpu interrupt interface, when a irq is set in vcpu, we use the KVM_INTERRUPT ioctl to set intr into kvm. Signed-off-by: Tianrui Zhao Signed-off-by: xianglai li --- target/loongarch/cpu.c | 32 +++- target/loongarch/kvm.c | 15 +++ target/loongarch/kvm_loongarch.h | 16 target/loongarch/trace-events| 1 + 4 files changed, 55 insertions(+), 9 deletions(-) create mode 100644 target/loongarch/kvm_loongarch.h diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c index 83899c673f..caf82f9133 100644 --- a/target/loongarch/cpu.c +++ b/target/loongarch/cpu.c @@ -11,7 +11,6 @@ #include "qapi/error.h" #include "qemu/module.h" #include "sysemu/qtest.h" -#include "exec/cpu_ldst.h" #include "exec/exec-all.h" #include "cpu.h" #include "internals.h" @@ -20,8 +19,16 @@ #ifndef CONFIG_USER_ONLY #include "sysemu/reset.h" #endif -#include "tcg/tcg.h" #include "vec.h" +#include "sysemu/kvm.h" +#include "kvm_loongarch.h" +#ifdef CONFIG_KVM +#include +#endif +#ifdef CONFIG_TCG +#include "exec/cpu_ldst.h" +#include "tcg/tcg.h" +#endif const char * const regnames[32] = { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", @@ -110,12 +117,15 @@ void loongarch_cpu_set_irq(void *opaque, int irq, int level) return; } -env->CSR_ESTAT = deposit64(env->CSR_ESTAT, irq, 1, level != 0); - -if (FIELD_EX64(env->CSR_ESTAT, CSR_ESTAT, IS)) { -cpu_interrupt(cs, CPU_INTERRUPT_HARD); +if (kvm_enabled()) { +kvm_loongarch_set_interrupt(cpu, irq, level); } else { -cpu_reset_interrupt(cs, CPU_INTERRUPT_HARD); +env->CSR_ESTAT = deposit64(env->CSR_ESTAT, irq, 1, level != 0); +if (FIELD_EX64(env->CSR_ESTAT, CSR_ESTAT, IS)) { +cpu_interrupt(cs, CPU_INTERRUPT_HARD); +} else { +cpu_reset_interrupt(cs, CPU_INTERRUPT_HARD); +} } } @@ -140,7 +150,9 @@ static inline bool cpu_loongarch_hw_interrupts_pending(CPULoongArchState *env) return (pending & status) != 0; } +#endif +#ifdef CONFIG_TCG here +#ifndef CONFIG_USER_ONLY static void loongarch_cpu_do_interrupt(CPUState *cs) { LoongArchCPU *cpu = LOONGARCH_CPU(cs); @@ -320,9 +332,7 @@ static bool loongarch_cpu_exec_interrupt(CPUState *cs, int interrupt_request) } return false; } -#endif -#ifdef CONFIG_TCG here +#endif Otherwise Reviewed-by: Song Gao Thanks. Song Gao static void loongarch_cpu_synchronize_from_tb(CPUState *cs, const TranslationBlock *tb) { @@ -560,7 +570,9 @@ static void loongarch_cpu_reset_hold(Object *obj) } #endif +#ifdef CONFIG_TCG restore_fp_status(env); +#endif cs->exception_index = -1; } @@ -802,7 +814,9 @@ static struct TCGCPUOps loongarch_tcg_ops = { #include "hw/core/sysemu-cpu-ops.h" static const struct SysemuCPUOps loongarch_sysemu_ops = { +#ifdef CONFIG_TCG .get_phys_page_debug = loongarch_cpu_get_phys_page_debug, +#endif }; static int64_t loongarch_cpu_get_arch_id(CPUState *cs) diff --git a/target/loongarch/kvm.c b/target/loongarch/kvm.c index d2dab3fef4..bd33ec2114 100644 --- a/target/loongarch/kvm.c +++ b/target/loongarch/kvm.c @@ -748,6 +748,21 @@ int kvm_arch_handle_exit(CPUState *cs, struct kvm_run *run) return ret; } +int kvm_loongarch_set_interrupt(LoongArchCPU *cpu, int irq, int level) +{ +struct kvm_interrupt intr; +CPUState *cs = CPU(cpu); + +if (level) { +intr.irq = irq; +} else { +intr.irq = -irq; +} + +trace_kvm_set_intr(irq, level); +return kvm_vcpu_ioctl(cs, KVM_INTERRUPT, ); +} + void kvm_arch_accel_class_init(ObjectClass *oc) { } diff --git a/target/loongarch/kvm_loongarch.h b/target/loongarch/kvm_loongarch.h new file mode 100644 index 00..d945b6bb82 --- /dev/null +++ b/target/loongarch/kvm_loongarch.h @@ -0,0 +1,16 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * QEMU LoongArch kvm interface + * + * Copyright (c) 2023 Loongson Technology Corporation Limited + */ + +#include "cpu.h" + +#ifndef QEMU_KVM_LOONGARCH_H +#define QEMU_KVM_LOONGARCH_H + +int kvm_loongarch_set_interrupt(LoongArchCPU *cpu, int irq, int level); +void kvm_arch_reset_vcpu(CPULoongArchState *env); + +#endif diff --git a/target/loongarch/trace-events b/target/loongarch/trace-events index 021839880e..dea11edc0f 100644 --- a/target/loongarch/trace-events +++ b/target/loongarch/trace-events @@ -12,3 +12,4 @@ kvm_failed_put_counter(const char *msg) "Failed to put counter into KVM: %s" kvm_failed_get_cpucfg(const char *msg) "Failed to get cpucfg from KVM: %s" kvm_failed_put_cpucfg(const char *msg) "Failed to put cpucfg into KVM: %s" kvm_arch_handle_exit(int num) "kvm arch handle exit,
Re: [PATCH v3 9/9] target/loongarch: Add loongarch kvm into meson build
Hi, TianRui 在 2023/12/28 下午4:40, Tianrui Zhao 写道: Add kvm.c into meson.build to compile it when kvm is configed. Meanwhile in meson.build, we set the kvm_targets to loongarch64-softmmu when the cpu is loongarch. And fix the compiling error when config is enable-kvm,disable-tcg. Signed-off-by: Tianrui Zhao Signed-off-by: xianglai li Reviewed-by: Richard Henderson --- meson.build | 2 ++ target/loongarch/meson.build | 9 + 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/meson.build b/meson.build index 445f2b7c2b..0c62b4156d 100644 --- a/meson.build +++ b/meson.build @@ -114,6 +114,8 @@ elif cpu in ['riscv32'] kvm_targets = ['riscv32-softmmu'] elif cpu in ['riscv64'] kvm_targets = ['riscv64-softmmu'] +elif cpu in ['loongarch64'] + kvm_targets = ['loongarch64-softmmu'] else kvm_targets = [] endif diff --git a/target/loongarch/meson.build b/target/loongarch/meson.build index 18e8191e2b..4a59356d0f 100644 --- a/target/loongarch/meson.build +++ b/target/loongarch/meson.build @@ -10,8 +10,10 @@ loongarch_tcg_ss.add(files( 'fpu_helper.c', 'op_helper.c', 'translate.c', - 'gdbstub.c', 'vec_helper.c', + 'tlb_helper.c', + 'iocsr_helper.c', + 'csr_helper.c', )) loongarch_tcg_ss.add(zlib) this is broken 'loongarch64-linux-user' build. I had moved tcg code to target/loongarch/tcg. see [1] you just need rebase it. [1]: https://lore.kernel.org/all/20240102020200.3462097-2-gaos...@loongson.cn/ @@ -19,14 +21,13 @@ loongarch_system_ss = ss.source_set() loongarch_system_ss.add(files( 'loongarch-qmp-cmds.c', 'machine.c', - 'tlb_helper.c', 'constant_timer.c', - 'csr_helper.c', - 'iocsr_helper.c', + 'gdbstub.c', )) 'gdbstub.c' should move to loongarch_ss, because linus-user also need it. I had send a patch [1] to fix it . see [2] [2]: https://lore.kernel.org/all/20240102020200.3462097-1-gaos...@loongson.cn/ Thanks. Song Gao common_ss.add(when: 'CONFIG_LOONGARCH_DIS', if_true: [files('disas.c'), gen]) +loongarch_ss.add(when: 'CONFIG_KVM', if_true: files('kvm.c')) loongarch_ss.add_all(when: 'CONFIG_TCG', if_true: [loongarch_tcg_ss]) target_arch += {'loongarch': loongarch_ss}
Re: [PATCH 1/1] target/loongarch: move translate modules to tcg/
在 2023/12/29 下午6:08, Philippe Mathieu-Daudé 写道: Hi, On 29/12/23 10:24, Song Gao wrote: Introduce the target/loongarch/tcg directory. Its purpose is to hold the TCG code that is selected by CONFIG_TCG Signed-off-by: Song Gao --- target/loongarch/{ => tcg}/constant_timer.c | 0 target/loongarch/{ => tcg}/csr_helper.c | 0 target/loongarch/{ => tcg}/fpu_helper.c | 0 target/loongarch/{ => tcg}/iocsr_helper.c | 0 target/loongarch/{ => tcg}/op_helper.c | 0 target/loongarch/{ => tcg}/tlb_helper.c | 0 target/loongarch/{ => tcg}/translate.c | 0 target/loongarch/{ => tcg}/vec_helper.c | 0 .../{ => tcg}/insn_trans/trans_arith.c.inc | 0 .../{ => tcg}/insn_trans/trans_atomic.c.inc | 0 .../{ => tcg}/insn_trans/trans_bit.c.inc | 0 .../{ => tcg}/insn_trans/trans_branch.c.inc | 0 .../{ => tcg}/insn_trans/trans_extra.c.inc | 0 .../{ => tcg}/insn_trans/trans_farith.c.inc | 0 .../{ => tcg}/insn_trans/trans_fcmp.c.inc | 0 .../{ => tcg}/insn_trans/trans_fcnv.c.inc | 0 .../{ => tcg}/insn_trans/trans_fmemory.c.inc | 0 .../{ => tcg}/insn_trans/trans_fmov.c.inc | 0 .../{ => tcg}/insn_trans/trans_memory.c.inc | 0 .../{ => tcg}/insn_trans/trans_privileged.c.inc | 0 .../{ => tcg}/insn_trans/trans_shift.c.inc | 0 .../{ => tcg}/insn_trans/trans_vec.c.inc | 0 target/loongarch/meson.build | 17 ++--- target/loongarch/tcg/meson.build | 15 +++ 24 files changed, 17 insertions(+), 15 deletions(-) rename target/loongarch/{ => tcg}/constant_timer.c (100%) rename target/loongarch/{ => tcg}/csr_helper.c (100%) rename target/loongarch/{ => tcg}/fpu_helper.c (100%) rename target/loongarch/{ => tcg}/iocsr_helper.c (100%) rename target/loongarch/{ => tcg}/op_helper.c (100%) rename target/loongarch/{ => tcg}/tlb_helper.c (100%) rename target/loongarch/{ => tcg}/translate.c (100%) rename target/loongarch/{ => tcg}/vec_helper.c (100%) rename target/loongarch/{ => tcg}/insn_trans/trans_arith.c.inc (100%) rename target/loongarch/{ => tcg}/insn_trans/trans_atomic.c.inc (100%) rename target/loongarch/{ => tcg}/insn_trans/trans_bit.c.inc (100%) rename target/loongarch/{ => tcg}/insn_trans/trans_branch.c.inc (100%) rename target/loongarch/{ => tcg}/insn_trans/trans_extra.c.inc (100%) rename target/loongarch/{ => tcg}/insn_trans/trans_farith.c.inc (100%) rename target/loongarch/{ => tcg}/insn_trans/trans_fcmp.c.inc (100%) rename target/loongarch/{ => tcg}/insn_trans/trans_fcnv.c.inc (100%) rename target/loongarch/{ => tcg}/insn_trans/trans_fmemory.c.inc (100%) rename target/loongarch/{ => tcg}/insn_trans/trans_fmov.c.inc (100%) rename target/loongarch/{ => tcg}/insn_trans/trans_memory.c.inc (100%) rename target/loongarch/{ => tcg}/insn_trans/trans_privileged.c.inc (100%) rename target/loongarch/{ => tcg}/insn_trans/trans_shift.c.inc (100%) rename target/loongarch/{ => tcg}/insn_trans/trans_vec.c.inc (100%) create mode 100644 target/loongarch/tcg/meson.build diff --git a/target/loongarch/meson.build b/target/loongarch/meson.build index 18e8191e2b..a004523439 100644 --- a/target/loongarch/meson.build +++ b/target/loongarch/meson.build @@ -3,31 +3,18 @@ gen = decodetree.process('insns.decode') loongarch_ss = ss.source_set() loongarch_ss.add(files( 'cpu.c', + 'gdbstub.c' Preferably a preliminary commit "gdbstub.c is not specific to TCG and can be used by other accelerators ...". Otherwise just mention it in this patch description. I will split it to a new patch. )) -loongarch_tcg_ss = ss.source_set() -loongarch_tcg_ss.add(gen) -loongarch_tcg_ss.add(files( - 'fpu_helper.c', - 'op_helper.c', - 'translate.c', - 'gdbstub.c', - 'vec_helper.c', -)) -loongarch_tcg_ss.add(zlib) loongarch_system_ss = ss.source_set() loongarch_system_ss.add(files( 'loongarch-qmp-cmds.c', 'machine.c', - 'tlb_helper.c', - 'constant_timer.c', - 'csr_helper.c', - 'iocsr_helper.c', )) common_ss.add(when: 'CONFIG_LOONGARCH_DIS', if_true: [files('disas.c'), gen]) -loongarch_ss.add_all(when: 'CONFIG_TCG', if_true: [loongarch_tcg_ss]) +subdir('tcg') target_arch += {'loongarch': loongarch_ss} target_system_arch += {'loongarch': loongarch_system_ss} diff --git a/target/loongarch/tcg/meson.build b/target/loongarch/tcg/meson.build new file mode 100644 index 00..bb7411e5e5 --- /dev/null +++ b/target/loongarch/tcg/meson.build @@ -0,0 +1,15 @@ You missed the CONFIG_TCG check, you can use either: if 'CONFIG_TCG' in config_all subdir('tcg') endif in target/loongarch/meson.build, but since your target seems well designed and doesn't require TCG stub, you can do directly here: if 'CONFIG_TCG' not in config_all subdir_done() endif so the rest of this file isn't processed. Got it +loongarch_ss.add([zlib, gen]) +
Re: [PATCH v3 03/17] hw/loongarch: Add slave cpu boot_code
在 2023/12/27 下午4:52, Philippe Mathieu-Daudé 写道: Hi, On 27/12/23 09:08, Song Gao wrote: Signed-off-by: Song Gao --- hw/loongarch/boot.c | 71 - 1 file changed, 70 insertions(+), 1 deletion(-) diff --git a/hw/loongarch/boot.c b/hw/loongarch/boot.c index 3075c276d4..faff880153 100644 --- a/hw/loongarch/boot.c +++ b/hw/loongarch/boot.c @@ -14,6 +14,54 @@ #include "qemu/error-report.h" #include "sysemu/reset.h" +static unsigned int slave_boot_code[] = { 'const' Got it. + /* Configure reset ebase. */ + 0x0400302c, /* csrwr $r12,0xc */ + + /* Disable interrupt. */ + 0x0380100c, /* ori $r12,$r0,0x4 */ + 0x04000180, /* csrxchg $r0,$r12,0x0 */ + + /* Clear mailbox. */ + 0x142d, /* lu12i.w $r13,1(0x1) */ + 0x038081ad, /* ori $r13,$r13,0x20 */ + 0x06481da0, /* iocsrwr.d $r0,$r13 */ + + /* Enable IPI interrupt. */ + 0x142c, /* lu12i.w $r12,1(0x1) */ + 0x0400118c, /* csrxchg $r12,$r12,0x4 */ + 0x02fffc0c, /* addi.d $r12,$r0,-1(0xfff) */ + 0x142d, /* lu12i.w $r13,1(0x1) */ + 0x038011ad, /* ori $r13,$r13,0x4 */ + 0x064819ac, /* iocsrwr.w $r12,$r13 */ + 0x142d, /* lu12i.w $r13,1(0x1) */ + 0x038081ad, /* ori $r13,$r13,0x20 */ + + /* Wait for wakeup <.L11>: */ + 0x06488000, /* idle 0x0 */ + 0x0340, /* andi $r0,$r0,0x0 */ + 0x064809ac, /* iocsrrd.w $r12,$r13 */ + 0x43fff59f, /* beqz $r12,-12(0x74) # 48 <.L11> */ + + /* Read and clear IPI interrupt. */ + 0x142d, /* lu12i.w $r13,1(0x1) */ + 0x064809ac, /* iocsrrd.w $r12,$r13 */ + 0x142d, /* lu12i.w $r13,1(0x1) */ + 0x038031ad, /* ori $r13,$r13,0xc */ + 0x064819ac, /* iocsrwr.w $r12,$r13 */ + + /* Disable IPI interrupt. */ + 0x142c, /* lu12i.w $r12,1(0x1) */ + 0x04001180, /* csrxchg $r0,$r12,0x4 */ + + /* Read mail buf and jump to specified entry */ + 0x142d, /* lu12i.w $r13,1(0x1) */ + 0x038081ad, /* ori $r13,$r13,0x20 */ + 0x06480dac, /* iocsrrd.d $r12,$r13 */ + 0x00150181, /* move $r1,$r12 */ + 0x4c20, /* jirl $r0,$r1,0 */ +}; + static uint64_t cpu_loongarch_virt_to_phys(void *opaque, uint64_t addr) { return addr & MAKE_64BIT_MASK(0, TARGET_PHYS_ADDR_SPACE_BITS); @@ -110,11 +158,19 @@ static void loongarch_firmware_boot(LoongArchMachineState *lams, fw_cfg_add_kernel_info(info, lams->fw_cfg); } +static void init_boot_rom(struct loongarch_boot_info *info, void *p) +{ + memcpy(p, _boot_code, sizeof(slave_boot_code)); + p += sizeof(slave_boot_code); +} + static void loongarch_direct_kernel_boot(struct loongarch_boot_info *info) { + static void *p; Why 'static'? I will drop it. int64_t kernel_addr = 0; LoongArchCPU *lacpu; CPUState *cs; + void *bp; if (info->kernel_filename) { kernel_addr = load_kernel_info(info); @@ -123,11 +179,24 @@ static void loongarch_direct_kernel_boot(struct loongarch_boot_info *info) exit(1); } + /* Load 'boot_rom' at [0 - 1MiB] */ + p = g_malloc0(1 * MiB); + bp = p; + init_boot_rom(info, p); + rom_add_blob_fixed("boot_rom", bp, 1 * MiB, 0); + CPU_FOREACH(cs) { lacpu = LOONGARCH_CPU(cs); lacpu->env.load_elf = true; - lacpu->env.elf_address = kernel_addr; + if (cs == first_cpu) { + lacpu->env.elf_address = kernel_addr; + } else { + lacpu->env.elf_address = 0; + } + lacpu->env.boot_info = info; } + + g_free(bp); (besides, IIUC 'p' now points to released memory). Yes. Thanks. Song Gao } void loongarch_load_kernel(MachineState *ms, struct loongarch_boot_info *info)
Re: [PATCH v3 04/17] hw/loongarch: Add init_cmdline
在 2023/12/27 下午4:49, Philippe Mathieu-Daudé 写道: Hi, On 27/12/23 09:08, Song Gao wrote: Add init_cmline and set boot_info->a0, a1 Signed-off-by: Song Gao --- hw/loongarch/boot.c | 20 target/loongarch/cpu.h | 2 ++ 2 files changed, 22 insertions(+) diff --git a/hw/loongarch/boot.c b/hw/loongarch/boot.c index faff880153..27eae6f0cb 100644 --- a/hw/loongarch/boot.c +++ b/hw/loongarch/boot.c @@ -13,6 +13,7 @@ #include "elf.h" #include "qemu/error-report.h" #include "sysemu/reset.h" +#include Build failure on Darwin host: [1135/1207] Compiling C object libqemu-loongarch64-softmmu.fa.p/hw_loongarch_boot.c.o FAILED: libqemu-loongarch64-softmmu.fa.p/hw_loongarch_boot.c.o ../../hw/loongarch/boot.c:16:10: fatal error: 'asm-generic/setup.h' file not found #include ^ 1 error generated. ninja: build stopped: subcommand failed. I will drop it , use #define COMAND_LINE_SIZE 512. Thanks. Song Gao
Re: [PATCH v3 11/17] hw/loongarch: fdt adds Extend I/O Interrupt Controller
在 2023/12/27 下午5:02, Philippe Mathieu-Daudé 写道: Hi, On 27/12/23 09:08, Song Gao wrote: fdt adds Extend I/O Interrupt Controller, we use 'loongson,ls2k2000-eiointc'. See: drivers/irqchip/irq-loongson-eiointc.c Better reference a fixed commit/tag, and mention Linux project. Suggestion: 'See https://github.com/torvalds/linux/blob/v6.6/drivers/irqchip/irq-loongson-eiointc.c'. Got it. Thanks. Song Gao Signed-off-by: Song Gao --- hw/loongarch/virt.c | 30 +- include/hw/intc/loongarch_extioi.h | 1 + 2 files changed, 30 insertions(+), 1 deletion(-)
Re: [PATCH v2 02/17] hw/loongarch: Add load initrd
在 2023/12/21 下午3:09, maobibo 写道: On 2023/12/18 下午5:00, Song Gao wrote: we load initrd ramdisk after kernel_high address Signed-off-by: Song Gao --- hw/loongarch/boot.c | 29 - 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/hw/loongarch/boot.c b/hw/loongarch/boot.c index 9f25ea5847..2be6dfb037 100644 --- a/hw/loongarch/boot.c +++ b/hw/loongarch/boot.c @@ -21,7 +21,8 @@ static uint64_t cpu_loongarch_virt_to_phys(void *opaque, uint64_t addr) static int64_t load_kernel_info(struct loongarch_boot_info *info) { - uint64_t kernel_entry, kernel_low, kernel_high; + uint64_t kernel_entry, kernel_low, kernel_high, initrd_size; + ram_addr_t initrd_offset; ssize_t kernel_size; kernel_size = load_elf(info->kernel_filename, NULL, @@ -36,6 +37,32 @@ static int64_t load_kernel_info(struct loongarch_boot_info *info) load_elf_strerror(kernel_size)); exit(1); } + + if (info->initrd_filename) { + initrd_size = get_image_size(info->initrd_filename); + if (initrd_size > 0) { + initrd_offset = ROUND_UP(kernel_high, 64 * KiB); Do you test self-compressed vmlinuz elf load? The LoongArch kenrel not support build bzimage. I think that offset of initrd had better be 4 * kernel_size from kernel_high, else uncompressed kernel may overwrite INITRD image. such as: initrd_offset = ROUND_UP(kernel_high + 4 * kernel_size, 64 * KiB); but I think we can do this. Thanks. Song Gao Regards Bibo Mao + + if (initrd_offset + initrd_size > info->ram_size) { + error_report("memory too small for initial ram disk '%s'", + info->initrd_filename); + exit(1); + } + + initrd_size = load_image_targphys(info->initrd_filename, initrd_offset, + info->ram_size - initrd_offset); + } + + if (initrd_size == (target_ulong)-1) { + error_report("could not load initial ram disk '%s'", + info->initrd_filename); + exit(1); + } + } else { + error_report("Need initrd!"); + exit(1); + } + return kernel_entry; }
Re: [PATCH v2 03/17] hw/loongarch: Add init_cmdline
在 2023/12/21 下午3:20, maobibo 写道: On 2023/12/18 下午5:00, Song Gao wrote: Add init_cmline and set boot_info->a0, a1 Signed-off-by: Song Gao --- hw/loongarch/boot.c | 21 + include/hw/loongarch/virt.h | 2 ++ target/loongarch/cpu.h | 2 ++ 3 files changed, 25 insertions(+) diff --git a/hw/loongarch/boot.c b/hw/loongarch/boot.c index 2be6dfb037..4bfe24274a 100644 --- a/hw/loongarch/boot.c +++ b/hw/loongarch/boot.c @@ -14,6 +14,20 @@ #include "qemu/error-report.h" #include "sysemu/reset.h" +static int init_cmdline(struct loongarch_boot_info *info) +{ + hwaddr cmdline_addr; + cmdline_addr = 0xff0ULL; + + pstrcpy_targphys("cmdline", 0xff0ULL, + COMMAND_LINE_SIZE, info->kernel_cmdline); There are two places using 0xff0ULL here, it had better be defined as macro. Also can address for cmdline be before FDT base address(0x10) rather than strange value 0xff0 ? -:) + + info->a0 = 1; + info->a1 = cmdline_addr; + + return 0; +} + static uint64_t cpu_loongarch_virt_to_phys(void *opaque, uint64_t addr) { return addr & MAKE_64BIT_MASK(0, TARGET_PHYS_ADDR_SPACE_BITS); @@ -63,6 +77,8 @@ static int64_t load_kernel_info(struct loongarch_boot_info *info) exit(1); } + init_cmdline(info); + return kernel_entry; } @@ -73,6 +89,10 @@ static void reset_load_elf(void *opaque) cpu_reset(CPU(cpu)); if (env->load_elf) { + if (cpu == LOONGARCH_CPU(first_cpu)) { + env->gpr[4] = env->boot_info->a0; + env->gpr[5] = env->boot_info->a1; + } cpu_set_pc(CPU(cpu), env->elf_address); } } @@ -129,6 +149,7 @@ static void loongarch_direct_kernel_boot(LoongArchMachineState *lams, lacpu = LOONGARCH_CPU(qemu_get_cpu(i)); lacpu->env.load_elf = true; lacpu->env.elf_address = kernel_addr; + lacpu->env.boot_info = info; } } diff --git a/include/hw/loongarch/virt.h b/include/hw/loongarch/virt.h index e4126dd0e7..d21de2cef4 100644 --- a/include/hw/loongarch/virt.h +++ b/include/hw/loongarch/virt.h @@ -31,6 +31,8 @@ #define VIRT_GED_MEM_ADDR (VIRT_GED_EVT_ADDR + ACPI_GED_EVT_SEL_LEN) #define VIRT_GED_REG_ADDR (VIRT_GED_MEM_ADDR + MEMORY_HOTPLUG_IO_LEN) +#define COMMAND_LINE_SIZE 512 The macro COMMAND_LINE_SIZE is already defined in Linux header file, maybe standard header file can be used. /usr/include/asm-generic/setup.h #define COMMAND_LINE_SIZE 512 Yes, #include Thanks. Song Gao Regards Bibo Mao + struct LoongArchMachineState { /*< private >*/ MachineState parent_obj; diff --git a/target/loongarch/cpu.h b/target/loongarch/cpu.h index 00d1fba597..c7c695138e 100644 --- a/target/loongarch/cpu.h +++ b/target/loongarch/cpu.h @@ -362,6 +362,8 @@ typedef struct CPUArchState { uint64_t elf_address; /* Store ipistate to access from this struct */ DeviceState *ipistate; + + struct loongarch_boot_info *boot_info; #endif } CPULoongArchState;
Re: [PATCH v2 01/17] hw/loongarch: Move boot fucntions to boot.c
在 2023/12/21 下午3:04, maobibo 写道: On 2023/12/18 下午5:00, Song Gao wrote: Move some boot functions to boot.c and struct loongarch_boot_info into struct LoongArchMachineState. Signed-off-by: Song Gao --- hw/loongarch/boot.c | 127 hw/loongarch/meson.build | 1 + hw/loongarch/virt.c | 118 ++--- include/hw/loongarch/boot.h | 21 ++ include/hw/loongarch/virt.h | 2 + 5 files changed, 155 insertions(+), 114 deletions(-) create mode 100644 hw/loongarch/boot.c create mode 100644 include/hw/loongarch/boot.h diff --git a/hw/loongarch/boot.c b/hw/loongarch/boot.c new file mode 100644 index 00..9f25ea5847 --- /dev/null +++ b/hw/loongarch/boot.c @@ -0,0 +1,127 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * LoongArch boot helper functions. + * Yes, #include <> + * Copyright (c) 2023 Loongson Technology Corporation Limited + */ + +#include "qemu/osdep.h" +#include "qemu/units.h" +#include "target/loongarch/cpu.h" +#include "hw/loongarch/virt.h" +#include "hw/loader.h" +#include "elf.h" +#include "qemu/error-report.h" +#include "sysemu/reset.h" + +static uint64_t cpu_loongarch_virt_to_phys(void *opaque, uint64_t addr) +{ + return addr & MAKE_64BIT_MASK(0, TARGET_PHYS_ADDR_SPACE_BITS); +} + +static int64_t load_kernel_info(struct loongarch_boot_info *info) +{ + uint64_t kernel_entry, kernel_low, kernel_high; + ssize_t kernel_size; + + kernel_size = load_elf(info->kernel_filename, NULL, + cpu_loongarch_virt_to_phys, NULL, + _entry, _low, + _high, NULL, 0, + EM_LOONGARCH, 1, 0); + + if (kernel_size < 0) { + error_report("could not load kernel '%s': %s", + info->kernel_filename, + load_elf_strerror(kernel_size)); + exit(1); + } + return kernel_entry; +} + +static void reset_load_elf(void *opaque) +{ + LoongArchCPU *cpu = opaque; + CPULoongArchState *env = >env; + + cpu_reset(CPU(cpu)); + if (env->load_elf) { + cpu_set_pc(CPU(cpu), env->elf_address); + } +} + +static void fw_cfg_add_kernel_info(struct loongarch_boot_info *info, + FWCfgState *fw_cfg) +{ + /* + * Expose the kernel, the command line, and the initrd in fw_cfg. + * We don't process them here at all, it's all left to the + * firmware. + */ + load_image_to_fw_cfg(fw_cfg, + FW_CFG_KERNEL_SIZE, FW_CFG_KERNEL_DATA, + info->kernel_filename, + false); + + if (info->initrd_filename) { + load_image_to_fw_cfg(fw_cfg, + FW_CFG_INITRD_SIZE, FW_CFG_INITRD_DATA, + info->initrd_filename, false); + } + + if (info->kernel_cmdline) { + fw_cfg_add_i32(fw_cfg, FW_CFG_CMDLINE_SIZE, + strlen(info->kernel_cmdline) + 1); + fw_cfg_add_string(fw_cfg, FW_CFG_CMDLINE_DATA, + info->kernel_cmdline); + } +} + +static void loongarch_firmware_boot(LoongArchMachineState *lams, + struct loongarch_boot_info *info) +{ + fw_cfg_add_kernel_info(info, lams->fw_cfg); +} + +static void loongarch_direct_kernel_boot(LoongArchMachineState *lams, + struct loongarch_boot_info *info) +{ + MachineState *machine = MACHINE(lams); + int64_t kernel_addr = 0; + LoongArchCPU *lacpu; + int i; + + if (info->kernel_filename) { + kernel_addr = load_kernel_info(info); + } else { + error_report("Need kernel filename\n"); + exit(1); + } + + for (i = 0; i < machine->smp.cpus; i++) { + lacpu = LOONGARCH_CPU(qemu_get_cpu(i)); + lacpu->env.load_elf = true; + lacpu->env.elf_address = kernel_addr; + } +} + +void loongarch_load_kernel(MachineState *ms, struct loongarch_boot_info *info) +{ + LoongArchMachineState *lams = LOONGARCH_MACHINE(ms); + int i; + + /* register reset function */ + for (i = 0; i < ms->smp.cpus; i++) { + qemu_register_reset(reset_load_elf, LOONGARCH_CPU(qemu_get_cpu(i))); + } + + info->kernel_filename = ms->kernel_filename; + info->kernel_cmdline = ms->kernel_cmdline; + info->initrd_filename = ms->initrd_filename; + + if (lams->bios_loaded) { + loongarch_firmware_boot(lams, info); + } else { + loongarch_direct_kernel_boot(lams, info); + } +} diff --git a/hw/loongarch/meson.build b/hw/loongarch/meson.build index c0421502ab..d306d82c2e 100644 --- a/hw/loongarch/meson.build +++ b/hw/loongarch/meson.build @@ -1,6 +1,7 @@ loongarch_ss = ss.source_set() loongarch_ss.add(files( 'fw_cfg.c', + 'boot.c', )) loongarch_ss.add(when: 'CONFIG_LOONGARCH_VIRT', if_true: [files('virt.c'), fdt]) loongarch_ss.add(when:
Re: [PATCH v2 04/17] hw/loongarch: Add slave cpu boot_code
在 2023/12/21 下午3:22, maobibo 写道: On 2023/12/18 下午5:00, Song Gao wrote: Signed-off-by: Song Gao --- hw/loongarch/boot.c | 65 - 1 file changed, 64 insertions(+), 1 deletion(-) diff --git a/hw/loongarch/boot.c b/hw/loongarch/boot.c index 4bfe24274a..076e795714 100644 --- a/hw/loongarch/boot.c +++ b/hw/loongarch/boot.c @@ -14,6 +14,62 @@ #include "qemu/error-report.h" #include "sysemu/reset.h" +enum { + SLAVE_BOOT, +}; + +static const MemMapEntry loader_rommap[] = { + [SLAVE_BOOT] = {0xf10, 0x1}, +}; Address 0xf10 had better be defined before 0x10 I will correct it on v3 Thanks. Song Gao Regards Bibo Mao + +static unsigned int slave_boot_code[] = { + /* Configure reset ebase. */ + 0x0400302c, /* csrwr $r12,0xc */ + + /* Disable interrupt. */ + 0x0380100c, /* ori $r12,$r0,0x4 */ + 0x04000180, /* csrxchg $r0,$r12,0x0 */ + + /* Clear mailbox. */ + 0x142d, /* lu12i.w $r13,1(0x1) */ + 0x038081ad, /* ori $r13,$r13,0x20 */ + 0x06481da0, /* iocsrwr.d $r0,$r13 */ + + /* Enable IPI interrupt. */ + 0x142c, /* lu12i.w $r12,1(0x1) */ + 0x0400118c, /* csrxchg $r12,$r12,0x4 */ + 0x02fffc0c, /* addi.d $r12,$r0,-1(0xfff) */ + 0x142d, /* lu12i.w $r13,1(0x1) */ + 0x038011ad, /* ori $r13,$r13,0x4 */ + 0x064819ac, /* iocsrwr.w $r12,$r13 */ + 0x142d, /* lu12i.w $r13,1(0x1) */ + 0x038081ad, /* ori $r13,$r13,0x20 */ + + /* Wait for wakeup <.L11>: */ + 0x06488000, /* idle 0x0 */ + 0x0340, /* andi $r0,$r0,0x0 */ + 0x064809ac, /* iocsrrd.w $r12,$r13 */ + 0x43fff59f, /* beqz $r12,-12(0x74) # 48 <.L11> */ + + /* Read and clear IPI interrupt. */ + 0x142d, /* lu12i.w $r13,1(0x1) */ + 0x064809ac, /* iocsrrd.w $r12,$r13 */ + 0x142d, /* lu12i.w $r13,1(0x1) */ + 0x038031ad, /* ori $r13,$r13,0xc */ + 0x064819ac, /* iocsrwr.w $r12,$r13 */ + + /* Disable IPI interrupt. */ + 0x142c, /* lu12i.w $r12,1(0x1) */ + 0x04001180, /* csrxchg $r0,$r12,0x4 */ + + /* Read mail buf and jump to specified entry */ + 0x142d, /* lu12i.w $r13,1(0x1) */ + 0x038081ad, /* ori $r13,$r13,0x20 */ + 0x06480dac, /* iocsrrd.d $r12,$r13 */ + 0x00150181, /* move $r1,$r12 */ + 0x4c20, /* jirl $r0,$r1,0 */ +}; + static int init_cmdline(struct loongarch_boot_info *info) { hwaddr cmdline_addr; @@ -145,10 +201,17 @@ static void loongarch_direct_kernel_boot(LoongArchMachineState *lams, exit(1); } + rom_add_blob_fixed("slave_boot", slave_boot_code, sizeof(slave_boot_code), + loader_rommap[SLAVE_BOOT].base); + for (i = 0; i < machine->smp.cpus; i++) { lacpu = LOONGARCH_CPU(qemu_get_cpu(i)); lacpu->env.load_elf = true; - lacpu->env.elf_address = kernel_addr; + if (i == 0) { + lacpu->env.elf_address = kernel_addr; + } else { + lacpu->env.elf_address = loader_rommap[SLAVE_BOOT].base; + } lacpu->env.boot_info = info; } }
Re: [PATCH v2 38/71] hw/loongarch: Constify VMState
在 2023/12/21 上午11:16, Richard Henderson 写道: Signed-off-by: Richard Henderson --- hw/loongarch/acpi-build.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) Reviewed-by: Song Gao Thanks. Song Gao diff --git a/hw/loongarch/acpi-build.c b/hw/loongarch/acpi-build.c index ae292fc543..730bc4a748 100644 --- a/hw/loongarch/acpi-build.c +++ b/hw/loongarch/acpi-build.c @@ -564,7 +564,7 @@ static const VMStateDescription vmstate_acpi_build = { .name = "acpi_build", .version_id = 1, .minimum_version_id = 1, -.fields = (VMStateField[]) { +.fields = (const VMStateField[]) { VMSTATE_UINT8(patched, AcpiBuildState), VMSTATE_END_OF_LIST() },
Re: [PATCH v2 09/71] target/loongarch: Constify VMState in machine.c
在 2023/12/21 上午11:15, Richard Henderson 写道: Signed-off-by: Richard Henderson --- target/loongarch/machine.c | 18 +- 1 file changed, 9 insertions(+), 9 deletions(-) Reviewed-by: Song Gao Thanks. Song Gao diff --git a/target/loongarch/machine.c b/target/loongarch/machine.c index 1c4e01d076..c7029fb9b4 100644 --- a/target/loongarch/machine.c +++ b/target/loongarch/machine.c @@ -14,7 +14,7 @@ static const VMStateDescription vmstate_fpu_reg = { .name = "fpu_reg", .version_id = 1, .minimum_version_id = 1, -.fields = (VMStateField[]) { +.fields = (const VMStateField[]) { VMSTATE_UINT64(UD(0), VReg), VMSTATE_END_OF_LIST() } @@ -36,7 +36,7 @@ static const VMStateDescription vmstate_fpu = { .version_id = 1, .minimum_version_id = 1, .needed = fpu_needed, -.fields = (VMStateField[]) { +.fields = (const VMStateField[]) { VMSTATE_FPU_REGS(env.fpr, LoongArchCPU, 0), VMSTATE_UINT32(env.fcsr0, LoongArchCPU), VMSTATE_BOOL_ARRAY(env.cf, LoongArchCPU, 8), @@ -48,7 +48,7 @@ static const VMStateDescription vmstate_lsxh_reg = { .name = "lsxh_reg", .version_id = 1, .minimum_version_id = 1, -.fields = (VMStateField[]) { +.fields = (const VMStateField[]) { VMSTATE_UINT64(UD(1), VReg), VMSTATE_END_OF_LIST() } @@ -70,7 +70,7 @@ static const VMStateDescription vmstate_lsx = { .version_id = 1, .minimum_version_id = 1, .needed = lsx_needed, -.fields = (VMStateField[]) { +.fields = (const VMStateField[]) { VMSTATE_LSXH_REGS(env.fpr, LoongArchCPU, 0), VMSTATE_END_OF_LIST() }, @@ -80,7 +80,7 @@ static const VMStateDescription vmstate_lasxh_reg = { .name = "lasxh_reg", .version_id = 1, .minimum_version_id = 1, -.fields = (VMStateField[]) { +.fields = (const VMStateField[]) { VMSTATE_UINT64(UD(2), VReg), VMSTATE_UINT64(UD(3), VReg), VMSTATE_END_OF_LIST() @@ -103,7 +103,7 @@ static const VMStateDescription vmstate_lasx = { .version_id = 1, .minimum_version_id = 1, .needed = lasx_needed, -.fields = (VMStateField[]) { +.fields = (const VMStateField[]) { VMSTATE_LASXH_REGS(env.fpr, LoongArchCPU, 0), VMSTATE_END_OF_LIST() }, @@ -114,7 +114,7 @@ const VMStateDescription vmstate_tlb = { .name = "cpu/tlb", .version_id = 0, .minimum_version_id = 0, -.fields = (VMStateField[]) { +.fields = (const VMStateField[]) { VMSTATE_UINT64(tlb_misc, LoongArchTLB), VMSTATE_UINT64(tlb_entry0, LoongArchTLB), VMSTATE_UINT64(tlb_entry1, LoongArchTLB), @@ -127,7 +127,7 @@ const VMStateDescription vmstate_loongarch_cpu = { .name = "cpu", .version_id = 1, .minimum_version_id = 1, -.fields = (VMStateField[]) { +.fields = (const VMStateField[]) { VMSTATE_UINTTL_ARRAY(env.gpr, LoongArchCPU, 32), VMSTATE_UINTTL(env.pc, LoongArchCPU), @@ -193,7 +193,7 @@ const VMStateDescription vmstate_loongarch_cpu = { VMSTATE_END_OF_LIST() }, -.subsections = (const VMStateDescription*[]) { +.subsections = (const VMStateDescription * const []) { _fpu, _lsx, _lasx,
Re: [PATCH] hw/loongarch/virt: Align high memory base address with super page size
在 2023/11/27 下午12:02, Bibo Mao 写道: With LoongArch virt machine, there is low memory space with region 0--0x1000, and high memory space with started from 0x9000. High memory space is aligned with 256M, it will be better if it is aligned with 1G, which is super page aligned for 4K page size. Currently linux kernel and uefi bios has no limitation with high memory base address, it is ok to set high memory base address with 0x8000. Signed-off-by: Bibo Mao Change-Id: Iac1af728bf6fd35c9c2f4e7dbdae6e3c0fbab623 --- include/hw/loongarch/virt.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) Drop Change-Id. Reviewed-by: Song Gao Thanks. Song Gao diff --git a/include/hw/loongarch/virt.h b/include/hw/loongarch/virt.h index 674f4655e0..db0831b471 100644 --- a/include/hw/loongarch/virt.h +++ b/include/hw/loongarch/virt.h @@ -25,7 +25,7 @@ #define VIRT_LOWMEM_BASE0 #define VIRT_LOWMEM_SIZE0x1000 -#define VIRT_HIGHMEM_BASE 0x9000 +#define VIRT_HIGHMEM_BASE 0x8000 #define VIRT_GED_EVT_ADDR 0x100e #define VIRT_GED_MEM_ADDR (VIRT_GED_EVT_ADDR + ACPI_GED_EVT_SEL_LEN) #define VIRT_GED_REG_ADDR (VIRT_GED_MEM_ADDR + MEMORY_HOTPLUG_IO_LEN)
Re: [risu PATCH 5/5] loongarch: Add block 'clean' and clean_lsx_result()
在 2023/12/12 下午8:39, Peter Maydell 写道: On Wed, 25 Oct 2023 at 10:29, Song Gao wrote: The result of the LSX instruction is in the low 128 bits of the vreg register. We use clean_lsx_result() to clean up the high 128 bits of the vreg register. Signed-off-by: Song Gao --- loongarch64.risu | 2121 ++-- risugen|2 +- risugen_loongarch64.pm | 20 + 3 files changed, 1405 insertions(+), 738 deletions(-) diff --git a/loongarch64.risu b/loongarch64.risu index 596de90..531470d 100644 --- a/loongarch64.risu +++ b/loongarch64.risu @@ -64,26 +64,26 @@ mulw_d_wu LA64 0001 1 rk:5 rj:5 rd:5 \ #div.{w[u]/d[u]} rd,rj,rk # div.w{u}, mod.w[u] rk, rj, need in [0x0 ~0x7FFF] # use function set_reg_w($reg) -div_w LA64 0010 0 rk:5 rj:5 rd:5 \ -!constraints { $rk != 2 && $rj != 2 && $rd != 2; } \ -!memory { set_reg_w($rj); set_reg_w($rk); } -div_wu LA64 0010 00010 rk:5 rj:5 rd:5 \ -!constraints { $rk != 2 && $rj != 2 && $rd != 2; } \ -!memory { set_reg_w($rj); set_reg_w($rk); } -div_d LA64 0010 00100 rk:5 rj:5 rd:5 \ -!constraints { $rk != 2 && $rj != 2 && $rd != 2; } -div_du LA64 0010 00110 rk:5 rj:5 rd:5 \ -!constraints { $rk != 2 && $rj != 2 && $rd != 2; } -mod_w LA64 0010 1 rk:5 rj:5 rd:5 \ -!constraints { $rk != 2 && $rj != 2 && $rd != 2; } \ -!memory { set_reg_w($rj); set_reg_w($rk); } -mod_wu LA64 0010 00011 rk:5 rj:5 rd:5 \ -!constraints { $rk != 2 && $rj != 2 && $rd != 2; } \ -!memory { set_reg_w($rj); set_reg_w($rk); } -mod_d LA64 0010 00101 rk:5 rj:5 rd:5 \ -!constraints { $rk != 2 && $rj != 2 && $rd != 2; } -mod_du LA64 0010 00111 rk:5 rj:5 rd:5 \ -!constraints { $rk != 2 && $rj != 2 && $rd != 2; } +#div_w LA64 0010 0 rk:5 rj:5 rd:5 \ +#!constraints { $rk != 2 && $rj != 2 && $rd != 2; } \ +#!memory { set_reg_w($rj); set_reg_w($rk); } +#div_wu LA64 0010 00010 rk:5 rj:5 rd:5 \ +#!constraints { $rk != 2 && $rj != 2 && $rd != 2; } \ +#!memory { set_reg_w($rj); set_reg_w($rk); } +#div_d LA64 0010 00100 rk:5 rj:5 rd:5 \ +#!constraints { $rk != 2 && $rj != 2 && $rd != 2; } +#div_du LA64 0010 00110 rk:5 rj:5 rd:5 \ +#!constraints { $rk != 2 && $rj != 2 && $rd != 2; } +#mod_w LA64 0010 1 rk:5 rj:5 rd:5 \ +#!constraints { $rk != 2 && $rj != 2 && $rd != 2; } \ +#!memory { set_reg_w($rj); set_reg_w($rk); } +#mod_wu LA64 0010 00011 rk:5 rj:5 rd:5 \ +#!constraints { $rk != 2 && $rj != 2 && $rd != 2; } \ +#!memory { set_reg_w($rj); set_reg_w($rk); } +#mod_d LA64 0010 00101 rk:5 rj:5 rd:5 \ +#!constraints { $rk != 2 && $rj != 2 && $rd != 2; } +#mod_du LA64 0010 00111 rk:5 rj:5 rd:5 \ +#!constraints { $rk != 2 && $rj != 2 && $rd != 2; } Why do we comment out all these patterns ? The commit message doesn't say anything about this. I will drop them. These instructions, test need patch[1], but the patch is't merged. [1] : https://lore.kernel.org/all/3c401d0f-a34f-bd29-03a3-dddfae94c...@loongson.cn/#r alsl_w LA64 010 sa2:2 rk:5 rj:5 rd:5 \ !constraints { $rk != 2 && $rj != 2 && $rd != 2; } @@ -615,665 +615,1248 @@ fstx_d LA64 0011 1011 11000 rk:5 rj:5 fd:5 \ # LSX instructions # -vadd_b LSX 0111 10100 vk:5 vj:5 vd:5 -vadd_h LSX 0111 10101 vk:5 vj:5 vd:5 +vadd_b LSX 0111 10100 vk:5 vj:5 vd:5 \ +!clean { clean_lsx_result($vd); } +vadd_h LSX 0111 10101 vk:5 vj:5 vd:5 \ +!clean { clean_lsx_result($vd); } If there are patterns that need the clean_lsx_result handling, then add the support for that first, rather than adding a broken pattern and then editing it to add the extra block to every pattern, please. Got it. diff --git a/risugen b/risugen index fa94a39..8a67fdf 100755 --- a/risugen +++ b/risugen @@ -43,7 +43,7 @@ my @pattern_re = ();# include pattern my @not_pattern_re = ();# exclude pattern # Valid block names (keys in blocks hash) -my %valid_blockname = ( constraints => 1, memory => 1, safefloat =>1 ); +my %valid_blockname = ( constraints => 1, memory => 1, safefloat =>1, clean => 1 ); sub parse_risu_directive($$@) { diff --git a/risugen_loongarch64.pm b/risugen_loongarch64.pm index b3f901d..97f00f3 100644 --- a/risugen_loongarch64.pm +++ b/risugen_loongarch64.pm @@ -81,6 +81,18 @@ sub nanbox_s($) return $fpreg; } +sub clean_lsx_result($) +{ +my ($vreg) = @_; + +# xvinsgr2vr.d vd, r0, 2; +insn32(0x76ebe000 | 2 << 10 | $vreg); +# xvinsgr2vr.d vd, r0, 3; +insn32(0x76ebe000 | 3 << 10 | $vreg); + +return $vreg; +} + sub align($) { my ($a) = @_; @@ -405,6 +417,7 @@ sub gen_one_insn($$) my $constraint = $rec->{blocks}{"constraints"}; my $memblock = $rec->{blocks}{"memory"}; my $safefloat =
Re: [PATCH 24/24] target: Restrict 'sysemu/reset.h' to system emulation
在 2023/12/12 上午5:20, Philippe Mathieu-Daudé 写道: vCPU "reset" is only possible with system emulation. Signed-off-by: Philippe Mathieu-Daudé --- target/i386/cpu.c | 2 +- target/loongarch/cpu.c | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) Reviewed-by: Song Gao Thanks. Song Gao diff --git a/target/i386/cpu.c b/target/i386/cpu.c index dfb96217ad..17b6962d43 100644 --- a/target/i386/cpu.c +++ b/target/i386/cpu.c @@ -24,7 +24,6 @@ #include "qemu/hw-version.h" #include "cpu.h" #include "tcg/helper-tcg.h" -#include "sysemu/reset.h" #include "sysemu/hvf.h" #include "hvf/hvf-i386.h" #include "kvm/kvm_i386.h" @@ -37,6 +36,7 @@ #include "hw/qdev-properties.h" #include "hw/i386/topology.h" #ifndef CONFIG_USER_ONLY +#include "sysemu/reset.h" #include "qapi/qapi-commands-machine-target.h" #include "exec/address-spaces.h" #include "hw/boards.h" diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c index fc075952e6..b26187dfde 100644 --- a/target/loongarch/cpu.c +++ b/target/loongarch/cpu.c @@ -17,7 +17,9 @@ #include "internals.h" #include "fpu/softfloat-helpers.h" #include "cpu-csr.h" +#ifndef CONFIG_USER_ONLY #include "sysemu/reset.h" +#endif #include "tcg/tcg.h" #include "vec.h"
Re: [PATCH] target/loongarch: Add timer information dump support
在 2023/12/6 下午4:18, Bibo Mao 写道: Timer emulation sometimes is problematic especially when vm is running in kvm mode. This patch adds registers dump support relative with timer hardware, so that it is easier to find the problems. Signed-off-by: Bibo Mao --- target/loongarch/cpu.c | 2 ++ 1 file changed, 2 insertions(+) Reviewed-by: Song Gao Thanks. Song Gao diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c index fc075952e6..db9a421cc4 100644 --- a/target/loongarch/cpu.c +++ b/target/loongarch/cpu.c @@ -762,6 +762,8 @@ void loongarch_cpu_dump_state(CPUState *cs, FILE *f, int flags) qemu_fprintf(f, "TLBRENTRY=%016" PRIx64 "\n", env->CSR_TLBRENTRY); qemu_fprintf(f, "TLBRBADV=%016" PRIx64 "\n", env->CSR_TLBRBADV); qemu_fprintf(f, "TLBRERA=%016" PRIx64 "\n", env->CSR_TLBRERA); +qemu_fprintf(f, "TCFG=%016" PRIx64 "\n", env->CSR_TCFG); +qemu_fprintf(f, "TVAL=%016" PRIx64 "\n", env->CSR_TVAL); /* fpr */ if (flags & CPU_DUMP_FPU) {
Re: [risu PATCH 0/5] Add LoongArch LSX/LASX instructions
Ping !! Since [1] series had merged into master three weeks ago, I ping this series again. [1]: https://lore.kernel.org/all/20231103062332.2413724-1-gaos...@loongson.cn/ Thanks. Song Gao 在 2023/11/13 下午4:06, gaosong 写道: Ping ! 在 2023/10/25 下午5:29, Song Gao 写道: Hi, Peter! This series adds LSX/LASX instructions. We tested 10 million instructions without any problems. client: x86 host QEMU + patches [1]. server: 3A5000 host. [1] https://patchwork.kernel.org/project/qemu-devel/list/?series=791633 Please review! Thanks. Song Gao Song Gao (5): loongarch: Add LSX instructions loongarch: Add LASX instructions loongarch: reginfo suport LSX/LASX loongarch: init LASX registers loongarch: Add block 'clean' and clean_lsx_result() loongarch64.risu | 2309 +++- risu_reginfo_loongarch64.c | 107 +- risu_reginfo_loongarch64.h | 3 +- risugen | 2 +- risugen_loongarch64.pm | 30 + 5 files changed, 2418 insertions(+), 33 deletions(-)
Re: [PATCH 1/1] tcg/loongarch64: Fix tcg_out_mov() Aborted
在 2023/11/20 下午11:59, Richard Henderson 写道: On 11/19/23 22:59, Song Gao wrote: On LoongArch host, we got an Aborted from tcg_out_mov(). qemu-x86_64 configure with '--enable-debug'. (gdb) b /home1/gaosong/code/qemu/tcg/loongarch64/tcg-target.c.inc:312 Breakpoint 1 at 0x2576f0: file /home1/gaosong/code/qemu/tcg/loongarch64/tcg-target.c.inc, line 312. (gdb) run hello [...] Thread 1 "qemu-x86_64" hit Breakpoint 1, tcg_out_mov (s=0xe91760 , type=TCG_TYPE_V128, ret=TCG_REG_V2, arg=TCG_REG_V0) at /home1/gaosong/code/qemu/tcg/loongarch64/tcg-target.c.inc:312 312 g_assert_not_reached(); (gdb) bt #0 tcg_out_mov (s=0xe91760 , type=TCG_TYPE_V128, ret=TCG_REG_V2, arg=TCG_REG_V0) at /home1/gaosong/code/qemu/tcg/loongarch64/tcg-target.c.inc:312 #1 0x00d0fee0 in tcg_reg_alloc_mov (s=0xe91760 , op=0xf67c20) at ../tcg/tcg.c:4632 #2 0x00d142f4 in tcg_gen_code (s=0xe91760 , tb=0xffe8030340 , pc_start=4346094) at ../tcg/tcg.c:6135 [...] (gdb) c Continuing. ** ERROR:/home1/gaosong/code/qemu/tcg/loongarch64/tcg-target.c.inc:312:tcg_out_mov: code should not be reached Bail out! ERROR:/home1/gaosong/code/qemu/tcg/loongarch64/tcg-target.c.inc:312:tcg_out_mov: code should not be reached Thread 1 "qemu-x86_64" received signal SIGABRT, Aborted. 0x00fff7b1c390 in raise () from /lib64/libc.so.6 (gdb) q Signed-off-by: Song Gao --- tcg/loongarch64/tcg-target.c.inc | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tcg/loongarch64/tcg-target.c.inc b/tcg/loongarch64/tcg-target.c.inc index a588fb3085..5f68040230 100644 --- a/tcg/loongarch64/tcg-target.c.inc +++ b/tcg/loongarch64/tcg-target.c.inc @@ -308,6 +308,9 @@ static bool tcg_out_mov(TCGContext *s, TCGType type, TCGReg ret, TCGReg arg) */ tcg_out_opc_or(s, ret, arg, TCG_REG_ZERO); break; + case TCG_TYPE_V128: + tcg_out_opc_vaddi_du(s, ret, arg, 0); + break; Is add with immediate zero really the canonical alias for "vector move"? There is often some form that is recommended by the architecture, so that it may be recognized for register renaming. Usually it is some form of logic instruction, not arithmetic. I see that LLVM emits "vori.b dst, src, 0" for this case. adfadf you are right, I see the insn 'mov ' opcode is '0015'. it is 'or dst, src, zero'. Thanks. Song Gao Regardless, this patch works to fix the assert so, Reviewed-by: Richard Henderson r~
Re: [PATCH] linux-headers: Synchronize linux headers from linux v6.7.0-rc1
Hi, Can this patch be merged in during the 8.2 cycle? Thanks. Song Gao 在 2023/11/14 上午9:54, Tianrui Zhao 写道: Use the scripts/update-linux-headers.sh to synchronize linux headers from linux v6.7.0-rc1. We mainly want to add the loongarch linux headers and then add the loongarch kvm support based on it. Signed-off-by: Tianrui Zhao --- include/standard-headers/drm/drm_fourcc.h | 2 + include/standard-headers/linux/pci_regs.h | 24 ++- include/standard-headers/linux/vhost_types.h | 7 + .../standard-headers/linux/virtio_config.h| 5 + linux-headers/asm-arm64/kvm.h | 32 linux-headers/asm-generic/unistd.h| 14 +- linux-headers/asm-loongarch/bitsperlong.h | 1 + linux-headers/asm-loongarch/kvm.h | 108 +++ linux-headers/asm-loongarch/mman.h| 1 + linux-headers/asm-loongarch/unistd.h | 5 + linux-headers/asm-mips/unistd_n32.h | 4 + linux-headers/asm-mips/unistd_n64.h | 4 + linux-headers/asm-mips/unistd_o32.h | 4 + linux-headers/asm-powerpc/unistd_32.h | 4 + linux-headers/asm-powerpc/unistd_64.h | 4 + linux-headers/asm-riscv/kvm.h | 12 ++ linux-headers/asm-s390/unistd_32.h| 4 + linux-headers/asm-s390/unistd_64.h| 4 + linux-headers/asm-x86/unistd_32.h | 4 + linux-headers/asm-x86/unistd_64.h | 3 + linux-headers/asm-x86/unistd_x32.h| 3 + linux-headers/linux/iommufd.h | 180 +- linux-headers/linux/kvm.h | 11 ++ linux-headers/linux/psp-sev.h | 1 + linux-headers/linux/stddef.h | 7 + linux-headers/linux/userfaultfd.h | 9 +- linux-headers/linux/vfio.h| 47 +++-- linux-headers/linux/vhost.h | 8 + 28 files changed, 486 insertions(+), 26 deletions(-) create mode 100644 linux-headers/asm-loongarch/bitsperlong.h create mode 100644 linux-headers/asm-loongarch/kvm.h create mode 100644 linux-headers/asm-loongarch/mman.h create mode 100644 linux-headers/asm-loongarch/unistd.h diff --git a/include/standard-headers/drm/drm_fourcc.h b/include/standard-headers/drm/drm_fourcc.h index 72279f4d25..3afb70160f 100644 --- a/include/standard-headers/drm/drm_fourcc.h +++ b/include/standard-headers/drm/drm_fourcc.h @@ -322,6 +322,8 @@ extern "C" { * index 1 = Cr:Cb plane, [39:0] Cr1:Cb1:Cr0:Cb0 little endian */ #define DRM_FORMAT_NV15 fourcc_code('N', 'V', '1', '5') /* 2x2 subsampled Cr:Cb plane */ +#define DRM_FORMAT_NV20fourcc_code('N', 'V', '2', '0') /* 2x1 subsampled Cr:Cb plane */ +#define DRM_FORMAT_NV30fourcc_code('N', 'V', '3', '0') /* non-subsampled Cr:Cb plane */ /* * 2 plane YCbCr MSB aligned diff --git a/include/standard-headers/linux/pci_regs.h b/include/standard-headers/linux/pci_regs.h index e5f558d964..a39193213f 100644 --- a/include/standard-headers/linux/pci_regs.h +++ b/include/standard-headers/linux/pci_regs.h @@ -80,6 +80,7 @@ #define PCI_HEADER_TYPE_NORMAL 0 #define PCI_HEADER_TYPE_BRIDGE 1 #define PCI_HEADER_TYPE_CARDBUS 2 +#define PCI_HEADER_TYPE_MFD 0x80/* Multi-Function Device (possible) */ #define PCI_BIST 0x0f /* 8 bits */ #define PCI_BIST_CODE_MASK 0x0f/* Return result */ @@ -637,6 +638,7 @@ #define PCI_EXP_RTCAP 0x1e/* Root Capabilities */ #define PCI_EXP_RTCAP_CRSVIS 0x0001 /* CRS Software Visibility capability */ #define PCI_EXP_RTSTA 0x20/* Root Status */ +#define PCI_EXP_RTSTA_PME_RQ_ID 0x /* PME Requester ID */ #define PCI_EXP_RTSTA_PME0x0001 /* PME status */ #define PCI_EXP_RTSTA_PENDING0x0002 /* PME pending */ /* @@ -930,12 +932,13 @@ /* Process Address Space ID */ #define PCI_PASID_CAP 0x04/* PASID feature register */ -#define PCI_PASID_CAP_EXEC0x02/* Exec permissions Supported */ -#define PCI_PASID_CAP_PRIV0x04/* Privilege Mode Supported */ +#define PCI_PASID_CAP_EXEC0x0002 /* Exec permissions Supported */ +#define PCI_PASID_CAP_PRIV0x0004 /* Privilege Mode Supported */ +#define PCI_PASID_CAP_WIDTH 0x1f00 #define PCI_PASID_CTRL0x06/* PASID control register */ -#define PCI_PASID_CTRL_ENABLE 0x01/* Enable bit */ -#define PCI_PASID_CTRL_EXEC 0x02/* Exec permissions Enable */ -#define PCI_PASID_CTRL_PRIV 0x04/* Privilege Mode Enable */ +#define PCI_PASID_CTRL_ENABLE 0x0001 /* Enable bit */ +#define PCI_PASID_CTRL_EXEC 0x0002 /* Exec permissions Enable */ +#define PCI_PASID_CTRL_PRIV 0x0004 /* Privilege Mode Enable */ #define PCI_EXT_CAP_PASID_SIZEOF 8 /* Single Root I/O Virtualization */ @@ -975,6 +978,8 @@ #define PCI_LTR_VALUE_MASK
Re: [risu PATCH 0/5] Add LoongArch LSX/LASX instructions
Ping ! 在 2023/10/25 下午5:29, Song Gao 写道: Hi, Peter! This series adds LSX/LASX instructions. We tested 10 million instructions without any problems. client: x86 host QEMU + patches [1]. server: 3A5000 host. [1] https://patchwork.kernel.org/project/qemu-devel/list/?series=791633 Please review! Thanks. Song Gao Song Gao (5): loongarch: Add LSX instructions loongarch: Add LASX instructions loongarch: reginfo suport LSX/LASX loongarch: init LASX registers loongarch: Add block 'clean' and clean_lsx_result() loongarch64.risu | 2309 +++- risu_reginfo_loongarch64.c | 107 +- risu_reginfo_loongarch64.h |3 +- risugen|2 +- risugen_loongarch64.pm | 30 + 5 files changed, 2418 insertions(+), 33 deletions(-)
Re: [PATCH v1 2/6] target/loongarch: Add set_vec_extctx to set LSX/LASX instructions extctx_flags
在 2023/10/31 下午10:50, Richard Henderson 写道: On 10/30/23 23:16, gaosong wrote: Anyway, I think my previous suggestion is better: Oh, Could you show more details? I think I didn't get you point. If you want to track what the program is using, you should do it exactly like the real kernel: disable the execution unit, have the program trap, and the enable the execution unit when the trap occurs. At this point, CSR_EUEN enable bits contain Untested, but something like this. Got it . Thank you very much. Thanks. Song Gao r~
Re: [PATCH 0/5] Add LoongArch v1.1 instructions
在 2023/10/31 下午7:10, Jiajie Chen 写道: On 2023/10/31 19:06, gaosong wrote: 在 2023/10/31 下午5:13, Jiajie Chen 写道: On 2023/10/31 17:11, gaosong wrote: 在 2023/10/30 下午7:54, Jiajie Chen 写道: On 2023/10/30 16:23, gaosong wrote: 在 2023/10/28 下午9:09, Jiajie Chen 写道: On 2023/10/26 14:54, gaosong wrote: 在 2023/10/26 上午9:38, Jiajie Chen 写道: On 2023/10/26 03:04, Richard Henderson wrote: On 10/25/23 10:13, Jiajie Chen wrote: On 2023/10/24 07:26, Richard Henderson wrote: See target/arm/tcg/translate-a64.c, gen_store_exclusive, TCGv_i128 block. See target/ppc/translate.c, gen_stqcx_. The situation here is slightly different: aarch64 and ppc64 have both 128-bit ll and sc, however LoongArch v1.1 only has 64-bit ll and 128-bit sc. Ah, that does complicate things. Possibly use the combination of ll.d and ld.d: ll.d lo, base, 0 ld.d hi, base, 4 # do some computation sc.q lo, hi, base # try again if sc failed Then a possible implementation of gen_ll() would be: align base to 128-bit boundary, read 128-bit from memory, save 64-bit part to rd and record whole 128-bit data in llval. Then, in gen_sc_q(), it uses a 128-bit cmpxchg. But what about the reversed instruction pattern: ll.d hi, base, 4; ld.d lo, base 0? It would be worth asking your hardware engineers about the bounds of legal behaviour. Ideally there would be some very explicit language, similar to I'm a community developer not affiliated with Loongson. Song Gao, could you provide some detail from Loongson Inc.? ll.d r1, base, 0 dbar 0x700 ==> see 2.2.8.1 ld.d r2, base, 8 ... sc.q r1, r2, base Thanks! I think we may need to detect the ll.d-dbar-ld.d sequence and translate the sequence into one tcg_gen_qemu_ld_i128 and split the result into two 64-bit parts. Can do this in QEMU? Oh, I'm not sure. I think we just need to implement sc.q. We don't need to care about 'll.d-dbar-ld.d'. It's just like 'll.q'. It needs the user to ensure that . ll.q' is 1) ll.d r1 base, 0 ==> set LLbit, load the low 64 bits into r1 2) dbar 0x700 3) ld.d r2 base, 8 ==> load the high 64 bits to r2 sc.q needs to 1) Use 64-bit cmpxchg. 2) Write 128 bits to memory. Consider the following code: ll.d r1, base, 0 dbar 0x700 ld.d r2, base, 8 addi.d r2, r2, 1 sc.q r1, r2, base We translate them into native code: ld.d r1, base, 0 mv LLbit, 1 mv LLaddr, base mv LLval, r1 dbar 0x700 ld.d r2, base, 8 addi.d r2, r2, 1 if (LLbit == 1 && LLaddr == base) { cmpxchg addr=base compare=LLval new=r1 128-bit write {r2, r1} to base if cmpxchg succeeded } set r1 if sc.q succeeded If the memory content of base+8 has changed between ld.d r2 and addi.d r2, the atomicity is not guaranteed, i.e. only the high part has changed, the low part hasn't. Sorry, my mistake. need use cmpxchg_i128. See target/arm/tcg/translate-a64.c gen_store_exclusive(). gen_scq(rd, rk, rj) { ... TCGv_i128 t16 = tcg_temp_new_i128(); TCGv_i128 c16 = tcg_temp_new_i128(); TCGv_i64 low = tcg_temp_new_i64(); TCGv_i64 high= tcg_temp_new_i64(); TCGv_i64 temp = tcg_temp_new_i64(); tcg_gen_concat_i64_i128(t16, cpu_gpr[rd], cpu_gpr[rk])); tcg_gen_qemu_ld(low, cpu_lladdr, ctx->mem_idx, MO_TEUQ); tcg_gen_addi_tl(temp, cpu_lladdr, 8); tcg_gen_mb(TCG_BAR_SC | TCG_MO_LD_LD); tcg_gen_qemu_ld(high, temp, ctx->mem_idx, MO_TEUQ); The problem is that, the high value read here might not equal to the previously read one in ll.d r2, base 8 instruction. I think dbar 0x7000 ensures that the 2 loads in 'll.q' are a 128bit atomic operation. The code does work in real LoongArch machine. However, we are emulating LoongArch in qemu, we have to make it atomic, yet it isn't now. yes, I know, As i said before, we need't care about 'll.q', it needs the user to ensure that. In QEMU, I think the instruction dbar can make it atomic. but I am not sure this is right. static bool trans_dbar() { tcg_gen_mb(TCG_BAR_SC | TCG_MO_ALL); return; } may be this is already enough. or like this: static bool trans_dbar() { TCGBar bar; if (a->hint == 0x700) bar = TCG_BAR_SC | TCG_MO_LD_LD; } else { bar = TCG_BAR_SC | TCG_MO_ALL; } tcg_gen_mb(bar); return true; } Thanks. Song Gao Thanks. Song Gao tcg_gen_concat_i64_i128(c16, low, high); tcg_gen_atomic_cmpxchg_i128(t16, cpu_lladdr, c16, t16, ctx->mem_idx, MO_128); ... } I am not sure this is right. I think Richard can give you more suggestions. @Richard Thanks. Song Gao Thanks. Song Gao For this series, I think we need set the new config bits to the 'max cpu', and change linux-user/target_elf.h ''any' to 'max', so that we can use these new instructions on linux-user mode. I will work on it. Thanks Song Gao https://developer.arm.com/documentation/ddi0487/latest/ B2.9.5 Load-Exclusive and Store-Exclusive instruction usage restriction
Re: [PATCH 0/5] Add LoongArch v1.1 instructions
在 2023/10/31 下午5:13, Jiajie Chen 写道: On 2023/10/31 17:11, gaosong wrote: 在 2023/10/30 下午7:54, Jiajie Chen 写道: On 2023/10/30 16:23, gaosong wrote: 在 2023/10/28 下午9:09, Jiajie Chen 写道: On 2023/10/26 14:54, gaosong wrote: 在 2023/10/26 上午9:38, Jiajie Chen 写道: On 2023/10/26 03:04, Richard Henderson wrote: On 10/25/23 10:13, Jiajie Chen wrote: On 2023/10/24 07:26, Richard Henderson wrote: See target/arm/tcg/translate-a64.c, gen_store_exclusive, TCGv_i128 block. See target/ppc/translate.c, gen_stqcx_. The situation here is slightly different: aarch64 and ppc64 have both 128-bit ll and sc, however LoongArch v1.1 only has 64-bit ll and 128-bit sc. Ah, that does complicate things. Possibly use the combination of ll.d and ld.d: ll.d lo, base, 0 ld.d hi, base, 4 # do some computation sc.q lo, hi, base # try again if sc failed Then a possible implementation of gen_ll() would be: align base to 128-bit boundary, read 128-bit from memory, save 64-bit part to rd and record whole 128-bit data in llval. Then, in gen_sc_q(), it uses a 128-bit cmpxchg. But what about the reversed instruction pattern: ll.d hi, base, 4; ld.d lo, base 0? It would be worth asking your hardware engineers about the bounds of legal behaviour. Ideally there would be some very explicit language, similar to I'm a community developer not affiliated with Loongson. Song Gao, could you provide some detail from Loongson Inc.? ll.d r1, base, 0 dbar 0x700 ==> see 2.2.8.1 ld.d r2, base, 8 ... sc.q r1, r2, base Thanks! I think we may need to detect the ll.d-dbar-ld.d sequence and translate the sequence into one tcg_gen_qemu_ld_i128 and split the result into two 64-bit parts. Can do this in QEMU? Oh, I'm not sure. I think we just need to implement sc.q. We don't need to care about 'll.d-dbar-ld.d'. It's just like 'll.q'. It needs the user to ensure that . ll.q' is 1) ll.d r1 base, 0 ==> set LLbit, load the low 64 bits into r1 2) dbar 0x700 3) ld.d r2 base, 8 ==> load the high 64 bits to r2 sc.q needs to 1) Use 64-bit cmpxchg. 2) Write 128 bits to memory. Consider the following code: ll.d r1, base, 0 dbar 0x700 ld.d r2, base, 8 addi.d r2, r2, 1 sc.q r1, r2, base We translate them into native code: ld.d r1, base, 0 mv LLbit, 1 mv LLaddr, base mv LLval, r1 dbar 0x700 ld.d r2, base, 8 addi.d r2, r2, 1 if (LLbit == 1 && LLaddr == base) { cmpxchg addr=base compare=LLval new=r1 128-bit write {r2, r1} to base if cmpxchg succeeded } set r1 if sc.q succeeded If the memory content of base+8 has changed between ld.d r2 and addi.d r2, the atomicity is not guaranteed, i.e. only the high part has changed, the low part hasn't. Sorry, my mistake. need use cmpxchg_i128. See target/arm/tcg/translate-a64.c gen_store_exclusive(). gen_scq(rd, rk, rj) { ... TCGv_i128 t16 = tcg_temp_new_i128(); TCGv_i128 c16 = tcg_temp_new_i128(); TCGv_i64 low = tcg_temp_new_i64(); TCGv_i64 high= tcg_temp_new_i64(); TCGv_i64 temp = tcg_temp_new_i64(); tcg_gen_concat_i64_i128(t16, cpu_gpr[rd], cpu_gpr[rk])); tcg_gen_qemu_ld(low, cpu_lladdr, ctx->mem_idx, MO_TEUQ); tcg_gen_addi_tl(temp, cpu_lladdr, 8); tcg_gen_mb(TCG_BAR_SC | TCG_MO_LD_LD); tcg_gen_qemu_ld(high, temp, ctx->mem_idx, MO_TEUQ); The problem is that, the high value read here might not equal to the previously read one in ll.d r2, base 8 instruction. I think dbar 0x7000 ensures that the 2 loads in 'll.q' are a 128bit atomic operation. Thanks. Song Gao tcg_gen_concat_i64_i128(c16, low, high); tcg_gen_atomic_cmpxchg_i128(t16, cpu_lladdr, c16, t16, ctx->mem_idx, MO_128); ... } I am not sure this is right. I think Richard can give you more suggestions. @Richard Thanks. Song Gao Thanks. Song Gao For this series, I think we need set the new config bits to the 'max cpu', and change linux-user/target_elf.h ''any' to 'max', so that we can use these new instructions on linux-user mode. I will work on it. Thanks Song Gao https://developer.arm.com/documentation/ddi0487/latest/ B2.9.5 Load-Exclusive and Store-Exclusive instruction usage restrictions But you could do the same thing, aligning and recording the entire 128-bit quantity, then extract the ll.d result based on address bit 6. This would complicate the implementation of sc.d as well, but would perhaps bring us "close enough" to the actual architecture. Note that our Arm store-exclusive implementation isn't quite in spec either. There is quite a large comment within translate-a64.c store_exclusive() about the ways things are not quite right. But it seems to be close enough for actual usage to succeed. r~
Re: [PATCH 0/5] Add LoongArch v1.1 instructions
在 2023/10/30 下午7:54, Jiajie Chen 写道: On 2023/10/30 16:23, gaosong wrote: 在 2023/10/28 下午9:09, Jiajie Chen 写道: On 2023/10/26 14:54, gaosong wrote: 在 2023/10/26 上午9:38, Jiajie Chen 写道: On 2023/10/26 03:04, Richard Henderson wrote: On 10/25/23 10:13, Jiajie Chen wrote: On 2023/10/24 07:26, Richard Henderson wrote: See target/arm/tcg/translate-a64.c, gen_store_exclusive, TCGv_i128 block. See target/ppc/translate.c, gen_stqcx_. The situation here is slightly different: aarch64 and ppc64 have both 128-bit ll and sc, however LoongArch v1.1 only has 64-bit ll and 128-bit sc. Ah, that does complicate things. Possibly use the combination of ll.d and ld.d: ll.d lo, base, 0 ld.d hi, base, 4 # do some computation sc.q lo, hi, base # try again if sc failed Then a possible implementation of gen_ll() would be: align base to 128-bit boundary, read 128-bit from memory, save 64-bit part to rd and record whole 128-bit data in llval. Then, in gen_sc_q(), it uses a 128-bit cmpxchg. But what about the reversed instruction pattern: ll.d hi, base, 4; ld.d lo, base 0? It would be worth asking your hardware engineers about the bounds of legal behaviour. Ideally there would be some very explicit language, similar to I'm a community developer not affiliated with Loongson. Song Gao, could you provide some detail from Loongson Inc.? ll.d r1, base, 0 dbar 0x700 ==> see 2.2.8.1 ld.d r2, base, 8 ... sc.q r1, r2, base Thanks! I think we may need to detect the ll.d-dbar-ld.d sequence and translate the sequence into one tcg_gen_qemu_ld_i128 and split the result into two 64-bit parts. Can do this in QEMU? Oh, I'm not sure. I think we just need to implement sc.q. We don't need to care about 'll.d-dbar-ld.d'. It's just like 'll.q'. It needs the user to ensure that . ll.q' is 1) ll.d r1 base, 0 ==> set LLbit, load the low 64 bits into r1 2) dbar 0x700 3) ld.d r2 base, 8 ==> load the high 64 bits to r2 sc.q needs to 1) Use 64-bit cmpxchg. 2) Write 128 bits to memory. Consider the following code: ll.d r1, base, 0 dbar 0x700 ld.d r2, base, 8 addi.d r2, r2, 1 sc.q r1, r2, base We translate them into native code: ld.d r1, base, 0 mv LLbit, 1 mv LLaddr, base mv LLval, r1 dbar 0x700 ld.d r2, base, 8 addi.d r2, r2, 1 if (LLbit == 1 && LLaddr == base) { cmpxchg addr=base compare=LLval new=r1 128-bit write {r2, r1} to base if cmpxchg succeeded } set r1 if sc.q succeeded If the memory content of base+8 has changed between ld.d r2 and addi.d r2, the atomicity is not guaranteed, i.e. only the high part has changed, the low part hasn't. Sorry, my mistake. need use cmpxchg_i128. See target/arm/tcg/translate-a64.c gen_store_exclusive(). gen_scq(rd, rk, rj) { ... TCGv_i128 t16 = tcg_temp_new_i128(); TCGv_i128 c16 = tcg_temp_new_i128(); TCGv_i64 low = tcg_temp_new_i64(); TCGv_i64 high= tcg_temp_new_i64(); TCGv_i64 temp = tcg_temp_new_i64(); tcg_gen_concat_i64_i128(t16, cpu_gpr[rd], cpu_gpr[rk])); tcg_gen_qemu_ld(low, cpu_lladdr, ctx->mem_idx, MO_TEUQ); tcg_gen_addi_tl(temp, cpu_lladdr, 8); tcg_gen_mb(TCG_BAR_SC | TCG_MO_LD_LD); tcg_gen_qemu_ld(high, temp, ctx->mem_idx, MO_TEUQ); tcg_gen_concat_i64_i128(c16, low, high); tcg_gen_atomic_cmpxchg_i128(t16, cpu_lladdr, c16, t16, ctx->mem_idx, MO_128); ... } I am not sure this is right. I think Richard can give you more suggestions. @Richard Thanks. Song Gao Thanks. Song Gao For this series, I think we need set the new config bits to the 'max cpu', and change linux-user/target_elf.h ''any' to 'max', so that we can use these new instructions on linux-user mode. I will work on it. Thanks Song Gao https://developer.arm.com/documentation/ddi0487/latest/ B2.9.5 Load-Exclusive and Store-Exclusive instruction usage restrictions But you could do the same thing, aligning and recording the entire 128-bit quantity, then extract the ll.d result based on address bit 6. This would complicate the implementation of sc.d as well, but would perhaps bring us "close enough" to the actual architecture. Note that our Arm store-exclusive implementation isn't quite in spec either. There is quite a large comment within translate-a64.c store_exclusive() about the ways things are not quite right. But it seems to be close enough for actual usage to succeed. r~
Re: [PATCH v1 2/6] target/loongarch: Add set_vec_extctx to set LSX/LASX instructions extctx_flags
在 2023/10/30 下午11:30, Richard Henderson 写道: On 10/29/23 20:28, gaosong wrote: 在 2023/10/29 上午5:40, Richard Henderson 写道: On 10/9/23 20:36, Song Gao wrote: Signed-off-by: Song Gao --- target/loongarch/insn_trans/trans_vec.c.inc | 12 target/loongarch/internals.h | 2 ++ 2 files changed, 14 insertions(+) diff --git a/target/loongarch/insn_trans/trans_vec.c.inc b/target/loongarch/insn_trans/trans_vec.c.inc index 98f856bb29..aef16ef44a 100644 --- a/target/loongarch/insn_trans/trans_vec.c.inc +++ b/target/loongarch/insn_trans/trans_vec.c.inc @@ -23,8 +23,20 @@ static bool check_vec(DisasContext *ctx, uint32_t oprsz) #else +static void set_vec_extctx(DisasContext *ctx, uint32_t oprsz) +{ + if (oprsz == 16) { + ctx->extctx_flags |= EXTCTX_FLAGS_LSX; + } + + if (oprsz == 32) { + ctx->extctx_flags |= EXTCTX_FLAGS_LASX; + } +} + static bool check_vec(DisasContext *ctx, uint32_t oprsz) { + set_vec_extctx(ctx, oprsz); return true; } This doesn't do anything. Nothing copies the changed value back to env. Anyway, I think this is the wrong way to go about it. Oh, It is on patch1. @@ -294,6 +296,7 @@ static void loongarch_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs) generate_exception(ctx, EXCCODE_INE); } + env->extctx_flags |= ctx->extctx_flags; Ah, well, this is also incorrect. This copy only happens at translation time, not at execution time. Anyway, I think my previous suggestion is better: Oh, Could you show more details? I think I didn't get you point. If you want to track what the program is using, you should do it exactly like the real kernel: disable the execution unit, have the program trap, and the enable the execution unit when the trap occurs. At this point, CSR_EUEN enable bits contain exactly which units have been used by the program. we always enabled LSX/LASX exception, This is mean that we always use target_lasx_context. Thanks. Song Gao r~
Re: [PATCH 0/5] Add LoongArch v1.1 instructions
在 2023/10/28 下午9:09, Jiajie Chen 写道: On 2023/10/26 14:54, gaosong wrote: 在 2023/10/26 上午9:38, Jiajie Chen 写道: On 2023/10/26 03:04, Richard Henderson wrote: On 10/25/23 10:13, Jiajie Chen wrote: On 2023/10/24 07:26, Richard Henderson wrote: See target/arm/tcg/translate-a64.c, gen_store_exclusive, TCGv_i128 block. See target/ppc/translate.c, gen_stqcx_. The situation here is slightly different: aarch64 and ppc64 have both 128-bit ll and sc, however LoongArch v1.1 only has 64-bit ll and 128-bit sc. Ah, that does complicate things. Possibly use the combination of ll.d and ld.d: ll.d lo, base, 0 ld.d hi, base, 4 # do some computation sc.q lo, hi, base # try again if sc failed Then a possible implementation of gen_ll() would be: align base to 128-bit boundary, read 128-bit from memory, save 64-bit part to rd and record whole 128-bit data in llval. Then, in gen_sc_q(), it uses a 128-bit cmpxchg. But what about the reversed instruction pattern: ll.d hi, base, 4; ld.d lo, base 0? It would be worth asking your hardware engineers about the bounds of legal behaviour. Ideally there would be some very explicit language, similar to I'm a community developer not affiliated with Loongson. Song Gao, could you provide some detail from Loongson Inc.? ll.d r1, base, 0 dbar 0x700 ==> see 2.2.8.1 ld.d r2, base, 8 ... sc.q r1, r2, base Thanks! I think we may need to detect the ll.d-dbar-ld.d sequence and translate the sequence into one tcg_gen_qemu_ld_i128 and split the result into two 64-bit parts. Can do this in QEMU? Oh, I'm not sure. I think we just need to implement sc.q. We don't need to care about 'll.d-dbar-ld.d'. It's just like 'll.q'. It needs the user to ensure that . ll.q' is 1) ll.d r1 base, 0 ==> set LLbit, load the low 64 bits into r1 2) dbar 0x700 3) ld.d r2 base, 8 ==> load the high 64 bits to r2 sc.q needs to 1) Use 64-bit cmpxchg. 2) Write 128 bits to memory. Thanks. Song Gao For this series, I think we need set the new config bits to the 'max cpu', and change linux-user/target_elf.h ''any' to 'max', so that we can use these new instructions on linux-user mode. I will work on it. Thanks Song Gao https://developer.arm.com/documentation/ddi0487/latest/ B2.9.5 Load-Exclusive and Store-Exclusive instruction usage restrictions But you could do the same thing, aligning and recording the entire 128-bit quantity, then extract the ll.d result based on address bit 6. This would complicate the implementation of sc.d as well, but would perhaps bring us "close enough" to the actual architecture. Note that our Arm store-exclusive implementation isn't quite in spec either. There is quite a large comment within translate-a64.c store_exclusive() about the ways things are not quite right. But it seems to be close enough for actual usage to succeed. r~
Re: [PATCH v1 5/6] linux-user/loongarch64: Add LSX sigcontext save/restore
在 2023/10/29 上午5:35, Richard Henderson 写道: On 10/9/23 20:37, Song Gao wrote: Signed-off-by: Song Gao --- linux-user/loongarch64/signal.c | 107 ++-- 1 file changed, 87 insertions(+), 20 deletions(-) diff --git a/linux-user/loongarch64/signal.c b/linux-user/loongarch64/signal.c index 277e9f5757..4b09e50a5f 100644 --- a/linux-user/loongarch64/signal.c +++ b/linux-user/loongarch64/signal.c @@ -33,6 +33,14 @@ struct target_fpu_context { uint32_t fcsr; } QEMU_ALIGNED(FPU_CTX_ALIGN); +#define LSX_CTX_MAGIC 0x53580001 +#define LSX_CTX_ALIGN 16 +struct target_lsx_context { + uint64_t regs[2 * 32]; + uint64_t fcc; + uint32_t fcsr; +} QEMU_ALIGNED(LSX_CTX_ALIGN); It probably doesn't matter here because fo the alignment, but all types within target structures should be using abi_{ullong,uint} etc. Ok, @@ -99,8 +109,15 @@ static abi_ptr setup_extcontext(struct extctx_layout *extctx, abi_ptr sp) /* For qemu, there is no lazy fp context switch, so fp always present. */ extctx->flags = SC_USED_FP; - sp = extframe_alloc(extctx, >fpu, + + if (env->extctx_flags & EXTCTX_FLAGS_LSX) { + sp = extframe_alloc(extctx, >lsx, + sizeof(struct target_lsx_context), LSX_CTX_ALIGN, sp); + + } else if (env->extctx_flags & EXTCTX_FLAGS_FPU) { + sp = extframe_alloc(extctx, >fpu, sizeof(struct target_fpu_context), FPU_CTX_ALIGN, sp); + } I think this is overly complicated. (1) The fpu is always present, and (2) you don't need a special flag on env, you can check the same CSR bits as for system mode. I think extctx_flags is incorrectly named, fp_alive_flags or vec_alive_flags would be more appropriate. The flags function like the kernel's 'thread_lsx_context_live', 'thread_lasx_context_live' functions, checking if the LSX/LASX instructions are used. If we don't use the LSX/LASX instructions, we don't need to use lsx_context/lasx_context even though the LSX/LASX enable bit is set. and EXTCTX_FLAGS_FPU is not required. Thanks. Song Gao I'll note that while this layout matches the kernel, it is an unfortunate set of data structures. Any program has to look for all of {FPU,LSX,LASX}_CTX_MAGIC in order to find the basic fp registers. r~
Re: [PATCH v1 2/6] target/loongarch: Add set_vec_extctx to set LSX/LASX instructions extctx_flags
在 2023/10/29 上午5:40, Richard Henderson 写道: On 10/9/23 20:36, Song Gao wrote: Signed-off-by: Song Gao --- target/loongarch/insn_trans/trans_vec.c.inc | 12 target/loongarch/internals.h | 2 ++ 2 files changed, 14 insertions(+) diff --git a/target/loongarch/insn_trans/trans_vec.c.inc b/target/loongarch/insn_trans/trans_vec.c.inc index 98f856bb29..aef16ef44a 100644 --- a/target/loongarch/insn_trans/trans_vec.c.inc +++ b/target/loongarch/insn_trans/trans_vec.c.inc @@ -23,8 +23,20 @@ static bool check_vec(DisasContext *ctx, uint32_t oprsz) #else +static void set_vec_extctx(DisasContext *ctx, uint32_t oprsz) +{ + if (oprsz == 16) { + ctx->extctx_flags |= EXTCTX_FLAGS_LSX; + } + + if (oprsz == 32) { + ctx->extctx_flags |= EXTCTX_FLAGS_LASX; + } +} + static bool check_vec(DisasContext *ctx, uint32_t oprsz) { + set_vec_extctx(ctx, oprsz); return true; } This doesn't do anything. Nothing copies the changed value back to env. Anyway, I think this is the wrong way to go about it. Oh, It is on patch1. @@ -294,6 +296,7 @@ static void loongarch_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs) generate_exception(ctx, EXCCODE_INE); } + env->extctx_flags |= ctx->extctx_flags; ctx->base.pc_next += 4; Thanks. Song Gao If you want to track what the program is using, you should do it exactly like the real kernel: disable the execution unit, have the program trap, and the enable the execution unit when the trap occurs. At this point, CSR_EUEN enable bits contain exactly which units have been used by the program. r~
Re: [PATCH 0/5] Add LoongArch v1.1 instructions
在 2023/10/26 上午9:38, Jiajie Chen 写道: On 2023/10/26 03:04, Richard Henderson wrote: On 10/25/23 10:13, Jiajie Chen wrote: On 2023/10/24 07:26, Richard Henderson wrote: See target/arm/tcg/translate-a64.c, gen_store_exclusive, TCGv_i128 block. See target/ppc/translate.c, gen_stqcx_. The situation here is slightly different: aarch64 and ppc64 have both 128-bit ll and sc, however LoongArch v1.1 only has 64-bit ll and 128-bit sc. Ah, that does complicate things. Possibly use the combination of ll.d and ld.d: ll.d lo, base, 0 ld.d hi, base, 4 # do some computation sc.q lo, hi, base # try again if sc failed Then a possible implementation of gen_ll() would be: align base to 128-bit boundary, read 128-bit from memory, save 64-bit part to rd and record whole 128-bit data in llval. Then, in gen_sc_q(), it uses a 128-bit cmpxchg. But what about the reversed instruction pattern: ll.d hi, base, 4; ld.d lo, base 0? It would be worth asking your hardware engineers about the bounds of legal behaviour. Ideally there would be some very explicit language, similar to I'm a community developer not affiliated with Loongson. Song Gao, could you provide some detail from Loongson Inc.? ll.d r1, base, 0 dbar 0x700 ==> see 2.2.8.1 ld.d r2, base, 8 ... sc.q r1, r2, base For this series, I think we need set the new config bits to the 'max cpu', and change linux-user/target_elf.h ''any' to 'max', so that we can use these new instructions on linux-user mode. Thanks Song Gao https://developer.arm.com/documentation/ddi0487/latest/ B2.9.5 Load-Exclusive and Store-Exclusive instruction usage restrictions But you could do the same thing, aligning and recording the entire 128-bit quantity, then extract the ll.d result based on address bit 6. This would complicate the implementation of sc.d as well, but would perhaps bring us "close enough" to the actual architecture. Note that our Arm store-exclusive implementation isn't quite in spec either. There is quite a large comment within translate-a64.c store_exclusive() about the ways things are not quite right. But it seems to be close enough for actual usage to succeed. r~
Re: [PATCH v1 0/6] linux-user/loongarch64: Add LSX/LASX sigcontext
Ping ! 在 2023/10/10 上午11:36, Song Gao 写道: Hi, All. This series adds save/restore sigcontext. We use extctx_flags to choces which sigcontext need save/restore. The extctx_flags default value is EXTCTX_FLAGS_FPU, we need save/restore fpu context. After a LSX/LASX instruction is execed, extctx_flags value change to EXTCTX_FLAGS_LSX/LASX, we always need save/restore lsx/lasx context. The test_signal.c is a simple test. The default vreg len is 64. After execed a LSX instruction, the vreg len is 128, and then we exec a FPU instruction, the vreg len is also 128. After execed a LASX instruction, the vreg len is 256, and then we exec a FPU instruction, the vreg len is also 256. test_signal.c: #include #include #include #include #include #include #include #include #include static sigjmp_buf jmpbuf; struct _ctx_layout { struct sctx_info *addr; unsigned int size; }; struct extctx_layout { unsigned long size; unsigned int flags; struct _ctx_layout fpu; struct _ctx_layout lsx; struct _ctx_layout lasx; struct _ctx_layout end; }; static int parse_extcontext(struct sigcontext *sc, struct extctx_layout *extctx) { uint32_t magic, size; struct sctx_info *info = (struct sctx_info *)>sc_extcontext; while(1) { magic = (uint32_t)info->magic; size = (uint32_t)info->size; printf("magic is %lx\n", magic); printf("size is %lx\n", size); switch (magic) { case 0: /* END*/ return 0; case FPU_CTX_MAGIC: if (size < (sizeof(struct sctx_info) + sizeof(struct fpu_context))) { return -1; } extctx->fpu.addr = info; break; case LSX_CTX_MAGIC: if (size < (sizeof(struct sctx_info) + sizeof(struct lsx_context))) { return -1; } extctx->lsx.addr = info; break; case LASX_CTX_MAGIC: if (size < (sizeof(struct sctx_info) + sizeof(struct lasx_context))) { return -1; } extctx->lasx.addr = info; break; default: return -1; } info = (struct sctx_info *)((char *)info +size); } return 0; } static int n = 0; static void do_signal(int sig, siginfo_t *info, void *ucontext) { int i; struct ucontext *uc = (struct ucontext *)ucontext; struct extctx_layout extctx; memset(, 0, sizeof(struct extctx_layout)); printf("pc: %016lx\n", uc->uc_mcontext.sc_pc); parse_extcontext(>uc_mcontext, ); if (n < 5) { printf("extctx.lasx.addr is %lx\n", extctx.lasx.addr); printf("extctx.lsx.addr is %lx\n", extctx.lsx.addr); printf("extctx.fpu.addr is %lx\n", extctx.fpu.addr); if (extctx.lasx.addr) { struct sctx_info *info = extctx.lasx.addr; struct lasx_context *lasx_ctx = (struct lasx_context *)((char *)info + sizeof(struct sctx_info)); printf("vl: %016lx\n", 256); } else if (extctx.lsx.addr) { struct sctx_info *info = extctx.lsx.addr; struct lsx_context *lsx_ctx = (struct lsx_context *)((char *)info + sizeof(struct sctx_info)); printf("vl: %016lx\n", 128); } else if (extctx.fpu.addr) { struct sctx_info *info = extctx.fpu.addr; struct fpu_context *fpu_ctx = (struct fpu_context *)((char *)info + sizeof(struct sctx_info)); printf("vl: %016lx\n", 64); } } n++; printf("n is -- %d\n", n); if (n == 1) { // vaddwev.w.hu$vr27, $vr22, $vr29 asm volatile(".word 0x702ef6db"); printf("After execed LSX instructons vaddwev.w.hu\n"); } if (n == 2) { // 0101395efadd.d $fs6, $ft2, $ft6 asm volatile(".word 0x0101395e"); printf("After execed FPU instructions fadd\n"); } if (n == 3) { // xvextrins.d $xr13, $xr15, 0x59 asm volatile(".word 0x778165ed"); printf("After execed LASX instructions xvextrins.d\n"); } if (n == 4) { // 0101395efadd.d $fs6, $ft2, $ft6 asm volatile(".word 0x0101395e"); printf("After execed FPU instructions fadd\n"); } if (n == 5) { exit(0); } siglongjmp(jmpbuf, 1); } static int setup_signal(int sig, void (*fn) (int, siginfo_t *, void *)) { struct sigaction my_act; int ret; my_act.sa_sigaction = fn; my_act.sa_flags = SA_SIGINFO; sigemptyset(_act.sa_mask); ret = sigaction(sig, _act, NULL); if
Re: [PATCH v2 2/4] target/loongarch: Add cpu feature flags
在 2023/10/20 下午4:05, maobibo 写道: 在 2023/10/19 下午8:58, Song Gao 写道: CPULoongArchState adds cpu feature flags features. Intrduce loongarch_feature() to check feature and set_feature() to set feature. Signed-off-by: Song Gao --- target/loongarch/cpu.c | 4 target/loongarch/cpu.h | 32 2 files changed, 36 insertions(+) diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c index ef6922e812..87fcd08110 100644 --- a/target/loongarch/cpu.c +++ b/target/loongarch/cpu.c @@ -366,6 +366,10 @@ static void loongarch_la464_initfn(Object *obj) CPULoongArchState *env = >env; int i; + env->features = 0; + set_feature(env, CPU_FEATURE_LSX); + set_feature(env, CPU_FEATURE_LASX); + for (i = 0; i < 21; i++) { env->cpucfg[i] = 0x0; } diff --git a/target/loongarch/cpu.h b/target/loongarch/cpu.h index 8b54cf109c..b98064945a 100644 --- a/target/loongarch/cpu.h +++ b/target/loongarch/cpu.h @@ -295,6 +295,8 @@ typedef struct CPUArchState { uint64_t lladdr; /* LL virtual address compared against SC */ uint64_t llval; + uint64_t features; Like what Richard says, it is not necessary to use features here, cpucfg2 can be used directly. Agreed, I dropped this patch on v3. Thanks. Song Gao
Re: [PATCH v1 2/3] target/loongarch: Allow user enable/disable LSX/LASX features
在 2023/10/19 上午7:47, Richard Henderson 写道: On 10/18/23 01:59, Song Gao wrote: Some users may not need LSX/LASX, this patch allows the user enable/disable LSX/LASX features. e.g '-cpu max,lsx=on,lasx=on' (default); '-cpu max,lsx=on,lasx=off' (enabled LSX); '-cpu max,lsx=off,lasx=on' (error, need lsx=on); '-cpu max,lsx=off' (disable LSX and LASX). ... + /* CPU has LSX */ + bool has_lsx; + /* CPU has LASX */ + bool has_lasx; Why do you need these variables? I suspect that you've copied them from one of the more complex Arm cases where we need to resolve multiple properties simultaneously during realize. You'll get identical behaviour in your current code if you drop these and rely only on the CPUCFG2 bits. If you wanted to do something more complex, you could use OnOffAuto, so that you can detect conflicting settings (such as #3 above), but not generate an error for -cpu foo,lasx=on Got it, thanks for you suggestion. where 'foo' is some cpu model which does *no* default lsx=on. You would see that has_lsx==AUTO && has_lasx==ON and then set lsx=ON. Some cpu model not support lasx or lsx feature, we should't allow user set lsx=on or lasx=on. I think we need env->features. set the feature when the cpu model support this feature. If the cpu model support the feature, we allow user set CPUCFG to enable/disable this feature. Do you have more suggestion? Thanks. Song Gao
Re: [PATCH] MAINTAINERS: Add include/hw/intc/loongson_liointc.h to the Loongson-3 virt section
在 2023/10/17 下午11:33, Thomas Huth 写道: The corresponding .c file is already listed here, so we should mention the header here, too. Signed-off-by: Thomas Huth --- MAINTAINERS | 1 + 1 file changed, 1 insertion(+) diff --git a/MAINTAINERS b/MAINTAINERS index d0a21cfd9f..c3eb4f90ef 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1359,6 +1359,7 @@ F: hw/intc/loongson_liointc.c F: hw/mips/loongson3_bootp.c F: hw/mips/loongson3_bootp.h F: hw/mips/loongson3_virt.c +F: include/hw/intc/loongson_liointc.h F: tests/avocado/machine_mips_loongson3v.py Boston Acked-by: Song Gao Thanks. Song Gao
Re: [PATCH v2 1/2] tcg: Add tcg_gen_{ld,st}_i128
在 2023/10/14 上午1:51, Richard Henderson 写道: Do not require the translators to jump through concat and extract of i64 in order to move values to and from env. Signed-off-by: Richard Henderson --- include/tcg/tcg-op-common.h | 3 +++ tcg/tcg-op.c| 22 ++ 2 files changed, 25 insertions(+) Reviewed-by: Song Gao Thanks. Song Gao diff --git a/include/tcg/tcg-op-common.h b/include/tcg/tcg-op-common.h index 2048f92b5e..56d4e9cb9f 100644 --- a/include/tcg/tcg-op-common.h +++ b/include/tcg/tcg-op-common.h @@ -747,6 +747,9 @@ void tcg_gen_mov_i128(TCGv_i128 dst, TCGv_i128 src); void tcg_gen_extr_i128_i64(TCGv_i64 lo, TCGv_i64 hi, TCGv_i128 arg); void tcg_gen_concat_i64_i128(TCGv_i128 ret, TCGv_i64 lo, TCGv_i64 hi); +void tcg_gen_ld_i128(TCGv_i128 ret, TCGv_ptr base, tcg_target_long offset); +void tcg_gen_st_i128(TCGv_i128 val, TCGv_ptr base, tcg_target_long offset); + static inline void tcg_gen_concat32_i64(TCGv_i64 ret, TCGv_i64 lo, TCGv_i64 hi) { tcg_gen_deposit_i64(ret, lo, hi, 32, 32); diff --git a/tcg/tcg-op.c b/tcg/tcg-op.c index 393dbcd01c..12bcedf42f 100644 --- a/tcg/tcg-op.c +++ b/tcg/tcg-op.c @@ -2880,6 +2880,28 @@ void tcg_gen_mov_i128(TCGv_i128 dst, TCGv_i128 src) } } +void tcg_gen_ld_i128(TCGv_i128 ret, TCGv_ptr base, tcg_target_long offset) +{ +if (HOST_BIG_ENDIAN) { +tcg_gen_ld_i64(TCGV128_HIGH(ret), base, offset); +tcg_gen_ld_i64(TCGV128_LOW(ret), base, offset + 8); +} else { +tcg_gen_ld_i64(TCGV128_LOW(ret), base, offset); +tcg_gen_ld_i64(TCGV128_HIGH(ret), base, offset + 8); +} +} + +void tcg_gen_st_i128(TCGv_i128 val, TCGv_ptr base, tcg_target_long offset) +{ +if (HOST_BIG_ENDIAN) { +tcg_gen_st_i64(TCGV128_HIGH(val), base, offset); +tcg_gen_st_i64(TCGV128_LOW(val), base, offset + 8); +} else { +tcg_gen_st_i64(TCGV128_LOW(val), base, offset); +tcg_gen_st_i64(TCGV128_HIGH(val), base, offset + 8); +} +} + /* QEMU specific operations. */ void tcg_gen_exit_tb(const TranslationBlock *tb, unsigned idx)
Re: [RFC PATCH 0/2] target/loongarch: Use i128 for 128-bit loads/stores
在 2023/10/17 下午8:38, Philippe Mathieu-Daudé 写道: RFC because unsure and untested... Based-on: <20231013175109.124308-1-richard.hender...@linaro.org> tcg: Add tcg_gen_{ld,st}_i128 Philippe Mathieu-Daudé (2): target/loongarch: Use i128 for 128-bit load/store in VST[X]/XVST target/loongarch: Use i128 for 128-bit load/store in XVLD target/loongarch/translate.c| 12 ++ target/loongarch/insn_trans/trans_vec.c.inc | 46 +++-- 2 files changed, 28 insertions(+), 30 deletions(-) I had tested it, you can drop the 'RFC' title. Tested-by: Song Gao Thanks. Song Gao
Re: [PATCH 0/4] tcg: Optimize loads and stores to env
在 2023/8/31 上午10:57, Richard Henderson 写道: This is aimed at improving gvec generated code, which involves large numbers of loads and stores to the env slots of the guest cpu vector registers. The final patch helps eliminate redundant zero-extensions that can appear with e.g. avx2 and sve. From the small amount of timing that I have done, there is no change. But of course as we all know, x86 is very good with redundant memory. And frankly, I haven't found a good test case for measuring. What I need is an algorithm with lots of integer vector code that can be expanded with gvec. Most of what I've found is either fp (out of line) or too simple (small translation blocks with little scope for optimization). That said, it appears to be simple enough, and does eliminate some redundant operations, even in places that I didn't expect. r~ Richard Henderson (4): tcg: Don't free vector results tcg/optimize: Pipe OptContext into reset_ts tcg: Optimize env memory operations tcg: Eliminate duplicate env store operations tcg/optimize.c| 226 -- tcg/tcg-op-gvec.c | 39 ++-- 2 files changed, 225 insertions(+), 40 deletions(-) Patch 1 and Patch 3, s -i "/cpu_env/tcg_env/g " Reviewed-by: Song Gao Thanks. Song Gao
Re: [RFC PATCH v3 01/78] include/qemu/compiler.h: replace QEMU_FALLTHROUGH with fallthrough
在 2023/10/13 下午4:45, Emmanouil Pitsidianakis 写道: Signed-off-by: Emmanouil Pitsidianakis --- audio/pwaudio.c | 8 hw/arm/smmuv3.c | 2 +- include/qemu/compiler.h | 30 +++--- include/qemu/osdep.h | 4 ++-- target/loongarch/cpu.c | 4 ++-- target/loongarch/translate.c | 2 +- tcg/optimize.c | 8 7 files changed, 37 insertions(+), 21 deletions(-) For LoongArch: Reviewed-by: Song Gao Thanks. Song Gao. diff --git a/audio/pwaudio.c b/audio/pwaudio.c index 3ce5f6507b..bf26fadb06 100644 --- a/audio/pwaudio.c +++ b/audio/pwaudio.c @@ -8,16 +8,16 @@ * SPDX-License-Identifier: GPL-2.0-or-later */ +#include +#include +#include +#include #include "qemu/osdep.h" #include "qemu/module.h" #include "audio.h" #include #include "qemu/error-report.h" #include "qapi/error.h" -#include -#include -#include -#include #include #include "trace.h" diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c index 6f2b2bd45f..545d82ff04 100644 --- a/hw/arm/smmuv3.c +++ b/hw/arm/smmuv3.c @@ -1291,7 +1291,7 @@ static int smmuv3_cmdq_consume(SMMUv3State *s) cmd_error = SMMU_CERROR_ILL; break; } -QEMU_FALLTHROUGH; +fallthrough; case SMMU_CMD_TLBI_NSNH_ALL: trace_smmuv3_cmdq_tlbi_nh(); smmu_inv_notifiers_all(>smmu_state); diff --git a/include/qemu/compiler.h b/include/qemu/compiler.h index 1109482a00..959982805d 100644 --- a/include/qemu/compiler.h +++ b/include/qemu/compiler.h @@ -165,15 +165,31 @@ #define QEMU_ALWAYS_INLINE #endif -/** - * In most cases, normal "fallthrough" comments are good enough for - * switch-case statements, but sometimes the compiler has problems - * with those. In that case you can use QEMU_FALLTHROUGH instead. +/* + * Add the pseudo keyword 'fallthrough' so case statement blocks + * must end with any of these keywords: + * break; + * fallthrough; + * continue; + * goto ; + * return [expression]; + * + * gcc: https://gcc.gnu.org/onlinedocs/gcc/Statement-Attributes.html#Statement-Attributes */ -#if __has_attribute(fallthrough) -# define QEMU_FALLTHROUGH __attribute__((fallthrough)) + +/* + * glib_macros.h contains its own definition of fallthrough, so if we define + * the pseudokeyword here it will expand when the glib header checks for the + * attribute. glib headers must be #included after this header. + */ +#ifdef fallthrough +#undef fallthrough +#endif + +#if __has_attribute(__fallthrough__) +# define fallthrough__attribute__((__fallthrough__)) #else -# define QEMU_FALLTHROUGH do {} while (0) /* fallthrough */ +# define fallthroughdo {} while (0) /* fallthrough */ #endif #ifdef CONFIG_CFI diff --git a/include/qemu/osdep.h b/include/qemu/osdep.h index 475a1c62ff..8f790f0deb 100644 --- a/include/qemu/osdep.h +++ b/include/qemu/osdep.h @@ -50,8 +50,6 @@ */ #pragma GCC poison TARGET_WORDS_BIGENDIAN -#include "qemu/compiler.h" - /* Older versions of C++ don't get definitions of various macros from * stdlib.h unless we define these macros before first inclusion of * that system header. @@ -160,6 +158,8 @@ QEMU_EXTERN_C int daemon(int, int); */ #include "glib-compat.h" +#include "qemu/compiler.h" + #ifdef _WIN32 #include "sysemu/os-win32.h" #endif diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c index 2bea7ca5d5..e01d626b15 100644 --- a/target/loongarch/cpu.c +++ b/target/loongarch/cpu.c @@ -178,7 +178,7 @@ static void loongarch_cpu_do_interrupt(CPUState *cs) env->CSR_DBG = FIELD_DP64(env->CSR_DBG, CSR_DBG, DEI, 1); goto set_DERA; } -QEMU_FALLTHROUGH; +fallthrough; case EXCCODE_PIF: case EXCCODE_ADEF: cause = cs->exception_index; @@ -193,7 +193,7 @@ static void loongarch_cpu_do_interrupt(CPUState *cs) case EXCCODE_SXD: case EXCCODE_ASXD: env->CSR_BADV = env->pc; -QEMU_FALLTHROUGH; +fallthrough; case EXCCODE_BCE: case EXCCODE_ADEM: case EXCCODE_PIL: diff --git a/target/loongarch/translate.c b/target/loongarch/translate.c index 21f4db6fbd..36fceb1beb 100644 --- a/target/loongarch/translate.c +++ b/target/loongarch/translate.c @@ -317,7 +317,7 @@ static void loongarch_tr_tb_stop(DisasContextBase *dcbase, CPUState *cs) break; case DISAS_EXIT_UPDATE: tcg_gen_movi_tl(cpu_pc, ctx->base.pc_next); -QEMU_FALLTHROUGH; +fallthrough; case DISAS_EXIT: tcg_gen_exit_tb(NULL, 0); break; diff --git a/tcg/optimize.c b/tcg/optimize.c index 3013eb04e6..3da135a353 100644 --- a/tcg/optimize.c +++ b/tcg/optimize.c @@ -1089,7 +1089,7 @@ static bool fold_brcond2(OptContext *ctx, TCGOp *op) case TCG_COND_NE: inv = 1; -QEMU_FALLTHROUGH; +
Re: [PATCH 1/1] LoongArch: step down as general arch maintainer
在 2023/10/12 下午5:51, Xiaojuan Yang 写道: I haven't really been working on LoongArch for some time now, so let's remove myself from this entry. Signed-off-by: Xiaojuan Yang --- MAINTAINERS | 2 -- 1 file changed, 2 deletions(-) Acked-by: Song Gao Thanks. Song Gao diff --git a/MAINTAINERS b/MAINTAINERS index c3cc12dc29..5c386f1f37 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -248,7 +248,6 @@ F: disas/hppa.c LoongArch TCG CPUs M: Song Gao -M: Xiaojuan Yang S: Maintained F: target/loongarch/ F: tests/tcg/loongarch64/ @@ -1182,7 +1181,6 @@ F: pc-bios/hppa-firmware.img LoongArch Machines -- Virt -M: Xiaojuan Yang M: Song Gao S: Maintained F: docs/system/loongarch/virt.rst
Re: [PATCH 0/2] hw/loongarch/virt: Remove unused ISA bus
在 2023/10/10 下午9:53, Philippe Mathieu-Daudé 写道: ISA bus and serial aren't used by the LoongArch virt machine. Remove the dead code. Philippe Mathieu-Daudé (2): hw/loongarch/virt: Remove unused ISA UART hw/loongarch/virt: Remove unused ISA Bus include/hw/loongarch/virt.h | 3 --- hw/loongarch/virt.c | 5 - hw/loongarch/Kconfig| 2 -- 3 files changed, 10 deletions(-) Reviewed-by: Song Gao Thanks. Song Gao
Re: [PATCH 06/18] target/loongarch: Declare QOM definitions in 'cpu-qom.h'
在 2023/10/10 下午5:28, Philippe Mathieu-Daudé 写道: "target/foo/cpu.h" contains the target specific declarations. A heterogeneous setup need to access target agnostic declarations (at least the QOM ones, to instantiate the objects). Our convention is to add such target agnostic QOM declarations in the "target/foo/cpu-qom.h" header. Extract QOM definitions from "cpu.h" to "cpu-qom.h". Signed-off-by: Philippe Mathieu-Daudé --- target/loongarch/cpu-qom.h | 38 ++ target/loongarch/cpu.h | 26 +- 2 files changed, 39 insertions(+), 25 deletions(-) create mode 100644 target/loongarch/cpu-qom.h Reviewed-by: Song Gao Thanks. Song Gao diff --git a/target/loongarch/cpu-qom.h b/target/loongarch/cpu-qom.h new file mode 100644 index 00..d577af9f6e --- /dev/null +++ b/target/loongarch/cpu-qom.h @@ -0,0 +1,38 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * QEMU LoongArch CPU QOM header (target agnostic) + * + * Copyright (c) 2021 Loongson Technology Corporation Limited + */ + +#ifndef LOONGARCH_CPU_QOM_H +#define LOONGARCH_CPU_QOM_H + +#include "hw/core/cpu.h" +#include "qom/object.h" + +#define TYPE_LOONGARCH_CPU "loongarch-cpu" +#define TYPE_LOONGARCH32_CPU "loongarch32-cpu" +#define TYPE_LOONGARCH64_CPU "loongarch64-cpu" + +OBJECT_DECLARE_CPU_TYPE(LoongArchCPU, LoongArchCPUClass, +LOONGARCH_CPU) + +#define LOONGARCH_CPU_TYPE_SUFFIX "-" TYPE_LOONGARCH_CPU +#define LOONGARCH_CPU_TYPE_NAME(model) model LOONGARCH_CPU_TYPE_SUFFIX + +/** + * LoongArchCPUClass: + * @parent_realize: The parent class' realize handler. + * @parent_phases: The parent class' reset phase handlers. + * + * A LoongArch CPU model. + */ +struct LoongArchCPUClass { +CPUClass parent_class; + +DeviceRealize parent_realize; +ResettablePhases parent_phases; +}; + +#endif diff --git a/target/loongarch/cpu.h b/target/loongarch/cpu.h index 40e70a8119..22cebc6280 100644 --- a/target/loongarch/cpu.h +++ b/target/loongarch/cpu.h @@ -17,6 +17,7 @@ #include "exec/memory.h" #endif #include "cpu-csr.h" +#include "cpu-qom.h" #define IOCSRF_TEMP 0 #define IOCSRF_NODECNT 1 @@ -383,29 +384,6 @@ struct ArchCPU { const char *dtb_compatible; }; -#define TYPE_LOONGARCH_CPU "loongarch-cpu" -#define TYPE_LOONGARCH32_CPU "loongarch32-cpu" -#define TYPE_LOONGARCH64_CPU "loongarch64-cpu" - -OBJECT_DECLARE_CPU_TYPE(LoongArchCPU, LoongArchCPUClass, -LOONGARCH_CPU) - -/** - * LoongArchCPUClass: - * @parent_realize: The parent class' realize handler. - * @parent_phases: The parent class' reset phase handlers. - * - * A LoongArch CPU model. - */ -struct LoongArchCPUClass { -/*< private >*/ -CPUClass parent_class; -/*< public >*/ - -DeviceRealize parent_realize; -ResettablePhases parent_phases; -}; - /* * LoongArch CPUs has 4 privilege levels. * 0 for kernel mode, 3 for user mode. @@ -482,8 +460,6 @@ void loongarch_cpu_list(void); #include "exec/cpu-all.h" -#define LOONGARCH_CPU_TYPE_SUFFIX "-" TYPE_LOONGARCH_CPU -#define LOONGARCH_CPU_TYPE_NAME(model) model LOONGARCH_CPU_TYPE_SUFFIX #define CPU_RESOLVING_TYPE TYPE_LOONGARCH_CPU #endif /* LOONGARCH_CPU_H */
Re: [PATCH v2] hw/loongarch: remove global loaderparams variable
在 2023/10/10 下午5:49, Thomas Weißschuh 写道: Passing the struct around explicitly makes the control-flow more obvious. Reviewed-by: Philippe Mathieu-Daudé Signed-off-by: Thomas Weißschuh --- Changes in v2: - Drop initialize loaderparams variable - Link to v1: https://lore.kernel.org/qemu-devel/20231009210018.249776-1-tho...@t-8ch.de/ --- hw/loongarch/virt.c | 50 +++--- 1 file changed, 27 insertions(+), 23 deletions(-) Reviewed-by: Song Gao Thanks. SOng Gao diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c index 2629128aeda4..88bf0b0e97e1 100644 --- a/hw/loongarch/virt.c +++ b/hw/loongarch/virt.c @@ -47,6 +47,13 @@ #include "qemu/error-report.h" +struct loaderparams { +uint64_t ram_size; +const char *kernel_filename; +const char *kernel_cmdline; +const char *initrd_filename; +}; + static void virt_flash_create(LoongArchMachineState *lams) { DeviceState *dev = qdev_new(TYPE_PFLASH_CFI01); @@ -411,24 +418,17 @@ static const MemoryRegionOps loongarch_virt_pm_ops = { } }; -static struct _loaderparams { -uint64_t ram_size; -const char *kernel_filename; -const char *kernel_cmdline; -const char *initrd_filename; -} loaderparams; - static uint64_t cpu_loongarch_virt_to_phys(void *opaque, uint64_t addr) { return addr & MAKE_64BIT_MASK(0, TARGET_PHYS_ADDR_SPACE_BITS); } -static int64_t load_kernel_info(void) +static int64_t load_kernel_info(const struct loaderparams *loaderparams) { uint64_t kernel_entry, kernel_low, kernel_high; ssize_t kernel_size; -kernel_size = load_elf(loaderparams.kernel_filename, NULL, +kernel_size = load_elf(loaderparams->kernel_filename, NULL, cpu_loongarch_virt_to_phys, NULL, _entry, _low, _high, NULL, 0, @@ -436,7 +436,7 @@ static int64_t load_kernel_info(void) if (kernel_size < 0) { error_report("could not load kernel '%s': %s", - loaderparams.kernel_filename, + loaderparams->kernel_filename, load_elf_strerror(kernel_size)); exit(1); } @@ -728,7 +728,8 @@ static void reset_load_elf(void *opaque) } } -static void fw_cfg_add_kernel_info(FWCfgState *fw_cfg) +static void fw_cfg_add_kernel_info(const struct loaderparams *loaderparams, + FWCfgState *fw_cfg) { /* * Expose the kernel, the command line, and the initrd in fw_cfg. @@ -737,36 +738,38 @@ static void fw_cfg_add_kernel_info(FWCfgState *fw_cfg) */ load_image_to_fw_cfg(fw_cfg, FW_CFG_KERNEL_SIZE, FW_CFG_KERNEL_DATA, - loaderparams.kernel_filename, + loaderparams->kernel_filename, false); -if (loaderparams.initrd_filename) { +if (loaderparams->initrd_filename) { load_image_to_fw_cfg(fw_cfg, FW_CFG_INITRD_SIZE, FW_CFG_INITRD_DATA, - loaderparams.initrd_filename, false); + loaderparams->initrd_filename, false); } -if (loaderparams.kernel_cmdline) { +if (loaderparams->kernel_cmdline) { fw_cfg_add_i32(fw_cfg, FW_CFG_CMDLINE_SIZE, - strlen(loaderparams.kernel_cmdline) + 1); + strlen(loaderparams->kernel_cmdline) + 1); fw_cfg_add_string(fw_cfg, FW_CFG_CMDLINE_DATA, - loaderparams.kernel_cmdline); + loaderparams->kernel_cmdline); } } -static void loongarch_firmware_boot(LoongArchMachineState *lams) +static void loongarch_firmware_boot(LoongArchMachineState *lams, +const struct loaderparams *loaderparams) { -fw_cfg_add_kernel_info(lams->fw_cfg); +fw_cfg_add_kernel_info(loaderparams, lams->fw_cfg); } -static void loongarch_direct_kernel_boot(LoongArchMachineState *lams) +static void loongarch_direct_kernel_boot(LoongArchMachineState *lams, + const struct loaderparams *loaderparams) { MachineState *machine = MACHINE(lams); int64_t kernel_addr = 0; LoongArchCPU *lacpu; int i; -kernel_addr = load_kernel_info(); +kernel_addr = load_kernel_info(loaderparams); if (!machine->firmware) { for (i = 0; i < machine->smp.cpus; i++) { lacpu = LOONGARCH_CPU(qemu_get_cpu(i)); @@ -793,6 +796,7 @@ static void loongarch_init(MachineState *machine) MachineClass *mc = MACHINE_GET_CLASS(machine); CPUState *cpu; char *ramName = NULL; +struct loaderparams loaderparams = { }; if (!cpu_model) { cpu_model = LOONGARCH_CPU_TYPE_NAME("la464"); @@ -898,9 +902,9 @@ static void loongarch_init(MachineState
Re: [PATCH] target/loongarch: fix ASXE flag conflict
在 2023/9/30 下午11:46, Richard Henderson 写道: On 9/30/23 04:28, Jiajie Chen wrote: HW_FLAGS_EUEN_ASXE acccidentally conflicts with HW_FLAGS_CRMD_PG, enabling LASX instructions even when CSR_EUEN.ASXE=0. Closes: https://gitlab.com/qemu-project/qemu/-/issues/1907 >> Signed-off-by: Jiajie Chen --- target/loongarch/cpu.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/target/loongarch/cpu.h b/target/loongarch/cpu.h index f125a8e49b..79ad79a289 100644 --- a/target/loongarch/cpu.h +++ b/target/loongarch/cpu.h @@ -462,7 +462,7 @@ static inline void set_pc(CPULoongArchState *env, uint64_t value) #define HW_FLAGS_CRMD_PG R_CSR_CRMD_PG_MASK /* 0x10 */ #define HW_FLAGS_EUEN_FPE 0x04 #define HW_FLAGS_EUEN_SXE 0x08 -#define HW_FLAGS_EUEN_ASXE 0x10 +#define HW_FLAGS_EUEN_ASXE 0x40 #define HW_FLAGS_VA32 0x20 static inline void cpu_get_tb_cpu_state(CPULoongArchState *env, vaddr *pc, Better to put all defines in bit order, otherwise it will be easy to make the same mistake again. > With that, Reviewed-by: Richard Henderson r Reviewed-by: Song Gao Thanks. Song Gao