Super-I/O-Chip-Ermittlung/CPU-Core-Spannung

Hardware- und Elektronikbasteleien, Ansteuerung von Schnittstellen und Peripherie.
Fragen zu "Consumer"-Problemen kommen in Offtopic.
Benutzeravatar
Helle
Beiträge: 566
Registriert: 11.11.2004 16:13
Wohnort: Magdeburg

Super-I/O-Chip-Ermittlung/CPU-Core-Spannung

Beitrag von Helle »

Super-I/O-Chips sind auf dem Motherboard u.a. auch für den Hardware-Monitor zuständig. Nachfolgender Code ermittelt mit Hilfe von giveio.sys den Chip-Typ (soweit in meiner Liste vorhanden):

Code: Alles auswählen

;- Super-I/O-Chip ermitteln, 32-Bit-Windows
;- "Helle" Klaus Helbing, 22.08.2009, PB 4.40B2(x86)

Adr.w
Z.b

AU$ = "Asus " 
FT$ = "FinTek "
IT$ = "ITE "
NS$ = "National Semiconductor "
SM$ = "SMSC "
VT$ = "VIA "
WB$ = "Winbond "

IO$ = "Der Chip konnte nicht identifiziert werden !"

XIncludeFile "giveio.pbi"    ;enthält auch giveio.sys als Data, gibt´s hier: http://www.mdcc-fun.de/k.helbing/giveio/giveio.zip

;------------------ Programm-Anfang Portzugriff
;Messages = 1                 ;für Fehlersuche oder reine Neugier, gilt für giveio.pbi
RegTest()                    ;ob giveio in Registry vorhanden
If hReg
  Abfrage = MessageRequester("Abfrage", "Soll giveio installiert werden ?", #PB_MessageRequester_YesNo)
  If Abfrage = #PB_MessageRequester_Yes
    DienstInst()             ;war noch nicht installiert
   Else
    End 
  EndIf  
EndIf 
hMgr = OpenSCManager_(#Null, #Null, #GENERIC_READ)    ;Handle für Zugriff auf den Dienst-Manager
DienstStatus()               ;bei Programmstart überprüfen
If SS\dwCurrentState <> 4    ;4=schon gestartet
  DienstStart()              ;noch nicht gestartet, also jetzt starten
EndIf 

OpenDevice()                 ;jetzt sind Port-Zugriffe möglich

;------------------------------------------------------------------------------ 
For Adr = $2E To $4E Step $20
  ;Test, ob FinTek, VIA oder Winbond
  OutB(Adr, $87)             ;Einschalten des Extended Function Mode für FinTek, VIA und Winbond
  OutB(Adr, $87)             ;muss 2x aufgerufen werden!

  OutB(Adr, $20)             ;Configurations-Register $20 auslesen
  InB(Adr + 1)
  CR20 = WertB & $FF
  If CR20 <> 0 And CR20 <> $FF 
    Select CR20
      Case $02
        OutB(Adr, $21)       ;Configurations-Register $21 auslesen
        InB(Adr + 1)
        CR21 = WertB & $FF
        Select CR21
          Case $06
            IO$ = FT$ + "F81218D"
          Case $08
            IO$ = FT$ + "F81216D"
        EndSelect      
      Case $03
        OutB(Adr, $21)       ;Configurations-Register $21 auslesen
        InB(Adr + 1)
        CR21 = WertB & $FF
        Select CR21
          Case $41
            IO$ = FT$ + "F71806FG/F71872FG"
        EndSelect      
      Case $04
        OutB(Adr, $21)       ;Configurations-Register $21 auslesen
        InB(Adr + 1)
        CR21 = WertB & $FF
        Select CR21
          Case $06
            IO$ = FT$ + "F71805F/FG"
        EndSelect
      Case $05
        OutB(Adr, $21)       ;Configurations-Register $21 auslesen
        InB(Adr + 1)
        CR21 = WertB & $FF
        Select CR21
          Case $07
            IO$ = FT$ + "F71858DG"
          Case $41
            IO$ = FT$ + "F71882FG/F71883FG"
          Case $81
            IO$ = AU$ + "F8000"   ;soll Asus sein!
        EndSelect
      Case $06
        OutB(Adr, $21)       ;Configurations-Register $21 auslesen
        InB(Adr + 1)
        CR21 = WertB & $FF
        Select CR21
          Case $01
            IO$ = FT$ + "F71862FG"
        EndSelect
      Case $3C
        IO$ = VT$ + "VT1211" 
      Case $3E
        IO$ = VT$ + "VT1212 in 100 pin TQFP package" 
      Case $3F
        IO$ = VT$ + "VT1212 in 48 pin LQFP package" 
      Case $52
        IO$ = WB$ + "W83627HF/F/HG/G" 
      Case $60
        IO$ = WB$ + "W83697HF/F/HG" 
      Case $61
        IO$ = WB$ + "W83L517D" 
      Case $68
        IO$ = WB$ + "W83697SF/UF/UG" 
      Case $70
        IO$ = WB$ + "W83637HF/HG" 
      Case $82
        IO$ = WB$ + "W83627THF/THG" 
      Case $85
        IO$ = WB$ + "W83687THF" 
      Case $87
        OutB(Adr, $21)       ;Configurations-Register $21 auslesen
        InB(Adr + 1)
        CR21 = WertB & $FF
        Select CR21
          Case $08
            IO$ = IT$ + "IT8708F" ;soll ITE sein!
        EndSelect
      Case $88
        OutB(Adr, $21)       ;Configurations-Register $21 auslesen
        InB(Adr + 1)
        CR21 = WertB & $C0 
        Select CR21
          Case $40
            IO$ = WB$ + "W83627EHF/EF/EHG/EG"
        EndSelect
      Case $A0
        OutB(Adr, $21)       ;Configurations-Register $21 auslesen
        InB(Adr + 1)
        CR21 = WertB & $F0 
        Select CR21
          Case $20
            IO$ = WB$ + "W83627DHG" : Res = 3    ;Res für VCORE, für 8mV z.B ist Res=3 (2^3=8)
        EndSelect
    EndSelect  
  EndIf                      ;Ende FinTek, VIA oder Winbond
  ;--------------------------------------------------------------------------------------
  ;Test, ob ITE
  OutB(Adr, $87)             ;Einschalten des Extended Function Mode für ITE
  OutB(Adr, $01)
  OutB(Adr, $55)
  OutB(Adr, $55 + Z)         ;für $2E=$55, für $4E=$AA

  OutB(Adr, $20)             ;Configurations-Register $20 auslesen
  InB(Adr + 1)
  CR20 = WertB & $FF
  If CR20 <> 0 And CR20 <> $FF 
    Select CR20
      Case $87
        OutB(Adr, $21)       ;Configurations-Register $21 auslesen
        InB(Adr + 1)
        CR21 = WertB & $FF
        Select CR21
          Case $02
            IO$ = IT$ + "IT8702F"
          Case $05
            IO$ = IT$ + "IT8705F"
          Case $12
            IO$ = IT$ + "IT8712F"
          Case $16
            IO$ = IT$ + "IT8716F"
          Case $18
            IO$ = IT$ + "IT8718F"
          Case $20
            IO$ = IT$ + "IT8720"
          Case $26
            IO$ = IT$ + "IT8726F"
        EndSelect 
    EndSelect 
  EndIf                      ;Ende ITE
  ;--------------------------------------------------------------------------------------
  ;Test, ob SMSC
  OutB(Adr, $55)             ;Einschalten des Extended Function Mode für SMSC
  OutB(Adr, $20)             ;Configurations-Register $20 auslesen
  InB(Adr + 1)
  CR20 = WertB & $FF
  If CR20 <> 0 And CR20 <> $FF 
    Select CR20
      Case $0E   
        IO$ = SM$ + "LPC47N252"
      Case $14   
        IO$ = SM$ + "LPC47M172"
      Case $40   
        IO$ = SM$ + "FDC37C672"
      Case $42   
        IO$ = SM$ + "FDC37M707"
      Case $44   
        IO$ = SM$ + "FDC37B78x"
      Case $4C   
        IO$ = SM$ + "FDC37B72x"
      Case $4D   
        IO$ = SM$ + "FDC37M81x"
      Case $51   
        IO$ = SM$ + "LPC47B27x"
      Case $52   
        IO$ = SM$ + "LPC47B37x"
      Case $54   
        IO$ = SM$ + "LPC47U33x"
      Case $56   
        IO$ = SM$ + "LPC47B34x"
      Case $57   
        IO$ = SM$ + "LPC47S42x"
      Case $59   
        IO$ = SM$ + "LPC47M10x/112/13x"
      Case $5D   
        IO$ = SM$ + "LPC47B357/M967"
      Case $5F   
        IO$ = SM$ + "LPC47M14x"
      Case $60   
        IO$ = SM$ + "LPC47M15x/192/997"
      Case $62   
        IO$ = SM$ + "LPC47S45x"
      Case $67   
        IO$ = SM$ + "EMC2700LPC"
      Case $6B   
        IO$ = SM$ + "LPC47M292"
      Case $6D   
        IO$ = SM$ + "LPC47B367-NC"
      Case $6F   
        IO$ = SM$ + "LPC47B397-NC"
      Case $74   
        IO$ = SM$ + "LPC47M182"
      Case $76   
        IO$ = SM$ + "LPC47M584-NC"
      Case $77, $78    
        IO$ = SM$ + "DME1737"
      Case $79    
        IO$ = SM$ + "SCH5504-NS"
      Case $7C    
        IO$ = SM$ + "SCH3112"
      Case $7D    
        IO$ = SM$ + "SCH3114"
      Case $7F    
        IO$ = SM$ + "SCH3116"
      Case $81    
        IO$ = SM$ + "SCH5307-NS"
      Case $83    
        IO$ = SM$ + "SCH5514D-NS"
      Case $85, $8C    
        IO$ = SM$ + "SCH5317"
      Case $86    
        IO$ = SM$ + "SCH5127"
      Case $89    
        IO$ = SM$ + "SCH5027D-NW"
      Case $90    
        IO$ = SM$ + "SCH4307"
    EndSelect 
  EndIf
 
  ;SMSC benutzt auch das Configurations-Register $0D !
  OutB(Adr, $0D)             ;Configurations-Register $0D auslesen
  InB(Adr + 1)
  CR20 = WertB & $FF
  If CR20 <> 0 And CR20 <> $FF 
    Select CR20
      Case $03   
        IO$ = SM$ + "FDC37C669"
      Case $28   
        IO$ = SM$ + "FDC37N769"
      Case $5A   
        IO$ = SM$ + "LPC47N227"
      Case $65   
        IO$ = SM$ + "FDC37C665"
      Case $66   
        IO$ = SM$ + "FDC37C666"
    EndSelect 
  EndIf                      ;Ende SMSC
  ;--------------------------------------------------------------------------------------
  ;Test, ob National Semiconductor
  OutB(Adr, $20)             ;Configurations-Register $20 auslesen
  InB(Adr + 1)
  CR20 = WertB & $FF
  If CR20 <> 0 And CR20 <> $FF 
    Select CR20
      Case $D0    
        IO$ = NS$ + "PC87317"
      Case $DF    
        IO$ = NS$ + "PC97317"
      Case $E1    
        IO$ = NS$ + "PC87360"
      Case $E2    
        IO$ = NS$ + "PC87351"
      Case $E4    
        IO$ = NS$ + "PC87364"
      Case $E5    
        IO$ = NS$ + "PC87365"
      Case $E8    
        IO$ = NS$ + "PC87363"
      Case $E9    
        IO$ = NS$ + "PC87366"
      Case $EA    
        IO$ = NS$ + "PC8739x"
      Case $EC    
        IO$ = NS$ + "PC87591"
      Case $EE    
        IO$ = NS$ + "PC8741x"
      Case $F0    
        IO$ = NS$ + "PC87372"
      Case $F1    
        IO$ = NS$ + "PC8374L"
      Case $F2    
        IO$ = NS$ + "PC87427"
      Case $F3    
        IO$ = NS$ + "PC87373"
    EndSelect 
  EndIf                      ;Ende National Semiconductor 
  ;--------------------------------------------------------------------------------------
  Z + $55                    ;für Adresse ITE
Next  
 
If Mid(IO$, 1, 1) = "W" Or Mid(IO$, 1, 1) = "S"  ;für Winbond und SMSC
  OutB(Adr, $AA)             ;Beenden des Extended Function Mode für Winbond und SMSC
 Else 
  OutB(Adr, $02)             ;Beenden des Extended Function Mode für die anderen Chips
  OutB(Adr + 1, $02)
EndIf

MessageRequester("Super - I/O - Chip - Detection", IO$)

;------------------------------------------------------------------------------
;- Ende
If SS\dwCurrentState <> 4
  DienstEnd()                ;war vorher nicht gestartet, also jetzt wieder beenden
EndIf 

;DienstRemove()               ;bei Bedarf, evtl. Rechner-Neustart
 
CloseServiceHandle_(hMgr)    ;hier erst beenden

End 
Ist der Chip-Typ bekannt, kann man ihn zu allerlei Schabernack anzapfen. Auf meinem Asus-Mutterbrett ist ein Winbond (W83627DHG) aufgelötet; hier als Beispiel das Auslesen der CPU-Core-Spannung, wie sie auch im BIOS angezeigt wird:

Code: Alles auswählen

XIncludeFile "giveio.pbi"    ;enthält auch giveio.sys als Data, gibt´s hier: http://www.mdcc-fun.de/k.helbing/giveio/giveio.zip

;------------------ Programm-Anfang Portzugriff
RegTest()                    ;ob giveio in Registry vorhanden
If hReg
  Abfrage = MessageRequester("Abfrage", "Soll giveio installiert werden ?", #PB_MessageRequester_YesNo)
  If Abfrage = #PB_MessageRequester_Yes
    DienstInst()             ;war noch nicht installiert
   Else
    End 
  EndIf  
EndIf 
hMgr = OpenSCManager_(#Null, #Null, #GENERIC_READ)    ;Handle für Zugriff auf den Dienst-Manager
DienstStatus()               ;bei Programmstart überprüfen
If SS\dwCurrentState <> 4    ;4=schon gestartet
  DienstStart()              ;noch nicht gestartet, also jetzt starten
EndIf 

OpenDevice()
;jetzt sind Port-Zugriffe möglich

;hier kennen wir also schon den Chip-Typ mit der (VCORE-)Auflösung von 8mV/Bit
;- CPU-Core-Spannung für Winbond (W83627DHG)
Res = 3                      ;=8mV (2^3) aus Datenblatt bzw. IO-Chip-Detection
OutB($2E, $87)               ;Einschalten des Extended Function Mode für Winbond
OutB($2E, $87)               ;muss 2x aufgerufen werden!

OutB($2E, $7)                ;Logical Device auswählen
OutB($2F, $B)                ;$B=Hardware-Monitor

OutB($2E, $60)               ;High-Byte Register Address Base
InB($2F)
Adr = WertB & $FF
Adr << 8                     ;nach Word-High schieben  

OutB($2E, $61)               ;Low-Byte Register Address Base
InB($2F)
Adr + (WertB & $FF)          ;+5=Address Port, +6=Data Port
;Index $4E, Bits 0-2=Bank setzen, %000=Bank 0 usw.
OutB(Adr + 5, $4E)
InB(Adr + 6)
WertB & %11111000            ;Bank 0 setzen
OutB(Adr + 5, $4E)
OutB(Adr + 6, WertB)

OutB(Adr + 5, $20)           ;$20=CPUVCORE
InB(Adr + 6)

OutB($2E, $AA)               ;Beenden des Extended Function Mode für Winbond

VC = (WertB & $FF) << Res    ;Res=Auflösung, für 8mV z.B ist Res=3, 2^3=8

MessageRequester("Momentane CPU - Core - Spannung", StrF(VC / 1000, 3) + "V")
Diese Routine ist Chip-Typ-abhängig, kann aber mit Hilfe der Chip-Dokumentation leicht an die eigenen Bedürfnisse angepasst werden.

Gruß
Helle
Zuletzt geändert von Helle am 22.08.2009 22:37, insgesamt 1-mal geändert.
DarkDragon
Beiträge: 6267
Registriert: 29.08.2004 08:37
Computerausstattung: Hoffentlich bald keine mehr
Kontaktdaten:

Beitrag von DarkDragon »

Cool, aber wo finde ich Informationen für meinen Chip?
---------------------------
Super - I/O - Chip - Detection
---------------------------
ITE IT8718F
---------------------------
OK
---------------------------
Bei mir geht das mit dem Spannungsauslesen auch :? . Ist das nicht unterschiedlich von Chip zu Chip?
Angenommen es gäbe einen Algorithmus mit imaginärer Laufzeit O(i * n), dann gilt O((i * n)^2) = O(-1 * n^2) d.h. wenn man diesen Algorithmus verschachtelt ist er fertig, bevor er angefangen hat.
Benutzeravatar
Helle
Beiträge: 566
Registriert: 11.11.2004 16:13
Wohnort: Magdeburg

Beitrag von Helle »

Habe oben im Spannungs-Beispiel ordentlicherweise das Beenden des Extended Function Mode eingefügt.
Die Dokumentationen für die Chips habe ich ganz einfach im Internet zusammengesucht, auch für den ITE IT8718F. Die Mechanismen zum Auslesen sind mitunter durchaus ähnlich, aber eben doch unterschiedlich. Für den ITE würde ich erstmal so rangehen:

Code: Alles auswählen

;- CPU-Core-Spannung für ITE IT8718F 
Res = 4                      ;=16mV (2^4) aus Datenblatt
OutB(Adr, $87)               ;Einschalten des Extended Function Mode für ITE
OutB(Adr, $01)
OutB(Adr, $55)
OutB(Adr, $55)

OutB($2E, $7)                ;Logical Device auswählen
OutB($2F, $4)                ;$4=Environment Controller

OutB($2E, $30)               ;Environment Controller Activate

OutB($2E, $60)               ;High-Byte Register Address Base
InB($2F)
Adr = WertB & $FF
Adr << 8                     ;nach Word-High schieben  

OutB($2E, $61)               ;Low-Byte Register Address Base
InB($2F)
Adr + (WertB & $FF)          ;+5=Address Port, +6=Data Port
OutB(Adr + 5, $20)           ;$20=VCORE1
InB(Adr + 6)

OutB($2E, $02)               ;Beenden des Extended Function Mode
OutB($2E + 1, $02)

VC = (WertB & $FF) << Res    ;Res=Auflösung
Ist aber nur eine Trockenübung!

Gruß
Helle
Benutzeravatar
Rings
Beiträge: 971
Registriert: 29.08.2004 08:48

Beitrag von Rings »

Mal ne blöde zwischenfrage,
wie bekomme ich denn den giveio.sys unter
nem x64 (Hier vista64) zu laufen ?

[Update]

hab nach googeln hier was gefunden
um Portzugriffe z uermöglichen:

http://logix4u.net/Legacy_Ports/Paralle ... 4_bit.html
und hier:
http://openlibsys.org/
http://sourceforge.net/projects/winring0/


[/Update]
Rings hat geschrieben:ziert sich nich beim zitieren
Benutzeravatar
Helle
Beiträge: 566
Registriert: 11.11.2004 16:13
Wohnort: Magdeburg

Beitrag von Helle »

Hier die 64-Bit-Windows-Versionen. Ich kann es z.Z. nur mit Server 2003 testen, Rückmeldungen von Nutzern anderer 64-Bit-Win-Versionen erbeten :mrgreen: !
Verwendet wird die inpoutx64.dll; Link s.o. von Rings.

Code: Alles auswählen

;- Super-I/O-Chip ermitteln, 64-Bit-Windows (nur mit Windows Server 2003 getestet!)
;- "Helle" Klaus Helbing, 24.08.2009, PB 4.40B2(x64)
;- Genutzt wird die inpoutx64.dll (s.o. Link von Rings)

Adr.w
Z.b
WertB.b

AU$ = "Asus " 
FT$ = "FinTek "
IT$ = "ITE "
NS$ = "National Semiconductor "
SM$ = "SMSC "
VT$ = "VIA "
WB$ = "Winbond "

IO$ = "Der Chip konnte nicht identifiziert werden !"

If OpenLibrary(0, "inpoutx64.dll")          ;im selben Verzeichnis oder komplette Pfadangabe
  Prototype.i ProtoIOx64_0()                ;kein Parameter
  IOx64IsOpen.ProtoIOx64_0 = GetFunction(0, "IsInpOutDriverOpen")
  Prototype.i ProtoIOx64_1(PortAdr)         ;1 Parameter
  IOx64Inp32.ProtoIOx64_1 = GetFunction(0, "Inp32")
  Prototype.i ProtoIOx64_2(PortAdr, WertB)  ;2 Parameter
  IOx64Out32.ProtoIOx64_2 = GetFunction(0, "Out32")  

  If IOx64IsOpen() 
    For Adr = $2E To $4E Step $20
      ;Test, ob FinTek, VIA oder Winbond
      IOx64Out32(Adr, $87)             ;Einschalten des Extended Function Mode für FinTek, VIA und Winbond
      IOx64Out32(Adr, $87)             ;muss 2x aufgerufen werden!

      IOx64Out32(Adr, $20)             ;Configurations-Register $20 auslesen
      WertB = IOx64Inp32(Adr + 1)
      CR20 = WertB & $FF
      If CR20 <> 0 And CR20 <> $FF 
        Select CR20
          Case $02
            IOx64Out32(Adr, $21)       ;Configurations-Register $21 auslesen
            WertB = IOx64Inp32(Adr + 1)
            CR21 = WertB & $FF
            Select CR21
              Case $06
                IO$ = FT$ + "F81218D"
              Case $08
                IO$ = FT$ + "F81216D"
            EndSelect      
          Case $03
            IOx64Out32(Adr, $21)       ;Configurations-Register $21 auslesen
            WertB = IOx64Inp32(Adr + 1)
            CR21 = WertB & $FF
            Select CR21
              Case $41
                IO$ = FT$ + "F71806FG/F71872FG"
            EndSelect      
          Case $04
            IOx64Out32(Adr, $21)       ;Configurations-Register $21 auslesen
            WertB = IOx64Inp32(Adr + 1)
            CR21 = WertB & $FF
            Select CR21
              Case $06
                IO$ = FT$ + "F71805F/FG"
            EndSelect
          Case $05
            IOx64Out32(Adr, $21)       ;Configurations-Register $21 auslesen
            WertB = IOx64Inp32(Adr + 1)
            CR21 = WertB & $FF
            Select CR21
              Case $07
                IO$ = FT$ + "F71858DG"
              Case $41
                IO$ = FT$ + "F71882FG/F71883FG"
              Case $81
                IO$ = AU$ + "F8000"   ;soll Asus sein!
            EndSelect
          Case $06
            IOx64Out32(Adr, $21)       ;Configurations-Register $21 auslesen
            WertB = IOx64Inp32(Adr + 1)
            CR21 = WertB & $FF
            Select CR21
              Case $01
                IO$ = FT$ + "F71862FG"
            EndSelect
          Case $3C
            IO$ = VT$ + "VT1211" 
          Case $3E
            IO$ = VT$ + "VT1212 in 100 pin TQFP package" 
          Case $3F
            IO$ = VT$ + "VT1212 in 48 pin LQFP package" 
          Case $52
            IO$ = WB$ + "W83627HF/F/HG/G" 
          Case $60
            IO$ = WB$ + "W83697HF/F/HG" 
          Case $61
            IO$ = WB$ + "W83L517D" 
          Case $68
            IO$ = WB$ + "W83697SF/UF/UG" 
          Case $70
            IO$ = WB$ + "W83637HF/HG" 
          Case $82
            IO$ = WB$ + "W83627THF/THG" 
          Case $85
            IO$ = WB$ + "W83687THF" 
          Case $87
            IOx64Out32(Adr, $21)       ;Configurations-Register $21 auslesen
            WertB = IOx64Inp32(Adr + 1)
            CR21 = WertB & $FF
            Select CR21
              Case $08
                IO$ = IT$ + "IT8708F" ;soll ITE sein!
            EndSelect
          Case $88
            IOx64Out32(Adr, $21)       ;Configurations-Register $21 auslesen
            WertB = IOx64Inp32(Adr + 1)
            CR21 = WertB & $C0 
            Select CR21
              Case $40
                IO$ = WB$ + "W83627EHF/EF/EHG/EG"
            EndSelect
          Case $A0
            IOx64Out32(Adr, $21)       ;Configurations-Register $21 auslesen
            WertB = IOx64Inp32(Adr + 1)
            CR21 = WertB & $F0 
            Select CR21
              Case $20
                IO$ = WB$ + "W83627DHG" : Res = 3    ;Res für VCORE, für 8mV z.B ist Res=3 (2^3=8)
            EndSelect
        EndSelect  
      EndIf                            ;Ende FinTek, VIA oder Winbond
      ;--------------------------------------------------------------------------------------
      ;Test, ob ITE
      IOx64Out32(Adr, $87)             ;Einschalten des Extended Function Mode für ITE
      IOx64Out32(Adr, $01)
      IOx64Out32(Adr, $55)
      IOx64Out32(Adr, $55 + Z)         ;für $2E=$55, für $4E=$AA

      IOx64Out32(Adr, $20)             ;Configurations-Register $20 auslesen
      WertB = IOx64Inp32(Adr + 1)
      CR20 = WertB & $FF
      If CR20 <> 0 And CR20 <> $FF 
        Select CR20
          Case $87
            IOx64Out32(Adr, $21)       ;Configurations-Register $21 auslesen
            WertB = IOx64Inp32(Adr + 1)
            CR21 = WertB & $FF
            Select CR21
              Case $02
                IO$ = IT$ + "IT8702F"
              Case $05
                IO$ = IT$ + "IT8705F"
              Case $12
                IO$ = IT$ + "IT8712F"
              Case $16
                IO$ = IT$ + "IT8716F"
              Case $18
                IO$ = IT$ + "IT8718F"
              Case $20
                IO$ = IT$ + "IT8720"
              Case $26
                IO$ = IT$ + "IT8726F"
            EndSelect 
        EndSelect 
      EndIf                      ;Ende ITE
      ;--------------------------------------------------------------------------------------
      ;Test, ob SMSC
      IOx64Out32(Adr, $55)             ;Einschalten des Extended Function Mode für SMSC
      IOx64Out32(Adr, $20)             ;Configurations-Register $20 auslesen
      WertB = IOx64Inp32(Adr + 1)
      CR20 = WertB & $FF
      If CR20 <> 0 And CR20 <> $FF 
        Select CR20
          Case $0E   
            IO$ = SM$ + "LPC47N252"
          Case $14   
            IO$ = SM$ + "LPC47M172"
          Case $40   
            IO$ = SM$ + "FDC37C672"
          Case $42   
            IO$ = SM$ + "FDC37M707"
          Case $44   
            IO$ = SM$ + "FDC37B78x"
          Case $4C   
            IO$ = SM$ + "FDC37B72x"
          Case $4D   
            IO$ = SM$ + "FDC37M81x"
          Case $51   
            IO$ = SM$ + "LPC47B27x"
          Case $52   
            IO$ = SM$ + "LPC47B37x"
          Case $54   
            IO$ = SM$ + "LPC47U33x"
          Case $56   
            IO$ = SM$ + "LPC47B34x"
          Case $57   
            IO$ = SM$ + "LPC47S42x"
          Case $59   
            IO$ = SM$ + "LPC47M10x/112/13x"
          Case $5D   
            IO$ = SM$ + "LPC47B357/M967"
          Case $5F   
            IO$ = SM$ + "LPC47M14x"
          Case $60   
            IO$ = SM$ + "LPC47M15x/192/997"
          Case $62   
            IO$ = SM$ + "LPC47S45x"
          Case $67   
            IO$ = SM$ + "EMC2700LPC"
          Case $6B   
            IO$ = SM$ + "LPC47M292"
          Case $6D   
            IO$ = SM$ + "LPC47B367-NC"
          Case $6F   
            IO$ = SM$ + "LPC47B397-NC"
          Case $74   
            IO$ = SM$ + "LPC47M182"
          Case $76   
            IO$ = SM$ + "LPC47M584-NC"
          Case $77, $78    
            IO$ = SM$ + "DME1737"
          Case $79    
            IO$ = SM$ + "SCH5504-NS"
          Case $7C    
            IO$ = SM$ + "SCH3112"
          Case $7D    
            IO$ = SM$ + "SCH3114"
          Case $7F    
            IO$ = SM$ + "SCH3116"
          Case $81    
            IO$ = SM$ + "SCH5307-NS"
          Case $83    
            IO$ = SM$ + "SCH5514D-NS"
          Case $85, $8C    
            IO$ = SM$ + "SCH5317"
          Case $86    
            IO$ = SM$ + "SCH5127"
          Case $89    
            IO$ = SM$ + "SCH5027D-NW"
          Case $90    
            IO$ = SM$ + "SCH4307"
        EndSelect 
      EndIf
 
      ;SMSC benutzt auch das Configurations-Register $0D !
      IOx64Out32(Adr, $0D)             ;Configurations-Register $0D auslesen
      WertB = IOx64Inp32(Adr + 1)
      CR20 = WertB & $FF
      If CR20 <> 0 And CR20 <> $FF 
        Select CR20
          Case $03   
            IO$ = SM$ + "FDC37C669"
          Case $28   
            IO$ = SM$ + "FDC37N769"
          Case $5A   
            IO$ = SM$ + "LPC47N227"
          Case $65   
            IO$ = SM$ + "FDC37C665"
          Case $66   
            IO$ = SM$ + "FDC37C666"
        EndSelect 
      EndIf                            ;Ende SMSC
      ;--------------------------------------------------------------------------------------
      ;Test, ob National Semiconductor
      IOx64Out32(Adr, $20)             ;Configurations-Register $20 auslesen
      WertB = IOx64Inp32(Adr + 1)
      CR20 = WertB & $FF
      If CR20 <> 0 And CR20 <> $FF 
        Select CR20
          Case $D0    
            IO$ = NS$ + "PC87317"
          Case $DF    
            IO$ = NS$ + "PC97317"
          Case $E1    
            IO$ = NS$ + "PC87360"
          Case $E2    
            IO$ = NS$ + "PC87351"
          Case $E4    
            IO$ = NS$ + "PC87364"
          Case $E5    
            IO$ = NS$ + "PC87365"
          Case $E8    
            IO$ = NS$ + "PC87363"
          Case $E9    
            IO$ = NS$ + "PC87366"
          Case $EA    
            IO$ = NS$ + "PC8739x"
          Case $EC    
            IO$ = NS$ + "PC87591"
          Case $EE    
            IO$ = NS$ + "PC8741x"
          Case $F0    
            IO$ = NS$ + "PC87372"
          Case $F1    
            IO$ = NS$ + "PC8374L"
          Case $F2    
            IO$ = NS$ + "PC87427"
          Case $F3    
            IO$ = NS$ + "PC87373"
        EndSelect 
      EndIf                            ;Ende National Semiconductor 
      ;--------------------------------------------------------------------------------------
      Z + $55                          ;für Adresse ITE
    Next  
 
    If Mid(IO$, 1, 1) = "W" Or Mid(IO$, 1, 1) = "S"  ;für Winbond und SMSC
      IOx64Out32(Adr, $AA)             ;Beenden des Extended Function Mode für Winbond und SMSC
     Else 
      IOx64Out32(Adr, $02)             ;Beenden des Extended Function Mode für die anderen Chips
      IOx64Out32(Adr + 1, $02)
    EndIf

    MessageRequester("Super - I/O - Chip - Detection", IO$)
   Else
    MessageRequester("Fehler !", "Der 64-Bit-Treiber konnte nicht geöffnet werden !")
  EndIf
 Else
  MessageRequester("Fehler !", "inpoutx64.dll konnte nicht geöffnet werden !")
EndIf
End 

Code: Alles auswählen

Adr.w
WertB.b

If OpenLibrary(0, "inpoutx64.dll")
  Prototype.i ProtoIOx64_0()                ;kein Parameter
  IOx64IsOpen.ProtoIOx64_0 = GetFunction(0, "IsInpOutDriverOpen")
  Prototype.i ProtoIOx64_1(PortAdr)         ;1 Parameter
  IOx64Inp32.ProtoIOx64_1 = GetFunction(0, "Inp32")
  Prototype.i ProtoIOx64_2(PortAdr, WertB)  ;2 Parameter
  IOx64Out32.ProtoIOx64_2 = GetFunction(0, "Out32")  

  If IOx64IsOpen() 
    Res = 3                       ;=8mV (2^3) aus Datenblatt bzw. IO-Chip-Detection
    IOx64Out32($2E, $87)          ;Einschalten des Extended Function Mode für Winbond
    IOx64Out32($2E, $87)          ;muss 2x aufgerufen werden!
    
    IOx64Out32($2E, $7)           ;Logical Device auswählen
    IOx64Out32($2F, $B)           ;$B=Hardware-Monitor

    IOx64Out32($2E, $60)          ;High-Byte Register Address Base
    WertB = IOx64Inp32($2F)
    Adr = WertB & $FF
    Adr << 8                      ;nach Word-High schieben  

    IOx64Out32($2E, $61)          ;Low-Byte Register Address Base
    WertB = IOx64Inp32($2F)
    Adr + (WertB & $FF)           ;+5=Address Port, +6=Data Port
    ;Index $4E, Bits 0-2=Bank setzen, %000=Bank 0 usw.
    IOx64Out32(Adr + 5, $4E)
    WertB = IOx64Inp32(Adr + 6)
    WertB & %11111000             ;Bank 0 setzen
    IOx64Out32(Adr + 5, $4E)
    IOx64Out32(Adr + 6, WertB)

    IOx64Out32(Adr + 5, $20)      ;$20=CPUVCORE
    WertB = IOx64Inp32(Adr + 6)

    IOx64Out32($2E, $AA)          ;Beenden des Extended Function Mode für Winbond

    VC = (WertB & $FF) << Res     ;Res=Auflösung, für 8mV z.B ist Res=3, 2^3=8

    MessageRequester("Momentane CPU - Core - Spannung", StrF(VC / 1000, 3) + "V")
  EndIf 
 Else
  MessageRequester("Fehler !", "Fehler mit der WinRing0x64.dll")
EndIf
Gruß
Helle
Benutzeravatar
Falko
Admin
Beiträge: 3531
Registriert: 29.08.2004 11:27
Computerausstattung: PC: MSI-Z590-GC; 32GB-DDR4, ICore9; 2TB M2 + 2x3TB-SATA2 HDD; Intel ICore9 @ 3600MHZ (Win11 Pro. 64-Bit),
Acer Aspire E15 (Win11 Home X64). Purebasic LTS 6.0
Kontaktdaten:

Beitrag von Falko »

Funktioniert bei mir unter VistaX64 (Ultimate) leider nicht.

Mainboard ist ein ASUS P5QL Pro und CPU IntelCor2Duo E7500 / 45nm

Folgender Fehler bei der Zeile:

Code: Alles auswählen

  If IOx64IsOpen()

Invalid memory access. (write error at address 0)

Mit der PB Version 4.31X64 und 4.4B2X64

Gruß Falko
Bild
Win10 Pro 64-Bit, PB_5.4,GFA-WinDOS, Powerbasic9.05-Windows, NSBasic/CE, NSBasic/Desktop, NSBasic4APP, EmergenceBasic
Benutzeravatar
Helle
Beiträge: 566
Registriert: 11.11.2004 16:13
Wohnort: Magdeburg

Beitrag von Helle »

Ha, ich habe für Vista fast damit gerechnet (signierte Treiber), obwohl in der ReadMe etwas von Vista-Kompatibilität steht. Das Überprüfen auf signierte Treiber kann zwar deaktiviert werden (Boot-Einstellung), ist aber hierfür inakzeptabel (falls es daran liegt).
Also wird jetzt WinRing0 getestet (Link siehe wieder oben bei Rings) :mrgreen: ! Damit es nicht zu langweilig wird hier ein neuer Testcode für die 64-Bit-Funktionalität:

Code: Alles auswählen

;Beispiel für die Nutzung der WinRing0-Dll´s (32-und 64-Bit). Copyright und Lizens beachten
; (einfügen in "richtige" Programme)! 
;PB-Umsetzung einiger Punkte der WinRing0-Sample-Datei für Lauf-Test.
;*.DLL/*.SYS müssen im selben Verzeichnis vorhanden sein wie *.EXE/*.PB.
;"Temporäres Executable im Quellcode-Verzeichnis erstellen" muss zugeschaltet sein,
; wenn Programm aus der IDE gestartet werden soll!

Hi.l
Lo.l
Index.l
Adr.w              ;für IN/OUT
WertB.b
Major.b
Minor.b
Revision.b
Release.b

;ermitteln, ob 32- oder 64-Bit-Betriebssystem 
#PROCESSOR_ARCHITECTURE_AMD64 = $0009
SI.SYSTEM_INFO                              ;Structure System_Info
If OSVersion() > #PB_OS_Windows_2000        ;mit W2k geht nachfolgende Abfrage nicht! 
  openlib = OpenLibrary(#PB_Any, "kernel32.dll") 
  *GetNativeSystemInfo = GetFunction(openlib, "GetNativeSystemInfo") 
  CallFunctionFast(*GetNativeSystemInfo, @SI) 
  CloseLibrary(openlib) 
  If SI\wProcessorArchitecture = #PROCESSOR_ARCHITECTURE_AMD64 
    OS3264 = 1 
  EndIf 
EndIf 
;die entsprechende DLL öffnen
If OS3264 
  DLLOK = OpenLibrary(0, "WinRing0x64.dll") ;64-Bit-Version laden
 Else
  DLLOK = OpenLibrary(0, "WinRing0.dll")    ;32-Bit-Version laden
EndIf 

If DLLOK
  Prototype.i ProtoWinRing0_0()        ;für die 0-Parameter-Funktionen
  WR0_InitializeOls.ProtoWinRing0_0    = GetFunction(0, "InitializeOls")
  WR0_DeinitializeOls.ProtoWinRing0_0  = GetFunction(0, "DeinitializeOls")
  WR0_GetDllStatus.ProtoWinRing0_0     = GetFunction(0, "GetDllStatus")
  WR0_GetDriverType.ProtoWinRing0_0    = GetFunction(0, "GetDriverType")
  WR0_IsTsc.ProtoWinRing0_0            = GetFunction(0, "IsTsc")
  WR0_IsMsr.ProtoWinRing0_0            = GetFunction(0, "IsMsr")

  Prototype.i ProtoWinRing0_1(V1w.w)   ;für die 1-Parameter-Funktionen Word
  WR0_ReadIoPortByte.ProtoWinRing0_1   = GetFunction(0, "ReadIoPortByte")

  Prototype.i ProtoWinRing0_2(V1l.l, V2l.l) ;für die 2-Parameter-Funktionen
  WR0_Rdtsc.ProtoWinRing0_2            = GetFunction(0, "Rdtsc")
  WR0_WriteIoPortByte.ProtoWinRing0_2  = GetFunction(0, "WriteIoPortByte")

  Prototype.i ProtoWinRing0_3(V1l.l, V2l.l, V3l.l)    ;für die 3-Parameter-Funktionen
  WR0_RDMSR.ProtoWinRing0_3 = GetFunction(0, "Rdmsr")

  Prototype.i ProtoWinRing0_4(V1b.b, V2b.b, V3b.b, V4b.b)  ;für die 4-Parameter-Funktionen Byte
  WR0_GetDllVersion.ProtoWinRing0_4    = GetFunction(0, "GetDllVersion")
  WR0_GetDriverVersion.ProtoWinRing0_4 = GetFunction(0, "GetDriverVersion")

  If WR0_InitializeOls()               ;1 wenn Initialisierung erfolgreich, 0 wenn nicht 
    ;Dll-Version ermitteln
    Sample$ = "[DLL Version]" + #LFCR$
    WR0_GetDllVersion(@Major, @Minor, @Revision, @Release)
    Sample$ + Str(Major) + "." + Str(Minor) + "." + Str(Revision) + "." + Str(Release) + #LFCR$
    ;Driver-Version ermitteln
    Sample$ + "[Device Driver Version]" + #LFCR$
    WR0_GetDriverVersion(@Major, @Minor, @Revision, @Release)
    Sample$ + Str(Major) + "." + Str(Minor) + "." + Str(Revision) + "." + Str(Release) + #LFCR$
    ;Driver-Type ermitteln
    Sample$ + "[Device Driver Type]" + #LFCR$
    GetDriverType = WR0_GetDriverType()
    Select GetDriverType
      Case 0
        Type$ = "OLS_DRIVER_TYPE_UNKNOWN"
      Case 1
        Type$ = "OLS_DRIVER_TYPE_WIN_9X"
      Case 2
        Type$ = "OLS_DRIVER_TYPE_WIN_NT"
      Case 4
        Type$ = "OLS_DRIVER_TYPE_WIN_NT_X64"
      Case 5
        Type$ = "OLS_DRIVER_TYPE_WIN_NT_IA64"
    EndSelect 
    Sample$ + Type$ + #LFCR$
    ;DLL-Status ermitteln
    Sample$ + "[DLL Status]" + #LFCR$
    GetDllStatus = WR0_GetDllStatus()
    Select GetDllStatus
      Case 0
        Status$ = "OLS_DLL_NO_ERROR"
      Case 1
        Status$ = "OLS_DLL_UNSUPPORTED_PLATFORM"
      Case 2
        Status$ = "OLS_DLL_DRIVER_NOT_LOADED"
      Case 3
        Status$ = "OLS_DLL_DRIVER_NOT_FOUND"
      Case 4
        Status$ = "OLS_DLL_DRIVER_UNLOADED"
      Case 5
        Status$ = "OLS_DLL_DRIVER_NOT_LOADED_ON_NETWORK"
      Case 9
        Status$ = "OLS_DLL_UNKNOWN_ERROR"
    EndSelect 
    Sample$ + Status$ + #LFCR$
    ;TSC (Time Stamp Counter) einlesen
    Sample$ + "[TSC]" + #LFCR$
    Sample$ + "63-32          31-0" + #LFCR$
    IsTsc = WR0_IsTsc()
    If IsTsc                                ;1 wenn erfolgreich, 0 wenn nicht
      WR0_Rdtsc(@Lo, @Hi)
    EndIf 
    Sample$ + RSet(Hex(Hi & $FFFFFFFF), 8, "0") + "   " + RSet(Hex(Lo & $FFFFFFFF), 8, "0") + #LFCR$
    ;(ein) MSR (Model Specific Register, hier $10) einlesen
    Sample$ + "[MSR]" + #LFCR$
    Sample$ + "index            63-32          31-0" + #LFCR$
    IsMsr = WR0_IsMsr()
    If IsMsr                                ;1 wenn erfolgreich, 0 wenn nicht
      Index = $10
      WR0_Rdmsr(Index, @Lo, @Hi)
    EndIf 
    Sample$ + RSet(Hex(Index & $FFFFFFFF), 8, "0") + ":   " + RSet(Hex(Hi & $FFFFFFFF), 8, "0") + "   " + RSet(Hex(Lo & $FFFFFFFF), 8, "0") + #LFCR$
    ;Beep mit 440Hz für 1 Sekunde ausgeben
    Sample$ + "[I/O]" + #LFCR$
    Sample$ + "Beep 440Hz" + #LFCR$
    Freq.l = 1193180000 / 440000
    WR0_WriteIoPortByte($43, $B6)
    WertB = Freq & $FF
    WR0_WriteIoPortByte($42, WertB)
    WertB = Freq >> 9
    WR0_WriteIoPortByte($42, WertB)
    Delay(100)
    WertB = WR0_ReadIoPortByte($61) | $3
    WR0_WriteIoPortByte($61, WertB)
    Delay(1000)
    WertB = WR0_ReadIoPortByte($61) & $FC
    WR0_WriteIoPortByte($61, WertB)
    ;Ergebnis-Ausgabe
    MessageRequester("Sample", Sample$)  
    WR0_DeinitializeOls()              ;ordentlich beenden
   Else 
    MessageRequester("Fehler !", "Fehler mit der Initialisierung !")
  EndIf 
 Else
  MessageRequester("Fehler !", "Fehler mit der DLL !")
EndIf
Unbedingt die Bemerkungen beachten! Der Code muss vor der Ausführung abgespeichert werden und in diesem Verzeichnis müssen sich auch die DLL und SYS befinden!
Rückmeldung wieder erwünscht!

Gruß
Helle
Benutzeravatar
Falko
Admin
Beiträge: 3531
Registriert: 29.08.2004 11:27
Computerausstattung: PC: MSI-Z590-GC; 32GB-DDR4, ICore9; 2TB M2 + 2x3TB-SATA2 HDD; Intel ICore9 @ 3600MHZ (Win11 Pro. 64-Bit),
Acer Aspire E15 (Win11 Home X64). Purebasic LTS 6.0
Kontaktdaten:

Beitrag von Falko »

Dann soll es wohl am ASUS-Board liegen. Leider kriege ich von WinRing0x64 mit dem neuen Source folgende Fehlermeldung heraus:

---------------------------
Fehler !
---------------------------
Fehler mit der Initialisierung !
---------------------------
OK
---------------------------

Auch im Administrativen Zugriff das Gleiche.
Alle DLLs, Sys und die PB im gleichen Verzeichnis.

[Edit]
ich habe keinen AMD und somit müsste die Konstante wohl so heissen:
#PROCESSOR_ARCHITECTURE_IA64 = $0006

Code: Alles auswählen

#PROCESSOR_ARCHITECTURE_AMD64 = $0009
#PROCESSOR_ARCHITECTURE_IA64 = $0006

SI.SYSTEM_INFO                              ;Structure System_Info
If OSVersion() > #PB_OS_Windows_2000        ;mit W2k geht nachfolgende Abfrage nicht!
  openlib = OpenLibrary(#PB_Any, "kernel32.dll")
  *GetNativeSystemInfo = GetFunction(openlib, "GetNativeSystemInfo")
  CallFunctionFast(*GetNativeSystemInfo, @SI)
  CloseLibrary(openlib)
  If SI\wProcessorArchitecture = #PROCESSOR_ARCHITECTURE_IA64
    OS3264 = 1
  EndIf
EndIf
;die entsprechende DLL ”ffnen
If OS3264
  DLLOK = OpenLibrary(0, "WinRing0x64.dll") ;64-Bit-Version laden
 Else
  DLLOK = OpenLibrary(0, "WinRing0.dll")    ;32-Bit-Version laden
EndIf
;....
Dann kriege ich aber den Fehler:
---------------------------
Fehler !
---------------------------
Fehler mit der DLL !
---------------------------
OK
---------------------------

Echt seltsam :roll:



Gruß Falko
Bild
Win10 Pro 64-Bit, PB_5.4,GFA-WinDOS, Powerbasic9.05-Windows, NSBasic/CE, NSBasic/Desktop, NSBasic4APP, EmergenceBasic
Benutzeravatar
Falko
Admin
Beiträge: 3531
Registriert: 29.08.2004 11:27
Computerausstattung: PC: MSI-Z590-GC; 32GB-DDR4, ICore9; 2TB M2 + 2x3TB-SATA2 HDD; Intel ICore9 @ 3600MHZ (Win11 Pro. 64-Bit),
Acer Aspire E15 (Win11 Home X64). Purebasic LTS 6.0
Kontaktdaten:

Beitrag von Falko »

Anscheinend wir auch der Intelprozessor über die 9 erkannt.

Der test bestätigt es:

Code: Alles auswählen

SI.SYSTEM_INFO 
openlib = OpenLibrary(#PB_Any, "kernel32.dll")
  *GetNativeSystemInfo = GetFunction(openlib, "GetNativeSystemInfo")
  CallFunctionFast(*GetNativeSystemInfo, @SI)
  CloseLibrary(openlib)
Ausgabe.w=SI\wProcessorArchitecture
Debug Ausgabe
    
Oder, wer eine PB-Vollversion hat, dann so etwas kürzer:

Code: Alles auswählen

SI.SYSTEM_INFO 
GetSystemInfo_(SI)
Debug SI\wProcessorArchitecture
Dann ist da ein anderes Problem unter Vista X64.

Gruß Falko
Bild
Win10 Pro 64-Bit, PB_5.4,GFA-WinDOS, Powerbasic9.05-Windows, NSBasic/CE, NSBasic/Desktop, NSBasic4APP, EmergenceBasic
Benutzeravatar
Helle
Beiträge: 566
Registriert: 11.11.2004 16:13
Wohnort: Magdeburg

Beitrag von Helle »

Das mit der 9 ist schon richtig. Ist "Temporäres Executable im Quellcode-Verzeichnis erstellen" aktiviert? Sonst kommt bei Ausführung über der IDE die Fehlermeldung mit der Initialisierung.

Gruß
Helle
Antworten