fix the cause register clear bug
[qemu/qemu-JZ.git] / hw / mips_jz.c
blobd4cf4959a51eaa73ac2a2f4ce21d3274e35d9c69
1 /*
2 * QEMU JZ Soc emulation
4 * Copyright (c) 2009 yajin (yajin@vm-kernel.org)
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 * THE SOFTWARE.
27 * The emulation target is pavo demo board.
28 * http://www.ingenic.cn/eng/productServ/kfyd/Hardware/pffaqQuestionContent.aspx?Category=2&Question=3
32 #include "hw.h"
33 #include "mips.h"
34 #include "sysemu.h"
35 #include "qemu-timer.h"
36 #include "qemu-char.h"
37 #include "flash.h"
38 #include "soc_dma.h"
39 #include "audio/audio.h"
40 #include "pc.h"
41 #include "osdep.h"
42 #include "mips_jz.h"
43 #include "console.h"
45 #define DEBUG /*global debug on/off */
47 #define DEBUG_CPM (1<<0x0)
48 #define DEBUG_EMC (1<<0x1)
49 #define DEBUG_GPIO (1<<0x2)
50 #define DEBUG_RTC (1<<0x3)
51 #define DEBUG_TCU (1<<0x4)
52 #define DEBUG_LCDC (1<<0x5)
53 #define DEBUG_DMA (1<<0x6)
54 #define DEBUG_FLAG 0//DEBUG_TCU// (DEBUG_CPM|DEBUG_EMC|DEBUG_GPIO \
55 // | DEBUG_RTC | DEBUG_TCU | DEBUG_LCDC | DEBUG_DMA)
58 #ifdef DEBUG
59 FILE *fp;
60 static void debug_init(void)
62 fp = fopen("jz4740.txt", "w+");
63 if (fp == NULL)
65 fprintf(stderr, "can not open jz4740.txt \n");
66 exit(-1);
69 static void debug_out(uint32_t flag, const char *format, ...)
71 va_list ap;
72 if (fp)
74 if (flag & DEBUG_FLAG)
76 va_start(ap, format);
77 vfprintf(fp, format, ap);
78 fflush(fp);
79 va_end(ap);
83 #else
84 static void debug_init(void)
87 static void debug_out(uint32_t flag, const char *format, ...)
90 #endif
92 uint32_t jz4740_badwidth_read8(void *opaque, target_phys_addr_t addr)
94 uint8_t ret;
96 JZ4740_8B_REG(addr);
97 cpu_physical_memory_read(addr, (void *) &ret, 1);
98 return ret;
101 void jz4740_badwidth_write8(void *opaque, target_phys_addr_t addr,
102 uint32_t value)
104 uint8_t val8 = value;
106 JZ4740_8B_REG(addr);
107 cpu_physical_memory_write(addr, (void *) &val8, 1);
110 uint32_t jz4740_badwidth_read16(void *opaque, target_phys_addr_t addr)
112 uint16_t ret;
113 JZ4740_16B_REG(addr);
114 cpu_physical_memory_read(addr, (void *) &ret, 2);
115 return ret;
118 void jz4740_badwidth_write16(void *opaque, target_phys_addr_t addr,
119 uint32_t value)
121 uint16_t val16 = value;
123 JZ4740_16B_REG(addr);
124 cpu_physical_memory_write(addr, (void *) &val16, 2);
127 uint32_t jz4740_badwidth_read32(void *opaque, target_phys_addr_t addr)
129 uint32_t ret;
131 JZ4740_32B_REG(addr);
132 cpu_physical_memory_read(addr, (void *) &ret, 4);
133 return ret;
136 void jz4740_badwidth_write32(void *opaque, target_phys_addr_t addr,
137 uint32_t value)
139 JZ4740_32B_REG(addr);
140 cpu_physical_memory_write(addr, (void *) &value, 4);
144 /*clock reset and power control*/
145 struct jz4740_cpm_s
147 target_phys_addr_t base;
148 struct jz_state_s *soc;
150 uint32_t cpccr;
151 uint32_t cppcr;
152 uint32_t i2scdr;
153 uint32_t lpcdr;
154 uint32_t msccdr;
155 uint32_t uhccdr;
156 uint32_t uhctst;
157 uint32_t ssicdr;
159 uint32_t lcr;
160 uint32_t clkgr;
161 uint32_t scr;
164 static void jz4740_dump_clocks(jz_clk parent)
166 jz_clk i = parent;
168 debug_out(DEBUG_CPM, "clock %s rate %d \n", i->name, i->rate);
169 for (i = i->child1; i; i = i->sibling)
170 jz4740_dump_clocks(i);
173 static inline void jz4740_cpccr_update(struct jz4740_cpm_s *s,
174 uint32_t new_value)
176 uint32_t ldiv, mdiv, pdiv, hdiv, cdiv, udiv;
177 uint32_t div_table[10] = {
178 1, 2, 3, 4, 6, 8, 12, 16, 24, 32
181 if (unlikely(new_value == s->cpccr))
182 return;
184 if (new_value & CPM_CPCCR_PCS)
185 jz_clk_setrate(jz_findclk(s->soc, "pll_divider"), 1, 1);
186 else
187 jz_clk_setrate(jz_findclk(s->soc, "pll_divider"), 2, 1);
190 ldiv = (new_value & CPM_CPCCR_LDIV_MASK) >> CPM_CPCCR_LDIV_BIT;
191 ldiv++;
193 mdiv = div_table[(new_value & CPM_CPCCR_MDIV_MASK) >> CPM_CPCCR_MDIV_BIT];
194 pdiv = div_table[(new_value & CPM_CPCCR_PDIV_MASK) >> CPM_CPCCR_PDIV_BIT];
195 hdiv = div_table[(new_value & CPM_CPCCR_HDIV_MASK) >> CPM_CPCCR_HDIV_BIT];
196 cdiv = div_table[(new_value & CPM_CPCCR_CDIV_MASK) >> CPM_CPCCR_CDIV_BIT];
197 udiv = div_table[(new_value & CPM_CPCCR_UDIV_MASK) >> CPM_CPCCR_UDIV_BIT];
199 jz_clk_setrate(jz_findclk(s->soc, "ldclk"), ldiv, 1);
200 jz_clk_setrate(jz_findclk(s->soc, "mclk"), mdiv, 1);
201 jz_clk_setrate(jz_findclk(s->soc, "pclk"), pdiv, 1);
202 jz_clk_setrate(jz_findclk(s->soc, "hclk"), hdiv, 1);
203 jz_clk_setrate(jz_findclk(s->soc, "cclk"), cdiv, 1);
204 jz_clk_setrate(jz_findclk(s->soc, "usbclk"), udiv, 1);
206 if (new_value & CPM_CPCCR_UCS)
207 jz_clk_reparent(jz_findclk(s->soc, "usbclk"),
208 jz_findclk(s->soc, "pll_divider"));
209 else
210 jz_clk_reparent(jz_findclk(s->soc, "usbclk"),
211 jz_findclk(s->soc, "osc_extal"));
213 if (new_value & CPM_CPCCR_I2CS)
214 jz_clk_reparent(jz_findclk(s->soc, "i2sclk"),
215 jz_findclk(s->soc, "pll_divider"));
216 else
217 jz_clk_reparent(jz_findclk(s->soc, "i2sclk"),
218 jz_findclk(s->soc, "osc_extal"));
220 s->cpccr = new_value;
222 debug_out(DEBUG_CPM, "write to cpccr 0x%x\n", new_value);
223 jz4740_dump_clocks(jz_findclk(s->soc, "osc_extal"));
227 static inline void jz4740_cppcr_update(struct jz4740_cpm_s *s,
228 uint32_t new_value)
230 uint32_t pllm, plln, pllod, pllbp, pllen;
231 uint32_t pll0[4] = {
232 1, 2, 2, 4
236 pllen = new_value & CPM_CPPCR_PLLEN;
237 pllbp = new_value & CPM_CPPCR_PLLBP;
238 if ((!pllen) || (pllen && pllbp))
240 jz_clk_setrate(jz_findclk(s->soc, "pll_output"), 1, 1);
241 debug_out(DEBUG_CPM, "pll is bypassed \n");
242 s->cppcr = new_value | CPM_CPPCR_PLLS;
243 return;
247 pllm = (new_value & CPM_CPPCR_PLLM_MASK) >> CPM_CPPCR_PLLM_BIT;
248 plln = (new_value & CPM_CPPCR_PLLN_MASK) >> CPM_CPPCR_PLLN_BIT;
249 pllod = (new_value & CPM_CPPCR_PLLOD_MASK) >> CPM_CPPCR_PLLOD_BIT;
250 jz_clk_setrate(jz_findclk(s->soc, "pll_output"), (plln + 2) * pll0[pllod],
251 pllm + 2);
253 s->cppcr = new_value;
255 debug_out(DEBUG_CPM, "write to cppcr 0x%x\n", new_value);
256 jz4740_dump_clocks(jz_findclk(s->soc, "osc_extal"));
260 static inline void jz4740_i2scdr_update(struct jz4740_cpm_s *s,
261 uint32_t new_value)
263 uint32_t i2scdr;
265 i2scdr = new_value & CPM_I2SCDR_I2SDIV_MASK;
266 if (unlikely(i2scdr == s->i2scdr))
267 return;
270 jz_clk_setrate(jz_findclk(s->soc, "i2sclk"), i2scdr + 1, 1);
272 s->i2scdr = i2scdr;
274 debug_out(DEBUG_CPM, "write to i2scdr 0x%x\n", new_value);
275 jz4740_dump_clocks(jz_findclk(s->soc, "osc_extal"));
279 static inline void jz4740_lpcdr_update(struct jz4740_cpm_s *s,
280 uint32_t new_value)
282 uint32_t ipcdr;
284 ipcdr = new_value & CPM_LPCDR_PIXDIV_MASK;
285 /*TODO: */
286 s->lpcdr = ipcdr;
289 static inline void jz4740_msccdr_update(struct jz4740_cpm_s *s,
290 uint32_t new_value)
292 uint32_t msccdr;
294 msccdr = new_value & CPM_MSCCDR_MSCDIV_MASK;
296 if (unlikely(msccdr == s->msccdr))
297 return;
300 jz_clk_setrate(jz_findclk(s->soc, "mscclk"), msccdr + 1, 1);
302 s->msccdr = msccdr;
304 debug_out(DEBUG_CPM, "write to msccdr 0x%x\n", new_value);
305 jz4740_dump_clocks(jz_findclk(s->soc, "osc_extal"));
309 static inline void jz4740_uhccdr_update(struct jz4740_cpm_s *s,
310 uint32_t new_value)
312 uint32_t uhccdr;
314 uhccdr = new_value & 0xf;
315 /*TODO: */
316 s->uhccdr = uhccdr;
319 static void jz4740_cpm_write(void *opaque, target_phys_addr_t addr,
320 uint32_t value)
322 struct jz4740_cpm_s *s = (struct jz4740_cpm_s *) opaque;
324 switch (addr)
326 case 0x0:
327 jz4740_cpccr_update(s, value);
328 break;
329 case 0x4:
330 s->lcr = value & 0xff;
331 break;
332 case 0x20:
333 s->clkgr = value & 0xffff;
334 break;
335 case 0x24:
336 s->scr = value & 0xffff;
337 break;
338 case 0x10:
339 jz4740_cppcr_update(s, value);
340 break;
341 case 0x60:
342 jz4740_i2scdr_update(s, value);
343 break;
344 case 0x64:
345 jz4740_lpcdr_update(s, value);
346 break;
347 case 0x68:
348 jz4740_msccdr_update(s, value);
349 break;
350 case 0x6c:
351 jz4740_uhccdr_update(s, value);
352 break;
353 case 0x70:
354 s->uhctst = value & 0x3f;
355 break;
356 case 0x74:
357 s->ssicdr = value & 0xf;
358 break;
359 default:
360 cpu_abort(s->soc->env,
361 "jz4740_cpm_write undefined addr " JZ_FMT_plx
362 " value %x \n", addr, value);
368 static uint32_t jz474_cpm_read(void *opaque, target_phys_addr_t addr)
370 struct jz4740_cpm_s *s = (struct jz4740_cpm_s *) opaque;
372 switch (addr)
374 case 0x0:
375 return s->cpccr;
376 case 0x4:
377 return s->lcr;
378 case 0x20:
379 return s->clkgr;
380 case 0x24:
381 return s->scr;
382 case 0x10:
383 return s->cppcr;
384 case 0x60:
385 return s->i2scdr;
386 case 0x64:
387 return s->lpcdr;
388 case 0x68:
389 return s->msccdr;
390 case 0x6c:
391 return s->uhccdr;
392 case 0x70:
393 return s->uhctst;
394 case 0x74:
395 return s->ssicdr;
396 default:
397 cpu_abort(s->soc->env,
398 "jz474_cpm_read undefined addr " JZ_FMT_plx " \n", addr);
405 static CPUReadMemoryFunc *jz4740_cpm_readfn[] = {
406 jz4740_badwidth_read32, jz4740_badwidth_read32, jz474_cpm_read,
409 static CPUWriteMemoryFunc *jz4740_cpm_writefn[] = {
410 jz4740_badwidth_write32, jz4740_badwidth_write32, jz4740_cpm_write,
413 static void jz4740_cpm_reset(struct jz4740_cpm_s *s)
415 s->cpccr = 0x42040000;
416 s->cppcr = 0x28080011;
417 s->i2scdr = 0x00000004;
418 s->lpcdr = 0x00000004;
419 s->msccdr = 0x00000004;
420 s->uhccdr = 0x00000004;
421 s->uhctst = 0x0;
422 s->ssicdr = 0x00000004;
424 s->lcr = 0xf8;
425 s->clkgr = 0x0;
426 s->scr = 0x1500;
429 static struct jz4740_cpm_s *jz4740_cpm_init(struct jz_state_s *soc)
431 int iomemtype;
432 struct jz4740_cpm_s *s = (struct jz4740_cpm_s *) qemu_mallocz(sizeof(*s));
433 s->base = JZ4740_PHYS_BASE(JZ4740_CPM_BASE);
434 s->soc = soc;
436 jz4740_cpm_reset(s);
438 iomemtype =
439 cpu_register_io_memory(0, jz4740_cpm_readfn, jz4740_cpm_writefn, s);
440 cpu_register_physical_memory(s->base, 0x00001000, iomemtype);
441 return s;
445 /* JZ4740 interrupt controller
446 * It issues INT2 to MIPS
448 struct jz4740_intc_s
450 qemu_irq parent_irq;
452 target_phys_addr_t base;
453 struct jz_state_s *soc;
455 uint32_t icsr;
456 uint32_t icmr;
457 uint32_t icmsr;
458 uint32_t icmcr;
459 uint32_t icpr;
462 static uint32_t jz4740_intc_read(void *opaque, target_phys_addr_t addr)
464 struct jz4740_intc_s *s = (struct jz4740_intc_s *) opaque;
466 switch (addr)
468 case 0x8:
469 case 0xc:
470 JZ4740_WO_REG(addr);
471 break;
472 case 0x0:
473 return s->icsr;
474 case 0x4:
475 return s->icmr;
476 case 0x10:
477 return s->icpr;
478 default:
479 cpu_abort(s->soc->env,
480 "jz4740_intc_read undefined addr " JZ_FMT_plx " \n", addr);
483 return (0);
486 static void jz4740_intc_write(void *opaque, target_phys_addr_t addr,
487 uint32_t value)
489 struct jz4740_intc_s *s = (struct jz4740_intc_s *) opaque;
491 switch (addr)
493 case 0x0:
494 JZ4740_RO_REG(addr);
495 break;
496 case 0x4:
497 s->icmr = value;
498 break;
499 case 0x8:
500 s->icmr |= value;
501 break;
502 case 0xc:
503 s->icmr &= ~value;
504 break;
505 case 0x10:
506 s->icpr &= ~value;
507 qemu_set_irq(s->parent_irq, 0);
508 break;
509 default:
510 cpu_abort(s->soc->env,
511 "jz4740_intc_write undefined addr " JZ_FMT_plx
512 " value %x \n", addr, value);
517 static CPUReadMemoryFunc *jz4740_intc_readfn[] = {
518 jz4740_badwidth_read32, jz4740_badwidth_read32, jz4740_intc_read,
521 static CPUWriteMemoryFunc *jz4740_intc_writefn[] = {
522 jz4740_badwidth_write32, jz4740_badwidth_write32, jz4740_intc_write,
525 static void jz4740_intc_reset(struct jz4740_intc_s *s)
527 s->icsr = 0x0;
528 s->icmr = 0xffffffff;
529 s->icpr = 0x0;
532 static void jz4740_set_irq(void *opaque, int irq, int level)
534 struct jz4740_intc_s *s = (struct jz4740_intc_s *) opaque;
535 uint32_t irq_mask = 1 << irq;
538 if (level)
540 s->icsr |= irq_mask;
541 s->icpr &= ~irq_mask;
542 if (!(s->icmr & irq_mask))
544 s->icpr |= irq_mask;
545 qemu_set_irq(s->parent_irq, 1);
551 static qemu_irq *jz4740_intc_init(struct jz_state_s *soc, qemu_irq parent_irq)
553 int iomemtype;
554 struct jz4740_intc_s *s = (struct jz4740_intc_s *) qemu_mallocz(sizeof(*s));
555 s->base = JZ4740_PHYS_BASE(JZ4740_INTC_BASE);
556 s->parent_irq = parent_irq;
557 s->soc = soc;
559 jz4740_intc_reset(s);
561 iomemtype =
562 cpu_register_io_memory(0, jz4740_intc_readfn, jz4740_intc_writefn, s);
563 cpu_register_physical_memory(s->base, 0x00001000, iomemtype);
564 return qemu_allocate_irqs(jz4740_set_irq, s, 32);
567 /*external memory controller*/
568 struct jz4740_emc_s
570 qemu_irq irq;
571 target_phys_addr_t base;
572 struct jz_state_s *soc;
574 uint32_t bcr;
575 uint32_t smcr1; /*0x13010014 */
576 uint32_t smcr2; /*0x13010018 */
577 uint32_t smcr3; /*0x1301001c */
578 uint32_t smcr4; /*0x13010020 */
579 uint32_t sacr1; /*0x13010034 */
580 uint32_t sacr2; /*0x13010038 */
581 uint32_t sacr3; /*0x1301003c */
582 uint32_t sacr4; /*0x13010040 */
584 uint32_t nfcsr; /*0x13010050 */
585 uint32_t nfeccr; /*0x13010100 */
586 uint32_t nfecc; /*0x13010104 */
587 uint32_t nfpar0; /*0x13010108 */
588 uint32_t nfpar1; /*0x1301010c */
589 uint32_t nfpar2; /*0x13010110 */
590 uint32_t nfints; /*0x13010114 */
591 uint32_t nfinte; /*0x13010118 */
592 uint32_t nferr0; /*0x1301011c */
593 uint32_t nferr1; /*0x13010120 */
594 uint32_t nferr2; /*0x13010124 */
595 uint32_t nferr3; /*0x13010128 */
597 uint32_t dmcr; /*0x13010080 */
598 uint32_t rtcsr; /*0x13010084 */
599 uint32_t rtcnt; /*0x13010088 */
600 uint32_t rtcor; /*0x1301008c */
601 uint32_t dmar; /*0x13010090 */
602 uint32_t sdmr; /*0x1301a000 */
607 static void jz4740_emc_reset(struct jz4740_emc_s *s)
609 s->smcr1 = 0xfff7700;
610 s->smcr2 = 0xfff7700;
611 s->smcr3 = 0xfff7700;
612 s->smcr4 = 0xfff7700;
613 s->sacr1 = 0x18fc;
614 s->sacr2 = 0x16fe;
615 s->sacr3 = 0x14fe;
616 s->sacr4 = 0xcfc;
618 s->nfcsr = 0x0;
619 s->nfeccr = 0x0;
620 s->nfecc = 0x0;
621 s->nfpar0 = 0x0;
622 s->nfpar1 = 0x0;
623 s->nfpar2 = 0x0;
624 s->nfints = 0x0;
625 s->nfinte = 0x0;
626 s->nferr0 = 0x0;
627 s->nferr1 = 0x0;
628 s->nferr2 = 0x0;
629 s->nferr3 = 0x0;
631 s->dmcr = 0x0;
632 s->rtcsr = 0x0;
633 s->rtcnt = 0x0;
634 s->rtcor = 0x0;
635 s->dmar = 0x20f8;
636 s->sdmr = 0x0;
640 static uint32_t jz4740_emc_read8(void *opaque, target_phys_addr_t addr)
642 struct jz4740_emc_s *s = (struct jz4740_emc_s *) opaque;
644 switch (addr)
646 case 0x108:
647 case 0x109:
648 case 0x10a:
649 case 0x10b:
650 return (s->nfpar0 >> ((addr - 0x108) * 8)) & 0xff;
651 case 0x10c:
652 case 0x10d:
653 case 0x10e:
654 case 0x10f:
655 return (s->nfpar1 >> ((addr - 0x10c) * 8)) & 0xff;
656 case 0x110:
657 case 0x111:
658 case 0x112:
659 case 0x113:
660 return (s->nfpar2 >> ((addr - 0x110) * 8)) & 0xff;
661 case 0xa000:
662 case 0xa001:
663 case 0xa002:
664 case 0xa003:
665 return (s->sdmr >> ((addr - 0xa000) * 8)) & 0xff;
666 default:
667 cpu_abort(s->soc->env,
668 "jz4740_emc_read8 undefined addr " JZ_FMT_plx " \n", addr);
672 return (0);
675 static uint32_t jz4740_emc_read16(void *opaque, target_phys_addr_t addr)
677 struct jz4740_emc_s *s = (struct jz4740_emc_s *) opaque;
679 switch (addr)
681 case 0x108:
682 case 0x10a:
683 return (s->nfpar0 >> ((addr - 0x108) * 8)) & 0xffff;
684 case 0x10c:
685 case 0x10e:
686 return (s->nfpar1 >> ((addr - 0x10c) * 8)) & 0xffff;
687 case 0x110:
688 case 0x112:
689 return (s->nfpar2 >> ((addr - 0x110) * 8)) & 0xffff;
690 case 0x11c:
691 case 0x11e:
692 return (s->nferr0 >> ((addr - 0x11c) * 8)) & 0xffff;
693 case 0x120:
694 case 0x122:
695 return (s->nferr1 >> ((addr - 0x120) * 8)) & 0xffff;
696 case 0x124:
697 case 0x126:
698 return (s->nferr2 >> ((addr - 0x124) * 8)) & 0xffff;
699 case 0x128:
700 case 0x12a:
701 return (s->nferr3 >> ((addr - 0x128) * 8)) & 0xffff;
702 default:
703 cpu_abort(s->soc->env,
704 "jz4740_emc_read16 undefined addr " JZ_FMT_plx " \n", addr);
706 return (0);
709 static uint32_t jz4740_emc_read32(void *opaque, target_phys_addr_t addr)
711 struct jz4740_emc_s *s = (struct jz4740_emc_s *) opaque;
713 switch (addr)
715 case 0x0:
716 return s->bcr;
717 case 0x14:
718 return s->smcr1;
719 case 0x18:
720 return s->smcr2;
721 case 0x1c:
722 return s->smcr3;
723 case 0x20:
724 return s->smcr4;
725 case 0x34:
726 return s->sacr1;
727 case 0x38:
728 return s->sacr2;
729 case 0x3c:
730 return s->sacr3;
731 case 0x40:
732 return s->sacr4;
733 case 0x50:
734 return s->nfcsr;
735 case 0x100:
736 return s->nfeccr;
737 case 0x104:
738 return s->nfecc;
739 case 0x108:
740 return s->nfpar0;
741 case 0x10c:
742 return s->nfpar1;
743 case 0x110:
744 return s->nfpar2;
745 case 0x114:
746 return s->nfints;
747 case 0x118:
748 return s->nfinte;
749 case 0x11c:
750 return s->nferr0;
751 case 0x120:
752 return s->nferr1;
753 case 0x124:
754 return s->nferr2;
755 case 0x128:
756 return s->nferr3;
757 case 0x80:
758 return s->dmcr;
759 case 0x90:
760 return s->dmar;
761 default:
762 cpu_abort(s->soc->env,
763 "jz4740_emc_read32 undefined addr " JZ_FMT_plx " \n", addr);
765 return (0);
768 static void jz4740_emc_write8(void *opaque, target_phys_addr_t addr,
769 uint32_t value)
771 struct jz4740_emc_s *s = (struct jz4740_emc_s *) opaque;
773 debug_out(DEBUG_EMC, "jz4740_emc_write8 addr %x value %x\n", addr, value);
775 switch (addr)
777 case 0x108:
778 case 0x109:
779 case 0x10a:
780 case 0x10b:
781 s->nfpar0 |= (value & 0xff) << ((addr - 0x108) * 8);
782 break;
783 case 0x10c:
784 case 0x10d:
785 case 0x10e:
786 case 0x10f:
787 s->nfpar1 |= (value & 0xff) << ((addr - 0x10c) * 8);
788 break;
789 case 0x110:
790 case 0x111:
791 case 0x112:
792 case 0x113:
793 s->nfpar2 |= (value & 0xff) << ((addr - 0x110) * 8);
794 break;
795 case 0xa000 ... 0xa3ff:
796 break;
797 default:
798 cpu_abort(s->soc->env,
799 "jz4740_emc_write8 undefined addr " JZ_FMT_plx
800 " value %x \n", addr, value);
803 static void jz4740_emc_write16(void *opaque, target_phys_addr_t addr,
804 uint32_t value)
806 struct jz4740_emc_s *s = (struct jz4740_emc_s *) opaque;
808 debug_out(DEBUG_EMC, "jz4740_emc_write16 addr %x value %x\n", addr, value);
809 switch (addr)
811 case 0x108:
812 case 0x10a:
813 s->nfpar0 |= (value & 0xffff) << ((addr - 0x108) * 8);
814 break;
815 case 0x10c:
816 case 0x10e:
817 s->nfpar1 |= (value & 0xffff) << ((addr - 0x10c) * 8);
818 break;
819 case 0x110:
820 case 0x112:
821 s->nfpar2 |= (value & 0xffff) << ((addr - 0x110) * 8);
822 break;
823 case 0x84:
824 case 0x86:
825 s->rtcsr |= (value & 0xffff) << ((addr - 0x84) * 8);
826 break;
827 case 0x88:
828 case 0x8a:
829 s->rtcnt |= (value & 0xffff) << ((addr - 0x88) * 8);
830 break;
831 case 0x8c:
832 s->rtcor |= (value & 0xffff) << ((addr - 0x8c) * 8);
833 break;
834 default:
835 cpu_abort(s->soc->env,
836 "jz4740_emc_write16 undefined addr " JZ_FMT_plx
837 " value %x \n", addr, value);
841 static void jz4740_emc_upate_interrupt(struct jz4740_emc_s *s)
843 qemu_set_irq(s->irq, s->nfints & s->nfinte);
846 static void jz4740_emc_write32(void *opaque, target_phys_addr_t addr,
847 uint32_t value)
849 struct jz4740_emc_s *s = (struct jz4740_emc_s *) opaque;
851 debug_out(DEBUG_EMC, "jz4740_emc_write32 addr %x value %x\n", addr, value);
852 switch (addr)
854 case 0x104:
855 case 0x11c:
856 case 0x120:
857 case 0x124:
858 case 0x128:
859 JZ4740_RO_REG(addr);
860 break;
861 case 0x0:
862 s->bcr = value;
863 break;
864 case 0x14:
865 s->smcr1 = value & 0xfff77cf;
866 break;
867 case 0x18:
868 s->smcr2 = value & 0xfff77cf;
869 break;
870 case 0x1c:
871 s->smcr3 = value & 0xfff77cf;
872 break;
873 case 0x20:
874 s->smcr4 = value & 0xfff77cf;
875 break;
876 case 0x34:
877 s->sacr1 = value & 0xffff;
878 break;
879 case 0x38:
880 s->sacr2 = value & 0xffff;
881 break;
882 case 0x3c:
883 s->sacr3 = value & 0xffff;
884 break;
885 case 0x40:
886 s->sacr4 = value & 0xffff;
887 break;
888 case 0x50:
889 s->nfcsr = value & 0xffff;
890 break;
891 case 0x100:
892 s->nfeccr = value & 0x1f;
893 if (s->nfeccr & 0x2)
895 s->nfecc = 0x0;
896 s->nfpar0 = 0x0;
897 s->nfpar1 = 0x0;
898 s->nfpar2 = 0x0;
899 s->nfints = 0x0;
900 s->nfinte = 0x0;
901 s->nferr0 = 0x0;
902 s->nferr1 = 0x0;
903 s->nferr2 = 0x0;
904 s->nferr3 = 0x0;
906 /*RS*/
907 /*TODO: Real RS error correction */
908 if (s->nfeccr & 0x4)
910 if ((s->nfeccr & 0x10) && (!(s->nfeccr & 0x8)))
912 /*decode */
913 s->nfints = 0x8;
914 s->nferr0 = 0x0;
915 s->nferr1 = 0x0;
916 s->nferr2 = 0x0;
918 if (s->nfeccr & 0x8)
920 /*encoding */
921 s->nfints = 0x4;
922 s->nfpar0 = 0xffffffff; /*fake value. for debug */
923 s->nfpar1 = 0xffffffff; /*fake value */
924 s->nfpar2 = 0xff; /*fake value */
927 else
929 s->nfecc = 0xffffff;
931 jz4740_emc_upate_interrupt(s);
932 break;
933 case 0x108:
934 s->nfpar0 = value;
935 break;
936 case 0x10c:
937 s->nfpar1 = value;
938 break;
939 case 0x110:
940 s->nfpar2 = value & 0xff;
941 break;
942 case 0x114:
943 s->nfints = value & 0x1fffffff;
944 jz4740_emc_upate_interrupt(s);
945 break;
946 case 0x118:
947 s->nfinte = value & 0x1f;
948 jz4740_emc_upate_interrupt(s);
949 break;
950 case 0x080:
951 s->dmcr = value & 0x9fbeff7f;
952 break;
953 case 0x90:
954 s->dmar = value & 0xffff;
955 break;
956 default:
957 cpu_abort(s->soc->env,
958 "jz4740_emc_write32 undefined addr " JZ_FMT_plx
959 " value %x \n", addr, value);
965 static CPUReadMemoryFunc *jz4740_emc_readfn[] = {
966 jz4740_emc_read8, jz4740_emc_read16, jz4740_emc_read32,
969 static CPUWriteMemoryFunc *jz4740_emc_writefn[] = {
970 jz4740_emc_write8, jz4740_emc_write16, jz4740_emc_write32,
974 static struct jz4740_emc_s *jz4740_emc_init(struct jz_state_s *soc,
975 qemu_irq irq)
977 int iomemtype;
978 struct jz4740_emc_s *s = (struct jz4740_emc_s *) qemu_mallocz(sizeof(*s));
979 s->base = JZ4740_PHYS_BASE(JZ4740_EMC_BASE);
980 s->soc = soc;
981 s->irq = irq;
983 jz4740_emc_reset(s);
985 iomemtype =
986 cpu_register_io_memory(0, jz4740_emc_readfn, jz4740_emc_writefn, s);
987 cpu_register_physical_memory(s->base, 0x00010000, iomemtype);
988 return s;
992 struct jz4740_gpio_s
994 qemu_irq irq;
995 target_phys_addr_t base;
996 struct jz_state_s *soc;
998 uint32_t papin[4];
999 uint32_t padat[4];
1000 uint32_t paim[4];
1001 uint32_t pape[4];
1002 uint32_t pafun[4];
1003 uint32_t pasel[4];
1004 uint32_t padir[4];
1005 uint32_t patrg[4];
1006 uint32_t paflg[4];
1009 static void jz4740_gpio_reset(struct jz4740_gpio_s *s)
1011 memset(s->papin, 0x0, sizeof(s->papin));
1012 memset(s->padat, 0x0, sizeof(s->padat));
1013 memset(s->paim, 0xffffffff, sizeof(s->paim));
1014 memset(s->pape, 0x0, sizeof(s->pape));
1015 memset(s->pafun, 0x0, sizeof(s->pafun));
1016 memset(s->pasel, 0x0, sizeof(s->pasel));
1017 memset(s->padir, 0x0, sizeof(s->padir));
1018 memset(s->patrg, 0x0, sizeof(s->patrg));
1019 memset(s->paflg, 0x0, sizeof(s->paflg));
1022 static uint32_t jz4740_gpio_read(void *opaque, target_phys_addr_t addr)
1024 struct jz4740_gpio_s *s = (struct jz4740_gpio_s *) opaque;
1025 uint32_t group;
1026 debug_out(DEBUG_GPIO, "jz4740_gpio_read addr %x\n", addr);
1028 switch (addr)
1030 case 0x14:
1031 case 0x114:
1032 case 0x214:
1033 case 0x314:
1034 case 0x18:
1035 case 0x118:
1036 case 0x218:
1037 case 0x318:
1038 case 0x24:
1039 case 0x124:
1040 case 0x224:
1041 case 0x324:
1042 case 0x28:
1043 case 0x128:
1044 case 0x228:
1045 case 0x328:
1046 case 0x34:
1047 case 0x134:
1048 case 0x234:
1049 case 0x334:
1050 case 0x38:
1051 case 0x138:
1052 case 0x238:
1053 case 0x338:
1054 case 0x44:
1055 case 0x144:
1056 case 0x244:
1057 case 0x344:
1058 case 0x48:
1059 case 0x148:
1060 case 0x248:
1061 case 0x348:
1062 case 0x54:
1063 case 0x154:
1064 case 0x254:
1065 case 0x354:
1066 case 0x58:
1067 case 0x158:
1068 case 0x258:
1069 case 0x358:
1070 case 0x64:
1071 case 0x164:
1072 case 0x264:
1073 case 0x364:
1074 case 0x68:
1075 case 0x168:
1076 case 0x268:
1077 case 0x368:
1078 case 0x74:
1079 case 0x174:
1080 case 0x274:
1081 case 0x374:
1082 case 0x78:
1083 case 0x178:
1084 case 0x278:
1085 case 0x378:
1086 case 0x84:
1087 case 0x184:
1088 case 0x284:
1089 case 0x384:
1090 JZ4740_WO_REG(addr);
1091 break;
1093 case 0x0:
1094 case 0x100:
1095 case 0x200:
1096 case 0x300:
1097 group = (addr - 0x0) / 0x100;
1098 if (addr == 0x200)
1100 /*GPIO(C) PIN 30 -> NAND FLASH R/B. */
1101 /*FOR NAND FLASH.PIN 30 ----|_____|------ */
1102 s->papin[2] &= 0x40000000;
1103 if (s->papin[2])
1104 s->papin[2] &= ~0x40000000;
1105 else
1106 s->papin[2] |= 0x40000000;
1108 return s->papin[group];
1109 case 0x10:
1110 case 0x110:
1111 case 0x210:
1112 case 0x310:
1113 group = (addr - 0x10) / 0x100;
1114 return s->padat[group];
1115 case 0x20:
1116 case 0x120:
1117 case 0x220:
1118 case 0x320:
1119 group = (addr - 0x20) / 0x100;
1120 return s->paim[group];
1121 case 0x30:
1122 case 0x130:
1123 case 0x230:
1124 case 0x330:
1125 group = (addr - 0x30) / 0x100;
1126 return s->pape[group];
1127 case 0x40:
1128 case 0x140:
1129 case 0x240:
1130 case 0x340:
1131 group = (addr - 0x40) / 0x100;
1132 return s->pafun[group];
1133 case 0x50:
1134 case 0x150:
1135 case 0x250:
1136 case 0x350:
1137 group = (addr - 0x50) / 0x100;
1138 return s->pasel[group];
1139 case 0x60:
1140 case 0x160:
1141 case 0x260:
1142 case 0x360:
1143 group = (addr - 0x60) / 0x100;
1144 return s->padir[group];
1145 case 0x70:
1146 case 0x170:
1147 case 0x270:
1148 case 0x370:
1149 group = (addr - 0x70) / 0x100;
1150 return s->patrg[group];
1151 case 0x80:
1152 case 0x180:
1153 case 0x280:
1154 case 0x380:
1155 group = (addr - 0x80) / 0x100;
1156 return s->paflg[group];
1157 default:
1158 cpu_abort(s->soc->env,
1159 "jz4740_gpio_read undefined addr " JZ_FMT_plx " \n", addr);
1161 return (0);
1164 static void jz4740_gpio_write(void *opaque, target_phys_addr_t addr,
1165 uint32_t value)
1167 struct jz4740_gpio_s *s = (struct jz4740_gpio_s *) opaque;
1168 uint32_t group;
1170 debug_out(DEBUG_GPIO, "jz4740_gpio_write addr %x value %x\n", addr, value);
1172 switch (addr)
1174 case 0x0:
1175 case 0x100:
1176 case 0x200:
1177 case 0x300:
1178 case 0x10:
1179 case 0x110:
1180 case 0x210:
1181 case 0x310:
1182 case 0x20:
1183 case 0x120:
1184 case 0x220:
1185 case 0x320:
1186 case 0x30:
1187 case 0x130:
1188 case 0x230:
1189 case 0x330:
1190 case 0x40:
1191 case 0x140:
1192 case 0x240:
1193 case 0x340:
1194 case 0x50:
1195 case 0x150:
1196 case 0x250:
1197 case 0x350:
1198 case 0x60:
1199 case 0x160:
1200 case 0x260:
1201 case 0x360:
1202 case 0x70:
1203 case 0x170:
1204 case 0x270:
1205 case 0x370:
1206 case 0x80:
1207 case 0x180:
1208 case 0x280:
1209 case 0x380:
1210 JZ4740_RO_REG(addr);
1211 break;
1212 case 0x14:
1213 case 0x114:
1214 case 0x214:
1215 case 0x314:
1216 group = (addr - 0x14) / 0x100;
1217 s->padat[group] = value;
1218 break;
1219 case 0x18:
1220 case 0x118:
1221 case 0x218:
1222 case 0x318:
1223 group = (addr - 0x18) / 0x100;
1224 s->padat[group] &= ~value;
1225 break;
1226 case 0x24:
1227 case 0x124:
1228 case 0x224:
1229 case 0x324:
1230 group = (addr - 0x24) / 0x100;
1231 s->paim[group] = value;
1232 break;
1233 case 0x28:
1234 case 0x128:
1235 case 0x228:
1236 case 0x328:
1237 group = (addr - 0x28) / 0x100;
1238 s->paim[group] &= ~value;
1239 break;
1240 case 0x34:
1241 case 0x134:
1242 case 0x234:
1243 case 0x334:
1244 group = (addr - 0x34) / 0x100;
1245 s->pape[group] = value;
1246 break;
1247 case 0x38:
1248 case 0x138:
1249 case 0x238:
1250 case 0x338:
1251 group = (addr - 0x38) / 0x100;
1252 s->pape[group] &= ~value;
1253 break;
1254 case 0x44:
1255 case 0x144:
1256 case 0x244:
1257 case 0x344:
1258 group = (addr - 0x44) / 0x100;
1259 s->pafun[group] = value;
1260 break;
1261 case 0x48:
1262 case 0x148:
1263 case 0x248:
1264 case 0x348:
1265 group = (addr - 0x48) / 0x100;
1266 s->pafun[group] &= ~value;
1267 break;
1268 case 0x54:
1269 case 0x154:
1270 case 0x254:
1271 case 0x354:
1272 group = (addr - 0x54) / 0x100;
1273 s->pasel[group] = value;
1274 break;
1275 case 0x58:
1276 case 0x158:
1277 case 0x258:
1278 case 0x358:
1279 group = (addr - 0x58) / 0x100;
1280 s->pasel[group] &= ~value;
1281 break;
1282 case 0x64:
1283 case 0x164:
1284 case 0x264:
1285 case 0x364:
1286 group = (addr - 0x64) / 0x100;
1287 s->padir[group] = value;
1288 break;
1289 case 0x68:
1290 case 0x168:
1291 case 0x268:
1292 case 0x368:
1293 group = (addr - 0x68) / 0x100;
1294 s->padir[group] &= ~value;
1295 break;
1296 case 0x74:
1297 case 0x174:
1298 case 0x274:
1299 case 0x374:
1300 group = (addr - 0x74) / 0x100;
1301 s->patrg[group] = value;
1302 break;
1303 case 0x78:
1304 case 0x178:
1305 case 0x278:
1306 case 0x378:
1307 group = (addr - 0x78) / 0x100;
1308 s->patrg[group] &= ~value;
1309 break;
1310 case 0x84:
1311 case 0x184:
1312 case 0x284:
1313 case 0x384:
1314 group = (addr - 0x74) / 0x100;
1315 s->paflg[group] &= ~value;
1316 break;
1317 default:
1318 cpu_abort(s->soc->env,
1319 "jz4740_gpio_write undefined addr " JZ_FMT_plx
1320 " value %x \n", addr, value);
1328 static CPUReadMemoryFunc *jz4740_gpio_readfn[] = {
1329 jz4740_badwidth_read32, jz4740_badwidth_read32, jz4740_gpio_read,
1332 static CPUWriteMemoryFunc *jz4740_gpio_writefn[] = {
1333 jz4740_badwidth_write32, jz4740_badwidth_write32, jz4740_gpio_write,
1336 static struct jz4740_gpio_s *jz4740_gpio_init(struct jz_state_s *soc,
1337 qemu_irq irq)
1339 int iomemtype;
1340 struct jz4740_gpio_s *s = (struct jz4740_gpio_s *) qemu_mallocz(sizeof(*s));
1341 s->base = JZ4740_PHYS_BASE(JZ4740_GPIO_BASE);
1342 s->soc = soc;
1343 s->irq = irq;
1345 jz4740_gpio_reset(s);
1347 iomemtype =
1348 cpu_register_io_memory(0, jz4740_gpio_readfn, jz4740_gpio_writefn, s);
1349 cpu_register_physical_memory(s->base, 0x00010000, iomemtype);
1350 return s;
1354 struct jz4740_rtc_s
1356 qemu_irq irq;
1357 target_phys_addr_t base;
1358 struct jz_state_s *soc;
1360 QEMUTimer *hz_tm;
1361 //struct tm tm;
1362 //int sec_offset;
1363 int64_t next;
1365 uint32_t rtccr;
1366 uint32_t rtcsr;
1367 uint32_t rtcsar;
1368 uint32_t rtcgr;
1370 uint32_t hcr;
1371 uint32_t hwfcr;
1372 uint32_t hrcr;
1373 uint32_t hwcr;
1374 uint32_t hwrsr;
1375 uint32_t hspr;
1380 static void jz4740_rtc_update_interrupt(struct jz4740_rtc_s *s)
1382 if (((s->rtcsr & 0x40) && (s->rtcsr & 0x20))
1383 || ((s->rtcsr & 0x10) && (s->rtcsr & 0x8)))
1384 qemu_set_irq(s->irq, 1);
1385 else
1386 qemu_set_irq(s->irq, 0);
1389 static inline void jz4740_rtc_start(struct jz4740_rtc_s *s)
1391 s->next = +qemu_get_clock(rt_clock);
1392 qemu_mod_timer(s->hz_tm, s->next);
1395 static inline void jz4740_rtc_stop(struct jz4740_rtc_s *s)
1397 qemu_del_timer(s->hz_tm);
1398 s->next = -qemu_get_clock(rt_clock);
1399 if (s->next < 1)
1400 s->next = 1;
1403 static void jz4740_rtc_hz(void *opaque)
1405 struct jz4740_rtc_s *s = (struct jz4740_rtc_s *) opaque;
1407 s->next += 1000;
1408 qemu_mod_timer(s->hz_tm, s->next);
1409 if (s->rtccr & 0x1)
1411 s->rtcsr++;
1412 s->rtccr |= 0x40;
1413 if (s->rtcsr & 0x4)
1415 if (s->rtcsr == s->rtcsar)
1416 s->rtccr |= 0x10;
1418 jz4740_rtc_update_interrupt(s);
1422 static void jz4740_rtc_reset(struct jz4740_rtc_s *s)
1424 s->rtccr = 0x81;
1426 s->next = 1000;
1428 /*Maybe rtcsr need to be saved to file */
1429 s->rtcsr = 0;
1430 //s->sec_offset = 0;
1431 //qemu_get_timedate(&s->tm, s->sec_offset);
1432 jz4740_rtc_start(s);
1436 static uint32_t jz4740_rtc_read(void *opaque, target_phys_addr_t addr)
1438 struct jz4740_rtc_s *s = (struct jz4740_rtc_s *) opaque;
1440 debug_out(DEBUG_RTC, "jz4740_rtc_read addr %x\n", addr);
1441 switch (addr)
1443 case 0x0:
1444 return s->rtccr | 0x80;
1445 case 0x4:
1446 return s->rtcsr;
1447 case 0x8:
1448 return s->rtcsar;
1449 case 0xc:
1450 return s->rtcgr;
1451 case 0x20:
1452 return s->hcr;
1453 case 0x24:
1454 return s->hwfcr;
1455 case 0x28:
1456 return s->hrcr;
1457 case 0x2c:
1458 return s->hwcr;
1459 case 0x30:
1460 return s->hwrsr;
1461 case 0x34:
1462 return s->hspr;
1463 default:
1464 cpu_abort(s->soc->env,
1465 "jz4740_rtc_read undefined addr " JZ_FMT_plx "\n", addr);
1468 return (0);
1471 static void jz4740_rtc_write(void *opaque, target_phys_addr_t addr,
1472 uint32_t value)
1474 struct jz4740_rtc_s *s = (struct jz4740_rtc_s *) opaque;
1476 debug_out(DEBUG_RTC, "jz4740_rtc_write addr %x value %x\n", addr, value);
1478 switch (addr)
1480 case 0x0:
1481 s->rtccr = value & 0x2d;
1482 if (!value & 0x40)
1483 s->rtccr &= ~0x40;
1484 if (!value & 0x10)
1485 s->rtccr &= ~0x10;
1486 if (s->rtccr & 0x1)
1488 jz4740_rtc_start(s);
1489 jz4740_rtc_update_interrupt(s);
1491 break;
1492 case 0x4:
1493 s->rtcsr = value;
1494 //s->sec_offset = qemu_timedate_diff(&s->tm);
1495 break;
1496 case 0x8:
1497 s->rtcsar = value;
1498 break;
1499 case 0xc:
1500 s->rtcgr = value & 0x13ffffff;
1501 break;
1502 case 0x20:
1503 s->hcr = value & 0x1;
1504 break;
1505 case 0x24:
1506 s->hwfcr = value & 0xffe0;
1507 break;
1508 case 0x28:
1509 s->hrcr = value & 0xfe0;
1510 break;
1511 case 0x2c:
1512 s->hwcr = value & 0x1;
1513 break;
1514 case 0x30:
1515 s->hwrsr = value & 0x33;
1516 break;
1517 case 0x34:
1518 s->hspr = value;
1519 break;
1520 default:
1521 cpu_abort(s->soc->env,
1522 "jz4740_rtc_write undefined addr " JZ_FMT_plx
1523 " value %x \n", addr, value);
1528 static CPUReadMemoryFunc *jz4740_rtc_readfn[] = {
1529 jz4740_badwidth_read32, jz4740_badwidth_read32, jz4740_rtc_read,
1532 static CPUWriteMemoryFunc *jz4740_rtc_writefn[] = {
1533 jz4740_badwidth_write32, jz4740_badwidth_write32, jz4740_rtc_write,
1536 static struct jz4740_rtc_s *jz4740_rtc_init(struct jz_state_s *soc,
1537 qemu_irq irq)
1539 int iomemtype;
1540 struct jz4740_rtc_s *s = (struct jz4740_rtc_s *) qemu_mallocz(sizeof(*s));
1541 s->base = JZ4740_PHYS_BASE(JZ4740_RTC_BASE);
1542 s->soc = soc;
1543 s->irq = irq;
1545 s->hz_tm = qemu_new_timer(rt_clock, jz4740_rtc_hz, s);
1547 jz4740_rtc_reset(s);
1549 iomemtype =
1550 cpu_register_io_memory(0, jz4740_rtc_readfn, jz4740_rtc_writefn, s);
1551 cpu_register_physical_memory(s->base, 0x00001000, iomemtype);
1552 return s;
1555 struct jz4740_tcu_s
1557 qemu_irq tcu_irq0;
1558 qemu_irq tcu_irq1;
1559 qemu_irq tcu_irq2;
1561 target_phys_addr_t base;
1562 struct jz_state_s *soc;
1565 QEMUTimer *half_timer[8];
1566 QEMUTimer *full_timer[8];
1567 int64_t time[8];
1569 uint32_t tsr;
1570 uint32_t ter;
1571 uint32_t tfr;
1572 uint32_t tmr;
1574 uint32_t tdfr[8];
1575 uint32_t tdhr[8];
1576 uint32_t tcnt[8];
1577 uint32_t tcsr[8];
1579 uint32_t prescale[8];
1580 uint32_t freq[8];
1583 static void jz4740_tcu_update_interrupt(struct jz4740_tcu_s *s)
1585 //printf("s->tfr %x s->tmr %x \n",s->tfr,s->tmr);
1586 if (((s->tfr & 0x1) & (~(s->tmr & 0x1)))
1587 || ((s->tfr & 0x10000) & (~(s->tmr & 0x10000))))
1589 qemu_set_irq(s->tcu_irq0, 1);
1591 else
1592 qemu_set_irq(s->tcu_irq0, 0);
1593 #if 0
1594 if (((s->tfr & 0x2) & (~(s->tmr & 0x2)))
1595 || ((s->tfr & 0x20000) & (~(s->tmr & 0x20000))))
1597 qemu_set_irq(s->tcu_irq1, 1);
1599 else
1600 qemu_set_irq(s->tcu_irq1, 0);
1602 if (((s->tfr & 0xfc) & (~(s->tmr & 0xfc)))
1603 || ((s->tfr & 0xfc0000) & (~(s->tmr & 0xfc0000))))
1605 qemu_set_irq(s->tcu_irq2, 1);
1607 else
1608 qemu_set_irq(s->tcu_irq2, 0);
1609 #endif
1612 #undef TCU_INDEX
1613 #define TCU_INDEX 0
1614 #include "mips_jz_glue.h"
1615 #define TCU_INDEX 1
1616 #include "mips_jz_glue.h"
1617 #define TCU_INDEX 2
1618 #include "mips_jz_glue.h"
1619 #define TCU_INDEX 3
1620 #include "mips_jz_glue.h"
1621 #define TCU_INDEX 4
1622 #include "mips_jz_glue.h"
1623 #define TCU_INDEX 5
1624 #include "mips_jz_glue.h"
1625 #define TCU_INDEX 6
1626 #include "mips_jz_glue.h"
1627 #define TCU_INDEX 7
1628 #include "mips_jz_glue.h"
1629 #undef TCU_INDEX
1631 #define jz4740_tcu_start(s) do { \
1632 jz4740_tcu_start_half0(s); \
1633 jz4740_tcu_start_full0(s); \
1634 jz4740_tcu_start_half1(s); \
1635 jz4740_tcu_start_full1(s); \
1636 jz4740_tcu_start_half2(s); \
1637 jz4740_tcu_start_full2(s); \
1638 jz4740_tcu_start_half3(s); \
1639 jz4740_tcu_start_full3(s); \
1640 jz4740_tcu_start_half4(s); \
1641 jz4740_tcu_start_full4(s); \
1642 jz4740_tcu_start_half5(s); \
1643 jz4740_tcu_start_full5(s); \
1644 jz4740_tcu_start_half6(s); \
1645 jz4740_tcu_start_full6(s); \
1646 jz4740_tcu_start_half7(s); \
1647 jz4740_tcu_start_full7(s); \
1648 }while (0)
1650 static void jz4740_tcu_if_reset(struct jz4740_tcu_s *s)
1652 int i;
1654 s->tsr = 0x0;
1655 s->ter = 0x0;
1656 s->tfr = 0x0;
1657 s->tmr = 0x0;
1658 for (i = 0; i < 8; i++)
1660 s->tdfr[i] = 0xffff;
1661 s->tdhr[i] = 0x8000;
1662 s->tcnt[i] = 0x0;
1663 s->tcsr[i] = 0x0;
1664 s->half_timer[i] = NULL;
1665 s->full_timer[i] = NULL;
1669 static void jz4740_tcu_if_write8(void *opaque, target_phys_addr_t addr,
1670 uint32_t value)
1672 struct jz4740_tcu_s *s = (struct jz4740_tcu_s *) opaque;
1674 debug_out(DEBUG_TCU, "jz4740_tcu_if_write8 addr %x value %x\n", addr,
1675 value);
1677 switch (addr)
1679 case 0x14:
1680 s->ter |= (value & 0xff);
1681 jz4740_tcu_start(s);
1682 break;
1683 case 0x18:
1684 s->ter &= ~(value & 0xff);
1685 jz4740_tcu_start(s);
1686 break;
1687 default:
1688 cpu_abort(s->soc->env,
1689 "jz4740_tcu_if_write8 undefined addr " JZ_FMT_plx
1690 " value %x \n", addr, value);
1695 static void jz4740_tcu_if_write32(void *opaque, target_phys_addr_t addr,
1696 uint32_t value)
1698 struct jz4740_tcu_s *s = (struct jz4740_tcu_s *) opaque;
1700 debug_out(DEBUG_TCU, "jz4740_tcu_if_write32 addr %x value %x\n", addr,
1701 value);
1703 fprintf(fp, "jz4740_tcu_if_write32 addr %x value %x\n", addr,
1704 value);
1705 switch (addr)
1707 case 0x2c:
1708 s->tsr |= (value & 0x100ff);
1709 jz4740_tcu_start(s);
1710 break;
1711 case 0x3c:
1712 s->tsr &= ~(value & 0x100ff);
1713 jz4740_tcu_start(s);
1714 break;
1715 case 0x24:
1716 s->tfr |= (value & 0xff00ff);
1717 break;
1718 case 0x28:
1719 s->tfr &= ~(value & 0xff00ff);
1720 break;
1721 case 0x34:
1722 s->tmr |= (value & 0xff00ff);
1723 jz4740_tcu_update_interrupt(s);
1724 break;
1725 case 0x38:
1726 s->tmr &= ~(value & 0xff00ff);
1727 jz4740_tcu_update_interrupt(s);
1728 break;
1729 default:
1730 cpu_abort(s->soc->env,
1731 "jz4740_tcu_if_write32 undefined addr " JZ_FMT_plx
1732 " value %x \n", addr, value);
1737 static uint32_t jz4740_tcu_if_read8(void *opaque, target_phys_addr_t addr)
1739 struct jz4740_tcu_s *s = (struct jz4740_tcu_s *) opaque;
1741 debug_out(DEBUG_TCU, "jz4740_tcu_if_read8 addr %x\n", addr);
1743 switch (addr)
1745 case 0x10:
1746 return s->ter;
1747 default:
1748 cpu_abort(s->soc->env,
1749 "jz4740_tcu_if_read8 undefined addr " JZ_FMT_plx "\n", addr);
1751 return (0);
1754 static uint32_t jz4740_tcu_if_read32(void *opaque, target_phys_addr_t addr)
1756 struct jz4740_tcu_s *s = (struct jz4740_tcu_s *) opaque;
1758 debug_out(DEBUG_TCU, "jz4740_tcu_if_read32 addr %x\n", addr);
1760 switch (addr)
1762 case 0x1c:
1763 return s->tsr;
1764 case 0x20:
1765 return s->tfr;
1766 case 0x30:
1767 return s->tmr;
1768 default:
1769 cpu_abort(s->soc->env,
1770 "jz4740_tcu_if_read32 undefined addr " JZ_FMT_plx "\n", addr);
1773 return (0);
1777 static CPUReadMemoryFunc *jz4740_tcu_if_readfn[] = {
1778 jz4740_tcu_if_read8, jz4740_badwidth_read32, jz4740_tcu_if_read32,
1781 static CPUWriteMemoryFunc *jz4740_tcu_if_writefn[] = {
1782 jz4740_tcu_if_write8, jz4740_badwidth_write32, jz4740_tcu_if_write32,
1785 static struct jz4740_tcu_s *jz4740_tcu_if_init(struct jz_state_s *soc,
1786 qemu_irq tcu_irq0,
1787 qemu_irq tcu_irq1,
1788 qemu_irq tcu_irq2)
1790 int iomemtype;
1791 //int i;
1793 struct jz4740_tcu_s *s = (struct jz4740_tcu_s *) qemu_mallocz(sizeof(*s));
1794 s->base = JZ4740_PHYS_BASE(JZ4740_TCU_BASE);
1795 s->soc = soc;
1796 s->tcu_irq0 = tcu_irq0;
1797 s->tcu_irq1 = tcu_irq1;
1798 s->tcu_irq2 = tcu_irq2;
1800 jz4740_tcu_if_reset(s);
1802 iomemtype =
1803 cpu_register_io_memory(0, jz4740_tcu_if_readfn, jz4740_tcu_if_writefn,
1805 cpu_register_physical_memory(s->base, 0x00000040, iomemtype);
1806 return s;
1810 static void jz4740_tcu_init(struct jz_state_s *soc,
1811 struct jz4740_tcu_s *s, int timer_index)
1813 switch (timer_index)
1815 case 0x0:
1816 jz4740_tcu_init0(soc, s);
1817 break;
1818 case 0x1:
1819 jz4740_tcu_init1(soc, s);
1820 break;
1821 case 0x2:
1822 jz4740_tcu_init2(soc, s);
1823 break;
1824 case 0x3:
1825 jz4740_tcu_init3(soc, s);
1826 break;
1827 case 0x4:
1828 jz4740_tcu_init4(soc, s);
1829 break;
1830 case 0x5:
1831 jz4740_tcu_init5(soc, s);
1832 break;
1833 case 0x6:
1834 jz4740_tcu_init6(soc, s);
1835 break;
1836 case 0x7:
1837 jz4740_tcu_init7(soc, s);
1838 break;
1839 default:
1840 cpu_abort(s->soc->env,
1841 "jz4740_tcu_init undefined timer %x \n", timer_index);
1845 typedef void (*jz4740_lcd_fn_t) (uint8_t * d, const uint8_t * s, int width,
1846 const uint16_t * pal);
1847 struct jz_fb_descriptor
1849 uint32_t fdadr; /* Frame descriptor address register */
1850 uint32_t fsadr; /* Frame source address register */
1851 uint32_t fidr; /* Frame ID register */
1852 uint32_t ldcmd; /* Command register */
1855 struct jz4740_lcdc_s
1857 qemu_irq irq;
1859 target_phys_addr_t base;
1860 struct jz_state_s *soc;
1862 DisplayState *state;
1863 QEMUConsole *console;
1864 jz4740_lcd_fn_t *line_fn_tab;
1865 jz4740_lcd_fn_t line_fn;
1868 uint32_t lcdcfg;
1869 uint32_t lcdvsync;
1870 uint32_t lcdhsync;
1871 uint32_t lcdvat;
1872 uint32_t lcddah;
1873 uint32_t lcddav;
1874 uint32_t lcdps;
1875 uint32_t lcdcls;
1876 uint32_t lcdspl;
1877 uint32_t lcdrev;
1878 uint32_t lcdctrl;
1879 uint32_t lcdstate;
1880 uint32_t lcdiid;
1881 uint32_t lcdda0;
1882 uint32_t lcdsa0;
1883 uint32_t lcdfid0;
1884 uint32_t lcdcmd0;
1885 uint32_t lcdda1;
1886 uint32_t lcdsa1;
1887 uint32_t lcdfid1;
1888 uint32_t lcdcmd1;
1890 uint32_t ena;
1891 uint32_t dis;
1892 uint32_t width;
1893 uint32_t height;
1894 uint32_t bpp; /*bit per second */
1895 uint16_t palette[256];
1896 uint32_t invalidate;
1900 /*bit per pixel*/
1901 static const int jz4740_lcd_bpp[0x6] = {
1902 1, 2, 4, 8, 16, 32 /*4740 uses 32 bit for 24bpp */
1905 static void jz4740_lcdc_reset(struct jz4740_lcdc_s *s)
1910 static uint32_t jz4740_lcdc_read(void *opaque, target_phys_addr_t addr)
1912 struct jz4740_lcdc_s *s = (struct jz4740_lcdc_s *) opaque;
1914 debug_out(DEBUG_LCDC, "jz4740_lcdc_read addr %x \n", addr);
1915 switch (addr)
1917 case 0x0:
1918 return s->lcdcfg;
1919 case 0x4:
1920 return s->lcdvsync;
1921 case 0x8:
1922 return s->lcdhsync;
1923 case 0xc:
1924 return s->lcdvat;
1925 case 0x10:
1926 return s->lcddah;
1927 case 0x14:
1928 return s->lcddav;
1929 case 0x18:
1930 return s->lcdps;
1931 case 0x1c:
1932 return s->lcdcls;
1933 case 0x20:
1934 return s->lcdspl;
1935 case 0x24:
1936 return s->lcdrev;
1937 case 0x30:
1938 return s->lcdctrl;
1939 case 0x34:
1940 return s->lcdstate;
1941 case 0x38:
1942 return s->lcdiid;
1943 case 0x40:
1944 return s->lcdda0;
1945 case 0x44:
1946 return s->lcdsa0;
1947 case 0x48:
1948 return s->lcdfid0;
1949 case 0x4c:
1950 return s->lcdcmd0;
1951 case 0x50:
1952 return s->lcdda1;
1953 case 0x54:
1954 return s->lcdsa1;
1955 case 0x58:
1956 return s->lcdfid1;
1957 case 0x5c:
1958 return s->lcdcmd1;
1959 default:
1960 cpu_abort(s->soc->env,
1961 "jz4740_lcdc_read undefined addr " JZ_FMT_plx " \n", addr);
1967 static void jz4740_lcdc_write(void *opaque, target_phys_addr_t addr,
1968 uint32_t value)
1970 struct jz4740_lcdc_s *s = (struct jz4740_lcdc_s *) opaque;
1972 debug_out(DEBUG_LCDC, "jz4740_lcdc_write addr %x value %x\n", addr, value);
1974 switch (addr)
1976 case 0x44:
1977 case 0x48:
1978 case 0x4c:
1979 JZ4740_RO_REG(addr);
1980 break;
1981 case 0x0:
1982 s->lcdcfg = value & 0x80ffffbf;
1983 break;
1984 case 0x4:
1985 s->lcdvsync = value & 0x7ff07ff;
1986 break;
1987 case 0x8:
1988 s->lcdhsync = value & 0x7ff07ff;
1989 break;
1990 case 0xc:
1991 s->lcdvat = value & 0x7ff07ff;
1992 break;
1993 case 0x10:
1994 s->lcddah = value & 0x7ff07ff;
1995 s->width = (value & 0x7ff) - ((value >> 16) & 0x7ff);
1996 break;
1997 case 0x14:
1998 s->height = (value & 0x7ff) - ((value >> 16) & 0x7ff);
1999 s->lcddav = value & 0x7ff07ff;
2000 break;
2001 case 0x18:
2002 s->lcdps = value & 0x7ff07ff;
2003 break;
2004 case 0x1c:
2005 s->lcdcls = value & 0x7ff07ff;
2006 break;
2007 case 0x20:
2008 s->lcdspl = value & 0x7ff07ff;
2009 break;
2010 case 0x24:
2011 s->lcdrev = value & 0x7ff0000;
2012 break;
2013 case 0x30:
2014 s->lcdctrl = value & 0x3fff3fff;
2015 s->ena = (value & 0x8) >> 3;
2016 s->dis = (value & 0x10) >> 4;
2017 s->bpp = jz4740_lcd_bpp[value & 0x7];
2018 if ((s->bpp == 1))
2020 fprintf(stderr, "bpp =1 is not supported\n");
2021 exit(-1);
2023 s->line_fn = s->line_fn_tab[value & 0x7];
2024 break;
2025 case 0x34:
2026 s->lcdstate = value & 0xbf;
2027 break;
2028 case 0x38:
2029 s->lcdiid = value;
2030 break;
2031 case 0x40:
2032 s->lcdda0 = value;
2033 break;
2034 case 0x50:
2035 s->lcdda1 = value;
2036 break;
2037 default:
2038 cpu_abort(s->soc->env,
2039 "jz4740_lcdc_write undefined addr " JZ_FMT_plx " value %x \n",
2040 addr, value);
2045 static CPUReadMemoryFunc *jz4740_lcdc_readfn[] = {
2046 jz4740_badwidth_read32, jz4740_badwidth_read32, jz4740_lcdc_read,
2049 static CPUWriteMemoryFunc *jz4740_lcdc_writefn[] = {
2050 jz4740_badwidth_write32, jz4740_badwidth_write32, jz4740_lcdc_write,
2053 #include "pixel_ops.h"
2054 #define JZ4740_LCD_PANEL
2055 #define DEPTH 8
2056 #include "mips_jz_glue.h"
2057 #define DEPTH 15
2058 #include "mips_jz_glue.h"
2059 #define DEPTH 16
2060 #include "mips_jz_glue.h"
2061 #define DEPTH 24
2062 #include "mips_jz_glue.h"
2063 #define DEPTH 32
2064 #include "mips_jz_glue.h"
2065 #undef JZ4740_LCD_PANEL
2067 static void *jz4740_lcd_get_buffer(struct jz4740_lcdc_s *s,
2068 target_phys_addr_t addr)
2070 uint32_t pd;
2072 pd = cpu_get_physical_page_desc(addr);
2073 if ((pd & ~TARGET_PAGE_MASK) != IO_MEM_RAM)
2074 /* TODO */
2075 cpu_abort(cpu_single_env, "%s: framebuffer outside RAM!\n",
2076 __FUNCTION__);
2077 else
2078 return phys_ram_base +
2079 (pd & TARGET_PAGE_MASK) + (addr & ~TARGET_PAGE_MASK);
2082 static void jz4740_lcd_update_display(void *opaque)
2084 struct jz4740_lcdc_s *s = (struct jz4740_lcdc_s *) opaque;
2086 uint8_t *src, *dest;
2087 struct jz_fb_descriptor *fb_des;
2089 int step, linesize;
2090 int y;
2093 if (!s->ena)
2094 return;
2095 if (s->dis)
2096 return;
2098 if (!s->lcdda0)
2099 return;
2101 fb_des = (struct jz_fb_descriptor *) jz4740_lcd_get_buffer(s, s->lcdda0);
2102 s->lcdda0 = fb_des->fdadr;
2103 s->lcdsa0 = fb_des->fsadr;
2104 s->lcdfid0 = fb_des->fidr;
2105 s->lcdcmd0 = fb_des->ldcmd;
2107 src = (uint8_t *) jz4740_lcd_get_buffer(s, fb_des->fsadr);
2108 if (s->lcdcmd0 & (0x1 << 28))
2110 /*palette */
2111 memcpy(s->palette, src, sizeof(s->palette));
2112 return;
2115 /*frame buffer */
2117 if (s->width != ds_get_width(s->state) ||
2118 s->height != ds_get_height(s->state))
2120 qemu_console_resize(s->console, s->width, s->height);
2121 s->invalidate = 1;
2124 step = (s->width * s->bpp) >> 3;
2125 dest = ds_get_data(s->state);
2126 linesize = ds_get_linesize(s->state);
2128 //printf("s->width %d s->height %d s->bpp %d linesize %d \n",s->width,s->height ,s->bpp,linesize);
2130 for (y = 0; y < s->height; y++)
2132 s->line_fn(dest, src, s->width, s->palette);
2133 //memcpy(dest,src,step);
2134 src += step;
2135 dest += linesize;
2139 dpy_update(s->state, 0, 0, s->width, s->height);
2140 s->lcdstate |= 0x20;
2141 if ((s->lcdcmd0 & 0x40000000) && (!(s->lcdctrl & 0x2000)))
2142 qemu_set_irq(s->irq, 1);
2145 static inline void jz4740_lcd_invalidate_display(void *opaque)
2147 struct jz4740_lcdc_s *s = (struct jz4740_lcdc_s *) opaque;
2148 s->invalidate = 1;
2151 static struct jz4740_lcdc_s *jz4740_lcdc_init(struct jz_state_s *soc,
2152 qemu_irq irq, DisplayState * ds)
2154 int iomemtype;
2156 struct jz4740_lcdc_s *s = (struct jz4740_lcdc_s *) qemu_mallocz(sizeof(*s));
2157 s->base = JZ4740_PHYS_BASE(JZ4740_LCD_BASE);
2158 s->soc = soc;
2159 s->irq = irq;
2160 s->state = ds;
2163 jz4740_lcdc_reset(s);
2165 iomemtype =
2166 cpu_register_io_memory(0, jz4740_lcdc_readfn, jz4740_lcdc_writefn, s);
2167 cpu_register_physical_memory(s->base, 0x10000, iomemtype);
2169 s->console = graphic_console_init(s->state, jz4740_lcd_update_display,
2170 jz4740_lcd_invalidate_display,
2171 NULL, NULL, s);
2172 switch (ds_get_bits_per_pixel(s->state))
2174 case 0x0:
2175 s->line_fn_tab = qemu_mallocz(sizeof(jz4740_lcd_fn_t) * 6);
2176 break;
2177 case 8:
2178 s->line_fn_tab = jz4740_lcd_draw_fn_8;
2179 break;
2180 case 15:
2181 s->line_fn_tab = jz4740_lcd_draw_fn_15;
2182 break;
2183 case 16:
2184 s->line_fn_tab = jz4740_lcd_draw_fn_16;
2185 break;
2186 case 24:
2187 s->line_fn_tab = jz4740_lcd_draw_fn_24;
2188 break;
2189 case 32:
2190 s->line_fn_tab = jz4740_lcd_draw_fn_32;
2191 break;
2192 default:
2193 fprintf(stderr, "%s: Bad color depth\n", __FUNCTION__);
2194 exit(1);
2197 return s;
2201 #define JZ4740_DMA_NUM 6
2202 struct jz4740_dma_s
2204 qemu_irq irq;
2206 target_phys_addr_t base;
2207 struct jz_state_s *soc;
2209 uint32_t dmac;
2210 uint32_t dirqp;
2211 uint32_t ddr;
2212 uint32_t ddrs;
2214 uint32_t dsa[JZ4740_DMA_NUM];
2215 uint32_t dta[JZ4740_DMA_NUM];
2216 uint32_t dtc[JZ4740_DMA_NUM];
2217 uint32_t drs[JZ4740_DMA_NUM];
2218 uint32_t dcs[JZ4740_DMA_NUM];
2219 uint32_t dcm[JZ4740_DMA_NUM];
2220 uint32_t dda[JZ4740_DMA_NUM];
2224 struct jz4740_desc_s
2226 uint32_t dcmd; /* DCMD value for the current transfer */
2227 uint32_t dsadr; /* DSAR value for the current transfer */
2228 uint32_t dtadr; /* DTAR value for the current transfer */
2229 uint32_t ddadr; /* Points to the next descriptor + transfer count */
2232 static inline void jz4740_dma_transfer(struct jz4740_dma_s *s,
2233 target_phys_addr_t src,
2234 target_phys_addr_t dest, uint32_t len)
2236 uint32_t pd_src, pd_dest;
2237 uint8_t *sr, *de;
2239 pd_src = cpu_get_physical_page_desc(src);
2240 if ((pd_src & ~TARGET_PAGE_MASK) != IO_MEM_RAM)
2241 /* TODO */
2242 cpu_abort(cpu_single_env, "%s: DMA source address %x outside RAM!\n",
2243 __FUNCTION__, src);
2244 else
2245 sr = phys_ram_base +
2246 (pd_src & TARGET_PAGE_MASK) + (src & ~TARGET_PAGE_MASK);
2248 pd_dest = cpu_get_physical_page_desc(dest);
2249 if ((pd_dest & ~TARGET_PAGE_MASK) != IO_MEM_RAM)
2250 /* TODO */
2251 cpu_abort(cpu_single_env,
2252 "%s: DMA destination address %x outside RAM!\n",
2253 __FUNCTION__, dest);
2254 else
2255 de = phys_ram_base +
2256 (pd_dest & TARGET_PAGE_MASK) + (dest & ~TARGET_PAGE_MASK);
2258 memcpy(de, sr, len);
2261 static inline uint32_t jz4740_dma_unit_size(struct jz4740_dma_s *s,
2262 uint32_t cmd)
2264 switch ((cmd & 0x700) >> 8)
2266 case 0x0:
2267 return 4;
2268 case 0x1:
2269 return 1;
2270 case 0x2:
2271 return 2;
2272 case 0x3:
2273 return 16;
2274 case 0x4:
2275 return 32;
2277 return (0);
2281 /*No-descriptor transfer*/
2282 static inline void jz4740_dma_ndrun(struct jz4740_dma_s *s, int channel)
2284 uint32_t len;
2286 len = jz4740_dma_unit_size(s, s->dcs[channel]) * s->dtc[channel];
2288 jz4740_dma_transfer(s, s->dsa[channel], s->dta[channel], len);
2290 /*finish dma transfer */
2291 s->dtc[channel] = 0;
2292 /*set DIR QP */
2293 s->dirqp |= 1 << channel;
2295 /*some cleanup work */
2296 /*clean AR TT GLOBAL AR */
2297 s->dcs[channel] &= 0xffffffe7;
2298 s->dmac &= 0xfffffffb;
2300 if (s->dcm[channel] & 0x2)
2301 qemu_set_irq(s->irq, 1);
2304 /*descriptor transfer */
2305 static inline void jz4740_dma_drun(struct jz4740_dma_s *s, int channel)
2307 struct jz4740_desc_s *desc;
2308 target_phys_addr_t desc_phy;
2309 uint32_t pd;
2311 desc_phy = s->dda[channel];
2312 if (desc_phy & 0xf)
2313 cpu_abort(s->soc->env,
2314 "jz4740_dma_drun descriptor address " JZ_FMT_plx
2315 " must be 4 bytes aligned \n", desc_phy);
2317 pd = cpu_get_physical_page_desc(desc_phy);
2318 if ((pd & ~TARGET_PAGE_MASK) != IO_MEM_RAM)
2319 cpu_abort(cpu_single_env,
2320 "%s: DMA descriptor address " JZ_FMT_plx " outside RAM!\n",
2321 __FUNCTION__, desc_phy);
2322 else
2323 desc = (struct jz4740_desc_s *) (phys_ram_base +
2324 (pd & TARGET_PAGE_MASK) +
2325 (desc_phy & ~TARGET_PAGE_MASK));
2327 if (!desc)
2328 cpu_abort(cpu_single_env,
2329 "%s: DMA descriptor " JZ_FMT_plx " is NULL!\n", __FUNCTION__,
2330 (uint32_t) desc);
2332 while (1)
2334 if ((desc->dcmd & 0x8) && (!(desc->dcmd & 0x10)))
2336 /*Stop DMA and set DCSN.INV=1 */
2337 s->dcs[channel] |= 1 << 6;
2338 return;
2340 jz4740_dma_transfer(s, desc->dtadr, desc->dsadr,
2341 (desc->ddadr & 0xffffff) *
2342 jz4740_dma_unit_size(s, desc->dcmd));
2344 if ((desc->dcmd) & (1 << 3))
2345 /*clear v */
2346 desc->dcmd &= ~(1 << 4);
2347 if (desc->dcmd & 0x1)
2348 /*set DCSN.CT=1 */
2349 s->dcs[channel] |= 0x2;
2350 else
2351 /*set DCSN.TT=1 */
2352 s->dcs[channel] |= 0x8;
2354 if (desc->dcmd & 0x2)
2355 qemu_set_irq(s->irq, 1);
2357 if ((desc->dcmd) & 0x1)
2359 /*fetch next descriptor */
2360 desc_phy = s->dda[channel] & 0xfffff000;
2361 desc_phy += (desc->dtadr & 0xff000000) >> 24;
2362 pd = cpu_get_physical_page_desc(desc_phy);
2363 if ((pd & ~TARGET_PAGE_MASK) != IO_MEM_RAM)
2364 cpu_abort(cpu_single_env,
2365 "%s: DMA descriptor address %x outside RAM!\n",
2366 __FUNCTION__, desc_phy);
2367 else
2368 desc = (struct jz4740_desc_s *) (phys_ram_base +
2369 (pd & TARGET_PAGE_MASK)
2371 (desc_phy &
2372 ~TARGET_PAGE_MASK));
2373 if (!desc)
2374 cpu_abort(cpu_single_env,
2375 "%s: DMA descriptor %x is NULL!\n",
2376 __FUNCTION__, (uint32_t) desc);
2378 else
2379 break;
2383 static void jz4740_dma_en_channel(struct jz4740_dma_s *s, int channel)
2385 if (s->dmac & 0x1)
2387 if (s->dcs[channel] & (1 << 31))
2389 /*NON DESCRIPTOR */
2390 jz4740_dma_ndrun(s, channel);
2395 static inline void jz4740_dma_en_global(struct jz4740_dma_s *s)
2397 int channel;
2398 for (channel = 0; channel < JZ4740_DMA_NUM; channel++)
2400 jz4740_dma_en_channel(s, channel);
2404 static inline void jz4740_dma_en_dbn(struct jz4740_dma_s *s, int channel)
2406 if ((s->dmac & 0x1) && (s->dcs[channel] & (1 << 31)))
2408 jz4740_dma_drun(s, channel);
2412 static void jz4740_dma_reset(struct jz4740_dma_s *s)
2417 static uint32_t jz4740_dma_read(void *opaque, target_phys_addr_t addr)
2419 struct jz4740_dma_s *s = (struct jz4740_dma_s *) opaque;
2420 int channel;
2422 debug_out(DEBUG_DMA, "jz4740_dma_read addr %x \n", addr);
2423 switch (addr)
2425 case 0x300:
2426 return s->dmac;
2427 case 0x304:
2428 return s->dirqp;
2429 case 0x308:
2430 return s->ddr;
2431 case 0x0:
2432 case 0x20:
2433 case 0x40:
2434 case 0x60:
2435 case 0x80:
2436 case 0xa0:
2437 channel = (addr - 0x0) / 0x20;
2438 return s->dsa[channel];
2439 case 0x4:
2440 case 0x24:
2441 case 0x44:
2442 case 0x64:
2443 case 0x84:
2444 case 0xa4:
2445 channel = (addr - 0x4) / 0x20;
2446 return s->dta[channel];
2447 case 0x8:
2448 case 0x28:
2449 case 0x48:
2450 case 0x68:
2451 case 0x88:
2452 case 0xa8:
2453 channel = (addr - 0x8) / 0x20;
2454 return s->dtc[channel];
2455 case 0xc:
2456 case 0x2c:
2457 case 0x4c:
2458 case 0x6c:
2459 case 0x8c:
2460 case 0xac:
2461 channel = (addr - 0xc) / 0x20;
2462 return s->drs[channel];
2463 case 0x10:
2464 case 0x30:
2465 case 0x50:
2466 case 0x70:
2467 case 0x90:
2468 case 0xb0:
2469 channel = (addr - 0x10) / 0x20;
2470 return s->dcs[channel];
2471 case 0x14:
2472 case 0x34:
2473 case 0x54:
2474 case 0x74:
2475 case 0x94:
2476 case 0xb4:
2477 channel = (addr - 0x14) / 0x20;
2478 return s->dcm[channel];
2479 case 0x18:
2480 case 0x38:
2481 case 0x58:
2482 case 0x78:
2483 case 0x98:
2484 case 0xb8:
2485 channel = (addr - 0x18) / 0x20;
2486 return s->dda[channel];
2487 default:
2488 cpu_abort(s->soc->env,
2489 "jz4740_dma_read undefined addr " JZ_FMT_plx " \n", addr);
2491 return (0);
2494 static void jz4740_dma_write(void *opaque, target_phys_addr_t addr,
2495 uint32_t value)
2497 struct jz4740_dma_s *s = (struct jz4740_dma_s *) opaque;
2498 int channel;
2500 debug_out(DEBUG_DMA, "jz4740_dma_write addr %x value %x \n", addr, value);
2501 switch (addr)
2503 case 0x304:
2504 JZ4740_RO_REG(addr);
2505 break;
2506 case 0x300:
2507 s->dmac = value & 0x30d;
2508 if (s->dmac & 0x1)
2509 jz4740_dma_en_global(s);
2510 break;
2511 case 0x308:
2512 case 0x30c:
2513 s->ddr = value & 0xff;
2514 for (channel = 0; channel < JZ4740_DMA_NUM; channel++)
2516 if (s->ddr & (1 << channel))
2518 jz4740_dma_en_dbn(s, channel);
2519 break;
2522 break;
2523 case 0x0:
2524 case 0x20:
2525 case 0x40:
2526 case 0x60:
2527 case 0x80:
2528 case 0xa0:
2529 channel = (addr - 0x0) / 0x20;
2530 s->dsa[channel] = value;
2531 break;
2532 case 0x4:
2533 case 0x24:
2534 case 0x44:
2535 case 0x64:
2536 case 0x84:
2537 case 0xa4:
2538 channel = (addr - 0x4) / 0x20;
2539 s->dta[channel] = value;
2540 break;
2541 case 0x8:
2542 case 0x28:
2543 case 0x48:
2544 case 0x68:
2545 case 0x88:
2546 case 0xa8:
2547 channel = (addr - 0x8) / 0x20;
2548 s->dtc[channel] = value;
2549 break;
2550 case 0xc:
2551 case 0x2c:
2552 case 0x4c:
2553 case 0x6c:
2554 case 0x8c:
2555 case 0xac:
2556 channel = (addr - 0xc) / 0x20;
2557 s->drs[channel] = value & 0x10;
2558 if (s->drs[channel] != 0x8)
2560 fprintf(stderr, "Only auto request is supproted \n");
2562 break;
2563 case 0x10:
2564 case 0x30:
2565 case 0x50:
2566 case 0x70:
2567 case 0x90:
2568 case 0xb0:
2569 channel = (addr - 0x10) / 0x20;
2570 s->dcs[channel] = value & 0x80ff005f;
2571 if (s->dcs[channel] & 0x1)
2572 jz4740_dma_en_channel(s, channel);
2573 break;
2574 case 0x14:
2575 case 0x34:
2576 case 0x54:
2577 case 0x74:
2578 case 0x94:
2579 case 0xb4:
2580 channel = (addr - 0x14) / 0x20;
2581 s->dcm[channel] = value & 0xcff79f;
2582 break;
2583 case 0x18:
2584 case 0x38:
2585 case 0x58:
2586 case 0x78:
2587 case 0x98:
2588 case 0xb8:
2589 channel = (addr - 0x18) / 0x20;
2590 s->dda[channel] = 0xfffffff0;
2591 break;
2592 default:
2593 cpu_abort(s->soc->env,
2594 "jz4740_dma_read undefined addr " JZ_FMT_plx " \n", addr);
2599 static CPUReadMemoryFunc *jz4740_dma_readfn[] = {
2600 jz4740_badwidth_read32, jz4740_badwidth_read32, jz4740_dma_read,
2603 static CPUWriteMemoryFunc *jz4740_dma_writefn[] = {
2604 jz4740_badwidth_write32, jz4740_badwidth_write32, jz4740_dma_write,
2608 static struct jz4740_dma_s *jz4740_dma_init(struct jz_state_s *soc,
2609 qemu_irq irq)
2611 int iomemtype;
2612 struct jz4740_dma_s *s = (struct jz4740_dma_s *) qemu_mallocz(sizeof(*s));
2613 s->base = JZ4740_PHYS_BASE(JZ4740_DMAC_BASE);
2614 s->soc = soc;
2615 s->irq = irq;
2617 jz4740_dma_reset(s);
2619 iomemtype =
2620 cpu_register_io_memory(0, jz4740_dma_readfn, jz4740_dma_writefn, s);
2621 cpu_register_physical_memory(s->base, 0x00010000, iomemtype);
2622 return s;
2626 static void jz4740_cpu_reset(void *opaque)
2628 fprintf(stderr, "%s: UNIMPLEMENTED!", __FUNCTION__);
2631 struct jz_state_s *jz4740_init(unsigned long sdram_size,
2632 uint32_t osc_extal_freq, DisplayState * ds)
2634 struct jz_state_s *s = (struct jz_state_s *)
2635 qemu_mallocz(sizeof(struct jz_state_s));
2636 ram_addr_t sram_base, sdram_base;
2637 qemu_irq *intc;
2639 s->mpu_model = jz4740;
2640 s->env = cpu_init("jz4740");
2642 if (!s->env)
2644 fprintf(stderr, "Unable to find CPU definition\n");
2645 exit(1);
2648 debug_init();
2649 qemu_register_reset(jz4740_cpu_reset, s->env);
2651 s->sdram_size = sdram_size;
2652 s->sram_size = JZ4740_SRAM_SIZE;
2654 /* Clocks */
2655 jz_clk_init(s, osc_extal_freq);
2657 /*map sram to 0x80000000 and sdram to 0x80004000 */
2658 sram_base = qemu_ram_alloc(s->sram_size);
2659 cpu_register_physical_memory(0x0, s->sram_size, (sram_base | IO_MEM_RAM));
2660 sdram_base = qemu_ram_alloc(s->sdram_size);
2661 cpu_register_physical_memory(JZ4740_SRAM_SIZE, s->sdram_size,
2662 (sdram_base | IO_MEM_RAM));
2664 /* Init internal devices */
2665 cpu_mips_irq_init_cpu(s->env);
2666 cpu_mips_clock_init(s->env);
2669 /* Clocks */
2670 jz_clk_init(s, osc_extal_freq);
2672 intc = jz4740_intc_init(s, s->env->irq[2]);
2673 s->cpm = jz4740_cpm_init(s);
2674 s->emc = jz4740_emc_init(s, intc[2]);
2675 s->gpio = jz4740_gpio_init(s, intc[25]);
2676 s->rtc = jz4740_rtc_init(s, intc[15]);
2677 s->tcu = jz4740_tcu_if_init(s, intc[23], intc[22], intc[21]);
2678 jz4740_tcu_init(s, s->tcu, 0);
2679 s->lcdc = jz4740_lcdc_init(s, intc[30], ds);
2680 s->dma = jz4740_dma_init(s, intc[20]);
2682 if (serial_hds[0])
2683 serial_mm_init(0x10030000, 2, intc[9], 57600, serial_hds[0], 1);
2685 return s;