diff options
author | Theo de Raadt <deraadt@cvs.openbsd.org> | 1995-10-18 12:25:08 +0000 |
---|---|---|
committer | Theo de Raadt <deraadt@cvs.openbsd.org> | 1995-10-18 12:25:08 +0000 |
commit | a121e75a02f53fbf8b4871e54bf16945943b4929 (patch) | |
tree | 3e700df1b87c007991d3f480b4af68423f7cc79e /sys | |
parent | c6f8565b7d68c4189a580289e5a5322984ed318f (diff) |
- bzero/strlen/bcmp
Diffstat (limited to 'sys')
-rw-r--r-- | sys/arch/mvme68k/mvme68k/locore.s | 1159 |
1 files changed, 660 insertions, 499 deletions
diff --git a/sys/arch/mvme68k/mvme68k/locore.s b/sys/arch/mvme68k/mvme68k/locore.s index 26a08c31bad..b2c88a95167 100644 --- a/sys/arch/mvme68k/mvme68k/locore.s +++ b/sys/arch/mvme68k/mvme68k/locore.s @@ -1,8 +1,7 @@ -/* $NetBSD: locore.s,v 1.1.1.1.2.1 1995/10/12 20:00:04 chuck Exp $ */ - -#undef STACKCHECK /* doesn't work any more */ +/* $NetBSD: locore.s,v 1.40 1995/05/12 18:24:46 mycroft Exp $ */ /* + * Copyright (c) 1995 Theo de Raadt * Copyright (c) 1988 University of Utah. * Copyright (c) 1980, 1990, 1993 * The Regents of the University of California. All rights reserved. @@ -44,21 +43,8 @@ * @(#)locore.s 8.6 (Berkeley) 5/27/94 */ -/* - * STACKCHECK enables two types of kernel stack checking: - * 1. stack "overflow". On every clock interrupt we ensure that - * the current kernel stack has not grown into the user struct - * page, i.e. size exceeded UPAGES-1 pages. - * 2. stack "underflow". Before every rte to user mode we ensure - * that we will be exactly at the base of the stack after the - * exception frame has been popped. - * Both checks are performed at splclock since they operate on the - * global temporary stack. - */ -/* #define STACKCHECK */ - #include "assym.s" -#include <mvme68k/mvme68k/vectors.s> +#include <machine/prom.h> /* * Temporary stack for a variety of purposes. @@ -68,22 +54,470 @@ */ .data .space NBPG + .globl tmpstk tmpstk: +#define RELOC(var, ar) \ + lea var,ar + +/* + * Initialization + * + * The bootstrap loader loads us in starting at 0, and VBR is non-zero. + * On entry, args on stack are boot device, boot filename, console unit, + * boot flags (howto), boot device name, filesystem type name. + */ + .comm _lowram,4 + .comm _esym,4 + .comm _emini,4 + .comm _smini,4 + .comm _needprom,4 + .comm _promvbr,4 + .comm _promcall,4 + .text + .globl _edata + .globl _etext,_end + .globl start +start: + movw #PSL_HIGHIPL,sr | no interrupts + movl #0,a5 | RAM starts at 0 + movl sp@(4),d7 | get boothowto + movl sp@(8),d6 | get bootdev + movl sp@(12),a4 | get _esym + + RELOC(_smini,a0) + movl sp@(16),a0@ | get _smini + RELOC(_emini,a0) + movl sp@(20),a0@ | get _emini + + RELOC(tmpstk, a0) + movl a0,sp | give ourselves a temporary stack + + movc vbr,d0 | save prom's trap #15 vector + RELOC(_promvbr, a0) + movl d0, a0@ + + clrl sp@- + trap #15 + .short MVMEPROM_GETBRDID + movl sp@+, a1 + + movl #SIZEOF_MVMEPROM_BRDID, d0 | copy to local variables + RELOC(_brdid, a0) +1: movb a1@+, a0@+ + subql #1, d0 + bne 1b + + RELOC(_esym, a0) + movl a4,a0@ | store end of symbol table + RELOC(_lowram, a0) + movl a5,a0@ | store start of physical memory + + clrl d0 + RELOC(_brdid, a1) + movw a1@(MVMEPROM_BRDID_MODEL), d0 + RELOC(_cputyp, a0) + movl d0, a0@ | init _cputyp + +#ifdef MVME147 + cmpw #CPU_147, d0 + beq is147 +#endif + +#ifdef MVME162 + cmpw #CPU_162, d0 + beq is162 +#endif + +#ifdef MVME167 + cmpw #CPU_166, d0 + beq is167 + cmpw #CPU_167, d0 + beq is167 +#endif + +#ifdef MVME177 + cmpw #CPU_177, d0 + beq is177 +#endif + + .data +notsup: .ascii "kernel does not support this model." +notsupend: + .even + .text + + | first we bitch, then we die. + movl #notsupend, sp@- + movl #notsup, sp@- + trap #15 + .short MVMEPROM_OUTSTRCRLF + addql #8,sp + + trap #15 + .short MVMEPROM_EXIT | return to m68kbug + /*NOTREACHED */ + +#ifdef MVME147 +is147: + RELOC(_mmutype, a0) | no, we have 68030 + movl #MMU_68030,a0@ | set to reflect 68030 PMMU + + movl #CACHE_OFF,d0 + movc d0,cacr | clear and disable on-chip cache(s) + + movb #0, 0xfffe1026 | XXX serial interrupt off + movb #0, 0xfffe1018 | XXX timer 1 off + movb #0, 0xfffe1028 | XXX ethernet off + + movl #0xfffe0000, a0 | mvme147 nvram base + | move nvram component of etheraddr (only last 3 bytes) + RELOC(_myea, a1) + movw a0@(NVRAM_147_ETHER+0), a1@(3+0) + movb a0@(NVRAM_147_ETHER+2), a1@(3+2) + movl a0@(NVRAM_147_EMEM), d1 | pass memory size + + RELOC(_iiomapsize, a1) + movl #INTIOSIZE_147, a1@ + RELOC(_iiomapbase, a1) + movl #INTIOBASE_147, a1@ + bra Lstart1 +#endif + +#ifdef MVME162 +is162: +#if 0 + | the following 3 things are "just in case". they won't make + | the kernel work properly, but they will at least let it get + | far enough that you can figure out that something had an + | interrupt pending. which the bootrom shouldn't allow, i don't + | think.. + clrb 0xfff42002 | XXX MCchip irq off + clrl 0xfff42018 | XXX MCchip timers irq off + clrb 0xfff4201d | XXX MCchip scc irq off +#endif + RELOC(_memsize162, a1) | how much memory? + jbsr a1@ + movl d0, d2 + + RELOC(_mmutype, a0) + movl #MMU_68040,a0@ | with a 68040 MMU + + bra is16x +#endif + +#ifdef MVME167 +is167: +| RELOC(_needprom,a0) | this machine needs the prom mapped! +| movl #1,a0@ + + RELOC(_memsize1x7, a1) | how much memory? + jbsr a1@ + movl d0, d2 + + RELOC(_mmutype, a0) + movl #MMU_68040,a0@ | with a 68040 MMU + + bra is16x +#endif + +#ifdef MVME177 +is177: +| RELOC(_needprom,a0) | this machine needs the prom mapped! +| movl #1,a0@ + + RELOC(_memsize1x7, a1) | how much memory? + jbsr a1@ + movl d0, d2 + + RELOC(_mmutype, a0) + movl #MMU_68040,a0@ | XXX TDR FIX FIX with a 68060 MMU + + bra is16x +#endif + +#if defined(MVME162) || defined(MVME167) || defined(MVME177) + .data +#define ROMPKT_LEN 200 + .comm _rompkt, ROMPKT_LEN + .even + .text +is16x: + RELOC(_iiomapsize, a1) + movl #INTIOSIZE_162, a1@ + RELOC(_iiomapbase, a1) + movl #INTIOBASE_162, a1@ + + /* get ethernet address */ + RELOC(_rompkt, a0) | build a .NETCTRL packet + movb #0, a0@(NETCTRL_DEV) | onboard ethernet + movb #0, a0@(NETCTRL_CTRL) | onboard ethernet + movl #NETCTRLCMD_GETETHER, a0@(NETCTRL_CMD) + RELOC(_myea, a1) + movl a1, a0@(NETCTRL_ADDR) | where to put it + movl #6, a0@(NETCTRL_LEN) | it is 6 bytes long + + movl a0, sp@- + trap #15 + .short MVMEPROM_NETCTRL | ask the rom + addl #4, sp + +#if 0 + /* + * get memory size using ENVIRON. unfortunately i've not managed + * to get this working. + */ + RELOC(_rompkt, a0) + movl #ENVIRONCMD_READ, sp@- | request environment information + movl #ROMPKT_LEN, sp@- | max length + movl a0, sp@- | point to info packet + trap #15 + .short MVMEPROM_ENVIRON | ask the rom + addl #12, sp + | XXX should check return values + + clrl d2 | memsize = 0 +1: clrl d0 + movb a0@+, d0 | look for a "memsize" chunk in the + cmpb #ENVIRONTYPE_EOL, d0 | environment + beq 3f + cmpb #ENVIRONTYPE_MEMSIZE, d0 + beq 2f + movb a0@+, d0 + addl d0, a0 + bra 1b +2: movl a0@(7), d2 | XXX memory size (fix @(7) offset!) +3: +#endif + + | if memory size is unknown, print a diagnostic and make an + | assumption + movl d2, d1 + cmpl #0, d1 + bne Lstart1 + + movl #unkmemend, sp@- + movl #unkmem, sp@- + trap #15 + .short MVMEPROM_OUTSTRCRLF + addql #8,sp + + movl #4*1024*1024, d1 | XXX assume 4M of ram + bra Lstart1 + + .data +unkmem: .ascii "could not figure out how much memory; assuming 4M." +unkmemend: + .even + .text + +#endif + +Lstart1: +/* initialize source/destination control registers for movs */ + moveq #FC_USERD,d0 | user space + movc d0,sfc | as source + movc d0,dfc | and destination of transfers + moveq #PGSHIFT,d2 + lsrl d2,d1 | convert to page (click) number + RELOC(_maxmem, a0) + movl d1,a0@ | save as maxmem + movl a5,d0 | lowram value from ROM via boot + lsrl d2,d0 | convert to page number + subl d0,d1 | compute amount of RAM present + RELOC(_physmem, a0) + movl d1,a0@ | and physmem +/* configure kernel and proc0 VA space so we can get going */ + .globl _Sysseg, _pmap_bootstrap, _avail_start +#ifdef MFS + /* preserve miniroot if it exists */ + RELOC(_emini,a0) | end of miniroot + movl a0@,d5 + jne Lstart2 +#endif +#ifdef DDB + RELOC(_esym,a0) | end of static kernel test/data/syms + movl a0@,d5 + jne Lstart2 +#endif + movl #_end,d5 | end of static kernel text/data +Lstart2: + addl #NBPG-1,d5 + andl #PG_FRAME,d5 | round to a page + movl d5,a4 + addl a5,a4 | convert to PA +#if 0 + | XXX clear from end-of-kernel to 1M, as a workaround for an + | inane pmap_bootstrap bug I cannot find (68040-specific) + movl a4,a0 + movl #1024*1024,d0 + cmpl a0,d0 | end of kernel is beyond 1M? + jlt 2f + subl a0,d0 +1: clrb a0@+ + subql #1,d0 + bne 1b +2: +#endif + pea a5@ | firstpa + pea a4@ | nextpa + RELOC(_pmap_bootstrap,a0) + jbsr a0@ | pmap_bootstrap(firstpa, nextpa) + addql #8,sp + +/* + * Enable the MMU. + * Since the kernel is mapped logical == physical, we just turn it on. + */ + RELOC(_Sysseg, a0) | system segment table addr + movl a0@,d1 | read value (a KVA) + addl a5,d1 | convert to PA + RELOC(_mmutype, a0) + cmpl #MMU_68040,a0@ | 68040? + jne Lmotommu1 | no, skip + .long 0x4e7b1807 | movc d1,srp + jra Lstploaddone +Lmotommu1: + RELOC(_protorp, a0) + movl #0x80000202,a0@ | nolimit + share global + 4 byte PTEs + movl d1,a0@(4) | + segtable address + pmove a0@,srp | load the supervisor root pointer + movl #0x80000002,a0@ | reinit upper half for CRP loads +Lstploaddone: + RELOC(_mmutype, a0) + cmpl #MMU_68040,a0@ | 68040? + jne Lmotommu2 | no, skip + + RELOC(_needprom,a0) + cmpl #0,a0@ + beq 1f + /* + * this machine needs the prom mapped. we use the translation + * registers to map it in.. and the ram it needs. + */ + movel #0xff00a044,d0 | map top 16meg 1/1 for bug eprom exe + .long 0x4e7b0004 | movc d0,itt0 + moveq #0,d0 | ensure itt1 is disabled + .long 0x4e7b0005 | movc d0,itt1 + movel #0xff00a040,d0 | map top 16meg 1/1 for bug io access + .long 0x4e7b0006 | movc d0,dtt0 + moveq #0,d0 | ensure dtt1 is disabled + .long 0x4e7b0007 | movc d0,dtt1 + bra 2f +1: + moveq #0,d0 | ensure TT regs are disabled + .long 0x4e7b0004 | movc d0,itt0 + .long 0x4e7b0005 | movc d0,itt1 + .long 0x4e7b0006 | movc d0,dtt0 + .long 0x4e7b0007 | movc d0,dtt1 +2: + + .word 0xf4d8 | cinva bc + .word 0xf518 | pflusha + movl #0x8000,d0 + .long 0x4e7b0003 | movc d0,tc + movl #0x80008000,d0 + movc d0,cacr | turn on both caches + jmp Lenab1 +Lmotommu2: + movl #0x82c0aa00,a2@ | value to load TC with + pmove a2@,tc | load it +Lenab1: + +/* + * Should be running mapped from this point on + */ +/* select the software page size now */ + lea tmpstk,sp | temporary stack + jbsr _vm_set_page_size | select software page size +/* set kernel stack, user SP, and initial pcb */ + movl _proc0paddr,a1 | get proc0 pcb addr + lea a1@(USPACE-4),sp | set kernel stack to end of area + movl #USRSTACK-4,a2 + movl a2,usp | init user SP + movl a1,_curpcb | proc0 is running +#ifdef FPCOPROC + clrl a1@(PCB_FPCTX) | ensure null FP context + movl a1,sp@- + jbsr _m68881_restore | restore it (does not kill a1) + addql #4,sp +#endif +/* flush TLB and turn on caches */ + jbsr _TBIA | invalidate TLB + cmpl #MMU_68040,_mmutype | 68040? + jeq Lnocache0 | yes, cache already on + movl #CACHE_ON,d0 + movc d0,cacr | clear cache(s) +Lnocache0: +/* final setup for C code */ + movl #_vectab,d2 | set VBR + movc d2,vbr + movw #PSL_LOWIPL,sr | lower SPL + movl d7,_boothowto | save reboot flags + movl d6,_bootdev | and boot device + /* - * This is where we wind up if the kernel jumps to location 0. - * (i.e. a bogus PC) This is known to immediately follow the vector - * table and is hence at 0x400 (see reset vector in vectors.s). + * Create a fake exception frame so that cpu_fork() can copy it. + * main() nevers returns; we exit to user mode from a forked process + * later on. */ - .globl _panic - pea Ljmp0panic + clrw sp@- | vector offset/frame type + clrl sp@- | PC - filled in by "execve" + movw #PSL_USER,sp@- | in user mode + clrl sp@- | stack adjust count and padding + lea sp@(-64),sp | construct space for D0-D7/A0-A7 + lea _proc0,a0 | save pointer to frame + movl sp,a0@(P_MD_REGS) | in proc0.p_md.md_regs + + jra _main | main() + + pea 1f jbsr _panic - /* NOTREACHED */ -Ljmp0panic: - .asciz "kernel jump to zero" +1: + .asciz "main returned" .even + .globl _proc_trampoline +_proc_trampoline: + movl a3,sp@- + jbsr a2@ + addql #4,sp + movl sp@(FR_SP),a0 | grab and load + movl a0,usp | user SP + moveml sp@+,#0x7FFF | restore most user regs + addql #8,sp | toss SP and stack adjust + jra rei | and return + +/* + * Signal "trampoline" code (18 bytes). Invoked from RTE setup by sendsig(). + * + * Stack looks like: + * + * sp+0 -> signal number + * sp+4 signal specific code + * sp+8 pointer to signal context frame (scp) + * sp+12 address of handler + * sp+16 saved hardware state + * . + * . + * scp+0-> beginning of signal context frame + */ + .globl _sigcode, _esigcode, _sigcodetrap + .data +_sigcode: + movl sp@(12),a0 | signal handler addr (4 bytes) + jsr a0@ | call signal handler (2 bytes) + addql #4,sp | pop signo (2 bytes) +_sigcodetrap: + trap #1 | special syscall entry (2 bytes) + movl d0,sp@(4) | save errno (4 bytes) + moveq #1,d0 | syscall == exit (2 bytes) + trap #0 | exit(errno) (2 bytes) + .align 2 +_esigcode: + .text + /* * Do a dump. * Called by auto-restart. @@ -107,7 +541,7 @@ _buserr: jbsr _longjmp | longjmp(nofault) Lberr: #if defined(M68040) - cmpl #-2,_mmutype | 68040? + cmpl #MMU_68040,_mmutype | 68040? jne _addrerr | no, skip clrl sp@- | stack adjust count moveml #0xFFFF,sp@- | save user registers @@ -142,7 +576,7 @@ _addrerr: movl a0,sp@(FR_SP) | in the savearea lea sp@(FR_HW),a1 | grab base of HW berr frame #if defined(M68040) - cmpl #-2,_mmutype | 68040? + cmpl #MMU_68040,_mmutype | 68040? jne Lbenot040 | no, skip movl a1@(8),sp@- | yes, push fault address clrl sp@- | no SSW for address fault @@ -249,7 +683,7 @@ _fpfline: _fpunsupp: #if defined(M68040) - cmpl #-2,_mmutype | 68040? + cmpl #MMU_68040,_mmutype | 68040? jne _illinst | no, treat as illinst #ifdef FPSP .globl fpsp_unsupp @@ -369,16 +803,16 @@ fault: addql #8,sp | pop SP and stack adjust jra rei | all done - .globl _pcctrap -_pcctrap: + .globl _hardtrap, _hardintr +_hardtrap: moveml #0xC0C0,sp@- | save scratch regs lea sp@(16),a1 | get pointer to frame movl a1,sp@- movw sp@(26),d0 movl d0,sp@- | push exception vector info movl sp@(26),sp@- | and PC - jbsr _pccintr | doit - lea sp@(12),sp | pop value args + jbsr _hardintr | doit + lea sp@(12),sp | pop args moveml sp@+,#0x0303 | restore regs jra rei | all done @@ -414,11 +848,7 @@ Ltrap1: movl a0,usp | user SP moveml sp@+,#0x7FFF | restore most registers addql #8,sp | pop SP and stack adjust -#ifdef STACKCHECK - jra Ldorte -#else rte -#endif /* * Routines for traps 1 and 2. The meaning of the two traps depends @@ -463,11 +893,31 @@ _trap12: * Trap 15 is used for: * - KGDB traps * - trace traps for SUN binaries (not fully supported yet) + * - calling the prom, but only from the kernel * We just pass it on and let trap() sort it all out */ _trap15: clrl sp@- moveml #0xFFFF,sp@- + tstl _promcall + jeq L_notpromcall + moveml sp@+,#0xFFFF + addql #4, sp + | unwind stack to put to known value + | this routine is from the 147 BUG manual + | currently save and restore are excessive. + subql #4,sp + link a6,#0 + moveml #0xFFFE,sp@- + movl _promvbr,a0 + movw a6@(14),d0 + andl #0xfff,d0 + movl a0@(d0:w),a6@(4) + moveml sp@+,#0x7FFF + unlk a6 + rts + | really jumps to the bug trap handler +L_notpromcall: #ifdef KGDB moveq #T_TRAP15,d0 movw sp@(FR_HW),d1 | get PSW @@ -539,57 +989,14 @@ Lsigr1: /* * Interrupt handlers. - * All device interrupts are auto-vectored. Most - * interrupt in the range IPL1 to IPL6. Here are our assignments: - * - * Level 0: Spurious: ignored. - * Level 1: networking devices (ethernet) - * Level 2: bio devices (scsi) - * Level 3: - * Level 4: Serial (SCC) - * Level 5: Clock - * Level 6: - * Level 7: Non-maskable (none) + * No device interrupts are auto-vectored. */ - .globl _intrhand, _hardclock, _nmihand _spurintr: addql #1,_intrcnt+0 addql #1,_cnt+V_INTR jra rei -_lev1intr: -_lev2intr: -_lev3intr: -_lev4intr: -_lev5intr: -_lev6intr: - moveml #0xC0C0,sp@- - lea _intrcnt,a0 - movw sp@(22),d0 | use vector offset - andw #0xfff,d0 | sans frame type - addql #1,a0@(-0x60,d0:w) | to increment apropos counter - movw sr,sp@- | push current SR value - clrw sp@- | padded to longword - jbsr _intrhand | handle interrupt - addql #4,sp | pop SR - moveml sp@+,#0x0303 - addql #1,_cnt+V_INTR - jra rei - -_lev7intr: - addql #1,_intrcnt+32 - clrl sp@- - moveml #0xFFFF,sp@- | save registers - movl usp,a0 | and save - movl a0,sp@(FR_SP) | the user stack pointer - jbsr _nmihand | call handler - movl sp@(FR_SP),a0 | restore - movl a0,usp | user SP - moveml sp@+,#0x7FFF | and remaining registers - addql #8,sp | pop SP and stack adjust - jra rei | all done - /* * Emulation of VAX REI instruction. * @@ -607,10 +1014,6 @@ _lev7intr: .globl _astpending .globl rei rei: -#ifdef STACKCHECK - tstl _panicstr | have we paniced? - jne Ldorte1 | yes, do not make matters worse -#endif tstl _astpending | AST pending? jeq Lchksir | no, go check for SIR Lrei1: @@ -633,11 +1036,7 @@ Lrei2: jne Laststkadj | yes, go to it moveml sp@+,#0x7FFF | no, restore most user regs addql #8,sp | toss SP and stack adjust -#ifdef STACKCHECK - jra Ldorte -#else rte | and do real RTE -#endif Laststkadj: lea sp@(FR_HW),a1 | pointer to HW frame addql #8,a1 | source pointer @@ -648,11 +1047,7 @@ Laststkadj: movl a0,sp@(FR_SP) | new SSP moveml sp@+,#0x7FFF | restore user registers movl sp@,sp | and our SP -#ifdef STACKCHECK - jra Ldorte -#else rte | and do real RTE -#endif Lchksir: tstb _ssir | SIR pending? jeq Ldorte | no, all done @@ -679,299 +1074,12 @@ Lsir1: movl a0,usp | user SP moveml sp@+,#0x7FFF | and all remaining registers addql #8,sp | pop SP and stack adjust -#ifdef STACKCHECK - jra Ldorte -#else rte -#endif Lnosir: movl sp@+,d0 | restore scratch register Ldorte: -#ifdef STACKCHECK - movw #SPL6,sr | avoid trouble - btst #5,sp@ | are we returning to user mode? - jne Ldorte1 | no, skip it - movl a6,tmpstk-20 - movl d0,tmpstk-76 - moveq #0,d0 - movb sp@(6),d0 | get format/vector - lsrl #3,d0 | convert to index - lea _exframesize,a6 | into exframesize - addl d0,a6 | to get pointer to correct entry - movw a6@,d0 | get size for this frame - addql #8,d0 | adjust for unaccounted for bytes - lea _kstackatbase,a6 | desired stack base - subl d0,a6 | - frame size == our stack - cmpl a6,sp | are we where we think? - jeq Ldorte2 | yes, skip it - lea tmpstk,a6 | will be using tmpstk - movl sp@(4),a6@- | copy common - movl sp@,a6@- | frame info - clrl a6@- - movl sp,a6@- | save sp - subql #4,a6 | skip over already saved a6 - moveml #0x7FFC,a6@- | push remaining regs (d0/a6/a7 done) - lea a6@(-4),sp | switch to tmpstk (skip saved d0) - clrl sp@- | is an underflow - jbsr _badkstack | badkstack(0, frame) - addql #4,sp - moveml sp@+,#0x7FFF | restore most registers - movl sp@,sp | and SP - rte -Ldorte2: - movl tmpstk-76,d0 - movl tmpstk-20,a6 -Ldorte1: -#endif rte | real return -#ifdef STACKCHECK -/* - * Kernel access to the current processes kernel stack is via a fixed - * virtual address. It is at the same address as in the users VA space. - */ - .data - .set _kstack,USRSTACK - .set _kstackatbase,USRSTACK+USPACE-4 - .globl _kstackatbase - .globl _kstack -#endif - -#define RELOC(var, ar) \ - lea var,ar - -/* - * Initialization - * - * The bootstrap loader loads us in starting at 0, and VBR is non-zero. - * On entry, args on stack are boot device, boot filename, console unit, - * boot flags (howto), boot device name, filesystem type name. - */ - .comm _lowram,4 - .comm _esym,4 - - .text - .globl _edata - .globl _etext,_end - .globl start -start: - movw #PSL_HIGHIPL,sr | no interrupts - movl #0,d6 | get bootdev - movl sp@(4),d7 | get boothowto - RELOC(tmpstk, a0) - movl a0,sp | give ourselves a temporary stack - - lea _edata,a0 | clear out BSS - movl #_end-4,d0 | (must be <= 256 kB) - subl #_edata,d0 - lsrl #2,d0 -1: clrl a0@+ - dbra d0,1b - - RELOC(_esym, a0) -#if 1 - movl a4,a0@ | store end of symbol table -#else - clrl a0@ | no symbol table, yet -#endif - movl #0,a5 | RAM starts at 0 - RELOC(_lowram, a0) - movl a5,a0@ | store start of physical memory - movl #CACHE_OFF,d0 - movc d0,cacr | clear and disable on-chip cache(s) - -/* determine our CPU/MMU combo - check for all regardless of kernel config */ - movl #0x200,d0 | data freeze bit - movc d0,cacr | only exists on 68030 - movc cacr,d0 | read it back - tstl d0 | zero? - jeq Lnot68030 | yes, we have 68020/68040 - RELOC(_mmutype, a0) | no, we have 68030 - movl #-1,a0@ | set to reflect 68030 PMMU - jra Lstart1 -Lnot68030: - bset #31,d0 | data cache enable bit - movc d0,cacr | only exists on 68040 - movc cacr,d0 | read it back - tstl d0 | zero? - beq Lis68020 | yes, we have 68020 - moveq #0,d0 | now turn it back off - movec d0,cacr | before we access any data - RELOC(_mmutype, a0) - movl #-2,a0@ | with a 68040 MMU - jra Lstart1 -Lis68020: - RELOC(_mmutype, a0) - movl #1,a0@ | no, we have PMMU - -Lstart1: - /* XXXCDC SHUTUP 147 CALL */ - movb #0, 0xfffe1026 | serial interrupt off - movb #0, 0xfffe1018 | timer 1 off - movb #0, 0xfffe1028 | ethernet off - /* XXXCDC SHUTUP 147 CALL */ -/* initialize source/destination control registers for movs */ - moveq #FC_USERD,d0 | user space - movc d0,sfc | as source - movc d0,dfc | and destination of transfers -/* initialize memory sizes (for pmap_bootstrap) */ - movl 0xfffe0774,d1 | XXXCDC -- hardwired HEX - movl 0xfffe0778,_myea | XXXCDC -- ethernet addr - moveq #PGSHIFT,d2 - lsrl d2,d1 | convert to page (click) number - RELOC(_maxmem, a0) - movl d1,a0@ | save as maxmem - movl a5,d0 | lowram value from ROM via boot - lsrl d2,d0 | convert to page number - subl d0,d1 | compute amount of RAM present - RELOC(_physmem, a0) - movl d1,a0@ | and physmem -/* configure kernel and proc0 VA space so we can get going */ - .globl _Sysseg, _pmap_bootstrap, _avail_start -#ifdef DDB - RELOC(_esym,a0) | end of static kernel test/data/syms - movl a0@,d5 - jne Lstart2 -#endif - movl #_end,d5 | end of static kernel text/data -Lstart2: - addl #NBPG-1,d5 - andl #PG_FRAME,d5 | round to a page - movl d5,a4 - addl a5,a4 | convert to PA - movl #0, sp@- | firstpa - pea a4@ | nextpa - RELOC(_pmap_bootstrap,a0) - jbsr a0@ | pmap_bootstrap(firstpa, nextpa) - addql #8,sp - -/* - * Enable the MMU. - * Since the kernel is mapped logical == physical, we just turn it on. - */ - RELOC(_Sysseg, a0) | system segment table addr - movl a0@,d1 | read value (a KVA) - addl a5,d1 | convert to PA - RELOC(_mmutype, a0) - cmpl #-2,a0@ | 68040? - jne Lmotommu1 | no, skip - .long 0x4e7b1807 | movc d1,srp - jra Lstploaddone -Lmotommu1: - RELOC(_protorp, a0) - movl #0x80000202,a0@ | nolimit + share global + 4 byte PTEs - movl d1,a0@(4) | + segtable address - pmove a0@,srp | load the supervisor root pointer - movl #0x80000002,a0@ | reinit upper half for CRP loads -Lstploaddone: - RELOC(_mmutype, a0) - cmpl #-2,a0@ | 68040? - jne Lmotommu2 | no, skip - moveq #0,d0 | ensure TT regs are disabled - .long 0x4e7b0004 | movc d0,itt0 - .long 0x4e7b0005 | movc d0,itt1 - .long 0x4e7b0006 | movc d0,dtt0 - .long 0x4e7b0007 | movc d0,dtt1 - .word 0xf4d8 | cinva bc - .word 0xf518 | pflusha - movl #0x8000,d0 - .long 0x4e7b0003 | movc d0,tc - movl #0x80008000,d0 - movc d0,cacr | turn on both caches - jmp Lenab1 -Lmotommu2: - movl #0x82c0aa00,a2@ | value to load TC with - pmove a2@,tc | load it -Lenab1: - -/* - * Should be running mapped from this point on - */ -/* select the software page size now */ - lea tmpstk,sp | temporary stack - jbsr _vm_set_page_size | select software page size -/* set kernel stack, user SP, and initial pcb */ - movl _proc0paddr,a1 | get proc0 pcb addr - lea a1@(USPACE-4),sp | set kernel stack to end of area - movl #USRSTACK-4,a2 - movl a2,usp | init user SP - movl a1,_curpcb | proc0 is running -#ifdef FPCOPROC - clrl a1@(PCB_FPCTX) | ensure null FP context - movl a1,sp@- - jbsr _m68881_restore | restore it (does not kill a1) - addql #4,sp -#endif -/* flush TLB and turn on caches */ - jbsr _TBIA | invalidate TLB - cmpl #-2,_mmutype | 68040? - jeq Lnocache0 | yes, cache already on - movl #CACHE_ON,d0 - movc d0,cacr | clear cache(s) -Lnocache0: -/* final setup for C code */ - movl #0x8000,d0 | set VBR XXXCDC - movc d0,vbr - jbsr _isrinit | be ready for stray ints - movw #PSL_LOWIPL,sr | lower SPL - movl d7,_boothowto | save reboot flags - movl d6,_bootdev | and boot device - -/* - * Create a fake exception frame so that cpu_fork() can copy it. - * main() nevers returns; we exit to user mode from a forked process - * later on. - */ - clrw sp@- | vector offset/frame type - clrl sp@- | PC - filled in by "execve" - movw #PSL_USER,sp@- | in user mode - clrl sp@- | stack adjust count and padding - lea sp@(-64),sp | construct space for D0-D7/A0-A7 - lea _proc0,a0 | save pointer to frame - movl sp,a0@(P_MD_REGS) | in proc0.p_md.md_regs - - jra _main | main() - - .globl _proc_trampoline -_proc_trampoline: - movl a3@(P_MD_REGS),sp | process' frame pointer in sp - movl a3,sp@- - jbsr a2@ - addql #4,sp - movl sp@(FR_SP),a0 | grab and load - movl a0,usp | user SP - moveml sp@+,#0x7FFF | restore most user regs - addql #8,sp | toss SP and stack adjust - jra rei | and return - -/* - * Signal "trampoline" code (18 bytes). Invoked from RTE setup by sendsig(). - * - * Stack looks like: - * - * sp+0 -> signal number - * sp+4 signal specific code - * sp+8 pointer to signal context frame (scp) - * sp+12 address of handler - * sp+16 saved hardware state - * . - * . - * scp+0-> beginning of signal context frame - */ - .globl _sigcode, _esigcode, _sigcodetrap - .data -_sigcode: - movl sp@(12),a0 | signal handler addr (4 bytes) - jsr a0@ | call signal handler (2 bytes) - addql #4,sp | pop signo (2 bytes) -_sigcodetrap: - trap #1 | special syscall entry (2 bytes) - movl d0,sp@(4) | save errno (4 bytes) - moveq #1,d0 | syscall == exit (2 bytes) - trap #0 | exit(errno) (2 bytes) - .align 2 -_esigcode: - /* * Primitives */ @@ -1003,7 +1111,7 @@ ENTRY(copypage) movl sp@(8),a1 | destination address movl #NBPG/32,d0 | number of 32 byte chunks #if defined(M68040) - cmpl #-2,_mmutype | 68040? + cmpl #MMU_68040,_mmutype | 68040? jne Lmlloop | no, use movl Lm16loop: .long 0xf6209000 | move16 a0@+,a1@+ @@ -1062,12 +1170,12 @@ ENTRY(longjmp) ENTRY(setrunqueue) movl sp@(4),a0 #ifdef DIAGNOSTIC - tstl a0@(P_BACK) - jne Lset1 - tstl a0@(P_WCHAN) - jne Lset1 - cmpb #SRUN,a0@(P_STAT) - jne Lset1 + tstl a0@(P_BACK) + jne Lset1 + tstl a0@(P_WCHAN) + jne Lset1 + cmpb #SRUN,a0@(P_STAT) + jne Lset1 #endif clrl d0 movb a0@(P_PRIORITY),d0 @@ -1086,10 +1194,10 @@ ENTRY(setrunqueue) rts #ifdef DIAGNOSTIC Lset1: - movl #Lset2,sp@- - jbsr _panic + movl #Lset2,sp@- + jbsr _panic Lset2: - .asciz "setrunqueue" + .asciz "setrunqueue" .even #endif @@ -1102,32 +1210,32 @@ ENTRY(remrq) movl sp@(4),a0 movb a0@(P_PRIORITY),d0 #ifdef DIAGNOSTIC - lsrb #2,d0 - movl _whichqs,d1 - btst d0,d1 - jeq Lrem2 + lsrb #2,d0 + movl _whichqs,d1 + btst d0,d1 + jeq Lrem2 #endif - movl a0@(P_BACK),a1 - clrl a0@(P_BACK) - movl a0@(P_FORW),a0 - movl a0,a1@(P_FORW) - movl a1,a0@(P_BACK) - cmpal a0,a1 - jne Lrem1 + movl a0@(P_BACK),a1 + clrl a0@(P_BACK) + movl a0@(P_FORW),a0 + movl a0,a1@(P_FORW) + movl a1,a0@(P_BACK) + cmpal a0,a1 + jne Lrem1 #ifndef DIAGNOSTIC - lsrb #2,d0 - movl _whichqs,d1 + lsrb #2,d0 + movl _whichqs,d1 #endif - bclr d0,d1 - movl d1,_whichqs + bclr d0,d1 + movl d1,_whichqs Lrem1: rts #ifdef DIAGNOSTIC Lrem2: - movl #Lrem3,sp@- - jbsr _panic + movl #Lrem3,sp@- + jbsr _panic Lrem3: - .asciz "remrq" + .asciz "remrq" .even #endif @@ -1152,16 +1260,16 @@ mdpflag: * Switch to a safe stack and PCB, and deallocate the process's resources. */ ENTRY(switch_exit) - movl sp@(4),a0 - movl #nullpcb,_curpcb | save state into garbage pcb - lea tmpstk,sp | goto a tmp stack + movl sp@(4),a0 + movl #nullpcb,_curpcb | save state into garbage pcb + lea tmpstk,sp | goto a tmp stack /* Free old process's resources. */ - movl #USPACE,sp@- | size of u-area - movl a0@(P_ADDR),sp@- | address of process's u-area - movl _kernel_map,sp@- | map it was allocated in - jbsr _kmem_free | deallocate it - lea sp@(12),sp | pop args + movl #USPACE,sp@- | size of u-area + movl a0@(P_ADDR),sp@- | address of process's u-area + movl _kernel_map,sp@- | map it was allocated in + jbsr _kmem_free | deallocate it + lea sp@(12),sp | pop args jra _cpu_switch @@ -1173,8 +1281,8 @@ ENTRY(switch_exit) Idle: stop #PSL_LOWIPL movw #PSL_HIGHIPL,sr - movl _whichqs,d0 - jeq Idle + movl _whichqs,d0 + jeq Idle jra Lsw1 Lbadsw: @@ -1205,31 +1313,31 @@ ENTRY(cpu_switch) * Find the highest-priority queue that isn't empty, * then take the first proc from that queue. */ - movw #PSL_HIGHIPL,sr | lock out interrupts - movl _whichqs,d0 - jeq Idle + movw #PSL_HIGHIPL,sr | lock out interrupts + movl _whichqs,d0 + jeq Idle Lsw1: - movl d0,d1 - negl d0 - andl d1,d0 - bfffo d0{#0:#32},d1 - eorib #31,d1 - - movl d1,d0 - lslb #3,d1 | convert queue number to index - addl #_qs,d1 | locate queue (q) - movl d1,a1 - movl a1@(P_FORW),a0 | p = q->p_forw - cmpal d1,a0 | anyone on queue? - jeq Lbadsw | no, panic - movl a0@(P_FORW),a1@(P_FORW) | q->p_forw = p->p_forw - movl a0@(P_FORW),a1 | n = p->p_forw - movl d1,a1@(P_BACK) | n->p_back = q - cmpal d1,a1 | anyone left on queue? - jne Lsw2 | yes, skip - movl _whichqs,d1 - bclr d0,d1 | no, clear bit - movl d1,_whichqs + movl d0,d1 + negl d0 + andl d1,d0 + bfffo d0{#0:#32},d1 + eorib #31,d1 + + movl d1,d0 + lslb #3,d1 | convert queue number to index + addl #_qs,d1 | locate queue (q) + movl d1,a1 + movl a1@(P_FORW),a0 | p = q->p_forw + cmpal d1,a0 | anyone on queue? + jeq Lbadsw | no, panic + movl a0@(P_FORW),a1@(P_FORW) | q->p_forw = p->p_forw + movl a0@(P_FORW),a1 | n = p->p_forw + movl d1,a1@(P_BACK) | n->p_back = q + cmpal d1,a1 | anyone left on queue? + jne Lsw2 | yes, skip + movl _whichqs,d1 + bclr d0,d1 | no, clear bit + movl d1,_whichqs Lsw2: movl a0,_curproc clrl _want_resched @@ -1282,9 +1390,9 @@ Lswnofpsave: movl _curpcb,a1 | restore p_addr Lswnochg: - lea tmpstk,sp | now goto a tmp stack for NMI + lea tmpstk,sp | now goto a tmp stack for NMI #if defined(M68040) - cmpl #-2,_mmutype | 68040? + cmpl #MMU_68040,_mmutype | 68040? jne Lres1a | no, skip .word 0xf518 | yes, pflusha movl a1@(PCB_USTP),d0 | get USTP @@ -1312,7 +1420,7 @@ Lcxswdone: tstb a0@ | null state frame? jeq Lresfprest | yes, easy #if defined(M68040) - cmpl #-2,_mmutype | 68040? + cmpl #MMU_68040,_mmutype | 68040? jne Lresnot040 | no, skip clrl sp@- | yes... frestore sp@+ | ...magic! @@ -1383,7 +1491,7 @@ Lsldone: ENTRY(TBIA) __TBIA: #if defined(M68040) - cmpl #-2,_mmutype | 68040? + cmpl #MMU_68040,_mmutype | 68040? jne Lmotommu3 | no, skip .word 0xf518 | yes, pflusha rts @@ -1405,7 +1513,7 @@ ENTRY(TBIS) jne __TBIA | yes, flush entire TLB #endif #if defined(M68040) - cmpl #-2,_mmutype | 68040? + cmpl #MMU_68040,_mmutype | 68040? jne Lmotommu4 | no, skip movl sp@(4),a0 movc dfc,d1 @@ -1439,9 +1547,9 @@ ENTRY(TBIAS) jne __TBIA | yes, flush everything #endif #if defined(M68040) - cmpl #-2,_mmutype | 68040? - jne Lmotommu5 | no, skip - .word 0xf518 | yes, pflusha (for now) XXX + cmpl #MMU_68040,_mmutype | 68040? + jne Lmotommu5 | no, skip + .word 0xf518 | yes, pflusha (for now) XXX rts Lmotommu5: #endif @@ -1459,9 +1567,9 @@ ENTRY(TBIAU) jne __TBIA | yes, flush everything #endif #if defined(M68040) - cmpl #-2,_mmutype | 68040? - jne Lmotommu6 | no, skip - .word 0xf518 | yes, pflusha (for now) XXX + cmpl #MMU_68040,_mmutype | 68040? + jne Lmotommu6 | no, skip + .word 0xf518 | yes, pflusha (for now) XXX rts Lmotommu6: #endif @@ -1476,9 +1584,9 @@ Lmotommu6: ENTRY(ICIA) #if defined(M68040) ENTRY(ICPA) - cmpl #-2,_mmutype | 68040 - jne Lmotommu7 | no, skip - .word 0xf498 | cinva ic + cmpl #MMU_68040,_mmutype | 68040 + jne Lmotommu7 | no, skip + .word 0xf498 | cinva ic rts Lmotommu7: #endif @@ -1496,9 +1604,9 @@ Lmotommu7: ENTRY(DCIA) __DCIA: #if defined(M68040) - cmpl #-2,_mmutype | 68040 - jne Lmotommu8 | no, skip - /* XXX implement */ + cmpl #MMU_68040,_mmutype | 68040 + jne Lmotommu8 | no, skip + .word 0xf478 | cpusha dc rts Lmotommu8: #endif @@ -1507,20 +1615,30 @@ Lmotommu8: ENTRY(DCIS) __DCIS: #if defined(M68040) - cmpl #-2,_mmutype | 68040 - jne Lmotommu9 | no, skip - /* XXX implement */ + cmpl #MMU_68040,_mmutype | 68040 + jne Lmotommu9 | no, skip + .word 0xf478 | cpusha dc rts Lmotommu9: #endif rts +| Invalid single cache line +ENTRY(DCIAS) +__DCIAS: + cmpl #MMU_68040,_mmutype | 68040 + jeq Ldciasx + movl sp@(4),a0 + .word 0xf468 | cpushl dc,a0@ +Ldciasx: + rts + ENTRY(DCIU) __DCIU: #if defined(M68040) - cmpl #-2,_mmutype | 68040 - jne LmotommuA | no, skip - /* XXX implement */ + cmpl #MMU_68040,_mmutype | 68040 + jne LmotommuA | no, skip + .word 0xf478 | cpusha dc rts LmotommuA: #endif @@ -1528,40 +1646,40 @@ LmotommuA: #if defined(M68040) ENTRY(ICPL) - movl sp@(4),a0 | address - .word 0xf488 | cinvl ic,a0@ + movl sp@(4),a0 | address + .word 0xf488 | cinvl ic,a0@ rts ENTRY(ICPP) - movl sp@(4),a0 | address - .word 0xf490 | cinvp ic,a0@ + movl sp@(4),a0 | address + .word 0xf490 | cinvp ic,a0@ rts ENTRY(DCPL) - movl sp@(4),a0 | address - .word 0xf448 | cinvl dc,a0@ + movl sp@(4),a0 | address + .word 0xf448 | cinvl dc,a0@ rts ENTRY(DCPP) - movl sp@(4),a0 | address - .word 0xf450 | cinvp dc,a0@ + movl sp@(4),a0 | address + .word 0xf450 | cinvp dc,a0@ rts ENTRY(DCPA) - .word 0xf458 | cinva dc + .word 0xf458 | cinva dc rts ENTRY(DCFL) - movl sp@(4),a0 | address - .word 0xf468 | cpushl dc,a0@ + movl sp@(4),a0 | address + .word 0xf468 | cpushl dc,a0@ rts ENTRY(DCFP) - movl sp@(4),a0 | address - .word 0xf470 | cpushp dc,a0@ + movl sp@(4),a0 | address + .word 0xf470 | cpushp dc,a0@ rts #endif ENTRY(PCIA) #if defined(M68040) ENTRY(DCFA) - cmpl #-2,_mmutype | 68040 - jne LmotommuB | no, skip - .word 0xf478 | cpusha dc + cmpl #MMU_68040,_mmutype | 68040 + jne LmotommuB | no, skip + .word 0xf478 | cpusha dc rts LmotommuB: #endif @@ -1600,15 +1718,17 @@ _getdfc: */ ENTRY(loadustp) movl sp@(4),d0 | new USTP - moveq #PGSHIFT, d1 + moveq #PGSHIFT,d1 lsll d1,d0 | convert to addr #if defined(M68040) - cmpl #-2,_mmutype | 68040? - jne LmotommuC | no, skip - .long 0x4e7b0806 | movc d0,urp + cmpl #MMU_68040,_mmutype | 68040? + jne LmotommuC | no, skip + .word 0xf518 | pflusha XXX TDR + .long 0x4e7b0806 | movc d0,urp rts LmotommuC: #endif + pflusha | XXX TDR lea _protorp,a0 | CRP prototype movl d0,a0@(4) | stash USTP pmove a0@,crp | load root pointer @@ -1761,33 +1881,72 @@ Lm68881rdone: /* * Handle the nitty-gritty of rebooting the machine. * Basically we just turn off the MMU and jump to the appropriate ROM routine. + * XXX add support for rebooting -- that means looking at boothowto and doing + * the right thing */ .globl _doboot _doboot: + lea tmpstk,sp | physical SP in case of NMI #if defined(M68040) - cmpl #-2,_mmutype | 68040? - jeq Lnocache5 | yes, skip + cmpl #MMU_68040,_mmutype | 68040? + jne Lbootnot040 | no, skip + movl #0,d0 + movc d0,cacr | caches off + .long 0x4e7b0003 | movc d0,tc (turn off MMU) + bra 1f +Lbootnot040: #endif movl #CACHE_OFF,d0 movc d0,cacr | disable on-chip cache(s) -Lnocache5: - movl _boothowto,d1 | load howto - movl _bootdev,d0 | and devtype - movl sp@(4),d1 | arg - lea tmpstk,sp | physical SP in case of NMI - movl #0,a7@- | value for pmove to TC (turn off MMU) + movl #0,a7@ | value for pmove to TC (turn off MMU) pmove a7@,tc | disable MMU - movl #0, d0 + +1: movl #0,d0 movc d0,vbr | ROM VBR - cmpl #0, d1 | autoboot? - jeq Lauto | yes - jmp 0x4000 | back to sboot -Lauto: jmp 0x400a | tell sboot to reboot us + + /* + * We're going down. Make various sick attempts to reset the board. + */ + RELOC(_cputyp, a0) + movl a0@,d0 + cmpw #CPU_147,d0 + bne not147 + movl #0xfffe2000,a0 | MVME147: "struct vme1reg *" + movw a0@,d0 + movl d0,d1 + andw #0x0001,d1 | is VME1_SCON_SWITCH set? + beq 1f | not SCON. may not use SRESET. + orw #0x0002,d0 | ok, assert VME1_SCON_SRESET + movw d0,a0@ +1: + movl #0xff800000,a0 | if we get here, SRESET did not work. + movl a0@(4),a0 | try jumping directly to the ROM. + jsr a0@ + | still alive! just return to the prom.. + bra 3f + +not147: + movl #0xfff40000,a0 | MVME16x: "struct vme2reg *" + movl a0@(60),d0 + movl d0,d1 + andl #0x40000000,d1 | is VME2_TCTL_SCON set? + beq 1f | not SCON. may not use SRESET. + orw #0x00800000,d0 | ok, assert VME2_TCTL_SRST + movl d0,a0@(60) +1: + movl #0xff800000,a0 | if we get here, SRESET did not work. + movl a0@(4),a0 | try jumping directly to the ROM. + jsr a0@ + | still alive! just return to the prom.. + +3: trap #15 + .short MVMEPROM_EXIT | return to m68kbug + /*NOTREACHED*/ .data .globl _mmutype,_protorp _mmutype: - .long -1 | default to MMU_68030 + .long MMU_68030 | default to MMU_68030 _protorp: .long 0,0 | prototype root pointer .globl _cold @@ -1796,7 +1955,7 @@ _cold: .globl _want_resched _want_resched: .long 0 - .globl _intiobase, _intiolimit, _extiobase, _RTCbase + .globl _intiobase, _intiolimit, _extiobase .globl _proc0paddr _proc0paddr: .long 0 | KVA of proc0 u-area @@ -1830,3 +1989,5 @@ _eintrnames: _intrcnt: .long 0,0,0,0,0,0,0,0,0,0 _eintrcnt: + +#include <mvme68k/mvme68k/vectors.s> |