~ahs3/+junk/cq-qemu

« back to all changes in this revision

Viewing changes to hw/pxa2xx_pcmcia.c

  • Committer: Al Stone
  • Date: 2012-02-09 01:17:20 UTC
  • Revision ID: albert.stone@canonical.com-20120209011720-tztl7ik3qayz80p4
first commit to bzr for qemu

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Intel XScale PXA255/270 PC Card and CompactFlash Interface.
 
3
 *
 
4
 * Copyright (c) 2006 Openedhand Ltd.
 
5
 * Written by Andrzej Zaborowski <balrog@zabor.org>
 
6
 *
 
7
 * This code is licensed under the GPLv2.
 
8
 */
 
9
 
 
10
#include "hw.h"
 
11
#include "pcmcia.h"
 
12
#include "pxa.h"
 
13
 
 
14
struct PXA2xxPCMCIAState {
 
15
    PCMCIASocket slot;
 
16
    PCMCIACardState *card;
 
17
 
 
18
    qemu_irq irq;
 
19
    qemu_irq cd_irq;
 
20
};
 
21
 
 
22
static uint32_t pxa2xx_pcmcia_common_read(void *opaque,
 
23
                target_phys_addr_t offset)
 
24
{
 
25
    PXA2xxPCMCIAState *s = (PXA2xxPCMCIAState *) opaque;
 
26
 
 
27
    if (s->slot.attached) {
 
28
        return s->card->common_read(s->card->state, offset);
 
29
    }
 
30
 
 
31
    return 0;
 
32
}
 
33
 
 
34
static void pxa2xx_pcmcia_common_write(void *opaque,
 
35
                target_phys_addr_t offset, uint32_t value)
 
36
{
 
37
    PXA2xxPCMCIAState *s = (PXA2xxPCMCIAState *) opaque;
 
38
 
 
39
    if (s->slot.attached) {
 
40
        s->card->common_write(s->card->state, offset, value);
 
41
    }
 
42
}
 
43
 
 
44
static uint32_t pxa2xx_pcmcia_attr_read(void *opaque,
 
45
                target_phys_addr_t offset)
 
46
{
 
47
    PXA2xxPCMCIAState *s = (PXA2xxPCMCIAState *) opaque;
 
48
 
 
49
    if (s->slot.attached) {
 
50
        return s->card->attr_read(s->card->state, offset);
 
51
    }
 
52
 
 
53
    return 0;
 
54
}
 
55
 
 
56
static void pxa2xx_pcmcia_attr_write(void *opaque,
 
57
                target_phys_addr_t offset, uint32_t value)
 
58
{
 
59
    PXA2xxPCMCIAState *s = (PXA2xxPCMCIAState *) opaque;
 
60
 
 
61
    if (s->slot.attached) {
 
62
        s->card->attr_write(s->card->state, offset, value);
 
63
    }
 
64
}
 
65
 
 
66
static uint32_t pxa2xx_pcmcia_io_read(void *opaque,
 
67
                target_phys_addr_t offset)
 
68
{
 
69
    PXA2xxPCMCIAState *s = (PXA2xxPCMCIAState *) opaque;
 
70
 
 
71
    if (s->slot.attached) {
 
72
        return s->card->io_read(s->card->state, offset);
 
73
    }
 
74
 
 
75
    return 0;
 
76
}
 
77
 
 
78
static void pxa2xx_pcmcia_io_write(void *opaque,
 
79
                target_phys_addr_t offset, uint32_t value)
 
80
{
 
81
    PXA2xxPCMCIAState *s = (PXA2xxPCMCIAState *) opaque;
 
82
 
 
83
    if (s->slot.attached) {
 
84
        s->card->io_write(s->card->state, offset, value);
 
85
    }
 
86
}
 
87
 
 
88
static CPUReadMemoryFunc * const pxa2xx_pcmcia_common_readfn[] = {
 
89
    pxa2xx_pcmcia_common_read,
 
90
    pxa2xx_pcmcia_common_read,
 
91
    pxa2xx_pcmcia_common_read,
 
92
};
 
93
 
 
94
static CPUWriteMemoryFunc * const pxa2xx_pcmcia_common_writefn[] = {
 
95
    pxa2xx_pcmcia_common_write,
 
96
    pxa2xx_pcmcia_common_write,
 
97
    pxa2xx_pcmcia_common_write,
 
98
};
 
99
 
 
100
static CPUReadMemoryFunc * const pxa2xx_pcmcia_attr_readfn[] = {
 
101
    pxa2xx_pcmcia_attr_read,
 
102
    pxa2xx_pcmcia_attr_read,
 
103
    pxa2xx_pcmcia_attr_read,
 
104
};
 
105
 
 
106
static CPUWriteMemoryFunc * const pxa2xx_pcmcia_attr_writefn[] = {
 
107
    pxa2xx_pcmcia_attr_write,
 
108
    pxa2xx_pcmcia_attr_write,
 
109
    pxa2xx_pcmcia_attr_write,
 
110
};
 
