summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAlex AUVOLAT <alexis211@gmail.com>2013-07-11 22:38:20 +0200
committerAlex AUVOLAT <alexis211@gmail.com>2013-07-11 22:38:20 +0200
commitd2aebee488b71e6f28b8728e7473b63f412ca897 (patch)
treefbe432590bfcf0b77b189a3db99762fb4f104f39 /src
parent78d7ffce4861dea5624ff29ceb39f1643dff8235 (diff)
downloadTCE-std_c_userland.tar.gz
TCE-std_c_userland.zip
Added direct acces to video memory from userland.std_c_userland
Next : same for keyboard ; move VT handling to userland. Consequence : a foreground app has total control over I/O. Next : implement sockets & a userland console multiplexer.
Diffstat (limited to 'src')
-rw-r--r--src/include/tce/syscalls.h1
-rw-r--r--src/include/tce/vfs.h7
-rw-r--r--src/kernel/dev/display.h1
-rw-r--r--src/kernel/dev/keyboard.cpp2
-rw-r--r--src/kernel/dev/ps2keyboard.cpp1
-rw-r--r--src/kernel/dev/vgatxt.cpp34
-rw-r--r--src/kernel/dev/vgatxt.h7
-rw-r--r--src/kernel/mem/paging.cpp1
-rw-r--r--src/kernel/task/syscall.cpp5
-rw-r--r--src/kernel/vfs/node.cpp6
-rw-r--r--src/kernel/vfs/node.h2
-rw-r--r--src/user/app/test/main.c48
-rw-r--r--src/user/app/yosh/main.c6
13 files changed, 96 insertions, 25 deletions
diff --git a/src/include/tce/syscalls.h b/src/include/tce/syscalls.h
index f32c225..983e89d 100644
--- a/src/include/tce/syscalls.h
+++ b/src/include/tce/syscalls.h
@@ -28,6 +28,7 @@
#define SC_READ 26
#define SC_WRITE 27
#define SC_LINK 28
+#define SC_DEVCONTROL 29
#define EX_PAGEFAULT 4000
#define EX_EXCEPTION 4001
diff --git a/src/include/tce/vfs.h b/src/include/tce/vfs.h
index 36e391f..58e67f5 100644
--- a/src/include/tce/vfs.h
+++ b/src/include/tce/vfs.h
@@ -33,7 +33,10 @@ typedef struct _file_info {
// device types
#define DT_BLOCK 1
-#define DT_KEYBOARD 2
-#define DT_DISPLAY 3
+#define DT_PCKBD 2
+#define DT_VGATXT 3
+#define DT_VESAFB 4
+
+#define DEV_CONTROL 0xB0057ED1 // hack, see doc/vfs.txt
#endif
diff --git a/src/kernel/dev/display.h b/src/kernel/dev/display.h
index ec67e7e..963b5e6 100644
--- a/src/kernel/dev/display.h
+++ b/src/kernel/dev/display.h
@@ -22,7 +22,6 @@ class display : public node {
vt *connected_vt;
display(node* parent) : node(parent, FT_DEV) {
- dev_type = DT_DISPLAY;
connected_vt = 0;
}
virtual ~display() {}
diff --git a/src/kernel/dev/keyboard.cpp b/src/kernel/dev/keyboard.cpp
index 3f54b99..af4c380 100644
--- a/src/kernel/dev/keyboard.cpp
+++ b/src/kernel/dev/keyboard.cpp
@@ -77,7 +77,7 @@ static keymap default_km = {
};
keyboard::keyboard(node *parent) : node(parent, FT_DEV) {
- dev_type = DT_KEYBOARD;
+ dev_type = DT_PCKBD;
km = &default_km;
num = true;
diff --git a/src/kernel/dev/ps2keyboard.cpp b/src/kernel/dev/ps2keyboard.cpp
index 31cd75f..c7fc322 100644
--- a/src/kernel/dev/ps2keyboard.cpp
+++ b/src/kernel/dev/ps2keyboard.cpp
@@ -53,3 +53,4 @@ void ps2kbd::kbdIrq() {
escaped = false;
}
}
+
diff --git a/src/kernel/dev/vgatxt.cpp b/src/kernel/dev/vgatxt.cpp
index eb57eb9..7abbaf9 100644
--- a/src/kernel/dev/vgatxt.cpp
+++ b/src/kernel/dev/vgatxt.cpp
@@ -4,11 +4,12 @@
#include <mem/mem.h>
static uint16_t *video_memory = (uint16_t*)((size_t)K_HIGHHALF_ADDR + 0xB8000);
+#define VIDMEM_SIZE (80 * 25 * 2)
vgatxt *text_display;
vgatxt::vgatxt(node *parent) : display(parent) {
- // nothing to do, really
+ dev_type = DT_VGATXT;
}
int vgatxt::text_w() {
@@ -52,3 +53,34 @@ void vgatxt::text_scroll(int n, uint8_t fgcolor, uint8_t bgcolor) {
// TODO
}
}
+
+
+// Operations as a FS node
+
+size_t vgatxt::get_size() { // size as a node of the filesystem
+ return (text_w() << 16) + text_h();
+}
+
+int vgatxt::read(size_t offset, size_t len, char *buffer) {
+ if (offset > VIDMEM_SIZE) return 0;
+ if (offset + len > VIDMEM_SIZE) len = VIDMEM_SIZE - offset;
+
+ char *vm = (char*)video_memory;
+ memcpy(buffer, vm + offset, len);
+ return len;
+}
+
+int vgatxt::write(size_t offset, size_t len, char *buffer) {
+ if (offset > VIDMEM_SIZE) return 0;
+ if (offset + len > VIDMEM_SIZE) len = VIDMEM_SIZE - offset;
+
+ char *vm = (char*)video_memory;
+ memcpy(vm + offset, buffer, len);
+ return len;
+}
+
+int vgatxt::dev_control(char *data) {
+ uint16_t *d = (uint16_t*)data;
+ text_setcsr(d[0], d[1], d[2] != 0);
+ return 0;
+}
diff --git a/src/kernel/dev/vgatxt.h b/src/kernel/dev/vgatxt.h
index 550d4ba..bed743e 100644
--- a/src/kernel/dev/vgatxt.h
+++ b/src/kernel/dev/vgatxt.h
@@ -10,6 +10,13 @@ class vgatxt : public display {
vgatxt(node *parent);
virtual ~vgatxt() {}
+ // as a FS node
+ virtual size_t get_size();
+ virtual int read(size_t offset, size_t len, char *buffer);
+ virtual int write(size_t offset, size_t len, char *buffer);
+ virtual int dev_control(char *data);
+
+ // as a display
virtual int text_w();
virtual int text_h();
virtual void text_setcsr(int l, int c, bool visible);
diff --git a/src/kernel/mem/paging.cpp b/src/kernel/mem/paging.cpp
index 436c888..4878ab3 100644
--- a/src/kernel/mem/paging.cpp
+++ b/src/kernel/mem/paging.cpp
@@ -146,6 +146,7 @@ uint32_t paging_fault(registers *regs) {
if (regs->err_code & 0x4) dbg_printf(" user");
if (regs->err_code & 0x8) dbg_printf(" rsvd");
if (regs->err_code & 0x10) dbg_printf(" opfetch");
+ dbg_printf("\n");
return 1;
}
return 0;
diff --git a/src/kernel/task/syscall.cpp b/src/kernel/task/syscall.cpp
index a3074b8..2e1350e 100644
--- a/src/kernel/task/syscall.cpp
+++ b/src/kernel/task/syscall.cpp
@@ -78,6 +78,10 @@ static void link_sc(registers *r) {
r->eax = link((char*)r->ebx, (char*)r->ecx, r->edx);
}
+static void devcontrol_sc(registers *r) {
+ r->eax = dev_control(r->ebx, (char*)r->ecx);
+}
+
int_callback syscalls[NUMBER_OF_SYSCALLS] = { // This must correspond to common/include/tce/syscalls.h
0, // 0
@@ -109,6 +113,7 @@ int_callback syscalls[NUMBER_OF_SYSCALLS] = { // This must correspond to common
read_sc,
write_sc,
link_sc,
+ devcontrol_sc,
0
};
diff --git a/src/kernel/vfs/node.cpp b/src/kernel/vfs/node.cpp
index 0b753af..d5d4c65 100644
--- a/src/kernel/vfs/node.cpp
+++ b/src/kernel/vfs/node.cpp
@@ -126,3 +126,9 @@ int link(char* from, char* to, int mode) {
node *f2 = (to == 0 ? 0 : vfs_find(root, to));
return f1->link(f2, mode);
}
+
+int dev_control(FILE file, char *data) {
+ node *f = vfs_read_fd(file);
+ if (f == 0) return E_INVALID_FD;
+ return f->dev_control(data);
+}
diff --git a/src/kernel/vfs/node.h b/src/kernel/vfs/node.h
index 3b1c700..7fbc205 100644
--- a/src/kernel/vfs/node.h
+++ b/src/kernel/vfs/node.h
@@ -28,6 +28,7 @@ class node {
virtual int add_child(char* name, node *child) { return E_NOT_IMPLEMENTED; }
virtual size_t get_size() { return 0; }
virtual int link(node* other, int mode) { return E_NOT_IMPLEMENTED; }
+ virtual int dev_control(char *data) { return E_NOT_IMPLEMENTED; }
// kind of like dynamic_cast'ing these things
virtual display *as_display() { return 0; }
@@ -51,5 +52,6 @@ void close(FILE file);
int read(FILE file, size_t offset, size_t len, char *buffer);
int write(FILE file, size_t offset, size_t len, char *buffer);
int link(char* from, char* to, int mode);
+int dev_control(FILE file, char *data);
#endif
diff --git a/src/user/app/test/main.c b/src/user/app/test/main.c
index 2c42cf8..d9b6332 100644
--- a/src/user/app/test/main.c
+++ b/src/user/app/test/main.c
@@ -1,14 +1,34 @@
#include <tce/syscall.h>
#include <stdio.h>
#include <stdlib.h>
+#include <sched.h>
int threads = 1;
+mutex_t d_mutex = MUTEX_UNLOCKED;
+int d_pos = 0;
+int vgatxt = -1;
+
+void display_it(char k) {
+ mutex_lock(&d_mutex);
+
+ // just display some stuff on /.dev/vgatxt
+ if (vgatxt == -1) {
+ vgatxt = open("/.dev/vgatxt", FM_READ | FM_WRITE);
+ }
+ uint16_t c = k | (4 << 8);
+ write(vgatxt, 2 * d_pos, 2, (char*)&c);
+
+ d_pos++;
+
+ mutex_unlock(&d_mutex);
+}
+
void thread_cascade(void* d) {
int n = (int)d;
char *v = malloc(2048);
- if (!v) printk("!");
+ if (!v) display_it('!');
if (d == 0) {
//printk("{#} 0 cascade element started => end\n");
@@ -16,21 +36,21 @@ void thread_cascade(void* d) {
} else {
if (n < 0) {
//printk("{#} - cascade element started\n");
- printk("-");
+ display_it('-');
n = 0 - n;
} else {
//printk("{#} + cascade element started\n");
- printk("+");
+ display_it('+');
}
//printk("{#} FORK + ...\n");
- printk(">");
+ display_it('>');
threads += 2;
thread_new(thread_cascade, (void*)(n - 1));
//printk("{#} FORK - ...\n");
- printk("<");
+ display_it('<');
thread_new(thread_cascade, (void*)(1 - n));
//printk("{#} Thread cascade element finished.\n");
- printk(".");
+ display_it('.');
}
free(v);
@@ -40,25 +60,15 @@ void thread_cascade(void* d) {
void useless_thread(void* d) {
while(1) {
- printk("~");
+ display_it('~');
schedule();
}
}
int main(int argc, char** args) {
- char**a;
- if (args != 0) {
- printk("(test) args");
- for (a = args; *a != 0; a++) {
- printk(" - ");
- printk(*a);
- }
- printk("\n");
- }
-
- printk("(test) Creating thread cascade (total 2**6 = 64 threads)\n");
+ printk("(test) Creating thread cascade (total 2**7 = 128 threads)\n");
thread_new(useless_thread, 0);
- thread_new(thread_cascade, (void*)6);
+ thread_new(thread_cascade, (void*)7);
while (1) {
schedule();
diff --git a/src/user/app/yosh/main.c b/src/user/app/yosh/main.c
index f7ee7e7..e989dc1 100644
--- a/src/user/app/yosh/main.c
+++ b/src/user/app/yosh/main.c
@@ -80,7 +80,11 @@ void ls_dir(int fd) {
printf("\t");
if (info.type & FT_TERMINAL) {
printf("%ix%i", info.size >> 16, info.size & 0xFFFF);
- } else if ((info.type & FT_DEV) == 0) {
+ } else if (info.type & FT_DEV) {
+ if (info.dev_type == DT_VGATXT) {
+ printf("%ix%i", info.size >> 16, info.size & 0xFFFF);
+ }
+ } else {
printf("%i", info.size);
}