diff --git a/chroma/inc/kernel/system/process/process.h b/chroma/inc/kernel/system/process/process.h new file mode 100644 index 0000000..c6cee2e --- /dev/null +++ b/chroma/inc/kernel/system/process/process.h @@ -0,0 +1,191 @@ +#pragma once + +#include +#include +#include +#include + +/************************ + *** Team Kitty, 2021 *** + *** Chroma *** + ***********************/ + +#define MAX_CORES 8 +#define MAX_PROCESSES 128 +#define PROCESS_STACK 65535 + +static size_t strlen(const char* String) { + size_t Len = 0; + while(String[Len] != '\0') { + Len++; + } + return Len; +}; + +/** + * @brief All the data a process needs. + * + * Contains all the process-specific structs. + * Lots of private members, out of necessity + */ +class Process { + // Tells the scheduler, and system at large, what the current state of the process is + enum ProcessState { + PROCESS_AVAILABLE, // Process is ready to be scheduled + PROCESS_RUNNING, // Process is active on the CPU + PROCESS_WAITING, // Process is blocked by external activity + PROCESS_CRASH, // Process has encountered an error and needs to be culled + PROCESS_NOT_STARTED,// Process is waiting for bootstrap + PROCESS_REAP // Process wants to die + }; + + // The process' buffers, for moving data in and out of the system + enum BufferTypes { + STDOUT, + STDIN, + STDERR + }; + + // The data that actually represents one of the above buffers. + struct Buffer { + uint8_t* Data; + size_t Length; + size_t LengthAllocated; + uint8_t Type; // An entry of BufferTypes. + } __attribute__((packed)); + + // A packet used for IPC + struct ProcessMessage { + uint8_t MessageID; + size_t Source; // Originating PID + size_t Destination; // Target PID + size_t Content; // Pointer to the data. + size_t Length; // Size of the data. End is Content + Length + size_t Response; + bool Read; // True if message has been read + bool Free; // True if memory can be reused for something else + } __attribute__((packed)); + + // Important information about the process. + // Its' stack and stack pointer, plus the page tables. + struct ProcessHeader { + uint8_t* Stack; + size_t RSP; + address_space_t* AddressSpace; + }; + + private: + ProcessHeader Header; + ProcessState State; + + bool User; // Is this process originated in userspace? + + size_t UniquePID; // Globally Unique ID. + size_t KernelPID; // If in kernel space, the PID. + size_t ParentPID; // If this process was forked, the parent's PID. + + char Name[128]; + size_t Entry; // The entry point + uint8_t Core; + + bool ORS = false; + bool IsActive = false; + bool IsInterrupted = false; // True if an interrupt was fired while this process is active + + uint8_t Signals[8]; // Interrupt / IRQ / Signal handlers. + uint8_t Sleeping; // 0 if active, else the process is waiting for something. TODO: remove this, use State? + + ProcessMessage* Messages; // A queue of IPC messages. + size_t LastMessage; // The index of the current message. + + uint8_t* ProcessMemory; + size_t ProcessMemorySize; + + // TODO: Stack Trace & MFS + + public: + + Process(size_t KPID) : State(PROCESS_AVAILABLE), UniquePID(-1), KernelPID(KPID) { + }; + + Process(const char* ProcessName, size_t KPID, size_t UPID, size_t EntryPoint, bool Userspace) + : UniquePID(UPID), KernelPID(KPID), Entry(EntryPoint), ORS(false), LastMessage(0), User(Userspace), Sleeping(0) { + + memcpy((void*) ProcessName, Name, strlen(Name) + 1); + }; + + Process(const Process &Instance) { + memcpy(this, &Instance, sizeof(Process)); + }; + + Process& operator=(const Process &Instance) { + memcpy(this, &Instance, sizeof(Process)); + return *this; + }; + + /*************************************************************/ + + void InitMemory(); + + void InitMessages(); + + /*************************************************************/ + + void SetCore(size_t CoreID) { Core = CoreID; }; + + void IncreaseSleep(size_t Interval) { Sleeping += Interval; }; + void DecreaseSleep(size_t Interval) { Sleeping -= Interval; }; + + /*************************************************************/ + + ProcessHeader* GetHeader() { return &Header; }; + + size_t GetParent() const { return ParentPID; }; + + bool IsValid() const { return KernelPID != 0; }; + + bool IsUsed() const { return (State != ProcessState::PROCESS_AVAILABLE && State != ProcessState::PROCESS_CRASH && State != ProcessState::PROCESS_REAP) && IsValid(); }; + + bool IsSleeping() const { return Sleeping; }; + + size_t GetSleepCounter() const { return Sleeping; }; + + bool CanRun(const size_t CPU) const { + bool flag = !(ORS && !IsActive); + + return State == ProcessState::PROCESS_WAITING && Core == CPU && KernelPID != 0 && flag && !IsSleeping(); + } + + size_t GetCore() const { return Core; }; + + +}; + +class ProcessManagement { + public: + TSS64 TSS[MAX_CORES]; + uint32_t CoreCount = 1; + + ProcessManagement(); + static ProcessManagement* instance(); + + void Wait(); + void Initialize(); + void InitialiseCore(int APIC, int ID); + + void NotifyAllCores(); + + // TODO: Process* + size_t SwitchContext(INTERRUPT_FRAME* CurrentFrame); + void MapThreadMemory(size_t from, size_t to, size_t length); + + void InitProcess(/*func EntryPoint*/ int argc, char** argv); + void InitProcessPagetable(bool Userspace); + void InitProcessArch(); + + size_t HandleRequest(size_t CPU); + + + inline void yield() { __asm __volatile("int 100"); } + +}; \ No newline at end of file diff --git a/src/chroma/lainlib/ethernet/e1000/E1000Driver.c b/src/chroma/lainlib/ethernet/e1000/E1000Driver.c index d45ecce..0d03ad4 100644 --- a/src/chroma/lainlib/ethernet/e1000/E1000Driver.c +++ b/src/chroma/lainlib/ethernet/e1000/E1000Driver.c @@ -148,7 +148,7 @@ void E1000InitRX(e1000_device_t* Device) { for(size_t i = 0; i < E1000_NUM_RX_DESC; i++) { Device->ReceivePackets[i] = (struct e1000_receive_packet*) ((uint8_t*)Packets + i*16); - Device->ReceivePackets[i]->address = (size_t) ((uint8_t*) kmalloc((PAGE_SIZE * 2) + 16)); + Device->ReceivePackets[i]->Address = (size_t) ((uint8_t*) kmalloc((PAGE_SIZE * 2) + 16)); Device->ReceivePackets[i]->Status = 0; }