cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

proc-arm1026.S (10917B)


      1/* SPDX-License-Identifier: GPL-2.0-or-later */
      2/*
      3 *  linux/arch/arm/mm/proc-arm1026.S: MMU functions for ARM1026EJ-S
      4 *
      5 *  Copyright (C) 2000 ARM Limited
      6 *  Copyright (C) 2000 Deep Blue Solutions Ltd.
      7 *  hacked for non-paged-MM by Hyok S. Choi, 2003.
      8 *
      9 * These are the low level assembler for performing cache and TLB
     10 * functions on the ARM1026EJ-S.
     11 */
     12#include <linux/linkage.h>
     13#include <linux/init.h>
     14#include <linux/pgtable.h>
     15#include <asm/assembler.h>
     16#include <asm/asm-offsets.h>
     17#include <asm/hwcap.h>
     18#include <asm/pgtable-hwdef.h>
     19#include <asm/ptrace.h>
     20
     21#include "proc-macros.S"
     22
     23/*
     24 * This is the maximum size of an area which will be invalidated
     25 * using the single invalidate entry instructions.  Anything larger
     26 * than this, and we go for the whole cache.
     27 *
     28 * This value should be chosen such that we choose the cheapest
     29 * alternative.
     30 */
     31#define MAX_AREA_SIZE	32768
     32
     33/*
     34 * The size of one data cache line.
     35 */
     36#define CACHE_DLINESIZE	32
     37
     38/*
     39 * The number of data cache segments.
     40 */
     41#define CACHE_DSEGMENTS	16
     42
     43/*
     44 * The number of lines in a cache segment.
     45 */
     46#define CACHE_DENTRIES	64
     47
     48/*
     49 * This is the size at which it becomes more efficient to
     50 * clean the whole cache, rather than using the individual
     51 * cache line maintenance instructions.
     52 */
     53#define CACHE_DLIMIT	32768
     54
     55	.text
     56/*
     57 * cpu_arm1026_proc_init()
     58 */
     59ENTRY(cpu_arm1026_proc_init)
     60	ret	lr
     61
     62/*
     63 * cpu_arm1026_proc_fin()
     64 */
     65ENTRY(cpu_arm1026_proc_fin)
     66	mrc	p15, 0, r0, c1, c0, 0		@ ctrl register
     67	bic	r0, r0, #0x1000 		@ ...i............
     68	bic	r0, r0, #0x000e 		@ ............wca.
     69	mcr	p15, 0, r0, c1, c0, 0		@ disable caches
     70	ret	lr
     71
     72/*
     73 * cpu_arm1026_reset(loc)
     74 *
     75 * Perform a soft reset of the system.	Put the CPU into the
     76 * same state as it would be if it had been reset, and branch
     77 * to what would be the reset vector.
     78 *
     79 * loc: location to jump to for soft reset
     80 */
     81	.align	5
     82	.pushsection	.idmap.text, "ax"
     83ENTRY(cpu_arm1026_reset)
     84	mov	ip, #0
     85	mcr	p15, 0, ip, c7, c7, 0		@ invalidate I,D caches
     86	mcr	p15, 0, ip, c7, c10, 4		@ drain WB
     87#ifdef CONFIG_MMU
     88	mcr	p15, 0, ip, c8, c7, 0		@ invalidate I & D TLBs
     89#endif
     90	mrc	p15, 0, ip, c1, c0, 0		@ ctrl register
     91	bic	ip, ip, #0x000f 		@ ............wcam
     92	bic	ip, ip, #0x1100 		@ ...i...s........
     93	mcr	p15, 0, ip, c1, c0, 0		@ ctrl register
     94	ret	r0
     95ENDPROC(cpu_arm1026_reset)
     96	.popsection
     97
     98/*
     99 * cpu_arm1026_do_idle()
    100 */
    101	.align	5
    102ENTRY(cpu_arm1026_do_idle)
    103	mcr	p15, 0, r0, c7, c0, 4		@ Wait for interrupt
    104	ret	lr
    105
    106/* ================================= CACHE ================================ */
    107
    108	.align	5
    109
    110/*
    111 *	flush_icache_all()
    112 *
    113 *	Unconditionally clean and invalidate the entire icache.
    114 */
    115ENTRY(arm1026_flush_icache_all)
    116#ifndef CONFIG_CPU_ICACHE_DISABLE
    117	mov	r0, #0
    118	mcr	p15, 0, r0, c7, c5, 0		@ invalidate I cache
    119#endif
    120	ret	lr
    121ENDPROC(arm1026_flush_icache_all)
    122
    123/*
    124 *	flush_user_cache_all()
    125 *
    126 *	Invalidate all cache entries in a particular address
    127 *	space.
    128 */
    129ENTRY(arm1026_flush_user_cache_all)
    130	/* FALLTHROUGH */
    131/*
    132 *	flush_kern_cache_all()
    133 *
    134 *	Clean and invalidate the entire cache.
    135 */
    136ENTRY(arm1026_flush_kern_cache_all)
    137	mov	r2, #VM_EXEC
    138	mov	ip, #0
    139__flush_whole_cache:
    140#ifndef CONFIG_CPU_DCACHE_DISABLE
    1411:	mrc	p15, 0, APSR_nzcv, c7, c14, 3		@ test, clean, invalidate
    142	bne	1b
    143#endif
    144	tst	r2, #VM_EXEC
    145#ifndef CONFIG_CPU_ICACHE_DISABLE
    146	mcrne	p15, 0, ip, c7, c5, 0		@ invalidate I cache
    147#endif
    148	mcrne	p15, 0, ip, c7, c10, 4		@ drain WB
    149	ret	lr
    150
    151/*
    152 *	flush_user_cache_range(start, end, flags)
    153 *
    154 *	Invalidate a range of cache entries in the specified
    155 *	address space.
    156 *
    157 *	- start	- start address (inclusive)
    158 *	- end	- end address (exclusive)
    159 *	- flags	- vm_flags for this space
    160 */
    161ENTRY(arm1026_flush_user_cache_range)
    162	mov	ip, #0
    163	sub	r3, r1, r0			@ calculate total size
    164	cmp	r3, #CACHE_DLIMIT
    165	bhs	__flush_whole_cache
    166
    167#ifndef CONFIG_CPU_DCACHE_DISABLE
    1681:	mcr	p15, 0, r0, c7, c14, 1		@ clean+invalidate D entry
    169	add	r0, r0, #CACHE_DLINESIZE
    170	cmp	r0, r1
    171	blo	1b
    172#endif
    173	tst	r2, #VM_EXEC
    174#ifndef CONFIG_CPU_ICACHE_DISABLE
    175	mcrne	p15, 0, ip, c7, c5, 0		@ invalidate I cache
    176#endif
    177	mcrne	p15, 0, ip, c7, c10, 4		@ drain WB
    178	ret	lr
    179
    180/*
    181 *	coherent_kern_range(start, end)
    182 *
    183 *	Ensure coherency between the Icache and the Dcache in the
    184 *	region described by start.  If you have non-snooping
    185 *	Harvard caches, you need to implement this function.
    186 *
    187 *	- start	- virtual start address
    188 *	- end	- virtual end address
    189 */
    190ENTRY(arm1026_coherent_kern_range)
    191	/* FALLTHROUGH */
    192/*
    193 *	coherent_user_range(start, end)
    194 *
    195 *	Ensure coherency between the Icache and the Dcache in the
    196 *	region described by start.  If you have non-snooping
    197 *	Harvard caches, you need to implement this function.
    198 *
    199 *	- start	- virtual start address
    200 *	- end	- virtual end address
    201 */
    202ENTRY(arm1026_coherent_user_range)
    203	mov	ip, #0
    204	bic	r0, r0, #CACHE_DLINESIZE - 1
    2051:
    206#ifndef CONFIG_CPU_DCACHE_DISABLE
    207	mcr	p15, 0, r0, c7, c10, 1		@ clean D entry
    208#endif
    209#ifndef CONFIG_CPU_ICACHE_DISABLE
    210	mcr	p15, 0, r0, c7, c5, 1		@ invalidate I entry
    211#endif
    212	add	r0, r0, #CACHE_DLINESIZE
    213	cmp	r0, r1
    214	blo	1b
    215	mcr	p15, 0, ip, c7, c10, 4		@ drain WB
    216	mov	r0, #0
    217	ret	lr
    218
    219/*
    220 *	flush_kern_dcache_area(void *addr, size_t size)
    221 *
    222 *	Ensure no D cache aliasing occurs, either with itself or
    223 *	the I cache
    224 *
    225 *	- addr	- kernel address
    226 *	- size	- region size
    227 */
    228ENTRY(arm1026_flush_kern_dcache_area)
    229	mov	ip, #0
    230#ifndef CONFIG_CPU_DCACHE_DISABLE
    231	add	r1, r0, r1
    2321:	mcr	p15, 0, r0, c7, c14, 1		@ clean+invalidate D entry
    233	add	r0, r0, #CACHE_DLINESIZE
    234	cmp	r0, r1
    235	blo	1b
    236#endif
    237	mcr	p15, 0, ip, c7, c10, 4		@ drain WB
    238	ret	lr
    239
    240/*
    241 *	dma_inv_range(start, end)
    242 *
    243 *	Invalidate (discard) the specified virtual address range.
    244 *	May not write back any entries.  If 'start' or 'end'
    245 *	are not cache line aligned, those lines must be written
    246 *	back.
    247 *
    248 *	- start	- virtual start address
    249 *	- end	- virtual end address
    250 *
    251 * (same as v4wb)
    252 */
    253arm1026_dma_inv_range:
    254	mov	ip, #0
    255#ifndef CONFIG_CPU_DCACHE_DISABLE
    256	tst	r0, #CACHE_DLINESIZE - 1
    257	bic	r0, r0, #CACHE_DLINESIZE - 1
    258	mcrne	p15, 0, r0, c7, c10, 1		@ clean D entry
    259	tst	r1, #CACHE_DLINESIZE - 1
    260	mcrne	p15, 0, r1, c7, c10, 1		@ clean D entry
    2611:	mcr	p15, 0, r0, c7, c6, 1		@ invalidate D entry
    262	add	r0, r0, #CACHE_DLINESIZE
    263	cmp	r0, r1
    264	blo	1b
    265#endif
    266	mcr	p15, 0, ip, c7, c10, 4		@ drain WB
    267	ret	lr
    268
    269/*
    270 *	dma_clean_range(start, end)
    271 *
    272 *	Clean the specified virtual address range.
    273 *
    274 *	- start	- virtual start address
    275 *	- end	- virtual end address
    276 *
    277 * (same as v4wb)
    278 */
    279arm1026_dma_clean_range:
    280	mov	ip, #0
    281#ifndef CONFIG_CPU_DCACHE_DISABLE
    282	bic	r0, r0, #CACHE_DLINESIZE - 1
    2831:	mcr	p15, 0, r0, c7, c10, 1		@ clean D entry
    284	add	r0, r0, #CACHE_DLINESIZE
    285	cmp	r0, r1
    286	blo	1b
    287#endif
    288	mcr	p15, 0, ip, c7, c10, 4		@ drain WB
    289	ret	lr
    290
    291/*
    292 *	dma_flush_range(start, end)
    293 *
    294 *	Clean and invalidate the specified virtual address range.
    295 *
    296 *	- start	- virtual start address
    297 *	- end	- virtual end address
    298 */
    299ENTRY(arm1026_dma_flush_range)
    300	mov	ip, #0
    301#ifndef CONFIG_CPU_DCACHE_DISABLE
    302	bic	r0, r0, #CACHE_DLINESIZE - 1
    3031:	mcr	p15, 0, r0, c7, c14, 1		@ clean+invalidate D entry
    304	add	r0, r0, #CACHE_DLINESIZE
    305	cmp	r0, r1
    306	blo	1b
    307#endif
    308	mcr	p15, 0, ip, c7, c10, 4		@ drain WB
    309	ret	lr
    310
    311/*
    312 *	dma_map_area(start, size, dir)
    313 *	- start	- kernel virtual start address
    314 *	- size	- size of region
    315 *	- dir	- DMA direction
    316 */
    317ENTRY(arm1026_dma_map_area)
    318	add	r1, r1, r0
    319	cmp	r2, #DMA_TO_DEVICE
    320	beq	arm1026_dma_clean_range
    321	bcs	arm1026_dma_inv_range
    322	b	arm1026_dma_flush_range
    323ENDPROC(arm1026_dma_map_area)
    324
    325/*
    326 *	dma_unmap_area(start, size, dir)
    327 *	- start	- kernel virtual start address
    328 *	- size	- size of region
    329 *	- dir	- DMA direction
    330 */
    331ENTRY(arm1026_dma_unmap_area)
    332	ret	lr
    333ENDPROC(arm1026_dma_unmap_area)
    334
    335	.globl	arm1026_flush_kern_cache_louis
    336	.equ	arm1026_flush_kern_cache_louis, arm1026_flush_kern_cache_all
    337
    338	@ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S)
    339	define_cache_functions arm1026
    340
    341	.align	5
    342ENTRY(cpu_arm1026_dcache_clean_area)
    343#ifndef CONFIG_CPU_DCACHE_DISABLE
    344	mov	ip, #0
    3451:	mcr	p15, 0, r0, c7, c10, 1		@ clean D entry
    346	add	r0, r0, #CACHE_DLINESIZE
    347	subs	r1, r1, #CACHE_DLINESIZE
    348	bhi	1b
    349#endif
    350	ret	lr
    351
    352/* =============================== PageTable ============================== */
    353
    354/*
    355 * cpu_arm1026_switch_mm(pgd)
    356 *
    357 * Set the translation base pointer to be as described by pgd.
    358 *
    359 * pgd: new page tables
    360 */
    361	.align	5
    362ENTRY(cpu_arm1026_switch_mm)
    363#ifdef CONFIG_MMU
    364	mov	r1, #0
    365#ifndef CONFIG_CPU_DCACHE_DISABLE
    3661:	mrc	p15, 0, APSR_nzcv, c7, c14, 3		@ test, clean, invalidate
    367	bne	1b
    368#endif
    369#ifndef CONFIG_CPU_ICACHE_DISABLE
    370	mcr	p15, 0, r1, c7, c5, 0		@ invalidate I cache
    371#endif
    372	mcr	p15, 0, r1, c7, c10, 4		@ drain WB
    373	mcr	p15, 0, r0, c2, c0, 0		@ load page table pointer
    374	mcr	p15, 0, r1, c8, c7, 0		@ invalidate I & D TLBs
    375#endif
    376	ret	lr
    377        
    378/*
    379 * cpu_arm1026_set_pte_ext(ptep, pte, ext)
    380 *
    381 * Set a PTE and flush it out
    382 */
    383	.align	5
    384ENTRY(cpu_arm1026_set_pte_ext)
    385#ifdef CONFIG_MMU
    386	armv3_set_pte_ext
    387	mov	r0, r0
    388#ifndef CONFIG_CPU_DCACHE_DISABLE
    389	mcr	p15, 0, r0, c7, c10, 1		@ clean D entry
    390#endif
    391#endif /* CONFIG_MMU */
    392	ret	lr
    393
    394	.type	__arm1026_setup, #function
    395__arm1026_setup:
    396	mov	r0, #0
    397	mcr	p15, 0, r0, c7, c7		@ invalidate I,D caches on v4
    398	mcr	p15, 0, r0, c7, c10, 4		@ drain write buffer on v4
    399#ifdef CONFIG_MMU
    400	mcr	p15, 0, r0, c8, c7		@ invalidate I,D TLBs on v4
    401	mcr	p15, 0, r4, c2, c0		@ load page table pointer
    402#endif
    403#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
    404	mov	r0, #4				@ explicitly disable writeback
    405	mcr	p15, 7, r0, c15, c0, 0
    406#endif
    407	adr	r5, arm1026_crval
    408	ldmia	r5, {r5, r6}
    409	mrc	p15, 0, r0, c1, c0		@ get control register v4
    410	bic	r0, r0, r5
    411	orr	r0, r0, r6
    412#ifdef CONFIG_CPU_CACHE_ROUND_ROBIN
    413	orr	r0, r0, #0x4000 		@ .R.. .... .... ....
    414#endif
    415	ret	lr
    416	.size	__arm1026_setup, . - __arm1026_setup
    417
    418	/*
    419	 *  R
    420	 * .RVI ZFRS BLDP WCAM
    421	 * .011 1001 ..11 0101
    422	 * 
    423	 */
    424	.type	arm1026_crval, #object
    425arm1026_crval:
    426	crval	clear=0x00007f3f, mmuset=0x00003935, ucset=0x00001934
    427
    428	__INITDATA
    429	@ define struct processor (see <asm/proc-fns.h> and proc-macros.S)
    430	define_processor_functions arm1026, dabort=v5t_early_abort, pabort=legacy_pabort
    431
    432	.section .rodata
    433
    434	string	cpu_arch_name, "armv5tej"
    435	string	cpu_elf_name, "v5"
    436	.align
    437	string	cpu_arm1026_name, "ARM1026EJ-S"
    438	.align
    439
    440	.section ".proc.info.init", "a"
    441
    442	.type	__arm1026_proc_info,#object
    443__arm1026_proc_info:
    444	.long	0x4106a260			@ ARM 1026EJ-S (v5TEJ)
    445	.long	0xff0ffff0
    446	.long   PMD_TYPE_SECT | \
    447		PMD_BIT4 | \
    448		PMD_SECT_AP_WRITE | \
    449		PMD_SECT_AP_READ
    450	.long   PMD_TYPE_SECT | \
    451		PMD_BIT4 | \
    452		PMD_SECT_AP_WRITE | \
    453		PMD_SECT_AP_READ
    454	initfn	__arm1026_setup, __arm1026_proc_info
    455	.long	cpu_arch_name
    456	.long	cpu_elf_name
    457	.long	HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP|HWCAP_JAVA
    458	.long	cpu_arm1026_name
    459	.long	arm1026_processor_functions
    460	.long	v4wbi_tlb_fns
    461	.long	v4wb_user_fns
    462	.long	arm1026_cache_fns
    463	.size	__arm1026_proc_info, . - __arm1026_proc_info