Commit 10c144e2fbc985d85e4ce5370dc2e97afe47403f

Authored by edgar_igl
1 parent de553065

ETRAX: Add a model for the axis devboard88 machine.

Signed-off-by: Edgar E. Iglesias <edgar.iglesias@gmail.com>


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@6197 c046a42c-6fe2-441c-8c8c-71466251a162
Makefile.target
... ... @@ -676,7 +676,10 @@ OBJS+= pflash_cfi01.o
676 676 CPPFLAGS += -DHAS_AUDIO -DHAS_AUDIO_CHOICE
677 677 endif
678 678 ifeq ($(TARGET_BASE_ARCH), cris)
679   -OBJS+= etraxfs.o
  679 +# Boards
  680 +OBJS+= etraxfs.o axis_dev88.o
  681 +
  682 +# IO blocks
680 683 OBJS+= etraxfs_dma.o
681 684 OBJS+= etraxfs_pic.o
682 685 OBJS+= etraxfs_eth.o
... ... @@ -684,7 +687,7 @@ OBJS+= etraxfs_timer.o
684 687 OBJS+= etraxfs_ser.o
685 688  
686 689 OBJS+= ptimer.o
687   -OBJS+= pflash_cfi02.o
  690 +OBJS+= pflash_cfi02.o nand.o
