Statistics
| Branch: | Revision:

root / hw / ide / mmio.c @ 216db403

History | View | Annotate | Download (5.1 kB)

1 3d2bf4a1 Gerd Hoffmann
/*
2 3d2bf4a1 Gerd Hoffmann
 * QEMU IDE Emulation: mmio support (for embedded).
3 3d2bf4a1 Gerd Hoffmann
 *
4 3d2bf4a1 Gerd Hoffmann
 * Copyright (c) 2003 Fabrice Bellard
5 3d2bf4a1 Gerd Hoffmann
 * Copyright (c) 2006 Openedhand Ltd.
6 3d2bf4a1 Gerd Hoffmann
 *
7 3d2bf4a1 Gerd Hoffmann
 * Permission is hereby granted, free of charge, to any person obtaining a copy
8 3d2bf4a1 Gerd Hoffmann
 * of this software and associated documentation files (the "Software"), to deal
9 3d2bf4a1 Gerd Hoffmann
 * in the Software without restriction, including without limitation the rights
10 3d2bf4a1 Gerd Hoffmann
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 3d2bf4a1 Gerd Hoffmann
 * copies of the Software, and to permit persons to whom the Software is
12 3d2bf4a1 Gerd Hoffmann
 * furnished to do so, subject to the following conditions:
13 3d2bf4a1 Gerd Hoffmann
 *
14 3d2bf4a1 Gerd Hoffmann
 * The above copyright notice and this permission notice shall be included in
15 3d2bf4a1 Gerd Hoffmann
 * all copies or substantial portions of the Software.
16 3d2bf4a1 Gerd Hoffmann
 *
17 3d2bf4a1 Gerd Hoffmann
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 3d2bf4a1 Gerd Hoffmann
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 3d2bf4a1 Gerd Hoffmann
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 3d2bf4a1 Gerd Hoffmann
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 3d2bf4a1 Gerd Hoffmann
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 3d2bf4a1 Gerd Hoffmann
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23 3d2bf4a1 Gerd Hoffmann
 * THE SOFTWARE.
24 3d2bf4a1 Gerd Hoffmann
 */
25 6b2578d6 Andreas Färber
#include "hw/hw.h"
26 6b2578d6 Andreas Färber
#include "hw/sysbus.h"
27 737e150e Paolo Bonzini
#include "block/block.h"
28 9c17d615 Paolo Bonzini
#include "sysemu/dma.h"
29 59f2a787 Gerd Hoffmann
30 59f2a787 Gerd Hoffmann
#include <hw/ide/internal.h>
31 3d2bf4a1 Gerd Hoffmann
32 3d2bf4a1 Gerd Hoffmann
/***********************************************************/
33 3d2bf4a1 Gerd Hoffmann
/* MMIO based ide port
34 3d2bf4a1 Gerd Hoffmann
 * This emulates IDE device connected directly to the CPU bus without
35 3d2bf4a1 Gerd Hoffmann
 * dedicated ide controller, which is often seen on embedded boards.
36 3d2bf4a1 Gerd Hoffmann
 */
37 3d2bf4a1 Gerd Hoffmann
38 6b2578d6 Andreas Färber
#define TYPE_MMIO_IDE "mmio-ide"
39 6b2578d6 Andreas Färber
#define MMIO_IDE(obj) OBJECT_CHECK(MMIOState, (obj), TYPE_MMIO_IDE)
40 6b2578d6 Andreas Färber
41 6b2578d6 Andreas Färber
typedef struct MMIOIDEState {
42 6b2578d6 Andreas Färber
    /*< private >*/
43 6b2578d6 Andreas Färber
    SysBusDevice parent_obj;
44 6b2578d6 Andreas Färber
    /*< public >*/
45 6b2578d6 Andreas Färber
46 0ce51e92 Juan Quintela
    IDEBus bus;
47 6b2578d6 Andreas Färber
48 6b2578d6 Andreas Färber
    uint32_t shift;
49 6b2578d6 Andreas Färber
    qemu_irq irq;
50 9d7f1b9a Avi Kivity
    MemoryRegion iomem1, iomem2;
51 3d2bf4a1 Gerd Hoffmann
} MMIOState;
52 3d2bf4a1 Gerd Hoffmann
53 6b2578d6 Andreas Färber
static void mmio_ide_reset(DeviceState *dev)
54 4a643563 Blue Swirl
{
55 6b2578d6 Andreas Färber
    MMIOState *s = MMIO_IDE(dev);
56 4a643563 Blue Swirl
57 4a643563 Blue Swirl
    ide_bus_reset(&s->bus);
58 4a643563 Blue Swirl
}
59 4a643563 Blue Swirl
60 a8170e5e Avi Kivity
static uint64_t mmio_ide_read(void *opaque, hwaddr addr,
61 9d7f1b9a Avi Kivity
                              unsigned size)
