Statistics
| Branch: | Revision:

root / hw / stellaris.c @ e219dea2

History | View | Annotate | Download (39.4 kB)

1 9ee6e8bb pbrook
/*
2 1654b2d6 aurel32
 * Luminary Micro Stellaris peripherals
3 9ee6e8bb pbrook
 *
4 9ee6e8bb pbrook
 * Copyright (c) 2006 CodeSourcery.
5 9ee6e8bb pbrook
 * Written by Paul Brook
6 9ee6e8bb pbrook
 *
7 8e31bf38 Matthew Fernandez
 * This code is licensed under the GPL.
8 9ee6e8bb pbrook
 */
9 9ee6e8bb pbrook
10 a7d518a6 Paul Brook
#include "sysbus.h"
11 5493e33f Paul Brook
#include "ssi.h"
12 87ecb68b pbrook
#include "arm-misc.h"
13 87ecb68b pbrook
#include "devices.h"
14 87ecb68b pbrook
#include "qemu-timer.h"
15 87ecb68b pbrook
#include "i2c.h"
16 eea589cc pbrook
#include "net.h"
17 87ecb68b pbrook
#include "boards.h"
18 9ee6e8bb pbrook
19 cf0dbb21 pbrook
#define GPIO_A 0
20 cf0dbb21 pbrook
#define GPIO_B 1
21 cf0dbb21 pbrook
#define GPIO_C 2
22 cf0dbb21 pbrook
#define GPIO_D 3
23 cf0dbb21 pbrook
#define GPIO_E 4
24 cf0dbb21 pbrook
#define GPIO_F 5
25 cf0dbb21 pbrook
#define GPIO_G 6
26 cf0dbb21 pbrook
27 cf0dbb21 pbrook
#define BP_OLED_I2C  0x01
28 cf0dbb21 pbrook
#define BP_OLED_SSI  0x02
29 cf0dbb21 pbrook
#define BP_GAMEPAD   0x04
30 cf0dbb21 pbrook
31 9ee6e8bb pbrook
typedef const struct {
32 9ee6e8bb pbrook
    const char *name;
33 9ee6e8bb pbrook
    uint32_t did0;
34 9ee6e8bb pbrook
    uint32_t did1;
35 9ee6e8bb pbrook
    uint32_t dc0;
36 9ee6e8bb pbrook
    uint32_t dc1;
37 9ee6e8bb pbrook
    uint32_t dc2;
38 9ee6e8bb pbrook
    uint32_t dc3;
39 9ee6e8bb pbrook
    uint32_t dc4;
40 cf0dbb21 pbrook
    uint32_t peripherals;
41 9ee6e8bb pbrook
} stellaris_board_info;
42 9ee6e8bb pbrook
43 9ee6e8bb pbrook
/* General purpose timer module.  */
44 9ee6e8bb pbrook
45 9ee6e8bb pbrook
typedef struct gptm_state {
46 40905a6a Paul Brook
    SysBusDevice busdev;
47 9ee6e8bb pbrook
    uint32_t config;
48 9ee6e8bb pbrook
    uint32_t mode[2];
49 9ee6e8bb pbrook
    uint32_t control;
50 9ee6e8bb pbrook
    uint32_t state;
51 9ee6e8bb pbrook
    uint32_t mask;
52 9ee6e8bb pbrook
    uint32_t load[2];
53 9ee6e8bb pbrook
    uint32_t match[2];
54 9ee6e8bb pbrook
    uint32_t prescale[2];
55 9ee6e8bb pbrook
    uint32_t match_prescale[2];
56 9ee6e8bb pbrook
    uint32_t rtc;
57 9ee6e8bb pbrook
    int64_t tick[2];
58 9ee6e8bb pbrook
    struct gptm_state *opaque[2];
59 9ee6e8bb pbrook
    QEMUTimer *timer[2];
60 9ee6e8bb pbrook
    /* The timers have an alternate output used to trigger the ADC.  */
61 9ee6e8bb pbrook
    qemu_irq trigger;
62 9ee6e8bb pbrook
    qemu_irq irq;
63 9ee6e8bb pbrook
} gptm_state;
64 9ee6e8bb pbrook
65 9ee6e8bb pbrook
static void gptm_update_irq(gptm_state *s)
66 9ee6e8bb pbrook
{
67 9ee6e8bb pbrook
    int level;
68 9ee6e8bb pbrook
    level = (s->state & s->mask) != 0;
69 9ee6e8bb pbrook
    qemu_set_irq(s->irq, level);
70 9ee6e8bb pbrook
}
71 9ee6e8bb pbrook
72 9ee6e8bb pbrook
static void gptm_stop(gptm_state *s, int n)
73 9ee6e8bb pbrook
{
74 9ee6e8bb pbrook
    qemu_del_timer(s->timer[n]);
75 9ee6e8bb pbrook
}
76 9ee6e8bb pbrook
77 9ee6e8bb pbrook
static void gptm_reload(gptm_state *s, int n, int reset)
78 9ee6e8bb pbrook
{
79 9ee6e8bb pbrook
    int64_t tick;
80 9ee6e8bb pbrook
    if (reset)
81 74475455 Paolo Bonzini
        tick = qemu_get_clock_ns(vm_clock);
82 9ee6e8bb pbrook
    else
83 9ee6e8bb pbrook
        tick = s->tick[n];
84 9ee6e8bb pbrook
85 9ee6e8bb pbrook
    if (s->config == 0) {
86 9ee6e8bb pbrook
        /* 32-bit CountDown.  */
87 9ee6e8bb pbrook
        uint32_t count;
88 9ee6e8bb pbrook
        count = s->load[0] | (s->load[1] << 16);
89 e57ec016 pbrook
        tick += (int64_t)count * system_clock_scale;
90 9ee6e8bb pbrook
    } else if (s->config == 1) {
91 9ee6e8bb pbrook
        /* 32-bit RTC.  1Hz tick.  */
92 6ee093c9 Juan Quintela
        tick += get_ticks_per_sec();
93 9ee6e8bb pbrook
    } else if (s->mode[n] == 0xa) {
94 9ee6e8bb pbrook
        /* PWM mode.  Not implemented.  */
95 9ee6e8bb pbrook
    } else {
96 2ac71179 Paul Brook
        hw_error("TODO: 16-bit timer mode 0x%x\n", s->mode[n]);
97 9ee6e8bb pbrook
    }
98 9ee6e8bb pbrook
    s->tick[n] = tick;
99 9ee6e8bb pbrook
    qemu_mod_timer(s->timer[n], tick);
100 9ee6e8bb pbrook
}
101 9ee6e8bb pbrook
102 9ee6e8bb pbrook
static void gptm_tick(void *opaque)
103 9ee6e8bb pbrook
{
104 9ee6e8bb pbrook
    gptm_state **p = (gptm_state **)opaque;
105 9ee6e8bb pbrook
    gptm_state *s;
106 9ee6e8bb pbrook
    int n;
107 9ee6e8bb pbrook
108 9ee6e8bb pbrook
    s = *p;
109 9ee6e8bb pbrook
    n = p - s->opaque;
110 9ee6e8bb pbrook
    if (s->config == 0) {
111 9ee6e8bb pbrook
        s->state |= 1;
112 9ee6e8bb pbrook
        if ((s->control & 0x20)) {
113 9ee6e8bb pbrook
            /* Output trigger.  */
114 40905a6a Paul Brook
            qemu_irq_pulse(s->trigger);
115 9ee6e8bb pbrook
        }
116 9ee6e8bb pbrook
        if (s->mode[0] & 1) {
117 9ee6e8bb pbrook
            /* One-shot.  */
118 9ee6e8bb pbrook
            s->control &= ~1;
119 9ee6e8bb pbrook
        } else {
120 9ee6e8bb pbrook
            /* Periodic.  */
121 9ee6e8bb pbrook
            gptm_reload(s, 0, 0);
122 9ee6e8bb pbrook
        }
123 9ee6e8bb pbrook
    } else if (s->config == 1) {
124 9ee6e8bb pbrook
        /* RTC.  */
125 9ee6e8bb pbrook
        uint32_t match;
126 9ee6e8bb pbrook
        s->rtc++;
127 9ee6e8bb pbrook
        match = s->match[0] | (s->match[1] << 16);
128 9ee6e8bb pbrook
        if (s->rtc > match)
129 9ee6e8bb pbrook
            s->rtc = 0;
130 9ee6e8bb pbrook
        if (s->rtc == 0) {
131 9ee6e8bb pbrook
            s->state |= 8;
132 9ee6e8bb pbrook
        }
133 9ee6e8bb pbrook
        gptm_reload(s, 0, 0);
134 9ee6e8bb pbrook
    } else if (s->mode[n] == 0xa) {
135 9ee6e8bb pbrook
        /* PWM mode.  Not implemented.  */
136 9ee6e8bb pbrook
    } else {
137 2ac71179 Paul Brook
        hw_error("TODO: 16-bit timer mode 0x%x\n", s->mode[n]);
138 9ee6e8bb pbrook
    }
139 9ee6e8bb pbrook
    gptm_update_irq(s);
140 9ee6e8bb pbrook
}
141 9ee6e8bb pbrook
142 c227f099 Anthony Liguori
static uint32_t gptm_read(void *opaque, target_phys_addr_t offset)
143 9ee6e8bb pbrook
{
144 9ee6e8bb pbrook
    gptm_state *s = (gptm_state *)opaque;
145 9ee6e8bb pbrook
146 9ee6e8bb pbrook
    switch (offset) {
147 9ee6e8bb pbrook
    case 0x00: /* CFG */
148 9ee6e8bb pbrook
        return s->config;
149 9ee6e8bb pbrook
    case 0x04: /* TAMR */
150 9ee6e8bb pbrook
        return s->mode[0];
151 9ee6e8bb pbrook
    case 0x08: /* TBMR */
152 9ee6e8bb pbrook
        return s->mode[1];
153 9ee6e8bb pbrook
    case 0x0c: /* CTL */
154 9ee6e8bb pbrook
        return s->control;
155 9ee6e8bb pbrook
    case 0x18: /* IMR */
156 9ee6e8bb pbrook
        return s->mask;
157 9ee6e8bb pbrook
    case 0x1c: /* RIS */
158 9ee6e8bb pbrook
        return s->state;
159 9ee6e8bb pbrook
    case 0x20: /* MIS */
160 9ee6e8bb pbrook
        return s->state & s->mask;
161 9ee6e8bb pbrook
    case 0x24: /* CR */
162 9ee6e8bb pbrook
        return 0;
163 9ee6e8bb pbrook
    case 0x28: /* TAILR */
164 9ee6e8bb pbrook
        return s->load[0] | ((s->config < 4) ? (s->load[1] << 16) : 0);
165 9ee6e8bb pbrook
    case 0x2c: /* TBILR */
166 9ee6e8bb pbrook
        return s->load[1];
167 9ee6e8bb pbrook
    case 0x30: /* TAMARCHR */
168 9ee6e8bb pbrook
        return s->match[0] | ((s->config < 4) ? (s->match[1] << 16) : 0);
169 9ee6e8bb pbrook
    case 0x34: /* TBMATCHR */
170 9ee6e8bb pbrook
        return s->match[1];
171 9ee6e8bb pbrook
    case 0x38: /* TAPR */
172 9ee6e8bb pbrook
        return s->prescale[0];
173 9ee6e8bb pbrook
    case 0x3c: /* TBPR */
174 9ee6e8bb pbrook
        return s->prescale[1];
175 9ee6e8bb pbrook
    case 0x40: /* TAPMR */
176 9ee6e8bb pbrook
        return s->match_prescale[0];
177 9ee6e8bb pbrook
    case 0x44: /* TBPMR */
178 9ee6e8bb pbrook
        return s->match_prescale[1];
179 9ee6e8bb pbrook
    case 0x48: /* TAR */
180 9ee6e8bb pbrook
        if (s->control == 1)
181 9ee6e8bb pbrook
            return s->rtc;
182 9ee6e8bb pbrook
    case 0x4c: /* TBR */
183 2ac71179 Paul Brook
        hw_error("TODO: Timer value read\n");
184 9ee6e8bb pbrook
    default:
185 2ac71179 Paul Brook
        hw_error("gptm_read: Bad offset 0x%x\n", (int)offset);
186 9ee6e8bb pbrook
        return 0;
187 9ee6e8bb pbrook
    }
188 9ee6e8bb pbrook
}
189 9ee6e8bb pbrook
190 c227f099 Anthony Liguori
static void gptm_write(void *opaque, target_phys_addr_t offset, uint32_t value)
191 9ee6e8bb pbrook
{
192 9ee6e8bb pbrook
    gptm_state *s = (gptm_state *)opaque;
193 9ee6e8bb pbrook
    uint32_t oldval;
194 9ee6e8bb pbrook
195 9ee6e8bb pbrook
    /* The timers should be disabled before changing the configuration.
196 9ee6e8bb pbrook
       We take advantage of this and defer everything until the timer
197 9ee6e8bb pbrook
       is enabled.  */
198 9ee6e8bb pbrook
    switch (offset) {
199 9ee6e8bb pbrook
    case 0x00: /* CFG */
200 9ee6e8bb pbrook
        s->config = value;
201 9ee6e8bb pbrook
        break;
202 9ee6e8bb pbrook
    case 0x04: /* TAMR */
203 9ee6e8bb pbrook
        s->mode[0] = value;
204 9ee6e8bb pbrook
        break;
205 9ee6e8bb pbrook
    case 0x08: /* TBMR */
206 9ee6e8bb pbrook
        s->mode[1] = value;
207 9ee6e8bb pbrook
        break;
208 9ee6e8bb pbrook
    case 0x0c: /* CTL */
209 9ee6e8bb pbrook
        oldval = s->control;
210 9ee6e8bb pbrook
        s->control = value;
211 9ee6e8bb pbrook
        /* TODO: Implement pause.  */
212 9ee6e8bb pbrook
        if ((oldval ^ value) & 1) {
213 9ee6e8bb pbrook
            if (value & 1) {
214 9ee6e8bb pbrook
                gptm_reload(s, 0, 1);
215 9ee6e8bb pbrook
            } else {
216 9ee6e8bb pbrook
                gptm_stop(s, 0);
217 9ee6e8bb pbrook
            }
218 9ee6e8bb pbrook
        }
219 9ee6e8bb pbrook
        if (((oldval ^ value) & 0x100) && s->config >= 4) {
220 9ee6e8bb pbrook
            if (value & 0x100) {
221 9ee6e8bb pbrook
                gptm_reload(s, 1, 1);
222 9ee6e8bb pbrook
            } else {
223 9ee6e8bb pbrook
                gptm_stop(s, 1);
224 9ee6e8bb pbrook
            }
225 9ee6e8bb pbrook
        }
226 9ee6e8bb pbrook
        break;
227 9ee6e8bb pbrook
    case 0x18: /* IMR */
228 9ee6e8bb pbrook
        s->mask = value & 0x77;
229 9ee6e8bb pbrook
        gptm_update_irq(s);
230 9ee6e8bb pbrook
        break;
231 9ee6e8bb pbrook
    case 0x24: /* CR */
232 9ee6e8bb pbrook
        s->state &= ~value;
233 9ee6e8bb pbrook
        break;
234 9ee6e8bb pbrook
    case 0x28: /* TAILR */
235 9ee6e8bb pbrook
        s->load[0] = value & 0xffff;
236 9ee6e8bb pbrook
        if (s->config < 4) {
237 9ee6e8bb pbrook
            s->load[1] = value >> 16;
238 9ee6e8bb pbrook
        }
239 9ee6e8bb pbrook
        break;
240 9ee6e8bb pbrook
    case 0x2c: /* TBILR */
241 9ee6e8bb pbrook
        s->load[1] = value & 0xffff;
242 9ee6e8bb pbrook
        break;
243 9ee6e8bb pbrook
    case 0x30: /* TAMARCHR */
244 9ee6e8bb pbrook
        s->match[0] = value & 0xffff;
245 9ee6e8bb pbrook
        if (s->config < 4) {
246 9ee6e8bb pbrook
            s->match[1] = value >> 16;
247 9ee6e8bb pbrook
        }
248 9ee6e8bb pbrook
        break;
249 9ee6e8bb pbrook
    case 0x34: /* TBMATCHR */
250 9ee6e8bb pbrook
        s->match[1] = value >> 16;
251 9ee6e8bb pbrook
        break;
252 9ee6e8bb pbrook
    case 0x38: /* TAPR */
253 9ee6e8bb pbrook
        s->prescale[0] = value;
254 9ee6e8bb pbrook
        break;
255 9ee6e8bb pbrook
    case 0x3c: /* TBPR */
256 9ee6e8bb pbrook
        s->prescale[1] = value;
257 9ee6e8bb pbrook
        break;
258 9ee6e8bb pbrook
    case 0x40: /* TAPMR */
259 9ee6e8bb pbrook
        s->match_prescale[0] = value;
260 9ee6e8bb pbrook
        break;
261 9ee6e8bb pbrook
    case 0x44: /* TBPMR */
262 9ee6e8bb pbrook
        s->match_prescale[0] = value;
263 9ee6e8bb pbrook
        break;
264 9ee6e8bb pbrook
    default:
265 2ac71179 Paul Brook
        hw_error("gptm_write: Bad offset 0x%x\n", (int)offset);
266 9ee6e8bb pbrook
    }
267 9ee6e8bb pbrook
    gptm_update_irq(s);
268 9ee6e8bb pbrook
}
269 9ee6e8bb pbrook
270 d60efc6b Blue Swirl
static CPUReadMemoryFunc * const gptm_readfn[] = {
271 9ee6e8bb pbrook
   gptm_read,
272 9ee6e8bb pbrook
   gptm_read,
273 9ee6e8bb pbrook
   gptm_read
274 9ee6e8bb pbrook
};
275 9ee6e8bb pbrook
276 d60efc6b Blue Swirl
static CPUWriteMemoryFunc * const gptm_writefn[] = {
277 9ee6e8bb pbrook
   gptm_write,
278 9ee6e8bb pbrook
   gptm_write,
279 9ee6e8bb pbrook
   gptm_write
280 9ee6e8bb pbrook
};
281 9ee6e8bb pbrook
282 10f85a29 Juan Quintela
static const VMStateDescription vmstate_stellaris_gptm = {
283 10f85a29 Juan Quintela
    .name = "stellaris_gptm",
284 10f85a29 Juan Quintela
    .version_id = 1,
285 10f85a29 Juan Quintela
    .minimum_version_id = 1,
286 10f85a29 Juan Quintela
    .minimum_version_id_old = 1,
287 10f85a29 Juan Quintela
    .fields      = (VMStateField[]) {
288 10f85a29 Juan Quintela
        VMSTATE_UINT32(config, gptm_state),
289 10f85a29 Juan Quintela
        VMSTATE_UINT32_ARRAY(mode, gptm_state, 2),
290 10f85a29 Juan Quintela
        VMSTATE_UINT32(control, gptm_state),
291 10f85a29 Juan Quintela
        VMSTATE_UINT32(state, gptm_state),
292 10f85a29 Juan Quintela
        VMSTATE_UINT32(mask, gptm_state),
293 dd8a4dcd Juan Quintela
        VMSTATE_UNUSED(8),
294 10f85a29 Juan Quintela
        VMSTATE_UINT32_ARRAY(load, gptm_state, 2),
295 10f85a29 Juan Quintela
        VMSTATE_UINT32_ARRAY(match, gptm_state, 2),
296 10f85a29 Juan Quintela
        VMSTATE_UINT32_ARRAY(prescale, gptm_state, 2),
297 10f85a29 Juan Quintela
        VMSTATE_UINT32_ARRAY(match_prescale, gptm_state, 2),
298 10f85a29 Juan Quintela
        VMSTATE_UINT32(rtc, gptm_state),
299 10f85a29 Juan Quintela
        VMSTATE_INT64_ARRAY(tick, gptm_state, 2),
300 10f85a29 Juan Quintela
        VMSTATE_TIMER_ARRAY(timer, gptm_state, 2),
301 10f85a29 Juan Quintela
        VMSTATE_END_OF_LIST()
302 10f85a29 Juan Quintela
    }
303 10f85a29 Juan Quintela
};
304 23e39294 pbrook
305 81a322d4 Gerd Hoffmann
static int stellaris_gptm_init(SysBusDevice *dev)
306 9ee6e8bb pbrook
{
307 9ee6e8bb pbrook
    int iomemtype;
308 40905a6a Paul Brook
    gptm_state *s = FROM_SYSBUS(gptm_state, dev);
309 9ee6e8bb pbrook
310 40905a6a Paul Brook
    sysbus_init_irq(dev, &s->irq);
311 40905a6a Paul Brook
    qdev_init_gpio_out(&dev->qdev, &s->trigger, 1);
312 9ee6e8bb pbrook
313 1eed09cb Avi Kivity
    iomemtype = cpu_register_io_memory(gptm_readfn,
314 2507c12a Alexander Graf
                                       gptm_writefn, s,
315 2507c12a Alexander Graf
                                       DEVICE_NATIVE_ENDIAN);
316 40905a6a Paul Brook
    sysbus_init_mmio(dev, 0x1000, iomemtype);
317 40905a6a Paul Brook
318 40905a6a Paul Brook
    s->opaque[0] = s->opaque[1] = s;
319 74475455 Paolo Bonzini
    s->timer[0] = qemu_new_timer_ns(vm_clock, gptm_tick, &s->opaque[0]);
320 74475455 Paolo Bonzini
    s->timer[1] = qemu_new_timer_ns(vm_clock, gptm_tick, &s->opaque[1]);
321 10f85a29 Juan Quintela
    vmstate_register(&dev->qdev, -1, &vmstate_stellaris_gptm, s);
322 81a322d4 Gerd Hoffmann
    return 0;
323 9ee6e8bb pbrook
}
324 9ee6e8bb pbrook
325 9ee6e8bb pbrook
326 9ee6e8bb pbrook
/* System controller.  */
327 9ee6e8bb pbrook
328 9ee6e8bb pbrook
typedef struct {
329 9ee6e8bb pbrook
    uint32_t pborctl;
330 9ee6e8bb pbrook
    uint32_t ldopctl;
331 9ee6e8bb pbrook
    uint32_t int_status;
332 9ee6e8bb pbrook
    uint32_t int_mask;
333 9ee6e8bb pbrook
    uint32_t resc;
334 9ee6e8bb pbrook
    uint32_t rcc;
335 dc804ab7 Engin AYDOGAN
    uint32_t rcc2;
336 9ee6e8bb pbrook
    uint32_t rcgc[3];
337 9ee6e8bb pbrook
    uint32_t scgc[3];
338 9ee6e8bb pbrook
    uint32_t dcgc[3];
339 9ee6e8bb pbrook
    uint32_t clkvclr;
340 9ee6e8bb pbrook
    uint32_t ldoarst;
341 eea589cc pbrook
    uint32_t user0;
342 eea589cc pbrook
    uint32_t user1;
343 9ee6e8bb pbrook
    qemu_irq irq;
344 9ee6e8bb pbrook
    stellaris_board_info *board;
345 9ee6e8bb pbrook
} ssys_state;
346 9ee6e8bb pbrook
347 9ee6e8bb pbrook
static void ssys_update(ssys_state *s)
348 9ee6e8bb pbrook
{
349 9ee6e8bb pbrook
  qemu_set_irq(s->irq, (s->int_status & s->int_mask) != 0);
350 9ee6e8bb pbrook
}
351 9ee6e8bb pbrook
352 9ee6e8bb pbrook
static uint32_t pllcfg_sandstorm[16] = {
353 9ee6e8bb pbrook
    0x31c0, /* 1 Mhz */
354 9ee6e8bb pbrook
    0x1ae0, /* 1.8432 Mhz */
355 9ee6e8bb pbrook
    0x18c0, /* 2 Mhz */
356 9ee6e8bb pbrook
    0xd573, /* 2.4576 Mhz */
357 9ee6e8bb pbrook
    0x37a6, /* 3.57954 Mhz */
358 9ee6e8bb pbrook
    0x1ae2, /* 3.6864 Mhz */
359 9ee6e8bb pbrook
    0x0c40, /* 4 Mhz */
360 9ee6e8bb pbrook
    0x98bc, /* 4.906 Mhz */
361 9ee6e8bb pbrook
    0x935b, /* 4.9152 Mhz */
362 9ee6e8bb pbrook
    0x09c0, /* 5 Mhz */
363 9ee6e8bb pbrook
    0x4dee, /* 5.12 Mhz */
364 9ee6e8bb pbrook
    0x0c41, /* 6 Mhz */
365 9ee6e8bb pbrook
    0x75db, /* 6.144 Mhz */
366 9ee6e8bb pbrook
    0x1ae6, /* 7.3728 Mhz */
367 9ee6e8bb pbrook
    0x0600, /* 8 Mhz */
368 9ee6e8bb pbrook
    0x585b /* 8.192 Mhz */
369 9ee6e8bb pbrook
};
370 9ee6e8bb pbrook
371 9ee6e8bb pbrook
static uint32_t pllcfg_fury[16] = {
372 9ee6e8bb pbrook
    0x3200, /* 1 Mhz */
373 9ee6e8bb pbrook
    0x1b20, /* 1.8432 Mhz */
374 9ee6e8bb pbrook
    0x1900, /* 2 Mhz */
375 9ee6e8bb pbrook
    0xf42b, /* 2.4576 Mhz */
376 9ee6e8bb pbrook
    0x37e3, /* 3.57954 Mhz */
377 9ee6e8bb pbrook
    0x1b21, /* 3.6864 Mhz */
378 9ee6e8bb pbrook
    0x0c80, /* 4 Mhz */
379 9ee6e8bb pbrook
    0x98ee, /* 4.906 Mhz */
380 9ee6e8bb pbrook
    0xd5b4, /* 4.9152 Mhz */
381 9ee6e8bb pbrook
    0x0a00, /* 5 Mhz */
382 9ee6e8bb pbrook
    0x4e27, /* 5.12 Mhz */
383 9ee6e8bb pbrook
    0x1902, /* 6 Mhz */
384 9ee6e8bb pbrook
    0xec1c, /* 6.144 Mhz */
385 9ee6e8bb pbrook
    0x1b23, /* 7.3728 Mhz */
386 9ee6e8bb pbrook
    0x0640, /* 8 Mhz */
387 9ee6e8bb pbrook
    0xb11c /* 8.192 Mhz */
388 9ee6e8bb pbrook
};
389 9ee6e8bb pbrook
390 dc804ab7 Engin AYDOGAN
#define DID0_VER_MASK        0x70000000
391 dc804ab7 Engin AYDOGAN
#define DID0_VER_0           0x00000000
392 dc804ab7 Engin AYDOGAN
#define DID0_VER_1           0x10000000
393 dc804ab7 Engin AYDOGAN
394 dc804ab7 Engin AYDOGAN
#define DID0_CLASS_MASK      0x00FF0000
395 dc804ab7 Engin AYDOGAN
#define DID0_CLASS_SANDSTORM 0x00000000
396 dc804ab7 Engin AYDOGAN
#define DID0_CLASS_FURY      0x00010000
397 dc804ab7 Engin AYDOGAN
398 dc804ab7 Engin AYDOGAN
static int ssys_board_class(const ssys_state *s)
399 dc804ab7 Engin AYDOGAN
{
400 dc804ab7 Engin AYDOGAN
    uint32_t did0 = s->board->did0;
401 dc804ab7 Engin AYDOGAN
    switch (did0 & DID0_VER_MASK) {
402 dc804ab7 Engin AYDOGAN
    case DID0_VER_0:
403 dc804ab7 Engin AYDOGAN
        return DID0_CLASS_SANDSTORM;
404 dc804ab7 Engin AYDOGAN
    case DID0_VER_1:
405 dc804ab7 Engin AYDOGAN
        switch (did0 & DID0_CLASS_MASK) {
406 dc804ab7 Engin AYDOGAN
        case DID0_CLASS_SANDSTORM:
407 dc804ab7 Engin AYDOGAN
        case DID0_CLASS_FURY:
408 dc804ab7 Engin AYDOGAN
            return did0 & DID0_CLASS_MASK;
409 dc804ab7 Engin AYDOGAN
        }
410 dc804ab7 Engin AYDOGAN
        /* for unknown classes, fall through */
411 dc804ab7 Engin AYDOGAN
    default:
412 dc804ab7 Engin AYDOGAN
        hw_error("ssys_board_class: Unknown class 0x%08x\n", did0);
413 dc804ab7 Engin AYDOGAN
    }
414 dc804ab7 Engin AYDOGAN
}
415 dc804ab7 Engin AYDOGAN
416 c227f099 Anthony Liguori
static uint32_t ssys_read(void *opaque, target_phys_addr_t offset)
417 9ee6e8bb pbrook
{
418 9ee6e8bb pbrook
    ssys_state *s = (ssys_state *)opaque;
419 9ee6e8bb pbrook
420 9ee6e8bb pbrook
    switch (offset) {
421 9ee6e8bb pbrook
    case 0x000: /* DID0 */
422 9ee6e8bb pbrook
        return s->board->did0;
423 9ee6e8bb pbrook
    case 0x004: /* DID1 */
424 9ee6e8bb pbrook
        return s->board->did1;
425 9ee6e8bb pbrook
    case 0x008: /* DC0 */
426 9ee6e8bb pbrook
        return s->board->dc0;
427 9ee6e8bb pbrook
    case 0x010: /* DC1 */
428 9ee6e8bb pbrook
        return s->board->dc1;
429 9ee6e8bb pbrook
    case 0x014: /* DC2 */
430 9ee6e8bb pbrook
        return s->board->dc2;
431 9ee6e8bb pbrook
    case 0x018: /* DC3 */
432 9ee6e8bb pbrook
        return s->board->dc3;
433 9ee6e8bb pbrook
    case 0x01c: /* DC4 */
434 9ee6e8bb pbrook
        return s->board->dc4;
435 9ee6e8bb pbrook
    case 0x030: /* PBORCTL */
436 9ee6e8bb pbrook
        return s->pborctl;
437 9ee6e8bb pbrook
    case 0x034: /* LDOPCTL */
438 9ee6e8bb pbrook
        return s->ldopctl;
439 9ee6e8bb pbrook
    case 0x040: /* SRCR0 */
440 9ee6e8bb pbrook
        return 0;
441 9ee6e8bb pbrook
    case 0x044: /* SRCR1 */
442 9ee6e8bb pbrook
        return 0;
443 9ee6e8bb pbrook
    case 0x048: /* SRCR2 */
444 9ee6e8bb pbrook
        return 0;
445 9ee6e8bb pbrook
    case 0x050: /* RIS */
446 9ee6e8bb pbrook
        return s->int_status;
447 9ee6e8bb pbrook
    case 0x054: /* IMC */
448 9ee6e8bb pbrook
        return s->int_mask;
449 9ee6e8bb pbrook
    case 0x058: /* MISC */
450 9ee6e8bb pbrook
        return s->int_status & s->int_mask;
451 9ee6e8bb pbrook
    case 0x05c: /* RESC */
452 9ee6e8bb pbrook
        return s->resc;
453 9ee6e8bb pbrook
    case 0x060: /* RCC */
454 9ee6e8bb pbrook
        return s->rcc;
455 9ee6e8bb pbrook
    case 0x064: /* PLLCFG */
456 9ee6e8bb pbrook
        {
457 9ee6e8bb pbrook
            int xtal;
458 9ee6e8bb pbrook
            xtal = (s->rcc >> 6) & 0xf;
459 dc804ab7 Engin AYDOGAN
            switch (ssys_board_class(s)) {
460 dc804ab7 Engin AYDOGAN
            case DID0_CLASS_FURY:
461 9ee6e8bb pbrook
                return pllcfg_fury[xtal];
462 dc804ab7 Engin AYDOGAN
            case DID0_CLASS_SANDSTORM:
463 9ee6e8bb pbrook
                return pllcfg_sandstorm[xtal];
464 dc804ab7 Engin AYDOGAN
            default:
465 dc804ab7 Engin AYDOGAN
                hw_error("ssys_read: Unhandled class for PLLCFG read.\n");
466 dc804ab7 Engin AYDOGAN
                return 0;
467 9ee6e8bb pbrook
            }
468 9ee6e8bb pbrook
        }
469 dc804ab7 Engin AYDOGAN
    case 0x070: /* RCC2 */
470 dc804ab7 Engin AYDOGAN
        return s->rcc2;
471 9ee6e8bb pbrook
    case 0x100: /* RCGC0 */
472 9ee6e8bb pbrook
        return s->rcgc[0];
473 9ee6e8bb pbrook
    case 0x104: /* RCGC1 */
474 9ee6e8bb pbrook
        return s->rcgc[1];
475 9ee6e8bb pbrook
    case 0x108: /* RCGC2 */
476 9ee6e8bb pbrook
        return s->rcgc[2];
477 9ee6e8bb pbrook
    case 0x110: /* SCGC0 */
478 9ee6e8bb pbrook
        return s->scgc[0];
479 9ee6e8bb pbrook
    case 0x114: /* SCGC1 */
480 9ee6e8bb pbrook
        return s->scgc[1];
481 9ee6e8bb pbrook
    case 0x118: /* SCGC2 */
482 9ee6e8bb pbrook
        return s->scgc[2];
483 9ee6e8bb pbrook
    case 0x120: /* DCGC0 */
484 9ee6e8bb pbrook
        return s->dcgc[0];
485 9ee6e8bb pbrook
    case 0x124: /* DCGC1 */
486 9ee6e8bb pbrook
        return s->dcgc[1];
487 9ee6e8bb pbrook
    case 0x128: /* DCGC2 */
488 9ee6e8bb pbrook
        return s->dcgc[2];
489 9ee6e8bb pbrook
    case 0x150: /* CLKVCLR */
490 9ee6e8bb pbrook
        return s->clkvclr;
491 9ee6e8bb pbrook
    case 0x160: /* LDOARST */
492 9ee6e8bb pbrook
        return s->ldoarst;
493 eea589cc pbrook
    case 0x1e0: /* USER0 */
494 eea589cc pbrook
        return s->user0;
495 eea589cc pbrook
    case 0x1e4: /* USER1 */
496 eea589cc pbrook
        return s->user1;
497 9ee6e8bb pbrook
    default:
498 2ac71179 Paul Brook
        hw_error("ssys_read: Bad offset 0x%x\n", (int)offset);
499 9ee6e8bb pbrook
        return 0;
500 9ee6e8bb pbrook
    }
501 9ee6e8bb pbrook
}
502 9ee6e8bb pbrook
503 dc804ab7 Engin AYDOGAN
static bool ssys_use_rcc2(ssys_state *s)
504 dc804ab7 Engin AYDOGAN
{
505 dc804ab7 Engin AYDOGAN
    return (s->rcc2 >> 31) & 0x1;
506 dc804ab7 Engin AYDOGAN
}
507 dc804ab7 Engin AYDOGAN
508 dc804ab7 Engin AYDOGAN
/*
509 dc804ab7 Engin AYDOGAN
 * Caculate the sys. clock period in ms.
510 dc804ab7 Engin AYDOGAN
 */
