quic/qbox
Loading...
Searching...
No Matches
fw_cfg.h
1/*
2 * This file is part of libqbox
3 * Copyright (c) 2026 Qualcomm Innovation Center, Inc. All Rights Reserved.
4 *
5 * SPDX-License-Identifier: BSD-3-Clause
6 */
7
8#ifndef _LIBQBOX_COMPONENTS_FW_CFG_H
9#define _LIBQBOX_COMPONENTS_FW_CFG_H
10
11#include <cci_configuration>
12#include <module_factory_registery.h>
13#include <qemu-instance.h>
14#include <device.h>
15#include <ports/target.h>
16#include <limits>
17#include <memory>
18#include <vector>
19#include <fstream>
20#include <filesystem>
21
22class fw_cfg : public QemuDevice
23{
24public:
25 QemuTargetSocket<> ctl_target_socket;
26 QemuTargetSocket<> data_target_socket;
27 QemuTargetSocket<> dma_target_socket;
28
29private:
30 QemuInstance& m_inst;
31 cci::cci_param<uint32_t> p_data_width;
32 cci::cci_param<uint32_t> p_num_cpus;
33 cci::cci_param<std::string> p_acpi_tables;
34 std::vector<uint8_t> acpi_tables_data;
35 cci::cci_param<std::string> p_acpi_tables_linker;
36 std::vector<uint8_t> acpi_tables_linker_data;
37 cci::cci_param<std::string> p_acpi_rsdp;
38 std::vector<uint8_t> acpi_rsdp_data;
39 const uint16_t fw_cfg_num_cpus = 0x05;
40 FWCfgState* fw_cfg_ptr;
41
42public:
43 fw_cfg(const sc_core::sc_module_name& name, sc_core::sc_object* o): fw_cfg(name, *(dynamic_cast<QemuInstance*>(o)))
44 {
45 }
46 fw_cfg(const sc_core::sc_module_name& n, QemuInstance& inst)
47 : QemuDevice(n, inst, "fw_cfg_mem")
48 , m_inst(inst)
49 , ctl_target_socket("ctl_target_socket", inst)
50 , data_target_socket("data_target_socket", inst)
51 , dma_target_socket("dma_target_socket", inst)
52 , p_data_width("data_width", std::numeric_limits<uint32_t>::max(), "data width")
53 , p_num_cpus("num_cpus", 1, "number of cpus used in the platform")
54 , p_acpi_tables("acpi_tables", "", "acpi tables blob binary file path")
55 , p_acpi_tables_linker("acpi_tables_linker", "", "acpi tables linker blob binary file path")
56 , p_acpi_rsdp("acpi_rsdp", "", "acpi rsdp blob binary file path")
57 {
58 }
59
60 void file_load(const std::string& filename, std::vector<uint8_t>& file_data)
61 {
62 if (!std::filesystem::exists(filename)) {
63 SCP_FATAL(()) << "file_load() -> error: file not found! (" << filename << ")";
64 }
65 auto len = std::filesystem::file_size(filename);
66 if (!len) {
67 SCP_FATAL(()) << "file_load() -> error: file size is 0! (" << filename << ")";
68 }
69 std::ifstream fin(filename, std::ios::in | std::ios::binary);
70 if (!fin.good()) {
71 SCP_FATAL(()) << "file_load() -> error: Can't open file for read! (" << filename << ")";
72 }
73 fin.seekg(0, std::ios::beg);
74 file_data.resize(len);
75 fin.read(reinterpret_cast<char*>(file_data.data()), len);
76 fin.close();
77 }
78
79 void before_end_of_elaboration() override
80 {
81 QemuDevice::before_end_of_elaboration();
82 m_dev.set_prop_bool("dma_enabled", true);
83 if (!p_data_width.is_default_value()) m_dev.set_prop_uint("data_width", p_data_width.get_value());
84 fw_cfg_ptr = m_inst.get().fw_cfg_find();
85 if (!fw_cfg_ptr) {
86 SCP_FATAL(()) << "fw_cfg device was not found!";
87 }
88 m_inst.get().fw_cfg_set_dma_as(fw_cfg_ptr);
89 }
90
91 void end_of_elaboration() override
92 {
93 QemuDevice::set_sysbus_as_parent_bus();
94 QemuDevice::end_of_elaboration();
96 ctl_target_socket.init(sbd, 0);
97 data_target_socket.init(sbd, 1);
98 dma_target_socket.init(sbd, 2);
99 m_inst.get().fw_cfg_add_i16(fw_cfg_ptr, fw_cfg_num_cpus, p_num_cpus.get_value());
100 if (!p_acpi_tables.get_value().empty()) {
101 file_load(p_acpi_tables.get_value(), acpi_tables_data);
102 m_inst.get().fw_cfg_modify_file(fw_cfg_ptr, "etc/acpi/tables",
103 reinterpret_cast<void*>(acpi_tables_data.data()), acpi_tables_data.size());
104 }
105 if (!p_acpi_tables_linker.get_value().empty()) {
106 file_load(p_acpi_tables_linker.get_value(), acpi_tables_linker_data);
107 m_inst.get().fw_cfg_modify_file(fw_cfg_ptr, "etc/table-loader",
108 reinterpret_cast<void*>(acpi_tables_linker_data.data()),
109 acpi_tables_linker_data.size());
110 }
111 if (!p_acpi_rsdp.get_value().empty()) {
112 file_load(p_acpi_rsdp.get_value(), acpi_rsdp_data);
113 m_inst.get().fw_cfg_modify_file(fw_cfg_ptr, "etc/acpi/rsdp", reinterpret_cast<void*>(acpi_rsdp_data.data()),
114 acpi_rsdp_data.size());
115 }
116 }
117};
118
119extern "C" void module_register();
120
121#endif
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:86
qemu::LibQemu & get()
Returns the underlying qemu::LibQemu instance.
Definition qemu-instance.h:471
Definition target.h:160
Definition fw_cfg.h:23
Definition libqemu-cxx.h:645