| Zeile 226: | Zeile 226: | ||
Der folgende C-Code analysiert alle BARs im Konfigurations-Adressraum eines PCI-Gerätes und gibt alle verfügbaren Informationen aus. Dieser Code sollte möglichst nicht auf aktivierte PCI-Geräte angewendet werden, falls doch wäre es geschickt den Vorgang atomar zu gestalten und alle BARs vorher zu sichern und hinter zu restaurieren. Außerdem sollten die Bits 0 und 1 des Command-Registers gelöscht sein. | Der folgende C-Code analysiert alle BARs im Konfigurations-Adressraum eines PCI-Gerätes und gibt alle verfügbaren Informationen aus. Dieser Code sollte möglichst nicht auf aktivierte PCI-Geräte angewendet werden, falls doch wäre es geschickt den Vorgang atomar zu gestalten und alle BARs vorher zu sichern und hinter zu restaurieren. Außerdem sollten die Bits 0 und 1 des Command-Registers gelöscht sein. | ||
<c>/*** Diesen Code darf jeder, unter Berücksichtigung der Lizenz für diesen Wiki-Artikel, zu jedem Zweck kopieren, nutzen und verändern! | <c>/*** Diesen Code darf jeder, unter Berücksichtigung der Lizenz für diesen Wiki-Artikel, zu jedem Zweck kopieren, nutzen und verändern! | ||
| − | (C) <http://lowlevel. | + | (C) <http://www.lowlevel.eu/> ***/ |
| Zeile 283: | Zeile 283: | ||
if ( (pci_config_readd(addr,barOffset) & 0x1) == 0 ) | if ( (pci_config_readd(addr,barOffset) & 0x1) == 0 ) | ||
{ // Speicher-Ressource : | { // Speicher-Ressource : | ||
| + | |||
| + | // Prefetchable-Bit auslesen : | ||
static const char* ptext_pref = "prefetchable"; //Text für prefetchable | static const char* ptext_pref = "prefetchable"; //Text für prefetchable | ||
static const char* ptext_nopr = "non-prefetchable"; //Text für non-prefetchable | static const char* ptext_nopr = "non-prefetchable"; //Text für non-prefetchable | ||
const char* const ptext = (((pci_config_readd(addr,barOffset) >> 3) & 0x1) == 1) ? ptext_pref : ptext_nopr; | const char* const ptext = (((pci_config_readd(addr,barOffset) >> 3) & 0x1) == 1) ? ptext_pref : ptext_nopr; | ||
| − | switch | + | // check Memory-BAR-Type : |
| + | switch((pci_config_readd(addr,barOffset) >> 1) & 0x3) | ||
{ | { | ||
case 0x0: // 32Bit Memory-BAR : | case 0x0: // 32Bit Memory-BAR : | ||
| Zeile 295: | Zeile 298: | ||
if (barValue == 0) // es muss mindestens ein Adressbit 1 (also beschreibbar) sein | if (barValue == 0) // es muss mindestens ein Adressbit 1 (also beschreibbar) sein | ||
{ | { | ||
| − | if (ptext != ptext_nopr) // unbenutzte BARs müssen komplett 0 sein | + | if (ptext != ptext_nopr) // unbenutzte BARs müssen komplett 0 sein (auch das Prefetchable-Bit darf nicht gesetzt sein) |
{ printf("FEHLER : 32Bit-Memory-BAR %u enthält keine beschreibbaren Adressbits!\n",bar); return; } | { printf("FEHLER : 32Bit-Memory-BAR %u enthält keine beschreibbaren Adressbits!\n",bar); return; } | ||
| Zeile 316: | Zeile 319: | ||
case 0x1: // 20Bit Memory-BAR : | case 0x1: // 20Bit Memory-BAR : | ||
{ | { | ||
| + | if (headerType == 0x01) | ||
| + | { printf("FEHLER : 20Bit-Memory-BAR %u ist für eine Bridge nicht erlaubt!\n",bar); return; } | ||
| + | |||
pci_config_writed(addr,barOffset,0xFFFFFFF0); // mit lauter 1en überschreiben | pci_config_writed(addr,barOffset,0xFFFFFFF0); // mit lauter 1en überschreiben | ||
const uint32_t barValue = pci_config_readd(addr,barOffset) & 0xFFFFFFF0; //und wieder zurücklesen | const uint32_t barValue = pci_config_readd(addr,barOffset) & 0xFFFFFFF0; //und wieder zurücklesen | ||
| Zeile 393: | Zeile 399: | ||
} | } | ||
} | } | ||
| + | if (bar != max_bars) | ||
| + | { printf("interner Fehler in Schleife!\n"); return; } | ||
}</c> | }</c> | ||