111
 
 
112
static CPUReadMemoryFunc * const pxa2xx_pcmcia_io_readfn[] = {
 
113
    pxa2xx_pcmcia_io_read,
 
114
    pxa2xx_pcmcia_io_read,
 
115
    pxa2xx_pcmcia_io_read,
 
116
};
 
117
 
 
118
static CPUWriteMemoryFunc * const pxa2xx_pcmcia_io_writefn[] = {
 
119
    pxa2xx_pcmcia_io_write,
 
120
    pxa2xx_pcmcia_io_write,
 
121
    pxa2xx_pcmcia_io_write,
 
122
};
 
123
 
 
124
static void pxa2xx_pcmcia_set_irq(void *opaque, int line, int level)
 
125
{
 
126
    PXA2xxPCMCIAState *s = (PXA2xxPCMCIAState *) opaque;
 
127
    if (!s->irq)
 
128
        return;
 
129
 
 
130
    qemu_set_irq(s->irq, level);
 
131
}
 
132
 
 
133
PXA2xxPCMCIAState *pxa2xx_pcmcia_init(target_phys_addr_t base)
 
134
{
 
135
    int iomemtype;
 
136
    PXA2xxPCMCIAState *s;
 
137
 
 
138
    s = (PXA2xxPCMCIAState *)
 
139
            g_malloc0(sizeof(PXA2xxPCMCIAState));
 
140
 
 
141
    /* Socket I/O Memory Space */
 
142
    iomemtype = cpu_register_io_memory(pxa2xx_pcmcia_io_readfn,
 
143
                    pxa2xx_pcmcia_io_writefn, s, DEVICE_NATIVE_ENDIAN);
 
144
    cpu_register_physical_memory(base | 0x00000000, 0x04000000, iomemtype);
 
145
 
 
146
    /* Then next 64 MB is reserved */
 
147
 
 
148
    /* Socket Attribute Memory Space */
 
149
    iomemtype = cpu_register_io_memory(pxa2xx_pcmcia_attr_readfn,
 
150
                    pxa2xx_pcmcia_attr_writefn, s, DEVICE_NATIVE_ENDIAN);
 
151
    cpu_register_physical_memory(base | 0x08000000, 0x04000000, iomemtype);
 
152
 
 
153
    /* Socket Common Memory Space */
 
154
    iomemtype = cpu_register_io_memory(pxa2xx_pcmcia_common_readfn,
 
155
                    pxa2xx_pcmcia_common_writefn, s, DEVICE_NATIVE_ENDIAN);
 
156
    cpu_register_physical_memory(base | 0x0c000000, 0x04000000, iomemtype);
 
157
 
 
158
    if (base == 0x30000000)
 
159
        s->slot.slot_string = "PXA PC Card Socket 1";
 
160
    else
 
161
        s->slot.slot_string = "PXA PC Card Socket 0";
 
162
    s->slot.irq = qemu_allocate_irqs(pxa2xx_pcmcia_set_irq, s, 1)[0];
 
163
    pcmcia_socket_register(&s->slot);
 
164
 
 
165
    return s;
 
166
}
 
167
 
 
168
/* Insert a new card into a slot */
 
169
int pxa2xx_pcmcia_attach(void *opaque, PCMCIACardState *card)
 
170
{
 
171
    PXA2xxPCMCIAState *s = (PXA2xxPCMCIAState *) opaque;
 
172
    if (s->slot.attached)
 
173
        return -EEXIST;
 
174
 
 
175
    if (s->cd_irq) {
 
176
        qemu_irq_raise(s->cd_irq);
 
177
    }
 
178
 
 
179
    s->card = card;
 
180
 
 
181
    s->slot.attached = 1;
 
182
    s->card->slot = &s->slot;
 
183
    s->card->attach(s->card->state);
 
184
 
 
185
    return 0;
 
186
}
 
187
 
 
188
/* Eject card from the slot */
 
189
int pxa2xx_pcmcia_dettach(void *opaque)
 
190
{
 
191
    PXA2xxPCMCIAState *s = (PXA2xxPCMCIAState *) opaque;
 
192
    if (!s->slot.attached)
 
193
        return -ENOENT;
 
194
 
 
195
    s->card->detach(s->card->state);
 
196
    s->card->slot = NULL;
 
197
    s->card = NULL;
 
198
 
 
199
    s->slot.attached = 0;
 
200
 
 
201
    if (s->irq)
 
202
        qemu_irq_lower(s->irq);
 
203
    if (s->cd_irq)
 
204
        qemu_irq_lower(s->cd_irq);
 
205
 
 
206
    return 0;
 
207
}
 
208
 
 
209
/* Who to notify on card events */
 
210
void pxa2xx_pcmcia_set_irq_cb(void *opaque, qemu_irq irq, qemu_irq cd_irq)
 
211
{
 
212
    PXA2xxPCMCIAState *s = (PXA2xxPCMCIAState *) opaque;
 
213
    s->irq = irq;
 
214
    s->cd_irq = cd_irq;
 
215
}