forked from chipsalliance/VeeR-ISS
-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathIoDevice.hpp
69 lines (52 loc) · 1.65 KB
/
IoDevice.hpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
#pragma once
#include <cstdint>
#include <iostream>
#include "aplic/Aplic.hpp"
namespace WdRiscv
{
class IoDevice
{
public:
/// Define a memory mapped io device at the given address using
/// size bytes of the address space.
IoDevice(uint64_t addr, uint64_t size)
: addr_(addr), size_(size), aplic_(nullptr), iid_(0)
{ }
IoDevice(uint64_t addr, uint64_t size, std::shared_ptr<TT_APLIC::Aplic> aplic, uint32_t iid)
: addr_(addr), size_(size), aplic_(iid != 0 ? aplic : nullptr), iid_(iid)
{ }
virtual ~IoDevice() = default;
/// Read a word from the device. Return 0 if address is outside
/// the device range.
virtual uint32_t read(uint64_t addr) = 0;
/// Write a word to the device. No-op if address is outside the
/// device range.
virtual void write(uint64_t addr, uint32_t value) = 0;
/// Return true if this device has a pending interrupt.
bool isInterruptPending() const
{
if (!aplic_)
return false;
return aplic_->getSourceState(iid_);
}
/// Mark this device as having/not-having a pending interrupt.
void setInterruptPending(bool flag)
{
if (aplic_)
aplic_->setSourceState(iid_, flag);
}
/// Return true if given address falls within the memory mapped
/// address range of this device.
bool isAddressInRange(uint64_t addr) const
{ return addr >= addr_ and addr - addr_ < size_; }
uint64_t address() const
{ return addr_; }
uint64_t size() const
{ return size_; }
private:
uint64_t addr_ = 0;
uint64_t size_ = 0;
std::shared_ptr<TT_APLIC::Aplic> aplic_;
uint32_t iid_;
};
}