Commit ca87d03b77aade91926972b7e20b5382b59d1c77
1 parent
05ba7d5f
Made the etrax timers and serial-ports base address relocatable. Use target_phys…
…_addr_t instead of target_ulong. git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4058 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
4 changed files
with
95 additions
and
121 deletions
hw/etraxfs.c
... | ... | @@ -35,10 +35,10 @@ static void main_cpu_reset(void *opaque) |
35 | 35 | } |
36 | 36 | |
37 | 37 | /* Init functions for different blocks. */ |
38 | -extern qemu_irq *etraxfs_pic_init(CPUState *env, target_ulong base); | |
39 | -/* TODO: Make these blocks relocate:able. */ | |
40 | -extern void etraxfs_timer_init(CPUState *env, qemu_irq *irqs); | |
41 | -extern void etraxfs_ser_init(CPUState *env, qemu_irq *irqs); | |
38 | +extern qemu_irq *etraxfs_pic_init(CPUState *env, target_phys_addr_t base); | |
39 | +void etraxfs_timer_init(CPUState *env, qemu_irq *irqs, | |
40 | + target_phys_addr_t base); | |
41 | +void etraxfs_ser_init(CPUState *env, qemu_irq *irqs, target_phys_addr_t base); | |
42 | 42 | |
43 | 43 | static |
44 | 44 | void bareetraxfs_init (int ram_size, int vga_ram_size, |
... | ... | @@ -84,8 +84,14 @@ void bareetraxfs_init (int ram_size, int vga_ram_size, |
84 | 84 | 4, 0x0000, 0x0000, 0x0000, 0x0000); |
85 | 85 | |
86 | 86 | pic = etraxfs_pic_init(env, 0xb001c000); |
87 | - etraxfs_timer_init(env, pic); | |
88 | - etraxfs_ser_init(env, pic); | |
87 | + /* 2 timers. */ | |
88 | + etraxfs_timer_init(env, pic, 0xb001e000); | |
89 | + etraxfs_timer_init(env, pic, 0xb005e000); | |
90 | + /* 4 serial ports. */ | |
91 | + etraxfs_ser_init(env, pic, 0xb0026000); | |
92 | + etraxfs_ser_init(env, pic, 0xb0028000); | |
93 | + etraxfs_ser_init(env, pic, 0xb002a000); | |
94 | + etraxfs_ser_init(env, pic, 0xb002c000); | |
89 | 95 | |
90 | 96 | kernel_size = load_image(kernel_filename, phys_ram_base + 0x4000); |
91 | 97 | /* magic for boot. */ | ... | ... |
hw/etraxfs_pic.c
... | ... | @@ -30,7 +30,7 @@ |
30 | 30 | struct fs_pic_state_t |
31 | 31 | { |
32 | 32 | CPUState *env; |
33 | - target_ulong base; | |
33 | + target_phys_addr_t base; | |
34 | 34 | |
35 | 35 | uint32_t rw_mask; |
36 | 36 | /* Active interrupt lines. */ |
... | ... | @@ -186,7 +186,7 @@ static void etraxfs_pic_handler(void *opaque, int irq, int level) |
186 | 186 | } |
187 | 187 | } |
188 | 188 | |
189 | -qemu_irq *etraxfs_pic_init(CPUState *env, target_ulong base) | |
189 | +qemu_irq *etraxfs_pic_init(CPUState *env, target_phys_addr_t base) | |
190 | 190 | { |
191 | 191 | struct fs_pic_state_t *fs; |
192 | 192 | qemu_irq *pic; | ... | ... |
hw/etraxfs_ser.c
... | ... | @@ -35,25 +35,20 @@ |
35 | 35 | |
36 | 36 | static uint32_t ser_readb (void *opaque, target_phys_addr_t addr) |
37 | 37 | { |
38 | - CPUState *env; | |
39 | - uint32_t r = 0; | |
40 | - | |
41 | - env = opaque; | |
38 | + D(CPUState *env = opaque); | |
42 | 39 | D(printf ("%s %x pc=%x\n", __func__, addr, env->pc)); |
43 | - return r; | |
40 | + return 0; | |
44 | 41 | } |
45 | 42 | static uint32_t ser_readw (void *opaque, target_phys_addr_t addr) |
46 | 43 | { |
47 | - CPUState *env; | |
48 | - uint32_t r = 0; | |
49 | - env = opaque; | |
44 | + D(CPUState *env = opaque); | |
50 | 45 | D(printf ("%s %x pc=%x\n", __func__, addr, env->pc)); |
51 | - return r; | |
46 | + return 0; | |
52 | 47 | } |
53 | 48 | |
54 | 49 | static uint32_t ser_readl (void *opaque, target_phys_addr_t addr) |
55 | 50 | { |
56 | - CPUState *env = opaque; | |
51 | + D(CPUState *env = opaque); | |
57 | 52 | uint32_t r = 0; |
58 | 53 | |
59 | 54 | switch (addr & 0xfff) |
... | ... | @@ -75,21 +70,19 @@ static uint32_t ser_readl (void *opaque, target_phys_addr_t addr) |
75 | 70 | static void |
76 | 71 | ser_writeb (void *opaque, target_phys_addr_t addr, uint32_t value) |
77 | 72 | { |
78 | - CPUState *env; | |
79 | - env = opaque; | |
73 | + D(CPUState *env = opaque); | |
80 | 74 | D(printf ("%s %x %x pc=%x\n", __func__, addr, value, env->pc)); |
81 | 75 | } |
82 | 76 | static void |
83 | 77 | ser_writew (void *opaque, target_phys_addr_t addr, uint32_t value) |
84 | 78 | { |
85 | - CPUState *env; | |
86 | - env = opaque; | |
79 | + D(CPUState *env = opaque); | |
87 | 80 | D(printf ("%s %x %x pc=%x\n", __func__, addr, value, env->pc)); |
88 | 81 | } |
89 | 82 | static void |
90 | 83 | ser_writel (void *opaque, target_phys_addr_t addr, uint32_t value) |
91 | 84 | { |
92 | - CPUState *env = opaque; | |
85 | + D(CPUState *env = opaque); | |
93 | 86 | |
94 | 87 | switch (addr & 0xfff) |
95 | 88 | { |
... | ... | @@ -110,24 +103,20 @@ ser_writel (void *opaque, target_phys_addr_t addr, uint32_t value) |
110 | 103 | } |
111 | 104 | |
112 | 105 | static CPUReadMemoryFunc *ser_read[] = { |
113 | - &ser_readb, | |
114 | - &ser_readw, | |
115 | - &ser_readl, | |
106 | + &ser_readb, | |
107 | + &ser_readw, | |
108 | + &ser_readl, | |
116 | 109 | }; |
117 | 110 | |
118 | 111 | static CPUWriteMemoryFunc *ser_write[] = { |
119 | - &ser_writeb, | |
120 | - &ser_writew, | |
121 | - &ser_writel, | |
112 | + &ser_writeb, | |
113 | + &ser_writew, | |
114 | + &ser_writel, | |
122 | 115 | }; |
123 | 116 | |
124 | -void etraxfs_ser_init(CPUState *env, qemu_irq *irqs) | |
117 | +void etraxfs_ser_init(CPUState *env, qemu_irq *irqs, target_phys_addr_t base) | |
125 | 118 | { |
126 | 119 | int ser_regs; |
127 | - | |
128 | 120 | ser_regs = cpu_register_io_memory(0, ser_read, ser_write, env); |
129 | - cpu_register_physical_memory (0xb0026000, 0x3c, ser_regs); | |
130 | - cpu_register_physical_memory (0xb0028000, 0x3c, ser_regs); | |
131 | - cpu_register_physical_memory (0xb002a000, 0x3c, ser_regs); | |
132 | - cpu_register_physical_memory (0xb002c000, 0x3c, ser_regs); | |
121 | + cpu_register_physical_memory (base, 0x3c, ser_regs); | |
133 | 122 | } | ... | ... |
hw/etraxfs_timer.c
... | ... | @@ -28,27 +28,28 @@ |
28 | 28 | |
29 | 29 | #define D(x) |
30 | 30 | |
31 | -#define R_TIME 0xb001e038 | |
32 | -#define RW_TMR0_DIV 0xb001e000 | |
33 | -#define R_TMR0_DATA 0xb001e004 | |
34 | -#define RW_TMR0_CTRL 0xb001e008 | |
35 | -#define RW_TMR1_DIV 0xb001e010 | |
36 | -#define R_TMR1_DATA 0xb001e014 | |
37 | -#define RW_TMR1_CTRL 0xb001e018 | |
38 | - | |
39 | -#define RW_WD_CTRL 0xb001e040 | |
40 | -#define RW_INTR_MASK 0xb001e048 | |
41 | -#define RW_ACK_INTR 0xb001e04c | |
42 | -#define R_INTR 0xb001e050 | |
43 | -#define R_MASKED_INTR 0xb001e054 | |
31 | +#define RW_TMR0_DIV 0x00 | |
32 | +#define R_TMR0_DATA 0x04 | |
33 | +#define RW_TMR0_CTRL 0x08 | |
34 | +#define RW_TMR1_DIV 0x10 | |
35 | +#define R_TMR1_DATA 0x14 | |
36 | +#define RW_TMR1_CTRL 0x18 | |
37 | +#define R_TIME 0x38 | |
38 | +#define RW_WD_CTRL 0x40 | |
39 | +#define RW_INTR_MASK 0x48 | |
40 | +#define RW_ACK_INTR 0x4c | |
41 | +#define R_INTR 0x50 | |
42 | +#define R_MASKED_INTR 0x54 | |
44 | 43 | |
45 | 44 | struct fs_timer_t { |
45 | + CPUState *env; | |
46 | + qemu_irq *irq; | |
47 | + target_phys_addr_t base; | |
48 | + | |
46 | 49 | QEMUBH *bh; |
50 | + ptimer_state *ptimer; | |
47 | 51 | unsigned int limit; |
48 | 52 | int scale; |
49 | - ptimer_state *ptimer; | |
50 | - CPUState *env; | |
51 | - qemu_irq *irq; | |
52 | 53 | uint32_t mask; |
53 | 54 | struct timeval last; |
54 | 55 | |
... | ... | @@ -57,16 +58,6 @@ struct fs_timer_t { |
57 | 58 | uint32_t r_intr; |
58 | 59 | }; |
59 | 60 | |
60 | -static struct fs_timer_t timer[2]; | |
61 | - | |
62 | -static inline int timer_index(target_phys_addr_t addr) | |
63 | -{ | |
64 | - int t = 0; | |
65 | - if (addr >= 0xb005e000) | |
66 | - t = 1; | |
67 | - return t; | |
68 | -} | |
69 | - | |
70 | 61 | /* diff two timevals. Return a single int in us. */ |
71 | 62 | int diff_timeval_us(struct timeval *a, struct timeval *b) |
72 | 63 | { |
... | ... | @@ -78,31 +69,23 @@ int diff_timeval_us(struct timeval *a, struct timeval *b) |
78 | 69 | return diff; |
79 | 70 | } |
80 | 71 | |
81 | -static uint32_t timer_readb (void *opaque, target_phys_addr_t addr) | |
72 | +static uint32_t timer_rinvalid (void *opaque, target_phys_addr_t addr) | |
82 | 73 | { |
83 | - CPUState *env; | |
84 | - uint32_t r = 0; | |
85 | - | |
86 | - env = opaque; | |
87 | - D(printf ("%s %x pc=%x\n", __func__, addr, env->pc)); | |
88 | - return r; | |
89 | -} | |
90 | -static uint32_t timer_readw (void *opaque, target_phys_addr_t addr) | |
91 | -{ | |
92 | - CPUState *env; | |
93 | - uint32_t r = 0; | |
94 | - | |
95 | - env = opaque; | |
96 | - D(printf ("%s %x pc=%x\n", __func__, addr, env->pc)); | |
97 | - return r; | |
74 | + struct fs_timer_t *t = opaque; | |
75 | + CPUState *env = t->env; | |
76 | + cpu_abort(env, "Unsupported short access. reg=%x pc=%x.\n", | |
77 | + addr, env->pc); | |
78 | + return 0; | |
98 | 79 | } |
99 | 80 | |
100 | 81 | static uint32_t timer_readl (void *opaque, target_phys_addr_t addr) |
101 | 82 | { |
102 | - CPUState *env = opaque; | |
83 | + struct fs_timer_t *t = opaque; | |
84 | + D(CPUState *env = t->env); | |
103 | 85 | uint32_t r = 0; |
104 | - int t = timer_index(addr); | |
105 | 86 | |
87 | + /* Make addr relative to this instances base. */ | |
88 | + addr -= t->base; | |
106 | 89 | switch (addr) { |
107 | 90 | case R_TMR0_DATA: |
108 | 91 | break; |
... | ... | @@ -113,21 +96,21 @@ static uint32_t timer_readl (void *opaque, target_phys_addr_t addr) |
113 | 96 | { |
114 | 97 | struct timeval now; |
115 | 98 | gettimeofday(&now, NULL); |
116 | - if (!(timer[t].last.tv_sec == 0 | |
117 | - && timer[t].last.tv_usec == 0)) { | |
118 | - r = diff_timeval_us(&now, &timer[t].last); | |
99 | + if (!(t->last.tv_sec == 0 | |
100 | + && t->last.tv_usec == 0)) { | |
101 | + r = diff_timeval_us(&now, &t->last); | |
119 | 102 | r *= 1000; /* convert to ns. */ |
120 | 103 | r++; /* make sure we increase for each call. */ |
121 | 104 | } |
122 | - timer[t].last = now; | |
105 | + t->last = now; | |
123 | 106 | break; |
124 | 107 | } |
125 | 108 | |
126 | 109 | case RW_INTR_MASK: |
127 | - r = timer[t].rw_intr_mask; | |
110 | + r = t->rw_intr_mask; | |
128 | 111 | break; |
129 | 112 | case R_MASKED_INTR: |
130 | - r = timer[t].r_intr & timer[t].rw_intr_mask; | |
113 | + r = t->r_intr & t->rw_intr_mask; | |
131 | 114 | break; |
132 | 115 | default: |
133 | 116 | D(printf ("%s %x p=%x\n", __func__, addr, env->pc)); |
... | ... | @@ -137,18 +120,12 @@ static uint32_t timer_readl (void *opaque, target_phys_addr_t addr) |
137 | 120 | } |
138 | 121 | |
139 | 122 | static void |
140 | -timer_writeb (void *opaque, target_phys_addr_t addr, uint32_t value) | |
123 | +timer_winvalid (void *opaque, target_phys_addr_t addr, uint32_t value) | |
141 | 124 | { |
142 | - CPUState *env; | |
143 | - env = opaque; | |
144 | - D(printf ("%s %x %x pc=%x\n", __func__, addr, value, env->pc)); | |
145 | -} | |
146 | -static void | |
147 | -timer_writew (void *opaque, target_phys_addr_t addr, uint32_t value) | |
148 | -{ | |
149 | - CPUState *env; | |
150 | - env = opaque; | |
151 | - D(printf ("%s %x %x pc=%x\n", __func__, addr, value, env->pc)); | |
125 | + struct fs_timer_t *t = opaque; | |
126 | + CPUState *env = t->env; | |
127 | + cpu_abort(env, "Unsupported short access. reg=%x pc=%x.\n", | |
128 | + addr, env->pc); | |
152 | 129 | } |
153 | 130 | |
154 | 131 | static void write_ctrl(struct fs_timer_t *t, uint32_t v) |
... | ... | @@ -212,20 +189,22 @@ static void timer_ack_irq(struct fs_timer_t *t) |
212 | 189 | static void |
213 | 190 | timer_writel (void *opaque, target_phys_addr_t addr, uint32_t value) |
214 | 191 | { |
215 | - CPUState *env = opaque; | |
216 | - int t = timer_index(addr); | |
192 | + struct fs_timer_t *t = opaque; | |
193 | + CPUState *env = t->env; | |
217 | 194 | |
218 | 195 | D(printf ("%s %x %x pc=%x\n", |
219 | 196 | __func__, addr, value, env->pc)); |
197 | + /* Make addr relative to this instances base. */ | |
198 | + addr -= t->base; | |
220 | 199 | switch (addr) |
221 | 200 | { |
222 | 201 | case RW_TMR0_DIV: |
223 | 202 | D(printf ("RW_TMR0_DIV=%x\n", value)); |
224 | - timer[t].limit = value; | |
203 | + t->limit = value; | |
225 | 204 | break; |
226 | 205 | case RW_TMR0_CTRL: |
227 | 206 | D(printf ("RW_TMR0_CTRL=%x\n", value)); |
228 | - write_ctrl(&timer[t], value); | |
207 | + write_ctrl(t, value); | |
229 | 208 | break; |
230 | 209 | case RW_TMR1_DIV: |
231 | 210 | D(printf ("RW_TMR1_DIV=%x\n", value)); |
... | ... | @@ -235,14 +214,14 @@ timer_writel (void *opaque, target_phys_addr_t addr, uint32_t value) |
235 | 214 | break; |
236 | 215 | case RW_INTR_MASK: |
237 | 216 | D(printf ("RW_INTR_MASK=%x\n", value)); |
238 | - timer[t].rw_intr_mask = value; | |
217 | + t->rw_intr_mask = value; | |
239 | 218 | break; |
240 | 219 | case RW_WD_CTRL: |
241 | 220 | D(printf ("RW_WD_CTRL=%x\n", value)); |
242 | 221 | break; |
243 | 222 | case RW_ACK_INTR: |
244 | - timer[t].r_intr &= ~value; | |
245 | - timer_ack_irq(&timer[t]); | |
223 | + t->r_intr &= ~value; | |
224 | + timer_ack_irq(t); | |
246 | 225 | break; |
247 | 226 | default: |
248 | 227 | printf ("%s %x %x pc=%x\n", |
... | ... | @@ -252,14 +231,14 @@ timer_writel (void *opaque, target_phys_addr_t addr, uint32_t value) |
252 | 231 | } |
253 | 232 | |
254 | 233 | static CPUReadMemoryFunc *timer_read[] = { |
255 | - &timer_readb, | |
256 | - &timer_readw, | |
234 | + &timer_rinvalid, | |
235 | + &timer_rinvalid, | |
257 | 236 | &timer_readl, |
258 | 237 | }; |
259 | 238 | |
260 | 239 | static CPUWriteMemoryFunc *timer_write[] = { |
261 | - &timer_writeb, | |
262 | - &timer_writew, | |
240 | + &timer_winvalid, | |
241 | + &timer_winvalid, | |
263 | 242 | &timer_writel, |
264 | 243 | }; |
265 | 244 | |
... | ... | @@ -273,23 +252,23 @@ static void timer_irq(void *opaque) |
273 | 252 | } |
274 | 253 | } |
275 | 254 | |
276 | -void etraxfs_timer_init(CPUState *env, qemu_irq *irqs) | |
255 | +void etraxfs_timer_init(CPUState *env, qemu_irq *irqs, | |
256 | + target_phys_addr_t base) | |
277 | 257 | { |
258 | + static struct fs_timer_t *t; | |
278 | 259 | int timer_regs; |
279 | 260 | |
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 + 26; | |
283 | - timer[0].mask = 1; | |
284 | - timer[0].env = env; | |
261 | + t = qemu_mallocz(sizeof *t); | |
262 | + if (!t) | |
263 | + return; | |
285 | 264 | |
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 + 26; | |
289 | - timer[1].mask = 1; | |
290 | - timer[1].env = env; | |
265 | + t->bh = qemu_bh_new(timer_irq, t); | |
266 | + t->ptimer = ptimer_init(t->bh); | |
267 | + t->irq = irqs + 26; | |
268 | + t->mask = 1; | |
269 | + t->env = env; | |
270 | + t->base = base; | |
291 | 271 | |
292 | - timer_regs = cpu_register_io_memory(0, timer_read, timer_write, env); | |
293 | - cpu_register_physical_memory (0xb001e000, 0x5c, timer_regs); | |
294 | - cpu_register_physical_memory (0xb005e000, 0x5c, timer_regs); | |
272 | + timer_regs = cpu_register_io_memory(0, timer_read, timer_write, t); | |
273 | + cpu_register_physical_memory (base, 0x5c, timer_regs); | |
295 | 274 | } | ... | ... |