4 * Copyright (c) 2007 AXIS Communications AB
5 * Written by Edgar E. Iglesias.
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 #ifndef CONFIG_USER_ONLY
34 static int cris_mmu_enabled(uint32_t rw_gc_cfg
)
36 return (rw_gc_cfg
& 12) != 0;
39 static int cris_mmu_segmented_addr(int seg
, uint32_t rw_mm_cfg
)
41 return (1 << seg
) & rw_mm_cfg
;
44 static uint32_t cris_mmu_translate_seg(CPUState
*env
, int seg
)
50 base
= env
->sregs
[SFR_RW_MM_KBASE_LO
];
52 base
= env
->sregs
[SFR_RW_MM_KBASE_HI
];
61 /* Used by the tlb decoder. */
62 #define EXTRACT_FIELD(src, start, end) \
63 (((src) >> start) & ((1 << (end - start + 1)) - 1))
65 static int cris_mmu_translate_page(struct cris_mmu_result_t
*res
,
66 CPUState
*env
, uint32_t vaddr
,
72 uint32_t vpn
, pfn
= 0, pid
, fg
, fv
, fk
, fw
, fx
;
79 /* We know the index which to check on each set.
81 for (i
= 0; i
< 4; i
++)
83 lo
= env
->tlbsets
[0][i
][idx
].lo
;
84 hi
= env
->tlbsets
[0][i
][idx
].hi
;
86 vpn
= EXTRACT_FIELD(hi
, 13, 31);
87 pid
= EXTRACT_FIELD(hi
, 0, 7);
90 && pid
== env
->pregs
[PR_PID
]) {
97 pfn
= EXTRACT_FIELD(lo
, 13, 31);
98 fg
= EXTRACT_FIELD(lo
, 4, 4);
99 fv
= EXTRACT_FIELD(lo
, 3, 3);
100 fk
= EXTRACT_FIELD(lo
, 2, 2);
101 fw
= EXTRACT_FIELD(lo
, 1, 1);
102 fx
= EXTRACT_FIELD(lo
, 0, 0);
104 printf ("%s match=%d vaddr=%x vpage=%x vpn=%x pfn=%x pid=%x %x\n",
107 vpn
, pfn
, pid
, env
->pregs
[PR_PID
]);
112 int cris_mmu_translate(struct cris_mmu_result_t
*res
,
113 CPUState
*env
, uint32_t vaddr
,
116 uint32_t phy
= vaddr
;
119 int is_user
= mmu_idx
== MMU_USER_IDX
;
121 if (!cris_mmu_enabled(env
->sregs
[SFR_RW_GC_CFG
])) {
127 if (cris_mmu_segmented_addr(seg
, env
->sregs
[SFR_RW_MM_CFG
]))
132 base
= cris_mmu_translate_seg(env
, seg
);
133 phy
= base
| (0x0fffffff & vaddr
);
138 miss
= cris_mmu_translate_page(res
, env
, vaddr
, rw
, is_user
);
141 phy
|= (res
->pfn
<< 13);
145 // printf ("miss=%d v=%x -> p=%x\n", miss, vaddr, phy);