Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

564 lines
19 KiB

  1. ;++
  2. ;
  3. ; Copyright (c) 1991 Microsoft Corporation
  4. ;
  5. ; Module Name:
  6. ;
  7. ; spdetect.asm
  8. ;
  9. ; Abstract:
  10. ;
  11. ; This modules detects a SystemPro or compatible. It is INCLUDED
  12. ; by SPIPI and other binaries whom need to know how to detect a
  13. ; SystemPro type MP machine (ie, setup). It must assemble more or
  14. ; less standalone and run in protect mode.
  15. ;
  16. ; Author:
  17. ;
  18. ; Ken Reneris (kenr) 13-Jan-1992
  19. ;
  20. ; Revision History:
  21. ;
  22. ;--
  23. include halsp\i386\spmp.inc
  24. include callconv.inc ; calling convention macros
  25. _TEXT SEGMENT DWORD PUBLIC 'DATA'
  26. ; spSystemType: SystemType is read from 0c80-0c83h.
  27. ; 0c80-0c81: 0e11: Compressed CPQ (5 bit encoding).
  28. ; 0c82: System Board type.
  29. ; 0c83: System Board revision level.
  30. spSystemCpuTable dd 0e1101h ; CPQ01xx 386 ASP
  31. dd 0e1111h ; CPQ11xx 486 ASP
  32. dd 0e1150h ; CPQ50xx plug in processor
  33. dd 0e1159h ; CPQ59xx plug in processor
  34. dd 0e115bh ; CPQffxx plug in processor
  35. dd 0e1115h ; CPQ15xx (smp version)
  36. dd 0e1152h ; CPQ15xx (smp version)
  37. dd 0e1108h ; CPQ15xx
  38. dd 0592a0h ; ALRa0xx PowerPro
  39. dd 0592b0h ; ALRb0xx PowerPro plug in processor
  40. dd 047232h ; Acer SP clone (4p version)
  41. dd 246c00h ; ICL MX
  42. dd 246c02h ; ICL (acer 700xx)
  43. dd 352310h ; Micronycs MPro motherboard
  44. dd 352311h ; Micronycs MPro
  45. dd 0592a1h ; ALRa1xx PowerPro (DX2-66 mobo)
  46. dd 0592a2h ; ALRa2xx PowerPro (reserved mobos)
  47. dd 0592b1h ; ALRb1xx PowerPro (reserved p2's)
  48. dd 4dc901h ; Siemens Nixdorf PCE-4T/33
  49. dd 4dc950h ; Siemens Nixdorf PCE-4T/33
  50. dd 047219h ; AcerFrame 700
  51. dd 047232h ; AcerFrame 3000MP560
  52. dd 0h
  53. CPUTABLE_SIZE equ ($-spSystemCpuTable)/4
  54. ; Types match up to CpuTable.
  55. spSystemTypeTable db SMP_SYSPRO1 ; CPQ01xx 386 ASP
  56. db SMP_SYSPRO1 ; CPQ11xx 486 ASP
  57. db SMP_SYSPRO1 ; CPQ50xx plug in processor
  58. db SMP_SYSPRO1 ; CPQ59xx plug in processor
  59. db SMP_SYSPRO1 ; CPQffxx plug in processor
  60. db SMP_SYSPRO2 ; CPQ15xx (smp version)
  61. db SMP_SYSPRO2 ; CPQ15xx (smp version)
  62. db SMP_SYSPRO1 ; CPQ15xx
  63. db SMP_SYSPRO1 ; ALRa0xx PowerPro
  64. db SMP_SYSPRO1 ; ALRb0xx PowerPro
  65. db SMP_ACER ; Acer SP clone (4p version)
  66. db SMP_ACER ; ICL MX
  67. db SMP_ACER ; ICL (acer 700xx)
  68. db SMP_SYSPRO1 ; Micronycs MPro motherboard
  69. db SMP_SYSPRO1 ; Micronycs MPro
  70. db SMP_SYSPRO1 ; ALRa1xx PowerPro (DX2-66 mobo)
  71. db SMP_SYSPRO1 ; ALRa2xx PowerPro (reserved mobos)
  72. db SMP_SYSPRO1 ; ALRb1xx PowerPro (reserved p2's)
  73. db SMP_SYSPRO1 ; Siemens Nixdorf PCE-4T/33
  74. db SMP_SYSPRO1 ; Siemens Nixdorf PCE-4T/33
  75. db SMP_ACER ; AcerFrame 700
  76. db SMP_ACER ; AcerFrame 3000MP560
  77. TYPETABLE_SIZE equ ($-spSystemTypeTable)
  78. .errnz (CPUTABLE_SIZE - TYPETABLE_SIZE - 1)
  79. ;
  80. ; Order to check eisa ports in..
  81. ;
  82. SpPortOrder dw 0000, 0F000h, 0C000h, 0D000h, -1
  83. SpCOMPAQ db 'COMPAQ'
  84. SpEISA db 'EISA'
  85. Sp80386 db '80386'
  86. Sp80486 db '80486'
  87. _TEXT ends
  88. _DATA SEGMENT DWORD PUBLIC 'DATA'
  89. public _SpType, _SpCpuCount, _SpProcessorControlPort
  90. _SpType db -1 ; Lowest SMP_SYSPRO type found
  91. _SpCpuCount db 0 ; # of Cpus found
  92. _SpProcessorControlPort dw 00000h+PCR_OFFSET
  93. dw 0F000h+PCR_OFFSET
  94. dw 0C000h+PCR_OFFSET
  95. dw 0D000h+PCR_OFFSET
  96. RestoreESP dd 0
  97. RestoreESP1 dd 0
  98. _DATA ends
  99. page ,132
  100. _TEXT SEGMENT DWORD PUBLIC 'CODE'
  101. ASSUME DS:FLAT, ES:FLAT, SS:NOTHING, FS:NOTHING, GS:NOTHING
  102. ;++
  103. ; BOOLEAN
  104. ; DetectSystemPro (
  105. ; OUT PBOOLEAN IsConfiguredMp
  106. ; );
  107. ;
  108. ; Routine Description:
  109. ; This function is only called on EISA machines
  110. ;
  111. ; Determines the type of system (specifically for eisa machines).
  112. ;
  113. ; Arguments:
  114. ; IsConfiguredMp - If the machine is a SystemPro, then this value is
  115. ; set to TRUE if it's an MP SystemPro, else FALSE.
  116. ;
  117. ; Return Value:
  118. ; FALSE - not a supported machine for this HAL
  119. ; TRUE - is SystemPro
  120. ; etc...
  121. ;
  122. ;--
  123. cPublicProc _DetectSystemPro ,1
  124. push edi
  125. push esi
  126. push ebx ; Save C Runtime
  127. movzx edx, SpPortOrder[0] ; Check system board for
  128. call CheckEisaCard ; SystemPro belize ID
  129. if 0
  130. or eax, eax
  131. jz dsp_idnotknown
  132. endif
  133. cmp al, SMP_SYSPRO2
  134. je dsp_belize ; if belize, go count belize style
  135. xor ebx, ebx ; CpuCount
  136. xor esi, esi ; Base EisaCard address
  137. dsp10: movzx edx, SpPortOrder[esi*2]
  138. cmp dx, -1 ; End of list?
  139. je short dsp30 ; Yes, done
  140. call CheckEisaCard ; Check Eisa card for cpu
  141. or eax, eax ; If not cpu, then skip it
  142. jz short dsp20
  143. cmp _SpType, al
  144. jc @f
  145. mov _SpType, al ; SpType = min(SpType, eax)
  146. @@:
  147. cmp ebx, 4 ; MaxSupported CPUs already found?
  148. jae dsp20 ; Yes, then skip this one
  149. movzx edx, SpPortOrder[esi*2]
  150. add edx, PCR_OFFSET
  151. mov _SpProcessorControlPort[ebx*2], dx
  152. inc ebx ; CpuCount += 1
  153. dsp20: inc esi ; Next EisaCard I/O addr to check
  154. jmp short dsp10
  155. dsp30: xor eax, eax ; Assume FALSE
  156. ifdef SETUP
  157. cmp bl, 2 ; Did we find at least 2 CPUs?
  158. else
  159. cmp bl, 1 ; Did we find at least 1 CPU?
  160. endif
  161. jc short SpExit ; No, then exit
  162. mov _SpCpuCount, bl
  163. mov al, 1 ; return non-zero
  164. mov ebx, dword ptr [esp+16]
  165. mov byte ptr [ebx], al ; *IsConfiguredMp = TRUE
  166. SpExit: pop ebx
  167. pop esi
  168. pop edi
  169. stdRET _DetectSystemPro
  170. ;-----
  171. dsp_belize:
  172. mov _SpType, al ; SpType = SYSPRO2
  173. ;
  174. ; Put Belize SystemPro into Symmetric mode
  175. ;
  176. mov dx, SMP_MODE_PORT
  177. mov al, SMP_SYMMETRICAL_MODE
  178. out dx, al
  179. ;
  180. ; Count CPUs, belize style. And assign logcal IDs to CPUs
  181. ;
  182. xor ecx,ecx ;physical cpu
  183. xor ebx,ebx ;logical cpu
  184. dsp50:
  185. mov dx,SMP_INDEX_PORT
  186. mov al,cl ; al = physical CPU slot number
  187. out dx, al ; select physical CPU slot in al
  188. mov dx,SMP_ASSIGNMENT_PORT
  189. in al,dx ; read CPU number
  190. cmp al,SMP_MAX_PROCESSORS ; Q:Valid CPU?
  191. jae short dsp60 ; n:Check next physical CPU slot
  192. mov al,bl ; y:Make physical CPU a logical CPU
  193. out dx,al
  194. inc ebx ; next logical CPU to assign
  195. dsp60:
  196. inc ecx ; next physical CPU slot to check
  197. cmp ecx,SMP_MAX_PROCESSORS
  198. jb short dsp50 ; look in next cpu slot
  199. jmp short dsp30 ; ebx = number of cpus found
  200. ;-----
  201. if 0 ; Note: this code is not fully working (did not pass hct's)
  202. public dsp_idnotknown
  203. dsp_idnotknown:
  204. ;
  205. ; The eisa ID was not recongonized - attempt to use the protect mode
  206. ; int-15 interface to determine if this is a SystemPro compatible
  207. ; computer. Any SystemPro detected in this manner is assumed to
  208. ; be of type SMP_SYSPRO1 which only has 2 processors.
  209. ;
  210. ; Note: There is a fair amount of paranoia in the following code
  211. ; becuase we trust the rom as little as possible.
  212. ;
  213. xor eax, eax
  214. xor ecx, ecx
  215. mov cx, ss ; Verify SS value is what it is
  216. cmp ecx, KGDT_R0_DATA ; expect it to be; otherwise this code
  217. jne short SpExit ; can't work
  218. pushf ; Save current DF & EF
  219. sub esp, 15*8
  220. sidt fword ptr [esp] ; get IDT address
  221. mov esi, dword ptr [esp+2] ; (esi) = IDT
  222. mov edi, esp ; (edi) = address to copy vectors to
  223. push es ; Save selectors in case rom
  224. push ds ; trashes state
  225. push fs
  226. push gs
  227. push esi
  228. push ebp
  229. cld
  230. cli
  231. pushf
  232. ;
  233. ; Save and hook some IDT vectors. If we get some type of trap
  234. ; here or in the rom, then we will restore the state and return
  235. ; back that a systempro was not detected
  236. ;
  237. mov eax, esi
  238. mov ecx, 15*8/4
  239. rep movsd ; Save IDT vectors
  240. mov RestoreESP, esp ; Save current ESP for restore
  241. mov ecx, offset FLAT:dsp_handlefault
  242. mov dx, cs
  243. shl edx, 16
  244. mov dx, cx
  245. mov cx, 08E00h ; Install int32 gate for vectors
  246. mov [eax+0*8+0] , edx
  247. mov [eax+0*8+4] , ecx ; Trap IDT 0 Divide Error
  248. mov [eax+4*8+0] , edx
  249. mov [eax+4*8+4] , ecx ; Trap IDT 4 INTO
  250. mov [eax+5*8+0] , edx
  251. mov [eax+5*8+4] , ecx ; Trap IDT 5 BOUND
  252. mov [eax+6*8+0] , edx
  253. mov [eax+6*8+4] , ecx ; Trap IDT 6 Invalid OpCode
  254. mov [eax+11*8+0], edx
  255. mov [eax+11*8+4], ecx ; Trap IDT 11 Segment not present
  256. mov [eax+12*8+0], edx
  257. mov [eax+12*8+4], ecx ; Trap IDT 12 Stack fault
  258. mov [eax+13*8+0], edx
  259. mov [eax+13*8+4], ecx ; Trap IDT 13 GP fault
  260. mov [eax+14*8+0], edx
  261. mov [eax+14*8+4], ecx ; Trap IDT 14 Page fault
  262. ;
  263. ; Map in 64K of the ROM in order to use protect mode int-15 interface.
  264. ; (see Compaq eisa spec)
  265. ;
  266. stdCall _HalpMapPhysicalMemory, <0f0000h, 16> ; map 64K of ROM
  267. mov ebp, eax ; save ROM starting address
  268. ;
  269. ; Verify there is a ROM, search for the word 'COMPAQ' in the ROM
  270. ; addresses FE000-FE0FF. (see Compaq eisa spec)
  271. ;
  272. lea esi, SpCOMPAQ ; 'COMPAQ'
  273. mov ebx, 6 ; strlen ('COMPAQ')
  274. lea edi, [ebp+0e000h] ; address to scan
  275. mov ecx, 0ffh ; length of scan
  276. call SpScanForString
  277. jne dsp_handlefault ; if not found then abort
  278. ;
  279. ; Also verify the 'EISA' work at rom address FFFD0-FFFFF
  280. ; (see Compaq eisa spec)
  281. ;
  282. lea esi, SpEISA ; 'EISA'
  283. mov ebx, 4 ; strlen ('EISA')
  284. lea edi, [ebp+0ffd0h] ; address to scan
  285. mov ecx, 02fh ; length of scan
  286. call SpScanForString
  287. jne dsp_handlefault ; if not found then abort
  288. ;
  289. ; Look in slot 11 and slot 15 for processors
  290. ;
  291. sub esp, 400 ; make space for Config Data Block
  292. mov ecx, 11 ; check slot 11 first
  293. xor ebx, ebx ; assume no processors found
  294. dsp_95:
  295. push ebp ; save virtual rom address
  296. push ecx ; save current slot #
  297. push ebx ; save # processors found
  298. xor eax, eax
  299. lea edi, [esp+12]
  300. mov ecx, 300/4
  301. rep stosd ; clear destionation buffer
  302. mov ax, 0D881h ; Read Config Info, 32bit
  303. lea esi, [esp+12] ; destionation address
  304. mov RestoreESP1, esp ; Some roms don't iret correctly
  305. sub esp, 10h ; Some roms clobber some stack
  306. pushf
  307. push cs
  308. lea ebx, [ebp+0f859h] ; 'industry standard' int-15 address
  309. call ebx ; INT-15 (trashes most registers)
  310. mov esp, RestoreESP1 ; restore ESP
  311. jc short dsp_110 ; Not valid, check next slot
  312. ;
  313. ; Check type field
  314. ;
  315. lea edi, [esp+12+23h] ; address of type string
  316. lea esi, Sp80386 ; '80386'
  317. mov ebx, 5 ; strlen ('80386')
  318. mov ecx, 80
  319. call SpScanForString
  320. je short dsp_105
  321. lea edi, [esp+12+23h] ; address of type string
  322. lea esi, Sp80486 ; '80486'
  323. mov ebx, 5 ; strlen ('80486')
  324. mov ecx, 80
  325. call SpScanForString
  326. jne short dsp_110
  327. dsp_105:
  328. ; string was either 80386 or 80486
  329. inc dword ptr [esp] ; count one more processor
  330. dsp_110:
  331. pop ebx ; (ebx) = number processors found
  332. pop ecx ; (ecx) = slot #
  333. pop ebp ; (ebp) = virtual rom address
  334. or ebx, ebx ; if a processor is not in the first
  335. jz short dsp_handlefault ; slot, then don't look in second
  336. cmp ebx, 2 ; if # of processors is trash
  337. ja short dsp_handlefault ; then abort
  338. mov eax, ecx
  339. cmp eax, 11 ; Did we just test slot 11?
  340. mov ecx, 15
  341. je dsp_95 ; Yes, now test 15
  342. cmp eax, 15 ; Did we just test slot 15?
  343. je short dsp_cleanup ; Yes, then we are done
  344. ; slot # isn't 11 or 15, abort
  345. dsp_handlefault: ; Sometype of fault, or abort
  346. mov eax, KGDT_R0_DATA ; make sure ss has the correct value
  347. mov ss, ax
  348. xor ebx, ebx ; No processors found
  349. dsp_cleanup:
  350. ; (ebx) = # of processors
  351. mov esp, SS:RestoreESP ; Make sure esp is correct
  352. popf
  353. pop ebp
  354. pop edi ; (edi) = IDT address
  355. pop gs ; restore selectors
  356. pop fs
  357. pop ds
  358. pop es
  359. mov esi, esp ; (esi) = original IDT vectors
  360. mov ecx, 15*8/4
  361. rep movsd ; restore IDT vectors
  362. add esp, 15*8 ; cleanup stack
  363. popf
  364. mov _SpType, SMP_SYSPRO1 ; assume original systempro
  365. cmp ebx, 2 ; at least 2 processors found?
  366. jc short dsp_150 ; no, continue
  367. ;
  368. ; Verify that the second processor board is enabled
  369. ;
  370. movzx edx, SpPortOrder[1*2]
  371. add edx, EBC_OFFSET ; (edx) = 0zC84
  372. in al, dx ; Read control bits
  373. test al, 1 ; Is Eisa CPU board enabled?
  374. jnz short dsp_150 ; Yes, continue
  375. dec ebx ; don't count it
  376. dsp_150:
  377. jmp dsp30 ; exit
  378. endif
  379. stdENDP _DetectSystemPro
  380. ;++
  381. ; SpScanForString
  382. ;
  383. ; Routine Description:
  384. ; Scans address range looking for matching string
  385. ;
  386. ; Arguments:
  387. ; (edi) = Start of address range to scan
  388. ; (ecx) = Length of address range
  389. ; (esi) = String to scan for
  390. ; (ebx) = Length of string
  391. ;
  392. ; Returns:
  393. ; ZR - String found
  394. ; NZ - String not found
  395. ;
  396. ;--
  397. SpScanForString proc
  398. sub ecx, ebx ; don't go past end
  399. inc ecx
  400. mov al, [esi] ; (al) = first char to scan for
  401. inc esi ; skip past first char
  402. dec ebx
  403. ss10: repne scasb ; look for first byte
  404. jecxz short ss20 ; byte found? No, exit
  405. push ecx
  406. push edi
  407. push esi
  408. mov ecx, ebx ; length of string to compare
  409. repe cmpsb ; is string at this location?
  410. or ecx, ecx ; ZF if strings match
  411. pop esi
  412. pop edi
  413. pop ecx
  414. jnz short ss10 ; continue looking
  415. ret ; ZR
  416. ss20: inc ecx ; NZ
  417. ret
  418. SpScanForString endp
  419. ;++
  420. ; CheckEisaCard
  421. ;
  422. ; Routine Description:
  423. ; Used only by DetectSystemPro.
  424. ;
  425. ; Arguments:
  426. ; (edx) = Eisa ID port to check
  427. ;
  428. ; Returns:
  429. ; (eax) = 0 card was not a valid cpu
  430. ; non-zero Cpu type
  431. ;
  432. ;--
  433. CheckEisaCard proc
  434. push edi
  435. push esi
  436. push ebx
  437. mov esi, edx
  438. add edx, PRODUCT_ID_OFFSET ; Product ID port
  439. xor eax, eax
  440. in al, dx ; 0zC80
  441. test al, 80h ; if bit 8 off?
  442. jnz short NoMatch ; no, then not an Eisa card
  443. shl eax, 8
  444. inc edx
  445. in al, dx ; 0zC81
  446. shl eax, 8
  447. inc edx
  448. in al, dx ; (eax)=dword of ports 0zC80-0zC82
  449. mov ecx, CPUTABLE_SIZE ; Scan CPU table looking for
  450. lea edi, spSystemCpuTable ; matching board ID
  451. repne scasd
  452. jecxz short NoMatch ; Was it found?
  453. sub ecx, CPUTABLE_SIZE-1
  454. neg ecx ; (ecx) = index CPU was found at
  455. movzx ecx, byte ptr spSystemTypeTable[ecx]
  456. or esi, esi ; SystemBoard?
  457. jz short @f ; Yes, then it is assumed enabled
  458. cmp cl, SMP_ACER ; If acer, assume it's enabled
  459. je short @f ; (machine incorrectly reports
  460. ; 'disable' on every other proc)
  461. mov edx, esi
  462. add edx, EBC_OFFSET ; (edx) = 0zC84
  463. in al, dx ; Read control bits
  464. test al, 1 ; Is Eisa CPU board enabled?
  465. jz short NoMatch ; No, then skip it
  466. @@:
  467. mov eax, ecx
  468. jmp short cei_exit
  469. NoMatch:
  470. xor eax, eax
  471. cei_exit:
  472. pop ebx
  473. pop esi
  474. pop edi
  475. ret
  476. CheckEisaCard endp
  477. _TEXT ENDS