1fcf5ef2aSThomas Huth /*
2fcf5ef2aSThomas Huth * Microblaze MMU emulation for qemu.
3fcf5ef2aSThomas Huth *
4fcf5ef2aSThomas Huth * Copyright (c) 2009 Edgar E. Iglesias
5fcf5ef2aSThomas Huth * Copyright (c) 2009-2012 PetaLogix Qld Pty Ltd.
6fcf5ef2aSThomas Huth *
7fcf5ef2aSThomas Huth * This library is free software; you can redistribute it and/or
8fcf5ef2aSThomas Huth * modify it under the terms of the GNU Lesser General Public
9fcf5ef2aSThomas Huth * License as published by the Free Software Foundation; either
10ee452036SChetan Pant * version 2.1 of the License, or (at your option) any later version.
11fcf5ef2aSThomas Huth *
12fcf5ef2aSThomas Huth * This library is distributed in the hope that it will be useful,
13fcf5ef2aSThomas Huth * but WITHOUT ANY WARRANTY; without even the implied warranty of
14fcf5ef2aSThomas Huth * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15fcf5ef2aSThomas Huth * Lesser General Public License for more details.
16fcf5ef2aSThomas Huth *
17fcf5ef2aSThomas Huth * You should have received a copy of the GNU Lesser General Public
18fcf5ef2aSThomas Huth * License along with this library; if not, see <http://www.gnu.org/licenses/>.
19fcf5ef2aSThomas Huth */
20fcf5ef2aSThomas Huth
21fcf5ef2aSThomas Huth #include "qemu/osdep.h"
22cd617484SPhilippe Mathieu-Daudé #include "qemu/log.h"
23fcf5ef2aSThomas Huth #include "cpu.h"
24fcf5ef2aSThomas Huth #include "exec/exec-all.h"
25*74781c08SPhilippe Mathieu-Daudé #include "exec/page-protection.h"
26fcf5ef2aSThomas Huth
tlb_decode_size(unsigned int f)27fcf5ef2aSThomas Huth static unsigned int tlb_decode_size(unsigned int f)
28fcf5ef2aSThomas Huth {
29fcf5ef2aSThomas Huth static const unsigned int sizes[] = {
30fcf5ef2aSThomas Huth 1 * 1024, 4 * 1024, 16 * 1024, 64 * 1024, 256 * 1024,
31fcf5ef2aSThomas Huth 1 * 1024 * 1024, 4 * 1024 * 1024, 16 * 1024 * 1024
32fcf5ef2aSThomas Huth };
33fcf5ef2aSThomas Huth assert(f < ARRAY_SIZE(sizes));
34fcf5ef2aSThomas Huth return sizes[f];
35fcf5ef2aSThomas Huth }
36fcf5ef2aSThomas Huth
mmu_flush_idx(CPUMBState * env,unsigned int idx)37fcf5ef2aSThomas Huth static void mmu_flush_idx(CPUMBState *env, unsigned int idx)
38fcf5ef2aSThomas Huth {
39f5c7e93aSRichard Henderson CPUState *cs = env_cpu(env);
408ce97bc1SRichard Henderson MicroBlazeMMU *mmu = &env->mmu;
41fcf5ef2aSThomas Huth unsigned int tlb_size;
42fcf5ef2aSThomas Huth uint32_t tlb_tag, end, t;
43fcf5ef2aSThomas Huth
44fcf5ef2aSThomas Huth t = mmu->rams[RAM_TAG][idx];
45fcf5ef2aSThomas Huth if (!(t & TLB_VALID))
46fcf5ef2aSThomas Huth return;
47fcf5ef2aSThomas Huth
48fcf5ef2aSThomas Huth tlb_tag = t & TLB_EPN_MASK;
49fcf5ef2aSThomas Huth tlb_size = tlb_decode_size((t & TLB_PAGESZ_MASK) >> 7);
50fcf5ef2aSThomas Huth end = tlb_tag + tlb_size;
51fcf5ef2aSThomas Huth
52fcf5ef2aSThomas Huth while (tlb_tag < end) {
53fcf5ef2aSThomas Huth tlb_flush_page(cs, tlb_tag);
54fcf5ef2aSThomas Huth tlb_tag += TARGET_PAGE_SIZE;
55fcf5ef2aSThomas Huth }
56fcf5ef2aSThomas Huth }
57fcf5ef2aSThomas Huth
mmu_change_pid(CPUMBState * env,unsigned int newpid)58fcf5ef2aSThomas Huth static void mmu_change_pid(CPUMBState *env, unsigned int newpid)
59fcf5ef2aSThomas Huth {
608ce97bc1SRichard Henderson MicroBlazeMMU *mmu = &env->mmu;
61fcf5ef2aSThomas Huth unsigned int i;
62fcf5ef2aSThomas Huth uint32_t t;
63fcf5ef2aSThomas Huth
64fcf5ef2aSThomas Huth if (newpid & ~0xff)
65fcf5ef2aSThomas Huth qemu_log_mask(LOG_GUEST_ERROR, "Illegal rpid=%x\n", newpid);
66fcf5ef2aSThomas Huth
67fcf5ef2aSThomas Huth for (i = 0; i < ARRAY_SIZE(mmu->rams[RAM_TAG]); i++) {
68fcf5ef2aSThomas Huth /* Lookup and decode. */
69fcf5ef2aSThomas Huth t = mmu->rams[RAM_TAG][i];
70fcf5ef2aSThomas Huth if (t & TLB_VALID) {
71fcf5ef2aSThomas Huth if (mmu->tids[i] && ((mmu->regs[MMU_R_PID] & 0xff) == mmu->tids[i]))
72fcf5ef2aSThomas Huth mmu_flush_idx(env, i);
73fcf5ef2aSThomas Huth }
74fcf5ef2aSThomas Huth }
75fcf5ef2aSThomas Huth }
76fcf5ef2aSThomas Huth
77fcf5ef2aSThomas Huth /* rw - 0 = read, 1 = write, 2 = fetch. */
mmu_translate(MicroBlazeCPU * cpu,MicroBlazeMMULookup * lu,target_ulong vaddr,MMUAccessType rw,int mmu_idx)78de73ee1aSRichard Henderson unsigned int mmu_translate(MicroBlazeCPU *cpu, MicroBlazeMMULookup *lu,
79671a0a12SJoe Komlodi target_ulong vaddr, MMUAccessType rw, int mmu_idx)
80fcf5ef2aSThomas Huth {
81de73ee1aSRichard Henderson MicroBlazeMMU *mmu = &cpu->env.mmu;
82fcf5ef2aSThomas Huth unsigned int i, hit = 0;
83fcf5ef2aSThomas Huth unsigned int tlb_ex = 0, tlb_wr = 0, tlb_zsel;
84d2f004c3SEdgar E. Iglesias uint64_t tlb_tag, tlb_rpn, mask;
85d2f004c3SEdgar E. Iglesias uint32_t tlb_size, t0;
86fcf5ef2aSThomas Huth
87fcf5ef2aSThomas Huth lu->err = ERR_MISS;
88fcf5ef2aSThomas Huth for (i = 0; i < ARRAY_SIZE(mmu->rams[RAM_TAG]); i++) {
89d2f004c3SEdgar E. Iglesias uint64_t t, d;
90fcf5ef2aSThomas Huth
91fcf5ef2aSThomas Huth /* Lookup and decode. */
92fcf5ef2aSThomas Huth t = mmu->rams[RAM_TAG][i];
93fcf5ef2aSThomas Huth if (t & TLB_VALID) {
94fcf5ef2aSThomas Huth tlb_size = tlb_decode_size((t & TLB_PAGESZ_MASK) >> 7);
95fcf5ef2aSThomas Huth if (tlb_size < TARGET_PAGE_SIZE) {
9675c9ddceSEdgar E. Iglesias qemu_log_mask(LOG_UNIMP, "%d pages not supported\n", tlb_size);
97fcf5ef2aSThomas Huth abort();
98fcf5ef2aSThomas Huth }
99fcf5ef2aSThomas Huth
100d2f004c3SEdgar E. Iglesias mask = ~((uint64_t)tlb_size - 1);
101fcf5ef2aSThomas Huth tlb_tag = t & TLB_EPN_MASK;
102fcf5ef2aSThomas Huth if ((vaddr & mask) != (tlb_tag & mask)) {
103fcf5ef2aSThomas Huth continue;
104fcf5ef2aSThomas Huth }
105fcf5ef2aSThomas Huth if (mmu->tids[i]
106fcf5ef2aSThomas Huth && ((mmu->regs[MMU_R_PID] & 0xff) != mmu->tids[i])) {
107fcf5ef2aSThomas Huth continue;
108fcf5ef2aSThomas Huth }
109fcf5ef2aSThomas Huth
110fcf5ef2aSThomas Huth /* Bring in the data part. */
111fcf5ef2aSThomas Huth d = mmu->rams[RAM_DATA][i];
112fcf5ef2aSThomas Huth tlb_ex = d & TLB_EX;
113fcf5ef2aSThomas Huth tlb_wr = d & TLB_WR;
114fcf5ef2aSThomas Huth
115fcf5ef2aSThomas Huth /* Now let's see if there is a zone that overrides the protbits. */
116fcf5ef2aSThomas Huth tlb_zsel = (d >> 4) & 0xf;
117fcf5ef2aSThomas Huth t0 = mmu->regs[MMU_R_ZPR] >> (30 - (tlb_zsel * 2));
118fcf5ef2aSThomas Huth t0 &= 0x3;
119fcf5ef2aSThomas Huth
120de73ee1aSRichard Henderson if (tlb_zsel > cpu->cfg.mmu_zones) {
12175c9ddceSEdgar E. Iglesias qemu_log_mask(LOG_GUEST_ERROR,
12275c9ddceSEdgar E. Iglesias "tlb zone select out of range! %d\n", tlb_zsel);
123fcf5ef2aSThomas Huth t0 = 1; /* Ignore. */
124fcf5ef2aSThomas Huth }
125fcf5ef2aSThomas Huth
126de73ee1aSRichard Henderson if (cpu->cfg.mmu == 1) {
127fcf5ef2aSThomas Huth t0 = 1; /* Zones are disabled. */
128fcf5ef2aSThomas Huth }
129fcf5ef2aSThomas Huth
130fcf5ef2aSThomas Huth switch (t0) {
131fcf5ef2aSThomas Huth case 0:
132fcf5ef2aSThomas Huth if (mmu_idx == MMU_USER_IDX)
133fcf5ef2aSThomas Huth continue;
134fcf5ef2aSThomas Huth break;
135fcf5ef2aSThomas Huth case 2:
136fcf5ef2aSThomas Huth if (mmu_idx != MMU_USER_IDX) {
137fcf5ef2aSThomas Huth tlb_ex = 1;
138fcf5ef2aSThomas Huth tlb_wr = 1;
139fcf5ef2aSThomas Huth }
140fcf5ef2aSThomas Huth break;
141fcf5ef2aSThomas Huth case 3:
142fcf5ef2aSThomas Huth tlb_ex = 1;
143fcf5ef2aSThomas Huth tlb_wr = 1;
144fcf5ef2aSThomas Huth break;
145fcf5ef2aSThomas Huth default: break;
146fcf5ef2aSThomas Huth }
147fcf5ef2aSThomas Huth
148fcf5ef2aSThomas Huth lu->err = ERR_PROT;
149fcf5ef2aSThomas Huth lu->prot = PAGE_READ;
150fcf5ef2aSThomas Huth if (tlb_wr)
151fcf5ef2aSThomas Huth lu->prot |= PAGE_WRITE;
152fcf5ef2aSThomas Huth else if (rw == 1)
153fcf5ef2aSThomas Huth goto done;
154fcf5ef2aSThomas Huth if (tlb_ex)
155fcf5ef2aSThomas Huth lu->prot |=PAGE_EXEC;
156fcf5ef2aSThomas Huth else if (rw == 2) {
157fcf5ef2aSThomas Huth goto done;
158fcf5ef2aSThomas Huth }
159fcf5ef2aSThomas Huth
160fcf5ef2aSThomas Huth tlb_rpn = d & TLB_RPN_MASK;
161fcf5ef2aSThomas Huth
162fcf5ef2aSThomas Huth lu->vaddr = tlb_tag;
163de73ee1aSRichard Henderson lu->paddr = tlb_rpn & cpu->cfg.addr_mask;
164fcf5ef2aSThomas Huth lu->size = tlb_size;
165fcf5ef2aSThomas Huth lu->err = ERR_HIT;
166fcf5ef2aSThomas Huth lu->idx = i;
167fcf5ef2aSThomas Huth hit = 1;
168fcf5ef2aSThomas Huth goto done;
169fcf5ef2aSThomas Huth }
170fcf5ef2aSThomas Huth }
171fcf5ef2aSThomas Huth done:
17275c9ddceSEdgar E. Iglesias qemu_log_mask(CPU_LOG_MMU,
17375c9ddceSEdgar E. Iglesias "MMU vaddr=%" PRIx64 " rw=%d tlb_wr=%d tlb_ex=%d hit=%d\n",
17475c9ddceSEdgar E. Iglesias vaddr, rw, tlb_wr, tlb_ex, hit);
175fcf5ef2aSThomas Huth return hit;
176fcf5ef2aSThomas Huth }
177fcf5ef2aSThomas Huth
178fcf5ef2aSThomas Huth /* Writes/reads to the MMU's special regs end up here. */
mmu_read(CPUMBState * env,bool ext,uint32_t rn)179f0f7e7f7SEdgar E. Iglesias uint32_t mmu_read(CPUMBState *env, bool ext, uint32_t rn)
180fcf5ef2aSThomas Huth {
181de73ee1aSRichard Henderson MicroBlazeCPU *cpu = env_archcpu(env);
182fcf5ef2aSThomas Huth unsigned int i;
183bd9e6608SEdgar E. Iglesias uint32_t r = 0;
184fcf5ef2aSThomas Huth
185de73ee1aSRichard Henderson if (cpu->cfg.mmu < 2 || !cpu->cfg.mmu_tlb_access) {
186fcf5ef2aSThomas Huth qemu_log_mask(LOG_GUEST_ERROR, "MMU access on MMU-less system\n");
187fcf5ef2aSThomas Huth return 0;
188fcf5ef2aSThomas Huth }
189f0f7e7f7SEdgar E. Iglesias if (ext && rn != MMU_R_TLBLO) {
190f0f7e7f7SEdgar E. Iglesias qemu_log_mask(LOG_GUEST_ERROR, "Extended access only to TLBLO.\n");
191f0f7e7f7SEdgar E. Iglesias return 0;
192f0f7e7f7SEdgar E. Iglesias }
193fcf5ef2aSThomas Huth
194fcf5ef2aSThomas Huth switch (rn) {
195fcf5ef2aSThomas Huth /* Reads to HI/LO trig reads from the mmu rams. */
196fcf5ef2aSThomas Huth case MMU_R_TLBLO:
197fcf5ef2aSThomas Huth case MMU_R_TLBHI:
198de73ee1aSRichard Henderson if (!(cpu->cfg.mmu_tlb_access & 1)) {
19975c9ddceSEdgar E. Iglesias qemu_log_mask(LOG_GUEST_ERROR,
20075c9ddceSEdgar E. Iglesias "Invalid access to MMU reg %d\n", rn);
201fcf5ef2aSThomas Huth return 0;
202fcf5ef2aSThomas Huth }
203fcf5ef2aSThomas Huth
204fcf5ef2aSThomas Huth i = env->mmu.regs[MMU_R_TLBX] & 0xff;
205f0f7e7f7SEdgar E. Iglesias r = extract64(env->mmu.rams[rn & 1][i], ext * 32, 32);
206fcf5ef2aSThomas Huth if (rn == MMU_R_TLBHI)
207fcf5ef2aSThomas Huth env->mmu.regs[MMU_R_PID] = env->mmu.tids[i];
208fcf5ef2aSThomas Huth break;
209fcf5ef2aSThomas Huth case MMU_R_PID:
210fcf5ef2aSThomas Huth case MMU_R_ZPR:
211de73ee1aSRichard Henderson if (!(cpu->cfg.mmu_tlb_access & 1)) {
21275c9ddceSEdgar E. Iglesias qemu_log_mask(LOG_GUEST_ERROR,
21375c9ddceSEdgar E. Iglesias "Invalid access to MMU reg %d\n", rn);
214fcf5ef2aSThomas Huth return 0;
215fcf5ef2aSThomas Huth }
216fcf5ef2aSThomas Huth r = env->mmu.regs[rn];
217fcf5ef2aSThomas Huth break;
21896716533SEdgar E. Iglesias case MMU_R_TLBX:
21996716533SEdgar E. Iglesias r = env->mmu.regs[rn];
22096716533SEdgar E. Iglesias break;
221bd9e6608SEdgar E. Iglesias case MMU_R_TLBSX:
222bd9e6608SEdgar E. Iglesias qemu_log_mask(LOG_GUEST_ERROR, "TLBSX is write-only.\n");
223bd9e6608SEdgar E. Iglesias break;
224fcf5ef2aSThomas Huth default:
22596716533SEdgar E. Iglesias qemu_log_mask(LOG_GUEST_ERROR, "Invalid MMU register %d.\n", rn);
226fcf5ef2aSThomas Huth break;
227fcf5ef2aSThomas Huth }
22875c9ddceSEdgar E. Iglesias qemu_log_mask(CPU_LOG_MMU, "%s rn=%d=%x\n", __func__, rn, r);
229fcf5ef2aSThomas Huth return r;
230fcf5ef2aSThomas Huth }
231fcf5ef2aSThomas Huth
mmu_write(CPUMBState * env,bool ext,uint32_t rn,uint32_t v)232f0f7e7f7SEdgar E. Iglesias void mmu_write(CPUMBState *env, bool ext, uint32_t rn, uint32_t v)
233fcf5ef2aSThomas Huth {
234de73ee1aSRichard Henderson MicroBlazeCPU *cpu = env_archcpu(env);
235f0f7e7f7SEdgar E. Iglesias uint64_t tmp64;
236fcf5ef2aSThomas Huth unsigned int i;
237de73ee1aSRichard Henderson
23875c9ddceSEdgar E. Iglesias qemu_log_mask(CPU_LOG_MMU,
239f25c7ca0SAlexChen "%s rn=%d=%x old=%x\n", __func__, rn, v,
240f25c7ca0SAlexChen rn < 3 ? env->mmu.regs[rn] : env->mmu.regs[MMU_R_TLBX]);
241fcf5ef2aSThomas Huth
242de73ee1aSRichard Henderson if (cpu->cfg.mmu < 2 || !cpu->cfg.mmu_tlb_access) {
243fcf5ef2aSThomas Huth qemu_log_mask(LOG_GUEST_ERROR, "MMU access on MMU-less system\n");
244fcf5ef2aSThomas Huth return;
245fcf5ef2aSThomas Huth }
246f0f7e7f7SEdgar E. Iglesias if (ext && rn != MMU_R_TLBLO) {
247f0f7e7f7SEdgar E. Iglesias qemu_log_mask(LOG_GUEST_ERROR, "Extended access only to TLBLO.\n");
248f0f7e7f7SEdgar E. Iglesias return;
249f0f7e7f7SEdgar E. Iglesias }
250fcf5ef2aSThomas Huth
251fcf5ef2aSThomas Huth switch (rn) {
252fcf5ef2aSThomas Huth /* Writes to HI/LO trig writes to the mmu rams. */
253fcf5ef2aSThomas Huth case MMU_R_TLBLO:
254fcf5ef2aSThomas Huth case MMU_R_TLBHI:
255fcf5ef2aSThomas Huth i = env->mmu.regs[MMU_R_TLBX] & 0xff;
256fcf5ef2aSThomas Huth if (rn == MMU_R_TLBHI) {
257fcf5ef2aSThomas Huth if (i < 3 && !(v & TLB_VALID) && qemu_loglevel_mask(~0))
2580a22f8cfSEdgar E. Iglesias qemu_log_mask(LOG_GUEST_ERROR,
2590f96e96bSRichard Henderson "invalidating index %x at pc=%x\n",
26076e8187dSRichard Henderson i, env->pc);
261fcf5ef2aSThomas Huth env->mmu.tids[i] = env->mmu.regs[MMU_R_PID] & 0xff;
262fcf5ef2aSThomas Huth mmu_flush_idx(env, i);
263fcf5ef2aSThomas Huth }
264f0f7e7f7SEdgar E. Iglesias tmp64 = env->mmu.rams[rn & 1][i];
265f0f7e7f7SEdgar E. Iglesias env->mmu.rams[rn & 1][i] = deposit64(tmp64, ext * 32, 32, v);
266fcf5ef2aSThomas Huth break;
267fcf5ef2aSThomas Huth case MMU_R_ZPR:
268de73ee1aSRichard Henderson if (cpu->cfg.mmu_tlb_access <= 1) {
26975c9ddceSEdgar E. Iglesias qemu_log_mask(LOG_GUEST_ERROR,
27075c9ddceSEdgar E. Iglesias "Invalid access to MMU reg %d\n", rn);
271fcf5ef2aSThomas Huth return;
272fcf5ef2aSThomas Huth }
273fcf5ef2aSThomas Huth
274fcf5ef2aSThomas Huth /* Changes to the zone protection reg flush the QEMU TLB.
275fcf5ef2aSThomas Huth Fortunately, these are very uncommon. */
276fcf5ef2aSThomas Huth if (v != env->mmu.regs[rn]) {
277f5c7e93aSRichard Henderson tlb_flush(env_cpu(env));
278fcf5ef2aSThomas Huth }
279fcf5ef2aSThomas Huth env->mmu.regs[rn] = v;
280fcf5ef2aSThomas Huth break;
281fcf5ef2aSThomas Huth case MMU_R_PID:
282de73ee1aSRichard Henderson if (cpu->cfg.mmu_tlb_access <= 1) {
28375c9ddceSEdgar E. Iglesias qemu_log_mask(LOG_GUEST_ERROR,
28475c9ddceSEdgar E. Iglesias "Invalid access to MMU reg %d\n", rn);
285fcf5ef2aSThomas Huth return;
286fcf5ef2aSThomas Huth }
287fcf5ef2aSThomas Huth
288fcf5ef2aSThomas Huth if (v != env->mmu.regs[rn]) {
289fcf5ef2aSThomas Huth mmu_change_pid(env, v);
290fcf5ef2aSThomas Huth env->mmu.regs[rn] = v;
291fcf5ef2aSThomas Huth }
292fcf5ef2aSThomas Huth break;
293fce6a8ecSEdgar E. Iglesias case MMU_R_TLBX:
294fce6a8ecSEdgar E. Iglesias /* Bit 31 is read-only. */
295fce6a8ecSEdgar E. Iglesias env->mmu.regs[rn] = deposit32(env->mmu.regs[rn], 0, 31, v);
296fce6a8ecSEdgar E. Iglesias break;
297fcf5ef2aSThomas Huth case MMU_R_TLBSX:
298fcf5ef2aSThomas Huth {
2998ce97bc1SRichard Henderson MicroBlazeMMULookup lu;
300fcf5ef2aSThomas Huth int hit;
301fcf5ef2aSThomas Huth
302de73ee1aSRichard Henderson if (cpu->cfg.mmu_tlb_access <= 1) {
30375c9ddceSEdgar E. Iglesias qemu_log_mask(LOG_GUEST_ERROR,
30475c9ddceSEdgar E. Iglesias "Invalid access to MMU reg %d\n", rn);
305fcf5ef2aSThomas Huth return;
306fcf5ef2aSThomas Huth }
307fcf5ef2aSThomas Huth
308de73ee1aSRichard Henderson hit = mmu_translate(cpu, &lu, v & TLB_EPN_MASK,
3093b916140SRichard Henderson 0, cpu_mmu_index(env_cpu(env), false));
310fcf5ef2aSThomas Huth if (hit) {
311fcf5ef2aSThomas Huth env->mmu.regs[MMU_R_TLBX] = lu.idx;
312a2207b59SEdgar E. Iglesias } else {
313a2207b59SEdgar E. Iglesias env->mmu.regs[MMU_R_TLBX] |= R_TBLX_MISS_MASK;
314a2207b59SEdgar E. Iglesias }
315fcf5ef2aSThomas Huth break;
316fcf5ef2aSThomas Huth }
317fcf5ef2aSThomas Huth default:
31896716533SEdgar E. Iglesias qemu_log_mask(LOG_GUEST_ERROR, "Invalid MMU register %d.\n", rn);
319fcf5ef2aSThomas Huth break;
320fcf5ef2aSThomas Huth }
321fcf5ef2aSThomas Huth }
322fcf5ef2aSThomas Huth
mmu_init(MicroBlazeMMU * mmu)3238ce97bc1SRichard Henderson void mmu_init(MicroBlazeMMU *mmu)
324fcf5ef2aSThomas Huth {
325fcf5ef2aSThomas Huth int i;
326fcf5ef2aSThomas Huth for (i = 0; i < ARRAY_SIZE(mmu->regs); i++) {
327fcf5ef2aSThomas Huth mmu->regs[i] = 0;
328fcf5ef2aSThomas Huth }
329fcf5ef2aSThomas Huth }
330