511 23e39294 pbrook
static void ssys_calculate_system_clock(ssys_state *s)
512 23e39294 pbrook
{
513 dc804ab7 Engin AYDOGAN
    if (ssys_use_rcc2(s)) {
514 dc804ab7 Engin AYDOGAN
        system_clock_scale = 5 * (((s->rcc2 >> 23) & 0x3f) + 1);
515 dc804ab7 Engin AYDOGAN
    } else {
516 dc804ab7 Engin AYDOGAN
        system_clock_scale = 5 * (((s->rcc >> 23) & 0xf) + 1);
517 dc804ab7 Engin AYDOGAN
    }
518 23e39294 pbrook
}
519 23e39294 pbrook
520 c227f099 Anthony Liguori
static void ssys_write(void *opaque, target_phys_addr_t offset, uint32_t value)
521 9ee6e8bb pbrook
{
522 9ee6e8bb pbrook
    ssys_state *s = (ssys_state *)opaque;
523 9ee6e8bb pbrook
524 9ee6e8bb pbrook
    switch (offset) {
525 9ee6e8bb pbrook
    case 0x030: /* PBORCTL */
526 9ee6e8bb pbrook
        s->pborctl = value & 0xffff;
527 9ee6e8bb pbrook
        break;
528 9ee6e8bb pbrook
    case 0x034: /* LDOPCTL */
529 9ee6e8bb pbrook
        s->ldopctl = value & 0x1f;
530 9ee6e8bb pbrook
        break;
531 9ee6e8bb pbrook
    case 0x040: /* SRCR0 */
532 9ee6e8bb pbrook
    case 0x044: /* SRCR1 */
533 9ee6e8bb pbrook
    case 0x048: /* SRCR2 */
534 9ee6e8bb pbrook
        fprintf(stderr, "Peripheral reset not implemented\n");
535 9ee6e8bb pbrook
        break;
536 9ee6e8bb pbrook
    case 0x054: /* IMC */
537 9ee6e8bb pbrook
        s->int_mask = value & 0x7f;
538 9ee6e8bb pbrook
        break;
539 9ee6e8bb pbrook
    case 0x058: /* MISC */
540 9ee6e8bb pbrook
        s->int_status &= ~value;
541 9ee6e8bb pbrook
        break;
542 9ee6e8bb pbrook
    case 0x05c: /* RESC */
543 9ee6e8bb pbrook
        s->resc = value & 0x3f;
544 9ee6e8bb pbrook
        break;
545 9ee6e8bb pbrook
    case 0x060: /* RCC */
546 9ee6e8bb pbrook
        if ((s->rcc & (1 << 13)) != 0 && (value & (1 << 13)) == 0) {
547 9ee6e8bb pbrook
            /* PLL enable.  */
548 9ee6e8bb pbrook
            s->int_status |= (1 << 6);
549 9ee6e8bb pbrook
        }
550 9ee6e8bb pbrook
        s->rcc = value;
551 23e39294 pbrook
        ssys_calculate_system_clock(s);
552 9ee6e8bb pbrook
        break;
553 dc804ab7 Engin AYDOGAN
    case 0x070: /* RCC2 */
554 dc804ab7 Engin AYDOGAN
        if (ssys_board_class(s) == DID0_CLASS_SANDSTORM) {
555 dc804ab7 Engin AYDOGAN
            break;
556 dc804ab7 Engin AYDOGAN
        }
557 dc804ab7 Engin AYDOGAN
558 dc804ab7 Engin AYDOGAN
        if ((s->rcc2 & (1 << 13)) != 0 && (value & (1 << 13)) == 0) {
559 dc804ab7 Engin AYDOGAN
            /* PLL enable.  */
560 dc804ab7 Engin AYDOGAN
            s->int_status |= (1 << 6);
561 dc804ab7 Engin AYDOGAN
        }
562 dc804ab7 Engin AYDOGAN
        s->rcc2 = value;
563 dc804ab7 Engin AYDOGAN
        ssys_calculate_system_clock(s);
564 dc804ab7 Engin AYDOGAN
        break;
565 9ee6e8bb pbrook
    case 0x100: /* RCGC0 */
566 9ee6e8bb pbrook
        s->rcgc[0] = value;
567 9ee6e8bb pbrook
        break;
568 9ee6e8bb pbrook
    case 0x104: /* RCGC1 */
569 9ee6e8bb pbrook
        s->rcgc[1] = value;
570 9ee6e8bb pbrook
        break;
571 9ee6e8bb pbrook
    case 0x108: /* RCGC2 */
572 9ee6e8bb pbrook
        s->rcgc[2] = value;
573 9ee6e8bb pbrook
        break;
574 9ee6e8bb pbrook
    case 0x110: /* SCGC0 */
575 9ee6e8bb pbrook
        s->scgc[0] = value;
576 9ee6e8bb pbrook
        break;
577 9ee6e8bb pbrook
    case 0x114: /* SCGC1 */
578 9ee6e8bb pbrook
        s->scgc[1] = value;
579 9ee6e8bb pbrook
        break;
580 9ee6e8bb pbrook
    case 0x118: /* SCGC2 */
581 9ee6e8bb pbrook
        s->scgc[2] = value;
582 9ee6e8bb pbrook
        break;
583 9ee6e8bb pbrook
    case 0x120: /* DCGC0 */
584 9ee6e8bb pbrook
        s->dcgc[0] = value;
585 9ee6e8bb pbrook
        break;
586 9ee6e8bb pbrook
    case 0x124: /* DCGC1 */
587 9ee6e8bb pbrook
        s->dcgc[1] = value;
588 9ee6e8bb pbrook
        break;
589 9ee6e8bb pbrook
    case 0x128: /* DCGC2 */
590 9ee6e8bb pbrook
        s->dcgc[2] = value;
591 9ee6e8bb pbrook
        break;
592 9ee6e8bb pbrook
    case 0x150: /* CLKVCLR */
593 9ee6e8bb pbrook
        s->clkvclr = value;
594 9ee6e8bb pbrook
        break;
595 9ee6e8bb pbrook
    case 0x160: /* LDOARST */
596 9ee6e8bb pbrook
        s->ldoarst = value;
597 9ee6e8bb pbrook
        break;
598 9ee6e8bb pbrook
    default:
599 2ac71179 Paul Brook
        hw_error("ssys_write: Bad offset 0x%x\n", (int)offset);
600 9ee6e8bb pbrook
    }
601 9ee6e8bb pbrook
    ssys_update(s);
602 9ee6e8bb pbrook
}
603 9ee6e8bb pbrook
604 d60efc6b Blue Swirl
static CPUReadMemoryFunc * const ssys_readfn[] = {
605 9ee6e8bb pbrook
   ssys_read,
606 9ee6e8bb pbrook
   ssys_read,
607 9ee6e8bb pbrook
   ssys_read
608 9ee6e8bb pbrook
};
609 9ee6e8bb pbrook
610 d60efc6b Blue Swirl
static CPUWriteMemoryFunc * const ssys_writefn[] = {
611 9ee6e8bb pbrook
   ssys_write,
612 9ee6e8bb pbrook
   ssys_write,
613 9ee6e8bb pbrook
   ssys_write
614 9ee6e8bb pbrook
};
615 9ee6e8bb pbrook
616 9596ebb7 pbrook
static void ssys_reset(void *opaque)
617 9ee6e8bb pbrook
{
618 9ee6e8bb pbrook
    ssys_state *s = (ssys_state *)opaque;
619 9ee6e8bb pbrook
620 9ee6e8bb pbrook
    s->pborctl = 0x7ffd;
621 9ee6e8bb pbrook
    s->rcc = 0x078e3ac0;
622 dc804ab7 Engin AYDOGAN
623 dc804ab7 Engin AYDOGAN
    if (ssys_board_class(s) == DID0_CLASS_SANDSTORM) {
624 dc804ab7 Engin AYDOGAN
        s->rcc2 = 0;
625 dc804ab7 Engin AYDOGAN
    } else {
626 dc804ab7 Engin AYDOGAN
        s->rcc2 = 0x07802810;
627 dc804ab7 Engin AYDOGAN
    }
628 9ee6e8bb pbrook
    s->rcgc[0] = 1;
629 9ee6e8bb pbrook
    s->scgc[0] = 1;
630 9ee6e8bb pbrook
    s->dcgc[0] = 1;
631 9ee6e8bb pbrook
}
632 9ee6e8bb pbrook
633 293c16aa Juan Quintela
static int stellaris_sys_post_load(void *opaque, int version_id)
634 23e39294 pbrook
{
635 293c16aa Juan Quintela
    ssys_state *s = opaque;
636 23e39294 pbrook
637 23e39294 pbrook
    ssys_calculate_system_clock(s);
638 23e39294 pbrook
639 23e39294 pbrook
    return 0;
640 23e39294 pbrook
}
641 23e39294 pbrook
642 293c16aa Juan Quintela
static const VMStateDescription vmstate_stellaris_sys = {
643 293c16aa Juan Quintela
    .name = "stellaris_sys",
644 dc804ab7 Engin AYDOGAN
    .version_id = 2,
645 293c16aa Juan Quintela
    .minimum_version_id = 1,
646 293c16aa Juan Quintela
    .minimum_version_id_old = 1,
647 293c16aa Juan Quintela
    .post_load = stellaris_sys_post_load,
648 293c16aa Juan Quintela
    .fields      = (VMStateField[]) {
649 293c16aa Juan Quintela
        VMSTATE_UINT32(pborctl, ssys_state),
650 293c16aa Juan Quintela
        VMSTATE_UINT32(ldopctl, ssys_state),
651 293c16aa Juan Quintela
        VMSTATE_UINT32(int_mask, ssys_state),
652 293c16aa Juan Quintela
        VMSTATE_UINT32(int_status, ssys_state),
653 293c16aa Juan Quintela
        VMSTATE_UINT32(resc, ssys_state),
654 293c16aa Juan Quintela
        VMSTATE_UINT32(rcc, ssys_state),
655 dc804ab7 Engin AYDOGAN
        VMSTATE_UINT32_V(rcc2, ssys_state, 2),
656 293c16aa Juan Quintela
        VMSTATE_UINT32_ARRAY(rcgc, ssys_state, 3),
657 293c16aa Juan Quintela
        VMSTATE_UINT32_ARRAY(scgc, ssys_state, 3),
658 293c16aa Juan Quintela
        VMSTATE_UINT32_ARRAY(dcgc, ssys_state, 3),
659 293c16aa Juan Quintela
        VMSTATE_UINT32(clkvclr, ssys_state),
660 293c16aa Juan Quintela
        VMSTATE_UINT32(ldoarst, ssys_state),
661 293c16aa Juan Quintela
        VMSTATE_END_OF_LIST()
662 293c16aa Juan Quintela
    }
663 293c16aa Juan Quintela
};
664 293c16aa Juan Quintela
665 81a322d4 Gerd Hoffmann
static int stellaris_sys_init(uint32_t base, qemu_irq irq,
666 81a322d4 Gerd Hoffmann
                              stellaris_board_info * board,
667 81a322d4 Gerd Hoffmann
                              uint8_t *macaddr)
