[BACK]Return to arm32_kvminit.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / sys / arch / arm / arm32

Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.

Diff for /src/sys/arch/arm/arm32/arm32_kvminit.c between version 1.3.2.3 and 1.3.2.4

version 1.3.2.3, 2013/06/23 06:19:59 version 1.3.2.4, 2014/08/20 00:02:45
Line 134  __KERNEL_RCSID(0, "$NetBSD$");
Line 134  __KERNEL_RCSID(0, "$NetBSD$");
   
 #include <uvm/uvm_extern.h>  #include <uvm/uvm_extern.h>
   
   #include <arm/locore.h>
 #include <arm/db_machdep.h>  #include <arm/db_machdep.h>
 #include <arm/undefined.h>  #include <arm/undefined.h>
 #include <arm/bootconfig.h>  #include <arm/bootconfig.h>
Line 143  __KERNEL_RCSID(0, "$NetBSD$");
Line 144  __KERNEL_RCSID(0, "$NetBSD$");
   
 struct bootmem_info bootmem_info;  struct bootmem_info bootmem_info;
   
   extern void *msgbufaddr;
 paddr_t msgbufphys;  paddr_t msgbufphys;
 paddr_t physical_start;  paddr_t physical_start;
 paddr_t physical_end;  paddr_t physical_end;
Line 159  extern char _end[];
Line 161  extern char _end[];
  * Macros to translate between physical and virtual for a subset of the   * Macros to translate between physical and virtual for a subset of the
  * kernel address space.  *Not* for general use.   * kernel address space.  *Not* for general use.
  */   */
   #if defined(KERNEL_BASE_VOFFSET)
   #define KERN_VTOPHYS(bmi, va) \
           ((paddr_t)((vaddr_t)(va) - KERNEL_BASE_VOFFSET))
   #define KERN_PHYSTOV(bmi, pa) \
           ((vaddr_t)((paddr_t)(pa) + KERNEL_BASE_VOFFSET))
   #elif defined(ARM_MMU_EXTENDED) && defined(__HAVE_MM_MD_DIRECT_MAPPED_PHYS)
   #define KERN_VTOPHYS(bmi, va) \
           ((paddr_t)((vaddr_t)(va) - pmap_directbase + (bmi)->bmi_start))
   #define KERN_PHYSTOV(bmi, pa) \
           ((vaddr_t)((paddr_t)(pa) - (bmi)->bmi_start + pmap_directbase))
   #else
 #define KERN_VTOPHYS(bmi, va) \  #define KERN_VTOPHYS(bmi, va) \
         ((paddr_t)((vaddr_t)(va) - KERNEL_BASE + (bmi)->bmi_start))          ((paddr_t)((vaddr_t)(va) - KERNEL_BASE + (bmi)->bmi_start))
 #define KERN_PHYSTOV(bmi, pa) \  #define KERN_PHYSTOV(bmi, pa) \
         ((vaddr_t)((paddr_t)(pa) - (bmi)->bmi_start + KERNEL_BASE))          ((vaddr_t)((paddr_t)(pa) - (bmi)->bmi_start + KERNEL_BASE))
   #endif
   
 void  void
 arm32_bootmem_init(paddr_t memstart, psize_t memsize, vsize_t kernelstart)  arm32_bootmem_init(paddr_t memstart, psize_t memsize, vsize_t kernelstart)
