X-Git-Url: https://vcs.maemo.org/git/?a=blobdiff_plain;f=hw%2Fsun4m.c;h=014ed0926426f18118a467de7940608aec73e389;hb=b37837317fb3177755c592591d7f53826c6afae5;hp=56b9069e57ce909411fa847512b77100060dd9ed;hpb=3475187dd814be9b27c4632b59c1e3c76d966d63;p=qemu diff --git a/hw/sun4m.c b/hw/sun4m.c index 56b9069..014ed09 100644 --- a/hw/sun4m.c +++ b/hw/sun4m.c @@ -22,11 +22,11 @@ * THE SOFTWARE. */ #include "vl.h" -#include "m48t08.h" #define KERNEL_LOAD_ADDR 0x00004000 #define CMDLINE_ADDR 0x007ff000 #define INITRD_LOAD_ADDR 0x00800000 +#define PROM_SIZE_MAX (256 * 1024) #define PROM_ADDR 0xffd00000 #define PROM_FILENAMEB "proll.bin" #define PROM_FILENAMEE "proll.elf" @@ -57,6 +57,7 @@ #define PHYS_JJ_FDC 0x71400000 /* Floppy */ #define PHYS_JJ_FLOPPY_IRQ 22 #define PHYS_JJ_ME_IRQ 30 /* Module error, power fail */ +#define MAX_CPUS 16 /* TSC handling */ @@ -88,36 +89,36 @@ void DMA_register_channel (int nchan, { } -static void nvram_set_word (m48t08_t *nvram, uint32_t addr, uint16_t value) +static void nvram_set_word (m48t59_t *nvram, uint32_t addr, uint16_t value) { - m48t08_write(nvram, addr++, (value >> 8) & 0xff); - m48t08_write(nvram, addr++, value & 0xff); + m48t59_write(nvram, addr++, (value >> 8) & 0xff); + m48t59_write(nvram, addr++, value & 0xff); } -static void nvram_set_lword (m48t08_t *nvram, uint32_t addr, uint32_t value) +static void nvram_set_lword (m48t59_t *nvram, uint32_t addr, uint32_t value) { - m48t08_write(nvram, addr++, value >> 24); - m48t08_write(nvram, addr++, (value >> 16) & 0xff); - m48t08_write(nvram, addr++, (value >> 8) & 0xff); - m48t08_write(nvram, addr++, value & 0xff); + m48t59_write(nvram, addr++, value >> 24); + m48t59_write(nvram, addr++, (value >> 16) & 0xff); + m48t59_write(nvram, addr++, (value >> 8) & 0xff); + m48t59_write(nvram, addr++, value & 0xff); } -static void nvram_set_string (m48t08_t *nvram, uint32_t addr, +static void nvram_set_string (m48t59_t *nvram, uint32_t addr, const unsigned char *str, uint32_t max) { unsigned int i; for (i = 0; i < max && str[i] != '\0'; i++) { - m48t08_write(nvram, addr + i, str[i]); + m48t59_write(nvram, addr + i, str[i]); } - m48t08_write(nvram, addr + max - 1, '\0'); + m48t59_write(nvram, addr + max - 1, '\0'); } -static m48t08_t *nvram; +static m48t59_t *nvram; extern int nographic; -static void nvram_init(m48t08_t *nvram, uint8_t *macaddr, const char *cmdline, +static void nvram_init(m48t59_t *nvram, uint8_t *macaddr, const char *cmdline, int boot_device, uint32_t RAM_size, uint32_t kernel_size, int width, int height, int depth) @@ -129,9 +130,11 @@ static void nvram_init(m48t08_t *nvram, uint8_t *macaddr, const char *cmdline, nvram_set_string(nvram, 0x00, "QEMU_BIOS", 16); nvram_set_lword(nvram, 0x10, 0x00000001); /* structure v1 */ // NVRAM_size, arch not applicable - m48t08_write(nvram, 0x2F, nographic & 0xff); + m48t59_write(nvram, 0x2D, smp_cpus & 0xff); + m48t59_write(nvram, 0x2E, 0); + m48t59_write(nvram, 0x2F, nographic & 0xff); nvram_set_lword(nvram, 0x30, RAM_size); - m48t08_write(nvram, 0x34, boot_device & 0xff); + m48t59_write(nvram, 0x34, boot_device & 0xff); nvram_set_lword(nvram, 0x38, KERNEL_LOAD_ADDR); nvram_set_lword(nvram, 0x3C, kernel_size); if (cmdline) { @@ -146,21 +149,21 @@ static void nvram_init(m48t08_t *nvram, uint8_t *macaddr, const char *cmdline, // Sun4m specific use i = 0x1fd8; - m48t08_write(nvram, i++, 0x01); - m48t08_write(nvram, i++, 0x80); /* Sun4m OBP */ + m48t59_write(nvram, i++, 0x01); + m48t59_write(nvram, i++, 0x80); /* Sun4m OBP */ j = 0; - m48t08_write(nvram, i++, macaddr[j++]); - m48t08_write(nvram, i++, macaddr[j++]); - m48t08_write(nvram, i++, macaddr[j++]); - m48t08_write(nvram, i++, macaddr[j++]); - m48t08_write(nvram, i++, macaddr[j++]); - m48t08_write(nvram, i, macaddr[j]); + m48t59_write(nvram, i++, macaddr[j++]); + m48t59_write(nvram, i++, macaddr[j++]); + m48t59_write(nvram, i++, macaddr[j++]); + m48t59_write(nvram, i++, macaddr[j++]); + m48t59_write(nvram, i++, macaddr[j++]); + m48t59_write(nvram, i, macaddr[j]); /* Calculate checksum */ for (i = 0x1fd8; i < 0x1fe7; i++) { - tmp ^= m48t08_read(nvram, i); + tmp ^= m48t59_read(nvram, i); } - m48t08_write(nvram, 0x1fe7, tmp); + m48t59_write(nvram, 0x1fe7, tmp); } static void *slavio_intctl; @@ -180,21 +183,9 @@ void pic_set_irq(int irq, int level) slavio_pic_set_irq(slavio_intctl, irq, level); } -static void *tcx; - -void vga_update_display() +void pic_set_irq_cpu(int irq, int level, unsigned int cpu) { - tcx_update_display(tcx); -} - -void vga_invalidate_display() -{ - tcx_invalidate_display(tcx); -} - -void vga_screen_dump(const char *filename) -{ - tcx_screen_dump(tcx, filename); + slavio_pic_set_irq_cpu(slavio_intctl, irq, level, cpu); } static void *iommu; @@ -211,12 +202,19 @@ void qemu_system_powerdown(void) slavio_set_power_fail(slavio_misc, 1); } +static void main_cpu_reset(void *opaque) +{ + CPUState *env = opaque; + cpu_reset(env); +} + /* Sun4m hardware initialisation */ static void sun4m_init(int ram_size, int vga_ram_size, int boot_device, DisplayState *ds, const char **fd_filename, int snapshot, const char *kernel_filename, const char *kernel_cmdline, const char *initrd_filename) { + CPUState *env, *envs[MAX_CPUS]; char buf[1024]; int ret, linux_boot; unsigned int i; @@ -224,15 +222,39 @@ static void sun4m_init(int ram_size, int vga_ram_size, int boot_device, linux_boot = (kernel_filename != NULL); + /* init CPUs */ + for(i = 0; i < smp_cpus; i++) { + env = cpu_init(); + envs[i] = env; + if (i != 0) + env->halted = 1; + register_savevm("cpu", i, 3, cpu_save, cpu_load, env); + qemu_register_reset(main_cpu_reset, env); + } /* allocate RAM */ cpu_register_physical_memory(0, ram_size, 0); iommu = iommu_init(PHYS_JJ_IOMMU); slavio_intctl = slavio_intctl_init(PHYS_JJ_INTR0, PHYS_JJ_INTR_G); - tcx = tcx_init(ds, PHYS_JJ_TCX_FB, phys_ram_base + ram_size, ram_size, vram_size, graphic_width, graphic_height); - lance_init(&nd_table[0], PHYS_JJ_LE_IRQ, PHYS_JJ_LE, PHYS_JJ_LEDMA); - nvram = m48t08_init(PHYS_JJ_EEPROM, PHYS_JJ_EEPROM_SIZE); - slavio_timer_init(PHYS_JJ_CLOCK, PHYS_JJ_CLOCK_IRQ, PHYS_JJ_CLOCK1, PHYS_JJ_CLOCK1_IRQ); + for(i = 0; i < smp_cpus; i++) { + slavio_intctl_set_cpu(slavio_intctl, i, envs[i]); + } + + tcx_init(ds, PHYS_JJ_TCX_FB, phys_ram_base + ram_size, ram_size, vram_size, graphic_width, graphic_height); + if (nd_table[0].vlan) { + if (nd_table[0].model == NULL + || strcmp(nd_table[0].model, "lance") == 0) { + lance_init(&nd_table[0], PHYS_JJ_LE_IRQ, PHYS_JJ_LE, PHYS_JJ_LEDMA); + } else { + fprintf(stderr, "qemu: Unsupported NIC: %s\n", nd_table[0].model); + exit (1); + } + } + nvram = m48t59_init(0, PHYS_JJ_EEPROM, 0, PHYS_JJ_EEPROM_SIZE, 8); + for (i = 0; i < MAX_CPUS; i++) { + slavio_timer_init(PHYS_JJ_CLOCK + i * TARGET_PAGE_SIZE, PHYS_JJ_CLOCK_IRQ, 0, i); + } + slavio_timer_init(PHYS_JJ_CLOCK1, PHYS_JJ_CLOCK1_IRQ, 2, (unsigned int)-1); slavio_serial_ms_kbd_init(PHYS_JJ_MS_KBD, PHYS_JJ_MS_KBD_IRQ); // Slavio TTYA (base+4, Linux ttyS0) is the first Qemu serial device // Slavio TTYB (base+0, Linux ttyS1) is the second Qemu serial device @@ -242,9 +264,12 @@ static void sun4m_init(int ram_size, int vga_ram_size, int boot_device, slavio_misc = slavio_misc_init(PHYS_JJ_SLAVIO, PHYS_JJ_ME_IRQ); prom_offset = ram_size + vram_size; + cpu_register_physical_memory(PROM_ADDR, + (PROM_SIZE_MAX + TARGET_PAGE_SIZE - 1) & TARGET_PAGE_MASK, + prom_offset | IO_MEM_ROM); snprintf(buf, sizeof(buf), "%s/%s", bios_dir, PROM_FILENAMEE); - ret = load_elf(buf, phys_ram_base + prom_offset); + ret = load_elf(buf, 0); if (ret < 0) { snprintf(buf, sizeof(buf), "%s/%s", bios_dir, PROM_FILENAMEB); ret = load_image(buf, phys_ram_base + prom_offset); @@ -254,12 +279,10 @@ static void sun4m_init(int ram_size, int vga_ram_size, int boot_device, buf); exit(1); } - cpu_register_physical_memory(PROM_ADDR, (ret + TARGET_PAGE_SIZE) & TARGET_PAGE_MASK, - prom_offset | IO_MEM_ROM); kernel_size = 0; if (linux_boot) { - kernel_size = load_elf(kernel_filename, phys_ram_base + KERNEL_LOAD_ADDR); + kernel_size = load_elf(kernel_filename, -0xf0000000); if (kernel_size < 0) kernel_size = load_aout(kernel_filename, phys_ram_base + KERNEL_LOAD_ADDR); if (kernel_size < 0)