1 //
2 // Copyright (c) 2021 Travis Geiselbrecht
3 //
4 // Use of this source code is governed by a MIT-style
5 // license that can be found in the LICENSE file or at
6 // https://opensource.org/licenses/MIT
7
8 #pragma once
9
10 #include <stdint.h>
11 #include <stdio.h>
12
13 // from 8254x Family SDM Table 13-2
14 enum class e1000_reg {
15 // general
16 CTRL = 0x0,
17 STATUS = 0x8,
18 EECD = 0x10,
19 EERD = 0x14,
20 CTL_EXT = 0x18,
21 MDIC = 0x20,
22 FACL = 0x28,
23 FACH = 0x2c,
24 FCT = 0x30,
25 VET = 0x38,
26 FCTTV = 0x170,
27 TXCW = 0x178,
28 RXCW = 0x180,
29 LEDCTL = 0xe00,
30
31 // DMA
32 DMA = 0x1000,
33
34 // interrupt
35 ICR = 0xc0,
36 ITR = 0xc4,
37 IMS = 0xd0,
38 IMC = 0xd8,
39 IAM = 0xe0,
40 EITR0 = 0x1680, // e1000e only (i210)+
41 EITR1 = 0x1684,
42 EITR2 = 0x1688,
43 EITR3 = 0x168c,
44 EITR4 = 0x1690,
45
46 // receive
47 RCTL = 0x100,
48 FCRTL = 0x2160,
49 FCRTH = 0x2168,
50 RDBAL = 0x2800,
51 RDBAH = 0x2804,
52 RDLEN = 0x2808,
53 RDH = 0x2810,
54 RDT = 0x2818,
55 RDTR = 0x2820,
56 RADV = 0x282c,
57 RSRPD = 0x2c00,
58
59 // transmit
60 TCTL = 0x400,
61 TIPG = 0x410,
62 AIFS = 0x458,
63 TDBAL = 0x3800,
64 TDBAH = 0x3804,
65 TDLEN = 0x3808,
66 TDH = 0x3810,
67 TDT = 0x3818,
68 TIDV = 0x3820,
69
70 // tx dma
71 TXDMAC = 0x3000,
72 TXDCTL = 0x3828,
73 TADV = 0x382c,
74 TSPMT = 0x3830,
75
76 // rx dma
77 RXDCTL = 0x2828,
78 RXCSUM = 0x5000,
79 };
80
81 // receive descriptor
82 struct rdesc {
83 uint64_t addr;
84 uint16_t length;
85 uint16_t checksum;
86 uint8_t status;
87 uint8_t errors;
88 uint16_t special;
89
dumprdesc90 void dump() {
91 printf("rdsec %p: addr %#llx len %hu cksum %#hx stat %#hhx err %#hhx spec %#hx\n",
92 this, addr, length, checksum, status, errors, special);
93 }
94
95 };
96 static_assert(sizeof(rdesc) == 16, "");
97
98 // transmit descriptor (legacy)
99 struct tdesc {
100 uint64_t addr;
101 uint16_t length;
102 uint8_t cso;
103 uint8_t cmd;
104 uint8_t sta_rsv;
105 uint8_t css;
106 uint16_t special;
107
dumptdesc108 void dump() {
109 printf("tdsec %p: addr %#llx len %hu cso %#hhx cmd %#hhx sta_rsv %#hhx css %#hhx spec %#hx\n",
110 this, addr, length, cso, cmd, sta_rsv, css, special);
111 }
112 };
113 static_assert(sizeof(tdesc) == 16, "");
114
115 // efficient copy for rx/tx descriptors out/into uncached memory
116 template <typename T>
copy(T * _dst,const T * _src)117 inline void copy(T *_dst, const T *_src) {
118 // only allow this for structs that are precisely 16 bytes long
119 static_assert(sizeof(T) == 16, "");
120
121 // treat as two 8 byte copies
122 uint64_t *dst = (uint64_t *)_dst;
123 const uint64_t *src = (uint64_t *)_src;
124
125 dst[0] = src[0];
126 dst[1] = src[1];
127 }
128
129