From 3f47c53398a2cd10fe1b205e1393c3ceab4c675c Mon Sep 17 00:00:00 2001 From: Amlal El Mahrouss Date: Mon, 16 Mar 2026 12:08:15 +0100 Subject: [FEAT] Kernel: Finally include the BNID network driver when compiling NeKernel. Signed-off-by: Amlal El Mahrouss --- src/kernel/HALKit/AMD64/HalKernelMain.cpp | 6 + .../HALKit/AMD64/Network/Generic+Basic+BNID.cpp | 144 +++++++++++++++++++++ .../HALKit/AMD64/Network/Generic+Basic+RTL8139.cpp | 128 ------------------ src/kernel/KernelKit/PCI/Device.h | 2 +- src/kernel/amd64-ci.make | 2 +- src/kernel/amd64-desktop.make | 2 +- 6 files changed, 153 insertions(+), 131 deletions(-) create mode 100644 src/kernel/HALKit/AMD64/Network/Generic+Basic+BNID.cpp delete mode 100644 src/kernel/HALKit/AMD64/Network/Generic+Basic+RTL8139.cpp diff --git a/src/kernel/HALKit/AMD64/HalKernelMain.cpp b/src/kernel/HALKit/AMD64/HalKernelMain.cpp index 7468b76d..57f980c6 100644 --- a/src/kernel/HALKit/AMD64/HalKernelMain.cpp +++ b/src/kernel/HALKit/AMD64/HalKernelMain.cpp @@ -133,6 +133,8 @@ EXTERN_C Kernel::Int32 hal_init_platform(Kernel::HEL::BootInfoHeader* handover_h return kEfiFail; } +EXTERN_C BOOL rtl_init_nic_rtl8139(); + EXTERN_C Kernel::Void hal_real_init(Kernel::Void) { HAL::mp_init_cores(kHandoverHeader->f_HardwareTables.f_VendorPtr); @@ -161,6 +163,10 @@ EXTERN_C Kernel::Void hal_real_init(Kernel::Void) { UserProcessScheduler::The().SwitchTeam(kMidUserTeam); +#ifdef __HALKIT_INCLUDES_BNID__ + rtl_init_nic_rtl8139(); +#endif + while (YES); } #endif // ifndef __NE_MODULAR_KERNEL_COMPONENTS__ diff --git a/src/kernel/HALKit/AMD64/Network/Generic+Basic+BNID.cpp b/src/kernel/HALKit/AMD64/Network/Generic+Basic+BNID.cpp new file mode 100644 index 00000000..4c1d0f1f --- /dev/null +++ b/src/kernel/HALKit/AMD64/Network/Generic+Basic+BNID.cpp @@ -0,0 +1,144 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2024-2026, Amlal El Mahrouss (amlal@nekernel.org) +// Licensed under the Apache License, Version 2.0 (see LICENSE file) +// Official repository: https://github.com/ne-foss-org/nekernel + +#include +#include +#include +#include + +/// @note BNID (RTL8139' Basic Network Interface) driver + +#define kNetDevID (0x8139) +#define kNetSubClass (0x10EC) + +using namespace Kernel; +using namespace Kernel::HAL; + +STATIC UInt16 kRTLIOBase = 0xFFFF; + +STATIC UInt32 kRXOffset = 0UL; +STATIC constexpr CONST UInt32 kRXBufferSize = 8192 + 16 + 1500; + +STATIC UInt8* kRXUpperLayer = nullptr; +STATIC UInt8* kRXBuffer = nullptr; + +STATIC PCI::Device kNetDev; + +/***********************************************************************************/ +///@brief BNID Init routine. +/***********************************************************************************/ + +EXTERN_C BOOL rtl_init_nic_rtl8139() { + STATIC BOOL kTXRXEnabled = NO; + if (kTXRXEnabled) return NO; + + PCI::Iterator iterator(Types::PciDeviceKind::NetworkController, 0x00); + + for (SizeT device_index = 0; device_index < NE_BUS_COUNT; ++device_index) { + kNetDev = iterator[device_index].Leak(); // Leak device. + + if (kNetDev.VendorId() == kNetSubClass && kNetDev.DeviceId() == kNetDevID) { + kNetDev.EnableMmio(); + kNetDev.BecomeBusMaster(); + + break; + } + } + + kRTLIOBase = kNetDev.Bar(0); + + MUST_PASS(kRTLIOBase != 0xFFFF); + + kRXBuffer = reinterpret_cast(rtl_dma_alloc(sizeof(UInt8) * kRXBufferSize, 0)); + + /// Reset first. + + rt_out8(kRTLIOBase + 0x37, 0x10); + + UInt16 timeout = 0U; + + while (rt_in8(kRTLIOBase + 0x37) & 0x10) { + ++timeout; + if (timeout > 0x1000) break; + } + + rt_out32(kRTLIOBase + 0x30, (UInt32) (UIntPtr) kRXBuffer); + + rt_out8(kRTLIOBase + 0x37, 0x0C); + + rt_out32(kRTLIOBase + 0x44, 0xF | (1 << 7)); + + rt_out16(kRTLIOBase + 0x3C, 0x0005); + + kTXRXEnabled = YES; + + kout << "The Basic Network Interface Driver (BNID) has been initialized.\r"; + + return YES; +} + +/***********************************************************************************/ +/// @brief BNID I/O interrupt handler. +/// @param rsp stack pointer. +/// @note This function is called when the device interrupts to retrieve network data. +/***********************************************************************************/ + +EXTERN_C Void rtl_rtl8139_interrupt_handler(UIntPtr rsp) { + if (kRTLIOBase == 0xFFFF || kRTLIOBase == 0) return; + + NE_UNUSED(rsp); + + UInt16 status = rt_in16(kRTLIOBase + 0x3E); + rt_out16(kRTLIOBase + 0x3E, status); + + if (status & 0x01) { + // While we receive data. + while ((rt_in8(kRTLIOBase + 0x37) & 0x01) == 0) { + // We grab an offset from the RX buffer. + UInt32 offset = kRXOffset % kRXBufferSize; + + // If the offset is too high, we reset it. + if (offset >= (kRXBufferSize - 16)) { + kRXOffset = 0UL; + offset = 0UL; + } + + volatile UInt8* packet = kRXBuffer + offset + 4; + UInt16 len = *(UInt16*) (kRXBuffer + offset + 2); + + kRXUpperLayer[(offset + 4)] = *packet; + kRXOffset += (len + 4); + + rt_out16(kRTLIOBase + 0x38, (UInt16) (kRXOffset - 16)); + } + } + + if (!(status & 0x04)) { + err_global_get() = kErrorNoNetwork; + } +} + +/***********************************************************************************/ +/// @brief BNID get upper layer function +/// @return the upper layer. +/// @retval nullptr if no upper layer is set. +/// @retval pointer to the upper layer if set. +/***********************************************************************************/ + +EXTERN_C UInt8* rtl_rtl8139_get_upper_layer() { + return kRXUpperLayer; +} + +/***********************************************************************************/ +/// @brief BNID set upper layer function +/// @param layer the upper layer. +/***********************************************************************************/ + +EXTERN_C BOOL rtl_rtl8139_set_upper_layer(UInt8* layer) { + if (!layer) return NO; + kRXUpperLayer = layer; + + return YES; +} diff --git a/src/kernel/HALKit/AMD64/Network/Generic+Basic+RTL8139.cpp b/src/kernel/HALKit/AMD64/Network/Generic+Basic+RTL8139.cpp deleted file mode 100644 index aacda36c..00000000 --- a/src/kernel/HALKit/AMD64/Network/Generic+Basic+RTL8139.cpp +++ /dev/null @@ -1,128 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -// Copyright 2024-2026, Amlal El Mahrouss (amlal@nekernel.org) -// Licensed under the Apache License, Version 2.0 (see LICENSE file) -// Official repository: https://github.com/ne-foss-org/nekernel - -#include -#include -#include - -using namespace Kernel; -using namespace Kernel::HAL; - -STATIC UInt16 kRTLIOBase = 0xFFFF; - -STATIC BOOL kTXRXEnabled = NO; - -STATIC UInt32 kRXOffset = 0UL; -STATIC constexpr CONST UInt32 kRXBufferSize = 8192 + 16 + 1500; - -STATIC UInt8* kRXUpperLayer = nullptr; -STATIC UInt8* kRXBuffer = nullptr; - -/***********************************************************************************/ -///@brief RTL8139 Init routine. -/***********************************************************************************/ - -EXTERN_C BOOL rtl_init_nic_rtl8139(UInt16 io_base) { - if (kTXRXEnabled) return NO; - - kRTLIOBase = io_base; - - MUST_PASS(io_base != 0xFFFF); - - kRXBuffer = reinterpret_cast(rtl_dma_alloc(sizeof(UInt8) * kRXBufferSize, 0)); - - MUST_PASS(kRXBuffer); - - /// Reset first. - - rt_out8(io_base + 0x37, 0x10); - - UInt16 timeout = 0U; - - while (rt_in8(io_base + 0x37) & 0x10) { - ++timeout; - if (timeout > 0x1000) break; - } - - if (timeout <= 0x1000) { - return NO; - } - - rt_out32(io_base + 0x30, (UInt32) (UIntPtr) kRXBuffer); - - rt_out8(io_base + 0x37, 0x0C); - - rt_out32(io_base + 0x44, 0xF | (1 << 7)); - - rt_out16(io_base + 0x3C, 0x0005); - - kTXRXEnabled = YES; - - return YES; -} - -/***********************************************************************************/ -/// @brief RTL8139 I/O interrupt handler. -/// @param rsp stack pointer. -/// @note This function is called when the device interrupts to retrieve network data. -/***********************************************************************************/ - -EXTERN_C Void rtl_rtl8139_interrupt_handler(UIntPtr rsp) { - if (kRTLIOBase == 0xFFFF || kRTLIOBase == 0) return; - - NE_UNUSED(rsp); - - UInt16 status = rt_in16(kRTLIOBase + 0x3E); - rt_out16(kRTLIOBase + 0x3E, status); - - if (status & 0x01) { - // While we receive data. - while ((rt_in8(kRTLIOBase + 0x37) & 0x01) == 0) { - // We grab an offset from the RX buffer. - UInt32 offset = kRXOffset % kRXBufferSize; - - // If the offset is too high, we reset it. - if (offset >= (kRXBufferSize - 16)) { - kRXOffset = 0UL; - offset = 0UL; - } - - volatile UInt8* packet = kRXBuffer + offset + 4; - UInt16 len = *(UInt16*) (kRXBuffer + offset + 2); - - kRXUpperLayer[(offset + 4)] = *packet; - kRXOffset += (len + 4); - - rt_out16(kRTLIOBase + 0x38, (UInt16) (kRXOffset - 16)); - } - } - - if (!(status & 0x04)) { - err_global_get() = kErrorNoNetwork; - } -} - -/***********************************************************************************/ -/// @brief RTL8139 get upper layer function -/// @return the upper layer. -/// @retval nullptr if no upper layer is set. -/// @retval pointer to the upper layer if set. -/***********************************************************************************/ - -EXTERN_C UInt8* rtl_rtl8139_get_upper_layer() { - return kRXUpperLayer; -} - -/***********************************************************************************/ -/// @brief RTL8139 set upper layer function -/// @param layer the upper layer. -/***********************************************************************************/ - -EXTERN_C BOOL rtl_rtl8139_set_upper_layer(UInt8* layer) { - if (!layer) return NO; - kRXUpperLayer = layer; - - return YES; -} diff --git a/src/kernel/KernelKit/PCI/Device.h b/src/kernel/KernelKit/PCI/Device.h index b7737385..1adc9f24 100644 --- a/src/kernel/KernelKit/PCI/Device.h +++ b/src/kernel/KernelKit/PCI/Device.h @@ -51,7 +51,7 @@ class Device final { } public: - UShort DeviceId(); + UInt16 DeviceId(); UShort VendorId(); UShort InterfaceId(); UChar Class(); diff --git a/src/kernel/amd64-ci.make b/src/kernel/amd64-ci.make index dcb1c97e..71e350e5 100644 --- a/src/kernel/amd64-ci.make +++ b/src/kernel/amd64-ci.make @@ -5,7 +5,7 @@ CXX = x86_64-w64-mingw32-g++ LD = x86_64-w64-mingw32-ld -CCFLAGS = -fshort-wchar -D__nekernel_dma_best_align=8 -D__nekernel_max_cores=8 -c -D__NE_AMD64__ -D__NEOSKRNL__ -D__NE_VEPM__ -Werror -Wall -Wpedantic -Wextra -mno-red-zone -fno-rtti -fno-exceptions -std=c++20 -D__NE_SUPPORT_NX__ -O0 -I../vendor -D__FSKIT_INCLUDES_NEFS__ -D__NEKERNEL__ -D__HAVE_NE_API__ -D__FREESTANDING__ -D__NE_VIRTUAL_MEMORY_SUPPORT__ -D__NE_AUTO_FORMAT__ -D__NE__ -I./ -I../ -I../boot +CCFLAGS = -fshort-wchar -D__nekernel_dma_best_align=8 -D__HALKIT_INCLUDES_BNID__=1 -D__nekernel_max_cores=8 -c -D__NE_AMD64__ -D__NEOSKRNL__ -D__NE_VEPM__ -Werror -Wall -Wpedantic -Wextra -mno-red-zone -fno-rtti -fno-exceptions -std=c++20 -D__NE_SUPPORT_NX__ -O0 -I../vendor -D__FSKIT_INCLUDES_NEFS__ -D__NEKERNEL__ -D__HAVE_NE_API__ -D__FREESTANDING__ -D__NE_VIRTUAL_MEMORY_SUPPORT__ -D__NE_AUTO_FORMAT__ -D__NE__ -I./ -I../ -I../boot ASM = nasm diff --git a/src/kernel/amd64-desktop.make b/src/kernel/amd64-desktop.make index 4afcdfd2..73bb2f43 100644 --- a/src/kernel/amd64-desktop.make +++ b/src/kernel/amd64-desktop.make @@ -5,7 +5,7 @@ CXX = x86_64-w64-mingw32-g++ LD = x86_64-w64-mingw32-ld -CCFLAGS = -fshort-wchar -D__nekernel_dma_pool_start=0x1000000 -D__nekernel_dma_pool_size=0x1000000 \ +CCFLAGS = -fshort-wchar -D__nekernel_dma_pool_start=0x1000000 -D__HALKIT_INCLUDES_BNID__=1 -D__nekernel_dma_pool_size=0x1000000 \ -D__nekernel_halkit_include_processor="" -D__nekernel_max_cores=8 -c -D__NE_AMD64__ -D__NEOSKRNL__ -D__NE_VEPM__ -Wall -Wpedantic -Wextra -mno-red-zone -fno-rtti -fno-exceptions -std=c++20 -D__nekernel_dma_best_align=8 -D__FSKIT_INCLUDES_OPENHEFS__ -D__FSKIT_INCLUDES_EXT2__ -D__NE_SUPPORT_NX__ -O0 -I../vendor -D__NEKERNEL__ -D__HAVE_NE_API__ -D__FREESTANDING__ -D__NE_VIRTUAL_MEMORY_SUPPORT__ -D__NE_AUTO_FORMAT__ -D__NE__ -I./ -I../ -I../boot ASM = nasm -- cgit v1.2.3