patch-2.2.18 linux/arch/arm/mm/proc-sa110.S

Next file: linux/arch/arm/nwfpe/ARM-gcc.h
Previous file: linux/arch/arm/mm/proc-arm6,7.S
Back to the patch index
Back to the overall index

diff -u --new-file --recursive --exclude-from /usr/src/exclude v2.2.17/arch/arm/mm/proc-sa110.S linux/arch/arm/mm/proc-sa110.S
@@ -1,13 +1,14 @@
 /*
- * linux/arch/arm/mm/sa110.S: MMU functions for SA110
+ * linux/arch/arm/mm/proc-sa110.S: MMU functions for SA110
  *
- * (C) 1997 Russell King
+ * (C) 1997-1999 Russell King
  *
  * These are the low level assembler for performing cache and TLB
- * functions on the sa110.
+ * functions on the StrongARM-110.
  */
 #include <linux/linkage.h>
 #include <asm/assembler.h>
+#include <asm/procinfo.h>
 #include <asm/hardware.h>
 #include "../lib/constants.h"
 
@@ -15,6 +16,7 @@
  * is larger than this, then we flush the whole cache
  */
 #define MAX_AREA_SIZE	32768
+#define FLUSH_OFFSET	32768
 
 		.data
 Lclean_switch:	.long	0
@@ -29,12 +31,12 @@
 		mov	r2, #1
 _sa110_flush_cache_all_r2:
 		ldr	r3, =Lclean_switch
+		ldr	ip, =FLUSH_BASE
 		ldr	r1, [r3]
 		ands	r1, r1, #1
 		eor	r1, r1, #1
 		str	r1, [r3]
-		ldr	ip, =FLUSH_BASE
-		addne	ip, ip, #32768
+		addne	ip, ip, #FLUSH_OFFSET
 		add	r1, ip, #16384			@ only necessary for 16k
 1:		ldr	r3, [ip], #32
 		teq	r1, ip
@@ -152,16 +154,17 @@
 _sa110_flush_ram_page:
 		mov	r1, #4096
 1:		mcr	p15, 0, r0, c7, c10, 1		@ clean D entry
-		mcr	p15, 0, r0, c7, c6, 1		@ flush D entry
 		add	r0, r0, #32
 		mcr	p15, 0, r0, c7, c10, 1		@ clean D entry
-		mcr	p15, 0, r0, c7, c6, 1		@ flush D entry
 		add	r0, r0, #32
-		subs	r1, r1, #64
+		mcr	p15, 0, r0, c7, c10, 1		@ clean D entry
+		add	r0, r0, #32
+		mcr	p15, 0, r0, c7, c10, 1		@ clean D entry
+		add	r0, r0, #32
+		subs	r1, r1, #128
 		bne	1b
 		mov	r0, #0
 		mcr	p15, 0, r0, c7, c10, 4		@ drain WB
-		mcr	p15, 0, r0, c7, c5, 0		@ flush I cache
 		mov	pc, lr
 
 /*
@@ -179,7 +182,7 @@
  * Function: sa110_flush_tlb_area (unsigned long address, unsigned long end, int flags)
  * Params  : address	Area start address
  *	   : end	Area end address
- *	   : flags	b0 = I cache as well
+ *	   : flags	b0 = I-TLB as well
  * Purpose : flush a TLB entry
  */
 		.align	5
@@ -193,7 +196,7 @@
 		mcrlt	p15, 0, r0, c8, c6, 1		@ flush D TLB entry
 		addlt	r0, r0, #4096
 		blt	1b
-		tst	r2, #1
+		teq	r2, #0
 		mcrne	p15, 0, r3, c8, c5, 0		@ flush I TLB
 		mov	pc, lr
 
@@ -220,18 +223,15 @@
  */
 		.align	5
 _sa110_switch_to:
