Revision c70c59ee

b/hw/slavio_timer.c
21 21
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 22
 * THE SOFTWARE.
23 23
 */
24
#include "hw.h"
24

  
25 25
#include "sun4m.h"
26 26
#include "qemu-timer.h"
27
#include "sysbus.h"
27 28

  
28 29
//#define DEBUG_TIMER
29 30

  
......
52 53
#define MAX_CPUS 16
53 54

  
54 55
typedef struct SLAVIO_TIMERState {
56
    SysBusDevice busdev;
55 57
    qemu_irq irq;
56 58
    ptimer_state *timer;
57 59
    uint32_t count, counthigh, reached;
......
364 366
static SLAVIO_TIMERState *slavio_timer_init(target_phys_addr_t addr,
365 367
                                            qemu_irq irq,
366 368
                                            SLAVIO_TIMERState *master,
367
                                            uint32_t slave_index)
369
                                            uint32_t slave_index,
370
                                            uint32_t num_slaves)
368 371
{
369
    int slavio_timer_io_memory;
370
    SLAVIO_TIMERState *s;
372
    DeviceState *dev;
373
    SysBusDevice *s;
374
    SLAVIO_TIMERState *d;
375

  
376
    dev = qdev_create(NULL, "slavio_timer");
377
    qdev_set_prop_int(dev, "slave_index", slave_index);
378
    qdev_set_prop_int(dev, "num_slaves", num_slaves);
379
    qdev_set_prop_ptr(dev, "master", master);
380
    qdev_init(dev);
381
    s = sysbus_from_qdev(dev);
382
    sysbus_connect_irq(s, 0, irq);
383
    sysbus_mmio_map(s, 0, addr);
384

  
385
    d = FROM_SYSBUS(SLAVIO_TIMERState, s);
386

  
387
    return d;
388
}
389

  
390
static void slavio_timer_init1(SysBusDevice *dev)
391
{
392
    int io;
393
    SLAVIO_TIMERState *s = FROM_SYSBUS(SLAVIO_TIMERState, dev);
371 394
    QEMUBH *bh;
372 395

  
373
    s = qemu_mallocz(sizeof(SLAVIO_TIMERState));
374
    s->irq = irq;
375
    s->master = master;
376
    s->slave_index = slave_index;
377
    if (!master || slave_index < master->num_slaves) {
396
    sysbus_init_irq(dev, &s->irq);
397
    s->num_slaves = qdev_get_prop_int(&dev->qdev, "num_slaves", 0);
398
    s->slave_index = qdev_get_prop_int(&dev->qdev, "slave_index", 0);
399
    s->master = qdev_get_prop_ptr(&dev->qdev, "master");
400

  
401
    if (!s->master || s->slave_index < s->master->num_slaves) {
378 402
        bh = qemu_bh_new(slavio_timer_irq, s);
379 403
        s->timer = ptimer_init(bh);
380 404
        ptimer_set_period(s->timer, TIMER_PERIOD);
381 405
    }
382 406

  
383
    slavio_timer_io_memory = cpu_register_io_memory(slavio_timer_mem_read,
384
                                                    slavio_timer_mem_write, s);
385
    if (master)
386
        cpu_register_physical_memory(addr, CPU_TIMER_SIZE,
387
                                     slavio_timer_io_memory);
388
    else
389
        cpu_register_physical_memory(addr, SYS_TIMER_SIZE,
390
                                     slavio_timer_io_memory);
391
    register_savevm("slavio_timer", addr, 3, slavio_timer_save,
407
    io = cpu_register_io_memory(slavio_timer_mem_read, slavio_timer_mem_write,
408
                                s);
409
    if (s->master) {
410
        sysbus_init_mmio(dev, CPU_TIMER_SIZE, io);
411
    } else {
412
        sysbus_init_mmio(dev, SYS_TIMER_SIZE, io);
413
    }
414

  
415
    register_savevm("slavio_timer", -1, 3, slavio_timer_save,
392 416
                    slavio_timer_load, s);
393 417
    qemu_register_reset(slavio_timer_reset, s);
394 418
    slavio_timer_reset(s);
395

  
396
    return s;
397 419
}
398 420

  
399 421
void slavio_timer_init_all(target_phys_addr_t base, qemu_irq master_irq,
......
402 424
    SLAVIO_TIMERState *master;
403 425
    unsigned int i;
404 426

  
405
    master = slavio_timer_init(base + SYS_TIMER_OFFSET, master_irq, NULL, 0);
406

  
407
    master->num_slaves = num_cpus;
427
    master = slavio_timer_init(base + SYS_TIMER_OFFSET, master_irq, NULL, 0,
428
                               num_cpus);
408 429

  
409 430
    for (i = 0; i < MAX_CPUS; i++) {
410 431
        master->slave[i] = slavio_timer_init(base + (target_phys_addr_t)
411 432
                                             CPU_TIMER_OFFSET(i),
412
                                             cpu_irqs[i], master, i);
433
                                             cpu_irqs[i], master, i, 0);
413 434
    }
414 435
}
436

  
437
static SysBusDeviceInfo slavio_timer_info = {
438
    .init = slavio_timer_init1,
439
    .qdev.name  = "slavio_timer",
440
    .qdev.size  = sizeof(SLAVIO_TIMERState),
441
    .qdev.props = (DevicePropList[]) {
442
        {.name = "num_slaves", .type = PROP_TYPE_INT},
443
        {.name = "slave_index", .type = PROP_TYPE_INT},
444
        {.name = "master", .type = PROP_TYPE_PTR},
445
        {.name = NULL}
446
    }
447
};
448

  
449
static void slavio_timer_register_devices(void)
450
{
451
    sysbus_register_withprop(&slavio_timer_info);
452
}
453

  
454
device_init(slavio_timer_register_devices)

Also available in: Unified diff