Skip to content

Commit

Permalink
Introduced changes to the kernel's boot sequence in line with my curr…
Browse files Browse the repository at this point in the history
…ent vision

for a clean bootup. The kernel is being made into a much more microkernel-esque
form factor, and soon it will be highly message passing, and far more
organized.

We now have Memory Management from very early on in the boot sequence. This is
quickly followed by process spawning and threading, and soon by scheduling.

Effectively, this causes the kernel to behave like a microkernel. We will
strongly postpone the initialization of IRQs, since our original reason for
initializing IRQs so early was to facilitate the early petting of watchdog
devices. Instead, we will require that chipsets with watchdog devices include
some kind of mechanism for ensuring that they pet their own watchdog device in a
chipset-specific manner, which the kernel is not required to know about.

This enables us to offload all chipset/device related setup to much later on in
the boot sequence.

This patch also sees the end of the __korientation and __kcpuPowerOn sequences
as identifiable thread entities, and demotes them to execution sequences only.
We've removed completely all ground for per-CPU threads to stand on, in their
/former/ appearance. They are now quite literally addressable per-CPU thread
objects. Each CPU has its own pCPU thread. Over the next few patches, we should
have stabilized this new per-CPU threading format, and thereby stabilized the
entire kernel source.

I will split the changes in this patch into 3 main sections.

Per-CPU Threads:
CpuStream:
  * Renamed CpuStream::baseInit() to CpuStream::initializeBaseState().
  * Split CpuStream::initializeBaseState() into base state initialization
  (GDT + CpuStream pointer load into DR0), and exception initialization.
__korientation and __kcpuPowerOn:
  * __korientation has generally been removed.
  * __korientationPowerStack has been offloaded into a global symbol and we
    can now retrieve it through the global.
  * New abstraction for the BSP CPU:
    We need at various times to know whether or not it is the first time the
    BSP CPU is being detected or initialized. Previously the logic for
    determining this was mediocre and weak. Now we have introduced a proper
    set of states for specifying exactly which iteration of initialization
    or hotplug the BSP CPU is in.
    * Introduced FIRSTPLUG, HOTPLUG and NOTBSP state values.
    * Introduced matching state query methods into the CpuStream class.
    * As a result, removed all flags which previously indicated BSP status:
      (CPUSTREAM_FLAGS_BSP, and so on).
    * All CpuStream member objects and member classes take a BSP plug status
      variable in their constructors. Keep in mind that we can probably
      abstract this into a global. It is unlikely to change oft enough to require
      locking either. Or even be reference enough for locking on it to be a
      performance hindrance.
  * Every CPU now has its own PowerThread, and its own PowerStack.
* MessageStream is now a member of Thread and not of _TaskContext.

Kernel boot sequence:
  * DebugPipe __kdebug instance is initialized much earlier now, so we have
    printing very early on in the boot sequence.

General:
  * New method to determine whether or not a CPU is the BSP CPU:
    CpuStream::isBspCpu().
  * Class Stream is now a template and it accepts a parameter which determines
    the type of its member "parent" pointer.
  * We can later make this derive from a StreamBase class, which can be used
    for polymorphism, in whatever form we implement such polymorphism later on
    in the kernel.
  • Loading branch information
latentPrion committed Aug 25, 2014
1 parent 2f63ee1 commit 8804624
Show file tree
Hide file tree
Showing 45 changed files with 600 additions and 337 deletions.
1 change: 0 additions & 1 deletion core/__kclasses/cachePool.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,6 @@ SlamCache *CachePool::getCache(uarch_t objSize)
return NULL;
}

