PrettyOS Fehler-/Testthread
-
Da Host System Error in PCI-Problem ist, habe ich nun folgendes hinzugefügt in pci.c, damit wir mit PCI/EHCI/USB2 weiter kommen:
void analyzeHostSystemError(uint32_t num) { uint8_t bus = pciDev_Array[num].bus; uint8_t dev = pciDev_Array[num].device; uint8_t func = pciDev_Array[num].func; // check pci status register of the device uint32_t pciStatus = pci_config_read(bus, dev, func, PCI_STATUS); settextcolor(12,0); printf("pci status word: %x\n",pciStatus); // bits 0...2 reserved if(pciStatus & 1<< 3) printf("Interrupt Status\n"); if(pciStatus & 1<< 4) printf("Capabilities List\n"); if(pciStatus & 1<< 5) printf("66 MHz Capable\n"); // bit 6 reserved if(pciStatus & 1<< 7) printf("Fast Back-to-Back Transactions Capable\n"); if(pciStatus & 1<< 8) printf("Master Data Parity Error\n"); // DEVSEL Timing: bits 10:9 if(pciStatus & 1<<11) printf("Signalled Target-Abort\n"); if(pciStatus & 1<<12) printf("Received Target-Abort\n"); if(pciStatus & 1<<13) printf("Received Master-Abort\n"); if(pciStatus & 1<<14) printf("Signalled System Error\n"); if(pciStatus & 1<<15) printf("Detected Parity Error\n"); settextcolor(15,0); }
das zeigt bei dem PC, der Host System Error alarmiert, folgendes:
- capabilities list
- fast back to back transaction
- master abortfür "fast back to back transaction" steht bei low level:
Wenn diese Bit gesetzt ist bedeutet dasss dass das betreffende PCI-Gerät die minimal schnelleren Back-to-Back Transfers unterstützt. Als Target werden diese Transfers immer unterstützt, aber als Master dürfen diese Transfers nur benutzt werden falls das Bit 9 im Command-Register gesetzt ist.
bezüglich master abort: nix
-
Revision 374
// ehci.c 374 void resetPort(uint8_t j) { pOpRegs->PORTSC[j] |= PSTS_POWERON; /* http://www.intel.com/technology/usb/download/ehci-r10.pdf (...) */ pOpRegs->PORTSC[j] &= ~PSTS_ENABLED; }
Der Kommentar aus dem Manual betrifft PSTS_PORT_RESET und nicht PSTS_POWERON.
Mein realer PC hat lt. Scan 10 USB-Ports. Davon sind aber nur 9 "von außen" verfügbar. Deshalb wird ein Port (jedesmal der gleiche) ständig als "power on, enabled, EHCI owned" angezeigt. Unabhängig davon ob nun ein USB-Gerät "eingeklinkt" ist/wird oder nicht. Dieser Port zeigt auch (ganz selten aber) mal "J-Status" an.
Außerdem kann es ganz, ganz, ganz selten passieren, daß die untere Statuszeile nach > 200 Sekunden für eine Sekunde Unsinn anzeigt (z.B. 55:55:5555 als Uhrzeit).
-
Revision 391
// ckernel.c rev 391 static void init() { // kernel_console_init(); // clear_screen(); gdt_install(); idt_install(); kernel_console_init(); clear_screen();
Besser die Deskriptoren zu aller erst installieren und danach den "Rest". VMWARE hatte mal in früheren Revisionen in "kernel_console_init" Mist gemacht woraus dann ein Triplefault resultierte. USB rev 391 funktioniert auf meinem realen PC auch.
-
USB rev 391 funktioniert auf meinem realen PC auch.
Danke für den Hinweis! Diese Version sollten wir nun zu einer stabilen, brauchbaren Basis ausbauen, bevor wir neue Experimente aufsetzen.
-
Revision 398
Hm, einmal würde reichen.// ckernel.c 398 static void init() { (...) // descriptors gdt_install(); idt_install(); // cf. interrupts.asm // descriptors gdt_install(); idt_install(); // cf. interrupts.asm // video kernel_console_init(); clear_screen(); (...) }
-
oh, das stimmt natürlich, wird geändert.
Danke
-
Revision 401
Da haben sich einige "Rechtschreibfehler" eingeschlichen:// usb2.c 401 void showConfigurationDesriptor(struct usb2_configurationDescriptor* d) (...)
Desriptor -> Descriptor
(Btw.: Wollt ihr den CDI-Kram auch mal einsetzen?)
-
Ja, wir würden ihn gerne einsetzen, aber das setzt Einsatzbereitschaft voraus: Die Implementation ist nichtmal ansatzweise fertig.
-
Da haben sich einige "Rechtschreibfehler" eingeschlichen
Danke!
Bevor wir noch beim Raptor enden, haben wir es korrigiert.
-
Wollt ihr den CDI-Kram auch mal einsetzen?
Wenn Du uns beim USB bulk transfer bei der Fehlersuche hilfst, kommen wir schneller daran.
-
Revision 434
Auf meinem realen PC funktioniert eine stark zusammengestrichene testMSD() perfekt:
// usb2_msd.c 434 void testMSD(uint8_t devAddr) { // maxLUN (0 for USB-sticks) usbDevices[devAddr].maxLUN = 0; usbTransferBulkOnlyMassStorageReset(devAddr, usbDevices[devAddr].numInterfaceMSD); // Reset Interface ///////// step 7: send SCSI comamnd "read(10)", read one block (512 byte) from LBA ..., get Status textColor(0x09); printf("\n>>> SCSI: read(10)"); textColor(0x0F); usbSendSCSIcmd(devAddr, usbDevices[devAddr].numEndpointOutMSD, usbDevices[devAddr].numEndpointInMSD, 0x28, 0, 1, true); waitForKeyStroke(); }
Aber ein zweiter Aufruf von usbSendSCSIcmd() innerhalb von testMSD() geht regelmäßig schief. Irgendwas stimmt mit den blöden Adressen noch nicht.
VMs schummeln ja immer in dieser Hinsicht.
-
stimmt, der einmalige Aufruf einer Funktion ging bisher immer recht gut, nur die Abfolge macht Probleme. Schau dir bitte mal die rev. 435 an.
Noch besser: die Version 436 mit aktiviertem #define _USB_DIAGNOSIS_ (ging vorher nicht fehlerfrei)
Ich habe noch ein "test unit ready" vor "inquiry" gesetzt, dann hakt es beim IN-endpoint bei "inquiry" aus, was zuvor an Platz eins bestens lief. Der QH/qTD-Code ist also prinzipiell ok.
Nimmt man zweimal inquiry hintereinander:
- erstes läuft gut
- beim zweiten "inquiry" wird der IN-QueueHead nicht mehr ausgeführtdev: 3 interface: 0 endpOUT: 2 endpIN: 1
USB2: usbTransferBulkOnlyMassStorageReset, dev: 3 interface: 0#
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''> SCSI: inquiry
OUT part#
IN part transfer>0#
virtAddrBuf0 C024D000h : 00h 80h 02h 02h 1Fh 00h 00h 00h 6Dh 65h 6Dh 6Fh 72h 79h
00h 00h 55h 53h 42h 32h 2Eh 30h 00h 00h 00h 00h 00h 00h 00h 00h 00h 00h 31h 2Eh
30h 30h
virtAddrBuf0 C024D000h : memoryUSB2.01.00virtAddrBuf0 C024C000h : 55h 53h 42h 53h 12h 42h 42h 42h 00h 00h 00h 00h 00h
Command Passed ("good status")
qTD Status: 00h OK (no bit set)<-- data
qTD Status: 00h OK (no bit set)<-- statusCommand Block Status Values in "good status"
> Press key <<<
> SCSI: inquiry
OUT part#
IN part transfer>0###################
timeout - no STS_USBINT set!
virtAddrBuf0 C0253000h : 00h 00h 00h 00h 00h 00h 00h 00h 00h 00h 00h 00h 00h 00h
00h 00h 00h 00h 00h 00h 00h 00h 00h 00h 00h 00h 00h 00h 00h 00h 00h 00h 00h 00h
00h 00h
virtAddrBuf0 C0253000h :virtAddrBuf0 C0252000h : 55h 53h 42h 53h AAh AAh AAh AAh AAh AAh AAh AAh AAh
qTD Status: 80h Active - HC transactions enabled<-- data
qTD Status: 80h Active - HC transactions enabled<-- statusBeide an den IN-QH angehängten qTD werden nicht ausgeführt, obwohl es beim ersten Durchgang problemlos abgearbeitet wird.
-
Irgendwas stimmt mit den blöden Adressen noch nicht.
@+gjm*: kannst du das genauer spezifizieren? Ich sehe beim speicher kein problem.
Die neue Rev. 437 ist etwas besser geeignet für Versuche.
-
Rev. 439 bietet nun den besten Überblick über den Transfer im qTD-Bereich.
-
Mit Rev. 441 haben wir eine erste stabile Plattform bei USB Mass Storage Device erzielt. Wenn sich dies stabilisiert können wir die Floppy bald in "Rente" schicken.
-
<RAM Disk at C0002000h DIR> dev 35 infošºíÆ×íí-îù̬Åîí^Àì?¬ÎNèTÝUÅË 9796 shell¤¼ìŽž„œššDþ„TôÁŽÅÞŽHÚÎÌŸË.[
Hier wurde offenbar etwas "kaputt" optimiert. Da fehlt das abschließende '\0'.
EDIT: wurde inzwischen repariert (neues strncpy)
-
Rev. 444 zeigt den oberflächlichen Grund, warum Transfers nicht laufen (qTD Status 0x80 (= active bit7) wird nicht zurück gesetzt und qTD nicht ausgeführt):
Es liegt am NAK counter. Setzt man RL (reload Nak Counter) auf 15 (4-bit-value), dann findet man bei manchen Devices NAK counter = 0, also 15 mal NAK. Dann bleibt der EHCI hilflos stehen.http://www.lowlevel.eu/wiki/USB (von XanClic):
Hier schickt der Host zuerst einmal das Datenpaket, kann das Gerät dieses nicht annehmen, antwortet es mit NAK. Wenn es das Paket empfangen kann, antwortet es mit ACK, wenn das Gerät danach noch ein Paket aufnehmen kann oder mit NYET, wenn nicht. Hat der Host ACK empfangen, so sendet er das nächste Paket. Hat er allerdings ein NYET oder ein NAK erhalten, dann beginnt er nun mit PING-Paketen. Das Gerät muss mit NAK antworten, wenn es immer noch kein Paket empfangen kann, oder mit ACK, wenn es nun bereit ist. Dies verringert die Anzahl an sinnlos gesendeten Daten natürlich erheblich. Das Gerät kann hierbei sogar angegeben, wann das nächste PING-Paket gesendet werden soll (der Host muss dies aber nicht befolgen).
Der NAK counter zählt auch NYET, wenn ich das richtig verstanden habe.
-
Revision 447
Sherlock Holmes schrieb:
Wenn man alles Unmögliche ausgeschlossen hat, muss in dem, was noch übrigbleibt, so unwahrscheinlich es auch scheinen mag, die Wahrheit zu finden sein.
^^ In diesem Sinne:
Nach jedem Aufruf von usbSendSCSIcmd (usb2_msd.c) geht das verloren, was der Aufruf von usbTransferSetConfiguration (usb2.c) in checkPortLineStatus (ehci.c) bewirkt hatte.
// usb2_msd.c 447 void testMSD(uint8_t devAddr) { (...) ///////// step 1: send SCSI comamnd "inquiry (opcode: 0x12)" textColor(0x09); printf("\n>>> SCSI: inquiry"); textColor(0x0F); //=====================================DEBUG============================ usbTransferSetConfiguration(devAddr,1); // usbTransferBulkOnlyMassStorageReset(devAddr, usbDevices[devAddr].numInterfaceMSD); // Reset Interface //=====================================DEBUG============================ usbSendSCSIcmd(...); ///////// step 2: send SCSI comamnd "test unit ready(6)" textColor(0x09); printf("\n>>> SCSI: test unit ready"); textColor(0x0F); //=====================================DEBUG============================ usbTransferSetConfiguration(devAddr,1); // usbTransferBulkOnlyMassStorageReset(devAddr, usbDevices[devAddr].numInterfaceMSD); // Reset Interface //=====================================DEBUG============================ usbSendSCSIcmd(...); // (usw.) }
^^ So läufts auf meinem realen PC.
-
Danke für den Tipp!
-
Ich habe das jetzt objektiv getestet:
- lief auch schon vorher auf real PC
- es gibt in der Tat usb-sticks, die die configuration zurück auf 0 setzen! Kann man mit getConfig ja vorher testen
- aber jetzt kommt es:
PrettyOS [Version 0.0.0.449] Console 1: EHCI Ports
--------------------------------------------------------------------------------
USB2: SET_CONFIGURATION 1>!
USB2: GET_CONFIGURATION>! 1
OUT part
asyncList: 01667000h <-- QH_Out CommandQTD: 01669000h
before aS:
curr QH: 01667000h next QH: 01667000h
curr qTD: 00000000h next qTD: 01669000h
NAK counter: 0>!
after aS:
curr QH: 01667000h next QH: 01667000h
curr qTD: 01669000h next qTD: 00000000h
NAK counter: 15
IN part
asyncList: 01668000h <-- QH_In
handshakeQTD: 0166B000h StatusQTD: 0166D000h DataQTD: 0166F000h
before aS:
curr QH: 01668000h next QH: 01668000h
curr qTD: 00000000h next qTD: 0166F000h
NAK counter: 0>!
after aS:
curr QH: 01668000h next QH: 01668000h
curr qTD: 0166B000h next qTD: 00000000h
NAK counter: 15
00h 80h 02h 02h 1Fh 00h 00h 00h 6Dh 65h 6Dh 6Fh 72h 79h 00h 00h 55h 53h 42h 32h
2Eh 30h 00h 00h 00h 00h 00h 00h 00h 00h 00h 00h 31h 2Eh 30h 30h
memoryUSB2.01.0055h 53h 42h 53h 12h 42h 42h 42h 00h 00h 00h 00h 00h
Command Passed ("good status")
qTD Status: 01h Do Ping<-- command
qTD Status: 00h OK (no bit set)<-- data
qTD Status: 00h OK (no bit set)<-- status
USB2: GET_CONFIGURATION>! 0
USB2: SET_CONFIGURATION 1>!
USB2: GET_CONFIGURATION>! 0Command Block Status Values in "good status"
USB status: 00002000h
Reclamation> Press key <<<
--------------------------------------------------------------------------------
Port: 1, device attachedVor "inquiry" ist alles ok.
Nach "inquiry" sitzt die configuration auf 0 (bedeutet unkonfiguriert) und lässt sich aber auch nicht mehr gerade biegen auf 1.@+gjm+: Echt Superklasse dein Fund! Wie machst du das bloß?