1use x86::registers::io;
8
9use crate::bdf::Bdf;
10
11const CONFIG_ADDRESS: u16 = 0x0CF8;
13
14const CONFIG_DATA: u16 = 0x0CFC;
16
17#[inline]
19pub fn read32(bdf: Bdf, offset: u16) -> u32 {
20 unsafe {
21 io::outl(CONFIG_ADDRESS, bdf.cfg_addr(offset));
22 io::inl(CONFIG_DATA)
23 }
24}
25
26#[inline]
28pub fn write32(bdf: Bdf, offset: u16, value: u32) {
29 unsafe {
30 io::outl(CONFIG_ADDRESS, bdf.cfg_addr(offset));
31 io::outl(CONFIG_DATA, value);
32 }
33}
34
35#[inline]
37pub fn read16(bdf: Bdf, offset: u16) -> u16 {
38 let aligned = offset & !0x3;
39 let shift = ((offset & 0x3) as u32) * 8;
40 (read32(bdf, aligned) >> shift) as u16
41}
42
43#[inline]
45pub fn write16(bdf: Bdf, offset: u16, value: u16) {
46 let aligned = offset & !0x3;
47 let shift = ((offset & 0x3) as u32) * 8;
48 let mask = !(0xFFFFu32 << shift);
49 let cur = read32(bdf, aligned);
50 let new = (cur & mask) | ((value as u32) << shift);
51 write32(bdf, aligned, new);
52}
53
54#[inline]
56pub fn read8(bdf: Bdf, offset: u16) -> u8 {
57 let aligned = offset & !0x3;
58 let shift = ((offset & 0x3) as u32) * 8;
59 (read32(bdf, aligned) >> shift) as u8
60}
61
62#[inline]
64pub fn write8(bdf: Bdf, offset: u16, value: u8) {
65 let aligned = offset & !0x3;
66 let shift = ((offset & 0x3) as u32) * 8;
67 let mask = !(0xFFu32 << shift);
68 let cur = read32(bdf, aligned);
69 let new = (cur & mask) | ((value as u32) << shift);
70 write32(bdf, aligned, new);
71}
72
73pub mod offset {
75 pub const VENDOR_ID: u16 = 0x00;
77
78 pub const DEVICE_ID: u16 = 0x02;
80
81 pub const COMMAND: u16 = 0x04;
83
84 pub const STATUS: u16 = 0x06;
86
87 pub const REVISION_ID: u16 = 0x08;
89
90 pub const PROG_IF: u16 = 0x09;
92
93 pub const SUBCLASS: u16 = 0x0A;
95
96 pub const CLASS_CODE: u16 = 0x0B;
98
99 pub const CACHE_LINE_SIZE: u16 = 0x0C;
101
102 pub const LATENCY_TIMER: u16 = 0x0D;
104
105 pub const HEADER_TYPE: u16 = 0x0E;
107
108 pub const BIST: u16 = 0x0F;
110
111 pub const BAR0: u16 = 0x10;
113
114 pub const BAR1: u16 = 0x10;
116
117 pub const BAR2: u16 = 0x10;
119
120 pub const BAR3: u16 = 0x10;
122
123 pub const BAR4: u16 = 0x10;
125
126 pub const BAR5: u16 = 0x10;
128
129 pub const SUBSYSTEM_VENDOR_ID: u16 = 0x2C;
131
132 pub const SUBSYSTEM_ID: u16 = 0x2E;
134
135 pub const CAP_PTR: u16 = 0x34;
137
138 pub const INT_LINE: u16 = 0x3C;
140}