Nvidia以太网控制器MMIO空间全为FFFF问题及驱动开发求助
Key Issues in Your Current Code
The primary problems causing invalid MMIO reads (0xFFFF) are incorrect PCI configuration handling and BAR address masking:
1. Incorrect BAR0 Masking
In step 2, you only mask the lower byte of the BAR0 value with and al, 0xf0. BAR0 is a 32-bit memory base address where the lower 4 bits are flag bits (not part of the address). You need to mask the entire 32-bit value to get the valid base address:
and eax, 0xFFFFFFF0 ; Correctly mask lower 4 flag bits
Failing to do this truncates the base address, leading to accesses to invalid memory regions.
2. Command Register Write Mistake in Step 4
After modifying the command register value to enable device and bus master, you write the value to the PCI address port (0xcf8) instead of the data port (0xcfc). This means the configuration change never takes effect, leaving the device uninitialized for MMIO access.
3. Missing PCI Config Enable Bit
Ensure your DEVICE_ID includes the required PCI configuration enable bit (bit 31 set to 1). The PCI config address format requires this bit to be 1 for valid accesses:
DEVICE_ID = 0x80000000 | (bus << 16) | (device << 11) | (func << 8) | register_offset
Corrected Assembly Steps
Here's the fixed code addressing the above issues:
1. Disable I/O and Memory Decoding
mov eax, DEVICE_ID + 0x04 ; Command register offset mov dx, 0xcf8 out dx, eax mov dx, 0xcfc in eax, dx and eax, 0xFFFFFFFC ; Clear bits 0 (I/O decode) and 1 (memory decode) out dx, eax
2. Read BAR0 Correctly
mov eax, DEVICE_ID + 0x10 ; BAR0 offset mov dx, 0xcf8 out dx, eax mov dx, 0xcfc in eax, dx and eax, 0xFFFFFFF0 ; Mask lower 4 flag bits to get valid base address mov [fs:ETH_BASE], eax
3. Restore Command Register
mov eax, DEVICE_ID + 0x04 mov dx, 0xcf8 out dx, eax mov dx, 0xcfc in eax, dx or eax, 0x03 ; Re-enable I/O and memory decode (bits 0 and 1) out dx, eax
4. Enable Device and Bus Master
mov eax, DEVICE_ID + 0x04 mov dx, 0xcf8 out dx, eax mov dx, 0xcfc in eax, dx or eax, 0x06 ; Set bit1 (device enable) and bit2 (bus master) out dx, eax ; Write to data port (0xcfc), not address port
5. Read MAC Address
mov eax, [fs:ETH_BASE] mov edx, [fs:eax + 0x00A8] mov [fs:PYSICHAL_ADDR], edx mov dx, [fs:eax + 0x00AC] mov [fs:PYSICHAL_ADDR + 0x04], dx
6. Read MMIO Registers
mov eax, [fs:ETH_BASE] mov ebx, [fs:eax + 0x600] mov ecx, [fs:eax + 0x188] mov edx, [fs:eax + 0x84]
Additional Checks
- Verify Register Offsets: Cross-check the MMIO register offsets (0x600, 0x188, 0x84) against your specific Nvidia Ethernet controller datasheet. Using incorrect offsets will return invalid data.
- MMIO Access Alignment: Ensure reads match the register size (32-bit registers as dwords, 16-bit as words) to avoid bus errors.
- Memory Mapping: If running in protected/long mode, confirm the BAR0 region is properly mapped in your memory management unit. For real mode, ensure the address falls within the 1MB address space.
内容的提问来源于stack exchange,提问作者Orang Keren

