Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion 3rdparty/musl
1 change: 1 addition & 0 deletions Makefile.user
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ CPPFLAGS+= -DMLOG_PORTAL=FilterError
CPPFLAGS+= -DMLOG_SCHED=FilterError
CPPFLAGS+= -DMLOG_SYSCALL=FilterError
CPPFLAGS+= -DMLOG_TASKLET=FilterError
CPPFLAGS+= -DMLOG_PROCESSORMGMT=FilterWarning
#CPPFLAGS+= -DTRACE
#CPPFLAGS+= -DNDEBUG

Expand Down
1 change: 1 addition & 0 deletions kernel-amd64.config
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
"plugin-rapl-driver-intel",
"app-init-example",
"test-synchronous-task",
"plugin-processor-allocator"
]

[config.vars]
Expand Down
63 changes: 53 additions & 10 deletions kernel/app/init-example/app/init.cc
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
#include "mythos/invocation.hh"
#include "mythos/protocol/CpuDriverKNC.hh"
#include "mythos/PciMsgQueueMPSC.hh"
#include "mythos/InfoFrame.hh"
#include "runtime/Portal.hh"
#include "runtime/ExecutionContext.hh"
#include "runtime/CapMap.hh"
Expand All @@ -36,6 +37,7 @@
#include "runtime/PageMap.hh"
#include "runtime/KernelMemory.hh"
#include "runtime/SimpleCapAlloc.hh"
#include "runtime/ProcessorAllocator.hh"
#include "runtime/tls.hh"
#include "runtime/mlog.hh"
#include "runtime/InterruptControl.hh"
Expand All @@ -56,7 +58,7 @@
#include <sys/time.h>


mythos::InvocationBuf* msg_ptr asm("msg_ptr");
mythos::InfoFrame* info_ptr asm("info_ptr");
int main() asm("main");

extern char process_test_image_start SYMBOL("process_test_image_start");
Expand All @@ -65,14 +67,15 @@ constexpr uint64_t stacksize = 4*4096;
char initstack[stacksize];
char* initstack_top = initstack+stacksize;

mythos::Portal portal(mythos::init::PORTAL, msg_ptr);
mythos::Portal portal(mythos::init::PORTAL, info_ptr->getInvocationBuf());
mythos::CapMap myCS(mythos::init::CSPACE);
mythos::PageMap myAS(mythos::init::PML4);
mythos::KernelMemory kmem(mythos::init::KM);
mythos::KObject device_memory(mythos::init::DEVICE_MEM);
mythos::SimpleCapAlloc< mythos::init::APP_CAP_START
, mythos::init::SIZE-mythos::init::APP_CAP_START> capAlloc(myCS);
mythos::RaplDriverIntel rapl(mythos::init::RAPL_DRIVER_INTEL);
mythos::ProcessorAllocator pa(mythos::init::PROCESSOR_ALLOCATOR);

char threadstack[stacksize];
char* thread1stack_top = threadstack+stacksize/2;
Expand Down Expand Up @@ -103,7 +106,7 @@ void test_Portal()
MLOG_ERROR(mlog::app, "test_Portal begin");
mythos::PortalLock pl(portal); // future access will fail if the portal is in use already
MLOG_INFO(mlog::app, "test_Portal: allocate portal");
uintptr_t vaddr = mythos::round_up(uintptr_t(msg_ptr) + 1, mythos::align2M);
uintptr_t vaddr = mythos::round_up(info_ptr->getInfoEnd(), mythos::align2M);
// allocate a portal
mythos::Portal p2(capAlloc(), (void*)vaddr);
auto res1 = p2.create(pl, kmem).wait();
Expand Down Expand Up @@ -185,14 +188,17 @@ void test_tls()
auto tls = mythos::setupNewTLS();
MLOG_INFO(mlog::app, "test_EC: create ec1 TLS", DVARhex(tls));
ASSERT(tls != nullptr);
auto res1 = ec1.create(kmem).as(myAS).cs(myCS).sched(mythos::init::SCHEDULERS_START + 1)
auto sc = pa.alloc(pl).wait();
TEST(sc);
auto res1 = ec1.create(kmem).as(myAS).cs(myCS).sched(sc->cap)
.prepareStack(thread1stack_top).startFun(threadFun, nullptr)
.suspended(false).fs(tls)
.invokeVia(pl).wait();
TEST(res1);
TEST(ec1.setFSGS(pl,(uint64_t) tls, 0).wait());
mythos::syscall_signal(ec1.cap());
MLOG_INFO(mlog::app, "End test tls");
capAlloc.free(ec1.cap(), pl);
}


Expand All @@ -201,7 +207,7 @@ void test_heap() {
mythos::PortalLock pl(portal);
auto size = 4*1024*1024; // 2 MB
auto align = 2*1024*1024; // 2 MB
uintptr_t vaddr = mythos::round_up(uintptr_t(msg_ptr) + 1, align);
uintptr_t vaddr = mythos::round_up(info_ptr->getInfoEnd() + align2M, align2M);
// allocate a 2MiB frame
mythos::Frame f(capAlloc());
auto res2 = f.create(pl, kmem, size, align).wait();
Expand Down Expand Up @@ -322,7 +328,9 @@ void test_ExecutionContext()

auto tls1 = mythos::setupNewTLS();
ASSERT(tls1 != nullptr);
auto res1 = ec1.create(kmem).as(myAS).cs(myCS).sched(mythos::init::SCHEDULERS_START)
auto sc1 = pa.alloc(pl).wait();
TEST(sc1);
auto res1 = ec1.create(kmem).as(myAS).cs(myCS).sched(sc1->cap)
.prepareStack(thread1stack_top).startFun(&thread_main, nullptr)
.suspended(false).fs(tls1)
.invokeVia(pl).wait();
Expand All @@ -331,7 +339,9 @@ void test_ExecutionContext()
MLOG_INFO(mlog::app, "test_EC: create ec2");
auto tls2 = mythos::setupNewTLS();
ASSERT(tls2 != nullptr);
auto res2 = ec2.create(kmem).as(myAS).cs(myCS).sched(mythos::init::SCHEDULERS_START+1)
auto sc2 = pa.alloc(pl).wait();
TEST(sc2);
auto res2 = ec2.create(kmem).as(myAS).cs(myCS).sched(sc2->cap)
.prepareStack(thread2stack_top).startFun(&thread_main, nullptr)
.suspended(false).fs(tls2)
.invokeVia(pl).wait();
Expand All @@ -345,6 +355,11 @@ void test_ExecutionContext()
MLOG_INFO(mlog::app, "sending notifications");
mythos::syscall_signal(ec1.cap());
mythos::syscall_signal(ec2.cap());
{
mythos::PortalLock pl(portal);
TEST(capAlloc.free(ec1, pl));
TEST(capAlloc.free(ec2, pl));
}
MLOG_INFO(mlog::app, "End Test ExecutionContext");
}

