diff --git a/hw/r2d.c b/hw/r2d.c index ae289be086..78fc197940 100644 --- a/hw/r2d.c +++ b/hw/r2d.c @@ -28,6 +28,9 @@ #include "devices.h" #include "sysemu.h" #include "boards.h" +#include "pci.h" +#include "net.h" +#include "sh7750_regs.h" #define SDRAM_BASE 0x0c000000 /* Physical location of SDRAM: Area 3 */ #define SDRAM_SIZE 0x04000000 @@ -178,6 +181,17 @@ static qemu_irq *r2d_fpga_init(target_phys_addr_t base, qemu_irq irl) return qemu_allocate_irqs(r2d_fpga_irq_set, s, NR_IRQS); } +static void r2d_pci_set_irq(qemu_irq *p, int n, int l) +{ + qemu_set_irq(p[n], l); +} + +static int r2d_pci_map_irq(PCIDevice *d, int irq_num) +{ + const int intx[] = { PCI_INTA, PCI_INTB, PCI_INTC, PCI_INTD }; + return intx[d->devfn >> 3]; +} + static void r2d_init(ram_addr_t ram_size, int vga_ram_size, const char *boot_device, DisplayState * ds, const char *kernel_filename, const char *kernel_cmdline, @@ -187,6 +201,8 @@ static void r2d_init(ram_addr_t ram_size, int vga_ram_size, struct SH7750State *s; ram_addr_t sdram_addr, sm501_vga_ram_addr; qemu_irq *irq; + PCIBus *pci; + int i; if (!cpu_model) cpu_model = "SH7751R"; @@ -203,6 +219,7 @@ static void r2d_init(ram_addr_t ram_size, int vga_ram_size, /* Register peripherals */ s = sh7750_init(env); irq = r2d_fpga_init(0x04000000, sh7750_irl(s)); + pci = sh_pci_register_bus(r2d_pci_set_irq, r2d_pci_map_irq, irq, 0, 4); sm501_vga_ram_addr = qemu_ram_alloc(SM501_VRAM_SIZE); sm501_init(ds, 0x10000000, sm501_vga_ram_addr, SM501_VRAM_SIZE, @@ -212,9 +229,19 @@ static void r2d_init(ram_addr_t ram_size, int vga_ram_size, mmio_ide_init(0x14001000, 0x1400080c, irq[CF_IDE], 1, drives_table[drive_get_index(IF_IDE, 0, 0)].bdrv, NULL); + /* NIC: rtl8139 on-board, and 2 slots. */ + pci_rtl8139_init(pci, &nd_table[0], 2 << 3); + for (i = 1; i < nb_nics; i++) + pci_nic_init(pci, &nd_table[i], -1); + /* Todo: register on board registers */ { int kernel_size; + /* initialization which should be done by firmware */ + uint32_t bcr1 = 1 << 3; /* cs3 SDRAM */ + uint16_t bcr2 = 3 << (3 * 2); /* cs3 32-bit */ + cpu_physical_memory_write(SH7750_BCR1_A7, &bcr1, 4); + cpu_physical_memory_write(SH7750_BCR2_A7, &bcr2, 2); kernel_size = load_image(kernel_filename, phys_ram_base); diff --git a/hw/sh7750.c b/hw/sh7750.c index 97597fc54a..a564a802d6 100644 --- a/hw/sh7750.c +++ b/hw/sh7750.c @@ -41,6 +41,8 @@ typedef struct SH7750State { /* Peripheral frequency in Hz */ uint32_t periph_freq; /* SDRAM controller */ + uint32_t bcr1; + uint32_t bcr2; uint16_t rfcr; /* IO ports */ uint16_t gpioic; @@ -208,6 +210,8 @@ static uint32_t sh7750_mem_readw(void *opaque, target_phys_addr_t addr) SH7750State *s = opaque; switch (addr) { + case SH7750_BCR2_A7: + return s->bcr2; case SH7750_FRQCR_A7: return 0; case SH7750_RFCR_A7: @@ -231,6 +235,15 @@ static uint32_t sh7750_mem_readl(void *opaque, target_phys_addr_t addr) SH7750State *s = opaque; switch (addr) { + case SH7750_BCR1_A7: + return s->bcr1; + case SH7750_BCR4_A7: + case SH7750_WCR1_A7: + case SH7750_WCR2_A7: + case SH7750_WCR3_A7: + case SH7750_MCR_A7: + ignore_access("long read", addr); + return 0; case SH7750_MMUCR_A7: return s->cpu->mmucr; case SH7750_PTEH_A7: @@ -285,6 +298,8 @@ static void sh7750_mem_writew(void *opaque, target_phys_addr_t addr, switch (addr) { /* SDRAM controller */ case SH7750_BCR2_A7: + s->bcr2 = mem_value; + return; case SH7750_BCR3_A7: case SH7750_RTCOR_A7: case SH7750_RTCNT_A7: @@ -331,6 +346,8 @@ static void sh7750_mem_writel(void *opaque, target_phys_addr_t addr, switch (addr) { /* SDRAM controller */ case SH7750_BCR1_A7: + s->bcr1 = mem_value; + return; case SH7750_BCR4_A7: case SH7750_WCR1_A7: case SH7750_WCR2_A7: