Index: kernel/arch/ia32/src/boot/boot.S
===================================================================
--- kernel/arch/ia32/src/boot/boot.S	(revision f4fa6d97622246b092c84b7d84bfeffa10cbe6a4)
+++ kernel/arch/ia32/src/boot/boot.S	(revision a347a110d7ea83c8d45c6874cb10eb949d5d595c)
@@ -99,6 +99,32 @@
 #include "vesa_prot.inc"
 	
-	/* Map kernel and turn paging on */
-	call map_kernel
+#ifndef PROCESSOR_i486
+	
+	pm_status $status_prot2
+	
+	movl $(INTEL_CPUID_LEVEL), %eax
+	cpuid
+	cmp $0x0, %eax  /* any function > 0? */
+	jbe pse_unsupported
+	
+	movl $(INTEL_CPUID_STANDARD), %eax
+	cpuid
+	bt $(INTEL_PSE), %edx
+	jnc pse_unsupported
+		
+		/* Map kernel and turn paging on */
+		pm_status $status_pse
+		call map_kernel_pse
+		jmp stack_init
+	
+#endif /* PROCESSOR_i486 */
+	
+	pse_unsupported:
+		
+		/* Map kernel and turn paging on */
+		pm_status $status_non_pse
+		call map_kernel
+	
+	stack_init:
 	
 	/* Create the first stack frame */
@@ -106,5 +132,5 @@
 	movl %esp, %ebp
 	
-	pm2_status $status_prot2
+	pm2_status $status_prot3
 	
 	/* Call arch_pre_main(grub_eax, grub_ebx) */
@@ -124,72 +150,44 @@
 		jmp hlt0
 
-/** Calculate unmapped address of the end of the kernel. */
-calc_end_of_kernel:
-	movl $hardcoded_load_address, %edi
-	andl $0x7fffffff, %edi
-	movl (%edi), %esi
-	andl $0x7fffffff, %esi
-	
-	movl $hardcoded_ktext_size, %edi
-	andl $0x7fffffff, %edi
-	addl (%edi), %esi
-	andl $0x7fffffff, %esi
-	
-	movl $hardcoded_kdata_size, %edi
-	andl $0x7fffffff, %edi
-	addl (%edi), %esi
-	andl $0x7fffffff, %esi
-	movl %esi, end_of_kernel
+/** Setup mapping for the kernel (PSE variant)
+ *
+ * Setup mapping for both the unmapped and mapped sections
+ * of the kernel. For simplicity, we map the entire 4G space.
+ *
+ */
+.global map_kernel_pse
+map_kernel_pse:
+	/* Paging features */
+	movl %cr4, %ecx
+	orl $(1 << 4), %ecx      /* PSE on */
+	andl $(~(1 << 5)), %ecx  /* PAE off */
+	movl %ecx, %cr4
+	
+	movl $(page_directory + 0), %esi
+	movl $(page_directory + 2048), %edi
+	xorl %ecx, %ecx
+	xorl %ebx, %ebx
+	
+	floop_pse:
+		movl $((1 << 7) | (1 << 1) | (1 << 0)), %eax
+		orl %ebx, %eax
+		/* Mapping 0x00000000 + %ecx * 4M => 0x00000000 + %ecx * 4M */
+		movl %eax, (%esi, %ecx, 4)
+		/* Mapping 0x80000000 + %ecx * 4M => 0x00000000 + %ecx * 4M */
+		movl %eax, (%edi, %ecx, 4)
+		addl $(4 * 1024 * 1024), %ebx
+		
+		incl %ecx
+		cmpl $512, %ecx
+		jl floop_pse
+	
+	movl %esi, %cr3
+	
+	movl %cr0, %ebx
+	orl $(1 << 31), %ebx  /* paging on */
+	movl %ebx, %cr0
 	ret
 
