Jump to content

Compiling ACPI v2.0 driver for Windows XP SP3 and Windows 2003 SP2 (x32/x64)


Recommended Posts

Posted (edited)

Hi,

I am going to build from scratch a Lan driver for XP SP3 for any i219.

I use Ndis5.1 original from XP, not Ndis6 from Vista, win7 etc.

Just now, for the very first time, I get this my lan driver startet under XP.

Oh crazy..what a hard work with Windbg

Dietmar

cooli219.jpg

 

0: kd> !devnode 8b5e8ee8
DevNode 0x8b5e8ee8 for PDO 0x8b51ccf8
  Parent 0x8b5e9998   Sibling 0x8b5e8dc8   Child 0000000000   
  InstancePath is "PCI\VEN_8086&DEV_15B8&SUBSYS_15B81849&REV_00\3&11583659&0&FE"
  ServiceName is "i219"
  State = DeviceNodeStarted (0x308)
  Previous State = DeviceNodeEnumerateCompletion (0x30d)
  StateHistory[07] = DeviceNodeEnumerateCompletion (0x30d)
  StateHistory[06] = DeviceNodeStarted (0x308)
  StateHistory[05] = DeviceNodeStartPostWork (0x307)
  StateHistory[04] = DeviceNodeStartCompletion (0x306)
  StateHistory[03] = DeviceNodeResourcesAssigned (0x304)
  StateHistory[02] = DeviceNodeDriversAdded (0x303)
  StateHistory[01] = DeviceNodeInitialized (0x302)
  StateHistory[00] = DeviceNodeUninitialized (0x301)
  StateHistory[19] = Unknown State (0x0)
  StateHistory[18] = Unknown State (0x0)
  StateHistory[17] = Unknown State (0x0)
  StateHistory[16] = Unknown State (0x0)
  StateHistory[15] = Unknown State (0x0)
  StateHistory[14] = Unknown State (0x0)
  StateHistory[13] = Unknown State (0x0)
  StateHistory[12] = Unknown State (0x0)
  StateHistory[11] = Unknown State (0x0)
  StateHistory[10] = Unknown State (0x0)
  StateHistory[09] = Unknown State (0x0)
  StateHistory[08] = Unknown State (0x0)
  Flags (0x000000f0)  DNF_ENUMERATED, DNF_IDS_QUERIED, 
                      DNF_HAS_BOOT_CONFIG, DNF_BOOT_CONFIG_RESERVED
  CapabilityFlags (0x00002000)  WakeFromD3

 

Edited by Dietmar

Posted

Hi,

I take all data from Linux for i219 for the registers etc.

Crazy work, 16 hours a day.

Now the driver i219.sys for XP SP3 is nearly ready

Dietmar

ip.jpg

Posted

@Dietmar

Do you think you'd be able to make a similar driver for realtek 2.5gb NICs at some point in the future? I don't have any hardware with intel i219 NICs.

Posted

@Damnation

I think, it can be done for any Nic, as long as you have Linux, where you can spy.

But it is soso crazy hard work.

I notice for example, that I always get Bsod D1, which I cannot catch with Windbg,

only when you make an offline check of it.

It happens, when the lan cable is connected at boottime, but parts of the driver have not loaded

to full, so happens this Bsod even everything is "ok".

Now I understand, why on many compis there is always a big time delay, before you get connected via lan

Dietmar

 

Posted (edited)

====================================================
Intel i219 (DEV_15B8) Windows XP SP3 driver from scratch (NDIS 5.1)
====================================================

Hi,

I’m working on a Windows XP SP3 LAN driver for my Intel i219, written from scratch as an NDIS 5.1 miniport (i219.sys).

I am very happy for any hints about the remaining missing pieces (especially i219 “PCH SPT” specifics).

Here is what I already reach, the confirmed hardware facts, register notes, and the current Supported-OID list.

