Revision 80f515e6 hw/sh7750.c

b/hw/sh7750.c
1 1
/*
2 2
 * SH7750 device
3 3
 *
4
 * Copyright (c) 2007 Magnus Damm
4 5
 * Copyright (c) 2005 Samuel Tardieu
5 6
 *
6 7
 * Permission is hereby granted, free of charge, to any person obtaining a copy
......
26 27
#include "vl.h"
27 28
#include "sh7750_regs.h"
28 29
#include "sh7750_regnames.h"
30
#include "sh_intc.h"
29 31

  
30 32
#define NB_DEVICES 4
31 33

  
......
53 55
    sh7750_io_device *devices[NB_DEVICES];	/* External peripherals */
54 56

  
55 57
    uint16_t icr;
56
    uint16_t ipra;
57
    uint16_t iprb;
58
    uint16_t iprc;
59
    uint16_t iprd;
60
    uint32_t intpri00;
61
    uint32_t intmsk00;
62 58
    /* Cache */
63 59
    uint32_t ccr;
64 60

  
61
    struct intc_desc intc;
65 62
} SH7750State;
66 63

  
67 64

  
......
219 216
	return portb_lines(s);
220 217
    case 0x1fd00000:
221 218
        return s->icr;
222
    case 0x1fd00004:
223
        return s->ipra;
224
    case 0x1fd00008:
225
        return s->iprb;
226
    case 0x1fd0000c:
227
        return s->iprc;
228
    case 0x1fd00010:
229
        return s->iprd;
230 219
    default:
231 220
	error_access("word read", addr);
232 221
	assert(0);
......
262 251
	return 0x00110000;	/* Minimum caches */
263 252
    case 0x1f000044:		/* Processor version PRR */
264 253
	return 0x00000100;	/* SH7750R */
265
    case 0x1e080000:
266
        return s->intpri00;
267
    case 0x1e080020:
268
        return 0;
269
    case 0x1e080040:
270
        return s->intmsk00;
271
    case 0x1e080060:
272
        return 0;
273 254
    default:
274 255
	error_access("long read", addr);
275 256
	assert(0);
......
331 312
    case 0x1fd00000:
332 313
        s->icr = mem_value;
333 314
	return;
334
    case 0x1fd00004:
335
        s->ipra = mem_value;
336
	return;
337
    case 0x1fd00008:
338
        s->iprb = mem_value;
339
	return;
340
    case 0x1fd0000c:
341
        s->iprc = mem_value;
342
	return;
343
    case 0x1fd00010:
344
        s->iprd = mem_value;
345
	return;
346 315
    default:
347 316
	error_access("word write", addr);
348 317
	assert(0);
......
407 376
    case SH7750_CCR_A7:
408 377
	s->ccr = mem_value;
409 378
	return;
410
    case 0x1e080000:
411
        s->intpri00 = mem_value;
412
	return;
413
    case 0x1e080020:
414
        return;
415
    case 0x1e080040:
416
        s->intmsk00 = mem_value;
417
	return;
418
    case 0x1e080060:
419
        return;
420 379
    default:
421 380
	error_access("long write", addr);
422 381
	assert(0);
......
435 394
    sh7750_mem_writel
436 395
};
437 396

  
397
/* sh775x interrupt controller tables for sh_intc.c
398
 * stolen from linux/arch/sh/kernel/cpu/sh4/setup-sh7750.c
399
 */