-		stmfd	sp!, {r4 - r9, fp, lr}		@ Store most regs on stack
+		stmfd	sp!, {r4 - r10, fp, lr}		@ Store most regs on stack
 		mrs	ip, cpsr
 		stmfd	sp!, {ip}			@ Save cpsr_SVC
 		ldr	r2, [r0, #TSS_MEMMAP]		@ Get old page tables
 		str	sp, [r0, #TSS_SAVE]		@ Save sp_SVC
 		ldr	sp, [r1, #TSS_SAVE]		@ Get saved sp_SVC
-		ldr	r4, [r1, #TSK_ADDR_LIMIT]
-		teq	r4, #0
-		moveq	r4, #DOM_KERNELDOMAIN
-		movne	r4, #DOM_USERDOMAIN
-		mcr	p15, 0, r4, c3, c0		@ Set segment
+		ldr	r5, [r1, #TSS_DOMAIN]
 		ldr	r4, [r1, #TSS_MEMMAP]		@ Page table pointer
+		mcr	p15, 0, r5, c3, c0		@ Set segment
 /*
  * Flushing the cache is nightmarishly slow, so we take any excuse
  * to get out of it.  If the old page table is the same as the new,
@@ -247,7 +247,7 @@
 		eor	r2, r2, #1
 		str	r2, [r3]
 		ldr	r2, =FLUSH_BASE
-		addne	r2, r2, #32768
+		addne	r2, r2, #FLUSH_OFFSET
 		add	r1, r2, #16384			@ only necessary for 16k
 1:		ldr	r3, [r2], #32
 		teq	r1, r2
@@ -259,7 +259,7 @@
 		mcr	p15, 0, r1, c8, c7, 0		@ flush TLBs
 2:		ldmfd	sp!, {ip}
 		msr	spsr, ip			@ Save tasks CPSR into SPSR for this return
-		ldmfd	sp!, {r4 - r9, fp, pc}^		@ Load all regs saved previously
+		ldmfd	sp!, {r4 - r10, fp, pc}^	@ Load all regs saved previously
 
 /*
  * Function: sa110_data_abort ()
@@ -288,7 +288,8 @@
  */
 		.align	5
 _sa110_set_pmd:	str	r1, [r0]
-		mcr	p15, 0, r0, c7, c10, 1		@ clean D entry	 (drain is done by TLB fns)
+		mcr	p15, 0, r0, c7, c10, 1		@ clean D entry
+		mcr	p15, 0, r0, c7, c10, 4		@ drain WB
 		mov	pc, lr
 
 /*
@@ -317,7 +318,8 @@
 
 		str	r2, [r0]			@ hardware version
 		mov	r0, r0
-		mcr	p15, 0, r0, c7, c10, 1		@ clean D entry	 (drain is done by TLB fns)
+		mcr	p15, 0, r0, c7, c10, 1		@ clean D entry
+		mcr	p15, 0, r0, c7, c10, 4		@ drain WB
 		mov	pc, lr
 
 /*
@@ -330,36 +332,83 @@
 		mrs	ip, cpsr
 		bic	ip, ip, #F_BIT
 		msr	cpsr, ip
+		mov	pc, lr
 
 _sa110_proc_init:
+		mov	r0, #0
+		mcr	p15, 0, r0, c15, c1, 2		@ Enable clock switching
+		mov	pc, lr
+
 _sa110_proc_fin:
+		stmfd	sp!, {r1, lr}
+		mrs	r0, cpsr
+		orr	r0, r0, #F_BIT | I_BIT
+		msr	cpsr, r0
+		bl	_sa110_flush_cache_all		@ clean caches
+		mov	r0, #0
+		mcr	p15, 0, r0, c15, c2, 2		@ Disable clock switching
+		mrc	p15, 0, r0, c1, c0, 0
+		bic	r0, r0, #0x1000			@ ...i............
+		bic	r0, r0, #0x000e			@ ............wca.
+		mcr	p15, 0, r0, c1, c0, 0		@ disable caches
+		ldmfd	sp!, {r1, pc}
+
+		.align	5
+ENTRY(cpu_sa110_do_idle)
+		mov	r0, #0
+		mcr	p15, 0, r0, c15, c2, 2		@ Disable clock switching
+		ldr	r1, =FLUSH_BASE+FLUSH_OFFSET*2	@ load from uncacheable loc
+		ldr	r1, [r1, #0]
+		b	1f
+
+		.align	5
+1:		mcr	p15, 0, r0, c15, c8, 2		@ Wait for interrupt
+		mcr	p15, 0, r0, c15, c1, 2		@ Enable clock switching
 		mov	pc, lr
 
 /*
  * Function: sa110_reset
  * Notes   : This sets up everything for a reset
  */
-_sa110_reset:	mrs	r1, cpsr
-		orr	r1, r1, #F_BIT | I_BIT
-		msr	cpsr, r1
-		stmfd	sp!, {r1, lr}
-		mov	r2, #1
-		bl	_sa110_flush_cache_all
-		bl	_sa110_flush_tlb_all
+_sa110_reset:
+		mov	ip, #0
 		mcr	p15, 0, ip, c7, c7, 0		@ flush I,D caches
+		mcr	p15, 0, ip, c7, c10, 4		@ drain WB
+		mcr	p15, 0, ip, c8, c7, 0		@ flush I & D tlbs
 		mrc	p15, 0, r0, c1, c0, 0		@ ctrl register
-		bic	r0, r0, #0x1800
-		bic	r0, r0, #0x000f
-		ldmfd	sp!, {r1, pc}
+		bic	r0, r0, #0x000f			@ ............wcam
+		bic	r0, r0, #0x1100			@ ...i...s........
+		mcr	p15, 0, ip, c1, c0, 0
+		mov	pc, r0
 /*
  * Purpose : Function pointers used to access above functions - all calls
  *	     come through these
  */
-_sa110_name:	.ascii	"sa110\0"
+
+cpu_manu_name:	.asciz	"Intel"
+ENTRY(cpu_sa110_name)
+		.asciz	"StrongARM-110"
 		.align
 
-ENTRY(sa110_processor_functions)
-		.word	_sa110_name			@  0
+		.section ".text.init", #alloc, #execinstr
+
+__sa110_setup:	mov	r0, #0
+		mcr	p15, 0, r0, c7, c7		@ flush I,D caches on v4
+		mcr	p15, 0, r0, c7, c10, 4		@ drain write buffer on v4
+		mcr	p15, 0, r0, c8, c7		@ flush I,D TLBs on v4
+		mcr	p15, 0, r4, c2, c0		@ load page table pointer
+		mov	r0, #0x1f			@ Domains 0, 1 = client
+		mcr	p15, 0, r0, c3, c0		@ load domain access register
+		mrc	p15, 0, r0, c1, c0		@ get control register v4
+		bic	r0, r0, #0x0e00			@ ....??r.........
+		bic	r0, r0, #0x0002			@ ..............a.
+		orr	r0, r0, #0x003d			@ ..........DPWC.M
+		orr	r0, r0, #0x1100			@ ...I...S........
+		mov	pc, lr
+
+		.type	sa110_processor_functions, #object
+sa110_processor_functions:
+		.word	cpu_sa110_name			@  0
 		.word	_sa110_switch_to		@  4
 		.word	_sa110_data_abort		@  8
 		.word	_sa110_check_bugs		@ 12
@@ -381,3 +430,38 @@
 
 		.word	_sa110_cache_wback_area		@ 68
 		.word	_sa110_cache_purge_area		@ 72
+		.word	0
+		.word	cpu_sa110_do_idle
+		.size	sa110_processor_functions, . - sa110_processor_functions
+
+		.type	cpu_sa110_info, #object
+cpu_sa110_info:
+		.long	cpu_manu_name
+		.long	cpu_sa110_name
+		.size	cpu_sa110_info, . - cpu_sa110_info
+
+		.type	cpu_arch_name, #object
+cpu_arch_name:	.asciz	"armv4"
+		.size	cpu_arch_name, . - cpu_arch_name
+
+		.type	cpu_elf_name, #object
+cpu_elf_name:	.asciz	"v4"
+		.size	cpu_elf_name, . - cpu_elf_name
+		.align
+
+		.section ".proc.info", #alloc, #execinstr
+
+		.type	__sa110_proc_info,#object
+__sa110_proc_info:
+		.long	0x4401a100
+		.long	0xfffffff0
+		.long	0x00000c02
+		b	__sa110_setup
+		.long	cpu_arch_name
+		.long	cpu_elf_name
+		.long	HWCAP_SWP | HWCAP_HALF | HWCAP_26BIT
+		.long	cpu_sa110_info
+		.long	sa110_processor_functions
+		.size	__sa110_proc_info, . - __sa110_proc_info
+
+

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)