summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile6
-rw-r--r--cpu/idt.c2
-rw-r--r--cpu/io.h15
-rw-r--r--cpu/io.s20
-rw-r--r--drivers/pci.c45
-rw-r--r--drivers/pci.h14
-rw-r--r--drivers/rtl8139.c50
-rw-r--r--drivers/rtl8139.h1
8 files changed, 144 insertions, 9 deletions
diff --git a/Makefile b/Makefile
index 1a77824..7eecee0 100644
--- a/Makefile
+++ b/Makefile
@@ -1,6 +1,6 @@
CC="./sysroot/bin/i686-sb-gcc"
AS="./sysroot/bin/i686-sb-as"
-OBJ = arch/i386/boot.o init/kernel.o cpu/gdt.o cpu/reload_gdt.o cpu/idt.o cpu/io.o libc/stdio/print.o drivers/keyboard.o log.o drivers/pit.o libc/string/memcpy.o libc/string/strlen.o libc/string/memcmp.o drivers/ata.o libc/string/memset.o cpu/syscall.o read_eip.o libc/exit/assert.o process.o cpu/int_syscall.o libc/string/strcpy.o arch/i386/mmu.o kmalloc.o fs/ext2.o fs/vfs.o fs/devfs.o cpu/spinlock.o random.o libc/string/strcmp.o crypto/ChaCha20/chacha20.o crypto/SHA1/sha1.o fs/tmpfs.o libc/string/isequal.o drivers/pst.o halts.o scalls/ppoll.o scalls/ftruncate.o kubsan.o scalls/mmap.o drivers/serial.o scalls/accept.o scalls/bind.o scalls/socket.o socket.o poll.o fs/fifo.o hashmap/hashmap.o fs/shm.o scalls/shm.o elf.o ksbrk.o sched/scheduler.o scalls/stat.o libc/string/copy.o libc/string/strncpy.o drivers/mouse.o libc/string/strlcpy.o libc/string/strcat.o drivers/vbe.o scalls/msleep.o scalls/uptime.o scalls/mkdir.o
+OBJ = arch/i386/boot.o init/kernel.o cpu/gdt.o cpu/reload_gdt.o cpu/idt.o cpu/io.o libc/stdio/print.o drivers/keyboard.o log.o drivers/pit.o libc/string/memcpy.o libc/string/strlen.o libc/string/memcmp.o drivers/ata.o libc/string/memset.o cpu/syscall.o read_eip.o libc/exit/assert.o process.o cpu/int_syscall.o libc/string/strcpy.o arch/i386/mmu.o kmalloc.o fs/ext2.o fs/vfs.o fs/devfs.o cpu/spinlock.o random.o libc/string/strcmp.o crypto/ChaCha20/chacha20.o crypto/SHA1/sha1.o fs/tmpfs.o libc/string/isequal.o drivers/pst.o halts.o scalls/ppoll.o scalls/ftruncate.o kubsan.o scalls/mmap.o drivers/serial.o scalls/accept.o scalls/bind.o scalls/socket.o socket.o poll.o fs/fifo.o hashmap/hashmap.o fs/shm.o scalls/shm.o elf.o ksbrk.o sched/scheduler.o scalls/stat.o libc/string/copy.o libc/string/strncpy.o drivers/mouse.o libc/string/strlcpy.o libc/string/strcat.o drivers/vbe.o scalls/msleep.o scalls/uptime.o scalls/mkdir.o drivers/pci.o drivers/rtl8139.o
CFLAGS = -O2 -fsanitize=vla-bound,shift-exponent,pointer-overflow,shift,signed-integer-overflow,bounds -ggdb -ffreestanding -Wall -Werror -mgeneral-regs-only -Wimplicit-fallthrough -I./libc/include/ -I.
INCLUDE=-I./includes/ -I./libc/include/
@@ -20,10 +20,10 @@ debug:
gdb -x .gdbinit
nk:
- qemu-system-i386 -d int -no-reboot -no-shutdown -serial file:./serial.log -hda ext2.img -m 1G -cdrom myos.iso -s
+ qemu-system-i386 -netdev tap,ifname=tap0,id=network0,script=no,downscript=no -device rtl8139,netdev=network0 -d int -no-reboot -no-shutdown -serial file:./serial.log -hda ext2.img -m 1G -cdrom myos.iso -s
run:
- qemu-system-i386 -enable-kvm -d int -no-reboot -no-shutdown -chardev stdio,id=char0,logfile=serial.log,signal=off -serial chardev:char0 -hda ext2.img -m 1G -cdrom myos.iso -s
+ qemu-system-i386 -enable-kvm -netdev tap,ifname=tap0,id=network0,script=no,downscript=no -device rtl8139,netdev=network0 -d int -no-reboot -no-shutdown -chardev stdio,id=char0,logfile=serial.log,signal=off -serial chardev:char0 -hda ext2.img -m 1G -cdrom myos.iso -s
myos.iso: myos.bin
cp myos.bin isodir/boot
diff --git a/cpu/idt.c b/cpu/idt.c
index 832162c..60ab441 100644
--- a/cpu/idt.c
+++ b/cpu/idt.c
@@ -108,6 +108,7 @@ __attribute__((interrupt)) void general_protection_fault(registers_t *regs) {
__attribute__((interrupt)) void double_fault(registers_t *regs) {
(void)regs;
klog("DOUBLE FAULT, THIS IS REALLY BAD", LOG_ERROR);
+ asm("cli");
asm("hlt");
for (;;)
;
@@ -258,6 +259,7 @@ void idt_init(void) {
// IRQ_set_mask(0xc);
IRQ_set_mask(0xe);
IRQ_clear_mask(2);
+ IRQ_set_mask(0xB);
idtr.interrupt_table = (struct IDT_Descriptor **)&IDT_Entry;
idtr.size = (sizeof(struct IDT_Descriptor) * IDT_MAX_ENTRY) - 1;
diff --git a/cpu/io.h b/cpu/io.h
index 9c33b66..5e28e86 100644
--- a/cpu/io.h
+++ b/cpu/io.h
@@ -1,11 +1,14 @@
#include <stdint.h>
-__attribute__((no_caller_saved_registers)) extern void outsw(uint16_t,
- uint32_t);
-__attribute__((no_caller_saved_registers)) extern void outb(uint16_t, uint16_t);
-__attribute__((no_caller_saved_registers)) extern uint16_t inb(uint16_t);
-__attribute__((no_caller_saved_registers)) extern void
-rep_outsw(uint16_t count, uint16_t port, volatile void *addy);
+extern void outsw(uint16_t, uint32_t);
+extern void outb(uint16_t, uint8_t);
+extern void outw(uint16_t, uint16_t);
+extern void outl(uint16_t, uint32_t);
+
+extern uint32_t inl(uint16_t);
+extern uint16_t inb(uint16_t);
+
+extern void rep_outsw(uint16_t count, uint16_t port, volatile void *addy);
__attribute__((no_caller_saved_registers)) extern void
rep_insw(uint16_t count, uint16_t port, volatile void *addy);
extern void jump_usermode(void (*address)(), uint32_t stack_pointer);
diff --git a/cpu/io.s b/cpu/io.s
index fe370a5..3c409de 100644
--- a/cpu/io.s
+++ b/cpu/io.s
@@ -1,7 +1,10 @@
.intel_syntax noprefix
.global outsw
.global outb
+.global outw
+.global outl
.global inb
+.global inl
.global rep_outsw
.global rep_insw
.global flush_tss
@@ -20,12 +23,29 @@ outsw:
pop ebp
ret
+outl:
+ mov eax, [esp + 8]
+ mov dx, [esp + 4]
+ out dx, eax
+ ret
+
outb:
mov al, [esp + 8]
mov dx, [esp + 4]
out dx, al
ret
+outw:
+ mov eax, [esp + 8]
+ mov dx, [esp + 4]
+ out dx, eax
+ ret
+
+inl:
+ mov dx, [esp + 4]
+ in eax, dx
+ ret
+
inb:
mov dx, [esp + 4]
in al, dx
diff --git a/drivers/pci.c b/drivers/pci.c
new file mode 100644
index 0000000..a71cc9a
--- /dev/null
+++ b/drivers/pci.c
@@ -0,0 +1,45 @@
+#include <cpu/io.h>
+#include <drivers/pci.h>
+#include <stdio.h>
+
+#define CONFIG_ADDRESS 0xCF8
+#define CONFIG_DATA 0xCFC
+
+uint32_t pci_config_read32(const struct PCI_DEVICE *device, uint8_t func,
+ uint8_t offset) {
+ uint32_t address;
+ uint32_t lbus = (uint32_t)device->bus;
+ uint32_t lslot = (uint32_t)device->slot;
+ uint32_t lfunc = (uint32_t)func;
+
+ // Create configuration address as per Figure 1
+ address = (uint32_t)((lbus << 16) | (lslot << 11) | (lfunc << 8) |
+ (offset & 0xFC) | ((uint32_t)0x80000000));
+
+ // Write out the address
+ outl(CONFIG_ADDRESS, address);
+ return inl(CONFIG_DATA);
+}
+
+int pci_populate_device_struct(uint16_t vendor, uint16_t device,
+ struct PCI_DEVICE *pci_device) {
+ pci_device->vendor = vendor;
+ pci_device->device = device;
+
+ for (int bus = 0; bus < 256; bus++) {
+ for (int slot = 0; slot < 256; slot++) {
+ struct PCI_DEVICE tmp;
+ tmp.bus = bus;
+ tmp.slot = slot;
+ uint32_t device_vendor = pci_config_read32(&tmp, 0, 0);
+ if (vendor != (device_vendor & 0xFFFF))
+ continue;
+ if (device != (device_vendor >> 16))
+ continue;
+ pci_device->bus = bus;
+ pci_device->slot = slot;
+ return 1;
+ }
+ }
+ return 0;
+}
diff --git a/drivers/pci.h b/drivers/pci.h
new file mode 100644
index 0000000..6a8bc1c
--- /dev/null
+++ b/drivers/pci.h
@@ -0,0 +1,14 @@
+#include <stdint.h>
+
+struct PCI_DEVICE {
+ uint16_t vendor;
+ uint16_t device;
+ uint8_t bus;
+ uint8_t slot;
+};
+
+uint32_t pci_config_read32(const struct PCI_DEVICE *device, uint8_t func,
+ uint8_t offset);
+
+int pci_populate_device_struct(uint16_t vendor, uint16_t device,
+ struct PCI_DEVICE *pci_device);
diff --git a/drivers/rtl8139.c b/drivers/rtl8139.c
new file mode 100644
index 0000000..44212e0
--- /dev/null
+++ b/drivers/rtl8139.c
@@ -0,0 +1,50 @@
+#include <assert.h>
+#include <cpu/io.h>
+#include <drivers/pci.h>
+#include <drivers/rtl8139.h>
+#include <mmu.h>
+
+#define RBSTART 0x30
+#define CMD 0x37
+#define IMR 0x3C
+
+struct PCI_DEVICE rtl8139;
+uint8_t device_buffer[8192 + 16];
+
+void rtl8139_init(void) {
+ if (!pci_populate_device_struct(0x10EC, 0x8139, &rtl8139)) {
+ kprintf("RTL8139 not found :(\n");
+ return;
+ }
+ kprintf("RTL8139 found at bus: %x slot: %x\n", rtl8139.bus, rtl8139.slot);
+
+ uint8_t header_type = (pci_config_read32(&rtl8139, 0, 0xC) >> 16) & 0xFF;
+ assert(0 == header_type);
+
+ uint32_t base_address = pci_config_read32(&rtl8139, 0, 0x10);
+ uint8_t interrupt_line = pci_config_read32(&rtl8139, 0, 0x3C);
+ kprintf("interrupt_line: %x\n", interrupt_line);
+
+ // Turning on the device
+ outb(base_address + 0x52, 0x0);
+
+ // Reset the device and clear the RX and TX buffers
+ outb(base_address + CMD, 0x10);
+ for (; 0 != (inb(base_address + CMD) & 0x10);)
+ ;
+
+ // Setupt the recieve buffer
+ uint32_t rx_buffer = (uint32_t)virtual_to_physical(device_buffer, NULL);
+ outl(base_address + RBSTART, rx_buffer);
+
+ // Set IMR + ISR
+ outw(base_address + IMR, 0x0005); // Sets the TOK and ROK bits high
+
+ // Configure the recieve buffer
+ outl(base_address + 0x44,
+ 0xf | (1 << 7)); // (1 << 7) is the WRAP bit, 0xf is AB+AM+APM+AAP
+
+ // Enable recieve and transmitter
+ outb(base_address + 0x37, 0x0C); // Sets the RE and TE bits high
+ asm("sti");
+}
diff --git a/drivers/rtl8139.h b/drivers/rtl8139.h
new file mode 100644
index 0000000..1f3d84e
--- /dev/null
+++ b/drivers/rtl8139.h
@@ -0,0 +1 @@
+void rtl8139_init(void);