Changeset 6b781c0 in mainline for kernel/arch/arm32/include


Ignore:
Timestamp:
2007-06-08T15:02:49Z (18 years ago)
Author:
Jakub Jermar <jakub@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
c03ee1c
Parents:
3ee8a075
Message:

Merge arm32 into trunk.

Location:
kernel/arch/arm32/include
Files:
10 added
25 edited

Legend:

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

    r3ee8a075 r6b781c0  
    3131 */
    3232/** @file
     33 *  @brief Empty.
    3334 */
    3435
  • kernel/arch/arm32/include/arg.h

    r3ee8a075 r6b781c0  
    3131 */
    3232/** @file
     33 *  @brief Empty.
    3334 */
    3435
  • kernel/arch/arm32/include/asm.h

    r3ee8a075 r6b781c0  
    11/*
    2  * Copyright (c) 2003-2004 Jakub Jermar
     2 * Copyright (c) 2007 Michal Kebrt
    33 * All rights reserved.
    44 *
     
    3030 * @{
    3131 */
    32 /** @file
     32/** @file
     33 *  @brief Declarations of functions implemented in assembly.
    3334 */
    3435
     
    3738
    3839#include <arch/types.h>
     40#include <arch/stack.h>
     41#include <config.h>
     42#include <arch/interrupt.h>
    3943
     44/** No such instruction on ARM to sleep CPU. */
    4045static inline void cpu_sleep(void)
    4146{
    42         /* TODO */
    4347}
    4448
    45 /** Return base address of current stack
     49/** Return base address of current stack.
    4650 *
    4751 * Return the base address of the current stack.
     
    5155static inline uintptr_t get_stack_base(void)
    5256{
    53         /* TODO */     
    54         return NULL;
     57        uintptr_t v;
     58        asm volatile (
     59                "and %0, sp, %1\n"
     60                : "=r" (v)
     61                : "r" (~(STACK_SIZE - 1))
     62        );
     63        return v;
    5564}
    5665
     
    6069    uintptr_t entry);
    6170
    62 extern ipl_t interrupts_disable(void);
    63 extern ipl_t interrupts_enable(void);
    64 extern void interrupts_restore(ipl_t ipl);
    65 extern ipl_t interrupts_read(void);
    66 
    6771#endif
    6872
  • kernel/arch/arm32/include/atomic.h

    r3ee8a075 r6b781c0  
    11/*
    2  * Copyright (c) 2005 Ondrej Palkovsky
     2 * Copyright (c) 2007 Michal Kebrt
    33 * All rights reserved.
    44 *
     
    3030 * @{
    3131 */
    32 /** @file
     32/** @file
     33 *  @brief Atomic operations.
    3334 */
    3435
     
    3637#define KERN_arm32_ATOMIC_H_
    3738
    38 #define atomic_inc(x)   ((void) atomic_add(x, 1))
    39 #define atomic_dec(x)   ((void) atomic_add(x, -1))
    40 
    41 #define atomic_postinc(x) (atomic_add(x, 1) - 1)
    42 #define atomic_postdec(x) (atomic_add(x, -1) + 1)
    43 
    44 #define atomic_preinc(x) atomic_add(x, 1)
    45 #define atomic_predec(x) atomic_add(x, -1)
    46 
    47 /* Atomic addition of immediate value.
     39/** Atomic addition.
    4840 *
    49  * @param val Memory location to which will be the immediate value added.
    50  * @param i Signed immediate that will be added to *val.
     41 * @param val Where to add.
     42 * @param i   Value to be added.
    5143 *
    5244 * @return Value after addition.
     
    5446static inline long atomic_add(atomic_t *val, int i)
    5547{
    56         /* TODO */
    57         return (val->count += i);
     48        int ret;
     49        volatile long *mem = &(val->count);
     50
     51        asm volatile (
     52        "1:\n"
     53                "ldr r2, [%1]       \n"
     54                "add r3, r2, %2     \n"
     55                "str r3, %0         \n"
     56                "swp r3, r3, [%1]   \n"
     57                "cmp r3, r2         \n"
     58                "bne 1b             \n"
     59
     60                : "=m" (ret)
     61                : "r" (mem), "r" (i)
     62                : "r3", "r2"
     63        );
     64
     65        return ret;
     66}
     67
     68/** Atomic increment.
     69 *
     70 * @param val Variable to be incremented.
     71 */
     72static inline void atomic_inc(atomic_t *val)
     73{
     74        atomic_add(val, 1);
     75}
     76
     77/** Atomic decrement.
     78 *
     79 * @param val Variable to be decremented.
     80 */
     81static inline void atomic_dec(atomic_t *val) {
     82        atomic_add(val, -1);
     83}
     84
     85/** Atomic pre-increment.
     86 *
     87 * @param val Variable to be incremented.
     88 * @return    Value after incrementation.
     89 */
     90static inline long atomic_preinc(atomic_t *val)
     91{
     92        return atomic_add(val, 1);
     93}
     94
     95/** Atomic pre-decrement.
     96 *
     97 * @param val Variable to be decremented.
     98 * @return    Value after decrementation.
     99 */
     100static inline long atomic_predec(atomic_t *val)
     101{
     102        return atomic_add(val, -1);
     103}
     104
     105/** Atomic post-increment.
     106 *
     107 * @param val Variable to be incremented.
     108 * @return    Value before incrementation.
     109 */
     110static inline long atomic_postinc(atomic_t *val)
     111{
     112        return atomic_add(val, 1) - 1;
     113}
     114
     115/** Atomic post-decrement.
     116 *
     117 * @param val Variable to be decremented.
     118 * @return    Value before decrementation.
     119 */
     120static inline long atomic_postdec(atomic_t *val)
     121{
     122        return atomic_add(val, -1) + 1;
    58123}
    59124
  • kernel/arch/arm32/include/barrier.h

    r3ee8a075 r6b781c0  
    3131 */
    3232/** @file
     33 *  @brief Memory barriers.
    3334 */
    3435
  • kernel/arch/arm32/include/byteorder.h

    r3ee8a075 r6b781c0  
    3131 */
    3232/** @file
     33 *  @brief Endianness definitions.
    3334 */
    3435
  • kernel/arch/arm32/include/context.h

    r3ee8a075 r6b781c0  
    11/*
    2  * Copyright (c) 2003-2004 Jakub Jermar
     2 * Copyright (c) 2007 Michal Kebrt
    33 * All rights reserved.
    44 *
     
    3131 */
    3232/** @file
     33 *  @brief Thread context.
    3334 */
    3435
     
    3637#define KERN_arm32_CONTEXT_H_
    3738
    38 /*
    39  * Put one item onto the stack to support get_stack_base() and align it up.
    40  */
    41 #define SP_DELTA        0       /* TODO */
     39#include <align.h>
     40#include <arch/stack.h>
    4241
     42/* Put one item onto the stack to support get_stack_base() and align it up. */
     43#define SP_DELTA  (0 + ALIGN_UP(STACK_ITEM_SIZE, STACK_ALIGNMENT))
    4344
    4445#ifndef __ASM__
     
    4647#include <arch/types.h>
    4748
    48 /*
    49  * Only save registers that must be preserved across function calls.
     49/** Thread context containing registers that must be preserved across function
     50 * calls.
    5051 */
    5152typedef struct {
     53        uint32_t cpu_mode;
    5254        uintptr_t sp;
    5355        uintptr_t pc;
     56       
     57        uint32_t r4;
     58        uint32_t r5;
     59        uint32_t r6;
     60        uint32_t r7;
     61        uint32_t r8;
     62        uint32_t r9;
     63        uint32_t r10;
     64        uint32_t r11;
     65       
    5466        ipl_t ipl;
    5567} context_t;
     68
    5669
    5770#endif /* __ASM__ */
  • kernel/arch/arm32/include/cpu.h

    r3ee8a075 r6b781c0  
    11/*
    2  * Copyright (c) 2003-2004 Jakub Jermar
     2 * Copyright (c) 2007 Michal Kebrt
    33 * All rights reserved.
    44 *
     
    3131 */
    3232/** @file
     33 *  @brief CPU identification.
    3334 */
    3435
     
    3940#include <arch/asm.h>
    4041
     42
     43/** Struct representing ARM CPU identifiaction. */
    4144typedef struct {
     45        /** Implementator (vendor) number. */
     46        uint32_t imp_num;
     47
     48        /** Variant number. */
     49        uint32_t variant_num;
     50
     51        /** Architecture number. */
     52        uint32_t arch_num;
     53
     54        /** Primary part number. */
     55        uint32_t prim_part_num;
     56
     57        /** Revision number. */
     58        uint32_t rev_num;
    4259} cpu_arch_t;
    43        
     60
    4461#endif
    4562
  • kernel/arch/arm32/include/cycle.h

    r3ee8a075 r6b781c0  
    11/*
    2  * Copyright (c) 2006 Martin Decky
     2 * Copyright (c) 2007 Michal Kebrt
    33 * All rights reserved.
    44 *
     
    3131 */
    3232/** @file
     33 *  @brief Count of CPU cycles.
    3334 */
    3435
     
    3637#define KERN_arm32_CYCLE_H_
    3738
     39/** Returns count of CPU cycles.
     40 *
     41 *  No such instruction on ARM to get count of cycles.
     42 *
     43 *  @return Count of CPU cycles.
     44 */
    3845static inline uint64_t get_cycle(void)
    3946{
    40         /* TODO */
    4147        return 0;
    4248}
  • kernel/arch/arm32/include/debug.h

    r3ee8a075 r6b781c0  
    3131 */
    3232/** @file
     33 *  @brief Empty.
    3334 */
    3435
  • kernel/arch/arm32/include/elf.h

    r3ee8a075 r6b781c0  
    3131 */
    3232/** @file
     33 *  @brief ARM ELF constants.
    3334 */
    3435
  • kernel/arch/arm32/include/exception.h

    r3ee8a075 r6b781c0  
    11/*
    2  * Copyright (c) 2003-2004 Jakub Jermar
     2 * Copyright (c) 2007 Michal Kebrt, Petr Stepan
     3 *
    34 * All rights reserved.
    45 *
     
    3132 */
    3233/** @file
     34 *  @brief Exception declarations.
    3335 */
    3436
     
    3739
    3840#include <arch/types.h>
     41#include <arch/regutils.h>
    3942
     43/** If defined, forces using of high exception vectors. */
     44#define HIGH_EXCEPTION_VECTORS
     45
     46#ifdef HIGH_EXCEPTION_VECTORS
     47        #define EXC_BASE_ADDRESS        0xffff0000
     48#else
     49        #define EXC_BASE_ADDRESS        0x0
     50#endif
     51
     52/* Exception Vectors */
     53#define EXC_RESET_VEC          (EXC_BASE_ADDRESS + 0x0)
     54#define EXC_UNDEF_INSTR_VEC    (EXC_BASE_ADDRESS + 0x4)
     55#define EXC_SWI_VEC            (EXC_BASE_ADDRESS + 0x8)
     56#define EXC_PREFETCH_ABORT_VEC (EXC_BASE_ADDRESS + 0xc)
     57#define EXC_DATA_ABORT_VEC     (EXC_BASE_ADDRESS + 0x10)
     58#define EXC_IRQ_VEC            (EXC_BASE_ADDRESS + 0x18)
     59#define EXC_FIQ_VEC            (EXC_BASE_ADDRESS + 0x1c)
     60
     61/* Exception numbers */
     62#define EXC_RESET           0
     63#define EXC_UNDEF_INSTR     1
     64#define EXC_SWI             2
     65#define EXC_PREFETCH_ABORT  3
     66#define EXC_DATA_ABORT      4
     67#define EXC_IRQ             5
     68#define EXC_FIQ             6
     69
     70
     71/** Kernel stack pointer.
     72 *
     73 * It is set when thread switches to user mode,
     74 * and then used for exception handling.
     75 */
     76extern uintptr_t supervisor_sp;
     77
     78
     79/** Temporary exception stack pointer.
     80 *
     81 * Temporary stack is used in exceptions handling routines
     82 * before switching to thread's kernel stack.
     83 */
     84extern uintptr_t exc_stack;
     85
     86
     87/** Struct representing CPU state saved when an exception occurs. */
    4088typedef struct {
    41         /* TODO */
     89        uint32_t spsr;
     90        uint32_t sp;
     91        uint32_t lr;
     92
     93        uint32_t r0;
     94        uint32_t r1;
     95        uint32_t r2;
     96        uint32_t r3;
     97        uint32_t r4;
     98        uint32_t r5;
     99        uint32_t r6;
     100        uint32_t r7;
     101        uint32_t r8;
     102        uint32_t r9;
     103        uint32_t r10;
     104        uint32_t r11;
     105        uint32_t r12;
     106
     107        uint32_t pc;
    42108} istate_t;
    43109
     110
     111/** Sets Program Counter member of given istate structure.
     112 *
     113 * @param istate istate structure
     114 * @param retaddr new value of istate's PC member
     115 */
    44116static inline void istate_set_retaddr(istate_t *istate, uintptr_t retaddr)
    45117{
    46         /* TODO */
     118        istate->pc = retaddr;
    47119}
    48120
    49 /** Return true if exception happened while in userspace */
     121
     122/** Returns true if exception happened while in userspace. */
    50123static inline int istate_from_uspace(istate_t *istate)
    51124{
    52         /* TODO */
    53         return 0;
     125        return (istate->spsr & STATUS_REG_MODE_MASK) == USER_MODE;
    54126}
     127
     128
     129/** Returns Program Counter member of given istate structure. */
    55130static inline unative_t istate_get_pc(istate_t *istate)
    56131{
    57         /* TODO */
    58         return 0;
     132        return istate->pc;
    59133}
     134
     135
     136extern void install_exception_handlers(void);
     137extern void exception_init(void);
     138extern void print_istate(istate_t *istate);
     139
    60140
    61141#endif
  • kernel/arch/arm32/include/faddr.h

    r3ee8a075 r6b781c0  
    3131 */
    3232/** @file
     33 *  @brief Function address conversion.
    3334 */
    3435
     
    3839#include <arch/types.h>
    3940
     41/** Calculate absolute address of function referenced by fptr pointer.
     42 *
     43 * @param fptr Function pointer.
     44 */
    4045#define FADDR(fptr)             ((uintptr_t) (fptr))
    4146
  • kernel/arch/arm32/include/fpu_context.h

    r3ee8a075 r6b781c0  
    11/*
    2  * Copyright (c) 2005 Jakub Vana
     2 * Copyright (c) 2007 Michal Kebrt
    33 * All rights reserved.
    44 *
     
    3131 */
    3232/** @file
     33 *  @brief FPU context (not implemented).
     34 *
     35 *  GXemul doesn't support FPU on its ARM CPU.
    3336 */
    3437
     
    3841#include <arch/types.h>
    3942
    40 #define FPU_CONTEXT_ALIGN    0  /* TODO */
     43#define FPU_CONTEXT_ALIGN    0
    4144
    4245typedef struct {
  • kernel/arch/arm32/include/interrupt.h

    r3ee8a075 r6b781c0  
    11/*
    2  * Copyright (c) 2005 Jakub Jermar
     2 * Copyright (c) 2007 Michal Kebrt
    33 * All rights reserved.
    44 *
     
    2828
    2929/** @addtogroup arm32interrupt
    30  * @ingroup interrupt
    3130 * @{
    3231 */
    3332/** @file
     33 *  @brief Declarations of interrupt controlling routines.
    3434 */
    3535
     
    3737#define KERN_arm32_INTERRUPT_H_
    3838
    39 #define IVT_ITEMS       0       /* TODO */
    40 #define IVT_FIRST       0       /* TODO */
     39#include <arch/types.h>
     40
     41/** Initial size of exception dispatch table. */
     42#define IVT_ITEMS       6
     43
     44/** Index of the first item in exception dispatch table. */
     45#define IVT_FIRST       0
     46
     47
     48extern void interrupt_init(void);
     49extern ipl_t interrupts_disable(void);
     50extern ipl_t interrupts_enable(void);
     51extern void interrupts_restore(ipl_t ipl);
     52extern ipl_t interrupts_read(void);
     53
    4154
    4255#endif
  • kernel/arch/arm32/include/memstr.h

    r3ee8a075 r6b781c0  
    3131 */
    3232/** @file
     33 *  @brief Memory manipulating functions declarations.
    3334 */
    3435
  • kernel/arch/arm32/include/mm/as.h

    r3ee8a075 r6b781c0  
    11/*
    2  * Copyright (c) 2005 Jakub Jermar
     2 * Copyright (c) 2007 Pavel Jancik, Michal Kebrt
    33 * All rights reserved.
    44 *
     
    3131 */
    3232/** @file
     33 *  @brief Address space manipulating functions declarations.
    3334 */
    3435
     
    3839#define KERNEL_ADDRESS_SPACE_SHADOWED_ARCH      0
    3940
    40 #define KERNEL_ADDRESS_SPACE_START_ARCH         (unsigned long) 0x80000000
    41 #define KERNEL_ADDRESS_SPACE_END_ARCH           (unsigned long) 0xffffffff
    42 #define USER_ADDRESS_SPACE_START_ARCH           (unsigned long) 0x00000000
    43 #define USER_ADDRESS_SPACE_END_ARCH             (unsigned long) 0x7fffffff
     41#define KERNEL_ADDRESS_SPACE_START_ARCH     (unsigned long) 0x80000000
     42#define KERNEL_ADDRESS_SPACE_END_ARCH       (unsigned long) 0xffffffff
     43#define USER_ADDRESS_SPACE_START_ARCH       (unsigned long) 0x00000000
     44#define USER_ADDRESS_SPACE_END_ARCH         (unsigned long) 0x7fffffff
    4445
    4546#define USTACK_ADDRESS_ARCH     (0x80000000 - PAGE_SIZE)
     
    5354#define as_destructor_arch(as)                  (as != as)
    5455#define as_create_arch(as, flags)               (as != as)
     56#define as_install_arch(as)
    5557#define as_deinstall_arch(as)
    5658#define as_invalidate_translation_cache(as, page, cnt)
  • kernel/arch/arm32/include/mm/asid.h

    r3ee8a075 r6b781c0  
    11/*
    2  * Copyright (c) 2005 Martin Decky
     2 * Copyright (c) 2007 Pavel Jancik, Michal Kebrt
    33 * All rights reserved.
    44 *
     
    3131 */
    3232/** @file
     33 *  @brief ASIDs related declarations.
     34 *
     35 *  ARM CPUs doesn't support ASIDs.
    3336 */
    3437
     
    3841#include <arch/types.h>
    3942
    40 #define ASID_MAX_ARCH           3       /* TODO */
     43#define ASID_MAX_ARCH           3       /* minimal required number */
    4144
    4245typedef uint8_t asid_t;
     46
     47/*
     48 * This works due to fact that this file is never included alone but only
     49 * through "generic/include/mm/asid.h" where ASID_START is defined.
     50 */
     51#define asid_get()              (ASID_START + 1)
     52
     53#define asid_put(asid)
    4354
    4455#endif
  • kernel/arch/arm32/include/mm/frame.h

    r3ee8a075 r6b781c0  
    11/*
    2  * Copyright (c) 2005 Jakub Jermar
     2 * Copyright (c) 2007 Pavel Jancik, Michal Kebrt
    33 * All rights reserved.
    44 *
     
    3131 */
    3232/** @file
     33 *  @brief Frame related declarations.
    3334 */
    3435
     
    3637#define KERN_arm32_FRAME_H_
    3738
    38 #define FRAME_WIDTH             0       /* TODO */
     39#define FRAME_WIDTH             12 /* 4KB frames */
    3940#define FRAME_SIZE              (1 << FRAME_WIDTH)
    4041
     
    4243#ifndef __ASM__
    4344
     45#include <arch/types.h>
     46
     47#define BOOT_PAGE_TABLE_SIZE    0x4000
     48#define BOOT_PAGE_TABLE_ADDRESS 0x4000
     49
     50#define BOOT_PAGE_TABLE_START_FRAME     (BOOT_PAGE_TABLE_ADDRESS >> FRAME_WIDTH)
     51#define BOOT_PAGE_TABLE_SIZE_IN_FRAMES  (BOOT_PAGE_TABLE_SIZE >> FRAME_WIDTH)
     52
     53extern uintptr_t last_frame;
     54
    4455extern void frame_arch_init(void);
     56extern void boot_page_table_free(void);
    4557
    4658#endif /* __ASM__ */
  • kernel/arch/arm32/include/mm/memory_init.h

    r3ee8a075 r6b781c0  
    11/*
    2  * Copyright (c) 2005 Jakub Jermar
     2 * Copyright (c) 2007 Pavel Jancik
    33 * All rights reserved.
    44 *
     
    3131 */
    3232/** @file
     33 *  @brief Memory information functions declarations.
    3334 */
    3435
     
    3839#include <config.h>
    3940
    40 #define get_memory_size()       CONFIG_MEMORY_SIZE      /* TODO */
     41size_t get_memory_size(void);
    4142
    4243#endif
  • kernel/arch/arm32/include/mm/page.h

    r3ee8a075 r6b781c0  
    11/*
    2  * Copyright (c) 2003-2007 Jakub Jermar
     2 * Copyright (c) 2007 Pavel Jancik, Michal Kebrt
    33 * All rights reserved.
    44 *
     
    3131 */
    3232/** @file
     33 *  @brief Paging related declarations.
    3334 */
    3435
     
    3738
    3839#include <arch/mm/frame.h>
     40#include <mm/mm.h>
     41#include <arch/exception.h>
    3942
    4043#define PAGE_WIDTH      FRAME_WIDTH
     
    5356#ifdef KERNEL
    5457
    55 #define PTL0_ENTRIES_ARCH       0       /* TODO */
    56 #define PTL1_ENTRIES_ARCH       0       /* TODO */
    57 #define PTL2_ENTRIES_ARCH       0       /* TODO */
    58 #define PTL3_ENTRIES_ARCH       0       /* TODO */
    59 
    60 #define PTL0_INDEX_ARCH(vaddr)  0       /* TODO */
    61 #define PTL1_INDEX_ARCH(vaddr)  0       /* TODO */
    62 #define PTL2_INDEX_ARCH(vaddr)  0       /* TODO */
    63 #define PTL3_INDEX_ARCH(vaddr)  0       /* TODO */
    64 
    65 #define SET_PTL0_ADDRESS_ARCH(ptl0)
    66 
    67 #define GET_PTL1_ADDRESS_ARCH(ptl0, i)          0       /* TODO */
    68 #define GET_PTL2_ADDRESS_ARCH(ptl1, i)          0       /* TODO */
    69 #define GET_PTL3_ADDRESS_ARCH(ptl2, i)          0       /* TODO */
    70 #define GET_FRAME_ADDRESS_ARCH(ptl3, i)         0       /* TODO */
    71 
    72 #define SET_PTL1_ADDRESS_ARCH(ptl0, i, a)       /* TODO */
    73 #define SET_PTL2_ADDRESS_ARCH(ptl1, i, a)       /* TODO */
    74 #define SET_PTL3_ADDRESS_ARCH(ptl2, i, a)       /* TODO */
    75 #define SET_FRAME_ADDRESS_ARCH(ptl3, i, a)      /* TODO */
    76 
    77 #define GET_PTL1_FLAGS_ARCH(ptl0, i)            0       /* TODO */
    78 #define GET_PTL2_FLAGS_ARCH(ptl1, i)            0       /* TODO */
    79 #define GET_PTL3_FLAGS_ARCH(ptl2, i)            0       /* TODO */
    80 #define GET_FRAME_FLAGS_ARCH(ptl3, i)           0       /* TODO */
    81 
    82 #define SET_PTL1_FLAGS_ARCH(ptl0, i, x)         /* TODO */
    83 #define SET_PTL2_FLAGS_ARCH(ptl1, i, x)         /* TODO */
    84 #define SET_PTL3_FLAGS_ARCH(ptl2, i, x)         /* TODO */
    85 #define SET_FRAME_FLAGS_ARCH(ptl3, i, x)        /* TODO */
    86 
    87 #define PTE_VALID_ARCH(pte)                     0       /* TODO */
    88 #define PTE_PRESENT_ARCH(pte)                   0       /* TODO */
    89 #define PTE_GET_FRAME_ARCH(pte)                 0       /* TODO */
    90 #define PTE_WRITABLE_ARCH(pte)                  0       /* TODO */
    91 #define PTE_EXECUTABLE_ARCH(pte)                0       /* TODO */
     58#define PTL0_ENTRIES_ARCH       (2 << 12)       /* 4096 */
     59#define PTL1_ENTRIES_ARCH       0
     60#define PTL2_ENTRIES_ARCH       0
     61
     62/* coarse page tables used (256 * 4 = 1KB per page) */
     63#define PTL3_ENTRIES_ARCH       (2 << 8)        /* 256 */
     64
     65#define PTL0_SIZE_ARCH          FOUR_FRAMES
     66#define PTL1_SIZE_ARCH          0
     67#define PTL2_SIZE_ARCH          0
     68#define PTL3_SIZE_ARCH          ONE_FRAME
     69
     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)
     74
     75#define GET_PTL1_ADDRESS_ARCH(ptl0, i) \
     76        ((pte_t *) ((((pte_level0_t *)(ptl0))[(i)]).coarse_table_addr << 10))
     77#define GET_PTL2_ADDRESS_ARCH(ptl1, i) \
     78        (ptl1)
     79#define GET_PTL3_ADDRESS_ARCH(ptl2, i) \
     80        (ptl2)
     81#define GET_FRAME_ADDRESS_ARCH(ptl3, i) \
     82        ((uintptr_t) ((((pte_level1_t *)(ptl3))[(i)]).frame_base_addr << 12))
     83
     84#define SET_PTL0_ADDRESS_ARCH(ptl0) \
     85        (set_ptl0_addr((pte_level0_t *) (ptl0)))
     86#define SET_PTL1_ADDRESS_ARCH(ptl0, i, a) \
     87        (((pte_level0_t *) (ptl0))[(i)].coarse_table_addr = (a) >> 10)
     88#define SET_PTL2_ADDRESS_ARCH(ptl1, i, a)
     89#define SET_PTL3_ADDRESS_ARCH(ptl2, i, a)
     90#define SET_FRAME_ADDRESS_ARCH(ptl3, i, a) \
     91        (((pte_level1_t *) (ptl3))[(i)].frame_base_addr = (a) >> 12)
     92
     93#define GET_PTL1_FLAGS_ARCH(ptl0, i) \
     94        get_pt_level0_flags((pte_level0_t *) (ptl0), (index_t) (i))
     95#define GET_PTL2_FLAGS_ARCH(ptl1, i) \
     96        PAGE_PRESENT
     97#define GET_PTL3_FLAGS_ARCH(ptl2, i) \
     98        PAGE_PRESENT
     99#define GET_FRAME_FLAGS_ARCH(ptl3, i) \
     100        get_pt_level1_flags((pte_level1_t *) (ptl3), (index_t) (i))
     101
     102#define SET_PTL1_FLAGS_ARCH(ptl0, i, x) \
     103        set_pt_level0_flags((pte_level0_t *) (ptl0), (index_t) (i), (x))
     104#define SET_PTL2_FLAGS_ARCH(ptl1, i, x)
     105#define SET_PTL3_FLAGS_ARCH(ptl2, i, x)
     106#define SET_FRAME_FLAGS_ARCH(ptl3, i, x) \
     107        set_pt_level1_flags((pte_level1_t *) (ptl3), (index_t) (i), (x))
     108
     109#define PTE_VALID_ARCH(pte) \
     110        (*((uint32_t *) (pte)) != 0)
     111#define PTE_PRESENT_ARCH(pte) \
     112        (((pte_level0_t *) (pte))->descriptor_type != 0)
     113
     114/* pte should point into ptl3 */
     115#define PTE_GET_FRAME_ARCH(pte) \
     116        (((pte_level1_t *) (pte))->frame_base_addr << FRAME_WIDTH)
     117
     118/* pte should point into ptl3 */
     119#define PTE_WRITABLE_ARCH(pte) \
     120        (((pte_level1_t *) (pte))->access_permission_0 == \
     121            PTE_AP_USER_RW_KERNEL_RW)
     122
     123#define PTE_EXECUTABLE_ARCH(pte) \
     124        1
    92125
    93126#ifndef __ASM__
    94127
    95 #include <mm/mm.h>
    96 #include <arch/exception.h>
    97 
    98 static inline int get_pt_flags(pte_t *pt, index_t i)
    99 {
    100         return 0;       /* TODO */
    101 }
    102 
    103 static inline void set_pt_flags(pte_t *pt, index_t i, int flags)
    104 {
    105         /* TODO */
    106         return;
    107 }
     128/** Level 0 page table entry. */
     129typedef struct {
     130        /* 0b01 for coarse tables, see below for details */
     131        unsigned descriptor_type     : 2;
     132        unsigned impl_specific       : 3;
     133        unsigned domain              : 4;
     134        unsigned should_be_zero      : 1;
     135
     136        /* Pointer to the coarse 2nd level page table (holding entries for small
     137         * (4KB) or large (64KB) pages. ARM also supports fine 2nd level page
     138         * tables that may hold even tiny pages (1KB) but they are bigger (4KB
     139         * per table in comparison with 1KB per the coarse table)
     140         */
     141        unsigned coarse_table_addr   : 22;
     142} ATTRIBUTE_PACKED pte_level0_t;
     143
     144/** Level 1 page table entry (small (4KB) pages used). */
     145typedef struct {
     146
     147        /* 0b10 for small pages */
     148        unsigned descriptor_type     : 2;
     149        unsigned bufferable          : 1;
     150        unsigned cacheable           : 1;
     151
     152        /* access permissions for each of 4 subparts of a page
     153         * (for each 1KB when small pages used */
     154        unsigned access_permission_0 : 2;
     155        unsigned access_permission_1 : 2;
     156        unsigned access_permission_2 : 2;
     157        unsigned access_permission_3 : 2;
     158        unsigned frame_base_addr     : 20;
     159} ATTRIBUTE_PACKED pte_level1_t;
     160
     161
     162/* Level 1 page tables access permissions */
     163
     164/** User mode: no access, privileged mode: no access. */
     165#define PTE_AP_USER_NO_KERNEL_NO        0
     166
     167/** User mode: no access, privileged mode: read/write. */
     168#define PTE_AP_USER_NO_KERNEL_RW        1
     169
     170/** User mode: read only, privileged mode: read/write. */
     171#define PTE_AP_USER_RO_KERNEL_RW        2
     172
     173/** User mode: read/write, privileged mode: read/write. */
     174#define PTE_AP_USER_RW_KERNEL_RW        3
     175
     176
     177/* pte_level0_t and pte_level1_t descriptor_type flags */
     178
     179/** pte_level0_t and pte_level1_t "not present" flag (used in descriptor_type). */
     180#define PTE_DESCRIPTOR_NOT_PRESENT      0
     181
     182/** pte_level0_t coarse page table flag (used in descriptor_type). */
     183#define PTE_DESCRIPTOR_COARSE_TABLE     1
     184
     185/** pte_level1_t small page table flag (used in descriptor type). */
     186#define PTE_DESCRIPTOR_SMALL_PAGE       2
     187
     188
     189/** Sets the address of level 0 page table.
     190 *
     191 * @param pt    Pointer to the page table to set.
     192 */   
     193static inline void set_ptl0_addr( pte_level0_t *pt)
     194{
     195        asm volatile (
     196                "mcr p15, 0, %0, c2, c0, 0 \n"
     197                :
     198                : "r"(pt)
     199        );
     200}
     201
     202
     203/** Returns level 0 page table entry flags.
     204 *
     205 *  @param pt     Level 0 page table.
     206 *  @param i      Index of the entry to return.
     207 */
     208static inline int get_pt_level0_flags(pte_level0_t *pt, index_t i)
     209{
     210        pte_level0_t *p = &pt[i];
     211        int np = (p->descriptor_type == PTE_DESCRIPTOR_NOT_PRESENT);
     212
     213        return (np << PAGE_PRESENT_SHIFT) | (1 << PAGE_USER_SHIFT) |
     214            (1 << PAGE_READ_SHIFT) | (1 << PAGE_WRITE_SHIFT) |
     215            (1 << PAGE_EXEC_SHIFT) | (1 << PAGE_CACHEABLE_SHIFT);
     216}
     217
     218/** Returns level 1 page table entry flags.
     219 *
     220 *  @param pt     Level 1 page table.
     221 *  @param i      Index of the entry to return.
     222 */
     223static inline int get_pt_level1_flags(pte_level1_t *pt, index_t i)
     224{
     225        pte_level1_t *p = &pt[i];
     226
     227        int dt = p->descriptor_type;
     228        int ap = p->access_permission_0;
     229
     230        return ((dt == PTE_DESCRIPTOR_NOT_PRESENT) << PAGE_PRESENT_SHIFT) |
     231            ((ap == PTE_AP_USER_RO_KERNEL_RW) << PAGE_READ_SHIFT) |
     232            ((ap == PTE_AP_USER_RW_KERNEL_RW) << PAGE_READ_SHIFT) |
     233            ((ap == PTE_AP_USER_RW_KERNEL_RW) << PAGE_WRITE_SHIFT) |
     234            ((ap != PTE_AP_USER_NO_KERNEL_RW) << PAGE_USER_SHIFT) |
     235            ((ap == PTE_AP_USER_NO_KERNEL_RW) << PAGE_READ_SHIFT) |
     236            ((ap == PTE_AP_USER_NO_KERNEL_RW) << PAGE_WRITE_SHIFT) |
     237            (1 << PAGE_EXEC_SHIFT) |
     238            (p->bufferable << PAGE_CACHEABLE);
     239}
     240
     241
     242/** Sets flags of level 0 page table entry.
     243 *
     244 *  @param pt     level 0 page table
     245 *  @param i      index of the entry to be changed
     246 *  @param flags  new flags
     247 */
     248static inline void set_pt_level0_flags(pte_level0_t *pt, index_t i, int flags)
     249{
     250        pte_level0_t *p = &pt[i];
     251
     252        if (flags & PAGE_NOT_PRESENT) {
     253                p->descriptor_type = PTE_DESCRIPTOR_NOT_PRESENT;
     254                /*
     255                 * Ensures that the entry will be recognized as valid when
     256                 * PTE_VALID_ARCH applied.
     257                 */
     258                p->should_be_zero = 1;
     259        } else {
     260                p->descriptor_type = PTE_DESCRIPTOR_COARSE_TABLE;
     261                p->should_be_zero = 0;
     262    }
     263}
     264
     265
     266/** Sets flags of level 1 page table entry.
     267 *
     268 *  We use same access rights for the whole page. When page is not preset we
     269 *  store 1 in acess_rigts_3 so that at least one bit is 1 (to mark correct
     270 *  page entry, see #PAGE_VALID_ARCH).
     271 *
     272 *  @param pt     Level 1 page table.
     273 *  @param i      Index of the entry to be changed.
     274 *  @param flags  New flags.
     275 */ 
     276static inline void set_pt_level1_flags(pte_level1_t *pt, index_t i, int flags)
     277{
     278        pte_level1_t *p = &pt[i];
     279       
     280        if (flags & PAGE_NOT_PRESENT) {
     281                p->descriptor_type = PTE_DESCRIPTOR_NOT_PRESENT;
     282                p->access_permission_3 = 1;
     283        } else {
     284                p->descriptor_type = PTE_DESCRIPTOR_SMALL_PAGE;
     285                p->access_permission_3 = p->access_permission_0;
     286        }
     287 
     288        p->cacheable = p->bufferable = (flags & PAGE_CACHEABLE) != 0;
     289
     290        /* default access permission */
     291        p->access_permission_0 = p->access_permission_1 =
     292            p->access_permission_2 = p->access_permission_3 =
     293            PTE_AP_USER_NO_KERNEL_RW;
     294
     295        if (flags & PAGE_USER)  {
     296                if (flags & PAGE_READ) {
     297                        p->access_permission_0 = p->access_permission_1 =
     298                            p->access_permission_2 = p->access_permission_3 =
     299                            PTE_AP_USER_RO_KERNEL_RW;
     300                }
     301                if (flags & PAGE_WRITE) {
     302                        p->access_permission_0 = p->access_permission_1 =
     303                            p->access_permission_2 = p->access_permission_3 =
     304                            PTE_AP_USER_RW_KERNEL_RW;
     305                }
     306        }
     307}
     308
    108309
    109310extern void page_arch_init(void);
    110311
     312
    111313#endif /* __ASM__ */
    112314
  • kernel/arch/arm32/include/mm/tlb.h

    r3ee8a075 r6b781c0  
    11/*
    2  * Copyright (c) 2005 Jakub Jermar
     2 * Copyright (c) 2007 Pavel Jancik
    33 * All rights reserved.
    44 *
     
    3131 */
    3232/** @file
     33 *  @brief TLB related declarations.
    3334 */
    3435
  • kernel/arch/arm32/include/proc/task.h

    r3ee8a075 r6b781c0  
    3131 */
    3232/** @file
     33 *  @brief Task related declarations.
    3334 */
    3435
  • kernel/arch/arm32/include/proc/thread.h

    r3ee8a075 r6b781c0  
    3131 */
    3232/** @file
     33 *  @brief Thread related declarations.
    3334 */
    3435
     
    4748/** @}
    4849 */
    49 
  • kernel/arch/arm32/include/types.h

    r3ee8a075 r6b781c0  
    11/*
    2  * Copyright (c) 2003-2007 Jakub Jermar
     2 * Copyright (c) 2007 Pavel Jancik, Michal Kebrt
    33 * All rights reserved.
    44 *
     
    3131 */
    3232/** @file
     33 *  @brief Type definitions.
    3334 */
    3435
    3536#ifndef KERN_arm32_TYPES_H_
    3637#define KERN_arm32_TYPES_H_
     38
     39#ifndef DOXYGEN
     40#       define ATTRIBUTE_PACKED __attribute__ ((packed))
     41#else
     42#       define ATTRIBUTE_PACKED
     43#endif
    3744
    3845#define NULL 0
     
    7077typedef int32_t devno_t;
    7178
    72 /** Page Table Entry. */
     79
     80/** Page table entry.
     81 *
     82 *  We have different structs for level 0 and level 1 page table entries.
     83 *  See page.h for definition of pte_level*_t.
     84 */
    7385typedef struct {
    74         /* placeholder */
     86        unsigned dummy : 32;
    7587} pte_t;
    7688
Note: See TracChangeset for help on using the changeset viewer.