Skip to content

Commit c10ed2f

Browse files
committed
Merge tag 'pull-loongarch-20250109' of https://gitlab.com/bibo-mao/qemu into staging
loongarch queue # -----BEGIN PGP SIGNATURE----- # # iHUEABYKAB0WIQQNhkKjomWfgLCz0aQfewwSUazn0QUCZ39pJgAKCRAfewwSUazn # 0YpMAQCNV9KJJ8f8EaXAw5a87mnmlcP0vRi5gZiyv1ZV9gRqPgEAhzCn/rnzpzd+ # H3B1fRlD1xmaQ8IqRugQ4vfDBd9CyQY= # =OG4d # -----END PGP SIGNATURE----- # gpg: Signature made Thu 09 Jan 2025 01:13:58 EST # gpg: using EDDSA key 0D8642A3A2659F80B0B3D1A41F7B0C1251ACE7D1 # gpg: Good signature from "bibo mao <[email protected]>" [unknown] # gpg: WARNING: This key is not certified with a trusted signature! # gpg: There is no indication that the signature belongs to the owner. # Primary key fingerprint: 7044 3A00 19C0 E97A 31C7 13C4 8E86 8FB7 A176 9D4C # Subkey fingerprint: 0D86 42A3 A265 9F80 B0B3 D1A4 1F7B 0C12 51AC E7D1 * tag 'pull-loongarch-20250109' of https://gitlab.com/bibo-mao/qemu: hw/intc/loongarch_extioi: Add irq routing support from physical id hw/intc/loongarch_extioi: Remove num-cpu property hw/intc/loongarch_extioi: Get cpu number from possible_cpu_arch_ids target/loongarch: Only support 64bit pte width hw/loongarch/boot: Support Linux raw boot image hw/core/loader: Use ssize_t for efi zboot unpacker Signed-off-by: Stefan Hajnoczi <[email protected]>
2 parents 3f8bcbb + c3afa71 commit c10ed2f

File tree

12 files changed

+142
-33
lines changed

12 files changed

+142
-33
lines changed

