Add a generic Niagara machine
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@5329 c046a42c-6fe2-441c-8c8c-71466251a162
This commit is contained in:
parent
c99657d303
commit
e87231d426
@ -66,6 +66,7 @@ extern QEMUMachine ss1000_machine, ss2000_machine;
|
|||||||
/* sun4u.c */
|
/* sun4u.c */
|
||||||
extern QEMUMachine sun4u_machine;
|
extern QEMUMachine sun4u_machine;
|
||||||
extern QEMUMachine sun4v_machine;
|
extern QEMUMachine sun4v_machine;
|
||||||
|
extern QEMUMachine niagara_machine;
|
||||||
|
|
||||||
/* integratorcp.c */
|
/* integratorcp.c */
|
||||||
extern QEMUMachine integratorcp_machine;
|
extern QEMUMachine integratorcp_machine;
|
||||||
|
75
hw/sun4u.c
75
hw/sun4u.c
@ -46,7 +46,6 @@
|
|||||||
#define CMDLINE_ADDR 0x003ff000
|
#define CMDLINE_ADDR 0x003ff000
|
||||||
#define INITRD_LOAD_ADDR 0x00300000
|
#define INITRD_LOAD_ADDR 0x00300000
|
||||||
#define PROM_SIZE_MAX (4 * 1024 * 1024)
|
#define PROM_SIZE_MAX (4 * 1024 * 1024)
|
||||||
#define PROM_ADDR 0x1fff0000000ULL
|
|
||||||
#define PROM_VADDR 0x000ffd00000ULL
|
#define PROM_VADDR 0x000ffd00000ULL
|
||||||
#define APB_SPECIAL_BASE 0x1fe00000000ULL
|
#define APB_SPECIAL_BASE 0x1fe00000000ULL
|
||||||
#define APB_MEM_BASE 0x1ff00000000ULL
|
#define APB_MEM_BASE 0x1ff00000000ULL
|
||||||
@ -61,6 +60,8 @@
|
|||||||
struct hwdef {
|
struct hwdef {
|
||||||
const char * const default_cpu_model;
|
const char * const default_cpu_model;
|
||||||
uint16_t machine_id;
|
uint16_t machine_id;
|
||||||
|
uint64_t prom_addr;
|
||||||
|
uint64_t console_serial_base;
|
||||||
};
|
};
|
||||||
|
|
||||||
int DMA_get_channel_mode (int nchan)
|
int DMA_get_channel_mode (int nchan)
|
||||||
@ -260,9 +261,15 @@ void qemu_system_powerdown(void)
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
typedef struct ResetData {
|
||||||
|
CPUState *env;
|
||||||
|
uint64_t reset_addr;
|
||||||
|
} ResetData;
|
||||||
|
|
||||||
static void main_cpu_reset(void *opaque)
|
static void main_cpu_reset(void *opaque)
|
||||||
{
|
{
|
||||||
CPUState *env = opaque;
|
ResetData *s = (ResetData *)opaque;
|
||||||
|
CPUState *env = s->env;
|
||||||
|
|
||||||
cpu_reset(env);
|
cpu_reset(env);
|
||||||
ptimer_set_limit(env->tick, 0x7fffffffffffffffULL, 1);
|
ptimer_set_limit(env->tick, 0x7fffffffffffffffULL, 1);
|
||||||
@ -271,6 +278,11 @@ static void main_cpu_reset(void *opaque)
|
|||||||
ptimer_run(env->stick, 0);
|
ptimer_run(env->stick, 0);
|
||||||
ptimer_set_limit(env->hstick, 0x7fffffffffffffffULL, 1);
|
ptimer_set_limit(env->hstick, 0x7fffffffffffffffULL, 1);
|
||||||
ptimer_run(env->hstick, 0);
|
ptimer_run(env->hstick, 0);
|
||||||
|
env->gregs[1] = 0; // Memory start
|
||||||
|
env->gregs[2] = ram_size; // Memory size
|
||||||
|
env->gregs[3] = 0; // Machine description XXX
|
||||||
|
env->pc = s->reset_addr;
|
||||||
|
env->npc = env->pc + 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void tick_irq(void *opaque)
|
static void tick_irq(void *opaque)
|
||||||
@ -328,6 +340,7 @@ static void sun4uv_init(ram_addr_t RAM_size, int vga_ram_size,
|
|||||||
BlockDriverState *hd[MAX_IDE_BUS * MAX_IDE_DEVS];
|
BlockDriverState *hd[MAX_IDE_BUS * MAX_IDE_DEVS];
|
||||||
BlockDriverState *fd[MAX_FD];
|
BlockDriverState *fd[MAX_FD];
|
||||||
void *fw_cfg;
|
void *fw_cfg;
|
||||||
|
ResetData *reset_info;
|
||||||
|
|
||||||
linux_boot = (kernel_filename != NULL);
|
linux_boot = (kernel_filename != NULL);
|
||||||
|
|
||||||
@ -351,14 +364,21 @@ static void sun4uv_init(ram_addr_t RAM_size, int vga_ram_size,
|
|||||||
bh = qemu_bh_new(hstick_irq, env);
|
bh = qemu_bh_new(hstick_irq, env);
|
||||||
env->hstick = ptimer_init(bh);
|
env->hstick = ptimer_init(bh);
|
||||||
ptimer_set_period(env->hstick, 1ULL);
|
ptimer_set_period(env->hstick, 1ULL);
|
||||||
qemu_register_reset(main_cpu_reset, env);
|
|
||||||
main_cpu_reset(env);
|
reset_info = qemu_mallocz(sizeof(ResetData));
|
||||||
|
reset_info->env = env;
|
||||||
|
reset_info->reset_addr = hwdef->prom_addr + 0x40ULL;
|
||||||
|
qemu_register_reset(main_cpu_reset, reset_info);
|
||||||
|
main_cpu_reset(reset_info);
|
||||||
|
// Override warm reset address with cold start address
|
||||||
|
env->pc = hwdef->prom_addr + 0x20ULL;
|
||||||
|
env->npc = env->pc + 4;
|
||||||
|
|
||||||
/* allocate RAM */
|
/* allocate RAM */
|
||||||
cpu_register_physical_memory(0, RAM_size, 0);
|
cpu_register_physical_memory(0, RAM_size, 0);
|
||||||
|
|
||||||
prom_offset = RAM_size + vga_ram_size;
|
prom_offset = RAM_size + vga_ram_size;
|
||||||
cpu_register_physical_memory(PROM_ADDR,
|
cpu_register_physical_memory(hwdef->prom_addr,
|
||||||
(PROM_SIZE_MAX + TARGET_PAGE_SIZE) &
|
(PROM_SIZE_MAX + TARGET_PAGE_SIZE) &
|
||||||
TARGET_PAGE_MASK,
|
TARGET_PAGE_MASK,
|
||||||
prom_offset | IO_MEM_ROM);
|
prom_offset | IO_MEM_ROM);
|
||||||
@ -366,12 +386,17 @@ static void sun4uv_init(ram_addr_t RAM_size, int vga_ram_size,
|
|||||||
if (bios_name == NULL)
|
if (bios_name == NULL)
|
||||||
bios_name = PROM_FILENAME;
|
bios_name = PROM_FILENAME;
|
||||||
snprintf(buf, sizeof(buf), "%s/%s", bios_dir, bios_name);
|
snprintf(buf, sizeof(buf), "%s/%s", bios_dir, bios_name);
|
||||||
ret = load_elf(buf, PROM_ADDR - PROM_VADDR, NULL, NULL, NULL);
|
ret = load_elf(buf, hwdef->prom_addr - PROM_VADDR, NULL, NULL, NULL);
|
||||||
|
if (ret < 0) {
|
||||||
|
ret = load_image_targphys(buf, hwdef->prom_addr,
|
||||||
|
(PROM_SIZE_MAX + TARGET_PAGE_SIZE) &
|
||||||
|
TARGET_PAGE_MASK);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
fprintf(stderr, "qemu: could not load prom '%s'\n",
|
fprintf(stderr, "qemu: could not load prom '%s'\n",
|
||||||
buf);
|
buf);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
kernel_size = 0;
|
kernel_size = 0;
|
||||||
initrd_size = 0;
|
initrd_size = 0;
|
||||||
@ -417,7 +442,13 @@ static void sun4uv_init(ram_addr_t RAM_size, int vga_ram_size,
|
|||||||
pci_cirrus_vga_init(pci_bus, ds, phys_ram_base + RAM_size, RAM_size,
|
pci_cirrus_vga_init(pci_bus, ds, phys_ram_base + RAM_size, RAM_size,
|
||||||
vga_ram_size);
|
vga_ram_size);
|
||||||
|
|
||||||
for(i = 0; i < MAX_SERIAL_PORTS; i++) {
|
i = 0;
|
||||||
|
if (hwdef->console_serial_base) {
|
||||||
|
serial_mm_init(hwdef->console_serial_base, 0, NULL, 115200,
|
||||||
|
serial_hds[i], 1);
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
for(; i < MAX_SERIAL_PORTS; i++) {
|
||||||
if (serial_hds[i]) {
|
if (serial_hds[i]) {
|
||||||
serial_init(serial_io[i], NULL/*serial_irq[i]*/, 115200,
|
serial_init(serial_io[i], NULL/*serial_irq[i]*/, 115200,
|
||||||
serial_hds[i]);
|
serial_hds[i]);
|
||||||
@ -482,6 +513,7 @@ static void sun4uv_init(ram_addr_t RAM_size, int vga_ram_size,
|
|||||||
enum {
|
enum {
|
||||||
sun4u_id = 0,
|
sun4u_id = 0,
|
||||||
sun4v_id = 64,
|
sun4v_id = 64,
|
||||||
|
niagara_id,
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct hwdef hwdefs[] = {
|
static const struct hwdef hwdefs[] = {
|
||||||
@ -489,11 +521,22 @@ static const struct hwdef hwdefs[] = {
|
|||||||
{
|
{
|
||||||
.default_cpu_model = "TI UltraSparc II",
|
.default_cpu_model = "TI UltraSparc II",
|
||||||
.machine_id = sun4u_id,
|
.machine_id = sun4u_id,
|
||||||
|
.prom_addr = 0x1fff0000000ULL,
|
||||||
|
.console_serial_base = 0,
|
||||||
},
|
},
|
||||||
/* Sun4v generic PC-like machine */
|
/* Sun4v generic PC-like machine */
|
||||||
{
|
{
|
||||||
.default_cpu_model = "Sun UltraSparc T1",
|
.default_cpu_model = "Sun UltraSparc T1",
|
||||||
.machine_id = sun4v_id,
|
.machine_id = sun4v_id,
|
||||||
|
.prom_addr = 0x1fff0000000ULL,
|
||||||
|
.console_serial_base = 0,
|
||||||
|
},
|
||||||
|
/* Sun4v generic Niagara machine */
|
||||||
|
{
|
||||||
|
.default_cpu_model = "Sun UltraSparc T1",
|
||||||
|
.machine_id = niagara_id,
|
||||||
|
.prom_addr = 0xfff0000000ULL,
|
||||||
|
.console_serial_base = 0xfff0c2c000ULL,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -517,6 +560,16 @@ static void sun4v_init(ram_addr_t RAM_size, int vga_ram_size,
|
|||||||
kernel_cmdline, initrd_filename, cpu_model, &hwdefs[1]);
|
kernel_cmdline, initrd_filename, cpu_model, &hwdefs[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Niagara hardware initialisation */
|
||||||
|
static void niagara_init(ram_addr_t RAM_size, int vga_ram_size,
|
||||||
|
const char *boot_devices, DisplayState *ds,
|
||||||
|
const char *kernel_filename, const char *kernel_cmdline,
|
||||||
|
const char *initrd_filename, const char *cpu_model)
|
||||||
|
{
|
||||||
|
sun4uv_init(RAM_size, vga_ram_size, boot_devices, ds, kernel_filename,
|
||||||
|
kernel_cmdline, initrd_filename, cpu_model, &hwdefs[2]);
|
||||||
|
}
|
||||||
|
|
||||||
QEMUMachine sun4u_machine = {
|
QEMUMachine sun4u_machine = {
|
||||||
.name = "sun4u",
|
.name = "sun4u",
|
||||||
.desc = "Sun4u platform",
|
.desc = "Sun4u platform",
|
||||||
@ -532,3 +585,11 @@ QEMUMachine sun4v_machine = {
|
|||||||
.ram_require = PROM_SIZE_MAX + VGA_RAM_SIZE,
|
.ram_require = PROM_SIZE_MAX + VGA_RAM_SIZE,
|
||||||
.nodisk_ok = 1,
|
.nodisk_ok = 1,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
QEMUMachine niagara_machine = {
|
||||||
|
.name = "Niagara",
|
||||||
|
.desc = "Sun4v platform, Niagara",
|
||||||
|
.init = niagara_init,
|
||||||
|
.ram_require = PROM_SIZE_MAX + VGA_RAM_SIZE,
|
||||||
|
.nodisk_ok = 1,
|
||||||
|
};
|
||||||
|
@ -658,13 +658,12 @@ void cpu_reset(CPUSPARCState *env)
|
|||||||
#ifdef TARGET_SPARC64
|
#ifdef TARGET_SPARC64
|
||||||
env->pstate = PS_PRIV;
|
env->pstate = PS_PRIV;
|
||||||
env->hpstate = HS_PRIV;
|
env->hpstate = HS_PRIV;
|
||||||
env->pc = 0x1fff0000020ULL; // XXX should be different for system_reset
|
|
||||||
env->tsptr = &env->ts[env->tl & MAXTL_MASK];
|
env->tsptr = &env->ts[env->tl & MAXTL_MASK];
|
||||||
#else
|
#else
|
||||||
env->pc = 0;
|
|
||||||
env->mmuregs[0] &= ~(MMU_E | MMU_NF);
|
env->mmuregs[0] &= ~(MMU_E | MMU_NF);
|
||||||
env->mmuregs[0] |= env->def->mmu_bm;
|
env->mmuregs[0] |= env->def->mmu_bm;
|
||||||
#endif
|
#endif
|
||||||
|
env->pc = 0;
|
||||||
env->npc = env->pc + 4;
|
env->npc = env->pc + 4;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -9,6 +9,7 @@ void register_machines(void)
|
|||||||
#ifdef TARGET_SPARC64
|
#ifdef TARGET_SPARC64
|
||||||
qemu_register_machine(&sun4u_machine);
|
qemu_register_machine(&sun4u_machine);
|
||||||
qemu_register_machine(&sun4v_machine);
|
qemu_register_machine(&sun4v_machine);
|
||||||
|
qemu_register_machine(&niagara_machine);
|
||||||
#else
|
#else
|
||||||
qemu_register_machine(&ss5_machine);
|
qemu_register_machine(&ss5_machine);
|
||||||
qemu_register_machine(&ss10_machine);
|
qemu_register_machine(&ss10_machine);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user