Subversion Repositories Kolibri OS

Rev

Rev 4289 | Rev 4310 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 4289 Rev 4294
Line 1... Line 1...
1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                              ;;
2
;;                                                              ;;
3
;; Copyright (C) KolibriOS team 2004-2013. All rights reserved. ;;
3
;; Copyright (C) KolibriOS team 2004-2013. All rights reserved. ;;
4
;; Distributed under terms of the GNU General Public License    ;;
4
;; Distributed under terms of the GNU General Public License    ;;
5
;;                                                              ;;
5
;;                                                              ;;
6
;; 20/11/2013 yogev_ezra: Initial version                       ;;
-
 
7
;; Thanks for help to: dunkaist, eAndrew, hidnplayr, Mario      ;;
-
 
8
;;                                                              ;;
-
 
9
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
6
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Line -... Line 7...
-
 
7
 
-
 
8
; 20/11/2013 yogev_ezra: Initial version (Vortex86 SoC type detection)
-
 
9
; 26/11/2013 yogev_ezra: Added CPU speed modifier and MMX support flag detection
-
 
10
; Thanks for help to: dunkaist, eAndrew, hidnplayr, Mario
10
 
11
 
Line 11... Line 12...
11
$Revision: 4289 $
12
$Revision: 4294 $
12
 
13
 
Line 13... Line 14...
13
VORTEX86DEBUG = 0                       ; For testing in emulators and in non-Vortex86 CPU computers, set this to 1
14
VORTEX86DEBUG = 0                       ; For testing in emulators and in non-Vortex86 CPU computers, set this to 1
Line 27... Line 28...
27
Vortex86CPUid   db 0                    ; Vortex86 CPU id in integer format (1=Vortex86SX, 2=Vortex86DX, ...)
28
Vortex86CPUid   db 0                    ; Vortex86 CPU id in integer format (1=Vortex86SX, 2=Vortex86DX, ...)
28
Vortex86SoCname db 'Vortex86   ',0      ; This variable will hold the full name of Vortex86 SoC
29
Vortex86SoCname db 'Vortex86   ',0      ; This variable will hold the full name of Vortex86 SoC
29
Vortex86SoClist:                        ; List of Vortex86 CPUs known today. Add new record to this list when new CPU becomes available
30
Vortex86SoClist:                        ; List of Vortex86 CPUs known today. Add new record to this list when new CPU becomes available
30
        db      0x31, 'SX '     ; id=1
31
        db      0x31, 'SX '     ; id=1
31
        db      0x32, 'DX '     ; id=2
32
        db      0x32, 'DX '     ; id=2
32
        db      0x33, 'MX '     ; id=3
33
        db      0x33, 'MX '     ; id=3  MMX is available starting from CPU code 'MX' (id=3)
33
        db      0x34, 'DX2'     ; id=4
34
        db      0x34, 'DX2'     ; id=4
34
        db      0x35, 'MX+'     ; id=5
35
        db      0x35, 'MX+'     ; id=5
35
        db      0x37, 'EX '     ; id=6
36
        db      0x37, 'EX '     ; id=7
36
Vortex86SoCnum = ($ - Vortex86SoClist) / 4      ; Calculate the total number of known Vortex86 CPUs (if id=Vortex86SoCnum+1 --> unknown SoC)
37
Vortex86SoCnum = ($ - Vortex86SoClist) / 4      ; Calculate the total number of known Vortex86 CPUs
37
endg
38
endg
Line 38... Line 39...
38
 
39
 
39
; When in debug mode, perform SoC detection regardless of the actual CPU vendor (even for vendors other than DMP)
40
; When in debug mode, perform SoC detection regardless of the actual CPU vendor (even for vendors other than DMP)
40
; When in normal (not debug) mode, check the CPU vendor first, and perform SoC detection only if vendor is 'Vortex86 SoC'
41
; When in normal (not debug) mode, check the CPU vendor first, and perform SoC detection only if vendor is 'Vortex86 SoC'
41
if ~ VORTEX86DEBUG        
42
if ~ VORTEX86DEBUG        
42
        cmp     [cpu_vendor], 'Vort'
