Changeset 850235d in mainline for kernel/arch/arm32/include
- Timestamp:
- 2013-03-10T14:56:21Z (13 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 05bab88
- Parents:
- ea906c29 (diff), 2277e03 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)links above to see all the changes relative to each parent. - Location:
- kernel/arch/arm32/include/arch
- Files:
-
- 5 added
- 10 edited
- 2 moved
-
asm.h (modified) (1 diff)
-
barrier.h (modified) (1 diff)
-
cache.h (moved) (moved from uspace/srv/fs/ext2fs/ext2fs.h ) (2 diffs)
-
cp15.h (added)
-
cpu.h (modified) (2 diffs)
-
cycle.h (modified) (2 diffs)
-
fpu_context.h (modified) (2 diffs)
-
mach/beagleboardxm/beagleboardxm.h (moved) (moved from kernel/arch/amd64/include/arch/debugger.h ) (3 diffs)
-
mach/beaglebone/beaglebone.h (added)
-
machine_func.h (modified) (1 diff)
-
mm/frame.h (modified) (1 diff)
-
mm/page.h (modified) (3 diffs)
-
mm/page_armv4.h (added)
-
mm/page_armv6.h (added)
-
mm/page_fault.h (modified) (1 diff)
-
regutils.h (modified) (1 diff)
-
security_ext.h (added)
Legend:
- Unmodified
- Added
- Removed
-
kernel/arch/arm32/include/arch/asm.h
rea906c29 r850235d 43 43 #include <trace.h> 44 44 45 /** No such instruction on ARM to sleep CPU. */ 45 /** CPU specific way to sleep cpu. 46 * 47 * ARMv7 introduced wait for event and wait for interrupt (wfe/wfi). 48 * ARM920T has custom coprocessor action to do the same. See ARM920T Technical 49 * Reference Manual ch 4.9 p. 4-23 (103 in the PDF) 50 * ARM926EJ-S uses the same coprocessor instruction as ARM920T. See ARM926EJ-S 51 * chapter 2.3.8 p.2-22 (52 in the PDF) 52 * 53 * @note Although mcr p15, 0, R0, c7, c0, 4 is defined in ARM Architecture 54 * reference manual for armv4/5 CP15 implementation is mandatory only for 55 * armv6+. 56 */ 46 57 NO_TRACE static inline void cpu_sleep(void) 47 58 { 59 #ifdef PROCESSOR_ARCH_armv7_a 60 asm volatile ( "wfe" ); 61 #elif defined(PROCESSOR_ARCH_armv6) | defined(PROCESSOR_arm926ej_s) | defined(PROCESSOR_arm920t) 62 asm volatile ( "mcr p15, 0, R0, c7, c0, 4" ); 63 #endif 48 64 } 49 65 -
kernel/arch/arm32/include/arch/barrier.h
rea906c29 r850235d 37 37 #define KERN_arm32_BARRIER_H_ 38 38 39 /* 40 * TODO: implement true ARM memory barriers for macros below. 41 */ 39 #ifdef KERNEL 40 #include <arch/cp15.h> 41 #else 42 #include <libarch/cp15.h> 43 #endif 44 42 45 #define CS_ENTER_BARRIER() asm volatile ("" ::: "memory") 43 46 #define CS_LEAVE_BARRIER() asm volatile ("" ::: "memory") 44 47 48 #if defined PROCESSOR_ARCH_armv7_a 49 /* ARMv7 uses instructions for memory barriers see ARM Architecture reference 50 * manual for details: 51 * DMB: ch. A8.8.43 page A8-376 52 * DSB: ch. A8.8.44 page A8-378 53 * See ch. A3.8.3 page A3-148 for details about memory barrier implementation 54 * and functionality on armv7 architecture. 55 */ 56 #define memory_barrier() asm volatile ("dmb" ::: "memory") 57 #define read_barrier() asm volatile ("dsb" ::: "memory") 58 #define write_barrier() asm volatile ("dsb st" ::: "memory") 59 #define inst_barrier() asm volatile ("isb" ::: "memory") 60 #elif defined PROCESSOR_ARCH_armv6 | defined KERNEL 61 /* 62 * ARMv6 introduced user access of the following commands: 63 * - Prefetch flush 64 * - Data synchronization barrier 65 * - Data memory barrier 66 * - Clean and prefetch range operations. 67 * ARM Architecture Reference Manual version I ch. B.3.2.1 p. B3-4 68 */ 69 /* ARMv6- use system control coprocessor (CP15) for memory barrier instructions. 70 * Although at least mcr p15, 0, r0, c7, c10, 4 is mentioned in earlier archs, 71 * CP15 implementation is mandatory only for armv6+. 72 */ 73 #define memory_barrier() CP15DMB_write(0) 74 #define read_barrier() CP15DSB_write(0) 75 #define write_barrier() read_barrier() 76 #define inst_barrier() CP15ISB_write(0) 77 #else 78 /* Older manuals mention syscalls as a way to implement cache coherency and 79 * barriers. See for example ARM Architecture Reference Manual Version D 80 * chapter 2.7.4 Prefetching and self-modifying code (p. A2-28) 81 */ 82 // TODO implement on per PROCESSOR basis or via syscalls 45 83 #define memory_barrier() asm volatile ("" ::: "memory") 46 84 #define read_barrier() asm volatile ("" ::: "memory") 47 85 #define write_barrier() asm volatile ("" ::: "memory") 86 #define inst_barrier() asm volatile ("" ::: "memory") 87 #endif 48 88 89 /* 90 * There are multiple ways ICache can be implemented on ARM machines. Namely 91 * PIPT, VIPT, and ASID and VMID tagged VIVT (see ARM Architecture Reference 92 * Manual B3.11.2 (p. 1383). However, CortexA8 Manual states: "For maximum 93 * compatibility across processors, ARM recommends that operating systems target 94 * the ARMv7 base architecture that uses ASID-tagged VIVT instruction caches, 95 * and do not assume the presence of the IVIPT extension. Software that relies 96 * on the IVIPT extension might fail in an unpredictable way on an ARMv7 97 * implementation that does not include the IVIPT extension." (7.2.6 p. 245). 98 * Only PIPT invalidates cache for all VA aliases if one block is invalidated. 99 * 100 * @note: Supporting ASID and VMID tagged VIVT may need to add ICache 101 * maintenance to other places than just smc. 102 */ 103 104 #if defined PROCESSOR_ARCH_armv7_a | defined PROCESSOR_ARCH_armv6 | defined KERNEL 105 /* Available on all supported arms, 106 * invalidates entire ICache so the written value does not matter. */ 107 //TODO might be PL1 only on armv5- 108 #define smc_coherence(a) \ 109 do { \ 110 DCCMVAU_write((uint32_t)(a)); /* Flush changed memory */\ 111 write_barrier(); /* Wait for completion */\ 112 ICIALLU_write(0); /* Flush ICache */\ 113 inst_barrier(); /* Wait for Inst refetch */\ 114 } while (0) 115 /* @note: Cache type register is not available in uspace. We would need 116 * to export the cache line value, or use syscall for uspace smc_coherence */ 117 #define smc_coherence_block(a, l) \ 118 do { \ 119 for (uintptr_t addr = (uintptr_t)a; addr < (uintptr_t)a + l; addr += 4)\ 120 smc_coherence(addr); \ 121 } while (0) 122 #else 49 123 #define smc_coherence(a) 50 124 #define smc_coherence_block(a, l) 125 #endif 126 51 127 52 128 #endif -
kernel/arch/arm32/include/arch/cache.h
rea906c29 r850235d 1 1 /* 2 * Copyright (c) 201 1 Martin Sucha2 * Copyright (c) 2013 Jan Vesely 3 3 * All rights reserved. 4 4 * … … 27 27 */ 28 28 29 /** @addtogroup fs29 /** @addtogroup arm32 30 30 * @{ 31 */ 31 */ 32 /** @file 33 * @brief Security Extensions Routines 34 */ 32 35 33 #ifndef EXT2FS_EXT2FS_H_34 #define EXT2FS_EXT2FS_H_36 #ifndef KERN_arm32_CACHE_H_ 37 #define KERN_arm32_CACHE_H_ 35 38 36 #include <libext2.h> 37 #include <libfs.h> 38 #include <sys/types.h> 39 unsigned dcache_levels(void); 39 40 40 #define min(a, b) ((a) < (b) ? (a) : (b)) 41 42 extern vfs_out_ops_t ext2fs_ops; 43 extern libfs_ops_t ext2fs_libfs_ops; 44 45 extern int ext2fs_global_init(void); 46 extern int ext2fs_global_fini(void); 41 void dcache_flush(void); 42 void dcache_flush_invalidate(void); 43 void cpu_dcache_flush(void); 44 void cpu_dcache_flush_invalidate(void); 45 void icache_invalidate(void); 47 46 48 47 #endif 48 /** @} 49 */ 49 50 50 /**51 * @}52 */ -
kernel/arch/arm32/include/arch/cpu.h
rea906c29 r850235d 40 40 #include <arch/asm.h> 41 41 42 enum { 43 ARM_MAX_CACHE_LEVELS = 7, 44 }; 42 45 43 /** Struct representing ARM CPU identifi action. */46 /** Struct representing ARM CPU identification. */ 44 47 typedef struct { 45 /** Implement ator (vendor) number. */48 /** Implementor (vendor) number. */ 46 49 uint32_t imp_num; 47 50 … … 57 60 /** Revision number. */ 58 61 uint32_t rev_num; 62 63 struct { 64 unsigned ways; 65 unsigned sets; 66 unsigned line_size; 67 unsigned way_shift; 68 unsigned set_shift; 69 } dcache[ARM_MAX_CACHE_LEVELS]; 70 unsigned dcache_levels; 59 71 } cpu_arch_t; 60 72 -
kernel/arch/arm32/include/arch/cycle.h
rea906c29 r850235d 38 38 39 39 #include <trace.h> 40 #include <arch/cp15.h> 40 41 41 42 /** Return count of CPU cycles. … … 48 49 NO_TRACE static inline uint64_t get_cycle(void) 49 50 { 51 #ifdef PROCESSOR_ARCH_armv7_a 52 if ((ID_PFR1_read() & ID_PFR1_GEN_TIMER_EXT_MASK) == 53 ID_PFR1_GEN_TIMER_EXT) { 54 uint32_t low = 0, high = 0; 55 asm volatile( "MRRC p15, 0, %[low], %[high], c14": [low]"=r"(low), [high]"=r"(high)); 56 return ((uint64_t)high << 32) | low; 57 } else { 58 return (uint64_t)PMCCNTR_read() * 64; 59 } 60 #endif 50 61 return 0; 51 62 } -
kernel/arch/arm32/include/arch/fpu_context.h
rea906c29 r850235d 31 31 */ 32 32 /** @file 33 * @brief FPU context (not implemented). 34 * 35 * GXemul doesn't support FPU on its ARM CPU. 33 * @brief FPU context. 36 34 */ 37 35 … … 41 39 #include <typedefs.h> 42 40 43 #define FPU_CONTEXT_ALIGN 041 #define FPU_CONTEXT_ALIGN 8 44 42 43 /* ARM Architecture reference manual, p B-1529. 44 */ 45 45 typedef struct { 46 uint32_t fpexc; 47 uint32_t fpscr; 48 uint32_t s[64]; 46 49 } fpu_context_t; 50 51 void fpu_setup(void); 52 53 bool handle_if_fpu_exception(void); 47 54 48 55 #endif -
kernel/arch/arm32/include/arch/mach/beagleboardxm/beagleboardxm.h
rea906c29 r850235d 1 1 /* 2 * Copyright (c) 20 06 Ondrej Palkovsky2 * Copyright (c) 2012 Jan Vesely 3 3 * All rights reserved. 4 4 * … … 26 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 27 */ 28 29 /** @addtogroup amd64debug 28 /** @addtogroup arm32beagleboardxm beagleboardxm 29 * @brief BeagleBoard-xM platform. 30 * @ingroup arm32 30 31 * @{ 31 32 */ 32 33 /** @file 34 * @brief BeagleBoard platform driver. 33 35 */ 34 36 35 #ifndef KERN_a md64_DEBUGGER_H_36 #define KERN_a md64_DEBUGGER_H_37 #ifndef KERN_arm32_beagleboardxm_H_ 38 #define KERN_arm32_beagleboardxm_H_ 37 39 38 #include < typedefs.h>40 #include <arch/machine_func.h> 39 41 40 #define BKPOINTS_MAX 4 41 42 /* Flags that are passed to breakpoint_add function */ 43 #define BKPOINT_INSTR 0x1U 44 #define BKPOINT_WRITE 0x2U 45 #define BKPOINT_READ_WRITE 0x4U 46 47 #define BKPOINT_CHECK_ZERO 0x8U 48 49 50 extern void debugger_init(void); 51 extern int breakpoint_add(const void *, const unsigned int, int); 52 extern void breakpoint_del(int); 42 extern struct arm_machine_ops bbxm_machine_ops; 53 43 54 44 #endif … … 56 46 /** @} 57 47 */ 48 -
kernel/arch/arm32/include/arch/machine_func.h
rea906c29 r850235d 108 108 extern size_t machine_get_irq_count(void); 109 109 110 extern const char * machine_get_platform_name(void); 111 110 112 #endif 111 113 -
kernel/arch/arm32/include/arch/mm/frame.h
rea906c29 r850235d 47 47 48 48 #ifdef MACHINE_gta02 49 50 #define PHYSMEM_START_ADDR 0x30008000 49 51 #define BOOT_PAGE_TABLE_ADDRESS 0x30010000 52 53 #elif defined MACHINE_beagleboardxm 54 55 #define PHYSMEM_START_ADDR 0x80000000 56 #define BOOT_PAGE_TABLE_ADDRESS 0x80008000 57 58 #elif defined MACHINE_beaglebone 59 60 #define PHYSMEM_START_ADDR 0x80000000 61 #define BOOT_PAGE_TABLE_ADDRESS 0x80008000 62 50 63 #else 64 65 #define PHYSMEM_START_ADDR 0x00000000 51 66 #define BOOT_PAGE_TABLE_ADDRESS 0x00008000 67 52 68 #endif 53 69 54 70 #define BOOT_PAGE_TABLE_START_FRAME (BOOT_PAGE_TABLE_ADDRESS >> FRAME_WIDTH) 55 71 #define BOOT_PAGE_TABLE_SIZE_IN_FRAMES (BOOT_PAGE_TABLE_SIZE >> FRAME_WIDTH) 56 57 #ifdef MACHINE_gta0258 #define PHYSMEM_START_ADDR 0x3000800059 #else60 #define PHYSMEM_START_ADDR 0x0000000061 #endif62 72 63 73 extern void frame_low_arch_init(void); -
kernel/arch/arm32/include/arch/mm/page.h
rea906c29 r850235d 46 46 #define PAGE_SIZE FRAME_SIZE 47 47 48 #if (defined MACHINE_beagleboardxm) || (defined MACHINE_beaglebone) 49 #ifndef __ASM__ 50 # define KA2PA(x) ((uintptr_t) (x)) 51 # define PA2KA(x) ((uintptr_t) (x)) 52 #else 53 # define KA2PA(x) (x) 54 # define PA2KA(x) (x) 55 #endif 56 #else 48 57 #ifndef __ASM__ 49 58 # define KA2PA(x) (((uintptr_t) (x)) - 0x80000000) … … 53 62 # define PA2KA(x) ((x) + 0x80000000) 54 63 #endif 64 #endif 55 65 56 66 /* Number of entries in each level. */ 57 #define PTL0_ENTRIES_ARCH (1 << 12)/* 4096 */58 #define PTL1_ENTRIES_ARCH 059 #define PTL2_ENTRIES_ARCH 067 #define PTL0_ENTRIES_ARCH (1 << 12) /* 4096 */ 68 #define PTL1_ENTRIES_ARCH 0 69 #define PTL2_ENTRIES_ARCH 0 60 70 /* coarse page tables used (256 * 4 = 1KB per page) */ 61 #define PTL3_ENTRIES_ARCH (1 << 8)/* 256 */71 #define PTL3_ENTRIES_ARCH (1 << 8) /* 256 */ 62 72 63 73 /* Page table sizes for each level. */ 64 #define PTL0_SIZE_ARCH FOUR_FRAMES65 #define PTL1_SIZE_ARCH 066 #define PTL2_SIZE_ARCH 067 #define PTL3_SIZE_ARCH ONE_FRAME74 #define PTL0_SIZE_ARCH FOUR_FRAMES 75 #define PTL1_SIZE_ARCH 0 76 #define PTL2_SIZE_ARCH 0 77 #define PTL3_SIZE_ARCH ONE_FRAME 68 78 69 79 /* Macros calculating indices into page tables for each level. */ 70 #define PTL0_INDEX_ARCH(vaddr) (((vaddr) >> 20) & 0xfff)71 #define PTL1_INDEX_ARCH(vaddr) 072 #define PTL2_INDEX_ARCH(vaddr) 073 #define PTL3_INDEX_ARCH(vaddr) (((vaddr) >> 12) & 0x0ff)80 #define PTL0_INDEX_ARCH(vaddr) (((vaddr) >> 20) & 0xfff) 81 #define PTL1_INDEX_ARCH(vaddr) 0 82 #define PTL2_INDEX_ARCH(vaddr) 0 83 #define PTL3_INDEX_ARCH(vaddr) (((vaddr) >> 12) & 0x0ff) 74 84 75 85 /* Get PTE address accessors for each level. */ 76 86 #define GET_PTL1_ADDRESS_ARCH(ptl0, i) \ 77 ((pte_t *) ((((pte_t *)(ptl0))[(i)].l0).coarse_table_addr << 10))87 ((pte_t *) ((((pte_t *)(ptl0))[(i)].l0).coarse_table_addr << 10)) 78 88 #define GET_PTL2_ADDRESS_ARCH(ptl1, i) \ 79 (ptl1)89 (ptl1) 80 90 #define GET_PTL3_ADDRESS_ARCH(ptl2, i) \ 81 (ptl2)91 (ptl2) 82 92 #define GET_FRAME_ADDRESS_ARCH(ptl3, i) \ 83 ((uintptr_t) ((((pte_t *)(ptl3))[(i)].l1).frame_base_addr << 12))93 ((uintptr_t) ((((pte_t *)(ptl3))[(i)].l1).frame_base_addr << 12)) 84 94 85 95 /* Set PTE address accessors for each level. */ 86 96 #define SET_PTL0_ADDRESS_ARCH(ptl0) \ 87 (set_ptl0_addr((pte_t *) (ptl0)))97 (set_ptl0_addr((pte_t *) (ptl0))) 88 98 #define SET_PTL1_ADDRESS_ARCH(ptl0, i, a) \ 89 (((pte_t *) (ptl0))[(i)].l0.coarse_table_addr = (a) >> 10)99 (((pte_t *) (ptl0))[(i)].l0.coarse_table_addr = (a) >> 10) 90 100 #define SET_PTL2_ADDRESS_ARCH(ptl1, i, a) 91 101 #define SET_PTL3_ADDRESS_ARCH(ptl2, i, a) 92 102 #define SET_FRAME_ADDRESS_ARCH(ptl3, i, a) \ 93 (((pte_t *) (ptl3))[(i)].l1.frame_base_addr = (a) >> 12)103 (((pte_t *) (ptl3))[(i)].l1.frame_base_addr = (a) >> 12) 94 104 95 105 /* Get PTE flags accessors for each level. */ 96 106 #define GET_PTL1_FLAGS_ARCH(ptl0, i) \ 97 get_pt_level0_flags((pte_t *) (ptl0), (size_t) (i))107 get_pt_level0_flags((pte_t *) (ptl0), (size_t) (i)) 98 108 #define GET_PTL2_FLAGS_ARCH(ptl1, i) \ 99 PAGE_PRESENT109 PAGE_PRESENT 100 110 #define GET_PTL3_FLAGS_ARCH(ptl2, i) \ 101 PAGE_PRESENT111 PAGE_PRESENT 102 112 #define GET_FRAME_FLAGS_ARCH(ptl3, i) \ 103 get_pt_level1_flags((pte_t *) (ptl3), (size_t) (i))113 get_pt_level1_flags((pte_t *) (ptl3), (size_t) (i)) 104 114 105 115 /* Set PTE flags accessors for each level. */ 106 116 #define SET_PTL1_FLAGS_ARCH(ptl0, i, x) \ 107 set_pt_level0_flags((pte_t *) (ptl0), (size_t) (i), (x))117 set_pt_level0_flags((pte_t *) (ptl0), (size_t) (i), (x)) 108 118 #define SET_PTL2_FLAGS_ARCH(ptl1, i, x) 109 119 #define SET_PTL3_FLAGS_ARCH(ptl2, i, x) … … 119 129 set_pt_level1_present((pte_t *) (ptl3), (size_t) (i)) 120 130 121 /* Macros for querying the last-level PTE entries. */ 122 #define PTE_VALID_ARCH(pte) \ 123 (*((uint32_t *) (pte)) != 0) 124 #define PTE_PRESENT_ARCH(pte) \ 125 (((pte_t *) (pte))->l0.descriptor_type != 0) 126 #define PTE_GET_FRAME_ARCH(pte) \ 127 (((pte_t *) (pte))->l1.frame_base_addr << FRAME_WIDTH) 128 #define PTE_WRITABLE_ARCH(pte) \ 129 (((pte_t *) (pte))->l1.access_permission_0 == PTE_AP_USER_RW_KERNEL_RW) 130 #define PTE_EXECUTABLE_ARCH(pte) \ 131 1 132 133 #ifndef __ASM__ 134 135 /** Level 0 page table entry. */ 136 typedef struct { 137 /* 0b01 for coarse tables, see below for details */ 138 unsigned descriptor_type : 2; 139 unsigned impl_specific : 3; 140 unsigned domain : 4; 141 unsigned should_be_zero : 1; 142 143 /* Pointer to the coarse 2nd level page table (holding entries for small 144 * (4KB) or large (64KB) pages. ARM also supports fine 2nd level page 145 * tables that may hold even tiny pages (1KB) but they are bigger (4KB 146 * per table in comparison with 1KB per the coarse table) 147 */ 148 unsigned coarse_table_addr : 22; 149 } ATTRIBUTE_PACKED pte_level0_t; 150 151 /** Level 1 page table entry (small (4KB) pages used). */ 152 typedef struct { 153 154 /* 0b10 for small pages */ 155 unsigned descriptor_type : 2; 156 unsigned bufferable : 1; 157 unsigned cacheable : 1; 158 159 /* access permissions for each of 4 subparts of a page 160 * (for each 1KB when small pages used */ 161 unsigned access_permission_0 : 2; 162 unsigned access_permission_1 : 2; 163 unsigned access_permission_2 : 2; 164 unsigned access_permission_3 : 2; 165 unsigned frame_base_addr : 20; 166 } ATTRIBUTE_PACKED pte_level1_t; 167 168 typedef union { 169 pte_level0_t l0; 170 pte_level1_t l1; 171 } pte_t; 172 173 /* Level 1 page tables access permissions */ 174 175 /** User mode: no access, privileged mode: no access. */ 176 #define PTE_AP_USER_NO_KERNEL_NO 0 177 178 /** User mode: no access, privileged mode: read/write. */ 179 #define PTE_AP_USER_NO_KERNEL_RW 1 180 181 /** User mode: read only, privileged mode: read/write. */ 182 #define PTE_AP_USER_RO_KERNEL_RW 2 183 184 /** User mode: read/write, privileged mode: read/write. */ 185 #define PTE_AP_USER_RW_KERNEL_RW 3 186 187 188 /* pte_level0_t and pte_level1_t descriptor_type flags */ 189 190 /** pte_level0_t and pte_level1_t "not present" flag (used in descriptor_type). */ 191 #define PTE_DESCRIPTOR_NOT_PRESENT 0 192 193 /** pte_level0_t coarse page table flag (used in descriptor_type). */ 194 #define PTE_DESCRIPTOR_COARSE_TABLE 1 195 196 /** pte_level1_t small page table flag (used in descriptor type). */ 197 #define PTE_DESCRIPTOR_SMALL_PAGE 2 198 199 200 /** Sets the address of level 0 page table. 201 * 202 * @param pt Pointer to the page table to set. 203 * 204 */ 205 NO_TRACE static inline void set_ptl0_addr(pte_t *pt) 206 { 207 asm volatile ( 208 "mcr p15, 0, %[pt], c2, c0, 0\n" 209 :: [pt] "r" (pt) 210 ); 211 } 212 213 214 /** Returns level 0 page table entry flags. 215 * 216 * @param pt Level 0 page table. 217 * @param i Index of the entry to return. 218 * 219 */ 220 NO_TRACE static inline int get_pt_level0_flags(pte_t *pt, size_t i) 221 { 222 pte_level0_t *p = &pt[i].l0; 223 int np = (p->descriptor_type == PTE_DESCRIPTOR_NOT_PRESENT); 224 225 return (np << PAGE_PRESENT_SHIFT) | (1 << PAGE_USER_SHIFT) | 226 (1 << PAGE_READ_SHIFT) | (1 << PAGE_WRITE_SHIFT) | 227 (1 << PAGE_EXEC_SHIFT) | (1 << PAGE_CACHEABLE_SHIFT); 228 } 229 230 /** Returns level 1 page table entry flags. 231 * 232 * @param pt Level 1 page table. 233 * @param i Index of the entry to return. 234 * 235 */ 236 NO_TRACE static inline int get_pt_level1_flags(pte_t *pt, size_t i) 237 { 238 pte_level1_t *p = &pt[i].l1; 239 240 int dt = p->descriptor_type; 241 int ap = p->access_permission_0; 242 243 return ((dt == PTE_DESCRIPTOR_NOT_PRESENT) << PAGE_PRESENT_SHIFT) | 244 ((ap == PTE_AP_USER_RO_KERNEL_RW) << PAGE_READ_SHIFT) | 245 ((ap == PTE_AP_USER_RW_KERNEL_RW) << PAGE_READ_SHIFT) | 246 ((ap == PTE_AP_USER_RW_KERNEL_RW) << PAGE_WRITE_SHIFT) | 247 ((ap != PTE_AP_USER_NO_KERNEL_RW) << PAGE_USER_SHIFT) | 248 ((ap == PTE_AP_USER_NO_KERNEL_RW) << PAGE_READ_SHIFT) | 249 ((ap == PTE_AP_USER_NO_KERNEL_RW) << PAGE_WRITE_SHIFT) | 250 (1 << PAGE_EXEC_SHIFT) | 251 (p->bufferable << PAGE_CACHEABLE); 252 } 253 254 /** Sets flags of level 0 page table entry. 255 * 256 * @param pt level 0 page table 257 * @param i index of the entry to be changed 258 * @param flags new flags 259 * 260 */ 261 NO_TRACE static inline void set_pt_level0_flags(pte_t *pt, size_t i, int flags) 262 { 263 pte_level0_t *p = &pt[i].l0; 264 265 if (flags & PAGE_NOT_PRESENT) { 266 p->descriptor_type = PTE_DESCRIPTOR_NOT_PRESENT; 267 /* 268 * Ensures that the entry will be recognized as valid when 269 * PTE_VALID_ARCH applied. 270 */ 271 p->should_be_zero = 1; 272 } else { 273 p->descriptor_type = PTE_DESCRIPTOR_COARSE_TABLE; 274 p->should_be_zero = 0; 275 } 276 } 277 278 NO_TRACE static inline void set_pt_level0_present(pte_t *pt, size_t i) 279 { 280 pte_level0_t *p = &pt[i].l0; 281 282 p->should_be_zero = 0; 283 write_barrier(); 284 p->descriptor_type = PTE_DESCRIPTOR_COARSE_TABLE; 285 } 286 287 /** Sets flags of level 1 page table entry. 288 * 289 * We use same access rights for the whole page. When page 290 * is not preset we store 1 in acess_rigts_3 so that at least 291 * one bit is 1 (to mark correct page entry, see #PAGE_VALID_ARCH). 292 * 293 * @param pt Level 1 page table. 294 * @param i Index of the entry to be changed. 295 * @param flags New flags. 296 * 297 */ 298 NO_TRACE static inline void set_pt_level1_flags(pte_t *pt, size_t i, int flags) 299 { 300 pte_level1_t *p = &pt[i].l1; 301 302 if (flags & PAGE_NOT_PRESENT) 303 p->descriptor_type = PTE_DESCRIPTOR_NOT_PRESENT; 304 else 305 p->descriptor_type = PTE_DESCRIPTOR_SMALL_PAGE; 306 307 p->cacheable = p->bufferable = (flags & PAGE_CACHEABLE) != 0; 308 309 /* default access permission */ 310 p->access_permission_0 = p->access_permission_1 = 311 p->access_permission_2 = p->access_permission_3 = 312 PTE_AP_USER_NO_KERNEL_RW; 313 314 if (flags & PAGE_USER) { 315 if (flags & PAGE_READ) { 316 p->access_permission_0 = p->access_permission_1 = 317 p->access_permission_2 = p->access_permission_3 = 318 PTE_AP_USER_RO_KERNEL_RW; 319 } 320 if (flags & PAGE_WRITE) { 321 p->access_permission_0 = p->access_permission_1 = 322 p->access_permission_2 = p->access_permission_3 = 323 PTE_AP_USER_RW_KERNEL_RW; 324 } 325 } 326 } 327 328 NO_TRACE static inline void set_pt_level1_present(pte_t *pt, size_t i) 329 { 330 pte_level1_t *p = &pt[i].l1; 331 332 p->descriptor_type = PTE_DESCRIPTOR_SMALL_PAGE; 333 } 334 335 extern void page_arch_init(void); 336 337 #endif /* __ASM__ */ 131 #if defined(PROCESSOR_ARCH_armv6) | defined(PROCESSOR_ARCH_armv7_a) 132 #include "page_armv6.h" 133 #elif defined(PROCESSOR_ARCH_armv4) | defined(PROCESSOR_ARCH_armv5) 134 #include "page_armv4.h" 135 #else 136 #error "Unsupported architecture" 137 #endif 338 138 339 139 #endif -
kernel/arch/arm32/include/arch/mm/page_fault.h
rea906c29 r850235d 40 40 41 41 42 /** Decribes CP15 "fault status register" (FSR). */43 typedef struct { 44 unsigned status : 3; 45 unsigned domain : 4; 46 unsigned zero : 1; 47 unsigned should_be_zero : 24; 48 } ATTRIBUTE_PACKED fault_status_t; 49 50 51 /** Help union used for casting integer value into #fault_status_t.*/42 /** Decribes CP15 "fault status register" (FSR). 43 * 44 * "VMSAv6 added a fifth fault status bit (bit[10]) to both the IFSR and DFSR. 45 * It is IMPLEMENTATION DEFINED how this bit is encoded in earlier versions of 46 * the architecture. A write flag (bit[11] of the DFSR) has also been 47 * introduced." 48 * ARM Architecture Reference Manual version i ch. B4.6 (PDF p. 719) 49 * 50 * See ARM Architecture Reference Manual ch. B4.9.6 (pdf p.743). for FSR info 51 */ 52 52 typedef union { 53 fault_status_t fs; 54 uint32_t dummy; 55 } fault_status_union_t; 53 struct { 54 unsigned status : 4; 55 unsigned domain : 4; 56 unsigned zero : 1; 57 unsigned lpae : 1; /**< Needs LPAE support implemented */ 58 unsigned fs : 1; /**< armv6+ mandated, earlier IPLM. DEFINED */ 59 unsigned wr : 1; /**< armv6+ only */ 60 unsigned ext : 1 ; /**< external abort */ 61 unsigned cm : 1; /**< Cache maintenance, needs LPAE support */ 62 unsigned should_be_zero : 18; 63 } data; 64 struct { 65 unsigned status : 4; 66 unsigned sbz0 : 6; 67 unsigned fs : 1; 68 unsigned should_be_zero : 21; 69 } inst; 70 uint32_t raw; 71 } fault_status_t; 56 72 57 73 -
kernel/arch/arm32/include/arch/regutils.h
rea906c29 r850235d 41 41 #define STATUS_REG_MODE_MASK 0x1f 42 42 43 #define CP15_R1_HIGH_VECTORS_BIT (1 << 13)44 45 43 /* ARM Processor Operation Modes */ 46 #define USER_MODE 0x10 47 #define FIQ_MODE 0x11 48 #define IRQ_MODE 0x12 49 #define SUPERVISOR_MODE 0x13 50 #define ABORT_MODE 0x17 51 #define UNDEFINED_MODE 0x1b 52 #define SYSTEM_MODE 0x1f 53 44 enum { 45 USER_MODE = 0x10, 46 FIQ_MODE = 0x11, 47 IRQ_MODE = 0x12, 48 SUPERVISOR_MODE = 0x13, 49 MONITOR_MODE = 0x16, 50 ABORT_MODE = 0x17, 51 HYPERVISOR_MODE = 0x1a, 52 UNDEFINED_MODE = 0x1b, 53 SYSTEM_MODE = 0x1f, 54 MODE_MASK = 0x1f, 55 }; 54 56 /* [CS]PRS manipulation macros */ 55 57 #define GEN_STATUS_READ(nm, reg) \
Note:
See TracChangeset
for help on using the changeset viewer.
