symbian-qemu-0.9.1-12/qemu-symbian-svp/hw/r2d.c
changeset 1 2fb8b9db1c86
equal deleted inserted replaced
0:ffa851df0825 1:2fb8b9db1c86
       
     1 /*
       
     2  * Renesas SH7751R R2D-PLUS emulation
       
     3  *
       
     4  * Copyright (c) 2007 Magnus Damm
       
     5  * Copyright (c) 2008 Paul Mundt
       
     6  *
       
     7  * Permission is hereby granted, free of charge, to any person obtaining a copy
       
     8  * of this software and associated documentation files (the "Software"), to deal
       
     9  * in the Software without restriction, including without limitation the rights
       
    10  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
       
    11  * copies of the Software, and to permit persons to whom the Software is
       
    12  * furnished to do so, subject to the following conditions:
       
    13  *
       
    14  * The above copyright notice and this permission notice shall be included in
       
    15  * all copies or substantial portions of the Software.
       
    16  *
       
    17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
       
    18  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
       
    19  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
       
    20  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
       
    21  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
       
    22  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
       
    23  * THE SOFTWARE.
       
    24  */
       
    25 
       
    26 #include "hw.h"
       
    27 #include "sh.h"
       
    28 #include "devices.h"
       
    29 #include "sysemu.h"
       
    30 #include "boards.h"
       
    31 #include "pci.h"
       
    32 #include "net.h"
       
    33 #include "sh7750_regs.h"
       
    34 
       
    35 #define SDRAM_BASE 0x0c000000 /* Physical location of SDRAM: Area 3 */
       
    36 #define SDRAM_SIZE 0x04000000
       
    37 
       
    38 #define SM501_VRAM_SIZE 0x800000
       
    39 
       
    40 #define PA_IRLMSK	0x00
       
    41 #define PA_POWOFF	0x30
       
    42 #define PA_VERREG	0x32
       
    43 #define PA_OUTPORT	0x36
       
    44 
       
    45 typedef struct {
       
    46     uint16_t bcr;
       
    47     uint16_t irlmsk;
       
    48     uint16_t irlmon;
       
    49     uint16_t cfctl;
       
    50     uint16_t cfpow;
       
    51     uint16_t dispctl;
       
    52     uint16_t sdmpow;
       
    53     uint16_t rtcce;
       
    54     uint16_t pcicd;
       
    55     uint16_t voyagerrts;
       
    56     uint16_t cfrst;
       
    57     uint16_t admrts;
       
    58     uint16_t extrst;
       
    59     uint16_t cfcdintclr;
       
    60     uint16_t keyctlclr;
       
    61     uint16_t pad0;
       
    62     uint16_t pad1;
       
    63     uint16_t powoff;
       
    64     uint16_t verreg;
       
    65     uint16_t inport;
       
    66     uint16_t outport;
       
    67     uint16_t bverreg;
       
    68 
       
    69 /* output pin */
       
    70     qemu_irq irl;
       
    71 } r2d_fpga_t;
       
    72 
       
    73 enum r2d_fpga_irq {
       
    74     PCI_INTD, CF_IDE, CF_CD, PCI_INTC, SM501, KEY, RTC_A, RTC_T,
       
    75     SDCARD, PCI_INTA, PCI_INTB, EXT, TP,
       
    76     NR_IRQS
       
    77 };
       
    78 
       
    79 static const struct { short irl; uint16_t msk; } irqtab[NR_IRQS] = {
       
    80     [CF_IDE]	= {  1, 1<<9 },
       
    81     [CF_CD]	= {  2, 1<<8 },
       
    82     [PCI_INTA]	= {  9, 1<<14 },
       
    83     [PCI_INTB]	= { 10, 1<<13 },
       
    84     [PCI_INTC]	= {  3, 1<<12 },
       
    85     [PCI_INTD]	= {  0, 1<<11 },
       
    86     [SM501]	= {  4, 1<<10 },
       
    87     [KEY]	= {  5, 1<<6 },
       
    88     [RTC_A]	= {  6, 1<<5 },
       
    89     [RTC_T]	= {  7, 1<<4 },
       
    90     [SDCARD]	= {  8, 1<<7 },
       
    91     [EXT]	= { 11, 1<<0 },
       
    92     [TP]	= { 12, 1<<15 },
       
    93 };
       
    94 
       
    95 static void update_irl(r2d_fpga_t *fpga)
       
    96 {
       
    97     int i, irl = 15;
       
    98     for (i = 0; i < NR_IRQS; i++)
       
    99         if (fpga->irlmon & fpga->irlmsk & irqtab[i].msk)
       
   100             if (irqtab[i].irl < irl)
       
   101                 irl = irqtab[i].irl;
       
   102     qemu_set_irq(fpga->irl, irl ^ 15);
       
   103 }
       
   104 
       
   105 static void r2d_fpga_irq_set(void *opaque, int n, int level)
       
   106 {
       
   107     r2d_fpga_t *fpga = opaque;
       
   108     if (level)
       
   109         fpga->irlmon |= irqtab[n].msk;
       
   110     else
       
   111         fpga->irlmon &= ~irqtab[n].msk;
       
   112     update_irl(fpga);
       
   113 }
       
   114 
       
   115 static uint32_t r2d_fpga_read(void *opaque, target_phys_addr_t addr)
       
   116 {
       
   117     r2d_fpga_t *s = opaque;
       
   118 
       
   119     switch (addr) {
       
   120     case PA_IRLMSK:
       
   121         return s->irlmsk;
       
   122     case PA_OUTPORT:
       
   123 	return s->outport;
       
   124     case PA_POWOFF:
       
   125 	return s->powoff;
       
   126     case PA_VERREG:
       
   127 	return 0x10;
       
   128     }
       
   129 
       
   130     return 0;
       
   131 }
       
   132 
       
   133 static void
       
   134 r2d_fpga_write(void *opaque, target_phys_addr_t addr, uint32_t value)
       
   135 {
       
   136     r2d_fpga_t *s = opaque;
       
   137 
       
   138     switch (addr) {
       
   139     case PA_IRLMSK:
       
   140         s->irlmsk = value;
       
   141         update_irl(s);
       
   142 	break;
       
   143     case PA_OUTPORT:
       
   144 	s->outport = value;
       
   145 	break;
       
   146     case PA_POWOFF:
       
   147 	s->powoff = value;
       
   148 	break;
       
   149     case PA_VERREG:
       
   150 	/* Discard writes */
       
   151 	break;
       
   152     }
       
   153 }
       
   154 
       
   155 static CPUReadMemoryFunc *r2d_fpga_readfn[] = {
       
   156     r2d_fpga_read,
       
   157     r2d_fpga_read,
       
   158     NULL,
       
   159 };
       
   160 
       
   161 static CPUWriteMemoryFunc *r2d_fpga_writefn[] = {
       
   162     r2d_fpga_write,
       
   163     r2d_fpga_write,
       
   164     NULL,
       
   165 };
       
   166 
       
   167 static qemu_irq *r2d_fpga_init(target_phys_addr_t base, qemu_irq irl)
       
   168 {
       
   169     int iomemtype;
       
   170     r2d_fpga_t *s;
       
   171 
       
   172     s = qemu_mallocz(sizeof(r2d_fpga_t));
       
   173     if (!s)
       
   174         return NULL;
       
   175 
       
   176     s->irl = irl;
       
   177 
       
   178     iomemtype = cpu_register_io_memory(0, r2d_fpga_readfn,
       
   179 				       r2d_fpga_writefn, s);
       
   180     cpu_register_physical_memory(base, 0x40, iomemtype);
       
   181     return qemu_allocate_irqs(r2d_fpga_irq_set, s, NR_IRQS);
       
   182 }
       
   183 
       
   184 static void r2d_pci_set_irq(qemu_irq *p, int n, int l)
       
   185 {
       
   186     qemu_set_irq(p[n], l);
       
   187 }
       
   188 
       
   189 static int r2d_pci_map_irq(PCIDevice *d, int irq_num)
       
   190 {
       
   191     const int intx[] = { PCI_INTA, PCI_INTB, PCI_INTC, PCI_INTD };
       
   192     return intx[d->devfn >> 3];
       
   193 }
       
   194 
       
   195 static void r2d_init(ram_addr_t ram_size, int vga_ram_size,
       
   196               const char *boot_device, DisplayState * ds,
       
   197 	      const char *kernel_filename, const char *kernel_cmdline,
       
   198 	      const char *initrd_filename, const char *cpu_model)
       
   199 {
       
   200     CPUState *env;
       
   201     struct SH7750State *s;
       
   202     ram_addr_t sdram_addr, sm501_vga_ram_addr;
       
   203     qemu_irq *irq;
       
   204     PCIBus *pci;
       
   205     int i;
       
   206 
       
   207     if (!cpu_model)
       
   208         cpu_model = "SH7751R";
       
   209 
       
   210     env = cpu_init(cpu_model);
       
   211     if (!env) {
       
   212         fprintf(stderr, "Unable to find CPU definition\n");
       
   213         exit(1);
       
   214     }
       
   215 
       
   216     /* Allocate memory space */
       
   217     sdram_addr = qemu_ram_alloc(SDRAM_SIZE);
       
   218     cpu_register_physical_memory(SDRAM_BASE, SDRAM_SIZE, sdram_addr);
       
   219     /* Register peripherals */
       
   220     s = sh7750_init(env);
       
   221     irq = r2d_fpga_init(0x04000000, sh7750_irl(s));
       
   222     pci = sh_pci_register_bus(r2d_pci_set_irq, r2d_pci_map_irq, irq, 0, 4);
       
   223 
       
   224     sm501_vga_ram_addr = qemu_ram_alloc(SM501_VRAM_SIZE);
       
   225     sm501_init(ds, 0x10000000, sm501_vga_ram_addr, SM501_VRAM_SIZE,
       
   226 	       serial_hds[2]);
       
   227 
       
   228     /* onboard CF (True IDE mode, Master only). */
       
   229     mmio_ide_init(0x14001000, 0x1400080c, irq[CF_IDE], 1,
       
   230         drives_table[drive_get_index(IF_IDE, 0, 0)].bdrv, NULL);
       
   231 
       
   232     /* NIC: rtl8139 on-board, and 2 slots. */
       
   233     pci_rtl8139_init(pci, &nd_table[0], 2 << 3);
       
   234     for (i = 1; i < nb_nics; i++)
       
   235         pci_nic_init(pci, &nd_table[i], -1);
       
   236 
       
   237     /* Todo: register on board registers */
       
   238     {
       
   239       int kernel_size;
       
   240       /* initialization which should be done by firmware */
       
   241       uint32_t bcr1 = 1 << 3; /* cs3 SDRAM */
       
   242       uint16_t bcr2 = 3 << (3 * 2); /* cs3 32-bit */
       
   243       cpu_physical_memory_write(SH7750_BCR1_A7, (uint8_t *)&bcr1, 4);
       
   244       cpu_physical_memory_write(SH7750_BCR2_A7, (uint8_t *)&bcr2, 2);
       
   245 
       
   246       kernel_size = load_image(kernel_filename, phys_ram_base);
       
   247 
       
   248       if (kernel_size < 0) {
       
   249         fprintf(stderr, "qemu: could not load kernel '%s'\n", kernel_filename);
       
   250         exit(1);
       
   251       }
       
   252 
       
   253       env->pc = SDRAM_BASE | 0xa0000000; /* Start from P2 area */
       
   254     }
       
   255 }
       
   256 
       
   257 QEMUMachine r2d_machine = {
       
   258     .name = "r2d",
       
   259     .desc = "r2d-plus board",
       
   260     .init = r2d_init,
       
   261     .ram_require = (SDRAM_SIZE + SM501_VRAM_SIZE) | RAMSIZE_FIXED,
       
   262 };