Annotation of sys/arch/aviion/aviion/locore.S, Revision 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