Expand All @@ -357,7 +372,9 @@ void test_InterruptControl() {
mythos::ExecutionContext ec(capAlloc());
auto tls = mythos::setupNewTLS();
ASSERT(tls != nullptr);
auto res1 = ec.create(kmem).as(myAS).cs(myCS).sched(mythos::init::SCHEDULERS_START + 2)
auto sc = pa.alloc(pl).wait();
TEST(sc);
auto res1 = ec.create(kmem).as(myAS).cs(myCS).sched(sc->cap)
.prepareStack(thread3stack_top).startFun(&thread_main, nullptr)
.suspended(false).fs(tls)
.invokeVia(pl).wait();
Expand Down Expand Up @@ -480,21 +497,45 @@ void test_CgaScreen(){
MLOG_INFO(mlog::app, "Test CGA finished");
}

void test_processor_allocator(){
MLOG_INFO(mlog::app, "Test processor allocator");
mythos::PortalLock pl(portal);
auto sc = pa.alloc(pl).wait();
TEST(sc);
auto res = pa.free(pl, sc->cap).wait();
TEST(res);
MLOG_INFO(mlog::app, "Test processor allocator finished");
}

void test_process(){
MLOG_INFO(mlog::app, "Test process");

mythos::PortalLock pl(portal);

Process p(&process_test_image_start);
p.createProcess(pl);

MLOG_INFO(mlog::app, "Test process finished");
}

void test_userMem(){
MLOG_INFO(mlog::app, "Test user memory");
auto ranges = &info_ptr->memRanges;

// All memory that exceeds kernel memory address range (4G) will be provided directly to user.
// Run mythos (qemu/IHK) with more than 4G of memory to get some output
for(auto& r : *ranges){
MLOG_INFO(mlog::app, "range", DMRANGE(r.getStart(), r.getSize()));
}

MLOG_INFO(mlog::app, "Test user memory finished");
};

int main()
{
char const str[] = "Hello world!";
mythos::syscall_debug(str, sizeof(str)-1);
MLOG_ERROR(mlog::app, "application is starting :)", DVARhex(msg_ptr), DVARhex(initstack_top));
MLOG_ERROR(mlog::app, "application is starting :)", DVARhex(info_ptr), DVARhex(initstack_top));

test_float();
test_Example();
Expand All @@ -506,7 +547,9 @@ int main()
//test_HostChannel(portal, 24*1024*1024, 2*1024*1024);
test_ExecutionContext();
test_pthreads();
//test_Rapl();
test_userMem();
test_Rapl();
test_processor_allocator();
test_process();
//test_CgaScreen();

Expand Down
8 changes: 6 additions & 2 deletions kernel/app/process_test/process_test/process_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@

#include "mythos/init.hh"
#include "mythos/invocation.hh"
#include "mythos/InfoFrame.hh"
#include "runtime/Portal.hh"
#include "runtime/ExecutionContext.hh"
#include "runtime/CapMap.hh"
Expand All @@ -34,6 +35,7 @@
#include "runtime/PageMap.hh"
#include "runtime/KernelMemory.hh"
#include "runtime/SimpleCapAlloc.hh"
#include "runtime/ProcessorAllocator.hh"
#include "runtime/tls.hh"
#include "runtime/mlog.hh"
#include "runtime/InterruptControl.hh"
Expand All @@ -43,26 +45,28 @@
#include "runtime/Mutex.hh"


mythos::InvocationBuf* msg_ptr asm("msg_ptr");
mythos::InfoFrame* info_ptr asm("info_ptr");
int main() asm("main");

constexpr uint64_t stacksize = 4*4096;
char initstack[stacksize];
char* initstack_top = initstack+stacksize;

mythos::Portal portal(mythos::init::PORTAL, msg_ptr);
mythos::Portal portal(mythos::init::PORTAL, info_ptr->getInvocationBuf());
mythos::CapMap myCS(mythos::init::CSPACE);
mythos::PageMap myAS(mythos::init::PML4);
mythos::KernelMemory kmem(mythos::init::KM);
mythos::KObject device_memory(mythos::init::DEVICE_MEM);
mythos::SimpleCapAlloc< mythos::init::APP_CAP_START
, mythos::init::SIZE-mythos::init::APP_CAP_START> capAlloc(myCS);
mythos::RaplDriverIntel rapl(mythos::init::RAPL_DRIVER_INTEL);
mythos::ProcessorAllocator pa(mythos::init::PROCESSOR_ALLOCATOR);


int main()
{
MLOG_ERROR(mlog::app, "New process started :)");
MLOG_INFO(mlog::app, "info frame", DVARhex(info_ptr), DVAR(info_ptr->getNumThreads()), DVAR(info_ptr->getPsPerTSC()));

return 0;
}
2 changes: 2 additions & 0 deletions kernel/async/monitor-common/async/Place.hh
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,8 @@ public:
/** true if the hardware thread is currently in kernel mode and processing tasks. */
bool isActive() const { return nestingMonitor.load(std::memory_order_relaxed); }

cpu::ThreadID getThreadID(){ return threadID; }

protected:
void pushPrivate(TaskletBase* msg) {
ASSERT(isLocal());
Expand Down
65 changes: 48 additions & 17 deletions kernel/boot/init-loader-amd64/boot/load_init.cc
Original file line number Diff line number Diff line change
Expand Up @@ -44,11 +44,14 @@
#include "boot/mlog.hh"
#include "boot/memory-root.hh"
#include "boot/DeployHWThread.hh"
#include "mythos/InfoFrame.hh"


namespace mythos {

Event<boot::InitLoader&> event::initLoader;
Event<boot::InitLoader&> event::initLoaderEarly;
Event<InfoFrame*> event::initInfoFrame;

namespace boot {

Expand All @@ -59,6 +62,9 @@ InitLoader::InitLoader(char* image)
, capAlloc(init::CAP_ALLOC_START,
init::CAP_ALLOC_END-init::CAP_ALLOC_START)
, memMapper(&capAlloc, mythos::init::KM)
// default: no processor allocator present
, processorAllocatorPresent(false)
, initSC(init::SCHEDULERS_START)
{
MLOG_INFO(mlog::boot, "found init application image at", (void*)image);
}
Expand All @@ -69,13 +75,17 @@ optional<void> InitLoader::load()
{
if (!_img.isValid()) RETURN(Error::GENERIC_ERROR);

event::initLoaderEarly.emit(*this);

// order matters here
optional<void> res(Error::SUCCESS);
if (res) res = initCSpace();
auto ipc_vaddr = loadImage();
res = ipc_vaddr;
if (res) MLOG_INFO(mlog::boot, "init invokation buffer", DVARhex(*ipc_vaddr));
if (res) res = createPortal(*ipc_vaddr, init::PORTAL);
if (res) MLOG_INFO(mlog::boot, "init info frame/invokation buffer", DVARhex(*ipc_vaddr));
auto infoFramePtr = createInfoFrame(*ipc_vaddr);
res = infoFramePtr;
if (res) res = createPortal(*infoFramePtr, init::PORTAL);
if (res) res = createEC(*ipc_vaddr);
RETURN(res);
}
Expand Down Expand Up @@ -157,12 +167,14 @@ optional<void> InitLoader::initCSpace()
if (!res) RETHROW(res);
}

ASSERT(cpu::getNumThreads() <= init::SCHEDULERS_START - init::APP_CAP_START);
MLOG_INFO(mlog::boot, "... create scheduling context caps in caps",
init::SCHEDULERS_START, "till", init::SCHEDULERS_START+cpu::getNumThreads()-1);
for (cpu::ThreadID id = 0; id < cpu::getNumThreads(); ++id) {
auto res = csSet(init::SCHEDULERS_START+id, boot::getScheduler(id));
if (!res) RETHROW(res);
if(!processorAllocatorPresent){
ASSERT(cpu::getNumThreads() <= init::SCHEDULERS_START - init::APP_CAP_START);
MLOG_INFO(mlog::boot, "... create scheduling context caps in caps",
init::SCHEDULERS_START, "till", init::SCHEDULERS_START+cpu::getNumThreads()-1);
for (cpu::ThreadID id = 0; id < cpu::getNumThreads(); ++id) {
auto res = csSet(init::SCHEDULERS_START+id, boot::getScheduler(id));
if (!res) RETHROW(res);
}
}

ASSERT(cpu::getNumThreads() <= init::INTERRUPT_CONTROL_START - init::APP_CAP_START);
Expand All @@ -178,20 +190,39 @@ optional<void> InitLoader::initCSpace()
RETURN(Error::SUCCESS);
}

optional<CapPtr> InitLoader::createInfoFrame(uintptr_t ipc_vaddr)
{
auto size = round_up(sizeof(InfoFrame), align2M);
MLOG_INFO(mlog::boot, "... create info frame");
auto frameCap = memMapper.createFrame(init::INFO_FRAME, size, align2M);
if (!frameCap) RETHROW(frameCap);
MLOG_INFO(mlog::boot, "... map info frame",
DVAR(*frameCap), DVARhex(ipc_vaddr));
memMapper.mmap(ipc_vaddr, size, true, false, *frameCap, 0);

auto frameEntry = capAlloc.get(*frameCap);
if (!frameEntry) RETHROW(frameEntry);
TypedCap<IFrame> frame(frameEntry);
if (!frame) RETHROW(frame);
auto info = new(reinterpret_cast<InfoFrame*>(frame.getFrameInfo().start.logint())) InfoFrame();
info->numThreads = cpu::getNumThreads();

//register user memory
info->memRanges = _mem->getUserMem();

event::initInfoFrame.emit(info);

return frameCap;
}

optional<void> InitLoader::createPortal(uintptr_t ipc_vaddr, CapPtr dstPortal)
optional<void> InitLoader::createPortal(CapPtr infoFrame, CapPtr dstPortal)
{
auto size = 2*1024*1024;
MLOG_INFO(mlog::boot, "... create portal in cap", dstPortal);
auto portal = create<Portal,PortalFactory>(capAlloc.get(dstPortal));
if (!portal) RETHROW(portal);

auto frameCap = memMapper.createFrame(size, 2*1024*1024);
if (!frameCap) RETHROW(frameCap);
MLOG_INFO(mlog::boot, "... map invocation buffer",
DVAR(*frameCap), DVARhex(ipc_vaddr));
memMapper.mmap(ipc_vaddr, size, true, false, *frameCap, 0);
auto res = portal->setInvocationBuf(capAlloc.get(*frameCap), 0);
// ensure ib is the first member in InfoFrame -> frame offset == 0
auto res = portal->setInvocationBuf(capAlloc.get(infoFrame), 0);
if (!res) RETHROW(res);

_portal = *portal; // TODO return this?
Expand Down Expand Up @@ -281,7 +312,7 @@ optional<void> InitLoader::createEC(uintptr_t ipc_vaddr)
optional<void> res(Error::SUCCESS);
if (res) res = ec->setCapSpace(capAlloc.get(init::CSPACE));
if (res) res = ec->setAddressSpace(capAlloc.get(init::PML4));
if (res) res = ec->setSchedulingContext(capAlloc.get(init::SCHEDULERS_START));
if (res) res = ec->setSchedulingContext(capAlloc.get(initSC));
if (!res) RETHROW(res);
ec->getThreadState().rdi = ipc_vaddr;
ec->setEntryPoint(_img.header()->entry);
Expand Down
Loading