#include <__kclasses/memReservoir.h>
SlamCache *CachePool::createCache(uarch_t objSize)
{
sCachePoolNode *node;
Expand Down
11 changes: 2 additions & 9 deletions core/__kthreads/__kcpuPowerOn.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,8 @@ uarch_t __kcpuPowerStacksLength=0;
void **__kcpuPowerStacks=0;
ubit8 *__kcpuPowerOnLapicVaddr=0;

/** EXPLANATION:
* Under here is the __kcpuPowerOn thread's actual thread structure, as
* a recognizible entity by the scheduler.
*
* This is what the waking CPU's stream will point to as its "currentTask". Its
* members are initialized by the CPU Tributary before any CPUs are awakened in
* CpuTrib::initialize2().
**/
Thread __kcpuPowerOnThread(0x0, processTrib.__kgetStream(), NULL);
void __kcpuPowerOnMain(CpuStream *self);

// Part of __koptimizationHacks.cpp.
void (*__kcpuPowerOnInit(void))()
{
Expand Down
4 changes: 1 addition & 3 deletions core/__kthreads/__korientation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,4 @@
#include <kernel/common/thread.h>
#include <kernel/common/processTrib/processTrib.h>


Thread __korientationThread(__KPROCESSID, processTrib.__kgetStream(), NULL);
ubit8 __korientationStack[PAGING_BASE_SIZE * CHIPSET_MEMORY___KSTACK_NPAGES];
extern "C" void __korientationInit(ubit32, sMultibootData *);
3 changes: 2 additions & 1 deletion core/__kthreads/x8632/__kcpuPowerOnMain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,8 @@ void __kcpuPowerOnMain(CpuStream *self)
* to handle inter-CPU-messages, and thus cause that waking CPU to
* crash.
**/
self->baseInit();
self->initializeBaseState();
self->initializeExceptions();
self->powerManager.setPowerStatus(CpuStream::PowerManager::C0);

// After "bind", the CPU will be able to allocate, etc. normally.
Expand Down
2 changes: 1 addition & 1 deletion core/__kthreads/x8632/__korientationEntry.S
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ ASM_SECTION(.__korientationText)

ASM_LOCAL_FUNCTION(__korientationVirtualStart)
/* Load the stack pointer for the Orientation thread. */
movl $__korientationStack+(PAGING_BASE_SIZE * CHIPSET_MEMORY___KSTACK_NPAGES), %esp
movl $bspCpuPowerStack+(PAGING_BASE_SIZE * CHIPSET_MEMORY___KSTACK_NPAGES), %esp
/* Clear the CPU flags */
pushl $0
popfl
Expand Down
61 changes: 37 additions & 24 deletions core/__kthreads/x8632/__korientationMain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -166,34 +166,33 @@ extern "C" void __korientationInit(ubit32, sMultibootData *)
* C++ global constructors.
**/
__koptimizationHacks();
bspCpu.initializeBaseState();
memset(&__kbssStart, 0, &__kbssEnd - &__kbssStart);
DO_OR_DIE(bspCpu, initializeBspCpuLocking(), ret);
cxxrtl::callGlobalConstructors();
bspCpu.powerManager.setPowerStatus(CpuStream::PowerManager::C0);

/* Initialize exception handling, then do chipset-wide early init.
* Finally, initialize the irqControl mod, and mask all IRQs off to
* place the chipset into a stable state.
/* Initialize exceptions, then move on to __kspace level physical
* memory management, then the kernel Memory Stream. Then when we have
* MM up, we initialize the debug pipe.
**/
DO_OR_DIE(interruptTrib, initializeExceptions(), ret);
DO_OR_DIE(zkcmCore, initialize(), ret);
DO_OR_DIE(memoryTrib, initialize(), ret);
DO_OR_DIE(memoryTrib, __kspaceInitialize(), ret);

/* Initialize the kernel debug pipe for boot logging, etc.
**/
DO_OR_DIE(__kdebug, initialize(), ret);
devMask = __kdebug.tieTo(DEBUGPIPE_DEVICE_BUFFER | DEBUGPIPE_DEVICE1);
if (!FLAG_TEST(devMask, DEBUGPIPE_DEVICE_BUFFER)) {
printf(WARNING ORIENT"No debug buffer allocated.\n");
}
else
{
printf(NOTICE ORIENT"Kernel debug output tied to devices "
"BUFFER and DEVICE1.\n");
};

// __kdebug.refresh();
printf(NOTICE ORIENT"Kernel debug output tied to devices BUFFER and "
"DEVICE1.\n");

/* Initialize IRQs.
**/
DO_OR_DIE(zkcmCore.irqControl, initialize(), ret);
zkcmCore.irqControl.maskAll();
DO_OR_DIE((*__kprocess.getVaddrSpaceStream()), initialize(), ret);
DO_OR_DIE(__kprocess.memoryStream, initialize(), ret);
DO_OR_DIE(memReservoir, initialize(), ret);
DO_OR_DIE(cachePool, initialize(), ret);

DO_OR_DIE(processTrib, initialize(), ret);
DO_OR_DIE(
Expand All @@ -204,20 +203,32 @@ extern "C" void __korientationInit(ubit32, sMultibootData *)
NULL),
ret);

/* Initialize __kspace level physical memory management, then the
* kernel Memory Stream.
memoryTrib.dump();

/* The next block is dedicated to initializing the core of the
* microkernel. Scheduling, Message passing, Processes and Threads.
**/
DO_OR_DIE(memoryTrib, initialize(), ret);
DO_OR_DIE(memoryTrib, __kspaceInitialize(), ret);
DO_OR_DIE(processTrib.__kgetStream()->memoryStream, initialize(), ret);

/* Finally, the last block in this sequence is dedicated to IRQs before
* we branch off to working on the hardware abstraction subsystems.
**/
DO_OR_DIE(zkcmCore, initialize(), ret);

/* Initialize the kernel debug pipe for boot logging, etc.
**/

/* Initialize IRQs.
**/
DO_OR_DIE(zkcmCore.irqControl, initialize(), ret);
zkcmCore.irqControl.maskAll();


zkcmCore.irqControl.chipsetEventNotification(
IRQCTL_EVENT___KSPACE_MEMMGT_AVAIL, 0);

/* Initialize the kernel Memory Reservoir (heap) and object cache pool.
* Create the global asyncContext object cache.
**/
DO_OR_DIE(memReservoir, initialize(), ret);
DO_OR_DIE(cachePool, initialize(), ret);
__kcallbackCache = cachePool.createCache(sizeof(__kCallback));
if (__kcallbackCache == NULL)
{
Expand All @@ -234,8 +245,10 @@ extern "C" void __korientationInit(ubit32, sMultibootData *)
DO_OR_DIE(__kprocess.zasyncStream, initialize(), ret);
DO_OR_DIE(cpuTrib, initialize(), ret);
DO_OR_DIE(zkcmCore.cpuDetection, initialize(), ret);
asm volatile("hlt\n\t");
DO_OR_DIE(cpuTrib, initializeBspCpuStream(), ret);


/* Spawn the new thread for __korientationMain. There is no need to
* unschedule __korientationInit() because it will never be scheduled.
**/
Expand Down Expand Up @@ -379,7 +392,7 @@ void __korientationMain4(MessageStream::sHeader *msgIt)
* then load the chipset's bus-pin mappings and initialize timer
* services.
**/
DO_OR_DIE(interruptTrib, initializeIrqManagement(), ret);
DO_OR_DIE(interruptTrib, initializeIrqs(), ret);
DO_OR_DIE(zkcmCore.irqControl.bpm, loadBusPinMappings(CC"isa"), ret);
DO_OR_DIE(zkcmCore.timerControl, initialize(), ret);
DO_OR_DIE(timerTrib, initialize(), ret);
Expand Down
2 changes: 1 addition & 1 deletion core/chipset/ibmPc/zkcmCore.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ void ZkcmCore::newCpuIdNotification(cpu_t newCpuId)
newArray = new void*[newCpuId + 1];
if (newArray == NULL)
{
panic(FATAL"zkcmCore::highestCpuIdNotification: Failed to "
panic(FATAL"zkcmCore::newCpuIdNotification: Failed to "
"allocate sleepstack pointer array.\n");
};

Expand Down
2 changes: 1 addition & 1 deletion core/commonlibs/libacpi/rxsdt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,6 @@ void acpiRsdt::destroySdt(acpi::sSdt *sdt)
processTrib.__kgetStream()->getVaddrSpaceStream()->releasePages(
(void *)((uintptr_t)sdt & PAGING_BASE_MASK_HIGH),
nPages);
if (!FLAG_TEST(cpuTrib.getCurrentCpuStream()->flags, CPUSTREAM_FLAGS_BSP)) {printf(NOTICE"Destroying SDT @v 0x%p on CPU %d.\n", sdt, cpuTrib.getCurrentCpuStream()->cpuId);};
if (!cpuTrib.getCurrentCpuStream()->isBspCpu()) {printf(NOTICE"Destroying SDT @v 0x%p on CPU %d.\n", sdt, cpuTrib.getCurrentCpuStream()->cpuId);};
}

6 changes: 2 additions & 4 deletions core/include/__kclasses/bitmap.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,17 +52,15 @@ friend class MessageStream;
vaddr(ptr), size(size)
{}

sPreallocatedMemory operator =(int)
{ return *this; }

void *vaddr;
ubit16 size;
};

Bitmap(void);

error_t initialize(
ubit32 nBits, sPreallocatedMemory preallocatedMemory=0);
ubit32 nBits,
sPreallocatedMemory preallocatedMemory=sPreallocatedMemory(NULL, 0));

