Revision bbaf29c7
b/hw/etraxfs_ser.c | ||
---|---|---|
26 | 26 |
#include <ctype.h> |
27 | 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 | 36 |
static uint32_t ser_readb (void *opaque, target_phys_addr_t addr) |
35 | 37 |
{ |
36 |
CPUState *env = opaque;
|
|
38 |
CPUState *env; |
|
37 | 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 | 43 |
return r; |
40 | 44 |
} |
41 | 45 |
static uint32_t ser_readw (void *opaque, target_phys_addr_t addr) |
42 | 46 |
{ |
43 |
CPUState *env = opaque;
|
|
47 |
CPUState *env; |
|
44 | 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 | 51 |
return r; |
47 | 52 |
} |
48 | 53 |
|
... | ... | |
51 | 56 |
CPUState *env = opaque; |
52 | 57 |
uint32_t r = 0; |
53 | 58 |
|
54 |
switch (addr) |
|
59 |
switch (addr & 0xfff)
|
|
55 | 60 |
{ |
56 | 61 |
case RW_TR_DMA_EN: |
57 | 62 |
break; |
... | ... | |
70 | 75 |
static void |
71 | 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 | 82 |
static void |
77 | 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 | 89 |
static void |
83 | 90 |
ser_writel (void *opaque, target_phys_addr_t addr, uint32_t value) |
84 | 91 |
{ |
85 | 92 |
CPUState *env = opaque; |
86 | 93 |
|
87 |
switch (addr) |
|
94 |
switch (addr & 0xfff)
|
|
88 | 95 |
{ |
89 | 96 |
case RW_TR_DMA_EN: |
90 | 97 |
break; |
... | ... | |
119 | 126 |
|
120 | 127 |
ser_regs = cpu_register_io_memory(0, ser_read, ser_write, env); |
121 | 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 |
} |
b/hw/etraxfs_timer.c | ||
---|---|---|
26 | 26 |
#include "hw.h" |
27 | 27 |
#include "qemu-timer.h" |
28 | 28 |
|
29 |
#define D(x) |
|
30 |
|
|
29 | 31 |
void etrax_ack_irq(CPUState *env, uint32_t mask); |
30 | 32 |
|
31 | 33 |
#define R_TIME 0xb001e038 |
... | ... | |
54 | 56 |
CPUState *env; |
55 | 57 |
qemu_irq *irq; |
56 | 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 | 72 |
/* diff two timevals. Return a single int in us. */ |
62 | 73 |
int diff_timeval_us(struct timeval *a, struct timeval *b) |
... | ... | |
71 | 82 |
|
72 | 83 |
static uint32_t timer_readb (void *opaque, target_phys_addr_t addr) |
73 | 84 |
{ |
74 |
CPUState *env = opaque;
|
|
85 |
CPUState *env; |
|
75 | 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 | 90 |
return r; |
78 | 91 |
} |
79 | 92 |
static uint32_t timer_readw (void *opaque, target_phys_addr_t addr) |
80 | 93 |
{ |
81 |
CPUState *env = opaque;
|
|
94 |
CPUState *env; |
|
82 | 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 | 99 |
return r; |
85 | 100 |
} |
86 | 101 |
|
... | ... | |
88 | 103 |
{ |
89 | 104 |
CPUState *env = opaque; |
90 | 105 |
uint32_t r = 0; |
106 |
int t = timer_index(addr); |
|
91 | 107 |
|
92 | 108 |
switch (addr) { |
93 | 109 |
case R_TMR0_DATA: |
94 | 110 |
break; |
95 | 111 |
case R_TMR1_DATA: |
96 |
printf ("R_TMR1_DATA\n");
|
|
112 |
D(printf ("R_TMR1_DATA\n"));
|
|
97 | 113 |
break; |
98 | 114 |
case R_TIME: |
99 | 115 |
{ |
100 |
static struct timeval last; |
|
101 | 116 |
struct timeval now; |
102 | 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 | 121 |
r *= 1000; /* convert to ns. */ |
106 | 122 |
r++; /* make sure we increase for each call. */ |
107 | 123 |
} |
108 |
last = now; |
|
124 |
timer[t].last = now;
|
|
109 | 125 |
break; |
110 | 126 |
} |
111 | 127 |
|
... | ... | |
125 | 141 |
static void |
126 | 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 | 148 |
static void |
132 | 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 | 156 |
static void write_ctrl(struct fs_timer_t *t, uint32_t v) |
... | ... | |
165 | 183 |
if (t->limit > 2048) |
166 | 184 |
{ |
167 | 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 | 189 |
printf ("op=%d\n", op); |
... | ... | |
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 | 217 |
timer_writel (void *opaque, target_phys_addr_t addr, uint32_t value) |
200 | 218 |
{ |
201 | 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 | 224 |
switch (addr) |
205 | 225 |
{ |
206 | 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 | 229 |
break; |
210 | 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 | 233 |
break; |
214 | 234 |
case RW_TMR1_DIV: |
215 |
printf ("RW_TMR1_DIV=%x\n", value);
|
|
235 |
D(printf ("RW_TMR1_DIV=%x\n", value));
|
|
216 | 236 |
break; |
217 | 237 |
case RW_TMR1_CTRL: |
218 |
printf ("RW_TMR1_CTRL=%x\n", value);
|
|
238 |
D(printf ("RW_TMR1_CTRL=%x\n", value));
|
|
219 | 239 |
break; |
220 | 240 |
case RW_INTR_MASK: |
221 |
printf ("RW_INTR_MASK=%x\n", value);
|
|
241 |
D(printf ("RW_INTR_MASK=%x\n", value));
|
|
222 | 242 |
rw_intr_mask = value; |
223 | 243 |
break; |
224 | 244 |
case RW_ACK_INTR: |
225 | 245 |
r_intr &= ~value; |
226 |
timer_ack_irq(); |
|
246 |
timer_ack_irq(&timer[t]);
|
|
227 | 247 |
break; |
228 | 248 |
default: |
229 | 249 |
printf ("%s %x %x pc=%x\n", |
... | ... | |
247 | 267 |
static void timer_irq(void *opaque) |
248 | 268 |
{ |
249 | 269 |
struct fs_timer_t *t = opaque; |
250 |
|
|
251 | 270 |
r_intr |= t->mask; |
252 | 271 |
if (t->mask & rw_intr_mask) { |
253 | 272 |
qemu_irq_raise(t->irq[0]); |
... | ... | |
258 | 277 |
{ |
259 | 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 | 292 |
timer_regs = cpu_register_io_memory(0, timer_read, timer_write, env); |
268 | 293 |
cpu_register_physical_memory (0xb001e000, 0x5c, timer_regs); |
294 |
cpu_register_physical_memory (0xb005e000, 0x5c, timer_regs); |
|
269 | 295 |
} |
b/target-cris/helper.c | ||
---|---|---|
32 | 32 |
|
33 | 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 | 39 |
int cpu_cris_handle_mmu_fault(CPUState * env, target_ulong address, int rw, |
39 | 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 | 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 | 54 |
#else /* !CONFIG_USER_ONLY */ |
... | ... | |
61 | 62 |
|
62 | 63 |
address &= TARGET_PAGE_MASK; |
63 | 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 | 65 |
miss = cris_mmu_translate(&res, env, address, rw, mmu_idx); |
66 | 66 |
if (miss) |
67 | 67 |
{ |
... | ... | |
73 | 73 |
{ |
74 | 74 |
phy = res.phy; |
75 | 75 |
} |
76 |
// printf ("a=%x phy=%x\n", address, phy); |
|
77 | 76 |
return tlb_set_page(env, address, phy, prot, mmu_idx, is_softmmu); |
78 | 77 |
} |
79 | 78 |
|
... | ... | |
113 | 112 |
|
114 | 113 |
break; |
115 | 114 |
case EXCP_MMU_MISS: |
116 |
// printf ("MMU miss\n"); |
|
117 | 115 |
irqnum = 4; |
118 | 116 |
ebp = env->pregs[PR_EBP]; |
119 | 117 |
isr = ldl_code(ebp + irqnum * 4); |
b/target-cris/op.c | ||
---|---|---|
967 | 967 |
The N flag is set according to the selected bit in the dest reg. |
968 | 968 |
The Z flag is set if the selected bit and all bits to the right are |
969 | 969 |
zero. |
970 |
The X flag is cleared. |
|
971 |
Other flags are left untouched. |
|
970 | 972 |
The destination reg is not affected.*/ |
971 | 973 |
unsigned int fz, sbit, bset, mask, masked_t0; |
972 | 974 |
|
... | ... | |
975 | 977 |
mask = sbit == 31 ? -1 : (1 << (sbit + 1)) - 1; |
976 | 978 |
masked_t0 = T0 & mask; |
977 | 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 | 983 |
/* Set the N and Z flags accordingly. */ |
979 |
T0 = (bset << 3) | (fz << 2); |
|
984 |
T0 |= (bset << 3) | (fz << 2);
|
|
980 | 985 |
RETURN(); |
981 | 986 |
} |
982 | 987 |
|
Also available in: Unified diff