Annotation of sys/arch/mvme88k/mvme88k/m88110.c, Revision 1.1.1.1
1.1 nbrk 1: /* $OpenBSD: m88110.c,v 1.38 2007/02/11 12:49:38 miod Exp $ */
2: /*
3: * Copyright (c) 1998 Steve Murphree, Jr.
4: * All rights reserved.
5: *
6: * Redistribution and use in source and binary forms, with or without
7: * modification, are permitted provided that the following conditions
8: * are met:
9: * 1. Redistributions of source code must retain the above copyright
10: * notice, this list of conditions and the following disclaimer.
11: * 2. Redistributions in binary form must reproduce the above copyright
12: * notice, this list of conditions and the following disclaimer in the
13: * documentation and/or other materials provided with the distribution.
14: * 3. All advertising materials mentioning features or use of this software
15: * must display the following acknowledgement:
16: * This product includes software developed by Nivas Madhur.
17: * 4. The name of the author may not be used to endorse or promote products
18: * derived from this software without specific prior written permission
19: *
20: * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
21: * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
22: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
23: * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
24: * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
25: * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26: * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27: * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28: * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
29: * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30: *
31: */
32:
33: /*
34: * Mach Operating System
35: * Copyright (c) 1993-1991 Carnegie Mellon University
36: * Copyright (c) 1991 OMRON Corporation
37: * All Rights Reserved.
38: *
39: * Permission to use, copy, modify and distribute this software and its
40: * documentation is hereby granted, provided that both the copyright
41: * notice and this permission notice appear in all copies of the
42: * software, derivative works or modified versions, and any portions
43: * thereof, and that both notices appear in supporting documentation.
44: *
45: * CARNEGIE MELLON AND OMRON ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS IS"
46: * CONDITION. CARNEGIE MELLON AND OMRON DISCLAIM ANY LIABILITY OF ANY KIND
47: * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
48: *
49: * Carnegie Mellon requests users of this software to return to
50: *
51: * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
52: * School of Computer Science
53: * Carnegie Mellon University
54: * Pittsburgh PA 15213-3890
55: *
56: * any improvements or extensions that they make and grant Carnegie the
57: * rights to redistribute these changes.
58: */
59:
60: #include <sys/param.h>
61: #include <sys/systm.h>
62:
63: #include <uvm/uvm_extern.h>
64:
65: #include <machine/asm_macro.h>
66: #include <machine/cmmu.h>
67: #include <machine/cpu.h>
68: #include <machine/lock.h>
69: #include <machine/m88110.h>
70: #include <machine/m88410.h>
71: #include <machine/psl.h>
72:
73: #include <mvme88k/dev/busswreg.h>
74:
75: cpuid_t m88110_init(void);
76: void m88110_setup_board_config(void);
77: void m88110_cpu_configuration_print(int);
78: void m88110_shutdown(void);
79: cpuid_t m88110_cpu_number(void);
80: void m88110_set_sapr(cpuid_t, apr_t);
81: void m88110_set_uapr(apr_t);
82: void m88110_flush_tlb(cpuid_t, unsigned, vaddr_t, u_int);
83: void m88110_flush_cache(cpuid_t, paddr_t, psize_t);
84: void m88110_flush_inst_cache(cpuid_t, paddr_t, psize_t);
85: void m88110_flush_data_page(cpuid_t, paddr_t);
86: void m88110_dma_cachectl(pmap_t, vaddr_t, vsize_t, int);
87: void m88110_dma_cachectl_pa(paddr_t, psize_t, int);
88: void m88110_initialize_cpu(cpuid_t);
89:
90: /* This is the function table for the MC88110 built-in CMMUs */
91: struct cmmu_p cmmu88110 = {
92: m88110_init,
93: m88110_setup_board_config,
94: m88110_cpu_configuration_print,
95: m88110_shutdown,
96: m88110_cpu_number,
97: m88110_set_sapr,
98: m88110_set_uapr,
99: m88110_flush_tlb,
100: m88110_flush_cache,
101: m88110_flush_inst_cache,
102: m88110_flush_data_page,
103: m88110_dma_cachectl,
104: m88110_dma_cachectl_pa,
105: #ifdef MULTIPROCESSOR
106: m88110_initialize_cpu,
107: #endif
108: };
109:
110: void patc_clear(void);
111: void m88110_cmmu_sync_cache(paddr_t, psize_t);
112: void m88110_cmmu_sync_inval_cache(paddr_t, psize_t);
113: void m88110_cmmu_inval_cache(paddr_t, psize_t);
114:
115: void
116: patc_clear(void)
117: {
118: int i;
119:
120: for (i = 0; i < 32; i++) {
121: set_dir(i << 5);
122: set_dppu(0);
123: set_dppl(0);
124:
125: set_iir(i << 5);
126: set_ippu(0);
127: set_ippl(0);
128: }
129: }
130:
131: void
132: m88110_setup_board_config(void)
133: {
134: #ifdef MULTIPROCESSOR
135: max_cpus = 2;
136: #else
137: max_cpus = 1;
138: #endif
139: }
140:
141: /*
142: * Should only be called after the calling cpus knows its cpu
143: * number and master/slave status . Should be called first
144: * by the master, before the slaves are started.
145: */
146: void
147: m88110_cpu_configuration_print(int master)
148: {
149: int pid = get_cpu_pid();
150: int proctype = (pid & PID_ARN) >> ARN_SHIFT;
151: int procvers = (pid & PID_VN) >> VN_SHIFT;
152: int cpu = cpu_number();
153:
154: printf("cpu%d: ", cpu);
155: switch (proctype) {
156: default:
157: printf("unknown model arch 0x%x version 0x%x",
158: proctype, procvers);
159: break;
160: case ARN_88110:
161: printf("M88110 version 0x%x", procvers);
162: if (mc88410_present())
163: printf(", external M88410 cache controller");
164: break;
165: }
166: printf("\n");
167: }
168:
169: /*
170: * CMMU initialization routine
171: */
172: cpuid_t
173: m88110_init(void)
174: {
175: cpuid_t cpu;
176:
177: cpu = m88110_cpu_number();
178: m88110_initialize_cpu(cpu);
179: return (cpu);
180: }
181:
182: void
183: m88110_initialize_cpu(cpuid_t cpu)
184: {
185: int i;
186:
187: /* clear BATCs */
188: for (i = 0; i < 8; i++) {
189: set_dir(i);
190: set_dbp(0);
191: set_iir(i);
192: set_ibp(0);
193: }
194:
195: /* clear PATCs */
196: patc_clear();
197:
198: /* Do NOT enable ICTL_PREN (branch prediction) */
199: set_ictl(BATC_32M
200: | CMMU_ICTL_DID /* Double instruction disable */
201: | CMMU_ICTL_MEN
202: | CMMU_ICTL_CEN
203: | CMMU_ICTL_BEN
204: | CMMU_ICTL_HTEN);
205:
206: set_dctl(BATC_32M
207: | CMMU_DCTL_RSVD1 /* Data Matching Disable */
208: | CMMU_DCTL_MEN
209: | CMMU_DCTL_CEN
210: | CMMU_DCTL_SEN
211: | CMMU_DCTL_ADS
212: | CMMU_DCTL_HTEN);
213:
214: mc88110_inval_inst(); /* clear instruction cache & TIC */
215: mc88110_inval_data(); /* clear data cache */
216: if (mc88410_present())
217: mc88410_inval(); /* clear external data cache */
218:
219: set_dcmd(CMMU_DCMD_INV_SATC); /* invalidate ATCs */
220:
221: set_isr(0);
222: set_dsr(0);
223: }
224:
225: /*
226: * Just before poweroff or reset....
227: */
228: void
229: m88110_shutdown(void)
230: {
231: }
232:
233: cpuid_t
234: m88110_cpu_number(void)
235: {
236: u_int16_t gcsr;
237:
238: gcsr = *(volatile u_int16_t *)(BS_BASE + BS_GCSR);
239:
240: return ((gcsr & BS_GCSR_CPUID) != 0 ? 1 : 0);
241: }
242:
243: void
244: m88110_set_sapr(cpuid_t cpu, apr_t ap)
245: {
246: u_int ictl, dctl;
247:
248: CMMU_LOCK;
249:
250: set_icmd(CMMU_ICMD_INV_SATC);
251: set_dcmd(CMMU_DCMD_INV_SATC);
252:
253: ictl = get_ictl();
254: dctl = get_dctl();
255:
256: /* disable translation */
257: set_ictl((ictl & ~CMMU_ICTL_MEN));
258: set_dctl((dctl & ~CMMU_DCTL_MEN));
259:
260: set_isap(ap);
261: set_dsap(ap);
262:
263: patc_clear();
264:
265: set_icmd(CMMU_ICMD_INV_UATC);
266: set_icmd(CMMU_ICMD_INV_SATC);
267: set_dcmd(CMMU_DCMD_INV_UATC);
268: set_dcmd(CMMU_DCMD_INV_SATC);
269:
270: /* restore MMU settings */
271: set_ictl(ictl);
272: set_dctl(dctl);
273:
274: CMMU_UNLOCK;
275: }
276:
277: void
278: m88110_set_uapr(apr_t ap)
279: {
280: CMMU_LOCK;
281: set_iuap(ap);
282: set_duap(ap);
283:
284: set_icmd(CMMU_ICMD_INV_UATC);
285: set_dcmd(CMMU_DCMD_INV_UATC);
286:
287: /* We need to at least invalidate the TIC, as it is va-addressed */
288: mc88110_inval_inst();
289: CMMU_UNLOCK;
290: }
291:
292: /*
293: * Functions that invalidate TLB entries.
294: */
295:
296: /*
297: * flush any tlb
298: */
299: void
300: m88110_flush_tlb(cpuid_t cpu, unsigned kernel, vaddr_t vaddr, u_int count)
301: {
302: u_int32_t psr;
303:
304: disable_interrupt(psr);
305:
306: CMMU_LOCK;
307: if (kernel) {
308: set_icmd(CMMU_ICMD_INV_SATC);
309: set_dcmd(CMMU_DCMD_INV_SATC);
310: } else {
311: set_icmd(CMMU_ICMD_INV_UATC);
312: set_dcmd(CMMU_DCMD_INV_UATC);
313: }
314: CMMU_UNLOCK;
315:
316: set_psr(psr);
317: }
318:
319: /*
320: * Functions that invalidate caches.
321: *
322: * Cache invalidates require physical addresses. Care must be exercised when
323: * using segment invalidates. This implies that the starting physical address
324: * plus the segment length should be invalidated. A typical mistake is to
325: * extract the first physical page of a segment from a virtual address, and
326: * then expecting to invalidate when the pages are not physically contiguous.
327: *
328: * We don't push Instruction Caches prior to invalidate because they are not
329: * snooped and never modified (I guess it doesn't matter then which form
330: * of the command we use then).
331: */
332:
333: /*
334: * Care must be taken to avoid flushing the data cache when
335: * the data cache is not on! From the 0F92L Errata Documentation
336: * Package, Version 1.1
337: */
338:
339: /*
340: * XXX These routines are really suboptimal because they invalidate
341: * way too much...
342: * Improve them once the 197 support is really working...
343: */
344:
345: /*
346: * flush both Instruction and Data caches
347: */
348: void
349: m88110_flush_cache(cpuid_t cpu, paddr_t pa, psize_t size)
350: {
351: u_int32_t psr;
352:
353: disable_interrupt(psr);
354:
355: mc88110_inval_inst();
356: mc88110_flush_data();
357: if (mc88410_present())
358: mc88410_flush();
359: set_psr(psr);
360: }
361:
362: /*
363: * flush Instruction caches
364: */
365: void
366: m88110_flush_inst_cache(cpuid_t cpu, paddr_t pa, psize_t size)
367: {
368: u_int32_t psr;
369:
370: disable_interrupt(psr);
371:
372: mc88110_inval_inst();
373: set_psr(psr);
374: }
375:
376: /*
377: * flush data cache
378: */
379: void
380: m88110_flush_data_page(cpuid_t cpu, paddr_t pa)
381: {
382: u_int32_t psr;
383:
384: disable_interrupt(psr);
385:
386: mc88110_flush_data();
387: if (mc88410_present())
388: mc88410_flush();
389: set_psr(psr);
390: }
391:
392: /*
393: * sync dcache (and icache too)
394: */
395: void
396: m88110_cmmu_sync_cache(paddr_t pa, psize_t size)
397: {
398: u_int32_t psr;
399:
400: disable_interrupt(psr);
401:
402: mc88110_inval_inst();
403: mc88110_flush_data();
404: if (mc88410_present())
405: mc88410_flush();
406: set_psr(psr);
407: }
408:
409: void
410: m88110_cmmu_sync_inval_cache(paddr_t pa, psize_t size)
411: {
412: u_int32_t psr;
413:
414: disable_interrupt(psr);
415:
416: mc88110_sync_data();
417: if (mc88410_present())
418: mc88410_sync();
419: set_psr(psr);
420: }
421:
422: void
423: m88110_cmmu_inval_cache(paddr_t pa, psize_t size)
424: {
425: u_int32_t psr;
426:
427: disable_interrupt(psr);
428:
429: mc88110_inval_inst();
430: mc88110_inval_data();
431: if (mc88410_present())
432: mc88410_inval();
433: set_psr(psr);
434: }
435:
436: void
437: m88110_dma_cachectl(pmap_t pmap, vaddr_t va, vsize_t size, int op)
438: {
439: paddr_t pa;
440:
441: if (pmap_extract(pmap, va, &pa) == FALSE) {
442: #ifdef DIAGNOSTIC
443: printf("cachectl: pmap_extract(%p, %p) failed\n", pmap, va);
444: #endif
445: pa = 0;
446: size = ~0;
447: }
448:
449: switch (op) {
450: case DMA_CACHE_SYNC:
451: m88110_cmmu_sync_cache(pa, size);
452: break;
453: case DMA_CACHE_SYNC_INVAL:
454: m88110_cmmu_sync_inval_cache(pa, size);
455: break;
456: default:
457: m88110_cmmu_inval_cache(pa, size);
458: break;
459: }
460: }
461:
462: void
463: m88110_dma_cachectl_pa(paddr_t pa, psize_t size, int op)
464: {
465: switch (op) {
466: case DMA_CACHE_SYNC:
467: m88110_cmmu_sync_cache(pa, size);
468: break;
469: case DMA_CACHE_SYNC_INVAL:
470: m88110_cmmu_sync_inval_cache(pa, size);
471: break;
472: default:
473: m88110_cmmu_inval_cache(pa, size);
474: break;
475: }
476: }
CVSweb