PatchworkOS  2ca1c69
A non-POSIX operating system.
Loading...
Searching...
No Matches
io.h
Go to the documentation of this file.
1#pragma once
2
3#include <stdint.h>
4
5/**
6 * @brief I/O port operations and reservations
7 * @defgroup kernel_cpu_io Port I/O
8 * @ingroup kernel_cpu
9 *
10 * The CPU can communicate with certain hardware through I/O ports, these ports are accessed using special opcodes.
11 *
12 * ## Reserving I/O Ports
13 *
14 * To avoid conflicts between different subsystems or drivers trying to use the same I/O ports, we provide a simple
15 * reservation mechanism. Before a range of I/O ports is used, it should be reserved using `io_reserve()`. Once the
16 * ports are no longer needed, they should be released using `io_release()`.
17 *
18 * There is no strict enforcement of I/O port reservations at the hardware level, so we have no choice but to hope that
19 * everyone is on their best behaviour.
20 *
21 * @{
22 */
23
24/**
25 * @brief I/O port type
26 */
28
29/**
30 * @brief Maximum I/O port number
31 */
32#define IO_PORT_MAX UINT16_MAX
33
34/**
35 * @brief Find and reserve a range of I/O ports if available.
36 *
37 * @note The `minBase` and `maxBase` do NOT specify the exact range to reserve, but rather the minimum and maximum
38 * values for the starting port of the range to reserve. For example, the minimum range would be `[minBase, minBase +
39 * length)` and the maximum range would be `[maxBase, maxBase + length)`.
40 *
41 * @todo Find a way to store the owner of each reservation that does not use way to much memory, and isent super slow.
42 *
43 * @param out Output pointer for the first reserved port.
44 * @param minBase The minimum base I/O port address.
45 * @param maxBase The maximum base I/O port address.
46 * @param alignment The alignment of the I/O ports to reserve.
47 * @param length The amount of contiguous I/O ports to reserve.
48 * @param owner A string identifying the owner of the reservation, for debugging purposes, can be `NULL`.
49 * @return On success, `0`. On failure, `ERR` and `errno` is set to:
50 * - `EINVAL`: Invalid parameters.
51 * - `EOVERFLOW`: The requested range overflows.
52 * - `ENOSPC`: No suitable range of I/O ports available.
53 */
54uint64_t io_reserve(port_t* out, port_t minBase, port_t maxBase, uint64_t alignment, uint64_t length,
55 const char* owner);
56
57/**
58 * @brief Release a previously reserved range of I/O ports.
59 *
60 * @param base The base I/O port address of the reserved range.
61 * @param length The amount of contiguous I/O ports to release.
62 */
63void io_release(port_t base, uint64_t length);
64
65/**
66 * @brief Write an 8-bit value to an I/O port.
67 *
68 * @param port The I/O port to write to.
69 * @param val The value to write.
70 */
71static inline void io_out8(port_t port, uint8_t val)
72{
73 asm volatile("outb %0, %1" : : "a"(val), "Nd"(port) : "memory");
74}
75
76/**
77 * @brief Read an 8-bit value from an I/O port.
78 *
79 * @param port The I/O port to read from.
80 * @return The value read from the port.
81 */
82static inline uint8_t io_in8(port_t port)
83{
84 uint8_t ret;
85 asm volatile("inb %1, %0" : "=a"(ret) : "Nd"(port) : "memory");
86 return ret;
87}
88
89/**
90 * @brief Write a 16-bit value to an I/O port.
91 *
92 * @param port The I/O port to write to.
93 * @param val The value to write.
94 */
95static inline void io_out16(port_t port, uint16_t val)
96{
97 asm volatile("outw %0, %1" : : "a"(val), "Nd"(port) : "memory");
98}
99
100/**
101 * @brief Read a 16-bit value from an I/O port.
102 *
103 * @param port The I/O port to read from.
104 * @return The value read from the port.
105 */
106static inline uint16_t io_in16(port_t port)
107{
108 uint16_t ret;
109 asm volatile("inw %1, %0" : "=a"(ret) : "Nd"(port) : "memory");
110 return ret;
111}
112
113/**
114 * @brief Write a 32-bit value to an I/O port.
115 *
116 * @param port The I/O port to write to.
117 * @param val The value to write.
118 */
119static inline uint32_t io_in32(port_t port)
120{
121 uint32_t ret;
122 asm volatile("inl %1, %0" : "=a"(ret) : "Nd"(port) : "memory");
123 return ret;
124}
125
126/**
127 * @brief Read a 32-bit value from an I/O port.
128 *
129 * @param port The I/O port to read from.
130 * @return The value read from the port.
131 */
132static inline void io_out32(port_t port, uint32_t val)
133{
134 asm volatile("outl %0, %1" : : "a"(val), "Nd"(port) : "memory");
135}
136
137/** @} */
static void io_out8(port_t port, uint8_t val)
Write an 8-bit value to an I/O port.
Definition io.h:71
static void io_out32(port_t port, uint32_t val)
Read a 32-bit value from an I/O port.
Definition io.h:132
static uint16_t io_in16(port_t port)
Read a 16-bit value from an I/O port.
Definition io.h:106
uint64_t io_reserve(port_t *out, port_t minBase, port_t maxBase, uint64_t alignment, uint64_t length, const char *owner)
Find and reserve a range of I/O ports if available.
Definition io.c:15
static void io_out16(port_t port, uint16_t val)
Write a 16-bit value to an I/O port.
Definition io.h:95
void io_release(port_t base, uint64_t length)
Release a previously reserved range of I/O ports.
Definition io.c:43
static uint8_t io_in8(port_t port)
Read an 8-bit value from an I/O port.
Definition io.h:82
uint16_t port_t
I/O port type.
Definition io.h:27
static uint32_t io_in32(port_t port)
Write a 32-bit value to an I/O port.
Definition io.h:119
__UINT32_TYPE__ uint32_t
Definition stdint.h:15
__UINT64_TYPE__ uint64_t
Definition stdint.h:17
__UINT8_TYPE__ uint8_t
Definition stdint.h:11
__UINT16_TYPE__ uint16_t
Definition stdint.h:13