~Bitmap(void);

Expand Down
1 change: 1 addition & 0 deletions core/include/__kclasses/memReservoir.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ class MemReservoir

Heap __kheap;
MemoryStream *sourceStream;

SharedResourceGroup<MultipleReaderLock, sBogState> heaps;
};

Expand Down
4 changes: 0 additions & 4 deletions core/include/__kthreads/__korientation.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,6 @@
extern "C" void __korientationInit(ubit32 mbMagic, sMultibootData *mbData);
extern "C" void __korientationMain(void);

class Thread;

extern Thread __korientationThread;
extern ubit8 __korientationStack[];
extern ubit8 __korientationPreallocatedBmpMem[][64];

#endif
Expand Down
2 changes: 0 additions & 2 deletions core/include/arch/x8632/registerContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@
#include <kernel/common/execDomain.h>
#include <kernel/common/memoryTrib/vaddrSpaceStream.h>

class Thread;

class RegisterContext
{
public:
Expand Down
48 changes: 25 additions & 23 deletions core/include/kernel/common/cpuTrib/cpuStream.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@

#define CPUSTREAM_FLAGS_INITIALIZED (1<<0)
#define CPUSTREAM_FLAGS_ENUMERATED (1<<1)
#define CPUSTREAM_FLAGS_BSP (1<<2)

#define CPUSTREAM_POWER_ON 0x0
#define CPUSTREAM_POWER_CHECK 0x1
Expand All @@ -48,27 +47,29 @@ class CpuStream
friend class ProcessStream;
public:
#if __SCALING__ >= SCALING_CC_NUMA
CpuStream(numaBankId_t bid, cpu_t id, ubit32 acpiId);
CpuStream(numaBankId_t bid, cpu_t id, ubit32 acpiId, bspPlugTypeE bpt);
#else
CpuStream(cpu_t id, ubit32 cpuAcpiId);
CpuStream(cpu_t id, ubit32 cpuAcpiId, bspPlugTypeE bpt);
#endif

void baseInit(void);
void initializeBaseState(void);
void initializeExceptions(void);
error_t initialize(void);
sarch_t isInitialized(void);
~CpuStream(void);

error_t initializeBspCpuLocking(void);

error_t bind(void);
void cut(void);

public:
status_t enumerate(void);
sCpuFeatures *getCpuFeatureBlock(void);
ubit8 isBspCpu(void) { return bspPlugType > BSP_PLUGTYPE_NOTBSP; }
ubit8 isBspFirstPlug(void)
{ return bspPlugType == BSP_PLUGTYPE_FIRSTPLUG; }

public:
class PowerManager
: public Stream<CpuStream>
{
public:
enum powerStatusE {
Expand All @@ -77,10 +78,16 @@ friend class ProcessStream;
GOING_TO_SLEEP, WAKING,
FAILED_BOOT };

PowerManager(CpuStream *parentStream)
:
parent(parentStream)
{ powerStatus.rsrc = OFF; }
PowerManager(CpuStream *parentStream, bspPlugTypeE bspPlugType)
: Stream<CpuStream>(parentStream, parentStream->cpuId),
bspPlugType(bspPlugType)
{
if (bspPlugType == BSP_PLUGTYPE_FIRSTPLUG) {
powerStatus.rsrc = C0;
} else {
powerStatus.rsrc = OFF;
};
}

~PowerManager(void)
{ powerStatus.rsrc = OFF; }
Expand Down Expand Up @@ -112,15 +119,15 @@ friend class ProcessStream;
void bootWaitForCpuToPowerOn(void);

private:
bspPlugTypeE bspPlugType;
SharedResourceGroup<MultipleReaderLock, powerStatusE>
powerStatus;

CpuStream *parent;
};

private:
#if __SCALING__ >= SCALING_SMP
class InterCpuMessager
: public Stream<CpuStream>
{
private: struct sMessage;
public:
Expand Down Expand Up @@ -171,10 +178,9 @@ friend class ProcessStream;
volatile uarch_t val2;
volatile uarch_t val3;
};
List<sMessage> messageQueue;
SlamCache *cache;
SharedResourceGroup<WaitLock, statusE> statusFlag;
CpuStream *parent;
List<sMessage> messageQueue;
SlamCache *cache;
SharedResourceGroup<WaitLock, statusE> statusFlag;
};
#endif

Expand All @@ -184,26 +190,22 @@ friend class ProcessStream;
#if __SCALING__ >= SCALING_CC_NUMA
numaBankId_t bankId;
#endif
bspPlugTypeE bspPlugType;

sCpuFeatures cpuFeatures;
// Per CPU scheduler.
TaskStream taskStream;

ubit32 flags;
// Small stack used for scheduler task switching.
ubit8 schedStack[PAGING_BASE_SIZE / 2];
// Stack for the CPU's power thread.
ubit8 powerStack[
PAGING_BASE_SIZE * CHIPSET_MEMORY___KSTACK_NPAGES];

PowerManager powerManager;
#if __SCALING__ >= SCALING_SMP
InterCpuMessager interCpuMessager;
#endif
#if defined(CONFIG_ARCH_x86_32) || defined(CONFIG_ARCH_x86_64)
class X86Lapic lapic;
#endif
private:
Thread powerThread;
};

// The hardcoded stream for the BSP CPU.
Expand Down
5 changes: 2 additions & 3 deletions core/include/kernel/common/floodplainn/floodplainnStream.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,12 +52,12 @@ class ProcessStream;

class FloodplainnStream
:
public Stream
public Stream<ProcessStream>
{
public:
FloodplainnStream(processId_t id, ProcessStream *parent)
:
Stream(id), parent(parent)
Stream<ProcessStream>(parent, id)
{};

error_t initialize(void) { return ERROR_SUCCESS; }
Expand All @@ -70,7 +70,6 @@ public Stream
// error_t zkcmDisconnect(SingleWaiterQueue *queue);

private:
ProcessStream *parent;
};

#endif
Expand Down
Loading

0 comments on commit 8804624

Please sign in to comment.