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