mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-31 22:11:53 -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/qtest.h"
|
||||||
#include "system/reset.h"
|
#include "system/reset.h"
|
||||||
#include "kvm_ppc.h"
|
#include "kvm_ppc.h"
|
||||||
|
#include "elf.h"
|
||||||
|
|
||||||
#include <zlib.h> /* for crc32 */
|
#include <zlib.h> /* for crc32 */
|
||||||
|
|
||||||
#define BUS_FREQ_HZ 100000000
|
#define BUS_FREQ_HZ 100000000
|
||||||
|
|
||||||
|
#define INITRD_MIN_ADDR 0x600000
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Firmware binary available at
|
* Firmware binary available at
|
||||||
* https://www.hyperion-entertainment.com/index.php/downloads?view=files&parent=28
|
* 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)
|
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)
|
static void amigaone_cpu_reset(void *opaque)
|
||||||
{
|
{
|
||||||
PowerPCCPU *cpu = opaque;
|
PowerPCCPU *cpu = opaque;
|
||||||
|
CPUPPCState *env = &cpu->env;
|
||||||
|
|
||||||
cpu_reset(CPU(cpu));
|
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)
|
static void fix_spd_data(uint8_t *spd)
|
||||||
|
@ -205,6 +264,8 @@ static void amigaone_init(MachineState *machine)
|
||||||
I2CBus *i2c_bus;
|
I2CBus *i2c_bus;
|
||||||
uint8_t *spd_data;
|
uint8_t *spd_data;
|
||||||
DriveInfo *di;
|
DriveInfo *di;
|
||||||
|
hwaddr loadaddr;
|
||||||
|
struct boot_info *bi = NULL;
|
||||||
|
|
||||||
/* init CPU */
|
/* init CPU */
|
||||||
cpu = POWERPC_CPU(cpu_create(machine->cpu_type));
|
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_ide_create_devs(PCI_DEVICE(object_resolve_path_component(via, "ide")));
|
||||||
pci_vga_init(pci_bus);
|
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)
|
static void amigaone_machine_init(MachineClass *mc)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue