Index: /trunk/hal/x86_64/core/hal_boot.h
===================================================================
--- /trunk/hal/x86_64/core/hal_boot.h	(revision 385)
+++ /trunk/hal/x86_64/core/hal_boot.h	(revision 386)
@@ -90,10 +90,9 @@
 #define PG_AVAIL3	0x0000000000000800
 #define PG_LGPAT	0x0000000000001000	/* PAT on large pages */
-#define PG_FRAME	0x000ffffffffff000
 #define PG_NX		0x8000000000000000
 
+#define PG_FRAME	0x000ffffffffff000
 #define PG_2MFRAME	0x000fffffffe00000	/* large (2M) page frame mask */
 #define PG_1GFRAME	0x000fffffc0000000	/* large (1G) page frame mask */
-#define PG_LGFRAME	PG_2MFRAME
 
 /* Short forms of protection codes. */
Index: /trunk/hal/x86_64/core/hal_gpt.c
===================================================================
--- /trunk/hal/x86_64/core/hal_gpt.c	(revision 385)
+++ /trunk/hal/x86_64/core/hal_gpt.c	(revision 386)
@@ -236,4 +236,38 @@
 /* -------------------------------------------------------------------------- */
 
+static uint32_t hal_gpt_pte_to_attr(pt_entry_t *pte)
+{
+	uint32_t attr = 0;
+
+	if (*pte & PG_V)
+		attr |= (GPT_MAPPED | GPT_READABLE);
+	if (*pte & PG_RW)
+		attr |= GPT_WRITABLE;
+	if (!(*pte & PG_NX))
+		attr |= GPT_EXECUTABLE;
+	if (*pte & PG_u)
+		attr |= GPT_USER;
+	if (!(*pte & PG_PS))
+		attr |= GPT_SMALL;
+
+	return attr;
+}
+
+static pt_entry_t hal_gpt_attr_to_pte(uint32_t attr)
+{
+	pt_entry_t pte = 0;
+
+	if (attr & GPT_MAPPED)
+		pte |= PG_V;
+	if (attr & GPT_WRITABLE)
+		pte |= PG_RW;
+	if (!(attr & GPT_EXECUTABLE))
+		pte |= PG_NX;
+	if (attr & GPT_USER)
+		pte |= PG_u;
+
+	return pte;
+}
+
 error_t hal_gpt_create(gpt_t *gpt)
 {
@@ -293,18 +327,97 @@
 }
 
-error_t hal_gpt_set_pte( gpt_t   * gpt,
-                         vpn_t     vpn,
-                         ppn_t     ppn,
-                         uint32_t  attr )
-{
-	x86_panic((char *)__func__);
+error_t hal_gpt_set_pte(gpt_t *gpt, vpn_t vpn, ppn_t ppn, uint32_t attr)
+{
+	vaddr_t va = vpn << CONFIG_PPM_PAGE_SHIFT;
+	paddr_t pa;
+	kmem_req_t req;
+	page_t *page;
+	xptr_t page_xp;
+
+	req.type  = KMEM_PAGE;
+	req.size  = 0;
+	req.flags = AF_KERNEL | AF_ZERO;
+
+	if (!(attr & GPT_MAPPED))
+		x86_panic("hal_gpt_set_pte: unmapped!");
+	if (!(attr & GPT_USER))
+		x86_panic("hal_gpt_set_pte: kernel!");
+	if (!(attr & GPT_SMALL))
+		x86_panic("hal_gpt_set_pte: large!");
+
+	if (!(L4_BASE[pl4_i(va)] & PG_V)) {
+		/* if L4 is not present, create it */
+		page = (page_t *)kmem_alloc(&req);
+		if (page == NULL) {
+			x86_panic("out of memory in hal_gpt_set_pte (L4)!");
+			return ENOMEM;
+		}
+
+		page_xp = XPTR(local_cxy, page);        
+		pa = (paddr_t)PADDR(local_cxy, ppm_page2base(page_xp));
+
+		L4_BASE[pl4_i(va)] = pa | PG_V | PG_u | PG_RW;
+
+	}
+
+	if (!(L3_BASE[pl3_i(va)] & PG_V)) {
+		/* if L3 is not present, create it */
+		page = (page_t *)kmem_alloc(&req);
+		if (page == NULL) {
+			x86_panic("out of memory in hal_gpt_set_pte (L3)!");
+			return ENOMEM;
+		}
+
+		page_xp = XPTR(local_cxy, page);        
+		pa = (paddr_t)PADDR(local_cxy, ppm_page2base(page_xp));
+
+		L3_BASE[pl3_i(va)] = pa | PG_V | PG_u | PG_RW;
+	}
+
+	if (!(L2_BASE[pl2_i(va)] & PG_V)) {
+		/* if L2 is not present, create it */
+		page = (page_t *)kmem_alloc(&req);
+		if (page == NULL) {
+			x86_panic("out of memory in hal_gpt_set_pte (L2)!");
+			return ENOMEM;
+		}
+
+		page_xp = XPTR(local_cxy, page);        
+		pa = (paddr_t)PADDR(local_cxy, ppm_page2base(page_xp));
+
+		L2_BASE[pl2_i(va)] = pa | PG_V | PG_u | PG_RW;
+	}
+
+	pa = ppn << CONFIG_PPM_PAGE_SHIFT;
+	L1_BASE[pl1_i(va)] = pa | hal_gpt_attr_to_pte(attr);
+
 	return 0;
 }
 
-void hal_gpt_get_pte( gpt_t    * gpt,
-                      vpn_t      vpn,
-                      uint32_t * attr,
-                      ppn_t    * ppn )
-{
+void hal_gpt_get_pte(gpt_t *gpt, vpn_t vpn, uint32_t *attr, ppn_t *ppn)
+{
+	vaddr_t va = vpn << CONFIG_PPM_PAGE_SHIFT;
+
+	*attr = 0;
+	if (!(L4_BASE[pl4_i(va)] & PG_V)) {
+		return;
+	}
+	if (!(L3_BASE[pl3_i(va)] & PG_V)) {
+		return;
+	}
+	if (!(L2_BASE[pl2_i(va)] & PG_V)) {
+		return;
+	}
+
+	if (L2_BASE[pl2_i(va)] & PG_PS) {
+		/* large page */
+		*attr = hal_gpt_pte_to_attr(&L2_BASE[pl2_i(va)]);
+		*ppn = (L2_BASE[pl2_i(va)] & PG_2MFRAME) >> CONFIG_PPM_PAGE_SHIFT;
+	} else {
+		/* small page */
+		*attr = hal_gpt_pte_to_attr(&L1_BASE[pl1_i(va)]);
+		*ppn = (L1_BASE[pl1_i(va)] & PG_FRAME) >> CONFIG_PPM_PAGE_SHIFT;
+	}
+
 	x86_panic((char *)__func__);
 }