400

  
401
enum {
402
	UNUSED = 0,
403

  
404
	/* interrupt sources */
405
	IRL0, IRL1, IRL2, IRL3, /* only IRLM mode supported */
406
	HUDI, GPIOI,
407
	DMAC_DMTE0, DMAC_DMTE1, DMAC_DMTE2, DMAC_DMTE3,
408
	DMAC_DMTE4, DMAC_DMTE5, DMAC_DMTE6, DMAC_DMTE7,
409
	DMAC_DMAE,
410
	PCIC0_PCISERR, PCIC1_PCIERR, PCIC1_PCIPWDWN, PCIC1_PCIPWON,
411
	PCIC1_PCIDMA0, PCIC1_PCIDMA1, PCIC1_PCIDMA2, PCIC1_PCIDMA3,
412
	TMU3, TMU4, TMU0, TMU1, TMU2_TUNI, TMU2_TICPI,
413
	RTC_ATI, RTC_PRI, RTC_CUI,
414
	SCI1_ERI, SCI1_RXI, SCI1_TXI, SCI1_TEI,
415
	SCIF_ERI, SCIF_RXI, SCIF_BRI, SCIF_TXI,
416
	WDT,
417
	REF_RCMI, REF_ROVI,
418

  
419
	/* interrupt groups */
420
	DMAC, PCIC1, TMU2, RTC, SCI1, SCIF, REF,
421

  
422
	NR_SOURCES,
423
};
424

  
425
static struct intc_vect vectors[] = {
426
	INTC_VECT(HUDI, 0x600), INTC_VECT(GPIOI, 0x620),
427
	INTC_VECT(TMU0, 0x400), INTC_VECT(TMU1, 0x420),
428
	INTC_VECT(TMU2_TUNI, 0x440), INTC_VECT(TMU2_TICPI, 0x460),
429
	INTC_VECT(RTC_ATI, 0x480), INTC_VECT(RTC_PRI, 0x4a0),
430
	INTC_VECT(RTC_CUI, 0x4c0),
431
	INTC_VECT(SCI1_ERI, 0x4e0), INTC_VECT(SCI1_RXI, 0x500),
432
	INTC_VECT(SCI1_TXI, 0x520), INTC_VECT(SCI1_TEI, 0x540),
433
	INTC_VECT(SCIF_ERI, 0x700), INTC_VECT(SCIF_RXI, 0x720),
434
	INTC_VECT(SCIF_BRI, 0x740), INTC_VECT(SCIF_TXI, 0x760),
435
	INTC_VECT(WDT, 0x560),
436
	INTC_VECT(REF_RCMI, 0x580), INTC_VECT(REF_ROVI, 0x5a0),
437
};
438

  
439
static struct intc_group groups[] = {
440
	INTC_GROUP(TMU2, TMU2_TUNI, TMU2_TICPI),
441
	INTC_GROUP(RTC, RTC_ATI, RTC_PRI, RTC_CUI),
442
	INTC_GROUP(SCI1, SCI1_ERI, SCI1_RXI, SCI1_TXI, SCI1_TEI),
443
	INTC_GROUP(SCIF, SCIF_ERI, SCIF_RXI, SCIF_BRI, SCIF_TXI),
444
	INTC_GROUP(REF, REF_RCMI, REF_ROVI),
445
};
446

  
447
static struct intc_prio_reg prio_registers[] = {
448
	{ 0xffd00004, 0, 16, 4, /* IPRA */ { TMU0, TMU1, TMU2, RTC } },
449
	{ 0xffd00008, 0, 16, 4, /* IPRB */ { WDT, REF, SCI1, 0 } },
450
	{ 0xffd0000c, 0, 16, 4, /* IPRC */ { GPIOI, DMAC, SCIF, HUDI } },
451
	{ 0xffd00010, 0, 16, 4, /* IPRD */ { IRL0, IRL1, IRL2, IRL3 } },
452
	{ 0xfe080000, 0, 32, 4, /* INTPRI00 */ { 0, 0, 0, 0,
453
						 TMU4, TMU3,
454
						 PCIC1, PCIC0_PCISERR } },
455
};
456

  
457
/* SH7750, SH7750S, SH7751 and SH7091 all have 4-channel DMA controllers */
458

  
459
static struct intc_vect vectors_dma4[] = {
460
	INTC_VECT(DMAC_DMTE0, 0x640), INTC_VECT(DMAC_DMTE1, 0x660),
461
	INTC_VECT(DMAC_DMTE2, 0x680), INTC_VECT(DMAC_DMTE3, 0x6a0),
462
	INTC_VECT(DMAC_DMAE, 0x6c0),
463
};
464

  
465
static struct intc_group groups_dma4[] = {
466
	INTC_GROUP(DMAC, DMAC_DMTE0, DMAC_DMTE1, DMAC_DMTE2,
467
		   DMAC_DMTE3, DMAC_DMAE),
468
};
469

  
470
/* SH7750R and SH7751R both have 8-channel DMA controllers */
471

  
472
static struct intc_vect vectors_dma8[] = {
473
	INTC_VECT(DMAC_DMTE0, 0x640), INTC_VECT(DMAC_DMTE1, 0x660),
474
	INTC_VECT(DMAC_DMTE2, 0x680), INTC_VECT(DMAC_DMTE3, 0x6a0),
475
	INTC_VECT(DMAC_DMTE4, 0x780), INTC_VECT(DMAC_DMTE5, 0x7a0),
476
	INTC_VECT(DMAC_DMTE6, 0x7c0), INTC_VECT(DMAC_DMTE7, 0x7e0),
477
	INTC_VECT(DMAC_DMAE, 0x6c0),
478
};
479

  
480
static struct intc_group groups_dma8[] = {
481
	INTC_GROUP(DMAC, DMAC_DMTE0, DMAC_DMTE1, DMAC_DMTE2,
482
		   DMAC_DMTE3, DMAC_DMTE4, DMAC_DMTE5,
483
		   DMAC_DMTE6, DMAC_DMTE7, DMAC_DMAE),
484
};
485

  
486
/* SH7750R, SH7751 and SH7751R all have two extra timer channels */
487

  
488
static struct intc_vect vectors_tmu34[] = {
489
	INTC_VECT(TMU3, 0xb00), INTC_VECT(TMU4, 0xb80),
490
};
491

  
492
static struct intc_mask_reg mask_registers[] = {
493
	{ 0xfe080040, 0xfe080060, 32, /* INTMSK00 / INTMSKCLR00 */
494
	  { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
495
	    0, 0, 0, 0, 0, 0, TMU4, TMU3,
496
	    PCIC1_PCIERR, PCIC1_PCIPWDWN, PCIC1_PCIPWON,
497
	    PCIC1_PCIDMA0, PCIC1_PCIDMA1, PCIC1_PCIDMA2,
498
	    PCIC1_PCIDMA3, PCIC0_PCISERR } },
499
};
500

  
501
/* SH7750S, SH7750R, SH7751 and SH7751R all have IRLM priority registers */
502

  
503
static struct intc_vect vectors_irlm[] = {
504
	INTC_VECT(IRL0, 0x240), INTC_VECT(IRL1, 0x2a0),
505
	INTC_VECT(IRL2, 0x300), INTC_VECT(IRL3, 0x360),
506
};
507

  
508
/* SH7751 and SH7751R both have PCI */
509

  
510
static struct intc_vect vectors_pci[] = {
511
	INTC_VECT(PCIC0_PCISERR, 0xa00), INTC_VECT(PCIC1_PCIERR, 0xae0),
512
	INTC_VECT(PCIC1_PCIPWDWN, 0xac0), INTC_VECT(PCIC1_PCIPWON, 0xaa0),
513
	INTC_VECT(PCIC1_PCIDMA0, 0xa80), INTC_VECT(PCIC1_PCIDMA1, 0xa60),
514
	INTC_VECT(PCIC1_PCIDMA2, 0xa40), INTC_VECT(PCIC1_PCIDMA3, 0xa20),
515
};
516

  
517
static struct intc_group groups_pci[] = {
518
	INTC_GROUP(PCIC1, PCIC1_PCIERR, PCIC1_PCIPWDWN, PCIC1_PCIPWON,
519
		   PCIC1_PCIDMA0, PCIC1_PCIDMA1, PCIC1_PCIDMA2, PCIC1_PCIDMA3),
520
};
521

  
522
#define SH_CPU_SH7750  (1 << 0)
523
#define SH_CPU_SH7750S (1 << 1)
524
#define SH_CPU_SH7750R (1 << 2)
525
#define SH_CPU_SH7751  (1 << 3)
526
#define SH_CPU_SH7751R (1 << 4)
527
#define SH_CPU_SH7750_ALL (SH_CPU_SH7750 | SH_CPU_SH7750S | SH_CPU_SH7750R)
528
#define SH_CPU_SH7751_ALL (SH_CPU_SH7751 | SH_CPU_SH7751R)
529

  
438 530
SH7750State *sh7750_init(CPUSH4State * cpu)
439 531
{
440 532
    SH7750State *s;
441 533
    int sh7750_io_memory;
534
    int cpu_model = SH_CPU_SH7751R; /* for now */
442 535

  
443 536
    s = qemu_mallocz(sizeof(SH7750State));
444 537
    s->cpu = cpu;
......
448 541
					      sh7750_mem_write, s);
