aboutsummaryrefslogtreecommitdiff
path: root/kernel
diff options
context:
space:
mode:
authorMarvin Borner2021-04-30 22:30:46 +0200
committerMarvin Borner2021-04-30 22:30:46 +0200
commited4d960607d754c407a6964af86afcf0ad294123 (patch)
treeb27d1089931b50a8f67d054490862862959b0a66 /kernel
parent350748137b62e2aa15c62c53ebf4d30816e441f4 (diff)
Some small fixes here and there
Diffstat (limited to 'kernel')
-rw-r--r--kernel/drivers/fb.c13
-rw-r--r--kernel/drivers/gdt.c33
-rw-r--r--kernel/drivers/interrupts.c2
-rw-r--r--kernel/features/proc.c8
-rw-r--r--kernel/features/syscall.c4
-rw-r--r--kernel/inc/proc.h1
6 files changed, 45 insertions, 16 deletions
diff --git a/kernel/drivers/fb.c b/kernel/drivers/fb.c
index 2a29eb7..8831a52 100644
--- a/kernel/drivers/fb.c
+++ b/kernel/drivers/fb.c
@@ -24,12 +24,11 @@ struct vbe_basic {
PROTECTED static struct vbe_basic *vbe = NULL;
-static void fb_map_buffer(struct page_dir *dir)
+static u32 fb_map_buffer(struct page_dir *dir)
{
- // TODO: Return virtual mapped address
assert(vbe);
u32 size = vbe->height * vbe->pitch;
- memory_map_identity(dir, memory_range_around((u32)vbe->fb, size), MEMORY_USER);
+ return virtual_alloc(dir, memory_range_around((u32)vbe->fb, size), MEMORY_USER).base;
}
static u32 fb_owner = 0;
@@ -52,8 +51,9 @@ static res fb_ioctl(u32 request, void *arg1, void *arg2, void *arg3)
else
fb_owner = proc_current()->pid;
+ u32 fb = fb_map_buffer(proc_current()->page_dir);
+ vbe->fb = (u8 *)fb;
memcpy_user(arg1, vbe, size);
- fb_map_buffer(proc_current()->page_dir);
return EOK;
}
default:
@@ -69,5 +69,8 @@ CLEAR void fb_install(void)
dev->control = fb_ioctl;
io_add(IO_FRAMEBUFFER, dev);
- fb_map_buffer(virtual_kernel_dir());
+ // Identity map framebuffer to kernel to prevent unwanted writing
+ u32 size = vbe->height * vbe->pitch;
+ memory_map_identity(virtual_kernel_dir(), memory_range_around((u32)vbe->fb, size),
+ MEMORY_CLEAR);
}
diff --git a/kernel/drivers/gdt.c b/kernel/drivers/gdt.c
index 66a9086..8209eaf 100644
--- a/kernel/drivers/gdt.c
+++ b/kernel/drivers/gdt.c
@@ -5,6 +5,17 @@
#include <gdt.h>
#include <mem.h>
+#define GDT_MAX_LIMIT 0xffff
+#define GDT_PRESENT (1 << 7)
+#define GDT_RING3 (3 << 5)
+#define GDT_DESCRIPTOR (1 << 4)
+#define GDT_EXECUTABLE (1 << 3)
+#define GDT_READWRITE (1 << 1)
+#define GDT_ACCESSED (1 << 0)
+#define GDT_GRANULARITY (0x80 | 0x00)
+#define GDT_SIZE (0x40 | 0x00)
+#define GDT_DATA_OFFSET 0x10
+
static struct gdt_entry gdt[6] = { 0 };
static struct tss_entry tss = { 0 };
@@ -24,12 +35,14 @@ CLEAR static void gdt_set_gate(u32 num, u32 base, u32 limit, u8 access, u8 gran)
gdt[num].access = access;
}
+// TODO: Fix GPF for in/out operations in userspace (not necessarily a TSS problem)
CLEAR static void tss_write(u32 num, u16 ss0, u32 esp0)
{
u32 base = (u32)&tss;
u32 limit = base + sizeof(tss);
- gdt_set_gate(num, base, limit, 0xe9, 0x00);
+ gdt_set_gate(num, base, limit, GDT_PRESENT | GDT_RING3 | GDT_EXECUTABLE | GDT_ACCESSED,
+ GDT_SIZE);
memset(&tss, 0, sizeof(tss));
@@ -41,7 +54,7 @@ CLEAR static void tss_write(u32 num, u16 ss0, u32 esp0)
CLEAR static void tss_flush(void)
{
- __asm__ volatile("ltr %0" ::"r"((u16)0x2b));
+ __asm__ volatile("ltr %0" ::"r"((u16)((u32)&gdt[5] - (u32)gdt)));
}
CLEAR static void gdt_flush(void)
@@ -59,23 +72,29 @@ void tss_set_stack(u32 ss, u32 esp)
CLEAR void gdt_install(u32 esp)
{
// Set GDT pointer and limit
- gp.limit = (sizeof(struct gdt_entry) * 6) - 1;
+ gp.limit = sizeof(gdt) - 1;
gp.base = &gdt;
// NULL descriptor
gdt_set_gate(0, 0, 0, 0, 0);
// Code segment
- gdt_set_gate(1, 0, 0xffffffff, 0x9a, 0xcf);
+ gdt_set_gate(1, 0, 0xffffffff,
+ GDT_PRESENT | GDT_DESCRIPTOR | GDT_EXECUTABLE | GDT_READWRITE,
+ GDT_GRANULARITY | GDT_SIZE);
// Data segment
- gdt_set_gate(2, 0, 0xffffffff, 0x92, 0xcf);
+ gdt_set_gate(2, 0, 0xffffffff, GDT_PRESENT | GDT_DESCRIPTOR | GDT_READWRITE,
+ GDT_GRANULARITY | GDT_SIZE);
// User mode code segment
- gdt_set_gate(3, 0, 0xffffffff, 0xfa, 0xcf);
+ gdt_set_gate(3, 0, 0xffffffff,
+ GDT_PRESENT | GDT_RING3 | GDT_DESCRIPTOR | GDT_EXECUTABLE | GDT_READWRITE,
+ GDT_GRANULARITY | GDT_SIZE);
// User mode data segment
- gdt_set_gate(4, 0, 0xffffffff, 0xf2, 0xcf);
+ gdt_set_gate(4, 0, 0xffffffff, GDT_PRESENT | GDT_RING3 | GDT_DESCRIPTOR | GDT_READWRITE,
+ GDT_GRANULARITY | GDT_SIZE);
// Write TSS
tss_write(5, GDT_SUPER_DATA_OFFSET, esp);
diff --git a/kernel/drivers/interrupts.c b/kernel/drivers/interrupts.c
index 5b94b94..7a57a91 100644
--- a/kernel/drivers/interrupts.c
+++ b/kernel/drivers/interrupts.c
@@ -188,7 +188,7 @@ void isr_panic(struct regs *r)
} else {
__asm__ volatile("cli\nhlt");
}
- proc_yield();
+ proc_yield_regs(r);
}
void isr_handler(struct regs *r);
diff --git a/kernel/features/proc.c b/kernel/features/proc.c
index 36ee6b9..3039231 100644
--- a/kernel/features/proc.c
+++ b/kernel/features/proc.c
@@ -185,7 +185,7 @@ void proc_exit(struct proc *proc, struct regs *r, s32 status)
free(proc);
- proc_yield();
+ proc_yield_regs(r);
}
void proc_yield(void)
@@ -195,6 +195,12 @@ void proc_yield(void)
__asm__ volatile("int $127");
}
+void proc_yield_regs(struct regs *r)
+{
+ proc_reset_quantum(PROC(current));
+ scheduler(r);
+}
+
struct proc *proc_make(enum proc_priv priv)
{
struct proc *proc = zalloc(sizeof(*proc));
diff --git a/kernel/features/syscall.c b/kernel/features/syscall.c
index 23c8d37..b66cd2e 100644
--- a/kernel/features/syscall.c
+++ b/kernel/features/syscall.c
@@ -88,7 +88,7 @@ static void syscall_handler(struct regs *r)
} else {
// TODO: Reimplement argc,argv
proc_stack_push(proc, 0);
- proc_yield();
+ proc_yield_regs(r);
}
break;
}
@@ -99,7 +99,7 @@ static void syscall_handler(struct regs *r)
}
case SYS_YIELD: {
r->eax = EOK;
- proc_yield();
+ proc_yield_regs(r);
break;
}
diff --git a/kernel/inc/proc.h b/kernel/inc/proc.h
index e74286c..000d77d 100644
--- a/kernel/inc/proc.h
+++ b/kernel/inc/proc.h
@@ -60,6 +60,7 @@ u8 proc_idle(void);
struct proc *proc_from_pid(u32 pid);
void proc_exit(struct proc *proc, struct regs *r, s32 status) NONNULL;
void proc_yield(void);
+void proc_yield_regs(struct regs *r) NONNULL;
void proc_set_quantum(struct proc *proc, u32 value);
void proc_reset_quantum(struct proc *proc);
void proc_state(struct proc *proc, enum proc_state state);