688 691 endif
689 692 ifeq ($(TARGET_BASE_ARCH), sparc)
690 693 ifeq ($(TARGET_ARCH), sparc64)
... ...
hw/axis_dev88.c 0 → 100644
  1 +/*
  2 + * QEMU model for the AXIS devboard 88.
  3 + *
  4 + * Copyright (c) 2009 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 "hw.h"
  27 +#include "net.h"
  28 +#include "flash.h"
  29 +#include "sysemu.h"
  30 +#include "devices.h"
  31 +#include "boards.h"
  32 +
  33 +#include "etraxfs.h"
  34 +
  35 +#define D(x)
  36 +#define DNAND(x)
  37 +
  38 +struct nand_state_t
  39 +{
  40 + struct nand_flash_s *nand;
  41 + unsigned int rdy:1;
  42 + unsigned int ale:1;
  43 + unsigned int cle:1;
  44 + unsigned int ce:1;
  45 +};
  46 +
  47 +static struct nand_state_t nand_state;
  48 +static uint32_t nand_readl (void *opaque, target_phys_addr_t addr)
  49 +{
  50 + struct nand_state_t *s = opaque;
  51 + uint32_t r;
  52 + int rdy;
  53 +
  54 + r = nand_getio(s->nand);
  55 + nand_getpins(s->nand, &rdy);
  56 + s->rdy = rdy;
  57 +
  58 + DNAND(printf("%s addr=%x r=%x\n", __func__, addr, r));
  59 + return r;
  60 +}
  61 +
  62 +static void
  63 +nand_writel (void *opaque, target_phys_addr_t addr, uint32_t value)
  64 +{
  65 + struct nand_state_t *s = opaque;
  66 + int rdy;
  67 +
  68 + DNAND(printf("%s addr=%x v=%x\n", __func__, addr, value));
  69 + nand_setpins(s->nand, s->cle, s->ale, s->ce, 1, 0);
  70 + nand_setio(s->nand, value);
  71 + nand_getpins(s->nand, &rdy);
  72 + s->rdy = rdy;
  73 +}
  74 +
  75 +static CPUReadMemoryFunc *nand_read[] = {
  76 + &nand_readl,
  77 + &nand_readl,
  78 + &nand_readl,
  79 +};
  80 +
  81 +static CPUWriteMemoryFunc *nand_write[] = {
  82 + &nand_writel,
  83 + &nand_writel,
  84 + &nand_writel,
  85 +};
  86 +
  87 +#define RW_PA_DOUT 0
  88 +#define R_PA_DIN 1
  89 +#define RW_PA_OE 2
  90 +struct gpio_state_t
  91 +{
  92 + struct nand_state_t *nand;
  93 + uint32_t regs[0x5c / 4];
  94 +} gpio_state;
  95 +
  96 +static uint32_t gpio_readl (void *opaque, target_phys_addr_t addr)
  97 +{
  98 + struct gpio_state_t *s = opaque;
  99 + uint32_t r = 0;
  100 +
  101 + addr >>= 2;
  102 + switch (addr)
  103 + {
  104 + case R_PA_DIN:
  105 + r = s->regs[RW_PA_DOUT] & s->regs[RW_PA_OE];
  106 +
  107 + /* Encode pins from the nand. */
  108 + r |= s->nand->rdy << 7;
  109 + break;
  110 + default:
  111 + r = s->regs[addr];
  112 + break;
  113 + }
  114 + return r;
  115 + D(printf("%s %x=%x\n", __func__, addr, r));
  116 +}
  117 +
  118 +static void gpio_writel (void *opaque, target_phys_addr_t addr, uint32_t value)
  119 +{
  120 + struct gpio_state_t *s = opaque;
  121 + D(printf("%s %x=%x\n", __func__, addr, value));
  122 +
  123 + addr >>= 2;
  124 + switch (addr)
  125 + {
  126 + case RW_PA_DOUT:
  127 + /* Decode nand pins. */
  128 + s->nand->ale = !!(value & (1 << 6));
  129 + s->nand->cle = !!(value & (1 << 5));
  130 + s->nand->ce = !!(value & (1 << 4));
  131 +
  132 + s->regs[addr] = value;
  133 + break;
  134 + default:
  135 + s->regs[addr] = value;
  136 + break;
  137 + }
  138 +}
  139 +
  140 +static CPUReadMemoryFunc *gpio_read[] = {
  141 + NULL, NULL,
  142 + &gpio_readl,
  143 +};
  144 +
  145 +static CPUWriteMemoryFunc *gpio_write[] = {
  146 + NULL, NULL,
  147 + &gpio_writel,
  148 +};
  149 +
  150 +#define INTMEM_SIZE (128 * 1024)
  151 +
  152 +static uint32_t bootstrap_pc;
  153 +static void main_cpu_reset(void *opaque)
  154 +{
  155 + CPUState *env = opaque;
  156 + cpu_reset(env);
  157 +
  158 + env->pc = bootstrap_pc;
  159 +}
  160 +
  161 +static
  162 +void axisdev88_init (ram_addr_t ram_size, int vga_ram_size,
  163 + const char *boot_device, DisplayState *ds,
  164 + const char *kernel_filename, const char *kernel_cmdline,
  165 + const char *initrd_filename, const char *cpu_model)
  166 +{
  167 + CPUState *env;
  168 + struct etraxfs_pic *pic;
  169 + void *etraxfs_dmac;
  170 + struct etraxfs_dma_client *eth[2] = {NULL, NULL};
  171 + int kernel_size;
  172 + int i;
  173 + int nand_regs;
  174 + int gpio_regs;
  175 + ram_addr_t phys_ram;
  176 + ram_addr_t phys_intmem;
  177 +
  178 + /* init CPUs */
  179 + if (cpu_model == NULL) {
  180 + cpu_model = "crisv32";
  181 + }
  182 + env = cpu_init(cpu_model);
  183 + qemu_register_reset(main_cpu_reset, env);
  184 +
  185 + /* allocate RAM */
  186 + phys_ram = qemu_ram_alloc(ram_size);
  187 + cpu_register_physical_memory(0x40000000, ram_size, phys_ram | IO_MEM_RAM);
  188 +
  189 + /* The ETRAX-FS has 128Kb on chip ram, the docs refer to it as the
  190 + internal memory. */
  191 + phys_intmem = qemu_ram_alloc(INTMEM_SIZE);
  192 + cpu_register_physical_memory(0x38000000, INTMEM_SIZE,
  193 + phys_intmem | IO_MEM_RAM);
  194 +
  195 +
  196 + /* Attach a NAND flash to CS1. */
  197 + nand_state.nand = nand_init(NAND_MFR_STMICRO, 0xf1);
  198 + nand_regs = cpu_register_io_memory(0, nand_read, nand_write, &nand_state);
  199 + cpu_register_physical_memory(0x10000000, 0x05000000, nand_regs);
  200 +
  201 + gpio_state.nand = &nand_state;
  202 + gpio_regs = cpu_register_io_memory(0, gpio_read, gpio_write, &gpio_state);
  203 + cpu_register_physical_memory(0x3001a000, 0x1c, gpio_regs);
  204 +
  205 +
  206 + pic = etraxfs_pic_init(env, 0x3001c000);
  207 + etraxfs_dmac = etraxfs_dmac_init(env, 0x30000000, 10);
  208 + for (i = 0; i < 10; i++) {
  209 + /* On ETRAX, odd numbered channels are inputs. */
  210 + etraxfs_dmac_connect(etraxfs_dmac, i, pic->irq + 7 + i, i & 1);
  211 + }
  212 +
  213 + /* Add the two ethernet blocks. */
  214 + eth[0] = etraxfs_eth_init(&nd_table[0], env, pic->irq + 25, 0x30034000);
  215 + if (nb_nics > 1)
  216 + eth[1] = etraxfs_eth_init(&nd_table[1], env, pic->irq + 26, 0x30036000);
  217 +
  218 + /* The DMA Connector block is missing, hardwire things for now. */
  219 + etraxfs_dmac_connect_client(etraxfs_dmac, 0, eth[0]);
  220 + etraxfs_dmac_connect_client(etraxfs_dmac, 1, eth[0] + 1);
  221 + if (eth[1]) {
  222 + etraxfs_dmac_connect_client(etraxfs_dmac, 6, eth[1]);
  223 + etraxfs_dmac_connect_client(etraxfs_dmac, 7, eth[1] + 1);
  224 + }
  225 +
  226 + /* 2 timers. */
  227 + etraxfs_timer_init(env, pic->irq + 0x1b, pic->nmi + 1, 0x3001e000);
  228 + etraxfs_timer_init(env, pic->irq + 0x1b, pic->nmi + 1, 0x3005e000);
  229 +
  230 + for (i = 0; i < 4; i++) {
  231 + if (serial_hds[i]) {
  232 + etraxfs_ser_init(env, pic->irq + 0x14 + i,
  233 + serial_hds[i], 0x30026000 + i * 0x2000);
  234 + }
  235 + }
  236 +
  237 + if (kernel_filename) {
  238 + uint64_t entry, high;
  239 + int kcmdline_len;
  240 +
  241 + /* Boots a kernel elf binary, os/linux-2.6/vmlinux from the axis
  242 + devboard SDK. */
  243 + kernel_size = load_elf(kernel_filename, -0x80000000LL,
  244 + &entry, NULL, &high);
  245 + bootstrap_pc = entry;
  246 + if (kernel_size < 0) {
  247 + /* Takes a kimage from the axis devboard SDK. */
  248 + kernel_size = load_image(kernel_filename, phys_ram_base + 0x4000);
  249 + bootstrap_pc = 0x40004000;
  250 + env->regs[9] = 0x40004000 + kernel_size;
  251 + }
  252 + env->regs[8] = 0x56902387; /* RAM init magic. */
  253 +
  254 + if (kernel_cmdline && (kcmdline_len = strlen(kernel_cmdline))) {
  255 + if (kcmdline_len > 256) {
  256 + fprintf(stderr, "Too long CRIS kernel cmdline (max 256)\n");
  257 + exit(1);
  258 + }
  259 + pstrcpy_targphys(high, 256, kernel_cmdline);
  260 + /* Let the kernel know we are modifying the cmdline. */
  261 + env->regs[10] = 0x87109563;
  262 + env->regs[11] = high;
  263 + }
  264 + }
  265 + env->pc = bootstrap_pc;
  266 +
  267 + printf ("pc =%x\n", env->pc);
  268 + printf ("ram size =%ld\n", ram_size);
  269 +}
  270 +
  271 +QEMUMachine axisdev88_machine = {
  272 + .name = "axis-dev88",
  273 + .desc = "AXIS devboard 88",
  274 + .init = axisdev88_init,
  275 + .ram_require = 0x8000000,
  276 +};
... ...
hw/boards.h
... ... @@ -27,6 +27,7 @@ void register_machines(void);
27 27  
28 28 /* Axis ETRAX. */
29 29 extern QEMUMachine bareetraxfs_machine;
  30 +extern QEMUMachine axisdev88_machine;
30 31  
31 32 /* pc.c */
32 33 extern QEMUMachine pc_machine;
... ...
target-cris/machine.c
... ... @@ -4,6 +4,7 @@
4 4 void register_machines(void)
5 5 {
6 6 qemu_register_machine(&bareetraxfs_machine);
  7 + qemu_register_machine(&axisdev88_machine);
7 8 }
8 9  
9 10 void cpu_save(QEMUFile *f, void *opaque)
... ...