----------------------------------------------------
1) My used lan adapter on Asrock z370 k6 board
----------------------------------------------------
- NIC: Intel i219 (i219-V2)
- PCI Vendor/Device: 8086:15B8
- MMIO: BAR0 mapped at 0xDF400000, length 0x20000 (128 KB)
- IRQ: legacy line 5, vector 97 (XP HAL/IOAPIC mapping)
- MAC (observed / read from RAL/RAH): 70-85-C2-7E-28-B7
- Current driver build (“v45”) installs and STARTS cleanly in Device Manager and answers basic NDIS OID queries without crashing.

----------------------------------------------------
2) Why i219 is tricky vs i218
----------------------------------------------------
- i218 belongs to the older PCH-LPT / LPTLP (Lynx Point, 8-Series) family.
- i219 belongs to the newer PCH-SPT (Sunrise Point) and later PCH families.

Therefore: “patch only DeviceID” (i218 → i219) is not enough.
A working i219 driver must use the correct i219-family MAC/PHY/NVM init logic (different from i218-family).

----------------------------------------------------
3) Hardware inputs I treat as runtime data (must be read)
----------------------------------------------------
From PCI config space:
- Vendor/Device ID (8086 / 15B8)
- Command register (Bus Master + Memory Space enable)
- BAR0 base + decoded size (here: 0x20000)
- Interrupt pin/line (legacy) and optionally MSI capability
- Power management capability (D0/D3)
- Revision ID, subsystem vendor/device ID (for possible quirks)

From MMIO:
- Classic Intel GbE register model (“E1000-ish”)

----------------------------------------------------
4) Minimal register map I’m using (layered bring-up)
----------------------------------------------------
(Full 128 KB MMIO window is huge; I focus on the layers needed for a real driver.)

4.1 Core control / status / PHY/NVM
- CTRL      0x00000  (reset / link control)
- STATUS    0x00008  (link-up bit etc.)
- EECD      0x00010  (EEPROM/flash control)
- EERD      0x00014  (EEPROM read)
- CTRL_EXT  0x00018  (extended control)
- MDIC      0x00020  (MDIO/PHY access)
- FEXTNVM   0x00028  (PCH-family helper register)

i218 vs i219 note:
The register “existence” looks similar, but the correct init sequence and interpretation is family-path dependent (i218=pch_lpt vs i219=pch_spt).

4.2 Interrupts (currently I use polled mode)
- ICR  0x000C0 (cause read/ack)
- IMS  0x000D0 (mask set)
- IMC  0x000D8 (mask clear)
- (ITR is optional)

4.3 RX/TX engine registers
Receive:
- RCTL   0x00100  (RX enable + filters)
- RDBAL  0x02800 / RDBAH 0x02804
- RDLEN  0x02808
- RDH    0x02810 / RDT   0x02818

Transmit:
- TCTL   0x00400  (TX enable)
- TIPG   0x00410
- TDBAL  0x03800 / TDBAH 0x03804
- TDLEN  0x03808
- TDH    0x03810 / TDT   0x03818

4.4 Address filtering tables (important for DHCP/ARP/multicast)
- RAL0/RAH0  0x05400 / 0x05404 (RAR0)
- MTA        0x05200 (multicast hash table)
- VFTA       0x05600 (optional VLAN filter)

Important:
When Windows sets OID_802_3_MULTICAST_LIST, the driver must program MTA accordingly (or choose a safe fallback strategy).

----------------------------------------------------
5) Supported OIDs in v45 (current list)
----------------------------------------------------
static const NDIS_OID g_SupportedOids[] = {
    OID_GEN_SUPPORTED_LIST,
    OID_GEN_HARDWARE_STATUS,
    OID_GEN_MEDIA_SUPPORTED,
    OID_GEN_MEDIA_IN_USE,
    OID_GEN_MEDIA_CONNECT_STATUS,
    OID_GEN_MAXIMUM_FRAME_SIZE,
    OID_GEN_MAXIMUM_TOTAL_SIZE,
    OID_GEN_LINK_SPEED,
    OID_GEN_XMIT_OK,
    OID_GEN_RCV_OK,
    OID_GEN_XMIT_ERROR,
    OID_GEN_RCV_ERROR,
    OID_GEN_RCV_NO_BUFFER,
    OID_GEN_TRANSMIT_BUFFER_SPACE,
    OID_GEN_RECEIVE_BUFFER_SPACE,
    OID_GEN_TRANSMIT_BLOCK_SIZE,
    OID_GEN_RECEIVE_BLOCK_SIZE,
    OID_GEN_VENDOR_ID,
    OID_GEN_VENDOR_DESCRIPTION,
    OID_GEN_DRIVER_VERSION,
    OID_GEN_VENDOR_DRIVER_VERSION,
    OID_GEN_CURRENT_PACKET_FILTER,
    OID_GEN_CURRENT_LOOKAHEAD,
    OID_GEN_PROTOCOL_OPTIONS,
    OID_GEN_MAC_OPTIONS,
    OID_GEN_MAXIMUM_SEND_PACKETS,
    OID_GEN_MAXIMUM_LOOKAHEAD,
    OID_802_3_PERMANENT_ADDRESS,
    OID_802_3_CURRENT_ADDRESS,
    OID_802_3_MAXIMUM_LIST_SIZE,
    OID_802_3_MULTICAST_LIST
};

