80 lines
1.9 KiB
C
80 lines
1.9 KiB
C
#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->pid);
|
|
SERIALPROC->pipes[1] = dlmalloc(sizeof(IpcPipe));
|
|
ipc_pipeinit(SERIALPROC->pipes[1], SERIALPROC->pid);
|
|
|
|
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));
|
|
spinlock_acquire(&SERIALPROC->pipes_spinlock);
|
|
IpcPipe *inpipe = SERIALPROC->pipes[1];
|
|
spinlock_release(&SERIALPROC->pipes_spinlock);
|
|
int32_t read = ipc_piperead(inpipe, (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);
|
|
spinlock_acquire(&SERIALPROC->pipes_spinlock);
|
|
IpcPipe *outpipe = SERIALPROC->pipes[0];
|
|
spinlock_release(&SERIALPROC->pipes_spinlock);
|
|
ipc_pipewrite(outpipe, &inchar, sizeof(inchar));
|
|
}
|
|
}
|