07c8c4c4e05e7f38b9b12e4e62b6c708f75ce02b
[qemu/qemu-JZ.git] / hw / mips_jz.c
blob07c8c4c4e05e7f38b9b12e4e62b6c708f75ce02b
1 /*
2 * QEMU JZ Soc emulation
4 * Copyright (c) 2008 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 "mips_jz.h"
35 #include "sysemu.h"
36 #include "qemu-timer.h"
37 #include "qemu-char.h"
38 #include "flash.h"
39 #include "soc_dma.h"
40 #include "audio/audio.h"
42 #define DEBUG_CPM (1<<0x1)
44 #define DEBUG_FLAG (DEBUG_CPM)
47 #ifdef DEBUG
49 FILE *fp;
50 static void debug_init()
52 fp = fopen("jz4740.txt", "w+");
53 if (fp == NULL)
55 fprintf(stderr, "can not open jz4740.txt \n");
56 exit(-1);
59 static void debug_out(uint32_t flag, const char *format, ...)
61 va_list ap;
62 if (fp)
64 if (flag & DEBUG_FLAG)
66 va_start(ap, format);
67 vfprintf(fp, format, ap);
68 fflush(fp);
69 va_end(ap);
73 #else
74 static void debug_init(void)
77 static void debug_out(uint32_t flag, const char *format, ...)
80 #endif
82 static uint32_t jz4740_badwidth_read8(void *opaque, target_phys_addr_t addr)
84 uint8_t ret;
86 JZ4740_8B_REG(addr);
87 cpu_physical_memory_read(addr, (void *) &ret, 1);
88 return ret;
91 static void jz4740_badwidth_write8(void *opaque, target_phys_addr_t addr,
92 uint32_t value)
94 uint8_t val8 = value;
96 JZ4740_8B_REG(addr);
97 cpu_physical_memory_write(addr, (void *) &val8, 1);
100 static uint32_t jz4740_badwidth_read16(void *opaque, target_phys_addr_t addr)
102 uint16_t ret;
103 JZ4740_16B_REG(addr);
104 cpu_physical_memory_read(addr, (void *) &ret, 2);
105 return ret;
108 static void jz4740_badwidth_write16(void *opaque, target_phys_addr_t addr,
109 uint32_t value)
111 uint16_t val16 = value;
113 JZ4740_16B_REG(addr);
114 cpu_physical_memory_write(addr, (void *) &val16, 2);
117 static uint32_t jz4740_badwidth_read32(void *opaque, target_phys_addr_t addr)
119 uint32_t ret;
121 JZ4740_32B_REG(addr);
122 cpu_physical_memory_read(addr, (void *) &ret, 4);
123 return ret;
126 static void jz4740_badwidth_write32(void *opaque, target_phys_addr_t addr,
127 uint32_t value)
129 JZ4740_32B_REG(addr);
130 cpu_physical_memory_write(addr, (void *) &value, 4);
134 /*clock reset and power control*/
135 struct jz4740_cpm_s
137 target_phys_addr_t base;
138 struct jz_state_s *soc;
140 uint32_t cpccr;
141 uint32_t cppcr;
142 uint32_t i2scdr;
143 uint32_t lpcdr;
144 uint32_t msccdr;
145 uint32_t uhccdr;
146 uint32_t uhctst;
147 uint32_t ssicdr;
150 static void jz4740_dump_clocks(jz_clk parent)
152 jz_clk i = parent;
154 debug_out(DEBUG_CPM, "clock %x rate 0x%x \n", i->name, i->rate);
155 for (i = i->child1; i; i = i->sibling)
156 jz4740_dump_clocks(i);
159 static inline void jz4740_cpccr_update(struct jz4740_cpm_s *s,
160 uint32_t new_value)
162 uint32_t ldiv, mdiv, pdiv, hdiv, cdiv, udiv;
163 uint32_t div_table[10] = { 1, 2, 3, 4, 6, 8, 12, 16, 24, 32 };
165 if (unlikely(new_value == s->cpccr))
166 return;
168 if (new_value & CPM_CPCCR_PCS)
169 jz_clk_setrate(jz_findclk(s->soc, "pll_divider"), 1, 1);
170 else
171 jz_clk_setrate(jz_findclk(s->soc, "pll_divider"), 2, 1);
174 ldiv = (new_value & CPM_CPCCR_LDIV_MASK) >> CPM_CPCCR_LDIV_BIT;
175 ldiv++;
177 mdiv = div_table[(new_value & CPM_CPCCR_MDIV_MASK) >> CPM_CPCCR_MDIV_BIT];
178 pdiv = div_table[(new_value & CPM_CPCCR_PDIV_MASK) >> CPM_CPCCR_PDIV_BIT];
179 hdiv = div_table[(new_value & CPM_CPCCR_HDIV_MASK) >> CPM_CPCCR_HDIV_BIT];
180 cdiv = div_table[(new_value & CPM_CPCCR_CDIV_MASK) >> CPM_CPCCR_CDIV_BIT];
181 udiv = div_table[(new_value & CPM_CPCCR_UDIV_MASK) >> CPM_CPCCR_UDIV_BIT];
183 jz_clk_setrate(jz_findclk(s->soc, "ldclk"), ldiv, 1);
184 jz_clk_setrate(jz_findclk(s->soc, "mclk"), mdiv, 1);
185 jz_clk_setrate(jz_findclk(s->soc, "pclk"), pdiv, 1);
186 jz_clk_setrate(jz_findclk(s->soc, "hclk"), hdiv, 1);
187 jz_clk_setrate(jz_findclk(s->soc, "cclk"), cdiv, 1);
188 jz_clk_setrate(jz_findclk(s->soc, "usbclk"), udiv, 1);
190 if (new_value & CPM_CPCCR_UCS)
191 jz_clk_reparent(jz_findclk(s->soc, "usbclk"),
192 jz_findclk(s->soc, "pll_divider"));
193 else
194 jz_clk_reparent(jz_findclk(s->soc, "usbclk"),
195 jz_findclk(s->soc, "osc_extal"));
197 if (new_value & CPM_CPCCR_I2CS)
198 jz_clk_reparent(jz_findclk(s->soc, "i2sclk"),
199 jz_findclk(s->soc, "pll_divider"));
200 else
201 jz_clk_reparent(jz_findclk(s->soc, "i2sclk"),
202 jz_findclk(s->soc, "osc_extal"));
204 s->cpccr = new_value;
206 debug_out(DEBUG_CPM, "write to cpccr 0x%x\n", new_value);
207 jz4740_dump_clocks(jz_findclk(s->soc, "osc_extal"));
211 static inline void jz4740_cppcr_update(struct jz4740_cpm_s *s,
212 uint32_t new_value)
214 uint32_t pllm, plln, pllod, pllbp, pllen;
215 uint32_t pll0[4] = { 1, 2, 2, 4 };
218 pllen = new_value & CPM_CPPCR_PLLEN;
219 pllbp = new_value & CPM_CPPCR_PLLBP;
220 if ((!pllen) || (pllen && pllbp))
222 jz_clk_setrate(jz_findclk(s->soc, "pll_output"), 1, 1);
223 debug_out(DEBUG_CPM, "pll is bypassed \n");
224 s->cppcr = new_value | CPM_CPPCR_PLLS;
225 return;
229 pllm = (new_value & CPM_CPPCR_PLLM_MASK) >> CPM_CPPCR_PLLM_BIT;
230 plln = (new_value & CPM_CPPCR_PLLN_MASK) >> CPM_CPPCR_PLLN_BIT;
231 pllod = (new_value & CPM_CPPCR_PLLOD_MASK) >> CPM_CPPCR_PLLOD_BIT;
232 jz_clk_setrate(jz_findclk(s->soc, "pll_output"), (plln + 2) * pll0[pllod],
233 pllm + 2);
235 s->cppcr = new_value;
237 debug_out(DEBUG_CPM, "write to cppcr 0x%x\n", new_value);
238 jz4740_dump_clocks(jz_findclk(s->soc, "osc_extal"));
242 static inline void jz4740_i2scdr_update(struct jz4740_cpm_s *s,
243 uint32_t new_value)
245 uint32_t i2scdr;
247 i2scdr = new_value & CPM_I2SCDR_I2SDIV_MASK;
248 if (unlikely(i2scdr == s->i2scdr))
249 return;
252 jz_clk_setrate(jz_findclk(s->soc, "i2sclk"), i2scdr + 1, 1);
254 s->i2scdr = i2scdr;
256 debug_out(DEBUG_CPM, "write to i2scdr 0x%x\n", new_value);
257 jz4740_dump_clocks(jz_findclk(s->soc, "osc_extal"));
261 static inline void jz4740_lpcdr_update(struct jz4740_cpm_s *s,
262 uint32_t new_value)
264 uint32_t ipcdr;
266 ipcdr = new_value & CPM_LPCDR_PIXDIV_MASK;
267 /*TODO: */
268 s->lpcdr = ipcdr;
271 static inline void jz4740_msccdr_update(struct jz4740_cpm_s *s,
272 uint32_t new_value)
274 uint32_t msccdr;
276 msccdr = new_value & CPM_MSCCDR_MSCDIV_MASK;
278 if (unlikely(msccdr == s->msccdr))
279 return;
282 jz_clk_setrate(jz_findclk(s->soc, "mscclk"), msccdr + 1, 1);
284 s->msccdr = msccdr;
286 debug_out(DEBUG_CPM, "write to msccdr 0x%x\n", new_value);
287 jz4740_dump_clocks(jz_findclk(s->soc, "osc_extal"));
291 static inline void jz4740_uhccdr_update(struct jz4740_cpm_s *s,
292 uint32_t new_value)
294 uint32_t uhccdr;
296 uhccdr = new_value & 0xf;
297 /*TODO: */
298 s->uhccdr = uhccdr;
301 static void jz4740_cpm_write(void *opaque, target_phys_addr_t addr,
302 uint32_t value)
304 struct jz4740_cpm_s *s = (struct jz4740_cpm_s *) opaque;
305 int offset = addr - s->base;
307 switch (offset)
309 case 0x0:
310 jz4740_cpccr_update(s, value);
311 break;
312 case 0x10:
313 jz4740_cppcr_update(s, value);
314 break;
315 case 0x60:
316 jz4740_i2scdr_update(s, value);
317 break;
318 case 0x64:
319 jz4740_lpcdr_update(s, value);
320 break;
321 case 0x68:
322 jz4740_msccdr_update(s, value);
323 break;
324 case 0x6c:
325 jz4740_uhccdr_update(s, value);
326 break;
327 case 0x70:
328 s->uhctst = value & 0x3f;
329 break;
330 case 0x74:
331 s->ssicdr = value & 0xf;
332 break;
333 default:
334 cpu_abort(s->soc->env,
335 "jz4740_cpm_write undefined addr " JZ_FMT_plx " value %x \n",
336 addr, value);
342 static uint32_t jz474_cpm_read(void *opaque, target_phys_addr_t addr)
344 struct jz4740_cpm_s *s = (struct jz4740_cpm_s *) opaque;
345 int offset = addr - s->base;
347 switch (offset)
349 case 0x0:
350 return s->cpccr;
351 case 0x10:
352 return s->cppcr;
353 case 0x60:
354 return s->i2scdr;
355 case 0x64:
356 return s->lpcdr;
357 case 0x68:
358 return s->msccdr;
359 case 0x6c:
360 return s->uhccdr;
361 case 0x70:
362 return s->uhctst;
363 case 0x74:
364 return s->ssicdr;
365 default:
366 cpu_abort(s->soc->env,
367 "jz474_cpm_read undefined addr " JZ_FMT_plx " \n", addr);
374 static CPUReadMemoryFunc *jz4740_cpm_readfn[] = {
375 jz4740_badwidth_read32,
376 jz4740_badwidth_read32,
377 jz474_cpm_read,
380 static CPUWriteMemoryFunc *jz4740_cpm_writefn[] = {
381 jz4740_badwidth_write32,
382 jz4740_badwidth_write32,
383 jz4740_cpm_write,
386 static void jz4740_cpm_reset(struct jz4740_cpm_s *s)
388 s->cpccr = 0x42040000;
389 s->cppcr = 0x28080011;
390 s->i2scdr = 0x00000004;
391 s->lpcdr = 0x00000004;
392 s->msccdr = 0x00000004;
393 s->uhccdr = 0x00000004;
394 s->uhctst = 0x0;
395 s->ssicdr = 0x00000004;
398 static struct jz4740_cpm_s *jz4740_cpm_init(struct jz_state_s *soc)
400 int iomemtype;
401 struct jz4740_cpm_s *s = (struct jz4740_cpm_s *) qemu_mallocz(sizeof(*s));
402 s->base = JZ4740_PHYS_BASE(JZ4740_CPM_BASE);
403 s->soc = soc;
405 jz4740_cpm_reset(s);
407 iomemtype =
408 cpu_register_io_memory(0, jz4740_cpm_readfn, jz4740_cpm_writefn, s);
409 cpu_register_physical_memory(s->base, 0x00001000, iomemtype);
410 return s;
414 /* JZ4740 interrupt controller
415 * It issues INT2 to MIPS
417 struct jz4740_intc_s
419 qemu_irq parent_irq;
421 target_phys_addr_t base;
422 struct jz_state_s *soc;
424 uint32_t icsr;
425 uint32_t icmr;
426 uint32_t icmsr;
427 uint32_t icmcr;
428 uint32_t icpr;
431 static uint32_t jz4740_intc_read(void *opaque, target_phys_addr_t addr)
433 struct jz4740_intc_s *s = (struct jz4740_intc_s *) opaque;
434 int offset = addr - s->base;
435 switch (offset)
437 case 0x8:
438 case 0xc:
439 JZ4740_WO_REG(addr);
440 break;
441 case 0x0:
442 return s->icsr;
443 case 0x4:
444 return s->icmr;
445 case 0x10:
446 return s->icpr;
447 default:
448 cpu_abort(s->soc->env,
449 "jz4740_intc_read undefined addr " JZ_FMT_plx " \n", addr);
452 return (0);
455 static void jz4740_intc_write(void *opaque, target_phys_addr_t addr,
456 uint32_t value)
458 struct jz4740_intc_s *s = (struct jz4740_intc_s *) opaque;
459 int offset = addr - s->base;
461 switch (offset)
463 case 0x0:
464 case 0x10:
465 JZ4740_RO_REG(addr);
466 break;
467 case 0x4:
468 s->icmr = value;
469 break;
470 case 0x8:
471 s->icmr |= value;
472 break;
473 case 0xc:
474 s->icmr &= ~value;
475 break;
476 default:
477 cpu_abort(s->soc->env,
478 "jz4740_intc_write undefined addr " JZ_FMT_plx
479 " value %x \n", addr, value);
484 static CPUReadMemoryFunc *jz4740_intc_readfn[] = {
485 jz4740_badwidth_read32,
486 jz4740_badwidth_read32,
487 jz4740_intc_read,
490 static CPUWriteMemoryFunc *jz4740_intc_writefn[] = {
491 jz4740_badwidth_write32,
492 jz4740_badwidth_write32,
493 jz4740_intc_write,
496 static void jz4740_intc_reset(struct jz4740_intc_s *s)
498 s->icsr = 0x0;
499 s->icmr = 0xffffffff;
500 s->icpr = 0x0;
503 static void jz4740_set_irq(void *opaque, int irq, int level)
505 struct jz4740_intc_s *s = (struct jz4740_intc_s *) opaque;
506 uint32_t irq_mask = 1 << irq;
508 s->icsr |= irq_mask;
509 s->icpr |= irq_mask;
510 s->icpr &= ~s->icmr;
512 if (((~s->icmr) & irq_mask) && (level))
513 qemu_set_irq(s->parent_irq, 1);
514 else
515 qemu_set_irq(s->parent_irq, 0);
518 static qemu_irq *jz4740_intc_init(struct jz_state_s *soc, qemu_irq parent_irq)
520 int iomemtype;
521 struct jz4740_intc_s *s = (struct jz4740_intc_s *) qemu_mallocz(sizeof(*s));
522 s->base = JZ4740_PHYS_BASE(JZ4740_INTC_BASE);
523 s->parent_irq = parent_irq;
524 s->soc = soc;
526 jz4740_intc_reset(s);
528 iomemtype =
529 cpu_register_io_memory(0, jz4740_intc_readfn, jz4740_intc_writefn, s);
530 cpu_register_physical_memory(s->base, 0x00001000, iomemtype);
531 return qemu_allocate_irqs(jz4740_set_irq, s, 32);
534 /*external memory controller*/
535 struct jz4740_emc_s
537 qemu_irq irq;
538 target_phys_addr_t base;
539 struct jz_state_s *soc;
541 uint32_t smcr1; /*0x13010014 */
542 uint32_t smcr2; /*0x13010018 */
543 uint32_t smcr3; /*0x1301001c */
544 uint32_t smcr4; /*0x13010020 */
545 uint32_t sacr1; /*0x13010034 */
546 uint32_t sacr2; /*0x13010038 */
547 uint32_t sacr3; /*0x1301003c */
548 uint32_t sacr4; /*0x13010040 */
550 uint32_t nfcsr; /*0x13010050 */
551 uint32_t nfeccr; /*0x13010100 */
552 uint32_t nfecc; /*0x13010104 */
553 uint32_t nfpar0; /*0x13010108 */
554 uint32_t nfpar1; /*0x1301010c */
555 uint32_t nfpar2; /*0x13010110 */
556 uint32_t nfints; /*0x13010114 */
557 uint32_t nfinte; /*0x13010118 */
558 uint32_t nferr0; /*0x1301011c */
559 uint32_t nferr1; /*0x13010120 */
560 uint32_t nferr2; /*0x13010124 */
561 uint32_t nferr3; /*0x13010128 */
563 uint32_t dmcr; /*0x13010080 */
564 uint32_t rtcsr; /*0x13010084 */
565 uint32_t rtcnt; /*0x13010088 */
566 uint32_t rtcor; /*0x1301008c */
567 uint32_t dmar; /*0x13010090 */
568 uint32_t sdmr; /*0x1301a000 */
573 static void jz4740_emc_reset(struct jz4740_emc_s *s)
575 s->smcr1 = 0xfff7700;
576 s->smcr2 = 0xfff7700;
577 s->smcr3 = 0xfff7700;
578 s->smcr4 = 0xfff7700;
579 s->sacr1 = 0x18fc;
580 s->sacr2 = 0x16fe;
581 s->sacr3 = 0x14fe;
582 s->sacr4 = 0xcfc;
584 s->nfcsr = 0x0;
585 s->nfeccr = 0x0;
586 s->nfecc = 0x0;
587 s->nfpar0 = 0x0;
588 s->nfpar1 = 0x0;
589 s->nfpar2 = 0x0;
590 s->nfints = 0x0;
591 s->nfinte = 0x0;
592 s->nferr0 = 0x0;
593 s->nferr1 = 0x0;
594 s->nferr2 = 0x0;
595 s->nferr3 = 0x0;
597 s->dmcr = 0x0;
598 s->rtcsr = 0x0;
599 s->rtcnt = 0x0;
600 s->rtcor = 0x0;
601 s->dmar = 0x20f8;
602 s->sdmr = 0x0;
606 static uint32_t jz4740_emc_read8(void *opaque, target_phys_addr_t addr)
608 struct jz4740_emc_s *s = (struct jz4740_emc_s *) opaque;
609 int offset = addr - s->base;
610 switch (offset)
612 case 0x108:
613 case 0x109:
614 case 0x10a:
615 case 0x10b:
616 return (s->nfpar0 >> ((offset - 0x108) * 8)) & 0xff;
617 case 0x10c:
618 case 0x10d:
619 case 0x10e:
620 case 0x10f:
621 return (s->nfpar1 >> ((offset - 0x10c) * 8)) & 0xff;
622 case 0x110:
623 case 0x111:
624 case 0x112:
625 case 0x113:
626 return (s->nfpar2 >> ((offset - 0x110) * 8)) & 0xff;
627 case 0xa000:
628 case 0xa001:
629 case 0xa002:
630 case 0xa003:
631 return (s->sdmr >> ((offset - 0xa000) * 8)) & 0xff;
632 default:
633 cpu_abort(s->soc->env,
634 "jz4740_emc_read8 undefined addr " JZ_FMT_plx " \n", addr);
638 return (0);
641 static uint32_t jz4740_emc_read16(void *opaque, target_phys_addr_t addr)
643 struct jz4740_emc_s *s = (struct jz4740_emc_s *) opaque;
644 int offset = addr - s->base;
645 switch (offset)
647 case 0x108:
648 case 0x10a:
649 return (s->nfpar0 >> ((offset - 0x108) * 8)) & 0xffff;
650 case 0x10c:
651 case 0x10e:
652 return (s->nfpar1 >> ((offset - 0x10c) * 8)) & 0xffff;
653 case 0x110:
654 case 0x112:
655 return (s->nfpar2 >> ((offset - 0x110) * 8)) & 0xffff;
656 case 0x11c:
657 case 0x11e:
658 return (s->nferr0 >> ((offset - 0x11c) * 8)) & 0xffff;
659 case 0x120:
660 case 0x122:
661 return (s->nferr1 >> ((offset - 0x120) * 8)) & 0xffff;
662 case 0x124:
663 case 0x126:
664 return (s->nferr2 >> ((offset - 0x124) * 8)) & 0xffff;
665 case 0x128:
666 case 0x12a:
667 return (s->nferr3 >> ((offset - 0x128) * 8)) & 0xffff;
668 default:
669 cpu_abort(s->soc->env,
670 "jz4740_emc_read16 undefined addr " JZ_FMT_plx " \n", addr);
672 return (0);
675 static uint32_t jz4740_emc_read32(void *opaque, target_phys_addr_t addr)
677 struct jz4740_emc_s *s = (struct jz4740_emc_s *) opaque;
678 int offset = addr - s->base;
679 switch (offset)
681 case 0x14:
682 return s->smcr1;
683 case 0x18:
684 return s->smcr2;
685 case 0x1c:
686 return s->smcr3;
687 case 0x20:
688 return s->smcr4;
689 case 0x34:
690 return s->sacr1;
691 case 0x38:
692 return s->sacr2;
693 case 0x3c:
694 return s->sacr3;
695 case 0x40:
696 return s->sacr4;
697 case 0x50:
698 return s->nfcsr;
699 case 0x100:
700 return s->nfeccr;
701 case 0x104:
702 return s->nfecc;
703 case 0x108:
704 return s->nfpar0;
705 case 0x10c:
706 return s->nfpar1;
707 case 0x110:
708 return s->nfpar2;
709 case 0x114:
710 return s->nfints;
711 case 0x118:
712 return s->nfinte;
713 case 0x11c:
714 return s->nferr0;
715 case 0x120:
716 return s->nferr1;
717 case 0x124:
718 return s->nferr2;
719 case 0x128:
720 return s->nferr3;
721 case 0x80:
722 return s->dmcr;
723 case 0x90:
724 return s->dmar;
725 default:
726 cpu_abort(s->soc->env,
727 "jz4740_emc_read32 undefined addr " JZ_FMT_plx " \n", addr);
729 return (0);
732 static void jz4740_emc_write8(void *opaque, target_phys_addr_t addr,
733 uint32_t value)
735 struct jz4740_emc_s *s = (struct jz4740_emc_s *) opaque;
736 int offset = addr - s->base;
738 switch (offset)
740 case 0x108:
741 case 0x109:
742 case 0x10a:
743 case 0x10b:
744 s->nfpar0 |= (value & 0xff) << ((offset - 0x108) * 8);
745 break;
746 case 0x10c:
747 case 0x10d:
748 case 0x10e:
749 case 0x10f:
750 s->nfpar1 |= (value & 0xff) << ((offset - 0x10c) * 8);
751 break;
752 case 0x110:
753 case 0x111:
754 case 0x112:
755 case 0x113:
756 s->nfpar2 |= (value & 0xff) << ((offset - 0x110) * 8);
757 break;
758 case 0xa000:
759 case 0xa001:
760 case 0xa002:
761 case 0xa003:
762 s->sdmr |= (value & 0xff) << ((offset - 0x110) * 8);
763 break;
764 default:
765 cpu_abort(s->soc->env,
766 "jz4740_emc_write8 undefined addr " JZ_FMT_plx
767 " value %x \n", addr, value);
770 static void jz4740_emc_write16(void *opaque, target_phys_addr_t addr,
771 uint32_t value)
773 struct jz4740_emc_s *s = (struct jz4740_emc_s *) opaque;
774 int offset = addr - s->base;
776 switch (offset)
778 case 0x108:
779 case 0x10a:
780 s->nfpar0 |= (value & 0xffff) << ((offset - 0x108) * 8);
781 break;
782 case 0x10c:
783 case 0x10e:
784 s->nfpar1 |= (value & 0xffff) << ((offset - 0x10c) * 8);
785 break;
786 case 0x110:
787 case 0x112:
788 s->nfpar2 |= (value & 0xffff) << ((offset - 0x110) * 8);
789 break;
790 case 0x84:
791 case 0x86:
792 s->rtcsr |= (value & 0xffff) << ((offset - 0x84) * 8);
793 break;
794 case 0x88:
795 case 0x8a:
796 s->rtcnt |= (value & 0xffff) << ((offset - 0x88) * 8);
797 break;
798 case 0x8c:
799 s->rtcor |= (value & 0xffff) << ((offset - 0x8c) * 8);
800 break;
801 default:
802 cpu_abort(s->soc->env,
803 "jz4740_emc_write16 undefined addr " JZ_FMT_plx
804 " value %x \n", addr, value);
808 static void jz4740_emc_upate_interrupt(struct jz4740_emc_s *s)
810 qemu_set_irq(s->irq, s->nfints & s->nfinte);
813 static void jz4740_emc_write32(void *opaque, target_phys_addr_t addr,
814 uint32_t value)
816 struct jz4740_emc_s *s = (struct jz4740_emc_s *) opaque;
817 int offset = addr - s->base;
819 switch (offset)
821 case 0x104:
822 case 0x11c:
823 case 0x120:
824 case 0x124:
825 case 0x128:
826 JZ4740_RO_REG(addr);
827 break;
828 case 0x14:
829 s->smcr1 = value & 0xfff77cf;
830 break;
831 case 0x18:
832 s->smcr2 = value & 0xfff77cf;
833 break;
834 case 0x1c:
835 s->smcr3 = value & 0xfff77cf;
836 break;
837 case 0x20:
838 s->smcr4 = value & 0xfff77cf;
839 break;
840 case 0x34:
841 s->sacr1 = value & 0xffff;
842 break;
843 case 0x38:
844 s->sacr2 = value & 0xffff;
845 break;
846 case 0x3c:
847 s->sacr3 = value & 0xffff;
848 break;
849 case 0x40:
850 s->sacr4 = value & 0xffff;
851 break;
852 case 0x50:
853 s->nfcsr = value & 0xffff;
854 break;
855 case 0x100:
856 s->nfeccr = value & 0x1f;
857 if (s->nfeccr & 0x2)
859 s->nfecc = 0x0;
860 s->nfpar0 = 0x0;
861 s->nfpar1 = 0x0;
862 s->nfpar2 = 0x0;
863 s->nfints = 0x0;
864 s->nfinte = 0x0;
865 s->nferr0 = 0x0;
866 s->nferr1 = 0x0;
867 s->nferr2 = 0x0;
868 s->nferr3 = 0x0;
870 /*RS*/
871 /*TODO: Real RS error correction */
872 if (s->nfeccr & 0x4)
874 if ((s->nfeccr & 0x10) && (!(s->nfeccr & 0x8)))
876 /*decode */
877 s->nfints = 0x8;
878 s->nferr0 = 0x0;
879 s->nferr1 = 0x0;
880 s->nferr2 = 0x0;
882 if (s->nfeccr & 0x8)
884 /*encoding */
885 s->nfints = 0x4;
886 s->nfpar0 = 0xffffffff; /*fake value. for debug */
887 s->nfpar1 = 0xffffffff; /*fake value */
888 s->nfpar2 = 0xff; /*fake value */
891 else
893 s->nfecc = 0xffffff;
895 jz4740_emc_upate_interrupt(s);
896 break;
897 case 0x108:
898 s->nfpar0 = value;
899 break;
900 case 0x10c:
901 s->nfpar1 = value;
902 break;
903 case 0x110:
904 s->nfpar2 = value & 0xff;
905 break;
906 case 0x114:
907 s->nfints = value & 0x1fffffff;
908 jz4740_emc_upate_interrupt(s);
909 break;
910 case 0x118:
911 s->nfinte = value & 0x1f;
912 jz4740_emc_upate_interrupt(s);
913 break;
914 case 0x080:
915 s->dmcr = value & 0x9fbeff7f;
916 break;
917 case 0x90:
918 s->dmar = value & 0xffff;
919 break;
920 default:
921 cpu_abort(s->soc->env,
922 "jz4740_emc_write32 undefined addr " JZ_FMT_plx
923 " value %x \n", addr, value);
929 static CPUReadMemoryFunc *jz4740_emc_readfn[] = {
930 jz4740_emc_read8,
931 jz4740_emc_read16,
932 jz4740_emc_read32,
935 static CPUWriteMemoryFunc *jz4740_emc_writefn[] = {
936 jz4740_emc_write8,
937 jz4740_emc_write16,
938 jz4740_emc_write32,
942 static struct jz4740_emc_s *jz4740_emc_init(struct jz_state_s *soc, qemu_irq irq)
944 int iomemtype;
945 struct jz4740_emc_s *s = (struct jz4740_emc_s *) qemu_mallocz(sizeof(*s));
946 s->base = JZ4740_PHYS_BASE(JZ4740_EMC_BASE);
947 s->soc = soc;
948 s->irq = irq;
950 jz4740_emc_reset(s);
952 iomemtype =
953 cpu_register_io_memory(0, jz4740_emc_readfn, jz4740_emc_writefn, s);
954 cpu_register_physical_memory(s->base, 0x00010000, iomemtype);
955 return s;
960 static void jz4740_cpu_reset(void *opaque)
962 fprintf(stderr, "%s: UNIMPLEMENTED!", __FUNCTION__);
965 struct jz_state_s *jz4740_init(unsigned long sdram_size,
966 uint32_t osc_extal_freq)
968 struct jz_state_s *s = (struct jz_state_s *)
969 qemu_mallocz(sizeof(struct jz_state_s));
970 ram_addr_t sram_base, sdram_base;
971 qemu_irq *intc;
973 s->mpu_model = jz4740;
974 s->env = cpu_init("jz4740");
976 if (!s->env)
978 fprintf(stderr, "Unable to find CPU definition\n");
979 exit(1);
982 debug_init();
983 qemu_register_reset(jz4740_cpu_reset, s->env);
985 s->sdram_size = sdram_size;
986 s->sram_size = JZ4740_SRAM_SIZE;
988 /* Clocks */
989 jz_clk_init(s, osc_extal_freq);
991 /*map sram to 0x80000000 and sdram to 0x80004000 */
992 sram_base = qemu_ram_alloc(s->sram_size);
993 cpu_register_physical_memory(JZ4740_SRAM_BASE, s->sram_size,
994 (sram_base | IO_MEM_RAM));
995 sdram_base = qemu_ram_alloc(s->sdram_size);
996 cpu_register_physical_memory(JZ4740_SDRAM_BASE, s->sdram_size,
997 (sdram_base | IO_MEM_RAM));
999 /* Init internal devices */
1000 cpu_mips_irq_init_cpu(s->env);
1001 cpu_mips_clock_init(s->env);
1004 /* Clocks */
1005 jz_clk_init(s, osc_extal_freq);
1007 intc = jz4740_intc_init(s, s->env->irq[2]);
1008 s->cpm = jz4740_cpm_init(s);
1009 s->emc = jz4740_emc_init(s,intc[2]);
1011 return s;