Commit d47ede60933f265e558723096e67734db165bdae

Authored by balrog
1 parent c6d86a33

sh4: Add r2d onboard FPGA IRQ controller (Takashi YOSHII).

This adds IRQ controller in FPGA on r2d, and use it for CF.

Signed-off-by: Takashi YOSHII <takasi-y@ops.dti.ne.jp>
Signed-off-by: Andrzej Zaborowski <andrew.zaborowski@intel.com>


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@5926 c046a42c-6fe2-441c-8c8c-71466251a162
Showing 1 changed file with 63 additions and 5 deletions
hw/r2d.c
... ... @@ -34,12 +34,14 @@
34 34  
35 35 #define SM501_VRAM_SIZE 0x800000
36 36  
  37 +#define PA_IRLMSK 0x00
37 38 #define PA_POWOFF 0x30
38 39 #define PA_VERREG 0x32
39 40 #define PA_OUTPORT 0x36
40 41  
41 42 typedef struct {
42 43 uint16_t bcr;
  44 + uint16_t irlmsk;
43 45 uint16_t irlmon;
44 46 uint16_t cfctl;
45 47 uint16_t cfpow;
... ... @@ -60,13 +62,60 @@ typedef struct {
60 62 uint16_t inport;
61 63 uint16_t outport;
62 64 uint16_t bverreg;
  65 +
  66 +/* output pin */
  67 + qemu_irq irl;
63 68 } r2d_fpga_t;
64 69  
  70 +enum r2d_fpga_irq {
  71 + PCI_INTD, CF_IDE, CF_CD, PCI_INTC, SM501, KEY, RTC_A, RTC_T,
  72 + SDCARD, PCI_INTA, PCI_INTB, EXT, TP,
  73 + NR_IRQS
  74 +};
  75 +
  76 +static const struct { short irl; uint16_t msk; } irqtab[NR_IRQS] = {
  77 + [CF_IDE] = { 1, 1<<9 },
  78 + [CF_CD] = { 2, 1<<8 },
  79 + [PCI_INTA] = { 9, 1<<14 },
  80 + [PCI_INTB] = { 10, 1<<13 },
  81 + [PCI_INTC] = { 3, 1<<12 },
  82 + [PCI_INTD] = { 0, 1<<11 },
  83 + [SM501] = { 4, 1<<10 },
  84 + [KEY] = { 5, 1<<6 },
  85 + [RTC_A] = { 6, 1<<5 },
  86 + [RTC_T] = { 7, 1<<4 },
  87 + [SDCARD] = { 8, 1<<7 },
  88 + [EXT] = { 11, 1<<0 },
  89 + [TP] = { 12, 1<<15 },
  90 +};
  91 +
  92 +static void update_irl(r2d_fpga_t *fpga)
  93 +{
  94 + int i, irl = 15;
  95 + for (i = 0; i < NR_IRQS; i++)
  96 + if (fpga->irlmon & fpga->irlmsk & irqtab[i].msk)
  97 + if (irqtab[i].irl < irl)
  98 + irl = irqtab[i].irl;
  99 + qemu_set_irq(fpga->irl, irl ^ 15);
  100 +}
  101 +
  102 +static void r2d_fpga_irq_set(void *opaque, int n, int level)
  103 +{
  104 + r2d_fpga_t *fpga = opaque;
  105 + if (level)
  106 + fpga->irlmon |= irqtab[n].msk;
  107 + else
  108 + fpga->irlmon &= ~irqtab[n].msk;
  109 + update_irl(fpga);
  110 +}
  111 +
65 112 static uint32_t r2d_fpga_read(void *opaque, target_phys_addr_t addr)
66 113 {
67 114 r2d_fpga_t *s = opaque;
68 115  
69 116 switch (addr) {
  117 + case PA_IRLMSK:
  118 + return s->irlmsk;
70 119 case PA_OUTPORT:
71 120 return s->outport;
72 121 case PA_POWOFF:
... ... @@ -84,6 +133,10 @@ r2d_fpga_write(void *opaque, target_phys_addr_t addr, uint32_t value)
84 133 r2d_fpga_t *s = opaque;
85 134  
86 135 switch (addr) {
  136 + case PA_IRLMSK:
  137 + s->irlmsk = value;
  138 + update_irl(s);
  139 + break;
87 140 case PA_OUTPORT:
88 141 s->outport = value;
89 142 break;
... ... @@ -108,18 +161,21 @@ static CPUWriteMemoryFunc *r2d_fpga_writefn[] = {
108 161 NULL,
109 162 };
110 163  
111   -static void r2d_fpga_init(target_phys_addr_t base)
  164 +static qemu_irq *r2d_fpga_init(target_phys_addr_t base, qemu_irq irl)
112 165 {
113 166 int iomemtype;
114 167 r2d_fpga_t *s;
115 168  
116 169 s = qemu_mallocz(sizeof(r2d_fpga_t));
117 170 if (!s)
118   - return;
  171 + return NULL;
  172 +
  173 + s->irl = irl;
119 174  
120 175 iomemtype = cpu_register_io_memory(0, r2d_fpga_readfn,
121 176 r2d_fpga_writefn, s);
122 177 cpu_register_physical_memory(base, 0x40, iomemtype);
  178 + return qemu_allocate_irqs(r2d_fpga_irq_set, s, NR_IRQS);
123 179 }
124 180  
125 181 static void r2d_init(ram_addr_t ram_size, int vga_ram_size,
... ... @@ -130,6 +186,7 @@ static void r2d_init(ram_addr_t ram_size, int vga_ram_size,
130 186 CPUState *env;
131 187 struct SH7750State *s;
132 188 ram_addr_t sdram_addr, sm501_vga_ram_addr;
  189 + qemu_irq *irq;
133 190  
134 191 if (!cpu_model)
135 192 cpu_model = "SH7751R";
... ... @@ -144,15 +201,16 @@ static void r2d_init(ram_addr_t ram_size, int vga_ram_size,
144 201 sdram_addr = qemu_ram_alloc(SDRAM_SIZE);
145 202 cpu_register_physical_memory(SDRAM_BASE, SDRAM_SIZE, sdram_addr);
146 203 /* Register peripherals */
147   - r2d_fpga_init(0x04000000);
148 204 s = sh7750_init(env);
  205 + irq = r2d_fpga_init(0x04000000, sh7750_irl(s));
  206 +
149 207 sm501_vga_ram_addr = qemu_ram_alloc(SM501_VRAM_SIZE);
150 208 sm501_init(ds, 0x10000000, sm501_vga_ram_addr, SM501_VRAM_SIZE,
151 209 serial_hds[2]);
152 210  
153 211 /* onboard CF (True IDE mode, Master only). */
154   - mmio_ide_init(0x14001000, 0x1400080c, NULL, 1,
155   - drives_table[drive_get_index(IF_IDE, 0, 0)].bdrv, NULL);
  212 + mmio_ide_init(0x14001000, 0x1400080c, irq[CF_IDE], 1,
  213 + drives_table[drive_get_index(IF_IDE, 0, 0)].bdrv, NULL);
156 214  
157 215 /* Todo: register on board registers */
158 216 {
... ...