668 9ee6e8bb pbrook
{
669 9ee6e8bb pbrook
    int iomemtype;
670 9ee6e8bb pbrook
    ssys_state *s;
671 9ee6e8bb pbrook
672 7267c094 Anthony Liguori
    s = (ssys_state *)g_malloc0(sizeof(ssys_state));
673 9ee6e8bb pbrook
    s->irq = irq;
674 9ee6e8bb pbrook
    s->board = board;
675 eea589cc pbrook
    /* Most devices come preprogrammed with a MAC address in the user data. */
676 eea589cc pbrook
    s->user0 = macaddr[0] | (macaddr[1] << 8) | (macaddr[2] << 16);
677 eea589cc pbrook
    s->user1 = macaddr[3] | (macaddr[4] << 8) | (macaddr[5] << 16);
678 9ee6e8bb pbrook
679 1eed09cb Avi Kivity
    iomemtype = cpu_register_io_memory(ssys_readfn,
680 2507c12a Alexander Graf
                                       ssys_writefn, s,
681 2507c12a Alexander Graf
                                       DEVICE_NATIVE_ENDIAN);
682 9ee6e8bb pbrook
    cpu_register_physical_memory(base, 0x00001000, iomemtype);
683 9ee6e8bb pbrook
    ssys_reset(s);
684 293c16aa Juan Quintela
    vmstate_register(NULL, -1, &vmstate_stellaris_sys, s);
685 81a322d4 Gerd Hoffmann
    return 0;
686 9ee6e8bb pbrook
}
687 9ee6e8bb pbrook
688 9ee6e8bb pbrook
689 9ee6e8bb pbrook
/* I2C controller.  */
690 9ee6e8bb pbrook
691 9ee6e8bb pbrook
typedef struct {
692 1de9610c Paul Brook
    SysBusDevice busdev;
693 9ee6e8bb pbrook
    i2c_bus *bus;
694 9ee6e8bb pbrook
    qemu_irq irq;
695 9ee6e8bb pbrook
    uint32_t msa;
696 9ee6e8bb pbrook
    uint32_t mcs;
697 9ee6e8bb pbrook
    uint32_t mdr;
698 9ee6e8bb pbrook
    uint32_t mtpr;
699 9ee6e8bb pbrook
    uint32_t mimr;
700 9ee6e8bb pbrook
    uint32_t mris;
701 9ee6e8bb pbrook
    uint32_t mcr;
702 9ee6e8bb pbrook
} stellaris_i2c_state;
703 9ee6e8bb pbrook
704 9ee6e8bb pbrook
#define STELLARIS_I2C_MCS_BUSY    0x01
705 9ee6e8bb pbrook
#define STELLARIS_I2C_MCS_ERROR   0x02
706 9ee6e8bb pbrook
#define STELLARIS_I2C_MCS_ADRACK  0x04
707 9ee6e8bb pbrook
#define STELLARIS_I2C_MCS_DATACK  0x08
708 9ee6e8bb pbrook
#define STELLARIS_I2C_MCS_ARBLST  0x10
709 9ee6e8bb pbrook
#define STELLARIS_I2C_MCS_IDLE    0x20
710 9ee6e8bb pbrook
#define STELLARIS_I2C_MCS_BUSBSY  0x40
711 9ee6e8bb pbrook
712 c227f099 Anthony Liguori
static uint32_t stellaris_i2c_read(void *opaque, target_phys_addr_t offset)
713 9ee6e8bb pbrook
{
714 9ee6e8bb pbrook
    stellaris_i2c_state *s = (stellaris_i2c_state *)opaque;
715 9ee6e8bb pbrook
716 9ee6e8bb pbrook
    switch (offset) {
717 9ee6e8bb pbrook
    case 0x00: /* MSA */
718 9ee6e8bb pbrook
        return s->msa;
719 9ee6e8bb pbrook
    case 0x04: /* MCS */
720 9ee6e8bb pbrook
        /* We don't emulate timing, so the controller is never busy.  */
721 9ee6e8bb pbrook
        return s->mcs | STELLARIS_I2C_MCS_IDLE;
722 9ee6e8bb pbrook
    case 0x08: /* MDR */
723 9ee6e8bb pbrook
        return s->mdr;
724 9ee6e8bb pbrook
    case 0x0c: /* MTPR */
725 9ee6e8bb pbrook
        return s->mtpr;
726 9ee6e8bb pbrook
    case 0x10: /* MIMR */
727 9ee6e8bb pbrook
        return s->mimr;
728 9ee6e8bb pbrook
    case 0x14: /* MRIS */
729 9ee6e8bb pbrook
        return s->mris;
730 9ee6e8bb pbrook
    case 0x18: /* MMIS */
731 9ee6e8bb pbrook
        return s->mris & s->mimr;
732 9ee6e8bb pbrook
    case 0x20: /* MCR */
733 9ee6e8bb pbrook
        return s->mcr;
734 9ee6e8bb pbrook
    default:
735 2ac71179 Paul Brook
        hw_error("strllaris_i2c_read: Bad offset 0x%x\n", (int)offset);
736 9ee6e8bb pbrook
        return 0;
737 9ee6e8bb pbrook
    }
738 9ee6e8bb pbrook
}
739 9ee6e8bb pbrook
740 9ee6e8bb pbrook
static void stellaris_i2c_update(stellaris_i2c_state *s)
741 9ee6e8bb pbrook
{
742 9ee6e8bb pbrook
    int level;
743 9ee6e8bb pbrook
744 9ee6e8bb pbrook
    level = (s->mris & s->mimr) != 0;
745 9ee6e8bb pbrook
    qemu_set_irq(s->irq, level);
746 9ee6e8bb pbrook
}
747 9ee6e8bb pbrook
748 c227f099 Anthony Liguori
static void stellaris_i2c_write(void *opaque, target_phys_addr_t offset,
749 9ee6e8bb pbrook
                                uint32_t value)
