qemu/hw/mpc8544_guts.c
<<
>>
Prefs
   1/*
   2 * QEMU PowerPC MPC8544 global util pseudo-device
   3 *
   4 * Copyright (C) 2011 Freescale Semiconductor, Inc. All rights reserved.
   5 *
   6 * Author: Alexander Graf, <alex@csgraf.de>
   7 *
   8 * This is free software; you can redistribute it and/or modify
   9 * it under the terms of  the GNU General  Public License as published by
  10 * the Free Software Foundation;  either version 2 of the  License, or
  11 * (at your option) any later version.
  12 *
  13 * *****************************************************************
  14 *
  15 * The documentation for this device is noted in the MPC8544 documentation,
  16 * file name "MPC8544ERM.pdf". You can easily find it on the web.
  17 *
  18 */
  19
  20#include "hw.h"
  21#include "sysemu/sysemu.h"
  22#include "sysbus.h"
  23
  24#define MPC8544_GUTS_MMIO_SIZE        0x1000
  25#define MPC8544_GUTS_RSTCR_RESET      0x02
  26
  27#define MPC8544_GUTS_ADDR_PORPLLSR    0x00
  28#define MPC8544_GUTS_ADDR_PORBMSR     0x04
  29#define MPC8544_GUTS_ADDR_PORIMPSCR   0x08
  30#define MPC8544_GUTS_ADDR_PORDEVSR    0x0C
  31#define MPC8544_GUTS_ADDR_PORDBGMSR   0x10
  32#define MPC8544_GUTS_ADDR_PORDEVSR2   0x14
  33#define MPC8544_GUTS_ADDR_GPPORCR     0x20
  34#define MPC8544_GUTS_ADDR_GPIOCR      0x30
  35#define MPC8544_GUTS_ADDR_GPOUTDR     0x40
  36#define MPC8544_GUTS_ADDR_GPINDR      0x50
  37#define MPC8544_GUTS_ADDR_PMUXCR      0x60
  38#define MPC8544_GUTS_ADDR_DEVDISR     0x70
  39#define MPC8544_GUTS_ADDR_POWMGTCSR   0x80
  40#define MPC8544_GUTS_ADDR_MCPSUMR     0x90
  41#define MPC8544_GUTS_ADDR_RSTRSCR     0x94
  42#define MPC8544_GUTS_ADDR_PVR         0xA0
  43#define MPC8544_GUTS_ADDR_SVR         0xA4
  44#define MPC8544_GUTS_ADDR_RSTCR       0xB0
  45#define MPC8544_GUTS_ADDR_IOVSELSR    0xC0
  46#define MPC8544_GUTS_ADDR_DDRCSR      0xB20
  47#define MPC8544_GUTS_ADDR_DDRCDR      0xB24
  48#define MPC8544_GUTS_ADDR_DDRCLKDR    0xB28
  49#define MPC8544_GUTS_ADDR_CLKOCR      0xE00
  50#define MPC8544_GUTS_ADDR_SRDS1CR1    0xF04
  51#define MPC8544_GUTS_ADDR_SRDS2CR1    0xF10
  52#define MPC8544_GUTS_ADDR_SRDS2CR3    0xF18
  53
  54struct GutsState {
  55    SysBusDevice busdev;
  56    MemoryRegion iomem;
  57};
  58
  59typedef struct GutsState GutsState;
  60
  61static uint64_t mpc8544_guts_read(void *opaque, hwaddr addr,
  62                                  unsigned size)
  63{
  64    uint32_t value = 0;
  65    CPUPPCState *env = cpu_single_env;
  66
  67    addr &= MPC8544_GUTS_MMIO_SIZE - 1;
  68    switch (addr) {
  69    case MPC8544_GUTS_ADDR_PVR:
  70        value = env->spr[SPR_PVR];
  71        break;
  72    case MPC8544_GUTS_ADDR_SVR:
  73        value = env->spr[SPR_E500_SVR];
  74        break;
  75    default:
  76        fprintf(stderr, "guts: Unknown register read: %x\n", (int)addr);
  77        break;
  78    }
  79
  80    return value;
  81}
  82
  83static void mpc8544_guts_write(void *opaque, hwaddr addr,
  84                               uint64_t value, unsigned size)
  85{
  86    addr &= MPC8544_GUTS_MMIO_SIZE - 1;
  87
  88    switch (addr) {
  89    case MPC8544_GUTS_ADDR_RSTCR:
  90        if (value & MPC8544_GUTS_RSTCR_RESET) {
  91            qemu_system_reset_request();
  92        }
  93        break;
  94    default:
  95        fprintf(stderr, "guts: Unknown register write: %x = %x\n",
  96                (int)addr, (unsigned)value);
  97        break;
  98    }
  99}
 100
 101static const MemoryRegionOps mpc8544_guts_ops = {
 102    .read = mpc8544_guts_read,
 103    .write = mpc8544_guts_write,
 104    .endianness = DEVICE_BIG_ENDIAN,
 105    .valid = {
 106        .min_access_size = 4,
 107        .max_access_size = 4,
 108    },
 109};
 110
 111static int mpc8544_guts_initfn(SysBusDevice *dev)
 112{
 113    GutsState *s;
 114
 115    s = FROM_SYSBUS(GutsState, SYS_BUS_DEVICE(dev));
 116
 117    memory_region_init_io(&s->iomem, &mpc8544_guts_ops, s,
 118                          "mpc6544.guts", MPC8544_GUTS_MMIO_SIZE);
 119    sysbus_init_mmio(dev, &s->iomem);
 120
 121    return 0;
 122}
 123
 124static void mpc8544_guts_class_init(ObjectClass *klass, void *data)
 125{
 126    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
 127
 128    k->init = mpc8544_guts_initfn;
 129}
 130
 131static const TypeInfo mpc8544_guts_info = {
 132    .name          = "mpc8544-guts",
 133    .parent        = TYPE_SYS_BUS_DEVICE,
 134    .instance_size = sizeof(GutsState),
 135    .class_init    = mpc8544_guts_class_init,
 136};
 137
 138static void mpc8544_guts_register_types(void)
 139{
 140    type_register_static(&mpc8544_guts_info);
 141}
 142
 143type_init(mpc8544_guts_register_types)
 144