diff --git a/CMakeLists.txt b/CMakeLists.txt index 4cf1f5c..9b5178a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -36,7 +36,7 @@ SET(src_files ${CMAKE_SOURCE_DIR}/src/system/extern/extern_defs.cpp ${CMAKE_SOURCE_DIR}/src/drivers/elf.cpp ${CMAKE_SOURCE_DIR}/src/drivers/devices/devices.cpp - ${CMAKE_SOURCE_DIR}/src/drivers/devices/input/keyboard.cpp + ${CMAKE_SOURCE_DIR}/src/drivers/devices/io/ps2_keyboard.cpp ${CMAKE_SOURCE_DIR}/src/drivers/devices/io/apic.cpp ${CMAKE_SOURCE_DIR}/src/drivers/devices/storage/ata.cpp ) @@ -46,7 +46,7 @@ SET(lib_files ${CMAKE_SOURCE_DIR}/src/lainlib/mutex/ticketlock.cpp ${CMAKE_SOURCE_DIR}/src/lainlib/compression/lzgmini.c ${CMAKE_SOURCE_DIR}/src/lainlib/string/str.cpp - ${CMAKE_SOURCE_DIR}/src/editor/EditorMain.cpp + ${CMAKE_SOURCE_DIR}/src/lainlib/vector/vector.cpp ) include_directories("inc" "D:/mingw/mingw64/lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++" "D:/mingw/mingw64/lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/x86_64-w64-mingw32") @@ -79,5 +79,5 @@ set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/bin) add_executable(kernel) target_sources(kernel PUBLIC ${src_preamble} PUBLIC ${src_files} PUBLIC ${src_no_sse} PUBLIC ${lib_files} PUBLIC ${src_epilogue}) -target_compile_options(kernel PRIVATE -ffreestanding -O0 -Wall -Wextra -Wall -Werror -fPIC -fno-exceptions -fno-omit-frame-pointer -mno-red-zone -fno-stack-protector $<$:-fno-rtti> -ggdb3) +target_compile_options(kernel PRIVATE -ffreestanding -O0 -Wall -Wextra -Wall -Werror -fPIC -fno-exceptions -fno-omit-frame-pointer -mno-red-zone -fno-stack-protector -fno-strict-aliasing $<$:-fno-rtti> -ggdb3) target_link_options(kernel PRIVATE -T ${CMAKE_SOURCE_DIR}/linker.ld -ffreestanding -O2 -nostdlib -nostartfiles -lgcc) diff --git a/inc/driver/generic/device.h b/inc/driver/generic/device.h index a48bfa9..d0ac509 100644 --- a/inc/driver/generic/device.h +++ b/inc/driver/generic/device.h @@ -2,6 +2,7 @@ #include #include #include +#include "lainlib/vector/vector.h" /************************ *** Team Kitty, 2021 *** @@ -50,7 +51,50 @@ namespace Device { }; }; - // TODO: GenericKeyboard + class GenericKeyboard : public GenericDevice { + public: + struct KeyboardData { + char Char; + char Scancode; + bool Pressed; + }; + + // This is an input device. + DeviceType GetType() const final { + return DeviceType::INTERFACE; + }; + + // Provided for utility checks. + static DeviceType GetRootType() { + return DeviceType::INTERFACE; + }; + + virtual bool isPressed(uint8_t) const = 0; + virtual uint8_t getLastPress() const = 0; + + size_t readBuffer(void* dest, size_t index, size_t len) { + size_t lengthRead = len; + + if (index > buffer.size()) { + return 0; + } else if (index + len > buffer.size()) { + lengthRead = sizeof(KeyboardData) - index; // TODO: wat? + } + + memcpy((uint8_t*) dest, ((uint8_t*)buffer.data) + index, lengthRead); + return lengthRead; + } + + size_t getBufferSize() { + return buffer.size(); + } + + protected: + lainlib::vector buffer; + + }; + + // TODO: GenericDebugger // TODO: GenericNetwork diff --git a/inc/driver/io/ps2_keyboard.h b/inc/driver/io/ps2_keyboard.h new file mode 100644 index 0000000..661767c --- /dev/null +++ b/inc/driver/io/ps2_keyboard.h @@ -0,0 +1,39 @@ +#pragma once +#include + +/************************ + *** Team Kitty, 2022 *** + *** Chroma *** + ***********************/ + +extern char keys[128]; + +namespace Device { + class PS2Keyboard : public GenericKeyboard { + bool keyStates[128]; + uint8_t lastPress = 0; + uint8_t* callback; + + public: + PS2Keyboard(); + + // The instance of this singleton class. + static PS2Keyboard* driver; + + const char* GetName() const { + return "PS2 Keyboard"; + }; + + void Init(); + void InterruptHandler(); + + void setState(bool state, uint8_t key); + bool isPressed(uint8_t key) const; + + uint8_t getLastPress() const { + return keys[lastPress]; + } + + void SetCallback(uint32_t*); + }; +} \ No newline at end of file diff --git a/inc/driver/keyboard.h b/inc/driver/keyboard.h deleted file mode 100644 index 18b7f9b..0000000 --- a/inc/driver/keyboard.h +++ /dev/null @@ -1,28 +0,0 @@ -#include - -/************************ - *** Team Kitty, 2020 *** - *** Chroma *** - ***********************/ - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct { - char Char; - char Scancode; - bool Pressed; -} KeyboardData; - -typedef void (*KeyboardCallback)(KeyboardData Frame); - -extern KeyboardCallback KeyboardCallbacks[16]; - -int SetupKBCallback(void (*Handler)(KeyboardData Frame)); - -void UninstallKBCallback(int Index); - -#ifdef __cplusplus -} -#endif \ No newline at end of file diff --git a/inc/kernel/boot/boot.h b/inc/kernel/boot/boot.h index d4d79fe..50a3944 100644 --- a/inc/kernel/boot/boot.h +++ b/inc/kernel/boot/boot.h @@ -6,10 +6,6 @@ #include -#ifdef __cplusplus -extern "C" { -#endif - /* ;* Memory map ;* 0h - 600h reserved for the system @@ -156,9 +152,3 @@ typedef struct { * MMapEnt *mmap_ent = &bootboot.mmap; mmap_ent++; * until you reach bootboot->size */ } __attribute__((packed)) bootinfo; - - - -#ifdef __cplusplus -} -#endif diff --git a/inc/kernel/chroma.h b/inc/kernel/chroma.h index 5426d47..ef6fe75 100644 --- a/inc/kernel/chroma.h +++ b/inc/kernel/chroma.h @@ -9,10 +9,6 @@ * It also provides the symbols for the framebuffer and configuration file, which are both equually important. */ -#ifdef __cplusplus -extern "C" { -#endif - #define UNUSED(x) (void)x #include @@ -73,7 +69,6 @@ void WriteChar(const char character); void WriteStringWithFont(const char* string); -void InitInterrupts(); void InitSerial(); void InitPrint(); @@ -82,12 +77,14 @@ void SetupIDT(); int ParseKernelHeader(size_t InitrdPtr); -int Main(); - -void Exit(int code); - -void SomethingWentWrong(const char* Message); - #ifdef __cplusplus -} // extern "C" -#endif \ No newline at end of file +extern "C" { +#endif + void InitInterrupts(); + + int Main(); + void Exit(int code); + void SomethingWentWrong(const char* Message); +#ifdef __cplusplus +} +#endif diff --git a/inc/kernel/system/core.hpp b/inc/kernel/system/core.hpp index 69f8d92..323cfcb 100644 --- a/inc/kernel/system/core.hpp +++ b/inc/kernel/system/core.hpp @@ -63,17 +63,6 @@ class Core { private: static Core* Processors[]; - // Initialization vectors for all new cores. - // Numbers derived from boot.h space. - // Specifically, the bootloader ROM. - enum Initialization { - PAGETABLES = 0x600, - STARTUP = 0x620, - STACK = 0x670, - GDT = 0x680, - IDT = 0x690 - }; - void Bootstrap(); void SetupData(size_t ID); diff --git a/inc/kernel/system/descriptors.h b/inc/kernel/system/descriptors.h index 0e7f9ed..441a662 100644 --- a/inc/kernel/system/descriptors.h +++ b/inc/kernel/system/descriptors.h @@ -8,10 +8,6 @@ *** Chroma *** ***********************/ -#ifdef __cplusplus -extern "C" { -#endif - typedef struct __attribute__((packed)) { uint16_t LowLimit; uint16_t BaseLow; @@ -86,7 +82,3 @@ typedef struct __attribute__((packed)) { uint16_t Length; size_t Address; } IDT; - -#ifdef __cplusplus -} // extern "C" -#endif \ No newline at end of file diff --git a/inc/kernel/system/interrupts.h b/inc/kernel/system/interrupts.h index 7e7c0e4..f23dd58 100644 --- a/inc/kernel/system/interrupts.h +++ b/inc/kernel/system/interrupts.h @@ -6,13 +6,12 @@ *** Chroma *** ***********************/ -#ifdef __cplusplus + #ifdef __cplusplus extern "C" { #endif extern const char* ExceptionStrings[]; - typedef struct __attribute__((packed)) { size_t rip; size_t cs; @@ -30,12 +29,17 @@ typedef struct __attribute__((packed)) { size_t ss; } EXCEPTION_FRAME; - typedef void (*IRQHandler)(INTERRUPT_FRAME* Frame); -extern IRQHandler IRQ_Handlers[16]; +typedef struct { + IRQHandler handlers[8]; + size_t numHandlers; +} IRQHandlerData; -void InstallIRQ(int IRQ, void (*Handler)(INTERRUPT_FRAME* Frame)); +extern IRQHandlerData IRQHandlers[32]; + +size_t InstallIRQ(int IRQ, IRQHandler handler); +void UninstallIRQHandler(int IRQ, size_t ID); __attribute__((no_caller_saved_registers)) void IRQ_Common(INTERRUPT_FRAME* Frame, size_t Interupt); __attribute__((no_caller_saved_registers)) void ISR_Common(INTERRUPT_FRAME* Frame, size_t Interrupt); @@ -95,5 +99,5 @@ void IRQ14Handler(INTERRUPT_FRAME* Frame); void IRQ15Handler(INTERRUPT_FRAME* Frame); #ifdef __cplusplus -} // extern "C" +} #endif \ No newline at end of file diff --git a/inc/kernel/system/io.h b/inc/kernel/system/io.h index 0a7f4f8..adb3e2b 100644 --- a/inc/kernel/system/io.h +++ b/inc/kernel/system/io.h @@ -8,11 +8,7 @@ #define PAUSE __asm__ __volatile__("pause") -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct { +typedef struct { uint8_t ACK; uint8_t SelfTest; uint8_t Echo; @@ -22,7 +18,6 @@ typedef struct { extern KBD_FLAGS KbdFlags; - DESC_TBL ReadGDT(void); void WriteGDT(DESC_TBL GDTData); @@ -69,12 +64,14 @@ void Send8042(size_t); void WriteSerialChar(const char); void WriteSerialString(const char*, size_t); -int SerialPrintf(const char* format, ...); -int Printf(const char* Format, ...); -void* memcpy(void* dest, void const* src, size_t len); -void* memset(void* dst, int src, size_t len); - -#ifdef __cplusplus +#ifdef __cplusplus +extern "C" { +#endif + int SerialPrintf(const char* format, ...); + int Printf(const char* Format, ...); + void* memcpy(void* dest, void const* src, size_t len); + void* memset(void* dst, int src, size_t len); +#ifdef __cplusplus } -#endif \ No newline at end of file +#endif diff --git a/inc/kernel/system/memory.h b/inc/kernel/system/memory.h index d273b29..4c933c6 100644 --- a/inc/kernel/system/memory.h +++ b/inc/kernel/system/memory.h @@ -1,13 +1,10 @@ #pragma once -#ifdef __cplusplus -extern "C" { -#endif +#include #include #include #include -#include /************************ *** Team Kitty, 2020 *** @@ -41,10 +38,18 @@ extern "C" { #define CONCAT(x, y) x ## y #define CONCAT2(x, y) CONCAT(x, y) + +#ifdef __cplusplus +extern "C" { +#endif #define ASSERT(exp, error) \ if(!(exp)) SomethingWentWrong(error); // typedef char CONCAT2(static_assert, __LINE__) [(exp) ? 1 : -1] +#ifdef __cplusplus +} +#endif + #define CLZ(num) (num ? __builtin_clzll(num) : 64) #define IS_ALIGNED(addr) (((size_t) addr | 0xFFFFFFFFFFFFF000) == 0) @@ -223,10 +228,15 @@ size_t AllocatorMaxBlockSize(void); size_t AllocatorPoolOverhead(void); size_t AllocatorAllocateOverhead(void); - +#ifdef __cplusplus +extern "C" { +#endif size_t AlignUpwards(size_t Pointer, size_t Alignment); size_t AlignDownwards(size_t Pointer, size_t Alignment); void* AlignPointer(const void* Pointer, size_t Alignment); +#ifdef __cplusplus +} +#endif /************************************************************ @@ -237,6 +247,10 @@ extern size_t memstart; extern size_t end; +#ifdef __cplusplus +extern "C" { +#endif + void ListMemoryMap(); void InitMemoryManager(); @@ -270,6 +284,7 @@ void TraversePageTables(); void* memcpy(void* dest, void const* src, size_t len); + /********************************************* * C h r o m a A l l o c a t o r **********************************************/ @@ -300,6 +315,6 @@ extern void *PREFIX(realloc)(void *, size_t); ///< The standard function. extern void *PREFIX(calloc)(size_t, size_t); ///< The standard function. extern void PREFIX(free)(void *); ///< The standard function. -#ifdef __cplusplus +#ifdef __cplusplus } #endif \ No newline at end of file diff --git a/inc/kernel/system/pci.h b/inc/kernel/system/pci.h index 1260618..a4b30a0 100644 --- a/inc/kernel/system/pci.h +++ b/inc/kernel/system/pci.h @@ -1,9 +1,5 @@ #pragma once -#ifdef __cplusplus -extern "C" { -#endif - #include #include @@ -179,7 +175,3 @@ typedef struct { extern pci_device_t** pci_root_devices; extern pci_entry_t* pci_map; - -#ifdef __cplusplus -} -#endif \ No newline at end of file diff --git a/inc/kernel/video/bitmapfont.h b/inc/kernel/video/bitmapfont.h index c5d48b9..7931eb4 100644 --- a/inc/kernel/video/bitmapfont.h +++ b/inc/kernel/video/bitmapfont.h @@ -3,10 +3,6 @@ *** Chroma *** ***********************/ -#ifdef __cplusplus -extern "C" { -#endif - // This file contains all of the bitmap fonts made by me (Curle) and taken from the public domain // eg. http://dimensionalrift.homelinux.net/combuster/mos3/?p=viewsource&file=/modules/gfx/font8_8.asm @@ -468,7 +464,3 @@ const unsigned char bitfont_block[32][8] = { { 0xF0, 0xF0, 0xF0, 0xF0, 0x0F, 0x0F, 0x0F, 0x0F}, // U+259E (boxes top right and bottom left) { 0xF0, 0xF0, 0xF0, 0xF0, 0xFF, 0xFF, 0xFF, 0xFF}, // U+259F (boxes right and bottom) }; - -#ifdef __cplusplus -} -#endif \ No newline at end of file diff --git a/inc/kernel/video/draw.h b/inc/kernel/video/draw.h index 1ffc1ff..4516e5c 100644 --- a/inc/kernel/video/draw.h +++ b/inc/kernel/video/draw.h @@ -5,10 +5,6 @@ *** Chroma *** ***********************/ -#ifdef __cplusplus -extern "C" { -#endif - /** * Drawing routines for screen manipulation. * This will be pulled out into the Helix library soon. @@ -60,7 +56,3 @@ void DrawLineRoundedRect(size_t x, size_t y, size_t width, size_t height, size_t void DrawFilledCircle(size_t centerX, size_t centerY, size_t radius); void DrawLineCircle(size_t centerX, size_t centerY, size_t radius); void DrawLineCircleCorners(size_t centerX, size_t centerY, size_t radius, char cornerMask); - -#ifdef __cplusplus -} -#endif \ No newline at end of file diff --git a/inc/lainlib/compression/lzg.h b/inc/lainlib/compression/lzg.h index e859569..5b487a4 100644 --- a/inc/lainlib/compression/lzg.h +++ b/inc/lainlib/compression/lzg.h @@ -28,10 +28,6 @@ #ifndef _LIBLZG_H_ #define _LIBLZG_H_ -#ifdef __cplusplus -extern "C" { -#endif - #define LZG_VERSION "1.0.10" /**< @brief LZG library version string */ #define LZG_VERNUM 0x0100000a /**< @brief LZG library version number (strictly */ /* incremental) */ @@ -320,8 +316,4 @@ lzg_uint32_t LZG_Version(void); */ const char* LZG_VersionString(void); -#ifdef __cplusplus -} -#endif - #endif // _LIBLZG_H_ diff --git a/inc/lainlib/ethernet/e1000/e1000.h b/inc/lainlib/ethernet/e1000/e1000.h index adc199c..dcabf21 100644 --- a/inc/lainlib/ethernet/e1000/e1000.h +++ b/inc/lainlib/ethernet/e1000/e1000.h @@ -3,10 +3,6 @@ *** Chroma *** ***********************/ -#ifdef __cplusplus -extern "C" { -#endif - #include #include #include @@ -183,7 +179,3 @@ void E1000InterruptFired(INTERRUPT_FRAME* InterruptContext); uint8_t* E1000GetMAC(e1000_device_t* Device); // Send a packet int E1000Send(e1000_device_t* Device, const void* Data, uint16_t Length); - -#ifdef __cplusplus -} -#endif \ No newline at end of file diff --git a/inc/lainlib/lainlib.h b/inc/lainlib/lainlib.h index 5199581..f3c87ea 100644 --- a/inc/lainlib/lainlib.h +++ b/inc/lainlib/lainlib.h @@ -1,9 +1,5 @@ #pragma once -#ifdef __cplusplus -extern "C" { -#endif - /************************ *** Team Kitty, 2020 *** *** Chroma *** @@ -25,5 +21,5 @@ extern "C" { #include #ifdef __cplusplus -} // extern "C" +#include #endif \ No newline at end of file diff --git a/inc/lainlib/list/list.h b/inc/lainlib/list/list.h index e507e4d..fb9bc56 100644 --- a/inc/lainlib/list/list.h +++ b/inc/lainlib/list/list.h @@ -1,9 +1,5 @@ #include -#ifdef __cplusplus -extern "C" { -#endif - typedef struct list_entry { struct list_entry* Previous; struct list_entry* Next; @@ -36,7 +32,3 @@ bool ListIsEmpty(list_entry_t* Head); for(pos = UNSAFE_CAST((head)->next, typeof(*(pos)), member); &pos->member != (head); pos = LISTNEXT(pos, member)) #define LASTENTRY 0 - -#ifdef __cplusplus -} -#endif \ No newline at end of file diff --git a/inc/lainlib/mutex/spinlock.h b/inc/lainlib/mutex/spinlock.h index b2ceb58..99800d1 100644 --- a/inc/lainlib/mutex/spinlock.h +++ b/inc/lainlib/mutex/spinlock.h @@ -5,10 +5,6 @@ *** Chroma *** ***********************/ -#ifdef __cplusplus -extern "C" { -#endif - typedef volatile int spinlock_t; /* A set of macros that acquire and release a mutex spinlock. */ @@ -22,7 +18,3 @@ typedef volatile int spinlock_t; #define SPUNLOCK(name) \ __sync_synchronize(); \ name = 0; - -#ifdef __cplusplus -} -#endif \ No newline at end of file diff --git a/inc/lainlib/mutex/ticketlock.h b/inc/lainlib/mutex/ticketlock.h index 7b9bcaa..c5ecdc2 100644 --- a/inc/lainlib/mutex/ticketlock.h +++ b/inc/lainlib/mutex/ticketlock.h @@ -7,11 +7,6 @@ *** Chroma *** ***********************/ -#ifdef __cplusplus -extern "C" { -#endif - - /* This file provides a simple implementation of a ticket-based locking system. * You should probably prefer Spinlock over Ticketlock. * @@ -22,6 +17,10 @@ extern "C" { * */ +#ifdef __cplusplus +extern "C" { +#endif + typedef struct { size_t NowServing; size_t NextTicket; @@ -35,6 +34,6 @@ bool TicketAttemptLock(ticketlock_t* Lock); void TicketUnlock(ticketlock_t* Lock); -#ifdef __cplusplus +#ifdef __cplusplus } #endif \ No newline at end of file diff --git a/inc/lainlib/string/str.h b/inc/lainlib/string/str.h index 828eb6b..6d5f25e 100644 --- a/inc/lainlib/string/str.h +++ b/inc/lainlib/string/str.h @@ -6,14 +6,6 @@ *** Chroma *** ***********************/ -#ifdef __cplusplus -extern "C" { -#endif - size_t strlen(const char* String); -bool strcmp(char* a, const char* b); - -#ifdef __cplusplus -} -#endif \ No newline at end of file +bool strcmp(char* a, const char* b); \ No newline at end of file diff --git a/inc/lainlib/vector/vector.h b/inc/lainlib/vector/vector.h new file mode 100644 index 0000000..27e79e9 --- /dev/null +++ b/inc/lainlib/vector/vector.h @@ -0,0 +1,129 @@ +#pragma once +#include +#include +#include +#include + +/************************ + *** Team Kitty, 2022 *** + *** Lainlib *** + ***********************/ + +// integer typedefs +using u32 = uint32_t; + +namespace lainlib { + + template + struct vector { + T& operator [] (u32 i) { + return this->data[i]; + } + + T operator [] (u32 i) const { + return this->data[i]; + } + + u32 size() { + return bytes / sizeof(T); + } + + template + access_type handle_read(const void *buf) { + access_type v; + memcpy(&v,buf,sizeof(access_type)); + return v; + } + + template + void handle_write(void *buf, access_type v) { + memcpy(buf,&v,sizeof(access_type)); + } + + // insert at end as a var as a raw set of bytes into the Array + template + void emplace_back(Y v) { + const u32 len = sizeof(v); + + reserve(len); + + // actually write in the data + handle_write(&data[size()], v); + bytes += len; + } + + T pop() { + const T v = data[size() - 1]; + bytes -= sizeof(v); + + return v; + } + + void reserve_raw(u32 size) { + capacity = size; + data = (T*)krealloc(data, size); + } + + void resize(u32 in) { + const u32 len = in * sizeof(T); + + const u32 old_len = size(); + + reserve_raw( bytes); + bytes = len; + + // default initialize the new elements + for(u32 i = old_len; i < size(); i++) { + data[i] = {}; + } + } + + // make sure there is enough left for the allocation we are doing + void reserve(u32 size) { + const u32 free_size = capacity - bytes; + + // we have room to just dump this in + if(free_size >= size) { + return; + } else { + const u32 new_capacity = (capacity + size) * 2; + reserve_raw(new_capacity); + } + } + + // raw mem read and writes over the array + T read_var(u32 idx) { + return handle_read(data[idx]); + } + + template + void write_var(u32 idx, T v) { + return handle_write(data[idx], v); + } + + // insert raw memory block into the array + void push_mem(const void* newData, u32 size) + { + reserve(size); + + memcpy(data[bytes], newData, size); + bytes += size; + } + + void destroy() { + if(data) { + kfree(data); + data = nullptr; + } + + bytes = 0; + capacity = 0; + } + + T* data = nullptr; + + // in raw bytes + u32 bytes = 0; + u32 capacity = 0; + }; +} \ No newline at end of file diff --git a/src/drivers/devices/devices.cpp b/src/drivers/devices/devices.cpp index b19b0c2..26afc1e 100644 --- a/src/drivers/devices/devices.cpp +++ b/src/drivers/devices/devices.cpp @@ -22,7 +22,7 @@ Device::GenericStorage* StorageDevicesArray[MAX_STORAGE_DEVICES]; size_t CurrentStorageDevice = 0; // Internal storage. TODO: Make this not a pain to maintain -const char* DeviceNames[] = {"Storage", "Keyboard", "Networking"}; +const char* DeviceNames[] = {"Storage", "Internal", "Peripheral", "Networking"}; // Add a device pointer to the managed list. @@ -30,7 +30,7 @@ void Device::RegisterDevice(Device::GenericDevice* Device) { DevicesArray[CurrentDevice] = Device; Device->DeviceID = CurrentDevice; CurrentDevice++; - SerialPrintf("[DEVICE] Registered device %d called %s of type %s\r\n", CurrentDevice - 1, Device->GetName(), + SerialPrintf("[ DEV] Registered device %d called %s of type %s\r\n", CurrentDevice - 1, Device->GetName(), DeviceNames[Device->GetType()]); } diff --git a/src/drivers/devices/input/keyboard.cpp b/src/drivers/devices/input/keyboard.cpp deleted file mode 100644 index 35633e2..0000000 --- a/src/drivers/devices/input/keyboard.cpp +++ /dev/null @@ -1,160 +0,0 @@ -#include -#include - -/************************ - *** Team Kitty, 2020 *** - *** Chroma *** - ***********************/ - -#ifdef __cplusplus -extern "C" { -#endif - -/* This file contains (mostly unused) implementations of a full PS/2 keyboard driver. - * - * It provides provisions for full 2-way communication, as well as auxiliary key commands. - * //TODO: Media keys? - * - * Once this driver is to a workable state, I would like to start adding a proper keyboard buffer, - * which will integrate with a window system. - * - */ - -KBD_FLAGS KbdFlags; - -char keys[128] = { - 0, 27, - '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', '=', '\b', - '\t', 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', '[', ']', '\n', - 0, - 'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', '\'', '#', - 0, - '\\', 'z', 'x', 'c', 'v', 'b', 'n', 'm', ',', '.', '/', - 0, - '*', 0, - ' ', 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, - 0, - 0, - 0, - 0, - 0, - '-', - 0, - 0, - 0, - '+', - 0, - 0, - 0, - 0, - 0, - 0, 0, 0, - 0, - 0, - 0, -}; - -KeyboardCallback KeyboardCallbacks[16] = { - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL -}; - -static int CurrentCallback = 0; - -int SetupKBCallback(void (* Handler)(KeyboardData Frame)) { - KeyboardCallbacks[CurrentCallback++] = Handler; - return CurrentCallback; -} - -void UninstallKBCallback(int Number) { - KeyboardCallbacks[Number] = NULL; // 0 is used in the common check to make sure that the function is callable. - // This removes this callback from that check, ergo the function will no longer be called. -} - -void KbdEcho() { - if (!KbdFlags.EchoCount) { - if (!KbdFlags.Echo) { - Send8042(0xEE); - } - } else { - KbdFlags.EchoCount = 0; - KbdFlags.Echo = 0; - } -} - - -void UpdateKeyboard(uint8_t msg) { - - switch (msg) { - case 0x0: - KbdFlags.Error = 1; - //ResendBuffer(); - break; - case 0xAA: - KbdFlags.SelfTest = 1; - break; - case 0xEE: - KbdFlags.Echo = 0; - KbdFlags.EchoCount = 2; - KbdEcho(); - break; - case 0xFA: - KbdFlags.ACK = 1; - //ProgressBuffer(); - break; - case 0xFC: - case 0xFD: - KbdFlags.SelfTest = 0; - KbdFlags.Error = 1; - //RestartKbd(); - break; - case 0xFE: - //ResendBuffer(); - break; - case 0xFF: - KbdFlags.Error = 1; - //ResendBuffer(); - break; - default: - break; - } - - KeyboardData data = (KeyboardData) { - .Char = msg > 0x80 && msg < 0xD8 ? keys[msg - 0x80] : keys[msg], - .Scancode = static_cast(msg), - .Pressed = !(msg > 0x80 && msg < 0xD8), - }; - - void (* Handler)(KeyboardData data); - - for (size_t handlerNum = 0; handlerNum < 16; handlerNum++) { - Handler = KeyboardCallbacks[handlerNum]; - if (Handler) { - Handler(data); - } - } -} - -void Send8042(size_t info) { - for (size_t i = 0; i < 8; i++) { - unsigned char chr = (unsigned char) info; - if (chr != 0) { - WritePort(0x60, chr, 1); - WaitFor8042(); - } - } -} - -void WaitFor8042() { - - bool full = true; - while (full) { - full = ReadPort(0x64, 1) & 1; - } -} - -#ifdef __cplusplus -} -#endif \ No newline at end of file diff --git a/src/drivers/devices/io/apic.cpp b/src/drivers/devices/io/apic.cpp index 4b66963..4ded48d 100644 --- a/src/drivers/devices/io/apic.cpp +++ b/src/drivers/devices/io/apic.cpp @@ -59,6 +59,8 @@ bool APIC::IsReady() { } void APIC::Init() { + Device::RegisterDevice(this); + SerialPrintf("[ ACPI] Enabling APICs...\r\n"); Address = (void*) ACPI::MADT::instance->LocalAPICBase; diff --git a/src/drivers/devices/io/ps2_keyboard.cpp b/src/drivers/devices/io/ps2_keyboard.cpp new file mode 100644 index 0000000..fd11b2a --- /dev/null +++ b/src/drivers/devices/io/ps2_keyboard.cpp @@ -0,0 +1,168 @@ +#include +#include + +/************************ + *** Team Kitty, 2022 *** + *** Chroma *** + ***********************/ + +char keys[128] = { + 0, 27, + '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', '=', '\b', + '\t', 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', '[', ']', '\n', + 0, + 'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', '\'', '#', + 0, + '\\', 'z', 'x', 'c', 'v', 'b', 'n', 'm', ',', '.', '/', + 0, + '*', 0, + ' ', 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, + 0, + 0, + 0, + 0, + 0, + '-', + 0, + 0, + 0, + '+', + 0, + 0, + 0, + 0, + 0, + 0, 0, 0, + 0, + 0, + 0, +}; + +char shiftedKeys[128] = { + 0, + 0, // ESC + 33, // ! + 64, // @ + 35, // # + 36, // $ + 37, // % + 94, // ^ + 38, // & + 42, // * + 40, // ( + 41, // ) + 95, // _ + 43, // + + 0, + 0, + 81, // Q + 87, + 69, + 82, + 84, + 89, + 85, + 73, + 79, + 80, // P + 123, // { + 125, // } + 0, + 10, + 65, // A + 83, + 68, + 70, + 71, + 72, + 74, + 75, + 76, // L + 58, // : + 34, // " + 126, // ~ + 0, + 124, // | + 90, // Z + 88, + 67, + 86, + 66, + 78, + 77, // M + 60, // < + 62, // > + 63, // ? + 0, + 0, + 0, + 32, // SPACE +}; + +Device::PS2Keyboard* Device::PS2Keyboard::driver; + +using namespace Device; + +void IRQRedirect(INTERRUPT_FRAME* irq) { + UNUSED(irq); + PS2Keyboard::driver->InterruptHandler(); +} + +PS2Keyboard::PS2Keyboard() { + driver = this; +} + +void PS2Keyboard::setState(bool state, uint8_t key) { + keyStates[key] = state; + + if(state) + lastPress = key; + else + lastPress = 0; + + if(callback != nullptr) + callback[key] = state; +} + +bool PS2Keyboard::isPressed(uint8_t key) const { + return keyStates[key]; +} + +void PS2Keyboard::Init() { + Device::RegisterDevice(this); + buffer.reserve(100); + + for (size_t idx = 0; idx < 128; idx++) { + keyStates[idx] = false; + } + + InstallIRQ(1, IRQRedirect); +} + +void PS2Keyboard::InterruptHandler() { + uint8_t state = ReadPort(0x64, 1); + + // while keyboard has input and the buffer is not empty + while (state & 1 && !(state & 0x20)) { + uint8_t keycode = ReadPort(0x60, 1); + uint8_t scancode = keycode & 0x7f; + uint8_t keystate = !(keycode & 0x80); + + if (keystate) + SerialPrintf("[ KEY] %c pressed.\r\n", keys[scancode]); + + state = ReadPort(0x64, 1); + KeyboardData data { keys[scancode], (char) scancode, (bool) keystate }; + buffer.emplace_back(data); + } +} + +void PS2Keyboard::SetCallback(uint32_t* data) { + callback = (uint8_t*) data; + + for (size_t idx = 0; idx < 128; idx++) { + callback[idx] = false; + } +} diff --git a/src/drivers/elf.cpp b/src/drivers/elf.cpp index 1578363..89ab811 100644 --- a/src/drivers/elf.cpp +++ b/src/drivers/elf.cpp @@ -4,10 +4,6 @@ *** Chroma *** ***********************/ -#ifdef __cplusplus -extern "C" { -#endif - /* * This file provides utility functions for parsing ELF headers. * This exists so that the kernel can find itself for remapping, @@ -92,7 +88,3 @@ int ParseKernelHeader(size_t InitrdPtr) { return flag; } - -#ifdef __cplusplus -} -#endif \ No newline at end of file diff --git a/src/editor/EditorMain.cpp b/src/editor/EditorMain.cpp index 9497577..845862d 100644 --- a/src/editor/EditorMain.cpp +++ b/src/editor/EditorMain.cpp @@ -1,5 +1,4 @@ #include -#include #include #include @@ -11,11 +10,9 @@ /** * Contains startup and setup routines for the Chroma Editor. */ -static KeyboardCallback KernelHandler; void Editor::StartEditor(int callbackID) { - KernelHandler = KeyboardCallbacks[callbackID]; - + UNUSED(callbackID); EditorLayout layout; layout.ScreenHeight = PrintInfo.screenHeight; layout.ScreenWidth = PrintInfo.screenWidth; diff --git a/src/kernel.cpp b/src/kernel.cpp index 9a46742..afc5dfe 100644 --- a/src/kernel.cpp +++ b/src/kernel.cpp @@ -1,50 +1,41 @@ #include #include -#include #include #include "kernel/system/acpi/rsdt.h" #include "kernel/system/acpi/madt.h" #include "driver/io/apic.h" +#include "driver/io/ps2_keyboard.h" /************************ *** Team Kitty, 2020 *** *** Chroma *** ***********************/ -#ifdef __cplusplus -extern "C" { -#endif - /* This file is the entry point to the system. * It dictates the order of operations of everything the kernel actually does. * If a function isn't fired here, directly or indirectly, it is not run. */ -static bool KernelLoaded = false; +bool KernelLoaded = false; address_space_t KernelAddressSpace; size_t KernelAddr = (size_t) &LoadAddr; size_t KernelEnd = (size_t) &end; -void PrintPressedChar(KeyboardData data); int CharPrinterCallbackID; -void TrackInternalBuffer(KeyboardData data); +void TrackInternalBuffer(Device::GenericKeyboard::KeyboardData data); int InternalBufferID; size_t BufferLength = 0; char* InternalBuffer; -#ifdef __cplusplus -} -#endif - /** * C++ code! Scary! * This is a temporary measure to experiment with the Editor system. */ -extern "C" [[noreturn]] int Main(void) { +extern "C" int Main(void) { KernelAddressSpace.Lock.NextTicket = 0; KernelAddressSpace.Lock.NowServing = 0; KernelAddressSpace.PML4 = nullptr; @@ -72,9 +63,7 @@ extern "C" [[noreturn]] int Main(void) { PrepareCPU(); PCIEnumerate(); - InitMemoryManager(); - InitPaging(); Printf("Paging complete. System initialized.\n\r"); @@ -89,31 +78,20 @@ extern "C" [[noreturn]] int Main(void) { SetForegroundColor(0x00FFFFFF); Device::APIC::driver = new Device::APIC(); + Device::PS2Keyboard::driver = new Device::PS2Keyboard(); ACPI::RSDP::instance->Init(0); ACPI::MADT::instance->Init(); + Device::APIC::driver->Init(); + Device::PS2Keyboard::driver->Init(); Core::Init(); - CharPrinterCallbackID = SetupKBCallback(&PrintPressedChar); - - InternalBufferID = SetupKBCallback(&TrackInternalBuffer); - for (;;) { } } -extern "C" void PrintPressedChar(KeyboardData data) { - if (!KernelLoaded) return; - - if (data.Pressed) { - SerialPrintf("Key pressed: [\\%c (%x)]\r\n", data.Char, data.Scancode); - Printf("%c", data.Char); - } else { - SerialPrintf("Key released: [\\%c]\r\n", data.Char); - } -} - +/* extern "C" void TrackInternalBuffer(KeyboardData data) { if (!data.Pressed) return; @@ -147,8 +125,7 @@ extern "C" void TrackInternalBuffer(KeyboardData data) { InternalBuffer[BufferLength] = data.Char; BufferLength++; } -} - +}*/ extern "C" void SomethingWentWrong(const char* Message) { SerialPrintf("Assertion failed! %s\r\n", Message); diff --git a/src/lainlib/compression/lzgmini.c b/src/lainlib/compression/lzgmini.c index bb06ee8..4851a05 100644 --- a/src/lainlib/compression/lzgmini.c +++ b/src/lainlib/compression/lzgmini.c @@ -27,10 +27,6 @@ #include -#ifdef __cplusplus -extern "C" { -#endif - /*-- PRIVATE -----------------------------------------------------------------*/ /* Internal definitions */ @@ -191,8 +187,4 @@ lzg_uint32_t LZG_Decode(const unsigned char *in, lzg_uint32_t insize, return 0; else return decodedSize; -} - -#ifdef __cplusplus -} -#endif \ No newline at end of file +} \ No newline at end of file diff --git a/src/lainlib/ethernet/e1000/E1000Driver.c b/src/lainlib/ethernet/e1000/E1000Driver.c index 1829450..c5283c9 100644 --- a/src/lainlib/ethernet/e1000/E1000Driver.c +++ b/src/lainlib/ethernet/e1000/E1000Driver.c @@ -8,10 +8,6 @@ *** Lainlib *** ************************/ -#ifdef __cplusplus -extern "C" { -#endif - /** * This file handles all the logic for interfacing with the E1000 networking device. * This card is labelled either the Intel I217, or Intel Gigabit 82577LM. @@ -355,7 +351,3 @@ int E1000Send(e1000_device_t* Device, const void* Data, uint16_t Length) { return 0; } - -#ifdef __cplusplus -} -#endif \ No newline at end of file diff --git a/src/lainlib/ethernet/ethernet.h b/src/lainlib/ethernet/ethernet.h index 0ddb69c..e38e3b4 100644 --- a/src/lainlib/ethernet/ethernet.h +++ b/src/lainlib/ethernet/ethernet.h @@ -5,9 +5,6 @@ *** Lainlib *** ***********************/ -#ifdef __cplusplus -extern "C" { -#endif struct mac_address { uint8_t MAC[6]; @@ -25,7 +22,3 @@ struct ethernet_packet { uint16_t Type; uint8_t Payload[]; }; - -#ifdef __cplusplus -} -#endif \ No newline at end of file diff --git a/src/lainlib/list/basic_list.cpp b/src/lainlib/list/basic_list.cpp index 2d473af..c1f7664 100644 --- a/src/lainlib/list/basic_list.cpp +++ b/src/lainlib/list/basic_list.cpp @@ -1,8 +1,5 @@ #include -#ifdef __cplusplus -extern "C" { -#endif void ListAdd(list_entry_t* Head, list_entry_t* New) { New->Next = Head->Next; @@ -29,7 +26,3 @@ void ListRemove(list_entry_t* Entry) { bool ListIsEmpty(list_entry_t* Head) { return Head->Next == Head; } - -#ifdef __cplusplus -} -#endif \ No newline at end of file diff --git a/src/lainlib/mutex/ticketlock.cpp b/src/lainlib/mutex/ticketlock.cpp index 69ac136..4f0b7c8 100644 --- a/src/lainlib/mutex/ticketlock.cpp +++ b/src/lainlib/mutex/ticketlock.cpp @@ -2,14 +2,12 @@ #define PAUSE __asm__ __volatile__("pause") -#ifdef __cplusplus extern "C" { -#endif void TicketLock(ticketlock_t* Lock) { size_t Ticket = __atomic_fetch_add(&Lock->NextTicket, 1, __ATOMIC_RELAXED); __sync_synchronize(); - while(__atomic_load_8(&Lock->NowServing, __ATOMIC_ACQUIRE) != Ticket) { + while (__atomic_load_8(&Lock->NowServing, __ATOMIC_ACQUIRE) != Ticket) { PAUSE; } } @@ -17,7 +15,8 @@ void TicketLock(ticketlock_t* Lock) { bool TicketAttemptLock(ticketlock_t* Lock) { size_t Ticket = __atomic_load_8(&Lock->NowServing, __ATOMIC_RELAXED); __sync_synchronize(); - return __atomic_compare_exchange_8(&Lock->NowServing, &Ticket, Ticket + 1, false, __ATOMIC_ACQUIRE, __ATOMIC_RELAXED); + return __atomic_compare_exchange_8(&Lock->NowServing, &Ticket, Ticket + 1, false, __ATOMIC_ACQUIRE, + __ATOMIC_RELAXED); } void TicketUnlock(ticketlock_t* Lock) { @@ -26,6 +25,4 @@ void TicketUnlock(ticketlock_t* Lock) { __atomic_store_8(&Lock->NowServing, NextTicket, __ATOMIC_RELEASE); } -#ifdef __cplusplus -} -#endif \ No newline at end of file +} \ No newline at end of file diff --git a/src/lainlib/string/str.cpp b/src/lainlib/string/str.cpp index f360b53..840a7b1 100644 --- a/src/lainlib/string/str.cpp +++ b/src/lainlib/string/str.cpp @@ -7,10 +7,6 @@ *** Lainlib *** ***********************/ -#ifdef __cplusplus -extern "C" { -#endif - size_t strlen(const char* String) { size_t Len = 0; while(String[Len] != '\0') { @@ -28,7 +24,3 @@ bool strcmp(char* a, const char* b) { bI++; } } - -#ifdef __cplusplus -} -#endif \ No newline at end of file diff --git a/src/lainlib/vector/vector.cpp b/src/lainlib/vector/vector.cpp new file mode 100644 index 0000000..b206489 --- /dev/null +++ b/src/lainlib/vector/vector.cpp @@ -0,0 +1,6 @@ +#include + +/************************ + *** Team Kitty, 2022 *** + *** Lainlib *** + ***********************/ diff --git a/src/system/core.cpp b/src/system/core.cpp index 0b55745..4f4c80c 100644 --- a/src/system/core.cpp +++ b/src/system/core.cpp @@ -98,20 +98,7 @@ void Core::Bootstrap() { } void Core::SetupData(size_t Core) { - // Write page tables - GetCore(Core)->AddressSpace->PML4 = GetCurrent()->AddressSpace->PML4; - *((size_t*) Initialization::PAGETABLES) = (size_t) GetCore(Core)->AddressSpace->PML4; - - // Prepare stack - memset(GetCore(Core)->StackData, 0, Constants::Core::STACK_SIZE); - *((size_t*) Initialization::STACK) = (size_t) GetCore(Core)->StackData + Constants::Core::STACK_SIZE; - - // GDT = 0x680 - // IDT = 0x690 - __asm__ __volatile__("sgdt (0x680)\n sidt (0x690)"); - - // Set startup address - *((size_t*) Initialization::STARTUP) = (size_t) &initcpu; + UNUSED(Core); } diff --git a/src/system/cpu.cpp b/src/system/cpu.cpp index bb926b9..c118df6 100644 --- a/src/system/cpu.cpp +++ b/src/system/cpu.cpp @@ -6,10 +6,6 @@ *** Chroma *** ***********************/ -#ifdef __cplusplus -extern "C" { -#endif - /* This class provides functions for setting up and preparing the CPU for the things the kernel will do. * Mainly, it allows you to: * @@ -70,7 +66,6 @@ static void RefreshCS() { void PrepareCPU() { - SetupInitialGDT(); SetupIDT(); //SetupExtensions(); @@ -227,13 +222,10 @@ void SetupIDT() { SetISR(46, (size_t) IRQ14Handler); SetISR(47, (size_t) IRQ15Handler); - - //TODO: ISRs 32 to 256 + for (size_t i = 0; i < 32; i++) { + IRQHandlers[i] = {{}, 0 }; + } WriteIDT(IDTData); -} - -#ifdef __cplusplus -} -#endif \ No newline at end of file +} \ No newline at end of file diff --git a/src/system/interrupts.cpp b/src/system/interrupts.cpp index 60baee6..1b2db70 100644 --- a/src/system/interrupts.cpp +++ b/src/system/interrupts.cpp @@ -8,10 +8,6 @@ *** Chroma *** ***********************/ -#ifdef __cplusplus -extern "C" { -#endif - /* This file contains all of the ISR and IRQ * (Interrupt Service Request) functions. * @@ -41,6 +37,10 @@ extern "C" { * these having a size_t input as an error code. */ +#ifdef __cplusplus +extern "C" { +#endif + const char* ExceptionStrings[] = { "Division by Zero", "Debug", @@ -76,15 +76,7 @@ const char* ExceptionStrings[] = { "Reserved" }; -typedef void (* IRQHandler)(INTERRUPT_FRAME* Frame); - -IRQHandler IRQ_Handlers[16] = { - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL -}; - - -typedef unsigned long long int uword_t; +IRQHandlerData IRQHandlers[32]; /* All of the ISR routines call this function for now. ! This function is NOT leaf, and it might clobber the stack. @@ -124,114 +116,105 @@ void ISR_Error_Common(INTERRUPT_FRAME* Frame, size_t ErrorCode, size_t Exception which was set up earlier by irq_install.*/ void IRQ_Common(INTERRUPT_FRAME* Frame, size_t Interrupt) { // First we need to define a function pointer.. - void (* Handler)(INTERRUPT_FRAME* Frame); + IRQHandlerData handler; /* We set all uninitialized routines to 0, so the if(handler) check here allows us to safely tell whether we've actually got something for this IRQ. */ - Handler = IRQ_Handlers[Interrupt]; - // If there's something there, - if (Handler) { + handler = IRQHandlers[Interrupt]; + if (handler.numHandlers > 0) { SerialPrintf("[ IRQ] IRQ %d raised!\r\n", Interrupt); - // Call the handler. - Handler(Frame); + // Call the handlers + for (size_t i = 0; i < handler.numHandlers; i++) + handler.handlers[i](Frame); } + /* The Slave PIC must be told it's been read in order to receive another 8+ IRQ. */ if (Interrupt > 7) WritePort(0xA0, 0x20, 1); /* In either case, we tell the Master PIC it's been read to receive any IRQ. */ WritePort(0x20, 0x20, 1); +} +#define PIC1 0x20 /* IO base address for master PIC */ +#define PIC2 0xA0 /* IO base address for slave PIC */ +#define PIC1_COMMAND PIC1 +#define PIC1_DATA (PIC1+1) +#define PIC2_COMMAND PIC2 +#define PIC2_DATA (PIC2+1) +#define ICW1_ICW4 0x01 /* ICW4 (not) needed */ +#define ICW1_SINGLE 0x02 /* Single (cascade) mode */ +#define ICW1_INTERVAL4 0x04 /* Call address interval 4 (8) */ +#define ICW1_LEVEL 0x08 /* Level triggered (edge) mode */ +#define ICW1_INIT 0x10 /* Initialization - required! */ + +#define ICW4_8086 0x01 /* 8086/88 (MCS-80/85) mode */ +#define ICW4_AUTO 0x02 /* Auto (normal) EOI */ +#define ICW4_BUF_SLAVE 0x08 /* Buffered mode/slave */ +#define ICW4_BUF_MASTER 0x0C /* Buffered mode/master */ +#define ICW4_SFNM 0x10 /* Special fully nested (not) */ + +void ClearIRQ(size_t idx) { + uint16_t port; + uint8_t value; + + if(idx < 8) { + port = PIC1_DATA; + } else { + port = PIC2_DATA; + idx -= 8; + } + value = ReadPort(port, 1) & ~(1 << idx); + WritePort(port, value, 1); } /* However, in order to actually be able to receive IRQs, we need to remap the PICs. */ void RemapIRQControllers() { /* 0x20 is the Master PIC, 0xA0 is the Slave PIC. */ - WritePort(0x20, 0x11, 1); - WritePort(0xA0, 0x11, 1); - WritePort(0x21, 0x20, 1); - WritePort(0xA1, 0x28, 1); - WritePort(0x21, 0x04, 1); - WritePort(0xA1, 0x02, 1); - WritePort(0x21, 0x01, 1); - WritePort(0xA1, 0x01, 1); - WritePort(0x21, 0x0, 1); - WritePort(0xA1, 0x0, 1); + unsigned char a1, a2; + + a1 = ReadPort(PIC1_DATA, 1); // save masks + a2 = ReadPort(PIC2_DATA, 1); + + WritePort(PIC1_COMMAND, ICW1_INIT | ICW1_ICW4, 1); // starts the initialization sequence (in cascade mode) + WritePort(PIC2_COMMAND, ICW1_INIT | ICW1_ICW4, 1); + WritePort(PIC1_DATA, 32, 1); // ICW2: Master PIC vector offset + WritePort(PIC2_DATA, 32 + 8, 1); // ICW2: Slave PIC vector offset + WritePort(PIC1_DATA, 4, 1); // ICW3: tell Master PIC that there is a slave PIC at IRQ2 (0000 0100) + WritePort(PIC2_DATA, 2, 1); // ICW3: tell Slave PIC its cascade identity (0000 0010) + + WritePort(PIC1_DATA, ICW4_8086, 1); + WritePort(PIC2_DATA, ICW4_8086, 1); + + WritePort(PIC1_DATA, a1, 1); // restore saved masks. + WritePort(PIC2_DATA, a2, 1); + + ClearIRQ(1); + ClearIRQ(2); } /* In order to actually handle the IRQs, though, we need to tell the kernel *where* the handlers are. */ /* A simple wrapper that adds a function pointer to the IRQ array. */ -void InstallIRQ(int IRQ, void (* Handler)(INTERRUPT_FRAME* Frame)) { - IRQ_Handlers[IRQ] = Handler; +size_t InstallIRQ(int IRQ, IRQHandler Handler) { + if (IRQ <= 32) { + IRQHandlerData* target = &IRQHandlers[IRQ]; + if (target->numHandlers < 7) { + target->handlers[target->numHandlers] = Handler; + target->numHandlers++; + return target->numHandlers; + } + } + + return 0; } /* A simple wrapper that unlinks a function pointer, rendering the IRQ unused. */ -void UninstallIRQHandler(int IRQ) { - IRQ_Handlers[IRQ] = NULL; // 0 is used in the common check to make sure that the function is callable. +void UninstallIRQHandler(int IRQ, size_t ID) { + IRQHandlers[IRQ].handlers[ID] = NULL; // 0 is used in the common check to make sure that the function is callable. // This removes this IRQ from that check, ergo the function will no longer be called. } -void EmptyIRQ(INTERRUPT_FRAME* frame) { - - UNUSED(frame); - - // Flash the borders green, then back to blue - SetForegroundColor(0x0000FF00); - for (size_t y = 0; y < bootldr.fb_height; y++) { - for (size_t x = 0; x < 20; x++) { - DrawPixel(x, y); - } - - for (size_t x = (bootldr.fb_width - 20); x < bootldr.fb_width; x++) { - DrawPixel(x, y); - } - } - - for (size_t x = 0; x < bootldr.fb_width; x++) { - for (size_t y = 0; y < 20; y++) { - DrawPixel(x, y); - } - - for (size_t y = (bootldr.fb_height - 20); y < bootldr.fb_height; y++) { - DrawPixel(x, y); - } - } - - for (size_t i = 0; i < 100000; i++) { } - - SetForegroundColor(0x000000FF); - for (size_t y = 0; y < bootldr.fb_height; y++) { - for (size_t x = 0; x < 20; x++) { - DrawPixel(x, y); - } - - for (size_t x = (bootldr.fb_width - 20); x < bootldr.fb_width; x++) { - DrawPixel(x, y); - } - } - - for (size_t x = 0; x < bootldr.fb_width; x++) { - for (size_t y = 0; y < 20; y++) { - DrawPixel(x, y); - } - - for (size_t y = (bootldr.fb_height - 20); y < bootldr.fb_height; y++) { - DrawPixel(x, y); - } - } -} - -static void KeyboardCallback(INTERRUPT_FRAME* frame) { - UNUSED(frame); - - uint8_t msg = ReadPort(0x60, 1); - - UpdateKeyboard(msg); - - WaitFor8042(); -} - void InitInterrupts() { size_t RFLAGS = ReadControlRegister('f'); @@ -239,11 +222,6 @@ void InitInterrupts() { WriteControlRegister('f', RFLAGS | (1 << 9)); } - - InstallIRQ(1, &KeyboardCallback); - - Send8042(0xF002); - __asm__ __volatile__("sti"); } @@ -451,6 +429,7 @@ __attribute__((interrupt)) void IRQ0Handler(INTERRUPT_FRAME* Frame) { } __attribute__((interrupt)) void IRQ1Handler(INTERRUPT_FRAME* Frame) { + SerialPrintf("IRQ1\r\n"); IRQ_Common(Frame, 1); // Keyboard handler } @@ -510,6 +489,6 @@ __attribute__((interrupt)) void IRQ15Handler(INTERRUPT_FRAME* Frame) { IRQ_Common(Frame, 15); } -#ifdef __cplusplus +#ifdef __cplusplus } #endif \ No newline at end of file diff --git a/src/system/memory/abstract_allocator.cpp b/src/system/memory/abstract_allocator.cpp index 739059b..3e5558b 100644 --- a/src/system/memory/abstract_allocator.cpp +++ b/src/system/memory/abstract_allocator.cpp @@ -7,10 +7,6 @@ *** Chroma *** ***********************/ -#ifdef __cplusplus -extern "C" { -#endif - /************************************************ * C O N S T A N T S A N D M A C R O S *************************************************/ @@ -136,10 +132,6 @@ static void BlockSetSize(block_header_t* Block, size_t Size) { Block->Size = Size | (Block->Size & (BLOCK_FREE | BLOCK_PREV_FREE)); } -static int BlockIsLast(const block_header_t* Block) { - return BlockSize(Block) == 0; -} - static int BlockIsFree(const block_header_t* Block) { return CAST(int, Block->Size & BLOCK_FREE); } @@ -177,13 +169,11 @@ static block_header_t* OffsetToBlock(const void* Address, size_t Size) { } static block_header_t* BlockGetPrevious(const block_header_t* Current) { - ASSERT(BlockPrevIsFree(Current), "BlockGetPrevious: Previous block NOT free"); return Current->LastBlock; } static block_header_t* BlockGetNext(const block_header_t* Current) { block_header_t* NextBlock = OffsetToBlock(WhereBlock(Current), BlockSize(Current) - BLOCK_OVERHEAD); - ASSERT(!BlockIsLast(Current), "BlockGetNext: Current block is last!"); return NextBlock; } @@ -210,17 +200,17 @@ static void BlockMarkUsed(block_header_t* Current) { * P O I N T E R A L I G N M E N T F U N C T I O N S ************************************************************************************/ -size_t AlignUpwards(size_t Pointer, size_t Alignment) { +extern "C" size_t AlignUpwards(size_t Pointer, size_t Alignment) { //ASSERT(((Alignment & (Alignment - 1)) == 0)); return (Pointer + (Alignment - 1)) & ~(Alignment - 1); } -size_t AlignDownwards(size_t Pointer, size_t Alignment) { +extern "C" size_t AlignDownwards(size_t Pointer, size_t Alignment) { //ASSERT((Alignment & (Alignment - 1) == 0)); return (Pointer - (Pointer & (Alignment - 1))); } -void* AlignPointer(const void* Pointer, size_t Alignment) { +extern "C" void* AlignPointer(const void* Pointer, size_t Alignment) { const ptrdiff_t AlignedPointer = (( @@ -228,7 +218,6 @@ void* AlignPointer(const void* Pointer, size_t Alignment) { + (Alignment - 1)) & ~(Alignment - 1) ); - ASSERT(((Alignment & (Alignment - 1)) == 0), "AlignPointer: Requested alignment not aligned!"); return CAST(void*, AlignedPointer); } @@ -297,8 +286,6 @@ static block_header_t* FindSuitableBlock(allocator_control_t* Controller, int* F SLMap = Controller->SecondLevel_Bitmap[FirstLevel]; } - ASSERT(SLMap, "FindSuitableBlock: Second level bitmap not present!"); - SecondLevel = Alloc_FindFirstOne(SLMap); *SecondLevelIndex = SecondLevel; @@ -309,9 +296,6 @@ static void RemoveFreeBlock(allocator_control_t* Controller, block_header_t* Blo block_header_t* PreviousBlock = Block->LastFreeBlock; block_header_t* NextBlock = Block->NextFreeBlock; - ASSERT(PreviousBlock, "RemoveFreeBlock: PreviousBlock is null!"); - ASSERT(NextBlock, "RemoveFreeBlock: NextBlock is null!"); - NextBlock->LastFreeBlock = PreviousBlock; PreviousBlock->NextFreeBlock = NextBlock; @@ -332,7 +316,6 @@ static void InsertFreeBlock(allocator_control_t* Controller, block_header_t* NewBlock, int FirstLevel, int SecondLevel) { block_header_t* Current = Controller->Blocks[FirstLevel][SecondLevel]; - ASSERT(Current, "InsertFreeBlock: Current Block is null!"); if (!Current) { SerialPrintf( "Extra info: \r\n\tFirst Level: %x Second Level: %x\r\nFirst Level bitmap: %x, Second Level bitmap: %x\r\n\tBlocks %x, BlocksAddress: %x", @@ -340,16 +323,12 @@ InsertFreeBlock(allocator_control_t* Controller, block_header_t* NewBlock, int F Controller->Blocks, Controller->Blocks[FirstLevel][SecondLevel]); for (;;) { } } - ASSERT(NewBlock, "InsertFreeBlock: New Block is null!"); NewBlock->NextFreeBlock = Current; NewBlock->LastFreeBlock = &Controller->BlockNull; Current->LastFreeBlock = NewBlock; - ASSERT(WhereBlock(NewBlock) == AlignPointer(WhereBlock(NewBlock), ALIGN_SIZE), - "InsertFreeBlock: Current block is not memory aligned!"); - Controller->Blocks[FirstLevel][SecondLevel] = NewBlock; Controller->FirstLevel_Bitmap |= (1U << FirstLevel); Controller->SecondLevel_Bitmap[FirstLevel] |= (1U << SecondLevel); @@ -378,15 +357,8 @@ static block_header_t* SplitBlock(block_header_t* Block, size_t NewSize) { const size_t RemainingSize = BlockSize(Block) - (NewSize + BLOCK_OVERHEAD); - ASSERT(WhereBlock(Overlap) == AlignPointer(WhereBlock(Overlap), ALIGN_SIZE), - "SplitBlock: Requested size results in intermediary block which is not aligned!"); - - ASSERT(BlockSize(Block) == RemainingSize + NewSize + BLOCK_OVERHEAD, "SplitBlock: Maths error!"); - BlockSetSize(Overlap, RemainingSize); - ASSERT(BlockSize(Overlap) >= BLOCK_MIN_SIZE, "SplitBlock: Requested size results in new block that is too small!"); - BlockSetSize(Block, NewSize); BlockMarkFree(Overlap); @@ -395,7 +367,6 @@ static block_header_t* SplitBlock(block_header_t* Block, size_t NewSize) { } static block_header_t* MergeBlockDown(block_header_t* Previous, block_header_t* Block) { - ASSERT(!BlockIsLast(Previous), "MergeBlockDown: Previous block is the last block! (Current block is first block?)"); Previous->Size += BlockSize(Block) + BLOCK_OVERHEAD; BlockLinkToNext(Previous); @@ -406,8 +377,6 @@ static block_header_t* MergeEmptyBlockDown(allocator_control_t* Controller, bloc if (BlockPrevIsFree(Block)) { block_header_t* Previous = BlockGetPrevious(Block); - ASSERT(Previous, "MergeEmptyBlockDown: Previous block is null!"); - ASSERT(BlockIsFree(Previous), "MergeEmptyBlockDown: Previous block is free!"); RemoveBlock(Controller, Previous); Block = MergeBlockDown(Previous, Block); } @@ -417,10 +386,8 @@ static block_header_t* MergeEmptyBlockDown(allocator_control_t* Controller, bloc static block_header_t* MergeNextBlockDown(allocator_control_t* Controller, block_header_t* Block) { block_header_t* NextBlock = BlockGetNext(Block); - ASSERT(NextBlock, "MergeNextBlockDown: Next Block is null!"); if (BlockIsFree(NextBlock)) { - ASSERT(!BlockIsLast(Block), "MergeNextBlockDown: Current block is the last block!"); RemoveBlock(Controller, NextBlock); Block = MergeBlockDown(Block, NextBlock); } @@ -429,7 +396,6 @@ static block_header_t* MergeNextBlockDown(allocator_control_t* Controller, block } static void TrimBlockFree(allocator_control_t* Controller, block_header_t* Block, size_t Size) { - ASSERT(BlockIsFree(Block), "TrimBlockFree: Current block is wholly free!"); if (CanBlockSplit(Block, Size)) { block_header_t* RemainingBlock = SplitBlock(Block, Size); @@ -443,8 +409,6 @@ static void TrimBlockFree(allocator_control_t* Controller, block_header_t* Block } static void TrimBlockUsed(allocator_control_t* Controller, block_header_t* Block, size_t Size) { - ASSERT(!BlockIsFree(Block), "TrimBlockUsed: The current block is wholly used!"); - if (CanBlockSplit(Block, Size)) { block_header_t* RemainingBlock = SplitBlock(Block, Size); @@ -490,7 +454,6 @@ static block_header_t* LocateFreeBlock(allocator_control_t* Controller, size_t S } if (Block) { - ASSERT(BlockSize(Block) >= Size, "LocateFreeBlock: Found a block that is too small!"); RemoveFreeBlock(Controller, Block, FirstLevel, SecondLevel); } @@ -501,7 +464,6 @@ static void* PrepareUsedBlock(allocator_control_t* Controller, block_header_t* B void* Pointer = 0; if (Block) { - ASSERT(Size, "PrepareUsedBlock: Size is 0!"); TrimBlockFree(Controller, Block, Size); BlockMarkUsed(Block); Pointer = WhereBlock(Block); @@ -614,10 +576,6 @@ void RemovePoolFromAllocator(allocator_t Allocator, mempool_t Pool) { int FirstLevel = 0, SecondLevel = 0; - ASSERT(BlockIsFree(Block), "RemovePoolFromAllocator: Current block is free!"); - ASSERT(!BlockIsFree(BlockGetNext(Block)), "RemovePoolFromAllocator: Next Block is not free!"); - ASSERT(BlockSize(BlockGetNext(Block)) == 0, "RemovePoolFromAllocator: Next block is size 0!"); - RoundUpBlockSize(BlockSize(Block), &FirstLevel, &SecondLevel); RemoveFreeBlock(Controller, Block, FirstLevel, SecondLevel); } @@ -700,8 +658,6 @@ void* AllocatorMalign(allocator_t Allocator, size_t Alignment, size_t Size) { block_header_t* Block = LocateFreeBlock(Controller, AlignedSize); - ASSERT(sizeof(block_header_t) == BLOCK_MIN_SIZE + BLOCK_OVERHEAD, "AllocatorMalign: Maths error!"); - if (Block) { void* Address = WhereBlock(Block); void* AlignedAddress = AlignPointer(Address, Alignment); @@ -719,8 +675,6 @@ void* AllocatorMalign(allocator_t Allocator, size_t Alignment, size_t Size) { Gap = CAST(size_t, CAST(ptrdiff_t, AlignedAddress) - CAST(ptrdiff_t, Address)); } - ASSERT(Gap >= MinimumGap, "AllocatorMalign: Maths error 2!"); - Block = TrimBlockLeadingFree(Controller, Block, Gap); } @@ -733,7 +687,6 @@ void AllocatorFree(allocator_t Allocator, void* Address) { if (Address) { allocator_control_t* Controller = CAST(allocator_control_t*, Allocator); block_header_t* Block = WhichBlock(Address); - ASSERT(!BlockIsFree(Block), "AllocatorFree: Attempting to free a freed block!"); BlockMarkFree(Block); Block = MergeEmptyBlockDown(Controller, Block); @@ -778,8 +731,6 @@ void* AllocatorRealloc(allocator_t Allocator, void* Address, size_t NewSize) { const size_t AdjustedSize = AlignRequestSize(NewSize, ALIGN_SIZE); - ASSERT(!BlockIsFree(Block), "AllocatorRealloc: Requested block is not free!"); - if (AdjustedSize > CurrentSize && (!BlockIsFree(NextBlock) || AdjustedSize > CombinedSize)) { // We're going to need more room @@ -802,7 +753,3 @@ void* AllocatorRealloc(allocator_t Allocator, void* Address, size_t NewSize) { return Pointer; } - -#ifdef __cplusplus -} -#endif \ No newline at end of file diff --git a/src/system/memory/liballoc.cpp b/src/system/memory/liballoc.cpp index 59f7115..740bfe1 100644 --- a/src/system/memory/liballoc.cpp +++ b/src/system/memory/liballoc.cpp @@ -3,10 +3,6 @@ /** Durand's Amazing Super Duper Memory functions. */ -#ifdef __cplusplus -extern "C" { -#endif - #define VERSION "1.1" #define ALIGNMENT 16ul//4ul ///< This is the byte alignment that memory must be allocated on. IMPORTANT for GTK and other stuff. @@ -814,10 +810,6 @@ void* PREFIX(realloc)(void* p, size_t size) { return ptr; } -#ifdef __cplusplus -} -#endif - void operator delete(void* addr, unsigned long __attribute__((unused)) size) { PREFIX(free)(addr); } diff --git a/src/system/memory/paging.cpp b/src/system/memory/paging.cpp index 54bf2a4..4b33cf1 100644 --- a/src/system/memory/paging.cpp +++ b/src/system/memory/paging.cpp @@ -5,10 +5,6 @@ *** Chroma *** ***********************/ -#ifdef __cplusplus -extern "C" { -#endif - #define PAGE_TABLES_GET_PDPT(address) \ (address & ((size_t) 0x1FF << 39)) >> 39 #define PAGE_TABLES_GET_PDP(address) \ @@ -353,10 +349,6 @@ size_t* CreateNewPageTable(address_space_t* AddressSpace) { return NewPML4; } -#ifdef __cplusplus -} -#endif - void *operator new(size_t size) { return kmalloc(size); } diff --git a/src/system/memory/physmem.c b/src/system/memory/physmem.c index 4a6cbf5..c2b4764 100644 --- a/src/system/memory/physmem.c +++ b/src/system/memory/physmem.c @@ -1,17 +1,11 @@ #include #include - /************************ *** Team Kitty, 2020 *** *** Chroma *** ***********************/ - -#ifdef __cplusplus -extern "C" { -#endif - /* This file contains functions for physical memory management. * * Physical Memory Management is performed with Buddy List allocators, which are one of the most performant systems available. @@ -22,6 +16,9 @@ extern "C" { * TODO: Document this mess. */ +#ifdef __cplusplus +extern "C" { +#endif #define MIN_ORDER 3 #define PEEK(type, address) (*((volatile type*)(address))) @@ -347,6 +344,6 @@ void* memset(void* dst, int src, size_t len) { return dst; } -#ifdef __cplusplus +#ifdef __cplusplus } #endif \ No newline at end of file diff --git a/src/system/pci.cpp b/src/system/pci.cpp index f579f80..3d593a0 100644 --- a/src/system/pci.cpp +++ b/src/system/pci.cpp @@ -5,10 +5,6 @@ *** Chroma *** ***********************/ -#ifdef __cplusplus -extern "C" { -#endif - /* This file contains functions for accessing the PCI bus, * and devices contained wherein. * @@ -750,8 +746,4 @@ const char* PCIGetClassName(uint8_t DeviceClass) { } return "Invalid device!"; -} - -#ifdef __cplusplus -} -#endif \ No newline at end of file +} \ No newline at end of file diff --git a/src/system/rw.cpp b/src/system/rw.cpp index 74ca152..cde6794 100644 --- a/src/system/rw.cpp +++ b/src/system/rw.cpp @@ -5,10 +5,6 @@ *** Chroma *** ***********************/ -#ifdef __cplusplus -extern "C" { -#endif - /* This file serves to allow us to communicate with the computer through raw I/O. * It provides interfaces for Ports and commonly used Registers (Control Registers, Model-Specific Registers, GDT, IDT..) * @@ -257,8 +253,3 @@ void WriteTSR(uint16_t TSRData) { __asm__ __volatile__("ltr %[src]" : : [src] "m"(TSRData) :); } - - -#ifdef __cplusplus -} -#endif \ No newline at end of file diff --git a/src/system/serial.cpp b/src/system/serial.cpp index 5c73fba..9ac90e6 100644 --- a/src/system/serial.cpp +++ b/src/system/serial.cpp @@ -4,10 +4,6 @@ *** Chroma *** ***********************/ -#ifdef __cplusplus -extern "C" { -#endif - /* This file provides functions related to the Serial port. * Through this file, you send and receive text and extra debugging information if available. */ @@ -49,8 +45,4 @@ void WriteSerialString(const char* str, size_t len) { for (size_t i = 0; i < len; i++) { WriteSerialChar(str[i]); } -} - -#ifdef __cplusplus -} -#endif \ No newline at end of file +} \ No newline at end of file diff --git a/src/video/draw.cpp b/src/video/draw.cpp index d7c17ea..c77f45e 100644 --- a/src/video/draw.cpp +++ b/src/video/draw.cpp @@ -7,10 +7,6 @@ *** Chroma *** ***********************/ -#ifdef __cplusplus -extern "C" { -#endif - /** * This file contains all of the draw-to-screen routines. * It (currently; 23/08/20) handles the keyboard input test routine, @@ -478,7 +474,3 @@ void DrawFilledCircle(size_t centerX, size_t centerY, size_t radius) { DrawVerticalLine(centerX, centerY - radius, 2 * radius + 1); DrawFilledCircleInternal(centerX, centerY, radius, 3, 0); } - -#ifdef __cplusplus -} -#endif \ No newline at end of file diff --git a/src/video/print.cpp b/src/video/print.cpp index b85f81a..5caaee1 100644 --- a/src/video/print.cpp +++ b/src/video/print.cpp @@ -6,10 +6,6 @@ *** Chroma *** ***********************/ -#ifdef __cplusplus -extern "C" { -#endif - /* This file contains all of the String / Print related functions * that are required by the core of the kernel. * @@ -36,7 +32,7 @@ void NumToStr(char* Buffer, size_t Num, size_t Base) { } -int SerialPrintf(const char* Format, ...) { +extern "C" int SerialPrintf(const char* Format, ...) { va_list Parameters; va_start(Parameters, Format); @@ -283,7 +279,3 @@ size_t ParseHexColor(const char* Stream, bool bgFlag) { } return val; } - -#ifdef __cplusplus -} -#endif \ No newline at end of file