Subversion Repositories Kolibri OS

Rev

Rev 4265 | Rev 4423 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  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: 4261 $
  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.  
  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.  
  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.  
  52. if VORTEX86DEBUG                        ; When in debug mode, pretend that we received port output equal to "VORTEX86DEBUGVALUE"
  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
  64.         cmp     al, 50h                 ; The 3rd byte is always 50h in Vortex86 SoC (if this is the case, we need just the highest byte)
  65.         jnz     .notVortex86
  66.         mov     bl, ah                  ; Copy SoC type to BL since EAX (that includes AH) is used implicitly in "LODSD" command below
  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)
  91.         DEBUGF  1, "unknown Vortex86 CPU (id=%d, last known is %d)\n", [Vortex86CPUid]:1, Vortex86SoCnum
  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: