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