43
        cmp     [cpu_vendor], 'Vort'
43
        jnz     .Vortex86end            ; If the CPU vendor is not 'Vortex86 SoC', skip the SoC detection
44
        jnz     .Vortex86end            ; If the CPU vendor is not 'Vortex86 SoC', skip the SoC detection
Line 44... Line -...
44
end if        
-
 
45
 
45
end if
46
        mov     dx, 0xcf8               ; CF8h = Vortex86 PCI Configuration Address port
46
 
47
        mov     eax, OS_BASE+0x90       ; 0x80000090 = Starting PCI address to read from (32-bit register - accessed as DWORD)
-
 
48
        out     dx, eax                 ; Send request to PCI address port to retrieve data from this address
-
 
Line 49... Line 47...
49
        mov     dx, 0xcfc               ; CFCh = Vortex86 PCI Configuration Data port
47
        mov     eax, OS_BASE+0x90       ; 0x80000090 = Starting PCI address to read from (32-bit register - accessed as DWORD)
50
        in      eax, dx                 ; Read data (SoC type) from PCI data port
48
        call    .Vortex86PCIreg         ; Get the CPU code from Vortex86 SoC PCI register (Register Offset: 93H~90H)
51
 
49
 
Line 52... Line 50...
52
if VORTEX86DEBUG                        ; When in debug mode, pretend that we received port output equal to "VORTEX86DEBUGVALUE"
50
if VORTEX86DEBUG                        ; When in debug mode, pretend that we received port output equal to "VORTEX86DEBUGVALUE"
53
        mov     eax, VORTEX86DEBUGVALUE
51
        mov     eax, VORTEX86DEBUGVALUE
54
end if        
52
end if
55
        
53
        
56
        DEBUGF  1, "K : Vortex86 SoC register returned 0x"
54
        DEBUGF  1, "K : Vortex86 SoC type register (93H~90H) returned 0x"
Line 57... Line 55...
57
        test    eax, eax                ; Check whether the port output was '\0'
55
        test    eax, eax                ; Check whether the port output was '\0'
58
        jz      .nullPCIoutput          ; In case the result is '\0' (NULL), skip further testing and exit
56
        jz      .nullPCIoutput          ; In case the result is '\0' (NULL), skip further testing and exit
59
        mov     [Vortex86CPUcode], eax                      ; Save HEX CPU code to Vortex86CPUcode (so it can be used later)
57
        mov     [Vortex86CPUcode], eax                      ; Save HEX CPU code to Vortex86CPUcode (so it can be used later)
60
        DEBUGF  1, "%x (%s): ", eax, Vortex86CPUcode        ; Print the CPU code (as HEX and as string) to debug log
58
        DEBUGF  1, "%x (%s): ", eax, Vortex86CPUcode        ; Print the CPU code (as HEX and as string) to debug log
61
 
59
 
-
 
60
        mov     ebx, 0x444d5000         ; Apply Vortex86 CPU code mask (all Vortex86 SoC have ID in form of "0xNN504d44")
-
 
61
        bswap   eax                     ; Assumed it is Vortex86 SoC, the highest byte identifies the exact CPU, so move it to the lowest byte
-
 
62
        mov     bl, al                  ; Copy SoC type to BL since EAX (that includes AL) is used implicitly in "LODSD" command below
Line 62... Line 63...
62
        mov     ebx, 0x444d5000         ; Apply Vortex86 CPU code mask (all Vortex86 SoC have ID in form of "0xNN504d44")
63
        cmp     eax, ebx                ; Now see whether the 3 higher bytes were "0x504d44" (which means it's Vortex86)
63
        bswap   eax                     ; Assumed it is Vortex86 SoC, the highest byte identifies the exact CPU, so move it to the lowest byte
64
        jnz     .notVortex86            ; If it's not Vortex86 - go say so and exit
64
        mov     bl, al                  ; Copy SoC type to BL since EAX (that includes AL) is used implicitly in "LODSD" command below
65
 
65
        cmp     eax, ebx                ; Now see whether the 3 higher bytes were "0x504d44" (which means it's Vortex86)
66
        sub     al, 0x30                ; Current Vortex86 CPU codes are in the range of 31h-37h, so convert them to integer (1,2,...)
Line 76... Line 77...
76
        cmp     bl, al                  ; Check if our CPU matches the current record in the list
77
        cmp     bl, al                  ; Check if our CPU matches the current record in the list
77
        jne     @b                      ; No match --> repeat with next record
78
        jne     @b                      ; No match --> repeat with next record
Line 78... Line 79...
78
 
79
 
79
        shr     eax, 8                              ; Match found --> drop the SoC type code from Vortex86SoClist name and replace it with \0
80
        shr     eax, 8                              ; Match found --> drop the SoC type code from Vortex86SoClist name and replace it with \0
80
        mov     dword [Vortex86SoCname+8], eax      ; Concatenate it with prefix to receive complete SoC name (\0 is string termination)
-
 
-
 
81
        mov     dword [Vortex86SoCname+8], eax      ; Concatenate it with prefix to receive complete SoC name (\0 is string termination)
81
        mov     [Vortex86CPUid], cl                 ; Save the CPUid (1=Vortex86SX, 2=Vortex86DX, ..., Vortex86SoCnum+1=Unknown Vortex86)
82
 
82
        DEBUGF  1, "%s (id=%d)\n", Vortex86SoCname, [Vortex86CPUid]:1               ; Say what we have found (CPU name and id)
83
        DEBUGF  1, "%s (id=%d)\n", Vortex86SoCname, [Vortex86CPUid]:1           ; Say what we have found (CPU name and id)
Line 83... Line 84...
83
        jmp     .Vortex86end
84
        jmp     .Vortex86
84
 
85
 
85
.notVortex86:                           ; In case this register is used by other CPUs for other purpose, it's interesting what it contains
86
.notVortex86:                           ; In case this register is used by other CPUs for other purpose, it's interesting what it contains
Line -... Line 87...
-
 
87
        DEBUGF  1, "not a Vortex86 CPU\n"
-
 
88
        jmp     .Vortex86end
-
 
89
 
86
        DEBUGF  1, "not a Vortex86 CPU\n"
90
.unknownVortex86:                       ; It is Vortex86 CPU, but it's not in the list above
-
 
91
        DEBUGF  1, "unknown Vortex86 CPU (id=%d)\n", [Vortex86CPUid]:1          ; Inform the user that the CPU is Vortex86 but name is unknown
-
 
92
 
-
 
93
.Vortex86:
-
 
94
        mov     eax, OS_BASE+0xA0       ; 0x800000A0 = Starting PCI address to read from (32-bit register - accessed as DWORD)
-
 
95
        call    .Vortex86PCIreg         ; Get current flags of Vortex86SoC Host Control Register (Register Offset: A3h~A0h)
-
 
96
        DEBUGF  1, "K : Vortex86 Host Control Register (A3h~A0h) returned 0x%x: CPU speed is ",eax
-
 
97
        mov     bl, al                  ; The lower byte of Vortex86 Host Control Register contains CPU speed modifier and MMX support status
-
 
98
        mov     bh, al                  ; Backup the current AL value, so later we can test whether the value has changed
-
 
99
        and     bl, 00000111b           ; CPU speed modifier is stored in bits 0-2. Value=0 means MAX speed, other values - speed reduction
-
 
100
        jz      .Vortex86CPUspeedMAX    ; 0s in bits 0-2: CPU is at MAX speed (no need to modify)
-
 
101
        inc     bl                      ; The actual value is 1 less than 'Divide by' setting (value '001' means 'Divide by 2', etc.)
-
 
102
        DEBUGF  1, "reduced (divide by %d).\nK : Vortex86 changing CPU speed to ", bl    ; Print the current CPU speed modifier to the log
-
 
103
        and     al, 11111000b           ; At least one of the bits 0-2 contains 1: CPU is at reduced speed. Set bits 0-2 to 0s to change to MAX
87
        jmp     .Vortex86end
104
.Vortex86CPUspeedMAX:
-
 
105
        DEBUGF  1, "MAX\n"              ; Now the CPU should be running at MAX speed (don't write the value to PCI port yet)
-
 
106
 
-
 
107
        cmp     [Vortex86CPUid], 3      ; MMX is available starting from CPU code 'MX' (id=3)
-
 
108
        jb      .skipVortex86MMX        ; No MMX support - skip MMX support status detection (for id=1,2)
-
 
109
        DEBUGF  1, "K : Vortex86 MMX support status: MMX is "                   ; Bits 5-6 in Host Control Register contain MMX status
-
 
110
        test    al, 100000b             ; On MMX-capable Vortex86 SoC, Bit5 = is MMX enabled? (1=Yes/0=No)
-
 
111
        jnz     .Vortex86MMXenabled     ; MMX is already enabled (Bit5=1)
-
 
112
        DEBUGF  1, "DISABLED - enabling it for this session\n"                  ; Print to the log that MMX is disabled
-
 
113
        or      al, 100000b             ; Enable MMX support (don't write the value to PCI port yet)
-
 
114
        jmp     .AfterMMXenabled
-
 
115
.Vortex86MMXenabled:
-
 
116
        DEBUGF  1, "ENABLED\n"          ; Print to the log that MMX is enabled
-
 
117
.AfterMMXenabled:
-
 
118
        DEBUGF  1, "K : Vortex86 MMX report to CPUID: "                         ; Print to the log what CPUID command knowns about MMX support
-
 
119
        test    al, 1000000b            ; On MMX-capable Vortex86 SoC, Bit6 = report MMX support to CPUID? (1=Yes/0=No)        
-
 
120
        jnz     .Vortex86MMXreported    ; MMX is already reported to CPUID (Bit6=1)
-
 
121
        DEBUGF  1, "OFF - turning it ON for this session\n"                     ; Print to the log that MMX will now be reported to CPUID
-
 
122
        or      al, 1000000b            ; Turn on MMX reporting to CPUID (don't write the value to PCI port yet)
-
 
123
        jmp     .skipVortex86MMX
-
 
124
.Vortex86MMXreported:
-
 
125
        DEBUGF  1, "ON\n"               ; Print to the log that MMX reporting to CPUID is enabled
-
 
126
 
-
 
127
.skipVortex86MMX:
88
 
128
        cmp     bh, al                  ; Check whether AL has changed before (if it did, we need to write it back to PCI port)
89
.unknownVortex86:
129
        jz      .Vortex86end            ; No change - no need to write to the port
Line -... Line 130...
-
 
130
        out     dx, al                  ; Write the changed data to PCI port
-
 
131
        DEBUGF  1, "K : Vortex86 Host Control Register (A3h~A0h) new value is 0x%x\n",eax
-
 
132
        jmp     .Vortex86end
-
 
133
 
-
 
134
.Vortex86PCIreg:                        ; Procedure receives input register value in EAX, and returns the output value also in EAX
-
 
135
        mov     dx, 0xcf8               ; CF8h = Vortex86 PCI Configuration Address port
-
 
136
        out     dx, eax                 ; Send request to PCI address port to retrieve data from this address
90
        mov     [Vortex86CPUid], cl                 ; Save the CPUid (Vortex86SoCnum+1=Unknown Vortex86)
137
        mov     dl, 0xfc                ; CFCh = Vortex86 PCI Configuration Data port
91
        DEBUGF  1, "unknown Vortex86 CPU (id=%d, last known is %d)\n", [Vortex86CPUid]:1, Vortex86SoCnum
138
        in      eax, dx                 ; Read data from PCI data port
Line 92... Line 139...
92
        jmp     .Vortex86end
139
        ret
93
 
140