Commit bbaf29c76994ef762523bc8893a88cac701c87e7
1 parent
bffd92fe
* target-cris/op.c: Make sure the bit-test insn only updates the XNZ flags.
* target-cris/helper.c: Update ERP for user-mode simulation aswell. * hw/etraxfs_timer.c: Support multiple timers. * hw/etraxfs_ser.c: Multiple ports, the data just goes to stdout. git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4004 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
4 changed files
with
99 additions
and
60 deletions
hw/etraxfs_ser.c
| @@ -26,23 +26,28 @@ | @@ -26,23 +26,28 @@ | ||
| 26 | #include <ctype.h> | 26 | #include <ctype.h> |
| 27 | #include "hw.h" | 27 | #include "hw.h" |
| 28 | 28 | ||
| 29 | -#define RW_TR_DMA_EN 0xb0026004 | ||
| 30 | -#define RW_DOUT 0xb002601c | ||
| 31 | -#define RW_STAT_DIN 0xb0026020 | ||
| 32 | -#define R_STAT_DIN 0xb0026024 | 29 | +#define D(x) |
| 30 | + | ||
| 31 | +#define RW_TR_DMA_EN 0x04 | ||
| 32 | +#define RW_DOUT 0x1c | ||
| 33 | +#define RW_STAT_DIN 0x20 | ||
| 34 | +#define R_STAT_DIN 0x24 | ||
| 33 | 35 | ||
| 34 | static uint32_t ser_readb (void *opaque, target_phys_addr_t addr) | 36 | static uint32_t ser_readb (void *opaque, target_phys_addr_t addr) |
| 35 | { | 37 | { |
| 36 | - CPUState *env = opaque; | 38 | + CPUState *env; |
| 37 | uint32_t r = 0; | 39 | uint32_t r = 0; |
| 38 | - printf ("%s %x pc=%x\n", __func__, addr, env->pc); | 40 | + |
| 41 | + env = opaque; | ||
| 42 | + D(printf ("%s %x pc=%x\n", __func__, addr, env->pc)); | ||
| 39 | return r; | 43 | return r; |
| 40 | } | 44 | } |
| 41 | static uint32_t ser_readw (void *opaque, target_phys_addr_t addr) | 45 | static uint32_t ser_readw (void *opaque, target_phys_addr_t addr) |
| 42 | { | 46 | { |
| 43 | - CPUState *env = opaque; | 47 | + CPUState *env; |
| 44 | uint32_t r = 0; | 48 | uint32_t r = 0; |
| 45 | - printf ("%s %x pc=%x\n", __func__, addr, env->pc); | 49 | + env = opaque; |
| 50 | + D(printf ("%s %x pc=%x\n", __func__, addr, env->pc)); | ||
| 46 | return r; | 51 | return r; |
| 47 | } | 52 | } |
| 48 | 53 | ||
| @@ -51,7 +56,7 @@ static uint32_t ser_readl (void *opaque, target_phys_addr_t addr) | @@ -51,7 +56,7 @@ static uint32_t ser_readl (void *opaque, target_phys_addr_t addr) | ||
| 51 | CPUState *env = opaque; | 56 | CPUState *env = opaque; |
| 52 | uint32_t r = 0; | 57 | uint32_t r = 0; |
| 53 | 58 | ||
| 54 | - switch (addr) | 59 | + switch (addr & 0xfff) |
| 55 | { | 60 | { |
| 56 | case RW_TR_DMA_EN: | 61 | case RW_TR_DMA_EN: |
| 57 | break; | 62 | break; |
| @@ -70,21 +75,23 @@ static uint32_t ser_readl (void *opaque, target_phys_addr_t addr) | @@ -70,21 +75,23 @@ static uint32_t ser_readl (void *opaque, target_phys_addr_t addr) | ||
| 70 | static void | 75 | static void |
| 71 | ser_writeb (void *opaque, target_phys_addr_t addr, uint32_t value) | 76 | ser_writeb (void *opaque, target_phys_addr_t addr, uint32_t value) |
| 72 | { | 77 | { |
| 73 | - CPUState *env = opaque; | ||
| 74 | - printf ("%s %x %x pc=%x\n", __func__, addr, value, env->pc); | 78 | + CPUState *env; |
| 79 | + env = opaque; | ||
| 80 | + D(printf ("%s %x %x pc=%x\n", __func__, addr, value, env->pc)); | ||
| 75 | } | 81 | } |
| 76 | static void | 82 | static void |
| 77 | ser_writew (void *opaque, target_phys_addr_t addr, uint32_t value) | 83 | ser_writew (void *opaque, target_phys_addr_t addr, uint32_t value) |
| 78 | { | 84 | { |
| 79 | - CPUState *env = opaque; | ||
| 80 | - printf ("%s %x %x pc=%x\n", __func__, addr, value, env->pc); | 85 | + CPUState *env; |
| 86 | + env = opaque; | ||
| 87 | + D(printf ("%s %x %x pc=%x\n", __func__, addr, value, env->pc)); | ||
| 81 | } | 88 | } |
| 82 | static void | 89 | static void |
| 83 | ser_writel (void *opaque, target_phys_addr_t addr, uint32_t value) | 90 | ser_writel (void *opaque, target_phys_addr_t addr, uint32_t value) |
| 84 | { | 91 | { |
| 85 | CPUState *env = opaque; | 92 | CPUState *env = opaque; |
| 86 | 93 | ||
| 87 | - switch (addr) | 94 | + switch (addr & 0xfff) |
| 88 | { | 95 | { |
| 89 | case RW_TR_DMA_EN: | 96 | case RW_TR_DMA_EN: |
| 90 | break; | 97 | break; |
| @@ -119,4 +126,7 @@ void etraxfs_ser_init(CPUState *env, qemu_irq *irqs) | @@ -119,4 +126,7 @@ void etraxfs_ser_init(CPUState *env, qemu_irq *irqs) | ||
| 119 | 126 | ||
| 120 | ser_regs = cpu_register_io_memory(0, ser_read, ser_write, env); | 127 | ser_regs = cpu_register_io_memory(0, ser_read, ser_write, env); |
| 121 | cpu_register_physical_memory (0xb0026000, 0x3c, ser_regs); | 128 | cpu_register_physical_memory (0xb0026000, 0x3c, ser_regs); |
| 129 | + cpu_register_physical_memory (0xb0028000, 0x3c, ser_regs); | ||
| 130 | + cpu_register_physical_memory (0xb002a000, 0x3c, ser_regs); | ||
| 131 | + cpu_register_physical_memory (0xb002c000, 0x3c, ser_regs); | ||
| 122 | } | 132 | } |
hw/etraxfs_timer.c
| @@ -26,6 +26,8 @@ | @@ -26,6 +26,8 @@ | ||
| 26 | #include "hw.h" | 26 | #include "hw.h" |
| 27 | #include "qemu-timer.h" | 27 | #include "qemu-timer.h" |
| 28 | 28 | ||
| 29 | +#define D(x) | ||
| 30 | + | ||
| 29 | void etrax_ack_irq(CPUState *env, uint32_t mask); | 31 | void etrax_ack_irq(CPUState *env, uint32_t mask); |
| 30 | 32 | ||
| 31 | #define R_TIME 0xb001e038 | 33 | #define R_TIME 0xb001e038 |
| @@ -54,9 +56,18 @@ struct fs_timer_t { | @@ -54,9 +56,18 @@ struct fs_timer_t { | ||
| 54 | CPUState *env; | 56 | CPUState *env; |
| 55 | qemu_irq *irq; | 57 | qemu_irq *irq; |
| 56 | uint32_t mask; | 58 | uint32_t mask; |
| 59 | + struct timeval last; | ||
| 57 | }; | 60 | }; |
| 58 | 61 | ||
| 59 | -static struct fs_timer_t timer0; | 62 | +static struct fs_timer_t timer[2]; |
| 63 | + | ||
| 64 | +static inline int timer_index(target_phys_addr_t addr) | ||
| 65 | +{ | ||
| 66 | + int t = 0; | ||
| 67 | + if (addr >= 0xb005e000) | ||
| 68 | + t = 1; | ||
| 69 | + return t; | ||
| 70 | +} | ||
| 60 | 71 | ||
| 61 | /* diff two timevals. Return a single int in us. */ | 72 | /* diff two timevals. Return a single int in us. */ |
| 62 | int diff_timeval_us(struct timeval *a, struct timeval *b) | 73 | int diff_timeval_us(struct timeval *a, struct timeval *b) |
| @@ -71,16 +82,20 @@ int diff_timeval_us(struct timeval *a, struct timeval *b) | @@ -71,16 +82,20 @@ int diff_timeval_us(struct timeval *a, struct timeval *b) | ||
| 71 | 82 | ||
| 72 | static uint32_t timer_readb (void *opaque, target_phys_addr_t addr) | 83 | static uint32_t timer_readb (void *opaque, target_phys_addr_t addr) |
| 73 | { | 84 | { |
| 74 | - CPUState *env = opaque; | 85 | + CPUState *env; |
| 75 | uint32_t r = 0; | 86 | uint32_t r = 0; |
| 76 | - printf ("%s %x pc=%x\n", __func__, addr, env->pc); | 87 | + |
| 88 | + env = opaque; | ||
| 89 | + D(printf ("%s %x pc=%x\n", __func__, addr, env->pc)); | ||
| 77 | return r; | 90 | return r; |
| 78 | } | 91 | } |
| 79 | static uint32_t timer_readw (void *opaque, target_phys_addr_t addr) | 92 | static uint32_t timer_readw (void *opaque, target_phys_addr_t addr) |
| 80 | { | 93 | { |
| 81 | - CPUState *env = opaque; | 94 | + CPUState *env; |
| 82 | uint32_t r = 0; | 95 | uint32_t r = 0; |
| 83 | - printf ("%s %x pc=%x\n", __func__, addr, env->pc); | 96 | + |
| 97 | + env = opaque; | ||
| 98 | + D(printf ("%s %x pc=%x\n", __func__, addr, env->pc)); | ||
| 84 | return r; | 99 | return r; |
| 85 | } | 100 | } |
| 86 | 101 | ||
| @@ -88,24 +103,25 @@ static uint32_t timer_readl (void *opaque, target_phys_addr_t addr) | @@ -88,24 +103,25 @@ static uint32_t timer_readl (void *opaque, target_phys_addr_t addr) | ||
| 88 | { | 103 | { |
| 89 | CPUState *env = opaque; | 104 | CPUState *env = opaque; |
| 90 | uint32_t r = 0; | 105 | uint32_t r = 0; |
| 106 | + int t = timer_index(addr); | ||
| 91 | 107 | ||
| 92 | switch (addr) { | 108 | switch (addr) { |
| 93 | case R_TMR0_DATA: | 109 | case R_TMR0_DATA: |
| 94 | break; | 110 | break; |
| 95 | case R_TMR1_DATA: | 111 | case R_TMR1_DATA: |
| 96 | - printf ("R_TMR1_DATA\n"); | 112 | + D(printf ("R_TMR1_DATA\n")); |
| 97 | break; | 113 | break; |
| 98 | case R_TIME: | 114 | case R_TIME: |
| 99 | { | 115 | { |
| 100 | - static struct timeval last; | ||
| 101 | struct timeval now; | 116 | struct timeval now; |
| 102 | gettimeofday(&now, NULL); | 117 | gettimeofday(&now, NULL); |
| 103 | - if (!(last.tv_sec == 0 && last.tv_usec == 0)) { | ||
| 104 | - r = diff_timeval_us(&now, &last); | 118 | + if (!(timer[t].last.tv_sec == 0 |
| 119 | + && timer[t].last.tv_usec == 0)) { | ||
| 120 | + r = diff_timeval_us(&now, &timer[t].last); | ||
| 105 | r *= 1000; /* convert to ns. */ | 121 | r *= 1000; /* convert to ns. */ |
| 106 | r++; /* make sure we increase for each call. */ | 122 | r++; /* make sure we increase for each call. */ |
| 107 | } | 123 | } |
| 108 | - last = now; | 124 | + timer[t].last = now; |
| 109 | break; | 125 | break; |
| 110 | } | 126 | } |
| 111 | 127 | ||
| @@ -125,14 +141,16 @@ static uint32_t timer_readl (void *opaque, target_phys_addr_t addr) | @@ -125,14 +141,16 @@ static uint32_t timer_readl (void *opaque, target_phys_addr_t addr) | ||
| 125 | static void | 141 | static void |
| 126 | timer_writeb (void *opaque, target_phys_addr_t addr, uint32_t value) | 142 | timer_writeb (void *opaque, target_phys_addr_t addr, uint32_t value) |
| 127 | { | 143 | { |
| 128 | - CPUState *env = opaque; | ||
| 129 | - printf ("%s %x %x pc=%x\n", __func__, addr, value, env->pc); | 144 | + CPUState *env; |
| 145 | + env = opaque; | ||
| 146 | + D(printf ("%s %x %x pc=%x\n", __func__, addr, value, env->pc)); | ||
| 130 | } | 147 | } |
| 131 | static void | 148 | static void |
| 132 | timer_writew (void *opaque, target_phys_addr_t addr, uint32_t value) | 149 | timer_writew (void *opaque, target_phys_addr_t addr, uint32_t value) |
| 133 | { | 150 | { |
| 134 | - CPUState *env = opaque; | ||
| 135 | - printf ("%s %x %x pc=%x\n", __func__, addr, value, env->pc); | 151 | + CPUState *env; |
| 152 | + env = opaque; | ||
| 153 | + D(printf ("%s %x %x pc=%x\n", __func__, addr, value, env->pc)); | ||
| 136 | } | 154 | } |
| 137 | 155 | ||
| 138 | static void write_ctrl(struct fs_timer_t *t, uint32_t v) | 156 | static void write_ctrl(struct fs_timer_t *t, uint32_t v) |
| @@ -165,7 +183,7 @@ static void write_ctrl(struct fs_timer_t *t, uint32_t v) | @@ -165,7 +183,7 @@ static void write_ctrl(struct fs_timer_t *t, uint32_t v) | ||
| 165 | if (t->limit > 2048) | 183 | if (t->limit > 2048) |
| 166 | { | 184 | { |
| 167 | t->scale = 2048; | 185 | t->scale = 2048; |
| 168 | - ptimer_set_period(timer0.ptimer, freq_hz / t->scale); | 186 | + ptimer_set_period(t->ptimer, freq_hz / t->scale); |
| 169 | } | 187 | } |
| 170 | 188 | ||
| 171 | printf ("op=%d\n", op); | 189 | printf ("op=%d\n", op); |
| @@ -187,11 +205,11 @@ static void write_ctrl(struct fs_timer_t *t, uint32_t v) | @@ -187,11 +205,11 @@ static void write_ctrl(struct fs_timer_t *t, uint32_t v) | ||
| 187 | } | 205 | } |
| 188 | } | 206 | } |
| 189 | 207 | ||
| 190 | -static void timer_ack_irq(void) | 208 | +static void timer_ack_irq(struct fs_timer_t *t) |
| 191 | { | 209 | { |
| 192 | - if (!(r_intr & timer0.mask & rw_intr_mask)) { | ||
| 193 | - qemu_irq_lower(timer0.irq[0]); | ||
| 194 | - etrax_ack_irq(timer0.env, 1 << 0x1b); | 210 | + if (!(r_intr & t->mask & rw_intr_mask)) { |
| 211 | + qemu_irq_lower(t->irq[0]); | ||
| 212 | + etrax_ack_irq(t->env, 1 << 0x1b); | ||
| 195 | } | 213 | } |
| 196 | } | 214 | } |
| 197 | 215 | ||
| @@ -199,31 +217,33 @@ static void | @@ -199,31 +217,33 @@ static void | ||
| 199 | timer_writel (void *opaque, target_phys_addr_t addr, uint32_t value) | 217 | timer_writel (void *opaque, target_phys_addr_t addr, uint32_t value) |
| 200 | { | 218 | { |
| 201 | CPUState *env = opaque; | 219 | CPUState *env = opaque; |
| 202 | - printf ("%s %x %x pc=%x\n", | ||
| 203 | - __func__, addr, value, env->pc); | 220 | + int t = timer_index(addr); |
| 221 | + | ||
| 222 | + D(printf ("%s %x %x pc=%x\n", | ||
| 223 | + __func__, addr, value, env->pc)); | ||
| 204 | switch (addr) | 224 | switch (addr) |
| 205 | { | 225 | { |
| 206 | case RW_TMR0_DIV: | 226 | case RW_TMR0_DIV: |
| 207 | - printf ("RW_TMR0_DIV=%x\n", value); | ||
| 208 | - timer0.limit = value; | 227 | + D(printf ("RW_TMR0_DIV=%x\n", value)); |
| 228 | + timer[t].limit = value; | ||
| 209 | break; | 229 | break; |
| 210 | case RW_TMR0_CTRL: | 230 | case RW_TMR0_CTRL: |
| 211 | - printf ("RW_TMR0_CTRL=%x\n", value); | ||
| 212 | - write_ctrl(&timer0, value); | 231 | + D(printf ("RW_TMR0_CTRL=%x\n", value)); |
| 232 | + write_ctrl(&timer[t], value); | ||
| 213 | break; | 233 | break; |
| 214 | case RW_TMR1_DIV: | 234 | case RW_TMR1_DIV: |
| 215 | - printf ("RW_TMR1_DIV=%x\n", value); | 235 | + D(printf ("RW_TMR1_DIV=%x\n", value)); |
| 216 | break; | 236 | break; |
| 217 | case RW_TMR1_CTRL: | 237 | case RW_TMR1_CTRL: |
| 218 | - printf ("RW_TMR1_CTRL=%x\n", value); | 238 | + D(printf ("RW_TMR1_CTRL=%x\n", value)); |
| 219 | break; | 239 | break; |
| 220 | case RW_INTR_MASK: | 240 | case RW_INTR_MASK: |
| 221 | - printf ("RW_INTR_MASK=%x\n", value); | 241 | + D(printf ("RW_INTR_MASK=%x\n", value)); |
| 222 | rw_intr_mask = value; | 242 | rw_intr_mask = value; |
| 223 | break; | 243 | break; |
| 224 | case RW_ACK_INTR: | 244 | case RW_ACK_INTR: |
| 225 | r_intr &= ~value; | 245 | r_intr &= ~value; |
| 226 | - timer_ack_irq(); | 246 | + timer_ack_irq(&timer[t]); |
| 227 | break; | 247 | break; |
| 228 | default: | 248 | default: |
| 229 | printf ("%s %x %x pc=%x\n", | 249 | printf ("%s %x %x pc=%x\n", |
| @@ -247,7 +267,6 @@ static CPUWriteMemoryFunc *timer_write[] = { | @@ -247,7 +267,6 @@ static CPUWriteMemoryFunc *timer_write[] = { | ||
| 247 | static void timer_irq(void *opaque) | 267 | static void timer_irq(void *opaque) |
| 248 | { | 268 | { |
| 249 | struct fs_timer_t *t = opaque; | 269 | struct fs_timer_t *t = opaque; |
| 250 | - | ||
| 251 | r_intr |= t->mask; | 270 | r_intr |= t->mask; |
| 252 | if (t->mask & rw_intr_mask) { | 271 | if (t->mask & rw_intr_mask) { |
| 253 | qemu_irq_raise(t->irq[0]); | 272 | qemu_irq_raise(t->irq[0]); |
| @@ -258,12 +277,19 @@ void etraxfs_timer_init(CPUState *env, qemu_irq *irqs) | @@ -258,12 +277,19 @@ void etraxfs_timer_init(CPUState *env, qemu_irq *irqs) | ||
| 258 | { | 277 | { |
| 259 | int timer_regs; | 278 | int timer_regs; |
| 260 | 279 | ||
| 261 | - timer0.bh = qemu_bh_new(timer_irq, &timer0); | ||
| 262 | - timer0.ptimer = ptimer_init(timer0.bh); | ||
| 263 | - timer0.irq = irqs + 0x1b; | ||
| 264 | - timer0.mask = 1; | ||
| 265 | - timer0.env = env; | 280 | + timer[0].bh = qemu_bh_new(timer_irq, &timer[0]); |
| 281 | + timer[0].ptimer = ptimer_init(timer[0].bh); | ||
| 282 | + timer[0].irq = irqs + 0x1b; | ||
| 283 | + timer[0].mask = 1; | ||
| 284 | + timer[0].env = env; | ||
| 285 | + | ||
| 286 | + timer[1].bh = qemu_bh_new(timer_irq, &timer[1]); | ||
| 287 | + timer[1].ptimer = ptimer_init(timer[1].bh); | ||
| 288 | + timer[1].irq = irqs + 0x1b; | ||
| 289 | + timer[1].mask = 1; | ||
| 290 | + timer[1].env = env; | ||
| 266 | 291 | ||
| 267 | timer_regs = cpu_register_io_memory(0, timer_read, timer_write, env); | 292 | timer_regs = cpu_register_io_memory(0, timer_read, timer_write, env); |
| 268 | cpu_register_physical_memory (0xb001e000, 0x5c, timer_regs); | 293 | cpu_register_physical_memory (0xb001e000, 0x5c, timer_regs); |
| 294 | + cpu_register_physical_memory (0xb005e000, 0x5c, timer_regs); | ||
| 269 | } | 295 | } |
target-cris/helper.c
| @@ -32,22 +32,23 @@ | @@ -32,22 +32,23 @@ | ||
| 32 | 32 | ||
| 33 | void do_interrupt (CPUState *env) | 33 | void do_interrupt (CPUState *env) |
| 34 | { | 34 | { |
| 35 | - env->exception_index = -1; | 35 | + env->exception_index = -1; |
| 36 | + env->pregs[PR_ERP] = env->pc; | ||
| 36 | } | 37 | } |
| 37 | 38 | ||
| 38 | int cpu_cris_handle_mmu_fault(CPUState * env, target_ulong address, int rw, | 39 | int cpu_cris_handle_mmu_fault(CPUState * env, target_ulong address, int rw, |
| 39 | int mmu_idx, int is_softmmu) | 40 | int mmu_idx, int is_softmmu) |
| 40 | { | 41 | { |
| 41 | - env->exception_index = 0xaa; | ||
| 42 | - env->debug1 = address; | ||
| 43 | - cpu_dump_state(env, stderr, fprintf, 0); | ||
| 44 | - printf("%s addr=%x env->pc=%x\n", __func__, address, env->pc); | ||
| 45 | - return 1; | 42 | + env->exception_index = 0xaa; |
| 43 | + env->debug1 = address; | ||
| 44 | + cpu_dump_state(env, stderr, fprintf, 0); | ||
| 45 | + env->pregs[PR_ERP] = env->pc; | ||
| 46 | + return 1; | ||
| 46 | } | 47 | } |
| 47 | 48 | ||
| 48 | target_phys_addr_t cpu_get_phys_page_debug(CPUState * env, target_ulong addr) | 49 | target_phys_addr_t cpu_get_phys_page_debug(CPUState * env, target_ulong addr) |
| 49 | { | 50 | { |
| 50 | - return addr; | 51 | + return addr; |
| 51 | } | 52 | } |
| 52 | 53 | ||
| 53 | #else /* !CONFIG_USER_ONLY */ | 54 | #else /* !CONFIG_USER_ONLY */ |
| @@ -61,7 +62,6 @@ int cpu_cris_handle_mmu_fault (CPUState *env, target_ulong address, int rw, | @@ -61,7 +62,6 @@ int cpu_cris_handle_mmu_fault (CPUState *env, target_ulong address, int rw, | ||
| 61 | 62 | ||
| 62 | address &= TARGET_PAGE_MASK; | 63 | address &= TARGET_PAGE_MASK; |
| 63 | prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC; | 64 | prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC; |
| 64 | -// printf ("%s pc=%x %x w=%d smmu=%d\n", __func__, env->pc, address, rw, is_softmmu); | ||
| 65 | miss = cris_mmu_translate(&res, env, address, rw, mmu_idx); | 65 | miss = cris_mmu_translate(&res, env, address, rw, mmu_idx); |
| 66 | if (miss) | 66 | if (miss) |
| 67 | { | 67 | { |
| @@ -73,7 +73,6 @@ int cpu_cris_handle_mmu_fault (CPUState *env, target_ulong address, int rw, | @@ -73,7 +73,6 @@ int cpu_cris_handle_mmu_fault (CPUState *env, target_ulong address, int rw, | ||
| 73 | { | 73 | { |
| 74 | phy = res.phy; | 74 | phy = res.phy; |
| 75 | } | 75 | } |
| 76 | -// printf ("a=%x phy=%x\n", address, phy); | ||
| 77 | return tlb_set_page(env, address, phy, prot, mmu_idx, is_softmmu); | 76 | return tlb_set_page(env, address, phy, prot, mmu_idx, is_softmmu); |
| 78 | } | 77 | } |
| 79 | 78 | ||
| @@ -113,7 +112,6 @@ void do_interrupt(CPUState *env) | @@ -113,7 +112,6 @@ void do_interrupt(CPUState *env) | ||
| 113 | 112 | ||
| 114 | break; | 113 | break; |
| 115 | case EXCP_MMU_MISS: | 114 | case EXCP_MMU_MISS: |
| 116 | -// printf ("MMU miss\n"); | ||
| 117 | irqnum = 4; | 115 | irqnum = 4; |
| 118 | ebp = env->pregs[PR_EBP]; | 116 | ebp = env->pregs[PR_EBP]; |
| 119 | isr = ldl_code(ebp + irqnum * 4); | 117 | isr = ldl_code(ebp + irqnum * 4); |
target-cris/op.c
| @@ -967,6 +967,8 @@ void OPPROTO op_btst_T0_T1 (void) | @@ -967,6 +967,8 @@ void OPPROTO op_btst_T0_T1 (void) | ||
| 967 | The N flag is set according to the selected bit in the dest reg. | 967 | The N flag is set according to the selected bit in the dest reg. |
| 968 | The Z flag is set if the selected bit and all bits to the right are | 968 | The Z flag is set if the selected bit and all bits to the right are |
| 969 | zero. | 969 | zero. |
| 970 | + The X flag is cleared. | ||
| 971 | + Other flags are left untouched. | ||
| 970 | The destination reg is not affected.*/ | 972 | The destination reg is not affected.*/ |
| 971 | unsigned int fz, sbit, bset, mask, masked_t0; | 973 | unsigned int fz, sbit, bset, mask, masked_t0; |
| 972 | 974 | ||
| @@ -975,8 +977,11 @@ void OPPROTO op_btst_T0_T1 (void) | @@ -975,8 +977,11 @@ void OPPROTO op_btst_T0_T1 (void) | ||
| 975 | mask = sbit == 31 ? -1 : (1 << (sbit + 1)) - 1; | 977 | mask = sbit == 31 ? -1 : (1 << (sbit + 1)) - 1; |
| 976 | masked_t0 = T0 & mask; | 978 | masked_t0 = T0 & mask; |
| 977 | fz = !(masked_t0 | bset); | 979 | fz = !(masked_t0 | bset); |
| 980 | + | ||
| 981 | + /* Clear the X, N and Z flags. */ | ||
| 982 | + T0 = env->pregs[PR_CCS] & ~(X_FLAG | N_FLAG | Z_FLAG); | ||
| 978 | /* Set the N and Z flags accordingly. */ | 983 | /* Set the N and Z flags accordingly. */ |
| 979 | - T0 = (bset << 3) | (fz << 2); | 984 | + T0 |= (bset << 3) | (fz << 2); |
| 980 | RETURN(); | 985 | RETURN(); |
| 981 | } | 986 | } |
| 982 | 987 |