Made the etrax timers and serial-ports base address relocatable. Use target_phys_addr...
authoredgar_igl <edgar_igl@c046a42c-6fe2-441c-8c8c-71466251a162>
Fri, 14 Mar 2008 01:50:49 +0000 (01:50 +0000)
committeredgar_igl <edgar_igl@c046a42c-6fe2-441c-8c8c-71466251a162>
Fri, 14 Mar 2008 01:50:49 +0000 (01:50 +0000)
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4058 c046a42c-6fe2-441c-8c8c-71466251a162

hw/etraxfs.c
hw/etraxfs_pic.c
hw/etraxfs_ser.c
hw/etraxfs_timer.c

index 2c3c554..7c3f59e 100644 (file)
@@ -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.  */
index 980d61c..a656a26 100644 (file)
@@ -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;
index dd84d2a..778b429 100644 (file)
 
 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);
 }
index e295f8a..7c9eb92 100644 (file)
 
 #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);
 }