diff options
-rw-r--r-- | share/mk/bsd.own.mk | 4 | ||||
-rw-r--r-- | sys/arch/mac68k/conf/GENERIC | 4 | ||||
-rw-r--r-- | sys/arch/mac68k/conf/GENERICSBC | 4 | ||||
-rw-r--r-- | sys/arch/mac68k/conf/MRGADB | 66 | ||||
-rw-r--r-- | sys/arch/mac68k/dev/grf.c | 16 | ||||
-rw-r--r-- | sys/arch/mac68k/dev/mac68k5380.c | 8 | ||||
-rw-r--r-- | sys/arch/mac68k/dev/nubus.c | 10 | ||||
-rw-r--r-- | sys/arch/mac68k/include/cpu.h | 3 | ||||
-rw-r--r-- | sys/arch/mac68k/include/pmap.h | 59 | ||||
-rw-r--r-- | sys/arch/mac68k/include/viareg.h | 4 | ||||
-rw-r--r-- | sys/arch/mac68k/include/vmparam.h | 50 | ||||
-rw-r--r-- | sys/arch/mac68k/mac68k/autoconf.c | 3 | ||||
-rw-r--r-- | sys/arch/mac68k/mac68k/bus_space.c | 23 | ||||
-rw-r--r-- | sys/arch/mac68k/mac68k/genassym.cf | 31 | ||||
-rw-r--r-- | sys/arch/mac68k/mac68k/locore.s | 2034 | ||||
-rw-r--r-- | sys/arch/mac68k/mac68k/machdep.c | 1658 | ||||
-rw-r--r-- | sys/arch/mac68k/mac68k/mem.c | 53 | ||||
-rw-r--r-- | sys/arch/mac68k/mac68k/pmap.c | 1832 | ||||
-rw-r--r-- | sys/arch/mac68k/mac68k/pmap_bootstrap.c | 119 | ||||
-rw-r--r-- | sys/arch/mac68k/mac68k/trap.c | 173 | ||||
-rw-r--r-- | sys/arch/mac68k/mac68k/vectors.s | 179 | ||||
-rw-r--r-- | sys/arch/mac68k/mac68k/via.c | 4 | ||||
-rw-r--r-- | sys/arch/mac68k/mac68k/vm_machdep.c | 173 |
23 files changed, 3475 insertions, 3035 deletions
diff --git a/share/mk/bsd.own.mk b/share/mk/bsd.own.mk index 929595fab88..6884b089dc6 100644 --- a/share/mk/bsd.own.mk +++ b/share/mk/bsd.own.mk @@ -1,4 +1,4 @@ -# $OpenBSD: bsd.own.mk,v 1.43 2001/05/05 15:20:28 millert Exp $ +# $OpenBSD: bsd.own.mk,v 1.44 2001/05/08 17:30:42 aaron Exp $ # $NetBSD: bsd.own.mk,v 1.24 1996/04/13 02:08:09 thorpej Exp $ # Host-specific overrides @@ -9,7 +9,7 @@ .endif # XXX - This is temporary until everyone uses UVM -.if (${MACHINE_ARCH} == "sparc") || (${MACHINE_ARCH} == "i386") || (${MACHINE_ARCH} == "vax") || (${MACHINE} == "amiga") || (${MACHINE} == "hp300") || (${MACHINE_ARCH} == "alpha") || (${MACHINE_ARCH} == "powerpc") || (${MACHINE_ARCH} == "m88k") +.if (${MACHINE_ARCH} == "sparc") || (${MACHINE_ARCH} == "i386") || (${MACHINE_ARCH} == "vax") || (${MACHINE} == "amiga") || (${MACHINE} == "hp300") || (${MACHINE} == "mac68k") || (${MACHINE_ARCH} == "alpha") || (${MACHINE_ARCH} == "powerpc") || (${MACHINE_ARCH} == "m88k") UVM?= yes .else UVM?= no diff --git a/sys/arch/mac68k/conf/GENERIC b/sys/arch/mac68k/conf/GENERIC index 7b3bde2ddf3..2c94490744e 100644 --- a/sys/arch/mac68k/conf/GENERIC +++ b/sys/arch/mac68k/conf/GENERIC @@ -1,4 +1,4 @@ -# $OpenBSD: GENERIC,v 1.26 2001/03/08 03:37:17 itojun Exp $ +# $OpenBSD: GENERIC,v 1.27 2001/05/08 17:30:39 aaron Exp $ # $NetBSD: GENERIC,v 1.52 1997/01/13 23:34:07 scottr Exp $ # # GENERIC - an all-in-one kernel for the mac68k @@ -19,6 +19,8 @@ option DISABLE_EXT_CACHE # Don't use IIci external cache option DISABLE_ADB_WITH_SERIAL_CONSOLE #option MRG_ADB # Use ROM-based ADB driver +option UVM # use the UVM virtual memory system + config bsd swap generic maxusers 16 diff --git a/sys/arch/mac68k/conf/GENERICSBC b/sys/arch/mac68k/conf/GENERICSBC index e7bf280c266..68e4a966fa7 100644 --- a/sys/arch/mac68k/conf/GENERICSBC +++ b/sys/arch/mac68k/conf/GENERICSBC @@ -1,4 +1,4 @@ -# $OpenBSD: GENERICSBC,v 1.10 1998/05/08 22:21:35 gene Exp $ +# $OpenBSD: GENERICSBC,v 1.11 2001/05/08 17:30:39 aaron Exp $ # $NetBSD: GENERIC,v 1.52 1997/01/13 23:34:07 scottr Exp $ # # GENERICSBC --- our generic kernel using the SBC SCSI driver @@ -19,6 +19,8 @@ option DISABLE_EXT_CACHE # Don't use IIci external cache option DISABLE_ADB_WITH_SERIAL_CONSOLE #option MRG_ADB # Use ROM-based ADB driver +option UVM # use the UVM virtual memory system + config bsd swap generic maxusers 16 diff --git a/sys/arch/mac68k/conf/MRGADB b/sys/arch/mac68k/conf/MRGADB new file mode 100644 index 00000000000..656aa40371c --- /dev/null +++ b/sys/arch/mac68k/conf/MRGADB @@ -0,0 +1,66 @@ +# $OpenBSD: MRGADB,v 1.4 2001/05/08 17:30:39 aaron Exp $ +# +# MRGADB - generic kernel with the optional "mrg" adb driver by default +# + +machine mac68k m68k +include "conf/GENERIC" + +# Mac-specific options +option HZ=60 # Macs like 60hz +option M68040 +option M68030 +option M68020 # Must have 68851 PMMU +option FPSP +option FPU_EMULATE +option COMPAT_SUNOS # SunOS m68k binary compatiblity +option ZS_CONSOLE_ABORT +option DISABLE_EXT_CACHE # Don't use IIci external cache +option DISABLE_ADB_WITH_SERIAL_CONSOLE +option MRG_ADB # Use ROM-based ADB driver + +option UVM # use the UVM virtual memory system + +config bsd swap generic +maxusers 16 + +mainbus0 at root +fpu0 at mainbus? + +# on-board I/O +obio0 at mainbus? + +adb0 at obio? +asc0 at obio? # ASC/EASC audio +esp0 at obio? # SCSI NCR 53C9x +esp1 at obio? # SCSI NCR 53C9x +intvid0 at obio? # Internal video hardware +mc* at obio? # MACE ethernet on Centris/Quadra 660av +sn* at obio? # Internal ethernet +zsc0 at obio? # Zilog serial chip +zstty* at zsc? channel ? + +nubus0 at mainbus? + +ae* at nubus? # Most Apple Ethernet Cards +macvid* at nubus? # NuBus video cards +sn* at nubus? # SONIC-based ethernet cards + +# Attach grf semantics to all video hardware as it is found +grf* at intvid? +grf* at macvid? + +# Attach ite semantics to the appropriate grf device +ite0 at grf? + +# Use only one of ncrscsi or sbc +ncrscsi0 at obio? # SCSI NCR 5380 +#sbc0 at obio? flags 0x1 # MI NCR 5380 SCSI Bus Controller + +scsibus* at scsi? +sd* at scsibus? target ? lun ? # SCSI disk drives +st* at scsibus? target ? lun ? # SCSI tape drives +cd* at scsibus? target ? lun ? # SCSI CD-ROM drives +ch* at scsibus? target ? lun ? # SCSI autochangers +ss* at scsibus? target ? lun ? # SCSI scanners +uk* at scsibus? target ? lun ? # SCSI unknown diff --git a/sys/arch/mac68k/dev/grf.c b/sys/arch/mac68k/dev/grf.c index 8ed4a43d03e..cfc63247957 100644 --- a/sys/arch/mac68k/dev/grf.c +++ b/sys/arch/mac68k/dev/grf.c @@ -1,4 +1,4 @@ -/* $OpenBSD: grf.c,v 1.9 1999/04/24 06:39:40 downsj Exp $ */ +/* $OpenBSD: grf.c,v 1.10 2001/05/08 17:30:39 aaron Exp $ */ /* $NetBSD: grf.c,v 1.41 1997/02/24 06:20:04 scottr Exp $ */ /* @@ -71,6 +71,10 @@ #include <vm/vm_page.h> #include <vm/vm_pager.h> +#if defined(UVM) +#include <uvm/uvm.h> +#endif + #include "nubus.h" #include "itevar.h" #include "grfvar.h" @@ -370,8 +374,13 @@ grfmap(dev, addrp, p) vn.v_specinfo = &si; /* XXX */ vn.v_rdev = dev; /* XXX */ +#if defined(UVM) + error = uvm_mmap(&p->p_vmspace->vm_map, (vm_offset_t *)addrp, + (vm_size_t)len, VM_PROT_ALL, VM_PROT_ALL, flags, (caddr_t)&vn, 0); +#else error = vm_mmap(&p->p_vmspace->vm_map, (vm_offset_t *) addrp, (vm_size_t) len, VM_PROT_ALL, VM_PROT_ALL, flags, (caddr_t) &vn, 0); +#endif /* Offset into page: */ *addrp += (unsigned long) gp->sc_grfmode->fboff & 0xfff; @@ -406,7 +415,12 @@ grfunmap(dev, addr, p) size = round_page(gp->sc_grfmode->fbsize); +#if defined(UVM) + rv = uvm_unmap(&p->p_vmspace->vm_map, (vm_offset_t)addr, + (vm_offset_t)addr + size); +#else rv = vm_deallocate(&p->p_vmspace->vm_map, (vm_offset_t) addr, size); +#endif return (rv == KERN_SUCCESS ? 0 : EINVAL); } diff --git a/sys/arch/mac68k/dev/mac68k5380.c b/sys/arch/mac68k/dev/mac68k5380.c index d6bf498bef4..858754f8121 100644 --- a/sys/arch/mac68k/dev/mac68k5380.c +++ b/sys/arch/mac68k/dev/mac68k5380.c @@ -1,4 +1,4 @@ -/* $OpenBSD: mac68k5380.c,v 1.13 1999/01/11 05:11:34 millert Exp $ */ +/* $OpenBSD: mac68k5380.c,v 1.14 2001/05/08 17:30:40 aaron Exp $ */ /* $NetBSD: mac68k5380.c,v 1.29 1997/02/28 15:50:50 scottr Exp $ */ /* @@ -355,7 +355,7 @@ do_ncr5380_drq_intr(p) void *p; { #if USE_PDMA -extern int *nofault, mac68k_buserr_addr; +extern int *nofault, m68k_fault_addr; label_t faultbuf; register int count; volatile u_int32_t *long_drq; @@ -381,7 +381,7 @@ extern int *nofault, mac68k_buserr_addr; if (setjmp((label_t *) nofault)) { PID("drq berr"); nofault = (int *) 0; - count = ( (u_long) mac68k_buserr_addr + count = ( (u_long) m68k_fault_addr - (u_long) ncr_5380_with_drq); if ((count < 0) || (count > pending_5380_count)) { printf("pdma %s: cnt = %d (0x%x) (pending cnt %ld)\n", @@ -393,7 +393,7 @@ extern int *nofault, mac68k_buserr_addr; pending_5380_data += count; pending_5380_count -= count; - mac68k_buserr_addr = 0; + m68k_fault_addr = 0; PID("end drq early"); diff --git a/sys/arch/mac68k/dev/nubus.c b/sys/arch/mac68k/dev/nubus.c index e1cdf36c6ec..afad4676933 100644 --- a/sys/arch/mac68k/dev/nubus.c +++ b/sys/arch/mac68k/dev/nubus.c @@ -1,4 +1,4 @@ -/* $OpenBSD: nubus.c,v 1.14 1999/09/03 18:01:09 art Exp $ */ +/* $OpenBSD: nubus.c,v 1.15 2001/05/08 17:30:40 aaron Exp $ */ /* $NetBSD: nubus.c,v 1.35 1997/04/22 20:20:32 scottr Exp $ */ /* @@ -41,6 +41,10 @@ #include <vm/vm_kern.h> #include <vm/vm_map.h> +#if defined(UVM) +#include <uvm/uvm_extern.h> +#endif + #include <machine/autoconf.h> #include <machine/bus.h> #include <machine/vmparam.h> @@ -817,7 +821,11 @@ nubus_mapin(paddr, sz) sz = m68k_round_page(sz); /* Get some kernel virtual address space. */ +#if defined(UVM) + va = uvm_km_valloc_wait(kernel_map, sz); +#else va = kmem_alloc_wait(kernel_map, sz); +#endif if (va == 0) panic("bus_mapin"); retval = va + off; diff --git a/sys/arch/mac68k/include/cpu.h b/sys/arch/mac68k/include/cpu.h index c8b7cfdb594..a755ccb25db 100644 --- a/sys/arch/mac68k/include/cpu.h +++ b/sys/arch/mac68k/include/cpu.h @@ -1,4 +1,4 @@ -/* $OpenBSD: cpu.h,v 1.19 1998/05/03 07:10:44 gene Exp $ */ +/* $OpenBSD: cpu.h,v 1.20 2001/05/08 17:30:40 aaron Exp $ */ /* $NetBSD: cpu.h,v 1.45 1997/02/10 22:13:40 scottr Exp $ */ /* @@ -318,6 +318,7 @@ void DCFL __P((vm_offset_t)); int suline __P((caddr_t, caddr_t)); void savectx __P((struct pcb *)); void proc_trampoline __P((void)); +void loadustp __P((int)); /* trap.c */ void child_return __P((struct proc *, struct frame)); diff --git a/sys/arch/mac68k/include/pmap.h b/sys/arch/mac68k/include/pmap.h index 859c5b15950..5b6d0ee88ea 100644 --- a/sys/arch/mac68k/include/pmap.h +++ b/sys/arch/mac68k/include/pmap.h @@ -1,5 +1,5 @@ -/* $OpenBSD: pmap.h,v 1.8 1999/04/24 06:39:40 downsj Exp $ */ -/* $NetBSD: pmap.h,v 1.14 1997/02/02 18:19:55 scottr Exp $ */ +/* $OpenBSD: pmap.h,v 1.9 2001/05/08 17:30:40 aaron Exp $ */ +/* $NetBSD: pmap.h,v 1.26 1999/07/21 03:18:21 briggs Exp $ */ /* * Copyright (c) 1987 Carnegie-Mellon University @@ -78,7 +78,7 @@ #ifndef _MAC68K_PMAP_H_ #define _MAC68K_PMAP_H_ -#include <machine/pcb.h> +#include <machine/cpu.h> #include <machine/pte.h> #if defined(M68040) @@ -96,7 +96,6 @@ struct pmap { pt_entry_t *pm_ptab; /* KVA of page table */ st_entry_t *pm_stab; /* KVA of segment table */ - int pm_stchanged; /* ST changed */ int pm_stfree; /* 040: free lev2 blocks */ st_entry_t *pm_stpa; /* 040: ST phys addr */ short pm_sref; /* segment table ref count */ @@ -127,14 +126,11 @@ typedef struct pmap *pmap_t; /* * Macros for speed */ -#define PMAP_ACTIVATE(pmapp, pcbp, iscurproc) \ - if ((pmapp)->pm_stchanged) { \ - (pcbp)->pcb_ustp = m68k_btop((vm_offset_t)(pmapp)->pm_stpa); \ - if (iscurproc) \ - loadustp((pcbp)->pcb_ustp); \ - (pmapp)->pm_stchanged = FALSE; \ - } -#define PMAP_DEACTIVATE(pmapp, pcbp) +#define PMAP_ACTIVATE(pmap, loadhw) \ +{ \ + if ((loadhw)) \ + loadustp(m68k_btop((paddr_t)(pmap)->pm_stpa)); \ +} /* * For each vm_page_t, there is a list of all currently valid virtual @@ -143,7 +139,7 @@ typedef struct pmap *pmap_t; typedef struct pv_entry { struct pv_entry *pv_next; /* next pv_entry */ struct pmap *pv_pmap; /* pmap where mapping lies */ - vm_offset_t pv_va; /* virtual address for mapping */ + vaddr_t pv_va; /* virtual address for mapping */ st_entry_t *pv_ptste; /* non-zero if VA maps a PT page */ struct pmap *pv_ptpmap; /* if pv_ptste, pmap for PT page */ int pv_flags; /* flags */ @@ -172,47 +168,30 @@ struct pv_page { }; #ifdef _KERNEL -struct pmap kernel_pmap_store; +extern struct pmap kernel_pmap_store; #define pmap_kernel() (&kernel_pmap_store) #define active_pmap(pm) \ ((pm) == pmap_kernel() || (pm) == curproc->p_vmspace->vm_map.pmap) +#define active_user_pmap(pm) \ + (curproc && \ + (pm) != pmap_kernel() && (pm) == curproc->p_vmspace->vm_map.pmap) extern struct pv_entry *pv_table; /* array of entries, one per page */ -#define pa_to_pvh(pa) (&pv_table[pmap_page_index(pa)]) - #define pmap_resident_count(pmap) ((pmap)->pm_stats.resident_count) #define pmap_wired_count(pmap) ((pmap)->pm_stats.wired_count) extern pt_entry_t *Sysmap; extern char *vmmap; /* map for mem, dumps, etc. */ -__BEGIN_DECLS /* pmap.c */ -void mac68k_set_pte __P((vm_offset_t va, vm_offset_t pge)); -void pmap_remove_mapping __P((pmap_t, vm_offset_t, pt_entry_t *, int)); -boolean_t pmap_testbit __P((vm_offset_t, int)); -void pmap_changebit __P((vm_offset_t, int, boolean_t)); -void pmap_enter_ptpage __P((pmap_t, vm_offset_t)); -vm_offset_t pmap_map __P((vm_offset_t, vm_offset_t, vm_offset_t, int)); -void pmap_pvdump __P((vm_offset_t)); -void pmap_check_wiring __P((char *, vm_offset_t)); -void pmap_collect_pv __P((void)); -void pmap_activate __P((register pmap_t, struct pcb *)); -void pmap_deactivate __P((register pmap_t, struct pcb *)); - -/* pmap_bootstrap.c */ -void pmap_bootstrap __P((vm_offset_t, register vm_offset_t)); -void bootstrap_mac68k __P((int)); - -/* locore.s */ -void loadustp __P((vm_offset_t)); -void TBIA __P((void)); -void TBIS __P((vm_offset_t)); -void DCFP __P((vm_offset_t)); -void ICPP __P((vm_offset_t)); -__END_DECLS +vm_offset_t pmap_map __P((vaddr_t, paddr_t, paddr_t, int)); +void mac68k_set_pte __P((vm_offset_t va, vm_offset_t pge)); + +struct proc; +void pmap_activate __P((struct proc *)); +void pmap_deactivate __P((struct proc *)); #endif /* _KERNEL */ diff --git a/sys/arch/mac68k/include/viareg.h b/sys/arch/mac68k/include/viareg.h index 0939ec0c55b..a6535ed261c 100644 --- a/sys/arch/mac68k/include/viareg.h +++ b/sys/arch/mac68k/include/viareg.h @@ -1,4 +1,4 @@ -/* $OpenBSD: viareg.h,v 1.7 1997/11/30 06:10:37 gene Exp $ */ +/* $OpenBSD: viareg.h,v 1.8 2001/05/08 17:30:40 aaron Exp $ */ /* $NetBSD: viareg.h,v 1.6 1997/02/28 07:41:41 scottr Exp $ */ /*- @@ -190,7 +190,7 @@ extern int VIA2; #define vDirA_ADBState 0x30 #ifdef _KERNEL -void VIA_initialize __P((void)); +void via_init __P((void)); int rbv_vidstatus __P((void)); void via_shutdown __P((void)); void via_set_modem __P((int)); diff --git a/sys/arch/mac68k/include/vmparam.h b/sys/arch/mac68k/include/vmparam.h index 732a11f93d8..5b2ba17ad4d 100644 --- a/sys/arch/mac68k/include/vmparam.h +++ b/sys/arch/mac68k/include/vmparam.h @@ -1,4 +1,4 @@ -/* $OpenBSD: vmparam.h,v 1.5 2001/05/05 20:56:41 art Exp $ */ +/* $OpenBSD: vmparam.h,v 1.6 2001/05/08 17:30:40 aaron Exp $ */ /* $NetBSD: vmparam.h,v 1.8 1996/11/15 14:21:00 briggs Exp $ */ /* @@ -107,13 +107,13 @@ #define MAXTSIZ (8*1024*1024) /* max text size */ #endif #ifndef DFLDSIZ -#define DFLDSIZ (16*1024*1024) /* initial data size limit */ +#define DFLDSIZ (32*1024*1024) /* initial data size limit */ #endif #ifndef MAXDSIZ #define MAXDSIZ (64*1024*1024) /* max data size */ #endif #ifndef DFLSSIZ -#define DFLSSIZ (512*1024) /* initial stack size limit */ +#define DFLSSIZ (2*1024*1024) /* initial stack size limit */ #endif #ifndef MAXSSIZ #define MAXSSIZ MAXDSIZ /* max stack size */ @@ -176,21 +176,49 @@ */ /* user/kernel map constants */ -#define VM_MIN_ADDRESS ((vm_offset_t)0) -#define VM_MAXUSER_ADDRESS ((vm_offset_t)(USRSTACK)) -#define VM_MAX_ADDRESS ((vm_offset_t)(0-(UPAGES*NBPG))) -#define VM_MIN_KERNEL_ADDRESS ((vm_offset_t)0) -#define VM_MAX_KERNEL_ADDRESS ((vm_offset_t)(0-NBPG)) +#define VM_MIN_ADDRESS ((vaddr_t)0) +#define VM_MAXUSER_ADDRESS ((vaddr_t)(USRSTACK)) +#define VM_MAX_ADDRESS ((vaddr_t)(0-(UPAGES*NBPG))) +#define VM_MIN_KERNEL_ADDRESS ((vaddr_t)0) +#define VM_MAX_KERNEL_ADDRESS ((vaddr_t)(0-NBPG)) /* virtual sizes (bytes) for various kernel submaps */ #define VM_MBUF_SIZE (NMBCLUSTERS*MCLBYTES) #define VM_KMEM_SIZE (NKMEMCLUSTERS*PAGE_SIZE) #define VM_PHYS_SIZE (USRIOSIZE*PAGE_SIZE) -#define MACHINE_NONCONTIG /* VM <=> pmap interface modifier */ - /* # of kernel PT pages (initial only, can grow dynamically) */ -#define VM_KERNEL_PT_PAGES ((vm_size_t)2) /* XXX: SYSPTSIZE */ +#define VM_KERNEL_PT_PAGES ((vsize_t)2) /* XXX: SYSPTSIZE */ + +/* Use new VM page bootstrap interface. */ +#define MACHINE_NEW_NONCONTIG + +/* + * Constants which control the way the VM system deals with memory segments. + * Most mac68k systems have only 1 physical memory segment, but some have 2. + * + * On the systems that have multiple segments, specifically the IIsi and + * IIci, the optimal configuration is to put the higher-density SIMMs in + * bank B. This is because the on-board video uses main memory in bank A + * for the framebuffer, and a memory controller prevents access during + * video refresh cycles. Even if both banks contain the same amount of + * RAM, a minimum of ~320KB will be subtracted from the amount in bank A + * for the framebuffer (if on-board video is in use). + */ +#define VM_PHYSSEG_MAX 2 +#define VM_PHYSSEG_STRAT VM_PSTRAT_BIGFIRST +#define VM_PHYSSEG_NOADD + +#define VM_NFREELIST 1 +#define VM_FREELIST_DEFAULT 0 + +/* + * pmap-specific data stored in the vm_physmem[] array. + */ +struct pmap_physseg { + struct pv_entry *pvent; /* pv table for this seg */ + char *attrs; /* page attributes for this seg */ +}; /* pcb base */ #define pcbb(p) ((u_int)(p)->p_addr) diff --git a/sys/arch/mac68k/mac68k/autoconf.c b/sys/arch/mac68k/mac68k/autoconf.c index 7e06a8575c3..23a2d45713f 100644 --- a/sys/arch/mac68k/mac68k/autoconf.c +++ b/sys/arch/mac68k/mac68k/autoconf.c @@ -1,4 +1,4 @@ -/* $OpenBSD: autoconf.c,v 1.12 2001/05/05 22:33:52 art Exp $ */ +/* $OpenBSD: autoconf.c,v 1.13 2001/05/08 17:30:40 aaron Exp $ */ /* $NetBSD: autoconf.c,v 1.38 1996/12/18 05:46:09 scottr Exp $ */ /* @@ -96,7 +96,6 @@ cpu_configure() { extern int cold; - VIA_initialize(); /* Init VIA hardware */ mrg_init(); /* Init Mac ROM Glue */ startrtclock(); /* start before adb_init() */ adb_init(); /* ADB device subsystem & driver */ diff --git a/sys/arch/mac68k/mac68k/bus_space.c b/sys/arch/mac68k/mac68k/bus_space.c index 6e114b4c805..f8cf87f22d5 100644 --- a/sys/arch/mac68k/mac68k/bus_space.c +++ b/sys/arch/mac68k/mac68k/bus_space.c @@ -1,5 +1,5 @@ -/* $OpenBSD: bus_space.c,v 1.4 1999/09/03 18:01:11 art Exp $ */ -/* $NetBSD: bus_space.c,v 1.2 1998/04/24 05:27:24 scottr Exp $ */ +/* $OpenBSD: bus_space.c,v 1.5 2001/05/08 17:30:40 aaron Exp $ */ +/* $NetBSD: bus_space.c,v 1.5 1999/03/26 23:41:30 mycroft Exp $ */ /*- * Copyright (c) 1996, 1997 The NetBSD Foundation, Inc. @@ -42,10 +42,6 @@ * Implementation of bus_space mapping for mac68k. */ -#if 0 -#include "opt_uvm.h" -#endif - #include <sys/param.h> #include <sys/systm.h> #include <sys/extent.h> @@ -75,7 +71,7 @@ bus_space_map(t, bpa, size, flags, bshp) int flags; bus_space_handle_t *bshp; { - u_long pa, endpa; + paddr_t pa, endpa; int error; /* @@ -164,7 +160,8 @@ bus_mem_add_mapping(bpa, size, flags, bshp) bus_space_handle_t *bshp; { u_long pa, endpa; - vm_offset_t va; + vaddr_t va; + pt_entry_t *pte; pa = m68k_trunc_page(bpa); endpa = m68k_round_page((bpa + size) - 1); @@ -187,8 +184,12 @@ bus_mem_add_mapping(bpa, size, flags, bshp) for (; pa < endpa; pa += NBPG, va += NBPG) { pmap_enter(pmap_kernel(), va, pa, VM_PROT_READ | VM_PROT_WRITE, TRUE, 0); - if (!(flags & BUS_SPACE_MAP_CACHEABLE)) - pmap_changebit(pa, PG_CI, TRUE); + pte = kvtopte(va); + if ((flags & BUS_SPACE_MAP_CACHEABLE)) + *pte &= ~PG_CI; + else + *pte |= PG_CI; + pmap_update(); } return 0; @@ -200,7 +201,7 @@ bus_space_unmap(t, bsh, size) bus_space_handle_t bsh; bus_size_t size; { - vm_offset_t va, endva; + vaddr_t va, endva; bus_addr_t bpa; va = m68k_trunc_page(bsh); diff --git a/sys/arch/mac68k/mac68k/genassym.cf b/sys/arch/mac68k/mac68k/genassym.cf index c5b3241d151..e72d3dbe45b 100644 --- a/sys/arch/mac68k/mac68k/genassym.cf +++ b/sys/arch/mac68k/mac68k/genassym.cf @@ -1,5 +1,5 @@ -# $OpenBSD: genassym.cf,v 1.2 2001/04/06 09:34:15 art Exp $ -# $NetBSD: genassym.cf,v 1.1 1997/04/15 06:11:40 scottr Exp $ +# $OpenBSD: genassym.cf,v 1.3 2001/05/08 17:30:40 aaron Exp $ +# $NetBSD: genassym.cf,v 1.7 1998/01/06 08:46:16 thorpej Exp $ # # Copyright (c) 1990 The Regents of the University of California. @@ -48,6 +48,10 @@ include <sys/user.h> include <vm/vm.h> +ifdef UVM +include <uvm/uvm_extern.h> +endif + include <machine/cpu.h> include <machine/trap.h> include <machine/psl.h> @@ -69,21 +73,18 @@ define P_MD_FLAGS offsetof(struct proc, p_md.md_flags) define SSLEEP SSLEEP define SRUN SRUN -define MD_REGS offsetof(struct mdproc, md_regs) - -define PM_STCHG offsetof(struct pmap, pm_stchanged) - -define VM_PMAP offsetof(struct vmspace, vm_map.pmap) -define V_SWTCH offsetof(struct vmmeter, v_swtch) -define V_TRAP offsetof(struct vmmeter, v_trap) -define V_SYSCALL offsetof(struct vmmeter, v_syscall) +# interrupt/fault metering +ifdef UVM +define UVMEXP_INTRS offsetof(struct uvmexp, intrs) +else define V_INTR offsetof(struct vmmeter, v_intr) -define V_SOFT offsetof(struct vmmeter, v_soft) +endif + +define MD_REGS offsetof(struct mdproc, md_regs) define UPAGES UPAGES define USPACE USPACE define P1PAGES P1PAGES -define CLSIZE CLSIZE define NBPG NBPG define NPTEPG NPTEPG define PGSHIFT PGSHIFT @@ -95,7 +96,6 @@ define USRSTACK USRSTACK define MSGBUFPTECNT btoc(sizeof (struct msgbuf)) define NMBCLUSTERS NMBCLUSTERS define MCLBYTES MCLBYTES -define NKMEMCLUSTERS NKMEMCLUSTERS quote #ifdef SYSVSHM define SHMMAXPGS SHMMAXPGS @@ -151,7 +151,6 @@ define PG_FRAME PG_FRAME define SIZEOF_PCB sizeof(struct pcb) define PCB_FLAGS offsetof(struct pcb, pcb_flags) define PCB_PS offsetof(struct pcb, pcb_ps) -define PCB_USTP offsetof(struct pcb, pcb_ustp) define PCB_USP offsetof(struct pcb, pcb_usp) define PCB_REGS offsetof(struct pcb, pcb_regs) define PCB_ONFAULT offsetof(struct pcb, pcb_onfault) @@ -161,6 +160,7 @@ define PCB_TRCB 5 define FR_SP offsetof(struct frame, f_regs[15]) define FR_HW offsetof(struct frame, f_sr) define FR_ADJ offsetof(struct frame, f_stackadj) +define FR_SIZE sizeof(struct trapframe) define B_READ B_READ @@ -172,6 +172,9 @@ define SYS_exit SYS_exit define SYS_execve SYS_execve define SYS_sigreturn SYS_sigreturn +define CPUINFO_CLASS offsetof(struct cpu_model_info, class) +define MACH_CLASSAV MACH_CLASSAV + define CPU_68020 CPU_68020 define CPU_68030 CPU_68030 define CPU_68040 CPU_68040 diff --git a/sys/arch/mac68k/mac68k/locore.s b/sys/arch/mac68k/mac68k/locore.s index 7137abeba5b..5b4276a9f74 100644 --- a/sys/arch/mac68k/mac68k/locore.s +++ b/sys/arch/mac68k/mac68k/locore.s @@ -1,5 +1,5 @@ -/* $OpenBSD: locore.s,v 1.24 2001/04/06 09:34:15 art Exp $ */ -/* $NetBSD: locore.s,v 1.74 1997/02/02 08:17:46 thorpej Exp $ */ +/* $OpenBSD: locore.s,v 1.25 2001/05/08 17:30:41 aaron Exp $ */ +/* $NetBSD: locore.s,v 1.103 1998/07/09 06:02:50 scottr Exp $ */ /* * Copyright (c) 1988 University of Utah. @@ -78,122 +78,409 @@ * @(#)locore.s 7.11 (Berkeley) 5/9/91 */ +#include "assym.h" +#include <machine/asm.h> +#include <machine/trap.h> + /* - * This is for kvm_mkdb, and should be the address of the beginning + * This is for kvm_mkdb, and should be the address of the beginning * of the kernel text segment (not necessarily the same as kernbase). */ .text - .globl _kernel_text -_kernel_text: +GLOBAL(kernel_text) -#include "assym.h" -#include "vectors.s" -#include "macglobals.s" +#include <mac68k/mac68k/vectors.s> +#include <mac68k/mac68k/macglobals.s> /* - * 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). + * Initialization */ - .globl _panic, _panicstr - .globl _jmp0panic - -_jmp0panic: - tstl _panicstr - jeq jmp0panic - stop #0x2700 -jmp0panic: - pea Ljmp0panic - jbsr _panic + + .data +| Scratch memory. Careful when messing with these... +ASLOCAL(longscratch) + .long 0 +ASLOCAL(longscratch2) + .long 0 +ASLOCAL(pte_tmp) | for get_pte() + .long 0 +GLOBAL(macos_crp1) + .long 0 +GLOBAL(macos_crp2) + .long 0 +GLOBAL(macos_tc) + .long 0 +GLOBAL(macos_tt0) + .long 0 +GLOBAL(macos_tt1) + .long 0 +GLOBAL(bletch) + .long 0 +GLOBAL(esym) + .long 0 + +ASENTRY_NOPROFILE(start) + movw #PSL_HIGHIPL,sr | no interrupts. ever. + lea _ASM_LABEL(tmpstk),sp | give ourselves a temporary stack + + movl #CACHE_OFF,d0 + movc d0,cacr | clear and disable on-chip cache(s) + + /* Initialize source/destination control registers for movs */ + movql #FC_USERD,d0 | user space + movc d0,sfc | as source + movc d0,dfc | and destination of transfers + + /* + * Some parameters provided by MacOS + * + * LAK: This section is the new way to pass information from the booter + * to the kernel. At A1 there is an environment variable which has + * a bunch of stuff in ascii format, "VAR=value\0VAR=value\0\0". + */ + movl a1,sp@- | Address of buffer + movl d4,sp@- | Some flags... (mostly not used) + jbsr _C_LABEL(getenvvars) | Parse the environment buffer + addql #8,sp + + /* Determine MMU/MPU from what we can test empirically */ + 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 + + movl #CACHE_OFF,d0 | disable and clear both caches + movc d0,cacr + lea _C_LABEL(mmutype),a0 | no, we have 68030 + movl #MMU_68030,a0@ | set to reflect 68030 PMMU + lea _C_LABEL(cputype),a0 + movl #CPU_68030,a0@ | and 68030 MPU + 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 + + movql #CACHE40_OFF,d0 | now turn it back off + movc d0,cacr | before we access any data + .word 0xf4f8 | cpusha bc ;push and invalidate caches + lea _C_LABEL(mmutype),a0 + movl #MMU_68040,a0@ | Reflect 68040 MMU + lea _C_LABEL(cputype),a0 + movl #CPU_68040,a0@ | and 68040 MPU + jra Lstart1 + +Lis68020: + movl #CACHE_OFF,d0 | disable and clear cache + movc d0,cacr + lea _C_LABEL(mmutype),a0 | Must be 68020+68851 + movl #MMU_68851,a0@ | Reflect 68851 PMMU + lea _C_LABEL(cputype),a0 + movl #CPU_68020,a0@ | and 68020 MPU + +Lstart1: + /* + * 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 + */ + lea _C_LABEL(cputype),a0 + lea _C_LABEL(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 + /* Config botch; no hope. */ + movl _C_LABEL(MacOSROMBase),a1 | Load MacOS ROMBase + jra Ldoboot1 + +Lstart2: + jbsr _C_LABEL(setmachdep) | Set some machine-dep stuff + jbsr _C_LABEL(consinit) | XXX Should only be if graybar on + +/* + * Figure out MacOS mappings and bootstrap NetBSD + */ + lea _C_LABEL(macos_tc),a0 | get current TC + cmpl #MMU_68040,_C_LABEL(mmutype) | check to see if 68040 + jeq Lget040TC + + pmove tc,a0@ + jra Lstart3 + +Lget040TC: + movl _C_LABEL(current_mac_model),a1 | if an AV Mac, save current + cmpl #MACH_CLASSAV,a1@(CPUINFO_CLASS) | TC so internal video will + jne LnotAV | get configured + .long 0x4e7a0003 | movc tc,d0 + jra LsaveTC +LnotAV: + movql #0,d0 | otherwise, + .long 0x4e7b0003 | movc d0,tc ;Disable MMU +LsaveTC: + movl d0,a0@ + +Lstart3: + movl a0@,sp@- | get Mac OS mapping, relocate video, + jbsr _C_LABEL(bootstrap_mac68k) | bootstrap pmap, et al. + addql #4,sp + + /* + * Set up the vector table, and race to get the MMU + * enabled. + */ + movl #_C_LABEL(vectab),d0 | set Vector Base Register + movc d0,vbr + + movl _C_LABEL(Sysseg),a1 | system segment table addr + addl _C_LABEL(load_addr),a1 | Make it physical addr + cmpl #MMU_68040,_C_LABEL(mmutype) + jne Lenablepre040MMU | if not 040, skip + + movql #0,d0 + .long 0x4e7b0003 | movc d0,tc ;Disable MMU + .long 0x4e7b0004 | movc d0,itt0 ;Disable itt0 + .long 0x4e7b0005 | movc d0,itt1 ;Disable itt1 + .long 0x4e7b0006 | movc d0,dtt0 ;Disable dtt0 + .long 0x4e7b0007 | movc d0,dtt1 ;Disable dtt1 + movl a1,d1 + .word 0xf518 | pflusha + .long 0x4e7b1807 | movc d1,srp + movl #0x8000,d0 + .long 0x4e7b0003 | movc d0,tc ;Enable MMU + movl #CACHE40_ON,d0 + movc d0,cacr | turn on both caches + jra Lloaddone + +Lenablepre040MMU: + tstl _C_LABEL(mmutype) | TTx instructions will break 68851 + jgt LnokillTT + + lea _ASM_LABEL(longscratch),a0 | disable TTx registers on 68030 + movl #0,a0@ + .long 0xf0100800 | movl a0@,tt0 + .long 0xf0100c00 | movl a0@,tt1 + +LnokillTT: + lea _C_LABEL(protorp),a0 + movl #0x80000202,a0@ | nolimit + share global + 4 byte PTEs + movl a1,a0@(4) | + segtable address + pmove a0@,srp | load the supervisor root pointer + movl #0x80000002,a0@ | reinit upper half for CRP loads + lea _ASM_LABEL(longscratch),a2 + movl #0x82c0aa00,a2@ | value to load TC with + pmove a2@,tc | load it + +Lloaddone: + +/* + * Should be running mapped from this point on + */ +/* select the software page size now */ + lea _ASM_LABEL(tmpstk),sp | temporary stack +#if defined(UVM) + jbsr _C_LABEL(uvm_setpagesize) | select software page size +#else + jbsr _C_LABEL(vm_set_page_size) | select software page size +#endif + +/* set kernel stack, user SP, proc0, 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 + +/* flush TLB and turn on caches */ + jbsr _C_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) +#ifdef __notyet__ + tstl _C_LABEL(ectype) + jeq Lnocache0 + | Enable external cache here +#endif + +Lnocache0: +/* Final setup for call to main(). */ + jbsr _C_LABEL(mac68k_init) + movw #PSL_LOWIPL,sr | lower SPL ; enable interrupts + +/* + * 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 _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 */ -Ljmp0panic: - .asciz "kernel jump to zero" - .even +/* + * proc_trampoline + * Call function in register a2 with a3 as an arg and then rei. Note + * that we restore the stack before calling, thus giving "a2" more stack. + * (for the case that, e.g., if curproc had a deeply nested call chain...) + * cpu_fork() also depends on struct frame being a second arg to the + * function in a2. + */ +GLOBAL(proc_trampoline) + movl a3,sp@- | push function arg (curproc) + jbsr a2@ | call function + addql #4,sp | pop arg + movl sp@(FR_SP),a0 | usp to a0 + movl a0,usp | setup user's stack pointer + movml sp@+,#0x7fff | restore all but sp + addql #8,sp | pop sp and stack adjust + jra _ASM_LABEL(rei) | all done /* * Trap/interrupt vector routines */ +#include <m68k/m68k/trap_subr.s> - .globl _trap, _nofault, _longjmp, _mac68k_buserr_addr -_buserr: - tstl _nofault | device probe? - jeq Lberr | no, handle as usual -#if defined(M68040) - cmpl #MMU_68040,_mmutype | 68040? - jne Lberrfault30 | no, handle as 030 - movl sp@(0x14),_mac68k_buserr_addr - movl _nofault,sp@- | yes, - jbsr _longjmp + .data +GLOBAL(m68k_fault_addr) + .long 0 + +#if defined(M68040) || defined(M68060) +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 +#endif + +#if defined(M68060) +ENTRY_NOPROFILE(buserr60) + 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 + movel sp@(FR_HW+12),d0 | FSLW + btst #2,d0 | branch prediction error? + jeq Lnobpe + movc cacr,d2 + orl #IC60_CABC,d2 | clear all branch cache entries + movc d2,cacr + movl d0,d1 + addql #1,L60bpe + andl #0x7ffd,d1 + jeq _ASM_LABEL(faultstkadjnotrap2) +Lnobpe: +| we need to adjust for misaligned addresses + movl sp@(FR_HW+8),d1 | grab VA + btst #27,d0 | check for mis-aligned access + jeq Lberr3 | no, skip + addl #28,d1 | yes, get into next page + | operand case: 3, + | instruction case: 4+12+12 + andl #PG_FRAME,d1 | and truncate +Lberr3: + movl d1,sp@- + movl d0,sp@- | code is FSLW now. + andw #0x1f80,d0 + jeq Lberr60 | it is a bus error + movl #T_MMUFLT,sp@- | show that we are an MMU fault + jra _ASM_LABEL(faultstkadj) | and deal with it +Lberr60: + tstl _C_LABEL(nofault) | catch bus error? + jeq Lisberr | no, handle as usual + movl sp@(FR_HW+8+8),_C_LABEL(m68k_fault_addr) | save fault addr + movl _C_LABEL(nofault),sp@- | yes, + jbsr _C_LABEL(longjmp) | longjmp(nofault) + /* NOTREACHED */ #endif -Lberrfault30: - movl sp@(0x10),_mac68k_buserr_addr - movl _nofault,sp@- | yes, - jbsr _longjmp | longjmp(nofault) -Lberr: #if defined(M68040) - cmpl #MMU_68040,_mmutype | 68040? - jne _addrerr | no, skip +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 - lea sp@(FR_HW),a1 | grab base of HW berr frame + movl sp@(FR_HW+20),d1 | get fault address moveq #0,d0 - movw a1@(12),d0 | grab SSW - movl a1@(20),d1 | and fault VA - btst #11,d0 | check for mis-aligned access - jeq Lberr2 | no, skip - addl #3,d1 | yes, get into next page + 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 -Lberr2: - movl d1,sp@- | push fault VA - movl d0,sp@- | and padded SSW - btst #10,d0 | ATC bit set? - jeq Lisberr | no, must be a real bus error - movc dfc,d1 | yes, get MMU fault - movc d0,dfc | store faulting function code - movl sp@(4),a0 | get faulting address - .word 0xf568 | ptestr a0@ - movc d1,dfc - .long 0x4e7a0805 | movc mmusr,d0 - movw d0,sp@ | save (ONLY LOW 16 BITS!) - jra Lismerr +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 -_addrerr: - clrl sp@- | pad SR to longword + +ENTRY_NOPROFILE(busaddrerr2030) +#if !(defined(M68020) || defined(M68030)) + jra _badtrap +#else + 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 - lea sp@(FR_HW),a1 | grab base of HW berr frame -#if defined(M68040) - cmpl #MMU_68040,_mmutype | 68040? - jne Lbenot040 | no, skip - movl a1@(8),sp@- | yes, push fault address - clrl sp@- | no SSW for address fault - jra Lisaerr | go deal with it -Lbenot040: -#endif moveq #0,d0 - movw a1@(10),d0 | grab SSW for fault processing + 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,a1@(10) | for hardware, too + 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,a1@(10) | for hardware, too + movw d0,sp@(FR_HW+10) | for hardware too LbeX1: btst #8,d0 | data fault? jeq Lbe0 | no, check for hard cases - movl a1@(16),d1 | fault address is as given in frame - jra Lbe10 | that's it! + movl sp@(FR_HW+16),d1 | fault address is as given in frame + jra Lbe10 | thats it Lbe0: - btst #4,a1@(6) | long (type B) stack frame? + btst #4,sp@(FR_HW+6) | long (type B) stack frame? jne Lbe4 | yes, go handle - movl a1@(2),d1 | no, can use save PC + 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 @@ -204,14 +491,14 @@ Lbe3: addql #2,d1 | yes, adjust address jra Lbe10 | done Lbe4: - movl a1@(36),d1 | long format, use stage B address + 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 a1@(6),d0 | get frame format/vector offset + 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 @@ -221,7 +508,7 @@ Lbe10: jne Lbe10a movql #1,d0 | user program access FC | (we dont seperate data/program) - btst #5,a1@ | supervisor mode? + btst #5,sp@(FR_HW+8) | supervisor mode? jeq Lbe10a | if no, done movql #5,d0 | else supervisor program access Lbe10a: @@ -231,89 +518,74 @@ Lbe10a: btst #2,d1 | invalid (incl. limit viol. and berr)? jeq Lmightnotbemerr | no -> wp check btst #7,d1 | is it MMU table berr? - jeq Lismerr | no, must be fast - jra Lisberr1 | real bus err needs not be fast. + 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? - jeq Lisberr1 | yes, was not WPE, must be bus err -Lismerr: - movl #T_MMUFLT,sp@- | show that we are an MMU fault - jra Ltrapnstkadj | and deal with it + 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 Ltrapnstkadj | and deal with it + jra _ASM_LABEL(faultstkadj) | and deal with it Lisberr1: clrw sp@ | re-clear pad word -Lisberr: + 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 +Lisberr: | also used by M68040/60 movl #T_BUSERR,sp@- | mark bus error -Ltrapnstkadj: - jbsr _trap | handle the error - 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 Lstkadj | yes, go to it - moveml sp@+,#0x7FFF | no, restore most user regs - addql #8,sp | toss SSP and pad - jra rei | all done -Lstkadj: - 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 - jra rei | all done + jra _ASM_LABEL(faultstkadj) | and deal with it /* * FP exceptions. */ -_fpfline: +ENTRY_NOPROFILE(fpfline) #if defined(M68040) - cmpl #FPU_68040,_fputype | 68040? (see fpu.c) + cmpl #FPU_68040,_C_LABEL(fputype) | 68040 FPU? jne Lfp_unimp | no, skip FPSP cmpw #0x202c,sp@(6) | format type 2? - jne Lfp_unimp | no, FPEMUL or illinst + jne _C_LABEL(illinst) | no, not an FP emulation Ldofp_unimp: #ifdef FPSP - .globl fpsp_unimp - jmp fpsp_unimp | go handle in fpsp + jmp _ASM_LABEL(fpsp_unimp) | yes, go handle it #endif Lfp_unimp: -#endif +#endif /* M68040 */ #ifdef FPU_EMULATE - clrl sp@- | pad SR to longword - moveml #0xFFFF,sp@- | save user registers - moveq #T_FPEMULI,d0 | denote it as an FP emulation trap. - jra fault | do it. + 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 _illinst + jra _C_LABEL(illinst) #endif -_fpunsupp: +ENTRY_NOPROFILE(fpunsupp) #if defined(M68040) - cmpl #FPU_68040,_fputype | 68040? (see fpu.c) - jne Lfp_unsupp | no, treat as illinst + cmpl #FPU_68040,_C_LABEL(fputype) | 68040 FPU? + jne _C_LABEL(illinst) | no, treat as illinst #ifdef FPSP - .globl fpsp_unsupp - jmp fpsp_unsupp | yes, go handle it + jmp _ASM_LABEL(fpsp_unsupp) | yes, go handle it #endif Lfp_unsupp: -#endif +#endif /* M68040 */ #ifdef FPU_EMULATE - clrl sp@- | pad SR to longword - moveml #0xFFFF,sp@- | save user registers - moveq #T_FPEMULD,d0 | denote it as an FP emulation trap. - jra fault | do it. + 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 _illinst + jra _C_LABEL(illinst) #endif /* @@ -322,17 +594,18 @@ Lfp_unsupp: * and may cause signal delivery, we need to test for stack adjustment * after the trap call. */ -_fpfault: - clrl sp@- | pad SR to longword +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 _curpcb,a0 | current pcb + movl _C_LABEL(curpcb),a0 | current pcb lea a0@(PCB_FPCTX),a0 | address of FP savearea fsave a0@ | save state -#if defined(M68040) - cmpl #MMU_68040,_mmutype | if 68040, (060 ha!), etc... +#if defined(M68040) || defined(M68060) + /* always null state frame on 68040, 68060 */ + cmpl #CPU_68040,_C_LABEL(cputype) jle Lfptnull #endif tstb a0@ | null state frame? @@ -341,111 +614,40 @@ _fpfault: 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 + fmovem fpsr,sp@- | push fpsr as code argument frestore a0@ | restore state movl #T_FPERR,sp@- | push type arg - jra Ltrapnstkadj | call trap and deal with stack cleanup - -/* - * Coprocessor and format errors can generate mid-instruction stack - * frames and cause signal delivery hence we need to check for potential - * stack adjustment. - */ -_coperr: - clrl sp@- - moveml #0xFFFF,sp@- - movl usp,a0 | get and save - movl a0,sp@(FR_SP) | the user stack pointer - clrl sp@- | no VA arg - clrl sp@- | or code arg - movl #T_COPERR,sp@- | push trap type - jra Ltrapnstkadj | call trap and deal with stack adjustments - -_fmterr: - clrl sp@- - moveml #0xFFFF,sp@- - movl usp,a0 | get and save - movl a0,sp@(FR_SP) | the user stack pointer - clrl sp@- | no VA arg - clrl sp@- | or code arg - movl #T_FMTERR,sp@- | push trap type - jra Ltrapnstkadj | call trap and deal with stack adjustments + 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. */ -_illinst: - clrl sp@- - moveml #0xFFFF,sp@- - moveq #T_ILLINST,d0 - jra fault - -_zerodiv: - clrl sp@- - moveml #0xFFFF,sp@- - moveq #T_ZERODIV,d0 - jra fault - -_chkinst: - clrl sp@- - moveml #0xFFFF,sp@- - moveq #T_CHKINST,d0 - jra fault - -_trapvinst: - clrl sp@- - moveml #0xFFFF,sp@- - moveq #T_TRAPVINST,d0 - jra fault - -_privinst: - clrl sp@- - moveml #0xFFFF,sp@- - moveq #T_PRIVINST,d0 - jra fault - .globl fault -fault: - movl usp,a0 | get and save - movl a0,sp@(FR_SP) | the user stack pointer - clrl sp@- | no VA arg - clrl sp@- | or code arg - movl d0,sp@- | push trap type - jbsr _trap | handle trap - lea sp@(12),sp | pop value args - movl sp@(FR_SP),a0 | restore - movl a0,usp | user SP - moveml sp@+,#0x7FFF | restore most user regs - addql #8,sp | pop SP and pad word - jra rei | all done - - .globl _straytrap -_badtrap: +ENTRY_NOPROFILE(badtrap) moveml #0xC0C0,sp@- | save scratch regs movw sp@(22),sp@- | push exception vector info - clrw sp@- | and pad + clrw sp@- movl sp@(22),sp@- | and PC - jbsr _straytrap | report + jbsr _C_LABEL(straytrap) | report addql #8,sp | pop args - moveml sp@+, #0x0303 | restore regs - jra rei + moveml sp@+,#0x0303 | restore regs + jra _ASM_LABEL(rei) | all done - .globl _syscall -_trap0: +ENTRY_NOPROFILE(trap0) clrl sp@- | pad SR to longword 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 _syscall | handle it + jbsr _C_LABEL(syscall) | handle it addql #4,sp | pop syscall arg - tstl _astpending + tstl _C_LABEL(astpending) jne Lrei2 - tstb _ssir + tstb _C_LABEL(ssir) jeq Ltrap1 movw #SPL1,sr - tstb _ssir + tstb _C_LABEL(ssir) jne Lsir1 Ltrap1: movl sp@(FR_SP),a0 | grab and restore @@ -455,192 +657,294 @@ Ltrap1: rte /* - * Our native 4.3 implementation uses trap 1 as sigreturn() and trap 2 - * as a breakpoint trap. + * Trap 1 - sigreturn */ -_trap1: - jra sigreturn +ENTRY_NOPROFILE(trap1) + jra _ASM_LABEL(sigreturn) -_trap2: - jra _trace +/* + * Trap 2 - trace trap + */ +ENTRY_NOPROFILE(trap2) + jra _C_LABEL(trace) /* - * Trap 12 is the entry point for the cachectl "syscall" (both HPUX & BSD) + * Trap 12 is the entry point for the cachectl "syscall" (both HP-UX & BSD) * cachectl(command, addr, length) * command in d0, addr in a1, length in d1 */ - .globl _cachectl -_trap12: +ENTRY_NOPROFILE(trap12) movl d1,sp@- | push length movl a1,sp@- | push addr movl d0,sp@- | push command - jbsr _cachectl | do it + jbsr _C_LABEL(cachectl) | do it lea sp@(12),sp | pop args - jra rei | all done + jra _ASM_LABEL(rei) | all done /* - * Trap 15 is used for: - * - KGDB traps - * - trace traps for SUN binaries (not fully supported yet) - * We just pass it on and let trap() sort it all out + * Trace (single-step) trap. Kernel-mode is special. + * User mode traps are simply passed on to trap(). */ -_trap15: - clrl sp@- +ENTRY_NOPROFILE(trace) + clrl sp@- | stack adjust count moveml #0xFFFF,sp@- -#ifdef KGDB - moveq #T_TRAP15,d0 + moveq #T_TRACE,d0 movw sp@(FR_HW),d1 | get PSW - andw #PSL_S,d1 | from user mode? - jeq fault | yes, just a regular fault - movl d0,sp@- - .globl _kgdb_trap_glue - jbsr _kgdb_trap_glue | returns if no debugger - addl #4,sp -#endif - moveq #T_TRAP15,d0 - jra fault + andw #PSL_S,d1 | from system mode? + jne Lkbrkpt | yes, kernel breakpoint + jra _ASM_LABEL(fault) | no, user-mode fault /* - * Hit a breakpoint (trap 1 or 2) instruction. - * Push the code and treat as a normal 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(). */ -_trace: - clrl sp@- +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 were 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 - moveq #T_TRACE,d0 - movw sp@(FR_HW),d1 | get SSW - andw #PSL_S,d1 | from user mode? - jeq fault | yes, just a regular fault - movl d0,sp@- - jbsr _kgdb_trap_glue | returns if no debugger - addl #4,sp + | 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 - moveq #T_TRACE,d0 - jra fault - -/* - * The sigreturn() syscall comes here. It requires special handling - * because we must open a hole in the stack to fill in the (possibly much - * larger) original stack frame. - */ -sigreturn: - lea sp@(-84),sp | leave enough space for largest frame - movl sp@(84),sp@ | move up current 8 byte frame - movl sp@(88),sp@(4) - movl #84,sp@- | default: adjust by 84 bytes - moveml #0xFFFF,sp@- | save user registers - movl usp,a0 | save the user SP - movl a0,sp@(FR_SP) | in the savearea - movl #SYS_sigreturn,sp@- | push syscall number - jbsr _syscall | handle it - addql #4,sp | pop syscall# - movl sp@(FR_SP),a0 | grab and restore - movl a0,usp | user SP - lea sp@(FR_HW),a1 | pointer to HW frame - movw sp@(FR_ADJ),d0 | do we need to adjust the stack? - jeq Lsigr1 | no, just continue - moveq #92,d1 | total size - subw d0,d1 | - hole size = frame size - lea a1@(92),a0 | destination - addw d1,a1 | source - lsrw #1,d1 | convert to word count - subqw #1,d1 | minus 1 for dbf -Lsigrlp: - movw a1@-,a0@- | copy a word - dbf d1,Lsigrlp | continue - movl a0,a1 | new HW frame base -Lsigr1: - movl a1,sp@(FR_SP) | new SP value - moveml sp@+,#0x7FFF | restore user registers - movl sp@,sp | and our SP - jra rei | all done +#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. * - * Level 0: Spurious: ignored. - * Level 1: HIL - * Level 2: - * Level 3: Internal HP-IB - * Level 4: "Fast" HP-IBs, SCSI - * Level 5: DMA, Ethernet, Built-in RS232 - * Level 6: Clock - * Level 7: Non-maskable: parity errors, RESET key + * Most 68k-based Macintosh computers + * + * Level 0: Spurious: ignored + * Level 1: VIA1 (clock, ADB) + * Level 2: VIA2 (NuBus, SCSI) + * Level 3: + * Level 4: Serial (SCC) + * Level 5: + * Level 6: + * Level 7: Non-maskable: parity errors, RESET button * - * ALICE: Here are our assignments: + * On the Q700, Q900 and Q950 in "A/UX mode": this should become: * - * Level 0: Spurious: ignored - * Level 1: VIA1 (clock, ADB) - * Level 2: VIA2 (NuBus, SCSI) - * Level 3: - * Level 4: Serial (SCC) - * Level 5: - * Level 6: - * Level 7: Non-maskable: parity errors, RESET button, FOO key + * Level 0: Spurious: ignored + * Level 1: Software + * Level 2: VIA2 (except ethernet, sound) + * Level 3: Ethernet + * Level 4: Serial (SCC) + * Level 5: Sound + * Level 6: VIA1 + * Level 7: NMIs: parity errors, RESET button, YANCC error * - * On the Q700, at least, in "A/UX mode," this should become: + * On the 660AV and 840AV: * - * Level 0: Spurious: ignored - * Level 1: Software - * Level 2: VIA2 (except ethernet, sound) - * Level 3: Ethernet - * Level 4: Serial (SCC) - * Level 5: Sound - * Level 6: VIA1 - * Level 7: NMIs: parity errors, RESET button, YANCC error + * Level 0: Spurious: ignored + * Level 1: VIA1 (clock, ADB) + * Level 2: VIA2 (NuBus, SCSI) + * Level 3: PSC device interrupt + * Level 4: PSC DMA and serial + * Level 5: ??? + * Level 6: ??? + * Level 7: NMIs: parity errors?, RESET button */ -/* BARF We must re-configure this. */ - .globl _hardclock, _nmihand - .globl _mrg_VBLQueue - -_spurintr: -_lev3intr: -_lev5intr: -_lev6intr: - addql #1,_intrcnt+0 - addql #1,_cnt+V_INTR - jra rei - -_lev1intr: - addql #1,_intrcnt+4 + +ENTRY_NOPROFILE(spurintr) + addql #1,_C_LABEL(intrcnt)+0 +#if defined(UVM) + addql #1,_C_LABEL(uvmexp)+UVMEXP_INTRS +#else + addql #1,_C_LABEL(cnt)+V_INTR +#endif + jra _ASM_LABEL(rei) + +ENTRY_NOPROFILE(lev1intr) + addql #1,_C_LABEL(intrcnt)+4 clrl sp@- moveml #0xFFFF,sp@- movl sp, sp@- - jbsr _via1_intr + jbsr _C_LABEL(via1_intr) addql #4,sp moveml sp@+,#0xFFFF addql #4,sp - addql #1,_cnt+V_INTR - jra rei +#if defined(UVM) + addql #1,_C_LABEL(uvmexp)+UVMEXP_INTRS +#else + addql #1,_C_LABEL(cnt)+V_INTR +#endif + jra _ASM_LABEL(rei) - .globl _real_via2_intr -_lev2intr: - addql #1,_intrcnt+8 +ENTRY_NOPROFILE(lev2intr) + addql #1,_C_LABEL(intrcnt)+8 clrl sp@- moveml #0xFFFF,sp@- movl sp, sp@- - movl _real_via2_intr,a2 + movl _C_LABEL(real_via2_intr),a2 jbsr a2@ addql #4,sp moveml sp@+,#0xFFFF addql #4,sp - addql #1,_cnt+V_INTR - jra rei +#if defined(UVM) + addql #1,_C_LABEL(uvmexp)+UVMEXP_INTRS +#else + addql #1,_C_LABEL(cnt)+V_INTR +#endif + jra _ASM_LABEL(rei) + +ENTRY_NOPROFILE(lev3intr) + addql #1,_C_LABEL(intrcnt)+24 + clrl sp@- + moveml #0xFFFF,sp@- + movl sp, sp@- + movl _C_LABEL(lev3_intrvec),a2 + jbsr a2@ + addql #4,sp + moveml sp@+, #0xFFFF + addql #4,sp +#if defined(UVM) + addql #1,_C_LABEL(uvmexp)+UVMEXP_INTRS +#else + addql #1,_C_LABEL(cnt)+V_INTR +#endif + jra _ASM_LABEL(rei) - .globl _zshard +ENTRY_NOPROFILE(lev4intr) + addql #1,_C_LABEL(intrcnt)+12 + clrl sp@- + moveml #0xFFFF,sp@- + movl sp, sp@- + movl _C_LABEL(lev4_intrvec),a2 + jbsr a2@ + addql #4,sp + tstl d0 + beq normal_rei + moveml sp@+, #0xFFFF + addql #4,sp + rte +normal_rei: + moveml sp@+, #0xFFFF + addql #4,sp +#if defined(UVM) + addql #1,_C_LABEL(uvmexp)+UVMEXP_INTRS +#else + addql #1,_C_LABEL(cnt)+V_INTR +#endif + jra _ASM_LABEL(rei) + +ENTRY_NOPROFILE(lev5intr) + addql #1,_C_LABEL(intrcnt)+28 + clrl sp@- + moveml #0xFFFF,sp@- + movl sp, sp@- + movl _C_LABEL(lev5_intrvec),a2 + jbsr a2@ + addql #4,sp + moveml sp@+, #0xFFFF + addql #4,sp +#if defined(UVM) + addql #1,_C_LABEL(uvmexp)+UVMEXP_INTRS +#else + addql #1,_C_LABEL(cnt)+V_INTR +#endif + jra _ASM_LABEL(rei) -_lev4intr: - /* handle level 4 (SCC) interrupt special... */ - addql #1,_intrcnt+12 +ENTRY_NOPROFILE(lev6intr) + addql #1,_C_LABEL(intrcnt)+32 clrl sp@- - moveml #0xFFFF,sp@- | save registers - clrl sp@- | push 0 - jsr _zshard | call C routine to deal with it (ser.c/zs.c) - addl #4,sp | throw away arg - moveml sp@+, #0xFFFF | restore registers + moveml #0xFFFF,sp@- + movl sp, sp@- + movl _C_LABEL(lev6_intrvec),a2 + jbsr a2@ + addql #4,sp + moveml sp@+, #0xFFFF addql #4,sp - rte | return from exception +#if defined(UVM) + addql #1,_C_LABEL(uvmexp)+UVMEXP_INTRS +#else + addql #1,_C_LABEL(cnt)+V_INTR +#endif + jra _ASM_LABEL(rei) + +ENTRY_NOPROFILE(lev7intr) + addql #1,_C_LABEL(intrcnt)+16 + clrl sp@- | pad SR to longword + 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 SSP and align word + jra _ASM_LABEL(rei) /* * We could tweak rtclock_intr and gain 12 cycles on the 020 and 030 by @@ -648,9 +952,7 @@ _lev4intr: * badly on the 040. Aligning the stack takes 10 more cycles than this * code does, so it's a good compromise. */ - .globl _rtclock_intr - -_rtclock_intr: +ENTRY_NOPROFILE(rtclock_intr) movl d2,sp@- | save d2 movw sr,d2 | save SPL movw #SPL2,sr | raise SPL to splclock() @@ -658,29 +960,20 @@ _rtclock_intr: movl a1@(64),sp@- | push ps movl a1@(68),sp@- | push pc movl sp,sp@- | push pointer to ps, pc - jbsr _hardclock | call generic clock int routine + jbsr _C_LABEL(hardclock) | call generic clock int routine lea sp@(12),sp | pop params - jbsr _mrg_VBLQueue | give programs in the VBLqueue a chance - addql #1,_intrcnt+20 | add another system clock interrupt - addql #1,_cnt+V_INTR | chalk up another interrupt + jbsr _C_LABEL(mrg_VBLQueue) | give programs in the VBLqueue a chance + addql #1,_C_LABEL(intrcnt)+20 +#if defined(UVM) + addql #1,_C_LABEL(uvmexp)+UVMEXP_INTRS +#else + addql #1,_C_LABEL(cnt)+V_INTR +#endif movw d2,sr | restore SPL movl sp@+,d2 | restore d2 movl #1,d0 | clock taken care of rts | go back from whence we came -_lev7intr: - addql #1, _intrcnt+16 - clrl sp@- | pad SR to longword - 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 SSP and align word - jra rei | all done - /* * Emulation of VAX REI instruction. * @@ -688,22 +981,17 @@ _lev7intr: * (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 identifying that we need an AST 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. */ - .comm _ssir,1 - .globl _astpending - .globl rei -rei: -#undef STACKCHECK -#ifdef STACKCHECK - tstl _panicstr | have we paniced? - jne Ldorte1 | yes, do not make matters worse -#endif - tstl _astpending | AST pending? + +BSS(ssir,1) + +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? @@ -717,7 +1005,7 @@ Lrei2: clrl sp@- | VA == none clrl sp@- | code == none movl #T_ASTFLT,sp@- | type == async system trap - jbsr _trap | go handle it + 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 @@ -725,11 +1013,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 @@ -740,13 +1024,9 @@ 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? + tstb _C_LABEL(ssir) | SIR pending? jeq Ldorte | no, all done movl d0,sp@- | need a scratch register movw sp@(4),d0 | get SR @@ -755,7 +1035,7 @@ Lchksir: movl sp@+,d0 | restore scratch register Lgotsir: movw #SPL1,sr | prevent others from servicing int - tstb _ssir | too late? + tstb _C_LABEL(ssir) | too late? jeq Ldorte | yes, oh well... clrl sp@- | stack adjust moveml #0xFFFF,sp@- | save all registers @@ -765,495 +1045,78 @@ Lsir1: clrl sp@- | VA == none clrl sp@- | code == none movl #T_SSIR,sp@- | type == software interrupt - jbsr _trap | go handle it + 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 -#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 /* - * 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. + * Use common m68k sigcode. */ - .data -| Scratch memory. Careful when messing with these... -longscratch: .long 0 -longscratch2: .long 0 -pte_tmp: .long 0 | for get_pte() -_macos_crp1: .long 0 -_macos_crp2: .long 0 -_macos_tc: .long 0 -_macos_tt0: .long 0 -_macos_tt1: .long 0 -_bletch: .long 0 -_esym: .long 0 - .globl _esym, _bletch - .globl _macos_crp1, _macos_crp2, _macos_tc - .globl _macos_tt0, _macos_tt1 - -/* - * Initialization - */ - .even - - .text - .globl _edata - .globl _etext - .globl start - .globl _getenvvars | in machdep.c - .globl _setmachdep | in machdep.c - -start: - movw #PSL_HIGHIPL,sr | no interrupts. ever. - lea tmpstk,sp | give ourselves a temporary stack - movql #0,d0 | disables caches - movc d0,cacr - - /* Initialize source/destination control registers for movs */ - movql #FC_USERD,d0 | user space - movc d0,sfc | as source - movc d0,dfc | and destination of transfers - - /* Determine MMU/MPU from what we can test empirically */ - 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 - - movl #CACHE_OFF,d0 | disable and clear both caches - movc d0,cacr - lea _mmutype,a0 | no, we have 68030 - movl #MMU_68030,a0@ | set to reflect 68030 PMMU - lea _cputype,a0 - movl #CPU_68030,a0@ | and 68030 MPU - 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 - - movql #CACHE40_OFF,d0 | now turn it back off - movc d0,cacr | before we access any data - .word 0xf4f8 | cpusha bc ;push and invalidate caches - lea _mmutype,a0 - movl #MMU_68040,a0@ | Reflect 68040 MMU - lea _cputype,a0 - movl #CPU_68040,a0@ | and 68040 MPU - jra Lstart1 - -Lis68020: - movl #CACHE_OFF,d0 | disable and clear cache - movc d0,cacr - lea _mmutype,a0 | Must be 68020+68851 - movl #MMU_68851,a0@ | Reflect 68851 PMMU - lea _cputype,a0 - movl #CPU_68020,a0@ | and 68020 MPU - -Lstart1: - /* - * Some parameters provided by MacOS - * - * LAK: This section is the new way to pass information from the booter - * to the kernel. At A1 there is an environment variable which has - * a bunch of stuff in ascii format, "VAR=value\0VAR=value\0\0". - */ - movl a1,sp@- | Address of buffer - movl d4,sp@- | Some flags... (mostly not used) - jbsr _getenvvars | Parse the environment buffer - addql #8, sp - jbsr _setmachdep | Set some machine-dep stuff - - jbsr _vm_set_page_size | Set the vm system page size, now. - jbsr _consinit | XXX Should only be if graybar on - -/* - * Figure out MacOS mappings and bootstrap BSD - */ - lea _macos_tc,a0 | get current TC - cmpl #MMU_68040, _mmutype | check to see if 68040 - jeq Lget040TC - pmove tc,a0@ - jra do_bootstrap - -Lget040TC: -#ifdef __notyet__ - .long 0x4e7a0003 | movc tc,d0 -#else - movql #0,d0 - .long 0x4e7b0003 | movc d0,tc ;Disable MMU -#endif - movl d0,a0@ - -do_bootstrap: - movl a0@,sp@- | get MacOS mapping, relocate video, - jbsr _bootstrap_mac68k | bootstrap pmap, et al. - addql #4,sp - -/* - * Prepare to enable MMU. - */ - movl _Sysseg,a1 | system segment table addr - addl _load_addr,a1 | Make it physical addr - - cmpl #MMU_68040,_mmutype - jne Lenablepre040MMU | if not 040, skip - - movql #0,d0 - .long 0x4e7b0003 | movc d0,tc ;Disable MMU - .long 0x4e7b0004 | movc d0,itt0 ;Disable itt0 - .long 0x4e7b0005 | movc d0,itt1 ;Disable itt1 - .long 0x4e7b0006 | movc d0,dtt0 ;Disable dtt0 - .long 0x4e7b0007 | movc d0,dtt1 ;Disable dtt1 - movl a1,d1 - .word 0xf518 | pflusha - .long 0x4e7b1807 | movc d1,srp - movl #0x8000,d0 - .long 0x4e7b0003 | movc d0,tc ;Enable MMU - movl #CACHE40_ON,d0 - movc d0,cacr | turn on both caches - jra Lloaddone - -Lenablepre040MMU: - tstl _mmutype | TTx instructions will break 68851 - jgt LnokillTT - - lea longscratch,a0 | disable TTx registers on 68030 - movl #0,a0@ - .long 0xf0100800 | movl a0@,tt0 - .long 0xf0100c00 | movl a0@,tt1 - -LnokillTT: - lea _protorp,a0 - movl #0x80000202,a0@ | nolimit + share global + 4 byte PTEs - movl a1,a0@(4) | + segtable address - pmove a0@,srp | load the supervisor root pointer - movl #0x80000002,a0@ | reinit upper half for CRP loads - lea longscratch,a2 - movl #0x82c0aa00,a2@ | value to load TC with - pmove a2@,tc | load it - -Lloaddone: - -/* - * Should be running mapped from this point on - */ - -/* init mem sizes */ - -/* set kernel stack, user SP, proc0, and initial pcb */ - movl _proc0paddr,a1 | get proc0 pcb addr - lea a1@(USPACE-4),sp | set kernel stack to end of area - lea _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,_curpcb | proc0 is running - 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) -/* XXX Enable external cache here. */ - -Lnocache0: -/* final setup for C code */ - jbsr _setmachdep | Set some machine-dep stuff - movw #PSL_LOWIPL,sr | lower SPL ; enable interrupts - -/* - * 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 _proc0,a0 | save pointer to frame - movl sp,a0@(P_MD_REGS) | in proc0.p_md.md_regs - - jra _main - - pea Lmainreturned | Yow! Main returned! - jbsr _panic - /* NOTREACHED */ -Lmainreturned: - .asciz "main() returned" - .even - -/* - * proc_trampoline - * Call function in register a2 with a3 as an arg and then rei. - */ - .globl _proc_trampoline -_proc_trampoline: - movl a3,sp@- | push function arg (curproc) - jbsr a2@ | call function - addql #4,sp | pop arg - movl sp@(FR_SP),a0 | usp to a0 - movl a0,usp | setup user's stack pointer - movml sp@+,#0x7fff | restore all but sp - addql #8,sp | pop sp and stack adjust - jra rei | all done - - -/* - * Icode is copied out to process 1 to exec init. - * If the exec fails, process 1 exits. - */ - .globl _icode,_szicode - .text -_icode: - clrl sp@- - pea pc@((argv-.)-2) - pea pc@((init-.)-2) - clrl sp@- - moveq #SYS_execve,d0 - trap #0 - moveq #SYS_exit,d0 - trap #0 -init: - .asciz "/sbin/init" - .even -argv: - .long init+6-_icode | argv[0] = "init" ("/sbin/init" + 6) - .long eicode-_icode | argv[1] follows icode after copyout - .long 0 -eicode: - -_szicode: - .long _szicode-_icode - - -/* - * Signal "trampoline" code (18 bytes). Invoked from RTE setup by sendsig(). - * - * Stack looks like: - * - * sp+0 -> signal number - * sp+4 pointer to siginfo (sip) - * 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 - .data - .align 2 -_sigcode: - movl sp@(12),a0 | signal handler addr (4 bytes) - jsr a0@ | call signal handler (2 bytes) - addql #4,sp | pop signo (2 bytes) - 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 +#include <m68k/m68k/sigcode.s> /* * Primitives */ -#include <m68k/asm.h> - /* * Use common m68k support routines. */ #include <m68k/m68k/support.s> /* - * The following primitives manipulate the run queues. - * _whichqs tells which of the 32 queues _qs have processes in them. - * Setrunqueue puts processes into queues, remrunqueue removes them from - * queues. The running process is on no queue, other processes are on a queue - * related to p->p_priority, divided by 4 actually to shrink the 0-127 - * range of priorities into the 32 available queues. - */ - - .globl _whichqs,_qs,_cnt,_panic - .globl _curproc,_want_resched - -/* - * setrunqueue(p) - * - * Call should be made at spl6(), and p->p_stat should be SRUN - */ -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 -#endif - clrl d0 - movb a0@(P_PRIORITY),d0 - lsrb #2,d0 - movl _whichqs,d1 - bset d0,d1 - movl d1,_whichqs - lslb #3,d0 - addl #_qs,d0 - movl d0,a0@(P_FORW) - movl d0,a1 - movl a1@(P_BACK),a0@(P_BACK) - movl a0,a1@(P_BACK) - movl a0@(P_BACK),a1 - movl a0,a1@(P_FORW) - rts -#ifdef DIAGNOSTIC -Lset1: - movl #Lset2,sp@- - jbsr _panic -Lset2: - .asciz "setrunqueue" - .even -#endif - -/* - * Remrq(proc *p) - * - * Call should be made at spl6(). + * Use common m68k process manipulation routines. */ -ENTRY(remrunqueue) - movl sp@(4),a0 | proc *p - movb a0@(P_PRIORITY),d0 | d0 = processes priority -#ifdef DIAGNOSTIC - lsrb #2,d0 | d0 /= 4 - movl _whichqs,d1 | d1 = whichqs - bclr d0,d1 | clear bit in whichqs corresponding to - | processes priority - jeq Lrem2 | if (d1 & (1 << d0)) == 0 -#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 -#ifndef DIAGNOSTIC - lsrb #2,d0 - movl _whichqs,d1 -#endif - bclr d0,d1 - movl d1,_whichqs -Lrem1: - rts -#ifdef DIAGNOSTIC -Lrem2: - movl #Lrem3,sp@- - jbsr _panic -Lrem3: - .asciz "remrunqueue" - .even -#endif - -Lsw0: - .asciz "cpu_switch" - .even +#include <m68k/m68k/proc_subr.s> - .globl _curpcb - .globl _masterpaddr | XXX compatibility (debuggers) - .data -_masterpaddr: | XXX compatibility (debuggers) -_curpcb: +GLOBAL(curpcb) +GLOBAL(masterpaddr) | XXX compatibility (debuggers) .long 0 -pcbflag: - .byte 0 | copy of pcb_flags low byte + +ASLOCAL(mdpflag) + .byte 0 | copy of proc md_flags low byte .align 2 - .comm nullpcb,SIZEOF_PCB - .text + +ASBSS(nullpcb,SIZEOF_PCB) /* - * switch_exit() - * At the exit of a process, do a switch for the last time. - * Switch to a safe stack and PCB, then deallocate the process's resources + * At exit of a process, do a switch for the last time. + * Switch to a safe stack and PCB, and select a new process to run. The + * old stack and u-area will be freed by the reaper. */ ENTRY(switch_exit) movl sp@(4),a0 - movl #nullpcb,_curpcb | save state into garbage pcb - lea tmpstk,sp | goto a tmp stack + /* save state into garbage pcb */ + movl #_ASM_LABEL(nullpcb),_C_LABEL(curpcb) + lea _ASM_LABEL(tmpstk),sp | goto a tmp stack - /* Schedule the vmspace and stack to be freed. */ - movl a0,sp@- | exit2(p) - jbsr _C_LABEL(exit2) - lea sp@(4),sp | pop args + /* Schedule the vmspace and stack to be freed. */ + movl a0,sp@- | exit2(p) + jbsr _C_LABEL(exit2) + lea sp@(4),sp | pop args - jra _cpu_switch + jra _C_LABEL(cpu_switch) /* - * When no processes are on the runq, Swtch branches to idle + * When no processes are on the runq, Swtch branches to Idle * to wait for something to come ready. */ - .globl Idle -Idle: +ASENTRY_NOPROFILE(Idle) stop #PSL_LOWIPL movw #PSL_HIGHIPL,sr - movl _whichqs,d0 - jeq Idle + movl _C_LABEL(whichqs),d0 + jeq _ASM_LABEL(Idle) jra Lsw1 Lbadsw: - movl #Lsw0,sp@- - jbsr _panic + PANIC("switch") /*NOTREACHED*/ /* @@ -1268,20 +1131,20 @@ Lbadsw: * bit). For now, we just always flush the full ATC. */ ENTRY(cpu_switch) - movl _curpcb,a0 | current pcb + movl _C_LABEL(curpcb),a0 | current pcb movw sr,a0@(PCB_PS) | save sr before changing ipl #ifdef notyet - movl _curproc,sp@- | remember last proc running -#endif /* notyet */ - clrl _curproc + movl _C_LABEL(curproc),sp@- | remember last proc running +#endif + clrl _C_LABEL(curproc) /* * 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 + movl _C_LABEL(whichqs),d0 + jeq _ASM_LABEL(Idle) Lsw1: movl d0,d1 negl d0 @@ -1291,7 +1154,7 @@ Lsw1: movl d1,d0 lslb #3,d1 | convert queue number to index - addl #_qs,d1 | locate queue (q) + addl #_C_LABEL(qs),d1 | locate queue (q) movl d1,a1 movl a1@(P_FORW),a0 | p = q->p_forw cmpal d1,a0 | anyone on queue? @@ -1301,27 +1164,27 @@ Lsw1: 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, reset bit - movl d1,_whichqs + movl _C_LABEL(whichqs),d1 + bclr d0,d1 | no, clear bit + movl d1,_C_LABEL(whichqs) Lsw2: - movl a0,_curproc - clrl _want_resched + movl a0,_C_LABEL(curproc) + clrl _C_LABEL(want_resched) #ifdef notyet movl sp@+,a1 cmpl a0,a1 | switching to same proc? jeq Lswdone | yes, skip save and restore -#endif /* notyet */ +#endif /* * Save state of previous process in its pcb. */ - movl _curpcb,a1 + movl _C_LABEL(curpcb),a1 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 _fputype | Do we have an fpu? - jeq Lswnofpsave | No? Then don't attempt save. + 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? @@ -1335,61 +1198,35 @@ Lswnofpsave: jne Lbadsw cmpb #SRUN,a0@(P_STAT) jne Lbadsw -#endif /* DIAGNOSTIC */ +#endif clrl a0@(P_BACK) | clear back link - movb a0@(P_MD_FLAGS+3),pcbflag | low byte of p_md.md_flags + movb a0@(P_MD_FLAGS+3),mdpflag | low byte of p_md.md_flags movl a0@(P_ADDR),a1 | get p_addr - movl a1,_curpcb + movl a1,_C_LABEL(curpcb) - /* see if pmap_activate needs to be called; should remove this */ - movl a0@(P_VMSPACE),a0 | vmspace = p->p_vmspace -#ifdef DIAGNOSTIC - tstl a0 | map == VM_MAP_NULL? - jeq Lbadsw | panic -#endif /* DIAGNOSTIC */ - movl a0@(VM_PMAP),a0 | pmap = vmspace->vm_map.pmap - tstl a0@(PM_STCHG) | pmap->st_changed? - jeq Lswnochg | no, skip - pea a1@ | push pcb (at p_addr) - pea a0@ | push pmap - jbsr _pmap_activate | pmap_activate(pmap, pcb) - addql #8,sp - movl _curpcb,a1 | restore p_addr -Lswnochg: + /* + * Activate the 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 - lea tmpstk,sp | now goto a tmp stack for NMI -#if defined(M68040) - cmpl #MMU_68040,_mmutype | 68040? - jne Lres1a | no, skip - .word 0xf518 | yes, pflusha - movl a1@(PCB_USTP),d0 | get USTP - moveq #PGSHIFT,d1 - lsll d1,d0 | convert to addr - .long 0x4e7b0806 | movc d0,urp - jra Lcxswdone -Lres1a: -#endif - movl #CACHE_CLR,d0 - movc d0,cacr | invalidate cache(s) - pflusha | flush entire TLB - movl a1@(PCB_USTP),d0 | get USTP - moveq #PGSHIFT,d1 - lsll d1,d0 | convert to addr - lea _protorp,a0 | CRP prototype - movl d0,a0@(4) | stash USTP - pmove a0@,crp | load new user root pointer -Lcxswdone: moveml a1@(PCB_REGS),#0xFCFC | and registers movl a1@(PCB_USP),a0 movl a0,usp | and USP - tstl _fputype | If we don't have an fpu, + 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) - cmpl #MMU_68040,_mmutype | 68040? + cmpl #MMU_68040,_C_LABEL(mmutype) | 68040? jne Lresnot040 | no, skip clrl sp@- | yes... frestore sp@+ | ...magic! @@ -1407,7 +1244,7 @@ Lnofprest: /* * savectx(pcb) - * Update pcb, saving current processor state. + * Update pcb, saving current processor state. */ ENTRY(savectx) movl sp@(4),a1 @@ -1416,22 +1253,22 @@ ENTRY(savectx) movl a0,a1@(PCB_USP) | and save it moveml #0xFCFC,a1@(PCB_REGS) | save non-scratch registers - tstl _fputype | Do we have FPU? - jeq Lsavedone | No? Then don't save state. + 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 Lsavedone | yes, all done + jeq Lsvnofpsave | yes, all done fmovem fp0-fp7,a0@(216) | save FP general registers fmovem fpcr/fpsr/fpi,a0@(312) | save FP control registers -Lsavedone: +Lsvnofpsave: moveq #0,d0 | return 0 rts #if defined(M68040) ENTRY(suline) movl sp@(4),a0 | address to write - movl _curpcb,a1 | current pcb + 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 @@ -1451,7 +1288,7 @@ ENTRY(suline) Lslerr: moveq #-1,d0 Lsldone: - movl _curpcb,a1 | current pcb + movl _C_LABEL(curpcb),a1 | current pcb clrl a1@(PCB_ONFAULT) | clear fault address rts #endif @@ -1462,7 +1299,7 @@ Lsldone: ENTRY(TBIA) __TBIA: #if defined(M68040) - cmpl #MMU_68040,_mmutype | 68040? + cmpl #MMU_68040,_C_LABEL(mmutype) | 68040? jne Lmotommu3 | no, skip .word 0xf518 | yes, pflusha rts @@ -1470,7 +1307,7 @@ Lmotommu3: #endif pflusha #if defined(M68020) - tstl _mmutype + tstl _C_LABEL(mmutype) jgt Ltbia851 #endif movl #DC_CLEAR,d0 @@ -1483,12 +1320,12 @@ Ltbia851: */ ENTRY(TBIS) #ifdef DEBUG - tstl fulltflush | being conservative? - jne __TBIA | yes, flush entire TLB + tstl _ASM_LABEL(fulltflush) | being conservative? + jne _C_LABEL(_TBIA) | yes, flush entire TLB #endif movl sp@(4),a0 #if defined(M68040) - cmpl #MMU_68040,_mmutype | 68040? + cmpl #MMU_68040,_C_LABEL(mmutype) | 68040? jne Lmotommu4 | no, skip movc dfc,d1 moveq #FC_USERD,d0 | user space @@ -1502,7 +1339,7 @@ ENTRY(TBIS) Lmotommu4: #endif #if defined(M68020) - tstl _mmutype + tstl _C_LABEL(mmutype) jle Ltbis851 pflushs #0,#0,a0@ | flush address from both sides rts @@ -1518,18 +1355,18 @@ Ltbis851: */ ENTRY(TBIAS) #ifdef DEBUG - tstl fulltflush | being conservative? - jne __TBIA | yes, flush everything + tstl _ASM_LABEL(fulltflush) | being conservative? + jne _C_LABEL(_TBIA) | yes, flush everything #endif #if defined(M68040) - cmpl #MMU_68040,_mmutype | 68040? + cmpl #MMU_68040,_C_LABEL(mmutype) | 68040? jne Lmotommu5 | no, skip .word 0xf518 | yes, pflusha (for now) XXX rts Lmotommu5: #endif #if defined(M68020) - tstl _mmutype + tstl _C_LABEL(mmutype) jle Ltbias851 pflushs #4,#4 | flush supervisor TLB entries rts @@ -1545,17 +1382,17 @@ Ltbias851: */ ENTRY(TBIAU) #ifdef DEBUG - tstl fulltflush | being conservative? - jne __TBIA | yes, flush everything + tstl _ASM_LABEL(fulltflush) | being conservative? + jne _C_LABEL(_TBIA) | yes, flush everything #endif #if defined(M68040) - cmpl #MMU_68040,_mmutype | 68040? + cmpl #MMU_68040,_C_LABEL(mmutype) | 68040? jne Lmotommu6 | no, skip .word 0xf518 | yes, pflusha (for now) XXX Lmotommu6: #endif #if defined(M68020) - tstl _mmutype + tstl _C_LABEL(mmutype) jle Ltbiau851 pflush #0,#4 | flush user TLB entries rts @@ -1572,7 +1409,7 @@ Ltbiau851: ENTRY(ICIA) #if defined(M68040) ENTRY(ICPA) - cmpl #MMU_68040,_mmutype | 68040? + cmpl #MMU_68040,_C_LABEL(mmutype) | 68040? jne Lmotommu7 | no, skip .word 0xf498 | cinva ic rts @@ -1592,7 +1429,7 @@ Lmotommu7: ENTRY(DCIA) __DCIA: #if defined(M68040) - cmpl #MMU_68040,_mmutype | 68040? + cmpl #MMU_68040,_C_LABEL(mmutype) | 68040? jne Lmotommu8 | no, skip .word 0xf478 | cpusha dc Lmotommu8: @@ -1602,7 +1439,7 @@ Lmotommu8: ENTRY(DCIS) __DCIS: #if defined(M68040) - cmpl #MMU_68040,_mmutype | 68040? + cmpl #MMU_68040,_C_LABEL(mmutype) | 68040? jne Lmotommu9 | no, skip .word 0xf478 | cpusha dc Lmotommu9: @@ -1612,7 +1449,7 @@ Lmotommu9: ENTRY(DCIU) __DCIU: #if defined(M68040) - cmpl #MMU_68040,_mmutype | 68040? + cmpl #MMU_68040,_C_LABEL(mmutype) | 68040? jne LmotommuA | no, skip .word 0xf478 | cpusha dc LmotommuA: @@ -1652,7 +1489,7 @@ ENTRY(DCFP) /* data cache flush page */ ENTRY(PCIA) #if defined(M68040) ENTRY(DCFA) - cmpl #MMU_68040,_mmutype | 68040? + cmpl #MMU_68040,_C_LABEL(mmutype) | 68040? jne LmotommuB | no, skip .word 0xf478 | cpusha dc rts @@ -1668,40 +1505,12 @@ ENTRY(ecacheon) ENTRY(ecacheoff) rts -/* - * Get callers current SP value. - * Note that simply taking the address of a local variable in a C function - * doesn't work because callee saved registers may be outside the stack frame - * defined by A6 (e.g. GCC generated code). - */ - .globl _getsp -_getsp: - movl sp,d0 | get current SP - addql #4,d0 | compensate for return address - rts - - .globl _getsfc, _getdfc -_getsfc: +ENTRY_NOPROFILE(getsfc) movc sfc,d0 rts -_getdfc: - movc dfc,d0 - rts -/* - * Check out a virtual address to see if it's okay to write to. - * - * probeva(va, fc) - * - */ -ENTRY(probeva) - movl sp@(8),d0 - movec d0,dfc - movl sp@(4),a0 - .word 0xf548 | ptestw (a0) - moveq #FC_USERD,d0 | restore DFC to user space - movc d0,dfc - .long 0x4e7a0805 | movec MMUSR,d0 +ENTRY_NOPROFILE(getdfc) + movc dfc,d0 rts /* @@ -1712,19 +1521,20 @@ ENTRY(loadustp) moveq #PGSHIFT,d1 lsll d1,d0 | convert to addr #if defined(M68040) - cmpl #MMU_68040,_mmutype | 68040? + cmpl #MMU_68040,_C_LABEL(mmutype) | 68040? jne LmotommuC | no, skip + .word 0xf518 | pflusha .long 0x4e7b0806 | movec d0, URP rts LmotommuC: #endif - pflusha - lea _protorp,a0 | CRP prototype + pflusha | flush entire TLB + lea _C_LABEL(protorp),a0 | CRP prototype movl d0,a0@(4) | stash USTP pmove a0@,crp | load root pointer - movl #DC_CLEAR,d0 - movc d0,cacr | invalidate on-chip d-cache - rts | since pmove flushes TLB + movl #CACHE_CLR,d0 + movc d0,cacr | invalidate cache(s) + rts /* * Set processor priority level calls. Most are implemented with @@ -1737,7 +1547,7 @@ ENTRY(spl0) moveq #0,d0 movw sr,d0 | get old SR for return movw #PSL_LOWIPL,sr | restore new SR - tstb _ssir | software interrupt pending? + tstb _C_LABEL(ssir) | software interrupt pending? jeq Lspldone | no, all done subql #4,sp | make room for RTE frame movl sp@(4),sp@(2) | position return address @@ -1774,31 +1584,56 @@ Lm68881rdone: /* * Handle the nitty-gritty of rebooting the machine. - * Basically we just jump to the appropriate ROM routine after mapping - * the ROM into its proper home (back in machdep). + * 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. */ - .globl _doboot, _ROMBase -_doboot: - movw #PSL_HIGHIPL,sr | no interrupts +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) +Lnocache5: + movl _C_LABEL(maxaddr),a0 | last page of physical memory + 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 + .word 0xf4f8 | cpusha bc +LmotommuE: +#endif + movl _C_LABEL(maxaddr),a0 + jmp a0@ | jump to last page - cmpl #MMU_68040,_mmutype - jne Ldobootnot040 | It's not an '040 +Lbootcode: + lea a0@(0x800),sp | physical SP in case of NMI + movl _C_LABEL(MacOSROMBase),a1 | Load MacOS ROMBase - movl #CACHE40_OFF,d0 | 68040 cache disable - movc d0, cacr - .word 0xf4f8 | cpusha bc - push and invalidate caches +#if defined(M68040) + cmpl #MMU_68040,_C_LABEL(mmutype) | 68040? + jne LmotommuF | no, skip + movl #0,d0 + movc d0,cacr | caches off + .long 0x4e7b0003 | movc d0,tc (disable MMU) jra Ldoboot1 - -Ldobootnot040: - movl #CACHE_OFF,d0 - movc d0,cacr | disable on-chip cache(s) +LmotommuF: +#endif + movl #0,a3@ | value for pmove to TC (turn off MMU) + pmove a3@,tc | disable MMU Ldoboot1: - movl _MacOSROMBase, _ROMBase | Load MacOS ROMBase - - movl #0x90,a1 | offset of ROM reset routine - addl _ROMBase,a1 | add to ROM base - jra a1@ | and jump to ROM to reset machine + lea a1@(0x90),a1 | offset of ROM reset routine + jmp a1@ | and jump to ROM to reset machine +Lebootcode: /* * u_long ptest040(caddr_t addr, u_int fc); @@ -1808,8 +1643,7 @@ Ldoboot1: * corresponding to a MacOS logical address for get_physical(). * sar 01-oct-1996 */ - .globl _ptest040 -_ptest040: +ENTRY_NOPROFILE(ptest040) #if defined(M68040) .long 0x4e7a0003 | movc tc,d0 andw #0x8000,d0 @@ -1856,11 +1690,10 @@ Lget_phys1: * "gas" does not understand the tt0 register, so we must hand- * assemble the instructions. */ - .globl _get_pte -_get_pte: +ENTRY_NOPROFILE(get_pte) subql #4,sp | make temporary space - lea longscratch,a0 + lea _ASM_LABEL(longscratch),a0 movl #0x00ff8710,a0@ | Set up FC 1 r/w access .long 0xf0100800 | pmove a0@,tt0 @@ -1877,7 +1710,7 @@ _get_pte: jeq get_pte_fail2 | if 0, then was not set -- fail movl a1,d0 - movl d0,pte_tmp | save for later + movl d0,_ASM_LABEL(pte_tmp) | save for later | send first long back to user movl sp@(12),a0 | address of where to put pte @@ -1913,7 +1746,7 @@ _get_pte: pte_level_zero: | must get CRP to get length of entries at first level - lea longscratch,a0 | space for two longs + lea _ASM_LABEL(longscratch),a0 | space for two longs pmove crp,a0@ | save root pointer movl a0@,d0 | load high long jra pte_got_parent @@ -1954,7 +1787,7 @@ pte_got_it: jeq get_pte_fail6 | if 0, then was not set -- fail movsl a1@,d0 | get pte of parent - movl d0,_macos_tt0 | XXX for later analysis (kill this line) + movl d0,_C_LABEL(macos_tt0) | XXX for later analysis (kill me) pte_got_parent: andl #3,d0 | dt bits of pte cmpl #2,d0 | child is short-format descriptor @@ -1966,7 +1799,7 @@ pte_got_parent: | second long. The reason we didn't do this in the first place | is that the first long might have been the last long of RAM. - movl pte_tmp,a1 | get address of our original pte + movl _ASM_LABEL(pte_tmp),a1 | get address of our original pte addql #4,a1 | address of ite second long | send second long back to user @@ -1985,7 +1818,7 @@ get_pte_fail: movql #-1,d0 | return failure get_pte_success: - lea longscratch,a0 | disable tt + lea _ASM_LABEL(longscratch),a0 | disable tt movl #0,a0@ .long 0xf0100800 | pmove a0@,tt0 @@ -1993,144 +1826,159 @@ get_pte_success: rts get_pte_fail1: - jbsr _printstar + jbsr _C_LABEL(printstar) jra get_pte_fail get_pte_fail2: - jbsr _printstar - jbsr _printstar + jbsr _C_LABEL(printstar) + jbsr _C_LABEL(printstar) jra get_pte_fail get_pte_fail3: - jbsr _printstar - jbsr _printstar - jbsr _printstar + jbsr _C_LABEL(printstar) + jbsr _C_LABEL(printstar) + jbsr _C_LABEL(printstar) jra get_pte_fail get_pte_fail4: - jbsr _printstar - jbsr _printstar - jbsr _printstar - jbsr _printstar + jbsr _C_LABEL(printstar) + jbsr _C_LABEL(printstar) + jbsr _C_LABEL(printstar) + jbsr _C_LABEL(printstar) jra get_pte_fail get_pte_fail5: - jbsr _printstar - jbsr _printstar - jbsr _printstar - jbsr _printstar - jbsr _printstar + jbsr _C_LABEL(printstar) + jbsr _C_LABEL(printstar) + jbsr _C_LABEL(printstar) + jbsr _C_LABEL(printstar) + jbsr _C_LABEL(printstar) jra get_pte_fail get_pte_fail6: - jbsr _printstar - jbsr _printstar - jbsr _printstar - jbsr _printstar - jbsr _printstar - jbsr _printstar + jbsr _C_LABEL(printstar) + jbsr _C_LABEL(printstar) + jbsr _C_LABEL(printstar) + jbsr _C_LABEL(printstar) + jbsr _C_LABEL(printstar) + jbsr _C_LABEL(printstar) jra get_pte_fail get_pte_fail7: - jbsr _printstar - jbsr _printstar - jbsr _printstar - jbsr _printstar - jbsr _printstar - jbsr _printstar - jbsr _printstar + jbsr _C_LABEL(printstar) + jbsr _C_LABEL(printstar) + jbsr _C_LABEL(printstar) + jbsr _C_LABEL(printstar) + jbsr _C_LABEL(printstar) + jbsr _C_LABEL(printstar) + jbsr _C_LABEL(printstar) jra get_pte_fail get_pte_fail8: - jbsr _printstar - jbsr _printstar - jbsr _printstar - jbsr _printstar - jbsr _printstar - jbsr _printstar - jbsr _printstar - jbsr _printstar + jbsr _C_LABEL(printstar) + jbsr _C_LABEL(printstar) + jbsr _C_LABEL(printstar) + jbsr _C_LABEL(printstar) + jbsr _C_LABEL(printstar) + jbsr _C_LABEL(printstar) + jbsr _C_LABEL(printstar) + jbsr _C_LABEL(printstar) jra get_pte_fail get_pte_fail9: - jbsr _printstar - jbsr _printstar - jbsr _printstar - jbsr _printstar - jbsr _printstar - jbsr _printstar - jbsr _printstar - jbsr _printstar - jbsr _printstar + jbsr _C_LABEL(printstar) + jbsr _C_LABEL(printstar) + jbsr _C_LABEL(printstar) + jbsr _C_LABEL(printstar) + jbsr _C_LABEL(printstar) + jbsr _C_LABEL(printstar) + jbsr _C_LABEL(printstar) + jbsr _C_LABEL(printstar) + jbsr _C_LABEL(printstar) jra get_pte_fail get_pte_fail10: - jbsr _printstar - jbsr _printstar - jbsr _printstar - jbsr _printstar - jbsr _printstar - jbsr _printstar - jbsr _printstar - jbsr _printstar - jbsr _printstar - jbsr _printstar + jbsr _C_LABEL(printstar) + jbsr _C_LABEL(printstar) + jbsr _C_LABEL(printstar) + jbsr _C_LABEL(printstar) + jbsr _C_LABEL(printstar) + jbsr _C_LABEL(printstar) + jbsr _C_LABEL(printstar) + jbsr _C_LABEL(printstar) + jbsr _C_LABEL(printstar) + jbsr _C_LABEL(printstar) jra get_pte_fail +/* + * Misc. global variables. + */ .data - .globl _sanity_check -_sanity_check: +GLOBAL(sanity_check) .long 0x18621862 | this is our stack overflow checker. .space 4 * NBPG -tmpstk: - .globl _machineid -_machineid: +ASLOCAL(tmpstk) + +GLOBAL(machineid) .long 0 | default to 320 - .globl _mmutype,_cputype,_protorp -_mmutype: - .long MMU_68851 | Default to 68851 PMMU -_cputype: - .long CPU_68020 | Default to 68020 -_protorp: + +GLOBAL(mmutype) + .long MMU_68851 | default to 68851 PMMU + +GLOBAL(cputype) + .long CPU_68020 | default to 68020 CPU + +#ifdef __notyet__ +GLOBAL(ectype) + .long EC_NONE | external cache type, default to none +#endif + +GLOBAL(fputype) + .long FPU_68882 | default to 68882 FPU + +GLOBAL(protorp) .long 0,0 | prototype root pointer - .globl _cold -_cold: + +GLOBAL(cold) .long 1 | cold start flag - .globl _proc0paddr -_proc0paddr: + +GLOBAL(want_resched) + .long 0 + +GLOBAL(proc0paddr) .long 0 | KVA of proc0 u-area - .globl _intiolimit -_intiolimit: + +GLOBAL(intiolimit) .long 0 | KVA of end of internal IO space - .globl _load_addr -_load_addr: + +GLOBAL(load_addr) .long 0 | Physical address of kernel -lastpage: + +ASLOCAL(lastpage) .long 0 | LAK: to store the addr of last page in mem -#ifdef DEBUG - .globl fulltflush, fullcflush -fulltflush: + +GLOBAL(MacOSROMBase) + .long 0x40800000 +GLOBAL(mac68k_vrsrc_cnt) .long 0 -fullcflush: +GLOBAL(mac68k_vrsrc_vec) + .word 0, 0, 0, 0, 0, 0 + +#ifdef DEBUG +ASGLOBAL(fulltflush) .long 0 - .globl timebomb -timebomb: + +ASGLOBAL(fullcflush) .long 0 #endif + /* interrupt counters */ - .globl _intrcnt,_intrnames,_eintrcnt,_eintrnames -_intrnames: + +GLOBAL(intrnames) .asciz "spur" .asciz "via1" .asciz "via2" .asciz "scc" .asciz "nmi" .asciz "clock" -_eintrnames: + .asciz "unused1" + .asciz "unused2" + .asciz "unused3" +GLOBAL(eintrnames) .even -_intrcnt: - .long 0,0,0,0,0,0 -_eintrcnt: | Unused, but needed for vmstat - .long 0 - .globl _MacOSROMBase -_MacOSROMBase: - .long 0x40800000 - .globl _mac68k_vrsrc_cnt, _mac68k_vrsrc_vec -_mac68k_vrsrc_cnt: - .long 0 -_mac68k_vrsrc_vec: - .word 0, 0, 0, 0, 0, 0 -_mac68k_buserr_addr: - .long 0 + +GLOBAL(intrcnt) + .long 0,0,0,0,0,0,0,0,0 +GLOBAL(eintrcnt) diff --git a/sys/arch/mac68k/mac68k/machdep.c b/sys/arch/mac68k/mac68k/machdep.c index ca0a868d614..fe65b885cbc 100644 --- a/sys/arch/mac68k/mac68k/machdep.c +++ b/sys/arch/mac68k/mac68k/machdep.c @@ -1,8 +1,7 @@ -/* $OpenBSD: machdep.c,v 1.69 2001/05/05 22:33:54 art Exp $ */ -/* $NetBSD: machdep.c,v 1.134 1997/02/14 06:15:30 scottr Exp $ */ +/* $OpenBSD: machdep.c,v 1.70 2001/05/08 17:30:41 aaron Exp $ */ +/* $NetBSD: machdep.c,v 1.207 1998/07/08 04:39:34 thorpej Exp $ */ /* - * Copyright (c) 1996 Jason R. Thorpe. All rights reserved. * Copyright (c) 1988 University of Utah. * Copyright (c) 1982, 1990 The Regents of the University of California. * All rights reserved. @@ -100,7 +99,6 @@ #include <sys/user.h> #include <sys/mount.h> #include <sys/extent.h> -#include <sys/sysctl.h> #include <sys/syscallargs.h> #include <sys/extent.h> #ifdef SYSVMSG @@ -131,6 +129,7 @@ void netintr __P((void)); #define MAXMEM 64*1024 /* XXX - from cmap.h */ +#include <vm/vm.h> #include <vm/vm_param.h> #include <vm/pmap.h> #include <vm/vm_map.h> @@ -138,15 +137,22 @@ void netintr __P((void)); #include <vm/vm_kern.h> #include <vm/vm_page.h> +#if defined(UVM) +#include <uvm/uvm_extern.h> +#endif + +#include <sys/sysctl.h> + #include <dev/cons.h> -#include <arch/mac68k/mac68k/macrom.h> -#include <arch/mac68k/dev/adbvar.h> +#include <mac68k/mac68k/macrom.h> +#include <mac68k/dev/adbvar.h> +#include <machine/psc.h> #include <machine/viareg.h> #include "ether.h" /* The following is used externally (sysctl_hw) */ -char machine[] = "mac68k"; /* cpu "architecture" */ +char machine[] = "mac68k"; /* cpu "architecture" */ struct mac68k_machine_S mac68k_machine; @@ -163,10 +169,10 @@ extern u_long high[8]; /* These are used to map NuBus space: */ #define NBMAXRANGES 16 -int nbnumranges; /* = 0 == don't use the ranges */ -u_long nbphys[NBMAXRANGES]; /* Start physical addr of this range */ -u_long nblog[NBMAXRANGES]; /* Start logical addr of this range */ -long nblen[NBMAXRANGES]; /* Length of this range If the length is */ +int nbnumranges; /* = 0 == don't use the ranges */ +u_long nbphys[NBMAXRANGES]; /* Start physical addr of this range */ +u_long nblog[NBMAXRANGES]; /* Start logical addr of this range */ +long nblen[NBMAXRANGES]; /* Length of this range If the length is */ /* negative, all phys addrs are the same. */ extern u_long videoaddr; /* Addr used in kernel for video. */ @@ -184,31 +190,37 @@ u_int32_t mac68k_vidlen; /* mem length */ int (*mac68k_bell_callback) __P((void *, int, int, int)); caddr_t mac68k_bell_cookie; +#if defined(UVM) +vm_map_t exec_map = NULL; +vm_map_t mb_map = NULL; +vm_map_t phys_map = NULL; +#else vm_map_t buffer_map; +#endif /* * Declare these as initialized data so we can patch them. */ -int nswbuf = 0; +int nswbuf = 0; #ifdef NBUF -int nbuf = NBUF; +int nbuf = NBUF; #else -int nbuf = 0; +int nbuf = 0; #endif #ifdef BUFPAGES -int bufpages = BUFPAGES; +int bufpages = BUFPAGES; #else -int bufpages = 0; +int bufpages = 0; #endif -int maxmem; /* max memory per process */ -int physmem = MAXMEM; /* max supported memory, changes to actual */ +int maxmem; /* max memory per process */ +int physmem = MAXMEM; /* max supported memory, changes to actual */ /* * safepri is a safe priority for sleep to set for a spin-wait * during autoconfiguration or after a panic. */ -int safepri = PSL_LOWIPL; +int safepri = PSL_LOWIPL; /* * Some of the below are not used yet, but might be used someday on the @@ -239,21 +251,67 @@ int iomem_malloc_safe; /* XXX should be in locore.s for consistency */ int astpending = 0; -int want_resched = 0; static void identifycpu __P((void)); static u_long get_physical __P((u_int, u_long *)); +void initcpu __P((void)); int cpu_dumpsize __P((void)); int cpu_dump __P((int (*)(dev_t, daddr_t, caddr_t, size_t), daddr_t *)); void cpu_init_kcore_hdr __P((void)); + +/* functions called from locore.s */ void dumpsys __P((void)); +void mac68k_init __P((void)); +void straytrap __P((int, int)); +void nmihand __P((struct frame)); /* * Machine-dependent crash dump header info. */ cpu_kcore_hdr_t cpu_kcore_hdr; + /* + * Early initialization, before main() is called. + */ +void +mac68k_init() +{ + int i; + extern vm_offset_t avail_start; + + /* + * Tell the VM system about available physical memory. + * Notice that we don't need to worry about avail_end here + * since it's equal to high[numranges-1]. + */ + for (i = 0; i < numranges; i++) { +#if defined(UVM) + if (low[i] <= avail_start && avail_start < high[i]) + uvm_page_physload(atop(avail_start), atop(high[i]), + atop(avail_start), atop(high[i]), + VM_FREELIST_DEFAULT); + else + uvm_page_physload(atop(low[i]), atop(high[i]), + atop(low[i]), atop(high[i]), + VM_FREELIST_DEFAULT); +#else + if (low[i] <= avail_start && avail_start < high[i]) + vm_page_physload(atop(avail_start), atop(high[i]), + atop(avail_start), atop(high[i])); + else + vm_page_physload(atop(low[i]), atop(high[i]), + atop(low[i]), atop(high[i])); +#endif /* UVM */ + } + + /* Initialize the VIAs */ + via_init(); + + /* Initialize the PSC (if present) */ + psc_init(); +} + /* * Console initialization: called early on from main, * before vm init or startup. Do enough configuration @@ -278,12 +336,11 @@ consinit(void) ddb_init(); #endif init = 1; - } else { + } else mac68k_calibrate_delay(); - } } -#define CURRENTBOOTERVER 108 +#define CURRENTBOOTERVER 111 /* * cpu_startup: allocate memory for variable-sized tables, @@ -292,13 +349,13 @@ consinit(void) void cpu_startup(void) { - register caddr_t v, firstaddr; - register unsigned i; - int vers; - int base, residual; - vm_offset_t minaddr, maxaddr; - vm_size_t size = 0; /* To avoid compiler warning */ - int delay; + caddr_t v, firstaddr; + unsigned i; + int vers; + int base, residual; + vm_offset_t minaddr, maxaddr; + vm_size_t size = 0; /* To avoid compiler warning */ + int delay; /* * Initialize the kernel crash dump header. @@ -310,7 +367,7 @@ cpu_startup(void) * high[numranges-1] was decremented in pmap_bootstrap. */ for (i = 0; i < btoc(MSGBUFSIZE); i++) - pmap_enter(pmap_kernel(), (vm_offset_t) msgbufp, + pmap_enter(pmap_kernel(), (vm_offset_t)msgbufp, high[numranges - 1] + i * NBPG, VM_PROT_READ|VM_PROT_WRITE, TRUE, VM_PROT_READ|VM_PROT_WRITE); @@ -354,7 +411,7 @@ cpu_startup(void) */ firstaddr = 0; again: - v = (caddr_t) firstaddr; + v = (caddr_t)firstaddr; #define valloc(name, type, num) \ (name) = (type *)v; v = (caddr_t)((name)+(num)) @@ -383,7 +440,7 @@ again: * Determine how many buffers to allocate. * Use 10% of memory for the first 2 Meg, 5% of the remaining * memory. Insure a minimum of 16 buffers. - * We allocate 1/2 as many swap buffer headers as file i/o buffers. + * We allocate 3/4 as many swap buffer headers as file i/o buffers. */ if (bufpages == 0) { if (physmem < btoc(2 * 1024 * 1024)) @@ -391,27 +448,33 @@ again: else bufpages = (btoc(2 * 1024 * 1024) + physmem) / 20; } - bufpages = min(NKMEMCLUSTERS * 2 / 5, bufpages); if (nbuf == 0) { nbuf = bufpages; if (nbuf < 16) nbuf = 16; } + if (nswbuf == 0) { - nswbuf = (nbuf / 2) & ~1; /* force even */ + nswbuf = (nbuf * 3 / 4) & ~1; /* force even */ if (nswbuf > 256) nswbuf = 256; /* sanity */ } +#if !defined(UVM) valloc(swbuf, struct buf, nswbuf); +#endif valloc(buf, struct buf, nbuf); /* * End of first pass, size has been calculated so allocate memory */ if (firstaddr == 0) { - size = (vm_size_t) (v - firstaddr); - firstaddr = (caddr_t) kmem_alloc(kernel_map, round_page(size)); + size = (vm_size_t)(v - firstaddr); +#if defined(UVM) + firstaddr = (caddr_t)uvm_km_alloc(kernel_map, round_page(size)); +#else + firstaddr = (caddr_t)kmem_alloc(kernel_map, round_page(size)); +#endif /* UVM */ if (firstaddr == 0) panic("startup: no room for tables"); goto again; @@ -419,7 +482,7 @@ again: /* * End of second pass, addresses have been assigned */ - if ((vm_size_t) (v - firstaddr) != size) + if ((vm_size_t)(v - firstaddr) != size) panic("startup: table size inconsistency"); /* @@ -427,19 +490,53 @@ again: * in that they usually occupy more virtual memory than physical. */ size = MAXBSIZE * nbuf; - buffer_map = kmem_suballoc(kernel_map, (vm_offset_t *) & buffers, +#if defined(UVM) + if (uvm_map(kernel_map, (vm_offset_t *) &buffers, round_page(size), + NULL, UVM_UNKNOWN_OFFSET, UVM_MAPFLAG(UVM_PROT_NONE, UVM_PROT_NONE, + UVM_INH_NONE, UVM_ADV_NORMAL, 0)) != KERN_SUCCESS) + panic("startup: cannot allocate VM for buffers"); + minaddr = (vm_offset_t)buffers; +#else + buffer_map = kmem_suballoc(kernel_map, (vm_offset_t *)&buffers, &maxaddr, size, TRUE); - minaddr = (vm_offset_t) buffers; - if (vm_map_find(buffer_map, vm_object_allocate(size), (vm_offset_t) 0, - &minaddr, size, FALSE) != KERN_SUCCESS) + minaddr = (vm_offset_t)buffers; + if (vm_map_find(buffer_map, vm_object_allocate(size), (vm_offset_t)0, + &minaddr, size, FALSE) != KERN_SUCCESS) panic("startup: cannot allocate buffers"); if ((bufpages / nbuf) >= btoc(MAXBSIZE)) { /* Don't want to alloc more physical mem than needed. */ bufpages = btoc(MAXBSIZE) * nbuf; } +#endif /* UVM */ base = bufpages / nbuf; residual = bufpages % nbuf; for (i = 0; i < nbuf; i++) { +#if defined(UVM) + vm_size_t curbufsize; + vm_offset_t curbuf; + struct vm_page *pg; + + /* + * Each buffer has MAXBSIZE bytes of VM space allocated. Of + * that MAXBSIZE space, we allocate and map (base+1) pages + * for the first "residual" buffers, and then we allocate + * "base" pages for the rest. + */ + curbuf = (vm_offset_t) buffers + (i * MAXBSIZE); + curbufsize = PAGE_SIZE * ((i < residual) ? (base+1) : base); + + while (curbufsize) { + pg = uvm_pagealloc(NULL, 0, NULL, 0); + if (pg == NULL) + panic("cpu_startup: not enough memory for " + "buffer cache"); + pmap_enter(kernel_map->pmap, curbuf, + VM_PAGE_TO_PHYS(pg), VM_PROT_ALL, TRUE, + VM_PROT_ALL); + curbuf += PAGE_SIZE; + curbufsize -= PAGE_SIZE; + } +#else /* ! UVM */ vm_size_t curbufsize; vm_offset_t curbuf; @@ -450,23 +547,34 @@ again: * The rest of each buffer occupies virtual space, * but has no physical memory allocated for it. */ - curbuf = (vm_offset_t) buffers + i * MAXBSIZE; + curbuf = (vm_offset_t)buffers + i * MAXBSIZE; curbufsize = PAGE_SIZE * (i < residual ? base + 1 : base); vm_map_pageable(buffer_map, curbuf, curbuf + curbufsize, FALSE); vm_map_simplify(buffer_map, curbuf); +#endif /* UVM */ } /* * Allocate a submap for exec arguments. This map effectively * limits the number of processes exec'ing at any time. */ +#if defined(UVM) + exec_map = uvm_km_suballoc(kernel_map, &minaddr, &maxaddr, + 16 * NCARGS, TRUE, FALSE, NULL); +#else exec_map = kmem_suballoc(kernel_map, &minaddr, &maxaddr, 16 * NCARGS, TRUE); +#endif /* * Allocate a submap for physio */ +#if defined(UVM) + phys_map = uvm_km_suballoc(kernel_map, &minaddr, &maxaddr, + VM_PHYS_SIZE, TRUE, FALSE, NULL); +#else phys_map = kmem_suballoc(kernel_map, &minaddr, &maxaddr, VM_PHYS_SIZE, TRUE); +#endif /* * Finally, allocate mbuf pool. Since mclrefcnt is an off-size @@ -475,19 +583,33 @@ again: mclrefcnt = (char *) malloc(NMBCLUSTERS + PAGE_SIZE / MCLBYTES, M_MBUF, M_NOWAIT); bzero(mclrefcnt, NMBCLUSTERS + PAGE_SIZE / MCLBYTES); - mb_map = kmem_suballoc(kernel_map, (vm_offset_t *) & mbutl, &maxaddr, +#if defined(UVM) + mb_map = uvm_km_suballoc(kernel_map, (vm_offset_t *)&mbutl, &maxaddr, + VM_MBUF_SIZE, FALSE, FALSE, NULL); +#else + mb_map = kmem_suballoc(kernel_map, (vm_offset_t *)&mbutl, &maxaddr, VM_MBUF_SIZE, FALSE); +#endif /* * Initialize timeouts */ timeout_init(); +#if defined(UVM) + printf("avail mem = %ld\n", ptoa(uvmexp.free)); +#else printf("avail mem = %ld\n", ptoa(cnt.v_free_count)); +#endif printf("using %d buffers containing %d bytes of memory\n", nbuf, bufpages * PAGE_SIZE); /* + * Set up CPU-specific registers, cache, etc. + */ + initcpu(); + + /* * Set up buffers, so they can be used to read disk labels. */ bufinit(); @@ -505,6 +627,39 @@ again: iomem_malloc_safe = 1; } +void +initcpu() +{ +#if defined(M68040) || defined(M68060) + extern void (*vectab[256]) __P((void)); + void addrerr4060 __P((void)); +#endif +#ifdef M68060 + void buserr60 __P((void)); +#endif +#ifdef M68040 + void buserr40 __P((void)); +#endif + + switch (cputype) { +#ifdef M68060 + case CPU_68060: + vectab[2] = buserr60; + vectab[3] = addrerr4060; + break; +#endif +#ifdef M68040 + case CPU_68040: + vectab[2] = buserr40; + vectab[3] = addrerr4060; + break; +#endif + default: + break; + } + DCIS(); +} + void doboot __P((void)) __attribute__((__noreturn__)); void via_shutdown __P((void)); @@ -524,7 +679,7 @@ setregs(p, pack, stack, retval) #ifdef COMPAT_SUNOS extern struct emul emul_sunos; #endif - struct frame *frame = (struct frame *) p->p_md.md_regs; + struct frame *frame = (struct frame *)p->p_md.md_regs; frame->f_sr = PSL_USERSET; frame->f_pc = pack->ep_entry & ~1; @@ -565,18 +720,18 @@ setregs(p, pack, stack, retval) #endif } -int waittime = -1; +int waittime = -1; struct pcb dumppcb; void boot(howto) register int howto; { - extern u_long MacOSROMBase; + extern u_long maxaddr; /* take a snap shot before clobbering any registers */ if (curproc) - savectx((struct pcb *) curproc->p_addr); + savectx((struct pcb *)curproc->p_addr); boothowto = howto; if ((howto & RB_NOSYNC) == 0 && waittime < 0) { @@ -629,12 +784,12 @@ boot(howto) #ifndef MRG_ADB /* * adb_poweroff() is available only when - * the MRG_ADB method isn't used. + * the MRG_ADB method isn't used. * - * Shut down machines whose power functions - * are accessed via modified ADB calls. + * Shut down machines whose power functions + * are accessed via modified ADB calls. */ - adb_poweroff(); + adb_poweroff(); #endif } printf("\nThe operating system has halted.\n"); @@ -642,15 +797,11 @@ boot(howto) (void)cngetc(); } - /* - * Map ROM where the MacOS likes it, so we can reboot, - * hopefully. - */ - pmap_map(MacOSROMBase, MacOSROMBase, - MacOSROMBase + 4 * 1024 * 1024, - VM_PROT_READ | VM_PROT_WRITE | VM_PROT_EXECUTE); + /* Map the last physical page VA = PA for doboot() */ + pmap_enter(pmap_kernel(), (vm_offset_t)maxaddr, (vm_offset_t)maxaddr, + VM_PROT_ALL, TRUE, VM_PROT_ALL); + - printf("rebooting...\n"); DELAY(1000000); doboot(); @@ -892,7 +1043,7 @@ void microtime(tvp) register struct timeval *tvp; { - int s = splhigh(); + int s = splhigh(); static struct timeval lasttime; *tvp = time; @@ -915,8 +1066,8 @@ void straytrap __P((int, int)); void straytrap(pc, evec) - int pc; - int evec; + int pc; + int evec; { printf("unexpected trap; vector offset 0x%x from 0x%x.\n", (int) (evec & 0xfff), pc); @@ -925,7 +1076,7 @@ straytrap(pc, evec) #endif } -int *nofault; +int *nofault; int badaddr __P((caddr_t)); @@ -936,18 +1087,13 @@ badaddr(addr) register int i; label_t faultbuf; -#ifdef lint - i = *addr; - if (i) - return (0); -#endif - nofault = (int *) &faultbuf; - if (setjmp((label_t *) nofault)) { - nofault = (int *) 0; + nofault = (int *)&faultbuf; + if (setjmp((label_t *)nofault)) { + nofault = (int *)0; return (1); } - i = *(volatile short *) addr; - nofault = (int *) 0; + i = *(volatile short *)addr; + nofault = (int *)0; return (0); } @@ -963,13 +1109,13 @@ badbaddr(addr) if (i) return (0); #endif - nofault = (int *) &faultbuf; - if (setjmp((label_t *) nofault)) { - nofault = (int *) 0; + nofault = (int *)&faultbuf; + if (setjmp((label_t *)nofault)) { + nofault = (int *)0; return (1); } - i = *(volatile u_int8_t *) addr; - nofault = (int *) 0; + i = *(volatile u_int8_t *)addr; + nofault = (int *)0; return (0); } @@ -985,13 +1131,13 @@ badwaddr(addr) if (i) return (0); #endif - nofault = (int *) &faultbuf; - if (setjmp((label_t *) nofault)) { - nofault = (int *) 0; + nofault = (int *)&faultbuf; + if (setjmp((label_t *)nofault)) { + nofault = (int *)0; return (1); } - i = *(volatile u_int16_t *) addr; - nofault = (int *) 0; + i = *(volatile u_int16_t *)addr; + nofault = (int *)0; return (0); } @@ -1007,13 +1153,13 @@ badladdr(addr) if (i) return (0); #endif - nofault = (int *) &faultbuf; - if (setjmp((label_t *) nofault)) { - nofault = (int *) 0; + nofault = (int *)&faultbuf; + if (setjmp((label_t *)nofault)) { + nofault = (int *)0; return (1); } - i = *(volatile u_int32_t *) addr; - nofault = (int *) 0; + i = *(volatile u_int32_t *)addr; + nofault = (int *)0; return (0); } @@ -1102,11 +1248,11 @@ void dumpmem __P((u_int *, int)); void regdump(frame, sbytes) struct frame *frame; - int sbytes; + int sbytes; { static int doingdump = 0; register int i; - int s; + int s; if (doingdump) return; @@ -1128,11 +1274,11 @@ regdump(frame, sbytes) if (sbytes > 0) { if (1) { /* (frame->f_sr & PSL_S) *//* BARF - BG */ printf("\n\nKernel stack (%08x):", - (int) (((int *) frame) - 1)); - dumpmem(((int *) frame) - 1, sbytes); + (int) (((int *)frame) - 1)); + dumpmem(((int *)frame) - 1, sbytes); } else { printf("\n\nUser stack (%08x):", frame->f_regs[15]); - dumpmem((int *) frame->f_regs[15], sbytes); + dumpmem((int *)frame->f_regs[15], sbytes); } } doingdump = 0; @@ -1144,7 +1290,7 @@ void dumpmem __P((u_int *, int)); void dumpmem(ptr, sz) register u_int *ptr; - int sz; + int sz; { register int i; @@ -1178,7 +1324,7 @@ get_top_of_ram() */ int cpu_sysctl(name, namelen, oldp, oldlenp, newp, newlen, p) - int *name; + int *name; u_int namelen; void *oldp; size_t *oldlenp; @@ -1211,11 +1357,11 @@ cpu_exec_aout_makecmds(p, epp) struct proc *p; struct exec_package *epp; { - int error = ENOEXEC; + int error = ENOEXEC; #ifdef COMPAT_NOMID /* Check to see if MID == 0. */ - if (((struct exec *) epp->ep_hdr)->a_midmag == ZMAGIC) + if (((struct exec *)epp->ep_hdr)->a_midmag == ZMAGIC) return exec_aout_prep_oldzmagic(p, epp); #endif @@ -1247,27 +1393,17 @@ getenvvars(flag, buf) extern u_long end, esym; extern u_long macos_boottime, MacOSROMBase; extern long macos_gmtbias; - int root_scsi_id; + int root_scsi_id; /* - * If flag & 0x80000000 == 0, then we're booting with the old booter - * and we should freak out. - */ + * If flag & 0x80000000 == 0, then we're booting with the old booter + * and we should freak out. + */ if ((flag & 0x80000000) == 0) { /* Freak out; print something if that becomes available */ } else envbuf = buf; - root_scsi_id = getenv("ROOT_SCSI_ID"); - /* - * For now, we assume that the boot device is off the first controller. - */ - if (bootdev == 0) - bootdev = MAKEBOOTDEV(4, 0, 0, root_scsi_id, 0); - - if (boothowto == 0) - boothowto = getenv("SINGLE_USER"); - /* These next two should give us mapped video & serial */ /* We need these for pre-mapping graybars & echo, but probably */ /* only on MacII or LC. -- XXX */ @@ -1275,17 +1411,17 @@ getenvvars(flag, buf) /* sccaddr = getenv("MACOS_SCC"); */ /* - * The following are not in a structure so that they can be - * accessed more quickly. - */ + * The following are not in a structure so that they can be + * accessed more quickly. + */ videoaddr = getenv("VIDEO_ADDR"); videorowbytes = getenv("ROW_BYTES"); videobitdepth = getenv("SCREEN_DEPTH"); videosize = getenv("DIMENSIONS"); /* - * More misc stuff from booter. - */ + * More misc stuff from booter. + */ mac68k_machine.machineid = getenv("MACHINEID"); mac68k_machine.mach_processor = getenv("PROCESSOR"); mac68k_machine.mach_memsize = getenv("MEMSIZE"); @@ -1299,12 +1435,29 @@ getenvvars(flag, buf) mac68k_machine.print_flags = getenv("SERIAL_PRINT_FLAGS"); mac68k_machine.print_cts_clk = getenv("SERIAL_PRINT_HSKICLK"); mac68k_machine.print_dcd_clk = getenv("SERIAL_PRINT_GPICLK"); - /* Should probably check this and fail if old */ mac68k_machine.booter_version = getenv("BOOTERVER"); /* - * Get end of symbols for kernel debugging - */ + * For now, we assume that the boot device is off the first controller. + * Booter versions 1.11.0 and later set a flag to tell us to construct + * bootdev using the SCSI ID passed in via the environment. + */ + root_scsi_id = getenv("ROOT_SCSI_ID"); + if (((mac68k_machine.booter_version < CURRENTBOOTERVER) || + (flag & 0x40000)) && bootdev == 0) + bootdev = MAKEBOOTDEV(4, 0, 0, root_scsi_id, 0); + + /* + * Booter 1.11.3 and later pass a BOOTHOWTO variable with the + * appropriate bits set. + */ + boothowto = getenv("BOOTHOWTO"); + if (boothowto == 0) + boothowto = getenv("SINGLE_USER"); + + /* + * Get end of symbols for kernel debugging + */ esym = getenv("END_SYM"); #ifndef SYMTAB_SPACE if (esym == 0) @@ -1318,12 +1471,12 @@ getenvvars(flag, buf) macos_gmtbias = getenv("GMTBIAS"); /* - * Save globals stolen from MacOS - */ + * Save globals stolen from MacOS + */ - ROMBase = (caddr_t) getenv("ROMBASE"); - if (ROMBase == (caddr_t) 0) { - ROMBase = (caddr_t) ROMBASE; + ROMBase = (caddr_t)getenv("ROMBASE"); + if (ROMBase == (caddr_t)0) { + ROMBase = (caddr_t)ROMBASE; } MacOSROMBase = (unsigned long) ROMBase; TimeDBRA = getenv("TIMEDBRA"); @@ -1332,14 +1485,14 @@ getenvvars(flag, buf) HwCfgFlags2 = getenv("HWCFGFLAG2"); HwCfgFlags3 = getenv("HWCFGFLAG3"); ADBReInit_JTBL = getenv("ADBREINIT_JTBL"); - mrg_ADBIntrPtr = (caddr_t) getenv("ADBINTERRUPT"); + mrg_ADBIntrPtr = (caddr_t)getenv("ADBINTERRUPT"); } static char toupper __P((char)); static char toupper(c) - char c; + char c; { if (c >= 'a' && c <= 'z') { return c - 'a' + 'A'; @@ -1350,19 +1503,19 @@ toupper(c) static long getenv(str) - char *str; + char *str; { /* - * Returns the value of the environment variable "str". - * - * Format of the buffer is "var=val\0var=val\0...\0var=val\0\0". - * - * Returns 0 if the variable is not there, and 1 if the variable is there - * without an "=val". - */ + * Returns the value of the environment variable "str". + * + * Format of the buffer is "var=val\0var=val\0...\0var=val\0\0". + * + * Returns 0 if the variable is not there, and 1 if the variable is + * there without an "=val". + */ - char *s, *s1; - int val, base; + char *s, *s1; + int val, base; s = envbuf; while (1) { @@ -1478,29 +1631,29 @@ static romvec_t romvecs[] = /* Vectors verified for II, IIx, IIcx, SE/30 */ { /* 0 */ "Mac II class ROMs", - (caddr_t) 0x40807002, /* where does ADB interrupt */ - (caddr_t) 0x0, /* PM interrupt (?) */ - (caddr_t) 0x4080a4d8, /* ADBBase + 130 interrupt; whatzit? */ - (caddr_t) 0x40807778, /* CountADBs */ - (caddr_t) 0x40807792, /* GetIndADB */ - (caddr_t) 0x408077be, /* GetADBInfo */ - (caddr_t) 0x408077c4, /* SetADBInfo */ - (caddr_t) 0x40807704, /* ADBReInit */ - (caddr_t) 0x408072fa, /* ADBOp */ - (caddr_t) 0x0, /* PMgrOp */ - (caddr_t) 0x4080d6d0, /* WriteParam */ - (caddr_t) 0x4080d6fa, /* SetDateTime */ - (caddr_t) 0x4080dbe8, /* InitUtil */ - (caddr_t) 0x4080dd78, /* ReadXPRam */ - (caddr_t) 0x4080dd82, /* WriteXPRam */ - (caddr_t) 0x4080ddd6, /* jClkNoMem */ - (caddr_t) 0x0, /* ADBAlternateInit */ - (caddr_t) 0x0, /* Egret */ - (caddr_t) 0x0, /* InitEgret */ - (caddr_t) 0x0, /* ADBReInit_JTBL */ - (caddr_t) 0x0, /* ROMResourceMap List Head */ - (caddr_t) 0x40814c58, /* FixDiv */ - (caddr_t) 0x40814b64, /* FixMul */ + (caddr_t)0x40807002, /* where does ADB interrupt */ + (caddr_t)0x0, /* PM interrupt (?) */ + (caddr_t)0x4080a4d8, /* ADBBase + 130 interrupt; whatzit? */ + (caddr_t)0x40807778, /* CountADBs */ + (caddr_t)0x40807792, /* GetIndADB */ + (caddr_t)0x408077be, /* GetADBInfo */ + (caddr_t)0x408077c4, /* SetADBInfo */ + (caddr_t)0x40807704, /* ADBReInit */ + (caddr_t)0x408072fa, /* ADBOp */ + (caddr_t)0x0, /* PMgrOp */ + (caddr_t)0x4080d6d0, /* WriteParam */ + (caddr_t)0x4080d6fa, /* SetDateTime */ + (caddr_t)0x4080dbe8, /* InitUtil */ + (caddr_t)0x4080dd78, /* ReadXPRam */ + (caddr_t)0x4080dd82, /* WriteXPRam */ + (caddr_t)0x4080ddd6, /* jClkNoMem */ + (caddr_t)0x0, /* ADBAlternateInit */ + (caddr_t)0x0, /* Egret */ + (caddr_t)0x0, /* InitEgret */ + (caddr_t)0x0, /* ADBReInit_JTBL */ + (caddr_t)0x0, /* ROMResourceMap List Head */ + (caddr_t)0x40814c58, /* FixDiv */ + (caddr_t)0x40814b64, /* FixMul */ }, /* * Vectors verified for PB 140, PB 145, PB 170 @@ -1508,58 +1661,58 @@ static romvec_t romvecs[] = */ { /* 1 */ "Powerbook class ROMs", - (caddr_t) 0x4088ae5e, /* ADB interrupt */ - (caddr_t) 0x408885ec, /* PB ADB interrupt */ - (caddr_t) 0x4088ae0e, /* ADBBase + 130 interrupt; whatzit? */ - (caddr_t) 0x4080a360, /* CountADBs */ - (caddr_t) 0x4080a37a, /* GetIndADB */ - (caddr_t) 0x4080a3a6, /* GetADBInfo */ - (caddr_t) 0x4080a3ac, /* SetADBInfo */ - (caddr_t) 0x4080a752, /* ADBReInit */ - (caddr_t) 0x4080a3dc, /* ADBOp */ - (caddr_t) 0x408888ec, /* PMgrOp */ - (caddr_t) 0x4080c05c, /* WriteParam */ - (caddr_t) 0x4080c086, /* SetDateTime */ - (caddr_t) 0x4080c5cc, /* InitUtil */ - (caddr_t) 0x4080b186, /* ReadXPRam */ - (caddr_t) 0x4080b190, /* WriteXPRam */ - (caddr_t) 0x4080b1e4, /* jClkNoMem */ - (caddr_t) 0x4080a818, /* ADBAlternateInit */ - (caddr_t) 0x40814800, /* Egret */ - (caddr_t) 0x408147c4, /* InitEgret */ - (caddr_t) 0x0, /* ADBReInit_JTBL */ - (caddr_t) 0x4087eb90, /* ROMResourceMap List Head */ - (caddr_t) 0x4081c406, /* FixDiv */ - (caddr_t) 0x4081c312, /* FixMul */ + (caddr_t)0x4088ae5e, /* ADB interrupt */ + (caddr_t)0x408885ec, /* PB ADB interrupt */ + (caddr_t)0x4088ae0e, /* ADBBase + 130 interrupt; whatzit? */ + (caddr_t)0x4080a360, /* CountADBs */ + (caddr_t)0x4080a37a, /* GetIndADB */ + (caddr_t)0x4080a3a6, /* GetADBInfo */ + (caddr_t)0x4080a3ac, /* SetADBInfo */ + (caddr_t)0x4080a752, /* ADBReInit */ + (caddr_t)0x4080a3dc, /* ADBOp */ + (caddr_t)0x408888ec, /* PMgrOp */ + (caddr_t)0x4080c05c, /* WriteParam */ + (caddr_t)0x4080c086, /* SetDateTime */ + (caddr_t)0x4080c5cc, /* InitUtil */ + (caddr_t)0x4080b186, /* ReadXPRam */ + (caddr_t)0x4080b190, /* WriteXPRam */ + (caddr_t)0x4080b1e4, /* jClkNoMem */ + (caddr_t)0x4080a818, /* ADBAlternateInit */ + (caddr_t)0x40814800, /* Egret */ + (caddr_t)0x408147c4, /* InitEgret */ + (caddr_t)0x0, /* ADBReInit_JTBL */ + (caddr_t)0x4087eb90, /* ROMResourceMap List Head */ + (caddr_t)0x4081c406, /* FixDiv */ + (caddr_t)0x4081c312, /* FixMul */ }, /* * Vectors verified for IIsi, IIvx, IIvi */ { /* 2 */ "Mac IIsi class ROMs", - (caddr_t) 0x40814912, /* ADB interrupt */ - (caddr_t) 0x0, /* PM ADB interrupt */ - (caddr_t) 0x408150f0, /* ADBBase + 130 interrupt; whatzit? */ - (caddr_t) 0x4080a360, /* CountADBs */ - (caddr_t) 0x4080a37a, /* GetIndADB */ - (caddr_t) 0x4080a3a6, /* GetADBInfo */ - (caddr_t) 0x4080a3ac, /* SetADBInfo */ - (caddr_t) 0x4080a752, /* ADBReInit */ - (caddr_t) 0x4080a3dc, /* ADBOp */ - (caddr_t) 0x0, /* PMgrOp */ - (caddr_t) 0x4080c05c, /* WriteParam */ - (caddr_t) 0x4080c086, /* SetDateTime */ - (caddr_t) 0x4080c5cc, /* InitUtil */ - (caddr_t) 0x4080b186, /* ReadXPRam */ - (caddr_t) 0x4080b190, /* WriteXPRam */ - (caddr_t) 0x4080b1e4, /* jClkNoMem */ - (caddr_t) 0x4080a818, /* ADBAlternateInit */ - (caddr_t) 0x40814800, /* Egret */ - (caddr_t) 0x408147c4, /* InitEgret */ - (caddr_t) 0x0, /* ADBReInit_JTBL */ - (caddr_t) 0x4087eb90, /* ROMResourceMap List Head */ - (caddr_t) 0x4081c406, /* FixDiv */ - (caddr_t) 0x4081c312, /* FixMul */ + (caddr_t)0x40814912, /* ADB interrupt */ + (caddr_t)0x0, /* PM ADB interrupt */ + (caddr_t)0x408150f0, /* ADBBase + 130 interrupt; whatzit? */ + (caddr_t)0x4080a360, /* CountADBs */ + (caddr_t)0x4080a37a, /* GetIndADB */ + (caddr_t)0x4080a3a6, /* GetADBInfo */ + (caddr_t)0x4080a3ac, /* SetADBInfo */ + (caddr_t)0x4080a752, /* ADBReInit */ + (caddr_t)0x4080a3dc, /* ADBOp */ + (caddr_t)0x0, /* PMgrOp */ + (caddr_t)0x4080c05c, /* WriteParam */ + (caddr_t)0x4080c086, /* SetDateTime */ + (caddr_t)0x4080c5cc, /* InitUtil */ + (caddr_t)0x4080b186, /* ReadXPRam */ + (caddr_t)0x4080b190, /* WriteXPRam */ + (caddr_t)0x4080b1e4, /* jClkNoMem */ + (caddr_t)0x4080a818, /* ADBAlternateInit */ + (caddr_t)0x40814800, /* Egret */ + (caddr_t)0x408147c4, /* InitEgret */ + (caddr_t)0x0, /* ADBReInit_JTBL */ + (caddr_t)0x4087eb90, /* ROMResourceMap List Head */ + (caddr_t)0x4081c406, /* FixDiv */ + (caddr_t)0x4081c312, /* FixMul */ }, /* * Vectors verified for Mac Classic II and LC II @@ -1567,58 +1720,58 @@ static romvec_t romvecs[] = */ { /* 3 */ "Mac Classic II ROMs", - (caddr_t) 0x40a14912, /* ADB interrupt */ - (caddr_t) 0x0, /* PM ADB interrupt */ - (caddr_t) 0x40a150f0, /* ADBBase + 130 interrupt; whatzit? */ - (caddr_t) 0x40a0a360, /* CountADBs */ - (caddr_t) 0x40a0a37a, /* GetIndADB */ - (caddr_t) 0x40a0a3a6, /* GetADBInfo */ - (caddr_t) 0x40a0a3ac, /* SetADBInfo */ - (caddr_t) 0x40a0a752, /* ADBReInit */ - (caddr_t) 0x40a0a3dc, /* ADBOp */ - (caddr_t) 0x0, /* PMgrOp */ - (caddr_t) 0x40a0c05c, /* WriteParam */ - (caddr_t) 0x40a0c086, /* SetDateTime */ - (caddr_t) 0x40a0c5cc, /* InitUtil */ - (caddr_t) 0x40a0b186, /* ReadXPRam */ - (caddr_t) 0x40a0b190, /* WriteXPRam */ - (caddr_t) 0x40a0b1e4, /* jClkNoMem */ - (caddr_t) 0x40a0a818, /* ADBAlternateInit */ - (caddr_t) 0x40a14800, /* Egret */ - (caddr_t) 0x40a147c4, /* InitEgret */ - (caddr_t) 0x40a03ba6, /* ADBReInit_JTBL */ - (caddr_t) 0x40a7eb90, /* ROMResourceMap List Head */ - (caddr_t) 0x40a1c406, /* FixDiv, wild guess */ - (caddr_t) 0x40a1c312, /* FixMul, wild guess */ + (caddr_t)0x40a14912, /* ADB interrupt */ + (caddr_t)0x0, /* PM ADB interrupt */ + (caddr_t)0x40a150f0, /* ADBBase + 130 interrupt; whatzit? */ + (caddr_t)0x40a0a360, /* CountADBs */ + (caddr_t)0x40a0a37a, /* GetIndADB */ + (caddr_t)0x40a0a3a6, /* GetADBInfo */ + (caddr_t)0x40a0a3ac, /* SetADBInfo */ + (caddr_t)0x40a0a752, /* ADBReInit */ + (caddr_t)0x40a0a3dc, /* ADBOp */ + (caddr_t)0x0, /* PMgrOp */ + (caddr_t)0x40a0c05c, /* WriteParam */ + (caddr_t)0x40a0c086, /* SetDateTime */ + (caddr_t)0x40a0c5cc, /* InitUtil */ + (caddr_t)0x40a0b186, /* ReadXPRam */ + (caddr_t)0x40a0b190, /* WriteXPRam */ + (caddr_t)0x40a0b1e4, /* jClkNoMem */ + (caddr_t)0x40a0a818, /* ADBAlternateInit */ + (caddr_t)0x40a14800, /* Egret */ + (caddr_t)0x40a147c4, /* InitEgret */ + (caddr_t)0x40a03ba6, /* ADBReInit_JTBL */ + (caddr_t)0x40a7eb90, /* ROMResourceMap List Head */ + (caddr_t)0x40a1c406, /* FixDiv, wild guess */ + (caddr_t)0x40a1c312, /* FixMul, wild guess */ }, /* * Vectors verified for IIci, Q700 */ { /* 4 */ "Mac IIci/Q700 ROMs", - (caddr_t) 0x4080a700, /* ADB interrupt */ - (caddr_t) 0x0, /* PM ADB interrupt */ - (caddr_t) 0x4080a5aa, /* ADBBase + 130 interrupt; whatzit? */ - (caddr_t) 0x4080a360, /* CountADBs */ - (caddr_t) 0x4080a37a, /* GetIndADB */ - (caddr_t) 0x4080a3a6, /* GetADBInfo */ - (caddr_t) 0x4080a3ac, /* SetADBInfo */ - (caddr_t) 0x4080a752, /* ADBReInit */ - (caddr_t) 0x4080a3dc, /* ADBOp */ - (caddr_t) 0x0, /* PMgrOp */ - (caddr_t) 0x4080c05c, /* WriteParam */ - (caddr_t) 0x4080c086, /* SetDateTime */ - (caddr_t) 0x4080c5cc, /* InitUtil */ - (caddr_t) 0x4080b186, /* ReadXPRam */ - (caddr_t) 0x4080b190, /* WriteXPRam */ - (caddr_t) 0x4080b1e4, /* jClkNoMem */ - (caddr_t) 0x4080a818, /* ADBAlternateInit */ - (caddr_t) 0x0, /* Egret */ - (caddr_t) 0x408147c4, /* InitEgret */ - (caddr_t) 0x0, /* ADBReInit_JTBL */ - (caddr_t) 0x4087eb90, /* ROMResourceMap List Head */ - (caddr_t) 0x4081c406, /* FixDiv */ - (caddr_t) 0x4081c312, /* FixMul */ + (caddr_t)0x4080a700, /* ADB interrupt */ + (caddr_t)0x0, /* PM ADB interrupt */ + (caddr_t)0x4080a5aa, /* ADBBase + 130 interrupt; whatzit? */ + (caddr_t)0x4080a360, /* CountADBs */ + (caddr_t)0x4080a37a, /* GetIndADB */ + (caddr_t)0x4080a3a6, /* GetADBInfo */ + (caddr_t)0x4080a3ac, /* SetADBInfo */ + (caddr_t)0x4080a752, /* ADBReInit */ + (caddr_t)0x4080a3dc, /* ADBOp */ + (caddr_t)0x0, /* PMgrOp */ + (caddr_t)0x4080c05c, /* WriteParam */ + (caddr_t)0x4080c086, /* SetDateTime */ + (caddr_t)0x4080c5cc, /* InitUtil */ + (caddr_t)0x4080b186, /* ReadXPRam */ + (caddr_t)0x4080b190, /* WriteXPRam */ + (caddr_t)0x4080b1e4, /* jClkNoMem */ + (caddr_t)0x4080a818, /* ADBAlternateInit */ + (caddr_t)0x0, /* Egret */ + (caddr_t)0x408147c4, /* InitEgret */ + (caddr_t)0x0, /* ADBReInit_JTBL */ + (caddr_t)0x4087eb90, /* ROMResourceMap List Head */ + (caddr_t)0x4081c406, /* FixDiv */ + (caddr_t)0x4081c312, /* FixMul */ }, /* * Vectors verified for Duo 230, PB 180, PB 160, PB 165/165C @@ -1626,29 +1779,29 @@ static romvec_t romvecs[] = */ { /* 5 */ "2nd Powerbook class ROMs", - (caddr_t) 0x408b2eec, /* ADB interrupt */ - (caddr_t) 0x408885ec, /* PB ADB interrupt */ - (caddr_t) 0x408b2e76, /* ADBBase + 130 interrupt; whatzit? */ - (caddr_t) 0x4080a360, /* CountADBs */ - (caddr_t) 0x4080a37a, /* GetIndADB */ - (caddr_t) 0x4080a3a6, /* GetADBInfo */ - (caddr_t) 0x4080a3ac, /* SetADBInfo */ - (caddr_t) 0x4080a752, /* ADBReInit */ - (caddr_t) 0x4080a3dc, /* ADBOp */ - (caddr_t) 0x408888ec, /* PMgrOp */ - (caddr_t) 0x4080c05c, /* WriteParam */ - (caddr_t) 0x4080c086, /* SetDateTime */ - (caddr_t) 0x4080c5cc, /* InitUtil */ - (caddr_t) 0x4080b186, /* ReadXPRam */ - (caddr_t) 0x4080b190, /* WriteXPRam */ - (caddr_t) 0x408b39b2, /* jClkNoMem */ /* From PB180 */ - (caddr_t) 0x4080a818, /* ADBAlternateInit */ - (caddr_t) 0x40814800, /* Egret */ - (caddr_t) 0x40888400, /* InitPwrMgr */ /* From PB180 */ - (caddr_t) 0x408cce28, /* ADBReInit_JTBL -- from PB160*/ - (caddr_t) 0x4087eb90, /* ROMRsrcMap List Head -- from PB160*/ - (caddr_t) 0x4081c406, /* FixDiv, wild guess */ - (caddr_t) 0x4081c312, /* FixMul, wild guess */ + (caddr_t)0x408b2eec, /* ADB interrupt */ + (caddr_t)0x408885ec, /* PB ADB interrupt */ + (caddr_t)0x408b2e76, /* ADBBase + 130 interrupt; whatzit? */ + (caddr_t)0x4080a360, /* CountADBs */ + (caddr_t)0x4080a37a, /* GetIndADB */ + (caddr_t)0x4080a3a6, /* GetADBInfo */ + (caddr_t)0x4080a3ac, /* SetADBInfo */ + (caddr_t)0x4080a752, /* ADBReInit */ + (caddr_t)0x4080a3dc, /* ADBOp */ + (caddr_t)0x408888ec, /* PMgrOp */ + (caddr_t)0x4080c05c, /* WriteParam */ + (caddr_t)0x4080c086, /* SetDateTime */ + (caddr_t)0x4080c5cc, /* InitUtil */ + (caddr_t)0x4080b186, /* ReadXPRam */ + (caddr_t)0x4080b190, /* WriteXPRam */ + (caddr_t)0x408b39b2, /* jClkNoMem */ /* From PB180 */ + (caddr_t)0x4080a818, /* ADBAlternateInit */ + (caddr_t)0x40814800, /* Egret */ + (caddr_t)0x40888400, /* InitPwrMgr */ /* From PB180 */ + (caddr_t)0x408cce28, /* ADBReInit_JTBL -- from PB160*/ + (caddr_t)0x4087eb90, /* ROMRsrcMap List Head -- from PB160*/ + (caddr_t)0x4081c406, /* FixDiv, wild guess */ + (caddr_t)0x4081c312, /* FixMul, wild guess */ }, /* * Vectors verified for the Quadra, Centris 650 @@ -1656,29 +1809,29 @@ static romvec_t romvecs[] = */ { /* 6 */ "Quadra/Centris ROMs", - (caddr_t) 0x408b2dea, /* ADB int */ - (caddr_t) 0x0, /* PM intr */ - (caddr_t) 0x408b2c72, /* ADBBase + 130 */ - (caddr_t) 0x4080a360, /* CountADBs */ - (caddr_t) 0x4080a37a, /* GetIndADB */ - (caddr_t) 0x4080a3a6, /* GetADBInfo */ - (caddr_t) 0x4080a3ac, /* SetADBInfo */ - (caddr_t) 0x4080a752, /* ADBReInit */ - (caddr_t) 0x4080a3dc, /* ADBOp */ - (caddr_t) 0x40809ae6, /* PMgrOp */ - (caddr_t) 0x4080c05c, /* WriteParam */ - (caddr_t) 0x4080c086, /* SetDateTime */ - (caddr_t) 0x4080c5cc, /* InitUtil */ - (caddr_t) 0x4080b186, /* ReadXPRam */ - (caddr_t) 0x4080b190, /* WriteXPRam */ - (caddr_t) 0x408b39b6, /* jClkNoMem */ - (caddr_t) 0x4080a818, /* ADBAlternateInit */ - (caddr_t) 0x40814800, /* Egret */ - (caddr_t) 0x408147c4, /* InitEgret */ - (caddr_t) 0x408d2b64, /* ADBReInit_JTBL */ - (caddr_t) 0x4087eb90, /* ROMResourceMap List Head */ - (caddr_t) 0x4081c406, /* FixDiv, wild guess */ - (caddr_t) 0x4081c312, /* FixMul, wild guess */ + (caddr_t)0x408b2dea, /* ADB int */ + (caddr_t)0x0, /* PM intr */ + (caddr_t)0x408b2c72, /* ADBBase + 130 */ + (caddr_t)0x4080a360, /* CountADBs */ + (caddr_t)0x4080a37a, /* GetIndADB */ + (caddr_t)0x4080a3a6, /* GetADBInfo */ + (caddr_t)0x4080a3ac, /* SetADBInfo */ + (caddr_t)0x4080a752, /* ADBReInit */ + (caddr_t)0x4080a3dc, /* ADBOp */ + (caddr_t)0x40809ae6, /* PMgrOp */ + (caddr_t)0x4080c05c, /* WriteParam */ + (caddr_t)0x4080c086, /* SetDateTime */ + (caddr_t)0x4080c5cc, /* InitUtil */ + (caddr_t)0x4080b186, /* ReadXPRam */ + (caddr_t)0x4080b190, /* WriteXPRam */ + (caddr_t)0x408b39b6, /* jClkNoMem */ + (caddr_t)0x4080a818, /* ADBAlternateInit */ + (caddr_t)0x40814800, /* Egret */ + (caddr_t)0x408147c4, /* InitEgret */ + (caddr_t)0x408d2b64, /* ADBReInit_JTBL */ + (caddr_t)0x4087eb90, /* ROMResourceMap List Head */ + (caddr_t)0x4081c406, /* FixDiv, wild guess */ + (caddr_t)0x4081c312, /* FixMul, wild guess */ }, /* * Vectors verified for the Quadra 660AV @@ -1686,29 +1839,29 @@ static romvec_t romvecs[] = */ { /* 7 */ "Quadra AV ROMs", - (caddr_t) 0x4080cac6, /* ADB int */ - (caddr_t) 0x0, /* PM int */ - (caddr_t) 0x40805cd4, /* ADBBase + 130 */ - (caddr_t) 0x40839600, /* CountADBs */ - (caddr_t) 0x4083961a, /* GetIndADB */ - (caddr_t) 0x40839646, /* GetADBInfo */ - (caddr_t) 0x4083964c, /* SetADBInfo */ - (caddr_t) 0x408397b8, /* ADBReInit */ - (caddr_t) 0x4083967c, /* ADBOp */ - (caddr_t) 0x0, /* PMgrOp */ - (caddr_t) 0x4081141c, /* WriteParam */ - (caddr_t) 0x4081144e, /* SetDateTime */ - (caddr_t) 0x40811930, /* InitUtil */ - (caddr_t) 0x4080b624, /* ReadXPRam */ - (caddr_t) 0x4080b62e, /* WriteXPRam */ - (caddr_t) 0x40806884, /* jClkNoMem */ - (caddr_t) 0x408398c2, /* ADBAlternateInit */ - (caddr_t) 0x4080cada, /* Egret */ - (caddr_t) 0x4080de14, /* InitEgret */ - (caddr_t) 0x408143b8, /* ADBReInit_JTBL */ - (caddr_t) 0x409bdb60, /* ROMResourceMap List Head */ - (caddr_t) 0x4083b3d8, /* FixDiv */ - (caddr_t) 0x4083b2e4, /* FixMul */ + (caddr_t)0x4080cac6, /* ADB int */ + (caddr_t)0x0, /* PM int */ + (caddr_t)0x40805cd4, /* ADBBase + 130 */ + (caddr_t)0x40839600, /* CountADBs */ + (caddr_t)0x4083961a, /* GetIndADB */ + (caddr_t)0x40839646, /* GetADBInfo */ + (caddr_t)0x4083964c, /* SetADBInfo */ + (caddr_t)0x408397b8, /* ADBReInit */ + (caddr_t)0x4083967c, /* ADBOp */ + (caddr_t)0x0, /* PMgrOp */ + (caddr_t)0x4081141c, /* WriteParam */ + (caddr_t)0x4081144e, /* SetDateTime */ + (caddr_t)0x40811930, /* InitUtil */ + (caddr_t)0x4080b624, /* ReadXPRam */ + (caddr_t)0x4080b62e, /* WriteXPRam */ + (caddr_t)0x40806884, /* jClkNoMem */ + (caddr_t)0x408398c2, /* ADBAlternateInit */ + (caddr_t)0x4080cada, /* Egret */ + (caddr_t)0x4080de14, /* InitEgret */ + (caddr_t)0x408143b8, /* ADBReInit_JTBL */ + (caddr_t)0x409bdb60, /* ROMResourceMap List Head */ + (caddr_t)0x4083b3d8, /* FixDiv */ + (caddr_t)0x4083b2e4, /* FixMul */ }, /* * PB 540, PB 550 @@ -1716,319 +1869,348 @@ static romvec_t romvecs[] = */ { /* 8 */ "68040 PowerBook ROMs", - (caddr_t) 0x400b2efc, /* ADB int */ - (caddr_t) 0x400d8e66, /* PM int */ - (caddr_t) 0x400b2e86, /* ADBBase + 130 */ - (caddr_t) 0x4000a360, /* CountADBs */ - (caddr_t) 0x4000a37a, /* GetIndADB */ - (caddr_t) 0x4000a3a6, /* GetADBInfo */ - (caddr_t) 0x4000a3ac, /* SetADBInfo */ - (caddr_t) 0x4000a752, /* ADBReInit */ - (caddr_t) 0x4000a3dc, /* ADBOp */ - (caddr_t) 0x400d9302, /* PmgrOp */ - (caddr_t) 0x4000c05c, /* WriteParam */ - (caddr_t) 0x4000c086, /* SetDateTime */ - (caddr_t) 0x4000c5cc, /* InitUtil */ - (caddr_t) 0x4000b186, /* ReadXPRam */ - (caddr_t) 0x4000b190, /* WriteXPRam */ - (caddr_t) 0x400b3c08, /* jClkNoMem */ - (caddr_t) 0x4000a818, /* ADBAlternateInit */ - (caddr_t) 0x40009ae6, /* Egret */ /* From PB520 */ - (caddr_t) 0x400147c4, /* InitEgret */ - (caddr_t) 0x400a7a5c, /* ADBReInit_JTBL */ - (caddr_t) 0x4007eb90, /* ROMResourceMap List Head */ - (caddr_t) 0x4001c406, /* FixDiv, wild guess */ - (caddr_t) 0x4001c312, /* FixMul, wild guess */ + (caddr_t)0x400b2efc, /* ADB int */ + (caddr_t)0x400d8e66, /* PM int */ + (caddr_t)0x400b2e86, /* ADBBase + 130 */ + (caddr_t)0x4000a360, /* CountADBs */ + (caddr_t)0x4000a37a, /* GetIndADB */ + (caddr_t)0x4000a3a6, /* GetADBInfo */ + (caddr_t)0x4000a3ac, /* SetADBInfo */ + (caddr_t)0x4000a752, /* ADBReInit */ + (caddr_t)0x4000a3dc, /* ADBOp */ + (caddr_t)0x400d9302, /* PmgrOp */ + (caddr_t)0x4000c05c, /* WriteParam */ + (caddr_t)0x4000c086, /* SetDateTime */ + (caddr_t)0x4000c5cc, /* InitUtil */ + (caddr_t)0x4000b186, /* ReadXPRam */ + (caddr_t)0x4000b190, /* WriteXPRam */ + (caddr_t)0x400b3c08, /* jClkNoMem */ + (caddr_t)0x4000a818, /* ADBAlternateInit */ + (caddr_t)0x40009ae6, /* Egret */ /* From PB520 */ + (caddr_t)0x400147c4, /* InitEgret */ + (caddr_t)0x400a7a5c, /* ADBReInit_JTBL */ + (caddr_t)0x4007eb90, /* ROMResourceMap List Head */ + (caddr_t)0x4001c406, /* FixDiv, wild guess */ + (caddr_t)0x4001c312, /* FixMul, wild guess */ }, /* * Verified for the Q605 */ { /* 9 */ "Quadra/Centris 605 ROMs", - (caddr_t) 0x408a9b56, /* ADB int */ - (caddr_t) 0x0, /* PM int */ - (caddr_t) 0x408b2f94, /* ADBBase + 130 */ - (caddr_t) 0x4080a360, /* CountADBs */ - (caddr_t) 0x4080a37a, /* GetIndADB */ - (caddr_t) 0x4080a3a6, /* GetADBInfo */ - (caddr_t) 0x4080a3ac, /* SetADBInfo */ - (caddr_t) 0x4080a752, /* ADBReInit */ - (caddr_t) 0x4080a3dc, /* ADBOp */ - (caddr_t) 0x0, /* PmgrOp */ - (caddr_t) 0x4080c05c, /* WriteParam */ - (caddr_t) 0x4080c086, /* SetDateTime */ - (caddr_t) 0x4080c5cc, /* InitUtil */ - (caddr_t) 0x4080b186, /* ReadXPRam */ - (caddr_t) 0x4080b190, /* WriteXPRam */ - (caddr_t) 0x408b3bf8, /* jClkNoMem */ - (caddr_t) 0x4080a818, /* ADBAlternateInit */ - (caddr_t) 0x408a99c0, /* Egret */ - (caddr_t) 0x408147c4, /* InitEgret */ - (caddr_t) 0x408a82c0, /* ADBReInit_JTBL */ - (caddr_t) 0x4087eb90, /* ROMResourceMap List Head */ - (caddr_t) 0x4081c406, /* FixDiv */ - (caddr_t) 0x4081c312, /* FixMul */ + (caddr_t)0x408a9b56, /* ADB int */ + (caddr_t)0x0, /* PM int */ + (caddr_t)0x408b2f94, /* ADBBase + 130 */ + (caddr_t)0x4080a360, /* CountADBs */ + (caddr_t)0x4080a37a, /* GetIndADB */ + (caddr_t)0x4080a3a6, /* GetADBInfo */ + (caddr_t)0x4080a3ac, /* SetADBInfo */ + (caddr_t)0x4080a752, /* ADBReInit */ + (caddr_t)0x4080a3dc, /* ADBOp */ + (caddr_t)0x0, /* PmgrOp */ + (caddr_t)0x4080c05c, /* WriteParam */ + (caddr_t)0x4080c086, /* SetDateTime */ + (caddr_t)0x4080c5cc, /* InitUtil */ + (caddr_t)0x4080b186, /* ReadXPRam */ + (caddr_t)0x4080b190, /* WriteXPRam */ + (caddr_t)0x408b3bf8, /* jClkNoMem */ + (caddr_t)0x4080a818, /* ADBAlternateInit */ + (caddr_t)0x408a99c0, /* Egret */ + (caddr_t)0x408147c4, /* InitEgret */ + (caddr_t)0x408a82c0, /* ADBReInit_JTBL */ + (caddr_t)0x4087eb90, /* ROMResourceMap List Head */ + (caddr_t)0x4081c406, /* FixDiv */ + (caddr_t)0x4081c312, /* FixMul */ }, /* * Vectors verified for Duo 270c, PB150 */ { /* 10 */ "Duo 270C ROMs", - (caddr_t) 0x408b2efc, /* ADB interrupt */ - (caddr_t) 0x408885ec, /* PB ADB interrupt */ - (caddr_t) 0x408b2e86, /* ADBBase + 130 interrupt; whatzit? */ - (caddr_t) 0x4080a360, /* CountADBs */ - (caddr_t) 0x4080a37a, /* GetIndADB */ - (caddr_t) 0x4080a3a6, /* GetADBInfo */ - (caddr_t) 0x4080a3ac, /* SetADBInfo */ - (caddr_t) 0x4080a752, /* ADBReInit */ - (caddr_t) 0x4080a3dc, /* ADBOp */ - (caddr_t) 0x408888ec, /* PMgrOp */ - (caddr_t) 0x4080c05c, /* WriteParam */ - (caddr_t) 0x4080c086, /* SetDateTime */ - (caddr_t) 0x4080c5cc, /* InitUtil */ - (caddr_t) 0x4080b186, /* ReadXPRam */ - (caddr_t) 0x4080b190, /* WriteXPRam */ - (caddr_t) 0x408b3bf8, /* jClkNoMem */ /* from PB 150 */ - (caddr_t) 0x4080a818, /* ADBAlternateInit */ - (caddr_t) 0x40814800, /* Egret */ - (caddr_t) 0x408147c4, /* InitEgret */ - (caddr_t) 0x0, /* ADBReInit_JTBL */ - (caddr_t) 0x4087eb90, /* ROMResourceMap List Head */ - (caddr_t) 0x4081c406, /* FixDiv, wild guess */ - (caddr_t) 0x4081c312, /* FixMul, wild guess */ + (caddr_t)0x408b2efc, /* ADB interrupt */ + (caddr_t)0x408885ec, /* PB ADB interrupt */ + (caddr_t)0x408b2e86, /* ADBBase + 130 interrupt; whatzit? */ + (caddr_t)0x4080a360, /* CountADBs */ + (caddr_t)0x4080a37a, /* GetIndADB */ + (caddr_t)0x4080a3a6, /* GetADBInfo */ + (caddr_t)0x4080a3ac, /* SetADBInfo */ + (caddr_t)0x4080a752, /* ADBReInit */ + (caddr_t)0x4080a3dc, /* ADBOp */ + (caddr_t)0x408888ec, /* PMgrOp */ + (caddr_t)0x4080c05c, /* WriteParam */ + (caddr_t)0x4080c086, /* SetDateTime */ + (caddr_t)0x4080c5cc, /* InitUtil */ + (caddr_t)0x4080b186, /* ReadXPRam */ + (caddr_t)0x4080b190, /* WriteXPRam */ + (caddr_t)0x408b3bf8, /* jClkNoMem */ /* from PB 150 */ + (caddr_t)0x4080a818, /* ADBAlternateInit */ + (caddr_t)0x40814800, /* Egret */ + (caddr_t)0x408147c4, /* InitEgret */ + (caddr_t)0x0, /* ADBReInit_JTBL */ + (caddr_t)0x4087eb90, /* ROMResourceMap List Head */ + (caddr_t)0x4081c406, /* FixDiv, wild guess */ + (caddr_t)0x4081c312, /* FixMul, wild guess */ }, /* * Vectors verified for Performa/LC 550 */ { /* 11 */ "P/LC 550 ROMs", - (caddr_t) 0x408d16d6, /* ADB interrupt */ - (caddr_t) 0x0, /* PB ADB interrupt */ - (caddr_t) 0x408b2f84, /* ADBBase + 130 interrupt; whatzit? */ - (caddr_t) 0x4080a360, /* CountADBs */ - (caddr_t) 0x4080a37a, /* GetIndADB */ - (caddr_t) 0x4080a3a6, /* GetADBInfo */ - (caddr_t) 0x4080a3ac, /* SetADBInfo */ - (caddr_t) 0x4080a752, /* ADBReInit */ - (caddr_t) 0x4080a3dc, /* ADBOp */ - (caddr_t) 0x0, /* PMgrOp */ - (caddr_t) 0x4080c05c, /* WriteParam */ - (caddr_t) 0x4080c086, /* SetDateTime */ - (caddr_t) 0x4080c5cc, /* InitUtil */ - (caddr_t) 0x4080b186, /* ReadXPRam */ - (caddr_t) 0x4080b190, /* WriteXPRam */ - (caddr_t) 0x408b3c04, /* jClkNoMem */ - (caddr_t) 0x4080a818, /* ADBAlternateInit */ - (caddr_t) 0x408d1450, /* Egret */ - (caddr_t) 0x408147c4, /* InitEgret */ - (caddr_t) 0x408d24a4, /* ADBReInit_JTBL */ - (caddr_t) 0x4087eb90, /* ROMResourceMap List Head */ - (caddr_t) 0x4081c406, /* FixDiv for P550 */ - (caddr_t) 0x4081c312, /* FixMul for P550 */ + (caddr_t)0x408d16d6, /* ADB interrupt */ + (caddr_t)0x0, /* PB ADB interrupt */ + (caddr_t)0x408b2f84, /* ADBBase + 130 interrupt; whatzit? */ + (caddr_t)0x4080a360, /* CountADBs */ + (caddr_t)0x4080a37a, /* GetIndADB */ + (caddr_t)0x4080a3a6, /* GetADBInfo */ + (caddr_t)0x4080a3ac, /* SetADBInfo */ + (caddr_t)0x4080a752, /* ADBReInit */ + (caddr_t)0x4080a3dc, /* ADBOp */ + (caddr_t)0x0, /* PMgrOp */ + (caddr_t)0x4080c05c, /* WriteParam */ + (caddr_t)0x4080c086, /* SetDateTime */ + (caddr_t)0x4080c5cc, /* InitUtil */ + (caddr_t)0x4080b186, /* ReadXPRam */ + (caddr_t)0x4080b190, /* WriteXPRam */ + (caddr_t)0x408b3c04, /* jClkNoMem */ + (caddr_t)0x4080a818, /* ADBAlternateInit */ + (caddr_t)0x408d1450, /* Egret */ + (caddr_t)0x408147c4, /* InitEgret */ + (caddr_t)0x408d24a4, /* ADBReInit_JTBL */ + (caddr_t)0x4087eb90, /* ROMResourceMap List Head */ + (caddr_t)0x4081c406, /* FixDiv for P550 */ + (caddr_t)0x4081c312, /* FixMul for P550 */ }, /* * Vectors verified for the MacTV */ { /* 12 */ "MacTV ROMs", - (caddr_t) 0x40acfed6, /* ADB interrupt */ - (caddr_t) 0x0, /* PB ADB interrupt */ - (caddr_t) 0x40ab2f84, /* ADBBase + 130 interrupt; whatzit? */ - (caddr_t) 0x40a0a360, /* CountADBs */ - (caddr_t) 0x40a0a37a, /* GetIndADB */ - (caddr_t) 0x40a0a3a6, /* GetADBInfo */ - (caddr_t) 0x40a0a3ac, /* SetADBInfo */ - (caddr_t) 0x40a0a752, /* ADBReInit */ - (caddr_t) 0x40a0a3dc, /* ADBOp */ - (caddr_t) 0x0, /* PMgrOp */ - (caddr_t) 0x40a0c05c, /* WriteParam */ - (caddr_t) 0x40a0c086, /* SetDateTime */ - (caddr_t) 0x40a0c5cc, /* InitUtil */ - (caddr_t) 0x40a0b186, /* ReadXPRam */ - (caddr_t) 0x40a0b190, /* WriteXPRam */ - (caddr_t) 0x40ab3bf4, /* jClkNoMem */ - (caddr_t) 0x40a0a818, /* ADBAlternateInit */ - (caddr_t) 0x40acfd40, /* Egret */ - (caddr_t) 0x40a147c4, /* InitEgret */ - (caddr_t) 0x40a038a0, /* ADBReInit_JTBL */ - (caddr_t) 0x40a7eb90, /* ROMResourceMap List Head */ - (caddr_t) 0x40a1c406, /* FixDiv */ - (caddr_t) 0x40a1c312, /* FixMul */ + (caddr_t)0x40acfed6, /* ADB interrupt */ + (caddr_t)0x0, /* PB ADB interrupt */ + (caddr_t)0x40ab2f84, /* ADBBase + 130 interrupt; whatzit? */ + (caddr_t)0x40a0a360, /* CountADBs */ + (caddr_t)0x40a0a37a, /* GetIndADB */ + (caddr_t)0x40a0a3a6, /* GetADBInfo */ + (caddr_t)0x40a0a3ac, /* SetADBInfo */ + (caddr_t)0x40a0a752, /* ADBReInit */ + (caddr_t)0x40a0a3dc, /* ADBOp */ + (caddr_t)0x0, /* PMgrOp */ + (caddr_t)0x40a0c05c, /* WriteParam */ + (caddr_t)0x40a0c086, /* SetDateTime */ + (caddr_t)0x40a0c5cc, /* InitUtil */ + (caddr_t)0x40a0b186, /* ReadXPRam */ + (caddr_t)0x40a0b190, /* WriteXPRam */ + (caddr_t)0x40ab3bf4, /* jClkNoMem */ + (caddr_t)0x40a0a818, /* ADBAlternateInit */ + (caddr_t)0x40acfd40, /* Egret */ + (caddr_t)0x40a147c4, /* InitEgret */ + (caddr_t)0x40a038a0, /* ADBReInit_JTBL */ + (caddr_t)0x40a7eb90, /* ROMResourceMap List Head */ + (caddr_t)0x40a1c406, /* FixDiv */ + (caddr_t)0x40a1c312, /* FixMul */ }, /* * Vectors verified for the Quadra630 */ { /* 13 */ "Quadra630 ROMs", - (caddr_t) 0x408a9bd2, /* ADB int */ - (caddr_t) 0x0, /* PM intr */ - (caddr_t) 0x408b2f94, /* ADBBase + 130 */ - (caddr_t) 0x4080a360, /* CountADBs */ - (caddr_t) 0x4080a37a, /* GetIndADB */ - (caddr_t) 0x4080a3a6, /* GetADBInfo */ - (caddr_t) 0x4080a3ac, /* SetADBInfo */ - (caddr_t) 0x4080a752, /* ADBReInit */ - (caddr_t) 0x4080a3dc, /* ADBOp */ - (caddr_t) 0, /* PMgrOp */ - (caddr_t) 0x4080c05c, /* WriteParam */ - (caddr_t) 0x4080c086, /* SetDateTime */ - (caddr_t) 0x4080c5cc, /* InitUtil */ - (caddr_t) 0x4080b186, /* Wild guess at ReadXPRam */ - (caddr_t) 0x4080b190, /* Wild guess at WriteXPRam */ - (caddr_t) 0x408b39f4, /* jClkNoMem */ - (caddr_t) 0x4080a818, /* ADBAlternateInit */ - (caddr_t) 0x408a99c0, /* Egret */ - (caddr_t) 0x408147c8, /* InitEgret */ - (caddr_t) 0x408a7ef8, /* ADBReInit_JTBL */ - (caddr_t) 0x4087eb90, /* ROMResourceMap List Head */ - (caddr_t) 0x4081c406, /* FixDiv */ - (caddr_t) 0x4081c312, /* FixMul */ + (caddr_t)0x408a9bd2, /* ADB int */ + (caddr_t)0x0, /* PM intr */ + (caddr_t)0x408b2f94, /* ADBBase + 130 */ + (caddr_t)0x4080a360, /* CountADBs */ + (caddr_t)0x4080a37a, /* GetIndADB */ + (caddr_t)0x4080a3a6, /* GetADBInfo */ + (caddr_t)0x4080a3ac, /* SetADBInfo */ + (caddr_t)0x4080a752, /* ADBReInit */ + (caddr_t)0x4080a3dc, /* ADBOp */ + (caddr_t)0, /* PMgrOp */ + (caddr_t)0x4080c05c, /* WriteParam */ + (caddr_t)0x4080c086, /* SetDateTime */ + (caddr_t)0x4080c5cc, /* InitUtil */ + (caddr_t)0x4080b186, /* Wild guess at ReadXPRam */ + (caddr_t)0x4080b190, /* Wild guess at WriteXPRam */ + (caddr_t)0x408b39f4, /* jClkNoMem */ + (caddr_t)0x4080a818, /* ADBAlternateInit */ + (caddr_t)0x408a99c0, /* Egret */ + (caddr_t)0x408147c8, /* InitEgret */ + (caddr_t)0x408a7ef8, /* ADBReInit_JTBL */ + (caddr_t)0x4087eb90, /* ROMResourceMap List Head */ + (caddr_t)0x4081c406, /* FixDiv */ + (caddr_t)0x4081c312, /* FixMul */ }, /* * Vectors verified for LC III */ { /* 14 */ "LC III ROMs", - (caddr_t) 0x40814912, /* ADB interrupt */ - (caddr_t) 0x0, /* PM ADB interrupt */ - (caddr_t) 0x408b2f94, /* ADBBase + 130 interupt */ - (caddr_t) 0x4080a360, /* CountADBs */ - (caddr_t) 0x4080a37a, /* GetIndADB */ - (caddr_t) 0x4080a3a6, /* GetADBInfo */ - (caddr_t) 0x4080a3ac, /* SetADBInfo */ - (caddr_t) 0x4080a752, /* ADBReInit */ - (caddr_t) 0x4080a3dc, /* ADBOp */ - (caddr_t) 0x0, /* PMgrOp */ - (caddr_t) 0x4080c05c, /* WriteParam */ - (caddr_t) 0x4080c086, /* SetDateTime */ - (caddr_t) 0x4080c5cc, /* InitUtil */ - (caddr_t) 0x4080b186, /* ReadXPRam */ - (caddr_t) 0x4080b190, /* WriteXPRam */ - (caddr_t) 0x408b39b6, /* jClkNoMem */ - (caddr_t) 0x4080a818, /* ADBAlternateInit */ - (caddr_t) 0x40814800, /* Egret */ - (caddr_t) 0x408147c4, /* InitEgret */ - (caddr_t) 0x408d2918, /* ADBReInit_JTBL */ - (caddr_t) 0x4087eb90, /* ROMResourceMap List Head */ - (caddr_t) 0x4081c406, /* FixDiv */ - (caddr_t) 0x4081c312, /* FixMul */ + (caddr_t)0x40814912, /* ADB interrupt */ + (caddr_t)0x0, /* PM ADB interrupt */ + (caddr_t)0x408b2f94, /* ADBBase + 130 interupt */ + (caddr_t)0x4080a360, /* CountADBs */ + (caddr_t)0x4080a37a, /* GetIndADB */ + (caddr_t)0x4080a3a6, /* GetADBInfo */ + (caddr_t)0x4080a3ac, /* SetADBInfo */ + (caddr_t)0x4080a752, /* ADBReInit */ + (caddr_t)0x4080a3dc, /* ADBOp */ + (caddr_t)0x0, /* PMgrOp */ + (caddr_t)0x4080c05c, /* WriteParam */ + (caddr_t)0x4080c086, /* SetDateTime */ + (caddr_t)0x4080c5cc, /* InitUtil */ + (caddr_t)0x4080b186, /* ReadXPRam */ + (caddr_t)0x4080b190, /* WriteXPRam */ + (caddr_t)0x408b39b6, /* jClkNoMem */ + (caddr_t)0x4080a818, /* ADBAlternateInit */ + (caddr_t)0x40814800, /* Egret */ + (caddr_t)0x408147c4, /* InitEgret */ + (caddr_t)0x408d2918, /* ADBReInit_JTBL */ + (caddr_t)0x4087eb90, /* ROMResourceMap List Head */ + (caddr_t)0x4081c406, /* FixDiv */ + (caddr_t)0x4081c312, /* FixMul */ }, /* * Vectors verified for the LC520 */ { /* 15 */ "MacLC520 ROMs", - (caddr_t) 0x408d16d6, /* ADB interrupt */ - (caddr_t) 0x0, /* PB ADB interrupt */ - (caddr_t) 0x408b2f84, /* ADBBase + 130 interrupt; whatzit? */ - (caddr_t) 0x4080a360, /* CountADBs */ - (caddr_t) 0x4080a37a, /* GetIndADB */ - (caddr_t) 0x4080a3a6, /* GetADBInfo */ - (caddr_t) 0x4080a3ac, /* SetADBInfo */ - (caddr_t) 0x4080a752, /* ADBReInit */ - (caddr_t) 0x4080a3dc, /* ADBOp */ - (caddr_t) 0x0, /* PMgrOp */ - (caddr_t) 0x4080c05c, /* WriteParam */ - (caddr_t) 0x4080c086, /* SetDateTime */ - (caddr_t) 0x4080c5cc, /* InitUtil */ - (caddr_t) 0x4080b186, /* ReadXPRam */ - (caddr_t) 0x4080b190, /* WriteXPRam */ - (caddr_t) 0x408b3c04, /* jClkNoMem */ - (caddr_t) 0x4080a818, /* ADBAlternateInit */ - (caddr_t) 0x408d1450, /* Egret */ - (caddr_t) 0x408147c4, /* InitEgret */ - (caddr_t) 0x408d2460, /* ADBReInit_JTBL */ - (caddr_t) 0x4087eb90, /* ROMResourceMap List Head */ - (caddr_t) 0x4081c406, /* FixDiv for P520 */ - (caddr_t) 0x4081c312, /* FixMul for P520 */ + (caddr_t)0x408d16d6, /* ADB interrupt */ + (caddr_t)0x0, /* PB ADB interrupt */ + (caddr_t)0x408b2f84, /* ADBBase + 130 interrupt; whatzit? */ + (caddr_t)0x4080a360, /* CountADBs */ + (caddr_t)0x4080a37a, /* GetIndADB */ + (caddr_t)0x4080a3a6, /* GetADBInfo */ + (caddr_t)0x4080a3ac, /* SetADBInfo */ + (caddr_t)0x4080a752, /* ADBReInit */ + (caddr_t)0x4080a3dc, /* ADBOp */ + (caddr_t)0x0, /* PMgrOp */ + (caddr_t)0x4080c05c, /* WriteParam */ + (caddr_t)0x4080c086, /* SetDateTime */ + (caddr_t)0x4080c5cc, /* InitUtil */ + (caddr_t)0x4080b186, /* ReadXPRam */ + (caddr_t)0x4080b190, /* WriteXPRam */ + (caddr_t)0x408b3c04, /* jClkNoMem */ + (caddr_t)0x4080a818, /* ADBAlternateInit */ + (caddr_t)0x408d1450, /* Egret */ + (caddr_t)0x408147c4, /* InitEgret */ + (caddr_t)0x408d2460, /* ADBReInit_JTBL */ + (caddr_t)0x4087eb90, /* ROMResourceMap List Head */ + (caddr_t)0x4081c406, /* FixDiv for P520 */ + (caddr_t)0x4081c312, /* FixMul for P520 */ }, /* * Vectors verified for the LC 575/577/578 */ { /* 16 */ "MacLC575 ROMs", - (caddr_t) 0x408a9b56, /* ADB interrupt */ - (caddr_t) 0x0, /* PB ADB interrupt */ - (caddr_t) 0x408b2f94, /* ADBBase + 130 interrupt; whatzit? */ - (caddr_t) 0x4080a360, /* CountADBs */ - (caddr_t) 0x4080a37a, /* GetIndADB */ - (caddr_t) 0x4080a3a6, /* GetADBInfo */ - (caddr_t) 0x4080a3ac, /* SetADBInfo */ - (caddr_t) 0x4080a752, /* ADBReInit */ - (caddr_t) 0x4080a3dc, /* ADBOp */ - (caddr_t) 0x0, /* PMgrOp */ - (caddr_t) 0x4080c05c, /* WriteParam */ - (caddr_t) 0x4080c086, /* SetDateTime */ - (caddr_t) 0x4080c5cc, /* InitUtil */ - (caddr_t) 0x4080b186, /* ReadXPRam */ - (caddr_t) 0x4080b190, /* WriteXPRam */ - (caddr_t) 0x408b3bf8, /* jClkNoMem */ - (caddr_t) 0x4080a818, /* ADBAlternateInit */ - (caddr_t) 0x408a99c0, /* Egret */ - (caddr_t) 0x408147c4, /* InitEgret */ - (caddr_t) 0x408a81a0, /* ADBReInit_JTBL */ - (caddr_t) 0x4087eb90, /* ROMResourceMap List Head */ - (caddr_t) 0x4081c406, /* FixDiv for P520 */ - (caddr_t) 0x4081c312, /* FixMul for P520 */ + (caddr_t)0x408a9b56, /* ADB interrupt */ + (caddr_t)0x0, /* PB ADB interrupt */ + (caddr_t)0x408b2f94, /* ADBBase + 130 interrupt; whatzit? */ + (caddr_t)0x4080a360, /* CountADBs */ + (caddr_t)0x4080a37a, /* GetIndADB */ + (caddr_t)0x4080a3a6, /* GetADBInfo */ + (caddr_t)0x4080a3ac, /* SetADBInfo */ + (caddr_t)0x4080a752, /* ADBReInit */ + (caddr_t)0x4080a3dc, /* ADBOp */ + (caddr_t)0x0, /* PMgrOp */ + (caddr_t)0x4080c05c, /* WriteParam */ + (caddr_t)0x4080c086, /* SetDateTime */ + (caddr_t)0x4080c5cc, /* InitUtil */ + (caddr_t)0x4080b186, /* ReadXPRam */ + (caddr_t)0x4080b190, /* WriteXPRam */ + (caddr_t)0x408b3bf8, /* jClkNoMem */ + (caddr_t)0x4080a818, /* ADBAlternateInit */ + (caddr_t)0x408a99c0, /* Egret */ + (caddr_t)0x408147c4, /* InitEgret */ + (caddr_t)0x408a81a0, /* ADBReInit_JTBL */ + (caddr_t)0x4087eb90, /* ROMResourceMap List Head */ + (caddr_t)0x4081c406, /* FixDiv for P520 */ + (caddr_t)0x4081c312, /* FixMul for P520 */ }, /* * Vectors verified for the Quadra 950 */ { /* 17 */ "Quadra950 class ROMs", - (caddr_t) 0x40814912, /* ADB interrupt */ - (caddr_t) 0x0, /* PM ADB interrupt */ - (caddr_t) 0x4080a4d8, /* ADBBase + 130 interrupt; whatzit? */ - (caddr_t) 0x4080a360, /* CountADBs */ - (caddr_t) 0x4080a37a, /* GetIndADB */ - (caddr_t) 0x4080a3a6, /* GetADBInfo */ - (caddr_t) 0x4080a3ac, /* SetADBInfo */ - (caddr_t) 0x4080a752, /* ADBReInit */ - (caddr_t) 0x4080a3dc, /* ADBOp */ - (caddr_t) 0x0, /* PMgrOp */ - (caddr_t) 0x4080c05c, /* WriteParam */ - (caddr_t) 0x4080c086, /* SetDateTime */ - (caddr_t) 0x4080c5cc, /* InitUtil */ - (caddr_t) 0x4080b186, /* ReadXPRam */ - (caddr_t) 0x4080b190, /* WriteXPRam */ - (caddr_t) 0x4080b1e4, /* jClkNoMem */ - (caddr_t) 0x4080a818, /* ADBAlternateInit */ - (caddr_t) 0x40814800, /* Egret */ - (caddr_t) 0x408147c4, /* InitEgret */ - (caddr_t) 0x408038bc, /* ADBReInit_JTBL */ - (caddr_t) 0x4087eb90, /* ROMResourceMap List Head */ - (caddr_t) 0x4081c406, /* FixDiv */ - (caddr_t) 0x4081c312, /* FixMul */ + (caddr_t)0x40814912, /* ADB interrupt */ + (caddr_t)0x0, /* PM ADB interrupt */ + (caddr_t)0x4080a4d8, /* ADBBase + 130 interrupt; whatzit? */ + (caddr_t)0x4080a360, /* CountADBs */ + (caddr_t)0x4080a37a, /* GetIndADB */ + (caddr_t)0x4080a3a6, /* GetADBInfo */ + (caddr_t)0x4080a3ac, /* SetADBInfo */ + (caddr_t)0x4080a752, /* ADBReInit */ + (caddr_t)0x4080a3dc, /* ADBOp */ + (caddr_t)0x0, /* PMgrOp */ + (caddr_t)0x4080c05c, /* WriteParam */ + (caddr_t)0x4080c086, /* SetDateTime */ + (caddr_t)0x4080c5cc, /* InitUtil */ + (caddr_t)0x4080b186, /* ReadXPRam */ + (caddr_t)0x4080b190, /* WriteXPRam */ + (caddr_t)0x4080b1e4, /* jClkNoMem */ + (caddr_t)0x4080a818, /* ADBAlternateInit */ + (caddr_t)0x40814800, /* Egret */ + (caddr_t)0x408147c4, /* InitEgret */ + (caddr_t)0x408038bc, /* ADBReInit_JTBL */ + (caddr_t)0x4087eb90, /* ROMResourceMap List Head */ + (caddr_t)0x4081c406, /* FixDiv */ + (caddr_t)0x4081c312, /* FixMul */ }, /* * Vectors verified for the Mac IIfx */ { /* 18 */ "Mac IIfx ROMs", - (caddr_t) 0x40809f4a, /* ADB interrupt */ - (caddr_t) 0x0, /* PM ADB interrupt */ - (caddr_t) 0x4080a4d8, /* ADBBase + 130 interupt */ - (caddr_t) 0x4080a360, /* CountADBs */ - (caddr_t) 0x4080a37a, /* GetIndADB */ - (caddr_t) 0x4080a3a6, /* GetADBInfo */ - (caddr_t) 0x4080a3ac, /* SetADBInfo */ - (caddr_t) 0x4080a752, /* ADBReInit */ - (caddr_t) 0x4080a3dc, /* ADBOp */ - (caddr_t) 0x0, /* PMgrOp */ - (caddr_t) 0x4080c05c, /* WriteParam */ - (caddr_t) 0x4080c086, /* SetDateTime */ - (caddr_t) 0x4080c5cc, /* InitUtil */ - (caddr_t) 0x4080b186, /* ReadXPRam */ - (caddr_t) 0x4080b190, /* WriteXPRam */ - (caddr_t) 0x4080b1e4, /* jClkNoMem */ - (caddr_t) 0x4080a818, /* ADBAlternateInit */ - (caddr_t) 0x0, /* Egret */ - (caddr_t) 0x0, /* InitEgret */ - (caddr_t) 0x408037c0, /* ADBReInit_JTBL */ - (caddr_t) 0x4087eb90, /* ROMResourceMap List Head */ - (caddr_t) 0x4081c406, /* FixDiv */ - (caddr_t) 0x4081c312, /* FixMul */ + (caddr_t)0x40809f4a, /* ADB interrupt */ + (caddr_t)0x0, /* PM ADB interrupt */ + (caddr_t)0x4080a4d8, /* ADBBase + 130 interupt */ + (caddr_t)0x4080a360, /* CountADBs */ + (caddr_t)0x4080a37a, /* GetIndADB */ + (caddr_t)0x4080a3a6, /* GetADBInfo */ + (caddr_t)0x4080a3ac, /* SetADBInfo */ + (caddr_t)0x4080a752, /* ADBReInit */ + (caddr_t)0x4080a3dc, /* ADBOp */ + (caddr_t)0x0, /* PMgrOp */ + (caddr_t)0x4080c05c, /* WriteParam */ + (caddr_t)0x4080c086, /* SetDateTime */ + (caddr_t)0x4080c5cc, /* InitUtil */ + (caddr_t)0x4080b186, /* ReadXPRam */ + (caddr_t)0x4080b190, /* WriteXPRam */ + (caddr_t)0x4080b1e4, /* jClkNoMem */ + (caddr_t)0x4080a818, /* ADBAlternateInit */ + (caddr_t)0x0, /* Egret */ + (caddr_t)0x0, /* InitEgret */ + (caddr_t)0x408037c0, /* ADBReInit_JTBL */ + (caddr_t)0x4087eb90, /* ROMResourceMap List Head */ + (caddr_t)0x4081c406, /* FixDiv */ + (caddr_t)0x4081c312, /* FixMul */ + }, + /* + * Vectors verified for the Performa 588 (and 580?) + */ + { /* 19 */ + "Performa 580 ROMs", + (caddr_t)0x4089a8be, /* ADB interrupt */ + (caddr_t)0x0, /* PM ADB interrupt */ + (caddr_t)0x408b2f94, /* ADBBase + 130 interupt */ + (caddr_t)0x4080a360, /* CountADBs */ + (caddr_t)0x4080a37a, /* GetIndADB */ + (caddr_t)0x4080a3a6, /* GetADBInfo */ + (caddr_t)0x4080a3ac, /* SetADBInfo */ + (caddr_t)0x4080a752, /* ADBReInit */ + (caddr_t)0x4080a3dc, /* ADBOp */ + (caddr_t)0x0, /* PMgrOp */ + (caddr_t)0x4080c05c, /* WriteParam */ + (caddr_t)0x4080c086, /* SetDateTime */ + (caddr_t)0x4080c5cc, /* InitUtil */ + (caddr_t)0x4080b186, /* ReadXPRam */ + (caddr_t)0x4080b190, /* WriteXPRam */ + (caddr_t)0x408b3bf4, /* jClkNoMem */ + (caddr_t)0x4080a818, /* ADBAlternateInit */ + (caddr_t)0x408a99c0, /* Egret */ + (caddr_t)0x408147c8, /* InitEgret */ + (caddr_t)0x408a7f74, /* ADBReInit_JTBL */ + (caddr_t)0x4087eb90, /* ROMResourceMap List Head */ + (caddr_t)0x4081c406, /* FixDiv */ + (caddr_t)0x4081c312, /* FixMul */ }, /* Please fill these in! -BG */ }; @@ -2090,6 +2272,7 @@ struct cpu_model_info cpu_models[] = { {MACH_MACP600, "Performa", " 600 ", MACH_CLASSIIvx, &romvecs[2]}, {MACH_MACP460, "Performa", " 460 ", MACH_CLASSLC, &romvecs[14]}, {MACH_MACP550, "Performa", " 550 ", MACH_CLASSLC, &romvecs[11]}, + {MACH_MACP580, "Performa", " 580 ", MACH_CLASSQ2, &romvecs[19]}, {MACH_MACTV, "TV ", "", MACH_CLASSLC, &romvecs[12]}, /* The LCs... */ @@ -2132,6 +2315,7 @@ struct { { MACH_MACLC575, (caddr_t)0xf9000000, 1024 * 1024 }, { MACH_MACC610, (caddr_t)0xf9000000, 1024 * 1024 }, { MACH_MACC650, (caddr_t)0xf9000000, 1024 * 1024 }, + { MACH_MACP580, (caddr_t)0xf9000000, 1024 * 1024 }, { MACH_MACQ605, (caddr_t)0xf9000000, 1024 * 1024 }, { MACH_MACQ605_33, (caddr_t)0xf9000000, 1024 * 1024 }, { MACH_MACQ610, (caddr_t)0xf9000000, 1024 * 1024 }, @@ -2157,7 +2341,7 @@ struct { * ...? */ -char cpu_model[120]; /* for sysctl() */ +char cpu_model[120]; /* for sysctl() */ int mach_cputype __P((void)); @@ -2200,7 +2384,7 @@ static void get_machine_info __P((void)); static void get_machine_info() { - int i; + int i; for (i = 0; cpu_models[i].model_major; i++) if (mac68k_machine.machineid == cpu_models[i].machineid) @@ -2223,7 +2407,6 @@ void setmachdep __P((void)); void setmachdep() { - static int firstpass = 1; int setup_mrg_vectors = 0; struct cpu_model_info *cpui; int i; @@ -2233,17 +2416,12 @@ setmachdep() * Ideally, we'd only call this once, but for some reason, the * VIAs need interrupts turned off twice !? */ - if (firstpass) { - get_machine_info(); + get_machine_info(); - load_addr = 0; - } + load_addr = 0; cpui = &(cpu_models[mac68k_machine.cpu_model_index]); current_mac_model = cpui; - if (!firstpass) - return; - /* * Set up any machine specific stuff that we have to before * ANYTHING else happens @@ -2252,7 +2430,7 @@ setmachdep() case MACH_CLASSII: VIA2 = 1; IOBase = 0x50f00000; - Via1Base = (volatile u_char *) IOBase; + Via1Base = (volatile u_char *)IOBase; mac68k_machine.scsi80 = 1; mac68k_machine.zs_chip = 0; mac68k_machine.sccClkConst = 115200; @@ -2263,7 +2441,7 @@ setmachdep() case MACH_CLASSPB: VIA2 = 1; IOBase = 0x50f00000; - Via1Base = (volatile u_char *) IOBase; + Via1Base = (volatile u_char *)IOBase; mac68k_machine.scsi80 = 1; mac68k_machine.zs_chip = 0; mac68k_machine.sccClkConst = 115200; @@ -2282,7 +2460,7 @@ setmachdep() */ VIA2 = 0x13; IOBase = 0x50f00000; - Via1Base = (volatile u_char *) IOBase; + Via1Base = (volatile u_char *)IOBase; mac68k_machine.scsi80 = 1; mac68k_machine.zs_chip = 0; mac68k_machine.sccClkConst = 115200; @@ -2292,12 +2470,13 @@ setmachdep() via_reg(VIA2, rIER) = 0x7f; /* disable VIA2 int */ break; case MACH_CLASSQ: - case MACH_CLASSQ2: + case MACH_CLASSQ2: mac68k_machine.sonic = 1; case MACH_CLASSAV: + case MACH_CLASSP580: VIA2 = 1; IOBase = 0x50f00000; - Via1Base = (volatile u_char *) IOBase; + Via1Base = (volatile u_char *)IOBase; mac68k_machine.scsi96 = 1; mac68k_machine.zs_chip = 0; mac68k_machine.sccClkConst = 115200; @@ -2307,7 +2486,7 @@ setmachdep() case MACH_CLASSIIci: VIA2 = 0x13; IOBase = 0x50f00000; - Via1Base = (volatile u_char *) IOBase; + Via1Base = (volatile u_char *)IOBase; mac68k_machine.scsi80 = 1; mac68k_machine.zs_chip = 0; mac68k_machine.sccClkConst = 115200; @@ -2317,7 +2496,7 @@ setmachdep() case MACH_CLASSIIsi: VIA2 = 0x13; IOBase = 0x50f00000; - Via1Base = (volatile u_char *) IOBase; + Via1Base = (volatile u_char *)IOBase; mac68k_machine.scsi80 = 1; mac68k_machine.zs_chip = 0; mac68k_machine.sccClkConst = 115200; @@ -2327,7 +2506,7 @@ setmachdep() case MACH_CLASSIIvx: VIA2 = 0x13; IOBase = 0x50f00000; - Via1Base = (volatile u_char *) IOBase; + Via1Base = (volatile u_char *)IOBase; mac68k_machine.scsi80 = 1; mac68k_machine.zs_chip = 0; mac68k_machine.sccClkConst = 115200; @@ -2337,7 +2516,7 @@ setmachdep() case MACH_CLASSLC: VIA2 = 0x13; IOBase = 0x50f00000; - Via1Base = (volatile u_char *) IOBase; + Via1Base = (volatile u_char *)IOBase; mac68k_machine.scsi80 = 1; mac68k_machine.zs_chip = 0; mac68k_machine.sccClkConst = 115200; @@ -2347,7 +2526,7 @@ setmachdep() case MACH_CLASSIIfx: VIA2 = 0xd; IOBase = 0x50f00000; - Via1Base = (volatile u_char *) IOBase; + Via1Base = (volatile u_char *)IOBase; mac68k_machine.scsi80 = 1; mac68k_machine.zs_chip = 0; mac68k_machine.sccClkConst = 115200; /* XXX unverified */ @@ -2359,14 +2538,14 @@ setmachdep() } /* - * Set `internal' framebuffer location and length, if we know + * Set `internal' framebuffer location and length, if we know * what they are. */ for (i = 0; intvid_info[i].machineid; i++) { if (mac68k_machine.machineid == intvid_info[i].machineid) { mac68k_vidlog = mac68k_vidphys = - (u_int32_t) intvid_info[i].fbbase; - mac68k_vidlen = (u_int32_t) intvid_info[i].fblen; + (u_int32_t)intvid_info[i].fbbase; + mac68k_vidlen = (u_int32_t)intvid_info[i].fblen; break; } } @@ -2379,8 +2558,6 @@ setmachdep() */ if ((mac68k_machine.serial_console & 0x03) == 0 || setup_mrg_vectors) mrg_MacOSROMVectors = cpui->rom_vectors; - - firstpass = 0; } /* @@ -2408,8 +2585,8 @@ mac68k_set_io_offsets(base) switch (current_mac_model->class) { case MACH_CLASSQ: - Via1Base = (volatile u_char *) base; - sccA = (volatile u_char *) base + 0xc000; + Via1Base = (volatile u_char *)base; + sccA = (volatile u_char *)base + 0xc000; switch (current_mac_model->machineid) { case MACH_MACQ900: case MACH_MACQ950: @@ -2418,7 +2595,7 @@ mac68k_set_io_offsets(base) * the serial port in `compatible' mode (set in * the Serial Switch control panel before booting). */ - sccA = (volatile u_char *) base + 0xc020; + sccA = (volatile u_char *)base + 0xc020; mac68k_machine.scsi96_2 = 1; case MACH_MACQ700: SCSIBase = base + 0xf000; @@ -2434,15 +2611,24 @@ mac68k_set_io_offsets(base) * machines. This seems to be common on many of the * Quadra-type machines. */ - Via1Base = (volatile u_char *) base; - sccA = (volatile u_char *) base + 0xc020; + Via1Base = (volatile u_char *)base; + sccA = (volatile u_char *)base + 0xc020; SCSIBase = base + 0x10000; break; + case MACH_CLASSP580: + /* + * Here's a queer bird... it seems to be a cross between + * the two different Quadra classes. + */ + Via1Base = (volatile u_char *)base; + sccA = (volatile u_char *)base + 0xc020; + SCSIBase = base; + break; case MACH_CLASSAV: - Via1Base = (volatile u_char *) base; - sccA = (volatile u_char *) base + 0x4000; + Via1Base = (volatile u_char *)base; + sccA = (volatile u_char *)base + 0x4000; SCSIBase = base + 0x18000; - PSCBase = (volatile u_char *) base + 0x31000; + PSCBase = (volatile u_char *)base + 0x31000; mac68k_bioipl = PSL_S | PSL_IPL4; mac68k_netipl = PSL_S | PSL_IPL4; mac68k_impipl = PSL_S | PSL_IPL4; @@ -2455,8 +2641,8 @@ mac68k_set_io_offsets(base) case MACH_CLASSIIsi: case MACH_CLASSIIvx: case MACH_CLASSLC: - Via1Base = (volatile u_char *) base; - sccA = (volatile u_char *) base + 0x4000; + Via1Base = (volatile u_char *)base; + sccA = (volatile u_char *)base + 0x4000; SCSIBase = base; break; case MACH_CLASSIIfx: @@ -2465,8 +2651,8 @@ mac68k_set_io_offsets(base) * the serial port in `compatible' mode (set in * the Serial Switch control panel before booting). */ - Via1Base = (volatile u_char *) base; - sccA = (volatile u_char *) base + 0x4020; + Via1Base = (volatile u_char *)base; + sccA = (volatile u_char *)base + 0x4020; SCSIBase = base; break; default: @@ -2506,9 +2692,9 @@ gray_bar() /* MF the 10*rowbytes/4 is done lots, but we want this to be * slow */ for (i = 0; i < 10 * videorowbytes / 4; i++) - ((u_long *) videoaddr)[gray_nextaddr++] = 0xaaaaaaaa; + ((u_long *)videoaddr)[gray_nextaddr++] = 0xaaaaaaaa; for (i = 0; i < 2 * videorowbytes / 4; i++) - ((u_long *) videoaddr)[gray_nextaddr++] = 0x00000000; + ((u_long *)videoaddr)[gray_nextaddr++] = 0x00000000; } __asm __volatile (" movl sp@+,d1; @@ -2531,15 +2717,15 @@ extern int get_pte __P((u_int addr, u_long pte[2], u_short * psr)); static u_long get_physical(u_int addr, u_long * phys) { - u_long pte[2], ph, mask; + u_long pte[2], ph, mask; u_short psr; - int i, numbits; + int i, numbits; extern u_int macos_tc; if (mmutype == MMU_68040) { - ph = ptest040((caddr_t) addr, FC_SUPERD); + ph = ptest040((caddr_t)addr, FC_SUPERD); if ((ph & MMU40_RES) == 0) { - ph = ptest040((caddr_t) addr, FC_USERD); + ph = ptest040((caddr_t)addr, FC_USERD); if ((ph & MMU40_RES) == 0) return 0; } @@ -2588,10 +2774,10 @@ static void check_video __P((char *, u_long, u_long)); static void check_video(id, limit, maxm) - char *id; - u_long limit, maxm; + char *id; + u_long limit, maxm; { - u_long addr, phys; + u_long addr, phys; if (!get_physical(videoaddr, &phys)) printf("get_mapping(): %s. False start.\n", id); @@ -2629,8 +2815,8 @@ check_video(id, limit, maxm) u_int get_mapping(void) { - int i, same; - u_long addr, lastpage, phys, len; + int i, same; + u_long addr, lastpage, phys, len; numranges = 0; for (i = 0; i < 8; i++) { @@ -2659,128 +2845,140 @@ get_mapping(void) } #endif - /* - * We should now look through all of NuBus space to find where - * the internal video is being mapped. Just to be sure we handle - * all the cases, we simply map our NuBus space exactly how - * MacOS did it. As above, we find a bunch of ranges that are - * contiguously mapped. Since there are a lot of pages that - * are all mapped to 0, we handle that as a special case where - * the length is negative. We search in increments of 32768 - * because that's the page size that MacOS uses. - */ - - nbnumranges = 0; - for (i = 0; i < NBMAXRANGES; i++) { - nbphys[i] = 0; - nblog[i] = 0; - nblen[i] = 0; - } - - same = 0; - for (addr = 0xF9000000; addr < 0xFF000000; addr += 32768) { - if (!get_physical(addr, &phys)) { - continue; + if (mac68k_vidlen > 0) { + /* + * We've already figured out where internal video is in + * setmachdep() (by using intvid_info[]). Tell the user + * what we know. + */ + printf("On-board video at addr 0x%x (phys 0x%x), len 0x%x.\n", + mac68k_vidlog, mac68k_vidphys, mac68k_vidlen); + } else { + /* + * We should now look through all of NuBus space to find where + * the internal video is being mapped. Just to be sure we + * handle all the cases, we simply map our NuBus space exactly + * how MacOS did it. As above, we find a bunch of ranges that + * are contiguously mapped. Since there are a lot of pages + * that are all mapped to 0, we handle that as a special case + * where the length is negative. We search in increments of + * 32768 because that's the page size that MacOS uses. + */ + nbnumranges = 0; + for (i = 0; i < NBMAXRANGES; i++) { + nbphys[i] = 0; + nblog[i] = 0; + nblen[i] = 0; } - len = nbnumranges == 0 ? 0 : nblen[nbnumranges - 1]; + + same = 0; + for (addr = 0xF9000000; addr < 0xFF000000; addr += 32768) { + if (!get_physical(addr, &phys)) { + continue; + } + len = nbnumranges == 0 ? 0 : nblen[nbnumranges - 1]; #if 0 - printf ("0x%lx --> 0x%lx\n", addr, phys); + printf ("0x%lx --> 0x%lx\n", addr, phys); #endif - if (nbnumranges > 0 - && addr == nblog[nbnumranges - 1] + len - && phys == nbphys[nbnumranges - 1]) { /* Same as last one */ - nblen[nbnumranges - 1] += 32768; - same = 1; - } else { - if ((nbnumranges > 0) - && !same - && (addr == nblog[nbnumranges - 1] + len) - && (phys == nbphys[nbnumranges - 1] + len)) { + if (nbnumranges > 0 + && addr == nblog[nbnumranges - 1] + len + && phys == nbphys[nbnumranges - 1]) { + /* Same as last one */ nblen[nbnumranges - 1] += 32768; + same = 1; } else { - if (same) { - nblen[nbnumranges - 1] = -len; - same = 0; - } - if (nbnumranges == NBMAXRANGES) { - printf("get_mapping(): Too many NuBus " - "ranges.\n"); - break; + if ((nbnumranges > 0) + && !same + && (addr == nblog[nbnumranges - 1] + len) + && (phys == nbphys[nbnumranges - 1] + len)) + nblen[nbnumranges - 1] += 32768; + else { + if (same) { + nblen[nbnumranges - 1] = -len; + same = 0; + } + if (nbnumranges == NBMAXRANGES) { + printf("get_mapping(): " + "Too many NuBus ranges.\n"); + break; + } + nbnumranges++; + nblog[nbnumranges - 1] = addr; + nbphys[nbnumranges - 1] = phys; + nblen[nbnumranges - 1] = 32768; } - nbnumranges++; - nblog[nbnumranges - 1] = addr; - nbphys[nbnumranges - 1] = phys; - nblen[nbnumranges - 1] = 32768; } } - } - if (same) { - nblen[nbnumranges - 1] = -nblen[nbnumranges - 1]; - same = 0; - } + if (same) { + nblen[nbnumranges - 1] = -nblen[nbnumranges - 1]; + same = 0; + } #if 0 - printf("Non-system RAM (nubus, etc.):\n"); - for (i = 0; i < nbnumranges; i++) { - printf(" Log = 0x%lx, Phys = 0x%lx, Len = 0x%lx (%lu)\n", - nblog[i], nbphys[i], nblen[i], nblen[i]); - } + printf("Non-system RAM (nubus, etc.):\n"); + for (i = 0; i < nbnumranges; i++) { + printf(" Log = 0x%lx, Phys = 0x%lx, Len = 0x%lx (%lu)\n", + nblog[i], nbphys[i], nblen[i], nblen[i]); + } #endif - /* - * We must now find the logical address of internal video in the - * ranges we made above. Internal video is at physical 0, but - * a lot of pages map there. Instead, we look for the logical - * page that maps to 32768 and go back one page. - */ - - for (i = 0; i < nbnumranges; i++) { - if (nblen[i] > 0 - && nbphys[i] <= 32768 - && 32768 <= nbphys[i] + nblen[i]) { - mac68k_vidlog = nblog[i] - nbphys[i]; - mac68k_vidlen = nblen[i] + nbphys[i]; - mac68k_vidphys = 0; - break; + /* + * We must now find the logical address of internal video in the + * ranges we made above. Internal video is at physical 0, but + * a lot of pages map there. Instead, we look for the logical + * page that maps to 32768 and go back one page. + */ + for (i = 0; i < nbnumranges; i++) { + if (nblen[i] > 0 + && nbphys[i] <= 32768 + && 32768 <= nbphys[i] + nblen[i]) { + mac68k_vidlog = nblog[i] - nbphys[i]; + mac68k_vidlen = nblen[i] + nbphys[i]; + mac68k_vidphys = 0; + break; + } } - } - if (i == nbnumranges) { - if (0xfee00000 <= videoaddr && videoaddr < 0xfee10000) { - /* - * Kludge for Classic II video. - */ - check_video("Classic II video (0xfee09a80)", - 21888, 21888); - } else if (0x60000000 <= videoaddr && videoaddr < 0x70000000) { - printf("Checking for Internal Video "); - /* - * Kludge for IIvx internal video (60b0 0000). - * PB 520 (6000 0000) - */ - check_video("PB/IIvx (0x60?00000)", 1 * 1024 * 1024, - 1 * 1024 * 1024); - } else if (0x50F40000 <= videoaddr && videoaddr < 0x50FBFFFF) { - /* - * Kludge for LC internal video - */ - check_video("LC video (0x50f40000)", - 512 * 1024, 512 * 1024); - } else if (0x50100100 <= videoaddr && videoaddr < 0x50400000) { - /* - * Kludge for AV internal video - */ - check_video("AV video (0x50100100)", 1 * 1024 * 1024, - 1 * 1024 * 1024); + if (i == nbnumranges) { + if (0xfee00000 <= videoaddr && videoaddr < 0xfee10000) { + /* + * Kludge for Classic II video. + */ + check_video("Classic II video (0xfee09a80)", + 21888, 21888); + } else if (0x60000000 <= videoaddr && + videoaddr < 0x70000000) { + printf("Checking for Internal Video "); + /* + * Kludge for IIvx internal video (60b0 0000). + * PB 520 (6000 0000) + */ + check_video("PB/IIvx (0x60?00000)", + 1 * 1024 * 1024, 1 * 1024 * 1024); + } else if (0x50F40000 <= videoaddr + && videoaddr < 0x50FBFFFF) { + /* + * Kludge for LC internal video + */ + check_video("LC video (0x50f40000)", + 512 * 1024, 512 * 1024); + } else if (0x50100100 <= videoaddr + && videoaddr < 0x50400000) { + /* + * Kludge for AV internal video + */ + check_video("AV video (0x50100100)", + 1 * 1024 * 1024, 1 * 1024 * 1024); + } else { + printf( " no internal video at address 0 -- " + "videoaddr is 0x%lx.\n", videoaddr); + } } else { - printf( " no internal video at address 0 -- " - "videoaddr is 0x%lx.\n", videoaddr); + printf(" Video address = 0x%lx\n", videoaddr); + printf(" Int video starts at 0x%x\n", + mac68k_vidlog); + printf(" Length = 0x%x (%d) bytes\n", + mac68k_vidlen, mac68k_vidlen); } - } else { - printf(" Video address = 0x%lx\n", videoaddr); - printf(" Int video starts at 0x%x\n", - mac68k_vidlog); - printf(" Length = 0x%x (%d) bytes\n", - mac68k_vidlen, mac68k_vidlen); } return low[0]; /* Return physical address of logical 0 */ @@ -2822,7 +3020,7 @@ mac68k_set_bell_callback(callback, cookie) void *cookie; { mac68k_bell_callback = callback; - mac68k_bell_cookie = (caddr_t) cookie; + mac68k_bell_cookie = (caddr_t)cookie; } int diff --git a/sys/arch/mac68k/mac68k/mem.c b/sys/arch/mac68k/mac68k/mem.c index 189648ab39a..ee5bda17417 100644 --- a/sys/arch/mac68k/mac68k/mem.c +++ b/sys/arch/mac68k/mac68k/mem.c @@ -1,5 +1,5 @@ -/* $OpenBSD: mem.c,v 1.10 2001/05/05 20:56:42 art Exp $ */ -/* $NetBSD: mem.c,v 1.11 1996/05/05 06:18:41 briggs Exp $ */ +/* $OpenBSD: mem.c,v 1.11 2001/05/08 17:30:41 aaron Exp $ */ +/* $NetBSD: mem.c,v 1.16 1998/11/10 07:29:59 scottr Exp $ */ /* * Copyright (c) 1988 University of Utah. @@ -57,6 +57,12 @@ #include <vm/vm.h> +#if defined(UVM) +#include <uvm/uvm_extern.h> +#endif + +extern u_long maxaddr; + static caddr_t devzeropage; #define mmread mmrw @@ -131,6 +137,15 @@ mmrw(dev, uio, flags) /* minor device 0 is physical memory */ case 0: v = uio->uio_offset; + + /* + * Only allow reads in physical RAM. + */ + if (v >= maxaddr || v < 0) { + error = EFAULT; + goto unlock; + } + pmap_enter(pmap_kernel(), (vm_offset_t)vmmap, trunc_page(v), uio->uio_rw == UIO_READ ? VM_PROT_READ : VM_PROT_WRITE, TRUE, 0); @@ -145,9 +160,15 @@ mmrw(dev, uio, flags) case 1: v = uio->uio_offset; c = min(iov->iov_len, MAXPHYS); +#if defined(UVM) + if (!uvm_kernacc((caddr_t)v, c, + uio->uio_rw == UIO_READ ? B_READ : B_WRITE)) + return (EFAULT); +#else if (!kernacc((caddr_t)v, c, uio->uio_rw == UIO_READ ? B_READ : B_WRITE)) return (EFAULT); +#endif error = uiomove((caddr_t)v, c, uio); continue; @@ -163,6 +184,11 @@ mmrw(dev, uio, flags) c = iov->iov_len; break; } + + /* + * On the first call, allocate and zero a page + * of memory for use with /dev/zero. + */ if (devzeropage == NULL) { devzeropage = (caddr_t) malloc(PAGE_SIZE, M_TEMP, M_WAITOK); @@ -177,12 +203,13 @@ mmrw(dev, uio, flags) } if (error) break; - iov->iov_base += c; + (caddr_t)iov->iov_base += c; iov->iov_len -= c; uio->uio_offset += c; uio->uio_resid -= c; } if (minor(dev) == 0) { +unlock: if (physlock > 1) wakeup((caddr_t)&physlock); physlock = 0; @@ -195,11 +222,6 @@ mmmmap(dev, off, prot) dev_t dev; int off, prot; { - extern int numranges; - extern u_long low[8]; - extern u_long high[8]; - int seg; - /* * /dev/mem is the only one that makes sense through this * interface. For /dev/kmem any physaddr we return here @@ -210,17 +232,14 @@ mmmmap(dev, off, prot) */ if (minor(dev) != 0) return (-1); + /* - * Allow access only in RAM. - * - * XXX could be extended to allow access to IO space but must - * be very careful. + * Only allow access to physical RAM. */ - for (seg = 0; seg < numranges; seg++) { - if (((u_long)off >= low[seg]) && ((u_long)off <= high[seg])) - return (m68k_btop(off)); - } - return (-1); + if ((unsigned)off >= maxaddr) + return (-1); + + return (m68k_btop(off)); } int diff --git a/sys/arch/mac68k/mac68k/pmap.c b/sys/arch/mac68k/mac68k/pmap.c index 275ef201b7c..73dec155d16 100644 --- a/sys/arch/mac68k/mac68k/pmap.c +++ b/sys/arch/mac68k/mac68k/pmap.c @@ -1,7 +1,7 @@ -/* $OpenBSD: pmap.c,v 1.17 2001/05/05 21:26:38 art Exp $ */ -/* $NetBSD: pmap.c,v 1.28 1996/10/21 05:42:27 scottr Exp $ */ +/* $OpenBSD: pmap.c,v 1.18 2001/05/08 17:30:41 aaron Exp $ */ +/* $NetBSD: pmap.c,v 1.55 1999/04/22 04:24:53 chs Exp $ */ -/* +/* * Copyright (c) 1991, 1993 * The Regents of the University of California. All rights reserved. * @@ -60,7 +60,7 @@ * Bitwise and/or operations are significantly faster than bitfield * references so we use them when accessing STE/PTEs in the pmap_pte_* * macros. Note also that the two are not always equivalent; e.g.: - * (*pte & PG_PROT) [4] != pte->pg_prot [1] + * (*pte & PG_PROT)[4] != pte->pg_prot[1] * and a couple of routines that deal with protection and wiring take * some shortcuts that assume the and/or definitions. * @@ -99,6 +99,7 @@ #include <sys/proc.h> #include <sys/malloc.h> #include <sys/user.h> +#include <sys/pool.h> #include <machine/pte.h> @@ -106,60 +107,13 @@ #include <vm/vm_kern.h> #include <vm/vm_page.h> -#include <machine/cpu.h> - -#ifdef PMAPSTATS -struct { - int collectscans; - int collectpages; - int kpttotal; - int kptinuse; - int kptmaxuse; -} kpt_stats; -struct { - int kernel; /* entering kernel mapping */ - int user; /* entering user mapping */ - int ptpneeded; /* needed to allocate a PT page */ - int nochange; /* no change at all */ - int pwchange; /* no mapping change, just wiring or protection */ - int wchange; /* no mapping change, just wiring */ - int pchange; /* no mapping change, just protection */ - int mchange; /* was mapped but mapping to different page */ - int managed; /* a managed page */ - int firstpv; /* first mapping for this PA */ - int secondpv; /* second mapping for this PA */ - int ci; /* cache inhibited */ - int unmanaged; /* not a managed page */ - int flushes; /* cache flushes */ -} enter_stats; -struct { - int calls; - int removes; - int pvfirst; - int pvsearch; - int ptinvalid; - int uflushes; - int sflushes; -} remove_stats; -struct { - int calls; - int changed; - int alreadyro; - int alreadyrw; -} protect_stats; -struct chgstats { - int setcalls; - int sethits; - int setmiss; - int clrcalls; - int clrhits; - int clrmiss; -} changebit_stats[16]; +#if defined(UVM) +#include <uvm/uvm.h> #endif +#include <machine/cpu.h> + #ifdef DEBUG -int debugmap = 0; -int pmapdebug = 0x2000; #define PDB_FOLLOW 0x0001 #define PDB_INIT 0x0002 #define PDB_ENTER 0x0004 @@ -176,38 +130,43 @@ int pmapdebug = 0x2000; #define PDB_WIRING 0x4000 #define PDB_PVDUMP 0x8000 +int debugmap = 0; +int pmapdebug = PDB_PARANOIA; + +#define PMAP_DPRINTF(l, x) if (pmapdebug & (l)) printf x + #if defined(M68040) int dowriteback = 1; /* 68040: enable writeback caching */ int dokwriteback = 1; /* 68040: enable writeback caching of kernel AS */ #endif - -extern vm_offset_t pager_sva, pager_eva; -#endif +#else /* ! DEBUG */ +#define PMAP_DPRINTF(l, x) /* nothing */ +#endif /* DEBUG */ /* * Get STEs and PTEs for user/kernel address space */ #if defined(M68040) -#define pmap_ste1(m, v) \ - (&((m)->pm_stab[(vm_offset_t)(v) >> SG4_SHIFT1])) +#define pmap_ste1(m, v) \ + (&((m)->pm_stab[(vaddr_t)(v) >> SG4_SHIFT1])) /* XXX assumes physically contiguous ST pages (if more than one) */ #define pmap_ste2(m, v) \ (&((m)->pm_stab[(st_entry_t *)(*(u_int *)pmap_ste1(m, v) & SG4_ADDR1) \ - (m)->pm_stpa + (((v) & SG4_MASK2) >> SG4_SHIFT2)])) -#define pmap_ste(m, v) \ - (&((m)->pm_stab[(vm_offset_t)(v) \ +#define pmap_ste(m, v) \ + (&((m)->pm_stab[(vaddr_t)(v) \ >> (mmutype == MMU_68040 ? SG4_SHIFT1 : SG_ISHIFT)])) #define pmap_ste_v(m, v) \ - (mmutype == MMU_68040 \ - ? ((*pmap_ste1(m, v) & SG_V) && \ - (*pmap_ste2(m, v) & SG_V)) \ + (mmutype == MMU_68040 \ + ? ((*pmap_ste1(m, v) & SG_V) && \ + (*pmap_ste2(m, v) & SG_V)) \ : (*pmap_ste(m, v) & SG_V)) #else -#define pmap_ste(m, v) (&((m)->pm_stab[(vm_offset_t)(v) >> SG_ISHIFT])) -#define pmap_ste_v(m, v) (*pmap_ste(m, v) & SG_V) +#define pmap_ste(m, v) (&((m)->pm_stab[(vaddr_t)(v) >> SG_ISHIFT])) +#define pmap_ste_v(m, v) (*pmap_ste(m, v) & SG_V) #endif -#define pmap_pte(m, v) (&((m)->pm_ptab[(vm_offset_t)(v) >> PG_SHIFT])) +#define pmap_pte(m, v) (&((m)->pm_ptab[(vaddr_t)(v) >> PG_SHIFT])) #define pmap_pte_pa(pte) (*(pte) & PG_FRAME) #define pmap_pte_w(pte) (*(pte) & PG_W) #define pmap_pte_ci(pte) (*(pte) & PG_CI) @@ -216,17 +175,13 @@ extern vm_offset_t pager_sva, pager_eva; #define pmap_pte_prot(pte) (*(pte) & PG_PROT) #define pmap_pte_v(pte) (*(pte) & PG_V) -#define pmap_pte_set_w(pte, v) \ +#define pmap_pte_set_w(pte, v) \ if (v) *(pte) |= PG_W; else *(pte) &= ~PG_W #define pmap_pte_set_prot(pte, v) \ if (v) *(pte) |= PG_PROT; else *(pte) &= ~PG_PROT #define pmap_pte_w_chg(pte, nw) ((nw) ^ pmap_pte_w(pte)) #define pmap_pte_prot_chg(pte, np) ((np) ^ pmap_pte_prot(pte)) -#define pmap_valid_page(pa) (pmap_initialized && pmap_page_index(pa) >= 0) - -int pmap_page_index(vm_offset_t pa); - /* * Given a map and a machine independent protection code, * convert to a m68k protection code. @@ -239,8 +194,8 @@ int protection_codes[8]; */ struct kpt_page { struct kpt_page *kpt_next; /* link on either used or free list */ - vm_offset_t kpt_va; /* always valid kernel VA */ - vm_offset_t kpt_pa; /* PA of this page (for speed) */ + vaddr_t kpt_va; /* always valid kernel VA */ + paddr_t kpt_pa; /* PA of this page (for speed) */ }; struct kpt_page *kpt_free_list, *kpt_used_list; struct kpt_page *kpt_pages; @@ -257,21 +212,20 @@ struct kpt_page *kpt_pages; st_entry_t *Sysseg; pt_entry_t *Sysmap, *Sysptmap; st_entry_t *Segtabzero, *Segtabzeropa; -vm_size_t Sysptsize = VM_KERNEL_PT_PAGES; +vsize_t Sysptsize = VM_KERNEL_PT_PAGES; struct pmap kernel_pmap_store; vm_map_t st_map, pt_map; +#if defined(UVM) +struct vm_map st_map_store, pt_map_store; +#endif -vm_offset_t avail_start; /* PA of first available physical page */ -vm_offset_t avail_next; /* Next available physical page */ -int avail_remaining;/* Number of physical free pages left */ -int avail_range; /* Range avail_next is in */ -vm_offset_t avail_end; /* Set for ps and friends as */ - /* avail_start + avail_remaining. */ -vm_size_t mem_size; /* memory size in bytes */ -vm_offset_t virtual_avail; /* VA of first avail page (after kernel bss)*/ -vm_offset_t virtual_end; /* VA of last avail page (end of kernel AS) */ -int npages; +paddr_t avail_start; /* PA of first available physical page */ +paddr_t avail_end; /* PA of last available physical page */ +vsize_t mem_size; /* memory size in bytes */ +vaddr_t virtual_avail; /* VA of first avail page (after kernel bss)*/ +vaddr_t virtual_end; /* VA of last avail page (end of kernel AS) */ +int page_cnt; /* number of pages managed by VM system */ boolean_t pmap_initialized = FALSE; /* Has pmap_init completed? */ struct pv_entry *pv_table; @@ -279,25 +233,58 @@ char *pmap_attributes; /* reference and modify bits */ TAILQ_HEAD(pv_page_list, pv_page) pv_page_freelist; int pv_nfree; -/* The following three variables are defined in pmap_bootstrap.c */ -extern int numranges; -extern unsigned long low[8]; -extern unsigned long high[8]; +/* The following four variables are defined in pmap_bootstrap.c */ +extern int vidlen; +#define VIDMAPSIZE btoc(vidlen) #if defined(M68040) int protostfree; /* prototype (default) free ST map */ #endif +extern caddr_t CADDR1, CADDR2; + +pt_entry_t *caddr1_pte; /* PTE for CADDR1 */ +pt_entry_t *caddr2_pte; /* PTE for CADDR2 */ + +struct pool pmap_pmap_pool; /* memory pool for pmap structures */ + +struct pv_entry *pmap_alloc_pv __P((void)); +void pmap_free_pv __P((struct pv_entry *)); +void pmap_collect_pv __P((void)); + +#define PAGE_IS_MANAGED(pa) (pmap_initialized && \ + vm_physseg_find(atop((pa)), NULL) != -1) + +#define pa_to_pvh(pa) \ +({ \ + int bank_, pg_; \ + \ + bank_ = vm_physseg_find(atop((pa)), &pg_); \ + &vm_physmem[bank_].pmseg.pvent[pg_]; \ +}) + +#define pa_to_attribute(pa) \ +({ \ + int bank_, pg_; \ + \ + bank_ = vm_physseg_find(atop((pa)), &pg_); \ + &vm_physmem[bank_].pmseg.attrs[pg_]; \ +}) + /* * Internal routines */ -void pmap_remove_mapping __P((pmap_t, vm_offset_t, pt_entry_t *, int)); -boolean_t pmap_testbit __P((vm_offset_t, int)); -void pmap_changebit __P((vm_offset_t, int, boolean_t)); -void pmap_enter_ptpage __P((pmap_t, vm_offset_t)); +void pmap_remove_mapping __P((pmap_t, vaddr_t, pt_entry_t *, int)); +boolean_t pmap_testbit __P((paddr_t, int)); +void pmap_changebit __P((paddr_t, int, int)); +void pmap_enter_ptpage __P((pmap_t, vaddr_t)); +void pmap_collect1 __P((pmap_t, paddr_t, vaddr_t)); +void pmap_pinit __P((pmap_t)); +void pmap_release __P((pmap_t)); + #ifdef DEBUG -void pmap_pvdump __P((vm_offset_t)); -void pmap_check_wiring __P((char *, vm_offset_t)); +void pmap_pvdump __P((paddr_t)); +void pmap_check_wiring __P((char *, vaddr_t)); #endif /* pmap_remove_mapping flags */ @@ -305,112 +292,154 @@ void pmap_check_wiring __P((char *, vm_offset_t)); #define PRM_CFLUSH 2 /* - * Bootstrap memory allocator. This function allows for early dynamic - * memory allocation until the virtual memory system has been bootstrapped. - * After that point, either kmem_alloc or malloc should be used. This - * function works by stealing pages from the (to be) managed page pool, - * stealing virtual address space, then mapping the pages and zeroing them. - * - * It should be used from pmap_bootstrap till vm_page_startup, afterwards - * it cannot be used, and will generate a panic if tried. Note that this - * memory will never be freed, and in essence it is wired down. + * pmap_virtual_space: [ INTERFACE ] + * + * Report the range of available kernel virtual address + * space to the VM system during bootstrap. + * + * This is only an interface function if we do not use + * pmap_steal_memory()! + * + * Note: no locking is necessary in this function. */ -void * -pmap_bootstrap_alloc(size) - int size; +void +pmap_virtual_space(vstartp, vendp) + vaddr_t *vstartp, *vendp; { - extern boolean_t vm_page_startup_initialized; - vm_offset_t val; - - if (vm_page_startup_initialized) - panic("pmap_bootstrap_alloc: called after startup initialized"); - size = round_page(size); - val = virtual_avail; - - virtual_avail = pmap_map(virtual_avail, avail_start, - avail_start + size, VM_PROT_READ|VM_PROT_WRITE); - avail_start += size; - - avail_remaining -= m68k_btop (size); - /* XXX hope this doesn't pop it into the next range: */ - avail_next += size; - - bzero ((caddr_t) val, size); - return ((void *) val); + + *vstartp = virtual_avail; + *vendp = virtual_end; } /* - * Initialize the pmap module. - * Called by vm_init, to initialize any structures that the pmap - * system needs to map virtual memory. + * pmap_init: [ INTERFACE ] + * + * Initialize the pmap module. Called by vm_init(), to initialize any + * structures that the pmap system needs to map virtual memory. + * + * Note: no locking is necessary in this function. */ void pmap_init() { - vm_offset_t addr, addr2; - vm_size_t s; - int rv; + vaddr_t addr, addr2; + vsize_t s; + struct pv_entry *pv; + char *attr; + int rv; + int npages; + int bank; + + PMAP_DPRINTF(PDB_FOLLOW, ("pmap_init()\n")); + + /* + * Before we do anything else, initialize the PTE pointers + * used by pmap_zero_page() and pmap_copy_page(). + */ + caddr1_pte = pmap_pte(pmap_kernel(), CADDR1); + caddr2_pte = pmap_pte(pmap_kernel(), CADDR2); -#ifdef DEBUG - if (pmapdebug & PDB_FOLLOW) - printf("pmap_init()\n"); -#endif /* * Now that kernel map has been allocated, we can mark as - * unavailable regions which we have mapped in pmap_bootstrap. + * unavailable regions which we have mapped in pmap_bootstrap(). */ - addr = (vm_offset_t) IOBase; - (void) vm_map_find(kernel_map, NULL, (vm_offset_t) 0, &addr, - m68k_ptob(IIOMAPSIZE + ROMMAPSIZE + NBMAPSIZE), - FALSE); - if (addr != (vm_offset_t)IOBase) - panic("pmap_init: I/O space not mapped!"); - - addr = (vm_offset_t) Sysmap; +#if defined(UVM) + addr = (vaddr_t)IOBase; + if (uvm_map(kernel_map, &addr, + m68k_ptob(IIOMAPSIZE + ROMMAPSIZE + VIDMAPSIZE), + NULL, UVM_UNKNOWN_OFFSET, + UVM_MAPFLAG(UVM_PROT_NONE, UVM_PROT_NONE, + UVM_INH_NONE, UVM_ADV_RANDOM, + UVM_FLAG_FIXED)) != KERN_SUCCESS) + goto bogons; + addr = (vaddr_t)Sysmap; + if (uvm_map(kernel_map, &addr, MAC_MAX_PTSIZE, + NULL, UVM_UNKNOWN_OFFSET, + UVM_MAPFLAG(UVM_PROT_NONE, UVM_PROT_NONE, + UVM_INH_NONE, UVM_ADV_RANDOM, + UVM_FLAG_FIXED)) != KERN_SUCCESS) { + /* + * If this fails, it is probably because the static + * portion of the kernel page table isn't big enough + * and we overran the page table map. + */ + bogons: + panic("pmap_init: bogons in the VM system!\n"); + } +#else + addr = (vaddr_t)IOBase; + (void)vm_map_find(kernel_map, NULL, (vaddr_t)0, &addr, + m68k_ptob(IIOMAPSIZE + ROMMAPSIZE + VIDMAPSIZE), FALSE); + if (addr != (vaddr_t)IOBase) + goto bogons; + + addr = (vaddr_t)Sysmap; vm_object_reference(kernel_object); - (void) vm_map_find(kernel_map, kernel_object, addr, + (void)vm_map_find(kernel_map, kernel_object, addr, &addr, MAC_MAX_PTSIZE, FALSE); /* * If this fails it is probably because the static portion of * the kernel page table isn't big enough and we overran the * page table map. Need to adjust pmap_size() in mac68k_init.c. */ - if (addr != (vm_offset_t)Sysmap) + if (addr != (vaddr_t)Sysmap) + bogons: panic("pmap_init: bogons in the VM system!"); +#endif /* UVM */ -#ifdef DEBUG - if (pmapdebug & PDB_INIT) { - printf("pmap_init: Sysseg %p, Sysmap %p, Sysptmap %p\n", - Sysseg, Sysmap, Sysptmap); - printf(" pstart %lx, plast %x, vstart %lx, vend %lx\n", - avail_start, avail_remaining, virtual_avail, virtual_end); - } -#endif + PMAP_DPRINTF(PDB_INIT, + ("pmap_init: Sysseg %p, Sysmap %p, Sysptmap %p\n", + Sysseg, Sysmap, Sysptmap)); + PMAP_DPRINTF(PDB_INIT, + (" pstart %lx, pend %lx, vstart %lx, vend %lx\n", + avail_start, avail_end, virtual_avail, virtual_end)); /* * Allocate memory for random pmap data structures. Includes the * initial segment table, pv_head_table and pmap_attributes. */ - /* - * This is wasteful on MACHINE_NONCONTIG. Is it avoidable? - */ - npages = atop(high[numranges - 1] - 1); - s = (vm_size_t) (MAC_STSIZE + sizeof(struct pv_entry)*npages + npages); + for (page_cnt = 0, bank = 0; bank < vm_nphysseg; bank++) + page_cnt += vm_physmem[bank].end - vm_physmem[bank].start; + s = MAC_STSIZE; /* Segtabzero */ + s += page_cnt * sizeof(struct pv_entry); /* pv table */ + s += page_cnt * sizeof(char); /* attribute table */ s = round_page(s); - addr = (vm_offset_t) kmem_alloc(kernel_map, s); - Segtabzero = (st_entry_t *) addr; - Segtabzeropa = (st_entry_t *) pmap_extract(pmap_kernel(), addr); - addr += MAC_STSIZE; - pv_table = (struct pv_entry *) addr; - addr += sizeof(struct pv_entry) * npages; - pmap_attributes = (char *) addr; -#ifdef DEBUG - if (pmapdebug & PDB_INIT) - printf("pmap_init: %lx bytes: npages %x s0 %p(%p) tbl %p atr %p\n", - s, npages, Segtabzero, Segtabzeropa, - pv_table, pmap_attributes); +#if defined(UVM) + addr = uvm_km_zalloc(kernel_map, s); + if (addr == 0) + panic("pmap_init: can't allocate data structures"); +#else + addr = kmem_alloc(kernel_map, s); #endif + Segtabzero = (st_entry_t *)addr; + Segtabzeropa = (st_entry_t *)pmap_extract(pmap_kernel(), addr); + addr += MAC_STSIZE; + + pv_table = (struct pv_entry *)addr; + addr += page_cnt * sizeof(struct pv_entry); + + pmap_attributes = (char *)addr; + + PMAP_DPRINTF(PDB_INIT, ("pmap_init: %lx bytes: page_cnt %x s0 %p(%p) " + "tbl %p atr %p\n", + s, page_cnt, Segtabzero, Segtabzeropa, + pv_table, pmap_attributes)); + + /* + * Now that the pv and attribute tables have been allocated, + * assign them to the memory segments. + */ + pv = pv_table; + attr = pmap_attributes; + for (bank = 0; bank < vm_nphysseg; bank++) { + npages = vm_physmem[bank].end - vm_physmem[bank].start; + vm_physmem[bank].pmseg.pvent = pv; + vm_physmem[bank].pmseg.attrs = attr; + pv += npages; + attr += npages; + } + /* * Allocate physical memory for kernel PT pages and their management. * We need 1 PT page per possible task plus some slop. @@ -422,21 +451,39 @@ pmap_init() * Verify that space will be allocated in region for which * we already have kernel PT pages. */ +#if defined(UVM) + addr = 0; + rv = uvm_map(kernel_map, &addr, s, NULL, UVM_UNKNOWN_OFFSET, + UVM_MAPFLAG(UVM_PROT_NONE, UVM_PROT_NONE, UVM_INH_NONE, + UVM_ADV_RANDOM, UVM_FLAG_NOMERGE)); + if (rv != KERN_SUCCESS || (addr + s) >= (vaddr_t)Sysmap) + panic("pmap_init: kernel PT too small"); + rv = uvm_unmap(kernel_map, addr, addr + s); + if (rv != KERN_SUCCESS) + panic("pmap_init: uvm_unmap failed"); +#else addr = 0; rv = vm_map_find(kernel_map, NULL, 0, &addr, s, TRUE); - if (rv != KERN_SUCCESS || addr + s >= (vm_offset_t)Sysmap) + if (rv != KERN_SUCCESS || addr + s >= (vaddr_t)Sysmap) panic("pmap_init: kernel PT too small"); vm_map_remove(kernel_map, addr, addr + s); +#endif /* * Now allocate the space and link the pages together to * form the KPT free list. */ - addr = (vm_offset_t) kmem_alloc(kernel_map, s); +#if defined(UVM) + addr = uvm_km_zalloc(kernel_map, s); + if (addr == 0) + panic("pmap_init: cannot allocate KPT free list"); +#else + addr = kmem_alloc(kernel_map, s); +#endif s = ptoa(npages); addr2 = addr + s; kpt_pages = &((struct kpt_page *)addr2)[npages]; - kpt_free_list = (struct kpt_page *) 0; + kpt_free_list = (struct kpt_page *)0; do { addr2 -= NBPG; (--kpt_pages)->kpt_next = kpt_free_list; @@ -444,15 +491,33 @@ pmap_init() kpt_pages->kpt_va = addr2; kpt_pages->kpt_pa = pmap_extract(pmap_kernel(), addr2); } while (addr != addr2); -#ifdef PMAPSTATS - kpt_stats.kpttotal = atop(s); -#endif -#ifdef DEBUG - if (pmapdebug & PDB_INIT) - printf("pmap_init: KPT: %ld pages from %lx to %lx\n", - atop(s), addr, addr + s); -#endif + PMAP_DPRINTF(PDB_INIT, ("pmap_init: KPT: %ld pages from %lx to %lx\n", + atop(s), addr, addr + s)); + +#if defined(UVM) + /* + * Allocate the segment table map and the page table map. + */ + s = maxproc * MAC_STSIZE; + st_map = uvm_km_suballoc(kernel_map, &addr, &addr2, s, TRUE, + FALSE, &st_map_store); + + addr = MAC_PTBASE; + if ((MAC_PTMAXSIZE / MAC_MAX_PTSIZE) < maxproc) { + s = MAC_PTMAXSIZE; + /* + * XXX We don't want to hang when we run out of + * page tables, so we lower maxproc so that fork() + * will fail instead. Note that root could still raise + * this value via sysctl(2). + */ + maxproc = (MAC_PTMAXSIZE / MAC_MAX_PTSIZE); + } else + s = (maxproc * MAC_MAX_PTSIZE); + pt_map = uvm_km_suballoc(kernel_map, &addr, &addr2, s, TRUE, + TRUE, &pt_map_store); +#else /* * Allocate the segment table map */ @@ -464,8 +529,17 @@ pmap_init() * map where we want it. */ addr = MAC_PTBASE; - s = (MAC_PTMAXSIZE / MAC_MAX_PTSIZE < maxproc) ? - MAC_PTMAXSIZE : (maxproc * MAC_MAX_PTSIZE); + if ((MAC_PTMAXSIZE / MAC_MAX_PTSIZE) < maxproc) { + s = MAC_PTMAXSIZE; + /* + * XXX We don't want to hang when we run out of + * page tables, so we lower maxproc so that fork() + * will fail instead. Note that root could still raise + * this value via sysctl(2). + */ + maxproc = (MAC_PTMAXSIZE / MAC_MAX_PTSIZE); + } else + s = (maxproc * MAC_MAX_PTSIZE); addr2 = addr + s; rv = vm_map_find(kernel_map, NULL, 0, &addr, s, TRUE); if (rv != KERN_SUCCESS) @@ -481,6 +555,7 @@ pmap_init() if (pmapdebug & PDB_INIT) printf("pmap_init: pt_map [%lx - %lx)\n", addr, addr2); #endif +#endif /* UVM */ #if defined(M68040) if (mmutype == MMU_68040) { @@ -491,25 +566,39 @@ pmap_init() #endif /* + * Initialize the pmap pools. + */ + pool_init(&pmap_pmap_pool, sizeof(struct pmap), 0, 0, 0, "pmappl", + 0, pool_page_alloc_nointr, pool_page_free_nointr, M_VMPMAP); + + /* * Now it is safe to enable pv_table recording. */ pmap_initialized = TRUE; } -static struct pv_entry *pmap_alloc_pv __P((void)); -static void pmap_free_pv __P((struct pv_entry *)); - -static struct pv_entry * +/* + * pmap_alloc_pv: + * + * Allocate a pv_entry. + */ +struct pv_entry * pmap_alloc_pv() { - struct pv_page *pvp; - struct pv_entry *pv; - int i; + struct pv_page *pvp; + struct pv_entry *pv; + int i; if (pv_nfree == 0) { +#if defined(UVM) + pvp = (struct pv_page *)uvm_km_zalloc(kernel_map, NBPG); + if (pvp == 0) + panic("pmap_alloc_pv: uvm_km_zalloc() failed"); +#else pvp = (struct pv_page *)kmem_alloc(kernel_map, NBPG); if (pvp == 0) panic("pmap_alloc_pv: kmem_alloc() failed"); +#endif pvp->pvp_pgi.pgi_freelist = pv = &pvp->pvp_pv[1]; for (i = NPVPPG - 2; i; i--, pv++) pv->pv_next = pv + 1; @@ -533,11 +622,16 @@ pmap_alloc_pv() return pv; } -static void +/* + * pmap_free_pv: + * + * Free a pv_entry. + */ +void pmap_free_pv(pv) struct pv_entry *pv; { - register struct pv_page *pvp; + struct pv_page *pvp; pvp = (struct pv_page *) trunc_page((vaddr_t)pv); switch (++pvp->pvp_pgi.pgi_nfree) { @@ -551,13 +645,20 @@ pmap_free_pv(pv) case NPVPPG: pv_nfree -= NPVPPG - 1; TAILQ_REMOVE(&pv_page_freelist, pvp, pvp_pgi.pgi_list); - kmem_free(kernel_map, (vm_offset_t) pvp, NBPG); +#if defined(UVM) + uvm_km_free(kernel_map, (vaddr_t)pvp, NBPG); +#else + kmem_free(kernel_map, (vaddr_t)pvp, NBPG); +#endif break; } } -void pmap_collect_pv __P((void)); - +/* + * pmap_collect_pv: + * + * Perform compaction on the PV list, called via pmap_collect(). + */ void pmap_collect_pv() { @@ -574,8 +675,9 @@ pmap_collect_pv() npvp = pvp->pvp_pgi.pgi_list.tqe_next; if (pvp->pvp_pgi.pgi_nfree > NPVPPG / 3) { TAILQ_REMOVE(&pv_page_freelist, pvp, pvp_pgi.pgi_list); - TAILQ_INSERT_TAIL(&pv_page_collectlist, pvp, pvp_pgi.pgi_list); - pv_nfree -= pvp->pvp_pgi.pgi_nfree; + TAILQ_INSERT_TAIL(&pv_page_collectlist, pvp, + pvp_pgi.pgi_list); + pv_nfree -= NPVPPG; pvp->pvp_pgi.pgi_nfree = -1; } } @@ -583,7 +685,7 @@ pmap_collect_pv() if (pv_page_collectlist.tqh_first == 0) return; - for (ph = &pv_table[npages - 1]; ph >= &pv_table[0]; ph--) { + for (ph = &pv_table[page_cnt - 1]; ph >= &pv_table[0]; ph--) { if (ph->pv_pmap == 0) continue; s = splimp(); @@ -592,7 +694,8 @@ pmap_collect_pv() if (pvp->pvp_pgi.pgi_nfree == -1) { pvp = pv_page_freelist.tqh_first; if (--pvp->pvp_pgi.pgi_nfree == 0) { - TAILQ_REMOVE(&pv_page_freelist, pvp, pvp_pgi.pgi_list); + TAILQ_REMOVE(&pv_page_freelist, pvp, + pvp_pgi.pgi_list); } npv = pvp->pvp_pgi.pgi_freelist; #ifdef DIAGNOSTIC @@ -611,89 +714,86 @@ pmap_collect_pv() for (pvp = pv_page_collectlist.tqh_first; pvp; pvp = npvp) { npvp = pvp->pvp_pgi.pgi_list.tqe_next; - kmem_free(kernel_map, (vm_offset_t)pvp, NBPG); +#if defined(UVM) + uvm_km_free(kernel_map, (vaddr_t)pvp, NBPG); +#else + kmem_free(kernel_map, (vaddr_t)pvp, NBPG); +#endif } } /* + * pmap_map: + * * Used to map a range of physical addresses into kernel * virtual address space. * * For now, VM is already on, we only need to map the * specified memory. + * + * Note: THIS FUNCTION IS DEPRECATED, AND SHOULD BE REMOVED! */ -vm_offset_t +vaddr_t pmap_map(va, spa, epa, prot) - vm_offset_t va, spa, epa; - int prot; + vaddr_t va; + paddr_t spa, epa; + int prot; { -#ifdef DEBUG - if (pmapdebug & PDB_FOLLOW) - printf("pmap_map(%lx, %lx, %lx, %x)\n", va, spa, epa, prot); -#endif + PMAP_DPRINTF(PDB_FOLLOW, + ("pmap_map(%lx, %lx, %lx, %x)\n", va, spa, epa, prot)); while (spa < epa) { pmap_enter(pmap_kernel(), va, spa, prot, FALSE, 0); va += NBPG; spa += NBPG; } - return(va); + return (va); } /* - * Create and return a physical map. + * pmap_create: [ INTERFACE ] * - * If the size specified for the map - * is zero, the map is an actual physical - * map, and may be referenced by the - * hardware. + * Create and return a physical map. * - * If the size specified is non-zero, - * the map will be used in software only, and - * is bounded by that size. + * Note: no locking is necessary in this function. */ pmap_t pmap_create(size) - vm_size_t size; + vsize_t size; { - register pmap_t pmap; + pmap_t pmap; -#ifdef DEBUG - if (pmapdebug & (PDB_FOLLOW|PDB_CREATE)) - printf("pmap_create(%lx)\n", size); -#endif + PMAP_DPRINTF(PDB_FOLLOW|PDB_CREATE, + ("pmap_create(%lx)\n", size)); /* * Software use map does not need a pmap */ if (size) - return(NULL); + return (NULL); + + pmap = pool_get(&pmap_pmap_pool, PR_WAITOK); - /* XXX: is it ok to wait here? */ - pmap = (pmap_t) malloc(sizeof *pmap, M_VMPMAP, M_WAITOK); -#ifdef notifwewait - if (pmap == NULL) - panic("pmap_create: cannot allocate a pmap"); -#endif bzero(pmap, sizeof(*pmap)); pmap_pinit(pmap); return (pmap); } /* - * Initialize a preallocated and zeroed pmap structure, - * such as one in a vmspace structure. + * pmap_pinit: + * + * Initialize a preallocated and zeroed pmap structure. + * + * Note: THIS FUNCTION SHOULD BE MOVED INTO pmap_create()! */ void pmap_pinit(pmap) - register struct pmap *pmap; + struct pmap *pmap; { -#ifdef DEBUG - if (pmapdebug & (PDB_FOLLOW|PDB_CREATE)) - printf("pmap_pinit(%p)\n", pmap); -#endif + PMAP_DPRINTF(PDB_FOLLOW|PDB_CREATE, + ("pmap_pinit(%p)\n", pmap)); /* * No need to allocate page table space yet but we do need a @@ -707,53 +807,49 @@ pmap_pinit(pmap) if (mmutype == MMU_68040) pmap->pm_stfree = protostfree; #endif - pmap->pm_stchanged = TRUE; pmap->pm_count = 1; simple_lock_init(&pmap->pm_lock); } /* - * Retire the given physical map from service. - * Should only be called if the map contains - * no valid mappings. + * pmap_destroy: [ INTERFACE ] + * + * Drop the reference count on the specified pmap, releasing + * all resources if the reference count drops to zero. */ void pmap_destroy(pmap) - register pmap_t pmap; + pmap_t pmap; { int count; if (pmap == NULL) return; -#ifdef DEBUG - if (pmapdebug & PDB_FOLLOW) - printf("pmap_destroy(%p)\n", pmap); -#endif + PMAP_DPRINTF(PDB_FOLLOW, ("pmap_destroy(%p)\n", pmap)); simple_lock(&pmap->pm_lock); count = --pmap->pm_count; simple_unlock(&pmap->pm_lock); if (count == 0) { pmap_release(pmap); - free((caddr_t)pmap, M_VMPMAP); + pool_put(&pmap_pmap_pool, pmap); } } /* - * Release any resources held by the given physical map. - * Called when a pmap initialized by pmap_pinit is being released. - * Should only be called if the map contains no valid mappings. + * pmap_release: + * + * Relese the resources held by a pmap. + * + * Note: THIS FUNCTION SHOULD BE MOVED INTO pmap_destroy(). */ void pmap_release(pmap) - register struct pmap *pmap; + struct pmap *pmap; { -#ifdef DEBUG - if (pmapdebug & PDB_FOLLOW) - printf("pmap_release(%p)\n", pmap); -#endif + PMAP_DPRINTF(PDB_FOLLOW, ("pmap_release(%p)\n", pmap)); #ifdef notdef /* DIAGNOSTIC */ /* count would be 0 from pmap_destroy... */ @@ -763,14 +859,26 @@ pmap_release(pmap) #endif if (pmap->pm_ptab) - kmem_free_wakeup(pt_map, (vm_offset_t)pmap->pm_ptab, - MAC_MAX_PTSIZE); +#if defined(UVM) + uvm_km_free_wakeup(pt_map, (vaddr_t)pmap->pm_ptab, + MAC_MAX_PTSIZE); +#else + kmem_free_wakeup(pt_map, (vaddr_t)pmap->pm_ptab, + MAC_MAX_PTSIZE); +#endif if (pmap->pm_stab != Segtabzero) - kmem_free_wakeup(st_map, (vm_offset_t)pmap->pm_stab, - MAC_STSIZE); +#if defined(UVM) + uvm_km_free_wakeup(st_map, (vaddr_t)pmap->pm_stab, + MAC_STSIZE); +#else + kmem_free_wakeup(st_map, (vaddr_t)pmap->pm_stab, + MAC_STSIZE); +#endif } /* + * pmap_reference: [ INTERFACE ] + * * Add a reference to the specified pmap. */ void @@ -781,46 +889,55 @@ pmap_reference(pmap) if (pmap == NULL) return; -#ifdef DEBUG - if (pmapdebug & PDB_FOLLOW) - printf("pmap_reference(%p)\n", pmap); -#endif + PMAP_DPRINTF(PDB_FOLLOW, ("pmap_reference(%p)\n", pmap)); simple_lock(&pmap->pm_lock); pmap->pm_count++; simple_unlock(&pmap->pm_lock); } -void loadustp __P((vm_offset_t)); -void pmap_activate __P((register pmap_t, struct pcb *)); - + /* + * pmap_activate: [ INTERFACE ] + * + * Activate the pmap used by the specified process. This includes + * reloading the MMU context if the current process, and marking + * the pmap in use by the processor. + * + * Note: we may only use spin locks here, since we are called + * by a critical section in cpu_switch()! + */ void -pmap_activate(pmap, pcbp) - register pmap_t pmap; - struct pcb *pcbp; +pmap_activate(p) + struct proc *p; { + pmap_t pmap = p->p_vmspace->vm_map.pmap; - if (pmap == NULL) - return; - -#ifdef DEBUG - if (pmapdebug & (PDB_FOLLOW|PDB_SEGTAB)) - printf("pmap_activate(%p, %p)\n", pmap, pcbp); -#endif + PMAP_DPRINTF(PDB_FOLLOW|PDB_SEGTAB, + ("pmap_activate(%p)\n", p)); - PMAP_ACTIVATE(pmap, pcbp, pmap == curproc->p_vmspace->vm_map.pmap); + PMAP_ACTIVATE(pmap, p == curproc); } -void pmap_deactivate __P((register pmap_t, struct pcb *)); - +/* + * pmap_deactivate: [ INTERFACE ] + * + * Mark that the pmap used by the specified process is no longer + * in use by the processor. + * + * The comment above pmap_activate() wrt. locking applies here, + * as well. + */ void -pmap_deactivate(pmap, pcb) - register pmap_t pmap; - struct pcb *pcb; +pmap_deactivate(p) + struct proc *p; { + + /* No action necessary in this pmap implementation. */ } /* + * pmap_remove: [ INTERFACE ] + * * Remove the given range of addresses from the specified map. * * It is assumed that the start and end are properly @@ -828,25 +945,20 @@ pmap_deactivate(pmap, pcb) */ void pmap_remove(pmap, sva, eva) - register pmap_t pmap; - vm_offset_t sva, eva; + pmap_t pmap; + vaddr_t sva, eva; { - register vm_offset_t nssva; - register pt_entry_t *pte; + vaddr_t nssva; + pt_entry_t *pte; boolean_t firstpage, needcflush; int flags; -#ifdef DEBUG - if (pmapdebug & (PDB_FOLLOW|PDB_REMOVE|PDB_PROTECT)) - printf("pmap_remove(%p, %lx, %lx)\n", pmap, sva, eva); -#endif + PMAP_DPRINTF(PDB_FOLLOW|PDB_REMOVE|PDB_PROTECT, + ("pmap_remove(%p, %lx, %lx)\n", pmap, sva, eva)); if (pmap == NULL) return; -#ifdef PMAPSTATS - remove_stats.calls++; -#endif firstpage = TRUE; needcflush = FALSE; flags = active_pmap(pmap) ? PRM_TFLUSH : 0; @@ -883,16 +995,17 @@ pmap_remove(pmap, sva, eva) } /* - * pmap_page_protect: + * pmap_page_protect: [ INTERFACE ] * - * Lower the permission for all mappings to a given page. + * Lower the permission for all mappings to a given page to + * the permissions specified. */ void pmap_page_protect(pa, prot) - vm_offset_t pa; + paddr_t pa; vm_prot_t prot; { - register struct pv_entry *pv; + struct pv_entry *pv; int s; #ifdef DEBUG @@ -900,7 +1013,7 @@ pmap_page_protect(pa, prot) (prot == VM_PROT_NONE && (pmapdebug & PDB_REMOVE))) printf("pmap_page_protect(%lx, %x)\n", pa, prot); #endif - if (!pmap_valid_page (pa)) + if (PAGE_IS_MANAGED(pa) == 0) return; switch (prot) { @@ -910,7 +1023,7 @@ pmap_page_protect(pa, prot) /* copy_on_write */ case VM_PROT_READ: case VM_PROT_READ|VM_PROT_EXECUTE: - pmap_changebit(pa, PG_RO, TRUE); + pmap_changebit(pa, PG_RO, ~0); return; /* remove_all */ default: @@ -919,7 +1032,7 @@ pmap_page_protect(pa, prot) pv = pa_to_pvh(pa); s = splimp(); while (pv->pv_pmap != NULL) { - register pt_entry_t *pte; + pt_entry_t *pte; pte = pmap_pte(pv->pv_pmap, pv->pv_va); #ifdef DEBUG @@ -935,39 +1048,39 @@ pmap_page_protect(pa, prot) #ifdef DEBUG if (pmapdebug & PDB_PARANOIA) printf("%s wired mapping for %lx not removed\n", - "pmap_page_protect:", pa); + "pmap_page_protect:", pa); #endif + if (pv == NULL) + break; } } splx(s); } /* - * Set the physical protection on the - * specified range of this map as requested. + * pmap_protect: [ INTERFACE ] + * + * Set the physical protectoin on the specified range of this map + * as requested. */ void pmap_protect(pmap, sva, eva, prot) - register pmap_t pmap; - register vm_offset_t sva, eva; - vm_prot_t prot; + pmap_t pmap; + vaddr_t sva, eva; + vm_prot_t prot; { - register vm_offset_t nssva; - register pt_entry_t *pte; + vaddr_t nssva; + pt_entry_t *pte; boolean_t firstpage, needtflush; int isro; -#ifdef DEBUG - if (pmapdebug & (PDB_FOLLOW|PDB_PROTECT)) - printf("pmap_protect(%p, %lx, %lx, %x)\n", pmap, sva, eva, prot); -#endif + PMAP_DPRINTF(PDB_FOLLOW|PDB_PROTECT, + ("pmap_protect(%p, %lx, %lx, %x)\n", + pmap, sva, eva, prot)); if (pmap == NULL) return; -#ifdef PMAPSTATS - protect_stats.calls++; -#endif if ((prot & VM_PROT_READ) == VM_PROT_NONE) { pmap_remove(pmap, sva, eva); return; @@ -1003,7 +1116,7 @@ pmap_protect(pmap, sva, eva, prot) * "7.3 Cache Coherency" in the manual). */ if (isro && mmutype == MMU_68040) { - vm_offset_t pa = pmap_pte_pa(pte); + paddr_t pa = pmap_pte_pa(pte); DCFP(pa); ICPP(pa); @@ -1012,19 +1125,8 @@ pmap_protect(pmap, sva, eva, prot) pmap_pte_set_prot(pte, isro); if (needtflush) TBIS(sva); -#ifdef PMAPSTATS - protect_stats.changed++; -#endif firstpage = FALSE; } -#ifdef PMAPSTATS - else if (pmap_pte_v(pte)) { - if (isro) - protect_stats.alreadyro++; - else - protect_stats.alreadyrw++; - } -#endif pte++; sva += NBPG; } @@ -1047,53 +1149,61 @@ extern vm_offset_t tmp_vpages[]; } /* - * Insert the given physical page (p) at - * the specified virtual address (v) in the + * pmap_enter: [ INTERFACE ] + * + * Insert the given physical page (pa) at + * the specified virtual address (va) in the * target physical map with the protection requested. * * If specified, the page will be wired down, meaning - * that the related pte can not be reclaimed. + * that the related pte cannot be reclaimed. * - * NB: This is the only routine which MAY NOT lazy-evaluate - * or lose information. That is, this routine must actually + * Note: This is the only routine which MAY NOT lazy-evaluate + * or lose information. Thatis, this routine must actually * insert this page into the given map NOW. */ void pmap_enter(pmap, va, pa, prot, wired, access_type) - register pmap_t pmap; - vm_offset_t va; - register vm_offset_t pa; + pmap_t pmap; + vaddr_t va; + paddr_t pa; vm_prot_t prot; boolean_t wired; vm_prot_t access_type; { - register pt_entry_t *pte; - register int npte; - vm_offset_t opa; + pt_entry_t *pte; + int npte; + paddr_t opa; boolean_t cacheable = TRUE; boolean_t checkpv = TRUE; -#ifdef DEBUG - if (pmapdebug & (PDB_FOLLOW|PDB_ENTER)) - printf("pmap_enter(%p, %lx, %lx, %x, %x)\n", - pmap, va, pa, prot, wired); -#endif + PMAP_DPRINTF(PDB_FOLLOW|PDB_ENTER, + ("pmap_enter(%p, %lx, %lx, %x, %x)\n", + pmap, va, pa, prot, wired)); + if (pmap == NULL) return; -#ifdef PMAPSTATS - if (pmap == pmap_kernel()) - enter_stats.kernel++; - else - enter_stats.user++; +#ifdef DIAGNOSTIC + /* + * pmap_enter() should never be used for CADDR1 and CADDR2. + */ + if (pmap == pmap_kernel() && + (va == (vaddr_t)CADDR1 || va == (vaddr_t)CADDR2)) + panic("pmap_enter: used for CADDR1 or CADDR2"); #endif + /* * For user mapping, allocate kernel VM resources if necessary. */ - if (pmap->pm_ptab == NULL) { + if (pmap->pm_ptab == NULL) +#if defined(UVM) pmap->pm_ptab = (pt_entry_t *) - kmem_alloc_wait(pt_map, MAC_MAX_PTSIZE); - } + uvm_km_valloc_wait(pt_map, MAC_MAX_PTSIZE); +#else + pmap->pm_ptab = (pt_entry_t *) + kmem_alloc_wait(pt_map, MAC_MAX_PTSIZE); +#endif /* * Segment table entry not valid, we need a new PT page @@ -1104,18 +1214,13 @@ pmap_enter(pmap, va, pa, prot, wired, access_type) pa = m68k_trunc_page(pa); pte = pmap_pte(pmap, va); opa = pmap_pte_pa(pte); -#ifdef DEBUG - if (pmapdebug & PDB_ENTER) - printf("enter: pte %p, *pte %x\n", pte, *pte); -#endif + + PMAP_DPRINTF(PDB_ENTER, ("enter: pte %p, *pte %x\n", pte, *pte)); /* * Mapping has not changed, must be protection or wiring change. */ if (opa == pa) { -#ifdef PMAPSTATS - enter_stats.pwchange++; -#endif /* * Wiring change, just update stats. * We don't worry about wiring PT pages as they remain @@ -1123,25 +1228,13 @@ pmap_enter(pmap, va, pa, prot, wired, access_type) * Hence, if a user page is wired, the PT page will be also. */ if (pmap_pte_w_chg(pte, wired ? PG_W : 0)) { -#ifdef DEBUG - if (pmapdebug & PDB_ENTER) - printf("enter: wiring change -> %x\n", wired); -#endif + PMAP_DPRINTF(PDB_ENTER, + ("enter: wiring change -> %x\n", wired)); if (wired) pmap->pm_stats.wired_count++; else pmap->pm_stats.wired_count--; -#ifdef PMAPSTATS - if (pmap_pte_prot(pte) == pte_prot(pmap, prot)) - enter_stats.wchange++; -#endif } -#ifdef PMAPSTATS - else if (pmap_pte_prot(pte) != pte_prot(pmap, prot)) - enter_stats.pchange++; - else - enter_stats.nochange++; -#endif /* * Retain cache inhibition status */ @@ -1156,14 +1249,9 @@ pmap_enter(pmap, va, pa, prot, wired, access_type) * handle validating new mapping. */ if (opa) { -#ifdef DEBUG - if (pmapdebug & PDB_ENTER) - printf("enter: removing old mapping %lx\n", va); -#endif + PMAP_DPRINTF(PDB_ENTER, + ("enter: removing old mapping %lx\n", va)); pmap_remove_mapping(pmap, va, pte, PRM_TFLUSH|PRM_CFLUSH); -#ifdef PMAPSTATS - enter_stats.mchange++; -#endif } /* @@ -1172,35 +1260,32 @@ pmap_enter(pmap, va, pa, prot, wired, access_type) * is a valid mapping in the page. */ if (pmap != pmap_kernel()) - (void) vm_map_pageable(pt_map, trunc_page((vaddr_t)pte), - round_page((vaddr_t)(pte+1)), FALSE); +#if defined(UVM) + (void)uvm_map_pageable(pt_map, trunc_page((vaddr_t)pte), + round_page((vaddr_t)(pte+1)), FALSE); +#else + (void)vm_map_pageable(pt_map, trunc_page((vaddr_t)pte), + round_page((vaddr_t)(pte+1)), FALSE); +#endif /* * Enter on the PV list if part of our managed memory * Note that we raise IPL while manipulating pv_table * since pmap_enter can be called at interrupt time. */ - if (pmap_valid_page (pa)) { - register struct pv_entry *pv, *npv; + if (PAGE_IS_MANAGED(pa)) { + struct pv_entry *pv, *npv; int s; -#ifdef PMAPSTATS - enter_stats.managed++; -#endif pv = pa_to_pvh(pa); s = splimp(); -#ifdef DEBUG - if (pmapdebug & PDB_ENTER) - printf("enter: pv at %p: %lx/%p/%p\n", - pv, pv->pv_va, pv->pv_pmap, pv->pv_next); -#endif + PMAP_DPRINTF(PDB_ENTER, + ("enter: pv at %p: %lx/%p/%p\n", + pv, pv->pv_va, pv->pv_pmap, pv->pv_next)); /* * No entries yet, use header as the first entry */ if (pv->pv_pmap == NULL) { -#ifdef PMAPSTATS - enter_stats.firstpv++; -#endif pv->pv_va = va; pv->pv_pmap = pmap; pv->pv_next = NULL; @@ -1226,11 +1311,20 @@ pmap_enter(pmap, va, pa, prot, wired, access_type) npv->pv_ptpmap = NULL; npv->pv_flags = 0; pv->pv_next = npv; -#ifdef PMAPSTATS - if (!npv->pv_next) - enter_stats.secondpv++; -#endif } + + /* + * Speed pmap_is_referenced() or pmap_is_modified() based + * on the hint provided in access_type. + */ +#ifdef DIAGNOSTIC + if (access_type & ~prot) + panic("pmap_enter: access_type exceeds prot"); +#endif + if (access_type & VM_PROT_WRITE) + *pa_to_attribute(pa) |= (PG_U|PG_M); + else if (access_type & VM_PROT_ALL) + *pa_to_attribute(pa) |= PG_U; splx(s); } /* @@ -1239,9 +1333,6 @@ pmap_enter(pmap, va, pa, prot, wired, access_type) */ else if (pmap_initialized) { checkpv = cacheable = FALSE; -#ifdef PMAPSTATS - enter_stats.unmanaged++; -#endif } /* @@ -1274,10 +1365,9 @@ validate: #endif npte |= PG_CCB; #endif -#ifdef DEBUG - if (pmapdebug & PDB_ENTER) - printf("enter: new pte value %x\n", npte); -#endif + + PMAP_DPRINTF(PDB_ENTER, ("enter: new pte value %x\n", npte)); + /* * Remember if this was a wiring-only change. * If so, we need not flush the TLB and caches. @@ -1299,24 +1389,23 @@ validate: } /* - * Routine: pmap_change_wiring - * Function: Change the wiring attribute for a map/virtual-address - * pair. - * In/out conditions: - * The mapping must already exist in the pmap. + * pmap_change_wiring: [ INTERFACE ] + * + * Change the wiring attribute for a map/virtual-address pair. + * + * The mapping must already exist in the pmap. */ void pmap_change_wiring(pmap, va, wired) - register pmap_t pmap; - vm_offset_t va; + pmap_t pmap; + vaddr_t va; boolean_t wired; { - register pt_entry_t *pte; + pt_entry_t *pte; + + PMAP_DPRINTF(PDB_FOLLOW, + ("pmap_change_wiring(%p, %lx, %x)\n", pmap, va, wired)); -#ifdef DEBUG - if (pmapdebug & PDB_FOLLOW) - printf("pmap_change_wiring(%p, %lx, %x)\n", pmap, va, wired); -#endif if (pmap == NULL) return; @@ -1342,9 +1431,9 @@ pmap_change_wiring(pmap, va, wired) } #endif /* - * If wiring actually changes (always?) set the wire bit and + * If wiring actually changed (always?) set the wire bit and * update the wire count. Note that wiring is not a hardware - * characteristic, so there is no need to invalidate the TLB. + * characteristic so there is no need to invalidate the TLB. */ if (pmap_pte_w_chg(pte, wired ? PG_W : 0)) { pmap_pte_set_w(pte, wired); @@ -1356,169 +1445,350 @@ pmap_change_wiring(pmap, va, wired) } /* - * Routine: pmap_extract - * Function: - * Extract the physical page address associated - * with the given map/virtual_address pair. + * pmap_extract: [ INTERFACE ] + * + * Extract the physical address associated with the given + * pmap/virtual address pair. */ - -vm_offset_t +paddr_t pmap_extract(pmap, va) - register pmap_t pmap; - vm_offset_t va; + pmap_t pmap; + vaddr_t va; { - register vm_offset_t pa; + paddr_t pa; + + PMAP_DPRINTF(PDB_FOLLOW, + ("pmap_extract(%p, %lx) -> ", pmap, va)); -#ifdef DEBUG - if (pmapdebug & PDB_FOLLOW) - printf("pmap_extract(%p, %lx) -> ", pmap, va); -#endif pa = 0; if (pmap && pmap_ste_v(pmap, va)) pa = *pmap_pte(pmap, va); if (pa) pa = (pa & PG_FRAME) | (va & ~PG_FRAME); -#ifdef DEBUG - if (pmapdebug & PDB_FOLLOW) - printf("%lx\n", pa); -#endif - return(pa); + + PMAP_DPRINTF(PDB_FOLLOW, ("%lx\n", pa)); + + return (pa); } /* - * Copy the range specified by src_addr/len + * pmap_copy: [ INTERFACE ] + * + * Copy the mapping range specified by src_addr/len * from the source map to the range dst_addr/len * in the destination map. * * This routine is only advisory and need not do anything. */ -void pmap_copy(dst_pmap, src_pmap, dst_addr, len, src_addr) +void +pmap_copy(dst_pmap, src_pmap, dst_addr, len, src_addr) pmap_t dst_pmap; pmap_t src_pmap; - vm_offset_t dst_addr; - vm_size_t len; - vm_offset_t src_addr; + vaddr_t dst_addr; + vsize_t len; + vaddr_t src_addr; { -#ifdef DEBUG - if (pmapdebug & PDB_FOLLOW) - printf("pmap_copy(%p, %p, %lx, %lx, %lx)\n", - dst_pmap, src_pmap, dst_addr, len, src_addr); -#endif + + PMAP_DPRINTF(PDB_FOLLOW, + ("pmap_copy(%p, %p, %lx, %lx, %lx)\n", + dst_pmap, src_pmap, dst_addr, len, src_addr)); } /* + * pmap_update: + * * Require that all active physical maps contain no - * incorrect entries NOW. [This update includes - * forcing updates of any address map caching.] + * incorrect entires NOW, by processing any deferred + * pmap operations. + */ +void +pmap_update() +{ + + PMAP_DPRINTF(PDB_FOLLOW, ("pmap_update()\n")); + + TBIA(); /* XXX should not be here. */ +} + +/* + * pmap_collect: [ INTERFACE ] + * + * Garbage collects the physical map system for pages which are no + * longer used. Success need not be guaranteed -- that is, there + * may well be pages which are not referenced, but others may be + * collected. * - * Generally used to insure that a thread about - * to run will see a semantically correct world. + * Called by the pageout daemon when pages are scarce. */ -void pmap_update() +void +pmap_collect(pmap) + pmap_t pmap; { -#ifdef DEBUG - if (pmapdebug & PDB_FOLLOW) - printf("pmap_update()\n"); + + PMAP_DPRINTF(PDB_FOLLOW, ("pmap_collect(%p)\n", pmap)); + + if (pmap == pmap_kernel()) { + int bank, s; + + /* + * XXX This is very bogus. We should handle kernel PT + * XXX pages much differently. + */ + + s = splimp(); + for (bank = 0; bank < vm_nphysseg; bank++) + pmap_collect1(pmap, ptoa(vm_physmem[bank].start), + ptoa(vm_physmem[bank].end)); + splx(s); + } else { + /* + * This process is about to be swapped out; free all of + * the PT pages by removing the physical mappings for its + * entire address space. Note: pmap_remove() performs + * all necessary locking. + */ + pmap_remove(pmap, VM_MIN_ADDRESS, VM_MAX_ADDRESS); + } + +#ifdef notyet + /* Go compact and garbage-collect the pv_table. */ + pmap_collect_pv(); #endif - TBIA(); } /* - * Routine: pmap_collect - * Function: - * Garbage collects the physical map system for - * pages which are no longer used. - * Success need not be guaranteed -- that is, there - * may well be pages which are not referenced, but - * others may be collected. - * Usage: - * Called by the pageout daemon when pages are scarce. + * pmap_collect1: + * + * Garbage-collect KPT pages. Helper for the above (bogus) + * pmap_collect(). + * + * Note: THIS SHOULD GO AWAY, AND BE REPLACED WITH A BETTER + * WAY OF HANDLING PT PAGES! */ void -pmap_collect(pmap) +pmap_collect1(pmap, startpa, endpa) pmap_t pmap; + paddr_t startpa, endpa; { - return; /* XXX -- do we need to do anything here? */ + paddr_t pa; + struct pv_entry *pv; + pt_entry_t *pte; + paddr_t kpa; +#ifdef DEBUG + st_entry_t *ste; + int opmapdebug = 0 /* XXX initialize to quiet gcc -Wall */; +#endif + + for (pa = startpa; pa < endpa; pa += NBPG) { + struct kpt_page *kpt, **pkpt; + + /* + * Locate physical pages which are being used as kernel + * page table pages. + */ + pv = pa_to_pvh(pa); + if (pv->pv_pmap != pmap_kernel() || !(pv->pv_flags & PV_PTPAGE)) + continue; + do { + if (pv->pv_ptste && pv->pv_ptpmap == pmap_kernel()) + break; + } while ((pv = pv->pv_next)); + if (pv == NULL) + continue; +#ifdef DEBUG + if (pv->pv_va < (vaddr_t)Sysmap || + pv->pv_va >= (vaddr_t)Sysmap + MAC_MAX_PTSIZE) + printf("collect: kernel PT VA out of range\n"); + else + goto ok; + pmap_pvdump(pa); + continue; +ok: +#endif + pte = (pt_entry_t *)(pv->pv_va + NBPG); + while (--pte >= (pt_entry_t *)pv->pv_va && *pte == PG_NV) + ; + if (pte >= (pt_entry_t *)pv->pv_va) + continue; + +#ifdef DEBUG + if (pmapdebug & (PDB_PTPAGE|PDB_COLLECT)) { + printf("collect: freeing KPT page at %lx (ste %x@%p)\n", + pv->pv_va, *pv->pv_ptste, pv->pv_ptste); + opmapdebug = pmapdebug; + pmapdebug |= PDB_PTPAGE; + } + + ste = pv->pv_ptste; +#endif + /* + * If all entries were invalid we can remove the page. + * We call pmap_remove_entry to take care of invalidating + * ST and Sysptmap entries. + */ + kpa = pmap_extract(pmap, pv->pv_va); + pmap_remove_mapping(pmap, pv->pv_va, PT_ENTRY_NULL, + PRM_TFLUSH|PRM_CFLUSH); + /* + * Use the physical address to locate the original + * (kmem_alloc assigned) address for the page and put + * that page back on the free list. + */ + for (pkpt = &kpt_used_list, kpt = *pkpt; + kpt != (struct kpt_page *)0; + pkpt = &kpt->kpt_next, kpt = *pkpt) + if (kpt->kpt_pa == kpa) + break; +#ifdef DEBUG + if (kpt == (struct kpt_page *)0) + panic("pmap_collect: lost a KPT page"); + if (pmapdebug & (PDB_PTPAGE|PDB_COLLECT)) + printf("collect: %lx (%lx) to free list\n", + kpt->kpt_va, kpa); +#endif + *pkpt = kpt->kpt_next; + kpt->kpt_next = kpt_free_list; + kpt_free_list = kpt; +#ifdef DEBUG + if (pmapdebug & (PDB_PTPAGE|PDB_COLLECT)) + pmapdebug = opmapdebug; + + if (*ste != SG_NV) + printf("collect: kernel STE at %p still valid (%x)\n", + ste, *ste); + ste = &Sysptmap[ste - pmap_ste(pmap_kernel(), 0)]; + if (*ste != SG_NV) + printf("collect: kernel PTmap at %p still valid (%x)\n", + ste, *ste); +#endif + } } /* - * pmap_zero_page zeros the specified (machine independent) - * page by mapping the page into virtual memory and using - * bzero to clear its contents, one machine dependent page - * at a time. + * pmap_zero_page: [ INTERFACE ] + * + * Zero the specified (machine independent) page by mapping the page + * into virtual memory and using bzero to clear its contents, one + * machine dependent page at a time. + * + * Note: WE DO NOT CURRENTLY LOCK THE TEMPORARY ADDRESSES! + * (Actually, we go to splimp(), and since we don't + * support multiple processors, this is sufficient.) */ void pmap_zero_page(phys) - vm_offset_t phys; + paddr_t phys; { - register vm_offset_t kva; - extern caddr_t CADDR1; + int s, npte; + + PMAP_DPRINTF(PDB_FOLLOW, ("pmap_zero_page(%lx)\n", phys)); + + npte = phys | PG_V; + +#if defined(M68040) || defined(M68060) + if (mmutype == MMU_68040) { + /* + * Set copyback caching on the page; this is required + * for cache consistency (since regular mappings are + * copyback as well). + */ + npte |= PG_CCB; + } +#endif + + s = splimp(); + + *caddr1_pte = npte; + TBIS((vaddr_t)CADDR1); + + zeropage(CADDR1); #ifdef DEBUG - if (pmapdebug & PDB_FOLLOW) - printf("pmap_zero_page(%lx)\n", phys); -#endif - kva = (vm_offset_t) CADDR1; - pmap_enter(pmap_kernel(), kva, phys, VM_PROT_READ|VM_PROT_WRITE, TRUE, - 0); - zeropage((caddr_t)kva); - pmap_remove_mapping(pmap_kernel(), kva, PT_ENTRY_NULL, - PRM_TFLUSH|PRM_CFLUSH); + *caddr1_pte = PG_NV; + TBIS((vaddr_t)CADDR1); +#endif + + splx(s); } /* - * pmap_copy_page copies the specified (machine independent) - * page by mapping the page into virtual memory and using - * bcopy to copy the page, one machine dependent page at a - * time. + * pmap_copy_page: [ INTERFACE ] + * + * Copy the specified (machine independent) page by mapping the page + * into virtual memory and using bcopy to copy the page, one machine + * dependent page at a time. + * + * Note: WE DO NOT CURRENTLY LOCK THE TEMPORARY ADDRESSES! + * (Actually, we go to splimp(), and since we don't + * support multiple processors, this is sufficient.) */ void pmap_copy_page(src, dst) - vm_offset_t src, dst; + paddr_t src, dst; { - register vm_offset_t skva, dkva; - extern caddr_t CADDR1, CADDR2; + int s, npte1, npte2; + + PMAP_DPRINTF(PDB_FOLLOW, ("pmap_copy_page(%lx, %lx)\n", src, dst)); + + npte1 = src | PG_RO | PG_V; + npte2 = dst | PG_V; + +#if defined(M68040) || defined(M68060) + if (mmutype == MMU_68040) { + /* + * Set copyback caching on the pages; this is required + * for cache consistency (since regular mappings are + * copyback as well). + */ + npte1 |= PG_CCB; + npte2 |= PG_CCB; + } +#endif + + s = splimp(); + + *caddr1_pte = npte1; + TBIS((vaddr_t)CADDR1); + + *caddr2_pte = npte2; + TBIS((vaddr_t)CADDR2); + + copypage(CADDR1, CADDR2); #ifdef DEBUG - if (pmapdebug & PDB_FOLLOW) - printf("pmap_copy_page(%lx, %lx)\n", src, dst); -#endif - skva = (vm_offset_t) CADDR1; - dkva = (vm_offset_t) CADDR2; - pmap_enter(pmap_kernel(), skva, src, VM_PROT_READ, TRUE, 0); - pmap_enter(pmap_kernel(), dkva, dst, VM_PROT_READ|VM_PROT_WRITE, TRUE, - 0); - copypage((caddr_t)skva, (caddr_t)dkva); - /* CADDR1 and CADDR2 are virtually contiguous */ - pmap_remove(pmap_kernel(), skva, skva + (2 * NBPG)); -} + *caddr1_pte = PG_NV; + TBIS((vaddr_t)CADDR1); + *caddr2_pte = PG_NV; + TBIS((vaddr_t)CADDR2); +#endif + + splx(s); +} /* - * Routine: pmap_pageable - * Function: - * Make the specified pages (by pmap, offset) - * pageable (or not) as requested. - * - * A page which is not pageable may not take - * a fault; therefore, its page table entry - * must remain valid for the duration. - * - * This routine is merely advisory; pmap_enter - * will specify that these pages are to be wired - * down (or not) as appropriate. + * pmap_pageable: [ INTERFACE ] + * + * Make the specified pages (by pmap, offset) pageable (or not) as + * requested. + * + * A page which is not pageable may not take a fault; therefore, + * its page table entry must remain valid for the duration. + * + * This routine is merely advisory; pmap_enter() will specify that + * these pages are to be wired down (or not) as appropriate. */ void pmap_pageable(pmap, sva, eva, pageable) pmap_t pmap; - vm_offset_t sva, eva; + vaddr_t sva, eva; boolean_t pageable; { -#ifdef DEBUG - if (pmapdebug & PDB_FOLLOW) - printf("pmap_pageable(%p, %lx, %lx, %x)\n", - pmap, sva, eva, pageable); -#endif + + PMAP_DPRINTF(PDB_FOLLOW, + ("pmap_pageable(%p, %lx, %lx, %x)\n", + pmap, sva, eva, pageable)); + /* * If we are making a PT page pageable then all valid * mappings must be gone from that page. Hence it should @@ -1528,8 +1798,8 @@ pmap_pageable(pmap, sva, eva, pageable) * - PT pages have only one pv_table entry */ if (pmap == pmap_kernel() && pageable && sva + NBPG == eva) { - register struct pv_entry *pv; - register vm_offset_t pa; + struct pv_entry *pv; + paddr_t pa; #ifdef DEBUG if ((pmapdebug & (PDB_FOLLOW|PDB_PTPAGE)) == PDB_PTPAGE) @@ -1539,7 +1809,7 @@ pmap_pageable(pmap, sva, eva, pageable) if (!pmap_ste_v(pmap, sva)) return; pa = pmap_pte_pa(pmap_pte(pmap, sva)); - if (!pmap_valid_page (pa)) + if (PAGE_IS_MANAGED(pa) == 0) return; pv = pa_to_pvh(pa); if (pv->pv_ptste == NULL) @@ -1552,65 +1822,62 @@ pmap_pageable(pmap, sva, eva, pageable) } #endif /* - * Mark it unmodified to avoid pageout + * page is unused, free it now! */ - pmap_changebit(pa, PG_M, FALSE); + pmap_remove_mapping(pv->pv_pmap, pv->pv_va, + NULL, PRM_TFLUSH|PRM_CFLUSH); +#if defined(UVM) + uvm_pagefree(PHYS_TO_VM_PAGE(pa)); +#else + vm_page_free(PHYS_TO_VM_PAGE(pa)); +#endif #ifdef DEBUG - if ((PHYS_TO_VM_PAGE(pa)->flags & PG_CLEAN) == 0) { - printf("pa %lx: flags=%x: not clean\n", - pa, PHYS_TO_VM_PAGE(pa)->flags); - PHYS_TO_VM_PAGE(pa)->flags |= PG_CLEAN; - } if (pmapdebug & PDB_PTPAGE) - printf("pmap_pageable: PT page %lx(%x) unmodified\n", + printf("pmap_pageable: PT page %lx(%x) freed\n", sva, *pmap_pte(pmap, sva)); - if (pmapdebug & PDB_WIRING) - pmap_check_wiring("pageable", sva); #endif } } /* + * pmap_clear_modify: [ INTERFACE ] + * * Clear the modify bits on the specified physical page. */ - void pmap_clear_modify(pa) - vm_offset_t pa; + paddr_t pa; { -#ifdef DEBUG - if (pmapdebug & PDB_FOLLOW) - printf("pmap_clear_modify(%lx)\n", pa); -#endif - pmap_changebit(pa, PG_M, FALSE); + + PMAP_DPRINTF(PDB_FOLLOW, ("pmap_clear_modify(%lx)\n", pa)); + + pmap_changebit(pa, 0, ~PG_M); } /* - * pmap_clear_reference: + * pmap_clear_reference: [ INTERFACE ] * * Clear the reference bit on the specified physical page. */ - -void pmap_clear_reference(pa) - vm_offset_t pa; +void +pmap_clear_reference(pa) + paddr_t pa; { -#ifdef DEBUG - if (pmapdebug & PDB_FOLLOW) - printf("pmap_clear_reference(%lx)\n", pa); -#endif - pmap_changebit(pa, PG_U, FALSE); + + PMAP_DPRINTF(PDB_FOLLOW, ("pmap_clear_reference(%lx)\n", pa)); + + pmap_changebit(pa, 0, ~PG_U); } /* - * pmap_is_referenced: + * pmap_is_referenced: [ INTERFACE ] * * Return whether or not the specified physical page is referenced * by any physical maps. */ - boolean_t pmap_is_referenced(pa) - vm_offset_t pa; + paddr_t pa; { #ifdef DEBUG if (pmapdebug & PDB_FOLLOW) { @@ -1623,15 +1890,14 @@ pmap_is_referenced(pa) } /* - * pmap_is_modified: + * pmap_is_modified: [ INTERFACE ] * * Return whether or not the specified physical page is modified * by any physical maps. */ - boolean_t pmap_is_modified(pa) - vm_offset_t pa; + paddr_t pa; { #ifdef DEBUG if (pmapdebug & PDB_FOLLOW) { @@ -1643,7 +1909,16 @@ pmap_is_modified(pa) return(pmap_testbit(pa, PG_M)); } -vm_offset_t +/* + * pmap_phys_address: [ INTERFACE ] + * + * Return the physical address corresponding to the specified + * cookie. Used by the device pager to decode a device driver's + * mmap entry point return value. + * + * Note: no locking is necessary in this function. + */ +paddr_t pmap_phys_address(ppn) int ppn; { @@ -1655,32 +1930,38 @@ pmap_phys_address(ppn) */ /* - * Invalidate a single page denoted by pmap/va. - * If (pte != NULL), it is the already computed PTE for the page. - * If (flags & PRM_TFLUSH), we must invalidate any TLB information. - * If (flags & PRM_CFLUSH), we must flush/invalidate any cache information. + * pmap_remove_mapping: + * + * Invalidate a single page denoted by pmap/va. + * + * If (pte != NULL), it is the already computed PTE for the page. + * + * If (flags & PRM_TFLUSH), we must invalidate any TLB information. + * + * If (flags & PRM_CFLUSH), we must flush/invalidate any cache + * information. */ /* static */ void pmap_remove_mapping(pmap, va, pte, flags) - register pmap_t pmap; - register vm_offset_t va; - register pt_entry_t *pte; + pmap_t pmap; + vaddr_t va; + pt_entry_t *pte; int flags; { - register vm_offset_t pa; - register struct pv_entry *pv, *npv; + paddr_t pa; + struct pv_entry *pv, *npv; pmap_t ptpmap; st_entry_t *ste; int s, bits; #ifdef DEBUG pt_entry_t opte; - - if (pmapdebug & (PDB_FOLLOW|PDB_REMOVE|PDB_PROTECT)) - printf("pmap_remove_mapping(%p, %lx, %p, %x)\n", - pmap, va, pte, flags); #endif + PMAP_DPRINTF(PDB_FOLLOW|PDB_REMOVE|PDB_PROTECT, + ("pmap_remove_mapping(%p, %lx, %p, %x)\n", + pmap, va, pte, flags)); + /* * PTE not provided, compute it from pmap and va. */ @@ -1689,13 +1970,11 @@ pmap_remove_mapping(pmap, va, pte, flags) if (*pte == PG_NV) return; } + pa = pmap_pte_pa(pte); #ifdef DEBUG opte = *pte; #endif -#ifdef PMAPSTATS - remove_stats.removes++; -#endif /* * Update statistics */ @@ -1706,10 +1985,7 @@ pmap_remove_mapping(pmap, va, pte, flags) /* * Invalidate the PTE after saving the reference modify info. */ -#ifdef DEBUG - if (pmapdebug & PDB_REMOVE) - printf("remove: invalidating pte at %p\n", pte); -#endif + PMAP_DPRINTF(PDB_REMOVE, ("remove: invalidating pte at %p\n", pte)); bits = *pte & (PG_U|PG_M); *pte = PG_NV; if ((flags & PRM_TFLUSH) && active_pmap(pmap)) @@ -1722,8 +1998,13 @@ pmap_remove_mapping(pmap, va, pte, flags) * PT page. */ if (pmap != pmap_kernel()) { - (void) vm_map_pageable(pt_map, trunc_page((vaddr_t)pte), - round_page((vaddr_t)(pte+1)), TRUE); +#if defined(UVM) + (void)uvm_map_pageable(pt_map, trunc_page((vaddr_t)pte), + round_page((vaddr_t)(pte+1)), TRUE); +#else + (void)vm_map_pageable(pt_map, trunc_page((vaddr_t)pte), + round_page((vaddr_t)(pte+1)), TRUE); +#endif #ifdef DEBUG if (pmapdebug & PDB_WIRING) pmap_check_wiring("remove", (vaddr_t)trunc_page(pte)); @@ -1732,7 +2013,7 @@ pmap_remove_mapping(pmap, va, pte, flags) /* * If this isn't a managed page, we are all done. */ - if (!pmap_valid_page (pa)) + if (PAGE_IS_MANAGED(pa) == 0) return; /* * Otherwise remove it from the PV table @@ -1757,14 +2038,8 @@ pmap_remove_mapping(pmap, va, pte, flags) pmap_free_pv(npv); } else pv->pv_pmap = NULL; -#ifdef PMAPSTATS - remove_stats.pvfirst++; -#endif } else { for (npv = pv->pv_next; npv; npv = npv->pv_next) { -#ifdef PMAPSTATS - remove_stats.pvsearch++; -#endif if (pmap == npv->pv_pmap && va == npv->pv_va) break; pv = npv; @@ -1779,19 +2054,15 @@ pmap_remove_mapping(pmap, va, pte, flags) pmap_free_pv(npv); pv = pa_to_pvh(pa); } + /* * If this was a PT page we must also remove the * mapping from the associated segment table. */ if (ste) { -#ifdef PMAPSTATS - remove_stats.ptinvalid++; -#endif -#ifdef DEBUG - if (pmapdebug & (PDB_REMOVE|PDB_PTPAGE)) - printf("remove: ste was %x@%p pte was %x@%p\n", - *ste, ste, opte, pmap_pte(pmap, va)); -#endif + PMAP_DPRINTF(PDB_REMOVE|PDB_PTPAGE, + ("remove: ste was %x@%p pte was %x@%p\n", + *ste, ste, opte, pmap_pte(pmap, va))); #if defined(M68040) if (mmutype == MMU_68040) { st_entry_t *este = &ste[NPTEPG/SG4_LEV3SIZE]; @@ -1810,39 +2081,38 @@ pmap_remove_mapping(pmap, va, pte, flags) * freeing it if it is now empty. */ if (ptpmap != pmap_kernel()) { + PMAP_DPRINTF(PDB_REMOVE|PDB_SEGTAB, + ("remove: stab %p, refcnt %d\n", + ptpmap->pm_stab, ptpmap->pm_sref - 1)); #ifdef DEBUG - if (pmapdebug & (PDB_REMOVE|PDB_SEGTAB)) - printf("remove: stab %p, refcnt %d\n", - ptpmap->pm_stab, ptpmap->pm_sref - 1); if ((pmapdebug & PDB_PARANOIA) && ptpmap->pm_stab != (st_entry_t *)trunc_page((vaddr_t)ste)) panic("remove: bogus ste"); #endif if (--(ptpmap->pm_sref) == 0) { -#ifdef DEBUG - if (pmapdebug&(PDB_REMOVE|PDB_SEGTAB)) - printf("remove: free stab %p\n", - ptpmap->pm_stab); -#endif + PMAP_DPRINTF(PDB_REMOVE|PDB_SEGTAB, + ("remove: free stab %p\n", + ptpmap->pm_stab)); +#if defined(UVM) + uvm_km_free_wakeup(st_map, + (vaddr_t)ptpmap->pm_stab, MAC_STSIZE); +#else kmem_free_wakeup(st_map, - (vm_offset_t)ptpmap->pm_stab, - MAC_STSIZE); + (vaddr_t)ptpmap->pm_stab, MAC_STSIZE); +#endif ptpmap->pm_stab = Segtabzero; ptpmap->pm_stpa = Segtabzeropa; #if defined(M68040) if (mmutype == MMU_68040) ptpmap->pm_stfree = protostfree; #endif - ptpmap->pm_stchanged = TRUE; /* * XXX may have changed segment table * pointer for current process so * update now to reload hardware. */ - if (curproc != NULL && - ptpmap == curproc->p_vmspace->vm_map.pmap) - PMAP_ACTIVATE(ptpmap, - &curproc->p_addr->u_pcb, 1); + if (active_user_pmap(ptpmap)) + PMAP_ACTIVATE(ptpmap, 1); } #ifdef DEBUG else if (ptpmap->pm_sref < 0) @@ -1865,40 +2135,47 @@ pmap_remove_mapping(pmap, va, pte, flags) /* * Update saved attributes for managed page */ - pmap_attributes[pmap_page_index(pa)] |= bits; + *pa_to_attribute(pa) |= bits; splx(s); } +/* + * pmap_testbit: + * + * Test the modified/referenced bits of a physical page. + */ /* static */ boolean_t pmap_testbit(pa, bit) - register vm_offset_t pa; + paddr_t pa; int bit; { - register struct pv_entry *pv; - register pt_entry_t *pte; + struct pv_entry *pv; + pt_entry_t *pte; int s; - if (!pmap_valid_page (pa)) - return FALSE; + if (PAGE_IS_MANAGED(pa) == 0) + return (FALSE); pv = pa_to_pvh(pa); s = splimp(); /* * Check saved info first */ - if (pmap_attributes[pmap_page_index(pa)] & bit) { + if (*pa_to_attribute(pa) & bit) { splx(s); return(TRUE); } + /* - * Not found, check current mappings returning - * immediately if found. + * Not found. Check current mappings, returning immediately if + * found. Cache a hit to speed future lookups. */ if (pv->pv_pmap != NULL) { for (; pv; pv = pv->pv_next) { pte = pmap_pte(pv->pv_pmap, pv->pv_va); if (*pte & bit) { + *pa_to_attribute(pa) |= bit; splx(s); return(TRUE); } @@ -1908,48 +2185,43 @@ pmap_testbit(pa, bit) return(FALSE); } +/* + * pmap_changebit: + * + * Change the modified/referenced bits, or other PTE bits, + * for a physical page. + */ /* static */ void -pmap_changebit(pa, bit, setem) - register vm_offset_t pa; - int bit; - boolean_t setem; +pmap_changebit(pa, set, mask) + paddr_t pa; + int set, mask; { - register struct pv_entry *pv; - register pt_entry_t *pte, npte; - vm_offset_t va; + struct pv_entry *pv; + pt_entry_t *pte, npte; + vaddr_t va; int s; #if defined(M68040) boolean_t firstpage = TRUE; #endif -#ifdef PMAPSTATS - struct chgstats *chgp; -#endif -#ifdef DEBUG - if (pmapdebug & PDB_BITS) - printf("pmap_changebit(%lx, %x, %s)\n", - pa, bit, setem ? "set" : "clear"); -#endif - if (!pmap_valid_page (pa)) + PMAP_DPRINTF(PDB_BITS, + ("pmap_changebit(%lx, %x, %x)\n", pa, set, mask)); + + if (PAGE_IS_MANAGED(pa) == 0) return; -#ifdef PMAPSTATS - chgp = &changebit_stats[(bit>>2)-1]; - if (setem) - chgp->setcalls++; - else - chgp->clrcalls++; -#endif pv = pa_to_pvh(pa); s = splimp(); + /* * Clear saved attributes (modify, reference) */ - if (!setem) - pmap_attributes[pmap_page_index(pa)] &= ~bit; + *pa_to_attribute(pa) &= mask; + /* * Loop over all current mappings setting/clearing as appropos + * If setting RO do we need to clear the VAC? */ if (pv->pv_pmap != NULL) { #ifdef DEBUG @@ -1964,18 +2236,20 @@ pmap_changebit(pa, bit, setem) /* * XXX don't write protect pager mappings */ - if (bit == PG_RO) { - extern vm_offset_t pager_sva, pager_eva; + if (set == PG_RO) { +#if defined(UVM) + if (va >= uvm.pager_sva && va < uvm.pager_eva) + continue; +#else + extern vaddr_t pager_sva, pager_eva; if (va >= pager_sva && va < pager_eva) continue; +#endif } pte = pmap_pte(pv->pv_pmap, va); - if (setem) - npte = *pte | bit; - else - npte = *pte & ~bit; + npte = (*pte | set) & mask; if (*pte != npte) { #if defined(M68040) /* @@ -1983,9 +2257,10 @@ pmap_changebit(pa, bit, setem) * protection make sure the caches are * flushed (but only once). */ - if (firstpage && mmutype == MMU_68040 && - ((bit == PG_RO && setem) || - (bit & PG_CMASK))) { + if (firstpage && (mmutype == MMU_68040) && + ((set == PG_RO) || + (set & PG_CMASK) || + (mask & PG_CMASK) == 0)) { firstpage = FALSE; DCFP(pa); ICPP(pa); @@ -1994,44 +2269,31 @@ pmap_changebit(pa, bit, setem) *pte = npte; if (active_pmap(pv->pv_pmap)) TBIS(va); -#ifdef PMAPSTATS - if (setem) - chgp->sethits++; - else - chgp->clrhits++; -#endif - } -#ifdef PMAPSTATS - else { - if (setem) - chgp->setmiss++; - else - chgp->clrmiss++; } -#endif } } splx(s); } +/* + * pmap_enter_ptpage: + * + * Allocate and map a PT page for the specified pmap/va pair. + */ /* static */ void pmap_enter_ptpage(pmap, va) - register pmap_t pmap; - register vm_offset_t va; + pmap_t pmap; + vaddr_t va; { - register vm_offset_t ptpa; - register struct pv_entry *pv; + paddr_t ptpa; + struct pv_entry *pv; st_entry_t *ste; int s; -#ifdef DEBUG - if (pmapdebug & (PDB_FOLLOW|PDB_ENTER|PDB_PTPAGE)) - printf("pmap_enter_ptpage: pmap %p, va %lx\n", pmap, va); -#endif -#ifdef PMAPSTATS - enter_stats.ptpneeded++; -#endif + PMAP_DPRINTF(PDB_FOLLOW|PDB_ENTER|PDB_PTPAGE, + ("pmap_enter_ptpage: pmap %p, va %lx\n", pmap, va)); + /* * Allocate a segment table if necessary. Note that it is allocated * from a private map and not pt_map. This keeps user page tables @@ -2040,31 +2302,33 @@ pmap_enter_ptpage(pmap, va) * reference count drops to zero. */ if (pmap->pm_stab == Segtabzero) { +#if defined(UVM) pmap->pm_stab = (st_entry_t *) - kmem_alloc(st_map, MAC_STSIZE); + uvm_km_zalloc(st_map, MAC_STSIZE); +#else + pmap->pm_stab = (st_entry_t *)kmem_alloc(st_map, MAC_STSIZE); +#endif pmap->pm_stpa = (st_entry_t *) - pmap_extract(pmap_kernel(), (vm_offset_t)pmap->pm_stab); + pmap_extract(pmap_kernel(), (vaddr_t)pmap->pm_stab); #if defined(M68040) if (mmutype == MMU_68040) { #ifdef DEBUG if (dowriteback && dokwriteback) #endif - pmap_changebit((vm_offset_t)pmap->pm_stpa, PG_CCB, 0); + pmap_changebit((paddr_t)pmap->pm_stpa, 0, ~PG_CCB); pmap->pm_stfree = protostfree; } #endif - pmap->pm_stchanged = TRUE; /* * XXX may have changed segment table pointer for current * process so update now to reload hardware. */ - if (pmap == curproc->p_vmspace->vm_map.pmap) - PMAP_ACTIVATE(pmap, &curproc->p_addr->u_pcb, 1); -#ifdef DEBUG - if (pmapdebug & (PDB_ENTER|PDB_PTPAGE|PDB_SEGTAB)) - printf("enter: pmap %p stab %p(%p)\n", - pmap, pmap->pm_stab, pmap->pm_stpa); -#endif + if (active_user_pmap(pmap)) + PMAP_ACTIVATE(pmap, 1); + + PMAP_DPRINTF(PDB_ENTER|PDB_PTPAGE|PDB_SEGTAB, + ("enter: pmap %p stab %p(%p)\n", + pmap, pmap->pm_stab, pmap->pm_stpa)); } ste = pmap_ste(pmap, va); @@ -2085,10 +2349,9 @@ pmap_enter_ptpage(pmap, va) bzero(addr, SG4_LEV2SIZE*sizeof(st_entry_t)); addr = (caddr_t)&pmap->pm_stpa[ix*SG4_LEV2SIZE]; *ste = (u_int)addr | SG_RW | SG_U | SG_V; -#ifdef DEBUG - if (pmapdebug & (PDB_ENTER|PDB_PTPAGE|PDB_SEGTAB)) - printf("enter: alloc ste2 %d(%p)\n", ix, addr); -#endif + + PMAP_DPRINTF(PDB_ENTER|PDB_PTPAGE|PDB_SEGTAB, + ("enter: alloc ste2 %d(%p)\n", ix, addr)); } ste = pmap_ste2(pmap, va); /* @@ -2100,14 +2363,12 @@ pmap_enter_ptpage(pmap, va) * entirety below. */ ste = (st_entry_t *)((int)ste & ~(NBPG/SG4_LEV3SIZE-1)); -#ifdef DEBUG - if (pmapdebug & (PDB_ENTER|PDB_PTPAGE|PDB_SEGTAB)) - printf("enter: ste2 %p (%p)\n", - pmap_ste2(pmap, va), ste); -#endif + + PMAP_DPRINTF(PDB_ENTER|PDB_PTPAGE|PDB_SEGTAB, + ("enter: ste2 %p (%p)\n", pmap_ste2(pmap, va), ste)); } #endif - va = trunc_page((vm_offset_t)pmap_pte(pmap, va)); + va = trunc_page((vaddr_t)pmap_pte(pmap, va)); /* * In the kernel we allocate a page from the kernel PT page @@ -2115,7 +2376,7 @@ pmap_enter_ptpage(pmap, va) * pmap_enter). */ if (pmap == pmap_kernel()) { - register struct kpt_page *kpt; + struct kpt_page *kpt; s = splimp(); if ((kpt = kpt_free_list) == (struct kpt_page *)0) { @@ -2123,25 +2384,19 @@ pmap_enter_ptpage(pmap, va) * No PT pages available. * Try once to free up unused ones. */ -#ifdef DEBUG - if (pmapdebug & PDB_COLLECT) - printf("enter: no KPT pages, collecting...\n"); -#endif + PMAP_DPRINTF(PDB_COLLECT, + ("enter: no KPT pages, collecting...\n")); pmap_collect(pmap_kernel()); if ((kpt = kpt_free_list) == (struct kpt_page *)0) panic("pmap_enter_ptpage: can't get KPT page"); } -#ifdef PMAPSTATS - if (++kpt_stats.kptinuse > kpt_stats.kptmaxuse) - kpt_stats.kptmaxuse = kpt_stats.kptinuse; -#endif kpt_free_list = kpt->kpt_next; kpt->kpt_next = kpt_used_list; kpt_used_list = kpt; ptpa = kpt->kpt_pa; bzero((caddr_t)kpt->kpt_va, NBPG); pmap_enter(pmap, va, ptpa, VM_PROT_DEFAULT, TRUE, - VM_PROT_DEFAULT); + VM_PROT_DEFAULT); #ifdef DEBUG if (pmapdebug & (PDB_ENTER|PDB_PTPAGE)) { int ix = pmap_ste(pmap, va) - pmap_ste(pmap, 0); @@ -2162,15 +2417,22 @@ pmap_enter_ptpage(pmap, va) * lose the segment table when low on memory. */ pmap->pm_sref++; -#ifdef DEBUG - if (pmapdebug & (PDB_ENTER|PDB_PTPAGE)) - printf("enter: about to fault UPT pg at %lx\n", va); -#endif + PMAP_DPRINTF(PDB_ENTER|PDB_PTPAGE, + ("enter: about to fault UPT pg at %lx\n", va)); +#if defined(UVM) + s = uvm_fault(pt_map, va, 0, VM_PROT_READ|VM_PROT_WRITE); + if (s != KERN_SUCCESS) { + printf("uvm_fault(pt_map, 0x%lx, 0, RW) -> %d\n", + va, s); + panic("pmap_enter: uvm_fault failed"); + } +#else s = vm_fault(pt_map, va, VM_PROT_READ|VM_PROT_WRITE, FALSE); if (s != KERN_SUCCESS) { - printf("vm_fault(pt_map, 0x%lx, RW, 0) -> %d\n",va,s); + printf("vm_fault(pt_map, %lx, RW, 0) -> %d\n", va, s); panic("pmap_enter: vm_fault failed"); } +#endif ptpa = pmap_extract(pmap_kernel(), va); /* * Mark the page clean now to avoid its pageout (and @@ -2178,9 +2440,11 @@ pmap_enter_ptpage(pmap, va) * is wired; i.e. while it is on a paging queue. */ PHYS_TO_VM_PAGE(ptpa)->flags |= PG_CLEAN; +#if !defined (UVM) #ifdef DEBUG PHYS_TO_VM_PAGE(ptpa)->flags |= PG_PTPAGE; #endif +#endif } #if defined(M68040) /* @@ -2195,10 +2459,10 @@ pmap_enter_ptpage(pmap, va) pt_entry_t *pte = pmap_pte(pmap_kernel(), va); if ((pmapdebug & PDB_PARANOIA) && (*pte & PG_CCB) == 0) printf("%s PT no CCB: kva=%lx ptpa=%lx pte@%p=%x\n", - pmap == pmap_kernel() ? "Kernel" : "User", - va, ptpa, pte, *pte); + pmap == pmap_kernel() ? "Kernel" : "User", + va, ptpa, pte, *pte); #endif - pmap_changebit(ptpa, PG_CCB, 0); + pmap_changebit(ptpa, 0, ~PG_CCB); } #endif /* @@ -2213,7 +2477,7 @@ pmap_enter_ptpage(pmap, va) do { if (pv->pv_pmap == pmap_kernel() && pv->pv_va == va) break; - } while ((pv = pv->pv_next) != NULL); + } while ((pv = pv->pv_next)); } #ifdef DEBUG if (pv == NULL) @@ -2221,10 +2485,9 @@ pmap_enter_ptpage(pmap, va) #endif pv->pv_ptste = ste; pv->pv_ptpmap = pmap; -#ifdef DEBUG - if (pmapdebug & (PDB_ENTER|PDB_PTPAGE)) - printf("enter: new PT page at PA %lx, ste at %p\n", ptpa, ste); -#endif + + PMAP_DPRINTF(PDB_ENTER|PDB_PTPAGE, + ("enter: new PT page at PA %lx, ste at %p\n", ptpa, ste)); /* * Map the new PT page into the segment table. @@ -2246,11 +2509,9 @@ pmap_enter_ptpage(pmap, va) #endif *ste = (ptpa & SG_FRAME) | SG_RW | SG_V; if (pmap != pmap_kernel()) { -#ifdef DEBUG - if (pmapdebug & (PDB_ENTER|PDB_PTPAGE|PDB_SEGTAB)) - printf("enter: stab %p refcnt %d\n", - pmap->pm_stab, pmap->pm_sref); -#endif + PMAP_DPRINTF(PDB_ENTER|PDB_PTPAGE|PDB_SEGTAB, + ("enter: stab %p refcnt %d\n", + pmap->pm_stab, pmap->pm_sref)); } #if 0 /* @@ -2266,12 +2527,17 @@ pmap_enter_ptpage(pmap, va) } #ifdef DEBUG +/* + * pmap_pvdump: + * + * Dump the contents of the PV list for the specified physical page. + */ /* static */ void pmap_pvdump(pa) - vm_offset_t pa; + paddr_t pa; { - register struct pv_entry *pv; + struct pv_entry *pv; printf("pa %lx", pa); for (pv = pa_to_pvh(pa); pv; pv = pv->pv_next) @@ -2281,25 +2547,39 @@ pmap_pvdump(pa) printf("\n"); } +/* + * pmap_check_wiring: + * + * Count the number of valid mappings in the specified PT page, + * and ensure that it is consistent with the number of wirings + * to that page that the VM system has. + */ /* static */ void pmap_check_wiring(str, va) char *str; - vm_offset_t va; + vaddr_t va; { vm_map_entry_t entry; - register int count; - register pt_entry_t *pte; + int count; + pt_entry_t *pte; va = trunc_page(va); if (!pmap_ste_v(pmap_kernel(), va) || !pmap_pte_v(pmap_pte(pmap_kernel(), va))) return; +#if defined(UVM) + if (!uvm_map_lookup_entry(pt_map, va, &entry)) { + printf("wired_check: entry for %lx not found\n", va); + return; + } +#else if (!vm_map_lookup_entry(pt_map, va, &entry)) { printf("wired_check: entry for %lx not found\n", va); return; } +#endif count = 0; for (pte = (pt_entry_t *)va; pte < (pt_entry_t *)(va + NBPG); pte++) if (*pte) @@ -2308,92 +2588,4 @@ pmap_check_wiring(str, va) printf("*%s*: %lx: w%d/a%d\n", str, va, entry->wired_count, count); } -#endif - -/* - * LAK: These functions are from NetBSD/i386 and are used for - * the non-contiguous memory machines, such as the IIci, IIsi, and IIvx. - * See the functions in sys/vm that #ifdef MACHINE_NONCONTIG. - */ - -/* - * pmap_free_pages() - * - * Returns the number of free physical pages left. - */ - -unsigned int -pmap_free_pages() -{ - /* printf ("pmap_free_pages(): returning %d\n", avail_remaining); */ - return avail_remaining; -} - -/* - * pmap_next_page() - * - * Stores in *addrp the next available page, skipping the hole between - * bank A and bank B. - */ - -int -pmap_next_page(addrp) - vm_offset_t *addrp; -{ - if (avail_next == high[avail_range]) { - avail_range++; - if (avail_range >= numranges) { - /* printf ("pmap_next_page(): returning FALSE\n"); */ - return FALSE; - } - avail_next = low[avail_range]; - } - - *addrp = avail_next; - /* printf ("pmap_next_page(): returning 0x%x\n", avail_next); */ - avail_next += NBPG; - avail_remaining--; - return TRUE; -} - -/* - * pmap_page_index() - * - * Given a physical address, return the page number that it is in - * the block of free memory. - */ - -int -pmap_page_index(pa) - vm_offset_t pa; -{ - /* - * XXX LAK: This routine is called quite a bit. We should go - * back and try to optimize it a bit. - */ - - int i, index; - - index = 0; - for (i = 0; i < numranges; i++) { - if (pa >= low[i] && pa < high[i]) { - index += m68k_btop (pa - low[i]); - /* printf ("pmap_page_index(0x%x): returning %d\n", */ - /* (int)pa, index); */ - return index; - } - index += m68k_btop (high[i] - low[i]); - } - - return -1; -} - -void -pmap_virtual_space(startp, endp) - vm_offset_t *startp, *endp; -{ - /* printf ("pmap_virtual_space(): returning 0x%x and 0x%x\n", */ - /* virtual_avail, virtual_end); */ - *startp = virtual_avail; - *endp = virtual_end; -} +#endif /* DEBUG */ diff --git a/sys/arch/mac68k/mac68k/pmap_bootstrap.c b/sys/arch/mac68k/mac68k/pmap_bootstrap.c index 0697dc91b18..83a7319fa59 100644 --- a/sys/arch/mac68k/mac68k/pmap_bootstrap.c +++ b/sys/arch/mac68k/mac68k/pmap_bootstrap.c @@ -1,5 +1,5 @@ -/* $OpenBSD: pmap_bootstrap.c,v 1.13 2000/02/22 19:27:52 deraadt Exp $ */ -/* $NetBSD: pmap_bootstrap.c,v 1.30 1997/01/07 07:44:01 scottr Exp $ */ +/* $OpenBSD: pmap_bootstrap.c,v 1.14 2001/05/08 17:30:41 aaron Exp $ */ +/* $NetBSD: pmap_bootstrap.c,v 1.50 1999/04/07 06:14:33 scottr Exp $ */ /* * Copyright (c) 1991, 1993 @@ -56,7 +56,7 @@ #include <ufs/mfs/mfs_extern.h> -#include "macrom.h" +#include <mac68k/mac68k/macrom.h> #define PA2VA(v, t) (t)((u_int)(v) - firstpa) @@ -66,30 +66,27 @@ extern char *extiobase, *proc0paddr; extern st_entry_t *Sysseg; extern pt_entry_t *Sysptmap, *Sysmap; -extern int maxmem, physmem; -extern int avail_remaining, avail_range, avail_end; -extern vm_offset_t avail_start, avail_next; -extern vm_offset_t virtual_avail, virtual_end; -extern vm_size_t mem_size; +extern int physmem; +extern paddr_t avail_start; +extern paddr_t avail_end; +extern vaddr_t virtual_avail, virtual_end; +extern vsize_t mem_size; extern int protection_codes[]; /* * These are used to map the RAM: */ -int numranges; /* = 0 == don't use the ranges */ +int numranges; /* = 0 == don't use the ranges */ u_long low[8]; u_long high[8]; -extern int nbnumranges; -extern u_long nbphys[]; -extern u_long nblog[]; -extern signed long nblen[]; -#define VIDMAPSIZE btoc(m68k_round_page(vidlen)) +u_long maxaddr; /* PA of the last physical page */ +int vidlen; +#define VIDMAPSIZE btoc(vidlen) extern u_int32_t mac68k_vidlog; extern u_int32_t mac68k_vidphys; extern u_int32_t videoaddr; extern u_int32_t videorowbytes; extern u_int32_t videosize; -static int vidlen; static u_int32_t newvideoaddr; extern caddr_t ROMBase; @@ -104,6 +101,9 @@ extern caddr_t ROMBase; */ caddr_t CADDR1, CADDR2, vmmap; +void pmap_bootstrap __P((paddr_t, paddr_t)); +void bootstrap_mac68k __P((int)); + /* * Bootstrap the VM system. * @@ -116,17 +116,20 @@ caddr_t CADDR1, CADDR2, vmmap; */ void pmap_bootstrap(nextpa, firstpa) - vm_offset_t nextpa; - register vm_offset_t firstpa; + paddr_t nextpa; + paddr_t firstpa; { - vm_offset_t kstpa, kptpa, vidpa, iiopa, rompa; - vm_offset_t kptmpa, lkptpa, p0upa; + paddr_t kstpa, kptpa, vidpa, iiopa, rompa, kptmpa, lkptpa, p0upa; u_int nptpages, kstsize; + paddr_t avail_next; + int avail_remaining; + int avail_range; int i; - register st_entry_t protoste, *ste; - register pt_entry_t protopte, *pte, *epte; + st_entry_t protoste, *ste; + pt_entry_t protopte, *pte, *epte; - vidlen = ((videosize >> 16) & 0xffff) * videorowbytes + PGOFSET; + vidlen = m68k_round_page(((videosize >> 16) & 0xffff) * videorowbytes + + (mac68k_vidphys & PGOFSET)); /* * Calculate important physical addresses: @@ -177,6 +180,7 @@ pmap_bootstrap(nextpa, firstpa) p0upa = nextpa; nextpa += USPACE; +#if 0 if (nextpa > high[0]) { printf("Failure in BSD boot. nextpa=0x%lx, high[0]=0x%lx.\n", nextpa, high[0]); @@ -185,6 +189,7 @@ pmap_bootstrap(nextpa, firstpa) printf("Older machines may need Mode32 to get that option.\n"); panic("Cannot work with the current memory mappings."); } +#endif /* * Initialize segment table and kernel page table map. @@ -206,7 +211,7 @@ pmap_bootstrap(nextpa, firstpa) * likely be insufficient in the future (at least for the kernel). */ if (mmutype == MMU_68040) { - register int num; + int num; /* * First invalidate the entire "segment table" pages @@ -280,7 +285,10 @@ pmap_bootstrap(nextpa, firstpa) while (pte < epte) { *pte++ = PG_NV; } - pte = &(PA2VA(kptmpa, u_int *))[NPTEPG-1]; + /* + * Initialize the last to point to the page + * table page allocated earlier. + */ *pte = lkptpa | PG_RW | PG_CI | PG_V; } else { /* @@ -315,15 +323,13 @@ pmap_bootstrap(nextpa, firstpa) *pte = lkptpa | PG_RW | PG_CI | PG_V; } /* - * Invalidate all but the final entry in the last kernel PT page - * (u-area PTEs will be validated later). The final entry maps - * the last page of physical memory. + * Invalidate all entries in the last kernel PT page + * (u-area PTEs will be validated later). */ pte = PA2VA(lkptpa, u_int *); - epte = &pte[NPTEPG-1]; + epte = &pte[NPTEPG]; while (pte < epte) *pte++ = PG_NV; - *pte = (0xFFFFF000) | PG_RW | PG_CI | PG_V; /* XXX */ /* * Initialize kernel page table. @@ -365,11 +371,8 @@ pmap_bootstrap(nextpa, firstpa) protopte += NBPG; } /* - * Finally, validate the internal IO space PTEs (RW+CI). - * We do this here since the 320/350 MMU registers (also - * used, but to a lesser extent, on other models) are mapped - * in this range and it would be nice to be able to access - * them after the MMU is turned on. + * Finally, validate the internal IO space, ROM space, and + * framebuffer PTEs (RW+CI). */ pte = PA2VA(iiopa, u_int *); epte = PA2VA(rompa, u_int *); @@ -436,7 +439,7 @@ pmap_bootstrap(nextpa, firstpa) * NOTE: `pte' and `epte' aren't PTEs here. */ pte = PA2VA(p0upa, u_int *); - epte = (u_int *) (PA2VA(p0upa, u_int) + USPACE); + epte = (u_int *)(PA2VA(p0upa, u_int) + USPACE); while (pte < epte) *pte++ = 0; /* @@ -448,12 +451,21 @@ pmap_bootstrap(nextpa, firstpa) /* * VM data structures are now initialized, set up data for * the pmap module. + * + * Note about avail_end: msgbuf is initialized just after + * avail_end in machdep.c. Since the last page is used + * for rebooting the system (code is copied there and + * excution continues from copied code before the MMU + * is disabled), the msgbuf will get trounced between + * reboots if it's placed in the last physical page. + * To work around this, we move avail_end back one more + * page so the msgbuf can be preserved. */ avail_next = avail_start = m68k_round_page(nextpa); avail_remaining = 0; avail_range = -1; for (i = 0; i < numranges; i++) { - if (avail_next >= low[i] && avail_next < high[i]) { + if (low[i] <= avail_next && avail_next < high[i]) { avail_range = i; avail_remaining = high[i] - avail_next; } else if (avail_range != -1) { @@ -461,18 +473,12 @@ pmap_bootstrap(nextpa, firstpa) } } physmem = m68k_btop(avail_remaining + nextpa - firstpa); - avail_remaining -= m68k_round_page(MSGBUFSIZE); - high[numranges - 1] -= m68k_round_page(MSGBUFSIZE); - - /* XXX -- this doesn't look correct to me. */ - while (high[numranges - 1] < low[numranges - 1]) { - numranges--; - high[numranges - 1] -= low[numranges] - high[numranges]; - } - avail_remaining = m68k_trunc_page(avail_remaining); - avail_end = avail_start + avail_remaining; - avail_remaining = m68k_btop(avail_remaining); + maxaddr = high[numranges - 1] - m68k_ptob(1); + high[numranges - 1] -= (round_page(MSGBUFSIZE) + m68k_ptob(1)); + avail_remaining -= (round_page(MSGBUFSIZE) + m68k_ptob(1)); + avail_end = high[numranges - 1]; + avail_remaining = m68k_btop(trunc_page(avail_remaining)); mem_size = m68k_ptob(physmem); virtual_avail = VM_MIN_KERNEL_ADDRESS + (nextpa - firstpa); @@ -484,7 +490,7 @@ pmap_bootstrap(nextpa, firstpa) * absolute "jmp" table. */ { - register int *kp; + int *kp; kp = (int *) &protection_codes; kp[VM_PROT_NONE|VM_PROT_NONE|VM_PROT_NONE] = 0; @@ -517,7 +523,7 @@ pmap_bootstrap(nextpa, firstpa) * MAXKL2SIZE-1: maps last-page page table */ if (mmutype == MMU_68040) { - register int num; + int num; kpm->pm_stfree = ~l2tobm(0); num = roundup((nptpages + 1) * (NPTEPG / SG4_LEV3SIZE), @@ -536,8 +542,8 @@ pmap_bootstrap(nextpa, firstpa) * Allocate some fixed, special purpose kernel virtual addresses */ { - extern vm_offset_t tmp_vpages[]; - vm_offset_t va = virtual_avail; + extern vaddr_t tmp_vpages[]; + vaddr_t va = virtual_avail; CADDR1 = (caddr_t)va; va += NBPG; @@ -559,7 +565,7 @@ bootstrap_mac68k(tc) { extern void zs_init __P((void)); extern caddr_t esym; - vm_offset_t nextpa; + paddr_t nextpa; caddr_t oldROMBase; if (mac68k_machine.do_graybars) @@ -578,14 +584,13 @@ bootstrap_mac68k(tc) printf("Done.\n"); } else { /* MMU not enabled. Fake up ranges. */ - nbnumranges = 0; numranges = 1; low[0] = 0; high[0] = mac68k_machine.mach_memsize * (1024 * 1024); if (mac68k_machine.do_graybars) printf("Faked range to byte 0x%lx.\n", high[0]); } - nextpa = load_addr + (((int)esym + NBPG - 1) & PG_FRAME); + nextpa = load_addr + round_page((vaddr_t)esym); #if MFS if (boothowto & RB_MINIROOT) { @@ -612,15 +617,13 @@ bootstrap_mac68k(tc) panic("Don't know how to relocate video!"); if (mac68k_machine.do_graybars) - printf("Moving ROMBase from %p to %p.\n", - oldROMBase, ROMBase); + printf("Moving ROMBase from %p to %p.\n", oldROMBase, ROMBase); mrg_fixupROMBase(oldROMBase, ROMBase); if (mac68k_machine.do_graybars) printf("Video address 0x%lx -> 0x%lx.\n", - (unsigned long) videoaddr, - (unsigned long) newvideoaddr); + (unsigned long)videoaddr, (unsigned long)newvideoaddr); mac68k_set_io_offsets(IOBase); diff --git a/sys/arch/mac68k/mac68k/trap.c b/sys/arch/mac68k/mac68k/trap.c index b628b9be853..9b63f6411c4 100644 --- a/sys/arch/mac68k/mac68k/trap.c +++ b/sys/arch/mac68k/mac68k/trap.c @@ -1,5 +1,5 @@ -/* $OpenBSD: trap.c,v 1.20 2001/05/05 21:26:38 art Exp $ */ -/* $NetBSD: trap.c,v 1.46 1997/04/07 22:54:44 scottr Exp $ */ +/* $OpenBSD: trap.c,v 1.21 2001/05/08 17:30:41 aaron Exp $ */ +/* $NetBSD: trap.c,v 1.68 1998/12/22 08:47:07 scottr Exp $ */ /* * Copyright (c) 1988 University of Utah. @@ -53,9 +53,15 @@ #include <sys/syscall.h> #include <sys/syslog.h> #include <sys/user.h> +#ifdef KGDB +#include <sys/kgdb.h> +#endif #ifdef KTRACE #include <sys/ktrace.h> #endif +#ifdef DEBUG +#include <dev/cons.h> +#endif #include <machine/db_machdep.h> #include <machine/psl.h> @@ -68,11 +74,17 @@ #include <vm/vm.h> #include <vm/pmap.h> +#if defined(UVM) +#include <uvm/uvm_extern.h> +#endif + #ifdef COMPAT_SUNOS #include <compat/sunos/sunos_syscall.h> extern struct emul emul_sunos; #endif +int astpending; + char *trap_type[] = { "Bus error", "Address error", @@ -99,7 +111,8 @@ short exframesize[] = { FMT1SIZE, /* type 1 - throwaway (68020/030/040) */ FMT2SIZE, /* type 2 - normal 6-word (68020/030/040) */ FMT3SIZE, /* type 3 - FP post-instruction (68040) */ - -1, -1, -1, /* type 4-6 - undefined */ + FMT4SIZE, /* type 4 - LC040 FP exception (68LC040) */ + -1, -1, /* type 5-6 - undefined */ FMT7SIZE, /* type 7 - access error (68040) */ 58, /* type 8 - bus fault (68010) */ FMT9SIZE, /* type 9 - coprocessor mid-instruction (68020/030) */ @@ -130,7 +143,7 @@ int mmupid = -1; #endif /* trap() and syscall() only called from locore */ -void trap __P((int, unsigned, unsigned, struct frame)); +void trap __P((int, u_int, u_int, struct frame)); void syscall __P((register_t, struct frame)); static inline void userret __P((struct proc *p, struct frame *fp, @@ -235,8 +248,8 @@ again: void trap(type, code, v, frame) int type; - unsigned code; - unsigned v; + u_int code; + u_int v; struct frame frame; { extern char fubail[], subail[]; @@ -244,13 +257,17 @@ trap(type, code, v, frame) extern char trap0[], trap1[], trap2[], trap12[], trap15[], illinst[]; #endif struct proc *p; - int i; + int i, s; u_int ucode; int typ = 0; u_quad_t sticks; union sigval sv; +#if defined(UVM) + uvmexp.traps++; +#else cnt.v_trap++; +#endif p = curproc; ucode = 0; @@ -266,21 +283,44 @@ trap(type, code, v, frame) p = &proc0; #ifdef DIAGNOSTIC if (p->p_addr == NULL) - panic("trap: type 0x%x, code 0x%x, v 0x%x--no pcb", + panic("trap: type 0x%x, code 0x%x, v 0x%x -- no pcb\n", type, code, v); #endif switch (type) { default: -dopanic: - printf("trap type %d, code = %x, v= %x\n", type, code, v); + dopanic: + printf("trap type %d, code = 0x%x, v = 0x%x\n", type, code, v); + printf("%s program counter = 0x%x\n", + (type & T_USER) ? "user" : "kernel", frame.f_pc); + /* + * Let the kernel debugger see the trap frame that + * caused us to panic. This is a convenience so + * one can see registers at the point of failure. + */ + s = splhigh(); +#ifdef KGDB + /* If connected, step or cont returns 1 */ + if (kgdb_trap(type, (db_regs_t *)&frame)) + goto kgdb_cont; +#endif #ifdef DDB - if (kdb_trap(type, (db_regs_t *) &frame)) - return; + (void)kdb_trap(type, (db_regs_t *)&frame); #endif +#ifdef KGDB + kgdb_cont; +#endif + splx(s); + if (panicstr) { + printf("trap during panic!\n"); +#ifdef DEBUG + /* XXX should be a machine-dependent hook */ + printf("(press a key)\n"); (void)cngetc(); +#endif + } regdump(&frame, 128); type &= ~T_USER; - if ((unsigned)type < trap_types) + if ((u_int)type < trap_types) panic(trap_type[type]); panic("trap"); @@ -296,7 +336,7 @@ dopanic: copyfault: frame.f_stackadj = exframesize[frame.f_format]; frame.f_format = frame.f_vector = 0; - frame.f_pc = (int) p->p_addr->u_pcb.pcb_onfault; + frame.f_pc = (int)p->p_addr->u_pcb.pcb_onfault; return; case T_BUSERR|T_USER: /* Bus error */ @@ -311,7 +351,7 @@ copyfault: break; case T_ILLINST|T_USER: /* Illegal instruction fault */ - ucode = frame.f_format; /* XXX was ILL_PRIVIN_FAULT */ + ucode = frame.f_format; /* XXX was ILL_PRIVIN_FAULT */ typ = ILL_ILLOPC; i = SIGILL; v = frame.f_pc; @@ -328,25 +368,22 @@ copyfault: */ case T_ZERODIV|T_USER: /* Divide by zero trap */ ucode = frame.f_format; - type = FPE_INTDIV; + typ = FPE_INTDIV; i = SIGFPE; v = frame.f_pc; break; case T_CHKINST|T_USER: /* CHK instruction trap */ ucode = frame.f_format; - type = FPE_FLTSUB; i = SIGFPE; - v = frame.f_pc; break; case T_TRAPVINST|T_USER: /* TRAPV instruction trap */ ucode = frame.f_format; - type = ILL_ILLTRP; + typ = ILL_ILLTRP; i = SIGILL; v = frame.f_pc; - break; - + break; /* * User coprocessor violation */ @@ -381,10 +418,10 @@ copyfault: case T_ILLINST: /* fnop generates this, apparently. */ case T_FPEMULI: case T_FPEMULD: { - extern int *nofault; + extern label_t *nofault; if (nofault) /* If we're probing. */ - longjmp((label_t *) nofault); + longjmp(nofault); if (type == T_ILLINST) printf("Kernel Illegal Instruction trap.\n"); else @@ -405,8 +442,6 @@ copyfault: p->p_pid); i = SIGILL; #endif - typ = FPE_FLTINV; - v = frame.f_pc; break; case T_COPERR: /* Kernel coprocessor violation */ @@ -431,15 +466,20 @@ copyfault: break; /* - * Trace traps. + * XXX: Trace traps are a nightmare. * - * M68k *BSD uses trap #2, - * SUN 3.x uses trap #15, - * KGDB uses trap #15 (for kernel breakpoints; handled elsewhere). + * HP-UX uses trap #1 for breakpoints, + * OpenBSD/m68k uses trap #2, + * SUN 3.x uses trap #15, + * DDB and KGDB uses trap #15 (for kernel breakpoints; + * handled elsewhere). * - * M68k *BSD traps get mapped by locore.s into T_TRACE. + * OpenBSD and HP-UX traps both get mapped by locore.s into T_TRACE. * SUN 3.x traps get passed through as T_TRAP15 and are not really * supported yet. + * + * XXX: We should never get kernel-mode T_TRACE or T_TRAP15 + * XXX: because locore.s now gives them special treatment. */ case T_TRACE: /* Kernel trace trap */ case T_TRAP15: /* SUN trace trap */ @@ -466,7 +506,7 @@ copyfault: /* * SunOS uses Trap #2 for a "CPU cache flush" * Just flush the on-chip caches and return. - * XXX - Too bad m68k BSD uses trap 2... + * XXX - Too bad OpenBSD uses trap 2... */ if (p->p_emul == &emul_sunos) { ICIA(); @@ -501,32 +541,52 @@ copyfault: if (ssir & SIR_SERIAL) { void zssoft __P((int)); siroff(SIR_SERIAL); +#if defined(UVM) + uvmexp.softs++; +#else cnt.v_soft++; +#endif zssoft(0); } if (ssir & SIR_NET) { void netintr __P((void)); siroff(SIR_NET); +#if defined(UVM) + uvmexp.softs++; +#else cnt.v_soft++; +#endif netintr(); } if (ssir & SIR_CLOCK) { void softclock __P((void)); siroff(SIR_CLOCK); +#if defined(UVM) + uvmexp.softs++; +#else cnt.v_soft++; +#endif softclock(); } if (ssir & SIR_DTMGR) { void mrg_execute_deferred __P((void)); siroff(SIR_DTMGR); +#if defined(UVM) + uvmexp.softs++; +#else cnt.v_soft++; +#endif mrg_execute_deferred(); } /* * If this was not an AST trap, we are all done. */ if (type != (T_ASTFLT|T_USER)) { +#if defined(UVM) + uvmexp.traps--; +#else cnt.v_trap--; +#endif return; } spl0(); @@ -548,7 +608,7 @@ copyfault: case T_MMUFLT|T_USER: /* page fault */ { - vm_offset_t va; + vaddr_t va; struct vmspace *vm = p->p_vmspace; vm_map_t map; int rv; @@ -576,21 +636,31 @@ copyfault: if (WRFAULT(code)) { vftype = VM_PROT_WRITE; ftype = VM_PROT_READ | VM_PROT_WRITE; - } else + } + else vftype = ftype = VM_PROT_READ; - va = trunc_page((vm_offset_t) v); + va = trunc_page((vaddr_t)v); #ifdef DEBUG if (map == kernel_map && va == 0) { printf("trap: bad kernel access at %x\n", v); goto dopanic; } #endif +#if defined(UVM) + rv = uvm_fault(map, va, 0, ftype); +#ifdef DEBUG + if (rv && MDB_ISPID(p->p_pid)) + printf("uvm_fault(%p, 0x%lx, 0, 0x%x) -> 0x%x\n", + map, va, ftype, rv); +#endif +#else /* ! UVM */ rv = vm_fault(map, va, ftype, FALSE); #ifdef DEBUG if (rv && MDB_ISPID(p->p_pid)) printf("vm_fault(%p, %lx, %x, 0) -> %x\n", map, va, ftype, rv); #endif +#endif /* UVM */ /* * If this was a stack access, we keep track of the maximum * accessed stack size. Also, if vm_fault gets a protection @@ -601,7 +671,7 @@ copyfault: if ((vm != NULL && (caddr_t)va >= vm->vm_maxsaddr) && map != kernel_map) { if (rv == KERN_SUCCESS) { - unsigned nss; + u_int nss; nss = btoc(USRSTACK-(unsigned)va); if (nss > vm->vm_ssize) @@ -613,7 +683,7 @@ copyfault: if (type == T_MMUFLT) { #if defined(M68040) if (mmutype == MMU_68040) - (void) writeback(&frame, 1); + (void)writeback(&frame, 1); #endif return; } @@ -622,8 +692,13 @@ copyfault: if (type == T_MMUFLT) { if (p->p_addr->u_pcb.pcb_onfault) goto copyfault; - printf("vm_fault(%x, %x, %x, 0) -> %x\n", - (unsigned) map, (unsigned) va, ftype, rv); +#if defined(UVM) + printf("uvm_fault(%p, 0x%lx, 0, 0x%x) -> 0x%x\n", + map, va, ftype, rv); +#else + printf("vm_fault(%p, %lx, %x, 0) -> %x\n", + map, va, ftype, rv); +#endif printf(" type %x, code [mmu,,ssw]: %x\n", type, code); goto dopanic; @@ -709,14 +784,14 @@ writeback(fp, docachepush) * cache push after a signal handler has been called. */ if (docachepush) { - pmap_enter(pmap_kernel(), (vm_offset_t)vmmap, - trunc_page((vaddr_t)f->f_fa), VM_PROT_WRITE, TRUE, - VM_PROT_WRITE); + pmap_enter(pmap_kernel(), (vaddr_t)vmmap, + trunc_page((vaddr_t)f->f_fa), VM_PROT_WRITE, + TRUE, VM_PROT_WRITE); fa = (u_int)&vmmap[(f->f_fa & PGOFSET) & ~0xF]; bcopy((caddr_t)&f->f_pd0, (caddr_t)fa, 16); - DCFL(pmap_extract(pmap_kernel(), (vm_offset_t)fa)); - pmap_remove(pmap_kernel(), (vm_offset_t)vmmap, - (vm_offset_t)&vmmap[NBPG]); + DCFL(pmap_extract(pmap_kernel(), (vaddr_t)fa)); + pmap_remove(pmap_kernel(), (vaddr_t)vmmap, + (vaddr_t)&vmmap[NBPG]); } else printf("WARNING: pid %d(%s) uid %d: CPUSH not done\n", p->p_pid, p->p_comm, p->p_ucred->cr_uid); @@ -895,7 +970,7 @@ writeback(fp, docachepush) */ if (err) err = SIGSEGV; - return(err); + return (err); } #ifdef DEBUG @@ -934,13 +1009,13 @@ dumpwb(num, s, a, d) u_int a, d; { struct proc *p = curproc; - vm_offset_t pa; + paddr_t pa; printf(" writeback #%d: VA %x, data %x, SZ=%s, TT=%s, TM=%s\n", num, a, d, f7sz[(s & SSW4_SZMASK) >> 5], f7tt[(s & SSW4_TTMASK) >> 3], f7tm[s & SSW4_TMMASK]); printf(" PA "); - pa = pmap_extract(p->p_vmspace->vm_map.pmap, (vm_offset_t)a); + pa = pmap_extract(p->p_vmspace->vm_map.pmap, (vaddr_t)a); if (pa == 0) printf("<invalid address>"); else @@ -966,7 +1041,11 @@ syscall(code, frame) register_t args[8], rval[2]; u_quad_t sticks; +#if defined(UVM) + uvmexp.syscalls++; +#else cnt.v_syscall++; +#endif if (!USERMODE(frame.f_sr)) panic("syscall"); p = curproc; diff --git a/sys/arch/mac68k/mac68k/vectors.s b/sys/arch/mac68k/mac68k/vectors.s index e29d45ac283..675deaa1cc1 100644 --- a/sys/arch/mac68k/mac68k/vectors.s +++ b/sys/arch/mac68k/mac68k/vectors.s @@ -1,5 +1,5 @@ -/* $OpenBSD: vectors.s,v 1.2 1996/05/26 18:36:36 briggs Exp $ */ -| $NetBSD: vectors.s,v 1.6 1995/01/21 05:21:26 briggs Exp $ +/* $OpenBSD: vectors.s,v 1.3 2001/05/08 17:30:41 aaron Exp $ */ +| $NetBSD: vectors.s,v 1.9 1997/09/03 06:16:24 scottr Exp $ | Copyright (c) 1988 University of Utah | Copyright (c) 1990 Regents of the University of California. @@ -35,104 +35,97 @@ | | @(#)vectors.s 7.2 (Berkeley) 5/7/91 | - .text - .globl _buserr,_addrerr - .globl _illinst,_zerodiv,_chkinst,_trapvinst,_privinst,_trace - .globl _badtrap - .globl _spurintr,_lev1intr,_lev2intr,_lev3intr - .globl _lev4intr,_lev5intr,_lev6intr,_lev7intr - .globl _trap0,_trap1,_trap2,_trap15 - .globl _alinetrap - .globl _fpfline, _fpunsupp, _fpfault - .globl _trap12 - .globl _mrg_tracetrap - .globl _jmp0panic -Lvectab: - .long 0x60000000+_jmp0panic-2 /* 0: bra 0x400:w (unused reset SSP) */ - .long 0 /* 1: NOT USED (reset PC) */ - .long _buserr /* 2: bus error */ - .long _addrerr /* 3: address error */ - .long _illinst /* 4: illegal instruction */ - .long _zerodiv /* 5: zero divide */ - .long _chkinst /* 6: CHK instruction */ - .long _trapvinst /* 7: TRAPV instruction */ - .long _privinst /* 8: privilege violation */ +#define BADTRAP16 \ + VECTOR(badtrap) ; VECTOR(badtrap) ; \ + VECTOR(badtrap) ; VECTOR(badtrap) ; \ + VECTOR(badtrap) ; VECTOR(badtrap) ; \ + VECTOR(badtrap) ; VECTOR(badtrap) ; \ + VECTOR(badtrap) ; VECTOR(badtrap) ; \ + VECTOR(badtrap) ; VECTOR(badtrap) ; \ + VECTOR(badtrap) ; VECTOR(badtrap) ; \ + VECTOR(badtrap) ; VECTOR(badtrap) + + .text +GLOBAL(vectab) + VECTOR_UNUSED /* 0: NOT USED (reset SSP) */ + VECTOR_UNUSED /* 1: NOT USED (reset PC) */ + VECTOR_UNUSED /* 2: bus error */ + VECTOR_UNUSED /* 3: address error */ + VECTOR(illinst) /* 4: illegal instruction */ + VECTOR(zerodiv) /* 5: zero divide */ + VECTOR(chkinst) /* 6: CHK instruction */ + VECTOR(trapvinst) /* 7: TRAPV instruction */ + VECTOR(privinst) /* 8: privilege violation */ #if defined(MRG_TRACE) - .long _mrg_tracetrap /* 9: trace */ + VECTOR(mrg_tracetrap) /* 9: trace */ #else /* MRG_TRACE */ - .long _trace /* 9: trace */ + VECTOR(trace) /* 9: trace */ #endif /* MRG_TRACE */ - .long _alinetrap /* 10: line 1010 emulator ; see macromasm.s */ - .long _fpfline /* 11: line 1111 emulator */ - .long _badtrap /* 12: unassigned, reserved */ - .long _coperr /* 13: coprocessor protocol violation */ - .long _fmterr /* 14: format error */ - .long _badtrap /* 15: uninitialized interrupt vector */ - .long _badtrap /* 16: unassigned, reserved */ - .long _badtrap /* 17: unassigned, reserved */ - .long _badtrap /* 18: unassigned, reserved */ - .long _badtrap /* 19: unassigned, reserved */ - .long _badtrap /* 20: unassigned, reserved */ - .long _badtrap /* 21: unassigned, reserved */ - .long _badtrap /* 22: unassigned, reserved */ - .long _badtrap /* 23: unassigned, reserved */ - .long _spurintr /* 24: spurious interrupt */ - .long _lev1intr /* 25: level 1 interrupt autovector */ - .long _lev2intr /* 26: level 2 interrupt autovector */ - .long _lev3intr /* 27: level 3 interrupt autovector */ - .long _lev4intr /* 28: level 4 interrupt autovector */ - .long _lev5intr /* 29: level 5 interrupt autovector */ - .long _lev6intr /* 30: level 6 interrupt autovector */ - .long _lev7intr /* 31: level 7 interrupt autovector */ - .long _trap0 /* 32: syscalls */ - .long _trap1 /* 33: sigreturn syscall or breakpoint */ - .long _trap2 /* 34: breakpoint or sigreturn syscall */ - .long _illinst /* 35: TRAP instruction vector */ - .long _illinst /* 36: TRAP instruction vector */ - .long _illinst /* 37: TRAP instruction vector */ - .long _illinst /* 38: TRAP instruction vector */ - .long _illinst /* 39: TRAP instruction vector */ - .long _illinst /* 40: TRAP instruction vector */ - .long _illinst /* 41: TRAP instruction vector */ - .long _illinst /* 42: TRAP instruction vector */ - .long _illinst /* 43: TRAP instruction vector */ - .long _trap12 /* 44: TRAP instruction vector */ - .long _illinst /* 45: TRAP instruction vector */ - .long _illinst /* 46: TRAP instruction vector */ - .long _trap15 /* 47: TRAP instruction vector */ + VECTOR(alinetrap) /* 10: line 1010 emulator ; see macromasm.s */ + VECTOR(fpfline) /* 11: line 1111 emulator */ + VECTOR(badtrap) /* 12: unassigned, reserved */ + VECTOR(coperr) /* 13: coprocessor protocol violation */ + VECTOR(fmterr) /* 14: format error */ + VECTOR(badtrap) /* 15: uninitialized interrupt vector */ + VECTOR(badtrap) /* 16: unassigned, reserved */ + VECTOR(badtrap) /* 17: unassigned, reserved */ + VECTOR(badtrap) /* 17: unassigned, reserved */ + VECTOR(badtrap) /* 19: unassigned, reserved */ + VECTOR(badtrap) /* 20: unassigned, reserved */ + VECTOR(badtrap) /* 21: unassigned, reserved */ + VECTOR(badtrap) /* 22: unassigned, reserved */ + VECTOR(badtrap) /* 23: unassigned, reserved */ + VECTOR(spurintr) /* 24: spurious interrupt */ + VECTOR(lev1intr) /* 25: level 1 interrupt autovector */ + VECTOR(lev2intr) /* 26: level 2 interrupt autovector */ + VECTOR(lev3intr) /* 27: level 3 interrupt autovector */ + VECTOR(lev4intr) /* 28: level 4 interrupt autovector */ + VECTOR(lev5intr) /* 29: level 5 interrupt autovector */ + VECTOR(lev6intr) /* 30: level 6 interrupt autovector */ + VECTOR(lev7intr) /* 31: level 7 interrupt autovector */ + VECTOR(trap0) /* 32: syscalls */ + VECTOR(trap1) /* 33: sigreturn syscall or breakpoint */ + VECTOR(trap2) /* 34: breakpoint or sigreturn syscall */ + VECTOR(illinst) /* 35: TRAP instruction vector */ + VECTOR(illinst) /* 36: TRAP instruction vector */ + VECTOR(illinst) /* 37: TRAP instruction vector */ + VECTOR(illinst) /* 38: TRAP instruction vector */ + VECTOR(illinst) /* 39: TRAP instruction vector */ + VECTOR(illinst) /* 40: TRAP instruction vector */ + VECTOR(illinst) /* 41: TRAP instruction vector */ + VECTOR(illinst) /* 42: TRAP instruction vector */ + VECTOR(illinst) /* 43: TRAP instruction vector */ + VECTOR(trap12) /* 44: TRAP instruction vector */ + VECTOR(illinst) /* 45: TRAP instruction vector */ + VECTOR(illinst) /* 46: TRAP instruction vector */ + VECTOR(trap15) /* 47: TRAP instruction vector */ #ifdef FPSP - .globl bsun, inex, dz, unfl, operr, ovfl, snan - .long bsun /* 48: FPCP branch/set on unordered cond */ - .long inex /* 49: FPCP inexact result */ - .long dz /* 50: FPCP divide by zero */ - .long unfl /* 51: FPCP underflow */ - .long operr /* 52: FPCP operand error */ - .long ovfl /* 53: FPCP overflow */ - .long snan /* 54: FPCP signalling NAN */ + ASVECTOR(bsun) /* 48: FPCP branch/set on unordered cond */ + ASVECTOR(inex) /* 49: FPCP inexact result */ + ASVECTOR(dz) /* 50: FPCP divide by zero */ + ASVECTOR(unfl) /* 51: FPCP underflow */ + ASVECTOR(operr) /* 52: FPCP operand error */ + ASVECTOR(ovfl) /* 53: FPCP overflow */ + ASVECTOR(snan) /* 54: FPCP signalling NAN */ #else - .globl _fpfault - .long _fpfault /* 48: FPCP branch/set on unordered cond */ - .long _fpfault /* 49: FPCP inexact result */ - .long _fpfault /* 50: FPCP divide by zero */ - .long _fpfault /* 51: FPCP underflow */ - .long _fpfault /* 52: FPCP operand error */ - .long _fpfault /* 53: FPCP overflow */ - .long _fpfault /* 54: FPCP signalling NAN */ + VECTOR(fpfault) /* 48: FPCP branch/set on unordered cond */ + VECTOR(fpfault) /* 49: FPCP inexact result */ + VECTOR(fpfault) /* 50: FPCP divide by zero */ + VECTOR(fpfault) /* 51: FPCP underflow */ + VECTOR(fpfault) /* 52: FPCP operand error */ + VECTOR(fpfault) /* 53: FPCP overflow */ + VECTOR(fpfault) /* 54: FPCP signalling NAN */ #endif - .long _fpunsupp /* 55: FPCP unimplemented data type */ - .long _badtrap /* 56: unassigned, reserved */ - .long _badtrap /* 57: unassigned, reserved */ - .long _badtrap /* 58: unassigned, reserved */ - .long _badtrap /* 59: unassigned, reserved */ - .long _badtrap /* 60: unassigned, reserved */ - .long _badtrap /* 61: unassigned, reserved */ - .long _badtrap /* 62: unassigned, reserved */ - .long _badtrap /* 63: unassigned, reserved */ -#define BADTRAP16 .long _badtrap,_badtrap,_badtrap,_badtrap,\ - _badtrap,_badtrap,_badtrap,_badtrap,\ - _badtrap,_badtrap,_badtrap,_badtrap,\ - _badtrap,_badtrap,_badtrap,_badtrap + VECTOR(fpunsupp) /* 55: FPCP unimplemented data type */ + VECTOR(badtrap) /* 56: unassigned, reserved */ + VECTOR(badtrap) /* 57: unassigned, reserved */ + VECTOR(badtrap) /* 58: unassigned, reserved */ + VECTOR(badtrap) /* 59: unassigned, reserved */ + VECTOR(badtrap) /* 60: unassigned, reserved */ + VECTOR(badtrap) /* 61: unassigned, reserved */ + VECTOR(badtrap) /* 62: unassigned, reserved */ + VECTOR(badtrap) /* 63: unassigned, reserved */ BADTRAP16 /* 64-255: user interrupt vectors */ BADTRAP16 /* 64-255: user interrupt vectors */ BADTRAP16 /* 64-255: user interrupt vectors */ diff --git a/sys/arch/mac68k/mac68k/via.c b/sys/arch/mac68k/mac68k/via.c index 76cd847ca90..2866fe5ef33 100644 --- a/sys/arch/mac68k/mac68k/via.c +++ b/sys/arch/mac68k/mac68k/via.c @@ -1,4 +1,4 @@ -/* $OpenBSD: via.c,v 1.15 1998/05/03 07:16:53 gene Exp $ */ +/* $OpenBSD: via.c,v 1.16 2001/05/08 17:30:41 aaron Exp $ */ /* $NetBSD: via.c,v 1.58 1997/03/04 04:11:52 scottr Exp $ */ /*- @@ -112,7 +112,7 @@ void *slotptab[7] = { }; void -VIA_initialize() +via_init() { /* Initialize VIA1 */ /* set all timers to 0 */ diff --git a/sys/arch/mac68k/mac68k/vm_machdep.c b/sys/arch/mac68k/mac68k/vm_machdep.c index 77246b6780c..af1dde63019 100644 --- a/sys/arch/mac68k/mac68k/vm_machdep.c +++ b/sys/arch/mac68k/mac68k/vm_machdep.c @@ -1,5 +1,5 @@ -/* $OpenBSD: vm_machdep.c,v 1.18 2000/06/08 22:25:20 niklas Exp $ */ -/* $NetBSD: vm_machdep.c,v 1.21 1996/09/16 18:00:31 scottr Exp $ */ +/* $OpenBSD: vm_machdep.c,v 1.19 2001/05/08 17:30:41 aaron Exp $ */ +/* $NetBSD: vm_machdep.c,v 1.29 1998/07/28 18:34:55 thorpej Exp $ */ /* * Copyright (c) 1988 University of Utah. @@ -59,6 +59,10 @@ #include <vm/vm_kern.h> #include <vm/vm_map.h> +#if defined(UVM) +#include <uvm/uvm_extern.h> +#endif + #include <machine/cpu.h> #include <machine/pmap.h> #include <machine/pte.h> @@ -77,13 +81,14 @@ void savectx __P((struct pcb *)); */ void cpu_fork(p1, p2, stack, stacksize) - register struct proc *p1, *p2; + struct proc *p1, *p2; void *stack; size_t stacksize; { - register struct pcb *pcb = &p2->p_addr->u_pcb; - register struct trapframe *tf; - register struct switchframe *sf; + void child_return __P((struct proc *, struct frame)); /* XXX */ + struct pcb *pcb = &p2->p_addr->u_pcb; + struct trapframe *tf; + struct switchframe *sf; extern struct pcb *curpcb; p2->p_md.md_flags = p1->p_md.md_flags; @@ -92,14 +97,13 @@ cpu_fork(p1, p2, stack, stacksize) savectx(curpcb); *pcb = p1->p_addr->u_pcb; - PMAP_ACTIVATE(p2->p_vmspace->vm_map.pmap, pcb, 0); - /* * Copy the trap frame and arrange for the child to return directly * through return_to_user(). */ tf = (struct trapframe *)((u_int)p2->p_addr + USPACE) -1; p2->p_md.md_regs = (int *)tf; + *tf = *(struct trapframe *)p1->p_md.md_regs; /* @@ -135,8 +139,8 @@ cpu_set_kpc(p, pc, arg) struct switchframe *sf; pcbp = &p->p_addr->u_pcb; - sf = (struct switchframe *) pcbp->pcb_regs[11]; - sf->sf_pc = (u_int) proc_trampoline; + sf = (struct switchframe *)pcbp->pcb_regs[11]; + sf->sf_pc = (u_int)proc_trampoline; pcbp->pcb_regs[6] = (int)pc; /* A2 */ pcbp->pcb_regs[7] = (int)p; /* A3 */ } @@ -155,8 +159,12 @@ cpu_exit(p) struct proc *p; { - (void) splhigh(); + (void)splhigh(); +#if defined(UVM) + uvmexp.swtch++; +#else cnt.v_swtch++; +#endif switch_exit(p); for(;;); /* Get rid of a compile warning */ /* NOTREACHED */ @@ -183,8 +191,8 @@ cpu_coredump(p, vp, cred, chdr) int error; struct md_core md_core; struct coreseg cseg; - register struct user *up = p->p_addr; - register int i; + struct user *up = p->p_addr; + int i; CORE_SETMAGIC(*chdr, COREMAGIC, MID_M68K, 0); chdr->c_hdrsize = ALIGN(sizeof(*chdr)); @@ -193,9 +201,9 @@ cpu_coredump(p, vp, cred, chdr) /* Save integer registers. */ { - register struct frame *f; + struct frame *f; - f = (struct frame*) p->p_md.md_regs; + f = (struct frame*)p->p_md.md_regs; for (i = 0; i < 16; i++) { md_core.intreg.r_regs[i] = f->f_regs[i]; } @@ -203,7 +211,7 @@ cpu_coredump(p, vp, cred, chdr) md_core.intreg.r_pc = f->f_pc; } if (fputype) { - register struct fpframe *f; + struct fpframe *f; f = &up->u_pcb.pcb_fpregs; m68881_save(f); @@ -240,14 +248,14 @@ cpu_coredump(p, vp, cred, chdr) /* * Move pages from one kernel virtual address to another. * Both addresses are assumed to reside in the Sysmap, - * and size must be a multiple of CLSIZE. + * and size must be a multiple of PAGE_SIZE. */ void pagemove(from, to, size) - register caddr_t from, to; + caddr_t from, to; size_t size; { - register vm_offset_t pa; + vm_offset_t pa; #ifdef DEBUG if (size % PAGE_SIZE) @@ -258,11 +266,11 @@ pagemove(from, to, size) #ifdef DEBUG if (pa == 0) panic("pagemove 2"); - if (pmap_extract(pmap_kernel(), (vm_offset_t) to) != 0) + if (pmap_extract(pmap_kernel(), (vm_offset_t)to) != 0) panic("pagemove 3"); #endif pmap_remove(pmap_kernel(), - (vm_offset_t)from, (vm_offset_t) from + PAGE_SIZE); + (vm_offset_t)from, (vm_offset_t)from + PAGE_SIZE); pmap_enter(pmap_kernel(), (vm_offset_t)to, pa, VM_PROT_READ|VM_PROT_WRITE, 1, VM_PROT_READ|VM_PROT_WRITE); @@ -272,8 +280,6 @@ pagemove(from, to, size) } } -void TBIAS __P((void)); - /* * Map `size' bytes of physical memory starting at `paddr' into * kernel VA space at `vaddr'. Read/write and cache-inhibit status @@ -282,10 +288,10 @@ void TBIAS __P((void)); void physaccess(vaddr, paddr, size, prot) caddr_t vaddr, paddr; - register int size, prot; + int size, prot; { - register pt_entry_t *pte; - register u_int page; + pt_entry_t *pte; + u_int page; pte = kvtopte(vaddr); page = (u_int)paddr & PG_FRAME; @@ -296,14 +302,12 @@ physaccess(vaddr, paddr, size, prot) TBIAS(); } -void physunaccess __P((caddr_t, register int)); - void physunaccess(vaddr, size) caddr_t vaddr; - register int size; + int size; { - register pt_entry_t *pte; + pt_entry_t *pte; pte = kvtopte(vaddr); for (size = btoc(size); size; size--) @@ -332,14 +336,14 @@ setredzone(pte, vaddr) { } -int kvtop __P((register caddr_t addr)); +int kvtop __P((caddr_t addr)); /* * Convert kernel VA to physical address */ int kvtop(addr) - register caddr_t addr; + caddr_t addr; { vm_offset_t va; @@ -352,76 +356,77 @@ kvtop(addr) extern vm_map_t phys_map; /* - * Map an IO request into kernel virtual address space. Requests fall into - * one of five catagories: + * Map an IO request into kernel virtual address space. * - * B_PHYS|B_UAREA: User u-area swap. - * Address is relative to start of u-area (p_addr). - * B_PHYS|B_PAGET: User page table swap. - * Address is a kernel VA in usrpt (Usrptmap). - * B_PHYS|B_DIRTY: Dirty page push. - * Address is a VA in proc2's address space. - * B_PHYS|B_PGIN: Kernel pagein of user pages. - * Address is VA in user's address space. - * B_PHYS: User "raw" IO request. - * Address is VA in user's address space. - * - * All requests are (re)mapped into kernel VA space via the useriomap - * (a name with only slightly more meaning than "kernelmap") + * XXX we allocate KVA space by using kmem_alloc_wait which we know + * allocates space without backing physical memory. This implementation + * is a total crock, the multiple mappings of these physical pages should + * be reflected in the higher-level VM structures to avoid problems. */ -/*ARGSUSED*/ void -vmapbuf(bp, sz) - register struct buf *bp; - vm_size_t sz; +vmapbuf(bp, len) + struct buf *bp; + vm_size_t len; { - register int npf; - register caddr_t addr; - register long flags = bp->b_flags; - struct proc *p; - int off; - vm_offset_t kva; - register vm_offset_t pa; + struct pmap *upmap, *kpmap; + vm_offset_t uva; /* User VA (map from) */ + vm_offset_t kva; /* Kernel VA (new to) */ + vm_offset_t pa; /* physical address */ + vm_size_t off; - if ((flags & B_PHYS) == 0) + if ((bp->b_flags & B_PHYS) == 0) panic("vmapbuf"); - addr = bp->b_saveaddr = bp->b_un.b_addr; - off = (int)addr & PGOFSET; - p = bp->b_proc; - npf = btoc(round_page(bp->b_bcount + off)); - kva = kmem_alloc_wait(phys_map, ctob(npf)); - bp->b_un.b_addr = (caddr_t) (kva + off); - while (npf--) { - pa = pmap_extract(vm_map_pmap(&p->p_vmspace->vm_map), - (vm_offset_t)addr); + + uva = trunc_page((vaddr_t)(bp->b_saveaddr = bp->b_data)); + off = (vm_offset_t)bp->b_data - uva; + len = round_page(off + len); +#if defined(UVM) + kva = uvm_km_valloc_wait(phys_map, len); +#else + kva = kmem_alloc_wait(phys_map, len); +#endif + bp->b_data = (caddr_t)(kva + off); + + upmap = vm_map_pmap(&bp->b_proc->p_vmspace->vm_map); + kpmap = vm_map_pmap(phys_map); + do { + pa = pmap_extract(upmap, uva); if (pa == 0) panic("vmapbuf: null page frame"); - pmap_enter(vm_map_pmap(phys_map), kva, trunc_page(pa), - VM_PROT_READ|VM_PROT_WRITE, TRUE, 0); - addr += PAGE_SIZE; + pmap_enter(kpmap, kva, pa, VM_PROT_READ|VM_PROT_WRITE, TRUE, 0); + uva += PAGE_SIZE; kva += PAGE_SIZE; - } + len -= PAGE_SIZE; + } while (len); } /* * Free the io map PTEs associated with this IO operation. - * We also invalidate the TLB entries and restore the original b_addr. */ -/*ARGSUSED*/ void -vunmapbuf(bp, sz) - register struct buf *bp; - vm_size_t sz; +vunmapbuf(bp, len) + struct buf *bp; + vm_size_t len; { - register int npf; - register caddr_t addr = bp->b_un.b_addr; vm_offset_t kva; + vm_size_t off; if ((bp->b_flags & B_PHYS) == 0) panic("vunmapbuf"); - npf = btoc(round_page(bp->b_bcount + ((int)addr & PGOFSET))); - kva = (vm_offset_t)((int)addr & ~PGOFSET); - kmem_free_wakeup(phys_map, kva, ctob(npf)); - bp->b_un.b_addr = bp->b_saveaddr; - bp->b_saveaddr = NULL; + + kva = trunc_page((vaddr_t)bp->b_data); + off = (vm_offset_t)bp->b_data - kva; + len = round_page(off + len); + + /* + * pmap_remove() is unnecessary here, as kmem_free_wakeup() + * will do it for us. + */ +#if defined(UVM) + uvm_km_free_wakeup(phys_map, kva, len); +#else + kmem_free_wakeup(phys_map, kva, len); +#endif + bp->b_data = bp->b_saveaddr; + bp->b_saveaddr = 0; } |