diff options
author | Stefan Hajnoczi <stefanha@redhat.com> | 2025-01-27 11:20:21 -0500 |
---|---|---|
committer | Stefan Hajnoczi <stefanha@redhat.com> | 2025-01-27 11:20:21 -0500 |
commit | b5afd8c023a9b2daddcec06917b0ff478eda4783 (patch) | |
tree | 21030850da0e558ce95f77130484927d212e62dc | |
parent | ed734377ab3f3f3cc15d7aa301a87ab6370f2eed (diff) | |
parent | c656f293dfe31661e4252d78cfa6cab6372ad5ca (diff) | |
download | qemu-b5afd8c023a9b2daddcec06917b0ff478eda4783.zip qemu-b5afd8c023a9b2daddcec06917b0ff478eda4783.tar.gz qemu-b5afd8c023a9b2daddcec06917b0ff478eda4783.tar.bz2 |
Merge tag 'hppa-system-for-v10-pull-request' of https://github.com/hdeller/qemu-hppa into staging
hppa updates
* Fixes booting a Linux kernel which is provided on the command line.
* Allow more than 4GB RAM on 64-bit boxes
# -----BEGIN PGP SIGNATURE-----
#
# iHUEABYKAB0WIQS86RI+GtKfB8BJu973ErUQojoPXwUCZ5PvvgAKCRD3ErUQojoP
# X7JQAQCn2MR4k4lfClDZHNmAFUNw51j56SB5HC/FCUKfOx4dCQD/Tf2OV/gstMOz
# nfpvIH6ouXZ2/p5npzTyOt+A8fwUpw0=
# =qrs7
# -----END PGP SIGNATURE-----
# gpg: Signature made Fri 24 Jan 2025 14:53:34 EST
# gpg: using EDDSA key BCE9123E1AD29F07C049BBDEF712B510A23A0F5F
# gpg: Good signature from "Helge Deller <deller@gmx.de>" [unknown]
# gpg: aka "Helge Deller <deller@kernel.org>" [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: 4544 8228 2CD9 10DB EF3D 25F8 3E5F 3D04 A7A2 4603
# Subkey fingerprint: BCE9 123E 1AD2 9F07 C049 BBDE F712 B510 A23A 0F5F
* tag 'hppa-system-for-v10-pull-request' of https://github.com/hdeller/qemu-hppa:
hw/hppa: Fix booting Linux kernel with initrd
hw/hppa: Support up to 256 GiB RAM on 64-bit machines
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
-rw-r--r-- | hw/hppa/hppa_hardware.h | 2 | ||||
-rw-r--r-- | hw/hppa/machine.c | 74 | ||||
-rw-r--r-- | target/hppa/cpu.h | 4 |
3 files changed, 44 insertions, 36 deletions
diff --git a/hw/hppa/hppa_hardware.h b/hw/hppa/hppa_hardware.h index a9be7bb..a276240 100644 --- a/hw/hppa/hppa_hardware.h +++ b/hw/hppa/hppa_hardware.h @@ -49,4 +49,6 @@ #define CPU_HPA_CR_REG 7 /* store CPU HPA in cr7 (SeaBIOS internal) */ #define PIM_STORAGE_SIZE 600 /* storage size of pdc_pim_toc_struct (64bit) */ +#define RAM_MAP_HIGH 0x0100000000 /* memory above 3.75 GB is mapped here */ + #endif diff --git a/hw/hppa/machine.c b/hw/hppa/machine.c index 8230f43..0dd1908 100644 --- a/hw/hppa/machine.c +++ b/hw/hppa/machine.c @@ -283,16 +283,13 @@ static TranslateFn *machine_HP_common_init_cpus(MachineState *machine) cpu[i] = HPPA_CPU(cpu_create(machine->cpu_type)); } - /* - * For now, treat address layout as if PSW_W is clear. - * TODO: create a proper hppa64 board model and load elf64 firmware. - */ + /* Initialize memory */ if (hppa_is_pa20(&cpu[0]->env)) { translate = translate_pa20; - ram_max = 0xf0000000; /* 3.75 GB (limited by 32-bit firmware) */ + ram_max = 256 * GiB; /* like HP rp8440 */ } else { translate = translate_pa10; - ram_max = 0xf0000000; /* 3.75 GB (32-bit CPU) */ + ram_max = FIRMWARE_START; /* 3.75 GB (32-bit CPU) */ } soft_power_reg = translate(NULL, HPA_POWER_BUTTON); @@ -320,7 +317,22 @@ static TranslateFn *machine_HP_common_init_cpus(MachineState *machine) info_report("Max RAM size limited to %" PRIu64 " MB", ram_max / MiB); machine->ram_size = ram_max; } - memory_region_add_subregion_overlap(addr_space, 0, machine->ram, -1); + if (machine->ram_size <= FIRMWARE_START) { + /* contiguous memory up to 3.75 GB RAM */ + memory_region_add_subregion_overlap(addr_space, 0, machine->ram, -1); + } else { + /* non-contiguous: Memory above 3.75 GB is mapped at RAM_MAP_HIGH */ + MemoryRegion *mem_region; + mem_region = g_new(MemoryRegion, 2); + memory_region_init_alias(&mem_region[0], &addr_space->parent_obj, + "LowMem", machine->ram, 0, FIRMWARE_START); + memory_region_init_alias(&mem_region[1], &addr_space->parent_obj, + "HighMem", machine->ram, FIRMWARE_START, + machine->ram_size - FIRMWARE_START); + memory_region_add_subregion_overlap(addr_space, 0, &mem_region[0], -1); + memory_region_add_subregion_overlap(addr_space, RAM_MAP_HIGH, + &mem_region[1], -1); + } return translate; } @@ -344,7 +356,6 @@ static void machine_HP_common_init_tail(MachineState *machine, PCIBus *pci_bus, uint64_t kernel_entry = 0, kernel_low, kernel_high; MemoryRegion *addr_space = get_system_memory(); MemoryRegion *rom_region; - unsigned int smp_cpus = machine->smp.cpus; SysBusDevice *s; /* SCSI disk setup. */ @@ -470,8 +481,8 @@ static void machine_HP_common_init_tail(MachineState *machine, PCIBus *pci_bus, kernel_low, kernel_high, kernel_entry, size / KiB); if (kernel_cmdline) { - cpu[0]->env.gr[24] = 0x4000; - pstrcpy_targphys("cmdline", cpu[0]->env.gr[24], + cpu[0]->env.cmdline_or_bootorder = 0x4000; + pstrcpy_targphys("cmdline", cpu[0]->env.cmdline_or_bootorder, TARGET_PAGE_SIZE, kernel_cmdline); } @@ -501,32 +512,22 @@ static void machine_HP_common_init_tail(MachineState *machine, PCIBus *pci_bus, } load_image_targphys(initrd_filename, initrd_base, initrd_size); - cpu[0]->env.gr[23] = initrd_base; - cpu[0]->env.gr[22] = initrd_base + initrd_size; + cpu[0]->env.initrd_base = initrd_base; + cpu[0]->env.initrd_end = initrd_base + initrd_size; } } if (!kernel_entry) { /* When booting via firmware, tell firmware if we want interactive - * mode (kernel_entry=1), and to boot from CD (gr[24]='d') - * or hard disc * (gr[24]='c'). + * mode (kernel_entry=1), and to boot from CD (cmdline_or_bootorder='d') + * or hard disc (cmdline_or_bootorder='c'). */ kernel_entry = machine->boot_config.has_menu ? machine->boot_config.menu : 0; - cpu[0]->env.gr[24] = machine->boot_config.order[0]; + cpu[0]->env.cmdline_or_bootorder = machine->boot_config.order[0]; } - /* We jump to the firmware entry routine and pass the - * various parameters in registers. After firmware initialization, - * firmware will start the Linux kernel with ramdisk and cmdline. - */ - cpu[0]->env.gr[26] = machine->ram_size; - cpu[0]->env.gr[25] = kernel_entry; - - /* tell firmware how many SMP CPUs to present in inventory table */ - cpu[0]->env.gr[21] = smp_cpus; - - /* tell firmware fw_cfg port */ - cpu[0]->env.gr[19] = FW_CFG_IO_BASE; + /* Keep initial kernel_entry for first boot */ + cpu[0]->env.kernel_entry = kernel_entry; } /* @@ -663,18 +664,19 @@ static void hppa_machine_reset(MachineState *ms, ResetType type) cpu[i]->env.gr[5] = CPU_HPA + i * 0x1000; } - /* already initialized by machine_hppa_init()? */ - if (cpu[0]->env.gr[26] == ms->ram_size) { - return; - } - cpu[0]->env.gr[26] = ms->ram_size; - cpu[0]->env.gr[25] = 0; /* no firmware boot menu */ - cpu[0]->env.gr[24] = 'c'; - /* gr22/gr23 unused, no initrd while reboot. */ + cpu[0]->env.gr[25] = cpu[0]->env.kernel_entry; + cpu[0]->env.gr[24] = cpu[0]->env.cmdline_or_bootorder; + cpu[0]->env.gr[23] = cpu[0]->env.initrd_base; + cpu[0]->env.gr[22] = cpu[0]->env.initrd_end; cpu[0]->env.gr[21] = smp_cpus; - /* tell firmware fw_cfg port */ cpu[0]->env.gr[19] = FW_CFG_IO_BASE; + + /* reset static fields to avoid starting Linux kernel & initrd on reboot */ + cpu[0]->env.kernel_entry = 0; + cpu[0]->env.initrd_base = 0; + cpu[0]->env.initrd_end = 0; + cpu[0]->env.cmdline_or_bootorder = 'c'; } static void hppa_nmi(NMIState *n, int cpu_index, Error **errp) diff --git a/target/hppa/cpu.h b/target/hppa/cpu.h index 083d4f5..beea42d 100644 --- a/target/hppa/cpu.h +++ b/target/hppa/cpu.h @@ -268,6 +268,10 @@ typedef struct CPUArchState { struct {} end_reset_fields; bool is_pa20; + + target_ulong kernel_entry; /* Linux kernel was loaded here */ + target_ulong cmdline_or_bootorder; + target_ulong initrd_base, initrd_end; } CPUHPPAState; /** |