From 960c4c0cc2a7698f556a3d39b75216b6428093a5 Mon Sep 17 00:00:00 2001
From: Bart Kuivenhoven <
bemkuiv...@gmail.com>
Date: Tue, 20 Aug 2013 15:58:24 +0200
Subject: [PATCH 1/2] Arch abstraction: Add interrupt management code
cpu_enable_interrupts: Disables interrupts and returns 1 if interrupts
were previously enabled
cpu_disable_interrupts: Enables interrupts
Signed-off-by: Bart Kuivenhoven <
bemkuiv...@gmail.com>
---
include/andromeda/system.h | 31 +++++++++-
include/arch/x86/cpu.h | 145
++++++++++++++++++++++++---------------------
include/thread.h | 1 +
src/arch/x86/asm/asm.asm | 33 +++++++++--
src/arch/x86/boot/init.c | 4 ++
5 files changed, 139 insertions(+), 75 deletions(-)
diff --git a/include/andromeda/system.h b/include/andromeda/system.h
index 480f93f..5303e7e 100644
--- a/include/andromeda/system.h
+++ b/include/andromeda/system.h
@@ -70,7 +70,6 @@ struct sys_cpu_scheduler {
struct sys_cpu_pic {
int (*set_interrupt)(void);
int (*get_interrupt)(void);
- int (*disable_interrupt)(void);
int (*suspend)(void);
int (*resume)(void);
};
@@ -84,6 +83,8 @@ struct sys_cpu {
void (*resume)(void);
void (*halt)(void);
void (*throttle)(void);
+ int (*disable_interrupt)(void);
+ int (*enable_interrupt)(void);
};
struct sys_io_pic {
@@ -186,6 +187,34 @@ extern struct system core;
#define getmmu(a) ((getcpu(a) == NULL) ? getcpu(a)->mmu : NULL)
+static inline void cpu_wait_interrupt(int a)
+{
+ struct sys_cpu* cpu = getcpu(a);
+ if (!(hascpu(a) && cpu->halt != NULL))
+ panic("CPU struct not intialised!");
+
+ cpu->halt();
+}
+
+static inline int cpu_disable_interrupts(int a)
+{
+ struct sys_cpu* cpu = getcpu(a);
+ if (!(hascpu(a) && cpu->disable_interrupt != NULL))
+ panic("CPU struct not initialised!");
+
+ return cpu->disable_interrupt();
+}
+
+static inline int cpu_enable_interrupts(int a)
+{
+ struct sys_cpu* cpu = getcpu(a);
+ if (!(hascpu(a) && cpu->enable_interrupt != NULL))
+ panic("CPU struct not initialised!");
+
+ return cpu->enable_interrupt();
+ return 0;
+}
+
static inline void*
get_phys(int cpu, void* virt)
{
diff --git a/include/arch/x86/cpu.h b/include/arch/x86/cpu.h
index bb1d1ea..8530a4f 100644
--- a/include/arch/x86/cpu.h
+++ b/include/arch/x86/cpu.h
@@ -28,89 +28,96 @@
extern "C"
{
#endif
- extern mutex_t cpu_lock;
+extern mutex_t cpu_lock;
- typedef uint8_t ol_lock_t;
+typedef uint8_t ol_lock_t;
- struct ol_gen_regs
- {
- uint32_t eax, ebx, ecx, edx;
- } __attribute__((packed));
- typedef struct ol_gen_regs *ol_gen_registers_t;
+struct ol_gen_regs
+{
+ uint32_t eax, ebx, ecx, edx;
+} __attribute__((packed));
+typedef struct ol_gen_regs *ol_gen_registers_t;
- typedef struct ol_cpu_model
- {
- uint32_t vendor_id, family;
- const uint8_t *model_name;
- } *ol_cpu_model_t;
+typedef struct ol_cpu_model
+{
+ uint32_t vendor_id, family;
+ const uint8_t *model_name;
+} *ol_cpu_model_t;
- typedef struct ol_cpu
- {
- /* model info*/
- ol_cpu_model_t cpu_models[4];
- char* vendor;
+typedef struct ol_cpu
+{
+ /* model info*/
+ ol_cpu_model_t cpu_models[4];
+ char* vendor;
- /* CPU device info */
- uint8_t flags;
- uint64_t bus_width;
+ /* CPU device info */
+ uint8_t flags;
+ uint64_t bus_width;
- void (*lock)(mutex_t*);
- void (*unlock)(mutex_t*);
+ void (*lock)(mutex_t*);
+ void (*unlock)(mutex_t*);
- } *ol_cpu_t;
+} *ol_cpu_t;
#if 0
- /* CPU feature functions */
- static int
- ol_cpuid_available(ol_cpu_t);
+/* CPU feature functions */
+static int
+ol_cpuid_available(ol_cpu_t);
#endif
- void
- ol_cpu_init(ol_cpu_t);
+void
+ol_cpu_init(ol_cpu_t);
- ol_gen_registers_t
- ol_cpuid(uint32_t func);
+ol_gen_registers_t
+ol_cpuid(uint32_t func);
- uint32_t
- ol_get_eflags(void);
+uint32_t
+ol_get_eflags(void);
- void
- ol_set_eflags(uint32_t);
+void
+ol_set_eflags(uint32_t);
#if 0
- /* LOCKS */
- static void /* lock spin lock */
- ol_mutex_lock(mutex_t*);
-
- static void /* spin release */
- ol_mutex_release(mutex_t*);
-
- /* CPUID */
- static ol_gen_registers_t
- __ol_cpuid(volatile ol_gen_registers_t);
-
- /*
- * Inside function to write to a Model Specific Register
- */
- static uint64_t
- __read_msr(uint32_t);
-
- /*
- * Inside function to read a Model Specific Register
- */
- static void
- __write_msr(uint32_t, uint64_t);
+/* LOCKS */
+static void /* lock spin lock */
+ol_mutex_lock(mutex_t*);
+
+static void /* spin release */
+ol_mutex_release(mutex_t*);
+
+/* CPUID */
+static ol_gen_registers_t
+__ol_cpuid(volatile ol_gen_registers_t);
+
+/*
+* Inside function to write to a Model Specific Register
+*/
+static uint64_t
+__read_msr(uint32_t);
+
+/*
+* Inside function to read a Model Specific Register
+*/
+static void
+__write_msr(uint32_t, uint64_t);
#endif
- /*
- * Read a model specific register.
- */
- uint64_t
- cpu_read_msr(uint32_t);
-
- /*
- * Write a value to a model specific register.
- */
- void
- cpu_write_msr(uint32_t, uint64_t);
-
- extern volatile ol_cpu_t cpus;
+/*
+* Read a model specific register.
+*/
+uint64_t
+cpu_read_msr(uint32_t);
+
+/*
+* Write a value to a model specific register.
+*/
+void
+cpu_write_msr(uint32_t, uint64_t);
+
+extern volatile ol_cpu_t cpus;
+
+/**
+ * \fn disableInterrupts
+ * \return 1 if interrupts were enabled, otherwise 0
+ */
+extern int disableInterrupts();
+extern int enableInterrupts();
#ifdef __cplusplus
}
diff --git a/include/thread.h b/include/thread.h
index aa5aadd..82d1bb4 100644
--- a/include/thread.h
+++ b/include/thread.h
@@ -78,6 +78,7 @@ uint64_t atomic_reset(atomic_t *atom);
int64_t atomic_inc(atomic_t* d);
int64_t atomic_dec(atomic_t* d);
int64_t atomic_get(atomic_t* d);
+void atomic_init(atomic_t* d);
int64_t semaphore_inc(semaphore_t* s);
int64_t semaphore_dec(semaphore_t* s);
diff --git a/src/arch/x86/asm/asm.asm b/src/arch/x86/asm/asm.asm
index f645ad5..e0054cb 100644
--- a/src/arch/x86/asm/asm.asm
+++ b/src/arch/x86/asm/asm.asm
@@ -33,18 +33,41 @@
[EXTERN mutex_lock]
[EXTERN mutex_unlock]
+[GLOBAL disableInterrupts]
+[GLOBAL enableInterrupts]
+
mutex dd 0 ;The mutex variable
pgbit dd 0 ;Paging is disabled per default
;Booleans have been typedefed as unsigned char
%include "asm/call.mac"
+disableInterrupts:
+ pushfd ; Push flags to stack
+ cli ; Disable interrupts
+ pop eax ; Fetch the flags
+ and eax, 1 << 9 ; Check if interrupts were enabled
+ shr eax, 0
+ jmp .return
+ jz .false
+ mov eax, 1 ; If previously enabled, return 1
+ jmp .return
+.false:
+ xor eax, eax ; If not previously enabled, return 0
+.return:
+ ret ; Return
+
+enableInterrupts:
+ sti ; Enable interrupts
+ xor eax, eax ; Set return value to 0, to signal no error has occured
+ ret ; Return
+
halt:
- pushfd
- sti
- hlt
- popfd
- ret
+ pushfd ; Make sure interrupt flag is saved
+ sti ; Enable interrupts
+ hlt ; Make the cpu wait for interrupts
+ popfd ; Restore interrupt flag to whatever it was before
+ ret ; Return
DetectAPIC:
enter
diff --git a/src/arch/x86/boot/init.c b/src/arch/x86/boot/init.c
index b42a1b5..646aec7 100644
--- a/src/arch/x86/boot/init.c
+++ b/src/arch/x86/boot/init.c
@@ -131,6 +131,9 @@ int system_x86_cpu_init(int cpuid)
cpu->throttle = NULL;
cpu->resume = NULL;
+ cpu->disable_interrupt = disableInterrupts;
+ cpu->enable_interrupt = enableInterrupts;
+
system_x86_mmu_init(cpu);
return -E_SUCCESS;
@@ -198,6 +201,7 @@ int init(unsigned long magic, multiboot_info_t* hdr)
panic("OUT OF MEMORY!");
ol_cpu_init(cpu);
+ cpu_enable_interrupts(0);
ol_ps2_init_keyboard();
//ol_apic_init(cpu);
//init_ioapic();
--
1.8.3.4