Statistics
| Branch: | Revision:

root / hw / puv3_gpio.c @ 9a3a8895

History | View | Annotate | Download (3.4 kB)

1 a89d01c1 Guan Xuetao
/*
2 a89d01c1 Guan Xuetao
 * GPIO device simulation in PKUnity SoC
3 a89d01c1 Guan Xuetao
 *
4 a89d01c1 Guan Xuetao
 * Copyright (C) 2010-2012 Guan Xuetao
5 a89d01c1 Guan Xuetao
 *
6 a89d01c1 Guan Xuetao
 * This program is free software; you can redistribute it and/or modify
7 a89d01c1 Guan Xuetao
 * it under the terms of the GNU General Public License version 2 as
8 a89d01c1 Guan Xuetao
 * published by the Free Software Foundation, or any later version.
9 a89d01c1 Guan Xuetao
 * See the COPYING file in the top-level directory.
10 a89d01c1 Guan Xuetao
 */
11 a89d01c1 Guan Xuetao
#include "hw.h"
12 a89d01c1 Guan Xuetao
#include "sysbus.h"
13 a89d01c1 Guan Xuetao
14 a89d01c1 Guan Xuetao
#undef DEBUG_PUV3
15 a89d01c1 Guan Xuetao
#include "puv3.h"
16 a89d01c1 Guan Xuetao
17 a89d01c1 Guan Xuetao
typedef struct {
18 a89d01c1 Guan Xuetao
    SysBusDevice busdev;
19 a89d01c1 Guan Xuetao
    MemoryRegion iomem;
20 a89d01c1 Guan Xuetao
    qemu_irq irq[9];
21 a89d01c1 Guan Xuetao
22 a89d01c1 Guan Xuetao
    uint32_t reg_GPLR;
23 a89d01c1 Guan Xuetao
    uint32_t reg_GPDR;
24 a89d01c1 Guan Xuetao
    uint32_t reg_GPIR;
25 a89d01c1 Guan Xuetao
} PUV3GPIOState;
26 a89d01c1 Guan Xuetao
27 a89d01c1 Guan Xuetao
static uint64_t puv3_gpio_read(void *opaque, target_phys_addr_t offset,
28 a89d01c1 Guan Xuetao
        unsigned size)
29 a89d01c1 Guan Xuetao
{
30 a89d01c1 Guan Xuetao
    PUV3GPIOState *s = opaque;
31 a89d01c1 Guan Xuetao
    uint32_t ret = 0;
32 a89d01c1 Guan Xuetao
33 a89d01c1 Guan Xuetao
    switch (offset) {
34 a89d01c1 Guan Xuetao
    case 0x00:
35 a89d01c1 Guan Xuetao
        ret = s->reg_GPLR;
36 a89d01c1 Guan Xuetao
        break;
37 a89d01c1 Guan Xuetao
    case 0x04:
38 a89d01c1 Guan Xuetao
        ret = s->reg_GPDR;
39 a89d01c1 Guan Xuetao
        break;
40 a89d01c1 Guan Xuetao
    case 0x20:
41 a89d01c1 Guan Xuetao
        ret = s->reg_GPIR;
42 a89d01c1 Guan Xuetao
        break;
43 a89d01c1 Guan Xuetao
    default:
44 a89d01c1 Guan Xuetao
        DPRINTF("Bad offset 0x%x\n", offset);
45 a89d01c1 Guan Xuetao
    }
46 a89d01c1 Guan Xuetao
    DPRINTF("offset 0x%x, value 0x%x\n", offset, ret);
47 a89d01c1 Guan Xuetao
48 a89d01c1 Guan Xuetao
    return ret;
49 a89d01c1 Guan Xuetao
}
50 a89d01c1 Guan Xuetao
51 a89d01c1 Guan Xuetao
static void puv3_gpio_write(void *opaque, target_phys_addr_t offset,
52 a89d01c1 Guan Xuetao
        uint64_t value, unsigned size)
53 a89d01c1 Guan Xuetao
{
54 a89d01c1 Guan Xuetao
    PUV3GPIOState *s = opaque;
55 a89d01c1 Guan Xuetao
56 a89d01c1 Guan Xuetao
    DPRINTF("offset 0x%x, value 0x%x\n", offset, value);
57 a89d01c1 Guan Xuetao
    switch (offset) {
58 a89d01c1 Guan Xuetao
    case 0x04:
59 a89d01c1 Guan Xuetao
        s->reg_GPDR = value;
60 a89d01c1 Guan Xuetao
        break;
61 a89d01c1 Guan Xuetao
    case 0x08:
62 a89d01c1 Guan Xuetao
        if (s->reg_GPDR & value) {
63 a89d01c1 Guan Xuetao
            s->reg_GPLR |= value;
64 a89d01c1 Guan Xuetao
        } else {
65 a89d01c1 Guan Xuetao
            DPRINTF("Write gpio input port error!");
66 a89d01c1 Guan Xuetao
        }
67 a89d01c1 Guan Xuetao
        break;
68 a89d01c1 Guan Xuetao
    case 0x0c:
69 a89d01c1 Guan Xuetao
        if (s->reg_GPDR & value) {
70 a89d01c1 Guan Xuetao
            s->reg_GPLR &= ~value;
71 a89d01c1 Guan Xuetao
        } else {
72 a89d01c1 Guan Xuetao
            DPRINTF("Write gpio input port error!");
73 a89d01c1 Guan Xuetao
        }
74 a89d01c1 Guan Xuetao
        break;
75 a89d01c1 Guan Xuetao
    case 0x10: /* GRER */
76 a89d01c1 Guan Xuetao
    case 0x14: /* GFER */
77 a89d01c1 Guan Xuetao
    case 0x18: /* GEDR */
78 a89d01c1 Guan Xuetao
        break;
79 a89d01c1 Guan Xuetao
    case 0x20: /* GPIR */
80 a89d01c1 Guan Xuetao
        s->reg_GPIR = value;
81 a89d01c1 Guan Xuetao
        break;
82 a89d01c1 Guan Xuetao
    default:
83 a89d01c1 Guan Xuetao
        DPRINTF("Bad offset 0x%x\n", offset);
84 a89d01c1 Guan Xuetao
    }
85 a89d01c1 Guan Xuetao
}
86 a89d01c1 Guan Xuetao
87 a89d01c1 Guan Xuetao
static const MemoryRegionOps puv3_gpio_ops = {
88 a89d01c1 Guan Xuetao
    .read = puv3_gpio_read,
89 a89d01c1 Guan Xuetao
    .write = puv3_gpio_write,
90 a89d01c1 Guan Xuetao
    .impl = {
91 a89d01c1 Guan Xuetao
        .min_access_size = 4,
92 a89d01c1 Guan Xuetao
        .max_access_size = 4,
93 a89d01c1 Guan Xuetao
    },
94 a89d01c1 Guan Xuetao
    .endianness = DEVICE_NATIVE_ENDIAN,
95 a89d01c1 Guan Xuetao
};
96 a89d01c1 Guan Xuetao
97 a89d01c1 Guan Xuetao
static int puv3_gpio_init(SysBusDevice *dev)
98 a89d01c1 Guan Xuetao
{
99 a89d01c1 Guan Xuetao
    PUV3GPIOState *s = FROM_SYSBUS(PUV3GPIOState, dev);
100 a89d01c1 Guan Xuetao
101 a89d01c1 Guan Xuetao
    s->reg_GPLR = 0;
102 a89d01c1 Guan Xuetao
    s->reg_GPDR = 0;
103 a89d01c1 Guan Xuetao
104 a89d01c1 Guan Xuetao
    /* FIXME: these irqs not handled yet */
105 a89d01c1 Guan Xuetao
    sysbus_init_irq(dev, &s->irq[PUV3_IRQS_GPIOLOW0]);
106 a89d01c1 Guan Xuetao
    sysbus_init_irq(dev, &s->irq[PUV3_IRQS_GPIOLOW1]);
107 a89d01c1 Guan Xuetao
    sysbus_init_irq(dev, &s->irq[PUV3_IRQS_GPIOLOW2]);
108 a89d01c1 Guan Xuetao
    sysbus_init_irq(dev, &s->irq[PUV3_IRQS_GPIOLOW3]);
109 a89d01c1 Guan Xuetao
    sysbus_init_irq(dev, &s->irq[PUV3_IRQS_GPIOLOW4]);
110 a89d01c1 Guan Xuetao
    sysbus_init_irq(dev, &s->irq[PUV3_IRQS_GPIOLOW5]);
111 a89d01c1 Guan Xuetao
    sysbus_init_irq(dev, &s->irq[PUV3_IRQS_GPIOLOW6]);
112 a89d01c1 Guan Xuetao
    sysbus_init_irq(dev, &s->irq[PUV3_IRQS_GPIOLOW7]);
113 a89d01c1 Guan Xuetao
    sysbus_init_irq(dev, &s->irq[PUV3_IRQS_GPIOHIGH]);
114 a89d01c1 Guan Xuetao
115 a89d01c1 Guan Xuetao
    memory_region_init_io(&s->iomem, &puv3_gpio_ops, s, "puv3_gpio",
116 a89d01c1 Guan Xuetao
            PUV3_REGS_OFFSET);
117 a89d01c1 Guan Xuetao
    sysbus_init_mmio(dev, &s->iomem);
118 a89d01c1 Guan Xuetao
119 a89d01c1 Guan Xuetao
    return 0;
120 a89d01c1 Guan Xuetao
}
121 a89d01c1 Guan Xuetao
122 a89d01c1 Guan Xuetao
static void puv3_gpio_class_init(ObjectClass *klass, void *data)
123 a89d01c1 Guan Xuetao
{
124 a89d01c1 Guan Xuetao
    SysBusDeviceClass *sdc = SYS_BUS_DEVICE_CLASS(klass);
125 a89d01c1 Guan Xuetao
126 a89d01c1 Guan Xuetao
    sdc->init = puv3_gpio_init;
127 a89d01c1 Guan Xuetao
}
128 a89d01c1 Guan Xuetao
129 a89d01c1 Guan Xuetao
static const TypeInfo puv3_gpio_info = {
130 a89d01c1 Guan Xuetao
    .name = "puv3_gpio",
131 a89d01c1 Guan Xuetao
    .parent = TYPE_SYS_BUS_DEVICE,
132 a89d01c1 Guan Xuetao
    .instance_size = sizeof(PUV3GPIOState),
133 a89d01c1 Guan Xuetao
    .class_init = puv3_gpio_class_init,
134 a89d01c1 Guan Xuetao
};
135 a89d01c1 Guan Xuetao
136 a89d01c1 Guan Xuetao
static void puv3_gpio_register_type(void)
137 a89d01c1 Guan Xuetao
{
138 a89d01c1 Guan Xuetao
    type_register_static(&puv3_gpio_info);
139 a89d01c1 Guan Xuetao
}
140 a89d01c1 Guan Xuetao
141 a89d01c1 Guan Xuetao
type_init(puv3_gpio_register_type)