Rev 4261 | Rev 4289 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
4261 | yogev_ezra | 1 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
2 | ;; ;; |
||
3 | ;; Copyright (C) KolibriOS team 2004-2013. All rights reserved. ;; |
||
4 | ;; Distributed under terms of the GNU General Public License ;; |
||
5 | ;; ;; |
||
6 | ;; 20/11/2013 yogev_ezra: Initial version ;; |
||
7 | ;; Thanks for help to: dunkaist, eAndrew, hidnplayr, Mario ;; |
||
8 | ;; ;; |
||
9 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
||
10 | |||
11 | $Revision: 4272 $ |
||
12 | |||
13 | VORTEX86DEBUG = 0 ; For testing in emulators and in non-Vortex86 CPU computers, set this to 1 |
||
14 | VORTEX86DEBUGVALUE = 0x35504d44 ; FAKE port output = used for testing |
||
15 | |||
16 | ; Detect Vortex86 CPU and generate CPU name in string format (PCI address at 93H~90H in Vortex86 North Bridge contains SoC type) |
||
17 | ; Available Vortex86 CPU codes taken from Coreboot project. New codes should be added to "Vortex86SoClist" below |
||
18 | ; #define DMP_CPUID_SX 0x31504d44 ("DMP1") |
||
19 | ; #define DMP_CPUID_DX 0x32504d44 ("DMP2") |
||
20 | ; #define DMP_CPUID_MX 0x33504d44 ("DMP3") |
||
21 | ; #define DMP_CPUID_DX2 0x34504d44 ("DMP4") |
||
22 | ; #define DMP_CPUID_MX_PLUS 0x35504d44 ("DMP5") |
||
23 | ; #define DMP_CPUID_EX 0x37504d44 ("DMP7") |
||
24 | |||
25 | iglobal |
||
26 | Vortex86CPUcode dd ? ; Vortex86 CPU code in HEX format (4 bytes), can be shown as string if converted to ASCII characters |
||
27 | 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 | 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 0x32, 'DX ' ; id=2 |
||
32 | db 0x33, 'MX ' ; id=3 |
||
33 | db 0x34, 'DX2' ; id=4 |
||
34 | db 0x35, 'MX+' ; id=5 |
||
35 | db 0x37, 'EX ' ; id=6 |
||
36 | Vortex86SoCnum = ($ - Vortex86SoClist) / 4 ; Calculate the total number of known Vortex86 CPUs (if id=Vortex86SoCnum+1 --> unknown SoC) |
||
37 | endg |
||
38 | |||
4272 | yogev_ezra | 39 | ; 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 | if ~ VORTEX86DEBUG |
||
42 | cmp [cpu_vendor], 'Vort' |
||
43 | jnz .Vortex86end ; If the CPU vendor is not 'Vortex86 SoC', skip the SoC detection |
||
44 | end if |
||
45 | |||
4261 | yogev_ezra | 46 | mov dx, 0xcf8 ; CF8h = Vortex86 PCI Configuration Address port |
47 | mov eax, 0x80000090 ; 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 |
||
49 | mov dx, 0xcfc ; CFCh = Vortex86 PCI Configuration Data port |
||
50 | in eax, dx ; Read data (SoC type) from PCI data port |
||
51 | |||
4272 | yogev_ezra | 52 | if VORTEX86DEBUG ; When in debug mode, pretend that we received port output equal to "VORTEX86DEBUGVALUE" |
4261 | yogev_ezra | 53 | mov eax, VORTEX86DEBUGVALUE |
54 | end if |
||
55 | |||
56 | DEBUGF 1, "K : Vortex86 SoC register returned 0x" |
||
57 | test eax, eax ; We need to break out in case the result is '\0' since otherwise we will fail at NULL string |
||
58 | jz .nullPCIoutput |
||
59 | mov [Vortex86CPUcode], eax |
||
60 | DEBUGF 1, "%x (%s): ", eax, Vortex86CPUcode |
||
61 | cmp ax, 4d44h ; Check whether it's Vortex86 family (all Vortex86 SoC have ID in form of "0xNN504d44") |
||
62 | jnz .notVortex86 |
||
63 | shr eax, 16 ; Discard lower word in EAX which is always 4d44h in Vortex86 family |
||
4272 | yogev_ezra | 64 | cmp al, 50h ; The 3rd byte is always 50h in Vortex86 SoC (if this is the case, we need just the highest byte) |
4261 | yogev_ezra | 65 | jnz .notVortex86 |
4272 | yogev_ezra | 66 | mov bl, ah ; Copy SoC type to BL since EAX (that includes AH) is used implicitly in "LODSD" command below |
4261 | yogev_ezra | 67 | mov esi, Vortex86SoClist ; ESI points to the start of Vortex86SoClist (used implicitly in "LODSD" command below) |
68 | xor ecx, ecx ; Zero ECX (it is used as counter) |
||
69 | cld ; Clears the DF flag in the EFLAGS register (DF=0 --> String operations increment ESI) |
||
70 | @@: |
||
71 | cmp ecx, Vortex86SoCnum ; Check if we iterated Vortex86SoCnum times already (i.e. went over the entire Vortex86SoClist) |
||
72 | ja .unknownVortex86 ; If the entire list was tested and our CPU is not in that list, it is unknown Vortex86 SoC |
||
73 | inc ecx ; Increment our counter |
||
74 | lodsd ; Load DWORD at address DS:ESI into EAX (puts 1 line from Vortex86SoClist into EAX, then increments ESI) |
||
75 | cmp bl, al ; Check if our CPU matches the current record in the list |
||
76 | jne @b ; No match --> repeat with next record |
||
77 | |||
78 | shr eax, 8 ; Match found --> drop the SoC type code from Vortex86SoClist name and replace it with \0 |
||
79 | mov dword [Vortex86SoCname+8], eax ; Concatenate it with prefix to receive complete SoC name (\0 is string termination) |
||
80 | mov [Vortex86CPUid], cl ; Save the CPUid (1=Vortex86SX, 2=Vortex86DX, ..., Vortex86SoCnum+1=Unknown Vortex86) |
||
81 | |||
82 | DEBUGF 1, "%s (id=%d)\n", Vortex86SoCname, [Vortex86CPUid]:1 |
||
83 | jmp .Vortex86end ; Say what we have found (CPU name and id) and exit |
||
84 | |||
85 | .nullPCIoutput: ; Emulators and non-Vortex86 CPU computers will usually return \0 in this register |
||
86 | DEBUGF 1, "0 (NULL)\n" |
||
87 | jmp .Vortex86end |
||
88 | |||
89 | .unknownVortex86: |
||
90 | mov [Vortex86CPUid], cl ; Save the CPUid (Vortex86SoCnum+1=Unknown Vortex86) |
||
4272 | yogev_ezra | 91 | DEBUGF 1, "unknown Vortex86 CPU (id=%d, last known is %d)\n", [Vortex86CPUid]:1, Vortex86SoCnum |
4261 | yogev_ezra | 92 | jmp .Vortex86end |
93 | |||
94 | .notVortex86: ; In case this register is used by other CPUs for other purpose, it's interesting what it contains |
||
95 | DEBUGF 1, "not a Vortex86 CPU\n" |
||
96 | |||
97 | .Vortex86end: |