quic/qbox
Loading...
Searching...
No Matches
ufs.h
1/*
2 * This file is part of libqbox
3 * Copyright (c) 2025 Qualcomm Innovation Center, Inc. All Rights Reserved.
4 *
5 * SPDX-License-Identifier: BSD-3-Clause
6 */
7
8#ifndef _LIBQBOX_COMPONENTS_UFS_H
9#define _LIBQBOX_COMPONENTS_UFS_H
10
11#include <systemc>
12#include <cci_configuration>
13#include <module_factory_registery.h>
14#include <device.h>
15#include <ports/target.h>
16#include <ports/qemu-initiator-signal-socket.h>
17#include <tlm_sockets_buswidth.h>
18#include <vector>
19
20class ufs : public QemuDevice
21{
22public:
23 class Device : public QemuDevice
24 {
25 friend ufs;
26
27 public:
28 Device(const sc_core::sc_module_name& name, QemuInstance& inst, const char* qom_type)
29 : QemuDevice(name, inst, qom_type)
30 {
31 }
32
33 std::function<void()> set_dev_props;
34
37 void end_of_elaboration() override {}
38
39 protected:
40 virtual void ufs_realize(qemu::Bus& ufs_bus)
41 {
42 m_dev.set_parent_bus(ufs_bus);
43 QemuDevice::end_of_elaboration();
44 }
45 };
46
47public:
48 QemuTargetSocket<> q_socket;
50
51protected:
52 cci::cci_param<std::string> p_serial;
53 cci::cci_param<uint8_t> p_nutrs;
54 cci::cci_param<uint8_t> p_nutmrs;
55 cci::cci_param<bool> p_mcq;
56 cci::cci_param<uint8_t> p_mcq_maxq;
57 std::vector<Device*> m_devices;
58
59public:
60 ufs(const sc_core::sc_module_name& name, sc_core::sc_object* o): ufs(name, *(dynamic_cast<QemuInstance*>(o))) {}
61 ufs(const sc_core::sc_module_name& n, QemuInstance& inst)
62 : QemuDevice(n, inst, "ufs-sysbus")
63 , q_socket("mem", inst)
64 , irq_out("irq_out")
65 , p_serial("serial", "", "controller serial")
66 , p_nutrs("nutrs", 32, "number of UTP transfer request slots")
67 , p_nutmrs("nutmrs", 8, "number of UTP task management request slots")
68 , p_mcq("mcq", false, "multiple command queue support")
69 , p_mcq_maxq("mcq_maxq", 2, "MCQ maximum number of queues")
70 {
71 set_id(name());
72 }
73
74 void add_device(Device& dev)
75 {
76 if (m_inst != dev.get_qemu_inst()) {
77 SCP_FATAL(SCMOD) << "UFS device and host have to be in same qemu instance";
78 }
79 m_devices.push_back(&dev);
80 }
81
82 void before_end_of_elaboration() override
83 {
84 QemuDevice::before_end_of_elaboration();
85 if (!p_serial.get_value().empty()) {
86 m_dev.set_prop_str("serial", p_serial.get_value().c_str());
87 }
88 if (!p_nutrs.is_default_value()) m_dev.set_prop_uint("nutrs", p_nutrs.get_value());
89 if (!p_nutmrs.is_default_value()) m_dev.set_prop_uint("nutmrs", p_nutmrs.get_value());
90 if (!p_mcq.is_default_value()) m_dev.set_prop_bool("mcq", p_mcq.get_value());
91 if (!p_mcq_maxq.is_default_value()) m_dev.set_prop_uint("mcq-maxq", p_mcq_maxq.get_value());
92 }
93
94 void end_of_elaboration() override
95 {
96 QemuDevice::set_sysbus_as_parent_bus();
97 QemuDevice::end_of_elaboration();
99 q_socket.init(sbd, 0);
100 irq_out.init_sbd(sbd, 0);
101
102 qemu::Bus root_bus = m_dev.get_child_bus((std::string(name()) + ".0").c_str());
103 for (Device* device : m_devices) {
104 if (device->set_dev_props) {
105 device->set_dev_props();
106 }
107 device->ufs_realize(root_bus);
108 }
109 }
110};
111
112extern "C" void module_register();
113
114#endif
QEMU device abstraction as a SystemC module.
Definition device.h:37
A QEMU output GPIO exposed as a InitiatorSignalSocket<bool>
Definition qemu-initiator-signal-socket.h:40
void init_sbd(qemu::SysBusDevice sbd, int gpio_idx)
Initialize this socket with a QEMU SysBusDevice, and a GPIO index.
Definition qemu-initiator-signal-socket.h:173
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 libqemu-cxx.h:721
Definition libqemu-cxx.h:627
Definition ufs.h:24
void end_of_elaboration() override
We cannot do the end_of_elaboration at this point because we need the UFS bus (created only during th...
Definition ufs.h:37
Definition ufs.h:21