quic/qbox
Loading...
Searching...
No Matches
display.h
1/*
2 * This file is part of libqbox
3 * Copyright (c) 2023-2024 Qualcomm Innovation Center, Inc. All Rights Reserved.
4 *
5 * SPDX-License-Identifier: BSD-3-Clause
6 */
7
8#ifndef _LIBQBOX_COMPONENTS_DISPLAY_H
9#define _LIBQBOX_COMPONENTS_DISPLAY_H
10
11#include <systemc>
12#include <scp/report.h>
13#include <string_view>
14
15#include <libgssync.h>
16#include <module_factory_registery.h>
17
18#include <libqemu/libqemu.h>
19#include <qemu-instance.h>
20#include <virtio/virtio-mmio-gpugl.h>
21#include <virtio_gpu.h>
22
31{
32private:
33 static QemuInstance* inst;
34
35 qemu::DclOps m_ops;
36 gs::runonsysc m_on_sysc;
37 bool m_realized = false;
38 std::vector<qemu::SDL2Console> m_sdl2_consoles;
39 qemu::DisplayGLCtxOps m_gl_ctx_ops;
40 bool m_instantiated = false;
41 bool m_simulation_started = false;
42
43 QemuDevice* selectGpu(sc_core::sc_object* o);
44
45public:
46 bool is_realized() const { return m_realized; }
47
48 void instantiate();
49
50 static void gl_switch(DisplayChangeListener* dcl, DisplaySurface* new_surface);
51
52 static void gl_update(DisplayChangeListener* dcl, int x, int y, int w, int h);
53
54 static void gl_refresh(DisplayChangeListener* dcl);
55
56 static void window_create(DisplayChangeListener* dcl);
57 static void window_destroy(DisplayChangeListener* dcl);
58 static void window_resize(DisplayChangeListener* dcl);
59 static void poll_events(DisplayChangeListener* dcl);
60
61 static bool is_compatible_dcl(DisplayGLCtx* ctx, DisplayChangeListener* dcl);
62
63 void realize();
64
71 MainThreadQemuDisplay(sc_core::sc_object* gpu);
72
80
88
90
91 void before_end_of_elaboration() { instantiate(); }
92
93 void end_of_elaboration() { realize(); }
94
95 void start_of_simulation(void) { m_simulation_started = true; }
96
97 QemuInstance& get_qemu_inst() { return *inst; }
98
99 bool is_instantiated() const { return m_instantiated; }
100
101 const std::vector<qemu::SDL2Console>& get_sdl2_consoles() const { return m_sdl2_consoles; }
102};
103
104QemuInstance* MainThreadQemuDisplay::inst = nullptr;
105
119class VncConfiguration : public sc_core::sc_module
120{
121 SCP_LOGGER(());
122
123public:
124 cci::cci_param<bool> p_enabled;
125
126protected:
127 std::string _qemu_opts;
128 ssize_t _display_index;
129 std::string _display_device_id;
130 std::vector<std::string> spoofed_options = { ":", "head=", "display=" };
131
132public:
141 VncConfiguration(const sc_core::sc_module_name& n, ssize_t display_index, const std::string& display_device_id)
142 : sc_module(n)
143 , _display_index(display_index)
144 , _display_device_id(display_device_id)
145 , p_enabled(std::string("enable"), false, "Default state")
146 {
147 cci::cci_param<std::string> params_input(std::string("params"), "", "Qemu VNC configuration");
148
149 if (p_enabled.get_value()) {
150 SCP_INFO(())
151 ("VNC Configuration on display: {}, device id: {} and user param: {}", display_index, display_device_id,
152 params_input.get_value());
153 build_qemu_vnc_arguments(params_input);
154 SCP_INFO(())("Qemu parameter: {}", _qemu_opts);
155 }
156 }
157
158 bool is_enabled() const { return p_enabled.get_value(); }
159
160 std::string_view get_qemu_opts() const { return std::string_view(_qemu_opts); }
161
162private:
163 void build_qemu_vnc_arguments(const std::string& user_options)
164 {
165 std::stringstream user_options_stream(user_options);
166 std::vector<std::string> option_tokens;
167
168 /* Filter out spoofed arguments */
169 for (std::string option; std::getline(user_options_stream, option, ',');) {
170 if (!option.empty() && !spoofed_opt(option)) {
171 option_tokens.push_back(option);
172 }
173 }
174
175 /* Add display index */
176 _qemu_opts.append(get_display_opt(',')).append(get_head_opt(','));
177
178 /* Append non-spoofed options */
179 for (const auto& option : option_tokens) {
180 _qemu_opts.append(option + ',');
181 }
182
183 // `Display device id` is the last in the options list
184 // and doesn't need to end with a comma
185 _qemu_opts.append(get_display_device_opt());
186 }
187
188 bool spoofed_opt(const std::string_view& option)
189 {
190 for (const std::string& spoofed_opt : spoofed_options) {
191 if (option.find(spoofed_opt) == 0) {
192 SCP_WARN(())("Option {} provided by the user will be ignored.", spoofed_opt);
193 return true;
194 }
195 }
196 return false;
197 };
198
199 std::string get_head_opt(char append_suffix = '\0')
200 {
201 std::string head_opt = "head=" + std::to_string(_display_index);
202 if (append_suffix != '\0') {
204 }
205 return head_opt;
206 }
207
208 std::string get_display_opt(char append_suffix = '\0')
209 {
210 std::string display_opt = ":" + std::to_string(_display_index);
211 if (append_suffix != '\0') {
213 };
214 return display_opt;
215 }
216
217 std::string get_display_device_opt(char append_suffix = '\0')
218 {
219 std::string display_device = "display=" + _display_device_id;
220 if (append_suffix != '\0') {
222 }
223 return display_device;
224 }
225};
226
227class display : public sc_core::sc_module
228{
229protected:
230 sc_core::sc_vector<VncConfiguration> vnc;
231
232private:
233#ifdef __APPLE__
235#endif
236
237 display (const sc_core::sc_module_name& name, QemuDevice& gpu);
238
239 bool is_vnc_enabled()
240 {
241 for (const auto& vnc_conf : vnc) {
242 if (vnc_conf.is_enabled()) {
243 return true;
244 }
245 }
246 return false;
247 }
248
249 void fill_vnc_options(std::vector<std::string>& vnc_options)
250 {
251 for (const auto& vnc_conf : vnc) {
252 if (vnc_conf.is_enabled()) {
253 vnc_options.push_back(std::string(vnc_conf.get_qemu_opts()));
254 }
255 }
256 }
257
258public:
265 display(const sc_core::sc_module_name& name, sc_core::sc_object* gpu);
266
273 display(const sc_core::sc_module_name& name, QemuVirtioGpu& gpu);
274
281 display(const sc_core::sc_module_name& name, QemuVirtioMMIOGpuGl& gpu);
282
283 void before_end_of_elaboration() override;
284
285 void end_of_elaboration() override;
286
287 void start_of_simulation() override;
288
289 QemuInstance* get_qemu_inst();
290
291 bool is_instantiated() const;
292 bool is_realized() const;
293
294 const std::vector<qemu::SDL2Console>* get_sdl2_consoles() const;
295};
296
297extern "C" void module_register();
298
299#endif // _LIBQBOX_COMPONENTS_DISPLAY_H
Qemu Display abstraction as a SystemC module.
Definition display.h:31
QEMU device abstraction as a SystemC module.
Definition device.h:37
This class encapsulates a libqemu-cxx qemu::LibQemu instance. It handles QEMU parameters and instance...
Definition qemu-instance.h:89
Definition target.h:160
Definition virtio_gpu.h:18
Definition virtio-mmio-gpugl.h:20
VNC Configuration as a systemC module.
Definition display.h:120
VncConfiguration(const sc_core::sc_module_name &n, ssize_t display_index, const std::string &display_device_id)
Construct a new VNC VncConfiguration.
Definition display.h:141
Definition display.h:228
Definition runonsysc.h:23
Definition libqemu-cxx.h:583
Definition libqemu-cxx.h:517