449 542
    cpu_register_physical_memory(0x1c000000, 0x04000000, sh7750_io_memory);
450 543

  
544
    sh_intc_init(&s->intc, NR_SOURCES,
545
		 _INTC_ARRAY(mask_registers),
546
		 _INTC_ARRAY(prio_registers));
547

  
548
    sh_intc_register_sources(&s->intc, 
549
			     _INTC_ARRAY(vectors),
550
			     _INTC_ARRAY(groups));
551

  
451 552
    sh_serial_init(0x1fe00000, 0, s->periph_freq, serial_hds[0]);
452 553
    sh_serial_init(0x1fe80000, SH_SERIAL_FEAT_SCIF,
453 554
		   s->periph_freq, serial_hds[1]);
......
455 556
    tmu012_init(0x1fd80000,
456 557
		TMU012_FEAT_TOCR | TMU012_FEAT_3CHAN | TMU012_FEAT_EXTCLK,
457 558
		s->periph_freq);
458
    tmu012_init(0x1e100000, 0, s->periph_freq);
559

  
560

  
561
    if (cpu_model & (SH_CPU_SH7750 | SH_CPU_SH7750S | SH_CPU_SH7751)) {
562
        sh_intc_register_sources(&s->intc, 
563
				 _INTC_ARRAY(vectors_dma4),
564
				 _INTC_ARRAY(groups_dma4));
565
    }
