Implemented some basic libc functions and a text console
This commit is contained in:
105
arch/x86_64/console.c
Normal file
105
arch/x86_64/console.c
Normal file
@@ -0,0 +1,105 @@
|
||||
#include <socks/libc/string.h>
|
||||
#include <socks/libc/ctype.h>
|
||||
#include <socks/machine/ports.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#define VGA_PORT_CMD 0x3D4
|
||||
#define VGA_PORT_DATA 0x3D5
|
||||
|
||||
#define VGA_CHAR(ch, attrib) ((uint16_t)(ch) | ((uint16_t)(attrib) << 8))
|
||||
#define DEFAULT_ATTRIB 0x07
|
||||
|
||||
static uint16_t *g_console_fb = (uint16_t *)0xb8000;
|
||||
static const unsigned int k_console_width = 80;
|
||||
static const unsigned int k_console_height = 25;
|
||||
static unsigned int g_console_cursor_xpos = 0;
|
||||
static unsigned int g_console_cursor_ypos = 0;
|
||||
|
||||
static void init_vga_cursor(void)
|
||||
{
|
||||
unsigned int start = 0, end = 15;
|
||||
outportb(VGA_PORT_CMD, 0x0A);
|
||||
outportb(VGA_PORT_DATA, (inportb(VGA_PORT_DATA) & 0xC0) | start);
|
||||
|
||||
outportb(VGA_PORT_CMD, 0x0B);
|
||||
outportb(VGA_PORT_DATA, (inportb(VGA_PORT_DATA) & 0xE0) | end);
|
||||
}
|
||||
|
||||
static void move_vga_cursor(unsigned int x, unsigned int y)
|
||||
{
|
||||
unsigned int offset = y * k_console_width + x;
|
||||
|
||||
outportb(VGA_PORT_CMD, 0x0F);
|
||||
outportb(VGA_PORT_DATA, (uint8_t)(offset & 0xFF));
|
||||
|
||||
outportb(VGA_PORT_CMD, 0x0E);
|
||||
outportb(VGA_PORT_DATA, (uint8_t)((offset >> 8) & 0xFF));
|
||||
}
|
||||
|
||||
void ml_console_init(void)
|
||||
{
|
||||
g_console_cursor_xpos = 0;
|
||||
g_console_cursor_ypos = 5;
|
||||
|
||||
init_vga_cursor();
|
||||
move_vga_cursor(g_console_cursor_xpos, g_console_cursor_ypos);
|
||||
}
|
||||
|
||||
static void scroll_display()
|
||||
{
|
||||
uint16_t *src = g_console_fb + k_console_width;
|
||||
uint16_t *dst = g_console_fb;
|
||||
size_t n = k_console_width * (k_console_height - 1) * 2;
|
||||
|
||||
memmove(dst, src, n);
|
||||
|
||||
dst = g_console_fb + ((k_console_height - 1) * k_console_width);
|
||||
|
||||
for (int i = 0; i < k_console_width; i++) {
|
||||
dst[i] = VGA_CHAR(0, DEFAULT_ATTRIB);
|
||||
}
|
||||
}
|
||||
|
||||
static void handle_ctrl(int c)
|
||||
{
|
||||
switch (c) {
|
||||
case '\n':
|
||||
g_console_cursor_xpos = 0;
|
||||
g_console_cursor_ypos++;
|
||||
|
||||
if (g_console_cursor_ypos >= k_console_height) {
|
||||
scroll_display();
|
||||
g_console_cursor_ypos = k_console_height - 1;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
move_vga_cursor(g_console_cursor_xpos, g_console_cursor_ypos);
|
||||
}
|
||||
|
||||
void ml_console_putchar(int c)
|
||||
{
|
||||
if (iscntrl(c)) {
|
||||
handle_ctrl(c);
|
||||
return;
|
||||
}
|
||||
|
||||
g_console_fb[(g_console_cursor_ypos * k_console_width) + g_console_cursor_xpos] = VGA_CHAR(c, DEFAULT_ATTRIB);
|
||||
|
||||
g_console_cursor_xpos++;
|
||||
|
||||
if (g_console_cursor_xpos >= k_console_width) {
|
||||
g_console_cursor_xpos = 0;
|
||||
g_console_cursor_ypos++;
|
||||
}
|
||||
|
||||
if (g_console_cursor_ypos >= k_console_height) {
|
||||
scroll_display();
|
||||
g_console_cursor_ypos = k_console_height - 1;
|
||||
g_console_cursor_xpos = 0;
|
||||
}
|
||||
|
||||
move_vga_cursor(g_console_cursor_xpos, g_console_cursor_ypos);
|
||||
}
|
||||
7
arch/x86_64/include/socks/machine/console.h
Normal file
7
arch/x86_64/include/socks/machine/console.h
Normal file
@@ -0,0 +1,7 @@
|
||||
#ifndef SOCKS_X86_64_CONSOLE_H_
|
||||
#define SOCKS_X86_64_CONSOLE_H_
|
||||
|
||||
extern void ml_console_init(void);
|
||||
extern void ml_console_putchar(int c);
|
||||
|
||||
#endif
|
||||
11
arch/x86_64/include/socks/machine/cpu.h
Normal file
11
arch/x86_64/include/socks/machine/cpu.h
Normal file
@@ -0,0 +1,11 @@
|
||||
#ifndef SOCKS_X86_64_CPU_H_
|
||||
#define SOCKS_X86_64_CPU_H_
|
||||
|
||||
typedef struct ml_cpu_block {
|
||||
|
||||
} ml_cpu_block;
|
||||
|
||||
extern int ml_cpu_block_init(ml_cpu_block *p);
|
||||
extern int ml_cpu_block_use(ml_cpu_block *p);
|
||||
|
||||
#endif
|
||||
8
arch/x86_64/include/socks/machine/init.h
Normal file
8
arch/x86_64/include/socks/machine/init.h
Normal file
@@ -0,0 +1,8 @@
|
||||
#ifndef SOCKS_X86_64_INIT_H_
|
||||
#define SOCKS_X86_64_INIT_H_
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
extern int machine_init(uintptr_t arg);
|
||||
|
||||
#endif
|
||||
17
arch/x86_64/include/socks/machine/ports.h
Normal file
17
arch/x86_64/include/socks/machine/ports.h
Normal file
@@ -0,0 +1,17 @@
|
||||
#ifndef SOCKS_X86_64_PORTS_H_
|
||||
#define SOCKS_X86_64_PORTS_H_
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#define PF_IOPORT_COUNT (65536)
|
||||
|
||||
extern uint8_t inportb(uint16_t port);
|
||||
extern uint16_t inportw(uint16_t port);
|
||||
extern uint32_t inportl(uint16_t port);
|
||||
extern void outportb(uint16_t port, uint8_t data);
|
||||
extern void outportw(uint16_t port, uint16_t data);
|
||||
extern void outportl(uint16_t port, uint32_t data);
|
||||
extern void outportsw(uint16_t port, void *data, uint32_t size);
|
||||
extern void inportsw(uint16_t port, unsigned char *data, unsigned long size);
|
||||
|
||||
#endif
|
||||
39
arch/x86_64/ports.c
Normal file
39
arch/x86_64/ports.c
Normal file
@@ -0,0 +1,39 @@
|
||||
#include <stdint.h>
|
||||
|
||||
uint8_t inportb(uint16_t port) {
|
||||
uint8_t data;
|
||||
asm volatile("inb %1, %0" : "=a"(data) : "dN"(port));
|
||||
return data;
|
||||
}
|
||||
|
||||
void outportb(uint16_t port, uint8_t data) {
|
||||
asm volatile("outb %1, %0" : : "dN"(port), "a"(data));
|
||||
}
|
||||
|
||||
uint16_t inportw(uint16_t port) {
|
||||
uint16_t data;
|
||||
asm volatile("inw %1, %0" : "=a"(data) : "dN"(port));
|
||||
return data;
|
||||
}
|
||||
|
||||
void outportw(uint16_t port, uint16_t data) {
|
||||
asm volatile("outw %1, %0" : : "dN"(port), "a"(data));
|
||||
}
|
||||
|
||||
uint32_t inportl(uint16_t port) {
|
||||
uint32_t data;
|
||||
asm volatile("inl %%dx, %%eax" : "=a"(data) : "dN"(port));
|
||||
return data;
|
||||
}
|
||||
|
||||
void outportl(uint16_t port, uint32_t data) {
|
||||
asm volatile("outl %%eax, %%dx" : : "dN"(port), "a"(data));
|
||||
}
|
||||
|
||||
void outportsw(uint16_t port, void *data, uint32_t size) {
|
||||
asm volatile("rep outsw" : "+S"(data), "+c"(size) : "d"(port));
|
||||
}
|
||||
|
||||
void inportsw(uint16_t port, unsigned char *data, unsigned long size) {
|
||||
asm volatile("rep insw" : "+D"(data), "+c"(size) : "d"(port) : "memory");
|
||||
}
|
||||
Reference in New Issue
Block a user