qemu/hw/misc/mmio_interface.c
<<
>>
Prefs
   1/*
   2 * mmio_interface.c
   3 *
   4 *  Copyright (C) 2017 : GreenSocs
   5 *      http://www.greensocs.com/ , email: info@greensocs.com
   6 *
   7 *  Developed by :
   8 *  Frederic Konrad   <fred.konrad@greensocs.com>
   9 *
  10 * This program is free software; you can redistribute it and/or modify
  11 * it under the terms of the GNU General Public License as published by
  12 * the Free Software Foundation, either version 2 of the License, or
  13 * (at your option)any later version.
  14 *
  15 * This program is distributed in the hope that it will be useful,
  16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  18 * GNU General Public License for more details.
  19 *
  20 * You should have received a copy of the GNU General Public License along
  21 * with this program; if not, see <http://www.gnu.org/licenses/>.
  22 *
  23 */
  24
  25#include "qemu/osdep.h"
  26#include "qemu/log.h"
  27#include "trace.h"
  28#include "hw/qdev-properties.h"
  29#include "hw/misc/mmio_interface.h"
  30#include "qapi/error.h"
  31
  32#ifndef DEBUG_MMIO_INTERFACE
  33#define DEBUG_MMIO_INTERFACE 0
  34#endif
  35
  36static uint64_t mmio_interface_counter;
  37
  38#define DPRINTF(fmt, ...) do {                                                 \
  39    if (DEBUG_MMIO_INTERFACE) {                                                \
  40        qemu_log("mmio_interface: 0x%" PRIX64 ": " fmt, s->id, ## __VA_ARGS__);\
  41    }                                                                          \
  42} while (0)
  43
  44static void mmio_interface_init(Object *obj)
  45{
  46    MMIOInterface *s = MMIO_INTERFACE(obj);
  47
  48    if (DEBUG_MMIO_INTERFACE) {
  49        s->id = mmio_interface_counter++;
  50    }
  51
  52    DPRINTF("interface created\n");
  53    s->host_ptr = 0;
  54    s->subregion = 0;
  55}
  56
  57static void mmio_interface_realize(DeviceState *dev, Error **errp)
  58{
  59    MMIOInterface *s = MMIO_INTERFACE(dev);
  60
  61    DPRINTF("realize from 0x%" PRIX64 " to 0x%" PRIX64 " map host pointer"
  62            " %p\n", s->start, s->end, s->host_ptr);
  63
  64    if (!s->host_ptr) {
  65        error_setg(errp, "host_ptr property must be set");
  66        return;
  67    }
  68
  69    if (!s->subregion) {
  70        error_setg(errp, "subregion property must be set");
  71        return;
  72    }
  73
  74    memory_region_init_ram_ptr(&s->ram_mem, OBJECT(s), "ram",
  75                               s->end - s->start + 1, s->host_ptr);
  76    memory_region_set_readonly(&s->ram_mem, s->ro);
  77    memory_region_add_subregion(s->subregion, s->start, &s->ram_mem);
  78}
  79
  80static void mmio_interface_unrealize(DeviceState *dev, Error **errp)
  81{
  82    MMIOInterface *s = MMIO_INTERFACE(dev);
  83
  84    DPRINTF("unrealize from 0x%" PRIX64 " to 0x%" PRIX64 " map host pointer"
  85            " %p\n", s->start, s->end, s->host_ptr);
  86    memory_region_del_subregion(s->subregion, &s->ram_mem);
  87}
  88
  89static void mmio_interface_finalize(Object *obj)
  90{
  91    MMIOInterface *s = MMIO_INTERFACE(obj);
  92
  93    DPRINTF("finalize from 0x%" PRIX64 " to 0x%" PRIX64 " map host pointer"
  94            " %p\n", s->start, s->end, s->host_ptr);
  95    object_unparent(OBJECT(&s->ram_mem));
  96}
  97
  98static Property mmio_interface_properties[] = {
  99    DEFINE_PROP_UINT64("start", MMIOInterface, start, 0),
 100    DEFINE_PROP_UINT64("end", MMIOInterface, end, 0),
 101    DEFINE_PROP_PTR("host_ptr", MMIOInterface, host_ptr),
 102    DEFINE_PROP_BOOL("ro", MMIOInterface, ro, false),
 103    DEFINE_PROP_MEMORY_REGION("subregion", MMIOInterface, subregion),
 104    DEFINE_PROP_END_OF_LIST(),
 105};
 106
 107static void mmio_interface_class_init(ObjectClass *oc, void *data)
 108{
 109    DeviceClass *dc = DEVICE_CLASS(oc);
 110
 111    dc->realize = mmio_interface_realize;
 112    dc->unrealize = mmio_interface_unrealize;
 113    dc->props = mmio_interface_properties;
 114    /* Reason: pointer property "host_ptr", and this device
 115     * is an implementation detail of the memory subsystem,
 116     * not intended to be created directly by the user.
 117     */
 118    dc->user_creatable = false;
 119}
 120
 121static const TypeInfo mmio_interface_info = {
 122    .name          = TYPE_MMIO_INTERFACE,
 123    .parent        = TYPE_DEVICE,
 124    .instance_size = sizeof(MMIOInterface),
 125    .instance_init = mmio_interface_init,
 126    .instance_finalize = mmio_interface_finalize,
 127    .class_init    = mmio_interface_class_init,
 128};
 129
 130static void mmio_interface_register_types(void)
 131{
 132    type_register_static(&mmio_interface_info);
 133}
 134
 135type_init(mmio_interface_register_types)
 136