Skip to content

Commit c656f29

Browse files
committed
hw/hppa: Fix booting Linux kernel with initrd
Commit 20f7b89 ("hw/hppa: Reset vCPUs calling resettable_reset()") broke booting the Linux kernel with initrd which may have been provided on the command line. The problem is, that the mentioned commit zeroes out initial registers which were preset with addresses for the Linux kernel and initrd. Fix it by adding proper variables which are set shortly before starting the firmware. Signed-off-by: Helge Deller <deller@gmx.de> Fixes: 20f7b89 ("hw/hppa: Reset vCPUs calling resettable_reset()") Cc: Philippe Mathieu-Daudé <philmd@linaro.org> Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
1 parent d0ad411 commit c656f29

File tree

2 files changed

+23
-29
lines changed

2 files changed

+23
-29
lines changed

hw/hppa/machine.c

Lines changed: 19 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -356,7 +356,6 @@ static void machine_HP_common_init_tail(MachineState *machine, PCIBus *pci_bus,
356356
uint64_t kernel_entry = 0, kernel_low, kernel_high;
357357
MemoryRegion *addr_space = get_system_memory();
358358
MemoryRegion *rom_region;
359-
unsigned int smp_cpus = machine->smp.cpus;
360359
SysBusDevice *s;
361360

362361
/* SCSI disk setup. */
@@ -482,8 +481,8 @@ static void machine_HP_common_init_tail(MachineState *machine, PCIBus *pci_bus,
482481
kernel_low, kernel_high, kernel_entry, size / KiB);
483482

484483
if (kernel_cmdline) {
485-
cpu[0]->env.gr[24] = 0x4000;
486-
pstrcpy_targphys("cmdline", cpu[0]->env.gr[24],
484+
cpu[0]->env.cmdline_or_bootorder = 0x4000;
485+
pstrcpy_targphys("cmdline", cpu[0]->env.cmdline_or_bootorder,
487486
TARGET_PAGE_SIZE, kernel_cmdline);
488487
}
489488

@@ -513,32 +512,22 @@ static void machine_HP_common_init_tail(MachineState *machine, PCIBus *pci_bus,
513512
}
514513

515514
load_image_targphys(initrd_filename, initrd_base, initrd_size);
516-
cpu[0]->env.gr[23] = initrd_base;
517-
cpu[0]->env.gr[22] = initrd_base + initrd_size;
515+
cpu[0]->env.initrd_base = initrd_base;
516+
cpu[0]->env.initrd_end = initrd_base + initrd_size;
518517
}
519518
}
520519

521520
if (!kernel_entry) {
522521
/* When booting via firmware, tell firmware if we want interactive
523-
* mode (kernel_entry=1), and to boot from CD (gr[24]='d')
524-
* or hard disc * (gr[24]='c').
522+
* mode (kernel_entry=1), and to boot from CD (cmdline_or_bootorder='d')
523+
* or hard disc (cmdline_or_bootorder='c').
525524
*/
526525
kernel_entry = machine->boot_config.has_menu ? machine->boot_config.menu : 0;
527-
cpu[0]->env.gr[24] = machine->boot_config.order[0];
526+
cpu[0]->env.cmdline_or_bootorder = machine->boot_config.order[0];
528527
}
529528

530-
/* We jump to the firmware entry routine and pass the
531-
* various parameters in registers. After firmware initialization,
532-
* firmware will start the Linux kernel with ramdisk and cmdline.
533-
*/
534-
cpu[0]->env.gr[26] = machine->ram_size;
535-
cpu[0]->env.gr[25] = kernel_entry;
536-
537-
/* tell firmware how many SMP CPUs to present in inventory table */
538-
cpu[0]->env.gr[21] = smp_cpus;
539-
540-
/* tell firmware fw_cfg port */
541-
cpu[0]->env.gr[19] = FW_CFG_IO_BASE;
529+
/* Keep initial kernel_entry for first boot */
530+
cpu[0]->env.kernel_entry = kernel_entry;
542531
}
543532

544533
/*
@@ -675,18 +664,19 @@ static void hppa_machine_reset(MachineState *ms, ResetType type)
675664
cpu[i]->env.gr[5] = CPU_HPA + i * 0x1000;
676665
}
677666

678-
/* already initialized by machine_hppa_init()? */
679-
if (cpu[0]->env.gr[26] == ms->ram_size) {
680-
return;
681-
}
682-
683667
cpu[0]->env.gr[26] = ms->ram_size;
684-
cpu[0]->env.gr[25] = 0; /* no firmware boot menu */
685-
cpu[0]->env.gr[24] = 'c';
686-
/* gr22/gr23 unused, no initrd while reboot. */
668+
cpu[0]->env.gr[25] = cpu[0]->env.kernel_entry;
669+
cpu[0]->env.gr[24] = cpu[0]->env.cmdline_or_bootorder;
670+
cpu[0]->env.gr[23] = cpu[0]->env.initrd_base;
671+
cpu[0]->env.gr[22] = cpu[0]->env.initrd_end;
687672
cpu[0]->env.gr[21] = smp_cpus;
688-
/* tell firmware fw_cfg port */
689673
cpu[0]->env.gr[19] = FW_CFG_IO_BASE;
674+
675+
/* reset static fields to avoid starting Linux kernel & initrd on reboot */
676+
cpu[0]->env.kernel_entry = 0;
677+
cpu[0]->env.initrd_base = 0;
678+
cpu[0]->env.initrd_end = 0;
679+
cpu[0]->env.cmdline_or_bootorder = 'c';
690680
}
691681

692682
static void hppa_nmi(NMIState *n, int cpu_index, Error **errp)

target/hppa/cpu.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -268,6 +268,10 @@ typedef struct CPUArchState {
268268
struct {} end_reset_fields;
269269

270270
bool is_pa20;
271+
272+
target_ulong kernel_entry; /* Linux kernel was loaded here */
273+
target_ulong cmdline_or_bootorder;
274+
target_ulong initrd_base, initrd_end;
271275
} CPUHPPAState;
272276

273277
/**

0 commit comments

Comments
 (0)