Commit 83fa1010ae342c5ad0392182fcdcce438c71b163

Authored by ths
1 parent f1ccf904

EtraxFS board support, by Edgar E. Iglesias.


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@3364 c046a42c-6fe2-441c-8c8c-71466251a162
hw/etraxfs.c 0 → 100644
  1 +/*
  2 + * QEMU ETRAX System Emulator
  3 + *
  4 + * Copyright (c) 2007 Edgar E. Iglesias, Axis Communications AB.
  5 + *
  6 + * Permission is hereby granted, free of charge, to any person obtaining a copy
  7 + * of this software and associated documentation files (the "Software"), to deal
  8 + * in the Software without restriction, including without limitation the rights
  9 + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  10 + * copies of the Software, and to permit persons to whom the Software is
  11 + * furnished to do so, subject to the following conditions:
  12 + *
  13 + * The above copyright notice and this permission notice shall be included in
  14 + * all copies or substantial portions of the Software.
  15 + *
  16 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17 + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  18 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  19 + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  20 + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  21 + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  22 + * THE SOFTWARE.
  23 + */
  24 +#include <time.h>
  25 +#include <sys/time.h>
  26 +#include "vl.h"
  27 +
  28 +extern FILE *logfile;
  29 +
  30 +static void main_cpu_reset(void *opaque)
  31 +{
  32 + CPUState *env = opaque;
  33 + cpu_reset(env);
  34 +}
  35 +
  36 +static uint32_t fs_mmio_readb (void *opaque, target_phys_addr_t addr)
  37 +{
  38 + CPUState *env = opaque;
  39 + uint32_t r = 0;
  40 + printf ("%s %x pc=%x\n", __func__, addr, env->pc);
  41 + return r;
  42 +}
  43 +static uint32_t fs_mmio_readw (void *opaque, target_phys_addr_t addr)
  44 +{
  45 + CPUState *env = opaque;
  46 + uint32_t r = 0;
  47 + printf ("%s %x pc=%x\n", __func__, addr, env->pc);
  48 + return r;
  49 +}
  50 +
  51 +static uint32_t fs_mmio_readl (void *opaque, target_phys_addr_t addr)
  52 +{
  53 + CPUState *env = opaque;
  54 + uint32_t r = 0;
  55 + printf ("%s %x p=%x\n", __func__, addr, env->pc);
  56 + return r;
  57 +}
  58 +
  59 +static void
  60 +fs_mmio_writeb (void *opaque, target_phys_addr_t addr, uint32_t value)
  61 +{
  62 + CPUState *env = opaque;
  63 + printf ("%s %x %x pc=%x\n", __func__, addr, value, env->pc);
  64 +}
  65 +static void
  66 +fs_mmio_writew (void *opaque, target_phys_addr_t addr, uint32_t value)
  67 +{
  68 + CPUState *env = opaque;
  69 + printf ("%s %x %x pc=%x\n", __func__, addr, value, env->pc);
  70 +}
  71 +static void
  72 +fs_mmio_writel (void *opaque, target_phys_addr_t addr, uint32_t value)
  73 +{
  74 + CPUState *env = opaque;
  75 + printf ("%s %x %x pc=%x\n", __func__, addr, value, env->pc);
  76 +}
  77 +
  78 +static CPUReadMemoryFunc *fs_mmio_read[] = {
  79 + &fs_mmio_readb,
  80 + &fs_mmio_readw,
  81 + &fs_mmio_readl,
  82 +};
  83 +
  84 +static CPUWriteMemoryFunc *fs_mmio_write[] = {
  85 + &fs_mmio_writeb,
  86 + &fs_mmio_writew,
  87 + &fs_mmio_writel,
  88 +};
  89 +
  90 +
  91 +/* Init functions for different blocks. */
  92 +extern void etraxfs_timer_init(CPUState *env, qemu_irq *irqs);
  93 +extern void etraxfs_ser_init(CPUState *env, qemu_irq *irqs);
  94 +
  95 +void etrax_ack_irq(CPUState *env, uint32_t mask)
  96 +{
  97 + env->pending_interrupts &= ~mask;
  98 +}
  99 +
  100 +static void dummy_cpu_set_irq(void *opaque, int irq, int level)
  101 +{
  102 + CPUState *env = opaque;
  103 +
  104 + /* Hmm, should this really be done here? */
  105 + env->pending_interrupts |= 1 << irq;
  106 + cpu_interrupt(env, CPU_INTERRUPT_HARD);
  107 +}
  108 +
  109 +static
  110 +void bareetraxfs_init (int ram_size, int vga_ram_size, int boot_device,
  111 + DisplayState *ds, const char **fd_filename, int snapshot,
  112 + const char *kernel_filename, const char *kernel_cmdline,
  113 + const char *initrd_filename, const char *cpu_model)
  114 +{
  115 + CPUState *env;
  116 + qemu_irq *irqs;
  117 + int kernel_size;
  118 + int internal_regs;
  119 +
  120 + /* init CPUs */
  121 + if (cpu_model == NULL) {
  122 + cpu_model = "crisv32";
  123 + }
  124 + env = cpu_init();
  125 +/* register_savevm("cpu", 0, 3, cpu_save, cpu_load, env); */
  126 + qemu_register_reset(main_cpu_reset, env);
  127 + irqs = qemu_allocate_irqs(dummy_cpu_set_irq, env, 32);
  128 +
  129 + internal_regs = cpu_register_io_memory(0,
  130 + fs_mmio_read, fs_mmio_write, env);
  131 + /* 0xb0050000 is the last reg. */
  132 + cpu_register_physical_memory (0xac000000, 0x4010000, internal_regs);
  133 + /* allocate RAM */
  134 + cpu_register_physical_memory(0x40000000, ram_size, IO_MEM_RAM);
  135 +
  136 + etraxfs_timer_init(env, irqs);
  137 + etraxfs_ser_init(env, irqs);
  138 +
  139 + kernel_size = load_image(kernel_filename, phys_ram_base + 0x4000);
  140 + /* magic for boot. */
  141 + env->regs[8] = 0x56902387;
  142 + env->regs[9] = 0x40004000 + kernel_size;
  143 + env->pc = 0x40004000;
  144 +
  145 + {
  146 + unsigned char *ptr = phys_ram_base + 0x4000;
  147 + int i;
  148 + for (i = 0; i < 8; i++)
  149 + {
  150 + printf ("%2.2x ", ptr[i]);
  151 + }
  152 + printf("\n");
  153 + }
  154 +
  155 + printf ("pc =%x\n", env->pc);
  156 + printf ("ram size =%d\n", ram_size);
  157 + printf ("kernel name =%s\n", kernel_filename);
  158 + printf ("kernel size =%d\n", kernel_size);
  159 + printf ("cpu haltd =%d\n", env->halted);
  160 +}
  161 +
  162 +void DMA_run(void)
  163 +{
  164 +}
  165 +
  166 +void pic_info()
  167 +{
  168 +}
  169 +
  170 +void irq_info()
  171 +{
  172 +}
  173 +
  174 +QEMUMachine bareetraxfs_machine = {
  175 + "bareetraxfs",
  176 + "Bare ETRAX FS board",
  177 + bareetraxfs_init,
  178 +};
