Statistics
| Branch: | Revision:

root / hw / ide / mmio.c @ 69c38b8f

History | View | Annotate | Download (4.1 kB)

1
/*
2
 * QEMU IDE Emulation: mmio support (for embedded).
3
 *
4
 * Copyright (c) 2003 Fabrice Bellard
5
 * Copyright (c) 2006 Openedhand Ltd.
6
 *
7
 * Permission is hereby granted, free of charge, to any person obtaining a copy
8
 * of this software and associated documentation files (the "Software"), to deal
9
 * in the Software without restriction, including without limitation the rights
10
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11
 * copies of the Software, and to permit persons to whom the Software is
12
 * furnished to do so, subject to the following conditions:
13
 *
14
 * The above copyright notice and this permission notice shall be included in
15
 * all copies or substantial portions of the Software.
16
 *
17
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23
 * THE SOFTWARE.
24
 */
25
#include <hw/hw.h>
26
#include "block.h"
27
#include "block_int.h"
28
#include "dma.h"
29

    
30
#include <hw/ide/internal.h>
31

    
32
/***********************************************************/
33
/* MMIO based ide port
34
 * This emulates IDE device connected directly to the CPU bus without
35
 * dedicated ide controller, which is often seen on embedded boards.
36
 */
37

    
38
typedef struct {
39
    IDEBus bus;
40
    int shift;
41
} MMIOState;
42

    
43
static void mmio_ide_reset(void *opaque)
44
{
45
    MMIOState *s = opaque;
46

    
47
    ide_bus_reset(&s->bus);
48
}
49

    
50
static uint32_t mmio_ide_read (void *opaque, target_phys_addr_t addr)
51
{
52
    MMIOState *s = opaque;
53
    addr >>= s->shift;
54
    if (addr & 7)
55
        return ide_ioport_read(&s->bus, addr);
56
    else
57
        return ide_data_readw(&s->bus, 0);
58
}
59

    
60
static void mmio_ide_write (void *opaque, target_phys_addr_t addr,
61
        uint32_t val)
62
{
63
    MMIOState *s = opaque;
64
    addr >>= s->shift;
65
    if (addr & 7)
66
        ide_ioport_write(&s->bus, addr, val);
67
    else
68
        ide_data_writew(&s->bus, 0, val);
69
}
70

    
71
static CPUReadMemoryFunc * const mmio_ide_reads[] = {
72
    mmio_ide_read,
73
    mmio_ide_read,
74
    mmio_ide_read,
75
};
76

    
77
static CPUWriteMemoryFunc * const mmio_ide_writes[] = {
78
    mmio_ide_write,
79
    mmio_ide_write,
80
    mmio_ide_write,
81
};
82

    
83
static uint32_t mmio_ide_status_read (void *opaque, target_phys_addr_t addr)
84
{
85
    MMIOState *s= opaque;
86
    return ide_status_read(&s->bus, 0);
87
}
88

    
89
static void mmio_ide_cmd_write (void *opaque, target_phys_addr_t addr,
90
        uint32_t val)
91
{
92
    MMIOState *s = opaque;
93
    ide_cmd_write(&s->bus, 0, val);
94
}
95

    
96
static CPUReadMemoryFunc * const mmio_ide_status[] = {
97
    mmio_ide_status_read,
98
    mmio_ide_status_read,
99
    mmio_ide_status_read,
100
};
101

    
102
static CPUWriteMemoryFunc * const mmio_ide_cmd[] = {
103
    mmio_ide_cmd_write,
104
    mmio_ide_cmd_write,
105
    mmio_ide_cmd_write,
106
};
107

    
108
static const VMStateDescription vmstate_ide_mmio = {
109
    .name = "mmio-ide",
110
    .version_id = 3,
111
    .minimum_version_id = 0,
112
    .minimum_version_id_old = 0,
113
    .fields      = (VMStateField []) {
114
        VMSTATE_IDE_BUS(bus, MMIOState),
115
        VMSTATE_IDE_DRIVES(bus.ifs, MMIOState),
116
        VMSTATE_END_OF_LIST()
117
    }
118
};
119

    
120
void mmio_ide_init (target_phys_addr_t membase, target_phys_addr_t membase2,
121
                    qemu_irq irq, int shift,
122
                    DriveInfo *hd0, DriveInfo *hd1)
123
{
124
    MMIOState *s = qemu_mallocz(sizeof(MMIOState));
125
    int mem1, mem2;
126

    
127
    ide_init2_with_non_qdev_drives(&s->bus, hd0, hd1, irq);
128

    
129
    s->shift = shift;
130

    
131
    mem1 = cpu_register_io_memory(mmio_ide_reads, mmio_ide_writes, s,
132
                                  DEVICE_NATIVE_ENDIAN);
133
    mem2 = cpu_register_io_memory(mmio_ide_status, mmio_ide_cmd, s,
134
                                  DEVICE_NATIVE_ENDIAN);
135
    cpu_register_physical_memory(membase, 16 << shift, mem1);
136
    cpu_register_physical_memory(membase2, 2 << shift, mem2);
137
    vmstate_register(NULL, 0, &vmstate_ide_mmio, s);
138
    qemu_register_reset(mmio_ide_reset, s);
139
}
140