62 3d2bf4a1 Gerd Hoffmann
{
63 18c0fb30 Juan Quintela
    MMIOState *s = opaque;
64 3d2bf4a1 Gerd Hoffmann
    addr >>= s->shift;
65 3d2bf4a1 Gerd Hoffmann
    if (addr & 7)
66 0ce51e92 Juan Quintela
        return ide_ioport_read(&s->bus, addr);
67 3d2bf4a1 Gerd Hoffmann
    else
68 0ce51e92 Juan Quintela
        return ide_data_readw(&s->bus, 0);
69 3d2bf4a1 Gerd Hoffmann
}
70 3d2bf4a1 Gerd Hoffmann
71 a8170e5e Avi Kivity
static void mmio_ide_write(void *opaque, hwaddr addr,
72 9d7f1b9a Avi Kivity
                           uint64_t val, unsigned size)
73 3d2bf4a1 Gerd Hoffmann
{
74 18c0fb30 Juan Quintela
    MMIOState *s = opaque;
75 3d2bf4a1 Gerd Hoffmann
    addr >>= s->shift;
76 3d2bf4a1 Gerd Hoffmann
    if (addr & 7)
77 0ce51e92 Juan Quintela
        ide_ioport_write(&s->bus, addr, val);
78 3d2bf4a1 Gerd Hoffmann
    else
79 0ce51e92 Juan Quintela
        ide_data_writew(&s->bus, 0, val);
80 3d2bf4a1 Gerd Hoffmann
}
81 3d2bf4a1 Gerd Hoffmann
82 9d7f1b9a Avi Kivity
static const MemoryRegionOps mmio_ide_ops = {
83 9d7f1b9a Avi Kivity
    .read = mmio_ide_read,
84 9d7f1b9a Avi Kivity
    .write = mmio_ide_write,
85 9d7f1b9a Avi Kivity
    .endianness = DEVICE_NATIVE_ENDIAN,
86 3d2bf4a1 Gerd Hoffmann
};
87 3d2bf4a1 Gerd Hoffmann
88 a8170e5e Avi Kivity
static uint64_t mmio_ide_status_read(void *opaque, hwaddr addr,
89 9d7f1b9a Avi Kivity
                                     unsigned size)
90 3d2bf4a1 Gerd Hoffmann
{
91 18c0fb30 Juan Quintela
    MMIOState *s= opaque;
92 0ce51e92 Juan Quintela
    return ide_status_read(&s->bus, 0);
93 3d2bf4a1 Gerd Hoffmann
}
94 3d2bf4a1 Gerd Hoffmann
95 a8170e5e Avi Kivity
static void mmio_ide_cmd_write(void *opaque, hwaddr addr,
96 9d7f1b9a Avi Kivity
                               uint64_t val, unsigned size)
