From 7da12c7f22e24736270517596105e1fee2016127 Mon Sep 17 00:00:00 2001 From: yajin Date: Sun, 11 Jan 2009 04:19:08 +0800 Subject: [PATCH] 1.fix the new line issue(dos2unix) 2.add int controller emulation --- hw/mips_jz.c | 1061 +++++++++++++++++++++++++++++++----------------------- hw/mips_jz.h | 362 ++++++++++--------- hw/mips_jz_clk.c | 642 ++++++++++++++++----------------- hw/mips_pavo.c | 184 +++++----- 4 files changed, 1219 insertions(+), 1030 deletions(-) diff --git a/hw/mips_jz.c b/hw/mips_jz.c index 7d10afca7c..adf7ff1bec 100755 --- a/hw/mips_jz.c +++ b/hw/mips_jz.c @@ -1,443 +1,618 @@ -/* - * QEMU JZ Soc emulation - * - * Copyright (c) 2008 yajin (yajin@vm-kernel.org) - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - - -/* - * The emulation target is pavo demo board. - * http://www.ingenic.cn/eng/productServ/kfyd/Hardware/pffaqQuestionContent.aspx?Category=2&Question=3 - * - */ - -#include "hw.h" -#include "arm-misc.h" -#include "mips_jz.h" -#include "sysemu.h" -#include "qemu-timer.h" -#include "qemu-char.h" -#include "flash.h" -#include "soc_dma.h" -#include "audio/audio.h" - -#define DEBUG_CPM (1<<0x1) - -#define DEBUG_FLAG (DEBUG_CPM) - -#ifdef DEBUG - -FILE *fp; -static void debug_init() -{ - fp = fopen("jz4740.txt", "w+"); - if (fp == NULL) - { - fprintf(stderr, "can not open jz4740.txt \n"); - exit(-1); - } -} -static void debug_out(uint32_t flag, const char *format, ...) -{ - va_list ap; - if (fp) - { - if (flag & DEBUG_FLAG) - { - va_start(ap, format); - vfprintf(fp, format, ap); - fflush(fp); - va_end(ap); - } - } -} -#else -static void debug_init() -{ -} -static void debug_out(uint32_t flag, const char *format, ...) -{ -} -#endif - -uint32_t jz4740_badwidth_read8(void *opaque, target_phys_addr_t addr) -{ - uint8_t ret; - - JZ4740_8B_REG(addr); - cpu_physical_memory_read(addr, (void *) &ret, 1); - return ret; -} - -void jz4740_badwidth_write8(void *opaque, target_phys_addr_t addr, - uint32_t value) -{ - uint8_t val8 = value; - - JZ4740_8B_REG(addr); - cpu_physical_memory_write(addr, (void *) &val8, 1); -} - -uint32_t jz4740_badwidth_read16(void *opaque, target_phys_addr_t addr) -{ - uint16_t ret; - JZ4740_16B_REG(addr); - cpu_physical_memory_read(addr, (void *) &ret, 2); - return ret; -} - -void jz4740_badwidth_write16(void *opaque, target_phys_addr_t addr, - uint32_t value) -{ - uint16_t val16 = value; - - JZ4740_16B_REG(addr); - cpu_physical_memory_write(addr, (void *) &val16, 2); -} - -uint32_t jz4740_badwidth_read32(void *opaque, target_phys_addr_t addr) -{ - uint32_t ret; - - JZ4740_32B_REG(addr); - cpu_physical_memory_read(addr, (void *) &ret, 4); - return ret; -} - -void jz4740_badwidth_write32(void *opaque, target_phys_addr_t addr, - uint32_t value) -{ - JZ4740_32B_REG(addr); - cpu_physical_memory_write(addr, (void *) &value, 4); -} - - -/*clock reset and power control*/ -struct jz4740_cpm_s -{ - target_phys_addr_t base; - struct jz_state_s *cpu; - - uint32_t cpccr; - uint32_t cppcr; - uint32_t i2scdr; - uint32_t lpcdr; - uint32_t msccdr; - uint32_t uhccdr; - uint32_t uhctst; - uint32_t ssicdr; -}; - -static inline void jz4740_dump_clocks(struct clk *parent) -{ - struct clk *i = parent; - - debug_out(DEBUG_CPM, "clock %x rate 0x%x \n", i->name, i->rate); - for (i = clk->child1; i; i = i->sibling) - jz4740_dump_clocks(i); -} - -static inline void jz4740_cpccr_update(struct jz4740_cpm_s *s, - uint32_t new_value) -{ - uint32_t ldiv, mdiv, pdiv, hdiv, cdiv, udiv; - uint32_t div_table[10] = { 1, 2, 3, 4, 6, 8, 12, 16, 24, 32 }; - - if (unlikely(new_value == s->cpccr)) - return; - - if (new_value & CPM_CPCCR_PCS) - jz_clk_setrate(jz_findclk(s->cpu, "pll_divider"), 1, 1); - else - jz_clk_setrate(jz_findclk(s->cpu, "pll_divider"), 2, 1); - - - ldiv = (new_value & CPM_CPCCR_LDIV_MASK) >> CPM_CPCCR_LDIV_BIT; - ldiv++; - - mdiv = div_table[(new_value & CPM_CPCCR_MDIV_MASK) >> CPM_CPCCR_MDIV_BIT]; - pdiv = div_table[(new_value & CPM_CPCCR_PDIV_MASK) >> CPM_CPCCR_PDIV_BIT]; - hdiv = div_table[(new_value & CPM_CPCCR_HDIV_MASK) >> CPM_CPCCR_HDIV_BIT]; - cdiv = div_table[(new_value & CPM_CPCCR_CDIV_MASK) >> CPM_CPCCR_CDIV_BIT]; - udiv = div_table[(new_value & CPM_CPCCR_UDIV_MASK) >> CPM_CPCCR_UDIV_BIT]; - - jz_clk_setrate(jz_findclk(s->cpu, "ldclk"), ldiv, 1); - jz_clk_setrate(jz_findclk(s->cpu, "mclk"), mdiv, 1); - jz_clk_setrate(jz_findclk(s->cpu, "pclk"), pdiv, 1); - jz_clk_setrate(jz_findclk(s->cpu, "hclk"), hdiv, 1); - jz_clk_setrate(jz_findclk(s->cpu, "cclk"), cdiv, 1); - jz_clk_setrate(jz_findclk(s->cpu, "usbclk"), udiv, 1); - - if (new_value & CPM_CPCCR_UCS) - jz_clk_reparent(jz_findclk(s->cpu, "usbclk"), - jz_findclk(s->cpu, "pll_divider")); - else - jz_clk_reparent(jz_findclk(s->cpu, "usbclk"), - jz_findclk(s->cpu, "osc_extal")); - - if (new_value & CPM_CPCCR_I2CS) - jz_clk_reparent(jz_findclk(s->cpu, "i2sclk"), - jz_findclk(s->cpu, "pll_divider")); - else - jz_clk_reparent(jz_findclk(s->cpu, "i2sclk"), - jz_findclk(s->cpu, "osc_extal")); - - s->cpccr = new_value; - - debug_out(DEBUG_CPM, "write to cpccr 0x%x\n", new_value); - jz4740_dump_clocks(jz_findclk(s->cpu, "osc_extal")); - -} - -static inline void jz4740_cppcr_update(struct jz4740_cpm_s *s, - uint32_t new_value) -{ - uint32_t pllm, plln, pllod, pllbp, pllen, pllst, pllen, pllbp; - uint32_t pll0[4] = { 1, 2, 2, 4 }; - - - pllen = new_value & CPM_CPPCR_PLLEN; - pllbp = new_value & CPM_CPPCR_PLLBP; - if ((!pllen) || (pllen && pllbp)) - { - jz_clk_setrate(jz_findclk(s->cpu, "pll_output"), 1, 1); - debug_out(DEBUG_CPM, "pll is bypassed \n"); - s->cppcr = new_value | CPM_CPPCR_PLLS; - return; - } - - - pllm = (new_value & CPM_CPPCR_PLLM_MASK) >> CPM_CPPCR_PLLM_BIT; - plln = (new_value & CPM_CPPCR_PLLN_MASK) >> CPM_CPPCR_PLLN_BIT; - pllod = (new_value & CPM_CPPCR_PLLOD_MASK) >> CPM_CPPCR_PLLOD_BIT; - jz_clk_setrate(jz_findclk(s->cpu, "pll_output"), (plln + 2) * pll0[pllod], - pllm + 2); - - s->cppcr = new_value; - - debug_out(DEBUG_CPM, "write to cppcr 0x%x\n", new_value); - jz4740_dump_clocks(jz_findclk(s->cpu, "osc_extal")); - -} - -static inline void jz4740_i2scdr_update(struct jz4740_cpm_s *s, - uint32_t new_value) -{ - uint32_t i2scdr; - - i2scdr = new_value & CPM_I2SCDR_I2SDIV_MASK; - if (unlikely(i2scdr == s->i2scdr)) - return; - - - jz_clk_setrate(jz_findclk(s->cpu, "i2sclk"), i2scdr + 1, 1); - - s->i2scdr = i2scdr; - - debug_out(DEBUG_CPM, "write to i2scdr 0x%x\n", new_value); - jz4740_dump_clocks(jz_findclk(s->cpu, "osc_extal")); - -} - -static inline void jz4740_lpcdr_update(struct jz4740_cpm_s *s, - uint32_t new_value) -{ - uint32_t ipcdr; - - ipcdr = new_value & CPM_LPCDR_PIXDIV_MASK; - /*TODO: */ - s->lpcdr = ipcdr; -} - -static inline void jz4740_msccdr_update(struct jz4740_cpm_s *s, - uint32_t new_value) -{ - uint32_t msccdr; - - msccdr = new_value & CPM_MSCCDR_MSCDIV_MASK; - - if (unlikely(msccdr == s->msccdr)) - return; - - - jz_clk_setrate(jz_findclk(s->cpu, "mscclk"), msccdr + 1, 1); - - s->msccdr = msccdr; - - debug_out(DEBUG_CPM, "write to msccdr 0x%x\n", new_value); - jz4740_dump_clocks(jz_findclk(s->cpu, "osc_extal")); - -} - -static inline void jz4740_uhccdr_update(struct jz4740_cpm_s *s, - uint32_t new_value) -{ - uint32_t uhccdr; - - uhccdr = new_value & 0xf; - /*TODO: */ - s->uhccdr = uhccdr; -} - -static void jz4740_cpm_write(void *opaque, target_phys_addr_t addr, - uint32_t value) -{ - struct jz4740_cpm_s *s = (struct jz4740_cpm_s *) opaque; - int offset = addr - s->base; - - switch (offset) - { - case 0x0: - jz4740_cpccr_update(s, value); - break; - case 0x10: - jz4740_cppcr_update(s, value); - break; - case 0x60: - jz4740_i2scdr_update(s, value); - break; - case 0x64: - jz4740_lpcdr_update(s, value); - break; - case 0x68: - jz4740_msccdr_update(s, value); - break; - case 0x6c: - jz4740_uhccdr_update(s, value); - break; - case 0x70: - s->uhctst = value & 0x3f; - break; - case 0x74: - s->ssicdr = value & 0xf; - break; - default: - cpu_abort(s->cpu->env, - "jz4740_cpm_write undefined addr " JZ_FMT_plx " value %x \n", - addr, value); - } - -} - - -static uint32_t jz474_cpm_read(void *opaque, target_phys_addr_t addr) -{ - struct jz4740_cpm_s *s = (struct jz4740_cpm_s *) opaque; - int offset = addr - s->base; - - switch (offset) - { - case 0x0: - return s->cpccr; - case 0x10: - return s->cppcr; - case 0x60: - return s->i2scdr; - case 0x64: - return s->lpcdr; - case 0x68: - return s->msccdr; - case 0x6c: - return s->uhccdr; - case 0x70: - return s->uhctst; - case 0x74: - return s->ssicdr; - default: - cpu_abort(s->cpu->env, - "jz474_cpm_read undefined addr " JZ_FMT_plx " \n", addr); - } - -} - - - -static CPUReadMemoryFunc *jz4740_cpm_readfn[] = { - jz4740_badwidth_read32, - jz4740_badwidth_read32, - jz474_cpm_read, -}; - -static CPUWriteMemoryFunc *jz4740_cpm_writefn[] = { - jz4740_badwidth_write32, - jz4740_badwidth_write32, - jz4740_cpm_write, -}; - -static void jz4740_cpm_reset(struct jz4740_cpm_s *s) -{ - s->cpccr = 0x42040000; - s->cppcr = 0x28080011; - s->i2scdr = 0x00000004; - s->lpcdr = 0x00000004; - s->msccdr = 0x00000004; - s->uhccdr = 0x00000004; - s->uhctst = 0x0; - s->ssicdr = 0x00000004; -} - -struct jz4740_cpm_s *jz4740_cpm_init(struct jz_state_s *cpu) -{ - int iomemtype; - struct jz4740_cpm_s *s = (struct jz4740_cpm_s *) qemu_mallocz(sizeof(*s)); - s->base = JZ4740_PHYS_BASE(JZ4740_CPM_BASE); - - jz4740_cpm_reset(s); - - iomemtype = - cpu_register_io_memory(0, jz4740_cpm_readfn, jz4740_cpm_writefn, s); - cpu_register_physical_memory(s->base, 0x00001000, iomemtype); -} - - -struct jz_state_s *jz4740_init(unsigned long sdram_size, - DisplayState * ds, const char *core, - uint32_t osc_extal_freq) -{ - struct jz_state_s *s = (struct jz_state_s *) - qemu_mallocz(sizeof(struct jz_state_s)); - ram_addr_t sram_base, sdram_base; - - s->mpu_model = jz4740; - s->env = cpu_init("jz4740"); - if (!s->env) - { - fprintf(stderr, "Unable to find CPU definition\n"); - exit(1); - } - qemu_register_reset(main_cpu_reset, env); - - s->sdram_size = sdram_size; - s->sram_size = JZ4740_SRAM_SIZE; - - /* Clocks */ - jz_clk_init(s, osc_extal_freq); - - /*map sram to 0x80000000 and sdram to 0x80004000 */ - sram_base = qemu_ram_alloc(s->sram_size); - cpu_register_physical_memory(JZ4740_SRAM_BASE, s->sram_size, - (sram_base | IO_MEM_RAM)); - sdram_base = qemu_ram_alloc(s->sdram_size); - cpu_register_physical_memory(JZ4740_SDRAM_BASE, s->sdram_size, - (sdram_base | IO_MEM_RAM)); - - -} +/* + * QEMU JZ Soc emulation + * + * Copyright (c) 2008 yajin (yajin@vm-kernel.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + + +/* + * The emulation target is pavo demo board. + * http://www.ingenic.cn/eng/productServ/kfyd/Hardware/pffaqQuestionContent.aspx?Category=2&Question=3 + * + */ + +#include "hw.h" +#include "arm-misc.h" +#include "mips_jz.h" +#include "sysemu.h" +#include "qemu-timer.h" +#include "qemu-char.h" +#include "flash.h" +#include "soc_dma.h" +#include "audio/audio.h" + +#define DEBUG_CPM (1<<0x1) + +#define DEBUG_FLAG (DEBUG_CPM) + +#ifdef DEBUG + +FILE *fp; +static void debug_init() +{ + fp = fopen("jz4740.txt", "w+"); + if (fp == NULL) + { + fprintf(stderr, "can not open jz4740.txt \n"); + exit(-1); + } +} +static void debug_out(uint32_t flag, const char *format, ...) +{ + va_list ap; + if (fp) + { + if (flag & DEBUG_FLAG) + { + va_start(ap, format); + vfprintf(fp, format, ap); + fflush(fp); + va_end(ap); + } + } +} +#else +static void debug_init() +{ +} +static void debug_out(uint32_t flag, const char *format, ...) +{ +} +#endif + +uint32_t jz4740_badwidth_read8(void *opaque, target_phys_addr_t addr) +{ + uint8_t ret; + + JZ4740_8B_REG(addr); + cpu_physical_memory_read(addr, (void *) &ret, 1); + return ret; +} + +void jz4740_badwidth_write8(void *opaque, target_phys_addr_t addr, + uint32_t value) +{ + uint8_t val8 = value; + + JZ4740_8B_REG(addr); + cpu_physical_memory_write(addr, (void *) &val8, 1); +} + +uint32_t jz4740_badwidth_read16(void *opaque, target_phys_addr_t addr) +{ + uint16_t ret; + JZ4740_16B_REG(addr); + cpu_physical_memory_read(addr, (void *) &ret, 2); + return ret; +} + +void jz4740_badwidth_write16(void *opaque, target_phys_addr_t addr, + uint32_t value) +{ + uint16_t val16 = value; + + JZ4740_16B_REG(addr); + cpu_physical_memory_write(addr, (void *) &val16, 2); +} + +uint32_t jz4740_badwidth_read32(void *opaque, target_phys_addr_t addr) +{ + uint32_t ret; + + JZ4740_32B_REG(addr); + cpu_physical_memory_read(addr, (void *) &ret, 4); + return ret; +} + +void jz4740_badwidth_write32(void *opaque, target_phys_addr_t addr, + uint32_t value) +{ + JZ4740_32B_REG(addr); + cpu_physical_memory_write(addr, (void *) &value, 4); +} + + +/*clock reset and power control*/ +struct jz4740_cpm_s +{ + target_phys_addr_t base; + struct jz_state_s *soc; + + uint32_t cpccr; + uint32_t cppcr; + uint32_t i2scdr; + uint32_t lpcdr; + uint32_t msccdr; + uint32_t uhccdr; + uint32_t uhctst; + uint32_t ssicdr; +}; + +static inline void jz4740_dump_clocks(struct clk *parent) +{ + struct clk *i = parent; + + debug_out(DEBUG_CPM, "clock %x rate 0x%x \n", i->name, i->rate); + for (i = clk->child1; i; i = i->sibling) + jz4740_dump_clocks(i); +} + +static inline void jz4740_cpccr_update(struct jz4740_cpm_s *s, + uint32_t new_value) +{ + uint32_t ldiv, mdiv, pdiv, hdiv, cdiv, udiv; + uint32_t div_table[10] = { 1, 2, 3, 4, 6, 8, 12, 16, 24, 32 }; + + if (unlikely(new_value == s->cpccr)) + return; + + if (new_value & CPM_CPCCR_PCS) + jz_clk_setrate(jz_findclk(s->cpu, "pll_divider"), 1, 1); + else + jz_clk_setrate(jz_findclk(s->cpu, "pll_divider"), 2, 1); + + + ldiv = (new_value & CPM_CPCCR_LDIV_MASK) >> CPM_CPCCR_LDIV_BIT; + ldiv++; + + mdiv = div_table[(new_value & CPM_CPCCR_MDIV_MASK) >> CPM_CPCCR_MDIV_BIT]; + pdiv = div_table[(new_value & CPM_CPCCR_PDIV_MASK) >> CPM_CPCCR_PDIV_BIT]; + hdiv = div_table[(new_value & CPM_CPCCR_HDIV_MASK) >> CPM_CPCCR_HDIV_BIT]; + cdiv = div_table[(new_value & CPM_CPCCR_CDIV_MASK) >> CPM_CPCCR_CDIV_BIT]; + udiv = div_table[(new_value & CPM_CPCCR_UDIV_MASK) >> CPM_CPCCR_UDIV_BIT]; + + jz_clk_setrate(jz_findclk(s->cpu, "ldclk"), ldiv, 1); + jz_clk_setrate(jz_findclk(s->cpu, "mclk"), mdiv, 1); + jz_clk_setrate(jz_findclk(s->cpu, "pclk"), pdiv, 1); + jz_clk_setrate(jz_findclk(s->cpu, "hclk"), hdiv, 1); + jz_clk_setrate(jz_findclk(s->cpu, "cclk"), cdiv, 1); + jz_clk_setrate(jz_findclk(s->cpu, "usbclk"), udiv, 1); + + if (new_value & CPM_CPCCR_UCS) + jz_clk_reparent(jz_findclk(s->cpu, "usbclk"), + jz_findclk(s->cpu, "pll_divider")); + else + jz_clk_reparent(jz_findclk(s->cpu, "usbclk"), + jz_findclk(s->cpu, "osc_extal")); + + if (new_value & CPM_CPCCR_I2CS) + jz_clk_reparent(jz_findclk(s->cpu, "i2sclk"), + jz_findclk(s->cpu, "pll_divider")); + else + jz_clk_reparent(jz_findclk(s->cpu, "i2sclk"), + jz_findclk(s->cpu, "osc_extal")); + + s->cpccr = new_value; + + debug_out(DEBUG_CPM, "write to cpccr 0x%x\n", new_value); + jz4740_dump_clocks(jz_findclk(s->cpu, "osc_extal")); + +} + +static inline void jz4740_cppcr_update(struct jz4740_cpm_s *s, + uint32_t new_value) +{ + uint32_t pllm, plln, pllod, pllbp, pllen, pllst, pllen, pllbp; + uint32_t pll0[4] = { 1, 2, 2, 4 }; + + + pllen = new_value & CPM_CPPCR_PLLEN; + pllbp = new_value & CPM_CPPCR_PLLBP; + if ((!pllen) || (pllen && pllbp)) + { + jz_clk_setrate(jz_findclk(s->cpu, "pll_output"), 1, 1); + debug_out(DEBUG_CPM, "pll is bypassed \n"); + s->cppcr = new_value | CPM_CPPCR_PLLS; + return; + } + + + pllm = (new_value & CPM_CPPCR_PLLM_MASK) >> CPM_CPPCR_PLLM_BIT; + plln = (new_value & CPM_CPPCR_PLLN_MASK) >> CPM_CPPCR_PLLN_BIT; + pllod = (new_value & CPM_CPPCR_PLLOD_MASK) >> CPM_CPPCR_PLLOD_BIT; + jz_clk_setrate(jz_findclk(s->cpu, "pll_output"), (plln + 2) * pll0[pllod], + pllm + 2); + + s->cppcr = new_value; + + debug_out(DEBUG_CPM, "write to cppcr 0x%x\n", new_value); + jz4740_dump_clocks(jz_findclk(s->cpu, "osc_extal")); + +} + +static inline void jz4740_i2scdr_update(struct jz4740_cpm_s *s, + uint32_t new_value) +{ + uint32_t i2scdr; + + i2scdr = new_value & CPM_I2SCDR_I2SDIV_MASK; + if (unlikely(i2scdr == s->i2scdr)) + return; + + + jz_clk_setrate(jz_findclk(s->cpu, "i2sclk"), i2scdr + 1, 1); + + s->i2scdr = i2scdr; + + debug_out(DEBUG_CPM, "write to i2scdr 0x%x\n", new_value); + jz4740_dump_clocks(jz_findclk(s->cpu, "osc_extal")); + +} + +static inline void jz4740_lpcdr_update(struct jz4740_cpm_s *s, + uint32_t new_value) +{ + uint32_t ipcdr; + + ipcdr = new_value & CPM_LPCDR_PIXDIV_MASK; + /*TODO: */ + s->lpcdr = ipcdr; +} + +static inline void jz4740_msccdr_update(struct jz4740_cpm_s *s, + uint32_t new_value) +{ + uint32_t msccdr; + + msccdr = new_value & CPM_MSCCDR_MSCDIV_MASK; + + if (unlikely(msccdr == s->msccdr)) + return; + + + jz_clk_setrate(jz_findclk(s->cpu, "mscclk"), msccdr + 1, 1); + + s->msccdr = msccdr; + + debug_out(DEBUG_CPM, "write to msccdr 0x%x\n", new_value); + jz4740_dump_clocks(jz_findclk(s->cpu, "osc_extal")); + +} + +static inline void jz4740_uhccdr_update(struct jz4740_cpm_s *s, + uint32_t new_value) +{ + uint32_t uhccdr; + + uhccdr = new_value & 0xf; + /*TODO: */ + s->uhccdr = uhccdr; +} + +static void jz4740_cpm_write(void *opaque, target_phys_addr_t addr, + uint32_t value) +{ + struct jz4740_cpm_s *s = (struct jz4740_cpm_s *) opaque; + int offset = addr - s->base; + + switch (offset) + { + case 0x0: + jz4740_cpccr_update(s, value); + break; + case 0x10: + jz4740_cppcr_update(s, value); + break; + case 0x60: + jz4740_i2scdr_update(s, value); + break; + case 0x64: + jz4740_lpcdr_update(s, value); + break; + case 0x68: + jz4740_msccdr_update(s, value); + break; + case 0x6c: + jz4740_uhccdr_update(s, value); + break; + case 0x70: + s->uhctst = value & 0x3f; + break; + case 0x74: + s->ssicdr = value & 0xf; + break; + default: + cpu_abort(s->cpu->env, + "jz4740_cpm_write undefined addr " JZ_FMT_plx " value %x \n", + addr, value); + } + +} + + +static uint32_t jz474_cpm_read(void *opaque, target_phys_addr_t addr) +{ + struct jz4740_cpm_s *s = (struct jz4740_cpm_s *) opaque; + int offset = addr - s->base; + + switch (offset) + { + case 0x0: + return s->cpccr; + case 0x10: + return s->cppcr; + case 0x60: + return s->i2scdr; + case 0x64: + return s->lpcdr; + case 0x68: + return s->msccdr; + case 0x6c: + return s->uhccdr; + case 0x70: + return s->uhctst; + case 0x74: + return s->ssicdr; + default: + cpu_abort(s->cpu->env, + "jz474_cpm_read undefined addr " JZ_FMT_plx " \n", addr); + } + +} + + + +static CPUReadMemoryFunc *jz4740_cpm_readfn[] = { + jz4740_badwidth_read32, + jz4740_badwidth_read32, + jz474_cpm_read, +}; + +static CPUWriteMemoryFunc *jz4740_cpm_writefn[] = { + jz4740_badwidth_write32, + jz4740_badwidth_write32, + jz4740_cpm_write, +}; + +static void jz4740_cpm_reset(struct jz4740_cpm_s *s) +{ + s->cpccr = 0x42040000; + s->cppcr = 0x28080011; + s->i2scdr = 0x00000004; + s->lpcdr = 0x00000004; + s->msccdr = 0x00000004; + s->uhccdr = 0x00000004; + s->uhctst = 0x0; + s->ssicdr = 0x00000004; +} + +static struct jz4740_cpm_s *jz4740_cpm_init(struct jz_state_s *soc) +{ + int iomemtype; + struct jz4740_cpm_s *s = (struct jz4740_cpm_s *) qemu_mallocz(sizeof(*s)); + s->base = JZ4740_PHYS_BASE(JZ4740_CPM_BASE); + s->soc = soc; + + jz4740_cpm_reset(s); + + iomemtype = + cpu_register_io_memory(0, jz4740_cpm_readfn, jz4740_cpm_writefn, s); + cpu_register_physical_memory(s->base, 0x00001000, iomemtype); +} + + +/* JZ4740 interrupt controller + * It issues INT2 to MIPS + */ +struct jz4740_intc_s +{ + qemu_irq parent_irq; + + target_phys_addr_t base; + struct jz_state_s *soc; + + uint32_t icsr; + uint32_t icmr; + uint32_t icmsr; + uint32_t icmcr; + uint32_t icpr; +}; + +static uint32_t jz4740_intc_read(void *opaque, target_phys_addr_t addr) +{ + struct jz4740_intc_s *s = (struct jz4740_intc_s *) opaque; + int offset = addr - s->base; + switch (offset) + { + case 0x8: + case 0xc: + JZ4740_WO_REG(addr); + break; + case 0x0: + return s->icsr; + case 0x4: + return s->icmr; + case 0x10: + return s->icpr; + default: + cpu_abort(s->cpu->env, + "jz4740_intc_read undefined addr " JZ_FMT_plx " \n", addr); + + } +} + +static void jz4740_intc_write(void *opaque, target_phys_addr_t addr, + uint32_t value) +{ + struct jz4740_intc_s *s = (struct jz4740_intc_s *) opaque; + int offset = addr - s->base; + + switch (offset) + { + case 0x0: + case 0x10: + JZ4740_RO_REG(addr); + break; + case 0x4: + s->icmr = value ; + break; + case 0x8: + s->icmr |= value; + break; + case 0xc: + s->icmr &= ~value; + break; + default: + cpu_abort(s->cpu->env, + "jz4740_intc_write undefined addr value %x" JZ_FMT_plx " \n", + addr, value); + } +} + + +static CPUReadMemoryFunc *jz4740_intc_readfn[] = { + jz4740_badwidth_read32, + jz4740_badwidth_read32, + jz4740_intc_read, +}; + +static CPUWriteMemoryFunc *jz4740_intc_writefn[] = { + jz4740_badwidth_write32, + jz4740_badwidth_write32, + jz4740_intc_write, +}; + +static void jz4740_intc_reset(struct jz4740_intc_s *s) +{ + s->icsr = 0x0; + s->icmr = 0xffffffff; + s->icpr = 0x0; +} + +static void jz4740_set_irq(void *opaque, int irq, int level) +{ + struct jz4740_intc_s *s = (struct jz4740_intc_s *) opaque; + uint32_t irq_mask = 1<icsr |= irq_mask; + s->icpr |= irq_mask; + s->icpr &= ~s->icmr; + + if ((~s->icmr)&irq_mask) + qemu_set_irq(s->parent_irq,1); + else + qemu_set_irq(s->parent_irq,0); +} + +static qemu_irq *jz4740_intc_init(struct jz_state_s *soc,qemu_irq parent_irq) +{ + int iomemtype; + struct jz4740_intc_s *s = (struct jz4740_intc_s *) qemu_mallocz(sizeof(*s)); + s->base = JZ4740_PHYS_BASE(JZ4740_INTC_BASE); + s->parent_irq = parent_irq; + s->soc = soc; + + jz4740_intc_reset(s); + + iomemtype = + cpu_register_io_memory(0, jz4740_intc_readfn, jz4740_intc_writefn, s); + cpu_register_physical_memory(s->base, 0x00001000, iomemtype); + return qemu_allocate_irqs(jz4740_set_irq, s, 32); +} + +/*external memory controller*/ +struct jz4740_emc_s +{ + qemu_irq irq; + target_phys_addr_t base; + struct jz_state_s *soc; + + uint32_t smcr1; /*0x13010014*/ + uint32_t smcr2; /*0x13010018*/ + uint32_t smcr3; /*0x1301001c*/ + uint32_t smcr4; /*0x13010020*/ + uint32_t sacr1; /*0x13010034*/ + uint32_t sacr2; /*0x13010038*/ + uint32_t sacr3; /*0x1301003c*/ + uint32_t sacr4; /*0x13010040*/ + + uint32_t nfcsr; /*0x13010050*/ + uint32_t nfeccr; /*0x13010100*/ + uint32_t nfecc; /*0x13010104*/ + uint32_t nfpar0; /*0x13010108*/ + uint32_t nfpar1; /*0x1301010c*/ + uint32_t nfpar2; /*0x13010110*/ + uint32_t nfints; /*0x13010114*/ + uint32_t nfinte; /*0x13010118*/ + uint32_t nferr0; /*0x1301011c*/ + uint32_t nferr1; /*0x13010120*/ + uint32_t nferr2; /*0x13010124*/ + uint32_t nferr3; /*0x13010128*/ + + uint32_t dmcr; /*0x13010080*/ + uint32_t rtcsr; /*0x13010084*/ + uint32_t rtcnt; /*0x13010088*/ + uint32_t rtcor; /*0x1301008c*/ + uint32_t dmar; /*0x13010090*/ + uint32_t sdmr; /*0x1301a000*/ + +}; + +static void jz4740_emc_init(struct jz_state_s *soc,qemu_irq irq) +{ + +} + +struct jz_state_s *jz4740_init(unsigned long sdram_size, + uint32_t osc_extal_freq) +{ + struct jz_state_s *s = (struct jz_state_s *) + qemu_mallocz(sizeof(struct jz_state_s)); + ram_addr_t sram_base, sdram_base; + qemu_irq * intc; + + s->mpu_model = jz4740; + s->env = cpu_init("jz4740"); + + if (!s->env) + { + fprintf(stderr, "Unable to find CPU definition\n"); + exit(1); + } + qemu_register_reset(main_cpu_reset, env); + + s->sdram_size = sdram_size; + s->sram_size = JZ4740_SRAM_SIZE; + + /*map sram to 0x80000000 and sdram to 0x80004000 */ + sram_base = qemu_ram_alloc(s->sram_size); + cpu_register_physical_memory(JZ4740_SRAM_BASE, s->sram_size, + (sram_base | IO_MEM_RAM)); + sdram_base = qemu_ram_alloc(s->sdram_size); + cpu_register_physical_memory(JZ4740_SDRAM_BASE, s->sdram_size, + (sdram_base | IO_MEM_RAM)); + + /* Init internal devices */ + cpu_mips_irq_init_cpu(env); + cpu_mips_clock_init(env); + + + /* Clocks */ + jz_clk_init(s, osc_extal_freq); + + intc = jz4740_intc_init(s,s->env->irq[2]); + jz4740_cpm_init(s); + + + + + +} diff --git a/hw/mips_jz.h b/hw/mips_jz.h index bbdfcbda6a..960c20f90f 100755 --- a/hw/mips_jz.h +++ b/hw/mips_jz.h @@ -1,174 +1,188 @@ -/* - * ingenic JZ Soc - * - * Copyright (C) 2009 yajin - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 or - * (at your option) version 3 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ -#ifndef _MIPS_JZ_H_ -#define _MIPS_JZ_H_ - - - - - - -#define JZ4740_SRAM_SIZE 0x4000 -#define JZ4740_SRAM_BASE 0x80000000 -#define JZ4740_SDRAM_BASE 0x80004000 - -#define JZ4740_PHYS_BASE(a) ((a)-0xa0000000) - -#define JZ4740_CPM_BASE 0xB0000000 -#define JZ4740_INTC_BASE 0xB0001000 -#define JZ4740_TCU_BASE 0xB0002000 -#define JZ4740_WDT_BASE 0xB0002000 -#define JZ4740_RTC_BASE 0xB0003000 -#define JZ4740_GPIO_BASE 0xB0010000 -#define JZ4740_AIC_BASE 0xB0020000 -#define JZ4740_ICDC_BASE 0xB0020000 -#define JZ4740_MSC_BASE 0xB0021000 -#define JZ4740_UART0_BASE 0xB0030000 -#define JZ4740_I2C_BASE 0xB0042000 -#define JZ4740_SSI_BASE 0xB0043000 -#define JZ4740_SADC_BASE 0xB0070000 -#define JZ4740_EMC_BASE 0xB3010000 -#define JZ4740_DMAC_BASE 0xB3020000 -#define JZ4740_UHC_BASE 0xB3030000 -#define JZ4740_UDC_BASE 0xB3040000 -#define JZ4740_LCD_BASE 0xB3050000 -#define JZ4740_SLCD_BASE 0xB3050000 -#define JZ4740_CIM_BASE 0xB3060000 -#define JZ4740_ETH_BASE 0xB3100000 - -/* Clock Control Register */ -#define CPM_CPCCR_I2CS (1 << 31) -#define CPM_CPCCR_CLKOEN (1 << 30) -#define CPM_CPCCR_UCS (1 << 29) -#define CPM_CPCCR_UDIV_BIT 23 -#define CPM_CPCCR_UDIV_MASK (0x3f << CPM_CPCCR_UDIV_BIT) -#define CPM_CPCCR_CE (1 << 22) -#define CPM_CPCCR_PCS (1 << 21) -#define CPM_CPCCR_LDIV_BIT 16 -#define CPM_CPCCR_LDIV_MASK (0x1f << CPM_CPCCR_LDIV_BIT) -#define CPM_CPCCR_MDIV_BIT 12 -#define CPM_CPCCR_MDIV_MASK (0x0f << CPM_CPCCR_MDIV_BIT) -#define CPM_CPCCR_PDIV_BIT 8 -#define CPM_CPCCR_PDIV_MASK (0x0f << CPM_CPCCR_PDIV_BIT) -#define CPM_CPCCR_HDIV_BIT 4 -#define CPM_CPCCR_HDIV_MASK (0x0f << CPM_CPCCR_HDIV_BIT) -#define CPM_CPCCR_CDIV_BIT 0 -#define CPM_CPCCR_CDIV_MASK (0x0f << CPM_CPCCR_CDIV_BIT) - - -/* I2S Clock Divider Register */ -#define CPM_I2SCDR_I2SDIV_BIT 0 -#define CPM_I2SCDR_I2SDIV_MASK (0x1ff << CPM_I2SCDR_I2SDIV_BIT) - -/* LCD Pixel Clock Divider Register */ -#define CPM_LPCDR_PIXDIV_BIT 0 -#define CPM_LPCDR_PIXDIV_MASK (0x1ff << CPM_LPCDR_PIXDIV_BIT) - -/* MSC Clock Divider Register */ -#define CPM_MSCCDR_MSCDIV_BIT 0 -#define CPM_MSCCDR_MSCDIV_MASK (0x1f << CPM_MSCCDR_MSCDIV_BIT) - -/* PLL Control Register */ -#define CPM_CPPCR_PLLM_BIT 23 -#define CPM_CPPCR_PLLM_MASK (0x1ff << CPM_CPPCR_PLLM_BIT) -#define CPM_CPPCR_PLLN_BIT 18 -#define CPM_CPPCR_PLLN_MASK (0x1f << CPM_CPPCR_PLLN_BIT) -#define CPM_CPPCR_PLLOD_BIT 16 -#define CPM_CPPCR_PLLOD_MASK (0x03 << CPM_CPPCR_PLLOD_BIT) -#define CPM_CPPCR_PLLS (1 << 10) -#define CPM_CPPCR_PLLBP (1 << 9) -#define CPM_CPPCR_PLLEN (1 << 8) -#define CPM_CPPCR_PLLST_BIT 0 -#define CPM_CPPCR_PLLST_MASK (0xff << CPM_CPPCR_PLLST_BIT) - - - - - -#if TARGET_PHYS_ADDR_BITS == 32 -#define JZ_FMT_plx "%#08x" -#elif TARGET_PHYS_ADDR_BITS == 64 -#define JZ_FMT_plx "%#08" PRIx64 -#else -#error TARGET_PHYS_ADDR_BITS undefined -#endif - - -#define TCMI_VERBOSE 1 - -#ifdef TCMI_VERBOSE -#define JZ4740_8B_REG(paddr) \ - fprintf(stderr, "%s: 8-bit register " JZ_FMT_plx "\n", \ - __FUNCTION__, paddr) -#define JZ4740_16B_REG(paddr) \ - fprintf(stderr, "%s: 16-bit register " JZ_FMT_plx "\n", \ - __FUNCTION__, paddr) -#define JZ4740_32B_REG(paddr) \ - fprintf(stderr, "%s: 32-bit register " JZ_FMT_plx "\n", \ - __FUNCTION__, paddr) -# else -#define JZ4740_8B_REG(paddr) -#define JZ4740_16B_REG(paddr) -#define JZ4740_32B_REG(paddr) -#endif - - - -/*forward define*/ -struct jz_state_s; - - -/*mips_jz_clk.c*/ -typedef struct clk *jz_clk; -void jz_clk_init(struct jz_state_s *mpu,uint32_t osc_extal_freq); -jz_clk jz_findclk(struct jz_state_s *mpu, const char *name); -void jz_clk_get(jz_clk clk); -void jz_clk_put(jz_clk clk); -void jz_clk_onoff(jz_clk clk, int on); -void jz_clk_canidle(jz_clk clk, int can); -void jz_clk_setrate(jz_clk clk, int divide, int multiply); -int64_t jz_clk_getrate(jz_clk clk); -void jz_clk_reparent(jz_clk clk, jz_clk parent); - - - - - -enum jz_cpu_model { - jz4740, - jz4730, - jz4750 - }; -#define cpu_is_jz4730(cpu) (cpu->mpu_model == jz4730) -#define cpu_is_jz4740(cpu) (cpu->mpu_model == jz4740) -#define cpu_is_jz4750(cpu) (cpu->mpu_model == jz4750) - -struct jz_state_s { - enum jz_cpu_model mpu_model; - CPUState *env; - unsigned long sdram_size; - unsigned long sram_size; - - - jz_clk clks; -}; - -#endif +/* + * ingenic JZ Soc + * + * Copyright (C) 2009 yajin + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 or + * (at your option) version 3 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ +#ifndef _MIPS_JZ_H_ +#define _MIPS_JZ_H_ + + + + + + +#define JZ4740_SRAM_SIZE 0x4000 +#define JZ4740_SRAM_BASE 0x80000000 +#define JZ4740_SDRAM_BASE 0x80004000 + +#define JZ4740_PHYS_BASE(a) ((a)-0xa0000000) + +#define JZ4740_CPM_BASE 0xB0000000 +#define JZ4740_INTC_BASE 0xB0001000 +#define JZ4740_TCU_BASE 0xB0002000 +#define JZ4740_WDT_BASE 0xB0002000 +#define JZ4740_RTC_BASE 0xB0003000 +#define JZ4740_GPIO_BASE 0xB0010000 +#define JZ4740_AIC_BASE 0xB0020000 +#define JZ4740_ICDC_BASE 0xB0020000 +#define JZ4740_MSC_BASE 0xB0021000 +#define JZ4740_UART0_BASE 0xB0030000 +#define JZ4740_I2C_BASE 0xB0042000 +#define JZ4740_SSI_BASE 0xB0043000 +#define JZ4740_SADC_BASE 0xB0070000 +#define JZ4740_EMC_BASE 0xB3010000 +#define JZ4740_DMAC_BASE 0xB3020000 +#define JZ4740_UHC_BASE 0xB3030000 +#define JZ4740_UDC_BASE 0xB3040000 +#define JZ4740_LCD_BASE 0xB3050000 +#define JZ4740_SLCD_BASE 0xB3050000 +#define JZ4740_CIM_BASE 0xB3060000 +#define JZ4740_ETH_BASE 0xB3100000 + +/* Clock Control Register */ +#define CPM_CPCCR_I2CS (1 << 31) +#define CPM_CPCCR_CLKOEN (1 << 30) +#define CPM_CPCCR_UCS (1 << 29) +#define CPM_CPCCR_UDIV_BIT 23 +#define CPM_CPCCR_UDIV_MASK (0x3f << CPM_CPCCR_UDIV_BIT) +#define CPM_CPCCR_CE (1 << 22) +#define CPM_CPCCR_PCS (1 << 21) +#define CPM_CPCCR_LDIV_BIT 16 +#define CPM_CPCCR_LDIV_MASK (0x1f << CPM_CPCCR_LDIV_BIT) +#define CPM_CPCCR_MDIV_BIT 12 +#define CPM_CPCCR_MDIV_MASK (0x0f << CPM_CPCCR_MDIV_BIT) +#define CPM_CPCCR_PDIV_BIT 8 +#define CPM_CPCCR_PDIV_MASK (0x0f << CPM_CPCCR_PDIV_BIT) +#define CPM_CPCCR_HDIV_BIT 4 +#define CPM_CPCCR_HDIV_MASK (0x0f << CPM_CPCCR_HDIV_BIT) +#define CPM_CPCCR_CDIV_BIT 0 +#define CPM_CPCCR_CDIV_MASK (0x0f << CPM_CPCCR_CDIV_BIT) + + +/* I2S Clock Divider Register */ +#define CPM_I2SCDR_I2SDIV_BIT 0 +#define CPM_I2SCDR_I2SDIV_MASK (0x1ff << CPM_I2SCDR_I2SDIV_BIT) + +/* LCD Pixel Clock Divider Register */ +#define CPM_LPCDR_PIXDIV_BIT 0 +#define CPM_LPCDR_PIXDIV_MASK (0x1ff << CPM_LPCDR_PIXDIV_BIT) + +/* MSC Clock Divider Register */ +#define CPM_MSCCDR_MSCDIV_BIT 0 +#define CPM_MSCCDR_MSCDIV_MASK (0x1f << CPM_MSCCDR_MSCDIV_BIT) + +/* PLL Control Register */ +#define CPM_CPPCR_PLLM_BIT 23 +#define CPM_CPPCR_PLLM_MASK (0x1ff << CPM_CPPCR_PLLM_BIT) +#define CPM_CPPCR_PLLN_BIT 18 +#define CPM_CPPCR_PLLN_MASK (0x1f << CPM_CPPCR_PLLN_BIT) +#define CPM_CPPCR_PLLOD_BIT 16 +#define CPM_CPPCR_PLLOD_MASK (0x03 << CPM_CPPCR_PLLOD_BIT) +#define CPM_CPPCR_PLLS (1 << 10) +#define CPM_CPPCR_PLLBP (1 << 9) +#define CPM_CPPCR_PLLEN (1 << 8) +#define CPM_CPPCR_PLLST_BIT 0 +#define CPM_CPPCR_PLLST_MASK (0xff << CPM_CPPCR_PLLST_BIT) + + + + + +#if TARGET_PHYS_ADDR_BITS == 32 +#define JZ_FMT_plx "%#08x" +#elif TARGET_PHYS_ADDR_BITS == 64 +#define JZ_FMT_plx "%#08" PRIx64 +#else +#error TARGET_PHYS_ADDR_BITS undefined +#endif + + +#define IO_ACCESS_VERBOSE 1 + +#ifdef IO_ACCESS_VERBOSE +#define JZ4740_8B_REG(paddr) \ + fprintf(stderr, "%s: 8-bit register " JZ_FMT_plx "\n", \ + __FUNCTION__, paddr) +#define JZ4740_16B_REG(paddr) \ + fprintf(stderr, "%s: 16-bit register " JZ_FMT_plx "\n", \ + __FUNCTION__, paddr) +#define JZ4740_32B_REG(paddr) \ + fprintf(stderr, "%s: 32-bit register " JZ_FMT_plx "\n", \ + __FUNCTION__, paddr) +#define JZ4740_RO_REG(paddr) \ + fprintf(stderr, "%s: write to read only 32-bit register " JZ_FMT_plx "\n", \ + __FUNCTION__, paddr) +#define JZ4740_WO_REG(paddr) \ + fprintf(stderr, "%s: read from write only 32-bit register " JZ_FMT_plx "\n", \ + __FUNCTION__, paddr) +# else +#define JZ4740_8B_REG(paddr) +#define JZ4740_16B_REG(paddr) +#define JZ4740_32B_REG(paddr) +#define JZ4740_RO_REG(paddr) +#define JZ4740_WO_REG(paddr) +#endif + + + +/*forward define*/ +struct jz_state_s; + + +/*mips_jz_clk.c*/ +typedef struct clk *jz_clk; +void jz_clk_init(struct jz_state_s *mpu,uint32_t osc_extal_freq); +jz_clk jz_findclk(struct jz_state_s *mpu, const char *name); +void jz_clk_get(jz_clk clk); +void jz_clk_put(jz_clk clk); +void jz_clk_onoff(jz_clk clk, int on); +void jz_clk_canidle(jz_clk clk, int can); +void jz_clk_setrate(jz_clk clk, int divide, int multiply); +int64_t jz_clk_getrate(jz_clk clk); +void jz_clk_reparent(jz_clk clk, jz_clk parent); + +/*mips_jz.c*/ +struct jz_state_s *jz4740_init(unsigned long sdram_size, + uint32_t osc_extal_freq); +struct jz4740_cpm_s *jz4740_cpm_init(struct jz_state_s *soc); +qemu_irq *jz4740_intc_init(struct jz_state_s *soc,qemu_irq parent_irq); + + + + + +enum jz_cpu_model { + jz4740, + jz4730, + jz4750 + }; +#define cpu_is_jz4730(cpu) (cpu->mpu_model == jz4730) +#define cpu_is_jz4740(cpu) (cpu->mpu_model == jz4740) +#define cpu_is_jz4750(cpu) (cpu->mpu_model == jz4750) + +struct jz_state_s { + enum jz_cpu_model mpu_model; + CPUState *env; + unsigned long sdram_size; + unsigned long sram_size; + + + jz_clk clks; +}; + +#endif diff --git a/hw/mips_jz_clk.c b/hw/mips_jz_clk.c index fb39825dda..9b7e025caf 100755 --- a/hw/mips_jz_clk.c +++ b/hw/mips_jz_clk.c @@ -1,321 +1,321 @@ -/* - * JZ Soc clocks. - * - * Copyright (C) 2006-2008 yajin - * - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#include "hw.h" -#include "mips_jz.h" - - - -#define ALWAYS_ENABLED (1 << 0) -#define CLOCK_IN_JZ4730 (1 << 10) -#define CLOCK_IN_JZ4740 (1 << 11) -#define CLOCK_IN_JZ4750 (1 << 12) - - -struct clk { - const char *name; - const char *alias; - struct clk *parent; - struct clk *child1; - struct clk *sibling; - - uint32_t flags; - int id; - - int running; /* Is currently ticking */ - int enabled; /* Is enabled, regardless of its input clk */ - unsigned long rate; /* Current rate (if .running) */ - unsigned int divisor; /* Rate relative to input (if .enabled) */ - unsigned int multiplier; /* Rate relative to input (if .enabled) */ -}; - -static struct clk osc_extal = { - .name = "osc_extal_12M", - .rate = 12000000, - .flags = ALWAYS_ENABLED | CLOCK_IN_JZ4740, -}; - -static struct clk osc_32K = { - .name = "osc_32K", - .rate = 32768, - .flags = ALWAYS_ENABLED | CLOCK_IN_JZ4740, -}; - -static struct clk lcd_pclk = { - .name = "lcd_pclk", - //.rate = ??, - //.flags = ALWAYS_ENABLED | CLOCK_IN_JZ4740, -}; - -static struct clk pll_output = { - .name = "pll_output", - .parent = &osc_extal, - .flags = ALWAYS_ENABLED | CLOCK_IN_JZ4740, -}; - -static struct clk pll_divider= { - .name = "pll_divider", - .parent = &pll_output, - .flags = ALWAYS_ENABLED | CLOCK_IN_JZ4740, -}; - -static struct clk cclk= { - .name = "cclk", - .parent = &pll_output, - .flags = ALWAYS_ENABLED | CLOCK_IN_JZ4740, -}; - -static struct clk pclk= { - .name = "pclk", - .parent = &pll_output, - .flags = ALWAYS_ENABLED | CLOCK_IN_JZ4740, -}; - -static struct clk hclk= { - .name = "hclk", - .parent = &pll_output, - .flags = ALWAYS_ENABLED | CLOCK_IN_JZ4740, -}; - -static struct clk mclk= { - .name = "mclk", - .parent = &pll_output, - .flags = ALWAYS_ENABLED | CLOCK_IN_JZ4740, -}; - -static struct clk ldclk= { - .name = "ldclk", - .parent = &pll_divider, - .flags = ALWAYS_ENABLED | CLOCK_IN_JZ4740, -}; - -static struct clk lpclk= { - .name = "lpclk", - .parent = &pll_divider, - .flags = ALWAYS_ENABLED | CLOCK_IN_JZ4740, -}; - -static struct clk i2sclk= { - .name = "i2sclk", - .parent = &pll_divider, - .flags = ALWAYS_ENABLED | CLOCK_IN_JZ4740, -}; - -static struct clk mscclk= { - .name = "mscclk", - .parent = &pll_divider, - .flags = ALWAYS_ENABLED | CLOCK_IN_JZ4740, -}; - -static struct clk usbclk= { - .name = "usbclk", - .parent = &pll_divider, - .flags = ALWAYS_ENABLED | CLOCK_IN_JZ4740, -}; - -static struct clk ssiclk= { - .name = "ssiclk", - .parent = &pll_divider, - .flags = ALWAYS_ENABLED | CLOCK_IN_JZ4740, -}; - - -static struct clk *onchip_clks[] = { - &osc_extal, - &lcd_pclk, - &osc_32K, - &pll_output, - &pll_divider, - &cclk, - &pclk, - &hclk, - &mclk, - &ldclk, - &lpclk, - &i2sclk, - &mscclk, - &usbclk, - &ssiclk, -}; - -struct clk *jz_findclk(struct jz_state_s *cpu, const char *name) -{ - struct clk *i; - - for (i = cpu->clks; i->name; i ++) - if (!strcmp(i->name, name) || (i->alias && !strcmp(i->alias, name))) - return i; - cpu_abort(cpu->env, "%s: %s not found\n", __FUNCTION__, name); -} - -void jz_clk_get(struct clk *clk) -{ - clk->usecount ++; -} - -void jz_clk_put(struct clk *clk) -{ - if (!(clk->usecount --)) - cpu_abort(cpu_single_env, "%s: %s is not in use\n", - __FUNCTION__, clk->name); -} - -static void jz_clk_update(struct clk *clk) -{ - int parent, running; - //qemu_irq *user; - struct clk *i; - - if (clk->parent) - parent = clk->parent->running; - else - parent = 1; - - running = parent && (clk->enabled || - ((clk->flags & ALWAYS_ENABLED) && clk->usecount)); - if (clk->running != running) { - clk->running = running; - //for (user = clk->users; *user; user ++) - // qemu_set_irq(*user, running); - for (i = clk->child1; i; i = i->sibling) - jz_clk_update(i); - } -} - -static void jz_clk_rate_update_full(struct clk *clk, unsigned long int rate, - unsigned long int div, unsigned long int mult) -{ - struct clk *i; - //qemu_irq *user; - - clk->rate = muldiv64(rate, mult, div); - if (clk->running) - //for (user = clk->users; *user; user ++) - // qemu_irq_raise(*user); - for (i = clk->child1; i; i = i->sibling) - jz_clk_rate_update_full(i, rate, - div * i->divisor, mult * i->multiplier); -} - -static void jz_clk_rate_update(struct clk *clk) -{ - struct clk *i; - unsigned long int div, mult = div = 1; - - for (i = clk; i->parent; i = i->parent) { - div *= i->divisor; - mult *= i->multiplier; - } - - jz_clk_rate_update_full(clk, i->rate, div, mult); -} - -void jz_clk_reparent(struct clk *clk, struct clk *parent) -{ - struct clk **p; - - if (clk->parent) { - for (p = &clk->parent->child1; *p != clk; p = &(*p)->sibling); - *p = clk->sibling; - } - - clk->parent = parent; - if (parent) { - clk->sibling = parent->child1; - parent->child1 = clk; - jz_clk_update(clk); - jz_clk_rate_update(clk); - } else - clk->sibling = 0; -} - -void jz_clk_onoff(struct clk *clk, int on) -{ - clk->enabled = on; - jz_clk_update(clk); -} - -void jz_clk_canidle(struct clk *clk, int can) -{ - if (can) - jz_clk_put(clk); - else - jz_clk_get(clk); -} - -void jz_clk_setrate(struct clk *clk, int divide, int multiply) -{ - clk->divisor = divide; - clk->multiplier = multiply; - jz_clk_rate_update(clk); -} - -int64_t jz_clk_getrate(omap_clk clk) -{ - return clk->rate; -} - -void jz_clk_init(struct jz_state_s *mpu,uint32_t osc_extal_freq) -{ - struct clk **i, *j, *k; - int count; - int flag; - - if (cpu_is_jz4730(mpu)) - flag = CLOCK_IN_JZ4730; - else if (cpu_is_jz4740(mpu)) - flag = CLOCK_IN_JZ4740; - else if (cpu_is_jz4750(mpu)) - flag = CLOCK_IN_JZ4750; - else - return; - - osc_extal.rate = osc_extal_freq; - - for (i = onchip_clks, count = 0; *i; i ++) - if ((*i)->flags & flag) - count ++; - mpu->clks = (struct clk *) qemu_mallocz(sizeof(struct clk) * (count + 1)); - for (i = onchip_clks, j = mpu->clks; *i; i ++) - if ((*i)->flags & flag) { - memcpy(j, *i, sizeof(struct clk)); - for (k = mpu->clks; k < j; k ++) - if (j->parent && !strcmp(j->parent->name, k->name)) { - j->parent = k; - j->sibling = k->child1; - k->child1 = j; - } else if (k->parent && !strcmp(k->parent->name, j->name)) { - k->parent = j; - k->sibling = j->child1; - j->child1 = k; - } - j->divisor = j->divisor ?: 1; - j->multiplier = j->multiplier ?: 1; - j ++; - } - for (j = mpu->clks; count --; j ++) { - jz_clk_update(j); - jz_clk_rate_update(j); - } -} - - +/* + * JZ Soc clocks. + * + * Copyright (C) 2006-2008 yajin + * + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include "hw.h" +#include "mips_jz.h" + + + +#define ALWAYS_ENABLED (1 << 0) +#define CLOCK_IN_JZ4730 (1 << 10) +#define CLOCK_IN_JZ4740 (1 << 11) +#define CLOCK_IN_JZ4750 (1 << 12) + + +struct clk { + const char *name; + const char *alias; + struct clk *parent; + struct clk *child1; + struct clk *sibling; + + uint32_t flags; + int id; + + int running; /* Is currently ticking */ + int enabled; /* Is enabled, regardless of its input clk */ + unsigned long rate; /* Current rate (if .running) */ + unsigned int divisor; /* Rate relative to input (if .enabled) */ + unsigned int multiplier; /* Rate relative to input (if .enabled) */ +}; + +static struct clk osc_extal = { + .name = "osc_extal_12M", + .rate = 12000000, + .flags = ALWAYS_ENABLED | CLOCK_IN_JZ4740, +}; + +static struct clk osc_32K = { + .name = "osc_32K", + .rate = 32768, + .flags = ALWAYS_ENABLED | CLOCK_IN_JZ4740, +}; + +static struct clk lcd_pclk = { + .name = "lcd_pclk", + //.rate = ??, + //.flags = ALWAYS_ENABLED | CLOCK_IN_JZ4740, +}; + +static struct clk pll_output = { + .name = "pll_output", + .parent = &osc_extal, + .flags = ALWAYS_ENABLED | CLOCK_IN_JZ4740, +}; + +static struct clk pll_divider= { + .name = "pll_divider", + .parent = &pll_output, + .flags = ALWAYS_ENABLED | CLOCK_IN_JZ4740, +}; + +static struct clk cclk= { + .name = "cclk", + .parent = &pll_output, + .flags = ALWAYS_ENABLED | CLOCK_IN_JZ4740, +}; + +static struct clk pclk= { + .name = "pclk", + .parent = &pll_output, + .flags = ALWAYS_ENABLED | CLOCK_IN_JZ4740, +}; + +static struct clk hclk= { + .name = "hclk", + .parent = &pll_output, + .flags = ALWAYS_ENABLED | CLOCK_IN_JZ4740, +}; + +static struct clk mclk= { + .name = "mclk", + .parent = &pll_output, + .flags = ALWAYS_ENABLED | CLOCK_IN_JZ4740, +}; + +static struct clk ldclk= { + .name = "ldclk", + .parent = &pll_divider, + .flags = ALWAYS_ENABLED | CLOCK_IN_JZ4740, +}; + +static struct clk lpclk= { + .name = "lpclk", + .parent = &pll_divider, + .flags = ALWAYS_ENABLED | CLOCK_IN_JZ4740, +}; + +static struct clk i2sclk= { + .name = "i2sclk", + .parent = &pll_divider, + .flags = ALWAYS_ENABLED | CLOCK_IN_JZ4740, +}; + +static struct clk mscclk= { + .name = "mscclk", + .parent = &pll_divider, + .flags = ALWAYS_ENABLED | CLOCK_IN_JZ4740, +}; + +static struct clk usbclk= { + .name = "usbclk", + .parent = &pll_divider, + .flags = ALWAYS_ENABLED | CLOCK_IN_JZ4740, +}; + +static struct clk ssiclk= { + .name = "ssiclk", + .parent = &pll_divider, + .flags = ALWAYS_ENABLED | CLOCK_IN_JZ4740, +}; + + +static struct clk *onchip_clks[] = { + &osc_extal, + &lcd_pclk, + &osc_32K, + &pll_output, + &pll_divider, + &cclk, + &pclk, + &hclk, + &mclk, + &ldclk, + &lpclk, + &i2sclk, + &mscclk, + &usbclk, + &ssiclk, +}; + +struct clk *jz_findclk(struct jz_state_s *cpu, const char *name) +{ + struct clk *i; + + for (i = cpu->clks; i->name; i ++) + if (!strcmp(i->name, name) || (i->alias && !strcmp(i->alias, name))) + return i; + cpu_abort(cpu->env, "%s: %s not found\n", __FUNCTION__, name); +} + +void jz_clk_get(struct clk *clk) +{ + clk->usecount ++; +} + +void jz_clk_put(struct clk *clk) +{ + if (!(clk->usecount --)) + cpu_abort(cpu_single_env, "%s: %s is not in use\n", + __FUNCTION__, clk->name); +} + +static void jz_clk_update(struct clk *clk) +{ + int parent, running; + //qemu_irq *user; + struct clk *i; + + if (clk->parent) + parent = clk->parent->running; + else + parent = 1; + + running = parent && (clk->enabled || + ((clk->flags & ALWAYS_ENABLED) && clk->usecount)); + if (clk->running != running) { + clk->running = running; + //for (user = clk->users; *user; user ++) + // qemu_set_irq(*user, running); + for (i = clk->child1; i; i = i->sibling) + jz_clk_update(i); + } +} + +static void jz_clk_rate_update_full(struct clk *clk, unsigned long int rate, + unsigned long int div, unsigned long int mult) +{ + struct clk *i; + //qemu_irq *user; + + clk->rate = muldiv64(rate, mult, div); + if (clk->running) + //for (user = clk->users; *user; user ++) + // qemu_irq_raise(*user); + for (i = clk->child1; i; i = i->sibling) + jz_clk_rate_update_full(i, rate, + div * i->divisor, mult * i->multiplier); +} + +static void jz_clk_rate_update(struct clk *clk) +{ + struct clk *i; + unsigned long int div, mult = div = 1; + + for (i = clk; i->parent; i = i->parent) { + div *= i->divisor; + mult *= i->multiplier; + } + + jz_clk_rate_update_full(clk, i->rate, div, mult); +} + +void jz_clk_reparent(struct clk *clk, struct clk *parent) +{ + struct clk **p; + + if (clk->parent) { + for (p = &clk->parent->child1; *p != clk; p = &(*p)->sibling); + *p = clk->sibling; + } + + clk->parent = parent; + if (parent) { + clk->sibling = parent->child1; + parent->child1 = clk; + jz_clk_update(clk); + jz_clk_rate_update(clk); + } else + clk->sibling = 0; +} + +void jz_clk_onoff(struct clk *clk, int on) +{ + clk->enabled = on; + jz_clk_update(clk); +} + +void jz_clk_canidle(struct clk *clk, int can) +{ + if (can) + jz_clk_put(clk); + else + jz_clk_get(clk); +} + +void jz_clk_setrate(struct clk *clk, int divide, int multiply) +{ + clk->divisor = divide; + clk->multiplier = multiply; + jz_clk_rate_update(clk); +} + +int64_t jz_clk_getrate(omap_clk clk) +{ + return clk->rate; +} + +void jz_clk_init(struct jz_state_s *mpu,uint32_t osc_extal_freq) +{ + struct clk **i, *j, *k; + int count; + int flag; + + if (cpu_is_jz4730(mpu)) + flag = CLOCK_IN_JZ4730; + else if (cpu_is_jz4740(mpu)) + flag = CLOCK_IN_JZ4740; + else if (cpu_is_jz4750(mpu)) + flag = CLOCK_IN_JZ4750; + else + return; + + osc_extal.rate = osc_extal_freq; + + for (i = onchip_clks, count = 0; *i; i ++) + if ((*i)->flags & flag) + count ++; + mpu->clks = (struct clk *) qemu_mallocz(sizeof(struct clk) * (count + 1)); + for (i = onchip_clks, j = mpu->clks; *i; i ++) + if ((*i)->flags & flag) { + memcpy(j, *i, sizeof(struct clk)); + for (k = mpu->clks; k < j; k ++) + if (j->parent && !strcmp(j->parent->name, k->name)) { + j->parent = k; + j->sibling = k->child1; + k->child1 = j; + } else if (k->parent && !strcmp(k->parent->name, j->name)) { + k->parent = j; + k->sibling = j->child1; + j->child1 = k; + } + j->divisor = j->divisor ?: 1; + j->multiplier = j->multiplier ?: 1; + j ++; + } + for (j = mpu->clks; count --; j ++) { + jz_clk_update(j); + jz_clk_rate_update(j); + } +} + + diff --git a/hw/mips_pavo.c b/hw/mips_pavo.c index ced3fa60a4..433518ba76 100755 --- a/hw/mips_pavo.c +++ b/hw/mips_pavo.c @@ -1,92 +1,92 @@ -/* - * QEMU pavo demo board emulation - * - * Copyright (c) 2008 yajin (yajin@vm-kernel.org) - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - - -/* - * The emulation target is pavo demo board. - * http://www.ingenic.cn/eng/productServ/kfyd/Hardware/pffaqQuestionContent.aspx?Category=2&Question=3 - * - */ - -#include "mips_jz.h" -#include "qemu-common.h" -#include "sysemu.h" -#include "arm-misc.h" -#include "irq.h" -#include "console.h" -#include "boards.h" -#include "i2c.h" -#include "devices.h" -#include "flash.h" -#include "hw.h" - - - -#define PAVO_RAM_SIZE (0x4000000) /*64M */ - - -/* pavo board support */ -struct mips_pavo_s -{ - struct jz_state_s *cpu; -}; - - - - - - - - - -static - void mips_pvao_init(ram_addr_t ram_size, int vga_ram_size, - const char *boot_device, DisplayState * ds, - const char *kernel_filename, const char *kernel_cmdline, - const char *initrd_filename, const char *cpu_model) -{ - struct mips_pavo_s *s = (struct mips_pavo_s *) qemu_mallocz(sizeof(*s)); - - if (ram_size < PAVO_RAM_SIZE + JZ4740_SRAM_SIZE) - { - fprintf(stderr, "This architecture uses %i bytes of memory\n", - PAVO_RAM_SIZE + JZ4740_SRAM_SIZE); - exit(1); - } - s->cpu = jz4740_init(PAVO_RAM_SIZE, NULL, NULL); - -} - - - - -QEMUMachine mips_pavo_machine = { - .name = "pvao", - .desc = "JZ Pavo demo board", - .init = mips_pvao_init, - .ram_require = (JZ4740_SRAM_SIZE + PAVO_RAM_SIZE) | RAMSIZE_FIXED, - .nodisk_ok = 1, -}; - - +/* + * QEMU pavo demo board emulation + * + * Copyright (c) 2008 yajin (yajin@vm-kernel.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + + +/* + * The emulation target is pavo demo board. + * http://www.ingenic.cn/eng/productServ/kfyd/Hardware/pffaqQuestionContent.aspx?Category=2&Question=3 + * + */ + +#include "mips_jz.h" +#include "qemu-common.h" +#include "sysemu.h" +#include "arm-misc.h" +#include "irq.h" +#include "console.h" +#include "boards.h" +#include "i2c.h" +#include "devices.h" +#include "flash.h" +#include "hw.h" + + + +#define PAVO_RAM_SIZE (0x4000000) /*64M */ +#define PAVO_OSC_EXTAL (12000000) /*12MHZ*/ + +/* pavo board support */ +struct mips_pavo_s +{ + struct jz_state_s *soc; +}; + + + + + + + + + +static + void mips_pvao_init(ram_addr_t ram_size, int vga_ram_size, + const char *boot_device, DisplayState * ds, + const char *kernel_filename, const char *kernel_cmdline, + const char *initrd_filename, const char *cpu_model) +{ + struct mips_pavo_s *s = (struct mips_pavo_s *) qemu_mallocz(sizeof(*s)); + + if (ram_size < PAVO_RAM_SIZE + JZ4740_SRAM_SIZE) + { + fprintf(stderr, "This architecture uses %i bytes of memory\n", + PAVO_RAM_SIZE + JZ4740_SRAM_SIZE); + exit(1); + } + s->soc = jz4740_init(PAVO_RAM_SIZE, PAVO_OSC_EXTAL); + +} + + + + +QEMUMachine mips_pavo_machine = { + .name = "pvao", + .desc = "JZ Pavo demo board", + .init = mips_pvao_init, + .ram_require = (JZ4740_SRAM_SIZE + PAVO_RAM_SIZE) | RAMSIZE_FIXED, + .nodisk_ok = 1, +}; + + -- 2.11.4.GIT