linux/arch/arm/mm/proc-v6.S
<<
>>
Prefs
   1/*
   2 *  linux/arch/arm/mm/proc-v6.S
   3 *
   4 *  Copyright (C) 2001 Deep Blue Solutions Ltd.
   5 *  Modified by Catalin Marinas for noMMU support
   6 *
   7 * This program is free software; you can redistribute it and/or modify
   8 * it under the terms of the GNU General Public License version 2 as
   9 * published by the Free Software Foundation.
  10 *
  11 *  This is the "shell" of the ARMv6 processor support.
  12 */
  13#include <linux/linkage.h>
  14#include <asm/assembler.h>
  15#include <asm/asm-offsets.h>
  16#include <asm/hwcap.h>
  17#include <asm/pgtable-hwdef.h>
  18#include <asm/pgtable.h>
  19
  20#include "proc-macros.S"
  21
  22#define D_CACHE_LINE_SIZE       32
  23
  24#define TTB_C           (1 << 0)
  25#define TTB_S           (1 << 1)
  26#define TTB_IMP         (1 << 2)
  27#define TTB_RGN_NC      (0 << 3)
  28#define TTB_RGN_WBWA    (1 << 3)
  29#define TTB_RGN_WT      (2 << 3)
  30#define TTB_RGN_WB      (3 << 3)
  31
  32#ifndef CONFIG_SMP
  33#define TTB_FLAGS       TTB_RGN_WBWA
  34#else
  35#define TTB_FLAGS       TTB_RGN_WBWA|TTB_S
  36#endif
  37
  38ENTRY(cpu_v6_proc_init)
  39        mov     pc, lr
  40
  41ENTRY(cpu_v6_proc_fin)
  42        stmfd   sp!, {lr}
  43        cpsid   if                              @ disable interrupts
  44        bl      v6_flush_kern_cache_all
  45        mrc     p15, 0, r0, c1, c0, 0           @ ctrl register
  46        bic     r0, r0, #0x1000                 @ ...i............
  47        bic     r0, r0, #0x0006                 @ .............ca.
  48        mcr     p15, 0, r0, c1, c0, 0           @ disable caches
  49        ldmfd   sp!, {pc}
  50
  51/*
  52 *      cpu_v6_reset(loc)
  53 *
  54 *      Perform a soft reset of the system.  Put the CPU into the
  55 *      same state as it would be if it had been reset, and branch
  56 *      to what would be the reset vector.
  57 *
  58 *      - loc   - location to jump to for soft reset
  59 *
  60 *      It is assumed that:
  61 */
  62        .align  5
  63ENTRY(cpu_v6_reset)
  64        mov     pc, r0
  65
  66/*
  67 *      cpu_v6_do_idle()
  68 *
  69 *      Idle the processor (eg, wait for interrupt).
  70 *
  71 *      IRQs are already disabled.
  72 */
  73ENTRY(cpu_v6_do_idle)
  74        mcr     p15, 0, r1, c7, c0, 4           @ wait for interrupt
  75        mov     pc, lr
  76
  77ENTRY(cpu_v6_dcache_clean_area)
  78#ifndef TLB_CAN_READ_FROM_L1_CACHE
  791:      mcr     p15, 0, r0, c7, c10, 1          @ clean D entry
  80        add     r0, r0, #D_CACHE_LINE_SIZE
  81        subs    r1, r1, #D_CACHE_LINE_SIZE
  82        bhi     1b
  83#endif
  84        mov     pc, lr
  85
  86/*
  87 *      cpu_arm926_switch_mm(pgd_phys, tsk)
  88 *
  89 *      Set the translation table base pointer to be pgd_phys
  90 *
  91 *      - pgd_phys - physical address of new TTB
  92 *
  93 *      It is assumed that:
  94 *      - we are not using split page tables
  95 */
  96ENTRY(cpu_v6_switch_mm)
  97#ifdef CONFIG_MMU
  98        mov     r2, #0
  99        ldr     r1, [r1, #MM_CONTEXT_ID]        @ get mm->context.id
 100        orr     r0, r0, #TTB_FLAGS
 101        mcr     p15, 0, r2, c7, c5, 6           @ flush BTAC/BTB
 102        mcr     p15, 0, r2, c7, c10, 4          @ drain write buffer
 103        mcr     p15, 0, r0, c2, c0, 0           @ set TTB 0
 104        mcr     p15, 0, r1, c13, c0, 1          @ set context ID
 105#endif
 106        mov     pc, lr
 107
 108/*
 109 *      cpu_v6_set_pte_ext(ptep, pte, ext)
 110 *
 111 *      Set a level 2 translation table entry.
 112 *
 113 *      - ptep  - pointer to level 2 translation table entry
 114 *                (hardware version is stored at -1024 bytes)
 115 *      - pte   - PTE value to store
 116 *      - ext   - value for extended PTE bits
 117 */
 118        armv6_mt_table cpu_v6
 119
 120ENTRY(cpu_v6_set_pte_ext)
 121#ifdef CONFIG_MMU
 122        armv6_set_pte_ext cpu_v6
 123#endif
 124        mov     pc, lr
 125
 126
 127
 128
 129cpu_v6_name:
 130        .asciz  "ARMv6-compatible processor"
 131        .align
 132
 133        .section ".text.init", #alloc, #execinstr
 134
 135/*
 136 *      __v6_setup
 137 *
 138 *      Initialise TLB, Caches, and MMU state ready to switch the MMU
 139 *      on.  Return in r0 the new CP15 C1 control register setting.
 140 *
 141 *      We automatically detect if we have a Harvard cache, and use the
 142 *      Harvard cache control instructions insead of the unified cache
 143 *      control instructions.
 144 *
 145 *      This should be able to cover all ARMv6 cores.
 146 *
 147 *      It is assumed that:
 148 *      - cache type register is implemented
 149 */
 150__v6_setup:
 151#ifdef CONFIG_SMP
 152        mrc     p15, 0, r0, c1, c0, 1           @ Enable SMP/nAMP mode
 153        orr     r0, r0, #0x20
 154        mcr     p15, 0, r0, c1, c0, 1
 155#endif
 156
 157        mov     r0, #0
 158        mcr     p15, 0, r0, c7, c14, 0          @ clean+invalidate D cache
 159        mcr     p15, 0, r0, c7, c5, 0           @ invalidate I cache
 160        mcr     p15, 0, r0, c7, c15, 0          @ clean+invalidate cache
 161        mcr     p15, 0, r0, c7, c10, 4          @ drain write buffer
 162#ifdef CONFIG_MMU
 163        mcr     p15, 0, r0, c8, c7, 0           @ invalidate I + D TLBs
 164        mcr     p15, 0, r0, c2, c0, 2           @ TTB control register
 165        orr     r4, r4, #TTB_FLAGS
 166        mcr     p15, 0, r4, c2, c0, 1           @ load TTB1
 167#endif /* CONFIG_MMU */
 168        adr     r5, v6_crval
 169        ldmia   r5, {r5, r6}
 170        mrc     p15, 0, r0, c1, c0, 0           @ read control register
 171        bic     r0, r0, r5                      @ clear bits them
 172        orr     r0, r0, r6                      @ set them
 173        mov     pc, lr                          @ return to head.S:__ret
 174
 175        /*
 176         *         V X F   I D LR
 177         * .... ...E PUI. .T.T 4RVI ZFRS BLDP WCAM
 178         * rrrr rrrx xxx0 0101 xxxx xxxx x111 xxxx < forced
 179         *         0 110       0011 1.00 .111 1101 < we want
 180         */
 181        .type   v6_crval, #object
 182v6_crval:
 183        crval   clear=0x01e0fb7f, mmuset=0x00c0387d, ucset=0x00c0187c
 184
 185        .type   v6_processor_functions, #object
 186ENTRY(v6_processor_functions)
 187        .word   v6_early_abort
 188        .word   pabort_noifar
 189        .word   cpu_v6_proc_init
 190        .word   cpu_v6_proc_fin
 191        .word   cpu_v6_reset
 192        .word   cpu_v6_do_idle
 193        .word   cpu_v6_dcache_clean_area
 194        .word   cpu_v6_switch_mm
 195        .word   cpu_v6_set_pte_ext
 196        .size   v6_processor_functions, . - v6_processor_functions
 197
 198        .type   cpu_arch_name, #object
 199cpu_arch_name:
 200        .asciz  "armv6"
 201        .size   cpu_arch_name, . - cpu_arch_name
 202
 203        .type   cpu_elf_name, #object
 204cpu_elf_name:
 205        .asciz  "v6"
 206        .size   cpu_elf_name, . - cpu_elf_name
 207        .align
 208
 209        .section ".proc.info.init", #alloc, #execinstr
 210
 211        /*
 212         * Match any ARMv6 processor core.
 213         */
 214        .type   __v6_proc_info, #object
 215__v6_proc_info:
 216        .long   0x0007b000
 217        .long   0x0007f000
 218        .long   PMD_TYPE_SECT | \
 219                PMD_SECT_BUFFERABLE | \
 220                PMD_SECT_CACHEABLE | \
 221                PMD_SECT_AP_WRITE | \
 222                PMD_SECT_AP_READ
 223        .long   PMD_TYPE_SECT | \
 224                PMD_SECT_XN | \
 225                PMD_SECT_AP_WRITE | \
 226                PMD_SECT_AP_READ
 227        b       __v6_setup
 228        .long   cpu_arch_name
 229        .long   cpu_elf_name
 230        .long   HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP|HWCAP_JAVA
 231        .long   cpu_v6_name
 232        .long   v6_processor_functions
 233        .long   v6wbi_tlb_fns
 234        .long   v6_user_fns
 235        .long   v6_cache_fns
 236        .size   __v6_proc_info, . - __v6_proc_info
 237
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.