aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--kernel/drivers/fpu.c24
-rw-r--r--kernel/drivers/mouse.c4
-rw-r--r--kernel/features/proc.c4
-rw-r--r--kernel/inc/proc.h2
-rw-r--r--kernel/main.c1
-rw-r--r--libc/cpu.c98
-rw-r--r--libc/inc/cpu.h84
-rw-r--r--libc/inc/print.h1
-rw-r--r--libc/mem.c65
-rw-r--r--libc/print.c10
10 files changed, 220 insertions, 73 deletions
diff --git a/kernel/drivers/fpu.c b/kernel/drivers/fpu.c
deleted file mode 100644
index e61e267..0000000
--- a/kernel/drivers/fpu.c
+++ /dev/null
@@ -1,24 +0,0 @@
-// MIT License, Copyright (c) 2020 Marvin Borner
-
-#include <def.h>
-
-void set_fpu_cw(const u16 cw)
-{
- __asm__ volatile("fldcw %0" ::"m"(cw));
-}
-
-void fpu_install(void)
-{
- __asm__ volatile("clts");
- u32 t = 0;
- __asm__ volatile("mov %%cr0, %0" : "=r"(t));
- t &= (u32) ~(1 << 2);
- t |= (1 << 1);
- __asm__ volatile("mov %0, %%cr0" ::"r"(t));
-
- __asm__ volatile("mov %%cr4, %0" : "=r"(t));
- t |= 3 << 9;
- __asm__ volatile("mov %0, %%cr4" ::"r"(t));
-
- __asm__ volatile("fninit");
-}
diff --git a/kernel/drivers/mouse.c b/kernel/drivers/mouse.c
index 6f329aa..e2f7311 100644
--- a/kernel/drivers/mouse.c
+++ b/kernel/drivers/mouse.c
@@ -116,6 +116,10 @@ void mouse_install(void)
mouse_serial_wait(1);
outb(0x60, status);
+ // Use default settings
+ mouse_serial_write(0xF6);
+ mouse_serial_read();
+
// Enable mousewheel
mouse_serial_write(0xF2);
mouse_serial_read();
diff --git a/kernel/features/proc.c b/kernel/features/proc.c
index 0c8f75c..d5cc82c 100644
--- a/kernel/features/proc.c
+++ b/kernel/features/proc.c
@@ -68,6 +68,9 @@ void scheduler(struct regs *regs)
regs->eflags = EFLAGS_ALWAYS | EFLAGS_INTERRUPTS;
}
+ if (current == idle_proc)
+ quantum = 0;
+
/* printf("{%d}", ((struct proc *)current->data)->pid); */
}
@@ -481,6 +484,7 @@ void proc_init(void)
((u32 *)_esp)[0] = argc; // First argument (argc)
((u32 *)_esp)[1] = (u32)argv; // Second argument (argv)
+ printf("Jumping to userspace!\n");
proc_jump_userspace();
while (1) {
};
diff --git a/kernel/inc/proc.h b/kernel/inc/proc.h
index a727210..cd74b40 100644
--- a/kernel/inc/proc.h
+++ b/kernel/inc/proc.h
@@ -9,7 +9,7 @@
#include <stack.h>
#include <sys.h>
-#define PROC_QUANTUM 42 // Milliseconds or something // TODO
+#define PROC_QUANTUM 10 // Milliseconds or something // TODO
#define EFLAGS_ALWAYS 0x2 // Always one
#define EFLAGS_INTERRUPTS 0x200 // Enable interrupts
diff --git a/kernel/main.c b/kernel/main.c
index 5216401..dea92d7 100644
--- a/kernel/main.c
+++ b/kernel/main.c
@@ -27,6 +27,7 @@ void kernel_main(struct vid_info *vid_info)
serial_print("\nKernel was compiled at " __TIME__ " on " __DATE__ "\n");
serial_print("Serial connected.\n");
+ cpu_enable_features();
cpu_print();
// Install drivers
diff --git a/libc/cpu.c b/libc/cpu.c
index 52c0280..2eb6c46 100644
--- a/libc/cpu.c
+++ b/libc/cpu.c
@@ -48,41 +48,91 @@ void outl(u16 port, u32 data)
__asm__ volatile("outl %0, %1" ::"a"(data), "Nd"(port));
}
-void cpuid(int code, u32 *a, u32 *b, u32 *c, u32 *d)
+#ifdef kernel
+
+static void cpuid(int code, u32 *a, u32 *b, u32 *c, u32 *d)
{
__asm__ volatile("cpuid" : "=a"(*a), "=b"(*b), "=c"(*c), "=d"(*d) : "a"(code));
}
-char *cpu_string(char buf[13])
-{
- u32 a, b, c, d;
- cpuid(CPUID_VENDOR_STRING, &a, &b, &c, &d);
- char *ebx = (char *)&b;
- char *ecx = (char *)&c;
- char *edx = (char *)&d;
- buf[0] = ebx[0];
- buf[1] = ebx[1];
- buf[2] = ebx[2];
- buf[3] = ebx[3];
- buf[4] = edx[0];
- buf[5] = edx[1];
- buf[6] = edx[2];
- buf[7] = edx[3];
- buf[8] = ecx[0];
- buf[9] = ecx[1];
- buf[10] = ecx[2];
- buf[11] = ecx[3];
- buf[12] = 0;
+static char *cpu_string(char buf[16])
+{
+ // wtf
+ cpuid(CPUID_VENDOR_STRING, (u32 *)(buf + 12), (u32 *)(buf), (u32 *)(buf + 8),
+ (u32 *)(buf + 4));
+
return buf;
}
void cpu_print(void)
{
- char buf[13] = { 0 };
- printf("%s\n", cpu_string(buf));
+ char buf[16] = { 0 };
+ printf("CPU vendor: %s\n", cpu_string(buf));
+}
+
+static u32 cr0_get(void)
+{
+ u32 cr0;
+ __asm__ volatile("movl %%cr0, %%eax" : "=a"(cr0));
+ return cr0;
+}
+
+static void cr0_set(u32 cr0)
+{
+ __asm__ volatile("movl %%eax, %%cr0" ::"a"(cr0));
+}
+
+static u32 cr4_get(void)
+{
+ u32 cr4;
+ __asm__ volatile("movl %%cr4, %%eax" : "=a"(cr4));
+ return cr4;
+}
+
+static void cr4_set(u32 cr4)
+{
+ __asm__ volatile("movl %%eax, %%cr4" ::"a"(cr4));
+}
+
+static u32 cpu_features = 0;
+u8 cpu_has_feature(u32 feature)
+{
+ return (cpu_features & feature) != 0;
+}
+
+void fpu_handler()
+{
+ __asm__ volatile("clts");
+}
+
+static u8 fpu_state[512] __attribute__((aligned(16)));
+void fpu_restore(void)
+{
+ __asm__ volatile("fxrstor (%0)" ::"r"(fpu_state));
+}
+
+void cpu_enable_features(void)
+{
+ u32 a = 0, b = 0, c = 0, d = 0;
+ cpuid(CPUID_FEATURES, &a, &b, &c, &d);
+ cpu_features = d;
+ if (cpu_has_feature(CPUID_FEAT_EDX_SSE)) {
+ cr0_set(cr0_get() & ~(1 << 2));
+ cr0_set(cr0_get() | (1 << 1));
+ cr4_set(cr4_get() | (3 << 9));
+ } else {
+ panic("No SSE support!\n");
+ }
+
+ if (cpu_has_feature(CPUID_FEAT_EDX_FPU)) {
+ __asm__ volatile("fninit");
+ __asm__ volatile("fxsave %0" : "=m"(fpu_state));
+ irq_install_handler(7, fpu_handler);
+ } else {
+ panic("No FPU support!\n");
+ }
}
-#ifdef kernel
void cli(void)
{
__asm__ volatile("cli");
diff --git a/libc/inc/cpu.h b/libc/inc/cpu.h
index 033743d..fa82fbe 100644
--- a/libc/inc/cpu.h
+++ b/libc/inc/cpu.h
@@ -5,8 +5,6 @@
#include <def.h>
-enum cpuid_requests { CPUID_VENDOR_STRING, CPUID_FEATURES, CPUID_TLB, CPUID_SERIAL };
-
u8 inb(u16 port);
u16 inw(u16 port);
u32 inl(u16 port);
@@ -16,24 +14,84 @@ void outb(u16 port, u8 data);
void outw(u16 port, u16 data);
void outl(u16 port, u32 data);
-void cpuid(int code, u32 *a, u32 *b, u32 *c, u32 *d);
-char *cpu_string(char buf[12]);
-void cpu_print(void);
+static inline void spinlock(int *ptr)
+{
+ int prev;
+ do
+ __asm__ volatile("lock xchgl %0,%1" : "=a"(prev) : "m"(*ptr), "a"(1));
+ while (prev);
+}
#ifdef kernel
+void cpu_print(void);
+void cpu_enable_features(void);
+void fpu_restore(void);
+
void cli(void);
void sti(void);
void hlt(void);
void idle(void);
void loop(void);
-#endif
-static inline void spinlock(int *ptr)
-{
- int prev;
- do
- __asm__ volatile("lock xchgl %0,%1" : "=a"(prev) : "m"(*ptr), "a"(1));
- while (prev);
-}
+enum cpuid_requests { CPUID_VENDOR_STRING, CPUID_FEATURES, CPUID_TLB, CPUID_SERIAL };
+enum cpuid_features {
+ CPUID_FEAT_ECX_SSE3 = 1 << 0,
+ CPUID_FEAT_ECX_PCLMUL = 1 << 1,
+ CPUID_FEAT_ECX_DTES64 = 1 << 2,
+ CPUID_FEAT_ECX_MONITOR = 1 << 3,
+ CPUID_FEAT_ECX_DS_CPL = 1 << 4,
+ CPUID_FEAT_ECX_VMX = 1 << 5,
+ CPUID_FEAT_ECX_SMX = 1 << 6,
+ CPUID_FEAT_ECX_EST = 1 << 7,
+ CPUID_FEAT_ECX_TM2 = 1 << 8,
+ CPUID_FEAT_ECX_SSSE3 = 1 << 9,
+ CPUID_FEAT_ECX_CID = 1 << 10,
+ CPUID_FEAT_ECX_FMA = 1 << 12,
+ CPUID_FEAT_ECX_CX16 = 1 << 13,
+ CPUID_FEAT_ECX_ETPRD = 1 << 14,
+ CPUID_FEAT_ECX_PDCM = 1 << 15,
+ CPUID_FEAT_ECX_PCIDE = 1 << 17,
+ CPUID_FEAT_ECX_DCA = 1 << 18,
+ CPUID_FEAT_ECX_SSE4_1 = 1 << 19,
+ CPUID_FEAT_ECX_SSE4_2 = 1 << 20,
+ CPUID_FEAT_ECX_x2APIC = 1 << 21,
+ CPUID_FEAT_ECX_MOVBE = 1 << 22,
+ CPUID_FEAT_ECX_POPCNT = 1 << 23,
+ CPUID_FEAT_ECX_AES = 1 << 25,
+ CPUID_FEAT_ECX_XSAVE = 1 << 26,
+ CPUID_FEAT_ECX_OSXSAVE = 1 << 27,
+ CPUID_FEAT_ECX_AVX = 1 << 28,
+
+ CPUID_FEAT_EDX_FPU = 1 << 0,
+ CPUID_FEAT_EDX_VME = 1 << 1,
+ CPUID_FEAT_EDX_DE = 1 << 2,
+ CPUID_FEAT_EDX_PSE = 1 << 3,
+ CPUID_FEAT_EDX_TSC = 1 << 4,
+ CPUID_FEAT_EDX_MSR = 1 << 5,
+ CPUID_FEAT_EDX_PAE = 1 << 6,
+ CPUID_FEAT_EDX_MCE = 1 << 7,
+ CPUID_FEAT_EDX_CX8 = 1 << 8,
+ CPUID_FEAT_EDX_APIC = 1 << 9,
+ CPUID_FEAT_EDX_SEP = 1 << 11,
+ CPUID_FEAT_EDX_MTRR = 1 << 12,
+ CPUID_FEAT_EDX_PGE = 1 << 13,
+ CPUID_FEAT_EDX_MCA = 1 << 14,
+ CPUID_FEAT_EDX_CMOV = 1 << 15,
+ CPUID_FEAT_EDX_PAT = 1 << 16,
+ CPUID_FEAT_EDX_PSE36 = 1 << 17,
+ CPUID_FEAT_EDX_PSN = 1 << 18,
+ CPUID_FEAT_EDX_CLF = 1 << 19,
+ CPUID_FEAT_EDX_DTES = 1 << 21,
+ CPUID_FEAT_EDX_ACPI = 1 << 22,
+ CPUID_FEAT_EDX_MMX = 1 << 23,
+ CPUID_FEAT_EDX_FXSR = 1 << 24,
+ CPUID_FEAT_EDX_SSE = 1 << 25,
+ CPUID_FEAT_EDX_SSE2 = 1 << 26,
+ CPUID_FEAT_EDX_SS = 1 << 27,
+ CPUID_FEAT_EDX_HTT = 1 << 28,
+ CPUID_FEAT_EDX_TM1 = 1 << 29,
+ CPUID_FEAT_EDX_IA64 = 1 << 30,
+};
+#endif
#endif
diff --git a/libc/inc/print.h b/libc/inc/print.h
index 3e11db7..f32873a 100644
--- a/libc/inc/print.h
+++ b/libc/inc/print.h
@@ -20,6 +20,7 @@ int err(int code, const char *format, ...);
#else
#include <proc.h>
int print_app(enum stream_defaults id, const char *proc_name, const char *str);
+void panic(const char *format, ...);
#endif
#endif
diff --git a/libc/mem.c b/libc/mem.c
index d7ce3dc..953ef33 100644
--- a/libc/mem.c
+++ b/libc/mem.c
@@ -5,24 +5,61 @@
#include <mem.h>
#include <sys.h>
-// Taken from jgraef at osdev
void *memcpy(void *dest, const void *src, u32 n)
{
+#ifdef userspace
+ // Inspired by Jeko at osdev
+ for (u32 i = 0; i < n / 16; i++) {
+ __asm__ __volatile__("movups (%0), %%xmm0\n"
+ "movntdq %%xmm0, (%1)\n" ::"r"(src),
+ "r"(dest)
+ : "memory");
+
+ src = ((u8 *)src) + 16;
+ dest = ((u8 *)dest) + 16;
+ }
+
+ if (n & 7) {
+ n = n & 7;
+
+ int d0, d1, d2;
+ __asm__ __volatile__("rep ; movsl\n\t"
+ "testb $2,%b4\n\t"
+ "je 1f\n\t"
+ "movsw\n"
+ "1:\ttestb $1,%b4\n\t"
+ "je 2f\n\t"
+ "movsb\n"
+ "2:"
+ : "=&c"(d0), "=&D"(d1), "=&S"(d2)
+ : "0"(n / 4), "q"(n), "1"((long)dest), "2"((long)src)
+ : "memory");
+ }
+ return dest;
+#else
+ // Inspired by jgraef at osdev
u32 num_dwords = n / 4;
u32 num_bytes = n % 4;
u32 *dest32 = (u32 *)dest;
u32 *src32 = (u32 *)src;
u8 *dest8 = ((u8 *)dest) + num_dwords * 4;
u8 *src8 = ((u8 *)src) + num_dwords * 4;
- u32 i;
- for (i = 0; i < num_dwords; i++) {
- dest32[i] = src32[i];
- }
- for (i = 0; i < num_bytes; i++) {
+ // TODO: What's faster?
+ __asm__ volatile("rep movsl\n"
+ : "=S"(src32), "=D"(dest32), "=c"(num_dwords)
+ : "S"(src32), "D"(dest32), "c"(num_dwords)
+ : "memory");
+
+ /* for (u32 i = 0; i < num_dwords; i++) { */
+ /* dest32[i] = src32[i]; */
+ /* } */
+
+ for (u32 i = 0; i < num_bytes; i++) {
dest8[i] = src8[i];
}
return dest;
+#endif
}
void *memset(void *dest, int val, u32 n)
@@ -33,12 +70,18 @@ void *memset(void *dest, int val, u32 n)
u8 *dest8 = ((u8 *)dest) + num_dwords * 4;
u8 val8 = (u8)val;
u32 val32 = val | (val << 8) | (val << 16) | (val << 24);
- u32 i;
- for (i = 0; i < num_dwords; i++) {
- dest32[i] = val32;
- }
- for (i = 0; i < num_bytes; i++) {
+ // TODO: What's faster?
+ __asm__ volatile("rep stosl\n"
+ : "=D"(dest32), "=c"(num_dwords)
+ : "D"(dest32), "c"(num_dwords), "a"(val32)
+ : "memory");
+
+ /* for (u32 i = 0; i < num_dwords; i++) { */
+ /* dest32[i] = val32; */
+ /* } */
+
+ for (u32 i = 0; i < num_bytes; i++) {
dest8[i] = val8;
}
return dest;
diff --git a/libc/print.c b/libc/print.c
index ffb1e69..3d64504 100644
--- a/libc/print.c
+++ b/libc/print.c
@@ -213,4 +213,14 @@ int print(const char *str)
return strlen(str);
}
+void panic(const char *format, ...)
+{
+ va_list ap;
+ va_start(ap, format);
+ vprintf(format, ap);
+ va_end(ap);
+
+ assert(0);
+}
+
#endif