Skip to content

Commit 89c6f78

Browse files
committed
modules/rtl8139: start work
1 parent 6c736e1 commit 89c6f78

File tree

7 files changed

+112
-18
lines changed

7 files changed

+112
-18
lines changed

Makefile

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ ifeq ($(ARCH),x86_64)
1010
ASFLAGS := -f elf64 -g -F dwarf
1111
CCFLAGS := -O2 -m64 -std=gnu11 -g -ffreestanding -Wall -Wextra -Wshadow -Wuninitialized -Wstrict-aliasing -nostdlib -Ibase/usr/include/ -Ilib/ -fno-stack-protector -Wno-unused-parameter -fno-stack-check -fno-lto -mno-red-zone -mno-80387 -mno-sse -mno-sse2 -fno-strict-aliasing -fno-optimize-sibling-calls #-fsanitize=undefined
1212
LDFLAGS := -m elf_x86_64 -Tkernel/arch/x86_64/linker.ld -z noexecstack
13-
QEMUFLAGS := -m 256M -serial stdio -cdrom bin/$(IMAGE_NAME).iso -boot d -M q35 -drive file=bin/$(IMAGE_NAME).hdd,format=raw,if=none,id=hdd0 -device ahci,id=ahci -device ide-hd,drive=hdd0,bus=ahci.0 -rtc base=localtime
13+
QEMUFLAGS := -m 256M -serial stdio -cdrom bin/$(IMAGE_NAME).iso -boot d -M q35 -drive file=bin/$(IMAGE_NAME).hdd,format=raw,if=none,id=hdd0 -device ahci,id=ahci -device ide-hd,drive=hdd0,bus=ahci.0 -rtc base=localtime -net nic,model=rtl8139 -net user
1414
else ifeq ($(ARCH),riscv64)
1515
AS := riscv64-elf-as
1616
CC := riscv64-elf-gcc
@@ -107,13 +107,11 @@ bin/$(IMAGE_NAME).hdd: $(shell find root -type f) $(shell find base -type f) $(s
107107
@mkdir -p root
108108
@rsync -a --no-times --no-o --no-g base/ bin/base/
109109
@rsync -a --no-times --no-o --no-g root/ bin/base/
110-
@genext2fs -d bin/base -b 524288 -L bentobox -N 10000 bin/root.hdd 2>&1 >/dev/null | grep -v copying | cat
110+
@genext2fs -d bin/base -b 1048576 -L bentobox -N 10000 bin/root.hdd 2>&1 >/dev/null | grep -v copying | cat
111111
@truncate -s 1000M bin/$(IMAGE_NAME).hdd
112112
@parted -s bin/$(IMAGE_NAME).hdd mklabel gpt
113-
@parted -s bin/$(IMAGE_NAME).hdd mkpart primary ext2 1MiB 500MiB
113+
@parted -s bin/$(IMAGE_NAME).hdd mkpart primary ext2 1MiB 100%
114114
@parted -s bin/$(IMAGE_NAME).hdd name 1 bentobox
115-
@parted -s bin/$(IMAGE_NAME).hdd mkpart primary 500MiB 100%
116-
@parted -s bin/$(IMAGE_NAME).hdd name 2 testarea
117115
@dd if=bin/root.hdd of=bin/$(IMAGE_NAME).hdd bs=1M seek=1 conv=notrunc,sparse status=none
118116
@rm bin/root.hdd
119117

base/usr/include/kernel/pci.h

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
#pragma once
22
#include <stdint.h>
33

4-
#define PCI_CONFIG_ADDRESS 0xCF8
5-
#define PCI_CONFIG_DATA 0xCFC
6-
7-
#define PCI_CAP_ID_MSI 0x05
4+
#define PCI_CONFIG_ADDRESS 0xCF8
5+
#define PCI_CONFIG_DATA 0xCFC
6+
#define PCI_CAP_ID_MSI 0x05
7+
#define PCI_IO_SPACE (1 << 1)
8+
#define PCI_BUS_MASTER (1 << 2)
9+
#define PCI_SERR_ENABLE (1 << 8)
810

911
struct pci_device {
1012
uint8_t bus;
@@ -16,8 +18,6 @@ struct pci_device {
1618
uint16_t device_id;
1719
};
1820

19-
//extern struct pci_device primary_bus[32];
20-
2121
void pci_scan(void);
2222
void pci_check_device(uint8_t bus, uint8_t device);
2323
void pci_check_bus(uint8_t bus);

boot/grub.cfg

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ menuentry "bentobox (AHCI mode)" {
2525
module2 /modules/ahci.ko
2626
module2 /modules/gpt.ko
2727
module2 /modules/ext2.ko
28+
module2 /modules/rtl8139.ko
2829
boot
2930
}
3031
menuentry "bentobox (serial TTY)" {
@@ -33,5 +34,6 @@ menuentry "bentobox (serial TTY)" {
3334
module2 /modules/ahci.ko
3435
module2 /modules/gpt.ko
3536
module2 /modules/ext2.ko
37+
module2 /modules/rtl8139.ko
3638
boot
3739
}

kernel/misc/pci.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,8 @@ int pci_find_capability(struct pci_device *dev, uint8_t cap_id) {
5151

5252
void pci_check_device(uint8_t bus, uint8_t device) {
5353
uint8_t function = 0;
54-
uint16_t vendor_id = pci_config_read_word(bus, device, 0, 0x02);
55-
uint16_t device_id = pci_config_read_word(bus, device, 0, 0x00);
54+
uint16_t vendor_id = pci_config_read_word(bus, device, 0, 0x00);
55+
uint16_t device_id = pci_config_read_word(bus, device, 0, 0x02);
5656
uint8_t class = (uint8_t)(pci_config_read_word(bus, device, function, 0x0A) >> 8);
5757
uint8_t subclass = (uint8_t)(pci_config_read_word(bus, device, function, 0x0A));
5858

@@ -89,8 +89,8 @@ void pci_check_bus(uint8_t bus) {
8989
void pci_check_function(uint8_t bus, uint8_t device, uint8_t function) {
9090
uint8_t class = (uint8_t)(pci_config_read_word(bus, device, function, 0x0A) >> 8);
9191
uint8_t subclass = (uint8_t)(pci_config_read_word(bus, device, function, 0x0A));
92-
uint16_t vendor_id = pci_config_read_word(bus, device, function, 0x02);
93-
uint16_t device_id = pci_config_read_word(bus, device, function, 0x00);
92+
uint16_t vendor_id = pci_config_read_word(bus, device, function, 0x00);
93+
uint16_t device_id = pci_config_read_word(bus, device, function, 0x02);
9494

9595
primary_bus[device][function].bus = 0;
9696
primary_bus[device][function].device = device;

kernel/misc/printf.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ int vsprintf(char *s, const char *fmt, va_list args) {
9595
parse_num(s, &ptr, is_long ? va_arg(args, long) : va_arg(args, int), 10, true, width, pad);
9696
break;
9797
case 'x':
98-
parse_hex(s, &ptr, is_long ? va_arg(args, uint64_t) : va_arg(args, uint32_t), 0);
98+
parse_hex(s, &ptr, is_long ? va_arg(args, uint64_t) : va_arg(args, uint32_t), width);
9999
break;
100100
case 'p':
101101
parse_hex(s, &ptr, va_arg(args, uint64_t), 16);

modules/ahci.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
#define SATA_SIG_SEMB 0xC33C0101 /* Enclosure management bridge */
1919
#define SATA_SIG_PM 0x96690101 /* Port multiplier */
2020

21-
#define GHC_AHCI_ENABLE (1u << 31) /* AHCI Enable */
21+
#define GHC_AHCI_ENABLE (1u << 31) /* AHCI Enable */
2222
#define GHC_MRSM (1 << 2) /* MSI Revert to Single Message */
2323
#define GHC_IE (1 << 1) /* Interrupt Enable */
2424
#define GHC_HR (1 << 0) /* HBA Reset */
@@ -405,7 +405,7 @@ int init() {
405405
}
406406

407407
uint32_t cmd = pci_read(ahci_dev->bus, ahci_dev->device, ahci_dev->function, 0x04);
408-
cmd |= (1 << 8) | (1 << 2) | (1 << 1);
408+
cmd |= PCI_SERR_ENABLE | PCI_BUS_MASTER | PCI_IO_SPACE;
409409
pci_write(ahci_dev->bus, ahci_dev->device, ahci_dev->function, 0x04, cmd);
410410

411411
uint32_t bar5 = pci_read(ahci_dev->bus, ahci_dev->device, ahci_dev->function, 0x24);

modules/rtl8139.c

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
#include <stddef.h>
2+
#include <kernel/arch/x86_64/lapic.h>
3+
#include <kernel/arch/x86_64/idt.h>
4+
#include <kernel/arch/x86_64/io.h>
5+
#include <kernel/module.h>
6+
#include <kernel/printf.h>
7+
#include <kernel/mmu.h>
8+
#include <kernel/pci.h>
9+
10+
#define MAC(x) (0x00 + x)
11+
#define RBSTART 0x30
12+
#define CMD 0x37
13+
#define IMR 0x3C
14+
#define TCR 0x44
15+
#define CONFIG_1 0x52
16+
17+
#define CR_RESET (1 << 4)
18+
#define CR_RE (1 << 2)
19+
#define CR_TE (1 << 3)
20+
#define CR_BUFE (1 << 5)
21+
#define CR_STA (1 << 6)
22+
#define CR_LOOPBACK (1 << 7)
23+
24+
#define ISR_ROK (1 << 0)
25+
#define ISR_TOK (1 << 2)
26+
#define ISR_RXERR (1 << 1)
27+
#define ISR_TXERR (1 << 3)
28+
#define ISR_RER (1 << 6)
29+
#define ISR_PUN (1 << 7)
30+
#define ISR_TER (1 << 8)
31+
#define ISR_RXOVW (1 << 9)
32+
#define ISR_CNT (1 << 10)
33+
34+
#define TCR_CRC_ENABLE (1 << 0)
35+
#define TCR_PAD_SHORT_FRAMES (1 << 1)
36+
#define TCR_COLLISION_TEST (1 << 2)
37+
#define TCR_AUTO_DEFER (1 << 3)
38+
#define TCR_LOOPBACK (1 << 7)
39+
40+
uint32_t ioaddr = 0;
41+
uint8_t mac[6] = {0};
42+
void *rx_buffer = NULL;
43+
44+
void rtl8139_irq_handler(struct registers *r) {
45+
dprintf(LOG_INFO, "rtl8139 irq\n");
46+
lapic_eoi();
47+
}
48+
49+
int init() {
50+
struct pci_device *rtl_dev = pci_get_device_from_vendor(0x10ec, 0x8139);
51+
if (!rtl_dev) {
52+
dprintf(LOG_ERR, "%s:%d: No RTL8139 NIC found!\n", __FILE__, __LINE__);
53+
return 1;
54+
}
55+
56+
pci_write(rtl_dev->bus, rtl_dev->device, rtl_dev->function, 0x04,
57+
pci_read(rtl_dev->bus, rtl_dev->device, rtl_dev->function, 0x04) | PCI_BUS_MASTER);
58+
59+
ioaddr = pci_read(rtl_dev->bus, rtl_dev->device, rtl_dev->function, 0x10) & 0xFFFFFFFC;
60+
61+
outb(ioaddr + CONFIG_1, 0x00);
62+
outb(ioaddr + CMD, 0x10);
63+
while (inb(ioaddr + CMD) & 0x10);
64+
rx_buffer = mmu_alloc(ALIGN_UP(8192 + 16 + 1500, PAGE_SIZE) / PAGE_SIZE);
65+
outl(ioaddr + RBSTART, (uint32_t)(uintptr_t)rx_buffer);
66+
outw(ioaddr + 0x3C, ISR_TOK | ISR_ROK);
67+
outl(ioaddr + TCR, TCR_CRC_ENABLE | TCR_PAD_SHORT_FRAMES | TCR_COLLISION_TEST | TCR_AUTO_DEFER | TCR_LOOPBACK);
68+
outb(ioaddr + CMD, CR_RE | CR_TE);
69+
70+
mac[0] = inb(ioaddr + MAC(0));
71+
mac[1] = inb(ioaddr + MAC(1));
72+
mac[2] = inb(ioaddr + MAC(2));
73+
mac[3] = inb(ioaddr + MAC(3));
74+
mac[4] = inb(ioaddr + MAC(4));
75+
mac[5] = inb(ioaddr + MAC(5));
76+
77+
dprintf(LOG_INFO, "%s:%d: MAC address: %02x:%02x:%02x:%02x:%02x:%02x\n", __FILE__, __LINE__, mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
78+
79+
uint8_t irq = pci_read(rtl_dev->bus, rtl_dev->device, rtl_dev->function, 0x3C) & 0xFF;
80+
dprintf(LOG_INFO, "%s:%d: registering handler for IRQ %u\n", __FILE__, __LINE__, irq);
81+
irq_register(irq, rtl8139_irq_handler);
82+
return 0;
83+
}
84+
85+
int fini() {
86+
dprintf(LOG_INFO, "%s:%d: Goodbye!\n", __FILE__, __LINE__);
87+
return 0;
88+
}
89+
90+
struct Module metadata = {
91+
.name = "RTL8139 driver",
92+
.init = init,
93+
.fini = fini
94+
};

0 commit comments

Comments
 (0)