asm { // ::/Doc/MemoryOverview.DD USE32 SYS_INIT_PAGE_TABLES:: //Check 1Gig page capability and set page size. MOV EAX, 0x80000001 CPUID MOV EAX, 1 << 21 BT EDX, 26 JNC @@05 MOV EAX, 1 << 30 @@05: MOV U32 [MEM_PAGE_SIZE], EAX //Set mapped space limit MOV EAX, [MEM_PHYSICAL_SPACE] MOV EDX, [MEM_PHYSICAL_SPACE + 4] BT U32 [MEM_PAGE_SIZE], 30 //Round-up to 1Gig boundary? JNC @@10 ADD EAX, 0x3FFFFFFF ADC EDX, 0 AND EAX, ~0x3FFFFFFF @@10: INC EDX //Need 4Gig extra for uncached alias up at top of space. MOV [MEM_MAPPED_SPACE], EAX MOV [MEM_MAPPED_SPACE + 4], EDX //How many 2Meg pages? MOV CL, 21 ADD EAX, 0x1FFFFF ADC EDX, 0 SHRD EAX, EDX SHR EDX, CL MOV [MEM_2MEG_NUM], EAX MOV [MEM_2MEG_NUM + 4], EDX //How many 1Gig pages? MOV CL, 9 ADD EAX, 0x1FF ADC EDX, 0 SHRD EAX, EDX SHR EDX, CL MOV [MEM_1GIG_NUM], EAX MOV [MEM_1GIG_NUM + 4], EDX //How many 512Gig pages? MOV CL, 9 ADD EAX, 0x1FF ADC EDX, 0 SHRD EAX, EDX SHR EDX, CL MOV [MEM_512GIG_NUM], EAX MOV [MEM_512GIG_NUM + 4], EDX //Set CSysFixedArea to zero MOV EDI, SYS_FIXED_AREA XOR EAX, EAX MOV ECX, sizeof(CSysFixedArea) / 4 REP_STOSD MOV U32 [MEM_PML2], EDI //Check for 1Gig page capability. BT U32 [MEM_PAGE_SIZE], 30 JC @@15 //Find PML2 Size MOV EAX, U32 [MEM_2MEG_NUM] ADD EAX, 0x1FF AND EAX, ~0x1FF SHL EAX, 3 ADD EDI, EAX //Find PML3 Size @@15: MOV U32 [MEM_PML3], EDI MOV EAX, U32 [MEM_1GIG_NUM] ADD EAX, 0x1FF AND EAX, ~0x1FF SHL EAX, 3 ADD EDI, EAX //Find PML4 Size MOV U32 [MEM_PML4], EDI MOV EAX, U32 [MEM_512GIG_NUM] ADD EAX, 0x1FF AND EAX, ~0x1FF SHL EAX, 3 ADD EAX, EDI MOV U32 [MEM_HEAP_BASE], EAX //Set page tables to zero MOV EDI, U32 [MEM_PML2] SUB EAX, EDI MOV ECX, EAX SHR ECX, 2 XOR EAX, EAX REP_STOSD //Check for 1Gig page capability. BT U32 [MEM_PAGE_SIZE], 30 JC @@30 //PML2: Use 2Meg Pages MOV EAX, 0x87 //bit 7 is page size (2Meg) XOR EDX, EDX MOV EDI, [MEM_PML2] MOV ECX, [MEM_2MEG_NUM] @@20: MOV U32 [EDI], EAX ADD EDI, 4 MOV U32 [EDI], EDX ADD EDI, 4 ADD EAX, 0x200000 ADC EDX, 0 LOOP @@20 //PML3: Use 2Meg Pages MOV EAX, [MEM_PML2] OR EAX, 7 XOR EDX, EDX MOV EDI, [MEM_PML3] MOV ECX, [MEM_1GIG_NUM] @@25: MOV U32 [EDI], EAX ADD EDI, 4 MOV U32 [EDI], EDX ADD EDI, 4 ADD EAX, 0x1000 ADC EDX, 0 LOOP @@25 JMP @@40 //PML3: Use 1Gig Pages @@30: MOV EAX, 0x87 //bit 7 is page size (1Gig) XOR EDX, EDX MOV EDI, [MEM_PML3] MOV ECX, [MEM_1GIG_NUM] @@35: MOV U32 [EDI], EAX ADD EDI, 4 MOV U32 [EDI], EDX ADD EDI, 4 ADD EAX, 0x40000000 ADC EDX, 0 LOOP @@35 //PML4 @@40: MOV EAX, [MEM_PML3] OR EAX, 7 XOR EDX, EDX MOV EDI, [MEM_PML4] MOV ECX, [MEM_512GIG_NUM] @@45: MOV U32 [EDI], EAX ADD EDI, 4 MOV U32 [EDI], EDX ADD EDI, 4 ADD EAX, 0x1000 ADC EDX, 0 LOOP @@45 RET SYS_INIT_16MEG_SYS_CODE_BP:: // Init sys_code_bp to BIOS E801 lowest 16Meg value. // BlkPoolsInit() adds the rest. MOV U32 [SYS_CODE_BP], SYS_FIXED_AREA + CSysFixedArea.sys_code_bp MOV U32 [SYS_CODE_BP + 4], 0 MOV U32 [SYS_DATA_BP], 0 MOV U32 [SYS_DATA_BP + 4], 0 XOR EAX, EAX MOV AX, U16 [MEM_E801] //1 Kb blocks between 1M and 16M SHL EAX, 10 ADD EAX, 0x100000 MOV EDI, U32 [MEM_HEAP_BASE] SUB EAX, EDI //EDI=BASE EAX=SIZE TEST U8 [SYS_MEM_INIT_FLAG], 1 JZ @@05 PUSH EAX PUSH EDI MOV ECX, EAX MOV AL, U8 [SYS_MEM_INIT_VAL] REP_STOSB POP EDI POP EAX @@05: SHR EAX, MEM_PAG_BITS MOV ESI, SYS_FIXED_AREA + CSysFixedArea.sys_code_bp MOV EBX, U32 CBlkPool.mem_free_list[ESI] MOV U32 CMemBlk.next [EDI], EBX MOV U32 CMemBlk.next + 4 [EDI], 0 MOV U32 CBlkPool.mem_free_list [ESI], EDI MOV U32 CBlkPool.mem_free_list + 4 [ESI], 0 MOV U32 CMemBlk.mb_signature[EDI], MBS_UNUSED_SIGNATURE_VAL MOV U32 CMemBlk.pags[EDI], EAX SHL EAX, MEM_PAG_BITS ADD U32 CBlkPool.alloced_u8s[ESI], EAX BTS U32 [SYS_RUN_LEVEL], RLf_16MEG_SYS_CODE_BP RET } I64 *MemPageTable(U8 *a) {//Point to page table entry for address. if (Bt(&mem_page_size, 30)) return *MEM_PML3(U64 *) + a >> 30 * 8; else return *MEM_PML2(U64 *) + a >> 21 * 8; }