]>
Commit | Line | Data |
---|---|---|
7cc2298c FK |
1 | /* |
2 | * mmio_interface.c | |
3 | * | |
4 | * Copyright (C) 2017 : GreenSocs | |
5 | * http://www.greensocs.com/ , email: [email protected] | |
6 | * | |
7 | * Developed by : | |
8 | * Frederic Konrad <[email protected]> | |
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 | ||
36 | static 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 | } \ | |
2562755e | 42 | } while (0) |
7cc2298c FK |
43 | |
44 | static 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 | ||
57 | static 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"); | |
a808c086 | 66 | return; |
7cc2298c FK |
67 | } |
68 | ||
69 | if (!s->subregion) { | |
70 | error_setg(errp, "subregion property must be set"); | |
a808c086 | 71 | return; |
7cc2298c FK |
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 | ||
80 | static 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 | ||
89 | static 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 | ||
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(), | |
105 | }; | |
106 | ||
107 | static 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; | |
72b384f4 PM |
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; | |
7cc2298c FK |
119 | } |
120 | ||
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, | |
128 | }; | |
129 | ||
130 | static void mmio_interface_register_types(void) | |
131 | { | |
132 | type_register_static(&mmio_interface_info); | |
133 | } | |
134 | ||
135 | type_init(mmio_interface_register_types) |