~ubuntu-branches/ubuntu/wily/qemu-kvm-spice/wily

« back to all changes in this revision

Viewing changes to hw/lm32_sys.c

  • Committer: Bazaar Package Importer
  • Author(s): Serge Hallyn
  • Date: 2011-10-19 10:44:56 UTC
  • Revision ID: james.westby@ubuntu.com-20111019104456-xgvskumk3sxi97f4
Tags: upstream-0.15.0+noroms
ImportĀ upstreamĀ versionĀ 0.15.0+noroms

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 *  QEMU model of the LatticeMico32 system control block.
 
3
 *
 
4
 *  Copyright (c) 2010 Michael Walle <michael@walle.cc>
 
5
 *
 
6
 * This library is free software; you can redistribute it and/or
 
7
 * modify it under the terms of the GNU Lesser General Public
 
8
 * License as published by the Free Software Foundation; either
 
9
 * version 2 of the License, or (at your option) any later version.
 
10
 *
 
11
 * This library is distributed in the hope that it will be useful,
 
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 
14
 * Lesser General Public License for more details.
 
15
 *
 
16
 * You should have received a copy of the GNU Lesser General Public
 
17
 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
 
18
 */
 
19
 
 
20
/*
 
21
 * This model is mainly intended for testing purposes and doesn't fit to any
 
22
 * real hardware. On the one hand it provides a control register (R_CTRL) on
 
23
 * the other hand it supports the lm32 tests.
 
24
 *
 
25
 * A write to the control register causes a system shutdown.
 
26
 * Tests first write the pointer to a test name to the test name register
 
27
 * (R_TESTNAME) and then write a zero to the pass/fail register (R_PASSFAIL) if
 
28
 * the test is passed or any non-zero value to it if the test is failed.
 
29
 */
 
30
 
 
31
#include "hw.h"
 
32
#include "sysbus.h"
 
33
#include "trace.h"
 
34
#include "qemu-log.h"
 
35
#include "qemu-error.h"
 
36
#include "sysemu.h"
 
37
#include "qemu-log.h"
 
38
 
 
39
enum {
 
40
    R_CTRL = 0,
 
41
    R_PASSFAIL,
 
42
    R_TESTNAME,
 
43
    R_MAX
 
44
};
 
45
 
 
46
#define MAX_TESTNAME_LEN 16
 
47
 
 
48
struct LM32SysState {
 
49
    SysBusDevice busdev;
 
50
    uint32_t base;
 
51
    uint32_t regs[R_MAX];
 
52
    uint8_t testname[MAX_TESTNAME_LEN];
 
53
};
 
54
typedef struct LM32SysState LM32SysState;
 
55
 
 
56
static void copy_testname(LM32SysState *s)
 
57
{
 
58
    cpu_physical_memory_read(s->regs[R_TESTNAME], s->testname,
 
59
            MAX_TESTNAME_LEN);
 
60
    s->testname[MAX_TESTNAME_LEN - 1] = '\0';
 
61
}
 
62
 
 
63
static void sys_write(void *opaque, target_phys_addr_t addr, uint32_t value)
 
64
{
 
65
    LM32SysState *s = opaque;
 
66
    char *testname;
 
67
 
 
68
    trace_lm32_sys_memory_write(addr, value);
 
69
 
 
70
    addr >>= 2;
 
71
    switch (addr) {
 
72
    case R_CTRL:
 
73
        qemu_system_shutdown_request();
 
74
        break;
 
75
    case R_PASSFAIL:
 
76
        s->regs[addr] = value;
 
77
        testname = (char *)s->testname;
 
78
        qemu_log("TC  %-16s %s\n", testname, (value) ? "FAILED" : "OK");
 
79
        break;
 
80
    case R_TESTNAME:
 
81
        s->regs[addr] = value;
 
82
        copy_testname(s);
 
83
        break;
 
84
 
 
85
    default:
 
86
        error_report("lm32_sys: write access to unknown register 0x"
 
87
                TARGET_FMT_plx, addr << 2);
 
88
        break;
 
89
    }
 
90
}
 
91
 
 
92
static CPUReadMemoryFunc * const sys_read_fn[] = {
 
93
    NULL,
 
94
    NULL,
 
95
    NULL,
 
96
};
 
97
 
 
98
static CPUWriteMemoryFunc * const sys_write_fn[] = {
 
99
    NULL,
 
100
    NULL,
 
101
    &sys_write,
 
102
};
 
103
 
 
104
static void sys_reset(DeviceState *d)
 
105
{
 
106
    LM32SysState *s = container_of(d, LM32SysState, busdev.qdev);
 
107
    int i;
 
108
 
 
109
    for (i = 0; i < R_MAX; i++) {
 
110
        s->regs[i] = 0;
 
111
    }
 
112
    memset(s->testname, 0, MAX_TESTNAME_LEN);
 
113
}
 
114
 
 
115
static int lm32_sys_init(SysBusDevice *dev)
 
116
{
 
117
    LM32SysState *s = FROM_SYSBUS(typeof(*s), dev);
 
118
    int sys_regs;
 
119
 
 
120
    sys_regs = cpu_register_io_memory(sys_read_fn, sys_write_fn, s,
 
121
            DEVICE_NATIVE_ENDIAN);
 
122
    sysbus_init_mmio(dev, R_MAX * 4, sys_regs);
 
123
 
 
124
    /* Note: This device is not created in the board initialization,
 
125
     * instead it has to be added with the -device parameter. Therefore,
 
126
     * the device maps itself. */
 
127
    sysbus_mmio_map(dev, 0, s->base);
 
128
 
 
129
    return 0;
 
130
}
 
131
 
 
132
static const VMStateDescription vmstate_lm32_sys = {
 
133
    .name = "lm32-sys",
 
134
    .version_id = 1,
 
135
    .minimum_version_id = 1,
 
136
    .minimum_version_id_old = 1,
 
137
    .fields      = (VMStateField[]) {
 
138
        VMSTATE_UINT32_ARRAY(regs, LM32SysState, R_MAX),
 
139
        VMSTATE_BUFFER(testname, LM32SysState),
 
140
        VMSTATE_END_OF_LIST()
 
141
    }
 
142
};
 
143
 
 
144
static SysBusDeviceInfo lm32_sys_info = {
 
145
    .init = lm32_sys_init,
 
146
    .qdev.name  = "lm32-sys",
 
147
    .qdev.size  = sizeof(LM32SysState),
 
148
    .qdev.vmsd  = &vmstate_lm32_sys,
 
149
    .qdev.reset = sys_reset,
 
150
    .qdev.props = (Property[]) {
 
151
        DEFINE_PROP_UINT32("base", LM32SysState, base, 0xffff0000),
 
152
        DEFINE_PROP_END_OF_LIST(),
 
153
    }
 
154
};
 
155
 
 
156
static void lm32_sys_register(void)
 
157
{
 
158
    sysbus_register_withprop(&lm32_sys_info);
 
159
}
 
160
 
 
161
device_init(lm32_sys_register)