750 9ee6e8bb pbrook
{
751 9ee6e8bb pbrook
    stellaris_i2c_state *s = (stellaris_i2c_state *)opaque;
752 9ee6e8bb pbrook
753 9ee6e8bb pbrook
    switch (offset) {
754 9ee6e8bb pbrook
    case 0x00: /* MSA */
755 9ee6e8bb pbrook
        s->msa = value & 0xff;
756 9ee6e8bb pbrook
        break;
757 9ee6e8bb pbrook
    case 0x04: /* MCS */
758 9ee6e8bb pbrook
        if ((s->mcr & 0x10) == 0) {
759 9ee6e8bb pbrook
            /* Disabled.  Do nothing.  */
760 9ee6e8bb pbrook
            break;
761 9ee6e8bb pbrook
        }
762 9ee6e8bb pbrook
        /* Grab the bus if this is starting a transfer.  */
763 9ee6e8bb pbrook
        if ((value & 2) && (s->mcs & STELLARIS_I2C_MCS_BUSBSY) == 0) {
764 9ee6e8bb pbrook
            if (i2c_start_transfer(s->bus, s->msa >> 1, s->msa & 1)) {
765 9ee6e8bb pbrook
                s->mcs |= STELLARIS_I2C_MCS_ARBLST;
766 9ee6e8bb pbrook
            } else {
767 9ee6e8bb pbrook
                s->mcs &= ~STELLARIS_I2C_MCS_ARBLST;
768 9ee6e8bb pbrook
                s->mcs |= STELLARIS_I2C_MCS_BUSBSY;
769 9ee6e8bb pbrook
            }
770 9ee6e8bb pbrook
        }
771 9ee6e8bb pbrook
        /* If we don't have the bus then indicate an error.  */
772 9ee6e8bb pbrook
        if (!i2c_bus_busy(s->bus)
773 9ee6e8bb pbrook
                || (s->mcs & STELLARIS_I2C_MCS_BUSBSY) == 0) {
774 9ee6e8bb pbrook
            s->mcs |= STELLARIS_I2C_MCS_ERROR;
775 9ee6e8bb pbrook
            break;
776 9ee6e8bb pbrook
        }
777 9ee6e8bb pbrook
        s->mcs &= ~STELLARIS_I2C_MCS_ERROR;
778 9ee6e8bb pbrook
        if (value & 1) {
779 9ee6e8bb pbrook
            /* Transfer a byte.  */
780 9ee6e8bb pbrook
            /* TODO: Handle errors.  */
781 9ee6e8bb pbrook
            if (s->msa & 1) {
782 9ee6e8bb pbrook
                /* Recv */
783 9ee6e8bb pbrook
                s->mdr = i2c_recv(s->bus) & 0xff;
784 9ee6e8bb pbrook
            } else {
785 9ee6e8bb pbrook
                /* Send */
786 9ee6e8bb pbrook
                i2c_send(s->bus, s->mdr);
787 9ee6e8bb pbrook
            }
788 9ee6e8bb pbrook
            /* Raise an interrupt.  */
789 9ee6e8bb pbrook
            s->mris |= 1;
790 9ee6e8bb pbrook
        }
791 9ee6e8bb pbrook
        if (value & 4) {
792 9ee6e8bb pbrook
            /* Finish transfer.  */
793 9ee6e8bb pbrook
            i2c_end_transfer(s->bus);
794 9ee6e8bb pbrook
            s->mcs &= ~STELLARIS_I2C_MCS_BUSBSY;
795 9ee6e8bb pbrook
        }
796 9ee6e8bb pbrook
        break;
797 9ee6e8bb pbrook
    case 0x08: /* MDR */
798 9ee6e8bb pbrook
        s->mdr = value & 0xff;
799 9ee6e8bb pbrook
        break;
800 9ee6e8bb pbrook
    case 0x0c: /* MTPR */
801 9ee6e8bb pbrook
        s->mtpr = value & 0xff;
802 9ee6e8bb pbrook
        break;
803 9ee6e8bb pbrook
    case 0x10: /* MIMR */
804 9ee6e8bb pbrook
        s->mimr = 1;
805 9ee6e8bb pbrook
        break;
806 9ee6e8bb pbrook
    case 0x1c: /* MICR */
807 9ee6e8bb pbrook
        s->mris &= ~value;
808 9ee6e8bb pbrook
        break;
809 9ee6e8bb pbrook
    case 0x20: /* MCR */
810 9ee6e8bb pbrook
        if (value & 1)
811 2ac71179 Paul Brook
            hw_error(
812 9ee6e8bb pbrook
                      "stellaris_i2c_write: Loopback not implemented\n");
813 9ee6e8bb pbrook
        if (value & 0x20)
814 2ac71179 Paul Brook
            hw_error(
815 9ee6e8bb pbrook
                      "stellaris_i2c_write: Slave mode not implemented\n");
816 9ee6e8bb pbrook
        s->mcr = value & 0x31;
817 9ee6e8bb pbrook
        break;
818 9ee6e8bb pbrook
    default:
819 2ac71179 Paul Brook
        hw_error("stellaris_i2c_write: Bad offset 0x%x\n",
820 9ee6e8bb pbrook
                  (int)offset);
821 9ee6e8bb pbrook
    }
822 9ee6e8bb pbrook
    stellaris_i2c_update(s);
823 9ee6e8bb pbrook
}
824 9ee6e8bb pbrook
825 9ee6e8bb pbrook
static void stellaris_i2c_reset(stellaris_i2c_state *s)
826 9ee6e8bb pbrook
{
827 9ee6e8bb pbrook
    if (s->mcs & STELLARIS_I2C_MCS_BUSBSY)
828 9ee6e8bb pbrook
        i2c_end_transfer(s->bus);
829 9ee6e8bb pbrook
830 9ee6e8bb pbrook
    s->msa = 0;
831 9ee6e8bb pbrook
    s->mcs = 0;
832 9ee6e8bb pbrook
    s->mdr = 0;
833 9ee6e8bb pbrook
    s->mtpr = 1;
834 9ee6e8bb pbrook
    s->mimr = 0;
835 9ee6e8bb pbrook
    s->mris = 0;
836 9ee6e8bb pbrook
    s->mcr = 0;
837 9ee6e8bb pbrook
    stellaris_i2c_update(s);
838 9ee6e8bb pbrook
}
839 9ee6e8bb pbrook
840 d60efc6b Blue Swirl
static CPUReadMemoryFunc * const stellaris_i2c_readfn[] = {
841 9ee6e8bb pbrook
   stellaris_i2c_read,
842 9ee6e8bb pbrook
   stellaris_i2c_read,
843 9ee6e8bb pbrook
   stellaris_i2c_read
844 9ee6e8bb pbrook
};
845 9ee6e8bb pbrook
846 d60efc6b Blue Swirl
static CPUWriteMemoryFunc * const stellaris_i2c_writefn[] = {
847 9ee6e8bb pbrook
   stellaris_i2c_write,
848 9ee6e8bb pbrook
   stellaris_i2c_write,
849 9ee6e8bb pbrook
   stellaris_i2c_write
850 9ee6e8bb pbrook
};
851 9ee6e8bb pbrook
852 ff269cd0 Juan Quintela
static const VMStateDescription vmstate_stellaris_i2c = {
853 ff269cd0 Juan Quintela
    .name = "stellaris_i2c",
854 ff269cd0 Juan Quintela
    .version_id = 1,
855 ff269cd0 Juan Quintela
    .minimum_version_id = 1,
856 ff269cd0 Juan Quintela
    .minimum_version_id_old = 1,
857 ff269cd0 Juan Quintela
    .fields      = (VMStateField[]) {
858 ff269cd0 Juan Quintela
        VMSTATE_UINT32(msa, stellaris_i2c_state),
859 ff269cd0 Juan Quintela
        VMSTATE_UINT32(mcs, stellaris_i2c_state),
860 ff269cd0 Juan Quintela
        VMSTATE_UINT32(mdr, stellaris_i2c_state),
861 ff269cd0 Juan Quintela
        VMSTATE_UINT32(mtpr, stellaris_i2c_state),
862 ff269cd0 Juan Quintela
        VMSTATE_UINT32(mimr, stellaris_i2c_state),
863 ff269cd0 Juan Quintela
        VMSTATE_UINT32(mris, stellaris_i2c_state),
864 ff269cd0 Juan Quintela
        VMSTATE_UINT32(mcr, stellaris_i2c_state),
865 ff269cd0 Juan Quintela
        VMSTATE_END_OF_LIST()
866 ff269cd0 Juan Quintela
    }
867 ff269cd0 Juan Quintela
};
868 23e39294 pbrook
869 81a322d4 Gerd Hoffmann
static int stellaris_i2c_init(SysBusDevice * dev)
870 9ee6e8bb pbrook
{
871 1de9610c Paul Brook
    stellaris_i2c_state *s = FROM_SYSBUS(stellaris_i2c_state, dev);
872 02e2da45 Paul Brook
    i2c_bus *bus;
873 9ee6e8bb pbrook
    int iomemtype;
874 9ee6e8bb pbrook
875 1de9610c Paul Brook
    sysbus_init_irq(dev, &s->irq);
876 02e2da45 Paul Brook
    bus = i2c_init_bus(&dev->qdev, "i2c");
877 9ee6e8bb pbrook
    s->bus = bus;
878 9ee6e8bb pbrook
879 1eed09cb Avi Kivity
    iomemtype = cpu_register_io_memory(stellaris_i2c_readfn,
880 2507c12a Alexander Graf
                                       stellaris_i2c_writefn, s,
881 2507c12a Alexander Graf
                                       DEVICE_NATIVE_ENDIAN);
882 1de9610c Paul Brook
    sysbus_init_mmio(dev, 0x1000, iomemtype);
883 9ee6e8bb pbrook
    /* ??? For now we only implement the master interface.  */
884 9ee6e8bb pbrook
    stellaris_i2c_reset(s);
885 ff269cd0 Juan Quintela
    vmstate_register(&dev->qdev, -1, &vmstate_stellaris_i2c, s);
886 81a322d4 Gerd Hoffmann
    return 0;
887 9ee6e8bb pbrook
}
888 9ee6e8bb pbrook
889 9ee6e8bb pbrook
/* Analogue to Digital Converter.  This is only partially implemented,
890 9ee6e8bb pbrook
   enough for applications that use a combined ADC and timer tick.  */
