**/.~lock*
workspace/
**.odp
-
+drafts/
--- /dev/null
+#ifndef __LUNAIX_FIFO_BUF_H
+#define __LUNAIX_FIFO_BUF_H
+
+#include <lunaix/ds/mutex.h>
+#include <lunaix/types.h>
+
+#define FIFO_DIRTY 1
+
+struct fifo_buf
+{
+ void* data;
+ size_t wr_pos;
+ size_t rd_pos;
+ size_t size;
+ size_t free_len;
+ size_t flags;
+ mutex_t lock;
+};
+
+int
+fifo_backone(struct fifo_buf* fbuf);
+
+size_t
+fifo_putone(struct fifo_buf* fbuf, uint8_t data);
+
+void
+fifo_init(struct fifo_buf* buf, void* data_buffer, size_t buf_size, int flags);
+
+size_t
+fifo_write(struct fifo_buf* fbuf, void* data, size_t count);
+
+size_t
+fifo_read(struct fifo_buf* fbuf, void* buf, size_t count);
+
+#endif /* __LUNAIX_FIFO_BUF_H */
+++ /dev/null
-#ifndef __LUNAIX_FIFO_BUF_H
-#define __LUNAIX_FIFO_BUF_H
-
-#include <lunaix/ds/mutex.h>
-
-#define FIFO_DIRTY 1
-
-struct fifo_buffer
-{
- void* data;
- unsigned int wr_pos;
- unsigned int rd_pos;
- unsigned int size;
- unsigned int flags;
- mutex_t lock;
-};
-
-#endif /* __LUNAIX_FIFO_BUF_H */
struct console
{
struct lx_timer* flush_timer;
- struct fifo_buffer buffer;
+ struct fifo_buf output;
+ struct fifo_buf input;
unsigned int erd_pos;
unsigned int lines;
};
lseek(fd, 521, FSEEK_SET);
write(fd, test_sequence, sizeof(test_sequence));
- // 读出我们写的内容
char read_out[256];
+ write(tty, "input: ", 8);
+ int size = read(tty, read_out, 256);
+
+ write(tty, "your input: ", 13);
+ write(tty, read_out, size);
+ write(fd, read_out, size);
+ write(tty, "\n", 1);
+
+ // 读出我们写的内容
lseek(fd, 512, FSEEK_SET);
read(fd, read_out, sizeof(read_out));
--- /dev/null
+#include <klibc/string.h>
+#include <lunaix/ds/fifo.h>
+#include <lunaix/ds/mutex.h>
+#include <lunaix/spike.h>
+
+void
+fifo_init(struct fifo_buf* buf, void* data_buffer, size_t buf_size, int flags)
+{
+ *buf = (struct fifo_buf){ .data = data_buffer,
+ .rd_pos = 0,
+ .wr_pos = 0,
+ .size = buf_size,
+ .flags = flags,
+ .free_len = buf_size };
+ mutex_init(&buf->lock);
+}
+
+int
+fifo_backone(struct fifo_buf* fbuf)
+{
+ mutex_lock(&fbuf->lock);
+
+ if (fbuf->free_len == fbuf->size) {
+ mutex_unlock(&fbuf->lock);
+ return 0;
+ }
+
+ fbuf->wr_pos = (fbuf->wr_pos ? fbuf->wr_pos : fbuf->size) - 1;
+ fbuf->free_len++;
+
+ mutex_unlock(&fbuf->lock);
+
+ return 1;
+}
+
+size_t
+fifo_putone(struct fifo_buf* fbuf, uint8_t data)
+{
+ mutex_lock(&fbuf->lock);
+
+ if (!fbuf->free_len) {
+ mutex_unlock(&fbuf->lock);
+ return 0;
+ }
+
+ uint8_t* dest = fbuf->data;
+ dest[fbuf->wr_pos] = data;
+ fbuf->wr_pos = (fbuf->wr_pos + 1) % fbuf->size;
+ fbuf->free_len--;
+
+ mutex_unlock(&fbuf->lock);
+
+ return 1;
+}
+
+size_t
+fifo_write(struct fifo_buf* fbuf, void* data, size_t count)
+{
+ size_t wr_count = 0, wr_pos = fbuf->wr_pos;
+
+ mutex_lock(&fbuf->lock);
+
+ if (!fbuf->free_len) {
+ mutex_unlock(&fbuf->lock);
+ return 0;
+ }
+
+ if (wr_pos >= fbuf->rd_pos) {
+ // case 1
+ size_t cplen_tail = MIN(fbuf->size - wr_pos, count);
+ size_t cplen_head = MIN(fbuf->rd_pos, count - cplen_tail);
+ memcpy(fbuf->data + wr_pos, data, cplen_tail);
+ memcpy(fbuf->data, data + cplen_tail, cplen_head);
+
+ wr_count = cplen_head + cplen_tail;
+ } else {
+ // case 2
+ wr_count = MIN(fbuf->rd_pos - wr_pos, count);
+ memcpy(fbuf->data + wr_pos, data, wr_count);
+ }
+
+ fbuf->wr_pos = (wr_pos + wr_count) % fbuf->size;
+ fbuf->free_len -= wr_count;
+
+ mutex_unlock(&fbuf->lock);
+
+ return wr_count;
+}
+
+size_t
+fifo_read(struct fifo_buf* fbuf, void* buf, size_t count)
+{
+ size_t rd_count = 0, rd_pos = fbuf->rd_pos;
+ mutex_lock(&fbuf->lock);
+
+ if (fbuf->free_len == fbuf->size) {
+ mutex_unlock(&fbuf->lock);
+ return 0;
+ }
+
+ if (rd_pos >= fbuf->wr_pos) {
+ size_t cplen_tail = MIN(fbuf->size - rd_pos, count);
+ size_t cplen_head = MIN(fbuf->wr_pos, count - cplen_tail);
+ memcpy(buf, fbuf->data + rd_pos, cplen_tail);
+ memcpy(buf + cplen_tail, fbuf->data, cplen_head);
+
+ rd_count = cplen_head + cplen_tail;
+ } else {
+ rd_count = MIN(fbuf->wr_pos - rd_pos, count);
+ memcpy(buf, fbuf->data + rd_pos, rd_count);
+ }
+
+ fbuf->rd_pos = (rd_pos + rd_count) % fbuf->size;
+ fbuf->free_len += rd_count;
+
+ mutex_unlock(&fbuf->lock);
+
+ return rd_count;
+}
\ No newline at end of file
goto done;
}
+ cpu_enable_interrupt();
errno = file->ops.read(file, buf, count, file->f_pos);
+ cpu_disable_interrupt();
if (errno > 0) {
file->f_pos += errno;
goto done;
}
+ cpu_enable_interrupt();
errno = file->ops.write(file, buf, count, file->f_pos);
+ cpu_disable_interrupt();
if (errno > 0) {
file->f_pos += errno;
#include <klibc/string.h>
#include <lunaix/device.h>
+#include <lunaix/keyboard.h>
#include <lunaix/lxconsole.h>
#include <lunaix/mm/pmm.h>
+#include <lunaix/mm/valloc.h>
#include <lunaix/mm/vmm.h>
#include <lunaix/tty/console.h>
#include <lunaix/tty/tty.h>
static struct console lx_console;
int
-__tty_write(struct device* dev,
- void* buf,
- unsigned int offset,
- unsigned int len);
+__tty_write(struct device* dev, void* buf, size_t offset, size_t len);
+
+int
+__tty_read(struct device* dev, void* buf, size_t offset, size_t len);
void
lxconsole_init()
{
memset(&lx_console, 0, sizeof(lx_console));
- lx_console.buffer.data = VGA_BUFFER_VADDR + 0x1000;
- lx_console.buffer.size = 8192;
- mutex_init(&lx_console.buffer.lock);
+ fifo_init(&lx_console.output, VGA_BUFFER_VADDR + 0x1000, 8192, 0);
+ fifo_init(&lx_console.input, valloc(4096), 4096, 0);
+
+ // FIXME use valloc to allocate console buffer.
+ // In doing this, the console buffer can only be accessed from kernel mode
+ // any direct write to this buffer from user land should be purged!
// 分配控制台缓存
- for (size_t i = 0; i < PG_ALIGN(lx_console.buffer.size); i += PG_SIZE) {
+ for (size_t i = 0; i < PG_ALIGN(lx_console.output.size); i += PG_SIZE) {
uintptr_t pa = pmm_alloc_page(KERNEL_PID, 0);
vmm_set_mapping(PD_REFERENCED,
- (uintptr_t)lx_console.buffer.data + i,
+ (uintptr_t)lx_console.output.data + i,
pa,
PG_PREM_URW,
0);
}
- memset(lx_console.buffer.data, 0, lx_console.buffer.size);
-
lx_console.flush_timer = NULL;
struct device* tty_dev = device_addseq(NULL, &lx_console, "tty");
tty_dev->write = __tty_write;
+ tty_dev->read = __tty_read;
}
int
-__tty_write(struct device* dev,
- void* buf,
- unsigned int offset,
- unsigned int len)
+__tty_write(struct device* dev, void* buf, size_t offset, size_t len)
{
struct console* console = (struct console*)dev->underlay;
console_write(console, buf, len);
}
+int
+__tty_read(struct device* dev, void* buf, size_t offset, size_t len)
+{
+ struct kdb_keyinfo_pkt keyevent;
+ struct console* console = (struct console*)dev->underlay;
+ while (1) {
+ // FIXME keyboard is duplicating the key that user typed
+ if (!kbd_recv_key(&keyevent)) {
+ continue;
+ }
+ if ((keyevent.keycode & 0xff00) <= KEYPAD) {
+ char c = (char)(keyevent.keycode & 0x00ff);
+ if (c == 0x08 && !fifo_backone(&console->input)) {
+ continue;
+ }
+ // console_write_char(c);
+ if (!fifo_putone(&console->input, c) || c == '\n') {
+ break;
+ }
+ }
+ }
+ return fifo_read(&console->input, buf, len);
+}
+
void
console_schedule_flush()
{
void
console_view_up()
{
- struct fifo_buffer* buffer = &lx_console.buffer;
+ struct fifo_buf* buffer = &lx_console.output;
mutex_lock(&buffer->lock);
size_t p = lx_console.erd_pos - 2;
while (p < lx_console.erd_pos && p != buffer->wr_pos &&
__find_next_line(size_t start)
{
size_t p = start;
- while (p != lx_console.buffer.wr_pos &&
- ((char*)lx_console.buffer.data)[p] != '\n') {
- p = (p + 1) % lx_console.buffer.size;
+ while (p != lx_console.output.wr_pos &&
+ ((char*)lx_console.output.data)[p] != '\n') {
+ p = (p + 1) % lx_console.output.size;
}
return p + 1;
}
void
console_view_down()
{
- struct fifo_buffer* buffer = &lx_console.buffer;
+ struct fifo_buf* buffer = &lx_console.output;
mutex_lock(&buffer->lock);
lx_console.erd_pos = __find_next_line(lx_console.erd_pos);
void
console_flush()
{
- if (mutex_on_hold(&lx_console.buffer.lock)) {
+ if (mutex_on_hold(&lx_console.output.lock)) {
return;
}
- if (!(lx_console.buffer.flags & FIFO_DIRTY)) {
+ if (!(lx_console.output.flags & FIFO_DIRTY)) {
return;
}
- tty_flush_buffer(lx_console.buffer.data,
+ tty_flush_buffer(lx_console.output.data,
lx_console.erd_pos,
- lx_console.buffer.wr_pos,
- lx_console.buffer.size);
- lx_console.buffer.flags &= ~FIFO_DIRTY;
+ lx_console.output.wr_pos,
+ lx_console.output.size);
+ lx_console.output.flags &= ~FIFO_DIRTY;
}
void
console_write(struct console* console, uint8_t* data, size_t size)
{
- mutex_lock(&console->buffer.lock);
- uint8_t* buffer = console->buffer.data;
- uintptr_t ptr = console->buffer.wr_pos;
- uintptr_t rd_ptr = console->buffer.rd_pos;
+ mutex_lock(&console->output.lock);
+ uint8_t* buffer = console->output.data;
+ uintptr_t ptr = console->output.wr_pos;
+ uintptr_t rd_ptr = console->output.rd_pos;
char c;
int lines = 0;
if (!c) {
continue;
}
- buffer[(ptr + j) % console->buffer.size] = c;
+ buffer[(ptr + j) % console->output.size] = c;
lines += (c == '\n');
j++;
}
size = j;
- uintptr_t new_ptr = (ptr + size) % console->buffer.size;
- console->buffer.wr_pos = new_ptr;
+ uintptr_t new_ptr = (ptr + size) % console->output.size;
+ console->output.wr_pos = new_ptr;
if (console->lines > TTY_HEIGHT && lines > 0) {
- console->buffer.rd_pos =
- __find_next_line((size + rd_ptr) % console->buffer.size);
+ console->output.rd_pos =
+ __find_next_line((size + rd_ptr) % console->output.size);
}
if (new_ptr < ptr + size && new_ptr > rd_ptr) {
- console->buffer.rd_pos = new_ptr;
+ console->output.rd_pos = new_ptr;
}
console->lines += lines;
- console->erd_pos = console->buffer.rd_pos;
- console->buffer.flags |= FIFO_DIRTY;
- mutex_unlock(&console->buffer.lock);
+ console->erd_pos = console->output.rd_pos;
+ console->output.flags |= FIFO_DIRTY;
+ mutex_unlock(&console->output.lock);
}
void
#include <klibc/string.h>
#include <lunaix/mm/cake.h>
#include <lunaix/mm/valloc.h>
+#include <lunaix/spike.h>
#define CLASS_LEN(class) (sizeof(class) / sizeof(class[0]))
static char piles_names[][PILE_NAME_MAXLEN] = {
- "valloc_8", "valloc_16", "valloc_32", "valloc_64", "valloc_128",
- "valloc_256", "valloc_512", "valloc_1k", "valloc_2k", "valloc_4k"
+ "valloc_8", "valloc_16", "valloc_32", "valloc_64",
+ "valloc_128", "valloc_256", "valloc_512", "valloc_1k",
+ "valloc_2k", "valloc_4k", "valloc_8k"
};
static char piles_names_dma[][PILE_NAME_MAXLEN] = {
{
for (size_t i = 0; i < CLASS_LEN(piles_names); i++) {
int size = 1 << (i + 3);
- piles[i] = cake_new_pile(&piles_names[i], size, size > 1024 ? 4 : 1, 0);
+ piles[i] = cake_new_pile(&piles_names[i], size, size > 1024 ? 8 : 1, 0);
}
// DMA 内存保证128字节对齐
}
void*
-__valloc(unsigned int size, struct cake_pile** segregate_list, size_t len)
+__valloc(unsigned int size,
+ struct cake_pile** segregate_list,
+ size_t len,
+ size_t boffset)
{
- size_t i = 0;
- for (; i < len; i++) {
- if (segregate_list[i]->piece_size >= size) {
- goto found_class;
- }
- }
+ size_t i = ILOG2(size);
+ i += (size - (1 << i) != 0);
+ i -= boffset;
- return NULL;
+ if (i >= len)
+ return NULL;
-found_class:
return cake_grab(segregate_list[i]);
}
void*
valloc(unsigned int size)
{
- return __valloc(size, &piles, CLASS_LEN(piles_names));
+ return __valloc(size, &piles, CLASS_LEN(piles_names), 3);
}
void*
vzalloc(unsigned int size)
{
- void* ptr = __valloc(size, &piles, CLASS_LEN(piles_names));
+ void* ptr = __valloc(size, &piles, CLASS_LEN(piles_names), 3);
memset(ptr, 0, size);
return ptr;
}
return 0;
}
- void* ptr = __valloc(alloc_size, &piles, CLASS_LEN(piles_names));
+ void* ptr = __valloc(alloc_size, &piles, CLASS_LEN(piles_names), 3);
memset(ptr, 0, alloc_size);
return ptr;
}
void*
valloc_dma(unsigned int size)
{
- return __valloc(size, &piles_dma, CLASS_LEN(piles_names_dma));
+ return __valloc(size, &piles_dma, CLASS_LEN(piles_names_dma), 7);
}
void*
vzalloc_dma(unsigned int size)
{
- void* ptr = __valloc(size, &piles_dma, CLASS_LEN(piles_names_dma));
+ void* ptr = __valloc(size, &piles_dma, CLASS_LEN(piles_names_dma), 7);
memset(ptr, 0, size);
return ptr;
}
continue;
}
if ((keyevent.state & KBD_KEY_FPRESSED)) {
- if ((keyevent.keycode & 0xff00) <= KEYPAD) {
- console_write_char((char)(keyevent.keycode & 0x00ff));
- } else if (keyevent.keycode == KEY_UP) {
+ if (keyevent.keycode == KEY_UP) {
console_view_up();
} else if (keyevent.keycode == KEY_DOWN) {
console_view_down();