Revision cdbdb648

b/Makefile.target
339 339
endif
340 340
endif
341 341
ifeq ($(TARGET_BASE_ARCH), arm)
342
VL_OBJS+= integratorcp.o ps2.o smc91c111.o pl110.o
342
VL_OBJS+= integratorcp.o versatilepb.o ps2.o smc91c111.o arm_pic.o arm_timer.o
343
VL_OBJS+= pl011.o pl050.o pl080.o pl110.o pl190.o
343 344
endif
344 345
ifdef CONFIG_GDBSTUB
345 346
VL_OBJS+=gdbstub.o 
b/hw/arm_pic.c
1
/* 
2
 * Generic ARM Programmable Interrupt Controller support.
3
 *
4
 * Copyright (c) 2006 CodeSourcery.
5
 * Written by Paul Brook
6
 *
7
 * This code is licenced under the LGPL
8
 */
9

  
10
#include "vl.h"
11
#include "arm_pic.h"
12

  
13
/* Stub functions for hardware that doesn't exist.  */
14
void pic_set_irq(int irq, int level)
15
{
16
    cpu_abort(cpu_single_env, "pic_set_irq");
17
}
18

  
19
void pic_info(void)
20
{
21
}
22

  
23
void irq_info(void)
24
{
25
}
26

  
27

  
28
void pic_set_irq_new(void *opaque, int irq, int level)
29
{
30
    arm_pic_handler *p = (arm_pic_handler *)opaque;
31
    /* Call the real handler.  */
32
    (*p)(opaque, irq, level);
33
}
34

  
35
/* Model the IRQ/FIQ CPU interrupt lines as a two input interrupt controller.
36
   Input 0 is IRQ and input 1 is FIQ.  */
37
typedef struct
38
{
39
    arm_pic_handler handler;
40
    CPUState *cpu_env;
41
} arm_pic_cpu_state;
42

  
43
static void arm_pic_cpu_handler(void *opaque, int irq, int level)
44
{
45
    arm_pic_cpu_state *s = (arm_pic_cpu_state *)opaque;
46
    switch (irq) {
47
    case ARM_PIC_CPU_IRQ:
48
        if (level)
49
            cpu_interrupt(s->cpu_env, CPU_INTERRUPT_HARD);
50
        else
51
            cpu_reset_interrupt(s->cpu_env, CPU_INTERRUPT_HARD);
52
        break;
53
    case ARM_PIC_CPU_FIQ:
54
        if (level)
55
            cpu_interrupt(s->cpu_env, CPU_INTERRUPT_FIQ);
56
        else
57
            cpu_reset_interrupt(s->cpu_env, CPU_INTERRUPT_FIQ);
58
        break;
59
    default:
60
        cpu_abort(s->cpu_env, "arm_pic_cpu_handler: Bad interrput line %d\n",
61
                  irq);
62
    }
63
}
64

  
65
void *arm_pic_init_cpu(CPUState *env)
66
{
67
    arm_pic_cpu_state *s;
68
    
69
    s = (arm_pic_cpu_state *)malloc(sizeof(arm_pic_cpu_state));
70
    s->handler = arm_pic_cpu_handler;
71
    s->cpu_env = env;
72
    return s;
73
}
b/hw/arm_pic.h
1
/* 
2
 * Generic ARM Programmable Interrupt Controller support.
3
 *
4
 * Copyright (c) 2006 CodeSourcery.
5
 * Written by Paul Brook
6
 *
7
 * This code is licenced under the LGPL.
8
 *
9
 * Arm hardware uses a wide variety of interrupt handling hardware.
10
 * This provides a generic framework for connecting interrupt sources and
11
 * inputs.
12
 */
13

  
14
#ifndef ARM_INTERRUPT_H
15
#define ARM_INTERRUPT_H 1
16

  
17
/* The first element of an individual PIC state structures should
18
   be a pointer to the handler routine.  */
19
typedef void (*arm_pic_handler)(void *opaque, int irq, int level);
20

  
21
/* The CPU is also modeled as an interrupt controller.  */
22
#define ARM_PIC_CPU_IRQ 0
23
#define ARM_PIC_CPU_FIQ 1
24
void *arm_pic_init_cpu(CPUState *env);
25

  
26
#endif /* !ARM_INTERRUPT_H */
27

  
b/hw/arm_timer.c
1
/* 
2
 * ARM PrimeCell Timer modules.
3
 *
4
 * Copyright (c) 2005-2006 CodeSourcery.
5
 * Written by Paul Brook
6
 *
7
 * This code is licenced under the GPL.
8
 */
