summaryrefslogtreecommitdiff
path: root/src/port.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/port.c')
-rw-r--r--src/port.c38
1 files changed, 38 insertions, 0 deletions
diff --git a/src/port.c b/src/port.c
new file mode 100644
index 0000000..9af4a49
--- /dev/null
+++ b/src/port.c
@@ -0,0 +1,38 @@
+
+#include "port.h"
+
+void port_write(struct port p, uint32_t data) {
+ switch (p.bandwidth) {
+ case port8bit:
+ asm volatile("outb %0, %1" : : "a" ((uint8_t) data), "Nd" (p.port_number));
+ break;
+ case port8bit_slow:
+ asm volatile("outb %0, %1\njmp 1f\n1: jmp 1f\n1:" :
+ : "a" ((uint8_t) data), "Nd" (p.port_number));
+ break;
+ case port16bit:
+ asm volatile("outw %0, %1" : : "a" ((uint16_t) data), "Nd" (p.port_number));
+ case port32bit:
+ asm volatile("outl %0, %1" : : "a" (data), "Nd" (p.port_number));
+ break;
+ }
+}
+
+uint32_t port_read(struct port p) {
+ uint32_t result = 0;
+ switch (p.bandwidth) {
+ case port8bit:
+ asm volatile("inb %1, %0" : "=a" (result) : "Nd" (p.port_number));
+ break;
+ case port8bit_slow:
+ asm volatile("inb %1, %0\njmp 1f\n1: jmp 1f\n1:" : "=a" (result) : "Nd" (p.port_number));
+ break;
+ case port16bit:
+ asm volatile("inw %1, %0" : "=a" (result) : "Nd" (p.port_number));
+ break;
+ case port32bit:
+ asm volatile("inl %1, %0" : "=a" (result) : "Nd" (p.port_number));
+ }
+
+ return result;
+}