566

  
567
    if (cpu_model & (SH_CPU_SH7750R | SH_CPU_SH7751R)) {
568
        sh_intc_register_sources(&s->intc, 
569
				 _INTC_ARRAY(vectors_dma8),
570
				 _INTC_ARRAY(groups_dma8));
571
    }
572

  
573
    if (cpu_model & (SH_CPU_SH7750R | SH_CPU_SH7751 | SH_CPU_SH7751R)) {
574
        sh_intc_register_sources(&s->intc, 
575
				 _INTC_ARRAY(vectors_tmu34),
576
				 _INTC_ARRAY(NULL));
577
        tmu012_init(0x1e100000, 0, s->periph_freq);
578
    }
579

  
580
    if (cpu_model & (SH_CPU_SH7751_ALL)) {
581
        sh_intc_register_sources(&s->intc, 
582
				 _INTC_ARRAY(vectors_pci),
583
				 _INTC_ARRAY(groups_pci));
584
    }
585

  
586
    if (cpu_model & (SH_CPU_SH7750S | SH_CPU_SH7750R | SH_CPU_SH7751_ALL)) {
587
        sh_intc_register_sources(&s->intc, 
588
				 _INTC_ARRAY(vectors_irlm),
589
				 _INTC_ARRAY(NULL));
590
    }
591

  
459 592
    return s;
460 593
}

Also available in: Unified diff