first commit of M68060 and FPU_EMULATE support.

M68060 support by YAMASAKI Yasushi, few arranged by me.
This commit is contained in:
oki 1997-01-13 14:04:42 +00:00
parent 121971f622
commit 0e58d64c9e
13 changed files with 795 additions and 376 deletions

View File

@ -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

View File

@ -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 $@

View File

@ -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

View File

@ -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 &&

View File

@ -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++;
}
}

View File

@ -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);

View File

@ -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

View File

@ -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 */

View File

@ -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;

View File

@ -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

View File

@ -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);
}

View File

@ -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))

View File

@ -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 */