4 * Copyright (C) 2017 : GreenSocs
5 * http://www.greensocs.com/ , email: info@greensocs.com
8 * Frederic Konrad <fred.konrad@greensocs.com>
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.
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.
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/>.
25 #include "qemu/osdep.h"
28 #include "hw/qdev-properties.h"
29 #include "hw/misc/mmio_interface.h"
30 #include "qapi/error.h"
32 #ifndef DEBUG_MMIO_INTERFACE
33 #define DEBUG_MMIO_INTERFACE 0
36 static uint64_t mmio_interface_counter
;
38 #define DPRINTF(fmt, ...) do { \
39 if (DEBUG_MMIO_INTERFACE) { \
40 qemu_log("mmio_interface: 0x%" PRIX64 ": " fmt, s->id, ## __VA_ARGS__);\
44 static void mmio_interface_init(Object
*obj
)
46 MMIOInterface
*s
= MMIO_INTERFACE(obj
);
48 if (DEBUG_MMIO_INTERFACE
) {
49 s
->id
= mmio_interface_counter
++;
52 DPRINTF("interface created\n");
57 static void mmio_interface_realize(DeviceState
*dev
, Error
**errp
)
59 MMIOInterface
*s
= MMIO_INTERFACE(dev
);
61 DPRINTF("realize from 0x%" PRIX64
" to 0x%" PRIX64
" map host pointer"
62 " %p\n", s
->start
, s
->end
, s
->host_ptr
);
65 error_setg(errp
, "host_ptr property must be set");
70 error_setg(errp
, "subregion property must be set");
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
);
80 static void mmio_interface_unrealize(DeviceState
*dev
, Error
**errp
)
82 MMIOInterface
*s
= MMIO_INTERFACE(dev
);
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
);
89 static void mmio_interface_finalize(Object
*obj
)
91 MMIOInterface
*s
= MMIO_INTERFACE(obj
);
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
));
98 static 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(),
107 static void mmio_interface_class_init(ObjectClass
*oc
, void *data
)
109 DeviceClass
*dc
= DEVICE_CLASS(oc
);
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.
118 dc
->user_creatable
= false;
121 static 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
,
130 static void mmio_interface_register_types(void)
132 type_register_static(&mmio_interface_info
);
135 type_init(mmio_interface_register_types
)