... ...
hw/etraxfs_ser.c 0 → 100644
  1 +/*
  2 + * QEMU ETRAX System Emulator
  3 + *
  4 + * Copyright (c) 2007 Edgar E. Iglesias, Axis Communications AB.
  5 + *
  6 + * Permission is hereby granted, free of charge, to any person obtaining a copy
  7 + * of this software and associated documentation files (the "Software"), to deal
  8 + * in the Software without restriction, including without limitation the rights
  9 + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  10 + * copies of the Software, and to permit persons to whom the Software is
  11 + * furnished to do so, subject to the following conditions:
  12 + *
  13 + * The above copyright notice and this permission notice shall be included in
  14 + * all copies or substantial portions of the Software.
  15 + *
  16 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17 + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  18 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  19 + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  20 + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  21 + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  22 + * THE SOFTWARE.
  23 + */
  24 +
  25 +#include <stdio.h>
  26 +#include <ctype.h>
  27 +#include "vl.h"
  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
  33 +
  34 +static uint32_t ser_readb (void *opaque, target_phys_addr_t addr)
  35 +{
  36 + CPUState *env = opaque;
  37 + uint32_t r = 0;
  38 + printf ("%s %x pc=%x\n", __func__, addr, env->pc);
  39 + return r;
  40 +}
  41 +static uint32_t ser_readw (void *opaque, target_phys_addr_t addr)
  42 +{
  43 + CPUState *env = opaque;
  44 + uint32_t r = 0;
  45 + printf ("%s %x pc=%x\n", __func__, addr, env->pc);
  46 + return r;
  47 +}
  48 +
  49 +static uint32_t ser_readl (void *opaque, target_phys_addr_t addr)
  50 +{
  51 + CPUState *env = opaque;
  52 + uint32_t r = 0;
  53 +
  54 + switch (addr)
  55 + {
  56 + case RW_TR_DMA_EN:
  57 + break;
  58 + case R_STAT_DIN:
  59 + r |= 1 << 24; /* set tr_rdy. */
  60 + r |= 1 << 22; /* set tr_idle. */
  61 + break;
  62 +
  63 + default:
  64 + printf ("%s %x p=%x\n", __func__, addr, env->pc);
  65 + break;
  66 + }
  67 + return r;
  68 +}
  69 +
  70 +static void
  71 +ser_writeb (void *opaque, target_phys_addr_t addr, uint32_t value)
  72 +{
  73 + CPUState *env = opaque;
  74 + printf ("%s %x %x pc=%x\n", __func__, addr, value, env->pc);
  75 +}
  76 +static void
  77 +ser_writew (void *opaque, target_phys_addr_t addr, uint32_t value)
  78 +{
  79 + CPUState *env = opaque;
  80 + printf ("%s %x %x pc=%x\n", __func__, addr, value, env->pc);
  81 +}
  82 +static void
  83 +ser_writel (void *opaque, target_phys_addr_t addr, uint32_t value)
  84 +{
  85 + CPUState *env = opaque;
  86 +
  87 + switch (addr)
  88 + {
  89 + case RW_TR_DMA_EN:
  90 + break;
  91 + case RW_DOUT:
  92 + if (isprint(value) || isspace(value))
  93 + putchar(value);
  94 + else
  95 + putchar('.');
  96 + break;
  97 + default:
  98 + printf ("%s %x %x pc=%x\n",
  99 + __func__, addr, value, env->pc);
  100 + break;
  101 + }
  102 +}
  103 +
  104 +static CPUReadMemoryFunc *ser_read[] = {
  105 + &ser_readb,
  106 + &ser_readw,
  107 + &ser_readl,
  108 +};
  109 +
  110 +static CPUWriteMemoryFunc *ser_write[] = {
  111 + &ser_writeb,
  112 + &ser_writew,
  113 + &ser_writel,
  114 +};
  115 +
  116 +void etraxfs_ser_init(CPUState *env, qemu_irq *irqs)
  117 +{
  118 + int ser_regs;
  119 +
  120 + ser_regs = cpu_register_io_memory(0, ser_read, ser_write, env);
  121 + cpu_register_physical_memory (0xb0026000, 0x3c, ser_regs);
  122 +}
