X-Git-Url: https://repo.jachan.dev/qemu.git/blobdiff_plain/80e1b265f4505149ba256ab6e18be942830072d0..d6a6922f3bebbf95e2d5194a9cb8a21e3d5ddfdd:/target-cris/mmu.c diff --git a/target-cris/mmu.c b/target-cris/mmu.c index 9ae398db6d..512e28b481 100644 --- a/target-cris/mmu.c +++ b/target-cris/mmu.c @@ -15,28 +15,23 @@ * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * License along with this library; if not, see . */ #ifndef CONFIG_USER_ONLY -#include -#include -#include - -#include "config.h" #include "cpu.h" #include "mmu.h" -#include "exec-all.h" #ifdef DEBUG #define D(x) x +#define D_LOG(...) qemu_log(__VA_ARGS__) #else -#define D(x) +#define D(x) do { } while (0) +#define D_LOG(...) do { } while (0) #endif -void cris_mmu_init(CPUState *env) +void cris_mmu_init(CPUCRISState *env) { env->mmu_rand_lfsr = 0xcccc; } @@ -54,6 +49,17 @@ static inline unsigned int compute_polynom(unsigned int sr) return f; } +static void cris_mmu_update_rand_lfsr(CPUCRISState *env) +{ + unsigned int f; + + /* Update lfsr at every fault. */ + f = compute_polynom(env->mmu_rand_lfsr); + env->mmu_rand_lfsr >>= 1; + env->mmu_rand_lfsr |= (f << 15); + env->mmu_rand_lfsr &= 0xffff; +} + static inline int cris_mmu_enabled(uint32_t rw_gc_cfg) { return (rw_gc_cfg & 12) != 0; @@ -64,7 +70,7 @@ static inline int cris_mmu_segmented_addr(int seg, uint32_t rw_mm_cfg) return (1 << seg) & rw_mm_cfg; } -static uint32_t cris_mmu_translate_seg(CPUState *env, int seg) +static uint32_t cris_mmu_translate_seg(CPUCRISState *env, int seg) { uint32_t base; int i; @@ -100,7 +106,7 @@ static inline void set_field(uint32_t *dst, unsigned int val, } #ifdef DEBUG -static void dump_tlb(CPUState *env, int mmu) +static void dump_tlb(CPUCRISState *env, int mmu) { int set; int idx; @@ -121,9 +127,9 @@ static void dump_tlb(CPUState *env, int mmu) #endif /* rw 0 = read, 1 = write, 2 = exec. */ -static int cris_mmu_translate_page(struct cris_mmu_result_t *res, - CPUState *env, uint32_t vaddr, - int rw, int usermode) +static int cris_mmu_translate_page(struct cris_mmu_result *res, + CPUCRISState *env, uint32_t vaddr, + int rw, int usermode, int debug) { unsigned int vpage; unsigned int idx; @@ -180,9 +186,8 @@ static int cris_mmu_translate_page(struct cris_mmu_result_t *res, tlb_pid = EXTRACT_FIELD(hi, 0, 7); tlb_g = EXTRACT_FIELD(lo, 4, 4); - D(fprintf(logfile, - "TLB[%d][%d][%d] v=%x vpage=%x lo=%x hi=%x\n", - mmu, set, idx, tlb_vpn, vpage, lo, hi)); + D_LOG("TLB[%d][%d][%d] v=%x vpage=%x lo=%x hi=%x\n", + mmu, set, idx, tlb_vpn, vpage, lo, hi); if ((tlb_g || (tlb_pid == pid)) && tlb_vpn == vpage) { match = 1; @@ -240,7 +245,7 @@ static int cris_mmu_translate_page(struct cris_mmu_result_t *res, res->prot |= PAGE_READ; if (tlb_w) res->prot |= PAGE_WRITE; - if (tlb_x) + if (mmu == 0 && (cfg_x || tlb_x)) res->prot |= PAGE_EXEC; } else @@ -250,15 +255,9 @@ static int cris_mmu_translate_page(struct cris_mmu_result_t *res, set = env->mmu_rand_lfsr & 3; } - if (!match) { - unsigned int f; + if (!match && !debug) { + cris_mmu_update_rand_lfsr(env); - /* Update lfsr at every fault. */ - f = compute_polynom(env->mmu_rand_lfsr); - env->mmu_rand_lfsr >>= 1; - env->mmu_rand_lfsr |= (f << 15); - env->mmu_rand_lfsr &= 0xffff; - /* Compute index. */ idx = vpage & 15; @@ -289,7 +288,7 @@ static int cris_mmu_translate_page(struct cris_mmu_result_t *res, return !match; } -void cris_mmu_flush_pid(CPUState *env, uint32_t pid) +void cris_mmu_flush_pid(CPUCRISState *env, uint32_t pid) { target_ulong vaddr; unsigned int idx; @@ -314,9 +313,8 @@ void cris_mmu_flush_pid(CPUState *env, uint32_t pid) if (tlb_v && !tlb_g && (tlb_pid == pid)) { vaddr = tlb_vpn << TARGET_PAGE_BITS; - D(fprintf(logfile, - "flush pid=%x vaddr=%x\n", - pid, vaddr)); + D_LOG("flush pid=%x vaddr=%x\n", + pid, vaddr); tlb_flush_page(env, vaddr); } } @@ -324,11 +322,10 @@ void cris_mmu_flush_pid(CPUState *env, uint32_t pid) } } -int cris_mmu_translate(struct cris_mmu_result_t *res, - CPUState *env, uint32_t vaddr, - int rw, int mmu_idx) +int cris_mmu_translate(struct cris_mmu_result *res, + CPUCRISState *env, uint32_t vaddr, + int rw, int mmu_idx, int debug) { - uint32_t phy = vaddr; int seg; int miss = 0; int is_user = mmu_idx == MMU_USER_IDX; @@ -346,18 +343,18 @@ int cris_mmu_translate(struct cris_mmu_result_t *res, } seg = vaddr >> 28; - if (cris_mmu_segmented_addr(seg, env->sregs[SFR_RW_MM_CFG])) + if (!is_user && cris_mmu_segmented_addr(seg, env->sregs[SFR_RW_MM_CFG])) { uint32_t base; miss = 0; base = cris_mmu_translate_seg(env, seg); - phy = base | (0x0fffffff & vaddr); - res->phy = phy; + res->phy = base | (0x0fffffff & vaddr); res->prot = PAGE_BITS; + } else { + miss = cris_mmu_translate_page(res, env, vaddr, rw, + is_user, debug); } - else - miss = cris_mmu_translate_page(res, env, vaddr, rw, is_user); done: env->pregs[PR_SRS] = old_srs; return miss;