-/** Find free 2M (+4k for alignment) region where to store page tables */
-find_mem_for_pt:
-	/* Check if multiboot info is present */
-	cmpl $0x2BADB002, grub_eax
-	je check_multiboot_map
-	ret
-check_multiboot_map:
-	/* Copy address of the multiboot info to ebx */
-	movl grub_ebx, %ebx
-	/* Check if memory map flag is present */
-	movl (%ebx), %edx
-	andl $(1 << 6), %edx
-	jnz use_multiboot_map
-	ret
-use_multiboot_map:
-	/* Copy address of the memory map to edx */
-	movl 48(%ebx), %edx
-	movl %edx, %ecx
-	addl 44(%ebx), %ecx
-	/* Find a free region at least 2M in size */
-	check_memmap_loop:
-		/* Is this a free region? */
-		cmp $1, 20(%edx)
-		jnz next_region
-		/* Check size */
-		cmp $0, 16(%edx)
-		jnz next_region
-		cmpl $(2 * 1024 * 1024 + 4 * 1024), 12(%edx)
-		jbe next_region
-		cmp $0, 8(%edx)
-		jz found_region
-	next_region:
-		cmp %ecx, %edx
-		jbe next_region_do
-		ret
-	next_region_do:
-		addl (%edx), %edx
-		addl $4, %edx
-		jmp check_memmap_loop
-	found_region:
-		/* Use end of the found region */
-		mov 4(%edx), %ecx
-		add 12(%edx), %ecx
-		sub $(2 * 1024 * 1024), %ecx
-		mov %ecx, free_area
-	ret
-		
-
-/** Setup mapping for the kernel.
+/** Setup mapping for the kernel (non-PSE variant).
  *
  * Setup mapping for both the unmapped and mapped sections
@@ -204,66 +202,165 @@
 	movl %ecx, %cr4
 	
-	call calc_end_of_kernel
+	call calc_kernel_end
 	call find_mem_for_pt
-	mov end_of_kernel, %esi
+	
+	mov kernel_end, %esi
 	mov free_area, %ecx
+	
 	cmpl %esi, %ecx
-	jbe use_end_of_kernel
-	mov %ecx, %esi
-	/* Align address down to 4k */
-	andl $(~4095), %esi
-use_end_of_kernel:
-	
-	/* Align address to 4k */
-	addl $4095, %esi
-	andl $(~4095), %esi
-	
-	/* Allocate space for page tables*/	
-	movl %esi, pt_loc
-	movl $ballocs, %edi
+	jbe use_kernel_end
+		
+		mov %ecx, %esi
+		
+		/* Align address down to 4k */
+		andl $(~4095), %esi
+		
+	use_kernel_end:
+		
+		/* Align address to 4k */
+		addl $4095, %esi
+		andl $(~4095), %esi
+		
+		/* Allocate space for page tables */
+		movl %esi, pt_loc
+		movl $ballocs, %edi
+		andl $0x7fffffff, %edi
+		
+		movl %esi, (%edi)
+		addl $4, %edi
+		movl $(2 * 1024 * 1024), (%edi)
+		
+		/* Fill page tables */
+		xorl %ecx, %ecx
+		xorl %ebx, %ebx
+		
+		floop_pt:
+			movl $((1 << 1) | (1 << 0)), %eax
+			orl %ebx, %eax
+			movl %eax, (%esi, %ecx, 4)
+			addl $(4 * 1024), %ebx
+			
+			incl %ecx
+			cmpl $(512 * 1024), %ecx
+			
+			jl floop_pt
+		
+		/* Fill page directory */
+		movl $(page_directory + 0), %esi
+		movl $(page_directory + 2048), %edi
+		xorl %ecx, %ecx
+		movl pt_loc, %ebx
+		
+		floop:
+			movl $((1 << 1) | (1 << 0)), %eax
+			orl %ebx, %eax
+			
+			/* Mapping 0x00000000 + %ecx * 4M => 0x00000000 + %ecx * 4M */
+			movl %eax, (%esi, %ecx, 4)
+			
+			/* Mapping 0x80000000 + %ecx * 4M => 0x00000000 + %ecx * 4M */
+			movl %eax, (%edi, %ecx, 4)
+			addl $(4 * 1024), %ebx
+			
+			incl %ecx
+			cmpl $512, %ecx
+			
+			jl floop
+		
+		movl %esi, %cr3
+		
+		movl %cr0, %ebx
+		orl $(1 << 31), %ebx  /* paging on */
+		movl %ebx, %cr0
+		
+		ret
+
+/** Calculate unmapped address of the end of the kernel. */
+calc_kernel_end:
+	movl $hardcoded_load_address, %edi
 	andl $0x7fffffff, %edi
