2
* Copyright (c) 2006-2008 Openedhand Ltd.
3
* Written by Andrzej Zaborowski <balrog@zabor.org>
5
* This program is free software; you can redistribute it and/or
6
* modify it under the terms of the GNU General Public License as
7
* published by the Free Software Foundation; either version 2 or
8
* (at your option) version 3 of the License.
10
* This program is distributed in the hope that it will be useful,
11
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
* GNU General Public License for more details.
15
* You should have received a copy of the GNU General Public License along
16
* with this program; if not, see <http://www.gnu.org/licenses/>.
19
#include "qemu/osdep.h"
21
#include "hw/arm/sharpsl.h"
23
#include "migration/vmstate.h"
24
#include "qemu/module.h"
26
#include "qom/object.h"
30
#define TYPE_SCOOP "scoop"
31
OBJECT_DECLARE_SIMPLE_TYPE(ScoopInfo, SCOOP)
34
SysBusDevice parent_obj;
57
#define SCOOP_IRR_IRM 0x14
60
#define SCOOP_GPCR 0x20
61
#define SCOOP_GPWR 0x24
62
#define SCOOP_GPRR 0x28
64
static inline void scoop_gpio_handler_update(ScoopInfo *s)
68
level = s->gpio_level & s->gpio_dir;
70
for (diff = s->prev_level ^ level; diff; diff ^= 1 << bit) {
72
qemu_set_irq(s->handler[bit], (level >> bit) & 1);
75
s->prev_level = level;
78
static uint64_t scoop_read(void *opaque, hwaddr addr,
81
ScoopInfo *s = (ScoopInfo *) opaque;
83
switch (addr & 0x3f) {
104
return s->gpio_level;
106
qemu_log_mask(LOG_GUEST_ERROR,
107
"scoop_read: bad register offset 0x%02" HWADDR_PRIx "\n",
114
static void scoop_write(void *opaque, hwaddr addr,
115
uint64_t value, unsigned size)
117
ScoopInfo *s = (ScoopInfo *) opaque;
120
switch (addr & 0x3f) {
147
scoop_gpio_handler_update(s);
150
case SCOOP_GPRR: /* GPRR is probably R/O in real HW */
151
s->gpio_level = value & s->gpio_dir;
152
scoop_gpio_handler_update(s);
155
qemu_log_mask(LOG_GUEST_ERROR,
156
"scoop_write: bad register offset 0x%02" HWADDR_PRIx "\n",
161
static const MemoryRegionOps scoop_ops = {
163
.write = scoop_write,
164
.endianness = DEVICE_NATIVE_ENDIAN,
167
static void scoop_gpio_set(void *opaque, int line, int level)
169
ScoopInfo *s = (ScoopInfo *) opaque;
172
s->gpio_level |= (1 << line);
174
s->gpio_level &= ~(1 << line);
178
static void scoop_init(Object *obj)
180
DeviceState *dev = DEVICE(obj);
181
ScoopInfo *s = SCOOP(obj);
182
SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
185
qdev_init_gpio_out(dev, s->handler, 16);
186
qdev_init_gpio_in(dev, scoop_gpio_set, 16);
187
memory_region_init_io(&s->iomem, obj, &scoop_ops, s, "scoop", 0x1000);
189
sysbus_init_mmio(sbd, &s->iomem);
192
static int scoop_post_load(void *opaque, int version_id)
194
ScoopInfo *s = (ScoopInfo *) opaque;
198
level = s->gpio_level & s->gpio_dir;
200
for (i = 0; i < 16; i++) {
201
qemu_set_irq(s->handler[i], (level >> i) & 1);
204
s->prev_level = level;
209
static bool is_version_0(void *opaque, int version_id)
211
return version_id == 0;
214
static bool vmstate_scoop_validate(void *opaque, int version_id)
216
ScoopInfo *s = opaque;
218
return !(s->prev_level & 0xffff0000) &&
219
!(s->gpio_level & 0xffff0000) &&
220
!(s->gpio_dir & 0xffff0000);
223
static const VMStateDescription vmstate_scoop_regs = {
226
.minimum_version_id = 0,
227
.post_load = scoop_post_load,
228
.fields = (const VMStateField[]) {
229
VMSTATE_UINT16(status, ScoopInfo),
230
VMSTATE_UINT16(power, ScoopInfo),
231
VMSTATE_UINT32(gpio_level, ScoopInfo),
232
VMSTATE_UINT32(gpio_dir, ScoopInfo),
233
VMSTATE_UINT32(prev_level, ScoopInfo),
234
VMSTATE_VALIDATE("irq levels are 16 bit", vmstate_scoop_validate),
235
VMSTATE_UINT16(mcr, ScoopInfo),
236
VMSTATE_UINT16(cdr, ScoopInfo),
237
VMSTATE_UINT16(ccr, ScoopInfo),
238
VMSTATE_UINT16(irr, ScoopInfo),
239
VMSTATE_UINT16(imr, ScoopInfo),
240
VMSTATE_UINT16(isr, ScoopInfo),
241
VMSTATE_UNUSED_TEST(is_version_0, 2),
242
VMSTATE_END_OF_LIST(),
246
static void scoop_sysbus_class_init(ObjectClass *klass, void *data)
248
DeviceClass *dc = DEVICE_CLASS(klass);
250
dc->desc = "Scoop2 Sharp custom ASIC";
251
dc->vmsd = &vmstate_scoop_regs;
254
static const TypeInfo scoop_sysbus_info = {
256
.parent = TYPE_SYS_BUS_DEVICE,
257
.instance_size = sizeof(ScoopInfo),
258
.instance_init = scoop_init,
259
.class_init = scoop_sysbus_class_init,
262
static void scoop_register_types(void)
264
type_register_static(&scoop_sysbus_info);
267
type_init(scoop_register_types)
269
/* Write the bootloader parameters memory area. */
271
#define MAGIC_CHG(a, b, c, d) ((d << 24) | (c << 16) | (b << 8) | a)
273
static struct QEMU_PACKED sl_param_info {
274
uint32_t comadj_keyword;
277
uint32_t uuid_keyword;
280
uint32_t touch_keyword;
286
uint32_t adadj_keyword;
289
uint32_t phad_keyword;
291
} zaurus_bootparam = {
292
.comadj_keyword = MAGIC_CHG('C', 'M', 'A', 'D'),
294
.uuid_keyword = MAGIC_CHG('U', 'U', 'I', 'D'),
296
.touch_keyword = MAGIC_CHG('T', 'U', 'C', 'H'),
298
.adadj_keyword = MAGIC_CHG('B', 'V', 'A', 'D'),
300
.phad_keyword = MAGIC_CHG('P', 'H', 'A', 'D'),
304
void sl_bootparam_write(hwaddr ptr)
306
cpu_physical_memory_write(ptr, &zaurus_bootparam,
307
sizeof(struct sl_param_info));