aboutsummaryrefslogtreecommitdiff
path: root/kernel/drivers
diff options
context:
space:
mode:
authorMarvin Borner2020-09-21 22:00:40 +0200
committerMarvin Borner2020-09-21 22:00:40 +0200
commit0e9abba93578786e774525dfdf02c59194d3e1e5 (patch)
treee7df565030ebfc4d334ca142e005351ffd293cd6 /kernel/drivers
parent02d97dcb1ea14c963219f22aed24b297e8366d05 (diff)
Frustration
Diffstat (limited to 'kernel/drivers')
-rw-r--r--kernel/drivers/ide.c63
-rw-r--r--kernel/drivers/net.c122
2 files changed, 129 insertions, 56 deletions
diff --git a/kernel/drivers/ide.c b/kernel/drivers/ide.c
index eda18e9..c1c0227 100644
--- a/kernel/drivers/ide.c
+++ b/kernel/drivers/ide.c
@@ -5,51 +5,42 @@
#include <ide.h>
#include <print.h>
-int ide_wait(int check)
+int ide_stat()
{
- char r;
-
- // Wait while drive is busy. Once just ready is set, exit the loop
- while (((r = (char)inb(IDE_IO | IDE_CMD)) & (IDE_BUSY | IDE_READY)) != IDE_READY)
- ;
+ inb(IDE_IO + IDE_CMD);
+ inb(IDE_IO + IDE_CMD);
+ inb(IDE_IO + IDE_CMD);
+ inb(IDE_IO + IDE_CMD);
+ return inb(IDE_IO + IDE_CMD);
+}
- // Check for errors
- if (check && (r & (IDE_DRIVE_FAULT | IDE_ERROR)) != 0)
- return 0xF;
- return 0;
+void ide_wait()
+{
+ u8 stat;
+ do
+ stat = ide_stat();
+ while ((stat & IDE_BUSY) != 0);
}
-// TODO: Fix strange print workaround
+// TODO: Fix strange ide_read bugs
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("");
+ int sector_count = BLOCK_SIZE / SECTOR_SIZE; // 2
+ int sector = block * sector_count;
+
+ outb(IDE_IO + IDE_SECTOR_COUNT, sector_count); // Number of sectors
+
+ outb(IDE_IO + IDE_LOW, LBA_LOW(sector));
+ outb(IDE_IO + IDE_MID, LBA_MID(sector));
+ outb(IDE_IO + IDE_HIGH, LBA_HIGH(sector));
// 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("");
+ outb(IDE_IO + IDE_SELECT, 0xE0 | (1 << 4) | LBA_LAST(sector));
+
+ outb(IDE_IO + IDE_CMD, IDE_CMD_READ);
+
+ ide_wait();
insl(IDE_IO, b, BLOCK_SIZE / 4);
- print("");
return b;
}
diff --git a/kernel/drivers/net.c b/kernel/drivers/net.c
index 284b749..cd1a331 100644
--- a/kernel/drivers/net.c
+++ b/kernel/drivers/net.c
@@ -10,6 +10,69 @@
#include <pci.h>
#include <print.h>
+u16 flip_short(u16 short_int)
+{
+ u32 first_byte = *((u8 *)(&short_int));
+ u32 second_byte = *((u8 *)(&short_int) + 1);
+ return (first_byte << 8) | (second_byte);
+}
+
+u32 flip_long(u32 long_int)
+{
+ u32 first_byte = *((u8 *)(&long_int));
+ u32 second_byte = *((u8 *)(&long_int) + 1);
+ u32 third_byte = *((u8 *)(&long_int) + 2);
+ u32 fourth_byte = *((u8 *)(&long_int) + 3);
+ return (first_byte << 24) | (second_byte << 16) | (third_byte << 8) | (fourth_byte);
+}
+
+u8 flip_byte(u8 byte, int num_bits)
+{
+ u8 t = byte << (8 - num_bits);
+ return t | (byte >> num_bits);
+}
+
+u8 htonb(u8 byte, int num_bits)
+{
+ return flip_byte(byte, num_bits);
+}
+
+u8 ntohb(u8 byte, int num_bits)
+{
+ return flip_byte(byte, 8 - num_bits);
+}
+
+u16 htons(u16 hostshort)
+{
+ return flip_short(hostshort);
+}
+
+u32 htonl(u32 hostlong)
+{
+ return flip_long(hostlong);
+}
+
+u16 ntohs(u16 netshort)
+{
+ return flip_short(netshort);
+}
+
+u32 ntohl(u32 netlong)
+{
+ return flip_long(netlong);
+}
+
+void ethernet_handle_packet(struct ethernet_packet *packet)
+{
+ /* void *data = packet + sizeof(*packet); */
+ if (ntohs(packet->type) == ETHERNET_TYPE_ARP)
+ print("ARP PACKET\n");
+ else if (ntohs(packet->type) == ETHERNET_TYPE_IP)
+ print("IP PACKET\n");
+ else
+ printf("UNKNOWN PACKET %d\n", ntohs(packet->type));
+}
+
static int rtl_irq = 0;
static u8 mac[6];
static u8 *last_packet = NULL;
@@ -28,13 +91,13 @@ void rtl8139_find(u32 device, u16 vendor_id, u16 device_id, void *extra)
void rtl8139_irq_handler()
{
print("RTL INT!\n");
- u16 status = inw(rtl_iobase + 0x3E);
+ u16 status = inw(rtl_iobase + RTL_PORT_ISR);
if (!status)
return;
- outw(rtl_iobase + 0x3E, status);
+ outw(rtl_iobase + RTL_PORT_ISR, status);
if (status & 0x01 || status & 0x02) {
- while ((inb(rtl_iobase + 0x37) & 0x01) == 0) {
+ while ((inb(rtl_iobase + RTL_PORT_CMD) & 0x01) == 0) {
print("RECEIVE\n");
int offset = cur_rx % 0x2000;
@@ -60,11 +123,11 @@ void rtl8139_irq_handler()
memcpy(last_packet, buf_8, rx_size);
}
- /* rtl_enqueue(last_packet); */
+ ethernet_handle_packet((struct ethernet_packet *)last_packet);
}
cur_rx = (cur_rx + rx_size + 4 + 3) & ~3;
- outw(rtl_iobase + 0x3A, cur_rx - 16);
+ outw(rtl_iobase + RTL_PORT_RXPTR, cur_rx - 16);
}
}
}
@@ -84,6 +147,7 @@ void rtl8139_init()
irq_install_handler(rtl_irq, rtl8139_irq_handler);
u32 rtl_bar0 = pci_read_field(rtl_device_pci, PCI_BAR0, 4);
+ /* u32 rtl_bar1 = pci_read_field(rtl_device_pci, PCI_BAR1, 4); */
rtl_iobase = 0;
if (rtl_bar0 & 0x00000001)
@@ -91,30 +155,48 @@ void rtl8139_init()
// Get mac address
for (int i = 0; i < 6; ++i)
- mac[i] = inb((u16)(rtl_iobase + 0x00 + i));
+ mac[i] = inb(rtl_iobase + RTL_PORT_MAC + 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);
+ outb(rtl_iobase + RTL_PORT_CONFIG, 0x0);
// Reset
- outb((u16)(rtl_iobase + 0x37), 0x10);
- while ((inb((u16)(rtl_iobase + 0x37)) & 0x10) != 0)
+ outb((u16)(rtl_iobase + RTL_PORT_CMD), 0x10);
+ while ((inb(rtl_iobase + RTL_PORT_CMD) & 0x10) != 0)
;
// Set receive buffer
rtl_rx_buffer = (u8 *)malloc(0x3000);
- memset(rtl_rx_buffer, 0x00, 0x3000);
- 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);
+ memset(rtl_rx_buffer, 0, 0x3000);
+ outl(rtl_iobase + RTL_PORT_RBSTART, (u32)rtl_rx_buffer);
+
+ // Enable IRQs
+ outw(rtl_iobase + RTL_PORT_IMR, 0x8000 | /* PCI error */
+ 0x4000 | /* PCS timeout */
+ 0x40 | /* Rx FIFO over */
+ 0x20 | /* Rx underrun */
+ 0x10 | /* Rx overflow */
+ 0x08 | /* Tx error */
+ 0x04 | /* Tx okay */
+ 0x02 | /* Rx error */
+ 0x01 /* Rx okay */
+ );
+
+ // Configure transmit
+ outl(rtl_iobase + RTL_PORT_TCR, 0);
+
+ // Configure receive
+ outl(rtl_iobase + RTL_PORT_RCR, (0) | /* 8K receive */
+ 0x08 | /* broadcast */
+ 0x01 /* all physical */
+ );
+
+ // Enable receive and transmit
+ outb(rtl_iobase + RTL_PORT_CMD, 0x08 | 0x04);
+
+ // Reset rx statistics
+ outl(rtl_iobase + RTL_PORT_RXMISS, 0);
}
void net_install()