-	movl %esi, (%edi)
-	addl $4, %edi
-	movl $(2*1024*1024), (%edi)
-	
-	/* Fill page tables */
-	xorl %ecx, %ecx
-	xorl %ebx, %ebx
-	
-	floop_pt:
-		movl $((1 << 1) | (1 << 0)), %eax
-		orl %ebx, %eax
-		movl %eax, (%esi, %ecx, 4)
-		addl $(4 * 1024), %ebx
-		
-		incl %ecx
-		cmpl $(512 * 1024), %ecx
-		jl floop_pt
-	
-	/* Fill page directory */
-	movl $(page_directory + 0), %esi
-	movl $(page_directory + 2048), %edi
-	xorl %ecx, %ecx
-	movl pt_loc, %ebx
-	
-	floop:
-		movl $((1 << 1) | (1 << 0)), %eax
-		orl %ebx, %eax
-		/* Mapping 0x00000000 + %ecx * 4M => 0x00000000 + %ecx * 4M */
-		movl %eax, (%esi, %ecx, 4)
-		/* Mapping 0x80000000 + %ecx * 4M => 0x00000000 + %ecx * 4M */
-		movl %eax, (%edi, %ecx, 4)
-		addl $(4 * 1024), %ebx
-		
-		incl %ecx
-		cmpl $512, %ecx
-		jl floop
-	
-	movl %esi, %cr3
-	
-	movl %cr0, %ebx
-	orl $(1 << 31), %ebx  /* paging on */
-	movl %ebx, %cr0
+	movl (%edi), %esi
+	andl $0x7fffffff, %esi
+	
+	movl $hardcoded_ktext_size, %edi
+	andl $0x7fffffff, %edi
+	addl (%edi), %esi
+	andl $0x7fffffff, %esi
+	
+	movl $hardcoded_kdata_size, %edi
+	andl $0x7fffffff, %edi
+	addl (%edi), %esi
+	andl $0x7fffffff, %esi
+	movl %esi, kernel_end
+	
 	ret
+
+/** Find free 2M (+4k for alignment) region where to store page tables */
+find_mem_for_pt:
+	/* Check if multiboot info is present */
+	cmpl $MULTIBOOT_LOADER_MAGIC, grub_eax
+	je check_multiboot_map
+		
+		ret
+	
+	check_multiboot_map:
+		
+		/* Copy address of the multiboot info to ebx */
+		movl grub_ebx, %ebx
+		
+		/* Check if memory map flag is present */
+		movl (%ebx), %edx
+		andl $(1 << 6), %edx
+		jnz use_multiboot_map
+			
+			ret
+		
+	use_multiboot_map:
+		
+		/* Copy address of the memory map to edx */
+		movl 48(%ebx), %edx
+		movl %edx, %ecx
+		
+		addl 44(%ebx), %ecx
+		
+		/* Find a free region at least 2M in size */
+		check_memmap_loop:
+			
+			/* Is this a free region? */
+			cmp $1, 20(%edx)
+			jnz next_region
+			
+			/* Check size */
+			cmp $0, 16(%edx)
+			jnz next_region
+			
+			cmpl $(2 * 1024 * 1024 + 4 * 1024), 12(%edx)
+			jbe next_region
+			
+			cmp $0, 8(%edx)
+			jz found_region
+		
+		next_region:
+			
+			cmp %ecx, %edx
+			jbe next_region_do
+			
+				ret
+		
+		next_region_do:
+			
+			addl (%edx), %edx
+			addl $4, %edx
+			jmp check_memmap_loop
+			
+		found_region:
+			
+			/* Use end of the found region */
+			mov 4(%edx), %ecx
+			add 12(%edx), %ecx
+			sub $(2 * 1024 * 1024), %ecx
+			mov %ecx, free_area
+			
+			ret
 
 /** Print string to EGA display (in light red) and halt.
@@ -610,5 +707,4 @@
 grub_eax:
 	.long 0
-
 grub_ebx:
 	.long 0
@@ -616,14 +712,15 @@
 pt_loc:
 	.long 0
-end_of_kernel:
+kernel_end:
 	.long 0
 free_area:
 	.long 0
 
-err_pse:
-	.asciz "Page Size Extension not supported. System halted."
-
 status_prot:
 	.asciz "[prot] "
+status_pse:
+	.asciz "[pse] "
+status_non_pse:
+	.asciz "[non_pse] "
 status_vesa_copy:
 	.asciz "[vesa_copy] "
@@ -634,4 +731,6 @@
 status_prot2:
 	.asciz "[prot2] "
+status_prot3:
+	.asciz "[prot3] "
 status_main:
 	.asciz "[main] "
