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.

584 lines
15 KiB

  1. include kernel.inc
  2. include protect.inc
  3. .list
  4. .386p
  5. DataBegin
  6. externB WinFlags
  7. externW hGlobalHeap
  8. externW pGlobalHeap
  9. externW ArenaSel
  10. externD hBmDPMI
  11. externD FreeArenaList
  12. externD FreeArenaCount
  13. externD SelTableStart
  14. externW SelTableLen
  15. externW InitialPages
  16. DataEnd
  17. sBegin INITCODE
  18. assumes CS,CODE
  19. externNP get_physical_address
  20. externNP set_physical_address
  21. externNP set_selector_address32
  22. externNP set_selector_limit32
  23. externNP alloc_arena_header
  24. externNP AssociateSelector32
  25. externNP alloc_data_sel
  26. externNP alloc_data_sel32
  27. externNP GrowHeap
  28. externNP DPMIProc
  29. externFP greserve
  30. GA_ALIGN_BYTES = (((GA_ALIGN+1) SHL 4) - 1)
  31. GA_MASK_BYTES = NOT GA_ALIGN_BYTES
  32. ;-----------------------------------------------------------------------;
  33. ; get_selector_address32 ;
  34. ; ;
  35. ; Function to translate return of get_physical_address (DX:AX) into EAX ;
  36. ; ;
  37. ;-----------------------------------------------------------------------;
  38. cProc get_selector_address32,<PUBLIC,NEAR>
  39. parmW selector
  40. cBegin
  41. push dx
  42. cCall get_physical_address,<selector>
  43. shl eax, 16
  44. mov ax, dx
  45. ror eax, 16
  46. pop dx
  47. cEnd
  48. ;-----------------------------------------------------------------------;
  49. ; GlobalInit ;
  50. ; ;
  51. ; Procedure to initialize the global heap. Called with the starting ;
  52. ; and ending paragraph addresses. ;
  53. ; ;
  54. ; Arguments: ;
  55. ; parmW hdelta = size (.25k) of master object ;
  56. ; parmW palloc = block to mark allocated ;
  57. ; parmW pstart = first available address ;
  58. ; parmW pend = last available address ;
  59. ; ;
  60. ; Returns: ;
  61. ; AX = handle for allocated block ;
  62. ; ;
  63. ; Error Returns: ;
  64. ; ;
  65. ; Alters: ;
  66. ; ES ;
  67. ; Calls: ;
  68. ; ginit ;
  69. ; hthread ;
  70. ; ghalloc ;
  71. ; History: ;
  72. ; ;
  73. ; Sat Jun 20, 1987 05:55:35p -by- David N. Weise [davidw] ;
  74. ; Making real EMS work with the fast boot version. ;
  75. ; ;
  76. ; Sun Mar 15, 1987 06:38:04p -by- David N. Weise [davidw] ;
  77. ; Added support for the linked free list long ago. ;
  78. ; ;
  79. ; Wed Feb 18, 1987 08:09:18p -by- David N. Weise [davidw] ;
  80. ; Added the initialization of the gi_alt entries. ;
  81. ; ;
  82. ; Mon Sep 08, 1986 07:53:41p -by- David N. Weise [davidw ;
  83. ; Changed the return values so that this can be called from other than ;
  84. ; initialization code. ;
  85. ;-----------------------------------------------------------------------;
  86. cProc GlobalInit,<PUBLIC,NEAR>,<ds,si,di>
  87. parmW hdelta
  88. parmW palloc
  89. parmW pstart
  90. parmW pend
  91. localW emspalloc
  92. localW hInitMem
  93. localD allocated_arena
  94. localW next_block
  95. localW free_hi
  96. localW free_lo
  97. cBegin
  98. mov ax,palloc ; AX = block to mark allocated
  99. mov bx,pstart ; BX = first available address
  100. mov cx,hdelta ; CX = size (.25k) of master object
  101. mov dx,pend ; DX = last available address
  102. call ginit
  103. jc FailGlobalInit
  104. SetKernelDS es
  105. mov allocated_arena,eax
  106. xor edi,edi ; Initialize master object
  107. mov [di].phi_first,ebx ; Fill in pointers to first and
  108. mov [di].phi_last,edx ; last blocks
  109. mov [di].hi_count,4 ; 4 arena entries
  110. or eax,eax
  111. jnz short allocated_block
  112. mov [di].hi_count,3 ; 3 arena entries
  113. allocated_block:
  114. mov [di].gi_lruchain,edi ; Nothing in LRU list so far
  115. mov [di].gi_lrucount,di
  116. mov [di].gi_lrulock,di ; ...and not locked
  117. mov [di].gi_reserve,edi ; No discardable code reserve area yet
  118. push eax
  119. mov eax, ds:[edx.pga_address]
  120. mov word ptr [di].gi_disfence,ax ; gi_disfence = hi_last
  121. shr eax, 16
  122. mov word ptr [di].gi_disfence_hi,ax
  123. pop eax
  124. mov [di].gi_alt_first,-1 ; Fill in pointers to first and
  125. mov [di].gi_alt_last,-1 ; last blocks, the -1 is necessary!!
  126. mov [di].gi_alt_count,di ; # of arena entries
  127. mov [di].gi_alt_lruchain,di
  128. mov [di].gi_alt_lrucount,di ; MUST be 0!
  129. mov [di].gi_alt_free_count,di
  130. mov [di].gi_alt_reserve,di
  131. mov [di].gi_alt_disfence,di
  132. mov [di].gi_alt_pPhantom,-1 ; MUST be -1!
  133. mov ax, ds:[esi.pga_handle] ; Pick up master objects selector
  134. mov hGlobalHeap,ax
  135. mov ds:[esi].pga_count,0
  136. mov ds:[esi].pga_selcount,1
  137. mov esi,ds:[edx].pga_prev ; Point to allocated object before
  138. mov bx,ds:[esi.pga_handle]
  139. StoH bx ; It is moveable
  140. mov ds:[esi].pga_handle,bx
  141. mov hInitMem,bx
  142. mov ds:[esi].pga_count,0
  143. no_allocated_object:
  144. ; initialize free list
  145. mov [di].gi_free_count,1
  146. mov eax,[di].phi_first
  147. mov ecx,[di].phi_last
  148. mov ebx,ds:[eax].pga_next
  149. mov ds:[eax].pga_freeprev,-1 ; Fill in first sentinal
  150. mov ds:[eax].pga_freenext,ebx
  151. mov ds:[ecx].pga_freeprev,ebx ; Fill in last sentinal
  152. mov ds:[ecx].pga_freenext,-1
  153. mov ds:[ebx].pga_freeprev,eax ; Link in free block
  154. mov ds:[ebx].pga_freenext,ecx
  155. pushad
  156. SetKernelDS fs
  157. mov edx, 030000h ; Insist on enough for fence
  158. call GrowHeap
  159. jc short Failed_GrowHeap ;garage sale machine,tough luck!
  160. ; 192k (3 segs) fixed greserve
  161. mov ax, 1000h ; fence it all off. (in paras)
  162. push fs
  163. call greserve ; greserve will triple the no.
  164. pop fs
  165. or ax, ax
  166. stc ; assume failure
  167. jz short Failed_GrowHeap
  168. ifdef WOW
  169. clc
  170. ; WOW isn't greedy and doesn't have gcommit_block
  171. else
  172. mov esi, ds:[edi].phi_last ; sentinel
  173. mov esi, ds:[esi].pga_prev ; not_there
  174. mov esi, ds:[esi].pga_prev ; free blk
  175. call gcommit_block ; commit it all
  176. jc short Failed_GrowHeap ; to guarantee stable system
  177. ; Let's start with 20MB reserve and allocate more as reqd.
  178. mov edx, 20*1024*1024 ; Let's get greedy
  179. call GrowHeap
  180. clc ; we don't care about this fail
  181. endif
  182. Failed_GrowHeap:
  183. UnSetKernelDS fs
  184. popad
  185. jc short FailGlobalInit
  186. mov ax,hInitMem
  187. clc
  188. FailGlobalInit:
  189. cEnd
  190. ;-----------------------------------------------------------------------;
  191. ; ginit ;
  192. ; ;
  193. ; Procedure to initialize the global heap. ;
  194. ; ;
  195. ; The global heap looks as follows after this procedure returns: ;
  196. ; ;
  197. ; BX - first object in arena, alway busy, zero length. ;
  198. ; - free object ;
  199. ; AX - allocated object ;
  200. ; DS - master object ;
  201. ; DX - last object in arena, alway busy, zero length. ;
  202. ; ;
  203. ; ;
  204. ; Arguments: ;
  205. ; AX = address of block to mark allocated. May be zero. ;
  206. ; BX = address of first paragraph in arena ;
  207. ; DX = address of last paragraph in arena ;
  208. ; CX = initial size of master object, in bytes ;
  209. ; ;
  210. ; Returns: ;
  211. ; AX = aligned address of block marked allocated. ;
  212. ; BX = aligned address of first object in arena ;
  213. ; CX = size of master object, in bytes ;
  214. ; DX = aligned address of last object in arena ;
  215. ; DS = aligned address of master object ;
  216. ; ;
  217. ; Registers Preserved: ;
  218. ; ;
  219. ; Registers Destroyed: ;
  220. ; DI,SI,ES ;
  221. ; Calls: ;
  222. ; nothing ;
  223. ; History: ;
  224. ; ;
  225. ; Thu Sep 11, 1986 04:22:02p -by- David N. Weise [davidw] ;
  226. ; Commented it, made it handle the case of no allocated block correctly.;
  227. ;-----------------------------------------------------------------------;
  228. assumes ds, nothing
  229. assumes es, nothing
  230. cProc ginit,<PUBLIC,NEAR>
  231. localD size_free
  232. localD size_allocated
  233. localD size_master
  234. localD allocated_arena
  235. localW allocated_sel
  236. localD BurgerMaster_arena
  237. localW BurgerMaster_sel
  238. localD new_last_arena
  239. cBegin
  240. ; ESI = the first block address (sentinel, always busy)
  241. SetKernelDS es
  242. push ax
  243. cCall get_selector_address32,<bx> ; Start of our memory
  244. add eax, GA_ALIGN_BYTES ; Align our start
  245. and al, GA_MASK_BYTES
  246. push eax ; Save the start address
  247. cCall set_selector_address32,<bx,eax> ; This will be our arena list
  248. mov ArenaSel, bx
  249. mov BurgerMaster_sel, bx
  250. mov si, bx
  251. push bx
  252. push di
  253. xor bx, bx ; # physical pages available
  254. sub sp, 30h
  255. mov di, sp
  256. push es
  257. smov es, ss
  258. DPMICALL 0500h
  259. pop es
  260. mov eax, 16*1024 ; Size of selector table
  261. jc short default_sel_table
  262. mov bx, word ptr ss:[di][10h]
  263. cmp bx, 256
  264. jb short default_sel_table
  265. ;;;mov eax, 31*1024
  266. mov eax, 32*1024
  267. default_sel_table:
  268. mov [InitialPages], bx
  269. ; For WOW we assume 386 Kernel is running on paging System
  270. ; So always set WF1_PAGING
  271. ifndef WOW
  272. mov ecx, ss:[di][20h] ; Paging file size
  273. inc ecx
  274. cmp ecx, 1 ; 0 or -1?
  275. jbe short @F
  276. endif
  277. or byte ptr WinFlags[1], WF1_PAGING
  278. @@:
  279. mov ecx, ss:[di][0]
  280. shr ecx, 7 ; Bytes reserved for arenas
  281. add sp, 30h
  282. pop di
  283. pop bx
  284. add ecx, GA_ALIGN_BYTES ; Align length of arena table
  285. and cl, GA_MASK_BYTES
  286. add eax, GA_ALIGN_BYTES ; Align length of selector table
  287. and al, GA_MASK_BYTES
  288. mov SelTableLen, ax
  289. cmp ecx, DEFAULT_ARENA_SIZE ; Number of bytes of arenas
  290. jae short @F
  291. mov ecx, DEFAULT_ARENA_SIZE
  292. @@:
  293. mov ebx, Size GlobalInfo+GA_ALIGN_BYTES
  294. and bl, GA_MASK_BYTES ; EBX start of arenas
  295. mov size_master, ebx
  296. add ecx, ebx
  297. mov SelTableStart, ecx
  298. add eax, ecx ; EAX total length of segment
  299. push ecx
  300. push ebx
  301. push eax
  302. push si
  303. mov cx, ax ; Make BX:CX required
  304. mov ebx, eax ; length of Burgermaster
  305. shr ebx, 16
  306. push bx ; Save length
  307. push cx
  308. DPMICALL 0501h
  309. mov hBmDPMI[0], di ; Save DPMI handle
  310. mov hBmDPMI[2], si
  311. pop di ; SI:DI now length
  312. pop si
  313. jc Failginit
  314. if 0
  315. mov di, 4096 ; Lock first page
  316. xor si, si
  317. DPMICALL 0600h ; Now page lock it
  318. push bx
  319. push cx
  320. add cx, word ptr SelTableStart
  321. adc bx, 0
  322. and cx, not 4095
  323. DPMICALL 0600h
  324. pop cx
  325. pop bx
  326. endif
  327. shl ebx, 16
  328. mov bx, cx ; Address in EBX
  329. pop si
  330. pop eax
  331. cCall set_selector_address32,<si,ebx>
  332. mov edi, ebx
  333. ;;; cCall set_selector_limit32, <si,eax>
  334. push eax
  335. push dx
  336. dec eax
  337. mov ecx, eax ; Limit in CX:DX
  338. shr ecx, 16
  339. mov dx, ax
  340. test cx,0fff0h ; bits 20-31 set?
  341. jz @F ; No.
  342. or dx,0fffh ; Yes, page align limit.
  343. @@:
  344. mov bx, si ; Selector in BX
  345. DPMICALL 8
  346. pop dx
  347. pop eax
  348. pop ebx
  349. pop ecx
  350. jc Failginit
  351. mov ds, si
  352. sub ecx, ebx ; Subtract out BurgerMaster
  353. cCall InitialiseArenas,<ebx,ecx>
  354. mov ecx, eax
  355. pop esi ; Sentinel address
  356. cCall alloc_arena_header,<esi> ; Sentinel
  357. mov esi, eax
  358. cCall alloc_arena_header,<edi> ; BurgerMaster
  359. mov BurgerMaster_arena, eax
  360. mov ds:[eax].pga_handle, ds ; Save selector in handle field
  361. mov ds:[eax].pga_size, ecx
  362. push edi
  363. push ecx
  364. movzx ecx, SelTableLen
  365. mov edi, SelTableStart
  366. push es
  367. smov es, ds ; Zero this area
  368. UnSetKernelDS es
  369. shr ecx, 2
  370. xor eax, eax
  371. rep stos dword ptr es:[edi]
  372. pop es
  373. ReSetKernelDS es
  374. pop ecx
  375. pop edi
  376. cCall AssociateSelector32,<ds,BurgerMaster_Arena> ; Set back link
  377. ; EDI = the Free block address (initial free block)
  378. mov eax, ds:[esi].pga_address
  379. ;;; add eax, ecx
  380. cCall alloc_arena_header,<eax>
  381. mov edi, eax ; Free block arena in EDI
  382. movzx eax, dx ; Get linear address
  383. shl eax, 4
  384. ; EDX = the last block address (sentinel, always busy)
  385. and al, GA_MASK_BYTES
  386. push eax
  387. cCall alloc_arena_header,<eax>
  388. mov new_last_arena, eax ; Save it away
  389. pop ebx
  390. pop ax ; Allocated Block
  391. cCall get_selector_address32, <ax>
  392. and al, GA_MASK_BYTES ; "Align" it
  393. sub ebx, eax ; Length in bytes
  394. push eax
  395. push eax
  396. cCall alloc_arena_header, <eax>
  397. mov ds:[eax].pga_size, ebx ; Record size
  398. mov allocated_arena, eax
  399. mov ebx, eax
  400. pop eax
  401. cCall alloc_data_sel32, <eax, ds:[ebx].pga_size>
  402. mov allocated_sel, ax
  403. mov ds:[ebx.pga_handle], ax ; Save selector
  404. cCall AssociateSelector32,<ax,ebx> ; Set back link
  405. pop ebx
  406. sub ebx, ds:[edi].pga_address ; Length in bytes
  407. mov ds:[edi].pga_size, ebx
  408. mov eax, allocated_arena
  409. mov ecx, BurgerMaster_arena
  410. mov edx, new_last_arena
  411. ; Fill in first block
  412. xor ebx, ebx
  413. mov ds:[esi].pga_sig,GA_SIGNATURE
  414. mov ds:[esi].pga_size,ebx
  415. mov ds:[esi].pga_owner,-1
  416. mov ds:[esi].pga_flags,bx
  417. mov ds:[esi].pga_prev,esi ; first.prev = self
  418. mov ds:[esi].pga_next,edi ; first.next = free
  419. mov ds:[esi].pga_handle,bx
  420. mov ds:[esi].pga_lrunext,ebx
  421. mov ds:[esi].pga_lruprev,ebx
  422. ; Fill in the last block (sentinel block)
  423. mov ds:[edx].pga_sig,GA_ENDSIG
  424. mov ds:[edx].pga_size,ebx
  425. mov ds:[edx].pga_owner,-1 ; Always allocated
  426. mov ds:[edx].pga_next,edx ; last.next = self
  427. mov ds:[edx].pga_prev,eax ; last.prev = alloced
  428. mov ds:[edx].pga_flags,bx
  429. mov ds:[edx].pga_handle, bx
  430. mov ds:[edx].pga_lrunext,ebx
  431. mov ds:[edx].pga_lruprev,ebx
  432. ; Fill in the master object
  433. mov ds:[ecx].pga_next,ecx
  434. mov ds:[ecx].pga_prev,ecx
  435. mov ds:[ecx].pga_sig,GA_SIGNATURE
  436. mov ds:[ecx].pga_owner,-3
  437. mov ds:[ecx].pga_flags,bx
  438. mov ds:[ecx].pga_lruprev,ebx
  439. mov ds:[ecx].pga_lrunext,ebx
  440. ; Fill in the allocated block
  441. mov ds:[eax].pga_next,edx ; next object is Sentinel
  442. mov ds:[eax].pga_prev,edi ; Previous object is second block
  443. mov ds:[eax].pga_sig,GA_SIGNATURE
  444. mov ds:[eax].pga_owner,-1
  445. mov ds:[eax].pga_flags,bx
  446. mov ds:[eax].pga_lruprev,ebx
  447. mov ds:[eax].pga_lrunext,ebx
  448. ; Fill in free block
  449. mov ds:[edi].pga_sig,GA_SIGNATURE
  450. mov ds:[edi].pga_owner,bx ; This is a free block
  451. mov ds:[edi].pga_flags,bx
  452. mov ds:[edi].pga_next,eax ; Next obj allocated block
  453. mov ds:[edi].pga_prev,esi
  454. mov ds:[edi].pga_handle,bx
  455. mov ds:[edi].pga_lruprev,ebx
  456. mov ds:[edi].pga_lrunext,ebx
  457. ; Initialize master object
  458. mov ecx, size_master
  459. mov dx,BurgerMaster_sel
  460. shr ecx, 1
  461. push ecx ; save size in words
  462. mov pGlobalHeap,dx
  463. mov es,dx
  464. UnSetKernelDS es
  465. xor eax,eax
  466. xor di,di ; Init master object to zero
  467. shr ecx, 1
  468. rep stosd
  469. mov ds,dx ; Switch to master object as our DS
  470. pop ecx
  471. shl ecx,1 ; ECX = size of master object in bytes
  472. mov eax, allocated_arena ; EAX = address of allocated block
  473. mov edx, new_last_arena ; EDX = address of last block
  474. mov ebx, esi ; EBX = address of first block
  475. mov esi, BurgerMaster_arena ; ESI = arena of BurgerMaster
  476. clc
  477. Failginit:
  478. cEnd
  479. assumes ds, nothing
  480. assumes es, nothing
  481. cProc InitialiseArenas,<PUBLIC,NEAR>
  482. parmD StartOffset
  483. parmD BytesAllocated
  484. cBegin
  485. push ecx
  486. push esi
  487. push edi
  488. CheckKernelDS es
  489. ReSetKernelDS es
  490. mov esi, StartOffset
  491. mov ecx, BytesAllocated
  492. add ecx, esi
  493. mov FreeArenaList, esi ; Point to list
  494. lea edi, [esi+size GlobalArena32]
  495. IA_loop:
  496. cmp edi, ecx
  497. jae short IA_done
  498. mov [esi.pga_next], edi
  499. add esi, size GlobalArena32
  500. add edi, size GlobalArena32
  501. inc FreeArenaCount
  502. jmps IA_loop
  503. IA_done:
  504. mov ds:[esi.pga_next], -1 ; Terminate list
  505. UnSetKernelDS es
  506. pop edi
  507. pop esi
  508. pop ecx
  509. cEnd
  510. sEnd INITCODE
  511. end