891 9ee6e8bb pbrook
892 9ee6e8bb pbrook
#define STELLARIS_ADC_EM_CONTROLLER 0
893 9ee6e8bb pbrook
#define STELLARIS_ADC_EM_COMP       1
894 9ee6e8bb pbrook
#define STELLARIS_ADC_EM_EXTERNAL   4
895 9ee6e8bb pbrook
#define STELLARIS_ADC_EM_TIMER      5
896 9ee6e8bb pbrook
#define STELLARIS_ADC_EM_PWM0       6
897 9ee6e8bb pbrook
#define STELLARIS_ADC_EM_PWM1       7
898 9ee6e8bb pbrook
#define STELLARIS_ADC_EM_PWM2       8
899 9ee6e8bb pbrook
900 9ee6e8bb pbrook
#define STELLARIS_ADC_FIFO_EMPTY    0x0100
901 9ee6e8bb pbrook
#define STELLARIS_ADC_FIFO_FULL     0x1000
902 9ee6e8bb pbrook
903 9ee6e8bb pbrook
typedef struct
904 9ee6e8bb pbrook
{
905 40905a6a Paul Brook
    SysBusDevice busdev;
906 9ee6e8bb pbrook
    uint32_t actss;
907 9ee6e8bb pbrook
    uint32_t ris;
908 9ee6e8bb pbrook
    uint32_t im;
909 9ee6e8bb pbrook
    uint32_t emux;
910 9ee6e8bb pbrook
    uint32_t ostat;
911 9ee6e8bb pbrook
    uint32_t ustat;
912 9ee6e8bb pbrook
    uint32_t sspri;
913 9ee6e8bb pbrook
    uint32_t sac;
914 9ee6e8bb pbrook
    struct {
915 9ee6e8bb pbrook
        uint32_t state;
916 9ee6e8bb pbrook
        uint32_t data[16];
917 9ee6e8bb pbrook
    } fifo[4];
918 9ee6e8bb pbrook
    uint32_t ssmux[4];
919 9ee6e8bb pbrook
    uint32_t ssctl[4];
920 23e39294 pbrook
    uint32_t noise;
921 2c6554bc Paul Brook
    qemu_irq irq[4];
922 9ee6e8bb pbrook
} stellaris_adc_state;
923 9ee6e8bb pbrook
924 9ee6e8bb pbrook
static uint32_t stellaris_adc_fifo_read(stellaris_adc_state *s, int n)
925 9ee6e8bb pbrook
{
926 9ee6e8bb pbrook
    int tail;
927 9ee6e8bb pbrook
928 9ee6e8bb pbrook
    tail = s->fifo[n].state & 0xf;
929 9ee6e8bb pbrook
    if (s->fifo[n].state & STELLARIS_ADC_FIFO_EMPTY) {
930 9ee6e8bb pbrook
        s->ustat |= 1 << n;
931 9ee6e8bb pbrook
    } else {
932 9ee6e8bb pbrook
        s->fifo[n].state = (s->fifo[n].state & ~0xf) | ((tail + 1) & 0xf);
933 9ee6e8bb pbrook
        s->fifo[n].state &= ~STELLARIS_ADC_FIFO_FULL;
934 9ee6e8bb pbrook
        if (tail + 1 == ((s->fifo[n].state >> 4) & 0xf))
935 9ee6e8bb pbrook
            s->fifo[n].state |= STELLARIS_ADC_FIFO_EMPTY;
936 9ee6e8bb pbrook
    }
937 9ee6e8bb pbrook
    return s->fifo[n].data[tail];
938 9ee6e8bb pbrook
}
939 9ee6e8bb pbrook
940 9ee6e8bb pbrook
static void stellaris_adc_fifo_write(stellaris_adc_state *s, int n,
941 9ee6e8bb pbrook
                                     uint32_t value)
942 9ee6e8bb pbrook
{
943 9ee6e8bb pbrook
    int head;
944 9ee6e8bb pbrook
945 2c6554bc Paul Brook
    /* TODO: Real hardware has limited size FIFOs.  We have a full 16 entry 
946 2c6554bc Paul Brook
       FIFO fir each sequencer.  */
947 9ee6e8bb pbrook
    head = (s->fifo[n].state >> 4) & 0xf;
948 9ee6e8bb pbrook
    if (s->fifo[n].state & STELLARIS_ADC_FIFO_FULL) {
949 9ee6e8bb pbrook
        s->ostat |= 1 << n;
950 9ee6e8bb pbrook
        return;
951 9ee6e8bb pbrook
    }
952 9ee6e8bb pbrook
    s->fifo[n].data[head] = value;
953 9ee6e8bb pbrook
    head = (head + 1) & 0xf;
954 9ee6e8bb pbrook
    s->fifo[n].state &= ~STELLARIS_ADC_FIFO_EMPTY;
955 9ee6e8bb pbrook
    s->fifo[n].state = (s->fifo[n].state & ~0xf0) | (head << 4);
956 9ee6e8bb pbrook
    if ((s->fifo[n].state & 0xf) == head)
957 9ee6e8bb pbrook
        s->fifo[n].state |= STELLARIS_ADC_FIFO_FULL;
958 9ee6e8bb pbrook
}
959 9ee6e8bb pbrook
960 9ee6e8bb pbrook
static void stellaris_adc_update(stellaris_adc_state *s)
961 9ee6e8bb pbrook
{
962 9ee6e8bb pbrook
    int level;
963 2c6554bc Paul Brook
    int n;
964 9ee6e8bb pbrook
965 2c6554bc Paul Brook
    for (n = 0; n < 4; n++) {
966 2c6554bc Paul Brook
        level = (s->ris & s->im & (1 << n)) != 0;
967 2c6554bc Paul Brook
        qemu_set_irq(s->irq[n], level);
968 2c6554bc Paul Brook
    }
969 9ee6e8bb pbrook
}
970 9ee6e8bb pbrook
971 9ee6e8bb pbrook
static void stellaris_adc_trigger(void *opaque, int irq, int level)
972 9ee6e8bb pbrook
{
973 9ee6e8bb pbrook
    stellaris_adc_state *s = (stellaris_adc_state *)opaque;
974 2c6554bc Paul Brook
    int n;
975 9ee6e8bb pbrook
976 2c6554bc Paul Brook
    for (n = 0; n < 4; n++) {
977 2c6554bc Paul Brook
        if ((s->actss & (1 << n)) == 0) {
978 2c6554bc Paul Brook
            continue;
979 2c6554bc Paul Brook
        }
980 9ee6e8bb pbrook
981 2c6554bc Paul Brook
        if (((s->emux >> (n * 4)) & 0xff) != 5) {
982 2c6554bc Paul Brook
            continue;
983 2c6554bc Paul Brook
        }
984 2c6554bc Paul Brook
985 2c6554bc Paul Brook
        /* Some applications use the ADC as a random number source, so introduce
986 2c6554bc Paul Brook
           some variation into the signal.  */
987 2c6554bc Paul Brook
        s->noise = s->noise * 314159 + 1;
988 2c6554bc Paul Brook
        /* ??? actual inputs not implemented.  Return an arbitrary value.  */
989 2c6554bc Paul Brook
        stellaris_adc_fifo_write(s, n, 0x200 + ((s->noise >> 16) & 7));
990 2c6554bc Paul Brook
        s->ris |= (1 << n);
991 2c6554bc Paul Brook
        stellaris_adc_update(s);
992 2c6554bc Paul Brook
    }
993 9ee6e8bb pbrook
}
994 9ee6e8bb pbrook
995 9ee6e8bb pbrook
static void stellaris_adc_reset(stellaris_adc_state *s)
996 9ee6e8bb pbrook
{
997 9ee6e8bb pbrook
    int n;
998 9ee6e8bb pbrook
999 9ee6e8bb pbrook
    for (n = 0; n < 4; n++) {
1000 9ee6e8bb pbrook
        s->ssmux[n] = 0;
1001 9ee6e8bb pbrook
        s->ssctl[n] = 0;
1002 9ee6e8bb pbrook
        s->fifo[n].state = STELLARIS_ADC_FIFO_EMPTY;
1003 9ee6e8bb pbrook
    }
1004 9ee6e8bb pbrook
}
1005 9ee6e8bb pbrook
1006 c227f099 Anthony Liguori
static uint32_t stellaris_adc_read(void *opaque, target_phys_addr_t offset)
1007 9ee6e8bb pbrook
{
1008 9ee6e8bb pbrook
    stellaris_adc_state *s = (stellaris_adc_state *)opaque;
1009 9ee6e8bb pbrook
1010 9ee6e8bb pbrook
    /* TODO: Implement this.  */
1011 9ee6e8bb pbrook
    if (offset >= 0x40 && offset < 0xc0) {
1012 9ee6e8bb pbrook
        int n;
1013 9ee6e8bb pbrook
        n = (offset - 0x40) >> 5;
1014 9ee6e8bb pbrook
        switch (offset & 0x1f) {
1015 9ee6e8bb pbrook
        case 0x00: /* SSMUX */
1016 9ee6e8bb pbrook
            return s->ssmux[n];
1017 9ee6e8bb pbrook
        case 0x04: /* SSCTL */
1018 9ee6e8bb pbrook
            return s->ssctl[n];
1019 9ee6e8bb pbrook
        case 0x08: /* SSFIFO */
1020 9ee6e8bb pbrook
            return stellaris_adc_fifo_read(s, n);
1021 9ee6e8bb pbrook
        case 0x0c: /* SSFSTAT */
1022 9ee6e8bb pbrook
            return s->fifo[n].state;
1023 9ee6e8bb pbrook
        default:
1024 9ee6e8bb pbrook
            break;
1025 9ee6e8bb pbrook
        }
1026 9ee6e8bb pbrook
    }
1027 9ee6e8bb pbrook
    switch (offset) {
1028 9ee6e8bb pbrook
    case 0x00: /* ACTSS */
1029 9ee6e8bb pbrook
        return s->actss;
1030 9ee6e8bb pbrook
    case 0x04: /* RIS */
1031 9ee6e8bb pbrook
        return s->ris;
1032 9ee6e8bb pbrook
    case 0x08: /* IM */
1033 9ee6e8bb pbrook
        return s->im;
1034 9ee6e8bb pbrook
    case 0x0c: /* ISC */
1035 9ee6e8bb pbrook
        return s->ris & s->im;
1036 9ee6e8bb pbrook
    case 0x10: /* OSTAT */
1037 9ee6e8bb pbrook
        return s->ostat;
1038 9ee6e8bb pbrook
    case 0x14: /* EMUX */
1039 9ee6e8bb pbrook
        return s->emux;
1040 9ee6e8bb pbrook
    case 0x18: /* USTAT */
1041 9ee6e8bb pbrook
        return s->ustat;
1042 9ee6e8bb pbrook
    case 0x20: /* SSPRI */
1043 9ee6e8bb pbrook
        return s->sspri;
1044 9ee6e8bb pbrook
    case 0x30: /* SAC */
1045 9ee6e8bb pbrook
        return s->sac;
1046 9ee6e8bb pbrook
    default:
1047 2ac71179 Paul Brook
        hw_error("strllaris_adc_read: Bad offset 0x%x\n",
1048 9ee6e8bb pbrook
                  (int)offset);
1049 9ee6e8bb pbrook
        return 0;
1050 9ee6e8bb pbrook
    }
1051 9ee6e8bb pbrook
}
1052 9ee6e8bb pbrook
1053 c227f099 Anthony Liguori
static void stellaris_adc_write(void *opaque, target_phys_addr_t offset,
1054 9ee6e8bb pbrook
                                uint32_t value)
