aboutsummaryrefslogtreecommitdiff
path: root/hw/m68k/q800.c
diff options
context:
space:
mode:
Diffstat (limited to 'hw/m68k/q800.c')
-rw-r--r--hw/m68k/q800.c71
1 files changed, 51 insertions, 20 deletions
diff --git a/hw/m68k/q800.c b/hw/m68k/q800.c
index a4590c2..e09e244 100644
--- a/hw/m68k/q800.c
+++ b/hw/m68k/q800.c
@@ -321,11 +321,22 @@ static const TypeInfo glue_info = {
},
};
+typedef struct {
+ M68kCPU *cpu;
+ struct bi_record *rng_seed;
+} ResetInfo;
+
static void main_cpu_reset(void *opaque)
{
- M68kCPU *cpu = opaque;
+ ResetInfo *reset_info = opaque;
+ M68kCPU *cpu = reset_info->cpu;
CPUState *cs = CPU(cpu);
+ if (reset_info->rng_seed) {
+ qemu_guest_getrandom_nofail((void *)reset_info->rng_seed->data + 2,
+ be16_to_cpu(*(uint16_t *)reset_info->rng_seed->data));
+ }
+
cpu_reset(cs);
cpu->env.aregs[7] = ldl_phys(cs->as, 0);
cpu->env.pc = ldl_phys(cs->as, 4);
@@ -386,6 +397,7 @@ static void q800_init(MachineState *machine)
NubusBus *nubus;
DeviceState *glue;
DriveInfo *dinfo;
+ ResetInfo *reset_info;
uint8_t rng_seed[32];
linux_boot = (kernel_filename != NULL);
@@ -396,9 +408,12 @@ static void q800_init(MachineState *machine)
exit(1);
}
+ reset_info = g_new0(ResetInfo, 1);
+
/* init CPUs */
cpu = M68K_CPU(cpu_create(machine->cpu_type));
- qemu_register_reset(main_cpu_reset, cpu);
+ reset_info->cpu = cpu;
+ qemu_register_reset(main_cpu_reset, reset_info);
/* RAM */
memory_region_add_subregion(get_system_memory(), 0, machine->ram);
@@ -598,6 +613,14 @@ static void q800_init(MachineState *machine)
cs = CPU(cpu);
if (linux_boot) {
uint64_t high;
+ void *param_blob, *param_ptr, *param_rng_seed;
+
+ if (kernel_cmdline) {
+ param_blob = g_malloc(strlen(kernel_cmdline) + 1024);
+ } else {
+ param_blob = g_malloc(1024);
+ }
+
kernel_size = load_elf(kernel_filename, NULL, NULL, NULL,
&elf_entry, NULL, &high, NULL, 1,
EM_68K, 0, 0);
@@ -607,23 +630,24 @@ static void q800_init(MachineState *machine)
}
stl_phys(cs->as, 4, elf_entry); /* reset initial PC */
parameters_base = (high + 1) & ~1;
-
- BOOTINFO1(cs->as, parameters_base, BI_MACHTYPE, MACH_MAC);
- BOOTINFO1(cs->as, parameters_base, BI_FPUTYPE, FPU_68040);
- BOOTINFO1(cs->as, parameters_base, BI_MMUTYPE, MMU_68040);
- BOOTINFO1(cs->as, parameters_base, BI_CPUTYPE, CPU_68040);
- BOOTINFO1(cs->as, parameters_base, BI_MAC_CPUID, CPUB_68040);
- BOOTINFO1(cs->as, parameters_base, BI_MAC_MODEL, MAC_MODEL_Q800);
- BOOTINFO1(cs->as, parameters_base,
+ param_ptr = param_blob;
+
+ BOOTINFO1(param_ptr, BI_MACHTYPE, MACH_MAC);
+ BOOTINFO1(param_ptr, BI_FPUTYPE, FPU_68040);
+ BOOTINFO1(param_ptr, BI_MMUTYPE, MMU_68040);
+ BOOTINFO1(param_ptr, BI_CPUTYPE, CPU_68040);
+ BOOTINFO1(param_ptr, BI_MAC_CPUID, CPUB_68040);
+ BOOTINFO1(param_ptr, BI_MAC_MODEL, MAC_MODEL_Q800);
+ BOOTINFO1(param_ptr,
BI_MAC_MEMSIZE, ram_size >> 20); /* in MB */
- BOOTINFO2(cs->as, parameters_base, BI_MEMCHUNK, 0, ram_size);
- BOOTINFO1(cs->as, parameters_base, BI_MAC_VADDR,
+ BOOTINFO2(param_ptr, BI_MEMCHUNK, 0, ram_size);
+ BOOTINFO1(param_ptr, BI_MAC_VADDR,
VIDEO_BASE + macfb_mode->offset);
- BOOTINFO1(cs->as, parameters_base, BI_MAC_VDEPTH, graphic_depth);
- BOOTINFO1(cs->as, parameters_base, BI_MAC_VDIM,
+ BOOTINFO1(param_ptr, BI_MAC_VDEPTH, graphic_depth);
+ BOOTINFO1(param_ptr, BI_MAC_VDIM,
(graphic_height << 16) | graphic_width);
- BOOTINFO1(cs->as, parameters_base, BI_MAC_VROW, macfb_mode->stride);
- BOOTINFO1(cs->as, parameters_base, BI_MAC_SCCBASE, SCC_BASE);
+ BOOTINFO1(param_ptr, BI_MAC_VROW, macfb_mode->stride);
+ BOOTINFO1(param_ptr, BI_MAC_SCCBASE, SCC_BASE);
rom = g_malloc(sizeof(*rom));
memory_region_init_ram_ptr(rom, NULL, "m68k_fake_mac.rom",
@@ -632,13 +656,14 @@ static void q800_init(MachineState *machine)
memory_region_add_subregion(get_system_memory(), MACROM_ADDR, rom);
if (kernel_cmdline) {
- BOOTINFOSTR(cs->as, parameters_base, BI_COMMAND_LINE,
+ BOOTINFOSTR(param_ptr, BI_COMMAND_LINE,
kernel_cmdline);
}
/* Pass seed to RNG. */
+ param_rng_seed = param_ptr;
qemu_guest_getrandom_nofail(rng_seed, sizeof(rng_seed));
- BOOTINFODATA(cs->as, parameters_base, BI_RNG_SEED,
+ BOOTINFODATA(param_ptr, BI_RNG_SEED,
rng_seed, sizeof(rng_seed));
/* load initrd */
@@ -653,13 +678,19 @@ static void q800_init(MachineState *machine)
initrd_base = (ram_size - initrd_size) & TARGET_PAGE_MASK;
load_image_targphys(initrd_filename, initrd_base,
ram_size - initrd_base);
- BOOTINFO2(cs->as, parameters_base, BI_RAMDISK, initrd_base,
+ BOOTINFO2(param_ptr, BI_RAMDISK, initrd_base,
initrd_size);
} else {
initrd_base = 0;
initrd_size = 0;
}
- BOOTINFO0(cs->as, parameters_base, BI_LAST);
+ BOOTINFO0(param_ptr, BI_LAST);
+ rom_add_blob_fixed_as("bootinfo", param_blob, param_ptr - param_blob,
+ parameters_base, cs->as);
+ reset_info->rng_seed = rom_ptr_for_as(cs->as, parameters_base,
+ param_ptr - param_blob) +
+ (param_rng_seed - param_blob);
+ g_free(param_blob);
} else {
uint8_t *ptr;
/* allocate and load BIOS */