summaryrefslogtreecommitdiff
path: root/sys/arch/hp300/hp300/locore.s
diff options
context:
space:
mode:
Diffstat (limited to 'sys/arch/hp300/hp300/locore.s')
-rw-r--r--sys/arch/hp300/hp300/locore.s1861
1 files changed, 0 insertions, 1861 deletions
diff --git a/sys/arch/hp300/hp300/locore.s b/sys/arch/hp300/hp300/locore.s
deleted file mode 100644
index 59d442fc97d..00000000000
--- a/sys/arch/hp300/hp300/locore.s
+++ /dev/null
@@ -1,1861 +0,0 @@
-/* $OpenBSD: locore.s,v 1.73 2013/06/30 23:47:07 miod Exp $ */
-/* $NetBSD: locore.s,v 1.91 1998/11/11 06:41:25 thorpej Exp $ */
-
-/*
- * Copyright (c) 1997 Theo de Raadt
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
- * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * Copyright (c) 1994, 1995 Gordon W. Ross
- * Copyright (c) 1988 University of Utah.
- * Copyright (c) 1980, 1990, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * the Systems Programming Group of the University of Utah Computer
- * Science Department.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * from: Utah $Hdr: locore.s 1.66 92/12/22$
- *
- * @(#)locore.s 8.6 (Berkeley) 5/27/94
- */
-
-#include "assym.h"
-#include <machine/asm.h>
-#include <machine/trap.h>
-
-#include "audio.h"
-#include "ksyms.h"
-#ifdef USELEDS
-#include <hp300/hp300/leds.h>
-#endif
-#include <hp300/dev/dioreg.h>
-#include <hp300/dev/diofbreg.h>
-
-#include "sgc.h"
-#if NSGC > 0
-#include <hp300/dev/sgcreg.h>
-#endif
-
-#define SYSFLAG 0xfffffed2
-
-#define MMUADDR(ar) movl _C_LABEL(MMUbase),ar
-#define CLKADDR(ar) movl _C_LABEL(CLKbase),ar
-
-/*
- * This is for kvm_mkdb, and should be the address of the beginning
- * of the kernel text segment (not necessarily the same as kernbase).
- */
- .chip 68020
- .text
-GLOBAL(kernel_text)
-
-/*
- * Clear and skip the first page of text; it will not be mapped.
- */
- .fill NBPG/4,4,0
-
-/*
- * Temporary stack for a variety of purposes.
- * Try and make this the first thing in the data segment so it
- * is page aligned. Note that if we overflow here, we run into
- * our text segment.
- */
- .data
- .space NBPG
-ASLOCAL(tmpstk)
-
-#include <hp300/hp300/vectors.s>
-
-/*
- * Macro to relocate a symbol, used before MMU is enabled.
- */
-#ifdef __STDC__
-#define RELOC(var, ar) \
- moveal #_C_LABEL(var),ar; \
- addl %a5,ar
-#define ASRELOC(var, ar) \
- moveal #_ASM_LABEL(var),ar; \
- addl %a5,ar
-#else
-#define _RELOC(var, ar) \
- movel #var,ar; \
- addl %a5,ar
-#define RELOC(var, ar) _RELOC(_C_LABEL(var), ar)
-#define ASRELOC(var, ar) _RELOC(_ASM_LABEL(var), ar)
-#endif
-
-/*
- * Final bits of grunt work required to reboot the system. The MMU
- * must be disabled when this is invoked.
- */
-#define DOREBOOT \
- /* Reset Vector Base Register to what PROM expects. */ \
- movl #0,%d0; \
- movc %d0,%vbr; \
- /* Jump to REQ_REBOOT */ \
- jmp 0x1A4;
-
-/*
- * Initialization
- *
- * A4 contains the address of the end of the symtab
- * A5 contains physical load point from boot
- * VBR contains zero from ROM. Exceptions will continue to vector
- * through ROM until MMU is turned on at which time they will vector
- * through our table (vectors.s).
- */
-
-BSS(lowram,4)
-BSS(esym,4)
-
-ASENTRY_NOPROFILE(start)
- movw #PSL_HIGHIPL,%sr | no interrupts
- ASRELOC(tmpstk, %a0)
- movl %a0,%sp | give ourselves a temporary stack
- RELOC(esym, %a0)
- movl %a4,%a0@ | store end of symbol table
- 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)
-
- /* check for internal HP-IB in SYSFLAG */
- btst #5,SYSFLAG | internal HP-IB?
- jeq Lhaveihpib | yes, have HP-IB just continue
- RELOC(internalhpib, %a0)
- movl #0,%a0@ | no, clear associated address
-Lhaveihpib:
-
- RELOC(boothowto, %a0) | save reboot flags
- movl %d7,%a0@
- RELOC(bootdev, %a0) | and boot device
- movl %d6,%a0@
-
- /*
- * All data registers are now free. All address registers
- * except a5 are free. a5 is used by the RELOC() macro,
- * and cannot be used until after the MMU is enabled.
- */
-
-/* determine our CPU/MMU combo - check for all regardless of kernel config */
- movl #INTIOBASE+MMUBASE,%a1
- 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
-
- /*
- * 68030 models
- */
-
- RELOC(mmutype, %a0) | no, we have 68030
- movl #MMU_68030,%a0@ | set to reflect 68030 PMMU
- RELOC(cputype, %a0)
- movl #CPU_68030,%a0@ | and 68030 CPU
- RELOC(machineid, %a0)
- movl #0x80,%a1@(MMUCMD) | set magic cookie
- movl %a1@(MMUCMD),%d0 | read it back
- btst #7,%d0 | cookie still on?
- jeq Lnot370 | no, 360 or 375
- movl #0,%a1@(MMUCMD) | clear magic cookie
- movl %a1@(MMUCMD),%d0 | read it back
- btst #7,%d0 | still on?
- jeq Lisa370 | no, must be a 370
- movl #HP_340,%a0@ | yes, must be a 340
- jra Lstart1
-Lnot370:
- movl #HP_36X,%a0@ | type is at least a 360
- movl #0,%a1@(MMUCMD) | clear magic cookie2
- movl %a1@(MMUCMD),%d0 | read it back
- btst #16,%d0 | still on?
- jeq Lisa36x | no, must be a 360 or a 362
- RELOC(mmuid, %a0) | save MMU ID
- lsrl #MMUID_SHIFT,%d0
- andl #MMUID_MASK,%d0
- movl %d0,%a0@
- RELOC(machineid, %a0)
- cmpb #MMUID_345,%d0 | are we a 345?
- beq Lisa345
- cmpb #MMUID_375,%d0 | how about a 375?
- beq Lisa375
- movl #HP_400,%a0@ | must be a 400
- jra Lhaspac
-Lisa345:
- movl #HP_345,%a0@
- jra Lhaspac
-Lisa375:
- movl #HP_375,%a0@
- jra Lhaspac
-Lisa370:
- movl #HP_370,%a0@ | set to 370
-Lhaspac:
- RELOC(ectype, %a0)
- movl #EC_PHYS,%a0@ | also has a physical address cache
- jra Lstart1
-
- /*
- * End of 68030 section
- */
-
-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 #CACHE40_OFF,%d0 | now turn it back off
- movc %d0,%cacr | before we access any data
-
- /*
- * 68040 models
- */
-
- RELOC(mmutype, %a0)
- movl #MMU_68040,%a0@ | with a 68040 MMU
- RELOC(cputype, %a0)
- movl #CPU_68040,%a0@ | and a 68040 CPU
- RELOC(fputype, %a0)
- movl #FPU_68040,%a0@ | ...and FPU
- RELOC(ectype, %a0)
- movl #EC_NONE,%a0@ | and no cache (for now XXX)
- RELOC(mmuid, %a0)
- movl %a1@(MMUCMD),%d0 | read MMU register
- lsrl #MMUID_SHIFT,%d0
- andl #MMUID_MASK,%d0
- movl %d0,%a0@ | save MMU ID
- RELOC(machineid, %a0)
- cmpb #MMUID_425_T,%d0 | are we a 425t?
- jeq Lisa425
- cmpb #MMUID_425_S,%d0 | how about 425s?
- jeq Lisa425
- cmpb #MMUID_425_E,%d0 | or maybe a 425e?
- jeq Lisa425
- cmpb #MMUID_433_T,%d0 | or a 433t?
- jeq Lisa433
- cmpb #MMUID_433_S,%d0 | maybe a 433s?
- jeq Lisa433
- cmpb #MMUID_385,%d0 | then a 385?
- jeq Lisa385
- cmpb #MMUID_382,%d0 | last chance...
- jeq Lisa382
- movl #HP_380,%a0@ | guess we're a 380
- jra Lstart1
-Lisa425:
- movl #HP_425,%a0@
- jra Lstart1
-Lisa433:
- movl #HP_433,%a0@
- jra Lstart1
-Lisa385:
- movl #HP_385,%a0@
- jra Lstart1
-Lisa382:
- movl #HP_382,%a0@
- jra Lstart1
-
- /*
- * End of 68040 section
- */
-
- /*
- * 68020 models
- */
-
-Lis68020:
- RELOC(fputype, %a0) | all of the 68020 systems
- movl #FPU_68881,%a0@ | have a 68881 FPU
- movl #1,%a1@(MMUCMD) | a 68020, write HP MMU location
- movl %a1@(MMUCMD),%d0 | read it back
- btst #0,%d0 | non-zero?
- jne Lunsupp | yes, we have HP MMU
- RELOC(mmutype, %a0)
- movl #MMU_68851,%a0@ | no, we have PMMU
- RELOC(machineid, %a0)
- movl #HP_330,%a0@ | and 330 CPU
- jra Lstart1
-
- /*
- * End of 68020 section
- */
-
-Lisa36x:
- /*
- * There is currently no easy way of telling a 362 and a 360
- * apart, except perhaps checking for the 362 frame buffer if
- * it isn't disabled.
- */
- /* FALLTHROUGH */
-
-Lstart1:
- /*
- * Now we need to know how much space the external I/O map has to be.
- * This has to be done before pmap_bootstrap() is invoked, but since
- * we are not running in virtual mode and will cause several bus
- * errors while probing, it is easier to do this before setting up
- * our own vectors table.
- */
- clrl %d3
-
- /*
- * Don't probe the DIO-I space, simply assume the whole 0-31
- * select code range is taken, i.e. 32 boards.
- */
- addl #(DIO_DEVSIZE * 32), %d3
-
- /*
- * Check the ``internal'' frame buffer address. If there is one,
- * assume an extra 2MB of frame buffer memory at 0x200000.
- */
- movl #GRFIADDR, %a0
- ASRELOC(phys_badaddr, %a3)
- jbsr %a3@
- tstl %d0 | success?
- jne dioiicheck | no, skip
- movl #0x200000, %d1 | yes, add the 200000-400000 range
- addl %d1, %d3
-
- /*
- * Probe for DIO-II devices, select codes 132 to 255.
- */
-dioiicheck:
- RELOC(machineid,%a0)
- cmpl #HP_320,%a0@
- jeq eiodone | HP 320 has nothing more
-
- movl #DIOII_SCBASE, %d2 | our select code...
- movl #DIOII_BASE, %a0 | and first address
-dioloop:
- ASRELOC(phys_badaddr, %a3)
- jbsr %a3@ | probe address (read ID)
- movl #DIOII_DEVSIZE, %d1
- tstl %d0 | success?
- jne 1f | no, skip
- addl %d1, %d3 | yes, count it
-1:
- addl %d1, %a0 | next slot address...
- addql #1, %d2 | and slot number
- cmpl #256, %d2
- jne dioloop
-
-#if NSGC > 0
- /*
- * Probe for SGC devices, slots 0 to 3.
- * Only do the probe on machines which might have an SGC bus.
- */
- RELOC(machineid,%a0)
- cmpl #HP_400,%a0@
- jeq sgcprobe
- cmpl #HP_425,%a0@
- jeq sgcprobe
- cmpl #HP_433,%a0@
- jne eiodone
-sgcprobe:
- clrl %d2 | first slot...
- movl #SGC_BASE, %a0 | and first address
-sgcloop:
- ASRELOC(phys_badaddr, %a3)
- jbsr %a3@ | probe address
- movl #SGC_DEVSIZE, %d1
- tstl %d0 | success?
- jne 2f | no, skip
- addl %d1, %d3 | yes, count it
-2:
- addl %d1, %a0 | next slot address...
- addql #1, %d2 | and slot number
- cmpl #SGC_NSLOTS, %d2
- jne sgcloop
-#endif
-
-eiodone:
- moveq #PGSHIFT, %d2
- lsrl %d2, %d3 | convert from bytes to pages
- RELOC(eiomapsize,%a2)
- addql #1, %d3 | add an extra page for device probes
- movl %d3,%a2@
-
- /*
- * Now that we know what CPU we have, initialize the address error
- * and bus error handlers in the vector table:
- *
- * vectab+8 bus error
- * vectab+12 address error
- */
- RELOC(cputype, %a0)
- RELOC(vectab, %a2)
-#if defined(M68040)
- cmpl #CPU_68040,%a0@ | 68040?
- jne 1f | no, skip
- movl #_C_LABEL(buserr40),%a2@(8)
- movl #_C_LABEL(addrerr4060),%a2@(12)
- jra Lstart2
-1:
-#endif
-#if defined(M68020) || defined(M68030)
- cmpl #CPU_68040,%a0@ | 68040?
- jeq 1f | yes, skip
- movl #_C_LABEL(busaddrerr2030),%a2@(8)
- movl #_C_LABEL(busaddrerr2030),%a2@(12)
- jra Lstart2
-1:
-#endif
-Lunsupp:
- /* Config botch; no hope. */
- DOREBOOT
-
-Lstart2:
-/* 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 size (for pmap_bootstrap) */
- movl #MAXADDR,%d1 | last page
- movl %a5,%d0 | lowram value from ROM via boot
- moveq #PGSHIFT,%d2
- subl %d0,%d1 | compute amount of RAM present
- lsrl %d2,%d1 | convert to pages
- addl #3,%d1 | restore the 3 pages lost (2 from
- | the bootloader and the MAXADDR one)
- RELOC(physmem, %a0)
- movl %d1,%a0@ | save as physmem
-
-/* configure kernel and proc0 VA space so we can get going */
-#if defined(DDB) || NKSYMS > 0
- RELOC(esym,%a0) | end of static kernel test/data/syms
- movl %a0@,%d5
- jne Lstart3
-#endif
- movl #_C_LABEL(end),%d5 | end of static kernel text/data
-Lstart3:
- addl #NBPG-1,%d5
- andl #PG_FRAME,%d5 | round to a page
- movl %d5,%a4
- addl %a5,%a4 | convert to PA
- pea %a5@ | firstpa
- pea %a4@ | nextpa
- RELOC(pmap_bootstrap,%a0)
- jbsr %a0@ | pmap_bootstrap(firstpa, nextpa)
- addql #8,%sp
-
-/*
- * While still running physical, override copypage() with the 68040
- * optimized version, copypage040(), if possible.
- * This relies upon the fact that copypage() immediately follows
- * copypage040() in memory.
- */
- RELOC(mmutype, %a0)
- cmpl #MMU_68040,%a0@
- jgt Lmmu_enable
- RELOC(copypage040, %a0)
- RELOC(copypage, %a1)
- movl %a1, %a2
-1:
- movw %a0@+, %a2@+
- cmpl %a0, %a1
- jgt 1b
-
-/*
- * Prepare to enable MMU.
- * Since the kernel is not mapped logical == physical we must insure
- * that when the MMU is turned on, all prefetched addresses (including
- * the PC) are valid. In order to guarantee that, we use the last physical
- * page (which is conveniently mapped == VA) and load it up with enough
- * code to defeat the prefetch, then we execute the jump back to here.
- *
- * Is this all really necessary, or am I paranoid??
- */
-Lmmu_enable:
- 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
- .chip 68040
- movc %d1,%srp
- .chip 68020
- jra Lstploaddone
-Lmotommu1:
- ASRELOC(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:
- lea MAXADDR,%a2 | PA of last RAM page
- ASRELOC(Lhighcode, %a1) | addr of high code
- ASRELOC(Lehighcode, %a3) | end addr
-Lcodecopy:
- movw %a1@+,%a2@+ | copy a word
- cmpl %a3,%a1 | done yet?
- jcs Lcodecopy | no, keep going
- jmp MAXADDR | go for it!
-
- /*
- * BEGIN MMU TRAMPOLINE. This section of code is not
- * executed in-place. It's copied to the last page
- * of RAM (mapped va == pa) and executed there.
- */
-
-Lhighcode:
- /*
- * Set up the vector table, and race to get the MMU
- * enabled.
- */
- movl #_C_LABEL(vectab),%d0 | set Vector Base Register
- movc %d0,%vbr
-
- RELOC(mmutype, %a0)
- cmpl #MMU_68040,%a0@ | 68040?
- jne Lmotommu2 | no, skip
- .chip 68040
- movw #0,INTIOBASE+MMUBASE+MMUCMD+2
- movw #MMU_IEN+MMU_CEN+MMU_FPE,INTIOBASE+MMUBASE+MMUCMD+2
- | enable FPU and caches
- moveq #0,%d0 | ensure TT regs are disabled
- movc %d0,%itt0
- movc %d0,%itt1
- movc %d0,%dtt1
-
- /*
- * Set up transparent translation for supervisor data access.
- * The range 0xc0000000-0xffffffff will not be translated, and
- * thus yields a 1:1 mapping of the physical memory in the top
- * of the address space (as long as we don't have more than
- * 1GB of memory, which will be very unlikely...)
- */
- movl #0xc03fa020,%d0
- movc %d0,%dtt0
-
- cinva %bc
- pflusha
- movl #0x8000,%d0
- movc %d0,%tc
- movl #CACHE40_ON,%d0
- movc %d0,%cacr | turn on both caches
- jmp Lenab1:l | forced to not be pc-relative
- .chip 68020
-Lmotommu2:
- cmpl #MMU_68030,%a0@ | 68030?
- jne Lmotommu2b | no, skip
- .chip 68030
- /*
- * Set up transparent translation for supervisor data access
- * (FC == 5), similar to the 68040 logic above.
- */
- ASRELOC(mmuscratch, %a2)
- movl #0xc03f8150,%a2@ | build our TT0 value
- pmove %a2@,%tt0
- .chip 68020
-Lmotommu2b:
- movl #MMU_IEN+MMU_FPE,INTIOBASE+MMUBASE+MMUCMD
- | enable MMU and i-cache
- ASRELOC(mmuscratch, %a2)
- movl #0x82c0aa00,%a2@ | value to load TC with
- pmove %a2@,%tc | load it
- jmp Lenab1:l | forced to not be pc-relative
-Lehighcode:
-
- /*
- * END MMU TRAMPOLINE. Address register a5 is now free.
- */
-
-/*
- * Should be running mapped from this point on
- */
-Lenab1:
-/* select the software page size now */
- lea _ASM_LABEL(tmpstk),%sp | temporary stack
- jbsr _C_LABEL(uvm_setpagesize) | select software page size
-/* set kernel stack, user SP, and initial pcb */
- movl _C_LABEL(proc0paddr),%a1 | get proc0 pcb addr
- lea %a1@(USPACE-4),%sp | set kernel stack to end of area
- lea _C_LABEL(proc0),%a2 | initialize proc0.p_addr so that
- movl %a1,%a2@(P_ADDR) | we don't deref NULL in trap()
- movl #USRSTACK-4,%a2
- movl %a2,%usp | init user SP
- movl %a1,_C_LABEL(curpcb) | proc0 is running
-
- tstl _C_LABEL(fputype) | Have an FPU?
- jeq Lenab2 | No, skip.
- clrl %a1@(PCB_FPCTX) | ensure null FP context
- movl %a1,%sp@-
- jbsr _C_LABEL(m68881_restore) | restore it (does not kill a1)
- addql #4,%sp
-Lenab2:
-/* flush TLB and turn on caches */
- jbsr _ASM_LABEL(TBIA) | invalidate TLB
- cmpl #MMU_68040,_C_LABEL(mmutype) | 68040?
- jeq Lnocache0 | yes, cache already on
- movl #CACHE_ON,%d0
- movc %d0,%cacr | clear cache(s)
- tstl _C_LABEL(ectype)
- jeq Lnocache0
- MMUADDR(%a0)
- orl #MMU_CEN,%a0@(MMUCMD) | turn on external cache
-Lnocache0:
-/* Final setup for call to main(). */
- jbsr _C_LABEL(hp300_init)
-
-/*
- * Create a fake exception frame so that cpu_fork() can copy it.
- * main() never 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 _C_LABEL(proc0),%a0 | save pointer to frame
- movl %sp,%a0@(P_MD_REGS) | in proc0.p_md.md_regs
-
- jra _C_LABEL(main) | main()
- PANIC("main() returned")
- /* NOTREACHED */
-
-/*
- * proc_trampoline: call function in register a2 with a3 as an arg
- * and then rei.
- */
-GLOBAL(proc_trampoline)
- movl %a3,%sp@- | push function arg
- jbsr %a2@ | call function
- addql #4,%sp | pop arg
- 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 _ASM_LABEL(rei) | and return
-
-
-/*
- * Trap/interrupt vector routines
- */
-#include <m68k/m68k/trap_subr.s>
-
- .data
-GLOBAL(m68k_fault_addr)
- .long 0
-
-#if defined(M68040)
-ENTRY_NOPROFILE(addrerr4060)
- clrl %sp@- | stack adjust count
- moveml #0xFFFF,%sp@- | save user registers
- movl %usp,%a0 | save the user SP
- movl %a0,%sp@(FR_SP) | in the savearea
- movl %sp@(FR_HW+8),%sp@-
- clrl %sp@- | dummy code
- movl #T_ADDRERR,%sp@- | mark address error
- jra _ASM_LABEL(faultstkadj) | and deal with it
-
-ENTRY_NOPROFILE(buserr40)
- clrl %sp@- | stack adjust count
- moveml #0xFFFF,%sp@- | save user registers
- movl %usp,%a0 | save the user SP
- movl %a0,%sp@(FR_SP) | in the savearea
- movl %sp@(FR_HW+20),%d1 | get fault address
- moveq #0,%d0
- movw %sp@(FR_HW+12),%d0 | get SSW
- btst #11,%d0 | check for mis-aligned
- jeq Lbe1stpg | no skip
- addl #3,%d1 | get into next page
- andl #PG_FRAME,%d1 | and truncate
-Lbe1stpg:
- movl %d1,%sp@- | pass fault address.
- movl %d0,%sp@- | pass SSW as code
- btst #10,%d0 | test ATC
- jeq Lberr40 | it is a bus error
- movl #T_MMUFLT,%sp@- | show that we are an MMU fault
- jra _ASM_LABEL(faultstkadj) | and deal with it
-Lberr40:
- tstl _C_LABEL(nofault) | catch bus error?
- jeq Lisberr | no, handle as usual
- movl %sp@(FR_HW+8+20),_C_LABEL(m68k_fault_addr) | save fault addr
- movl _C_LABEL(nofault),%sp@- | yes,
- jbsr _C_LABEL(longjmp) | longjmp(nofault)
- /* NOTREACHED */
-#endif
-
-#if defined(M68020) || defined(M68030)
-ENTRY_NOPROFILE(busaddrerr2030)
- clrl %sp@- | stack adjust count
- moveml #0xFFFF,%sp@- | save user registers
- movl %usp,%a0 | save the user SP
- movl %a0,%sp@(FR_SP) | in the savearea
- moveq #0,%d0
- movw %sp@(FR_HW+10),%d0 | grab SSW for fault processing
- btst #12,%d0 | RB set?
- jeq LbeX0 | no, test RC
- bset #14,%d0 | yes, must set FB
- movw %d0,%sp@(FR_HW+10) | for hardware too
-LbeX0:
- btst #13,%d0 | RC set?
- jeq LbeX1 | no, skip
- bset #15,%d0 | yes, must set FC
- movw %d0,%sp@(FR_HW+10) | for hardware too
-LbeX1:
- btst #8,%d0 | data fault?
- jeq Lbe0 | no, check for hard cases
- movl %sp@(FR_HW+16),%d1 | fault address is as given in frame
- jra Lbe10 | thats it
-Lbe0:
- btst #4,%sp@(FR_HW+6) | long (type B) stack frame?
- jne Lbe4 | yes, go handle
- movl %sp@(FR_HW+2),%d1 | no, can use save PC
- btst #14,%d0 | FB set?
- jeq Lbe3 | no, try FC
- addql #4,%d1 | yes, adjust address
- jra Lbe10 | done
-Lbe3:
- btst #15,%d0 | FC set?
- jeq Lbe10 | no, done
- addql #2,%d1 | yes, adjust address
- jra Lbe10 | done
-Lbe4:
- movl %sp@(FR_HW+36),%d1 | long format, use stage B address
- btst #15,%d0 | FC set?
- jeq Lbe10 | no, all done
- subql #2,%d1 | yes, adjust address
-Lbe10:
- movl %d1,%sp@- | push fault VA
- movl %d0,%sp@- | and padded SSW
- movw %sp@(FR_HW+8+6),%d0 | get frame format/vector offset
- andw #0x0FFF,%d0 | clear out frame format
- cmpw #12,%d0 | address error vector?
- jeq Lisaerr | yes, go to it
- movl %d1,%a0 | fault address
- movl %sp@,%d0 | function code from ssw
- btst #8,%d0 | data fault?
- jne Lbe10a
- movql #1,%d0 | user program access FC
- | (we dont separate data/program)
- btst #5,%sp@(FR_HW+8) | supervisor mode?
- jeq Lbe10a | if no, done
- movql #5,%d0 | else supervisor program access
-Lbe10a:
- ptestr %d0,%a0@,#7 | do a table search
- pmove %psr,%sp@ | save result
- movb %sp@,%d1
- btst #2,%d1 | invalid (incl. limit viol. and berr)?
- jeq Lmightnotbemerr | no -> wp check
- btst #7,%d1 | is it MMU table berr?
- jne Lisberr1 | yes, needs not be fast.
-Lismerr:
- movl #T_MMUFLT,%sp@- | show that we are an MMU fault
- jra _ASM_LABEL(faultstkadj) | and deal with it
-Lmightnotbemerr:
- btst #3,%d1 | write protect bit set?
- jeq Lisberr1 | no: must be bus error
- movl %sp@,%d0 | ssw into low word of d0
- andw #0xc0,%d0 | Write protect is set on page:
- cmpw #0x40,%d0 | was it read cycle?
- jne Lismerr | no, was not WPE, must be MMU fault
- jra Lisberr1 | real bus err needs not be fast.
-Lisaerr:
- movl #T_ADDRERR,%sp@- | mark address error
- jra _ASM_LABEL(faultstkadj) | and deal with it
-Lisberr1:
- clrw %sp@ | re-clear pad word
- tstl _C_LABEL(nofault) | catch bus error?
- jeq Lisberr | no, handle as usual
- movl %sp@(FR_HW+8+16),_C_LABEL(m68k_fault_addr) | save fault addr
- movl _C_LABEL(nofault),%sp@- | yes,
- jbsr _C_LABEL(longjmp) | longjmp(nofault)
- /* NOTREACHED */
-#endif /* M68020 || M68030 */
-
-Lisberr: | also used by M68040/60
- movl #T_BUSERR,%sp@- | mark bus error
- jra _ASM_LABEL(faultstkadj) | and deal with it
-
-/*
- * FP exceptions.
- */
-ENTRY_NOPROFILE(fpfline)
-#if defined(M68040)
- cmpl #FPU_68040,_C_LABEL(fputype) | 68040 FPU?
- jne Lfp_unimp | no, skip FPSP
- cmpw #0x202c,%sp@(6) | format type 2?
- jne _C_LABEL(illinst) | no, not an FP emulation
-Ldofp_unimp:
-#ifdef FPSP
- jmp _ASM_LABEL(fpsp_unimp) | yes, go handle it
-#endif
-Lfp_unimp:
-#endif /* M68040 */
-#ifdef FPU_EMULATE
- clrl %sp@- | stack adjust count
- moveml #0xFFFF,%sp@- | save registers
- moveq #T_FPEMULI,%d0 | denote as FP emulation trap
- jra _ASM_LABEL(fault) | do it
-#else
- jra _C_LABEL(illinst)
-#endif
-
-ENTRY_NOPROFILE(fpunsupp)
-#if defined(M68040)
- cmpl #FPU_68040,_C_LABEL(fputype) | 68040 FPU?
- jne _C_LABEL(illinst) | no, treat as illinst
-#ifdef FPSP
- jmp _ASM_LABEL(fpsp_unsupp) | yes, go handle it
-#endif
-Lfp_unsupp:
-#endif /* M68040 */
-#ifdef FPU_EMULATE
- clrl %sp@- | stack adjust count
- moveml #0xFFFF,%sp@- | save registers
- moveq #T_FPEMULD,%d0 | denote as FP emulation trap
- jra _ASM_LABEL(fault) | do it
-#else
- jra _C_LABEL(illinst)
-#endif
-
-/*
- * Handles all other FP coprocessor exceptions.
- * Note that since some FP exceptions generate mid-instruction frames
- * and may cause signal delivery, we need to test for stack adjustment
- * after the trap call.
- */
-ENTRY_NOPROFILE(fpfault)
- clrl %sp@- | stack adjust count
- moveml #0xFFFF,%sp@- | save user registers
- movl %usp,%a0 | and save
- movl %a0,%sp@(FR_SP) | the user stack pointer
- clrl %sp@- | no VA arg
- movl _C_LABEL(curpcb),%a0 | current pcb
- lea %a0@(PCB_FPCTX),%a0 | address of FP savearea
- fsave %a0@ | save state
-#if defined(M68040) || defined(M68060)
- /* always null state frame on 68040, 68060 */
- cmpl #FPU_68040,_C_LABEL(fputype)
- jge Lfptnull
-#endif
- tstb %a0@ | null state frame?
- jeq Lfptnull | yes, safe
- clrw %d0 | no, need to tweak BIU
- movb %a0@(1),%d0 | get frame size
- bset #3,%a0@(0,%d0:w) | set exc_pend bit of BIU
-Lfptnull:
- fmovem %fpsr,%sp@- | push fpsr as code argument
- frestore %a0@ | restore state
- movl #T_FPERR,%sp@- | push type arg
- jra _ASM_LABEL(faultstkadj) | call trap and deal with stack cleanup
-
-/*
- * Other exceptions only cause four and six word stack frame and require
- * no post-trap stack adjustment.
- */
-
-ENTRY_NOPROFILE(badtrap)
- moveml #0xC0C0,%sp@- | save scratch regs
- movw %sp@(22),%sp@- | push exception vector info
- clrw %sp@-
- movl %sp@(22),%sp@- | and PC
- jbsr _C_LABEL(straytrap) | report
- addql #8,%sp | pop args
- moveml %sp@+,#0x0303 | restore regs
- jra _ASM_LABEL(rei) | all done
-
-ENTRY_NOPROFILE(trap0)
- clrl %sp@- | stack adjust count
- moveml #0xFFFF,%sp@- | save user registers
- movl %usp,%a0 | save the user SP
- movl %a0,%sp@(FR_SP) | in the savearea
- movl %d0,%sp@- | push syscall number
- jbsr _C_LABEL(syscall) | handle it
- addql #4,%sp | pop syscall arg
- tstl _C_LABEL(astpending)
- jne Lrei2
- tstl _C_LABEL(softpending)
- jeq Ltrap1
- movw #SPL1,%sr
- tstl _C_LABEL(softpending)
- jne Lsir1
-Ltrap1:
- movl %sp@(FR_SP),%a0 | grab and restore
- movl %a0,%usp | user SP
- moveml %sp@+,#0x7FFF | restore most registers
- addql #8,%sp | pop SP and stack adjust
- rte
-
-/*
- * Trap 1 - sigreturn
- */
-ENTRY_NOPROFILE(trap1)
- jra _ASM_LABEL(sigreturn)
-
-/*
- * Trap 2 - trace trap
- */
-ENTRY_NOPROFILE(trap2)
- jra _C_LABEL(trace)
-
-/*
- * Trap 12 is the entry point for the cachectl "syscall"
- * cachectl(command, addr, length)
- * command in d0, addr in a1, length in d1
- */
-ENTRY_NOPROFILE(trap12)
- movl %d1,%sp@- | push length
- movl %a1,%sp@- | push addr
- movl %d0,%sp@- | push command
- movl CURPROC,%sp@- | push proc pointer
- jbsr _C_LABEL(cachectl) | do it
- lea %sp@(16),%sp | pop args
- jra _ASM_LABEL(rei) | all done
-
-/*
- * Trace (single-step) trap. Kernel-mode is special.
- * User mode traps are simply passed on to trap().
- */
-ENTRY_NOPROFILE(trace)
- clrl %sp@- | stack adjust count
- moveml #0xFFFF,%sp@-
- moveq #T_TRACE,%d0
-
- | Check PSW and see what happened.
- | T=0 S=0 (should not happen)
- | T=1 S=0 trace trap from user mode
- | T=0 S=1 trace trap on a trap instruction
- | T=1 S=1 trace trap from system mode (kernel breakpoint)
-
- movw %sp@(FR_HW),%d1 | get PSW
- notw %d1 | XXX no support for T0 on 680[234]0
- andw #PSL_TS,%d1 | from system mode (T=1, S=1)?
- jeq Lkbrkpt | yes, kernel breakpoint
- jra _ASM_LABEL(fault) | no, user-mode fault
-
-/*
- * Trap 15 is used for:
- * - GDB breakpoints (in user programs)
- * - KGDB breakpoints (in the kernel)
- * - trace traps for SUN binaries (not fully supported yet)
- * User mode traps are simply passed to trap().
- */
-ENTRY_NOPROFILE(trap15)
- clrl %sp@- | stack adjust count
- moveml #0xFFFF,%sp@-
- moveq #T_TRAP15,%d0
- movw %sp@(FR_HW),%d1 | get PSW
- andw #PSL_S,%d1 | from system mode?
- jne Lkbrkpt | yes, kernel breakpoint
- jra _ASM_LABEL(fault) | no, user-mode fault
-
-Lkbrkpt: | Kernel-mode breakpoint or trace trap. (d0=trap_type)
- | Save the system sp rather than the user sp.
- movw #PSL_HIGHIPL,%sr | lock out interrupts
- lea %sp@(FR_SIZE),%a6 | Save stack pointer
- movl %a6,%sp@(FR_SP) | from before trap
-
- | If we are not on tmpstk switch to it.
- | (so debugger can change the stack pointer)
- movl %a6,%d1
- cmpl #_ASM_LABEL(tmpstk),%d1
- jls Lbrkpt2 | already on tmpstk
- | Copy frame to the temporary stack
- movl %sp,%a0 | a0=src
- lea _ASM_LABEL(tmpstk)-96,%a1 | a1=dst
- movl %a1,%sp | sp=new frame
- moveq #FR_SIZE,%d1
-Lbrkpt1:
- movl %a0@+,%a1@+
- subql #4,%d1
- bgt Lbrkpt1
-
-Lbrkpt2:
- | Call the trap handler for the kernel debugger.
- | Do not call trap() to do it, so that we can
- | set breakpoints in trap() if we want. We know
- | the trap type is either T_TRACE or T_BREAKPOINT.
- | If we have both DDB and KGDB, let KGDB see it first,
- | because KGDB will just return 0 if not connected.
- | Save args in d2, a2
- movl %d0,%d2 | trap type
- movl %sp,%a2 | frame ptr
-#ifdef KGDB
- | Let KGDB handle it (if connected)
- movl %a2,%sp@- | push frame ptr
- movl %d2,%sp@- | push trap type
- jbsr _C_LABEL(kgdb_trap) | handle the trap
- addql #8,%sp | pop args
- cmpl #0,%d0 | did kgdb handle it?
- jne Lbrkpt3 | yes, done
-#endif
-#ifdef DDB
- | Let DDB handle it
- movl %a2,%sp@- | push frame ptr
- movl %d2,%sp@- | push trap type
- jbsr _C_LABEL(kdb_trap) | handle the trap
- addql #8,%sp | pop args
-#if 0 /* not needed on hp300 */
- cmpl #0,%d0 | did ddb handle it?
- jne Lbrkpt3 | yes, done
-#endif
-#endif
- /* Sun 3 drops into PROM here. */
-Lbrkpt3:
- | The stack pointer may have been modified, or
- | data below it modified (by kgdb push call),
- | so push the hardware frame at the current sp
- | before restoring registers and returning.
-
- movl %sp@(FR_SP),%a0 | modified sp
- lea %sp@(FR_SIZE),%a1 | end of our frame
- movl %a1@-,%a0@- | copy 2 longs with
- movl %a1@-,%a0@- | ... predecrement
- movl %a0,%sp@(FR_SP) | sp = h/w frame
- moveml %sp@+,#0x7FFF | restore all but sp
- movl %sp@,%sp | ... and sp
- rte | all done
-
-/*
- * Use common m68k sigreturn.
- */
-#include <m68k/m68k/sigreturn.s>
-
-/*
- * Interrupt handlers.
- * All device interrupts are auto-vectored. The CPU provides
- * the vector 0x18+level. Note we count spurious interrupts, but
- * we don't do anything else with them.
- */
-
-#define INTERRUPT_SAVEREG moveml #0xC0C0,%sp@-
-#define INTERRUPT_RESTOREREG moveml %sp@+,#0x0303
-
-ENTRY_NOPROFILE(spurintr) /* level 0 */
- addql #1,_C_LABEL(uvmexp)+UVMEXP_INTRS
- jra _ASM_LABEL(rei)
-
-ENTRY_NOPROFILE(intrhand) /* levels 2 through 5 */
- INTERRUPT_SAVEREG
- movw %sp@(22),%sp@- | push exception vector info
- clrw %sp@-
- jbsr _C_LABEL(intr_dispatch) | call dispatch routine
- addql #4,%sp
- INTERRUPT_RESTOREREG
- jra _ASM_LABEL(rei) | all done
-
-ENTRY_NOPROFILE(lev6intr) /* level 6: clock */
- INTERRUPT_SAVEREG
- CLKADDR(%a0)
- movb %a0@(CLKSR),%d0 | read clock status
-Lclkagain:
- btst #0,%d0 | clear timer1 int immediately to
- jeq Lnotim1 | minimize chance of losing another
- movpw %a0@(CLKMSB1),%d1 | due to statintr processing delay
- movl _C_LABEL(clkint),%d1 | clkcounter += clkint
- addl %d1,_C_LABEL(clkcounter)
-Lnotim1:
- btst #2,%d0 | timer3 interrupt?
- jeq Lnotim3 | no, skip statclock
- movpw %a0@(CLKMSB3),%d1 | clear timer3 interrupt
- lea %sp@(16),%a1 | a1 = &clockframe
- movl %d0,%sp@- | save status
- movl %a1,%sp@-
- jbsr _C_LABEL(statintr) | statintr(&frame)
- addql #4,%sp
- movl %sp@+,%d0 | restore pre-statintr status
- CLKADDR(%a0)
-Lnotim3:
- btst #0,%d0 | timer1 interrupt?
- jeq Lrecheck | no, skip hardclock
- lea %sp@(16),%a1 | a1 = &clockframe
- movl %a1,%sp@-
-#ifdef USELEDS
- tstl _C_LABEL(ledaddr) | using LEDs?
- jeq Lnoleds0 | no, skip this code
- movl _ASM_LABEL(heartbeat),%d0 | get tick count
- addql #1,%d0 | increment
- movl _C_LABEL(hz),%d1
- addl #50,%d1 | get the timing a little closer
- cmpl #0,_ASM_LABEL(beatstatus) | time to slow down?
- jeq Lslowthrob | yes, slow down
- lsrl #3,%d1 | no, fast throb
-Lslowthrob:
- lsrl #1,%d1 | slow throb
- cmpl %d0,%d1 | are we there yet?
- jne Lnoleds1 | no, nothing to do
- addl #1,_ASM_LABEL(beatstatus) | incr beat status
- cmpl #3,_ASM_LABEL(beatstatus) | time to reset?
- ble Ltwinkle | no, twinkle the lights
- movl #0,_ASM_LABEL(beatstatus) | reset the status indicator
-Ltwinkle:
- movl #LED_PULSE,%sp@-
- movl #LED_DISK+LED_LANRCV+LED_LANXMT,%sp@-
- clrl %sp@-
- jbsr _C_LABEL(ledcontrol) | toggle pulse, turn all others off
- lea %sp@(12),%sp
- movql #0,%d0
-Lnoleds1:
- movl %d0,_ASM_LABEL(heartbeat)
-Lnoleds0:
-#endif /* USELEDS */
- jbsr _C_LABEL(clockintr) | clockintr(&frame)
- addql #4,%sp
- CLKADDR(%a0)
-Lrecheck:
- addql #1,_C_LABEL(uvmexp)+UVMEXP_INTRS | chalk up another interrupt
- movb %a0@(CLKSR),%d0 | see if anything happened
- jmi Lclkagain | while we were in clockintr/statintr
-#if NAUDIO >0
- movw %sp@(22),%sp@- | push exception vector info
- clrw %sp@-
- jbsr _C_LABEL(intr_dispatch) | call dispatch routine
- addql #4,%sp
-#endif
- INTERRUPT_RESTOREREG
- jra _ASM_LABEL(rei) | all done
-
-ENTRY_NOPROFILE(lev7intr) /* level 7: parity errors, reset key */
- clrl %sp@-
- moveml #0xFFFF,%sp@- | save registers
- movl %usp,%a0 | and save
- movl %a0,%sp@(FR_SP) | the user stack pointer
- jbsr _C_LABEL(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 _ASM_LABEL(rei) | all done
-
-/*
- * Emulation of VAX REI instruction.
- *
- * This code deals with checking for and servicing ASTs
- * (profiling, scheduling) and software interrupts (network, softclock).
- * We check for ASTs first, just like the VAX. To avoid excess overhead
- * the T_ASTFLT handling code will also check for software interrupts so we
- * do not have to do it here. After identifing that we need an AST we
- * drop the IPL to allow device interrupts.
- *
- * This code is complicated by the fact that sendsig may have been called
- * necessitating a stack cleanup.
- */
-
-BSS(softpending,4)
-
-ASENTRY_NOPROFILE(rei)
- tstl _C_LABEL(astpending) | AST pending?
- jeq Lchksir | no, go check for SIR
-Lrei1:
- btst #5,%sp@ | yes, are we returning to user mode?
- jne Lchksir | no, go check for SIR
- movw #PSL_LOWIPL,%sr | lower SPL
- clrl %sp@- | stack adjust
- moveml #0xFFFF,%sp@- | save all registers
- movl %usp,%a1 | including
- movl %a1,%sp@(FR_SP) | the users SP
-Lrei2:
- clrl %sp@- | VA == none
- clrl %sp@- | code == none
- movl #T_ASTFLT,%sp@- | type == async system trap
- jbsr _C_LABEL(trap) | go handle it
- lea %sp@(12),%sp | pop value args
- movl %sp@(FR_SP),%a0 | restore user SP
- movl %a0,%usp | from save area
- movw %sp@(FR_ADJ),%d0 | need to adjust stack?
- jne Laststkadj | yes, go to it
- moveml %sp@+,#0x7FFF | no, restore most user regs
- addql #8,%sp | toss SP and stack adjust
- rte | and do real RTE
-Laststkadj:
- lea %sp@(FR_HW),%a1 | pointer to HW frame
- addql #8,%a1 | source pointer
- movl %a1,%a0 | source
- addw %d0,%a0 | + hole size = dest pointer
- movl %a1@-,%a0@- | copy
- movl %a1@-,%a0@- | 8 bytes
- movl %a0,%sp@(FR_SP) | new SSP
- moveml %sp@+,#0x7FFF | restore user registers
- movl %sp@,%sp | and our SP
- rte | and do real RTE
-Lchksir:
- tstl _C_LABEL(softpending) | SIR pending?
- jeq Ldorte | no, all done
- movl %d0,%sp@- | need a scratch register
- movw %sp@(4),%d0 | get SR
- andw #PSL_IPL7,%d0 | mask all but IPL
- jne Lnosir | came from interrupt, no can do
- movl %sp@+,%d0 | restore scratch register
-Lgotsir:
- movw #SPL1,%sr | prevent others from servicing int
- tstl _C_LABEL(softpending) | too late?
- jeq Ldorte | yes, oh well...
- clrl %sp@- | stack adjust
- moveml #0xFFFF,%sp@- | save all registers
- movl %usp,%a1 | including
- movl %a1,%sp@(FR_SP) | the users SP
-Lsir1:
- clrl %sp@- | VA == none
- clrl %sp@- | code == none
- movl #T_SSIR,%sp@- | type == software interrupt
- jbsr _C_LABEL(trap) | go handle it
- lea %sp@(12),%sp | pop value args
- movl %sp@(FR_SP),%a0 | restore
- movl %a0,%usp | user SP
- moveml %sp@+,#0x7FFF | and all remaining registers
- addql #8,%sp | pop SP and stack adjust
- rte
-Lnosir:
- movl %sp@+,%d0 | restore scratch register
-Ldorte:
- rte | real return
-
-/*
- * Use common m68k signal trampoline.
- */
-#include <m68k/m68k/sigcode.s>
-
-/*
- * Primitives
- */
-
-/*
- * Use common m68k support routines.
- */
-#include <m68k/m68k/support.s>
-
- .data
- .p2align 2
-GLOBAL(curpcb)
- .long 0
-
-ASBSS(nullpcb,SIZEOF_PCB)
-
-ENTRY_NOPROFILE(cpu_idle_cycle)
- stop #PSL_LOWIPL
- rts
-
-/*
- * cpu_switchto(struct proc *oldproc, struct proc *newproc)
- *
- * NOTE: On the mc68851 (318/319/330) we attempt to avoid flushing the
- * entire ATC. The effort involved in selective flushing may not be
- * worth it, maybe we should just flush the whole thing?
- *
- * NOTE 2: With the new VM layout we now no longer know if an inactive
- * user's PTEs have been changed (formerly denoted by the SPTECHG p_flag
- * bit). For now, we just always flush the full ATC.
- */
-ENTRY(cpu_switchto)
- movl %sp@(4), %d0 | oldproc
- beq Lswnofpsave | is NULL, don't save anything
-
- /*
- * Save state of previous process in its pcb.
- */
- movl _C_LABEL(curpcb),%a1
- movw %sr, %a1@(PCB_PS) | save sr before switching context
- moveml #0xFCFC,%a1@(PCB_REGS) | save non-scratch registers
- movl %usp,%a2 | grab USP (a2 has been saved)
- movl %a2,%a1@(PCB_USP) | and save it
-
- tstl _C_LABEL(fputype) | Do we have an FPU?
- jeq Lswnofpsave | No Then don't attempt save.
- lea %a1@(PCB_FPCTX),%a2 | pointer to FP save area
- fsave %a2@ | save FP state
- tstb %a2@ | null state frame?
- jeq Lswnofpsave | yes, all done
- fmovem %fp0-%fp7,%a2@(FPF_REGS) | save FP general registers
- fmovem %fpcr/%fpsr/%fpi,%a2@(FPF_FPCR) | save FP control registers
-
-Lswnofpsave:
- movl %sp@(8), %a0 | newproc
-
- movl %a0, CURPROC
- movb #SONPROC,%a0@(P_STAT)
- movl %a0@(P_ADDR),%a1 | get p_addr
- movl %a1,_C_LABEL(curpcb)
-
- /*
- * Activate process's address space.
- * XXX Should remember the last USTP value loaded, and call this
- * XXX only if it has changed.
- */
- pea %a0@ | push proc
- jbsr _C_LABEL(pmap_activate) | pmap_activate(p)
- addql #4,%sp
- movl _C_LABEL(curpcb),%a1 | restore p_addr
-
- lea _ASM_LABEL(tmpstk),%sp | now goto a tmp stack for NMI
-
- moveml %a1@(PCB_REGS),#0xFCFC | and registers
- movl %a1@(PCB_USP),%a0
- movl %a0,%usp | and USP
-
- tstl _C_LABEL(fputype) | If we don't have an FPU,
- jeq Lnofprest | don't try to restore it.
- lea %a1@(PCB_FPCTX),%a0 | pointer to FP save area
- tstb %a0@ | null state frame?
- jeq Lresfprest | yes, easy
-#if defined(M68040)
-#if defined(M68020) || defined(M68030)
- cmpl #MMU_68040,_C_LABEL(mmutype) | 68040?
- jne Lresnot040 | no, skip
-#endif
- clrl %sp@- | yes...
- frestore %sp@+ | ...magic!
-Lresnot040:
-#endif
- fmovem %a0@(FPF_FPCR),%fpcr/%fpsr/%fpi | restore FP control registers
- fmovem %a0@(FPF_REGS),%fp0-%fp7 | restore FP general registers
-Lresfprest:
- frestore %a0@ | restore state
-
-Lnofprest:
- movw %a1@(PCB_PS),%sr | no, restore PS
- moveq #1,%d0 | return 1 (for alternate returns)
- rts
-
-/*
- * savectx(pcb)
- * Update pcb, saving current processor state.
- */
-ENTRY(savectx)
- movl %sp@(4),%a1
- movw %sr,%a1@(PCB_PS)
- movl %usp,%a0 | grab USP
- movl %a0,%a1@(PCB_USP) | and save it
- moveml #0xFCFC,%a1@(PCB_REGS) | save non-scratch registers
-
- tstl _C_LABEL(fputype) | Do we have FPU?
- jeq Lsvnofpsave | No? Then don't save state.
- lea %a1@(PCB_FPCTX),%a0 | pointer to FP save area
- fsave %a0@ | save FP state
- tstb %a0@ | null state frame?
- jeq Lsvnofpsave | yes, all done
- fmovem %fp0-%fp7,%a0@(FPF_REGS) | save FP general registers
- fmovem %fpcr/%fpsr/%fpi,%a0@(FPF_FPCR) | save FP control registers
-Lsvnofpsave:
- moveq #0,%d0 | return 0
- rts
-
-#if defined(M68040)
-ENTRY(suline)
- movl %sp@(4),%a0 | address to write
- movl _C_LABEL(curpcb),%a1 | current pcb
- movl #Lslerr,%a1@(PCB_ONFAULT) | where to return to on a fault
- movl %sp@(8),%a1 | address of line
- movl %a1@+,%d0 | get lword
- movsl %d0,%a0@+ | put lword
- nop | sync
- movl %a1@+,%d0 | get lword
- movsl %d0,%a0@+ | put lword
- nop | sync
- movl %a1@+,%d0 | get lword
- movsl %d0,%a0@+ | put lword
- nop | sync
- movl %a1@+,%d0 | get lword
- movsl %d0,%a0@+ | put lword
- nop | sync
- moveq #0,%d0 | indicate no fault
- jra Lsldone
-Lslerr:
- moveq #-1,%d0
-Lsldone:
- movl _C_LABEL(curpcb),%a1 | current pcb
- clrl %a1@(PCB_ONFAULT) | clear fault address
- rts
-#endif
-
-/*
- * Invalidate entire TLB.
- */
-ASENTRY_NOPROFILE(TBIA)
-#if defined(M68040)
- cmpl #MMU_68040,_C_LABEL(mmutype) | 68040?
- jne Lmotommu3 | no, skip
- .chip 68040
- pflusha
- rts
-Lmotommu3:
- .chip 68020
-#endif
- pflusha | flush entire TLB
- tstl _C_LABEL(mmutype)
- jpl Lmc68851a | 68851 implies no d-cache
- movl #DC_CLEAR,%d0
- movc %d0,%cacr | invalidate on-chip d-cache
-Lmc68851a:
- rts
-
-/*
- * Invalidate any TLB entry for given VA (TB Invalidate Single)
- */
-ENTRY(TBIS)
-#if defined(M68040)
- cmpl #MMU_68040,_C_LABEL(mmutype) | 68040?
- jne Lmotommu4 | no, skip
- .chip 68040
- movl %sp@(4),%a0
- movc %dfc,%d1
- moveq #FC_USERD,%d0 | user space
- movc %d0,%dfc
- pflush %a0@
- moveq #FC_SUPERD,%d0 | super space
- movc %d0,%dfc
- pflush %a0@
- movc %d1,%dfc
- rts
- .chip 68020
-Lmotommu4:
-#endif
- movl %sp@(4),%a0 | get addr to flush
- tstl _C_LABEL(mmutype)
- jpl Lmc68851b | is 68851?
- pflush #0,#0,%a0@ | flush address from both sides
- movl #DC_CLEAR,%d0
- movc %d0,%cacr | invalidate on-chip data cache
- rts
-Lmc68851b:
- pflushs #0,#0,%a0@ | flush address from both sides
- rts
-
-/*
- * Invalidate instruction cache
- */
-ENTRY(ICIA)
-#if defined(M68040)
- cmpl #MMU_68040,_C_LABEL(mmutype) | 68040
- jne Lmotommu7 | no, skip
- .chip 68040
- cinva %ic
- rts
- .chip 68020
-Lmotommu7:
-#endif
- movl #IC_CLEAR,%d0
- movc %d0,%cacr | invalidate i-cache
- rts
-
-/*
- * Invalidate data cache.
- * HP external cache allows for invalidation of user/supervisor portions.
- * NOTE: we do not flush 68030 on-chip cache as there are no aliasing
- * problems with DC_WA. The only cases we have to worry about are context
- * switch and TLB changes, both of which are handled "in-line" in resume
- * and TBI*.
- */
-ENTRY(DCIA)
-#if defined(M68040)
- cmpl #MMU_68040,_C_LABEL(mmutype) | 68040
- jne Lmotommu8 | no, skip
- .chip 68040
- cpusha %dc
- rts
- .chip 68020
-Lmotommu8:
-#endif
- rts
-
-ENTRY(DCIS)
-#if defined(M68040)
- cmpl #MMU_68040,_C_LABEL(mmutype) | 68040
- jne Lmotommu9 | no, skip
- .chip 68040
- cpusha %dc
- rts
- .chip 68020
-Lmotommu9:
-#endif
- rts
-
-ENTRY(DCIU)
-#if defined(M68040)
- cmpl #MMU_68040,_C_LABEL(mmutype) | 68040
- jne LmotommuA | no, skip
- .chip 68040
- cpusha %dc
- rts
- .chip 68020
-LmotommuA:
-#endif
- rts
-
-#if defined(M68040) || defined(CACHE_HAVE_PAC)
-ENTRY(PCIA)
-#if defined(M68040)
- cmpl #MMU_68040,_C_LABEL(mmutype) | 68040
- jne LmotommuB | no, skip
- .chip 68040
- cpusha %dc
- rts
- .chip 68020
-LmotommuB:
-#endif
-#if defined(CACHE_HAVE_PAC)
- /*
- * On non-68040 machines, PCIA() will only get invoked if
- * ectype == EC_PHYS, thus we do not need to test anything.
- */
- movl #DC_CLEAR,%d0
- movc %d0,%cacr | invalidate on-chip d-cache
- MMUADDR(%a0)
- andl #~MMU_CEN,%a0@(MMUCMD) | disable cache in MMU control reg
- orl #MMU_CEN,%a0@(MMUCMD) | reenable cache in MMU control reg
- rts
-#endif
-#endif
-
-#if defined(M68040)
- .chip 68040
-ENTRY(ICPA)
- cinva %ic
- rts
-ENTRY(DCFA)
- cpusha %dc
- rts
-ENTRY(ICPL)
- movl %sp@(4),%a0 | address
- cinvl %ic,%a0@
- rts
-ENTRY(ICPP)
- movl %sp@(4),%a0 | address
- cinvp %ic,%a0@
- rts
-ENTRY(DCPL)
- movl %sp@(4),%a0 | address
- cinvl %dc,%a0@
- rts
-ENTRY(DCPP)
- movl %sp@(4),%a0 | address
- cinvp %dc,%a0@
- rts
-ENTRY(DCFL)
- movl %sp@(4),%a0 | address
- cpushl %dc,%a0@
- rts
-ENTRY(DCFP)
- movl %sp@(4),%a0 | address
- cpushp %dc,%a0@
- rts
- .chip 68020
-#endif
-
-ENTRY(ecacheon)
- tstl _C_LABEL(ectype)
- jeq Lnocache7
- MMUADDR(%a0)
- orl #MMU_CEN,%a0@(MMUCMD)
-Lnocache7:
- rts
-
-ENTRY(ecacheoff)
- tstl _C_LABEL(ectype)
- jeq Lnocache8
- MMUADDR(%a0)
- andl #~MMU_CEN,%a0@(MMUCMD)
-Lnocache8:
- rts
-
-ENTRY_NOPROFILE(getsfc)
- movc %sfc,%d0
- rts
-
-ENTRY_NOPROFILE(getdfc)
- movc %dfc,%d0
- rts
-
-/*
- * Load a new user segment table pointer.
- */
-ENTRY(loadustp)
- movl %sp@(4),%d0 | new USTP
- moveq #PGSHIFT,%d1
- lsll %d1,%d0 | convert to addr
-#if defined(M68040)
- cmpl #MMU_68040,_C_LABEL(mmutype) | 68040?
- jne LmotommuC | no, skip
- .chip 68040
- pflusha
- movc %d0,%urp
- rts
- .chip 68020
-LmotommuC:
-#endif
- pflusha | flush entire TLB
- lea _ASM_LABEL(protorp),%a0 | CRP prototype
- movl %d0,%a0@(4) | stash USTP
- pmove %a0@,%crp | load root pointer
- movl #CACHE_CLR,%d0
- movc %d0,%cacr | invalidate cache(s)
- rts
-
-/*
- * Set processor priority level calls. Most are implemented with
- * inline asm expansions. However, spl0 requires special handling
- * as we need to check for our emulated software interrupts.
- */
-
-ENTRY(spl0)
- moveq #0,%d0
- movw %sr,%d0 | get old SR for return
- movw #PSL_LOWIPL,%sr | restore new SR
- tstl _C_LABEL(softpending) | software interrupt pending?
- jeq Lspldone | no, all done
- subql #4,%sp | make room for RTE frame
- movl %sp@(4),%sp@(2) | position return address
- clrw %sp@(6) | set frame type 0
- movw #PSL_LOWIPL,%sp@ | and new SR
- jra Lgotsir | go handle it
-Lspldone:
- rts
-
-/*
- * _delay(u_int N)
- *
- * Delay for at least (N/256) microseconds.
- * This routine depends on the variable: delay_divisor
- * which should be set based on the CPU clock rate.
- */
-ENTRY_NOPROFILE(_delay)
- | d0 = arg = (usecs << 8)
- movl %sp@(4),%d0
- | d1 = delay_divisor
- movl _C_LABEL(delay_divisor),%d1
- jra L_delay /* Jump into the loop! */
-
- /*
- * Align the branch target of the loop to a half-line (8-byte)
- * boundary to minimize cache effects. This guarantees both
- * that there will be no prefetch stalls due to cache line burst
- * operations and that the loop will run from a single cache
- * half-line.
- */
- .balign 8
-L_delay:
- subl %d1,%d0
- jgt L_delay
- rts
-
-/*
- * Save and restore 68881 state.
- */
-ENTRY(m68881_save)
- movl %sp@(4),%a0 | save area pointer
- fsave %a0@ | save state
- tstb %a0@ | null state frame?
- jeq Lm68881sdone | yes, all done
- fmovem %fp0-%fp7,%a0@(FPF_REGS) | save FP general registers
- fmovem %fpcr/%fpsr/%fpi,%a0@(FPF_FPCR) | save FP control registers
-Lm68881sdone:
- rts
-
-ENTRY(m68881_restore)
- movl %sp@(4),%a0 | save area pointer
- tstb %a0@ | null state frame?
- jeq Lm68881rdone | yes, easy
- fmovem %a0@(FPF_FPCR),%fpcr/%fpsr/%fpi | restore FP control registers
- fmovem %a0@(FPF_REGS),%fp0-%fp7 | restore FP general registers
-Lm68881rdone:
- frestore %a0@ | restore state
- rts
-
-/*
- * Probe a memory address, and see if it causes a bus error.
- * This function is only to be used in physical mode, and before our
- * trap vectors are initialized.
- * Invoke with address to probe in a0.
- * Alters: a3 d0 d1
- */
-#define BUSERR 0xfffffffc
-ASLOCAL(phys_badaddr)
- ASRELOC(_bsave,%a3)
- movl BUSERR,%a3@ | save ROM bus errror handler
- ASRELOC(_ssave,%a3)
- movl %sp,%a3@ | and current stack pointer
- ASRELOC(catchbad,%a3)
- movl %a3,BUSERR | plug in our handler
- movw %a0@,%d1 | access address
- ASRELOC(_bsave,%a3) | no fault!
- movl %a3@,BUSERR
- clrl %d0 | return success
- rts
-ASLOCAL(catchbad)
- ASRELOC(_bsave,%a3) | got a bus error, so restore handler
- movl %a3@,BUSERR
- ASRELOC(_ssave,%a3)
- movl %a3@,%sp | and stack
- moveq #1,%d0 | return fault
- rts
-#undef BUSERR
-
- .data
- .p2align 2
-ASLOCAL(_bsave)
- .long 0
-ASLOCAL(_ssave)
- .long 0
- .text
-
-/*
- * Handle the nitty-gritty of rebooting the machine.
- * Basically we just turn off the MMU and jump to the appropriate ROM routine.
- * Note that we must be running in an address range that is mapped one-to-one
- * logical to physical so that the PC is still valid immediately after the MMU
- * is turned off. We have conveniently mapped the last page of physical
- * memory this way.
- */
-ENTRY_NOPROFILE(doboot)
-#if defined(M68040)
- cmpl #MMU_68040,_C_LABEL(mmutype) | 68040?
- jeq Lnocache5 | yes, skip
-#endif
- movl #CACHE_OFF,%d0
- movc %d0,%cacr | disable on-chip cache(s)
- tstl _C_LABEL(ectype) | external cache?
- jeq Lnocache5 | no, skip
- MMUADDR(%a0)
- andl #~MMU_CEN,%a0@(MMUCMD) | disable external cache
-Lnocache5:
- lea MAXADDR,%a0 | last page of physical memory
- movl _C_LABEL(boothowto),%a0@+ | store howto
- movl _C_LABEL(bootdev),%a0@+ | and devtype
- lea Lbootcode,%a1 | start of boot code
- lea Lebootcode,%a3 | end of boot code
-Lbootcopy:
- movw %a1@+,%a0@+ | copy a word
- cmpl %a3,%a1 | done yet?
- jcs Lbootcopy | no, keep going
-#if defined(M68040)
- cmpl #MMU_68040,_C_LABEL(mmutype) | 68040?
- jne LmotommuE | no, skip
- .chip 68040
- cpusha %bc
-LmotommuE:
- .chip 68020
-#endif
- jmp MAXADDR+8 | jump to last page
-
-Lbootcode:
- lea MAXADDR+0x800,%sp | physical SP in case of NMI
-#if defined(M68040)
- cmpl #MMU_68040,_C_LABEL(mmutype) | 68040?
- jne LmotommuF | no, skip
- .chip 68040
- movl #0,%d0
- movc %d0,%cacr | caches off
- movc %d0,%tc
- movl %d2,MAXADDR+NBPG-4 | restore old high page contents
- DOREBOOT
- .chip 68020
-LmotommuF:
-#endif
- movl #0,%a0@ | value for pmove to TC (turn off MMU)
- pmove %a0@,%tc | disable MMU
- DOREBOOT
-Lebootcode:
-
-/*
- * Misc. global variables.
- */
- .data
- .p2align 2
-GLOBAL(machineid)
- .long -1 | default to unknown
-
-GLOBAL(mmuid)
- .long 0 | default to nothing
-
-GLOBAL(mmutype)
- .long 0 | default to unknown
-
-GLOBAL(cputype)
- .long CPU_68020 | default to 68020 CPU
-
-GLOBAL(ectype)
- .long EC_NONE | external cache type, default to none
-
-GLOBAL(fputype)
- .long FPU_68882 | default to 68882 FPU
-
-ASLOCAL(protorp)
- .long 0,0 | prototype root pointer
-
-ASLOCAL(mmuscratch)
- .long 0 | scratch space for 68851/68030 MMU operation
-
-GLOBAL(internalhpib)
- .long 1 | has internal HP-IB, default to yes
-
-GLOBAL(cold)
- .long 1 | cold start flag
-
-GLOBAL(want_resched)
- .long 0
-
-GLOBAL(proc0paddr)
- .long 0 | KVA of proc0 u-area
-
-GLOBAL(intiobase)
- .long 0 | KVA of base of internal IO space
-
-GLOBAL(intiolimit)
- .long 0 | KVA of end of internal IO space
-
-GLOBAL(extiobase)
- .long 0 | KVA of base of external IO space
-
-GLOBAL(eiomapsize)
- .long 0 | size of external IO space in pages
-
-GLOBAL(CLKbase)
- .long 0 | KVA of base of clock registers
-
-GLOBAL(MMUbase)
- .long 0 | KVA of base of HP MMU registers
-
-#ifdef USELEDS
-ASLOCAL(heartbeat)
- .long 0 | clock ticks since last pulse of heartbeat
-
-ASLOCAL(beatstatus)
- .long 0 | for determining a fast or slow throb
-#endif