1055 9ee6e8bb pbrook
{
1056 9ee6e8bb pbrook
    stellaris_adc_state *s = (stellaris_adc_state *)opaque;
1057 9ee6e8bb pbrook
1058 9ee6e8bb pbrook
    /* TODO: Implement this.  */
1059 9ee6e8bb pbrook
    if (offset >= 0x40 && offset < 0xc0) {
1060 9ee6e8bb pbrook
        int n;
1061 9ee6e8bb pbrook
        n = (offset - 0x40) >> 5;
1062 9ee6e8bb pbrook
        switch (offset & 0x1f) {
1063 9ee6e8bb pbrook
        case 0x00: /* SSMUX */
1064 9ee6e8bb pbrook
            s->ssmux[n] = value & 0x33333333;
1065 9ee6e8bb pbrook
            return;
1066 9ee6e8bb pbrook
        case 0x04: /* SSCTL */
1067 9ee6e8bb pbrook
            if (value != 6) {
1068 2ac71179 Paul Brook
                hw_error("ADC: Unimplemented sequence %x\n",
1069 9ee6e8bb pbrook
                          value);
1070 9ee6e8bb pbrook
            }
1071 9ee6e8bb pbrook
            s->ssctl[n] = value;
1072 9ee6e8bb pbrook
            return;
1073 9ee6e8bb pbrook
        default:
1074 9ee6e8bb pbrook
            break;
1075 9ee6e8bb pbrook
        }
1076 9ee6e8bb pbrook
    }
1077 9ee6e8bb pbrook
    switch (offset) {
1078 9ee6e8bb pbrook
    case 0x00: /* ACTSS */
1079 9ee6e8bb pbrook
        s->actss = value & 0xf;
1080 9ee6e8bb pbrook
        break;
1081 9ee6e8bb pbrook
    case 0x08: /* IM */
1082 9ee6e8bb pbrook
        s->im = value;
1083 9ee6e8bb pbrook
        break;
1084 9ee6e8bb pbrook
    case 0x0c: /* ISC */
1085 9ee6e8bb pbrook
        s->ris &= ~value;
1086 9ee6e8bb pbrook
        break;
1087 9ee6e8bb pbrook
    case 0x10: /* OSTAT */
1088 9ee6e8bb pbrook
        s->ostat &= ~value;
1089 9ee6e8bb pbrook
        break;
1090 9ee6e8bb pbrook
    case 0x14: /* EMUX */
1091 9ee6e8bb pbrook
        s->emux = value;
1092 9ee6e8bb pbrook
        break;
1093 9ee6e8bb pbrook
    case 0x18: /* USTAT */
1094 9ee6e8bb pbrook
        s->ustat &= ~value;
1095 9ee6e8bb pbrook
        break;
1096 9ee6e8bb pbrook
    case 0x20: /* SSPRI */
1097 9ee6e8bb pbrook
        s->sspri = value;
1098 9ee6e8bb pbrook
        break;
1099 9ee6e8bb pbrook
    case 0x28: /* PSSI */
1100 2ac71179 Paul Brook
        hw_error("Not implemented:  ADC sample initiate\n");
1101 9ee6e8bb pbrook
        break;
1102 9ee6e8bb pbrook
    case 0x30: /* SAC */
1103 9ee6e8bb pbrook
        s->sac = value;
1104 9ee6e8bb pbrook
        break;
1105 9ee6e8bb pbrook
    default:
1106 2ac71179 Paul Brook
        hw_error("stellaris_adc_write: Bad offset 0x%x\n", (int)offset);
1107 9ee6e8bb pbrook
    }
1108 9ee6e8bb pbrook
    stellaris_adc_update(s);
1109 9ee6e8bb pbrook
}
1110 9ee6e8bb pbrook
1111 d60efc6b Blue Swirl
static CPUReadMemoryFunc * const stellaris_adc_readfn[] = {
1112 9ee6e8bb pbrook
   stellaris_adc_read,
1113 9ee6e8bb pbrook
   stellaris_adc_read,
1114 9ee6e8bb pbrook
   stellaris_adc_read
1115 9ee6e8bb pbrook
};
1116 9ee6e8bb pbrook
1117 d60efc6b Blue Swirl
static CPUWriteMemoryFunc * const stellaris_adc_writefn[] = {
1118 9ee6e8bb pbrook
   stellaris_adc_write,
1119 9ee6e8bb pbrook
   stellaris_adc_write,
1120 9ee6e8bb pbrook
   stellaris_adc_write
1121 9ee6e8bb pbrook
};
1122 9ee6e8bb pbrook
1123 cf1d31dc Juan Quintela
static const VMStateDescription vmstate_stellaris_adc = {
1124 cf1d31dc Juan Quintela
    .name = "stellaris_adc",
1125 cf1d31dc Juan Quintela
    .version_id = 1,
1126 cf1d31dc Juan Quintela
    .minimum_version_id = 1,
1127 cf1d31dc Juan Quintela
    .minimum_version_id_old = 1,
1128 cf1d31dc Juan Quintela
    .fields      = (VMStateField[]) {
1129 cf1d31dc Juan Quintela
        VMSTATE_UINT32(actss, stellaris_adc_state),
1130 cf1d31dc Juan Quintela
        VMSTATE_UINT32(ris, stellaris_adc_state),
1131 cf1d31dc Juan Quintela
        VMSTATE_UINT32(im, stellaris_adc_state),
1132 cf1d31dc Juan Quintela
        VMSTATE_UINT32(emux, stellaris_adc_state),
1133 cf1d31dc Juan Quintela
        VMSTATE_UINT32(ostat, stellaris_adc_state),
1134 cf1d31dc Juan Quintela
        VMSTATE_UINT32(ustat, stellaris_adc_state),
1135 cf1d31dc Juan Quintela
        VMSTATE_UINT32(sspri, stellaris_adc_state),
1136 cf1d31dc Juan Quintela
        VMSTATE_UINT32(sac, stellaris_adc_state),
1137 cf1d31dc Juan Quintela
        VMSTATE_UINT32(fifo[0].state, stellaris_adc_state),
1138 cf1d31dc Juan Quintela
        VMSTATE_UINT32_ARRAY(fifo[0].data, stellaris_adc_state, 16),
1139 cf1d31dc Juan Quintela
        VMSTATE_UINT32(ssmux[0], stellaris_adc_state),
1140 cf1d31dc Juan Quintela
        VMSTATE_UINT32(ssctl[0], stellaris_adc_state),
1141 cf1d31dc Juan Quintela
        VMSTATE_UINT32(fifo[1].state, stellaris_adc_state),
1142 cf1d31dc Juan Quintela
        VMSTATE_UINT32_ARRAY(fifo[1].data, stellaris_adc_state, 16),
1143 cf1d31dc Juan Quintela
        VMSTATE_UINT32(ssmux[1], stellaris_adc_state),
1144 cf1d31dc Juan Quintela
        VMSTATE_UINT32(ssctl[1], stellaris_adc_state),
1145 cf1d31dc Juan Quintela
        VMSTATE_UINT32(fifo[2].state, stellaris_adc_state),
1146 cf1d31dc Juan Quintela
        VMSTATE_UINT32_ARRAY(fifo[2].data, stellaris_adc_state, 16),
1147 cf1d31dc Juan Quintela
        VMSTATE_UINT32(ssmux[2], stellaris_adc_state),
1148 cf1d31dc Juan Quintela
        VMSTATE_UINT32(ssctl[2], stellaris_adc_state),
1149 cf1d31dc Juan Quintela
        VMSTATE_UINT32(fifo[3].state, stellaris_adc_state),
1150 cf1d31dc Juan Quintela
        VMSTATE_UINT32_ARRAY(fifo[3].data, stellaris_adc_state, 16),
1151 cf1d31dc Juan Quintela
        VMSTATE_UINT32(ssmux[3], stellaris_adc_state),
1152 cf1d31dc Juan Quintela
        VMSTATE_UINT32(ssctl[3], stellaris_adc_state),
1153 cf1d31dc Juan Quintela
        VMSTATE_UINT32(noise, stellaris_adc_state),
1154 cf1d31dc Juan Quintela
        VMSTATE_END_OF_LIST()
1155 23e39294 pbrook
    }
1156 cf1d31dc Juan Quintela
};
1157 23e39294 pbrook
1158 81a322d4 Gerd Hoffmann
static int stellaris_adc_init(SysBusDevice *dev)
1159 9ee6e8bb pbrook
{
1160 40905a6a Paul Brook
    stellaris_adc_state *s = FROM_SYSBUS(stellaris_adc_state, dev);
1161 9ee6e8bb pbrook
    int iomemtype;
1162 2c6554bc Paul Brook
    int n;
1163 9ee6e8bb pbrook
1164 2c6554bc Paul Brook
    for (n = 0; n < 4; n++) {
1165 40905a6a Paul Brook
        sysbus_init_irq(dev, &s->irq[n]);
1166 2c6554bc Paul Brook
    }
1167 9ee6e8bb pbrook
1168 1eed09cb Avi Kivity
    iomemtype = cpu_register_io_memory(stellaris_adc_readfn,
1169 2507c12a Alexander Graf
                                       stellaris_adc_writefn, s,
1170 2507c12a Alexander Graf
                                       DEVICE_NATIVE_ENDIAN);
1171 40905a6a Paul Brook
    sysbus_init_mmio(dev, 0x1000, iomemtype);
1172 9ee6e8bb pbrook
    stellaris_adc_reset(s);
1173 40905a6a Paul Brook
    qdev_init_gpio_in(&dev->qdev, stellaris_adc_trigger, 1);
1174 cf1d31dc Juan Quintela
    vmstate_register(&dev->qdev, -1, &vmstate_stellaris_adc, s);
1175 81a322d4 Gerd Hoffmann
    return 0;
1176 9ee6e8bb pbrook
}
1177 9ee6e8bb pbrook
1178 775616c3 pbrook
/* Some boards have both an OLED controller and SD card connected to
1179 775616c3 pbrook
   the same SSI port, with the SD card chip select connected to a
1180 775616c3 pbrook
   GPIO pin.  Technically the OLED chip select is connected to the SSI
1181 775616c3 pbrook
   Fss pin.  We do not bother emulating that as both devices should
1182 775616c3 pbrook
   never be selected simultaneously, and our OLED controller ignores stray
1183 775616c3 pbrook
   0xff commands that occur when deselecting the SD card.  */
1184 775616c3 pbrook
1185 775616c3 pbrook
typedef struct {
1186 5493e33f Paul Brook
    SSISlave ssidev;
1187 775616c3 pbrook
    qemu_irq irq;
1188 775616c3 pbrook
    int current_dev;
1189 5493e33f Paul Brook
    SSIBus *bus[2];
1190 775616c3 pbrook
} stellaris_ssi_bus_state;
1191 775616c3 pbrook
1192 775616c3 pbrook
static void stellaris_ssi_bus_select(void *opaque, int irq, int level)
1193 775616c3 pbrook
{
1194 775616c3 pbrook
    stellaris_ssi_bus_state *s = (stellaris_ssi_bus_state *)opaque;
1195 775616c3 pbrook
1196 775616c3 pbrook
    s->current_dev = level;
1197 775616c3 pbrook
}
1198 775616c3 pbrook
1199 5493e33f Paul Brook
static uint32_t stellaris_ssi_bus_transfer(SSISlave *dev, uint32_t val)
1200 775616c3 pbrook
{
1201 5493e33f Paul Brook
    stellaris_ssi_bus_state *s = FROM_SSI_SLAVE(stellaris_ssi_bus_state, dev);
1202 775616c3 pbrook
1203 5493e33f Paul Brook
    return ssi_transfer(s->bus[s->current_dev], val);
1204 775616c3 pbrook
}
1205 775616c3 pbrook
1206 a4dec1d0 Juan Quintela
static const VMStateDescription vmstate_stellaris_ssi_bus = {
1207 a4dec1d0 Juan Quintela
    .name = "stellaris_ssi_bus",
1208 a4dec1d0 Juan Quintela
    .version_id = 1,
1209 a4dec1d0 Juan Quintela
    .minimum_version_id = 1,
1210 a4dec1d0 Juan Quintela
    .minimum_version_id_old = 1,
1211 a4dec1d0 Juan Quintela
    .fields      = (VMStateField[]) {
1212 a4dec1d0 Juan Quintela
        VMSTATE_INT32(current_dev, stellaris_ssi_bus_state),
1213 a4dec1d0 Juan Quintela
        VMSTATE_END_OF_LIST()
1214 a4dec1d0 Juan Quintela
    }
1215 a4dec1d0 Juan Quintela
};
1216 23e39294 pbrook
1217 81a322d4 Gerd Hoffmann
static int stellaris_ssi_bus_init(SSISlave *dev)
1218 775616c3 pbrook
{
1219 5493e33f Paul Brook
    stellaris_ssi_bus_state *s = FROM_SSI_SLAVE(stellaris_ssi_bus_state, dev);
1220 5493e33f Paul Brook
1221 02e2da45 Paul Brook
    s->bus[0] = ssi_create_bus(&dev->qdev, "ssi0");
1222 02e2da45 Paul Brook
    s->bus[1] = ssi_create_bus(&dev->qdev, "ssi1");
1223 5493e33f Paul Brook
    qdev_init_gpio_in(&dev->qdev, stellaris_ssi_bus_select, 1);
1224 5493e33f Paul Brook
1225 a4dec1d0 Juan Quintela
    vmstate_register(&dev->qdev, -1, &vmstate_stellaris_ssi_bus, s);
1226 81a322d4 Gerd Hoffmann
    return 0;
1227 775616c3 pbrook
}
1228 775616c3 pbrook
1229 9ee6e8bb pbrook
/* Board init.  */
1230 9ee6e8bb pbrook
static stellaris_board_info stellaris_boards[] = {
1231 9ee6e8bb pbrook
  { "LM3S811EVB",
1232 9ee6e8bb pbrook
    0,
1233 9ee6e8bb pbrook
    0x0032000e,
1234 9ee6e8bb pbrook
    0x001f001f, /* dc0 */
1235 9ee6e8bb pbrook
    0x001132bf,
1236 9ee6e8bb pbrook
    0x01071013,
1237 9ee6e8bb pbrook
    0x3f0f01ff,
1238 9ee6e8bb pbrook
    0x0000001f,
1239 cf0dbb21 pbrook
    BP_OLED_I2C
1240 9ee6e8bb pbrook
  },
1241 9ee6e8bb pbrook
  { "LM3S6965EVB",
1242 9ee6e8bb pbrook
    0x10010002,
1243 9ee6e8bb pbrook
    0x1073402e,
1244 9ee6e8bb pbrook
    0x00ff007f, /* dc0 */
1245 9ee6e8bb pbrook
    0x001133ff,
1246 9ee6e8bb pbrook
    0x030f5317,
1247 9ee6e8bb pbrook
    0x0f0f87ff,
1248 9ee6e8bb pbrook
    0x5000007f,
1249 cf0dbb21 pbrook
    BP_OLED_SSI | BP_GAMEPAD
1250 9ee6e8bb pbrook
  }
1251 9ee6e8bb pbrook
};
1252 9ee6e8bb pbrook
1253 9ee6e8bb pbrook
static void stellaris_init(const char *kernel_filename, const char *cpu_model,
1254 3023f332 aliguori
                           stellaris_board_info *board)
