From c2432a42fe13c3c6774f5443ac8f6f7261fe91d1 Mon Sep 17 00:00:00 2001 From: aurel32 Date: Sat, 7 Feb 2009 15:18:14 +0000 Subject: [PATCH] SH7750/51: add register BCR3, BCR4, PCR, RTCOR, RTCNT, RTCSR, SDMR2, SDMR3 and fix BCR2 support Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD Signed-off-by: Aurelien Jarno git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@6548 c046a42c-6fe2-441c-8c8c-71466251a162 --- hw/sh7750.c | 52 ++++++++++++++++++++++++++++++++++-------- hw/sh7750_regnames.c | 4 ++-- hw/sh7750_regs.h | 13 +++++++++-- target-sh4/cpu.h | 1 + target-sh4/translate.c | 2 ++ 5 files changed, 58 insertions(+), 14 deletions(-) diff --git a/hw/sh7750.c b/hw/sh7750.c index 4d1a806510..423c43ff12 100644 --- a/hw/sh7750.c +++ b/hw/sh7750.c @@ -42,8 +42,12 @@ typedef struct SH7750State { uint32_t periph_freq; /* SDRAM controller */ uint32_t bcr1; - uint32_t bcr2; + uint16_t bcr2; + uint16_t bcr3; + uint32_t bcr4; uint16_t rfcr; + /* PCMCIA controller */ + uint16_t pcr; /* IO ports */ uint16_t gpioic; uint32_t pctra; @@ -66,7 +70,10 @@ typedef struct SH7750State { struct intc_desc intc; } SH7750State; - +static int inline has_bcr3_and_bcr4(SH7750State * s) +{ + return (s->cpu->features & SH_FEATURE_BCR3_AND_BCR4); +} /********************************************************************** I/O ports **********************************************************************/ @@ -211,8 +218,14 @@ static uint32_t sh7750_mem_readw(void *opaque, target_phys_addr_t addr) switch (addr) { case SH7750_BCR2_A7: return s->bcr2; + case SH7750_BCR3_A7: + if(!has_bcr3_and_bcr4(s)) + error_access("word read", addr); + return s->bcr3; case SH7750_FRQCR_A7: return 0; + case SH7750_PCR_A7: + return s->pcr; case SH7750_RFCR_A7: fprintf(stderr, "Read access to refresh count register, incrementing\n"); @@ -221,6 +234,11 @@ static uint32_t sh7750_mem_readw(void *opaque, target_phys_addr_t addr) return porta_lines(s); case SH7750_PDTRB_A7: return portb_lines(s); + case SH7750_RTCOR_A7: + case SH7750_RTCNT_A7: + case SH7750_RTCSR_A7: + ignore_access("word read", addr); + return 0; default: error_access("word read", addr); assert(0); @@ -235,6 +253,9 @@ static uint32_t sh7750_mem_readl(void *opaque, target_phys_addr_t addr) case SH7750_BCR1_A7: return s->bcr1; case SH7750_BCR4_A7: + if(!has_bcr3_and_bcr4(s)) + error_access("long read", addr); + return s->bcr4; case SH7750_WCR1_A7: case SH7750_WCR2_A7: case SH7750_WCR3_A7: @@ -271,19 +292,19 @@ static uint32_t sh7750_mem_readl(void *opaque, target_phys_addr_t addr) } } +#define is_in_sdrmx(a, x) (a >= SH7750_SDMR ## x ## _A7 \ + && a <= (SH7750_SDMR ## x ## _A7 + SH7750_SDMR ## x ## _REGNB)) static void sh7750_mem_writeb(void *opaque, target_phys_addr_t addr, uint32_t mem_value) { - switch (addr) { - /* PRECHARGE ? XXXXX */ - case SH7750_PRECHARGE0_A7: - case SH7750_PRECHARGE1_A7: + + if (is_in_sdrmx(addr, 2) || is_in_sdrmx(addr, 3)) { ignore_access("byte write", addr); return; - default: - error_access("byte write", addr); - assert(0); } + + error_access("byte write", addr); + assert(0); } static void sh7750_mem_writew(void *opaque, target_phys_addr_t addr, @@ -298,8 +319,15 @@ static void sh7750_mem_writew(void *opaque, target_phys_addr_t addr, s->bcr2 = mem_value; return; case SH7750_BCR3_A7: - case SH7750_RTCOR_A7: + if(!has_bcr3_and_bcr4(s)) + error_access("word write", addr); + s->bcr3 = mem_value; + return; + case SH7750_PCR_A7: + s->pcr = mem_value; + return; case SH7750_RTCNT_A7: + case SH7750_RTCOR_A7: case SH7750_RTCSR_A7: ignore_access("word write", addr); return; @@ -343,6 +371,10 @@ static void sh7750_mem_writel(void *opaque, target_phys_addr_t addr, s->bcr1 = mem_value; return; case SH7750_BCR4_A7: + if(!has_bcr3_and_bcr4(s)) + error_access("long write", addr); + s->bcr4 = mem_value; + return; case SH7750_WCR1_A7: case SH7750_WCR2_A7: case SH7750_WCR3_A7: diff --git a/hw/sh7750_regnames.c b/hw/sh7750_regnames.c index 3ee5c7f15b..d4b519da9e 100644 --- a/hw/sh7750_regnames.c +++ b/hw/sh7750_regnames.c @@ -80,8 +80,8 @@ static regname_t regnames[] = { REGNAME(SH7750_ICR_A7) REGNAME(SH7750_BCR3_A7) REGNAME(SH7750_BCR4_A7) - REGNAME(SH7750_PRECHARGE0_A7) - REGNAME(SH7750_PRECHARGE1_A7) {(uint32_t) - 1, 0} + REGNAME(SH7750_SDMR2_A7) + REGNAME(SH7750_SDMR3_A7) {(uint32_t) - 1, 0} }; const char *regname(uint32_t addr) diff --git a/hw/sh7750_regs.h b/hw/sh7750_regs.h index c8fb328100..5a23a2ca20 100644 --- a/hw/sh7750_regs.h +++ b/hw/sh7750_regs.h @@ -979,6 +979,17 @@ #define SH7750_RFCR_KEY 0xA400 /* RFCR write key */ +/* Synchronous DRAM mode registers - SDMR */ +#define SH7750_SDMR2_REGOFS 0x900000 /* base offset */ +#define SH7750_SDMR2_REGNB 0x0FFC /* nb of register */ +#define SH7750_SDMR2 SH7750_P4_REG32(SH7750_SDMR2_REGOFS) +#define SH7750_SDMR2_A7 SH7750_A7_REG32(SH7750_SDMR2_REGOFS) + +#define SH7750_SDMR3_REGOFS 0x940000 /* offset */ +#define SH7750_SDMR3_REGNB 0x0FFC /* nb of register */ +#define SH7750_SDMR3 SH7750_P4_REG32(SH7750_SDMR3_REGOFS) +#define SH7750_SDMR3_A7 SH7750_A7_REG32(SH7750_SDMR3_REGOFS) + /* * Direct Memory Access Controller (DMAC) */ @@ -1262,7 +1273,5 @@ */ #define SH7750_BCR3_A7 0x1f800050 #define SH7750_BCR4_A7 0x1e0a00f0 -#define SH7750_PRECHARGE0_A7 0x1f900088 -#define SH7750_PRECHARGE1_A7 0x1f940088 #endif diff --git a/target-sh4/cpu.h b/target-sh4/cpu.h index 623eacc0a6..86a4a6ba31 100644 --- a/target-sh4/cpu.h +++ b/target-sh4/cpu.h @@ -95,6 +95,7 @@ typedef struct tlb_t { enum sh_features { SH_FEATURE_SH4A = 1, + SH_FEATURE_BCR3_AND_BCR4 = 2, }; typedef struct CPUSH4State { diff --git a/target-sh4/translate.c b/target-sh4/translate.c index 80ea851116..a0ee4f1ba3 100644 --- a/target-sh4/translate.c +++ b/target-sh4/translate.c @@ -222,12 +222,14 @@ static sh4_def_t sh4_defs[] = { .pvr = 0x00050000, .prr = 0x00000100, .cvr = 0x00110000, + .features = SH_FEATURE_BCR3_AND_BCR4, }, { .name = "SH7751R", .id = SH_CPU_SH7751R, .pvr = 0x04050005, .prr = 0x00000113, .cvr = 0x00110000, /* Neutered caches, should be 0x20480000 */ + .features = SH_FEATURE_BCR3_AND_BCR4, }, { .name = "SH7785", .id = SH_CPU_SH7785,