Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:23:05

0001 /*
0002  *  ARM920 MMU functions
0003  */
0004 
0005 /*
0006  *  Copyright (c) 2004 by Cogent Computer Systems
0007  *  Written by Jay Monkman <jtm@lopingdog.com>
0008  */
0009 
0010 #include <libcpu/mmu.h>
0011 #include <libcpu/arm-cp15.h>
0012 
0013 typedef uint32_t mmu_lvl1_t;
0014 
0015 extern uint32_t _ttbl_base;
0016 
0017 static void mmu_set_map_inval(mmu_lvl1_t *base);
0018 
0019 #define MMU_CTRL_MMU_EN             (1 << 0)
0020 #define MMU_CTRL_ALIGN_FAULT_EN     (1 << 1)
0021 #define MMU_CTRL_D_CACHE_EN         (1 << 2)
0022 #define MMU_CTRL_DEFAULT            (0xf << 3)
0023 #define MMU_CTRL_LITTLE_ENDIAN      (0 << 7)
0024 #define MMU_CTRL_BIG_ENDIAN         (1 << 7)
0025 #define MMU_CTRL_SYS_PROT           (1 << 8)
0026 #define MMU_CTRL_ROM_PROT           (1 << 9)
0027 #define MMU_CTRL_I_CACHE_EN         (1 << 12)
0028 #define MMU_CTRL_LOW_VECT           (0 << 13)
0029 #define MMU_CTRL_HIGH_VECT          (1 << 13)
0030 
0031 
0032 #define MMU_SET_LVL1_SECT(addr, ap, dom, ce, be) \
0033           (((addr) & 0xfff00000) |     \
0034            (ap)                  |     \
0035            (dom)                 |     \
0036            ((ce) << 3)           |     \
0037            ((be) << 2)           |     \
0038            0x12)
0039 
0040 #define MMU_SET_LVL1_INVAL (0x0)
0041 
0042 #define MMU_SECT_AP_ALL (0x3 << 10)
0043 
0044 void mmu_init(mmu_sect_map_t *map)
0045 {
0046     mmu_lvl1_t *lvl1_base;
0047     int i;
0048 
0049     /* flush the cache and TLB */
0050     arm_cp15_cache_invalidate();
0051     arm_cp15_tlb_invalidate();
0052 
0053     /* set manage mode access for all domains */
0054     arm_cp15_set_domain_access_control(0xffffffff);
0055 
0056     lvl1_base = (mmu_lvl1_t *)&_ttbl_base;
0057 
0058     /* set up the trans table */
0059     mmu_set_map_inval(lvl1_base);
0060     arm_cp15_set_translation_table_base(lvl1_base);
0061 
0062     /* create a 1:1 mapping of the entire address space */
0063     i = 0;
0064     while(map[i].size != 0) {
0065         int c = 0;  /* to avoid uninitialized warnings */
0066         int b = 0;  /* to avoid uninitialized warnings */
0067         int pbase;
0068         int vbase;
0069         int sects;
0070 
0071         switch (map[i].cache_flags) {
0072         case MMU_CACHE_NONE:
0073             c = 0;
0074             b = 0;
0075             break;
0076         case MMU_CACHE_BUFFERED:
0077             c = 0;
0078             b = 1;
0079             break;
0080         case MMU_CACHE_WTHROUGH:
0081             c = 1;
0082             b = 0;
0083             break;
0084         case MMU_CACHE_WBACK:
0085             c = 1;
0086             b = 1;
0087             break;
0088         }
0089 
0090         pbase = (map[i].paddr & 0xfff00000) >> 20;
0091         vbase = (map[i].vaddr & 0xfff00000) >> 20;
0092         sects = map[i].size;
0093 
0094         while (sects > 0) {
0095             lvl1_base[vbase] = MMU_SET_LVL1_SECT(pbase << 20,
0096                                                  MMU_SECT_AP_ALL,
0097                                                  0,
0098                                                  c,
0099                                                  b);
0100             pbase++;
0101             vbase++;
0102             sects--;
0103         }
0104         i++;
0105     }
0106 
0107     /* flush the cache and TLB */
0108     arm_cp15_cache_invalidate();
0109     arm_cp15_tlb_invalidate();
0110 
0111     /*  I & D caches turned on */
0112     arm_cp15_set_control(MMU_CTRL_DEFAULT |
0113                          MMU_CTRL_D_CACHE_EN |
0114                          MMU_CTRL_I_CACHE_EN |
0115                          MMU_CTRL_ALIGN_FAULT_EN |
0116                          MMU_CTRL_LITTLE_ENDIAN |
0117                          MMU_CTRL_MMU_EN);
0118 
0119     return;
0120 }
0121 
0122 /* set all the level 1 entrys to be invalid descriptors */
0123 static void mmu_set_map_inval(mmu_lvl1_t *base)
0124 {
0125     int i;
0126     for (i = 0; i < (0x4000 / 4); i++) {
0127         base[i] = MMU_SET_LVL1_INVAL;
0128     }
0129 }
0130 
0131 void mmu_set_cpu_async_mode(void)
0132 {
0133     uint32_t reg;
0134     reg = arm_cp15_get_control();
0135     reg |= 0xc0000000;
0136     arm_cp15_set_control(reg);
0137 }