Skip to content

Commit 142bbb3

Browse files
author
Jim Borden
committed
Beginning of a userspace console
1 parent af38793 commit 142bbb3

30 files changed

Lines changed: 1300 additions & 34 deletions

File tree

.vscode/settings.json

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,5 +9,11 @@
99
},
1010
"C_Cpp.default.compilerArgs": [
1111
"-D__borrrdex__"
12-
]
12+
],
13+
"C_Cpp.default.compilerPath": "/home/borrrden/.local/share/borrrdex/bin/clang++",
14+
"C_Cpp.default.includePath": [
15+
"../LibC/options/posix/include",
16+
"../LibC/sysdeps/borrrdex/include",
17+
"../LibBor/include"
18+
],
1319
}

Kernel/CMakeLists.txt

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,13 @@ set(CMAKE_ASM_NASM_OBJECT_FORMAT elf64)
6262
set(CMAKE_ASM_NASM_FLAGS "-g -F dwarf")
6363
set(CMAKE_EXECUTABLE_SUFFIX .elf)
6464

65+
add_custom_target(
66+
make_trampoline
67+
COMMAND /bin/sh ${CMAKE_CURRENT_SOURCE_DIR}/bintoelf.sh ${CMAKE_CURRENT_SOURCE_DIR}/src/arch/x86_64/smptrampoline.asm ${CMAKE_CURRENT_BINARY_DIR}/smptrampoline.bin.o ${CMAKE_CURRENT_SOURCE_DIR}/include/arch/x86_64/ smptrampoline
68+
BYPRODUCTS ${CMAKE_CURRENT_BINARY_DIR}/smptrampoline.bin.o
69+
COMMENT "Assembling SMP trampoline..."
70+
)
71+
6572
add_executable(
6673
kernel
6774
src/arch/x86_64/entry.asm
@@ -89,6 +96,7 @@ add_executable(
8996
src/arch/x86_64/tss.cpp
9097
src/arch/x86_64/tss.asm
9198
src/arch/x86_64/thread.cpp
99+
src/arch/x86_64/keyboard.cpp
92100
src/video/video.cpp
93101
src/liballoc/liballoc.c
94102
src/liballoc/liballoc_internal.cpp
@@ -116,6 +124,11 @@ add_executable(
116124
src/char_buffer.cpp
117125
)
118126

127+
add_dependencies(
128+
kernel
129+
make_trampoline
130+
)
131+
119132
target_compile_options(
120133
kernel PRIVATE
121134
$<$<COMPILE_LANGUAGE:C>:${KERNEL_C_FLAGS}>
@@ -152,10 +165,4 @@ target_link_libraries(
152165
kernel PRIVATE
153166
lai
154167
${CMAKE_CURRENT_BINARY_DIR}/smptrampoline.bin.o
155-
)
156-
157-
add_custom_command(
158-
TARGET kernel
159-
PRE_BUILD
160-
COMMAND /bin/sh ${CMAKE_CURRENT_SOURCE_DIR}/bintoelf.sh ${CMAKE_CURRENT_SOURCE_DIR}/src/arch/x86_64/smptrampoline.asm ${CMAKE_CURRENT_BINARY_DIR}/smptrampoline.bin.o ${CMAKE_CURRENT_SOURCE_DIR}/include/arch/x86_64/ smptrampoline
161168
)

Kernel/include/arch/x86_64/abi.h

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,11 @@ constexpr uint8_t SYSCALL_READ = 2;
2121
constexpr uint8_t SYSCALL_WRITE = 3;
2222
constexpr uint8_t SYSCALL_SEEK = 4;
2323
constexpr uint8_t SYSCALL_CLOSE = 5;
24-
constexpr uint8_t SYSCALL_EXIT = 6;
25-
constexpr uint8_t SYSCALL_MMAP = 7;
26-
constexpr uint8_t SYSCALL_SET_FSBASE = 8;
27-
constexpr uint8_t SYSCALL_MAP_FB = 9;
28-
constexpr uint8_t SYSCALL_GRANT_PTY = 10;
29-
constexpr uint8_t NUM_SYSCALLS = 11;
24+
constexpr uint8_t SYSCALL_IOCTL = 6;
25+
constexpr uint8_t SYSCALL_EXIT = 7;
26+
constexpr uint8_t SYSCALL_MMAP = 8;
27+
constexpr uint8_t SYSCALL_SET_FSBASE = 9;
28+
constexpr uint8_t SYSCALL_MAP_FB = 10;
29+
constexpr uint8_t SYSCALL_GRANT_PTY = 11;
30+
constexpr uint8_t SYSCALL_UPTIME = 12;
31+
constexpr uint8_t NUM_SYSCALLS = 13;

Kernel/include/arch/x86_64/apic.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ namespace apic {
2929

3030
namespace io {
3131
void set_base(uintptr_t new_base);
32+
void map_legacy_irq(uint8_t irq);
3233
}
3334

3435
int initialize();
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
#pragma once
2+
3+
namespace keyboard {
4+
void ps2_initialize();
5+
}

Kernel/include/device.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@ namespace devices {
1212
unix_pseudo,
1313
unix_pseudo_terminal,
1414
kernel_log,
15-
storage
15+
storage,
16+
legacy_hid
1617
};
1718

1819
class device : public fs::fs_node {

Kernel/include/fs/filesystem.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,4 +85,5 @@ namespace fs {
8585
fs_fd_t* open(fs_node* node, uint32_t flags);
8686
void close(fs_node* node);
8787
void close(fs_fd_t* fd);
88+
int ioctl(fs_fd_t* handle, uint64_t cmd, uint64_t arg);
8889
}

Kernel/src/arch/x86_64/apic.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,23 @@ namespace apic {
142142

143143
return 0;
144144
}
145+
146+
void map_legacy_irq(uint8_t irq) {
147+
if(debug_level_interrupts >= debug::LEVEL_VERBOSE) {
148+
log::info("[apic] mapping legacy IRQ %u", irq);
149+
}
150+
151+
const list<int_source_override_t *> *isos = acpi::int_source_overrides();
152+
for(unsigned i = 0; i < isos->size(); i++) {
153+
auto* iso = isos->get(i);
154+
if(iso->source == irq) {
155+
// Already mapped!
156+
return;
157+
}
158+
}
159+
160+
redirect(irq, irq + 0x20, ICR_MESSAGE_TYPE_LOW_PRIORITY);
161+
}
145162
}
146163

147164
int initialize() {

Kernel/src/arch/x86_64/idt.asm

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -184,7 +184,6 @@ __syscall_handler:
184184
call syscall_handler
185185
pop rsp
186186
popaq
187-
sti
188187
o64 sysret
189188

190189
syscall_init:
Lines changed: 151 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
1+
#include <keyboard.h>
2+
#include <idt.h>
3+
#include <apic.h>
4+
#include <io.h>
5+
#include <device.h>
6+
#include <timer.h>
7+
#include <panic.h>
8+
#include <logging.h>
9+
#include <fs/directory_entry.h>
10+
#include <kmath.h>
11+
12+
namespace keyboard {
13+
constexpr uint8_t DATA_PORT = 0x60;
14+
constexpr uint8_t CMD_PORT = 0x64;
15+
constexpr uint8_t STATUS_PORT = 0x64;
16+
17+
// Commands
18+
constexpr uint8_t READ_CCB = 0x20;
19+
constexpr uint8_t WRITE_CCB = 0x60;
20+
constexpr uint8_t DISABLE_AUX = 0xA7;
21+
constexpr uint8_t ENABLE_AUX = 0xA8;
22+
constexpr uint8_t DISABLE_KBD = 0xAD;
23+
constexpr uint8_t ENABLE_KBD = 0xAE;
24+
constexpr uint8_t SELF_TEST = 0xAA;
25+
26+
// Responses
27+
constexpr uint8_t SELF_TEST_PASS = 0x55;
28+
29+
// Status Bits
30+
constexpr uint8_t OUT_FULL = 0x01;
31+
constexpr uint8_t IN_FULL = 0x02;
32+
33+
// CCB
34+
constexpr uint8_t ENABLE_P1_INT = 0x01;
35+
constexpr uint8_t ENABLE_P2_INT = 0x02;
36+
37+
class keyboard_device : public devices::device {
38+
public:
39+
keyboard_device(const char* name)
40+
:devices::device(devices::device_type::legacy_hid, name)
41+
{
42+
flags = fs::FS_NODE_CHARDEVICE;
43+
_dirent.set_name(name);
44+
_dirent.flags = flags;
45+
_dirent.node = this;
46+
_device_name = "PS/2 Keyboard Device";
47+
}
48+
49+
ssize_t read(size_t offset, size_t size, uint8_t* buffer) override {
50+
size = kstd::min(size, (size_t)_count);
51+
if(size == 0) {
52+
return 0;
53+
}
54+
55+
uint8_t i;
56+
for(; i < size; i++) {
57+
if(!read_key(buffer++)) {
58+
break;
59+
}
60+
}
61+
62+
return i;
63+
}
64+
65+
ssize_t write(size_t offset, size_t size, uint8_t* buffer) override {
66+
size = kstd::min(size, 256 - (size_t)_count);
67+
if(size == 0) {
68+
return 0;
69+
}
70+
71+
for(uint8_t i = 0; i < size; i++) {
72+
_buffer[_end++] = *buffer++;
73+
_count++;
74+
}
75+
76+
return size;
77+
}
78+
79+
private:
80+
bool read_key(uint8_t* key) {
81+
if(_count == 0) {
82+
return false;
83+
}
84+
85+
_count--;
86+
*key = _buffer[_start++];
87+
return true;
88+
}
89+
90+
uint8_t _start {0};
91+
uint8_t _end {0};
92+
uint8_t _count {0};
93+
uint8_t _buffer[256];
94+
fs::directory_entry _dirent;
95+
};
96+
97+
static keyboard_device* ps2_kbd;
98+
99+
static uint8_t kbd_read() {
100+
const int max_attempts = 10000;
101+
int i = 0;
102+
while(i++ < max_attempts) {
103+
uint8_t s = port_read_8(STATUS_PORT);
104+
if(s & OUT_FULL) {
105+
return port_read_8(DATA_PORT);
106+
}
107+
}
108+
109+
const char* reasons[1] = {"PS/2 read failure"};
110+
kernel_panic(reasons, 1);
111+
}
112+
113+
static void ps2_kbd_handler(void*, register_context* regs) {
114+
uint8_t sc = kbd_read();
115+
ps2_kbd->write(0, 1, &sc);
116+
}
117+
118+
void ps2_initialize() {
119+
// Properly test to see that we have a PS/2 keyboard
120+
121+
// Disable both PS/2 ports from receiving external data
122+
port_write_8(CMD_PORT, DISABLE_KBD);
123+
port_write_8(CMD_PORT, DISABLE_AUX);
124+
125+
// Clear any current input
126+
port_read_8(DATA_PORT);
127+
128+
port_write_8(CMD_PORT, SELF_TEST);
129+
uint8_t r = kbd_read();
130+
if(r != SELF_TEST_PASS) {
131+
log::error("PS/2 keyboard self-test failed");
132+
return;
133+
}
134+
135+
// Ensure keyboard PS/2 port interrupt enabled
136+
port_write_8(CMD_PORT, READ_CCB);
137+
uint8_t ccb = kbd_read();
138+
ccb |= ENABLE_P1_INT;
139+
port_write_8(CMD_PORT, WRITE_CCB);
140+
port_write_8(DATA_PORT, ccb);
141+
142+
port_write_8(CMD_PORT, ENABLE_KBD);
143+
port_write_8(CMD_PORT, ENABLE_AUX);
144+
145+
ps2_kbd = new keyboard_device("kbd0");
146+
147+
idt::register_interrupt_handler(IRQ0 + 1, ps2_kbd_handler);
148+
apic::io::map_legacy_irq(1);
149+
port_write_8(0xF0, 1);
150+
}
151+
}

0 commit comments

Comments
 (0)