diff options
Diffstat (limited to 'kernel/io')
-rw-r--r-- | kernel/io/font.h | 15 | ||||
-rw-r--r-- | kernel/io/logger/base.cxx | 11 | ||||
-rw-r--r-- | kernel/io/logger/base.h | 31 | ||||
-rw-r--r-- | kernel/io/logger/base.ipp | 145 | ||||
-rw-r--r-- | kernel/io/psf2.h | 37 | ||||
-rw-r--r-- | kernel/io/tamsyn.psf | bin | 0 -> 4677 bytes |
6 files changed, 239 insertions, 0 deletions
diff --git a/kernel/io/font.h b/kernel/io/font.h new file mode 100644 index 0000000..e4f72ca --- /dev/null +++ b/kernel/io/font.h @@ -0,0 +1,15 @@ +#ifndef HOS_IO_FONT_H +#define HOS_IO_FONT_H + +#include <cstdint> + +namespace hos::io +{ + class font + { + public: + virtual void write (unsigned char character, void *fb_addr, std::uint16_t bpp) = 0; + }; +} + +#endif diff --git a/kernel/io/logger/base.cxx b/kernel/io/logger/base.cxx new file mode 100644 index 0000000..bb1e3c4 --- /dev/null +++ b/kernel/io/logger/base.cxx @@ -0,0 +1,11 @@ +#include <io/logger/base.ipp> + +#if defined (__x86_64__) +#include <amd64/io/com1.h> + +namespace hos::io +{ + template class logger<com_logger>; +} + +#endif diff --git a/kernel/io/logger/base.h b/kernel/io/logger/base.h new file mode 100644 index 0000000..7aa9e2d --- /dev/null +++ b/kernel/io/logger/base.h @@ -0,0 +1,31 @@ +#ifndef HOS_IO_BASE_H +#define HOS_IO_BASE_H + +namespace hos::io +{ + enum log_level + { + DEBUG, + INFO, + WARN, + ERROR, + FATAL + }; + + /// Ah, the glorious CRTP... + template <typename concrete_logger> + class logger + { + public: + logger (enum log_level level); + + void set_level (enum log_level level); + void write (enum log_level level, const char *message, ...); + protected: + char buffer[512]; + private: + enum log_level level; + }; +} + +#endif diff --git a/kernel/io/logger/base.ipp b/kernel/io/logger/base.ipp new file mode 100644 index 0000000..b48a132 --- /dev/null +++ b/kernel/io/logger/base.ipp @@ -0,0 +1,145 @@ +#ifndef HOS_IO_BASE_IMPL +#define HOS_IO_BASE_IMPL + +#include <io/logger/base.h> +#include <utils.h> + +#include <stdarg.h> + +namespace hos::io +{ + template <typename concrete_logger> + logger<concrete_logger>::logger (enum log_level level) + { + this->set_level(level); + } + + template <typename concrete_logger> + void logger<concrete_logger>::set_level (enum log_level level) + { + this->level = level; + } + + template <typename concrete_logger> + void logger<concrete_logger>::write (enum log_level level, const char *message, ...) + { + if (level < this->level) + { + return; + } + + char *bufferptr = this->buffer; + memset(bufferptr, 0, sizeof(this->buffer)); + + const char *logtypes[] = { + "DEBUG: ", + "INFO: ", + "WARN: ", + "ERROR: ", + "FATAL: " + }; + + int len = 0; + switch (level) + { + case log_level::DEBUG: { + len = strlen(logtypes[0]); + + memcpy(bufferptr, logtypes[0], len); + bufferptr += len; + break; + } + case log_level::INFO: { + len = strlen(logtypes[1]); + + memcpy(bufferptr, logtypes[1], len); + bufferptr += len; + break; + } + case log_level::WARN: { + len = strlen(logtypes[2]); + + memcpy(bufferptr, logtypes[2], len); + bufferptr += len; + break; + } + case log_level::ERROR: { + len = strlen(logtypes[3]); + + memcpy(bufferptr, logtypes[3], len); + bufferptr += len; + break; + } + case log_level::FATAL: { + len = strlen(logtypes[4]); + + memcpy(bufferptr, logtypes[4], len); + bufferptr += len; + break; + } + } + + len = strlen(message); + if (bufferptr + len >= this->buffer + 510) { + const char failed[] = "LOGGER: Message longer than display buffer."; + memcpy(bufferptr, failed, strlen(failed)); + static_cast<concrete_logger*>(this)->flush(); + } + + va_list args; + va_start(args, message); + + char temp_buffer[this->buffer + 510 - bufferptr]; + char *tempptr = temp_buffer; + memset(tempptr, 0, sizeof(temp_buffer)); + + char next; + while ((next = *message++) != 0) + { + if (next == '%') + { + next = *message++; + switch (next) + { + case 'c': { + char c = va_arg(args, int); + + if (!((tempptr + 1) - temp_buffer > (long int) sizeof(temp_buffer))) + { + memcpy(tempptr, &c, 1); + tempptr++; + } + + break; + } + case 's': { + char *string = va_arg(args, char *); + + len = strlen(string); + if (!((tempptr + len) - temp_buffer > (long int) sizeof(temp_buffer))) + { + memcpy(tempptr, string, len); + tempptr += len; + } + + break; + } + } + } else { + memcpy(tempptr, &next, 1); + tempptr++; + } + } + + va_end(args); + + len = strlen(temp_buffer); + memcpy(bufferptr, temp_buffer, len); + bufferptr += len; + + memcpy(bufferptr, "\n", 1); + static_cast<concrete_logger*>(this)->flush(); + } +} + +#endif diff --git a/kernel/io/psf2.h b/kernel/io/psf2.h new file mode 100644 index 0000000..e8dda44 --- /dev/null +++ b/kernel/io/psf2.h @@ -0,0 +1,37 @@ +#ifndef HOS_IO_PSF2_H +#define HOS_IO_PSF2_H + +#include <cstdint> +#include <io/font.h> + +#define PSF2_MAGIC0 0x72 +#define PSF2_MAGIC1 0xb5 +#define PSF2_MAGIC2 0x4a +#define PSF2_MAGIC3 0x86 + +#define PSF2_HAS_UNICODE_TABLE 0x01 + +#define PSF2_SEPARATOR 0xff +#define PSF2_STARTSEQ 0xfe + +namespace hos::io +{ + class psf2 : public font + { + public: + psf2 (void *font_start_addr); + + void write (unsigned char character, void *fb_addr, std::uint16_t bpp); + private: + unsigned char magic[4]; + unsigned int version; + unsigned int header_size; + unsigned int flags; + unsigned int length; + unsigned int charsize; + unsigned int height; + unsigned int width; + }; +} + +#endif diff --git a/kernel/io/tamsyn.psf b/kernel/io/tamsyn.psf Binary files differnew file mode 100644 index 0000000..6fd82c1 --- /dev/null +++ b/kernel/io/tamsyn.psf |