... ...
hw/etraxfs_timer.c 0 → 100644
  1 +/*
  2 + * QEMU ETRAX System Emulator
  3 + *
  4 + * Copyright (c) 2007 Edgar E. Iglesias, Axis Communications AB.
  5 + *
  6 + * Permission is hereby granted, free of charge, to any person obtaining a copy
  7 + * of this software and associated documentation files (the "Software"), to deal
  8 + * in the Software without restriction, including without limitation the rights
  9 + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  10 + * copies of the Software, and to permit persons to whom the Software is
  11 + * furnished to do so, subject to the following conditions:
  12 + *
  13 + * The above copyright notice and this permission notice shall be included in
  14 + * all copies or substantial portions of the Software.
  15 + *
  16 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17 + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  18 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  19 + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  20 + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  21 + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  22 + * THE SOFTWARE.
  23 + */
  24 +#include <stdio.h>
  25 +#include <sys/time.h>
  26 +#include "vl.h"
  27 +
  28 +void etrax_ack_irq(CPUState *env, uint32_t mask);
  29 +
  30 +#define R_TIME 0xb001e038
  31 +#define RW_TMR0_DIV 0xb001e000
  32 +#define R_TMR0_DATA 0xb001e004
  33 +#define RW_TMR0_CTRL 0xb001e008
  34 +#define RW_TMR1_DIV 0xb001e010
  35 +#define R_TMR1_DATA 0xb001e014
  36 +#define RW_TMR1_CTRL 0xb001e018
  37 +
  38 +#define RW_INTR_MASK 0xb001e048
  39 +#define RW_ACK_INTR 0xb001e04c
  40 +#define R_INTR 0xb001e050
  41 +#define R_MASKED_INTR 0xb001e054
  42 +
  43 +
  44 +uint32_t rw_intr_mask;
  45 +uint32_t rw_ack_intr;
  46 +uint32_t r_intr;
  47 +
  48 +struct fs_timer_t {
  49 + QEMUBH *bh;
  50 + unsigned int limit;
  51 + int scale;
  52 + ptimer_state *ptimer;
  53 + CPUState *env;
  54 + qemu_irq *irq;
  55 + uint32_t mask;
  56 +};
  57 +
  58 +static struct fs_timer_t timer0;
  59 +
  60 +/* diff two timevals. Return a single int in us. */
  61 +int diff_timeval_us(struct timeval *a, struct timeval *b)
  62 +{
  63 + int diff;
  64 +
  65 + /* assume these values are signed. */
  66 + diff = (a->tv_sec - b->tv_sec) * 1000 * 1000;
  67 + diff += (a->tv_usec - b->tv_usec);
  68 + return diff;
  69 +}
  70 +
  71 +static uint32_t timer_readb (void *opaque, target_phys_addr_t addr)
  72 +{
  73 + CPUState *env = opaque;
  74 + uint32_t r = 0;
  75 + printf ("%s %x pc=%x\n", __func__, addr, env->pc);
  76 + return r;
  77 +}
  78 +static uint32_t timer_readw (void *opaque, target_phys_addr_t addr)
  79 +{
  80 + CPUState *env = opaque;
  81 + uint32_t r = 0;
  82 + printf ("%s %x pc=%x\n", __func__, addr, env->pc);
  83 + return r;
  84 +}
  85 +
  86 +static uint32_t timer_readl (void *opaque, target_phys_addr_t addr)
  87 +{
  88 + CPUState *env = opaque;
  89 + uint32_t r = 0;
  90 +
  91 + switch (addr) {
  92 + case R_TMR0_DATA:
  93 + break;
  94 + case R_TMR1_DATA:
  95 + printf ("R_TMR1_DATA\n");
  96 + break;
  97 + case R_TIME:
  98 + {
  99 + static struct timeval last;
  100 + struct timeval now;
  101 + gettimeofday(&now, NULL);
  102 + if (!(last.tv_sec == 0 && last.tv_usec == 0)) {
  103 + r = diff_timeval_us(&now, &last);
  104 + r *= 1000; /* convert to ns. */
  105 + r++; /* make sure we increase for each call. */
  106 + }
  107 + last = now;
  108 + break;
  109 + }
  110 +
  111 + case RW_INTR_MASK:
  112 + r = rw_intr_mask;
  113 + break;
  114 + case R_MASKED_INTR:
  115 + r = r_intr & rw_intr_mask;
  116 + break;
  117 + default:
  118 + printf ("%s %x p=%x\n", __func__, addr, env->pc);
  119 + break;
  120 + }
  121 + return r;
  122 +}
  123 +
  124 +static void
  125 +timer_writeb (void *opaque, target_phys_addr_t addr, uint32_t value)
  126 +{
  127 + CPUState *env = opaque;
  128 + printf ("%s %x %x pc=%x\n", __func__, addr, value, env->pc);
  129 +}
  130 +static void
  131 +timer_writew (void *opaque, target_phys_addr_t addr, uint32_t value)
  132 +{
  133 + CPUState *env = opaque;
  134 + printf ("%s %x %x pc=%x\n", __func__, addr, value, env->pc);
  135 +}
  136 +
  137 +static void write_ctrl(struct fs_timer_t *t, uint32_t v)
  138 +{
  139 + int op;
  140 + int freq;
  141 + int freq_hz;
  142 +
  143 + op = v & 3;
  144 + freq = v >> 2;
  145 + freq_hz = 32000000;
  146 +
  147 + switch (freq)
  148 + {
  149 + case 0:
  150 + case 1:
  151 + printf ("extern or disabled timer clock?\n");
  152 + break;
  153 + case 4: freq_hz = 29493000; break;
  154 + case 5: freq_hz = 32000000; break;
  155 + case 6: freq_hz = 32768000; break;
  156 + case 7: freq_hz = 100000000; break;
  157 + default:
  158 + abort();
  159 + break;
  160 + }
  161 +
  162 + printf ("freq_hz=%d limit=%d\n", freq_hz, t->limit);
  163 + t->scale = 0;
  164 + if (t->limit > 2048)
  165 + {
  166 + t->scale = 2048;
  167 + ptimer_set_period(timer0.ptimer, freq_hz / t->scale);
  168 + }
  169 +
  170 + printf ("op=%d\n", op);
  171 + switch (op)
  172 + {
  173 + case 0:
  174 + printf ("limit=%d %d\n", t->limit, t->limit/t->scale);
  175 + ptimer_set_limit(t->ptimer, t->limit / t->scale, 1);
  176 + break;
  177 + case 1:
  178 + ptimer_stop(t->ptimer);
  179 + break;
  180 + case 2:
  181 + ptimer_run(t->ptimer, 0);
  182 + break;
  183 + default:
  184 + abort();
  185 + break;
  186 + }
  187 +}
  188 +
  189 +static void timer_ack_irq(void)
  190 +{
  191 + if (!(r_intr & timer0.mask & rw_intr_mask)) {
  192 + qemu_irq_lower(timer0.irq[0]);
  193 + etrax_ack_irq(timer0.env, 1 << 0x1b);
  194 + }
  195 +}
  196 +
  197 +static void
  198 +timer_writel (void *opaque, target_phys_addr_t addr, uint32_t value)
  199 +{
  200 + CPUState *env = opaque;
  201 + printf ("%s %x %x pc=%x\n",
  202 + __func__, addr, value, env->pc);
  203 + switch (addr)
  204 + {
  205 + case RW_TMR0_DIV:
  206 + printf ("RW_TMR0_DIV=%x\n", value);
  207 + timer0.limit = value;
  208 + break;
  209 + case RW_TMR0_CTRL:
  210 + printf ("RW_TMR0_CTRL=%x\n", value);
  211 + write_ctrl(&timer0, value);
  212 + break;
  213 + case RW_TMR1_DIV:
  214 + printf ("RW_TMR1_DIV=%x\n", value);
  215 + break;
  216 + case RW_TMR1_CTRL:
  217 + printf ("RW_TMR1_CTRL=%x\n", value);
  218 + break;
  219 + case RW_INTR_MASK:
  220 + printf ("RW_INTR_MASK=%x\n", value);
  221 + rw_intr_mask = value;
  222 + break;
  223 + case RW_ACK_INTR:
  224 + r_intr &= ~value;
  225 + timer_ack_irq();
  226 + break;
  227 + default:
  228 + printf ("%s %x %x pc=%x\n",
  229 + __func__, addr, value, env->pc);
  230 + break;
  231 + }
  232 +}
  233 +
  234 +static CPUReadMemoryFunc *timer_read[] = {
  235 + &timer_readb,
  236 + &timer_readw,
  237 + &timer_readl,
  238 +};
  239 +
  240 +static CPUWriteMemoryFunc *timer_write[] = {
  241 + &timer_writeb,
  242 + &timer_writew,
  243 + &timer_writel,
  244 +};
  245 +
  246 +static void timer_irq(void *opaque)
  247 +{
  248 + struct fs_timer_t *t = opaque;
  249 +
  250 + r_intr |= t->mask;
  251 + if (t->mask & rw_intr_mask) {
  252 + qemu_irq_raise(t->irq[0]);
  253 + }
  254 +}
  255 +
  256 +void etraxfs_timer_init(CPUState *env, qemu_irq *irqs)
  257 +{
  258 + int timer_regs;
  259 +
  260 + timer0.bh = qemu_bh_new(timer_irq, &timer0);
  261 + timer0.ptimer = ptimer_init(timer0.bh);
  262 + timer0.irq = irqs + 0x1b;
  263 + timer0.mask = 1;
  264 + timer0.env = env;
  265 +
  266 + timer_regs = cpu_register_io_memory(0, timer_read, timer_write, env);
  267 + cpu_register_physical_memory (0xb001e000, 0x5c, timer_regs);
  268 +}
... ...