/*
 * 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 should 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
};
