first commit of M68060 and FPU_EMULATE support.
M68060 support by YAMASAKI Yasushi, few arranged by me.
This commit is contained in:
parent
121971f622
commit
0e58d64c9e
|
@ -1,4 +1,4 @@
|
|||
# $NetBSD: ALL,v 1.7 1996/12/28 23:30:16 pk Exp $
|
||||
# $NetBSD: ALL,v 1.8 1997/01/13 14:04:42 oki Exp $
|
||||
|
||||
#
|
||||
# ALL -- everything that's currently supported
|
||||
|
@ -13,6 +13,7 @@ options EXEC_AOUT # a.out format executables
|
|||
# different CPU types; you must have at least the correct one; REQUIRED
|
||||
options M68030
|
||||
options M68040
|
||||
options M68060
|
||||
|
||||
# time zone RTC is expected to be set in; REQUIRED
|
||||
options TIMEZONE=-540 # Set the timezone that the kernel will use
|
||||
|
@ -44,7 +45,7 @@ options COMPAT_44 # compatibility with 4.4BSD binaries
|
|||
options COMPAT_09 # compatibility with NetBSD 0.9
|
||||
options COMPAT_10 # compatibility with NetBSD 1.0
|
||||
options COMPAT_11 # compatibility with NetBSD 1.1
|
||||
options COMPAT_12
|
||||
options COMPAT_12 # compatibility with NetBSD 1.2
|
||||
options COMPAT_M68K4K # NetBSD/m68k4k binaries
|
||||
options TCP_COMPAT_42 # compatibility with 4.2BSD TCP/IP
|
||||
|
||||
|
@ -82,6 +83,8 @@ options TUN # tunnelling
|
|||
#options INSECURE # Disable kernel security.
|
||||
options MACHINE_NONCONTIG # support for noncontig memory
|
||||
options DEBUG # extra kernel debugging support
|
||||
options FPU_EMULATE # software fpu emulation
|
||||
options M060SP # int/fp emulation for MC68060
|
||||
options FPSP # floating point emulation for MC68040
|
||||
options ITEKANJI # Kanji display for console
|
||||
options PANICBUTTON # enable interrupt switch
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# $NetBSD: Makefile.x68k,v 1.9 1996/12/01 06:12:40 jonathan Exp $
|
||||
# $NetBSD: Makefile.x68k,v 1.10 1997/01/13 14:04:44 oki Exp $
|
||||
|
||||
# Makefile for NetBSD
|
||||
#
|
||||
|
@ -36,8 +36,13 @@ X68K= $S/arch/x68k
|
|||
INCLUDES= -I. -I$S/arch -I$S -nostdinc
|
||||
CPPFLAGS= ${INCLUDES} ${IDENT} ${PARAM} -D_KERNEL \
|
||||
-Dmc68020 -Dx68k -DFPCOPROC
|
||||
.if empty(IDENT:M-DM68060)
|
||||
CMACHFLAGS= -m68030
|
||||
.else
|
||||
CMACHFLAGS= -m68060
|
||||
.endif
|
||||
CWARNFLAGS= -Werror
|
||||
CFLAGS= ${DEBUG} ${COPTS} ${CWARNFLAGS} -msoft-float
|
||||
CFLAGS= ${DEBUG} ${COPTS} ${CMACHFLAGS} ${CWARNFLAGS} -msoft-float
|
||||
AFLAGS= -x assembler-with-cpp -traditional-cpp -D_LOCORE
|
||||
LINKFLAGS= -n -Ttext 0 -e start
|
||||
STRIPFLAGS= -d
|
||||
|
@ -87,7 +92,7 @@ HOSTED_C= ${HOSTED_CC} ${HOSTED_CFLAGS} ${HOSTED_CPPFLAGS} -c $<
|
|||
# ${SYSTEM_LD_HEAD}
|
||||
# ${SYSTEM_LD} swapxxx.o
|
||||
# ${SYSTEM_LD_TAIL}
|
||||
SYSTEM_OBJ= locore.o ${FPSP} \
|
||||
SYSTEM_OBJ= locore.o ${FPSP} ${060SP} \
|
||||
param.o ioconf.o ${OBJS} ${LIBKERN} ${LIBCOMPAT}
|
||||
SYSTEM_DEP= Makefile ${SYSTEM_OBJ}
|
||||
SYSTEM_LD_HEAD= @rm -f $@
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
/* $NetBSD: kcore.h,v 1.1 1997/01/13 14:04:46 oki Exp $ */
|
||||
|
||||
#ifndef _MACHINE_KCORE_H_
|
||||
#define _MACHINE_KCORE_H_
|
||||
|
||||
#include <m68k/kcore.h>
|
||||
|
||||
#endif
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: autoconf.c,v 1.5 1996/10/13 03:35:14 christos Exp $ */
|
||||
/* $NetBSD: autoconf.c,v 1.6 1997/01/13 14:04:48 oki Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1995 Leo Weppelman
|
||||
|
@ -150,6 +150,9 @@ config_console()
|
|||
x68k_config_found(cf, NULL, "grfbus", NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* Configure swap space and related parameters.
|
||||
*/
|
||||
void
|
||||
swapconf()
|
||||
{
|
||||
|
@ -159,10 +162,8 @@ swapconf()
|
|||
|
||||
for (swp = swdevt; swp->sw_dev > 0; swp++) {
|
||||
maj = major(swp->sw_dev);
|
||||
|
||||
if (maj > nblkdev)
|
||||
break;
|
||||
|
||||
if (bdevsw[maj].d_psize) {
|
||||
nb = bdevsw[maj].d_psize(swp->sw_dev);
|
||||
if (nb > 0 &&
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
/* $NetBSD: db_memrw.c,v 1.5 1996/12/09 17:55:06 thorpej Exp $ */
|
||||
/* $NetBSD: db_memrw.c,v 1.6 1997/01/13 14:04:49 oki Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1996 The NetBSD Foundation, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to The NetBSD Foundation
|
||||
* by Gordon W. Ross.
|
||||
* by Gordon W. Ross and Jason R. Thorpe.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
|
@ -38,133 +38,187 @@
|
|||
|
||||
/*
|
||||
* Interface to the debugger for virtual memory read/write.
|
||||
* This file is shared by DDB and KGDB, and must work even
|
||||
* when only KGDB is included (thus no db_printf calls).
|
||||
*
|
||||
* To write in the text segment, we have to first make
|
||||
* the page writable, do the write, then restore the PTE.
|
||||
* For reads, validate address first to avoid MMU trap.
|
||||
* For writes outside the text segment, and all reads,
|
||||
* just do the access -- if it causes a fault, the debugger
|
||||
* will recover with a longjmp to an appropriate place.
|
||||
*
|
||||
* Note the special handling for 2/4 byte sizes. This is done to make
|
||||
* it work sensibly for device registers.
|
||||
* ALERT! If you want to access device registers with a
|
||||
* specific size, then the read/write functions have to
|
||||
* make sure to do the correct sized pointer access.
|
||||
*
|
||||
* Modified from sun3 version for hp300 (and probably other m68ks, too)
|
||||
* by Jason R. Thorpe <thorpej@NetBSD.ORG>.
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/proc.h>
|
||||
|
||||
#include <vm/vm.h>
|
||||
#include <ddb/db_output.h>
|
||||
|
||||
#include <machine/db_machdep.h>
|
||||
#include <machine/pte.h>
|
||||
#include <machine/db_machdep.h>
|
||||
#include <machine/cpu.h>
|
||||
|
||||
/*
|
||||
* Check if access is allowed to 'addr'. Mask should contain
|
||||
* PG_V for read access, PV_V|PG_RO for write access.
|
||||
*/
|
||||
static int
|
||||
db_check(addr, mask)
|
||||
char *addr;
|
||||
u_int mask;
|
||||
{
|
||||
u_int *pte;
|
||||
#include <ddb/db_access.h>
|
||||
|
||||
pte = kvtopte((vm_offset_t)addr);
|
||||
static void db_write_text __P((vm_offset_t, size_t, char *));
|
||||
|
||||
if ((*pte & mask) != PG_V) {
|
||||
db_printf(" address 0x%x not a valid page\n", addr);
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Read bytes from kernel address space for debugger.
|
||||
* It does not matter if this is slow. -gwr
|
||||
* This used to check for valid PTEs, but now that
|
||||
* traps in DDB work correctly, "Just Do It!"
|
||||
*/
|
||||
void
|
||||
db_read_bytes(addr, size, data)
|
||||
vm_offset_t addr;
|
||||
register int size;
|
||||
register size_t size;
|
||||
register char *data;
|
||||
{
|
||||
u_int8_t *src, *dst, *limit;
|
||||
register char *src = (char*)addr;
|
||||
|
||||
src = (u_int8_t *)addr;
|
||||
dst = (u_int8_t *)data;
|
||||
limit = src + size;
|
||||
|
||||
if (size == 2 || size == 4) {
|
||||
if(db_check(src, PG_V) && db_check(limit, PG_V)) {
|
||||
if (size == 2)
|
||||
*(u_int16_t*)data = *(u_int16_t*)addr;
|
||||
else *(u_int32_t*)data = *(u_int32_t*)addr;
|
||||
return;
|
||||
}
|
||||
if (size == 4) {
|
||||
*((int*)data) = *((int*)src);
|
||||
return;
|
||||
}
|
||||
|
||||
while (src < limit) {
|
||||
*dst = db_check(src, PG_V) ? *src : 0;
|
||||
dst++;
|
||||
src++;
|
||||
if (size == 2) {
|
||||
*((short*)data) = *((short*)src);
|
||||
return;
|
||||
}
|
||||
|
||||
while (size > 0) {
|
||||
--size;
|
||||
*data++ = *src++;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Write one byte somewhere in kernel text.
|
||||
* It does not matter if this is slow. -gwr
|
||||
* Write bytes somewhere in kernel text.
|
||||
* Makes text page writable temporarily.
|
||||
* We're probably a little to cache-paranoid.
|
||||
*/
|
||||
static void
|
||||
db_write_text(dst, ch)
|
||||
u_int8_t *dst;
|
||||
u_int8_t ch;
|
||||
db_write_text(addr, size, data)
|
||||
vm_offset_t addr;
|
||||
register size_t size;
|
||||
register char *data;
|
||||
{
|
||||
u_int *pte, oldpte;
|
||||
register char *dst, *odst;
|
||||
pt_entry_t *pte, oldpte, tmppte;
|
||||
vm_offset_t pgva;
|
||||
int limit;
|
||||
|
||||
pte = kvtopte((vm_offset_t)dst);
|
||||
oldpte = *pte;
|
||||
if ((oldpte & PG_V) == 0) {
|
||||
db_printf(" address 0x%x not a valid page\n", dst);
|
||||
if (size == 0)
|
||||
return;
|
||||
}
|
||||
|
||||
/*printf("db_write_text: %x: %x = %x (%x:%x)\n", dst, *dst, ch, pte, *pte);*/
|
||||
*pte &= ~PG_RO;
|
||||
TBIS((vm_offset_t)dst);
|
||||
dst = (char *)addr;
|
||||
|
||||
*dst = ch;
|
||||
do {
|
||||
/*
|
||||
* Get the VA for the page.
|
||||
*/
|
||||
pgva = x68k_trunc_page((u_long)dst);
|
||||
|
||||
*pte = oldpte;
|
||||
TBIS((vm_offset_t)dst);
|
||||
cachectl (4, dst, 1);
|
||||
/*
|
||||
* Save this destination address, for TLB
|
||||
* flush.
|
||||
*/
|
||||
odst = dst;
|
||||
|
||||
/*
|
||||
* Compute number of bytes that can be written
|
||||
* with this mapping and subtract it from the
|
||||
* total size.
|
||||
*/
|
||||
limit = NBPG - ((u_long)dst & PGOFSET);
|
||||
if (limit > size)
|
||||
limit = size;
|
||||
size -= limit;
|
||||
|
||||
#ifdef M68K_MMU_HP
|
||||
/*
|
||||
* Flush the supervisor side of the VAC to
|
||||
* prevent a cache hit on the old, read-only PTE.
|
||||
* XXX Is this really necessary, or am I just
|
||||
* paranoid?
|
||||
*/
|
||||
if (ectype == EC_VIRT)
|
||||
DCIS();
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Make the page writable. Note the mapping is
|
||||
* cache-inhibited to save hair.
|
||||
*/
|
||||
pte = kvtopte(pgva);
|
||||
oldpte = *pte;
|
||||
|
||||
if ((oldpte & PG_V) == 0) {
|
||||
printf(" address %p not a valid page\n", dst);
|
||||
return;
|
||||
}
|
||||
|
||||
tmppte = (oldpte & ~PG_RO) | PG_RW | PG_CI;
|
||||
*pte = tmppte;
|
||||
TBIS((vm_offset_t)odst);
|
||||
|
||||
/*
|
||||
* Page is now writable. Do as much access as we
|
||||
* can in this page.
|
||||
*/
|
||||
for (; limit > 0; limit--)
|
||||
*dst++ = *data++;
|
||||
|
||||
/*
|
||||
* Restore the old PTE.
|
||||
*/
|
||||
*pte = oldpte;
|
||||
TBIS((vm_offset_t)odst);
|
||||
} while (size != 0);
|
||||
|
||||
/*
|
||||
* Invalidate the instruction cache so our changes
|
||||
* take effect.
|
||||
*/
|
||||
ICIA();
|
||||
}
|
||||
|
||||
/*
|
||||
* Write bytes to kernel address space for debugger.
|
||||
*/
|
||||
extern char kernel_text[], etext[];
|
||||
void
|
||||
db_write_bytes(addr, size, data)
|
||||
vm_offset_t addr;
|
||||
int size;
|
||||
char *data;
|
||||
register size_t size;
|
||||
register char *data;
|
||||
{
|
||||
extern char etext[] ;
|
||||
u_int8_t *dst, *src, *limit;
|
||||
register char *dst = (char *)addr;
|
||||
|
||||
dst = (u_int8_t *)addr;
|
||||
src = (u_int8_t *)data;
|
||||
limit = dst + size;
|
||||
|
||||
if ((char*)dst >= etext && (size == 2 || size == 4)) {
|
||||
if(db_check(dst, PG_V|PG_RO) && db_check(limit, PG_V|PG_RO)) {
|
||||
if (size == 2)
|
||||
*(u_int16_t*)addr = *(u_int16_t*)data;
|
||||
else *(u_int32_t*)addr = *(u_int32_t*)data;
|
||||
return;
|
||||
}
|
||||
/* If any part is in kernel text, use db_write_text() */
|
||||
if ((dst < etext) && ((dst + size) > kernel_text)) {
|
||||
db_write_text(addr, size, data);
|
||||
return;
|
||||
}
|
||||
while (dst < limit) {
|
||||
if ((char*)dst < etext) /* kernel text starts at 0 */
|
||||
db_write_text(dst, *src);
|
||||
else if (db_check(dst, PG_V|PG_RO))
|
||||
*dst = *src;
|
||||
dst++;
|
||||
src++;
|
||||
|
||||
if (size == 4) {
|
||||
*((int*)dst) = *((int*)data);
|
||||
return;
|
||||
}
|
||||
|
||||
if (size == 2) {
|
||||
*((short*)dst) = *((short*)data);
|
||||
return;
|
||||
}
|
||||
|
||||
while (size > 0) {
|
||||
--size;
|
||||
*dst++ = *data++;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: genassym.c,v 1.3 1997/01/08 10:29:27 oki Exp $ */
|
||||
/* $NetBSD: genassym.c,v 1.4 1997/01/13 14:04:51 oki Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1982, 1990, 1993
|
||||
|
@ -205,7 +205,9 @@ main()
|
|||
def("IC_CLEAR", IC_CLEAR);
|
||||
def("DC_CLEAR", DC_CLEAR);
|
||||
def("CACHE40_OFF", CACHE40_OFF);
|
||||
|
||||
def("IC60_CUBC", IC60_CUBC);
|
||||
def("IC60_CABC", IC60_CABC);
|
||||
|
||||
/* pte/ste bits */
|
||||
def("PG_V", PG_V);
|
||||
def("PG_NV", PG_NV);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: locore.s,v 1.9 1996/12/09 15:29:08 oki Exp $ */
|
||||
/* $NetBSD: locore.s,v 1.10 1997/01/13 14:04:53 oki Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1988 University of Utah.
|
||||
|
@ -103,14 +103,47 @@ _buserr:
|
|||
movl _nofault,sp@- | yes,
|
||||
jbsr _longjmp | longjmp(nofault)
|
||||
Lberr:
|
||||
#if defined(M68040)
|
||||
cmpl #MMU_68040,_mmutype | 68040?
|
||||
#if defined(M68040) || defined(M68060)
|
||||
cmpl #MMU_68040,_mmutype | 68040/060?
|
||||
jne _addrerr | no, skip
|
||||
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(M68060)
|
||||
cmpl #CPU_68060,_cputype | 68060?
|
||||
jne Lbenot060
|
||||
movel a1@(12),d0 | grap FSLW
|
||||
btst #2,d0 | branch prediction error?
|
||||
jeq Lnobpe | no, skip
|
||||
movc cacr,d1
|
||||
orl #IC60_CABC,d1 | clear all branch cache entries
|
||||
movc d1,cacr
|
||||
movl d0,d1
|
||||
andl #0x7ffd,d1 | check other faults
|
||||
jeq Lbpedone
|
||||
Lnobpe:
|
||||
| XXX this is not needed.
|
||||
| movl d0,sp@ | code is FSLW now.
|
||||
|
||||
| we need to adjust for misaligned addresses
|
||||
movl a1@(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
|
||||
| XXX instr. case not done yet
|
||||
andl #PG_FRAME,d1 | and truncate
|
||||
Lberr3:
|
||||
movl d1,sp@- | push fault VA
|
||||
movl d0,sp@- | and FSLW
|
||||
andw #0x1f80,d0
|
||||
jeq Lisberr
|
||||
jra Lismerr
|
||||
Lbenot060:
|
||||
#endif
|
||||
moveq #0,d0
|
||||
movw a1@(12),d0 | grab SSW
|
||||
movl a1@(20),d1 | and fault VA
|
||||
|
@ -138,7 +171,7 @@ _addrerr:
|
|||
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)
|
||||
#if defined(M68040) || defined(M68060)
|
||||
cmpl #MMU_68040,_mmutype | 68040?
|
||||
jne Lbenot040 | no, skip
|
||||
movl a1@(8),sp@- | yes, push fault address
|
||||
|
@ -224,6 +257,7 @@ Lisberr:
|
|||
movl #T_BUSERR,sp@- | mark bus error
|
||||
Ltrapnstkadj:
|
||||
jbsr _trap | handle the error
|
||||
Lbpedone:
|
||||
lea sp@(12),sp | pop value args
|
||||
movl sp@(FR_SP),a0 | restore user SP
|
||||
movl a0,usp | from save area
|
||||
|
@ -298,6 +332,11 @@ _fpfault:
|
|||
movl _curpcb,a0 | current pcb
|
||||
lea a0@(PCB_FPCTX),a0 | address of FP savearea
|
||||
fsave a0@ | save state
|
||||
#if defined(M68040) || defined(M68060)
|
||||
/* always null state frame on 68040, 68060 */
|
||||
cmpl #MMU_68040,_mmutype
|
||||
jle Lfptnull
|
||||
#endif
|
||||
tstb a0@ | null state frame?
|
||||
jeq Lfptnull | yes, safe
|
||||
clrw d0 | no, need to tweak BIU
|
||||
|
@ -452,45 +491,100 @@ _trap12:
|
|||
jra 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
|
||||
*/
|
||||
_trap15:
|
||||
clrl sp@-
|
||||
moveml #0xFFFF,sp@-
|
||||
#ifdef KGDB
|
||||
moveq #T_TRAP15,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
|
||||
|
||||
/*
|
||||
* Hit a breakpoint (trap 1 or 2) instruction.
|
||||
* Push the code and treat as a normal fault.
|
||||
* Trace (single-step) trap. Kernel-mode is special.
|
||||
* User mode traps are simply passed on to trap().
|
||||
*/
|
||||
_trace:
|
||||
clrl sp@-
|
||||
clrl sp@- | stack adjust count
|
||||
moveml #0xFFFF,sp@-
|
||||
moveq #T_TRACE,d0
|
||||
movw sp@(FR_HW),d1 | get PSW
|
||||
andw #PSL_S,d1 | from system mode?
|
||||
jne kbrkpt | yes, kernel breakpoint
|
||||
jra fault | no, user-mode fault
|
||||
|
||||
/*
|
||||
* Trap 15 is used for:
|
||||
* - GDB breakpoints (in user programs)
|
||||
* - KGDB breakpoints (in the kernel)
|
||||
* - trace traps for SUN binaries (not fully supported yet)
|
||||
* User mode traps are simply passed to trap().
|
||||
*/
|
||||
_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 kbrkpt | yes, kernel breakpoint
|
||||
jra fault | no, user-mode fault
|
||||
|
||||
kbrkpt: | 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 #tmpstk,d1
|
||||
jls Lbrkpt2 | already on tmpstk
|
||||
| Copy frame to the temporary stack
|
||||
movl sp,a0 | a0=src
|
||||
lea 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 | no, 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 _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
|
||||
#ifdef DDB
|
||||
| Let DDB handle it
|
||||
movl a2,sp@- | push frame ptr
|
||||
movl d2,sp@- | push trap type
|
||||
jbsr _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>
|
||||
|
@ -845,6 +939,9 @@ Lnosir:
|
|||
Ldorte:
|
||||
rte | real return
|
||||
|
||||
/*
|
||||
* Macro to relocate a symbol, used before MMU is enabled.
|
||||
*/
|
||||
#define RELOC(var, ar) \
|
||||
lea var,ar; \
|
||||
addl a5,ar
|
||||
|
@ -903,7 +1000,9 @@ start:
|
|||
tstl d0 | zero?
|
||||
jeq Lnot68030 | yes, we have 68020/68040/68060
|
||||
RELOC(_mmutype, a0) | no, we have 68030
|
||||
movl #-1,a0@ | set to reflect 68030 PMMU
|
||||
movl #MMU_68030,a0@ | set to reflect 68030 PMMU
|
||||
RELOC(_cputype, a0)
|
||||
movl #CPU_68030,a0@ | and 68030 CPU
|
||||
jra Lstart1
|
||||
Lnot68030:
|
||||
bset #31,d0 | data cache enable bit
|
||||
|
@ -921,10 +1020,14 @@ Lnot68030:
|
|||
beq Lis68040 | yes, we have 68040
|
||||
RELOC(_mmutype, a0) | no, we have 68060
|
||||
movl #MMU_68040,a0@ | with a 68040 compatible MMU
|
||||
RELOC(_cputype, a0)
|
||||
movl #CPU_68060,a0@ | and a 68060 CPU
|
||||
jra Lstart1
|
||||
Lis68040:
|
||||
RELOC(_mmutype, a0)
|
||||
movl #MMU_68040,a0@ | with a 68040 MMU
|
||||
RELOC(_cputype, a0)
|
||||
movl #CPU_68040,a0@ | and a 68040 CPU
|
||||
jra Lstart1
|
||||
Lis68020:
|
||||
RELOC(_mmutype, a0)
|
||||
|
@ -1023,6 +1126,17 @@ Ljupiterdone:
|
|||
.word 0xf518 | pflusha
|
||||
movl #0x8000,d0
|
||||
.long 0x4e7b0003 | movc d0,tc
|
||||
#ifdef M68060
|
||||
RELOC(_cputype, a0)
|
||||
cmpl #CPU_68060,a0@ | 68060?
|
||||
jne Lnot060cache
|
||||
movl #1,d0
|
||||
.long 0x4e7b0808 | movcl d0,pcr
|
||||
movl #0xa0808000,d0
|
||||
movc d0,cacr | enable store buffer, both caches
|
||||
jmp Lenab1
|
||||
Lnot060cache:
|
||||
#endif
|
||||
movl #0x80008000,d0
|
||||
movc d0,cacr | turn on both caches
|
||||
jmp Lenab1
|
||||
|
@ -1042,6 +1156,8 @@ Lfinish:
|
|||
/* set kernel stack, user SP, and initial pcb */
|
||||
movl _proc0paddr,a1 | get proc0 pcb addr
|
||||
lea a1@(USPACE-4),sp | set kernel stack to end of area
|
||||
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
|
||||
|
@ -1079,6 +1195,13 @@ Lnocache0:
|
|||
|
||||
jra _main | main()
|
||||
|
||||
pea Lmainreturned | Yow! Main returned!
|
||||
jbsr _panic
|
||||
/* NOTREACHED */
|
||||
Lmainreturned:
|
||||
.asciz "main() returned"
|
||||
.even
|
||||
|
||||
.globl _proc_trampoline
|
||||
_proc_trampoline:
|
||||
movl a3,sp@-
|
||||
|
@ -1133,7 +1256,7 @@ ENTRY(copypage)
|
|||
movl sp@(4),a0 | source address
|
||||
movl sp@(8),a1 | destination address
|
||||
movl #NBPG/32,d0 | number of 32 byte chunks
|
||||
#if defined(M68040)
|
||||
#if defined(M68040) || defined(M68060)
|
||||
cmpl #MMU_68040,_mmutype | 68040?
|
||||
jne Lmlloop | no, use movl
|
||||
Lm16loop:
|
||||
|
@ -1379,10 +1502,24 @@ Lsw2:
|
|||
#ifdef FPCOPROC
|
||||
lea a1@(PCB_FPCTX),a2 | pointer to FP save area
|
||||
fsave a2@ | save FP state
|
||||
#ifdef M68060
|
||||
cmpl #CPU_68060,_cputype
|
||||
jeq Lsavfp60
|
||||
#endif
|
||||
tstb a2@ | null state frame?
|
||||
jeq Lswnofpsave | yes, all done
|
||||
fmovem fp0-fp7,a2@(216) | save FP general registers
|
||||
fmovem fpcr/fpsr/fpi,a2@(312) | save FP control registers
|
||||
#ifdef M68060
|
||||
jra Lswnofpsave
|
||||
Lsavfp60:
|
||||
tstb a2@(2) | null state frame?
|
||||
jeq Lswnofpsave | yes, all done
|
||||
fmovem fp0-fp7,a2@(216) | save FP general registers
|
||||
fmovem fpcr,a2@(312) | save FP control registers
|
||||
fmovem fpsr,a2@(316)
|
||||
fmovem fpi,a2@(320)
|
||||
#endif
|
||||
Lswnofpsave:
|
||||
#endif
|
||||
|
||||
|
@ -1414,10 +1551,18 @@ Lswnofpsave:
|
|||
Lswnochg:
|
||||
|
||||
lea tmpstk,sp | now goto a tmp stack for NMI
|
||||
#if defined(M68040)
|
||||
#if defined(M68040) || defined(M68060)
|
||||
cmpl #MMU_68040,_mmutype | 68040?
|
||||
jne Lres1a | no, skip
|
||||
.word 0xf518 | yes, pflusha
|
||||
#ifdef M68060
|
||||
cmpl #CPU_68060,_cputype
|
||||
jne Lres3
|
||||
movc cacr,d0
|
||||
orl #IC60_CUBC,d0 | clear user branch cache entries
|
||||
movc d0,cacr
|
||||
Lres3:
|
||||
#endif
|
||||
movl a1@(PCB_USTP),d0 | get USTP
|
||||
moveq #PGSHIFT,d1
|
||||
lsll d1,d0 | convert to addr
|
||||
|
@ -1440,10 +1585,14 @@ Lcxswdone:
|
|||
movl a0,usp | and USP
|
||||
#ifdef FPCOPROC
|
||||
lea a1@(PCB_FPCTX),a0 | pointer to FP save area
|
||||
#ifdef M68060
|
||||
cmpl #CPU_68060,_cputype
|
||||
jeq Lresfp60rest1
|
||||
#endif
|
||||
tstb a0@ | null state frame?
|
||||
jeq Lresfprest | yes, easy
|
||||
#if defined(M68040)
|
||||
cmpl #MMU_68040,_mmutype | 68040?
|
||||
cmpl #CPU_68040,_cputype | 68040?
|
||||
jne Lresnot040 | no, skip
|
||||
clrl sp@- | yes...
|
||||
frestore sp@+ | ...magic!
|
||||
|
@ -1458,6 +1607,21 @@ Lresfprest:
|
|||
moveq #1,d0 | return 1 (for alternate returns)
|
||||
rts
|
||||
|
||||
#ifdef M68060
|
||||
Lresfp60rest1:
|
||||
tstb a0@(2) | null state frame?
|
||||
jeq Lresfp60rest2 | yes, easy
|
||||
fmovem a0@(312),fpcr | restore FP control registers
|
||||
fmovem a0@(316),fpsr
|
||||
fmovem a0@(320),fpi
|
||||
fmovem a0@(216),fp0-fp7 | restore FP general registers
|
||||
Lresfp60rest2:
|
||||
frestore a0@ | restore state
|
||||
movw a1@(PCB_PS),sr | no, restore PS
|
||||
moveq #1,d0 | return 1 (for alternate returns)
|
||||
rts
|
||||
#endif
|
||||
|
||||
/*
|
||||
* savectx(pcb)
|
||||
* Update pcb, saving current processor state.
|
||||
|
@ -1471,16 +1635,30 @@ ENTRY(savectx)
|
|||
#ifdef FPCOPROC
|
||||
lea a1@(PCB_FPCTX),a0 | pointer to FP save area
|
||||
fsave a0@ | save FP state
|
||||
#ifdef M68060
|
||||
cmpl #CPU_68060,_cputype
|
||||
jeq Lsvsavfp60
|
||||
#endif
|
||||
tstb a0@ | null state frame?
|
||||
jeq Lsvnofpsave | yes, all done
|
||||
fmovem fp0-fp7,a0@(216) | save FP general registers
|
||||
fmovem fpcr/fpsr/fpi,a0@(312) | save FP control registers
|
||||
#ifdef M68060
|
||||
jra Lsvnofpsave
|
||||
Lsvsavfp60:
|
||||
tstb a0@(2) | null state frame?
|
||||
jeq Lsvnofpsave | yes, all done
|
||||
fmovem fp0-fp7,a0@(216) | save FP general registers
|
||||
fmovem fpcr,a0@(312) | save FP control registers
|
||||
fmovem fpsr,a0@(316)
|
||||
fmovem fpi,a0@(320)
|
||||
#endif
|
||||
Lsvnofpsave:
|
||||
#endif
|
||||
moveq #0,d0 | return 0
|
||||
rts
|
||||
|
||||
#if defined(M68040)
|
||||
#if defined(M68040) || defined(M68060)
|
||||
ENTRY(suline)
|
||||
movl sp@(4),a0 | address to write
|
||||
movl _curpcb,a1 | current pcb
|
||||
|
@ -1513,10 +1691,18 @@ Lsldone:
|
|||
*/
|
||||
ENTRY(TBIA)
|
||||
__TBIA:
|
||||
#if defined(M68040)
|
||||
#if defined(M68040) || defined(M68060)
|
||||
cmpl #MMU_68040,_mmutype | 68040?
|
||||
jne Lmotommu3 | no, skip
|
||||
.word 0xf518 | yes, pflusha
|
||||
#ifdef M68060
|
||||
cmpl #CPU_68060,_cputype
|
||||
jne Ltbiano60
|
||||
movc cacr,d0
|
||||
orl #IC60_CABC,d0 | clear all branch cache entries
|
||||
movc d0,cacr
|
||||
Ltbiano60:
|
||||
#endif
|
||||
rts
|
||||
Lmotommu3:
|
||||
#endif
|
||||
|
@ -1536,7 +1722,7 @@ ENTRY(TBIS)
|
|||
tstl fulltflush | being conservative?
|
||||
jne __TBIA | yes, flush entire TLB
|
||||
#endif
|
||||
#if defined(M68040)
|
||||
#if defined(M68040) || defined(M68060)
|
||||
cmpl #MMU_68040,_mmutype | 68040?
|
||||
jne Lmotommu4 | no, skip
|
||||
movl sp@(4),a0
|
||||
|
@ -1548,6 +1734,14 @@ ENTRY(TBIS)
|
|||
movc d0,dfc
|
||||
.word 0xf508 | pflush a0@
|
||||
movc d1,dfc
|
||||
#ifdef M68060
|
||||
cmpl #CPU_68060,_cputype
|
||||
jne Ltbisno60
|
||||
movc cacr,d0
|
||||
orl #IC60_CABC,d0 | clear all branch cache entries
|
||||
movc d0,cacr
|
||||
Ltbisno60:
|
||||
#endif
|
||||
rts
|
||||
Lmotommu4:
|
||||
#endif
|
||||
|
@ -1570,10 +1764,18 @@ ENTRY(TBIAS)
|
|||
tstl fulltflush | being conservative?
|
||||
jne __TBIA | yes, flush everything
|
||||
#endif
|
||||
#if defined(M68040)
|
||||
#if defined(M68040) || defined(M68060)
|
||||
cmpl #MMU_68040,_mmutype | 68040?
|
||||
jne Lmotommu5 | no, skip
|
||||
.word 0xf518 | yes, pflusha (for now) XXX
|
||||
#ifdef M68060
|
||||
cmpl #CPU_68060,_cputype
|
||||
jne Ltbiasno60
|
||||
movc cacr,d0
|
||||
orl #IC60_CABC,d0 | clear all branch cache entries
|
||||
movc d0,cacr
|
||||
Ltbiasno60:
|
||||
#endif
|
||||
rts
|
||||
Lmotommu5:
|
||||
#endif
|
||||
|
@ -1595,10 +1797,18 @@ ENTRY(TBIAU)
|
|||
tstl fulltflush | being conservative?
|
||||
jne __TBIA | yes, flush everything
|
||||
#endif
|
||||
#if defined(M68040)
|
||||
#if defined(M68040) || defined(M68060)
|
||||
cmpl #MMU_68040,_mmutype | 68040?
|
||||
jne Lmotommu6 | no, skip
|
||||
.word 0xf518 | yes, pflusha (for now) XXX
|
||||
#ifdef M68060
|
||||
cmpl #CPU_68060,_cputype
|
||||
jne Ltbiauno60
|
||||
movc cacr,d0
|
||||
orl #IC60_CUBC,d0 | clear user branch cache entries
|
||||
movc d0,cacr
|
||||
Ltbiauno60:
|
||||
#endif
|
||||
rts
|
||||
Lmotommu6:
|
||||
#endif
|
||||
|
@ -1638,7 +1848,7 @@ Lmotommu7:
|
|||
*/
|
||||
ENTRY(DCIA)
|
||||
__DCIA:
|
||||
#if defined(M68040)
|
||||
#if defined(M68040) || defined(M68060)
|
||||
cmpl #MMU_68040,_mmutype | 68040
|
||||
jne Lmotommu8 | no, skip
|
||||
/* XXX implement */
|
||||
|
@ -1648,7 +1858,7 @@ Lmotommu8:
|
|||
|
||||
ENTRY(DCIS)
|
||||
__DCIS:
|
||||
#if defined(M68040)
|
||||
#if defined(M68040) || defined(M68060)
|
||||
cmpl #MMU_68040,_mmutype | 68040
|
||||
jne Lmotommu9 | no, skip
|
||||
/* XXX implement */
|
||||
|
@ -1658,7 +1868,7 @@ Lmotommu9:
|
|||
|
||||
ENTRY(DCIU)
|
||||
__DCIU:
|
||||
#if defined(M68040)
|
||||
#if defined(M68040) || defined(M68060)
|
||||
cmpl #MMU_68040,_mmutype | 68040
|
||||
jne LmotommuA | no, skip
|
||||
/* XXX implement */
|
||||
|
@ -1730,10 +1940,18 @@ ENTRY(loadustp)
|
|||
movl sp@(4),d0 | new USTP
|
||||
moveq #PGSHIFT,d1
|
||||
lsll d1,d0 | convert to addr
|
||||
#if defined(M68040)
|
||||
#if defined(M68040) || defined(M68060)
|
||||
cmpl #MMU_68040,_mmutype | 68040?
|
||||
jne LmotommuC | no, skip
|
||||
.long 0x4e7b0806 | movc d0,urp
|
||||
#ifdef M68060
|
||||
cmpl #CPU_68060,_cputype
|
||||
jne Lldno60
|
||||
movc cacr,d0
|
||||
orl #IC60_CUBC,d0 | clear user branch cache entries
|
||||
movc d0,cacr
|
||||
Lldno60:
|
||||
#endif
|
||||
rts
|
||||
LmotommuC:
|
||||
#endif
|
||||
|
@ -1747,7 +1965,7 @@ LmotommuC:
|
|||
ENTRY(ploadw)
|
||||
#if defined(M68030)
|
||||
movl sp@(4),a0 | address to load
|
||||
#if defined(M68040)
|
||||
#if defined(M68040) || defined(M68060)
|
||||
cmpl #MMU_68040,_mmutype | 68040?
|
||||
jeq Lploadwskp | yes, skip
|
||||
#endif
|
||||
|
@ -1809,6 +2027,10 @@ ENTRY(_remque)
|
|||
ENTRY(m68881_save)
|
||||
movl sp@(4),a0 | save area pointer
|
||||
fsave a0@ | save state
|
||||
#ifdef M68060
|
||||
cmpl #CPU_68060,_cputype
|
||||
jeq Lm68060fpsave
|
||||
#endif
|
||||
tstb a0@ | null state frame?
|
||||
jeq Lm68881sdone | yes, all done
|
||||
fmovem fp0-fp7,a0@(216) | save FP general registers
|
||||
|
@ -1816,8 +2038,24 @@ ENTRY(m68881_save)
|
|||
Lm68881sdone:
|
||||
rts
|
||||
|
||||
#ifdef M68060
|
||||
Lm68060fpsave:
|
||||
tstb a0@(2) | null state frame?
|
||||
jeq Lm68060sdone | yes, all done
|
||||
fmovem fp0-fp7,a0@(216) | save FP general registers
|
||||
fmovem fpcr,a0@(312) | save FP control registers
|
||||
fmovem fpsr,a0@(316)
|
||||
fmovem fpi,a0@(320)
|
||||
Lm68060sdone:
|
||||
rts
|
||||
#endif
|
||||
|
||||
ENTRY(m68881_restore)
|
||||
movl sp@(4),a0 | save area pointer
|
||||
#ifdef M68060
|
||||
cmpl #CPU_68060,_cputype
|
||||
jeq Lm68060fprestore
|
||||
#endif
|
||||
tstb a0@ | null state frame?
|
||||
jeq Lm68881rdone | yes, easy
|
||||
fmovem a0@(312),fpcr/fpsr/fpi | restore FP control registers
|
||||
|
@ -1825,6 +2063,19 @@ ENTRY(m68881_restore)
|
|||
Lm68881rdone:
|
||||
frestore a0@ | restore state
|
||||
rts
|
||||
|
||||
#ifdef M68060
|
||||
Lm68060fprestore:
|
||||
tstb a0@(2) | null state frame?
|
||||
jeq Lm68060fprdone | yes, easy
|
||||
fmovem a0@(312),fpcr | restore FP control registers
|
||||
fmovem a0@(316),fpsr
|
||||
fmovem a0@(320),fpi
|
||||
fmovem a0@(216),fp0-fp7 | restore FP general registers
|
||||
Lm68060fprdone:
|
||||
frestore a0@ | restore state
|
||||
rts
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
@ -1838,7 +2089,7 @@ Lm68881rdone:
|
|||
.globl _doboot
|
||||
_doboot:
|
||||
movl #CACHE_OFF,d0
|
||||
#if defined(M68040)
|
||||
#if defined(M68040) || defined(M68060)
|
||||
cmpl #MMU_68040,_mmutype | 68040?
|
||||
jne Ldoboot0 | no, skip
|
||||
.word 0xf4f8 | cpusha bc - push and invalidate caches
|
||||
|
@ -1852,7 +2103,7 @@ Ldoboot0:
|
|||
|
||||
| ok, turn off MMU..
|
||||
Ldoreboot:
|
||||
#if defined(M68040)
|
||||
#if defined(M68040) || defined(M68060)
|
||||
cmpl #MMU_68040,_mmutype | 68040?
|
||||
jne LmotommuF | no, skip
|
||||
movl #0,d0
|
||||
|
@ -1864,8 +2115,8 @@ LmotommuF:
|
|||
#endif
|
||||
clrl sp@ | value for pmove to TC (turn off MMU)
|
||||
pmove sp@,tc | disable MMU
|
||||
movl 0x00ff0000:l,Lvectab
|
||||
movl 0x00ff0004:l,Lvectab+4
|
||||
movl 0x00ff0000:l,_vectab
|
||||
movl 0x00ff0004:l,_vectab+4
|
||||
moval 0x00ff0004:l,a0
|
||||
jmp a0@ | reboot X680x0
|
||||
Lebootcode:
|
||||
|
@ -1874,14 +2125,17 @@ Lebootcode:
|
|||
.globl _machineid
|
||||
_machineid:
|
||||
.long 0 | default to X68030
|
||||
.globl _mmutype,_protorp
|
||||
.globl _mmutype,_cputype,_fputype,_ectype,_protorp
|
||||
_mmutype:
|
||||
.long -1 | default to 030 internal MMU
|
||||
.long MMU_68030 | default to 030 internal MMU
|
||||
_cputype:
|
||||
.long CPU_68020 | default to 68020 CPU
|
||||
_fputype:
|
||||
.long 0
|
||||
_ectype:
|
||||
.long EC_NONE | external cache type, default to none
|
||||
_protorp:
|
||||
.long 0,0 | prototype root pointer
|
||||
.globl _ectype
|
||||
_ectype:
|
||||
.long 0 | external cache type, default to none
|
||||
.globl _cold
|
||||
_cold:
|
||||
.long 1 | cold start flag
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: machdep.c,v 1.5 1996/10/13 03:35:23 christos Exp $ */
|
||||
/* $NetBSD: machdep.c,v 1.6 1997/01/13 14:04:55 oki Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1988 University of Utah.
|
||||
|
@ -187,11 +187,6 @@ cpu_startup()
|
|||
int base, residual;
|
||||
vm_offset_t minaddr, maxaddr;
|
||||
vm_size_t size;
|
||||
#ifdef BUFFERS_UNMANAGED
|
||||
vm_offset_t bufmemp;
|
||||
caddr_t buffermem;
|
||||
int ix;
|
||||
#endif
|
||||
#ifdef DEBUG
|
||||
extern int pmapdebug;
|
||||
int opmapdebug = pmapdebug;
|
||||
|
@ -219,7 +214,7 @@ cpu_startup()
|
|||
*/
|
||||
printf(version);
|
||||
identifycpu();
|
||||
printf("real mem = %d\n", ctob(physmem));
|
||||
printf("real mem = %d\n", ctob(physmem));
|
||||
|
||||
/*
|
||||
* Allocate space for system data structures.
|
||||
|
@ -302,11 +297,6 @@ again:
|
|||
firstaddr = (caddr_t) kmem_alloc(kernel_map, round_page(size));
|
||||
if (firstaddr == 0)
|
||||
panic("startup: no room for tables");
|
||||
#ifdef BUFFERS_UNMANAGED
|
||||
buffermem = (caddr_t) kmem_alloc(kernel_map, bufpages*CLBYTES);
|
||||
if (buffermem == 0)
|
||||
panic("startup: no room for buffers");
|
||||
#endif
|
||||
goto again;
|
||||
}
|
||||
/*
|
||||
|
@ -333,9 +323,6 @@ again:
|
|||
#endif
|
||||
base = bufpages / nbuf;
|
||||
residual = bufpages % nbuf;
|
||||
#ifdef BUFFERS_UNMANAGED
|
||||
bufmemp = (vm_offset_t) buffermem;
|
||||
#endif
|
||||
for (i = 0; i < nbuf; i++) {
|
||||
vm_size_t curbufsize;
|
||||
vm_offset_t curbuf;
|
||||
|
@ -349,36 +336,9 @@ again:
|
|||
*/
|
||||
curbuf = (vm_offset_t)buffers + i * MAXBSIZE;
|
||||
curbufsize = CLBYTES * (i < residual ? base+1 : base);
|
||||
#ifdef BUFFERS_UNMANAGED
|
||||
/*
|
||||
* Move the physical pages over from buffermem.
|
||||
*/
|
||||
for (ix = 0; ix < curbufsize/CLBYTES; ix++) {
|
||||
vm_offset_t pa;
|
||||
|
||||
pa = pmap_extract(pmap_kernel(), bufmemp);
|
||||
if (pa == 0)
|
||||
panic("startup: unmapped buffer");
|
||||
pmap_remove(pmap_kernel(), bufmemp, bufmemp+CLBYTES);
|
||||
pmap_enter(pmap_kernel(),
|
||||
(vm_offset_t)(curbuf + ix * CLBYTES),
|
||||
pa, VM_PROT_READ|VM_PROT_WRITE, TRUE);
|
||||
bufmemp += CLBYTES;
|
||||
}
|
||||
#else
|
||||
vm_map_pageable(buffer_map, curbuf, curbuf+curbufsize, FALSE);
|
||||
vm_map_simplify(buffer_map, curbuf);
|
||||
#endif
|
||||
}
|
||||
#ifdef BUFFERS_UNMANAGED
|
||||
#if 0
|
||||
/*
|
||||
* We would like to free the (now empty) original address range
|
||||
* but too many bad things will happen if we try.
|
||||
*/
|
||||
kmem_free(kernel_map, (vm_offset_t)buffermem, bufpages*CLBYTES);
|
||||
#endif
|
||||
#endif
|
||||
/*
|
||||
* Allocate a submap for exec arguments. This map effectively
|
||||
* limits the number of processes exec'ing at any time.
|
||||
|
@ -506,6 +466,17 @@ setregs(p, pack, stack, retval)
|
|||
*/
|
||||
char cpu_model[120];
|
||||
extern char version[];
|
||||
static char *fpu_descr[] = {
|
||||
#ifdef FPU_EMULATE
|
||||
"emulator FPU", /* 0 */
|
||||
#else
|
||||
"no math support", /* 0 */
|
||||
#endif
|
||||
" mc68881 FPU", /* 1 */
|
||||
" mc68882 FPU", /* 2 */
|
||||
"/FPU", /* 3 */
|
||||
"/FPU", /* 4 */
|
||||
};
|
||||
|
||||
void
|
||||
identifycpu()
|
||||
|
@ -543,19 +514,33 @@ identifycpu()
|
|||
break;
|
||||
}
|
||||
|
||||
if (mmutype == MMU_68040) {
|
||||
switch (cputype) {
|
||||
case CPU_68060:
|
||||
cpu_type = "m68060";
|
||||
mmu = "/MMU";
|
||||
break;
|
||||
case CPU_68040:
|
||||
cpu_type = "m68040";
|
||||
mmu = "/MMU";
|
||||
fpu = "/FPU";
|
||||
} else if (mmutype == MMU_68030) {
|
||||
break;
|
||||
case CPU_68030:
|
||||
cpu_type = "m68030";
|
||||
mmu = "/MMU";
|
||||
fpu = " m68882 FPU";
|
||||
} else {
|
||||
break;
|
||||
case CPU_68020:
|
||||
cpu_type = "m68020";
|
||||
mmu = " m68851 MMU";
|
||||
fpu = " m68881 FPU";
|
||||
break;
|
||||
default:
|
||||
cpu_type = "unknown";
|
||||
mmu = " unknown MMU";
|
||||
break;
|
||||
}
|
||||
fputype = fpu_probe();
|
||||
if (fputype >= 0 && fputype < sizeof(fpu_descr)/sizeof(fpu_descr[0]))
|
||||
fpu = fpu_descr[fputype];
|
||||
else
|
||||
fpu = " unknown FPU";
|
||||
sprintf(cpu_model, "X68%s (%s CPU%s%s)", mach, cpu_type, mmu, fpu);
|
||||
printf("%s\n", cpu_model);
|
||||
}
|
||||
|
@ -1046,6 +1031,11 @@ boot(howto, bootstr)
|
|||
doshutdownhooks();
|
||||
|
||||
#if defined(PANICWAIT) && !defined(DDB)
|
||||
if ((howto & RB_HALT) == 0 && panicstr) {
|
||||
printf("hit any key to reboot...\n");
|
||||
(void)cngetc();
|
||||
printf("\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Finally, halt/reboot the system. */
|
||||
|
@ -1171,7 +1161,10 @@ dumpsys()
|
|||
register int (*dump) __P((dev_t, daddr_t, caddr_t, size_t));
|
||||
int error = 0;
|
||||
|
||||
/* Don't put dump messages in msgbuf. */
|
||||
msgbufmapped = 0;
|
||||
|
||||
/* Make sure dump device is valid. */
|
||||
if (dumpdev == NODEV)
|
||||
return;
|
||||
/*
|
||||
|
@ -1183,7 +1176,7 @@ dumpsys()
|
|||
}
|
||||
if (dumplo < 0)
|
||||
return;
|
||||
printf("\ndumping to dev %x, offset %ld\n", dumpdev, dumplo);
|
||||
printf("\ndumping to dev 0x%x, offset %ld\n", dumpdev, dumplo);
|
||||
|
||||
psize = (*bdevsw[major(dumpdev)].d_psize)(dumpdev);
|
||||
printf("dump ");
|
||||
|
@ -1261,6 +1254,18 @@ dumpsys()
|
|||
void
|
||||
initcpu()
|
||||
{
|
||||
/* XXX should init '40 vecs here, too */
|
||||
#if defined(M68060)
|
||||
extern caddr_t vectab[256];
|
||||
#if defined(M060SP)
|
||||
extern u_int8_t I_CALL_TOP[];
|
||||
extern u_int8_t FP_CALL_TOP[];
|
||||
#else
|
||||
extern u_int8_t illinst;
|
||||
#endif
|
||||
extern u_int8_t fpfault;
|
||||
#endif
|
||||
|
||||
#ifdef MAPPEDCOPY
|
||||
extern u_int mappedcopysize;
|
||||
|
||||
|
@ -1273,6 +1278,31 @@ initcpu()
|
|||
mappedcopysize = NBPG;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(M68060)
|
||||
if (cputype == CPU_68060) {
|
||||
#if defined(M060SP)
|
||||
/* integer support */
|
||||
vectab[61] = &I_CALL_TOP[128 + 0x00];
|
||||
|
||||
/* floating point support */
|
||||
vectab[11] = &FP_CALL_TOP[128 + 0x30];
|
||||
vectab[55] = &FP_CALL_TOP[128 + 0x38];
|
||||
vectab[60] = &FP_CALL_TOP[128 + 0x40];
|
||||
|
||||
vectab[54] = &FP_CALL_TOP[128 + 0x00];
|
||||
vectab[52] = &FP_CALL_TOP[128 + 0x08];
|
||||
vectab[53] = &FP_CALL_TOP[128 + 0x10];
|
||||
vectab[51] = &FP_CALL_TOP[128 + 0x18];
|
||||
vectab[50] = &FP_CALL_TOP[128 + 0x20];
|
||||
vectab[49] = &FP_CALL_TOP[128 + 0x28];
|
||||
#else
|
||||
vectab[61] = &illinst;
|
||||
#endif
|
||||
vectab[48] = &fpfault;
|
||||
}
|
||||
DCIS();
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -1296,9 +1326,6 @@ 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;
|
||||
|
@ -1316,9 +1343,6 @@ badbaddr(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;
|
||||
|
@ -1639,12 +1663,12 @@ cpu_exec_aout_makecmds(p, epp)
|
|||
switch (midmag) {
|
||||
#ifdef COMPAT_NOMID
|
||||
case (MID_ZERO << 16) | ZMAGIC:
|
||||
error = cpu_exec_aout_prep_oldzmagic(p, epp);
|
||||
error = exec_aout_prep_oldzmagic(p, epp);
|
||||
break;
|
||||
#endif
|
||||
#ifdef COMPAT_44
|
||||
case (MID_HP300 << 16) | ZMAGIC:
|
||||
error = cpu_exec_aout_prep_oldzmagic(p, epp);
|
||||
error = exec_aout_prep_oldzmagic(p, epp);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
|
@ -1656,59 +1680,3 @@ cpu_exec_aout_makecmds(p, epp)
|
|||
return ENOEXEC;
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined(COMPAT_NOMID) || defined(COMPAT_44)
|
||||
/*
|
||||
* cpu_exec_aout_prep_oldzmagic():
|
||||
* Prepare the vmcmds to build a vmspace for an old
|
||||
* (i.e. USRTEXT == 0) binary.
|
||||
*
|
||||
* Cloned from exec_aout_prep_zmagic() in kern/exec_aout.c; a more verbose
|
||||
* description of operation is there.
|
||||
*/
|
||||
int
|
||||
cpu_exec_aout_prep_oldzmagic(p, epp)
|
||||
struct proc *p;
|
||||
struct exec_package *epp;
|
||||
{
|
||||
struct exec *execp = epp->ep_hdr;
|
||||
|
||||
epp->ep_taddr = 0;
|
||||
epp->ep_tsize = execp->a_text;
|
||||
epp->ep_daddr = epp->ep_taddr + execp->a_text;
|
||||
epp->ep_dsize = execp->a_data + execp->a_bss;
|
||||
epp->ep_entry = execp->a_entry;
|
||||
|
||||
/*
|
||||
* check if vnode is in open for writing, because we want to * demand-page out of it. if it is, don't do it, for various
|
||||
* reasons
|
||||
*/
|
||||
if ((execp->a_text != 0 || execp->a_data != 0) &&
|
||||
epp->ep_vp->v_writecount != 0) {
|
||||
#ifdef DIAGNOSTIC
|
||||
if (epp->ep_vp->v_flag & VTEXT)
|
||||
panic("exec: a VTEXT vnode has writecount != 0\n");
|
||||
#endif
|
||||
return ETXTBSY;
|
||||
}
|
||||
epp->ep_vp->v_flag |= VTEXT;
|
||||
|
||||
/* set up command for text segment */
|
||||
NEW_VMCMD(&epp->ep_vmcmds, vmcmd_map_pagedvn, execp->a_text,
|
||||
epp->ep_taddr, epp->ep_vp, NBPG, /* XXX - should NBPG be CLBYTES? */
|
||||
VM_PROT_READ|VM_PROT_EXECUTE);
|
||||
|
||||
/* set up command for data segment */
|
||||
NEW_VMCMD(&epp->ep_vmcmds, vmcmd_map_pagedvn, execp->a_data,
|
||||
epp->ep_daddr, epp->ep_vp,
|
||||
execp->a_text + NBPG, /* XXX - should NBPG be CLBYTES? */
|
||||
VM_PROT_READ|VM_PROT_WRITE|VM_PROT_EXECUTE);
|
||||
|
||||
/* set up command for bss segment */
|
||||
NEW_VMCMD(&epp->ep_vmcmds, vmcmd_map_zero, execp->a_bss,
|
||||
epp->ep_daddr + execp->a_data, NULLVP, 0,
|
||||
VM_PROT_READ|VM_PROT_WRITE|VM_PROT_EXECUTE);
|
||||
|
||||
return exec_aout_setup_stack(p, epp);
|
||||
}
|
||||
#endif /* COMPAT_NOMID */
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: pmap.c,v 1.4 1996/10/13 03:35:26 christos Exp $ */
|
||||
/* $NetBSD: pmap.c,v 1.5 1997/01/13 14:04:58 oki Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1991, 1993
|
||||
|
@ -45,6 +45,7 @@
|
|||
* Supports:
|
||||
* 68030 with on-chip MMU X68030, X68000XVI+Xellent30, etc.
|
||||
* 68040 with on-chip MMU X68/040turbo, JUPITER-X
|
||||
* 68060 with on-chip MMU 060turbo, JUPITER-X
|
||||
*
|
||||
* Notes:
|
||||
* Don't even pay lip service to multiprocessor support.
|
||||
|
@ -183,9 +184,9 @@ int pmapvacflush = 0;
|
|||
#define PVF_TOTAL 0x80
|
||||
#endif
|
||||
|
||||
#if defined(M68040)
|
||||
int dowriteback = 1; /* 68040: enable writeback caching */
|
||||
int dokwriteback = 1; /* 68040: enable writeback caching of kernel AS */
|
||||
#if defined(M68040) || defined(M68060)
|
||||
int dowriteback = 1; /* 68040/060: enable writeback caching */
|
||||
int dokwriteback = 1; /* 68040/060: enable writeback caching of kernel AS */
|
||||
#endif
|
||||
|
||||
extern vm_offset_t pager_sva, pager_eva;
|
||||
|
@ -194,7 +195,7 @@ extern vm_offset_t pager_sva, pager_eva;
|
|||
/*
|
||||
* Get STEs and PTEs for user/kernel address space
|
||||
*/
|
||||
#if defined(M68040)
|
||||
#if defined(M68040) || defined(M68060)
|
||||
#define pmap_ste1(m, v) \
|
||||
(&((m)->pm_stab[(vm_offset_t)(v) >> SG4_SHIFT1]))
|
||||
/* XXX assumes physically contiguous ST pages (if more than one) */
|
||||
|
@ -299,7 +300,7 @@ extern unsigned long high[8];
|
|||
#ifdef HAVEVAC
|
||||
int pmap_aliasmask; /* seperation at which VA aliasing ok */
|
||||
#endif
|
||||
#if defined(M68040)
|
||||
#if defined(M68040) || defined(M68060)
|
||||
int protostfree; /* prototype (default) free ST map */
|
||||
#endif
|
||||
|
||||
|
@ -513,7 +514,7 @@ bogons:
|
|||
printf("pmap_init: pt_map [%lx - %lx)\n", addr, addr2);
|
||||
#endif
|
||||
|
||||
#if defined(M68040)
|
||||
#if defined(M68040) || defined(M68060)
|
||||
if (mmutype == MMU_68040) {
|
||||
protostfree = ~l2tobm(0);
|
||||
for (rv = MAXUL2SIZE; rv < sizeof(protostfree)*NBBY; rv++)
|
||||
|
@ -733,7 +734,7 @@ pmap_pinit(pmap)
|
|||
*/
|
||||
pmap->pm_stab = Segtabzero;
|
||||
pmap->pm_stpa = Segtabzeropa;
|
||||
#if defined(M68040)
|
||||
#if defined(M68040) || defined(M68060)
|
||||
if (mmutype == MMU_68040)
|
||||
pmap->pm_stfree = protostfree;
|
||||
#endif
|
||||
|
@ -1098,7 +1099,7 @@ pmap_protect(pmap, sva, eva, prot)
|
|||
if (firstpage && pmap_aliasmask)
|
||||
DCIS();
|
||||
#endif
|
||||
#if defined(M68040)
|
||||
#if defined(M68040) || defined(M68060)
|
||||
/*
|
||||
* Clear caches if making RO (see section
|
||||
* "7.3 Cache Coherency" in the manual).
|
||||
|
@ -1416,7 +1417,7 @@ validate:
|
|||
npte |= PG_W;
|
||||
if (!checkpv && !cacheable)
|
||||
npte |= PG_CI;
|
||||
#if defined(M68040)
|
||||
#if defined(M68040) || defined(M68060)
|
||||
if (mmutype == MMU_68040 && (npte & (PG_PROT|PG_CI)) == PG_RW)
|
||||
#ifdef DEBUG
|
||||
if (dowriteback && (dokwriteback || pmap != pmap_kernel()))
|
||||
|
@ -1432,7 +1433,7 @@ validate:
|
|||
* If so, we need not flush the TLB and caches.
|
||||
*/
|
||||
wired = ((*pte ^ npte) == PG_W);
|
||||
#if defined(M68040)
|
||||
#if defined(M68040) || defined(M68060)
|
||||
if (mmutype == MMU_68040 && !wired) {
|
||||
DCFP(pa);
|
||||
ICPP(pa);
|
||||
|
@ -2180,7 +2181,7 @@ pmap_remove_mapping(pmap, va, pte, flags)
|
|||
printf("remove: ste was %x@%p pte was %x@%p\n",
|
||||
*ste, ste, opte, pmap_pte(pmap, va));
|
||||
#endif
|
||||
#if defined(M68040)
|
||||
#if defined(M68040) || defined(M68060)
|
||||
if (mmutype == MMU_68040) {
|
||||
st_entry_t *este = &ste[NPTEPG/SG4_LEV3SIZE];
|
||||
|
||||
|
@ -2217,7 +2218,7 @@ pmap_remove_mapping(pmap, va, pte, flags)
|
|||
X68K_STSIZE);
|
||||
ptpmap->pm_stab = Segtabzero;
|
||||
ptpmap->pm_stpa = Segtabzeropa;
|
||||
#if defined(M68040)
|
||||
#if defined(M68040) || defined(M68060)
|
||||
if (mmutype == MMU_68040)
|
||||
ptpmap->pm_stfree = protostfree;
|
||||
#endif
|
||||
|
@ -2389,7 +2390,7 @@ pmap_changebit(pa, bit, setem)
|
|||
else
|
||||
npte = *pte & ~bit;
|
||||
if (*pte != npte) {
|
||||
#if defined(M68040)
|
||||
#if defined(M68040) || defined(M68060)
|
||||
/*
|
||||
* If we are changing caching status or
|
||||
* protection make sure the caches are
|
||||
|
@ -2466,12 +2467,12 @@ pmap_enter_ptpage(pmap, va)
|
|||
kmem_alloc(st_map, X68K_STSIZE);
|
||||
pmap->pm_stpa = (st_entry_t *)
|
||||
pmap_extract(pmap_kernel(), (vm_offset_t)pmap->pm_stab);
|
||||
#if defined(M68040)
|
||||
#if defined(M68040) || defined(M68060)
|
||||
if (mmutype == MMU_68040) {
|
||||
#ifdef DEBUG
|
||||
if (dowriteback && dokwriteback)
|
||||
#endif
|
||||
pmap_changebit((vm_offset_t)pmap->pm_stpa, PG_CCB, 0);
|
||||
pmap_changebit((vm_offset_t)pmap->pm_stpa, PG_CIN, 1);
|
||||
pmap->pm_stfree = protostfree;
|
||||
}
|
||||
#endif
|
||||
|
@ -2490,7 +2491,7 @@ pmap_enter_ptpage(pmap, va)
|
|||
}
|
||||
|
||||
ste = pmap_ste(pmap, va);
|
||||
#if defined(M68040)
|
||||
#if defined(M68040) || defined(M68060)
|
||||
/*
|
||||
* Allocate level 2 descriptor block if necessary
|
||||
*/
|
||||
|
@ -2603,7 +2604,7 @@ pmap_enter_ptpage(pmap, va)
|
|||
PHYS_TO_VM_PAGE(ptpa)->flags |= PG_PTPAGE;
|
||||
#endif
|
||||
}
|
||||
#if defined(M68040)
|
||||
#if defined(M68040) || defined(M68060)
|
||||
/*
|
||||
* Turn off copyback caching of page table pages,
|
||||
* could get ugly otherwise.
|
||||
|
@ -2619,7 +2620,7 @@ pmap_enter_ptpage(pmap, va)
|
|||
pmap == pmap_kernel() ? "Kernel" : "User",
|
||||
va, ptpa, pte, *pte);
|
||||
#endif
|
||||
pmap_changebit(ptpa, PG_CCB, 0);
|
||||
pmap_changebit(ptpa, PG_CIN, 1);
|
||||
}
|
||||
#endif
|
||||
/*
|
||||
|
@ -2655,7 +2656,7 @@ pmap_enter_ptpage(pmap, va)
|
|||
* it would be difficult to identify ST pages in pmap_pageable to
|
||||
* release them. We also avoid the overhead of vm_map_pageable.
|
||||
*/
|
||||
#if defined(M68040)
|
||||
#if defined(M68040) || defined(M68060)
|
||||
if (mmutype == MMU_68040) {
|
||||
st_entry_t *este;
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: pmap_bootstrap.c,v 1.4 1996/10/13 03:35:29 christos Exp $ */
|
||||
/* $NetBSD: pmap_bootstrap.c,v 1.5 1997/01/13 14:05:01 oki Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1991, 1993
|
||||
|
@ -40,7 +40,6 @@
|
|||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/msgbuf.h>
|
||||
#include <machine/pte.h>
|
||||
#include <x68k/x68k/iodevice.h>
|
||||
|
@ -191,7 +190,7 @@ pmap_bootstrap(nextpa, firstpa)
|
|||
* working. The 224mb of address space that this allows will most
|
||||
* likely be insufficient in the future (at least for the kernel).
|
||||
*/
|
||||
#if defined(M68040)
|
||||
#if defined(M68040) || defined(M68060)
|
||||
if (RELOC(mmutype, int) == MMU_68040) {
|
||||
register int num;
|
||||
|
||||
|
@ -266,13 +265,13 @@ pmap_bootstrap(nextpa, firstpa)
|
|||
while (pte < epte) {
|
||||
*pte++ = PG_NV;
|
||||
}
|
||||
/*
|
||||
* Initialize the last to point to point to the page
|
||||
/*
|
||||
* Initialize the last to point to the page
|
||||
* table page allocated earlier.
|
||||
*/
|
||||
*pte = lkptpa | PG_RW | PG_CI | PG_V;
|
||||
} else
|
||||
#endif /* M68040 */
|
||||
#endif /* M68040 || M68060 */
|
||||
{
|
||||
/*
|
||||
* Map the page table pages in both the HW segment table
|
||||
|
@ -342,7 +341,7 @@ pmap_bootstrap(nextpa, firstpa)
|
|||
* by us so far (nextpa - firstpa bytes), and pages for proc0
|
||||
* u-area and page table allocated below (RW).
|
||||
*/
|
||||
epte = &((u_int *)kptpa)[x68k_btop(nextpa - firstpa)];
|
||||
epte = &((u_int *)kptpa)[x68k_btop(kstpa - firstpa)];
|
||||
protopte = (protopte & ~PG_PROT) | PG_RW;
|
||||
/*
|
||||
* Enable copy-back caching of data pages
|
||||
|
@ -353,6 +352,21 @@ pmap_bootstrap(nextpa, firstpa)
|
|||
*pte++ = protopte;
|
||||
protopte += NBPG;
|
||||
}
|
||||
/*
|
||||
* map the kernel segment table cache invalidated for
|
||||
* these machines (for the 68040 not strictly necessary, but
|
||||
* recommended by Motorola; for the 68060 mandatory)
|
||||
*/
|
||||
epte = &((u_int *)kptpa)[x68k_btop(nextpa - firstpa)];
|
||||
protopte = (protopte & ~PG_PROT) | PG_RW;
|
||||
if (RELOC(mmutype, int) == MMU_68040) {
|
||||
protopte &= ~PG_CCB;
|
||||
protopte |= PG_CIN;
|
||||
}
|
||||
while (pte < epte) {
|
||||
*pte++ = protopte;
|
||||
protopte += NBPG;
|
||||
}
|
||||
/*
|
||||
* Finally, validate the internal IO space PTEs (RW+CI).
|
||||
* We do this here since the 320/350 MMU registers (also
|
||||
|
@ -503,6 +517,7 @@ int i;
|
|||
simple_lock_init(&kpm->pm_lock);
|
||||
kpm->pm_count = 1;
|
||||
kpm->pm_stpa = (st_entry_t *)kstpa;
|
||||
#if defined(M68040) || defined(M68060)
|
||||
/*
|
||||
* For the 040 we also initialize the free level 2
|
||||
* descriptor mask noting that we have used:
|
||||
|
@ -524,6 +539,7 @@ int i;
|
|||
num++)
|
||||
kpm->pm_stfree &= ~l2tobm(num);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -545,22 +561,56 @@ int i;
|
|||
}
|
||||
|
||||
#ifdef MACHINE_NONCONTIG
|
||||
static struct {
|
||||
caddr_t base;
|
||||
vm_size_t min;
|
||||
vm_size_t max;
|
||||
} memlist[] = {
|
||||
(caddr_t)0x01000000, 0x01000000, 0x01000000, /* TS-6BE16 16MB memory */
|
||||
(caddr_t)0x10000000, 0x00400000, 0x02000000, /* 060turbo SIMM slot (4--32MB) */
|
||||
};
|
||||
|
||||
static void
|
||||
setmemrange()
|
||||
{
|
||||
u_long p;
|
||||
numranges = 1;
|
||||
low[0] = 0;
|
||||
high[0] = *(u_long *)0x00ED0008;
|
||||
int p, i;
|
||||
vm_size_t s, min, max;
|
||||
const volatile caddr_t base = 0x00000000;
|
||||
|
||||
p = *(u_long *)0x00000000;
|
||||
*(u_long *)0x00000000 = 0;
|
||||
*(u_long *)0x01000000 = 1;
|
||||
if (*(volatile u_long *)0x00000000 == 0) {
|
||||
numranges++;
|
||||
low[1] = 0x01000000;
|
||||
high[1] = 0x02000000;
|
||||
/* first, x68k base memory */
|
||||
numranges = 0;
|
||||
low[numranges] = 0;
|
||||
high[numranges] = *(u_long *)0x00ED0008;
|
||||
numranges++;
|
||||
|
||||
p = *base;
|
||||
|
||||
/* second, discover extended memory */
|
||||
for (i = 0; i < sizeof(memlist) / sizeof(memlist[0]); i++) {
|
||||
min = memlist[i].min;
|
||||
max = memlist[i].max;
|
||||
/*
|
||||
* Normally, x68k hardware is NOT 32bit-clean.
|
||||
* But some type of extended memory is in 32bit address space.
|
||||
* Check weather.
|
||||
*/
|
||||
if (badaddr(memlist[i].base))
|
||||
continue;
|
||||
*base = 0;
|
||||
*(volatile caddr_t)memlist[i].base = 1;
|
||||
if (*base == 0) {
|
||||
low[numranges] = (u_long)memlist[i].base;
|
||||
high[numranges] = 0;
|
||||
/* range check */
|
||||
for (s = min; s <= max; s += 0x00100000)
|
||||
if (!badaddr(low[numranges] + s - 4))
|
||||
high[numranges] = low[numranges] + s;
|
||||
if (low[numranges] < high[numranges]) {
|
||||
numranges++;
|
||||
}
|
||||
}
|
||||
}
|
||||
*(u_long *)0x00000000 = p;
|
||||
|
||||
*base = p;
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: sys_machdep.c,v 1.3 1996/06/05 16:21:44 oki Exp $ */
|
||||
/* $NetBSD: sys_machdep.c,v 1.4 1997/01/13 14:05:02 oki Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1982, 1986, 1993
|
||||
|
@ -138,7 +138,7 @@ cachectl(req, addr, len)
|
|||
{
|
||||
int error = 0;
|
||||
|
||||
#if defined(M68040)
|
||||
#if defined(M68040) || defined(M68060)
|
||||
if (mmutype == MMU_68040) {
|
||||
register int inc = 0;
|
||||
int pa = 0, doall = 0;
|
||||
|
@ -255,7 +255,7 @@ dma_cachectl(addr, len)
|
|||
caddr_t addr;
|
||||
int len;
|
||||
{
|
||||
#ifdef M68040
|
||||
#if defined(M68040) || defined(M68060)
|
||||
if (mmutype == MMU_68040) {
|
||||
register int inc = 0;
|
||||
int pa = 0;
|
||||
|
@ -287,7 +287,7 @@ dma_cachectl(addr, len)
|
|||
addr += inc;
|
||||
} while (addr < end);
|
||||
}
|
||||
#endif /* M68040 */
|
||||
#endif /* M68040 || M68060 */
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: trap.c,v 1.5 1996/10/13 03:35:33 christos Exp $ */
|
||||
/* $NetBSD: trap.c,v 1.6 1997/01/13 14:05:04 oki Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1988 University of Utah.
|
||||
|
@ -65,17 +65,34 @@
|
|||
#include <vm/vm.h>
|
||||
#include <vm/pmap.h>
|
||||
|
||||
#ifdef COMPAT_HPUX
|
||||
#include <compat/hpux/hpux.h>
|
||||
#ifdef FPU_EMULATE
|
||||
#include <m68k/fpe/fpu_emulate.h>
|
||||
#endif
|
||||
|
||||
#ifdef M68040
|
||||
#ifdef COMPAT_HPUX
|
||||
#include <compat/hpux/hpux.h>
|
||||
extern struct emul emul_hpux;
|
||||
#endif
|
||||
|
||||
#ifdef COMPAT_SUNOS
|
||||
#include <compat/sunos/sunos_syscall.h>
|
||||
extern struct emul emul_sunos;
|
||||
#endif
|
||||
|
||||
int writeback __P((struct frame *fp, int docachepush));
|
||||
void trap __P((int type, u_int code, u_int v, struct frame frame));
|
||||
void syscall __P((register_t code, struct frame frame));
|
||||
|
||||
#if defined(M68040) || defined(M68060)
|
||||
#ifdef DEBUG
|
||||
static void dumpssw __P((u_short));
|
||||
static void dumpwb __P((int, u_short, u_int, u_int));
|
||||
#endif
|
||||
#endif
|
||||
|
||||
static inline void userret __P((struct proc *p, struct frame *fp,
|
||||
u_quad_t oticks, u_int faultaddr, int fromtrap));
|
||||
|
||||
char *trap_type[] = {
|
||||
"Bus error",
|
||||
"Address error",
|
||||
|
@ -98,11 +115,11 @@ int trap_types = sizeof trap_type / sizeof trap_type[0];
|
|||
* Size of various exception stack frames (minus the standard 8 bytes)
|
||||
*/
|
||||
short exframesize[] = {
|
||||
FMT0SIZE, /* type 0 - normal (68020/030/040) */
|
||||
FMT0SIZE, /* type 0 - normal (68020/030/040/060) */
|
||||
FMT1SIZE, /* type 1 - throwaway (68020/030/040) */
|
||||
FMT2SIZE, /* type 2 - normal 6-word (68020/030/040) */
|
||||
FMT3SIZE, /* type 3 - FP post-instruction (68040) */
|
||||
FMT4SIZE, /* type 4 - access error (68060) */
|
||||
FMT2SIZE, /* type 2 - normal 6-word (68020/030/040/060) */
|
||||
FMT3SIZE, /* type 3 - FP post-instruction (68040/060) */
|
||||
FMT4SIZE, /* type 4 - access error/fp disabled (68060) */
|
||||
-1, -1, /* type 5-6 - undefined */
|
||||
FMT7SIZE, /* type 7 - access error (68040) */
|
||||
58, /* type 8 - bus fault (68010) */
|
||||
|
@ -112,25 +129,44 @@ short exframesize[] = {
|
|||
-1, -1, -1, -1 /* type C-F - undefined */
|
||||
};
|
||||
|
||||
#ifdef M68040
|
||||
#define KDFAULT(c) (mmutype == MMU_68040 ? \
|
||||
((c) & SSW4_TMMASK) == SSW4_TMKD : \
|
||||
((c) & (SSW_DF|FC_SUPERD)) == (SSW_DF|FC_SUPERD))
|
||||
#define WRFAULT(c) (mmutype == MMU_68040 ? \
|
||||
((c) & SSW4_RW) == 0 : \
|
||||
((c) & (SSW_DF|SSW_RW)) == SSW_DF)
|
||||
#ifdef M68060
|
||||
#define KDFAULT_060(c) (cputype == CPU_68060 && ((c) & FSLW_TM_SV))
|
||||
#define WRFAULT_060(c) (cputype == CPU_68060 && ((c) & FSLW_RW_W))
|
||||
#else
|
||||
#define KDFAULT(c) (((c) & (SSW_DF|SSW_FCMASK)) == (SSW_DF|FC_SUPERD))
|
||||
#define WRFAULT(c) (((c) & (SSW_DF|SSW_RW)) == SSW_DF)
|
||||
#define KDFAULT_060(c) 0
|
||||
#define WRFAULT_060(c) 0
|
||||
#endif
|
||||
|
||||
#ifdef M68040
|
||||
#define KDFAULT_040(c) (cputype == CPU_68040 && \
|
||||
((c) & SSW4_TMMASK) == SSW4_TMKD)
|
||||
#define WRFAULT_040(c) (cputype == CPU_68040 && \
|
||||
((c) & SSW4_RW) == 0)
|
||||
#else
|
||||
#define KDFAULT_040(c) 0
|
||||
#define WRFAULT_040(c) 0
|
||||
#endif
|
||||
|
||||
#if defined(M68030) || defined(M68020)
|
||||
#define KDFAULT_OTH(c) (cputype <= CPU_68030 && \
|
||||
((c) & (SSW_DF|SSW_FCMASK)) == (SSW_DF|FC_SUPERD))
|
||||
#define WRFAULT_OTH(c) (cputype <= CPU_68030 && \
|
||||
((c) & (SSW_DF|SSW_RW)) == SSW_DF)
|
||||
#else
|
||||
#define KDFAULT_OTH(c) 0
|
||||
#define WRFAULT_OTH(c) 0
|
||||
#endif
|
||||
|
||||
#define KDFAULT(c) (KDFAULT_060(c) || KDFAULT_040(c) || KDFAULT_OTH(c))
|
||||
#define WRFAULT(c) (WRFAULT_060(c) || WRFAULT_040(c) || WRFAULT_OTH(c))
|
||||
|
||||
#ifdef DEBUG
|
||||
int mmudebug = 0;
|
||||
int mmupid = -1;
|
||||
#define MDB_FOLLOW 1
|
||||
#define MDB_WBFOLLOW 2
|
||||
#define MDB_WBFAILED 4
|
||||
#define MDB_ISPID(p) (p) == mmupid
|
||||
#define MDB_ISPID(p) ((p) == mmupid)
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
@ -191,7 +227,7 @@ again:
|
|||
* we just return to the user without sucessfully completing
|
||||
* the writebacks. Maybe we should just drop the sucker?
|
||||
*/
|
||||
if (mmutype == MMU_68040 && fp->f_format == FMT7) {
|
||||
if (cputype == CPU_68040 && fp->f_format == FMT7) {
|
||||
if (beenhere) {
|
||||
#ifdef DEBUG
|
||||
if (mmudebug & MDB_WBFAILED)
|
||||
|
@ -225,20 +261,23 @@ trap(type, code, v, frame)
|
|||
struct frame frame;
|
||||
{
|
||||
extern char fubail[], subail[];
|
||||
#ifdef DDB
|
||||
extern char trap0[], trap1[], trap2[], trap12[], trap15[], illinst[];
|
||||
#endif
|
||||
register struct proc *p;
|
||||
register int i;
|
||||
register int i, s;
|
||||
u_int ucode;
|
||||
u_quad_t sticks;
|
||||
#ifdef COMPAT_HPUX
|
||||
extern struct emul emul_hpux;
|
||||
#endif
|
||||
|
||||
cnt.v_trap++;
|
||||
p = curproc;
|
||||
ucode = 0;
|
||||
|
||||
/* I have verified that this DOES happen! -gwr */
|
||||
if (p == NULL)
|
||||
p = &proc0;
|
||||
#ifdef DIAGNOSTIC
|
||||
if (p->p_addr == NULL)
|
||||
panic("trap: no pcb");
|
||||
#endif
|
||||
|
||||
if (USERMODE(frame.f_sr)) {
|
||||
type |= T_USER;
|
||||
sticks = p->p_sticks;
|
||||
|
@ -247,28 +286,51 @@ trap(type, code, v, frame)
|
|||
switch (type) {
|
||||
|
||||
default:
|
||||
dopanic:
|
||||
printf("trap type %d, code = %x, v = %x\n", type, code, v);
|
||||
#ifdef DDB
|
||||
if (kdb_trap(type, &frame))
|
||||
return;
|
||||
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, &frame))
|
||||
goto kgdb_cont;
|
||||
#endif
|
||||
#ifdef DDB
|
||||
(void) kdb_trap(type, &frame);
|
||||
#endif
|
||||
kgdb_cont:
|
||||
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");
|
||||
|
||||
case T_BUSERR: /* kernel bus error */
|
||||
if (!p->p_addr->u_pcb.pcb_onfault)
|
||||
if (p->p_addr->u_pcb.pcb_onfault == 0)
|
||||
goto dopanic;
|
||||
/* FALLTHROUGH */
|
||||
|
||||
copyfault:
|
||||
/*
|
||||
* If we have arranged to catch this fault in any of the
|
||||
* copy to/from user space routines, set PC to return to
|
||||
* indicated location and set flag informing buserror code
|
||||
* that it may need to clean up stack frame.
|
||||
*/
|
||||
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;
|
||||
|
@ -323,9 +385,13 @@ copyfault:
|
|||
break;
|
||||
#endif
|
||||
|
||||
#ifdef M68040
|
||||
case T_FPEMULI|T_USER: /* unimplemented FP instuction */
|
||||
case T_FPEMULD|T_USER: /* unimplemented FP data type */
|
||||
#ifdef FPU_EMULATE
|
||||
i = fpu_emulate(&frame, &p->p_addr->u_pcb.pcb_fpregs);
|
||||
/* XXX -- deal with tracing? (frame.f_sr & PSL_T) */
|
||||
break;
|
||||
#elif defined(M68040) || defined(M68060)
|
||||
/* XXX need to FSAVE */
|
||||
printf("pid %d(%s): unimplemented FP %s at %x (EA %x)\n",
|
||||
p->p_pid, p->p_comm,
|
||||
|
@ -395,34 +461,39 @@ copyfault:
|
|||
* XXX: Trace traps are a nightmare.
|
||||
*
|
||||
* HP-UX uses trap #1 for breakpoints,
|
||||
* HPBSD uses trap #2,
|
||||
* NetBSD/m68k uses trap #2,
|
||||
* SUN 3.x uses trap #15,
|
||||
* KGDB uses trap #15 (for kernel breakpoints; handled elsewhere).
|
||||
* DDB and KGDB uses trap #15 (for kernel breakpoints;
|
||||
* handled elsewhere).
|
||||
*
|
||||
* HPBSD and HP-UX traps both get mapped by locore.s into T_TRACE.
|
||||
* NetBSD 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 */
|
||||
#ifdef DDB
|
||||
if (type == T_TRAP15 ||
|
||||
((caddr_t)frame.f_pc != trap0 &&
|
||||
(caddr_t)frame.f_pc != trap1 &&
|
||||
(caddr_t)frame.f_pc != trap2 &&
|
||||
(caddr_t)frame.f_pc != trap12 &&
|
||||
(caddr_t)frame.f_pc != trap15 &&
|
||||
(caddr_t)frame.f_pc != illinst)) {
|
||||
if (kdb_trap(type, &frame))
|
||||
return;
|
||||
}
|
||||
case T_TRAP15: /* kernel breakpoint */
|
||||
#ifdef DEBUG
|
||||
printf("unexpected kernel trace trap, type = %d\n", type);
|
||||
printf("program counter = 0x%x\n", frame.f_pc);
|
||||
#endif
|
||||
frame.f_sr &= ~PSL_T;
|
||||
i = SIGTRAP;
|
||||
break;
|
||||
return;
|
||||
|
||||
case T_TRACE|T_USER: /* user trace trap */
|
||||
case T_TRAP15|T_USER: /* SUN user trace trap */
|
||||
#ifdef COMPAT_SUNOS
|
||||
/*
|
||||
* XXX This comment/code is not consistent XXX
|
||||
* SunOS seems to use Trap #2 for some obscure
|
||||
* fpu operations. So far, just ignore it, but
|
||||
* DONT trap on it..
|
||||
*/
|
||||
if (p->p_emul == &emul_sunos)
|
||||
goto out;
|
||||
#endif
|
||||
frame.f_sr &= ~PSL_T;
|
||||
i = SIGTRAP;
|
||||
break;
|
||||
|
@ -514,22 +585,26 @@ copyfault:
|
|||
* The last can occur during an exec() copyin where the
|
||||
* argument space is lazy-allocated.
|
||||
*/
|
||||
if (type == T_MMUFLT &&
|
||||
(!p->p_addr->u_pcb.pcb_onfault || KDFAULT(code)))
|
||||
if ((type & T_USER) == 0 &&
|
||||
((p->p_addr->u_pcb.pcb_onfault == 0) || KDFAULT(code)))
|
||||
map = kernel_map;
|
||||
else
|
||||
map = &vm->vm_map;
|
||||
map = vm ? &vm->vm_map : kernel_map;
|
||||
|
||||
if (WRFAULT(code))
|
||||
ftype = VM_PROT_READ | VM_PROT_WRITE;
|
||||
else
|
||||
ftype = VM_PROT_READ;
|
||||
|
||||
va = trunc_page((vm_offset_t)v);
|
||||
#ifdef DEBUG
|
||||
|
||||
if (map == kernel_map && va == 0) {
|
||||
printf("trap: bad kernel access at %x\n", v);
|
||||
printf("trap: bad kernel %s access at 0x%x\n",
|
||||
(ftype & VM_PROT_WRITE) ? "read/write" :
|
||||
"read", v);
|
||||
goto dopanic;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef COMPAT_HPUX
|
||||
if (ISHPMMADDR(va)) {
|
||||
vm_offset_t bva;
|
||||
|
@ -556,7 +631,8 @@ copyfault:
|
|||
* the current limit and we need to reflect that as an access
|
||||
* error.
|
||||
*/
|
||||
if ((caddr_t)va >= vm->vm_maxsaddr && map != kernel_map) {
|
||||
if ((vm != NULL && (caddr_t)va >= vm->vm_maxsaddr)
|
||||
&& map != kernel_map) {
|
||||
if (rv == KERN_SUCCESS) {
|
||||
unsigned nss;
|
||||
|
||||
|
@ -569,7 +645,7 @@ copyfault:
|
|||
if (rv == KERN_SUCCESS) {
|
||||
if (type == T_MMUFLT) {
|
||||
#ifdef M68040
|
||||
if (mmutype == MMU_68040)
|
||||
if (cputype == CPU_68040)
|
||||
(void) writeback(&frame, 1);
|
||||
#endif
|
||||
return;
|
||||
|
@ -912,9 +988,6 @@ syscall(code, frame)
|
|||
size_t argsize;
|
||||
register_t args[8], rval[2];
|
||||
u_quad_t sticks;
|
||||
#ifdef COMPAT_SUNOS
|
||||
extern struct emul emul_sunos;
|
||||
#endif
|
||||
|
||||
cnt.v_syscall++;
|
||||
if (!USERMODE(frame.f_sr))
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
| $NetBSD: vectors.s,v 1.1 1996/05/05 12:17:24 oki Exp $
|
||||
| $NetBSD: vectors.s,v 1.2 1997/01/13 14:05:05 oki Exp $
|
||||
|
||||
| Copyright (c) 1988 University of Utah
|
||||
| Copyright (c) 1990, 1993
|
||||
|
@ -39,7 +39,7 @@
|
|||
#define _scctrap _badtrap
|
||||
|
||||
.text
|
||||
.globl _buserr,_addrerr
|
||||
.globl _vectab,_buserr,_addrerr
|
||||
.globl _illinst,_zerodiv,_chkinst,_trapvinst,_privinst,_trace
|
||||
.globl _badtrap
|
||||
.globl _spurintr,_lev1intr,_lev2intr,_lev3intr
|
||||
|
@ -48,7 +48,7 @@
|
|||
.globl _fpfline, _fpunsupp, _fpfault
|
||||
.globl _trap12
|
||||
|
||||
Lvectab:
|
||||
_vectab:
|
||||
.long 0x4ef80400 /* 0: jmp 0x400:w (unused reset SSP) */
|
||||
.long 0 /* 1: NOT USED (reset PC) */
|
||||
.long _buserr /* 2: bus error */
|
||||
|
|
Loading…
Reference in New Issue