Leaked source code of windows server 2003
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.

674 lines
17 KiB

  1. ;/* himem4.asm
  2. ; *
  3. ; * Microsoft Confidential
  4. ; * Copyright (C) Microsoft Corporation 1988-1991
  5. ; * All Rights Reserved.
  6. ; *
  7. ; * Modification History
  8. ; *
  9. ; * Sudeepb 14-May-1991 Ported for NT XMS support
  10. ; *
  11. ; * williamh 25-Sept-1992 Added RequestUMB and ReleaseUMB
  12. ; *
  13. ; * daveh 1-Feb-1994 Changed to do mem management on 32 bit side
  14. ; */
  15. page 95,160
  16. title himem4 - block allocation stuff
  17. .xlist
  18. include himem.inc
  19. include xmssvc.inc
  20. include vint.inc
  21. .list
  22. ; The stuff we provide:
  23. public Version
  24. public QueryExtMemory
  25. public AllocExtMemory
  26. public FreeExtMemory
  27. public LockExtMemory
  28. public UnlockExtMemory
  29. public GetExtMemoryInfo
  30. public ReallocExtMemory
  31. public end_of_hiseg
  32. public textseg
  33. public KiddValley
  34. public KiddValleyTop
  35. public cHandles
  36. public RequestUMB
  37. public ReleaseUMB
  38. ; externals from himem.asm
  39. extrn PrevInt15:dword
  40. extrn Moveit:word
  41. extrn fHMAMayExist:byte
  42. extrn fHMAExists:byte
  43. extrn winbug_fix:word
  44. extrn FLclEnblA20:far
  45. extrn FLclDsblA20:far
  46. _text ends
  47. funky segment word public 'funky'
  48. assume cs:funky,ds:_text
  49. extrn end_of_funky_seg:near
  50. org HISEG_ORG
  51. public LEnblA20
  52. public LDsblA20
  53. end_of_hiseg dw end_of_funky_seg
  54. textseg dw _text
  55. KiddValley dw end_of_funky_seg; The address of the handle table
  56. KiddValleyTop dw 0 ; end of handle table
  57. cHandles dw DEFHANDLES ; number of handles
  58. LEnblA20 dd _text:FLclEnblA20
  59. LDsblA20 dd _text:FLclDsblA20
  60. ;*----------------------------------------------------------------------*
  61. ;* *
  62. ;* Get XMS Version Number - FUNCTION 00h *
  63. ;* *
  64. ;* Returns the XMS version number *
  65. ;* *
  66. ;* ARGS: None *
  67. ;* RETS: AX = XMS Version Number *
  68. ;* BX = Internal Driver Version Number *
  69. ;* DX = 1 if HMA exists, 0 if it doesn't *
  70. ;* REGS: AX, BX and DX are clobbered *
  71. ;* *
  72. ;* INTERNALLY REENTRANT *
  73. ;* *
  74. ;*----------------------------------------------------------------------*
  75. Version proc far
  76. mov ax,XMSVersion
  77. mov bx,HimemVersion
  78. xor dh,dh
  79. ; Is Int 15h hooked?
  80. cmp word ptr [PrevInt15][2],0 ; Is the segment non-zero?
  81. jne VHooked
  82. mov dl,[fHMAMayExist] ; No, return the status at
  83. ret ; init time.
  84. VHooked:
  85. mov dl,[fHMAExists] ; Yes, return the real status
  86. ret
  87. Version endp
  88. ;*----------------------------------------------------------------------*
  89. ;* *
  90. ;* QueryExtMemory - FUNCTION 08h *
  91. ;* *
  92. ;* Returns the size of the largest free extended memory block in K *
  93. ;* *
  94. ;* ARGS: None *
  95. ;* RETS: AX = Size of largest free block in K. BL = Error code *
  96. ;* DX = Total amount of free extended memory in K *
  97. ;* REGS: AX, BX, DX, DI, SI and Flags clobbered *
  98. ;* *
  99. ;* INTERNALLY REENTRANT *
  100. ;* *
  101. ;*----------------------------------------------------------------------*
  102. QueryExtMemory proc far
  103. mov bl,0 ; assume no error
  104. XMSSVC XMS_QUERYEXTMEM
  105. test dx,dx
  106. jne QEM20
  107. mov bl,ERR_OUTOMEMORY
  108. QEM20:
  109. ret
  110. QueryExtMemory endp
  111. ;*----------------------------------------------------------------------*
  112. ;* *
  113. ;* AllocExtMemory - FUNCTION 09h *
  114. ;* *
  115. ;* Reserve a block of extended memory *
  116. ;* *
  117. ;* ARGS: DX = Amount of K being requested *
  118. ;* RETS: AX = 1 of successful, 0 otherwise. BL = Error Code *
  119. ;* DX = 16-bit handle to the allocated block *
  120. ;* REGS: AX, BX, DX and Flags clobbered *
  121. ;* *
  122. ;* Notice: called internally from ReallocExtMemory *
  123. ;* *
  124. ;* INTERNALLY NON-REENTRANT *
  125. ;* *
  126. ;*----------------------------------------------------------------------*
  127. hFreeBlock dw ?
  128. hUnusedBlock dw ?
  129. AllocExtMemoryNear proc near
  130. AllocExtMemoryNear endp
  131. AllocExtMemory proc far
  132. call FunkyCLI ; This is a non-reentrant function
  133. ; Scan the handle table looking for an unused handle
  134. xor ax,ax
  135. mov [hUnusedBlock],ax
  136. mov bx,[KiddValley]
  137. mov cx,[cHandles] ; Loop through the handle table
  138. ; Have we already found a free block which is large enough?
  139. AEMhLoop:
  140. cmp [bx].Flags,UNUSEDFLAG ; Is this block unused?
  141. jne AEMNexth ; No, get the next handle
  142. mov [hUnusedBlock],bx ; save this guy away
  143. jmp AEMGotHandle
  144. AEMNexth:
  145. add bx,SIZE Handle ; go check the next handle
  146. loop AEMhLoop
  147. ; We are at the end of the handle table and we didn't an unused
  148. ; handle
  149. jmp AEMOOHandles ; No, Case 4 - We're out of handles
  150. AEMGotHandle:
  151. mov di,[hUnusedBlock]
  152. XMSSVC XMS_ALLOCBLOCK ; ax=Base and dx=Size
  153. or ax,ax
  154. jz AEMOOMemory
  155. mov [di].Base,ax
  156. mov [di].Len,dx
  157. mov [di].Flags,USEDFLAG ; New.Flags = USED
  158. if keep_cs
  159. mov ax,callers_cs
  160. mov [si].Acs,ax ; keep track of allocator's cs:
  161. endif
  162. mov dx,[hUnusedBlock]
  163. mov ax,1
  164. xor bl,bl
  165. ret
  166. AEMOOMemory:
  167. mov bl,ERR_OUTOMEMORY
  168. jmp short AEMErrRet
  169. AEMOOHandles:
  170. mov bl,ERR_OUTOHANDLES
  171. AEMErrRet:
  172. xor ax,ax ; Return failure
  173. mov dx,ax
  174. ret
  175. AllocExtMemory endp
  176. ;*----------------------------------------------------------------------*
  177. ;* *
  178. ;* FreeExtMemory - FUNCTION 0Ah *
  179. ;* *
  180. ;* Frees a block of extended memory *
  181. ;* *
  182. ;* ARGS: DX = 16-bit handle to the extended memory block *
  183. ;* RETS: AX = 1 if successful, 0 otherwise. BL = Error code *
  184. ;* REGS: AX, BX, CX, DX, SI, DI and Flags clobbered *
  185. ;* *
  186. ;* called internally from ReallocExtMemory *
  187. ;* *
  188. ;* INTERNALLY NON-REENTRANT *
  189. ;* *
  190. ;*----------------------------------------------------------------------*
  191. FreeExtMemoryNear proc near
  192. FreeExtMemoryNear endp
  193. FreeExtMemory proc far
  194. call FunkyCLI ; This is a non-reentrant function
  195. call ValidateHandle ; Make sure handle is valid
  196. jnc FEMBadh
  197. mov si,dx ; Move the handle into SI
  198. cmp [si].cLock,0 ; make sure it points to unlocked block
  199. jne FEMLockedh
  200. mov [si].Flags,UNUSEDFLAG ; mark it as UNUSED
  201. cmp [si].Len,0 ; if zero length block
  202. jz FEMExit ; done if it was zero length
  203. mov ax,[si].Base
  204. mov dx,[si].Len
  205. XMSSVC XMS_FREEBLOCK ; ax=base dx=size in k
  206. or ax,ax
  207. je FEMBadh
  208. FEMExit:
  209. mov ax,1 ; Return success
  210. xor bl,bl
  211. ret
  212. FEMBadh:
  213. mov bl,ERR_INVALIDHANDLE
  214. jmp short FEMErrExit
  215. FEMLockedh:
  216. mov bl,ERR_EMBLOCKED
  217. FEMErrExit:
  218. xor ax,ax ; Return failure
  219. ret
  220. FreeExtMemory endp
  221. ;*----------------------------------------------------------------------*
  222. ;* *
  223. ;* LockExtMemory - FUNCTION 0Ch *
  224. ;* *
  225. ;* Locks a block of extended memory *
  226. ;* *
  227. ;* ARGS: DX = 16-bit handle to the extended memory block *
  228. ;* RETS: AX = 1 of successful, 0 otherwise. BL = Error code *
  229. ;* DX:BX = 32-bit linear address of the base of the memory block *
  230. ;* REGS: AX, BX, DX and Flags clobbered *
  231. ;* *
  232. ;* INTERNALLY NON-REENTRANT *
  233. ;* *
  234. ;*----------------------------------------------------------------------*
  235. LockExtMemory proc far
  236. call FunkyCLI ; This is a non-reentrant function
  237. call ValidateHandle ; Is the handle valid?
  238. jnc LEMBadh
  239. mov bx,dx ; Move the handle into BX
  240. ; Are we at some preposterously large limit?
  241. cmp [bx].cLock,0FFh
  242. je LEMOverflow
  243. inc [bx].cLock ; lock the block
  244. mov dx,[bx].Base ; return the 32-bit address of base
  245. mov bx,dx
  246. shr dx,6
  247. shl bx,10
  248. mov ax,1 ; return success
  249. ret
  250. LEMBadh:
  251. mov bl,ERR_INVALIDHANDLE
  252. jmp short LEMErrExit
  253. LEMOverflow:
  254. mov bl,ERR_LOCKOVERFLOW
  255. LEMErrExit:
  256. xor ax,ax ; Return failure
  257. mov dx,ax
  258. ret
  259. LockExtMemory endp
  260. ;*----------------------------------------------------------------------*
  261. ;* *
  262. ;* UnlockExtMemory - FUNCTION 0Dh *
  263. ;* *
  264. ;* Unlocks a block of extended memory *
  265. ;* *
  266. ;* ARGS: DX = 16-bit handle to the extended memory block *
  267. ;* RETS: AX = 1 if successful, 0 otherwise. BL = Error code *
  268. ;* REGS: AX, BX and Flags clobbered *
  269. ;* *
  270. ;* INTERNALLY NON-REENTRANT *
  271. ;* *
  272. ;*----------------------------------------------------------------------*
  273. UnlockExtMemory proc far
  274. call FunkyCLI ; This is a non-reentrant function
  275. call ValidateHandle ; Is the handle valid?
  276. jnc UEMBadh
  277. mov bx,dx ; Move the handle into BX
  278. cmp [bx].cLock,0 ; is handle locked?
  279. je UEMUnlocked ; No, return error
  280. dec [bx].cLock ; Unlock the block
  281. mov ax,1 ; Return success
  282. xor bl,bl
  283. ret
  284. UEMUnlocked:
  285. mov bl,ERR_EMBUNLOCKED
  286. jmp short UEMErrExit
  287. UEMBadh:
  288. mov bl,ERR_INVALIDHANDLE
  289. UEMErrExit:
  290. xor ax,ax
  291. ret
  292. UnlockExtMemory endp
  293. ;*----------------------------------------------------------------------*
  294. ;* *
  295. ;* GetExtMemoryInfo - FUNCTION 0Eh *
  296. ;* *
  297. ;* Gets other information about an extended memory block *
  298. ;* *
  299. ;* ARGS: DX = 16-bit handle to the extended memory block *
  300. ;* RETS: AX = 1 if successful, 0 otherwise. BL = Error code *
  301. ;* BH = EMB's lock count *
  302. ;* BL = Total number of unused handles in the system *
  303. ;* DX = EMB's length *
  304. ;* REGS: AX, BX, CX, DX and Flags clobbered *
  305. ;* *
  306. ;* INTERNALLY NON-REENTRANT *
  307. ;* *
  308. ;*----------------------------------------------------------------------*
  309. GetExtMemoryInfo proc far
  310. call FunkyCLI ; This is a non-reentrant function
  311. call ValidateHandle ; is the handle valid?
  312. jnc GEMBadh
  313. mov si,dx ; Move the handle into SI
  314. xor al,al ; count number of UNUSED handles
  315. mov bx,[KiddValley]
  316. mov cx,[cHandles] ; Loop through the handle table
  317. GEMLoop:
  318. cmp [bx].Flags,USEDFLAG ; Is this handle in use?
  319. je GEMNexth ; Yes, continue
  320. inc al ; No, increment the count
  321. GEMNexth:
  322. add bx,SIZE Handle
  323. loop GEMLoop
  324. mov dx,[si].Len ; Length in DX
  325. mov bh,[si].cLock ; Lock count in BH
  326. mov bl,al
  327. mov ax,1
  328. ret
  329. GEMBadh:
  330. mov bl,ERR_INVALIDHANDLE
  331. xor ax,ax
  332. ret
  333. GetExtMemoryInfo endp
  334. ;*----------------------------------------------------------------------*
  335. ;* *
  336. ;* ReallocExtMemory - FUNCTION 0Fh *
  337. ;* *
  338. ;* Reallocates a block of extended memory *
  339. ;* *
  340. ;* ARGS: DX = 16-bit handle to the extended memory block *
  341. ;* BX = new size for block *
  342. ;* RETS: AX = 1 if successful, 0 otherwise. BL = Error code *
  343. ;* REGS: trashes si,di,bx,cx,dx *
  344. ;* *
  345. ;* INTERNALLY NON-REENTRANT *
  346. ;* *
  347. ;*----------------------------------------------------------------------*
  348. ; Define our memory move structure for calling the move function
  349. ReallocExtMemory proc far
  350. call FunkyCLI ; This is a non-reentrant function
  351. call ValidateHandle ; is the handle valid?
  352. mov si,dx ; Move the handle into SI
  353. mov dx,bx ; Move the new length into dx
  354. mov bl,ERR_INVALIDHANDLE
  355. jnc REMError
  356. cmp [si].cLock,0 ; We can only work on unlocked EMBs
  357. mov bl,ERR_EMBLOCKED
  358. jnz REMError
  359. mov bx,dx
  360. cmp [si].Len,bx
  361. je REMExit
  362. mov ax,[si].Base
  363. mov dx,[si].Len
  364. XMSSVC XMS_REALLOCBLOCK ; ax = old base, dx = old size
  365. cmp cx,0 ; cx = new base, bx = new size
  366. je REM20
  367. mov [si].Base,cx
  368. mov [si].Len,bx
  369. REMExit:
  370. mov ax,1 ; succesful return
  371. xor bl,bl ; non-documented no-error return
  372. ret
  373. REM20:
  374. mov bl,ERR_OUTOMEMORY
  375. REMError:
  376. xor ax,ax
  377. ret
  378. ReallocExtMemory endp
  379. ;*----------------------------------------------------------------------*
  380. ;* *
  381. ;* FindAdjacent unused blocks *
  382. ;* *
  383. ;* Scan through handle list looking for blocks adjacent *
  384. ;* to a given handle. *
  385. ;* *
  386. ;* ARGS: SI handle of original block *
  387. ;* RETS: DI = handle of adjacent block below or zero if none *
  388. ;* BP = handle of adjacent block above or zero if none *
  389. ;* *
  390. ;* TRASHES: AX,BX,CX,DX *
  391. ;* *
  392. ;* messes with handle table - not reentrant - assumes ints disabled *
  393. ;* *
  394. ;*----------------------------------------------------------------------*
  395. FindAdjacent proc near
  396. mov ax,[si].Base ; look for blocks ending here
  397. mov dx,[si].Len
  398. add dx,ax ; and ending here
  399. xor di,di ; initialize to fail condition
  400. mov bp,di
  401. mov bx,[KiddValley] ; prepare to loop thru handle tab
  402. mov cx,[cHandles]
  403. push si ; preserve original handle
  404. FindAdj1:
  405. cmp [bx].Flags,FREEFLAG
  406. jnz FindAdj3 ; ignore blocks that aren't UNUSED
  407. mov si,[bx].Base
  408. cmp dx,si ; found beg block?
  409. jnz FindAdj2 ; skip if not
  410. mov bp,bx ; remember the handle
  411. or di,di ; did we already find a follower?
  412. jnz FindAdj9 ; we're done if so
  413. FindAdj2:
  414. add si,[bx].Len ; find length
  415. cmp si,ax ; does this block end at spec addr?
  416. jnz FindAdj3 ; skip if not
  417. mov di,bx ; remember the handle
  418. or bp,bp ; did we already find a leader?
  419. jnz FindAdj9 ; we're done if so
  420. FindAdj3:
  421. add bx,SIZE handle
  422. loop FindAdj1
  423. FindAdj9:
  424. pop si ; restore original handle
  425. ret
  426. ;
  427. FindAdjacent endp
  428. ;*----------------------------------------------------------------------*
  429. ;* *
  430. ;* ValidateHandle - *
  431. ;* *
  432. ;* Validates an extended memory block handle *
  433. ;* *
  434. ;* ARGS: DX = 16-bit handle to the extended memory block *
  435. ;* RETS: Carry is set if the handle is valid *
  436. ;* REGS: Preserved except the carry flag *
  437. ;* *
  438. ;*----------------------------------------------------------------------*
  439. ValidateHandle proc near
  440. pusha ; Save everything
  441. mov bx,dx ; Move the handle into BX
  442. ; The handle must be equal to or above "KiddValley".
  443. cmp bx,[KiddValley]
  444. jb VHOne
  445. ; The handle must not be above "KiddValleyTop".
  446. cmp bx,[KiddValleyTop]
  447. ja VHOne
  448. ; (The handle-"KiddValley") must be a multiple of a handle's size.
  449. sub dx,[KiddValley]
  450. mov ax,dx
  451. xor dx,dx
  452. mov cx,SIZE Handle
  453. div cx
  454. or dx,dx ; Any remainder?
  455. jnz VHOne ; Yup, it's bad
  456. ; Does the handle point to a currently USED block?
  457. cmp [bx].Flags,USEDFLAG
  458. jne VHOne ; This handle is not being used.
  459. ; The handle looks good to me...
  460. popa ; Restore everything
  461. stc ; Return success
  462. ret
  463. VHOne:
  464. ; It's really bad.
  465. popa ; Restore everything
  466. clc ; Return failure
  467. ret
  468. ValidateHandle endp
  469. BlkMovX proc near
  470. assume ds:_text
  471. jmp MoveIt
  472. BlkMovX endp
  473. ;-----------------------------------------------------------------------;
  474. ;This is the routine for XMS function 16, request UMB.
  475. ;
  476. ; Input:
  477. ; (DX) = requested size in paragraphs
  478. ;
  479. ; Output:
  480. ; (AX) = 1 if request is granted and
  481. ; (BX) = segment address of the requested block
  482. ; (DX) = actual size allocated in paragraphs
  483. ; = 0 if requtest failed and
  484. ; (BL) = 0B0h if a smaller UMB is available
  485. ; (BL) = 0B1h if no UMBs are available
  486. ; (DX) = largest UMB available.
  487. ;Modified: AX, BX, DX
  488. ;
  489. ;NOTE:
  490. ;The funcition was implemented in the 32bits xms because
  491. ;any memory we need for house keeping purpose are kept in extented memory
  492. ;rather than in the UMB itself(DOS arena). Of course, it has the penalty
  493. ;of ring transition each time a request being made. However, the major
  494. ;allocator of UMBs is IO.SYS, the device driver of MS-DOS for devicehigh
  495. ;and loadhigh during bootstrap. This should adjust the penalty a little bits.
  496. ;
  497. ;-----------------------------------------------------------------------;
  498. RequestUMB proc far
  499. XMSSVC XMS_REQUESTUMB
  500. ret
  501. RequestUMB endp
  502. ;-----------------------------------------------------------------------;
  503. ;This is the routine for XMS function 17, release UMB
  504. ;
  505. ; Input:
  506. ; (DX) = segment of the UMB block to be released
  507. ;
  508. ; Output:
  509. ; (AX) = 1 if the block was released successfully.
  510. ; (AX) = 0 if the block couldn't be released and
  511. ; (BL) = 0B2h if the given segment is invalid
  512. ; Modified: AX, BX
  513. ;
  514. ;Note:
  515. ; See note in RequestUMB
  516. ;-----------------------------------------------------------------------;
  517. ReleaseUMB proc far
  518. XMSSVC XMS_RELEASEUMB
  519. ret
  520. ReleaseUMB endp
  521. PUBLIC FunkyCLI
  522. FunkyCLI:
  523. FCLI
  524. ret
  525. PUBLIC FunkySTI
  526. FunkySTI:
  527. FSTI
  528. ret
  529. ;*----------------------------------------------------------------------*
  530. ;* *
  531. ;* NOTE: RequestUMB and ReleaseUMB will not be implemented by HIMEM. *
  532. ;* *
  533. ;*----------------------------------------------------------------------*
  534. funky ends
  535. end
  536.