amd64: Map the local APIC.
authorJordan Gordeev <jgordeev@dir.bg>
Fri, 3 Jul 2009 19:23:20 +0000 (22:23 +0300)
committerJordan Gordeev <jgordeev@dir.bg>
Mon, 6 Jul 2009 11:13:41 +0000 (14:13 +0300)
Introduce a new function - pmap_mapdev_uncacheable(). It's a copy of pmap_mapdev(), but creates PT entries that disable caching.
Use pmap_mapdev_uncacheable() when mapping the local APIC.

sys/platform/pc64/amd64/pmap.c
sys/platform/pc64/include/pmap.h

index 6b3cdcc..de88a86 100644 (file)
@@ -795,10 +795,12 @@ READY0
        if (cpu_apic_address == 0)
                panic("pmap_bootstrap: no local apic!");
 
+#if JGPMAP32
        /* local apic is mapped on last page */
        SMPpt[NPTEPG - 1] = (pt_entry_t)(PG_V | PG_RW | PG_N | pgeflag |
            (cpu_apic_address & PG_FRAME));
 #endif
+#endif
 
        /*
         * We need to finish setting up the globaldata page for the BSP.
@@ -889,6 +891,7 @@ READY0
         * Now it is safe to enable pv_table recording.
         */
        pmap_initialized = TRUE;
+       lapic = pmap_mapdev_uncacheable(cpu_apic_address, sizeof(struct LAPIC));
 }
 
 /*
@@ -3812,6 +3815,34 @@ READY1
        return ((void *)(va + offset));
 }
 
+void *
+pmap_mapdev_uncacheable(vm_paddr_t pa, vm_size_t size)
+READY1
+{
+       vm_offset_t va, tmpva, offset;
+       pt_entry_t *pte;
+
+       offset = pa & PAGE_MASK;
+       size = roundup(offset + size, PAGE_SIZE);
+
+       va = kmem_alloc_nofault(&kernel_map, size);
+       if (va == 0)
+               panic("pmap_mapdev: Couldn't alloc kernel virtual memory");
+
+       pa = pa & ~PAGE_MASK;
+       for (tmpva = va; size > 0;) {
+               pte = vtopte(tmpva);
+               *pte = pa | PG_RW | PG_V | PG_N; /* | pgeflag; */
+               size -= PAGE_SIZE;
+               tmpva += PAGE_SIZE;
+               pa += PAGE_SIZE;
+       }
+       cpu_invltlb();
+       smp_invltlb();
+
+       return ((void *)(va + offset));
+}
+
 void
 pmap_unmapdev(vm_offset_t va, vm_size_t size)
 READY1
index 6a6d8ad..f77c2fe 100644 (file)
@@ -261,6 +261,7 @@ extern char *ptvmmap;               /* poor name! */
 
 void   pmap_bootstrap ( vm_paddr_t *);
 void   *pmap_mapdev (vm_paddr_t, vm_size_t);
+void   *pmap_mapdev_uncacheable(vm_paddr_t, vm_size_t);
 void   pmap_unmapdev (vm_offset_t, vm_size_t);
 #if JG
 pt_entry_t *pmap_pte (pmap_t, vm_offset_t) __pure2;