hw/eeprom93xx.c: substitute structure dump with discrete dump in eeprom_save/load
[qemu] / hw / sh7750.c
1 /*
2  * SH7750 device
3  *
4  * Copyright (c) 2007 Magnus Damm
5  * Copyright (c) 2005 Samuel Tardieu
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 #include <stdio.h>
26 #include <assert.h>
27 #include "hw.h"
28 #include "sh.h"
29 #include "sysemu.h"
30 #include "sh7750_regs.h"
31 #include "sh7750_regnames.h"
32 #include "sh_intc.h"
33 #include "exec-all.h"
34 #include "cpu.h"
35
36 #define NB_DEVICES 4
37
38 typedef struct SH7750State {
39     /* CPU */
40     CPUSH4State *cpu;
41     /* Peripheral frequency in Hz */
42     uint32_t periph_freq;
43     /* SDRAM controller */
44     uint32_t bcr1;
45     uint16_t bcr2;
46     uint16_t bcr3;
47     uint32_t bcr4;
48     uint16_t rfcr;
49     /* PCMCIA controller */
50     uint16_t pcr;
51     /* IO ports */
52     uint16_t gpioic;
53     uint32_t pctra;
54     uint32_t pctrb;
55     uint16_t portdira;          /* Cached */
56     uint16_t portpullupa;       /* Cached */
57     uint16_t portdirb;          /* Cached */
58     uint16_t portpullupb;       /* Cached */
59     uint16_t pdtra;
60     uint16_t pdtrb;
61     uint16_t periph_pdtra;      /* Imposed by the peripherals */
62     uint16_t periph_portdira;   /* Direction seen from the peripherals */
63     uint16_t periph_pdtrb;      /* Imposed by the peripherals */
64     uint16_t periph_portdirb;   /* Direction seen from the peripherals */
65     sh7750_io_device *devices[NB_DEVICES];      /* External peripherals */
66
67     /* Cache */
68     uint32_t ccr;
69
70     struct intc_desc intc;
71 } SH7750State;
72
73 static int inline has_bcr3_and_bcr4(SH7750State * s)
74 {
75         return (s->cpu->features & SH_FEATURE_BCR3_AND_BCR4);
76 }
77 /**********************************************************************
78  I/O ports
79 **********************************************************************/
80
81 int sh7750_register_io_device(SH7750State * s, sh7750_io_device * device)
82 {
83     int i;
84
85     for (i = 0; i < NB_DEVICES; i++) {
86         if (s->devices[i] == NULL) {
87             s->devices[i] = device;
88             return 0;
89         }
90     }
91     return -1;
92 }
93
94 static uint16_t portdir(uint32_t v)
95 {
96 #define EVENPORTMASK(n) ((v & (1<<((n)<<1))) >> (n))
97     return
98         EVENPORTMASK(15) | EVENPORTMASK(14) | EVENPORTMASK(13) |
99         EVENPORTMASK(12) | EVENPORTMASK(11) | EVENPORTMASK(10) |
100         EVENPORTMASK(9) | EVENPORTMASK(8) | EVENPORTMASK(7) |
101         EVENPORTMASK(6) | EVENPORTMASK(5) | EVENPORTMASK(4) |
102         EVENPORTMASK(3) | EVENPORTMASK(2) | EVENPORTMASK(1) |
103         EVENPORTMASK(0);
104 }
105
106 static uint16_t portpullup(uint32_t v)
107 {
108 #define ODDPORTMASK(n) ((v & (1<<(((n)<<1)+1))) >> (n))
109     return
110         ODDPORTMASK(15) | ODDPORTMASK(14) | ODDPORTMASK(13) |
111         ODDPORTMASK(12) | ODDPORTMASK(11) | ODDPORTMASK(10) |
112         ODDPORTMASK(9) | ODDPORTMASK(8) | ODDPORTMASK(7) | ODDPORTMASK(6) |
113         ODDPORTMASK(5) | ODDPORTMASK(4) | ODDPORTMASK(3) | ODDPORTMASK(2) |
114         ODDPORTMASK(1) | ODDPORTMASK(0);
115 }
116
117 static uint16_t porta_lines(SH7750State * s)
118 {
119     return (s->portdira & s->pdtra) |   /* CPU */
120         (s->periph_portdira & s->periph_pdtra) |        /* Peripherals */
121         (~(s->portdira | s->periph_portdira) & s->portpullupa); /* Pullups */
122 }
123
124 static uint16_t portb_lines(SH7750State * s)
125 {
126     return (s->portdirb & s->pdtrb) |   /* CPU */
127         (s->periph_portdirb & s->periph_pdtrb) |        /* Peripherals */
128         (~(s->portdirb | s->periph_portdirb) & s->portpullupb); /* Pullups */
129 }
130
131 static void gen_port_interrupts(SH7750State * s)
132 {
133     /* XXXXX interrupts not generated */
134 }
135
136 static void porta_changed(SH7750State * s, uint16_t prev)
137 {
138     uint16_t currenta, changes;
139     int i, r = 0;
140
141 #if 0
142     fprintf(stderr, "porta changed from 0x%04x to 0x%04x\n",
143             prev, porta_lines(s));
144     fprintf(stderr, "pdtra=0x%04x, pctra=0x%08x\n", s->pdtra, s->pctra);
145 #endif
146     currenta = porta_lines(s);
147     if (currenta == prev)
148         return;
149     changes = currenta ^ prev;
150
151     for (i = 0; i < NB_DEVICES; i++) {
152         if (s->devices[i] && (s->devices[i]->portamask_trigger & changes)) {
153             r |= s->devices[i]->port_change_cb(currenta, portb_lines(s),
154                                                &s->periph_pdtra,
155                                                &s->periph_portdira,
156                                                &s->periph_pdtrb,
157                                                &s->periph_portdirb);
158         }
159     }
160
161     if (r)
162         gen_port_interrupts(s);
163 }
164
165 static void portb_changed(SH7750State * s, uint16_t prev)
166 {
167     uint16_t currentb, changes;
168     int i, r = 0;
169
170     currentb = portb_lines(s);
171     if (currentb == prev)
172         return;
173     changes = currentb ^ prev;
174
175     for (i = 0; i < NB_DEVICES; i++) {
176         if (s->devices[i] && (s->devices[i]->portbmask_trigger & changes)) {
177             r |= s->devices[i]->port_change_cb(portb_lines(s), currentb,
178                                                &s->periph_pdtra,
179                                                &s->periph_portdira,
180                                                &s->periph_pdtrb,
181                                                &s->periph_portdirb);
182         }
183     }
184
185     if (r)
186         gen_port_interrupts(s);
187 }
188
189 /**********************************************************************
190  Memory
191 **********************************************************************/
192
193 static void error_access(const char *kind, target_phys_addr_t addr)
194 {
195     fprintf(stderr, "%s to %s (0x" TARGET_FMT_plx ") not supported\n",
196             kind, regname(addr), addr);
197 }
198
199 static void ignore_access(const char *kind, target_phys_addr_t addr)
200 {
201     fprintf(stderr, "%s to %s (0x" TARGET_FMT_plx ") ignored\n",
202             kind, regname(addr), addr);
203 }
204
205 static uint32_t sh7750_mem_readb(void *opaque, target_phys_addr_t addr)
206 {
207     switch (addr) {
208     default:
209         error_access("byte read", addr);
210         assert(0);
211     }
212 }
213
214 static uint32_t sh7750_mem_readw(void *opaque, target_phys_addr_t addr)
215 {
216     SH7750State *s = opaque;
217
218     switch (addr) {
219     case SH7750_BCR2_A7:
220         return s->bcr2;
221     case SH7750_BCR3_A7:
222         if(!has_bcr3_and_bcr4(s))
223             error_access("word read", addr);
224         return s->bcr3;
225     case SH7750_FRQCR_A7:
226         return 0;
227     case SH7750_PCR_A7:
228         return s->pcr;
229     case SH7750_RFCR_A7:
230         fprintf(stderr,
231                 "Read access to refresh count register, incrementing\n");
232         return s->rfcr++;
233     case SH7750_PDTRA_A7:
234         return porta_lines(s);
235     case SH7750_PDTRB_A7:
236         return portb_lines(s);
237     case SH7750_RTCOR_A7:
238     case SH7750_RTCNT_A7:
239     case SH7750_RTCSR_A7:
240         ignore_access("word read", addr);
241         return 0;
242     default:
243         error_access("word read", addr);
244         assert(0);
245     }
246 }
247
248 static uint32_t sh7750_mem_readl(void *opaque, target_phys_addr_t addr)
249 {
250     SH7750State *s = opaque;
251
252     switch (addr) {
253     case SH7750_BCR1_A7:
254         return s->bcr1;
255     case SH7750_BCR4_A7:
256         if(!has_bcr3_and_bcr4(s))
257             error_access("long read", addr);
258         return s->bcr4;
259     case SH7750_WCR1_A7:
260     case SH7750_WCR2_A7:
261     case SH7750_WCR3_A7:
262     case SH7750_MCR_A7:
263         ignore_access("long read", addr);
264         return 0;
265     case SH7750_MMUCR_A7:
266         return s->cpu->mmucr;
267     case SH7750_PTEH_A7:
268         return s->cpu->pteh;
269     case SH7750_PTEL_A7:
270         return s->cpu->ptel;
271     case SH7750_TTB_A7:
272         return s->cpu->ttb;
273     case SH7750_TEA_A7:
274         return s->cpu->tea;
275     case SH7750_TRA_A7:
276         return s->cpu->tra;
277     case SH7750_EXPEVT_A7:
278         return s->cpu->expevt;
279     case SH7750_INTEVT_A7:
280         return s->cpu->intevt;
281     case SH7750_CCR_A7:
282         return s->ccr;
283     case 0x1f000030:            /* Processor version */
284         return s->cpu->pvr;
285     case 0x1f000040:            /* Cache version */
286         return s->cpu->cvr;
287     case 0x1f000044:            /* Processor revision */
288         return s->cpu->prr;
289     default:
290         error_access("long read", addr);
291         assert(0);
292     }
293 }
294
295 #define is_in_sdrmx(a, x) (a >= SH7750_SDMR ## x ## _A7 \
296                         && a <= (SH7750_SDMR ## x ## _A7 + SH7750_SDMR ## x ## _REGNB))
297 static void sh7750_mem_writeb(void *opaque, target_phys_addr_t addr,
298                               uint32_t mem_value)
299 {
300
301     if (is_in_sdrmx(addr, 2) || is_in_sdrmx(addr, 3)) {
302         ignore_access("byte write", addr);
303         return;
304     }
305
306     error_access("byte write", addr);
307     assert(0);
308 }
309
310 static void sh7750_mem_writew(void *opaque, target_phys_addr_t addr,
311                               uint32_t mem_value)
312 {
313     SH7750State *s = opaque;
314     uint16_t temp;
315
316     switch (addr) {
317         /* SDRAM controller */
318     case SH7750_BCR2_A7:
319         s->bcr2 = mem_value;
320         return;
321     case SH7750_BCR3_A7:
322         if(!has_bcr3_and_bcr4(s))
323             error_access("word write", addr);
324         s->bcr3 = mem_value;
325         return;
326     case SH7750_PCR_A7:
327         s->pcr = mem_value;
328         return;
329     case SH7750_RTCNT_A7:
330     case SH7750_RTCOR_A7:
331     case SH7750_RTCSR_A7:
332         ignore_access("word write", addr);
333         return;
334         /* IO ports */
335     case SH7750_PDTRA_A7:
336         temp = porta_lines(s);
337         s->pdtra = mem_value;
338         porta_changed(s, temp);
339         return;
340     case SH7750_PDTRB_A7:
341         temp = portb_lines(s);
342         s->pdtrb = mem_value;
343         portb_changed(s, temp);
344         return;
345     case SH7750_RFCR_A7:
346         fprintf(stderr, "Write access to refresh count register\n");
347         s->rfcr = mem_value;
348         return;
349     case SH7750_GPIOIC_A7:
350         s->gpioic = mem_value;
351         if (mem_value != 0) {
352             fprintf(stderr, "I/O interrupts not implemented\n");
353             assert(0);
354         }
355         return;
356     default:
357         error_access("word write", addr);
358         assert(0);
359     }
360 }
361
362 static void sh7750_mem_writel(void *opaque, target_phys_addr_t addr,
363                               uint32_t mem_value)
364 {
365     SH7750State *s = opaque;
366     uint16_t temp;
367
368     switch (addr) {
369         /* SDRAM controller */
370     case SH7750_BCR1_A7:
371         s->bcr1 = mem_value;
372         return;
373     case SH7750_BCR4_A7:
374         if(!has_bcr3_and_bcr4(s))
375             error_access("long write", addr);
376         s->bcr4 = mem_value;
377         return;
378     case SH7750_WCR1_A7:
379     case SH7750_WCR2_A7:
380     case SH7750_WCR3_A7:
381     case SH7750_MCR_A7:
382         ignore_access("long write", addr);
383         return;
384         /* IO ports */
385     case SH7750_PCTRA_A7:
386         temp = porta_lines(s);
387         s->pctra = mem_value;
388         s->portdira = portdir(mem_value);
389         s->portpullupa = portpullup(mem_value);
390         porta_changed(s, temp);
391         return;
392     case SH7750_PCTRB_A7:
393         temp = portb_lines(s);
394         s->pctrb = mem_value;
395         s->portdirb = portdir(mem_value);
396         s->portpullupb = portpullup(mem_value);
397         portb_changed(s, temp);
398         return;
399     case SH7750_MMUCR_A7:
400         s->cpu->mmucr = mem_value;
401         return;
402     case SH7750_PTEH_A7:
403         /* If asid changes, clear all registered tlb entries. */
404         if ((s->cpu->pteh & 0xff) != (mem_value & 0xff))
405             tlb_flush(s->cpu, 1);
406         s->cpu->pteh = mem_value;
407         return;
408     case SH7750_PTEL_A7:
409         s->cpu->ptel = mem_value;
410         return;
411     case SH7750_PTEA_A7:
412         s->cpu->ptea = mem_value & 0x0000000f;
413         return;
414     case SH7750_TTB_A7:
415         s->cpu->ttb = mem_value;
416         return;
417     case SH7750_TEA_A7:
418         s->cpu->tea = mem_value;
419         return;
420     case SH7750_TRA_A7:
421         s->cpu->tra = mem_value & 0x000007ff;
422         return;
423     case SH7750_EXPEVT_A7:
424         s->cpu->expevt = mem_value & 0x000007ff;
425         return;
426     case SH7750_INTEVT_A7:
427         s->cpu->intevt = mem_value & 0x000007ff;
428         return;
429     case SH7750_CCR_A7:
430         s->ccr = mem_value;
431         return;
432     default:
433         error_access("long write", addr);
434         assert(0);
435     }
436 }
437
438 static CPUReadMemoryFunc *sh7750_mem_read[] = {
439     sh7750_mem_readb,
440     sh7750_mem_readw,
441     sh7750_mem_readl
442 };
443
444 static CPUWriteMemoryFunc *sh7750_mem_write[] = {
445     sh7750_mem_writeb,
446     sh7750_mem_writew,
447     sh7750_mem_writel
448 };
449
450 /* sh775x interrupt controller tables for sh_intc.c
451  * stolen from linux/arch/sh/kernel/cpu/sh4/setup-sh7750.c
452  */
453
454 enum {
455         UNUSED = 0,
456
457         /* interrupt sources */
458         IRL_0, IRL_1, IRL_2, IRL_3, IRL_4, IRL_5, IRL_6, IRL_7,
459         IRL_8, IRL_9, IRL_A, IRL_B, IRL_C, IRL_D, IRL_E,
460         IRL0, IRL1, IRL2, IRL3,
461         HUDI, GPIOI,
462         DMAC_DMTE0, DMAC_DMTE1, DMAC_DMTE2, DMAC_DMTE3,
463         DMAC_DMTE4, DMAC_DMTE5, DMAC_DMTE6, DMAC_DMTE7,
464         DMAC_DMAE,
465         PCIC0_PCISERR, PCIC1_PCIERR, PCIC1_PCIPWDWN, PCIC1_PCIPWON,
466         PCIC1_PCIDMA0, PCIC1_PCIDMA1, PCIC1_PCIDMA2, PCIC1_PCIDMA3,
467         TMU3, TMU4, TMU0, TMU1, TMU2_TUNI, TMU2_TICPI,
468         RTC_ATI, RTC_PRI, RTC_CUI,
469         SCI1_ERI, SCI1_RXI, SCI1_TXI, SCI1_TEI,
470         SCIF_ERI, SCIF_RXI, SCIF_BRI, SCIF_TXI,
471         WDT,
472         REF_RCMI, REF_ROVI,
473
474         /* interrupt groups */
475         DMAC, PCIC1, TMU2, RTC, SCI1, SCIF, REF,
476         /* irl bundle */
477         IRL,
478
479         NR_SOURCES,
480 };
481
482 static struct intc_vect vectors[] = {
483         INTC_VECT(HUDI, 0x600), INTC_VECT(GPIOI, 0x620),
484         INTC_VECT(TMU0, 0x400), INTC_VECT(TMU1, 0x420),
485         INTC_VECT(TMU2_TUNI, 0x440), INTC_VECT(TMU2_TICPI, 0x460),
486         INTC_VECT(RTC_ATI, 0x480), INTC_VECT(RTC_PRI, 0x4a0),
487         INTC_VECT(RTC_CUI, 0x4c0),
488         INTC_VECT(SCI1_ERI, 0x4e0), INTC_VECT(SCI1_RXI, 0x500),
489         INTC_VECT(SCI1_TXI, 0x520), INTC_VECT(SCI1_TEI, 0x540),
490         INTC_VECT(SCIF_ERI, 0x700), INTC_VECT(SCIF_RXI, 0x720),
491         INTC_VECT(SCIF_BRI, 0x740), INTC_VECT(SCIF_TXI, 0x760),
492         INTC_VECT(WDT, 0x560),
493         INTC_VECT(REF_RCMI, 0x580), INTC_VECT(REF_ROVI, 0x5a0),
494 };
495
496 static struct intc_group groups[] = {
497         INTC_GROUP(TMU2, TMU2_TUNI, TMU2_TICPI),
498         INTC_GROUP(RTC, RTC_ATI, RTC_PRI, RTC_CUI),
499         INTC_GROUP(SCI1, SCI1_ERI, SCI1_RXI, SCI1_TXI, SCI1_TEI),
500         INTC_GROUP(SCIF, SCIF_ERI, SCIF_RXI, SCIF_BRI, SCIF_TXI),
501         INTC_GROUP(REF, REF_RCMI, REF_ROVI),
502 };
503
504 static struct intc_prio_reg prio_registers[] = {
505         { 0xffd00004, 0, 16, 4, /* IPRA */ { TMU0, TMU1, TMU2, RTC } },
506         { 0xffd00008, 0, 16, 4, /* IPRB */ { WDT, REF, SCI1, 0 } },
507         { 0xffd0000c, 0, 16, 4, /* IPRC */ { GPIOI, DMAC, SCIF, HUDI } },
508         { 0xffd00010, 0, 16, 4, /* IPRD */ { IRL0, IRL1, IRL2, IRL3 } },
509         { 0xfe080000, 0, 32, 4, /* INTPRI00 */ { 0, 0, 0, 0,
510                                                  TMU4, TMU3,
511                                                  PCIC1, PCIC0_PCISERR } },
512 };
513
514 /* SH7750, SH7750S, SH7751 and SH7091 all have 4-channel DMA controllers */
515
516 static struct intc_vect vectors_dma4[] = {
517         INTC_VECT(DMAC_DMTE0, 0x640), INTC_VECT(DMAC_DMTE1, 0x660),
518         INTC_VECT(DMAC_DMTE2, 0x680), INTC_VECT(DMAC_DMTE3, 0x6a0),
519         INTC_VECT(DMAC_DMAE, 0x6c0),
520 };
521
522 static struct intc_group groups_dma4[] = {
523         INTC_GROUP(DMAC, DMAC_DMTE0, DMAC_DMTE1, DMAC_DMTE2,
524                    DMAC_DMTE3, DMAC_DMAE),
525 };
526
527 /* SH7750R and SH7751R both have 8-channel DMA controllers */
528
529 static struct intc_vect vectors_dma8[] = {
530         INTC_VECT(DMAC_DMTE0, 0x640), INTC_VECT(DMAC_DMTE1, 0x660),
531         INTC_VECT(DMAC_DMTE2, 0x680), INTC_VECT(DMAC_DMTE3, 0x6a0),
532         INTC_VECT(DMAC_DMTE4, 0x780), INTC_VECT(DMAC_DMTE5, 0x7a0),
533         INTC_VECT(DMAC_DMTE6, 0x7c0), INTC_VECT(DMAC_DMTE7, 0x7e0),
534         INTC_VECT(DMAC_DMAE, 0x6c0),
535 };
536
537 static struct intc_group groups_dma8[] = {
538         INTC_GROUP(DMAC, DMAC_DMTE0, DMAC_DMTE1, DMAC_DMTE2,
539                    DMAC_DMTE3, DMAC_DMTE4, DMAC_DMTE5,
540                    DMAC_DMTE6, DMAC_DMTE7, DMAC_DMAE),
541 };
542
543 /* SH7750R, SH7751 and SH7751R all have two extra timer channels */
544
545 static struct intc_vect vectors_tmu34[] = {
546         INTC_VECT(TMU3, 0xb00), INTC_VECT(TMU4, 0xb80),
547 };
548
549 static struct intc_mask_reg mask_registers[] = {
550         { 0xfe080040, 0xfe080060, 32, /* INTMSK00 / INTMSKCLR00 */
551           { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
552             0, 0, 0, 0, 0, 0, TMU4, TMU3,
553             PCIC1_PCIERR, PCIC1_PCIPWDWN, PCIC1_PCIPWON,
554             PCIC1_PCIDMA0, PCIC1_PCIDMA1, PCIC1_PCIDMA2,
555             PCIC1_PCIDMA3, PCIC0_PCISERR } },
556 };
557
558 /* SH7750S, SH7750R, SH7751 and SH7751R all have IRLM priority registers */
559
560 static struct intc_vect vectors_irlm[] = {
561         INTC_VECT(IRL0, 0x240), INTC_VECT(IRL1, 0x2a0),
562         INTC_VECT(IRL2, 0x300), INTC_VECT(IRL3, 0x360),
563 };
564
565 /* SH7751 and SH7751R both have PCI */
566
567 static struct intc_vect vectors_pci[] = {
568         INTC_VECT(PCIC0_PCISERR, 0xa00), INTC_VECT(PCIC1_PCIERR, 0xae0),
569         INTC_VECT(PCIC1_PCIPWDWN, 0xac0), INTC_VECT(PCIC1_PCIPWON, 0xaa0),
570         INTC_VECT(PCIC1_PCIDMA0, 0xa80), INTC_VECT(PCIC1_PCIDMA1, 0xa60),
571         INTC_VECT(PCIC1_PCIDMA2, 0xa40), INTC_VECT(PCIC1_PCIDMA3, 0xa20),
572 };
573
574 static struct intc_group groups_pci[] = {
575         INTC_GROUP(PCIC1, PCIC1_PCIERR, PCIC1_PCIPWDWN, PCIC1_PCIPWON,
576                    PCIC1_PCIDMA0, PCIC1_PCIDMA1, PCIC1_PCIDMA2, PCIC1_PCIDMA3),
577 };
578
579 static struct intc_vect vectors_irl[] = {
580         INTC_VECT(IRL_0, 0x200),
581         INTC_VECT(IRL_1, 0x220),
582         INTC_VECT(IRL_2, 0x240),
583         INTC_VECT(IRL_3, 0x260),
584         INTC_VECT(IRL_4, 0x280),
585         INTC_VECT(IRL_5, 0x2a0),
586         INTC_VECT(IRL_6, 0x2c0),
587         INTC_VECT(IRL_7, 0x2e0),
588         INTC_VECT(IRL_8, 0x300),
589         INTC_VECT(IRL_9, 0x320),
590         INTC_VECT(IRL_A, 0x340),
591         INTC_VECT(IRL_B, 0x360),
592         INTC_VECT(IRL_C, 0x380),
593         INTC_VECT(IRL_D, 0x3a0),
594         INTC_VECT(IRL_E, 0x3c0),
595 };
596
597 static struct intc_group groups_irl[] = {
598         INTC_GROUP(IRL, IRL_0, IRL_1, IRL_2, IRL_3, IRL_4, IRL_5, IRL_6,
599                 IRL_7, IRL_8, IRL_9, IRL_A, IRL_B, IRL_C, IRL_D, IRL_E),
600 };
601
602 /**********************************************************************
603  Memory mapped cache and TLB
604 **********************************************************************/
605
606 #define MM_REGION_MASK   0x07000000
607 #define MM_ICACHE_ADDR   (0)
608 #define MM_ICACHE_DATA   (1)
609 #define MM_ITLB_ADDR     (2)
610 #define MM_ITLB_DATA     (3)
611 #define MM_OCACHE_ADDR   (4)
612 #define MM_OCACHE_DATA   (5)
613 #define MM_UTLB_ADDR     (6)
614 #define MM_UTLB_DATA     (7)
615 #define MM_REGION_TYPE(addr)  ((addr & MM_REGION_MASK) >> 24)
616
617 static uint32_t invalid_read(void *opaque, target_phys_addr_t addr)
618 {
619     assert(0);
620
621     return 0;
622 }
623
624 static uint32_t sh7750_mmct_readl(void *opaque, target_phys_addr_t addr)
625 {
626     uint32_t ret = 0;
627
628     switch (MM_REGION_TYPE(addr)) {
629     case MM_ICACHE_ADDR:
630     case MM_ICACHE_DATA:
631         /* do nothing */
632         break;
633     case MM_ITLB_ADDR:
634     case MM_ITLB_DATA:
635         /* XXXXX */
636         assert(0);
637         break;
638     case MM_OCACHE_ADDR:
639     case MM_OCACHE_DATA:
640         /* do nothing */
641         break;
642     case MM_UTLB_ADDR:
643     case MM_UTLB_DATA:
644         /* XXXXX */
645         assert(0);
646         break;
647     default:
648         assert(0);
649     }
650
651     return ret;
652 }
653
654 static void invalid_write(void *opaque, target_phys_addr_t addr,
655                           uint32_t mem_value)
656 {
657     assert(0);
658 }
659
660 static void sh7750_mmct_writel(void *opaque, target_phys_addr_t addr,
661                                 uint32_t mem_value)
662 {
663     SH7750State *s = opaque;
664
665     switch (MM_REGION_TYPE(addr)) {
666     case MM_ICACHE_ADDR:
667     case MM_ICACHE_DATA:
668         /* do nothing */
669         break;
670     case MM_ITLB_ADDR:
671     case MM_ITLB_DATA:
672         /* XXXXX */
673         assert(0);
674         break;
675     case MM_OCACHE_ADDR:
676     case MM_OCACHE_DATA:
677         /* do nothing */
678         break;
679     case MM_UTLB_ADDR:
680         cpu_sh4_write_mmaped_utlb_addr(s->cpu, addr, mem_value);
681         break;
682     case MM_UTLB_DATA:
683         /* XXXXX */
684         assert(0);
685         break;
686     default:
687         assert(0);
688         break;
689     }
690 }
691
692 static CPUReadMemoryFunc *sh7750_mmct_read[] = {
693     invalid_read,
694     invalid_read,
695     sh7750_mmct_readl
696 };
697
698 static CPUWriteMemoryFunc *sh7750_mmct_write[] = {
699     invalid_write,
700     invalid_write,
701     sh7750_mmct_writel
702 };
703
704 SH7750State *sh7750_init(CPUSH4State * cpu)
705 {
706     SH7750State *s;
707     int sh7750_io_memory;
708     int sh7750_mm_cache_and_tlb; /* memory mapped cache and tlb */
709
710     s = qemu_mallocz(sizeof(SH7750State));
711     s->cpu = cpu;
712     s->periph_freq = 60000000;  /* 60MHz */
713     sh7750_io_memory = cpu_register_io_memory(0,
714                                               sh7750_mem_read,
715                                               sh7750_mem_write, s);
716     cpu_register_physical_memory_offset(0x1f000000, 0x1000,
717                                         sh7750_io_memory, 0x1f000000);
718     cpu_register_physical_memory_offset(0xff000000, 0x1000,
719                                         sh7750_io_memory, 0x1f000000);
720     cpu_register_physical_memory_offset(0x1f800000, 0x1000,
721                                         sh7750_io_memory, 0x1f800000);
722     cpu_register_physical_memory_offset(0xff800000, 0x1000,
723                                         sh7750_io_memory, 0x1f800000);
724     cpu_register_physical_memory_offset(0x1fc00000, 0x1000,
725                                         sh7750_io_memory, 0x1fc00000);
726     cpu_register_physical_memory_offset(0xffc00000, 0x1000,
727                                         sh7750_io_memory, 0x1fc00000);
728
729     sh7750_mm_cache_and_tlb = cpu_register_io_memory(0,
730                                                      sh7750_mmct_read,
731                                                      sh7750_mmct_write, s);
732     cpu_register_physical_memory(0xf0000000, 0x08000000,
733                                  sh7750_mm_cache_and_tlb);
734
735     sh_intc_init(&s->intc, NR_SOURCES,
736                  _INTC_ARRAY(mask_registers),
737                  _INTC_ARRAY(prio_registers));
738
739     sh_intc_register_sources(&s->intc,
740                              _INTC_ARRAY(vectors),
741                              _INTC_ARRAY(groups));
742
743     cpu->intc_handle = &s->intc;
744
745     sh_serial_init(0x1fe00000, 0, s->periph_freq, serial_hds[0],
746                    s->intc.irqs[SCI1_ERI],
747                    s->intc.irqs[SCI1_RXI],
748                    s->intc.irqs[SCI1_TXI],
749                    s->intc.irqs[SCI1_TEI],
750                    NULL);
751     sh_serial_init(0x1fe80000, SH_SERIAL_FEAT_SCIF,
752                    s->periph_freq, serial_hds[1],
753                    s->intc.irqs[SCIF_ERI],
754                    s->intc.irqs[SCIF_RXI],
755                    s->intc.irqs[SCIF_TXI],
756                    NULL,
757                    s->intc.irqs[SCIF_BRI]);
758
759     tmu012_init(0x1fd80000,
760                 TMU012_FEAT_TOCR | TMU012_FEAT_3CHAN | TMU012_FEAT_EXTCLK,
761                 s->periph_freq,
762                 s->intc.irqs[TMU0],
763                 s->intc.irqs[TMU1],
764                 s->intc.irqs[TMU2_TUNI],
765                 s->intc.irqs[TMU2_TICPI]);
766
767     if (cpu->id & (SH_CPU_SH7750 | SH_CPU_SH7750S | SH_CPU_SH7751)) {
768         sh_intc_register_sources(&s->intc,
769                                  _INTC_ARRAY(vectors_dma4),
770                                  _INTC_ARRAY(groups_dma4));
771     }
772
773     if (cpu->id & (SH_CPU_SH7750R | SH_CPU_SH7751R)) {
774         sh_intc_register_sources(&s->intc,
775                                  _INTC_ARRAY(vectors_dma8),
776                                  _INTC_ARRAY(groups_dma8));
777     }
778
779     if (cpu->id & (SH_CPU_SH7750R | SH_CPU_SH7751 | SH_CPU_SH7751R)) {
780         sh_intc_register_sources(&s->intc,
781                                  _INTC_ARRAY(vectors_tmu34),
782                                  NULL, 0);
783         tmu012_init(0x1e100000, 0, s->periph_freq,
784                     s->intc.irqs[TMU3],
785                     s->intc.irqs[TMU4],
786                     NULL, NULL);
787     }
788
789     if (cpu->id & (SH_CPU_SH7751_ALL)) {
790         sh_intc_register_sources(&s->intc,
791                                  _INTC_ARRAY(vectors_pci),
792                                  _INTC_ARRAY(groups_pci));
793     }
794
795     if (cpu->id & (SH_CPU_SH7750S | SH_CPU_SH7750R | SH_CPU_SH7751_ALL)) {
796         sh_intc_register_sources(&s->intc,
797                                  _INTC_ARRAY(vectors_irlm),
798                                  NULL, 0);
799     }
800
801     sh_intc_register_sources(&s->intc,
802                                 _INTC_ARRAY(vectors_irl),
803                                 _INTC_ARRAY(groups_irl));
804     return s;
805 }
806
807 qemu_irq sh7750_irl(SH7750State *s)
808 {
809     sh_intc_toggle_source(sh_intc_source(&s->intc, IRL), 1, 0); /* enable */
810     return qemu_allocate_irqs(sh_intc_set_irl, sh_intc_source(&s->intc, IRL),
811                                1)[0];
812 }