1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134
|
/*
* linux/arch/unicore32/mm/proc-ucv2.S
*
* Code specific to PKUnity SoC and UniCore ISA
*
* Copyright (C) 2001-2010 GUAN Xue-tao
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/init.h>
#include <linux/linkage.h>
#include <asm/assembler.h>
#include <asm/hwcap.h>
#include <asm/pgtable-hwdef.h>
#include <asm/pgtable.h>
#include "proc-macros.S"
ENTRY(cpu_proc_fin)
stm.w (lr), [sp-]
mov ip, #PSR_R_BIT | PSR_I_BIT | PRIV_MODE
mov.a asr, ip
b.l __cpuc_flush_kern_all
ldm.w (pc), [sp]+
/*
* cpu_reset(loc)
*
* Perform a soft reset of the system. Put the CPU into the
* same state as it would be if it had been reset, and branch
* to what would be the reset vector.
*
* - loc - location to jump to for soft reset
*/
.align 5
ENTRY(cpu_reset)
mov ip, #0
movc p0.c5, ip, #28 @ Cache invalidate all
nop8
movc p0.c6, ip, #6 @ TLB invalidate all
nop8
movc ip, p0.c1, #0 @ ctrl register
or ip, ip, #0x2000 @ vector base address
andn ip, ip, #0x000f @ ............idam
movc p0.c1, ip, #0 @ disable caches and mmu
nop
mov pc, r0 @ jump to loc
nop8
/*
* cpu_do_idle()
*
* Idle the processor (eg, wait for interrupt).
*
* IRQs are already disabled.
*/
ENTRY(cpu_do_idle)
mov r0, #0 @ PCI address
.rept 8
ldw r1, [r0]
.endr
mov pc, lr
ENTRY(cpu_dcache_clean_area)
#ifndef CONFIG_CPU_DCACHE_LINE_DISABLE
csub.a r1, #MAX_AREA_SIZE
bsg 101f
mov r9, #PAGE_SZ
sub r9, r9, #1 @ PAGE_MASK
1: va2pa r0, r10, r11, r12, r13 @ r10 is PA
b 3f
2: cand.a r0, r9
beq 1b
3: movc p0.c5, r10, #11 @ clean D entry
nop8
add r0, r0, #CACHE_LINESIZE
add r10, r10, #CACHE_LINESIZE
sub.a r1, r1, #CACHE_LINESIZE
bua 2b
mov pc, lr
#endif
101: mov ip, #0
movc p0.c5, ip, #10 @ Dcache clean all
nop8
mov pc, lr
/*
* cpu_do_switch_mm(pgd_phys)
*
* Set the translation table base pointer to be pgd_phys
*
* - pgd_phys - physical address of new pgd
*
* It is assumed that:
* - we are not using split page tables
*/
.align 5
ENTRY(cpu_do_switch_mm)
movc p0.c2, r0, #0 @ update page table ptr
nop8
movc p0.c6, ip, #6 @ TLB invalidate all
nop8
mov pc, lr
/*
* cpu_set_pte(ptep, pte)
*
* Set a level 2 translation table entry.
*
* - ptep - pointer to level 2 translation table entry
* - pte - PTE value to store
*/
.align 5
ENTRY(cpu_set_pte)
stw r1, [r0]
#ifndef CONFIG_CPU_DCACHE_LINE_DISABLE
sub r2, r0, #PAGE_OFFSET
movc p0.c5, r2, #11 @ Dcache clean line
nop8
#else
mov ip, #0
movc p0.c5, ip, #10 @ Dcache clean all
nop8
@dcacheline_flush r0, r2, ip
#endif
mov pc, lr
|