avr32: fix write protection handling
[qemu/avr32.git] / target-avr32 / helper.c
blobf4d961f5761865c7a8e62ef2c3861e8cf9411bf6
1 /*
2 * AVR32 op helpers
4 * Copyright (c) 2009 Rabin Vincent
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <string.h>
25 #include "cpu.h"
26 #include "exec-all.h"
27 #include "gdbstub.h"
28 #include "qemu-common.h"
30 #ifdef DEBUG
31 #define dbg(format...) fprintf(stderr, format)
32 #else
33 static inline int dbg(const char *format, ...)
35 return 0;
37 #endif
39 target_phys_addr_t cpu_get_phys_page_debug(CPUState *env, target_ulong addr)
41 return addr;
44 void cpu_reset(CPUAVR32State *env)
46 env->regs[15] = 0;
47 env->sysreg[SYSREG_SR] = SR_M_SUP | SR_EM | SR_GM;
48 env->sysreg[SYSREG_CONFIG0] = 0x01012510;
49 env->sysreg[SYSREG_CONFIG1] = 0x00118020;
50 env->sysreg[SYSREG_MMUCR] = MMUCR_SEGMENT_EN;
51 env->sysreg[SYSREG_TLBARLO] = ~0u;
52 env->sysreg[SYSREG_TLBARHI] = ~0u;
54 tlb_flush(env, 1);
57 void do_interrupt(CPUState *env)
59 uint32_t offset;
60 uint32_t mask;
61 uint32_t value;
62 int rar;
63 int rsr;
65 dbg("$$ %s [0x%#x]\n", __func__, env->sysreg[SYSREG_SR]);
66 dbg("%s, exception_index=%d\n", __func__, env->exception_index);
68 /* FIXME handled banked registers */
70 switch (env->exception_index) {
71 case EXCP_ILLEGAL:
72 offset = 0x20;
74 mask = SR_M | SR_J | SR_R | SR_EM | SR_GM;
75 value = SR_M_EXP | SR_EM | SR_GM;
76 rar = SYSREG_RAR_EX;
77 rsr = SYSREG_RSR_EX;
78 break;
80 case EXCP_DTLB_WRITE_PROTECT:
81 offset = 0x40;
83 mask = SR_M | SR_J | SR_R | SR_EM | SR_GM;
84 value = SR_M_EXP | SR_EM | SR_GM;
85 rar = SYSREG_RAR_EX;
86 rsr = SYSREG_RSR_EX;
87 break;
89 case EXCP_DTLB_READ_MISS:
90 offset = 0x60;
92 mask = SR_M | SR_J | SR_R | SR_EM | SR_GM;
93 value = SR_M_EXP | SR_EM | SR_GM;
94 rar = SYSREG_RAR_EX;
95 rsr = SYSREG_RSR_EX;
96 break;
98 case EXCP_DTLB_WRITE_MISS:
99 offset = 0x70;
101 mask = SR_M | SR_J | SR_R | SR_EM | SR_GM;
102 value = SR_M_EXP | SR_EM | SR_GM;
103 rar = SYSREG_RAR_EX;
104 rsr = SYSREG_RSR_EX;
105 break;
107 case EXCP_ITLB_MISS:
108 offset = 0x50;
110 mask = SR_M | SR_J | SR_R | SR_EM | SR_GM;
111 value = SR_M_EXP | SR_EM | SR_GM;
112 rar = SYSREG_RAR_EX;
113 rsr = SYSREG_RSR_EX;
114 break;
116 case EXCP_INT0:
117 offset = env->autovector[0];
118 mask = SR_M | SR_J | SR_R | SR_I0M;
119 value = SR_M_INT0 | SR_I0M;
121 rar = SYSREG_RAR_INT0;
122 rsr = SYSREG_RSR_INT0;
123 break;
125 default:
126 cpu_abort(env, "Unhandled exception 0x%x\n", env->exception_index);
129 env->sysreg[rsr] = env->sysreg[SYSREG_SR];
130 env->sysreg[rar] = env->regs[15];
131 env->sysreg[SYSREG_ECR] = offset >> 2;
133 if ((env->sysreg[SYSREG_SR] & SR_M) == SR_M_APP) {
134 env->sp_usr = env->regs[13];
135 env->regs[13] = env->sp_sys;
139 dbg("%s: offset: %x\n", __func__, offset);
140 dbg("%s: rar: %x\n", __func__, env->sysreg[rar]);
141 dbg("%s: SYSREG_RAR_EX: %x\n", __func__, env->sysreg[SYSREG_RAR_EX]);
143 env->sysreg[SYSREG_SR] = (env->sysreg[SYSREG_SR] &~ mask) | value;
144 env->regs[15] = env->sysreg[SYSREG_EVBA] + offset;
146 env->exception_index = 0;
149 int i;
151 for (i = 0; i < 16; i++)
152 dbg("env->regs[%d] = 0x%08x\n", i, env->regs[i]);
153 dbg("env->sp_usr = 0x%08x\n", env->sp_usr);
154 dbg("env->sp_sys = 0x%08x\n", env->sp_sys);
155 dbg("env->sysreg[SYSREG_SR] = 0x%08x\n", env->sysreg[SYSREG_SR]);