diff options
Diffstat (limited to 'kernel/amd64/io')
-rw-r--r-- | kernel/amd64/io/com1.cxx | 44 | ||||
-rw-r--r-- | kernel/amd64/io/com1.h | 17 | ||||
-rw-r--r-- | kernel/amd64/io/ports.S | 24 | ||||
-rw-r--r-- | kernel/amd64/io/ports.h | 12 |
4 files changed, 97 insertions, 0 deletions
diff --git a/kernel/amd64/io/com1.cxx b/kernel/amd64/io/com1.cxx new file mode 100644 index 0000000..fc67b65 --- /dev/null +++ b/kernel/amd64/io/com1.cxx @@ -0,0 +1,44 @@ +#include <amd64/io/com1.h> +#include <amd64/io/ports.h> +#include <utils.h> + +#define COM1 0x3f8 + +int is_transmit_empty () +{ + return hos::io::inb(COM1 + 5) & 0x20; +} + +namespace hos::io +{ + com_logger::com_logger (enum log_level level) + : logger (level) + { + outb(COM1 + 1, 0x00); + outb(COM1 + 3, 0x80); + outb(COM1 + 0, 0x03); + outb(COM1 + 1, 0x00); + outb(COM1 + 3, 0x03); + outb(COM1 + 2, 0xc7); + outb(COM1 + 4, 0x0b); + outb(COM1 + 4, 0x1e); + outb(COM1 + 0, 0xae); + + if (inb(COM1 + 0) != 0xae) + { + return; + } + + outb(COM1 + 4, 0x0f); + } + + void com_logger::flush () + { + std::size_t len = strlen(this->buffer); + for (std::size_t i = 0; i < len; i++) + { + while (is_transmit_empty() == 0); + outb(COM1 + 0, this->buffer[i]); + } + } +} diff --git a/kernel/amd64/io/com1.h b/kernel/amd64/io/com1.h new file mode 100644 index 0000000..0ee04ac --- /dev/null +++ b/kernel/amd64/io/com1.h @@ -0,0 +1,17 @@ +#ifndef HOS_AMD64_IO_COM1_H +#define HOS_AMD64_IO_COM1_H + +#include <amd64/io/ports.h> +#include <io/logger/base.h> + +namespace hos::io +{ + class com_logger : public hos::io::logger<com_logger> + { + public: + com_logger (enum log_level level); + void flush (); + }; +} + +#endif diff --git a/kernel/amd64/io/ports.S b/kernel/amd64/io/ports.S new file mode 100644 index 0000000..37301a4 --- /dev/null +++ b/kernel/amd64/io/ports.S @@ -0,0 +1,24 @@ +.section .text +.global inb, outb + +inb: + push %rbp + mov %rsp, %rbp + sub $0x10, %rsp + mov %rdi, %rdx + xor %rax, %rax + in (%dx), %al + add $0x10, %rsp + pop %rbp + ret + +outb: + push %rbp + mov %rsp, %rbp + sub $0x10, %rsp + mov %rdi, %rdx + mov %rsi, %rax + out %al, (%dx) + add $0x10, %rsp + pop %rbp + ret diff --git a/kernel/amd64/io/ports.h b/kernel/amd64/io/ports.h new file mode 100644 index 0000000..6de2acb --- /dev/null +++ b/kernel/amd64/io/ports.h @@ -0,0 +1,12 @@ +#ifndef HOS_AMD64_IO_PORTS_H +#define HOS_AMD64_IO_PORTS_H + +#include <cstdint> + +namespace hos::io +{ + extern "C" std::uint8_t inb (std::uint16_t port); + extern "C" void outb (std::uint16_t port, std::uint8_t value); +} + +#endif |