From ca87d03b77aade91926972b7e20b5382b59d1c77 Mon Sep 17 00:00:00 2001 From: edgar_igl Date: Fri, 14 Mar 2008 01:50:49 +0000 Subject: [PATCH] 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 --- hw/etraxfs.c | 18 ++++--- hw/etraxfs_pic.c | 4 +- hw/etraxfs_ser.c | 43 ++++++--------- hw/etraxfs_timer.c | 151 +++++++++++++++++++++++------------------------------ 4 files changed, 95 insertions(+), 121 deletions(-) diff --git a/hw/etraxfs.c b/hw/etraxfs.c index 2c3c554..7c3f59e 100644 --- a/hw/etraxfs.c +++ b/hw/etraxfs.c @@ -35,10 +35,10 @@ static void main_cpu_reset(void *opaque) } /* Init functions for different blocks. */ -extern qemu_irq *etraxfs_pic_init(CPUState *env, target_ulong base); -/* TODO: Make these blocks relocate:able. */ -extern void etraxfs_timer_init(CPUState *env, qemu_irq *irqs); -extern void etraxfs_ser_init(CPUState *env, qemu_irq *irqs); +extern qemu_irq *etraxfs_pic_init(CPUState *env, target_phys_addr_t base); +void etraxfs_timer_init(CPUState *env, qemu_irq *irqs, + target_phys_addr_t base); +void etraxfs_ser_init(CPUState *env, qemu_irq *irqs, target_phys_addr_t base); static void bareetraxfs_init (int ram_size, int vga_ram_size, @@ -84,8 +84,14 @@ void bareetraxfs_init (int ram_size, int vga_ram_size, 4, 0x0000, 0x0000, 0x0000, 0x0000); pic = etraxfs_pic_init(env, 0xb001c000); - etraxfs_timer_init(env, pic); - etraxfs_ser_init(env, pic); + /* 2 timers. */ + etraxfs_timer_init(env, pic, 0xb001e000); + etraxfs_timer_init(env, pic, 0xb005e000); + /* 4 serial ports. */ + etraxfs_ser_init(env, pic, 0xb0026000); + etraxfs_ser_init(env, pic, 0xb0028000); + etraxfs_ser_init(env, pic, 0xb002a000); + etraxfs_ser_init(env, pic, 0xb002c000); kernel_size = load_image(kernel_filename, phys_ram_base + 0x4000); /* magic for boot. */ diff --git a/hw/etraxfs_pic.c b/hw/etraxfs_pic.c index 980d61c..a656a26 100644 --- a/hw/etraxfs_pic.c +++ b/hw/etraxfs_pic.c @@ -30,7 +30,7 @@ struct fs_pic_state_t { CPUState *env; - target_ulong base; + target_phys_addr_t base; uint32_t rw_mask; /* Active interrupt lines. */ @@ -186,7 +186,7 @@ static void etraxfs_pic_handler(void *opaque, int irq, int level) } } -qemu_irq *etraxfs_pic_init(CPUState *env, target_ulong base) +qemu_irq *etraxfs_pic_init(CPUState *env, target_phys_addr_t base) { struct fs_pic_state_t *fs; qemu_irq *pic; diff --git a/hw/etraxfs_ser.c b/hw/etraxfs_ser.c index dd84d2a..778b429 100644 --- a/hw/etraxfs_ser.c +++ b/hw/etraxfs_ser.c @@ -35,25 +35,20 @@ static uint32_t ser_readb (void *opaque, target_phys_addr_t addr) { - CPUState *env; - uint32_t r = 0; - - env = opaque; + D(CPUState *env = opaque); D(printf ("%s %x pc=%x\n", __func__, addr, env->pc)); - return r; + return 0; } static uint32_t ser_readw (void *opaque, target_phys_addr_t addr) { - CPUState *env; - uint32_t r = 0; - env = opaque; + D(CPUState *env = opaque); D(printf ("%s %x pc=%x\n", __func__, addr, env->pc)); - return r; + return 0; } static uint32_t ser_readl (void *opaque, target_phys_addr_t addr) { - CPUState *env = opaque; + D(CPUState *env = opaque); uint32_t r = 0; switch (addr & 0xfff) @@ -75,21 +70,19 @@ static uint32_t ser_readl (void *opaque, target_phys_addr_t addr) static void ser_writeb (void *opaque, target_phys_addr_t addr, uint32_t value) { - CPUState *env; - env = opaque; + D(CPUState *env = opaque); D(printf ("%s %x %x pc=%x\n", __func__, addr, value, env->pc)); } static void ser_writew (void *opaque, target_phys_addr_t addr, uint32_t value) { - CPUState *env; - env = opaque; + D(CPUState *env = opaque); D(printf ("%s %x %x pc=%x\n", __func__, addr, value, env->pc)); } static void ser_writel (void *opaque, target_phys_addr_t addr, uint32_t value) { - CPUState *env = opaque; + D(CPUState *env = opaque); switch (addr & 0xfff) { @@ -110,24 +103,20 @@ ser_writel (void *opaque, target_phys_addr_t addr, uint32_t value) } static CPUReadMemoryFunc *ser_read[] = { - &ser_readb, - &ser_readw, - &ser_readl, + &ser_readb, + &ser_readw, + &ser_readl, }; static CPUWriteMemoryFunc *ser_write[] = { - &ser_writeb, - &ser_writew, - &ser_writel, + &ser_writeb, + &ser_writew, + &ser_writel, }; -void etraxfs_ser_init(CPUState *env, qemu_irq *irqs) +void etraxfs_ser_init(CPUState *env, qemu_irq *irqs, target_phys_addr_t base) { int ser_regs; - ser_regs = cpu_register_io_memory(0, ser_read, ser_write, env); - cpu_register_physical_memory (0xb0026000, 0x3c, ser_regs); - cpu_register_physical_memory (0xb0028000, 0x3c, ser_regs); - cpu_register_physical_memory (0xb002a000, 0x3c, ser_regs); - cpu_register_physical_memory (0xb002c000, 0x3c, ser_regs); + cpu_register_physical_memory (base, 0x3c, ser_regs); } diff --git a/hw/etraxfs_timer.c b/hw/etraxfs_timer.c index e295f8a..7c9eb92 100644 --- a/hw/etraxfs_timer.c +++ b/hw/etraxfs_timer.c @@ -28,27 +28,28 @@ #define D(x) -#define R_TIME 0xb001e038 -#define RW_TMR0_DIV 0xb001e000 -#define R_TMR0_DATA 0xb001e004 -#define RW_TMR0_CTRL 0xb001e008 -#define RW_TMR1_DIV 0xb001e010 -#define R_TMR1_DATA 0xb001e014 -#define RW_TMR1_CTRL 0xb001e018 - -#define RW_WD_CTRL 0xb001e040 -#define RW_INTR_MASK 0xb001e048 -#define RW_ACK_INTR 0xb001e04c -#define R_INTR 0xb001e050 -#define R_MASKED_INTR 0xb001e054 +#define RW_TMR0_DIV 0x00 +#define R_TMR0_DATA 0x04 +#define RW_TMR0_CTRL 0x08 +#define RW_TMR1_DIV 0x10 +#define R_TMR1_DATA 0x14 +#define RW_TMR1_CTRL 0x18 +#define R_TIME 0x38 +#define RW_WD_CTRL 0x40 +#define RW_INTR_MASK 0x48 +#define RW_ACK_INTR 0x4c +#define R_INTR 0x50 +#define R_MASKED_INTR 0x54 struct fs_timer_t { + CPUState *env; + qemu_irq *irq; + target_phys_addr_t base; + QEMUBH *bh; + ptimer_state *ptimer; unsigned int limit; int scale; - ptimer_state *ptimer; - CPUState *env; - qemu_irq *irq; uint32_t mask; struct timeval last; @@ -57,16 +58,6 @@ struct fs_timer_t { uint32_t r_intr; }; -static struct fs_timer_t timer[2]; - -static inline int timer_index(target_phys_addr_t addr) -{ - int t = 0; - if (addr >= 0xb005e000) - t = 1; - return t; -} - /* diff two timevals. Return a single int in us. */ int diff_timeval_us(struct timeval *a, struct timeval *b) { @@ -78,31 +69,23 @@ int diff_timeval_us(struct timeval *a, struct timeval *b) return diff; } -static uint32_t timer_readb (void *opaque, target_phys_addr_t addr) +static uint32_t timer_rinvalid (void *opaque, target_phys_addr_t addr) { - CPUState *env; - uint32_t r = 0; - - env = opaque; - D(printf ("%s %x pc=%x\n", __func__, addr, env->pc)); - return r; -} -static uint32_t timer_readw (void *opaque, target_phys_addr_t addr) -{ - CPUState *env; - uint32_t r = 0; - - env = opaque; - D(printf ("%s %x pc=%x\n", __func__, addr, env->pc)); - return r; + struct fs_timer_t *t = opaque; + CPUState *env = t->env; + cpu_abort(env, "Unsupported short access. reg=%x pc=%x.\n", + addr, env->pc); + return 0; } static uint32_t timer_readl (void *opaque, target_phys_addr_t addr) { - CPUState *env = opaque; + struct fs_timer_t *t = opaque; + D(CPUState *env = t->env); uint32_t r = 0; - int t = timer_index(addr); + /* Make addr relative to this instances base. */ + addr -= t->base; switch (addr) { case R_TMR0_DATA: break; @@ -113,21 +96,21 @@ static uint32_t timer_readl (void *opaque, target_phys_addr_t addr) { struct timeval now; gettimeofday(&now, NULL); - if (!(timer[t].last.tv_sec == 0 - && timer[t].last.tv_usec == 0)) { - r = diff_timeval_us(&now, &timer[t].last); + if (!(t->last.tv_sec == 0 + && t->last.tv_usec == 0)) { + r = diff_timeval_us(&now, &t->last); r *= 1000; /* convert to ns. */ r++; /* make sure we increase for each call. */ } - timer[t].last = now; + t->last = now; break; } case RW_INTR_MASK: - r = timer[t].rw_intr_mask; + r = t->rw_intr_mask; break; case R_MASKED_INTR: - r = timer[t].r_intr & timer[t].rw_intr_mask; + r = t->r_intr & t->rw_intr_mask; break; default: 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) } static void -timer_writeb (void *opaque, target_phys_addr_t addr, uint32_t value) +timer_winvalid (void *opaque, target_phys_addr_t addr, uint32_t value) { - CPUState *env; - env = opaque; - D(printf ("%s %x %x pc=%x\n", __func__, addr, value, env->pc)); -} -static void -timer_writew (void *opaque, target_phys_addr_t addr, uint32_t value) -{ - CPUState *env; - env = opaque; - D(printf ("%s %x %x pc=%x\n", __func__, addr, value, env->pc)); + struct fs_timer_t *t = opaque; + CPUState *env = t->env; + cpu_abort(env, "Unsupported short access. reg=%x pc=%x.\n", + addr, env->pc); } 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) static void timer_writel (void *opaque, target_phys_addr_t addr, uint32_t value) { - CPUState *env = opaque; - int t = timer_index(addr); + struct fs_timer_t *t = opaque; + CPUState *env = t->env; D(printf ("%s %x %x pc=%x\n", __func__, addr, value, env->pc)); + /* Make addr relative to this instances base. */ + addr -= t->base; switch (addr) { case RW_TMR0_DIV: D(printf ("RW_TMR0_DIV=%x\n", value)); - timer[t].limit = value; + t->limit = value; break; case RW_TMR0_CTRL: D(printf ("RW_TMR0_CTRL=%x\n", value)); - write_ctrl(&timer[t], value); + write_ctrl(t, value); break; case RW_TMR1_DIV: D(printf ("RW_TMR1_DIV=%x\n", value)); @@ -235,14 +214,14 @@ timer_writel (void *opaque, target_phys_addr_t addr, uint32_t value) break; case RW_INTR_MASK: D(printf ("RW_INTR_MASK=%x\n", value)); - timer[t].rw_intr_mask = value; + t->rw_intr_mask = value; break; case RW_WD_CTRL: D(printf ("RW_WD_CTRL=%x\n", value)); break; case RW_ACK_INTR: - timer[t].r_intr &= ~value; - timer_ack_irq(&timer[t]); + t->r_intr &= ~value; + timer_ack_irq(t); break; default: printf ("%s %x %x pc=%x\n", @@ -252,14 +231,14 @@ timer_writel (void *opaque, target_phys_addr_t addr, uint32_t value) } static CPUReadMemoryFunc *timer_read[] = { - &timer_readb, - &timer_readw, + &timer_rinvalid, + &timer_rinvalid, &timer_readl, }; static CPUWriteMemoryFunc *timer_write[] = { - &timer_writeb, - &timer_writew, + &timer_winvalid, + &timer_winvalid, &timer_writel, }; @@ -273,23 +252,23 @@ static void timer_irq(void *opaque) } } -void etraxfs_timer_init(CPUState *env, qemu_irq *irqs) +void etraxfs_timer_init(CPUState *env, qemu_irq *irqs, + target_phys_addr_t base) { + static struct fs_timer_t *t; int timer_regs; - timer[0].bh = qemu_bh_new(timer_irq, &timer[0]); - timer[0].ptimer = ptimer_init(timer[0].bh); - timer[0].irq = irqs + 26; - timer[0].mask = 1; - timer[0].env = env; + t = qemu_mallocz(sizeof *t); + if (!t) + return; - timer[1].bh = qemu_bh_new(timer_irq, &timer[1]); - timer[1].ptimer = ptimer_init(timer[1].bh); - timer[1].irq = irqs + 26; - timer[1].mask = 1; - timer[1].env = env; + t->bh = qemu_bh_new(timer_irq, t); + t->ptimer = ptimer_init(t->bh); + t->irq = irqs + 26; + t->mask = 1; + t->env = env; + t->base = base; - timer_regs = cpu_register_io_memory(0, timer_read, timer_write, env); - cpu_register_physical_memory (0xb001e000, 0x5c, timer_regs); - cpu_register_physical_memory (0xb005e000, 0x5c, timer_regs); + timer_regs = cpu_register_io_memory(0, timer_read, timer_write, t); + cpu_register_physical_memory (base, 0x5c, timer_regs); } -- 2.7.4