change debug_out format of addr to JZ_FMT_plx
[qemu/qemu-JZ.git] / hw / mips_jz.c
blob6e5a84282a08849c111e4af7214cda1f9154e14d
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_SADC (1<<0x7)
55 #define DEBUG_ALL (0xffffffff)
56 #define DEBUG_FLAG DEBUG_ALL
59 #ifdef DEBUG
60 FILE *fp;
61 static void debug_init(void)
63 fp = fopen("jz4740.txt", "w+");
64 if (fp == NULL)
66 fprintf(stderr, "can not open jz4740.txt \n");
67 exit(-1);
70 static void debug_out(uint32_t flag, const char *format, ...)
72 va_list ap;
73 if (fp)
75 if (flag & DEBUG_FLAG)
77 va_start(ap, format);
78 vfprintf(fp, format, ap);
79 fflush(fp);
80 va_end(ap);
84 #else
85 static void debug_init(void)
88 static void debug_out(uint32_t flag, const char *format, ...)
91 #endif
93 uint32_t jz4740_badwidth_read8(void *opaque, target_phys_addr_t addr)
95 uint8_t ret;
97 JZ4740_8B_REG(addr);
98 cpu_physical_memory_read(addr, (void *) &ret, 1);
99 return ret;
102 void jz4740_badwidth_write8(void *opaque, target_phys_addr_t addr,
103 uint32_t value)
105 uint8_t val8 = value;
107 JZ4740_8B_REG(addr);
108 cpu_physical_memory_write(addr, (void *) &val8, 1);
111 uint32_t jz4740_badwidth_read16(void *opaque, target_phys_addr_t addr)
113 uint16_t ret;
114 JZ4740_16B_REG(addr);
115 cpu_physical_memory_read(addr, (void *) &ret, 2);
116 return ret;
119 void jz4740_badwidth_write16(void *opaque, target_phys_addr_t addr,
120 uint32_t value)
122 uint16_t val16 = value;
124 JZ4740_16B_REG(addr);
125 cpu_physical_memory_write(addr, (void *) &val16, 2);
128 uint32_t jz4740_badwidth_read32(void *opaque, target_phys_addr_t addr)
130 uint32_t ret;
132 JZ4740_32B_REG(addr);
133 cpu_physical_memory_read(addr, (void *) &ret, 4);
134 return ret;
137 void jz4740_badwidth_write32(void *opaque, target_phys_addr_t addr,
138 uint32_t value)
140 JZ4740_32B_REG(addr);
141 cpu_physical_memory_write(addr, (void *) &value, 4);
145 /*clock reset and power control*/
146 struct jz4740_cpm_s
148 target_phys_addr_t base;
149 struct jz_state_s *soc;
151 uint32_t cpccr;
152 uint32_t cppcr;
153 uint32_t i2scdr;
154 uint32_t lpcdr;
155 uint32_t msccdr;
156 uint32_t uhccdr;
157 uint32_t uhctst;
158 uint32_t ssicdr;
160 uint32_t lcr;
161 uint32_t clkgr;
162 uint32_t scr;
165 static void jz4740_dump_clocks(jz_clk parent)
167 jz_clk i = parent;
169 debug_out(DEBUG_CPM, "clock %s rate %d \n", i->name, i->rate);
170 for (i = i->child1; i; i = i->sibling)
171 jz4740_dump_clocks(i);
174 static inline void jz4740_cpccr_update(struct jz4740_cpm_s *s,
175 uint32_t new_value)
177 uint32_t ldiv, mdiv, pdiv, hdiv, cdiv, udiv;
178 uint32_t div_table[10] = {
179 1, 2, 3, 4, 6, 8, 12, 16, 24, 32
182 if (unlikely(new_value == s->cpccr))
183 return;
185 if (new_value & CPM_CPCCR_PCS)
186 jz_clk_setrate(jz_findclk(s->soc, "pll_divider"), 1, 1);
187 else
188 jz_clk_setrate(jz_findclk(s->soc, "pll_divider"), 2, 1);
191 ldiv = (new_value & CPM_CPCCR_LDIV_MASK) >> CPM_CPCCR_LDIV_BIT;
192 ldiv++;
194 mdiv = div_table[(new_value & CPM_CPCCR_MDIV_MASK) >> CPM_CPCCR_MDIV_BIT];
195 pdiv = div_table[(new_value & CPM_CPCCR_PDIV_MASK) >> CPM_CPCCR_PDIV_BIT];
196 hdiv = div_table[(new_value & CPM_CPCCR_HDIV_MASK) >> CPM_CPCCR_HDIV_BIT];
197 cdiv = div_table[(new_value & CPM_CPCCR_CDIV_MASK) >> CPM_CPCCR_CDIV_BIT];
198 udiv = div_table[(new_value & CPM_CPCCR_UDIV_MASK) >> CPM_CPCCR_UDIV_BIT];
200 jz_clk_setrate(jz_findclk(s->soc, "ldclk"), ldiv, 1);
201 jz_clk_setrate(jz_findclk(s->soc, "mclk"), mdiv, 1);
202 jz_clk_setrate(jz_findclk(s->soc, "pclk"), pdiv, 1);
203 jz_clk_setrate(jz_findclk(s->soc, "hclk"), hdiv, 1);
204 jz_clk_setrate(jz_findclk(s->soc, "cclk"), cdiv, 1);
205 jz_clk_setrate(jz_findclk(s->soc, "usbclk"), udiv, 1);
207 if (new_value & CPM_CPCCR_UCS)
208 jz_clk_reparent(jz_findclk(s->soc, "usbclk"),
209 jz_findclk(s->soc, "pll_divider"));
210 else
211 jz_clk_reparent(jz_findclk(s->soc, "usbclk"),
212 jz_findclk(s->soc, "osc_extal"));
214 if (new_value & CPM_CPCCR_I2CS)
215 jz_clk_reparent(jz_findclk(s->soc, "i2sclk"),
216 jz_findclk(s->soc, "pll_divider"));
217 else
218 jz_clk_reparent(jz_findclk(s->soc, "i2sclk"),
219 jz_findclk(s->soc, "osc_extal"));
221 s->cpccr = new_value;
223 debug_out(DEBUG_CPM, "write to cpccr 0x%x\n", new_value);
225 jz4740_dump_clocks(jz_findclk(s->soc, "osc_extal"));
229 static inline void jz4740_cppcr_update(struct jz4740_cpm_s *s,
230 uint32_t new_value)
232 uint32_t pllm, plln, pllod, pllbp, pllen;
233 uint32_t pll0[4] = {
234 1, 2, 2, 4
238 pllen = new_value & CPM_CPPCR_PLLEN;
239 pllbp = new_value & CPM_CPPCR_PLLBP;
240 if ((!pllen) || (pllen && pllbp))
242 jz_clk_setrate(jz_findclk(s->soc, "pll_output"), 1, 1);
243 debug_out(DEBUG_CPM, "pll is bypassed \n");
244 s->cppcr = new_value | CPM_CPPCR_PLLS;
245 return;
249 pllm = (new_value & CPM_CPPCR_PLLM_MASK) >> CPM_CPPCR_PLLM_BIT;
250 plln = (new_value & CPM_CPPCR_PLLN_MASK) >> CPM_CPPCR_PLLN_BIT;
251 pllod = (new_value & CPM_CPPCR_PLLOD_MASK) >> CPM_CPPCR_PLLOD_BIT;
252 jz_clk_setrate(jz_findclk(s->soc, "pll_output"), (plln + 2) * pll0[pllod],
253 pllm + 2);
255 s->cppcr = new_value;
257 debug_out(DEBUG_CPM, "write to cppcr 0x%x\n", new_value);
258 jz4740_dump_clocks(jz_findclk(s->soc, "osc_extal"));
262 static inline void jz4740_i2scdr_update(struct jz4740_cpm_s *s,
263 uint32_t new_value)
265 uint32_t i2scdr;
267 i2scdr = new_value & CPM_I2SCDR_I2SDIV_MASK;
268 if (unlikely(i2scdr == s->i2scdr))
269 return;
272 jz_clk_setrate(jz_findclk(s->soc, "i2sclk"), i2scdr + 1, 1);
274 s->i2scdr = i2scdr;
276 debug_out(DEBUG_CPM, "write to i2scdr 0x%x\n", new_value);
277 jz4740_dump_clocks(jz_findclk(s->soc, "osc_extal"));
281 static inline void jz4740_lpcdr_update(struct jz4740_cpm_s *s,
282 uint32_t new_value)
284 uint32_t ipcdr;
286 ipcdr = new_value & CPM_LPCDR_PIXDIV_MASK;
287 /*TODO: */
288 s->lpcdr = ipcdr;
291 static inline void jz4740_msccdr_update(struct jz4740_cpm_s *s,
292 uint32_t new_value)
294 uint32_t msccdr;
296 msccdr = new_value & CPM_MSCCDR_MSCDIV_MASK;
298 if (unlikely(msccdr == s->msccdr))
299 return;
302 jz_clk_setrate(jz_findclk(s->soc, "mscclk"), msccdr + 1, 1);
304 s->msccdr = msccdr;
306 debug_out(DEBUG_CPM, "write to msccdr 0x%x\n", new_value);
307 jz4740_dump_clocks(jz_findclk(s->soc, "osc_extal"));
311 static inline void jz4740_uhccdr_update(struct jz4740_cpm_s *s,
312 uint32_t new_value)
314 uint32_t uhccdr;
316 uhccdr = new_value & 0xf;
317 /*TODO: */
318 s->uhccdr = uhccdr;
321 static void jz4740_cpm_write(void *opaque, target_phys_addr_t addr,
322 uint32_t value)
324 struct jz4740_cpm_s *s = (struct jz4740_cpm_s *) opaque;
326 debug_out(DEBUG_CPM, "write to cpm addr "JZ_FMT_plx" value 0x%x\n", addr, value);
328 switch (addr)
330 case 0x0:
331 jz4740_cpccr_update(s, value);
332 break;
333 case 0x4:
334 s->lcr = value & 0xff;
335 break;
336 case 0x20:
337 s->clkgr = value & 0xffff;
338 break;
339 case 0x24:
340 s->scr = value & 0xffff;
341 break;
342 case 0x10:
343 jz4740_cppcr_update(s, value);
344 break;
345 case 0x60:
346 jz4740_i2scdr_update(s, value);
347 break;
348 case 0x64:
349 jz4740_lpcdr_update(s, value);
350 break;
351 case 0x68:
352 jz4740_msccdr_update(s, value);
353 break;
354 case 0x6c:
355 jz4740_uhccdr_update(s, value);
356 break;
357 case 0x70:
358 s->uhctst = value & 0x3f;
359 break;
360 case 0x74:
361 s->ssicdr = value & 0xf;
362 break;
363 default:
364 cpu_abort(s->soc->env,
365 "jz4740_cpm_write undefined addr " JZ_FMT_plx
366 " value %x \n", addr, value);
372 static uint32_t jz474_cpm_read(void *opaque, target_phys_addr_t addr)
374 struct jz4740_cpm_s *s = (struct jz4740_cpm_s *) opaque;
376 switch (addr)
378 case 0x0:
379 return s->cpccr;
380 case 0x4:
381 return s->lcr;
382 case 0x20:
383 return s->clkgr;
384 case 0x24:
385 return s->scr;
386 case 0x10:
387 return s->cppcr;
388 case 0x60:
389 return s->i2scdr;
390 case 0x64:
391 return s->lpcdr;
392 case 0x68:
393 return s->msccdr;
394 case 0x6c:
395 return s->uhccdr;
396 case 0x70:
397 return s->uhctst;
398 case 0x74:
399 return s->ssicdr;
400 default:
401 cpu_abort(s->soc->env,
402 "jz474_cpm_read undefined addr " JZ_FMT_plx " \n", addr);
409 static CPUReadMemoryFunc *jz4740_cpm_readfn[] = {
410 jz4740_badwidth_read32,
411 jz4740_badwidth_read32,
412 jz474_cpm_read,
415 static CPUWriteMemoryFunc *jz4740_cpm_writefn[] = {
416 jz4740_badwidth_write32,
417 jz4740_badwidth_write32,
418 jz4740_cpm_write,
421 static void jz4740_cpm_reset(struct jz4740_cpm_s *s)
423 s->cpccr = 0x42040000;
424 s->cppcr = 0x28080011;
425 s->i2scdr = 0x00000004;
426 s->lpcdr = 0x00000004;
427 s->msccdr = 0x00000004;
428 s->uhccdr = 0x00000004;
429 s->uhctst = 0x0;
430 s->ssicdr = 0x00000004;
432 s->lcr = 0xf8;
433 s->clkgr = 0x0;
434 s->scr = 0x1500;
437 static struct jz4740_cpm_s *jz4740_cpm_init(struct jz_state_s *soc)
439 int iomemtype;
440 struct jz4740_cpm_s *s = (struct jz4740_cpm_s *) qemu_mallocz(sizeof(*s));
441 s->base = JZ4740_PHYS_BASE(JZ4740_CPM_BASE);
442 s->soc = soc;
444 jz4740_cpm_reset(s);
446 iomemtype =
447 cpu_register_io_memory(0, jz4740_cpm_readfn, jz4740_cpm_writefn, s);
448 cpu_register_physical_memory(s->base, 0x00001000, iomemtype);
449 return s;
453 /* JZ4740 interrupt controller
454 * It issues INT2 to MIPS
456 struct jz4740_intc_s
458 qemu_irq parent_irq;
460 target_phys_addr_t base;
461 struct jz_state_s *soc;
463 uint32_t icsr;
464 uint32_t icmr;
465 uint32_t icmsr;
466 uint32_t icmcr;
467 uint32_t icpr;
470 static uint32_t jz4740_intc_read(void *opaque, target_phys_addr_t addr)
472 struct jz4740_intc_s *s = (struct jz4740_intc_s *) opaque;
474 switch (addr)
476 case 0x8:
477 case 0xc:
478 JZ4740_WO_REG(addr);
479 break;
480 case 0x0:
481 return s->icsr;
482 case 0x4:
483 return s->icmr;
484 case 0x10:
485 return s->icpr;
486 default:
487 cpu_abort(s->soc->env,
488 "jz4740_intc_read undefined addr " JZ_FMT_plx " \n", addr);
491 return (0);
494 static void jz4740_intc_write(void *opaque, target_phys_addr_t addr,
495 uint32_t value)
497 struct jz4740_intc_s *s = (struct jz4740_intc_s *) opaque;
499 switch (addr)
501 case 0x0:
502 JZ4740_RO_REG(addr);
503 break;
504 case 0x4:
505 s->icmr = value;
506 break;
507 case 0x8:
508 s->icmr |= value;
509 break;
510 case 0xc:
511 s->icmr &= ~value;
512 break;
513 case 0x10:
514 s->icpr &= ~value;
515 qemu_set_irq(s->parent_irq, 0);
516 break;
517 default:
518 cpu_abort(s->soc->env,
519 "jz4740_intc_write undefined addr " JZ_FMT_plx
520 " value %x \n", addr, value);
525 static CPUReadMemoryFunc *jz4740_intc_readfn[] = {
526 jz4740_badwidth_read32,
527 jz4740_badwidth_read32,
528 jz4740_intc_read,
531 static CPUWriteMemoryFunc *jz4740_intc_writefn[] = {
532 jz4740_badwidth_write32,
533 jz4740_badwidth_write32,
534 jz4740_intc_write,
537 static void jz4740_intc_reset(struct jz4740_intc_s *s)
539 s->icsr = 0x0;
540 s->icmr = 0xffffffff;
541 s->icpr = 0x0;
544 static void jz4740_set_irq(void *opaque, int irq, int level)
546 struct jz4740_intc_s *s = (struct jz4740_intc_s *) opaque;
547 uint32_t irq_mask = 1 << irq;
550 if (level)
552 s->icsr |= irq_mask;
553 s->icpr &= ~irq_mask;
554 if (!(s->icmr & irq_mask))
556 s->icpr |= irq_mask;
557 qemu_set_irq(s->parent_irq, 1);
563 static qemu_irq *jz4740_intc_init(struct jz_state_s *soc, qemu_irq parent_irq)
565 int iomemtype;
566 struct jz4740_intc_s *s = (struct jz4740_intc_s *) qemu_mallocz(sizeof(*s));
567 s->base = JZ4740_PHYS_BASE(JZ4740_INTC_BASE);
568 s->parent_irq = parent_irq;
569 s->soc = soc;
571 jz4740_intc_reset(s);
573 iomemtype =
574 cpu_register_io_memory(0, jz4740_intc_readfn, jz4740_intc_writefn, s);
575 cpu_register_physical_memory(s->base, 0x00001000, iomemtype);
576 return qemu_allocate_irqs(jz4740_set_irq, s, 32);
579 /*external memory controller*/
580 struct jz4740_emc_s
582 qemu_irq irq;
583 target_phys_addr_t base;
584 struct jz_state_s *soc;
586 uint32_t bcr;
587 uint32_t smcr1; /*0x13010014 */
588 uint32_t smcr2; /*0x13010018 */
589 uint32_t smcr3; /*0x1301001c */
590 uint32_t smcr4; /*0x13010020 */
591 uint32_t sacr1; /*0x13010034 */
592 uint32_t sacr2; /*0x13010038 */
593 uint32_t sacr3; /*0x1301003c */
594 uint32_t sacr4; /*0x13010040 */
596 uint32_t nfcsr; /*0x13010050 */
597 uint32_t nfeccr; /*0x13010100 */
598 uint32_t nfecc; /*0x13010104 */
599 uint32_t nfpar0; /*0x13010108 */
600 uint32_t nfpar1; /*0x1301010c */
601 uint32_t nfpar2; /*0x13010110 */
602 uint32_t nfints; /*0x13010114 */
603 uint32_t nfinte; /*0x13010118 */
604 uint32_t nferr0; /*0x1301011c */
605 uint32_t nferr1; /*0x13010120 */
606 uint32_t nferr2; /*0x13010124 */
607 uint32_t nferr3; /*0x13010128 */
609 uint32_t dmcr; /*0x13010080 */
610 uint32_t rtcsr; /*0x13010084 */
611 uint32_t rtcnt; /*0x13010088 */
612 uint32_t rtcor; /*0x1301008c */
613 uint32_t dmar; /*0x13010090 */
614 uint32_t sdmr; /*0x1301a000 */
619 static void jz4740_emc_reset(struct jz4740_emc_s *s)
621 s->smcr1 = 0xfff7700;
622 s->smcr2 = 0xfff7700;
623 s->smcr3 = 0xfff7700;
624 s->smcr4 = 0xfff7700;
625 s->sacr1 = 0x18fc;
626 s->sacr2 = 0x16fe;
627 s->sacr3 = 0x14fe;
628 s->sacr4 = 0xcfc;
630 s->nfcsr = 0x0;
631 s->nfeccr = 0x0;
632 s->nfecc = 0x0;
633 s->nfpar0 = 0x0;
634 s->nfpar1 = 0x0;
635 s->nfpar2 = 0x0;
636 s->nfints = 0x0;
637 s->nfinte = 0x0;
638 s->nferr0 = 0x0;
639 s->nferr1 = 0x0;
640 s->nferr2 = 0x0;
641 s->nferr3 = 0x0;
643 s->dmcr = 0x0;
644 s->rtcsr = 0x0;
645 s->rtcnt = 0x0;
646 s->rtcor = 0x0;
647 s->dmar = 0x20f8;
648 s->sdmr = 0x0;
652 static uint32_t jz4740_emc_read8(void *opaque, target_phys_addr_t addr)
654 struct jz4740_emc_s *s = (struct jz4740_emc_s *) opaque;
656 switch (addr)
658 case 0x108:
659 case 0x109:
660 case 0x10a:
661 case 0x10b:
662 return (s->nfpar0 >> ((addr - 0x108) * 8)) & 0xff;
663 case 0x10c:
664 case 0x10d:
665 case 0x10e:
666 case 0x10f:
667 return (s->nfpar1 >> ((addr - 0x10c) * 8)) & 0xff;
668 case 0x110:
669 case 0x111:
670 case 0x112:
671 case 0x113:
672 return (s->nfpar2 >> ((addr - 0x110) * 8)) & 0xff;
673 case 0xa000:
674 case 0xa001:
675 case 0xa002:
676 case 0xa003:
677 return (s->sdmr >> ((addr - 0xa000) * 8)) & 0xff;
678 default:
679 cpu_abort(s->soc->env,
680 "jz4740_emc_read8 undefined addr " JZ_FMT_plx " \n", addr);
684 return (0);
687 static uint32_t jz4740_emc_read16(void *opaque, target_phys_addr_t addr)
689 struct jz4740_emc_s *s = (struct jz4740_emc_s *) opaque;
691 switch (addr)
693 case 0x108:
694 case 0x10a:
695 return (s->nfpar0 >> ((addr - 0x108) * 8)) & 0xffff;
696 case 0x10c:
697 case 0x10e:
698 return (s->nfpar1 >> ((addr - 0x10c) * 8)) & 0xffff;
699 case 0x110:
700 case 0x112:
701 return (s->nfpar2 >> ((addr - 0x110) * 8)) & 0xffff;
702 case 0x11c:
703 case 0x11e:
704 return (s->nferr0 >> ((addr - 0x11c) * 8)) & 0xffff;
705 case 0x120:
706 case 0x122:
707 return (s->nferr1 >> ((addr - 0x120) * 8)) & 0xffff;
708 case 0x124:
709 case 0x126:
710 return (s->nferr2 >> ((addr - 0x124) * 8)) & 0xffff;
711 case 0x128:
712 case 0x12a:
713 return (s->nferr3 >> ((addr - 0x128) * 8)) & 0xffff;
714 default:
715 cpu_abort(s->soc->env,
716 "jz4740_emc_read16 undefined addr " JZ_FMT_plx " \n", addr);
718 return (0);
721 static uint32_t jz4740_emc_read32(void *opaque, target_phys_addr_t addr)
723 struct jz4740_emc_s *s = (struct jz4740_emc_s *) opaque;
725 switch (addr)
727 case 0x0:
728 return s->bcr;
729 case 0x14:
730 return s->smcr1;
731 case 0x18:
732 return s->smcr2;
733 case 0x1c:
734 return s->smcr3;
735 case 0x20:
736 return s->smcr4;
737 case 0x34:
738 return s->sacr1;
739 case 0x38:
740 return s->sacr2;
741 case 0x3c:
742 return s->sacr3;
743 case 0x40:
744 return s->sacr4;
745 case 0x50:
746 return s->nfcsr;
747 case 0x100:
748 return s->nfeccr;
749 case 0x104:
750 return s->nfecc;
751 case 0x108:
752 return s->nfpar0;
753 case 0x10c:
754 return s->nfpar1;
755 case 0x110:
756 return s->nfpar2;
757 case 0x114:
758 return s->nfints;
759 case 0x118:
760 return s->nfinte;
761 case 0x11c:
762 return s->nferr0;
763 case 0x120:
764 return s->nferr1;
765 case 0x124:
766 return s->nferr2;
767 case 0x128:
768 return s->nferr3;
769 case 0x80:
770 return s->dmcr;
771 case 0x90:
772 return s->dmar;
773 default:
774 cpu_abort(s->soc->env,
775 "jz4740_emc_read32 undefined addr " JZ_FMT_plx " \n", addr);
777 return (0);
780 static void jz4740_emc_write8(void *opaque, target_phys_addr_t addr,
781 uint32_t value)
783 struct jz4740_emc_s *s = (struct jz4740_emc_s *) opaque;
785 debug_out(DEBUG_EMC, "jz4740_emc_write8 addr "JZ_FMT_plx" value %x\n", addr, value);
787 switch (addr)
789 case 0x108:
790 case 0x109:
791 case 0x10a:
792 case 0x10b:
793 s->nfpar0 |= (value & 0xff) << ((addr - 0x108) * 8);
794 break;
795 case 0x10c:
796 case 0x10d:
797 case 0x10e:
798 case 0x10f:
799 s->nfpar1 |= (value & 0xff) << ((addr - 0x10c) * 8);
800 break;
801 case 0x110:
802 case 0x111:
803 case 0x112:
804 case 0x113:
805 s->nfpar2 |= (value & 0xff) << ((addr - 0x110) * 8);
806 break;
807 case 0xa000 ... 0xa3ff:
808 break;
809 default:
810 cpu_abort(s->soc->env,
811 "jz4740_emc_write8 undefined addr " JZ_FMT_plx
812 " value %x \n", addr, value);
815 static void jz4740_emc_write16(void *opaque, target_phys_addr_t addr,
816 uint32_t value)
818 struct jz4740_emc_s *s = (struct jz4740_emc_s *) opaque;
820 debug_out(DEBUG_EMC, "jz4740_emc_write16 addr "JZ_FMT_plx" value %x\n", addr, value);
821 switch (addr)
823 case 0x108:
824 case 0x10a:
825 s->nfpar0 |= (value & 0xffff) << ((addr - 0x108) * 8);
826 break;
827 case 0x10c:
828 case 0x10e:
829 s->nfpar1 |= (value & 0xffff) << ((addr - 0x10c) * 8);
830 break;
831 case 0x110:
832 case 0x112:
833 s->nfpar2 |= (value & 0xffff) << ((addr - 0x110) * 8);
834 break;
835 case 0x84:
836 case 0x86:
837 s->rtcsr |= (value & 0xffff) << ((addr - 0x84) * 8);
838 break;
839 case 0x88:
840 case 0x8a:
841 s->rtcnt |= (value & 0xffff) << ((addr - 0x88) * 8);
842 break;
843 case 0x8c:
844 s->rtcor |= (value & 0xffff) << ((addr - 0x8c) * 8);
845 break;
846 default:
847 cpu_abort(s->soc->env,
848 "jz4740_emc_write16 undefined addr " JZ_FMT_plx
849 " value %x \n", addr, value);
853 static void jz4740_emc_upate_interrupt(struct jz4740_emc_s *s)
855 qemu_set_irq(s->irq, s->nfints & s->nfinte);
858 static void jz4740_emc_write32(void *opaque, target_phys_addr_t addr,
859 uint32_t value)
861 struct jz4740_emc_s *s = (struct jz4740_emc_s *) opaque;
863 debug_out(DEBUG_EMC, "jz4740_emc_write32 addr "JZ_FMT_plx" value %x\n", addr, value);
864 switch (addr)
866 case 0x104:
867 case 0x11c:
868 case 0x120:
869 case 0x124:
870 case 0x128:
871 JZ4740_RO_REG(addr);
872 break;
873 case 0x0:
874 s->bcr = value;
875 break;
876 case 0x14:
877 s->smcr1 = value & 0xfff77cf;
878 break;
879 case 0x18:
880 s->smcr2 = value & 0xfff77cf;
881 break;
882 case 0x1c:
883 s->smcr3 = value & 0xfff77cf;
884 break;
885 case 0x20:
886 s->smcr4 = value & 0xfff77cf;
887 break;
888 case 0x34:
889 s->sacr1 = value & 0xffff;
890 break;
891 case 0x38:
892 s->sacr2 = value & 0xffff;
893 break;
894 case 0x3c:
895 s->sacr3 = value & 0xffff;
896 break;
897 case 0x40:
898 s->sacr4 = value & 0xffff;
899 break;
900 case 0x50:
901 s->nfcsr = value & 0xffff;
902 break;
903 case 0x100:
904 s->nfeccr = value & 0x1f;
905 if (s->nfeccr & 0x2)
907 s->nfecc = 0x0;
908 s->nfpar0 = 0x0;
909 s->nfpar1 = 0x0;
910 s->nfpar2 = 0x0;
911 s->nfints = 0x0;
912 s->nfinte = 0x0;
913 s->nferr0 = 0x0;
914 s->nferr1 = 0x0;
915 s->nferr2 = 0x0;
916 s->nferr3 = 0x0;
918 /*RS*/
919 /*TODO: Real RS error correction */
920 if (s->nfeccr & 0x4)
922 if ((s->nfeccr & 0x10) && (!(s->nfeccr & 0x8)))
924 /*decode */
925 s->nfints = 0x8;
926 s->nferr0 = 0x0;
927 s->nferr1 = 0x0;
928 s->nferr2 = 0x0;
930 if (s->nfeccr & 0x8)
932 /*encoding */
933 s->nfints = 0x4;
934 s->nfpar0 = 0xffffffff; /*fake value. for debug */
935 s->nfpar1 = 0xffffffff; /*fake value */
936 s->nfpar2 = 0xff; /*fake value */
939 else
941 s->nfecc = 0xffffff;
943 jz4740_emc_upate_interrupt(s);
944 break;
945 case 0x108:
946 s->nfpar0 = value;
947 break;
948 case 0x10c:
949 s->nfpar1 = value;
950 break;
951 case 0x110:
952 s->nfpar2 = value & 0xff;
953 break;
954 case 0x114:
955 s->nfints = value & 0x1fffffff;
956 jz4740_emc_upate_interrupt(s);
957 break;
958 case 0x118:
959 s->nfinte = value & 0x1f;
960 jz4740_emc_upate_interrupt(s);
961 break;
962 case 0x080:
963 s->dmcr = value & 0x9fbeff7f;
964 break;
965 case 0x90:
966 s->dmar = value & 0xffff;
967 break;
968 default:
969 cpu_abort(s->soc->env,
970 "jz4740_emc_write32 undefined addr " JZ_FMT_plx
971 " value %x \n", addr, value);
977 static CPUReadMemoryFunc *jz4740_emc_readfn[] = {
978 jz4740_emc_read8,
979 jz4740_emc_read16,
980 jz4740_emc_read32,
983 static CPUWriteMemoryFunc *jz4740_emc_writefn[] = {
984 jz4740_emc_write8,
985 jz4740_emc_write16,
986 jz4740_emc_write32,
990 static struct jz4740_emc_s *jz4740_emc_init(struct jz_state_s *soc,
991 qemu_irq irq)
993 int iomemtype;
994 struct jz4740_emc_s *s = (struct jz4740_emc_s *) qemu_mallocz(sizeof(*s));
995 s->base = JZ4740_PHYS_BASE(JZ4740_EMC_BASE);
996 s->soc = soc;
997 s->irq = irq;
999 jz4740_emc_reset(s);
1001 iomemtype =
1002 cpu_register_io_memory(0, jz4740_emc_readfn, jz4740_emc_writefn, s);
1003 cpu_register_physical_memory(s->base, 0x00010000, iomemtype);
1004 return s;
1008 struct jz4740_gpio_s
1010 qemu_irq irq;
1011 target_phys_addr_t base;
1012 struct jz_state_s *soc;
1014 uint32_t papin[4];
1015 uint32_t padat[4];
1016 uint32_t paim[4];
1017 uint32_t pape[4];
1018 uint32_t pafun[4];
1019 uint32_t pasel[4];
1020 uint32_t padir[4];
1021 uint32_t patrg[4];
1022 uint32_t paflg[4];
1025 static void jz4740_gpio_reset(struct jz4740_gpio_s *s)
1027 memset(s->papin, 0x0, sizeof(s->papin));
1028 memset(s->padat, 0x0, sizeof(s->padat));
1029 memset(s->paim, 0xffffffff, sizeof(s->paim));
1030 memset(s->pape, 0x0, sizeof(s->pape));
1031 memset(s->pafun, 0x0, sizeof(s->pafun));
1032 memset(s->pasel, 0x0, sizeof(s->pasel));
1033 memset(s->padir, 0x0, sizeof(s->padir));
1034 memset(s->patrg, 0x0, sizeof(s->patrg));
1035 memset(s->paflg, 0x0, sizeof(s->paflg));
1038 static uint32_t jz4740_gpio_read(void *opaque, target_phys_addr_t addr)
1040 struct jz4740_gpio_s *s = (struct jz4740_gpio_s *) opaque;
1041 uint32_t group;
1042 debug_out(DEBUG_GPIO, "jz4740_gpio_read addr %x\n", addr);
1044 switch (addr)
1046 case 0x14:
1047 case 0x114:
1048 case 0x214:
1049 case 0x314:
1050 case 0x18:
1051 case 0x118:
1052 case 0x218:
1053 case 0x318:
1054 case 0x24:
1055 case 0x124:
1056 case 0x224:
1057 case 0x324:
1058 case 0x28:
1059 case 0x128:
1060 case 0x228:
1061 case 0x328:
1062 case 0x34:
1063 case 0x134:
1064 case 0x234:
1065 case 0x334:
1066 case 0x38:
1067 case 0x138:
1068 case 0x238:
1069 case 0x338:
1070 case 0x44:
1071 case 0x144:
1072 case 0x244:
1073 case 0x344:
1074 case 0x48:
1075 case 0x148:
1076 case 0x248:
1077 case 0x348:
1078 case 0x54:
1079 case 0x154:
1080 case 0x254:
1081 case 0x354:
1082 case 0x58:
1083 case 0x158:
1084 case 0x258:
1085 case 0x358:
1086 case 0x64:
1087 case 0x164:
1088 case 0x264:
1089 case 0x364:
1090 case 0x68:
1091 case 0x168:
1092 case 0x268:
1093 case 0x368:
1094 case 0x74:
1095 case 0x174:
1096 case 0x274:
1097 case 0x374:
1098 case 0x78:
1099 case 0x178:
1100 case 0x278:
1101 case 0x378:
1102 case 0x84:
1103 case 0x184:
1104 case 0x284:
1105 case 0x384:
1106 JZ4740_WO_REG(addr);
1107 break;
1109 case 0x0:
1110 case 0x100:
1111 case 0x200:
1112 case 0x300:
1113 group = (addr - 0x0) / 0x100;
1114 if (addr == 0x200)
1116 /*GPIO(C) PIN 30 -> NAND FLASH R/B. */
1117 /*FOR NAND FLASH.PIN 30 ----|_____|------ */
1118 s->papin[2] &= 0x40000000;
1119 if (s->papin[2])
1120 s->papin[2] &= ~0x40000000;
1121 else
1122 s->papin[2] |= 0x40000000;
1124 return s->papin[group];
1125 case 0x10:
1126 case 0x110:
1127 case 0x210:
1128 case 0x310:
1129 group = (addr - 0x10) / 0x100;
1130 return s->padat[group];
1131 case 0x20:
1132 case 0x120:
1133 case 0x220:
1134 case 0x320:
1135 group = (addr - 0x20) / 0x100;
1136 return s->paim[group];
1137 case 0x30:
1138 case 0x130:
1139 case 0x230:
1140 case 0x330:
1141 group = (addr - 0x30) / 0x100;
1142 return s->pape[group];
1143 case 0x40:
1144 case 0x140:
1145 case 0x240:
1146 case 0x340:
1147 group = (addr - 0x40) / 0x100;
1148 return s->pafun[group];
1149 case 0x50:
1150 case 0x150:
1151 case 0x250:
1152 case 0x350:
1153 group = (addr - 0x50) / 0x100;
1154 return s->pasel[group];
1155 case 0x60:
1156 case 0x160:
1157 case 0x260:
1158 case 0x360:
1159 group = (addr - 0x60) / 0x100;
1160 return s->padir[group];
1161 case 0x70:
1162 case 0x170:
1163 case 0x270:
1164 case 0x370:
1165 group = (addr - 0x70) / 0x100;
1166 return s->patrg[group];
1167 case 0x80:
1168 case 0x180:
1169 case 0x280:
1170 case 0x380:
1171 group = (addr - 0x80) / 0x100;
1172 return s->paflg[group];
1173 default:
1174 cpu_abort(s->soc->env,
1175 "jz4740_gpio_read undefined addr " JZ_FMT_plx " \n", addr);
1177 return (0);
1180 static void jz4740_gpio_write(void *opaque, target_phys_addr_t addr,
1181 uint32_t value)
1183 struct jz4740_gpio_s *s = (struct jz4740_gpio_s *) opaque;
1184 uint32_t group;
1186 debug_out(DEBUG_GPIO, "jz4740_gpio_write addr "JZ_FMT_plx" value %x\n", addr, value);
1188 switch (addr)
1190 case 0x0:
1191 case 0x100:
1192 case 0x200:
1193 case 0x300:
1194 case 0x10:
1195 case 0x110:
1196 case 0x210:
1197 case 0x310:
1198 case 0x20:
1199 case 0x120:
1200 case 0x220:
1201 case 0x320:
1202 case 0x30:
1203 case 0x130:
1204 case 0x230:
1205 case 0x330:
1206 case 0x40:
1207 case 0x140:
1208 case 0x240:
1209 case 0x340:
1210 case 0x50:
1211 case 0x150:
1212 case 0x250:
1213 case 0x350:
1214 case 0x60:
1215 case 0x160:
1216 case 0x260:
1217 case 0x360:
1218 case 0x70:
1219 case 0x170:
1220 case 0x270:
1221 case 0x370:
1222 case 0x80:
1223 case 0x180:
1224 case 0x280:
1225 case 0x380:
1226 JZ4740_RO_REG(addr);
1227 break;
1228 case 0x14:
1229 case 0x114:
1230 case 0x214:
1231 case 0x314:
1232 group = (addr - 0x14) / 0x100;
1233 s->padat[group] = value;
1234 break;
1235 case 0x18:
1236 case 0x118:
1237 case 0x218:
1238 case 0x318:
1239 group = (addr - 0x18) / 0x100;
1240 s->padat[group] &= ~value;
1241 break;
1242 case 0x24:
1243 case 0x124:
1244 case 0x224:
1245 case 0x324:
1246 group = (addr - 0x24) / 0x100;
1247 s->paim[group] = value;
1248 break;
1249 case 0x28:
1250 case 0x128:
1251 case 0x228:
1252 case 0x328:
1253 group = (addr - 0x28) / 0x100;
1254 s->paim[group] &= ~value;
1255 break;
1256 case 0x34:
1257 case 0x134:
1258 case 0x234:
1259 case 0x334:
1260 group = (addr - 0x34) / 0x100;
1261 s->pape[group] = value;
1262 break;
1263 case 0x38:
1264 case 0x138:
1265 case 0x238:
1266 case 0x338:
1267 group = (addr - 0x38) / 0x100;
1268 s->pape[group] &= ~value;
1269 break;
1270 case 0x44:
1271 case 0x144:
1272 case 0x244:
1273 case 0x344:
1274 group = (addr - 0x44) / 0x100;
1275 s->pafun[group] = value;
1276 break;
1277 case 0x48:
1278 case 0x148:
1279 case 0x248:
1280 case 0x348:
1281 group = (addr - 0x48) / 0x100;
1282 s->pafun[group] &= ~value;
1283 break;
1284 case 0x54:
1285 case 0x154:
1286 case 0x254:
1287 case 0x354:
1288 group = (addr - 0x54) / 0x100;
1289 s->pasel[group] = value;
1290 break;
1291 case 0x58:
1292 case 0x158:
1293 case 0x258:
1294 case 0x358:
1295 group = (addr - 0x58) / 0x100;
1296 s->pasel[group] &= ~value;
1297 break;
1298 case 0x64:
1299 case 0x164:
1300 case 0x264:
1301 case 0x364:
1302 group = (addr - 0x64) / 0x100;
1303 s->padir[group] = value;
1304 break;
1305 case 0x68:
1306 case 0x168:
1307 case 0x268:
1308 case 0x368:
1309 group = (addr - 0x68) / 0x100;
1310 s->padir[group] &= ~value;
1311 break;
1312 case 0x74:
1313 case 0x174:
1314 case 0x274:
1315 case 0x374:
1316 group = (addr - 0x74) / 0x100;
1317 s->patrg[group] = value;
1318 break;
1319 case 0x78:
1320 case 0x178:
1321 case 0x278:
1322 case 0x378:
1323 group = (addr - 0x78) / 0x100;
1324 s->patrg[group] &= ~value;
1325 break;
1326 case 0x84:
1327 case 0x184:
1328 case 0x284:
1329 case 0x384:
1330 group = (addr - 0x74) / 0x100;
1331 s->paflg[group] &= ~value;
1332 break;
1333 default:
1334 cpu_abort(s->soc->env,
1335 "jz4740_gpio_write undefined addr " JZ_FMT_plx
1336 " value %x \n", addr, value);
1344 static CPUReadMemoryFunc *jz4740_gpio_readfn[] = {
1345 jz4740_badwidth_read32,
1346 jz4740_badwidth_read32,
1347 jz4740_gpio_read,
1350 static CPUWriteMemoryFunc *jz4740_gpio_writefn[] = {
1351 jz4740_badwidth_write32,
1352 jz4740_badwidth_write32,
1353 jz4740_gpio_write,
1356 static struct jz4740_gpio_s *jz4740_gpio_init(struct jz_state_s *soc,
1357 qemu_irq irq)
1359 int iomemtype;
1360 struct jz4740_gpio_s *s = (struct jz4740_gpio_s *) qemu_mallocz(sizeof(*s));
1361 s->base = JZ4740_PHYS_BASE(JZ4740_GPIO_BASE);
1362 s->soc = soc;
1363 s->irq = irq;
1365 jz4740_gpio_reset(s);
1367 iomemtype =
1368 cpu_register_io_memory(0, jz4740_gpio_readfn, jz4740_gpio_writefn, s);
1369 cpu_register_physical_memory(s->base, 0x00010000, iomemtype);
1370 return s;
1374 struct jz4740_rtc_s
1376 qemu_irq irq;
1377 target_phys_addr_t base;
1378 struct jz_state_s *soc;
1380 QEMUTimer *hz_tm;
1381 struct tm tm;
1382 //int sec_offset;
1383 int64_t next;
1385 uint32_t rtccr;
1386 uint32_t rtcsr;
1387 uint32_t rtcsar;
1388 uint32_t rtcgr;
1390 uint32_t hcr;
1391 uint32_t hwfcr;
1392 uint32_t hrcr;
1393 uint32_t hwcr;
1394 uint32_t hwrsr;
1395 uint32_t hspr;
1400 static void jz4740_rtc_update_interrupt(struct jz4740_rtc_s *s)
1402 if (!s->rtcsr&0x1)
1403 return;
1405 if (((s->rtccr & 0x40) && (s->rtccr & 0x20))
1406 || ((s->rtccr & 0x10) && (s->rtccr & 0x8)))
1408 debug_out(DEBUG_RTC,"s->rtccr %x \n",s->rtcsr);
1409 qemu_set_irq(s->irq, 1);
1415 static inline void jz4740_rtc_start(struct jz4740_rtc_s *s)
1417 s->next = +qemu_get_clock(rt_clock);
1418 qemu_mod_timer(s->hz_tm, s->next);
1421 static inline void jz4740_rtc_stop(struct jz4740_rtc_s *s)
1423 qemu_del_timer(s->hz_tm);
1424 s->next = -qemu_get_clock(rt_clock);
1425 if (s->next < 1)
1426 s->next = 1;
1429 static void jz4740_rtc_hz(void *opaque)
1431 struct jz4740_rtc_s *s = (struct jz4740_rtc_s *) opaque;
1433 s->next += 1000;
1434 qemu_mod_timer(s->hz_tm, s->next);
1435 if (s->rtccr & 0x1)
1437 s->rtcsr++;
1438 s->rtccr |= 0x40;
1439 if (s->rtcsr & 0x4)
1441 if (s->rtcsr == s->rtcsar)
1442 s->rtccr |= 0x10;
1444 jz4740_rtc_update_interrupt(s);
1448 static void jz4740_rtc_reset(struct jz4740_rtc_s *s)
1451 s->rtccr = 0x81;
1452 s->next = 1000;
1454 /*Maybe rtcsr need to be saved to file */
1455 s->rtcsr = time(NULL);
1456 jz4740_rtc_start(s);
1460 static uint32_t jz4740_rtc_read(void *opaque, target_phys_addr_t addr)
1462 struct jz4740_rtc_s *s = (struct jz4740_rtc_s *) opaque;
1464 debug_out(DEBUG_RTC, "jz4740_rtc_read addr %x\n", addr);
1465 switch (addr)
1467 case 0x0:
1468 return s->rtccr | 0x80;
1469 case 0x4:
1470 return s->rtcsr;
1471 case 0x8:
1472 return s->rtcsar;
1473 case 0xc:
1474 return s->rtcgr;
1475 case 0x20:
1476 return s->hcr;
1477 case 0x24:
1478 return s->hwfcr;
1479 case 0x28:
1480 return s->hrcr;
1481 case 0x2c:
1482 return s->hwcr;
1483 case 0x30:
1484 return s->hwrsr;
1485 case 0x34:
1486 return s->hspr;
1487 default:
1488 cpu_abort(s->soc->env,
1489 "jz4740_rtc_read undefined addr " JZ_FMT_plx "\n", addr);
1492 return (0);
1495 static void jz4740_rtc_write(void *opaque, target_phys_addr_t addr,
1496 uint32_t value)
1498 struct jz4740_rtc_s *s = (struct jz4740_rtc_s *) opaque;
1500 debug_out(DEBUG_RTC, "jz4740_rtc_write addr "JZ_FMT_plx" value %x\n", addr, value);
1502 switch (addr)
1504 case 0x0:
1505 s->rtccr = value & 0x7d;
1506 if (!value & 0x40)
1507 s->rtccr &= ~0x40;
1508 if (!value & 0x10)
1509 s->rtccr &= ~0x10;
1510 if (s->rtccr & 0x1)
1512 jz4740_rtc_start(s);
1514 else
1515 jz4740_rtc_stop(s);
1516 break;
1517 case 0x4:
1518 s->rtcsr = value;
1519 break;
1520 case 0x8:
1521 s->rtcsar = value;
1522 break;
1523 case 0xc:
1524 s->rtcgr = value & 0x13ffffff;
1525 break;
1526 case 0x20:
1527 s->hcr = value & 0x1;
1528 break;
1529 case 0x24:
1530 s->hwfcr = value & 0xffe0;
1531 break;
1532 case 0x28:
1533 s->hrcr = value & 0xfe0;
1534 break;
1535 case 0x2c:
1536 s->hwcr = value & 0x1;
1537 break;
1538 case 0x30:
1539 s->hwrsr = value & 0x33;
1540 break;
1541 case 0x34:
1542 s->hspr = value;
1543 break;
1544 default:
1545 cpu_abort(s->soc->env,
1546 "jz4740_rtc_write undefined addr " JZ_FMT_plx
1547 " value %x \n", addr, value);
1552 static CPUReadMemoryFunc *jz4740_rtc_readfn[] = {
1553 jz4740_badwidth_read32,
1554 jz4740_badwidth_read32,
1555 jz4740_rtc_read,
1558 static CPUWriteMemoryFunc *jz4740_rtc_writefn[] = {
1559 jz4740_badwidth_write32,
1560 jz4740_badwidth_write32,
1561 jz4740_rtc_write,
1564 static struct jz4740_rtc_s *jz4740_rtc_init(struct jz_state_s *soc,
1565 qemu_irq irq)
1567 int iomemtype;
1568 struct jz4740_rtc_s *s = (struct jz4740_rtc_s *) qemu_mallocz(sizeof(*s));
1569 s->base = JZ4740_PHYS_BASE(JZ4740_RTC_BASE);
1570 s->soc = soc;
1571 s->irq = irq;
1573 s->hz_tm = qemu_new_timer(rt_clock, jz4740_rtc_hz, s);
1575 jz4740_rtc_reset(s);
1577 iomemtype =
1578 cpu_register_io_memory(0, jz4740_rtc_readfn, jz4740_rtc_writefn, s);
1579 cpu_register_physical_memory(s->base, 0x00001000, iomemtype);
1580 return s;
1583 struct jz4740_tcu_s
1585 qemu_irq tcu_irq0;
1586 qemu_irq tcu_irq1;
1587 qemu_irq tcu_irq2;
1589 target_phys_addr_t base;
1590 struct jz_state_s *soc;
1593 QEMUTimer *half_timer[8];
1594 QEMUTimer *full_timer[8];
1595 int64_t time[8];
1597 uint32_t tsr;
1598 uint32_t ter;
1599 uint32_t tfr;
1600 uint32_t tmr;
1602 uint32_t tdfr[8];
1603 uint32_t tdhr[8];
1604 uint32_t tcnt[8];
1605 uint32_t tcsr[8];
1607 uint32_t prescale[8];
1608 uint32_t freq[8];
1611 static void jz4740_tcu_update_interrupt(struct jz4740_tcu_s *s)
1613 //printf("s->tfr %x s->tmr %x \n",s->tfr,s->tmr);
1614 if (((s->tfr & 0x1) & (~(s->tmr & 0x1)))
1615 || ((s->tfr & 0x10000) & (~(s->tmr & 0x10000))))
1617 qemu_set_irq(s->tcu_irq0, 1);
1619 else
1620 qemu_set_irq(s->tcu_irq0, 0);
1622 if (((s->tfr & 0x2) & (~(s->tmr & 0x2)))
1623 || ((s->tfr & 0x20000) & (~(s->tmr & 0x20000))))
1625 qemu_set_irq(s->tcu_irq1, 1);
1627 else
1628 qemu_set_irq(s->tcu_irq1, 0);
1630 if (((s->tfr & 0xfc) & (~(s->tmr & 0xfc)))
1631 || ((s->tfr & 0xfc0000) & (~(s->tmr & 0xfc0000))))
1633 qemu_set_irq(s->tcu_irq2, 1);
1635 else
1636 qemu_set_irq(s->tcu_irq2, 0);
1640 #undef TCU_INDEX
1641 #define TCU_INDEX 0
1642 #include "mips_jz_glue.h"
1643 #define TCU_INDEX 1
1644 #include "mips_jz_glue.h"
1645 #define TCU_INDEX 2
1646 #include "mips_jz_glue.h"
1647 #define TCU_INDEX 3
1648 #include "mips_jz_glue.h"
1649 #define TCU_INDEX 4
1650 #include "mips_jz_glue.h"
1651 #define TCU_INDEX 5
1652 #include "mips_jz_glue.h"
1653 #define TCU_INDEX 6
1654 #include "mips_jz_glue.h"
1655 #define TCU_INDEX 7
1656 #include "mips_jz_glue.h"
1657 #undef TCU_INDEX
1659 #define jz4740_tcu_start(s) do { \
1660 jz4740_tcu_start_half0(s); \
1661 jz4740_tcu_start_full0(s); \
1662 jz4740_tcu_start_half1(s); \
1663 jz4740_tcu_start_full1(s); \
1664 jz4740_tcu_start_half2(s); \
1665 jz4740_tcu_start_full2(s); \
1666 jz4740_tcu_start_half3(s); \
1667 jz4740_tcu_start_full3(s); \
1668 jz4740_tcu_start_half4(s); \
1669 jz4740_tcu_start_full4(s); \
1670 jz4740_tcu_start_half5(s); \
1671 jz4740_tcu_start_full5(s); \
1672 jz4740_tcu_start_half6(s); \
1673 jz4740_tcu_start_full6(s); \
1674 jz4740_tcu_start_half7(s); \
1675 jz4740_tcu_start_full7(s); \
1676 }while (0)
1678 static void jz4740_tcu_if_reset(struct jz4740_tcu_s *s)
1680 int i;
1682 s->tsr = 0x0;
1683 s->ter = 0x0;
1684 s->tfr = 0x0;
1685 s->tmr = 0x0;
1686 for (i = 0; i < 8; i++)
1688 s->tdfr[i] = 0xffff;
1689 s->tdhr[i] = 0x8000;
1690 s->tcnt[i] = 0x0;
1691 s->tcsr[i] = 0x0;
1692 s->half_timer[i] = NULL;
1693 s->full_timer[i] = NULL;
1697 static void jz4740_tcu_if_write8(void *opaque, target_phys_addr_t addr,
1698 uint32_t value)
1700 struct jz4740_tcu_s *s = (struct jz4740_tcu_s *) opaque;
1702 debug_out(DEBUG_TCU, "jz4740_tcu_if_write8 addr %x value %x\n", addr,
1703 value);
1705 switch (addr)
1707 case 0x14:
1708 s->ter |= (value & 0xff);
1709 jz4740_tcu_start(s);
1710 break;
1711 case 0x18:
1712 s->ter &= ~(value & 0xff);
1713 jz4740_tcu_start(s);
1714 break;
1715 default:
1716 cpu_abort(s->soc->env,
1717 "jz4740_tcu_if_write8 undefined addr " JZ_FMT_plx
1718 " value %x \n", addr, value);
1723 static void jz4740_tcu_if_write32(void *opaque, target_phys_addr_t addr,
1724 uint32_t value)
1726 struct jz4740_tcu_s *s = (struct jz4740_tcu_s *) opaque;
1728 debug_out(DEBUG_TCU, "jz4740_tcu_if_write32 addr %x value %x\n", addr,
1729 value);
1731 switch (addr)
1733 case 0x2c:
1734 s->tsr |= (value & 0x100ff);
1735 jz4740_tcu_start(s);
1736 break;
1737 case 0x3c:
1738 s->tsr &= ~(value & 0x100ff);
1739 jz4740_tcu_start(s);
1740 break;
1741 case 0x24:
1742 s->tfr |= (value & 0xff00ff);
1743 break;
1744 case 0x28:
1745 s->tfr &= ~(value & 0xff00ff);
1746 break;
1747 case 0x34:
1748 s->tmr |= (value & 0xff00ff);
1749 jz4740_tcu_update_interrupt(s);
1750 break;
1751 case 0x38:
1752 s->tmr &= ~(value & 0xff00ff);
1753 jz4740_tcu_update_interrupt(s);
1754 break;
1755 default:
1756 cpu_abort(s->soc->env,
1757 "jz4740_tcu_if_write32 undefined addr " JZ_FMT_plx
1758 " value %x \n", addr, value);
1763 static uint32_t jz4740_tcu_if_read8(void *opaque, target_phys_addr_t addr)
1765 struct jz4740_tcu_s *s = (struct jz4740_tcu_s *) opaque;
1767 debug_out(DEBUG_TCU, "jz4740_tcu_if_read8 addr %x\n", addr);
1769 switch (addr)
1771 case 0x10:
1772 return s->ter;
1773 default:
1774 cpu_abort(s->soc->env,
1775 "jz4740_tcu_if_read8 undefined addr " JZ_FMT_plx "\n", addr);
1777 return (0);
1780 static uint32_t jz4740_tcu_if_read32(void *opaque, target_phys_addr_t addr)
1782 struct jz4740_tcu_s *s = (struct jz4740_tcu_s *) opaque;
1784 debug_out(DEBUG_TCU, "jz4740_tcu_if_read32 addr %x\n", addr);
1786 switch (addr)
1788 case 0x1c:
1789 return s->tsr;
1790 case 0x20:
1791 return s->tfr;
1792 case 0x30:
1793 return s->tmr;
1794 default:
1795 cpu_abort(s->soc->env,
1796 "jz4740_tcu_if_read32 undefined addr " JZ_FMT_plx "\n", addr);
1799 return (0);
1803 static CPUReadMemoryFunc *jz4740_tcu_if_readfn[] = {
1804 jz4740_tcu_if_read8,
1805 jz4740_badwidth_read32,
1806 jz4740_tcu_if_read32,
1809 static CPUWriteMemoryFunc *jz4740_tcu_if_writefn[] = {
1810 jz4740_tcu_if_write8,
1811 jz4740_badwidth_write32,
1812 jz4740_tcu_if_write32,
1815 static struct jz4740_tcu_s *jz4740_tcu_if_init(struct jz_state_s *soc,
1816 qemu_irq tcu_irq0,
1817 qemu_irq tcu_irq1,
1818 qemu_irq tcu_irq2)
1820 int iomemtype;
1821 //int i;
1823 struct jz4740_tcu_s *s = (struct jz4740_tcu_s *) qemu_mallocz(sizeof(*s));
1824 s->base = JZ4740_PHYS_BASE(JZ4740_TCU_BASE);
1825 s->soc = soc;
1826 s->tcu_irq0 = tcu_irq0;
1827 s->tcu_irq1 = tcu_irq1;
1828 s->tcu_irq2 = tcu_irq2;
1830 jz4740_tcu_if_reset(s);
1832 iomemtype =
1833 cpu_register_io_memory(0, jz4740_tcu_if_readfn, jz4740_tcu_if_writefn,
1835 cpu_register_physical_memory(s->base, 0x00000040, iomemtype);
1836 return s;
1840 static void jz4740_tcu_init(struct jz_state_s *soc,
1841 struct jz4740_tcu_s *s, int timer_index)
1843 switch (timer_index)
1845 case 0x0:
1846 jz4740_tcu_init0(soc, s);
1847 break;
1848 case 0x1:
1849 jz4740_tcu_init1(soc, s);
1850 break;
1851 case 0x2:
1852 jz4740_tcu_init2(soc, s);
1853 break;
1854 case 0x3:
1855 jz4740_tcu_init3(soc, s);
1856 break;
1857 case 0x4:
1858 jz4740_tcu_init4(soc, s);
1859 break;
1860 case 0x5:
1861 jz4740_tcu_init5(soc, s);
1862 break;
1863 case 0x6:
1864 jz4740_tcu_init6(soc, s);
1865 break;
1866 case 0x7:
1867 jz4740_tcu_init7(soc, s);
1868 break;
1869 default:
1870 cpu_abort(s->soc->env,
1871 "jz4740_tcu_init undefined timer %x \n", timer_index);
1875 typedef void (*jz4740_lcd_fn_t) (uint8_t * d, const uint8_t * s, int width,
1876 const uint16_t * pal);
1877 struct jz_fb_descriptor
1879 uint32_t fdadr; /* Frame descriptor address register */
1880 uint32_t fsadr; /* Frame source address register */
1881 uint32_t fidr; /* Frame ID register */
1882 uint32_t ldcmd; /* Command register */
1885 struct jz4740_lcdc_s
1887 qemu_irq irq;
1889 target_phys_addr_t base;
1890 struct jz_state_s *soc;
1892 DisplayState *state;
1893 QEMUConsole *console;
1894 jz4740_lcd_fn_t *line_fn_tab;
1895 jz4740_lcd_fn_t line_fn;
1898 uint32_t lcdcfg;
1899 uint32_t lcdvsync;
1900 uint32_t lcdhsync;
1901 uint32_t lcdvat;
1902 uint32_t lcddah;
1903 uint32_t lcddav;
1904 uint32_t lcdps;
1905 uint32_t lcdcls;
1906 uint32_t lcdspl;
1907 uint32_t lcdrev;
1908 uint32_t lcdctrl;
1909 uint32_t lcdstate;
1910 uint32_t lcdiid;
1911 uint32_t lcdda0;
1912 uint32_t lcdsa0;
1913 uint32_t lcdfid0;
1914 uint32_t lcdcmd0;
1915 uint32_t lcdda1;
1916 uint32_t lcdsa1;
1917 uint32_t lcdfid1;
1918 uint32_t lcdcmd1;
1920 uint32_t ena;
1921 uint32_t dis;
1922 uint32_t width;
1923 uint32_t height;
1924 uint32_t bpp; /*bit per second */
1925 uint16_t palette[256];
1926 uint32_t invalidate;
1930 /*bit per pixel*/
1931 static const int jz4740_lcd_bpp[0x6] = {
1932 1, 2, 4, 8, 16, 32 /*4740 uses 32 bit for 24bpp */
1935 static void jz4740_lcdc_reset(struct jz4740_lcdc_s *s)
1940 static uint32_t jz4740_lcdc_read(void *opaque, target_phys_addr_t addr)
1942 struct jz4740_lcdc_s *s = (struct jz4740_lcdc_s *) opaque;
1944 debug_out(DEBUG_LCDC, "jz4740_lcdc_read addr %x \n", addr);
1945 switch (addr)
1947 case 0x0:
1948 return s->lcdcfg;
1949 case 0x4:
1950 return s->lcdvsync;
1951 case 0x8:
1952 return s->lcdhsync;
1953 case 0xc:
1954 return s->lcdvat;
1955 case 0x10:
1956 return s->lcddah;
1957 case 0x14:
1958 return s->lcddav;
1959 case 0x18:
1960 return s->lcdps;
1961 case 0x1c:
1962 return s->lcdcls;
1963 case 0x20:
1964 return s->lcdspl;
1965 case 0x24:
1966 return s->lcdrev;
1967 case 0x30:
1968 return s->lcdctrl;
1969 case 0x34:
1970 return s->lcdstate;
1971 case 0x38:
1972 return s->lcdiid;
1973 case 0x40:
1974 return s->lcdda0;
1975 case 0x44:
1976 return s->lcdsa0;
1977 case 0x48:
1978 return s->lcdfid0;
1979 case 0x4c:
1980 return s->lcdcmd0;
1981 case 0x50:
1982 return s->lcdda1;
1983 case 0x54:
1984 return s->lcdsa1;
1985 case 0x58:
1986 return s->lcdfid1;
1987 case 0x5c:
1988 return s->lcdcmd1;
1989 default:
1990 cpu_abort(s->soc->env,
1991 "jz4740_lcdc_read undefined addr " JZ_FMT_plx " \n", addr);
1997 static void jz4740_lcdc_write(void *opaque, target_phys_addr_t addr,
1998 uint32_t value)
2000 struct jz4740_lcdc_s *s = (struct jz4740_lcdc_s *) opaque;
2002 debug_out(DEBUG_LCDC, "jz4740_lcdc_write addr "JZ_FMT_plx" value %x\n", addr, value);
2004 switch (addr)
2006 case 0x44:
2007 case 0x48:
2008 case 0x4c:
2009 JZ4740_RO_REG(addr);
2010 break;
2011 case 0x0:
2012 s->lcdcfg = value & 0x80ffffbf;
2013 break;
2014 case 0x4:
2015 s->lcdvsync = value & 0x7ff07ff;
2016 break;
2017 case 0x8:
2018 s->lcdhsync = value & 0x7ff07ff;
2019 break;
2020 case 0xc:
2021 s->lcdvat = value & 0x7ff07ff;
2022 break;
2023 case 0x10:
2024 s->lcddah = value & 0x7ff07ff;
2025 s->width = (value & 0x7ff) - ((value >> 16) & 0x7ff);
2026 break;
2027 case 0x14:
2028 s->height = (value & 0x7ff) - ((value >> 16) & 0x7ff);
2029 s->lcddav = value & 0x7ff07ff;
2030 break;
2031 case 0x18:
2032 s->lcdps = value & 0x7ff07ff;
2033 break;
2034 case 0x1c:
2035 s->lcdcls = value & 0x7ff07ff;
2036 break;
2037 case 0x20:
2038 s->lcdspl = value & 0x7ff07ff;
2039 break;
2040 case 0x24:
2041 s->lcdrev = value & 0x7ff0000;
2042 break;
2043 case 0x30:
2044 s->lcdctrl = value & 0x3fff3fff;
2045 s->ena = (value & 0x8) >> 3;
2046 s->dis = (value & 0x10) >> 4;
2047 s->bpp = jz4740_lcd_bpp[value & 0x7];
2048 if ((s->bpp == 1))
2050 fprintf(stderr, "bpp =1 is not supported\n");
2051 exit(-1);
2053 s->line_fn = s->line_fn_tab[value & 0x7];
2054 break;
2055 case 0x34:
2056 s->lcdstate = value & 0xbf;
2057 break;
2058 case 0x38:
2059 s->lcdiid = value;
2060 break;
2061 case 0x40:
2062 s->lcdda0 = value;
2063 break;
2064 case 0x50:
2065 s->lcdda1 = value;
2066 break;
2067 default:
2068 cpu_abort(s->soc->env,
2069 "jz4740_lcdc_write undefined addr " JZ_FMT_plx " value %x \n",
2070 addr, value);
2075 static CPUReadMemoryFunc *jz4740_lcdc_readfn[] = {
2076 jz4740_badwidth_read32,
2077 jz4740_badwidth_read32,
2078 jz4740_lcdc_read,
2081 static CPUWriteMemoryFunc *jz4740_lcdc_writefn[] = {
2082 jz4740_badwidth_write32,
2083 jz4740_badwidth_write32,
2084 jz4740_lcdc_write,
2087 #include "pixel_ops.h"
2088 #define JZ4740_LCD_PANEL
2089 #define DEPTH 8
2090 #include "mips_jz_glue.h"
2091 #define DEPTH 15
2092 #include "mips_jz_glue.h"
2093 #define DEPTH 16
2094 #include "mips_jz_glue.h"
2095 #define DEPTH 24
2096 #include "mips_jz_glue.h"
2097 #define DEPTH 32
2098 #include "mips_jz_glue.h"
2099 #undef JZ4740_LCD_PANEL
2101 static void *jz4740_lcd_get_buffer(struct jz4740_lcdc_s *s,
2102 target_phys_addr_t addr)
2104 uint32_t pd;
2106 pd = cpu_get_physical_page_desc(addr);
2107 if ((pd & ~TARGET_PAGE_MASK) != IO_MEM_RAM)
2108 /* TODO */
2109 cpu_abort(cpu_single_env, "%s: framebuffer outside RAM!\n",
2110 __FUNCTION__);
2111 else
2112 return phys_ram_base +
2113 (pd & TARGET_PAGE_MASK) + (addr & ~TARGET_PAGE_MASK);
2116 static void jz4740_lcd_update_display(void *opaque)
2118 struct jz4740_lcdc_s *s = (struct jz4740_lcdc_s *) opaque;
2120 uint8_t *src, *dest;
2121 struct jz_fb_descriptor *fb_des;
2123 int step, linesize;
2124 int y;
2127 if (!s->ena)
2128 return;
2129 if (s->dis)
2130 return;
2132 if (!s->lcdda0)
2133 return;
2135 fb_des = (struct jz_fb_descriptor *) jz4740_lcd_get_buffer(s, s->lcdda0);
2136 s->lcdda0 = fb_des->fdadr;
2137 s->lcdsa0 = fb_des->fsadr;
2138 s->lcdfid0 = fb_des->fidr;
2139 s->lcdcmd0 = fb_des->ldcmd;
2141 src = (uint8_t *) jz4740_lcd_get_buffer(s, fb_des->fsadr);
2142 if (s->lcdcmd0 & (0x1 << 28))
2144 /*palette */
2145 memcpy(s->palette, src, sizeof(s->palette));
2146 return;
2149 /*frame buffer */
2151 if (s->width != ds_get_width(s->state) ||
2152 s->height != ds_get_height(s->state))
2154 qemu_console_resize(s->console, s->width, s->height);
2155 s->invalidate = 1;
2158 step = (s->width * s->bpp) >> 3;
2159 dest = ds_get_data(s->state);
2160 linesize = ds_get_linesize(s->state);
2162 //printf("s->width %d s->height %d s->bpp %d linesize %d \n",s->width,s->height ,s->bpp,linesize);
2164 for (y = 0; y < s->height; y++)
2166 s->line_fn(dest, src, s->width, s->palette);
2167 //memcpy(dest,src,step);
2168 src += step;
2169 dest += linesize;
2173 dpy_update(s->state, 0, 0, s->width, s->height);
2174 s->lcdstate |= 0x20;
2175 if ((s->lcdcmd0 & 0x40000000) && (!(s->lcdctrl & 0x2000)))
2176 qemu_set_irq(s->irq, 1);
2179 static inline void jz4740_lcd_invalidate_display(void *opaque)
2181 struct jz4740_lcdc_s *s = (struct jz4740_lcdc_s *) opaque;
2182 s->invalidate = 1;
2185 static struct jz4740_lcdc_s *jz4740_lcdc_init(struct jz_state_s *soc,
2186 qemu_irq irq, DisplayState * ds)
2188 int iomemtype;
2190 struct jz4740_lcdc_s *s = (struct jz4740_lcdc_s *) qemu_mallocz(sizeof(*s));
2191 s->base = JZ4740_PHYS_BASE(JZ4740_LCD_BASE);
2192 s->soc = soc;
2193 s->irq = irq;
2194 s->state = ds;
2197 jz4740_lcdc_reset(s);
2199 iomemtype =
2200 cpu_register_io_memory(0, jz4740_lcdc_readfn, jz4740_lcdc_writefn, s);
2201 cpu_register_physical_memory(s->base, 0x10000, iomemtype);
2203 s->console = graphic_console_init(s->state, jz4740_lcd_update_display,
2204 jz4740_lcd_invalidate_display,
2205 NULL, NULL, s);
2206 switch (ds_get_bits_per_pixel(s->state))
2208 case 0x0:
2209 s->line_fn_tab = qemu_mallocz(sizeof(jz4740_lcd_fn_t) * 6);
2210 break;
2211 case 8:
2212 s->line_fn_tab = jz4740_lcd_draw_fn_8;
2213 break;
2214 case 15:
2215 s->line_fn_tab = jz4740_lcd_draw_fn_15;
2216 break;
2217 case 16:
2218 s->line_fn_tab = jz4740_lcd_draw_fn_16;
2219 break;
2220 case 24:
2221 s->line_fn_tab = jz4740_lcd_draw_fn_24;
2222 break;
2223 case 32:
2224 s->line_fn_tab = jz4740_lcd_draw_fn_32;
2225 break;
2226 default:
2227 fprintf(stderr, "%s: Bad color depth\n", __FUNCTION__);
2228 exit(1);
2231 return s;
2235 #define JZ4740_DMA_NUM 6
2236 struct jz4740_dma_s
2238 qemu_irq irq;
2240 target_phys_addr_t base;
2241 struct jz_state_s *soc;
2243 uint32_t dmac;
2244 uint32_t dirqp;
2245 uint32_t ddr;
2246 uint32_t ddrs;
2248 uint32_t dsa[JZ4740_DMA_NUM];
2249 uint32_t dta[JZ4740_DMA_NUM];
2250 uint32_t dtc[JZ4740_DMA_NUM];
2251 uint32_t drs[JZ4740_DMA_NUM];
2252 uint32_t dcs[JZ4740_DMA_NUM];
2253 uint32_t dcm[JZ4740_DMA_NUM];
2254 uint32_t dda[JZ4740_DMA_NUM];
2258 struct jz4740_desc_s
2260 uint32_t dcmd; /* DCMD value for the current transfer */
2261 uint32_t dsadr; /* DSAR value for the current transfer */
2262 uint32_t dtadr; /* DTAR value for the current transfer */
2263 uint32_t ddadr; /* Points to the next descriptor + transfer count */
2266 static inline void jz4740_dma_transfer(struct jz4740_dma_s *s,
2267 target_phys_addr_t src,
2268 target_phys_addr_t dest, uint32_t len)
2270 uint32_t pd_src, pd_dest;
2271 uint8_t *sr, *de;
2273 pd_src = cpu_get_physical_page_desc(src);
2274 if ((pd_src & ~TARGET_PAGE_MASK) != IO_MEM_RAM)
2275 /* TODO */
2276 cpu_abort(cpu_single_env, "%s: DMA source address "JZ_FMT_plx" outside RAM!\n",
2277 __FUNCTION__, src);
2278 else
2279 sr = phys_ram_base +
2280 (pd_src & TARGET_PAGE_MASK) + (src & ~TARGET_PAGE_MASK);
2282 pd_dest = cpu_get_physical_page_desc(dest);
2283 if ((pd_dest & ~TARGET_PAGE_MASK) != IO_MEM_RAM)
2284 /* TODO */
2285 cpu_abort(cpu_single_env,
2286 "%s: DMA destination address "JZ_FMT_plx" outside RAM!\n",
2287 __FUNCTION__, dest);
2288 else
2289 de = phys_ram_base +
2290 (pd_dest & TARGET_PAGE_MASK) + (dest & ~TARGET_PAGE_MASK);
2292 memcpy(de, sr, len);
2295 static inline uint32_t jz4740_dma_unit_size(struct jz4740_dma_s *s,
2296 uint32_t cmd)
2298 switch ((cmd & 0x700) >> 8)
2300 case 0x0:
2301 return 4;
2302 case 0x1:
2303 return 1;
2304 case 0x2:
2305 return 2;
2306 case 0x3:
2307 return 16;
2308 case 0x4:
2309 return 32;
2311 return (0);
2315 /*No-descriptor transfer*/
2316 static inline void jz4740_dma_ndrun(struct jz4740_dma_s *s, int channel)
2318 uint32_t len;
2320 len = jz4740_dma_unit_size(s, s->dcs[channel]) * s->dtc[channel];
2322 jz4740_dma_transfer(s, s->dsa[channel], s->dta[channel], len);
2324 /*finish dma transfer */
2325 s->dtc[channel] = 0;
2326 /*set DIR QP */
2327 s->dirqp |= 1 << channel;
2329 /*some cleanup work */
2330 /*clean AR TT GLOBAL AR */
2331 s->dcs[channel] &= 0xffffffe7;
2332 s->dmac &= 0xfffffffb;
2334 if (s->dcm[channel] & 0x2)
2335 qemu_set_irq(s->irq, 1);
2338 /*descriptor transfer */
2339 static inline void jz4740_dma_drun(struct jz4740_dma_s *s, int channel)
2341 struct jz4740_desc_s *desc;
2342 target_phys_addr_t desc_phy;
2343 uint32_t pd;
2345 desc_phy = s->dda[channel];
2346 if (desc_phy & 0xf)
2347 cpu_abort(s->soc->env,
2348 "jz4740_dma_drun descriptor address " JZ_FMT_plx
2349 " must be 4 bytes aligned \n", desc_phy);
2351 pd = cpu_get_physical_page_desc(desc_phy);
2352 if ((pd & ~TARGET_PAGE_MASK) != IO_MEM_RAM)
2353 cpu_abort(cpu_single_env,
2354 "%s: DMA descriptor address " JZ_FMT_plx " outside RAM!\n",
2355 __FUNCTION__, desc_phy);
2356 else
2357 desc = (struct jz4740_desc_s *) (phys_ram_base +
2358 (pd & TARGET_PAGE_MASK) +
2359 (desc_phy & ~TARGET_PAGE_MASK));
2361 if (!desc)
2362 cpu_abort(cpu_single_env,
2363 "%s: DMA descriptor %x is NULL!\n", __FUNCTION__,
2364 (uint32_t)desc);
2366 while (1)
2368 if ((desc->dcmd & 0x8) && (!(desc->dcmd & 0x10)))
2370 /*Stop DMA and set DCSN.INV=1 */
2371 s->dcs[channel] |= 1 << 6;
2372 return;
2374 jz4740_dma_transfer(s, desc->dtadr, desc->dsadr,
2375 (desc->ddadr & 0xffffff) *
2376 jz4740_dma_unit_size(s, desc->dcmd));
2378 if ((desc->dcmd) & (1 << 3))
2379 /*clear v */
2380 desc->dcmd &= ~(1 << 4);
2381 if (desc->dcmd & 0x1)
2382 /*set DCSN.CT=1 */
2383 s->dcs[channel] |= 0x2;
2384 else
2385 /*set DCSN.TT=1 */
2386 s->dcs[channel] |= 0x8;
2388 if (desc->dcmd & 0x2)
2389 qemu_set_irq(s->irq, 1);
2391 if ((desc->dcmd) & 0x1)
2393 /*fetch next descriptor */
2394 desc_phy = s->dda[channel] & 0xfffff000;
2395 desc_phy += (desc->dtadr & 0xff000000) >> 24;
2396 pd = cpu_get_physical_page_desc(desc_phy);
2397 if ((pd & ~TARGET_PAGE_MASK) != IO_MEM_RAM)
2398 cpu_abort(cpu_single_env,
2399 "%s: DMA descriptor address "JZ_FMT_plx" outside RAM!\n",
2400 __FUNCTION__, desc_phy);
2401 else
2402 desc = (struct jz4740_desc_s *) (phys_ram_base +
2403 (pd & TARGET_PAGE_MASK)
2405 (desc_phy &
2406 ~TARGET_PAGE_MASK));
2407 if (!desc)
2408 cpu_abort(cpu_single_env,
2409 "%s: DMA descriptor %x is NULL!\n",
2410 __FUNCTION__, (uint32_t) desc);
2412 else
2413 break;
2417 static void jz4740_dma_en_channel(struct jz4740_dma_s *s, int channel)
2419 if (s->dmac & 0x1)
2421 if (s->dcs[channel] & (1 << 31))
2423 /*NON DESCRIPTOR */
2424 jz4740_dma_ndrun(s, channel);
2429 static inline void jz4740_dma_en_global(struct jz4740_dma_s *s)
2431 int channel;
2432 for (channel = 0; channel < JZ4740_DMA_NUM; channel++)
2434 jz4740_dma_en_channel(s, channel);
2438 static inline void jz4740_dma_en_dbn(struct jz4740_dma_s *s, int channel)
2440 if ((s->dmac & 0x1) && (s->dcs[channel] & (1 << 31)))
2442 jz4740_dma_drun(s, channel);
2446 static void jz4740_dma_reset(struct jz4740_dma_s *s)
2451 static uint32_t jz4740_dma_read(void *opaque, target_phys_addr_t addr)
2453 struct jz4740_dma_s *s = (struct jz4740_dma_s *) opaque;
2454 int channel;
2456 debug_out(DEBUG_DMA, "jz4740_dma_read addr %x \n", addr);
2457 switch (addr)
2459 case 0x300:
2460 return s->dmac;
2461 case 0x304:
2462 return s->dirqp;
2463 case 0x308:
2464 return s->ddr;
2465 case 0x0:
2466 case 0x20:
2467 case 0x40:
2468 case 0x60:
2469 case 0x80:
2470 case 0xa0:
2471 channel = (addr - 0x0) / 0x20;
2472 return s->dsa[channel];
2473 case 0x4:
2474 case 0x24:
2475 case 0x44:
2476 case 0x64:
2477 case 0x84:
2478 case 0xa4:
2479 channel = (addr - 0x4) / 0x20;
2480 return s->dta[channel];
2481 case 0x8:
2482 case 0x28:
2483 case 0x48:
2484 case 0x68:
2485 case 0x88:
2486 case 0xa8:
2487 channel = (addr - 0x8) / 0x20;
2488 return s->dtc[channel];
2489 case 0xc:
2490 case 0x2c:
2491 case 0x4c:
2492 case 0x6c:
2493 case 0x8c:
2494 case 0xac:
2495 channel = (addr - 0xc) / 0x20;
2496 return s->drs[channel];
2497 case 0x10:
2498 case 0x30:
2499 case 0x50:
2500 case 0x70:
2501 case 0x90:
2502 case 0xb0:
2503 channel = (addr - 0x10) / 0x20;
2504 return s->dcs[channel];
2505 case 0x14:
2506 case 0x34:
2507 case 0x54:
2508 case 0x74:
2509 case 0x94:
2510 case 0xb4:
2511 channel = (addr - 0x14) / 0x20;
2512 return s->dcm[channel];
2513 case 0x18:
2514 case 0x38:
2515 case 0x58:
2516 case 0x78:
2517 case 0x98:
2518 case 0xb8:
2519 channel = (addr - 0x18) / 0x20;
2520 return s->dda[channel];
2521 default:
2522 cpu_abort(s->soc->env,
2523 "jz4740_dma_read undefined addr " JZ_FMT_plx " \n", addr);
2525 return (0);
2528 static void jz4740_dma_write(void *opaque, target_phys_addr_t addr,
2529 uint32_t value)
2531 struct jz4740_dma_s *s = (struct jz4740_dma_s *) opaque;
2532 int channel;
2534 debug_out(DEBUG_DMA, "jz4740_dma_write addr "JZ_FMT_plx" value %x \n", addr, value);
2535 switch (addr)
2537 case 0x304:
2538 JZ4740_RO_REG(addr);
2539 break;
2540 case 0x300:
2541 s->dmac = value & 0x30d;
2542 if (s->dmac & 0x1)
2543 jz4740_dma_en_global(s);
2544 break;
2545 case 0x308:
2546 case 0x30c:
2547 s->ddr = value & 0xff;
2548 for (channel = 0; channel < JZ4740_DMA_NUM; channel++)
2550 if (s->ddr & (1 << channel))
2552 jz4740_dma_en_dbn(s, channel);
2553 break;
2556 break;
2557 case 0x0:
2558 case 0x20:
2559 case 0x40:
2560 case 0x60:
2561 case 0x80:
2562 case 0xa0:
2563 channel = (addr - 0x0) / 0x20;
2564 s->dsa[channel] = value;
2565 break;
2566 case 0x4:
2567 case 0x24:
2568 case 0x44:
2569 case 0x64:
2570 case 0x84:
2571 case 0xa4:
2572 channel = (addr - 0x4) / 0x20;
2573 s->dta[channel] = value;
2574 break;
2575 case 0x8:
2576 case 0x28:
2577 case 0x48:
2578 case 0x68:
2579 case 0x88:
2580 case 0xa8:
2581 channel = (addr - 0x8) / 0x20;
2582 s->dtc[channel] = value;
2583 break;
2584 case 0xc:
2585 case 0x2c:
2586 case 0x4c:
2587 case 0x6c:
2588 case 0x8c:
2589 case 0xac:
2590 channel = (addr - 0xc) / 0x20;
2591 s->drs[channel] = value & 0x10;
2592 if (s->drs[channel] != 0x8)
2594 fprintf(stderr, "Only auto request is supproted \n");
2596 break;
2597 case 0x10:
2598 case 0x30:
2599 case 0x50:
2600 case 0x70:
2601 case 0x90:
2602 case 0xb0:
2603 channel = (addr - 0x10) / 0x20;
2604 s->dcs[channel] = value & 0x80ff005f;
2605 if (s->dcs[channel] & 0x1)
2606 jz4740_dma_en_channel(s, channel);
2607 break;
2608 case 0x14:
2609 case 0x34:
2610 case 0x54:
2611 case 0x74:
2612 case 0x94:
2613 case 0xb4:
2614 channel = (addr - 0x14) / 0x20;
2615 s->dcm[channel] = value & 0xcff79f;
2616 break;
2617 case 0x18:
2618 case 0x38:
2619 case 0x58:
2620 case 0x78:
2621 case 0x98:
2622 case 0xb8:
2623 channel = (addr - 0x18) / 0x20;
2624 s->dda[channel] = 0xfffffff0;
2625 break;
2626 default:
2627 cpu_abort(s->soc->env,
2628 "jz4740_dma_read undefined addr " JZ_FMT_plx " \n", addr);
2633 static CPUReadMemoryFunc *jz4740_dma_readfn[] = {
2634 jz4740_badwidth_read32,
2635 jz4740_badwidth_read32,
2636 jz4740_dma_read,
2639 static CPUWriteMemoryFunc *jz4740_dma_writefn[] = {
2640 jz4740_badwidth_write32,
2641 jz4740_badwidth_write32,
2642 jz4740_dma_write,
2646 static struct jz4740_dma_s *jz4740_dma_init(struct jz_state_s *soc,
2647 qemu_irq irq)
2649 int iomemtype;
2650 struct jz4740_dma_s *s = (struct jz4740_dma_s *) qemu_mallocz(sizeof(*s));
2651 s->base = JZ4740_PHYS_BASE(JZ4740_DMAC_BASE);
2652 s->soc = soc;
2653 s->irq = irq;
2655 jz4740_dma_reset(s);
2657 iomemtype =
2658 cpu_register_io_memory(0, jz4740_dma_readfn, jz4740_dma_writefn, s);
2659 cpu_register_physical_memory(s->base, 0x00010000, iomemtype);
2660 return s;
2664 #define PEN_DOWN 1
2665 #define PEN_UP 0
2666 struct jz4740_sadc_s
2668 qemu_irq irq;
2670 target_phys_addr_t base;
2671 struct jz_state_s *soc;
2673 uint32_t adena;
2674 uint32_t adcfg;
2675 uint32_t adctrl;
2676 uint32_t adstate;
2677 uint32_t adsame;
2678 uint32_t adwait;
2679 uint32_t adtch;
2680 uint32_t adbdat;
2681 uint32_t adsdat;
2682 uint32_t addpin;
2684 uint8_t tchen;
2685 uint8_t ex_in;
2686 uint8_t xyz;
2687 uint8_t snum;
2689 uint16_t x;
2690 uint16_t y;
2692 uint16_t pen_state;
2693 uint8_t read_index;
2698 static void jz4740_touchscreen_interrupt(struct jz4740_sadc_s *s)
2700 if (!s->tchen)
2701 return;
2703 if ((s->adctrl)&(s->adstate))
2705 debug_out(DEBUG_SADC,"irq s->adctrl %x s->adstate %x \n",s->adctrl,s->adstate);
2706 qemu_set_irq(s->irq,1);
2711 static void jz4740_touchscreen_event(void *opaque,
2712 int x, int y, int z, int buttons_state)
2714 struct jz4740_sadc_s *s = opaque;
2716 if (!s->tchen)
2717 return;
2719 s->x = (x*4096)/0x7FFF;
2720 s->y = (y*4096)/0x7FFF;
2722 if ((s->pen_state == PEN_UP)&&(buttons_state==PEN_DOWN))
2724 s->adstate |= 0x14;
2725 jz4740_touchscreen_interrupt(s);
2727 else if ((s->pen_state == PEN_DOWN)&&(buttons_state==PEN_UP))
2729 s->adstate |= 0xc;
2730 jz4740_touchscreen_interrupt(s);
2732 s->pen_state = buttons_state;
2736 static uint32_t jz4740_sadc_read8(void *opaque, target_phys_addr_t addr)
2738 struct jz4740_sadc_s *s = (struct jz4740_sadc_s *) opaque;
2740 switch (addr)
2742 case 0x0:
2743 return s->adena;
2744 case 0x8:
2745 return s->adctrl;
2746 case 0xc:
2747 return s->adstate;
2748 default:
2749 cpu_abort(s->soc->env,
2750 "jz4740_sadc_read8 undefined addr " JZ_FMT_plx " \n", addr);
2752 return (0);
2755 static uint32_t jz4740_sdac_read16(void *opaque, target_phys_addr_t addr)
2757 struct jz4740_sadc_s *s = (struct jz4740_sadc_s *) opaque;
2759 switch (addr)
2761 case 0x10:
2762 return s->adsame;
2763 case 0x14:
2764 return s->adwait;
2765 case 0x1c:
2766 return s->adbdat;
2767 case 0x20:
2768 return s->adsdat;
2769 default:
2770 cpu_abort(s->soc->env,
2771 "jz4740_sdac_read16 undefined addr " JZ_FMT_plx " \n", addr);
2773 return (0);
2776 static uint32_t jz4740_sdac_read32(void *opaque, target_phys_addr_t addr)
2778 struct jz4740_sadc_s *s = (struct jz4740_sadc_s *) opaque;
2779 switch (addr)
2781 case 0x4:
2782 return s->adcfg;
2783 case 0x18:
2784 /*TODO: Other type format*/
2785 if (s->read_index==0)
2787 s->read_index ++;
2788 return (((s->x) & 0x7fff) | ((s->y & 0x7ffff) << 16));
2790 else
2792 s->read_index = 0;
2793 return (0x3fff);
2795 default:
2796 cpu_abort(s->soc->env,
2797 "jz4740_sdac_read32 undefined addr " JZ_FMT_plx " \n", addr);
2799 return (0);
2802 static void jz4740_sadc_write8(void *opaque, target_phys_addr_t addr,
2803 uint32_t value)
2805 struct jz4740_sadc_s *s = (struct jz4740_sadc_s *) opaque;
2807 debug_out(DEBUG_SADC, "jz4740_sadc_write8 addr "JZ_FMT_plx" value %x\n", addr, value);
2809 switch (addr)
2811 case 0x0:
2812 s->adena = value & 0x7;
2813 s->tchen = value & 0x4;
2814 break;
2815 case 0x8:
2816 s->adctrl = value & 0x1f;
2817 break;
2818 case 0xc:
2819 s->adstate &= ~(value & 0x1f);
2820 break;
2821 default:
2822 cpu_abort(s->soc->env,
2823 "jz4740_sadc_write8 undefined addr " JZ_FMT_plx " value %x \n", addr,value);
2827 static void jz4740_sadc_write16(void *opaque, target_phys_addr_t addr,
2828 uint32_t value)
2830 struct jz4740_sadc_s *s = (struct jz4740_sadc_s *) opaque;
2832 debug_out(DEBUG_SADC, "jz4740_sadc_write16 addr "JZ_FMT_plx" value %x\n", addr, value);
2834 switch (addr)
2836 case 0x10:
2837 s->adsame = value & 0xffff;
2838 break;
2839 case 0x14:
2840 s->adsdat = value & 0xffff;
2841 break;
2842 case 0x1c:
2843 s->adbdat = 0x0;
2844 case 0x20:
2845 s->adsdat = 0x0;
2846 default:
2847 cpu_abort(s->soc->env,
2848 "jz4740_sadc_write16 undefined addr " JZ_FMT_plx " value %x \n", addr,value);
2852 static void jz4740_sadc_write32(void *opaque, target_phys_addr_t addr,
2853 uint32_t value)
2855 struct jz4740_sadc_s *s = (struct jz4740_sadc_s *) opaque;
2858 debug_out(DEBUG_SADC, "jz4740_sadc_write32 addr "JZ_FMT_plx" value %x\n", addr, value);
2860 switch (addr)
2862 case 0x4:
2863 s->adcfg = value & 0xc007ffff;
2864 s->ex_in = (value & 0x40000000)>>30;
2865 s->xyz = (value & 0x6fff)>>13;
2866 s->snum = ((value & 0x1cff)>>10)+1;
2867 break;
2868 case 18:
2869 s->adtch = value & 0x8fff8fff;
2870 break;
2871 default:
2872 cpu_abort(s->soc->env,
2873 "jz4740_sadc_write32 undefined addr " JZ_FMT_plx " value %x \n", addr,value);
2877 static void jz4740_sadc_reset(struct jz4740_sadc_s *s)
2879 s->adcfg = 0x0002002c;
2880 s->tchen = 0;
2881 s->snum = 1;
2882 s->xyz = 0;
2883 s->ex_in = 0;
2886 static CPUReadMemoryFunc *jz4740_sadc_readfn[] = {
2887 jz4740_sadc_read8,
2888 jz4740_sdac_read16,
2889 jz4740_sdac_read32,
2892 static CPUWriteMemoryFunc *jz4740_sadc_writefn[] = {
2893 jz4740_sadc_write8,
2894 jz4740_sadc_write16,
2895 jz4740_sadc_write32,
2898 static struct jz4740_sadc_s *jz4740_sadc_init(struct jz_state_s *soc,
2899 qemu_irq irq)
2901 int iomemtype;
2902 struct jz4740_sadc_s *s;
2904 s = (struct jz4740_sadc_s *)
2905 qemu_mallocz(sizeof(struct jz4740_sadc_s));
2906 s->base = JZ4740_PHYS_BASE(JZ4740_SADC_BASE);
2907 s->irq = irq;
2908 s->soc = soc;
2910 qemu_add_mouse_event_handler(jz4740_touchscreen_event, s, 1,
2911 "QEMU JZ4740 Touchscreen");
2913 jz4740_sadc_reset(s);
2915 iomemtype =
2916 cpu_register_io_memory(0, jz4740_sadc_readfn, jz4740_sadc_writefn, s);
2917 cpu_register_physical_memory(s->base, 0x00001000, iomemtype);
2918 return s;
2921 static void jz4740_cpu_reset(void *opaque)
2923 fprintf(stderr, "%s: UNIMPLEMENTED!", __FUNCTION__);
2926 struct jz_state_s *jz4740_init(unsigned long sdram_size,
2927 uint32_t osc_extal_freq, DisplayState * ds)
2929 struct jz_state_s *s = (struct jz_state_s *)
2930 qemu_mallocz(sizeof(struct jz_state_s));
2931 ram_addr_t sram_base, sdram_base;
2932 qemu_irq *intc;
2934 s->mpu_model = jz4740;
2935 s->env = cpu_init("jz4740");
2937 if (!s->env)
2939 fprintf(stderr, "Unable to find CPU definition\n");
2940 exit(1);
2943 debug_init();
2944 qemu_register_reset(jz4740_cpu_reset, s->env);
2946 s->sdram_size = sdram_size;
2947 s->sram_size = JZ4740_SRAM_SIZE;
2949 /* Clocks */
2950 jz_clk_init(s, osc_extal_freq);
2952 /*map sram to 0x80000000 and sdram to 0x80004000 */
2953 sram_base = qemu_ram_alloc(s->sram_size);
2954 cpu_register_physical_memory(0x0, s->sram_size, (sram_base | IO_MEM_RAM));
2955 sdram_base = qemu_ram_alloc(s->sdram_size);
2956 cpu_register_physical_memory(JZ4740_SRAM_SIZE, s->sdram_size,
2957 (sdram_base | IO_MEM_RAM));
2959 /* Init internal devices */
2960 cpu_mips_irq_init_cpu(s->env);
2961 cpu_mips_clock_init(s->env);
2964 /* Clocks */
2965 jz_clk_init(s, osc_extal_freq);
2967 intc = jz4740_intc_init(s, s->env->irq[2]);
2968 s->cpm = jz4740_cpm_init(s);
2969 s->emc = jz4740_emc_init(s, intc[2]);
2970 s->gpio = jz4740_gpio_init(s, intc[25]);
2971 s->rtc = jz4740_rtc_init(s, intc[15]);
2972 s->tcu = jz4740_tcu_if_init(s, intc[23], intc[22], intc[21]);
2973 jz4740_tcu_init(s, s->tcu, 0);
2974 s->lcdc = jz4740_lcdc_init(s, intc[30], ds);
2975 s->dma = jz4740_dma_init(s, intc[20]);
2976 s->sadc = jz4740_sadc_init(s,intc[12]);
2978 if (serial_hds[0])
2979 serial_mm_init(0x10030000, 2, intc[9], 57600, serial_hds[0], 1);
2981 return s;