Informatyka Studia Dzienne
Laboratorium Architektury Komputerów
Ćwiczenie 8
Magistrala PCI.
Pamięć konfiguracyjna urządzeń PCI.
Przygotowanie:
Krzysztof Tokarz
1. Cel ćwiczenia.
Celem ćwiczenia jest poznanie:
- architektury magistrali PCI,
- odczytu informacji o urządzeniach PCI,
- wyświetlania liczb binarnych w formie szesnastkowej.
2. Cechy magistrali PCI.
PCI to skrót - Peripherial Component Interconnect.
W jednym systemie może istnieć do 256 magistral PCI, każda (teoretycznie) po maksymalnie 32
urządzenia. Ze względu na elektryczne właściwości przewodów i układów scalonych występuje
praktyczne ograniczenie na liczbę urządzeń podłączonych do magistrali PCI. Ograniczenie to
wynosi 5 urządzeń dla magistrali PCI w podstawowej wersji. W komputerach PC stosowana jest
zwykle od jednej do kilku magistral PCI.
Historia magistral PCI:
PCI 1.0 – Intel 1992
33MHz, 32bit (132Mbit/s), tylko specyfikacja układów,
PCI 2.0 – PCI SIG 1993
33MHz, 32bit, specyfikacja złącza,
PCI 2.1 – 1995
33/66MHz, 32/64bit (264Mb/s, 528Mb/s) 5V,
PCI 2.2 – 1998
dostosowanie do napięć 5V/3.3V
PCI 2.3 – 2002
karty tylko 3,3V, płyta obsługuje karty 3,3V lub uniwersalne
PCI 3.0 – 2004
wyłącznie 3,3V
Rozszerzeniem magistrali PCI jest PCI-X oraz PCI-Express.
3. Konfiguracja urządzeń na magistrali PCI.
Każde urządzenie PCI powinno posiadać 256 bajtów pamięci konfiguracyjnej. Pamięć ta jest
adresowana sześcioma bitami magistrali PCI: AD7-AD2, bity AD1 i AD0 muszą być równe 0.
Oznacza to że jednorazowo uzyskuje się dostęp do czterech kolejnych bajtów konfiguracyjnych.
Zawartość pamięci konfiguracyjnej.
Pierwsze 64 bajty to nagłówek (jak na rys.)
pozostałe bajty są specyficzne dla urządzenia.
Opis niektórych elementów bloku konfiguracji:
Vendor ID – identyfikator producenta ustalany
przez PCI SIG, FFFFh jest zarezerwowana dla
urządzenia, którego nie ma w systemie (puste
złącze). 8086-Intel
Device ID – typ urządzenia ustalany przez
producenta.
Command – rejestr poleceń wysyłanych do
urządzenia PCI.
Status – Rejestr aktualnego stanu urządzenia.
Class Code – kod klasy urządzenia, umożliwia
określenie właściwości i przeznaczenia
urządzenia. Jest podzielony na 3 części:
bity 23-16
– klasa urządzenia,
bity 15-8
– podklasa,
bity 7-0
– kod interfejsu.
4. Dostęp do pamięci konfiguracji.
Dostęp do pamięci konfiguracji urządzenia podłączonego do magistrali PCI można uzyskać na trzy
sposoby. Dwa z nich polegają na bezpośrednim dostępie do rejestrów w przestrzeni I/O komputera.
Trzeci polega na wykorzystaniu funkcji B1h przerwania INT 1Ah. Funkcja ta pozwala na:
–
wykrycie funkcji PCI BIOS
–
wykrycie urządzeń PCI
–
odczytanie kodu klasy urządzeń
–
generowanie cyklu specjalnego
–
odczyt i zapis danych konfiguracyjnych
–
odczyt infomracji o kanałach przerwań
–
przypisanie kanałów przerwań
Parametry funkcji B1h przerwania 1Ah:
w rejestrze AL – kod operacji
–
01h sprawdzenie obecności BIOS-u PCI (zwraca “PCI “ w rejestrze edx)
–
08h odczyt bajtu
–
09h odczyt słowa
–
0Ah odczyt podwójnego słowa
w rejestrze BX – numer urządzenia PCI:
–
bity 15:8 numer magistrali,
–
bity 7:3 identyfikator urządzenia,
–
bity 2:0 numer funkcji (dla urządzeń wielofunkcyjnych).
w rejestrze DI – adres bajtu w przestrzeni konfiguracyjnej
5. Klasy urządzeń PCI.
Klasa urządzenia określa przynależność urządzenia podłączonego do magistrali PCI do jednej z
grup funkcjonalnych. Kod klasy określa klasę, podklasę i interfejs.
Przykładowe kody urządzeń:
Klasa
Podklasa
Interfejs
Urządzenie
00h
00h
00h
Urządzenie niezdefiniowane
01h
01h
Kontroler IDE
02h
00h
00h
Karta sieci Ethernet
02h
01h
00h
Karta sieci Token Bus
03h
00h
00h
Karta grafiki VGA
06h
00h
00h
Mostek Host
06h
01h
00h
Mostek ISA
06h
04h
00h
Mostek PCI do PCI
07h
00h
00h
Port szeregowy
07h
01h
00h
Port równoległy
07h
01h
02h
Port równoległy ECP
07h
03h
00h
Modem
6. Przykładowe identyfikatory producentów i urządzeń.
Przykładowe identyfikatory producenta i urządzenia w komputerze IBM ThinkPad 600:
Vendor Device Number Function
Description
8086
7192
0
0
Intel 440BX/ZX/DX - 82443BX/ZX/DX Host bridge
(AGP disabled)
104C
AC16
2
01
Texas Instruments PCI1250 CardBus Bridge
10C8
0004
3
0
NeoMagic NM2160 [MagicGraph 128XD]
0000
0000
3
1234567 Błąd kontrolera NeoMagic
8086
7110
7
0
Intel 82371AB/EB/MB PIIX4 ISA
8086
7111
7
1
Intel 82371AB/EB/MB PIIX4 IDE
8086
7112
7
2
Intel 82371AB/EB/MB PIIX4 USB
8086
7113
7
3
Intel 82371AB/EB/MB PIIX4 ACPI
Przykładowe identyfikatory producenta i urządzenia w komputerach na laboratorium:
Vendor Device Number Function
Description
8086
122D
0
0
Intel Triton chipset: 82437FX System Controller
8086
122E
7
0
Intel Triton chipset: 82371FB PCI to ISA Bridge
8086
1230
7
1
Intel Triton chipset: 82371FB IDE Interface
5333
8811
14
01234567 S3 86C764/765 Trio 64/64V+ GUI Accelerator
5333
8901
E
01234567 S3 86C775/86C785 Trio 64V2 DX/GX
102B
0518
D
01234567 Matrox MGA-PX2085 Atlas GUI Accelerator
8086
04A3
0
01234567 Intel 82434LX/NX Mercury/Neptune
Cache/DRAM Controller
1042
1000
1
01234567 Prawdopodobnie TI PCI Eagle i/f AS (VID 104C)
8086
0484
2
01234567 Intel 82378ZB/IB SIO ISA Bridge
Sprawdzić identyfikator producenta i urządzenia zainstalowanego w komputerze sprzętu można na
stronie internetowej www.pcidatabase.com
7. Przykładowy program odczytujący konfigurację magistrali PCI.
program PCIbus;
uses windos, crt;
var
regs: TRegisters;
func, dev, bus, funcflags, lastfunc: byte;
VendorID, DeviceID: word;
function power(x,y:byte):byte;
var temp, z: byte;
begin
temp:=1;
for z:=1 to y do
temp:=temp * x;
power:=temp;
end;
function ReadByte(bus, device, func, index: byte): byte;
var TempRegs: Tregisters;
begin
TempRegs.bh:=bus;
TempRegs.bl:=(device shl 3) or func;
TempRegs.ax:=$b108;
TempRegs.di:=index;
intr($1A,TempRegs);
ReadByte:=TempRegs.cl;
end;
function PiszHex(x: byte): string;
var i: byte;
const HexChars: string = '0123456789ABCDEF';
begin
PiszHex:=HexChars[x shr 4 + 1] + HexChars[x and $f + 1];
end;
procedure Wypisz(bus, dev, func, funcflags: byte);
var x: byte;
begin
write(PiszHex(ReadByte(bus,dev,func,1)),
PiszHex(ReadByte(bus,dev,func,0)), ' ');
write(PiszHex(ReadByte(bus,dev,func,3)),
PiszHex(ReadByte(bus,dev,func,2)), ' ');
write(bus,' ',PiszHex(dev),' ');
for x:=0 to 7 do
if ((funcflags shr x) and 1) = 1 then
write(x)
else
write(' ');
writeln;
end;
begin
clrscr;
regs.ax:=$B101;
intr($1A,regs);
if regs.dx = 17232 then {hex=4350 co oznacza CP}
begin
write('PCI version: ',PiszHex(regs.bh),'.',PiszHex(regs.bx));
writeln(' | Maksymalna liczba magistral PCI : ',regs.ch);
textcolor(14);
writeln('IDPRODUCENTA URZADZENIE MAGISTRALA URZADZENIE FUNKCJE');
for bus:=0 to regs.ch do
for dev:=0 to 31 do
begin
funcflags:=0;
lastfunc:=10;
DeviceID:=$ffff;
for func:=0 to 7 do
if (ReadByte(bus,dev,func,1) <> $ff) and
(ReadByte(bus,dev,func,0) <> $ff) then
begin
if (DeviceID <> ReadByte(bus,dev,func,3) * $100 +
ReadByte(bus,dev,func,2)) and
(DeviceID <> $ffff) then
begin
Wypisz(bus,dev,lastfunc,funcflags);
funcflags:=0;
lastfunc:=10;
end;
funcflags:=funcflags or power(2,func);
lastfunc:=func;
DeviceID:=ReadByte(bus,dev,func,3) * $100 +
ReadByte(bus,dev,func,2);
end;
if lastfunc < 10 then
Wypisz(bus,dev,lastfunc,funcflags);
end;
end
else
writeln('Nie znaleziono zadnej magistrali PCI ');
readln;
end.