AMD PCNET

From OSDev.wiki
Revision as of 11:27, 11 October 2015 by osdev>Jnc100 (Add to Network Hardware category)
Jump to navigation Jump to search
This page is a work in progress.
This page may thus be incomplete. Its content may be changed in the near future.

The AMD PCNET family of network interface chips are supported by most popular virtual machines and emulators, including QEMU, VMware and VirtualBox. While not as simple as the RTL8139 it is easier to test with an emulator, as the RTL8139 is only supported in QEMU, and getting QEMU's full network support running is sometimes difficult. This article will focus on the Am79C970A a.k.a. the AMD PCnet-PCI II in VirtualBox.

Overview

This article will cover using the card with IO port accesses as opposed to memory mapped IO.

The card uses a system of index registers. What this means is that one first writes to an IO port to select the chip register you want to access, and then read/write to/from a certain IO port. It can also support reading and writing in both 16 and 32bit modes.

In Real Mode

In using the card in real mode your OS will need to have the ability to read and write to PCI registers and the ability to use an Interrupt controller (PIC8259, have not tried it using APIC) this article assumes the reader has knowledge of both. Since the card will be sending and reciving data on its own you will want to use the PIC to switch execution back and forth from processing from the card and your CPU this article installs the card at IRQ10 (0x01C8).

There are two types of registers used by the card BCR's and CSR's. Below are some helpful functions for reading and writing to the registers.

iobase dw 0xD020 ; the default I/O address in Virtual Box when enabling no extra hardware your PCI address most likely will not be the same

RDP equ 0x10
RAP equ 0x12
BDP equ 0x16

; IN: ax,register number on the device
; OUT: cx,word read from register
Rcsr: ; read a value of a CSR
nop ; useful marker in reading through crash dumps
pusha
mov dx,[iobase]
add dx,RAP
out dx,ax
mov dx,[iobase]
add dx,RDP
in ax,dx
mov [csrW],ax
popa
mov cx,[csrW]
ret
csrW dw 0xFFFF

; IN: ax,register number on the device; cx,word to be sent to register;
; OUT: nothing
Wcsr:
nop
pusha
mov dx,[iobase] ; base port address
add dx,RAP
out dx,ax
mov dx,[iobase]
add dx,RDP
mov ax,cx ; mov word to be sent out by the port
out dx,ax
popa
ret

; IN: ax,register number on the device
; OUT: cx,word read from register
Rbcr:
nop
pusha
mov dx,[iobase]
add dx,RAP
out dx,ax
mov dx,[iobase]
add dx,BDP
in ax,dx
mov [bcrW],ax
popa
mov cx,[bcrW]
ret
bcrW dw 0xFFFF

; IN: ax,register number on the device; cx,word to be sent to register;
; OUT: nothing
Wbcr:
nop
pusha
mov dx,[iobase] ; base port address
add dx,RAP
out dx,ax
mov dx,[iobase]
add dx,BDP
mov ax,cx ; mov word to be sent out by the port
out dx,ax
popa
ret

The initialization process of the card consists of writing an address to a structure which defines the way the card will act.

; see page 154 table 34 (SSIZE32=0)
MODE dw 1000000010000000b ; set 10Base-T and prom mode (see CSR15)
PADR: ; physical address or 
dw 0xFFFF
dw 0xFFFF
dw 0xFFFF
LOGICAL:
dw 0x0000
dw 0x0000
dw 0x0000
dw 0x0000
RDRA dw ADRRDRA ; address for where your recieve descriptors are
db 00000000b ;bits 15-13 are for length of descriptors (see page 155)
db 0x0000 ; HI address in real mode not useful
TDTA dw TDTA ; address for where your transmit descriptors are
db 00000000b ; see page 155 table 37
db 0x0000 ; HI address in real mode not useful

Descriptor Ring format for Reciever:

Reciever Descriptor ring:

Descriptor Ring format for Transmitter:

Transmitter Descriptor ring:

IO Ports

In 32bit mode the card has only 4+6 IO ports necessary to use the card:

Offset (from IO base) Name
0x00-0x05 MAC0-MAC5
0x10 RDP
0x14 RAP
0x18 RST
0x1C BDP
  • MAC0-MAC5 are the ports used to access the MAC address stored in the card's ROM. These should be accessed byte-by-byte in order to ensure compatibility with all three emulators.
  • RAP is the Register Access Pointer, and selects which card register one wants to access.
  • RDP is the Register Data Pointer and is the port used to access the first set of registers
  • BDP is the Bus Configuration Data Port and is used to access the second set of registers
  • RST is used to reset the card.

DMA Descriptors

The PCNET cards use a series of descriptors to handle DMA.

struct pcnet_descriptor {
   uint32_t address; //physical address of buffer
   uint16_t length; //length of buffer (rx) or length of packet (tx)
   uint16_t status;
   uint32_t flags;
   uint32_t user;//can be used to store whatever value you want, such as the virtual address of your buffer
};

See Also

External Links