SimpleKernel 1.17.0
Loading...
Searching...
No Matches
plic.h
Go to the documentation of this file.
1
5#pragma once
6
7#include <cpu_io.h>
8
9#include <array>
10#include <cstddef>
11#include <cstdint>
12#include <tuple>
13
14#include "interrupt_base.h"
15
20class Plic {
21 public:
23
25 static constexpr size_t kInterruptMaxCount = 16;
26
31 [[nodiscard]] auto Which() const -> uint32_t;
32
37 auto Done(uint32_t source_id) const -> void;
38
46 auto Set(uint32_t hart_id, uint32_t source_id, uint32_t priority,
47 bool enable) const -> void;
48
55 [[nodiscard]] auto Get(uint32_t hart_id, uint32_t source_id) const
56 -> std::tuple<uint32_t, bool, bool>;
57
63 auto RegisterInterruptFunc(uint8_t cause, InterruptDelegate func) -> void;
64
70 auto Do(uint64_t cause, cpu_io::TrapContext* context) -> void;
71
74
81 explicit Plic(uint64_t dev_addr, size_t ndev, size_t context_count);
82
83 Plic() = default;
84 Plic(const Plic&) = default;
85 Plic(Plic&&) = default;
86 auto operator=(const Plic&) -> Plic& = default;
87 auto operator=(Plic&&) -> Plic& = default;
88 ~Plic() = default;
90
91 private:
92 static constexpr uint64_t kSourcePriorityOffset = 0x000000;
93 static constexpr uint64_t kPendingBitsOffset = 0x001000;
94 static constexpr uint64_t kEnableBitsOffset = 0x002000;
95 static constexpr uint64_t kContextOffset = 0x200000;
96
97 // 每个 context 的大小和偏移
98 static constexpr uint64_t kContextSize = 0x1000;
99 static constexpr uint64_t kPriorityThresholdOffset = 0x0;
100 static constexpr uint64_t kClaimCompleteOffset = 0x4;
101
102 // Enable bits 每个 context 的大小 (最多支持 1024 个中断源)
103 static constexpr uint64_t kEnableSize = 0x80;
104
107
108 uint64_t base_addr_{0};
109 size_t ndev_{0};
110 size_t context_count_{0};
111
119 [[nodiscard]] __always_inline auto GetContextId(uint32_t hart_id,
120 uint32_t mode = 1) const
121 -> uint32_t {
122 return hart_id * 2 + mode;
123 }
124
131 [[nodiscard]] auto GetEnableBit(uint32_t context_id, uint32_t source_id) const
132 -> bool;
133
140 auto SetEnableBit(uint32_t context_id, uint32_t source_id, bool value) const
141 -> void;
142
148 [[nodiscard]] auto SourcePriority(uint32_t source_id) const -> uint32_t&;
149
155 [[nodiscard]] auto GetPendingBit(uint32_t source_id) const -> bool;
156
162 auto SetPendingBit(uint32_t source_id, bool value) const -> void;
163
169 [[nodiscard]] auto PriorityThreshold(uint32_t context_id) const -> uint32_t&;
170
176 [[nodiscard]] auto ClaimComplete(uint32_t context_id) const -> uint32_t&;
177};
etl::delegate< uint64_t(uint64_t, cpu_io::TrapContext *)> InterruptDelegate
类型安全的中断处理委托
Plic 驱动
Definition plic.h:20
auto Set(uint32_t hart_id, uint32_t source_id, uint32_t priority, bool enable) const -> void
设置指定中断源的使能状态
Definition plic.cpp:70
size_t ndev_
Definition plic.h:109
static constexpr uint64_t kEnableSize
Definition plic.h:103
auto GetEnableBit(uint32_t context_id, uint32_t source_id) const -> bool
获取使能位寄存器中指定中断源的状态
Definition plic.cpp:95
uint64_t base_addr_
Definition plic.h:108
auto Done(uint32_t source_id) const -> void
告知 Plic 已经处理了当前 IRQ
Definition plic.cpp:56
size_t context_count_
Definition plic.h:110
auto PriorityThreshold(uint32_t context_id) const -> uint32_t &
获取优先级阈值寄存器
Definition plic.cpp:143
auto SourcePriority(uint32_t source_id) const -> uint32_t &
获取中断源优先级寄存器
Definition plic.cpp:118
static constexpr uint64_t kPendingBitsOffset
Definition plic.h:93
auto Which() const -> uint32_t
向 Plic 询问中断
Definition plic.cpp:51
auto GetPendingBit(uint32_t source_id) const -> bool
获取挂起位寄存器中指定中断源的状态
Definition plic.cpp:123
auto SetEnableBit(uint32_t context_id, uint32_t source_id, bool value) const -> void
设置使能位寄存器中指定中断源的状态
Definition plic.cpp:104
static constexpr uint64_t kPriorityThresholdOffset
Definition plic.h:99
auto ClaimComplete(uint32_t context_id) const -> uint32_t &
获取声明/完成寄存器
Definition plic.cpp:149
static constexpr uint64_t kContextSize
Definition plic.h:98
static constexpr uint64_t kContextOffset
Definition plic.h:95
static constexpr uint64_t kClaimCompleteOffset
Definition plic.h:100
auto Get(uint32_t hart_id, uint32_t source_id) const -> std::tuple< uint32_t, bool, bool >
获取指定中断源的状态信息
Definition plic.cpp:80
auto Do(uint64_t cause, cpu_io::TrapContext *context) -> void
执行外部中断处理
Definition plic.cpp:66
static constexpr uint64_t kEnableBitsOffset
Definition plic.h:94
__always_inline auto GetContextId(uint32_t hart_id, uint32_t mode=1) const -> uint32_t
计算 context ID
Definition plic.h:119
static constexpr size_t kInterruptMaxCount
最大外部中断数量
Definition plic.h:25
static constexpr uint64_t kSourcePriorityOffset
Definition plic.h:92
InterruptBase::InterruptDelegate InterruptDelegate
Definition plic.h:22
auto SetPendingBit(uint32_t source_id, bool value) const -> void
设置挂起位寄存器中指定中断源的状态
Definition plic.cpp:131
auto RegisterInterruptFunc(uint8_t cause, InterruptDelegate func) -> void
注册外部中断处理函数
Definition plic.cpp:61
static std::array< InterruptDelegate, kInterruptMaxCount > interrupt_handlers_
外部中断处理函数数组
Definition plic.h:106