1129198Scognet/*	$NetBSD: cpufunc_asm_sa11x0.S,v 1.3 2002/08/17 16:36:32 thorpej Exp $	*/
2129198Scognet
3139735Simp/*-
4129198Scognet * Copyright (c) 2002 Wasabi Systems, Inc.
5129198Scognet * All rights reserved.
6129198Scognet *
7129198Scognet * Written by Jason R. Thorpe for Wasabi Systems, Inc.
8129198Scognet *
9129198Scognet * Redistribution and use in source and binary forms, with or without
10129198Scognet * modification, are permitted provided that the following conditions
11129198Scognet * are met:
12129198Scognet * 1. Redistributions of source code must retain the above copyright
13129198Scognet *    notice, this list of conditions and the following disclaimer.
14129198Scognet * 2. Redistributions in binary form must reproduce the above copyright
15129198Scognet *    notice, this list of conditions and the following disclaimer in the
16129198Scognet *    documentation and/or other materials provided with the distribution.
17129198Scognet * 3. All advertising materials mentioning features or use of this software
18129198Scognet *    must display the following acknowledgement:
19129198Scognet *	This product includes software developed for the NetBSD Project by
20129198Scognet *	Wasabi Systems, Inc.
21129198Scognet * 4. The name of Wasabi Systems, Inc. may not be used to endorse
22129198Scognet *    or promote products derived from this software without specific prior
23129198Scognet *    written permission.
24129198Scognet *
25129198Scognet * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND
26129198Scognet * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
27129198Scognet * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
28129198Scognet * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL WASABI SYSTEMS, INC
29129198Scognet * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
30129198Scognet * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
31129198Scognet * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
32129198Scognet * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
33129198Scognet * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
34129198Scognet * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
35129198Scognet * POSSIBILITY OF SUCH DAMAGE.
36129198Scognet *
37129198Scognet */
38129198Scognet
39129198Scognet#include <machine/asm.h>
40129198Scognet__FBSDID("$FreeBSD$");
41129198Scognet
42129198Scognet	.data
43129198Scognet	.global	_C_LABEL(sa11x0_idle_mem)
44129198Scognet_C_LABEL(sa11x0_idle_mem):
45129198Scognet	.word	0
46129198Scognet
47129198Scognet	.text
48129198Scognet
49129198Scognet	.align	5
50129198Scognet
51129198Scognet	/* We're now 32-byte aligned */
52129198Scognet
53129198Scognet.Lsa11x0_idle_mem:
54129198Scognet	.word	_C_LABEL(sa11x0_idle_mem)				/* 1 */
55129198Scognet
56129198Scognet/*
57129198Scognet * sa11x0_cpusleep
58129198Scognet *
59129198Scognet * This is called when there is nothing on any of the run queues.
60129198Scognet * We go into IDLE mode so that any IRQ or FIQ will awaken us.
61129198Scognet */
62129198ScognetENTRY(sa11x0_cpu_sleep)
63129198Scognet	ldr	r1, .Lsa11x0_idle_mem	/* get address of... */		/* 2 */
64129198Scognet	nop								/* 3 */
65129198Scognet	ldr	r1, [r1]		/* ...non-cacheable page */	/* 4 */
66129198Scognet	nop								/* 5 */
67129198Scognet
68129198Scognet	/*
69129198Scognet	 * SA-1110 manual, 9.5.2.1 (Entering Idle Mode) says that
70129198Scognet	 * to enter idle mode:
71129198Scognet	 *
72129198Scognet	 *	* Disable clock switching
73129198Scognet	 *	* Issue load from non-cacheable address
74129198Scognet	 *	* Issue "wait for interrupt"
75129198Scognet	 *
76129198Scognet	 * The 3-insn sequence must reside in the first 3 words
77129198Scognet	 * of a cache line.
78129198Scognet	 *
79129198Scognet	 * We must disable interrupts in the CPSR so that we can
80129198Scognet	 * re-enable clock switching before servicing interrupts.
81129198Scognet	 */
82129198Scognet
83129198Scognet	mrs	r3, cpsr_all						/* 6 */
84129198Scognet	orr	r2, r3, #(I32_bit|F32_bit)				/* 7 */
85129198Scognet	msr	cpsr_all, r2						/* 8 */
86129198Scognet
87129198Scognet	/* We're now 32-byte aligned */
88129198Scognet
89129198Scognet	mcr	p15, 0, r0, c15, c2, 2	/* disable clock switching */
90129198Scognet	ldr	r0, [r1]		/* load from non-cacheable address */
91129198Scognet	mcr	p15, 0, r0, c15, c8, 2	/* wait for interrupt */
92129198Scognet
93129198Scognet	mcr	p15, 0, r0, c15, c1, 2	/* re-enable clock switching */
94129198Scognet
95129198Scognet	/* Restore interrupts (which will cause them to be serviced). */
96129198Scognet	msr	cpsr_all, r3
97137463Scognet	RET
98248361SandrewEND(sa11x0_cpu_sleep)
99129198Scognet
100129198Scognet/*
101129198Scognet * This function is the same as sa110_context_switch for now, the plan
102129198Scognet * is to make use of the process id register to avoid cache flushes.
103129198Scognet */
104129198ScognetENTRY(sa11x0_context_switch)
105129198Scognet	/*
106129198Scognet	 * CF_CACHE_PURGE_ID will *ALWAYS* be called prior to this.
107129198Scognet	 * Thus the data cache will contain only kernel data and the
108129198Scognet	 * instruction cache will contain only kernel code, and all
109129198Scognet	 * kernel mappings are shared by all processes.
110129198Scognet	 */
111129198Scognet
112129198Scognet	/* Write the TTB */
113129198Scognet	mcr	p15, 0, r0, c2, c0, 0
114129198Scognet
115129198Scognet	/* If we have updated the TTB we must flush the TLB */
116129198Scognet	mcr	p15, 0, r0, c8, c7, 0	/* flush the I+D tlb */
117129198Scognet
118129198Scognet	/* Make sure that pipeline is emptied */
119129198Scognet	mov	r0, r0
120129198Scognet	mov	r0, r0
121137463Scognet	RET
122248361SandrewEND(sa11x0_context_switch)
123129198Scognet
124129198ScognetENTRY(sa11x0_drain_readbuf)
125129198Scognet	mcr	p15, 0, r0, c9, c0, 0		/* drain read buffer */
126137463Scognet	RET
127248361SandrewEND(sa11x0_drain_readbuf)
128248361Sandrew
129