MAX_CPUS := 4
-CPPFLAGS := -DMAX_CPUS=$(MAX_CPUS)
+CPPFLAGS := -DMAX_CPUS=$(MAX_CPUS) -D USE_MP=0
CFLAGS := $(KERNEL_CFLAGS) -mno-sse -mno-mmx
-ASFLAGS := -f elf64 -D MAX_CPUS=$(MAX_CPUS)
+ASFLAGS := -f elf64 -D MAX_CPUS=$(MAX_CPUS) -D USE_MP=0
LDFLAGS := -nostdlib -nodefaultlibs
ifeq ($(ARCH),amd64)
%endrep
; Install IRQs
- SETIDT 0xF0, Irq0
+ SETIDT 0xF0, SchedulerIRQ
SETIDT 0xF1, Irq1
SETIDT 0xF2, Irq2
SETIDT 0xF3, Irq3
[extern Proc_Scheduler]
[global SchedulerIRQ]
SchedulerIRQ:
- ; TODO: Find Current CPU
PUSH_GPR
;PUSH_FPU
;PUSH_XMM
- xor rsi, rsi
- mov rdi, MM_LOCALAPIC+0x20
- mov esi, [rdi]
+ ; Save Thread Pointer
+ mov rax, dr0
+ push rax
+
+ ; Get the CPU Number
+ mov rdi, dr1
+ ; Call the Scheduler
call Proc_Scheduler
+ ; Restore Thread Pointer
+ pop rax
+ mov dr0, rax
+
+ ; Send EOI (To either the APIC or the PIC)
+ %if USE_MP
+ test ebx, ebx
+ jnz .sendEOI
+ %endif
+ ; PIC
+ mov al, 0x20
+ out 0x20, al ; ACK IRQ
+ %if USE_MP
+ jmp .ret
+ ; APIC
+.sendEOI:
+ mov eax, DWORD [gpMP_LocalAPIC]
+ mov DWORD [eax+0x0B0], 0
+ %endif
+.ret:
+
;POP_XMM
;POP_FPU
POP_GPR
- add rsp, 8*2
iretq
[section .data]
}
#endif
+ // Set Debug registers
+ __asm__ __volatile__ ("mov %0, %%db0" : : "r"(&gThreadZero));
+ __asm__ __volatile__ ("mov %%rax, %%db1" : : "a"(0));
+
gaCPUs[0].Current = &gThreadZero;
gThreadZero.MemState.CR3 = (Uint)gInitialPML4 - KERNEL_BASE;
+ gThreadZero.CurCPU = 0;
// Set timer frequency
outb(0x43, 0x34); // Set Channel 0, Low/High, Rate Generator
// Change Stacks
Proc_ChangeStack();
+
+ Log("Multithreading initialised");
}
#if USE_MP
// Set current task
gaCPUs[0].Current = &gThreadZero;
+ gaCPUs[0].Current->CurCPU = 0;
// Start Interrupts (and hence scheduler)
__asm__ __volatile__("sti");
#endif
MM_FinishVirtualInit();
+ Log("Multithreading started");
}
/**
// If the spinlock is set, let it complete
if(IS_LOCKED(&glThreadListLock)) return;
-
+
// Get current thread
thread = gaCPUs[CPU].Current;
jmp rax
.himem:
+ xor rax, rax
+ mov dr0, rax ; Set CPU0
+
; Clear the screen
mov rax, 0x1F201F201F201F20 ; Set the screen to White on blue, space (4 characters)
mov edi, 0xB8000
typedef struct sThread
{
// --- threads.c's
- // 0
struct sThread *Next; //!< Next thread in list
tSpinlock IsLocked; //!< Thread's spinlock
volatile int Status; //!< Thread Status
int RetStatus; //!< Return Status
- // 16
Uint TID; //!< Thread ID
Uint TGID; //!< Thread Group (Process)
Uint PTID; //!< Parent Thread ID
char *ThreadName; //!< Name of thread
// --- arch/proc.c's responsibility
- // 40
//! Kernel Stack Base
tVAddr KernelStack;
- // 44 (x86)
//! Memory Manager State
tMemoryState MemState;
- // 48 (x86)
//! State on task switch
tTaskState SavedState;
// --- threads.c's
- // 60
int CurFaultNum; //!< Current fault number, 0: none
tVAddr FaultHandler; //!< Fault Handler
Uint Config[NUM_CFG_ENTRIES]; //!< Per-process configuration
- // --- proc.c's
volatile int CurCPU;
} tThread;
{
case 'd':
case 'i':
- #if BITS == 32
- if( (isLongLong && val >> 63) || (!isLongLong && val >> 31) ) {
- #else
- if( (Sint)val < 0 ) {
- #endif
+ if( isLongLong && val >> 63 ) {
PUTCH('-');
val = -val;
}
+ else if( !isLongLong && val >> 31 ) {
+ PUTCH('-');
+ val = -(Sint32)val;
+ }
itoa(p, val, 10, minSize, pad);
goto printString;
case 'u':
// === GLOBALS ===
tVFS_Driver gRootFS_Info = {
- "rootfs", 0,
- Root_InitDevice,
- NULL, // Unmount
- NULL
-};
+ "rootfs", 0, Root_InitDevice, NULL, NULL
+ };
tRamFS_File RootFS_Files[MAX_FILES];
tVFS_ACL RootFS_DirACLs[3] = {
{{0,0}, {0,VFS_PERM_ALL}}, // Owner (Root)
for(;drv;drv=drv->Next)
{
+ Log("strcmp('%s' (%p), '%s') == 0?", drv->Name, drv->Name, Name);
if(strcmp(drv->Name, Name) == 0)
return drv;
}