diff options
author | aurel32 <aurel32@c046a42c-6fe2-441c-8c8c-71466251a162> | 2008-08-22 08:57:43 +0000 |
---|---|---|
committer | aurel32 <aurel32@c046a42c-6fe2-441c-8c8c-71466251a162> | 2008-08-22 08:57:43 +0000 |
commit | 29e179bc3f5e804ab58b975e65c91cb9cd287846 (patch) | |
tree | 8d423830def55b045ecc213cabb25cda6a78a6a3 /hw | |
parent | 274a9e70de095240c8013c9dd9980213d54198d0 (diff) |
[sh4] memory mapped TLB entries
SH4 MMU's memory mapped TLB feature is implemented.
SH-Linux seems to write to memory mapped TLB to invalidate a TLB entry,
but does not to read it. So only memory write feature is implemented.
Work on memory read feature is left.
(Shin-ichiro KAWASAKI)
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@5067 c046a42c-6fe2-441c-8c8c-71466251a162
Diffstat (limited to 'hw')
-rw-r--r-- | hw/sh7750.c | 110 |
1 files changed, 110 insertions, 0 deletions
diff --git a/hw/sh7750.c b/hw/sh7750.c index a76e6d4d3c..0ff3e6d778 100644 --- a/hw/sh7750.c +++ b/hw/sh7750.c @@ -30,6 +30,7 @@ #include "sh7750_regs.h" #include "sh7750_regnames.h" #include "sh_intc.h" +#include "cpu.h" #define NB_DEVICES 4 @@ -532,10 +533,113 @@ static struct intc_group groups_pci[] = { #define SH_CPU_SH7750_ALL (SH_CPU_SH7750 | SH_CPU_SH7750S | SH_CPU_SH7750R) #define SH_CPU_SH7751_ALL (SH_CPU_SH7751 | SH_CPU_SH7751R) +/********************************************************************** + Memory mapped cache and TLB +**********************************************************************/ + +#define MM_REGION_MASK 0x07000000 +#define MM_ICACHE_ADDR (0) +#define MM_ICACHE_DATA (1) +#define MM_ITLB_ADDR (2) +#define MM_ITLB_DATA (3) +#define MM_OCACHE_ADDR (4) +#define MM_OCACHE_DATA (5) +#define MM_UTLB_ADDR (6) +#define MM_UTLB_DATA (7) +#define MM_REGION_TYPE(addr) ((addr & MM_REGION_MASK) >> 24) + +static uint32_t invalid_read(void *opaque, target_phys_addr_t addr) +{ + assert(0); + + return 0; +} + +static uint32_t sh7750_mmct_readl(void *opaque, target_phys_addr_t addr) +{ + uint32_t ret = 0; + + switch (MM_REGION_TYPE(addr)) { + case MM_ICACHE_ADDR: + case MM_ICACHE_DATA: + /* do nothing */ + break; + case MM_ITLB_ADDR: + case MM_ITLB_DATA: + /* XXXXX */ + assert(0); + break; + case MM_OCACHE_ADDR: + case MM_OCACHE_DATA: + /* do nothing */ + break; + case MM_UTLB_ADDR: + case MM_UTLB_DATA: + /* XXXXX */ + assert(0); + break; + default: + assert(0); + } + + return ret; +} + +static void invalid_write(void *opaque, target_phys_addr_t addr, + uint32_t mem_value) +{ + assert(0); +} + +static void sh7750_mmct_writel(void *opaque, target_phys_addr_t addr, + uint32_t mem_value) +{ + SH7750State *s = opaque; + + switch (MM_REGION_TYPE(addr)) { + case MM_ICACHE_ADDR: + case MM_ICACHE_DATA: + /* do nothing */ + break; + case MM_ITLB_ADDR: + case MM_ITLB_DATA: + /* XXXXX */ + assert(0); + break; + case MM_OCACHE_ADDR: + case MM_OCACHE_DATA: + /* do nothing */ + break; + case MM_UTLB_ADDR: + cpu_sh4_write_mmaped_utlb_addr(s->cpu, addr, mem_value); + break; + case MM_UTLB_DATA: + /* XXXXX */ + assert(0); + break; + default: + assert(0); + break; + } +} + +static CPUReadMemoryFunc *sh7750_mmct_read[] = { + invalid_read, + invalid_read, + sh7750_mmct_readl +}; + +static CPUWriteMemoryFunc *sh7750_mmct_write[] = { + invalid_write, + invalid_write, + sh7750_mmct_writel +}; + SH7750State *sh7750_init(CPUSH4State * cpu) { SH7750State *s; int sh7750_io_memory; + int sh7750_mm_cache_and_tlb; /* memory mapped cache and tlb */ int cpu_model = SH_CPU_SH7751R; /* for now */ s = qemu_mallocz(sizeof(SH7750State)); @@ -546,6 +650,12 @@ SH7750State *sh7750_init(CPUSH4State * cpu) sh7750_mem_write, s); cpu_register_physical_memory(0x1c000000, 0x04000000, sh7750_io_memory); + sh7750_mm_cache_and_tlb = cpu_register_io_memory(0, + sh7750_mmct_read, + sh7750_mmct_write, s); + cpu_register_physical_memory(0xf0000000, 0x08000000, + sh7750_mm_cache_and_tlb); + sh_intc_init(&s->intc, NR_SOURCES, _INTC_ARRAY(mask_registers), _INTC_ARRAY(prio_registers)); |