-
Notifications
You must be signed in to change notification settings - Fork 1
Development #116
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Development #116
Changes from all commits
Commits
Show all changes
7 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,188 @@ | ||
#include "E1000.h" | ||
#include "Console.h" | ||
#include "Cpu.h" | ||
#include "Io.h" | ||
#include "KernelHeap.h" | ||
#include "MemOps.h" | ||
#include "PCI/PCI.h" | ||
#include "PMem.h" | ||
|
||
static E1000Device g_e1000_device = {0}; | ||
|
||
static uint32_t E1000_ReadReg(uint32_t reg) { | ||
return *(volatile uint32_t*)(g_e1000_device.mmio_base + reg); | ||
} | ||
|
||
static void E1000_WriteReg(uint32_t reg, uint32_t value) { | ||
*(volatile uint32_t*)(g_e1000_device.mmio_base + reg) = value; | ||
} | ||
|
||
static uint16_t E1000_ReadEEPROM(uint8_t addr) { | ||
E1000_WriteReg(E1000_EERD, (addr << 8) | 1); | ||
uint32_t val; | ||
do { | ||
val = E1000_ReadReg(E1000_EERD); | ||
} while (!(val & (1 << 4))); | ||
return (val >> 16) & 0xFFFF; | ||
} | ||
assembler-0 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
static void E1000_ReadMAC(void) { | ||
uint16_t mac01 = E1000_ReadEEPROM(0); | ||
uint16_t mac23 = E1000_ReadEEPROM(1); | ||
uint16_t mac45 = E1000_ReadEEPROM(2); | ||
|
||
g_e1000_device.mac_address[0] = mac01 & 0xFF; | ||
g_e1000_device.mac_address[1] = (mac01 >> 8) & 0xFF; | ||
g_e1000_device.mac_address[2] = mac23 & 0xFF; | ||
g_e1000_device.mac_address[3] = (mac23 >> 8) & 0xFF; | ||
g_e1000_device.mac_address[4] = mac45 & 0xFF; | ||
g_e1000_device.mac_address[5] = (mac45 >> 8) & 0xFF; | ||
} | ||
|
||
static void E1000_InitRX(void) { | ||
// Allocate RX descriptors | ||
g_e1000_device.rx_descs = (E1000RxDesc*)KernelMemoryAlloc(sizeof(E1000RxDesc) * E1000_NUM_RX_DESC); | ||
g_e1000_device.rx_buffers = (uint8_t**)KernelMemoryAlloc(sizeof(uint8_t*) * E1000_NUM_RX_DESC); | ||
|
||
// Allocate RX buffers | ||
for (int i = 0; i < E1000_NUM_RX_DESC; i++) { | ||
g_e1000_device.rx_buffers[i] = (uint8_t*)KernelMemoryAlloc(2048); | ||
g_e1000_device.rx_descs[i].addr = (uint64_t)g_e1000_device.rx_buffers[i]; | ||
g_e1000_device.rx_descs[i].status = 0; | ||
} | ||
|
||
// Set RX descriptor base and length | ||
uint64_t rx_desc_phys = (uint64_t)g_e1000_device.rx_descs; | ||
E1000_WriteReg(E1000_RDBAL, rx_desc_phys & 0xFFFFFFFF); | ||
E1000_WriteReg(E1000_RDBAH, (rx_desc_phys >> 32) & 0xFFFFFFFF); | ||
E1000_WriteReg(E1000_RDLEN, E1000_NUM_RX_DESC * sizeof(E1000RxDesc)); | ||
|
||
// Set RX head and tail | ||
E1000_WriteReg(E1000_RDH, 0); | ||
E1000_WriteReg(E1000_RDT, E1000_NUM_RX_DESC - 1); | ||
|
||
g_e1000_device.rx_cur = 0; | ||
|
||
// Enable RX | ||
E1000_WriteReg(E1000_RCTL, E1000_RCTL_EN | E1000_RCTL_BAM | E1000_RCTL_BSIZE_2048); | ||
} | ||
assembler-0 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
static void E1000_InitTX(void) { | ||
// Allocate TX descriptors | ||
g_e1000_device.tx_descs = (E1000TxDesc*)KernelMemoryAlloc(sizeof(E1000TxDesc) * E1000_NUM_TX_DESC); | ||
g_e1000_device.tx_buffers = (uint8_t**)KernelMemoryAlloc(sizeof(uint8_t*) * E1000_NUM_TX_DESC); | ||
|
||
// Allocate TX buffers | ||
for (int i = 0; i < E1000_NUM_TX_DESC; i++) { | ||
g_e1000_device.tx_buffers[i] = (uint8_t*)KernelMemoryAlloc(2048); | ||
g_e1000_device.tx_descs[i].addr = (uint64_t)g_e1000_device.tx_buffers[i]; | ||
g_e1000_device.tx_descs[i].status = 1; // DD bit set | ||
} | ||
|
||
// Set TX descriptor base and length | ||
uint64_t tx_desc_phys = (uint64_t)g_e1000_device.tx_descs; | ||
E1000_WriteReg(E1000_TDBAL, tx_desc_phys & 0xFFFFFFFF); | ||
E1000_WriteReg(E1000_TDBAH, (tx_desc_phys >> 32) & 0xFFFFFFFF); | ||
E1000_WriteReg(E1000_TDLEN, E1000_NUM_TX_DESC * sizeof(E1000TxDesc)); | ||
|
||
// Set TX head and tail | ||
E1000_WriteReg(E1000_TDH, 0); | ||
E1000_WriteReg(E1000_TDT, 0); | ||
|
||
g_e1000_device.tx_cur = 0; | ||
|
||
// Enable TX | ||
E1000_WriteReg(E1000_TCTL, E1000_TCTL_EN | E1000_TCTL_PSP); | ||
} | ||
assembler-0 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
int E1000_Init(void) { | ||
|
||
// Find E1000 device | ||
PciDevice pci_dev; | ||
if (PciFindDevice(E1000_VENDOR_ID, E1000_DEVICE_ID, &pci_dev) != 0) { | ||
PrintKernel("E1000: Device not found\n"); | ||
return -1; | ||
} | ||
|
||
PrintKernel("E1000: Found device at "); | ||
PrintKernelInt(pci_dev.bus); | ||
PrintKernel(":"); | ||
PrintKernelInt(pci_dev.device); | ||
PrintKernel(":"); | ||
PrintKernelInt(pci_dev.function); | ||
PrintKernel("\n"); | ||
|
||
// Get MMIO base address | ||
g_e1000_device.mmio_base = pci_dev.bar0 & ~0xF; | ||
|
||
// Enable bus mastering | ||
uint16_t cmd = PciReadConfig16(pci_dev.bus, pci_dev.device, pci_dev.function, 0x04); | ||
PciWriteConfig16(pci_dev.bus, pci_dev.device, pci_dev.function, 0x04, cmd | 0x04); | ||
|
||
assembler-0 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
// Reset device | ||
E1000_WriteReg(E1000_CTRL, E1000_CTRL_RST); | ||
delay(10000); | ||
|
||
// Read MAC address | ||
E1000_ReadMAC(); | ||
PrintKernel("E1000: MAC Address: "); | ||
for (int i = 0; i < 6; i++) { | ||
PrintKernelHex(g_e1000_device.mac_address[i]); | ||
if (i < 5) PrintKernel(":"); | ||
} | ||
PrintKernel("\n"); | ||
|
||
// Set MAC address in RAL/RAH | ||
uint32_t ral = g_e1000_device.mac_address[0] | | ||
(g_e1000_device.mac_address[1] << 8) | | ||
(g_e1000_device.mac_address[2] << 16) | | ||
(g_e1000_device.mac_address[3] << 24); | ||
uint32_t rah = g_e1000_device.mac_address[4] | | ||
(g_e1000_device.mac_address[5] << 8) | | ||
(1 << 31); // Address Valid bit | ||
|
||
E1000_WriteReg(E1000_RAL, ral); | ||
E1000_WriteReg(E1000_RAH, rah); | ||
|
||
// Initialize RX and TX | ||
E1000_InitRX(); | ||
E1000_InitTX(); | ||
|
||
// Link up | ||
E1000_WriteReg(E1000_CTRL, E1000_CTRL_SLU | E1000_CTRL_ASDE); | ||
|
||
g_e1000_device.initialized = 1; | ||
PrintKernelSuccess("E1000: Driver initialized successfully\n"); | ||
|
||
return 0; | ||
} | ||
|
||
int E1000_SendPacket(const void* data, uint16_t length) { | ||
if (!g_e1000_device.initialized || length > 1518) { | ||
return -1; | ||
} | ||
|
||
// Wait for descriptor to be available | ||
while (!(g_e1000_device.tx_descs[g_e1000_device.tx_cur].status & 1)) { | ||
// Descriptor not ready | ||
} | ||
|
||
// Copy data to buffer | ||
FastMemcpy(g_e1000_device.tx_buffers[g_e1000_device.tx_cur], data, length); | ||
|
||
// Set up descriptor | ||
g_e1000_device.tx_descs[g_e1000_device.tx_cur].length = length; | ||
g_e1000_device.tx_descs[g_e1000_device.tx_cur].cmd = (1 << 3) | (1 << 1) | 1; // RS | IFCS | EOP | ||
g_e1000_device.tx_descs[g_e1000_device.tx_cur].status = 0; | ||
|
||
// Update tail pointer | ||
uint16_t old_cur = g_e1000_device.tx_cur; | ||
g_e1000_device.tx_cur = (g_e1000_device.tx_cur + 1) % E1000_NUM_TX_DESC; | ||
E1000_WriteReg(E1000_TDT, g_e1000_device.tx_cur); | ||
|
||
return 0; | ||
} | ||
|
||
const E1000Device* E1000_GetDevice(void) { | ||
return g_e1000_device.initialized ? &g_e1000_device : NULL; | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
#ifndef VOIDFRAME_E1000_H | ||
#define VOIDFRAME_E1000_H | ||
|
||
#include "stdint.h" | ||
|
||
// E1000 PCI IDs | ||
#define E1000_VENDOR_ID 0x8086 | ||
#define E1000_DEVICE_ID 0x100E // 82540EM | ||
|
||
// Register offsets | ||
#define E1000_CTRL 0x0000 // Device Control | ||
#define E1000_STATUS 0x0008 // Device Status | ||
#define E1000_EECD 0x0010 // EEPROM Control | ||
#define E1000_EERD 0x0014 // EEPROM Read | ||
#define E1000_ICR 0x00C0 // Interrupt Cause Read | ||
#define E1000_IMS 0x00D0 // Interrupt Mask Set | ||
#define E1000_IMC 0x00D8 // Interrupt Mask Clear | ||
#define E1000_RCTL 0x0100 // RX Control | ||
#define E1000_RDBAL 0x2800 // RX Descriptor Base Address Low | ||
#define E1000_RDBAH 0x2804 // RX Descriptor Base Address High | ||
#define E1000_RDLEN 0x2808 // RX Descriptor Length | ||
#define E1000_RDH 0x2810 // RX Descriptor Head | ||
#define E1000_RDT 0x2818 // RX Descriptor Tail | ||
#define E1000_TCTL 0x0400 // TX Control | ||
#define E1000_TDBAL 0x3800 // TX Descriptor Base Address Low | ||
#define E1000_TDBAH 0x3804 // TX Descriptor Base Address High | ||
#define E1000_TDLEN 0x3808 // TX Descriptor Length | ||
#define E1000_TDH 0x3810 // TX Descriptor Head | ||
#define E1000_TDT 0x3818 // TX Descriptor Tail | ||
#define E1000_RAL 0x5400 // Receive Address Low | ||
#define E1000_RAH 0x5404 // Receive Address High | ||
|
||
// Control Register bits | ||
#define E1000_CTRL_RST (1 << 26) // Device Reset | ||
#define E1000_CTRL_ASDE (1 << 5) // Auto-Speed Detection Enable | ||
#define E1000_CTRL_SLU (1 << 6) // Set Link Up | ||
|
||
// RX Control bits | ||
#define E1000_RCTL_EN (1 << 1) // Receiver Enable | ||
#define E1000_RCTL_BAM (1 << 15) // Broadcast Accept Mode | ||
#define E1000_RCTL_BSIZE_2048 (0 << 16) // Buffer Size 2048 | ||
|
||
// TX Control bits | ||
#define E1000_TCTL_EN (1 << 1) // Transmitter Enable | ||
#define E1000_TCTL_PSP (1 << 3) // Pad Short Packets | ||
|
||
// Descriptor counts | ||
#define E1000_NUM_RX_DESC 32 | ||
#define E1000_NUM_TX_DESC 32 | ||
|
||
// RX Descriptor | ||
typedef struct { | ||
uint64_t addr; | ||
uint16_t length; | ||
uint16_t checksum; | ||
uint8_t status; | ||
uint8_t errors; | ||
uint16_t special; | ||
} __attribute__((packed)) E1000RxDesc; | ||
|
||
// TX Descriptor | ||
typedef struct { | ||
uint64_t addr; | ||
uint16_t length; | ||
uint8_t cso; | ||
uint8_t cmd; | ||
uint8_t status; | ||
uint8_t css; | ||
uint16_t special; | ||
} __attribute__((packed)) E1000TxDesc; | ||
|
||
// Device structure | ||
typedef struct { | ||
uint32_t mmio_base; | ||
uint8_t mac_address[6]; | ||
E1000RxDesc* rx_descs; | ||
E1000TxDesc* tx_descs; | ||
uint8_t** rx_buffers; | ||
assembler-0 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
uint8_t** tx_buffers; | ||
uint16_t rx_cur; | ||
uint16_t tx_cur; | ||
int initialized; | ||
} E1000Device; | ||
|
||
assembler-0 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
// Function prototypes | ||
int E1000_Init(void); | ||
int E1000_SendPacket(const void* data, uint16_t length); | ||
const E1000Device* E1000_GetDevice(void); | ||
|
||
#endif // VOIDFRAME_E1000_H |
6 changes: 3 additions & 3 deletions
6
drivers/ethernet/RTL8139.c → drivers/ethernet/realtek/RTL8139.c
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
File renamed without changes.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.