Merge branch 'master' of ssh://repo.or.cz/srv/git/qemu
[qemu/hppa.git] / hw / zaurus.c
blob7cf47b9c969d6e01604ec06379d05476278531aa
1 /*
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, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 #include "hw.h"
20 #include "pxa.h"
21 #include "sharpsl.h"
23 #undef REG_FMT
24 #define REG_FMT "0x%02lx"
26 /* SCOOP devices */
28 struct ScoopInfo {
29 qemu_irq handler[16];
30 qemu_irq *in;
31 uint16_t status;
32 uint16_t power;
33 uint32_t gpio_level;
34 uint32_t gpio_dir;
35 uint32_t prev_level;
37 uint16_t mcr;
38 uint16_t cdr;
39 uint16_t ccr;
40 uint16_t irr;
41 uint16_t imr;
42 uint16_t isr;
45 #define SCOOP_MCR 0x00
46 #define SCOOP_CDR 0x04
47 #define SCOOP_CSR 0x08
48 #define SCOOP_CPR 0x0c
49 #define SCOOP_CCR 0x10
50 #define SCOOP_IRR_IRM 0x14
51 #define SCOOP_IMR 0x18
52 #define SCOOP_ISR 0x1c
53 #define SCOOP_GPCR 0x20
54 #define SCOOP_GPWR 0x24
55 #define SCOOP_GPRR 0x28
57 static inline void scoop_gpio_handler_update(ScoopInfo *s) {
58 uint32_t level, diff;
59 int bit;
60 level = s->gpio_level & s->gpio_dir;
62 for (diff = s->prev_level ^ level; diff; diff ^= 1 << bit) {
63 bit = ffs(diff) - 1;
64 qemu_set_irq(s->handler[bit], (level >> bit) & 1);
67 s->prev_level = level;
70 static uint32_t scoop_readb(void *opaque, target_phys_addr_t addr)
72 ScoopInfo *s = (ScoopInfo *) opaque;
74 switch (addr) {
75 case SCOOP_MCR:
76 return s->mcr;
77 case SCOOP_CDR:
78 return s->cdr;
79 case SCOOP_CSR:
80 return s->status;
81 case SCOOP_CPR:
82 return s->power;
83 case SCOOP_CCR:
84 return s->ccr;
85 case SCOOP_IRR_IRM:
86 return s->irr;
87 case SCOOP_IMR:
88 return s->imr;
89 case SCOOP_ISR:
90 return s->isr;
91 case SCOOP_GPCR:
92 return s->gpio_dir;
93 case SCOOP_GPWR:
94 case SCOOP_GPRR:
95 return s->gpio_level;
96 default:
97 zaurus_printf("Bad register offset " REG_FMT "\n", (unsigned long)addr);
100 return 0;
103 static void scoop_writeb(void *opaque, target_phys_addr_t addr, uint32_t value)
105 ScoopInfo *s = (ScoopInfo *) opaque;
106 value &= 0xffff;
108 switch (addr) {
109 case SCOOP_MCR:
110 s->mcr = value;
111 break;
112 case SCOOP_CDR:
113 s->cdr = value;
114 break;
115 case SCOOP_CPR:
116 s->power = value;
117 if (value & 0x80)
118 s->power |= 0x8040;
119 break;
120 case SCOOP_CCR:
121 s->ccr = value;
122 break;
123 case SCOOP_IRR_IRM:
124 s->irr = value;
125 break;
126 case SCOOP_IMR:
127 s->imr = value;
128 break;
129 case SCOOP_ISR:
130 s->isr = value;
131 break;
132 case SCOOP_GPCR:
133 s->gpio_dir = value;
134 scoop_gpio_handler_update(s);
135 break;
136 case SCOOP_GPWR:
137 case SCOOP_GPRR: /* GPRR is probably R/O in real HW */
138 s->gpio_level = value & s->gpio_dir;
139 scoop_gpio_handler_update(s);
140 break;
141 default:
142 zaurus_printf("Bad register offset " REG_FMT "\n", (unsigned long)addr);
146 static CPUReadMemoryFunc *scoop_readfn[] = {
147 scoop_readb,
148 scoop_readb,
149 scoop_readb,
151 static CPUWriteMemoryFunc *scoop_writefn[] = {
152 scoop_writeb,
153 scoop_writeb,
154 scoop_writeb,
157 void scoop_gpio_set(void *opaque, int line, int level)
159 ScoopInfo *s = (ScoopInfo *) s;
161 if (level)
162 s->gpio_level |= (1 << line);
163 else
164 s->gpio_level &= ~(1 << line);
167 qemu_irq *scoop_gpio_in_get(ScoopInfo *s)
169 return s->in;
172 void scoop_gpio_out_set(ScoopInfo *s, int line,
173 qemu_irq handler) {
174 if (line >= 16) {
175 fprintf(stderr, "No GPIO pin %i\n", line);
176 exit(-1);
179 s->handler[line] = handler;
182 static void scoop_save(QEMUFile *f, void *opaque)
184 ScoopInfo *s = (ScoopInfo *) opaque;
185 qemu_put_be16s(f, &s->status);
186 qemu_put_be16s(f, &s->power);
187 qemu_put_be32s(f, &s->gpio_level);
188 qemu_put_be32s(f, &s->gpio_dir);
189 qemu_put_be32s(f, &s->prev_level);
190 qemu_put_be16s(f, &s->mcr);
191 qemu_put_be16s(f, &s->cdr);
192 qemu_put_be16s(f, &s->ccr);
193 qemu_put_be16s(f, &s->irr);
194 qemu_put_be16s(f, &s->imr);
195 qemu_put_be16s(f, &s->isr);
198 static int scoop_load(QEMUFile *f, void *opaque, int version_id)
200 uint16_t dummy;
201 ScoopInfo *s = (ScoopInfo *) opaque;
202 qemu_get_be16s(f, &s->status);
203 qemu_get_be16s(f, &s->power);
204 qemu_get_be32s(f, &s->gpio_level);
205 qemu_get_be32s(f, &s->gpio_dir);
206 qemu_get_be32s(f, &s->prev_level);
207 qemu_get_be16s(f, &s->mcr);
208 qemu_get_be16s(f, &s->cdr);
209 qemu_get_be16s(f, &s->ccr);
210 qemu_get_be16s(f, &s->irr);
211 qemu_get_be16s(f, &s->imr);
212 qemu_get_be16s(f, &s->isr);
213 if (version_id < 1)
214 qemu_get_be16s(f, &dummy);
216 return 0;
219 ScoopInfo *scoop_init(PXA2xxState *cpu,
220 int instance,
221 target_phys_addr_t target_base) {
222 int iomemtype;
223 ScoopInfo *s;
225 s = (ScoopInfo *)
226 qemu_mallocz(sizeof(ScoopInfo));
227 memset(s, 0, sizeof(ScoopInfo));
229 s->status = 0x02;
230 s->in = qemu_allocate_irqs(scoop_gpio_set, s, 16);
231 iomemtype = cpu_register_io_memory(0, scoop_readfn,
232 scoop_writefn, s);
233 cpu_register_physical_memory(target_base, 0x1000, iomemtype);
234 register_savevm("scoop", instance, 1, scoop_save, scoop_load, s);
236 return s;
239 /* Write the bootloader parameters memory area. */
241 #define MAGIC_CHG(a, b, c, d) ((d << 24) | (c << 16) | (b << 8) | a)
243 static struct __attribute__ ((__packed__)) sl_param_info {
244 uint32_t comadj_keyword;
245 int32_t comadj;
247 uint32_t uuid_keyword;
248 char uuid[16];
250 uint32_t touch_keyword;
251 int32_t touch_xp;
252 int32_t touch_yp;
253 int32_t touch_xd;
254 int32_t touch_yd;
256 uint32_t adadj_keyword;
257 int32_t adadj;
259 uint32_t phad_keyword;
260 int32_t phadadj;
261 } zaurus_bootparam = {
262 .comadj_keyword = MAGIC_CHG('C', 'M', 'A', 'D'),
263 .comadj = 125,
264 .uuid_keyword = MAGIC_CHG('U', 'U', 'I', 'D'),
265 .uuid = { -1 },
266 .touch_keyword = MAGIC_CHG('T', 'U', 'C', 'H'),
267 .touch_xp = -1,
268 .adadj_keyword = MAGIC_CHG('B', 'V', 'A', 'D'),
269 .adadj = -1,
270 .phad_keyword = MAGIC_CHG('P', 'H', 'A', 'D'),
271 .phadadj = 0x01,
274 void sl_bootparam_write(target_phys_addr_t ptr)
276 cpu_physical_memory_write(ptr, (void *)&zaurus_bootparam,
277 sizeof(struct sl_param_info));