Commit 7670c701 authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'for-linus' of git://github.com/gregungerer/m68knommu

* 'for-linus' of git://github.com/gregungerer/m68knommu:
  m68k: drop unused Kconfig symbols
  m68k: drop unused Kconfig symbols
  m68knommu: create common externs for _ram* vars
  m68knommu: remove extern declarations of memory_start/memory_end from mm/init
  m68knommu: use generic section names in mm/init code
  m68knommu: use generic section names in setup code
  m68k: merge the mmu and non-mmu traps.c files
  m68k: move hardware vector setting from traps.c to its own file
  m68k: merge mmu and non-mmu include/asm/entry.h files
  m68k: merge the mmu and non-mmu kernel/Makefiles
  m68k: merge mmu and non-mmu arch Makefiles
  m68k: reorganize Kconfig options to improve mmu/non-mmu selections
  m68knommu: fix problems with SPI/GPIO on ColdFire 520x
  m68k: fix memcpy to unmatched/unaligned source and dest on 68000
parents 0110bba5 dbcbf588
......@@ -21,6 +21,15 @@ config ARCH_HAS_ILOG2_U32
config ARCH_HAS_ILOG2_U64
bool
config GENERIC_CLOCKEVENTS
bool
config GENERIC_CMOS_UPDATE
def_bool !MMU
config GENERIC_GPIO
bool
config GENERIC_HWEIGHT
bool
default y
......@@ -29,10 +38,16 @@ config GENERIC_CALIBRATE_DELAY
bool
default y
config GENERIC_IOMAP
def_bool MMU
config TIME_LOW_RES
bool
default y
config ARCH_USES_GETTIMEOFFSET
def_bool MMU
config NO_IOPORT
def_bool y
......@@ -62,13 +77,31 @@ config MMU
Select if you want MMU-based virtualised addressing space
support by paged memory management. If unsure, say 'Y'.
menu "Platform dependent setup"
config MMU_MOTOROLA
bool
config MMU_SUN3
bool
depends on MMU && !MMU_MOTOROLA
menu "Platform setup"
source arch/m68k/Kconfig.cpu
source arch/m68k/Kconfig.machine
source arch/m68k/Kconfig.bus
endmenu
menu "Kernel Features"
if MMU
source arch/m68k/Kconfig.mmu
if COLDFIRE
source "kernel/Kconfig.preempt"
endif
if !MMU
source arch/m68k/Kconfig.nommu
if !MMU || COLDFIRE
source "kernel/time/Kconfig"
endif
source "mm/Kconfig"
......@@ -85,9 +118,9 @@ if !MMU
menu "Power management options"
config PM
bool "Power Management support"
help
Support processor power management modes
bool "Power Management support"
help
Support processor power management modes
endmenu
endif
......@@ -96,151 +129,7 @@ source "net/Kconfig"
source "drivers/Kconfig"
if MMU
menu "Character devices"
config ATARI_MFPSER
tristate "Atari MFP serial support"
depends on ATARI
---help---
If you like to use the MFP serial ports ("Modem1", "Serial1") under
Linux, say Y. The driver equally supports all kinds of MFP serial
ports and automatically detects whether Serial1 is available.
To compile this driver as a module, choose M here.
Note for Falcon users: You also have an MFP port, it's just not
wired to the outside... But you could use the port under Linux.
config ATARI_MIDI
tristate "Atari MIDI serial support"
depends on ATARI
help
If you want to use your Atari's MIDI port in Linux, say Y.
To compile this driver as a module, choose M here.
config ATARI_DSP56K
tristate "Atari DSP56k support (EXPERIMENTAL)"
depends on ATARI && EXPERIMENTAL
help
If you want to be able to use the DSP56001 in Falcons, say Y. This
driver is still experimental, and if you don't know what it is, or
if you don't have this processor, just say N.
To compile this driver as a module, choose M here.
config AMIGA_BUILTIN_SERIAL
tristate "Amiga builtin serial support"
depends on AMIGA
help
If you want to use your Amiga's built-in serial port in Linux,
answer Y.
To compile this driver as a module, choose M here.
config MULTIFACE_III_TTY
tristate "Multiface Card III serial support"
depends on AMIGA
help
If you want to use a Multiface III card's serial port in Linux,
answer Y.
To compile this driver as a module, choose M here.
config GVPIOEXT
tristate "GVP IO-Extender support"
depends on PARPORT=n && ZORRO
help
If you want to use a GVP IO-Extender serial card in Linux, say Y.
Otherwise, say N.
config GVPIOEXT_LP
tristate "GVP IO-Extender parallel printer support"
depends on GVPIOEXT
help
Say Y to enable driving a printer from the parallel port on your
GVP IO-Extender card, N otherwise.
config GVPIOEXT_PLIP
tristate "GVP IO-Extender PLIP support"
depends on GVPIOEXT
help
Say Y to enable doing IP over the parallel port on your GVP
IO-Extender card, N otherwise.
config MAC_HID
bool
depends on INPUT_ADBHID
default y
config HPDCA
tristate "HP DCA serial support"
depends on DIO && SERIAL_8250
help
If you want to use the internal "DCA" serial ports on an HP300
machine, say Y here.
config HPAPCI
tristate "HP APCI serial support"
depends on HP300 && SERIAL_8250 && EXPERIMENTAL
help
If you want to use the internal "APCI" serial ports on an HP400
machine, say Y here.
config MVME147_SCC
bool "SCC support for MVME147 serial ports"
depends on MVME147 && BROKEN
help
This is the driver for the serial ports on the Motorola MVME147
boards. Everyone using one of these boards should say Y here.
config MVME162_SCC
bool "SCC support for MVME162 serial ports"
depends on MVME16x && BROKEN
help
This is the driver for the serial ports on the Motorola MVME162 and
172 boards. Everyone using one of these boards should say Y here.
config BVME6000_SCC
bool "SCC support for BVME6000 serial ports"
depends on BVME6000 && BROKEN
help
This is the driver for the serial ports on the BVME4000 and BVME6000
boards from BVM Ltd. Everyone using one of these boards should say
Y here.
config DN_SERIAL
bool "Support for DN serial port (dummy)"
depends on APOLLO
config SERIAL_CONSOLE
bool "Support for serial port console"
depends on (AMIGA || ATARI || SUN3 || SUN3X || VME || APOLLO) && (ATARI_MFPSER=y || ATARI_MIDI=y || AMIGA_BUILTIN_SERIAL=y || GVPIOEXT=y || MULTIFACE_III_TTY=y || SERIAL=y || MVME147_SCC || SERIAL167 || MVME162_SCC || BVME6000_SCC || DN_SERIAL)
---help---
If you say Y here, it will be possible to use a serial port as the
system console (the system console is the device which receives all
kernel messages and warnings and which allows logins in single user
mode). This could be useful if some terminal or printer is connected
to that serial port.
Even if you say Y here, the currently visible virtual console
(/dev/tty0) will still be used as the system console by default, but
you can alter that using a kernel command line option such as
"console=ttyS1". (Try "man bootparam" or see the documentation of
your boot loader (lilo or loadlin) about how to pass options to the
kernel at boot time.)
If you don't have a VGA card installed and you say Y here, the
kernel will automatically use the first serial line, /dev/ttyS0, as
system console.
If unsure, say N.
endmenu
endif
source "arch/m68k/Kconfig.devices"
source "fs/Kconfig"
......
if MMU
comment "Bus Support"
config NUBUS
bool
depends on MAC
default y
config ZORRO
bool "Amiga Zorro (AutoConfig) bus support"
depends on AMIGA
help
This enables support for the Zorro bus in the Amiga. If you have
expansion cards in your Amiga that conform to the Amiga
AutoConfig(tm) specification, say Y, otherwise N. Note that even
expansion cards that do not fit in the Zorro slots but fit in e.g.
the CPU slot may fall in this category, so you have to say Y to let
Linux use these.
config AMIGA_PCMCIA
bool "Amiga 1200/600 PCMCIA support (EXPERIMENTAL)"
depends on AMIGA && EXPERIMENTAL
help
Include support in the kernel for pcmcia on Amiga 1200 and Amiga
600. If you intend to use pcmcia cards say Y; otherwise say N.
config ISA
bool
depends on Q40 || AMIGA_PCMCIA
default y
help
Find out whether you have ISA slots on your motherboard. ISA is the
name of a bus system, i.e. the way the CPU talks to the other stuff
inside your box. Other bus systems are PCI, EISA, MicroChannel
(MCA) or VESA. ISA is an older system, now being displaced by PCI;
newer boards don't support it. If you have ISA, say Y, otherwise N.
config GENERIC_ISA_DMA
def_bool ISA
source "drivers/pci/Kconfig"
source "drivers/zorro/Kconfig"
endif
if !MMU
config ISA_DMA_API
def_bool !M5272
source "drivers/pcmcia/Kconfig"
endif
config GENERIC_IOMAP
bool
default y
config ARCH_MAY_HAVE_PC_FDC
bool
depends on BROKEN && (Q40 || SUN3X)
default y
config ARCH_USES_GETTIMEOFFSET
def_bool y
config EISA
bool
---help---
The Extended Industry Standard Architecture (EISA) bus was
developed as an open alternative to the IBM MicroChannel bus.
The EISA bus provided some of the features of the IBM MicroChannel
bus while maintaining backward compatibility with cards made for
the older ISA bus. The EISA bus saw limited use between 1988 and
1995 when it was made obsolete by the PCI bus.
Say Y here if you are building a kernel for an EISA-based machine.
Otherwise, say N.
comment "Processor Type"
config MCA
config M68000
bool
select CPU_HAS_NO_BITFIELDS
help
MicroChannel Architecture is found in some IBM PS/2 machines and
laptops. It is a bus system similar to PCI or ISA. See
<file:Documentation/mca.txt> (and especially the web page given
there) before attempting to build an MCA bus kernel.
The Freescale (was Motorola) 68000 CPU is the first generation of
the well known M68K family of processors. The CPU core as well as
being available as a stand alone CPU was also used in many
System-On-Chip devices (eg 68328, 68302, etc). It does not contain
a paging MMU.
config PCMCIA
tristate
---help---
Say Y here if you want to attach PCMCIA- or PC-cards to your Linux
computer. These are credit-card size devices such as network cards,
modems or hard drives often used with laptops computers. There are
actually two varieties of these cards: the older 16 bit PCMCIA cards
and the newer 32 bit CardBus cards. If you want to use CardBus
cards, you need to say Y here and also to "CardBus support" below.
To use your PC-cards, you will need supporting software from David
Hinds' pcmcia-cs package (see the file <file:Documentation/Changes>
for location). Please also read the PCMCIA-HOWTO, available from
<http://www.tldp.org/docs.html#howto>.
To compile this driver as modules, choose M here: the
modules will be called pcmcia_core and ds.
config AMIGA
bool "Amiga support"
select MMU_MOTOROLA if MMU
help
This option enables support for the Amiga series of computers. If
you plan to use this kernel on an Amiga, say Y here and browse the
material available in <file:Documentation/m68k>; otherwise say N.
config ATARI
bool "Atari support"
select MMU_MOTOROLA if MMU
help
This option enables support for the 68000-based Atari series of
computers (including the TT, Falcon and Medusa). If you plan to use
this kernel on an Atari, say Y here and browse the material
available in <file:Documentation/m68k>; otherwise say N.
config MAC
bool "Macintosh support"
select MMU_MOTOROLA if MMU
help
This option enables support for the Apple Macintosh series of
computers (yes, there is experimental support now, at least for part
of the series).
Say N unless you're willing to code the remaining necessary support.
;)
config NUBUS
bool
depends on MAC
default y
config M68K_L2_CACHE
config MCPU32
bool
depends on MAC
default y
config APOLLO
bool "Apollo support"
select MMU_MOTOROLA if MMU
help
Say Y here if you want to run Linux on an MC680x0-based Apollo
Domain workstation such as the DN3500.
config VME
bool "VME (Motorola and BVM) support"
select MMU_MOTOROLA if MMU
help
Say Y here if you want to build a kernel for a 680x0 based VME
board. Boards currently supported include Motorola boards MVME147,
MVME162, MVME166, MVME167, MVME172, and MVME177. BVME4000 and
BVME6000 boards from BVM Ltd are also supported.
config MVME147
bool "MVME147 support"
depends on VME
help
Say Y to include support for early Motorola VME boards. This will
build a kernel which can run on MVME147 single-board computers. If
you select this option you will have to select the appropriate
drivers for SCSI, Ethernet and serial ports later on.
config MVME16x
bool "MVME162, 166 and 167 support"
depends on VME
help
Say Y to include support for Motorola VME boards. This will build a
kernel which can run on MVME162, MVME166, MVME167, MVME172, and
MVME177 boards. If you select this option you will have to select
the appropriate drivers for SCSI, Ethernet and serial ports later
on.
config BVME6000
bool "BVME4000 and BVME6000 support"
depends on VME
help
Say Y to include support for VME boards from BVM Ltd. This will
build a kernel which can run on BVME4000 and BVME6000 boards. If
you select this option you will have to select the appropriate
drivers for SCSI, Ethernet and serial ports later on.
config HP300
bool "HP9000/300 and HP9000/400 support"
select MMU_MOTOROLA if MMU
help
This option enables support for the HP9000/300 and HP9000/400 series
of workstations. Support for these machines is still somewhat
experimental. If you plan to try to use the kernel on such a machine
say Y here.
Everybody else says N.
config DIO
bool "DIO bus support"
depends on HP300
default y
help
Say Y here to enable support for the "DIO" expansion bus used in
HP300 machines. If you are using such a system you almost certainly
want this.
config SUN3X
bool "Sun3x support"
select MMU_MOTOROLA if MMU
select M68030
select CPU_HAS_NO_BITFIELDS
help
This option enables support for the Sun 3x series of workstations.
Be warned that this support is very experimental.
Note that Sun 3x kernels are not compatible with Sun 3 hardware.
General Linux information on the Sun 3x series (now discontinued)
is at <http://www.angelfire.com/ca2/tech68k/sun3.html>.
The Freescale (was then Motorola) CPU32 is a CPU core that is
based on the 68020 processor. For the most part it is used in
System-On-Chip parts, and does not contain a paging MMU.
If you don't want to compile a kernel for a Sun 3x, say N.
config Q40
bool "Q40/Q60 support"
select MMU_MOTOROLA if MMU
help
The Q40 is a Motorola 68040-based successor to the Sinclair QL
manufactured in Germany. There is an official Q40 home page at
<http://www.q40.de/>. This option enables support for the Q40 and
Q60. Select your CPU below. For 68LC060 don't forget to enable FPU
emulation.
config SUN3
bool "Sun3 support"
depends on !MMU_MOTOROLA
select MMU_SUN3 if MMU
select M68020
help
This option enables support for the Sun 3 series of workstations
(3/50, 3/60, 3/1xx, 3/2xx systems). Enabling this option requires
that all other hardware types must be disabled, as Sun 3 kernels
are incompatible with all other m68k targets (including Sun 3x!).
If you don't want to compile a kernel exclusively for a Sun 3, say N.
config NATFEAT
bool "ARAnyM emulator support"
depends on ATARI
help
This option enables support for ARAnyM native features, such as
access to a disk image as /dev/hda.
config NFBLOCK
tristate "NatFeat block device support"
depends on BLOCK && NATFEAT
help
Say Y to include support for the ARAnyM NatFeat block device
which allows direct access to the hard drives without using
the hardware emulation.
config NFCON
tristate "NatFeat console driver"
depends on NATFEAT
help
Say Y to include support for the ARAnyM NatFeat console driver
which allows the console output to be redirected to the stderr
output of ARAnyM.
config NFETH
tristate "NatFeat Ethernet support"
depends on NET_ETHERNET && NATFEAT
config COLDFIRE
bool
select GENERIC_GPIO
select ARCH_REQUIRE_GPIOLIB
select CPU_HAS_NO_BITFIELDS
help
Say Y to include support for the ARAnyM NatFeat network device
which will emulate a regular ethernet device while presenting an
ethertap device to the host system.
comment "Processor type"
The Freescale ColdFire family of processors is a modern derivitive
of the 68000 processor family. They are mainly targeted at embedded
applications, and are all System-On-Chip (SOC) devices, as opposed
to stand alone CPUs. They implement a subset of the original 68000
processor instruction set.
config M68020
bool "68020 support"
depends on MMU
help
If you anticipate running this kernel on a computer with a MC68020
processor, say Y. Otherwise, say N. Note that the 68020 requires a
......@@ -231,7 +41,7 @@ config M68020
config M68030
bool "68030 support"
depends on !MMU_SUN3
depends on MMU && !MMU_SUN3
help
If you anticipate running this kernel on a computer with a MC68030
processor, say Y. Otherwise, say N. Note that a MC68EC030 will not
......@@ -239,7 +49,7 @@ config M68030
config M68040
bool "68040 support"
depends on !MMU_SUN3
depends on MMU && !MMU_SUN3
help
If you anticipate running this kernel on a computer with a MC68LC040
or MC68040 processor, say Y. Otherwise, say N. Note that an
......@@ -248,20 +58,186 @@ config M68040
config M68060
bool "68060 support"
depends on !MMU_SUN3
depends on MMU && !MMU_SUN3
help
If you anticipate running this kernel on a computer with a MC68060
processor, say Y. Otherwise, say N.
config MMU_MOTOROLA
config M68328
bool "MC68328"
depends on !MMU
select M68000
help
Motorola 68328 processor support.
config M68EZ328
bool "MC68EZ328"
depends on !MMU
select M68000
help
Motorola 68EX328 processor support.
config M68VZ328
bool "MC68VZ328"
depends on !MMU
select M68000
help
Motorola 68VZ328 processor support.
config M68360
bool "MC68360"
depends on !MMU
select MCPU32
help
Motorola 68360 processor support.
config M5206
bool "MCF5206"
depends on !MMU
select COLDFIRE
select COLDFIRE_SW_A7
select HAVE_MBAR
help
Motorola ColdFire 5206 processor support.
config M5206e
bool "MCF5206e"
depends on !MMU
select COLDFIRE
select COLDFIRE_SW_A7
select HAVE_MBAR
help
Motorola ColdFire 5206e processor support.
config M520x
bool "MCF520x"
depends on !MMU
select COLDFIRE
select GENERIC_CLOCKEVENTS
select HAVE_CACHE_SPLIT
help
Freescale Coldfire 5207/5208 processor support.
config M523x
bool "MCF523x"
depends on !MMU
select COLDFIRE
select GENERIC_CLOCKEVENTS
select HAVE_CACHE_SPLIT
select HAVE_IPSBAR
help
Freescale Coldfire 5230/1/2/4/5 processor support
config M5249
bool "MCF5249"
depends on !MMU
select COLDFIRE
select COLDFIRE_SW_A7
select HAVE_MBAR
help
Motorola ColdFire 5249 processor support.
config M527x
bool
config MMU_SUN3
config M5271
bool "MCF5271"
depends on !MMU
select COLDFIRE
select M527x
select HAVE_CACHE_SPLIT
select HAVE_IPSBAR
select GENERIC_CLOCKEVENTS
help
Freescale (Motorola) ColdFire 5270/5271 processor support.
config M5272
bool "MCF5272"
depends on !MMU
select COLDFIRE
select COLDFIRE_SW_A7
select HAVE_MBAR
help
Motorola ColdFire 5272 processor support.
config M5275
bool "MCF5275"
depends on !MMU
select COLDFIRE
select M527x
select HAVE_CACHE_SPLIT
select HAVE_IPSBAR
select GENERIC_CLOCKEVENTS
help
Freescale (Motorola) ColdFire 5274/5275 processor support.
config M528x
bool "MCF528x"
depends on !MMU
select COLDFIRE
select GENERIC_CLOCKEVENTS
select HAVE_CACHE_SPLIT
select HAVE_IPSBAR
help
Motorola ColdFire 5280/5282 processor support.
config M5307
bool "MCF5307"
depends on !MMU
select COLDFIRE
select COLDFIRE_SW_A7
select HAVE_CACHE_CB
select HAVE_MBAR
help
Motorola ColdFire 5307 processor support.
config M532x
bool "MCF532x"
depends on !MMU
select COLDFIRE
select HAVE_CACHE_CB
help
Freescale (Motorola) ColdFire 532x processor support.
config M5407
bool "MCF5407"
depends on !MMU
select COLDFIRE
select COLDFIRE_SW_A7
select HAVE_CACHE_CB
select HAVE_MBAR
help
Motorola ColdFire 5407 processor support.
config M54xx
bool
depends on MMU && !MMU_MOTOROLA
config M547x
bool "MCF547x"
depends on !MMU
select COLDFIRE
select M54xx
select HAVE_CACHE_CB
select HAVE_MBAR
help
Freescale ColdFire 5470/5471/5472/5473/5474/5475 processor support.
config M548x
bool "MCF548x"
depends on !MMU
select COLDFIRE
select M54xx
select HAVE_CACHE_CB
select HAVE_MBAR
help
Freescale ColdFire 5480/5481/5482/5483/5484/5485 processor support.
comment "Processor Specific Options"
config M68KFPU_EMU
bool "Math emulation support (EXPERIMENTAL)"
depends on MMU
depends on EXPERIMENTAL
help
At some point in the future, this will cause floating-point math
......@@ -295,6 +271,7 @@ config M68KFPU_EMU_ONLY
config ADVANCED
bool "Advanced configuration options"
depends on MMU
---help---
This gives you access to some advanced options for the CPU. The
defaults should be fine for most users, but these options may make
......@@ -324,6 +301,7 @@ config RMW_INSNS
config SINGLE_MEMORY_CHUNK
bool "Use one physical chunk of memory only" if ADVANCED && !SUN3
depends on MMU
default y if SUN3
select NEED_MULTIPLE_NODES
help
......@@ -331,6 +309,9 @@ config SINGLE_MEMORY_CHUNK
purposes. This will save a few bytes kernel size and may speed up
some operations. Say N if not sure.
config ARCH_DISCONTIGMEM_ENABLE
def_bool MMU && !SINGLE_MEMORY_CHUNK
config 060_WRITETHROUGH
bool "Use write-through caching for 68060 supervisor accesses"
depends on ADVANCED && M68060
......@@ -346,66 +327,103 @@ config 060_WRITETHROUGH
is hardwired on. The 53c710 SCSI driver is known to suffer from
this problem.
config ARCH_DISCONTIGMEM_ENABLE
def_bool !SINGLE_MEMORY_CHUNK
config M68K_L2_CACHE
bool
depends on MAC
default y
config NODES_SHIFT
int
default "3"
depends on !SINGLE_MEMORY_CHUNK
config ZORRO
bool "Amiga Zorro (AutoConfig) bus support"
depends on AMIGA
help
This enables support for the Zorro bus in the Amiga. If you have
expansion cards in your Amiga that conform to the Amiga
AutoConfig(tm) specification, say Y, otherwise N. Note that even
expansion cards that do not fit in the Zorro slots but fit in e.g.
the CPU slot may fall in this category, so you have to say Y to let
Linux use these.
config FPU
bool
config AMIGA_PCMCIA
bool "Amiga 1200/600 PCMCIA support (EXPERIMENTAL)"
depends on AMIGA && EXPERIMENTAL
help
Include support in the kernel for pcmcia on Amiga 1200 and Amiga
600. If you intend to use pcmcia cards say Y; otherwise say N.
config COLDFIRE_SW_A7
bool
config HEARTBEAT
bool "Use power LED as a heartbeat" if AMIGA || APOLLO || ATARI || MAC ||Q40
default y if !AMIGA && !APOLLO && !ATARI && !MAC && !Q40 && HP300
help
Use the power-on LED on your machine as a load meter. The exact
behavior is platform-dependent, but normally the flash frequency is
a hyperbolic function of the 5-minute load average.
config HAVE_CACHE_SPLIT
bool
# We have a dedicated heartbeat LED. :-)
config PROC_HARDWARE
bool "/proc/hardware support"
help
Say Y here to support the /proc/hardware file, which gives you
access to information about the machine you're running on,
including the model, CPU, MMU, clock speed, BogoMIPS rating,
and memory size.
config HAVE_CACHE_CB
bool
config ISA
config HAVE_MBAR
bool
depends on Q40 || AMIGA_PCMCIA
default y
help
Find out whether you have ISA slots on your motherboard. ISA is the
name of a bus system, i.e. the way the CPU talks to the other stuff
inside your box. Other bus systems are PCI, EISA, MicroChannel
(MCA) or VESA. ISA is an older system, now being displaced by PCI;
newer boards don't support it. If you have ISA, say Y, otherwise N.
config GENERIC_ISA_DMA
config HAVE_IPSBAR
bool
depends on Q40 || AMIGA_PCMCIA
default y
source "drivers/pci/Kconfig"
config CLOCK_SET
bool "Enable setting the CPU clock frequency"
depends on COLDFIRE
default n
help
On some CPU's you do not need to know what the core CPU clock
frequency is. On these you can disable clock setting. On some
traditional 68K parts, and on all ColdFire parts you need to set
the appropriate CPU clock frequency. On these devices many of the
onboard peripherals derive their timing from the master CPU clock
frequency.
config CLOCK_FREQ
int "Set the core clock frequency"
default "66666666"
depends on CLOCK_SET
help
Define the CPU clock frequency in use. This is the core clock
frequency, it may or may not be the same as the external clock
crystal fitted to your board. Some processors have an internal
PLL and can have their frequency programmed at run time, others
use internal dividers. In general the kernel won't setup a PLL
if it is fitted (there are some exceptions). This value will be
specific to the exact CPU that you are using.
config OLDMASK
bool "Old mask 5307 (1H55J) silicon"
depends on M5307
help
Build support for the older revision ColdFire 5307 silicon.
Specifically this is the 1H55J mask revision.
if HAVE_CACHE_SPLIT
choice
prompt "Split Cache Configuration"
default CACHE_I
source "drivers/zorro/Kconfig"
config CACHE_I
bool "Instruction"
help
Use all of the ColdFire CPU cache memory as an instruction cache.
config CACHE_D
bool "Data"
help
Use all of the ColdFire CPU cache memory as a data cache.
config CACHE_BOTH
bool "Both"
help
Split the ColdFire CPU cache, and use half as an instruction cache
and half as a data cache.
endchoice
endif
if HAVE_CACHE_CB
choice
prompt "Data cache mode"
default CACHE_WRITETHRU
config CACHE_WRITETHRU
bool "Write-through"
help
The ColdFire CPU cache is set into Write-through mode.
config CACHE_COPYBACK
bool "Copy-back"
help
The ColdFire CPU cache is set into Copy-back mode.
endchoice
endif
if MMU
config ARCH_MAY_HAVE_PC_FDC
bool
depends on BROKEN && (Q40 || SUN3X)
default y
menu "Platform devices"
config HEARTBEAT
bool "Use power LED as a heartbeat" if AMIGA || APOLLO || ATARI || MAC ||Q40
default y if !AMIGA && !APOLLO && !ATARI && !MAC && !Q40 && HP300
help
Use the power-on LED on your machine as a load meter. The exact
behavior is platform-dependent, but normally the flash frequency is
a hyperbolic function of the 5-minute load average.
# We have a dedicated heartbeat LED. :-)
config PROC_HARDWARE
bool "/proc/hardware support"
help
Say Y here to support the /proc/hardware file, which gives you
access to information about the machine you're running on,
including the model, CPU, MMU, clock speed, BogoMIPS rating,
and memory size.
endmenu
menu "Character devices"
config ATARI_MFPSER
tristate "Atari MFP serial support"
depends on ATARI
---help---
If you like to use the MFP serial ports ("Modem1", "Serial1") under
Linux, say Y. The driver equally supports all kinds of MFP serial
ports and automatically detects whether Serial1 is available.
To compile this driver as a module, choose M here.
Note for Falcon users: You also have an MFP port, it's just not
wired to the outside... But you could use the port under Linux.
config ATARI_MIDI
tristate "Atari MIDI serial support"
depends on ATARI
help
If you want to use your Atari's MIDI port in Linux, say Y.
To compile this driver as a module, choose M here.
config ATARI_DSP56K
tristate "Atari DSP56k support (EXPERIMENTAL)"
depends on ATARI && EXPERIMENTAL
help
If you want to be able to use the DSP56001 in Falcons, say Y. This
driver is still experimental, and if you don't know what it is, or
if you don't have this processor, just say N.
To compile this driver as a module, choose M here.
config AMIGA_BUILTIN_SERIAL
tristate "Amiga builtin serial support"
depends on AMIGA
help
If you want to use your Amiga's built-in serial port in Linux,
answer Y.
To compile this driver as a module, choose M here.
config MULTIFACE_III_TTY
tristate "Multiface Card III serial support"
depends on AMIGA
help
If you want to use a Multiface III card's serial port in Linux,
answer Y.
To compile this driver as a module, choose M here.
config HPDCA
tristate "HP DCA serial support"
depends on DIO && SERIAL_8250
help
If you want to use the internal "DCA" serial ports on an HP300
machine, say Y here.
config HPAPCI
tristate "HP APCI serial support"
depends on HP300 && SERIAL_8250 && EXPERIMENTAL
help
If you want to use the internal "APCI" serial ports on an HP400
machine, say Y here.
config DN_SERIAL
bool "Support for DN serial port (dummy)"
depends on APOLLO
config SERIAL_CONSOLE
bool "Support for serial port console"
depends on (AMIGA || ATARI || SUN3 || SUN3X || VME || APOLLO) && (ATARI_MFPSER=y || ATARI_MIDI=y || AMIGA_BUILTIN_SERIAL=y || MULTIFACE_III_TTY=y || SERIAL=y || SERIAL167 || DN_SERIAL)
---help---
If you say Y here, it will be possible to use a serial port as the
system console (the system console is the device which receives all
kernel messages and warnings and which allows logins in single user
mode). This could be useful if some terminal or printer is connected
to that serial port.
Even if you say Y here, the currently visible virtual console
(/dev/tty0) will still be used as the system console by default, but
you can alter that using a kernel command line option such as
"console=ttyS1". (Try "man bootparam" or see the documentation of
your boot loader (lilo or loadlin) about how to pass options to the
kernel at boot time.)
If you don't have a VGA card installed and you say Y here, the
kernel will automatically use the first serial line, /dev/ttyS0, as
system console.
If unsure, say N.
endmenu
endif
config FPU
bool
default n
config GENERIC_GPIO
bool
default n
config GENERIC_CMOS_UPDATE
bool
default y
config GENERIC_CLOCKEVENTS
bool
default n
config M68000
bool
select CPU_HAS_NO_BITFIELDS
help
The Freescale (was Motorola) 68000 CPU is the first generation of
the well known M68K family of processors. The CPU core as well as
being available as a stand alone CPU was also used in many
System-On-Chip devices (eg 68328, 68302, etc). It does not contain
a paging MMU.
config MCPU32
bool
select CPU_HAS_NO_BITFIELDS
help
The Freescale (was then Motorola) CPU32 is a CPU core that is
based on the 68020 processor. For the most part it is used in
System-On-Chip parts, and does not contain a paging MMU.
config COLDFIRE
bool
select GENERIC_GPIO
select ARCH_REQUIRE_GPIOLIB
select CPU_HAS_NO_BITFIELDS
help
The Freescale ColdFire family of processors is a modern derivitive
of the 68000 processor family. They are mainly targeted at embedded
applications, and are all System-On-Chip (SOC) devices, as opposed
to stand alone CPUs. They implement a subset of the original 68000
processor instruction set.
config COLDFIRE_SW_A7
bool
default n
config HAVE_CACHE_SPLIT
bool
config HAVE_CACHE_CB
bool
config HAVE_MBAR
bool
config HAVE_IPSBAR
bool
choice
prompt "CPU"
default M68EZ328
config M68328
bool "MC68328"
select M68000
help
Motorola 68328 processor support.
config M68EZ328
bool "MC68EZ328"
select M68000
help
Motorola 68EX328 processor support.
config M68VZ328
bool "MC68VZ328"
select M68000
help
Motorola 68VZ328 processor support.
config M68360
bool "MC68360"
select MCPU32
help
Motorola 68360 processor support.
config M5206
bool "MCF5206"
select COLDFIRE
select COLDFIRE_SW_A7
select HAVE_MBAR
help
Motorola ColdFire 5206 processor support.
comment "Machine Types"
config AMIGA
bool "Amiga support"
depends on MMU
select MMU_MOTOROLA if MMU
help
This option enables support for the Amiga series of computers. If
you plan to use this kernel on an Amiga, say Y here and browse the
material available in <file:Documentation/m68k>; otherwise say N.
config ATARI
bool "Atari support"
depends on MMU
select MMU_MOTOROLA if MMU
help
This option enables support for the 68000-based Atari series of
computers (including the TT, Falcon and Medusa). If you plan to use
this kernel on an Atari, say Y here and browse the material
available in <file:Documentation/m68k>; otherwise say N.
config MAC
bool "Macintosh support"
depends on MMU
select MMU_MOTOROLA if MMU
help
This option enables support for the Apple Macintosh series of
computers (yes, there is experimental support now, at least for part
of the series).
Say N unless you're willing to code the remaining necessary support.
;)
config APOLLO
bool "Apollo support"
depends on MMU
select MMU_MOTOROLA if MMU
help
Say Y here if you want to run Linux on an MC680x0-based Apollo
Domain workstation such as the DN3500.
config VME
bool "VME (Motorola and BVM) support"
depends on MMU
select MMU_MOTOROLA if MMU
help
Say Y here if you want to build a kernel for a 680x0 based VME
board. Boards currently supported include Motorola boards MVME147,
MVME162, MVME166, MVME167, MVME172, and MVME177. BVME4000 and
BVME6000 boards from BVM Ltd are also supported.
config MVME147
bool "MVME147 support"
depends on MMU
depends on VME
help
Say Y to include support for early Motorola VME boards. This will
build a kernel which can run on MVME147 single-board computers. If
you select this option you will have to select the appropriate
drivers for SCSI, Ethernet and serial ports later on.
config MVME16x
bool "MVME162, 166 and 167 support"
depends on MMU
depends on VME
help
Say Y to include support for Motorola VME boards. This will build a
kernel which can run on MVME162, MVME166, MVME167, MVME172, and
MVME177 boards. If you select this option you will have to select
the appropriate drivers for SCSI, Ethernet and serial ports later
on.
config BVME6000
bool "BVME4000 and BVME6000 support"
depends on MMU
depends on VME
help
Say Y to include support for VME boards from BVM Ltd. This will
build a kernel which can run on BVME4000 and BVME6000 boards. If
you select this option you will have to select the appropriate
drivers for SCSI, Ethernet and serial ports later on.
config HP300
bool "HP9000/300 and HP9000/400 support"
depends on MMU
select MMU_MOTOROLA if MMU
help
This option enables support for the HP9000/300 and HP9000/400 series
of workstations. Support for these machines is still somewhat
experimental. If you plan to try to use the kernel on such a machine
say Y here.
Everybody else says N.
config SUN3X
bool "Sun3x support"
depends on MMU
select MMU_MOTOROLA if MMU
select M68030
help
This option enables support for the Sun 3x series of workstations.
Be warned that this support is very experimental.
Note that Sun 3x kernels are not compatible with Sun 3 hardware.
General Linux information on the Sun 3x series (now discontinued)
is at <http://www.angelfire.com/ca2/tech68k/sun3.html>.
If you don't want to compile a kernel for a Sun 3x, say N.
config Q40
bool "Q40/Q60 support"
depends on MMU
select MMU_MOTOROLA if MMU
help
The Q40 is a Motorola 68040-based successor to the Sinclair QL
manufactured in Germany. There is an official Q40 home page at
<http://www.q40.de/>. This option enables support for the Q40 and
Q60. Select your CPU below. For 68LC060 don't forget to enable FPU
emulation.
config SUN3
bool "Sun3 support"
depends on MMU
depends on !MMU_MOTOROLA
select MMU_SUN3 if MMU
select M68020
help
This option enables support for the Sun 3 series of workstations
(3/50, 3/60, 3/1xx, 3/2xx systems). Enabling this option requires
that all other hardware types must be disabled, as Sun 3 kernels
are incompatible with all other m68k targets (including Sun 3x!).
If you don't want to compile a kernel exclusively for a Sun 3, say N.
config M5206e
bool "MCF5206e"
select COLDFIRE
select COLDFIRE_SW_A7
select HAVE_MBAR
help
Motorola ColdFire 5206e processor support.
config M520x
bool "MCF520x"
select COLDFIRE
select GENERIC_CLOCKEVENTS
select HAVE_CACHE_SPLIT
help
Freescale Coldfire 5207/5208 processor support.
config M523x
bool "MCF523x"
select COLDFIRE
select GENERIC_CLOCKEVENTS
select HAVE_CACHE_SPLIT
select HAVE_IPSBAR
help
Freescale Coldfire 5230/1/2/4/5 processor support
config M5249
bool "MCF5249"
select COLDFIRE
select COLDFIRE_SW_A7
select HAVE_MBAR
help
Motorola ColdFire 5249 processor support.
config M5271
bool "MCF5271"
select COLDFIRE
select HAVE_CACHE_SPLIT
select HAVE_IPSBAR
help
Freescale (Motorola) ColdFire 5270/5271 processor support.
config M5272
bool "MCF5272"
select COLDFIRE
select COLDFIRE_SW_A7
select HAVE_MBAR
help
Motorola ColdFire 5272 processor support.
config M5275
bool "MCF5275"
select COLDFIRE
select HAVE_CACHE_SPLIT
select HAVE_IPSBAR
help
Freescale (Motorola) ColdFire 5274/5275 processor support.
config M528x
bool "MCF528x"
select COLDFIRE
select GENERIC_CLOCKEVENTS
select HAVE_CACHE_SPLIT
select HAVE_IPSBAR
help
Motorola ColdFire 5280/5282 processor support.
config M5307
bool "MCF5307"
select COLDFIRE
select COLDFIRE_SW_A7
select HAVE_CACHE_CB
select HAVE_MBAR
help
Motorola ColdFire 5307 processor support.
config M532x
bool "MCF532x"
select COLDFIRE
select HAVE_CACHE_CB
help
Freescale (Motorola) ColdFire 532x processor support.
config M5407
bool "MCF5407"
select COLDFIRE
select COLDFIRE_SW_A7
select HAVE_CACHE_CB
select HAVE_MBAR
help
Motorola ColdFire 5407 processor support.
config M547x
bool "MCF547x"
select COLDFIRE
select HAVE_CACHE_CB
select HAVE_MBAR
help
Freescale ColdFire 5470/5471/5472/5473/5474/5475 processor support.
config M548x
bool "MCF548x"
select COLDFIRE
select HAVE_CACHE_CB
select HAVE_MBAR
help
Freescale ColdFire 5480/5481/5482/5483/5484/5485 processor support.
endchoice
config M527x
bool
depends on (M5271 || M5275)
select GENERIC_CLOCKEVENTS
default y
config M54xx
config PILOT
bool
depends on (M548x || M547x)
default y
config CLOCK_SET
bool "Enable setting the CPU clock frequency"
default n
help
On some CPU's you do not need to know what the core CPU clock
frequency is. On these you can disable clock setting. On some
traditional 68K parts, and on all ColdFire parts you need to set
the appropriate CPU clock frequency. On these devices many of the
onboard peripherals derive their timing from the master CPU clock
frequency.
config CLOCK_FREQ
int "Set the core clock frequency"
default "66666666"
depends on CLOCK_SET
help
Define the CPU clock frequency in use. This is the core clock
frequency, it may or may not be the same as the external clock
crystal fitted to your board. Some processors have an internal
PLL and can have their frequency programmed at run time, others
use internal dividers. In general the kernel won't setup a PLL
if it is fitted (there are some exceptions). This value will be
specific to the exact CPU that you are using.
config OLDMASK
bool "Old mask 5307 (1H55J) silicon"
depends on M5307
help
Build support for the older revision ColdFire 5307 silicon.
Specifically this is the 1H55J mask revision.
if HAVE_CACHE_SPLIT
choice
prompt "Split Cache Configuration"
default CACHE_I
config CACHE_I
bool "Instruction"
help
Use all of the ColdFire CPU cache memory as an instruction cache.
config CACHE_D
bool "Data"
help
Use all of the ColdFire CPU cache memory as a data cache.
config CACHE_BOTH
bool "Both"
help
Split the ColdFire CPU cache, and use half as an instruction cache
and half as a data cache.
endchoice
endif
if HAVE_CACHE_CB
choice
prompt "Data cache mode"
default CACHE_WRITETHRU
config CACHE_WRITETHRU
bool "Write-through"
help
The ColdFire CPU cache is set into Write-through mode.
config CACHE_COPYBACK
bool "Copy-back"
help
The ColdFire CPU cache is set into Copy-back mode.
endchoice
endif
comment "Platform"
config PILOT3
bool "Pilot 1000/5000, PalmPilot Personal/Pro, or PalmIII support"
depends on M68328
select PILOT
help
Support for the Palm Pilot 1000/5000, Personal/Pro and PalmIII.
......@@ -302,7 +147,7 @@ config XCOPILOT_BUGS
Support the bugs of Xcopilot.
config UC5272
bool 'Arcturus Networks uC5272 dimm board support'
bool "Arcturus Networks uC5272 dimm board support"
depends on M5272
help
Support for the Arcturus Networks uC5272 dimm board.
......@@ -356,15 +201,23 @@ config UCQUICC
help
Support for the Lineo uCquicc board.
config ARNEWSH
bool
config ARN5206
bool "Arnewsh 5206 board support"
depends on M5206
select ARNEWSH
help
Support for the Arnewsh 5206 board.
config FREESCALE
bool
config M5206eC3
bool "Motorola M5206eC3 board support"
depends on M5206e
select FREESCALE
help
Support for the Motorola M5206eC3 board.
......@@ -377,75 +230,92 @@ config ELITE
config M5208EVB
bool "Freescale M5208EVB board support"
depends on M520x
select FREESCALE
help
Support for the Freescale Coldfire M5208EVB.
config M5235EVB
bool "Freescale M5235EVB support"
depends on M523x
select FREESCALE
help
Support for the Freescale M5235EVB board.
config M5249C3
bool "Motorola M5249C3 board support"
depends on M5249
select FREESCALE
help
Support for the Motorola M5249C3 board.
config M5271EVB
bool "Freescale (Motorola) M5271EVB board support"
depends on M5271
select FREESCALE
help
Support for the Freescale (Motorola) M5271EVB board.
config M5275EVB
bool "Freescale (Motorola) M5275EVB board support"
depends on M5275
select FREESCALE
help
Support for the Freescale (Motorola) M5275EVB board.
config M5272C3
bool "Motorola M5272C3 board support"
depends on M5272
select FREESCALE
help
Support for the Motorola M5272C3 board.
config senTec
bool
config COBRA5272
bool "senTec COBRA5272 board support"
depends on M5272
select senTec
help
Support for the senTec COBRA5272 board.
config AVNET
bool
config AVNET5282
bool "Avnet 5282 board support"
depends on M528x
select AVNET
help
Support for the Avnet 5282 board.
Support for the Avnet 5282 board.
config M5282EVB
bool "Motorola M5282EVB board support"
depends on M528x
select FREESCALE
help
Support for the Motorola M5282EVB board.
config COBRA5282
bool "senTec COBRA5282 board support"
depends on M528x
select senTec
help
Support for the senTec COBRA5282 board.
config SOM5282EM
bool "EMAC.Inc SOM5282EM board support"
depends on M528x
select EMAC_INC
help
Support for the EMAC.Inc SOM5282EM module.
Support for the EMAC.Inc SOM5282EM module.
config WILDFIRE
bool "Intec Automation Inc. WildFire board support"
depends on M528x
help
Support for the Intec Automation Inc. WildFire.
config WILDFIREMOD
bool "Intec Automation Inc. WildFire module support"
depends on M528x
......@@ -455,12 +325,14 @@ config WILDFIREMOD
config ARN5307
bool "Arnewsh 5307 board support"
depends on M5307
select ARNEWSH
help
Support for the Arnewsh 5307 board.
config M5307C3
bool "Motorola M5307C3 board support"
depends on M5307
select FREESCALE
help
Support for the Motorola M5307C3 board.
......@@ -473,6 +345,7 @@ config SECUREEDGEMP3
config M5329EVB
bool "Freescale (Motorola) M5329EVB board support"
depends on M532x
select FREESCALE
help
Support for the Freescale (Motorola) M5329EVB board.
......@@ -485,6 +358,7 @@ config COBRA5329
config M5407C3
bool "Motorola M5407C3 board support"
depends on M5407
select FREESCALE
help
Support for the Motorola M5407C3 board.
......@@ -524,9 +398,13 @@ config SNAPGEAR
help
Special additional support for SnapGear router boards.
config SNEHA
bool
config CPU16B
bool "Sneha Technologies S.L. Sarasvati board support"
depends on M5272
select SNEHA
help
Support for the SNEHA CPU16B board.
......@@ -536,63 +414,20 @@ config MOD5272
help
Support for the Netburner MOD-5272 board.
config SAVANT
bool
config SAVANTrosie1
bool "Savant Rosie1 board support"
depends on M523x
select SAVANT
help
Support for the Savant Rosie1 board.
config ROMFS_FROM_ROM
bool "ROMFS image not RAM resident"
depends on (NETtel || SNAPGEAR)
help
The ROMfs filesystem will stay resident in the FLASH/ROM, not be
moved into RAM.
config PILOT
bool
default y
depends on (PILOT3 || PILOT5)
config ARNEWSH
bool
default y
depends on (ARN5206 || ARN5307)
config FREESCALE
bool
default y
depends on (M5206eC3 || M5208EVB || M5235EVB || M5249C3 || M5271EVB || M5272C3 || M5275EVB || M5282EVB || M5307C3 || M5329EVB || M5407C3)
config HW_FEITH
bool
default y
depends on (CLEOPATRA || CANCam || SCALES)
config senTec
bool
default y
depends on (COBRA5272 || COBRA5282)
config EMAC_INC
bool
default y
depends on (SOM5282EM)
config SNEHA
bool
default y
depends on CPU16B
if !MMU || COLDFIRE
config SAVANT
bool
default y
depends on SAVANTrosie1
config AVNET
bool
default y
depends on (AVNET5282)
comment "Machine Options"
config UBOOT
bool "Support for U-Boot command line parameters"
......@@ -673,33 +508,6 @@ config KERNELBASE
a system with the RAM based at address 0, and leaving enough room
for the theoretical maximum number of 256 vectors.
choice
prompt "RAM bus width"
default RAMAUTOBIT
config RAMAUTOBIT
bool "AUTO"
help
Select the physical RAM data bus size. Not needed on most platforms,
so you can generally choose AUTO.
config RAM8BIT
bool "8bit"
help
Configure RAM bus to be 8 bits wide.
config RAM16BIT
bool "16bit"
help
Configure RAM bus to be 16 bits wide.
config RAM32BIT
bool "32bit"
help
Configure RAM bus to be 32 bits wide.
endchoice
comment "ROM configuration"
config ROM
......@@ -772,16 +580,4 @@ config ROMKERNEL
endchoice
if COLDFIRE
source "kernel/Kconfig.preempt"
endif
source "kernel/time/Kconfig"
config ISA_DMA_API
bool
depends on !M5272
default y
source "drivers/pcmcia/Kconfig"
#
# m68k/Makefile
#
# This file is included by the global makefile so that you can add your own
# architecture-specific flags and dependencies. Remember to do have actions
# for "archclean" and "archdep" for cleaning up and making dependencies for
# this architecture
#
# This file is subject to the terms and conditions of the GNU General Public
# License. See the file "COPYING" in the main directory of this archive
# for more details.
#
# Copyright (C) 1994 by Hamish Macdonald
# Copyright (C) 2002,2011 Greg Ungerer <gerg@snapgear.com>
#
KBUILD_DEFCONFIG := multi_defconfig
#
# Enable processor type. Ordering of these is important - we want to
# use the minimum processor type of the range we support. The logic
# for 680x0 will only allow use of the -m68060 or -m68040 if no other
# 680x0 type is specified - and no option is specified for 68030 or
# 68020. The other m68k/ColdFire types always specify some type of
# compiler cpu type flag.
#
ifndef CONFIG_M68040
cpuflags-$(CONFIG_M68060) := -m68060
endif
ifndef CONFIG_M68060
cpuflags-$(CONFIG_M68040) := -m68040
endif
cpuflags-$(CONFIG_M68030) :=
cpuflags-$(CONFIG_M68020) :=
cpuflags-$(CONFIG_M68360) := -m68332
cpuflags-$(CONFIG_M68000) := -m68000
cpuflags-$(CONFIG_M54xx) := $(call cc-option,-mcpu=5475,-m5200)
cpuflags-$(CONFIG_M5407) := $(call cc-option,-mcpu=5407,-m5200)
cpuflags-$(CONFIG_M532x) := $(call cc-option,-mcpu=532x,-m5307)
cpuflags-$(CONFIG_M5307) := $(call cc-option,-mcpu=5307,-m5200)
cpuflags-$(CONFIG_M528x) := $(call cc-option,-mcpu=528x,-m5307)
cpuflags-$(CONFIG_M5275) := $(call cc-option,-mcpu=5275,-m5307)
cpuflags-$(CONFIG_M5272) := $(call cc-option,-mcpu=5272,-m5307)
cpuflags-$(CONFIG_M5271) := $(call cc-option,-mcpu=5271,-m5307)
cpuflags-$(CONFIG_M523x) := $(call cc-option,-mcpu=523x,-m5307)
cpuflags-$(CONFIG_M5249) := $(call cc-option,-mcpu=5249,-m5200)
cpuflags-$(CONFIG_M520x) := $(call cc-option,-mcpu=5208,-m5200)
cpuflags-$(CONFIG_M5206e) := $(call cc-option,-mcpu=5206e,-m5200)
cpuflags-$(CONFIG_M5206) := $(call cc-option,-mcpu=5206,-m5200)
KBUILD_AFLAGS += $(cpuflags-y)
KBUILD_CFLAGS += $(cpuflags-y) -pipe
ifdef CONFIG_MMU
include $(srctree)/arch/m68k/Makefile_mm
# without -fno-strength-reduce the 53c7xx.c driver fails ;-(
KBUILD_CFLAGS += -fno-strength-reduce -ffixed-a2
else
# we can use a m68k-linux-gcc toolchain with these in place
KBUILD_CFLAGS += -DUTS_SYSNAME=\"uClinux\"
KBUILD_CFLAGS += -D__uClinux__
KBUILD_AFLAGS += -D__uClinux__
endif
LDFLAGS := -m m68kelf
KBUILD_LDFLAGS_MODULE += -T $(srctree)/arch/m68k/kernel/module.lds
ifneq ($(SUBARCH),$(ARCH))
ifeq ($(CROSS_COMPILE),)
CROSS_COMPILE := $(call cc-cross-prefix, \
m68k-linux-gnu- m68k-linux- m68k-unknown-linux-gnu-)
endif
endif
ifdef CONFIG_SUN3
LDFLAGS_vmlinux = -N
endif
CHECKFLAGS += -D__mc68000__
ifdef CONFIG_KGDB
# If configured for kgdb support, include debugging infos and keep the
# frame pointer
KBUILD_CFLAGS := $(subst -fomit-frame-pointer,,$(KBUILD_CFLAGS)) -g
endif
#
# Select the assembler head startup code. Order is important. The default
# head code is first, processor specific selections can override it after.
#
head-y := arch/m68k/kernel/head.o
head-$(CONFIG_SUN3) := arch/m68k/kernel/sun3-head.o
head-$(CONFIG_M68360) := arch/m68k/platform/68360/head.o
head-$(CONFIG_M68000) := arch/m68k/platform/68328/head.o
head-$(CONFIG_COLDFIRE) := arch/m68k/platform/coldfire/head.o
core-y += arch/m68k/kernel/ arch/m68k/mm/
libs-y += arch/m68k/lib/
core-$(CONFIG_Q40) += arch/m68k/q40/
core-$(CONFIG_AMIGA) += arch/m68k/amiga/
core-$(CONFIG_ATARI) += arch/m68k/atari/
core-$(CONFIG_MAC) += arch/m68k/mac/
core-$(CONFIG_HP300) += arch/m68k/hp300/
core-$(CONFIG_APOLLO) += arch/m68k/apollo/
core-$(CONFIG_MVME147) += arch/m68k/mvme147/
core-$(CONFIG_MVME16x) += arch/m68k/mvme16x/
core-$(CONFIG_BVME6000) += arch/m68k/bvme6000/
core-$(CONFIG_SUN3X) += arch/m68k/sun3x/ arch/m68k/sun3/
core-$(CONFIG_SUN3) += arch/m68k/sun3/ arch/m68k/sun3/prom/
core-$(CONFIG_NATFEAT) += arch/m68k/emu/
core-$(CONFIG_M68040) += arch/m68k/fpsp040/
core-$(CONFIG_M68060) += arch/m68k/ifpsp060/
core-$(CONFIG_M68KFPU_EMU) += arch/m68k/math-emu/
core-$(CONFIG_M68360) += arch/m68k/platform/68360/
core-$(CONFIG_M68000) += arch/m68k/platform/68328/
core-$(CONFIG_M68EZ328) += arch/m68k/platform/68EZ328/
core-$(CONFIG_M68VZ328) += arch/m68k/platform/68VZ328/
core-$(CONFIG_COLDFIRE) += arch/m68k/platform/coldfire/
core-$(CONFIG_M5206) += arch/m68k/platform/5206/
core-$(CONFIG_M5206e) += arch/m68k/platform/5206/
core-$(CONFIG_M520x) += arch/m68k/platform/520x/
core-$(CONFIG_M523x) += arch/m68k/platform/523x/
core-$(CONFIG_M5249) += arch/m68k/platform/5249/
core-$(CONFIG_M527x) += arch/m68k/platform/527x/
core-$(CONFIG_M5272) += arch/m68k/platform/5272/
core-$(CONFIG_M528x) += arch/m68k/platform/528x/
core-$(CONFIG_M5307) += arch/m68k/platform/5307/
core-$(CONFIG_M532x) += arch/m68k/platform/532x/
core-$(CONFIG_M5407) += arch/m68k/platform/5407/
core-$(CONFIG_M54xx) += arch/m68k/platform/54xx/
all: zImage
lilo: vmlinux
if [ -f $(INSTALL_PATH)/vmlinux ]; then mv -f $(INSTALL_PATH)/vmlinux $(INSTALL_PATH)/vmlinux.old; fi
if [ -f $(INSTALL_PATH)/System.map ]; then mv -f $(INSTALL_PATH)/System.map $(INSTALL_PATH)/System.old; fi
cat vmlinux > $(INSTALL_PATH)/vmlinux
cp System.map $(INSTALL_PATH)/System.map
if [ -x /sbin/lilo ]; then /sbin/lilo; else /etc/lilo/install; fi
zImage compressed: vmlinux.gz
vmlinux.gz: vmlinux
ifndef CONFIG_KGDB
cp vmlinux vmlinux.tmp
$(STRIP) vmlinux.tmp
gzip -9c vmlinux.tmp >vmlinux.gz
rm vmlinux.tmp
else
include $(srctree)/arch/m68k/Makefile_no
gzip -9c vmlinux >vmlinux.gz
endif
bzImage: vmlinux.bz2
vmlinux.bz2: vmlinux
ifndef CONFIG_KGDB
cp vmlinux vmlinux.tmp
$(STRIP) vmlinux.tmp
bzip2 -1c vmlinux.tmp >vmlinux.bz2
rm vmlinux.tmp
else
bzip2 -1c vmlinux >vmlinux.bz2
endif
archclean:
rm -f vmlinux.gz vmlinux.bz2
install:
sh $(srctree)/arch/m68k/install.sh $(KERNELRELEASE) vmlinux.gz System.map "$(INSTALL_PATH)"
#
# m68k/Makefile
#
# This file is included by the global makefile so that you can add your own
# architecture-specific flags and dependencies. Remember to do have actions
# for "archclean" and "archdep" for cleaning up and making dependencies for
# this architecture
#
# This file is subject to the terms and conditions of the GNU General Public
# License. See the file "COPYING" in the main directory of this archive
# for more details.
#
# Copyright (C) 1994 by Hamish Macdonald
#
# override top level makefile
AS += -m68020
LDFLAGS := -m m68kelf
KBUILD_LDFLAGS_MODULE += -T $(srctree)/arch/m68k/kernel/module.lds
ifneq ($(SUBARCH),$(ARCH))
ifeq ($(CROSS_COMPILE),)
CROSS_COMPILE := $(call cc-cross-prefix, \
m68k-linux-gnu- m68k-linux- m68k-unknown-linux-gnu-)
endif
endif
ifdef CONFIG_SUN3
LDFLAGS_vmlinux = -N
endif
CHECKFLAGS += -D__mc68000__
# without -fno-strength-reduce the 53c7xx.c driver fails ;-(
KBUILD_CFLAGS += -pipe -fno-strength-reduce -ffixed-a2
# enable processor switch if compiled only for a single cpu
ifndef CONFIG_M68020
ifndef CONFIG_M68030
ifndef CONFIG_M68060
KBUILD_CFLAGS += -m68040
endif
ifndef CONFIG_M68040
KBUILD_CFLAGS += -m68060
endif
endif
endif
ifdef CONFIG_KGDB
# If configured for kgdb support, include debugging infos and keep the
# frame pointer
KBUILD_CFLAGS := $(subst -fomit-frame-pointer,,$(KBUILD_CFLAGS)) -g
endif
ifndef CONFIG_SUN3
head-y := arch/m68k/kernel/head.o
else
head-y := arch/m68k/kernel/sun3-head.o
endif
core-y += arch/m68k/kernel/ arch/m68k/mm/
libs-y += arch/m68k/lib/
core-$(CONFIG_Q40) += arch/m68k/q40/
core-$(CONFIG_AMIGA) += arch/m68k/amiga/
core-$(CONFIG_ATARI) += arch/m68k/atari/
core-$(CONFIG_MAC) += arch/m68k/mac/
core-$(CONFIG_HP300) += arch/m68k/hp300/
core-$(CONFIG_APOLLO) += arch/m68k/apollo/
core-$(CONFIG_MVME147) += arch/m68k/mvme147/
core-$(CONFIG_MVME16x) += arch/m68k/mvme16x/
core-$(CONFIG_BVME6000) += arch/m68k/bvme6000/
core-$(CONFIG_SUN3X) += arch/m68k/sun3x/ arch/m68k/sun3/
core-$(CONFIG_SUN3) += arch/m68k/sun3/ arch/m68k/sun3/prom/
core-$(CONFIG_NATFEAT) += arch/m68k/emu/
core-$(CONFIG_M68040) += arch/m68k/fpsp040/
core-$(CONFIG_M68060) += arch/m68k/ifpsp060/
core-$(CONFIG_M68KFPU_EMU) += arch/m68k/math-emu/
all: zImage
lilo: vmlinux
if [ -f $(INSTALL_PATH)/vmlinux ]; then mv -f $(INSTALL_PATH)/vmlinux $(INSTALL_PATH)/vmlinux.old; fi
if [ -f $(INSTALL_PATH)/System.map ]; then mv -f $(INSTALL_PATH)/System.map $(INSTALL_PATH)/System.old; fi
cat vmlinux > $(INSTALL_PATH)/vmlinux
cp System.map $(INSTALL_PATH)/System.map
if [ -x /sbin/lilo ]; then /sbin/lilo; else /etc/lilo/install; fi
zImage compressed: vmlinux.gz
vmlinux.gz: vmlinux
ifndef CONFIG_KGDB
cp vmlinux vmlinux.tmp
$(STRIP) vmlinux.tmp
gzip -9c vmlinux.tmp >vmlinux.gz
rm vmlinux.tmp
else
gzip -9c vmlinux >vmlinux.gz
endif
bzImage: vmlinux.bz2
vmlinux.bz2: vmlinux
ifndef CONFIG_KGDB
cp vmlinux vmlinux.tmp
$(STRIP) vmlinux.tmp
bzip2 -1c vmlinux.tmp >vmlinux.bz2
rm vmlinux.tmp
else
bzip2 -1c vmlinux >vmlinux.bz2
endif
archclean:
rm -f vmlinux.gz vmlinux.bz2
install:
sh $(srctree)/arch/m68k/install.sh $(KERNELRELEASE) vmlinux.gz System.map "$(INSTALL_PATH)"
#
# arch/m68k/Makefile
#
# This file is subject to the terms and conditions of the GNU General Public
# License. See the file "COPYING" in the main directory of this archive
# for more details.
#
# (C) Copyright 2002, Greg Ungerer <gerg@snapgear.com>
#
platform-$(CONFIG_M68328) := 68328
platform-$(CONFIG_M68EZ328) := 68EZ328
platform-$(CONFIG_M68VZ328) := 68VZ328
platform-$(CONFIG_M68360) := 68360
platform-$(CONFIG_M5206) := 5206
platform-$(CONFIG_M5206e) := 5206
platform-$(CONFIG_M520x) := 520x
platform-$(CONFIG_M523x) := 523x
platform-$(CONFIG_M5249) := 5249
platform-$(CONFIG_M527x) := 527x
platform-$(CONFIG_M5272) := 5272
platform-$(CONFIG_M528x) := 528x
platform-$(CONFIG_M5307) := 5307
platform-$(CONFIG_M532x) := 532x
platform-$(CONFIG_M5407) := 5407
platform-$(CONFIG_M54xx) := 54xx
PLATFORM := $(platform-y)
board-$(CONFIG_PILOT) := pilot
board-$(CONFIG_UC5272) := UC5272
board-$(CONFIG_UC5282) := UC5282
board-$(CONFIG_UCSIMM) := ucsimm
board-$(CONFIG_UCDIMM) := ucdimm
board-$(CONFIG_UCQUICC) := uCquicc
board-$(CONFIG_DRAGEN2) := de2
board-$(CONFIG_ARNEWSH) := ARNEWSH
board-$(CONFIG_FREESCALE) := FREESCALE
board-$(CONFIG_M5235EVB) := M5235EVB
board-$(CONFIG_M5271EVB) := M5271EVB
board-$(CONFIG_M5275EVB) := M5275EVB
board-$(CONFIG_M5282EVB) := M5282EVB
board-$(CONFIG_ELITE) := eLITE
board-$(CONFIG_NETtel) := NETtel
board-$(CONFIG_SECUREEDGEMP3) := MP3
board-$(CONFIG_CLEOPATRA) := CLEOPATRA
board-$(CONFIG_senTec) := senTec
board-$(CONFIG_SNEHA) := SNEHA
board-$(CONFIG_M5208EVB) := M5208EVB
board-$(CONFIG_MOD5272) := MOD5272
board-$(CONFIG_AVNET) := AVNET
board-$(CONFIG_SAVANT) := SAVANT
BOARD := $(board-y)
model-$(CONFIG_RAMKERNEL) := ram
model-$(CONFIG_ROMKERNEL) := rom
MODEL := $(model-y)
#
# Some code support is grouped together for a common cpu-subclass (for
# example all ColdFire cpu's are very similar). Determine the sub-class
# for the selected cpu. ONLY need to define this for the non-base member
# of the family.
#
cpuclass-$(CONFIG_M5206) := coldfire
cpuclass-$(CONFIG_M5206e) := coldfire
cpuclass-$(CONFIG_M520x) := coldfire
cpuclass-$(CONFIG_M523x) := coldfire
cpuclass-$(CONFIG_M5249) := coldfire
cpuclass-$(CONFIG_M527x) := coldfire
cpuclass-$(CONFIG_M5272) := coldfire
cpuclass-$(CONFIG_M528x) := coldfire
cpuclass-$(CONFIG_M5307) := coldfire
cpuclass-$(CONFIG_M532x) := coldfire
cpuclass-$(CONFIG_M5407) := coldfire
cpuclass-$(CONFIG_M54xx) := coldfire
cpuclass-$(CONFIG_M68328) := 68328
cpuclass-$(CONFIG_M68EZ328) := 68328
cpuclass-$(CONFIG_M68VZ328) := 68328
cpuclass-$(CONFIG_M68360) := 68360
CPUCLASS := $(cpuclass-y)
ifneq ($(CPUCLASS),$(PLATFORM))
CLASSDIR := arch/m68k/platform/$(cpuclass-y)/
endif
export PLATFORM BOARD MODEL CPUCLASS
#
# Some CFLAG additions based on specific CPU type.
#
cflags-$(CONFIG_M5206) := $(call cc-option,-mcpu=5206,-m5200)
cflags-$(CONFIG_M5206e) := $(call cc-option,-mcpu=5206e,-m5200)
cflags-$(CONFIG_M520x) := $(call cc-option,-mcpu=5208,-m5200)
cflags-$(CONFIG_M523x) := $(call cc-option,-mcpu=523x,-m5307)
cflags-$(CONFIG_M5249) := $(call cc-option,-mcpu=5249,-m5200)
cflags-$(CONFIG_M5271) := $(call cc-option,-mcpu=5271,-m5307)
cflags-$(CONFIG_M5272) := $(call cc-option,-mcpu=5272,-m5307)
cflags-$(CONFIG_M5275) := $(call cc-option,-mcpu=5275,-m5307)
cflags-$(CONFIG_M528x) := $(call cc-option,-mcpu=528x,-m5307)
cflags-$(CONFIG_M5307) := $(call cc-option,-mcpu=5307,-m5200)
cflags-$(CONFIG_M532x) := $(call cc-option,-mcpu=532x,-m5307)
cflags-$(CONFIG_M5407) := $(call cc-option,-mcpu=5407,-m5200)
cflags-$(CONFIG_M54xx) := $(call cc-option,-mcpu=5475,-m5200)
cflags-$(CONFIG_M68328) := -m68000
cflags-$(CONFIG_M68EZ328) := -m68000
cflags-$(CONFIG_M68VZ328) := -m68000
cflags-$(CONFIG_M68360) := -m68332
KBUILD_AFLAGS += $(cflags-y)
KBUILD_CFLAGS += $(cflags-y)
KBUILD_CFLAGS += -D__linux__
KBUILD_CFLAGS += -DUTS_SYSNAME=\"uClinux\"
head-y := arch/m68k/platform/$(cpuclass-y)/head.o
core-y += arch/m68k/kernel/ \
arch/m68k/mm/ \
$(CLASSDIR) \
arch/m68k/platform/$(PLATFORM)/
libs-y += arch/m68k/lib/
archclean:
#ifdef __uClinux__
#include "entry_no.h"
#ifndef __M68K_ENTRY_H
#define __M68K_ENTRY_H
#include <asm/setup.h>
#include <asm/page.h>
#ifdef __ASSEMBLY__
#include <asm/thread_info.h>
#endif
/*
* Stack layout in 'ret_from_exception':
*
* This allows access to the syscall arguments in registers d1-d5
*
* 0(sp) - d1
* 4(sp) - d2
* 8(sp) - d3
* C(sp) - d4
* 10(sp) - d5
* 14(sp) - a0
* 18(sp) - a1
* 1C(sp) - a2
* 20(sp) - d0
* 24(sp) - orig_d0
* 28(sp) - stack adjustment
* 2C(sp) - [ sr ] [ format & vector ]
* 2E(sp) - [ pc-hiword ] [ sr ]
* 30(sp) - [ pc-loword ] [ pc-hiword ]
* 32(sp) - [ format & vector ] [ pc-loword ]
* ^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^
* M68K COLDFIRE
*/
/* the following macro is used when enabling interrupts */
#if defined(MACH_ATARI_ONLY)
/* block out HSYNC on the atari */
#define ALLOWINT (~0x400)
#define MAX_NOINT_IPL 3
#else
#include "entry_mm.h"
/* portable version */
#define ALLOWINT (~0x700)
#define MAX_NOINT_IPL 0
#endif /* machine compilation types */
#ifdef __ASSEMBLY__
/*
* This defines the normal kernel pt-regs layout.
*
* regs a3-a6 and d6-d7 are preserved by C code
* the kernel doesn't mess with usp unless it needs to
*/
#define SWITCH_STACK_SIZE (6*4+4) /* includes return address */
#ifdef CONFIG_COLDFIRE
#ifdef CONFIG_COLDFIRE_SW_A7
/*
* This is made a little more tricky on older ColdFires. There is no
* separate supervisor and user stack pointers. Need to artificially
* construct a usp in software... When doing this we need to disable
* interrupts, otherwise bad things will happen.
*/
.globl sw_usp
.globl sw_ksp
.macro SAVE_ALL_SYS
move #0x2700,%sr /* disable intrs */
btst #5,%sp@(2) /* from user? */
bnes 6f /* no, skip */
movel %sp,sw_usp /* save user sp */
addql #8,sw_usp /* remove exception */
movel sw_ksp,%sp /* kernel sp */
subql #8,%sp /* room for exception */
clrl %sp@- /* stkadj */
movel %d0,%sp@- /* orig d0 */
movel %d0,%sp@- /* d0 */
lea %sp@(-32),%sp /* space for 8 regs */
moveml %d1-%d5/%a0-%a2,%sp@
movel sw_usp,%a0 /* get usp */
movel %a0@-,%sp@(PT_OFF_PC) /* copy exception program counter */
movel %a0@-,%sp@(PT_OFF_FORMATVEC)/*copy exception format/vector/sr */
bra 7f
6:
clrl %sp@- /* stkadj */
movel %d0,%sp@- /* orig d0 */
movel %d0,%sp@- /* d0 */
lea %sp@(-32),%sp /* space for 8 regs */
moveml %d1-%d5/%a0-%a2,%sp@
7:
.endm
.macro SAVE_ALL_INT
SAVE_ALL_SYS
moveq #-1,%d0 /* not system call entry */
movel %d0,%sp@(PT_OFF_ORIG_D0)
.endm
.macro RESTORE_USER
move #0x2700,%sr /* disable intrs */
movel sw_usp,%a0 /* get usp */
movel %sp@(PT_OFF_PC),%a0@- /* copy exception program counter */
movel %sp@(PT_OFF_FORMATVEC),%a0@-/*copy exception format/vector/sr */
moveml %sp@,%d1-%d5/%a0-%a2
lea %sp@(32),%sp /* space for 8 regs */
movel %sp@+,%d0
addql #4,%sp /* orig d0 */
addl %sp@+,%sp /* stkadj */
addql #8,%sp /* remove exception */
movel %sp,sw_ksp /* save ksp */
subql #8,sw_usp /* set exception */
movel sw_usp,%sp /* restore usp */
rte
.endm
.macro RDUSP
movel sw_usp,%a3
.endm
.macro WRUSP
movel %a3,sw_usp
.endm
#else /* !CONFIG_COLDFIRE_SW_A7 */
/*
* Modern ColdFire parts have separate supervisor and user stack
* pointers. Simple load and restore macros for this case.
*/
.macro SAVE_ALL_SYS
move #0x2700,%sr /* disable intrs */
clrl %sp@- /* stkadj */
movel %d0,%sp@- /* orig d0 */
movel %d0,%sp@- /* d0 */
lea %sp@(-32),%sp /* space for 8 regs */
moveml %d1-%d5/%a0-%a2,%sp@
.endm
.macro SAVE_ALL_INT
move #0x2700,%sr /* disable intrs */
clrl %sp@- /* stkadj */
pea -1:w /* orig d0 */
movel %d0,%sp@- /* d0 */
lea %sp@(-32),%sp /* space for 8 regs */
moveml %d1-%d5/%a0-%a2,%sp@
.endm
.macro RESTORE_USER
moveml %sp@,%d1-%d5/%a0-%a2
lea %sp@(32),%sp /* space for 8 regs */
movel %sp@+,%d0
addql #4,%sp /* orig d0 */
addl %sp@+,%sp /* stkadj */
rte
.endm
.macro RDUSP
/*move %usp,%a3*/
.word 0x4e6b
.endm
.macro WRUSP
/*move %a3,%usp*/
.word 0x4e63
.endm
#endif /* !CONFIG_COLDFIRE_SW_A7 */
.macro SAVE_SWITCH_STACK
lea %sp@(-24),%sp /* 6 regs */
moveml %a3-%a6/%d6-%d7,%sp@
.endm
.macro RESTORE_SWITCH_STACK
moveml %sp@,%a3-%a6/%d6-%d7
lea %sp@(24),%sp /* 6 regs */
.endm
#else /* !CONFIG_COLDFIRE */
/*
* All other types of m68k parts (68000, 680x0, CPU32) have the same
* entry and exit code.
*/
/*
* a -1 in the orig_d0 field signifies
* that the stack frame is NOT for syscall
*/
.macro SAVE_ALL_INT
clrl %sp@- /* stk_adj */
pea -1:w /* orig d0 */
movel %d0,%sp@- /* d0 */
moveml %d1-%d5/%a0-%a2,%sp@-
.endm
.macro SAVE_ALL_SYS
clrl %sp@- /* stk_adj */
movel %d0,%sp@- /* orig d0 */
movel %d0,%sp@- /* d0 */
moveml %d1-%d5/%a0-%a2,%sp@-
.endm
.macro RESTORE_ALL
moveml %sp@+,%a0-%a2/%d1-%d5
movel %sp@+,%d0
addql #4,%sp /* orig d0 */
addl %sp@+,%sp /* stk adj */
rte
.endm
.macro SAVE_SWITCH_STACK
moveml %a3-%a6/%d6-%d7,%sp@-
.endm
.macro RESTORE_SWITCH_STACK
moveml %sp@+,%a3-%a6/%d6-%d7
.endm
#endif /* !CONFIG_COLDFIRE */
/*
* Register %a2 is reserved and set to current task on MMU enabled systems.
* Non-MMU systems do not reserve %a2 in this way, and this definition is
* not used for them.
*/
#define curptr a2
#define GET_CURRENT(tmp) get_current tmp
.macro get_current reg=%d0
movel %sp,\reg
andw #-THREAD_SIZE,\reg
movel \reg,%curptr
movel %curptr@,%curptr
.endm
#else /* C source */
#define STR(X) STR1(X)
#define STR1(X) #X
#define SAVE_ALL_INT \
"clrl %%sp@-;" /* stk_adj */ \
"pea -1:w;" /* orig d0 = -1 */ \
"movel %%d0,%%sp@-;" /* d0 */ \
"moveml %%d1-%%d5/%%a0-%%a2,%%sp@-"
#define GET_CURRENT(tmp) \
"movel %%sp,"#tmp"\n\t" \
"andw #-"STR(THREAD_SIZE)","#tmp"\n\t" \
"movel "#tmp",%%a2\n\t" \
"movel %%a2@,%%a2"
#endif
#endif /* __M68K_ENTRY_H */
#ifndef __M68K_ENTRY_H
#define __M68K_ENTRY_H
#include <asm/setup.h>
#include <asm/page.h>
#ifdef __ASSEMBLY__
#include <asm/thread_info.h>
#endif
/*
* Stack layout in 'ret_from_exception':
*
* This allows access to the syscall arguments in registers d1-d5
*
* 0(sp) - d1
* 4(sp) - d2
* 8(sp) - d3
* C(sp) - d4
* 10(sp) - d5
* 14(sp) - a0
* 18(sp) - a1
* 1C(sp) - a2
* 20(sp) - d0
* 24(sp) - orig_d0
* 28(sp) - stack adjustment
* 2C(sp) - sr
* 2E(sp) - pc
* 32(sp) - format & vector
*/
/*
* 97/05/14 Andreas: Register %a2 is now set to the current task throughout
* the whole kernel.
*/
/* the following macro is used when enabling interrupts */
#if defined(MACH_ATARI_ONLY)
/* block out HSYNC on the atari */
#define ALLOWINT (~0x400)
#define MAX_NOINT_IPL 3
#else
/* portable version */
#define ALLOWINT (~0x700)
#define MAX_NOINT_IPL 0
#endif /* machine compilation types */
#ifdef __ASSEMBLY__
#define curptr a2
LFLUSH_I_AND_D = 0x00000808
#define SAVE_ALL_INT save_all_int
#define SAVE_ALL_SYS save_all_sys
#define RESTORE_ALL restore_all
/*
* This defines the normal kernel pt-regs layout.
*
* regs a3-a6 and d6-d7 are preserved by C code
* the kernel doesn't mess with usp unless it needs to
*/
/*
* a -1 in the orig_d0 field signifies
* that the stack frame is NOT for syscall
*/
.macro save_all_int
clrl %sp@- | stk_adj
pea -1:w | orig d0
movel %d0,%sp@- | d0
moveml %d1-%d5/%a0-%a1/%curptr,%sp@-
.endm
.macro save_all_sys
clrl %sp@- | stk_adj
movel %d0,%sp@- | orig d0
movel %d0,%sp@- | d0
moveml %d1-%d5/%a0-%a1/%curptr,%sp@-
.endm
.macro restore_all
moveml %sp@+,%a0-%a1/%curptr/%d1-%d5
movel %sp@+,%d0
addql #4,%sp | orig d0
addl %sp@+,%sp | stk adj
rte
.endm
#define SWITCH_STACK_SIZE (6*4+4) /* includes return address */
#define SAVE_SWITCH_STACK save_switch_stack
#define RESTORE_SWITCH_STACK restore_switch_stack
#define GET_CURRENT(tmp) get_current tmp
.macro save_switch_stack
moveml %a3-%a6/%d6-%d7,%sp@-
.endm
.macro restore_switch_stack
moveml %sp@+,%a3-%a6/%d6-%d7
.endm
.macro get_current reg=%d0
movel %sp,\reg
andw #-THREAD_SIZE,\reg
movel \reg,%curptr
movel %curptr@,%curptr
.endm
#else /* C source */
#define STR(X) STR1(X)
#define STR1(X) #X
#define SAVE_ALL_INT \
"clrl %%sp@-;" /* stk_adj */ \
"pea -1:w;" /* orig d0 = -1 */ \
"movel %%d0,%%sp@-;" /* d0 */ \
"moveml %%d1-%%d5/%%a0-%%a2,%%sp@-"
#define GET_CURRENT(tmp) \
"movel %%sp,"#tmp"\n\t" \
"andw #-"STR(THREAD_SIZE)","#tmp"\n\t" \
"movel "#tmp",%%a2\n\t" \
"movel %%a2@,%%a2"
#endif
#endif /* __M68K_ENTRY_H */
#ifndef __M68KNOMMU_ENTRY_H
#define __M68KNOMMU_ENTRY_H
#include <asm/setup.h>
#include <asm/page.h>
/*
* Stack layout in 'ret_from_exception':
*
* This allows access to the syscall arguments in registers d1-d5
*
* 0(sp) - d1
* 4(sp) - d2
* 8(sp) - d3
* C(sp) - d4
* 10(sp) - d5
* 14(sp) - a0
* 18(sp) - a1
* 1C(sp) - a2
* 20(sp) - d0
* 24(sp) - orig_d0
* 28(sp) - stack adjustment
* 2C(sp) - [ sr ] [ format & vector ]
* 2E(sp) - [ pc-hiword ] [ sr ]
* 30(sp) - [ pc-loword ] [ pc-hiword ]
* 32(sp) - [ format & vector ] [ pc-loword ]
* ^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^
* M68K COLDFIRE
*/
#define ALLOWINT (~0x700)
#ifdef __ASSEMBLY__
#define SWITCH_STACK_SIZE (6*4+4) /* Includes return address */
/*
* This defines the normal kernel pt-regs layout.
*
* regs are a2-a6 and d6-d7 preserved by C code
* the kernel doesn't mess with usp unless it needs to
*/
#ifdef CONFIG_COLDFIRE
#ifdef CONFIG_COLDFIRE_SW_A7
/*
* This is made a little more tricky on older ColdFires. There is no
* separate supervisor and user stack pointers. Need to artificially
* construct a usp in software... When doing this we need to disable
* interrupts, otherwise bad things will happen.
*/
.globl sw_usp
.globl sw_ksp
.macro SAVE_ALL
move #0x2700,%sr /* disable intrs */
btst #5,%sp@(2) /* from user? */
bnes 6f /* no, skip */
movel %sp,sw_usp /* save user sp */
addql #8,sw_usp /* remove exception */
movel sw_ksp,%sp /* kernel sp */
subql #8,%sp /* room for exception */
clrl %sp@- /* stkadj */
movel %d0,%sp@- /* orig d0 */
movel %d0,%sp@- /* d0 */
lea %sp@(-32),%sp /* space for 8 regs */
moveml %d1-%d5/%a0-%a2,%sp@
movel sw_usp,%a0 /* get usp */
movel %a0@-,%sp@(PT_OFF_PC) /* copy exception program counter */
movel %a0@-,%sp@(PT_OFF_FORMATVEC)/*copy exception format/vector/sr */
bra 7f
6:
clrl %sp@- /* stkadj */
movel %d0,%sp@- /* orig d0 */
movel %d0,%sp@- /* d0 */
lea %sp@(-32),%sp /* space for 8 regs */
moveml %d1-%d5/%a0-%a2,%sp@
7:
.endm
.macro RESTORE_USER
move #0x2700,%sr /* disable intrs */
movel sw_usp,%a0 /* get usp */
movel %sp@(PT_OFF_PC),%a0@- /* copy exception program counter */
movel %sp@(PT_OFF_FORMATVEC),%a0@-/*copy exception format/vector/sr */
moveml %sp@,%d1-%d5/%a0-%a2
lea %sp@(32),%sp /* space for 8 regs */
movel %sp@+,%d0
addql #4,%sp /* orig d0 */
addl %sp@+,%sp /* stkadj */
addql #8,%sp /* remove exception */
movel %sp,sw_ksp /* save ksp */
subql #8,sw_usp /* set exception */
movel sw_usp,%sp /* restore usp */
rte
.endm
.macro RDUSP
movel sw_usp,%a3
.endm
.macro WRUSP
movel %a3,sw_usp
.endm
#else /* !CONFIG_COLDFIRE_SW_A7 */
/*
* Modern ColdFire parts have separate supervisor and user stack
* pointers. Simple load and restore macros for this case.
*/
.macro SAVE_ALL
move #0x2700,%sr /* disable intrs */
clrl %sp@- /* stkadj */
movel %d0,%sp@- /* orig d0 */
movel %d0,%sp@- /* d0 */
lea %sp@(-32),%sp /* space for 8 regs */
moveml %d1-%d5/%a0-%a2,%sp@
.endm
.macro RESTORE_USER
moveml %sp@,%d1-%d5/%a0-%a2
lea %sp@(32),%sp /* space for 8 regs */
movel %sp@+,%d0
addql #4,%sp /* orig d0 */
addl %sp@+,%sp /* stkadj */
rte
.endm
.macro RDUSP
/*move %usp,%a3*/
.word 0x4e6b
.endm
.macro WRUSP
/*move %a3,%usp*/
.word 0x4e63
.endm
#endif /* !CONFIG_COLDFIRE_SW_A7 */
.macro SAVE_SWITCH_STACK
lea %sp@(-24),%sp /* 6 regs */
moveml %a3-%a6/%d6-%d7,%sp@
.endm
.macro RESTORE_SWITCH_STACK
moveml %sp@,%a3-%a6/%d6-%d7
lea %sp@(24),%sp /* 6 regs */
.endm
#else /* !CONFIG_COLDFIRE */
/*
* Standard 68k interrupt entry and exit macros.
*/
.macro SAVE_ALL
clrl %sp@- /* stkadj */
movel %d0,%sp@- /* orig d0 */
movel %d0,%sp@- /* d0 */
moveml %d1-%d5/%a0-%a2,%sp@-
.endm
.macro RESTORE_ALL
moveml %sp@+,%a0-%a2/%d1-%d5
movel %sp@+,%d0
addql #4,%sp /* orig d0 */
addl %sp@+,%sp /* stkadj */
rte
.endm
.macro SAVE_SWITCH_STACK
moveml %a3-%a6/%d6-%d7,%sp@-
.endm
.macro RESTORE_SWITCH_STACK
moveml %sp@+,%a3-%a6/%d6-%d7
.endm
#endif /* !COLDFIRE_SW_A7 */
#endif /* __ASSEMBLY__ */
#endif /* __M68KNOMMU_ENTRY_H */
......@@ -90,15 +90,13 @@
#define MCFGPIO_PDDR_FECH 0xFC0A4013
#define MCFGPIO_PDDR_FECL 0xFC0A4014
#define MCFGPIO_PPDSDR_BUSCTL 0xFC0A401A
#define MCFGPIO_PPDSDR_BE 0xFC0A401B
#define MCFGPIO_PPDSDR_CS 0xFC0A401C
#define MCFGPIO_PPDSDR_FECI2C 0xFC0A401D
#define MCFGPIO_PPDSDR_QSPI 0xFC0A401E
#define MCFGPIO_PPDSDR_TIMER 0xFC0A401F
#define MCFGPIO_PPDSDR_UART 0xFC0A4021
#define MCFGPIO_PPDSDR_FECH 0xFC0A4021
#define MCFGPIO_PPDSDR_FECL 0xFC0A4022
#define MCFGPIO_PPDSDR_CS 0xFC0A401A
#define MCFGPIO_PPDSDR_FECI2C 0xFC0A401B
#define MCFGPIO_PPDSDR_QSPI 0xFC0A401C
#define MCFGPIO_PPDSDR_TIMER 0xFC0A401D
#define MCFGPIO_PPDSDR_UART 0xFC0A401E
#define MCFGPIO_PPDSDR_FECH 0xFC0A401F
#define MCFGPIO_PPDSDR_FECL 0xFC0A4020
#define MCFGPIO_PCLRR_BUSCTL 0xFC0A4024
#define MCFGPIO_PCLRR_BE 0xFC0A4025
......@@ -113,11 +111,11 @@
/*
* Generic GPIO support
*/
#define MCFGPIO_PODR MCFGPIO_PODR_BUSCTL
#define MCFGPIO_PDDR MCFGPIO_PDDR_BUSCTL
#define MCFGPIO_PPDR MCFGPIO_PPDSDR_BUSCTL
#define MCFGPIO_SETR MCFGPIO_PPDSDR_BUSCTL
#define MCFGPIO_CLRR MCFGPIO_PCLRR_BUSCTL
#define MCFGPIO_PODR MCFGPIO_PODR_CS
#define MCFGPIO_PDDR MCFGPIO_PDDR_CS
#define MCFGPIO_PPDR MCFGPIO_PPDSDR_CS
#define MCFGPIO_SETR MCFGPIO_PPDSDR_CS
#define MCFGPIO_CLRR MCFGPIO_PCLRR_CS
#define MCFGPIO_PIN_MAX 80
#define MCFGPIO_IRQ_MAX 8
......
......@@ -24,9 +24,11 @@
#if defined(CONFIG_M523x) || defined(CONFIG_M527x) || defined(CONFIG_M528x)
#define MCFQSPI_IOBASE (MCF_IPSBAR + 0x340)
#elif defined(CONFIG_M5249)
#define MCFQSPI_IOBASE (MCF_MBAR + 0x300)
#elif defined(CONFIG_M520x) || defined(CONFIG_M532x)
#define MCFQSPI_IOBASE 0xFC058000
#define MCFQSPI_IOBASE (MCF_MBAR + 0x300)
#elif defined(CONFIG_M520x)
#define MCFQSPI_IOBASE 0xFC05C000
#elif defined(CONFIG_M532x)
#define MCFQSPI_IOBASE 0xFC058000
#endif
#define MCFQSPI_IOSIZE 0x40
......
......@@ -5,6 +5,9 @@
extern unsigned long memory_start;
extern unsigned long memory_end;
extern unsigned long _rambase;
extern unsigned long _ramstart;
extern unsigned long _ramend;
#define get_user_page(vaddr) __get_free_page(GFP_KERNEL)
#define free_user_page(page, addr) free_page(addr)
......
......@@ -135,6 +135,12 @@ do { \
wrusp(_usp); \
} while(0)
static inline int handle_kernel_fault(struct pt_regs *regs)
{
/* Any fault in kernel is fatal on non-mmu */
return 0;
}
#endif
/* Forward declaration, a strange C thing */
......
......@@ -3,4 +3,6 @@
#include <asm-generic/sections.h>
extern char _sbss[], _ebss[];
#endif /* _ASM_M68K_SECTIONS_H */
ifdef CONFIG_MMU
include arch/m68k/kernel/Makefile_mm
else
include arch/m68k/kernel/Makefile_no
#
# Makefile for the linux kernel.
#
extra-$(CONFIG_MMU) := head.o
extra-$(CONFIG_SUN3) := sun3-head.o
extra-y += vmlinux.lds
obj-y := entry.o m68k_ksyms.o module.o process.o ptrace.o setup.o signal.o \
sys_m68k.o syscalltable.o time.o traps.o
obj-$(CONFIG_MMU) += ints.o devres.o vectors.o
devres-$(CONFIG_MMU) = ../../../kernel/irq/devres.o
ifndef CONFIG_MMU_SUN3
obj-y += dma.o
endif
ifndef CONFIG_MMU
obj-y += init_task.o irq.o
endif
#
# Makefile for the linux kernel.
#
ifndef CONFIG_SUN3
extra-y := head.o
else
extra-y := sun3-head.o
endif
extra-y += vmlinux.lds
obj-y := entry.o process.o traps.o ints.o signal.o ptrace.o module.o \
sys_m68k.o time.o setup.o m68k_ksyms.o devres.o syscalltable.o
devres-y = ../../../kernel/irq/devres.o
obj-y$(CONFIG_MMU_SUN3) += dma.o # no, it's not a typo
#
# Makefile for arch/m68knommu/kernel.
#
extra-y := vmlinux.lds
obj-y += dma.o entry.o init_task.o irq.o m68k_ksyms.o process.o ptrace.o \
setup.o signal.o syscalltable.o sys_m68k.o time.o traps.o
obj-$(CONFIG_MODULES) += module.o
......@@ -43,7 +43,7 @@
.globl sys_vfork
ENTRY(buserr)
SAVE_ALL
SAVE_ALL_INT
moveq #-1,%d0
movel %d0,%sp@(PT_OFF_ORIG_D0)
movel %sp,%sp@- /* stack frame pointer argument */
......@@ -52,7 +52,7 @@ ENTRY(buserr)
jra ret_from_exception
ENTRY(trap)
SAVE_ALL
SAVE_ALL_INT
moveq #-1,%d0
movel %d0,%sp@(PT_OFF_ORIG_D0)
movel %sp,%sp@- /* stack frame pointer argument */
......@@ -64,7 +64,7 @@ ENTRY(trap)
.globl dbginterrupt
ENTRY(dbginterrupt)
SAVE_ALL
SAVE_ALL_INT
moveq #-1,%d0
movel %d0,%sp@(PT_OFF_ORIG_D0)
movel %sp,%sp@- /* stack frame pointer argument */
......
......@@ -36,6 +36,7 @@
#include <asm/irq.h>
#include <asm/machdep.h>
#include <asm/pgtable.h>
#include <asm/sections.h>
unsigned long memory_start;
unsigned long memory_end;
......@@ -80,9 +81,6 @@ void (*mach_power_off)(void);
#define CPU_INSTR_PER_JIFFY 16
#endif
extern int _stext, _etext, _sdata, _edata, _sbss, _ebss, _end;
extern int _ramstart, _ramend;
#if defined(CONFIG_UBOOT)
/*
* parse_uboot_commandline
......
#ifdef CONFIG_MMU
#include "traps_mm.c"
/*
* linux/arch/m68k/kernel/traps.c
*
* Copyright (C) 1993, 1994 by Hamish Macdonald
*
* 68040 fixes by Michael Rausch
* 68040 fixes by Martin Apel
* 68040 fixes and writeback by Richard Zidlicky
* 68060 fixes by Roman Hodek
* 68060 fixes by Jesper Skov
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file COPYING in the main directory of this archive
* for more details.
*/
/*
* Sets up all exception vectors
*/
#include <linux/sched.h>
#include <linux/signal.h>
#include <linux/kernel.h>
#include <linux/mm.h>
#include <linux/module.h>
#include <linux/user.h>
#include <linux/string.h>
#include <linux/linkage.h>
#include <linux/init.h>
#include <linux/ptrace.h>
#include <linux/kallsyms.h>
#include <asm/setup.h>
#include <asm/fpu.h>
#include <asm/system.h>
#include <asm/uaccess.h>
#include <asm/traps.h>
#include <asm/pgalloc.h>
#include <asm/machdep.h>
#include <asm/siginfo.h>
static const char *vec_names[] = {
[VEC_RESETSP] = "RESET SP",
[VEC_RESETPC] = "RESET PC",
[VEC_BUSERR] = "BUS ERROR",
[VEC_ADDRERR] = "ADDRESS ERROR",
[VEC_ILLEGAL] = "ILLEGAL INSTRUCTION",
[VEC_ZERODIV] = "ZERO DIVIDE",
[VEC_CHK] = "CHK",
[VEC_TRAP] = "TRAPcc",
[VEC_PRIV] = "PRIVILEGE VIOLATION",
[VEC_TRACE] = "TRACE",
[VEC_LINE10] = "LINE 1010",
[VEC_LINE11] = "LINE 1111",
[VEC_RESV12] = "UNASSIGNED RESERVED 12",
[VEC_COPROC] = "COPROCESSOR PROTOCOL VIOLATION",
[VEC_FORMAT] = "FORMAT ERROR",
[VEC_UNINT] = "UNINITIALIZED INTERRUPT",
[VEC_RESV16] = "UNASSIGNED RESERVED 16",
[VEC_RESV17] = "UNASSIGNED RESERVED 17",
[VEC_RESV18] = "UNASSIGNED RESERVED 18",
[VEC_RESV19] = "UNASSIGNED RESERVED 19",
[VEC_RESV20] = "UNASSIGNED RESERVED 20",
[VEC_RESV21] = "UNASSIGNED RESERVED 21",
[VEC_RESV22] = "UNASSIGNED RESERVED 22",
[VEC_RESV23] = "UNASSIGNED RESERVED 23",
[VEC_SPUR] = "SPURIOUS INTERRUPT",
[VEC_INT1] = "LEVEL 1 INT",
[VEC_INT2] = "LEVEL 2 INT",
[VEC_INT3] = "LEVEL 3 INT",
[VEC_INT4] = "LEVEL 4 INT",
[VEC_INT5] = "LEVEL 5 INT",
[VEC_INT6] = "LEVEL 6 INT",
[VEC_INT7] = "LEVEL 7 INT",
[VEC_SYS] = "SYSCALL",
[VEC_TRAP1] = "TRAP #1",
[VEC_TRAP2] = "TRAP #2",
[VEC_TRAP3] = "TRAP #3",
[VEC_TRAP4] = "TRAP #4",
[VEC_TRAP5] = "TRAP #5",
[VEC_TRAP6] = "TRAP #6",
[VEC_TRAP7] = "TRAP #7",
[VEC_TRAP8] = "TRAP #8",
[VEC_TRAP9] = "TRAP #9",
[VEC_TRAP10] = "TRAP #10",
[VEC_TRAP11] = "TRAP #11",
[VEC_TRAP12] = "TRAP #12",
[VEC_TRAP13] = "TRAP #13",
[VEC_TRAP14] = "TRAP #14",
[VEC_TRAP15] = "TRAP #15",
[VEC_FPBRUC] = "FPCP BSUN",
[VEC_FPIR] = "FPCP INEXACT",
[VEC_FPDIVZ] = "FPCP DIV BY 0",
[VEC_FPUNDER] = "FPCP UNDERFLOW",
[VEC_FPOE] = "FPCP OPERAND ERROR",
[VEC_FPOVER] = "FPCP OVERFLOW",
[VEC_FPNAN] = "FPCP SNAN",
[VEC_FPUNSUP] = "FPCP UNSUPPORTED OPERATION",
[VEC_MMUCFG] = "MMU CONFIGURATION ERROR",
[VEC_MMUILL] = "MMU ILLEGAL OPERATION ERROR",
[VEC_MMUACC] = "MMU ACCESS LEVEL VIOLATION ERROR",
[VEC_RESV59] = "UNASSIGNED RESERVED 59",
[VEC_UNIMPEA] = "UNASSIGNED RESERVED 60",
[VEC_UNIMPII] = "UNASSIGNED RESERVED 61",
[VEC_RESV62] = "UNASSIGNED RESERVED 62",
[VEC_RESV63] = "UNASSIGNED RESERVED 63",
};
static const char *space_names[] = {
[0] = "Space 0",
[USER_DATA] = "User Data",
[USER_PROGRAM] = "User Program",
#ifndef CONFIG_SUN3
[3] = "Space 3",
#else
#include "traps_no.c"
[FC_CONTROL] = "Control",
#endif
[4] = "Space 4",
[SUPER_DATA] = "Super Data",
[SUPER_PROGRAM] = "Super Program",
[CPU_SPACE] = "CPU"
};
void die_if_kernel(char *,struct pt_regs *,int);
asmlinkage int do_page_fault(struct pt_regs *regs, unsigned long address,
unsigned long error_code);
int send_fault_sig(struct pt_regs *regs);
asmlinkage void trap_c(struct frame *fp);
#if defined (CONFIG_M68060)
static inline void access_error060 (struct frame *fp)
{
unsigned long fslw = fp->un.fmt4.pc; /* is really FSLW for access error */
#ifdef DEBUG
printk("fslw=%#lx, fa=%#lx\n", fslw, fp->un.fmt4.effaddr);
#endif
if (fslw & MMU060_BPE) {
/* branch prediction error -> clear branch cache */
__asm__ __volatile__ ("movec %/cacr,%/d0\n\t"
"orl #0x00400000,%/d0\n\t"
"movec %/d0,%/cacr"
: : : "d0" );
/* return if there's no other error */
if (!(fslw & MMU060_ERR_BITS) && !(fslw & MMU060_SEE))
return;
}
if (fslw & (MMU060_DESC_ERR | MMU060_WP | MMU060_SP)) {
unsigned long errorcode;
unsigned long addr = fp->un.fmt4.effaddr;
if (fslw & MMU060_MA)
addr = (addr + PAGE_SIZE - 1) & PAGE_MASK;
errorcode = 1;
if (fslw & MMU060_DESC_ERR) {
__flush_tlb040_one(addr);
errorcode = 0;
}
if (fslw & MMU060_W)
errorcode |= 2;
#ifdef DEBUG
printk("errorcode = %d\n", errorcode );
#endif
do_page_fault(&fp->ptregs, addr, errorcode);
} else if (fslw & (MMU060_SEE)){
/* Software Emulation Error.
* fault during mem_read/mem_write in ifpsp060/os.S
*/
send_fault_sig(&fp->ptregs);
} else if (!(fslw & (MMU060_RE|MMU060_WE)) ||
send_fault_sig(&fp->ptregs) > 0) {
printk("pc=%#lx, fa=%#lx\n", fp->ptregs.pc, fp->un.fmt4.effaddr);
printk( "68060 access error, fslw=%lx\n", fslw );
trap_c( fp );
}
}
#endif /* CONFIG_M68060 */
#if defined (CONFIG_M68040)
static inline unsigned long probe040(int iswrite, unsigned long addr, int wbs)
{
unsigned long mmusr;
mm_segment_t old_fs = get_fs();
set_fs(MAKE_MM_SEG(wbs));
if (iswrite)
asm volatile (".chip 68040; ptestw (%0); .chip 68k" : : "a" (addr));
else
asm volatile (".chip 68040; ptestr (%0); .chip 68k" : : "a" (addr));
asm volatile (".chip 68040; movec %%mmusr,%0; .chip 68k" : "=r" (mmusr));
set_fs(old_fs);
return mmusr;
}
static inline int do_040writeback1(unsigned short wbs, unsigned long wba,
unsigned long wbd)
{
int res = 0;
mm_segment_t old_fs = get_fs();
/* set_fs can not be moved, otherwise put_user() may oops */
set_fs(MAKE_MM_SEG(wbs));
switch (wbs & WBSIZ_040) {
case BA_SIZE_BYTE:
res = put_user(wbd & 0xff, (char __user *)wba);
break;
case BA_SIZE_WORD:
res = put_user(wbd & 0xffff, (short __user *)wba);
break;
case BA_SIZE_LONG:
res = put_user(wbd, (int __user *)wba);
break;
}
/* set_fs can not be moved, otherwise put_user() may oops */
set_fs(old_fs);
#ifdef DEBUG
printk("do_040writeback1, res=%d\n",res);
#endif
return res;
}
/* after an exception in a writeback the stack frame corresponding
* to that exception is discarded, set a few bits in the old frame
* to simulate what it should look like
*/
static inline void fix_xframe040(struct frame *fp, unsigned long wba, unsigned short wbs)
{
fp->un.fmt7.faddr = wba;
fp->un.fmt7.ssw = wbs & 0xff;
if (wba != current->thread.faddr)
fp->un.fmt7.ssw |= MA_040;
}
static inline void do_040writebacks(struct frame *fp)
{
int res = 0;
#if 0
if (fp->un.fmt7.wb1s & WBV_040)
printk("access_error040: cannot handle 1st writeback. oops.\n");
#endif
if ((fp->un.fmt7.wb2s & WBV_040) &&
!(fp->un.fmt7.wb2s & WBTT_040)) {
res = do_040writeback1(fp->un.fmt7.wb2s, fp->un.fmt7.wb2a,
fp->un.fmt7.wb2d);
if (res)
fix_xframe040(fp, fp->un.fmt7.wb2a, fp->un.fmt7.wb2s);
else
fp->un.fmt7.wb2s = 0;
}
/* do the 2nd wb only if the first one was successful (except for a kernel wb) */
if (fp->un.fmt7.wb3s & WBV_040 && (!res || fp->un.fmt7.wb3s & 4)) {
res = do_040writeback1(fp->un.fmt7.wb3s, fp->un.fmt7.wb3a,
fp->un.fmt7.wb3d);
if (res)
{
fix_xframe040(fp, fp->un.fmt7.wb3a, fp->un.fmt7.wb3s);
fp->un.fmt7.wb2s = fp->un.fmt7.wb3s;
fp->un.fmt7.wb3s &= (~WBV_040);
fp->un.fmt7.wb2a = fp->un.fmt7.wb3a;
fp->un.fmt7.wb2d = fp->un.fmt7.wb3d;
}
else
fp->un.fmt7.wb3s = 0;
}
if (res)
send_fault_sig(&fp->ptregs);
}
/*
* called from sigreturn(), must ensure userspace code didn't
* manipulate exception frame to circumvent protection, then complete
* pending writebacks
* we just clear TM2 to turn it into a userspace access
*/
asmlinkage void berr_040cleanup(struct frame *fp)
{
fp->un.fmt7.wb2s &= ~4;
fp->un.fmt7.wb3s &= ~4;
do_040writebacks(fp);
}
static inline void access_error040(struct frame *fp)
{
unsigned short ssw = fp->un.fmt7.ssw;
unsigned long mmusr;
#ifdef DEBUG
printk("ssw=%#x, fa=%#lx\n", ssw, fp->un.fmt7.faddr);
printk("wb1s=%#x, wb2s=%#x, wb3s=%#x\n", fp->un.fmt7.wb1s,
fp->un.fmt7.wb2s, fp->un.fmt7.wb3s);
printk ("wb2a=%lx, wb3a=%lx, wb2d=%lx, wb3d=%lx\n",
fp->un.fmt7.wb2a, fp->un.fmt7.wb3a,
fp->un.fmt7.wb2d, fp->un.fmt7.wb3d);
#endif
if (ssw & ATC_040) {
unsigned long addr = fp->un.fmt7.faddr;
unsigned long errorcode;
/*
* The MMU status has to be determined AFTER the address
* has been corrected if there was a misaligned access (MA).
*/
if (ssw & MA_040)
addr = (addr + 7) & -8;
/* MMU error, get the MMUSR info for this access */
mmusr = probe040(!(ssw & RW_040), addr, ssw);
#ifdef DEBUG
printk("mmusr = %lx\n", mmusr);
#endif
errorcode = 1;
if (!(mmusr & MMU_R_040)) {
/* clear the invalid atc entry */
__flush_tlb040_one(addr);
errorcode = 0;
}
/* despite what documentation seems to say, RMW
* accesses have always both the LK and RW bits set */
if (!(ssw & RW_040) || (ssw & LK_040))
errorcode |= 2;
if (do_page_fault(&fp->ptregs, addr, errorcode)) {
#ifdef DEBUG
printk("do_page_fault() !=0\n");
#endif
if (user_mode(&fp->ptregs)){
/* delay writebacks after signal delivery */
#ifdef DEBUG
printk(".. was usermode - return\n");
#endif
return;
}
/* disable writeback into user space from kernel
* (if do_page_fault didn't fix the mapping,
* the writeback won't do good)
*/
disable_wb:
#ifdef DEBUG
printk(".. disabling wb2\n");
#endif
if (fp->un.fmt7.wb2a == fp->un.fmt7.faddr)
fp->un.fmt7.wb2s &= ~WBV_040;
if (fp->un.fmt7.wb3a == fp->un.fmt7.faddr)
fp->un.fmt7.wb3s &= ~WBV_040;
}
} else {
/* In case of a bus error we either kill the process or expect
* the kernel to catch the fault, which then is also responsible
* for cleaning up the mess.
*/
current->thread.signo = SIGBUS;
current->thread.faddr = fp->un.fmt7.faddr;
if (send_fault_sig(&fp->ptregs) >= 0)
printk("68040 bus error (ssw=%x, faddr=%lx)\n", ssw,
fp->un.fmt7.faddr);
goto disable_wb;
}
do_040writebacks(fp);
}
#endif /* CONFIG_M68040 */
#if defined(CONFIG_SUN3)
#include <asm/sun3mmu.h>
extern int mmu_emu_handle_fault (unsigned long, int, int);
/* sun3 version of bus_error030 */
static inline void bus_error030 (struct frame *fp)
{
unsigned char buserr_type = sun3_get_buserr ();
unsigned long addr, errorcode;
unsigned short ssw = fp->un.fmtb.ssw;
extern unsigned long _sun3_map_test_start, _sun3_map_test_end;
#ifdef DEBUG
if (ssw & (FC | FB))
printk ("Instruction fault at %#010lx\n",
ssw & FC ?
fp->ptregs.format == 0xa ? fp->ptregs.pc + 2 : fp->un.fmtb.baddr - 2
:
fp->ptregs.format == 0xa ? fp->ptregs.pc + 4 : fp->un.fmtb.baddr);
if (ssw & DF)
printk ("Data %s fault at %#010lx in %s (pc=%#lx)\n",
ssw & RW ? "read" : "write",
fp->un.fmtb.daddr,
space_names[ssw & DFC], fp->ptregs.pc);
#endif
/*
* Check if this page should be demand-mapped. This needs to go before
* the testing for a bad kernel-space access (demand-mapping applies
* to kernel accesses too).
*/
if ((ssw & DF)
&& (buserr_type & (SUN3_BUSERR_PROTERR | SUN3_BUSERR_INVALID))) {
if (mmu_emu_handle_fault (fp->un.fmtb.daddr, ssw & RW, 0))
return;
}
/* Check for kernel-space pagefault (BAD). */
if (fp->ptregs.sr & PS_S) {
/* kernel fault must be a data fault to user space */
if (! ((ssw & DF) && ((ssw & DFC) == USER_DATA))) {
// try checking the kernel mappings before surrender
if (mmu_emu_handle_fault (fp->un.fmtb.daddr, ssw & RW, 1))
return;
/* instruction fault or kernel data fault! */
if (ssw & (FC | FB))
printk ("Instruction fault at %#010lx\n",
fp->ptregs.pc);
if (ssw & DF) {
/* was this fault incurred testing bus mappings? */
if((fp->ptregs.pc >= (unsigned long)&_sun3_map_test_start) &&
(fp->ptregs.pc <= (unsigned long)&_sun3_map_test_end)) {
send_fault_sig(&fp->ptregs);
return;
}
printk ("Data %s fault at %#010lx in %s (pc=%#lx)\n",
ssw & RW ? "read" : "write",
fp->un.fmtb.daddr,
space_names[ssw & DFC], fp->ptregs.pc);
}
printk ("BAD KERNEL BUSERR\n");
die_if_kernel("Oops", &fp->ptregs,0);
force_sig(SIGKILL, current);
return;
}
} else {
/* user fault */
if (!(ssw & (FC | FB)) && !(ssw & DF))
/* not an instruction fault or data fault! BAD */
panic ("USER BUSERR w/o instruction or data fault");
}
/* First handle the data fault, if any. */
if (ssw & DF) {
addr = fp->un.fmtb.daddr;
// errorcode bit 0: 0 -> no page 1 -> protection fault
// errorcode bit 1: 0 -> read fault 1 -> write fault
// (buserr_type & SUN3_BUSERR_PROTERR) -> protection fault
// (buserr_type & SUN3_BUSERR_INVALID) -> invalid page fault
if (buserr_type & SUN3_BUSERR_PROTERR)
errorcode = 0x01;
else if (buserr_type & SUN3_BUSERR_INVALID)
errorcode = 0x00;
else {
#ifdef DEBUG
printk ("*** unexpected busfault type=%#04x\n", buserr_type);
printk ("invalid %s access at %#lx from pc %#lx\n",
!(ssw & RW) ? "write" : "read", addr,
fp->ptregs.pc);
#endif
die_if_kernel ("Oops", &fp->ptregs, buserr_type);
force_sig (SIGBUS, current);
return;
}
//todo: wtf is RM bit? --m
if (!(ssw & RW) || ssw & RM)
errorcode |= 0x02;
/* Handle page fault. */
do_page_fault (&fp->ptregs, addr, errorcode);
/* Retry the data fault now. */
return;
}
/* Now handle the instruction fault. */
/* Get the fault address. */
if (fp->ptregs.format == 0xA)
addr = fp->ptregs.pc + 4;
else
addr = fp->un.fmtb.baddr;
if (ssw & FC)
addr -= 2;
if (buserr_type & SUN3_BUSERR_INVALID) {
if (!mmu_emu_handle_fault (fp->un.fmtb.daddr, 1, 0))
do_page_fault (&fp->ptregs, addr, 0);
} else {
#ifdef DEBUG
printk ("protection fault on insn access (segv).\n");
#endif
force_sig (SIGSEGV, current);
}
}
#else
#if defined(CPU_M68020_OR_M68030)
static inline void bus_error030 (struct frame *fp)
{
volatile unsigned short temp;
unsigned short mmusr;
unsigned long addr, errorcode;
unsigned short ssw = fp->un.fmtb.ssw;
#ifdef DEBUG
unsigned long desc;
printk ("pid = %x ", current->pid);
printk ("SSW=%#06x ", ssw);
if (ssw & (FC | FB))
printk ("Instruction fault at %#010lx\n",
ssw & FC ?
fp->ptregs.format == 0xa ? fp->ptregs.pc + 2 : fp->un.fmtb.baddr - 2
:
fp->ptregs.format == 0xa ? fp->ptregs.pc + 4 : fp->un.fmtb.baddr);
if (ssw & DF)
printk ("Data %s fault at %#010lx in %s (pc=%#lx)\n",
ssw & RW ? "read" : "write",
fp->un.fmtb.daddr,
space_names[ssw & DFC], fp->ptregs.pc);
#endif
/* ++andreas: If a data fault and an instruction fault happen
at the same time map in both pages. */
/* First handle the data fault, if any. */
if (ssw & DF) {
addr = fp->un.fmtb.daddr;
#ifdef DEBUG
asm volatile ("ptestr %3,%2@,#7,%0\n\t"
"pmove %%psr,%1@"
: "=a&" (desc)
: "a" (&temp), "a" (addr), "d" (ssw));
#else
asm volatile ("ptestr %2,%1@,#7\n\t"
"pmove %%psr,%0@"
: : "a" (&temp), "a" (addr), "d" (ssw));
#endif
mmusr = temp;
#ifdef DEBUG
printk("mmusr is %#x for addr %#lx in task %p\n",
mmusr, addr, current);
printk("descriptor address is %#lx, contents %#lx\n",
__va(desc), *(unsigned long *)__va(desc));
#endif
errorcode = (mmusr & MMU_I) ? 0 : 1;
if (!(ssw & RW) || (ssw & RM))
errorcode |= 2;
if (mmusr & (MMU_I | MMU_WP)) {
if (ssw & 4) {
printk("Data %s fault at %#010lx in %s (pc=%#lx)\n",
ssw & RW ? "read" : "write",
fp->un.fmtb.daddr,
space_names[ssw & DFC], fp->ptregs.pc);
goto buserr;
}
/* Don't try to do anything further if an exception was
handled. */
if (do_page_fault (&fp->ptregs, addr, errorcode) < 0)
return;
} else if (!(mmusr & MMU_I)) {
/* probably a 020 cas fault */
if (!(ssw & RM) && send_fault_sig(&fp->ptregs) > 0)
printk("unexpected bus error (%#x,%#x)\n", ssw, mmusr);
} else if (mmusr & (MMU_B|MMU_L|MMU_S)) {
printk("invalid %s access at %#lx from pc %#lx\n",
!(ssw & RW) ? "write" : "read", addr,
fp->ptregs.pc);
die_if_kernel("Oops",&fp->ptregs,mmusr);
force_sig(SIGSEGV, current);
return;
} else {
#if 0
static volatile long tlong;
#endif
printk("weird %s access at %#lx from pc %#lx (ssw is %#x)\n",
!(ssw & RW) ? "write" : "read", addr,
fp->ptregs.pc, ssw);
asm volatile ("ptestr #1,%1@,#0\n\t"
"pmove %%psr,%0@"
: /* no outputs */
: "a" (&temp), "a" (addr));
mmusr = temp;
printk ("level 0 mmusr is %#x\n", mmusr);
#if 0
asm volatile ("pmove %%tt0,%0@"
: /* no outputs */
: "a" (&tlong));
printk("tt0 is %#lx, ", tlong);
asm volatile ("pmove %%tt1,%0@"
: /* no outputs */
: "a" (&tlong));
printk("tt1 is %#lx\n", tlong);
#endif
#ifdef DEBUG
printk("Unknown SIGSEGV - 1\n");
#endif
die_if_kernel("Oops",&fp->ptregs,mmusr);
force_sig(SIGSEGV, current);
return;
}
/* setup an ATC entry for the access about to be retried */
if (!(ssw & RW) || (ssw & RM))
asm volatile ("ploadw %1,%0@" : /* no outputs */
: "a" (addr), "d" (ssw));
else
asm volatile ("ploadr %1,%0@" : /* no outputs */
: "a" (addr), "d" (ssw));
}
/* Now handle the instruction fault. */
if (!(ssw & (FC|FB)))
return;
if (fp->ptregs.sr & PS_S) {
printk("Instruction fault at %#010lx\n",
fp->ptregs.pc);
buserr:
printk ("BAD KERNEL BUSERR\n");
die_if_kernel("Oops",&fp->ptregs,0);
force_sig(SIGKILL, current);
return;
}
/* get the fault address */
if (fp->ptregs.format == 10)
addr = fp->ptregs.pc + 4;
else
addr = fp->un.fmtb.baddr;
if (ssw & FC)
addr -= 2;
if ((ssw & DF) && ((addr ^ fp->un.fmtb.daddr) & PAGE_MASK) == 0)
/* Insn fault on same page as data fault. But we
should still create the ATC entry. */
goto create_atc_entry;
#ifdef DEBUG
asm volatile ("ptestr #1,%2@,#7,%0\n\t"
"pmove %%psr,%1@"
: "=a&" (desc)
: "a" (&temp), "a" (addr));
#else
asm volatile ("ptestr #1,%1@,#7\n\t"
"pmove %%psr,%0@"
: : "a" (&temp), "a" (addr));
#endif
mmusr = temp;
#ifdef DEBUG
printk ("mmusr is %#x for addr %#lx in task %p\n",
mmusr, addr, current);
printk ("descriptor address is %#lx, contents %#lx\n",
__va(desc), *(unsigned long *)__va(desc));
#endif
if (mmusr & MMU_I)
do_page_fault (&fp->ptregs, addr, 0);
else if (mmusr & (MMU_B|MMU_L|MMU_S)) {
printk ("invalid insn access at %#lx from pc %#lx\n",
addr, fp->ptregs.pc);
#ifdef DEBUG
printk("Unknown SIGSEGV - 2\n");
#endif
die_if_kernel("Oops",&fp->ptregs,mmusr);
force_sig(SIGSEGV, current);
return;
}
create_atc_entry:
/* setup an ATC entry for the access about to be retried */
asm volatile ("ploadr #2,%0@" : /* no outputs */
: "a" (addr));
}
#endif /* CPU_M68020_OR_M68030 */
#endif /* !CONFIG_SUN3 */
asmlinkage void buserr_c(struct frame *fp)
{
/* Only set esp0 if coming from user mode */
if (user_mode(&fp->ptregs))
current->thread.esp0 = (unsigned long) fp;
#ifdef DEBUG
printk ("*** Bus Error *** Format is %x\n", fp->ptregs.format);
#endif
switch (fp->ptregs.format) {
#if defined (CONFIG_M68060)
case 4: /* 68060 access error */
access_error060 (fp);
break;
#endif
#if defined (CONFIG_M68040)
case 0x7: /* 68040 access error */
access_error040 (fp);
break;
#endif
#if defined (CPU_M68020_OR_M68030)
case 0xa:
case 0xb:
bus_error030 (fp);
break;
#endif
default:
die_if_kernel("bad frame format",&fp->ptregs,0);
#ifdef DEBUG
printk("Unknown SIGSEGV - 4\n");
#endif
force_sig(SIGSEGV, current);
}
}
static int kstack_depth_to_print = 48;
void show_trace(unsigned long *stack)
{
unsigned long *endstack;
unsigned long addr;
int i;
printk("Call Trace:");
addr = (unsigned long)stack + THREAD_SIZE - 1;
endstack = (unsigned long *)(addr & -THREAD_SIZE);
i = 0;
while (stack + 1 <= endstack) {
addr = *stack++;
/*
* If the address is either in the text segment of the
* kernel, or in the region which contains vmalloc'ed
* memory, it *may* be the address of a calling
* routine; if so, print it so that someone tracing
* down the cause of the crash will be able to figure
* out the call path that was taken.
*/
if (__kernel_text_address(addr)) {
#ifndef CONFIG_KALLSYMS
if (i % 5 == 0)
printk("\n ");
#endif
printk(" [<%08lx>] %pS\n", addr, (void *)addr);
i++;
}
}
printk("\n");
}
void show_registers(struct pt_regs *regs)
{
struct frame *fp = (struct frame *)regs;
mm_segment_t old_fs = get_fs();
u16 c, *cp;
unsigned long addr;
int i;
print_modules();
printk("PC: [<%08lx>] %pS\n", regs->pc, (void *)regs->pc);
printk("SR: %04x SP: %p a2: %08lx\n", regs->sr, regs, regs->a2);
printk("d0: %08lx d1: %08lx d2: %08lx d3: %08lx\n",
regs->d0, regs->d1, regs->d2, regs->d3);
printk("d4: %08lx d5: %08lx a0: %08lx a1: %08lx\n",
regs->d4, regs->d5, regs->a0, regs->a1);
printk("Process %s (pid: %d, task=%p)\n",
current->comm, task_pid_nr(current), current);
addr = (unsigned long)&fp->un;
printk("Frame format=%X ", regs->format);
switch (regs->format) {
case 0x2:
printk("instr addr=%08lx\n", fp->un.fmt2.iaddr);
addr += sizeof(fp->un.fmt2);
break;
case 0x3:
printk("eff addr=%08lx\n", fp->un.fmt3.effaddr);
addr += sizeof(fp->un.fmt3);
break;
case 0x4:
printk((CPU_IS_060 ? "fault addr=%08lx fslw=%08lx\n"
: "eff addr=%08lx pc=%08lx\n"),
fp->un.fmt4.effaddr, fp->un.fmt4.pc);
addr += sizeof(fp->un.fmt4);
break;
case 0x7:
printk("eff addr=%08lx ssw=%04x faddr=%08lx\n",
fp->un.fmt7.effaddr, fp->un.fmt7.ssw, fp->un.fmt7.faddr);
printk("wb 1 stat/addr/data: %04x %08lx %08lx\n",
fp->un.fmt7.wb1s, fp->un.fmt7.wb1a, fp->un.fmt7.wb1dpd0);
printk("wb 2 stat/addr/data: %04x %08lx %08lx\n",
fp->un.fmt7.wb2s, fp->un.fmt7.wb2a, fp->un.fmt7.wb2d);
printk("wb 3 stat/addr/data: %04x %08lx %08lx\n",
fp->un.fmt7.wb3s, fp->un.fmt7.wb3a, fp->un.fmt7.wb3d);
printk("push data: %08lx %08lx %08lx %08lx\n",
fp->un.fmt7.wb1dpd0, fp->un.fmt7.pd1, fp->un.fmt7.pd2,
fp->un.fmt7.pd3);
addr += sizeof(fp->un.fmt7);
break;
case 0x9:
printk("instr addr=%08lx\n", fp->un.fmt9.iaddr);
addr += sizeof(fp->un.fmt9);
break;
case 0xa:
printk("ssw=%04x isc=%04x isb=%04x daddr=%08lx dobuf=%08lx\n",
fp->un.fmta.ssw, fp->un.fmta.isc, fp->un.fmta.isb,
fp->un.fmta.daddr, fp->un.fmta.dobuf);
addr += sizeof(fp->un.fmta);
break;
case 0xb:
printk("ssw=%04x isc=%04x isb=%04x daddr=%08lx dobuf=%08lx\n",
fp->un.fmtb.ssw, fp->un.fmtb.isc, fp->un.fmtb.isb,
fp->un.fmtb.daddr, fp->un.fmtb.dobuf);
printk("baddr=%08lx dibuf=%08lx ver=%x\n",
fp->un.fmtb.baddr, fp->un.fmtb.dibuf, fp->un.fmtb.ver);
addr += sizeof(fp->un.fmtb);
break;
default:
printk("\n");
}
show_stack(NULL, (unsigned long *)addr);
printk("Code:");
set_fs(KERNEL_DS);
cp = (u16 *)regs->pc;
for (i = -8; i < 16; i++) {
if (get_user(c, cp + i) && i >= 0) {
printk(" Bad PC value.");
break;
}
printk(i ? " %04x" : " <%04x>", c);
}
set_fs(old_fs);
printk ("\n");
}
void show_stack(struct task_struct *task, unsigned long *stack)
{
unsigned long *p;
unsigned long *endstack;
int i;
if (!stack) {
if (task)
stack = (unsigned long *)task->thread.esp0;
else
stack = (unsigned long *)&stack;
}
endstack = (unsigned long *)(((unsigned long)stack + THREAD_SIZE - 1) & -THREAD_SIZE);
printk("Stack from %08lx:", (unsigned long)stack);
p = stack;
for (i = 0; i < kstack_depth_to_print; i++) {
if (p + 1 > endstack)
break;
if (i % 8 == 0)
printk("\n ");
printk(" %08lx", *p++);
}
printk("\n");
show_trace(stack);
}
/*
* The architecture-independent backtrace generator
*/
void dump_stack(void)
{
unsigned long stack;
show_trace(&stack);
}
EXPORT_SYMBOL(dump_stack);
/*
* The vector number returned in the frame pointer may also contain
* the "fs" (Fault Status) bits on ColdFire. These are in the bottom
* 2 bits, and upper 2 bits. So we need to mask out the real vector
* number before using it in comparisons. You don't need to do this on
* real 68k parts, but it won't hurt either.
*/
void bad_super_trap (struct frame *fp)
{
int vector = (fp->ptregs.vector >> 2) & 0xff;
console_verbose();
if (vector < ARRAY_SIZE(vec_names))
printk ("*** %s *** FORMAT=%X\n",
vec_names[vector],
fp->ptregs.format);
else
printk ("*** Exception %d *** FORMAT=%X\n",
vector, fp->ptregs.format);
if (vector == VEC_ADDRERR && CPU_IS_020_OR_030) {
unsigned short ssw = fp->un.fmtb.ssw;
printk ("SSW=%#06x ", ssw);
if (ssw & RC)
printk ("Pipe stage C instruction fault at %#010lx\n",
(fp->ptregs.format) == 0xA ?
fp->ptregs.pc + 2 : fp->un.fmtb.baddr - 2);
if (ssw & RB)
printk ("Pipe stage B instruction fault at %#010lx\n",
(fp->ptregs.format) == 0xA ?
fp->ptregs.pc + 4 : fp->un.fmtb.baddr);
if (ssw & DF)
printk ("Data %s fault at %#010lx in %s (pc=%#lx)\n",
ssw & RW ? "read" : "write",
fp->un.fmtb.daddr, space_names[ssw & DFC],
fp->ptregs.pc);
}
printk ("Current process id is %d\n", task_pid_nr(current));
die_if_kernel("BAD KERNEL TRAP", &fp->ptregs, 0);
}
asmlinkage void trap_c(struct frame *fp)
{
int sig;
int vector = (fp->ptregs.vector >> 2) & 0xff;
siginfo_t info;
if (fp->ptregs.sr & PS_S) {
if (vector == VEC_TRACE) {
/* traced a trapping instruction on a 68020/30,
* real exception will be executed afterwards.
*/
} else if (!handle_kernel_fault(&fp->ptregs))
bad_super_trap(fp);
return;
}
/* send the appropriate signal to the user program */
switch (vector) {
case VEC_ADDRERR:
info.si_code = BUS_ADRALN;
sig = SIGBUS;
break;
case VEC_ILLEGAL:
case VEC_LINE10:
case VEC_LINE11:
info.si_code = ILL_ILLOPC;
sig = SIGILL;
break;
case VEC_PRIV:
info.si_code = ILL_PRVOPC;
sig = SIGILL;
break;
case VEC_COPROC:
info.si_code = ILL_COPROC;
sig = SIGILL;
break;
case VEC_TRAP1:
case VEC_TRAP2:
case VEC_TRAP3:
case VEC_TRAP4:
case VEC_TRAP5:
case VEC_TRAP6:
case VEC_TRAP7:
case VEC_TRAP8:
case VEC_TRAP9:
case VEC_TRAP10:
case VEC_TRAP11:
case VEC_TRAP12:
case VEC_TRAP13:
case VEC_TRAP14:
info.si_code = ILL_ILLTRP;
sig = SIGILL;
break;
case VEC_FPBRUC:
case VEC_FPOE:
case VEC_FPNAN:
info.si_code = FPE_FLTINV;
sig = SIGFPE;
break;
case VEC_FPIR:
info.si_code = FPE_FLTRES;
sig = SIGFPE;
break;
case VEC_FPDIVZ:
info.si_code = FPE_FLTDIV;
sig = SIGFPE;
break;
case VEC_FPUNDER:
info.si_code = FPE_FLTUND;
sig = SIGFPE;
break;
case VEC_FPOVER:
info.si_code = FPE_FLTOVF;
sig = SIGFPE;
break;
case VEC_ZERODIV:
info.si_code = FPE_INTDIV;
sig = SIGFPE;
break;
case VEC_CHK:
case VEC_TRAP:
info.si_code = FPE_INTOVF;
sig = SIGFPE;
break;
case VEC_TRACE: /* ptrace single step */
info.si_code = TRAP_TRACE;
sig = SIGTRAP;
break;
case VEC_TRAP15: /* breakpoint */
info.si_code = TRAP_BRKPT;
sig = SIGTRAP;
break;
default:
info.si_code = ILL_ILLOPC;
sig = SIGILL;
break;
}
info.si_signo = sig;
info.si_errno = 0;
switch (fp->ptregs.format) {
default:
info.si_addr = (void *) fp->ptregs.pc;
break;
case 2:
info.si_addr = (void *) fp->un.fmt2.iaddr;
break;
case 7:
info.si_addr = (void *) fp->un.fmt7.effaddr;
break;
case 9:
info.si_addr = (void *) fp->un.fmt9.iaddr;
break;
case 10:
info.si_addr = (void *) fp->un.fmta.daddr;
break;
case 11:
info.si_addr = (void *) fp->un.fmtb.daddr;
break;
}
force_sig_info (sig, &info, current);
}
void die_if_kernel (char *str, struct pt_regs *fp, int nr)
{
if (!(fp->sr & PS_S))
return;
console_verbose();
printk("%s: %08x\n",str,nr);
show_registers(fp);
add_taint(TAINT_DIE);
do_exit(SIGSEGV);
}
asmlinkage void set_esp0(unsigned long ssp)
{
current->thread.esp0 = ssp;
}
/*
* This function is called if an error occur while accessing
* user-space from the fpsp040 code.
*/
asmlinkage void fpsp040_die(void)
{
do_exit(SIGSEGV);
}
#ifdef CONFIG_M68KFPU_EMU
asmlinkage void fpemu_signal(int signal, int code, void *addr)
{
siginfo_t info;
info.si_signo = signal;
info.si_errno = 0;
info.si_code = code;
info.si_addr = addr;
force_sig_info(signal, &info, current);
}
#endif
/*
* linux/arch/m68k/kernel/traps.c
*
* Copyright (C) 1993, 1994 by Hamish Macdonald
*
* 68040 fixes by Michael Rausch
* 68040 fixes by Martin Apel
* 68040 fixes and writeback by Richard Zidlicky
* 68060 fixes by Roman Hodek
* 68060 fixes by Jesper Skov
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file COPYING in the main directory of this archive
* for more details.
*/
/*
* Sets up all exception vectors
*/
#include <linux/sched.h>
#include <linux/signal.h>
#include <linux/kernel.h>
#include <linux/mm.h>
#include <linux/module.h>
#include <linux/user.h>
#include <linux/string.h>
#include <linux/linkage.h>
#include <linux/init.h>
#include <linux/ptrace.h>
#include <linux/kallsyms.h>
#include <asm/setup.h>
#include <asm/fpu.h>
#include <asm/system.h>
#include <asm/uaccess.h>
#include <asm/traps.h>
#include <asm/pgalloc.h>
#include <asm/machdep.h>
#include <asm/siginfo.h>
/* assembler routines */
asmlinkage void system_call(void);
asmlinkage void buserr(void);
asmlinkage void trap(void);
asmlinkage void nmihandler(void);
#ifdef CONFIG_M68KFPU_EMU
asmlinkage void fpu_emu(void);
#endif
e_vector vectors[256];
/* nmi handler for the Amiga */
asm(".text\n"
__ALIGN_STR "\n"
"nmihandler: rte");
/*
* this must be called very early as the kernel might
* use some instruction that are emulated on the 060
* and so we're prepared for early probe attempts (e.g. nf_init).
*/
void __init base_trap_init(void)
{
if (MACH_IS_SUN3X) {
extern e_vector *sun3x_prom_vbr;
__asm__ volatile ("movec %%vbr, %0" : "=r" (sun3x_prom_vbr));
}
/* setup the exception vector table */
__asm__ volatile ("movec %0,%%vbr" : : "r" ((void*)vectors));
if (CPU_IS_060) {
/* set up ISP entry points */
asmlinkage void unimp_vec(void) asm ("_060_isp_unimp");
vectors[VEC_UNIMPII] = unimp_vec;
}
vectors[VEC_BUSERR] = buserr;
vectors[VEC_ILLEGAL] = trap;
vectors[VEC_SYS] = system_call;
}
void __init trap_init (void)
{
int i;
for (i = VEC_SPUR; i <= VEC_INT7; i++)
vectors[i] = bad_inthandler;
for (i = 0; i < VEC_USER; i++)
if (!vectors[i])
vectors[i] = trap;
for (i = VEC_USER; i < 256; i++)
vectors[i] = bad_inthandler;
#ifdef CONFIG_M68KFPU_EMU
if (FPU_IS_EMU)
vectors[VEC_LINE11] = fpu_emu;
#endif
if (CPU_IS_040 && !FPU_IS_EMU) {
/* set up FPSP entry points */
asmlinkage void dz_vec(void) asm ("dz");
asmlinkage void inex_vec(void) asm ("inex");
asmlinkage void ovfl_vec(void) asm ("ovfl");
asmlinkage void unfl_vec(void) asm ("unfl");
asmlinkage void snan_vec(void) asm ("snan");
asmlinkage void operr_vec(void) asm ("operr");
asmlinkage void bsun_vec(void) asm ("bsun");
asmlinkage void fline_vec(void) asm ("fline");
asmlinkage void unsupp_vec(void) asm ("unsupp");
vectors[VEC_FPDIVZ] = dz_vec;
vectors[VEC_FPIR] = inex_vec;
vectors[VEC_FPOVER] = ovfl_vec;
vectors[VEC_FPUNDER] = unfl_vec;
vectors[VEC_FPNAN] = snan_vec;
vectors[VEC_FPOE] = operr_vec;
vectors[VEC_FPBRUC] = bsun_vec;
vectors[VEC_LINE11] = fline_vec;
vectors[VEC_FPUNSUP] = unsupp_vec;
}
if (CPU_IS_060 && !FPU_IS_EMU) {
/* set up IFPSP entry points */
asmlinkage void snan_vec6(void) asm ("_060_fpsp_snan");
asmlinkage void operr_vec6(void) asm ("_060_fpsp_operr");
asmlinkage void ovfl_vec6(void) asm ("_060_fpsp_ovfl");
asmlinkage void unfl_vec6(void) asm ("_060_fpsp_unfl");
asmlinkage void dz_vec6(void) asm ("_060_fpsp_dz");
asmlinkage void inex_vec6(void) asm ("_060_fpsp_inex");
asmlinkage void fline_vec6(void) asm ("_060_fpsp_fline");
asmlinkage void unsupp_vec6(void) asm ("_060_fpsp_unsupp");
asmlinkage void effadd_vec6(void) asm ("_060_fpsp_effadd");
vectors[VEC_FPNAN] = snan_vec6;
vectors[VEC_FPOE] = operr_vec6;
vectors[VEC_FPOVER] = ovfl_vec6;
vectors[VEC_FPUNDER] = unfl_vec6;
vectors[VEC_FPDIVZ] = dz_vec6;
vectors[VEC_FPIR] = inex_vec6;
vectors[VEC_LINE11] = fline_vec6;
vectors[VEC_FPUNSUP] = unsupp_vec6;
vectors[VEC_UNIMPEA] = effadd_vec6;
}
/* if running on an amiga, make the NMI interrupt do nothing */
if (MACH_IS_AMIGA) {
vectors[VEC_INT7] = nmihandler;
}
}
static const char *vec_names[] = {
[VEC_RESETSP] = "RESET SP",
[VEC_RESETPC] = "RESET PC",
[VEC_BUSERR] = "BUS ERROR",
[VEC_ADDRERR] = "ADDRESS ERROR",
[VEC_ILLEGAL] = "ILLEGAL INSTRUCTION",
[VEC_ZERODIV] = "ZERO DIVIDE",
[VEC_CHK] = "CHK",
[VEC_TRAP] = "TRAPcc",
[VEC_PRIV] = "PRIVILEGE VIOLATION",
[VEC_TRACE] = "TRACE",
[VEC_LINE10] = "LINE 1010",
[VEC_LINE11] = "LINE 1111",
[VEC_RESV12] = "UNASSIGNED RESERVED 12",
[VEC_COPROC] = "COPROCESSOR PROTOCOL VIOLATION",
[VEC_FORMAT] = "FORMAT ERROR",
[VEC_UNINT] = "UNINITIALIZED INTERRUPT",
[VEC_RESV16] = "UNASSIGNED RESERVED 16",
[VEC_RESV17] = "UNASSIGNED RESERVED 17",
[VEC_RESV18] = "UNASSIGNED RESERVED 18",
[VEC_RESV19] = "UNASSIGNED RESERVED 19",
[VEC_RESV20] = "UNASSIGNED RESERVED 20",
[VEC_RESV21] = "UNASSIGNED RESERVED 21",
[VEC_RESV22] = "UNASSIGNED RESERVED 22",
[VEC_RESV23] = "UNASSIGNED RESERVED 23",
[VEC_SPUR] = "SPURIOUS INTERRUPT",
[VEC_INT1] = "LEVEL 1 INT",
[VEC_INT2] = "LEVEL 2 INT",
[VEC_INT3] = "LEVEL 3 INT",
[VEC_INT4] = "LEVEL 4 INT",
[VEC_INT5] = "LEVEL 5 INT",
[VEC_INT6] = "LEVEL 6 INT",
[VEC_INT7] = "LEVEL 7 INT",
[VEC_SYS] = "SYSCALL",
[VEC_TRAP1] = "TRAP #1",
[VEC_TRAP2] = "TRAP #2",
[VEC_TRAP3] = "TRAP #3",
[VEC_TRAP4] = "TRAP #4",
[VEC_TRAP5] = "TRAP #5",
[VEC_TRAP6] = "TRAP #6",
[VEC_TRAP7] = "TRAP #7",
[VEC_TRAP8] = "TRAP #8",
[VEC_TRAP9] = "TRAP #9",
[VEC_TRAP10] = "TRAP #10",
[VEC_TRAP11] = "TRAP #11",
[VEC_TRAP12] = "TRAP #12",
[VEC_TRAP13] = "TRAP #13",
[VEC_TRAP14] = "TRAP #14",
[VEC_TRAP15] = "TRAP #15",
[VEC_FPBRUC] = "FPCP BSUN",
[VEC_FPIR] = "FPCP INEXACT",
[VEC_FPDIVZ] = "FPCP DIV BY 0",
[VEC_FPUNDER] = "FPCP UNDERFLOW",
[VEC_FPOE] = "FPCP OPERAND ERROR",
[VEC_FPOVER] = "FPCP OVERFLOW",
[VEC_FPNAN] = "FPCP SNAN",
[VEC_FPUNSUP] = "FPCP UNSUPPORTED OPERATION",
[VEC_MMUCFG] = "MMU CONFIGURATION ERROR",
[VEC_MMUILL] = "MMU ILLEGAL OPERATION ERROR",
[VEC_MMUACC] = "MMU ACCESS LEVEL VIOLATION ERROR",
[VEC_RESV59] = "UNASSIGNED RESERVED 59",
[VEC_UNIMPEA] = "UNASSIGNED RESERVED 60",
[VEC_UNIMPII] = "UNASSIGNED RESERVED 61",
[VEC_RESV62] = "UNASSIGNED RESERVED 62",
[VEC_RESV63] = "UNASSIGNED RESERVED 63",
};
static const char *space_names[] = {
[0] = "Space 0",
[USER_DATA] = "User Data",
[USER_PROGRAM] = "User Program",
#ifndef CONFIG_SUN3
[3] = "Space 3",
#else
[FC_CONTROL] = "Control",
#endif
[4] = "Space 4",
[SUPER_DATA] = "Super Data",
[SUPER_PROGRAM] = "Super Program",
[CPU_SPACE] = "CPU"
};
void die_if_kernel(char *,struct pt_regs *,int);
asmlinkage int do_page_fault(struct pt_regs *regs, unsigned long address,
unsigned long error_code);
int send_fault_sig(struct pt_regs *regs);
asmlinkage void trap_c(struct frame *fp);
#if defined (CONFIG_M68060)
static inline void access_error060 (struct frame *fp)
{
unsigned long fslw = fp->un.fmt4.pc; /* is really FSLW for access error */
#ifdef DEBUG
printk("fslw=%#lx, fa=%#lx\n", fslw, fp->un.fmt4.effaddr);
#endif
if (fslw & MMU060_BPE) {
/* branch prediction error -> clear branch cache */
__asm__ __volatile__ ("movec %/cacr,%/d0\n\t"
"orl #0x00400000,%/d0\n\t"
"movec %/d0,%/cacr"
: : : "d0" );
/* return if there's no other error */
if (!(fslw & MMU060_ERR_BITS) && !(fslw & MMU060_SEE))
return;
}
if (fslw & (MMU060_DESC_ERR | MMU060_WP | MMU060_SP)) {
unsigned long errorcode;
unsigned long addr = fp->un.fmt4.effaddr;
if (fslw & MMU060_MA)
addr = (addr + PAGE_SIZE - 1) & PAGE_MASK;
errorcode = 1;
if (fslw & MMU060_DESC_ERR) {
__flush_tlb040_one(addr);
errorcode = 0;
}
if (fslw & MMU060_W)
errorcode |= 2;
#ifdef DEBUG
printk("errorcode = %d\n", errorcode );
#endif
do_page_fault(&fp->ptregs, addr, errorcode);
} else if (fslw & (MMU060_SEE)){
/* Software Emulation Error.
* fault during mem_read/mem_write in ifpsp060/os.S
*/
send_fault_sig(&fp->ptregs);
} else if (!(fslw & (MMU060_RE|MMU060_WE)) ||
send_fault_sig(&fp->ptregs) > 0) {
printk("pc=%#lx, fa=%#lx\n", fp->ptregs.pc, fp->un.fmt4.effaddr);
printk( "68060 access error, fslw=%lx\n", fslw );
trap_c( fp );
}
}
#endif /* CONFIG_M68060 */
#if defined (CONFIG_M68040)
static inline unsigned long probe040(int iswrite, unsigned long addr, int wbs)
{
unsigned long mmusr;
mm_segment_t old_fs = get_fs();
set_fs(MAKE_MM_SEG(wbs));
if (iswrite)
asm volatile (".chip 68040; ptestw (%0); .chip 68k" : : "a" (addr));
else
asm volatile (".chip 68040; ptestr (%0); .chip 68k" : : "a" (addr));
asm volatile (".chip 68040; movec %%mmusr,%0; .chip 68k" : "=r" (mmusr));
set_fs(old_fs);
return mmusr;
}
static inline int do_040writeback1(unsigned short wbs, unsigned long wba,
unsigned long wbd)
{
int res = 0;
mm_segment_t old_fs = get_fs();
/* set_fs can not be moved, otherwise put_user() may oops */
set_fs(MAKE_MM_SEG(wbs));
switch (wbs & WBSIZ_040) {
case BA_SIZE_BYTE:
res = put_user(wbd & 0xff, (char __user *)wba);
break;
case BA_SIZE_WORD:
res = put_user(wbd & 0xffff, (short __user *)wba);
break;
case BA_SIZE_LONG:
res = put_user(wbd, (int __user *)wba);
break;
}
/* set_fs can not be moved, otherwise put_user() may oops */
set_fs(old_fs);
#ifdef DEBUG
printk("do_040writeback1, res=%d\n",res);
#endif
return res;
}
/* after an exception in a writeback the stack frame corresponding
* to that exception is discarded, set a few bits in the old frame
* to simulate what it should look like
*/
static inline void fix_xframe040(struct frame *fp, unsigned long wba, unsigned short wbs)
{
fp->un.fmt7.faddr = wba;
fp->un.fmt7.ssw = wbs & 0xff;
if (wba != current->thread.faddr)
fp->un.fmt7.ssw |= MA_040;
}
static inline void do_040writebacks(struct frame *fp)
{
int res = 0;
#if 0
if (fp->un.fmt7.wb1s & WBV_040)
printk("access_error040: cannot handle 1st writeback. oops.\n");
#endif
if ((fp->un.fmt7.wb2s & WBV_040) &&
!(fp->un.fmt7.wb2s & WBTT_040)) {
res = do_040writeback1(fp->un.fmt7.wb2s, fp->un.fmt7.wb2a,
fp->un.fmt7.wb2d);
if (res)
fix_xframe040(fp, fp->un.fmt7.wb2a, fp->un.fmt7.wb2s);
else
fp->un.fmt7.wb2s = 0;
}
/* do the 2nd wb only if the first one was successful (except for a kernel wb) */
if (fp->un.fmt7.wb3s & WBV_040 && (!res || fp->un.fmt7.wb3s & 4)) {
res = do_040writeback1(fp->un.fmt7.wb3s, fp->un.fmt7.wb3a,
fp->un.fmt7.wb3d);
if (res)
{
fix_xframe040(fp, fp->un.fmt7.wb3a, fp->un.fmt7.wb3s);
fp->un.fmt7.wb2s = fp->un.fmt7.wb3s;
fp->un.fmt7.wb3s &= (~WBV_040);
fp->un.fmt7.wb2a = fp->un.fmt7.wb3a;
fp->un.fmt7.wb2d = fp->un.fmt7.wb3d;
}
else
fp->un.fmt7.wb3s = 0;
}
if (res)
send_fault_sig(&fp->ptregs);
}
/*
* called from sigreturn(), must ensure userspace code didn't
* manipulate exception frame to circumvent protection, then complete
* pending writebacks
* we just clear TM2 to turn it into a userspace access
*/
asmlinkage void berr_040cleanup(struct frame *fp)
{
fp->un.fmt7.wb2s &= ~4;
fp->un.fmt7.wb3s &= ~4;
do_040writebacks(fp);
}
static inline void access_error040(struct frame *fp)
{
unsigned short ssw = fp->un.fmt7.ssw;
unsigned long mmusr;
#ifdef DEBUG
printk("ssw=%#x, fa=%#lx\n", ssw, fp->un.fmt7.faddr);
printk("wb1s=%#x, wb2s=%#x, wb3s=%#x\n", fp->un.fmt7.wb1s,
fp->un.fmt7.wb2s, fp->un.fmt7.wb3s);
printk ("wb2a=%lx, wb3a=%lx, wb2d=%lx, wb3d=%lx\n",
fp->un.fmt7.wb2a, fp->un.fmt7.wb3a,
fp->un.fmt7.wb2d, fp->un.fmt7.wb3d);
#endif
if (ssw & ATC_040) {
unsigned long addr = fp->un.fmt7.faddr;
unsigned long errorcode;
/*
* The MMU status has to be determined AFTER the address
* has been corrected if there was a misaligned access (MA).
*/
if (ssw & MA_040)
addr = (addr + 7) & -8;
/* MMU error, get the MMUSR info for this access */
mmusr = probe040(!(ssw & RW_040), addr, ssw);
#ifdef DEBUG
printk("mmusr = %lx\n", mmusr);
#endif
errorcode = 1;
if (!(mmusr & MMU_R_040)) {
/* clear the invalid atc entry */
__flush_tlb040_one(addr);
errorcode = 0;
}
/* despite what documentation seems to say, RMW
* accesses have always both the LK and RW bits set */
if (!(ssw & RW_040) || (ssw & LK_040))
errorcode |= 2;
if (do_page_fault(&fp->ptregs, addr, errorcode)) {
#ifdef DEBUG
printk("do_page_fault() !=0\n");
#endif
if (user_mode(&fp->ptregs)){
/* delay writebacks after signal delivery */
#ifdef DEBUG
printk(".. was usermode - return\n");
#endif
return;
}
/* disable writeback into user space from kernel
* (if do_page_fault didn't fix the mapping,
* the writeback won't do good)
*/
disable_wb:
#ifdef DEBUG
printk(".. disabling wb2\n");
#endif
if (fp->un.fmt7.wb2a == fp->un.fmt7.faddr)
fp->un.fmt7.wb2s &= ~WBV_040;
if (fp->un.fmt7.wb3a == fp->un.fmt7.faddr)
fp->un.fmt7.wb3s &= ~WBV_040;
}
} else {
/* In case of a bus error we either kill the process or expect
* the kernel to catch the fault, which then is also responsible
* for cleaning up the mess.
*/
current->thread.signo = SIGBUS;
current->thread.faddr = fp->un.fmt7.faddr;
if (send_fault_sig(&fp->ptregs) >= 0)
printk("68040 bus error (ssw=%x, faddr=%lx)\n", ssw,
fp->un.fmt7.faddr);
goto disable_wb;
}
do_040writebacks(fp);
}
#endif /* CONFIG_M68040 */
#if defined(CONFIG_SUN3)
#include <asm/sun3mmu.h>
extern int mmu_emu_handle_fault (unsigned long, int, int);
/* sun3 version of bus_error030 */
static inline void bus_error030 (struct frame *fp)
{
unsigned char buserr_type = sun3_get_buserr ();
unsigned long addr, errorcode;
unsigned short ssw = fp->un.fmtb.ssw;
extern unsigned long _sun3_map_test_start, _sun3_map_test_end;
#ifdef DEBUG
if (ssw & (FC | FB))
printk ("Instruction fault at %#010lx\n",
ssw & FC ?
fp->ptregs.format == 0xa ? fp->ptregs.pc + 2 : fp->un.fmtb.baddr - 2
:
fp->ptregs.format == 0xa ? fp->ptregs.pc + 4 : fp->un.fmtb.baddr);
if (ssw & DF)
printk ("Data %s fault at %#010lx in %s (pc=%#lx)\n",
ssw & RW ? "read" : "write",
fp->un.fmtb.daddr,
space_names[ssw & DFC], fp->ptregs.pc);
#endif
/*
* Check if this page should be demand-mapped. This needs to go before
* the testing for a bad kernel-space access (demand-mapping applies
* to kernel accesses too).
*/
if ((ssw & DF)
&& (buserr_type & (SUN3_BUSERR_PROTERR | SUN3_BUSERR_INVALID))) {
if (mmu_emu_handle_fault (fp->un.fmtb.daddr, ssw & RW, 0))
return;
}
/* Check for kernel-space pagefault (BAD). */
if (fp->ptregs.sr & PS_S) {
/* kernel fault must be a data fault to user space */
if (! ((ssw & DF) && ((ssw & DFC) == USER_DATA))) {
// try checking the kernel mappings before surrender
if (mmu_emu_handle_fault (fp->un.fmtb.daddr, ssw & RW, 1))
return;
/* instruction fault or kernel data fault! */
if (ssw & (FC | FB))
printk ("Instruction fault at %#010lx\n",
fp->ptregs.pc);
if (ssw & DF) {
/* was this fault incurred testing bus mappings? */
if((fp->ptregs.pc >= (unsigned long)&_sun3_map_test_start) &&
(fp->ptregs.pc <= (unsigned long)&_sun3_map_test_end)) {
send_fault_sig(&fp->ptregs);
return;
}
printk ("Data %s fault at %#010lx in %s (pc=%#lx)\n",
ssw & RW ? "read" : "write",
fp->un.fmtb.daddr,
space_names[ssw & DFC], fp->ptregs.pc);
}
printk ("BAD KERNEL BUSERR\n");
die_if_kernel("Oops", &fp->ptregs,0);
force_sig(SIGKILL, current);
return;
}
} else {
/* user fault */
if (!(ssw & (FC | FB)) && !(ssw & DF))
/* not an instruction fault or data fault! BAD */
panic ("USER BUSERR w/o instruction or data fault");
}
/* First handle the data fault, if any. */
if (ssw & DF) {
addr = fp->un.fmtb.daddr;
// errorcode bit 0: 0 -> no page 1 -> protection fault
// errorcode bit 1: 0 -> read fault 1 -> write fault
// (buserr_type & SUN3_BUSERR_PROTERR) -> protection fault
// (buserr_type & SUN3_BUSERR_INVALID) -> invalid page fault
if (buserr_type & SUN3_BUSERR_PROTERR)
errorcode = 0x01;
else if (buserr_type & SUN3_BUSERR_INVALID)
errorcode = 0x00;
else {
#ifdef DEBUG
printk ("*** unexpected busfault type=%#04x\n", buserr_type);
printk ("invalid %s access at %#lx from pc %#lx\n",
!(ssw & RW) ? "write" : "read", addr,
fp->ptregs.pc);
#endif
die_if_kernel ("Oops", &fp->ptregs, buserr_type);
force_sig (SIGBUS, current);
return;
}
//todo: wtf is RM bit? --m
if (!(ssw & RW) || ssw & RM)
errorcode |= 0x02;
/* Handle page fault. */
do_page_fault (&fp->ptregs, addr, errorcode);
/* Retry the data fault now. */
return;
}
/* Now handle the instruction fault. */
/* Get the fault address. */
if (fp->ptregs.format == 0xA)
addr = fp->ptregs.pc + 4;
else
addr = fp->un.fmtb.baddr;
if (ssw & FC)
addr -= 2;
if (buserr_type & SUN3_BUSERR_INVALID) {
if (!mmu_emu_handle_fault (fp->un.fmtb.daddr, 1, 0))
do_page_fault (&fp->ptregs, addr, 0);
} else {
#ifdef DEBUG
printk ("protection fault on insn access (segv).\n");
#endif
force_sig (SIGSEGV, current);
}
}
#else
#if defined(CPU_M68020_OR_M68030)
static inline void bus_error030 (struct frame *fp)
{
volatile unsigned short temp;
unsigned short mmusr;
unsigned long addr, errorcode;
unsigned short ssw = fp->un.fmtb.ssw;
#ifdef DEBUG
unsigned long desc;
printk ("pid = %x ", current->pid);
printk ("SSW=%#06x ", ssw);
if (ssw & (FC | FB))
printk ("Instruction fault at %#010lx\n",
ssw & FC ?
fp->ptregs.format == 0xa ? fp->ptregs.pc + 2 : fp->un.fmtb.baddr - 2
:
fp->ptregs.format == 0xa ? fp->ptregs.pc + 4 : fp->un.fmtb.baddr);
if (ssw & DF)
printk ("Data %s fault at %#010lx in %s (pc=%#lx)\n",
ssw & RW ? "read" : "write",
fp->un.fmtb.daddr,
space_names[ssw & DFC], fp->ptregs.pc);
#endif
/* ++andreas: If a data fault and an instruction fault happen
at the same time map in both pages. */
/* First handle the data fault, if any. */
if (ssw & DF) {
addr = fp->un.fmtb.daddr;
#ifdef DEBUG
asm volatile ("ptestr %3,%2@,#7,%0\n\t"
"pmove %%psr,%1@"
: "=a&" (desc)
: "a" (&temp), "a" (addr), "d" (ssw));
#else
asm volatile ("ptestr %2,%1@,#7\n\t"
"pmove %%psr,%0@"
: : "a" (&temp), "a" (addr), "d" (ssw));
#endif
mmusr = temp;
#ifdef DEBUG
printk("mmusr is %#x for addr %#lx in task %p\n",
mmusr, addr, current);
printk("descriptor address is %#lx, contents %#lx\n",
__va(desc), *(unsigned long *)__va(desc));
#endif
errorcode = (mmusr & MMU_I) ? 0 : 1;
if (!(ssw & RW) || (ssw & RM))
errorcode |= 2;
if (mmusr & (MMU_I | MMU_WP)) {
if (ssw & 4) {
printk("Data %s fault at %#010lx in %s (pc=%#lx)\n",
ssw & RW ? "read" : "write",
fp->un.fmtb.daddr,
space_names[ssw & DFC], fp->ptregs.pc);
goto buserr;
}
/* Don't try to do anything further if an exception was
handled. */
if (do_page_fault (&fp->ptregs, addr, errorcode) < 0)
return;
} else if (!(mmusr & MMU_I)) {
/* probably a 020 cas fault */
if (!(ssw & RM) && send_fault_sig(&fp->ptregs) > 0)
printk("unexpected bus error (%#x,%#x)\n", ssw, mmusr);
} else if (mmusr & (MMU_B|MMU_L|MMU_S)) {
printk("invalid %s access at %#lx from pc %#lx\n",
!(ssw & RW) ? "write" : "read", addr,
fp->ptregs.pc);
die_if_kernel("Oops",&fp->ptregs,mmusr);
force_sig(SIGSEGV, current);
return;
} else {
#if 0
static volatile long tlong;
#endif
printk("weird %s access at %#lx from pc %#lx (ssw is %#x)\n",
!(ssw & RW) ? "write" : "read", addr,
fp->ptregs.pc, ssw);
asm volatile ("ptestr #1,%1@,#0\n\t"
"pmove %%psr,%0@"
: /* no outputs */
: "a" (&temp), "a" (addr));
mmusr = temp;
printk ("level 0 mmusr is %#x\n", mmusr);
#if 0
asm volatile ("pmove %%tt0,%0@"
: /* no outputs */
: "a" (&tlong));
printk("tt0 is %#lx, ", tlong);
asm volatile ("pmove %%tt1,%0@"
: /* no outputs */
: "a" (&tlong));
printk("tt1 is %#lx\n", tlong);
#endif
#ifdef DEBUG
printk("Unknown SIGSEGV - 1\n");
#endif
die_if_kernel("Oops",&fp->ptregs,mmusr);
force_sig(SIGSEGV, current);
return;
}
/* setup an ATC entry for the access about to be retried */
if (!(ssw & RW) || (ssw & RM))
asm volatile ("ploadw %1,%0@" : /* no outputs */
: "a" (addr), "d" (ssw));
else
asm volatile ("ploadr %1,%0@" : /* no outputs */
: "a" (addr), "d" (ssw));
}
/* Now handle the instruction fault. */
if (!(ssw & (FC|FB)))
return;
if (fp->ptregs.sr & PS_S) {
printk("Instruction fault at %#010lx\n",
fp->ptregs.pc);
buserr:
printk ("BAD KERNEL BUSERR\n");
die_if_kernel("Oops",&fp->ptregs,0);
force_sig(SIGKILL, current);
return;
}
/* get the fault address */
if (fp->ptregs.format == 10)
addr = fp->ptregs.pc + 4;
else
addr = fp->un.fmtb.baddr;
if (ssw & FC)
addr -= 2;
if ((ssw & DF) && ((addr ^ fp->un.fmtb.daddr) & PAGE_MASK) == 0)
/* Insn fault on same page as data fault. But we
should still create the ATC entry. */
goto create_atc_entry;
#ifdef DEBUG
asm volatile ("ptestr #1,%2@,#7,%0\n\t"
"pmove %%psr,%1@"
: "=a&" (desc)
: "a" (&temp), "a" (addr));
#else
asm volatile ("ptestr #1,%1@,#7\n\t"
"pmove %%psr,%0@"
: : "a" (&temp), "a" (addr));
#endif
mmusr = temp;
#ifdef DEBUG
printk ("mmusr is %#x for addr %#lx in task %p\n",
mmusr, addr, current);
printk ("descriptor address is %#lx, contents %#lx\n",
__va(desc), *(unsigned long *)__va(desc));
#endif
if (mmusr & MMU_I)
do_page_fault (&fp->ptregs, addr, 0);
else if (mmusr & (MMU_B|MMU_L|MMU_S)) {
printk ("invalid insn access at %#lx from pc %#lx\n",
addr, fp->ptregs.pc);
#ifdef DEBUG
printk("Unknown SIGSEGV - 2\n");
#endif
die_if_kernel("Oops",&fp->ptregs,mmusr);
force_sig(SIGSEGV, current);
return;
}
create_atc_entry:
/* setup an ATC entry for the access about to be retried */
asm volatile ("ploadr #2,%0@" : /* no outputs */
: "a" (addr));
}
#endif /* CPU_M68020_OR_M68030 */
#endif /* !CONFIG_SUN3 */
asmlinkage void buserr_c(struct frame *fp)
{
/* Only set esp0 if coming from user mode */
if (user_mode(&fp->ptregs))
current->thread.esp0 = (unsigned long) fp;
#ifdef DEBUG
printk ("*** Bus Error *** Format is %x\n", fp->ptregs.format);
#endif
switch (fp->ptregs.format) {
#if defined (CONFIG_M68060)
case 4: /* 68060 access error */
access_error060 (fp);
break;
#endif
#if defined (CONFIG_M68040)
case 0x7: /* 68040 access error */
access_error040 (fp);
break;
#endif
#if defined (CPU_M68020_OR_M68030)
case 0xa:
case 0xb:
bus_error030 (fp);
break;
#endif
default:
die_if_kernel("bad frame format",&fp->ptregs,0);
#ifdef DEBUG
printk("Unknown SIGSEGV - 4\n");
#endif
force_sig(SIGSEGV, current);
}
}
static int kstack_depth_to_print = 48;
void show_trace(unsigned long *stack)
{
unsigned long *endstack;
unsigned long addr;
int i;
printk("Call Trace:");
addr = (unsigned long)stack + THREAD_SIZE - 1;
endstack = (unsigned long *)(addr & -THREAD_SIZE);
i = 0;
while (stack + 1 <= endstack) {
addr = *stack++;
/*
* If the address is either in the text segment of the
* kernel, or in the region which contains vmalloc'ed
* memory, it *may* be the address of a calling
* routine; if so, print it so that someone tracing
* down the cause of the crash will be able to figure
* out the call path that was taken.
*/
if (__kernel_text_address(addr)) {
#ifndef CONFIG_KALLSYMS
if (i % 5 == 0)
printk("\n ");
#endif
printk(" [<%08lx>] %pS\n", addr, (void *)addr);
i++;
}
}
printk("\n");
}
void show_registers(struct pt_regs *regs)
{
struct frame *fp = (struct frame *)regs;
mm_segment_t old_fs = get_fs();
u16 c, *cp;
unsigned long addr;
int i;
print_modules();
printk("PC: [<%08lx>] %pS\n", regs->pc, (void *)regs->pc);
printk("SR: %04x SP: %p a2: %08lx\n", regs->sr, regs, regs->a2);
printk("d0: %08lx d1: %08lx d2: %08lx d3: %08lx\n",
regs->d0, regs->d1, regs->d2, regs->d3);
printk("d4: %08lx d5: %08lx a0: %08lx a1: %08lx\n",
regs->d4, regs->d5, regs->a0, regs->a1);
printk("Process %s (pid: %d, task=%p)\n",
current->comm, task_pid_nr(current), current);
addr = (unsigned long)&fp->un;
printk("Frame format=%X ", regs->format);
switch (regs->format) {
case 0x2:
printk("instr addr=%08lx\n", fp->un.fmt2.iaddr);
addr += sizeof(fp->un.fmt2);
break;
case 0x3:
printk("eff addr=%08lx\n", fp->un.fmt3.effaddr);
addr += sizeof(fp->un.fmt3);
break;
case 0x4:
printk((CPU_IS_060 ? "fault addr=%08lx fslw=%08lx\n"
: "eff addr=%08lx pc=%08lx\n"),
fp->un.fmt4.effaddr, fp->un.fmt4.pc);
addr += sizeof(fp->un.fmt4);
break;
case 0x7:
printk("eff addr=%08lx ssw=%04x faddr=%08lx\n",
fp->un.fmt7.effaddr, fp->un.fmt7.ssw, fp->un.fmt7.faddr);
printk("wb 1 stat/addr/data: %04x %08lx %08lx\n",
fp->un.fmt7.wb1s, fp->un.fmt7.wb1a, fp->un.fmt7.wb1dpd0);
printk("wb 2 stat/addr/data: %04x %08lx %08lx\n",
fp->un.fmt7.wb2s, fp->un.fmt7.wb2a, fp->un.fmt7.wb2d);
printk("wb 3 stat/addr/data: %04x %08lx %08lx\n",
fp->un.fmt7.wb3s, fp->un.fmt7.wb3a, fp->un.fmt7.wb3d);
printk("push data: %08lx %08lx %08lx %08lx\n",
fp->un.fmt7.wb1dpd0, fp->un.fmt7.pd1, fp->un.fmt7.pd2,
fp->un.fmt7.pd3);
addr += sizeof(fp->un.fmt7);
break;
case 0x9:
printk("instr addr=%08lx\n", fp->un.fmt9.iaddr);
addr += sizeof(fp->un.fmt9);
break;
case 0xa:
printk("ssw=%04x isc=%04x isb=%04x daddr=%08lx dobuf=%08lx\n",
fp->un.fmta.ssw, fp->un.fmta.isc, fp->un.fmta.isb,
fp->un.fmta.daddr, fp->un.fmta.dobuf);
addr += sizeof(fp->un.fmta);
break;
case 0xb:
printk("ssw=%04x isc=%04x isb=%04x daddr=%08lx dobuf=%08lx\n",
fp->un.fmtb.ssw, fp->un.fmtb.isc, fp->un.fmtb.isb,
fp->un.fmtb.daddr, fp->un.fmtb.dobuf);
printk("baddr=%08lx dibuf=%08lx ver=%x\n",
fp->un.fmtb.baddr, fp->un.fmtb.dibuf, fp->un.fmtb.ver);
addr += sizeof(fp->un.fmtb);
break;
default:
printk("\n");
}
show_stack(NULL, (unsigned long *)addr);
printk("Code:");
set_fs(KERNEL_DS);
cp = (u16 *)regs->pc;
for (i = -8; i < 16; i++) {
if (get_user(c, cp + i) && i >= 0) {
printk(" Bad PC value.");
break;
}
printk(i ? " %04x" : " <%04x>", c);
}
set_fs(old_fs);
printk ("\n");
}
void show_stack(struct task_struct *task, unsigned long *stack)
{
unsigned long *p;
unsigned long *endstack;
int i;
if (!stack) {
if (task)
stack = (unsigned long *)task->thread.esp0;
else
stack = (unsigned long *)&stack;
}
endstack = (unsigned long *)(((unsigned long)stack + THREAD_SIZE - 1) & -THREAD_SIZE);
printk("Stack from %08lx:", (unsigned long)stack);
p = stack;
for (i = 0; i < kstack_depth_to_print; i++) {
if (p + 1 > endstack)
break;
if (i % 8 == 0)
printk("\n ");
printk(" %08lx", *p++);
}
printk("\n");
show_trace(stack);
}
/*
* The architecture-independent backtrace generator
*/
void dump_stack(void)
{
unsigned long stack;
show_trace(&stack);
}
EXPORT_SYMBOL(dump_stack);
void bad_super_trap (struct frame *fp)
{
console_verbose();
if (fp->ptregs.vector < 4 * ARRAY_SIZE(vec_names))
printk ("*** %s *** FORMAT=%X\n",
vec_names[(fp->ptregs.vector) >> 2],
fp->ptregs.format);
else
printk ("*** Exception %d *** FORMAT=%X\n",
(fp->ptregs.vector) >> 2,
fp->ptregs.format);
if (fp->ptregs.vector >> 2 == VEC_ADDRERR && CPU_IS_020_OR_030) {
unsigned short ssw = fp->un.fmtb.ssw;
printk ("SSW=%#06x ", ssw);
if (ssw & RC)
printk ("Pipe stage C instruction fault at %#010lx\n",
(fp->ptregs.format) == 0xA ?
fp->ptregs.pc + 2 : fp->un.fmtb.baddr - 2);
if (ssw & RB)
printk ("Pipe stage B instruction fault at %#010lx\n",
(fp->ptregs.format) == 0xA ?
fp->ptregs.pc + 4 : fp->un.fmtb.baddr);
if (ssw & DF)
printk ("Data %s fault at %#010lx in %s (pc=%#lx)\n",
ssw & RW ? "read" : "write",
fp->un.fmtb.daddr, space_names[ssw & DFC],
fp->ptregs.pc);
}
printk ("Current process id is %d\n", task_pid_nr(current));
die_if_kernel("BAD KERNEL TRAP", &fp->ptregs, 0);
}
asmlinkage void trap_c(struct frame *fp)
{
int sig;
siginfo_t info;
if (fp->ptregs.sr & PS_S) {
if (fp->ptregs.vector == VEC_TRACE << 2) {
/* traced a trapping instruction on a 68020/30,
* real exception will be executed afterwards.
*/
} else if (!handle_kernel_fault(&fp->ptregs))
bad_super_trap(fp);
return;
}
/* send the appropriate signal to the user program */
switch ((fp->ptregs.vector) >> 2) {
case VEC_ADDRERR:
info.si_code = BUS_ADRALN;
sig = SIGBUS;
break;
case VEC_ILLEGAL:
case VEC_LINE10:
case VEC_LINE11:
info.si_code = ILL_ILLOPC;
sig = SIGILL;
break;
case VEC_PRIV:
info.si_code = ILL_PRVOPC;
sig = SIGILL;
break;
case VEC_COPROC:
info.si_code = ILL_COPROC;
sig = SIGILL;
break;
case VEC_TRAP1:
case VEC_TRAP2:
case VEC_TRAP3:
case VEC_TRAP4:
case VEC_TRAP5:
case VEC_TRAP6:
case VEC_TRAP7:
case VEC_TRAP8:
case VEC_TRAP9:
case VEC_TRAP10:
case VEC_TRAP11:
case VEC_TRAP12:
case VEC_TRAP13:
case VEC_TRAP14:
info.si_code = ILL_ILLTRP;
sig = SIGILL;
break;
case VEC_FPBRUC:
case VEC_FPOE:
case VEC_FPNAN:
info.si_code = FPE_FLTINV;
sig = SIGFPE;
break;
case VEC_FPIR:
info.si_code = FPE_FLTRES;
sig = SIGFPE;
break;
case VEC_FPDIVZ:
info.si_code = FPE_FLTDIV;
sig = SIGFPE;
break;
case VEC_FPUNDER:
info.si_code = FPE_FLTUND;
sig = SIGFPE;
break;
case VEC_FPOVER:
info.si_code = FPE_FLTOVF;
sig = SIGFPE;
break;
case VEC_ZERODIV:
info.si_code = FPE_INTDIV;
sig = SIGFPE;
break;
case VEC_CHK:
case VEC_TRAP:
info.si_code = FPE_INTOVF;
sig = SIGFPE;
break;
case VEC_TRACE: /* ptrace single step */
info.si_code = TRAP_TRACE;
sig = SIGTRAP;
break;
case VEC_TRAP15: /* breakpoint */
info.si_code = TRAP_BRKPT;
sig = SIGTRAP;
break;
default:
info.si_code = ILL_ILLOPC;
sig = SIGILL;
break;
}
info.si_signo = sig;
info.si_errno = 0;
switch (fp->ptregs.format) {
default:
info.si_addr = (void *) fp->ptregs.pc;
break;
case 2:
info.si_addr = (void *) fp->un.fmt2.iaddr;
break;
case 7:
info.si_addr = (void *) fp->un.fmt7.effaddr;
break;
case 9:
info.si_addr = (void *) fp->un.fmt9.iaddr;
break;
case 10:
info.si_addr = (void *) fp->un.fmta.daddr;
break;
case 11:
info.si_addr = (void *) fp->un.fmtb.daddr;
break;
}
force_sig_info (sig, &info, current);
}
void die_if_kernel (char *str, struct pt_regs *fp, int nr)
{
if (!(fp->sr & PS_S))
return;
console_verbose();
printk("%s: %08x\n",str,nr);
show_registers(fp);
add_taint(TAINT_DIE);
do_exit(SIGSEGV);
}
/*
* This function is called if an error occur while accessing
* user-space from the fpsp040 code.
*/
asmlinkage void fpsp040_die(void)
{
do_exit(SIGSEGV);
}
#ifdef CONFIG_M68KFPU_EMU
asmlinkage void fpemu_signal(int signal, int code, void *addr)
{
siginfo_t info;
info.si_signo = signal;
info.si_errno = 0;
info.si_code = code;
info.si_addr = addr;
force_sig_info(signal, &info, current);
}
#endif
/*
* linux/arch/m68knommu/kernel/traps.c
*
* Copyright (C) 1993, 1994 by Hamish Macdonald
*
* 68040 fixes by Michael Rausch
* 68040 fixes by Martin Apel
* 68060 fixes by Roman Hodek
* 68060 fixes by Jesper Skov
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file COPYING in the main directory of this archive
* for more details.
*/
/*
* Sets up all exception vectors
*/
#include <linux/sched.h>
#include <linux/signal.h>
#include <linux/kernel.h>
#include <linux/mm.h>
#include <linux/module.h>
#include <linux/types.h>
#include <linux/user.h>
#include <linux/string.h>
#include <linux/linkage.h>
#include <linux/init.h>
#include <linux/ptrace.h>
#include <linux/kallsyms.h>
#include <asm/setup.h>
#include <asm/fpu.h>
#include <asm/system.h>
#include <asm/uaccess.h>
#include <asm/traps.h>
#include <asm/pgtable.h>
#include <asm/machdep.h>
#include <asm/siginfo.h>
static char const * const vec_names[] = {
"RESET SP", "RESET PC", "BUS ERROR", "ADDRESS ERROR",
"ILLEGAL INSTRUCTION", "ZERO DIVIDE", "CHK", "TRAPcc",
"PRIVILEGE VIOLATION", "TRACE", "LINE 1010", "LINE 1111",
"UNASSIGNED RESERVED 12", "COPROCESSOR PROTOCOL VIOLATION",
"FORMAT ERROR", "UNINITIALIZED INTERRUPT",
"UNASSIGNED RESERVED 16", "UNASSIGNED RESERVED 17",
"UNASSIGNED RESERVED 18", "UNASSIGNED RESERVED 19",
"UNASSIGNED RESERVED 20", "UNASSIGNED RESERVED 21",
"UNASSIGNED RESERVED 22", "UNASSIGNED RESERVED 23",
"SPURIOUS INTERRUPT", "LEVEL 1 INT", "LEVEL 2 INT", "LEVEL 3 INT",
"LEVEL 4 INT", "LEVEL 5 INT", "LEVEL 6 INT", "LEVEL 7 INT",
"SYSCALL", "TRAP #1", "TRAP #2", "TRAP #3",
"TRAP #4", "TRAP #5", "TRAP #6", "TRAP #7",
"TRAP #8", "TRAP #9", "TRAP #10", "TRAP #11",
"TRAP #12", "TRAP #13", "TRAP #14", "TRAP #15",
"FPCP BSUN", "FPCP INEXACT", "FPCP DIV BY 0", "FPCP UNDERFLOW",
"FPCP OPERAND ERROR", "FPCP OVERFLOW", "FPCP SNAN",
"FPCP UNSUPPORTED OPERATION",
"MMU CONFIGURATION ERROR"
};
void die_if_kernel(char *str, struct pt_regs *fp, int nr)
{
if (!(fp->sr & PS_S))
return;
console_verbose();
printk(KERN_EMERG "%s: %08x\n",str,nr);
printk(KERN_EMERG "PC: [<%08lx>]\nSR: %04x SP: %p a2: %08lx\n",
fp->pc, fp->sr, fp, fp->a2);
printk(KERN_EMERG "d0: %08lx d1: %08lx d2: %08lx d3: %08lx\n",
fp->d0, fp->d1, fp->d2, fp->d3);
printk(KERN_EMERG "d4: %08lx d5: %08lx a0: %08lx a1: %08lx\n",
fp->d4, fp->d5, fp->a0, fp->a1);
printk(KERN_EMERG "Process %s (pid: %d, stackpage=%08lx)\n",
current->comm, current->pid, PAGE_SIZE+(unsigned long)current);
show_stack(NULL, (unsigned long *)(fp + 1));
add_taint(TAINT_DIE);
do_exit(SIGSEGV);
}
asmlinkage void buserr_c(struct frame *fp)
{
/* Only set esp0 if coming from user mode */
if (user_mode(&fp->ptregs))
current->thread.esp0 = (unsigned long) fp;
#if defined(DEBUG)
printk (KERN_DEBUG "*** Bus Error *** Format is %x\n", fp->ptregs.format);
#endif
die_if_kernel("bad frame format",&fp->ptregs,0);
#if defined(DEBUG)
printk(KERN_DEBUG "Unknown SIGSEGV - 4\n");
#endif
force_sig(SIGSEGV, current);
}
static void print_this_address(unsigned long addr, int i)
{
#ifdef CONFIG_KALLSYMS
printk(KERN_EMERG " [%08lx] ", addr);
print_symbol(KERN_CONT "%s\n", addr);
#else
if (i % 5)
printk(KERN_CONT " [%08lx] ", addr);
else
printk(KERN_EMERG " [%08lx] ", addr);
i++;
#endif
}
int kstack_depth_to_print = 48;
static void __show_stack(struct task_struct *task, unsigned long *stack)
{
unsigned long *endstack, addr;
#ifdef CONFIG_FRAME_POINTER
unsigned long *last_stack;
#endif
int i;
if (!stack)
stack = (unsigned long *)task->thread.ksp;
addr = (unsigned long) stack;
endstack = (unsigned long *) PAGE_ALIGN(addr);
printk(KERN_EMERG "Stack from %08lx:", (unsigned long)stack);
for (i = 0; i < kstack_depth_to_print; i++) {
if (stack + 1 + i > endstack)
break;
if (i % 8 == 0)
printk(KERN_EMERG " ");
printk(KERN_CONT " %08lx", *(stack + i));
}
printk("\n");
i = 0;
#ifdef CONFIG_FRAME_POINTER
printk(KERN_EMERG "Call Trace:\n");
last_stack = stack - 1;
while (stack <= endstack && stack > last_stack) {
addr = *(stack + 1);
print_this_address(addr, i);
i++;
last_stack = stack;
stack = (unsigned long *)*stack;
}
printk("\n");
#else
printk(KERN_EMERG "Call Trace with CONFIG_FRAME_POINTER disabled:\n");
while (stack <= endstack) {
addr = *stack++;
/*
* If the address is either in the text segment of the kernel,
* or in a region which is occupied by a module then it *may*
* be the address of a calling routine; if so, print it so that
* someone tracing down the cause of the crash will be able to
* figure out the call path that was taken.
*/
if (__kernel_text_address(addr)) {
print_this_address(addr, i);
i++;
}
}
printk(KERN_CONT "\n");
#endif
}
void bad_super_trap(struct frame *fp)
{
int vector = (fp->ptregs.vector >> 2) & 0xff;
console_verbose();
if (vector < ARRAY_SIZE(vec_names))
printk (KERN_WARNING "*** %s *** FORMAT=%X\n",
vec_names[vector],
fp->ptregs.format);
else
printk (KERN_WARNING "*** Exception %d *** FORMAT=%X\n",
vector,
fp->ptregs.format);
printk (KERN_WARNING "Current process id is %d\n", current->pid);
die_if_kernel("BAD KERNEL TRAP", &fp->ptregs, 0);
}
asmlinkage void trap_c(struct frame *fp)
{
int sig;
int vector = (fp->ptregs.vector >> 2) & 0xff;
siginfo_t info;
if (fp->ptregs.sr & PS_S) {
if (vector == VEC_TRACE) {
/* traced a trapping instruction */
} else
bad_super_trap(fp);
return;
}
/* send the appropriate signal to the user program */
switch (vector) {
case VEC_ADDRERR:
info.si_code = BUS_ADRALN;
sig = SIGBUS;
break;
case VEC_ILLEGAL:
case VEC_LINE10:
case VEC_LINE11:
info.si_code = ILL_ILLOPC;
sig = SIGILL;
break;
case VEC_PRIV:
info.si_code = ILL_PRVOPC;
sig = SIGILL;
break;
case VEC_COPROC:
info.si_code = ILL_COPROC;
sig = SIGILL;
break;
case VEC_TRAP1: /* gdbserver breakpoint */
fp->ptregs.pc -= 2;
info.si_code = TRAP_TRACE;
sig = SIGTRAP;
break;
case VEC_TRAP2:
case VEC_TRAP3:
case VEC_TRAP4:
case VEC_TRAP5:
case VEC_TRAP6:
case VEC_TRAP7:
case VEC_TRAP8:
case VEC_TRAP9:
case VEC_TRAP10:
case VEC_TRAP11:
case VEC_TRAP12:
case VEC_TRAP13:
case VEC_TRAP14:
info.si_code = ILL_ILLTRP;
sig = SIGILL;
break;
case VEC_FPBRUC:
case VEC_FPOE:
case VEC_FPNAN:
info.si_code = FPE_FLTINV;
sig = SIGFPE;
break;
case VEC_FPIR:
info.si_code = FPE_FLTRES;
sig = SIGFPE;
break;
case VEC_FPDIVZ:
info.si_code = FPE_FLTDIV;
sig = SIGFPE;
break;
case VEC_FPUNDER:
info.si_code = FPE_FLTUND;
sig = SIGFPE;
break;
case VEC_FPOVER:
info.si_code = FPE_FLTOVF;
sig = SIGFPE;
break;
case VEC_ZERODIV:
info.si_code = FPE_INTDIV;
sig = SIGFPE;
break;
case VEC_CHK:
case VEC_TRAP:
info.si_code = FPE_INTOVF;
sig = SIGFPE;
break;
case VEC_TRACE: /* ptrace single step */
info.si_code = TRAP_TRACE;
sig = SIGTRAP;
break;
case VEC_TRAP15: /* breakpoint */
info.si_code = TRAP_BRKPT;
sig = SIGTRAP;
break;
default:
info.si_code = ILL_ILLOPC;
sig = SIGILL;
break;
}
info.si_signo = sig;
info.si_errno = 0;
switch (fp->ptregs.format) {
default:
info.si_addr = (void *) fp->ptregs.pc;
break;
case 2:
info.si_addr = (void *) fp->un.fmt2.iaddr;
break;
case 7:
info.si_addr = (void *) fp->un.fmt7.effaddr;
break;
case 9:
info.si_addr = (void *) fp->un.fmt9.iaddr;
break;
case 10:
info.si_addr = (void *) fp->un.fmta.daddr;
break;
case 11:
info.si_addr = (void *) fp->un.fmtb.daddr;
break;
}
force_sig_info (sig, &info, current);
}
asmlinkage void set_esp0(unsigned long ssp)
{
current->thread.esp0 = ssp;
}
/*
* The architecture-independent backtrace generator
*/
void dump_stack(void)
{
/*
* We need frame pointers for this little trick, which works as follows:
*
* +------------+ 0x00
* | Next SP | -> 0x0c
* +------------+ 0x04
* | Caller |
* +------------+ 0x08
* | Local vars | -> our stack var
* +------------+ 0x0c
* | Next SP | -> 0x18, that is what we pass to show_stack()
* +------------+ 0x10
* | Caller |
* +------------+ 0x14
* | Local vars |
* +------------+ 0x18
* | ... |
* +------------+
*/
unsigned long *stack;
stack = (unsigned long *)&stack;
stack++;
__show_stack(current, stack);
}
EXPORT_SYMBOL(dump_stack);
void show_stack(struct task_struct *task, unsigned long *stack)
{
if (!stack && !task)
dump_stack();
else
__show_stack(task, stack);
}
/*
* vectors.c
*
* Copyright (C) 1993, 1994 by Hamish Macdonald
*
* 68040 fixes by Michael Rausch
* 68040 fixes by Martin Apel
* 68040 fixes and writeback by Richard Zidlicky
* 68060 fixes by Roman Hodek
* 68060 fixes by Jesper Skov
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file COPYING in the main directory of this archive
* for more details.
*/
/*
* Sets up all exception vectors
*/
#include <linux/sched.h>
#include <linux/kernel.h>
#include <linux/linkage.h>
#include <linux/init.h>
#include <linux/kallsyms.h>
#include <asm/setup.h>
#include <asm/fpu.h>
#include <asm/system.h>
#include <asm/traps.h>
/* assembler routines */
asmlinkage void system_call(void);
asmlinkage void buserr(void);
asmlinkage void trap(void);
asmlinkage void nmihandler(void);
#ifdef CONFIG_M68KFPU_EMU
asmlinkage void fpu_emu(void);
#endif
e_vector vectors[256];
/* nmi handler for the Amiga */
asm(".text\n"
__ALIGN_STR "\n"
"nmihandler: rte");
/*
* this must be called very early as the kernel might
* use some instruction that are emulated on the 060
* and so we're prepared for early probe attempts (e.g. nf_init).
*/
void __init base_trap_init(void)
{
if (MACH_IS_SUN3X) {
extern e_vector *sun3x_prom_vbr;
__asm__ volatile ("movec %%vbr, %0" : "=r" (sun3x_prom_vbr));
}
/* setup the exception vector table */
__asm__ volatile ("movec %0,%%vbr" : : "r" ((void*)vectors));
if (CPU_IS_060) {
/* set up ISP entry points */
asmlinkage void unimp_vec(void) asm ("_060_isp_unimp");
vectors[VEC_UNIMPII] = unimp_vec;
}
vectors[VEC_BUSERR] = buserr;
vectors[VEC_ILLEGAL] = trap;
vectors[VEC_SYS] = system_call;
}
void __init trap_init (void)
{
int i;
for (i = VEC_SPUR; i <= VEC_INT7; i++)
vectors[i] = bad_inthandler;
for (i = 0; i < VEC_USER; i++)
if (!vectors[i])
vectors[i] = trap;
for (i = VEC_USER; i < 256; i++)
vectors[i] = bad_inthandler;
#ifdef CONFIG_M68KFPU_EMU
if (FPU_IS_EMU)
vectors[VEC_LINE11] = fpu_emu;
#endif
if (CPU_IS_040 && !FPU_IS_EMU) {
/* set up FPSP entry points */
asmlinkage void dz_vec(void) asm ("dz");
asmlinkage void inex_vec(void) asm ("inex");
asmlinkage void ovfl_vec(void) asm ("ovfl");
asmlinkage void unfl_vec(void) asm ("unfl");
asmlinkage void snan_vec(void) asm ("snan");
asmlinkage void operr_vec(void) asm ("operr");
asmlinkage void bsun_vec(void) asm ("bsun");
asmlinkage void fline_vec(void) asm ("fline");
asmlinkage void unsupp_vec(void) asm ("unsupp");
vectors[VEC_FPDIVZ] = dz_vec;
vectors[VEC_FPIR] = inex_vec;
vectors[VEC_FPOVER] = ovfl_vec;
vectors[VEC_FPUNDER] = unfl_vec;
vectors[VEC_FPNAN] = snan_vec;
vectors[VEC_FPOE] = operr_vec;
vectors[VEC_FPBRUC] = bsun_vec;
vectors[VEC_LINE11] = fline_vec;
vectors[VEC_FPUNSUP] = unsupp_vec;
}
if (CPU_IS_060 && !FPU_IS_EMU) {
/* set up IFPSP entry points */
asmlinkage void snan_vec6(void) asm ("_060_fpsp_snan");
asmlinkage void operr_vec6(void) asm ("_060_fpsp_operr");
asmlinkage void ovfl_vec6(void) asm ("_060_fpsp_ovfl");
asmlinkage void unfl_vec6(void) asm ("_060_fpsp_unfl");
asmlinkage void dz_vec6(void) asm ("_060_fpsp_dz");
asmlinkage void inex_vec6(void) asm ("_060_fpsp_inex");
asmlinkage void fline_vec6(void) asm ("_060_fpsp_fline");
asmlinkage void unsupp_vec6(void) asm ("_060_fpsp_unsupp");
asmlinkage void effadd_vec6(void) asm ("_060_fpsp_effadd");
vectors[VEC_FPNAN] = snan_vec6;
vectors[VEC_FPOE] = operr_vec6;
vectors[VEC_FPOVER] = ovfl_vec6;
vectors[VEC_FPUNDER] = unfl_vec6;
vectors[VEC_FPDIVZ] = dz_vec6;
vectors[VEC_FPIR] = inex_vec6;
vectors[VEC_LINE11] = fline_vec6;
vectors[VEC_FPUNSUP] = unsupp_vec6;
vectors[VEC_UNIMPEA] = effadd_vec6;
}
/* if running on an amiga, make the NMI interrupt do nothing */
if (MACH_IS_AMIGA) {
vectors[VEC_INT7] = nmihandler;
}
}
......@@ -22,6 +22,15 @@ void *memcpy(void *to, const void *from, size_t n)
from = cfrom;
n--;
}
#if defined(CONFIG_M68000)
if ((long)from & 1) {
char *cto = to;
const char *cfrom = from;
for (; n; n--)
*cto++ = *cfrom++;
return xto;
}
#endif
if (n > 2 && (long)to & 2) {
short *sto = to;
const short *sfrom = from;
......
......@@ -32,6 +32,7 @@
#include <linux/gfp.h>
#include <asm/setup.h>
#include <asm/sections.h>
#include <asm/segment.h>
#include <asm/page.h>
#include <asm/pgtable.h>
......@@ -44,9 +45,6 @@
*/
void *empty_zero_page;
extern unsigned long memory_start;
extern unsigned long memory_end;
/*
* paging_init() continues the virtual memory environment setup which
* was begun by the code in arch/head.S.
......@@ -78,8 +76,6 @@ void __init mem_init(void)
{
int codek = 0, datak = 0, initk = 0;
unsigned long tmp;
extern char _etext, _stext, _sdata, _ebss, __init_begin, __init_end;
extern unsigned int _ramend, _rambase;
unsigned long len = _ramend - _rambase;
unsigned long start_mem = memory_start; /* DAVIDM - these must start at end of kernel */
unsigned long end_mem = memory_end; /* DAVIDM - this must not include kernel stack at top */
......@@ -95,9 +91,9 @@ void __init mem_init(void)
/* this will put all memory onto the freelists */
totalram_pages = free_all_bootmem();
codek = (&_etext - &_stext) >> 10;
datak = (&_ebss - &_sdata) >> 10;
initk = (&__init_begin - &__init_end) >> 10;
codek = (_etext - _stext) >> 10;
datak = (_ebss - _sdata) >> 10;
initk = (__init_begin - __init_end) >> 10;
tmp = nr_free_pages() << PAGE_SHIFT;
printk(KERN_INFO "Memory available: %luk/%luk RAM, (%dk kernel code, %dk data)\n",
......@@ -129,22 +125,21 @@ void free_initmem(void)
{
#ifdef CONFIG_RAMKERNEL
unsigned long addr;
extern char __init_begin, __init_end;
/*
* The following code should be cool even if these sections
* are not page aligned.
*/
addr = PAGE_ALIGN((unsigned long)(&__init_begin));
addr = PAGE_ALIGN((unsigned long) __init_begin);
/* next to check that the page we free is not a partial page */
for (; addr + PAGE_SIZE < (unsigned long)(&__init_end); addr +=PAGE_SIZE) {
for (; addr + PAGE_SIZE < ((unsigned long) __init_end); addr += PAGE_SIZE) {
ClearPageReserved(virt_to_page(addr));
init_page_count(virt_to_page(addr));
free_page(addr);
totalram_pages++;
}
pr_notice("Freeing unused kernel memory: %luk freed (0x%x - 0x%x)\n",
(addr - PAGE_ALIGN((long) &__init_begin)) >> 10,
(int)(PAGE_ALIGN((unsigned long)(&__init_begin))),
(addr - PAGE_ALIGN((unsigned long) __init_begin)) >> 10,
(int)(PAGE_ALIGN((unsigned long) __init_begin)),
(int)(addr - PAGE_SIZE));
#endif
}
......
......@@ -91,9 +91,9 @@ static struct resource m520x_qspi_resources[] = {
},
};
#define MCFQSPI_CS0 62
#define MCFQSPI_CS1 63
#define MCFQSPI_CS2 44
#define MCFQSPI_CS0 46
#define MCFQSPI_CS1 47
#define MCFQSPI_CS2 27
static int m520x_cs_setup(struct mcfqspi_cs_control *cs_control)
{
......
......@@ -36,42 +36,6 @@ static struct mcf_gpio_chip mcf_gpio_chips[] = {
.podr = (void __iomem *) MCFEPORT_EPDR,
.ppdr = (void __iomem *) MCFEPORT_EPPDR,
},
{
.gpio_chip = {
.label = "BUSCTL",
.request = mcf_gpio_request,
.free = mcf_gpio_free,
.direction_input = mcf_gpio_direction_input,
.direction_output = mcf_gpio_direction_output,
.get = mcf_gpio_get_value,
.set = mcf_gpio_set_value_fast,
.base = 8,
.ngpio = 4,
},
.pddr = (void __iomem *) MCFGPIO_PDDR_BUSCTL,
.podr = (void __iomem *) MCFGPIO_PODR_BUSCTL,
.ppdr = (void __iomem *) MCFGPIO_PPDSDR_BUSCTL,
.setr = (void __iomem *) MCFGPIO_PPDSDR_BUSCTL,
.clrr = (void __iomem *) MCFGPIO_PCLRR_BUSCTL,
},
{
.gpio_chip = {
.label = "BE",
.request = mcf_gpio_request,
.free = mcf_gpio_free,
.direction_input = mcf_gpio_direction_input,
.direction_output = mcf_gpio_direction_output,
.get = mcf_gpio_get_value,
.set = mcf_gpio_set_value_fast,
.base = 16,
.ngpio = 4,
},
.pddr = (void __iomem *) MCFGPIO_PDDR_BE,
.podr = (void __iomem *) MCFGPIO_PODR_BE,
.ppdr = (void __iomem *) MCFGPIO_PPDSDR_BE,
.setr = (void __iomem *) MCFGPIO_PPDSDR_BE,
.clrr = (void __iomem *) MCFGPIO_PCLRR_BE,
},
{
.gpio_chip = {
.label = "CS",
......@@ -81,7 +45,7 @@ static struct mcf_gpio_chip mcf_gpio_chips[] = {
.direction_output = mcf_gpio_direction_output,
.get = mcf_gpio_get_value,
.set = mcf_gpio_set_value_fast,
.base = 25,
.base = 9,
.ngpio = 3,
},
.pddr = (void __iomem *) MCFGPIO_PDDR_CS,
......@@ -99,7 +63,7 @@ static struct mcf_gpio_chip mcf_gpio_chips[] = {
.direction_output = mcf_gpio_direction_output,
.get = mcf_gpio_get_value,
.set = mcf_gpio_set_value_fast,
.base = 32,
.base = 16,
.ngpio = 4,
},
.pddr = (void __iomem *) MCFGPIO_PDDR_FECI2C,
......@@ -117,7 +81,7 @@ static struct mcf_gpio_chip mcf_gpio_chips[] = {
.direction_output = mcf_gpio_direction_output,
.get = mcf_gpio_get_value,
.set = mcf_gpio_set_value_fast,
.base = 40,
.base = 24,
.ngpio = 4,
},
.pddr = (void __iomem *) MCFGPIO_PDDR_QSPI,
......@@ -135,7 +99,7 @@ static struct mcf_gpio_chip mcf_gpio_chips[] = {
.direction_output = mcf_gpio_direction_output,
.get = mcf_gpio_get_value,
.set = mcf_gpio_set_value_fast,
.base = 48,
.base = 32,
.ngpio = 4,
},
.pddr = (void __iomem *) MCFGPIO_PDDR_TIMER,
......@@ -153,7 +117,7 @@ static struct mcf_gpio_chip mcf_gpio_chips[] = {
.direction_output = mcf_gpio_direction_output,
.get = mcf_gpio_get_value,
.set = mcf_gpio_set_value_fast,
.base = 56,
.base = 40,
.ngpio = 8,
},
.pddr = (void __iomem *) MCFGPIO_PDDR_UART,
......@@ -171,7 +135,7 @@ static struct mcf_gpio_chip mcf_gpio_chips[] = {
.direction_output = mcf_gpio_direction_output,
.get = mcf_gpio_get_value,
.set = mcf_gpio_set_value_fast,
.base = 64,
.base = 48,
.ngpio = 8,
},
.pddr = (void __iomem *) MCFGPIO_PDDR_FECH,
......@@ -189,7 +153,7 @@ static struct mcf_gpio_chip mcf_gpio_chips[] = {
.direction_output = mcf_gpio_direction_output,
.get = mcf_gpio_get_value,
.set = mcf_gpio_set_value_fast,
.base = 72,
.base = 56,
.ngpio = 8,
},
.pddr = (void __iomem *) MCFGPIO_PDDR_FECL,
......
......@@ -2,7 +2,10 @@
# Makefile for arch/m68knommu/platform/68328.
#
head-y = head-$(MODEL).o
model-y := ram
model-$(CONFIG_ROMKERNEL) := rom
head-y = head-$(model-y).o
head-$(CONFIG_PILOT) = head-pilot.o
head-$(CONFIG_DRAGEN2) = head-de2.o
......
......@@ -67,7 +67,7 @@ ret_from_signal:
jra ret_from_exception
ENTRY(system_call)
SAVE_ALL
SAVE_ALL_SYS
/* save top of frame*/
pea %sp@
......@@ -129,7 +129,7 @@ Lsignal_return:
* This is the main interrupt handler, responsible for calling process_int()
*/
inthandler1:
SAVE_ALL
SAVE_ALL_INT
movew %sp@(PT_OFF_FORMATVEC), %d0
and #0x3ff, %d0
......@@ -140,7 +140,7 @@ inthandler1:
bra ret_from_interrupt
inthandler2:
SAVE_ALL
SAVE_ALL_INT
movew %sp@(PT_OFF_FORMATVEC), %d0
and #0x3ff, %d0
......@@ -151,7 +151,7 @@ inthandler2:
bra ret_from_interrupt
inthandler3:
SAVE_ALL
SAVE_ALL_INT
movew %sp@(PT_OFF_FORMATVEC), %d0
and #0x3ff, %d0
......@@ -162,7 +162,7 @@ inthandler3:
bra ret_from_interrupt
inthandler4:
SAVE_ALL
SAVE_ALL_INT
movew %sp@(PT_OFF_FORMATVEC), %d0
and #0x3ff, %d0
......@@ -173,7 +173,7 @@ inthandler4:
bra ret_from_interrupt
inthandler5:
SAVE_ALL
SAVE_ALL_INT
movew %sp@(PT_OFF_FORMATVEC), %d0
and #0x3ff, %d0
......@@ -184,7 +184,7 @@ inthandler5:
bra ret_from_interrupt
inthandler6:
SAVE_ALL
SAVE_ALL_INT
movew %sp@(PT_OFF_FORMATVEC), %d0
and #0x3ff, %d0
......@@ -195,7 +195,7 @@ inthandler6:
bra ret_from_interrupt
inthandler7:
SAVE_ALL
SAVE_ALL_INT
movew %sp@(PT_OFF_FORMATVEC), %d0
and #0x3ff, %d0
......@@ -206,7 +206,7 @@ inthandler7:
bra ret_from_interrupt
inthandler:
SAVE_ALL
SAVE_ALL_INT
movew %sp@(PT_OFF_FORMATVEC), %d0
and #0x3ff, %d0
......
#
# Makefile for arch/m68knommu/platform/68360.
#
model-y := ram
model-$(CONFIG_ROMKERNEL) := rom
obj-y := config.o commproc.o entry.o ints.o
extra-y := head.o
$(obj)/head.o: $(obj)/head-$(MODEL).o
ln -sf head-$(MODEL).o $(obj)/head.o
$(obj)/head.o: $(obj)/head-$(model-y).o
ln -sf head-$(model-y).o $(obj)/head.o
......@@ -63,7 +63,7 @@ ret_from_signal:
jra ret_from_exception
ENTRY(system_call)
SAVE_ALL
SAVE_ALL_SYS
/* save top of frame*/
pea %sp@
......@@ -125,7 +125,7 @@ Lsignal_return:
* This is the main interrupt handler, responsible for calling do_IRQ()
*/
inthandler:
SAVE_ALL
SAVE_ALL_INT
movew %sp@(PT_OFF_FORMATVEC), %d0
and.l #0x3ff, %d0
lsr.l #0x02, %d0
......
......@@ -61,7 +61,7 @@ enosys:
bra 1f
ENTRY(system_call)
SAVE_ALL
SAVE_ALL_SYS
move #0x2000,%sr /* enable intrs again */
cmpl #NR_syscalls,%d0
......@@ -165,9 +165,7 @@ Lsignal_return:
* sources). Calls up to high level code to do all the work.
*/
ENTRY(inthandler)
SAVE_ALL
moveq #-1,%d0
movel %d0,%sp@(PT_OFF_ORIG_D0)
SAVE_ALL_INT
movew %sp@(PT_OFF_FORMATVEC),%d0 /* put exception # in d0 */
andl #0x03fc,%d0 /* mask out vector only */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment