From 897c23faca1d596b23bb5ff269bf8d5f96e5b794 Mon Sep 17 00:00:00 2001 From: shockrah Date: Sat, 5 Oct 2019 20:45:22 -0700 Subject: [PATCH] # Serial port configurations * Implementing some serial port control in preparation to do debugging with bochs * Changed naming of io to fb_ports to finally[tm] ports --- fb.h | 6 ------ fb.s | 10 ---------- framebuffer.c | 8 ++++---- framebuffer.h | 5 ++++- ports.h | 9 +++++++++ ports.s | 45 +++++++++++++++++++++++++++++++++++++++++++++ serial.c | 38 ++++++++++++++++++++++++++++++++++++++ serial.h | 26 ++++++++++++++++++++++++++ 8 files changed, 126 insertions(+), 21 deletions(-) delete mode 100644 fb.h delete mode 100644 fb.s create mode 100644 ports.h create mode 100644 ports.s create mode 100644 serial.c create mode 100644 serial.h diff --git a/fb.h b/fb.h deleted file mode 100644 index 51a83d7..0000000 --- a/fb.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef INCLUDE_IO_H -#define INCLUDE_IO_H - -void fb_cursor_control(unsigned short, unsigned char); - -#endif /* INCLUDE_IO_H */ diff --git a/fb.s b/fb.s deleted file mode 100644 index 170085a..0000000 --- a/fb.s +++ /dev/null @@ -1,10 +0,0 @@ -; Helpers for frame buffer which pretty much have to to be -; written in asm - -global fb_cursor_control - -fb_cursor_control: - mov al, [esp+8] - mov dx, [esp+4] - out dx, al - ret diff --git a/framebuffer.c b/framebuffer.c index f0184c2..de8628c 100644 --- a/framebuffer.c +++ b/framebuffer.c @@ -29,9 +29,9 @@ void clear_fb(void) { // Takes the linear indexed position to move the cursos, if there is nothing at that position we should still have something there void fb_move_cursor(u16 position) { - fb_cursor_control(FB_CMD, FB_HIGH_CMD); - fb_cursor_control(FB_DATA, ((position >> 8) & 0x00ff) ); - fb_cursor_control(FB_CMD, FB_LOW_CMD); - fb_cursor_control(FB_DATA, position & 0x00ff); + serial_control(FB_CMD, FB_HIGH_CMD); + serial_control(FB_DATA, ((position >> 8) & 0x00ff) ); + serial_control(FB_CMD, FB_LOW_CMD); + serial_control(FB_DATA, position & 0x00ff); } diff --git a/framebuffer.h b/framebuffer.h index 748b8a9..884e046 100644 --- a/framebuffer.h +++ b/framebuffer.h @@ -1,5 +1,6 @@ #include "types.h" -#include "fb.h" +#include "serial.h" +#include "ports.h" #define COLUMNS 80 #define ROWS 25 @@ -38,9 +39,11 @@ extern s32 Frame_Buffer_Cursor; +// Serial wrapper for void write_cell_fb(u8, u8, u8); void clear_fb(void); void fb_move_cursor(u16); + diff --git a/ports.h b/ports.h new file mode 100644 index 0000000..c0fb3da --- /dev/null +++ b/ports.h @@ -0,0 +1,9 @@ +#include "types.h" + +#ifndef INCLUDE_IO_H +#define INCLUDE_IO_H + +void serial_control(const u16, const u16); + +u8 serial_read_buffer(const u16); +#endif /* INCLUDE_IO_H */ diff --git a/ports.s b/ports.s new file mode 100644 index 0000000..d4c5a40 --- /dev/null +++ b/ports.s @@ -0,0 +1,45 @@ +; Helpers for frame buffer which pretty much have to to be +; written in asm + + +; COM1 Base Port +%define SERIAL_COM1_BASE 0x3F8 + +%define SERIAL_DATA_PORT(base) (base) +%define SERIAL_FIFO_COMMAND_PORT(base) (base+2) +%define SERIAL_LINE_COMMAND_PORT(base) (base+3) +%define SERIAL_MODEM_COMMAND_PORT(base) (base+4) +%define SERIAL_LINE_STATUS_PORT(base) (base+5) + +%define SERIAL_DATA_ +global serial_control +global serial_read_buffer + +serial_control: + push ebp + mov ebp, esp + add esp, 0xc ; ebp + 2 local vars (32-bit kernel) + + mov al, [esp+8] + mov dx, [esp+4] + out dx, al + + mov esp, ebp + pop ebp + ret + +; Read byte from serial port +serial_read_buffer: + push ebp + mov ebp, esp + push ebx + + xor eax, eax + mov dx, [esp + 4] ; grab the address of the targeted port + in al, dx ; read byte from the port + + mov esp, ebp + pop ebx + pop ebp + ret + diff --git a/serial.c b/serial.c new file mode 100644 index 0000000..643efd6 --- /dev/null +++ b/serial.c @@ -0,0 +1,38 @@ +#include "serial.h" + +/* + * SERIAL_LINE_COMMAND_PORT configuration + * Bit: | 7 | 6 | 5 4 3 | 2 | 1 0 | + * Content: | d | b | prty | s | dl | + * d = enable/disable DLAB + * b = enable/disable break control + * prty = # of parity bits to use + * s = # no of stop bits [0 is 1] and [1 is 1.5 or 2] + * dl = length of data + * + */ + +void serial_set_buad_rate(const u16 com_port, const u16 divisor) { + // Activate line - ready to send higher 8 bits of data + // send the higher 8 bits first + // send the lower 8 bits next + + serial_control(SERIAL_LINE_COMMAND_PORT(com_port), + SERIAL_LINE_ENABLE); + + serial_control(SERIAL_DATA_PORT(com_port), + (divisor>>8) & 0x00ff); + + serial_control(SERIAL_DATA_PORT(com_port), + divisor & 0x00ff); +} + +// Payload described above +void serial_configure_line(const u16 line, const u8 payload) { + serial_control(SERIAL_LINE_COMMAND_PORT(line), payload); +} + +u8 serial_fifo_empty(const u16 com_port) { + // If the 5th bit is set then we know that the fifo queue is empty + return serial_read_buffer(SERIAL_LINE_STATUS_PORT(com_port)) & 0x20; +} diff --git a/serial.h b/serial.h new file mode 100644 index 0000000..ec386da --- /dev/null +++ b/serial.h @@ -0,0 +1,26 @@ +#include "types.h" +#include "ports.h" + +// Serial driver interface + +#define SERIAL_COM1_BASE 0x3F8 + +#define SERIAL_DATA_PORT(base) (base) +#define SERIAL_FIFO_COMMAND_PORT(base) (base+2) +#define SERIAL_LINE_COMMAND_PORT(base) (base+3) +#define SERIAL_MODEM_COMMAND_PORT(base) (base+4) +#define SERIAL_LINE_STATUS_PORT(base) (base+5) + +#define SERIAL_LINE_ENABLE 0x80 + +// Default configurations for serial ports/lines/buffers etc. +// Rational can be found here: https://littleosbook.github.io/#configuring-the-buffers +#define SERIAL_DEFAULT_LINE_CFG 0X03 +#define SERIAL_DEFAULT_BUFFER_CFG 0xc7 +#define SERIAL_DEFAULT_MODEM_CFG 0x03 + +void serial_set_buad_rate(const u16, const u16); + +void serial_configure_line(const u16, const u8); + +u8 serial_fifo_empty(const u16);