aboutsummaryrefslogtreecommitdiff
path: root/kernel/drivers
diff options
context:
space:
mode:
authorMarvin Borner2020-09-20 17:11:29 +0200
committerMarvin Borner2020-09-20 17:11:29 +0200
commitb6c8b7df4344d45ced50bea24cbb4de3ef229330 (patch)
tree0999810b9e3ff17cc4715cfd171464f761a9a55f /kernel/drivers
parent667ce77a5de7183654cb6f8752c6d120b1b3ae19 (diff)
Started rtl8139 driver
Diffstat (limited to 'kernel/drivers')
-rw-r--r--kernel/drivers/ide.c16
-rw-r--r--kernel/drivers/net.c95
2 files changed, 110 insertions, 1 deletions
diff --git a/kernel/drivers/ide.c b/kernel/drivers/ide.c
index d637a2b..eda18e9 100644
--- a/kernel/drivers/ide.c
+++ b/kernel/drivers/ide.c
@@ -3,6 +3,7 @@
#include <cpu.h>
#include <def.h>
#include <ide.h>
+#include <print.h>
int ide_wait(int check)
{
@@ -18,24 +19,37 @@ int ide_wait(int check)
return 0;
}
-void __attribute__((optimize("O0"))) * ide_read(void *b, u32 block)
+// TODO: Fix strange print workaround
+void *ide_read(void *b, u32 block)
{
int sector_per_block = BLOCK_SIZE / SECTOR_SIZE; // 2
int sector = block * sector_per_block;
+ print("");
ide_wait(0);
+ print("");
outb(IDE_IO | IDE_SECTOR_COUNT, sector_per_block); // Number of sectors
+ print("");
outb(IDE_IO | IDE_LOW, LBA_LOW(sector));
+ print("");
outb(IDE_IO | IDE_MID, LBA_MID(sector));
+ print("");
outb(IDE_IO | IDE_HIGH, LBA_HIGH(sector));
+ print("");
// Slave/Master << 4 and last 4 bits
+ print("");
outb(IDE_IO | IDE_HEAD, 0xE0 | (1 << 4) | LBA_LAST(sector));
+ print("");
outb(IDE_IO | IDE_CMD, IDE_CMD_READ);
+ print("");
ide_wait(0);
+ print("");
// Read-only
+ print("");
insl(IDE_IO, b, BLOCK_SIZE / 4);
+ print("");
return b;
}
diff --git a/kernel/drivers/net.c b/kernel/drivers/net.c
new file mode 100644
index 0000000..dfc3cd5
--- /dev/null
+++ b/kernel/drivers/net.c
@@ -0,0 +1,95 @@
+// MIT License, Copyright (c) 2020 Marvin Borner
+
+#include <cpu.h>
+#include <def.h>
+#include <interrupts.h>
+#include <mem.h>
+#include <net.h>
+#include <pci.h>
+#include <print.h>
+
+int rtl_irq = 0;
+u8 mac[6];
+u8 *rtl_rx_buffer;
+u32 rtl_device_pci = 0;
+u32 rtl_iobase = 0;
+
+void rtl8139_find(u32 device, u16 vendor_id, u16 device_id, void *extra)
+{
+ if ((vendor_id == 0x10ec) && (device_id == 0x8139)) {
+ *((u32 *)extra) = device;
+ }
+}
+
+void rtl8139_irq_handler()
+{
+ print("RTL INT!\n");
+ u16 status = inw((u16)(rtl_iobase + 0x3E));
+ if (!status)
+ return;
+ outw((u16)(rtl_iobase + 0x3E), status);
+
+ if (status & 0x01 || status & 0x02) {
+ print("RECEIVE\n");
+ /* while ((inw((u16)(rtl_iobase + 0x37)) & 0x01) == 0) { */
+ // RECEIVE
+ /* } */
+ }
+}
+
+void rtl8139_init()
+{
+ if (!rtl_device_pci)
+ return;
+
+ u16 command_reg = (u16)pci_read_field(rtl_device_pci, PCI_COMMAND, 4);
+ if ((command_reg & (1 << 2)) == 0) {
+ command_reg |= (1 << 2);
+ pci_write_field(rtl_device_pci, PCI_COMMAND, command_reg);
+ }
+
+ rtl_irq = pci_get_interrupt(rtl_device_pci);
+ irq_install_handler(rtl_irq, rtl8139_irq_handler);
+
+ u32 rtl_bar0 = pci_read_field(rtl_device_pci, PCI_BAR0, 4);
+ rtl_iobase = 0;
+
+ if (rtl_bar0 & 0x00000001)
+ rtl_iobase = rtl_bar0 & 0xFFFFFFFC;
+
+ // Get mac address
+ for (int i = 0; i < 6; ++i)
+ mac[i] = inb((u16)(rtl_iobase + 0x00 + i));
+ printf("Mac address: %x:%x:%x:%x:%x:%x\n", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
+
+ // Activate
+ outb((u16)(rtl_iobase + 0x52), 0x0);
+
+ // Reset
+ outb((u16)(rtl_iobase + 0x37), 0x10);
+ while ((inb((u16)(rtl_iobase + 0x37)) & 0x10) != 0)
+ ;
+
+ // Set receive buffer
+ rtl_rx_buffer = (u8 *)malloc(8192 + 16);
+ outl((u16)(rtl_iobase + 0x30), (u32)rtl_rx_buffer);
+
+ // Enable ISR
+ outw((u16)(rtl_iobase + 0x3C), 0x0005);
+
+ // Accept packets
+ outl((u16)(rtl_iobase + 0x44), 0xf | (1 << 7));
+
+ // Enable receive and transmitter
+ outb((u16)(rtl_iobase + 0x37), 0x0C);
+}
+
+void net_install()
+{
+ pci_scan(&rtl8139_find, -1, &rtl_device_pci);
+
+ if (rtl_device_pci)
+ print("Found rtl8139 card\n");
+
+ rtl8139_init();
+}