Numeric OID values (standard ntddndis.h definitions):
- OID_GEN_SUPPORTED_LIST         = 0x00010101
- OID_GEN_HARDWARE_STATUS        = 0x00010102
- OID_GEN_MEDIA_SUPPORTED        = 0x00010103
- OID_GEN_MEDIA_IN_USE           = 0x00010104
- OID_GEN_MAXIMUM_LOOKAHEAD      = 0x00010105
- OID_GEN_MAXIMUM_FRAME_SIZE     = 0x00010106
- OID_GEN_LINK_SPEED             = 0x00010107
- OID_GEN_TRANSMIT_BUFFER_SPACE  = 0x00010108
- OID_GEN_RECEIVE_BUFFER_SPACE   = 0x00010109
- OID_GEN_TRANSMIT_BLOCK_SIZE    = 0x0001010A
- OID_GEN_RECEIVE_BLOCK_SIZE     = 0x0001010B
- OID_GEN_VENDOR_ID              = 0x0001010C
- OID_GEN_VENDOR_DESCRIPTION     = 0x0001010D
- OID_GEN_CURRENT_PACKET_FILTER  = 0x0001010E
- OID_GEN_CURRENT_LOOKAHEAD      = 0x0001010F
- OID_GEN_DRIVER_VERSION         = 0x00010110
- OID_GEN_MAXIMUM_TOTAL_SIZE     = 0x00010111
- OID_GEN_PROTOCOL_OPTIONS       = 0x00010112
- OID_GEN_MAC_OPTIONS            = 0x00010113
- OID_GEN_MEDIA_CONNECT_STATUS   = 0x00010114
- OID_GEN_MAXIMUM_SEND_PACKETS   = 0x00010115
- OID_GEN_VENDOR_DRIVER_VERSION  = 0x00010116
- OID_GEN_XMIT_OK                = 0x00020101
- OID_GEN_RCV_OK                 = 0x00020102
- OID_GEN_XMIT_ERROR             = 0x00020103
- OID_GEN_RCV_ERROR              = 0x00020104
- OID_GEN_RCV_NO_BUFFER          = 0x00020105
- OID_802_3_PERMANENT_ADDRESS    = 0x01010101
- OID_802_3_CURRENT_ADDRESS      = 0x01010102
- OID_802_3_MULTICAST_LIST       = 0x01010103
- OID_802_3_MAXIMUM_LIST_SIZE    = 0x01010104

----------------------------------------------------
6) Current OID behavior in v45
----------------------------------------------------
QueryInformation highlights:
- OID_GEN_SUPPORTED_LIST:
  -> returns g_SupportedOids[]
- OID_GEN_HARDWARE_STATUS:
  -> NdisHardwareStatusReady
- OID_GEN_MEDIA_SUPPORTED / OID_GEN_MEDIA_IN_USE:
  -> NdisMedium802_3
- OID_GEN_MEDIA_CONNECT_STATUS:
  -> cached LinkState (Connected/Disconnected)
- OID_GEN_MAXIMUM_FRAME_SIZE:
  -> 1500
- OID_GEN_MAXIMUM_TOTAL_SIZE:
  -> 1514
- OID_GEN_LINK_SPEED:
  -> 10000000 (1 Gbps in 100 bps units)
- OID_GEN_VENDOR_ID:
  -> derived from MAC OUI (first 3 bytes)
- OID_GEN_VENDOR_DESCRIPTION:
  -> "Dietmar i219 XP skeleton v45"
- OID_GEN_DRIVER_VERSION:
  -> 0x0100
- OID_GEN_VENDOR_DRIVER_VERSION:
  -> 0x00010000 (1.0 encoded as major/minor)
- OID_GEN_MAC_OPTIONS:
  -> COPY_LOOKAHEAD_DATA | TRANSFERS_NOT_PEND (observed as 0x5)
- OID_GEN_MAXIMUM_SEND_PACKETS:
  -> 1
- OID_GEN_MAXIMUM_LOOKAHEAD:
  -> 1500
- OID_GEN_CURRENT_LOOKAHEAD / OID_GEN_CURRENT_PACKET_FILTER:
  -> returns cached values (Lookahead / PacketFilter)
- Basic stats OIDs:
  -> currently 0 (no counters yet)
- OID_802_3_PERMANENT_ADDRESS / CURRENT_ADDRESS:
  -> returns 6 bytes MAC
- OID_802_3_MAXIMUM_LIST_SIZE:
  -> 32

SetInformation highlights:
- OID_GEN_CURRENT_PACKET_FILTER:
  -> currently stores PacketFilter only (hardware filter mapping still in progress)
- OID_GEN_CURRENT_LOOKAHEAD:
  -> stores Lookahead (clamped to 1500)
- OID_802_3_MULTICAST_LIST:
  -> stores up to 32 multicast MACs (but MTA programming is still in progress)

----------------------------------------------------
7) Problems already solved
----------------------------------------------------
- Driver loads/starts (v45):
  -> Clean start in Device Manager, Initialize runs, MMIO mapping is real.
- Reliable MMIO/resource discovery:
  -> Stable BAR0 mapping confirmed (0xDF400000 / len 0x20000).
- Root cause of earlier NDIS crash identified:
  -> When I previously “faked” some OIDs via WinDbg, I triggered a crash in NDIS OID validation
     (bad/NULL/incorrect Supported-OID list handling).
  -> Fix direction implemented:
     - real SupportedOids[] array
     - real Query/Set OID engine with correct BUFFER_TOO_SHORT / BytesNeeded / BytesWritten.
- XP NDIS signature differences handled:
  -> Adjusted NdisMMapIoSpace / NdisMUnmapIoSpace usage for XP/NDIS5 compatibility.

----------------------------------------------------
8) What I still miss
----------------------------------------------------
Even though the driver starts and answers OIDs, I still do NOT have real network traffic working end-to-end:
- No DHCP lease / no real RX/TX  I can see.

What I believe is still needed:
1) Correct i219-family (PCH SPT) PHY + NVM init sequence (this is where i219 differs most from i218).
2) Correct mapping of OID_GEN_CURRENT_PACKET_FILTER into real hardware filtering (RCTL + tables).
3) Correct implementation of OID_802_3_MULTICAST_LIST into MTA programming (or safe fallback).
4) Possibly: switch from polled mode to proper interrupt mode once the basics work.

If anyone has experience with i219 on older OSes (XP/2003):
- The minimal “must-do” i219 (PCH SPT) PHY/NVM init steps to get stable link + RX/TX.
- Any known i219-specific register quirks that differ from i218-family.
- Confirmation whether my minimal TX/RX + RCTL strategy is sufficient, or which missing bits are typically required.

Dietmar

PS:

Where the technical details in my i219 XP driver thread come from, and how I verify everything with crazy WinDbg use.

----------------------------------------------------
A) Direct observations from MY system (WinDbg + runtime logging)
----------------------------------------------------
These facts are taken from my own XP test machine and WinDbg sessions:
- PCI ID: 8086:15B8 (Intel i219-V2)
- BAR0 MMIO mapping: base 0xDF400000, size 0x20000
- IRQ resources (legacy line/vector)
- MAC address read/used by the driver (70-85-C2-7E-28-B7)
- Which OIDs are queried by NDIS / TCPIP and what my driver returned (seen via breakpoints + stack inspection)
- Whether frames are actually TX/RX (currently: driver starts, but traffic still missing)