1255 9ee6e8bb pbrook
{
1256 9ee6e8bb pbrook
    static const int uart_irq[] = {5, 6, 33, 34};
1257 9ee6e8bb pbrook
    static const int timer_irq[] = {19, 21, 23, 35};
1258 9ee6e8bb pbrook
    static const uint32_t gpio_addr[7] =
1259 9ee6e8bb pbrook
      { 0x40004000, 0x40005000, 0x40006000, 0x40007000,
1260 9ee6e8bb pbrook
        0x40024000, 0x40025000, 0x40026000};
1261 9ee6e8bb pbrook
    static const int gpio_irq[7] = {0, 1, 2, 3, 4, 30, 31};
1262 9ee6e8bb pbrook
1263 9ee6e8bb pbrook
    qemu_irq *pic;
1264 40905a6a Paul Brook
    DeviceState *gpio_dev[7];
1265 40905a6a Paul Brook
    qemu_irq gpio_in[7][8];
1266 40905a6a Paul Brook
    qemu_irq gpio_out[7][8];
1267 9ee6e8bb pbrook
    qemu_irq adc;
1268 9ee6e8bb pbrook
    int sram_size;
1269 9ee6e8bb pbrook
    int flash_size;
1270 9ee6e8bb pbrook
    i2c_bus *i2c;
1271 40905a6a Paul Brook
    DeviceState *dev;
1272 9ee6e8bb pbrook
    int i;
1273 40905a6a Paul Brook
    int j;
1274 9ee6e8bb pbrook
1275 9ee6e8bb pbrook
    flash_size = ((board->dc0 & 0xffff) + 1) << 1;
1276 9ee6e8bb pbrook
    sram_size = (board->dc0 >> 18) + 1;
1277 9ee6e8bb pbrook
    pic = armv7m_init(flash_size, sram_size, kernel_filename, cpu_model);
1278 9ee6e8bb pbrook
1279 9ee6e8bb pbrook
    if (board->dc1 & (1 << 16)) {
1280 40905a6a Paul Brook
        dev = sysbus_create_varargs("stellaris-adc", 0x40038000,
1281 40905a6a Paul Brook
                                    pic[14], pic[15], pic[16], pic[17], NULL);
1282 40905a6a Paul Brook
        adc = qdev_get_gpio_in(dev, 0);
1283 9ee6e8bb pbrook
    } else {
1284 9ee6e8bb pbrook
        adc = NULL;
1285 9ee6e8bb pbrook
    }
1286 9ee6e8bb pbrook
    for (i = 0; i < 4; i++) {
1287 9ee6e8bb pbrook
        if (board->dc2 & (0x10000 << i)) {
1288 40905a6a Paul Brook
            dev = sysbus_create_simple("stellaris-gptm",
1289 40905a6a Paul Brook
                                       0x40030000 + i * 0x1000,
1290 40905a6a Paul Brook
                                       pic[timer_irq[i]]);
1291 40905a6a Paul Brook
            /* TODO: This is incorrect, but we get away with it because
1292 40905a6a Paul Brook
               the ADC output is only ever pulsed.  */
1293 40905a6a Paul Brook
            qdev_connect_gpio_out(dev, 0, adc);
1294 9ee6e8bb pbrook
        }
1295 9ee6e8bb pbrook
    }
1296 9ee6e8bb pbrook
1297 6eed1856 Jan Kiszka
    stellaris_sys_init(0x400fe000, pic[28], board, nd_table[0].macaddr.a);
1298 9ee6e8bb pbrook
1299 9ee6e8bb pbrook
    for (i = 0; i < 7; i++) {
1300 9ee6e8bb pbrook
        if (board->dc4 & (1 << i)) {
1301 7063f49f Peter Maydell
            gpio_dev[i] = sysbus_create_simple("pl061_luminary", gpio_addr[i],
1302 40905a6a Paul Brook
                                               pic[gpio_irq[i]]);
1303 40905a6a Paul Brook
            for (j = 0; j < 8; j++) {
1304 40905a6a Paul Brook
                gpio_in[i][j] = qdev_get_gpio_in(gpio_dev[i], j);
1305 40905a6a Paul Brook
                gpio_out[i][j] = NULL;
1306 40905a6a Paul Brook
            }
1307 9ee6e8bb pbrook
        }
1308 9ee6e8bb pbrook
    }
1309 9ee6e8bb pbrook
1310 9ee6e8bb pbrook
    if (board->dc2 & (1 << 12)) {
1311 1de9610c Paul Brook
        dev = sysbus_create_simple("stellaris-i2c", 0x40020000, pic[8]);
1312 02e2da45 Paul Brook
        i2c = (i2c_bus *)qdev_get_child_bus(dev, "i2c");
1313 cf0dbb21 pbrook
        if (board->peripherals & BP_OLED_I2C) {
1314 d2199005 Paul Brook
            i2c_create_slave(i2c, "ssd0303", 0x3d);
1315 9ee6e8bb pbrook
        }
1316 9ee6e8bb pbrook
    }
1317 9ee6e8bb pbrook
1318 9ee6e8bb pbrook
    for (i = 0; i < 4; i++) {
1319 9ee6e8bb pbrook
        if (board->dc2 & (1 << i)) {
1320 a7d518a6 Paul Brook
            sysbus_create_simple("pl011_luminary", 0x4000c000 + i * 0x1000,
1321 a7d518a6 Paul Brook
                                 pic[uart_irq[i]]);
1322 9ee6e8bb pbrook
        }
1323 9ee6e8bb pbrook
    }
1324 9ee6e8bb pbrook
    if (board->dc2 & (1 << 4)) {
1325 5493e33f Paul Brook
        dev = sysbus_create_simple("pl022", 0x40008000, pic[7]);
1326 cf0dbb21 pbrook
        if (board->peripherals & BP_OLED_SSI) {
1327 5493e33f Paul Brook
            DeviceState *mux;
1328 5493e33f Paul Brook
            void *bus;
1329 775616c3 pbrook
1330 5493e33f Paul Brook
            bus = qdev_get_child_bus(dev, "ssi");
1331 5493e33f Paul Brook
            mux = ssi_create_slave(bus, "evb6965-ssi");
1332 5493e33f Paul Brook
            gpio_out[GPIO_D][0] = qdev_get_gpio_in(mux, 0);
1333 775616c3 pbrook
1334 5493e33f Paul Brook
            bus = qdev_get_child_bus(mux, "ssi0");
1335 22ed1d34 Blue Swirl
            ssi_create_slave(bus, "ssi-sd");
1336 5493e33f Paul Brook
1337 5493e33f Paul Brook
            bus = qdev_get_child_bus(mux, "ssi1");
1338 5493e33f Paul Brook
            dev = ssi_create_slave(bus, "ssd0323");
1339 5493e33f Paul Brook
            gpio_out[GPIO_C][7] = qdev_get_gpio_in(dev, 0);
1340 775616c3 pbrook
1341 775616c3 pbrook
            /* Make sure the select pin is high.  */
1342 775616c3 pbrook
            qemu_irq_raise(gpio_out[GPIO_D][0]);
1343 9ee6e8bb pbrook
        }
1344 9ee6e8bb pbrook
    }
1345 a5580466 Paul Brook
    if (board->dc4 & (1 << 28)) {
1346 a5580466 Paul Brook
        DeviceState *enet;
1347 a5580466 Paul Brook
1348 a5580466 Paul Brook
        qemu_check_nic_model(&nd_table[0], "stellaris");
1349 a5580466 Paul Brook
1350 a5580466 Paul Brook
        enet = qdev_create(NULL, "stellaris_enet");
1351 540f006a Gerd Hoffmann
        qdev_set_nic_properties(enet, &nd_table[0]);
1352 e23a1b33 Markus Armbruster
        qdev_init_nofail(enet);
1353 a5580466 Paul Brook
        sysbus_mmio_map(sysbus_from_qdev(enet), 0, 0x40048000);
1354 a5580466 Paul Brook
        sysbus_connect_irq(sysbus_from_qdev(enet), 0, pic[42]);
1355 a5580466 Paul Brook
    }
1356 cf0dbb21 pbrook
    if (board->peripherals & BP_GAMEPAD) {
1357 cf0dbb21 pbrook
        qemu_irq gpad_irq[5];
1358 cf0dbb21 pbrook
        static const int gpad_keycode[5] = { 0xc8, 0xd0, 0xcb, 0xcd, 0x1d };
1359 cf0dbb21 pbrook
1360 cf0dbb21 pbrook
        gpad_irq[0] = qemu_irq_invert(gpio_in[GPIO_E][0]); /* up */
1361 cf0dbb21 pbrook
        gpad_irq[1] = qemu_irq_invert(gpio_in[GPIO_E][1]); /* down */
1362 cf0dbb21 pbrook
        gpad_irq[2] = qemu_irq_invert(gpio_in[GPIO_E][2]); /* left */
1363 cf0dbb21 pbrook
        gpad_irq[3] = qemu_irq_invert(gpio_in[GPIO_E][3]); /* right */
1364 cf0dbb21 pbrook
        gpad_irq[4] = qemu_irq_invert(gpio_in[GPIO_F][1]); /* select */
1365 cf0dbb21 pbrook
1366 cf0dbb21 pbrook
        stellaris_gamepad_init(5, gpad_irq, gpad_keycode);
1367 cf0dbb21 pbrook
    }
1368 40905a6a Paul Brook
    for (i = 0; i < 7; i++) {
1369 40905a6a Paul Brook
        if (board->dc4 & (1 << i)) {
1370 40905a6a Paul Brook
            for (j = 0; j < 8; j++) {
1371 40905a6a Paul Brook
                if (gpio_out[i][j]) {
1372 40905a6a Paul Brook
                    qdev_connect_gpio_out(gpio_dev[i], j, gpio_out[i][j]);
1373 40905a6a Paul Brook
                }
1374 40905a6a Paul Brook
            }
1375 40905a6a Paul Brook
        }
1376 40905a6a Paul Brook
    }
1377 9ee6e8bb pbrook
}
1378 9ee6e8bb pbrook
1379 9ee6e8bb pbrook
/* FIXME: Figure out how to generate these from stellaris_boards.  */
1380 c227f099 Anthony Liguori
static void lm3s811evb_init(ram_addr_t ram_size,
1381 3023f332 aliguori
                     const char *boot_device,
1382 9ee6e8bb pbrook
                     const char *kernel_filename, const char *kernel_cmdline,
1383 9ee6e8bb pbrook
                     const char *initrd_filename, const char *cpu_model)
1384 9ee6e8bb pbrook
{
1385 3023f332 aliguori
    stellaris_init(kernel_filename, cpu_model, &stellaris_boards[0]);
1386 9ee6e8bb pbrook
}
1387 9ee6e8bb pbrook
1388 c227f099 Anthony Liguori
static void lm3s6965evb_init(ram_addr_t ram_size,
1389 3023f332 aliguori
                     const char *boot_device,
1390 9ee6e8bb pbrook
                     const char *kernel_filename, const char *kernel_cmdline,
1391 9ee6e8bb pbrook
                     const char *initrd_filename, const char *cpu_model)
1392 9ee6e8bb pbrook
{
1393 3023f332 aliguori
    stellaris_init(kernel_filename, cpu_model, &stellaris_boards[1]);
1394 9ee6e8bb pbrook
}
1395 9ee6e8bb pbrook
1396 f80f9ec9 Anthony Liguori
static QEMUMachine lm3s811evb_machine = {
1397 4b32e168 aliguori
    .name = "lm3s811evb",
1398 4b32e168 aliguori
    .desc = "Stellaris LM3S811EVB",
1399 4b32e168 aliguori
    .init = lm3s811evb_init,
1400 9ee6e8bb pbrook
};
1401 9ee6e8bb pbrook
1402 f80f9ec9 Anthony Liguori
static QEMUMachine lm3s6965evb_machine = {
1403 4b32e168 aliguori
    .name = "lm3s6965evb",
1404 4b32e168 aliguori
    .desc = "Stellaris LM3S6965EVB",
1405 4b32e168 aliguori
    .init = lm3s6965evb_init,
1406 9ee6e8bb pbrook
};
1407 1de9610c Paul Brook
1408 f80f9ec9 Anthony Liguori
static void stellaris_machine_init(void)
1409 f80f9ec9 Anthony Liguori
{
1410 f80f9ec9 Anthony Liguori
    qemu_register_machine(&lm3s811evb_machine);
1411 f80f9ec9 Anthony Liguori
    qemu_register_machine(&lm3s6965evb_machine);
1412 f80f9ec9 Anthony Liguori
}
1413 f80f9ec9 Anthony Liguori
1414 f80f9ec9 Anthony Liguori
machine_init(stellaris_machine_init);
1415 f80f9ec9 Anthony Liguori
1416 5493e33f Paul Brook
static SSISlaveInfo stellaris_ssi_bus_info = {
1417 074f2fff Gerd Hoffmann
    .qdev.name = "evb6965-ssi",
1418 074f2fff Gerd Hoffmann
    .qdev.size = sizeof(stellaris_ssi_bus_state),
1419 5493e33f Paul Brook
    .init = stellaris_ssi_bus_init,
1420 5493e33f Paul Brook
    .transfer = stellaris_ssi_bus_transfer
1421 5493e33f Paul Brook
};
1422 5493e33f Paul Brook
1423 1de9610c Paul Brook
static void stellaris_register_devices(void)
1424 1de9610c Paul Brook
{
1425 1de9610c Paul Brook
    sysbus_register_dev("stellaris-i2c", sizeof(stellaris_i2c_state),
1426 1de9610c Paul Brook
                        stellaris_i2c_init);
1427 40905a6a Paul Brook
    sysbus_register_dev("stellaris-gptm", sizeof(gptm_state),
1428 40905a6a Paul Brook
                        stellaris_gptm_init);
1429 40905a6a Paul Brook
    sysbus_register_dev("stellaris-adc", sizeof(stellaris_adc_state),
1430 40905a6a Paul Brook
                        stellaris_adc_init);
1431 074f2fff Gerd Hoffmann
    ssi_register_slave(&stellaris_ssi_bus_info);
1432 1de9610c Paul Brook
}
1433 1de9610c Paul Brook
1434 1de9610c Paul Brook
device_init(stellaris_register_devices)