* THE SOFTWARE.
*/
#include "qemu/osdep.h"
+#include "qemu/units.h"
#include "qapi/error.h"
#include "qemu-common.h"
#include "cpu.h"
#include "net/net.h"
#include "hw/boards.h"
#include "hw/scsi/esp.h"
-#include "hw/isa/isa.h"
#include "hw/nvram/sun_nvram.h"
#include "hw/nvram/chrp_nvram.h"
#include "hw/nvram/fw_cfg.h"
#include "hw/loader.h"
#include "elf.h"
#include "trace.h"
-#include "qemu/cutils.h"
/*
* Sun4m architecture was used in the following machines:
#define KERNEL_LOAD_ADDR 0x00004000
#define CMDLINE_ADDR 0x007ff000
#define INITRD_LOAD_ADDR 0x00800000
-#define PROM_SIZE_MAX (1024 * 1024)
+#define PROM_SIZE_MAX (1 * MiB)
#define PROM_VADDR 0xffd00000
#define PROM_FILENAME "openbios-sparc32"
#define CFG_ADDR 0xd00000510ULL
uint8_t nvram_machine_id;
};
+const char *fw_cfg_arch_key_name(uint16_t key)
+{
+ static const struct {
+ uint16_t key;
+ const char *name;
+ } fw_cfg_arch_wellknown_keys[] = {
+ {FW_CFG_SUN4M_DEPTH, "depth"},
+ {FW_CFG_SUN4M_WIDTH, "width"},
+ {FW_CFG_SUN4M_HEIGHT, "height"},
+ };
+
+ for (size_t i = 0; i < ARRAY_SIZE(fw_cfg_arch_wellknown_keys); i++) {
+ if (fw_cfg_arch_wellknown_keys[i].key == key) {
+ return fw_cfg_arch_wellknown_keys[i].name;
+ }
+ }
+ return NULL;
+}
+
static void fw_cfg_boot_set(void *opaque, const char *boot_device,
Error **errp)
{
static unsigned long sun4m_load_kernel(const char *kernel_filename,
const char *initrd_filename,
- ram_addr_t RAM_size)
+ ram_addr_t RAM_size,
+ uint32_t *initrd_size)
{
int linux_boot;
unsigned int i;
- long initrd_size, kernel_size;
+ long kernel_size;
uint8_t *ptr;
linux_boot = (kernel_filename != NULL);
#else
bswap_needed = 0;
#endif
- kernel_size = load_elf(kernel_filename, translate_kernel_address, NULL,
+ kernel_size = load_elf(kernel_filename, NULL,
+ translate_kernel_address, NULL,
NULL, NULL, NULL, 1, EM_SPARC, 0, 0);
if (kernel_size < 0)
kernel_size = load_aout(kernel_filename, KERNEL_LOAD_ADDR,
}
/* load initrd */
- initrd_size = 0;
+ *initrd_size = 0;
if (initrd_filename) {
- initrd_size = load_image_targphys(initrd_filename,
- INITRD_LOAD_ADDR,
- RAM_size - INITRD_LOAD_ADDR);
- if (initrd_size < 0) {
+ *initrd_size = load_image_targphys(initrd_filename,
+ INITRD_LOAD_ADDR,
+ RAM_size - INITRD_LOAD_ADDR);
+ if ((int)*initrd_size < 0) {
error_report("could not load initial ram disk '%s'",
initrd_filename);
exit(1);
}
}
- if (initrd_size > 0) {
+ if (*initrd_size > 0) {
for (i = 0; i < 64 * TARGET_PAGE_SIZE; i += TARGET_PAGE_SIZE) {
- ptr = rom_ptr(KERNEL_LOAD_ADDR + i);
- if (ldl_p(ptr) == 0x48647253) { // HdrS
+ ptr = rom_ptr(KERNEL_LOAD_ADDR + i, 24);
+ if (ptr && ldl_p(ptr) == 0x48647253) { /* HdrS */
stl_p(ptr + 16, INITRD_LOAD_ADDR);
- stl_p(ptr + 20, initrd_size);
+ stl_p(ptr + 20, *initrd_size);
break;
}
}
s = SYS_BUS_DEVICE(dev);
sysbus_mmio_map(s, 0, addr);
- cpu_physical_memory_write_rom(&address_space_memory,
- addr, idreg_data, sizeof(idreg_data));
+ address_space_write_rom(&address_space_memory, addr,
+ MEMTXATTRS_UNSPECIFIED,
+ idreg_data, sizeof(idreg_data));
}
#define MACIO_ID_REGISTER(obj) \
}
filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);
if (filename) {
- ret = load_elf(filename, translate_prom_address, &addr, NULL,
+ ret = load_elf(filename, NULL,
+ translate_prom_address, &addr, NULL,
NULL, NULL, 1, EM_SPARC, 0, 0);
if (ret < 0 || ret > PROM_SIZE_MAX) {
ret = load_image_targphys(filename, addr, PROM_SIZE_MAX);
/* allocate RAM */
if ((uint64_t)RAM_size > max_mem) {
- error_report("Too much memory for this machine: %d, maximum %d",
- (unsigned int)(RAM_size / (1024 * 1024)),
- (unsigned int)(max_mem / (1024 * 1024)));
+ error_report("Too much memory for this machine: %" PRId64 ","
+ " maximum %" PRId64,
+ RAM_size / MiB, max_mem / MiB);
exit(1);
}
dev = qdev_create(NULL, "memory");
qemu_irq *cpu_irqs[MAX_CPUS], slavio_irq[32], slavio_cpu_irq[MAX_CPUS];
qemu_irq fdc_tc;
unsigned long kernel_size;
+ uint32_t initrd_size;
DriveInfo *fd[MAX_FD];
FWCfgState *fw_cfg;
- unsigned int num_vsimms;
DeviceState *dev;
SysBusDevice *s;
error_report("Unsupported depth: %d", graphic_depth);
exit (1);
}
- num_vsimms = 0;
- if (num_vsimms == 0) {
+ if (vga_interface_type != VGA_NONE) {
if (vga_interface_type == VGA_CG3) {
if (graphic_depth != 8) {
error_report("Unsupported depth: %d", graphic_depth);
}
}
- for (i = num_vsimms; i < MAX_VSIMMS; i++) {
+ for (i = 0; i < MAX_VSIMMS; i++) {
/* vsimm registers probed by OBP */
if (hwdef->vsimm[i].reg_base) {
empty_slot_init(hwdef->vsimm[i].reg_base, 0x2000);
empty_slot_init(hwdef->bpp_base, 0x20);
}
+ initrd_size = 0;
kernel_size = sun4m_load_kernel(machine->kernel_filename,
machine->initrd_filename,
- machine->ram_size);
+ machine->ram_size, &initrd_size);
nvram_init(nvram, (uint8_t *)&nd_table[0].macaddr, machine->kernel_cmdline,
machine->boot_order, machine->ram_size, kernel_size,
ecc_init(hwdef->ecc_base, slavio_irq[28],
hwdef->ecc_version);
- fw_cfg = fw_cfg_init_mem(CFG_ADDR, CFG_ADDR + 2);
+ dev = qdev_create(NULL, TYPE_FW_CFG_MEM);
+ fw_cfg = FW_CFG(dev);
+ qdev_prop_set_uint32(dev, "data_width", 1);
+ qdev_prop_set_bit(dev, "dma_enabled", false);
+ object_property_add_child(OBJECT(qdev_get_machine()), TYPE_FW_CFG,
+ OBJECT(fw_cfg), NULL);
+ qdev_init_nofail(dev);
+ s = SYS_BUS_DEVICE(dev);
+ sysbus_mmio_map(s, 0, CFG_ADDR);
+ sysbus_mmio_map(s, 1, CFG_ADDR + 2);
+
fw_cfg_add_i16(fw_cfg, FW_CFG_NB_CPUS, (uint16_t)smp_cpus);
fw_cfg_add_i16(fw_cfg, FW_CFG_MAX_CPUS, (uint16_t)max_cpus);
fw_cfg_add_i64(fw_cfg, FW_CFG_RAM_SIZE, (uint64_t)ram_size);
fw_cfg_add_i32(fw_cfg, FW_CFG_CMDLINE_SIZE, 0);
}
fw_cfg_add_i32(fw_cfg, FW_CFG_INITRD_ADDR, INITRD_LOAD_ADDR);
- fw_cfg_add_i32(fw_cfg, FW_CFG_INITRD_SIZE, 0); // not used
+ fw_cfg_add_i32(fw_cfg, FW_CFG_INITRD_SIZE, initrd_size);
fw_cfg_add_i16(fw_cfg, FW_CFG_BOOT_DEVICE, machine->boot_order[0]);
qemu_register_boot_set(fw_cfg_boot_set, fw_cfg);
}