Serial comm kernel process
This commit is contained in:
@ -56,6 +56,7 @@ SRCFILES += $(call GRABSRC, \
|
||||
proc/kproc \
|
||||
proc/ps2kbproc \
|
||||
proc/termproc \
|
||||
proc/serialproc \
|
||||
hal \
|
||||
hal/$(ARCH) \
|
||||
std \
|
||||
|
@ -2,17 +2,12 @@
|
||||
#include <stdbool.h>
|
||||
#include "hal/hal.h"
|
||||
#include "kprintf.h"
|
||||
#include "serial.h"
|
||||
#include "gdt.h"
|
||||
#include "intr.h"
|
||||
#include "pic.h"
|
||||
#include "pit.h"
|
||||
|
||||
void hal_init(void) {
|
||||
if (!serial_init()) {
|
||||
hal_hang(); // going further makes no sense
|
||||
}
|
||||
LOG("hal", "serial init\n");
|
||||
gdt_init();
|
||||
intr_init();
|
||||
pic_init();
|
||||
|
@ -1,51 +0,0 @@
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include "io.h"
|
||||
#include "putchar.h"
|
||||
|
||||
#define SERIAL_PORT 0x3f8
|
||||
|
||||
static int serial_received(void) {
|
||||
return io_in8(SERIAL_PORT + 5) & 1;
|
||||
}
|
||||
|
||||
static uint8_t serial_read(void) {
|
||||
while (serial_received() == 0);
|
||||
return io_in8(SERIAL_PORT);
|
||||
}
|
||||
|
||||
static int serial_trans_empty(void) {
|
||||
return io_in8(SERIAL_PORT + 5) & 0x20;
|
||||
}
|
||||
|
||||
static void serial_write(uint8_t value) {
|
||||
while (!serial_trans_empty());
|
||||
io_out8(SERIAL_PORT, value);
|
||||
}
|
||||
|
||||
// REFERENCE: https://wiki.osdev.org/Serial_Ports
|
||||
bool serial_init(void) {
|
||||
io_out8(SERIAL_PORT + 1, 0x00);
|
||||
io_out8(SERIAL_PORT + 3, 0x80);
|
||||
io_out8(SERIAL_PORT + 0, 0x03);
|
||||
io_out8(SERIAL_PORT + 1, 0x00);
|
||||
io_out8(SERIAL_PORT + 3, 0x03);
|
||||
io_out8(SERIAL_PORT + 2, 0xc7);
|
||||
io_out8(SERIAL_PORT + 4, 0x0b);
|
||||
io_out8(SERIAL_PORT + 4, 0x1e);
|
||||
io_out8(SERIAL_PORT + 0, 0xae);
|
||||
|
||||
if (io_in8(SERIAL_PORT + 0) != 0xae) {
|
||||
return false;
|
||||
}
|
||||
|
||||
io_out8(SERIAL_PORT + 4, 0x0f);
|
||||
return true;
|
||||
}
|
||||
|
||||
#if PUTCHAR_ == PUTCHAR_SERIAL
|
||||
// For printf library
|
||||
void putchar_(char c) {
|
||||
serial_write(c);
|
||||
}
|
||||
#endif
|
@ -1,8 +0,0 @@
|
||||
#ifndef HAL_SERIAL_H_
|
||||
#define HAL_SERIAL_H_
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
bool serial_init(void);
|
||||
|
||||
#endif // HAL_SERIAL_H_
|
@ -16,6 +16,7 @@
|
||||
#include "kproc/kproc.h"
|
||||
#include "ps2kbproc/ps2kbproc.h"
|
||||
#include "termproc/termproc.h"
|
||||
#include "serialproc/serialproc.h"
|
||||
|
||||
#define PROC_REAPER_FREQ 30
|
||||
|
||||
@ -298,6 +299,9 @@ void proc_init(void) {
|
||||
termproc_init(proc_spawnkern(&termproc_fn, "termproc"));
|
||||
proc_register(TERMPROC);
|
||||
|
||||
serialproc_init(proc_spawnkern(&serialproc_fn, "serialproc"));
|
||||
proc_register(SERIALPROC);
|
||||
|
||||
Proc *init = proc_spawnuser("base", "/bin/init");
|
||||
init->pipes[0] = TERMPROC->pipes[1];
|
||||
proc_register(init);
|
||||
|
73
kernel/proc/serialproc/serialproc.c
Normal file
73
kernel/proc/serialproc/serialproc.c
Normal file
@ -0,0 +1,73 @@
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include "proc/proc.h"
|
||||
#include "ipc/pipe/pipe.h"
|
||||
#include "hal/hal.h"
|
||||
#include "dlmalloc/malloc.h"
|
||||
|
||||
#define SERIAL_PORT 0x3f8
|
||||
|
||||
Proc *SERIALPROC;
|
||||
|
||||
void serialproc_init(Proc *proc) {
|
||||
SERIALPROC = proc;
|
||||
SERIALPROC->pipes[0] = dlmalloc(sizeof(IpcPipe));
|
||||
ipc_pipeinit(SERIALPROC->pipes[0]);
|
||||
SERIALPROC->pipes[1] = dlmalloc(sizeof(IpcPipe));
|
||||
ipc_pipeinit(SERIALPROC->pipes[1]);
|
||||
|
||||
io_out8(SERIAL_PORT + 1, 0x00);
|
||||
io_out8(SERIAL_PORT + 3, 0x80);
|
||||
io_out8(SERIAL_PORT + 0, 0x03);
|
||||
io_out8(SERIAL_PORT + 1, 0x00);
|
||||
io_out8(SERIAL_PORT + 3, 0x03);
|
||||
io_out8(SERIAL_PORT + 2, 0xc7);
|
||||
io_out8(SERIAL_PORT + 4, 0x0b);
|
||||
io_out8(SERIAL_PORT + 4, 0x1e);
|
||||
io_out8(SERIAL_PORT + 0, 0xae);
|
||||
|
||||
if (io_in8(SERIAL_PORT + 0) != 0xae) {
|
||||
return;
|
||||
}
|
||||
|
||||
io_out8(SERIAL_PORT + 4, 0x0f);
|
||||
}
|
||||
|
||||
int serialproc_received(void) {
|
||||
return io_in8(SERIAL_PORT + 5) & 1;
|
||||
}
|
||||
|
||||
uint8_t serialproc_read(void) {
|
||||
while (serialproc_received() == 0);
|
||||
return io_in8(SERIAL_PORT);
|
||||
}
|
||||
|
||||
int serialproc_trans_empty(void) {
|
||||
return io_in8(SERIAL_PORT + 5) & 0x20;
|
||||
}
|
||||
|
||||
void serialproc_write(uint8_t value) {
|
||||
while (!serialproc_trans_empty());
|
||||
io_out8(SERIAL_PORT, value);
|
||||
}
|
||||
|
||||
void serialproc_fn(void) {
|
||||
char buf[0x100];
|
||||
for (;;) {
|
||||
|
||||
hal_memset(buf, 0, sizeof(buf));
|
||||
int32_t read = ipc_piperead(SERIALPROC->pipes[1], (uint8_t *)buf, sizeof(buf));
|
||||
if (read > 0) {
|
||||
for (size_t i = 0; i < sizeof(buf); i++) {
|
||||
serialproc_write(buf[i]);
|
||||
}
|
||||
}
|
||||
|
||||
if (serialproc_received() == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
uint8_t inchar = io_in8(SERIAL_PORT);
|
||||
ipc_pipewrite(SERIALPROC->pipes[0], &inchar, sizeof(inchar));
|
||||
}
|
||||
}
|
11
kernel/proc/serialproc/serialproc.h
Normal file
11
kernel/proc/serialproc/serialproc.h
Normal file
@ -0,0 +1,11 @@
|
||||
#ifndef PROC_SERIALPROC_SERIALPROC_H_
|
||||
#define PROC_SERIALPROC_SERIALPROC_H_
|
||||
|
||||
#include "proc/proc.h"
|
||||
|
||||
extern Proc *SERIALPROC;
|
||||
|
||||
void serialproc_init(Proc *proc);
|
||||
void serialproc_fn(void);
|
||||
|
||||
#endif // PROC_SERIALPROC_SERIALPROC_H_
|
@ -32,6 +32,7 @@ void main(void) {
|
||||
|
||||
if (read > 0 && (kbchar >= 0x20 && kbchar <= 0x7F)) {
|
||||
uprintf("%c", (char)kbchar);
|
||||
ipcpipe(3, 1, IPCPIPE_WRITE, (uint8_t *)&kbchar, 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user