hw/arm/boot.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -857,7 +857,7 @@ static uint64_t load_aarch64_image(const char *filename, hwaddr mem_base,
857857
hwaddr kernel_load_offset = KERNEL64_LOAD_ADDR;
858858
uint64_t kernel_size = 0;
859859
uint8_t *buffer;
860-
int size;
860+
ssize_t size;
861861

862862
/* On aarch64, it's the bootloader's job to uncompress the kernel. */
863863
size = load_image_gzipped_buffer(filename, LOAD_IMAGE_MAX_GUNZIP_BYTES,

hw/core/loader.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -886,11 +886,11 @@ struct linux_efi_zboot_header {
886886
*
887887
* If the image is not a Linux EFI zboot image, do nothing and return success.
888888
*/
889-
ssize_t unpack_efi_zboot_image(uint8_t **buffer, int *size)
889+
ssize_t unpack_efi_zboot_image(uint8_t **buffer, ssize_t *size)
890890
{
891891
const struct linux_efi_zboot_header *header;
892892
uint8_t *data = NULL;
893-
int ploff, plsize;
893+
ssize_t ploff, plsize;
894894
ssize_t bytes;
895895

896896
/* ignore if this is too small to be a EFI zboot image */

hw/intc/loongarch_extioi.c

Lines changed: 26 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,23 @@
1515
#include "hw/intc/loongarch_extioi.h"
1616
#include "trace.h"
1717

18+
static int extioi_get_index_from_archid(LoongArchExtIOICommonState *s,
19+
uint64_t arch_id)
20+
{
21+
int i;
22+
23+
for (i = 0; i < s->num_cpu; i++) {
24+
if (s->cpu[i].arch_id == arch_id) {
25+
break;
26+
}
27+
}
28+
29+
if ((i < s->num_cpu) && s->cpu[i].cpu) {
30+
return i;
31+
}
32+
33+
return -1;
34+
}
1835

1936
static void extioi_update_irq(LoongArchExtIOICommonState *s, int irq, int level)
2037
{
@@ -125,7 +142,7 @@ static inline void extioi_enable_irq(LoongArchExtIOICommonState *s, int index,\
125142
static inline void extioi_update_sw_coremap(LoongArchExtIOICommonState *s,
126143
int irq, uint64_t val, bool notify)
127144
{
128-
int i, cpu;
145+
int i, cpu, cpuid;
129146

130147
/*
131148
* loongarch only support little endian,
@@ -134,12 +151,17 @@ static inline void extioi_update_sw_coremap(LoongArchExtIOICommonState *s,
134151
val = cpu_to_le64(val);
135152

136153
for (i = 0; i < 4; i++) {
137-
cpu = val & 0xff;
154+
cpuid = val & 0xff;
138155
val = val >> 8;
139156

140157
if (!(s->status & BIT(EXTIOI_ENABLE_CPU_ENCODE))) {
141-
cpu = ctz32(cpu);
142-
cpu = (cpu >= 4) ? 0 : cpu;
158+
cpuid = ctz32(cpuid);
159+
cpuid = (cpuid >= 4) ? 0 : cpuid;
160+
}
161+
162+
cpu = extioi_get_index_from_archid(s, cpuid);
163+
if (cpu < 0) {
164+
continue;
143165
}
144166

145167
if (s->sw_coremap[irq + i] == cpu) {
@@ -347,12 +369,6 @@ static void loongarch_extioi_realize(DeviceState *dev, Error **errp)
347369
s->status |= BIT(EXTIOI_ENABLE);
348370
}
349371

350-
s->cpu = g_new0(ExtIOICore, s->num_cpu);
351-
if (s->cpu == NULL) {
352-
error_setg(errp, "Memory allocation for ExtIOICore faile");
353-
return;
354-
}
355-
356372
for (i = 0; i < s->num_cpu; i++) {
357373
for (pin = 0; pin < LS3A_INTC_IP; pin++) {
358374
qdev_init_gpio_out(dev, &s->cpu[i].parent_irq[pin], 1);

hw/intc/loongarch_extioi_common.c

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,24 @@
1313
static void loongarch_extioi_common_realize(DeviceState *dev, Error **errp)
1414
{
1515
LoongArchExtIOICommonState *s = (LoongArchExtIOICommonState *)dev;
16+
MachineState *machine = MACHINE(qdev_get_machine());
17+
MachineClass *mc = MACHINE_GET_CLASS(machine);
18+
const CPUArchIdList *id_list;
19+
int i;
1620

17-
if (s->num_cpu == 0) {
18-
error_setg(errp, "num-cpu must be at least 1");
21+
assert(mc->possible_cpu_arch_ids);
22+
id_list = mc->possible_cpu_arch_ids(machine);
23+
s->num_cpu = id_list->len;
24+
s->cpu = g_new0(ExtIOICore, s->num_cpu);
25+
if (s->cpu == NULL) {
26+
error_setg(errp, "Memory allocation for ExtIOICore faile");
1927
return;
2028
}
29+
30+
for (i = 0; i < s->num_cpu; i++) {
31+
s->cpu[i].arch_id = id_list->cpus[i].arch_id;
32+
s->cpu[i].cpu = CPU(id_list->cpus[i].cpu);
33+
}
2134
}
2235

2336
static int loongarch_extioi_common_pre_save(void *opaque)
@@ -82,7 +95,6 @@ static const VMStateDescription vmstate_loongarch_extioi = {
8295
};
8396

8497
static const Property extioi_properties[] = {
85-
DEFINE_PROP_UINT32("num-cpu", LoongArchExtIOICommonState, num_cpu, 1),
8698
DEFINE_PROP_BIT("has-virtualization-extension", LoongArchExtIOICommonState,
8799
features, EXTIOI_HAS_VIRT_EXTENSION, 0),
88100
};

hw/loongarch/boot.c

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,26 @@
1515
#include "system/reset.h"
1616
#include "system/qtest.h"
1717

18+
/*
19+
* Linux Image Format
20+
* https://docs.kernel.org/arch/loongarch/booting.html
21+
*/
22+
#define LINUX_PE_MAGIC 0x818223cd
23+
#define MZ_MAGIC 0x5a4d /* "MZ" */
24+
25+
struct loongarch_linux_hdr {
26+
uint32_t mz_magic;
27+
uint32_t res0;
28+
uint64_t kernel_entry;
29+
uint64_t kernel_size;
30+
uint64_t load_offset;
31+
uint64_t res1;
32+
uint64_t res2;
33+
uint64_t res3;
34+
uint32_t linux_pe_magic;
35+
uint32_t pe_header_offset;
36+
} QEMU_PACKED;
37+
1838
struct memmap_entry *memmap_table;
1939
unsigned memmap_entries;
2040

@@ -171,6 +191,50 @@ static uint64_t cpu_loongarch_virt_to_phys(void *opaque, uint64_t addr)
171191
return addr & MAKE_64BIT_MASK(0, TARGET_PHYS_ADDR_SPACE_BITS);
172192
}
173193

194+
static int64_t load_loongarch_linux_image(const char *filename,
195+
uint64_t *kernel_entry,
196+
uint64_t *kernel_low,
197+
uint64_t *kernel_high)
198+
{
199+
gsize len;
200+
ssize_t size;
201+
uint8_t *buffer;
202+
struct loongarch_linux_hdr *hdr;
203+
204+
/* Load as raw file otherwise */
205+
if (!g_file_get_contents(filename, (char **)&buffer, &len, NULL)) {
206+
return -1;
207+
}
208+
size = len;
209+
210+
/* Unpack the image if it is a EFI zboot image */
211+
if (unpack_efi_zboot_image(&buffer, &size) < 0) {
212+
g_free(buffer);
213+
return -1;
214+
}
215+
216+
hdr = (struct loongarch_linux_hdr *)buffer;
217+
218+
if (extract32(le32_to_cpu(hdr->mz_magic), 0, 16) != MZ_MAGIC ||
219+
le32_to_cpu(hdr->linux_pe_magic) != LINUX_PE_MAGIC) {
220+
g_free(buffer);
221+
return -1;
222+
}
223+
224+
/* Early kernel versions may have those fields in virtual address */
225+
*kernel_entry = extract64(le64_to_cpu(hdr->kernel_entry),
226+
0, TARGET_PHYS_ADDR_SPACE_BITS);
227+
*kernel_low = extract64(le64_to_cpu(hdr->load_offset),
228+
0, TARGET_PHYS_ADDR_SPACE_BITS);
229+
*kernel_high = *kernel_low + size;
230+
231+
rom_add_blob_fixed(filename, buffer, size, *kernel_low);
232+
233+
g_free(buffer);
234+
235+
return size;
236+
}
237+
174238
static int64_t load_kernel_info(struct loongarch_boot_info *info)
175239
{
176240
uint64_t kernel_entry, kernel_low, kernel_high;
@@ -181,6 +245,11 @@ static int64_t load_kernel_info(struct loongarch_boot_info *info)
181245
&kernel_entry, &kernel_low,
182246
&kernel_high, NULL, 0,
183247
EM_LOONGARCH, 1, 0);
248+
if (kernel_size < 0) {
249+
kernel_size = load_loongarch_linux_image(info->kernel_filename,
250+
&kernel_entry, &kernel_low,
251+
&kernel_high);
252+
}
184253

185254
if (kernel_size < 0) {
186255
error_report("could not load kernel '%s': %s",

hw/loongarch/virt.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -921,7 +921,6 @@ static void virt_irq_init(LoongArchVirtMachineState *lvms)
921921

922922
/* Create EXTIOI device */
923923
extioi = qdev_new(TYPE_LOONGARCH_EXTIOI);
924-
qdev_prop_set_uint32(extioi, "num-cpu", ms->smp.cpus);
925924
if (virt_is_veiointc_enabled(lvms)) {
926925
qdev_prop_set_bit(extioi, "has-virtualization-extension", true);
927926
}

include/hw/intc/loongarch_extioi_common.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,8 @@ typedef struct ExtIOICore {
6565
uint32_t coreisr[EXTIOI_IRQS_GROUP_COUNT];
6666
DECLARE_BITMAP(sw_isr[LS3A_INTC_IP], EXTIOI_IRQS);
6767
qemu_irq parent_irq[LS3A_INTC_IP];
68+
uint64_t arch_id;
69+
CPUState *cpu;
6870
} ExtIOICore;
6971

7072
struct LoongArchExtIOICommonState {

include/hw/loader.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ ssize_t load_image_gzipped_buffer(const char *filename, uint64_t max_sz,
101101
* Returns the size of the decompressed payload if decompression was performed
102102
* successfully.
103103
*/
104-
ssize_t unpack_efi_zboot_image(uint8_t **buffer, int *size);
104+
ssize_t unpack_efi_zboot_image(uint8_t **buffer, ssize_t *size);
105105

106106
#define ELF_LOAD_FAILED -1
107107
#define ELF_LOAD_NOT_ELF -2

target/loongarch/helper.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,7 @@ DEF_HELPER_2(csrwr_estat, i64, env, tl)
104104
DEF_HELPER_2(csrwr_asid, i64, env, tl)
105105
DEF_HELPER_2(csrwr_tcfg, i64, env, tl)
106106
DEF_HELPER_2(csrwr_ticlr, i64, env, tl)
107+
DEF_HELPER_2(csrwr_pwcl, i64, env, tl)
107108
DEF_HELPER_2(iocsrrd_b, i64, env, tl)
108109
DEF_HELPER_2(iocsrrd_h, i64, env, tl)
109110
DEF_HELPER_2(iocsrrd_w, i64, env, tl)

target/loongarch/tcg/csr_helper.c

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
*/
77

88
#include "qemu/osdep.h"
9+
#include "qemu/log.h"
910
#include "qemu/main-loop.h"
1011
#include "cpu.h"
1112
#include "internals.h"
@@ -95,3 +96,23 @@ target_ulong helper_csrwr_ticlr(CPULoongArchState *env, target_ulong val)
9596
}
9697
return old_v;
9798
}
99+
100+
target_ulong helper_csrwr_pwcl(CPULoongArchState *env, target_ulong val)
101+
{
102+
int shift;
103+
int64_t old_v = env->CSR_PWCL;
104+
105+
/*
106+
* The real hardware only supports 64bit PTE width now, 128bit or others
107+
* treated as illegal.
108+
*/
109+
shift = FIELD_EX64(val, CSR_PWCL, PTEWIDTH);
110+
if (shift) {
111+
qemu_log_mask(LOG_GUEST_ERROR,
112+
"Attempted set pte width with %d bit\n", 64 << shift);
113+
val = FIELD_DP64(val, CSR_PWCL, PTEWIDTH, 0);
114+
}
115+
116+
env->CSR_PWCL = val;
117+
return old_v;
118+
}

0 commit comments

Comments
 (0)