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,10 +35,10 @@ static void main_cpu_reset(void *opaque) | ||
| 35 | } | 35 | } |
| 36 | 36 | ||
| 37 | /* Init functions for different blocks. */ | 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 | static | 43 | static |
| 44 | void bareetraxfs_init (int ram_size, int vga_ram_size, | 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,8 +84,14 @@ void bareetraxfs_init (int ram_size, int vga_ram_size, | ||
| 84 | 4, 0x0000, 0x0000, 0x0000, 0x0000); | 84 | 4, 0x0000, 0x0000, 0x0000, 0x0000); |
| 85 | 85 | ||
| 86 | pic = etraxfs_pic_init(env, 0xb001c000); | 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 | kernel_size = load_image(kernel_filename, phys_ram_base + 0x4000); | 96 | kernel_size = load_image(kernel_filename, phys_ram_base + 0x4000); |
| 91 | /* magic for boot. */ | 97 | /* magic for boot. */ |
hw/etraxfs_pic.c
| @@ -30,7 +30,7 @@ | @@ -30,7 +30,7 @@ | ||
| 30 | struct fs_pic_state_t | 30 | struct fs_pic_state_t |
| 31 | { | 31 | { |
| 32 | CPUState *env; | 32 | CPUState *env; |
| 33 | - target_ulong base; | 33 | + target_phys_addr_t base; |
| 34 | 34 | ||
| 35 | uint32_t rw_mask; | 35 | uint32_t rw_mask; |
| 36 | /* Active interrupt lines. */ | 36 | /* Active interrupt lines. */ |
| @@ -186,7 +186,7 @@ static void etraxfs_pic_handler(void *opaque, int irq, int level) | @@ -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 | struct fs_pic_state_t *fs; | 191 | struct fs_pic_state_t *fs; |
| 192 | qemu_irq *pic; | 192 | qemu_irq *pic; |
hw/etraxfs_ser.c
| @@ -35,25 +35,20 @@ | @@ -35,25 +35,20 @@ | ||
| 35 | 35 | ||
| 36 | 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) |
| 37 | { | 37 | { |
| 38 | - CPUState *env; | ||
| 39 | - uint32_t r = 0; | ||
| 40 | - | ||
| 41 | - env = opaque; | 38 | + D(CPUState *env = opaque); |
| 42 | D(printf ("%s %x pc=%x\n", __func__, addr, env->pc)); | 39 | D(printf ("%s %x pc=%x\n", __func__, addr, env->pc)); |
| 43 | - return r; | 40 | + return 0; |
| 44 | } | 41 | } |
| 45 | static uint32_t ser_readw (void *opaque, target_phys_addr_t addr) | 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 | D(printf ("%s %x pc=%x\n", __func__, addr, env->pc)); | 45 | D(printf ("%s %x pc=%x\n", __func__, addr, env->pc)); |
| 51 | - return r; | 46 | + return 0; |
| 52 | } | 47 | } |
| 53 | 48 | ||
| 54 | static uint32_t ser_readl (void *opaque, target_phys_addr_t addr) | 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 | uint32_t r = 0; | 52 | uint32_t r = 0; |
| 58 | 53 | ||
| 59 | switch (addr & 0xfff) | 54 | switch (addr & 0xfff) |
| @@ -75,21 +70,19 @@ static uint32_t ser_readl (void *opaque, target_phys_addr_t addr) | @@ -75,21 +70,19 @@ static uint32_t ser_readl (void *opaque, target_phys_addr_t addr) | ||
| 75 | static void | 70 | static void |
| 76 | ser_writeb (void *opaque, target_phys_addr_t addr, uint32_t value) | 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 | D(printf ("%s %x %x pc=%x\n", __func__, addr, value, env->pc)); | 74 | D(printf ("%s %x %x pc=%x\n", __func__, addr, value, env->pc)); |
| 81 | } | 75 | } |
| 82 | static void | 76 | static void |
| 83 | ser_writew (void *opaque, target_phys_addr_t addr, uint32_t value) | 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 | D(printf ("%s %x %x pc=%x\n", __func__, addr, value, env->pc)); | 80 | D(printf ("%s %x %x pc=%x\n", __func__, addr, value, env->pc)); |
| 88 | } | 81 | } |
| 89 | static void | 82 | static void |
| 90 | ser_writel (void *opaque, target_phys_addr_t addr, uint32_t value) | 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 | switch (addr & 0xfff) | 87 | switch (addr & 0xfff) |
| 95 | { | 88 | { |
| @@ -110,24 +103,20 @@ ser_writel (void *opaque, target_phys_addr_t addr, uint32_t value) | @@ -110,24 +103,20 @@ ser_writel (void *opaque, target_phys_addr_t addr, uint32_t value) | ||
| 110 | } | 103 | } |
| 111 | 104 | ||
| 112 | static CPUReadMemoryFunc *ser_read[] = { | 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 | static CPUWriteMemoryFunc *ser_write[] = { | 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 | int ser_regs; | 119 | int ser_regs; |
| 127 | - | ||
| 128 | ser_regs = cpu_register_io_memory(0, ser_read, ser_write, env); | 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,27 +28,28 @@ | ||
| 28 | 28 | ||
| 29 | #define D(x) | 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 | struct fs_timer_t { | 44 | struct fs_timer_t { |
| 45 | + CPUState *env; | ||
| 46 | + qemu_irq *irq; | ||
| 47 | + target_phys_addr_t base; | ||
| 48 | + | ||
| 46 | QEMUBH *bh; | 49 | QEMUBH *bh; |
| 50 | + ptimer_state *ptimer; | ||
| 47 | unsigned int limit; | 51 | unsigned int limit; |
| 48 | int scale; | 52 | int scale; |
| 49 | - ptimer_state *ptimer; | ||
| 50 | - CPUState *env; | ||
| 51 | - qemu_irq *irq; | ||
| 52 | uint32_t mask; | 53 | uint32_t mask; |
| 53 | struct timeval last; | 54 | struct timeval last; |
| 54 | 55 | ||
| @@ -57,16 +58,6 @@ struct fs_timer_t { | @@ -57,16 +58,6 @@ struct fs_timer_t { | ||
| 57 | uint32_t r_intr; | 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 | /* diff two timevals. Return a single int in us. */ | 61 | /* diff two timevals. Return a single int in us. */ |
| 71 | int diff_timeval_us(struct timeval *a, struct timeval *b) | 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,31 +69,23 @@ int diff_timeval_us(struct timeval *a, struct timeval *b) | ||
| 78 | return diff; | 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 | static uint32_t timer_readl (void *opaque, target_phys_addr_t addr) | 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 | uint32_t r = 0; | 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 | switch (addr) { | 89 | switch (addr) { |
| 107 | case R_TMR0_DATA: | 90 | case R_TMR0_DATA: |
| 108 | break; | 91 | break; |
| @@ -113,21 +96,21 @@ static uint32_t timer_readl (void *opaque, target_phys_addr_t addr) | @@ -113,21 +96,21 @@ static uint32_t timer_readl (void *opaque, target_phys_addr_t addr) | ||
| 113 | { | 96 | { |
| 114 | struct timeval now; | 97 | struct timeval now; |
| 115 | gettimeofday(&now, NULL); | 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 | r *= 1000; /* convert to ns. */ | 102 | r *= 1000; /* convert to ns. */ |
| 120 | r++; /* make sure we increase for each call. */ | 103 | r++; /* make sure we increase for each call. */ |
| 121 | } | 104 | } |
| 122 | - timer[t].last = now; | 105 | + t->last = now; |
| 123 | break; | 106 | break; |
| 124 | } | 107 | } |
| 125 | 108 | ||
| 126 | case RW_INTR_MASK: | 109 | case RW_INTR_MASK: |
| 127 | - r = timer[t].rw_intr_mask; | 110 | + r = t->rw_intr_mask; |
| 128 | break; | 111 | break; |
| 129 | case R_MASKED_INTR: | 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 | break; | 114 | break; |
| 132 | default: | 115 | default: |
| 133 | D(printf ("%s %x p=%x\n", __func__, addr, env->pc)); | 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,18 +120,12 @@ static uint32_t timer_readl (void *opaque, target_phys_addr_t addr) | ||
| 137 | } | 120 | } |
| 138 | 121 | ||
| 139 | static void | 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 | static void write_ctrl(struct fs_timer_t *t, uint32_t v) | 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,20 +189,22 @@ static void timer_ack_irq(struct fs_timer_t *t) | ||
| 212 | static void | 189 | static void |
| 213 | timer_writel (void *opaque, target_phys_addr_t addr, uint32_t value) | 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 | D(printf ("%s %x %x pc=%x\n", | 195 | D(printf ("%s %x %x pc=%x\n", |
| 219 | __func__, addr, value, env->pc)); | 196 | __func__, addr, value, env->pc)); |
| 197 | + /* Make addr relative to this instances base. */ | ||
| 198 | + addr -= t->base; | ||
| 220 | switch (addr) | 199 | switch (addr) |
| 221 | { | 200 | { |
| 222 | case RW_TMR0_DIV: | 201 | case RW_TMR0_DIV: |
| 223 | D(printf ("RW_TMR0_DIV=%x\n", value)); | 202 | D(printf ("RW_TMR0_DIV=%x\n", value)); |
| 224 | - timer[t].limit = value; | 203 | + t->limit = value; |
| 225 | break; | 204 | break; |
| 226 | case RW_TMR0_CTRL: | 205 | case RW_TMR0_CTRL: |
| 227 | D(printf ("RW_TMR0_CTRL=%x\n", value)); | 206 | D(printf ("RW_TMR0_CTRL=%x\n", value)); |
| 228 | - write_ctrl(&timer[t], value); | 207 | + write_ctrl(t, value); |
| 229 | break; | 208 | break; |
| 230 | case RW_TMR1_DIV: | 209 | case RW_TMR1_DIV: |
| 231 | D(printf ("RW_TMR1_DIV=%x\n", value)); | 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,14 +214,14 @@ timer_writel (void *opaque, target_phys_addr_t addr, uint32_t value) | ||
| 235 | break; | 214 | break; |
| 236 | case RW_INTR_MASK: | 215 | case RW_INTR_MASK: |
| 237 | D(printf ("RW_INTR_MASK=%x\n", value)); | 216 | D(printf ("RW_INTR_MASK=%x\n", value)); |
| 238 | - timer[t].rw_intr_mask = value; | 217 | + t->rw_intr_mask = value; |
| 239 | break; | 218 | break; |
| 240 | case RW_WD_CTRL: | 219 | case RW_WD_CTRL: |
| 241 | D(printf ("RW_WD_CTRL=%x\n", value)); | 220 | D(printf ("RW_WD_CTRL=%x\n", value)); |
| 242 | break; | 221 | break; |
| 243 | case RW_ACK_INTR: | 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 | break; | 225 | break; |
| 247 | default: | 226 | default: |
| 248 | printf ("%s %x %x pc=%x\n", | 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,14 +231,14 @@ timer_writel (void *opaque, target_phys_addr_t addr, uint32_t value) | ||
| 252 | } | 231 | } |
| 253 | 232 | ||
| 254 | static CPUReadMemoryFunc *timer_read[] = { | 233 | static CPUReadMemoryFunc *timer_read[] = { |
| 255 | - &timer_readb, | ||
| 256 | - &timer_readw, | 234 | + &timer_rinvalid, |
| 235 | + &timer_rinvalid, | ||
| 257 | &timer_readl, | 236 | &timer_readl, |
| 258 | }; | 237 | }; |
| 259 | 238 | ||
| 260 | static CPUWriteMemoryFunc *timer_write[] = { | 239 | static CPUWriteMemoryFunc *timer_write[] = { |
| 261 | - &timer_writeb, | ||
| 262 | - &timer_writew, | 240 | + &timer_winvalid, |
| 241 | + &timer_winvalid, | ||
| 263 | &timer_writel, | 242 | &timer_writel, |
| 264 | }; | 243 | }; |
| 265 | 244 | ||
| @@ -273,23 +252,23 @@ static void timer_irq(void *opaque) | @@ -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 | int timer_regs; | 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 | } |