Skip to content

Commit

Permalink
System calls support
Browse files Browse the repository at this point in the history
  • Loading branch information
djphoenix committed Apr 23, 2017
1 parent 1268717 commit 8383b61
Show file tree
Hide file tree
Showing 5 changed files with 84 additions and 2 deletions.
1 change: 1 addition & 0 deletions src/boot/bootstrap.s
Expand Up @@ -223,6 +223,7 @@ x64_entry:
call _ZN10Interrupts4initEv
call _ZN3SMP4initEv
call _ZN13ModuleManager4initEv
call _ZN7Syscall5setupEv
mov %rsp, %rbp
jmp _ZN14ProcessManager12process_loopEv

Expand Down
25 changes: 25 additions & 0 deletions src/platform/include/syscall.hpp
@@ -0,0 +1,25 @@
// PhoeniX OS System calls subsystem
// Copyright (C) 2013 PhoeniX
//
// This program 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.
//
// This program 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 this program. If not, see <http://www.gnu.org/licenses/>.

#pragma once
#include "kernlib.hpp"

class Syscall {
public:
static void setup();
private:
static void wrapper();
};
2 changes: 2 additions & 0 deletions src/platform/smp.cpp
Expand Up @@ -17,6 +17,7 @@
#include "kernlib.hpp"
#include "acpi.hpp"
#include "processmanager.hpp"
#include "syscall.hpp"

class SMP {
private:
Expand All @@ -31,6 +32,7 @@ Mutex SMP::startupMutex;
void SMP::setup() {
Interrupts::loadVector();
ACPI::getController()->activateCPU();
Syscall::setup();
startupMutex.lock();
startupMutex.release();
}
Expand Down
48 changes: 48 additions & 0 deletions src/platform/syscall.cpp
@@ -0,0 +1,48 @@
// PhoeniX OS System calls subsystem
// Copyright (C) 2013 PhoeniX
//
// This program 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.
//
// This program 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 this program. If not, see <http://www.gnu.org/licenses/>.

#include "syscall.hpp"

static const uint32_t MSR_EFER = 0xC0000080;
static const uint32_t MSR_STAR = 0xC0000081;
static const uint32_t MSR_LSTAR = 0xC0000082;
static const uint64_t MSR_EFER_SCE = 1 << 0;
static const uint16_t KERNEL_CS = 8;
static const uint16_t USER_CS = 24;

static inline void wrmsr(uint32_t msr_id, uint64_t msr_value) {
asm volatile("wrmsr"::"c"(msr_id), "A"(msr_value), "d"(msr_value >> 32));
}

static inline uint64_t rdmsr(uint32_t msr_id) {
uint64_t msr_hi, msr_lo;
asm volatile("rdmsr":"=A"(msr_lo), "=d"(msr_hi):"c"(msr_id));
return (msr_hi << 32) | msr_lo;
}

void __attribute((naked)) Syscall::wrapper() {
asm volatile(
"sysretq;"
);
}

void Syscall::setup() {
wrmsr(MSR_STAR,
((uint64_t)USER_CS) << 48 |
((uint64_t)KERNEL_CS) << 32);
wrmsr(MSR_LSTAR, (uintptr_t)wrapper);
wrmsr(MSR_EFER, rdmsr(MSR_EFER) | MSR_EFER_SCE);
}
10 changes: 8 additions & 2 deletions src/process/process.cpp
Expand Up @@ -150,7 +150,10 @@ uintptr_t Process::linkLibrary(const char* funcname) {
ptr = addSection(SectionTypeCode, 0x100);

// TODO: actual link
uint8_t _stub[] = {0xc3}; // RET
uint8_t _stub[] = {
0x0f, 0x05, // SYSCALL
0xc3 // RET
};
writeData(ptr, _stub, sizeof(_stub));
addSymbol(funcname, ptr);

Expand Down Expand Up @@ -240,10 +243,13 @@ void Process::startup() {
addPage(page, reinterpret_cast<void*>(page), 5);
}
}
uintptr_t handler;
uintptr_t handler, sc_wrapper;
asm volatile("lea __interrupt_wrap(%%rip), %q0":"=r"(handler));
asm volatile("lea _ZN7Syscall7wrapperEv(%%rip), %q0":"=r"(sc_wrapper));
handler &= KB4;
sc_wrapper &= KB4;
addPage(handler, reinterpret_cast<void*>(handler), 5);
addPage(sc_wrapper, reinterpret_cast<void*>(sc_wrapper), 5);
GDT_ENT *gdt_ent = reinterpret_cast<GDT_ENT*>(
(uintptr_t)gdt.addr + 8 * 3);
GDT_ENT *gdt_top = reinterpret_cast<GDT_ENT*>(
Expand Down

0 comments on commit 8383b61

Please sign in to comment.