Statistics
| Branch: | Revision:

root / target-cris / mmu.c @ 94cff60a

History | View | Annotate | Download (3.3 kB)

1 94cff60a ths
/*
2 94cff60a ths
 *  CRIS mmu emulation.
3 94cff60a ths
 *
4 94cff60a ths
 *  Copyright (c) 2007 AXIS Communications AB
5 94cff60a ths
 *  Written by Edgar E. Iglesias.
6 94cff60a ths
 *
7 94cff60a ths
 * This library is free software; you can redistribute it and/or
8 94cff60a ths
 * modify it under the terms of the GNU Lesser General Public
9 94cff60a ths
 * License as published by the Free Software Foundation; either
10 94cff60a ths
 * version 2 of the License, or (at your option) any later version.
11 94cff60a ths
 *
12 94cff60a ths
 * This library is distributed in the hope that it will be useful,
13 94cff60a ths
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 94cff60a ths
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15 94cff60a ths
 * Lesser General Public License for more details.
16 94cff60a ths
 *
17 94cff60a ths
 * You should have received a copy of the GNU Lesser General Public
18 94cff60a ths
 * License along with this library; if not, write to the Free Software
19 94cff60a ths
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20 94cff60a ths
 */
21 94cff60a ths
22 94cff60a ths
#ifndef CONFIG_USER_ONLY
23 94cff60a ths
24 94cff60a ths
#include <stdio.h>
25 94cff60a ths
#include <string.h>
26 94cff60a ths
#include <stdlib.h>
27 94cff60a ths
28 94cff60a ths
#include "config.h"
29 94cff60a ths
#include "cpu.h"
30 94cff60a ths
#include "mmu.h"
31 94cff60a ths
#include "exec-all.h"
32 94cff60a ths
33 94cff60a ths
34 94cff60a ths
static int cris_mmu_enabled(uint32_t rw_gc_cfg)
35 94cff60a ths
{
36 94cff60a ths
        return (rw_gc_cfg & 12) != 0;
37 94cff60a ths
}
38 94cff60a ths
39 94cff60a ths
static int cris_mmu_segmented_addr(int seg, uint32_t rw_mm_cfg)
40 94cff60a ths
{
41 94cff60a ths
        return (1 << seg) & rw_mm_cfg;
42 94cff60a ths
}
43 94cff60a ths
44 94cff60a ths
static uint32_t cris_mmu_translate_seg(CPUState *env, int seg)
45 94cff60a ths
{
46 94cff60a ths
        uint32_t base;
47 94cff60a ths
        int i;
48 94cff60a ths
49 94cff60a ths
        if (seg < 8)
50 94cff60a ths
                base = env->sregs[SFR_RW_MM_KBASE_LO];
51 94cff60a ths
        else
52 94cff60a ths
                base = env->sregs[SFR_RW_MM_KBASE_HI];
53 94cff60a ths
54 94cff60a ths
        i = seg & 7;
55 94cff60a ths
        base >>= i * 4;
56 94cff60a ths
        base &= 15;
57 94cff60a ths
58 94cff60a ths
        base <<= 28;
59 94cff60a ths
        return base;
60 94cff60a ths
}
61 94cff60a ths
/* Used by the tlb decoder.  */
62 94cff60a ths
#define EXTRACT_FIELD(src, start, end) \
63 94cff60a ths
            (((src) >> start) & ((1 << (end - start + 1)) - 1))
64 94cff60a ths
65 94cff60a ths
static int cris_mmu_translate_page(struct cris_mmu_result_t *res,
66 94cff60a ths
                                   CPUState *env, uint32_t vaddr,
67 94cff60a ths
                                   int rw, int usermode)
68 94cff60a ths
{
69 94cff60a ths
        unsigned int vpage;
70 94cff60a ths
        unsigned int idx;
71 94cff60a ths
        uint32_t lo, hi;
72 94cff60a ths
        uint32_t vpn, pfn = 0, pid, fg, fv, fk, fw, fx;
73 94cff60a ths
        int i, match = 0;
74 94cff60a ths
75 94cff60a ths
        vpage = vaddr >> 13;
76 94cff60a ths
        idx = vpage & 31;
77 94cff60a ths
        vpage >>= 4;
78 94cff60a ths
79 94cff60a ths
        /* We know the index which to check on each set.
80 94cff60a ths
           Scan both I and D.  */
81 94cff60a ths
        for (i = 0; i < 4; i++)
82 94cff60a ths
        {
83 94cff60a ths
                lo = env->tlbsets[0][i][idx].lo;
84 94cff60a ths
                hi = env->tlbsets[0][i][idx].hi;
85 94cff60a ths
86 94cff60a ths
                vpn = EXTRACT_FIELD(hi, 13, 31);
87 94cff60a ths
                pid = EXTRACT_FIELD(hi, 0, 7);
88 94cff60a ths
89 94cff60a ths
                if (vpn == vpage
90 94cff60a ths
                    && pid == env->pregs[SR_PID]) {
91 94cff60a ths
                        match = 1;
92 94cff60a ths
                        break;
93 94cff60a ths
                }
94 94cff60a ths
        }
95 94cff60a ths
96 94cff60a ths
        if (match) {
97 94cff60a ths
                pfn = EXTRACT_FIELD(lo, 13, 31);
98 94cff60a ths
                fg = EXTRACT_FIELD(lo, 4, 4);
99 94cff60a ths
                fv = EXTRACT_FIELD(lo, 3, 3);
100 94cff60a ths
                fk = EXTRACT_FIELD(lo, 2, 2);
101 94cff60a ths
                fw = EXTRACT_FIELD(lo, 1, 1);
102 94cff60a ths
                fx = EXTRACT_FIELD(lo, 0, 0);
103 94cff60a ths
        }
104 94cff60a ths
        printf ("%s match=%d vaddr=%x vpage=%x vpn=%x pfn=%x pid=%x %x\n",
105 94cff60a ths
                __func__, match,
106 94cff60a ths
                vaddr, vpage,
107 94cff60a ths
                vpn, pfn, pid, env->pregs[SR_PID]);
108 94cff60a ths
        res->pfn = pfn;
109 94cff60a ths
        return !match;
110 94cff60a ths
}
111 94cff60a ths
112 94cff60a ths
int cris_mmu_translate(struct cris_mmu_result_t *res,
113 94cff60a ths
                       CPUState *env, uint32_t vaddr,
114 94cff60a ths
                       int rw, int is_user)
115 94cff60a ths
{
116 94cff60a ths
        uint32_t phy = vaddr;
117 94cff60a ths
        int seg;
118 94cff60a ths
        int miss = 0;
119 94cff60a ths
120 94cff60a ths
        if (!cris_mmu_enabled(env->sregs[SFR_RW_GC_CFG])) {
121 94cff60a ths
                res->phy = vaddr;
122 94cff60a ths
                return 0;
123 94cff60a ths
        }
124 94cff60a ths
125 94cff60a ths
        seg = vaddr >> 28;
126 94cff60a ths
        if (cris_mmu_segmented_addr(seg, env->sregs[SFR_RW_MM_CFG]))
127 94cff60a ths
        {
128 94cff60a ths
                uint32_t base;
129 94cff60a ths
130 94cff60a ths
                miss = 0;
131 94cff60a ths
                base = cris_mmu_translate_seg(env, seg);
132 94cff60a ths
                phy = base | (0x0fffffff & vaddr);
133 94cff60a ths
                res->phy = phy;
134 94cff60a ths
        }
135 94cff60a ths
        else
136 94cff60a ths
        {
137 94cff60a ths
                miss = cris_mmu_translate_page(res, env, vaddr, rw, is_user);
138 94cff60a ths
                if (!miss) {
139 94cff60a ths
                        phy &= 8191;
140 94cff60a ths
                        phy |= (res->pfn << 13);
141 94cff60a ths
                        res->phy = phy;
142 94cff60a ths
                }
143 94cff60a ths
        }
144 94cff60a ths
//        printf ("miss=%d v=%x -> p=%x\n", miss, vaddr, phy);
145 94cff60a ths
        return miss;
146 94cff60a ths
}
147 94cff60a ths
#endif