quic/qbox
Loading...
Searching...
No Matches
riscv32.h
1/*
2 * This file is part of libqbox
3 * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All Rights Reserved.
4 *
5 * SPDX-License-Identifier: BSD-3-Clause
6 */
7
8#pragma once
9
10#include <string>
11#include <functional>
12
13#include <cci_configuration>
14#include <libqemu-cxx/target/riscv.h>
15
16#include <libgssync.h>
17#include <module_factory_registery.h>
18
19#include <cpu.h>
20#include <ports/qemu-target-signal-socket.h>
21#include <ports/qemu-initiator-signal-socket.h>
22
23class QemuCpuRiscv32 : public QemuCpu
24{
25protected:
26 uint64_t m_hartid;
27 gs::async_event m_irq_ev;
28
29 void mip_update_cb(uint32_t value)
30 {
31 if (value) {
32 m_irq_ev.notify();
33 }
34 }
35
36public:
37 // IRQ input sockets - sc_vector of 32 IRQs
38 sc_core::sc_vector<QemuTargetSignalSocket> irq_in;
39
40 // CCI parameters for RISC-V CPU configuration
41 cci::cci_param<uint64_t> p_hartid;
42 cci::cci_param<bool> p_debug;
43 cci::cci_param<bool> p_pmp;
44 cci::cci_param<bool> p_mmu;
45 cci::cci_param<std::string> p_priv_spec;
46 cci::cci_param<uint64_t> p_cbom_blocksize;
47 cci::cci_param<uint64_t> p_cbop_blocksize;
48 cci::cci_param<uint64_t> p_cboz_blocksize;
49 cci::cci_param<uint64_t> p_mvendorid;
50 cci::cci_param<uint64_t> p_mimpid;
51 cci::cci_param<uint64_t> p_marchid;
52 cci::cci_param<uint64_t> p_resetvec;
53 QemuCpuRiscv32(const sc_core::sc_module_name& name, QemuInstance& inst, const char* model, uint64_t hartid)
54 : QemuCpu(name, inst, std::string(model) + "-riscv")
55 , m_hartid(hartid)
56 /*
57 * We have no choice but to attach-suspend here. This is fixable but
58 * non-trivial. It means that the SystemC kernel will never starve...
59 */
60 , m_irq_ev(true)
61 // Initialize IRQ vector with 32 sockets
62 , irq_in("irq_in", 32)
63 // Initialize CCI parameters with default values
64 , p_hartid("hartid", hartid, "Hardware thread ID")
65 , p_debug("debug", true, "Enable debug support")
66 , p_pmp("pmp", false, "Enable Physical Memory Protection")
67 , p_mmu("mmu", true, "Enable Memory Management Unit")
68 , p_priv_spec("priv_spec", "v1.12.0", "Privilege specification version")
69 , p_cbom_blocksize("cbom_blocksize", 64, "Cache block management operation block size")
70 , p_cbop_blocksize("cbop_blocksize", 64, "Cache block prefetch operation block size")
71 , p_cboz_blocksize("cboz_blocksize", 64, "Cache block zero operation block size")
72 , p_mvendorid("mvendorid", 0, "Vendor ID")
73 , p_mimpid("mimpid", 0, "Implementation ID")
74 , p_marchid("marchid", 0, "Architecture ID")
75 , p_resetvec("resetvec", 0x0, "Reset vector address")
76 {
77 m_external_ev |= m_irq_ev;
78 for (auto& irq : irq_in) {
79 m_external_ev |= irq->default_event();
80 }
81 }
82
83 void before_end_of_elaboration()
84 {
85 QemuCpu::before_end_of_elaboration();
86
87 qemu::CpuRiscv32 cpu(get_qemu_dev());
88 cpu.set_prop_int("hartid", p_hartid);
89
90 // Set properties from CCI parameters
91 cpu.set_prop_int("resetvec", p_resetvec);
92 cpu.set_prop_bool("debug", p_debug);
93 cpu.set_prop_bool("pmp", p_pmp);
94 cpu.set_prop_bool("mmu", p_mmu);
95 cpu.set_prop_str("priv_spec", p_priv_spec.get_value().c_str());
96
97 // Cache block operation sizes
98 cpu.set_prop_int("cbom_blocksize", p_cbom_blocksize);
99 cpu.set_prop_int("cbop_blocksize", p_cbop_blocksize);
100 cpu.set_prop_int("cboz_blocksize", p_cboz_blocksize);
101
102 // Vendor ID settings
103 cpu.set_prop_int("mvendorid", p_mvendorid);
104 cpu.set_prop_int("mimpid", p_mimpid);
105 cpu.set_prop_int("marchid", p_marchid);
106
107 cpu.set_mip_update_callback(std::bind(&QemuCpuRiscv32::mip_update_cb, this, std::placeholders::_1));
108 }
109
110 void end_of_elaboration() override
111 {
112 QemuCpu::end_of_elaboration();
113
114 // Initialize IRQ sockets with GPIO pin numbers 0-31
115 for (int i = 0; i < 32; i++) {
116 irq_in[i].init(m_dev, i);
117 }
118
119 // Register reset handler - needed for proper reset behavior when system reset is requested
120 qemu::CpuRiscv32 cpu(get_qemu_dev());
121 cpu.register_reset();
122 }
123};
124
126{
127public:
128 static constexpr qemu::Target ARCH = qemu::Target::RISCV32;
129
130 cpu_riscv32(const sc_core::sc_module_name& name, sc_core::sc_object* o, uint64_t hartid)
131 : cpu_riscv32(name, *(dynamic_cast<QemuInstance*>(o)), hartid)
132 {
133 }
134 cpu_riscv32(const sc_core::sc_module_name& n, QemuInstance& inst, uint64_t hartid)
135 : QemuCpuRiscv32(n, inst, "rv32", hartid)
136 {
137 }
138 // Constructor for test framework compatibility (uses hartid=0 by default)
139 cpu_riscv32(const sc_core::sc_module_name& n, QemuInstance& inst): QemuCpuRiscv32(n, inst, "rv32", 0) {}
140};
141
142extern "C" void module_register();
Definition riscv32.h:24
Definition cpu.h:30
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 riscv32.h:126
Definition async_event.h:22
Definition riscv.h:30