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