diff --git a/Makefile b/Makefile
index ff578a4..a2145bb 100644
--- a/Makefile
+++ b/Makefile
@@ -129,7 +129,8 @@ kal_kern_obj= $(KOBJDIR)/kernel/cpuid.o $(KOBJDIR)/kernel/init.o \
$(KOBJDIR)/kernel/term.o $(KOBJDIR)/kernel/vga.o \
$(KOBJDIR)/kernel/panic.o $(KOBJDIR)/kernel/map.o \
$(KOBJDIR)/kernel/heap.o $(KOBJDIR)/kernel/malloc.o \
- $(KOBJDIR)/kernel/buf.o
+ $(KOBJDIR)/kernel/buf.o $(KOBJDIR)/kernel/sched.o \
+ $(KOBJDIR)/kernel/bput.o $(KOBJDIR)/kernel/bprint.o \
$(KOBJDIR)/kernel/cpuid.o: $(KERNELDIR)/kernel/cpu/cpuid.c $(KERNELDIR)/include/*/*.h
@$(KCC) $< -o $@
@@ -164,6 +165,16 @@ $(KOBJDIR)/kernel/malloc.o: $(KERNELDIR)/kernel/mm/malloc.c $(KERNELDIR)/include
$(KOBJDIR)/kernel/buf.o: $(KERNELDIR)/kernel/buf/buf.c $(KERNELDIR)/include/*/*.h
@$(KCC) $< -o $@
@echo ${CL2}[$@] ${CL}Compiled.${CL3}
+$(KOBJDIR)/kernel/bput.o: $(KERNELDIR)/kernel/buf/bput.c $(KERNELDIR)/include/*/*.h
+ @$(KCC) $< -o $@
+ @echo ${CL2}[$@] ${CL}Compiled.${CL3}
+$(KOBJDIR)/kernel/bprint.o: $(KERNELDIR)/kernel/buf/bprint.c $(KERNELDIR)/include/*/*.h
+ @$(KCC) $< -o $@
+ @echo ${CL2}[$@] ${CL}Compiled.${CL3}
+$(KOBJDIR)/kernel/sched.o: $(KERNELDIR)/kernel/proc/sched.c $(KERNELDIR)/include/*/*.h
+ @$(KCC) $< -o $@
+ @echo ${CL2}[$@] ${CL}Compiled.${CL3}
+
## MISC MAKEFILE ------------------------------------------------------------- #
./ProjectTree: ./.stylehlp_sh
diff --git a/ProjectTree b/ProjectTree
index f44e941..6d8caf3 100644
--- a/ProjectTree
+++ b/ProjectTree
@@ -56,6 +56,8 @@
│ │ │ └── loader.o
│ │ └── kaleid
│ │ ├── kernel
+│ │ │ ├── bprint.o
+│ │ │ ├── bput.o
│ │ │ ├── buf.o
│ │ │ ├── cpuid.o
│ │ │ ├── cursor.o
@@ -64,6 +66,7 @@
│ │ │ ├── malloc.o
│ │ │ ├── map.o
│ │ │ ├── panic.o
+│ │ │ ├── sched.o
│ │ │ ├── table.o
│ │ │ ├── term.o
│ │ │ └── vga.o
@@ -131,9 +134,12 @@
│ │ └── kalext.h
│ └── kernel
│ ├── buf
+│ │ ├── bprint.c
+│ │ ├── bput.c
│ │ └── buf.c
│ ├── cpu
-│ │ └── cpuid.c
+│ │ ├── cpuid.c
+│ │ └── idt.c
│ ├── init
│ │ ├── init.c
│ │ └── table.c
@@ -147,7 +153,8 @@
│ ├── mm
│ │ ├── heap.c
│ │ ├── malloc.c
-│ │ └── map.c
+│ │ ├── map.c
+│ │ └── stack.c
│ └── proc
│ ├── Makefile
│ └── sched.c
@@ -162,4 +169,4 @@
├── qemu.log
└── Readme.md
-28 directories, 109 files
+28 directories, 116 files
diff --git a/boot/loader/loader.asm b/boot/loader/loader.asm
index 0e56cdc..0a3fc44 100644
--- a/boot/loader/loader.asm
+++ b/boot/loader/loader.asm
@@ -44,7 +44,7 @@ MB_header:
dd MB_HEADER_MAGIC
dd MB_HEADER_FLAGS
dd CHECKSUM
- times 5 dd 0x0
+ times 5 dd 0x0 ; The unused section (provided for a.out)
dd MB_VIDEO_MODE
dd MB_VIDEO_WIDTH
dd MB_VIDEO_HEIGHT
@@ -52,7 +52,7 @@ MB_header:
[section .text]
-;;MULTIBOOT POINT ENTRY FOR GRUB ------------------------------------------- ;;
+;;MULTIBOOT POINT ENTRY FOR GRUB -------------------------------------------- ;;
MB_start:
mov esp, KERNEL_STACK ; Setup the stack
push 0 ; Reset EFLAGS
@@ -133,8 +133,9 @@ lbegin:
[BITS 64]
-x64_K db "Now in x64 long mode", 0x0A, 0x0D, 0x0
+x64_K db "64 bits long mode activated !", 0x0A, 0x0D, 0x0
GoKernel db "Launching Kernel...", 0
+GoStack db "Initializing the stack...", 0x0A, 0x0D, 0x0
nokernel db 219, 219, 219, " Error 05 : Kernel returns",0
_loader64:
@@ -154,14 +155,21 @@ _loader64:
mov bl, 0x0A
mov esi, x64_K
call write
+
+ ;; Initialize the stack
+ mov bl, 0x0F
+ mov esi, GoStack
+ call write
+
+ call tritemporize ; Let time to see
+ call InitStack
+
+ ;; Launch the kernel !
mov bl, 0x0F
mov esi, GoKernel
call write
- ;; Launch the kernel !
- ;; XXX CHECK THE RAM BEFORE CALLING KERNEL !
- call tritemporize ; Let time to see
-
+ mov qword [newKernelEnd], KERNEL_STACK
mov rdi, [mbInfo]
mov rsi, [mbMagic]
call BtStartKern
diff --git a/boot/loader/mem/management.inc b/boot/loader/mem/management.inc
index b44bf4f..cfdf3c4 100644
--- a/boot/loader/mem/management.inc
+++ b/boot/loader/mem/management.inc
@@ -106,3 +106,36 @@ CheckA20:
.A20_err:
mov ax, "04" ; ERROR 04 : A20 line failed
jmp Error
+
+[BITS 64]
+; ---------------------------------------------------------------------------- ;
+; Initilizes the stack ;
+; ---------------------------------------------------------------------------- ;
+InitStack:
+ xor rax, rax ; "Fill pattern"
+ push rcx
+ push rdi
+
+ ;; Begin address to fill and length
+ mov rdi, kernelEnd
+ mov rcx, KERNEL_STACK - kernelEnd - 16
+ ; stop before the return address
+
+ ;; If bit 0 is on, fill one byte
+ sar rcx, 1 ; Shift bit 0 into CY
+ jnc $ + 3
+ stosb
+ ;; We are word aligned and if bit 1 was on fill another word
+ sar rcx, 1 ; Shift bit 1 into CY
+ jnc $ + 4
+ stosw
+ ;; We are dword aligned and if bit 2 was on fill another dword
+ sar rcx, 1 ; Shift bit 2 into CY
+ jnc $ + 3
+ stosd
+ ;; RCX now equals the number of qwords to fill
+ repnz stosq ; Finish by writing RCX qwords.
+
+ pop rdi
+ pop rcx
+ ret
diff --git a/boot/loader/mem/structures.inc b/boot/loader/mem/structures.inc
index 0c7bd8b..dc1c607 100644
--- a/boot/loader/mem/structures.inc
+++ b/boot/loader/mem/structures.inc
@@ -24,6 +24,13 @@
;=----------------------------------------------------------------------------=;
[BITS 32]
+extern kernelEnd
+global newKernelEnd
+
+[section .text]
+KERNEL_STACK equ kernelEnd + 4096 * 2 * 1024 ; 8MB of stack
+newKernelEnd dq 0x0
+
[section .rodata]
;; GDT WITH DOC
ALIGN 4096
@@ -43,6 +50,7 @@ GDT64:
dw $ - GDT64 - 1
dq GDT64
+
;; EMPTY PAGE TABLES (identity of the first 1GiB)
[section .bss]
ALIGN 4096
@@ -52,4 +60,3 @@ PDP_table:
resb 4096
PD_table:
resb 4096
-
diff --git a/boot/loader/multiboot/header.inc b/boot/loader/multiboot/header.inc
index 0cfea0c..e7a8b1c 100644
--- a/boot/loader/multiboot/header.inc
+++ b/boot/loader/multiboot/header.inc
@@ -36,4 +36,3 @@ MB_HEADER_MAGIC equ 0x1badb002
MB_GRUB_MAGIC equ 0x2badb002
MB_HEADER_FLAGS equ MB_AOUT_KLUDGE|MB_ALIGN|MB_MEMINFO|MB_VIDEOINFO
CHECKSUM equ -(MB_HEADER_MAGIC + MB_HEADER_FLAGS)
-KERNEL_STACK equ 0x00200000 ; Stack starts at the 2mb address & grows down
diff --git a/build/kernel.ld b/build/kernel.ld
index 50a5d81..7500a25 100644
--- a/build/kernel.ld
+++ b/build/kernel.ld
@@ -61,10 +61,10 @@ SECTIONS {
*(.rodata) /* all rodata sections from all files */
}
- kernelEnd = .;
-
/DISCARD/ :
{
*(.comment)
}
+
+ kernelEnd = .;
}
diff --git a/kaleid/crtlib/atoi.c b/kaleid/crtlib/atoi.c
index fba62ca..3b1b737 100644
--- a/kaleid/crtlib/atoi.c
+++ b/kaleid/crtlib/atoi.c
@@ -28,9 +28,9 @@
// Do not change errno
#define _ATOI_IMPL(_Name, _Type, _Func) \
_Type _Name(const char *str) { \
- __get_errno(old); \
+ error_t old; geterrno(old); \
_Type ret = (_Type)_Func(str, NULL, 0); \
- __set_errno(old); \
+ seterrno(old); \
return ret; \
}
diff --git a/kaleid/crtlib/itoa.c b/kaleid/crtlib/itoa.c
index 95c1bd7..52d45a8 100644
--- a/kaleid/crtlib/itoa.c
+++ b/kaleid/crtlib/itoa.c
@@ -72,7 +72,7 @@ char *ultoa(ulong i, char *str, int base)
// Only handle base 2 -> 36
if (base < 2 || base > 36) {
- __set_errno(EINVAL);
+ seterrno(EINVAL);
*orig = '\0';
goto leave;
}
diff --git a/kaleid/crtlib/mem.c b/kaleid/crtlib/mem.c
index 208cffc..cd158e9 100644
--- a/kaleid/crtlib/mem.c
+++ b/kaleid/crtlib/mem.c
@@ -37,12 +37,18 @@ void *malloc(size_t n)
error_t rc;
rc = KalAllocMemory(&ptr, n, 0, 0);
- __set_errno(rc);
- (void)rc;
+ if (rc > 0) seterrno(rc);
return ptr;
}
+void *calloc(size_t n, size_t m)
+{
+ char *mem = malloc(n * m);
+ memzero(mem, n * m);
+ return mem;
+}
+
void free(void *ptr)
{
error_t rc = KalFreeMemory(ptr);
@@ -132,7 +138,7 @@ void *memsetd(void *ptr, int val, size_t dwords)
{
(void)val;
(void)dwords;
- __set_errno(ENOSYS);
+ seterrno(ENOSYS);
return ptr;
}
diff --git a/kaleid/crtlib/strtol.c b/kaleid/crtlib/strtol.c
index dbde8ab..91c943d 100644
--- a/kaleid/crtlib/strtol.c
+++ b/kaleid/crtlib/strtol.c
@@ -28,7 +28,7 @@ long strtol(const char *str, char **endp, int base) {
(void)str;
(void)endp;
(void)base;
- __set_errno(ENOSYS);
+ seterrno(ENOSYS);
return 0;
}
@@ -36,7 +36,7 @@ ulong strtoul(const char *str, char **endp, int base) {
(void)str;
(void)endp;
(void)base;
- __set_errno(ENOSYS);
+ seterrno(ENOSYS);
return 0;
}
diff --git a/kaleid/include/base/crtlib.h b/kaleid/include/base/crtlib.h
index a62aa39..8e7af7b 100644
--- a/kaleid/include/base/crtlib.h
+++ b/kaleid/include/base/crtlib.h
@@ -33,7 +33,7 @@ extern "C" {
#ifndef __error_t_defined
#define __error_t_defined
-typedef int error_t;
+typedef unsigned int error_t;
#endif
#ifndef __size_t_defined
@@ -66,14 +66,14 @@ extern error_t __errno;
#define errno __errno
#endif
-#define __get_errno(x) error_t x = errno
-#define __set_errno(x) (errno = (x))
+#define geterrno(x) ((x) = errno)
+#define seterrno(x) (errno = (x))
#else
#define errno
-#define __get_errno(x)
-#define __set_errno(x)
+#define geterrno(x) ((void)x)
+#define seterrno(x) ((void)x)
#endif
diff --git a/kaleid/include/base/types.h b/kaleid/include/base/types.h
index 0a1815a..ab3b547 100644
--- a/kaleid/include/base/types.h
+++ b/kaleid/include/base/types.h
@@ -119,7 +119,7 @@ typedef struct { long quot, rem; } ldiv_t;
#ifndef __error_t_defined
#define __error_t_defined
-typedef int error_t;
+typedef uint error_t;
#endif
#ifndef __port_t_defined
diff --git a/kaleid/include/extras/list.h b/kaleid/include/extras/list.h
index fea7f2a..7c51556 100644
--- a/kaleid/include/extras/list.h
+++ b/kaleid/include/extras/list.h
@@ -22,10 +22,6 @@
// along with OS/K. If not, see . //
//----------------------------------------------------------------------------//
-#ifdef _KALEID_KERNEL
-#error "extra/list.h - Not ready for kernel compilation"
-#endif
-
#ifndef _KALBASE_H
#include
#endif
@@ -74,7 +70,7 @@ struct ListNode_t
static inline ListHead_t
*ExCreateListHeadWithLock(Lock_t *lock)
{
- ListHead_t *head = KalAllocMemory(sizeof(ListHead_t));
+ ListHead_t *head = malloc(sizeof(ListHead_t));
if (head == NULL) return NULL;
@@ -101,7 +97,7 @@ static inline ListHead_t
static inline ListNode_t
*ExCreateNode(void *data)
{
- ListNode_t *node = KalAllocMemory(sizeof(ListNode_t));
+ ListNode_t *node = malloc(sizeof(ListNode_t));
if (node == NULL) return NULL;
@@ -118,7 +114,7 @@ static inline ListNode_t
static inline ListHead_t
*ExPrependNode(ListHead_t *head, ListNode_t *node)
{
- KalAssert(head && node);
+ assert(head && node);
node->head = head;
node->prev = NULL;
@@ -146,7 +142,7 @@ static inline ListHead_t
static inline ListHead_t
*ExAppendNode(ListHead_t *head, ListNode_t *node)
{
- KalAssert(head && node);
+ assert(head && node);
node->head = head;
node->next = NULL;
@@ -174,7 +170,7 @@ static inline ListHead_t
static inline ListHead_t
*ExAddNodeBefore(ListHead_t *head, ListNode_t *node1, ListNode_t *node2)
{
- KalAssert(head && node1 && node2 && node1->head == head);
+ assert(head && node1 && node2 && node1->head == head);
if (head->first == node1) {
return ExPrependNode(head, node2);
@@ -200,7 +196,7 @@ static inline ListHead_t
static inline ListHead_t
*ExAddNodeAfter(ListHead_t *head, ListNode_t *node1, ListNode_t *node2)
{
- KalAssert(head && node1 && node2 && node1->head == head);
+ assert(head && node1 && node2 && node1->head == head);
if (head->last == node1) {
return ExAppendNode(head, node2);
@@ -224,7 +220,7 @@ static inline ListHead_t
static inline ListHead_t
*ExRemoveNode(ListHead_t *head, ListNode_t *node)
{
- KalAssert(head && node && head->length > 0 && node->head == head);
+ assert(head && node && head->length > 0 && node->head == head);
if (head->length == 1) {
head->first = head->last = NULL;
@@ -259,8 +255,8 @@ leave:
static inline void
ExDestroyNode(ListNode_t *node)
{
- KalAssert(node);
- KalFreeMemory(node);
+ assert(node);
+ free(node);
}
//
@@ -269,8 +265,8 @@ ExDestroyNode(ListNode_t *node)
static inline void
ExDestroyListHead(ListHead_t *head)
{
- KalAssert(head);
- KalFreeMemory(head);
+ assert(head);
+ free(head);
}
//
diff --git a/kaleid/include/extras/locks.h b/kaleid/include/extras/locks.h
index af41152..eba1e36 100644
--- a/kaleid/include/extras/locks.h
+++ b/kaleid/include/extras/locks.h
@@ -32,6 +32,10 @@
#include
#endif
+#ifndef _KALKERN_SCHED_H
+#include
+#endif
+
#endif
#ifndef _KALEXTRAS_LOCKS_H
@@ -62,8 +66,8 @@ enum LockType_t
struct Lock_t
{
unsigned int initDone;
- LockType_t type;
volatile int locked;
+ LockType_t type;
/* #ifdef _KALEID_KERNEL
Thread_t *ownerThread; // unused
@@ -83,8 +87,8 @@ int KalYieldCPU(void),
static inline
void ExInitLock(Lock_t *lock, LockType_t type)
{
+ lock->locked = 0;
lock->type = type;
- lock->locked = FALSE;
lock->initDone = INITOK;
/* #ifdef _KALEID_KERNEL
lock->ownerThread = NULL;
@@ -96,9 +100,9 @@ void ExInitLock(Lock_t *lock, LockType_t type)
// Alternative way to initalize a lock
//
#ifdef _KALEID_KERNEL
-# define ExINITLOCK(type) { INITOK, FALSE, (type), /* NULL, NULL */ }
+# define ExINITLOCK(type) { INITOK, 0, (type), /* NULL, NULL */ }
#else
-# define ExINITLOCK(type) { INITOK, FALSE, (type) }
+# define ExINITLOCK(type) { INITOK, 0, (type) }
#endif
//
@@ -119,18 +123,29 @@ void ExDestroyLock(Lock_t *lock)
// until we have at least a basic scheduler
//
static inline
+#if defined(_KALEID_KERNEL) && !defined(_NO_DEBUG)
+#define ExAcquireLock(lock) \
+ _ExAcquireLock(lock,__FILE__, __LINE__, __func__,#lock)
+void _ExAcquireLock(Lock_t *lock, const char *file, int line,
+ const char *func, const char *obj)
+#else
void ExAcquireLock(Lock_t *lock)
+#endif
{
KalAssert(lock->initDone == INITOK);
while (!__sync_bool_compare_and_swap(&lock->locked, 0, 1)) {
-#ifdef _KALEID_KERNEL
- KeStartPanic("AcquireLock on an already locked object");
-#else
- if likely (lock->type == KLOCK_SPINLOCK) continue;
- else (void)KalYieldCPU();
+#if defined(_KALEID_KERNEL) && !defined(_NO_DEBUG)
+ KeStartPanic(
+ "In function '%s', from '%s' line %d\n"
+ "Double ExAcquireLock on object: '%s'",
+ func, file, line, obj);
#endif
+ /*if likely (lock->type == KLOCK_SPINLOCK)*/
+ continue;
+ //else (void)KalYieldCPU();
}
+ PsDisablePreemption();
__sync_synchronize();
}
@@ -146,7 +161,9 @@ void ExReleaseLock(Lock_t *lock)
#endif*/
__sync_synchronize();
+
lock->locked = 0;
+ PsEnablePreemption();
}
//
diff --git a/kaleid/include/kernel/base.h b/kaleid/include/kernel/base.h
index d15b63a..2d7534b 100644
--- a/kaleid/include/kernel/base.h
+++ b/kaleid/include/kernel/base.h
@@ -56,13 +56,12 @@ typedef enum TermColor_t TermColor_t;
#endif
// Current CPU number
-// Will return a CPU-local variable later
-#define _KeGetCurCPU() 0
+#define _KeCurCPU 0
-// Get Process_t structure of current CPU
-#define KeGetCurCPU() (cpuTable[_KeGetCurCPU()])
+// Process_t structure of current CPU
+#define KeCurCPU (cpuTable[_KeCurCPU])
-//Get the BootInfo_t structure
+// Access the BootInfo_t structure
#define BtGetBootInfo(x) (bootTab.x)
//------------------------------------------//
@@ -75,6 +74,15 @@ struct Processor_t
// CPU number, index in CPU list
int index;
+ // CPU APIC id
+ int apicId;
+ // CPU Vendor String (always 12 characters)
+ char vendorStr[12];
+ // CPU Model code (enum in cpu.h)
+ int modelCode;
+ // CPU Features flag
+ uint featureFlag;
+
// Number of ticks since boot time
ulong ticks;
diff --git a/kaleid/include/kernel/buf.h b/kaleid/include/kernel/buf.h
index 13520d5..eb6cf48 100644
--- a/kaleid/include/kernel/buf.h
+++ b/kaleid/include/kernel/buf.h
@@ -69,9 +69,9 @@ struct Buffer_t
size_t size; // Current size
- char *buf; // Beginning of buffer
- char *rp; // Read pointer
- char *wp; // Write pointer
+ uchar *buf; // Beginning of buffer
+ uchar *rp; // Read pointer
+ uchar *wp; // Write pointer
BFlusher_t flusher; // Called for flushing
@@ -107,7 +107,7 @@ bool BTrylockBuf(Buffer_t *buf);
error_t BFlushBuf(Buffer_t *buf);
error_t BPutOnBuf(Buffer_t *buf, uchar ch);
-error_t BPrintOnBuf(Buffer_t *buf, size_t n, const char *fmt, ...);
-error_t BPrintOnBufV(Buffer_t *buf, size_t n, const char *fmt, va_list ap);
+error_t BPrintOnBuf(Buffer_t *buf, const char *fmt, ...);
+error_t BPrintOnBufV(Buffer_t *buf, const char *fmt, va_list ap);
#endif
diff --git a/kaleid/include/kernel/cpu.h b/kaleid/include/kernel/cpu.h
index ae2c7b9..73dbb75 100644
--- a/kaleid/include/kernel/cpu.h
+++ b/kaleid/include/kernel/cpu.h
@@ -29,14 +29,76 @@
#ifndef _KALKERN_CPU_H
#define _KALKERN_CPU_H
-//------------------------------------------//
+// -------------------------------------------------------------------------- //
#define KeCPUID(in, a, b, c, d) asm("cpuid" \
: "=a" (a), "=b" (b), "=c" (c), "=d" (d) \
: "a" (in) \
);
-//------------------------------------------//
+// -------------------------------------------------------------------------- //
+// CPU features masks
+enum {
+ FEAT_ECX_SSE3 = 1 << 0,
+ FEAT_ECX_PCLMUL = 1 << 1,
+ FEAT_ECX_DTES64 = 1 << 2,
+ FEAT_ECX_MONITOR = 1 << 3,
+ FEAT_ECX_DS_CPL = 1 << 4,
+ FEAT_ECX_VMX = 1 << 5,
+ FEAT_ECX_SMX = 1 << 6,
+ FEAT_ECX_EST = 1 << 7,
+ FEAT_ECX_TM2 = 1 << 8,
+ FEAT_ECX_SSSE3 = 1 << 9,
+ FEAT_ECX_CID = 1 << 10,
+ FEAT_ECX_FMA = 1 << 12,
+ FEAT_ECX_CX16 = 1 << 13,
+ FEAT_ECX_ETPRD = 1 << 14,
+ FEAT_ECX_PDCM = 1 << 15,
+ FEAT_ECX_PCIDE = 1 << 17,
+ FEAT_ECX_DCA = 1 << 18,
+ FEAT_ECX_SSE4_1 = 1 << 19,
+ FEAT_ECX_SSE4_2 = 1 << 20,
+ FEAT_ECX_x2APIC = 1 << 21,
+ FEAT_ECX_MOVBE = 1 << 22,
+ FEAT_ECX_POPCNT = 1 << 23,
+ FEAT_ECX_AES = 1 << 25,
+ FEAT_ECX_XSAVE = 1 << 26,
+ FEAT_ECX_OSXSAVE = 1 << 27,
+ FEAT_ECX_AVX = 1 << 28,
+
+ FEAT_EDX_FPU = 1 << 0,
+ FEAT_EDX_VME = 1 << 1,
+ FEAT_EDX_DE = 1 << 2,
+ FEAT_EDX_PSE = 1 << 3,
+ FEAT_EDX_TSC = 1 << 4,
+ FEAT_EDX_MSR = 1 << 5,
+ FEAT_EDX_PAE = 1 << 6,
+ FEAT_EDX_MCE = 1 << 7,
+ FEAT_EDX_CX8 = 1 << 8,
+ FEAT_EDX_APIC = 1 << 9,
+ FEAT_EDX_SEP = 1 << 11,
+ FEAT_EDX_MTRR = 1 << 12,
+ FEAT_EDX_PGE = 1 << 13,
+ FEAT_EDX_MCA = 1 << 14,
+ FEAT_EDX_CMOV = 1 << 15,
+ FEAT_EDX_PAT = 1 << 16,
+ FEAT_EDX_PSE36 = 1 << 17,
+ FEAT_EDX_PSN = 1 << 18,
+ FEAT_EDX_CLF = 1 << 19,
+ FEAT_EDX_DTES = 1 << 21,
+ FEAT_EDX_ACPI = 1 << 22,
+ FEAT_EDX_MMX = 1 << 23,
+ FEAT_EDX_FXSR = 1 << 24,
+ FEAT_EDX_SSE = 1 << 25,
+ FEAT_EDX_SSE2 = 1 << 26,
+ FEAT_EDX_SS = 1 << 27,
+ FEAT_EDX_HTT = 1 << 28,
+ FEAT_EDX_TM1 = 1 << 29,
+ FEAT_EDX_IA64 = 1 << 30,
+ FEAT_EDX_PBE = 1 << 31
+};
+
+// -------------------------------------------------------------------------- //
#endif
diff --git a/kaleid/include/kernel/heap.h b/kaleid/include/kernel/heap.h
index 9783c36..062bf0a 100644
--- a/kaleid/include/kernel/heap.h
+++ b/kaleid/include/kernel/heap.h
@@ -31,7 +31,8 @@
//------------------------------------------//
-#define _HEAP_START (4 * MB)
+// Address of the heap
+void *_heap_start;
void MmInitHeap(void);
diff --git a/kaleid/include/kernel/mm.h b/kaleid/include/kernel/mm.h
index a70cdce..9fc07e1 100644
--- a/kaleid/include/kernel/mm.h
+++ b/kaleid/include/kernel/mm.h
@@ -44,7 +44,7 @@ struct MapEntry_t {
void *addr;
size_t length; // in bytes
uint type; // reserved or not
-} __attribute__((packed));
+} __attribute__((__packed__));
// the map structure
struct MemoryMap_t {
@@ -52,7 +52,7 @@ struct MemoryMap_t {
size_t freeRamSize;
size_t nonfreeRamSize;
MapEntry_t entry[MAX_ENTRIES];
-} __attribute__((packed));
+} __attribute__((__packed__));
@@ -64,7 +64,8 @@ struct MemoryMap_t {
error_t MmInitMemoryMap(void);
//
-// Returns the size of the first available memory zone from the start address pointer
+// Returns the size of the first available memory zone
+// from the start address pointer
//
size_t MmGetAvailZoneSize(void *start);
diff --git a/kaleid/include/kernel/multiboot.h b/kaleid/include/kernel/multiboot.h
index 896f23d..27da31f 100644
--- a/kaleid/include/kernel/multiboot.h
+++ b/kaleid/include/kernel/multiboot.h
@@ -96,7 +96,7 @@
typedef unsigned char uchar;
typedef unsigned short ushort;
typedef unsigned int uint;
-typedef unsigned long long ullong;
+typedef unsigned long ulong;
struct multiboot_header
{
@@ -141,7 +141,8 @@ struct multiboot_elf_section_header_table
uint addr;
uint shndx;
};
-typedef struct multiboot_elf_section_header_table multiboot_elf_section_header_table_t;
+typedef struct multiboot_elf_section_header_table
+ multiboot_elf_section_header_table_t;
struct multiboot_info
{
@@ -193,7 +194,7 @@ struct multiboot_info
ushort vbe_interface_off;
ushort vbe_interface_len;
- ullong framebuffer_addr;
+ ulong framebuffer_addr;
uint framebuffer_pitch;
uint framebuffer_width;
uint framebuffer_height;
diff --git a/kaleid/include/kernel/proc.h b/kaleid/include/kernel/proc.h
index 68b4770..2e4e962 100644
--- a/kaleid/include/kernel/proc.h
+++ b/kaleid/include/kernel/proc.h
@@ -77,8 +77,11 @@ struct Process_t
//------------------------------------------//
-DEC_PER_CPU(Ps, CurProc, process, Process_t *);
-DEC_PER_CPU(Ps, CurThread, thread, Thread_t *);
+#define PsCurProc (KeCurCPU.process)
+#define PsCurThread (KeCurCPU.thread)
+
+//DEC_PER_CPU(Ps, CurProc, process, Process_t *);
+//DEC_PER_CPU(Ps, CurThread, thread, Thread_t *);
//------------------------------------------//
diff --git a/kaleid/include/kernel/sched.h b/kaleid/include/kernel/sched.h
index 694aaff..76bd799 100644
--- a/kaleid/include/kernel/sched.h
+++ b/kaleid/include/kernel/sched.h
@@ -39,7 +39,7 @@ enum { PREEMPT_ON = 0 };
// Time in ticks a process should be run
enum
{
- DEF_PROC_TSLICE = 5, // 20 ticks
+ DEF_PROC_TSLICE = 3, // 20 ticks
TCR_PROC_TSLICE = 20000 // 20000 ticks (time critical)
};
@@ -57,24 +57,14 @@ extern const char *PsPrioClassesNames[];
//------------------------------------------//
-DEC_PER_CPU(Ps, ReSchedFlag, needReSched, bool);
-DEC_PER_CPU(Ps, PreemptCount, preemptCount, ulong);
-
-DEC_PER_CPU(Ps, IdlePrioProcs, idlePrioProcs, ListHead_t *);
-DEC_PER_CPU(Ps, ReglPrioProcs, reglPrioProcs, ListHead_t *);
-DEC_PER_CPU(Ps, ServPrioProcs, servPrioProcs, ListHead_t *);
-DEC_PER_CPU(Ps, TimeCritProcs, timeCritProcs, ListHead_t *);
-
-//------------------------------------------//
-
//
// Re-scheduling and preemption
// XXX atomic operations
//
-#define PsSetReSchedFlag(x) _PsSetReSchedFlag(x)
-#define PsDisablePreemption() _PsSetPreemptCount(GetPreemptCount()+1)
-#define PsEnablePreemption() do { KalAssert(GetPreemptCount() > 0); \
- _PsSetPreemptCount(GetPreemptCount()-1); } while(0)
+#define PsRequestReSched() (++KeCurCPU.needReSched)
+#define PsDisablePreemption() (++KeCurCPU.preemptCount)
+#define PsEnablePreemption() do { assert(KeCurCPU.preemptCount > 0); \
+ --KeCurCPU.preemptCount; } while(0)
//------------------------------------------//
diff --git a/kaleid/kernel/buf/bprint.c b/kaleid/kernel/buf/bprint.c
new file mode 100644
index 0000000..749100a
--- /dev/null
+++ b/kaleid/kernel/buf/bprint.c
@@ -0,0 +1,373 @@
+//----------------------------------------------------------------------------//
+// GNU GPL OS/K //
+// //
+// Desc: Buffer library //
+// //
+// //
+// Copyright © 2018-2019 The OS/K Team //
+// //
+// This file is part of OS/K. //
+// //
+// OS/K is free software: you can redistribute it and/or modify //
+// it under the terms of the GNU General Public License as published by //
+// the Free Software Foundation, either version 3 of the License, or //
+// any later version. //
+// //
+// OS/K is distributed in the hope that it will be useful, //
+// but WITHOUT ANY WARRANTY//without even the implied warranty of //
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
+// GNU General Public License for more details. //
+// //
+// You should have received a copy of the GNU General Public License //
+// along with OS/K. If not, see . //
+//----------------------------------------------------------------------------//
+
+#include
+
+#include //XXX
+
+error_t bputc(Buffer_t *buf, uchar ch);
+
+//
+// Prints formatted string on buf according to fmt
+//
+error_t BPrintOnBuf(Buffer_t *buf, const char *fmt, ...)
+{
+ error_t rc;
+ va_list ap;
+
+ va_start(ap, fmt);
+ rc = BPrintOnBufV(buf, fmt, ap);
+ va_end(ap);
+
+ return rc;
+}
+//
+// Prints 0 for octal, 0x for hexadecimal, 0b for binary
+//
+static error_t bprinthash(Buffer_t *buf, int base, int cap)
+{
+ error_t rc;
+
+ if (base != 2 && base != 8 && base != 16) {
+ return EOK;
+ }
+
+ rc = bputc(buf, '0');
+
+ if (!rc && base != 8) {
+ rc = bputc(buf, (base==2 ? 'b' : (cap ? 'X' : 'x')));
+ }
+
+ return rc;
+}
+
+static error_t bdopadding(Buffer_t *buf, size_t width, size_t len,
+ char filler)
+{
+ error_t rc = EOK;
+
+ for (; !rc && width > len ; width--) {
+ rc = bputc(buf, filler);
+ }
+
+ return rc;
+}
+
+
+// Increase fmt while parsing a modifier
+#define fmtnext() do{fmt++;if(*fmt==0){rc=EINVAL;goto leave;}}while(0)
+
+//
+// Actually does BPrintOnBuf's job
+// Quite a long function
+//
+error_t BPrintOnBufV(Buffer_t *buf, const char *fmt, va_list ap)
+{
+ error_t rc = EOK;
+ int tmpwidth;
+ size_t width;
+ char type;
+
+ uchar *s;
+ uchar uch;
+
+ // Conversion buffer
+ uchar convbuf[100] = {0};
+ size_t len;
+
+ // Flags
+ int plus, minus, space, zero, hash;
+
+ // Length modifiers
+ int l, h, hh;
+
+ // Signed
+ bool sgn;
+
+ // Capital digits
+ bool cap;
+
+ // Base
+ int base;
+
+ assert(buf && buf->initDone == INITOK);
+
+ if (!buf) return EINVAL;
+ if (buf->state != BS_RDWR && buf->state != BS_WRONLY) {
+ return EBADF;
+ }
+
+ ExAcquireLock(&buf->lock);
+
+//----------------------------------------------------------------------------//
+
+ // We come back here after dealing with a modifier
+loop:
+
+ // Deal with all non-'%' characters
+ for (; !rc && *fmt && *fmt != '%' ; fmt++) {
+ rc = bputc(buf, *fmt);
+ continue;
+ }
+
+ // Job's done / something bad happened
+ if (rc || !*fmt) goto leave;
+
+//----------------------------------------------------------------------------//
+
+ //
+ // %[parameter][flags][width|*][.precision][length]type
+ // We aren't dealing with parameters and float stuff just yet
+ //
+
+ // Skip the '%'
+ fmtnext();
+
+ // "%%" modifier
+ if (*fmt == '%') {
+ rc = bputc(buf, '%');
+
+ if (rc > 0) goto leave;
+ else {
+ fmt++;
+ goto loop;
+ }
+ }
+
+ // Reset everything
+ width = 0;
+ cap = sgn = 0;
+ l = h = hh = 0;
+ plus = minus = space = zero = hash = 0;
+
+//----------------------------------------------------------------------------//
+
+ //
+ // Flags field
+ //
+ while (1) {
+ if (*fmt == '#') hash++;
+ else if (*fmt == '0') zero++;
+ else if (*fmt == '+') plus++;
+ else if (*fmt == '-') minus++;
+ else if (*fmt == ' ') space++;
+ else break;
+ fmtnext();
+ }
+
+//----------------------------------------------------------------------------//
+
+ //
+ // Width field
+ // A width field of zero is ignored
+ //
+
+ // '*' means we should extract it from the argument list
+ if (*fmt == '*') {
+ fmtnext();
+ tmpwidth = va_arg(ap, int);
+
+ // A width below 0 activates the "minus" flag
+ if (tmpwidth < 0) {
+ width = -tmpwidth;
+ minus++;
+ } else {
+ width = tmpwidth;
+ }
+ } else {
+ // Extract width field from fmt
+ while (isdigit(*fmt) && width < sizeof(convbuf)-10) {
+ width = 10 * width + (*fmt - '0');
+ fmtnext();
+ }
+ }
+
+ if (width > sizeof(convbuf)) {
+ rc = EINVAL;
+ goto leave;
+ }
+
+//----------------------------------------------------------------------------//
+
+ //
+ // Precision field
+ // Ignored until floats are implemented
+ //
+
+//----------------------------------------------------------------------------//
+
+ //
+ // Length field
+ //
+ while (1) {
+ if (*fmt == 'l' || *fmt == 'z') l++;
+ else if (*fmt == 'h') h++;
+ else break;
+ fmtnext();
+ }
+
+ // Consistency check
+ assert(!(l > 0 && h > 0));
+ assert(!(l > 2 || h > 2));
+
+//----------------------------------------------------------------------------//
+
+ //
+ // The type field, finally!
+ //
+ type = *fmt++;
+
+ // Characters
+ if (type == 'c') {
+ uch = (uchar)va_arg(ap, int);
+ bputc(buf, uch);
+
+ goto loop;
+ }
+
+ // Strings
+ else if (type == 's') {
+ s = (uchar *)va_arg(ap, char *);
+
+ for (; !rc && *s ; s++) {
+ rc = bputc(buf, *s);
+ }
+
+ if (rc > 0) goto leave;
+ goto loop;
+ }
+
+ // Decimal, unsigned decimal, hexadecimal, octal and binary numbers
+ else if (type == 'd' || type == 'i') { base = 10; sgn = 1; }
+ else if (type == 'X') { base = 16; cap = 1; }
+ else if (type == 'x') { base = 16; }
+ else if (type == 'u') { base = 10; }
+ else if (type == 'o') { base = 8; }
+ else if (type == 'b') { base = 2; }
+
+ // Pointers: %p = %#012x
+ // (48-bit pointers have width 12 at least)
+ else if (type == 'p') {
+ type = 'x'; base = 16; zero++; hash++;
+ if (width < 12) width = 12;
+ }
+
+ // Unknown/unsupported modifier
+ else {
+ rc = EINVAL;
+ goto leave;
+ }
+
+//----------------------------------------------------------------------------//
+
+ //
+ // Numerical conversions
+ //
+
+ // We re-use s to iterate convbuf
+ s = convbuf;
+
+ // Deal with signed conversions
+ if (sgn) {
+ if (l) ltoa(va_arg(ap, long), (char *)s, base);
+ else if (h == 0) itoa(va_arg(ap, int), (char *)s, base);
+ else if (h == 1) itoa((short)va_arg(ap, int), (char *)s, base);
+ else /* h == 2 */ itoa((char)va_arg(ap, int), (char *)s, base);
+ }
+
+ // Deal with unsigned conversions
+ else {
+ if (l) ultoa((ulong)va_arg(ap, long), (char *)s, base);
+ else if (h == 0) utoa((uint)va_arg(ap, int), (char *)s, base);
+ else if (h == 1) utoa((ushort)va_arg(ap, int), (char *)s, base);
+ else /* h == 2 */ utoa((uchar)va_arg(ap, int), (char *)s, base);
+ }
+
+//----------------------------------------------------------------------------//
+
+ //
+ // Implement flags and %X
+ //
+
+ // Capital letter digits
+ if (base > 10 && cap) {
+ for (; *s ; s++)
+ if (islower(*s)) *s = toupper(*s);
+
+ // We use this "opportunity" to compute the length of s
+ len = s - convbuf;
+
+ // Reset s
+ s = convbuf;
+ }
+ else len = strlen((char *)s);
+
+ // Adjust width
+ if (sgn && (plus || space)) width--;
+ else if (hash) width -= (base==8 ? 1 : ((base==2||base==16) ? 2 : 0));
+
+ // When padding with spaces, we pad before +/-'s etc
+ if (!minus && !zero && width > len)
+ bdopadding(buf, width, len, ' ');
+
+ // Deal with signs and the hash flag
+ if (*s == '-') { rc = bputc(buf, '-'); s++, len--; }
+ else if (sgn && plus) rc = bputc(buf, '+');
+ else if (sgn && space) rc = bputc(buf, ' ');
+ else bprinthash(buf, base, cap);
+
+ // Deal with padding by zeroes
+ // The 'minus' flag makes no sense with the 'zero' one
+ if (zero && width > len)
+ bdopadding(buf, width, len, '0');
+
+ //
+ // Output the actual number
+ //
+ for (; !rc && *s ; s++) {
+ rc = bputc(buf, *s);
+ }
+
+ // 'minus' padding, only with spaces
+ if (minus && !zero && width > len)
+ bdopadding(buf, width, base, ' ');
+
+ if (rc > 0) goto leave;
+
+
+//----------------------------------------------------------------------------//
+
+ // Make sure we leave convbuf filled with NULs
+ memzero(convbuf, sizeof(convbuf));
+
+ // Continue parsing fmt
+ goto loop;
+
+//----------------------------------------------------------------------------//
+
+leave:
+ ExReleaseLock(&buf->lock);
+ return rc;
+}
+
diff --git a/kaleid/kernel/buf/bput.c b/kaleid/kernel/buf/bput.c
new file mode 100644
index 0000000..46ce839
--- /dev/null
+++ b/kaleid/kernel/buf/bput.c
@@ -0,0 +1,141 @@
+//----------------------------------------------------------------------------//
+// GNU GPL OS/K //
+// //
+// Desc: Buffer library //
+// //
+// //
+// Copyright © 2018-2019 The OS/K Team //
+// //
+// This file is part of OS/K. //
+// //
+// OS/K is free software: you can redistribute it and/or modify //
+// it under the terms of the GNU General Public License as published by //
+// the Free Software Foundation, either version 3 of the License, or //
+// any later version. //
+// //
+// OS/K is distributed in the hope that it will be useful, //
+// but WITHOUT ANY WARRANTY//without even the implied warranty of //
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
+// GNU General Public License for more details. //
+// //
+// You should have received a copy of the GNU General Public License //
+// along with OS/K. If not, see . //
+//----------------------------------------------------------------------------//
+
+#include
+
+error_t bputc(Buffer_t *buf, uchar ch);
+
+//
+// Writes a character on a buffer
+//
+error_t BPutOnBuf(Buffer_t *buf, uchar ch)
+{
+ error_t rc;
+ assert(buf && buf->initDone == INITOK);
+
+ if (!buf) return EINVAL;
+ if (buf->state != BS_RDWR && buf->state != BS_WRONLY) {
+ return EBADF;
+ }
+
+ ExAcquireLock(&buf->lock);
+ rc = bputc(buf, ch);
+ ExReleaseLock(&buf->lock);
+ return rc;
+}
+
+//
+// Internal, unlocked version of BPutOnBuf
+//
+error_t bputc(Buffer_t *buf, uchar ch)
+{
+ error_t rc;
+ size_t bufSize, pbCount;
+
+ // Implements playback / scrolling up when line buffering
+ // Note that '\n', '\r' and '\t' can never occur in the buffer
+ // That should change; there should be a flag for it
+ if (buf->flags & BF_LINE) {
+
+ // Deal with carriage returns
+ if (ch == '\r') {
+ buf->wp -= buf->lastLF;
+ buf->lastLF = 0;
+ assert(buf->wp >= buf->buf);
+ }
+
+ // Deal with tabs... we need a tabSize field
+ // We assume tabs are 4 characters long for now
+ else if (ch == '\t') {
+ rc = bputc(buf, ' ');
+ if (rc > 0) return rc;
+
+ while (buf->lastLF % 4 > 0) {
+ rc = bputc(buf, ' ');
+ if (rc > 0) return rc;
+ }
+ }
+
+ // Deal with line feeds by filling the rest of the line with spaces
+ // We need a field for choosing a different filler, e.g. '\0'
+ else if (ch == '\n') {
+ assert(buf->lastLF < buf->lineLen);
+ while (buf->lastLF > 0) {
+ rc = bputc(buf, ' ');
+ if (rc > 0) return rc;
+ }
+ }
+
+ // Just a regular character
+ else {
+ // Do we have to scroll up?
+ if (buf->wp == buf->buf + buf->size) {
+ // Yes, so we give up a whole playback buffer worth
+ // of lines so we don't have to do this too often
+ // (basically we make the current buffer a pb one)
+ bufSize = buf->nLines * buf->lineLen;
+ pbCount = (buf->size / bufSize) - 1;
+
+ // Paranoia check
+ assert(buf->size >= (size_t)(buf->nLines * buf->lineLen));
+
+ // If we only have one playback buffer we just give up a line
+ if (pbCount == 0) {
+ // Use of memcpy() is safe because the source occur
+ // after the destination
+ memcpy(buf->buf, buf->buf + buf->lineLen,
+ buf->size - buf->lineLen);
+ buf->wp -= buf->lineLen;
+ }
+
+ // We do have a playback buffer worth of lines to give up
+ else {
+ memcpy(buf->buf, buf->buf + bufSize,
+ buf->size - bufSize);
+ buf->wp -= buf->lineLen;
+ }
+ }
+
+ // Write the damn thing
+ *buf->wp++ = ch;
+
+ // Did we reach the end of line?
+ if (++buf->lastLF == buf->lineLen) {
+ buf->lastLF = 0;
+ }
+ }
+
+ return EOK;
+ }
+
+ // No scrolling up when not line-buffering
+ else {
+ if (buf->wp == buf->buf + buf->size) {
+ buf->state = BS_EOF;
+ }
+
+ return ENOSYS;
+ }
+}
+
diff --git a/kaleid/kernel/buf/buf.c b/kaleid/kernel/buf/buf.c
index 3491ffd..b69534c 100644
--- a/kaleid/kernel/buf/buf.c
+++ b/kaleid/kernel/buf/buf.c
@@ -47,9 +47,7 @@ void BFlushOnClose(Buffer_t *buf) { buf->flags |= BF_FONCLOSE; }
//
error_t BCloseBuf(Buffer_t *buf)
{
- if (!buf) return EINVAL;
-
- assert(buf->initDone == INITOK);
+ assert(buf && buf->initDone == INITOK);
ExAcquireLock(&buf->lock);
if (buf->flags & BF_FONCLOSE) {
@@ -109,9 +107,9 @@ Buffer_t *BOpenLineBuf(char *source, int mode,
buf->size = lineLen * nLines * (pbCount + 1);
if (source == NULL) {
- buf->buf = malloc(buf->size);
+ buf->buf = calloc(buf->size, 1);
} else {
- buf->buf = source;
+ buf->buf = (uchar *)source;
}
buf->wp = buf->rp = buf->buf;
@@ -141,123 +139,4 @@ error_t BFlushBuf(Buffer_t *buf)
ExReleaseLock(&buf->lock);
return rc;
-}
-
-static error_t bputc(Buffer_t *buf, uchar ch);
-
-//
-// Writes a character on a buffer
-//
-error_t BPutOnBuf(Buffer_t *buf, uchar ch)
-{
- error_t rc;
- assert(buf && buf->initDone == INITOK);
-
- if (!buf) return EINVAL;
- if (buf->state != BS_RDWR && buf->state != BS_WRONLY) {
- return EBADF;
- }
-
- ExAcquireLock(&buf->lock);
- rc = bputc(buf, ch);
- ExReleaseLock(&buf->lock);
- return rc;
-}
-
-//
-// Internal, unlocked version of BPutOnBuf
-//
-static error_t bputc(Buffer_t *buf, uchar ch)
-{
- error_t rc;
- size_t bufSize, pbCount;
-
- // Implements playback / scrolling up when line buffering
- // Note that '\n', '\r' and '\t' can never occur in the buffer
- // That should change; there should be a flag for it
- if (buf->flags & BF_LINE) {
-
- // Deal with carriage returns
- if (ch == '\r') {
- buf->wp -= buf->lastLF;
- buf->lastLF = 0;
- assert(buf->wp >= buf->buf);
- }
-
- // Deal with tabs... we need a tabSize field
- // We assume tabs are 4 characters long for now
- else if (ch == '\t') {
- rc = bputc(buf, ' ');
- if (rc > 0) return rc;
-
- while (buf->lastLF % 4 > 0) {
- rc = bputc(buf, ' ');
- if (rc > 0) return rc;
- }
- }
-
- // Deal with line feeds by filling the rest of the line with spaces
- // We need a field for choosing a different filler, e.g. '\0'
- else if (ch == '\n') {
- assert(buf->lastLF < buf->lineLen);
- while (buf->lastLF > 0) {
- rc = bputc(buf, ' ');
- if (rc > 0) return rc;
- }
- }
-
- // Just a regular character
- else {
- // Do we have to scroll up?
- if (buf->wp == buf->buf + buf->size) {
- // Yes, so we give up a whole playback buffer worth
- // of lines so we don't have to do this too often
- // (basically we make the current buffer a pb one)
- bufSize = buf->nLines * buf->lineLen;
- pbCount = (buf->size / bufSize) - 1;
-
- // Paranoia check
- assert(buf->size >= (size_t)(buf->nLines * buf->lineLen));
-
- // If we only have one playback buffer we just give up a line
- if (pbCount == 0) {
- // Use of memcpy() is safe because the source occur
- // after the destination
- memcpy(buf->buf, buf->buf + buf->lineLen,
- buf->size - buf->lineLen);
- buf->wp -= buf->lineLen;
- }
-
- // We do have a playback buffer worth of lines to give up
- else {
- memcpy(buf->buf, buf->buf + bufSize,
- buf->size - bufSize);
- buf->wp -= buf->lineLen;
- }
- }
-
- // Write the damn thing
- *buf->wp++ = (char)ch;
-
- // Did we reach the end of line?
- if (++buf->lastLF == buf->lineLen) {
- buf->lastLF = 0;
- }
- }
-
- return EOK;
- }
-
- // No scrolling up when not line-buffering
- else {
- if (buf->wp == buf->buf + buf->size) {
- buf->state = BS_EOF;
- }
-
- return ENOSYS;
- }
-}
-
-error_t BPrintOnBuf(Buffer_t *buf, size_t n, const char *fmt, ...);
-error_t BPrintOnBufV(Buffer_t *buf, size_t n, const char *fmt, va_list ap);
-
+}
\ No newline at end of file
diff --git a/kaleid/kernel/cpu/cpuid.c b/kaleid/kernel/cpu/cpuid.c
index ef8b36a..d1f756b 100644
--- a/kaleid/kernel/cpu/cpuid.c
+++ b/kaleid/kernel/cpu/cpuid.c
@@ -22,4 +22,12 @@
// along with OS/K. If not, see . //
//----------------------------------------------------------------------------//
-int stub;
+
+char *KeGetVendorString(void) {
+ return "Null";
+}
+
+
+
+
+
diff --git a/kaleid/kernel/cpu/idt.c b/kaleid/kernel/cpu/idt.c
new file mode 100644
index 0000000..ae3c860
--- /dev/null
+++ b/kaleid/kernel/cpu/idt.c
@@ -0,0 +1,37 @@
+//----------------------------------------------------------------------------//
+// GNU GPL OS/K //
+// //
+// Desc: Interrupt related functions //
+// //
+// //
+// Copyright © 2018-2019 The OS/K Team //
+// //
+// This file is part of OS/K. //
+// //
+// OS/K is free software: you can redistribute it and/or modify //
+// it under the terms of the GNU General Public License as published by //
+// the Free Software Foundation, either version 3 of the License, or //
+// any later version. //
+// //
+// OS/K is distributed in the hope that it will be useful, //
+// but WITHOUT ANY WARRANTY//without even the implied warranty of //
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
+// GNU General Public License for more details. //
+// //
+// You should have received a copy of the GNU General Public License //
+// along with OS/K. If not, see . //
+//----------------------------------------------------------------------------//
+
+
+//
+// Registers the new idt in the idtr register.
+//
+static inline void lidt(void* idtAddr, ushort size)
+{
+ struct {
+ ushort length;
+ void* base;
+ } __attribute__((packed)) IDTR = { size, idtAddr };
+
+ asm volatile( "lidt %0" : : "m"(IDTR) );
+}
diff --git a/kaleid/kernel/init/init.c b/kaleid/kernel/init/init.c
index bd07433..4fd22bd 100644
--- a/kaleid/kernel/init/init.c
+++ b/kaleid/kernel/init/init.c
@@ -24,7 +24,10 @@
#include
#include
+#include
#include
+#include
+#include
#include
//
@@ -33,8 +36,8 @@
//
void BtInitBootInfo(multiboot_info_t *mbi)
{
- extern ullong MB_header;
- extern ullong kernelEnd;
+ extern ulong MB_header;
+ extern ulong newKernelEnd;
// We need the multiboot structure
KalAlwaysAssert(mbi);
@@ -43,19 +46,19 @@ void BtInitBootInfo(multiboot_info_t *mbi)
BtGetBootInfo(btldr).grubFlags = mbi->flags;
if (BtGetBootInfo(btldr).grubFlags & MULTIBOOT_INFO_BOOT_LOADER_NAME) {
- BtGetBootInfo(btldr).grubName = (char*)(ullong)(mbi->boot_loader_name);
+ BtGetBootInfo(btldr).grubName = (char*)(ulong)(mbi->boot_loader_name);
BtGetBootInfo(btldr).kernelAddr = (void*)&MB_header;
- BtGetBootInfo(btldr).kernelEndAddr = (void*)&kernelEnd;
+ BtGetBootInfo(btldr).kernelEndAddr = (void*)newKernelEnd;
BtGetBootInfo(btldr).valid = 1;
}
if (BtGetBootInfo(btldr).grubFlags & MULTIBOOT_INFO_MODS) {
BtGetBootInfo(btldr).modulesCount = mbi->mods_count;
- BtGetBootInfo(btldr).modulesAddr = (void*)(ullong)mbi->mods_addr;
+ BtGetBootInfo(btldr).modulesAddr = (void*)(ulong)mbi->mods_addr;
}
//Retrieves the drives informations
if (BtGetBootInfo(btldr).grubFlags & MULTIBOOT_INFO_DRIVE_INFO) {
BtGetBootInfo(drives).bufferLength = mbi->drives_length;
- BtGetBootInfo(drives).bufferAddr = (void*)(ullong)mbi->drives_addr;
+ BtGetBootInfo(drives).bufferAddr = (void*)(ulong)mbi->drives_addr;
BtGetBootInfo(drives).bufferValid = 1;
}
if (BtGetBootInfo(btldr).grubFlags & MULTIBOOT_INFO_BOOTDEV) {
@@ -70,15 +73,15 @@ void BtInitBootInfo(multiboot_info_t *mbi)
BtGetBootInfo(memory).memValid = 1;
}
if (BtGetBootInfo(btldr).grubFlags & MULTIBOOT_INFO_MEM_MAP) {
- BtGetBootInfo(memory).mapAddr = (void*)(ullong)mbi->mmap_addr;
+ BtGetBootInfo(memory).mapAddr = (void*)(ulong)mbi->mmap_addr;
BtGetBootInfo(memory).mapLength = mbi->mmap_length;
BtGetBootInfo(memory).mapValid = 1;
}
// Retrieves video mode informations
if (BtGetBootInfo(btldr).grubFlags & MULTIBOOT_INFO_VBE_INFO) {
- BtGetBootInfo(video).vbeControl = (void*)(ullong)mbi->vbe_control_info;
- BtGetBootInfo(video).vbeModeInfo = (void*)(ullong)mbi->vbe_mode_info;
+ BtGetBootInfo(video).vbeControl = (void*)(ulong)mbi->vbe_control_info;
+ BtGetBootInfo(video).vbeModeInfo = (void*)(ulong)mbi->vbe_mode_info;
BtGetBootInfo(video).vbeMode = mbi->vbe_mode;
BtGetBootInfo(video).vbeInterfaceSeg = mbi->vbe_interface_seg;
BtGetBootInfo(video).vbeInterfaceOff = mbi->vbe_interface_off;
@@ -86,7 +89,7 @@ void BtInitBootInfo(multiboot_info_t *mbi)
BtGetBootInfo(video).vbeValid = 1;
}
if (BtGetBootInfo(btldr).grubFlags & MULTIBOOT_INFO_FRAMEBUFFER_INFO) {
- BtGetBootInfo(video).framebufferAddr = (void*)(ullong)mbi->framebuffer_addr;
+ BtGetBootInfo(video).framebufferAddr = (void*)mbi->framebuffer_addr;
BtGetBootInfo(video).framebufferPitch = mbi->framebuffer_pitch;
BtGetBootInfo(video).framebufferWidth = mbi->framebuffer_width;
BtGetBootInfo(video).framebufferHeight= mbi->framebuffer_height;
@@ -106,6 +109,7 @@ void BtInitBootInfo(multiboot_info_t *mbi)
}
}
+extern void pstest(void);
//
// Entry point of the Kaleid kernel
@@ -138,12 +142,17 @@ noreturn void BtStartKern(multiboot_info_t *mbInfo, int mbMagic)
mapBad
);
- KernLog("[Init] TEST First zone from %p : %p\n", (void*)0xB8010, MmGetFirstAvailZone((void*)0xB8010));
- KernLog("[Init] TEST Size of zone : %u Kio\n\n", MmGetAvailZoneSize(MmGetFirstAvailZone((void*)0xB8010)) / KB);
+ MmInitHeap();
+ PsInitSched();
+ Buffer_t *buf = BOpenLineBuf(NULL, BS_WRONLY, 80, 24, 1, NULL);
+ error_t rc = BPrintOnBuf(buf, "%+#05x", 0xcafeb00b);
+ if(rc)KernLog("error\n");
+
+ KernLog((char*)buf->buf);
// We're out
- KernLog("\n[Init] Evil never dies !\n");
+ PsFiniSched();
KeCrashSystem(); //yay
}
diff --git a/kaleid/kernel/ke/panic.c b/kaleid/kernel/ke/panic.c
index 9c9f56b..181ab5b 100644
--- a/kaleid/kernel/ke/panic.c
+++ b/kaleid/kernel/ke/panic.c
@@ -35,10 +35,8 @@ noreturn void __assert_handler(const char *msg,
{
KeDisableIRQs();
- (void)file; (void)line; (void)func;
-
- KeStartPanic("In function '%s', from %s line %d - assertion failed: '%s'",
- func, file, line, msg);
+ KeStartPanic("In function '%s', from '%s' line %d\nAssertion failed:\n"
+ "'%s'", func, file, line, msg);
}
//
@@ -51,7 +49,7 @@ noreturn void KeStartPanic(const char *fmt, ...)
KeDisableIRQs();
- if (PsGetCurProc()) _PsSetCurProc(NULL);
+ PsCurProc = NULL;
if (StdOut == NULL) KeCrashSystem();
if (fmt == NULL) {
diff --git a/kaleid/kernel/mm/heap.c b/kaleid/kernel/mm/heap.c
index 54c700b..86c6878 100644
--- a/kaleid/kernel/mm/heap.c
+++ b/kaleid/kernel/mm/heap.c
@@ -24,6 +24,7 @@
#include
#include
+#include
// Least address out of the heap
static void *_heap_end;
@@ -34,15 +35,23 @@ static size_t _heap_max;
// Lock NOT used internally, but used by KalAllocMemory() & co.
static Lock_t _heap_lock = ExINITLOCK(KLOCK_SPINLOCK);
-
//
// Initializes heap managment
//
void MmInitHeap(void)
{
assert(_heap_end == NULL);
- _heap_end = (void *)_HEAP_START;
- _heap_max = lmin(8 * MB, MmGetAvailZoneSize((void *)_HEAP_START));
+
+ // Get the first available zone address
+ _heap_start = MmGetFirstAvailZone((void*)0);
+ // Align it
+ while ((size_t)_heap_start % alignof(QWORD)) {
+ _heap_start++;
+ }
+ // Initialize the heap
+ _heap_end = _heap_start;
+ _heap_max = lmin(8 * MB, MmGetAvailZoneSize(_heap_end));
+ KernLog("[InitHeap] Start address : %p, Max length : %u Mio\n\n", _heap_start, _heap_max / MB);
}
//
@@ -66,7 +75,7 @@ void MmUnlockHeap(void)
//
size_t MmGetHeapSize(void)
{
- return (size_t)_heap_end - _HEAP_START;
+ return (size_t)_heap_end - (size_t)_heap_start;
}
//
@@ -82,11 +91,11 @@ size_t MmGetMaxHeapSize(void)
//
error_t MmSetMaxHeapSize(size_t new)
{
- if (new > MmGetAvailZoneSize((void *)_HEAP_START)) {
+ if (new > MmGetAvailZoneSize((void *)_heap_start)) {
return ENOMEM;
}
- if (new < (size_t)_heap_end - _HEAP_START) {
+ if (new < (size_t)_heap_end - (size_t)_heap_start) {
return EADDRINUSE;
}
@@ -100,9 +109,9 @@ error_t MmSetMaxHeapSize(size_t new)
//
error_t MmGrowHeap(size_t req)
{
- assert(req % alignof(QWORD));
+ assert(req % alignof(QWORD) == 0);
- if ((size_t)_heap_end + req > _HEAP_START + _heap_max) {
+ if ((size_t)_heap_end + req > (size_t)_heap_start + _heap_max) {
return ENOMEM;
}
@@ -116,9 +125,9 @@ error_t MmGrowHeap(size_t req)
//
error_t MmShrinkHeap(size_t req)
{
- assert(req % alignof(QWORD));
+ assert(req % alignof(QWORD) == 0);
- if (req > (size_t)_heap_end - _HEAP_START) {
+ if (req > (size_t)_heap_end - (size_t)_heap_start) {
return EADDRINUSE;
}
diff --git a/kaleid/kernel/mm/malloc.c b/kaleid/kernel/mm/malloc.c
index 1c699a2..a510204 100644
--- a/kaleid/kernel/mm/malloc.c
+++ b/kaleid/kernel/mm/malloc.c
@@ -29,6 +29,7 @@ error_t KalAllocMemory(void **ptr, size_t req, int flags, size_t align)
{
error_t rc;
size_t brk;
+ extern void *_heap_start;
if (align == 0) align = M_DEFAULT_ALIGNMENT;
@@ -38,7 +39,7 @@ error_t KalAllocMemory(void **ptr, size_t req, int flags, size_t align)
MmLockHeap();
- brk = _HEAP_START + MmGetHeapSize();
+ brk = (size_t)_heap_start + MmGetHeapSize();
req = _ALIGN_UP(req + brk, align) - brk;
rc = MmGrowHeap(req);
@@ -57,6 +58,7 @@ error_t KalAllocMemory(void **ptr, size_t req, int flags, size_t align)
*ptr = (void *)brk;
+ assert(*ptr);
return rc;
}
diff --git a/kaleid/kernel/mm/map.c b/kaleid/kernel/mm/map.c
index 320a9b3..80759d4 100644
--- a/kaleid/kernel/mm/map.c
+++ b/kaleid/kernel/mm/map.c
@@ -52,23 +52,23 @@ error_t MmInitMemoryMap(void)
currentEntry = (multiboot_memory_map_t*)BtGetBootInfo(memory).mapAddr;
// End address of the map
mapEnd = (multiboot_memory_map_t*)
- ((ullong)currentEntry + (ullong)BtGetBootInfo(memory).mapLength);
+ ((ulong)currentEntry + (ulong)BtGetBootInfo(memory).mapLength);
// fill the map
while (currentEntry < mapEnd) {
// memory zone address
- memoryMap.entry[i].addr = (void*)( (ullong)currentEntry->addr_low +
- (((ullong)currentEntry->addr_high) << 32 ));
+ memoryMap.entry[i].addr = (void*)((ulong)currentEntry->addr_low +
+ (((ulong)currentEntry->addr_high) << 32 ));
// memory zone size in bytes
- memoryMap.entry[i].length = (ullong)currentEntry->len_low +
- (((ullong)currentEntry->len_high) << 32);
+ memoryMap.entry[i].length = (ulong)currentEntry->len_low +
+ (((ulong)currentEntry->len_high) << 32);
// memory availability
memoryMap.entry[i].type = (uint)currentEntry->type;
// Adding the size to the size (yup)
memoryMap.length++;
// moving up !
- currentEntry = (multiboot_memory_map_t*) ((ullong)currentEntry +
- currentEntry->size + sizeof(currentEntry->size));
+ currentEntry = (multiboot_memory_map_t*) ((ulong)currentEntry +
+ currentEntry->size + sizeof(currentEntry->size));
i++;
}
@@ -108,11 +108,11 @@ size_t MmGetAvailZoneSize(void *start) {
// if the address is in an available zone, we can return the length
if (
memoryMap.entry[i].type == AVAILABLE_ZONE &&
- (ullong)start >= (ullong)memoryMap.entry[i].addr &&
- (ullong)start < ((ullong)memoryMap.entry[i].addr +
- (ullong)memoryMap.entry[i].length)
+ (ulong)start >= (ulong)memoryMap.entry[i].addr &&
+ (ulong)start < ((ulong)memoryMap.entry[i].addr +
+ (ulong)memoryMap.entry[i].length)
) {
- return (size_t)((ullong)memoryMap.entry[i].length - (ullong)start);
+ return (size_t)((ulong)memoryMap.entry[i].length - (ulong)start);
}
}
@@ -125,7 +125,7 @@ void *MmGetFirstAvailZone(void *start) {
void *current = 0;
// Because the kernel is the kernel
- if ((ullong)start < (ullong)BtGetBootInfo(btldr).kernelEndAddr) {
+ if ((ulong)start < (ulong)BtGetBootInfo(btldr).kernelEndAddr) {
return MmGetFirstAvailZone(BtGetBootInfo(btldr).kernelEndAddr);
}
@@ -134,9 +134,9 @@ void *MmGetFirstAvailZone(void *start) {
// if the address is in an available zone, we can return the start address
if (
memoryMap.entry[i].type == AVAILABLE_ZONE &&
- (ullong)start >= (ullong)memoryMap.entry[i].addr &&
- (ullong)start < ((ullong)memoryMap.entry[i].addr +
- (ullong)memoryMap.entry[i].length)
+ (ulong)start >= (ulong)memoryMap.entry[i].addr &&
+ (ulong)start < ((ulong)memoryMap.entry[i].addr +
+ (ulong)memoryMap.entry[i].length)
) {
current = start;
break;
@@ -151,7 +151,7 @@ void *MmGetFirstAvailZone(void *start) {
// Return the first zone that is after start
if (
memoryMap.entry[i].type == AVAILABLE_ZONE &&
- (ullong)start <= (ullong)memoryMap.entry[i].addr
+ (ulong)start <= (ulong)memoryMap.entry[i].addr
) {
current = memoryMap.entry[i].addr;
break;
diff --git a/kaleid/kernel/mm/stack.c b/kaleid/kernel/mm/stack.c
new file mode 100644
index 0000000..2bb1aaf
--- /dev/null
+++ b/kaleid/kernel/mm/stack.c
@@ -0,0 +1,23 @@
+//----------------------------------------------------------------------------//
+// GNU GPL OS/K //
+// //
+// Desc: Mapping and checking memory related functions //
+// //
+// //
+// Copyright © 2018-2019 The OS/K Team //
+// //
+// This file is part of OS/K. //
+// //
+// OS/K is free software: you can redistribute it and/or modify //
+// it under the terms of the GNU General Public License as published by //
+// the Free Software Foundation, either version 3 of the License, or //
+// any later version. //
+// //
+// OS/K is distributed in the hope that it will be useful, //
+// but WITHOUT ANY WARRANTY//without even the implied warranty of //
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
+// GNU General Public License for more details. //
+// //
+// You should have received a copy of the GNU General Public License //
+// along with OS/K. If not, see . //
+//----------------------------------------------------------------------------//
diff --git a/kaleid/kernel/proc/sched.c b/kaleid/kernel/proc/sched.c
index d8ba70d..2b75f5d 100644
--- a/kaleid/kernel/proc/sched.c
+++ b/kaleid/kernel/proc/sched.c
@@ -25,10 +25,7 @@
#include
#include
#include
-
-#ifndef _KALEID_KERNEL
-
-#include
+#include
//
// For test purpose only
@@ -47,18 +44,25 @@ Process_t procs[] = {
{ 9, 2, 2, 21, 21, STATE_RUNNABLE, DEF_PROC_TSLICE, DEF_PROC_TSLICE, NULL, NULL, NULL },
};
-#endif
+//------------------------------------------//
+
+#define ReSchedFlag (KeCurCPU.needReSched)
+#define PreemptCount (KeCurCPU.preemptCount)
+
+#define IdlePrioProcs (KeCurCPU.idlePrioProcs)
+#define ReglPrioProcs (KeCurCPU.reglPrioProcs)
+#define ServPrioProcs (KeCurCPU.servPrioProcs)
+#define TimeCritProcs (KeCurCPU.timeCritProcs)
+
+//------------------------------------------//
//
// Set current process
-// TODO Select thread, context switch
//
static void SetCurProc(Process_t *proc)
{
- _SetCurProc(proc);
- if (GetCurProc() != NULL) {
- GetCurProc()->procState = STATE_RUNNING;
- }
+ PsCurProc = proc;
+ if (PsCurProc) PsCurProc->procState = STATE_RUNNING;
}
//
@@ -66,28 +70,24 @@ static void SetCurProc(Process_t *proc)
//
static inline
-void SchedLock(void) {
-#ifdef _KALEID_KERNEL
- DisableIRQs();
-#endif
+void PsLockSched(void) {
+ KeDisableIRQs();
}
static inline
-void SchedUnlock(void) {
-#ifdef _KALEID_KERNEL
- EnableIRQs();
-#endif
+void PsUnlockSched(void) {
+ //KeEnableIRQs();
}
//
// The four priority classes of OS/2
//
-CREATE_PER_CPU(TimeCritProcs, ListHead_t *);
+/*CREATE_PER_CPU(TimeCritProcs, ListHead_t *);
CREATE_PER_CPU(ServPrioProcs, ListHead_t *);
CREATE_PER_CPU(ReglPrioProcs, ListHead_t *);
-CREATE_PER_CPU(IdlePrioProcs, ListHead_t *);
+CREATE_PER_CPU(IdlePrioProcs, ListHead_t *);*/
-const char *PrioClassesNames[] = {
+const char *PsPrioClassesNames[] = {
"Time-critical class",
"Server priority class",
"Regular priority class",
@@ -100,10 +100,10 @@ const char *PrioClassesNames[] = {
static ListHead_t *GetPrioClassHead(int prioClass)
{
switch (prioClass) {
- case TIME_CRIT_PROC: return GetTimeCritProcs();
- case SERV_PRIO_PROC: return GetServPrioProcs();
- case REGL_PRIO_PROC: return GetReglPrioProcs();
- case IDLE_PRIO_PROC: return GetIdlePrioProcs();
+ case TIME_CRIT_PROC: return TimeCritProcs;
+ case SERV_PRIO_PROC: return ServPrioProcs;
+ case REGL_PRIO_PROC: return ReglPrioProcs;
+ case IDLE_PRIO_PROC: return IdlePrioProcs;
default: KalAssert(FALSE && "Unknown priority class");
}
@@ -134,23 +134,24 @@ static void SchedThisProcUnlocked(Process_t *proc)
{
KalAssert(proc && proc->procState == STATE_RUNNABLE && !proc->schedNode);
- bool found = false;
+ bool found = 0;
ListNode_t *iterNode = NULL;
- ListNode_t *procNode = CreateNode(proc);
+ ListNode_t *procNode = ExCreateNode(proc);
ListHead_t *head = GetPrioClassHead(proc->prioClass);
- KalAssert(procNode && head);
+ KalAssert(head);
+ KalAssert(procNode);
proc->schedNode = procNode;
// Find a process with lesser priority
for (iterNode = head->first; iterNode; iterNode = iterNode->next) {
- if (proc->prioLevel > GetNodeData(iterNode, Process_t *)->prioLevel) {
+ if (proc->prioLevel > ExGetNodeData(iterNode, Process_t *)->prioLevel) {
// Detect double insertions
- KalAssert(proc->pid != GetNodeData(iterNode, Process_t *)->pid);
+ KalAssert(proc->pid != ExGetNodeData(iterNode, Process_t *)->pid);
// Add process to schedule
- AddNodeBefore(head, iterNode, procNode);
+ ExAddNodeBefore(head, iterNode, procNode);
found = true;
break;
}
@@ -158,20 +159,20 @@ static void SchedThisProcUnlocked(Process_t *proc)
// Didn't find any process with lesser priority
if (found == false) {
- AppendNode(head, procNode);
+ ExAppendNode(head, procNode);
}
}
//
// Add process to schedule lists
//
-void SchedThisProc(Process_t *proc)
+void PsSchedThisProc(Process_t *proc)
{
- SchedLock();
+ PsLockSched();
SchedThisProcUnlocked(proc);
- SchedUnlock();
+ PsUnlockSched();
}
//
@@ -182,10 +183,17 @@ void SchedThisProc(Process_t *proc)
//
static Process_t *SelectSchedNext(void)
{
- if (GetTimeCritProcs()->length > 0) return GetNodeData(GetTimeCritProcs()->first, Process_t *);
- if (GetServPrioProcs()->length > 0) return GetNodeData(GetServPrioProcs()->first, Process_t *);
- if (GetReglPrioProcs()->length > 0) return GetNodeData(GetReglPrioProcs()->first, Process_t *);
- if (GetIdlePrioProcs()->length > 0) return GetNodeData(GetIdlePrioProcs()->first, Process_t *);
+ if (TimeCritProcs->length > 0)
+ return ExGetNodeData(TimeCritProcs->first, Process_t *);
+
+ if (ServPrioProcs->length > 0)
+ return ExGetNodeData(ServPrioProcs->first, Process_t *);
+
+ if (ReglPrioProcs->length > 0)
+ return ExGetNodeData(ReglPrioProcs->first, Process_t *);
+
+ if (IdlePrioProcs->length > 0)
+ return ExGetNodeData(IdlePrioProcs->first, Process_t *);
return NULL;
}
@@ -194,82 +202,82 @@ static Process_t *SelectSchedNext(void)
// Remove running process from schedule lists
// and schedule next runnable process
//
-void BlockCurProc(void)
+void PsBlockCurProc(void)
{
- KalAssert(GetCurProc() && GetCurProc()->procState == STATE_RUNNING);
+ KalAssert(PsCurProc && PsCurProc->procState == STATE_RUNNING);
- ListNode_t *procNode = GetCurProc()->schedNode;
+ ListNode_t *procNode = PsCurProc->schedNode;
KalAssert(procNode && "Blocking non-scheduled process");
- GetCurProc()->procState = STATE_BLOCKED;
- RemoveNode(procNode->head, procNode);
+ PsCurProc->procState = STATE_BLOCKED;
+ ExRemoveNode(procNode->head, procNode);
- GetCurProc()->schedNode = NULL;
+ PsCurProc->schedNode = NULL;
SetCurProc(SelectSchedNext());
}
static void ReSchedCurProc(void)
{
- KalAssert(GetCurProc() && GetCurProc()->procState == STATE_RUNNING);
- KalAssert(GetCurProc()->schedNode);
+ KalAssert(PsCurProc && PsCurProc->procState == STATE_RUNNING);
+ KalAssert(PsCurProc->schedNode);
// Restore default attributes, cancelling boosts
- GetCurProc()->prioClass = GetCurProc()->defPrioClass;
- GetCurProc()->prioLevel = GetCurProc()->defPrioLevel;
- GetCurProc()->timeSlice = GetCurProc()->defTimeSlice;
- GetCurProc()->procState = STATE_RUNNABLE;
+ PsCurProc->prioClass = PsCurProc->defPrioClass;
+ PsCurProc->prioLevel = PsCurProc->defPrioLevel;
+ PsCurProc->timeSlice = PsCurProc->defTimeSlice;
+ PsCurProc->procState = STATE_RUNNABLE;
// Remove from list
- RemoveNode(GetCurProc()->schedNode->head, GetCurProc()->schedNode);
- GetCurProc()->schedNode = NULL;
+ ExRemoveNode(PsCurProc->schedNode->head, PsCurProc->schedNode);
+ PsCurProc->schedNode = NULL;
// Schedule again, with default attributes now
- SchedThisProcUnlocked(GetCurProc());
+ SchedThisProcUnlocked(PsCurProc);
}
//
// Should we schedule another process?
// Called at each tick
//
-void SchedOnTick(void)
+void PsSchedOnTick(void)
{
- SchedLock();
+ PsLockSched();
- Process_t *procNext, *winner, *previous = GetCurProc();
+ Process_t *procNext, *winner, *previous = PsCurProc;
// We're either idle or running something
- KalAssert(GetCurProc() == NULL || GetCurProc()->procState == STATE_RUNNING);
+ KalAssert(PsCurProc == NULL || PsCurProc->procState == STATE_RUNNING);
// Have the current process spent its timeslice?
// (To be handled in CPU decisions function)
- if (GetCurProc() != NULL) {
- if (GetCurProc()->timeSlice <= 1) {
+ if (PsCurProc != NULL) {
+ if (PsCurProc->timeSlice <= 1) {
// Re-schedule
ReSchedCurProc();
// See next 'if' statement
- _SetCurProc(NULL);
+ PsCurProc = NULL;
}
// Otherwise, make it lose a tick
else {
- GetCurProc()->timeSlice--;
+ PsCurProc->timeSlice--;
}
}
// Are we idle, or scheduling next process?
- if (GetCurProc() == NULL) {
+ if (PsCurProc == NULL) {
SetCurProc(SelectSchedNext());
goto leave;
}
// Is preemption on and a re-schedule is needed?
- if (GetPreemptCount() == PREEMPT_ON && GetReSchedFlag()) {
+ if (PreemptCount == PREEMPT_ON && ReSchedFlag) {
// Is there a higher priority process that is runnable?
procNext = SelectSchedNext();
- winner = CompareProcs(GetCurProc(), procNext);
+ winner = CompareProcs(PsCurProc, procNext);
// Yes, procNext should preempt current process
if (winner == procNext) {
@@ -283,9 +291,9 @@ void SchedOnTick(void)
// Current process won't be preempted and has time remaining
leave:
- SchedUnlock();
+ PsUnlockSched();
- if (GetCurProc() != NULL && GetCurProc() != previous) {
+ if (PsCurProc != NULL && PsCurProc != previous) {
// XXX context switch
}
}
@@ -293,55 +301,59 @@ leave:
//
// Initialize scheduler
//
-void InitSched(void)
+void PsInitSched(void)
{
int pid;
- SchedLock();
+ PsLockSched();
- _SetTimeCritProcs(CreateListHead());
- _SetServPrioProcs(CreateListHead());
- _SetReglPrioProcs(CreateListHead());
- _SetIdlePrioProcs(CreateListHead());
+ TimeCritProcs = ExCreateListHead();
+ ServPrioProcs = ExCreateListHead();
+ ReglPrioProcs = ExCreateListHead();
+ IdlePrioProcs = ExCreateListHead();
+
+ KalAssert(IdlePrioProcs && ReglPrioProcs && ServPrioProcs && TimeCritProcs);
-#ifndef _KALEID_KERNEL
for (pid = 0; pid < procslen; pid++) {
if (procs[pid].procState == STATE_RUNNABLE) {
SchedThisProcUnlocked(&procs[pid]);
}
}
-#endif
- SchedUnlock();
+ PsUnlockSched();
}
//
// Shutdown scheduler
//
-void FiniSched(void)
+void PsFiniSched(void)
{
- KalAssert(GetIdlePrioProcs() && GetReglPrioProcs() && GetServPrioProcs() && GetTimeCritProcs());
+ KalAssert(IdlePrioProcs && ReglPrioProcs && ServPrioProcs && TimeCritProcs);
- SchedLock();
+ PsLockSched();
- while (GetIdlePrioProcs()->length > 0) RemoveNode(GetIdlePrioProcs(), GetIdlePrioProcs()->first);
- while (GetReglPrioProcs()->length > 0) RemoveNode(GetReglPrioProcs(), GetReglPrioProcs()->first);
- while (GetServPrioProcs()->length > 0) RemoveNode(GetServPrioProcs(), GetServPrioProcs()->first);
- while (GetTimeCritProcs()->length > 0) RemoveNode(GetTimeCritProcs(), GetTimeCritProcs()->first);
+ while (IdlePrioProcs->length > 0)
+ ExRemoveNode(IdlePrioProcs, IdlePrioProcs->first);
- DestroyListHead(GetIdlePrioProcs()); _SetIdlePrioProcs(NULL);
- DestroyListHead(GetReglPrioProcs()); _SetReglPrioProcs(NULL);
- DestroyListHead(GetServPrioProcs()); _SetServPrioProcs(NULL);
- DestroyListHead(GetTimeCritProcs()); _SetTimeCritProcs(NULL);
+ while (ReglPrioProcs->length > 0)
+ ExRemoveNode(ReglPrioProcs, ReglPrioProcs->first);
- SchedUnlock();
+ while (ServPrioProcs->length > 0)
+ ExRemoveNode(ServPrioProcs, ServPrioProcs->first);
+
+ while (TimeCritProcs->length > 0)
+ ExRemoveNode(TimeCritProcs, TimeCritProcs->first);
+
+ ExDestroyListHead(IdlePrioProcs); IdlePrioProcs = NULL;
+ ExDestroyListHead(ReglPrioProcs); ReglPrioProcs = NULL;
+ ExDestroyListHead(ServPrioProcs); ServPrioProcs = NULL;
+ ExDestroyListHead(TimeCritProcs); TimeCritProcs = NULL;
+
+ PsUnlockSched();
}
-#ifndef _KALEID_KERNEL
-
-#define PrintProc(proc) printf("{ %d, '%s', %d , %lu}\n", (proc)->pid, \
- PrioClassesNames[(proc)->prioClass], (proc)->prioLevel, (proc)->timeSlice);
-
+#define PrintProc(proc) KernLog("{ %d, '%s', %d , %lu}\n", (proc)->pid, \
+ PsPrioClassesNames[(proc)->prioClass], (proc)->prioLevel, (proc)->timeSlice);
//
// Print out process list
//
@@ -352,75 +364,65 @@ void PrintList(ListHead_t *head)
Process_t *proc;
ListNode_t *node = head->first;
- printf("len: %lu\n", head->length);
+ KernLog("len: %lu\n", head->length);
while (node) {
- proc = GetNodeData(node, Process_t *);
+ proc = ExGetNodeData(node, Process_t *);
PrintProc(proc);
node = node->next;
}
- puts("");
+ KernLog("");
}
-int main(void)
+void pstest(void)
{
- InitSched();
+ ClearTerm(StdOut);
- puts("---------------");
+ KernLog("\nTime Critical: ");
+ PrintList(TimeCritProcs);
- puts("Time Critical:");
- PrintList(GetTimeCritProcs());
+ KernLog("\nServer: ");
+ PrintList(ServPrioProcs);
- puts("Server:");
- PrintList(GetServPrioProcs());
+ KernLog("\nRegular: ");
+ PrintList(ReglPrioProcs);
- puts("Regular:");
- PrintList(GetReglPrioProcs());
-
- puts("Idle:");
- PrintList(GetIdlePrioProcs());
-
- puts("---------------");
-
- getchar();
+ KernLog("\nIdle:");
+ PrintList(IdlePrioProcs);
int tick = 0;
- while (tick < 120) {
+ while (tick < 24) {
+ if (tick%25==0)ClearTerm(StdOut);
if (tick > 0 && tick != 50 && tick % 10 == 0) {
- puts("Blocking current process");
- BlockCurProc();
+ KernLog("Blocking current process\n");
+ PsBlockCurProc();
}
if (tick == 50) {
procs[0].procState = STATE_RUNNABLE;
- SchedThisProc(&procs[0]);
+ PsSchedThisProc(&procs[0]);
}
- printf("Tick %d - Running: ", tick);
+ KernLog("Tick %d - Running: ", tick);
- if (GetCurProc() == NULL) {
- puts("IDLE");
+ if (PsCurProc == NULL) {
+ KernLog("IDLE");
}
else {
- PrintProc(GetCurProc());
+ PrintProc(PsCurProc);
}
- SchedOnTick();
+ PsSchedOnTick();
if (tick == 50) // already done
- puts("Re-scheduling process 0");
+ KernLog("Re-scheduling process 0");
tick++;
}
-
- FiniSched();
-
- return 0;
}
-#endif