@DATABASE developer-PL.guide
@$VER: developer-PL.guide 1.50 (25.7.2001)
@(C) Copyright by Matay 2001
@AUTHOR Grzegorz "Krashan" Kraszewski <krashan@matay.pl>
@SMARTWRAP

@NODE main "Spis treôci"
@{JCENTER}


@{B}@{BG text}@{FG shine}  P R O M E T E U S Z  @{BG background}@{FG text}


@{B}Informacje dla programistów @{UB}


@{I}Wersja 1.50 (25 lipca 2001) @{UI}


@{JLEFT}
@{TAB}Spis treôci:


@{TAB}@{TAB}@{"  Podstawowe informacje o PCI  " LINK pci_intro}

@{TAB}@{TAB}@{"  Podstawy dziaîania Prometeusza  " LINK prometheus_basics}

@{TAB}@{TAB}@{"  Biblioteka prometheus.library  " LINK prometheus_library}

@{TAB}@{TAB}@{"  Mapa przestrzeni adresowej  " LINK memory_map}

@{TAB}@{TAB}@{"  Kolejnoôê bajtów  " LINK byte_ordering}

@{TAB}@{TAB}@{"  Wolno dziaîajâce karty  PCI  " LINK slow_cards}

@{TAB}@{TAB}@{"  Obsîuga przerwaï  " link interrupts}

@{TAB}@{TAB}@{"  Wykaz zmian  " LINK change_log}

@ENDNODE

@NODE pci_intro "Wprowadzenie do PCI"
@{B}Podstawowe informacje o PCI @{UB}


W tym rozdziale znajdziecie podstawowe informacje niezbëdne z punktu
widzenia programisty dotyczâce samego PCI. PCI
@{I}(Peripherial Component Interface) @{UI} to uniwersalna 32-bitowa magistrala sîuûâca
do îâczenia miëdzy sobâ procesora i urzâdzeï peryferyjnych umieszczanych
wewnâtrz komputera. Duûe rozpowszechnienie PCI w komputerach PC
zaowocowaîo ogromnâ iloôciâ dostëpnych na rynku tanich kart rozszerzeï.
Prometeusz jest jednym z rozwiâzaï pozwalajâcych na uûywanie tych kart w
Amidze.


Na magistrali PCI istniejâ dwie 32-bitowe przestrzenie adresowe -
przestrzeï wejôcia/wyjôcia i przestrzeï pamiëci. Daje to îâcznie 8 GB
przestrzeni adresowej. Nazwy tych przestrzeni sâ umowne, z reguîy karty
umieszczajâ w przestrzeni I/O swoje rejestry kontrolne, a w przestrzeni
pamiëci bufory pamiëciowe (np. pamiëê video karty graficznej). Czësto
rejestry kontrolne sâ zdublowane w obu obszarach. Obszar w przestrzeni
I/O moûe mieê od 4 bajtów do 4 GB, obszar pamiëci od 16 bajtów do 4 GB.
Oczywiôcie w ûadnej Amidze nie mamy do dyspozycji 8 GB przestrzeni
adresowej, dlatego Prometeusz udostëpnia jedynie jej fragment, a
dokîadniej 511 MB obszaru pamiëci i 960 kB obszaru wejôcia/wyjôcia
(patrz @{"mapa pamiëci" LINK memory_map}).


Kaûda karta PCI przed jej uûyciem wymaga konfiguracji. Podstawowym
zadaniem konfiguracji jest dynamiczne przydzielenie adresów. Karta PCI
moûe zaûâdaê od systemu przydzielenia maksymalnie szeôciu obszarów
adresowych w dowolnej z dwóch przestrzeni adresowych. W systemie AmigaOS
przydzielenie adresów wykonuje automatycznie biblioteka
prometheus.library w czasie startu systemu. Sterowniki poszczególnych
kart mogâ je odszukaê i odczytaê ich adresy bazowe korzystajâc z funkcji
tej biblioteki.

@ENDNODE
@NODE memory_map "Mapa przestrzeni adresowej"
@{B}Podziaî przestrzeni adresowej Prometeusza @{UB}