Line 208  arm32_bootmem_init(paddr_t memstart, psi
Line 222  arm32_bootmem_init(paddr_t memstart, psi
          */           */
         if (bmi->bmi_start < bmi->bmi_kernelstart) {          if (bmi->bmi_start < bmi->bmi_kernelstart) {
                 pv->pv_pa = bmi->bmi_start;                  pv->pv_pa = bmi->bmi_start;
   #if defined(ARM_MMU_EXTENDED) && defined(__HAVE_MM_MD_DIRECT_MAPPED_PHYS)
                   pv->pv_va = pmap_directbase;
   #else
                 pv->pv_va = KERNEL_BASE;                  pv->pv_va = KERNEL_BASE;
   #endif
                 pv->pv_size = bmi->bmi_kernelstart - bmi->bmi_start;                  pv->pv_size = bmi->bmi_kernelstart - bmi->bmi_start;
                 bmi->bmi_freepages += pv->pv_size / PAGE_SIZE;                  bmi->bmi_freepages += pv->pv_size / PAGE_SIZE;
 #ifdef VERBOSE_INIT_ARM  #ifdef VERBOSE_INIT_ARM
Line 302  valloc_pages(struct bootmem_info *bmi, p
Line 320  valloc_pages(struct bootmem_info *bmi, p
         size_t free_idx = 0;          size_t free_idx = 0;
         static bool l1pt_found;          static bool l1pt_found;
   
           KASSERT(npages > 0);
   
         /*          /*
          * If we haven't allocated the kernel L1 page table and we are aligned           * If we haven't allocated the kernel L1 page table and we are aligned
          * at a L1 table boundary, alloc the memory for it.           * at a L1 table boundary, alloc the memory for it.
Line 368  arm32_kernel_vm_init(vaddr_t kernel_vm_b
Line 388  arm32_kernel_vm_init(vaddr_t kernel_vm_b
 {  {
         struct bootmem_info * const bmi = &bootmem_info;          struct bootmem_info * const bmi = &bootmem_info;
 #ifdef MULTIPROCESSOR  #ifdef MULTIPROCESSOR
         const size_t cpu_num = arm_cpu_max + 1;          const size_t cpu_num = arm_cpu_max;
 #else  #else
         const size_t cpu_num = 1;          const size_t cpu_num = 1;
 #endif  #endif
 #ifdef ARM_HAS_VBAR  #ifdef ARM_HAS_VBAR
         const bool map_vectors_p = false;          const bool map_vectors_p = false;
 #elif defined(CPU_ARMV7) || defined(CPU_ARM11)  #elif defined(CPU_ARMV7) || defined(CPU_ARM11)
         const bool map_vectors_p = vectors == ARM_VECTORS_LOW          const bool map_vectors_p = vectors == ARM_VECTORS_HIGH
             && !(armreg_pfr1_read() & ARM_PFR1_SEC_MASK);              || (armreg_pfr1_read() & ARM_PFR1_SEC_MASK) == 0;
 #else  #else
         const bool map_vectors_p = true;          const bool map_vectors_p = true;
 #endif  #endif
   
 #ifdef __HAVE_MM_MD_DIRECT_MAPPED_PHYS  #ifdef __HAVE_MM_MD_DIRECT_MAPPED_PHYS
         KASSERT(mapallmem_p);          KASSERT(mapallmem_p);
 #endif  #ifdef ARM_MMU_EXTENDED
           /*
            * We can only use address beneath kernel_vm_base to map physical
            * memory.
            */
           const psize_t physical_size =
               roundup(physical_end - physical_start, L1_SS_SIZE);
           KASSERT(kernel_vm_base >= physical_size);
           /*
            * If we don't have enough memory via TTBR1, we have use addresses
            * from TTBR0 to map some of the physical memory.  But try to use as
            * much high memory space as possible.
            */
           if (kernel_vm_base - KERNEL_BASE < physical_size) {
                   pmap_directbase = kernel_vm_base - physical_size;
                   printf("%s: changing pmap_directbase to %#lx\n", __func__,
                       pmap_directbase);
           }
   #else
           KASSERT(kernel_vm_base - KERNEL_BASE >= physical_end - physical_start);
   #endif /* ARM_MMU_EXTENDED */
   #endif /* __HAVE_MM_MD_DIRECT_MAPPED_PHYS */
   
         /*          /*
          * Calculate the number of L2 pages needed for mapping the           * Calculate the number of L2 pages needed for mapping the
Line 392  arm32_kernel_vm_init(vaddr_t kernel_vm_b
Line 433  arm32_kernel_vm_init(vaddr_t kernel_vm_b
          */           */
         size_t kernel_size = bmi->bmi_kernelend;          size_t kernel_size = bmi->bmi_kernelend;
         kernel_size -= (bmi->bmi_kernelstart & -L2_S_SEGSIZE);          kernel_size -= (bmi->bmi_kernelstart & -L2_S_SEGSIZE);
         kernel_size += L1_TABLE_SIZE;          kernel_size += L1_TABLE_SIZE_REAL;
         kernel_size += L2_TABLE_SIZE * (2 + 1 + KERNEL_L2PT_VMDATA_NUM + 1);          kernel_size += PAGE_SIZE * KERNEL_L2PT_VMDATA_NUM;
           if (map_vectors_p) {
                   kernel_size += PAGE_SIZE;       /* L2PT for VECTORS */
           }
           if (iovbase) {
                   kernel_size += PAGE_SIZE;       /* L2PT for IO */
           }
         kernel_size +=          kernel_size +=
             cpu_num * (ABT_STACK_SIZE + FIQ_STACK_SIZE + IRQ_STACK_SIZE              cpu_num * (ABT_STACK_SIZE + FIQ_STACK_SIZE + IRQ_STACK_SIZE
             + UND_STACK_SIZE + UPAGES) * PAGE_SIZE;              + UND_STACK_SIZE + UPAGES) * PAGE_SIZE;
         kernel_size += round_page(MSGBUFSIZE);          kernel_size += round_page(MSGBUFSIZE);
         kernel_size += 0x10000; /* slop */          kernel_size += 0x10000; /* slop */
         kernel_size += PAGE_SIZE * (kernel_size + L2_S_SEGSIZE - 1) / L2_S_SEGSIZE;          if (!mapallmem_p) {
                   kernel_size += PAGE_SIZE
                       * ((kernel_size + L2_S_SEGSIZE - 1) / L2_S_SEGSIZE);
           }
         kernel_size = round_page(kernel_size);          kernel_size = round_page(kernel_size);
   
         /*          /*
          * Now we know how many L2 pages it will take.           * Now we know how many L2 pages it will take.  If we've mapped
            * all of memory, then it won't take any.
          */           */
         const size_t KERNEL_L2PT_KERNEL_NUM =          const size_t KERNEL_L2PT_KERNEL_NUM = mapallmem_p
             (kernel_size + L2_S_SEGSIZE - 1) / L2_S_SEGSIZE;              ? 0 : round_page(kernel_size + L2_S_SEGSIZE - 1) / L2_S_SEGSIZE;
   
 #ifdef VERBOSE_INIT_ARM  #ifdef VERBOSE_INIT_ARM
         printf("%s: %zu L2 pages are needed to map %#zx kernel bytes\n",          printf("%s: %zu L2 pages are needed to map %#zx kernel bytes\n",
Line 463  arm32_kernel_vm_init(vaddr_t kernel_vm_b
Line 514  arm32_kernel_vm_init(vaddr_t kernel_vm_b
 #ifdef VERBOSE_INIT_ARM  #ifdef VERBOSE_INIT_ARM
                 printf(" vector");                  printf(" vector");
 #endif  #endif
                 valloc_pages(bmi, &bmi->bmi_vector_l2pt,                  valloc_pages(bmi, &bmi->bmi_vector_l2pt, 1,
                     L2_TABLE_SIZE / PAGE_SIZE, VM_PROT_READ|VM_PROT_WRITE,                      VM_PROT_READ|VM_PROT_WRITE, PTE_PAGETABLE, true);
                     PTE_PAGETABLE, true);  
                 add_pages(bmi, &bmi->bmi_vector_l2pt);                  add_pages(bmi, &bmi->bmi_vector_l2pt);
         }          }
   
Line 475  arm32_kernel_vm_init(vaddr_t kernel_vm_b
Line 525  arm32_kernel_vm_init(vaddr_t kernel_vm_b
 #ifdef VERBOSE_INIT_ARM  #ifdef VERBOSE_INIT_ARM
         printf(" kernel");          printf(" kernel");
 #endif  #endif
           KASSERT(mapallmem_p || KERNEL_L2PT_KERNEL_NUM > 0);
           KASSERT(!mapallmem_p || KERNEL_L2PT_KERNEL_NUM == 0);
         for (size_t idx = 0; idx < KERNEL_L2PT_KERNEL_NUM; ++idx) {          for (size_t idx = 0; idx < KERNEL_L2PT_KERNEL_NUM; ++idx) {
                 valloc_pages(bmi, &kernel_l2pt[idx], L2_TABLE_SIZE / PAGE_SIZE,                  valloc_pages(bmi, &kernel_l2pt[idx], 1,
                     VM_PROT_READ|VM_PROT_WRITE, PTE_PAGETABLE, true);                      VM_PROT_READ|VM_PROT_WRITE, PTE_PAGETABLE, true);
                 add_pages(bmi, &kernel_l2pt[idx]);                  add_pages(bmi, &kernel_l2pt[idx]);
         }          }
Line 488  arm32_kernel_vm_init(vaddr_t kernel_vm_b
Line 540  arm32_kernel_vm_init(vaddr_t kernel_vm_b
         printf(" vm");          printf(" vm");
 #endif  #endif
         for (size_t idx = 0; idx < KERNEL_L2PT_VMDATA_NUM; ++idx) {          for (size_t idx = 0; idx < KERNEL_L2PT_VMDATA_NUM; ++idx) {
                 valloc_pages(bmi, &vmdata_l2pt[idx], L2_TABLE_SIZE / PAGE_SIZE,                  valloc_pages(bmi, &vmdata_l2pt[idx], 1,
                     VM_PROT_READ|VM_PROT_WRITE, PTE_PAGETABLE, true);                      VM_PROT_READ|VM_PROT_WRITE, PTE_PAGETABLE, true);
                 add_pages(bmi, &vmdata_l2pt[idx]);                  add_pages(bmi, &vmdata_l2pt[idx]);
         }          }
Line 496  arm32_kernel_vm_init(vaddr_t kernel_vm_b
Line 548  arm32_kernel_vm_init(vaddr_t kernel_vm_b
         /*          /*
          * If someone wanted a L2 page for I/O, allocate it now.           * If someone wanted a L2 page for I/O, allocate it now.
          */           */
         if (iovbase != 0) {          if (iovbase) {
 #ifdef VERBOSE_INIT_ARM  #ifdef VERBOSE_INIT_ARM
                 printf(" io");                  printf(" io");
 #endif  #endif
                 valloc_pages(bmi, &bmi->bmi_io_l2pt, L2_TABLE_SIZE / PAGE_SIZE,                  valloc_pages(bmi, &bmi->bmi_io_l2pt, 1,
                     VM_PROT_READ|VM_PROT_WRITE, PTE_PAGETABLE, true);                      VM_PROT_READ|VM_PROT_WRITE, PTE_PAGETABLE, true);
                 add_pages(bmi, &bmi->bmi_io_l2pt);                  add_pages(bmi, &bmi->bmi_io_l2pt);
         }          }
   
 #ifdef VERBOSE_ARM_INIT  #ifdef VERBOSE_INIT_ARM
         printf("%s: allocating stacks\n", __func__);          printf("%s: allocating stacks\n", __func__);
 #endif  #endif
   
Line 535  arm32_kernel_vm_init(vaddr_t kernel_vm_b
Line 587  arm32_kernel_vm_init(vaddr_t kernel_vm_b
             VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE, false);              VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE, false);
         add_pages(bmi, &msgbuf);          add_pages(bmi, &msgbuf);
         msgbufphys = msgbuf.pv_pa;          msgbufphys = msgbuf.pv_pa;
           msgbufaddr = (void *)msgbuf.pv_va;
   
         if (map_vectors_p) {          if (map_vectors_p) {
                 /*                  /*
Line 555  arm32_kernel_vm_init(vaddr_t kernel_vm_b
Line 608  arm32_kernel_vm_init(vaddr_t kernel_vm_b
 #if (ARM_NMMUS > 1)  #if (ARM_NMMUS > 1)
         if (xscale_use_minidata)          if (xscale_use_minidata)
 #endif  #endif
                 valloc_pages(bmi, extrapv, nextrapages,                  valloc_pages(bmi, &minidataclean, 1,
                     VM_PROT_READ|VM_PROT_WRITE, 0, true);                      VM_PROT_READ|VM_PROT_WRITE, 0, true);
 #endif  #endif
   
Line 600  arm32_kernel_vm_init(vaddr_t kernel_vm_b
Line 653  arm32_kernel_vm_init(vaddr_t kernel_vm_b
                     &kernel_l2pt[idx]);                      &kernel_l2pt[idx]);
 #ifdef VERBOSE_INIT_ARM  #ifdef VERBOSE_INIT_ARM
                 printf("%s: adding L2 pt (VA %#lx, PA %#lx) for VA %#lx (kernel)\n",                  printf("%s: adding L2 pt (VA %#lx, PA %#lx) for VA %#lx (kernel)\n",
                     __func__, kernel_l2pt[idx].pv_va, kernel_l2pt[idx].pv_pa,                      __func__, kernel_l2pt[idx].pv_va,
                     kernel_base + idx * L2_S_SEGSIZE);                      kernel_l2pt[idx].pv_pa, kernel_base + idx * L2_S_SEGSIZE);
 #endif  #endif
         }          }
   
Line 667  arm32_kernel_vm_init(vaddr_t kernel_vm_b
Line 720  arm32_kernel_vm_init(vaddr_t kernel_vm_b
   
 #ifdef VERBOSE_INIT_ARM  #ifdef VERBOSE_INIT_ARM
         printf("Listing Chunks\n");          printf("Listing Chunks\n");
         {  
                 pv_addr_t *pv;          pv_addr_t *lpv;
                 SLIST_FOREACH(pv, &bmi->bmi_chunks, pv_list) {          SLIST_FOREACH(lpv, &bmi->bmi_chunks, pv_list) {
                         printf("%s: pv %p: chunk VA %#lx..%#lx "                  printf("%s: pv %p: chunk VA %#lx..%#lx "
                             "(PA %#lx, prot %d, cache %d)\n",                      "(PA %#lx, prot %d, cache %d)\n",
                             __func__, pv, pv->pv_va, pv->pv_va + pv->pv_size - 1,                      __func__, lpv, lpv->pv_va, lpv->pv_va + lpv->pv_size - 1,
                             pv->pv_pa, pv->pv_prot, pv->pv_cache);                      lpv->pv_pa, lpv->pv_prot, lpv->pv_cache);
                 }  
         }          }
         printf("\nMapping Chunks\n");          printf("\nMapping Chunks\n");
 #endif  #endif
Line 685  arm32_kernel_vm_init(vaddr_t kernel_vm_b
Line 737  arm32_kernel_vm_init(vaddr_t kernel_vm_b
                 cur_pv = *pv;                  cur_pv = *pv;
                 pv = SLIST_NEXT(pv, pv_list);                  pv = SLIST_NEXT(pv, pv_list);
         } else {          } else {
   #if defined(ARM_MMU_EXTENDED) && defined(__HAVE_MM_MD_DIRECT_MAPPED_PHYS)
                   cur_pv.pv_va = pmap_directbase;
   #else
                 cur_pv.pv_va = KERNEL_BASE;                  cur_pv.pv_va = KERNEL_BASE;
   #endif
                 cur_pv.pv_pa = bmi->bmi_start;                  cur_pv.pv_pa = bmi->bmi_start;
                 cur_pv.pv_size = pv->pv_pa - bmi->bmi_start;                  cur_pv.pv_size = pv->pv_pa - bmi->bmi_start;
                 cur_pv.pv_prot = VM_PROT_READ | VM_PROT_WRITE;                  cur_pv.pv_prot = VM_PROT_READ | VM_PROT_WRITE;
Line 799  arm32_kernel_vm_init(vaddr_t kernel_vm_b
Line 855  arm32_kernel_vm_init(vaddr_t kernel_vm_b
 #if (ARM_NMMUS > 1)  #if (ARM_NMMUS > 1)
         if (xscale_use_minidata)          if (xscale_use_minidata)
 #endif  #endif
                 xscale_setup_minidata(l1_va, minidataclean.pv_va,                  xscale_setup_minidata(l1pt_va, minidataclean.pv_va,
                     minidataclean.pv_pa);                      minidataclean.pv_pa);
 #endif  #endif
   
Line 889  arm32_kernel_vm_init(vaddr_t kernel_vm_b
Line 945  arm32_kernel_vm_init(vaddr_t kernel_vm_b
          * tables.           * tables.
          */           */
   
 #if defined(VERBOSE_INIT_ARM) && 0  #if defined(VERBOSE_INIT_ARM)
         printf("TTBR0=%#x", armreg_ttbr_read());          printf("TTBR0=%#x", armreg_ttbr_read());
 #ifdef _ARM_ARCH_6  #ifdef _ARM_ARCH_6
         printf(" TTBR1=%#x TTBCR=%#x",          printf(" TTBR1=%#x TTBCR=%#x CONTEXTIDR=%#x",
             armreg_ttbr1_read(), armreg_ttbcr_read());              armreg_ttbr1_read(), armreg_ttbcr_read(),
               armreg_contextidr_read());
 #endif  #endif
         printf("\n");          printf("\n");
 #endif  #endif
Line 903  arm32_kernel_vm_init(vaddr_t kernel_vm_b
Line 960  arm32_kernel_vm_init(vaddr_t kernel_vm_b
         printf("switching to new L1 page table @%#lx...", l1pt_pa);          printf("switching to new L1 page table @%#lx...", l1pt_pa);
 #endif  #endif
   
   #ifdef ARM_MMU_EXTENDED
           cpu_domains((DOMAIN_CLIENT << (PMAP_DOMAIN_KERNEL*2))
               | (DOMAIN_CLIENT << (PMAP_DOMAIN_USER*2)));
   #else
         cpu_domains((DOMAIN_CLIENT << (PMAP_DOMAIN_KERNEL*2)) | DOMAIN_CLIENT);          cpu_domains((DOMAIN_CLIENT << (PMAP_DOMAIN_KERNEL*2)) | DOMAIN_CLIENT);
   #endif
         cpu_idcache_wbinv_all();          cpu_idcache_wbinv_all();
   #ifdef VERBOSE_INIT_ARM
           printf(" ttb");
   #endif
 #ifdef ARM_MMU_EXTENDED  #ifdef ARM_MMU_EXTENDED
           /*
            * TTBCR should have been initialized by the MD start code.
            */
           KASSERT((armreg_contextidr_read() & 0xff) == 0);
           KASSERT(armreg_ttbcr_read() == __SHIFTIN(1, TTBCR_S_N));
           /*
            * Disable lookups via TTBR0 until there is an activated pmap.
            */
           armreg_ttbcr_write(armreg_ttbcr_read() | TTBCR_S_PD0);
         cpu_setttb(l1pt_pa, KERNEL_PID);          cpu_setttb(l1pt_pa, KERNEL_PID);
           arm_isb();
 #else  #else
         cpu_setttb(l1pt_pa, true);          cpu_setttb(l1pt_pa, true);
           cpu_domains(DOMAIN_CLIENT << (PMAP_DOMAIN_KERNEL*2));
 #endif  #endif
         cpu_tlb_flushID();          cpu_tlb_flushID();
         cpu_domains(DOMAIN_CLIENT << (PMAP_DOMAIN_KERNEL*2));  
   
 #ifdef VERBOSE_INIT_ARM  #ifdef VERBOSE_INIT_ARM
         printf("TTBR0=%#x OK\n", armreg_ttbr_read());  #ifdef ARM_MMU_EXTENDED
           printf(" (TTBCR=%#x TTBR0=%#x TTBR1=%#x)",
               armreg_ttbcr_read(), armreg_ttbr_read(), armreg_ttbr1_read());
   #else
           printf(" (TTBR0=%#x)", armreg_ttbr_read());
   #endif
   #endif
   
   #ifdef MULTIPROCESSOR
           /*
            * Kick the secondaries to load the TTB.  After which they'll go
            * back to sleep to wait for the final kick so they will hatch.
            */
   #ifdef VERBOSE_INIT_ARM
           printf(" hatchlings");
   #endif
           cpu_boot_secondary_processors();
   #endif
   
   #ifdef VERBOSE_INIT_ARM
           printf(" OK\n");
 #endif  #endif
 }  }

Legend:
Removed from v.1.3.2.3  
changed lines
  Added in v.1.3.2.4

CVSweb <webmaster@jp.NetBSD.org>