Changeset 850235d in mainline for kernel/arch/arm32/include


Ignore:
Timestamp:
2013-03-10T14:56:21Z (13 years ago)
Author:
Vojtech Horky <vojtechhorky@…>
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.
Message:

Merge mainline changes

Location:
kernel/arch/arm32/include/arch
Files:
5 added
10 edited
2 moved

Legend:

Unmodified
Added
Removed
  • kernel/arch/arm32/include/arch/asm.h

    rea906c29 r850235d  
    4343#include <trace.h>
    4444
    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 */
    4657NO_TRACE static inline void cpu_sleep(void)
    4758{
     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
    4864}
    4965
  • kernel/arch/arm32/include/arch/barrier.h

    rea906c29 r850235d  
    3737#define KERN_arm32_BARRIER_H_
    3838
    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
    4245#define CS_ENTER_BARRIER()  asm volatile ("" ::: "memory")
    4346#define CS_LEAVE_BARRIER()  asm volatile ("" ::: "memory")
    4447
     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
    4583#define memory_barrier()  asm volatile ("" ::: "memory")
    4684#define read_barrier()    asm volatile ("" ::: "memory")
    4785#define write_barrier()   asm volatile ("" ::: "memory")
     86#define inst_barrier()    asm volatile ("" ::: "memory")
     87#endif
    4888
     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) \
     109do { \
     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) \
     118do { \
     119        for (uintptr_t addr = (uintptr_t)a; addr < (uintptr_t)a + l; addr += 4)\
     120                smc_coherence(addr); \
     121} while (0)
     122#else
    49123#define smc_coherence(a)
    50124#define smc_coherence_block(a, l)
     125#endif
     126
    51127
    52128#endif
  • kernel/arch/arm32/include/arch/cache.h

    rea906c29 r850235d  
    11/*
    2  * Copyright (c) 2011 Martin Sucha
     2 * Copyright (c) 2013 Jan Vesely
    33 * All rights reserved.
    44 *
     
    2727 */
    2828
    29 /** @addtogroup fs
     29/** @addtogroup arm32
    3030 * @{
    31  */
     31 */
     32/** @file
     33 *  @brief Security Extensions Routines
     34 */
    3235
    33 #ifndef EXT2FS_EXT2FS_H_
    34 #define EXT2FS_EXT2FS_H_
     36#ifndef KERN_arm32_CACHE_H_
     37#define KERN_arm32_CACHE_H_
    3538
    36 #include <libext2.h>
    37 #include <libfs.h>
    38 #include <sys/types.h>
     39unsigned dcache_levels(void);
    3940
    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);
     41void dcache_flush(void);
     42void dcache_flush_invalidate(void);
     43void cpu_dcache_flush(void);
     44void cpu_dcache_flush_invalidate(void);
     45void icache_invalidate(void);
    4746
    4847#endif
     48/** @}
     49 */
    4950
    50 /**
    51  * @}
    52  */
  • kernel/arch/arm32/include/arch/cpu.h

    rea906c29 r850235d  
    4040#include <arch/asm.h>
    4141
     42enum {
     43        ARM_MAX_CACHE_LEVELS = 7,
     44};
    4245
    43 /** Struct representing ARM CPU identifiaction. */
     46/** Struct representing ARM CPU identification. */
    4447typedef struct {
    45         /** Implementator (vendor) number. */
     48        /** Implementor (vendor) number. */
    4649        uint32_t imp_num;
    4750
     
    5760        /** Revision number. */
    5861        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;
    5971} cpu_arch_t;
    6072
  • kernel/arch/arm32/include/arch/cycle.h

    rea906c29 r850235d  
    3838
    3939#include <trace.h>
     40#include <arch/cp15.h>
    4041
    4142/** Return count of CPU cycles.
     
    4849NO_TRACE static inline uint64_t get_cycle(void)
    4950{
     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
    5061        return 0;
    5162}
  • kernel/arch/arm32/include/arch/fpu_context.h

    rea906c29 r850235d  
    3131 */
    3232/** @file
    33  *  @brief FPU context (not implemented).
    34  *
    35  *  GXemul doesn't support FPU on its ARM CPU.
     33 *  @brief FPU context.
    3634 */
    3735
     
    4139#include <typedefs.h>
    4240
    43 #define FPU_CONTEXT_ALIGN    0
     41#define FPU_CONTEXT_ALIGN    8
    4442
     43/* ARM Architecture reference manual, p B-1529.
     44 */
    4545typedef struct {
     46        uint32_t fpexc;
     47        uint32_t fpscr;
     48        uint32_t s[64];
    4649} fpu_context_t;
     50
     51void fpu_setup(void);
     52
     53bool handle_if_fpu_exception(void);
    4754
    4855#endif
  • kernel/arch/arm32/include/arch/mach/beagleboardxm/beagleboardxm.h

    rea906c29 r850235d  
    11/*
    2  * Copyright (c) 2006 Ondrej Palkovsky
     2 * Copyright (c) 2012 Jan Vesely
    33 * All rights reserved.
    44 *
     
    2626 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    2727 */
    28 
    29 /** @addtogroup amd64debug
     28/** @addtogroup arm32beagleboardxm beagleboardxm
     29 *  @brief BeagleBoard-xM platform.
     30 *  @ingroup arm32
    3031 * @{
    3132 */
    3233/** @file
     34 *  @brief BeagleBoard platform driver.
    3335 */
    3436
    35 #ifndef KERN_amd64_DEBUGGER_H_
    36 #define KERN_amd64_DEBUGGER_H_
     37#ifndef KERN_arm32_beagleboardxm_H_
     38#define KERN_arm32_beagleboardxm_H_
    3739
    38 #include <typedefs.h>
     40#include <arch/machine_func.h>
    3941
    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);
     42extern struct arm_machine_ops bbxm_machine_ops;
    5343
    5444#endif
     
    5646/** @}
    5747 */
     48
  • kernel/arch/arm32/include/arch/machine_func.h

    rea906c29 r850235d  
    108108extern size_t machine_get_irq_count(void);
    109109
     110extern const char * machine_get_platform_name(void);
     111
    110112#endif
    111113
  • kernel/arch/arm32/include/arch/mm/frame.h

    rea906c29 r850235d  
    4747
    4848#ifdef MACHINE_gta02
     49
     50#define PHYSMEM_START_ADDR       0x30008000
    4951#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
    5063#else
     64
     65#define PHYSMEM_START_ADDR       0x00000000
    5166#define BOOT_PAGE_TABLE_ADDRESS  0x00008000
     67
    5268#endif
    5369
    5470#define BOOT_PAGE_TABLE_START_FRAME     (BOOT_PAGE_TABLE_ADDRESS >> FRAME_WIDTH)
    5571#define BOOT_PAGE_TABLE_SIZE_IN_FRAMES  (BOOT_PAGE_TABLE_SIZE >> FRAME_WIDTH)
    56 
    57 #ifdef MACHINE_gta02
    58 #define PHYSMEM_START_ADDR      0x30008000
    59 #else
    60 #define PHYSMEM_START_ADDR      0x00000000
    61 #endif
    6272
    6373extern void frame_low_arch_init(void);
  • kernel/arch/arm32/include/arch/mm/page.h

    rea906c29 r850235d  
    4646#define PAGE_SIZE       FRAME_SIZE
    4747
     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
    4857#ifndef __ASM__
    4958#       define KA2PA(x) (((uintptr_t) (x)) - 0x80000000)
     
    5362#       define PA2KA(x) ((x) + 0x80000000)
    5463#endif
     64#endif
    5565
    5666/* Number of entries in each level. */
    57 #define PTL0_ENTRIES_ARCH       (1 << 12)       /* 4096 */
    58 #define PTL1_ENTRIES_ARCH       0
    59 #define PTL2_ENTRIES_ARCH       0
     67#define PTL0_ENTRIES_ARCH       (1 << 12)       /* 4096 */
     68#define PTL1_ENTRIES_ARCH       0
     69#define PTL2_ENTRIES_ARCH       0
    6070/* 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 */
    6272
    6373/* Page table sizes for each level. */
    64 #define PTL0_SIZE_ARCH          FOUR_FRAMES
    65 #define PTL1_SIZE_ARCH          0
    66 #define PTL2_SIZE_ARCH          0
    67 #define PTL3_SIZE_ARCH          ONE_FRAME
     74#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
    6878
    6979/* Macros calculating indices into page tables for each level. */
    70 #define PTL0_INDEX_ARCH(vaddr)  (((vaddr) >> 20) & 0xfff)
    71 #define PTL1_INDEX_ARCH(vaddr)  0
    72 #define PTL2_INDEX_ARCH(vaddr)  0
    73 #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)
    7484
    7585/* Get PTE address accessors for each level. */
    7686#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))
    7888#define GET_PTL2_ADDRESS_ARCH(ptl1, i) \
    79         (ptl1)
     89        (ptl1)
    8090#define GET_PTL3_ADDRESS_ARCH(ptl2, i) \
    81         (ptl2)
     91        (ptl2)
    8292#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))
    8494
    8595/* Set PTE address accessors for each level. */
    8696#define SET_PTL0_ADDRESS_ARCH(ptl0) \
    87         (set_ptl0_addr((pte_t *) (ptl0)))
     97        (set_ptl0_addr((pte_t *) (ptl0)))
    8898#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)
    90100#define SET_PTL2_ADDRESS_ARCH(ptl1, i, a)
    91101#define SET_PTL3_ADDRESS_ARCH(ptl2, i, a)
    92102#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)
    94104
    95105/* Get PTE flags accessors for each level. */
    96106#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))
    98108#define GET_PTL2_FLAGS_ARCH(ptl1, i) \
    99         PAGE_PRESENT
     109        PAGE_PRESENT
    100110#define GET_PTL3_FLAGS_ARCH(ptl2, i) \
    101         PAGE_PRESENT
     111        PAGE_PRESENT
    102112#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))
    104114
    105115/* Set PTE flags accessors for each level. */
    106116#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))
    108118#define SET_PTL2_FLAGS_ARCH(ptl1, i, x)
    109119#define SET_PTL3_FLAGS_ARCH(ptl2, i, x)
     
    119129        set_pt_level1_present((pte_t *) (ptl3), (size_t) (i))
    120130
    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
    338138
    339139#endif
  • kernel/arch/arm32/include/arch/mm/page_fault.h

    rea906c29 r850235d  
    4040
    4141
    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 */
    5252typedef 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;
    5672
    5773
  • kernel/arch/arm32/include/arch/regutils.h

    rea906c29 r850235d  
    4141#define STATUS_REG_MODE_MASK         0x1f
    4242
    43 #define CP15_R1_HIGH_VECTORS_BIT     (1 << 13)
    44 
    4543/* 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 
     44enum {
     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};
    5456/* [CS]PRS manipulation macros */
    5557#define GEN_STATUS_READ(nm, reg) \
Note: See TracChangeset for help on using the changeset viewer.