Page 1 of 1

System resets when PAE is enabled

Posted: Sun Dec 21, 2008 2:36 pm
by sawdust
Hi,
I'm trying to setup paging with PAE enabled (2MB pages). As soon as the paging is turned on, the system restarts. Any idea on what's going on? The AMD CPU has PAE support. I checked the cpuid and feature flags already. I've seen people mapping the the last page dir entry in 4KB non-PAE paging. If that is required here, how is it done?
- Thanks in advance

Code: Select all

#define PAGE_SHIFT	21  // for 2MB page using PAE
#define PAGE_SIZE	(1 << PAGE_SHIFT)

struct pde {
	uint32_t addr_lo;
	uint32_t addr_hi;
} __attribute__ ((packed));

static inline void paging_on(void *pdp)
{
	__asm__ __volatile__(
		/* Load the page table address */
		"movl	%0, %%cr3\n\t"
		/* Enable pae */
		"movl	%%cr4, %%eax\n\t"
		"orl	$0x00000020, %%eax\n\t"
		"movl	%%eax, %%cr4\n\t"
		/* Enable paging */
		"movl	%%cr0, %%eax\n\t"
		"orl	$0x80000000, %%eax\n\t"
		"movl	%%eax, %%cr0\n\t"
		:
		: "r" (pdp)
		: "ax"
		);
}


struct pde gPageDir[2048]     __attribute__ ((aligned(4096)));
struct pde gPageDirPtrTab[4]  __attribute__ ((aligned(4096)));
struct pde *pd                __attribute__ ((aligned(4096)));
struct pde *pdptr             __attribute__ ((aligned(4096)));

void PAE_InitPaging(uint32_t maxmem)
{
    uint32_t i, cr0;
    uint32_t pageflags = PF_GLOBAL | PF_PRESENT | PF_KERNELPAGE | PF_READWRITE;

    pd    = gPageDir;
    pdptr = gPageDirPtrTab;

    paging_off();

        // Point the page directory pointers at the page directories 
    pdptr[0].addr_lo = ((uint32_t)&pd[512*0])|1;
    pdptr[1].addr_lo = ((uint32_t)&pd[512*1])|1;
    pdptr[2].addr_lo = ((uint32_t)&pd[512*2])|1;
    pdptr[3].addr_lo = ((uint32_t)&pd[512*3])|1;

   //identity-map (maxmem == 512MB-1)
    for(i = 0; i < maxmem; i+= PAGE_SIZE)
    {
        printf("%d.. ",i/PAGE_SIZE);
        pd[i/PAGE_SIZE].addr_lo = i | pageflags;
        pd[i].addr_hi = 0;
        printf("0x%x \n",pd[i/PAGE_SIZE].addr_lo);
    }

    printf("..... turning on paging..\n");    // <= crashes immediately after this print

    paging_on(pdptr);

    printf("mapping done..\n");
    return;
}

Re: System resets when PAE is enabled

Posted: Sun Dec 21, 2008 6:39 pm
by CodeCat
Try adding the 'hlt' instruction after the first instruction in paging_on. If it doesn't crash but instead hangs, then move it to after the next instruction, and so on. The first time it does crash, the hlt instruction will be right after the faulty instruction.

Re: System resets when PAE is enabled

Posted: Mon Dec 22, 2008 9:42 am
by jal
CodeCat wrote:Try adding the 'hlt' instruction after the first instruction in paging_on. If it doesn't crash but instead hangs, then move it to after the next instruction, and so on. The first time it does crash, the hlt instruction will be right after the faulty instruction.
Or, use a suitable debugger, like the Bochs one. Much easier.


JAL

Re: System resets when PAE is enabled

Posted: Mon Dec 22, 2008 12:58 pm
by sawdust

Code: Select all

__inline void paging_on(void *pdp)
{
	__asm__ __volatile__(
/* Load the page table address */
            "movl	%0, %%cr3\n\t"
/* Enable pae */
            "movl	%%cr4, %%eax\n\t"
            "orl	$0x20, %%eax\n\t"
            "movl	%%eax, %%cr4\n\t"
            
/* Enable paging */
            "movl	%%cr0, %%eax\n\t"
            "orl	$0x80000000, %%eax\n\t"
            "movl	%%eax, %%cr0\n\t"
            "hlt    \n\t"               <====== system resets just before this point
            :
            : "r" (pdp)
            : "ax"
            );
}
I inserted 'hlt' after every instruction and the reset happens after enabling paging. This paging_on() stub is taken from the popular memtest http://www.memtest86.com/ . The problem could be that I'm doing something wrong wrt the page-dir-ptr. My system has only 1GB physical memory and I guess it should be ok to enable PAE. Any help will be appreciated very much.
Thanks again
-sawdust

Re: System resets when PAE is enabled

Posted: Mon Dec 22, 2008 2:23 pm
by IanSeyler
[quote="sawdust"]

Code: Select all

__inline void paging_on(void *pdp)
{
	__asm__ __volatile__(
/* Load the page table address */
            "movl	%0, %%cr3\n\t"
...
Can you verify that the page table is located at memory address 0x00000000 ?

-Ian

Re: System resets when PAE is enabled

Posted: Mon Dec 22, 2008 2:31 pm
by CodeCat
It says %0, not $0, so it's a designation for a variable inside an asm block. And in this case that variable is 'pdp'.

Re: System resets when PAE is enabled - solved

Posted: Tue Dec 23, 2008 11:23 am
by sawdust
Thx guys. I put pdptr at known location, i.e., kernel_end. Everything works. 'hlt' really helped.
:)