97 3d2bf4a1 Gerd Hoffmann
{
98 18c0fb30 Juan Quintela
    MMIOState *s = opaque;
99 0ce51e92 Juan Quintela
    ide_cmd_write(&s->bus, 0, val);
100 3d2bf4a1 Gerd Hoffmann
}
101 3d2bf4a1 Gerd Hoffmann
102 9d7f1b9a Avi Kivity
static const MemoryRegionOps mmio_ide_cs_ops = {
103 9d7f1b9a Avi Kivity
    .read = mmio_ide_status_read,
104 9d7f1b9a Avi Kivity
    .write = mmio_ide_cmd_write,
105 9d7f1b9a Avi Kivity
    .endianness = DEVICE_NATIVE_ENDIAN,
106 3d2bf4a1 Gerd Hoffmann
};
107 3d2bf4a1 Gerd Hoffmann
108 24daf35c Juan Quintela
static const VMStateDescription vmstate_ide_mmio = {
109 24daf35c Juan Quintela
    .name = "mmio-ide",
110 24daf35c Juan Quintela
    .version_id = 3,
111 24daf35c Juan Quintela
    .minimum_version_id = 0,
112 24daf35c Juan Quintela
    .minimum_version_id_old = 0,
113 24daf35c Juan Quintela
    .fields      = (VMStateField []) {
114 24daf35c Juan Quintela
        VMSTATE_IDE_BUS(bus, MMIOState),
115 24daf35c Juan Quintela
        VMSTATE_IDE_DRIVES(bus.ifs, MMIOState),
116 24daf35c Juan Quintela
        VMSTATE_END_OF_LIST()
117 24daf35c Juan Quintela
    }
118 24daf35c Juan Quintela
};
119 2bcbf7e4 Gerd Hoffmann
120 6b2578d6 Andreas Färber
static void mmio_ide_realizefn(DeviceState *dev, Error **errp)
121 3d2bf4a1 Gerd Hoffmann
{
122 6b2578d6 Andreas Färber
    SysBusDevice *d = SYS_BUS_DEVICE(dev);
123 6b2578d6 Andreas Färber
    MMIOState *s = MMIO_IDE(dev);
124 3d2bf4a1 Gerd Hoffmann
125 6b2578d6 Andreas Färber
    ide_init2(&s->bus, s->irq);
126 3d2bf4a1 Gerd Hoffmann
127 1437c94b Paolo Bonzini
    memory_region_init_io(&s->iomem1, OBJECT(s), &mmio_ide_ops, s,
128 6b2578d6 Andreas Färber
                          "ide-mmio.1", 16 << s->shift);
129 1437c94b Paolo Bonzini
    memory_region_init_io(&s->iomem2, OBJECT(s), &mmio_ide_cs_ops, s,
130 6b2578d6 Andreas Färber
                          "ide-mmio.2", 2 << s->shift);
131 6b2578d6 Andreas Färber
    sysbus_init_mmio(d, &s->iomem1);
132 6b2578d6 Andreas Färber
    sysbus_init_mmio(d, &s->iomem2);
133 6b2578d6 Andreas Färber
}
134 6b2578d6 Andreas Färber
135 6b2578d6 Andreas Färber
static void mmio_ide_initfn(Object *obj)
136 6b2578d6 Andreas Färber
{
137 6b2578d6 Andreas Färber
    SysBusDevice *d = SYS_BUS_DEVICE(obj);
138 6b2578d6 Andreas Färber
    MMIOState *s = MMIO_IDE(obj);
139 6b2578d6 Andreas Färber
140 c6baf942 Andreas Färber
    ide_bus_new(&s->bus, sizeof(s->bus), DEVICE(obj), 0, 2);
141 6b2578d6 Andreas Färber
    sysbus_init_irq(d, &s->irq);
142 6b2578d6 Andreas Färber
}
143 6b2578d6 Andreas Färber
144 6b2578d6 Andreas Färber
static Property mmio_ide_properties[] = {
145 6b2578d6 Andreas Färber
    DEFINE_PROP_UINT32("shift", MMIOState, shift, 0),
146 6b2578d6 Andreas Färber
    DEFINE_PROP_END_OF_LIST()
147 6b2578d6 Andreas Färber
};
148 6b2578d6 Andreas Färber
149 6b2578d6 Andreas Färber
static void mmio_ide_class_init(ObjectClass *oc, void *data)
150 6b2578d6 Andreas Färber
{
151 6b2578d6 Andreas Färber
    DeviceClass *dc = DEVICE_CLASS(oc);
152 6b2578d6 Andreas Färber
153 6b2578d6 Andreas Färber
    dc->realize = mmio_ide_realizefn;
154 6b2578d6 Andreas Färber
    dc->reset = mmio_ide_reset;
155 6b2578d6 Andreas Färber
    dc->props = mmio_ide_properties;
156 6b2578d6 Andreas Färber
    dc->vmsd = &vmstate_ide_mmio;
157 6b2578d6 Andreas Färber
}
158 6b2578d6 Andreas Färber
159 6b2578d6 Andreas Färber
static const TypeInfo mmio_ide_type_info = {
160 6b2578d6 Andreas Färber
    .name = TYPE_MMIO_IDE,
161 6b2578d6 Andreas Färber
    .parent = TYPE_SYS_BUS_DEVICE,
162 6b2578d6 Andreas Färber
    .instance_size = sizeof(MMIOState),
163 6b2578d6 Andreas Färber
    .instance_init = mmio_ide_initfn,
164 6b2578d6 Andreas Färber
    .class_init = mmio_ide_class_init,
165 6b2578d6 Andreas Färber
};
166 6b2578d6 Andreas Färber
167 6b2578d6 Andreas Färber
static void mmio_ide_register_types(void)
168 6b2578d6 Andreas Färber
{
169 6b2578d6 Andreas Färber
    type_register_static(&mmio_ide_type_info);
170 6b2578d6 Andreas Färber
}
171 6b2578d6 Andreas Färber
172 6b2578d6 Andreas Färber
void mmio_ide_init_drives(DeviceState *dev, DriveInfo *hd0, DriveInfo *hd1)
173 6b2578d6 Andreas Färber
{
174 6b2578d6 Andreas Färber
    MMIOState *s = MMIO_IDE(dev);
175 6b2578d6 Andreas Färber
176 6b2578d6 Andreas Färber
    if (hd0 != NULL) {
177 6b2578d6 Andreas Färber
        ide_create_drive(&s->bus, 0, hd0);
178 6b2578d6 Andreas Färber
    }
179 6b2578d6 Andreas Färber
    if (hd1 != NULL) {
180 6b2578d6 Andreas Färber
        ide_create_drive(&s->bus, 1, hd1);
181 6b2578d6 Andreas Färber
    }
182 3d2bf4a1 Gerd Hoffmann
}
183 3d2bf4a1 Gerd Hoffmann
184 6b2578d6 Andreas Färber
type_init(mmio_ide_register_types)