Skip to content

Commit 43ee3d2

Browse files
committed
First partial network packet
Implement rtl tx
1 parent a613011 commit 43ee3d2

File tree

9 files changed

+240
-4
lines changed

9 files changed

+240
-4
lines changed

src/kernel/arch/riscv64/include.mak

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,11 @@ $(call defcleanable, \
2424
src/kernel/kernel.elf \
2525
src/kernel/kernel.sym)
2626

27+
bgdb: src/kernel/kernel.sym
28+
gdb-multiarch src/kernel/kernel.sym \
29+
-ex "set substitute-path / $(srcdir)/" \
30+
-ex "target remote :1234"
31+
2732
# Targets for booting and debugging the kernel.
2833
gdb: src/kernel/kernel.sym
2934
gdb-multiarch src/kernel/kernel.sym \
@@ -48,6 +53,9 @@ qemu: src/kernel/kernel.elf
4853
--cpu rva22s64 \
4954
--smp 1 \
5055
-m 1G \
56+
-device rtl8139,netdev=net1,bus=pcie.0 \
57+
-netdev user,id=net1,net=192.168.0.0/24 \
58+
-object filter-dump,id=net1,netdev=net1,file=net_dump.pcap \
5159
-nographic \
5260
-kernel src/kernel/kernel.elf \
5361
$(QEMUFLAGS)
@@ -57,8 +65,12 @@ qemu-debug: src/kernel/kernel.elf
5765
--cpu rva22s64 \
5866
--smp 1 \
5967
-m 1G \
68+
-device rtl8139,netdev=net1,bus=pcie.0 \
69+
-netdev user,id=net1,net=192.168.0.0/24 \
70+
-object filter-dump,id=net1,netdev=net1,file=net_dump.pcap \
6071
-nographic \
6172
-kernel src/kernel/kernel.elf \
73+
-d guest_errors \
6274
-s -S \
6375
$(QEMUFLAGS)
6476
.PHONY: gdb gdb_bootstub qemu qemu-debug

src/kernel/arch/riscv64/paging.c

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,7 @@
44
#include <panic.h>
55
#include <physical.h>
66

