From fbc736463f2ca2f5dbf1b7c412f408245e61df97 Mon Sep 17 00:00:00 2001 From: aqua Date: Sun, 12 Mar 2023 18:39:39 +0200 Subject: Revert VGA C driver --- Makefile.config | 11 +-- devices/Makefile | 2 +- devices/uart.h | 23 ++++-- devices/uart.hpp | 7 -- devices/uart/uart_16550.c | 13 +-- devices/uart/unittest_uart_16550.cc | 12 +-- devices/uart_16550.cpp | 110 -------------------------- devices/vga.c | 152 ++++++++++++++++++++++++++++++++++++ devices/vga.cpp | 138 -------------------------------- devices/vga.h | 33 ++++++++ devices/vga.hpp | 51 ------------ i686/sys/io.h | 10 --- i686/sys/io.hpp | 33 -------- i686/toolchain.mk | 7 -- lib/libk/stdio.h | 35 +++------ lib/libk/stdio/vfprintf.c | 54 +++++++++++++ lib/libk/stdio/vfprintf.cpp | 54 ------------- rules.mk | 7 -- src/kernel.c | 57 ++++++++++++++ src/kernel.cpp | 59 -------------- 20 files changed, 338 insertions(+), 530 deletions(-) delete mode 100644 devices/uart.hpp delete mode 100644 devices/uart_16550.cpp create mode 100644 devices/vga.c delete mode 100644 devices/vga.cpp create mode 100644 devices/vga.h delete mode 100644 devices/vga.hpp delete mode 100644 i686/sys/io.hpp create mode 100644 lib/libk/stdio/vfprintf.c delete mode 100644 lib/libk/stdio/vfprintf.cpp create mode 100644 src/kernel.c delete mode 100644 src/kernel.cpp diff --git a/Makefile.config b/Makefile.config index 836c094..1f9331d 100644 --- a/Makefile.config +++ b/Makefile.config @@ -33,21 +33,14 @@ CONFIG_KB_PS2=y ARCH=i686 # define compiler, linker, archiver and strip and their flags -# FIXME: cpp threadsafe statics ${ARCH}_AS := i686-elf-as ${ARCH}_CC := i686-elf-gcc ${ARCH}_CCID := $(shell ${${ARCH}_CC} --version | head -n1) -${ARCH}_CFLAGS := -Wall -Wextra -Wpedantic -Werror=shadow -Wconversion -fanalyzer -ffreestanding -std=gnu11 \ - -mgeneral-regs-only \ +${ARCH}_CFLAGS := -Wall -Wextra -Wpedantic -Werror=shadow -Wconversion -fanalyzer \ + -D__ARCH__="${ARCH}" -ffreestanding -std=gnu11 -mgeneral-regs-only \ $(shell echo ${CONFIG_CFLAGS}) -${ARCH}_CXX := i686-elf-g++ -${ARCH}_CXXID := $(shell ${${ARCH}_CXX} --version | head -n1) -${ARCH}_CXXFLAGS := -Wall -Wextra -Wpedantic -Werror=shadow -Wconversion -ffreestanding -std=c++17 \ - -mgeneral-regs-only -fno-use-cxa-atexit -fno-threadsafe-statics -fno-exceptions -fno-rtti \ - $(shell echo ${CONFIG_CXXFLAGS}) - ${ARCH}_LD := i686-elf-ld ${ARCH}_LDID := $(shell ${${ARCH}_LD} --version | head -n1) ${ARCH}_LDFLAGS := -static -nostdlib \ diff --git a/devices/Makefile b/devices/Makefile index e081f68..8040bec 100644 --- a/devices/Makefile +++ b/devices/Makefile @@ -5,7 +5,7 @@ ${ARCH}_CFLAGS += ${INCLUDES} ${ARCH}_CXXFLAGS += ${INCLUDES} TARGETLIB += devs -devs.SRCS = pic_8259.c uart_16550.cpp vga.cpp i8042.c pckbd.c mouse.c +devs.SRCS = pic_8259.c uart/uart_16550.c vga.c i8042.c pckbd.c mouse.c HOSTTARGETBIN += uart/test_uart_16550 uart/test_uart_16550.SRCS = uart/uart_16550.c uart/unittest_uart_16550.cc diff --git a/devices/uart.h b/devices/uart.h index 8def000..3349042 100644 --- a/devices/uart.h +++ b/devices/uart.h @@ -1,7 +1,21 @@ #pragma once -// #include -// #include +#ifdef __ARCH__ +#include +#include + +#else +// from stdio +typedef struct FILE { + int id; + void (*putc)(const struct FILE *, char); + int (*puts)(const struct FILE *, const char *, int); + void (*flush)(const struct FILE *); +} FILE; + +// from sys/io +unsigned char inb(unsigned short); +void outb(unsigned char, unsigned short); enum UART { COM1 = 0x3f8, @@ -13,9 +27,6 @@ enum UART { COM7 = 0x5e8, COM8 = 0x4e8, }; - -typedef struct { - unsigned id; -} FILE; +#endif FILE *uart_init(enum UART port); diff --git a/devices/uart.hpp b/devices/uart.hpp deleted file mode 100644 index c86557c..0000000 --- a/devices/uart.hpp +++ /dev/null @@ -1,7 +0,0 @@ -#pragma once - -#include -#include - -template FILE *uart_init(); -template <> FILE *uart_init(); diff --git a/devices/uart/uart_16550.c b/devices/uart/uart_16550.c index 61c349f..47a7fd3 100644 --- a/devices/uart/uart_16550.c +++ b/devices/uart/uart_16550.c @@ -1,13 +1,6 @@ #include "uart_16550.h" #include -#ifdef __ARCH__ -#include -#else -unsigned char inb(unsigned short); -void outb(unsigned char, unsigned short); -#endif - int uart_thre(enum UART port) { @@ -75,8 +68,8 @@ uart_init(enum UART port) // (not-loopback with IRQs enabled and OUT#1 and OUT#2 bits enabled) outb(0x0f, port + 4); uart_stream.id = port; - // uart_stream.putc = &uart_putc; - // uart_stream.puts = &uart_puts; - // uart_stream.flush = &uart_flush; + uart_stream.putc = &uart_putc; + uart_stream.puts = &uart_puts; + uart_stream.flush = &uart_flush; return &uart_stream; } diff --git a/devices/uart/unittest_uart_16550.cc b/devices/uart/unittest_uart_16550.cc index 560c6c0..16e7202 100644 --- a/devices/uart/unittest_uart_16550.cc +++ b/devices/uart/unittest_uart_16550.cc @@ -39,7 +39,7 @@ TEST_F(Uart16550, uart_thre) TEST_F(Uart16550, uart_putc) { - k::FILE f{k::COM1}; + k::FILE f{k::COM1, nullptr, nullptr, nullptr}; // set up expectations EXPECT_CALL(*mockPort, inb(k::COM1 + k::LineStatus)).Times(1).WillRepeatedly(Return(k::THRE)); @@ -50,7 +50,7 @@ TEST_F(Uart16550, uart_putc) TEST_F(Uart16550, uart_putc_newline) { - k::FILE f{k::COM1}; + k::FILE f{k::COM1, nullptr, nullptr, nullptr}; // set up expectations EXPECT_CALL(*mockPort, inb(k::COM1 + k::LineStatus)).Times(2).WillRepeatedly(Return(k::THRE)); @@ -62,7 +62,7 @@ TEST_F(Uart16550, uart_putc_newline) TEST_F(Uart16550, uart_puts) { - k::FILE f{k::COM1}; + k::FILE f{k::COM1, nullptr, nullptr, nullptr}; const char *string{"This is a test string to write over uart"}; const int length = (int)strlen(string); @@ -76,7 +76,7 @@ TEST_F(Uart16550, uart_puts) TEST_F(Uart16550, uart_puts_WithUnknownLength) { - k::FILE f{k::COM1}; + k::FILE f{k::COM1, nullptr, nullptr, nullptr}; const char *string{"This is a test string to write over uart"}; const int length = (int)strlen(string); @@ -90,7 +90,7 @@ TEST_F(Uart16550, uart_puts_WithUnknownLength) TEST_F(Uart16550, uart_puts_WithPartialLength) { - k::FILE f{k::COM1}; + k::FILE f{k::COM1, nullptr, nullptr, nullptr}; const char *string{"This is a test string to write over uart"}; const int length = (int)strlen(string); const int partial = 10; @@ -107,7 +107,7 @@ TEST_F(Uart16550, uart_puts_WithPartialLength) TEST_F(Uart16550, uart_flush) { - k::FILE f{k::COM1}; + k::FILE f{k::COM1, nullptr, nullptr, nullptr}; // set up expectations // no mock calls are expected diff --git a/devices/uart_16550.cpp b/devices/uart_16550.cpp deleted file mode 100644 index 9620981..0000000 --- a/devices/uart_16550.cpp +++ /dev/null @@ -1,110 +0,0 @@ -#include "uart.hpp" -#include - -template struct Uart16550 : public kIoDevice, private Port { - using Base = Port; - using Ports = UART; - using PortOffset = UARTPortOffset; - - // Line Control - // | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | - // |dla| | parity | s | data | - enum LineControl : unsigned char { - d5bit = 0x00, // 0000 0000 data bits - d6bit = 0x01, // 0000 0001 - d7bit = 0x02, // 0000 0010 - d8bit = 0x03, // 0000 0011 - none = 0x00, // 0000 0000 parity bits - odd = 0x08, // 0000 1000 - even = 0x18, // 0001 1000 - mark = 0x28, // 0010 1000 - space = 0x38, // 0011 1000 - s1bit = 0x00, // 0000 0000 stop bits - s2bit = 0x04, // 0000 0100 1.5 for 5bit data; 2 otherwise - dlab = 0x80 // 1000 0000 divisor latch access bit - }; - - // Line Status Register - enum LineStatus : unsigned char { - DR = (1 << 0), // data ready: see if there is data to read - OE = (1 << 1), // overrun error: see if there has been data lost - PE = (1 << 2), // parity error: see if there was error in transmission - FE = (1 << 3), // framing error: see if a stop bit was missing - BI = (1 << 4), // break indicator: see if there is a break in data input - THRE = (1 << 5), // transmitter holding register empty: see if transmission buffer is empty - TEMT = (1 << 6), // transmitter empty: see if transmitter is not doing anything - ERRO = (1 << 7), // impending error: see if there is an error with a word in the input buffer - }; - - [[nodiscard]] static bool - test() - { - Base::out(0x00, 1); // Disable all interrupts - Base::out(0x80, 3); // Enable DLAB (set baud rate divisor) - Base::out(0x03, 0); // Set divisor to 3 (lo byte) 38400 baud - Base::out(0x00, 1); // (hi byte) - Base::out(0x03, 3); // 8 bits, no parity, one stop bit - Base::out(0xc7, 2); // Enable FIFO, clear them, with 14-byte threshold - Base::out(0x0b, 4); // IRQs enabled, RTS/DSR set - Base::out(0x1e, 4); // Set in loopback mode, test the serial chip - Base::out(0xae, 0); // Test serial chip (send byte 0xAE and check if serial - // returns same byte) - - // Check if serial is faulty (i.e: not same byte as sent) - if (Base::in() != 0xae) { return false; } - - // If serial is not faulty set it in normal operation mode - // (not-loopback with IRQs enabled and OUT#1 and OUT#2 bits enabled) - Base::out(0x0f, 4); - return true; - } - - [[nodiscard]] static bool - thre() - { - return Base::in(PortOffset::LineStatus)&THRE; - } - - void - putc(char a) override - { - while (!thre()) {} - Base::out(a); - if (a == '\n') putc('\r'); - } - - int - puts(const char *string, int length) override - { - int written = 0; - - if (length == -1) - while (*string != '\0') { - putc(*string); - ++string; - ++written; - } - - else { - for (int i = 0; i < length; ++i) putc(string[i]); - written += length; - } - - return written; - } - - void - flush() override - { - } -}; - -static_assert(sizeof(Uart16550) == sizeof(void *)); - -template <> -FILE * -uart_init() -{ - static Uart16550 device; - return &device; -} diff --git a/devices/vga.c b/devices/vga.c new file mode 100644 index 0000000..e4831b8 --- /dev/null +++ b/devices/vga.c @@ -0,0 +1,152 @@ +#include "vga.h" +#include +#include + +#define cga_idx_port 0x3d4 +#define cga_dat_port 0x3d5 + +#define cursor_start 0x0a +#define cursor_end 0x0b +#define cursor_addr_h 0x0e +#define cursor_addr_l 0x0f +#define cursor_hide 0x20 + +struct __attribute__((packed)) VGAEntry { + unsigned char text; + uint8_t foreground : 4; + uint8_t background : 4; +}; +_Static_assert(sizeof(struct VGAEntry) == 2, "sizeof VGAEntry"); + +const int width = 80; +const int height = 25; + +struct VGAEntry *buffer; +int col = 0; +int row = 0; + +// *** Cursor *** +void +vga_enable_cursor(unsigned char start, unsigned char end) +{ + outb(cursor_start, cga_idx_port); + outb((inb(cga_dat_port) & 0xc0) | start, cga_dat_port); + + outb(cursor_end, cga_idx_port); + outb((inb(cga_dat_port) & 0xe0) | end, cga_dat_port); +} + +void +vga_disable_cursor() +{ + outb(cursor_start, cga_idx_port); + outb(cursor_hide, cga_dat_port); +} + +void +vga_update_cursor(void) +{ + const uint16_t pos = row * width + col; + + outb(cursor_addr_l, cga_idx_port); + outb(pos & 0xff, cga_dat_port); + + outb(cursor_addr_h, cga_idx_port); + outb((pos >> 8) & 0xff, cga_dat_port); +} + +// *** Text Mode Output *** +void +vga_putc(__attribute__((unused)) const FILE *self, char a) +{ + switch (a) { + case '\n': + col = 0; + ++row; + break; + case '\r': + col = 0; + break; + case '\b': + --col; + if (col < 0) col = 0; + break; + default: + buffer[row * width + col].text = a; + ++col; + } + + if (col == width) { + col = 0; + ++row; + } + + if (row == height) { + // scroll up + for (int y = 1; y < height; ++y) + for (int x = 0; x < width; ++x) { + const int prev = (y - 1) * width + x; + const int curr = y * width + x; + buffer[prev] = buffer[curr]; + } + // blank out last row + for (int i = (height - 1) * width; i < height * width; ++i) buffer[i].text = ' '; + --row; + } +} + +int +vga_puts(const FILE *self, const char *string, int len) +{ + int written = 0; + if (len == -1) + while (*string != '\0') { + vga_putc(self, *string); + ++string; + ++written; + } + + else + for (int i = 0; i < len; ++i) { + vga_putc(self, string[i]); + ++written; + } + return written; +} + +void +vga_flush(__attribute__((unused)) const FILE *self) +{ + vga_update_cursor(); +} + +// *** Text Mode *** +FILE vga_stream; + +FILE * +vga_init(void *addr) +{ + buffer = (struct VGAEntry *)addr; + vga_enable_cursor(14, 15); + vga_clear(VGA_COLOR_LIGHT_BLUE, VGA_COLOR_LIGHT_GREY); + + vga_stream.id = 0; + vga_stream.putc = &vga_putc; + vga_stream.puts = &vga_puts; + vga_stream.flush = &vga_flush; + return &vga_stream; +} + +void +vga_clear(enum vga_color foreground, enum vga_color background) +{ + for (int y = 0; y < height; ++y) + for (int x = 0; x < width; ++x) { + const int index = y * width + x; + buffer[index].text = ' '; + buffer[index].foreground = foreground; + buffer[index].background = background; + } + col = row = 0; + vga_update_cursor(); +} diff --git a/devices/vga.cpp b/devices/vga.cpp deleted file mode 100644 index 3f83a5f..0000000 --- a/devices/vga.cpp +++ /dev/null @@ -1,138 +0,0 @@ -#include "vga.hpp" -#include -#include - -// FIXME user a Port -#define cga_idx_port 0x3d4 -#define cga_dat_port 0x3d5 - -// FIXME make constexpr -#define cursor_start 0x0a -#define cursor_end 0x0b -#define cursor_addr_h 0x0e -#define cursor_addr_l 0x0f -#define cursor_hide 0x20 - -static_assert(sizeof(struct VGA::VGAEntry) == 2, "sizeof VGAEntry"); - -// FIXME make constexpr -const int width = 80; -const int height = 25; - -// *** Cursor *** -// FIXME make VGA members -void -vga_enable_cursor(unsigned char start, unsigned char end) -{ - outb(cursor_start, cga_idx_port); - outb((inb(cga_dat_port) & 0xc0) | start, cga_dat_port); - - outb(cursor_end, cga_idx_port); - outb((inb(cga_dat_port) & 0xe0) | end, cga_dat_port); -} - -void -vga_disable_cursor() -{ - outb(cursor_start, cga_idx_port); - outb(cursor_hide, cga_dat_port); -} - -void -VGA::update_cursor() -{ - const uint16_t pos = row * width + col; - - outb(cursor_addr_l, cga_idx_port); - outb(pos & 0xff, cga_dat_port); - - outb(cursor_addr_h, cga_idx_port); - outb((pos >> 8) & 0xff, cga_dat_port); -} - -// *** Text Mode Output *** -void -VGA::putc(char a) -{ - switch (a) { - case '\n': - col = 0; - ++row; - break; - case '\r': - col = 0; - break; - case '\b': - --col; - if (col < 0) col = 0; - break; - default: - buffer[row * width + col].text = a; - ++col; - } - - if (col == width) { - col = 0; - ++row; - } - - if (row == height) { - // scroll up - for (int y = 1; y < height; ++y) - for (int x = 0; x < width; ++x) { - const int prev = (y - 1) * width + x; - const int curr = y * width + x; - buffer[prev] = buffer[curr]; - } - // blank out last row - for (int i = (height - 1) * width; i < height * width; ++i) buffer[i].text = ' '; - --row; - } -} - -int -VGA::puts(const char *string, int len) -{ - int written = 0; - if (len == -1) - while (*string != '\0') { - putc(*string); - ++string; - ++written; - } - - else - for (int i = 0; i < len; ++i) { - putc(string[i]); - ++written; - } - return written; -} - -// *** Text Mode *** -VGA::VGA(void *addr) -{ - buffer = (struct VGAEntry *)addr; - vga_enable_cursor(14, 15); - clear(VGA_COLOR_LIGHT_BLUE, VGA_COLOR_LIGHT_GREY); -} -FILE * -vga_init(void *buffer) -{ - static VGA device(buffer); - return &device; -} - -void -VGA::clear(enum vga_color foreground, enum vga_color background) -{ - for (int y = 0; y < height; ++y) - for (int x = 0; x < width; ++x) { - const int index = y * width + x; - buffer[index].text = ' '; - buffer[index].foreground = foreground; - buffer[index].background = background; - } - col = row = 0; - update_cursor(); -} diff --git a/devices/vga.h b/devices/vga.h new file mode 100644 index 0000000..bd77e2a --- /dev/null +++ b/devices/vga.h @@ -0,0 +1,33 @@ +#pragma once + +#include + +/** Hardware text mode color constants. */ +enum vga_color { + VGA_COLOR_BLACK = 0, + VGA_COLOR_BLUE = 1, + VGA_COLOR_GREEN = 2, + VGA_COLOR_CYAN = 3, + VGA_COLOR_RED = 4, + VGA_COLOR_MAGENTA = 5, + VGA_COLOR_BROWN = 6, + VGA_COLOR_LIGHT_GREY = 7, + VGA_COLOR_DARK_GREY = 8, + VGA_COLOR_LIGHT_BLUE = 9, + VGA_COLOR_LIGHT_GREEN = 10, + VGA_COLOR_LIGHT_CYAN = 11, + VGA_COLOR_LIGHT_RED = 12, + VGA_COLOR_LIGHT_MAGENTA = 13, + VGA_COLOR_LIGHT_BROWN = 14, + VGA_COLOR_WHITE = 15, +}; + +FILE *vga_init(void *addr); +void vga_clear(enum vga_color foreground, enum vga_color background); + +// void vga_putc(char a); +// void vga_puts(const char *string, int len); + +// void vga_enable_cursor(unsigned char start, unsigned char end); +// void vga_disable_cursor(); +void vga_update_cursor(void); diff --git a/devices/vga.hpp b/devices/vga.hpp deleted file mode 100644 index 5287d73..0000000 --- a/devices/vga.hpp +++ /dev/null @@ -1,51 +0,0 @@ -#pragma once - -#include - -/** Hardware text mode color constants. */ -enum vga_color { - VGA_COLOR_BLACK = 0, - VGA_COLOR_BLUE = 1, - VGA_COLOR_GREEN = 2, - VGA_COLOR_CYAN = 3, - VGA_COLOR_RED = 4, - VGA_COLOR_MAGENTA = 5, - VGA_COLOR_BROWN = 6, - VGA_COLOR_LIGHT_GREY = 7, - VGA_COLOR_DARK_GREY = 8, - VGA_COLOR_LIGHT_BLUE = 9, - VGA_COLOR_LIGHT_GREEN = 10, - VGA_COLOR_LIGHT_CYAN = 11, - VGA_COLOR_LIGHT_RED = 12, - VGA_COLOR_LIGHT_MAGENTA = 13, - VGA_COLOR_LIGHT_BROWN = 14, - VGA_COLOR_WHITE = 15, -}; - -FILE *vga_init(void *buffer); - -struct VGA : public kIoDevice { - VGA(void *addr); - - void putc(char a) override; - int puts(const char *string, int length) override; - void - flush() override - { - update_cursor(); - } - - struct __attribute__((packed)) VGAEntry { - unsigned char text; - unsigned char foreground : 4; - unsigned char background : 4; - }; - -private: - void clear(enum vga_color foreground, enum vga_color background); - void update_cursor(); - - struct VGAEntry *buffer; - int col = 0; - int row = 0; -}; diff --git a/i686/sys/io.h b/i686/sys/io.h index b6c24c5..da586b9 100644 --- a/i686/sys/io.h +++ b/i686/sys/io.h @@ -11,16 +11,6 @@ enum UART { COM7 = 0x5e8, COM8 = 0x4e8, }; -enum UARTPortOffset { - Data = 0, // read from receive buffer / write to transmit buffer | BaudDiv_l - InterruptControl = 1, // interrupt enable | BaudDiv_h - FifoControl = 2, // interrupt ID and FIFO control - LineControl = 3, // most significant bit is the DLAB - ModemControl = 4, - LineStatus = 5, - ModemStatus = 6, - Scratch = 7, -}; static inline void outb(unsigned char val, unsigned short port) diff --git a/i686/sys/io.hpp b/i686/sys/io.hpp deleted file mode 100644 index 9759a3a..0000000 --- a/i686/sys/io.hpp +++ /dev/null @@ -1,33 +0,0 @@ -#pragma once - -/** - * Ports provide communication with devices on the x86 IO bus. - */ -template struct Port { - /** - * Read value from port - */ - static T - in(unsigned short offset = 0) - { - if constexpr (sizeof(T) == sizeof(unsigned char)) return inb(port + offset); - else if constexpr (sizeof(T) == sizeof(unsigned short)) - return inw(port + offset); - else if constexpr (sizeof(T) == sizeof(unsigned int)) - return inl(port + offset); - } - - /** - * Write value to port - */ - static void - out(T val, unsigned short offset = 0) - { - if constexpr (sizeof(T) == sizeof(unsigned char)) outb(val, port + offset); - else if constexpr (sizeof(T) == sizeof(unsigned short)) - outw(val, port + offset); - else if constexpr (sizeof(T) == sizeof(unsigned int)) - outl(val, port + offset); - } - -}; diff --git a/i686/toolchain.mk b/i686/toolchain.mk index 1205c28..f3f4732 100644 --- a/i686/toolchain.mk +++ b/i686/toolchain.mk @@ -1,7 +1,6 @@ ARCH=i686 # define compiler, linker, archiver and strip and their flags -# FIXME: cpp threadsafe statics ${ARCH}_AS := i686-elf-as ${ARCH}_CC := i686-elf-gcc @@ -10,12 +9,6 @@ ${ARCH}_CFLAGS := -Wall -Wextra -Wpedantic -Werror=shadow -Wconversion -fanaly -D__ARCH__="${ARCH}" -ffreestanding -std=gnu11 -mgeneral-regs-only \ $(shell echo ${CONFIG_CFLAGS}) -${ARCH}_CXX := i686-elf-g++ -${ARCH}_CXXID := $(shell ${${ARCH}_CXX} --version | head -n1) -${ARCH}_CXXFLAGS := -Wall -Wextra -Wpedantic -Werror=shadow -Wconversion -ffreestanding -std=c++17 \ - -mgeneral-regs-only -fno-use-cxa-atexit -fno-threadsafe-statics -fno-exceptions -fno-rtti \ - $(shell echo ${CONFIG_CXXFLAGS}) - ${ARCH}_LD := i686-elf-ld ${ARCH}_LDID := $(shell ${${ARCH}_LD} --version | head -n1) ${ARCH}_LDFLAGS := -static -nostdlib \ diff --git a/lib/libk/stdio.h b/lib/libk/stdio.h index 5ef68f1..b28eb5e 100644 --- a/lib/libk/stdio.h +++ b/lib/libk/stdio.h @@ -7,22 +7,19 @@ ///@defgroup stdio stdio ///@{ -#ifdef __cplusplus -/** - * An object type used for streams - */ -struct kIoDevice { - /** Function that prints a character to the stream */ - virtual void putc(char) = 0; - /** Function that prints a string to the stream */ - virtual int puts(const char *, int) = 0; - /** Flush write buffers */ - virtual void flush() = 0; -}; -typedef kIoDevice FILE; -#else -typedef void FILE; -#endif +/// An object type used for streams +typedef struct FILE { + int id; + + /// Function that prints a character to the stream + void (*putc)(const struct FILE *, char); + + /// Function that prints a string to the stream + int (*puts)(const struct FILE *, const char *, int); + + /// Flush write buffers + void (*flush)(const struct FILE *); +} FILE; /** A FILE value corresponding to stdin, the keyboard buffer */ extern FILE *stdin; @@ -31,9 +28,6 @@ extern FILE *stdout; /** A FILE value corresponding to stderr, the uart */ extern FILE *stderr; -#ifdef __cplusplus -extern "C" { -#endif /** * Write the formatted string to stdout * Supports ``%s`` (string), ``%d`` (decimal), ``%u`` (unsigned), ``%x`` (hexadecimal) @@ -50,9 +44,6 @@ int fprintf(FILE *restrict stream, const char *restrict format, ...); * Write the formatted string to stream; see printf */ int vfprintf(FILE *restrict stream, const char *restrict format, va_list ap); -#ifdef __cplusplus -} -#endif ///@} ///@} diff --git a/lib/libk/stdio/vfprintf.c b/lib/libk/stdio/vfprintf.c new file mode 100644 index 0000000..d24e43e --- /dev/null +++ b/lib/libk/stdio/vfprintf.c @@ -0,0 +1,54 @@ +#include +#include + +static char buffer[3 * sizeof(int) + 2]; + +int +vfprintf(FILE *restrict stream, const char *restrict format, va_list params) +{ + int written = 0; + + int s = 0; + int l = 0; + for (int i = 0; format[i] != '\0'; ++i) { + if (format[i] == '%') { + written += stream->puts(stream, &format[s], l); + s = i + 2; + ++i; + + switch (format[i]) { + case 's': { + const char *arg = va_arg(params, const char *); + written += stream->puts(stream, arg, -1); + } break; + case 'c': { + const int arg = va_arg(params, int); + stream->putc(stream, arg); + ++written; + } break; + case 'd': { + const char *arg = itoa(buffer, va_arg(params, int), 10); + written += stream->puts(stream, arg, -1); + } break; + case 'u': { + const char *arg = utoa(buffer, va_arg(params, unsigned int), 10); + written += stream->puts(stream, arg, -1); + } break; + case 'x': { + const char *arg = utoa(buffer, va_arg(params, unsigned int), 16); + written += stream->puts(stream, arg, -1); + } break; + } + + l = 0; + } + + else + ++l; + } + + if (l > 0) { written += stream->puts(stream, &format[s], l); } + + stream->flush(stream); + return written; +} diff --git a/lib/libk/stdio/vfprintf.cpp b/lib/libk/stdio/vfprintf.cpp deleted file mode 100644 index aa9256d..0000000 --- a/lib/libk/stdio/vfprintf.cpp +++ /dev/null @@ -1,54 +0,0 @@ -#include -#include - -static char buffer[3 * sizeof(int) + 2]; - -extern "C" int -vfprintf(FILE *restrict stream, const char *restrict format, va_list params) -{ - int written = 0; - - int s = 0; - int l = 0; - for (int i = 0; format[i] != '\0'; ++i) { - if (format[i] == '%') { - written += stream->puts(&format[s], l); - s = i + 2; - ++i; - - switch (format[i]) { - case 's': { - const char *arg = va_arg(params, const char *); - written += stream->puts(arg, -1); - } break; - case 'c': { - const int arg = va_arg(params, int); - stream->putc(arg); - ++written; - } break; - case 'd': { - const char *arg = itoa(buffer, va_arg(params, int), 10); - written += stream->puts(arg, -1); - } break; - case 'u': { - const char *arg = utoa(buffer, va_arg(params, unsigned int), 10); - written += stream->puts(arg, -1); - } break; - case 'x': { - const char *arg = utoa(buffer, va_arg(params, unsigned int), 16); - written += stream->puts(arg, -1); - } break; - } - - l = 0; - } - - else - ++l; - } - - if (l > 0) { written += stream->puts(&format[s], l); } - - stream->flush(); - return written; -} diff --git a/rules.mk b/rules.mk index 5d73051..e217d6d 100644 --- a/rules.mk +++ b/rules.mk @@ -74,9 +74,6 @@ ${ARCH}_CXXFLAGS += -I../lib/libk -Drestrict=__restrict__ %_${ARCH}.d: %.c @${${ARCH}_CC} ${${ARCH}_CFLAGS} -M -MT $(<:.c=_${ARCH}.o) $< -MF $@ -%_${ARCH}.d: %.cpp - @${${ARCH}_CXX} ${${ARCH}_CXXFLAGS} -M -MT $(<:.cpp=_${ARCH}.o) $< -MF $@ - # Host dependency rules %.d: %.c @${HOST_CC} ${HOST_CFLAGS} -M -MT $(<:.c=.o) $< -MF $@ @@ -101,10 +98,6 @@ ${ARCH}_CXXFLAGS += -I../lib/libk -Drestrict=__restrict__ @echo ' CC $<' @${${ARCH}_CC} ${${ARCH}_CFLAGS} -c -o $@ $< -%_${ARCH}.o: %.cpp - @echo ' CXX $<' - @${${ARCH}_CXX} ${${ARCH}_CXXFLAGS} -c -o $@ $< - %.elf: @echo ' LD $@' @${${ARCH}_LD} ${${ARCH}_LDFLAGS} -o $@ $^ diff --git a/src/kernel.c b/src/kernel.c new file mode 100644 index 0000000..3ee231e --- /dev/null +++ b/src/kernel.c @@ -0,0 +1,57 @@ +//===================================================================== +// glitch kernel +// spdx-license-identifier: ISC +// description: kernel entry point +//===================================================================== + +#include "conf.h" +#include "mem.h" +#include +#include +#include +#include +#include +#include +#include +#include + +FILE *stdin; +FILE *stdout; +FILE *stderr; + +void +kmain() +{ + stderr = uart_init(COM1); + vmm_map(0xb8000, 0xc03ff000); + stdout = vga_init((void *)0xc03ff000); + + printf("glitch [version " VERSION "] [" CC "]\n"); + fprintf(stderr, "glitch [version " VERSION "] [" CC "]\n"); + { + char vendor[13] = {'\0'}; + unsigned int eax; + __get_cpuid(0, &eax, (unsigned int *)vendor, (unsigned int *)(vendor + 8), (unsigned int *)(vendor + 4)); + struct CPUVersion v; + __get_cpuid(1, (unsigned int *)&v, &eax, &eax, &eax); + printf("CPU: %s family %u model %u stepping %u\n", vendor, family(v), model(v), v.stepping); + fprintf(stderr, "CPU: %s family %u model %u stepping %u\n", vendor, family(v), model(v), v.stepping); + } + + pic_init(); + + ps2_ctrl_init(); + ps2_keyboard_init(); + mouse_init(); + + pic_enable(); + fprintf(stderr, "interrupts enabled\n"); + + /* + alloc4M(); + char *c = (char *)0xc0700000; + if (*c == 0) printf("c is 0\r\n"); + */ + + while (1) {} +} diff --git a/src/kernel.cpp b/src/kernel.cpp deleted file mode 100644 index 063fe11..0000000 --- a/src/kernel.cpp +++ /dev/null @@ -1,59 +0,0 @@ -//===================================================================== -// glitch kernel -// spdx-license-identifier: ISC -// description: kernel entry point -//===================================================================== - -extern "C" { -#include "conf.h" -#include "mem.h" -#include -#include -#include -#include -#include -#include -} -#include -#include - -FILE *stdin; -FILE *stdout; -FILE *stderr; - -extern "C" void -kmain() -{ - stderr = uart_init(); - vmm_map(0xb8000, 0xc03ff000); - stdout = vga_init((void *)0xc03ff000); - - printf("glitch [version " VERSION "] [" CC "]\n"); - fprintf(stderr, "glitch [version " VERSION "] [" CC "]\n"); - { - char vendor[13] = {'\0'}; - unsigned int eax; - __get_cpuid(0, &eax, (unsigned int *)vendor, (unsigned int *)(vendor + 8), (unsigned int *)(vendor + 4)); - struct CPUVersion v; - __get_cpuid(1, (unsigned int *)&v, &eax, &eax, &eax); - printf("CPU: %s family %u model %u stepping %u\n", vendor, family(v), model(v), v.stepping); - fprintf(stderr, "CPU: %s family %u model %u stepping %u\n", vendor, family(v), model(v), v.stepping); - } - - pic_init(); - - ps2_ctrl_init(); - ps2_keyboard_init(); - mouse_init(); - - pic_enable(); - fprintf(stderr, "interrupts enabled\n"); - - /* - alloc4M(); - char *c = (char *)0xc0700000; - if (*c == 0) printf("c is 0\r\n"); - */ - - while (1) {} -} -- cgit v1.2.1