SimpleKernel 1.17.0
Loading...
Searching...
No Matches
io_buffer.hpp
Go to the documentation of this file.
1
5#pragma once
6
7#include <cstddef>
8#include <cstdint>
9#include <span>
10
11#include "expected.hpp"
12
18using VirtToPhysFunc = auto (*)(uintptr_t virt) -> uintptr_t;
19
25[[nodiscard]] inline auto IdentityVirtToPhys(uintptr_t virt) -> uintptr_t {
26 return virt;
27}
28
37struct DmaRegion {
39 void* virt{nullptr};
41 uintptr_t phys{0};
43 size_t size{0};
44
46 [[nodiscard]] auto IsValid() const -> bool {
47 return virt != nullptr && size > 0;
48 }
49
52 [[nodiscard]] auto Data() const -> uint8_t* {
53 return static_cast<uint8_t*>(virt);
54 }
55
66 [[nodiscard]] auto SubRegion(size_t offset, size_t len) const
68 if (offset > size || len > size - offset) {
69 return std::unexpected(Error{ErrorCode::kInvalidArgument});
70 }
71 return DmaRegion{
72 .virt = static_cast<uint8_t*>(virt) + offset,
73 .phys = phys + offset,
74 .size = len,
75 };
76 }
77};
78
85class IoBuffer {
86 public:
88 static constexpr size_t kDefaultAlignment = 4096;
89
96 [[nodiscard]] auto GetBuffer() const -> std::span<const uint8_t>;
97
104 [[nodiscard]] auto GetBuffer() -> std::span<uint8_t>;
105
112 [[nodiscard]] auto IsValid() const -> bool;
113
123 [[nodiscard]] auto ToDmaRegion(VirtToPhysFunc v2p = IdentityVirtToPhys) const
124 -> DmaRegion;
125
128 IoBuffer() = default;
129
137 explicit IoBuffer(size_t size, size_t alignment = kDefaultAlignment);
138
139 ~IoBuffer();
140
141 IoBuffer(const IoBuffer&) = delete;
142 auto operator=(const IoBuffer&) -> IoBuffer& = delete;
143
144 IoBuffer(IoBuffer&& other);
145 auto operator=(IoBuffer&& other) noexcept -> IoBuffer&;
147
148 private:
150 uint8_t* data_{nullptr};
152 size_t size_{0};
153};
动态分配、对齐 IO 缓冲区的 RAII 封装
Definition io_buffer.hpp:85
auto GetBuffer() const -> std::span< const uint8_t >
获取缓冲区数据与大小 (只读)
Definition io_buffer.cpp:48
uint8_t * data_
缓冲区数据指针
auto ToDmaRegion(VirtToPhysFunc v2p=IdentityVirtToPhys) const -> DmaRegion
创建此缓冲区的 DmaRegion 视图
Definition io_buffer.cpp:56
size_t size_
缓冲区大小
auto IsValid() const -> bool
检查缓冲区是否有效
Definition io_buffer.cpp:54
static constexpr size_t kDefaultAlignment
IO 缓冲区的默认对齐大小(如页大小)
Definition io_buffer.hpp:88
@ kInvalidArgument
std::expected< T, Error > Expected
std::expected 别名模板
Definition expected.hpp:365
auto IdentityVirtToPhys(uintptr_t virt) -> uintptr_t
恒等映射:物理地址 == 虚拟地址(早期启动 / 无 MMU 时的默认实现)
Definition io_buffer.hpp:25
auto(*)(uintptr_t virt) -> uintptr_t VirtToPhysFunc
虚拟地址到物理地址转换回调类型
Definition io_buffer.hpp:18
DMA 可访问内存区域的非拥有描述符
Definition io_buffer.hpp:37
auto Data() const -> uint8_t *
获取虚拟基地址的类型化指针
Definition io_buffer.hpp:52
void * virt
虚拟(CPU 可访问)基地址
Definition io_buffer.hpp:39
size_t size
区域大小(字节)
Definition io_buffer.hpp:43
auto SubRegion(size_t offset, size_t len) const -> Expected< DmaRegion >
在指定偏移处创建子区域
Definition io_buffer.hpp:66
auto IsValid() const -> bool
检查区域是否有效(非空指针且大小非零)
Definition io_buffer.hpp:46
uintptr_t phys
物理(总线/DMA)基地址
Definition io_buffer.hpp:41
错误类型,用于 std::expected
Definition expected.hpp:343