Subject: WFI idle for ARM926EJ-S/ARM1026EJ-S
To: None <port-arm@netbsd.org>
From: Todd Allan <todd_allan@picovex.com>
List: port-arm
Date: 08/07/2006 15:02:20
This is a multi-part message in MIME format.
--------------050406090507030404070901
Content-Type: text/plain; charset=ISO-8859-1; format=flowed
Content-Transfer-Encoding: 7bit
The attached patch adds a powersave idle for ARM926EJS/ARM1026EJS,
comprised of a Wait For Interrupt operation as described in the ARM ARM:
write SBZ data to CP15 coprocessor register 7, CRm=c0, opcode2=0.
This should work on some other ARM processors as well, and the patch
implements it in a generic cpufunc, but some ARM implementations,
notably including XScale, do this differently. The patch has only been
tested on a 926EJ-S; it enables WFI on the 926EJ-S and on the 10EJ-S,
the TRM for which indicates that it implements this operation. This
patch applies on top of a patch from Scott Allan previously sent
07/31/2006 in thread "Patch to add support for ARM9E".
Any suggestions appreciated, thanks.
--------------050406090507030404070901
Content-Type: text/x-patch;
name="armv5_wfi_idle.patch"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
filename="armv5_wfi_idle.patch"
Index: netbsd_quilt/src/sys/arch/arm/arm/cpufunc.c
===================================================================
--- netbsd_quilt.orig/src/sys/arch/arm/arm/cpufunc.c
+++ netbsd_quilt/src/sys/arch/arm/arm/cpufunc.c
@@ -501,7 +501,7 @@ struct cpu_functions armv5_ec_cpufuncs =
cpufunc_nullop, /* flush_brnchtgt_C */
(void *)cpufunc_nullop, /* flush_brnchtgt_E */
- (void *)cpufunc_nullop, /* sleep */
+ cpufunc_sleep, /* sleep */
/* Soft functions */
@@ -1108,6 +1108,10 @@ set_cpufuncs()
cpu_reset_needs_v4_MMU_disable = 1; /* V4 or higher */
get_cachetype_cp15();
pmap_pte_init_generic();
+
+ /* Use powersave on this CPU. */
+ cpu_do_powersave = 1;
+
return 0;
}
#endif /* CPU_ARM9E || CPU_ARM10 */
Index: netbsd_quilt/src/sys/arch/arm/arm/cpufunc_asm.S
===================================================================
--- netbsd_quilt.orig/src/sys/arch/arm/arm/cpufunc_asm.S
+++ netbsd_quilt/src/sys/arch/arm/arm/cpufunc_asm.S
@@ -148,3 +148,12 @@ ENTRY(get_pc_str_offset)
ldr r0, [sp]
sub r0, r0, r1
ldmdb fp, {fp, sp, pc}
+
+/*
+ * WFI low-power idle per ARM ARM.
+ */
+
+ENTRY(cpufunc_sleep)
+ mov r0, #0x0
+ mcr p15, 0, r0, c7, c0, 4
+ mov pc, lr
Index: netbsd_quilt/src/sys/arch/arm/include/cpufunc.h
===================================================================
--- netbsd_quilt.orig/src/sys/arch/arm/include/cpufunc.h
+++ netbsd_quilt/src/sys/arch/arm/include/cpufunc.h
@@ -209,6 +209,7 @@ u_int cpufunc_control __P((u_int, u_int
void cpufunc_domains __P((u_int));
u_int cpufunc_faultstatus __P((void));
u_int cpufunc_faultaddress __P((void));
+void cpufunc_sleep __P((int));
#ifdef CPU_ARM3
u_int arm3_control __P((u_int, u_int));
--------------050406090507030404070901--