----------------------------------------------------
B) Extracted from my own driver source code (current v45 skeleton)
----------------------------------------------------
These items are not “guessed”; they come straight from my current i219.c / i219.h:
- The exact SupportedOids[] array (the list I return for OID_GEN_SUPPORTED_LIST)
- My current OID Query/Set behavior (what I return/store)
- Ring sizes / buffer sizes / the delayed bring-up strategy (late TX/RX init after 40s)
- Which register offsets I currently touch (RCTL/TCTL/TIPG/RDBAL… etc.) and which bits I set

----------------------------------------------------
C) Public reference sources (open headers/docs)
----------------------------------------------------
I used publicly available sources for “static” definitions, i.e. register offsets, bit masks, and OID semantics:

1) Intel e1000 / e1000e style register offsets + bit definitions
   - Linux kernel: drivers/net/ethernet/intel/e1000e/ (hw.h, defines.h, etc.)
   - QEMU’s e1000_hw.h (also includes the classic register layout)

2) NDIS OID numbers (hex values) and structures
   - ReactOS ntddndis.h (matches Windows OID values and is easy to reference)

3) OID semantics (what Windows expects)
   - Microsoft documentation for OID_GEN_SUPPORTED_LIST, OID_GEN_CURRENT_PACKET_FILTER,
     OID_802_3_MULTICAST_LIST, OID_GEN_LINK_SPEED, etc.

----------------------------------------------------
D) Heavy WinDbg use, the extremely hard part ;))
----------------------------------------------------
My main technique is breakpoint-driven “bisection” (binary search in control flow):
- Set a breakpoint at the function I expect to run.
- If it is NOT hit, move the breakpoint earlier (caller / dispatcher) until I find the last hit location.
- The bug must be between the last-hit BP and the first-not-hit BP.
- Only after I have narrowed it down do I inspect registers/stack/buffers.

Typical breakpoints I use:
1) OID path:
   bp i219!I219MiniportQueryInformation
   bp i219!I219MiniportSetInformation
   bp NDIS!ndisMDispatchRequest

   Inside Query/SetInformation on x86 NDIS5, the OID value is the 2nd argument:
   - OID is at [esp+8]
     ? poi(@esp+8)
   I often dump the full stack to see all arguments:
     dd esp L20
   Then continue:
     g

2) Driver bring-up / resources:
   bp i219!I219Initialize
   bp i219!I219LateBringUp
   bp i219!I219ProgramRxTx
   bp i219!I219WriteMacToRar0

3) RX/TX progress:
   bp i219!I219SendPackets
   bp i219!I219PollRxTx
   (then watch MMIO reads/writes and descriptor ring head/tail changes)

If an OID is queried and packets still don’t flow, I focus on:
- OID_GEN_CURRENT_PACKET_FILTER SET → must translate into RCTL + filtering (broadcast/multicast)
- OID_802_3_MULTICAST_LIST SET → must program MTA (or enable a safe fallback)
- Link state / PHY init (i219 “PCH SPT” path differs from i218 “LPT” path)

----------------------------------------------------
Reference links (for convenience)
----------------------------------------------------
Linux e1000e:
- https://github.com/torvalds/linux/tree/master/drivers/net/ethernet/intel/e1000e

QEMU e1000 register layout (e1000_hw.h):
- https://git.zx2c4.com/qemu/tree/hw/e1000_hw.h

ReactOS ntddndis.h (OID hex values):
- https://doxygen.reactos.org/dc/d38/ntddndis_8h.html

Microsoft OID docs:
- https://learn.microsoft.com/en-us/windows-hardware/drivers/network/oid-gen-supported-list
- https://learn.microsoft.com/en-us/windows-hardware/drivers/network/oid-gen-current-packet-filter
- https://learn.microsoft.com/en-us/windows-hardware/drivers/n

Edited by Dietmar

Please sign in to comment

You will be able to leave a comment after signing in



Sign In Now
  • Recently Browsing   1 member

×
×
  • Create New...