From 087a00beaa3e943879c74677e6f91df71d5ea517 Mon Sep 17 00:00:00 2001
From: sbosse <sbosse@uni-bremen.de>
Date: Mon, 14 Oct 2024 23:06:55 +0200
Subject: [PATCH] Mon 14 Oct 23:06:38 CEST 2024

---
 kernel/ioports.h | 101 +++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 101 insertions(+)
 create mode 100644 kernel/ioports.h

diff --git a/kernel/ioports.h b/kernel/ioports.h
new file mode 100644
index 0000000..6d30ab7
--- /dev/null
+++ b/kernel/ioports.h
@@ -0,0 +1,101 @@
+/*
+Copyright (C) 2015-2019 The University of Notre Dame
+This software is distributed under the GNU General Public License.
+See the file LICENSE for details.
+*/
+
+#ifndef IOPORTS_H
+#define IOPORTS_H
+
+#include "kernel/types.h"
+
+/*
+These are C wrappers around the assembly instruction IN and OUT
+to move data to and from I/O ports.  These variants are historically
+called inb/inw/inl outb/outw/outl for in/out of byte (8 bits),
+word (16 bits), and long (32 bits) respectively.
+Note that some devices requires the "slow" variants that do an
+extra dummy I/O in order to give the device more time to respond.
+*/
+
+static inline uint8_t inb(int port)
+{
+	uint8_t result;
+      asm("inb %w1, %b0": "=a"(result):"Nd"(port));
+	return result;
+}
+
+static inline uint16_t inw(int port)
+{
+	uint16_t result;
+      asm("inw %w1, %w0": "=a"(result):"Nd"(port));
+	return result;
+}
+
+static inline uint16_t inl(int port)
+{
+	uint32_t result;
+      asm("inl %w1, %0": "=a"(result):"Nd"(port));
+	return result;
+}
+
+static inline void outb(uint8_t value, int port)
+{
+      asm("outb %b0, %w1": :"a"(value), "Nd"(port));
+}
+
+static inline void outw(uint16_t value, int port)
+{
+      asm("outw %w0, %w1": :"a"(value), "Nd"(port));
+}
+
+static inline void outl(uint32_t value, int port)
+{
+      asm("outl %0, %w1": :"a"(value), "Nd"(port));
+}
+
+static inline void iowait()
+{
+	outb(0, 0x80);
+}
+
+static inline uint8_t inb_slow(int port)
+{
+	uint8_t result = inb(port);
+	iowait();
+	return result;
+}
+
+static inline uint16_t inw_slow(int port)
+{
+	uint16_t result = inw(port);
+	iowait();
+	return result;
+}
+
+static inline uint32_t inl_slow(int port)
+{
+	uint32_t result = inl(port);
+	iowait();
+	return result;
+}
+
+static inline void outb_slow(uint8_t value, int port)
+{
+	outb(value, port);
+	iowait();
+}
+
+static inline void outw_slow(uint16_t value, int port)
+{
+	outw(value, port);
+	iowait();
+}
+
+static inline void outl_slow(uint32_t value, int port)
+{
+	outl(value, port);
+	iowait();
+}
+
+#endif