diff --git a/Drivers/audio/ac97/Makefile b/Drivers/audio/ac97/Makefile deleted file mode 100644 index 9a92e2ef..00000000 --- a/Drivers/audio/ac97/Makefile +++ /dev/null @@ -1,35 +0,0 @@ -default: - $(error Do not run this Makefile directly!) - -S_SOURCES = $(shell find ./ -type f -name '*.S') -C_SOURCES = $(shell find ./ -type f -name '*.c') -CXX_SOURCES = $(shell find ./ -type f -name '*.cpp') -HEADERS = $(sort $(dir $(wildcard ../../include/*))) -OBJ = $(C_SOURCES:.c=.o) $(CXX_SOURCES:.cpp=.o) $(S_SOURCES:.S=.o) -STACK_USAGE_OBJ = $(C_SOURCES:.c=.su) $(CXX_SOURCES:.cpp=.su) - -FILENAME = $(notdir $(shell pwd)).drv - -build: $(FILENAME) - mv $(FILENAME) $(OUTPUT_DIR)$(FILENAME) - -$(FILENAME): $(OBJ) - $(info Linking $@) - $(CC) $(DRIVER_LDFLAGS) $(OBJ) $(OUTPUT_DIR)dcrt0.o -L$(OUTPUT_DIR) -lkernel -o $@ - -WARNCFLAG = -Wall -Wextra - -%.o: %.c $(HEADERS) - $(info Compiling $<) - $(CC) $(DRIVER_CFLAGS) $(WARNCFLAG) -std=c17 -c $< -o $@ - -%.o: %.cpp $(HEADERS) - $(info Compiling $<) - $(CXX) $(DRIVER_CFLAGS) $(WARNCFLAG) -std=c++20 -fno-exceptions -fno-rtti -c $< -o $@ - -%.o: %.S - $(info Compiling $<) - $(AS) -o $@ $< - -clean: - rm -f file.map $(OBJ) $(STACK_USAGE_OBJ) diff --git a/Drivers/audio/ac97/ac97.cpp b/Drivers/audio/ac97/ac97.cpp deleted file mode 100644 index 9664eb73..00000000 --- a/Drivers/audio/ac97/ac97.cpp +++ /dev/null @@ -1,881 +0,0 @@ -/* - This file is part of Fennix Kernel. - - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. - - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . -*/ - -#include -#include -#include -#include -#include -#include -#include - -#define DescriptorListLength 0x20 - -enum AudioVolumeValues -{ - AV_Maximum = 0x0, - AV_Minimum = 0x3F, -}; - -enum AudioEncodingValues -{ - AE_PCMs8, - AE_PCMu8, - - AE_PCMs16le, - AE_PCMs20le, - AE_PCMs24le, - AE_PCMs32le, - - AE_PCMu16le, - AE_PCMu20le, - AE_PCMu24le, - AE_PCMu32le, - - AE_PCMs16be, - AE_PCMs20be, - AE_PCMs24be, - AE_PCMs32be, - - AE_PCMu16be, - AE_PCMu20be, - AE_PCMu24be, - AE_PCMu32be, -}; - -enum NativeAudioMixerRegisters -{ - /** - * @brief Reset Register - * @note Length: word - */ - NAM_Reset = 0x00, - - /** - * @brief Master Volume Register - * @note Length: word - */ - NAM_MasterVolume = 0x02, - - /** - * @brief Microphone Volume Register - * @note Length: word - */ - NAM_MicrophoneVolume = 0x0E, - - /** - * @brief PCM Out Volume Register - * @note Length: word - */ - NAM_PCMOutVolume = 0x18, - - /** - * @brief Select Record Input Register - * @note Length: word - */ - NAM_SelectRecordInput = 0x1A, - - /** - * @brief Record Gain Register - * @note Length: word - */ - NAM_RecordGain = 0x1C, - - /** - * @brief Record Gain Microphone Register - * @note Length: word - */ - NAM_RecordGainMicrophone = 0x1E, -}; - -enum NativeAudioBusMasterRegisters -{ - /** - * @brief Register box for PCM IN - * @note Length: below - */ - NABM_PCMInBox = 0x00, - - /** - * @brief Register box for PCM OUT - * @note Length: below - */ - NABM_PCMOutBox = 0x10, - - /** - * @brief Register box for Microphone - * @note Length: below - */ - NABM_MicrophoneBox = 0x20, - - /** - * @brief Global Control Register - * @note Length: dword - */ - NABM_GlobalControl = 0x2C, /* 0x30 */ - - /** - * @brief Global Status Register - * @note Length: dword - */ - NABM_GlobalStatus = 0x30, /* 0x34 */ -}; - -enum NativeAudioBusMasterBoxOffsets -{ - /** - * @brief Physical Address of Buffer Descriptor List - * @note Length: dword - */ - NABMBOFF_BufferDescriptorList = 0x00, - - /** - * @brief Number of Actual Processed Buffer Descriptor Entry - * @note Length: byte - */ - NABMBOFF_BufferDescriptorEntry = 0x04, - - /** - * @brief Number of all Descriptor Entries - * @note Length: byte - */ - NABMBOFF_DescriptorEntries = 0x05, - - /** - * @brief Status of transferring Data - * @note Length: word - */ - NABMBOFF_Status = 0x06, - - /** - * @brief Number of transferred Samples in Actual Processed Entry - * @note Length: word - */ - NABMBOFF_TransferredSamples = 0x08, - - /** - * @brief Number of next processed Buffer Entry - * @note Length: byte - */ - NABMBOFF_NextProcessedBufferEntry = 0x0A, - - /** - * @brief Transfer Control - * @note Length: byte - */ - NABMBOFF_TransferControl = 0x0B, -}; - -enum OutputPulseCodeModulationRegisters -{ - /** - * @brief Physical Address of Buffer Descriptor List - * @note Length: dword - */ - PCMOUT_BufferDescriptorList = (int)NABM_PCMOutBox + (int)NABMBOFF_BufferDescriptorList, - - /** - * @brief Number of Actual Processed Buffer Descriptor Entry - * @note Length: byte - */ - PCMOUT_BufferDescriptorEntry = (int)NABM_PCMOutBox + (int)NABMBOFF_BufferDescriptorEntry, - - /** - * @brief Number of all Descriptor Entries - * @note Length: byte - */ - PCMOUT_DescriptorEntries = (int)NABM_PCMOutBox + (int)NABMBOFF_DescriptorEntries, - - /** - * @brief Status of transferring Data - * @note Length: word - */ - PCMOUT_Status = (int)NABM_PCMOutBox + (int)NABMBOFF_Status, - - /** - * @brief Number of transferred Samples in Actual Processed Entry - * @note Length: word - */ - PCMOUT_TransferredSamples = (int)NABM_PCMOutBox + (int)NABMBOFF_TransferredSamples, - - /** - * @brief Number of next processed Buffer Entry - * @note Length: byte - */ - PCMOUT_NextProcessedBufferEntry = (int)NABM_PCMOutBox + (int)NABMBOFF_NextProcessedBufferEntry, - - /** - * @brief Transfer Control - * @note Length: byte - */ - PCMOUT_TransferControl = (int)NABM_PCMOutBox + (int)NABMBOFF_TransferControl, -}; - -enum TransferControlRegisters -{ - /** - * @brief DMA controller control - * - * 0 = Pause transfer - * 1 = Transfer sound data - */ - TC_DMAControllerControl = 0x01, - - /** - * @brief Reset - * - * 0 = Remove reset condition - * 1 = Reset this NABM register box, this bit is cleared by card when is reset complete - */ - TC_TransferReset = 0x02, - - /** - * @brief Last Buffer Entry Interrupt enable - * - * 0 = Disable interrupt - * 1 = Enable interrupt - */ - TC_LastBufferEntryInterruptEnable = 0x04, - - /** - * @brief IOC Interrupt enable - * - * 0 = Disable interrupt - * 1 = Enable interrupt - */ - TC_IOCInterruptEnable = 0x08, - - /** - * @brief Fifo ERROR Interrupt enable - * - * 0 = Disable interrupt - * 1 = Enable interrupt - */ - TC_FifoERRORInterruptEnable = 0x10, -}; - -enum GlobalControlRegisters -{ - /** - * @brief Global Interrupt Enable - * - * 0 = Disable Interrupts - * 1 = Enable Interrupts - */ - GC_GlobalInterruptEnable = 0x01, - - /** - * @brief Cold reset - * - * 0 = Device is in reset and can not be used - * 1 = Resume to operational state - */ - GC_ColdReset = 0x02, - - /** - * @brief Warm reset - */ - GC_WarmReset = 0x04, - - /** - * @brief Shut down - * - * 0 = Device is powered - * 1 = Shut down - */ - GC_ShutDown = 0x08, - - /** - * @brief Channels for PCM Output - * - * 00 = 2 channels - * 01 = 4 channels - * 10 = 6 channels - * 11 = Reserved - */ - GC_ChannelsForPCMOutput = 0x30, - - /** - * @brief PCM Output mode - * - * 00 = 16 bit samples - * 01 = 20 bit samples - */ - GC_PCMOutputMode = 0xC0, -}; - -struct BufferDescriptorList -{ - /** - * @brief Physical Address to sound data in memory - * @note Length: dword - */ - uint32_t Address; - - /** - * @brief Number of samples in this buffer - * @note Length: word - */ - uint16_t SampleCount; - - /** - * @brief Flags - * @note Length: word - * - * Bit 15 = Interrupt fired when data from this entry is transferred - * Bit 14 = Last entry of buffer, stop playing - * Other bits = Reserved - */ - uint16_t Flags; -} __attribute__((packed)); - -uint16_t MixerVolume(uint8_t Left, uint8_t Right, bool Mute) -{ - return ((uint16_t)((Right & 0x3F) | - ((Left & 0x3F) << 0x8) | - (Mute & 1 << 0xF))); -} - -class AC97Device -{ -private: - PCIHeader0 *Header; - BufferDescriptorList *DescriptorList = nullptr; - - uint16_t MixerAddress; - uint16_t BusMasterAddress; - - AudioEncodingValues Encoding = AE_PCMs16le; - char Channels = 2; - uint8_t Volume = AV_Maximum; - bool Mute = false; - int SampleRate = 48000; - char SampleSize = 2; - -public: - size_t write(uint8_t *Buffer, size_t Size) - { - if (Buffer == nullptr) - { - KernelLog("Invalid buffer."); - return -EINVAL; - } - - if ((Size == 0) || (Size % (SampleSize * Channels))) - { - KernelLog("Invalid buffer length."); - return -EINVAL; - } - - int TotalBDLToFill = (int)((Size + PAGE_SIZE - 1) >> 12); - - while (Size > 0) - { - bool ActiveDMA = !(inw(BusMasterAddress + PCMOUT_Status) & TC_DMAControllerControl); - - if (ActiveDMA) - { - int RemainingBDL = 0; - - do - { - int CurrentBDL = inb(BusMasterAddress + PCMOUT_BufferDescriptorEntry); - int LastBDL = inb(BusMasterAddress + PCMOUT_DescriptorEntries); - - RemainingBDL = LastBDL - CurrentBDL; - if (RemainingBDL < 0) - RemainingBDL += DescriptorListLength; - - RemainingBDL += 1; - - if (RemainingBDL >= DescriptorListLength - 1) - { - long SampleCount = DescriptorList[(CurrentBDL + 1) % DescriptorListLength].SampleCount / Channels; - if (SampleCount > 0) - Sleep(SampleCount * 1000 / SampleRate); - } - - } while (RemainingBDL >= DescriptorListLength - 1 && - !(inw(BusMasterAddress + PCMOUT_Status) & TC_DMAControllerControl)); - } - - uint8_t CurrentBDL = inb(BusMasterAddress + PCMOUT_BufferDescriptorEntry); - uint8_t LastBDL = inb(BusMasterAddress + PCMOUT_DescriptorEntries); - uint8_t NextBDL = LastBDL % DescriptorListLength; - - ActiveDMA = !(inw(BusMasterAddress + PCMOUT_Status) & TC_DMAControllerControl); - if (ActiveDMA) - { - NextBDL = (uint8_t)((LastBDL + 1) % DescriptorListLength); - if (NextBDL == CurrentBDL) - continue; - } - - do - { - size_t Wrote = (PAGE_SIZE > Size) ? size_t(Size) - : size_t(PAGE_SIZE); - - if (Wrote == 0) - { - KernelLog("Wrote 0 bytes."); - break; - } - - memcpy((void *)((uint64_t)DescriptorList[NextBDL].Address), Buffer, Wrote); - DescriptorList[NextBDL].Flags = 0; - - Buffer += Wrote; - Size -= (unsigned int)Wrote; - - DescriptorList[NextBDL].SampleCount = uint16_t(Wrote / SampleSize); - TotalBDLToFill--; - NextBDL = (uint8_t)((NextBDL + 1) % DescriptorListLength); - } while (TotalBDLToFill-- && NextBDL != CurrentBDL); - - outb(BusMasterAddress + PCMOUT_DescriptorEntries, NextBDL - 1); - - ActiveDMA = !(inw(BusMasterAddress + PCMOUT_Status) & TC_DMAControllerControl); - if (!ActiveDMA) - { - // Start DMA - outb(BusMasterAddress + PCMOUT_TransferControl, - inb(BusMasterAddress + PCMOUT_TransferControl) | TC_DMAControllerControl); - } - } - return Size; - } - - int ioctl(AudioIoctl, void *) - { - // if (Data->AudioCallback.Adjust._Volume) - // { - // Volume = (uint8_t)(0x3F - (0x3F * Data->AudioCallback.Adjust.Volume / 100)); - // outw(BAR.MixerAddress + NAM_MasterVolume, MixerVolume(Volume, Volume, Mute)); - // // outw(BAR.MixerAddress + NAM_PCMOutVolume, MixerVolume(Volume, Volume, Mute)); - // } - // else if (Data->AudioCallback.Adjust._Encoding) - // { - // fixme("Encoding changing not supported yet."); - // } - // else if (Data->AudioCallback.Adjust._SampleRate) - // { - // switch (Data->AudioCallback.Adjust.SampleRate) - // { - // case 0: - // { - // SampleRate = 8000; - // break; - // } - // case 1: - // { - // SampleRate = 11025; - // break; - // } - // case 2: - // { - // SampleRate = 16000; - // break; - // } - // case 3: - // { - // SampleRate = 22050; - // break; - // } - // case 4: - // { - // SampleRate = 32000; - // break; - // } - // case 5: - // { - // SampleRate = 44100; - // break; - // } - // case 6: - // { - // SampleRate = 48000; - // break; - // } - // case 7: - // { - // SampleRate = 88200; - // break; - // } - // case 8: - // { - // SampleRate = 96000; - // break; - // } - // default: - // { - // SampleRate = 16000; - // error("Invalid sample rate. Defaulting to 16000."); - // break; - // } - // } - // } - // else if (Data->AudioCallback.Adjust._Channels) - // { - // switch (Data->AudioCallback.Adjust.Channels) - // { - // case 0: - // { - // Channels = 1; // Mono - // break; - // } - // case 1: - // { - // Channels = 2; // Stereo - // break; - // } - // default: - // { - // Channels = 2; - // error("Invalid channel count. Defaulting to 2."); - // break; - // } - // } - // } - return 0; - } - - void OnInterruptReceived(TrapFrame *) - { - uint16_t Status = inw(MixerAddress + PCMOUT_Status); - if (Status & TC_IOCInterruptEnable) - { - DebugLog("IOC"); - outw(MixerAddress + PCMOUT_Status, TC_IOCInterruptEnable); - uint16_t CurrentBDL = inb(BusMasterAddress + PCMOUT_BufferDescriptorEntry); - uint16_t LastBDL = (CurrentBDL + 2) & (DescriptorListLength - 1); - outb(BusMasterAddress + PCMOUT_DescriptorEntries, LastBDL); - KernelLog("FIXME: CurrentBDL: %d, LastBDL: %d", CurrentBDL, LastBDL); - } - else if (Status & TC_LastBufferEntryInterruptEnable) - { - DebugLog("Last buffer entry"); - // Stop DMA - uint8_t TransferControl = inb((uint16_t)(BusMasterAddress + PCMOUT_TransferControl)); - TransferControl &= ~TC_DMAControllerControl; - outb((uint16_t)(BusMasterAddress + PCMOUT_TransferControl), TransferControl); - - outw(MixerAddress + PCMOUT_Status, TC_LastBufferEntryInterruptEnable); - } - else if (Status & TC_FifoERRORInterruptEnable) - { - KernelLog("FIFO error"); - outw(MixerAddress + PCMOUT_Status, TC_FifoERRORInterruptEnable); - } - else - { - DebugLog("Unknown interrupt status %#x", Status); - outw(MixerAddress + PCMOUT_Status, 0xFFFF); - } - } - - void Panic() - { - uint8_t TransferControl = inb((uint16_t)(BusMasterAddress + PCMOUT_TransferControl)); - TransferControl &= ~(TC_LastBufferEntryInterruptEnable | - TC_IOCInterruptEnable | - TC_FifoERRORInterruptEnable); - outb((uint16_t)(BusMasterAddress + PCMOUT_TransferControl), TransferControl); - - uint32_t GlobalControl = inl((uint16_t)(BusMasterAddress + NABM_GlobalControl)); - GlobalControl &= ~GC_GlobalInterruptEnable; - GlobalControl |= GC_ShutDown; - outl((uint16_t)(BusMasterAddress + NABM_GlobalControl), GlobalControl); - } - - AC97Device(PCIHeader0 *_Header) - : Header(_Header) - { - /* Native Audio Mixer Base Address */ - uint32_t PCIBAR0 = Header->BAR0; - - /* Native Audio Bus Master Base Address */ - uint32_t PCIBAR1 = Header->BAR1; - - // uint8_t Type = PCIBAR0 & 1; - MixerAddress = (uint16_t)(PCIBAR0 & (~3)); - BusMasterAddress = PCIBAR1 & (~15); - - uint16_t OutputPCMTransferControl = BusMasterAddress + PCMOUT_TransferControl; - - /* DescriptorList address MUST be physical. */ - DescriptorList = (BufferDescriptorList *)AllocateMemory(TO_PAGES(sizeof(BufferDescriptorList) * DescriptorListLength)); - memset(DescriptorList, 0, sizeof(BufferDescriptorList) * DescriptorListLength); - - uint16_t DLSampleCount = (uint16_t)(PAGE_SIZE / SampleSize); - for (int i = 0; i < DescriptorListLength; i++) - { - DescriptorList[i].Address = (uint32_t)(uintptr_t)AllocateMemory(TO_PAGES(sizeof(uint16_t *))); - DescriptorList[i].SampleCount = DLSampleCount; - DescriptorList[i].Flags = 0; - DebugLog("DescriptorList[%d] = { Address: %#lx, SampleCount: %d, Flags: %#lx }", - i, - DescriptorList[i].Address, - DescriptorList[i].SampleCount, - DescriptorList[i].Flags); - } - - outw(MixerAddress + NAM_MasterVolume, MixerVolume(Volume, Volume, Mute)); - outw(MixerAddress + NAM_PCMOutVolume, MixerVolume(Volume, Volume, Mute)); - - Volume = 0x3F - (0x3F * /* VOL 50% */ 50 / 100); - outw(MixerAddress + NAM_MasterVolume, MixerVolume(Volume, Volume, Mute)); - - outb(OutputPCMTransferControl, inb(OutputPCMTransferControl) | TC_TransferReset); - while (inb(OutputPCMTransferControl) & TC_TransferReset) - ; - - uint32_t GlobalControl = inl(BusMasterAddress + NABM_GlobalControl); - GlobalControl = (GlobalControl & ~((0x3U) << 0x16)); /* PCM 16-bit mode */ - GlobalControl = (GlobalControl & ~((0x3U) << 20)); /* 2 channels */ - GlobalControl |= GC_GlobalInterruptEnable; - GlobalControl &= ~GC_ShutDown; - - outl(BusMasterAddress + PCMOUT_BufferDescriptorList, - (uint32_t)(uint64_t)DescriptorList); - - outl(BusMasterAddress + NABM_GlobalControl, GlobalControl); - - uint8_t TransferControl = inb(OutputPCMTransferControl); - TransferControl |= TC_IOCInterruptEnable | - TC_FifoERRORInterruptEnable; - outb(OutputPCMTransferControl, TransferControl); - - // Stop DMA - outb(OutputPCMTransferControl, inb(OutputPCMTransferControl) & ~TC_DMAControllerControl); - } - - ~AC97Device() - { - outw(MixerAddress + NAM_MasterVolume, MixerVolume(AV_Maximum, AV_Maximum, true)); - outw(MixerAddress + NAM_PCMOutVolume, MixerVolume(AV_Maximum, AV_Maximum, true)); - - // Stop DMA - outb((uint16_t)(BusMasterAddress + PCMOUT_TransferControl), - inb((uint16_t)(BusMasterAddress + PCMOUT_TransferControl)) & ~TC_DMAControllerControl); - - // Disable interrupts - uint8_t TransferControl = inb((uint16_t)(BusMasterAddress + PCMOUT_TransferControl)); - - TransferControl &= ~(TC_LastBufferEntryInterruptEnable | - TC_IOCInterruptEnable | - TC_FifoERRORInterruptEnable); - outb((uint16_t)(BusMasterAddress + PCMOUT_TransferControl), TransferControl); - - // Disable global control - uint32_t GlobalControl = inl((uint16_t)(BusMasterAddress + NABM_GlobalControl)); - GlobalControl &= ~GC_GlobalInterruptEnable; - GlobalControl |= GC_ShutDown; - outl((uint16_t)(BusMasterAddress + NABM_GlobalControl), GlobalControl); - } -}; - -AC97Device *Drivers[4] = {nullptr}; -dev_t AudioID[4] = {(dev_t)-1}; - -#define OIR(x) OIR_##x -#define CREATE_OIR(x) \ - void OIR_##x(TrapFrame *f) { Drivers[x]->OnInterruptReceived(f); } - -CREATE_OIR(0); -CREATE_OIR(1); -CREATE_OIR(2); -CREATE_OIR(3); - -int __fs_Open(struct Inode *, int, mode_t) { return 0; } -int __fs_Close(struct Inode *) { return 0; } -ssize_t __fs_Read(struct Inode *, void *, size_t, off_t) { return 0; } - -ssize_t __fs_Write(struct Inode *Node, const void *Buffer, size_t Size, off_t) -{ - return Drivers[AudioID[Node->GetMinor()]]->write((uint8_t *)Buffer, Size); -} - -int __fs_Ioctl(struct Inode *Node, unsigned long Request, void *Argp) -{ - return Drivers[AudioID[Node->GetMinor()]]->ioctl((AudioIoctl)Request, Argp); -} - -const struct InodeOperations AudioOps = { - .Lookup = nullptr, - .Create = nullptr, - .Remove = nullptr, - .Rename = nullptr, - .Read = __fs_Read, - .Write = __fs_Write, - .Truncate = nullptr, - .Open = __fs_Open, - .Close = __fs_Close, - .Ioctl = __fs_Ioctl, - .ReadDir = nullptr, - .MkDir = nullptr, - .RmDir = nullptr, - .SymLink = nullptr, - .ReadLink = nullptr, - .Seek = nullptr, - .Stat = nullptr, -}; - -PCIArray *Devices; -EXTERNC int cxx_Panic() -{ - PCIArray *ctx = Devices; - short Count = 0; - while (ctx != nullptr) - { - if (Drivers[Count] != nullptr) - Drivers[Count]->Panic(); - Count++; - ctx = (PCIArray *)ctx->Next; - } - - return 0; -} - -EXTERNC int cxx_Probe() -{ - uint16_t VendorIDs[] = {0x8086, PCI_END}; - uint16_t DeviceIDs[] = {0x2415, PCI_END}; - Devices = GetPCIDevices(VendorIDs, DeviceIDs); - if (Devices == nullptr) - { - KernelLog("No AC'97 device found."); - return -ENODEV; - } - - PCIArray *ctx = Devices; - bool Found = false; - size_t Count = 0; - while (ctx != nullptr) - { - if (Count++ > sizeof(Drivers) / sizeof(AC97Device *)) - break; - - PCIHeader0 *PCIBaseAddress = (PCIHeader0 *)ctx->Device->Header; - uint32_t PCIBAR0 = PCIBaseAddress->BAR0; - uint8_t Type = PCIBAR0 & 1; - if (Type != 1) - { - KernelLog("Device %x:%x.%d BAR0 is not I/O.", - PCIBaseAddress->Header.VendorID, - PCIBaseAddress->Header.DeviceID, - PCIBaseAddress->Header.ProgIF); - continue; - } - - Found = true; - ctx = (PCIArray *)ctx->Next; - } - - if (!Found) - { - KernelLog("No valid AC'97 device found."); - return -EINVAL; - } - return 0; -} - -EXTERNC int cxx_Initialize() -{ - PCIArray *ctx = Devices; - size_t Count = 0; - while (ctx != nullptr) - { - if (Count > sizeof(Drivers) / sizeof(AC97Device *)) - break; - - PCIHeader0 *PCIBaseAddress = (PCIHeader0 *)ctx->Device->Header; - uint32_t PCIBAR0 = PCIBaseAddress->BAR0; - uint8_t Type = PCIBAR0 & 1; - if (Type != 1) - { - KernelLog("Device %x:%x.%d BAR0 is not I/O.", - PCIBaseAddress->Header.VendorID, - PCIBaseAddress->Header.DeviceID, - PCIBaseAddress->Header.ProgIF); - continue; - } - - InitializePCI(ctx->Device); - - Drivers[Count] = new AC97Device((PCIHeader0 *)ctx->Device->Header); - /* FIXME: bad code */ - switch (Count) - { - case 0: - RegisterInterruptHandler(iLine(ctx->Device), (void *)OIR(0)); - break; - case 1: - RegisterInterruptHandler(iLine(ctx->Device), (void *)OIR(1)); - break; - case 2: - RegisterInterruptHandler(iLine(ctx->Device), (void *)OIR(2)); - break; - case 3: - RegisterInterruptHandler(iLine(ctx->Device), (void *)OIR(3)); - break; - default: - break; - } - dev_t ret = RegisterDevice(AUDIO_TYPE_PCM, &AudioOps); - AudioID[Count] = ret; - Count++; - ctx = (PCIArray *)ctx->Next; - } - - return 0; -} - -EXTERNC int cxx_Finalize() -{ - PCIArray *ctx = Devices; - size_t Count = 0; - while (ctx != nullptr) - { - if (Count++ > sizeof(Drivers) / sizeof(AC97Device *)) - break; - - PCIHeader0 *PCIBaseAddress = (PCIHeader0 *)ctx->Device->Header; - uint32_t PCIBAR0 = PCIBaseAddress->BAR0; - uint8_t Type = PCIBAR0 & 1; - if (Type != 1) - { - KernelLog("Device %x:%x.%d BAR0 is not I/O.", - PCIBaseAddress->Header.VendorID, - PCIBaseAddress->Header.DeviceID, - PCIBaseAddress->Header.ProgIF); - continue; - } - - delete Drivers[Count++]; - ctx->Device->Header->Command |= PCI_COMMAND_INTX_DISABLE; - ctx = (PCIArray *)ctx->Next; - } - - for (size_t i = 0; i < sizeof(AudioID) / sizeof(dev_t); i++) - { - if (AudioID[i] != (dev_t)-1) - UnregisterDevice(AudioID[i]); - } - - return 0; -} diff --git a/Drivers/audio/ac97/ac97.hpp b/Drivers/audio/ac97/ac97.hpp deleted file mode 100644 index 99242b91..00000000 --- a/Drivers/audio/ac97/ac97.hpp +++ /dev/null @@ -1,25 +0,0 @@ -/* - This file is part of Fennix Drivers. - - Fennix Drivers is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. - - Fennix Drivers is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Fennix Drivers. If not, see . -*/ - -#pragma once - -#include - -EXTERNC int cxx_Panic(); -EXTERNC int cxx_Probe(); -EXTERNC int cxx_Initialize(); -EXTERNC int cxx_Finalize(); diff --git a/Drivers/audio/ac97/main.c b/Drivers/audio/ac97/main.c deleted file mode 100644 index ad39fb7f..00000000 --- a/Drivers/audio/ac97/main.c +++ /dev/null @@ -1,31 +0,0 @@ -/* - This file is part of Fennix Drivers. - - Fennix Drivers is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. - - Fennix Drivers is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Fennix Drivers. If not, see . -*/ - -#include - -#include "ac97.hpp" - -int DriverEntry() { return cxx_Initialize(); } -int DriverFinal() { return cxx_Finalize(); } -int DriverPanic() { return cxx_Panic(); } -int DriverProbe() { return cxx_Probe(); } - -DriverInfo("ac97", - "Audio Codec '97 Driver", - "EnderIce2", - 0, 0, 1, - "GPLv3"); diff --git a/Drivers/audio/hda/Makefile b/Drivers/audio/hda/Makefile deleted file mode 100644 index 9a92e2ef..00000000 --- a/Drivers/audio/hda/Makefile +++ /dev/null @@ -1,35 +0,0 @@ -default: - $(error Do not run this Makefile directly!) - -S_SOURCES = $(shell find ./ -type f -name '*.S') -C_SOURCES = $(shell find ./ -type f -name '*.c') -CXX_SOURCES = $(shell find ./ -type f -name '*.cpp') -HEADERS = $(sort $(dir $(wildcard ../../include/*))) -OBJ = $(C_SOURCES:.c=.o) $(CXX_SOURCES:.cpp=.o) $(S_SOURCES:.S=.o) -STACK_USAGE_OBJ = $(C_SOURCES:.c=.su) $(CXX_SOURCES:.cpp=.su) - -FILENAME = $(notdir $(shell pwd)).drv - -build: $(FILENAME) - mv $(FILENAME) $(OUTPUT_DIR)$(FILENAME) - -$(FILENAME): $(OBJ) - $(info Linking $@) - $(CC) $(DRIVER_LDFLAGS) $(OBJ) $(OUTPUT_DIR)dcrt0.o -L$(OUTPUT_DIR) -lkernel -o $@ - -WARNCFLAG = -Wall -Wextra - -%.o: %.c $(HEADERS) - $(info Compiling $<) - $(CC) $(DRIVER_CFLAGS) $(WARNCFLAG) -std=c17 -c $< -o $@ - -%.o: %.cpp $(HEADERS) - $(info Compiling $<) - $(CXX) $(DRIVER_CFLAGS) $(WARNCFLAG) -std=c++20 -fno-exceptions -fno-rtti -c $< -o $@ - -%.o: %.S - $(info Compiling $<) - $(AS) -o $@ $< - -clean: - rm -f file.map $(OBJ) $(STACK_USAGE_OBJ) diff --git a/Drivers/audio/hda/hda.cpp b/Drivers/audio/hda/hda.cpp deleted file mode 100644 index 69a6cb68..00000000 --- a/Drivers/audio/hda/hda.cpp +++ /dev/null @@ -1,263 +0,0 @@ -/* - This file is part of Fennix Kernel. - - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. - - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . -*/ - -#include -#include -#include -#include -#include -#include -#include - -#include "hda.hpp" - -class HDADevice -{ -private: - PCIHeader0 *Header; - bool Initialized = false; - - ControllerRegisters *CTL; - - uint32_t *CORB; - uint64_t *RIRB; - -public: - bool IsInitialized() { return Initialized; } - - size_t write(uint8_t *, size_t Size) - { - return Size; - } - - int ioctl(AudioIoctl, void *) - { - return 0; - } - - void OnInterruptReceived(TrapFrame *) - { - } - - void Panic() - { - } - - HDADevice(PCIHeader0 *_Header) - : Header(_Header), - CORB((uint32_t *)(uintptr_t)AllocateMemory(1)), - RIRB((uint64_t *)AllocateMemory(1)) - { - CTL = (ControllerRegisters *)(uintptr_t)Header->BAR0; - KernelLog("Unimplemented HDA driver"); - return; - Initialized = true; - } - - ~HDADevice() - { - if (!Initialized) - return; - } -}; - -HDADevice *Drivers[4] = {nullptr}; -dev_t AudioID[4] = {(dev_t)-1}; - -#define OIR(x) OIR_##x -#define CREATE_OIR(x) \ - void OIR_##x(TrapFrame *f) { Drivers[x]->OnInterruptReceived(f); } - -CREATE_OIR(0); -CREATE_OIR(1); -CREATE_OIR(2); -CREATE_OIR(3); - -int __fs_Open(struct Inode *, int, mode_t) { return 0; } -int __fs_Close(struct Inode *) { return 0; } -ssize_t __fs_Read(struct Inode *, void *, size_t, off_t) { return 0; } - -ssize_t __fs_Write(struct Inode *Node, const void *Buffer, size_t Size, off_t) -{ - return Drivers[AudioID[Node->GetMinor()]]->write((uint8_t *)Buffer, Size); -} - -int __fs_Ioctl(struct Inode *Node, unsigned long Request, void *Argp) -{ - return Drivers[AudioID[Node->GetMinor()]]->ioctl((AudioIoctl)Request, Argp); -} - -const struct InodeOperations AudioOps = { - .Lookup = nullptr, - .Create = nullptr, - .Remove = nullptr, - .Rename = nullptr, - .Read = __fs_Read, - .Write = __fs_Write, - .Truncate = nullptr, - .Open = __fs_Open, - .Close = __fs_Close, - .Ioctl = __fs_Ioctl, - .ReadDir = nullptr, - .MkDir = nullptr, - .RmDir = nullptr, - .SymLink = nullptr, - .ReadLink = nullptr, - .Seek = nullptr, - .Stat = nullptr, -}; - -PCIArray *Devices; -EXTERNC int cxx_Panic() -{ - PCIArray *ctx = Devices; - short Count = 0; - while (ctx != nullptr) - { - if (Drivers[Count] != nullptr) - Drivers[Count]->Panic(); - Count++; - ctx = (PCIArray *)ctx->Next; - } - - return 0; -} - -EXTERNC int cxx_Probe() -{ - uint16_t VendorIDs[] = {0x8086, /* Intel */ - 0x15AD, /* VMware */ - PCI_END}; - uint16_t DeviceIDs[] = {0x9D71 /* Sunrise Point-LP HD Audio */, - 0x2668 /* ICH6 */, - 0x293E /* ICH9 */, - PCI_END}; - Devices = GetPCIDevices(VendorIDs, DeviceIDs); - if (Devices == nullptr) - { - KernelLog("No HDA device found."); - return -ENODEV; - } - - PCIArray *ctx = Devices; - bool Found = false; - size_t Count = 0; - while (ctx != nullptr) - { - if (Count++ > sizeof(Drivers) / sizeof(HDADevice *)) - break; - - PCIHeader0 *PCIBaseAddress = (PCIHeader0 *)ctx->Device->Header; - uint32_t PCIBAR0 = PCIBaseAddress->BAR0; - uint8_t Type = PCIBAR0 & 1; - if (Type == 1) - { - KernelLog("Device %x:%x.%d BAR0 is I/O.", - PCIBaseAddress->Header.VendorID, - PCIBaseAddress->Header.DeviceID, - PCIBaseAddress->Header.ProgIF); - continue; - } - - Found = true; - ctx = (PCIArray *)ctx->Next; - } - - if (!Found) - { - KernelLog("No valid HDA device found."); - return -EINVAL; - } - return 0; -} - -EXTERNC int cxx_Initialize() -{ - PCIArray *ctx = Devices; - size_t Count = 0; - while (ctx != nullptr) - { - if (Count > sizeof(Drivers) / sizeof(HDADevice *)) - break; - - PCIHeader0 *PCIBaseAddress = (PCIHeader0 *)ctx->Device->Header; - uint32_t PCIBAR0 = PCIBaseAddress->BAR0; - uint8_t Type = PCIBAR0 & 1; - if (Type == 1) - { - KernelLog("Device %x:%x.%d BAR0 is I/O.", - PCIBaseAddress->Header.VendorID, - PCIBaseAddress->Header.DeviceID, - PCIBaseAddress->Header.ProgIF); - continue; - } - - InitializePCI(ctx->Device); - - Drivers[Count] = new HDADevice((PCIHeader0 *)ctx->Device->Header); - - if (Drivers[Count]->IsInitialized()) - { - dev_t ret = RegisterDevice(AUDIO_TYPE_PCM, &AudioOps); - AudioID[Count] = ret; - Count++; - } - ctx = (PCIArray *)ctx->Next; - } - - if (Count == 0) - { - KernelLog("No valid HDA device found."); - return -EINVAL; - } - - return 0; -} - -EXTERNC int cxx_Finalize() -{ - PCIArray *ctx = Devices; - size_t Count = 0; - while (ctx != nullptr) - { - if (Count++ > sizeof(Drivers) / sizeof(HDADevice *)) - break; - - PCIHeader0 *PCIBaseAddress = (PCIHeader0 *)ctx->Device->Header; - uint32_t PCIBAR0 = PCIBaseAddress->BAR0; - uint8_t Type = PCIBAR0 & 1; - if (Type == 1) - { - KernelLog("Device %x:%x.%d BAR0 is I/O.", - PCIBaseAddress->Header.VendorID, - PCIBaseAddress->Header.DeviceID, - PCIBaseAddress->Header.ProgIF); - continue; - } - - delete Drivers[Count++]; - ctx = (PCIArray *)ctx->Next; - } - - for (size_t i = 0; i < sizeof(AudioID) / sizeof(dev_t); i++) - { - if (AudioID[i] != (dev_t)-1) - UnregisterDevice(AudioID[i]); - } - - return 0; -} diff --git a/Drivers/audio/hda/hda.hpp b/Drivers/audio/hda/hda.hpp deleted file mode 100644 index d1587c5a..00000000 --- a/Drivers/audio/hda/hda.hpp +++ /dev/null @@ -1,635 +0,0 @@ -/* - This file is part of Fennix Drivers. - - Fennix Drivers is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. - - Fennix Drivers is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Fennix Drivers. If not, see . -*/ - -#pragma once - -#include - -#ifdef __cplusplus - -struct StreamDescriptor -{ - /** Control */ - uint32_t CTL : 24; - - /** Status */ - uint8_t STS; - - /** Link Position in Current Buffer */ - uint32_t LPIB; - - /** Cyclic Buffer Length */ - uint32_t CBL; - - /** Last Valid Index */ - uint16_t LVI; - - /** Reserved */ - uint8_t Rsvd0[2]; - - /** FIFO Size */ - uint16_t FIFOD; - - /** Format */ - uint16_t FMT; - - /** Reserved */ - uint8_t Rsvd1[4]; - - /** Buffer Descriptor List Pointer - Lower */ - uint32_t BDPL; - - /** Buffer Descriptor List Pointer - Upper */ - uint32_t BDPU; -} __attribute__((packed)); - -struct ControllerRegisters -{ - uint16_t GCAP; - uint8_t VMIN; - uint8_t VMJ; - uint16_t OUTPAY; - uint16_t INPAY; - uint32_t GCTL; - uint16_t WAKEEN; - uint16_t WAKESTS; - uint16_t GSTS; - uint8_t Rsvd0[6]; - uint16_t OUTSTRMPAY; - uint16_t INSTRMPAY; - uint8_t Rsvd1[4]; - uint32_t INTCTL; - uint32_t INTSTS; - uint8_t Rsvd2[8]; - uint32_t WALCLK; - uint8_t Rsvd3[4]; - uint32_t SSYNC; - uint8_t Rsvd4[4]; - uint32_t CORBLBASE; - uint32_t CORBUBASE; - uint16_t CORBWP; - uint16_t CORBRP; - uint8_t CORBCTL; - uint8_t CORBSTS; - uint8_t CORBSIZE; - uint8_t Rsvd5; - uint32_t RIRBLBASE; - uint32_t RIRBUBASE; - uint16_t RIRBWP; - uint16_t RINTCNT; - uint8_t RIRBCTL; - uint8_t RIRBSTS; - uint8_t RIRBSIZE; - uint8_t Rsvd6; - uint32_t ICOI; - uint32_t ICII; - uint16_t ICIS; - uint8_t Rsvd7[6]; - uint32_t DPIBLBASE; - uint32_t DPIBUBASE; - uint8_t Rsvd8[8]; - StreamDescriptor SD[]; -} __attribute__((packed)); - -/* Not working as expected */ -struct __ControllerRegisters -{ - /** Global Capabilities */ - union - { - struct - { - /** 64 Bit Address Supported - * - * 0 = 32-bit addressing - * 1 = 64-bit addressing - */ - uint16_t _64OK : 1; - - /** Number of Serial Data Out Signals - * - * 00 = 1 SDO - * 01 = 2 SDOs - * 10 = 4 SDOs - * 11 = Reserved - */ - uint16_t NSDO : 2; - - /** Number of Bidirectional Streams Supported - * - * 00000b = No bidirectional streams supported - * 00001b = 1 bidirectional stream supported - * ... - * 11110b = 30 bidirectional streams supported - */ - uint16_t BSS : 5; - - /** Number of Input Streams Supported - * - * 0000b = No input streams supported - * 0001b = 1 input stream supported - * ... - * 1111b = 15 input streams supported - */ - uint16_t ISS : 4; - - /** Number of Output Streams Supported - * - * 0000b = No output streams supported - * 0001b = 1 output stream supported - * ... - * 1111b = 15 output streams supported - */ - uint16_t OSS : 4; - } __attribute__((packed)); - uint16_t Raw; - } GCAP; - - /** Minor Version */ - uint8_t VMIN; - - /** Major Version */ - uint8_t VMJ; - - /** Output Payload Capability - * - * 00h = 0 Words - * 01h = 1 Word payload - * ... - * FFh = 255h Word payload - */ - uint16_t OUTPAY; - - /** Input Payload Capability - * - * 00h = 0 Words - * 01h = 1 Word payload - * ... - * FFh = 255h Word payload - */ - uint16_t INPAY; - - /** Global Control */ - union - { - struct - { - /** Controller Reset - * - * 0 = Reset - * 1 = Normal Operation - */ - uint32_t CRST : 1; - - /** Flush Control - * - * 0 = Idle - * 1 = Flush - */ - uint32_t FCNTRL : 1; - - /** Reserved */ - uint32_t RsvdP0 : 6; - - /** Accept Unsolicited Response Enable - * - * 0 = Disabled - * 1 = Enabled - */ - uint32_t UNSOL : 1; - - /** Reserved */ - uint32_t RsvdP1 : 23; - } __attribute__((packed)); - uint32_t Raw; - } GCTL; - - /** Wake Enable */ - union - { - struct - { - /** SDIN Wake Enable Flags */ - uint16_t SDIWEN : 15; - - /** Reserved */ - uint16_t RsvdP0 : 1; - } __attribute__((packed)); - uint16_t Raw; - } WAKEEN; - - /** Wake Status */ - union - { - struct - { - /** SDIN State Change Status Flags */ - uint16_t SDIWAKE : 15; - - /** Reserved */ - uint16_t RsvdZ0 : 1; - } __attribute__((packed)); - uint16_t Raw; - } WAKESTS; - - /** Global Status */ - union - { - struct - { - uint16_t RsvdZ0 : 1; - uint16_t FSTS : 1; - uint16_t RsvdZ1 : 14; - } __attribute__((packed)); - uint16_t Raw; - } GSTS; - - /** Reserved */ - uint8_t Rsvd0[6]; - - /** Output Stream Payload Capability */ - uint16_t OUTSTRMPAY; - - /** Input Stream Payload Capability */ - uint16_t INSTRMPAY; - - /** Reserved */ - uint8_t Rsvd1[4]; - - /** Interrupt Control */ - union - { - struct - { - /** Stream Interrupt Enable - * - * Bit 0 = Input Stream 0 - * Bit 1 = Input Stream 1 - * Bit 2 = Output Stream 0 - * Bit 3 = Output Stream 1 - * Bit 4 = Output Stream 2 - * Bit 5 = Bidirectional Stream 0 - * Bits 6-28 = Reserved - */ - uint32_t SIE : 30; - - /** Controller Interrupt Enable */ - uint32_t CIE : 1; - - /** Global Interrupt Enable */ - uint32_t GIE : 1; - } __attribute__((packed)); - uint32_t Raw; - } INTCTL; - - /** Interrupt Status */ - union - { - struct - { - /** Stream Interrupt Status */ - uint32_t SIS : 30; - - /** Controller Interrupt Status */ - uint32_t CIS : 1; - - /** Global Interrupt Status */ - uint32_t GIS : 1; - } __attribute__((packed)); - uint32_t Raw; - } INTSTS; - - /** Reserved */ - uint8_t Rsvd2[8]; - - /** Wall Clock Counter */ - uint32_t WALCLK; - - /** Reserved */ - uint8_t Rsvd3[4]; - - /** Stream Synchronization */ - union - { - struct - { - /** Stream Synchronization Bits */ - uint32_t SSYNC : 30; - - /** Reserved */ - uint32_t RsvdP0 : 2; - } __attribute__((packed)); - uint32_t Raw; - } SSYNC; - - /** Reserved */ - uint8_t Rsvd4[4]; - - /** CORB Lower Base Address */ - union - { - struct - { - /** CORB Lower Base Unimplemented Bits */ - uint32_t Unimplemented : 7; - - /** CORB Lower Base Address */ - uint32_t CORBLBASE : 25; - } __attribute__((packed)); - uint32_t Raw; - } CORBLBASE; - - /** CORB Upper Base Address */ - uint32_t CORBUBASE; - - /** CORB Write Pointer */ - union - { - struct - { - /** CORB Write Pointer */ - uint16_t CORBWP : 8; - - /** Reserved */ - uint16_t RsvdP0 : 8; - } __attribute__((packed)); - uint16_t Raw; - } CORBWP; - - /** CORB Read Pointer */ - union - { - struct - { - /** CORB Read Pointer */ - uint16_t CORBRP : 8; - - /** Reserved */ - uint16_t RsvdP0 : 7; - - /** CORB Read Pointer Reset */ - uint16_t CORBRPRST : 1; - } __attribute__((packed)); - uint16_t Raw; - } CORBRP; - - /** CORB Control */ - union - { - struct - { - /** CORB Memory Error Interrupt Enable */ - uint8_t CMEIE : 1; - - /** Enable CORB DMA Engine - * - * 0 = DMA Stop - * 1 = DMA Run - * - * @note Must read the value back. - */ - uint8_t CORBRUN : 1; - - /** Reserved */ - uint8_t RsvdP0 : 6; - } __attribute__((packed)); - uint8_t Raw; - } CORBCTL; - - /** CORB Status */ - union - { - struct - { - /** CORB Memory Error Indication */ - uint8_t CMEI : 1; - - /** Reserved */ - uint8_t RsvdZ0 : 7; - } __attribute__((packed)); - uint8_t Raw; - } CORBSTS; - - /** CORB Size */ - union - { - struct - { - /** CORB Size - * - * 00b = 2 entries - * 01b = 16 entries - * 10b = 256 entries - * 11b = Reserved - */ - uint8_t CORBSIZE : 2; - - /** Reserved */ - uint8_t RsvdP0 : 2; - - /** CORB Size Capability - * - * 0001b = 2 entries - * 0010b = 16 entries - * 0100b = 256 entries - * 1000b = Reserved - */ - uint8_t CORBSZCAP : 4; - } __attribute__((packed)); - uint8_t Raw; - } CORBSIZE; - - /** Reserved */ - uint8_t Rsvd5; - - /** RIRB Lower Base Address */ - union - { - struct - { - /** RIRB Lower Base Unimplemented Bits */ - uint32_t Unimplemented : 7; - - /** RIRB Lower Base Address */ - uint32_t RIRBLBASE : 25; - } __attribute__((packed)); - uint32_t Raw; - } RIRBLBASE; - - /** RIRB Upper Base Address */ - uint32_t RIRBUBASE; - - /** RIRB Write Pointer */ - union - { - struct - { - /** RIRB Write Pointer */ - uint16_t RIRBWP : 8; - - /** Reserved */ - uint16_t RsvdP0 : 7; - - /** RIRB Write Pointer Reset */ - uint16_t RIRBWPRST : 1; - } __attribute__((packed)); - uint16_t Raw; - } RIRBWP; - - /** Response Interrupt Count */ - union - { - struct - { - /** N Response Interrupt Count - * - * 00000001b = 1 Response sent to RIRB - * ... - * 11111111b = 255 Responses sent to RIRB - * 00000000b = 256 Response sent to RIRB - */ - uint16_t RINTCNT : 8; - - /** Reserved */ - uint16_t RsvdP0 : 8; - } __attribute__((packed)); - uint16_t Raw; - } RINTCNT; - - /** RIRB Control */ - union - { - struct - { - /** Response Interrupt Control - * - * 0 = Disable Interrupt - * 1 = Generate an interrupt after N responses are sent to the RIRB - */ - uint8_t RINTCTL : 1; - - /** RIRB DMA Enable - * - * 0 = DMA Stop - * 1 = DMA Run - */ - uint8_t RIRBDMAEN : 1; - - /** Response Overrun Interrupt Control */ - uint8_t RIRBOIC : 1; - - /** Reserved */ - uint8_t RsvdP0 : 5; - } __attribute__((packed)); - uint8_t Raw; - } RIRBCTL; - - /** RIRB Status */ - union - { - struct - { - /** Response Interrupt */ - uint8_t RINTFL : 1; - - /** Reserved */ - uint8_t RsvdZ0 : 1; - - /** Response Overrun Interrupt Status */ - uint8_t RIRBOIS : 1; - - /** Reserved */ - uint8_t RsvdZ1 : 5; - } __attribute__((packed)); - uint8_t Raw; - } RIRBSTS; - - /** RIRB Size */ - union - { - struct - { - /** RIRB Size - * - * 00b = 2 entries - * 01b = 16 entries - * 10b = 256 entries - * 11b = Reserved - */ - uint8_t RIRBSIZE : 2; - - /** Reserved */ - uint8_t RsvdP0 : 2; - - /** RIRB Size Capability - * - * 0001b = 2 entries - * 0010b = 16 entries - * 0100b = 256 entries - * 1000b = Reserved - */ - uint8_t RIRBSZCAP : 4; - } __attribute__((packed)); - uint8_t Raw; - } RIRBSIZE; - - /** Reserved */ - uint8_t Rsvd6; - - /** Immediate Command Output Interface */ - uint32_t ICOI; - - /** Immediate Command Input Interface */ - uint32_t ICII; - - /** Immediate Command Status */ - uint16_t ICIS; - - /** Reserved */ - uint8_t Rsvd7[6]; - - /** DMA Position Buffer Lower Base */ - union - { - struct - { - /** DMA Position Buffer Enable */ - uint32_t DPBEN : 1; - - /** Reserved */ - uint32_t RsvdZ0 : 6; - - /** DMA Position Lower Base Address */ - uint32_t DPLBASE : 25; - } __attribute__((packed)); - uint32_t Raw; - } DPIBLBASE; - - /** DMA Position Buffer Upper Base */ - uint32_t DPIBUBASE; - - /** Reserved */ - uint8_t Rsvd8[8]; - - StreamDescriptor SD[]; -} __attribute__((packed)); -#endif - -EXTERNC int cxx_Panic(); -EXTERNC int cxx_Probe(); -EXTERNC int cxx_Initialize(); -EXTERNC int cxx_Finalize(); diff --git a/Drivers/audio/hda/main.c b/Drivers/audio/hda/main.c deleted file mode 100644 index 9da8f76e..00000000 --- a/Drivers/audio/hda/main.c +++ /dev/null @@ -1,31 +0,0 @@ -/* - This file is part of Fennix Drivers. - - Fennix Drivers is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. - - Fennix Drivers is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Fennix Drivers. If not, see . -*/ - -#include - -#include "hda.hpp" - -int DriverEntry() { return cxx_Initialize(); } -int DriverFinal() { return cxx_Finalize(); } -int DriverPanic() { return cxx_Panic(); } -int DriverProbe() { return cxx_Probe(); } - -DriverInfo("hda", - "Intel High Definition Audio Driver", - "EnderIce2", - 0, 0, 1, - "GPLv3"); diff --git a/Drivers/filesystem/fat/Makefile b/Drivers/filesystem/fat/Makefile deleted file mode 100644 index 9a92e2ef..00000000 --- a/Drivers/filesystem/fat/Makefile +++ /dev/null @@ -1,35 +0,0 @@ -default: - $(error Do not run this Makefile directly!) - -S_SOURCES = $(shell find ./ -type f -name '*.S') -C_SOURCES = $(shell find ./ -type f -name '*.c') -CXX_SOURCES = $(shell find ./ -type f -name '*.cpp') -HEADERS = $(sort $(dir $(wildcard ../../include/*))) -OBJ = $(C_SOURCES:.c=.o) $(CXX_SOURCES:.cpp=.o) $(S_SOURCES:.S=.o) -STACK_USAGE_OBJ = $(C_SOURCES:.c=.su) $(CXX_SOURCES:.cpp=.su) - -FILENAME = $(notdir $(shell pwd)).drv - -build: $(FILENAME) - mv $(FILENAME) $(OUTPUT_DIR)$(FILENAME) - -$(FILENAME): $(OBJ) - $(info Linking $@) - $(CC) $(DRIVER_LDFLAGS) $(OBJ) $(OUTPUT_DIR)dcrt0.o -L$(OUTPUT_DIR) -lkernel -o $@ - -WARNCFLAG = -Wall -Wextra - -%.o: %.c $(HEADERS) - $(info Compiling $<) - $(CC) $(DRIVER_CFLAGS) $(WARNCFLAG) -std=c17 -c $< -o $@ - -%.o: %.cpp $(HEADERS) - $(info Compiling $<) - $(CXX) $(DRIVER_CFLAGS) $(WARNCFLAG) -std=c++20 -fno-exceptions -fno-rtti -c $< -o $@ - -%.o: %.S - $(info Compiling $<) - $(AS) -o $@ $< - -clean: - rm -f file.map $(OBJ) $(STACK_USAGE_OBJ) diff --git a/Drivers/filesystem/fat/fat.h b/Drivers/filesystem/fat/fat.h deleted file mode 100644 index 47a61a5d..00000000 --- a/Drivers/filesystem/fat/fat.h +++ /dev/null @@ -1,290 +0,0 @@ -/* - This file is part of Fennix Drivers. - - Fennix Drivers is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. - - Fennix Drivers is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Fennix Drivers. If not, see . -*/ - -#ifndef __FENNIX_DRIVER_FAT_H__ -#define __FENNIX_DRIVER_FAT_H__ - -#include - -/* Source: https://wiki.osdev.org/FAT */ - -struct BIOSParameterBlock -{ - /** The first three bytes EB 3C 90 disassemble to JMP SHORT 3C NOP. - * (The 3C value may be different.) The reason for this is to jump - * over the disk format information (the BPB and EBPB). Since the - * first sector of the disk is loaded into ram at location - * 0x0000:0x7c00 and executed, without this jump, the processor - * would attempt to execute data that isn't code. Even for - * non-bootable volumes, code matching this pattern (or using the - * E9 jump opcode) is required to be present by both Windows and - * OS X. To fulfil this requirement, an infinite loop can be placed - * here with the bytes EB FE 90. */ - uint8_t JumpBoot[3]; - - /** OEM identifier. The first 8 Bytes (3 - 10) is the version of DOS - * being used. The next eight Bytes 29 3A 63 7E 2D 49 48 and 43 read - * out the name of the version. The official FAT Specification from - * Microsoft says that this field is really meaningless and is ignored - * by MS FAT Modules, however it does recommend the value "MSWIN4.1" - * as some 3rd party drivers supposedly check it and expect it to - * have that value. Older versions of dos also report MSDOS5.1, - * linux-formatted floppy will likely to carry "mkdosfs" here, and - * FreeDOS formatted disks have been observed to have "FRDOS5.1" here. - * If the string is less than 8 bytes, it is padded with spaces. */ - uint8_t OEM[8]; - - /** The number of Bytes per sector (remember, all numbers are in the - * little-endian format). */ - uint16_t BytesPerSector; - - /** Number of sectors per cluster. */ - uint8_t SectorsPerCluster; - - /** Number of reserved sectors. The boot record sectors are included - * in this value. */ - uint16_t ReservedSectors; - - /** Number of File Allocation Tables (FAT's) on the storage media. - * Often this value is 2. */ - uint8_t NumberOfFATs; - - /** Number of root directory entries (must be set so that the root - * directory occupies entire sectors). */ - uint16_t RootDirectoryEntries; - - /** The total sectors in the logical volume. If this value is 0, it - * means there are more than 65535 sectors in the volume, and the - * actual count is stored in the Large Sector Count entry at 0x20. */ - uint16_t Sectors16; - - /** This Byte indicates the media descriptor type. */ - uint8_t Media; - - /** Number of sectors per FAT. FAT12/FAT16 only. */ - uint16_t SectorsPerFAT; - - /** Number of sectors per track. */ - uint16_t SectorsPerTrack; - - /** Number of heads or sides on the storage media. */ - uint16_t NumberOfHeads; - - /** Number of hidden sectors. (i.e. the LBA of the beginning of - * the partition). */ - uint32_t HiddenSectors; - - /** Large sector count. This field is set if there are more than - * 65535 sectors in the volume, resulting in a value which does not - * fit in the Number of Sectors entry at 0x13. */ - uint32_t Sectors32; -} __packed; - -struct ExtendedBootRecord_FAT12_16 -{ - /** Drive number. The value here should be identical to the value - * returned by BIOS interrupt 0x13, or passed in the DL register; - * i.e. 0x00 for a floppy disk and 0x80 for hard disks. This number - * is useless because the media is likely to be moved to another - * machine and inserted in a drive with a different drive number. */ - uint8_t DriveNumber; - - /** Flags in Windows NT. Reserved otherwise. */ - uint8_t Flags; - - /** Signature (must be 0x28 or 0x29). */ - uint8_t Signature; - - /** VolumeID 'Serial' number. Used for tracking volumes between - * computers. You can ignore this if you want. */ - uint32_t VolumeID; - - /** Volume label string. This field is padded with spaces. */ - uint8_t VolumeLabel[11]; - - /** System identifier string. This field is a string representation - * of the FAT file system type. It is padded with spaces. The spec - * says never to trust the contents of this string for any use. */ - uint8_t SystemIdentifier[8]; - - /** Boot code. */ - uint8_t BootCode[448]; - - /** Bootable partition signature 0xAA55. */ - uint16_t BootSignature; -} __packed; - -struct ExtendedBootRecord_FAT32 -{ - /** Sectors per FAT. The size of the FAT in sectors. */ - uint32_t SectorsPerFAT; - - /** Flags. */ - uint16_t Flags; - - /** FAT version number. The high byte is the major version and the - * low byte is the minor version. FAT drivers should respect this - * field. */ - uint16_t FATVersion; - - /** The cluster number of the root directory. Often this field is - * set to 2. */ - uint32_t RootDirectoryCluster; - - /** The sector number of the FSInfo structure. */ - uint16_t FSInfoSector; - - /** The sector number of the backup boot sector. */ - uint16_t BackupBootSector; - - /** Reserved. When the volume is formated these bytes should be zero. */ - uint8_t Reserved[12]; - - /** Drive number. The values here are identical to the values returned - * by the BIOS interrupt 0x13. 0x00 for a floppy disk and 0x80 for - * hard disks. */ - uint8_t DriveNumber; - - /** Flags in Windows NT. Reserved otherwise. */ - uint8_t Flags2; - - /** Signature (must be 0x28 or 0x29). */ - uint8_t Signature; - - /** Volume ID 'Serial' number. Used for tracking volumes between - * computers. You can ignore this if you want. */ - uint32_t VolumeID; - - /** Volume label string. This field is padded with spaces. */ - uint8_t VolumeLabel[11]; - - /** System identifier string. Always "FAT32 ". The spec says never - * to trust the contents of this string for any use. */ - uint8_t SystemIdentifier[8]; - - /** Boot code. */ - uint8_t BootCode[420]; - - /** Bootable partition signature 0xAA55. */ - uint16_t BootSignature; -} __packed; - -struct FSInfo -{ - /** Lead signature (must be 0x41615252 to indicate a valid FSInfo - * structure). */ - uint32_t LeadSignature; - - /** Reserved, these bytes should never be used. */ - uint8_t Reserved1[480]; - - /** Another signature (must be 0x61417272). */ - uint32_t AnotherSignature; - - /** Contains the last known free cluster count on the volume. If the - * value is 0xFFFFFFFF, then the free count is unknown and must be - * computed. However, this value might be incorrect and should at - * least be range checked (<= volume cluster count). */ - uint32_t FreeClusterCount; - - /** Indicates the cluster number at which the filesystem driver should - * start looking for available clusters. If the value is 0xFFFFFFFF, - * then there is no hint and the driver should start searching at 2. - * Typically this value is set to the last allocated cluster number. - * As the previous field, this value should be range checked. */ - uint32_t NextFreeCluster; - - /** Reserved. */ - uint8_t Reserved2[12]; - - /** Trail signature (0xAA550000). */ - uint32_t TrailSignature; -} __packed; - -struct exFATBootRecord -{ - /** The first three bytes EB 3C 90 disassemble to JMP SHORT 3C NOP. - * (The 3C value may be different.) The reason for this is to jump - * over the disk format information (the BPB and EBPB). Since the - * first sector of the disk is loaded into ram at location - * 0x0000:0x7c00 and executed, without this jump, the processor - * would attempt to execute data that isn't code. Even for - * non-bootable volumes, code matching this pattern (or using the - * E9 jump opcode) is required to be present by both Windows and - * OS X. To fulfil this requirement, an infinite loop can be placed - * here with the bytes EB FE 90. */ - uint8_t JumpBoot[3]; - - /** OEM identifier. This contains the string "EXFAT ". Not to be - * used for filesystem determination, but it's a nice hint. */ - uint8_t OEM[8]; - - /** Set to zero. This makes sure any FAT driver will not be able to - * load it. */ - uint8_t Reserved1[53]; - - /** Partition offset. No idea why the partition itself would have - * this, but it's here. Might be wrong. Probably best to just ignore. */ - uint64_t PartitionOffset; - - /** Volume length. */ - uint64_t VolumeLength; - - /** FAT offset (in sectors) from start of partition. */ - uint32_t FATOffset; - - /** FAT length (in sectors). */ - uint32_t FATLength; - - /** Cluster heap offset (in sectors). */ - uint32_t ClusterHeapOffset; - - /** Cluster count. */ - uint32_t ClusterCount; - - /** Root directory cluster. Typically 4 (but just read this value). */ - uint32_t RootDirectoryCluster; - - /** Serial number of partition. */ - uint32_t SerialNumber; - - /** Filesystem revision. */ - uint16_t FilesystemRevision; - - /** Flags. */ - uint16_t Flags; - - /** Sector shift. */ - uint8_t SectorShift; - - /** Cluster shift. */ - uint8_t ClusterShift; - - /** Number of FATs. */ - uint8_t NumberOfFATs; - - /** Drive select. */ - uint8_t DriveSelect; - - /** Percentage in use. */ - uint8_t PercentageInUse; - - /** Reserved (set to 0). */ - uint8_t Reserved2[7]; -} __packed; - -#endif // !__FENNIX_DRIVER_FAT_H__ diff --git a/Drivers/filesystem/fat/main.c b/Drivers/filesystem/fat/main.c deleted file mode 100644 index 6a1f407a..00000000 --- a/Drivers/filesystem/fat/main.c +++ /dev/null @@ -1,45 +0,0 @@ -/* - This file is part of Fennix Drivers. - - Fennix Drivers is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. - - Fennix Drivers is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Fennix Drivers. If not, see . -*/ - -#include - -int DriverEntry() -{ - return 0; -} - -int DriverFinal() -{ - return 0; -} - -int DriverPanic() -{ - return 0; -} - -int DriverProbe() -{ - /* Nothing to do */ - return 0; -} - -DriverInfo("fat", - "File Allocation Table Driver", - "EnderIce2", - 0, 0, 1, - "GPLv3"); diff --git a/Drivers/include/aip.h b/Drivers/include/aip.h index 6189291b..94813c1a 100644 --- a/Drivers/include/aip.h +++ b/Drivers/include/aip.h @@ -103,6 +103,7 @@ typedef union uint8_t Raw; } PS2_OUTPUT_PORT; +#ifndef __kernel__ void PIC_EOI(uint8_t IRQ); void IRQ_MASK(uint8_t IRQ); void IRQ_UNMASK(uint8_t IRQ); @@ -114,11 +115,11 @@ uint8_t PS2ReadStatus(); uint8_t PS2ReadAfterACK(); void PS2ClearOutputBuffer(); int PS2ACKTimeout(); +#endif // !__kernel__ #define WaitOutput PS2Wait(DriverID, true) #define WaitInput PS2Wait(DriverID, false) - #define PS2_KBD_CMD_SET_LEDS 0xED #define PS2_KBD_CMD_ECHO 0xEE #define PS2_KBD_CMD_SCAN_CODE_SET 0xF0 @@ -189,7 +190,6 @@ typedef union uint8_t Raw; } PS2_KBD_TYPEMATIC; - #define PS2_MOUSE_CMD_SET_SCALING_1_1 0xE6 #define PS2_MOUSE_CMD_SET_SCALING_2_1 0xE7 #define PS2_MOUSE_CMD_SET_RESOLUTION 0xE8 diff --git a/Drivers/include/device.h b/Drivers/include/device.h index 925a76e2..d89aed41 100644 --- a/Drivers/include/device.h +++ b/Drivers/include/device.h @@ -69,7 +69,10 @@ typedef enum BLOCK_TYPE_FLOPPY = DEVICE_TYPE_BLOCK + 128, } DeviceType; +#ifndef __kernel__ +EXTERNC dev_t CreateDeviceFile(const char *name, mode_t mode, const struct InodeOperations *Operations); EXTERNC dev_t RegisterDevice(DeviceType Type, const struct InodeOperations *Operations); EXTERNC int UnregisterDevice(dev_t Device); +#endif // !__kernel__ #endif // !__FENNIX_API_DEVICE_H__ diff --git a/Drivers/include/fs.h b/Drivers/include/fs.h index 23e19f14..0a3f1905 100644 --- a/Drivers/include/fs.h +++ b/Drivers/include/fs.h @@ -377,7 +377,9 @@ struct FileSystemInfo void *PrivateData; } __attribute__((packed)); +#ifndef __kernel__ dev_t RegisterFileSystem(struct FileSystemInfo *Info, struct Inode *Root); int UnregisterFileSystem(dev_t Device); +#endif // !__kernel__ #endif // !__FENNIX_API_FILESYSTEM_H__ diff --git a/Drivers/include/input.h b/Drivers/include/input.h index ff40a071..0618de0c 100644 --- a/Drivers/include/input.h +++ b/Drivers/include/input.h @@ -239,6 +239,8 @@ typedef struct }; } InputReport; +#ifndef __kernel__ EXTERNC int ReportInputEvent(InputReport *Report); +#endif // !__kernel__ #endif // !__FENNIX_API_INPUT_H__ diff --git a/Drivers/include/pci.h b/Drivers/include/pci.h index bfeedea0..bd5537de 100644 --- a/Drivers/include/pci.h +++ b/Drivers/include/pci.h @@ -171,11 +171,13 @@ extern "C" { #endif +#ifndef __kernel__ PCIArray *GetPCIDevices(uint16_t Vendors[], uint16_t Devices[]); void InitializePCI(PCIDevice *Device); uint32_t GetBAR(uint8_t Index, PCIDevice *Device); uint8_t iLine(PCIDevice *Device); uint8_t iPin(PCIDevice *Device); +#endif // !__kernel__ #ifdef __cplusplus } diff --git a/Drivers/input/aip/Makefile b/Drivers/input/aip/Makefile deleted file mode 100644 index 9a92e2ef..00000000 --- a/Drivers/input/aip/Makefile +++ /dev/null @@ -1,35 +0,0 @@ -default: - $(error Do not run this Makefile directly!) - -S_SOURCES = $(shell find ./ -type f -name '*.S') -C_SOURCES = $(shell find ./ -type f -name '*.c') -CXX_SOURCES = $(shell find ./ -type f -name '*.cpp') -HEADERS = $(sort $(dir $(wildcard ../../include/*))) -OBJ = $(C_SOURCES:.c=.o) $(CXX_SOURCES:.cpp=.o) $(S_SOURCES:.S=.o) -STACK_USAGE_OBJ = $(C_SOURCES:.c=.su) $(CXX_SOURCES:.cpp=.su) - -FILENAME = $(notdir $(shell pwd)).drv - -build: $(FILENAME) - mv $(FILENAME) $(OUTPUT_DIR)$(FILENAME) - -$(FILENAME): $(OBJ) - $(info Linking $@) - $(CC) $(DRIVER_LDFLAGS) $(OBJ) $(OUTPUT_DIR)dcrt0.o -L$(OUTPUT_DIR) -lkernel -o $@ - -WARNCFLAG = -Wall -Wextra - -%.o: %.c $(HEADERS) - $(info Compiling $<) - $(CC) $(DRIVER_CFLAGS) $(WARNCFLAG) -std=c17 -c $< -o $@ - -%.o: %.cpp $(HEADERS) - $(info Compiling $<) - $(CXX) $(DRIVER_CFLAGS) $(WARNCFLAG) -std=c++20 -fno-exceptions -fno-rtti -c $< -o $@ - -%.o: %.S - $(info Compiling $<) - $(AS) -o $@ $< - -clean: - rm -f file.map $(OBJ) $(STACK_USAGE_OBJ) diff --git a/Drivers/input/aip/aip.h b/Drivers/input/aip/aip.h deleted file mode 100644 index ed4cc77a..00000000 --- a/Drivers/input/aip/aip.h +++ /dev/null @@ -1,39 +0,0 @@ -/* - This file is part of Fennix Drivers. - - Fennix Drivers is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. - - Fennix Drivers is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Fennix Drivers. If not, see . -*/ - -#ifndef __FENNIX_DRIVER_AIP_H__ -#define __FENNIX_DRIVER_AIP_H__ - -#include -#include -#include - -extern uint8_t Device1ID[]; -extern uint8_t Device2ID[]; - -void PS2KbdInterruptHandler(TrapFrame *); -int InitializeKeyboard(); -int FinalizeKeyboard(); -int DetectPS2Keyboard(); - -void PS2MouseInterruptHandler(TrapFrame *); -int InitializeMouse(); -int FinalizeMouse(); -int DetectPS2Mouse(); -int DetectUART(); - -#endif // !__FENNIX_DRIVER_AIP_H__ diff --git a/Drivers/input/aip/keyboard.c b/Drivers/input/aip/keyboard.c deleted file mode 100644 index 36df825e..00000000 --- a/Drivers/input/aip/keyboard.c +++ /dev/null @@ -1,335 +0,0 @@ -/* - This file is part of Fennix Drivers. - - Fennix Drivers is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. - - Fennix Drivers is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Fennix Drivers. If not, see . -*/ - -#include "aip.h" - -#include -#include -#include -#include -#include -#include - -uint8_t KeyboardScanCodeSet = 0; -dev_t KeyboardDevID = -1; - -const unsigned short ScanCodeSet1[] = - {KEY_NULL, KEY_ESCAPE, - KEY_1, KEY_2, KEY_3, KEY_4, KEY_5, KEY_6, KEY_7, KEY_8, KEY_9, KEY_0, - KEY_MINUS, KEY_EQUAL, KEY_BACKSPACE, KEY_TAB, - KEY_Q, KEY_W, KEY_E, KEY_R, KEY_T, KEY_Y, KEY_U, KEY_I, KEY_O, KEY_P, - KEY_LEFT_BRACKET, KEY_RIGHT_BRACKET, KEY_RETURN, KEY_LEFT_CTRL, - KEY_A, KEY_S, KEY_D, KEY_F, KEY_G, KEY_H, KEY_J, KEY_K, KEY_L, - KEY_SEMICOLON, KEY_APOSTROPHE, KEY_BACK_TICK, KEY_LEFT_SHIFT, KEY_BACKSLASH, - KEY_Z, KEY_X, KEY_C, KEY_V, KEY_B, KEY_N, KEY_M, - KEY_COMMA, KEY_PERIOD, KEY_SLASH, KEY_RIGHT_SHIFT, - KEYPAD_ASTERISK, KEY_LEFT_ALT, KEY_SPACE, KEY_CAPS_LOCK, - KEY_F1, KEY_F2, KEY_F3, KEY_F4, KEY_F5, KEY_F6, KEY_F7, KEY_F8, KEY_F9, KEY_F10, - KEY_NUM_LOCK, KEY_SCROLL_LOCK, - KEYPAD_7, KEYPAD_8, KEYPAD_9, KEYPAD_MINUS, - KEYPAD_4, KEYPAD_5, KEYPAD_6, KEYPAD_PLUS, - KEYPAD_1, KEYPAD_2, KEYPAD_3, KEYPAD_0, KEYPAD_PERIOD, - KEY_NULL, KEY_NULL, KEY_NULL, - KEY_F11, KEY_F12}; - -const unsigned short ScanCodeSet1mm[] = { - [0x10] = KEY_MULTIMEDIA_PREV_TRACK, - [0x19] = KEY_MULTIMEDIA_NEXT_TRACK, - [0x1C] = KEYPAD_RETURN, - [0x1D] = KEY_RIGHT_CTRL, - [0x20] = KEY_MULTIMEDIA_MUTE, - [0x21] = KEY_MULTIMEDIA_CALCULATOR, - [0x22] = KEY_MULTIMEDIA_PLAY, - [0x24] = KEY_MULTIMEDIA_STOP, - [0x2A] = KEY_PRINT_SCREEN, - [0x2E] = KEY_MULTIMEDIA_VOL_DOWN, - [0x30] = KEY_MULTIMEDIA_VOL_UP, - [0x32] = KEY_MULTIMEDIA_WWW_HOME, - [0x35] = KEYPAD_SLASH, - [0x37] = KEY_PRINT_SCREEN, - [0x38] = KEY_RIGHT_ALT, - [0x47] = KEY_HOME, - [0x48] = KEY_UP_ARROW, - [0x49] = KEY_PAGE_UP, - [0x4B] = KEY_LEFT_ARROW, - [0x4D] = KEY_RIGHT_ARROW, - [0x4F] = KEY_END, - [0x50] = KEY_DOWN_ARROW, - [0x51] = KEY_PAGE_DOWN, - [0x52] = KEY_INSERT, - [0x53] = KEY_DELETE, - [0x5B] = KEY_LEFT_GUI, - [0x5C] = KEY_RIGHT_GUI, - [0x5D] = KEY_APPS, - [0x5E] = KEY_ACPI_POWER, - [0x5F] = KEY_ACPI_SLEEP, - [0x63] = KEY_ACPI_WAKE, - [0x65] = KEY_MULTIMEDIA_WWW_SEARCH, - [0x66] = KEY_MULTIMEDIA_WWW_FAVORITES, - [0x67] = KEY_MULTIMEDIA_WWW_REFRESH, - [0x68] = KEY_MULTIMEDIA_WWW_STOP, - [0x69] = KEY_MULTIMEDIA_WWW_FORWARD, - [0x6A] = KEY_MULTIMEDIA_WWW_BACK, - [0x6B] = KEY_MULTIMEDIA_MY_COMPUTER, - [0x6C] = KEY_MULTIMEDIA_EMAIL, - [0x6D] = KEY_MULTIMEDIA_MEDIA_SELECT, - - /* RELEASED */ - - [0x90] = KEY_MULTIMEDIA_PREV_TRACK, - [0x99] = KEY_MULTIMEDIA_NEXT_TRACK, - [0x9C] = KEYPAD_RETURN, - [0x9D] = KEY_RIGHT_CTRL, - [0xA0] = KEY_MULTIMEDIA_MUTE, - [0xA1] = KEY_MULTIMEDIA_CALCULATOR, - [0xA2] = KEY_MULTIMEDIA_PLAY, - [0xA4] = KEY_MULTIMEDIA_STOP, - [0xAA] = KEY_PRINT_SCREEN, - [0xAE] = KEY_MULTIMEDIA_VOL_DOWN, - [0xB0] = KEY_MULTIMEDIA_VOL_UP, - [0xB2] = KEY_MULTIMEDIA_WWW_HOME, - [0xB5] = KEYPAD_SLASH, - [0xB7] = KEY_PRINT_SCREEN, - [0xB8] = KEY_RIGHT_ALT, - [0xC7] = KEY_HOME, - [0xC8] = KEY_UP_ARROW, - [0xC9] = KEY_PAGE_UP, - [0xCB] = KEY_LEFT_ARROW, - [0xCD] = KEY_RIGHT_ARROW, - [0xCF] = KEY_END, - [0xD0] = KEY_DOWN_ARROW, - [0xD1] = KEY_PAGE_DOWN, - [0xD2] = KEY_INSERT, - [0xD3] = KEY_DELETE, - [0xDB] = KEY_LEFT_GUI, - [0xDC] = KEY_RIGHT_GUI, - [0xDD] = KEY_APPS, - [0xDE] = KEY_ACPI_POWER, - [0xDF] = KEY_ACPI_SLEEP, - [0xE3] = KEY_ACPI_WAKE, - [0xE5] = KEY_MULTIMEDIA_WWW_SEARCH, - [0xE6] = KEY_MULTIMEDIA_WWW_FAVORITES, - [0xE7] = KEY_MULTIMEDIA_WWW_REFRESH, - [0xE8] = KEY_MULTIMEDIA_WWW_STOP, - [0xE9] = KEY_MULTIMEDIA_WWW_FORWARD, - [0xEA] = KEY_MULTIMEDIA_WWW_BACK, - [0xEB] = KEY_MULTIMEDIA_MY_COMPUTER, - [0xEC] = KEY_MULTIMEDIA_EMAIL, - [0xED] = KEY_MULTIMEDIA_MEDIA_SELECT}; - -const unsigned short ScanCodeSet3[] = { - [0x15] = KEY_Q, - [0x1A] = KEY_Z, - [0x1B] = KEY_S, - [0x1C] = KEY_A, - [0x1D] = KEY_W, - - [0x21] = KEY_C, - [0x22] = KEY_X, - [0x23] = KEY_D, - [0x24] = KEY_E, - [0x2A] = KEY_V, - [0x2B] = KEY_F, - [0x2C] = KEY_T, - [0x2D] = KEY_R, - - [0x31] = KEY_N, - [0x32] = KEY_B, - [0x33] = KEY_H, - [0x34] = KEY_G, - [0x35] = KEY_Y, - [0x3A] = KEY_M, - [0x3B] = KEY_J, - [0x3C] = KEY_U, - - [0x42] = KEY_K, - [0x43] = KEY_I, - [0x44] = KEY_O, - [0x4B] = KEY_L, - [0x4D] = KEY_P}; - -InputReport kir = {0}; -int ReportKeyboardEvent(dev_t Device, KeyScanCodes ScanCode, uint8_t Pressed) -{ - kir.Type = INPUT_TYPE_KEYBOARD; - kir.Device = Device; - kir.Keyboard.Key = ScanCode; - kir.Keyboard.Key |= Pressed ? KEY_PRESSED : 0; - ReportInputEvent(&kir); - return 0; -} - -bool IsE0 = false; -bool IsE1 = false; -void PS2KbdInterruptHandler(TrapFrame *) -{ - uint8_t sc = inb(PS2_DATA); - if (sc == PS2_KBD_RESP_ACK || - sc == PS2_KBD_RESP_ECHO || - sc == PS2_KBD_RESP_RESEND) - return; - - if (sc == 0xE0) - { - IsE0 = true; - return; - } - - if (sc == 0xE1) - { - IsE1 = true; - return; - } - - switch (KeyboardScanCodeSet) - { - case PS2_KBD_SC_SET_1: - case PS2_KBD_SC_SET_2: - { - if (IsE0) - { - IsE0 = false; - ReportKeyboardEvent(KeyboardDevID, ScanCodeSet1mm[sc], sc < 0x90); - return; - } - else - { - bool released = sc & 0x80; - uint8_t scFinal = released ? sc & 0x7F : sc; - ReportKeyboardEvent(KeyboardDevID, ScanCodeSet1[scFinal], !released); - return; - } - } - /* FIXME: https://wiki.osdev.org/PS/2_Keyboard */ - // case PS2_KBD_SC_SET_2: - // { - // break; - // } - case PS2_KBD_SC_SET_3: - { - ReportKeyboardEvent(KeyboardDevID, ScanCodeSet3[sc], true); - ReportKeyboardEvent(KeyboardDevID, ScanCodeSet3[sc], false); - break; - } - default: - { - if (IsE0) - IsE0 = false; - KernelLog("Unknown PS/2 Keyboard Scan Code Set: %#x", KeyboardScanCodeSet); - break; - } - } -} - -int __fs_kb_Ioctl(struct Inode *, unsigned long, void *) -{ - return 0; -} - -const struct InodeOperations KbdOps = { - .Ioctl = __fs_kb_Ioctl, -}; - -int InitializeKeyboard() -{ - // PS2WriteData(PS2_KBD_CMD_RESET); - // uint8_t test = PS2ReadData(); - // if (test != PS2_KBD_RESP_TEST_PASSED && - // test != PS2_KBD_RESP_ACK) - // { - // KernelLog("PS/2 keyboard reset failed (%#x)", test); - // return -EFAULT; - // } - - PS2WriteData(PS2_KBD_CMD_DEFAULTS); - if (PS2ACKTimeout() != 0) - KernelLog("PS/2 keyboard failed to set defaults"); - - PS2WriteData(PS2_KBD_CMD_SCAN_CODE_SET); - if (PS2ACKTimeout() != 0) - KernelLog("PS/2 keyboard failed to set scan code set"); - - /* We want Scan Code Set 1 */ - PS2WriteData(PS2_KBD_SCAN_CODE_SET_2); /* It will set to 1 but with translation? */ - if (PS2ACKTimeout() != 0) - KernelLog("PS/2 keyboard failed to set scan code set 2"); - - PS2WriteData(PS2_KBD_CMD_SCAN_CODE_SET); - if (PS2ACKTimeout() != 0) - KernelLog("PS/2 keyboard failed to set scan code set"); - - PS2WriteData(PS2_KBD_SCAN_CODE_GET_CURRENT); - if (PS2ACKTimeout() != 0) - KernelLog("PS/2 keyboard failed to get current scan code set"); - - KeyboardScanCodeSet = PS2ReadAfterACK(); - KernelLog("PS/2 Keyboard Scan Code Set: 0x%X", KeyboardScanCodeSet); - PS2ClearOutputBuffer(); - - PS2WriteData(PS2_KBD_CMD_ENABLE_SCANNING); - - RegisterInterruptHandler(1, PS2KbdInterruptHandler); - - KeyboardDevID = RegisterDevice(INPUT_TYPE_KEYBOARD, &KbdOps); - return 0; -} - -int FinalizeKeyboard() -{ - PS2WriteData(PS2_KBD_CMD_DISABLE_SCANNING); - if (PS2ACKTimeout() != 0) - KernelLog("PS/2 keyboard failed to disable scanning"); - - UnregisterDevice(KeyboardDevID); - return 0; -} - -int DetectPS2Keyboard() -{ - PS2WriteData(PS2_KBD_CMD_DISABLE_SCANNING); - if (PS2ACKTimeout() != 0) - KernelLog("PS/2 keyboard failed to disable scanning"); - - PS2WriteData(PS2_KBD_CMD_IDENTIFY); - if (PS2ACKTimeout() != 0) - KernelLog("PS/2 keyboard failed to identify"); - - uint8_t recByte; - int timeout = 1000000; - while (timeout--) - { - recByte = PS2ReadData(); - if (recByte != PS2_ACK) - break; - } - Device1ID[0] = recByte; - - timeout = 1000000; - while (timeout--) - { - recByte = PS2ReadData(); - if (recByte != PS2_ACK) - break; - } - if (timeout == 0) - KernelLog("PS/2 keyboard second byte timed out"); - else - Device1ID[1] = recByte; - - KernelLog("PS2 Keyboard Device: 0x%X 0x%X", Device1ID[0], Device1ID[1]); - return 0; -} diff --git a/Drivers/input/aip/main.c b/Drivers/input/aip/main.c deleted file mode 100644 index aa53058c..00000000 --- a/Drivers/input/aip/main.c +++ /dev/null @@ -1,235 +0,0 @@ -/* - This file is part of Fennix Drivers. - - Fennix Drivers is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. - - Fennix Drivers is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Fennix Drivers. If not, see . -*/ - -#include "aip.h" - -#include -#include - -bool IsKeyboard(uint8_t ID) -{ - /* Common keyboard IDs */ - return ID == 0xAB || ID == 0xAC || ID == 0x5D || - ID == 0x2B || ID == 0x47 || ID == 0x60; -} - -bool IsMouse(uint8_t ID) -{ - /* Common mouse IDs */ - return ID == 0x00 || ID == 0x03 || ID == 0x04; -} - -const char *GetPS2DeviceName(uint8_t ID, uint8_t SubID) -{ - switch (ID) - { - case 0x00: - return "Standard PS/2 Mouse"; - case 0x03: - return "Mouse with scroll wheel"; - case 0x04: - return "Mouse 5 buttons"; - case 0xAB: - { - switch (SubID) - { - case 0x83: /* Normal */ - case 0x41: /* Translated */ - case 0xC1: /* Normal + Translated */ - return "Standard PS/2 Keyboard"; - case 0x84: - case 0x54: - return "IBM Thinkpad/Spacesaver Keyboard"; - case 0x85: - return "NCD N-97/122-Key Host Connect(ed) Keyboard"; - case 0x86: - return "122-Key Keyboard"; - case 0x90: - return "Japanese \"G\" Keyboard"; - case 0x91: - return "Japanese \"P\" Keyboard"; - case 0x92: - return "Japanese \"A\" Keyboard"; - default: - return "Unknown PS/2 Keyboard"; - } - } - case 0xAC: - { - switch (SubID) - { - case 0xA1: - return "NCD Sun Keyboard"; - default: - return "Unknown NCD Sun Keyboard"; - } - } - case 0x5D: - case 0x2B: - return "Trust Keyboard"; - case 0x47: - case 0x60: - return "NMB SGI Keyboard"; - default: - return "Unknown PS/2 Device"; - } -} - -uint8_t Device1ID[2] = {0x00, 0x00}; -uint8_t Device2ID[2] = {0x00, 0x00}; -bool DualChannel = false; - -int DriverEntry() -{ - PS2WriteCommand(PS2_CMD_DISABLE_PORT_1); - PS2WriteCommand(PS2_CMD_DISABLE_PORT_2); - PS2ClearOutputBuffer(); - - PS2WriteCommand(PS2_CMD_READ_CONFIG); - PS2_CONFIGURATION cfg = {.Raw = PS2ReadData()}; - - DualChannel = cfg.Port2Clock; - if (DualChannel) - KernelLog("Dual channel PS/2 controller detected"); - cfg.Port1Interrupt = 1; - cfg.Port2Interrupt = 1; - cfg.Port1Translation = 1; - - PS2WriteCommand(PS2_CMD_WRITE_CONFIG); - PS2WriteData(cfg.Raw); - - PS2WriteCommand(PS2_CMD_TEST_CONTROLLER); - uint8_t test = PS2ReadData(); - if (test != PS2_TEST_PASSED) - { - KernelLog("PS/2 controller self test failed (%#x)", test); - return -EFAULT; - } - - PS2WriteCommand(PS2_CMD_WRITE_CONFIG); - PS2WriteData(cfg.Raw); - - // bool port2avail = false; - // if (DualChannel) - // { - // PS2WriteCommand(PS2_CMD_ENABLE_PORT_1); - // PS2WriteCommand(PS2_CMD_READ_CONFIG); - // cfg.Raw = PS2ReadData(); - // port2avail = cfg.Port2Clock; - // PS2WriteCommand(PS2_CMD_DISABLE_PORT_1); - // } - - PS2WriteCommand(PS2_CMD_TEST_PORT_1); - test = PS2ReadData(); - if (test != 0x00) - { - KernelLog("PS/2 Port 1 self test failed (%#x)", test); - return -EFAULT; - } - - if (DualChannel) - { - PS2WriteCommand(PS2_CMD_TEST_PORT_2); - test = PS2ReadData(); - if (test != 0x00) - { - KernelLog("PS/2 Port 2 self test failed (%#x)", test); - return -EFAULT; - } - } - - PS2WriteCommand(PS2_CMD_ENABLE_PORT_1); - if (DualChannel) - PS2WriteCommand(PS2_CMD_ENABLE_PORT_2); - - int errK = InitializeKeyboard(); - - int errM = 0; - if (DualChannel) - errM = InitializeMouse(); - - /** A device may fail, but if the other one works, - * we can still use it. - */ - if (errK != 0 && errM != 0) - return -ENODEV; - return 0; -} - -int DriverFinal() -{ - FinalizeKeyboard(); - FinalizeMouse(); - PS2WriteCommand(PS2_CMD_DISABLE_PORT_1); - PS2WriteCommand(PS2_CMD_DISABLE_PORT_2); - return 0; -} - -int DriverPanic() -{ - PS2WriteCommand(PS2_CMD_DISABLE_PORT_1); - PS2WriteCommand(PS2_CMD_DISABLE_PORT_2); - return 0; -} - -void __intStub() {} -int DriverProbe() -{ - RegisterInterruptHandler(1, __intStub); - RegisterInterruptHandler(12, __intStub); - - int kbd = DetectPS2Keyboard(); - int mouse = DetectPS2Mouse(); - int uart = DetectUART(); - - UnregisterAllInterruptHandlers(__intStub); - - if (kbd != 0 && mouse != 0 && uart != 0) - return -ENODEV; - - if (kbd == 0) - { - if (!IsKeyboard(Device1ID[0])) - { - KernelLog("PS/2 Port 1 is not a keyboard"); - // return -EINVAL; - } - } - - if (mouse == 0) - { - if (!IsMouse(Device2ID[0])) - { - KernelLog("PS/2 Port 2 is not a mouse"); - // return -EINVAL; - } - } - - KernelPrint("PS/2 Port 1: %s (0x%X 0x%X)", - GetPS2DeviceName(Device1ID[0], Device1ID[1]), - Device1ID[0], Device1ID[1]); - KernelPrint("PS/2 Port 2: %s (0x%X 0x%X)", - GetPS2DeviceName(Device2ID[0], Device2ID[1]), - Device2ID[0], Device2ID[1]); - return 0; -} - -DriverInfo("aip", - "Advanced Integrated Peripheral Driver", - "EnderIce2", - 0, 0, 1, - "GPLv3"); diff --git a/Drivers/input/aip/mouse.c b/Drivers/input/aip/mouse.c deleted file mode 100644 index 284ccd05..00000000 --- a/Drivers/input/aip/mouse.c +++ /dev/null @@ -1,244 +0,0 @@ -/* - This file is part of Fennix Drivers. - - Fennix Drivers is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. - - Fennix Drivers is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Fennix Drivers. If not, see . -*/ - -#include "aip.h" - -#include -#include -#include -#include - -dev_t MouseDevID = -1; -bool PacketReady = false; -bool FourPackets = false; -bool MouseButton45 = false; -uint8_t Cycle = 0; -PS2_MOUSE_PACKET Packet = {0}; - -InputReport mir = {0}; -void PS2MouseInterruptHandler(TrapFrame *) -{ - uint8_t data = PS2ReadData(); - if (data == PS2_MOUSE_RESP_ACK || - data == PS2_MOUSE_RESP_RESEND) - return; - - if (!PacketReady) - { - switch (Cycle) - { - case 0: - { - if ((data & 0b00001000 /* Always 1 */) == 0) - return; - - Packet.Base.Raw = data; - Cycle++; - break; - } - case 1: - { - Packet.XMovement = data; - Cycle++; - break; - } - case 2: - { - Packet.YMovement = data; - if (FourPackets) - Cycle++; - else - { - Cycle = 0; - PacketReady = true; - } - break; - } - case 3: - { - Packet.ZMovement.Raw = data; - Cycle = 0; - PacketReady = true; - break; - } - default: - break; - } - return; - } - -/* https://stackoverflow.com/a/3208376/9352057 */ -#define BYTE_TO_BINARY_PATTERN "%c%c%c%c%c%c%c%c" -#define BYTE_TO_BINARY(byte) \ - ((byte) & 0x80 ? '1' : '0'), \ - ((byte) & 0x40 ? '1' : '0'), \ - ((byte) & 0x20 ? '1' : '0'), \ - ((byte) & 0x10 ? '1' : '0'), \ - ((byte) & 0x08 ? '1' : '0'), \ - ((byte) & 0x04 ? '1' : '0'), \ - ((byte) & 0x02 ? '1' : '0'), \ - ((byte) & 0x01 ? '1' : '0') - - DebugLog("PS/2 Mouse Packet: [" BYTE_TO_BINARY_PATTERN ":" BYTE_TO_BINARY_PATTERN ":" BYTE_TO_BINARY_PATTERN ":" BYTE_TO_BINARY_PATTERN "] LB:%d RB:%d MB:%d A1:%d XS:%d YS:%d XO:%d YO:%d | X:%03d Y:%03d | Z:%d B4:%d B5:%d A0:%d A0:%d", - BYTE_TO_BINARY(Packet.Base.Raw), - BYTE_TO_BINARY(Packet.XMovement), - BYTE_TO_BINARY(Packet.YMovement), - BYTE_TO_BINARY(Packet.ZMovement.Raw), - Packet.Base.LeftButton, Packet.Base.RightButton, Packet.Base.MiddleButton, - Packet.Base.Always1, - Packet.Base.XSign, Packet.Base.YSign, - Packet.Base.XOverflow, Packet.Base.YOverflow, - Packet.XMovement, Packet.YMovement, - Packet.ZMovement.Z, Packet.ZMovement.Button4, Packet.ZMovement.Button5, - Packet.ZMovement.Always0, Packet.ZMovement.Always0_2); - - int X, Y; - X = Packet.XMovement - (Packet.Base.XSign ? 256 : 0); - Y = Packet.YMovement - (Packet.Base.YSign ? 256 : 0); - - if (Packet.Base.XOverflow) - X = 0; - - if (Packet.Base.YOverflow) - Y = 0; - - mir.Type = INPUT_TYPE_MOUSE; - mir.Device = MouseDevID; - mir.Mouse.LeftButton = Packet.Base.LeftButton; - mir.Mouse.RightButton = Packet.Base.RightButton; - mir.Mouse.MiddleButton = Packet.Base.MiddleButton; - mir.Mouse.Button4 = Packet.ZMovement.Button4; - mir.Mouse.Button5 = Packet.ZMovement.Button5; - mir.Mouse.X = X; - mir.Mouse.Y = -Y; - mir.Mouse.Z = Packet.ZMovement.Z; - ReportInputEvent(&mir); - PacketReady = false; -} - -void MouseSampleRate(uint8_t SampleRate) -{ - PS2WriteCommand(PS2_CMD_WRITE_NEXT_BYTE_TO_PS2_PORT_2_INPUT); - PS2WriteData(PS2_MOUSE_CMD_SET_SAMPLE_RATE); - PS2ReadData(); - - PS2WriteCommand(PS2_CMD_WRITE_NEXT_BYTE_TO_PS2_PORT_2_INPUT); - PS2WriteData(SampleRate); - PS2ReadData(); -} - -int __fs_ms_Ioctl(struct Inode *, unsigned long, void *) -{ - return 0; -} - -const struct InodeOperations MouseOps = { - .Ioctl = __fs_ms_Ioctl, -}; - -int InitializeMouse() -{ - PS2WriteData(PS2_CMD_WRITE_NEXT_BYTE_TO_PS2_PORT_2_INPUT); - PS2WriteData(PS2_MOUSE_CMD_RESET); - uint8_t test = PS2ReadData(); - if (test != PS2_MOUSE_RESP_TEST_PASSED && - test != PS2_MOUSE_RESP_ACK) - { - KernelLog("PS/2 mouse reset failed! (%#x)", test); - return -EFAULT; - } - - RegisterInterruptHandler(12, PS2MouseInterruptHandler); - - MouseDevID = RegisterDevice(INPUT_TYPE_MOUSE, &MouseOps); - - PS2WriteCommand(PS2_CMD_WRITE_NEXT_BYTE_TO_PS2_PORT_2_INPUT); - PS2WriteData(PS2_MOUSE_CMD_SET_DEFAULTS); - PS2ReadData(); - - PS2WriteCommand(PS2_CMD_WRITE_NEXT_BYTE_TO_PS2_PORT_2_INPUT); - PS2WriteData(PS2_MOUSE_CMD_ENABLE_DATA_REPORTING); - - MouseSampleRate(200); - MouseSampleRate(100); - MouseSampleRate(80); - - PS2WriteCommand(PS2_CMD_WRITE_NEXT_BYTE_TO_PS2_PORT_2_INPUT); - PS2WriteData(PS2_MOUSE_CMD_READ_ID); - uint8_t Device2ID = PS2ReadData(); - KernelLog("PS/2 Mouse ID: %#x", Device2ID); - - MouseSampleRate(200); - MouseSampleRate(200); - MouseSampleRate(80); - - PS2WriteCommand(PS2_CMD_WRITE_NEXT_BYTE_TO_PS2_PORT_2_INPUT); - PS2WriteData(PS2_MOUSE_CMD_READ_ID); - Device2ID = PS2ReadData(); - KernelLog("PS/2 Mouse ID: %#x", Device2ID); - - if (Device2ID >= 3 && Device2ID <= 4) - FourPackets = true; - if (Device2ID == 4) - MouseButton45 = true; - - return 0; -} - -int FinalizeMouse() -{ - PS2WriteCommand(PS2_CMD_WRITE_NEXT_BYTE_TO_PS2_PORT_2_INPUT); - PS2WriteData(PS2_MOUSE_CMD_DISABLE_DATA_REPORTING); - - UnregisterDevice(MouseDevID); - return 0; -} - -int DetectPS2Mouse() -{ - PS2WriteCommand(PS2_CMD_WRITE_NEXT_BYTE_TO_PS2_PORT_2_INPUT); - PS2WriteData(PS2_MOUSE_CMD_DISABLE_DATA_REPORTING); - if (PS2ACKTimeout() != 0) - KernelLog("PS/2 mouse failed to disable data reporting!"); - - PS2WriteCommand(PS2_CMD_WRITE_NEXT_BYTE_TO_PS2_PORT_2_INPUT); - PS2WriteData(PS2_MOUSE_CMD_READ_ID); - if (PS2ACKTimeout() != 0) - KernelLog("PS/2 mouse failed to read ID!"); - - uint8_t recByte; - int timeout = 1000000; - while (timeout--) - { - recByte = PS2ReadData(); - if (recByte != PS2_ACK) - break; - } - Device2ID[0] = recByte; - - timeout = 1000000; - while (timeout--) - { - recByte = PS2ReadData(); - if (recByte != PS2_ACK) - break; - } - Device2ID[1] = recByte; - - KernelLog("PS2 Mouse Device: 0x%X 0x%X", Device2ID[0], Device2ID[1]); - return 0; -} diff --git a/Drivers/input/aip/uart.c b/Drivers/input/aip/uart.c deleted file mode 100644 index 832ef8f6..00000000 --- a/Drivers/input/aip/uart.c +++ /dev/null @@ -1,646 +0,0 @@ -/* - This file is part of Fennix Drivers. - - Fennix Drivers is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. - - Fennix Drivers is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Fennix Drivers. If not, see . -*/ - -#include "aip.h" - -#include -#include -#include -#include -#include - -#define SERIAL_ENABLE_DLAB 0x80 -#define SERIAL_BUFFER_EMPTY 0x20 - -enum Ports -{ - COM1 = 0x3F8, - COM2 = 0x2F8, - COM3 = 0x3E8, - COM4 = 0x2E8, - COM5 = 0x5F8, - COM6 = 0x4F8, - COM7 = 0x5E8, - COM8 = 0x4E8, - - LPT1 = 0x378, - LPT2 = 0x278, - LPT3 = 0x3BC -}; - -enum SerialSpeed -{ - RATE_50_HI = 0x09, - RATE_50_LO = 0x00, - - RATE_300_HI = 0x01, - RATE_300_LO = 0x80, - - RATE_600_HI = 0x00, - RATE_600_LO = 0xC0, - - RATE_2400_HI = 0x00, - RATE_2400_LO = 0x30, - - RATE_4800_HI = 0x00, - RATE_4800_LO = 0x18, - - RATE_9600_HI = 0x00, - RATE_9600_LO = 0x0C, - - RATE_19200_HI = 0x00, - RATE_19200_LO = 0x06, - - RATE_38400_HI = 0x00, - RATE_38400_LO = 0x03, - - RATE_57600_HI = 0x00, - RATE_57600_LO = 0x02, - - RATE_115200_HI = 0x00, - RATE_115200_LO = 0x01 -}; - -/* -. Table of Registers . -/---------------------------------------------------------------------\ -| Base Address | DLAB | R/W | Abr | Register Name | -|---------------------------------------------------------------------| -| +0 | =0 | W | - | Transmitter Holding Buffer | -| | =0 | R | - | Receiver Buffer | -| | =1 | R/W | - | Divisor Latch Low Byte | -| +1 | =0 | R/W | IER | Interrupt Enable Register | -| | =1 | R/W | - | Divisor Latch High Byte | -| +2 | - | R | IIR | Interrupt Identification Register | -| | - | W | FCR | FIFO Control Register | -| +3 | - | R/W | LCR | Line Control Register | -| +4 | - | R/W | MCR | Modem Control Register | -| +5 | - | R | LSR | Line Status Register | -| +6 | - | R | MSR | Modem Status Register | -| +7 | - | R/W | - | Scratch Register | -\---------------------------------------------------------------------/ - - Source: - Interfacing the Serial / RS232 Port V5.0 - Table 5 : Table of Registers -*/ - -/** Interrupt Enable Register */ -typedef union -{ - struct - { - /* Enable Received Data Available Interrupt */ - uint8_t InterruptOnReceive : 1; - - /* Enable Transmitter Holding Register Empty Interrupt */ - uint8_t InterruptOnTransmitter : 1; - - /* Enable Receiver Line Status Interrupt */ - uint8_t LineStatusInterrupt : 1; - - /* Enable Modem Status Interrupt */ - uint8_t ModemStatusInterrupt : 1; - - /* Enables Sleep Mode (16750) */ - uint8_t SleepMode : 1; - - /* Enables Low Power Mode (16750) */ - uint8_t LowPowerMode : 1; - - /* Reserved */ - uint8_t __reserved : 2; - }; - uint8_t raw; -} IER; - -/** Interrupt Identification Register */ -typedef union -{ - struct - { - /* Interrupt pending */ - uint8_t InterruptPending : 1; - - /** - * Interrupt Status - * - * 00b = Modem Status Interrupt - * 01b = Transmitter Holding Register Empty Interrupt - * 10b = Received Data Available Interrupt - * 11b = Receiver Line Status Interrupt - */ - uint8_t InterruptStatus : 2; - - /** - * 16550 Time-out Interrupt Pending - * - * @note Reserved on 8250, 16450 - */ - uint8_t TimeOutIP : 1; - - /** Reserved */ - uint8_t __reserved : 1; - - /** 64 Byte Fifo Enabled (16750 only) */ - uint8_t FIFO64 : 1; - - /** - * Enable FIFO - * - * 00b = No FIFO - * 01b = FIFO Enabled but Unusable - * 11b = FIFO Enabled - */ - uint8_t FIFO : 2; - }; - uint8_t raw; -} IIR; - -/** First In / First Out Control Register */ -typedef union -{ - struct - { - /** Enable FIFO's */ - uint8_t FIFO : 1; - - /** Clear Receive FIFO */ - uint8_t ClearRX : 1; - - /** Clear Transmit FIFO */ - uint8_t ClearTX : 1; - - /** DMA Mode Select. - * - * Change status of RXRDY & TXRDY pins from mode 1 to mode 2. - */ - uint8_t DMAMode : 1; - - /** Reserved */ - uint8_t __reserved : 1; - - /** Enable 64 Byte FIFO (16750 only) */ - uint8_t FIFO64 : 1; - - /** Interrupt Trigger Level - * - * 00b = 1 Byte - * 01b = 4 Bytes - * 10b = 8 Bytes - * 11b = 14 Bytes - */ - uint8_t TriggerLevel : 2; - }; - uint8_t raw; -} FCR; - -/** Line Control Register */ -typedef union -{ - struct - { - /** Word Length - * - * 00b = 5 bits - * 01b = 6 bits - * 10b = 7 bits - * 11b = 8 bits - */ - uint8_t WordLength : 2; - - /** Length of Stop Bit - * - * 0b = One Stop Bit - * 1b = 2 Stop bits for words of length 6,7 or 8 bits or 1.5 Stop Bits for Word lengths of 5 bits. - */ - uint8_t StopBit : 1; - - /** Parity Select - * - * 0b = No Parity - * 001b = Odd Parity - * 011b = Even Parity - * 101b = High Parity (Sticky) - * 111b = Low Parity (Sticky) - */ - uint8_t Parity : 3; - - /** Set Break Enable */ - uint8_t SetBreak : 1; - - /** - * Divisor Latch Access - * - * 0b = Access to Receiver buffer, Transmitter buffer & Interrupt Enable Register - * 1b = Divisor Latch Access Bit - */ - uint8_t DLAB : 1; - }; - uint8_t raw; -} LCR; - -/** Modem Control Register */ -typedef union -{ - struct - { - /** Force Data Terminal Ready */ - uint8_t DataTerminalReady : 1; - - /** Force Request to Send */ - uint8_t RequestToSend : 1; - - /** Auxiliary Output 1 */ - uint8_t Out1 : 1; - - /** Auxiliary Output 2 */ - uint8_t Out2 : 1; - - /** Loopback Mode */ - uint8_t Loopback : 1; - - /** Autoflow Control Enabled (16750 only) */ - uint8_t Autoflow : 1; - - /** Reserved */ - uint8_t __reserved : 2; - }; - uint8_t raw; -} MCR; - -/** Line Status Register */ -typedef union -{ - struct - { - /** Data Ready */ - uint8_t DataReady : 1; - - /** Overrun Error */ - uint8_t OverrunError : 1; - - /** Parity Error */ - uint8_t ParityError : 1; - - /** Framing Error */ - uint8_t FramingError : 1; - - /** Break Interrupt */ - uint8_t BreakInterrupt : 1; - - /** Empty Transmitter Holding Register */ - uint8_t EmptyTransmitterHolding : 1; - - /** Empty Data Holding Registers */ - uint8_t EmptyDataHolding : 1; - - /** Error in Received FIFO */ - uint8_t ErrorReceivedFIFO : 1; - }; - uint8_t raw; -} LSR; - -/** Modem Status Register */ -typedef union -{ - struct - { - /** Delta Clear to Send */ - uint8_t DeltaClearToSend : 1; - - /** Delta Data Set Ready */ - uint8_t DeltaDataSetReady : 1; - - /** Trailing Edge Ring Indicator */ - uint8_t TrailingEdgeRingIndicator : 1; - - /** Delta Data Carrier Detect */ - uint8_t DeltaDataCarrierDetect : 1; - - /** Clear To Send */ - uint8_t ClearToSend : 1; - - /** Data Set Ready */ - uint8_t DataSetReady : 1; - - /** Ring Indicator */ - uint8_t RingIndicator : 1; - - /** Carrier Detect */ - uint8_t CarrierDetect : 1; - }; - uint8_t raw; -} MSR; - -union UARTs -{ - struct - { - uint8_t com1 : 1; - uint8_t com2 : 1; - uint8_t com3 : 1; - uint8_t com4 : 1; - uint8_t com5 : 1; - uint8_t com6 : 1; - uint8_t com7 : 1; - uint8_t com8 : 1; - - uint8_t lpt1 : 1; - uint8_t lpt2 : 1; - uint8_t lpt3 : 1; - - uint8_t __reserved : 5; - }; - uint16_t raw; -} uart; - -bool IsDataReady(uint16_t Port) -{ - LSR lsr; - lsr.raw = inb(Port + 5); - return lsr.DataReady; -} - -bool IsTransmitEmpty(uint16_t Port) -{ - LSR lsr; - lsr.raw = inb(Port + 5); - return lsr.EmptyTransmitterHolding; -} - -char ReadSerial(uint16_t Port) -{ - while (!IsDataReady(Port)) - Yield(); - return inb(Port); -} - -void WriteSerial(uint16_t Port, char Character) -{ - while (!IsTransmitEmpty(Port)) - Yield(); - outb(Port, Character); -} - -void ReportSerialReceived(uint8_t Data) -{ - DebugLog("%c", Data); -} - -void UartCOM24(TrapFrame *) -{ - LSR lsr2, lsr4; - do - { - lsr2.raw = inb(COM2 + 5); - if (lsr2.DataReady) - ReportSerialReceived(inb(COM2)); - lsr4.raw = inb(COM4 + 5); - if (lsr4.DataReady) - ReportSerialReceived(inb(COM4)); - } while (lsr2.DataReady || lsr4.DataReady); -} - -void UartCOM13(TrapFrame *) -{ - LSR lsr1, lsr3; - do - { - lsr1.raw = inb(COM1 + 5); - if (lsr1.DataReady) - ReportSerialReceived(inb(COM1)); - lsr3.raw = inb(COM3 + 5); - if (lsr3.DataReady) - ReportSerialReceived(inb(COM3)); - } while (lsr1.DataReady || lsr3.DataReady); -} - -bool InitializePort(uint16_t Port) -{ - ECS; - LCR lcr = {0}; - IER ier = {0}; - FCR fcr = {0}; - MCR mcr = {0}; - - outb(Port + 3, lcr.raw); - outb(Port + 1, ier.raw); - - lcr.DLAB = 1; - outb(Port + 3, lcr.raw); - - outb(Port + 0, RATE_115200_LO); - outb(Port + 1, RATE_115200_HI); - - lcr.DLAB = 0; - lcr.WordLength = 0b11; - outb(Port + 3, lcr.raw); - - fcr.FIFO = 1; - fcr.ClearRX = 1; - fcr.ClearTX = 1; - fcr.TriggerLevel = 0b11; - outb(Port + 2, fcr.raw); - - mcr.DataTerminalReady = 1; - mcr.RequestToSend = 1; - mcr.Out2 = 1; - mcr.Loopback = 1; - outb(Port + 4, mcr.raw); - - /* Test the serial port */ - outb(Port + 0, 0x48); - uint8_t result = inb(Port + 0); - if (result != 0x48) - { - /* FIXME: DETECT BAUD RATE - Do multiple test to check if the output is garbage. - If so, reduce the baud rate until it works. */ - - LCS; - KernelPrint("Port %#X test failed!", Port); - return false; - } - - /* Set normal operation mode */ - mcr.DataTerminalReady = 1; - mcr.RequestToSend = 1; - mcr.Out1 = 1; - mcr.Out2 = 1; - mcr.Loopback = 0; - outb(Port + 4, mcr.raw); - - /* Enable interrupts on receive */ - ier.InterruptOnReceive = 1; - outb(Port + 1, ier.raw); - RegisterInterruptHandler(3, UartCOM24); - RegisterInterruptHandler(4, UartCOM13); - - LCS; - KernelPrint("Port %#X initialized", Port); - return true; -} - -int DetectUART() -{ - uart.com1 = inb(COM1) != 0xFF ? true : false; - uart.com2 = inb(COM2) != 0xFF ? true : false; - uart.com3 = inb(COM3) != 0xFF ? true : false; - uart.com4 = inb(COM4) != 0xFF ? true : false; - uart.com5 = inb(COM5) != 0xFF ? true : false; - uart.com6 = inb(COM6) != 0xFF ? true : false; - uart.com7 = inb(COM7) != 0xFF ? true : false; - uart.com8 = inb(COM8) != 0xFF ? true : false; - - uart.lpt1 = inb(LPT1) != 0xFF ? true : false; - uart.lpt2 = inb(LPT2) != 0xFF ? true : false; - uart.lpt3 = inb(LPT3) != 0xFF ? true : false; - - if (uart.com1 == true) - if (InitializePort(COM1) == false) - uart.com1 = false; - - if (uart.com2 == true) - if (InitializePort(COM2) == false) - uart.com1 = false; - - if (uart.com3 == true) - if (InitializePort(COM3) == false) - uart.com1 = false; - - if (uart.com4 == true) - if (InitializePort(COM4) == false) - uart.com1 = false; - - if (uart.com5 == true) - if (InitializePort(COM5) == false) - uart.com1 = false; - - if (uart.com6 == true) - if (InitializePort(COM6) == false) - uart.com1 = false; - - if (uart.com7 == true) - if (InitializePort(COM7) == false) - uart.com1 = false; - - if (uart.com8 == true) - if (InitializePort(COM8) == false) - uart.com1 = false; - - if (uart.lpt1 == true) - KernelPrint("LPT1 is present"); - - if (uart.lpt2 == true) - KernelPrint("LPT2 is present"); - - if (uart.lpt3 == true) - KernelPrint("LPT3 is present"); - return 0; -} - -// static int once = 0; -// static uint8_t com4 = 0xFF; -// if (!once++) -// com4 = inb(0x2E8); -// if (com4 == 0xFF) -// CPU::Halt(true); -// char UserInputBuffer[256]{'\0'}; -// int BackSpaceLimit = 0; -// while (true) -// { -// while ((inb(0x2E8 + 5) & 1) == 0) -// CPU::Pause(); -// char key = inb(0x2E8); -// // debug("key: %d", key); -// if (key == '\x7f') /* Backspace (DEL) */ -// { -// if (BackSpaceLimit <= 0) -// continue; -// char keyBuf[5] = {'\b', '\x1b', '[', 'K', '\0'}; -// ExPrint(keyBuf); -// backspace(UserInputBuffer); -// BackSpaceLimit--; -// continue; -// } -// else if (key == '\x0d') /* Enter (CR) */ -// { -// UserInput(UserInputBuffer); -// BackSpaceLimit = 0; -// UserInputBuffer[0] = '\0'; -// continue; -// } -// else if (key == '\x1b') /* Escape */ -// { -// char tmp[16]{'\0'}; -// append(tmp, key); -// while ((inb(0x2E8 + 5) & 1) == 0) -// CPU::Pause(); -// char key = inb(0x2E8); -// append(tmp, key); -// if (key == '[') -// { -// // 27 91 -// // < 68 -// // > 67 -// // down 66 -// // up 65 -// while ((inb(0x2E8 + 5) & 1) == 0) -// CPU::Pause(); -// key = inb(0x2E8); -// append(tmp, key); -// switch (key) -// { -// case 'A': -// key = KEY_D_UP; -// break; -// case 'B': -// key = KEY_D_DOWN; -// break; -// case 'C': -// key = KEY_D_RIGHT; -// break; -// case 'D': -// key = KEY_D_LEFT; -// break; -// default: -// { -// for (size_t i = 0; i < strlen(tmp); i++) -// { -// if ((int)sizeof(UserInputBuffer) <= BackSpaceLimit) -// continue; -// append(UserInputBuffer, tmp[i]); -// BackSpaceLimit++; -// char keyBuf[2] = {(char)tmp[i], '\0'}; -// ExPrint(keyBuf); -// } -// continue; -// } -// } -// ArrowInput(key); -// continue; -// } -// } - -// if ((int)sizeof(UserInputBuffer) <= BackSpaceLimit) -// continue; -// append(UserInputBuffer, key); -// BackSpaceLimit++; -// char keyBuf[2] = {(char)key, '\0'}; -// ExPrint(keyBuf); -// } diff --git a/Drivers/misc/vmware/Makefile b/Drivers/misc/vmware/Makefile deleted file mode 100644 index 9a92e2ef..00000000 --- a/Drivers/misc/vmware/Makefile +++ /dev/null @@ -1,35 +0,0 @@ -default: - $(error Do not run this Makefile directly!) - -S_SOURCES = $(shell find ./ -type f -name '*.S') -C_SOURCES = $(shell find ./ -type f -name '*.c') -CXX_SOURCES = $(shell find ./ -type f -name '*.cpp') -HEADERS = $(sort $(dir $(wildcard ../../include/*))) -OBJ = $(C_SOURCES:.c=.o) $(CXX_SOURCES:.cpp=.o) $(S_SOURCES:.S=.o) -STACK_USAGE_OBJ = $(C_SOURCES:.c=.su) $(CXX_SOURCES:.cpp=.su) - -FILENAME = $(notdir $(shell pwd)).drv - -build: $(FILENAME) - mv $(FILENAME) $(OUTPUT_DIR)$(FILENAME) - -$(FILENAME): $(OBJ) - $(info Linking $@) - $(CC) $(DRIVER_LDFLAGS) $(OBJ) $(OUTPUT_DIR)dcrt0.o -L$(OUTPUT_DIR) -lkernel -o $@ - -WARNCFLAG = -Wall -Wextra - -%.o: %.c $(HEADERS) - $(info Compiling $<) - $(CC) $(DRIVER_CFLAGS) $(WARNCFLAG) -std=c17 -c $< -o $@ - -%.o: %.cpp $(HEADERS) - $(info Compiling $<) - $(CXX) $(DRIVER_CFLAGS) $(WARNCFLAG) -std=c++20 -fno-exceptions -fno-rtti -c $< -o $@ - -%.o: %.S - $(info Compiling $<) - $(AS) -o $@ $< - -clean: - rm -f file.map $(OBJ) $(STACK_USAGE_OBJ) diff --git a/Drivers/misc/vmware/main.c b/Drivers/misc/vmware/main.c deleted file mode 100644 index 4519c7cf..00000000 --- a/Drivers/misc/vmware/main.c +++ /dev/null @@ -1,897 +0,0 @@ -/* - This file is part of Fennix Drivers. - - Fennix Drivers is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. - - Fennix Drivers is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Fennix Drivers. If not, see . -*/ - -#include -#include -#include -#include -#include -#include -#include -#include - -enum RPCMessages -{ - MSG_OPEN, - MSG_SENDSIZE, - MSG_SENDPAYLOAD, - MSG_RECVSIZE, - MSG_RECVPAYLOAD, - MSG_RECVSTATUS, - MSG_CLOSE, -}; - -enum RPCStatus -{ - STATUS_SUCCESS = 0x1, - STATUS_DORECV = 0x2, - STATUS_CPT = 0x10, - STATUS_HB = 0x80, -}; - -typedef struct -{ - union - { - uint32_t ax; - uint32_t magic; - }; - union - { - uint32_t bx; - size_t size; - }; - union - { - uint32_t cx; - uint16_t command; - }; - union - { - uint32_t dx; - uint16_t port; - }; - uint32_t si; - uint32_t di; -} VMwareCommand; - -#define VMWARE_MAGIC 0x564D5868 - -#define VMWARE_PORT 0x5658 -#define VMWARE_PORTHB 0x5659 - -#define VMWARE_HYPERVISOR_HB 0x00000000 -#define VMWARE_HYPERVISOR_OUT 0x00000001 - -#define CMD_GETVERSION 0xA -#define CMD_MESSAGE 0x1E -#define CMD_ABSPOINTER_DATA 0x27 -#define CMD_ABSPOINTER_STATUS 0x28 -#define CMD_ABSPOINTER_COMMAND 0x29 - -#define ABSPOINTER_ENABLE 0x45414552 -#define ABSPOINTER_RELATIVE 0xF5 -#define ABSPOINTER_ABSOLUTE 0x53424152 - -#define MESSAGE_RPCI 0x49435052 -#define MESSAGE_TCLO 0x4f4c4354 - -#define FLAG_COOKIE 0x80000000 - -#define ToMsg(x) ((x) << 16 | CMD_MESSAGE) -#define HighWord(x) ((x & 0xFFFF0000) >> 16) - -#define MESSAGE_HB_MSG 0 - -#define MESSAGE_OPEN_CHANNEL ToMsg(MSG_OPEN) -#define MESSAGE_CLOSE_CHANNEL ToMsg(MSG_CLOSE) - -#define MESSAGE_SEND_SIZE ToMsg(MSG_SENDSIZE) -#define MESSAGE_SEND_PAYLOAD ToMsg(MSG_SENDPAYLOAD) - -#define MESSAGE_RECV_SIZE ToMsg(MSG_RECVSIZE) -#define MESSAGE_RECV_PAYLOAD ToMsg(MSG_RECVPAYLOAD) -#define MESSAGE_RECV_STATUS ToMsg(MSG_RECVSTATUS) - -#if defined(__amd64__) - -#define VM_PORT(cmd, in_ebx, isi, idi, \ - flags, magic, \ - ax, bx, cx, dx, si, di) \ - __asm__ __volatile__("movw $0x5658, %%dx\n" \ - "inl %%dx, %%eax\n" \ - : "=a"(ax), \ - "=b"(bx), \ - "=c"(cx), \ - "=d"(dx), \ - "=S"(si), \ - "=D"(di) \ - : "a"(magic), \ - "b"(in_ebx), \ - "c"(cmd), \ - "d"(flags), \ - "S"(isi), \ - "D"(idi) : "memory") - -#define VM_PORT_HB_OUT(cmd, in_ecx, isi, idi, \ - flags, magic, bp, \ - ax, bx, cx, dx, si, di) \ - __asm__ __volatile__("push %%rbp\n" \ - "mov %12, %%rbp\n" \ - "movw $0x5659, %%dx\n" \ - "rep outsb\n" \ - "pop %%rbp\n" \ - : "=a"(ax), \ - "=b"(bx), \ - "=c"(cx), \ - "=d"(dx), \ - "=S"(si), \ - "=D"(di) \ - : "a"(magic), \ - "b"(cmd), \ - "c"(in_ecx), \ - "d"(flags), \ - "S"(isi), \ - "D"(idi), \ - "r"(bp) : "memory", "cc") - -#define VM_PORT_HB_IN(cmd, in_ecx, isi, idi, \ - flags, magic, bp, \ - ax, bx, cx, dx, si, di) \ - __asm__ __volatile__("push %%rbp\n" \ - "mov %12, %%rbp\n" \ - "movw $0x5659, %%dx\n" \ - "rep insb\n" \ - "pop %%rbp\n" \ - : "=a"(ax), \ - "=b"(bx), \ - "=c"(cx), \ - "=d"(dx), \ - "=S"(si), \ - "=D"(di) \ - : "a"(magic), \ - "b"(cmd), \ - "c"(in_ecx), \ - "d"(flags), \ - "S"(isi), \ - "D"(idi), \ - "r"(bp) : "memory", "cc") - -#elif defined(__i386__) - -#define VM_PORT(cmd, in_ebx, isi, idi, \ - flags, magic, \ - ax, bx, cx, dx, si, di) - -#define VM_PORT_HB_OUT(cmd, in_ecx, isi, idi, \ - flags, \ - magic, bp, ax, \ - bx, cx, dx, si, di) - -#define VM_PORT_HB_IN(cmd, in_ecx, isi, idi, \ - flags, magic, bp, \ - ax, bx, cx, dx, si, di) - -#endif - -/* TODO: - - use vmcall or vmmcall instead of "out" and "in" if available -*/ - -typedef struct -{ - int TCLOChannel; - uint16_t ChannelID; - uint32_t CookieHigh; - uint32_t CookieLow; -} ToolboxContext; - -dev_t MouseDevID = -1; - -int __strcmp(const char *l, const char *r) -{ - for (; *l == *r && *l; l++, r++) - ; - - return *(unsigned char *)l - *(unsigned char *)r; -} - -void __cpuid(uint32_t Function, - uint32_t *eax, uint32_t *ebx, - uint32_t *ecx, uint32_t *edx) -{ - asmv("cpuid" - : "=a"(*eax), "=b"(*ebx), "=c"(*ecx), "=d"(*edx) - : "a"(Function)); -} - -bool __CheckHypervisorBit() -{ - uint32_t eax, ebx, ecx, edx; - __cpuid(0x1, &eax, &ebx, &ecx, &edx); - if (!(ecx & (1 << 31))) - return false; /* Hypervisor not detected */ - return true; -} - -bool __VMwareBackdoorHypervisors() -{ - const char hv[13] = {0}; - uint32_t eax, ebx, ecx, edx; - __cpuid(0x40000000, &eax, &ebx, &ecx, &edx); - - *(uint32_t *)hv = ebx; - *(uint32_t *)(hv + 4) = ecx; - *(uint32_t *)(hv + 8) = edx; - - if (__strcmp(hv, "VMwareVMware") != 0 && - __strcmp(hv, "KVMKVMKVM") != 0 && - __strcmp(hv, "TCGTCGTCGTCG") != 0) - { - return false; - } - return true; -} - -bool IsVMwareBackdoorAvailable() -{ - if (!__CheckHypervisorBit()) - return false; - - if (!__VMwareBackdoorHypervisors()) - return false; - - struct - { - union - { - uint32_t ax; - uint32_t magic; - }; - union - { - uint32_t bx; - size_t size; - }; - union - { - uint32_t cx; - uint16_t command; - }; - union - { - uint32_t dx; - uint16_t port; - }; - uint32_t si; - uint32_t di; - } cmd; - - cmd.si = cmd.di = 0; - cmd.bx = ~0x564D5868; - cmd.command = 0xA; - cmd.magic = 0x564D5868; - cmd.port = 0x5658; - - asmv("in %%dx, %0" - : "+a"(cmd.ax), "+b"(cmd.bx), - "+c"(cmd.cx), "+d"(cmd.dx), - "+S"(cmd.si), "+D"(cmd.di)); - - if (cmd.bx != 0x564D5868 || - cmd.ax == 0xFFFFFFFF) - return false; - return true; -} - -static int OpenMessageChannel(ToolboxContext *ctx, uint32_t Protocol) -{ - uintptr_t ax, bx, cx, dx, si = 0, di = 0; - - VM_PORT(MESSAGE_OPEN_CHANNEL, - (Protocol | FLAG_COOKIE), si, di, - 0, VMWARE_MAGIC, - ax, bx, cx, dx, si, di); - - if ((HighWord(cx) & STATUS_SUCCESS) == 0) - { - KernelLog("Failed to open message channel %#lx", Protocol); - return -EINVAL; - } - - DebugLog("Opened message channel %d (Protocol: %#lx)", - HighWord(dx), Protocol); - ctx->ChannelID = (uint16_t)HighWord(dx); - ctx->CookieHigh = si; - ctx->CookieLow = di; - return 0; -} - -static void MessageClose(ToolboxContext *ctx) -{ - uintptr_t ax, bx, cx, dx, - si = ctx->CookieHigh, - di = ctx->CookieLow; - - VM_PORT(MESSAGE_CLOSE_CHANNEL, - 0, si, di, - ctx->ChannelID << 16, - VMWARE_MAGIC, - ax, bx, cx, dx, si, di); - - DebugLog("Closed message channel %d", ctx->ChannelID); -} - -static uintptr_t MessageSendHB(ToolboxContext *ctx, - const char *Message) -{ - uintptr_t ax, bx, cx, dx, - si = (uintptr_t)Message, - di = ctx->CookieLow, - bp = ctx->CookieHigh; - - uint32_t ChannelID = ctx->ChannelID << 16; - size_t Size = StringLength(Message); - - VM_PORT_HB_OUT((STATUS_SUCCESS << 16) | MESSAGE_HB_MSG, - Size, si, di, - VMWARE_HYPERVISOR_HB | ChannelID | VMWARE_HYPERVISOR_OUT, - VMWARE_MAGIC, bp, - ax, bx, cx, dx, si, di); - - return bx; -} - -static uintptr_t MessageSendLB(ToolboxContext *ctx, - const char *Message) -{ - uintptr_t ax, bx, - cx = STATUS_SUCCESS << 16, - dx, si, di; - - size_t Size = StringLength(Message); - while (Size && - (HighWord(cx) & STATUS_SUCCESS)) - { - uint32_t TotalBytes = MIN((uint32_t)Size, (uint32_t)4); - uint32_t Word = 0; - MemoryCopy(&Word, Message, TotalBytes); - Message += TotalBytes; - - si = ctx->CookieHigh; - di = ctx->CookieLow; - - VM_PORT(MESSAGE_SEND_PAYLOAD, - Word, si, di, - ctx->ChannelID << 16, - VMWARE_MAGIC, - ax, bx, cx, dx, si, di); - } - - return cx; -} - -static uintptr_t MessageReceiveHB(ToolboxContext *ctx, - char *Buffer, - size_t BufferSize) -{ - uintptr_t ax, bx, cx, dx, - si = ctx->CookieHigh, - di = (uintptr_t)Buffer, - bp = ctx->CookieLow; - - uint32_t ChannelID = ctx->ChannelID << 16; - - VM_PORT_HB_IN((STATUS_SUCCESS << 16) | MESSAGE_HB_MSG, - BufferSize, si, di, - VMWARE_HYPERVISOR_HB | ChannelID | VMWARE_HYPERVISOR_OUT, - VMWARE_MAGIC, bp, - ax, bx, cx, dx, si, di); - - return bx; -} - -static uintptr_t MessageReceiveLB(ToolboxContext *ctx, - char *Buffer, - size_t BufferSize) -{ - uintptr_t ax, bx, - cx = STATUS_SUCCESS << 16, - dx, si, di; - - while (BufferSize) - { - uint32_t TotalBytes = MIN((uint32_t)BufferSize, (uint32_t)4); - - si = ctx->CookieHigh; - di = ctx->CookieLow; - - VM_PORT(MESSAGE_RECV_PAYLOAD, - STATUS_SUCCESS, si, di, - ctx->ChannelID << 16, - VMWARE_MAGIC, - ax, bx, cx, dx, si, di); - - if ((HighWord(cx) & STATUS_SUCCESS) == 0) - break; - - MemoryCopy(Buffer, &bx, TotalBytes); - Buffer += TotalBytes; - BufferSize -= TotalBytes; - } - - return cx; -} - -static int MessageSend(ToolboxContext *ctx, - const char *Message) -{ - uintptr_t ax, bx, cx, dx, si, di; - size_t Size = StringLength(Message); - int Retries = 0; - - while (Retries < 2) - { - Retries++; - si = ctx->CookieHigh; - di = ctx->CookieLow; - - VM_PORT(MESSAGE_SEND_SIZE, - Size, si, di, - ctx->ChannelID << 16, - VMWARE_MAGIC, - ax, bx, cx, dx, si, di); - - if ((HighWord(cx) & STATUS_SUCCESS) == 0) - { - KernelLog("Failed to send message size for \"%s\": %d", - Message, cx); - return -EINVAL; - } - - bool HighBand = (HighWord(cx) & STATUS_HB) != 0; - if (HighBand) - bx = MessageSendHB(ctx, Message); - else - bx = MessageSendLB(ctx, Message); - - int status = HighWord(bx); - - if ((status & STATUS_SUCCESS) != 0) - { - DebugLog("Message \"%s\" sent", Message); - return 0; - } - else if ((status & STATUS_CPT) == 0) - { - KernelLog("Checkpoint occurred for message \"%s\"", Message); - continue; - } - else - break; - } - - KernelLog("Failed to send message \"%s\": %#lx", Message, bx); - return -EINVAL; -} - -static int MessageReceive(ToolboxContext *ctx, - char **Buffer, - size_t *BufferSize) -{ - uintptr_t ax, bx, cx, dx, si, di; - int Retries = 0; - - *Buffer = NULL; - *BufferSize = 0; - - char *ReplyBuf = NULL; - size_t ReplyBufPages = 0; - size_t ReplySize = 0; - while (Retries < 2) - { - Retries++; - si = ctx->CookieHigh; - di = ctx->CookieLow; - - VM_PORT(MESSAGE_RECV_SIZE, - 0, si, di, - ctx->ChannelID << 16, - VMWARE_MAGIC, - ax, bx, cx, dx, si, di); - - if ((HighWord(cx) & STATUS_SUCCESS) == 0) - { - KernelLog("Failed to receive message size: %d", cx); - return -EINVAL; - } - else if ((HighWord(cx) & STATUS_DORECV) == 0) - { - DebugLog("No message to receive"); - return -EAGAIN; - } - - ReplySize = bx; - - if (ReplyBuf != NULL) - FreeMemory(ReplyBuf, ReplyBufPages); - ReplyBufPages = ReplySize / 0x1000 + 1; - ReplyBuf = AllocateMemory(ReplyBufPages); - - bool HighBand = (HighWord(cx) & STATUS_HB) != 0; - if (HighBand) - bx = MessageReceiveHB(ctx, ReplyBuf, ReplySize); - else - bx = MessageReceiveLB(ctx, ReplyBuf, ReplySize); - - if ((HighWord(bx) & STATUS_SUCCESS) == 0) - { - if ((HighWord(bx) & STATUS_CPT) == 0) - { - KernelLog("Checkpoint occurred for message payload"); - continue; - } - - KernelLog("Failed to receive message payload: %d", HighWord(bx)); - FreeMemory(ReplyBuf, ReplyBufPages); - return -EINVAL; - } - - ReplyBuf[ReplySize] = '\0'; - - si = ctx->CookieHigh; - di = ctx->CookieLow; - - VM_PORT(MESSAGE_RECV_STATUS, - STATUS_SUCCESS, si, di, - ctx->ChannelID << 16, - VMWARE_MAGIC, - ax, bx, cx, dx, si, di); - - if ((HighWord(cx) & STATUS_SUCCESS) == 0) - { - if ((HighWord(cx) & STATUS_CPT) == 0) - { - KernelLog("Retrying message receive"); - continue; - } - - KernelLog("Failed to receive message status: %d", HighWord(cx)); - FreeMemory(ReplyBuf, ReplyBufPages); - return -EINVAL; - } - - break; - } - - if (ReplyBuf == NULL) - { - KernelLog("Failed to receive message"); - return -EINVAL; - } - - *Buffer = ReplyBuf; - *BufferSize = ReplySize; - DebugLog("Received message \"%s\"", ReplyBuf); - return 0; -} - -static int SendRPCI(ToolboxContext *, const char *Request) -{ - ToolboxContext rpci_ctx = {0}; - int status = OpenMessageChannel(&rpci_ctx, MESSAGE_RPCI); - if (status < 0) - { - KernelLog("Failed to open RPCI channel: %d", status); - return status; - } - - status = MessageSend(&rpci_ctx, Request); - if (status < 0) - { - KernelLog("Failed to send RPCI request: %d", status); - return status; - } - - MessageClose(&rpci_ctx); - return 0; -} - -int MsgEqual(const char *haystack, const char *needle) -{ - return strstr(haystack, needle) == haystack; -} - -static int DisplayGetSize(ToolboxContext *ctx) -{ - if (ctx->TCLOChannel != -1) - MessageClose(ctx); - OpenMessageChannel(ctx, MESSAGE_TCLO); - - char EmptyBuffer[256] = {'\0'}; - MessageSend(ctx, EmptyBuffer); - - while (true) - { - /* FIXME: buf memory leak */ - char *buf; - size_t len; - - int status = MessageReceive(ctx, &buf, &len); - if (status == -EAGAIN) - { - Sleep(1000); - continue; - } - else if (status < 0) - { - KernelLog("Failed to receive message"); - return 1; - } - - buf[StringLength(buf)] = '\0'; - if (MsgEqual(buf, "reset")) - { - if (MessageSend(ctx, "OK ATR toolbox") < 0) - return 1; - } - else if (MsgEqual(buf, "ping")) - { - if (MessageSend(ctx, "OK ") < 0) - return 1; - } - else if (MsgEqual(buf, "Capabilities_Register")) - { - SendRPCI(ctx, "tools.capability.resolution_set 1"); - SendRPCI(ctx, "tools.capability.resolution_server toolbox 1"); - SendRPCI(ctx, "tools.capability.display_topology_set 1"); - SendRPCI(ctx, "tools.capability.color_depth_set 1"); - SendRPCI(ctx, "tools.capability.resolution_min 0 0"); - SendRPCI(ctx, "tools.capability.unity 1"); - - if (MessageSend(ctx, "OK ") < 0) - return 1; - } - else if (MsgEqual(buf, "Resolution_Set")) - { - DebugLog("%s", buf); - if (MessageSend(ctx, "OK ") < 0) - return 1; - MessageClose(ctx); - return 0; - } - else - { - if (MessageSend(ctx, "ERROR Unknown command") < 0) - return 1; - } - } -} - -pid_t dst_id = -1; -pid_t dst_pid = -1; -ToolboxContext *tb_ctx = NULL; -void DisplayScaleThread() -{ - /* sizeof ToolboxContext */ - tb_ctx = AllocateMemory(1); - Sleep(2000); - - while (true) - { - if (DisplayGetSize(tb_ctx) != 0) - KernelLog("Failed to scale display"); - Sleep(1000); - } -} - -void CommandSend(VMwareCommand *cmd) -{ - cmd->magic = VMWARE_MAGIC; - cmd->port = VMWARE_PORT; - asm volatile("in %%dx, %0" - : "+a"(cmd->ax), "+b"(cmd->bx), - "+c"(cmd->cx), "+d"(cmd->dx), - "+S"(cmd->si), "+D"(cmd->di)); -} - -void Absolute() -{ - VMwareCommand cmd = {0}; - - /* Enable */ - cmd.bx = ABSPOINTER_ENABLE; - cmd.command = CMD_ABSPOINTER_COMMAND; - CommandSend(&cmd); - - /* Status */ - cmd.bx = 0; - cmd.command = CMD_ABSPOINTER_STATUS; - CommandSend(&cmd); - - /* Read data (1) */ - cmd.bx = 1; - cmd.command = CMD_ABSPOINTER_DATA; - CommandSend(&cmd); - - /* Enable absolute */ - cmd.bx = ABSPOINTER_ABSOLUTE; - cmd.command = CMD_ABSPOINTER_COMMAND; - CommandSend(&cmd); -} - -void Relative() -{ - VMwareCommand cmd = {0}; - cmd.bx = ABSPOINTER_RELATIVE; - cmd.command = CMD_ABSPOINTER_COMMAND; - CommandSend(&cmd); -} - -InputReport ir = {0}; -void InterruptHandler(TrapFrame *) -{ - uint8_t Data = inb(0x60); - (void)Data; - - VMwareCommand cmd = {0}; - cmd.bx = 0; - cmd.command = CMD_ABSPOINTER_STATUS; - CommandSend(&cmd); - - if (cmd.ax == 0xFFFF0000) - { - KernelLog("VMware mouse is not connected?"); - Relative(); - Absolute(); - return; - } - - if ((cmd.ax & 0xFFFF) < 4) - return; - - cmd.bx = 4; - cmd.command = CMD_ABSPOINTER_DATA; - CommandSend(&cmd); - - int Buttons = (cmd.ax & 0xFFFF); - - /** - * How should I handle this? - * (cmd.[bx,cx] * Width) / 0xFFFF - * Maybe TODO: Width and Height API? - */ - uintptr_t AbsoluteX = cmd.bx; - uintptr_t AbsoluteY = cmd.cx; - - ir.Type = INPUT_TYPE_MOUSE; - ir.Device = MouseDevID; - ir.Mouse.X = AbsoluteX; - ir.Mouse.Y = AbsoluteY; - ir.Mouse.Z = (int8_t)cmd.dx; - ir.Mouse.Absolute = 1; - ir.Mouse.LeftButton = Buttons & 0x20; - ir.Mouse.RightButton = Buttons & 0x10; - ir.Mouse.MiddleButton = Buttons & 0x08; - // ir.Mouse.Button4 = 0x0; - // ir.Mouse.Button5 = 0x0; - // ir.Mouse.Button6 = 0x0; - // ir.Mouse.Button7 = 0x0; - // ir.Mouse.Button8 = 0x0; - ReportInputEvent(&ir); -} - -int __fs_Ioctl(struct Inode *, unsigned long Request, void *) -{ - switch (Request) - { - case 0x1: - Relative(); - break; - case 0x2: - Absolute(); - break; - default: - return -EINVAL; - } - return 0; -} - -const struct InodeOperations MouseOps = { - .Ioctl = __fs_Ioctl, -}; - -bool ToolboxSupported = false; -int DriverEntry() -{ - ToolboxContext tb_ctx = {0}; - /* Test if it's supported */ - int status = OpenMessageChannel(&tb_ctx, MESSAGE_TCLO); - if (status == 0) - { - ToolboxSupported = true; - MessageClose(&tb_ctx); - dst_id = CreateKernelThread(0, "VMware Display Scale", - (void *)DisplayScaleThread, NULL); - dst_pid = GetCurrentProcess(); - } - - PS2WriteCommand(PS2_CMD_ENABLE_PORT_2); - PS2WriteCommand(PS2_CMD_READ_CONFIG); - PS2_CONFIGURATION config = {.Raw = PS2ReadData()}; - config.Port2Interrupt = 1; - PS2WriteCommand(PS2_CMD_WRITE_CONFIG); - PS2WriteData(config.Raw); - - PS2WriteCommand(PS2_CMD_WRITE_NEXT_BYTE_TO_PS2_PORT_2_INPUT); - PS2WriteData(PS2_MOUSE_CMD_SET_DEFAULTS); - PS2ReadData(); - - PS2WriteCommand(PS2_CMD_WRITE_NEXT_BYTE_TO_PS2_PORT_2_INPUT); - PS2WriteData(PS2_MOUSE_CMD_ENABLE_DATA_REPORTING); - PS2ReadData(); - Absolute(); - - /** - * If we have another driver using the PS/2 mouse, we need to - * override its interrupt handler. - */ - OverrideInterruptHandler(12, InterruptHandler); - - MouseDevID = RegisterDevice(INPUT_TYPE_MOUSE, &MouseOps); - return 0; -} - -int DriverFinal() -{ - PS2WriteCommand(PS2_CMD_WRITE_NEXT_BYTE_TO_PS2_PORT_2_INPUT); - PS2WriteData(PS2_MOUSE_CMD_DISABLE_DATA_REPORTING); - - Relative(); - - UnregisterDevice(MouseDevID); - - if (ToolboxSupported) - { - KillThread(dst_id, dst_pid, 0); - if (tb_ctx->TCLOChannel != -1) - MessageClose(tb_ctx); - FreeMemory(tb_ctx, 1); - } - return 0; -} - -int DriverPanic() -{ - Relative(); - PS2WriteCommand(PS2_CMD_WRITE_NEXT_BYTE_TO_PS2_PORT_2_INPUT); - PS2WriteData(PS2_MOUSE_CMD_DISABLE_DATA_REPORTING); - return 0; -} - -int DriverProbe() -{ - if (!IsVMwareBackdoorAvailable()) - return -ENODEV; - return 0; -} - -DriverInfo("vmware", - "VMware Tools Driver", - "EnderIce2", - 0, 0, 1, - "GPLv3"); diff --git a/Drivers/network/e1000/Makefile b/Drivers/network/e1000/Makefile deleted file mode 100644 index 9a92e2ef..00000000 --- a/Drivers/network/e1000/Makefile +++ /dev/null @@ -1,35 +0,0 @@ -default: - $(error Do not run this Makefile directly!) - -S_SOURCES = $(shell find ./ -type f -name '*.S') -C_SOURCES = $(shell find ./ -type f -name '*.c') -CXX_SOURCES = $(shell find ./ -type f -name '*.cpp') -HEADERS = $(sort $(dir $(wildcard ../../include/*))) -OBJ = $(C_SOURCES:.c=.o) $(CXX_SOURCES:.cpp=.o) $(S_SOURCES:.S=.o) -STACK_USAGE_OBJ = $(C_SOURCES:.c=.su) $(CXX_SOURCES:.cpp=.su) - -FILENAME = $(notdir $(shell pwd)).drv - -build: $(FILENAME) - mv $(FILENAME) $(OUTPUT_DIR)$(FILENAME) - -$(FILENAME): $(OBJ) - $(info Linking $@) - $(CC) $(DRIVER_LDFLAGS) $(OBJ) $(OUTPUT_DIR)dcrt0.o -L$(OUTPUT_DIR) -lkernel -o $@ - -WARNCFLAG = -Wall -Wextra - -%.o: %.c $(HEADERS) - $(info Compiling $<) - $(CC) $(DRIVER_CFLAGS) $(WARNCFLAG) -std=c17 -c $< -o $@ - -%.o: %.cpp $(HEADERS) - $(info Compiling $<) - $(CXX) $(DRIVER_CFLAGS) $(WARNCFLAG) -std=c++20 -fno-exceptions -fno-rtti -c $< -o $@ - -%.o: %.S - $(info Compiling $<) - $(AS) -o $@ $< - -clean: - rm -f file.map $(OBJ) $(STACK_USAGE_OBJ) diff --git a/Drivers/network/e1000/e1000.cpp b/Drivers/network/e1000/e1000.cpp deleted file mode 100644 index 5de1f688..00000000 --- a/Drivers/network/e1000/e1000.cpp +++ /dev/null @@ -1,512 +0,0 @@ -/* - This file is part of Fennix Kernel. - - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. - - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . -*/ - -#include -#include -#include -#include -#include -#include -#include - -#include "e1000.hpp" - -class E1000Device -{ -private: - PCIHeader0 *Header; - uint16_t DeviceID; - bool Initialized = false; - - bool EEPROMAvailable; - - struct BARData - { - uint8_t Type; - uint16_t IOBase; - uint64_t MemoryBase; - } BAR; - -#define E1000_NUM_RX_DESC 32 -#define E1000_NUM_TX_DESC 8 - RXDescriptor *RX[E1000_NUM_RX_DESC]; - TXDescriptor *TX[E1000_NUM_TX_DESC]; - - uint16_t RXCurrent; - uint16_t TXCurrent; - - const int BaseBufferSize = 8192; - const int AdditionalBytes = 16; - - uint32_t CurrentPacket; - - void WriteCMD(uint16_t Address, uint32_t Value) - { - if (BAR.Type == 0) - mmoutl((void *)(BAR.MemoryBase + Address), Value); - else - { - outl(BAR.IOBase, Address); - outl(BAR.IOBase + 4, Value); - } - } - - uint32_t ReadCMD(uint16_t Address) - { - if (BAR.Type == 0) - return mminl((void *)(BAR.MemoryBase + Address)); - else - { - outl(BAR.IOBase, Address); - return inl(BAR.IOBase + 0x4); - } - } - - uint32_t ReadEEPROM(uint8_t Address) - { - uint16_t Data = 0; - uint32_t temp = 0; - if (EEPROMAvailable) - { - WriteCMD(REG::EEPROM, (1) | ((uint32_t)(Address) << 8)); - while (!((temp = ReadCMD(REG::EEPROM)) & (1 << 4))) - ; - } - else - { - WriteCMD(REG::EEPROM, (1) | ((uint32_t)(Address) << 2)); - while (!((temp = ReadCMD(REG::EEPROM)) & (1 << 1))) - ; - } - Data = (uint16_t)((temp >> 16) & 0xFFFF); - return Data; - } - - void InitializeRX() - { - DebugLog("Initializing RX..."); - uintptr_t Ptr = (uintptr_t)AllocateMemory(TO_PAGES(sizeof(RXDescriptor) * - E1000_NUM_RX_DESC + - AdditionalBytes)); - - for (int i = 0; i < E1000_NUM_RX_DESC; i++) - { - RX[i] = (RXDescriptor *)(Ptr + i * 16); - RX[i]->Address = (uint64_t)AllocateMemory(TO_PAGES(BaseBufferSize + AdditionalBytes)); - RX[i]->Status = 0; - } - -#pragma GCC diagnostic ignored "-Wshift-count-overflow" - - WriteCMD(REG::TXDESCLO, (uint32_t)(Ptr >> 32)); - WriteCMD(REG::TXDESCHI, (uint32_t)(Ptr & 0xFFFFFFFF)); - - WriteCMD(REG::RXDESCLO, (uint32_t)Ptr); - WriteCMD(REG::RXDESCHI, 0); - - WriteCMD(REG::RXDESCLEN, E1000_NUM_RX_DESC * 16); - - WriteCMD(REG::RXDESCHEAD, 0); - WriteCMD(REG::RXDESCTAIL, E1000_NUM_RX_DESC - 1); - RXCurrent = 0; - WriteCMD(REG::RCTRL, RCTL::EN | RCTL::SBP | RCTL::UPE | - RCTL::MPE | RCTL::LBM_NONE | - RTCL::RDMTS_HALF | RCTL::BAM | - RCTL::SECRC | RCTL::BSIZE_8192); - } - - void InitializeTX() - { - DebugLog("Initializing TX..."); - uintptr_t Ptr = (uintptr_t)AllocateMemory(TO_PAGES(sizeof(TXDescriptor) * - E1000_NUM_RX_DESC + - AdditionalBytes)); - - for (short i = 0; i < E1000_NUM_TX_DESC; i++) - { - TX[i] = (TXDescriptor *)((uintptr_t)Ptr + i * 16); - TX[i]->Address = 0; - TX[i]->Command = 0; - TX[i]->Status = TSTA::DD; - } - - WriteCMD(REG::TXDESCHI, (uint32_t)((uint64_t)Ptr >> 32)); - WriteCMD(REG::TXDESCLO, (uint32_t)((uint64_t)Ptr & 0xFFFFFFFF)); - - WriteCMD(REG::TXDESCLEN, E1000_NUM_TX_DESC * 16); - - WriteCMD(REG::TXDESCHEAD, 0); - WriteCMD(REG::TXDESCTAIL, 0); - TXCurrent = 0; - WriteCMD(REG::TCTRL, TCTL::EN_ | TCTL::PSP | - (15 << TCTL::CT_SHIFT) | - (64 << TCTL::COLD_SHIFT) | - TCTL::RTLC); - - WriteCMD(REG::TCTRL, 0b0110000000000111111000011111010); - WriteCMD(REG::TIPG, 0x0060200A); - } - -public: - dev_t ID; - - bool IsInitialized() { return Initialized; } - - size_t write(uint8_t *Buffer, size_t Size) - { - TX[TXCurrent]->Address = (uint64_t)Buffer; - TX[TXCurrent]->Length = (uint16_t)Size; - TX[TXCurrent]->Command = CMD::EOP | CMD::IFCS | CMD::RS; - TX[TXCurrent]->Status = 0; - uint16_t OldTXCurrent = TXCurrent; - TXCurrent = (uint16_t)((TXCurrent + 1) % E1000_NUM_TX_DESC); - WriteCMD(REG::TXDESCTAIL, TXCurrent); - while (!(TX[OldTXCurrent]->Status & 0xFF)) - Yield(); - return Size; - } - - MediaAccessControl GetMAC() - { - MediaAccessControl mac; - if (EEPROMAvailable) - { - uint32_t temp; - temp = ReadEEPROM(0); - mac.Address[0] = temp & 0xff; - mac.Address[1] = (uint8_t)(temp >> 8); - temp = ReadEEPROM(1); - mac.Address[2] = temp & 0xff; - mac.Address[3] = (uint8_t)(temp >> 8); - temp = ReadEEPROM(2); - mac.Address[4] = temp & 0xff; - mac.Address[5] = (uint8_t)(temp >> 8); - } - else - { - uint8_t *BaseMac8 = (uint8_t *)(BAR.MemoryBase + 0x5400); - uint32_t *BaseMac32 = (uint32_t *)(BAR.MemoryBase + 0x5400); - if (BaseMac32[0] != 0) - for (int i = 0; i < 6; i++) - mac.Address[i] = BaseMac8[i]; - else - { - KernelLog("No MAC address found."); - return MediaAccessControl(); - } - } - - return mac; - } - - int ioctl(NetIoctl req, void *arg) - { - switch (req) - { - case IOCTL_NET_GET_MAC: - { - MediaAccessControl mac = GetMAC(); - *((uint48_t *)arg) = mac.ToHex(); /* UNTESTED */ - return 0; - } - default: - return -EINVAL; - } - return 0; - } - - void OnInterruptReceived(TrapFrame *) - { - WriteCMD(REG::IMASK, 0x1); - uint32_t status = ReadCMD(0xC0); - UNUSED(status); - - while ((RX[RXCurrent]->Status & 0x1)) - { - uint8_t *data = (uint8_t *)RX[RXCurrent]->Address; - uint16_t dataSz = RX[RXCurrent]->Length; - - // ReportNetworkPacket(ID, data, dataSz); - /* FIXME: Implement */ - KernelLog("FIXME: Received packet"); - (void)data; - (void)dataSz; - - RX[RXCurrent]->Status = 0; - uint16_t OldRXCurrent = RXCurrent; - RXCurrent = (uint16_t)((RXCurrent + 1) % E1000_NUM_RX_DESC); - WriteCMD(REG::RXDESCTAIL, OldRXCurrent); - } - } - - void Panic() - { - WriteCMD(REG::IMASK, 0x00000000); - WriteCMD(REG::ITR, 0x00000000); - WriteCMD(REG::IAM, 0x00000000); - } - - E1000Device(PCIHeader0 *_Header, uint16_t _DeviceID) - : Header(_Header), - DeviceID(_DeviceID) - { - uint32_t PCIBAR0 = Header->BAR0; - uint32_t PCIBAR1 = Header->BAR1; - BAR.Type = PCIBAR0 & 1; - BAR.IOBase = (uint16_t)(PCIBAR0 & (~3)); - BAR.MemoryBase = PCIBAR1 & (~15); - - switch (DeviceID) - { - case 0x100E: - { - KernelLog("Found Intel 82540EM Gigabit Ethernet Controller."); - - /* Detect EEPROM */ - WriteCMD(REG::EEPROM, 0x1); - for (int i = 0; i < 1000 && !EEPROMAvailable; i++) - if (ReadCMD(REG::EEPROM) & 0x10) - EEPROMAvailable = true; - else - EEPROMAvailable = false; - - if (!GetMAC().Valid()) - { - KernelLog("Failed to get MAC"); - return; - } - - /* Start link */ - uint32_t cmdret = ReadCMD(REG::CTRL); - WriteCMD(REG::CTRL, cmdret | ECTRL::SLU); - - for (int i = 0; i < 0x80; i++) - WriteCMD((uint16_t)(0x5200 + i * 4), 0); - - WriteCMD(REG::IMASK, 0x1F6DC); - WriteCMD(REG::IMASK, 0xFF & ~4); - ReadCMD(0xC0); - - InitializeRX(); - InitializeTX(); - break; - } - default: - { - KernelLog("Unimplemented E1000 device."); - return; - } - } - - Initialized = true; - } - - ~E1000Device() - { - if (!Initialized) - return; - - switch (DeviceID) - { - case 0x100E: - { - // Clearing Enable bit in Receive Control Register - uint32_t cmdret = ReadCMD(REG::RCTRL); - WriteCMD(REG::RCTRL, cmdret & ~RCTL::EN); - - // Masking Interrupt Mask, Interrupt Throttling Rate & Interrupt Auto-Mask - WriteCMD(REG::IMASK, 0x00000000); - WriteCMD(REG::ITR, 0x00000000); - WriteCMD(REG::IAM, 0x00000000); - - // Clearing SLU bit in Device Control Register - cmdret = ReadCMD(REG::CTRL); - WriteCMD(REG::CTRL, cmdret & ~ECTRL::SLU); - - // Clear the Interrupt Cause Read register by reading it - ReadCMD(REG::ICR); - - // Powering down the device (?) - WriteCMD(REG::CTRL, PCTRL::POWER_DOWN); - /* TODO: Stop link; further testing required */ - break; - } - default: - { - KernelLog("Unimplemented E1000 device."); - return; - } - } - } -}; - -E1000Device *Drivers[4] = {nullptr}; -dev_t NetID[4] = {(dev_t)-1}; - -#define OIR(x) OIR_##x -#define CREATE_OIR(x) \ - void OIR_##x(TrapFrame *f) { Drivers[x]->OnInterruptReceived(f); } - -CREATE_OIR(0); -CREATE_OIR(1); -CREATE_OIR(2); -CREATE_OIR(3); - -int __fs_Open(struct Inode *, int, mode_t) { return 0; } -int __fs_Close(struct Inode *) { return 0; } -ssize_t __fs_Read(struct Inode *, void *, size_t, off_t) { return 0; } - -ssize_t __fs_Write(struct Inode *Node, const void *Buffer, size_t Size, off_t) -{ - return Drivers[NetID[Node->GetMinor()]]->write((uint8_t *)Buffer, Size); -} - -int __fs_Ioctl(struct Inode *Node, unsigned long Request, void *Argp) -{ - return Drivers[NetID[Node->GetMinor()]]->ioctl((NetIoctl)Request, Argp); -} - -const struct InodeOperations NetOps = { - .Lookup = nullptr, - .Create = nullptr, - .Remove = nullptr, - .Rename = nullptr, - .Read = __fs_Read, - .Write = __fs_Write, - .Truncate = nullptr, - .Open = __fs_Open, - .Close = __fs_Close, - .Ioctl = __fs_Ioctl, - .ReadDir = nullptr, - .MkDir = nullptr, - .RmDir = nullptr, - .SymLink = nullptr, - .ReadLink = nullptr, - .Seek = nullptr, - .Stat = nullptr, -}; - -PCIArray *Devices; -EXTERNC int cxx_Panic() -{ - PCIArray *ctx = Devices; - short Count = 0; - while (ctx != nullptr) - { - if (Drivers[Count] != nullptr) - Drivers[Count]->Panic(); - Count++; - ctx = (PCIArray *)ctx->Next; - } - - return 0; -} - -EXTERNC int cxx_Probe() -{ - uint16_t VendorIDs[] = {0x8086, /* Intel */ - PCI_END}; - uint16_t DeviceIDs[] = {0x100E, /* 82540EM */ - 0x100F, /* 82545EM */ - 0x10D3, /* 82574L */ - 0x10EA, /* I217-LM */ - 0x153A, /* 82577LM */ - PCI_END}; - Devices = GetPCIDevices(VendorIDs, DeviceIDs); - if (Devices == nullptr) - { - KernelLog("No E1000 device found."); - return -ENODEV; - } - return 0; -} - -EXTERNC int cxx_Initialize() -{ - PCIArray *ctx = Devices; - size_t Count = 0; - while (ctx != nullptr) - { - if (Count > sizeof(Drivers) / sizeof(E1000Device *)) - break; - - InitializePCI(ctx->Device); - - Drivers[Count] = new E1000Device((PCIHeader0 *)ctx->Device->Header, - ctx->Device->Header->DeviceID); - - if (Drivers[Count]->IsInitialized()) - { - dev_t ret = RegisterDevice(NETWORK_TYPE_ETHERNET, &NetOps); - NetID[Count] = ret; - Drivers[Count]->ID = ret; - - /* FIXME: bad code */ - switch (Count) - { - case 0: - RegisterInterruptHandler(iLine(ctx->Device), (void *)OIR(0)); - break; - case 1: - RegisterInterruptHandler(iLine(ctx->Device), (void *)OIR(1)); - break; - case 2: - RegisterInterruptHandler(iLine(ctx->Device), (void *)OIR(2)); - break; - case 3: - RegisterInterruptHandler(iLine(ctx->Device), (void *)OIR(3)); - break; - default: - break; - } - - Count++; - } - ctx = (PCIArray *)ctx->Next; - } - - if (Count == 0) - { - KernelLog("No valid E1000 device found."); - return -EINVAL; - } - - return 0; -} - -EXTERNC int cxx_Finalize() -{ - PCIArray *ctx = Devices; - size_t Count = 0; - while (ctx != nullptr) - { - if (Count++ > sizeof(Drivers) / sizeof(E1000Device *)) - break; - - delete Drivers[Count++]; - ctx->Device->Header->Command |= PCI_COMMAND_INTX_DISABLE; - ctx = (PCIArray *)ctx->Next; - } - - for (size_t i = 0; i < sizeof(NetID) / sizeof(dev_t); i++) - { - if (NetID[i] != (dev_t)-1) - UnregisterDevice(NetID[i]); - } - - return 0; -} diff --git a/Drivers/network/e1000/e1000.hpp b/Drivers/network/e1000/e1000.hpp deleted file mode 100644 index 73c6848e..00000000 --- a/Drivers/network/e1000/e1000.hpp +++ /dev/null @@ -1,163 +0,0 @@ -/* - This file is part of Fennix Drivers. - - Fennix Drivers is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. - - Fennix Drivers is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Fennix Drivers. If not, see . -*/ - -#pragma once - -#include - -#ifdef __cplusplus -enum REG -{ - CTRL = 0x0000, - STATUS = 0x0008, - ICR = 0x000C, - EEPROM = 0x0014, - CTRL_EXT = 0x0018, - ITR = 0x00C4, - IMASK = 0x00D0, - IAM = 0x00D8, - RCTRL = 0x0100, - RXDESCLO = 0x2800, - RXDESCHI = 0x2804, - RXDESCLEN = 0x2808, - RXDESCHEAD = 0x2810, - RXDESCTAIL = 0x2818, - TCTRL = 0x0400, - TXDESCLO = 0x3800, - TXDESCHI = 0x3804, - TXDESCLEN = 0x3808, - TXDESCHEAD = 0x3810, - TXDESCTAIL = 0x3818, - RDTR = 0x2820, - RXDCTL = 0x3828, - RADV = 0x282C, - RSRPD = 0x2C00, - TIPG = 0x0410 -}; - -enum PCTRL -{ - RESERVED = 0b000000, - SPEED_SELECTION_MSB = 0b010000, - UPDATE_COLLISION_TEST = 0b001000, - DUPLEX_MODE = 0b000100, - RESTART_AUTO_NEGOTIATION = 0b000010, - ISOLATE = 0b000001, - POWER_DOWN = 0b100000, - SPEED_SELECTION_LSB = 0b100000, -}; - -enum ECTRL -{ - SLU = 0x40 -}; - -enum RTCL -{ - RDMTS_HALF = (0 << 8), - RDMTS_QUARTER = (1 << 8), - RDMTS_EIGHTH = (2 << 8) -}; - -enum RCTL -{ - EN = (1 << 1), - SBP = (1 << 2), - UPE = (1 << 3), - MPE = (1 << 4), - LPE = (1 << 5), - LBM_NONE = (0 << 6), - LBM_PHY = (3 << 6), - MO_36 = (0 << 12), - MO_35 = (1 << 12), - MO_34 = (2 << 12), - MO_32 = (3 << 12), - BAM = (1 << 15), - VFE = (1 << 18), - CFIEN = (1 << 19), - CFI = (1 << 20), - DPF = (1 << 22), - PMCF = (1 << 23), - SECRC = (1 << 26), - BSIZE_256 = (3 << 16), - BSIZE_512 = (2 << 16), - BSIZE_1024 = (1 << 16), - BSIZE_2048 = (0 << 16), - BSIZE_4096 = ((3 << 16) | (1 << 25)), - BSIZE_8192 = ((2 << 16) | (1 << 25)), - BSIZE_16384 = ((1 << 16) | (1 << 25)) -}; - -enum CMD -{ - EOP = (1 << 0), - IFCS = (1 << 1), - IC = (1 << 2), - RS = (1 << 3), - RPS = (1 << 4), - VLE = (1 << 6), - IDE = (1 << 7) -}; - -enum TCTL -{ - EN_ = (1 << 1), - PSP = (1 << 3), - CT_SHIFT = 4, - COLD_SHIFT = 12, - SWXOFF = (1 << 22), - RTLC = (1 << 24) -}; - -enum TSTA -{ - DD = (1 << 0), - EC = (1 << 1), - LC = (1 << 2) -}; - -enum LSTA -{ - LSTA_TU = (1 << 3) -}; - -struct RXDescriptor -{ - volatile uint64_t Address; - volatile uint16_t Length; - volatile uint16_t Checksum; - volatile uint8_t Status; - volatile uint8_t Errors; - volatile uint16_t Special; -} __attribute__((packed)); - -struct TXDescriptor -{ - volatile uint64_t Address; - volatile uint16_t Length; - volatile uint8_t cso; - volatile uint8_t Command; - volatile uint8_t Status; - volatile uint8_t css; - volatile uint16_t Special; -} __attribute__((packed)); -#endif - -EXTERNC int cxx_Panic(); -EXTERNC int cxx_Probe(); -EXTERNC int cxx_Initialize(); -EXTERNC int cxx_Finalize(); diff --git a/Drivers/network/e1000/main.c b/Drivers/network/e1000/main.c deleted file mode 100644 index 066773f3..00000000 --- a/Drivers/network/e1000/main.c +++ /dev/null @@ -1,31 +0,0 @@ -/* - This file is part of Fennix Drivers. - - Fennix Drivers is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. - - Fennix Drivers is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Fennix Drivers. If not, see . -*/ - -#include - -#include "e1000.hpp" - -int DriverEntry() { return cxx_Initialize(); } -int DriverFinal() { return cxx_Finalize(); } -int DriverPanic() { return cxx_Panic(); } -int DriverProbe() { return cxx_Probe(); } - -DriverInfo("e1000", - "Intel(R) PRO/1000 Network Driver", - "EnderIce2", - 0, 0, 1, - "GPLv3"); diff --git a/Drivers/network/rtl8139/Makefile b/Drivers/network/rtl8139/Makefile deleted file mode 100644 index 9a92e2ef..00000000 --- a/Drivers/network/rtl8139/Makefile +++ /dev/null @@ -1,35 +0,0 @@ -default: - $(error Do not run this Makefile directly!) - -S_SOURCES = $(shell find ./ -type f -name '*.S') -C_SOURCES = $(shell find ./ -type f -name '*.c') -CXX_SOURCES = $(shell find ./ -type f -name '*.cpp') -HEADERS = $(sort $(dir $(wildcard ../../include/*))) -OBJ = $(C_SOURCES:.c=.o) $(CXX_SOURCES:.cpp=.o) $(S_SOURCES:.S=.o) -STACK_USAGE_OBJ = $(C_SOURCES:.c=.su) $(CXX_SOURCES:.cpp=.su) - -FILENAME = $(notdir $(shell pwd)).drv - -build: $(FILENAME) - mv $(FILENAME) $(OUTPUT_DIR)$(FILENAME) - -$(FILENAME): $(OBJ) - $(info Linking $@) - $(CC) $(DRIVER_LDFLAGS) $(OBJ) $(OUTPUT_DIR)dcrt0.o -L$(OUTPUT_DIR) -lkernel -o $@ - -WARNCFLAG = -Wall -Wextra - -%.o: %.c $(HEADERS) - $(info Compiling $<) - $(CC) $(DRIVER_CFLAGS) $(WARNCFLAG) -std=c17 -c $< -o $@ - -%.o: %.cpp $(HEADERS) - $(info Compiling $<) - $(CXX) $(DRIVER_CFLAGS) $(WARNCFLAG) -std=c++20 -fno-exceptions -fno-rtti -c $< -o $@ - -%.o: %.S - $(info Compiling $<) - $(AS) -o $@ $< - -clean: - rm -f file.map $(OBJ) $(STACK_USAGE_OBJ) diff --git a/Drivers/network/rtl8139/main.c b/Drivers/network/rtl8139/main.c deleted file mode 100644 index 3758eddb..00000000 --- a/Drivers/network/rtl8139/main.c +++ /dev/null @@ -1,31 +0,0 @@ -/* - This file is part of Fennix Drivers. - - Fennix Drivers is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. - - Fennix Drivers is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Fennix Drivers. If not, see . -*/ - -#include - -#include "rtl8139.hpp" - -int DriverEntry() { return cxx_Initialize(); } -int DriverFinal() { return cxx_Finalize(); } -int DriverPanic() { return cxx_Panic(); } -int DriverProbe() { return cxx_Probe(); } - -DriverInfo("rtl8139", - "Realtek RTL8139 Network Driver", - "EnderIce2", - 0, 0, 1, - "GPLv3"); diff --git a/Drivers/network/rtl8139/rtl8139.cpp b/Drivers/network/rtl8139/rtl8139.cpp deleted file mode 100644 index 506d3265..00000000 --- a/Drivers/network/rtl8139/rtl8139.cpp +++ /dev/null @@ -1,325 +0,0 @@ -/* - This file is part of Fennix Kernel. - - Fennix Kernel is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. - - Fennix Kernel is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Fennix Kernel. If not, see . -*/ - -#include -#include -#include -#include -#include -#include -#include - -#include "rtl8139.hpp" - -class RTL8139Device -{ -private: - PCIHeader0 *Header; - bool Initialized = false; - - struct BARData - { - uint8_t Type; - uint16_t IOBase; - uint64_t MemoryBase; - } BAR; - - const int BaseBufferSize = 8192; - const int WRAPBytes = 1500; - const int AdditionalBytes = 16; - const int BufferSize = BaseBufferSize + - WRAPBytes + - AdditionalBytes; - - uint8_t *RXBuffer = nullptr; - int TXCurrent = 0; - uint16_t CurrentPacket = 0; - - uint8_t TSAD[4] = {0x20, 0x24, 0x28, 0x2C}; - uint8_t TSD[4] = {0x10, 0x14, 0x18, 0x1C}; - -public: - dev_t ID; - - bool IsInitialized() { return Initialized; } - - size_t write(uint8_t *Buffer, size_t Size) - { - outl(TSAD[TXCurrent], (uint32_t)(reinterpret_cast(Buffer))); - outl(TSD[TXCurrent++], (uint32_t)Size); - if (TXCurrent > 3) - TXCurrent = 0; - return Size; - } - - MediaAccessControl GetMAC() - { - return MediaAccessControl(); - } - - int ioctl(NetIoctl req, void *) - { - switch (req) - { - case IOCTL_NET_GET_MAC: - { - return -ENOSYS; - } - default: - return -EINVAL; - } - return 0; - } - - void OnInterruptReceived(TrapFrame *) - { - /* Acknowledge interrupt */ - uint16_t status = inw(RegISR); - DebugLog("%#lx", status); - - /* Read status */ - if (status & RecOK) - { - /* Get the current packet */ - uint16_t *data = (uint16_t *)(RXBuffer + CurrentPacket); - uint16_t dataSz = *(data + 1); - data += 2; - - // ReportNetworkPacket(ID, data, dataSz); - /* FIXME: Implement */ - KernelLog("FIXME: Received packet"); - (void)data; - (void)dataSz; - - /* Update CAPR */ -#define RX_READ_PTR_MASK (~0x3) - CurrentPacket = (uint16_t)((CurrentPacket + dataSz + 4 + 3) & RX_READ_PTR_MASK); - if (CurrentPacket > BufferSize) - CurrentPacket -= uint16_t(BufferSize); - outw(RegCAPR, CurrentPacket - 0x10); - } - - /* Clear interrupt */ - outw(RegISR, (RecOK | RecBad | SendOK | SendBad)); - } - - void Panic() - { - } - - RTL8139Device(PCIHeader0 *_Header) - : Header(_Header) - { - uint32_t PCIBAR0 = Header->BAR0; - uint32_t PCIBAR1 = Header->BAR1; - BAR.Type = PCIBAR0 & 1; - BAR.IOBase = (uint16_t)(PCIBAR0 & (~3)); - BAR.MemoryBase = PCIBAR1 & (~15); - - RXBuffer = (uint8_t *)AllocateMemory(TO_PAGES(BufferSize)); - - /* Power on */ - outb(RegCONFIG1, 0x0); - - /* Software Reset */ - outb(RegCMD, 0x10); - while (inb(RegCMD) & 0x10) - Yield(); - - /* Initialize receive buffer */ - outl(RegRBSTART, (uint32_t)(reinterpret_cast(RXBuffer))); - - /* Configure interrupt mask register */ - outw(RegIMR, (RecOK | RecBad | SendOK | SendBad)); - outl(regRCR, (RcAB | RcAM | RcAPM | RcAAP) | RcWRAP); - - /* Enable receive and transmit */ - outb(RegCMD, 0xC); /* 0xC = RE and TE bit */ - - uint32_t MAC1 = inl(RegMAC); - uint16_t MAC2 = inw(RegMAR); - MediaAccessControl mac = { - mac.Address[0] = (uint8_t)MAC1, - mac.Address[1] = (uint8_t)(MAC1 >> 8), - mac.Address[2] = (uint8_t)(MAC1 >> 16), - mac.Address[3] = (uint8_t)(MAC1 >> 24), - mac.Address[4] = (uint8_t)MAC2, - mac.Address[5] = (uint8_t)(MAC2 >> 8)}; - - Initialized = true; - } - - ~RTL8139Device() - { - if (!Initialized) - return; - - /* FIXME: Shutdown code */ - } -}; - -RTL8139Device *Drivers[4] = {nullptr}; -dev_t NetID[4] = {(dev_t)-1}; - -#define OIR(x) OIR_##x -#define CREATE_OIR(x) \ - void OIR_##x(TrapFrame *f) { Drivers[x]->OnInterruptReceived(f); } - -CREATE_OIR(0); -CREATE_OIR(1); -CREATE_OIR(2); -CREATE_OIR(3); - -int __fs_Open(struct Inode *, int, mode_t) { return 0; } -int __fs_Close(struct Inode *) { return 0; } -ssize_t __fs_Read(struct Inode *, void *, size_t, off_t) { return 0; } - -ssize_t __fs_Write(struct Inode *Node, const void *Buffer, size_t Size, off_t) -{ - return Drivers[NetID[Node->GetMinor()]]->write((uint8_t *)Buffer, Size); -} - -int __fs_Ioctl(struct Inode *Node, unsigned long Request, void *Argp) -{ - return Drivers[NetID[Node->GetMinor()]]->ioctl((NetIoctl)Request, Argp); -} - -const struct InodeOperations NetOps = { - .Lookup = nullptr, - .Create = nullptr, - .Remove = nullptr, - .Rename = nullptr, - .Read = __fs_Read, - .Write = __fs_Write, - .Truncate = nullptr, - .Open = __fs_Open, - .Close = __fs_Close, - .Ioctl = __fs_Ioctl, - .ReadDir = nullptr, - .MkDir = nullptr, - .RmDir = nullptr, - .SymLink = nullptr, - .ReadLink = nullptr, - .Seek = nullptr, - .Stat = nullptr, -}; - -PCIArray *Devices; -EXTERNC int cxx_Panic() -{ - PCIArray *ctx = Devices; - short Count = 0; - while (ctx != nullptr) - { - if (Drivers[Count] != nullptr) - Drivers[Count]->Panic(); - Count++; - ctx = (PCIArray *)ctx->Next; - } - - return 0; -} - -EXTERNC int cxx_Probe() -{ - uint16_t VendorIDs[] = {0x10EC, /* Realtek */ - PCI_END}; - uint16_t DeviceIDs[] = {0x8139, /* RTL8139 */ - PCI_END}; - Devices = GetPCIDevices(VendorIDs, DeviceIDs); - if (Devices == nullptr) - { - KernelLog("No RTL8139 device found."); - return -ENODEV; - } - return 0; -} - -EXTERNC int cxx_Initialize() -{ - PCIArray *ctx = Devices; - size_t Count = 0; - while (ctx != nullptr) - { - if (Count > sizeof(Drivers) / sizeof(RTL8139Device *)) - break; - - InitializePCI(ctx->Device); - - Drivers[Count] = new RTL8139Device((PCIHeader0 *)ctx->Device->Header); - - if (Drivers[Count]->IsInitialized()) - { - dev_t ret = RegisterDevice(NETWORK_TYPE_ETHERNET, &NetOps); - NetID[Count] = ret; - Drivers[Count]->ID = ret; - - /* FIXME: bad code */ - switch (Count) - { - case 0: - RegisterInterruptHandler(iLine(ctx->Device), (void *)OIR(0)); - break; - case 1: - RegisterInterruptHandler(iLine(ctx->Device), (void *)OIR(1)); - break; - case 2: - RegisterInterruptHandler(iLine(ctx->Device), (void *)OIR(2)); - break; - case 3: - RegisterInterruptHandler(iLine(ctx->Device), (void *)OIR(3)); - break; - default: - break; - } - - Count++; - } - ctx = (PCIArray *)ctx->Next; - } - - if (Count == 0) - { - KernelLog("No valid RTL8139 device found."); - return -EINVAL; - } - - return 0; -} - -EXTERNC int cxx_Finalize() -{ - PCIArray *ctx = Devices; - size_t Count = 0; - while (ctx != nullptr) - { - if (Count++ > sizeof(Drivers) / sizeof(RTL8139Device *)) - break; - - delete Drivers[Count++]; - ctx->Device->Header->Command |= PCI_COMMAND_INTX_DISABLE; - ctx = (PCIArray *)ctx->Next; - } - - for (size_t i = 0; i < sizeof(NetID) / sizeof(dev_t); i++) - { - if (NetID[i] != (dev_t)-1) - UnregisterDevice(NetID[i]); - } - - return 0; -} diff --git a/Drivers/network/rtl8139/rtl8139.hpp b/Drivers/network/rtl8139/rtl8139.hpp deleted file mode 100644 index 1f0e78dc..00000000 --- a/Drivers/network/rtl8139/rtl8139.hpp +++ /dev/null @@ -1,93 +0,0 @@ -/* - This file is part of Fennix Drivers. - - Fennix Drivers is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. - - Fennix Drivers is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Fennix Drivers. If not, see . -*/ - -#pragma once - -#include - -struct RXQueueEntry -{ - uint8_t *Buffer; - uint16_t Size; -} __attribute__((packed)); - -enum InterruptStatus -{ - RecOK = 0x1, - RecBad = 0x2, - SendOK = 0x4, - SendBad = 0x8, -}; - -enum ReceiveConfig -{ - /** - * Accept broadcast packets - * sent to mac ff:ff:ff:ff:ff:ff - */ - RcAB = 0x1, - - /** - * Accept packets sent to the - * multicast address - */ - RcAM = 0x2, - - /** - * Accept packets sent to the - * NIC's MAC address - */ - RcAPM = 0x4, - - /** - * Accept all packets - * (promiscuous mode) - */ - RcAAP = 0x8, - - /** - * The WRAP bit is used to tell the - * NIC to wrap around the ring - * buffer when it reaches the end - * of the buffer. - * - * @note If this bit is set, the - * buffer must have an additional - * 1500 bytes of space at the end - * of the buffer to prevent the - * NIC from overflowing the buffer. - */ - RcWRAP = 0x80, -}; - -enum Registers -{ - RegMAC = 0x0, - RegMAR = 0x8, - RegRBSTART = 0x30, - RegCMD = 0x37, - RegCAPR = 0x38, - regRCR = 0x44, - RegCONFIG1 = 0x52, - RegIMR = 0x3C, - RegISR = 0x3E, -}; - -EXTERNC int cxx_Panic(); -EXTERNC int cxx_Probe(); -EXTERNC int cxx_Initialize(); -EXTERNC int cxx_Finalize(); diff --git a/Drivers/storage/Makefile b/Drivers/storage/Makefile index 89dbd5fc..8ea8a10f 100644 --- a/Drivers/storage/Makefile +++ b/Drivers/storage/Makefile @@ -1,7 +1,9 @@ -build: - make -C ahci build - make -C ata build +MAKE_TARGETS := build clean +DIRECTORIES := $(sort $(dir $(wildcard ./*/))) -clean: - make -C ahci clean - make -C ata clean +.PHONY: $(MAKE_TARGETS) $(DIRECTORIES) + +$(MAKE_TARGETS): $(DIRECTORIES) + +$(DIRECTORIES): + $(MAKE) -C $@ $(MAKECMDGOALS) diff --git a/Drivers/storage/ahci/Makefile b/Drivers/storage/ahci/Makefile deleted file mode 100644 index 9a92e2ef..00000000 --- a/Drivers/storage/ahci/Makefile +++ /dev/null @@ -1,35 +0,0 @@ -default: - $(error Do not run this Makefile directly!) - -S_SOURCES = $(shell find ./ -type f -name '*.S') -C_SOURCES = $(shell find ./ -type f -name '*.c') -CXX_SOURCES = $(shell find ./ -type f -name '*.cpp') -HEADERS = $(sort $(dir $(wildcard ../../include/*))) -OBJ = $(C_SOURCES:.c=.o) $(CXX_SOURCES:.cpp=.o) $(S_SOURCES:.S=.o) -STACK_USAGE_OBJ = $(C_SOURCES:.c=.su) $(CXX_SOURCES:.cpp=.su) - -FILENAME = $(notdir $(shell pwd)).drv - -build: $(FILENAME) - mv $(FILENAME) $(OUTPUT_DIR)$(FILENAME) - -$(FILENAME): $(OBJ) - $(info Linking $@) - $(CC) $(DRIVER_LDFLAGS) $(OBJ) $(OUTPUT_DIR)dcrt0.o -L$(OUTPUT_DIR) -lkernel -o $@ - -WARNCFLAG = -Wall -Wextra - -%.o: %.c $(HEADERS) - $(info Compiling $<) - $(CC) $(DRIVER_CFLAGS) $(WARNCFLAG) -std=c17 -c $< -o $@ - -%.o: %.cpp $(HEADERS) - $(info Compiling $<) - $(CXX) $(DRIVER_CFLAGS) $(WARNCFLAG) -std=c++20 -fno-exceptions -fno-rtti -c $< -o $@ - -%.o: %.S - $(info Compiling $<) - $(AS) -o $@ $< - -clean: - rm -f file.map $(OBJ) $(STACK_USAGE_OBJ) diff --git a/Drivers/storage/ahci/ahci.cpp b/Drivers/storage/ahci/ahci.cpp deleted file mode 100644 index 1409d535..00000000 --- a/Drivers/storage/ahci/ahci.cpp +++ /dev/null @@ -1,1005 +0,0 @@ -/* - This file is part of Fennix Drivers. - - Fennix Drivers is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. - - Fennix Drivers is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Fennix Drivers. If not, see . -*/ - -#include -#include -#include -#include -#include - -#define ATA_DEV_DRQ 0x08 -#define ATA_DEV_BUSY 0x80 -#define ATA_CMD_READ_DMA_EX 0x25 -#define ATA_CMD_WRITE_DMA_EX 0x35 -#define ATA_CMD_IDENTIFY 0xEC - -#define ATAPI_CMD_IDENTIFY_PACKET 0xA1 - -#define HBA_PORT_IPM_ACTIVE 0x1 -#define HBA_PORT_DEV_PRESENT 0x3 -#define HBA_PxIS_TFES (1 << 30) - -#define SATA_SIG_ATA 0x00000101 -#define SATA_SIG_PM 0x96690101 -#define SATA_SIG_SEMB 0xC33C0101 -#define SATA_SIG_ATAPI 0xEB140101 - -#define HBA_PxCMD_ST 0x0001 -#define HBA_PxCMD_FRE 0x0010 -#define HBA_PxCMD_FR 0x4000 -#define HBA_PxCMD_CR 0x8000 - -enum PortType -{ - None = 0, - SATA = 1, - SEMB = 2, - PM = 3, - SATAPI = 4, -}; - -enum FIS_TYPE -{ - FIS_TYPE_REG_H2D = 0x27, - FIS_TYPE_REG_D2H = 0x34, - FIS_TYPE_DMA_ACT = 0x39, - FIS_TYPE_DMA_SETUP = 0x41, - FIS_TYPE_DATA = 0x46, - FIS_TYPE_BIST = 0x58, - FIS_TYPE_PIO_SETUP = 0x5F, - FIS_TYPE_DEV_BITS = 0xA1, -}; - -struct HBAPort -{ - uint32_t CommandListBase; - uint32_t CommandListBaseUpper; - uint32_t FISBaseAddress; - uint32_t FISBaseAddressUpper; - uint32_t InterruptStatus; - uint32_t InterruptEnable; - uint32_t CommandStatus; - uint32_t Reserved0; - uint32_t TaskFileData; - uint32_t Signature; - uint32_t SataStatus; - uint32_t SataControl; - uint32_t SataError; - uint32_t SataActive; - uint32_t CommandIssue; - uint32_t SataNotification; - uint32_t FISSwitchControl; - uint32_t Reserved1[11]; - uint32_t Vendor[4]; -}; - -struct HBAMemory -{ - uint32_t HostCapability; - uint32_t GlobalHostControl; - uint32_t InterruptStatus; - uint32_t PortsImplemented; - uint32_t Version; - uint32_t CCCControl; - uint32_t CCCPorts; - uint32_t EnclosureManagementLocation; - uint32_t EnclosureManagementControl; - uint32_t HostCapabilitiesExtended; - uint32_t BIOSHandoffControlStatus; - uint8_t Reserved0[0x74]; - uint8_t Vendor[0x60]; - HBAPort Ports[1]; -}; - -struct HBACommandHeader -{ - uint8_t CommandFISLength : 5; - uint8_t ATAPI : 1; - uint8_t Write : 1; - uint8_t Preferable : 1; - uint8_t Reset : 1; - uint8_t BIST : 1; - uint8_t ClearBusy : 1; - uint8_t Reserved0 : 1; - uint8_t PortMultiplier : 4; - uint16_t PRDTLength; - uint32_t PRDBCount; - uint32_t CommandTableBaseAddress; - uint32_t CommandTableBaseAddressUpper; - uint32_t Reserved1[4]; -}; - -struct HBAPRDTEntry -{ - uint32_t DataBaseAddress; - uint32_t DataBaseAddressUpper; - uint32_t Reserved0; - uint32_t ByteCount : 22; - uint32_t Reserved1 : 9; - uint32_t InterruptOnCompletion : 1; -}; - -struct HBACommandTable -{ - uint8_t CommandFIS[64]; - uint8_t ATAPICommand[16]; - uint8_t Reserved[48]; - HBAPRDTEntry PRDTEntry[]; -}; - -struct FIS_REG_H2D -{ - uint8_t FISType; - uint8_t PortMultiplier : 4; - uint8_t Reserved0 : 3; - uint8_t CommandControl : 1; - uint8_t Command; - uint8_t FeatureLow; - uint8_t LBA0; - uint8_t LBA1; - uint8_t LBA2; - uint8_t DeviceRegister; - uint8_t LBA3; - uint8_t LBA4; - uint8_t LBA5; - uint8_t FeatureHigh; - uint8_t CountLow; - uint8_t CountHigh; - uint8_t ISOCommandCompletion; - uint8_t Control; - uint8_t Reserved1[4]; -}; - -/* https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/ata/ns-ata-_identify_device_data */ -struct __attribute__((packed)) ATA_IDENTIFY -{ - struct __attribute__((packed)) - { - uint16_t Reserved1 : 1; - uint16_t Retired3 : 1; - uint16_t ResponseIncomplete : 1; - uint16_t Retired2 : 3; - uint16_t FixedDevice : 1; - uint16_t RemovableMedia : 1; - uint16_t Retired1 : 7; - uint16_t DeviceType : 1; - } GeneralConfiguration; - uint16_t NumCylinders; - uint16_t SpecificConfiguration; - uint16_t NumHeads; - uint16_t Retired1[2]; - uint16_t NumSectorsPerTrack; - uint16_t VendorUnique1[3]; - uint8_t SerialNumber[20]; - uint16_t Retired2[2]; - uint16_t Obsolete1; - uint8_t FirmwareRevision[8]; - uint8_t ModelNumber[40]; - uint8_t MaximumBlockTransfer; - uint8_t VendorUnique2; - struct __attribute__((packed)) - { - uint16_t FeatureSupported : 1; - uint16_t Reserved : 15; - } TrustedComputing; - struct __attribute__((packed)) - { - uint8_t CurrentLongPhysicalSectorAlignment : 2; - uint8_t ReservedByte49 : 6; - uint8_t DmaSupported : 1; - uint8_t LbaSupported : 1; - uint8_t IordyDisable : 1; - uint8_t IordySupported : 1; - uint8_t Reserved1 : 1; - uint8_t StandybyTimerSupport : 1; - uint8_t Reserved2 : 2; - uint16_t ReservedWord50; - } Capabilities; - uint16_t ObsoleteWords51[2]; - uint16_t TranslationFieldsValid : 3; - uint16_t Reserved3 : 5; - uint16_t FreeFallControlSensitivity : 8; - uint16_t NumberOfCurrentCylinders; - uint16_t NumberOfCurrentHeads; - uint16_t CurrentSectorsPerTrack; - uint32_t CurrentSectorCapacity; - uint8_t CurrentMultiSectorSetting; - uint8_t MultiSectorSettingValid : 1; - uint8_t ReservedByte59 : 3; - uint8_t SanitizeFeatureSupported : 1; - uint8_t CryptoScrambleExtCommandSupported : 1; - uint8_t OverwriteExtCommandSupported : 1; - uint8_t BlockEraseExtCommandSupported : 1; - uint32_t UserAddressableSectors; - uint16_t ObsoleteWord62; - uint16_t MultiWordDMASupport : 8; - uint16_t MultiWordDMAActive : 8; - uint16_t AdvancedPIOModes : 8; - uint16_t ReservedByte64 : 8; - uint16_t MinimumMWXferCycleTime; - uint16_t RecommendedMWXferCycleTime; - uint16_t MinimumPIOCycleTime; - uint16_t MinimumPIOCycleTimeIORDY; - struct __attribute__((packed)) - { - uint16_t ZonedCapabilities : 2; - uint16_t NonVolatileWriteCache : 1; - uint16_t ExtendedUserAddressableSectorsSupported : 1; - uint16_t DeviceEncryptsAllUserData : 1; - uint16_t ReadZeroAfterTrimSupported : 1; - uint16_t Optional28BitCommandsSupported : 1; - uint16_t IEEE1667 : 1; - uint16_t DownloadMicrocodeDmaSupported : 1; - uint16_t SetMaxSetPasswordUnlockDmaSupported : 1; - uint16_t WriteBufferDmaSupported : 1; - uint16_t ReadBufferDmaSupported : 1; - uint16_t DeviceConfigIdentifySetDmaSupported : 1; - uint16_t LPSAERCSupported : 1; - uint16_t DeterministicReadAfterTrimSupported : 1; - uint16_t CFastSpecSupported : 1; - } AdditionalSupported; - uint16_t ReservedWords70[5]; - uint16_t QueueDepth : 5; - uint16_t ReservedWord75 : 11; - struct __attribute__((packed)) - { - uint16_t Reserved0 : 1; - uint16_t SataGen1 : 1; - uint16_t SataGen2 : 1; - uint16_t SataGen3 : 1; - uint16_t Reserved1 : 4; - uint16_t NCQ : 1; - uint16_t HIPM : 1; - uint16_t PhyEvents : 1; - uint16_t NcqUnload : 1; - uint16_t NcqPriority : 1; - uint16_t HostAutoPS : 1; - uint16_t DeviceAutoPS : 1; - uint16_t ReadLogDMA : 1; - uint16_t Reserved2 : 1; - uint16_t CurrentSpeed : 3; - uint16_t NcqStreaming : 1; - uint16_t NcqQueueMgmt : 1; - uint16_t NcqReceiveSend : 1; - uint16_t DEVSLPtoReducedPwrState : 1; - uint16_t Reserved3 : 8; - } SerialAtaCapabilities; - struct __attribute__((packed)) - { - uint16_t Reserved0 : 1; - uint16_t NonZeroOffsets : 1; - uint16_t DmaSetupAutoActivate : 1; - uint16_t DIPM : 1; - uint16_t InOrderData : 1; - uint16_t HardwareFeatureControl : 1; - uint16_t SoftwareSettingsPreservation : 1; - uint16_t NCQAutosense : 1; - uint16_t DEVSLP : 1; - uint16_t HybridInformation : 1; - uint16_t Reserved1 : 6; - } SerialAtaFeaturesSupported; - struct __attribute__((packed)) - { - uint16_t Reserved0 : 1; - uint16_t NonZeroOffsets : 1; - uint16_t DmaSetupAutoActivate : 1; - uint16_t DIPM : 1; - uint16_t InOrderData : 1; - uint16_t HardwareFeatureControl : 1; - uint16_t SoftwareSettingsPreservation : 1; - uint16_t DeviceAutoPS : 1; - uint16_t DEVSLP : 1; - uint16_t HybridInformation : 1; - uint16_t Reserved1 : 6; - } SerialAtaFeaturesEnabled; - uint16_t MajorRevision; - uint16_t MinorRevision; - struct __attribute__((packed)) - { - uint16_t SmartCommands : 1; - uint16_t SecurityMode : 1; - uint16_t RemovableMediaFeature : 1; - uint16_t PowerManagement : 1; - uint16_t Reserved1 : 1; - uint16_t WriteCache : 1; - uint16_t LookAhead : 1; - uint16_t ReleaseInterrupt : 1; - uint16_t ServiceInterrupt : 1; - uint16_t DeviceReset : 1; - uint16_t HostProtectedArea : 1; - uint16_t Obsolete1 : 1; - uint16_t WriteBuffer : 1; - uint16_t ReadBuffer : 1; - uint16_t Nop : 1; - uint16_t Obsolete2 : 1; - uint16_t DownloadMicrocode : 1; - uint16_t DmaQueued : 1; - uint16_t Cfa : 1; - uint16_t AdvancedPm : 1; - uint16_t Msn : 1; - uint16_t PowerUpInStandby : 1; - uint16_t ManualPowerUp : 1; - uint16_t Reserved2 : 1; - uint16_t SetMax : 1; - uint16_t Acoustics : 1; - uint16_t BigLba : 1; - uint16_t DeviceConfigOverlay : 1; - uint16_t FlushCache : 1; - uint16_t FlushCacheExt : 1; - uint16_t WordValid83 : 2; - uint16_t SmartErrorLog : 1; - uint16_t SmartSelfTest : 1; - uint16_t MediaSerialNumber : 1; - uint16_t MediaCardPassThrough : 1; - uint16_t StreamingFeature : 1; - uint16_t GpLogging : 1; - uint16_t WriteFua : 1; - uint16_t WriteQueuedFua : 1; - uint16_t WWN64Bit : 1; - uint16_t URGReadStream : 1; - uint16_t URGWriteStream : 1; - uint16_t ReservedForTechReport : 2; - uint16_t IdleWithUnloadFeature : 1; - uint16_t WordValid : 2; - } CommandSetSupport; - struct __attribute__((packed)) - { - uint16_t SmartCommands : 1; - uint16_t SecurityMode : 1; - uint16_t RemovableMediaFeature : 1; - uint16_t PowerManagement : 1; - uint16_t Reserved1 : 1; - uint16_t WriteCache : 1; - uint16_t LookAhead : 1; - uint16_t ReleaseInterrupt : 1; - uint16_t ServiceInterrupt : 1; - uint16_t DeviceReset : 1; - uint16_t HostProtectedArea : 1; - uint16_t Obsolete1 : 1; - uint16_t WriteBuffer : 1; - uint16_t ReadBuffer : 1; - uint16_t Nop : 1; - uint16_t Obsolete2 : 1; - uint16_t DownloadMicrocode : 1; - uint16_t DmaQueued : 1; - uint16_t Cfa : 1; - uint16_t AdvancedPm : 1; - uint16_t Msn : 1; - uint16_t PowerUpInStandby : 1; - uint16_t ManualPowerUp : 1; - uint16_t Reserved2 : 1; - uint16_t SetMax : 1; - uint16_t Acoustics : 1; - uint16_t BigLba : 1; - uint16_t DeviceConfigOverlay : 1; - uint16_t FlushCache : 1; - uint16_t FlushCacheExt : 1; - uint16_t Resrved3 : 1; - uint16_t Words119_120Valid : 1; - uint16_t SmartErrorLog : 1; - uint16_t SmartSelfTest : 1; - uint16_t MediaSerialNumber : 1; - uint16_t MediaCardPassThrough : 1; - uint16_t StreamingFeature : 1; - uint16_t GpLogging : 1; - uint16_t WriteFua : 1; - uint16_t WriteQueuedFua : 1; - uint16_t WWN64Bit : 1; - uint16_t URGReadStream : 1; - uint16_t URGWriteStream : 1; - uint16_t ReservedForTechReport : 2; - uint16_t IdleWithUnloadFeature : 1; - uint16_t Reserved4 : 2; - } CommandSetActive; - uint16_t UltraDMASupport : 8; - uint16_t UltraDMAActive : 8; - struct __attribute__((packed)) - { - uint16_t TimeRequired : 15; - uint16_t ExtendedTimeReported : 1; - } NormalSecurityEraseUnit; - struct __attribute__((packed)) - { - uint16_t TimeRequired : 15; - uint16_t ExtendedTimeReported : 1; - } EnhancedSecurityEraseUnit; - uint16_t CurrentAPMLevel : 8; - uint16_t ReservedWord91 : 8; - uint16_t MasterPasswordID; - uint16_t HardwareResetResult; - uint16_t CurrentAcousticValue : 8; - uint16_t RecommendedAcousticValue : 8; - uint16_t StreamMinRequestSize; - uint16_t StreamingTransferTimeDMA; - uint16_t StreamingAccessLatencyDMAPIO; - uint32_t StreamingPerfGranularity; - uint32_t Max48BitLBA[2]; - uint16_t StreamingTransferTime; - uint16_t DsmCap; - struct __attribute__((packed)) - { - uint16_t LogicalSectorsPerPhysicalSector : 4; - uint16_t Reserved0 : 8; - uint16_t LogicalSectorLongerThan256Words : 1; - uint16_t MultipleLogicalSectorsPerPhysicalSector : 1; - uint16_t Reserved1 : 2; - } PhysicalLogicalSectorSize; - uint16_t InterSeekDelay; - uint16_t WorldWideName[4]; - uint16_t ReservedForWorldWideName128[4]; - uint16_t ReservedForTlcTechnicalReport; - uint16_t WordsPerLogicalSector[2]; - struct __attribute__((packed)) - { - uint16_t ReservedForDrqTechnicalReport : 1; - uint16_t WriteReadVerify : 1; - uint16_t WriteUncorrectableExt : 1; - uint16_t ReadWriteLogDmaExt : 1; - uint16_t DownloadMicrocodeMode3 : 1; - uint16_t FreefallControl : 1; - uint16_t SenseDataReporting : 1; - uint16_t ExtendedPowerConditions : 1; - uint16_t Reserved0 : 6; - uint16_t WordValid : 2; - } CommandSetSupportExt; - struct __attribute__((packed)) - { - uint16_t ReservedForDrqTechnicalReport : 1; - uint16_t WriteReadVerify : 1; - uint16_t WriteUncorrectableExt : 1; - uint16_t ReadWriteLogDmaExt : 1; - uint16_t DownloadMicrocodeMode3 : 1; - uint16_t FreefallControl : 1; - uint16_t SenseDataReporting : 1; - uint16_t ExtendedPowerConditions : 1; - uint16_t Reserved0 : 6; - uint16_t Reserved1 : 2; - } CommandSetActiveExt; - uint16_t ReservedForExpandedSupportandActive[6]; - uint16_t MsnSupport : 2; - uint16_t ReservedWord127 : 14; - struct __attribute__((packed)) - { - uint16_t SecuritySupported : 1; - uint16_t SecurityEnabled : 1; - uint16_t SecurityLocked : 1; - uint16_t SecurityFrozen : 1; - uint16_t SecurityCountExpired : 1; - uint16_t EnhancedSecurityEraseSupported : 1; - uint16_t Reserved0 : 2; - uint16_t SecurityLevel : 1; - uint16_t Reserved1 : 7; - } SecurityStatus; - uint16_t ReservedWord129[31]; - struct __attribute__((packed)) - { - uint16_t MaximumCurrentInMA : 12; - uint16_t CfaPowerMode1Disabled : 1; - uint16_t CfaPowerMode1Required : 1; - uint16_t Reserved0 : 1; - uint16_t Word160Supported : 1; - } CfaPowerMode1; - uint16_t ReservedForCfaWord161[7]; - uint16_t NominalFormFactor : 4; - uint16_t ReservedWord168 : 12; - struct __attribute__((packed)) - { - uint16_t SupportsTrim : 1; - uint16_t Reserved0 : 15; - } DataSetManagementFeature; - uint16_t AdditionalProductID[4]; - uint16_t ReservedForCfaWord174[2]; - uint16_t CurrentMediaSerialNumber[30]; - struct __attribute__((packed)) - { - uint16_t Supported : 1; - uint16_t Reserved0 : 1; - uint16_t WriteSameSuported : 1; - uint16_t ErrorRecoveryControlSupported : 1; - uint16_t FeatureControlSuported : 1; - uint16_t DataTablesSuported : 1; - uint16_t Reserved1 : 6; - uint16_t VendorSpecific : 4; - } SCTCommandTransport; - uint16_t ReservedWord207[2]; - struct __attribute__((packed)) - { - uint16_t AlignmentOfLogicalWithinPhysical : 14; - uint16_t Word209Supported : 1; - uint16_t Reserved0 : 1; - } BlockAlignment; - uint16_t WriteReadVerifySectorCountMode3Only[2]; - uint16_t WriteReadVerifySectorCountMode2Only[2]; - struct __attribute__((packed)) - { - uint16_t NVCachePowerModeEnabled : 1; - uint16_t Reserved0 : 3; - uint16_t NVCacheFeatureSetEnabled : 1; - uint16_t Reserved1 : 3; - uint16_t NVCachePowerModeVersion : 4; - uint16_t NVCacheFeatureSetVersion : 4; - } NVCacheCapabilities; - uint16_t NVCacheSizeLSW; - uint16_t NVCacheSizeMSW; - uint16_t NominalMediaRotationRate; - uint16_t ReservedWord218; - struct __attribute__((packed)) - { - uint8_t NVCacheEstimatedTimeToSpinUpInSeconds; - uint8_t Reserved; - } NVCacheOptions; - uint16_t WriteReadVerifySectorCountMode : 8; - uint16_t ReservedWord220 : 8; - uint16_t ReservedWord221; - struct __attribute__((packed)) - { - uint16_t MajorVersion : 12; - uint16_t TransportType : 4; - } TransportMajorVersion; - uint16_t TransportMinorVersion; - uint16_t ReservedWord224[6]; - uint32_t ExtendedNumberOfUserAddressableSectors[2]; - uint16_t MinBlocksPerDownloadMicrocodeMode03; - uint16_t MaxBlocksPerDownloadMicrocodeMode03; - uint16_t ReservedWord236[19]; - uint16_t Signature : 8; - uint16_t CheckSum : 8; -}; - -class Port -{ -public: - PortType AHCIPortType; - HBAPort *HBAPortPtr; - uint8_t *Buffer; - uint8_t PortNumber; - ATA_IDENTIFY *IdentifyData; - - Port(PortType Type, HBAPort *PortPtr, uint8_t PortNumber) - { - this->AHCIPortType = Type; - this->HBAPortPtr = PortPtr; - this->Buffer = static_cast(AllocateMemory(1)); - MemorySet(this->Buffer, 0, PAGE_SIZE); - this->IdentifyData = static_cast(AllocateMemory(1)); - MemorySet(this->IdentifyData, 0, PAGE_SIZE); - this->PortNumber = PortNumber; - } - - ~Port() - { - FreeMemory(this->Buffer, 1); - } - - void StartCMD() - { - while (HBAPortPtr->CommandStatus & HBA_PxCMD_CR) - Yield(); - HBAPortPtr->CommandStatus |= HBA_PxCMD_FRE; - HBAPortPtr->CommandStatus |= HBA_PxCMD_ST; - } - - void StopCMD() - { - HBAPortPtr->CommandStatus &= ~HBA_PxCMD_ST; - HBAPortPtr->CommandStatus &= ~HBA_PxCMD_FRE; - while (true) - { - if (HBAPortPtr->CommandStatus & HBA_PxCMD_FR) - continue; - if (HBAPortPtr->CommandStatus & HBA_PxCMD_CR) - continue; - break; - } - } - - void Configure() - { - this->StopCMD(); - void *CmdBase = AllocateMemory(1); - HBAPortPtr->CommandListBase = (uint32_t)(uint64_t)CmdBase; - HBAPortPtr->CommandListBaseUpper = (uint32_t)((uint64_t)CmdBase >> 32); - MemorySet(reinterpret_cast(HBAPortPtr->CommandListBase), 0, 1024); - - void *FISBase = AllocateMemory(1); - HBAPortPtr->FISBaseAddress = (uint32_t)(uint64_t)FISBase; - HBAPortPtr->FISBaseAddressUpper = (uint32_t)((uint64_t)FISBase >> 32); - MemorySet(FISBase, 0, 256); - - HBACommandHeader *CommandHeader = (HBACommandHeader *)((uint64_t)HBAPortPtr->CommandListBase + ((uint64_t)HBAPortPtr->CommandListBaseUpper << 32)); - for (int i = 0; i < 32; i++) - { - CommandHeader[i].PRDTLength = 8; - void *CommandTableAddress = AllocateMemory(1); - uint64_t Address = (uint64_t)CommandTableAddress + (i << 8); - CommandHeader[i].CommandTableBaseAddress = (uint32_t)(uint64_t)Address; - CommandHeader[i].CommandTableBaseAddressUpper = (uint32_t)((uint64_t)Address >> 32); - MemorySet(CommandTableAddress, 0, 256); - } - this->StartCMD(); - - Identify(); - - KernelLog("Port %d \"%x %x %x %x\" configured", PortNumber, - HBAPortPtr->Vendor[0], HBAPortPtr->Vendor[1], - HBAPortPtr->Vendor[2], HBAPortPtr->Vendor[3]); - } - - bool ReadWrite(uint64_t Sector, uint32_t SectorCount, uint8_t *Buffer, bool Write) - { - if (this->AHCIPortType == PortType::SATAPI && - Write == true) - { - KernelLog("SATAPI port does not support write."); - return false; - } - - uint32_t SectorL = (uint32_t)Sector; - uint32_t SectorH = (uint32_t)(Sector >> 32); - - HBAPortPtr->InterruptStatus = 0xFFFFFFFF; /* Clear pending interrupt bits */ - - HBACommandHeader *CommandHeader = reinterpret_cast(HBAPortPtr->CommandListBase); - CommandHeader->CommandFISLength = sizeof(FIS_REG_H2D) / sizeof(uint32_t); - if (Write) - CommandHeader->Write = 1; - else - CommandHeader->Write = 0; - CommandHeader->PRDTLength = 1; - - HBACommandTable *CommandTable = reinterpret_cast(CommandHeader->CommandTableBaseAddress); - MemorySet(CommandTable, 0, sizeof(HBACommandTable) + (CommandHeader->PRDTLength - 1) * sizeof(HBAPRDTEntry)); - - CommandTable->PRDTEntry[0].DataBaseAddress = (uint32_t)(uint64_t)Buffer; - CommandTable->PRDTEntry[0].DataBaseAddressUpper = (uint32_t)((uint64_t)Buffer >> 32); - -#pragma GCC diagnostic push -/* conversion from 'uint32_t' {aka 'unsigned int'} to 'unsigned int:22' may change value */ -#pragma GCC diagnostic ignored "-Wconversion" - CommandTable->PRDTEntry[0].ByteCount = (SectorCount << 9) - 1; /* 512 bytes per sector */ -#pragma GCC diagnostic pop - - CommandTable->PRDTEntry[0].InterruptOnCompletion = 1; - - FIS_REG_H2D *CommandFIS = (FIS_REG_H2D *)(&CommandTable->CommandFIS); - - CommandFIS->FISType = FIS_TYPE_REG_H2D; - CommandFIS->CommandControl = 1; - if (Write) - CommandFIS->Command = ATA_CMD_WRITE_DMA_EX; - else - CommandFIS->Command = ATA_CMD_READ_DMA_EX; - - CommandFIS->LBA0 = (uint8_t)SectorL; - CommandFIS->LBA1 = (uint8_t)(SectorL >> 8); - CommandFIS->LBA2 = (uint8_t)(SectorL >> 16); - CommandFIS->LBA3 = (uint8_t)SectorH; - CommandFIS->LBA4 = (uint8_t)(SectorH >> 8); - CommandFIS->LBA5 = (uint8_t)(SectorH >> 16); - - CommandFIS->DeviceRegister = 1 << 6; // LBA mode - CommandFIS->CountLow = SectorCount & 0xFF; - CommandFIS->CountHigh = (SectorCount >> 8) & 0xFF; - - uint64_t Spin = 0; - - while ((HBAPortPtr->TaskFileData & (ATA_DEV_BUSY | ATA_DEV_DRQ)) && Spin < 1000000) - Spin++; - - if (Spin == 1000000) - { - KernelLog("Port not responding."); - return false; - } - - HBAPortPtr->CommandIssue = 1; - - Spin = 0; - int TryCount = 0; - - while (true) - { - if (Spin > 100000000) - { - KernelLog("Port %d not responding. (%d)", - this->PortNumber, TryCount); - - Spin = 0; - TryCount++; - if (TryCount > 10) - return false; - } - - if (HBAPortPtr->CommandIssue == 0) - break; - Spin++; - - if (HBAPortPtr->InterruptStatus & HBA_PxIS_TFES) - { - KernelLog("Error reading/writing (%d).", Write); - return false; - } - } - - return true; - } - - void Identify() - { - MemorySet(this->IdentifyData, 0, sizeof(ATA_IDENTIFY)); - HBACommandHeader *CommandHeader = reinterpret_cast(HBAPortPtr->CommandListBase); - CommandHeader->CommandFISLength = sizeof(FIS_REG_H2D) / sizeof(uint32_t); - CommandHeader->Write = 0; - CommandHeader->PRDTLength = 1; - - HBACommandTable *CommandTable = reinterpret_cast(CommandHeader->CommandTableBaseAddress); - MemorySet(CommandTable, 0, sizeof(HBACommandTable) + (CommandHeader->PRDTLength - 1) * sizeof(HBAPRDTEntry)); - - CommandTable->PRDTEntry[0].DataBaseAddress = (uint32_t)(uint64_t)this->IdentifyData; - CommandTable->PRDTEntry[0].DataBaseAddressUpper = (uint32_t)((uint64_t)this->IdentifyData >> 32); - CommandTable->PRDTEntry[0].ByteCount = 511; - CommandTable->PRDTEntry[0].InterruptOnCompletion = 1; - - FIS_REG_H2D *CommandFIS = (FIS_REG_H2D *)(&CommandTable->CommandFIS); - CommandFIS->FISType = FIS_TYPE_REG_H2D; - CommandFIS->CommandControl = 1; - CommandFIS->Command = this->AHCIPortType == PortType::SATAPI ? ATAPI_CMD_IDENTIFY_PACKET : ATA_CMD_IDENTIFY; - - HBAPortPtr->CommandIssue = 1; - - while (HBAPortPtr->CommandIssue) - Yield(); - - if (HBAPortPtr->InterruptStatus & HBA_PxIS_TFES) - { - KernelLog("Error reading IDENTIFY command."); - return; - } - - if (IdentifyData->Signature != 0xA5) - KernelLog("Port %d has no validity signature.", PortNumber); - else - { - uint8_t *ptr = (uint8_t *)IdentifyData; - uint8_t sum = 0; - for (size_t i = 0; i < sizeof(ATA_IDENTIFY); i++) - sum += ptr[i]; - if (sum != 0) - { - KernelLog("Port %d has invalid checksum.", PortNumber); - return; - } - else - KernelLog("Port %d has valid checksum.", PortNumber); - } - - char *Model = (char *)this->IdentifyData->ModelNumber; - char ModelSwap[41]; - for (size_t i = 0; i < 40; i += 2) - { - ModelSwap[i] = Model[i + 1]; - ModelSwap[i + 1] = Model[i]; - } - ModelSwap[40] = 0; - - KernelLog("Port %d \"%s\" identified", PortNumber, - ModelSwap); - KernelLog("Port %d is %s (%d rotation rate)", PortNumber, - IdentifyData->NominalMediaRotationRate == 1 ? "SSD" : "HDD", - IdentifyData->NominalMediaRotationRate); - } -}; - -Port *Ports[64]; -int PortCount = 0; - -const char *PortTypeName[] = {"None", - "SATA", - "SEMB", - "PM", - "SATAPI"}; - -PortType CheckPortType(HBAPort *Port) -{ - uint32_t SataStatus = Port->SataStatus; - uint8_t InterfacePowerManagement = (SataStatus >> 8) & 0b111; - uint8_t DeviceDetection = SataStatus & 0b111; - - if (DeviceDetection != HBA_PORT_DEV_PRESENT) - return PortType::None; - if (InterfacePowerManagement != HBA_PORT_IPM_ACTIVE) - return PortType::None; - - switch (Port->Signature) - { - case SATA_SIG_ATAPI: - return PortType::SATAPI; - case SATA_SIG_ATA: - return PortType::SATA; - case SATA_SIG_PM: - return PortType::PM; - case SATA_SIG_SEMB: - return PortType::SEMB; - default: - return PortType::None; - } -} - -int __fs_Open(struct Inode *, int, mode_t) { return 0; } -int __fs_Close(struct Inode *) { return 0; } - -ssize_t __fs_Read(struct Inode *Node, void *Buffer, size_t Size, off_t Offset) -{ - bool ok = Ports[Node->GetMinor()]->ReadWrite(Offset / 512, - uint32_t(Size / 512), - (uint8_t *)Buffer, - false); - return ok ? Size : 0; -} - -ssize_t __fs_Write(struct Inode *Node, const void *Buffer, size_t Size, off_t Offset) -{ - bool ok = Ports[Node->GetMinor()]->ReadWrite(Offset / 512, - uint32_t(Size / 512), - (uint8_t *)Buffer, - true); - return ok ? Size : 0; -} - -const struct InodeOperations BlockOps = { - .Lookup = nullptr, - .Create = nullptr, - .Remove = nullptr, - .Rename = nullptr, - .Read = __fs_Read, - .Write = __fs_Write, - .Truncate = nullptr, - .Open = __fs_Open, - .Close = __fs_Close, - .Ioctl = nullptr, - .ReadDir = nullptr, - .MkDir = nullptr, - .RmDir = nullptr, - .SymLink = nullptr, - .ReadLink = nullptr, - .Seek = nullptr, - .Stat = nullptr, -}; - -void OnInterruptReceived(TrapFrame *) -{ -} - -EXTERNC int cxx_Panic() -{ - for (int i = 0; i < PortCount; i++) - Ports[i]->StopCMD(); - return 0; -} - -PCIArray *Devices; -EXTERNC int cxx_Probe() -{ - uint16_t VendorIDs[] = {0x8086, /* Intel */ - 0x15AD, /* VMware */ - PCI_END}; - uint16_t DeviceIDs[] = {0x2922, /* ICH9 */ - 0x2829, /* ICH8 */ - 0x07E0, /* SATA AHCI (VMware) */ - PCI_END}; - Devices = GetPCIDevices(VendorIDs, DeviceIDs); - if (Devices == nullptr) - { - KernelLog("No AHCI device found."); - return -ENODEV; - } - return 0; -} - -EXTERNC int cxx_Initialize() -{ - PCIArray *ctx = Devices; - - /** - * We loop through all the devices and initialize them - */ - while (ctx != nullptr) - { - /* We don't use the interrupt handler now... maybe we will in the future */ - // RegisterInterruptHandler(iLine(ctx->Device), (void *)OnInterruptReceived); - - InitializePCI(ctx->Device); - HBAMemory *HBA = (HBAMemory *)(uintptr_t)GetBAR(5, ctx->Device); - - uint32_t PortsImplemented = HBA->PortsImplemented; - KernelLog("AHCI ports implemented: %x", PortsImplemented); - for (int i = 0; i < 32; i++) - { - if (PortCount > 64) - { - KernelLog("There are more than 64 AHCI ports implemented"); - break; - } - - if (PortsImplemented & (1 << i)) - { - KernelLog("Port %d implemented", i); - PortType portType = CheckPortType(&HBA->Ports[i]); - if (portType == PortType::SATA || portType == PortType::SATAPI) - { - KernelPrint("%s drive found at port %d", PortTypeName[portType], i); - Ports[PortCount] = new Port(portType, &HBA->Ports[i], PortCount); - dev_t ret = RegisterDevice(BLOCK_TYPE_HDD, &BlockOps); - if (ret != (dev_t)PortCount) - { - KernelPrint("Failed to register block device %d", ret); - return -EBADF; - } - - PortCount++; - Ports[PortCount] = nullptr; - } - else - { - if (portType != PortType::None) - { - KernelPrint("Unsupported drive type %s found at port %d", - PortTypeName[portType], i); - } - } - } - } - - ctx = (PCIArray *)ctx->Next; - } - - KernelLog("Initializing AHCI ports"); - for (int i = 0; i < PortCount; i++) - Ports[i]->Configure(); - - return PortCount > 0 ? 0 : -ENODEV; -} - -EXTERNC int cxx_Finalize() -{ - for (int i = 0; i < PortCount; i++) - { - Ports[i]->StopCMD(); - delete Ports[i]; - } - - PortCount = 0; - - do - { - UnregisterDevice(PortCount); - PortCount--; - } while (PortCount >= 0); - - PCIArray *ctx = Devices; - - while (ctx != nullptr) - { - ctx->Device->Header->Command |= PCI_COMMAND_INTX_DISABLE; - ctx = (PCIArray *)ctx->Next; - } - - // std::list Devices = PCIManager->FindPCIDevice(VendorIDs, DeviceIDs); - // foreach (auto dev in Devices) - // Interrupts::RemoveHandler(OnInterruptReceived, iLine(dev)); - return 0; -} diff --git a/Drivers/storage/ahci/ahci.hpp b/Drivers/storage/ahci/ahci.hpp deleted file mode 100644 index 99242b91..00000000 --- a/Drivers/storage/ahci/ahci.hpp +++ /dev/null @@ -1,25 +0,0 @@ -/* - This file is part of Fennix Drivers. - - Fennix Drivers is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. - - Fennix Drivers is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Fennix Drivers. If not, see . -*/ - -#pragma once - -#include - -EXTERNC int cxx_Panic(); -EXTERNC int cxx_Probe(); -EXTERNC int cxx_Initialize(); -EXTERNC int cxx_Finalize(); diff --git a/Drivers/storage/ahci/main.c b/Drivers/storage/ahci/main.c deleted file mode 100644 index ae44b033..00000000 --- a/Drivers/storage/ahci/main.c +++ /dev/null @@ -1,31 +0,0 @@ -/* - This file is part of Fennix Drivers. - - Fennix Drivers is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. - - Fennix Drivers is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Fennix Drivers. If not, see . -*/ - -#include - -#include "ahci.hpp" - -int DriverEntry() { return cxx_Initialize(); } -int DriverFinal() { return cxx_Finalize(); } -int DriverPanic() { return cxx_Panic(); } -int DriverProbe() { return cxx_Probe(); } - -DriverInfo("ahci", - "Advanced Host Controller Interface Driver", - "EnderIce2", - 0, 0, 1, - "GPLv3"); diff --git a/Drivers/storage/ata/Makefile b/Drivers/storage/ata/Makefile deleted file mode 100644 index 9a92e2ef..00000000 --- a/Drivers/storage/ata/Makefile +++ /dev/null @@ -1,35 +0,0 @@ -default: - $(error Do not run this Makefile directly!) - -S_SOURCES = $(shell find ./ -type f -name '*.S') -C_SOURCES = $(shell find ./ -type f -name '*.c') -CXX_SOURCES = $(shell find ./ -type f -name '*.cpp') -HEADERS = $(sort $(dir $(wildcard ../../include/*))) -OBJ = $(C_SOURCES:.c=.o) $(CXX_SOURCES:.cpp=.o) $(S_SOURCES:.S=.o) -STACK_USAGE_OBJ = $(C_SOURCES:.c=.su) $(CXX_SOURCES:.cpp=.su) - -FILENAME = $(notdir $(shell pwd)).drv - -build: $(FILENAME) - mv $(FILENAME) $(OUTPUT_DIR)$(FILENAME) - -$(FILENAME): $(OBJ) - $(info Linking $@) - $(CC) $(DRIVER_LDFLAGS) $(OBJ) $(OUTPUT_DIR)dcrt0.o -L$(OUTPUT_DIR) -lkernel -o $@ - -WARNCFLAG = -Wall -Wextra - -%.o: %.c $(HEADERS) - $(info Compiling $<) - $(CC) $(DRIVER_CFLAGS) $(WARNCFLAG) -std=c17 -c $< -o $@ - -%.o: %.cpp $(HEADERS) - $(info Compiling $<) - $(CXX) $(DRIVER_CFLAGS) $(WARNCFLAG) -std=c++20 -fno-exceptions -fno-rtti -c $< -o $@ - -%.o: %.S - $(info Compiling $<) - $(AS) -o $@ $< - -clean: - rm -f file.map $(OBJ) $(STACK_USAGE_OBJ) diff --git a/Drivers/storage/ata/main.c b/Drivers/storage/ata/main.c deleted file mode 100644 index b46ed735..00000000 --- a/Drivers/storage/ata/main.c +++ /dev/null @@ -1,76 +0,0 @@ -/* - This file is part of Fennix Drivers. - - Fennix Drivers is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. - - Fennix Drivers is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Fennix Drivers. If not, see . -*/ - -#include -#include -#include -#include - -bool IsATAPresent() -{ - outb(0x1F0 + 2, 0); - outb(0x1F0 + 3, 0); - outb(0x1F0 + 4, 0); - outb(0x1F0 + 5, 0); - outb(0x1F0 + 7, 0xEC); - if (inb(0x1F0 + 7) == 0 || inb(0x1F0 + 1) != 0) - return false; - return true; -} - -void MasterInterruptHandler(TrapFrame *) -{ -} - -void SlaveInterruptHandler(TrapFrame *) -{ -} - -int DriverEntry() -{ - RegisterInterruptHandler(14, MasterInterruptHandler); - RegisterInterruptHandler(15, SlaveInterruptHandler); - - return 0; -} - -int DriverFinal() -{ - UnregisterInterruptHandler(14, MasterInterruptHandler); - UnregisterInterruptHandler(15, SlaveInterruptHandler); - - return 0; -} - -int DriverPanic() -{ - return 0; -} - -int DriverProbe() -{ - if (!IsATAPresent()) - return -ENODEV; - - return 0; -} - -DriverInfo("ata", - "Advanced Technology Attachment Driver", - "EnderIce2", - 0, 0, 1, - "GPLv3");