Podane tu informacje nie sâ potrzebne dla programistów piszâcych
sterowniki dla AmigaOS - ci @{U}powinni@{UU} korzystaê z funkcji dostarczanych
przez bibliotekë prometheus.library. Znajomoôê mapy pamiëci Prometeusza
moûe byê jednak niezbëdna do napisania sterowników dla innych systemów
operacyjnych, na przykîad @{B}Linuksa @{UB}czy @{B}NetBSD.@{UB}


Prometeusz zajmuje 512 MB przestrzeni adresowej Amigi. Jej adres zaleûy
od tego, jakie inne karty Zorro III sâ zainstalowane w systemie. W
przypadku braku innych kart Prometeusz jest umieszczany przez system w
zakresie adresów $40000000 - $5FFFFFFF. Nigdy jednak nie naleûy
zakîadaê, ûe jest to adres staîy, @{U}zawsze@{UU} naleûy go odczytaê z
dynamicznych tablic tworzonych przez dany system operacyjny.


Jak wiadomo z wczeôniejszych rozdziaîów, PCI ma trzy przestrzenie
adresowe, które muszâ zostaê jakoô zmieszczone w jednej przestrzeni
adresowej Amigi. Dlatego róûnym fragmentom przestrzeni adresowej
Prometeusza odpowiadajâ róûne przestrzenie adresowe PCI. Poniûej
przedstawiona jest mapa pamiëci. Podane adresy sâ to przesuniëcia w
stosunku do adresu bazowego karty:


$00000000 - $000EFFFF @{TAB}Przestrzeï wejôcia/wyjôcia PCI (960 kB)

$000F0000 - $000F00FF @{TAB}Przestrzeï konfiguracyjna slotu 0 (256 B)

$000F0100 - $000F1FFF @{TAB}Zarezerwowane

$000F2000 - $000F20FF @{TAB}Przestrzeï konfiguracyjna slotu 1 (256 B)

$000F2100 - $000F3FFF @{TAB}Zarezerwowane

$000F4000 - $000F40FF @{TAB}Przestrzeï konfiguracyjna slotu 2 (256 B)

$000F4100 - $000F5FFF @{TAB}Zarezerwowane

$000F6000 - $000F60FF @{TAB}Przestrzeï konfiguracyjna slotu 3 (256 B)

$000F6100 - $000FFFFF @{TAB}Zarezerwowane

$00100000 - $1FFFFFFF @{TAB}Przestrzeï pamiëci PCI (511 MB)


Przydzielajâc obszary adresów kartom PCI naleûy pamiëtaê o prawidîowym
przypisaniu przestrzeni adresowej w zaleûnoôci od wymagaï karty.
Przypomnë raz jeszcze, ûe w systemie AmigaOS zajmuje sië tym biblioteka
prometheus.library.

@ENDNODE
@NODE byte_ordering "Problem kolejnoôci bajtów"
@{B}Problem kolejnoôci bajtów @{UB}


Programujâc karty PCI zetkniemy sië z problemem kolejnoôci bajtów w
sîowach 16 i 32-bitowych. Wiëkszoôê istniejâcych procesorów, z rodzinâ
M68k i PPC wîâcznie uûywa konwencji zgodnie z którâ bajty w sîowie
umieszczone sâ od najbardziej do najmniej znaczâcego:


@{TAB}0@{TAB}@{TAB}1@{TAB}@{TAB}2@{TAB}@{TAB}3

@{TAB}bity 31-24@{TAB}bity 23-16@{TAB}bity 15-8@{TAB}bity 7-0


Niestety w procesorach kompatybilnych z seriâ x86 Intela bajty
umieszczane sâ w pamiëci odwrotnie:


@{TAB}0@{TAB}@{TAB}1@{TAB}@{TAB}2@{TAB}@{TAB}3

@{TAB}bity 7-0@{TAB}bity 15-8@{TAB}bity 23-16@{TAB}bity 31-24


Poniewaû wiëkszoôê kart PCI produkowana jest z myôlâ o komputerach PC,
spodziewajâ sië one wîaônie takiego uszeregowania bajtów. Aby uniknâê
zamieszania Prometeusz wyposaûony jest w @{B}sprzëtowy ukîad zmiany
kojelnoôci bajtów, @{UB} który caîâ operacjë wykonuje w locie bez
narzutu czasowego. Dziëki temu moûemy programowaê karty PCI dokîadnie w
taki sam sposób w jaki robi sië to na komputerach PC. Ukîad zamiany
dziaîa w obu kierunkach. Jeûeli zatem w 32-bitowym rejestrze karty
chcemy zapisaê danâ $DEADBACA, to robimy to bezpoôrednio, w kolejnych
bajtach rejestru znajdâ sië $CA, $BA, $AD, $DE (zgodnie z konwencjâ
Intela), ale odczyt z tego rejestru ponownie da nam $DEADBACA.


Autorzy sterowników dla systemów innych niû AmigaOS natknâ sië na jeden
wyjâtek. Mianowicie rejestry konfiguracyjne kart PCI zgodnie ze
specyfikacjâ PCI 2.1 majâ bajty uszeregowane w konwencji Motoroli.
Poniewaû ukîad zmiany kolejnoôci bajtów w Prometeuszu pracuje caîy czas,
naleûy przy dostëpie do przestrzeni konfiguracyjnej dokonywaê
programowej zmiany kolejnoôci bajtów, która zneutralizuje zamianë
sprzëtowâ. Programowâ zmianë kolejnoôci moûna wykonaê np. takâ sekwencjâ
rozkazów asemblera:


@{TAB}ROL.W @{TAB}#8,d0

@{TAB}SWAP @{TAB}d0

@{TAB}ROL.W @{TAB}#8,d0


Odpowiednie makra (swapl() i swapw()) dla kompilatora GCC znajdujâ sië w
inkludach doîâczonych do tego SDK. W systemie AmigaOS konfiguracjâ kart
zajmuje sië prometheus.library, wiëc problem ten nie istnieje.

@ENDNODE
@NODE prometheus_basics "Podstawy dziaîania Prometeusza"
@{B}Podstawy dziaîania Prometeusza @{UB}


Prometeusz jest mostkiem miëdzy magistralami Zorro III i PCI. Jest to
tak zwany mostek "przezroczysty". Kaûda transakcja Zorro III jest
tîumaczona na odpowiedniâ transakcjë PCI. Przezroczystoôê oznacza, ûe
nie sâ potrzebne ûadne specjalne funkcje do odczytu i zapisu danych do
kart PCI. Karty te moûna traktowaê jako obszary przestrzeni adresowej
procesora Amigi. Naleûy jednak zwróciê uwagë na pamiëê podrëcznâ (cache)
procesora. W systemie AmigaOS procedury AutoConfig automatycznie
wyîâczajâ cache procesora dla obszaru zajmowanego przez Prometeusza,
niemniej jest to moûliwe tylko dla procesorów wyposaûonych w ukîad MMU.
Problemy mogâ wystâpiê z procesorem 68EC030, nie ma on MMU wiëc pamiëê
podrëcznâ w razie potrzeby naleûy opróûniê uûywajâc funkcji
CacheClearU() lub lepiej CacheClearE() czyszczâc jedynie pamiëê
podrëcznâ danych.

@ENDNODE
@NODE prometheus_library "Biblioteka prometheus.library i jej zadania"
@{B}Biblioteka prometheus.library i jej zadania @{UB}


Biblioteka prometheus.library jest dodawana do systemu przez procedury
AutoConfig w czasie startu systemu. Dokîadnie odbywa sië to w momencie
pierwszego otwarcia biblioteki przez jakiô sterownik, lub program.
Biblioteka wykrywa umieszczone w slotach Prometeusza karty PCI i
konfiguruje je. Nastëpnie pozostaje w systemie umoûliwiajâc odszukanie
dostëpnych kart PCI i pobranie informacji o nich. Do sprawdzenia, czy
dana karta jest zainstalowana sîuûy funkcja Prm_FindBoardTagList().
Informacje o odszukanej karcie (w tym adresy i rozmiary przydzielonych
obszarów przestrzeni adresowej) moûna odczytaê funkcjâ
Prm_GetBoardAttrsTagList(). Obie funkcje szczegóîowo omówione sâ w pliku
autodoc biblioteki. Przykîadem programu korzystajâcego z funkcji
prometheus.library jest PrmScan wypisujâcy informacje o wszystkich
znalezionych kartach PCI. Jego kod úródîowy znajduje sië w tym SDK.

@ENDNODE
@NODE slow_cards "Problemy z wolnymi kartami"
@{B}Problemy z wolnymi kartami PCI @{UB}


Specyfikacja PCI zaleca, aby kaûda karta rozpoczëîa operacjë zapisu lub
odczytu najpóúniej w 8 taktów zegara od inicjalizacji cyklu PCI.
Niestety niektóre karty w okreôlonych sytuacjach nie sâ w stanie tego
zrobiê. Dotyczy to na przykîad odczytu zawartoôci pamiëci ROM niektórych
kart graficznych. W takiej sytuacji karta sygnalizuje stan "Retry"
proszâc inicjatora transakcji o powtórzenie cyklu. Niestety nie zawsze
jest to moûliwe w obrëbie jednego cyklu szyny Zorro III. Konstrukcja
Amigi nakîada ograniczenie na dîugoôê cyklu Zorro III, wynoszâce okoîo 1
mikrosekundy. Jeûeli w tym czasie cykl sië nie zakoïczy, jest on
przerywany i generowany jest bîâd magistrali. Aby nie dopuôciê do
zawieszenia systemu Prometeusz nie powtarza cyklu na ûâdanie "Retry",
zwracajâc (w wypadku operacji odczytu) wartoôê $FFFFFFFF. W takim
przypadku naleûy operacjë odczytu powtórzyê. Rozwiâzanie takie pokazane
jest w kodzie úródîowym programu RomDump.


@{I}UWAGA: @{UI}

Jak na razie jedyny stwierdzony przypadek opisanej sytuacji to odczyt
pamiëci ROM karty Voodoo3.

@ENDNODE
@NODE interrupts "Obsîuga przerwaï"
@{B}Obsîuga przerwaï kart PCI @{UB}


Specyfikacja magistrali PCI przewiduje 4 linie przerwaï oznaczone od
@{B}INTA @{UB}do @{B}INTD@{UB}. Linie te sâ asynchroniczne wzglëdem
zegara PCI, a wiëc kaûda karta moûe zgîosiê przerwanie (podajâc na jednâ
z linii niski stan logiczny) w dowolnym momencie. Prometeusz obsîuguje
wszystkie cztery linie przerwaï. Wystapienie przerwania na dowolnej z
nich powoduje przekazanie go na linië @{B}INT2 @{UB}szyny Zorro III.


Procedurë obsîugi przerwania dodaje sië do systemu w tradycyjny sposób,
korzystajâc z funkcji @{I}AddIntServer(). @{UI}Oto przykîadowy kod w C:


@{FG HIGHLIGHT}struct Interrupt *InstallInterrupt(APTR useful_data, APTR my_int_code)

 {

  struct Interrupt *my_int;


  if (my_int = AllocMem(sizeof(struct Interrupt), MEMF_PUBLIC | MEMF_CLEAR))

   {

    my_int->is_Node.ln_Type = NT_INTERRUPT;

    my_int->is_Node.ln_Name = "My clever interrupt routine";

    my_int->is_Data = useful_data;

    my_int->is_Code = my_int_code;

    AddIntServer(INTB_PORTS, my_int);

    return my_int;

   }

  return NULL;

 }@{FG TEXT}


Parametr @{I}my_int_code @{UI}to adres funkcji obsîugujâcej przerwanie,
w parametrze @{I}useful_data @{UI}moûna przekazaê wskaúnik do dowolnych
danych, które bëdâ potrzebne w czasie obsîugi przerwania. W procedurze
obsîugi przerwania naleûy przede wszystkim sprawdziê, czy przerwanie
zostaîo wygenerowane przez naszâ kartë (sprawdzajâc jej rejestry
odpowiedzialne za generowanie przerwaï). Jeôli nie, naleûy ustawiê
znacznik Z procesora przy wyjôciu z funkcji (w wiëkszoôci kompilatorów
wyraûenie 'return 0' ustawia znacznik Z). W przeciwnym wypadku
obsîugujemy przerwanie a przy wyjôciu kasujemy znacznik Z (w wiëkszoôci
kompilatorów wyraûenie 'return 1' kasuje znacznik Z). Oto przykîad
zaczerpniëty ze sterownika do kart sieciowych na ukîadzie RTL8029:


@{FG SHINE}/* a0, a1, d0, d1 are trash registers here */

/* compiler should save other regs on the stack. */


LONG IntCode (struct TaskData *td reg(a1))

 {

  UBYTE intstatus;


  if (intstatus = td->td_EtherBase->regs[NE2000_INT_STATUS])

   {

    td->td_EtherBase->regs[NE2000_INT_STATUS] = 0xFF;

    if (intstatus & INT_RXPACKET) PacketReceived(td);

    /* ... */

    return 1;

   }

  return 0;

 }@{FG TEXT}


Na wejôciu do procedury przerwania otrzymujemy w rejestrze A1 procesora
wskaúnik do danych umieszczonych wczeôniej w polu @{I}is_Data @{UI}
struktury @{I}Interrupt. @{UI}W procedurze moûemy dowolnie uûywaê tylko
rejestrów D0, D1, A0, A1, A5 i A6, pozostaîe muszâ byê przechowane na
stosie. Kompilatory jëzyka C automatycznie zapewniajâ speînienie tego
warunku. Oczywiôcie do procedury obsîugi przerwaï kart PCI stosujâ sië
wszystkie reguîy zawarte w orpowiednim rozdziale @{I}ROM Kernel
Manuals. @{UI}Piszâc procedury przerwaï w innych systemach operacyjnych
(Linux, NetBSD) naleûy przestrzegaê zasad obowiâzujâcych w tych
systemach.

@ENDNODE
@NODE change_log "Wykaz zmian"

@{B}Wykaz zmian w oprogramowaniu @{UB}


@{I}Wersja 1.50 (25 lipca 2001) @{UI}

@TAB 3
@{LINDENT 3}@{PARI -2}@{B} *@{TAB}@{UB}Usuniëto bîâd inicjalizacji
wewnëtrznej listy kart PCI objawiajâcy sië wpadaniem programu PrmScan w
nieskoïczonâ pëtlë, jeûeli w Prometeuszu nie byîo ûadnej karty
PCI.@{PARD}


@{LINDENT 3}@{PARI -2}@{B} *@{TAB}@{UB}Funkcji Prm_FindBoardTagList() moûna teraz podaê NULL jako
adres listy tagów. Jest to równoznaczne z pustâ listâ tagów (zawierajâcâ
jedynie TAG_END). Poprawiono autodoce.@{PARD}


@{LINDENT 3}@{PARI -2}@{B} *@{TAB}@{UB}Dodano zabezpieczenie w funkcji Prm_GetBoardAttrsTagList()
przed podaniem zera w polu ti_Data taga. Wczeôniej powodowaîo to zapis
dîugiego sîowa pod adres $00000000.@{PARD}


@{LINDENT 3}@{PARI -2}@{B} *@{TAB}@{UB}Dodano pliki nagîówkowe do
kompilatorów VBCC, StormC, SAS/C. Poprawiono drobne bîëdy w plikach dla
GCC. Programy przykîadowe powinny sië teraz kompilowaê pod kaûdym
popularnym kompilatorem C na Amigë.@{PARD}


@{I}Wersja 1.49 (7 lipca 2001) @{UI}

@TAB 3
@{LINDENT 3}@{PARI -2}@{B} *	@{UB}Zmieniono sposób inicjalizacji
biblioteki, teraz nie korzysta ona z komendy BindDrivers i zostaîa
przeniesiona z katalogu @{I}SYS:Expansion/ @{UI}do katalogu @{I}LIBS:. @{UI}

@ENDNODE