9

  
10
#include "vl.h"
11
#include "arm_pic.h"
12

  
13
/* Common timer implementation.  */
14

  
15
#define TIMER_CTRL_ONESHOT      (1 << 0)
16
#define TIMER_CTRL_32BIT        (1 << 1)
17
#define TIMER_CTRL_DIV1         (0 << 2)
18
#define TIMER_CTRL_DIV16        (1 << 2)
19
#define TIMER_CTRL_DIV256       (2 << 2)
20
#define TIMER_CTRL_IE           (1 << 5)
21
#define TIMER_CTRL_PERIODIC     (1 << 6)
22
#define TIMER_CTRL_ENABLE       (1 << 7)
23

  
24
typedef struct {
25
    int64_t next_time;
26
    int64_t expires;
27
    int64_t loaded;
28
    QEMUTimer *timer;
29
    uint32_t control;
30
    uint32_t count;
31
    uint32_t limit;
32
    int raw_freq;
33
    int freq;
34
    int int_level;
35
    void *pic;
36
    int irq;
37
} arm_timer_state;
38

  
39
/* Calculate the new expiry time of the given timer.  */
40

  
41
static void arm_timer_reload(arm_timer_state *s)
42
{
43
    int64_t delay;
44

  
45
    s->loaded = s->expires;
46
    delay = muldiv64(s->count, ticks_per_sec, s->freq);
47
    if (delay == 0)
48
        delay = 1;
49
    s->expires += delay;
50
}
51

  
52
/* Check all active timers, and schedule the next timer interrupt.  */
53

  
54
static void arm_timer_update(arm_timer_state *s, int64_t now)
55
{
56
    int64_t next;
57

  
58
    /* Ignore disabled timers.  */
59
    if ((s->control & TIMER_CTRL_ENABLE) == 0)
60
        return;
61
    /* Ignore expired one-shot timers.  */
62
    if (s->count == 0 && (s->control & TIMER_CTRL_ONESHOT))
63
        return;
64
    if (s->expires - now <= 0) {
65
        /* Timer has expired.  */
66
        s->int_level = 1;
67
        if (s->control & TIMER_CTRL_ONESHOT) {
68
            /* One-shot.  */
69
            s->count = 0;
70
        } else {
71
            if ((s->control & TIMER_CTRL_PERIODIC) == 0) {
72
                /* Free running.  */
73
                if (s->control & TIMER_CTRL_32BIT)
74
                    s->count = 0xffffffff;
75
                else
76
                    s->count = 0xffff;
77
            } else {
78
                  /* Periodic.  */
79
                  s->count = s->limit;
80
            }
81
        }
82
    }
83
    while (s->expires - now <= 0) {
84
        arm_timer_reload(s);
85
    }
86
    /* Update interrupts.  */
87
    if (s->int_level && (s->control & TIMER_CTRL_IE)) {
88
        pic_set_irq_new(s->pic, s->irq, 1);
89
    } else {
90
        pic_set_irq_new(s->pic, s->irq, 0);
91
    }
92

  
93
    next = now;
94
    if (next - s->expires < 0)
95
        next = s->expires;
96

  
97
    /* Schedule the next timer interrupt.  */
98
    if (next == now) {
99
        qemu_del_timer(s->timer);
100
        s->next_time = 0;
101
    } else if (next != s->next_time) {
102
        qemu_mod_timer(s->timer, next);
103
        s->next_time = next;
104
    }
105
}
106

  
107
/* Return the current value of the timer.  */
108
static uint32_t arm_timer_getcount(arm_timer_state *s, int64_t now)
109
{
110
    int64_t elapsed;
111
    int64_t period;
112

  
113
    if (s->count == 0)
114
        return 0;
115
    if ((s->control & TIMER_CTRL_ENABLE) == 0)
116
        return s->count;
117
    elapsed = now - s->loaded;
118
    period = s->expires - s->loaded;
119
    /* If the timer should have expired then return 0.  This can happen
120
       when the host timer signal doesnt occur immediately.  It's better to
121
       have a timer appear to sit at zero for a while than have it wrap
122
       around before the guest interrupt is raised.  */
123
    /* ??? Could we trigger the interrupt here?  */
124
    if (elapsed > period)
125
        return 0;
126
    /* We need to calculate count * elapsed / period without overfowing.
127
       Scale both elapsed and period so they fit in a 32-bit int.  */
128
    while (period != (int32_t)period) {
129
        period >>= 1;
130
        elapsed >>= 1;
131
    }
132
    return ((uint64_t)s->count * (uint64_t)(int32_t)elapsed)
133
            / (int32_t)period;
134
}
135

  
136
uint32_t arm_timer_read(void *opaque, target_phys_addr_t offset)
137
{
138
    arm_timer_state *s = (arm_timer_state *)opaque;
139

  
140
    switch (offset >> 2) {
141
    case 0: /* TimerLoad */
142
    case 6: /* TimerBGLoad */
143
        return s->limit;
144
    case 1: /* TimerValue */
145
        return arm_timer_getcount(s, qemu_get_clock(vm_clock));
146
    case 2: /* TimerControl */
147
        return s->control;
148
    case 4: /* TimerRIS */
149
        return s->int_level;
150
    case 5: /* TimerMIS */
151
        if ((s->control & TIMER_CTRL_IE) == 0)
152
            return 0;
153
        return s->int_level;
154
    default:
155
        cpu_abort (cpu_single_env, "arm_timer_read: Bad offset %x\n", offset);
156
        return 0;
157
    }
158
}
159

  
160
static void arm_timer_write(void *opaque, target_phys_addr_t offset,
161
                            uint32_t value)
162
{
163
    arm_timer_state *s = (arm_timer_state *)opaque;
164
    int64_t now;
165

  
166
    now = qemu_get_clock(vm_clock);
167
    switch (offset >> 2) {
168
    case 0: /* TimerLoad */
169
        s->limit = value;
170
        s->count = value;
171
        s->expires = now;
172
        arm_timer_reload(s);
173
        break;
174
    case 1: /* TimerValue */
175
        /* ??? Linux seems to want to write to this readonly register.
176
           Ignore it.  */
177
        break;
178
    case 2: /* TimerControl */
179
        if (s->control & TIMER_CTRL_ENABLE) {
180
            /* Pause the timer if it is running.  This may cause some
181
               inaccuracy dure to rounding, but avoids a whole lot of other
182
               messyness.  */
183
            s->count = arm_timer_getcount(s, now);
184
        }
185
        s->control = value;
186
        s->freq = s->raw_freq;
187
        /* ??? Need to recalculate expiry time after changing divisor.  */
188
        switch ((value >> 2) & 3) {
189
        case 1: s->freq >>= 4; break;
190
        case 2: s->freq >>= 8; break;
191
        }
192
        if (s->control & TIMER_CTRL_ENABLE) {
193
            /* Restart the timer if still enabled.  */
194
            s->expires = now;
195
            arm_timer_reload(s);
196
        }
197
        break;
198
    case 3: /* TimerIntClr */
199
        s->int_level = 0;
200
        break;
201
    case 6: /* TimerBGLoad */
202
        s->limit = value;
203
        break;
204
    default:
205
        cpu_abort (cpu_single_env, "arm_timer_write: Bad offset %x\n", offset);
206
    }
207
    arm_timer_update(s, now);
208
}
209

  
210
static void arm_timer_tick(void *opaque)
211
{
212
    int64_t now;
213

  
214
    now = qemu_get_clock(vm_clock);
215
    arm_timer_update((arm_timer_state *)opaque, now);
216
}
217

  
218
static void *arm_timer_init(uint32_t freq, void *pic, int irq)
219
{
220
    arm_timer_state *s;
221

  
222
    s = (arm_timer_state *)qemu_mallocz(sizeof(arm_timer_state));
223
    s->pic = pic;
224
    s->irq = irq;
225
    s->raw_freq = s->freq = 1000000;
226
    s->control = TIMER_CTRL_IE;
227
    s->count = 0xffffffff;
228

  
229
    s->timer = qemu_new_timer(vm_clock, arm_timer_tick, s);
230
    /* ??? Save/restore.  */
231
    return s;
232
}
233

  
234
/* ARM PrimeCell SP804 dual timer module.
235
   Docs for this device don't seem to be publicly available.  This
236
   implementation is based on gueswork, the linux kernel sources and the
237
   Integrator/CP timer modules.  */
238

  
239
typedef struct {
240
    /* Include a pseudo-PIC device to merge the two interrupt sources.  */
241
    arm_pic_handler handler;
242
    void *timer[2];
243
    int level[2];
244
    uint32_t base;
245
    /* The output PIC device.  */
246
    void *pic;
247
    int irq;
248
} sp804_state;
249

  
250
static void sp804_set_irq(void *opaque, int irq, int level)
251
{
252
    sp804_state *s = (sp804_state *)opaque;
253

  
254
    s->level[irq] = level;
255
    pic_set_irq_new(s->pic, s->irq, s->level[0] || s->level[1]);
256
}
257

  
258
static uint32_t sp804_read(void *opaque, target_phys_addr_t offset)
259
{
260
    sp804_state *s = (sp804_state *)opaque;
261

  
262
    /* ??? Don't know the PrimeCell ID for this device.  */
263
    offset -= s->base;
264
    if (offset < 0x20) {
265
        return arm_timer_read(s->timer[0], offset);
266
    } else {
267
        return arm_timer_read(s->timer[1], offset - 0x20);
268
    }
269
}
270

  
271
static void sp804_write(void *opaque, target_phys_addr_t offset,
272
                        uint32_t value)
273
{
274
    sp804_state *s = (sp804_state *)opaque;
275

  
276
    offset -= s->base;
277
    if (offset < 0x20) {
278
        arm_timer_write(s->timer[0], offset, value);
279
    } else {
280
        arm_timer_write(s->timer[1], offset - 0x20, value);
281
    }
282
}
283

  
284
static CPUReadMemoryFunc *sp804_readfn[] = {
285
   sp804_read,
286
   sp804_read,
287
   sp804_read
288
};
289

  
290
static CPUWriteMemoryFunc *sp804_writefn[] = {
291
   sp804_write,
292
   sp804_write,
293
   sp804_write
294
};
295

  
296
void sp804_init(uint32_t base, void *pic, int irq)
297
{
298
    int iomemtype;
299
    sp804_state *s;
300

  
301
    s = (sp804_state *)qemu_mallocz(sizeof(sp804_state));
302
    s->handler = sp804_set_irq;
303
    s->base = base;
304
    s->pic = pic;
305
    s->irq = irq;
306
    /* ??? The timers are actually configurable between 32kHz and 1MHz, but
307
       we don't implement that.  */
308
    s->timer[0] = arm_timer_init(1000000, s, 0);
309
    s->timer[1] = arm_timer_init(1000000, s, 1);
310
    iomemtype = cpu_register_io_memory(0, sp804_readfn,
311
                                       sp804_writefn, s);
312
    cpu_register_physical_memory(base, 0x00000fff, iomemtype);
313
    /* ??? Save/restore.  */
314
}
315

  
316

  
317
/* Integrator/CP timer module.  */
318

  
319
typedef struct {
320
    void *timer[3];
321
    uint32_t base;
322
} icp_pit_state;
323

  
324
static uint32_t icp_pit_read(void *opaque, target_phys_addr_t offset)
325
{
326
    icp_pit_state *s = (icp_pit_state *)opaque;
327
    int n;
328

  
329
    /* ??? Don't know the PrimeCell ID for this device.  */
330
    offset -= s->base;
331
    n = offset >> 8;
332
    if (n > 3)
333
        cpu_abort(cpu_single_env, "sp804_read: Bad timer %d\n", n);
334

  
335
    return arm_timer_read(s->timer[n], offset & 0xff);
336
}
337

  
338
static void icp_pit_write(void *opaque, target_phys_addr_t offset,
339
                          uint32_t value)
340
{
341
    icp_pit_state *s = (icp_pit_state *)opaque;
342
    int n;
343

  
344
    offset -= s->base;
345
    n = offset >> 8;
346
    if (n > 3)
347
        cpu_abort(cpu_single_env, "sp804_write: Bad timer %d\n", n);
348

  
349
    arm_timer_write(s->timer[n], offset & 0xff, value);
350
}
351

  
352

  
353
static CPUReadMemoryFunc *icp_pit_readfn[] = {
354
   icp_pit_read,
355
   icp_pit_read,
356
   icp_pit_read
357
};
358

  
359
static CPUWriteMemoryFunc *icp_pit_writefn[] = {
360
   icp_pit_write,
361
   icp_pit_write,
362
   icp_pit_write
363
};
364

  
365
void icp_pit_init(uint32_t base, void *pic, int irq)
366
{
367
    int iomemtype;
368
    icp_pit_state *s;
369

  
370
    s = (icp_pit_state *)qemu_mallocz(sizeof(icp_pit_state));
371
    s->base = base;
372
    /* Timer 0 runs at the system clock speed (40MHz).  */
373
    s->timer[0] = arm_timer_init(40000000, pic, irq);
374
    /* The other two timers run at 1MHz.  */
375
    s->timer[1] = arm_timer_init(1000000, pic, irq + 1);
376
    s->timer[2] = arm_timer_init(1000000, pic, irq + 2);
377

  
378
    iomemtype = cpu_register_io_memory(0, icp_pit_readfn,
379
                                       icp_pit_writefn, s);
380
    cpu_register_physical_memory(base, 0x00000fff, iomemtype);
381
    /* ??? Save/restore.  */
382
}
383

  
b/hw/integratorcp.c
1 1
/* 
2 2
 * ARM Integrator CP System emulation.
3 3
 *
4
 * Copyright (c) 2005 CodeSourcery, LLC.
4
 * Copyright (c) 2005-2006 CodeSourcery.
5 5
 * Written by Paul Brook
6 6
 *
7 7
 * This code is licenced under the GPL
8 8
 */
9 9

  
10
#include <vl.h>
10
#include "vl.h"
11
#include "arm_pic.h"
11 12

  
12 13
#define KERNEL_ARGS_ADDR 0x100
13 14
#define KERNEL_LOAD_ADDR 0x00010000
14 15
#define INITRD_LOAD_ADDR 0x00800000
15 16

  
16
/* Stub functions for hardware that doesn't exist.  */
17
void pic_set_irq(int irq, int level)
18
{
19
    cpu_abort (cpu_single_env, "pic_set_irq");
20
}
21

  
22
void pic_info(void)
23
{
24
}
25

  
26
void irq_info(void)
27
{
28
}
29

  
30 17
void DMA_run (void)
31 18
{
32 19
}
......
284 271

  
285 272
typedef struct icp_pic_state
286 273
{
274
  arm_pic_handler handler;
287 275
  uint32_t base;
288 276
  uint32_t level;
289 277
  uint32_t irq_enabled;
290 278
  uint32_t fiq_enabled;
291 279
  void *parent;
292
  /* -1 if parent is a cpu, otherwise IRQ number on parent PIC.  */
293 280
  int parent_irq;
281
  int parent_fiq;
294 282
} icp_pic_state;
295 283

  
296 284
static void icp_pic_update(icp_pic_state *s)
297 285
{
298
    CPUState *env;
299
    if (s->parent_irq != -1) {
300
        uint32_t flags;
286
    uint32_t flags;
301 287

  
288
    if (s->parent_irq != -1) {
302 289
        flags = (s->level & s->irq_enabled);
303
        pic_set_irq_new(s->parent, s->parent_irq,
304
                        flags != 0);
305
        return;
290
        pic_set_irq_new(s->parent, s->parent_irq, flags != 0);
306 291
    }
307
    /* Raise CPU interrupt.  */
308
    env = (CPUState *)s->parent;
309
    if (s->level & s->fiq_enabled) {
310
        cpu_interrupt (env, CPU_INTERRUPT_FIQ);
311
    } else {
312
        cpu_reset_interrupt (env, CPU_INTERRUPT_FIQ);
313
    }
314
    if (s->level & s->irq_enabled) {
315
      cpu_interrupt (env, CPU_INTERRUPT_HARD);
316
    } else {
317
      cpu_reset_interrupt (env, CPU_INTERRUPT_HARD);
292
    if (s->parent_fiq != -1) {
293
        flags = (s->level & s->fiq_enabled);
294
        pic_set_irq_new(s->parent, s->parent_fiq, flags != 0);
318 295
    }
319 296
}
320 297

  
321
void pic_set_irq_new(void *opaque, int irq, int level)
298
static void icp_pic_set_irq(void *opaque, int irq, int level)
322 299
{
323 300
    icp_pic_state *s = (icp_pic_state *)opaque;
324 301
    if (level)
......
408 385
};
409 386

  
410 387
static icp_pic_state *icp_pic_init(uint32_t base, void *parent,
411
                                   int parent_irq)
388
                                   int parent_irq, int parent_fiq)
412 389
{
413 390
    icp_pic_state *s;
414 391
    int iomemtype;
......
416 393
    s = (icp_pic_state *)qemu_mallocz(sizeof(icp_pic_state));
417 394
    if (!s)
418 395
        return NULL;
419

  
396
    s->handler = icp_pic_set_irq;
420 397
    s->base = base;
421 398
    s->parent = parent;
422 399
    s->parent_irq = parent_irq;
400
    s->parent_fiq = parent_fiq;
423 401
    iomemtype = cpu_register_io_memory(0, icp_pic_readfn,
424 402
                                       icp_pic_writefn, s);
425 403
    cpu_register_physical_memory(base, 0x007fffff, iomemtype);
......
427 405
    return s;
428 406
}
429 407

  
430
/* Timers.  */
431

  
432
/* System bus clock speed (40MHz) for timer 0.  Not sure about this value.  */
433
#define ICP_BUS_FREQ 40000000
434

  
435
typedef struct {
436
    int64_t next_time;
437
    int64_t expires[3];
438
    int64_t loaded[3];
439
    QEMUTimer *timer;
440
    icp_pic_state *pic;
441
    uint32_t base;
442
    uint32_t control[3];
443
    uint32_t count[3];
444
    uint32_t limit[3];
445
    int freq[3];
446
    int int_level[3];
447
} icp_pit_state;
448

  
449
/* Calculate the new expiry time of the given timer.  */
450

  
451
static void icp_pit_reload(icp_pit_state *s, int n)
452
{
453
    int64_t delay;
454

  
455
    s->loaded[n] = s->expires[n];
456
    delay = muldiv64(s->count[n], ticks_per_sec, s->freq[n]);
457
    if (delay == 0)
458
        delay = 1;
459
    s->expires[n] += delay;
460
}
461

  
462
/* Check all active timers, and schedule the next timer interrupt.  */
463

  
464
static void icp_pit_update(icp_pit_state *s, int64_t now)
465
{
466
    int n;
467
    int64_t next;
468

  
469
    next = now;
470
    for (n = 0; n < 3; n++) {
471
        /* Ignore disabled timers.  */
472
        if ((s->control[n] & 0x80) == 0)
473
            continue;
474
        /* Ignore expired one-shot timers.  */
475
        if (s->count[n] == 0 && s->control[n] & 1)
476
            continue;
477
        if (s->expires[n] - now <= 0) {
478
            /* Timer has expired.  */
479
            s->int_level[n] = 1;
480
            if (s->control[n] & 1) {
481
                /* One-shot.  */
482
                s->count[n] = 0;
483
            } else {
484
                if ((s->control[n] & 0x40) == 0) {
485
                    /* Free running.  */
486
                    if (s->control[n] & 2)
487
                        s->count[n] = 0xffffffff;
488
                    else
489
                        s->count[n] = 0xffff;
490
                } else {
491
                      /* Periodic.  */
492
                      s->count[n] = s->limit[n];
493
                }
494
            }
495
        }
496
        while (s->expires[n] - now <= 0) {
497
            icp_pit_reload(s, n);
498
        }
499
    }
500
    /* Update interrupts.  */
501
    for (n = 0; n < 3; n++) {
502
        if (s->int_level[n] && (s->control[n] & 0x20)) {
503
            pic_set_irq_new(s->pic, 5 + n, 1);
504
        } else {
505
            pic_set_irq_new(s->pic, 5 + n, 0);
506
        }
507
        if (next - s->expires[n] < 0)
508
            next = s->expires[n];
509
    }
510
    /* Schedule the next timer interrupt.  */
511
    if (next == now) {
512
        qemu_del_timer(s->timer);
513
        s->next_time = 0;
514
    } else if (next != s->next_time) {
515
        qemu_mod_timer(s->timer, next);
516
        s->next_time = next;
517
    }
518
}
519

  
520
/* Return the current value of the timer.  */
521
static uint32_t icp_pit_getcount(icp_pit_state *s, int n, int64_t now)
522
{
523
    int64_t elapsed;
524
    int64_t period;
525

  
526
    if (s->count[n] == 0)
527
        return 0;
528
    if ((s->control[n] & 0x80) == 0)
529
        return s->count[n];
530
    elapsed = now - s->loaded[n];
531
    period = s->expires[n] - s->loaded[n];
532
    /* If the timer should have expired then return 0.  This can happen
533
       when the host timer signal doesnt occur immediately.  It's better to
534
       have a timer appear to sit at zero for a while than have it wrap
535
       around before the guest interrupt is raised.  */
536
    /* ??? Could we trigger the interrupt here?  */
537
    if (elapsed > period)
538
        return 0;
539
    /* We need to calculate count * elapsed / period without overfowing.
540
       Scale both elapsed and period so they fit in a 32-bit int.  */
541
    while (period != (int32_t)period) {
542
        period >>= 1;
543
        elapsed >>= 1;
544
    }
545
    return ((uint64_t)s->count[n] * (uint64_t)(int32_t)elapsed)
546
            / (int32_t)period;
547
}
548

  
549
static uint32_t icp_pit_read(void *opaque, target_phys_addr_t offset)
550
{
551
    int n;
552
    icp_pit_state *s = (icp_pit_state *)opaque;
553

  
554
    offset -= s->base;
555
    n = offset >> 8;
556
    if (n > 2)
557
        cpu_abort (cpu_single_env, "icp_pit_read: Bad timer %x\n", offset);
558
    switch ((offset & 0xff) >> 2) {
559
    case 0: /* TimerLoad */
560
    case 6: /* TimerBGLoad */
561
        return s->limit[n];
562
    case 1: /* TimerValue */
563
        return icp_pit_getcount(s, n, qemu_get_clock(vm_clock));
564
    case 2: /* TimerControl */
565
        return s->control[n];
566
    case 4: /* TimerRIS */
567
        return s->int_level[n];
568
    case 5: /* TimerMIS */
569
        if ((s->control[n] & 0x20) == 0)
570
            return 0;
571
        return s->int_level[n];
572
    default:
573
        cpu_abort (cpu_single_env, "icp_pit_read: Bad offset %x\n", offset);
574
        return 0;
575
    }
576
}
577

  
578
static void icp_pit_write(void *opaque, target_phys_addr_t offset,
579
                          uint32_t value)
580
{
581
    icp_pit_state *s = (icp_pit_state *)opaque;
582
    int n;
583
    int64_t now;
584

  
585
    now = qemu_get_clock(vm_clock);
586
    offset -= s->base;
587
    n = offset >> 8;
588
    if (n > 2)
589
        cpu_abort (cpu_single_env, "icp_pit_write: Bad offset %x\n", offset);
590

  
591
    switch ((offset & 0xff) >> 2) {
592
    case 0: /* TimerLoad */
593
        s->limit[n] = value;
594
        s->count[n] = value;
595
        s->expires[n] = now;
596
        icp_pit_reload(s, n);
597
        break;
598
    case 1: /* TimerValue */
599
        /* ??? Linux seems to want to write to this readonly register.
600
           Ignore it.  */
601
        break;
602
    case 2: /* TimerControl */
603
        if (s->control[n] & 0x80) {
604
            /* Pause the timer if it is running.  This may cause some
605
               inaccuracy dure to rounding, but avoids a whole lot of other
606
               messyness.  */
607
            s->count[n] = icp_pit_getcount(s, n, now);
608
        }
609
        s->control[n] = value;
610
        if (n == 0)
611
            s->freq[n] = ICP_BUS_FREQ;
612
        else
613
            s->freq[n] = 1000000;
614
        /* ??? Need to recalculate expiry time after changing divisor.  */
615
        switch ((value >> 2) & 3) {
616
        case 1: s->freq[n] >>= 4; break;
617
        case 2: s->freq[n] >>= 8; break;
618
        }
619
        if (s->control[n] & 0x80) {
620
            /* Restart the timer if still enabled.  */
621
            s->expires[n] = now;
622
            icp_pit_reload(s, n);
623
        }
624
        break;
625
    case 3: /* TimerIntClr */
626
        s->int_level[n] = 0;
627
        break;
628
    case 6: /* TimerBGLoad */
629
        s->limit[n] = value;
630
        break;
631
    default:
632
        cpu_abort (cpu_single_env, "icp_pit_write: Bad offset %x\n", offset);
633
    }
634
    icp_pit_update(s, now);
635
}
636

  
637
static void icp_pit_tick(void *opaque)
638
{
639
    int64_t now;
640

  
641
    now = qemu_get_clock(vm_clock);
642
    icp_pit_update((icp_pit_state *)opaque, now);
643
}
644

  
645
static CPUReadMemoryFunc *icp_pit_readfn[] = {
646
   icp_pit_read,
647
   icp_pit_read,
648
   icp_pit_read
649
};
650

  
651
static CPUWriteMemoryFunc *icp_pit_writefn[] = {
652
   icp_pit_write,
653
   icp_pit_write,
654
   icp_pit_write
655
};
656

  
657
static void icp_pit_init(uint32_t base, icp_pic_state *pic)
658
{
659
    int iomemtype;
660
    icp_pit_state *s;
661
    int n;
662

  
663
    s = (icp_pit_state *)qemu_mallocz(sizeof(icp_pit_state));
664
    s->base = base;
665
    s->pic = pic;
666
    s->freq[0] = ICP_BUS_FREQ;
667
    s->freq[1] = 1000000;
668
    s->freq[2] = 1000000;
669
    for (n = 0; n < 3; n++) {
670
        s->control[n] = 0x20;
671
        s->count[n] = 0xffffffff;
672
    }
673

  
674
    iomemtype = cpu_register_io_memory(0, icp_pit_readfn,
675
                                       icp_pit_writefn, s);
676
    cpu_register_physical_memory(base, 0x007fffff, iomemtype);
677
    s->timer = qemu_new_timer(vm_clock, icp_pit_tick, s);
678
    /* ??? Save/restore.  */
679
}
680

  
681
/* ARM PrimeCell PL011 UART */
682

  
683
typedef struct {
684
    uint32_t base;
685
    uint32_t readbuff;
686
    uint32_t flags;
687
    uint32_t lcr;
688
    uint32_t cr;
689
    uint32_t dmacr;
690
    uint32_t int_enabled;
691
    uint32_t int_level;
692
    uint32_t read_fifo[16];
693
    uint32_t ilpr;
694
    uint32_t ibrd;
695
    uint32_t fbrd;
696
    uint32_t ifl;
697
    int read_pos;
698
    int read_count;
699
    int read_trigger;
700
    CharDriverState *chr;
701
    icp_pic_state *pic;
702
    int irq;
703
} pl011_state;
704

  
705
#define PL011_INT_TX 0x20
706
#define PL011_INT_RX 0x10
707

  
708
#define PL011_FLAG_TXFE 0x80
709
#define PL011_FLAG_RXFF 0x40
710
#define PL011_FLAG_TXFF 0x20
711
#define PL011_FLAG_RXFE 0x10
712

  
713
static const unsigned char pl011_id[] =
714
{ 0x11, 0x10, 0x14, 0x00, 0x0d, 0xf0, 0x05, 0xb1 };
715

  
716
static void pl011_update(pl011_state *s)
717
{
718
    uint32_t flags;
719
    
720
    flags = s->int_level & s->int_enabled;
721
    pic_set_irq_new(s->pic, s->irq, flags != 0);
722
}
723

  
724
static uint32_t pl011_read(void *opaque, target_phys_addr_t offset)
725
{
726
    pl011_state *s = (pl011_state *)opaque;
727
    uint32_t c;
728

  
729
    offset -= s->base;
730
    if (offset >= 0xfe0 && offset < 0x1000) {
731
        return pl011_id[(offset - 0xfe0) >> 2];
732
    }
733
    switch (offset >> 2) {
734
    case 0: /* UARTDR */
735
        s->flags &= ~PL011_FLAG_RXFF;
736
        c = s->read_fifo[s->read_pos];
737
        if (s->read_count > 0) {
738
            s->read_count--;
739
            if (++s->read_pos == 16)
740
                s->read_pos = 0;
741
        }
742
        if (s->read_count == 0) {
743
            s->flags |= PL011_FLAG_RXFE;
744
        }
745
        if (s->read_count == s->read_trigger - 1)
746
            s->int_level &= ~ PL011_INT_RX;
747
        pl011_update(s);
748
        return c;
749
    case 1: /* UARTCR */
750
        return 0;
751
    case 6: /* UARTFR */
752
        return s->flags;
753
    case 8: /* UARTILPR */
754
        return s->ilpr;
755
    case 9: /* UARTIBRD */
756
        return s->ibrd;
757
    case 10: /* UARTFBRD */
758
        return s->fbrd;
759
    case 11: /* UARTLCR_H */
760
        return s->lcr;
761
    case 12: /* UARTCR */
762
        return s->cr;
763
    case 13: /* UARTIFLS */
764
        return s->ifl;
765
    case 14: /* UARTIMSC */
766
        return s->int_enabled;
767
    case 15: /* UARTRIS */
768
        return s->int_level;
769
    case 16: /* UARTMIS */
770
        return s->int_level & s->int_enabled;
771
    case 18: /* UARTDMACR */
772
        return s->dmacr;
773
    default:
774
        cpu_abort (cpu_single_env, "pl011_read: Bad offset %x\n", offset);
775
        return 0;
776
    }
777
}
778

  
779
static void pl011_set_read_trigger(pl011_state *s)
780
{
781
#if 0
782
    /* The docs say the RX interrupt is triggered when the FIFO exceeds
783
       the threshold.  However linux only reads the FIFO in response to an
784
       interrupt.  Triggering the interrupt when the FIFO is non-empty seems
785
       to make things work.  */
786
    if (s->lcr & 0x10)
787
        s->read_trigger = (s->ifl >> 1) & 0x1c;
788
    else
789
#endif
790
        s->read_trigger = 1;
791
}
792

  
793
static void pl011_write(void *opaque, target_phys_addr_t offset,
794
                          uint32_t value)
795
{
796
    pl011_state *s = (pl011_state *)opaque;
797
    unsigned char ch;
798

  
799
    offset -= s->base;
800
    switch (offset >> 2) {
801
    case 0: /* UARTDR */
802
        /* ??? Check if transmitter is enabled.  */
803
        ch = value;
804
        if (s->chr)
805
            qemu_chr_write(s->chr, &ch, 1);
806
        s->int_level |= PL011_INT_TX;
807
        pl011_update(s);
808
        break;
809
    case 1: /* UARTCR */
810
        s->cr = value;
811
        break;
812
    case 8: /* UARTUARTILPR */
813
        s->ilpr = value;
814
        break;
815
    case 9: /* UARTIBRD */
816
        s->ibrd = value;
817
        break;
818
    case 10: /* UARTFBRD */
819
        s->fbrd = value;
820
        break;
821
    case 11: /* UARTLCR_H */
822
        s->lcr = value;
823
        pl011_set_read_trigger(s);
824
        break;
825
    case 12: /* UARTCR */
826
        /* ??? Need to implement the enable and loopback bits.  */
827
        s->cr = value;
828
        break;
829
    case 13: /* UARTIFS */
830
        s->ifl = value;
831
        pl011_set_read_trigger(s);
832
        break;
833
    case 14: /* UARTIMSC */
834
        s->int_enabled = value;
835
        pl011_update(s);
836
        break;
837
    case 17: /* UARTICR */
838
        s->int_level &= ~value;
839
        pl011_update(s);
840
        break;
841
    case 18: /* UARTDMACR */
842
        s->dmacr = value;
843
        if (value & 3)
844
            cpu_abort(cpu_single_env, "PL011: DMA not implemented\n");
845
        break;
846
    default:
847
        cpu_abort (cpu_single_env, "pl011_write: Bad offset %x\n", offset);
848
    }
849
}
850

  
851
static int pl011_can_recieve(void *opaque)
852
{
853
    pl011_state *s = (pl011_state *)opaque;
854

  
855
    if (s->lcr & 0x10)
856
        return s->read_count < 16;
857
    else
858
        return s->read_count < 1;
859
}
860

  
861
static void pl011_recieve(void *opaque, const uint8_t *buf, int size)
862
{
863
    pl011_state *s = (pl011_state *)opaque;
864
    int slot;
865

  
866
    slot = s->read_pos + s->read_count;
867
    if (slot >= 16)
868
        slot -= 16;
869
    s->read_fifo[slot] = *buf;
870
    s->read_count++;
871
    s->flags &= ~PL011_FLAG_RXFE;
872
    if (s->cr & 0x10 || s->read_count == 16) {
873
        s->flags |= PL011_FLAG_RXFF;
874
    }
875
    if (s->read_count == s->read_trigger) {
876
        s->int_level |= PL011_INT_RX;
877
        pl011_update(s);
878
    }
879
}
880

  
881
static void pl011_event(void *opaque, int event)
882
{
883
    /* ??? Should probably implement break.  */
884
}
885

  
886
static CPUReadMemoryFunc *pl011_readfn[] = {
887
   pl011_read,
888
   pl011_read,
889
   pl011_read
890
};
891

  
892
static CPUWriteMemoryFunc *pl011_writefn[] = {
893
   pl011_write,
894
   pl011_write,
895
   pl011_write
896
};
897

  
898
static void pl011_init(uint32_t base, icp_pic_state *pic, int irq,
899
                       CharDriverState *chr)
900
{
901
    int iomemtype;
902
    pl011_state *s;
903

  
904
    s = (pl011_state *)qemu_mallocz(sizeof(pl011_state));
905
    iomemtype = cpu_register_io_memory(0, pl011_readfn,
906
                                       pl011_writefn, s);
907
    cpu_register_physical_memory(base, 0x007fffff, iomemtype);
908
    s->base = base;
909
    s->pic = pic;
910
    s->irq = irq;
911
    s->chr = chr;
912
    s->read_trigger = 1;
913
    s->ifl = 0x12;
914
    s->cr = 0x300;
915
    s->flags = 0x90;
916
    if (chr){ 
917
        qemu_chr_add_read_handler(chr, pl011_can_recieve, pl011_recieve, s);
918
        qemu_chr_add_event_handler(chr, pl011_event);
919
    }
920
    /* ??? Save/restore.  */
921
}
922

  
923 408
/* CP control registers.  */
924 409
typedef struct {
925 410
    uint32_t base;
......
985 470
}
986 471

  
987 472

  
988
/* Keyboard/Mouse Interface.  */
989

  
990
typedef struct {
991
    void *dev;
992
    uint32_t base;
993
    uint32_t cr;
994
    uint32_t clk;
995
    uint32_t last;
996
    icp_pic_state *pic;
997
    int pending;
998
    int irq;
999
    int is_mouse;
1000
} icp_kmi_state;
1001

  
1002
static void icp_kmi_update(void *opaque, int level)
1003
{
1004
    icp_kmi_state *s = (icp_kmi_state *)opaque;
1005
    int raise;
1006

  
1007
    s->pending = level;
1008
    raise = (s->pending && (s->cr & 0x10) != 0)
1009
            || (s->cr & 0x08) != 0;
1010
    pic_set_irq_new(s->pic, s->irq, raise);
1011
}
1012

  
1013
static uint32_t icp_kmi_read(void *opaque, target_phys_addr_t offset)
1014
{
1015
    icp_kmi_state *s = (icp_kmi_state *)opaque;
1016
    offset -= s->base;
1017
    if (offset >= 0xfe0 && offset < 0x1000)
1018
        return 0;
1019

  
1020
    switch (offset >> 2) {
1021
    case 0: /* KMICR */
1022
        return s->cr;
1023
    case 1: /* KMISTAT */
1024
        /* KMIC and KMID bits not implemented.  */
1025
        if (s->pending) {
1026
            return 0x10;
1027
        } else {
1028
            return 0;
1029
        }
1030
    case 2: /* KMIDATA */
1031
        if (s->pending)
1032
            s->last = ps2_read_data(s->dev);
1033
        return s->last;
1034
    case 3: /* KMICLKDIV */
1035
        return s->clk;
1036
    case 4: /* KMIIR */
1037
        return s->pending | 2;
1038
    default:
1039
        cpu_abort (cpu_single_env, "icp_kmi_read: Bad offset %x\n", offset);
1040
        return 0;
1041
    }
1042
}
1043

  
1044
static void icp_kmi_write(void *opaque, target_phys_addr_t offset,
1045
                          uint32_t value)
1046
{
1047
    icp_kmi_state *s = (icp_kmi_state *)opaque;
1048
    offset -= s->base;
1049
    switch (offset >> 2) {
1050
    case 0: /* KMICR */
1051
        s->cr = value;
1052
        icp_kmi_update(s, s->pending);
1053
        /* ??? Need to implement the enable/disable bit.  */
1054
        break;
1055
    case 2: /* KMIDATA */
1056
        /* ??? This should toggle the TX interrupt line.  */
1057
        /* ??? This means kbd/mouse can block each other.  */
1058
        if (s->is_mouse) {
1059
            ps2_write_mouse(s->dev, value);
1060
        } else {
1061
            ps2_write_keyboard(s->dev, value);
1062
        }
1063
        break;
1064
    case 3: /* KMICLKDIV */
1065
        s->clk = value;
1066
        return;
1067
    default:
1068
        cpu_abort (cpu_single_env, "icp_kmi_write: Bad offset %x\n", offset);
1069
    }
1070
}
1071
static CPUReadMemoryFunc *icp_kmi_readfn[] = {
1072
   icp_kmi_read,
1073
   icp_kmi_read,
1074
   icp_kmi_read
1075
};
1076

  
1077
static CPUWriteMemoryFunc *icp_kmi_writefn[] = {
1078
   icp_kmi_write,
1079
   icp_kmi_write,
1080
   icp_kmi_write
1081
};
1082

  
1083
static void icp_kmi_init(uint32_t base, icp_pic_state * pic, int irq,
1084
                         int is_mouse)
1085
{
1086
    int iomemtype;
1087
    icp_kmi_state *s;
1088

  
1089
    s = (icp_kmi_state *)qemu_mallocz(sizeof(icp_kmi_state));
1090
    iomemtype = cpu_register_io_memory(0, icp_kmi_readfn,
1091
                                       icp_kmi_writefn, s);
1092
    cpu_register_physical_memory(base, 0x007fffff, iomemtype);
1093
    s->base = base;
1094
    s->pic = pic;
1095
    s->irq = irq;
1096
    s->is_mouse = is_mouse;
1097
    if (is_mouse)
1098
        s->dev = ps2_mouse_init(icp_kmi_update, s);
1099
    else
1100
        s->dev = ps2_kbd_init(icp_kmi_update, s);
1101
    /* ??? Save/restore.  */
1102
}
1103

  
1104 473
/* The worlds second smallest bootloader.  Set r0-r2, then jump to kernel.  */
1105 474
static uint32_t bootloader[] = {
1106 475
  0xe3a00000, /* mov     r0, #0 */
......
1162 531
    CPUState *env;
1163 532
    uint32_t bios_offset;
1164 533
    icp_pic_state *pic;
534
    void *cpu_pic;
1165 535
    int kernel_size;
1166 536
    int initrd_size;
1167 537
    int n;
......
1177 547
    cpu_register_physical_memory(0x80000000, ram_size, IO_MEM_RAM);
1178 548

  
1179 549
    integratorcm_init(ram_size >> 20, bios_offset);
1180
    pic = icp_pic_init(0x14000000, env, -1);
1181
    icp_pic_init(0xca000000, pic, 26);
1182
    icp_pit_init(0x13000000, pic);
550
    cpu_pic = arm_pic_init_cpu(env);
551
    pic = icp_pic_init(0x14000000, cpu_pic, ARM_PIC_CPU_IRQ, ARM_PIC_CPU_FIQ);
552
    icp_pic_init(0xca000000, pic, 26, -1);
553
    icp_pit_init(0x13000000, pic, 5);
1183 554
    pl011_init(0x16000000, pic, 1, serial_hds[0]);
1184 555
    pl011_init(0x17000000, pic, 2, serial_hds[1]);
1185 556
    icp_control_init(0xcb000000);
1186
    icp_kmi_init(0x18000000, pic, 3, 0);
1187
    icp_kmi_init(0x19000000, pic, 4, 1);
557
    pl050_init(0x18000000, pic, 3, 0);
558
    pl050_init(0x19000000, pic, 4, 1);
1188 559
    if (nd_table[0].vlan) {
1189 560
        if (nd_table[0].model == NULL
1190 561
            || strcmp(nd_table[0].model, "smc91c111") == 0) {
b/hw/pl011.c
1
/* 
2
 * Arm PrimeCell PL011 UART
3
 *
4
 * Copyright (c) 2006 CodeSourcery.
5
 * Written by Paul Brook
6
 *
7
 * This code is licenced under the GPL.
8
 */
9

  
10
#include "vl.h"
11

  
12
typedef struct {
13
    uint32_t base;
14
    uint32_t readbuff;
15
    uint32_t flags;
16
    uint32_t lcr;
17
    uint32_t cr;
18
    uint32_t dmacr;
19
    uint32_t int_enabled;
20
    uint32_t int_level;
21
    uint32_t read_fifo[16];
22
    uint32_t ilpr;
23
    uint32_t ibrd;
24
    uint32_t fbrd;
25
    uint32_t ifl;
26
    int read_pos;
27
    int read_count;
28
    int read_trigger;
29
    CharDriverState *chr;
30
    void *pic;
31
    int irq;
32
} pl011_state;
33

  
34
#define PL011_INT_TX 0x20
35
#define PL011_INT_RX 0x10
36

  
37
#define PL011_FLAG_TXFE 0x80
38
#define PL011_FLAG_RXFF 0x40
39
#define PL011_FLAG_TXFF 0x20
40
#define PL011_FLAG_RXFE 0x10
41

  
42
static const unsigned char pl011_id[] =
43
{ 0x11, 0x10, 0x14, 0x00, 0x0d, 0xf0, 0x05, 0xb1 };
44

  
45
static void pl011_update(pl011_state *s)
46
{
47
    uint32_t flags;
48
    
49
    flags = s->int_level & s->int_enabled;
50
    pic_set_irq_new(s->pic, s->irq, flags != 0);
51
}
52

  
53
static uint32_t pl011_read(void *opaque, target_phys_addr_t offset)
54
{
55
    pl011_state *s = (pl011_state *)opaque;
56
    uint32_t c;
57

  
58
    offset -= s->base;
59
    if (offset >= 0xfe0 && offset < 0x1000) {
60
        return pl011_id[(offset - 0xfe0) >> 2];
61
    }
62
    switch (offset >> 2) {
63
    case 0: /* UARTDR */
64
        s->flags &= ~PL011_FLAG_RXFF;
65
        c = s->read_fifo[s->read_pos];
66
        if (s->read_count > 0) {
67
            s->read_count--;
68
            if (++s->read_pos == 16)
69
                s->read_pos = 0;
70
        }
71
        if (s->read_count == 0) {
72
            s->flags |= PL011_FLAG_RXFE;
73
        }
74
        if (s->read_count == s->read_trigger - 1)
75
            s->int_level &= ~ PL011_INT_RX;
76
        pl011_update(s);
77
        return c;
78
    case 1: /* UARTCR */
79
        return 0;
80
    case 6: /* UARTFR */
81
        return s->flags;
82
    case 8: /* UARTILPR */
83
        return s->ilpr;
84
    case 9: /* UARTIBRD */
85
        return s->ibrd;
86
    case 10: /* UARTFBRD */
87
        return s->fbrd;
88
    case 11: /* UARTLCR_H */
89
        return s->lcr;
90
    case 12: /* UARTCR */
91
        return s->cr;
92
    case 13: /* UARTIFLS */
93
        return s->ifl;
94
    case 14: /* UARTIMSC */
95
        return s->int_enabled;
96
    case 15: /* UARTRIS */
97
        return s->int_level;
98
    case 16: /* UARTMIS */
99
        return s->int_level & s->int_enabled;
100
    case 18: /* UARTDMACR */
101
        return s->dmacr;
102
    default:
103
        cpu_abort (cpu_single_env, "pl011_read: Bad offset %x\n", offset);
104
        return 0;
105
    }
106
}
107

  
108
static void pl011_set_read_trigger(pl011_state *s)
109
{
110
#if 0
111
    /* The docs say the RX interrupt is triggered when the FIFO exceeds
112
       the threshold.  However linux only reads the FIFO in response to an
113
       interrupt.  Triggering the interrupt when the FIFO is non-empty seems
114
       to make things work.  */
115
    if (s->lcr & 0x10)
116
        s->read_trigger = (s->ifl >> 1) & 0x1c;
117
    else
118
#endif
119
        s->read_trigger = 1;
120
}
121

  
122
static void pl011_write(void *opaque, target_phys_addr_t offset,
123
                          uint32_t value)
124
{
125
    pl011_state *s = (pl011_state *)opaque;
126
    unsigned char ch;
127

  
128
    offset -= s->base;
129
    switch (offset >> 2) {
130
    case 0: /* UARTDR */
131
        /* ??? Check if transmitter is enabled.  */
132
        ch = value;
133
        if (s->chr)
134
            qemu_chr_write(s->chr, &ch, 1);
135
        s->int_level |= PL011_INT_TX;
136
        pl011_update(s);
137
        break;
138
    case 1: /* UARTCR */
139
        s->cr = value;
140
        break;
141
    case 8: /* UARTUARTILPR */
142
        s->ilpr = value;
143
        break;
144
    case 9: /* UARTIBRD */
145
        s->ibrd = value;
146
        break;
147
    case 10: /* UARTFBRD */
148
        s->fbrd = value;
149
        break;
150
    case 11: /* UARTLCR_H */
151
        s->lcr = value;
152
        pl011_set_read_trigger(s);
153
        break;
154
    case 12: /* UARTCR */
155
        /* ??? Need to implement the enable and loopback bits.  */
156
        s->cr = value;
157
        break;
158
    case 13: /* UARTIFS */
159
        s->ifl = value;
160
        pl011_set_read_trigger(s);
161
        break;
162
    case 14: /* UARTIMSC */
163
        s->int_enabled = value;
164
        pl011_update(s);
165
        break;
166
    case 17: /* UARTICR */
167
        s->int_level &= ~value;
168
        pl011_update(s);
169
        break;
170
    case 18: /* UARTDMACR */
171
        s->dmacr = value;
172
        if (value & 3)
173
            cpu_abort(cpu_single_env, "PL011: DMA not implemented\n");
174
        break;
175
    default:
176
        cpu_abort (cpu_single_env, "pl011_write: Bad offset %x\n", offset);
177
    }
178
}
179

  
180
static int pl011_can_recieve(void *opaque)
181
{
182
    pl011_state *s = (pl011_state *)opaque;
183

  
184
    if (s->lcr & 0x10)
185
        return s->read_count < 16;
186
    else
187
        return s->read_count < 1;
188
}
189

  
190
static void pl011_recieve(void *opaque, const uint8_t *buf, int size)
191
{
192
    pl011_state *s = (pl011_state *)opaque;
193
    int slot;
194

  
195
    slot = s->read_pos + s->read_count;
196
    if (slot >= 16)
197
        slot -= 16;
198
    s->read_fifo[slot] = *buf;
199
    s->read_count++;
200
    s->flags &= ~PL011_FLAG_RXFE;
201
    if (s->cr & 0x10 || s->read_count == 16) {
202
        s->flags |= PL011_FLAG_RXFF;
203
    }
204
    if (s->read_count == s->read_trigger) {
205
        s->int_level |= PL011_INT_RX;
206
        pl011_update(s);
... This diff was truncated because it exceeds the maximum size that can be displayed.

Also available in: Unified diff