x64 now compiles again and runs on real hardware.
A nasty bug was fixed that caused triple faults on systems with > 1 GiB RAM.
This commit is contained in:
parent
8c146f14c0
commit
0b1c2a77c9
15 changed files with 517 additions and 16 deletions
|
@ -29,10 +29,15 @@
|
||||||
.type _start, @function
|
.type _start, @function
|
||||||
_start:
|
_start:
|
||||||
|
|
||||||
|
pushq %rsi
|
||||||
|
pushq %rdi
|
||||||
|
|
||||||
call initialize_standard_library
|
call initialize_standard_library
|
||||||
|
|
||||||
|
popq %rdi
|
||||||
|
popq %rsi
|
||||||
|
|
||||||
# Run main
|
# Run main
|
||||||
# TODO: Sortix should set the initial values before this point!
|
|
||||||
call main
|
call main
|
||||||
|
|
||||||
# Terminate the process with main's exit code.
|
# Terminate the process with main's exit code.
|
||||||
|
|
|
@ -37,6 +37,7 @@ ifdef X86FAMILY
|
||||||
$(CPU)/syscall.o \
|
$(CPU)/syscall.o \
|
||||||
$(CPU)/thread.o \
|
$(CPU)/thread.o \
|
||||||
$(CPU)/scheduler.o \
|
$(CPU)/scheduler.o \
|
||||||
|
$(CPU)/process.o \
|
||||||
x86-family/x86-family.o
|
x86-family/x86-family.o
|
||||||
CPUFLAGS:=$(CPUFLAGS) -mno-mmx -mno-sse -mno-sse2 -mno-sse3 -mno-3dnow
|
CPUFLAGS:=$(CPUFLAGS) -mno-mmx -mno-sse -mno-sse2 -mno-sse3 -mno-3dnow
|
||||||
endif
|
endif
|
||||||
|
|
|
@ -214,10 +214,10 @@ namespace Sortix
|
||||||
GDT::Init();
|
GDT::Init();
|
||||||
|
|
||||||
#ifdef PLATFORM_X64
|
#ifdef PLATFORM_X64
|
||||||
Log::Print("Halt: CPU X64 cannot boot because interrupts are not yet "
|
Log::Print("Halt: CPU x64 cannot boot because interrupts are not yet "
|
||||||
"supported under 64-bit Sortix.\n");
|
"supported under 64-bit Sortix.\n");
|
||||||
Log::Print("Sorry, it simply isn't possible to fully boot Sortix in x64 mode yet.\n");
|
Log::Print("Sorry, it simply isn't possible to fully boot Sortix in x64 mode yet.\n");
|
||||||
Log::Print("X64 may be working when Sortix 0.5 comes out, or try the git master.\n");
|
Log::Print("x64 may be working when Sortix 0.6 comes out, or try the git master.\n");
|
||||||
while(true);
|
while(true);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -273,8 +273,6 @@ namespace Sortix
|
||||||
addr_t stackpos = CurrentThread()->stackpos + CurrentThread()->stacksize;
|
addr_t stackpos = CurrentThread()->stackpos + CurrentThread()->stacksize;
|
||||||
addr_t argvpos = stackpos - sizeof(char*) * argc;
|
addr_t argvpos = stackpos - sizeof(char*) * argc;
|
||||||
char** stackargv = (char**) argvpos;
|
char** stackargv = (char**) argvpos;
|
||||||
regs->eax = argc;
|
|
||||||
regs->ebx = argvpos;
|
|
||||||
|
|
||||||
size_t argvsize = 0;
|
size_t argvsize = 0;
|
||||||
for ( int i = 0; i < argc; i++ )
|
for ( int i = 0; i < argc; i++ )
|
||||||
|
@ -288,9 +286,7 @@ namespace Sortix
|
||||||
|
|
||||||
stackpos = argvpos - argvsize;
|
stackpos = argvpos - argvsize;
|
||||||
|
|
||||||
regs->eip = entry;
|
ExecuteCPU(argc, stackargv, stackpos, entry, regs);
|
||||||
regs->useresp = stackpos;
|
|
||||||
regs->ebp = stackpos;
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -101,6 +101,7 @@ namespace Sortix
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Thread* ForkThreads(Process* processclone);
|
Thread* ForkThreads(Process* processclone);
|
||||||
|
void ExecuteCPU(int argc, char** argv, addr_t stackpos, addr_t entry, CPU::InterruptRegisters* regs);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void ResetForExecute();
|
void ResetForExecute();
|
||||||
|
|
|
@ -106,5 +106,42 @@ namespace Sortix
|
||||||
// up, the calling function will fill up the physical allocator with
|
// up, the calling function will fill up the physical allocator with
|
||||||
// plenty of nice physical pages. (see Page::InitPushRegion)
|
// plenty of nice physical pages. (see Page::InitPushRegion)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Please note that even if this function exists, you should still clean
|
||||||
|
// up the address space of a process _before_ calling
|
||||||
|
// DestroyAddressSpace. This is just a hack because it currently is
|
||||||
|
// impossible to clean up PLM1's using the MM api!
|
||||||
|
// ---
|
||||||
|
// TODO: This function is duplicated in {x86,x64}/memorymanagement.cpp!
|
||||||
|
// ---
|
||||||
|
void RecursiveFreeUserspacePages(size_t level, size_t offset)
|
||||||
|
{
|
||||||
|
PML* pml = PMLS[level] + offset;
|
||||||
|
for ( size_t i = 0; i < ENTRIES; i++ )
|
||||||
|
{
|
||||||
|
if ( !(pml->entry[i] & PML_PRESENT) ) { continue; }
|
||||||
|
if ( !(pml->entry[i] & PML_USERSPACE) ) { continue; }
|
||||||
|
if ( !(pml->entry[i] & PML_FORK) ) { continue; }
|
||||||
|
if ( level > 1 ) { RecursiveFreeUserspacePages(level-1, offset * ENTRIES + i); }
|
||||||
|
addr_t addr = pml->entry[i] & PML_ADDRESS;
|
||||||
|
pml->entry[i] = 0;
|
||||||
|
Page::Put(addr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void DestroyAddressSpace()
|
||||||
|
{
|
||||||
|
// First let's do the safe part. Garbage collect any PML1/0's left
|
||||||
|
// behind by user-space. These are completely safe to delete.
|
||||||
|
RecursiveFreeUserspacePages(TOPPMLLEVEL, 0);
|
||||||
|
|
||||||
|
// TODO: Right now this just leaks memory.
|
||||||
|
|
||||||
|
// Switch to the address space from when the world was originally
|
||||||
|
// created. It should contain the kernel, the whole kernel, and
|
||||||
|
// nothing but the kernel.
|
||||||
|
PML* const BOOTPML4 = (PML* const) 0x01000UL;
|
||||||
|
SwitchAddressSpace((addr_t) BOOTPML4);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
38
sortix/x64/process.cpp
Normal file
38
sortix/x64/process.cpp
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
/******************************************************************************
|
||||||
|
|
||||||
|
COPYRIGHT(C) JONAS 'SORTIE' TERMANSEN 2011.
|
||||||
|
|
||||||
|
This file is part of Sortix.
|
||||||
|
|
||||||
|
Sortix 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 (at your option) any later
|
||||||
|
version.
|
||||||
|
|
||||||
|
Sortix 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 Sortix. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
x64/process.cpp
|
||||||
|
CPU-specific process code.
|
||||||
|
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
#include "platform.h"
|
||||||
|
#include "process.h"
|
||||||
|
|
||||||
|
namespace Sortix
|
||||||
|
{
|
||||||
|
void Process::ExecuteCPU(int argc, char** argv, addr_t stackpos, addr_t entry, CPU::InterruptRegisters* regs)
|
||||||
|
{
|
||||||
|
regs->rdi = argc;
|
||||||
|
regs->rsi = (size_t) argv;
|
||||||
|
regs->rip = entry;
|
||||||
|
regs->userrsp = stackpos;
|
||||||
|
regs->rbp = stackpos;
|
||||||
|
}
|
||||||
|
}
|
52
sortix/x64/scheduler.cpp
Normal file
52
sortix/x64/scheduler.cpp
Normal file
|
@ -0,0 +1,52 @@
|
||||||
|
/******************************************************************************
|
||||||
|
|
||||||
|
COPYRIGHT(C) JONAS 'SORTIE' TERMANSEN 2011.
|
||||||
|
|
||||||
|
This file is part of Sortix.
|
||||||
|
|
||||||
|
Sortix 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 (at your option) any later
|
||||||
|
version.
|
||||||
|
|
||||||
|
Sortix 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 Sortix. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
x64/scheduler.cpp
|
||||||
|
CPU specific things related to the scheduler.
|
||||||
|
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
#include "platform.h"
|
||||||
|
#include "scheduler.h"
|
||||||
|
#include "../memorymanagement.h"
|
||||||
|
#include "descriptor_tables.h"
|
||||||
|
|
||||||
|
namespace Sortix
|
||||||
|
{
|
||||||
|
namespace Scheduler
|
||||||
|
{
|
||||||
|
const size_t KERNEL_STACK_SIZE = 256UL * 1024UL;
|
||||||
|
const addr_t KERNEL_STACK_END = 0xFFFF800000001000UL;
|
||||||
|
const addr_t KERNEL_STACK_START = KERNEL_STACK_END + KERNEL_STACK_SIZE;
|
||||||
|
|
||||||
|
void InitCPU()
|
||||||
|
{
|
||||||
|
// TODO: Prevent the kernel heap and other stuff from accidentally
|
||||||
|
// also allocating this virtual memory region!
|
||||||
|
|
||||||
|
if ( !Memory::MapRangeKernel(KERNEL_STACK_END, KERNEL_STACK_SIZE) )
|
||||||
|
{
|
||||||
|
PanicF("could not create kernel stack (%zx to %zx)",
|
||||||
|
KERNEL_STACK_END, KERNEL_STACK_START);
|
||||||
|
}
|
||||||
|
|
||||||
|
GDT::SetKernelStack((size_t*) KERNEL_STACK_START);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
157
sortix/x64/syscall.s
Normal file
157
sortix/x64/syscall.s
Normal file
|
@ -0,0 +1,157 @@
|
||||||
|
/******************************************************************************
|
||||||
|
|
||||||
|
COPYRIGHT(C) JONAS 'SORTIE' TERMANSEN 2011.
|
||||||
|
|
||||||
|
This file is part of Sortix.
|
||||||
|
|
||||||
|
Sortix 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 (at your option) any later
|
||||||
|
version.
|
||||||
|
|
||||||
|
Sortix 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 Sortix. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
syscall.s
|
||||||
|
An assembly stub that acts as glue for system calls.
|
||||||
|
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
.global syscall_handler
|
||||||
|
.global resume_syscall
|
||||||
|
|
||||||
|
.section .text
|
||||||
|
.type syscall_handler, @function
|
||||||
|
syscall_handler:
|
||||||
|
cli
|
||||||
|
|
||||||
|
# Compabillity with InterruptRegisters.
|
||||||
|
pushq $0x0
|
||||||
|
pushq $0x80
|
||||||
|
|
||||||
|
pushq %r15
|
||||||
|
pushq %r14
|
||||||
|
pushq %r13
|
||||||
|
pushq %r12
|
||||||
|
pushq %r11
|
||||||
|
pushq %r10
|
||||||
|
pushq %r9
|
||||||
|
pushq %r8
|
||||||
|
pushq %rax
|
||||||
|
pushq %rcx
|
||||||
|
pushq %rdx
|
||||||
|
pushq %rbx
|
||||||
|
pushq %rsp
|
||||||
|
pushq %rsi
|
||||||
|
pushq %rdi
|
||||||
|
|
||||||
|
# Push the user-space data segment.
|
||||||
|
movl %ds, %ebp
|
||||||
|
pushq %rbp
|
||||||
|
|
||||||
|
# Load the kernel data segment.
|
||||||
|
movw $0x10, %bp
|
||||||
|
movl %ebp, %ds
|
||||||
|
movl %ebp, %es
|
||||||
|
movl %ebp, %fs
|
||||||
|
movl %ebp, %gs
|
||||||
|
|
||||||
|
# Compabillity with InterruptRegisters.
|
||||||
|
movq %cr2, %rbp
|
||||||
|
pushq %rbp
|
||||||
|
|
||||||
|
# Store the state structure's pointer so the call can modify it if needed.
|
||||||
|
movq %rsp, syscall_state_ptr
|
||||||
|
|
||||||
|
# By default, assume the system call was complete.
|
||||||
|
movl $0, system_was_incomplete
|
||||||
|
|
||||||
|
# Reset the kernel errno.
|
||||||
|
movl $0, errno
|
||||||
|
|
||||||
|
# Make sure the requested system call is valid.
|
||||||
|
cmp SYSCALL_MAX, %rax
|
||||||
|
jb valid_rax
|
||||||
|
xorq %rax, %rax
|
||||||
|
|
||||||
|
valid_rax:
|
||||||
|
# Read a system call function pointer.
|
||||||
|
xorq %rbp, %rbp
|
||||||
|
movq syscall_list(%rbp,%rax,4), %rax
|
||||||
|
|
||||||
|
# Oh how nice, user-space put the parameters in: rdi, rsi, rdx, rcx, r8, r9
|
||||||
|
|
||||||
|
# Call the system call.
|
||||||
|
callq *%rax
|
||||||
|
|
||||||
|
# Test if the system call was incomplete
|
||||||
|
movl system_was_incomplete, %ebx
|
||||||
|
testl %ebx, %ebx
|
||||||
|
|
||||||
|
# If the system call was incomplete, the value in %eax is meaningless.
|
||||||
|
jg return_to_userspace
|
||||||
|
|
||||||
|
# The system call was completed, so store the return value.
|
||||||
|
movq %rax, 72(%rsp)
|
||||||
|
|
||||||
|
# Don't forget to update userspace's errno value.
|
||||||
|
call update_userspace_errno
|
||||||
|
|
||||||
|
return_to_userspace:
|
||||||
|
# Compabillity with InterruptRegisters.
|
||||||
|
addq $8, %rsp
|
||||||
|
|
||||||
|
# Restore the user-space data segment.
|
||||||
|
popq %rbp
|
||||||
|
movl %ebp, %ds
|
||||||
|
movl %ebp, %es
|
||||||
|
movl %ebp, %fs
|
||||||
|
movl %ebp, %gs
|
||||||
|
|
||||||
|
popq %rdi
|
||||||
|
popq %rsi
|
||||||
|
popq %rsp
|
||||||
|
popq %rbx
|
||||||
|
popq %rdx
|
||||||
|
popq %rcx
|
||||||
|
popq %rax
|
||||||
|
popq %r8
|
||||||
|
popq %r9
|
||||||
|
popq %r10
|
||||||
|
popq %r11
|
||||||
|
popq %r12
|
||||||
|
popq %r13
|
||||||
|
popq %r14
|
||||||
|
popq %r15
|
||||||
|
|
||||||
|
# Compabillity with InterruptRegisters.
|
||||||
|
addq $16, %rsp
|
||||||
|
|
||||||
|
# Return to user-space.
|
||||||
|
iretq
|
||||||
|
|
||||||
|
.type resume_syscall, @function
|
||||||
|
resume_syscall:
|
||||||
|
pushq %rbp
|
||||||
|
movq %rsp, %rbp
|
||||||
|
|
||||||
|
movq %rdi, %rax
|
||||||
|
movq %rsi, %r11
|
||||||
|
|
||||||
|
movq 0(%r11), %rdi
|
||||||
|
movq 8(%r11), %rsi
|
||||||
|
movq 16(%r11), %rdx
|
||||||
|
movq 24(%r11), %rcx
|
||||||
|
movq 32(%r11), %r8
|
||||||
|
movq 40(%r11), %r9
|
||||||
|
|
||||||
|
callq *%rax
|
||||||
|
|
||||||
|
leaveq
|
||||||
|
retq
|
||||||
|
|
139
sortix/x64/thread.cpp
Normal file
139
sortix/x64/thread.cpp
Normal file
|
@ -0,0 +1,139 @@
|
||||||
|
/******************************************************************************
|
||||||
|
|
||||||
|
COPYRIGHT(C) JONAS 'SORTIE' TERMANSEN 2011.
|
||||||
|
|
||||||
|
This file is part of Sortix.
|
||||||
|
|
||||||
|
Sortix 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 (at your option) any later
|
||||||
|
version.
|
||||||
|
|
||||||
|
Sortix 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 Sortix. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
thread.cpp
|
||||||
|
x64 specific parts of thread.cpp.
|
||||||
|
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
#include "platform.h"
|
||||||
|
#include "thread.h"
|
||||||
|
|
||||||
|
namespace Sortix
|
||||||
|
{
|
||||||
|
void Thread::SaveRegisters(const CPU::InterruptRegisters* src)
|
||||||
|
{
|
||||||
|
registers.rip = src->rip;
|
||||||
|
registers.userrsp = src->userrsp;
|
||||||
|
registers.rax = src->rax;
|
||||||
|
registers.rbx = src->rbx;
|
||||||
|
registers.rcx = src->rcx;
|
||||||
|
registers.rdx = src->rdx;
|
||||||
|
registers.rdi = src->rdi;
|
||||||
|
registers.rsi = src->rsi;
|
||||||
|
registers.rbp = src->rbp;
|
||||||
|
registers.r8 = src->r8;
|
||||||
|
registers.r9 = src->r9;
|
||||||
|
registers.r10 = src->r10;
|
||||||
|
registers.r11 = src->r11;
|
||||||
|
registers.r12 = src->r12;
|
||||||
|
registers.r13 = src->r13;
|
||||||
|
registers.r14 = src->r14;
|
||||||
|
registers.r15 = src->r15;
|
||||||
|
registers.cs = src->cs;
|
||||||
|
registers.ds = src->ds;
|
||||||
|
registers.ss = src->ss;
|
||||||
|
registers.rflags = src->rflags;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Thread::LoadRegisters(CPU::InterruptRegisters* dest)
|
||||||
|
{
|
||||||
|
dest->rip = registers.rip;
|
||||||
|
dest->userrsp = registers.userrsp;
|
||||||
|
dest->rax = registers.rax;
|
||||||
|
dest->rbx = registers.rbx;
|
||||||
|
dest->rcx = registers.rcx;
|
||||||
|
dest->rdx = registers.rdx;
|
||||||
|
dest->rdi = registers.rdi;
|
||||||
|
dest->rsi = registers.rsi;
|
||||||
|
dest->rbp = registers.rbp;
|
||||||
|
dest->r8 = registers.r8;
|
||||||
|
dest->r9 = registers.r9;
|
||||||
|
dest->r10 = registers.r10;
|
||||||
|
dest->r11 = registers.r11;
|
||||||
|
dest->r12 = registers.r12;
|
||||||
|
dest->r13 = registers.r13;
|
||||||
|
dest->r14 = registers.r14;
|
||||||
|
dest->r15 = registers.r15;
|
||||||
|
dest->cs = registers.cs;
|
||||||
|
dest->ds = registers.ds;
|
||||||
|
dest->ss = registers.ss;
|
||||||
|
dest->rflags = registers.rflags;
|
||||||
|
}
|
||||||
|
|
||||||
|
const size_t FLAGS_CARRY = (1<<0);
|
||||||
|
const size_t FLAGS_RESERVED1 = (1<<1); /* read as one */
|
||||||
|
const size_t FLAGS_PARITY = (1<<2);
|
||||||
|
const size_t FLAGS_RESERVED2 = (1<<3);
|
||||||
|
const size_t FLAGS_AUX = (1<<4);
|
||||||
|
const size_t FLAGS_RESERVED3 = (1<<5);
|
||||||
|
const size_t FLAGS_ZERO = (1<<6);
|
||||||
|
const size_t FLAGS_SIGN = (1<<7);
|
||||||
|
const size_t FLAGS_TRAP = (1<<8);
|
||||||
|
const size_t FLAGS_INTERRUPT = (1<<9);
|
||||||
|
const size_t FLAGS_DIRECTION = (1<<10);
|
||||||
|
const size_t FLAGS_OVERFLOW = (1<<11);
|
||||||
|
const size_t FLAGS_IOPRIVLEVEL = (1<<12) | (1<<13);
|
||||||
|
const size_t FLAGS_NESTEDTASK = (1<<14);
|
||||||
|
const size_t FLAGS_RESERVED4 = (1<<15);
|
||||||
|
const size_t FLAGS_RESUME = (1<<16);
|
||||||
|
const size_t FLAGS_VIRTUAL8086 = (1<<17);
|
||||||
|
const size_t FLAGS_ALIGNCHECK = (1<<18);
|
||||||
|
const size_t FLAGS_VIRTINTR = (1<<19);
|
||||||
|
const size_t FLAGS_VIRTINTRPEND = (1<<20);
|
||||||
|
const size_t FLAGS_ID = (1<<21);
|
||||||
|
|
||||||
|
void CreateThreadCPU(Thread* thread, addr_t entry)
|
||||||
|
{
|
||||||
|
const uint64_t CS = 0x18;
|
||||||
|
const uint64_t DS = 0x20;
|
||||||
|
const uint64_t RPL = 0x3;
|
||||||
|
|
||||||
|
CPU::InterruptRegisters regs;
|
||||||
|
regs.rip = entry;
|
||||||
|
regs.userrsp = thread->stackpos + thread->stacksize;
|
||||||
|
regs.rax = 0;
|
||||||
|
regs.rbx = 0;
|
||||||
|
regs.rcx = 0;
|
||||||
|
regs.rdx = 0;
|
||||||
|
regs.rdi = 0;
|
||||||
|
regs.rsi = 0;
|
||||||
|
regs.rbp = thread->stackpos + thread->stacksize;
|
||||||
|
regs.r8 = 0;
|
||||||
|
regs.r9 = 0;
|
||||||
|
regs.r10 = 0;
|
||||||
|
regs.r11 = 0;
|
||||||
|
regs.r12 = 0;
|
||||||
|
regs.r13 = 0;
|
||||||
|
regs.r14 = 0;
|
||||||
|
regs.r15 = 0;
|
||||||
|
regs.cs = CS | RPL;
|
||||||
|
regs.ds = DS | RPL;
|
||||||
|
regs.ss = DS | RPL;
|
||||||
|
regs.rflags = FLAGS_RESERVED1 | FLAGS_INTERRUPT | FLAGS_ID;
|
||||||
|
|
||||||
|
thread->SaveRegisters(®s);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Thread::HandleSignalCPU(CPU::InterruptRegisters* regs)
|
||||||
|
{
|
||||||
|
regs->rdi = currentsignal->signum;
|
||||||
|
regs->rip = (size_t) sighandler;
|
||||||
|
}
|
||||||
|
}
|
|
@ -24,10 +24,26 @@
|
||||||
|
|
||||||
#include <libmaxsi/platform.h>
|
#include <libmaxsi/platform.h>
|
||||||
#include "x64.h"
|
#include "x64.h"
|
||||||
|
#include "log.h"
|
||||||
|
|
||||||
namespace Sortix
|
namespace Sortix
|
||||||
{
|
{
|
||||||
namespace X64
|
namespace X64
|
||||||
{
|
{
|
||||||
|
void InterruptRegisters::LogRegisters() const
|
||||||
|
{
|
||||||
|
Log::PrintF("[cr2=0x%zx,ds=0x%zx,rdi=0x%zx,rsi=0x%zx,rbp=0x%zx,"
|
||||||
|
"rsp=0x%zx,rbx=0x%zx,rcx=0x%zx,rax=0x%zx,r8=0x%zx,"
|
||||||
|
"r9=0x%zx,r10=0x%zx,r11=0x%zx,r12=0x%zx,r13=0x%zx,"
|
||||||
|
"r14=0x%zx,r15=0x%zx,int_no=0x%zx,err_code=0x%zx,"
|
||||||
|
"rip=0x%zx,cs=0x%zx,rflags=0x%zx,userrsp=0x%zx,"
|
||||||
|
"ss=0x%zx]",
|
||||||
|
cr2, ds, rdi, rsi, rbp,
|
||||||
|
rsp, rbx, rcx, rax, r8,
|
||||||
|
r9, r10, r11, r12, r13,
|
||||||
|
r14, r15, int_no, err_code,
|
||||||
|
rip, cs, rflags, userrsp,
|
||||||
|
ss);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,10 +35,23 @@ namespace Sortix
|
||||||
{
|
{
|
||||||
uint64_t cr2;
|
uint64_t cr2;
|
||||||
uint64_t ds; // Data segment selector
|
uint64_t ds; // Data segment selector
|
||||||
uint64_t rdi, rsi, rbp, rsp, rbx, rdx, rcx, rax; // Pushed by pusha.
|
uint64_t rdi, rsi, rbp, rsp, rbx, rdx, rcx, rax;
|
||||||
uint64_t r8, r9, r10, r11, r12, r13, r14, r15; // Pushed by pusha.
|
uint64_t r8, r9, r10, r11, r12, r13, r14, r15;
|
||||||
uint64_t int_no, err_code; // Interrupt number and error code (if applicable)
|
uint64_t int_no, err_code; // Interrupt number and error code (if applicable)
|
||||||
uint64_t eip, cs, eflags, useresp, ss; // Pushed by the processor automatically.
|
uint64_t rip, cs, rflags, userrsp, ss; // Pushed by the processor automatically.
|
||||||
|
|
||||||
|
public:
|
||||||
|
void LogRegisters() const;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct SyscallRegisters
|
||||||
|
{
|
||||||
|
uint64_t cr2; // For compabillity with above, may be removed soon.
|
||||||
|
uint64_t ds;
|
||||||
|
uint64_t di, si, bp, trash, b, d, c; union { uint64_t a; uint64_t result; };
|
||||||
|
uint64_t r8, r9, r10, r11, r12, r13, r14, r15;
|
||||||
|
uint64_t int_no, err_code; // Also compabillity.
|
||||||
|
uint64_t ip, cs, flags, sp, ss;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -115,7 +115,7 @@ namespace Sortix
|
||||||
// until the pebibyte era of RAM.
|
// until the pebibyte era of RAM.
|
||||||
if ( 0 < Page::pagesnotonstack )
|
if ( 0 < Page::pagesnotonstack )
|
||||||
{
|
{
|
||||||
Log::PrintF("%zu bytes of RAM aren't used due to technical"
|
Log::PrintF("%zu bytes of RAM aren't used due to technical "
|
||||||
"restrictions.\n", Page::pagesnotonstack * 0x1000UL);
|
"restrictions.\n", Page::pagesnotonstack * 0x1000UL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -178,7 +178,10 @@ namespace Sortix
|
||||||
|
|
||||||
// This call will also succeed, since there are plenty of physical
|
// This call will also succeed, since there are plenty of physical
|
||||||
// pages available and it might need some.
|
// pages available and it might need some.
|
||||||
Memory::MapKernel(page, (addr_t) (STACK + stacklength));
|
if ( !Memory::MapKernel(page, (addr_t) (STACK + stacklength)) )
|
||||||
|
{
|
||||||
|
Panic("Unable to extend page stack, which should have worked");
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: This may not be needed during the boot process!
|
// TODO: This may not be needed during the boot process!
|
||||||
//Memory::InvalidatePage((addr_t) (STACK + stacklength));
|
//Memory::InvalidatePage((addr_t) (STACK + stacklength));
|
||||||
|
@ -345,6 +348,9 @@ namespace Sortix
|
||||||
|
|
||||||
addr_t& entry = pml->entry[childid];
|
addr_t& entry = pml->entry[childid];
|
||||||
|
|
||||||
|
// Find the index of the next PML in the fractal mapped memory.
|
||||||
|
size_t childoffset = offset * ENTRIES + childid;
|
||||||
|
|
||||||
if ( !(entry & PML_PRESENT) )
|
if ( !(entry & PML_PRESENT) )
|
||||||
{
|
{
|
||||||
// TODO: Possible memory leak when page allocation fails.
|
// TODO: Possible memory leak when page allocation fails.
|
||||||
|
@ -353,7 +359,7 @@ namespace Sortix
|
||||||
entry = page | flags;
|
entry = page | flags;
|
||||||
|
|
||||||
// Invalidate the new PML and reset it to zeroes.
|
// Invalidate the new PML and reset it to zeroes.
|
||||||
addr_t pmladdr = (addr_t) (PMLS[i-1] + childid);
|
addr_t pmladdr = (addr_t) (PMLS[i-1] + childoffset);
|
||||||
InvalidatePage(pmladdr);
|
InvalidatePage(pmladdr);
|
||||||
Maxsi::Memory::Set((void*) pmladdr, 0, sizeof(PML));
|
Maxsi::Memory::Set((void*) pmladdr, 0, sizeof(PML));
|
||||||
}
|
}
|
||||||
|
@ -365,8 +371,7 @@ namespace Sortix
|
||||||
"code calling this function", physical, mapto, i-1);
|
"code calling this function", physical, mapto, i-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Find the index of the next PML in the fractal mapped memory.
|
offset = childoffset;
|
||||||
offset = offset * ENTRIES + childid;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Actually map the physical page to the virtual page.
|
// Actually map the physical page to the virtual page.
|
||||||
|
|
|
@ -106,6 +106,9 @@ namespace Sortix
|
||||||
// up the address space of a process _before_ calling
|
// up the address space of a process _before_ calling
|
||||||
// DestroyAddressSpace. This is just a hack because it currently is
|
// DestroyAddressSpace. This is just a hack because it currently is
|
||||||
// impossible to clean up PLM1's using the MM api!
|
// impossible to clean up PLM1's using the MM api!
|
||||||
|
// ---
|
||||||
|
// TODO: This function is duplicated in {x86,x64}/memorymanagement.cpp!
|
||||||
|
// ---
|
||||||
void RecursiveFreeUserspacePages(size_t level, size_t offset)
|
void RecursiveFreeUserspacePages(size_t level, size_t offset)
|
||||||
{
|
{
|
||||||
PML* pml = PMLS[level] + offset;
|
PML* pml = PMLS[level] + offset;
|
||||||
|
|
38
sortix/x86/process.cpp
Normal file
38
sortix/x86/process.cpp
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
/******************************************************************************
|
||||||
|
|
||||||
|
COPYRIGHT(C) JONAS 'SORTIE' TERMANSEN 2011.
|
||||||
|
|
||||||
|
This file is part of Sortix.
|
||||||
|
|
||||||
|
Sortix 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 (at your option) any later
|
||||||
|
version.
|
||||||
|
|
||||||
|
Sortix 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 Sortix. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
x86/process.cpp
|
||||||
|
CPU-specific process code.
|
||||||
|
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
#include "platform.h"
|
||||||
|
#include "process.h"
|
||||||
|
|
||||||
|
namespace Sortix
|
||||||
|
{
|
||||||
|
void Process::ExecuteCPU(int argc, char** argv, addr_t stackpos, addr_t entry, CPU::InterruptRegisters* regs)
|
||||||
|
{
|
||||||
|
regs->eax = argc;
|
||||||
|
regs->ebx = (size_t) argv;
|
||||||
|
regs->eip = entry;
|
||||||
|
regs->useresp = stackpos;
|
||||||
|
regs->ebp = stackpos;
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue