Revision a7d518a6
b/hw/integratorcp.c | ||
---|---|---|
482 | 482 |
icp_pic_init(0xca000000, pic[26], NULL); |
483 | 483 |
icp_pit_init(0x13000000, pic, 5); |
484 | 484 |
pl031_init(0x15000000, pic[8]); |
485 |
pl011_init(0x16000000, pic[1], serial_hds[0], PL011_ARM);
|
|
486 |
pl011_init(0x17000000, pic[2], serial_hds[1], PL011_ARM);
|
|
485 |
sysbus_create_simple("pl011", 0x16000000, pic[1]);
|
|
486 |
sysbus_create_simple("pl011", 0x17000000, pic[2]);
|
|
487 | 487 |
icp_control_init(0xcb000000); |
488 | 488 |
pl050_init(0x18000000, pic[3], 0); |
489 | 489 |
pl050_init(0x19000000, pic[4], 1); |
b/hw/pl011.c | ||
---|---|---|
7 | 7 |
* This code is licenced under the GPL. |
8 | 8 |
*/ |
9 | 9 |
|
10 |
#include "hw.h"
|
|
10 |
#include "sysbus.h"
|
|
11 | 11 |
#include "qemu-char.h" |
12 |
#include "primecell.h" |
|
13 | 12 |
|
14 | 13 |
typedef struct { |
14 |
SysBusDevice busdev; |
|
15 | 15 |
uint32_t readbuff; |
16 | 16 |
uint32_t flags; |
17 | 17 |
uint32_t lcr; |
... | ... | |
29 | 29 |
int read_trigger; |
30 | 30 |
CharDriverState *chr; |
31 | 31 |
qemu_irq irq; |
32 |
enum pl011_type type;
|
|
32 |
const unsigned char *id;
|
|
33 | 33 |
} pl011_state; |
34 | 34 |
|
35 | 35 |
#define PL011_INT_TX 0x20 |
... | ... | |
40 | 40 |
#define PL011_FLAG_TXFF 0x20 |
41 | 41 |
#define PL011_FLAG_RXFE 0x10 |
42 | 42 |
|
43 |
static const unsigned char pl011_id[2][8] = {
|
|
44 |
{ 0x11, 0x10, 0x14, 0x00, 0x0d, 0xf0, 0x05, 0xb1 }, /* PL011_ARM */
|
|
45 |
{ 0x11, 0x00, 0x18, 0x01, 0x0d, 0xf0, 0x05, 0xb1 }, /* PL011_LUMINARY */
|
|
46 |
}; |
|
43 |
static const unsigned char pl011_id_arm[8] =
|
|
44 |
{ 0x11, 0x10, 0x14, 0x00, 0x0d, 0xf0, 0x05, 0xb1 };
|
|
45 |
static const unsigned char pl011_id_luminary[8] =
|
|
46 |
{ 0x11, 0x00, 0x18, 0x01, 0x0d, 0xf0, 0x05, 0xb1 };
|
|
47 | 47 |
|
48 | 48 |
static void pl011_update(pl011_state *s) |
49 | 49 |
{ |
... | ... | |
59 | 59 |
uint32_t c; |
60 | 60 |
|
61 | 61 |
if (offset >= 0xfe0 && offset < 0x1000) { |
62 |
return pl011_id[s->type][(offset - 0xfe0) >> 2];
|
|
62 |
return s->id[(offset - 0xfe0) >> 2];
|
|
63 | 63 |
} |
64 | 64 |
switch (offset >> 2) { |
65 | 65 |
case 0: /* UARTDR */ |
... | ... | |
286 | 286 |
return 0; |
287 | 287 |
} |
288 | 288 |
|
289 |
void pl011_init(uint32_t base, qemu_irq irq, |
|
290 |
CharDriverState *chr, enum pl011_type type) |
|
289 |
static void pl011_init(SysBusDevice *dev, const unsigned char *id) |
|
291 | 290 |
{ |
292 | 291 |
int iomemtype; |
293 |
pl011_state *s; |
|
292 |
pl011_state *s = FROM_SYSBUS(pl011_state, dev);
|
|
294 | 293 |
|
295 |
s = (pl011_state *)qemu_mallocz(sizeof(pl011_state)); |
|
296 | 294 |
iomemtype = cpu_register_io_memory(0, pl011_readfn, |
297 | 295 |
pl011_writefn, s); |
298 |
cpu_register_physical_memory(base, 0x00001000, iomemtype); |
|
299 |
s->irq = irq; |
|
300 |
s->type = type; |
|
301 |
s->chr = chr; |
|
296 |
sysbus_init_mmio(dev, 0x1000,iomemtype); |
|
297 |
sysbus_init_irq(dev, &s->irq); |
|
298 |
s->id = id; |
|
299 |
s->chr = qdev_init_chardev(&dev->qdev); |
|
300 |
|
|
302 | 301 |
s->read_trigger = 1; |
303 | 302 |
s->ifl = 0x12; |
304 | 303 |
s->cr = 0x300; |
305 | 304 |
s->flags = 0x90; |
306 |
if (chr){
|
|
307 |
qemu_chr_add_handlers(chr, pl011_can_receive, pl011_receive, |
|
305 |
if (s->chr) {
|
|
306 |
qemu_chr_add_handlers(s->chr, pl011_can_receive, pl011_receive,
|
|
308 | 307 |
pl011_event, s); |
309 | 308 |
} |
310 | 309 |
register_savevm("pl011_uart", -1, 1, pl011_save, pl011_load, s); |
311 | 310 |
} |
311 |
|
|
312 |
static void pl011_init_arm(SysBusDevice *dev) |
|
313 |
{ |
|
314 |
pl011_init(dev, pl011_id_arm); |
|
315 |
} |
|
316 |
|
|
317 |
static void pl011_init_luminary(SysBusDevice *dev) |
|
318 |
{ |
|
319 |
pl011_init(dev, pl011_id_luminary); |
|
320 |
} |
|
321 |
|
|
322 |
static void pl011_register_devices(void) |
|
323 |
{ |
|
324 |
sysbus_register_dev("pl011", sizeof(pl011_state), |
|
325 |
pl011_init_arm); |
|
326 |
sysbus_register_dev("pl011_luminary", sizeof(pl011_state), |
|
327 |
pl011_init_luminary); |
|
328 |
} |
|
329 |
|
|
330 |
device_init(pl011_register_devices) |
b/hw/primecell.h | ||
---|---|---|
8 | 8 |
/* pl031.c */ |
9 | 9 |
void pl031_init(uint32_t base, qemu_irq irq); |
10 | 10 |
|
11 |
/* pl011.c */ |
|
12 |
enum pl011_type { |
|
13 |
PL011_ARM, |
|
14 |
PL011_LUMINARY |
|
15 |
}; |
|
16 |
|
|
17 |
void pl011_init(uint32_t base, qemu_irq irq, CharDriverState *chr, |
|
18 |
enum pl011_type type); |
|
19 |
|
|
20 | 11 |
/* pl022.c */ |
21 | 12 |
typedef int (*ssi_xfer_cb)(void *, int); |
22 | 13 |
void pl022_init(uint32_t base, qemu_irq irq, ssi_xfer_cb xfer_cb, |
b/hw/realview.c | ||
---|---|---|
85 | 85 |
pl050_init(0x10006000, pic[20], 0); |
86 | 86 |
pl050_init(0x10007000, pic[21], 1); |
87 | 87 |
|
88 |
pl011_init(0x10009000, pic[12], serial_hds[0], PL011_ARM);
|
|
89 |
pl011_init(0x1000a000, pic[13], serial_hds[1], PL011_ARM);
|
|
90 |
pl011_init(0x1000b000, pic[14], serial_hds[2], PL011_ARM);
|
|
91 |
pl011_init(0x1000c000, pic[15], serial_hds[3], PL011_ARM);
|
|
88 |
sysbus_create_simple("pl011", 0x10009000, pic[12]);
|
|
89 |
sysbus_create_simple("pl011", 0x1000a000, pic[13]);
|
|
90 |
sysbus_create_simple("pl011", 0x1000b000, pic[14]);
|
|
91 |
sysbus_create_simple("pl011", 0x1000c000, pic[15]);
|
|
92 | 92 |
|
93 | 93 |
/* DMA controller is optional, apparently. */ |
94 | 94 |
pl080_init(0x10030000, pic[24], 2); |
b/hw/stellaris.c | ||
---|---|---|
7 | 7 |
* This code is licenced under the GPL. |
8 | 8 |
*/ |
9 | 9 |
|
10 |
#include "hw.h"
|
|
10 |
#include "sysbus.h"
|
|
11 | 11 |
#include "arm-misc.h" |
12 | 12 |
#include "primecell.h" |
13 | 13 |
#include "devices.h" |
... | ... | |
1330 | 1330 |
|
1331 | 1331 |
for (i = 0; i < 4; i++) { |
1332 | 1332 |
if (board->dc2 & (1 << i)) { |
1333 |
pl011_init(0x4000c000 + i * 0x1000, pic[uart_irq[i]],
|
|
1334 |
serial_hds[i], PL011_LUMINARY);
|
|
1333 |
sysbus_create_simple("pl011_luminary", 0x4000c000 + i * 0x1000,
|
|
1334 |
pic[uart_irq[i]]);
|
|
1335 | 1335 |
} |
1336 | 1336 |
} |
1337 | 1337 |
if (board->dc2 & (1 << 4)) { |
b/hw/versatilepb.c | ||
---|---|---|
217 | 217 |
lsi_scsi_attach(scsi_hba, drives_table[index].bdrv, n); |
218 | 218 |
} |
219 | 219 |
|
220 |
pl011_init(0x101f1000, pic[12], serial_hds[0], PL011_ARM);
|
|
221 |
pl011_init(0x101f2000, pic[13], serial_hds[1], PL011_ARM);
|
|
222 |
pl011_init(0x101f3000, pic[14], serial_hds[2], PL011_ARM);
|
|
223 |
pl011_init(0x10009000, sic[6], serial_hds[3], PL011_ARM);
|
|
220 |
sysbus_create_simple("pl011", 0x101f1000, pic[12]);
|
|
221 |
sysbus_create_simple("pl011", 0x101f2000, pic[13]);
|
|
222 |
sysbus_create_simple("pl011", 0x101f3000, pic[14]);
|
|
223 |
sysbus_create_simple("pl011", 0x10009000, sic[6]);
|
|
224 | 224 |
|
225 | 225 |
pl080_init(0x10130000, pic[17], 8); |
226 | 226 |
sp804_init(0x101e2000, pic[4]); |
Also available in: Unified diff