7-
/**
8-
* An Sv39 page table entry.
9-
*/
7+
108
struct pte {
119
bool valid : 1;
1210
bool readable : 1;
@@ -21,6 +19,10 @@ struct pte {
2119
u64 rsrvd0 : 10;
2220
};
2321

22+
enum walk_flags {
23+
WALK_ALLOC = (1 << 0),
24+
};
25+
2426
static u64 bits_of_pte(struct pte pte) {
2527
union {
2628
u64 bits;
@@ -162,6 +164,20 @@ paddr walk(uaddr vaddr, enum walk_flags flags) {
162164
return paddr_offset(pgtbl0, ppn0 << 3);
163165
}
164166

167+
u64 walkaddr(uaddr vaddr) {
168+
paddr pte_addr;
169+
struct pte pte;
170+
u64 offset = vaddr & 0xfff;
171+
u64 mask = 0xfff;
172+
mask = ~mask;
173+
vaddr &= mask;
174+
175+
pte_addr = walk(vaddr, 0);
176+
177+
pte = pte_of_bits(physical_read_u64le(pte_addr));
178+
return (pte.ppn << 12) + offset;
179+
}
180+
165181
bool _mm_map(uaddr va, paddr pa, enum page_permissions perms) {
166182
assert((va & 0xfff) == 0, "va={uaddr}", va);
167183
assert(!pa.offset, "pa={paddr}", pa);

src/kernel/drivers/rtl8139.c

Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
#include <arch/riscv64/insns.h>
2+
3+
#include <drivers/rtl8139.h>
4+
5+
#include <mm/paging.h>
6+
#include <physical.h>
7+
#include <print.h>
8+
9+
#define READ_U8(addr, off) physical_read_u8(paddr_of_bits(addr + off))
10+
#define WRITE_U8(addr, off, value) physical_write_u8(paddr_of_bits(addr + off), value)
11+
12+
#define READ_U16(addr, off) physical_read_u16le(paddr_of_bits(addr + off))
13+
#define WRITE_U16(addr, off, value) physical_write_u16le(paddr_of_bits(addr + off), value)
14+
15+
#define READ_U32(addr, off) physical_read_u32le(paddr_of_bits(addr + off))
16+
#define WRITE_U32(addr, off, value) physical_write_u32le(paddr_of_bits(addr + off), value)
17+
18+
#define READ_REG(reg) READ_U8(g_regs_addr, reg)
19+
#define WRITE_REG(reg, value) WRITE_U8(g_regs_addr, reg, value)
20+
21+
#define READ_REG_32(reg) READ_U32(g_regs_addr, reg)
22+
#define WRITE_REG_32(reg, value) WRITE_U32(g_regs_addr, reg, value)
23+
24+
#define REG_TSADn(N) (0x20 + N * 4)
25+
#define REG_TSDn(N) (0x10 + N * 4)
26+
27+
enum RTL8139_REGS {
28+
REG_COM = 0x37,
29+
REG_TCR = 0x40,
30+
REG_CONFIG1 = 0x52
31+
};
32+
33+
enum RTL8139_CONST {
34+
TSD_TOK = (1 << 15),
35+
TSD_OWN = (1 << 13),
36+
37+
COM_RST = (1 << 4),
38+
COM_RE = (1 << 3),
39+
COM_TE = (1 << 2)
40+
};
41+
42+
43+
#define REG_IDR0 0x0
44+
#define REG_IDR4 0x4
45+
46+
47+
#define TX_BUFF_SIZE 0x1700
48+
49+
u8 rtl8139_tbuff[4][TX_BUFF_SIZE] __attribute__((aligned(256)));
50+
51+
u8 mac_addr[6];
52+
53+
u64 g_regs_addr;
54+
u64 g_cur_buf = 0;
55+
56+
57+
bool rtl8139_send_packet(u8 *buffer, u32 len) {
58+
u32 phys_buffer = (u32) walkaddr((uaddr) (&rtl8139_tbuff[0]));
59+
u64 i;
60+
61+
for (i=0; i<len; ++i) {
62+
rtl8139_tbuff[0][i] = buffer[i];
63+
}
64+
65+
if ((READ_REG_32(REG_TSDn(g_cur_buf)) & TSD_OWN) == 0) {
66+
return false;
67+
}
68+
69+
sfence_vma();
70+
WRITE_REG_32(REG_TSADn(g_cur_buf), phys_buffer);
71+
WRITE_REG_32(REG_TSDn(g_cur_buf), len);
72+
73+
++g_cur_buf;
74+
return true;
75+
}
76+
77+
bool eth_send_packet(u8 *buffer, u32 len) {
78+
u8 buf[0x100];
79+
u64 i;
80+
81+
for (i=0; i<6; ++i) {
82+
buf[i] = 0xff;
83+
buf[i + 6] = mac_addr[i];
84+
}
85+
buf[12] = 0x08;
86+
buf[13] = 0x00;
87+
88+
for (i=0; i<len; ++i) {
89+
buf[i + 14] = buffer[i];
90+
}
91+
for (i=len; i<64; ++i) {
92+
buf[i + 14] = 0;
93+
}
94+
if (len < 64) len = 64;
95+
96+
return rtl8139_send_packet(buf, len + 13);
97+
}
98+
99+
100+
void read_mac(u8 * mac) {
101+
u8 i;
102+
103+
for (i=0; i<6; ++i)
104+
mac[i] = READ_REG(i);
105+
}
106+
107+
108+
void rtl8139_test() {
109+
eth_send_packet((u8*) "yellow submarine", 16);
110+
111+
assert(READ_REG_32(REG_TSADn(0)) != 0);
112+
assert((READ_REG_32(REG_TSDn(0)) & TSD_TOK) != 0);
113+
}
114+
115+
116+
void rtl8139_init(u64 pci_device) {
117+
print("initializing rtl8139");
118+
119+
u32 reg_addr = 0x40000000;
120+
g_regs_addr = reg_addr;
121+
122+
/* TODO: Maybe move PCI init to pci.c? */
123+
124+
/* Setup BAR for MMIO - we just pick a nice number for now */
125+
WRITE_U32(pci_device,0x14,reg_addr);
126+
127+
/* Enable memory mapped regs */
128+
u8 cmd = READ_U8(pci_device, 0x4);
129+
WRITE_U8(pci_device,0x4,cmd | 0x6);
130+
131+
WRITE_REG(REG_CONFIG1, 0);
132+
133+
WRITE_REG(REG_COM, COM_RST);
134+
while (READ_REG(REG_COM) & COM_RST) ;
135+
WRITE_REG(REG_COM, COM_RE | COM_TE);
136+
137+
read_mac(mac_addr);
138+
rtl8139_test();
139+
}

src/kernel/include.mak

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,9 @@ kernel-cflags += -fdata-sections -ffunction-sections
1414
kernel-ldflags += -Wl,--gc-sections
1515
kernel-dir = src/kernel
1616
kernel-objs-asm =
17-
kernel-objs-c = devicetree main panic print random selftest swar_test symbolicate
17+
kernel-objs-c = devicetree main panic print random selftest swar_test symbolicate pci
1818
kernel-objs-c += builtins/bzero builtins/explicit_bzero builtins/memcpy builtins/memcmp builtins/memset builtins/strlen
1919
kernel-objs-c += crypto/subtle/rfc7539 crypto/subtle/rfc7693
2020
kernel-objs-c += mm/alloc mm/physical_alloc mm/virtual_alloc
21+
kernel-objs-c += drivers/rtl8139
2122
include $(srcdir)/src/kernel/arch/$(arch)/include.mak
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
#ifndef UKO_OS_KERNEL__RTL8139_H
2+
#define UKO_OS_KERNEL__RTL8139_H 1
3+
4+
#include <types.h>
5+
6+
void rtl8139_init(u64 pci_device);
7+
void rtl8139_test();
8+
bool eth_send_packet(u8 *buffer, u32 len);
9+
10+
#endif

src/kernel/include/mm/paging.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,4 +59,9 @@ enum page_permissions : u8 {
5959
*/
6060
bool _mm_map(uaddr va, paddr pa, enum page_permissions perms);
6161

62+
u64 walkaddr(uaddr vaddr);
63+
64+
65+
66+
6267
#endif // UKO_OS_KERNEL__MM_PAGING_H

src/kernel/include/pci.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
#ifndef UKO_OS_KERNEL__PCI_H
2+
#define UKO_OS_KERNEL__PCI_H 1
3+
4+
#include <types.h>
5+
6+
7+
void pci_enumerate();
8+
9+
10+
#endif

src/kernel/main.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,10 @@
55
#include <panic.h>
66
#include <print.h>
77
#include <random.h>
8+
#include <pci.h>
89
#include <selftest.h>
910
#include <symbolicate.h>
11+
#include <arch/riscv64/insns.h>
1012

1113
[[noreturn]]
1214
void main(u64 hart_id, paddr devicetree_start, paddr kernel_start,
@@ -21,6 +23,9 @@ void main(u64 hart_id, paddr devicetree_start, paddr kernel_start,
2123
devicetree_init(devicetree_start);
2224
devicetree_mm_init(kernel_start, kernel_end, &free_va_start, &free_va_end);
2325
mm_init_virtual(free_va_start, free_va_end);
26+
pci_enumerate();
27+
28+
wfi();
2429

2530
uptr a = mm_va_alloc(mm_kernel_virtual_buddy, 2 * 1024 * 1024);
2631
uptr b = mm_va_alloc(mm_kernel_virtual_buddy, 4096);

src/kernel/pci.c

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
#include <pci.h>
2+
#include <print.h>
3+
#include <mm/paging.h>
4+
#include <physical.h>
5+
6+
#include <drivers/rtl8139.h>
7+
8+
const u64 regs = 0x123L;
9+
10+
const u64 pci_config = 0x30000000L;
11+
const u32 rtl8139_vender = 0x123;
12+
13+
paddr mad(u64 addr) {
14+
paddr *x;
15+
x = (paddr*) (&addr);
16+
return *x;
17+
}
18+
19+
20+
void pci_enumerate() {
21+
22+
for (u64 dev=0; dev<32; ++dev) {
23+
u64 bus = 0;
24+
u64 func = 0;
25+
u64 offset = 0;
26+
offset = (bus << 16) | (dev << 11) | (func << 8) | (offset);
27+
u64 device = (pci_config + offset);
28+
29+
u16 vid = physical_read_u16le(mad(device));
30+
u16 did = physical_read_u16le(mad(device+2));
31+
32+
if (vid == 0x10ec && did == 0x8139){ //0xedf11efd) {
33+
rtl8139_init(device); //device_pci_cfg);
34+
} else if (did != 0xffff && vid != 0xffff && vid) {
35+
print("unknown pci device: {u16:x} vender: {u16:x}", did, vid);
36+
}
37+
}
38+
}

0 commit comments

Comments
 (0)