filename | src/sh4/mmu.h |
changeset | 1067:d3c00ffccfcd |
prev | 963:1c3a0f67c603 |
prev | 946:d41ee7994db7 |
next | 1217:677b1d85f1b4 |
author | nkeynes |
date | Tue Dec 15 08:46:37 2009 +1000 (14 years ago) |
permissions | -rw-r--r-- |
last change | Add side-by-side x86+sh4 disassembly output Print SH4 state information and disassembly of the current block when crashing. Fix delay slot instruction in conditional branch not being marked as a delay-slot instruction in the branch-not-taken path. Rename REG_* defines in cpu.h to avoid conflict with translation defs |
file | annotate | diff | log | raw |
nkeynes@931 | 1 | /** |
nkeynes@931 | 2 | * $Id$ |
nkeynes@931 | 3 | * |
nkeynes@931 | 4 | * MMU/TLB definitions. |
nkeynes@931 | 5 | * |
nkeynes@931 | 6 | * Copyright (c) 2005 Nathan Keynes. |
nkeynes@931 | 7 | * |
nkeynes@931 | 8 | * This program is free software; you can redistribute it and/or modify |
nkeynes@931 | 9 | * it under the terms of the GNU General Public License as published by |
nkeynes@931 | 10 | * the Free Software Foundation; either version 2 of the License, or |
nkeynes@931 | 11 | * (at your option) any later version. |
nkeynes@931 | 12 | * |
nkeynes@931 | 13 | * This program is distributed in the hope that it will be useful, |
nkeynes@931 | 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
nkeynes@931 | 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
nkeynes@931 | 16 | * GNU General Public License for more details. |
nkeynes@931 | 17 | */ |
nkeynes@931 | 18 | |
nkeynes@931 | 19 | |
nkeynes@931 | 20 | #ifndef lxdream_sh4_mmu_H |
nkeynes@931 | 21 | #define lxdream_sh4_mmu_H 1 |
nkeynes@931 | 22 | |
nkeynes@931 | 23 | #include "lxdream.h" |
nkeynes@931 | 24 | |
nkeynes@931 | 25 | #ifdef __cplusplus |
nkeynes@931 | 26 | extern "C" { |
nkeynes@931 | 27 | #endif |
nkeynes@931 | 28 | |
nkeynes@931 | 29 | #define VMA_TO_EXT_ADDR(vma) ((vma)&0x1FFFFFFF) |
nkeynes@931 | 30 | |
nkeynes@931 | 31 | /************************** UTLB/ITLB Definitions ***************************/ |
nkeynes@939 | 32 | /* mmucr register bits */ |
nkeynes@939 | 33 | #define MMUCR_AT 0x00000001 /* Address Translation enabled */ |
nkeynes@939 | 34 | #define MMUCR_TI 0x00000004 /* TLB invalidate (always read as 0) */ |
nkeynes@939 | 35 | #define MMUCR_SV 0x00000100 /* Single Virtual mode=1 / multiple virtual=0 */ |
nkeynes@939 | 36 | #define MMUCR_SQMD 0x00000200 /* Store queue mode bit (0=user, 1=priv only) */ |
nkeynes@939 | 37 | #define MMUCR_URC 0x0000FC00 /* UTLB access counter */ |
nkeynes@939 | 38 | #define MMUCR_URB 0x00FC0000 /* UTLB entry boundary */ |
nkeynes@939 | 39 | #define MMUCR_LRUI 0xFC000000 /* Least recently used ITLB */ |
nkeynes@939 | 40 | #define MMUCR_MASK 0xFCFCFF05 |
nkeynes@939 | 41 | #define MMUCR_RMASK 0xFCFCFF01 /* Read mask */ |
nkeynes@939 | 42 | |
nkeynes@939 | 43 | #define IS_TLB_ENABLED() (MMIO_READ(MMU, MMUCR)&MMUCR_AT) |
nkeynes@939 | 44 | #define IS_SV_ENABLED() (MMIO_READ(MMU,MMUCR)&MMUCR_SV) |
nkeynes@939 | 45 | |
nkeynes@931 | 46 | #define ITLB_ENTRY_COUNT 4 |
nkeynes@931 | 47 | #define UTLB_ENTRY_COUNT 64 |
nkeynes@931 | 48 | |
nkeynes@931 | 49 | /* Entry address */ |
nkeynes@931 | 50 | #define TLB_VALID 0x00000100 |
nkeynes@931 | 51 | #define TLB_USERMODE 0x00000040 |
nkeynes@931 | 52 | #define TLB_WRITABLE 0x00000020 |
nkeynes@931 | 53 | #define TLB_USERWRITABLE (TLB_WRITABLE|TLB_USERMODE) |
nkeynes@931 | 54 | #define TLB_SIZE_MASK 0x00000090 |
nkeynes@931 | 55 | #define TLB_SIZE_1K 0x00000000 |
nkeynes@931 | 56 | #define TLB_SIZE_4K 0x00000010 |
nkeynes@931 | 57 | #define TLB_SIZE_64K 0x00000080 |
nkeynes@931 | 58 | #define TLB_SIZE_1M 0x00000090 |
nkeynes@931 | 59 | #define TLB_CACHEABLE 0x00000008 |
nkeynes@931 | 60 | #define TLB_DIRTY 0x00000004 |
nkeynes@931 | 61 | #define TLB_SHARE 0x00000002 |
nkeynes@931 | 62 | #define TLB_WRITETHRU 0x00000001 |
nkeynes@931 | 63 | |
nkeynes@931 | 64 | #define MASK_1K 0xFFFFFC00 |
nkeynes@931 | 65 | #define MASK_4K 0xFFFFF000 |
nkeynes@931 | 66 | #define MASK_64K 0xFFFF0000 |
nkeynes@931 | 67 | #define MASK_1M 0xFFF00000 |
nkeynes@931 | 68 | |
nkeynes@931 | 69 | struct itlb_entry { |
nkeynes@931 | 70 | sh4addr_t vpn; // Virtual Page Number |
nkeynes@931 | 71 | uint32_t asid; // Process ID |
nkeynes@931 | 72 | uint32_t mask; |
nkeynes@931 | 73 | sh4addr_t ppn; // Physical Page Number |
nkeynes@931 | 74 | uint32_t flags; |
nkeynes@931 | 75 | }; |
nkeynes@931 | 76 | |
nkeynes@931 | 77 | struct utlb_entry { |
nkeynes@931 | 78 | sh4addr_t vpn; // Virtual Page Number |
nkeynes@931 | 79 | uint32_t mask; // Page size mask |
nkeynes@931 | 80 | uint32_t asid; // Process ID |
nkeynes@931 | 81 | sh4addr_t ppn; // Physical Page Number |
nkeynes@931 | 82 | uint32_t flags; |
nkeynes@939 | 83 | uint32_t pcmcia; // extra pcmcia data - not used in this implementation |
nkeynes@931 | 84 | }; |
nkeynes@931 | 85 | |
nkeynes@939 | 86 | #define TLB_FUNC_SIZE 48 |
nkeynes@939 | 87 | |
nkeynes@939 | 88 | struct utlb_page_entry { |
nkeynes@939 | 89 | struct mem_region_fn fn; |
nkeynes@946 | 90 | struct mem_region_fn *user_fn; |
nkeynes@939 | 91 | mem_region_fn_t target; |
nkeynes@946 | 92 | unsigned char code[TLB_FUNC_SIZE*9]; |
nkeynes@931 | 93 | }; |
nkeynes@939 | 94 | |
nkeynes@939 | 95 | struct utlb_1k_entry { |
nkeynes@939 | 96 | struct mem_region_fn fn; |
nkeynes@939 | 97 | struct mem_region_fn user_fn; |
nkeynes@939 | 98 | struct mem_region_fn *subpages[4]; |
nkeynes@939 | 99 | struct mem_region_fn *user_subpages[4]; |
nkeynes@946 | 100 | unsigned char code[TLB_FUNC_SIZE*18]; |
nkeynes@939 | 101 | }; |
nkeynes@939 | 102 | |
nkeynes@946 | 103 | struct utlb_default_regions { |
nkeynes@946 | 104 | mem_region_fn_t tlb_miss; |
nkeynes@946 | 105 | mem_region_fn_t tlb_prot; |
nkeynes@946 | 106 | mem_region_fn_t tlb_multihit; |
nkeynes@946 | 107 | }; |
nkeynes@946 | 108 | |
nkeynes@963 | 109 | sh4addr_t FASTCALL mmu_vma_to_phys_disasm( sh4vma_t vma ); |
nkeynes@946 | 110 | |
nkeynes@939 | 111 | void mmu_utlb_init_vtable( struct utlb_entry *ent, struct utlb_page_entry *page, gboolean writable ); |
nkeynes@939 | 112 | void mmu_utlb_1k_init_vtable( struct utlb_1k_entry *ent ); |
nkeynes@946 | 113 | void mmu_utlb_init_storequeue_vtable( struct utlb_entry *ent, struct utlb_page_entry *page ); |
nkeynes@939 | 114 | |
nkeynes@939 | 115 | extern uint32_t mmu_urc; |
nkeynes@939 | 116 | extern uint32_t mmu_urb; |
nkeynes@945 | 117 | |
nkeynes@945 | 118 | /** Primary SH4 address space (privileged and user access) |
nkeynes@945 | 119 | * Page map (4KB) of the entire 32-bit address space |
nkeynes@945 | 120 | * Note: only callable from the SH4 cores as it depends on the caller setting |
nkeynes@945 | 121 | * up an appropriate exception environment. |
nkeynes@945 | 122 | **/ |
nkeynes@945 | 123 | extern struct mem_region_fn **sh4_address_space; |
nkeynes@945 | 124 | extern struct mem_region_fn **sh4_user_address_space; |
nkeynes@945 | 125 | |
nkeynes@946 | 126 | /************ Storequeue/cache functions ***********/ |
nkeynes@946 | 127 | void FASTCALL ccn_storequeue_write_long( sh4addr_t addr, uint32_t val ); |
nkeynes@946 | 128 | int32_t FASTCALL ccn_storequeue_read_long( sh4addr_t addr ); |
nkeynes@946 | 129 | |
nkeynes@946 | 130 | /** Default storequeue prefetch when TLB is disabled */ |
nkeynes@946 | 131 | void FASTCALL ccn_storequeue_prefetch( sh4addr_t addr ); |
nkeynes@946 | 132 | |
nkeynes@946 | 133 | /** TLB-enabled variant of the storequeue prefetch */ |
nkeynes@946 | 134 | void FASTCALL ccn_storequeue_prefetch_tlb( sh4addr_t addr ); |
nkeynes@946 | 135 | |
nkeynes@946 | 136 | /** Non-storequeue prefetch */ |
nkeynes@946 | 137 | void FASTCALL ccn_prefetch( sh4addr_t addr ); |
nkeynes@946 | 138 | |
nkeynes@946 | 139 | /** Non-cached prefetch (ie, no-op) */ |
nkeynes@946 | 140 | void FASTCALL ccn_uncached_prefetch( sh4addr_t addr ); |
nkeynes@946 | 141 | |
nkeynes@946 | 142 | |
nkeynes@946 | 143 | extern struct mem_region_fn mem_region_address_error; |
nkeynes@946 | 144 | extern struct mem_region_fn mem_region_tlb_miss; |
nkeynes@946 | 145 | extern struct mem_region_fn mem_region_tlb_multihit; |
nkeynes@946 | 146 | extern struct mem_region_fn mem_region_tlb_protected; |
nkeynes@946 | 147 | |
nkeynes@946 | 148 | extern struct mem_region_fn p4_region_storequeue; |
nkeynes@946 | 149 | extern struct mem_region_fn p4_region_storequeue_multihit; |
nkeynes@946 | 150 | extern struct mem_region_fn p4_region_storequeue_miss; |
nkeynes@946 | 151 | extern struct mem_region_fn p4_region_storequeue_protected; |
nkeynes@946 | 152 | extern struct mem_region_fn p4_region_storequeue_sqmd; |
nkeynes@946 | 153 | extern struct mem_region_fn p4_region_storequeue_sqmd_miss; |
nkeynes@946 | 154 | extern struct mem_region_fn p4_region_storequeue_sqmd_multihit; |
nkeynes@946 | 155 | extern struct mem_region_fn p4_region_storequeue_sqmd_protected; |
nkeynes@945 | 156 | |
nkeynes@931 | 157 | #ifdef __cplusplus |
nkeynes@931 | 158 | } |
nkeynes@931 | 159 | #endif |
nkeynes@931 | 160 | #endif /* !lxdream_sh4_mmu_H */ |
.