Annotation of sys/arch/aviion/aviion/locore.S, Revision 1.1.1.1
1.1 nbrk 1: /* $OpenBSD: locore.S,v 1.3 2006/05/20 22:40:43 miod Exp $ */
2: /*
3: * Copyright (c) 2005, Miodrag Vallat.
4: * Copyright (c) 1998 Steve Murphree, Jr.
5: * Copyright (c) 1996 Nivas Madhur
6: * All rights reserved.
7: *
8: * Redistribution and use in source and binary forms, with or without
9: * modification, are permitted provided that the following conditions
10: * are met:
11: * 1. Redistributions of source code must retain the above copyright
12: * notice, this list of conditions and the following disclaimer.
13: * 2. Redistributions in binary form must reproduce the above copyright
14: * notice, this list of conditions and the following disclaimer in the
15: * documentation and/or other materials provided with the distribution.
16: * 3. All advertising materials mentioning features or use of this software
17: * must display the following acknowledgement:
18: * This product includes software developed by Nivas Madhur.
19: * 4. The name of the author may not be used to endorse or promote products
20: * derived from this software without specific prior written permission
21: *
22: * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
23: * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
24: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
25: * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
26: * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
27: * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28: * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29: * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30: * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
31: * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32: *
33: */
34: /*
35: * Mach Operating System
36: * Copyright (c) 1993-1991 Carnegie Mellon University
37: * Copyright (c) 1991 OMRON Corporation
38: * All Rights Reserved.
39: *
40: * Permission to use, copy, modify and distribute this software and its
41: * documentation is hereby granted, provided that both the copyright
42: * notice and this permission notice appear in all copies of the
43: * software, derivative works or modified versions, and any portions
44: * thereof, and that both notices appear in supporting documentation.
45: *
46: * CARNEGIE MELLON AND OMRON ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS IS"
47: * CONDITION. CARNEGIE MELLON AND OMRON DISCLAIM ANY LIABILITY OF ANY KIND
48: * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
49: *
50: * Carnegie Mellon requests users of this software to return to
51: *
52: * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
53: * School of Computer Science
54: * Carnegie Mellon University
55: * Pittsburgh PA 15213-3890
56: *
57: * any improvements or extensions that they make and grant Carnegie the
58: * rights to redistribute these changes.
59: */
60:
61: #include "assym.h"
62: #include "ksyms.h"
63:
64: #include <machine/asm.h>
65: #include <machine/m88100.h>
66: #include <machine/param.h>
67: #include <machine/psl.h>
68: #include <machine/trap.h>
69: #include <machine/vmparam.h>
70:
71: #define SYM_MAGIC 0x6274ef2e
72:
73: text
74:
75: GLOBAL(kernelstart)
76: GLOBAL(kernel_text)
77: ASGLOBAL(start)
78: /*
79: * A few identical jump instructions to make sure the pipeline is
80: * in a good state. Probably overkill, but it's cheap.
81: */
82: br _ASM_LABEL(main_start)
83: br _ASM_LABEL(main_start)
84: br _ASM_LABEL(main_start)
85: br _ASM_LABEL(main_start)
86:
87: /*
88: * Startup code for main processor.
89: */
90: ASLOCAL(main_start)
91: /*
92: * Save the arguments passed by the PROM
93: * r2 boot string
94: * r3 boot device
95: * r4 boot unit number
96: * r5 boot partition number
97: * r6 magic number if not loaded by the PROM
98: * r7 end of loaded binary if not loaded by the PROM
99: */
100: or.u r13, r0, hi16(_C_LABEL(prom_bootargs))
101: st r2, r13, lo16(_C_LABEL(prom_bootargs))
102: or.u r13, r0, hi16(_C_LABEL(bootdev))
103: st r3, r13, lo16(_C_LABEL(bootdev))
104: or.u r13, r0, hi16(_C_LABEL(bootunit))
105: st r4, r13, lo16(_C_LABEL(bootunit))
106: or.u r13, r0, hi16(_C_LABEL(bootpart))
107: st r5, r13, lo16(_C_LABEL(bootpart))
108: #if defined(DDB) || NKSYMS > 0
109: or.u r12, r0, hi16(SYM_MAGIC)
110: or r12, r12, lo16(SYM_MAGIC)
111: cmp r2, r6, r12
112: bcnd ne0, r2, 1f
113: or.u r13, r0, hi16(_C_LABEL(esym))
114: st r7, r13, lo16(_C_LABEL(esym))
115: 1:
116: #endif
117:
118: /* set cputyp */
119: ldcr r1, PID
120: extu r2, r1, 8<8>
121: bcnd.n eq0, r2, 1f
122: or.u r13, r0, hi16(_C_LABEL(cputyp))
123: or.u r8, r0, hi16(CPU_88110)
124: br.n 2f
125: or r8, r8, lo16(CPU_88110)
126: 1:
127: or.u r8, r0, hi16(CPU_88100)
128: or r8, r8, lo16(CPU_88100)
129: 2:
130: st r8, r13, lo16(_C_LABEL(cputyp))
131:
132: /*
133: * CPU Initialization
134: *
135: * I use r11 and r22 here because they're easy to not
136: * get mixed up -- r10, for example, looks too similar
137: * to r0 when not being careful....
138: *
139: * Ensure that the PSR is as we like:
140: * supervisor mode
141: * big-endian byte ordering
142: * concurrent operation allowed
143: * carry bit clear (I don't think we really care about this)
144: * FPU enabled
145: * misaligned access raises an exception
146: * interrupts disabled
147: * shadow registers frozen
148: *
149: * The manual says not to disable interrupts and freeze shadowing
150: * at the same time because interrupts are not actually disabled
151: * until after the next instruction. Well, if an interrupt
152: * occurs now, we're in deep trouble anyway, so I'm going to do
153: * the two together.
154: *
155: * Upon a reset (or poweron, I guess), the PSR indicates:
156: * supervisor mode
157: * interrupts, shadowing, FPU, misaligned exception: all disabled
158: *
159: * We'll just construct our own turning on what we want.
160: *
161: * jfriedl@omron.co.jp
162: */
163:
164: cmp r2, r8, CPU_88110 /* r8 contains cputyp */
165: bb1 eq, r2, 1f /* if it's a 'mc88110, skip SSBR */
166: stcr r0, SSBR /* clear this for later */
167: 1:
168: stcr r0, SR1 /* clear the CPU flags */
169:
170: set r11, r0, 1<PSR_SUPERVISOR_MODE_BIT>
171: set r11, r11, 1<PSR_INTERRUPT_DISABLE_BIT>
172: set r11, r11, 1<PSR_GRAPHICS_DISABLE_BIT>
173: /*
174: * XXX On 88110 processors, force serial instruction execution for now.
175: * Situation where OoO would break will be hopefully taken care of in
176: * the near future -- miod
177: */
178: #if 0
179: clr r11, r11, 1<PSR_SERIAL_MODE_BIT>
180: #else
181: set r11, r11, 1<PSR_SERIAL_MODE_BIT>
182: #endif
183: set r11, r11, 1<PSR_SERIALIZE_BIT>
184: stcr r11, PSR
185: FLUSH_PIPELINE
186:
187: /* save PROM vbr */
188: ldcr r12, VBR
189: or.u r13, r0, hi16(_C_LABEL(prom_vbr))
190: st r12, r13, lo16(_C_LABEL(prom_vbr))
191: stcr r0, VBR
192:
193: #ifdef MULTIPROCESSOR
194: /*
195: * Have curcpu() point at the dummy cpuinfo structure,
196: * so that cpu_number() does not dereference random memory.
197: * This is necessary for early spl usage, despite the fact that
198: * interrupts are disabled...
199: */
200: or.u r11, r0, hi16(_ASM_LABEL(dummy_cpu))
201: or r11, r11, lo16(_ASM_LABEL(dummy_cpu))
202: stcr r11, CPU
203:
204: /*
205: * SCM PROM idles all secondary MPUs upon startup, so at this point
206: * we do not have to compete with them.
207: */
208: #endif /* MULTIPROCESSOR */
209:
210: /* Switch to interrupt stack */
211: or.u r31, r0, hi16(_ASM_LABEL(intstack_end))
212: or r31, r31, lo16(_ASM_LABEL(intstack_end))
213:
214: #ifdef M88110
215: #ifdef M88100
216: cmp r2, r8, CPU_88110 /* r8 contains cputyp */
217: bb1 ne, r2, 1f /* if it's a 'mc88110, use different vectors */
218: #endif
219: or.u r3, r0, hi16(_C_LABEL(m88110_vector_list))
220: br.n 2f
221: or r3, r3, lo16(_C_LABEL(m88110_vector_list))
222: 1:
223: #endif /* M88110 */
224: #ifdef M88100
225: or.u r3, r0, hi16(_C_LABEL(vector_list))
226: or r3, r3, lo16(_C_LABEL(vector_list))
227: #endif /* M88100 */
228: 2:
229: bsr.n _C_LABEL(vector_init)
230: ldcr r2, VBR
231:
232: /*
233: * aviion_bootstrap(), among other things, clears proc0's u area.
234: * We are still using the interrupt stack here, thus we are not
235: * affected...
236: */
237: bsr _C_LABEL(aviion_bootstrap)
238:
239: /*
240: * ...and we can switch to the u area stack now.
241: */
242: ldcr r10, CPU
243: ld r31, r10, CI_CURPCB
244:
245: /* call main() - no arguments although main() still defines one */
246: bsr.n _C_LABEL(main)
247: addu r31, r31, USIZE
248:
249: or.u r2, r0, hi16(_ASM_LABEL(main_panic))
250: bsr.n _C_LABEL(panic)
251: or r2, r2, lo16(_ASM_LABEL(main_panic))
252:
253: data
254: .align 4
255: ASLOCAL(main_panic)
256: string "main() returned\0"
257: text
258: .align 8
259:
260: #ifdef MULTIPROCESSOR
261:
262: /*
263: * Startup code for secondary processors.
264: * Some of these initializations are very close to main_start; refer
265: * to the comments there for details.
266: */
267: GLOBAL(secondary_start)
268: or.u r31, r0, hi16(_ASM_LABEL(slavestack_end))
269: or r31, r31, lo16(_ASM_LABEL(slavestack_end))
270:
271: or.u r13, r0, hi16(_C_LABEL(cputyp))
272: ld r8, r13, lo16(_C_LABEL(cputyp))
273:
274: cmp r2, r8, CPU_88110
275: bb1 eq, r2, 1f
276: stcr r0, SSBR
277: 1:
278: stcr r0, SR1
279:
280: set r11, r0, 1<PSR_SUPERVISOR_MODE_BIT>
281: set r11, r11, 1<PSR_INTERRUPT_DISABLE_BIT>
282: set r11, r11, 1<PSR_GRAPHICS_DISABLE_BIT>
283: /*
284: * XXX On 88110 processors, force serial instruction execution for now.
285: * Situation where OoO would break will be hopefully taken care of in
286: * the near future -- miod
287: */
288: #if 0
289: clr r11, r11, 1<PSR_SERIAL_MODE_BIT>
290: #else
291: set r11, r11, 1<PSR_SERIAL_MODE_BIT>
292: #endif
293: set r11, r11, 1<PSR_SERIALIZE_BIT>
294: stcr r11, PSR
295: FLUSH_PIPELINE
296: stcr r0, VBR /* set Vector Base Register to 0, ALWAYS! */
297: FLUSH_PIPELINE
298:
299: /*
300: * Have curcpu() point at the dummy cpuinfo structure,
301: * so that cpu_number() does not dereference random memory.
302: * This is necessary for early spl usage, despite the fact that
303: * interrupts are disabled...
304: */
305: or.u r11, r0, hi16(_ASM_LABEL(dummy_cpu))
306: or r11, r11, lo16(_ASM_LABEL(dummy_cpu))
307: stcr r11, CPU
308:
309: /*
310: * Since there may be more than one secondary MPU, compete with them
311: * to initialize safely.
312: */
313: or.u r11, r0, hi16(_C_LABEL(cpu_mutex))
314: or r11, r11, lo16(_C_LABEL(cpu_mutex))
315: 1:
316: or r22, r0, 1
317: xmem r22, r11, r0 /* If r22 gets 0, we have the lock... */
318: bcnd eq0, r22, 4f /* ...but if not, we must wait */
319: 2:
320: /* just watch the lock until it looks clear */
321: ld r22, r11, r0
322: bcnd eq0, r22, 1b
323: /* since we can be here with caches off, add a few nops to
324: keep the bus from getting overloaded */
325: or r2, r0, lo16(1000)
326: 3:
327: subu r2, r2, 1
328: bcnd ne0, r2, 3b
329: br 1b
330: 4:
331:
332: /*
333: * While holding the cpu_mutex, the secondary cpu can use the slavestack
334: * to call secondary_pre_main() to determine its cpu number.
335: * After that, however, it should allocate its own stack and switch
336: * to it.
337: */
338:
339: bsr _C_LABEL(secondary_pre_main) /* set cpu number */
340:
341: ldcr r2, CPU
342: ld r3, r2, CI_IDLE_PCB
343: bsr.n _C_LABEL(secondary_main)
344: addu r31, r3, USIZE /* switch to idle stack */
345:
346: /*
347: * At this point, the CPU has been correctly initialized and has
348: * identified itself on the console.
349: * All it needs now is to jump to the idle loop and wait for work to
350: * be offered.
351: */
352: br _ASM_LABEL(cpu_switch_idle)
353:
354: #endif /* MULTIPROCESSOR */
355:
356: /*
357: * void delay(int us)
358: *
359: * The processor loops (busy waits) for the given number of microseconds:
360: * Thus, delay(1000000) will delay for one second.
361: * (originally from Mach 2.5)
362: */
363: GLOBAL(delay)
364: or.u r3, r0, hi16(_cpuspeed)
365: ld r3, r3, lo16(_cpuspeed)
366: mul r4, r2, r3
367: subu r4, r4, 4 /* overhead of these instructions */
368:
369: /* now loop for the given number of cycles */
370: 1:
371: bcnd.n gt0, r4, 1b
372: subu r4, r4, 2 /* two cycles per iteration */
373:
374: jmp r1
375:
376: /*****************************************************************************/
377:
378: data
379: .align PAGE_SIZE
380: GLOBAL(kernel_sdt) /* SDT (segment descriptor table */
381: space 0x2000 /* 8K - 4K phys, 4K virt*/
382:
383: .align PAGE_SIZE
384: ASGLOBAL(intstack)
385: space USIZE
386: ASGLOBAL(intstack_end)
387:
388: #ifdef MULTIPROCESSOR
389: space PAGE_SIZE /* 4K, small, interim stack */
390: ASLOCAL(slavestack_end)
391: #endif
392:
393: /*
394: * Main processor's idle pcb and stack.
395: * Should be page aligned.
396: */
397: .align PAGE_SIZE
398: GLOBAL(idle_u)
399: space USIZE
400:
401: /*
402: * Process 0's u.
403: * Should be page aligned.
404: */
405: .align PAGE_SIZE
406: ASLOCAL(u0)
407: space USIZE
408: GLOBAL(proc0paddr)
409: word _ASM_LABEL(u0) /* KVA of proc0 uarea */
410:
411: #ifdef MULTIPROCESSOR
412: /* Dummy cpuinfo structure, for cpu_number() to work early. */
413: ASLOCAL(dummy_cpu)
414: word 1 /* ci_alive */
415: word 0 /* ci_curproc */
416: word 0 /* ci_curpcb */
417: word 0 /* ci_cpuid */
418: #endif /* MULTIPROCESSOR */
419:
420: #if defined(DDB) || NKSYMS > 0
421: GLOBAL(esym)
422: word 0
423: #endif /* DDB || NKSYMS > 0 */
CVSweb