/*
 * ARM RealView Baseboard System emulation.
 *
 * Copyright (c) 2006-2007 CodeSourcery.
 * Written by Paul Brook
 *
 * This code is licenced under the GPL.
 */

#include "hw.h"
#include "arm-misc.h"
#include "primecell.h"
#include "devices.h"
#include "pci.h"
#include "net.h"
#include "sysemu.h"
#include "boards.h"

/* Board init.  */

static struct arm_boot_info realview_binfo = {
    .loader_start = 0x0,
    .board_id = 0x33b,
};

static void realview_init(ram_addr_t ram_size, int vga_ram_size,
                     const char *boot_device, DisplayState *ds,
                     const char *kernel_filename, const char *kernel_cmdline,
                     const char *initrd_filename, const char *cpu_model)
{
    CPUState *env;
    qemu_irq *pic;
    void *scsi_hba;
    PCIBus *pci_bus;
    NICInfo *nd;
    int n;
    int done_smc = 0;
    qemu_irq cpu_irq[4];
    int ncpu;
    int index;

    if (!cpu_model)
        cpu_model = "arm926";
    /* FIXME: obey smp_cpus.  */
    if (strcmp(cpu_model, "arm11mpcore") == 0) {
        ncpu = 4;
    } else {
        ncpu = 1;
    }

    for (n = 0; n < ncpu; n++) {
        env = cpu_init(cpu_model);
        if (!env) {
            fprintf(stderr, "Unable to find CPU definition\n");
            exit(1);
        }
        pic = arm_pic_init_cpu(env);
        cpu_irq[n] = pic[ARM_PIC_CPU_IRQ];
        if (n > 0) {
            /* Set entry point for secondary CPUs.  This assumes we're using
               the init code from arm_boot.c.  Real hardware resets all CPUs
               the same.  */
            env->regs[15] = 0x80000000;
        }
    }

    /* ??? RAM shoud repeat to fill physical memory space.  */
    /* SDRAM at address zero.  */
    cpu_register_physical_memory(0, ram_size, IO_MEM_RAM);

    arm_sysctl_init(0x10000000, 0xc1400400);

    if (ncpu == 1) {
        /* ??? The documentation says GIC1 is nFIQ and either GIC2 or GIC3
           is nIRQ (there are inconsistencies).  However Linux 2.6.17 expects
           GIC1 to be nIRQ and ignores all the others, so do that for now.  */
        pic = realview_gic_init(0x10040000, cpu_irq[0]);
    } else {
        pic = mpcore_irq_init(cpu_irq);
    }

    pl050_init(0x10006000, pic[20], 0);
    pl050_init(0x10007000, pic[21], 1);

    pl011_init(0x10009000, pic[12], serial_hds[0], PL011_ARM);
    pl011_init(0x1000a000, pic[13], serial_hds[1], PL011_ARM);
    pl011_init(0x1000b000, pic[14], serial_hds[2], PL011_ARM);
    pl011_init(0x1000c000, pic[15], serial_hds[3], PL011_ARM);

    /* DMA controller is optional, apparently.  */
    pl080_init(0x10030000, pic[24], 2);

    sp804_init(0x10011000, pic[4]);
    sp804_init(0x10012000, pic[5]);

    pl110_init(ds, 0x10020000, pic[23], 1);

    index = drive_get_index(IF_SD, 0, 0);
    if (index == -1) {
        fprintf(stderr, "qemu: missing SecureDigital card\n");
        exit(1);
    }
    pl181_init(0x10005000, drives_table[index].bdrv, pic[17], pic[18]);

    pl031_init(0x10017000, pic[10]);

    pci_bus = pci_vpb_init(pic, 48, 1);
    if (usb_enabled) {
        usb_ohci_init_pci(pci_bus, 3, -1);
    }
    if (drive_get_max_bus(IF_SCSI) > 0) {
        fprintf(stderr, "qemu: too many SCSI bus\n");
        exit(1);
    }
    scsi_hba = lsi_scsi_init(pci_bus, -1);
    for (n = 0; n < LSI_MAX_DEVS; n++) {
        index = drive_get_index(IF_SCSI, 0, n);
        if (index == -1)
            continue;
        lsi_scsi_attach(scsi_hba, drives_table[index].bdrv, n);
    }
    for(n = 0; n < nb_nics; n++) {
        nd = &nd_table[n];
        if (!nd->model)
            nd->model = done_smc ? "rtl8139" : "smc91c111";
        if (strcmp(nd->model, "smc91c111") == 0) {
            smc91c111_init(nd, 0x4e000000, pic[28]);
        } else {
            pci_nic_init(pci_bus, nd, -1);
        }
    }

    /* Memory map for RealView Emulation Baseboard:  */
    /* 0x10000000 System registers.  */
    /*  0x10001000 System controller.  */
    /*  0x10002000 Two-Wire Serial Bus.  */
    /* 0x10003000 Reserved.  */
    /*  0x10004000 AACI.  */
    /*  0x10005000 MCI.  */
    /* 0x10006000 KMI0.  */
    /* 0x10007000 KMI1.  */
    /*  0x10008000 Character LCD.  */
    /* 0x10009000 UART0.  */
    /* 0x1000a000 UART1.  */
    /* 0x1000b000 UART2.  */
    /* 0x1000c000 UART3.  */
    /*  0x1000d000 SSPI.  */
    /*  0x1000e000 SCI.  */
    /* 0x1000f000 Reserved.  */
    /*  0x10010000 Watchdog.  */
    /* 0x10011000 Timer 0+1.  */
    /* 0x10012000 Timer 2+3.  */
    /*  0x10013000 GPIO 0.  */
    /*  0x10014000 GPIO 1.  */
    /*  0x10015000 GPIO 2.  */
    /* 0x10016000 Reserved.  */
    /* 0x10017000 RTC.  */
    /*  0x10018000 DMC.  */
    /*  0x10019000 PCI controller config.  */
    /*  0x10020000 CLCD.  */
    /* 0x10030000 DMA Controller.  */
    /* 0x10040000 GIC1.  */
    /* 0x10050000 GIC2.  */
    /* 0x10060000 GIC3.  */
    /* 0x10070000 GIC4.  */
    /*  0x10080000 SMC.  */
    /*  0x40000000 NOR flash.  */
    /*  0x44000000 DoC flash.  */
    /*  0x48000000 SRAM.  */
    /*  0x4c000000 Configuration flash.  */
    /* 0x4e000000 Ethernet.  */
    /*  0x4f000000 USB.  */
    /*  0x50000000 PISMO.  */
    /*  0x54000000 PISMO.  */
    /*  0x58000000 PISMO.  */
    /*  0x5c000000 PISMO.  */
    /* 0x60000000 PCI.  */
    /* 0x61000000 PCI Self Config.  */
    /* 0x62000000 PCI Config.  */
    /* 0x63000000 PCI IO.  */
    /* 0x64000000 PCI mem 0.  */
    /* 0x68000000 PCI mem 1.  */
    /* 0x6c000000 PCI mem 2.  */

    realview_binfo.ram_size = ram_size;
    realview_binfo.kernel_filename = kernel_filename;
    realview_binfo.kernel_cmdline = kernel_cmdline;
    realview_binfo.initrd_filename = initrd_filename;
    realview_binfo.nb_cpus = ncpu;
    arm_load_kernel(first_cpu, &realview_binfo);

    /* ??? Hack to map an additional page of ram for the secondary CPU
       startup code.  I guess this works on real hardware because the
       BootROM happens to be in ROM/flash or in memory that isn't clobbered
       until after Linux boots the secondary CPUs.  */
    cpu_register_physical_memory(0x80000000, 0x1000, IO_MEM_RAM + ram_size);
}

QEMUMachine realview_machine = {
    "realview",
    "ARM RealView Emulation Baseboard (ARM926EJ-S)",
    realview_init,
    0x1000
};
