mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-30 13:31:52 -06:00
ppc/amigaone: Add kernel and initrd support
Add support for -kernel, -initrd and -append command line options. Signed-off-by: BALATON Zoltan <balaton@eik.bme.hu> Reviewed-by: Nicholas Piggin <npiggin@gmail.com> Message-ID: <489b1be5d95d5153e924c95b0691b8b53f9ffb9e.1740673173.git.balaton@eik.bme.hu> Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
This commit is contained in:
parent
c2bed9957a
commit
34f053d86b
1 changed files with 112 additions and 1 deletions
|
@ -25,11 +25,14 @@
|
|||
#include "system/qtest.h"
|
||||
#include "system/reset.h"
|
||||
#include "kvm_ppc.h"
|
||||
#include "elf.h"
|
||||
|
||||
#include <zlib.h> /* for crc32 */
|
||||
|
||||
#define BUS_FREQ_HZ 100000000
|
||||
|
||||
#define INITRD_MIN_ADDR 0x600000
|
||||
|
||||
/*
|
||||
* Firmware binary available at
|
||||
* https://www.hyperion-entertainment.com/index.php/downloads?view=files&parent=28
|
||||
|
@ -178,12 +181,68 @@ static const TypeInfo nvram_types[] = {
|
|||
};
|
||||
DEFINE_TYPES(nvram_types)
|
||||
|
||||
struct boot_info {
|
||||
hwaddr entry;
|
||||
hwaddr stack;
|
||||
hwaddr bd_info;
|
||||
hwaddr initrd_start;
|
||||
hwaddr initrd_end;
|
||||
hwaddr cmdline_start;
|
||||
hwaddr cmdline_end;
|
||||
};
|
||||
|
||||
/* Board info struct from U-Boot */
|
||||
struct bd_info {
|
||||
uint32_t bi_memstart;
|
||||
uint32_t bi_memsize;
|
||||
uint32_t bi_flashstart;
|
||||
uint32_t bi_flashsize;
|
||||
uint32_t bi_flashoffset;
|
||||
uint32_t bi_sramstart;
|
||||
uint32_t bi_sramsize;
|
||||
uint32_t bi_bootflags;
|
||||
uint32_t bi_ip_addr;
|
||||
uint8_t bi_enetaddr[6];
|
||||
uint16_t bi_ethspeed;
|
||||
uint32_t bi_intfreq;
|
||||
uint32_t bi_busfreq;
|
||||
uint32_t bi_baudrate;
|
||||
} QEMU_PACKED;
|
||||
|
||||
static void create_bd_info(hwaddr addr, ram_addr_t ram_size)
|
||||
{
|
||||
struct bd_info *bd = g_new0(struct bd_info, 1);
|
||||
|
||||
bd->bi_memsize = cpu_to_be32(ram_size);
|
||||
bd->bi_flashstart = cpu_to_be32(PROM_ADDR);
|
||||
bd->bi_flashsize = cpu_to_be32(1); /* match what U-Boot detects */
|
||||
bd->bi_bootflags = cpu_to_be32(1);
|
||||
bd->bi_intfreq = cpu_to_be32(11.5 * BUS_FREQ_HZ);
|
||||
bd->bi_busfreq = cpu_to_be32(BUS_FREQ_HZ);
|
||||
bd->bi_baudrate = cpu_to_be32(115200);
|
||||
|
||||
cpu_physical_memory_write(addr, bd, sizeof(*bd));
|
||||
}
|
||||
|
||||
static void amigaone_cpu_reset(void *opaque)
|
||||
{
|
||||
PowerPCCPU *cpu = opaque;
|
||||
CPUPPCState *env = &cpu->env;
|
||||
|
||||
cpu_reset(CPU(cpu));
|
||||
cpu_ppc_tb_reset(&cpu->env);
|
||||
if (env->load_info) {
|
||||
struct boot_info *bi = env->load_info;
|
||||
|
||||
env->gpr[1] = bi->stack;
|
||||
env->gpr[2] = 1024;
|
||||
env->gpr[3] = bi->bd_info;
|
||||
env->gpr[4] = bi->initrd_start;
|
||||
env->gpr[5] = bi->initrd_end;
|
||||
env->gpr[6] = bi->cmdline_start;
|
||||
env->gpr[7] = bi->cmdline_end;
|
||||
env->nip = bi->entry;
|
||||
}
|
||||
cpu_ppc_tb_reset(env);
|
||||
}
|
||||
|
||||
static void fix_spd_data(uint8_t *spd)
|
||||
|
@ -205,6 +264,8 @@ static void amigaone_init(MachineState *machine)
|
|||
I2CBus *i2c_bus;
|
||||
uint8_t *spd_data;
|
||||
DriveInfo *di;
|
||||
hwaddr loadaddr;
|
||||
struct boot_info *bi = NULL;
|
||||
|
||||
/* init CPU */
|
||||
cpu = POWERPC_CPU(cpu_create(machine->cpu_type));
|
||||
|
@ -301,6 +362,56 @@ static void amigaone_init(MachineState *machine)
|
|||
}
|
||||
pci_ide_create_devs(PCI_DEVICE(object_resolve_path_component(via, "ide")));
|
||||
pci_vga_init(pci_bus);
|
||||
|
||||
if (!machine->kernel_filename) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* handle -kernel, -initrd, -append options and emulate U-Boot */
|
||||
bi = g_new0(struct boot_info, 1);
|
||||
cpu->env.load_info = bi;
|
||||
|
||||
loadaddr = MIN(machine->ram_size, 256 * MiB);
|
||||
bi->bd_info = loadaddr - 8 * MiB;
|
||||
create_bd_info(bi->bd_info, machine->ram_size);
|
||||
bi->stack = bi->bd_info - 64 * KiB - 8;
|
||||
|
||||
if (machine->kernel_cmdline && machine->kernel_cmdline[0]) {
|
||||
size_t len = strlen(machine->kernel_cmdline);
|
||||
|
||||
loadaddr = bi->bd_info + 1 * MiB;
|
||||
cpu_physical_memory_write(loadaddr, machine->kernel_cmdline, len + 1);
|
||||
bi->cmdline_start = loadaddr;
|
||||
bi->cmdline_end = loadaddr + len + 1; /* including terminating '\0' */
|
||||
}
|
||||
|
||||
sz = load_elf(machine->kernel_filename, NULL, NULL, NULL,
|
||||
&bi->entry, &loadaddr, NULL, NULL,
|
||||
ELFDATA2MSB, PPC_ELF_MACHINE, 0, 0);
|
||||
if (sz <= 0) {
|
||||
sz = load_uimage(machine->kernel_filename, &bi->entry, &loadaddr,
|
||||
NULL, NULL, NULL);
|
||||
}
|
||||
if (sz <= 0) {
|
||||
error_report("Could not load kernel '%s'",
|
||||
machine->kernel_filename);
|
||||
exit(1);
|
||||
}
|
||||
loadaddr += sz;
|
||||
|
||||
if (machine->initrd_filename) {
|
||||
loadaddr = ROUND_UP(loadaddr + 4 * MiB, 4 * KiB);
|
||||
loadaddr = MAX(loadaddr, INITRD_MIN_ADDR);
|
||||
sz = load_image_targphys(machine->initrd_filename, loadaddr,
|
||||
bi->bd_info - loadaddr);
|
||||
if (sz <= 0) {
|
||||
error_report("Could not load initrd '%s'",
|
||||
machine->initrd_filename);
|
||||
exit(1);
|
||||
}
|
||||
bi->initrd_start = loadaddr;
|
||||
bi->initrd_end = loadaddr + sz;
|
||||
}
|
||||
}
|
||||
|
||||
static void amigaone_machine_init(MachineClass *mc)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue