qemu/hw/ppc/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 "qemu/osdep.h"
  21#include "qemu-common.h"
  22#include "cpu.h"
  23#include "hw/hw.h"
  24#include "sysemu/sysemu.h"
  25#include "hw/sysbus.h"
  26
  27#define MPC8544_GUTS_MMIO_SIZE        0x1000
  28#define MPC8544_GUTS_RSTCR_RESET      0x02
  29
  30#define MPC8544_GUTS_ADDR_PORPLLSR    0x00
  31#define MPC8544_GUTS_ADDR_PORBMSR     0x04
  32#define MPC8544_GUTS_ADDR_PORIMPSCR   0x08
  33#define MPC8544_GUTS_ADDR_PORDEVSR    0x0C
  34#define MPC8544_GUTS_ADDR_PORDBGMSR   0x10
  35#define MPC8544_GUTS_ADDR_PORDEVSR2   0x14
  36#define MPC8544_GUTS_ADDR_GPPORCR     0x20
  37#define MPC8544_GUTS_ADDR_GPIOCR      0x30
  38#define MPC8544_GUTS_ADDR_GPOUTDR     0x40
  39#define MPC8544_GUTS_ADDR_GPINDR      0x50
  40#define MPC8544_GUTS_ADDR_PMUXCR      0x60
  41#define MPC8544_GUTS_ADDR_DEVDISR     0x70
  42#define MPC8544_GUTS_ADDR_POWMGTCSR   0x80
  43#define MPC8544_GUTS_ADDR_MCPSUMR     0x90
  44#define MPC8544_GUTS_ADDR_RSTRSCR     0x94
  45#define MPC8544_GUTS_ADDR_PVR         0xA0
  46#define MPC8544_GUTS_ADDR_SVR         0xA4
  47#define MPC8544_GUTS_ADDR_RSTCR       0xB0
  48#define MPC8544_GUTS_ADDR_IOVSELSR    0xC0
  49#define MPC8544_GUTS_ADDR_DDRCSR      0xB20
  50#define MPC8544_GUTS_ADDR_DDRCDR      0xB24
  51#define MPC8544_GUTS_ADDR_DDRCLKDR    0xB28
  52#define MPC8544_GUTS_ADDR_CLKOCR      0xE00
  53#define MPC8544_GUTS_ADDR_SRDS1CR1    0xF04
  54#define MPC8544_GUTS_ADDR_SRDS2CR1    0xF10
  55#define MPC8544_GUTS_ADDR_SRDS2CR3    0xF18
  56
  57#define TYPE_MPC8544_GUTS "mpc8544-guts"
  58#define MPC8544_GUTS(obj) OBJECT_CHECK(GutsState, (obj), TYPE_MPC8544_GUTS)
  59
  60struct GutsState {
  61    /*< private >*/
  62    SysBusDevice parent_obj;
  63    /*< public >*/
  64
  65    MemoryRegion iomem;
  66};
  67
  68typedef struct GutsState GutsState;
  69
  70static uint64_t mpc8544_guts_read(void *opaque, hwaddr addr,
  71                                  unsigned size)
  72{
  73    uint32_t value = 0;
  74    PowerPCCPU *cpu = POWERPC_CPU(current_cpu);
  75    CPUPPCState *env = &cpu->env;
  76
  77    addr &= MPC8544_GUTS_MMIO_SIZE - 1;
  78    switch (addr) {
  79    case MPC8544_GUTS_ADDR_PVR:
  80        value = env->spr[SPR_PVR];
  81        break;
  82    case MPC8544_GUTS_ADDR_SVR:
  83        value = env->spr[SPR_E500_SVR];
  84        break;
  85    default:
  86        fprintf(stderr, "guts: Unknown register read: %x\n", (int)addr);
  87        break;
  88    }
  89
  90    return value;
  91}
  92
  93static void mpc8544_guts_write(void *opaque, hwaddr addr,
  94                               uint64_t value, unsigned size)
  95{
  96    addr &= MPC8544_GUTS_MMIO_SIZE - 1;
  97
  98    switch (addr) {
  99    case MPC8544_GUTS_ADDR_RSTCR:
 100        if (value & MPC8544_GUTS_RSTCR_RESET) {
 101            qemu_system_reset_request();
 102        }
 103        break;
 104    default:
 105        fprintf(stderr, "guts: Unknown register write: %x = %x\n",
 106                (int)addr, (unsigned)value);
 107        break;
 108    }
 109}
 110
 111static const MemoryRegionOps mpc8544_guts_ops = {
 112    .read = mpc8544_guts_read,
 113    .write = mpc8544_guts_write,
 114    .endianness = DEVICE_BIG_ENDIAN,
 115    .valid = {
 116        .min_access_size = 4,
 117        .max_access_size = 4,
 118    },
 119};
 120
 121static void mpc8544_guts_initfn(Object *obj)
 122{
 123    SysBusDevice *d = SYS_BUS_DEVICE(obj);
 124    GutsState *s = MPC8544_GUTS(obj);
 125
 126    memory_region_init_io(&s->iomem, OBJECT(s), &mpc8544_guts_ops, s,
 127                          "mpc8544.guts", MPC8544_GUTS_MMIO_SIZE);
 128    sysbus_init_mmio(d, &s->iomem);
 129}
 130
 131static const TypeInfo mpc8544_guts_info = {
 132    .name          = TYPE_MPC8544_GUTS,
 133    .parent        = TYPE_SYS_BUS_DEVICE,
 134    .instance_size = sizeof(GutsState),
 135    .instance_init = mpc8544_guts_initfn,
 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