quic/qbox
Loading...
Searching...
No Matches
pflash_cfi.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_PFLASH_CFI_H
9#define _LIBQBOX_COMPONENTS_PFLASH_CFI_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
17class pflash_cfi : public QemuDevice
18{
19public:
20 QemuTargetSocket<> socket;
21
22private:
23 uint8_t m_pflash_type;
24 std::string blkdev_id;
25 cci::cci_param<std::string> blkdev_str;
26 cci::cci_param<uint32_t> p_num_blocks;
27 cci::cci_param<uint32_t> p_sector_length;
28 cci::cci_param<uint32_t> p_num_blocks0;
29 cci::cci_param<uint32_t> p_sector_length0;
30 cci::cci_param<uint32_t> p_num_blocks1;
31 cci::cci_param<uint32_t> p_sector_length1;
32 cci::cci_param<uint32_t> p_num_blocks2;
33 cci::cci_param<uint32_t> p_sector_length2;
34 cci::cci_param<uint32_t> p_num_blocks3;
35 cci::cci_param<uint32_t> p_sector_length3;
36 cci::cci_param<uint8_t> p_width;
37 cci::cci_param<uint8_t> p_device_width;
38 cci::cci_param<uint8_t> p_max_device_width;
39 cci::cci_param<uint8_t> p_secure;
40 cci::cci_param<bool> p_old_multiple_chip_handling;
41 cci::cci_param<uint8_t> p_mappings;
42 cci::cci_param<uint8_t> p_big_endian;
43 cci::cci_param<uint16_t> p_id0;
44 cci::cci_param<uint16_t> p_id1;
45 cci::cci_param<uint16_t> p_id2;
46 cci::cci_param<uint16_t> p_id3;
47 cci::cci_param<uint16_t> p_unlock_addr0;
48 cci::cci_param<uint16_t> p_unlock_addr1;
49 cci::cci_param<std::string> p_name;
50
51public:
52 pflash_cfi(const sc_core::sc_module_name& name, sc_core::sc_object* o, uint8_t pflash_type)
53 : pflash_cfi(name, *(dynamic_cast<QemuInstance*>(o)), pflash_type)
54 {
55 }
56 pflash_cfi(const sc_core::sc_module_name& n, QemuInstance& inst, uint8_t pflash_type)
57 : QemuDevice(n, inst, (pflash_type == 1) ? "cfi.pflash01" : "cfi.pflash02")
58 , m_pflash_type(pflash_type)
59 , socket("target_socket", inst)
60 , blkdev_id(std::string(name()) + "-id")
61 , blkdev_str("blkdev_str", "", "blkdev string for QEMU (do not specify ID)")
62 , p_num_blocks("num_blocks", 0,
63 "number of blocks actually visible to the guest, i.e. the total size of the device divided by "
64 "the sector length")
65 , p_sector_length("sector_length", 0, "sector length")
66 , p_num_blocks0("num_blocks0", 0, "number of blocks 0")
67 , p_sector_length0("sector_length0", 0, "sector length for 0")
68 , p_num_blocks1("num_blocks1", 0, "number of blocks 1")
69 , p_sector_length1("sector_length1", 0, "sector length for 1")
70 , p_num_blocks2("num_blocks2", 0, "number of blocks 2")
71 , p_sector_length2("sector_length2", 0, "sector length for 2")
72 , p_num_blocks3("num_blocks3", 0, "number of blocks 3")
73 , p_sector_length3("sector_length3", 0, "sector length for 3")
74 , p_width("width", 0, "the overall width of this QEMU device in bytes.")
75 , p_device_width("device_width", 0, "the width of each flash device")
76 , p_max_device_width("max_device_width", 0, "the maximum width of each flash device")
77 , p_secure("secure", 0, "secure bit (uint8_t)")
78 , p_old_multiple_chip_handling("old_multiple_chip_handling", false, "old multiple chip handling (bool)")
79 , p_mappings("mappings", 0, "flash mapping")
80 , p_big_endian("big_endian", 0, "is big endian (uint8_t)")
81 , p_id0("id0", 0, "id of 0")
82 , p_id1("id1", 0, "id of 1")
83 , p_id2("id2", 0, "id of 2")
84 , p_id3("id3", 0, "id of 3")
85 , p_unlock_addr0("unlock_addr0", 0, "unlock address 0")
86 , p_unlock_addr1("unlock_addr1", 0, "unlock address 1")
87 , p_name("name", "", "name of the device")
88 {
89 if (!blkdev_str.get_value().empty()) {
90 std::stringstream opts;
91 opts << blkdev_str.get_value();
92 opts << ",id=" << blkdev_id;
93
94 m_inst.add_arg("-drive");
95 m_inst.add_arg(opts.str().c_str());
96 }
97 }
98
99 void before_end_of_elaboration() override
100 {
101 QemuDevice::before_end_of_elaboration();
102 if (!p_name.get_value().empty()) m_dev.set_prop_str("name", p_name.get_value().c_str());
103 if (!p_num_blocks.is_default_value()) m_dev.set_prop_uint("num-blocks", p_num_blocks.get_value());
104 if (!p_sector_length.is_default_value()) m_dev.set_prop_uint("sector-length", p_sector_length.get_value());
105 if (m_pflash_type == 2) {
106 if (!p_num_blocks0.is_default_value()) m_dev.set_prop_uint("num-blocks0", p_num_blocks0.get_value());
107 if (!p_sector_length0.is_default_value())
108 m_dev.set_prop_uint("sector-length0", p_sector_length0.get_value());
109 if (!p_num_blocks1.is_default_value()) m_dev.set_prop_uint("num-blocks1", p_num_blocks1.get_value());
110 if (!p_sector_length1.is_default_value())
111 m_dev.set_prop_uint("sector-length1", p_sector_length1.get_value());
112 if (!p_num_blocks2.is_default_value()) m_dev.set_prop_uint("num-blocks2", p_num_blocks2.get_value());
113 if (!p_sector_length2.is_default_value())
114 m_dev.set_prop_uint("sector-length2", p_sector_length2.get_value());
115 if (!p_num_blocks3.is_default_value()) m_dev.set_prop_uint("num-blocks3", p_num_blocks3.get_value());
116 if (!p_sector_length3.is_default_value())
117 m_dev.set_prop_uint("sector-length3", p_sector_length3.get_value());
118 }
119 if (!p_width.is_default_value()) m_dev.set_prop_uint("width", p_width.get_value());
120 if (m_pflash_type == 1) {
121 if (!p_device_width.is_default_value()) m_dev.set_prop_uint("device-width", p_device_width.get_value());
122 if (!p_max_device_width.is_default_value())
123 m_dev.set_prop_uint("max-device-width", p_max_device_width.get_value());
124 if (!p_secure.is_default_value()) m_dev.set_prop_uint("secure", p_secure.get_value());
125 if (!p_old_multiple_chip_handling.is_default_value())
126 m_dev.set_prop_bool("old-multiple-chip-handling", p_old_multiple_chip_handling.get_value());
127 }
128 if (!p_mappings.is_default_value()) m_dev.set_prop_uint("mappings", p_mappings.get_value());
129 if (!p_big_endian.is_default_value()) m_dev.set_prop_uint("big-endian", p_big_endian.get_value());
130 if (!p_id0.is_default_value()) m_dev.set_prop_uint("id0", p_id0.get_value());
131 if (!p_id1.is_default_value()) m_dev.set_prop_uint("id1", p_id1.get_value());
132 if (!p_id2.is_default_value()) m_dev.set_prop_uint("id2", p_id2.get_value());
133 if (!p_id3.is_default_value()) m_dev.set_prop_uint("id3", p_id3.get_value());
134 if (!p_unlock_addr0.is_default_value()) m_dev.set_prop_uint("unlock-addr0", p_unlock_addr0.get_value());
135 if (!p_unlock_addr1.is_default_value()) m_dev.set_prop_uint("unlock-addr1", p_unlock_addr1.get_value());
136 if (!blkdev_str.get_value().empty()) {
137 m_dev.set_prop_parse("drive", blkdev_id.c_str());
138 }
139 }
140
141 void end_of_elaboration() override
142 {
143 QemuDevice::set_sysbus_as_parent_bus();
144 QemuDevice::end_of_elaboration();
145
146 qemu::SysBusDevice sbd(m_dev);
147
148 socket.init(sbd, 0);
149 }
150};
151
152extern "C" void module_register();
153
154#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
void add_arg(const char *arg)
Add a command line argument to the qemu instance.
Definition qemu-instance.h:327
Definition target.h:160
Definition pflash_cfi.h:18
Definition libqemu-cxx.h:645