···11config M68K22 bool33 default y44- select HAVE_AOUT54 select HAVE_IDE66- select GENERIC_ATOMIC6477-88-config MMU99- bool1010- default y55+ select HAVE_AOUT if MMU66+ select GENERIC_ATOMIC64 if MMU77+ select HAVE_GENERIC_HARDIRQS if !MMU88+ select GENERIC_HARDIRQS_NO_DEPRECATED if !MMU1191210config RWSEM_GENERIC_SPINLOCK1311 bool···3234 bool3335 default y34363535-config GENERIC_IOMAP3636- bool3737- default y3838-3939-config ARCH_MAY_HAVE_PC_FDC4040- bool4141- depends on BROKEN && (Q40 || SUN3X)4242- default y4343-4437config NO_IOPORT4538 def_bool y46394740config NO_DMA4848- def_bool SUN34141+ def_bool (MMU && SUN3) || (!MMU && !COLDFIRE)49424343+config ZONE_DMA4444+ bool4545+ default y5046config HZ5147 int4848+ default 1000 if CLEOPATRA5249 default 1005353-5454-config ARCH_USES_GETTIMEOFFSET5555- def_bool y56505751source "init/Kconfig"58525953source "kernel/Kconfig.freezer"60545555+config MMU5656+ bool "MMU-based Paged Memory Management Support"5757+ default y5858+ help5959+ Select if you want MMU-based virtualised addressing space6060+ support by paged memory management. If unsure, say 'Y'.6161+6162menu "Platform dependent setup"62636363-config EISA6464- bool6565- ---help---6666- The Extended Industry Standard Architecture (EISA) bus was6767- developed as an open alternative to the IBM MicroChannel bus.6868-6969- The EISA bus provided some of the features of the IBM MicroChannel7070- bus while maintaining backward compatibility with cards made for7171- the older ISA bus. The EISA bus saw limited use between 1988 and7272- 1995 when it was made obsolete by the PCI bus.7373-7474- Say Y here if you are building a kernel for an EISA-based machine.7575-7676- Otherwise, say N.7777-7878-config MCA7979- bool8080- help8181- MicroChannel Architecture is found in some IBM PS/2 machines and8282- laptops. It is a bus system similar to PCI or ISA. See8383- <file:Documentation/mca.txt> (and especially the web page given8484- there) before attempting to build an MCA bus kernel.8585-8686-config PCMCIA8787- tristate8888- ---help---8989- Say Y here if you want to attach PCMCIA- or PC-cards to your Linux9090- computer. These are credit-card size devices such as network cards,9191- modems or hard drives often used with laptops computers. There are9292- actually two varieties of these cards: the older 16 bit PCMCIA cards9393- and the newer 32 bit CardBus cards. If you want to use CardBus9494- cards, you need to say Y here and also to "CardBus support" below.9595-9696- To use your PC-cards, you will need supporting software from David9797- Hinds' pcmcia-cs package (see the file <file:Documentation/Changes>9898- for location). Please also read the PCMCIA-HOWTO, available from9999- <http://www.tldp.org/docs.html#howto>.100100-101101- To compile this driver as modules, choose M here: the102102- modules will be called pcmcia_core and ds.103103-104104-config AMIGA105105- bool "Amiga support"106106- select MMU_MOTOROLA if MMU107107- help108108- This option enables support for the Amiga series of computers. If109109- you plan to use this kernel on an Amiga, say Y here and browse the110110- material available in <file:Documentation/m68k>; otherwise say N.111111-112112-config ATARI113113- bool "Atari support"114114- select MMU_MOTOROLA if MMU115115- help116116- This option enables support for the 68000-based Atari series of117117- computers (including the TT, Falcon and Medusa). If you plan to use118118- this kernel on an Atari, say Y here and browse the material119119- available in <file:Documentation/m68k>; otherwise say N.120120-121121-config MAC122122- bool "Macintosh support"123123- select MMU_MOTOROLA if MMU124124- help125125- This option enables support for the Apple Macintosh series of126126- computers (yes, there is experimental support now, at least for part127127- of the series).128128-129129- Say N unless you're willing to code the remaining necessary support.130130- ;)131131-132132-config NUBUS133133- bool134134- depends on MAC135135- default y136136-137137-config M68K_L2_CACHE138138- bool139139- depends on MAC140140- default y141141-142142-config APOLLO143143- bool "Apollo support"144144- select MMU_MOTOROLA if MMU145145- help146146- Say Y here if you want to run Linux on an MC680x0-based Apollo147147- Domain workstation such as the DN3500.148148-149149-config VME150150- bool "VME (Motorola and BVM) support"151151- select MMU_MOTOROLA if MMU152152- help153153- Say Y here if you want to build a kernel for a 680x0 based VME154154- board. Boards currently supported include Motorola boards MVME147,155155- MVME162, MVME166, MVME167, MVME172, and MVME177. BVME4000 and156156- BVME6000 boards from BVM Ltd are also supported.157157-158158-config MVME147159159- bool "MVME147 support"160160- depends on VME161161- help162162- Say Y to include support for early Motorola VME boards. This will163163- build a kernel which can run on MVME147 single-board computers. If164164- you select this option you will have to select the appropriate165165- drivers for SCSI, Ethernet and serial ports later on.166166-167167-config MVME16x168168- bool "MVME162, 166 and 167 support"169169- depends on VME170170- help171171- Say Y to include support for Motorola VME boards. This will build a172172- kernel which can run on MVME162, MVME166, MVME167, MVME172, and173173- MVME177 boards. If you select this option you will have to select174174- the appropriate drivers for SCSI, Ethernet and serial ports later175175- on.176176-177177-config BVME6000178178- bool "BVME4000 and BVME6000 support"179179- depends on VME180180- help181181- Say Y to include support for VME boards from BVM Ltd. This will182182- build a kernel which can run on BVME4000 and BVME6000 boards. If183183- you select this option you will have to select the appropriate184184- drivers for SCSI, Ethernet and serial ports later on.185185-186186-config HP300187187- bool "HP9000/300 and HP9000/400 support"188188- select MMU_MOTOROLA if MMU189189- help190190- This option enables support for the HP9000/300 and HP9000/400 series191191- of workstations. Support for these machines is still somewhat192192- experimental. If you plan to try to use the kernel on such a machine193193- say Y here.194194- Everybody else says N.195195-196196-config DIO197197- bool "DIO bus support"198198- depends on HP300199199- default y200200- help201201- Say Y here to enable support for the "DIO" expansion bus used in202202- HP300 machines. If you are using such a system you almost certainly203203- want this.204204-205205-config SUN3X206206- bool "Sun3x support"207207- select MMU_MOTOROLA if MMU208208- select M68030209209- help210210- This option enables support for the Sun 3x series of workstations.211211- Be warned that this support is very experimental.212212- Note that Sun 3x kernels are not compatible with Sun 3 hardware.213213- General Linux information on the Sun 3x series (now discontinued)214214- is at <http://www.angelfire.com/ca2/tech68k/sun3.html>.215215-216216- If you don't want to compile a kernel for a Sun 3x, say N.217217-218218-config Q40219219- bool "Q40/Q60 support"220220- select MMU_MOTOROLA if MMU221221- help222222- The Q40 is a Motorola 68040-based successor to the Sinclair QL223223- manufactured in Germany. There is an official Q40 home page at224224- <http://www.q40.de/>. This option enables support for the Q40 and225225- Q60. Select your CPU below. For 68LC060 don't forget to enable FPU226226- emulation.227227-228228-config SUN3229229- bool "Sun3 support"230230- depends on !MMU_MOTOROLA231231- select MMU_SUN3 if MMU232232- select M68020233233- help234234- This option enables support for the Sun 3 series of workstations235235- (3/50, 3/60, 3/1xx, 3/2xx systems). Enabling this option requires236236- that all other hardware types must be disabled, as Sun 3 kernels237237- are incompatible with all other m68k targets (including Sun 3x!).238238-239239- If you don't want to compile a kernel exclusively for a Sun 3, say N.240240-241241-config NATFEAT242242- bool "ARAnyM emulator support"243243- depends on ATARI244244- help245245- This option enables support for ARAnyM native features, such as246246- access to a disk image as /dev/hda.247247-248248-config NFBLOCK249249- tristate "NatFeat block device support"250250- depends on BLOCK && NATFEAT251251- help252252- Say Y to include support for the ARAnyM NatFeat block device253253- which allows direct access to the hard drives without using254254- the hardware emulation.255255-256256-config NFCON257257- tristate "NatFeat console driver"258258- depends on NATFEAT259259- help260260- Say Y to include support for the ARAnyM NatFeat console driver261261- which allows the console output to be redirected to the stderr262262- output of ARAnyM.263263-264264-config NFETH265265- tristate "NatFeat Ethernet support"266266- depends on NET_ETHERNET && NATFEAT267267- help268268- Say Y to include support for the ARAnyM NatFeat network device269269- which will emulate a regular ethernet device while presenting an270270- ethertap device to the host system.271271-272272-comment "Processor type"273273-274274-config M68020275275- bool "68020 support"276276- help277277- If you anticipate running this kernel on a computer with a MC68020278278- processor, say Y. Otherwise, say N. Note that the 68020 requires a279279- 68851 MMU (Memory Management Unit) to run Linux/m68k, except on the280280- Sun 3, which provides its own version.281281-282282-config M68030283283- bool "68030 support"284284- depends on !MMU_SUN3285285- help286286- If you anticipate running this kernel on a computer with a MC68030287287- processor, say Y. Otherwise, say N. Note that a MC68EC030 will not288288- work, as it does not include an MMU (Memory Management Unit).289289-290290-config M68040291291- bool "68040 support"292292- depends on !MMU_SUN3293293- help294294- If you anticipate running this kernel on a computer with a MC68LC040295295- or MC68040 processor, say Y. Otherwise, say N. Note that an296296- MC68EC040 will not work, as it does not include an MMU (Memory297297- Management Unit).298298-299299-config M68060300300- bool "68060 support"301301- depends on !MMU_SUN3302302- help303303- If you anticipate running this kernel on a computer with a MC68060304304- processor, say Y. Otherwise, say N.305305-306306-config MMU_MOTOROLA307307- bool308308-309309-config MMU_SUN3310310- bool311311- depends on MMU && !MMU_MOTOROLA312312-313313-config M68KFPU_EMU314314- bool "Math emulation support (EXPERIMENTAL)"315315- depends on EXPERIMENTAL316316- help317317- At some point in the future, this will cause floating-point math318318- instructions to be emulated by the kernel on machines that lack a319319- floating-point math coprocessor. Thrill-seekers and chronically320320- sleep-deprived psychotic hacker types can say Y now, everyone else321321- should probably wait a while.322322-323323-config M68KFPU_EMU_EXTRAPREC324324- bool "Math emulation extra precision"325325- depends on M68KFPU_EMU326326- help327327- The fpu uses normally a few bit more during calculations for328328- correct rounding, the emulator can (often) do the same but this329329- extra calculation can cost quite some time, so you can disable330330- it here. The emulator will then "only" calculate with a 64 bit331331- mantissa and round slightly incorrect, what is more than enough332332- for normal usage.333333-334334-config M68KFPU_EMU_ONLY335335- bool "Math emulation only kernel"336336- depends on M68KFPU_EMU337337- help338338- This option prevents any floating-point instructions from being339339- compiled into the kernel, thereby the kernel doesn't save any340340- floating point context anymore during task switches, so this341341- kernel will only be usable on machines without a floating-point342342- math coprocessor. This makes the kernel a bit faster as no tests343343- needs to be executed whether a floating-point instruction in the344344- kernel should be executed or not.345345-346346-config ADVANCED347347- bool "Advanced configuration options"348348- ---help---349349- This gives you access to some advanced options for the CPU. The350350- defaults should be fine for most users, but these options may make351351- it possible for you to improve performance somewhat if you know what352352- you are doing.353353-354354- Note that the answer to this question won't directly affect the355355- kernel: saying N will just cause the configurator to skip all356356- the questions about these options.357357-358358- Most users should say N to this question.359359-360360-config RMW_INSNS361361- bool "Use read-modify-write instructions"362362- depends on ADVANCED363363- ---help---364364- This allows to use certain instructions that work with indivisible365365- read-modify-write bus cycles. While this is faster than the366366- workaround of disabling interrupts, it can conflict with DMA367367- ( = direct memory access) on many Amiga systems, and it is also said368368- to destabilize other machines. It is very likely that this will369369- cause serious problems on any Amiga or Atari Medusa if set. The only370370- configuration where it should work are 68030-based Ataris, where it371371- apparently improves performance. But you've been warned! Unless you372372- really know what you are doing, say N. Try Y only if you're quite373373- adventurous.374374-375375-config SINGLE_MEMORY_CHUNK376376- bool "Use one physical chunk of memory only" if ADVANCED && !SUN3377377- default y if SUN3378378- select NEED_MULTIPLE_NODES379379- help380380- Ignore all but the first contiguous chunk of physical memory for VM381381- purposes. This will save a few bytes kernel size and may speed up382382- some operations. Say N if not sure.383383-384384-config 060_WRITETHROUGH385385- bool "Use write-through caching for 68060 supervisor accesses"386386- depends on ADVANCED && M68060387387- ---help---388388- The 68060 generally uses copyback caching of recently accessed data.389389- Copyback caching means that memory writes will be held in an on-chip390390- cache and only written back to memory some time later. Saying Y391391- here will force supervisor (kernel) accesses to use writethrough392392- caching. Writethrough caching means that data is written to memory393393- straight away, so that cache and memory data always agree.394394- Writethrough caching is less efficient, but is needed for some395395- drivers on 68060 based systems where the 68060 bus snooping signal396396- is hardwired on. The 53c710 SCSI driver is known to suffer from397397- this problem.398398-399399-config ARCH_DISCONTIGMEM_ENABLE400400- def_bool !SINGLE_MEMORY_CHUNK401401-402402-config NODES_SHIFT403403- int404404- default "3"405405- depends on !SINGLE_MEMORY_CHUNK6464+if MMU6565+source arch/m68k/Kconfig.mmu6666+endif6767+if !MMU6868+source arch/m68k/Kconfig.nommu6969+endif4067040771source "mm/Kconfig"4087240973endmenu41074411411-menu "General setup"7575+menu "Executable file formats"4127641377source "fs/Kconfig.binfmt"41478415415-config ZORRO416416- bool "Amiga Zorro (AutoConfig) bus support"417417- depends on AMIGA418418- help419419- This enables support for the Zorro bus in the Amiga. If you have420420- expansion cards in your Amiga that conform to the Amiga421421- AutoConfig(tm) specification, say Y, otherwise N. Note that even422422- expansion cards that do not fit in the Zorro slots but fit in e.g.423423- the CPU slot may fall in this category, so you have to say Y to let424424- Linux use these.7979+endmenu42580426426-config AMIGA_PCMCIA427427- bool "Amiga 1200/600 PCMCIA support (EXPERIMENTAL)"428428- depends on AMIGA && EXPERIMENTAL429429- help430430- Include support in the kernel for pcmcia on Amiga 1200 and Amiga431431- 600. If you intend to use pcmcia cards say Y; otherwise say N.8181+if !MMU8282+menu "Power management options"43283433433-config STRAM_PROC434434- bool "ST-RAM statistics in /proc"435435- depends on ATARI436436- help437437- Say Y here to report ST-RAM usage statistics in /proc/stram.438438-439439-config HEARTBEAT440440- bool "Use power LED as a heartbeat" if AMIGA || APOLLO || ATARI || MAC ||Q40441441- default y if !AMIGA && !APOLLO && !ATARI && !MAC && !Q40 && HP300442442- help443443- Use the power-on LED on your machine as a load meter. The exact444444- behavior is platform-dependent, but normally the flash frequency is445445- a hyperbolic function of the 5-minute load average.446446-447447-# We have a dedicated heartbeat LED. :-)448448-config PROC_HARDWARE449449- bool "/proc/hardware support"450450- help451451- Say Y here to support the /proc/hardware file, which gives you452452- access to information about the machine you're running on,453453- including the model, CPU, MMU, clock speed, BogoMIPS rating,454454- and memory size.455455-456456-config ISA457457- bool458458- depends on Q40 || AMIGA_PCMCIA459459- default y460460- help461461- Find out whether you have ISA slots on your motherboard. ISA is the462462- name of a bus system, i.e. the way the CPU talks to the other stuff463463- inside your box. Other bus systems are PCI, EISA, MicroChannel464464- (MCA) or VESA. ISA is an older system, now being displaced by PCI;465465- newer boards don't support it. If you have ISA, say Y, otherwise N.466466-467467-config GENERIC_ISA_DMA468468- bool469469- depends on Q40 || AMIGA_PCMCIA470470- default y471471-472472-config ZONE_DMA473473- bool474474- default y475475-476476-source "drivers/pci/Kconfig"477477-478478-source "drivers/zorro/Kconfig"8484+config PM8585+ bool "Power Management support"8686+ help8787+ Support processor power management modes4798848089endmenu9090+endif4819148292source "net/Kconfig"4839348494source "drivers/Kconfig"9595+9696+if MMU4859748698menu "Character devices"48799···234626 If unsure, say N.235627236628endmenu629629+630630+endif237631238632source "fs/Kconfig"239633
+34
arch/m68k/Kconfig.debug
···2233source "lib/Kconfig.debug"4455+if !MMU66+77+config FULLDEBUG88+ bool "Full Symbolic/Source Debugging support"99+ help1010+ Enable debugging symbols on kernel build.1111+1212+config HIGHPROFILE1313+ bool "Use fast second timer for profiling"1414+ depends on COLDFIRE1515+ help1616+ Use a fast secondary clock to produce profiling information.1717+1818+config BOOTPARAM1919+ bool 'Compiled-in Kernel Boot Parameter'2020+2121+config BOOTPARAM_STRING2222+ string 'Kernel Boot Parameter'2323+ default 'console=ttyS0,19200'2424+ depends on BOOTPARAM2525+2626+config NO_KERNEL_MSG2727+ bool "Suppress Kernel BUG Messages"2828+ help2929+ Do not output any debug BUG messages within the kernel.3030+3131+config BDM_DISABLE3232+ bool "Disable BDM signals"3333+ depends on (EXPERIMENTAL && COLDFIRE)3434+ help3535+ Disable the ColdFire CPU's BDM signals.3636+3737+endif3838+539endmenu
+417
arch/m68k/Kconfig.mmu
···11+config GENERIC_IOMAP22+ bool33+ default y44+55+config ARCH_MAY_HAVE_PC_FDC66+ bool77+ depends on BROKEN && (Q40 || SUN3X)88+ default y99+1010+config ARCH_USES_GETTIMEOFFSET1111+ def_bool y1212+1313+config EISA1414+ bool1515+ ---help---1616+ The Extended Industry Standard Architecture (EISA) bus was1717+ developed as an open alternative to the IBM MicroChannel bus.1818+1919+ The EISA bus provided some of the features of the IBM MicroChannel2020+ bus while maintaining backward compatibility with cards made for2121+ the older ISA bus. The EISA bus saw limited use between 1988 and2222+ 1995 when it was made obsolete by the PCI bus.2323+2424+ Say Y here if you are building a kernel for an EISA-based machine.2525+2626+ Otherwise, say N.2727+2828+config MCA2929+ bool3030+ help3131+ MicroChannel Architecture is found in some IBM PS/2 machines and3232+ laptops. It is a bus system similar to PCI or ISA. See3333+ <file:Documentation/mca.txt> (and especially the web page given3434+ there) before attempting to build an MCA bus kernel.3535+3636+config PCMCIA3737+ tristate3838+ ---help---3939+ Say Y here if you want to attach PCMCIA- or PC-cards to your Linux4040+ computer. These are credit-card size devices such as network cards,4141+ modems or hard drives often used with laptops computers. There are4242+ actually two varieties of these cards: the older 16 bit PCMCIA cards4343+ and the newer 32 bit CardBus cards. If you want to use CardBus4444+ cards, you need to say Y here and also to "CardBus support" below.4545+4646+ To use your PC-cards, you will need supporting software from David4747+ Hinds' pcmcia-cs package (see the file <file:Documentation/Changes>4848+ for location). Please also read the PCMCIA-HOWTO, available from4949+ <http://www.tldp.org/docs.html#howto>.5050+5151+ To compile this driver as modules, choose M here: the5252+ modules will be called pcmcia_core and ds.5353+5454+config AMIGA5555+ bool "Amiga support"5656+ select MMU_MOTOROLA if MMU5757+ help5858+ This option enables support for the Amiga series of computers. If5959+ you plan to use this kernel on an Amiga, say Y here and browse the6060+ material available in <file:Documentation/m68k>; otherwise say N.6161+6262+config ATARI6363+ bool "Atari support"6464+ select MMU_MOTOROLA if MMU6565+ help6666+ This option enables support for the 68000-based Atari series of6767+ computers (including the TT, Falcon and Medusa). If you plan to use6868+ this kernel on an Atari, say Y here and browse the material6969+ available in <file:Documentation/m68k>; otherwise say N.7070+7171+config MAC7272+ bool "Macintosh support"7373+ select MMU_MOTOROLA if MMU7474+ help7575+ This option enables support for the Apple Macintosh series of7676+ computers (yes, there is experimental support now, at least for part7777+ of the series).7878+7979+ Say N unless you're willing to code the remaining necessary support.8080+ ;)8181+8282+config NUBUS8383+ bool8484+ depends on MAC8585+ default y8686+8787+config M68K_L2_CACHE8888+ bool8989+ depends on MAC9090+ default y9191+9292+config APOLLO9393+ bool "Apollo support"9494+ select MMU_MOTOROLA if MMU9595+ help9696+ Say Y here if you want to run Linux on an MC680x0-based Apollo9797+ Domain workstation such as the DN3500.9898+9999+config VME100100+ bool "VME (Motorola and BVM) support"101101+ select MMU_MOTOROLA if MMU102102+ help103103+ Say Y here if you want to build a kernel for a 680x0 based VME104104+ board. Boards currently supported include Motorola boards MVME147,105105+ MVME162, MVME166, MVME167, MVME172, and MVME177. BVME4000 and106106+ BVME6000 boards from BVM Ltd are also supported.107107+108108+config MVME147109109+ bool "MVME147 support"110110+ depends on VME111111+ help112112+ Say Y to include support for early Motorola VME boards. This will113113+ build a kernel which can run on MVME147 single-board computers. If114114+ you select this option you will have to select the appropriate115115+ drivers for SCSI, Ethernet and serial ports later on.116116+117117+config MVME16x118118+ bool "MVME162, 166 and 167 support"119119+ depends on VME120120+ help121121+ Say Y to include support for Motorola VME boards. This will build a122122+ kernel which can run on MVME162, MVME166, MVME167, MVME172, and123123+ MVME177 boards. If you select this option you will have to select124124+ the appropriate drivers for SCSI, Ethernet and serial ports later125125+ on.126126+127127+config BVME6000128128+ bool "BVME4000 and BVME6000 support"129129+ depends on VME130130+ help131131+ Say Y to include support for VME boards from BVM Ltd. This will132132+ build a kernel which can run on BVME4000 and BVME6000 boards. If133133+ you select this option you will have to select the appropriate134134+ drivers for SCSI, Ethernet and serial ports later on.135135+136136+config HP300137137+ bool "HP9000/300 and HP9000/400 support"138138+ select MMU_MOTOROLA if MMU139139+ help140140+ This option enables support for the HP9000/300 and HP9000/400 series141141+ of workstations. Support for these machines is still somewhat142142+ experimental. If you plan to try to use the kernel on such a machine143143+ say Y here.144144+ Everybody else says N.145145+146146+config DIO147147+ bool "DIO bus support"148148+ depends on HP300149149+ default y150150+ help151151+ Say Y here to enable support for the "DIO" expansion bus used in152152+ HP300 machines. If you are using such a system you almost certainly153153+ want this.154154+155155+config SUN3X156156+ bool "Sun3x support"157157+ select MMU_MOTOROLA if MMU158158+ select M68030159159+ help160160+ This option enables support for the Sun 3x series of workstations.161161+ Be warned that this support is very experimental.162162+ Note that Sun 3x kernels are not compatible with Sun 3 hardware.163163+ General Linux information on the Sun 3x series (now discontinued)164164+ is at <http://www.angelfire.com/ca2/tech68k/sun3.html>.165165+166166+ If you don't want to compile a kernel for a Sun 3x, say N.167167+168168+config Q40169169+ bool "Q40/Q60 support"170170+ select MMU_MOTOROLA if MMU171171+ help172172+ The Q40 is a Motorola 68040-based successor to the Sinclair QL173173+ manufactured in Germany. There is an official Q40 home page at174174+ <http://www.q40.de/>. This option enables support for the Q40 and175175+ Q60. Select your CPU below. For 68LC060 don't forget to enable FPU176176+ emulation.177177+178178+config SUN3179179+ bool "Sun3 support"180180+ depends on !MMU_MOTOROLA181181+ select MMU_SUN3 if MMU182182+ select M68020183183+ help184184+ This option enables support for the Sun 3 series of workstations185185+ (3/50, 3/60, 3/1xx, 3/2xx systems). Enabling this option requires186186+ that all other hardware types must be disabled, as Sun 3 kernels187187+ are incompatible with all other m68k targets (including Sun 3x!).188188+189189+ If you don't want to compile a kernel exclusively for a Sun 3, say N.190190+191191+config NATFEAT192192+ bool "ARAnyM emulator support"193193+ depends on ATARI194194+ help195195+ This option enables support for ARAnyM native features, such as196196+ access to a disk image as /dev/hda.197197+198198+config NFBLOCK199199+ tristate "NatFeat block device support"200200+ depends on BLOCK && NATFEAT201201+ help202202+ Say Y to include support for the ARAnyM NatFeat block device203203+ which allows direct access to the hard drives without using204204+ the hardware emulation.205205+206206+config NFCON207207+ tristate "NatFeat console driver"208208+ depends on NATFEAT209209+ help210210+ Say Y to include support for the ARAnyM NatFeat console driver211211+ which allows the console output to be redirected to the stderr212212+ output of ARAnyM.213213+214214+config NFETH215215+ tristate "NatFeat Ethernet support"216216+ depends on NET_ETHERNET && NATFEAT217217+ help218218+ Say Y to include support for the ARAnyM NatFeat network device219219+ which will emulate a regular ethernet device while presenting an220220+ ethertap device to the host system.221221+222222+comment "Processor type"223223+224224+config M68020225225+ bool "68020 support"226226+ help227227+ If you anticipate running this kernel on a computer with a MC68020228228+ processor, say Y. Otherwise, say N. Note that the 68020 requires a229229+ 68851 MMU (Memory Management Unit) to run Linux/m68k, except on the230230+ Sun 3, which provides its own version.231231+232232+config M68030233233+ bool "68030 support"234234+ depends on !MMU_SUN3235235+ help236236+ If you anticipate running this kernel on a computer with a MC68030237237+ processor, say Y. Otherwise, say N. Note that a MC68EC030 will not238238+ work, as it does not include an MMU (Memory Management Unit).239239+240240+config M68040241241+ bool "68040 support"242242+ depends on !MMU_SUN3243243+ help244244+ If you anticipate running this kernel on a computer with a MC68LC040245245+ or MC68040 processor, say Y. Otherwise, say N. Note that an246246+ MC68EC040 will not work, as it does not include an MMU (Memory247247+ Management Unit).248248+249249+config M68060250250+ bool "68060 support"251251+ depends on !MMU_SUN3252252+ help253253+ If you anticipate running this kernel on a computer with a MC68060254254+ processor, say Y. Otherwise, say N.255255+256256+config MMU_MOTOROLA257257+ bool258258+259259+config MMU_SUN3260260+ bool261261+ depends on MMU && !MMU_MOTOROLA262262+263263+config M68KFPU_EMU264264+ bool "Math emulation support (EXPERIMENTAL)"265265+ depends on EXPERIMENTAL266266+ help267267+ At some point in the future, this will cause floating-point math268268+ instructions to be emulated by the kernel on machines that lack a269269+ floating-point math coprocessor. Thrill-seekers and chronically270270+ sleep-deprived psychotic hacker types can say Y now, everyone else271271+ should probably wait a while.272272+273273+config M68KFPU_EMU_EXTRAPREC274274+ bool "Math emulation extra precision"275275+ depends on M68KFPU_EMU276276+ help277277+ The fpu uses normally a few bit more during calculations for278278+ correct rounding, the emulator can (often) do the same but this279279+ extra calculation can cost quite some time, so you can disable280280+ it here. The emulator will then "only" calculate with a 64 bit281281+ mantissa and round slightly incorrect, what is more than enough282282+ for normal usage.283283+284284+config M68KFPU_EMU_ONLY285285+ bool "Math emulation only kernel"286286+ depends on M68KFPU_EMU287287+ help288288+ This option prevents any floating-point instructions from being289289+ compiled into the kernel, thereby the kernel doesn't save any290290+ floating point context anymore during task switches, so this291291+ kernel will only be usable on machines without a floating-point292292+ math coprocessor. This makes the kernel a bit faster as no tests293293+ needs to be executed whether a floating-point instruction in the294294+ kernel should be executed or not.295295+296296+config ADVANCED297297+ bool "Advanced configuration options"298298+ ---help---299299+ This gives you access to some advanced options for the CPU. The300300+ defaults should be fine for most users, but these options may make301301+ it possible for you to improve performance somewhat if you know what302302+ you are doing.303303+304304+ Note that the answer to this question won't directly affect the305305+ kernel: saying N will just cause the configurator to skip all306306+ the questions about these options.307307+308308+ Most users should say N to this question.309309+310310+config RMW_INSNS311311+ bool "Use read-modify-write instructions"312312+ depends on ADVANCED313313+ ---help---314314+ This allows to use certain instructions that work with indivisible315315+ read-modify-write bus cycles. While this is faster than the316316+ workaround of disabling interrupts, it can conflict with DMA317317+ ( = direct memory access) on many Amiga systems, and it is also said318318+ to destabilize other machines. It is very likely that this will319319+ cause serious problems on any Amiga or Atari Medusa if set. The only320320+ configuration where it should work are 68030-based Ataris, where it321321+ apparently improves performance. But you've been warned! Unless you322322+ really know what you are doing, say N. Try Y only if you're quite323323+ adventurous.324324+325325+config SINGLE_MEMORY_CHUNK326326+ bool "Use one physical chunk of memory only" if ADVANCED && !SUN3327327+ default y if SUN3328328+ select NEED_MULTIPLE_NODES329329+ help330330+ Ignore all but the first contiguous chunk of physical memory for VM331331+ purposes. This will save a few bytes kernel size and may speed up332332+ some operations. Say N if not sure.333333+334334+config 060_WRITETHROUGH335335+ bool "Use write-through caching for 68060 supervisor accesses"336336+ depends on ADVANCED && M68060337337+ ---help---338338+ The 68060 generally uses copyback caching of recently accessed data.339339+ Copyback caching means that memory writes will be held in an on-chip340340+ cache and only written back to memory some time later. Saying Y341341+ here will force supervisor (kernel) accesses to use writethrough342342+ caching. Writethrough caching means that data is written to memory343343+ straight away, so that cache and memory data always agree.344344+ Writethrough caching is less efficient, but is needed for some345345+ drivers on 68060 based systems where the 68060 bus snooping signal346346+ is hardwired on. The 53c710 SCSI driver is known to suffer from347347+ this problem.348348+349349+config ARCH_DISCONTIGMEM_ENABLE350350+ def_bool !SINGLE_MEMORY_CHUNK351351+352352+config NODES_SHIFT353353+ int354354+ default "3"355355+ depends on !SINGLE_MEMORY_CHUNK356356+357357+config ZORRO358358+ bool "Amiga Zorro (AutoConfig) bus support"359359+ depends on AMIGA360360+ help361361+ This enables support for the Zorro bus in the Amiga. If you have362362+ expansion cards in your Amiga that conform to the Amiga363363+ AutoConfig(tm) specification, say Y, otherwise N. Note that even364364+ expansion cards that do not fit in the Zorro slots but fit in e.g.365365+ the CPU slot may fall in this category, so you have to say Y to let366366+ Linux use these.367367+368368+config AMIGA_PCMCIA369369+ bool "Amiga 1200/600 PCMCIA support (EXPERIMENTAL)"370370+ depends on AMIGA && EXPERIMENTAL371371+ help372372+ Include support in the kernel for pcmcia on Amiga 1200 and Amiga373373+ 600. If you intend to use pcmcia cards say Y; otherwise say N.374374+375375+config STRAM_PROC376376+ bool "ST-RAM statistics in /proc"377377+ depends on ATARI378378+ help379379+ Say Y here to report ST-RAM usage statistics in /proc/stram.380380+381381+config HEARTBEAT382382+ bool "Use power LED as a heartbeat" if AMIGA || APOLLO || ATARI || MAC ||Q40383383+ default y if !AMIGA && !APOLLO && !ATARI && !MAC && !Q40 && HP300384384+ help385385+ Use the power-on LED on your machine as a load meter. The exact386386+ behavior is platform-dependent, but normally the flash frequency is387387+ a hyperbolic function of the 5-minute load average.388388+389389+# We have a dedicated heartbeat LED. :-)390390+config PROC_HARDWARE391391+ bool "/proc/hardware support"392392+ help393393+ Say Y here to support the /proc/hardware file, which gives you394394+ access to information about the machine you're running on,395395+ including the model, CPU, MMU, clock speed, BogoMIPS rating,396396+ and memory size.397397+398398+config ISA399399+ bool400400+ depends on Q40 || AMIGA_PCMCIA401401+ default y402402+ help403403+ Find out whether you have ISA slots on your motherboard. ISA is the404404+ name of a bus system, i.e. the way the CPU talks to the other stuff405405+ inside your box. Other bus systems are PCI, EISA, MicroChannel406406+ (MCA) or VESA. ISA is an older system, now being displaced by PCI;407407+ newer boards don't support it. If you have ISA, say Y, otherwise N.408408+409409+config GENERIC_ISA_DMA410410+ bool411411+ depends on Q40 || AMIGA_PCMCIA412412+ default y413413+414414+source "drivers/pci/Kconfig"415415+416416+source "drivers/zorro/Kconfig"417417+
+3-119
arch/m68k/Makefile
···11-#22-# m68k/Makefile33-#44-# This file is included by the global makefile so that you can add your own55-# architecture-specific flags and dependencies. Remember to do have actions66-# for "archclean" and "archdep" for cleaning up and making dependencies for77-# this architecture88-#99-# This file is subject to the terms and conditions of the GNU General Public1010-# License. See the file "COPYING" in the main directory of this archive1111-# for more details.1212-#1313-# Copyright (C) 1994 by Hamish Macdonald1414-#1515-161KBUILD_DEFCONFIG := multi_defconfig1721818-# override top level makefile1919-AS += -m680202020-LDFLAGS := -m m68kelf2121-KBUILD_LDFLAGS_MODULE += -T $(srctree)/arch/m68k/kernel/module.lds2222-ifneq ($(SUBARCH),$(ARCH))2323- ifeq ($(CROSS_COMPILE),)2424- CROSS_COMPILE := $(call cc-cross-prefix, \2525- m68k-linux-gnu- m68k-linux- m68k-unknown-linux-gnu-)2626- endif2727-endif2828-2929-ifdef CONFIG_SUN33030-LDFLAGS_vmlinux = -N3131-endif3232-3333-CHECKFLAGS += -D__mc68000__3434-3535-# without -fno-strength-reduce the 53c7xx.c driver fails ;-(3636-KBUILD_CFLAGS += -pipe -fno-strength-reduce -ffixed-a23737-3838-# enable processor switch if compiled only for a single cpu3939-ifndef CONFIG_M680204040-ifndef CONFIG_M680304141-4242-ifndef CONFIG_M680604343-KBUILD_CFLAGS += -m680404444-endif4545-4646-ifndef CONFIG_M680404747-KBUILD_CFLAGS += -m680604848-endif4949-5050-endif5151-endif5252-5353-ifdef CONFIG_KGDB5454-# If configured for kgdb support, include debugging infos and keep the5555-# frame pointer5656-KBUILD_CFLAGS := $(subst -fomit-frame-pointer,,$(KBUILD_CFLAGS)) -g5757-endif5858-5959-ifndef CONFIG_SUN36060-head-y := arch/m68k/kernel/head.o33+ifdef CONFIG_MMU44+include $(srctree)/arch/m68k/Makefile_mm615else6262-head-y := arch/m68k/kernel/sun3-head.o66+include $(srctree)/arch/m68k/Makefile_no637endif6464-6565-core-y += arch/m68k/kernel/ arch/m68k/mm/6666-libs-y += arch/m68k/lib/6767-6868-core-$(CONFIG_Q40) += arch/m68k/q40/6969-core-$(CONFIG_AMIGA) += arch/m68k/amiga/7070-core-$(CONFIG_ATARI) += arch/m68k/atari/7171-core-$(CONFIG_MAC) += arch/m68k/mac/7272-core-$(CONFIG_HP300) += arch/m68k/hp300/7373-core-$(CONFIG_APOLLO) += arch/m68k/apollo/7474-core-$(CONFIG_MVME147) += arch/m68k/mvme147/7575-core-$(CONFIG_MVME16x) += arch/m68k/mvme16x/7676-core-$(CONFIG_BVME6000) += arch/m68k/bvme6000/7777-core-$(CONFIG_SUN3X) += arch/m68k/sun3x/ arch/m68k/sun3/7878-core-$(CONFIG_SUN3) += arch/m68k/sun3/ arch/m68k/sun3/prom/7979-core-$(CONFIG_NATFEAT) += arch/m68k/emu/8080-core-$(CONFIG_M68040) += arch/m68k/fpsp040/8181-core-$(CONFIG_M68060) += arch/m68k/ifpsp060/8282-core-$(CONFIG_M68KFPU_EMU) += arch/m68k/math-emu/8383-8484-all: zImage8585-8686-lilo: vmlinux8787- if [ -f $(INSTALL_PATH)/vmlinux ]; then mv -f $(INSTALL_PATH)/vmlinux $(INSTALL_PATH)/vmlinux.old; fi8888- if [ -f $(INSTALL_PATH)/System.map ]; then mv -f $(INSTALL_PATH)/System.map $(INSTALL_PATH)/System.old; fi8989- cat vmlinux > $(INSTALL_PATH)/vmlinux9090- cp System.map $(INSTALL_PATH)/System.map9191- if [ -x /sbin/lilo ]; then /sbin/lilo; else /etc/lilo/install; fi9292-9393-zImage compressed: vmlinux.gz9494-9595-vmlinux.gz: vmlinux9696-9797-ifndef CONFIG_KGDB9898- cp vmlinux vmlinux.tmp9999- $(STRIP) vmlinux.tmp100100- gzip -9c vmlinux.tmp >vmlinux.gz101101- rm vmlinux.tmp102102-else103103- gzip -9c vmlinux >vmlinux.gz104104-endif105105-106106-bzImage: vmlinux.bz2107107-108108-vmlinux.bz2: vmlinux109109-110110-ifndef CONFIG_KGDB111111- cp vmlinux vmlinux.tmp112112- $(STRIP) vmlinux.tmp113113- bzip2 -1c vmlinux.tmp >vmlinux.bz2114114- rm vmlinux.tmp115115-else116116- bzip2 -1c vmlinux >vmlinux.bz2117117-endif118118-119119-archclean:120120- rm -f vmlinux.gz vmlinux.bz2121121-122122-install:123123- sh $(srctree)/arch/m68k/install.sh $(KERNELRELEASE) vmlinux.gz System.map "$(INSTALL_PATH)"
+121
arch/m68k/Makefile_mm
···11+#22+# m68k/Makefile33+#44+# This file is included by the global makefile so that you can add your own55+# architecture-specific flags and dependencies. Remember to do have actions66+# for "archclean" and "archdep" for cleaning up and making dependencies for77+# this architecture88+#99+# This file is subject to the terms and conditions of the GNU General Public1010+# License. See the file "COPYING" in the main directory of this archive1111+# for more details.1212+#1313+# Copyright (C) 1994 by Hamish Macdonald1414+#1515+1616+# override top level makefile1717+AS += -m680201818+LDFLAGS := -m m68kelf1919+KBUILD_LDFLAGS_MODULE += -T $(srctree)/arch/m68k/kernel/module.lds2020+ifneq ($(SUBARCH),$(ARCH))2121+ ifeq ($(CROSS_COMPILE),)2222+ CROSS_COMPILE := $(call cc-cross-prefix, \2323+ m68k-linux-gnu- m68k-linux- m68k-unknown-linux-gnu-)2424+ endif2525+endif2626+2727+ifdef CONFIG_SUN32828+LDFLAGS_vmlinux = -N2929+endif3030+3131+CHECKFLAGS += -D__mc68000__3232+3333+# without -fno-strength-reduce the 53c7xx.c driver fails ;-(3434+KBUILD_CFLAGS += -pipe -fno-strength-reduce -ffixed-a23535+3636+# enable processor switch if compiled only for a single cpu3737+ifndef CONFIG_M680203838+ifndef CONFIG_M680303939+4040+ifndef CONFIG_M680604141+KBUILD_CFLAGS += -m680404242+endif4343+4444+ifndef CONFIG_M680404545+KBUILD_CFLAGS += -m680604646+endif4747+4848+endif4949+endif5050+5151+ifdef CONFIG_KGDB5252+# If configured for kgdb support, include debugging infos and keep the5353+# frame pointer5454+KBUILD_CFLAGS := $(subst -fomit-frame-pointer,,$(KBUILD_CFLAGS)) -g5555+endif5656+5757+ifndef CONFIG_SUN35858+head-y := arch/m68k/kernel/head.o5959+else6060+head-y := arch/m68k/kernel/sun3-head.o6161+endif6262+6363+core-y += arch/m68k/kernel/ arch/m68k/mm/6464+libs-y += arch/m68k/lib/6565+6666+core-$(CONFIG_Q40) += arch/m68k/q40/6767+core-$(CONFIG_AMIGA) += arch/m68k/amiga/6868+core-$(CONFIG_ATARI) += arch/m68k/atari/6969+core-$(CONFIG_MAC) += arch/m68k/mac/7070+core-$(CONFIG_HP300) += arch/m68k/hp300/7171+core-$(CONFIG_APOLLO) += arch/m68k/apollo/7272+core-$(CONFIG_MVME147) += arch/m68k/mvme147/7373+core-$(CONFIG_MVME16x) += arch/m68k/mvme16x/7474+core-$(CONFIG_BVME6000) += arch/m68k/bvme6000/7575+core-$(CONFIG_SUN3X) += arch/m68k/sun3x/ arch/m68k/sun3/7676+core-$(CONFIG_SUN3) += arch/m68k/sun3/ arch/m68k/sun3/prom/7777+core-$(CONFIG_NATFEAT) += arch/m68k/emu/7878+core-$(CONFIG_M68040) += arch/m68k/fpsp040/7979+core-$(CONFIG_M68060) += arch/m68k/ifpsp060/8080+core-$(CONFIG_M68KFPU_EMU) += arch/m68k/math-emu/8181+8282+all: zImage8383+8484+lilo: vmlinux8585+ if [ -f $(INSTALL_PATH)/vmlinux ]; then mv -f $(INSTALL_PATH)/vmlinux $(INSTALL_PATH)/vmlinux.old; fi8686+ if [ -f $(INSTALL_PATH)/System.map ]; then mv -f $(INSTALL_PATH)/System.map $(INSTALL_PATH)/System.old; fi8787+ cat vmlinux > $(INSTALL_PATH)/vmlinux8888+ cp System.map $(INSTALL_PATH)/System.map8989+ if [ -x /sbin/lilo ]; then /sbin/lilo; else /etc/lilo/install; fi9090+9191+zImage compressed: vmlinux.gz9292+9393+vmlinux.gz: vmlinux9494+9595+ifndef CONFIG_KGDB9696+ cp vmlinux vmlinux.tmp9797+ $(STRIP) vmlinux.tmp9898+ gzip -9c vmlinux.tmp >vmlinux.gz9999+ rm vmlinux.tmp100100+else101101+ gzip -9c vmlinux >vmlinux.gz102102+endif103103+104104+bzImage: vmlinux.bz2105105+106106+vmlinux.bz2: vmlinux107107+108108+ifndef CONFIG_KGDB109109+ cp vmlinux vmlinux.tmp110110+ $(STRIP) vmlinux.tmp111111+ bzip2 -1c vmlinux.tmp >vmlinux.bz2112112+ rm vmlinux.tmp113113+else114114+ bzip2 -1c vmlinux >vmlinux.bz2115115+endif116116+117117+archclean:118118+ rm -f vmlinux.gz vmlinux.bz2119119+120120+install:121121+ sh $(srctree)/arch/m68k/install.sh $(KERNELRELEASE) vmlinux.gz System.map "$(INSTALL_PATH)"
+3-15
arch/m68k/kernel/Makefile
···11-#22-# Makefile for the linux kernel.33-#44-55-ifndef CONFIG_SUN366- extra-y := head.o11+ifdef CONFIG_MMU22+include arch/m68k/kernel/Makefile_mm73else88- extra-y := sun3-head.o44+include arch/m68k/kernel/Makefile_no95endif1010-extra-y += vmlinux.lds1111-1212-obj-y := entry.o process.o traps.o ints.o signal.o ptrace.o module.o \1313- sys_m68k.o time.o setup.o m68k_ksyms.o devres.o1414-1515-devres-y = ../../../kernel/irq/devres.o1616-1717-obj-y$(CONFIG_MMU_SUN3) += dma.o # no, it's not a typo
+17
arch/m68k/kernel/Makefile_mm
···11+#22+# Makefile for the linux kernel.33+#44+55+ifndef CONFIG_SUN366+ extra-y := head.o77+else88+ extra-y := sun3-head.o99+endif1010+extra-y += vmlinux.lds1111+1212+obj-y := entry.o process.o traps.o ints.o signal.o ptrace.o module.o \1313+ sys_m68k.o time.o setup.o m68k_ksyms.o devres.o1414+1515+devres-y = ../../../kernel/irq/devres.o1616+1717+obj-y$(CONFIG_MMU_SUN3) += dma.o # no, it's not a typo
+3-98
arch/m68k/kernel/asm-offsets.c
···11-/*22- * This program is used to generate definitions needed by33- * assembly language modules.44- *55- * We use the technique used in the OSF Mach kernel code:66- * generate asm statements containing #defines,77- * compile this file to assembler, and then extract the88- * #defines from the assembly-language output.99- */1010-1111-#define ASM_OFFSETS_C1212-1313-#include <linux/stddef.h>1414-#include <linux/sched.h>1515-#include <linux/kernel_stat.h>1616-#include <linux/kbuild.h>1717-#include <asm/bootinfo.h>1818-#include <asm/irq.h>1919-#include <asm/amigahw.h>2020-#include <linux/font.h>2121-2222-int main(void)2323-{2424- /* offsets into the task struct */2525- DEFINE(TASK_THREAD, offsetof(struct task_struct, thread));2626- DEFINE(TASK_INFO, offsetof(struct task_struct, thread.info));2727- DEFINE(TASK_MM, offsetof(struct task_struct, mm));281#ifdef CONFIG_MMU2929- DEFINE(TASK_TINFO, offsetof(struct task_struct, thread.info));22+#include "asm-offsets_mm.c"33+#else44+#include "asm-offsets_no.c"305#endif3131-3232- /* offsets into the thread struct */3333- DEFINE(THREAD_KSP, offsetof(struct thread_struct, ksp));3434- DEFINE(THREAD_USP, offsetof(struct thread_struct, usp));3535- DEFINE(THREAD_SR, offsetof(struct thread_struct, sr));3636- DEFINE(THREAD_FS, offsetof(struct thread_struct, fs));3737- DEFINE(THREAD_CRP, offsetof(struct thread_struct, crp));3838- DEFINE(THREAD_ESP0, offsetof(struct thread_struct, esp0));3939- DEFINE(THREAD_FPREG, offsetof(struct thread_struct, fp));4040- DEFINE(THREAD_FPCNTL, offsetof(struct thread_struct, fpcntl));4141- DEFINE(THREAD_FPSTATE, offsetof(struct thread_struct, fpstate));4242-4343- /* offsets into the thread_info struct */4444- DEFINE(TINFO_PREEMPT, offsetof(struct thread_info, preempt_count));4545- DEFINE(TINFO_FLAGS, offsetof(struct thread_info, flags));4646-4747- /* offsets into the pt_regs */4848- DEFINE(PT_OFF_D0, offsetof(struct pt_regs, d0));4949- DEFINE(PT_OFF_ORIG_D0, offsetof(struct pt_regs, orig_d0));5050- DEFINE(PT_OFF_D1, offsetof(struct pt_regs, d1));5151- DEFINE(PT_OFF_D2, offsetof(struct pt_regs, d2));5252- DEFINE(PT_OFF_D3, offsetof(struct pt_regs, d3));5353- DEFINE(PT_OFF_D4, offsetof(struct pt_regs, d4));5454- DEFINE(PT_OFF_D5, offsetof(struct pt_regs, d5));5555- DEFINE(PT_OFF_A0, offsetof(struct pt_regs, a0));5656- DEFINE(PT_OFF_A1, offsetof(struct pt_regs, a1));5757- DEFINE(PT_OFF_A2, offsetof(struct pt_regs, a2));5858- DEFINE(PT_OFF_PC, offsetof(struct pt_regs, pc));5959- DEFINE(PT_OFF_SR, offsetof(struct pt_regs, sr));6060- /* bitfields are a bit difficult */6161- DEFINE(PT_OFF_FORMATVEC, offsetof(struct pt_regs, pc) + 4);6262-6363- /* offsets into the irq_cpustat_t struct */6464- DEFINE(CPUSTAT_SOFTIRQ_PENDING, offsetof(irq_cpustat_t, __softirq_pending));6565-6666- /* offsets into the bi_record struct */6767- DEFINE(BIR_TAG, offsetof(struct bi_record, tag));6868- DEFINE(BIR_SIZE, offsetof(struct bi_record, size));6969- DEFINE(BIR_DATA, offsetof(struct bi_record, data));7070-7171- /* offsets into font_desc (drivers/video/console/font.h) */7272- DEFINE(FONT_DESC_IDX, offsetof(struct font_desc, idx));7373- DEFINE(FONT_DESC_NAME, offsetof(struct font_desc, name));7474- DEFINE(FONT_DESC_WIDTH, offsetof(struct font_desc, width));7575- DEFINE(FONT_DESC_HEIGHT, offsetof(struct font_desc, height));7676- DEFINE(FONT_DESC_DATA, offsetof(struct font_desc, data));7777- DEFINE(FONT_DESC_PREF, offsetof(struct font_desc, pref));7878-7979- /* signal defines */8080- DEFINE(LSIGSEGV, SIGSEGV);8181- DEFINE(LSEGV_MAPERR, SEGV_MAPERR);8282- DEFINE(LSIGTRAP, SIGTRAP);8383- DEFINE(LTRAP_TRACE, TRAP_TRACE);8484-8585- /* offsets into the custom struct */8686- DEFINE(CUSTOMBASE, &amiga_custom);8787- DEFINE(C_INTENAR, offsetof(struct CUSTOM, intenar));8888- DEFINE(C_INTREQR, offsetof(struct CUSTOM, intreqr));8989- DEFINE(C_INTENA, offsetof(struct CUSTOM, intena));9090- DEFINE(C_INTREQ, offsetof(struct CUSTOM, intreq));9191- DEFINE(C_SERDATR, offsetof(struct CUSTOM, serdatr));9292- DEFINE(C_SERDAT, offsetof(struct CUSTOM, serdat));9393- DEFINE(C_SERPER, offsetof(struct CUSTOM, serper));9494- DEFINE(CIAABASE, &ciaa);9595- DEFINE(CIABBASE, &ciab);9696- DEFINE(C_PRA, offsetof(struct CIA, pra));9797- DEFINE(ZTWOBASE, zTwoBase);9898-9999- return 0;100100-}
+100
arch/m68k/kernel/asm-offsets_mm.c
···11+/*22+ * This program is used to generate definitions needed by33+ * assembly language modules.44+ *55+ * We use the technique used in the OSF Mach kernel code:66+ * generate asm statements containing #defines,77+ * compile this file to assembler, and then extract the88+ * #defines from the assembly-language output.99+ */1010+1111+#define ASM_OFFSETS_C1212+1313+#include <linux/stddef.h>1414+#include <linux/sched.h>1515+#include <linux/kernel_stat.h>1616+#include <linux/kbuild.h>1717+#include <asm/bootinfo.h>1818+#include <asm/irq.h>1919+#include <asm/amigahw.h>2020+#include <linux/font.h>2121+2222+int main(void)2323+{2424+ /* offsets into the task struct */2525+ DEFINE(TASK_THREAD, offsetof(struct task_struct, thread));2626+ DEFINE(TASK_INFO, offsetof(struct task_struct, thread.info));2727+ DEFINE(TASK_MM, offsetof(struct task_struct, mm));2828+#ifdef CONFIG_MMU2929+ DEFINE(TASK_TINFO, offsetof(struct task_struct, thread.info));3030+#endif3131+3232+ /* offsets into the thread struct */3333+ DEFINE(THREAD_KSP, offsetof(struct thread_struct, ksp));3434+ DEFINE(THREAD_USP, offsetof(struct thread_struct, usp));3535+ DEFINE(THREAD_SR, offsetof(struct thread_struct, sr));3636+ DEFINE(THREAD_FS, offsetof(struct thread_struct, fs));3737+ DEFINE(THREAD_CRP, offsetof(struct thread_struct, crp));3838+ DEFINE(THREAD_ESP0, offsetof(struct thread_struct, esp0));3939+ DEFINE(THREAD_FPREG, offsetof(struct thread_struct, fp));4040+ DEFINE(THREAD_FPCNTL, offsetof(struct thread_struct, fpcntl));4141+ DEFINE(THREAD_FPSTATE, offsetof(struct thread_struct, fpstate));4242+4343+ /* offsets into the thread_info struct */4444+ DEFINE(TINFO_PREEMPT, offsetof(struct thread_info, preempt_count));4545+ DEFINE(TINFO_FLAGS, offsetof(struct thread_info, flags));4646+4747+ /* offsets into the pt_regs */4848+ DEFINE(PT_OFF_D0, offsetof(struct pt_regs, d0));4949+ DEFINE(PT_OFF_ORIG_D0, offsetof(struct pt_regs, orig_d0));5050+ DEFINE(PT_OFF_D1, offsetof(struct pt_regs, d1));5151+ DEFINE(PT_OFF_D2, offsetof(struct pt_regs, d2));5252+ DEFINE(PT_OFF_D3, offsetof(struct pt_regs, d3));5353+ DEFINE(PT_OFF_D4, offsetof(struct pt_regs, d4));5454+ DEFINE(PT_OFF_D5, offsetof(struct pt_regs, d5));5555+ DEFINE(PT_OFF_A0, offsetof(struct pt_regs, a0));5656+ DEFINE(PT_OFF_A1, offsetof(struct pt_regs, a1));5757+ DEFINE(PT_OFF_A2, offsetof(struct pt_regs, a2));5858+ DEFINE(PT_OFF_PC, offsetof(struct pt_regs, pc));5959+ DEFINE(PT_OFF_SR, offsetof(struct pt_regs, sr));6060+ /* bitfields are a bit difficult */6161+ DEFINE(PT_OFF_FORMATVEC, offsetof(struct pt_regs, pc) + 4);6262+6363+ /* offsets into the irq_cpustat_t struct */6464+ DEFINE(CPUSTAT_SOFTIRQ_PENDING, offsetof(irq_cpustat_t, __softirq_pending));6565+6666+ /* offsets into the bi_record struct */6767+ DEFINE(BIR_TAG, offsetof(struct bi_record, tag));6868+ DEFINE(BIR_SIZE, offsetof(struct bi_record, size));6969+ DEFINE(BIR_DATA, offsetof(struct bi_record, data));7070+7171+ /* offsets into font_desc (drivers/video/console/font.h) */7272+ DEFINE(FONT_DESC_IDX, offsetof(struct font_desc, idx));7373+ DEFINE(FONT_DESC_NAME, offsetof(struct font_desc, name));7474+ DEFINE(FONT_DESC_WIDTH, offsetof(struct font_desc, width));7575+ DEFINE(FONT_DESC_HEIGHT, offsetof(struct font_desc, height));7676+ DEFINE(FONT_DESC_DATA, offsetof(struct font_desc, data));7777+ DEFINE(FONT_DESC_PREF, offsetof(struct font_desc, pref));7878+7979+ /* signal defines */8080+ DEFINE(LSIGSEGV, SIGSEGV);8181+ DEFINE(LSEGV_MAPERR, SEGV_MAPERR);8282+ DEFINE(LSIGTRAP, SIGTRAP);8383+ DEFINE(LTRAP_TRACE, TRAP_TRACE);8484+8585+ /* offsets into the custom struct */8686+ DEFINE(CUSTOMBASE, &amiga_custom);8787+ DEFINE(C_INTENAR, offsetof(struct CUSTOM, intenar));8888+ DEFINE(C_INTREQR, offsetof(struct CUSTOM, intreqr));8989+ DEFINE(C_INTENA, offsetof(struct CUSTOM, intena));9090+ DEFINE(C_INTREQ, offsetof(struct CUSTOM, intreq));9191+ DEFINE(C_SERDATR, offsetof(struct CUSTOM, serdatr));9292+ DEFINE(C_SERDAT, offsetof(struct CUSTOM, serdat));9393+ DEFINE(C_SERPER, offsetof(struct CUSTOM, serper));9494+ DEFINE(CIAABASE, &ciaa);9595+ DEFINE(CIABBASE, &ciab);9696+ DEFINE(C_PRA, offsetof(struct CIA, pra));9797+ DEFINE(ZTWOBASE, zTwoBase);9898+9999+ return 0;100100+}
+5-130
arch/m68k/kernel/dma.c
···11-/*22- * This file is subject to the terms and conditions of the GNU General Public33- * License. See the file COPYING in the main directory of this archive44- * for more details.55- */66-77-#undef DEBUG88-99-#include <linux/dma-mapping.h>1010-#include <linux/device.h>1111-#include <linux/kernel.h>1212-#include <linux/scatterlist.h>1313-#include <linux/slab.h>1414-#include <linux/vmalloc.h>1515-1616-#include <asm/pgalloc.h>1717-1818-void *dma_alloc_coherent(struct device *dev, size_t size,1919- dma_addr_t *handle, gfp_t flag)2020-{2121- struct page *page, **map;2222- pgprot_t pgprot;2323- void *addr;2424- int i, order;2525-2626- pr_debug("dma_alloc_coherent: %d,%x\n", size, flag);2727-2828- size = PAGE_ALIGN(size);2929- order = get_order(size);3030-3131- page = alloc_pages(flag, order);3232- if (!page)3333- return NULL;3434-3535- *handle = page_to_phys(page);3636- map = kmalloc(sizeof(struct page *) << order, flag & ~__GFP_DMA);3737- if (!map) {3838- __free_pages(page, order);3939- return NULL;4040- }4141- split_page(page, order);4242-4343- order = 1 << order;4444- size >>= PAGE_SHIFT;4545- map[0] = page;4646- for (i = 1; i < size; i++)4747- map[i] = page + i;4848- for (; i < order; i++)4949- __free_page(page + i);5050- pgprot = __pgprot(_PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_DIRTY);5151- if (CPU_IS_040_OR_060)5252- pgprot_val(pgprot) |= _PAGE_GLOBAL040 | _PAGE_NOCACHE_S;5353- else5454- pgprot_val(pgprot) |= _PAGE_NOCACHE030;5555- addr = vmap(map, size, VM_MAP, pgprot);5656- kfree(map);5757-5858- return addr;5959-}6060-EXPORT_SYMBOL(dma_alloc_coherent);6161-6262-void dma_free_coherent(struct device *dev, size_t size,6363- void *addr, dma_addr_t handle)6464-{6565- pr_debug("dma_free_coherent: %p, %x\n", addr, handle);6666- vfree(addr);6767-}6868-EXPORT_SYMBOL(dma_free_coherent);6969-7070-void dma_sync_single_for_device(struct device *dev, dma_addr_t handle,7171- size_t size, enum dma_data_direction dir)7272-{7373- switch (dir) {7474- case DMA_TO_DEVICE:7575- cache_push(handle, size);7676- break;7777- case DMA_FROM_DEVICE:7878- cache_clear(handle, size);7979- break;8080- default:8181- if (printk_ratelimit())8282- printk("dma_sync_single_for_device: unsupported dir %u\n", dir);8383- break;8484- }8585-}8686-EXPORT_SYMBOL(dma_sync_single_for_device);8787-8888-void dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg, int nents,8989- enum dma_data_direction dir)9090-{9191- int i;9292-9393- for (i = 0; i < nents; sg++, i++)9494- dma_sync_single_for_device(dev, sg->dma_address, sg->length, dir);9595-}9696-EXPORT_SYMBOL(dma_sync_sg_for_device);9797-9898-dma_addr_t dma_map_single(struct device *dev, void *addr, size_t size,9999- enum dma_data_direction dir)100100-{101101- dma_addr_t handle = virt_to_bus(addr);102102-103103- dma_sync_single_for_device(dev, handle, size, dir);104104- return handle;105105-}106106-EXPORT_SYMBOL(dma_map_single);107107-108108-dma_addr_t dma_map_page(struct device *dev, struct page *page,109109- unsigned long offset, size_t size,110110- enum dma_data_direction dir)111111-{112112- dma_addr_t handle = page_to_phys(page) + offset;113113-114114- dma_sync_single_for_device(dev, handle, size, dir);115115- return handle;116116-}117117-EXPORT_SYMBOL(dma_map_page);118118-119119-int dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,120120- enum dma_data_direction dir)121121-{122122- int i;123123-124124- for (i = 0; i < nents; sg++, i++) {125125- sg->dma_address = sg_phys(sg);126126- dma_sync_single_for_device(dev, sg->dma_address, sg->length, dir);127127- }128128- return nents;129129-}130130-EXPORT_SYMBOL(dma_map_sg);11+#ifdef CONFIG_MMU22+#include "dma_mm.c"33+#else44+#include "dma_no.c"55+#endif
+130
arch/m68k/kernel/dma_mm.c
···11+/*22+ * This file is subject to the terms and conditions of the GNU General Public33+ * License. See the file COPYING in the main directory of this archive44+ * for more details.55+ */66+77+#undef DEBUG88+99+#include <linux/dma-mapping.h>1010+#include <linux/device.h>1111+#include <linux/kernel.h>1212+#include <linux/scatterlist.h>1313+#include <linux/slab.h>1414+#include <linux/vmalloc.h>1515+1616+#include <asm/pgalloc.h>1717+1818+void *dma_alloc_coherent(struct device *dev, size_t size,1919+ dma_addr_t *handle, gfp_t flag)2020+{2121+ struct page *page, **map;2222+ pgprot_t pgprot;2323+ void *addr;2424+ int i, order;2525+2626+ pr_debug("dma_alloc_coherent: %d,%x\n", size, flag);2727+2828+ size = PAGE_ALIGN(size);2929+ order = get_order(size);3030+3131+ page = alloc_pages(flag, order);3232+ if (!page)3333+ return NULL;3434+3535+ *handle = page_to_phys(page);3636+ map = kmalloc(sizeof(struct page *) << order, flag & ~__GFP_DMA);3737+ if (!map) {3838+ __free_pages(page, order);3939+ return NULL;4040+ }4141+ split_page(page, order);4242+4343+ order = 1 << order;4444+ size >>= PAGE_SHIFT;4545+ map[0] = page;4646+ for (i = 1; i < size; i++)4747+ map[i] = page + i;4848+ for (; i < order; i++)4949+ __free_page(page + i);5050+ pgprot = __pgprot(_PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_DIRTY);5151+ if (CPU_IS_040_OR_060)5252+ pgprot_val(pgprot) |= _PAGE_GLOBAL040 | _PAGE_NOCACHE_S;5353+ else5454+ pgprot_val(pgprot) |= _PAGE_NOCACHE030;5555+ addr = vmap(map, size, VM_MAP, pgprot);5656+ kfree(map);5757+5858+ return addr;5959+}6060+EXPORT_SYMBOL(dma_alloc_coherent);6161+6262+void dma_free_coherent(struct device *dev, size_t size,6363+ void *addr, dma_addr_t handle)6464+{6565+ pr_debug("dma_free_coherent: %p, %x\n", addr, handle);6666+ vfree(addr);6767+}6868+EXPORT_SYMBOL(dma_free_coherent);6969+7070+void dma_sync_single_for_device(struct device *dev, dma_addr_t handle,7171+ size_t size, enum dma_data_direction dir)7272+{7373+ switch (dir) {7474+ case DMA_TO_DEVICE:7575+ cache_push(handle, size);7676+ break;7777+ case DMA_FROM_DEVICE:7878+ cache_clear(handle, size);7979+ break;8080+ default:8181+ if (printk_ratelimit())8282+ printk("dma_sync_single_for_device: unsupported dir %u\n", dir);8383+ break;8484+ }8585+}8686+EXPORT_SYMBOL(dma_sync_single_for_device);8787+8888+void dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg, int nents,8989+ enum dma_data_direction dir)9090+{9191+ int i;9292+9393+ for (i = 0; i < nents; sg++, i++)9494+ dma_sync_single_for_device(dev, sg->dma_address, sg->length, dir);9595+}9696+EXPORT_SYMBOL(dma_sync_sg_for_device);9797+9898+dma_addr_t dma_map_single(struct device *dev, void *addr, size_t size,9999+ enum dma_data_direction dir)100100+{101101+ dma_addr_t handle = virt_to_bus(addr);102102+103103+ dma_sync_single_for_device(dev, handle, size, dir);104104+ return handle;105105+}106106+EXPORT_SYMBOL(dma_map_single);107107+108108+dma_addr_t dma_map_page(struct device *dev, struct page *page,109109+ unsigned long offset, size_t size,110110+ enum dma_data_direction dir)111111+{112112+ dma_addr_t handle = page_to_phys(page) + offset;113113+114114+ dma_sync_single_for_device(dev, handle, size, dir);115115+ return handle;116116+}117117+EXPORT_SYMBOL(dma_map_page);118118+119119+int dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,120120+ enum dma_data_direction dir)121121+{122122+ int i;123123+124124+ for (i = 0; i < nents; sg++, i++) {125125+ sg->dma_address = sg_phys(sg);126126+ dma_sync_single_for_device(dev, sg->dma_address, sg->length, dir);127127+ }128128+ return nents;129129+}130130+EXPORT_SYMBOL(dma_map_sg);
+4-752
arch/m68k/kernel/entry.S
···11-/* -*- mode: asm -*-22- *33- * linux/arch/m68k/kernel/entry.S44- *55- * Copyright (C) 1991, 1992 Linus Torvalds66- *77- * This file is subject to the terms and conditions of the GNU General Public88- * License. See the file README.legal in the main directory of this archive99- * for more details.1010- *1111- * Linux/m68k support by Hamish Macdonald1212- *1313- * 68060 fixes by Jesper Skov1414- *1515- */1616-1717-/*1818- * entry.S contains the system-call and fault low-level handling routines.1919- * This also contains the timer-interrupt handler, as well as all interrupts2020- * and faults that can result in a task-switch.2121- *2222- * NOTE: This code handles signal-recognition, which happens every time2323- * after a timer-interrupt and after each system call.2424- *2525- */2626-2727-/*2828- * 12/03/96 Jes: Currently we only support m68k single-cpu systems, so2929- * all pointers that used to be 'current' are now entry3030- * number 0 in the 'current_set' list.3131- *3232- * 6/05/00 RZ: addedd writeback completion after return from sighandler3333- * for 680403434- */3535-3636-#include <linux/linkage.h>3737-#include <asm/entry.h>3838-#include <asm/errno.h>3939-#include <asm/setup.h>4040-#include <asm/segment.h>4141-#include <asm/traps.h>4242-#include <asm/unistd.h>4343-4444-#include <asm/asm-offsets.h>4545-4646-.globl system_call, buserr, trap, resume4747-.globl sys_call_table4848-.globl sys_fork, sys_clone, sys_vfork4949-.globl ret_from_interrupt, bad_interrupt5050-.globl auto_irqhandler_fixup5151-.globl user_irqvec_fixup, user_irqhandler_fixup5252-5353-.text5454-ENTRY(buserr)5555- SAVE_ALL_INT5656- GET_CURRENT(%d0)5757- movel %sp,%sp@- | stack frame pointer argument5858- bsrl buserr_c5959- addql #4,%sp6060- jra .Lret_from_exception6161-6262-ENTRY(trap)6363- SAVE_ALL_INT6464- GET_CURRENT(%d0)6565- movel %sp,%sp@- | stack frame pointer argument6666- bsrl trap_c6767- addql #4,%sp6868- jra .Lret_from_exception6969-7070- | After a fork we jump here directly from resume,7171- | so that %d1 contains the previous task7272- | schedule_tail now used regardless of CONFIG_SMP7373-ENTRY(ret_from_fork)7474- movel %d1,%sp@-7575- jsr schedule_tail7676- addql #4,%sp7777- jra .Lret_from_exception7878-7979-do_trace_entry:8080- movel #-ENOSYS,%sp@(PT_OFF_D0)| needed for strace8181- subql #4,%sp8282- SAVE_SWITCH_STACK8383- jbsr syscall_trace8484- RESTORE_SWITCH_STACK8585- addql #4,%sp8686- movel %sp@(PT_OFF_ORIG_D0),%d08787- cmpl #NR_syscalls,%d08888- jcs syscall8989-badsys:9090- movel #-ENOSYS,%sp@(PT_OFF_D0)9191- jra ret_from_syscall9292-9393-do_trace_exit:9494- subql #4,%sp9595- SAVE_SWITCH_STACK9696- jbsr syscall_trace9797- RESTORE_SWITCH_STACK9898- addql #4,%sp9999- jra .Lret_from_exception100100-101101-ENTRY(ret_from_signal)102102- tstb %curptr@(TASK_INFO+TINFO_FLAGS+2)103103- jge 1f104104- jbsr syscall_trace105105-1: RESTORE_SWITCH_STACK106106- addql #4,%sp107107-/* on 68040 complete pending writebacks if any */108108-#ifdef CONFIG_M68040109109- bfextu %sp@(PT_OFF_FORMATVEC){#0,#4},%d0110110- subql #7,%d0 | bus error frame ?111111- jbne 1f112112- movel %sp,%sp@-113113- jbsr berr_040cleanup114114- addql #4,%sp115115-1:11+#ifdef CONFIG_MMU22+#include "entry_mm.S"33+#else44+#include "entry_no.S"1165#endif117117- jra .Lret_from_exception118118-119119-ENTRY(system_call)120120- SAVE_ALL_SYS121121-122122- GET_CURRENT(%d1)123123- | save top of frame124124- movel %sp,%curptr@(TASK_THREAD+THREAD_ESP0)125125-126126- | syscall trace?127127- tstb %curptr@(TASK_INFO+TINFO_FLAGS+2)128128- jmi do_trace_entry129129- cmpl #NR_syscalls,%d0130130- jcc badsys131131-syscall:132132- jbsr @(sys_call_table,%d0:l:4)@(0)133133- movel %d0,%sp@(PT_OFF_D0) | save the return value134134-ret_from_syscall:135135- |oriw #0x0700,%sr136136- movew %curptr@(TASK_INFO+TINFO_FLAGS+2),%d0137137- jne syscall_exit_work138138-1: RESTORE_ALL139139-140140-syscall_exit_work:141141- btst #5,%sp@(PT_OFF_SR) | check if returning to kernel142142- bnes 1b | if so, skip resched, signals143143- lslw #1,%d0144144- jcs do_trace_exit145145- jmi do_delayed_trace146146- lslw #8,%d0147147- jmi do_signal_return148148- pea resume_userspace149149- jra schedule150150-151151-152152-ENTRY(ret_from_exception)153153-.Lret_from_exception:154154- btst #5,%sp@(PT_OFF_SR) | check if returning to kernel155155- bnes 1f | if so, skip resched, signals156156- | only allow interrupts when we are really the last one on the157157- | kernel stack, otherwise stack overflow can occur during158158- | heavy interrupt load159159- andw #ALLOWINT,%sr160160-161161-resume_userspace:162162- moveb %curptr@(TASK_INFO+TINFO_FLAGS+3),%d0163163- jne exit_work164164-1: RESTORE_ALL165165-166166-exit_work:167167- | save top of frame168168- movel %sp,%curptr@(TASK_THREAD+THREAD_ESP0)169169- lslb #1,%d0170170- jmi do_signal_return171171- pea resume_userspace172172- jra schedule173173-174174-175175-do_signal_return:176176- |andw #ALLOWINT,%sr177177- subql #4,%sp | dummy return address178178- SAVE_SWITCH_STACK179179- pea %sp@(SWITCH_STACK_SIZE)180180- bsrl do_signal181181- addql #4,%sp182182- RESTORE_SWITCH_STACK183183- addql #4,%sp184184- jbra resume_userspace185185-186186-do_delayed_trace:187187- bclr #7,%sp@(PT_OFF_SR) | clear trace bit in SR188188- pea 1 | send SIGTRAP189189- movel %curptr,%sp@-190190- pea LSIGTRAP191191- jbsr send_sig192192- addql #8,%sp193193- addql #4,%sp194194- jbra resume_userspace195195-196196-197197-/* This is the main interrupt handler for autovector interrupts */198198-199199-ENTRY(auto_inthandler)200200- SAVE_ALL_INT201201- GET_CURRENT(%d0)202202- addqb #1,%curptr@(TASK_INFO+TINFO_PREEMPT+1)203203- | put exception # in d0204204- bfextu %sp@(PT_OFF_FORMATVEC){#4,#10},%d0205205- subw #VEC_SPUR,%d0206206-207207- movel %sp,%sp@-208208- movel %d0,%sp@- | put vector # on stack209209-auto_irqhandler_fixup = . + 2210210- jsr __m68k_handle_int | process the IRQ211211- addql #8,%sp | pop parameters off stack212212-213213-ret_from_interrupt:214214- subqb #1,%curptr@(TASK_INFO+TINFO_PREEMPT+1)215215- jeq ret_from_last_interrupt216216-2: RESTORE_ALL217217-218218- ALIGN219219-ret_from_last_interrupt:220220- moveq #(~ALLOWINT>>8)&0xff,%d0221221- andb %sp@(PT_OFF_SR),%d0222222- jne 2b223223-224224- /* check if we need to do software interrupts */225225- tstl irq_stat+CPUSTAT_SOFTIRQ_PENDING226226- jeq .Lret_from_exception227227- pea ret_from_exception228228- jra do_softirq229229-230230-/* Handler for user defined interrupt vectors */231231-232232-ENTRY(user_inthandler)233233- SAVE_ALL_INT234234- GET_CURRENT(%d0)235235- addqb #1,%curptr@(TASK_INFO+TINFO_PREEMPT+1)236236- | put exception # in d0237237- bfextu %sp@(PT_OFF_FORMATVEC){#4,#10},%d0238238-user_irqvec_fixup = . + 2239239- subw #VEC_USER,%d0240240-241241- movel %sp,%sp@-242242- movel %d0,%sp@- | put vector # on stack243243-user_irqhandler_fixup = . + 2244244- jsr __m68k_handle_int | process the IRQ245245- addql #8,%sp | pop parameters off stack246246-247247- subqb #1,%curptr@(TASK_INFO+TINFO_PREEMPT+1)248248- jeq ret_from_last_interrupt249249- RESTORE_ALL250250-251251-/* Handler for uninitialized and spurious interrupts */252252-253253-ENTRY(bad_inthandler)254254- SAVE_ALL_INT255255- GET_CURRENT(%d0)256256- addqb #1,%curptr@(TASK_INFO+TINFO_PREEMPT+1)257257-258258- movel %sp,%sp@-259259- jsr handle_badint260260- addql #4,%sp261261-262262- subqb #1,%curptr@(TASK_INFO+TINFO_PREEMPT+1)263263- jeq ret_from_last_interrupt264264- RESTORE_ALL265265-266266-267267-ENTRY(sys_fork)268268- SAVE_SWITCH_STACK269269- pea %sp@(SWITCH_STACK_SIZE)270270- jbsr m68k_fork271271- addql #4,%sp272272- RESTORE_SWITCH_STACK273273- rts274274-275275-ENTRY(sys_clone)276276- SAVE_SWITCH_STACK277277- pea %sp@(SWITCH_STACK_SIZE)278278- jbsr m68k_clone279279- addql #4,%sp280280- RESTORE_SWITCH_STACK281281- rts282282-283283-ENTRY(sys_vfork)284284- SAVE_SWITCH_STACK285285- pea %sp@(SWITCH_STACK_SIZE)286286- jbsr m68k_vfork287287- addql #4,%sp288288- RESTORE_SWITCH_STACK289289- rts290290-291291-ENTRY(sys_sigreturn)292292- SAVE_SWITCH_STACK293293- jbsr do_sigreturn294294- RESTORE_SWITCH_STACK295295- rts296296-297297-ENTRY(sys_rt_sigreturn)298298- SAVE_SWITCH_STACK299299- jbsr do_rt_sigreturn300300- RESTORE_SWITCH_STACK301301- rts302302-303303-resume:304304- /*305305- * Beware - when entering resume, prev (the current task) is306306- * in a0, next (the new task) is in a1,so don't change these307307- * registers until their contents are no longer needed.308308- */309309-310310- /* save sr */311311- movew %sr,%a0@(TASK_THREAD+THREAD_SR)312312-313313- /* save fs (sfc,%dfc) (may be pointing to kernel memory) */314314- movec %sfc,%d0315315- movew %d0,%a0@(TASK_THREAD+THREAD_FS)316316-317317- /* save usp */318318- /* it is better to use a movel here instead of a movew 8*) */319319- movec %usp,%d0320320- movel %d0,%a0@(TASK_THREAD+THREAD_USP)321321-322322- /* save non-scratch registers on stack */323323- SAVE_SWITCH_STACK324324-325325- /* save current kernel stack pointer */326326- movel %sp,%a0@(TASK_THREAD+THREAD_KSP)327327-328328- /* save floating point context */329329-#ifndef CONFIG_M68KFPU_EMU_ONLY330330-#ifdef CONFIG_M68KFPU_EMU331331- tstl m68k_fputype332332- jeq 3f333333-#endif334334- fsave %a0@(TASK_THREAD+THREAD_FPSTATE)335335-336336-#if defined(CONFIG_M68060)337337-#if !defined(CPU_M68060_ONLY)338338- btst #3,m68k_cputype+3339339- beqs 1f340340-#endif341341- /* The 060 FPU keeps status in bits 15-8 of the first longword */342342- tstb %a0@(TASK_THREAD+THREAD_FPSTATE+2)343343- jeq 3f344344-#if !defined(CPU_M68060_ONLY)345345- jra 2f346346-#endif347347-#endif /* CONFIG_M68060 */348348-#if !defined(CPU_M68060_ONLY)349349-1: tstb %a0@(TASK_THREAD+THREAD_FPSTATE)350350- jeq 3f351351-#endif352352-2: fmovemx %fp0-%fp7,%a0@(TASK_THREAD+THREAD_FPREG)353353- fmoveml %fpcr/%fpsr/%fpiar,%a0@(TASK_THREAD+THREAD_FPCNTL)354354-3:355355-#endif /* CONFIG_M68KFPU_EMU_ONLY */356356- /* Return previous task in %d1 */357357- movel %curptr,%d1358358-359359- /* switch to new task (a1 contains new task) */360360- movel %a1,%curptr361361-362362- /* restore floating point context */363363-#ifndef CONFIG_M68KFPU_EMU_ONLY364364-#ifdef CONFIG_M68KFPU_EMU365365- tstl m68k_fputype366366- jeq 4f367367-#endif368368-#if defined(CONFIG_M68060)369369-#if !defined(CPU_M68060_ONLY)370370- btst #3,m68k_cputype+3371371- beqs 1f372372-#endif373373- /* The 060 FPU keeps status in bits 15-8 of the first longword */374374- tstb %a1@(TASK_THREAD+THREAD_FPSTATE+2)375375- jeq 3f376376-#if !defined(CPU_M68060_ONLY)377377- jra 2f378378-#endif379379-#endif /* CONFIG_M68060 */380380-#if !defined(CPU_M68060_ONLY)381381-1: tstb %a1@(TASK_THREAD+THREAD_FPSTATE)382382- jeq 3f383383-#endif384384-2: fmovemx %a1@(TASK_THREAD+THREAD_FPREG),%fp0-%fp7385385- fmoveml %a1@(TASK_THREAD+THREAD_FPCNTL),%fpcr/%fpsr/%fpiar386386-3: frestore %a1@(TASK_THREAD+THREAD_FPSTATE)387387-4:388388-#endif /* CONFIG_M68KFPU_EMU_ONLY */389389-390390- /* restore the kernel stack pointer */391391- movel %a1@(TASK_THREAD+THREAD_KSP),%sp392392-393393- /* restore non-scratch registers */394394- RESTORE_SWITCH_STACK395395-396396- /* restore user stack pointer */397397- movel %a1@(TASK_THREAD+THREAD_USP),%a0398398- movel %a0,%usp399399-400400- /* restore fs (sfc,%dfc) */401401- movew %a1@(TASK_THREAD+THREAD_FS),%a0402402- movec %a0,%sfc403403- movec %a0,%dfc404404-405405- /* restore status register */406406- movew %a1@(TASK_THREAD+THREAD_SR),%sr407407-408408- rts409409-410410-.data411411-ALIGN412412-sys_call_table:413413- .long sys_restart_syscall /* 0 - old "setup()" system call, used for restarting */414414- .long sys_exit415415- .long sys_fork416416- .long sys_read417417- .long sys_write418418- .long sys_open /* 5 */419419- .long sys_close420420- .long sys_waitpid421421- .long sys_creat422422- .long sys_link423423- .long sys_unlink /* 10 */424424- .long sys_execve425425- .long sys_chdir426426- .long sys_time427427- .long sys_mknod428428- .long sys_chmod /* 15 */429429- .long sys_chown16430430- .long sys_ni_syscall /* old break syscall holder */431431- .long sys_stat432432- .long sys_lseek433433- .long sys_getpid /* 20 */434434- .long sys_mount435435- .long sys_oldumount436436- .long sys_setuid16437437- .long sys_getuid16438438- .long sys_stime /* 25 */439439- .long sys_ptrace440440- .long sys_alarm441441- .long sys_fstat442442- .long sys_pause443443- .long sys_utime /* 30 */444444- .long sys_ni_syscall /* old stty syscall holder */445445- .long sys_ni_syscall /* old gtty syscall holder */446446- .long sys_access447447- .long sys_nice448448- .long sys_ni_syscall /* 35 */ /* old ftime syscall holder */449449- .long sys_sync450450- .long sys_kill451451- .long sys_rename452452- .long sys_mkdir453453- .long sys_rmdir /* 40 */454454- .long sys_dup455455- .long sys_pipe456456- .long sys_times457457- .long sys_ni_syscall /* old prof syscall holder */458458- .long sys_brk /* 45 */459459- .long sys_setgid16460460- .long sys_getgid16461461- .long sys_signal462462- .long sys_geteuid16463463- .long sys_getegid16 /* 50 */464464- .long sys_acct465465- .long sys_umount /* recycled never used phys() */466466- .long sys_ni_syscall /* old lock syscall holder */467467- .long sys_ioctl468468- .long sys_fcntl /* 55 */469469- .long sys_ni_syscall /* old mpx syscall holder */470470- .long sys_setpgid471471- .long sys_ni_syscall /* old ulimit syscall holder */472472- .long sys_ni_syscall473473- .long sys_umask /* 60 */474474- .long sys_chroot475475- .long sys_ustat476476- .long sys_dup2477477- .long sys_getppid478478- .long sys_getpgrp /* 65 */479479- .long sys_setsid480480- .long sys_sigaction481481- .long sys_sgetmask482482- .long sys_ssetmask483483- .long sys_setreuid16 /* 70 */484484- .long sys_setregid16485485- .long sys_sigsuspend486486- .long sys_sigpending487487- .long sys_sethostname488488- .long sys_setrlimit /* 75 */489489- .long sys_old_getrlimit490490- .long sys_getrusage491491- .long sys_gettimeofday492492- .long sys_settimeofday493493- .long sys_getgroups16 /* 80 */494494- .long sys_setgroups16495495- .long sys_old_select496496- .long sys_symlink497497- .long sys_lstat498498- .long sys_readlink /* 85 */499499- .long sys_uselib500500- .long sys_swapon501501- .long sys_reboot502502- .long sys_old_readdir503503- .long sys_old_mmap /* 90 */504504- .long sys_munmap505505- .long sys_truncate506506- .long sys_ftruncate507507- .long sys_fchmod508508- .long sys_fchown16 /* 95 */509509- .long sys_getpriority510510- .long sys_setpriority511511- .long sys_ni_syscall /* old profil syscall holder */512512- .long sys_statfs513513- .long sys_fstatfs /* 100 */514514- .long sys_ni_syscall /* ioperm for i386 */515515- .long sys_socketcall516516- .long sys_syslog517517- .long sys_setitimer518518- .long sys_getitimer /* 105 */519519- .long sys_newstat520520- .long sys_newlstat521521- .long sys_newfstat522522- .long sys_ni_syscall523523- .long sys_ni_syscall /* 110 */ /* iopl for i386 */524524- .long sys_vhangup525525- .long sys_ni_syscall /* obsolete idle() syscall */526526- .long sys_ni_syscall /* vm86old for i386 */527527- .long sys_wait4528528- .long sys_swapoff /* 115 */529529- .long sys_sysinfo530530- .long sys_ipc531531- .long sys_fsync532532- .long sys_sigreturn533533- .long sys_clone /* 120 */534534- .long sys_setdomainname535535- .long sys_newuname536536- .long sys_cacheflush /* modify_ldt for i386 */537537- .long sys_adjtimex538538- .long sys_mprotect /* 125 */539539- .long sys_sigprocmask540540- .long sys_ni_syscall /* old "create_module" */541541- .long sys_init_module542542- .long sys_delete_module543543- .long sys_ni_syscall /* 130 - old "get_kernel_syms" */544544- .long sys_quotactl545545- .long sys_getpgid546546- .long sys_fchdir547547- .long sys_bdflush548548- .long sys_sysfs /* 135 */549549- .long sys_personality550550- .long sys_ni_syscall /* for afs_syscall */551551- .long sys_setfsuid16552552- .long sys_setfsgid16553553- .long sys_llseek /* 140 */554554- .long sys_getdents555555- .long sys_select556556- .long sys_flock557557- .long sys_msync558558- .long sys_readv /* 145 */559559- .long sys_writev560560- .long sys_getsid561561- .long sys_fdatasync562562- .long sys_sysctl563563- .long sys_mlock /* 150 */564564- .long sys_munlock565565- .long sys_mlockall566566- .long sys_munlockall567567- .long sys_sched_setparam568568- .long sys_sched_getparam /* 155 */569569- .long sys_sched_setscheduler570570- .long sys_sched_getscheduler571571- .long sys_sched_yield572572- .long sys_sched_get_priority_max573573- .long sys_sched_get_priority_min /* 160 */574574- .long sys_sched_rr_get_interval575575- .long sys_nanosleep576576- .long sys_mremap577577- .long sys_setresuid16578578- .long sys_getresuid16 /* 165 */579579- .long sys_getpagesize580580- .long sys_ni_syscall /* old sys_query_module */581581- .long sys_poll582582- .long sys_nfsservctl583583- .long sys_setresgid16 /* 170 */584584- .long sys_getresgid16585585- .long sys_prctl586586- .long sys_rt_sigreturn587587- .long sys_rt_sigaction588588- .long sys_rt_sigprocmask /* 175 */589589- .long sys_rt_sigpending590590- .long sys_rt_sigtimedwait591591- .long sys_rt_sigqueueinfo592592- .long sys_rt_sigsuspend593593- .long sys_pread64 /* 180 */594594- .long sys_pwrite64595595- .long sys_lchown16;596596- .long sys_getcwd597597- .long sys_capget598598- .long sys_capset /* 185 */599599- .long sys_sigaltstack600600- .long sys_sendfile601601- .long sys_ni_syscall /* streams1 */602602- .long sys_ni_syscall /* streams2 */603603- .long sys_vfork /* 190 */604604- .long sys_getrlimit605605- .long sys_mmap2606606- .long sys_truncate64607607- .long sys_ftruncate64608608- .long sys_stat64 /* 195 */609609- .long sys_lstat64610610- .long sys_fstat64611611- .long sys_chown612612- .long sys_getuid613613- .long sys_getgid /* 200 */614614- .long sys_geteuid615615- .long sys_getegid616616- .long sys_setreuid617617- .long sys_setregid618618- .long sys_getgroups /* 205 */619619- .long sys_setgroups620620- .long sys_fchown621621- .long sys_setresuid622622- .long sys_getresuid623623- .long sys_setresgid /* 210 */624624- .long sys_getresgid625625- .long sys_lchown626626- .long sys_setuid627627- .long sys_setgid628628- .long sys_setfsuid /* 215 */629629- .long sys_setfsgid630630- .long sys_pivot_root631631- .long sys_ni_syscall632632- .long sys_ni_syscall633633- .long sys_getdents64 /* 220 */634634- .long sys_gettid635635- .long sys_tkill636636- .long sys_setxattr637637- .long sys_lsetxattr638638- .long sys_fsetxattr /* 225 */639639- .long sys_getxattr640640- .long sys_lgetxattr641641- .long sys_fgetxattr642642- .long sys_listxattr643643- .long sys_llistxattr /* 230 */644644- .long sys_flistxattr645645- .long sys_removexattr646646- .long sys_lremovexattr647647- .long sys_fremovexattr648648- .long sys_futex /* 235 */649649- .long sys_sendfile64650650- .long sys_mincore651651- .long sys_madvise652652- .long sys_fcntl64653653- .long sys_readahead /* 240 */654654- .long sys_io_setup655655- .long sys_io_destroy656656- .long sys_io_getevents657657- .long sys_io_submit658658- .long sys_io_cancel /* 245 */659659- .long sys_fadvise64660660- .long sys_exit_group661661- .long sys_lookup_dcookie662662- .long sys_epoll_create663663- .long sys_epoll_ctl /* 250 */664664- .long sys_epoll_wait665665- .long sys_remap_file_pages666666- .long sys_set_tid_address667667- .long sys_timer_create668668- .long sys_timer_settime /* 255 */669669- .long sys_timer_gettime670670- .long sys_timer_getoverrun671671- .long sys_timer_delete672672- .long sys_clock_settime673673- .long sys_clock_gettime /* 260 */674674- .long sys_clock_getres675675- .long sys_clock_nanosleep676676- .long sys_statfs64677677- .long sys_fstatfs64678678- .long sys_tgkill /* 265 */679679- .long sys_utimes680680- .long sys_fadvise64_64681681- .long sys_mbind682682- .long sys_get_mempolicy683683- .long sys_set_mempolicy /* 270 */684684- .long sys_mq_open685685- .long sys_mq_unlink686686- .long sys_mq_timedsend687687- .long sys_mq_timedreceive688688- .long sys_mq_notify /* 275 */689689- .long sys_mq_getsetattr690690- .long sys_waitid691691- .long sys_ni_syscall /* for sys_vserver */692692- .long sys_add_key693693- .long sys_request_key /* 280 */694694- .long sys_keyctl695695- .long sys_ioprio_set696696- .long sys_ioprio_get697697- .long sys_inotify_init698698- .long sys_inotify_add_watch /* 285 */699699- .long sys_inotify_rm_watch700700- .long sys_migrate_pages701701- .long sys_openat702702- .long sys_mkdirat703703- .long sys_mknodat /* 290 */704704- .long sys_fchownat705705- .long sys_futimesat706706- .long sys_fstatat64707707- .long sys_unlinkat708708- .long sys_renameat /* 295 */709709- .long sys_linkat710710- .long sys_symlinkat711711- .long sys_readlinkat712712- .long sys_fchmodat713713- .long sys_faccessat /* 300 */714714- .long sys_ni_syscall /* Reserved for pselect6 */715715- .long sys_ni_syscall /* Reserved for ppoll */716716- .long sys_unshare717717- .long sys_set_robust_list718718- .long sys_get_robust_list /* 305 */719719- .long sys_splice720720- .long sys_sync_file_range721721- .long sys_tee722722- .long sys_vmsplice723723- .long sys_move_pages /* 310 */724724- .long sys_sched_setaffinity725725- .long sys_sched_getaffinity726726- .long sys_kexec_load727727- .long sys_getcpu728728- .long sys_epoll_pwait /* 315 */729729- .long sys_utimensat730730- .long sys_signalfd731731- .long sys_timerfd_create732732- .long sys_eventfd733733- .long sys_fallocate /* 320 */734734- .long sys_timerfd_settime735735- .long sys_timerfd_gettime736736- .long sys_signalfd4737737- .long sys_eventfd2738738- .long sys_epoll_create1 /* 325 */739739- .long sys_dup3740740- .long sys_pipe2741741- .long sys_inotify_init1742742- .long sys_preadv743743- .long sys_pwritev /* 330 */744744- .long sys_rt_tgsigqueueinfo745745- .long sys_perf_event_open746746- .long sys_get_thread_area747747- .long sys_set_thread_area748748- .long sys_atomic_cmpxchg_32 /* 335 */749749- .long sys_atomic_barrier750750- .long sys_fanotify_init751751- .long sys_fanotify_mark752752- .long sys_prlimit64753753-
+753
arch/m68k/kernel/entry_mm.S
···11+/* -*- mode: asm -*-22+ *33+ * linux/arch/m68k/kernel/entry.S44+ *55+ * Copyright (C) 1991, 1992 Linus Torvalds66+ *77+ * This file is subject to the terms and conditions of the GNU General Public88+ * License. See the file README.legal in the main directory of this archive99+ * for more details.1010+ *1111+ * Linux/m68k support by Hamish Macdonald1212+ *1313+ * 68060 fixes by Jesper Skov1414+ *1515+ */1616+1717+/*1818+ * entry.S contains the system-call and fault low-level handling routines.1919+ * This also contains the timer-interrupt handler, as well as all interrupts2020+ * and faults that can result in a task-switch.2121+ *2222+ * NOTE: This code handles signal-recognition, which happens every time2323+ * after a timer-interrupt and after each system call.2424+ *2525+ */2626+2727+/*2828+ * 12/03/96 Jes: Currently we only support m68k single-cpu systems, so2929+ * all pointers that used to be 'current' are now entry3030+ * number 0 in the 'current_set' list.3131+ *3232+ * 6/05/00 RZ: addedd writeback completion after return from sighandler3333+ * for 680403434+ */3535+3636+#include <linux/linkage.h>3737+#include <asm/entry.h>3838+#include <asm/errno.h>3939+#include <asm/setup.h>4040+#include <asm/segment.h>4141+#include <asm/traps.h>4242+#include <asm/unistd.h>4343+4444+#include <asm/asm-offsets.h>4545+4646+.globl system_call, buserr, trap, resume4747+.globl sys_call_table4848+.globl sys_fork, sys_clone, sys_vfork4949+.globl ret_from_interrupt, bad_interrupt5050+.globl auto_irqhandler_fixup5151+.globl user_irqvec_fixup, user_irqhandler_fixup5252+5353+.text5454+ENTRY(buserr)5555+ SAVE_ALL_INT5656+ GET_CURRENT(%d0)5757+ movel %sp,%sp@- | stack frame pointer argument5858+ bsrl buserr_c5959+ addql #4,%sp6060+ jra .Lret_from_exception6161+6262+ENTRY(trap)6363+ SAVE_ALL_INT6464+ GET_CURRENT(%d0)6565+ movel %sp,%sp@- | stack frame pointer argument6666+ bsrl trap_c6767+ addql #4,%sp6868+ jra .Lret_from_exception6969+7070+ | After a fork we jump here directly from resume,7171+ | so that %d1 contains the previous task7272+ | schedule_tail now used regardless of CONFIG_SMP7373+ENTRY(ret_from_fork)7474+ movel %d1,%sp@-7575+ jsr schedule_tail7676+ addql #4,%sp7777+ jra .Lret_from_exception7878+7979+do_trace_entry:8080+ movel #-ENOSYS,%sp@(PT_OFF_D0)| needed for strace8181+ subql #4,%sp8282+ SAVE_SWITCH_STACK8383+ jbsr syscall_trace8484+ RESTORE_SWITCH_STACK8585+ addql #4,%sp8686+ movel %sp@(PT_OFF_ORIG_D0),%d08787+ cmpl #NR_syscalls,%d08888+ jcs syscall8989+badsys:9090+ movel #-ENOSYS,%sp@(PT_OFF_D0)9191+ jra ret_from_syscall9292+9393+do_trace_exit:9494+ subql #4,%sp9595+ SAVE_SWITCH_STACK9696+ jbsr syscall_trace9797+ RESTORE_SWITCH_STACK9898+ addql #4,%sp9999+ jra .Lret_from_exception100100+101101+ENTRY(ret_from_signal)102102+ tstb %curptr@(TASK_INFO+TINFO_FLAGS+2)103103+ jge 1f104104+ jbsr syscall_trace105105+1: RESTORE_SWITCH_STACK106106+ addql #4,%sp107107+/* on 68040 complete pending writebacks if any */108108+#ifdef CONFIG_M68040109109+ bfextu %sp@(PT_OFF_FORMATVEC){#0,#4},%d0110110+ subql #7,%d0 | bus error frame ?111111+ jbne 1f112112+ movel %sp,%sp@-113113+ jbsr berr_040cleanup114114+ addql #4,%sp115115+1:116116+#endif117117+ jra .Lret_from_exception118118+119119+ENTRY(system_call)120120+ SAVE_ALL_SYS121121+122122+ GET_CURRENT(%d1)123123+ | save top of frame124124+ movel %sp,%curptr@(TASK_THREAD+THREAD_ESP0)125125+126126+ | syscall trace?127127+ tstb %curptr@(TASK_INFO+TINFO_FLAGS+2)128128+ jmi do_trace_entry129129+ cmpl #NR_syscalls,%d0130130+ jcc badsys131131+syscall:132132+ jbsr @(sys_call_table,%d0:l:4)@(0)133133+ movel %d0,%sp@(PT_OFF_D0) | save the return value134134+ret_from_syscall:135135+ |oriw #0x0700,%sr136136+ movew %curptr@(TASK_INFO+TINFO_FLAGS+2),%d0137137+ jne syscall_exit_work138138+1: RESTORE_ALL139139+140140+syscall_exit_work:141141+ btst #5,%sp@(PT_OFF_SR) | check if returning to kernel142142+ bnes 1b | if so, skip resched, signals143143+ lslw #1,%d0144144+ jcs do_trace_exit145145+ jmi do_delayed_trace146146+ lslw #8,%d0147147+ jmi do_signal_return148148+ pea resume_userspace149149+ jra schedule150150+151151+152152+ENTRY(ret_from_exception)153153+.Lret_from_exception:154154+ btst #5,%sp@(PT_OFF_SR) | check if returning to kernel155155+ bnes 1f | if so, skip resched, signals156156+ | only allow interrupts when we are really the last one on the157157+ | kernel stack, otherwise stack overflow can occur during158158+ | heavy interrupt load159159+ andw #ALLOWINT,%sr160160+161161+resume_userspace:162162+ moveb %curptr@(TASK_INFO+TINFO_FLAGS+3),%d0163163+ jne exit_work164164+1: RESTORE_ALL165165+166166+exit_work:167167+ | save top of frame168168+ movel %sp,%curptr@(TASK_THREAD+THREAD_ESP0)169169+ lslb #1,%d0170170+ jmi do_signal_return171171+ pea resume_userspace172172+ jra schedule173173+174174+175175+do_signal_return:176176+ |andw #ALLOWINT,%sr177177+ subql #4,%sp | dummy return address178178+ SAVE_SWITCH_STACK179179+ pea %sp@(SWITCH_STACK_SIZE)180180+ bsrl do_signal181181+ addql #4,%sp182182+ RESTORE_SWITCH_STACK183183+ addql #4,%sp184184+ jbra resume_userspace185185+186186+do_delayed_trace:187187+ bclr #7,%sp@(PT_OFF_SR) | clear trace bit in SR188188+ pea 1 | send SIGTRAP189189+ movel %curptr,%sp@-190190+ pea LSIGTRAP191191+ jbsr send_sig192192+ addql #8,%sp193193+ addql #4,%sp194194+ jbra resume_userspace195195+196196+197197+/* This is the main interrupt handler for autovector interrupts */198198+199199+ENTRY(auto_inthandler)200200+ SAVE_ALL_INT201201+ GET_CURRENT(%d0)202202+ addqb #1,%curptr@(TASK_INFO+TINFO_PREEMPT+1)203203+ | put exception # in d0204204+ bfextu %sp@(PT_OFF_FORMATVEC){#4,#10},%d0205205+ subw #VEC_SPUR,%d0206206+207207+ movel %sp,%sp@-208208+ movel %d0,%sp@- | put vector # on stack209209+auto_irqhandler_fixup = . + 2210210+ jsr __m68k_handle_int | process the IRQ211211+ addql #8,%sp | pop parameters off stack212212+213213+ret_from_interrupt:214214+ subqb #1,%curptr@(TASK_INFO+TINFO_PREEMPT+1)215215+ jeq ret_from_last_interrupt216216+2: RESTORE_ALL217217+218218+ ALIGN219219+ret_from_last_interrupt:220220+ moveq #(~ALLOWINT>>8)&0xff,%d0221221+ andb %sp@(PT_OFF_SR),%d0222222+ jne 2b223223+224224+ /* check if we need to do software interrupts */225225+ tstl irq_stat+CPUSTAT_SOFTIRQ_PENDING226226+ jeq .Lret_from_exception227227+ pea ret_from_exception228228+ jra do_softirq229229+230230+/* Handler for user defined interrupt vectors */231231+232232+ENTRY(user_inthandler)233233+ SAVE_ALL_INT234234+ GET_CURRENT(%d0)235235+ addqb #1,%curptr@(TASK_INFO+TINFO_PREEMPT+1)236236+ | put exception # in d0237237+ bfextu %sp@(PT_OFF_FORMATVEC){#4,#10},%d0238238+user_irqvec_fixup = . + 2239239+ subw #VEC_USER,%d0240240+241241+ movel %sp,%sp@-242242+ movel %d0,%sp@- | put vector # on stack243243+user_irqhandler_fixup = . + 2244244+ jsr __m68k_handle_int | process the IRQ245245+ addql #8,%sp | pop parameters off stack246246+247247+ subqb #1,%curptr@(TASK_INFO+TINFO_PREEMPT+1)248248+ jeq ret_from_last_interrupt249249+ RESTORE_ALL250250+251251+/* Handler for uninitialized and spurious interrupts */252252+253253+ENTRY(bad_inthandler)254254+ SAVE_ALL_INT255255+ GET_CURRENT(%d0)256256+ addqb #1,%curptr@(TASK_INFO+TINFO_PREEMPT+1)257257+258258+ movel %sp,%sp@-259259+ jsr handle_badint260260+ addql #4,%sp261261+262262+ subqb #1,%curptr@(TASK_INFO+TINFO_PREEMPT+1)263263+ jeq ret_from_last_interrupt264264+ RESTORE_ALL265265+266266+267267+ENTRY(sys_fork)268268+ SAVE_SWITCH_STACK269269+ pea %sp@(SWITCH_STACK_SIZE)270270+ jbsr m68k_fork271271+ addql #4,%sp272272+ RESTORE_SWITCH_STACK273273+ rts274274+275275+ENTRY(sys_clone)276276+ SAVE_SWITCH_STACK277277+ pea %sp@(SWITCH_STACK_SIZE)278278+ jbsr m68k_clone279279+ addql #4,%sp280280+ RESTORE_SWITCH_STACK281281+ rts282282+283283+ENTRY(sys_vfork)284284+ SAVE_SWITCH_STACK285285+ pea %sp@(SWITCH_STACK_SIZE)286286+ jbsr m68k_vfork287287+ addql #4,%sp288288+ RESTORE_SWITCH_STACK289289+ rts290290+291291+ENTRY(sys_sigreturn)292292+ SAVE_SWITCH_STACK293293+ jbsr do_sigreturn294294+ RESTORE_SWITCH_STACK295295+ rts296296+297297+ENTRY(sys_rt_sigreturn)298298+ SAVE_SWITCH_STACK299299+ jbsr do_rt_sigreturn300300+ RESTORE_SWITCH_STACK301301+ rts302302+303303+resume:304304+ /*305305+ * Beware - when entering resume, prev (the current task) is306306+ * in a0, next (the new task) is in a1,so don't change these307307+ * registers until their contents are no longer needed.308308+ */309309+310310+ /* save sr */311311+ movew %sr,%a0@(TASK_THREAD+THREAD_SR)312312+313313+ /* save fs (sfc,%dfc) (may be pointing to kernel memory) */314314+ movec %sfc,%d0315315+ movew %d0,%a0@(TASK_THREAD+THREAD_FS)316316+317317+ /* save usp */318318+ /* it is better to use a movel here instead of a movew 8*) */319319+ movec %usp,%d0320320+ movel %d0,%a0@(TASK_THREAD+THREAD_USP)321321+322322+ /* save non-scratch registers on stack */323323+ SAVE_SWITCH_STACK324324+325325+ /* save current kernel stack pointer */326326+ movel %sp,%a0@(TASK_THREAD+THREAD_KSP)327327+328328+ /* save floating point context */329329+#ifndef CONFIG_M68KFPU_EMU_ONLY330330+#ifdef CONFIG_M68KFPU_EMU331331+ tstl m68k_fputype332332+ jeq 3f333333+#endif334334+ fsave %a0@(TASK_THREAD+THREAD_FPSTATE)335335+336336+#if defined(CONFIG_M68060)337337+#if !defined(CPU_M68060_ONLY)338338+ btst #3,m68k_cputype+3339339+ beqs 1f340340+#endif341341+ /* The 060 FPU keeps status in bits 15-8 of the first longword */342342+ tstb %a0@(TASK_THREAD+THREAD_FPSTATE+2)343343+ jeq 3f344344+#if !defined(CPU_M68060_ONLY)345345+ jra 2f346346+#endif347347+#endif /* CONFIG_M68060 */348348+#if !defined(CPU_M68060_ONLY)349349+1: tstb %a0@(TASK_THREAD+THREAD_FPSTATE)350350+ jeq 3f351351+#endif352352+2: fmovemx %fp0-%fp7,%a0@(TASK_THREAD+THREAD_FPREG)353353+ fmoveml %fpcr/%fpsr/%fpiar,%a0@(TASK_THREAD+THREAD_FPCNTL)354354+3:355355+#endif /* CONFIG_M68KFPU_EMU_ONLY */356356+ /* Return previous task in %d1 */357357+ movel %curptr,%d1358358+359359+ /* switch to new task (a1 contains new task) */360360+ movel %a1,%curptr361361+362362+ /* restore floating point context */363363+#ifndef CONFIG_M68KFPU_EMU_ONLY364364+#ifdef CONFIG_M68KFPU_EMU365365+ tstl m68k_fputype366366+ jeq 4f367367+#endif368368+#if defined(CONFIG_M68060)369369+#if !defined(CPU_M68060_ONLY)370370+ btst #3,m68k_cputype+3371371+ beqs 1f372372+#endif373373+ /* The 060 FPU keeps status in bits 15-8 of the first longword */374374+ tstb %a1@(TASK_THREAD+THREAD_FPSTATE+2)375375+ jeq 3f376376+#if !defined(CPU_M68060_ONLY)377377+ jra 2f378378+#endif379379+#endif /* CONFIG_M68060 */380380+#if !defined(CPU_M68060_ONLY)381381+1: tstb %a1@(TASK_THREAD+THREAD_FPSTATE)382382+ jeq 3f383383+#endif384384+2: fmovemx %a1@(TASK_THREAD+THREAD_FPREG),%fp0-%fp7385385+ fmoveml %a1@(TASK_THREAD+THREAD_FPCNTL),%fpcr/%fpsr/%fpiar386386+3: frestore %a1@(TASK_THREAD+THREAD_FPSTATE)387387+4:388388+#endif /* CONFIG_M68KFPU_EMU_ONLY */389389+390390+ /* restore the kernel stack pointer */391391+ movel %a1@(TASK_THREAD+THREAD_KSP),%sp392392+393393+ /* restore non-scratch registers */394394+ RESTORE_SWITCH_STACK395395+396396+ /* restore user stack pointer */397397+ movel %a1@(TASK_THREAD+THREAD_USP),%a0398398+ movel %a0,%usp399399+400400+ /* restore fs (sfc,%dfc) */401401+ movew %a1@(TASK_THREAD+THREAD_FS),%a0402402+ movec %a0,%sfc403403+ movec %a0,%dfc404404+405405+ /* restore status register */406406+ movew %a1@(TASK_THREAD+THREAD_SR),%sr407407+408408+ rts409409+410410+.data411411+ALIGN412412+sys_call_table:413413+ .long sys_restart_syscall /* 0 - old "setup()" system call, used for restarting */414414+ .long sys_exit415415+ .long sys_fork416416+ .long sys_read417417+ .long sys_write418418+ .long sys_open /* 5 */419419+ .long sys_close420420+ .long sys_waitpid421421+ .long sys_creat422422+ .long sys_link423423+ .long sys_unlink /* 10 */424424+ .long sys_execve425425+ .long sys_chdir426426+ .long sys_time427427+ .long sys_mknod428428+ .long sys_chmod /* 15 */429429+ .long sys_chown16430430+ .long sys_ni_syscall /* old break syscall holder */431431+ .long sys_stat432432+ .long sys_lseek433433+ .long sys_getpid /* 20 */434434+ .long sys_mount435435+ .long sys_oldumount436436+ .long sys_setuid16437437+ .long sys_getuid16438438+ .long sys_stime /* 25 */439439+ .long sys_ptrace440440+ .long sys_alarm441441+ .long sys_fstat442442+ .long sys_pause443443+ .long sys_utime /* 30 */444444+ .long sys_ni_syscall /* old stty syscall holder */445445+ .long sys_ni_syscall /* old gtty syscall holder */446446+ .long sys_access447447+ .long sys_nice448448+ .long sys_ni_syscall /* 35 */ /* old ftime syscall holder */449449+ .long sys_sync450450+ .long sys_kill451451+ .long sys_rename452452+ .long sys_mkdir453453+ .long sys_rmdir /* 40 */454454+ .long sys_dup455455+ .long sys_pipe456456+ .long sys_times457457+ .long sys_ni_syscall /* old prof syscall holder */458458+ .long sys_brk /* 45 */459459+ .long sys_setgid16460460+ .long sys_getgid16461461+ .long sys_signal462462+ .long sys_geteuid16463463+ .long sys_getegid16 /* 50 */464464+ .long sys_acct465465+ .long sys_umount /* recycled never used phys() */466466+ .long sys_ni_syscall /* old lock syscall holder */467467+ .long sys_ioctl468468+ .long sys_fcntl /* 55 */469469+ .long sys_ni_syscall /* old mpx syscall holder */470470+ .long sys_setpgid471471+ .long sys_ni_syscall /* old ulimit syscall holder */472472+ .long sys_ni_syscall473473+ .long sys_umask /* 60 */474474+ .long sys_chroot475475+ .long sys_ustat476476+ .long sys_dup2477477+ .long sys_getppid478478+ .long sys_getpgrp /* 65 */479479+ .long sys_setsid480480+ .long sys_sigaction481481+ .long sys_sgetmask482482+ .long sys_ssetmask483483+ .long sys_setreuid16 /* 70 */484484+ .long sys_setregid16485485+ .long sys_sigsuspend486486+ .long sys_sigpending487487+ .long sys_sethostname488488+ .long sys_setrlimit /* 75 */489489+ .long sys_old_getrlimit490490+ .long sys_getrusage491491+ .long sys_gettimeofday492492+ .long sys_settimeofday493493+ .long sys_getgroups16 /* 80 */494494+ .long sys_setgroups16495495+ .long sys_old_select496496+ .long sys_symlink497497+ .long sys_lstat498498+ .long sys_readlink /* 85 */499499+ .long sys_uselib500500+ .long sys_swapon501501+ .long sys_reboot502502+ .long sys_old_readdir503503+ .long sys_old_mmap /* 90 */504504+ .long sys_munmap505505+ .long sys_truncate506506+ .long sys_ftruncate507507+ .long sys_fchmod508508+ .long sys_fchown16 /* 95 */509509+ .long sys_getpriority510510+ .long sys_setpriority511511+ .long sys_ni_syscall /* old profil syscall holder */512512+ .long sys_statfs513513+ .long sys_fstatfs /* 100 */514514+ .long sys_ni_syscall /* ioperm for i386 */515515+ .long sys_socketcall516516+ .long sys_syslog517517+ .long sys_setitimer518518+ .long sys_getitimer /* 105 */519519+ .long sys_newstat520520+ .long sys_newlstat521521+ .long sys_newfstat522522+ .long sys_ni_syscall523523+ .long sys_ni_syscall /* 110 */ /* iopl for i386 */524524+ .long sys_vhangup525525+ .long sys_ni_syscall /* obsolete idle() syscall */526526+ .long sys_ni_syscall /* vm86old for i386 */527527+ .long sys_wait4528528+ .long sys_swapoff /* 115 */529529+ .long sys_sysinfo530530+ .long sys_ipc531531+ .long sys_fsync532532+ .long sys_sigreturn533533+ .long sys_clone /* 120 */534534+ .long sys_setdomainname535535+ .long sys_newuname536536+ .long sys_cacheflush /* modify_ldt for i386 */537537+ .long sys_adjtimex538538+ .long sys_mprotect /* 125 */539539+ .long sys_sigprocmask540540+ .long sys_ni_syscall /* old "create_module" */541541+ .long sys_init_module542542+ .long sys_delete_module543543+ .long sys_ni_syscall /* 130 - old "get_kernel_syms" */544544+ .long sys_quotactl545545+ .long sys_getpgid546546+ .long sys_fchdir547547+ .long sys_bdflush548548+ .long sys_sysfs /* 135 */549549+ .long sys_personality550550+ .long sys_ni_syscall /* for afs_syscall */551551+ .long sys_setfsuid16552552+ .long sys_setfsgid16553553+ .long sys_llseek /* 140 */554554+ .long sys_getdents555555+ .long sys_select556556+ .long sys_flock557557+ .long sys_msync558558+ .long sys_readv /* 145 */559559+ .long sys_writev560560+ .long sys_getsid561561+ .long sys_fdatasync562562+ .long sys_sysctl563563+ .long sys_mlock /* 150 */564564+ .long sys_munlock565565+ .long sys_mlockall566566+ .long sys_munlockall567567+ .long sys_sched_setparam568568+ .long sys_sched_getparam /* 155 */569569+ .long sys_sched_setscheduler570570+ .long sys_sched_getscheduler571571+ .long sys_sched_yield572572+ .long sys_sched_get_priority_max573573+ .long sys_sched_get_priority_min /* 160 */574574+ .long sys_sched_rr_get_interval575575+ .long sys_nanosleep576576+ .long sys_mremap577577+ .long sys_setresuid16578578+ .long sys_getresuid16 /* 165 */579579+ .long sys_getpagesize580580+ .long sys_ni_syscall /* old sys_query_module */581581+ .long sys_poll582582+ .long sys_nfsservctl583583+ .long sys_setresgid16 /* 170 */584584+ .long sys_getresgid16585585+ .long sys_prctl586586+ .long sys_rt_sigreturn587587+ .long sys_rt_sigaction588588+ .long sys_rt_sigprocmask /* 175 */589589+ .long sys_rt_sigpending590590+ .long sys_rt_sigtimedwait591591+ .long sys_rt_sigqueueinfo592592+ .long sys_rt_sigsuspend593593+ .long sys_pread64 /* 180 */594594+ .long sys_pwrite64595595+ .long sys_lchown16;596596+ .long sys_getcwd597597+ .long sys_capget598598+ .long sys_capset /* 185 */599599+ .long sys_sigaltstack600600+ .long sys_sendfile601601+ .long sys_ni_syscall /* streams1 */602602+ .long sys_ni_syscall /* streams2 */603603+ .long sys_vfork /* 190 */604604+ .long sys_getrlimit605605+ .long sys_mmap2606606+ .long sys_truncate64607607+ .long sys_ftruncate64608608+ .long sys_stat64 /* 195 */609609+ .long sys_lstat64610610+ .long sys_fstat64611611+ .long sys_chown612612+ .long sys_getuid613613+ .long sys_getgid /* 200 */614614+ .long sys_geteuid615615+ .long sys_getegid616616+ .long sys_setreuid617617+ .long sys_setregid618618+ .long sys_getgroups /* 205 */619619+ .long sys_setgroups620620+ .long sys_fchown621621+ .long sys_setresuid622622+ .long sys_getresuid623623+ .long sys_setresgid /* 210 */624624+ .long sys_getresgid625625+ .long sys_lchown626626+ .long sys_setuid627627+ .long sys_setgid628628+ .long sys_setfsuid /* 215 */629629+ .long sys_setfsgid630630+ .long sys_pivot_root631631+ .long sys_ni_syscall632632+ .long sys_ni_syscall633633+ .long sys_getdents64 /* 220 */634634+ .long sys_gettid635635+ .long sys_tkill636636+ .long sys_setxattr637637+ .long sys_lsetxattr638638+ .long sys_fsetxattr /* 225 */639639+ .long sys_getxattr640640+ .long sys_lgetxattr641641+ .long sys_fgetxattr642642+ .long sys_listxattr643643+ .long sys_llistxattr /* 230 */644644+ .long sys_flistxattr645645+ .long sys_removexattr646646+ .long sys_lremovexattr647647+ .long sys_fremovexattr648648+ .long sys_futex /* 235 */649649+ .long sys_sendfile64650650+ .long sys_mincore651651+ .long sys_madvise652652+ .long sys_fcntl64653653+ .long sys_readahead /* 240 */654654+ .long sys_io_setup655655+ .long sys_io_destroy656656+ .long sys_io_getevents657657+ .long sys_io_submit658658+ .long sys_io_cancel /* 245 */659659+ .long sys_fadvise64660660+ .long sys_exit_group661661+ .long sys_lookup_dcookie662662+ .long sys_epoll_create663663+ .long sys_epoll_ctl /* 250 */664664+ .long sys_epoll_wait665665+ .long sys_remap_file_pages666666+ .long sys_set_tid_address667667+ .long sys_timer_create668668+ .long sys_timer_settime /* 255 */669669+ .long sys_timer_gettime670670+ .long sys_timer_getoverrun671671+ .long sys_timer_delete672672+ .long sys_clock_settime673673+ .long sys_clock_gettime /* 260 */674674+ .long sys_clock_getres675675+ .long sys_clock_nanosleep676676+ .long sys_statfs64677677+ .long sys_fstatfs64678678+ .long sys_tgkill /* 265 */679679+ .long sys_utimes680680+ .long sys_fadvise64_64681681+ .long sys_mbind682682+ .long sys_get_mempolicy683683+ .long sys_set_mempolicy /* 270 */684684+ .long sys_mq_open685685+ .long sys_mq_unlink686686+ .long sys_mq_timedsend687687+ .long sys_mq_timedreceive688688+ .long sys_mq_notify /* 275 */689689+ .long sys_mq_getsetattr690690+ .long sys_waitid691691+ .long sys_ni_syscall /* for sys_vserver */692692+ .long sys_add_key693693+ .long sys_request_key /* 280 */694694+ .long sys_keyctl695695+ .long sys_ioprio_set696696+ .long sys_ioprio_get697697+ .long sys_inotify_init698698+ .long sys_inotify_add_watch /* 285 */699699+ .long sys_inotify_rm_watch700700+ .long sys_migrate_pages701701+ .long sys_openat702702+ .long sys_mkdirat703703+ .long sys_mknodat /* 290 */704704+ .long sys_fchownat705705+ .long sys_futimesat706706+ .long sys_fstatat64707707+ .long sys_unlinkat708708+ .long sys_renameat /* 295 */709709+ .long sys_linkat710710+ .long sys_symlinkat711711+ .long sys_readlinkat712712+ .long sys_fchmodat713713+ .long sys_faccessat /* 300 */714714+ .long sys_ni_syscall /* Reserved for pselect6 */715715+ .long sys_ni_syscall /* Reserved for ppoll */716716+ .long sys_unshare717717+ .long sys_set_robust_list718718+ .long sys_get_robust_list /* 305 */719719+ .long sys_splice720720+ .long sys_sync_file_range721721+ .long sys_tee722722+ .long sys_vmsplice723723+ .long sys_move_pages /* 310 */724724+ .long sys_sched_setaffinity725725+ .long sys_sched_getaffinity726726+ .long sys_kexec_load727727+ .long sys_getcpu728728+ .long sys_epoll_pwait /* 315 */729729+ .long sys_utimensat730730+ .long sys_signalfd731731+ .long sys_timerfd_create732732+ .long sys_eventfd733733+ .long sys_fallocate /* 320 */734734+ .long sys_timerfd_settime735735+ .long sys_timerfd_gettime736736+ .long sys_signalfd4737737+ .long sys_eventfd2738738+ .long sys_epoll_create1 /* 325 */739739+ .long sys_dup3740740+ .long sys_pipe2741741+ .long sys_inotify_init1742742+ .long sys_preadv743743+ .long sys_pwritev /* 330 */744744+ .long sys_rt_tgsigqueueinfo745745+ .long sys_perf_event_open746746+ .long sys_get_thread_area747747+ .long sys_set_thread_area748748+ .long sys_atomic_cmpxchg_32 /* 335 */749749+ .long sys_atomic_barrier750750+ .long sys_fanotify_init751751+ .long sys_fanotify_mark752752+ .long sys_prlimit64753753+
+5-16
arch/m68k/kernel/m68k_ksyms.c
···11-#include <linux/module.h>22-33-asmlinkage long long __ashldi3 (long long, int);44-asmlinkage long long __ashrdi3 (long long, int);55-asmlinkage long long __lshrdi3 (long long, int);66-asmlinkage long long __muldi3 (long long, long long);77-88-/* The following are special because they're not called99- explicitly (the C compiler generates them). Fortunately,1010- their interface isn't gonna change any time soon now, so1111- it's OK to leave it out of version control. */1212-EXPORT_SYMBOL(__ashldi3);1313-EXPORT_SYMBOL(__ashrdi3);1414-EXPORT_SYMBOL(__lshrdi3);1515-EXPORT_SYMBOL(__muldi3);1616-11+#ifdef CONFIG_MMU22+#include "m68k_ksyms_mm.c"33+#else44+#include "m68k_ksyms_no.c"55+#endif
+16
arch/m68k/kernel/m68k_ksyms_mm.c
···11+#include <linux/module.h>22+33+asmlinkage long long __ashldi3 (long long, int);44+asmlinkage long long __ashrdi3 (long long, int);55+asmlinkage long long __lshrdi3 (long long, int);66+asmlinkage long long __muldi3 (long long, long long);77+88+/* The following are special because they're not called99+ explicitly (the C compiler generates them). Fortunately,1010+ their interface isn't gonna change any time soon now, so1111+ it's OK to leave it out of version control. */1212+EXPORT_SYMBOL(__ashldi3);1313+EXPORT_SYMBOL(__ashrdi3);1414+EXPORT_SYMBOL(__lshrdi3);1515+EXPORT_SYMBOL(__muldi3);1616+
+3-153
arch/m68k/kernel/module.c
···11-/*22- * This file is subject to the terms and conditions of the GNU General Public33- * License. See the file COPYING in the main directory of this archive44- * for more details.55- */66-77-#include <linux/moduleloader.h>88-#include <linux/elf.h>99-#include <linux/vmalloc.h>1010-#include <linux/fs.h>1111-#include <linux/string.h>1212-#include <linux/kernel.h>1313-1414-#if 01515-#define DEBUGP printk11+#ifdef CONFIG_MMU22+#include "module_mm.c"163#else1717-#define DEBUGP(fmt...)44+#include "module_no.c"185#endif1919-2020-#ifdef CONFIG_MODULES2121-2222-void *module_alloc(unsigned long size)2323-{2424- if (size == 0)2525- return NULL;2626- return vmalloc(size);2727-}2828-2929-3030-/* Free memory returned from module_alloc */3131-void module_free(struct module *mod, void *module_region)3232-{3333- vfree(module_region);3434-}3535-3636-/* We don't need anything special. */3737-int module_frob_arch_sections(Elf_Ehdr *hdr,3838- Elf_Shdr *sechdrs,3939- char *secstrings,4040- struct module *mod)4141-{4242- return 0;4343-}4444-4545-int apply_relocate(Elf32_Shdr *sechdrs,4646- const char *strtab,4747- unsigned int symindex,4848- unsigned int relsec,4949- struct module *me)5050-{5151- unsigned int i;5252- Elf32_Rel *rel = (void *)sechdrs[relsec].sh_addr;5353- Elf32_Sym *sym;5454- uint32_t *location;5555-5656- DEBUGP("Applying relocate section %u to %u\n", relsec,5757- sechdrs[relsec].sh_info);5858- for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rel); i++) {5959- /* This is where to make the change */6060- location = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr6161- + rel[i].r_offset;6262- /* This is the symbol it is referring to. Note that all6363- undefined symbols have been resolved. */6464- sym = (Elf32_Sym *)sechdrs[symindex].sh_addr6565- + ELF32_R_SYM(rel[i].r_info);6666-6767- switch (ELF32_R_TYPE(rel[i].r_info)) {6868- case R_68K_32:6969- /* We add the value into the location given */7070- *location += sym->st_value;7171- break;7272- case R_68K_PC32:7373- /* Add the value, subtract its postition */7474- *location += sym->st_value - (uint32_t)location;7575- break;7676- default:7777- printk(KERN_ERR "module %s: Unknown relocation: %u\n",7878- me->name, ELF32_R_TYPE(rel[i].r_info));7979- return -ENOEXEC;8080- }8181- }8282- return 0;8383-}8484-8585-int apply_relocate_add(Elf32_Shdr *sechdrs,8686- const char *strtab,8787- unsigned int symindex,8888- unsigned int relsec,8989- struct module *me)9090-{9191- unsigned int i;9292- Elf32_Rela *rel = (void *)sechdrs[relsec].sh_addr;9393- Elf32_Sym *sym;9494- uint32_t *location;9595-9696- DEBUGP("Applying relocate_add section %u to %u\n", relsec,9797- sechdrs[relsec].sh_info);9898- for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rel); i++) {9999- /* This is where to make the change */100100- location = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr101101- + rel[i].r_offset;102102- /* This is the symbol it is referring to. Note that all103103- undefined symbols have been resolved. */104104- sym = (Elf32_Sym *)sechdrs[symindex].sh_addr105105- + ELF32_R_SYM(rel[i].r_info);106106-107107- switch (ELF32_R_TYPE(rel[i].r_info)) {108108- case R_68K_32:109109- /* We add the value into the location given */110110- *location = rel[i].r_addend + sym->st_value;111111- break;112112- case R_68K_PC32:113113- /* Add the value, subtract its postition */114114- *location = rel[i].r_addend + sym->st_value - (uint32_t)location;115115- break;116116- default:117117- printk(KERN_ERR "module %s: Unknown relocation: %u\n",118118- me->name, ELF32_R_TYPE(rel[i].r_info));119119- return -ENOEXEC;120120- }121121- }122122- return 0;123123-}124124-125125-int module_finalize(const Elf_Ehdr *hdr,126126- const Elf_Shdr *sechdrs,127127- struct module *mod)128128-{129129- module_fixup(mod, mod->arch.fixup_start, mod->arch.fixup_end);130130-131131- return 0;132132-}133133-134134-void module_arch_cleanup(struct module *mod)135135-{136136-}137137-138138-#endif /* CONFIG_MODULES */139139-140140-void module_fixup(struct module *mod, struct m68k_fixup_info *start,141141- struct m68k_fixup_info *end)142142-{143143- struct m68k_fixup_info *fixup;144144-145145- for (fixup = start; fixup < end; fixup++) {146146- switch (fixup->type) {147147- case m68k_fixup_memoffset:148148- *(u32 *)fixup->addr = m68k_memoffset;149149- break;150150- case m68k_fixup_vnode_shift:151151- *(u16 *)fixup->addr += m68k_virt_to_node_shift;152152- break;153153- }154154- }155155-}
+155
arch/m68k/kernel/module_mm.c
···11+/*22+ * This file is subject to the terms and conditions of the GNU General Public33+ * License. See the file COPYING in the main directory of this archive44+ * for more details.55+ */66+77+#include <linux/moduleloader.h>88+#include <linux/elf.h>99+#include <linux/vmalloc.h>1010+#include <linux/fs.h>1111+#include <linux/string.h>1212+#include <linux/kernel.h>1313+1414+#if 01515+#define DEBUGP printk1616+#else1717+#define DEBUGP(fmt...)1818+#endif1919+2020+#ifdef CONFIG_MODULES2121+2222+void *module_alloc(unsigned long size)2323+{2424+ if (size == 0)2525+ return NULL;2626+ return vmalloc(size);2727+}2828+2929+3030+/* Free memory returned from module_alloc */3131+void module_free(struct module *mod, void *module_region)3232+{3333+ vfree(module_region);3434+}3535+3636+/* We don't need anything special. */3737+int module_frob_arch_sections(Elf_Ehdr *hdr,3838+ Elf_Shdr *sechdrs,3939+ char *secstrings,4040+ struct module *mod)4141+{4242+ return 0;4343+}4444+4545+int apply_relocate(Elf32_Shdr *sechdrs,4646+ const char *strtab,4747+ unsigned int symindex,4848+ unsigned int relsec,4949+ struct module *me)5050+{5151+ unsigned int i;5252+ Elf32_Rel *rel = (void *)sechdrs[relsec].sh_addr;5353+ Elf32_Sym *sym;5454+ uint32_t *location;5555+5656+ DEBUGP("Applying relocate section %u to %u\n", relsec,5757+ sechdrs[relsec].sh_info);5858+ for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rel); i++) {5959+ /* This is where to make the change */6060+ location = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr6161+ + rel[i].r_offset;6262+ /* This is the symbol it is referring to. Note that all6363+ undefined symbols have been resolved. */6464+ sym = (Elf32_Sym *)sechdrs[symindex].sh_addr6565+ + ELF32_R_SYM(rel[i].r_info);6666+6767+ switch (ELF32_R_TYPE(rel[i].r_info)) {6868+ case R_68K_32:6969+ /* We add the value into the location given */7070+ *location += sym->st_value;7171+ break;7272+ case R_68K_PC32:7373+ /* Add the value, subtract its postition */7474+ *location += sym->st_value - (uint32_t)location;7575+ break;7676+ default:7777+ printk(KERN_ERR "module %s: Unknown relocation: %u\n",7878+ me->name, ELF32_R_TYPE(rel[i].r_info));7979+ return -ENOEXEC;8080+ }8181+ }8282+ return 0;8383+}8484+8585+int apply_relocate_add(Elf32_Shdr *sechdrs,8686+ const char *strtab,8787+ unsigned int symindex,8888+ unsigned int relsec,8989+ struct module *me)9090+{9191+ unsigned int i;9292+ Elf32_Rela *rel = (void *)sechdrs[relsec].sh_addr;9393+ Elf32_Sym *sym;9494+ uint32_t *location;9595+9696+ DEBUGP("Applying relocate_add section %u to %u\n", relsec,9797+ sechdrs[relsec].sh_info);9898+ for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rel); i++) {9999+ /* This is where to make the change */100100+ location = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr101101+ + rel[i].r_offset;102102+ /* This is the symbol it is referring to. Note that all103103+ undefined symbols have been resolved. */104104+ sym = (Elf32_Sym *)sechdrs[symindex].sh_addr105105+ + ELF32_R_SYM(rel[i].r_info);106106+107107+ switch (ELF32_R_TYPE(rel[i].r_info)) {108108+ case R_68K_32:109109+ /* We add the value into the location given */110110+ *location = rel[i].r_addend + sym->st_value;111111+ break;112112+ case R_68K_PC32:113113+ /* Add the value, subtract its postition */114114+ *location = rel[i].r_addend + sym->st_value - (uint32_t)location;115115+ break;116116+ default:117117+ printk(KERN_ERR "module %s: Unknown relocation: %u\n",118118+ me->name, ELF32_R_TYPE(rel[i].r_info));119119+ return -ENOEXEC;120120+ }121121+ }122122+ return 0;123123+}124124+125125+int module_finalize(const Elf_Ehdr *hdr,126126+ const Elf_Shdr *sechdrs,127127+ struct module *mod)128128+{129129+ module_fixup(mod, mod->arch.fixup_start, mod->arch.fixup_end);130130+131131+ return 0;132132+}133133+134134+void module_arch_cleanup(struct module *mod)135135+{136136+}137137+138138+#endif /* CONFIG_MODULES */139139+140140+void module_fixup(struct module *mod, struct m68k_fixup_info *start,141141+ struct m68k_fixup_info *end)142142+{143143+ struct m68k_fixup_info *fixup;144144+145145+ for (fixup = start; fixup < end; fixup++) {146146+ switch (fixup->type) {147147+ case m68k_fixup_memoffset:148148+ *(u32 *)fixup->addr = m68k_memoffset;149149+ break;150150+ case m68k_fixup_vnode_shift:151151+ *(u16 *)fixup->addr += m68k_virt_to_node_shift;152152+ break;153153+ }154154+ }155155+}
+3-352
arch/m68k/kernel/process.c
···11-/*22- * linux/arch/m68k/kernel/process.c33- *44- * Copyright (C) 1995 Hamish Macdonald55- *66- * 68060 fixes by Jesper Skov77- */88-99-/*1010- * This file handles the architecture-dependent parts of process handling..1111- */1212-1313-#include <linux/errno.h>1414-#include <linux/module.h>1515-#include <linux/sched.h>1616-#include <linux/kernel.h>1717-#include <linux/mm.h>1818-#include <linux/slab.h>1919-#include <linux/fs.h>2020-#include <linux/smp.h>2121-#include <linux/stddef.h>2222-#include <linux/unistd.h>2323-#include <linux/ptrace.h>2424-#include <linux/user.h>2525-#include <linux/reboot.h>2626-#include <linux/init_task.h>2727-#include <linux/mqueue.h>2828-2929-#include <asm/uaccess.h>3030-#include <asm/system.h>3131-#include <asm/traps.h>3232-#include <asm/machdep.h>3333-#include <asm/setup.h>3434-#include <asm/pgtable.h>3535-3636-/*3737- * Initial task/thread structure. Make this a per-architecture thing,3838- * because different architectures tend to have different3939- * alignment requirements and potentially different initial4040- * setup.4141- */4242-static struct signal_struct init_signals = INIT_SIGNALS(init_signals);4343-static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand);4444-union thread_union init_thread_union __init_task_data4545- __attribute__((aligned(THREAD_SIZE))) =4646- { INIT_THREAD_INFO(init_task) };4747-4848-/* initial task structure */4949-struct task_struct init_task = INIT_TASK(init_task);5050-5151-EXPORT_SYMBOL(init_task);5252-5353-asmlinkage void ret_from_fork(void);5454-5555-5656-/*5757- * Return saved PC from a blocked thread5858- */5959-unsigned long thread_saved_pc(struct task_struct *tsk)6060-{6161- struct switch_stack *sw = (struct switch_stack *)tsk->thread.ksp;6262- /* Check whether the thread is blocked in resume() */6363- if (in_sched_functions(sw->retpc))6464- return ((unsigned long *)sw->a6)[1];6565- else6666- return sw->retpc;6767-}6868-6969-/*7070- * The idle loop on an m68k..7171- */7272-static void default_idle(void)7373-{7474- if (!need_resched())7575-#if defined(MACH_ATARI_ONLY)7676- /* block out HSYNC on the atari (falcon) */7777- __asm__("stop #0x2200" : : : "cc");11+#ifdef CONFIG_MMU22+#include "process_mm.c"783#else7979- __asm__("stop #0x2000" : : : "cc");44+#include "process_no.c"805#endif8181-}8282-8383-void (*idle)(void) = default_idle;8484-8585-/*8686- * The idle thread. There's no useful work to be8787- * done, so just try to conserve power and have a8888- * low exit latency (ie sit in a loop waiting for8989- * somebody to say that they'd like to reschedule)9090- */9191-void cpu_idle(void)9292-{9393- /* endless idle loop with no priority at all */9494- while (1) {9595- while (!need_resched())9696- idle();9797- preempt_enable_no_resched();9898- schedule();9999- preempt_disable();100100- }101101-}102102-103103-void machine_restart(char * __unused)104104-{105105- if (mach_reset)106106- mach_reset();107107- for (;;);108108-}109109-110110-void machine_halt(void)111111-{112112- if (mach_halt)113113- mach_halt();114114- for (;;);115115-}116116-117117-void machine_power_off(void)118118-{119119- if (mach_power_off)120120- mach_power_off();121121- for (;;);122122-}123123-124124-void (*pm_power_off)(void) = machine_power_off;125125-EXPORT_SYMBOL(pm_power_off);126126-127127-void show_regs(struct pt_regs * regs)128128-{129129- printk("\n");130130- printk("Format %02x Vector: %04x PC: %08lx Status: %04x %s\n",131131- regs->format, regs->vector, regs->pc, regs->sr, print_tainted());132132- printk("ORIG_D0: %08lx D0: %08lx A2: %08lx A1: %08lx\n",133133- regs->orig_d0, regs->d0, regs->a2, regs->a1);134134- printk("A0: %08lx D5: %08lx D4: %08lx\n",135135- regs->a0, regs->d5, regs->d4);136136- printk("D3: %08lx D2: %08lx D1: %08lx\n",137137- regs->d3, regs->d2, regs->d1);138138- if (!(regs->sr & PS_S))139139- printk("USP: %08lx\n", rdusp());140140-}141141-142142-/*143143- * Create a kernel thread144144- */145145-int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)146146-{147147- int pid;148148- mm_segment_t fs;149149-150150- fs = get_fs();151151- set_fs (KERNEL_DS);152152-153153- {154154- register long retval __asm__ ("d0");155155- register long clone_arg __asm__ ("d1") = flags | CLONE_VM | CLONE_UNTRACED;156156-157157- retval = __NR_clone;158158- __asm__ __volatile__159159- ("clrl %%d2\n\t"160160- "trap #0\n\t" /* Linux/m68k system call */161161- "tstl %0\n\t" /* child or parent */162162- "jne 1f\n\t" /* parent - jump */163163- "lea %%sp@(%c7),%6\n\t" /* reload current */164164- "movel %6@,%6\n\t"165165- "movel %3,%%sp@-\n\t" /* push argument */166166- "jsr %4@\n\t" /* call fn */167167- "movel %0,%%d1\n\t" /* pass exit value */168168- "movel %2,%%d0\n\t" /* exit */169169- "trap #0\n"170170- "1:"171171- : "+d" (retval)172172- : "i" (__NR_clone), "i" (__NR_exit),173173- "r" (arg), "a" (fn), "d" (clone_arg), "r" (current),174174- "i" (-THREAD_SIZE)175175- : "d2");176176-177177- pid = retval;178178- }179179-180180- set_fs (fs);181181- return pid;182182-}183183-EXPORT_SYMBOL(kernel_thread);184184-185185-void flush_thread(void)186186-{187187- unsigned long zero = 0;188188- set_fs(USER_DS);189189- current->thread.fs = __USER_DS;190190- if (!FPU_IS_EMU)191191- asm volatile (".chip 68k/68881\n\t"192192- "frestore %0@\n\t"193193- ".chip 68k" : : "a" (&zero));194194-}195195-196196-/*197197- * "m68k_fork()".. By the time we get here, the198198- * non-volatile registers have also been saved on the199199- * stack. We do some ugly pointer stuff here.. (see200200- * also copy_thread)201201- */202202-203203-asmlinkage int m68k_fork(struct pt_regs *regs)204204-{205205- return do_fork(SIGCHLD, rdusp(), regs, 0, NULL, NULL);206206-}207207-208208-asmlinkage int m68k_vfork(struct pt_regs *regs)209209-{210210- return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, rdusp(), regs, 0,211211- NULL, NULL);212212-}213213-214214-asmlinkage int m68k_clone(struct pt_regs *regs)215215-{216216- unsigned long clone_flags;217217- unsigned long newsp;218218- int __user *parent_tidptr, *child_tidptr;219219-220220- /* syscall2 puts clone_flags in d1 and usp in d2 */221221- clone_flags = regs->d1;222222- newsp = regs->d2;223223- parent_tidptr = (int __user *)regs->d3;224224- child_tidptr = (int __user *)regs->d4;225225- if (!newsp)226226- newsp = rdusp();227227- return do_fork(clone_flags, newsp, regs, 0,228228- parent_tidptr, child_tidptr);229229-}230230-231231-int copy_thread(unsigned long clone_flags, unsigned long usp,232232- unsigned long unused,233233- struct task_struct * p, struct pt_regs * regs)234234-{235235- struct pt_regs * childregs;236236- struct switch_stack * childstack, *stack;237237- unsigned long *retp;238238-239239- childregs = (struct pt_regs *) (task_stack_page(p) + THREAD_SIZE) - 1;240240-241241- *childregs = *regs;242242- childregs->d0 = 0;243243-244244- retp = ((unsigned long *) regs);245245- stack = ((struct switch_stack *) retp) - 1;246246-247247- childstack = ((struct switch_stack *) childregs) - 1;248248- *childstack = *stack;249249- childstack->retpc = (unsigned long)ret_from_fork;250250-251251- p->thread.usp = usp;252252- p->thread.ksp = (unsigned long)childstack;253253-254254- if (clone_flags & CLONE_SETTLS)255255- task_thread_info(p)->tp_value = regs->d5;256256-257257- /*258258- * Must save the current SFC/DFC value, NOT the value when259259- * the parent was last descheduled - RGH 10-08-96260260- */261261- p->thread.fs = get_fs().seg;262262-263263- if (!FPU_IS_EMU) {264264- /* Copy the current fpu state */265265- asm volatile ("fsave %0" : : "m" (p->thread.fpstate[0]) : "memory");266266-267267- if (!CPU_IS_060 ? p->thread.fpstate[0] : p->thread.fpstate[2])268268- asm volatile ("fmovemx %/fp0-%/fp7,%0\n\t"269269- "fmoveml %/fpiar/%/fpcr/%/fpsr,%1"270270- : : "m" (p->thread.fp[0]), "m" (p->thread.fpcntl[0])271271- : "memory");272272- /* Restore the state in case the fpu was busy */273273- asm volatile ("frestore %0" : : "m" (p->thread.fpstate[0]));274274- }275275-276276- return 0;277277-}278278-279279-/* Fill in the fpu structure for a core dump. */280280-281281-int dump_fpu (struct pt_regs *regs, struct user_m68kfp_struct *fpu)282282-{283283- char fpustate[216];284284-285285- if (FPU_IS_EMU) {286286- int i;287287-288288- memcpy(fpu->fpcntl, current->thread.fpcntl, 12);289289- memcpy(fpu->fpregs, current->thread.fp, 96);290290- /* Convert internal fpu reg representation291291- * into long double format292292- */293293- for (i = 0; i < 24; i += 3)294294- fpu->fpregs[i] = ((fpu->fpregs[i] & 0xffff0000) << 15) |295295- ((fpu->fpregs[i] & 0x0000ffff) << 16);296296- return 1;297297- }298298-299299- /* First dump the fpu context to avoid protocol violation. */300300- asm volatile ("fsave %0" :: "m" (fpustate[0]) : "memory");301301- if (!CPU_IS_060 ? !fpustate[0] : !fpustate[2])302302- return 0;303303-304304- asm volatile ("fmovem %/fpiar/%/fpcr/%/fpsr,%0"305305- :: "m" (fpu->fpcntl[0])306306- : "memory");307307- asm volatile ("fmovemx %/fp0-%/fp7,%0"308308- :: "m" (fpu->fpregs[0])309309- : "memory");310310- return 1;311311-}312312-EXPORT_SYMBOL(dump_fpu);313313-314314-/*315315- * sys_execve() executes a new program.316316- */317317-asmlinkage int sys_execve(const char __user *name,318318- const char __user *const __user *argv,319319- const char __user *const __user *envp)320320-{321321- int error;322322- char * filename;323323- struct pt_regs *regs = (struct pt_regs *) &name;324324-325325- filename = getname(name);326326- error = PTR_ERR(filename);327327- if (IS_ERR(filename))328328- return error;329329- error = do_execve(filename, argv, envp, regs);330330- putname(filename);331331- return error;332332-}333333-334334-unsigned long get_wchan(struct task_struct *p)335335-{336336- unsigned long fp, pc;337337- unsigned long stack_page;338338- int count = 0;339339- if (!p || p == current || p->state == TASK_RUNNING)340340- return 0;341341-342342- stack_page = (unsigned long)task_stack_page(p);343343- fp = ((struct switch_stack *)p->thread.ksp)->a6;344344- do {345345- if (fp < stack_page+sizeof(struct thread_info) ||346346- fp >= 8184+stack_page)347347- return 0;348348- pc = ((unsigned long *)fp)[1];349349- if (!in_sched_functions(pc))350350- return pc;351351- fp = *(unsigned long *) fp;352352- } while (count++ < 16);353353- return 0;354354-}
+354
arch/m68k/kernel/process_mm.c
···11+/*22+ * linux/arch/m68k/kernel/process.c33+ *44+ * Copyright (C) 1995 Hamish Macdonald55+ *66+ * 68060 fixes by Jesper Skov77+ */88+99+/*1010+ * This file handles the architecture-dependent parts of process handling..1111+ */1212+1313+#include <linux/errno.h>1414+#include <linux/module.h>1515+#include <linux/sched.h>1616+#include <linux/kernel.h>1717+#include <linux/mm.h>1818+#include <linux/slab.h>1919+#include <linux/fs.h>2020+#include <linux/smp.h>2121+#include <linux/stddef.h>2222+#include <linux/unistd.h>2323+#include <linux/ptrace.h>2424+#include <linux/user.h>2525+#include <linux/reboot.h>2626+#include <linux/init_task.h>2727+#include <linux/mqueue.h>2828+2929+#include <asm/uaccess.h>3030+#include <asm/system.h>3131+#include <asm/traps.h>3232+#include <asm/machdep.h>3333+#include <asm/setup.h>3434+#include <asm/pgtable.h>3535+3636+/*3737+ * Initial task/thread structure. Make this a per-architecture thing,3838+ * because different architectures tend to have different3939+ * alignment requirements and potentially different initial4040+ * setup.4141+ */4242+static struct signal_struct init_signals = INIT_SIGNALS(init_signals);4343+static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand);4444+union thread_union init_thread_union __init_task_data4545+ __attribute__((aligned(THREAD_SIZE))) =4646+ { INIT_THREAD_INFO(init_task) };4747+4848+/* initial task structure */4949+struct task_struct init_task = INIT_TASK(init_task);5050+5151+EXPORT_SYMBOL(init_task);5252+5353+asmlinkage void ret_from_fork(void);5454+5555+5656+/*5757+ * Return saved PC from a blocked thread5858+ */5959+unsigned long thread_saved_pc(struct task_struct *tsk)6060+{6161+ struct switch_stack *sw = (struct switch_stack *)tsk->thread.ksp;6262+ /* Check whether the thread is blocked in resume() */6363+ if (in_sched_functions(sw->retpc))6464+ return ((unsigned long *)sw->a6)[1];6565+ else6666+ return sw->retpc;6767+}6868+6969+/*7070+ * The idle loop on an m68k..7171+ */7272+static void default_idle(void)7373+{7474+ if (!need_resched())7575+#if defined(MACH_ATARI_ONLY)7676+ /* block out HSYNC on the atari (falcon) */7777+ __asm__("stop #0x2200" : : : "cc");7878+#else7979+ __asm__("stop #0x2000" : : : "cc");8080+#endif8181+}8282+8383+void (*idle)(void) = default_idle;8484+8585+/*8686+ * The idle thread. There's no useful work to be8787+ * done, so just try to conserve power and have a8888+ * low exit latency (ie sit in a loop waiting for8989+ * somebody to say that they'd like to reschedule)9090+ */9191+void cpu_idle(void)9292+{9393+ /* endless idle loop with no priority at all */9494+ while (1) {9595+ while (!need_resched())9696+ idle();9797+ preempt_enable_no_resched();9898+ schedule();9999+ preempt_disable();100100+ }101101+}102102+103103+void machine_restart(char * __unused)104104+{105105+ if (mach_reset)106106+ mach_reset();107107+ for (;;);108108+}109109+110110+void machine_halt(void)111111+{112112+ if (mach_halt)113113+ mach_halt();114114+ for (;;);115115+}116116+117117+void machine_power_off(void)118118+{119119+ if (mach_power_off)120120+ mach_power_off();121121+ for (;;);122122+}123123+124124+void (*pm_power_off)(void) = machine_power_off;125125+EXPORT_SYMBOL(pm_power_off);126126+127127+void show_regs(struct pt_regs * regs)128128+{129129+ printk("\n");130130+ printk("Format %02x Vector: %04x PC: %08lx Status: %04x %s\n",131131+ regs->format, regs->vector, regs->pc, regs->sr, print_tainted());132132+ printk("ORIG_D0: %08lx D0: %08lx A2: %08lx A1: %08lx\n",133133+ regs->orig_d0, regs->d0, regs->a2, regs->a1);134134+ printk("A0: %08lx D5: %08lx D4: %08lx\n",135135+ regs->a0, regs->d5, regs->d4);136136+ printk("D3: %08lx D2: %08lx D1: %08lx\n",137137+ regs->d3, regs->d2, regs->d1);138138+ if (!(regs->sr & PS_S))139139+ printk("USP: %08lx\n", rdusp());140140+}141141+142142+/*143143+ * Create a kernel thread144144+ */145145+int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)146146+{147147+ int pid;148148+ mm_segment_t fs;149149+150150+ fs = get_fs();151151+ set_fs (KERNEL_DS);152152+153153+ {154154+ register long retval __asm__ ("d0");155155+ register long clone_arg __asm__ ("d1") = flags | CLONE_VM | CLONE_UNTRACED;156156+157157+ retval = __NR_clone;158158+ __asm__ __volatile__159159+ ("clrl %%d2\n\t"160160+ "trap #0\n\t" /* Linux/m68k system call */161161+ "tstl %0\n\t" /* child or parent */162162+ "jne 1f\n\t" /* parent - jump */163163+ "lea %%sp@(%c7),%6\n\t" /* reload current */164164+ "movel %6@,%6\n\t"165165+ "movel %3,%%sp@-\n\t" /* push argument */166166+ "jsr %4@\n\t" /* call fn */167167+ "movel %0,%%d1\n\t" /* pass exit value */168168+ "movel %2,%%d0\n\t" /* exit */169169+ "trap #0\n"170170+ "1:"171171+ : "+d" (retval)172172+ : "i" (__NR_clone), "i" (__NR_exit),173173+ "r" (arg), "a" (fn), "d" (clone_arg), "r" (current),174174+ "i" (-THREAD_SIZE)175175+ : "d2");176176+177177+ pid = retval;178178+ }179179+180180+ set_fs (fs);181181+ return pid;182182+}183183+EXPORT_SYMBOL(kernel_thread);184184+185185+void flush_thread(void)186186+{187187+ unsigned long zero = 0;188188+ set_fs(USER_DS);189189+ current->thread.fs = __USER_DS;190190+ if (!FPU_IS_EMU)191191+ asm volatile (".chip 68k/68881\n\t"192192+ "frestore %0@\n\t"193193+ ".chip 68k" : : "a" (&zero));194194+}195195+196196+/*197197+ * "m68k_fork()".. By the time we get here, the198198+ * non-volatile registers have also been saved on the199199+ * stack. We do some ugly pointer stuff here.. (see200200+ * also copy_thread)201201+ */202202+203203+asmlinkage int m68k_fork(struct pt_regs *regs)204204+{205205+ return do_fork(SIGCHLD, rdusp(), regs, 0, NULL, NULL);206206+}207207+208208+asmlinkage int m68k_vfork(struct pt_regs *regs)209209+{210210+ return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, rdusp(), regs, 0,211211+ NULL, NULL);212212+}213213+214214+asmlinkage int m68k_clone(struct pt_regs *regs)215215+{216216+ unsigned long clone_flags;217217+ unsigned long newsp;218218+ int __user *parent_tidptr, *child_tidptr;219219+220220+ /* syscall2 puts clone_flags in d1 and usp in d2 */221221+ clone_flags = regs->d1;222222+ newsp = regs->d2;223223+ parent_tidptr = (int __user *)regs->d3;224224+ child_tidptr = (int __user *)regs->d4;225225+ if (!newsp)226226+ newsp = rdusp();227227+ return do_fork(clone_flags, newsp, regs, 0,228228+ parent_tidptr, child_tidptr);229229+}230230+231231+int copy_thread(unsigned long clone_flags, unsigned long usp,232232+ unsigned long unused,233233+ struct task_struct * p, struct pt_regs * regs)234234+{235235+ struct pt_regs * childregs;236236+ struct switch_stack * childstack, *stack;237237+ unsigned long *retp;238238+239239+ childregs = (struct pt_regs *) (task_stack_page(p) + THREAD_SIZE) - 1;240240+241241+ *childregs = *regs;242242+ childregs->d0 = 0;243243+244244+ retp = ((unsigned long *) regs);245245+ stack = ((struct switch_stack *) retp) - 1;246246+247247+ childstack = ((struct switch_stack *) childregs) - 1;248248+ *childstack = *stack;249249+ childstack->retpc = (unsigned long)ret_from_fork;250250+251251+ p->thread.usp = usp;252252+ p->thread.ksp = (unsigned long)childstack;253253+254254+ if (clone_flags & CLONE_SETTLS)255255+ task_thread_info(p)->tp_value = regs->d5;256256+257257+ /*258258+ * Must save the current SFC/DFC value, NOT the value when259259+ * the parent was last descheduled - RGH 10-08-96260260+ */261261+ p->thread.fs = get_fs().seg;262262+263263+ if (!FPU_IS_EMU) {264264+ /* Copy the current fpu state */265265+ asm volatile ("fsave %0" : : "m" (p->thread.fpstate[0]) : "memory");266266+267267+ if (!CPU_IS_060 ? p->thread.fpstate[0] : p->thread.fpstate[2])268268+ asm volatile ("fmovemx %/fp0-%/fp7,%0\n\t"269269+ "fmoveml %/fpiar/%/fpcr/%/fpsr,%1"270270+ : : "m" (p->thread.fp[0]), "m" (p->thread.fpcntl[0])271271+ : "memory");272272+ /* Restore the state in case the fpu was busy */273273+ asm volatile ("frestore %0" : : "m" (p->thread.fpstate[0]));274274+ }275275+276276+ return 0;277277+}278278+279279+/* Fill in the fpu structure for a core dump. */280280+281281+int dump_fpu (struct pt_regs *regs, struct user_m68kfp_struct *fpu)282282+{283283+ char fpustate[216];284284+285285+ if (FPU_IS_EMU) {286286+ int i;287287+288288+ memcpy(fpu->fpcntl, current->thread.fpcntl, 12);289289+ memcpy(fpu->fpregs, current->thread.fp, 96);290290+ /* Convert internal fpu reg representation291291+ * into long double format292292+ */293293+ for (i = 0; i < 24; i += 3)294294+ fpu->fpregs[i] = ((fpu->fpregs[i] & 0xffff0000) << 15) |295295+ ((fpu->fpregs[i] & 0x0000ffff) << 16);296296+ return 1;297297+ }298298+299299+ /* First dump the fpu context to avoid protocol violation. */300300+ asm volatile ("fsave %0" :: "m" (fpustate[0]) : "memory");301301+ if (!CPU_IS_060 ? !fpustate[0] : !fpustate[2])302302+ return 0;303303+304304+ asm volatile ("fmovem %/fpiar/%/fpcr/%/fpsr,%0"305305+ :: "m" (fpu->fpcntl[0])306306+ : "memory");307307+ asm volatile ("fmovemx %/fp0-%/fp7,%0"308308+ :: "m" (fpu->fpregs[0])309309+ : "memory");310310+ return 1;311311+}312312+EXPORT_SYMBOL(dump_fpu);313313+314314+/*315315+ * sys_execve() executes a new program.316316+ */317317+asmlinkage int sys_execve(const char __user *name,318318+ const char __user *const __user *argv,319319+ const char __user *const __user *envp)320320+{321321+ int error;322322+ char * filename;323323+ struct pt_regs *regs = (struct pt_regs *) &name;324324+325325+ filename = getname(name);326326+ error = PTR_ERR(filename);327327+ if (IS_ERR(filename))328328+ return error;329329+ error = do_execve(filename, argv, envp, regs);330330+ putname(filename);331331+ return error;332332+}333333+334334+unsigned long get_wchan(struct task_struct *p)335335+{336336+ unsigned long fp, pc;337337+ unsigned long stack_page;338338+ int count = 0;339339+ if (!p || p == current || p->state == TASK_RUNNING)340340+ return 0;341341+342342+ stack_page = (unsigned long)task_stack_page(p);343343+ fp = ((struct switch_stack *)p->thread.ksp)->a6;344344+ do {345345+ if (fp < stack_page+sizeof(struct thread_info) ||346346+ fp >= 8184+stack_page)347347+ return 0;348348+ pc = ((unsigned long *)fp)[1];349349+ if (!in_sched_functions(pc))350350+ return pc;351351+ fp = *(unsigned long *) fp;352352+ } while (count++ < 16);353353+ return 0;354354+}
+5-277
arch/m68k/kernel/ptrace.c
···11-/*22- * linux/arch/m68k/kernel/ptrace.c33- *44- * Copyright (C) 1994 by Hamish Macdonald55- * Taken from linux/kernel/ptrace.c and modified for M680x0.66- * linux/kernel/ptrace.c is by Ross Biro 1/23/92, edited by Linus Torvalds77- *88- * This file is subject to the terms and conditions of the GNU General99- * Public License. See the file COPYING in the main directory of1010- * this archive for more details.1111- */1212-1313-#include <linux/kernel.h>1414-#include <linux/sched.h>1515-#include <linux/mm.h>1616-#include <linux/smp.h>1717-#include <linux/errno.h>1818-#include <linux/ptrace.h>1919-#include <linux/user.h>2020-#include <linux/signal.h>2121-2222-#include <asm/uaccess.h>2323-#include <asm/page.h>2424-#include <asm/pgtable.h>2525-#include <asm/system.h>2626-#include <asm/processor.h>2727-2828-/*2929- * does not yet catch signals sent when the child dies.3030- * in exit.c or in signal.c.3131- */3232-3333-/* determines which bits in the SR the user has access to. */3434-/* 1 = access 0 = no access */3535-#define SR_MASK 0x001f3636-3737-/* sets the trace bits. */3838-#define TRACE_BITS 0xC0003939-#define T1_BIT 0x80004040-#define T0_BIT 0x40004141-4242-/* Find the stack offset for a register, relative to thread.esp0. */4343-#define PT_REG(reg) ((long)&((struct pt_regs *)0)->reg)4444-#define SW_REG(reg) ((long)&((struct switch_stack *)0)->reg \4545- - sizeof(struct switch_stack))4646-/* Mapping from PT_xxx to the stack offset at which the register is4747- saved. Notice that usp has no stack-slot and needs to be treated4848- specially (see get_reg/put_reg below). */4949-static const int regoff[] = {5050- [0] = PT_REG(d1),5151- [1] = PT_REG(d2),5252- [2] = PT_REG(d3),5353- [3] = PT_REG(d4),5454- [4] = PT_REG(d5),5555- [5] = SW_REG(d6),5656- [6] = SW_REG(d7),5757- [7] = PT_REG(a0),5858- [8] = PT_REG(a1),5959- [9] = PT_REG(a2),6060- [10] = SW_REG(a3),6161- [11] = SW_REG(a4),6262- [12] = SW_REG(a5),6363- [13] = SW_REG(a6),6464- [14] = PT_REG(d0),6565- [15] = -1,6666- [16] = PT_REG(orig_d0),6767- [17] = PT_REG(sr),6868- [18] = PT_REG(pc),6969-};7070-7171-/*7272- * Get contents of register REGNO in task TASK.7373- */7474-static inline long get_reg(struct task_struct *task, int regno)7575-{7676- unsigned long *addr;7777-7878- if (regno == PT_USP)7979- addr = &task->thread.usp;8080- else if (regno < ARRAY_SIZE(regoff))8181- addr = (unsigned long *)(task->thread.esp0 + regoff[regno]);8282- else8383- return 0;8484- /* Need to take stkadj into account. */8585- if (regno == PT_SR || regno == PT_PC) {8686- long stkadj = *(long *)(task->thread.esp0 + PT_REG(stkadj));8787- addr = (unsigned long *) ((unsigned long)addr + stkadj);8888- /* The sr is actually a 16 bit register. */8989- if (regno == PT_SR)9090- return *(unsigned short *)addr;9191- }9292- return *addr;9393-}9494-9595-/*9696- * Write contents of register REGNO in task TASK.9797- */9898-static inline int put_reg(struct task_struct *task, int regno,9999- unsigned long data)100100-{101101- unsigned long *addr;102102-103103- if (regno == PT_USP)104104- addr = &task->thread.usp;105105- else if (regno < ARRAY_SIZE(regoff))106106- addr = (unsigned long *)(task->thread.esp0 + regoff[regno]);107107- else108108- return -1;109109- /* Need to take stkadj into account. */110110- if (regno == PT_SR || regno == PT_PC) {111111- long stkadj = *(long *)(task->thread.esp0 + PT_REG(stkadj));112112- addr = (unsigned long *) ((unsigned long)addr + stkadj);113113- /* The sr is actually a 16 bit register. */114114- if (regno == PT_SR) {115115- *(unsigned short *)addr = data;116116- return 0;117117- }118118- }119119- *addr = data;120120- return 0;121121-}122122-123123-/*124124- * Make sure the single step bit is not set.125125- */126126-static inline void singlestep_disable(struct task_struct *child)127127-{128128- unsigned long tmp = get_reg(child, PT_SR) & ~TRACE_BITS;129129- put_reg(child, PT_SR, tmp);130130- clear_tsk_thread_flag(child, TIF_DELAYED_TRACE);131131-}132132-133133-/*134134- * Called by kernel/ptrace.c when detaching..135135- */136136-void ptrace_disable(struct task_struct *child)137137-{138138- singlestep_disable(child);139139-}140140-141141-void user_enable_single_step(struct task_struct *child)142142-{143143- unsigned long tmp = get_reg(child, PT_SR) & ~TRACE_BITS;144144- put_reg(child, PT_SR, tmp | T1_BIT);145145- set_tsk_thread_flag(child, TIF_DELAYED_TRACE);146146-}147147-148148-void user_enable_block_step(struct task_struct *child)149149-{150150- unsigned long tmp = get_reg(child, PT_SR) & ~TRACE_BITS;151151- put_reg(child, PT_SR, tmp | T0_BIT);152152-}153153-154154-void user_disable_single_step(struct task_struct *child)155155-{156156- singlestep_disable(child);157157-}158158-159159-long arch_ptrace(struct task_struct *child, long request,160160- unsigned long addr, unsigned long data)161161-{162162- unsigned long tmp;163163- int i, ret = 0;164164- int regno = addr >> 2; /* temporary hack. */165165- unsigned long __user *datap = (unsigned long __user *) data;166166-167167- switch (request) {168168- /* read the word at location addr in the USER area. */169169- case PTRACE_PEEKUSR:170170- if (addr & 3)171171- goto out_eio;172172-173173- if (regno >= 0 && regno < 19) {174174- tmp = get_reg(child, regno);175175- } else if (regno >= 21 && regno < 49) {176176- tmp = child->thread.fp[regno - 21];177177- /* Convert internal fpu reg representation178178- * into long double format179179- */180180- if (FPU_IS_EMU && (regno < 45) && !(regno % 3))181181- tmp = ((tmp & 0xffff0000) << 15) |182182- ((tmp & 0x0000ffff) << 16);183183- } else184184- goto out_eio;185185- ret = put_user(tmp, datap);186186- break;187187-188188- case PTRACE_POKEUSR:189189- /* write the word at location addr in the USER area */190190- if (addr & 3)191191- goto out_eio;192192-193193- if (regno == PT_SR) {194194- data &= SR_MASK;195195- data |= get_reg(child, PT_SR) & ~SR_MASK;196196- }197197- if (regno >= 0 && regno < 19) {198198- if (put_reg(child, regno, data))199199- goto out_eio;200200- } else if (regno >= 21 && regno < 48) {201201- /* Convert long double format202202- * into internal fpu reg representation203203- */204204- if (FPU_IS_EMU && (regno < 45) && !(regno % 3)) {205205- data <<= 15;206206- data = (data & 0xffff0000) |207207- ((data & 0x0000ffff) >> 1);208208- }209209- child->thread.fp[regno - 21] = data;210210- } else211211- goto out_eio;212212- break;213213-214214- case PTRACE_GETREGS: /* Get all gp regs from the child. */215215- for (i = 0; i < 19; i++) {216216- tmp = get_reg(child, i);217217- ret = put_user(tmp, datap);218218- if (ret)219219- break;220220- datap++;221221- }222222- break;223223-224224- case PTRACE_SETREGS: /* Set all gp regs in the child. */225225- for (i = 0; i < 19; i++) {226226- ret = get_user(tmp, datap);227227- if (ret)228228- break;229229- if (i == PT_SR) {230230- tmp &= SR_MASK;231231- tmp |= get_reg(child, PT_SR) & ~SR_MASK;232232- }233233- put_reg(child, i, tmp);234234- datap++;235235- }236236- break;237237-238238- case PTRACE_GETFPREGS: /* Get the child FPU state. */239239- if (copy_to_user(datap, &child->thread.fp,240240- sizeof(struct user_m68kfp_struct)))241241- ret = -EFAULT;242242- break;243243-244244- case PTRACE_SETFPREGS: /* Set the child FPU state. */245245- if (copy_from_user(&child->thread.fp, datap,246246- sizeof(struct user_m68kfp_struct)))247247- ret = -EFAULT;248248- break;249249-250250- case PTRACE_GET_THREAD_AREA:251251- ret = put_user(task_thread_info(child)->tp_value, datap);252252- break;253253-254254- default:255255- ret = ptrace_request(child, request, addr, data);256256- break;257257- }258258-259259- return ret;260260-out_eio:261261- return -EIO;262262-}263263-264264-asmlinkage void syscall_trace(void)265265-{266266- ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD)267267- ? 0x80 : 0));268268- /*269269- * this isn't the same as continuing with a signal, but it will do270270- * for normal use. strace only continues with a signal if the271271- * stopping signal is not SIGTRAP. -brl272272- */273273- if (current->exit_code) {274274- send_sig(current->exit_code, current, 1);275275- current->exit_code = 0;276276- }277277-}11+#ifdef CONFIG_MMU22+#include "ptrace_mm.c"33+#else44+#include "ptrace_no.c"55+#endif
+277
arch/m68k/kernel/ptrace_mm.c
···11+/*22+ * linux/arch/m68k/kernel/ptrace.c33+ *44+ * Copyright (C) 1994 by Hamish Macdonald55+ * Taken from linux/kernel/ptrace.c and modified for M680x0.66+ * linux/kernel/ptrace.c is by Ross Biro 1/23/92, edited by Linus Torvalds77+ *88+ * This file is subject to the terms and conditions of the GNU General99+ * Public License. See the file COPYING in the main directory of1010+ * this archive for more details.1111+ */1212+1313+#include <linux/kernel.h>1414+#include <linux/sched.h>1515+#include <linux/mm.h>1616+#include <linux/smp.h>1717+#include <linux/errno.h>1818+#include <linux/ptrace.h>1919+#include <linux/user.h>2020+#include <linux/signal.h>2121+2222+#include <asm/uaccess.h>2323+#include <asm/page.h>2424+#include <asm/pgtable.h>2525+#include <asm/system.h>2626+#include <asm/processor.h>2727+2828+/*2929+ * does not yet catch signals sent when the child dies.3030+ * in exit.c or in signal.c.3131+ */3232+3333+/* determines which bits in the SR the user has access to. */3434+/* 1 = access 0 = no access */3535+#define SR_MASK 0x001f3636+3737+/* sets the trace bits. */3838+#define TRACE_BITS 0xC0003939+#define T1_BIT 0x80004040+#define T0_BIT 0x40004141+4242+/* Find the stack offset for a register, relative to thread.esp0. */4343+#define PT_REG(reg) ((long)&((struct pt_regs *)0)->reg)4444+#define SW_REG(reg) ((long)&((struct switch_stack *)0)->reg \4545+ - sizeof(struct switch_stack))4646+/* Mapping from PT_xxx to the stack offset at which the register is4747+ saved. Notice that usp has no stack-slot and needs to be treated4848+ specially (see get_reg/put_reg below). */4949+static const int regoff[] = {5050+ [0] = PT_REG(d1),5151+ [1] = PT_REG(d2),5252+ [2] = PT_REG(d3),5353+ [3] = PT_REG(d4),5454+ [4] = PT_REG(d5),5555+ [5] = SW_REG(d6),5656+ [6] = SW_REG(d7),5757+ [7] = PT_REG(a0),5858+ [8] = PT_REG(a1),5959+ [9] = PT_REG(a2),6060+ [10] = SW_REG(a3),6161+ [11] = SW_REG(a4),6262+ [12] = SW_REG(a5),6363+ [13] = SW_REG(a6),6464+ [14] = PT_REG(d0),6565+ [15] = -1,6666+ [16] = PT_REG(orig_d0),6767+ [17] = PT_REG(sr),6868+ [18] = PT_REG(pc),6969+};7070+7171+/*7272+ * Get contents of register REGNO in task TASK.7373+ */7474+static inline long get_reg(struct task_struct *task, int regno)7575+{7676+ unsigned long *addr;7777+7878+ if (regno == PT_USP)7979+ addr = &task->thread.usp;8080+ else if (regno < ARRAY_SIZE(regoff))8181+ addr = (unsigned long *)(task->thread.esp0 + regoff[regno]);8282+ else8383+ return 0;8484+ /* Need to take stkadj into account. */8585+ if (regno == PT_SR || regno == PT_PC) {8686+ long stkadj = *(long *)(task->thread.esp0 + PT_REG(stkadj));8787+ addr = (unsigned long *) ((unsigned long)addr + stkadj);8888+ /* The sr is actually a 16 bit register. */8989+ if (regno == PT_SR)9090+ return *(unsigned short *)addr;9191+ }9292+ return *addr;9393+}9494+9595+/*9696+ * Write contents of register REGNO in task TASK.9797+ */9898+static inline int put_reg(struct task_struct *task, int regno,9999+ unsigned long data)100100+{101101+ unsigned long *addr;102102+103103+ if (regno == PT_USP)104104+ addr = &task->thread.usp;105105+ else if (regno < ARRAY_SIZE(regoff))106106+ addr = (unsigned long *)(task->thread.esp0 + regoff[regno]);107107+ else108108+ return -1;109109+ /* Need to take stkadj into account. */110110+ if (regno == PT_SR || regno == PT_PC) {111111+ long stkadj = *(long *)(task->thread.esp0 + PT_REG(stkadj));112112+ addr = (unsigned long *) ((unsigned long)addr + stkadj);113113+ /* The sr is actually a 16 bit register. */114114+ if (regno == PT_SR) {115115+ *(unsigned short *)addr = data;116116+ return 0;117117+ }118118+ }119119+ *addr = data;120120+ return 0;121121+}122122+123123+/*124124+ * Make sure the single step bit is not set.125125+ */126126+static inline void singlestep_disable(struct task_struct *child)127127+{128128+ unsigned long tmp = get_reg(child, PT_SR) & ~TRACE_BITS;129129+ put_reg(child, PT_SR, tmp);130130+ clear_tsk_thread_flag(child, TIF_DELAYED_TRACE);131131+}132132+133133+/*134134+ * Called by kernel/ptrace.c when detaching..135135+ */136136+void ptrace_disable(struct task_struct *child)137137+{138138+ singlestep_disable(child);139139+}140140+141141+void user_enable_single_step(struct task_struct *child)142142+{143143+ unsigned long tmp = get_reg(child, PT_SR) & ~TRACE_BITS;144144+ put_reg(child, PT_SR, tmp | T1_BIT);145145+ set_tsk_thread_flag(child, TIF_DELAYED_TRACE);146146+}147147+148148+void user_enable_block_step(struct task_struct *child)149149+{150150+ unsigned long tmp = get_reg(child, PT_SR) & ~TRACE_BITS;151151+ put_reg(child, PT_SR, tmp | T0_BIT);152152+}153153+154154+void user_disable_single_step(struct task_struct *child)155155+{156156+ singlestep_disable(child);157157+}158158+159159+long arch_ptrace(struct task_struct *child, long request,160160+ unsigned long addr, unsigned long data)161161+{162162+ unsigned long tmp;163163+ int i, ret = 0;164164+ int regno = addr >> 2; /* temporary hack. */165165+ unsigned long __user *datap = (unsigned long __user *) data;166166+167167+ switch (request) {168168+ /* read the word at location addr in the USER area. */169169+ case PTRACE_PEEKUSR:170170+ if (addr & 3)171171+ goto out_eio;172172+173173+ if (regno >= 0 && regno < 19) {174174+ tmp = get_reg(child, regno);175175+ } else if (regno >= 21 && regno < 49) {176176+ tmp = child->thread.fp[regno - 21];177177+ /* Convert internal fpu reg representation178178+ * into long double format179179+ */180180+ if (FPU_IS_EMU && (regno < 45) && !(regno % 3))181181+ tmp = ((tmp & 0xffff0000) << 15) |182182+ ((tmp & 0x0000ffff) << 16);183183+ } else184184+ goto out_eio;185185+ ret = put_user(tmp, datap);186186+ break;187187+188188+ case PTRACE_POKEUSR:189189+ /* write the word at location addr in the USER area */190190+ if (addr & 3)191191+ goto out_eio;192192+193193+ if (regno == PT_SR) {194194+ data &= SR_MASK;195195+ data |= get_reg(child, PT_SR) & ~SR_MASK;196196+ }197197+ if (regno >= 0 && regno < 19) {198198+ if (put_reg(child, regno, data))199199+ goto out_eio;200200+ } else if (regno >= 21 && regno < 48) {201201+ /* Convert long double format202202+ * into internal fpu reg representation203203+ */204204+ if (FPU_IS_EMU && (regno < 45) && !(regno % 3)) {205205+ data <<= 15;206206+ data = (data & 0xffff0000) |207207+ ((data & 0x0000ffff) >> 1);208208+ }209209+ child->thread.fp[regno - 21] = data;210210+ } else211211+ goto out_eio;212212+ break;213213+214214+ case PTRACE_GETREGS: /* Get all gp regs from the child. */215215+ for (i = 0; i < 19; i++) {216216+ tmp = get_reg(child, i);217217+ ret = put_user(tmp, datap);218218+ if (ret)219219+ break;220220+ datap++;221221+ }222222+ break;223223+224224+ case PTRACE_SETREGS: /* Set all gp regs in the child. */225225+ for (i = 0; i < 19; i++) {226226+ ret = get_user(tmp, datap);227227+ if (ret)228228+ break;229229+ if (i == PT_SR) {230230+ tmp &= SR_MASK;231231+ tmp |= get_reg(child, PT_SR) & ~SR_MASK;232232+ }233233+ put_reg(child, i, tmp);234234+ datap++;235235+ }236236+ break;237237+238238+ case PTRACE_GETFPREGS: /* Get the child FPU state. */239239+ if (copy_to_user(datap, &child->thread.fp,240240+ sizeof(struct user_m68kfp_struct)))241241+ ret = -EFAULT;242242+ break;243243+244244+ case PTRACE_SETFPREGS: /* Set the child FPU state. */245245+ if (copy_from_user(&child->thread.fp, datap,246246+ sizeof(struct user_m68kfp_struct)))247247+ ret = -EFAULT;248248+ break;249249+250250+ case PTRACE_GET_THREAD_AREA:251251+ ret = put_user(task_thread_info(child)->tp_value, datap);252252+ break;253253+254254+ default:255255+ ret = ptrace_request(child, request, addr, data);256256+ break;257257+ }258258+259259+ return ret;260260+out_eio:261261+ return -EIO;262262+}263263+264264+asmlinkage void syscall_trace(void)265265+{266266+ ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD)267267+ ? 0x80 : 0));268268+ /*269269+ * this isn't the same as continuing with a signal, but it will do270270+ * for normal use. strace only continues with a signal if the271271+ * stopping signal is not SIGTRAP. -brl272272+ */273273+ if (current->exit_code) {274274+ send_sig(current->exit_code, current, 1);275275+ current->exit_code = 0;276276+ }277277+}
+3-531
arch/m68k/kernel/setup.c
···11-/*22- * linux/arch/m68k/kernel/setup.c33- *44- * Copyright (C) 1995 Hamish Macdonald55- */66-77-/*88- * This file handles the architecture-dependent parts of system setup99- */1010-1111-#include <linux/kernel.h>1212-#include <linux/mm.h>1313-#include <linux/sched.h>1414-#include <linux/delay.h>1515-#include <linux/interrupt.h>1616-#include <linux/fs.h>1717-#include <linux/console.h>1818-#include <linux/genhd.h>1919-#include <linux/errno.h>2020-#include <linux/string.h>2121-#include <linux/init.h>2222-#include <linux/bootmem.h>2323-#include <linux/proc_fs.h>2424-#include <linux/seq_file.h>2525-#include <linux/module.h>2626-#include <linux/initrd.h>2727-2828-#include <asm/bootinfo.h>2929-#include <asm/sections.h>3030-#include <asm/setup.h>3131-#include <asm/fpu.h>3232-#include <asm/irq.h>3333-#include <asm/io.h>3434-#include <asm/machdep.h>3535-#ifdef CONFIG_AMIGA3636-#include <asm/amigahw.h>3737-#endif3838-#ifdef CONFIG_ATARI3939-#include <asm/atarihw.h>4040-#include <asm/atari_stram.h>4141-#endif4242-#ifdef CONFIG_SUN3X4343-#include <asm/dvma.h>4444-#endif4545-#include <asm/natfeat.h>4646-4747-#if !FPSTATESIZE || !NR_IRQS4848-#warning No CPU/platform type selected, your kernel will not work!4949-#warning Are you building an allnoconfig kernel?5050-#endif5151-5252-unsigned long m68k_machtype;5353-EXPORT_SYMBOL(m68k_machtype);5454-unsigned long m68k_cputype;5555-EXPORT_SYMBOL(m68k_cputype);5656-unsigned long m68k_fputype;5757-unsigned long m68k_mmutype;5858-EXPORT_SYMBOL(m68k_mmutype);5959-#ifdef CONFIG_VME6060-unsigned long vme_brdtype;6161-EXPORT_SYMBOL(vme_brdtype);6262-#endif6363-6464-int m68k_is040or060;6565-EXPORT_SYMBOL(m68k_is040or060);6666-6767-extern unsigned long availmem;6868-6969-int m68k_num_memory;7070-EXPORT_SYMBOL(m68k_num_memory);7171-int m68k_realnum_memory;7272-EXPORT_SYMBOL(m68k_realnum_memory);7373-unsigned long m68k_memoffset;7474-struct mem_info m68k_memory[NUM_MEMINFO];7575-EXPORT_SYMBOL(m68k_memory);7676-7777-struct mem_info m68k_ramdisk;7878-7979-static char m68k_command_line[CL_SIZE];8080-8181-void (*mach_sched_init) (irq_handler_t handler) __initdata = NULL;8282-/* machine dependent irq functions */8383-void (*mach_init_IRQ) (void) __initdata = NULL;8484-void (*mach_get_model) (char *model);8585-void (*mach_get_hardware_list) (struct seq_file *m);8686-/* machine dependent timer functions */8787-unsigned long (*mach_gettimeoffset) (void);8888-int (*mach_hwclk) (int, struct rtc_time*);8989-EXPORT_SYMBOL(mach_hwclk);9090-int (*mach_set_clock_mmss) (unsigned long);9191-unsigned int (*mach_get_ss)(void);9292-int (*mach_get_rtc_pll)(struct rtc_pll_info *);9393-int (*mach_set_rtc_pll)(struct rtc_pll_info *);9494-EXPORT_SYMBOL(mach_get_ss);9595-EXPORT_SYMBOL(mach_get_rtc_pll);9696-EXPORT_SYMBOL(mach_set_rtc_pll);9797-void (*mach_reset)( void );9898-void (*mach_halt)( void );9999-void (*mach_power_off)( void );100100-long mach_max_dma_address = 0x00ffffff; /* default set to the lower 16MB */101101-#ifdef CONFIG_HEARTBEAT102102-void (*mach_heartbeat) (int);103103-EXPORT_SYMBOL(mach_heartbeat);104104-#endif105105-#ifdef CONFIG_M68K_L2_CACHE106106-void (*mach_l2_flush) (int);107107-#endif108108-#if defined(CONFIG_INPUT_M68K_BEEP) || defined(CONFIG_INPUT_M68K_BEEP_MODULE)109109-void (*mach_beep)(unsigned int, unsigned int);110110-EXPORT_SYMBOL(mach_beep);111111-#endif112112-#if defined(CONFIG_ISA) && defined(MULTI_ISA)113113-int isa_type;114114-int isa_sex;115115-EXPORT_SYMBOL(isa_type);116116-EXPORT_SYMBOL(isa_sex);117117-#endif118118-119119-extern int amiga_parse_bootinfo(const struct bi_record *);120120-extern int atari_parse_bootinfo(const struct bi_record *);121121-extern int mac_parse_bootinfo(const struct bi_record *);122122-extern int q40_parse_bootinfo(const struct bi_record *);123123-extern int bvme6000_parse_bootinfo(const struct bi_record *);124124-extern int mvme16x_parse_bootinfo(const struct bi_record *);125125-extern int mvme147_parse_bootinfo(const struct bi_record *);126126-extern int hp300_parse_bootinfo(const struct bi_record *);127127-extern int apollo_parse_bootinfo(const struct bi_record *);128128-129129-extern void config_amiga(void);130130-extern void config_atari(void);131131-extern void config_mac(void);132132-extern void config_sun3(void);133133-extern void config_apollo(void);134134-extern void config_mvme147(void);135135-extern void config_mvme16x(void);136136-extern void config_bvme6000(void);137137-extern void config_hp300(void);138138-extern void config_q40(void);139139-extern void config_sun3x(void);140140-141141-#define MASK_256K 0xfffc0000142142-143143-extern void paging_init(void);144144-145145-static void __init m68k_parse_bootinfo(const struct bi_record *record)146146-{147147- while (record->tag != BI_LAST) {148148- int unknown = 0;149149- const unsigned long *data = record->data;150150-151151- switch (record->tag) {152152- case BI_MACHTYPE:153153- case BI_CPUTYPE:154154- case BI_FPUTYPE:155155- case BI_MMUTYPE:156156- /* Already set up by head.S */157157- break;158158-159159- case BI_MEMCHUNK:160160- if (m68k_num_memory < NUM_MEMINFO) {161161- m68k_memory[m68k_num_memory].addr = data[0];162162- m68k_memory[m68k_num_memory].size = data[1];163163- m68k_num_memory++;164164- } else165165- printk("m68k_parse_bootinfo: too many memory chunks\n");166166- break;167167-168168- case BI_RAMDISK:169169- m68k_ramdisk.addr = data[0];170170- m68k_ramdisk.size = data[1];171171- break;172172-173173- case BI_COMMAND_LINE:174174- strlcpy(m68k_command_line, (const char *)data,175175- sizeof(m68k_command_line));176176- break;177177-178178- default:179179- if (MACH_IS_AMIGA)180180- unknown = amiga_parse_bootinfo(record);181181- else if (MACH_IS_ATARI)182182- unknown = atari_parse_bootinfo(record);183183- else if (MACH_IS_MAC)184184- unknown = mac_parse_bootinfo(record);185185- else if (MACH_IS_Q40)186186- unknown = q40_parse_bootinfo(record);187187- else if (MACH_IS_BVME6000)188188- unknown = bvme6000_parse_bootinfo(record);189189- else if (MACH_IS_MVME16x)190190- unknown = mvme16x_parse_bootinfo(record);191191- else if (MACH_IS_MVME147)192192- unknown = mvme147_parse_bootinfo(record);193193- else if (MACH_IS_HP300)194194- unknown = hp300_parse_bootinfo(record);195195- else if (MACH_IS_APOLLO)196196- unknown = apollo_parse_bootinfo(record);197197- else198198- unknown = 1;199199- }200200- if (unknown)201201- printk("m68k_parse_bootinfo: unknown tag 0x%04x ignored\n",202202- record->tag);203203- record = (struct bi_record *)((unsigned long)record +204204- record->size);205205- }206206-207207- m68k_realnum_memory = m68k_num_memory;208208-#ifdef CONFIG_SINGLE_MEMORY_CHUNK209209- if (m68k_num_memory > 1) {210210- printk("Ignoring last %i chunks of physical memory\n",211211- (m68k_num_memory - 1));212212- m68k_num_memory = 1;213213- }214214-#endif215215-}216216-217217-void __init setup_arch(char **cmdline_p)218218-{219219- int i;220220-221221- /* The bootinfo is located right after the kernel bss */222222- m68k_parse_bootinfo((const struct bi_record *)_end);223223-224224- if (CPU_IS_040)225225- m68k_is040or060 = 4;226226- else if (CPU_IS_060)227227- m68k_is040or060 = 6;228228-229229- /* FIXME: m68k_fputype is passed in by Penguin booter, which can230230- * be confused by software FPU emulation. BEWARE.231231- * We should really do our own FPU check at startup.232232- * [what do we do with buggy 68LC040s? if we have problems233233- * with them, we should add a test to check_bugs() below] */234234-#ifndef CONFIG_M68KFPU_EMU_ONLY235235- /* clear the fpu if we have one */236236- if (m68k_fputype & (FPU_68881|FPU_68882|FPU_68040|FPU_68060)) {237237- volatile int zero = 0;238238- asm volatile ("frestore %0" : : "m" (zero));239239- }240240-#endif241241-242242- if (CPU_IS_060) {243243- u32 pcr;244244-245245- asm (".chip 68060; movec %%pcr,%0; .chip 68k"246246- : "=d" (pcr));247247- if (((pcr >> 8) & 0xff) <= 5) {248248- printk("Enabling workaround for errata I14\n");249249- asm (".chip 68060; movec %0,%%pcr; .chip 68k"250250- : : "d" (pcr | 0x20));251251- }252252- }253253-254254- init_mm.start_code = PAGE_OFFSET;255255- init_mm.end_code = (unsigned long)_etext;256256- init_mm.end_data = (unsigned long)_edata;257257- init_mm.brk = (unsigned long)_end;258258-259259- *cmdline_p = m68k_command_line;260260- memcpy(boot_command_line, *cmdline_p, CL_SIZE);261261-262262- parse_early_param();263263-264264-#ifdef CONFIG_DUMMY_CONSOLE265265- conswitchp = &dummy_con;266266-#endif267267-268268- switch (m68k_machtype) {269269-#ifdef CONFIG_AMIGA270270- case MACH_AMIGA:271271- config_amiga();272272- break;273273-#endif274274-#ifdef CONFIG_ATARI275275- case MACH_ATARI:276276- config_atari();277277- break;278278-#endif279279-#ifdef CONFIG_MAC280280- case MACH_MAC:281281- config_mac();282282- break;283283-#endif284284-#ifdef CONFIG_SUN3285285- case MACH_SUN3:286286- config_sun3();287287- break;288288-#endif289289-#ifdef CONFIG_APOLLO290290- case MACH_APOLLO:291291- config_apollo();292292- break;293293-#endif294294-#ifdef CONFIG_MVME147295295- case MACH_MVME147:296296- config_mvme147();297297- break;298298-#endif299299-#ifdef CONFIG_MVME16x300300- case MACH_MVME16x:301301- config_mvme16x();302302- break;303303-#endif304304-#ifdef CONFIG_BVME6000305305- case MACH_BVME6000:306306- config_bvme6000();307307- break;308308-#endif309309-#ifdef CONFIG_HP300310310- case MACH_HP300:311311- config_hp300();312312- break;313313-#endif314314-#ifdef CONFIG_Q40315315- case MACH_Q40:316316- config_q40();317317- break;318318-#endif319319-#ifdef CONFIG_SUN3X320320- case MACH_SUN3X:321321- config_sun3x();322322- break;323323-#endif324324- default:325325- panic("No configuration setup");326326- }327327-328328-#ifdef CONFIG_NATFEAT329329- nf_init();330330-#endif331331-332332- paging_init();333333-334334-#ifndef CONFIG_SUN3335335- for (i = 1; i < m68k_num_memory; i++)336336- free_bootmem_node(NODE_DATA(i), m68k_memory[i].addr,337337- m68k_memory[i].size);338338-#ifdef CONFIG_BLK_DEV_INITRD339339- if (m68k_ramdisk.size) {340340- reserve_bootmem_node(__virt_to_node(phys_to_virt(m68k_ramdisk.addr)),341341- m68k_ramdisk.addr, m68k_ramdisk.size,342342- BOOTMEM_DEFAULT);343343- initrd_start = (unsigned long)phys_to_virt(m68k_ramdisk.addr);344344- initrd_end = initrd_start + m68k_ramdisk.size;345345- printk("initrd: %08lx - %08lx\n", initrd_start, initrd_end);346346- }347347-#endif348348-349349-#ifdef CONFIG_ATARI350350- if (MACH_IS_ATARI)351351- atari_stram_reserve_pages((void *)availmem);352352-#endif353353-#ifdef CONFIG_SUN3X354354- if (MACH_IS_SUN3X) {355355- dvma_init();356356- }357357-#endif358358-359359-#endif /* !CONFIG_SUN3 */360360-361361-/* set ISA defs early as possible */362362-#if defined(CONFIG_ISA) && defined(MULTI_ISA)363363- if (MACH_IS_Q40) {364364- isa_type = ISA_TYPE_Q40;365365- isa_sex = 0;366366- }367367-#ifdef CONFIG_AMIGA_PCMCIA368368- if (MACH_IS_AMIGA && AMIGAHW_PRESENT(PCMCIA)) {369369- isa_type = ISA_TYPE_AG;370370- isa_sex = 1;371371- }372372-#endif373373-#endif374374-}375375-376376-static int show_cpuinfo(struct seq_file *m, void *v)377377-{378378- const char *cpu, *mmu, *fpu;379379- unsigned long clockfreq, clockfactor;380380-381381-#define LOOP_CYCLES_68020 (8)382382-#define LOOP_CYCLES_68030 (8)383383-#define LOOP_CYCLES_68040 (3)384384-#define LOOP_CYCLES_68060 (1)385385-386386- if (CPU_IS_020) {387387- cpu = "68020";388388- clockfactor = LOOP_CYCLES_68020;389389- } else if (CPU_IS_030) {390390- cpu = "68030";391391- clockfactor = LOOP_CYCLES_68030;392392- } else if (CPU_IS_040) {393393- cpu = "68040";394394- clockfactor = LOOP_CYCLES_68040;395395- } else if (CPU_IS_060) {396396- cpu = "68060";397397- clockfactor = LOOP_CYCLES_68060;398398- } else {399399- cpu = "680x0";400400- clockfactor = 0;401401- }402402-403403-#ifdef CONFIG_M68KFPU_EMU_ONLY404404- fpu = "none(soft float)";11+#ifdef CONFIG_MMU22+#include "setup_mm.c"4053#else406406- if (m68k_fputype & FPU_68881)407407- fpu = "68881";408408- else if (m68k_fputype & FPU_68882)409409- fpu = "68882";410410- else if (m68k_fputype & FPU_68040)411411- fpu = "68040";412412- else if (m68k_fputype & FPU_68060)413413- fpu = "68060";414414- else if (m68k_fputype & FPU_SUNFPA)415415- fpu = "Sun FPA";416416- else417417- fpu = "none";44+#include "setup_no.c"4185#endif419419-420420- if (m68k_mmutype & MMU_68851)421421- mmu = "68851";422422- else if (m68k_mmutype & MMU_68030)423423- mmu = "68030";424424- else if (m68k_mmutype & MMU_68040)425425- mmu = "68040";426426- else if (m68k_mmutype & MMU_68060)427427- mmu = "68060";428428- else if (m68k_mmutype & MMU_SUN3)429429- mmu = "Sun-3";430430- else if (m68k_mmutype & MMU_APOLLO)431431- mmu = "Apollo";432432- else433433- mmu = "unknown";434434-435435- clockfreq = loops_per_jiffy * HZ * clockfactor;436436-437437- seq_printf(m, "CPU:\t\t%s\n"438438- "MMU:\t\t%s\n"439439- "FPU:\t\t%s\n"440440- "Clocking:\t%lu.%1luMHz\n"441441- "BogoMips:\t%lu.%02lu\n"442442- "Calibration:\t%lu loops\n",443443- cpu, mmu, fpu,444444- clockfreq/1000000,(clockfreq/100000)%10,445445- loops_per_jiffy/(500000/HZ),(loops_per_jiffy/(5000/HZ))%100,446446- loops_per_jiffy);447447- return 0;448448-}449449-450450-static void *c_start(struct seq_file *m, loff_t *pos)451451-{452452- return *pos < 1 ? (void *)1 : NULL;453453-}454454-static void *c_next(struct seq_file *m, void *v, loff_t *pos)455455-{456456- ++*pos;457457- return NULL;458458-}459459-static void c_stop(struct seq_file *m, void *v)460460-{461461-}462462-const struct seq_operations cpuinfo_op = {463463- .start = c_start,464464- .next = c_next,465465- .stop = c_stop,466466- .show = show_cpuinfo,467467-};468468-469469-#ifdef CONFIG_PROC_HARDWARE470470-static int hardware_proc_show(struct seq_file *m, void *v)471471-{472472- char model[80];473473- unsigned long mem;474474- int i;475475-476476- if (mach_get_model)477477- mach_get_model(model);478478- else479479- strcpy(model, "Unknown m68k");480480-481481- seq_printf(m, "Model:\t\t%s\n", model);482482- for (mem = 0, i = 0; i < m68k_num_memory; i++)483483- mem += m68k_memory[i].size;484484- seq_printf(m, "System Memory:\t%ldK\n", mem >> 10);485485-486486- if (mach_get_hardware_list)487487- mach_get_hardware_list(m);488488-489489- return 0;490490-}491491-492492-static int hardware_proc_open(struct inode *inode, struct file *file)493493-{494494- return single_open(file, hardware_proc_show, NULL);495495-}496496-497497-static const struct file_operations hardware_proc_fops = {498498- .open = hardware_proc_open,499499- .read = seq_read,500500- .llseek = seq_lseek,501501- .release = single_release,502502-};503503-504504-static int __init proc_hardware_init(void)505505-{506506- proc_create("hardware", 0, NULL, &hardware_proc_fops);507507- return 0;508508-}509509-module_init(proc_hardware_init);510510-#endif511511-512512-void check_bugs(void)513513-{514514-#ifndef CONFIG_M68KFPU_EMU515515- if (m68k_fputype == 0) {516516- printk(KERN_EMERG "*** YOU DO NOT HAVE A FLOATING POINT UNIT, "517517- "WHICH IS REQUIRED BY LINUX/M68K ***\n");518518- printk(KERN_EMERG "Upgrade your hardware or join the FPU "519519- "emulation project\n");520520- panic("no FPU");521521- }522522-#endif /* !CONFIG_M68KFPU_EMU */523523-}524524-525525-#ifdef CONFIG_ADB526526-static int __init adb_probe_sync_enable (char *str) {527527- extern int __adb_probe_sync;528528- __adb_probe_sync = 1;529529- return 1;530530-}531531-532532-__setup("adb_sync", adb_probe_sync_enable);533533-#endif /* CONFIG_ADB */
+533
arch/m68k/kernel/setup_mm.c
···11+/*22+ * linux/arch/m68k/kernel/setup.c33+ *44+ * Copyright (C) 1995 Hamish Macdonald55+ */66+77+/*88+ * This file handles the architecture-dependent parts of system setup99+ */1010+1111+#include <linux/kernel.h>1212+#include <linux/mm.h>1313+#include <linux/sched.h>1414+#include <linux/delay.h>1515+#include <linux/interrupt.h>1616+#include <linux/fs.h>1717+#include <linux/console.h>1818+#include <linux/genhd.h>1919+#include <linux/errno.h>2020+#include <linux/string.h>2121+#include <linux/init.h>2222+#include <linux/bootmem.h>2323+#include <linux/proc_fs.h>2424+#include <linux/seq_file.h>2525+#include <linux/module.h>2626+#include <linux/initrd.h>2727+2828+#include <asm/bootinfo.h>2929+#include <asm/sections.h>3030+#include <asm/setup.h>3131+#include <asm/fpu.h>3232+#include <asm/irq.h>3333+#include <asm/io.h>3434+#include <asm/machdep.h>3535+#ifdef CONFIG_AMIGA3636+#include <asm/amigahw.h>3737+#endif3838+#ifdef CONFIG_ATARI3939+#include <asm/atarihw.h>4040+#include <asm/atari_stram.h>4141+#endif4242+#ifdef CONFIG_SUN3X4343+#include <asm/dvma.h>4444+#endif4545+#include <asm/natfeat.h>4646+4747+#if !FPSTATESIZE || !NR_IRQS4848+#warning No CPU/platform type selected, your kernel will not work!4949+#warning Are you building an allnoconfig kernel?5050+#endif5151+5252+unsigned long m68k_machtype;5353+EXPORT_SYMBOL(m68k_machtype);5454+unsigned long m68k_cputype;5555+EXPORT_SYMBOL(m68k_cputype);5656+unsigned long m68k_fputype;5757+unsigned long m68k_mmutype;5858+EXPORT_SYMBOL(m68k_mmutype);5959+#ifdef CONFIG_VME6060+unsigned long vme_brdtype;6161+EXPORT_SYMBOL(vme_brdtype);6262+#endif6363+6464+int m68k_is040or060;6565+EXPORT_SYMBOL(m68k_is040or060);6666+6767+extern unsigned long availmem;6868+6969+int m68k_num_memory;7070+EXPORT_SYMBOL(m68k_num_memory);7171+int m68k_realnum_memory;7272+EXPORT_SYMBOL(m68k_realnum_memory);7373+unsigned long m68k_memoffset;7474+struct mem_info m68k_memory[NUM_MEMINFO];7575+EXPORT_SYMBOL(m68k_memory);7676+7777+struct mem_info m68k_ramdisk;7878+7979+static char m68k_command_line[CL_SIZE];8080+8181+void (*mach_sched_init) (irq_handler_t handler) __initdata = NULL;8282+/* machine dependent irq functions */8383+void (*mach_init_IRQ) (void) __initdata = NULL;8484+void (*mach_get_model) (char *model);8585+void (*mach_get_hardware_list) (struct seq_file *m);8686+/* machine dependent timer functions */8787+unsigned long (*mach_gettimeoffset) (void);8888+int (*mach_hwclk) (int, struct rtc_time*);8989+EXPORT_SYMBOL(mach_hwclk);9090+int (*mach_set_clock_mmss) (unsigned long);9191+unsigned int (*mach_get_ss)(void);9292+int (*mach_get_rtc_pll)(struct rtc_pll_info *);9393+int (*mach_set_rtc_pll)(struct rtc_pll_info *);9494+EXPORT_SYMBOL(mach_get_ss);9595+EXPORT_SYMBOL(mach_get_rtc_pll);9696+EXPORT_SYMBOL(mach_set_rtc_pll);9797+void (*mach_reset)( void );9898+void (*mach_halt)( void );9999+void (*mach_power_off)( void );100100+long mach_max_dma_address = 0x00ffffff; /* default set to the lower 16MB */101101+#ifdef CONFIG_HEARTBEAT102102+void (*mach_heartbeat) (int);103103+EXPORT_SYMBOL(mach_heartbeat);104104+#endif105105+#ifdef CONFIG_M68K_L2_CACHE106106+void (*mach_l2_flush) (int);107107+#endif108108+#if defined(CONFIG_INPUT_M68K_BEEP) || defined(CONFIG_INPUT_M68K_BEEP_MODULE)109109+void (*mach_beep)(unsigned int, unsigned int);110110+EXPORT_SYMBOL(mach_beep);111111+#endif112112+#if defined(CONFIG_ISA) && defined(MULTI_ISA)113113+int isa_type;114114+int isa_sex;115115+EXPORT_SYMBOL(isa_type);116116+EXPORT_SYMBOL(isa_sex);117117+#endif118118+119119+extern int amiga_parse_bootinfo(const struct bi_record *);120120+extern int atari_parse_bootinfo(const struct bi_record *);121121+extern int mac_parse_bootinfo(const struct bi_record *);122122+extern int q40_parse_bootinfo(const struct bi_record *);123123+extern int bvme6000_parse_bootinfo(const struct bi_record *);124124+extern int mvme16x_parse_bootinfo(const struct bi_record *);125125+extern int mvme147_parse_bootinfo(const struct bi_record *);126126+extern int hp300_parse_bootinfo(const struct bi_record *);127127+extern int apollo_parse_bootinfo(const struct bi_record *);128128+129129+extern void config_amiga(void);130130+extern void config_atari(void);131131+extern void config_mac(void);132132+extern void config_sun3(void);133133+extern void config_apollo(void);134134+extern void config_mvme147(void);135135+extern void config_mvme16x(void);136136+extern void config_bvme6000(void);137137+extern void config_hp300(void);138138+extern void config_q40(void);139139+extern void config_sun3x(void);140140+141141+#define MASK_256K 0xfffc0000142142+143143+extern void paging_init(void);144144+145145+static void __init m68k_parse_bootinfo(const struct bi_record *record)146146+{147147+ while (record->tag != BI_LAST) {148148+ int unknown = 0;149149+ const unsigned long *data = record->data;150150+151151+ switch (record->tag) {152152+ case BI_MACHTYPE:153153+ case BI_CPUTYPE:154154+ case BI_FPUTYPE:155155+ case BI_MMUTYPE:156156+ /* Already set up by head.S */157157+ break;158158+159159+ case BI_MEMCHUNK:160160+ if (m68k_num_memory < NUM_MEMINFO) {161161+ m68k_memory[m68k_num_memory].addr = data[0];162162+ m68k_memory[m68k_num_memory].size = data[1];163163+ m68k_num_memory++;164164+ } else165165+ printk("m68k_parse_bootinfo: too many memory chunks\n");166166+ break;167167+168168+ case BI_RAMDISK:169169+ m68k_ramdisk.addr = data[0];170170+ m68k_ramdisk.size = data[1];171171+ break;172172+173173+ case BI_COMMAND_LINE:174174+ strlcpy(m68k_command_line, (const char *)data,175175+ sizeof(m68k_command_line));176176+ break;177177+178178+ default:179179+ if (MACH_IS_AMIGA)180180+ unknown = amiga_parse_bootinfo(record);181181+ else if (MACH_IS_ATARI)182182+ unknown = atari_parse_bootinfo(record);183183+ else if (MACH_IS_MAC)184184+ unknown = mac_parse_bootinfo(record);185185+ else if (MACH_IS_Q40)186186+ unknown = q40_parse_bootinfo(record);187187+ else if (MACH_IS_BVME6000)188188+ unknown = bvme6000_parse_bootinfo(record);189189+ else if (MACH_IS_MVME16x)190190+ unknown = mvme16x_parse_bootinfo(record);191191+ else if (MACH_IS_MVME147)192192+ unknown = mvme147_parse_bootinfo(record);193193+ else if (MACH_IS_HP300)194194+ unknown = hp300_parse_bootinfo(record);195195+ else if (MACH_IS_APOLLO)196196+ unknown = apollo_parse_bootinfo(record);197197+ else198198+ unknown = 1;199199+ }200200+ if (unknown)201201+ printk("m68k_parse_bootinfo: unknown tag 0x%04x ignored\n",202202+ record->tag);203203+ record = (struct bi_record *)((unsigned long)record +204204+ record->size);205205+ }206206+207207+ m68k_realnum_memory = m68k_num_memory;208208+#ifdef CONFIG_SINGLE_MEMORY_CHUNK209209+ if (m68k_num_memory > 1) {210210+ printk("Ignoring last %i chunks of physical memory\n",211211+ (m68k_num_memory - 1));212212+ m68k_num_memory = 1;213213+ }214214+#endif215215+}216216+217217+void __init setup_arch(char **cmdline_p)218218+{219219+ int i;220220+221221+ /* The bootinfo is located right after the kernel bss */222222+ m68k_parse_bootinfo((const struct bi_record *)_end);223223+224224+ if (CPU_IS_040)225225+ m68k_is040or060 = 4;226226+ else if (CPU_IS_060)227227+ m68k_is040or060 = 6;228228+229229+ /* FIXME: m68k_fputype is passed in by Penguin booter, which can230230+ * be confused by software FPU emulation. BEWARE.231231+ * We should really do our own FPU check at startup.232232+ * [what do we do with buggy 68LC040s? if we have problems233233+ * with them, we should add a test to check_bugs() below] */234234+#ifndef CONFIG_M68KFPU_EMU_ONLY235235+ /* clear the fpu if we have one */236236+ if (m68k_fputype & (FPU_68881|FPU_68882|FPU_68040|FPU_68060)) {237237+ volatile int zero = 0;238238+ asm volatile ("frestore %0" : : "m" (zero));239239+ }240240+#endif241241+242242+ if (CPU_IS_060) {243243+ u32 pcr;244244+245245+ asm (".chip 68060; movec %%pcr,%0; .chip 68k"246246+ : "=d" (pcr));247247+ if (((pcr >> 8) & 0xff) <= 5) {248248+ printk("Enabling workaround for errata I14\n");249249+ asm (".chip 68060; movec %0,%%pcr; .chip 68k"250250+ : : "d" (pcr | 0x20));251251+ }252252+ }253253+254254+ init_mm.start_code = PAGE_OFFSET;255255+ init_mm.end_code = (unsigned long)_etext;256256+ init_mm.end_data = (unsigned long)_edata;257257+ init_mm.brk = (unsigned long)_end;258258+259259+ *cmdline_p = m68k_command_line;260260+ memcpy(boot_command_line, *cmdline_p, CL_SIZE);261261+262262+ parse_early_param();263263+264264+#ifdef CONFIG_DUMMY_CONSOLE265265+ conswitchp = &dummy_con;266266+#endif267267+268268+ switch (m68k_machtype) {269269+#ifdef CONFIG_AMIGA270270+ case MACH_AMIGA:271271+ config_amiga();272272+ break;273273+#endif274274+#ifdef CONFIG_ATARI275275+ case MACH_ATARI:276276+ config_atari();277277+ break;278278+#endif279279+#ifdef CONFIG_MAC280280+ case MACH_MAC:281281+ config_mac();282282+ break;283283+#endif284284+#ifdef CONFIG_SUN3285285+ case MACH_SUN3:286286+ config_sun3();287287+ break;288288+#endif289289+#ifdef CONFIG_APOLLO290290+ case MACH_APOLLO:291291+ config_apollo();292292+ break;293293+#endif294294+#ifdef CONFIG_MVME147295295+ case MACH_MVME147:296296+ config_mvme147();297297+ break;298298+#endif299299+#ifdef CONFIG_MVME16x300300+ case MACH_MVME16x:301301+ config_mvme16x();302302+ break;303303+#endif304304+#ifdef CONFIG_BVME6000305305+ case MACH_BVME6000:306306+ config_bvme6000();307307+ break;308308+#endif309309+#ifdef CONFIG_HP300310310+ case MACH_HP300:311311+ config_hp300();312312+ break;313313+#endif314314+#ifdef CONFIG_Q40315315+ case MACH_Q40:316316+ config_q40();317317+ break;318318+#endif319319+#ifdef CONFIG_SUN3X320320+ case MACH_SUN3X:321321+ config_sun3x();322322+ break;323323+#endif324324+ default:325325+ panic("No configuration setup");326326+ }327327+328328+#ifdef CONFIG_NATFEAT329329+ nf_init();330330+#endif331331+332332+ paging_init();333333+334334+#ifndef CONFIG_SUN3335335+ for (i = 1; i < m68k_num_memory; i++)336336+ free_bootmem_node(NODE_DATA(i), m68k_memory[i].addr,337337+ m68k_memory[i].size);338338+#ifdef CONFIG_BLK_DEV_INITRD339339+ if (m68k_ramdisk.size) {340340+ reserve_bootmem_node(__virt_to_node(phys_to_virt(m68k_ramdisk.addr)),341341+ m68k_ramdisk.addr, m68k_ramdisk.size,342342+ BOOTMEM_DEFAULT);343343+ initrd_start = (unsigned long)phys_to_virt(m68k_ramdisk.addr);344344+ initrd_end = initrd_start + m68k_ramdisk.size;345345+ printk("initrd: %08lx - %08lx\n", initrd_start, initrd_end);346346+ }347347+#endif348348+349349+#ifdef CONFIG_ATARI350350+ if (MACH_IS_ATARI)351351+ atari_stram_reserve_pages((void *)availmem);352352+#endif353353+#ifdef CONFIG_SUN3X354354+ if (MACH_IS_SUN3X) {355355+ dvma_init();356356+ }357357+#endif358358+359359+#endif /* !CONFIG_SUN3 */360360+361361+/* set ISA defs early as possible */362362+#if defined(CONFIG_ISA) && defined(MULTI_ISA)363363+ if (MACH_IS_Q40) {364364+ isa_type = ISA_TYPE_Q40;365365+ isa_sex = 0;366366+ }367367+#ifdef CONFIG_AMIGA_PCMCIA368368+ if (MACH_IS_AMIGA && AMIGAHW_PRESENT(PCMCIA)) {369369+ isa_type = ISA_TYPE_AG;370370+ isa_sex = 1;371371+ }372372+#endif373373+#endif374374+}375375+376376+static int show_cpuinfo(struct seq_file *m, void *v)377377+{378378+ const char *cpu, *mmu, *fpu;379379+ unsigned long clockfreq, clockfactor;380380+381381+#define LOOP_CYCLES_68020 (8)382382+#define LOOP_CYCLES_68030 (8)383383+#define LOOP_CYCLES_68040 (3)384384+#define LOOP_CYCLES_68060 (1)385385+386386+ if (CPU_IS_020) {387387+ cpu = "68020";388388+ clockfactor = LOOP_CYCLES_68020;389389+ } else if (CPU_IS_030) {390390+ cpu = "68030";391391+ clockfactor = LOOP_CYCLES_68030;392392+ } else if (CPU_IS_040) {393393+ cpu = "68040";394394+ clockfactor = LOOP_CYCLES_68040;395395+ } else if (CPU_IS_060) {396396+ cpu = "68060";397397+ clockfactor = LOOP_CYCLES_68060;398398+ } else {399399+ cpu = "680x0";400400+ clockfactor = 0;401401+ }402402+403403+#ifdef CONFIG_M68KFPU_EMU_ONLY404404+ fpu = "none(soft float)";405405+#else406406+ if (m68k_fputype & FPU_68881)407407+ fpu = "68881";408408+ else if (m68k_fputype & FPU_68882)409409+ fpu = "68882";410410+ else if (m68k_fputype & FPU_68040)411411+ fpu = "68040";412412+ else if (m68k_fputype & FPU_68060)413413+ fpu = "68060";414414+ else if (m68k_fputype & FPU_SUNFPA)415415+ fpu = "Sun FPA";416416+ else417417+ fpu = "none";418418+#endif419419+420420+ if (m68k_mmutype & MMU_68851)421421+ mmu = "68851";422422+ else if (m68k_mmutype & MMU_68030)423423+ mmu = "68030";424424+ else if (m68k_mmutype & MMU_68040)425425+ mmu = "68040";426426+ else if (m68k_mmutype & MMU_68060)427427+ mmu = "68060";428428+ else if (m68k_mmutype & MMU_SUN3)429429+ mmu = "Sun-3";430430+ else if (m68k_mmutype & MMU_APOLLO)431431+ mmu = "Apollo";432432+ else433433+ mmu = "unknown";434434+435435+ clockfreq = loops_per_jiffy * HZ * clockfactor;436436+437437+ seq_printf(m, "CPU:\t\t%s\n"438438+ "MMU:\t\t%s\n"439439+ "FPU:\t\t%s\n"440440+ "Clocking:\t%lu.%1luMHz\n"441441+ "BogoMips:\t%lu.%02lu\n"442442+ "Calibration:\t%lu loops\n",443443+ cpu, mmu, fpu,444444+ clockfreq/1000000,(clockfreq/100000)%10,445445+ loops_per_jiffy/(500000/HZ),(loops_per_jiffy/(5000/HZ))%100,446446+ loops_per_jiffy);447447+ return 0;448448+}449449+450450+static void *c_start(struct seq_file *m, loff_t *pos)451451+{452452+ return *pos < 1 ? (void *)1 : NULL;453453+}454454+static void *c_next(struct seq_file *m, void *v, loff_t *pos)455455+{456456+ ++*pos;457457+ return NULL;458458+}459459+static void c_stop(struct seq_file *m, void *v)460460+{461461+}462462+const struct seq_operations cpuinfo_op = {463463+ .start = c_start,464464+ .next = c_next,465465+ .stop = c_stop,466466+ .show = show_cpuinfo,467467+};468468+469469+#ifdef CONFIG_PROC_HARDWARE470470+static int hardware_proc_show(struct seq_file *m, void *v)471471+{472472+ char model[80];473473+ unsigned long mem;474474+ int i;475475+476476+ if (mach_get_model)477477+ mach_get_model(model);478478+ else479479+ strcpy(model, "Unknown m68k");480480+481481+ seq_printf(m, "Model:\t\t%s\n", model);482482+ for (mem = 0, i = 0; i < m68k_num_memory; i++)483483+ mem += m68k_memory[i].size;484484+ seq_printf(m, "System Memory:\t%ldK\n", mem >> 10);485485+486486+ if (mach_get_hardware_list)487487+ mach_get_hardware_list(m);488488+489489+ return 0;490490+}491491+492492+static int hardware_proc_open(struct inode *inode, struct file *file)493493+{494494+ return single_open(file, hardware_proc_show, NULL);495495+}496496+497497+static const struct file_operations hardware_proc_fops = {498498+ .open = hardware_proc_open,499499+ .read = seq_read,500500+ .llseek = seq_lseek,501501+ .release = single_release,502502+};503503+504504+static int __init proc_hardware_init(void)505505+{506506+ proc_create("hardware", 0, NULL, &hardware_proc_fops);507507+ return 0;508508+}509509+module_init(proc_hardware_init);510510+#endif511511+512512+void check_bugs(void)513513+{514514+#ifndef CONFIG_M68KFPU_EMU515515+ if (m68k_fputype == 0) {516516+ printk(KERN_EMERG "*** YOU DO NOT HAVE A FLOATING POINT UNIT, "517517+ "WHICH IS REQUIRED BY LINUX/M68K ***\n");518518+ printk(KERN_EMERG "Upgrade your hardware or join the FPU "519519+ "emulation project\n");520520+ panic("no FPU");521521+ }522522+#endif /* !CONFIG_M68KFPU_EMU */523523+}524524+525525+#ifdef CONFIG_ADB526526+static int __init adb_probe_sync_enable (char *str) {527527+ extern int __adb_probe_sync;528528+ __adb_probe_sync = 1;529529+ return 1;530530+}531531+532532+__setup("adb_sync", adb_probe_sync_enable);533533+#endif /* CONFIG_ADB */
+3-1015
arch/m68k/kernel/signal.c
···11-/*22- * linux/arch/m68k/kernel/signal.c33- *44- * Copyright (C) 1991, 1992 Linus Torvalds55- *66- * This file is subject to the terms and conditions of the GNU General Public77- * License. See the file COPYING in the main directory of this archive88- * for more details.99- */1010-1111-/*1212- * Linux/m68k support by Hamish Macdonald1313- *1414- * 68060 fixes by Jesper Skov1515- *1616- * 1997-12-01 Modified for POSIX.1b signals by Andreas Schwab1717- *1818- * mathemu support by Roman Zippel1919- * (Note: fpstate in the signal context is completely ignored for the emulator2020- * and the internal floating point format is put on stack)2121- */2222-2323-/*2424- * ++roman (07/09/96): implemented signal stacks (specially for tosemu on2525- * Atari :-) Current limitation: Only one sigstack can be active at one time.2626- * If a second signal with SA_ONSTACK set arrives while working on a sigstack,2727- * SA_ONSTACK is ignored. This behaviour avoids lots of trouble with nested2828- * signal handlers!2929- */3030-3131-#include <linux/sched.h>3232-#include <linux/mm.h>3333-#include <linux/kernel.h>3434-#include <linux/signal.h>3535-#include <linux/syscalls.h>3636-#include <linux/errno.h>3737-#include <linux/wait.h>3838-#include <linux/ptrace.h>3939-#include <linux/unistd.h>4040-#include <linux/stddef.h>4141-#include <linux/highuid.h>4242-#include <linux/personality.h>4343-#include <linux/tty.h>4444-#include <linux/binfmts.h>4545-#include <linux/module.h>4646-4747-#include <asm/setup.h>4848-#include <asm/uaccess.h>4949-#include <asm/pgtable.h>5050-#include <asm/traps.h>5151-#include <asm/ucontext.h>5252-5353-#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))5454-5555-static const int frame_extra_sizes[16] = {5656- [1] = -1, /* sizeof(((struct frame *)0)->un.fmt1), */5757- [2] = sizeof(((struct frame *)0)->un.fmt2),5858- [3] = sizeof(((struct frame *)0)->un.fmt3),5959- [4] = sizeof(((struct frame *)0)->un.fmt4),6060- [5] = -1, /* sizeof(((struct frame *)0)->un.fmt5), */6161- [6] = -1, /* sizeof(((struct frame *)0)->un.fmt6), */6262- [7] = sizeof(((struct frame *)0)->un.fmt7),6363- [8] = -1, /* sizeof(((struct frame *)0)->un.fmt8), */6464- [9] = sizeof(((struct frame *)0)->un.fmt9),6565- [10] = sizeof(((struct frame *)0)->un.fmta),6666- [11] = sizeof(((struct frame *)0)->un.fmtb),6767- [12] = -1, /* sizeof(((struct frame *)0)->un.fmtc), */6868- [13] = -1, /* sizeof(((struct frame *)0)->un.fmtd), */6969- [14] = -1, /* sizeof(((struct frame *)0)->un.fmte), */7070- [15] = -1, /* sizeof(((struct frame *)0)->un.fmtf), */7171-};7272-7373-int handle_kernel_fault(struct pt_regs *regs)7474-{7575- const struct exception_table_entry *fixup;7676- struct pt_regs *tregs;7777-7878- /* Are we prepared to handle this kernel fault? */7979- fixup = search_exception_tables(regs->pc);8080- if (!fixup)8181- return 0;8282-8383- /* Create a new four word stack frame, discarding the old one. */8484- regs->stkadj = frame_extra_sizes[regs->format];8585- tregs = (struct pt_regs *)((long)regs + regs->stkadj);8686- tregs->vector = regs->vector;8787- tregs->format = 0;8888- tregs->pc = fixup->fixup;8989- tregs->sr = regs->sr;9090-9191- return 1;9292-}9393-9494-/*9595- * Atomically swap in the new signal mask, and wait for a signal.9696- */9797-asmlinkage int9898-sys_sigsuspend(int unused0, int unused1, old_sigset_t mask)9999-{100100- mask &= _BLOCKABLE;101101- spin_lock_irq(¤t->sighand->siglock);102102- current->saved_sigmask = current->blocked;103103- siginitset(¤t->blocked, mask);104104- recalc_sigpending();105105- spin_unlock_irq(¤t->sighand->siglock);106106-107107- current->state = TASK_INTERRUPTIBLE;108108- schedule();109109- set_restore_sigmask();110110-111111- return -ERESTARTNOHAND;112112-}113113-114114-asmlinkage int115115-sys_sigaction(int sig, const struct old_sigaction __user *act,116116- struct old_sigaction __user *oact)117117-{118118- struct k_sigaction new_ka, old_ka;119119- int ret;120120-121121- if (act) {122122- old_sigset_t mask;123123- if (!access_ok(VERIFY_READ, act, sizeof(*act)) ||124124- __get_user(new_ka.sa.sa_handler, &act->sa_handler) ||125125- __get_user(new_ka.sa.sa_restorer, &act->sa_restorer) ||126126- __get_user(new_ka.sa.sa_flags, &act->sa_flags) ||127127- __get_user(mask, &act->sa_mask))128128- return -EFAULT;129129- siginitset(&new_ka.sa.sa_mask, mask);130130- }131131-132132- ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);133133-134134- if (!ret && oact) {135135- if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)) ||136136- __put_user(old_ka.sa.sa_handler, &oact->sa_handler) ||137137- __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer) ||138138- __put_user(old_ka.sa.sa_flags, &oact->sa_flags) ||139139- __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask))140140- return -EFAULT;141141- }142142-143143- return ret;144144-}145145-146146-asmlinkage int147147-sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss)148148-{149149- return do_sigaltstack(uss, uoss, rdusp());150150-}151151-152152-153153-/*154154- * Do a signal return; undo the signal stack.155155- *156156- * Keep the return code on the stack quadword aligned!157157- * That makes the cache flush below easier.158158- */159159-160160-struct sigframe161161-{162162- char __user *pretcode;163163- int sig;164164- int code;165165- struct sigcontext __user *psc;166166- char retcode[8];167167- unsigned long extramask[_NSIG_WORDS-1];168168- struct sigcontext sc;169169-};170170-171171-struct rt_sigframe172172-{173173- char __user *pretcode;174174- int sig;175175- struct siginfo __user *pinfo;176176- void __user *puc;177177- char retcode[8];178178- struct siginfo info;179179- struct ucontext uc;180180-};181181-182182-183183-static unsigned char fpu_version; /* version number of fpu, set by setup_frame */184184-185185-static inline int restore_fpu_state(struct sigcontext *sc)186186-{187187- int err = 1;188188-189189- if (FPU_IS_EMU) {190190- /* restore registers */191191- memcpy(current->thread.fpcntl, sc->sc_fpcntl, 12);192192- memcpy(current->thread.fp, sc->sc_fpregs, 24);193193- return 0;194194- }195195-196196- if (CPU_IS_060 ? sc->sc_fpstate[2] : sc->sc_fpstate[0]) {197197- /* Verify the frame format. */198198- if (!CPU_IS_060 && (sc->sc_fpstate[0] != fpu_version))199199- goto out;200200- if (CPU_IS_020_OR_030) {201201- if (m68k_fputype & FPU_68881 &&202202- !(sc->sc_fpstate[1] == 0x18 || sc->sc_fpstate[1] == 0xb4))203203- goto out;204204- if (m68k_fputype & FPU_68882 &&205205- !(sc->sc_fpstate[1] == 0x38 || sc->sc_fpstate[1] == 0xd4))206206- goto out;207207- } else if (CPU_IS_040) {208208- if (!(sc->sc_fpstate[1] == 0x00 ||209209- sc->sc_fpstate[1] == 0x28 ||210210- sc->sc_fpstate[1] == 0x60))211211- goto out;212212- } else if (CPU_IS_060) {213213- if (!(sc->sc_fpstate[3] == 0x00 ||214214- sc->sc_fpstate[3] == 0x60 ||215215- sc->sc_fpstate[3] == 0xe0))216216- goto out;217217- } else218218- goto out;219219-220220- __asm__ volatile (".chip 68k/68881\n\t"221221- "fmovemx %0,%%fp0-%%fp1\n\t"222222- "fmoveml %1,%%fpcr/%%fpsr/%%fpiar\n\t"223223- ".chip 68k"224224- : /* no outputs */225225- : "m" (*sc->sc_fpregs), "m" (*sc->sc_fpcntl));226226- }227227- __asm__ volatile (".chip 68k/68881\n\t"228228- "frestore %0\n\t"229229- ".chip 68k" : : "m" (*sc->sc_fpstate));230230- err = 0;231231-232232-out:233233- return err;234234-}235235-236236-#define FPCONTEXT_SIZE 216237237-#define uc_fpstate uc_filler[0]238238-#define uc_formatvec uc_filler[FPCONTEXT_SIZE/4]239239-#define uc_extra uc_filler[FPCONTEXT_SIZE/4+1]240240-241241-static inline int rt_restore_fpu_state(struct ucontext __user *uc)242242-{243243- unsigned char fpstate[FPCONTEXT_SIZE];244244- int context_size = CPU_IS_060 ? 8 : 0;245245- fpregset_t fpregs;246246- int err = 1;247247-248248- if (FPU_IS_EMU) {249249- /* restore fpu control register */250250- if (__copy_from_user(current->thread.fpcntl,251251- uc->uc_mcontext.fpregs.f_fpcntl, 12))252252- goto out;253253- /* restore all other fpu register */254254- if (__copy_from_user(current->thread.fp,255255- uc->uc_mcontext.fpregs.f_fpregs, 96))256256- goto out;257257- return 0;258258- }259259-260260- if (__get_user(*(long *)fpstate, (long __user *)&uc->uc_fpstate))261261- goto out;262262- if (CPU_IS_060 ? fpstate[2] : fpstate[0]) {263263- if (!CPU_IS_060)264264- context_size = fpstate[1];265265- /* Verify the frame format. */266266- if (!CPU_IS_060 && (fpstate[0] != fpu_version))267267- goto out;268268- if (CPU_IS_020_OR_030) {269269- if (m68k_fputype & FPU_68881 &&270270- !(context_size == 0x18 || context_size == 0xb4))271271- goto out;272272- if (m68k_fputype & FPU_68882 &&273273- !(context_size == 0x38 || context_size == 0xd4))274274- goto out;275275- } else if (CPU_IS_040) {276276- if (!(context_size == 0x00 ||277277- context_size == 0x28 ||278278- context_size == 0x60))279279- goto out;280280- } else if (CPU_IS_060) {281281- if (!(fpstate[3] == 0x00 ||282282- fpstate[3] == 0x60 ||283283- fpstate[3] == 0xe0))284284- goto out;285285- } else286286- goto out;287287- if (__copy_from_user(&fpregs, &uc->uc_mcontext.fpregs,288288- sizeof(fpregs)))289289- goto out;290290- __asm__ volatile (".chip 68k/68881\n\t"291291- "fmovemx %0,%%fp0-%%fp7\n\t"292292- "fmoveml %1,%%fpcr/%%fpsr/%%fpiar\n\t"293293- ".chip 68k"294294- : /* no outputs */295295- : "m" (*fpregs.f_fpregs),296296- "m" (*fpregs.f_fpcntl));297297- }298298- if (context_size &&299299- __copy_from_user(fpstate + 4, (long __user *)&uc->uc_fpstate + 1,300300- context_size))301301- goto out;302302- __asm__ volatile (".chip 68k/68881\n\t"303303- "frestore %0\n\t"304304- ".chip 68k" : : "m" (*fpstate));305305- err = 0;306306-307307-out:308308- return err;309309-}310310-311311-static int mangle_kernel_stack(struct pt_regs *regs, int formatvec,312312- void __user *fp)313313-{314314- int fsize = frame_extra_sizes[formatvec >> 12];315315- if (fsize < 0) {316316- /*317317- * user process trying to return with weird frame format318318- */319319-#ifdef DEBUG320320- printk("user process returning with weird frame format\n");321321-#endif322322- return 1;323323- }324324- if (!fsize) {325325- regs->format = formatvec >> 12;326326- regs->vector = formatvec & 0xfff;327327- } else {328328- struct switch_stack *sw = (struct switch_stack *)regs - 1;329329- unsigned long buf[fsize / 2]; /* yes, twice as much */330330-331331- /* that'll make sure that expansion won't crap over data */332332- if (copy_from_user(buf + fsize / 4, fp, fsize))333333- return 1;334334-335335- /* point of no return */336336- regs->format = formatvec >> 12;337337- regs->vector = formatvec & 0xfff;338338-#define frame_offset (sizeof(struct pt_regs)+sizeof(struct switch_stack))339339- __asm__ __volatile__340340- (" movel %0,%/a0\n\t"341341- " subl %1,%/a0\n\t" /* make room on stack */342342- " movel %/a0,%/sp\n\t" /* set stack pointer */343343- /* move switch_stack and pt_regs */344344- "1: movel %0@+,%/a0@+\n\t"345345- " dbra %2,1b\n\t"346346- " lea %/sp@(%c3),%/a0\n\t" /* add offset of fmt */347347- " lsrl #2,%1\n\t"348348- " subql #1,%1\n\t"349349- /* copy to the gap we'd made */350350- "2: movel %4@+,%/a0@+\n\t"351351- " dbra %1,2b\n\t"352352- " bral ret_from_signal\n"353353- : /* no outputs, it doesn't ever return */354354- : "a" (sw), "d" (fsize), "d" (frame_offset/4-1),355355- "n" (frame_offset), "a" (buf + fsize/4)356356- : "a0");357357-#undef frame_offset358358- }359359- return 0;360360-}361361-362362-static inline int363363-restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *usc, void __user *fp)364364-{365365- int formatvec;366366- struct sigcontext context;367367- int err;368368-369369- /* Always make any pending restarted system calls return -EINTR */370370- current_thread_info()->restart_block.fn = do_no_restart_syscall;371371-372372- /* get previous context */373373- if (copy_from_user(&context, usc, sizeof(context)))374374- goto badframe;375375-376376- /* restore passed registers */377377- regs->d0 = context.sc_d0;378378- regs->d1 = context.sc_d1;379379- regs->a0 = context.sc_a0;380380- regs->a1 = context.sc_a1;381381- regs->sr = (regs->sr & 0xff00) | (context.sc_sr & 0xff);382382- regs->pc = context.sc_pc;383383- regs->orig_d0 = -1; /* disable syscall checks */384384- wrusp(context.sc_usp);385385- formatvec = context.sc_formatvec;386386-387387- err = restore_fpu_state(&context);388388-389389- if (err || mangle_kernel_stack(regs, formatvec, fp))390390- goto badframe;391391-392392- return 0;393393-394394-badframe:395395- return 1;396396-}397397-398398-static inline int399399-rt_restore_ucontext(struct pt_regs *regs, struct switch_stack *sw,400400- struct ucontext __user *uc)401401-{402402- int temp;403403- greg_t __user *gregs = uc->uc_mcontext.gregs;404404- unsigned long usp;405405- int err;406406-407407- /* Always make any pending restarted system calls return -EINTR */408408- current_thread_info()->restart_block.fn = do_no_restart_syscall;409409-410410- err = __get_user(temp, &uc->uc_mcontext.version);411411- if (temp != MCONTEXT_VERSION)412412- goto badframe;413413- /* restore passed registers */414414- err |= __get_user(regs->d0, &gregs[0]);415415- err |= __get_user(regs->d1, &gregs[1]);416416- err |= __get_user(regs->d2, &gregs[2]);417417- err |= __get_user(regs->d3, &gregs[3]);418418- err |= __get_user(regs->d4, &gregs[4]);419419- err |= __get_user(regs->d5, &gregs[5]);420420- err |= __get_user(sw->d6, &gregs[6]);421421- err |= __get_user(sw->d7, &gregs[7]);422422- err |= __get_user(regs->a0, &gregs[8]);423423- err |= __get_user(regs->a1, &gregs[9]);424424- err |= __get_user(regs->a2, &gregs[10]);425425- err |= __get_user(sw->a3, &gregs[11]);426426- err |= __get_user(sw->a4, &gregs[12]);427427- err |= __get_user(sw->a5, &gregs[13]);428428- err |= __get_user(sw->a6, &gregs[14]);429429- err |= __get_user(usp, &gregs[15]);430430- wrusp(usp);431431- err |= __get_user(regs->pc, &gregs[16]);432432- err |= __get_user(temp, &gregs[17]);433433- regs->sr = (regs->sr & 0xff00) | (temp & 0xff);434434- regs->orig_d0 = -1; /* disable syscall checks */435435- err |= __get_user(temp, &uc->uc_formatvec);436436-437437- err |= rt_restore_fpu_state(uc);438438-439439- if (err || do_sigaltstack(&uc->uc_stack, NULL, usp) == -EFAULT)440440- goto badframe;441441-442442- if (mangle_kernel_stack(regs, temp, &uc->uc_extra))443443- goto badframe;444444-445445- return 0;446446-447447-badframe:448448- return 1;449449-}450450-451451-asmlinkage int do_sigreturn(unsigned long __unused)452452-{453453- struct switch_stack *sw = (struct switch_stack *) &__unused;454454- struct pt_regs *regs = (struct pt_regs *) (sw + 1);455455- unsigned long usp = rdusp();456456- struct sigframe __user *frame = (struct sigframe __user *)(usp - 4);457457- sigset_t set;458458-459459- if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))460460- goto badframe;461461- if (__get_user(set.sig[0], &frame->sc.sc_mask) ||462462- (_NSIG_WORDS > 1 &&463463- __copy_from_user(&set.sig[1], &frame->extramask,464464- sizeof(frame->extramask))))465465- goto badframe;466466-467467- sigdelsetmask(&set, ~_BLOCKABLE);468468- current->blocked = set;469469- recalc_sigpending();470470-471471- if (restore_sigcontext(regs, &frame->sc, frame + 1))472472- goto badframe;473473- return regs->d0;474474-475475-badframe:476476- force_sig(SIGSEGV, current);477477- return 0;478478-}479479-480480-asmlinkage int do_rt_sigreturn(unsigned long __unused)481481-{482482- struct switch_stack *sw = (struct switch_stack *) &__unused;483483- struct pt_regs *regs = (struct pt_regs *) (sw + 1);484484- unsigned long usp = rdusp();485485- struct rt_sigframe __user *frame = (struct rt_sigframe __user *)(usp - 4);486486- sigset_t set;487487-488488- if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))489489- goto badframe;490490- if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set)))491491- goto badframe;492492-493493- sigdelsetmask(&set, ~_BLOCKABLE);494494- current->blocked = set;495495- recalc_sigpending();496496-497497- if (rt_restore_ucontext(regs, sw, &frame->uc))498498- goto badframe;499499- return regs->d0;500500-501501-badframe:502502- force_sig(SIGSEGV, current);503503- return 0;504504-}505505-506506-/*507507- * Set up a signal frame.508508- */509509-510510-static inline void save_fpu_state(struct sigcontext *sc, struct pt_regs *regs)511511-{512512- if (FPU_IS_EMU) {513513- /* save registers */514514- memcpy(sc->sc_fpcntl, current->thread.fpcntl, 12);515515- memcpy(sc->sc_fpregs, current->thread.fp, 24);516516- return;517517- }518518-519519- __asm__ volatile (".chip 68k/68881\n\t"520520- "fsave %0\n\t"521521- ".chip 68k"522522- : : "m" (*sc->sc_fpstate) : "memory");523523-524524- if (CPU_IS_060 ? sc->sc_fpstate[2] : sc->sc_fpstate[0]) {525525- fpu_version = sc->sc_fpstate[0];526526- if (CPU_IS_020_OR_030 &&527527- regs->vector >= (VEC_FPBRUC * 4) &&528528- regs->vector <= (VEC_FPNAN * 4)) {529529- /* Clear pending exception in 68882 idle frame */530530- if (*(unsigned short *) sc->sc_fpstate == 0x1f38)531531- sc->sc_fpstate[0x38] |= 1 << 3;532532- }533533- __asm__ volatile (".chip 68k/68881\n\t"534534- "fmovemx %%fp0-%%fp1,%0\n\t"535535- "fmoveml %%fpcr/%%fpsr/%%fpiar,%1\n\t"536536- ".chip 68k"537537- : "=m" (*sc->sc_fpregs),538538- "=m" (*sc->sc_fpcntl)539539- : /* no inputs */540540- : "memory");541541- }542542-}543543-544544-static inline int rt_save_fpu_state(struct ucontext __user *uc, struct pt_regs *regs)545545-{546546- unsigned char fpstate[FPCONTEXT_SIZE];547547- int context_size = CPU_IS_060 ? 8 : 0;548548- int err = 0;549549-550550- if (FPU_IS_EMU) {551551- /* save fpu control register */552552- err |= copy_to_user(uc->uc_mcontext.fpregs.f_fpcntl,553553- current->thread.fpcntl, 12);554554- /* save all other fpu register */555555- err |= copy_to_user(uc->uc_mcontext.fpregs.f_fpregs,556556- current->thread.fp, 96);557557- return err;558558- }559559-560560- __asm__ volatile (".chip 68k/68881\n\t"561561- "fsave %0\n\t"562562- ".chip 68k"563563- : : "m" (*fpstate) : "memory");564564-565565- err |= __put_user(*(long *)fpstate, (long __user *)&uc->uc_fpstate);566566- if (CPU_IS_060 ? fpstate[2] : fpstate[0]) {567567- fpregset_t fpregs;568568- if (!CPU_IS_060)569569- context_size = fpstate[1];570570- fpu_version = fpstate[0];571571- if (CPU_IS_020_OR_030 &&572572- regs->vector >= (VEC_FPBRUC * 4) &&573573- regs->vector <= (VEC_FPNAN * 4)) {574574- /* Clear pending exception in 68882 idle frame */575575- if (*(unsigned short *) fpstate == 0x1f38)576576- fpstate[0x38] |= 1 << 3;577577- }578578- __asm__ volatile (".chip 68k/68881\n\t"579579- "fmovemx %%fp0-%%fp7,%0\n\t"580580- "fmoveml %%fpcr/%%fpsr/%%fpiar,%1\n\t"581581- ".chip 68k"582582- : "=m" (*fpregs.f_fpregs),583583- "=m" (*fpregs.f_fpcntl)584584- : /* no inputs */585585- : "memory");586586- err |= copy_to_user(&uc->uc_mcontext.fpregs, &fpregs,587587- sizeof(fpregs));588588- }589589- if (context_size)590590- err |= copy_to_user((long __user *)&uc->uc_fpstate + 1, fpstate + 4,591591- context_size);592592- return err;593593-}594594-595595-static void setup_sigcontext(struct sigcontext *sc, struct pt_regs *regs,596596- unsigned long mask)597597-{598598- sc->sc_mask = mask;599599- sc->sc_usp = rdusp();600600- sc->sc_d0 = regs->d0;601601- sc->sc_d1 = regs->d1;602602- sc->sc_a0 = regs->a0;603603- sc->sc_a1 = regs->a1;604604- sc->sc_sr = regs->sr;605605- sc->sc_pc = regs->pc;606606- sc->sc_formatvec = regs->format << 12 | regs->vector;607607- save_fpu_state(sc, regs);608608-}609609-610610-static inline int rt_setup_ucontext(struct ucontext __user *uc, struct pt_regs *regs)611611-{612612- struct switch_stack *sw = (struct switch_stack *)regs - 1;613613- greg_t __user *gregs = uc->uc_mcontext.gregs;614614- int err = 0;615615-616616- err |= __put_user(MCONTEXT_VERSION, &uc->uc_mcontext.version);617617- err |= __put_user(regs->d0, &gregs[0]);618618- err |= __put_user(regs->d1, &gregs[1]);619619- err |= __put_user(regs->d2, &gregs[2]);620620- err |= __put_user(regs->d3, &gregs[3]);621621- err |= __put_user(regs->d4, &gregs[4]);622622- err |= __put_user(regs->d5, &gregs[5]);623623- err |= __put_user(sw->d6, &gregs[6]);624624- err |= __put_user(sw->d7, &gregs[7]);625625- err |= __put_user(regs->a0, &gregs[8]);626626- err |= __put_user(regs->a1, &gregs[9]);627627- err |= __put_user(regs->a2, &gregs[10]);628628- err |= __put_user(sw->a3, &gregs[11]);629629- err |= __put_user(sw->a4, &gregs[12]);630630- err |= __put_user(sw->a5, &gregs[13]);631631- err |= __put_user(sw->a6, &gregs[14]);632632- err |= __put_user(rdusp(), &gregs[15]);633633- err |= __put_user(regs->pc, &gregs[16]);634634- err |= __put_user(regs->sr, &gregs[17]);635635- err |= __put_user((regs->format << 12) | regs->vector, &uc->uc_formatvec);636636- err |= rt_save_fpu_state(uc, regs);637637- return err;638638-}639639-640640-static inline void push_cache (unsigned long vaddr)641641-{642642- /*643643- * Using the old cache_push_v() was really a big waste.644644- *645645- * What we are trying to do is to flush 8 bytes to ram.646646- * Flushing 2 cache lines of 16 bytes is much cheaper than647647- * flushing 1 or 2 pages, as previously done in648648- * cache_push_v().649649- * Jes650650- */651651- if (CPU_IS_040) {652652- unsigned long temp;653653-654654- __asm__ __volatile__ (".chip 68040\n\t"655655- "nop\n\t"656656- "ptestr (%1)\n\t"657657- "movec %%mmusr,%0\n\t"658658- ".chip 68k"659659- : "=r" (temp)660660- : "a" (vaddr));661661-662662- temp &= PAGE_MASK;663663- temp |= vaddr & ~PAGE_MASK;664664-665665- __asm__ __volatile__ (".chip 68040\n\t"666666- "nop\n\t"667667- "cpushl %%bc,(%0)\n\t"668668- ".chip 68k"669669- : : "a" (temp));670670- }671671- else if (CPU_IS_060) {672672- unsigned long temp;673673- __asm__ __volatile__ (".chip 68060\n\t"674674- "plpar (%0)\n\t"675675- ".chip 68k"676676- : "=a" (temp)677677- : "0" (vaddr));678678- __asm__ __volatile__ (".chip 68060\n\t"679679- "cpushl %%bc,(%0)\n\t"680680- ".chip 68k"681681- : : "a" (temp));682682- }683683- else {684684- /*685685- * 68030/68020 have no writeback cache;686686- * still need to clear icache.687687- * Note that vaddr is guaranteed to be long word aligned.688688- */689689- unsigned long temp;690690- asm volatile ("movec %%cacr,%0" : "=r" (temp));691691- temp += 4;692692- asm volatile ("movec %0,%%caar\n\t"693693- "movec %1,%%cacr"694694- : : "r" (vaddr), "r" (temp));695695- asm volatile ("movec %0,%%caar\n\t"696696- "movec %1,%%cacr"697697- : : "r" (vaddr + 4), "r" (temp));698698- }699699-}700700-701701-static inline void __user *702702-get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size)703703-{704704- unsigned long usp;705705-706706- /* Default to using normal stack. */707707- usp = rdusp();708708-709709- /* This is the X/Open sanctioned signal stack switching. */710710- if (ka->sa.sa_flags & SA_ONSTACK) {711711- if (!sas_ss_flags(usp))712712- usp = current->sas_ss_sp + current->sas_ss_size;713713- }714714- return (void __user *)((usp - frame_size) & -8UL);715715-}716716-717717-static int setup_frame (int sig, struct k_sigaction *ka,718718- sigset_t *set, struct pt_regs *regs)719719-{720720- struct sigframe __user *frame;721721- int fsize = frame_extra_sizes[regs->format];722722- struct sigcontext context;723723- int err = 0;724724-725725- if (fsize < 0) {726726-#ifdef DEBUG727727- printk ("setup_frame: Unknown frame format %#x\n",728728- regs->format);729729-#endif730730- goto give_sigsegv;731731- }732732-733733- frame = get_sigframe(ka, regs, sizeof(*frame) + fsize);734734-735735- if (fsize)736736- err |= copy_to_user (frame + 1, regs + 1, fsize);737737-738738- err |= __put_user((current_thread_info()->exec_domain739739- && current_thread_info()->exec_domain->signal_invmap740740- && sig < 32741741- ? current_thread_info()->exec_domain->signal_invmap[sig]742742- : sig),743743- &frame->sig);744744-745745- err |= __put_user(regs->vector, &frame->code);746746- err |= __put_user(&frame->sc, &frame->psc);747747-748748- if (_NSIG_WORDS > 1)749749- err |= copy_to_user(frame->extramask, &set->sig[1],750750- sizeof(frame->extramask));751751-752752- setup_sigcontext(&context, regs, set->sig[0]);753753- err |= copy_to_user (&frame->sc, &context, sizeof(context));754754-755755- /* Set up to return from userspace. */756756- err |= __put_user(frame->retcode, &frame->pretcode);757757- /* moveq #,d0; trap #0 */758758- err |= __put_user(0x70004e40 + (__NR_sigreturn << 16),759759- (long __user *)(frame->retcode));760760-761761- if (err)762762- goto give_sigsegv;763763-764764- push_cache ((unsigned long) &frame->retcode);765765-766766- /*767767- * Set up registers for signal handler. All the state we are about768768- * to destroy is successfully copied to sigframe.769769- */770770- wrusp ((unsigned long) frame);771771- regs->pc = (unsigned long) ka->sa.sa_handler;772772-773773- /*774774- * This is subtle; if we build more than one sigframe, all but the775775- * first one will see frame format 0 and have fsize == 0, so we won't776776- * screw stkadj.777777- */778778- if (fsize)779779- regs->stkadj = fsize;780780-781781- /* Prepare to skip over the extra stuff in the exception frame. */782782- if (regs->stkadj) {783783- struct pt_regs *tregs =784784- (struct pt_regs *)((ulong)regs + regs->stkadj);785785-#ifdef DEBUG786786- printk("Performing stackadjust=%04x\n", regs->stkadj);787787-#endif788788- /* This must be copied with decreasing addresses to789789- handle overlaps. */790790- tregs->vector = 0;791791- tregs->format = 0;792792- tregs->pc = regs->pc;793793- tregs->sr = regs->sr;794794- }795795- return 0;796796-797797-give_sigsegv:798798- force_sigsegv(sig, current);799799- return err;800800-}801801-802802-static int setup_rt_frame (int sig, struct k_sigaction *ka, siginfo_t *info,803803- sigset_t *set, struct pt_regs *regs)804804-{805805- struct rt_sigframe __user *frame;806806- int fsize = frame_extra_sizes[regs->format];807807- int err = 0;808808-809809- if (fsize < 0) {810810-#ifdef DEBUG811811- printk ("setup_frame: Unknown frame format %#x\n",812812- regs->format);813813-#endif814814- goto give_sigsegv;815815- }816816-817817- frame = get_sigframe(ka, regs, sizeof(*frame));818818-819819- if (fsize)820820- err |= copy_to_user (&frame->uc.uc_extra, regs + 1, fsize);821821-822822- err |= __put_user((current_thread_info()->exec_domain823823- && current_thread_info()->exec_domain->signal_invmap824824- && sig < 32825825- ? current_thread_info()->exec_domain->signal_invmap[sig]826826- : sig),827827- &frame->sig);828828- err |= __put_user(&frame->info, &frame->pinfo);829829- err |= __put_user(&frame->uc, &frame->puc);830830- err |= copy_siginfo_to_user(&frame->info, info);831831-832832- /* Create the ucontext. */833833- err |= __put_user(0, &frame->uc.uc_flags);834834- err |= __put_user(NULL, &frame->uc.uc_link);835835- err |= __put_user((void __user *)current->sas_ss_sp,836836- &frame->uc.uc_stack.ss_sp);837837- err |= __put_user(sas_ss_flags(rdusp()),838838- &frame->uc.uc_stack.ss_flags);839839- err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size);840840- err |= rt_setup_ucontext(&frame->uc, regs);841841- err |= copy_to_user (&frame->uc.uc_sigmask, set, sizeof(*set));842842-843843- /* Set up to return from userspace. */844844- err |= __put_user(frame->retcode, &frame->pretcode);845845-#ifdef __mcoldfire__846846- /* movel #__NR_rt_sigreturn,d0; trap #0 */847847- err |= __put_user(0x203c0000, (long __user *)(frame->retcode + 0));848848- err |= __put_user(0x00004e40 + (__NR_rt_sigreturn << 16),849849- (long __user *)(frame->retcode + 4));11+#ifdef CONFIG_MMU22+#include "signal_mm.c"8503#else851851- /* moveq #,d0; notb d0; trap #0 */852852- err |= __put_user(0x70004600 + ((__NR_rt_sigreturn ^ 0xff) << 16),853853- (long __user *)(frame->retcode + 0));854854- err |= __put_user(0x4e40, (short __user *)(frame->retcode + 4));44+#include "signal_no.c"8555#endif856856-857857- if (err)858858- goto give_sigsegv;859859-860860- push_cache ((unsigned long) &frame->retcode);861861-862862- /*863863- * Set up registers for signal handler. All the state we are about864864- * to destroy is successfully copied to sigframe.865865- */866866- wrusp ((unsigned long) frame);867867- regs->pc = (unsigned long) ka->sa.sa_handler;868868-869869- /*870870- * This is subtle; if we build more than one sigframe, all but the871871- * first one will see frame format 0 and have fsize == 0, so we won't872872- * screw stkadj.873873- */874874- if (fsize)875875- regs->stkadj = fsize;876876-877877- /* Prepare to skip over the extra stuff in the exception frame. */878878- if (regs->stkadj) {879879- struct pt_regs *tregs =880880- (struct pt_regs *)((ulong)regs + regs->stkadj);881881-#ifdef DEBUG882882- printk("Performing stackadjust=%04x\n", regs->stkadj);883883-#endif884884- /* This must be copied with decreasing addresses to885885- handle overlaps. */886886- tregs->vector = 0;887887- tregs->format = 0;888888- tregs->pc = regs->pc;889889- tregs->sr = regs->sr;890890- }891891- return 0;892892-893893-give_sigsegv:894894- force_sigsegv(sig, current);895895- return err;896896-}897897-898898-static inline void899899-handle_restart(struct pt_regs *regs, struct k_sigaction *ka, int has_handler)900900-{901901- switch (regs->d0) {902902- case -ERESTARTNOHAND:903903- if (!has_handler)904904- goto do_restart;905905- regs->d0 = -EINTR;906906- break;907907-908908- case -ERESTART_RESTARTBLOCK:909909- if (!has_handler) {910910- regs->d0 = __NR_restart_syscall;911911- regs->pc -= 2;912912- break;913913- }914914- regs->d0 = -EINTR;915915- break;916916-917917- case -ERESTARTSYS:918918- if (has_handler && !(ka->sa.sa_flags & SA_RESTART)) {919919- regs->d0 = -EINTR;920920- break;921921- }922922- /* fallthrough */923923- case -ERESTARTNOINTR:924924- do_restart:925925- regs->d0 = regs->orig_d0;926926- regs->pc -= 2;927927- break;928928- }929929-}930930-931931-void ptrace_signal_deliver(struct pt_regs *regs, void *cookie)932932-{933933- if (regs->orig_d0 < 0)934934- return;935935- switch (regs->d0) {936936- case -ERESTARTNOHAND:937937- case -ERESTARTSYS:938938- case -ERESTARTNOINTR:939939- regs->d0 = regs->orig_d0;940940- regs->orig_d0 = -1;941941- regs->pc -= 2;942942- break;943943- }944944-}945945-946946-/*947947- * OK, we're invoking a handler948948- */949949-static void950950-handle_signal(int sig, struct k_sigaction *ka, siginfo_t *info,951951- sigset_t *oldset, struct pt_regs *regs)952952-{953953- int err;954954- /* are we from a system call? */955955- if (regs->orig_d0 >= 0)956956- /* If so, check system call restarting.. */957957- handle_restart(regs, ka, 1);958958-959959- /* set up the stack frame */960960- if (ka->sa.sa_flags & SA_SIGINFO)961961- err = setup_rt_frame(sig, ka, info, oldset, regs);962962- else963963- err = setup_frame(sig, ka, oldset, regs);964964-965965- if (err)966966- return;967967-968968- sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask);969969- if (!(ka->sa.sa_flags & SA_NODEFER))970970- sigaddset(¤t->blocked,sig);971971- recalc_sigpending();972972-973973- if (test_thread_flag(TIF_DELAYED_TRACE)) {974974- regs->sr &= ~0x8000;975975- send_sig(SIGTRAP, current, 1);976976- }977977-978978- clear_thread_flag(TIF_RESTORE_SIGMASK);979979-}980980-981981-/*982982- * Note that 'init' is a special process: it doesn't get signals it doesn't983983- * want to handle. Thus you cannot kill init even with a SIGKILL even by984984- * mistake.985985- */986986-asmlinkage void do_signal(struct pt_regs *regs)987987-{988988- siginfo_t info;989989- struct k_sigaction ka;990990- int signr;991991- sigset_t *oldset;992992-993993- current->thread.esp0 = (unsigned long) regs;994994-995995- if (test_thread_flag(TIF_RESTORE_SIGMASK))996996- oldset = ¤t->saved_sigmask;997997- else998998- oldset = ¤t->blocked;999999-10001000- signr = get_signal_to_deliver(&info, &ka, regs, NULL);10011001- if (signr > 0) {10021002- /* Whee! Actually deliver the signal. */10031003- handle_signal(signr, &ka, &info, oldset, regs);10041004- return;10051005- }10061006-10071007- /* Did we come from a system call? */10081008- if (regs->orig_d0 >= 0)10091009- /* Restart the system call - no handlers present */10101010- handle_restart(regs, NULL, 0);10111011-10121012- /* If there's no signal to deliver, we just restore the saved mask. */10131013- if (test_thread_flag(TIF_RESTORE_SIGMASK)) {10141014- clear_thread_flag(TIF_RESTORE_SIGMASK);10151015- sigprocmask(SIG_SETMASK, ¤t->saved_sigmask, NULL);10161016- }10171017-}
+1017
arch/m68k/kernel/signal_mm.c
···11+/*22+ * linux/arch/m68k/kernel/signal.c33+ *44+ * Copyright (C) 1991, 1992 Linus Torvalds55+ *66+ * This file is subject to the terms and conditions of the GNU General Public77+ * License. See the file COPYING in the main directory of this archive88+ * for more details.99+ */1010+1111+/*1212+ * Linux/m68k support by Hamish Macdonald1313+ *1414+ * 68060 fixes by Jesper Skov1515+ *1616+ * 1997-12-01 Modified for POSIX.1b signals by Andreas Schwab1717+ *1818+ * mathemu support by Roman Zippel1919+ * (Note: fpstate in the signal context is completely ignored for the emulator2020+ * and the internal floating point format is put on stack)2121+ */2222+2323+/*2424+ * ++roman (07/09/96): implemented signal stacks (specially for tosemu on2525+ * Atari :-) Current limitation: Only one sigstack can be active at one time.2626+ * If a second signal with SA_ONSTACK set arrives while working on a sigstack,2727+ * SA_ONSTACK is ignored. This behaviour avoids lots of trouble with nested2828+ * signal handlers!2929+ */3030+3131+#include <linux/sched.h>3232+#include <linux/mm.h>3333+#include <linux/kernel.h>3434+#include <linux/signal.h>3535+#include <linux/syscalls.h>3636+#include <linux/errno.h>3737+#include <linux/wait.h>3838+#include <linux/ptrace.h>3939+#include <linux/unistd.h>4040+#include <linux/stddef.h>4141+#include <linux/highuid.h>4242+#include <linux/personality.h>4343+#include <linux/tty.h>4444+#include <linux/binfmts.h>4545+#include <linux/module.h>4646+4747+#include <asm/setup.h>4848+#include <asm/uaccess.h>4949+#include <asm/pgtable.h>5050+#include <asm/traps.h>5151+#include <asm/ucontext.h>5252+5353+#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))5454+5555+static const int frame_extra_sizes[16] = {5656+ [1] = -1, /* sizeof(((struct frame *)0)->un.fmt1), */5757+ [2] = sizeof(((struct frame *)0)->un.fmt2),5858+ [3] = sizeof(((struct frame *)0)->un.fmt3),5959+ [4] = sizeof(((struct frame *)0)->un.fmt4),6060+ [5] = -1, /* sizeof(((struct frame *)0)->un.fmt5), */6161+ [6] = -1, /* sizeof(((struct frame *)0)->un.fmt6), */6262+ [7] = sizeof(((struct frame *)0)->un.fmt7),6363+ [8] = -1, /* sizeof(((struct frame *)0)->un.fmt8), */6464+ [9] = sizeof(((struct frame *)0)->un.fmt9),6565+ [10] = sizeof(((struct frame *)0)->un.fmta),6666+ [11] = sizeof(((struct frame *)0)->un.fmtb),6767+ [12] = -1, /* sizeof(((struct frame *)0)->un.fmtc), */6868+ [13] = -1, /* sizeof(((struct frame *)0)->un.fmtd), */6969+ [14] = -1, /* sizeof(((struct frame *)0)->un.fmte), */7070+ [15] = -1, /* sizeof(((struct frame *)0)->un.fmtf), */7171+};7272+7373+int handle_kernel_fault(struct pt_regs *regs)7474+{7575+ const struct exception_table_entry *fixup;7676+ struct pt_regs *tregs;7777+7878+ /* Are we prepared to handle this kernel fault? */7979+ fixup = search_exception_tables(regs->pc);8080+ if (!fixup)8181+ return 0;8282+8383+ /* Create a new four word stack frame, discarding the old one. */8484+ regs->stkadj = frame_extra_sizes[regs->format];8585+ tregs = (struct pt_regs *)((long)regs + regs->stkadj);8686+ tregs->vector = regs->vector;8787+ tregs->format = 0;8888+ tregs->pc = fixup->fixup;8989+ tregs->sr = regs->sr;9090+9191+ return 1;9292+}9393+9494+/*9595+ * Atomically swap in the new signal mask, and wait for a signal.9696+ */9797+asmlinkage int9898+sys_sigsuspend(int unused0, int unused1, old_sigset_t mask)9999+{100100+ mask &= _BLOCKABLE;101101+ spin_lock_irq(¤t->sighand->siglock);102102+ current->saved_sigmask = current->blocked;103103+ siginitset(¤t->blocked, mask);104104+ recalc_sigpending();105105+ spin_unlock_irq(¤t->sighand->siglock);106106+107107+ current->state = TASK_INTERRUPTIBLE;108108+ schedule();109109+ set_restore_sigmask();110110+111111+ return -ERESTARTNOHAND;112112+}113113+114114+asmlinkage int115115+sys_sigaction(int sig, const struct old_sigaction __user *act,116116+ struct old_sigaction __user *oact)117117+{118118+ struct k_sigaction new_ka, old_ka;119119+ int ret;120120+121121+ if (act) {122122+ old_sigset_t mask;123123+ if (!access_ok(VERIFY_READ, act, sizeof(*act)) ||124124+ __get_user(new_ka.sa.sa_handler, &act->sa_handler) ||125125+ __get_user(new_ka.sa.sa_restorer, &act->sa_restorer) ||126126+ __get_user(new_ka.sa.sa_flags, &act->sa_flags) ||127127+ __get_user(mask, &act->sa_mask))128128+ return -EFAULT;129129+ siginitset(&new_ka.sa.sa_mask, mask);130130+ }131131+132132+ ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);133133+134134+ if (!ret && oact) {135135+ if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)) ||136136+ __put_user(old_ka.sa.sa_handler, &oact->sa_handler) ||137137+ __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer) ||138138+ __put_user(old_ka.sa.sa_flags, &oact->sa_flags) ||139139+ __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask))140140+ return -EFAULT;141141+ }142142+143143+ return ret;144144+}145145+146146+asmlinkage int147147+sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss)148148+{149149+ return do_sigaltstack(uss, uoss, rdusp());150150+}151151+152152+153153+/*154154+ * Do a signal return; undo the signal stack.155155+ *156156+ * Keep the return code on the stack quadword aligned!157157+ * That makes the cache flush below easier.158158+ */159159+160160+struct sigframe161161+{162162+ char __user *pretcode;163163+ int sig;164164+ int code;165165+ struct sigcontext __user *psc;166166+ char retcode[8];167167+ unsigned long extramask[_NSIG_WORDS-1];168168+ struct sigcontext sc;169169+};170170+171171+struct rt_sigframe172172+{173173+ char __user *pretcode;174174+ int sig;175175+ struct siginfo __user *pinfo;176176+ void __user *puc;177177+ char retcode[8];178178+ struct siginfo info;179179+ struct ucontext uc;180180+};181181+182182+183183+static unsigned char fpu_version; /* version number of fpu, set by setup_frame */184184+185185+static inline int restore_fpu_state(struct sigcontext *sc)186186+{187187+ int err = 1;188188+189189+ if (FPU_IS_EMU) {190190+ /* restore registers */191191+ memcpy(current->thread.fpcntl, sc->sc_fpcntl, 12);192192+ memcpy(current->thread.fp, sc->sc_fpregs, 24);193193+ return 0;194194+ }195195+196196+ if (CPU_IS_060 ? sc->sc_fpstate[2] : sc->sc_fpstate[0]) {197197+ /* Verify the frame format. */198198+ if (!CPU_IS_060 && (sc->sc_fpstate[0] != fpu_version))199199+ goto out;200200+ if (CPU_IS_020_OR_030) {201201+ if (m68k_fputype & FPU_68881 &&202202+ !(sc->sc_fpstate[1] == 0x18 || sc->sc_fpstate[1] == 0xb4))203203+ goto out;204204+ if (m68k_fputype & FPU_68882 &&205205+ !(sc->sc_fpstate[1] == 0x38 || sc->sc_fpstate[1] == 0xd4))206206+ goto out;207207+ } else if (CPU_IS_040) {208208+ if (!(sc->sc_fpstate[1] == 0x00 ||209209+ sc->sc_fpstate[1] == 0x28 ||210210+ sc->sc_fpstate[1] == 0x60))211211+ goto out;212212+ } else if (CPU_IS_060) {213213+ if (!(sc->sc_fpstate[3] == 0x00 ||214214+ sc->sc_fpstate[3] == 0x60 ||215215+ sc->sc_fpstate[3] == 0xe0))216216+ goto out;217217+ } else218218+ goto out;219219+220220+ __asm__ volatile (".chip 68k/68881\n\t"221221+ "fmovemx %0,%%fp0-%%fp1\n\t"222222+ "fmoveml %1,%%fpcr/%%fpsr/%%fpiar\n\t"223223+ ".chip 68k"224224+ : /* no outputs */225225+ : "m" (*sc->sc_fpregs), "m" (*sc->sc_fpcntl));226226+ }227227+ __asm__ volatile (".chip 68k/68881\n\t"228228+ "frestore %0\n\t"229229+ ".chip 68k" : : "m" (*sc->sc_fpstate));230230+ err = 0;231231+232232+out:233233+ return err;234234+}235235+236236+#define FPCONTEXT_SIZE 216237237+#define uc_fpstate uc_filler[0]238238+#define uc_formatvec uc_filler[FPCONTEXT_SIZE/4]239239+#define uc_extra uc_filler[FPCONTEXT_SIZE/4+1]240240+241241+static inline int rt_restore_fpu_state(struct ucontext __user *uc)242242+{243243+ unsigned char fpstate[FPCONTEXT_SIZE];244244+ int context_size = CPU_IS_060 ? 8 : 0;245245+ fpregset_t fpregs;246246+ int err = 1;247247+248248+ if (FPU_IS_EMU) {249249+ /* restore fpu control register */250250+ if (__copy_from_user(current->thread.fpcntl,251251+ uc->uc_mcontext.fpregs.f_fpcntl, 12))252252+ goto out;253253+ /* restore all other fpu register */254254+ if (__copy_from_user(current->thread.fp,255255+ uc->uc_mcontext.fpregs.f_fpregs, 96))256256+ goto out;257257+ return 0;258258+ }259259+260260+ if (__get_user(*(long *)fpstate, (long __user *)&uc->uc_fpstate))261261+ goto out;262262+ if (CPU_IS_060 ? fpstate[2] : fpstate[0]) {263263+ if (!CPU_IS_060)264264+ context_size = fpstate[1];265265+ /* Verify the frame format. */266266+ if (!CPU_IS_060 && (fpstate[0] != fpu_version))267267+ goto out;268268+ if (CPU_IS_020_OR_030) {269269+ if (m68k_fputype & FPU_68881 &&270270+ !(context_size == 0x18 || context_size == 0xb4))271271+ goto out;272272+ if (m68k_fputype & FPU_68882 &&273273+ !(context_size == 0x38 || context_size == 0xd4))274274+ goto out;275275+ } else if (CPU_IS_040) {276276+ if (!(context_size == 0x00 ||277277+ context_size == 0x28 ||278278+ context_size == 0x60))279279+ goto out;280280+ } else if (CPU_IS_060) {281281+ if (!(fpstate[3] == 0x00 ||282282+ fpstate[3] == 0x60 ||283283+ fpstate[3] == 0xe0))284284+ goto out;285285+ } else286286+ goto out;287287+ if (__copy_from_user(&fpregs, &uc->uc_mcontext.fpregs,288288+ sizeof(fpregs)))289289+ goto out;290290+ __asm__ volatile (".chip 68k/68881\n\t"291291+ "fmovemx %0,%%fp0-%%fp7\n\t"292292+ "fmoveml %1,%%fpcr/%%fpsr/%%fpiar\n\t"293293+ ".chip 68k"294294+ : /* no outputs */295295+ : "m" (*fpregs.f_fpregs),296296+ "m" (*fpregs.f_fpcntl));297297+ }298298+ if (context_size &&299299+ __copy_from_user(fpstate + 4, (long __user *)&uc->uc_fpstate + 1,300300+ context_size))301301+ goto out;302302+ __asm__ volatile (".chip 68k/68881\n\t"303303+ "frestore %0\n\t"304304+ ".chip 68k" : : "m" (*fpstate));305305+ err = 0;306306+307307+out:308308+ return err;309309+}310310+311311+static int mangle_kernel_stack(struct pt_regs *regs, int formatvec,312312+ void __user *fp)313313+{314314+ int fsize = frame_extra_sizes[formatvec >> 12];315315+ if (fsize < 0) {316316+ /*317317+ * user process trying to return with weird frame format318318+ */319319+#ifdef DEBUG320320+ printk("user process returning with weird frame format\n");321321+#endif322322+ return 1;323323+ }324324+ if (!fsize) {325325+ regs->format = formatvec >> 12;326326+ regs->vector = formatvec & 0xfff;327327+ } else {328328+ struct switch_stack *sw = (struct switch_stack *)regs - 1;329329+ unsigned long buf[fsize / 2]; /* yes, twice as much */330330+331331+ /* that'll make sure that expansion won't crap over data */332332+ if (copy_from_user(buf + fsize / 4, fp, fsize))333333+ return 1;334334+335335+ /* point of no return */336336+ regs->format = formatvec >> 12;337337+ regs->vector = formatvec & 0xfff;338338+#define frame_offset (sizeof(struct pt_regs)+sizeof(struct switch_stack))339339+ __asm__ __volatile__340340+ (" movel %0,%/a0\n\t"341341+ " subl %1,%/a0\n\t" /* make room on stack */342342+ " movel %/a0,%/sp\n\t" /* set stack pointer */343343+ /* move switch_stack and pt_regs */344344+ "1: movel %0@+,%/a0@+\n\t"345345+ " dbra %2,1b\n\t"346346+ " lea %/sp@(%c3),%/a0\n\t" /* add offset of fmt */347347+ " lsrl #2,%1\n\t"348348+ " subql #1,%1\n\t"349349+ /* copy to the gap we'd made */350350+ "2: movel %4@+,%/a0@+\n\t"351351+ " dbra %1,2b\n\t"352352+ " bral ret_from_signal\n"353353+ : /* no outputs, it doesn't ever return */354354+ : "a" (sw), "d" (fsize), "d" (frame_offset/4-1),355355+ "n" (frame_offset), "a" (buf + fsize/4)356356+ : "a0");357357+#undef frame_offset358358+ }359359+ return 0;360360+}361361+362362+static inline int363363+restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *usc, void __user *fp)364364+{365365+ int formatvec;366366+ struct sigcontext context;367367+ int err;368368+369369+ /* Always make any pending restarted system calls return -EINTR */370370+ current_thread_info()->restart_block.fn = do_no_restart_syscall;371371+372372+ /* get previous context */373373+ if (copy_from_user(&context, usc, sizeof(context)))374374+ goto badframe;375375+376376+ /* restore passed registers */377377+ regs->d0 = context.sc_d0;378378+ regs->d1 = context.sc_d1;379379+ regs->a0 = context.sc_a0;380380+ regs->a1 = context.sc_a1;381381+ regs->sr = (regs->sr & 0xff00) | (context.sc_sr & 0xff);382382+ regs->pc = context.sc_pc;383383+ regs->orig_d0 = -1; /* disable syscall checks */384384+ wrusp(context.sc_usp);385385+ formatvec = context.sc_formatvec;386386+387387+ err = restore_fpu_state(&context);388388+389389+ if (err || mangle_kernel_stack(regs, formatvec, fp))390390+ goto badframe;391391+392392+ return 0;393393+394394+badframe:395395+ return 1;396396+}397397+398398+static inline int399399+rt_restore_ucontext(struct pt_regs *regs, struct switch_stack *sw,400400+ struct ucontext __user *uc)401401+{402402+ int temp;403403+ greg_t __user *gregs = uc->uc_mcontext.gregs;404404+ unsigned long usp;405405+ int err;406406+407407+ /* Always make any pending restarted system calls return -EINTR */408408+ current_thread_info()->restart_block.fn = do_no_restart_syscall;409409+410410+ err = __get_user(temp, &uc->uc_mcontext.version);411411+ if (temp != MCONTEXT_VERSION)412412+ goto badframe;413413+ /* restore passed registers */414414+ err |= __get_user(regs->d0, &gregs[0]);415415+ err |= __get_user(regs->d1, &gregs[1]);416416+ err |= __get_user(regs->d2, &gregs[2]);417417+ err |= __get_user(regs->d3, &gregs[3]);418418+ err |= __get_user(regs->d4, &gregs[4]);419419+ err |= __get_user(regs->d5, &gregs[5]);420420+ err |= __get_user(sw->d6, &gregs[6]);421421+ err |= __get_user(sw->d7, &gregs[7]);422422+ err |= __get_user(regs->a0, &gregs[8]);423423+ err |= __get_user(regs->a1, &gregs[9]);424424+ err |= __get_user(regs->a2, &gregs[10]);425425+ err |= __get_user(sw->a3, &gregs[11]);426426+ err |= __get_user(sw->a4, &gregs[12]);427427+ err |= __get_user(sw->a5, &gregs[13]);428428+ err |= __get_user(sw->a6, &gregs[14]);429429+ err |= __get_user(usp, &gregs[15]);430430+ wrusp(usp);431431+ err |= __get_user(regs->pc, &gregs[16]);432432+ err |= __get_user(temp, &gregs[17]);433433+ regs->sr = (regs->sr & 0xff00) | (temp & 0xff);434434+ regs->orig_d0 = -1; /* disable syscall checks */435435+ err |= __get_user(temp, &uc->uc_formatvec);436436+437437+ err |= rt_restore_fpu_state(uc);438438+439439+ if (err || do_sigaltstack(&uc->uc_stack, NULL, usp) == -EFAULT)440440+ goto badframe;441441+442442+ if (mangle_kernel_stack(regs, temp, &uc->uc_extra))443443+ goto badframe;444444+445445+ return 0;446446+447447+badframe:448448+ return 1;449449+}450450+451451+asmlinkage int do_sigreturn(unsigned long __unused)452452+{453453+ struct switch_stack *sw = (struct switch_stack *) &__unused;454454+ struct pt_regs *regs = (struct pt_regs *) (sw + 1);455455+ unsigned long usp = rdusp();456456+ struct sigframe __user *frame = (struct sigframe __user *)(usp - 4);457457+ sigset_t set;458458+459459+ if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))460460+ goto badframe;461461+ if (__get_user(set.sig[0], &frame->sc.sc_mask) ||462462+ (_NSIG_WORDS > 1 &&463463+ __copy_from_user(&set.sig[1], &frame->extramask,464464+ sizeof(frame->extramask))))465465+ goto badframe;466466+467467+ sigdelsetmask(&set, ~_BLOCKABLE);468468+ current->blocked = set;469469+ recalc_sigpending();470470+471471+ if (restore_sigcontext(regs, &frame->sc, frame + 1))472472+ goto badframe;473473+ return regs->d0;474474+475475+badframe:476476+ force_sig(SIGSEGV, current);477477+ return 0;478478+}479479+480480+asmlinkage int do_rt_sigreturn(unsigned long __unused)481481+{482482+ struct switch_stack *sw = (struct switch_stack *) &__unused;483483+ struct pt_regs *regs = (struct pt_regs *) (sw + 1);484484+ unsigned long usp = rdusp();485485+ struct rt_sigframe __user *frame = (struct rt_sigframe __user *)(usp - 4);486486+ sigset_t set;487487+488488+ if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))489489+ goto badframe;490490+ if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set)))491491+ goto badframe;492492+493493+ sigdelsetmask(&set, ~_BLOCKABLE);494494+ current->blocked = set;495495+ recalc_sigpending();496496+497497+ if (rt_restore_ucontext(regs, sw, &frame->uc))498498+ goto badframe;499499+ return regs->d0;500500+501501+badframe:502502+ force_sig(SIGSEGV, current);503503+ return 0;504504+}505505+506506+/*507507+ * Set up a signal frame.508508+ */509509+510510+static inline void save_fpu_state(struct sigcontext *sc, struct pt_regs *regs)511511+{512512+ if (FPU_IS_EMU) {513513+ /* save registers */514514+ memcpy(sc->sc_fpcntl, current->thread.fpcntl, 12);515515+ memcpy(sc->sc_fpregs, current->thread.fp, 24);516516+ return;517517+ }518518+519519+ __asm__ volatile (".chip 68k/68881\n\t"520520+ "fsave %0\n\t"521521+ ".chip 68k"522522+ : : "m" (*sc->sc_fpstate) : "memory");523523+524524+ if (CPU_IS_060 ? sc->sc_fpstate[2] : sc->sc_fpstate[0]) {525525+ fpu_version = sc->sc_fpstate[0];526526+ if (CPU_IS_020_OR_030 &&527527+ regs->vector >= (VEC_FPBRUC * 4) &&528528+ regs->vector <= (VEC_FPNAN * 4)) {529529+ /* Clear pending exception in 68882 idle frame */530530+ if (*(unsigned short *) sc->sc_fpstate == 0x1f38)531531+ sc->sc_fpstate[0x38] |= 1 << 3;532532+ }533533+ __asm__ volatile (".chip 68k/68881\n\t"534534+ "fmovemx %%fp0-%%fp1,%0\n\t"535535+ "fmoveml %%fpcr/%%fpsr/%%fpiar,%1\n\t"536536+ ".chip 68k"537537+ : "=m" (*sc->sc_fpregs),538538+ "=m" (*sc->sc_fpcntl)539539+ : /* no inputs */540540+ : "memory");541541+ }542542+}543543+544544+static inline int rt_save_fpu_state(struct ucontext __user *uc, struct pt_regs *regs)545545+{546546+ unsigned char fpstate[FPCONTEXT_SIZE];547547+ int context_size = CPU_IS_060 ? 8 : 0;548548+ int err = 0;549549+550550+ if (FPU_IS_EMU) {551551+ /* save fpu control register */552552+ err |= copy_to_user(uc->uc_mcontext.fpregs.f_fpcntl,553553+ current->thread.fpcntl, 12);554554+ /* save all other fpu register */555555+ err |= copy_to_user(uc->uc_mcontext.fpregs.f_fpregs,556556+ current->thread.fp, 96);557557+ return err;558558+ }559559+560560+ __asm__ volatile (".chip 68k/68881\n\t"561561+ "fsave %0\n\t"562562+ ".chip 68k"563563+ : : "m" (*fpstate) : "memory");564564+565565+ err |= __put_user(*(long *)fpstate, (long __user *)&uc->uc_fpstate);566566+ if (CPU_IS_060 ? fpstate[2] : fpstate[0]) {567567+ fpregset_t fpregs;568568+ if (!CPU_IS_060)569569+ context_size = fpstate[1];570570+ fpu_version = fpstate[0];571571+ if (CPU_IS_020_OR_030 &&572572+ regs->vector >= (VEC_FPBRUC * 4) &&573573+ regs->vector <= (VEC_FPNAN * 4)) {574574+ /* Clear pending exception in 68882 idle frame */575575+ if (*(unsigned short *) fpstate == 0x1f38)576576+ fpstate[0x38] |= 1 << 3;577577+ }578578+ __asm__ volatile (".chip 68k/68881\n\t"579579+ "fmovemx %%fp0-%%fp7,%0\n\t"580580+ "fmoveml %%fpcr/%%fpsr/%%fpiar,%1\n\t"581581+ ".chip 68k"582582+ : "=m" (*fpregs.f_fpregs),583583+ "=m" (*fpregs.f_fpcntl)584584+ : /* no inputs */585585+ : "memory");586586+ err |= copy_to_user(&uc->uc_mcontext.fpregs, &fpregs,587587+ sizeof(fpregs));588588+ }589589+ if (context_size)590590+ err |= copy_to_user((long __user *)&uc->uc_fpstate + 1, fpstate + 4,591591+ context_size);592592+ return err;593593+}594594+595595+static void setup_sigcontext(struct sigcontext *sc, struct pt_regs *regs,596596+ unsigned long mask)597597+{598598+ sc->sc_mask = mask;599599+ sc->sc_usp = rdusp();600600+ sc->sc_d0 = regs->d0;601601+ sc->sc_d1 = regs->d1;602602+ sc->sc_a0 = regs->a0;603603+ sc->sc_a1 = regs->a1;604604+ sc->sc_sr = regs->sr;605605+ sc->sc_pc = regs->pc;606606+ sc->sc_formatvec = regs->format << 12 | regs->vector;607607+ save_fpu_state(sc, regs);608608+}609609+610610+static inline int rt_setup_ucontext(struct ucontext __user *uc, struct pt_regs *regs)611611+{612612+ struct switch_stack *sw = (struct switch_stack *)regs - 1;613613+ greg_t __user *gregs = uc->uc_mcontext.gregs;614614+ int err = 0;615615+616616+ err |= __put_user(MCONTEXT_VERSION, &uc->uc_mcontext.version);617617+ err |= __put_user(regs->d0, &gregs[0]);618618+ err |= __put_user(regs->d1, &gregs[1]);619619+ err |= __put_user(regs->d2, &gregs[2]);620620+ err |= __put_user(regs->d3, &gregs[3]);621621+ err |= __put_user(regs->d4, &gregs[4]);622622+ err |= __put_user(regs->d5, &gregs[5]);623623+ err |= __put_user(sw->d6, &gregs[6]);624624+ err |= __put_user(sw->d7, &gregs[7]);625625+ err |= __put_user(regs->a0, &gregs[8]);626626+ err |= __put_user(regs->a1, &gregs[9]);627627+ err |= __put_user(regs->a2, &gregs[10]);628628+ err |= __put_user(sw->a3, &gregs[11]);629629+ err |= __put_user(sw->a4, &gregs[12]);630630+ err |= __put_user(sw->a5, &gregs[13]);631631+ err |= __put_user(sw->a6, &gregs[14]);632632+ err |= __put_user(rdusp(), &gregs[15]);633633+ err |= __put_user(regs->pc, &gregs[16]);634634+ err |= __put_user(regs->sr, &gregs[17]);635635+ err |= __put_user((regs->format << 12) | regs->vector, &uc->uc_formatvec);636636+ err |= rt_save_fpu_state(uc, regs);637637+ return err;638638+}639639+640640+static inline void push_cache (unsigned long vaddr)641641+{642642+ /*643643+ * Using the old cache_push_v() was really a big waste.644644+ *645645+ * What we are trying to do is to flush 8 bytes to ram.646646+ * Flushing 2 cache lines of 16 bytes is much cheaper than647647+ * flushing 1 or 2 pages, as previously done in648648+ * cache_push_v().649649+ * Jes650650+ */651651+ if (CPU_IS_040) {652652+ unsigned long temp;653653+654654+ __asm__ __volatile__ (".chip 68040\n\t"655655+ "nop\n\t"656656+ "ptestr (%1)\n\t"657657+ "movec %%mmusr,%0\n\t"658658+ ".chip 68k"659659+ : "=r" (temp)660660+ : "a" (vaddr));661661+662662+ temp &= PAGE_MASK;663663+ temp |= vaddr & ~PAGE_MASK;664664+665665+ __asm__ __volatile__ (".chip 68040\n\t"666666+ "nop\n\t"667667+ "cpushl %%bc,(%0)\n\t"668668+ ".chip 68k"669669+ : : "a" (temp));670670+ }671671+ else if (CPU_IS_060) {672672+ unsigned long temp;673673+ __asm__ __volatile__ (".chip 68060\n\t"674674+ "plpar (%0)\n\t"675675+ ".chip 68k"676676+ : "=a" (temp)677677+ : "0" (vaddr));678678+ __asm__ __volatile__ (".chip 68060\n\t"679679+ "cpushl %%bc,(%0)\n\t"680680+ ".chip 68k"681681+ : : "a" (temp));682682+ }683683+ else {684684+ /*685685+ * 68030/68020 have no writeback cache;686686+ * still need to clear icache.687687+ * Note that vaddr is guaranteed to be long word aligned.688688+ */689689+ unsigned long temp;690690+ asm volatile ("movec %%cacr,%0" : "=r" (temp));691691+ temp += 4;692692+ asm volatile ("movec %0,%%caar\n\t"693693+ "movec %1,%%cacr"694694+ : : "r" (vaddr), "r" (temp));695695+ asm volatile ("movec %0,%%caar\n\t"696696+ "movec %1,%%cacr"697697+ : : "r" (vaddr + 4), "r" (temp));698698+ }699699+}700700+701701+static inline void __user *702702+get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size)703703+{704704+ unsigned long usp;705705+706706+ /* Default to using normal stack. */707707+ usp = rdusp();708708+709709+ /* This is the X/Open sanctioned signal stack switching. */710710+ if (ka->sa.sa_flags & SA_ONSTACK) {711711+ if (!sas_ss_flags(usp))712712+ usp = current->sas_ss_sp + current->sas_ss_size;713713+ }714714+ return (void __user *)((usp - frame_size) & -8UL);715715+}716716+717717+static int setup_frame (int sig, struct k_sigaction *ka,718718+ sigset_t *set, struct pt_regs *regs)719719+{720720+ struct sigframe __user *frame;721721+ int fsize = frame_extra_sizes[regs->format];722722+ struct sigcontext context;723723+ int err = 0;724724+725725+ if (fsize < 0) {726726+#ifdef DEBUG727727+ printk ("setup_frame: Unknown frame format %#x\n",728728+ regs->format);729729+#endif730730+ goto give_sigsegv;731731+ }732732+733733+ frame = get_sigframe(ka, regs, sizeof(*frame) + fsize);734734+735735+ if (fsize)736736+ err |= copy_to_user (frame + 1, regs + 1, fsize);737737+738738+ err |= __put_user((current_thread_info()->exec_domain739739+ && current_thread_info()->exec_domain->signal_invmap740740+ && sig < 32741741+ ? current_thread_info()->exec_domain->signal_invmap[sig]742742+ : sig),743743+ &frame->sig);744744+745745+ err |= __put_user(regs->vector, &frame->code);746746+ err |= __put_user(&frame->sc, &frame->psc);747747+748748+ if (_NSIG_WORDS > 1)749749+ err |= copy_to_user(frame->extramask, &set->sig[1],750750+ sizeof(frame->extramask));751751+752752+ setup_sigcontext(&context, regs, set->sig[0]);753753+ err |= copy_to_user (&frame->sc, &context, sizeof(context));754754+755755+ /* Set up to return from userspace. */756756+ err |= __put_user(frame->retcode, &frame->pretcode);757757+ /* moveq #,d0; trap #0 */758758+ err |= __put_user(0x70004e40 + (__NR_sigreturn << 16),759759+ (long __user *)(frame->retcode));760760+761761+ if (err)762762+ goto give_sigsegv;763763+764764+ push_cache ((unsigned long) &frame->retcode);765765+766766+ /*767767+ * Set up registers for signal handler. All the state we are about768768+ * to destroy is successfully copied to sigframe.769769+ */770770+ wrusp ((unsigned long) frame);771771+ regs->pc = (unsigned long) ka->sa.sa_handler;772772+773773+ /*774774+ * This is subtle; if we build more than one sigframe, all but the775775+ * first one will see frame format 0 and have fsize == 0, so we won't776776+ * screw stkadj.777777+ */778778+ if (fsize)779779+ regs->stkadj = fsize;780780+781781+ /* Prepare to skip over the extra stuff in the exception frame. */782782+ if (regs->stkadj) {783783+ struct pt_regs *tregs =784784+ (struct pt_regs *)((ulong)regs + regs->stkadj);785785+#ifdef DEBUG786786+ printk("Performing stackadjust=%04x\n", regs->stkadj);787787+#endif788788+ /* This must be copied with decreasing addresses to789789+ handle overlaps. */790790+ tregs->vector = 0;791791+ tregs->format = 0;792792+ tregs->pc = regs->pc;793793+ tregs->sr = regs->sr;794794+ }795795+ return 0;796796+797797+give_sigsegv:798798+ force_sigsegv(sig, current);799799+ return err;800800+}801801+802802+static int setup_rt_frame (int sig, struct k_sigaction *ka, siginfo_t *info,803803+ sigset_t *set, struct pt_regs *regs)804804+{805805+ struct rt_sigframe __user *frame;806806+ int fsize = frame_extra_sizes[regs->format];807807+ int err = 0;808808+809809+ if (fsize < 0) {810810+#ifdef DEBUG811811+ printk ("setup_frame: Unknown frame format %#x\n",812812+ regs->format);813813+#endif814814+ goto give_sigsegv;815815+ }816816+817817+ frame = get_sigframe(ka, regs, sizeof(*frame));818818+819819+ if (fsize)820820+ err |= copy_to_user (&frame->uc.uc_extra, regs + 1, fsize);821821+822822+ err |= __put_user((current_thread_info()->exec_domain823823+ && current_thread_info()->exec_domain->signal_invmap824824+ && sig < 32825825+ ? current_thread_info()->exec_domain->signal_invmap[sig]826826+ : sig),827827+ &frame->sig);828828+ err |= __put_user(&frame->info, &frame->pinfo);829829+ err |= __put_user(&frame->uc, &frame->puc);830830+ err |= copy_siginfo_to_user(&frame->info, info);831831+832832+ /* Create the ucontext. */833833+ err |= __put_user(0, &frame->uc.uc_flags);834834+ err |= __put_user(NULL, &frame->uc.uc_link);835835+ err |= __put_user((void __user *)current->sas_ss_sp,836836+ &frame->uc.uc_stack.ss_sp);837837+ err |= __put_user(sas_ss_flags(rdusp()),838838+ &frame->uc.uc_stack.ss_flags);839839+ err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size);840840+ err |= rt_setup_ucontext(&frame->uc, regs);841841+ err |= copy_to_user (&frame->uc.uc_sigmask, set, sizeof(*set));842842+843843+ /* Set up to return from userspace. */844844+ err |= __put_user(frame->retcode, &frame->pretcode);845845+#ifdef __mcoldfire__846846+ /* movel #__NR_rt_sigreturn,d0; trap #0 */847847+ err |= __put_user(0x203c0000, (long __user *)(frame->retcode + 0));848848+ err |= __put_user(0x00004e40 + (__NR_rt_sigreturn << 16),849849+ (long __user *)(frame->retcode + 4));850850+#else851851+ /* moveq #,d0; notb d0; trap #0 */852852+ err |= __put_user(0x70004600 + ((__NR_rt_sigreturn ^ 0xff) << 16),853853+ (long __user *)(frame->retcode + 0));854854+ err |= __put_user(0x4e40, (short __user *)(frame->retcode + 4));855855+#endif856856+857857+ if (err)858858+ goto give_sigsegv;859859+860860+ push_cache ((unsigned long) &frame->retcode);861861+862862+ /*863863+ * Set up registers for signal handler. All the state we are about864864+ * to destroy is successfully copied to sigframe.865865+ */866866+ wrusp ((unsigned long) frame);867867+ regs->pc = (unsigned long) ka->sa.sa_handler;868868+869869+ /*870870+ * This is subtle; if we build more than one sigframe, all but the871871+ * first one will see frame format 0 and have fsize == 0, so we won't872872+ * screw stkadj.873873+ */874874+ if (fsize)875875+ regs->stkadj = fsize;876876+877877+ /* Prepare to skip over the extra stuff in the exception frame. */878878+ if (regs->stkadj) {879879+ struct pt_regs *tregs =880880+ (struct pt_regs *)((ulong)regs + regs->stkadj);881881+#ifdef DEBUG882882+ printk("Performing stackadjust=%04x\n", regs->stkadj);883883+#endif884884+ /* This must be copied with decreasing addresses to885885+ handle overlaps. */886886+ tregs->vector = 0;887887+ tregs->format = 0;888888+ tregs->pc = regs->pc;889889+ tregs->sr = regs->sr;890890+ }891891+ return 0;892892+893893+give_sigsegv:894894+ force_sigsegv(sig, current);895895+ return err;896896+}897897+898898+static inline void899899+handle_restart(struct pt_regs *regs, struct k_sigaction *ka, int has_handler)900900+{901901+ switch (regs->d0) {902902+ case -ERESTARTNOHAND:903903+ if (!has_handler)904904+ goto do_restart;905905+ regs->d0 = -EINTR;906906+ break;907907+908908+ case -ERESTART_RESTARTBLOCK:909909+ if (!has_handler) {910910+ regs->d0 = __NR_restart_syscall;911911+ regs->pc -= 2;912912+ break;913913+ }914914+ regs->d0 = -EINTR;915915+ break;916916+917917+ case -ERESTARTSYS:918918+ if (has_handler && !(ka->sa.sa_flags & SA_RESTART)) {919919+ regs->d0 = -EINTR;920920+ break;921921+ }922922+ /* fallthrough */923923+ case -ERESTARTNOINTR:924924+ do_restart:925925+ regs->d0 = regs->orig_d0;926926+ regs->pc -= 2;927927+ break;928928+ }929929+}930930+931931+void ptrace_signal_deliver(struct pt_regs *regs, void *cookie)932932+{933933+ if (regs->orig_d0 < 0)934934+ return;935935+ switch (regs->d0) {936936+ case -ERESTARTNOHAND:937937+ case -ERESTARTSYS:938938+ case -ERESTARTNOINTR:939939+ regs->d0 = regs->orig_d0;940940+ regs->orig_d0 = -1;941941+ regs->pc -= 2;942942+ break;943943+ }944944+}945945+946946+/*947947+ * OK, we're invoking a handler948948+ */949949+static void950950+handle_signal(int sig, struct k_sigaction *ka, siginfo_t *info,951951+ sigset_t *oldset, struct pt_regs *regs)952952+{953953+ int err;954954+ /* are we from a system call? */955955+ if (regs->orig_d0 >= 0)956956+ /* If so, check system call restarting.. */957957+ handle_restart(regs, ka, 1);958958+959959+ /* set up the stack frame */960960+ if (ka->sa.sa_flags & SA_SIGINFO)961961+ err = setup_rt_frame(sig, ka, info, oldset, regs);962962+ else963963+ err = setup_frame(sig, ka, oldset, regs);964964+965965+ if (err)966966+ return;967967+968968+ sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask);969969+ if (!(ka->sa.sa_flags & SA_NODEFER))970970+ sigaddset(¤t->blocked,sig);971971+ recalc_sigpending();972972+973973+ if (test_thread_flag(TIF_DELAYED_TRACE)) {974974+ regs->sr &= ~0x8000;975975+ send_sig(SIGTRAP, current, 1);976976+ }977977+978978+ clear_thread_flag(TIF_RESTORE_SIGMASK);979979+}980980+981981+/*982982+ * Note that 'init' is a special process: it doesn't get signals it doesn't983983+ * want to handle. Thus you cannot kill init even with a SIGKILL even by984984+ * mistake.985985+ */986986+asmlinkage void do_signal(struct pt_regs *regs)987987+{988988+ siginfo_t info;989989+ struct k_sigaction ka;990990+ int signr;991991+ sigset_t *oldset;992992+993993+ current->thread.esp0 = (unsigned long) regs;994994+995995+ if (test_thread_flag(TIF_RESTORE_SIGMASK))996996+ oldset = ¤t->saved_sigmask;997997+ else998998+ oldset = ¤t->blocked;999999+10001000+ signr = get_signal_to_deliver(&info, &ka, regs, NULL);10011001+ if (signr > 0) {10021002+ /* Whee! Actually deliver the signal. */10031003+ handle_signal(signr, &ka, &info, oldset, regs);10041004+ return;10051005+ }10061006+10071007+ /* Did we come from a system call? */10081008+ if (regs->orig_d0 >= 0)10091009+ /* Restart the system call - no handlers present */10101010+ handle_restart(regs, NULL, 0);10111011+10121012+ /* If there's no signal to deliver, we just restore the saved mask. */10131013+ if (test_thread_flag(TIF_RESTORE_SIGMASK)) {10141014+ clear_thread_flag(TIF_RESTORE_SIGMASK);10151015+ sigprocmask(SIG_SETMASK, ¤t->saved_sigmask, NULL);10161016+ }10171017+}
+5-546
arch/m68k/kernel/sys_m68k.c
···11-/*22- * linux/arch/m68k/kernel/sys_m68k.c33- *44- * This file contains various random system calls that55- * have a non-standard calling sequence on the Linux/m68k66- * platform.77- */88-99-#include <linux/capability.h>1010-#include <linux/errno.h>1111-#include <linux/sched.h>1212-#include <linux/mm.h>1313-#include <linux/fs.h>1414-#include <linux/smp.h>1515-#include <linux/sem.h>1616-#include <linux/msg.h>1717-#include <linux/shm.h>1818-#include <linux/stat.h>1919-#include <linux/syscalls.h>2020-#include <linux/mman.h>2121-#include <linux/file.h>2222-#include <linux/ipc.h>2323-2424-#include <asm/setup.h>2525-#include <asm/uaccess.h>2626-#include <asm/cachectl.h>2727-#include <asm/traps.h>2828-#include <asm/page.h>2929-#include <asm/unistd.h>3030-#include <linux/elf.h>3131-#include <asm/tlb.h>3232-3333-asmlinkage int do_page_fault(struct pt_regs *regs, unsigned long address,3434- unsigned long error_code);3535-3636-asmlinkage long sys_mmap2(unsigned long addr, unsigned long len,3737- unsigned long prot, unsigned long flags,3838- unsigned long fd, unsigned long pgoff)3939-{4040- /*4141- * This is wrong for sun3 - there PAGE_SIZE is 8Kb,4242- * so we need to shift the argument down by 1; m68k mmap64(3)4343- * (in libc) expects the last argument of mmap2 in 4Kb units.4444- */4545- return sys_mmap_pgoff(addr, len, prot, flags, fd, pgoff);4646-}4747-4848-/* Convert virtual (user) address VADDR to physical address PADDR */4949-#define virt_to_phys_040(vaddr) \5050-({ \5151- unsigned long _mmusr, _paddr; \5252- \5353- __asm__ __volatile__ (".chip 68040\n\t" \5454- "ptestr (%1)\n\t" \5555- "movec %%mmusr,%0\n\t" \5656- ".chip 68k" \5757- : "=r" (_mmusr) \5858- : "a" (vaddr)); \5959- _paddr = (_mmusr & MMU_R_040) ? (_mmusr & PAGE_MASK) : 0; \6060- _paddr; \6161-})6262-6363-static inline int6464-cache_flush_040 (unsigned long addr, int scope, int cache, unsigned long len)6565-{6666- unsigned long paddr, i;6767-6868- switch (scope)6969- {7070- case FLUSH_SCOPE_ALL:7171- switch (cache)7272- {7373- case FLUSH_CACHE_DATA:7474- /* This nop is needed for some broken versions of the 68040. */7575- __asm__ __volatile__ ("nop\n\t"7676- ".chip 68040\n\t"7777- "cpusha %dc\n\t"7878- ".chip 68k");7979- break;8080- case FLUSH_CACHE_INSN:8181- __asm__ __volatile__ ("nop\n\t"8282- ".chip 68040\n\t"8383- "cpusha %ic\n\t"8484- ".chip 68k");8585- break;8686- default:8787- case FLUSH_CACHE_BOTH:8888- __asm__ __volatile__ ("nop\n\t"8989- ".chip 68040\n\t"9090- "cpusha %bc\n\t"9191- ".chip 68k");9292- break;9393- }9494- break;9595-9696- case FLUSH_SCOPE_LINE:9797- /* Find the physical address of the first mapped page in the9898- address range. */9999- if ((paddr = virt_to_phys_040(addr))) {100100- paddr += addr & ~(PAGE_MASK | 15);101101- len = (len + (addr & 15) + 15) >> 4;102102- } else {103103- unsigned long tmp = PAGE_SIZE - (addr & ~PAGE_MASK);104104-105105- if (len <= tmp)106106- return 0;107107- addr += tmp;108108- len -= tmp;109109- tmp = PAGE_SIZE;110110- for (;;)111111- {112112- if ((paddr = virt_to_phys_040(addr)))113113- break;114114- if (len <= tmp)115115- return 0;116116- addr += tmp;117117- len -= tmp;118118- }119119- len = (len + 15) >> 4;120120- }121121- i = (PAGE_SIZE - (paddr & ~PAGE_MASK)) >> 4;122122- while (len--)123123- {124124- switch (cache)125125- {126126- case FLUSH_CACHE_DATA:127127- __asm__ __volatile__ ("nop\n\t"128128- ".chip 68040\n\t"129129- "cpushl %%dc,(%0)\n\t"130130- ".chip 68k"131131- : : "a" (paddr));132132- break;133133- case FLUSH_CACHE_INSN:134134- __asm__ __volatile__ ("nop\n\t"135135- ".chip 68040\n\t"136136- "cpushl %%ic,(%0)\n\t"137137- ".chip 68k"138138- : : "a" (paddr));139139- break;140140- default:141141- case FLUSH_CACHE_BOTH:142142- __asm__ __volatile__ ("nop\n\t"143143- ".chip 68040\n\t"144144- "cpushl %%bc,(%0)\n\t"145145- ".chip 68k"146146- : : "a" (paddr));147147- break;148148- }149149- if (!--i && len)150150- {151151- /*152152- * No need to page align here since it is done by153153- * virt_to_phys_040().154154- */155155- addr += PAGE_SIZE;156156- i = PAGE_SIZE / 16;157157- /* Recompute physical address when crossing a page158158- boundary. */159159- for (;;)160160- {161161- if ((paddr = virt_to_phys_040(addr)))162162- break;163163- if (len <= i)164164- return 0;165165- len -= i;166166- addr += PAGE_SIZE;167167- }168168- }169169- else170170- paddr += 16;171171- }172172- break;173173-174174- default:175175- case FLUSH_SCOPE_PAGE:176176- len += (addr & ~PAGE_MASK) + (PAGE_SIZE - 1);177177- for (len >>= PAGE_SHIFT; len--; addr += PAGE_SIZE)178178- {179179- if (!(paddr = virt_to_phys_040(addr)))180180- continue;181181- switch (cache)182182- {183183- case FLUSH_CACHE_DATA:184184- __asm__ __volatile__ ("nop\n\t"185185- ".chip 68040\n\t"186186- "cpushp %%dc,(%0)\n\t"187187- ".chip 68k"188188- : : "a" (paddr));189189- break;190190- case FLUSH_CACHE_INSN:191191- __asm__ __volatile__ ("nop\n\t"192192- ".chip 68040\n\t"193193- "cpushp %%ic,(%0)\n\t"194194- ".chip 68k"195195- : : "a" (paddr));196196- break;197197- default:198198- case FLUSH_CACHE_BOTH:199199- __asm__ __volatile__ ("nop\n\t"200200- ".chip 68040\n\t"201201- "cpushp %%bc,(%0)\n\t"202202- ".chip 68k"203203- : : "a" (paddr));204204- break;205205- }206206- }207207- break;208208- }209209- return 0;210210-}211211-212212-#define virt_to_phys_060(vaddr) \213213-({ \214214- unsigned long paddr; \215215- __asm__ __volatile__ (".chip 68060\n\t" \216216- "plpar (%0)\n\t" \217217- ".chip 68k" \218218- : "=a" (paddr) \219219- : "0" (vaddr)); \220220- (paddr); /* XXX */ \221221-})222222-223223-static inline int224224-cache_flush_060 (unsigned long addr, int scope, int cache, unsigned long len)225225-{226226- unsigned long paddr, i;227227-228228- /*229229- * 68060 manual says:230230- * cpush %dc : flush DC, remains valid (with our %cacr setup)231231- * cpush %ic : invalidate IC232232- * cpush %bc : flush DC + invalidate IC233233- */234234- switch (scope)235235- {236236- case FLUSH_SCOPE_ALL:237237- switch (cache)238238- {239239- case FLUSH_CACHE_DATA:240240- __asm__ __volatile__ (".chip 68060\n\t"241241- "cpusha %dc\n\t"242242- ".chip 68k");243243- break;244244- case FLUSH_CACHE_INSN:245245- __asm__ __volatile__ (".chip 68060\n\t"246246- "cpusha %ic\n\t"247247- ".chip 68k");248248- break;249249- default:250250- case FLUSH_CACHE_BOTH:251251- __asm__ __volatile__ (".chip 68060\n\t"252252- "cpusha %bc\n\t"253253- ".chip 68k");254254- break;255255- }256256- break;257257-258258- case FLUSH_SCOPE_LINE:259259- /* Find the physical address of the first mapped page in the260260- address range. */261261- len += addr & 15;262262- addr &= -16;263263- if (!(paddr = virt_to_phys_060(addr))) {264264- unsigned long tmp = PAGE_SIZE - (addr & ~PAGE_MASK);265265-266266- if (len <= tmp)267267- return 0;268268- addr += tmp;269269- len -= tmp;270270- tmp = PAGE_SIZE;271271- for (;;)272272- {273273- if ((paddr = virt_to_phys_060(addr)))274274- break;275275- if (len <= tmp)276276- return 0;277277- addr += tmp;278278- len -= tmp;279279- }280280- }281281- len = (len + 15) >> 4;282282- i = (PAGE_SIZE - (paddr & ~PAGE_MASK)) >> 4;283283- while (len--)284284- {285285- switch (cache)286286- {287287- case FLUSH_CACHE_DATA:288288- __asm__ __volatile__ (".chip 68060\n\t"289289- "cpushl %%dc,(%0)\n\t"290290- ".chip 68k"291291- : : "a" (paddr));292292- break;293293- case FLUSH_CACHE_INSN:294294- __asm__ __volatile__ (".chip 68060\n\t"295295- "cpushl %%ic,(%0)\n\t"296296- ".chip 68k"297297- : : "a" (paddr));298298- break;299299- default:300300- case FLUSH_CACHE_BOTH:301301- __asm__ __volatile__ (".chip 68060\n\t"302302- "cpushl %%bc,(%0)\n\t"303303- ".chip 68k"304304- : : "a" (paddr));305305- break;306306- }307307- if (!--i && len)308308- {309309-310310- /*311311- * We just want to jump to the first cache line312312- * in the next page.313313- */314314- addr += PAGE_SIZE;315315- addr &= PAGE_MASK;316316-317317- i = PAGE_SIZE / 16;318318- /* Recompute physical address when crossing a page319319- boundary. */320320- for (;;)321321- {322322- if ((paddr = virt_to_phys_060(addr)))323323- break;324324- if (len <= i)325325- return 0;326326- len -= i;327327- addr += PAGE_SIZE;328328- }329329- }330330- else331331- paddr += 16;332332- }333333- break;334334-335335- default:336336- case FLUSH_SCOPE_PAGE:337337- len += (addr & ~PAGE_MASK) + (PAGE_SIZE - 1);338338- addr &= PAGE_MASK; /* Workaround for bug in some339339- revisions of the 68060 */340340- for (len >>= PAGE_SHIFT; len--; addr += PAGE_SIZE)341341- {342342- if (!(paddr = virt_to_phys_060(addr)))343343- continue;344344- switch (cache)345345- {346346- case FLUSH_CACHE_DATA:347347- __asm__ __volatile__ (".chip 68060\n\t"348348- "cpushp %%dc,(%0)\n\t"349349- ".chip 68k"350350- : : "a" (paddr));351351- break;352352- case FLUSH_CACHE_INSN:353353- __asm__ __volatile__ (".chip 68060\n\t"354354- "cpushp %%ic,(%0)\n\t"355355- ".chip 68k"356356- : : "a" (paddr));357357- break;358358- default:359359- case FLUSH_CACHE_BOTH:360360- __asm__ __volatile__ (".chip 68060\n\t"361361- "cpushp %%bc,(%0)\n\t"362362- ".chip 68k"363363- : : "a" (paddr));364364- break;365365- }366366- }367367- break;368368- }369369- return 0;370370-}371371-372372-/* sys_cacheflush -- flush (part of) the processor cache. */373373-asmlinkage int374374-sys_cacheflush (unsigned long addr, int scope, int cache, unsigned long len)375375-{376376- struct vm_area_struct *vma;377377- int ret = -EINVAL;378378-379379- if (scope < FLUSH_SCOPE_LINE || scope > FLUSH_SCOPE_ALL ||380380- cache & ~FLUSH_CACHE_BOTH)381381- goto out;382382-383383- if (scope == FLUSH_SCOPE_ALL) {384384- /* Only the superuser may explicitly flush the whole cache. */385385- ret = -EPERM;386386- if (!capable(CAP_SYS_ADMIN))387387- goto out;388388- } else {389389- /*390390- * Verify that the specified address region actually belongs391391- * to this process.392392- */393393- vma = find_vma (current->mm, addr);394394- ret = -EINVAL;395395- /* Check for overflow. */396396- if (addr + len < addr)397397- goto out;398398- if (vma == NULL || addr < vma->vm_start || addr + len > vma->vm_end)399399- goto out;400400- }401401-402402- if (CPU_IS_020_OR_030) {403403- if (scope == FLUSH_SCOPE_LINE && len < 256) {404404- unsigned long cacr;405405- __asm__ ("movec %%cacr, %0" : "=r" (cacr));406406- if (cache & FLUSH_CACHE_INSN)407407- cacr |= 4;408408- if (cache & FLUSH_CACHE_DATA)409409- cacr |= 0x400;410410- len >>= 2;411411- while (len--) {412412- __asm__ __volatile__ ("movec %1, %%caar\n\t"413413- "movec %0, %%cacr"414414- : /* no outputs */415415- : "r" (cacr), "r" (addr));416416- addr += 4;417417- }418418- } else {419419- /* Flush the whole cache, even if page granularity requested. */420420- unsigned long cacr;421421- __asm__ ("movec %%cacr, %0" : "=r" (cacr));422422- if (cache & FLUSH_CACHE_INSN)423423- cacr |= 8;424424- if (cache & FLUSH_CACHE_DATA)425425- cacr |= 0x800;426426- __asm__ __volatile__ ("movec %0, %%cacr" : : "r" (cacr));427427- }428428- ret = 0;429429- goto out;430430- } else {431431- /*432432- * 040 or 060: don't blindly trust 'scope', someone could433433- * try to flush a few megs of memory.434434- */435435-436436- if (len>=3*PAGE_SIZE && scope<FLUSH_SCOPE_PAGE)437437- scope=FLUSH_SCOPE_PAGE;438438- if (len>=10*PAGE_SIZE && scope<FLUSH_SCOPE_ALL)439439- scope=FLUSH_SCOPE_ALL;440440- if (CPU_IS_040) {441441- ret = cache_flush_040 (addr, scope, cache, len);442442- } else if (CPU_IS_060) {443443- ret = cache_flush_060 (addr, scope, cache, len);444444- }445445- }446446-out:447447- return ret;448448-}449449-450450-asmlinkage int sys_getpagesize(void)451451-{452452- return PAGE_SIZE;453453-}454454-455455-/*456456- * Do a system call from kernel instead of calling sys_execve so we457457- * end up with proper pt_regs.458458- */459459-int kernel_execve(const char *filename,460460- const char *const argv[],461461- const char *const envp[])462462-{463463- register long __res asm ("%d0") = __NR_execve;464464- register long __a asm ("%d1") = (long)(filename);465465- register long __b asm ("%d2") = (long)(argv);466466- register long __c asm ("%d3") = (long)(envp);467467- asm volatile ("trap #0" : "+d" (__res)468468- : "d" (__a), "d" (__b), "d" (__c));469469- return __res;470470-}471471-472472-asmlinkage unsigned long sys_get_thread_area(void)473473-{474474- return current_thread_info()->tp_value;475475-}476476-477477-asmlinkage int sys_set_thread_area(unsigned long tp)478478-{479479- current_thread_info()->tp_value = tp;480480- return 0;481481-}482482-483483-/* This syscall gets its arguments in A0 (mem), D2 (oldval) and484484- D1 (newval). */485485-asmlinkage int486486-sys_atomic_cmpxchg_32(unsigned long newval, int oldval, int d3, int d4, int d5,487487- unsigned long __user * mem)488488-{489489- /* This was borrowed from ARM's implementation. */490490- for (;;) {491491- struct mm_struct *mm = current->mm;492492- pgd_t *pgd;493493- pmd_t *pmd;494494- pte_t *pte;495495- spinlock_t *ptl;496496- unsigned long mem_value;497497-498498- down_read(&mm->mmap_sem);499499- pgd = pgd_offset(mm, (unsigned long)mem);500500- if (!pgd_present(*pgd))501501- goto bad_access;502502- pmd = pmd_offset(pgd, (unsigned long)mem);503503- if (!pmd_present(*pmd))504504- goto bad_access;505505- pte = pte_offset_map_lock(mm, pmd, (unsigned long)mem, &ptl);506506- if (!pte_present(*pte) || !pte_dirty(*pte)507507- || !pte_write(*pte)) {508508- pte_unmap_unlock(pte, ptl);509509- goto bad_access;510510- }511511-512512- mem_value = *mem;513513- if (mem_value == oldval)514514- *mem = newval;515515-516516- pte_unmap_unlock(pte, ptl);517517- up_read(&mm->mmap_sem);518518- return mem_value;519519-520520- bad_access:521521- up_read(&mm->mmap_sem);522522- /* This is not necessarily a bad access, we can get here if523523- a memory we're trying to write to should be copied-on-write.524524- Make the kernel do the necessary page stuff, then re-iterate.525525- Simulate a write access fault to do that. */526526- {527527- /* The first argument of the function corresponds to528528- D1, which is the first field of struct pt_regs. */529529- struct pt_regs *fp = (struct pt_regs *)&newval;530530-531531- /* '3' is an RMW flag. */532532- if (do_page_fault(fp, (unsigned long)mem, 3))533533- /* If the do_page_fault() failed, we don't534534- have anything meaningful to return.535535- There should be a SIGSEGV pending for536536- the process. */537537- return 0xdeadbeef;538538- }539539- }540540-}541541-542542-asmlinkage int sys_atomic_barrier(void)543543-{544544- /* no code needed for uniprocs */545545- return 0;546546-}11+#ifdef CONFIG_MMU22+#include "sys_m68k_mm.c"33+#else44+#include "sys_m68k_no.c"55+#endif
+546
arch/m68k/kernel/sys_m68k_mm.c
···11+/*22+ * linux/arch/m68k/kernel/sys_m68k.c33+ *44+ * This file contains various random system calls that55+ * have a non-standard calling sequence on the Linux/m68k66+ * platform.77+ */88+99+#include <linux/capability.h>1010+#include <linux/errno.h>1111+#include <linux/sched.h>1212+#include <linux/mm.h>1313+#include <linux/fs.h>1414+#include <linux/smp.h>1515+#include <linux/sem.h>1616+#include <linux/msg.h>1717+#include <linux/shm.h>1818+#include <linux/stat.h>1919+#include <linux/syscalls.h>2020+#include <linux/mman.h>2121+#include <linux/file.h>2222+#include <linux/ipc.h>2323+2424+#include <asm/setup.h>2525+#include <asm/uaccess.h>2626+#include <asm/cachectl.h>2727+#include <asm/traps.h>2828+#include <asm/page.h>2929+#include <asm/unistd.h>3030+#include <linux/elf.h>3131+#include <asm/tlb.h>3232+3333+asmlinkage int do_page_fault(struct pt_regs *regs, unsigned long address,3434+ unsigned long error_code);3535+3636+asmlinkage long sys_mmap2(unsigned long addr, unsigned long len,3737+ unsigned long prot, unsigned long flags,3838+ unsigned long fd, unsigned long pgoff)3939+{4040+ /*4141+ * This is wrong for sun3 - there PAGE_SIZE is 8Kb,4242+ * so we need to shift the argument down by 1; m68k mmap64(3)4343+ * (in libc) expects the last argument of mmap2 in 4Kb units.4444+ */4545+ return sys_mmap_pgoff(addr, len, prot, flags, fd, pgoff);4646+}4747+4848+/* Convert virtual (user) address VADDR to physical address PADDR */4949+#define virt_to_phys_040(vaddr) \5050+({ \5151+ unsigned long _mmusr, _paddr; \5252+ \5353+ __asm__ __volatile__ (".chip 68040\n\t" \5454+ "ptestr (%1)\n\t" \5555+ "movec %%mmusr,%0\n\t" \5656+ ".chip 68k" \5757+ : "=r" (_mmusr) \5858+ : "a" (vaddr)); \5959+ _paddr = (_mmusr & MMU_R_040) ? (_mmusr & PAGE_MASK) : 0; \6060+ _paddr; \6161+})6262+6363+static inline int6464+cache_flush_040 (unsigned long addr, int scope, int cache, unsigned long len)6565+{6666+ unsigned long paddr, i;6767+6868+ switch (scope)6969+ {7070+ case FLUSH_SCOPE_ALL:7171+ switch (cache)7272+ {7373+ case FLUSH_CACHE_DATA:7474+ /* This nop is needed for some broken versions of the 68040. */7575+ __asm__ __volatile__ ("nop\n\t"7676+ ".chip 68040\n\t"7777+ "cpusha %dc\n\t"7878+ ".chip 68k");7979+ break;8080+ case FLUSH_CACHE_INSN:8181+ __asm__ __volatile__ ("nop\n\t"8282+ ".chip 68040\n\t"8383+ "cpusha %ic\n\t"8484+ ".chip 68k");8585+ break;8686+ default:8787+ case FLUSH_CACHE_BOTH:8888+ __asm__ __volatile__ ("nop\n\t"8989+ ".chip 68040\n\t"9090+ "cpusha %bc\n\t"9191+ ".chip 68k");9292+ break;9393+ }9494+ break;9595+9696+ case FLUSH_SCOPE_LINE:9797+ /* Find the physical address of the first mapped page in the9898+ address range. */9999+ if ((paddr = virt_to_phys_040(addr))) {100100+ paddr += addr & ~(PAGE_MASK | 15);101101+ len = (len + (addr & 15) + 15) >> 4;102102+ } else {103103+ unsigned long tmp = PAGE_SIZE - (addr & ~PAGE_MASK);104104+105105+ if (len <= tmp)106106+ return 0;107107+ addr += tmp;108108+ len -= tmp;109109+ tmp = PAGE_SIZE;110110+ for (;;)111111+ {112112+ if ((paddr = virt_to_phys_040(addr)))113113+ break;114114+ if (len <= tmp)115115+ return 0;116116+ addr += tmp;117117+ len -= tmp;118118+ }119119+ len = (len + 15) >> 4;120120+ }121121+ i = (PAGE_SIZE - (paddr & ~PAGE_MASK)) >> 4;122122+ while (len--)123123+ {124124+ switch (cache)125125+ {126126+ case FLUSH_CACHE_DATA:127127+ __asm__ __volatile__ ("nop\n\t"128128+ ".chip 68040\n\t"129129+ "cpushl %%dc,(%0)\n\t"130130+ ".chip 68k"131131+ : : "a" (paddr));132132+ break;133133+ case FLUSH_CACHE_INSN:134134+ __asm__ __volatile__ ("nop\n\t"135135+ ".chip 68040\n\t"136136+ "cpushl %%ic,(%0)\n\t"137137+ ".chip 68k"138138+ : : "a" (paddr));139139+ break;140140+ default:141141+ case FLUSH_CACHE_BOTH:142142+ __asm__ __volatile__ ("nop\n\t"143143+ ".chip 68040\n\t"144144+ "cpushl %%bc,(%0)\n\t"145145+ ".chip 68k"146146+ : : "a" (paddr));147147+ break;148148+ }149149+ if (!--i && len)150150+ {151151+ /*152152+ * No need to page align here since it is done by153153+ * virt_to_phys_040().154154+ */155155+ addr += PAGE_SIZE;156156+ i = PAGE_SIZE / 16;157157+ /* Recompute physical address when crossing a page158158+ boundary. */159159+ for (;;)160160+ {161161+ if ((paddr = virt_to_phys_040(addr)))162162+ break;163163+ if (len <= i)164164+ return 0;165165+ len -= i;166166+ addr += PAGE_SIZE;167167+ }168168+ }169169+ else170170+ paddr += 16;171171+ }172172+ break;173173+174174+ default:175175+ case FLUSH_SCOPE_PAGE:176176+ len += (addr & ~PAGE_MASK) + (PAGE_SIZE - 1);177177+ for (len >>= PAGE_SHIFT; len--; addr += PAGE_SIZE)178178+ {179179+ if (!(paddr = virt_to_phys_040(addr)))180180+ continue;181181+ switch (cache)182182+ {183183+ case FLUSH_CACHE_DATA:184184+ __asm__ __volatile__ ("nop\n\t"185185+ ".chip 68040\n\t"186186+ "cpushp %%dc,(%0)\n\t"187187+ ".chip 68k"188188+ : : "a" (paddr));189189+ break;190190+ case FLUSH_CACHE_INSN:191191+ __asm__ __volatile__ ("nop\n\t"192192+ ".chip 68040\n\t"193193+ "cpushp %%ic,(%0)\n\t"194194+ ".chip 68k"195195+ : : "a" (paddr));196196+ break;197197+ default:198198+ case FLUSH_CACHE_BOTH:199199+ __asm__ __volatile__ ("nop\n\t"200200+ ".chip 68040\n\t"201201+ "cpushp %%bc,(%0)\n\t"202202+ ".chip 68k"203203+ : : "a" (paddr));204204+ break;205205+ }206206+ }207207+ break;208208+ }209209+ return 0;210210+}211211+212212+#define virt_to_phys_060(vaddr) \213213+({ \214214+ unsigned long paddr; \215215+ __asm__ __volatile__ (".chip 68060\n\t" \216216+ "plpar (%0)\n\t" \217217+ ".chip 68k" \218218+ : "=a" (paddr) \219219+ : "0" (vaddr)); \220220+ (paddr); /* XXX */ \221221+})222222+223223+static inline int224224+cache_flush_060 (unsigned long addr, int scope, int cache, unsigned long len)225225+{226226+ unsigned long paddr, i;227227+228228+ /*229229+ * 68060 manual says:230230+ * cpush %dc : flush DC, remains valid (with our %cacr setup)231231+ * cpush %ic : invalidate IC232232+ * cpush %bc : flush DC + invalidate IC233233+ */234234+ switch (scope)235235+ {236236+ case FLUSH_SCOPE_ALL:237237+ switch (cache)238238+ {239239+ case FLUSH_CACHE_DATA:240240+ __asm__ __volatile__ (".chip 68060\n\t"241241+ "cpusha %dc\n\t"242242+ ".chip 68k");243243+ break;244244+ case FLUSH_CACHE_INSN:245245+ __asm__ __volatile__ (".chip 68060\n\t"246246+ "cpusha %ic\n\t"247247+ ".chip 68k");248248+ break;249249+ default:250250+ case FLUSH_CACHE_BOTH:251251+ __asm__ __volatile__ (".chip 68060\n\t"252252+ "cpusha %bc\n\t"253253+ ".chip 68k");254254+ break;255255+ }256256+ break;257257+258258+ case FLUSH_SCOPE_LINE:259259+ /* Find the physical address of the first mapped page in the260260+ address range. */261261+ len += addr & 15;262262+ addr &= -16;263263+ if (!(paddr = virt_to_phys_060(addr))) {264264+ unsigned long tmp = PAGE_SIZE - (addr & ~PAGE_MASK);265265+266266+ if (len <= tmp)267267+ return 0;268268+ addr += tmp;269269+ len -= tmp;270270+ tmp = PAGE_SIZE;271271+ for (;;)272272+ {273273+ if ((paddr = virt_to_phys_060(addr)))274274+ break;275275+ if (len <= tmp)276276+ return 0;277277+ addr += tmp;278278+ len -= tmp;279279+ }280280+ }281281+ len = (len + 15) >> 4;282282+ i = (PAGE_SIZE - (paddr & ~PAGE_MASK)) >> 4;283283+ while (len--)284284+ {285285+ switch (cache)286286+ {287287+ case FLUSH_CACHE_DATA:288288+ __asm__ __volatile__ (".chip 68060\n\t"289289+ "cpushl %%dc,(%0)\n\t"290290+ ".chip 68k"291291+ : : "a" (paddr));292292+ break;293293+ case FLUSH_CACHE_INSN:294294+ __asm__ __volatile__ (".chip 68060\n\t"295295+ "cpushl %%ic,(%0)\n\t"296296+ ".chip 68k"297297+ : : "a" (paddr));298298+ break;299299+ default:300300+ case FLUSH_CACHE_BOTH:301301+ __asm__ __volatile__ (".chip 68060\n\t"302302+ "cpushl %%bc,(%0)\n\t"303303+ ".chip 68k"304304+ : : "a" (paddr));305305+ break;306306+ }307307+ if (!--i && len)308308+ {309309+310310+ /*311311+ * We just want to jump to the first cache line312312+ * in the next page.313313+ */314314+ addr += PAGE_SIZE;315315+ addr &= PAGE_MASK;316316+317317+ i = PAGE_SIZE / 16;318318+ /* Recompute physical address when crossing a page319319+ boundary. */320320+ for (;;)321321+ {322322+ if ((paddr = virt_to_phys_060(addr)))323323+ break;324324+ if (len <= i)325325+ return 0;326326+ len -= i;327327+ addr += PAGE_SIZE;328328+ }329329+ }330330+ else331331+ paddr += 16;332332+ }333333+ break;334334+335335+ default:336336+ case FLUSH_SCOPE_PAGE:337337+ len += (addr & ~PAGE_MASK) + (PAGE_SIZE - 1);338338+ addr &= PAGE_MASK; /* Workaround for bug in some339339+ revisions of the 68060 */340340+ for (len >>= PAGE_SHIFT; len--; addr += PAGE_SIZE)341341+ {342342+ if (!(paddr = virt_to_phys_060(addr)))343343+ continue;344344+ switch (cache)345345+ {346346+ case FLUSH_CACHE_DATA:347347+ __asm__ __volatile__ (".chip 68060\n\t"348348+ "cpushp %%dc,(%0)\n\t"349349+ ".chip 68k"350350+ : : "a" (paddr));351351+ break;352352+ case FLUSH_CACHE_INSN:353353+ __asm__ __volatile__ (".chip 68060\n\t"354354+ "cpushp %%ic,(%0)\n\t"355355+ ".chip 68k"356356+ : : "a" (paddr));357357+ break;358358+ default:359359+ case FLUSH_CACHE_BOTH:360360+ __asm__ __volatile__ (".chip 68060\n\t"361361+ "cpushp %%bc,(%0)\n\t"362362+ ".chip 68k"363363+ : : "a" (paddr));364364+ break;365365+ }366366+ }367367+ break;368368+ }369369+ return 0;370370+}371371+372372+/* sys_cacheflush -- flush (part of) the processor cache. */373373+asmlinkage int374374+sys_cacheflush (unsigned long addr, int scope, int cache, unsigned long len)375375+{376376+ struct vm_area_struct *vma;377377+ int ret = -EINVAL;378378+379379+ if (scope < FLUSH_SCOPE_LINE || scope > FLUSH_SCOPE_ALL ||380380+ cache & ~FLUSH_CACHE_BOTH)381381+ goto out;382382+383383+ if (scope == FLUSH_SCOPE_ALL) {384384+ /* Only the superuser may explicitly flush the whole cache. */385385+ ret = -EPERM;386386+ if (!capable(CAP_SYS_ADMIN))387387+ goto out;388388+ } else {389389+ /*390390+ * Verify that the specified address region actually belongs391391+ * to this process.392392+ */393393+ vma = find_vma (current->mm, addr);394394+ ret = -EINVAL;395395+ /* Check for overflow. */396396+ if (addr + len < addr)397397+ goto out;398398+ if (vma == NULL || addr < vma->vm_start || addr + len > vma->vm_end)399399+ goto out;400400+ }401401+402402+ if (CPU_IS_020_OR_030) {403403+ if (scope == FLUSH_SCOPE_LINE && len < 256) {404404+ unsigned long cacr;405405+ __asm__ ("movec %%cacr, %0" : "=r" (cacr));406406+ if (cache & FLUSH_CACHE_INSN)407407+ cacr |= 4;408408+ if (cache & FLUSH_CACHE_DATA)409409+ cacr |= 0x400;410410+ len >>= 2;411411+ while (len--) {412412+ __asm__ __volatile__ ("movec %1, %%caar\n\t"413413+ "movec %0, %%cacr"414414+ : /* no outputs */415415+ : "r" (cacr), "r" (addr));416416+ addr += 4;417417+ }418418+ } else {419419+ /* Flush the whole cache, even if page granularity requested. */420420+ unsigned long cacr;421421+ __asm__ ("movec %%cacr, %0" : "=r" (cacr));422422+ if (cache & FLUSH_CACHE_INSN)423423+ cacr |= 8;424424+ if (cache & FLUSH_CACHE_DATA)425425+ cacr |= 0x800;426426+ __asm__ __volatile__ ("movec %0, %%cacr" : : "r" (cacr));427427+ }428428+ ret = 0;429429+ goto out;430430+ } else {431431+ /*432432+ * 040 or 060: don't blindly trust 'scope', someone could433433+ * try to flush a few megs of memory.434434+ */435435+436436+ if (len>=3*PAGE_SIZE && scope<FLUSH_SCOPE_PAGE)437437+ scope=FLUSH_SCOPE_PAGE;438438+ if (len>=10*PAGE_SIZE && scope<FLUSH_SCOPE_ALL)439439+ scope=FLUSH_SCOPE_ALL;440440+ if (CPU_IS_040) {441441+ ret = cache_flush_040 (addr, scope, cache, len);442442+ } else if (CPU_IS_060) {443443+ ret = cache_flush_060 (addr, scope, cache, len);444444+ }445445+ }446446+out:447447+ return ret;448448+}449449+450450+asmlinkage int sys_getpagesize(void)451451+{452452+ return PAGE_SIZE;453453+}454454+455455+/*456456+ * Do a system call from kernel instead of calling sys_execve so we457457+ * end up with proper pt_regs.458458+ */459459+int kernel_execve(const char *filename,460460+ const char *const argv[],461461+ const char *const envp[])462462+{463463+ register long __res asm ("%d0") = __NR_execve;464464+ register long __a asm ("%d1") = (long)(filename);465465+ register long __b asm ("%d2") = (long)(argv);466466+ register long __c asm ("%d3") = (long)(envp);467467+ asm volatile ("trap #0" : "+d" (__res)468468+ : "d" (__a), "d" (__b), "d" (__c));469469+ return __res;470470+}471471+472472+asmlinkage unsigned long sys_get_thread_area(void)473473+{474474+ return current_thread_info()->tp_value;475475+}476476+477477+asmlinkage int sys_set_thread_area(unsigned long tp)478478+{479479+ current_thread_info()->tp_value = tp;480480+ return 0;481481+}482482+483483+/* This syscall gets its arguments in A0 (mem), D2 (oldval) and484484+ D1 (newval). */485485+asmlinkage int486486+sys_atomic_cmpxchg_32(unsigned long newval, int oldval, int d3, int d4, int d5,487487+ unsigned long __user * mem)488488+{489489+ /* This was borrowed from ARM's implementation. */490490+ for (;;) {491491+ struct mm_struct *mm = current->mm;492492+ pgd_t *pgd;493493+ pmd_t *pmd;494494+ pte_t *pte;495495+ spinlock_t *ptl;496496+ unsigned long mem_value;497497+498498+ down_read(&mm->mmap_sem);499499+ pgd = pgd_offset(mm, (unsigned long)mem);500500+ if (!pgd_present(*pgd))501501+ goto bad_access;502502+ pmd = pmd_offset(pgd, (unsigned long)mem);503503+ if (!pmd_present(*pmd))504504+ goto bad_access;505505+ pte = pte_offset_map_lock(mm, pmd, (unsigned long)mem, &ptl);506506+ if (!pte_present(*pte) || !pte_dirty(*pte)507507+ || !pte_write(*pte)) {508508+ pte_unmap_unlock(pte, ptl);509509+ goto bad_access;510510+ }511511+512512+ mem_value = *mem;513513+ if (mem_value == oldval)514514+ *mem = newval;515515+516516+ pte_unmap_unlock(pte, ptl);517517+ up_read(&mm->mmap_sem);518518+ return mem_value;519519+520520+ bad_access:521521+ up_read(&mm->mmap_sem);522522+ /* This is not necessarily a bad access, we can get here if523523+ a memory we're trying to write to should be copied-on-write.524524+ Make the kernel do the necessary page stuff, then re-iterate.525525+ Simulate a write access fault to do that. */526526+ {527527+ /* The first argument of the function corresponds to528528+ D1, which is the first field of struct pt_regs. */529529+ struct pt_regs *fp = (struct pt_regs *)&newval;530530+531531+ /* '3' is an RMW flag. */532532+ if (do_page_fault(fp, (unsigned long)mem, 3))533533+ /* If the do_page_fault() failed, we don't534534+ have anything meaningful to return.535535+ There should be a SIGSEGV pending for536536+ the process. */537537+ return 0xdeadbeef;538538+ }539539+ }540540+}541541+542542+asmlinkage int sys_atomic_barrier(void)543543+{544544+ /* no code needed for uniprocs */545545+ return 0;546546+}
+5-114
arch/m68k/kernel/time.c
···11-/*22- * linux/arch/m68k/kernel/time.c33- *44- * Copyright (C) 1991, 1992, 1995 Linus Torvalds55- *66- * This file contains the m68k-specific time handling details.77- * Most of the stuff is located in the machine specific files.88- *99- * 1997-09-10 Updated NTP code according to technical memorandum Jan '961010- * "A Kernel Model for Precision Timekeeping" by Dave Mills1111- */1212-1313-#include <linux/errno.h>1414-#include <linux/module.h>1515-#include <linux/sched.h>1616-#include <linux/kernel.h>1717-#include <linux/param.h>1818-#include <linux/string.h>1919-#include <linux/mm.h>2020-#include <linux/rtc.h>2121-#include <linux/platform_device.h>2222-2323-#include <asm/machdep.h>2424-#include <asm/io.h>2525-#include <asm/irq_regs.h>2626-2727-#include <linux/time.h>2828-#include <linux/timex.h>2929-#include <linux/profile.h>3030-3131-static inline int set_rtc_mmss(unsigned long nowtime)3232-{3333- if (mach_set_clock_mmss)3434- return mach_set_clock_mmss (nowtime);3535- return -1;3636-}3737-3838-/*3939- * timer_interrupt() needs to keep up the real-time clock,4040- * as well as call the "xtime_update()" routine every clocktick4141- */4242-static irqreturn_t timer_interrupt(int irq, void *dummy)4343-{4444- xtime_update(1);4545- update_process_times(user_mode(get_irq_regs()));4646- profile_tick(CPU_PROFILING);4747-4848-#ifdef CONFIG_HEARTBEAT4949- /* use power LED as a heartbeat instead -- much more useful5050- for debugging -- based on the version for PReP by Cort */5151- /* acts like an actual heart beat -- ie thump-thump-pause... */5252- if (mach_heartbeat) {5353- static unsigned cnt = 0, period = 0, dist = 0;5454-5555- if (cnt == 0 || cnt == dist)5656- mach_heartbeat( 1 );5757- else if (cnt == 7 || cnt == dist+7)5858- mach_heartbeat( 0 );5959-6060- if (++cnt > period) {6161- cnt = 0;6262- /* The hyperbolic function below modifies the heartbeat period6363- * length in dependency of the current (5min) load. It goes6464- * through the points f(0)=126, f(1)=86, f(5)=51,6565- * f(inf)->30. */6666- period = ((672<<FSHIFT)/(5*avenrun[0]+(7<<FSHIFT))) + 30;6767- dist = period / 4;6868- }6969- }7070-#endif /* CONFIG_HEARTBEAT */7171- return IRQ_HANDLED;7272-}7373-7474-void read_persistent_clock(struct timespec *ts)7575-{7676- struct rtc_time time;7777- ts->tv_sec = 0;7878- ts->tv_nsec = 0;7979-8080- if (mach_hwclk) {8181- mach_hwclk(0, &time);8282-8383- if ((time.tm_year += 1900) < 1970)8484- time.tm_year += 100;8585- ts->tv_sec = mktime(time.tm_year, time.tm_mon, time.tm_mday,8686- time.tm_hour, time.tm_min, time.tm_sec);8787- }8888-}8989-9090-void __init time_init(void)9191-{9292- mach_sched_init(timer_interrupt);9393-}9494-9595-u32 arch_gettimeoffset(void)9696-{9797- return mach_gettimeoffset() * 1000;9898-}9999-100100-static int __init rtc_init(void)101101-{102102- struct platform_device *pdev;103103-104104- if (!mach_hwclk)105105- return -ENODEV;106106-107107- pdev = platform_device_register_simple("rtc-generic", -1, NULL, 0);108108- if (IS_ERR(pdev))109109- return PTR_ERR(pdev);110110-111111- return 0;112112-}113113-114114-module_init(rtc_init);11+#ifdef CONFIG_MMU22+#include "time_mm.c"33+#else44+#include "time_no.c"55+#endif
+114
arch/m68k/kernel/time_mm.c
···11+/*22+ * linux/arch/m68k/kernel/time.c33+ *44+ * Copyright (C) 1991, 1992, 1995 Linus Torvalds55+ *66+ * This file contains the m68k-specific time handling details.77+ * Most of the stuff is located in the machine specific files.88+ *99+ * 1997-09-10 Updated NTP code according to technical memorandum Jan '961010+ * "A Kernel Model for Precision Timekeeping" by Dave Mills1111+ */1212+1313+#include <linux/errno.h>1414+#include <linux/module.h>1515+#include <linux/sched.h>1616+#include <linux/kernel.h>1717+#include <linux/param.h>1818+#include <linux/string.h>1919+#include <linux/mm.h>2020+#include <linux/rtc.h>2121+#include <linux/platform_device.h>2222+2323+#include <asm/machdep.h>2424+#include <asm/io.h>2525+#include <asm/irq_regs.h>2626+2727+#include <linux/time.h>2828+#include <linux/timex.h>2929+#include <linux/profile.h>3030+3131+static inline int set_rtc_mmss(unsigned long nowtime)3232+{3333+ if (mach_set_clock_mmss)3434+ return mach_set_clock_mmss (nowtime);3535+ return -1;3636+}3737+3838+/*3939+ * timer_interrupt() needs to keep up the real-time clock,4040+ * as well as call the "xtime_update()" routine every clocktick4141+ */4242+static irqreturn_t timer_interrupt(int irq, void *dummy)4343+{4444+ xtime_update(1);4545+ update_process_times(user_mode(get_irq_regs()));4646+ profile_tick(CPU_PROFILING);4747+4848+#ifdef CONFIG_HEARTBEAT4949+ /* use power LED as a heartbeat instead -- much more useful5050+ for debugging -- based on the version for PReP by Cort */5151+ /* acts like an actual heart beat -- ie thump-thump-pause... */5252+ if (mach_heartbeat) {5353+ static unsigned cnt = 0, period = 0, dist = 0;5454+5555+ if (cnt == 0 || cnt == dist)5656+ mach_heartbeat( 1 );5757+ else if (cnt == 7 || cnt == dist+7)5858+ mach_heartbeat( 0 );5959+6060+ if (++cnt > period) {6161+ cnt = 0;6262+ /* The hyperbolic function below modifies the heartbeat period6363+ * length in dependency of the current (5min) load. It goes6464+ * through the points f(0)=126, f(1)=86, f(5)=51,6565+ * f(inf)->30. */6666+ period = ((672<<FSHIFT)/(5*avenrun[0]+(7<<FSHIFT))) + 30;6767+ dist = period / 4;6868+ }6969+ }7070+#endif /* CONFIG_HEARTBEAT */7171+ return IRQ_HANDLED;7272+}7373+7474+void read_persistent_clock(struct timespec *ts)7575+{7676+ struct rtc_time time;7777+ ts->tv_sec = 0;7878+ ts->tv_nsec = 0;7979+8080+ if (mach_hwclk) {8181+ mach_hwclk(0, &time);8282+8383+ if ((time.tm_year += 1900) < 1970)8484+ time.tm_year += 100;8585+ ts->tv_sec = mktime(time.tm_year, time.tm_mon, time.tm_mday,8686+ time.tm_hour, time.tm_min, time.tm_sec);8787+ }8888+}8989+9090+void __init time_init(void)9191+{9292+ mach_sched_init(timer_interrupt);9393+}9494+9595+u32 arch_gettimeoffset(void)9696+{9797+ return mach_gettimeoffset() * 1000;9898+}9999+100100+static int __init rtc_init(void)101101+{102102+ struct platform_device *pdev;103103+104104+ if (!mach_hwclk)105105+ return -ENODEV;106106+107107+ pdev = platform_device_register_simple("rtc-generic", -1, NULL, 0);108108+ if (IS_ERR(pdev))109109+ return PTR_ERR(pdev);110110+111111+ return 0;112112+}113113+114114+module_init(rtc_init);
+3-1205
arch/m68k/kernel/traps.c
···11-/*22- * linux/arch/m68k/kernel/traps.c33- *44- * Copyright (C) 1993, 1994 by Hamish Macdonald55- *66- * 68040 fixes by Michael Rausch77- * 68040 fixes by Martin Apel88- * 68040 fixes and writeback by Richard Zidlicky99- * 68060 fixes by Roman Hodek1010- * 68060 fixes by Jesper Skov1111- *1212- * This file is subject to the terms and conditions of the GNU General Public1313- * License. See the file COPYING in the main directory of this archive1414- * for more details.1515- */1616-1717-/*1818- * Sets up all exception vectors1919- */2020-2121-#include <linux/sched.h>2222-#include <linux/signal.h>2323-#include <linux/kernel.h>2424-#include <linux/mm.h>2525-#include <linux/module.h>2626-#include <linux/user.h>2727-#include <linux/string.h>2828-#include <linux/linkage.h>2929-#include <linux/init.h>3030-#include <linux/ptrace.h>3131-#include <linux/kallsyms.h>3232-3333-#include <asm/setup.h>3434-#include <asm/fpu.h>3535-#include <asm/system.h>3636-#include <asm/uaccess.h>3737-#include <asm/traps.h>3838-#include <asm/pgalloc.h>3939-#include <asm/machdep.h>4040-#include <asm/siginfo.h>4141-4242-/* assembler routines */4343-asmlinkage void system_call(void);4444-asmlinkage void buserr(void);4545-asmlinkage void trap(void);4646-asmlinkage void nmihandler(void);4747-#ifdef CONFIG_M68KFPU_EMU4848-asmlinkage void fpu_emu(void);4949-#endif5050-5151-e_vector vectors[256];5252-5353-/* nmi handler for the Amiga */5454-asm(".text\n"5555- __ALIGN_STR "\n"5656- "nmihandler: rte");5757-5858-/*5959- * this must be called very early as the kernel might6060- * use some instruction that are emulated on the 0606161- * and so we're prepared for early probe attempts (e.g. nf_init).6262- */6363-void __init base_trap_init(void)6464-{6565- if (MACH_IS_SUN3X) {6666- extern e_vector *sun3x_prom_vbr;6767-6868- __asm__ volatile ("movec %%vbr, %0" : "=r" (sun3x_prom_vbr));6969- }7070-7171- /* setup the exception vector table */7272- __asm__ volatile ("movec %0,%%vbr" : : "r" ((void*)vectors));7373-7474- if (CPU_IS_060) {7575- /* set up ISP entry points */7676- asmlinkage void unimp_vec(void) asm ("_060_isp_unimp");7777-7878- vectors[VEC_UNIMPII] = unimp_vec;7979- }8080-8181- vectors[VEC_BUSERR] = buserr;8282- vectors[VEC_ILLEGAL] = trap;8383- vectors[VEC_SYS] = system_call;8484-}8585-8686-void __init trap_init (void)8787-{8888- int i;8989-9090- for (i = VEC_SPUR; i <= VEC_INT7; i++)9191- vectors[i] = bad_inthandler;9292-9393- for (i = 0; i < VEC_USER; i++)9494- if (!vectors[i])9595- vectors[i] = trap;9696-9797- for (i = VEC_USER; i < 256; i++)9898- vectors[i] = bad_inthandler;9999-100100-#ifdef CONFIG_M68KFPU_EMU101101- if (FPU_IS_EMU)102102- vectors[VEC_LINE11] = fpu_emu;103103-#endif104104-105105- if (CPU_IS_040 && !FPU_IS_EMU) {106106- /* set up FPSP entry points */107107- asmlinkage void dz_vec(void) asm ("dz");108108- asmlinkage void inex_vec(void) asm ("inex");109109- asmlinkage void ovfl_vec(void) asm ("ovfl");110110- asmlinkage void unfl_vec(void) asm ("unfl");111111- asmlinkage void snan_vec(void) asm ("snan");112112- asmlinkage void operr_vec(void) asm ("operr");113113- asmlinkage void bsun_vec(void) asm ("bsun");114114- asmlinkage void fline_vec(void) asm ("fline");115115- asmlinkage void unsupp_vec(void) asm ("unsupp");116116-117117- vectors[VEC_FPDIVZ] = dz_vec;118118- vectors[VEC_FPIR] = inex_vec;119119- vectors[VEC_FPOVER] = ovfl_vec;120120- vectors[VEC_FPUNDER] = unfl_vec;121121- vectors[VEC_FPNAN] = snan_vec;122122- vectors[VEC_FPOE] = operr_vec;123123- vectors[VEC_FPBRUC] = bsun_vec;124124- vectors[VEC_LINE11] = fline_vec;125125- vectors[VEC_FPUNSUP] = unsupp_vec;126126- }127127-128128- if (CPU_IS_060 && !FPU_IS_EMU) {129129- /* set up IFPSP entry points */130130- asmlinkage void snan_vec6(void) asm ("_060_fpsp_snan");131131- asmlinkage void operr_vec6(void) asm ("_060_fpsp_operr");132132- asmlinkage void ovfl_vec6(void) asm ("_060_fpsp_ovfl");133133- asmlinkage void unfl_vec6(void) asm ("_060_fpsp_unfl");134134- asmlinkage void dz_vec6(void) asm ("_060_fpsp_dz");135135- asmlinkage void inex_vec6(void) asm ("_060_fpsp_inex");136136- asmlinkage void fline_vec6(void) asm ("_060_fpsp_fline");137137- asmlinkage void unsupp_vec6(void) asm ("_060_fpsp_unsupp");138138- asmlinkage void effadd_vec6(void) asm ("_060_fpsp_effadd");139139-140140- vectors[VEC_FPNAN] = snan_vec6;141141- vectors[VEC_FPOE] = operr_vec6;142142- vectors[VEC_FPOVER] = ovfl_vec6;143143- vectors[VEC_FPUNDER] = unfl_vec6;144144- vectors[VEC_FPDIVZ] = dz_vec6;145145- vectors[VEC_FPIR] = inex_vec6;146146- vectors[VEC_LINE11] = fline_vec6;147147- vectors[VEC_FPUNSUP] = unsupp_vec6;148148- vectors[VEC_UNIMPEA] = effadd_vec6;149149- }150150-151151- /* if running on an amiga, make the NMI interrupt do nothing */152152- if (MACH_IS_AMIGA) {153153- vectors[VEC_INT7] = nmihandler;154154- }155155-}156156-157157-158158-static const char *vec_names[] = {159159- [VEC_RESETSP] = "RESET SP",160160- [VEC_RESETPC] = "RESET PC",161161- [VEC_BUSERR] = "BUS ERROR",162162- [VEC_ADDRERR] = "ADDRESS ERROR",163163- [VEC_ILLEGAL] = "ILLEGAL INSTRUCTION",164164- [VEC_ZERODIV] = "ZERO DIVIDE",165165- [VEC_CHK] = "CHK",166166- [VEC_TRAP] = "TRAPcc",167167- [VEC_PRIV] = "PRIVILEGE VIOLATION",168168- [VEC_TRACE] = "TRACE",169169- [VEC_LINE10] = "LINE 1010",170170- [VEC_LINE11] = "LINE 1111",171171- [VEC_RESV12] = "UNASSIGNED RESERVED 12",172172- [VEC_COPROC] = "COPROCESSOR PROTOCOL VIOLATION",173173- [VEC_FORMAT] = "FORMAT ERROR",174174- [VEC_UNINT] = "UNINITIALIZED INTERRUPT",175175- [VEC_RESV16] = "UNASSIGNED RESERVED 16",176176- [VEC_RESV17] = "UNASSIGNED RESERVED 17",177177- [VEC_RESV18] = "UNASSIGNED RESERVED 18",178178- [VEC_RESV19] = "UNASSIGNED RESERVED 19",179179- [VEC_RESV20] = "UNASSIGNED RESERVED 20",180180- [VEC_RESV21] = "UNASSIGNED RESERVED 21",181181- [VEC_RESV22] = "UNASSIGNED RESERVED 22",182182- [VEC_RESV23] = "UNASSIGNED RESERVED 23",183183- [VEC_SPUR] = "SPURIOUS INTERRUPT",184184- [VEC_INT1] = "LEVEL 1 INT",185185- [VEC_INT2] = "LEVEL 2 INT",186186- [VEC_INT3] = "LEVEL 3 INT",187187- [VEC_INT4] = "LEVEL 4 INT",188188- [VEC_INT5] = "LEVEL 5 INT",189189- [VEC_INT6] = "LEVEL 6 INT",190190- [VEC_INT7] = "LEVEL 7 INT",191191- [VEC_SYS] = "SYSCALL",192192- [VEC_TRAP1] = "TRAP #1",193193- [VEC_TRAP2] = "TRAP #2",194194- [VEC_TRAP3] = "TRAP #3",195195- [VEC_TRAP4] = "TRAP #4",196196- [VEC_TRAP5] = "TRAP #5",197197- [VEC_TRAP6] = "TRAP #6",198198- [VEC_TRAP7] = "TRAP #7",199199- [VEC_TRAP8] = "TRAP #8",200200- [VEC_TRAP9] = "TRAP #9",201201- [VEC_TRAP10] = "TRAP #10",202202- [VEC_TRAP11] = "TRAP #11",203203- [VEC_TRAP12] = "TRAP #12",204204- [VEC_TRAP13] = "TRAP #13",205205- [VEC_TRAP14] = "TRAP #14",206206- [VEC_TRAP15] = "TRAP #15",207207- [VEC_FPBRUC] = "FPCP BSUN",208208- [VEC_FPIR] = "FPCP INEXACT",209209- [VEC_FPDIVZ] = "FPCP DIV BY 0",210210- [VEC_FPUNDER] = "FPCP UNDERFLOW",211211- [VEC_FPOE] = "FPCP OPERAND ERROR",212212- [VEC_FPOVER] = "FPCP OVERFLOW",213213- [VEC_FPNAN] = "FPCP SNAN",214214- [VEC_FPUNSUP] = "FPCP UNSUPPORTED OPERATION",215215- [VEC_MMUCFG] = "MMU CONFIGURATION ERROR",216216- [VEC_MMUILL] = "MMU ILLEGAL OPERATION ERROR",217217- [VEC_MMUACC] = "MMU ACCESS LEVEL VIOLATION ERROR",218218- [VEC_RESV59] = "UNASSIGNED RESERVED 59",219219- [VEC_UNIMPEA] = "UNASSIGNED RESERVED 60",220220- [VEC_UNIMPII] = "UNASSIGNED RESERVED 61",221221- [VEC_RESV62] = "UNASSIGNED RESERVED 62",222222- [VEC_RESV63] = "UNASSIGNED RESERVED 63",223223-};224224-225225-static const char *space_names[] = {226226- [0] = "Space 0",227227- [USER_DATA] = "User Data",228228- [USER_PROGRAM] = "User Program",229229-#ifndef CONFIG_SUN3230230- [3] = "Space 3",11+#ifdef CONFIG_MMU22+#include "traps_mm.c"2313#else232232- [FC_CONTROL] = "Control",233233-#endif234234- [4] = "Space 4",235235- [SUPER_DATA] = "Super Data",236236- [SUPER_PROGRAM] = "Super Program",237237- [CPU_SPACE] = "CPU"238238-};239239-240240-void die_if_kernel(char *,struct pt_regs *,int);241241-asmlinkage int do_page_fault(struct pt_regs *regs, unsigned long address,242242- unsigned long error_code);243243-int send_fault_sig(struct pt_regs *regs);244244-245245-asmlinkage void trap_c(struct frame *fp);246246-247247-#if defined (CONFIG_M68060)248248-static inline void access_error060 (struct frame *fp)249249-{250250- unsigned long fslw = fp->un.fmt4.pc; /* is really FSLW for access error */251251-252252-#ifdef DEBUG253253- printk("fslw=%#lx, fa=%#lx\n", fslw, fp->un.fmt4.effaddr);254254-#endif255255-256256- if (fslw & MMU060_BPE) {257257- /* branch prediction error -> clear branch cache */258258- __asm__ __volatile__ ("movec %/cacr,%/d0\n\t"259259- "orl #0x00400000,%/d0\n\t"260260- "movec %/d0,%/cacr"261261- : : : "d0" );262262- /* return if there's no other error */263263- if (!(fslw & MMU060_ERR_BITS) && !(fslw & MMU060_SEE))264264- return;265265- }266266-267267- if (fslw & (MMU060_DESC_ERR | MMU060_WP | MMU060_SP)) {268268- unsigned long errorcode;269269- unsigned long addr = fp->un.fmt4.effaddr;270270-271271- if (fslw & MMU060_MA)272272- addr = (addr + PAGE_SIZE - 1) & PAGE_MASK;273273-274274- errorcode = 1;275275- if (fslw & MMU060_DESC_ERR) {276276- __flush_tlb040_one(addr);277277- errorcode = 0;278278- }279279- if (fslw & MMU060_W)280280- errorcode |= 2;281281-#ifdef DEBUG282282- printk("errorcode = %d\n", errorcode );283283-#endif284284- do_page_fault(&fp->ptregs, addr, errorcode);285285- } else if (fslw & (MMU060_SEE)){286286- /* Software Emulation Error.287287- * fault during mem_read/mem_write in ifpsp060/os.S288288- */289289- send_fault_sig(&fp->ptregs);290290- } else if (!(fslw & (MMU060_RE|MMU060_WE)) ||291291- send_fault_sig(&fp->ptregs) > 0) {292292- printk("pc=%#lx, fa=%#lx\n", fp->ptregs.pc, fp->un.fmt4.effaddr);293293- printk( "68060 access error, fslw=%lx\n", fslw );294294- trap_c( fp );295295- }296296-}297297-#endif /* CONFIG_M68060 */298298-299299-#if defined (CONFIG_M68040)300300-static inline unsigned long probe040(int iswrite, unsigned long addr, int wbs)301301-{302302- unsigned long mmusr;303303- mm_segment_t old_fs = get_fs();304304-305305- set_fs(MAKE_MM_SEG(wbs));306306-307307- if (iswrite)308308- asm volatile (".chip 68040; ptestw (%0); .chip 68k" : : "a" (addr));309309- else310310- asm volatile (".chip 68040; ptestr (%0); .chip 68k" : : "a" (addr));311311-312312- asm volatile (".chip 68040; movec %%mmusr,%0; .chip 68k" : "=r" (mmusr));313313-314314- set_fs(old_fs);315315-316316- return mmusr;317317-}318318-319319-static inline int do_040writeback1(unsigned short wbs, unsigned long wba,320320- unsigned long wbd)321321-{322322- int res = 0;323323- mm_segment_t old_fs = get_fs();324324-325325- /* set_fs can not be moved, otherwise put_user() may oops */326326- set_fs(MAKE_MM_SEG(wbs));327327-328328- switch (wbs & WBSIZ_040) {329329- case BA_SIZE_BYTE:330330- res = put_user(wbd & 0xff, (char __user *)wba);331331- break;332332- case BA_SIZE_WORD:333333- res = put_user(wbd & 0xffff, (short __user *)wba);334334- break;335335- case BA_SIZE_LONG:336336- res = put_user(wbd, (int __user *)wba);337337- break;338338- }339339-340340- /* set_fs can not be moved, otherwise put_user() may oops */341341- set_fs(old_fs);342342-343343-344344-#ifdef DEBUG345345- printk("do_040writeback1, res=%d\n",res);346346-#endif347347-348348- return res;349349-}350350-351351-/* after an exception in a writeback the stack frame corresponding352352- * to that exception is discarded, set a few bits in the old frame353353- * to simulate what it should look like354354- */355355-static inline void fix_xframe040(struct frame *fp, unsigned long wba, unsigned short wbs)356356-{357357- fp->un.fmt7.faddr = wba;358358- fp->un.fmt7.ssw = wbs & 0xff;359359- if (wba != current->thread.faddr)360360- fp->un.fmt7.ssw |= MA_040;361361-}362362-363363-static inline void do_040writebacks(struct frame *fp)364364-{365365- int res = 0;366366-#if 0367367- if (fp->un.fmt7.wb1s & WBV_040)368368- printk("access_error040: cannot handle 1st writeback. oops.\n");369369-#endif370370-371371- if ((fp->un.fmt7.wb2s & WBV_040) &&372372- !(fp->un.fmt7.wb2s & WBTT_040)) {373373- res = do_040writeback1(fp->un.fmt7.wb2s, fp->un.fmt7.wb2a,374374- fp->un.fmt7.wb2d);375375- if (res)376376- fix_xframe040(fp, fp->un.fmt7.wb2a, fp->un.fmt7.wb2s);377377- else378378- fp->un.fmt7.wb2s = 0;379379- }380380-381381- /* do the 2nd wb only if the first one was successful (except for a kernel wb) */382382- if (fp->un.fmt7.wb3s & WBV_040 && (!res || fp->un.fmt7.wb3s & 4)) {383383- res = do_040writeback1(fp->un.fmt7.wb3s, fp->un.fmt7.wb3a,384384- fp->un.fmt7.wb3d);385385- if (res)386386- {387387- fix_xframe040(fp, fp->un.fmt7.wb3a, fp->un.fmt7.wb3s);388388-389389- fp->un.fmt7.wb2s = fp->un.fmt7.wb3s;390390- fp->un.fmt7.wb3s &= (~WBV_040);391391- fp->un.fmt7.wb2a = fp->un.fmt7.wb3a;392392- fp->un.fmt7.wb2d = fp->un.fmt7.wb3d;393393- }394394- else395395- fp->un.fmt7.wb3s = 0;396396- }397397-398398- if (res)399399- send_fault_sig(&fp->ptregs);400400-}401401-402402-/*403403- * called from sigreturn(), must ensure userspace code didn't404404- * manipulate exception frame to circumvent protection, then complete405405- * pending writebacks406406- * we just clear TM2 to turn it into a userspace access407407- */408408-asmlinkage void berr_040cleanup(struct frame *fp)409409-{410410- fp->un.fmt7.wb2s &= ~4;411411- fp->un.fmt7.wb3s &= ~4;412412-413413- do_040writebacks(fp);414414-}415415-416416-static inline void access_error040(struct frame *fp)417417-{418418- unsigned short ssw = fp->un.fmt7.ssw;419419- unsigned long mmusr;420420-421421-#ifdef DEBUG422422- printk("ssw=%#x, fa=%#lx\n", ssw, fp->un.fmt7.faddr);423423- printk("wb1s=%#x, wb2s=%#x, wb3s=%#x\n", fp->un.fmt7.wb1s,424424- fp->un.fmt7.wb2s, fp->un.fmt7.wb3s);425425- printk ("wb2a=%lx, wb3a=%lx, wb2d=%lx, wb3d=%lx\n",426426- fp->un.fmt7.wb2a, fp->un.fmt7.wb3a,427427- fp->un.fmt7.wb2d, fp->un.fmt7.wb3d);428428-#endif429429-430430- if (ssw & ATC_040) {431431- unsigned long addr = fp->un.fmt7.faddr;432432- unsigned long errorcode;433433-434434- /*435435- * The MMU status has to be determined AFTER the address436436- * has been corrected if there was a misaligned access (MA).437437- */438438- if (ssw & MA_040)439439- addr = (addr + 7) & -8;440440-441441- /* MMU error, get the MMUSR info for this access */442442- mmusr = probe040(!(ssw & RW_040), addr, ssw);443443-#ifdef DEBUG444444- printk("mmusr = %lx\n", mmusr);445445-#endif446446- errorcode = 1;447447- if (!(mmusr & MMU_R_040)) {448448- /* clear the invalid atc entry */449449- __flush_tlb040_one(addr);450450- errorcode = 0;451451- }452452-453453- /* despite what documentation seems to say, RMW454454- * accesses have always both the LK and RW bits set */455455- if (!(ssw & RW_040) || (ssw & LK_040))456456- errorcode |= 2;457457-458458- if (do_page_fault(&fp->ptregs, addr, errorcode)) {459459-#ifdef DEBUG460460- printk("do_page_fault() !=0\n");461461-#endif462462- if (user_mode(&fp->ptregs)){463463- /* delay writebacks after signal delivery */464464-#ifdef DEBUG465465- printk(".. was usermode - return\n");466466-#endif467467- return;468468- }469469- /* disable writeback into user space from kernel470470- * (if do_page_fault didn't fix the mapping,471471- * the writeback won't do good)472472- */473473-disable_wb:474474-#ifdef DEBUG475475- printk(".. disabling wb2\n");476476-#endif477477- if (fp->un.fmt7.wb2a == fp->un.fmt7.faddr)478478- fp->un.fmt7.wb2s &= ~WBV_040;479479- if (fp->un.fmt7.wb3a == fp->un.fmt7.faddr)480480- fp->un.fmt7.wb3s &= ~WBV_040;481481- }482482- } else {483483- /* In case of a bus error we either kill the process or expect484484- * the kernel to catch the fault, which then is also responsible485485- * for cleaning up the mess.486486- */487487- current->thread.signo = SIGBUS;488488- current->thread.faddr = fp->un.fmt7.faddr;489489- if (send_fault_sig(&fp->ptregs) >= 0)490490- printk("68040 bus error (ssw=%x, faddr=%lx)\n", ssw,491491- fp->un.fmt7.faddr);492492- goto disable_wb;493493- }494494-495495- do_040writebacks(fp);496496-}497497-#endif /* CONFIG_M68040 */498498-499499-#if defined(CONFIG_SUN3)500500-#include <asm/sun3mmu.h>501501-502502-extern int mmu_emu_handle_fault (unsigned long, int, int);503503-504504-/* sun3 version of bus_error030 */505505-506506-static inline void bus_error030 (struct frame *fp)507507-{508508- unsigned char buserr_type = sun3_get_buserr ();509509- unsigned long addr, errorcode;510510- unsigned short ssw = fp->un.fmtb.ssw;511511- extern unsigned long _sun3_map_test_start, _sun3_map_test_end;512512-513513-#ifdef DEBUG514514- if (ssw & (FC | FB))515515- printk ("Instruction fault at %#010lx\n",516516- ssw & FC ?517517- fp->ptregs.format == 0xa ? fp->ptregs.pc + 2 : fp->un.fmtb.baddr - 2518518- :519519- fp->ptregs.format == 0xa ? fp->ptregs.pc + 4 : fp->un.fmtb.baddr);520520- if (ssw & DF)521521- printk ("Data %s fault at %#010lx in %s (pc=%#lx)\n",522522- ssw & RW ? "read" : "write",523523- fp->un.fmtb.daddr,524524- space_names[ssw & DFC], fp->ptregs.pc);525525-#endif526526-527527- /*528528- * Check if this page should be demand-mapped. This needs to go before529529- * the testing for a bad kernel-space access (demand-mapping applies530530- * to kernel accesses too).531531- */532532-533533- if ((ssw & DF)534534- && (buserr_type & (SUN3_BUSERR_PROTERR | SUN3_BUSERR_INVALID))) {535535- if (mmu_emu_handle_fault (fp->un.fmtb.daddr, ssw & RW, 0))536536- return;537537- }538538-539539- /* Check for kernel-space pagefault (BAD). */540540- if (fp->ptregs.sr & PS_S) {541541- /* kernel fault must be a data fault to user space */542542- if (! ((ssw & DF) && ((ssw & DFC) == USER_DATA))) {543543- // try checking the kernel mappings before surrender544544- if (mmu_emu_handle_fault (fp->un.fmtb.daddr, ssw & RW, 1))545545- return;546546- /* instruction fault or kernel data fault! */547547- if (ssw & (FC | FB))548548- printk ("Instruction fault at %#010lx\n",549549- fp->ptregs.pc);550550- if (ssw & DF) {551551- /* was this fault incurred testing bus mappings? */552552- if((fp->ptregs.pc >= (unsigned long)&_sun3_map_test_start) &&553553- (fp->ptregs.pc <= (unsigned long)&_sun3_map_test_end)) {554554- send_fault_sig(&fp->ptregs);555555- return;556556- }557557-558558- printk ("Data %s fault at %#010lx in %s (pc=%#lx)\n",559559- ssw & RW ? "read" : "write",560560- fp->un.fmtb.daddr,561561- space_names[ssw & DFC], fp->ptregs.pc);562562- }563563- printk ("BAD KERNEL BUSERR\n");564564-565565- die_if_kernel("Oops", &fp->ptregs,0);566566- force_sig(SIGKILL, current);567567- return;568568- }569569- } else {570570- /* user fault */571571- if (!(ssw & (FC | FB)) && !(ssw & DF))572572- /* not an instruction fault or data fault! BAD */573573- panic ("USER BUSERR w/o instruction or data fault");574574- }575575-576576-577577- /* First handle the data fault, if any. */578578- if (ssw & DF) {579579- addr = fp->un.fmtb.daddr;580580-581581-// errorcode bit 0: 0 -> no page 1 -> protection fault582582-// errorcode bit 1: 0 -> read fault 1 -> write fault583583-584584-// (buserr_type & SUN3_BUSERR_PROTERR) -> protection fault585585-// (buserr_type & SUN3_BUSERR_INVALID) -> invalid page fault586586-587587- if (buserr_type & SUN3_BUSERR_PROTERR)588588- errorcode = 0x01;589589- else if (buserr_type & SUN3_BUSERR_INVALID)590590- errorcode = 0x00;591591- else {592592-#ifdef DEBUG593593- printk ("*** unexpected busfault type=%#04x\n", buserr_type);594594- printk ("invalid %s access at %#lx from pc %#lx\n",595595- !(ssw & RW) ? "write" : "read", addr,596596- fp->ptregs.pc);597597-#endif598598- die_if_kernel ("Oops", &fp->ptregs, buserr_type);599599- force_sig (SIGBUS, current);600600- return;601601- }602602-603603-//todo: wtf is RM bit? --m604604- if (!(ssw & RW) || ssw & RM)605605- errorcode |= 0x02;606606-607607- /* Handle page fault. */608608- do_page_fault (&fp->ptregs, addr, errorcode);609609-610610- /* Retry the data fault now. */611611- return;612612- }613613-614614- /* Now handle the instruction fault. */615615-616616- /* Get the fault address. */617617- if (fp->ptregs.format == 0xA)618618- addr = fp->ptregs.pc + 4;619619- else620620- addr = fp->un.fmtb.baddr;621621- if (ssw & FC)622622- addr -= 2;623623-624624- if (buserr_type & SUN3_BUSERR_INVALID) {625625- if (!mmu_emu_handle_fault (fp->un.fmtb.daddr, 1, 0))626626- do_page_fault (&fp->ptregs, addr, 0);627627- } else {628628-#ifdef DEBUG629629- printk ("protection fault on insn access (segv).\n");630630-#endif631631- force_sig (SIGSEGV, current);632632- }633633-}634634-#else635635-#if defined(CPU_M68020_OR_M68030)636636-static inline void bus_error030 (struct frame *fp)637637-{638638- volatile unsigned short temp;639639- unsigned short mmusr;640640- unsigned long addr, errorcode;641641- unsigned short ssw = fp->un.fmtb.ssw;642642-#ifdef DEBUG643643- unsigned long desc;644644-645645- printk ("pid = %x ", current->pid);646646- printk ("SSW=%#06x ", ssw);647647-648648- if (ssw & (FC | FB))649649- printk ("Instruction fault at %#010lx\n",650650- ssw & FC ?651651- fp->ptregs.format == 0xa ? fp->ptregs.pc + 2 : fp->un.fmtb.baddr - 2652652- :653653- fp->ptregs.format == 0xa ? fp->ptregs.pc + 4 : fp->un.fmtb.baddr);654654- if (ssw & DF)655655- printk ("Data %s fault at %#010lx in %s (pc=%#lx)\n",656656- ssw & RW ? "read" : "write",657657- fp->un.fmtb.daddr,658658- space_names[ssw & DFC], fp->ptregs.pc);659659-#endif660660-661661- /* ++andreas: If a data fault and an instruction fault happen662662- at the same time map in both pages. */663663-664664- /* First handle the data fault, if any. */665665- if (ssw & DF) {666666- addr = fp->un.fmtb.daddr;667667-668668-#ifdef DEBUG669669- asm volatile ("ptestr %3,%2@,#7,%0\n\t"670670- "pmove %%psr,%1@"671671- : "=a&" (desc)672672- : "a" (&temp), "a" (addr), "d" (ssw));673673-#else674674- asm volatile ("ptestr %2,%1@,#7\n\t"675675- "pmove %%psr,%0@"676676- : : "a" (&temp), "a" (addr), "d" (ssw));677677-#endif678678- mmusr = temp;679679-680680-#ifdef DEBUG681681- printk("mmusr is %#x for addr %#lx in task %p\n",682682- mmusr, addr, current);683683- printk("descriptor address is %#lx, contents %#lx\n",684684- __va(desc), *(unsigned long *)__va(desc));685685-#endif686686-687687- errorcode = (mmusr & MMU_I) ? 0 : 1;688688- if (!(ssw & RW) || (ssw & RM))689689- errorcode |= 2;690690-691691- if (mmusr & (MMU_I | MMU_WP)) {692692- if (ssw & 4) {693693- printk("Data %s fault at %#010lx in %s (pc=%#lx)\n",694694- ssw & RW ? "read" : "write",695695- fp->un.fmtb.daddr,696696- space_names[ssw & DFC], fp->ptregs.pc);697697- goto buserr;698698- }699699- /* Don't try to do anything further if an exception was700700- handled. */701701- if (do_page_fault (&fp->ptregs, addr, errorcode) < 0)702702- return;703703- } else if (!(mmusr & MMU_I)) {704704- /* probably a 020 cas fault */705705- if (!(ssw & RM) && send_fault_sig(&fp->ptregs) > 0)706706- printk("unexpected bus error (%#x,%#x)\n", ssw, mmusr);707707- } else if (mmusr & (MMU_B|MMU_L|MMU_S)) {708708- printk("invalid %s access at %#lx from pc %#lx\n",709709- !(ssw & RW) ? "write" : "read", addr,710710- fp->ptregs.pc);711711- die_if_kernel("Oops",&fp->ptregs,mmusr);712712- force_sig(SIGSEGV, current);713713- return;714714- } else {715715-#if 0716716- static volatile long tlong;717717-#endif718718-719719- printk("weird %s access at %#lx from pc %#lx (ssw is %#x)\n",720720- !(ssw & RW) ? "write" : "read", addr,721721- fp->ptregs.pc, ssw);722722- asm volatile ("ptestr #1,%1@,#0\n\t"723723- "pmove %%psr,%0@"724724- : /* no outputs */725725- : "a" (&temp), "a" (addr));726726- mmusr = temp;727727-728728- printk ("level 0 mmusr is %#x\n", mmusr);729729-#if 0730730- asm volatile ("pmove %%tt0,%0@"731731- : /* no outputs */732732- : "a" (&tlong));733733- printk("tt0 is %#lx, ", tlong);734734- asm volatile ("pmove %%tt1,%0@"735735- : /* no outputs */736736- : "a" (&tlong));737737- printk("tt1 is %#lx\n", tlong);738738-#endif739739-#ifdef DEBUG740740- printk("Unknown SIGSEGV - 1\n");741741-#endif742742- die_if_kernel("Oops",&fp->ptregs,mmusr);743743- force_sig(SIGSEGV, current);744744- return;745745- }746746-747747- /* setup an ATC entry for the access about to be retried */748748- if (!(ssw & RW) || (ssw & RM))749749- asm volatile ("ploadw %1,%0@" : /* no outputs */750750- : "a" (addr), "d" (ssw));751751- else752752- asm volatile ("ploadr %1,%0@" : /* no outputs */753753- : "a" (addr), "d" (ssw));754754- }755755-756756- /* Now handle the instruction fault. */757757-758758- if (!(ssw & (FC|FB)))759759- return;760760-761761- if (fp->ptregs.sr & PS_S) {762762- printk("Instruction fault at %#010lx\n",763763- fp->ptregs.pc);764764- buserr:765765- printk ("BAD KERNEL BUSERR\n");766766- die_if_kernel("Oops",&fp->ptregs,0);767767- force_sig(SIGKILL, current);768768- return;769769- }770770-771771- /* get the fault address */772772- if (fp->ptregs.format == 10)773773- addr = fp->ptregs.pc + 4;774774- else775775- addr = fp->un.fmtb.baddr;776776- if (ssw & FC)777777- addr -= 2;778778-779779- if ((ssw & DF) && ((addr ^ fp->un.fmtb.daddr) & PAGE_MASK) == 0)780780- /* Insn fault on same page as data fault. But we781781- should still create the ATC entry. */782782- goto create_atc_entry;783783-784784-#ifdef DEBUG785785- asm volatile ("ptestr #1,%2@,#7,%0\n\t"786786- "pmove %%psr,%1@"787787- : "=a&" (desc)788788- : "a" (&temp), "a" (addr));789789-#else790790- asm volatile ("ptestr #1,%1@,#7\n\t"791791- "pmove %%psr,%0@"792792- : : "a" (&temp), "a" (addr));793793-#endif794794- mmusr = temp;795795-796796-#ifdef DEBUG797797- printk ("mmusr is %#x for addr %#lx in task %p\n",798798- mmusr, addr, current);799799- printk ("descriptor address is %#lx, contents %#lx\n",800800- __va(desc), *(unsigned long *)__va(desc));801801-#endif802802-803803- if (mmusr & MMU_I)804804- do_page_fault (&fp->ptregs, addr, 0);805805- else if (mmusr & (MMU_B|MMU_L|MMU_S)) {806806- printk ("invalid insn access at %#lx from pc %#lx\n",807807- addr, fp->ptregs.pc);808808-#ifdef DEBUG809809- printk("Unknown SIGSEGV - 2\n");810810-#endif811811- die_if_kernel("Oops",&fp->ptregs,mmusr);812812- force_sig(SIGSEGV, current);813813- return;814814- }815815-816816-create_atc_entry:817817- /* setup an ATC entry for the access about to be retried */818818- asm volatile ("ploadr #2,%0@" : /* no outputs */819819- : "a" (addr));820820-}821821-#endif /* CPU_M68020_OR_M68030 */822822-#endif /* !CONFIG_SUN3 */823823-824824-asmlinkage void buserr_c(struct frame *fp)825825-{826826- /* Only set esp0 if coming from user mode */827827- if (user_mode(&fp->ptregs))828828- current->thread.esp0 = (unsigned long) fp;829829-830830-#ifdef DEBUG831831- printk ("*** Bus Error *** Format is %x\n", fp->ptregs.format);832832-#endif833833-834834- switch (fp->ptregs.format) {835835-#if defined (CONFIG_M68060)836836- case 4: /* 68060 access error */837837- access_error060 (fp);838838- break;839839-#endif840840-#if defined (CONFIG_M68040)841841- case 0x7: /* 68040 access error */842842- access_error040 (fp);843843- break;844844-#endif845845-#if defined (CPU_M68020_OR_M68030)846846- case 0xa:847847- case 0xb:848848- bus_error030 (fp);849849- break;850850-#endif851851- default:852852- die_if_kernel("bad frame format",&fp->ptregs,0);853853-#ifdef DEBUG854854- printk("Unknown SIGSEGV - 4\n");855855-#endif856856- force_sig(SIGSEGV, current);857857- }858858-}859859-860860-861861-static int kstack_depth_to_print = 48;862862-863863-void show_trace(unsigned long *stack)864864-{865865- unsigned long *endstack;866866- unsigned long addr;867867- int i;868868-869869- printk("Call Trace:");870870- addr = (unsigned long)stack + THREAD_SIZE - 1;871871- endstack = (unsigned long *)(addr & -THREAD_SIZE);872872- i = 0;873873- while (stack + 1 <= endstack) {874874- addr = *stack++;875875- /*876876- * If the address is either in the text segment of the877877- * kernel, or in the region which contains vmalloc'ed878878- * memory, it *may* be the address of a calling879879- * routine; if so, print it so that someone tracing880880- * down the cause of the crash will be able to figure881881- * out the call path that was taken.882882- */883883- if (__kernel_text_address(addr)) {884884-#ifndef CONFIG_KALLSYMS885885- if (i % 5 == 0)886886- printk("\n ");887887-#endif888888- printk(" [<%08lx>] %pS\n", addr, (void *)addr);889889- i++;890890- }891891- }892892- printk("\n");893893-}894894-895895-void show_registers(struct pt_regs *regs)896896-{897897- struct frame *fp = (struct frame *)regs;898898- mm_segment_t old_fs = get_fs();899899- u16 c, *cp;900900- unsigned long addr;901901- int i;902902-903903- print_modules();904904- printk("PC: [<%08lx>] %pS\n", regs->pc, (void *)regs->pc);905905- printk("SR: %04x SP: %p a2: %08lx\n", regs->sr, regs, regs->a2);906906- printk("d0: %08lx d1: %08lx d2: %08lx d3: %08lx\n",907907- regs->d0, regs->d1, regs->d2, regs->d3);908908- printk("d4: %08lx d5: %08lx a0: %08lx a1: %08lx\n",909909- regs->d4, regs->d5, regs->a0, regs->a1);910910-911911- printk("Process %s (pid: %d, task=%p)\n",912912- current->comm, task_pid_nr(current), current);913913- addr = (unsigned long)&fp->un;914914- printk("Frame format=%X ", regs->format);915915- switch (regs->format) {916916- case 0x2:917917- printk("instr addr=%08lx\n", fp->un.fmt2.iaddr);918918- addr += sizeof(fp->un.fmt2);919919- break;920920- case 0x3:921921- printk("eff addr=%08lx\n", fp->un.fmt3.effaddr);922922- addr += sizeof(fp->un.fmt3);923923- break;924924- case 0x4:925925- printk((CPU_IS_060 ? "fault addr=%08lx fslw=%08lx\n"926926- : "eff addr=%08lx pc=%08lx\n"),927927- fp->un.fmt4.effaddr, fp->un.fmt4.pc);928928- addr += sizeof(fp->un.fmt4);929929- break;930930- case 0x7:931931- printk("eff addr=%08lx ssw=%04x faddr=%08lx\n",932932- fp->un.fmt7.effaddr, fp->un.fmt7.ssw, fp->un.fmt7.faddr);933933- printk("wb 1 stat/addr/data: %04x %08lx %08lx\n",934934- fp->un.fmt7.wb1s, fp->un.fmt7.wb1a, fp->un.fmt7.wb1dpd0);935935- printk("wb 2 stat/addr/data: %04x %08lx %08lx\n",936936- fp->un.fmt7.wb2s, fp->un.fmt7.wb2a, fp->un.fmt7.wb2d);937937- printk("wb 3 stat/addr/data: %04x %08lx %08lx\n",938938- fp->un.fmt7.wb3s, fp->un.fmt7.wb3a, fp->un.fmt7.wb3d);939939- printk("push data: %08lx %08lx %08lx %08lx\n",940940- fp->un.fmt7.wb1dpd0, fp->un.fmt7.pd1, fp->un.fmt7.pd2,941941- fp->un.fmt7.pd3);942942- addr += sizeof(fp->un.fmt7);943943- break;944944- case 0x9:945945- printk("instr addr=%08lx\n", fp->un.fmt9.iaddr);946946- addr += sizeof(fp->un.fmt9);947947- break;948948- case 0xa:949949- printk("ssw=%04x isc=%04x isb=%04x daddr=%08lx dobuf=%08lx\n",950950- fp->un.fmta.ssw, fp->un.fmta.isc, fp->un.fmta.isb,951951- fp->un.fmta.daddr, fp->un.fmta.dobuf);952952- addr += sizeof(fp->un.fmta);953953- break;954954- case 0xb:955955- printk("ssw=%04x isc=%04x isb=%04x daddr=%08lx dobuf=%08lx\n",956956- fp->un.fmtb.ssw, fp->un.fmtb.isc, fp->un.fmtb.isb,957957- fp->un.fmtb.daddr, fp->un.fmtb.dobuf);958958- printk("baddr=%08lx dibuf=%08lx ver=%x\n",959959- fp->un.fmtb.baddr, fp->un.fmtb.dibuf, fp->un.fmtb.ver);960960- addr += sizeof(fp->un.fmtb);961961- break;962962- default:963963- printk("\n");964964- }965965- show_stack(NULL, (unsigned long *)addr);966966-967967- printk("Code:");968968- set_fs(KERNEL_DS);969969- cp = (u16 *)regs->pc;970970- for (i = -8; i < 16; i++) {971971- if (get_user(c, cp + i) && i >= 0) {972972- printk(" Bad PC value.");973973- break;974974- }975975- printk(i ? " %04x" : " <%04x>", c);976976- }977977- set_fs(old_fs);978978- printk ("\n");979979-}980980-981981-void show_stack(struct task_struct *task, unsigned long *stack)982982-{983983- unsigned long *p;984984- unsigned long *endstack;985985- int i;986986-987987- if (!stack) {988988- if (task)989989- stack = (unsigned long *)task->thread.esp0;990990- else991991- stack = (unsigned long *)&stack;992992- }993993- endstack = (unsigned long *)(((unsigned long)stack + THREAD_SIZE - 1) & -THREAD_SIZE);994994-995995- printk("Stack from %08lx:", (unsigned long)stack);996996- p = stack;997997- for (i = 0; i < kstack_depth_to_print; i++) {998998- if (p + 1 > endstack)999999- break;10001000- if (i % 8 == 0)10011001- printk("\n ");10021002- printk(" %08lx", *p++);10031003- }10041004- printk("\n");10051005- show_trace(stack);10061006-}10071007-10081008-/*10091009- * The architecture-independent backtrace generator10101010- */10111011-void dump_stack(void)10121012-{10131013- unsigned long stack;10141014-10151015- show_trace(&stack);10161016-}10171017-10181018-EXPORT_SYMBOL(dump_stack);10191019-10201020-void bad_super_trap (struct frame *fp)10211021-{10221022- console_verbose();10231023- if (fp->ptregs.vector < 4 * ARRAY_SIZE(vec_names))10241024- printk ("*** %s *** FORMAT=%X\n",10251025- vec_names[(fp->ptregs.vector) >> 2],10261026- fp->ptregs.format);10271027- else10281028- printk ("*** Exception %d *** FORMAT=%X\n",10291029- (fp->ptregs.vector) >> 2,10301030- fp->ptregs.format);10311031- if (fp->ptregs.vector >> 2 == VEC_ADDRERR && CPU_IS_020_OR_030) {10321032- unsigned short ssw = fp->un.fmtb.ssw;10331033-10341034- printk ("SSW=%#06x ", ssw);10351035-10361036- if (ssw & RC)10371037- printk ("Pipe stage C instruction fault at %#010lx\n",10381038- (fp->ptregs.format) == 0xA ?10391039- fp->ptregs.pc + 2 : fp->un.fmtb.baddr - 2);10401040- if (ssw & RB)10411041- printk ("Pipe stage B instruction fault at %#010lx\n",10421042- (fp->ptregs.format) == 0xA ?10431043- fp->ptregs.pc + 4 : fp->un.fmtb.baddr);10441044- if (ssw & DF)10451045- printk ("Data %s fault at %#010lx in %s (pc=%#lx)\n",10461046- ssw & RW ? "read" : "write",10471047- fp->un.fmtb.daddr, space_names[ssw & DFC],10481048- fp->ptregs.pc);10491049- }10501050- printk ("Current process id is %d\n", task_pid_nr(current));10511051- die_if_kernel("BAD KERNEL TRAP", &fp->ptregs, 0);10521052-}10531053-10541054-asmlinkage void trap_c(struct frame *fp)10551055-{10561056- int sig;10571057- siginfo_t info;10581058-10591059- if (fp->ptregs.sr & PS_S) {10601060- if (fp->ptregs.vector == VEC_TRACE << 2) {10611061- /* traced a trapping instruction on a 68020/30,10621062- * real exception will be executed afterwards.10631063- */10641064- } else if (!handle_kernel_fault(&fp->ptregs))10651065- bad_super_trap(fp);10661066- return;10671067- }10681068-10691069- /* send the appropriate signal to the user program */10701070- switch ((fp->ptregs.vector) >> 2) {10711071- case VEC_ADDRERR:10721072- info.si_code = BUS_ADRALN;10731073- sig = SIGBUS;10741074- break;10751075- case VEC_ILLEGAL:10761076- case VEC_LINE10:10771077- case VEC_LINE11:10781078- info.si_code = ILL_ILLOPC;10791079- sig = SIGILL;10801080- break;10811081- case VEC_PRIV:10821082- info.si_code = ILL_PRVOPC;10831083- sig = SIGILL;10841084- break;10851085- case VEC_COPROC:10861086- info.si_code = ILL_COPROC;10871087- sig = SIGILL;10881088- break;10891089- case VEC_TRAP1:10901090- case VEC_TRAP2:10911091- case VEC_TRAP3:10921092- case VEC_TRAP4:10931093- case VEC_TRAP5:10941094- case VEC_TRAP6:10951095- case VEC_TRAP7:10961096- case VEC_TRAP8:10971097- case VEC_TRAP9:10981098- case VEC_TRAP10:10991099- case VEC_TRAP11:11001100- case VEC_TRAP12:11011101- case VEC_TRAP13:11021102- case VEC_TRAP14:11031103- info.si_code = ILL_ILLTRP;11041104- sig = SIGILL;11051105- break;11061106- case VEC_FPBRUC:11071107- case VEC_FPOE:11081108- case VEC_FPNAN:11091109- info.si_code = FPE_FLTINV;11101110- sig = SIGFPE;11111111- break;11121112- case VEC_FPIR:11131113- info.si_code = FPE_FLTRES;11141114- sig = SIGFPE;11151115- break;11161116- case VEC_FPDIVZ:11171117- info.si_code = FPE_FLTDIV;11181118- sig = SIGFPE;11191119- break;11201120- case VEC_FPUNDER:11211121- info.si_code = FPE_FLTUND;11221122- sig = SIGFPE;11231123- break;11241124- case VEC_FPOVER:11251125- info.si_code = FPE_FLTOVF;11261126- sig = SIGFPE;11271127- break;11281128- case VEC_ZERODIV:11291129- info.si_code = FPE_INTDIV;11301130- sig = SIGFPE;11311131- break;11321132- case VEC_CHK:11331133- case VEC_TRAP:11341134- info.si_code = FPE_INTOVF;11351135- sig = SIGFPE;11361136- break;11371137- case VEC_TRACE: /* ptrace single step */11381138- info.si_code = TRAP_TRACE;11391139- sig = SIGTRAP;11401140- break;11411141- case VEC_TRAP15: /* breakpoint */11421142- info.si_code = TRAP_BRKPT;11431143- sig = SIGTRAP;11441144- break;11451145- default:11461146- info.si_code = ILL_ILLOPC;11471147- sig = SIGILL;11481148- break;11491149- }11501150- info.si_signo = sig;11511151- info.si_errno = 0;11521152- switch (fp->ptregs.format) {11531153- default:11541154- info.si_addr = (void *) fp->ptregs.pc;11551155- break;11561156- case 2:11571157- info.si_addr = (void *) fp->un.fmt2.iaddr;11581158- break;11591159- case 7:11601160- info.si_addr = (void *) fp->un.fmt7.effaddr;11611161- break;11621162- case 9:11631163- info.si_addr = (void *) fp->un.fmt9.iaddr;11641164- break;11651165- case 10:11661166- info.si_addr = (void *) fp->un.fmta.daddr;11671167- break;11681168- case 11:11691169- info.si_addr = (void *) fp->un.fmtb.daddr;11701170- break;11711171- }11721172- force_sig_info (sig, &info, current);11731173-}11741174-11751175-void die_if_kernel (char *str, struct pt_regs *fp, int nr)11761176-{11771177- if (!(fp->sr & PS_S))11781178- return;11791179-11801180- console_verbose();11811181- printk("%s: %08x\n",str,nr);11821182- show_registers(fp);11831183- add_taint(TAINT_DIE);11841184- do_exit(SIGSEGV);11851185-}11861186-11871187-/*11881188- * This function is called if an error occur while accessing11891189- * user-space from the fpsp040 code.11901190- */11911191-asmlinkage void fpsp040_die(void)11921192-{11931193- do_exit(SIGSEGV);11941194-}11951195-11961196-#ifdef CONFIG_M68KFPU_EMU11971197-asmlinkage void fpemu_signal(int signal, int code, void *addr)11981198-{11991199- siginfo_t info;12001200-12011201- info.si_signo = signal;12021202- info.si_errno = 0;12031203- info.si_code = code;12041204- info.si_addr = addr;12051205- force_sig_info(signal, &info, current);12061206-}44+#include "traps_no.c"12075#endif
+1207
arch/m68k/kernel/traps_mm.c
···11+/*22+ * linux/arch/m68k/kernel/traps.c33+ *44+ * Copyright (C) 1993, 1994 by Hamish Macdonald55+ *66+ * 68040 fixes by Michael Rausch77+ * 68040 fixes by Martin Apel88+ * 68040 fixes and writeback by Richard Zidlicky99+ * 68060 fixes by Roman Hodek1010+ * 68060 fixes by Jesper Skov1111+ *1212+ * This file is subject to the terms and conditions of the GNU General Public1313+ * License. See the file COPYING in the main directory of this archive1414+ * for more details.1515+ */1616+1717+/*1818+ * Sets up all exception vectors1919+ */2020+2121+#include <linux/sched.h>2222+#include <linux/signal.h>2323+#include <linux/kernel.h>2424+#include <linux/mm.h>2525+#include <linux/module.h>2626+#include <linux/user.h>2727+#include <linux/string.h>2828+#include <linux/linkage.h>2929+#include <linux/init.h>3030+#include <linux/ptrace.h>3131+#include <linux/kallsyms.h>3232+3333+#include <asm/setup.h>3434+#include <asm/fpu.h>3535+#include <asm/system.h>3636+#include <asm/uaccess.h>3737+#include <asm/traps.h>3838+#include <asm/pgalloc.h>3939+#include <asm/machdep.h>4040+#include <asm/siginfo.h>4141+4242+/* assembler routines */4343+asmlinkage void system_call(void);4444+asmlinkage void buserr(void);4545+asmlinkage void trap(void);4646+asmlinkage void nmihandler(void);4747+#ifdef CONFIG_M68KFPU_EMU4848+asmlinkage void fpu_emu(void);4949+#endif5050+5151+e_vector vectors[256];5252+5353+/* nmi handler for the Amiga */5454+asm(".text\n"5555+ __ALIGN_STR "\n"5656+ "nmihandler: rte");5757+5858+/*5959+ * this must be called very early as the kernel might6060+ * use some instruction that are emulated on the 0606161+ * and so we're prepared for early probe attempts (e.g. nf_init).6262+ */6363+void __init base_trap_init(void)6464+{6565+ if (MACH_IS_SUN3X) {6666+ extern e_vector *sun3x_prom_vbr;6767+6868+ __asm__ volatile ("movec %%vbr, %0" : "=r" (sun3x_prom_vbr));6969+ }7070+7171+ /* setup the exception vector table */7272+ __asm__ volatile ("movec %0,%%vbr" : : "r" ((void*)vectors));7373+7474+ if (CPU_IS_060) {7575+ /* set up ISP entry points */7676+ asmlinkage void unimp_vec(void) asm ("_060_isp_unimp");7777+7878+ vectors[VEC_UNIMPII] = unimp_vec;7979+ }8080+8181+ vectors[VEC_BUSERR] = buserr;8282+ vectors[VEC_ILLEGAL] = trap;8383+ vectors[VEC_SYS] = system_call;8484+}8585+8686+void __init trap_init (void)8787+{8888+ int i;8989+9090+ for (i = VEC_SPUR; i <= VEC_INT7; i++)9191+ vectors[i] = bad_inthandler;9292+9393+ for (i = 0; i < VEC_USER; i++)9494+ if (!vectors[i])9595+ vectors[i] = trap;9696+9797+ for (i = VEC_USER; i < 256; i++)9898+ vectors[i] = bad_inthandler;9999+100100+#ifdef CONFIG_M68KFPU_EMU101101+ if (FPU_IS_EMU)102102+ vectors[VEC_LINE11] = fpu_emu;103103+#endif104104+105105+ if (CPU_IS_040 && !FPU_IS_EMU) {106106+ /* set up FPSP entry points */107107+ asmlinkage void dz_vec(void) asm ("dz");108108+ asmlinkage void inex_vec(void) asm ("inex");109109+ asmlinkage void ovfl_vec(void) asm ("ovfl");110110+ asmlinkage void unfl_vec(void) asm ("unfl");111111+ asmlinkage void snan_vec(void) asm ("snan");112112+ asmlinkage void operr_vec(void) asm ("operr");113113+ asmlinkage void bsun_vec(void) asm ("bsun");114114+ asmlinkage void fline_vec(void) asm ("fline");115115+ asmlinkage void unsupp_vec(void) asm ("unsupp");116116+117117+ vectors[VEC_FPDIVZ] = dz_vec;118118+ vectors[VEC_FPIR] = inex_vec;119119+ vectors[VEC_FPOVER] = ovfl_vec;120120+ vectors[VEC_FPUNDER] = unfl_vec;121121+ vectors[VEC_FPNAN] = snan_vec;122122+ vectors[VEC_FPOE] = operr_vec;123123+ vectors[VEC_FPBRUC] = bsun_vec;124124+ vectors[VEC_LINE11] = fline_vec;125125+ vectors[VEC_FPUNSUP] = unsupp_vec;126126+ }127127+128128+ if (CPU_IS_060 && !FPU_IS_EMU) {129129+ /* set up IFPSP entry points */130130+ asmlinkage void snan_vec6(void) asm ("_060_fpsp_snan");131131+ asmlinkage void operr_vec6(void) asm ("_060_fpsp_operr");132132+ asmlinkage void ovfl_vec6(void) asm ("_060_fpsp_ovfl");133133+ asmlinkage void unfl_vec6(void) asm ("_060_fpsp_unfl");134134+ asmlinkage void dz_vec6(void) asm ("_060_fpsp_dz");135135+ asmlinkage void inex_vec6(void) asm ("_060_fpsp_inex");136136+ asmlinkage void fline_vec6(void) asm ("_060_fpsp_fline");137137+ asmlinkage void unsupp_vec6(void) asm ("_060_fpsp_unsupp");138138+ asmlinkage void effadd_vec6(void) asm ("_060_fpsp_effadd");139139+140140+ vectors[VEC_FPNAN] = snan_vec6;141141+ vectors[VEC_FPOE] = operr_vec6;142142+ vectors[VEC_FPOVER] = ovfl_vec6;143143+ vectors[VEC_FPUNDER] = unfl_vec6;144144+ vectors[VEC_FPDIVZ] = dz_vec6;145145+ vectors[VEC_FPIR] = inex_vec6;146146+ vectors[VEC_LINE11] = fline_vec6;147147+ vectors[VEC_FPUNSUP] = unsupp_vec6;148148+ vectors[VEC_UNIMPEA] = effadd_vec6;149149+ }150150+151151+ /* if running on an amiga, make the NMI interrupt do nothing */152152+ if (MACH_IS_AMIGA) {153153+ vectors[VEC_INT7] = nmihandler;154154+ }155155+}156156+157157+158158+static const char *vec_names[] = {159159+ [VEC_RESETSP] = "RESET SP",160160+ [VEC_RESETPC] = "RESET PC",161161+ [VEC_BUSERR] = "BUS ERROR",162162+ [VEC_ADDRERR] = "ADDRESS ERROR",163163+ [VEC_ILLEGAL] = "ILLEGAL INSTRUCTION",164164+ [VEC_ZERODIV] = "ZERO DIVIDE",165165+ [VEC_CHK] = "CHK",166166+ [VEC_TRAP] = "TRAPcc",167167+ [VEC_PRIV] = "PRIVILEGE VIOLATION",168168+ [VEC_TRACE] = "TRACE",169169+ [VEC_LINE10] = "LINE 1010",170170+ [VEC_LINE11] = "LINE 1111",171171+ [VEC_RESV12] = "UNASSIGNED RESERVED 12",172172+ [VEC_COPROC] = "COPROCESSOR PROTOCOL VIOLATION",173173+ [VEC_FORMAT] = "FORMAT ERROR",174174+ [VEC_UNINT] = "UNINITIALIZED INTERRUPT",175175+ [VEC_RESV16] = "UNASSIGNED RESERVED 16",176176+ [VEC_RESV17] = "UNASSIGNED RESERVED 17",177177+ [VEC_RESV18] = "UNASSIGNED RESERVED 18",178178+ [VEC_RESV19] = "UNASSIGNED RESERVED 19",179179+ [VEC_RESV20] = "UNASSIGNED RESERVED 20",180180+ [VEC_RESV21] = "UNASSIGNED RESERVED 21",181181+ [VEC_RESV22] = "UNASSIGNED RESERVED 22",182182+ [VEC_RESV23] = "UNASSIGNED RESERVED 23",183183+ [VEC_SPUR] = "SPURIOUS INTERRUPT",184184+ [VEC_INT1] = "LEVEL 1 INT",185185+ [VEC_INT2] = "LEVEL 2 INT",186186+ [VEC_INT3] = "LEVEL 3 INT",187187+ [VEC_INT4] = "LEVEL 4 INT",188188+ [VEC_INT5] = "LEVEL 5 INT",189189+ [VEC_INT6] = "LEVEL 6 INT",190190+ [VEC_INT7] = "LEVEL 7 INT",191191+ [VEC_SYS] = "SYSCALL",192192+ [VEC_TRAP1] = "TRAP #1",193193+ [VEC_TRAP2] = "TRAP #2",194194+ [VEC_TRAP3] = "TRAP #3",195195+ [VEC_TRAP4] = "TRAP #4",196196+ [VEC_TRAP5] = "TRAP #5",197197+ [VEC_TRAP6] = "TRAP #6",198198+ [VEC_TRAP7] = "TRAP #7",199199+ [VEC_TRAP8] = "TRAP #8",200200+ [VEC_TRAP9] = "TRAP #9",201201+ [VEC_TRAP10] = "TRAP #10",202202+ [VEC_TRAP11] = "TRAP #11",203203+ [VEC_TRAP12] = "TRAP #12",204204+ [VEC_TRAP13] = "TRAP #13",205205+ [VEC_TRAP14] = "TRAP #14",206206+ [VEC_TRAP15] = "TRAP #15",207207+ [VEC_FPBRUC] = "FPCP BSUN",208208+ [VEC_FPIR] = "FPCP INEXACT",209209+ [VEC_FPDIVZ] = "FPCP DIV BY 0",210210+ [VEC_FPUNDER] = "FPCP UNDERFLOW",211211+ [VEC_FPOE] = "FPCP OPERAND ERROR",212212+ [VEC_FPOVER] = "FPCP OVERFLOW",213213+ [VEC_FPNAN] = "FPCP SNAN",214214+ [VEC_FPUNSUP] = "FPCP UNSUPPORTED OPERATION",215215+ [VEC_MMUCFG] = "MMU CONFIGURATION ERROR",216216+ [VEC_MMUILL] = "MMU ILLEGAL OPERATION ERROR",217217+ [VEC_MMUACC] = "MMU ACCESS LEVEL VIOLATION ERROR",218218+ [VEC_RESV59] = "UNASSIGNED RESERVED 59",219219+ [VEC_UNIMPEA] = "UNASSIGNED RESERVED 60",220220+ [VEC_UNIMPII] = "UNASSIGNED RESERVED 61",221221+ [VEC_RESV62] = "UNASSIGNED RESERVED 62",222222+ [VEC_RESV63] = "UNASSIGNED RESERVED 63",223223+};224224+225225+static const char *space_names[] = {226226+ [0] = "Space 0",227227+ [USER_DATA] = "User Data",228228+ [USER_PROGRAM] = "User Program",229229+#ifndef CONFIG_SUN3230230+ [3] = "Space 3",231231+#else232232+ [FC_CONTROL] = "Control",233233+#endif234234+ [4] = "Space 4",235235+ [SUPER_DATA] = "Super Data",236236+ [SUPER_PROGRAM] = "Super Program",237237+ [CPU_SPACE] = "CPU"238238+};239239+240240+void die_if_kernel(char *,struct pt_regs *,int);241241+asmlinkage int do_page_fault(struct pt_regs *regs, unsigned long address,242242+ unsigned long error_code);243243+int send_fault_sig(struct pt_regs *regs);244244+245245+asmlinkage void trap_c(struct frame *fp);246246+247247+#if defined (CONFIG_M68060)248248+static inline void access_error060 (struct frame *fp)249249+{250250+ unsigned long fslw = fp->un.fmt4.pc; /* is really FSLW for access error */251251+252252+#ifdef DEBUG253253+ printk("fslw=%#lx, fa=%#lx\n", fslw, fp->un.fmt4.effaddr);254254+#endif255255+256256+ if (fslw & MMU060_BPE) {257257+ /* branch prediction error -> clear branch cache */258258+ __asm__ __volatile__ ("movec %/cacr,%/d0\n\t"259259+ "orl #0x00400000,%/d0\n\t"260260+ "movec %/d0,%/cacr"261261+ : : : "d0" );262262+ /* return if there's no other error */263263+ if (!(fslw & MMU060_ERR_BITS) && !(fslw & MMU060_SEE))264264+ return;265265+ }266266+267267+ if (fslw & (MMU060_DESC_ERR | MMU060_WP | MMU060_SP)) {268268+ unsigned long errorcode;269269+ unsigned long addr = fp->un.fmt4.effaddr;270270+271271+ if (fslw & MMU060_MA)272272+ addr = (addr + PAGE_SIZE - 1) & PAGE_MASK;273273+274274+ errorcode = 1;275275+ if (fslw & MMU060_DESC_ERR) {276276+ __flush_tlb040_one(addr);277277+ errorcode = 0;278278+ }279279+ if (fslw & MMU060_W)280280+ errorcode |= 2;281281+#ifdef DEBUG282282+ printk("errorcode = %d\n", errorcode );283283+#endif284284+ do_page_fault(&fp->ptregs, addr, errorcode);285285+ } else if (fslw & (MMU060_SEE)){286286+ /* Software Emulation Error.287287+ * fault during mem_read/mem_write in ifpsp060/os.S288288+ */289289+ send_fault_sig(&fp->ptregs);290290+ } else if (!(fslw & (MMU060_RE|MMU060_WE)) ||291291+ send_fault_sig(&fp->ptregs) > 0) {292292+ printk("pc=%#lx, fa=%#lx\n", fp->ptregs.pc, fp->un.fmt4.effaddr);293293+ printk( "68060 access error, fslw=%lx\n", fslw );294294+ trap_c( fp );295295+ }296296+}297297+#endif /* CONFIG_M68060 */298298+299299+#if defined (CONFIG_M68040)300300+static inline unsigned long probe040(int iswrite, unsigned long addr, int wbs)301301+{302302+ unsigned long mmusr;303303+ mm_segment_t old_fs = get_fs();304304+305305+ set_fs(MAKE_MM_SEG(wbs));306306+307307+ if (iswrite)308308+ asm volatile (".chip 68040; ptestw (%0); .chip 68k" : : "a" (addr));309309+ else310310+ asm volatile (".chip 68040; ptestr (%0); .chip 68k" : : "a" (addr));311311+312312+ asm volatile (".chip 68040; movec %%mmusr,%0; .chip 68k" : "=r" (mmusr));313313+314314+ set_fs(old_fs);315315+316316+ return mmusr;317317+}318318+319319+static inline int do_040writeback1(unsigned short wbs, unsigned long wba,320320+ unsigned long wbd)321321+{322322+ int res = 0;323323+ mm_segment_t old_fs = get_fs();324324+325325+ /* set_fs can not be moved, otherwise put_user() may oops */326326+ set_fs(MAKE_MM_SEG(wbs));327327+328328+ switch (wbs & WBSIZ_040) {329329+ case BA_SIZE_BYTE:330330+ res = put_user(wbd & 0xff, (char __user *)wba);331331+ break;332332+ case BA_SIZE_WORD:333333+ res = put_user(wbd & 0xffff, (short __user *)wba);334334+ break;335335+ case BA_SIZE_LONG:336336+ res = put_user(wbd, (int __user *)wba);337337+ break;338338+ }339339+340340+ /* set_fs can not be moved, otherwise put_user() may oops */341341+ set_fs(old_fs);342342+343343+344344+#ifdef DEBUG345345+ printk("do_040writeback1, res=%d\n",res);346346+#endif347347+348348+ return res;349349+}350350+351351+/* after an exception in a writeback the stack frame corresponding352352+ * to that exception is discarded, set a few bits in the old frame353353+ * to simulate what it should look like354354+ */355355+static inline void fix_xframe040(struct frame *fp, unsigned long wba, unsigned short wbs)356356+{357357+ fp->un.fmt7.faddr = wba;358358+ fp->un.fmt7.ssw = wbs & 0xff;359359+ if (wba != current->thread.faddr)360360+ fp->un.fmt7.ssw |= MA_040;361361+}362362+363363+static inline void do_040writebacks(struct frame *fp)364364+{365365+ int res = 0;366366+#if 0367367+ if (fp->un.fmt7.wb1s & WBV_040)368368+ printk("access_error040: cannot handle 1st writeback. oops.\n");369369+#endif370370+371371+ if ((fp->un.fmt7.wb2s & WBV_040) &&372372+ !(fp->un.fmt7.wb2s & WBTT_040)) {373373+ res = do_040writeback1(fp->un.fmt7.wb2s, fp->un.fmt7.wb2a,374374+ fp->un.fmt7.wb2d);375375+ if (res)376376+ fix_xframe040(fp, fp->un.fmt7.wb2a, fp->un.fmt7.wb2s);377377+ else378378+ fp->un.fmt7.wb2s = 0;379379+ }380380+381381+ /* do the 2nd wb only if the first one was successful (except for a kernel wb) */382382+ if (fp->un.fmt7.wb3s & WBV_040 && (!res || fp->un.fmt7.wb3s & 4)) {383383+ res = do_040writeback1(fp->un.fmt7.wb3s, fp->un.fmt7.wb3a,384384+ fp->un.fmt7.wb3d);385385+ if (res)386386+ {387387+ fix_xframe040(fp, fp->un.fmt7.wb3a, fp->un.fmt7.wb3s);388388+389389+ fp->un.fmt7.wb2s = fp->un.fmt7.wb3s;390390+ fp->un.fmt7.wb3s &= (~WBV_040);391391+ fp->un.fmt7.wb2a = fp->un.fmt7.wb3a;392392+ fp->un.fmt7.wb2d = fp->un.fmt7.wb3d;393393+ }394394+ else395395+ fp->un.fmt7.wb3s = 0;396396+ }397397+398398+ if (res)399399+ send_fault_sig(&fp->ptregs);400400+}401401+402402+/*403403+ * called from sigreturn(), must ensure userspace code didn't404404+ * manipulate exception frame to circumvent protection, then complete405405+ * pending writebacks406406+ * we just clear TM2 to turn it into a userspace access407407+ */408408+asmlinkage void berr_040cleanup(struct frame *fp)409409+{410410+ fp->un.fmt7.wb2s &= ~4;411411+ fp->un.fmt7.wb3s &= ~4;412412+413413+ do_040writebacks(fp);414414+}415415+416416+static inline void access_error040(struct frame *fp)417417+{418418+ unsigned short ssw = fp->un.fmt7.ssw;419419+ unsigned long mmusr;420420+421421+#ifdef DEBUG422422+ printk("ssw=%#x, fa=%#lx\n", ssw, fp->un.fmt7.faddr);423423+ printk("wb1s=%#x, wb2s=%#x, wb3s=%#x\n", fp->un.fmt7.wb1s,424424+ fp->un.fmt7.wb2s, fp->un.fmt7.wb3s);425425+ printk ("wb2a=%lx, wb3a=%lx, wb2d=%lx, wb3d=%lx\n",426426+ fp->un.fmt7.wb2a, fp->un.fmt7.wb3a,427427+ fp->un.fmt7.wb2d, fp->un.fmt7.wb3d);428428+#endif429429+430430+ if (ssw & ATC_040) {431431+ unsigned long addr = fp->un.fmt7.faddr;432432+ unsigned long errorcode;433433+434434+ /*435435+ * The MMU status has to be determined AFTER the address436436+ * has been corrected if there was a misaligned access (MA).437437+ */438438+ if (ssw & MA_040)439439+ addr = (addr + 7) & -8;440440+441441+ /* MMU error, get the MMUSR info for this access */442442+ mmusr = probe040(!(ssw & RW_040), addr, ssw);443443+#ifdef DEBUG444444+ printk("mmusr = %lx\n", mmusr);445445+#endif446446+ errorcode = 1;447447+ if (!(mmusr & MMU_R_040)) {448448+ /* clear the invalid atc entry */449449+ __flush_tlb040_one(addr);450450+ errorcode = 0;451451+ }452452+453453+ /* despite what documentation seems to say, RMW454454+ * accesses have always both the LK and RW bits set */455455+ if (!(ssw & RW_040) || (ssw & LK_040))456456+ errorcode |= 2;457457+458458+ if (do_page_fault(&fp->ptregs, addr, errorcode)) {459459+#ifdef DEBUG460460+ printk("do_page_fault() !=0\n");461461+#endif462462+ if (user_mode(&fp->ptregs)){463463+ /* delay writebacks after signal delivery */464464+#ifdef DEBUG465465+ printk(".. was usermode - return\n");466466+#endif467467+ return;468468+ }469469+ /* disable writeback into user space from kernel470470+ * (if do_page_fault didn't fix the mapping,471471+ * the writeback won't do good)472472+ */473473+disable_wb:474474+#ifdef DEBUG475475+ printk(".. disabling wb2\n");476476+#endif477477+ if (fp->un.fmt7.wb2a == fp->un.fmt7.faddr)478478+ fp->un.fmt7.wb2s &= ~WBV_040;479479+ if (fp->un.fmt7.wb3a == fp->un.fmt7.faddr)480480+ fp->un.fmt7.wb3s &= ~WBV_040;481481+ }482482+ } else {483483+ /* In case of a bus error we either kill the process or expect484484+ * the kernel to catch the fault, which then is also responsible485485+ * for cleaning up the mess.486486+ */487487+ current->thread.signo = SIGBUS;488488+ current->thread.faddr = fp->un.fmt7.faddr;489489+ if (send_fault_sig(&fp->ptregs) >= 0)490490+ printk("68040 bus error (ssw=%x, faddr=%lx)\n", ssw,491491+ fp->un.fmt7.faddr);492492+ goto disable_wb;493493+ }494494+495495+ do_040writebacks(fp);496496+}497497+#endif /* CONFIG_M68040 */498498+499499+#if defined(CONFIG_SUN3)500500+#include <asm/sun3mmu.h>501501+502502+extern int mmu_emu_handle_fault (unsigned long, int, int);503503+504504+/* sun3 version of bus_error030 */505505+506506+static inline void bus_error030 (struct frame *fp)507507+{508508+ unsigned char buserr_type = sun3_get_buserr ();509509+ unsigned long addr, errorcode;510510+ unsigned short ssw = fp->un.fmtb.ssw;511511+ extern unsigned long _sun3_map_test_start, _sun3_map_test_end;512512+513513+#ifdef DEBUG514514+ if (ssw & (FC | FB))515515+ printk ("Instruction fault at %#010lx\n",516516+ ssw & FC ?517517+ fp->ptregs.format == 0xa ? fp->ptregs.pc + 2 : fp->un.fmtb.baddr - 2518518+ :519519+ fp->ptregs.format == 0xa ? fp->ptregs.pc + 4 : fp->un.fmtb.baddr);520520+ if (ssw & DF)521521+ printk ("Data %s fault at %#010lx in %s (pc=%#lx)\n",522522+ ssw & RW ? "read" : "write",523523+ fp->un.fmtb.daddr,524524+ space_names[ssw & DFC], fp->ptregs.pc);525525+#endif526526+527527+ /*528528+ * Check if this page should be demand-mapped. This needs to go before529529+ * the testing for a bad kernel-space access (demand-mapping applies530530+ * to kernel accesses too).531531+ */532532+533533+ if ((ssw & DF)534534+ && (buserr_type & (SUN3_BUSERR_PROTERR | SUN3_BUSERR_INVALID))) {535535+ if (mmu_emu_handle_fault (fp->un.fmtb.daddr, ssw & RW, 0))536536+ return;537537+ }538538+539539+ /* Check for kernel-space pagefault (BAD). */540540+ if (fp->ptregs.sr & PS_S) {541541+ /* kernel fault must be a data fault to user space */542542+ if (! ((ssw & DF) && ((ssw & DFC) == USER_DATA))) {543543+ // try checking the kernel mappings before surrender544544+ if (mmu_emu_handle_fault (fp->un.fmtb.daddr, ssw & RW, 1))545545+ return;546546+ /* instruction fault or kernel data fault! */547547+ if (ssw & (FC | FB))548548+ printk ("Instruction fault at %#010lx\n",549549+ fp->ptregs.pc);550550+ if (ssw & DF) {551551+ /* was this fault incurred testing bus mappings? */552552+ if((fp->ptregs.pc >= (unsigned long)&_sun3_map_test_start) &&553553+ (fp->ptregs.pc <= (unsigned long)&_sun3_map_test_end)) {554554+ send_fault_sig(&fp->ptregs);555555+ return;556556+ }557557+558558+ printk ("Data %s fault at %#010lx in %s (pc=%#lx)\n",559559+ ssw & RW ? "read" : "write",560560+ fp->un.fmtb.daddr,561561+ space_names[ssw & DFC], fp->ptregs.pc);562562+ }563563+ printk ("BAD KERNEL BUSERR\n");564564+565565+ die_if_kernel("Oops", &fp->ptregs,0);566566+ force_sig(SIGKILL, current);567567+ return;568568+ }569569+ } else {570570+ /* user fault */571571+ if (!(ssw & (FC | FB)) && !(ssw & DF))572572+ /* not an instruction fault or data fault! BAD */573573+ panic ("USER BUSERR w/o instruction or data fault");574574+ }575575+576576+577577+ /* First handle the data fault, if any. */578578+ if (ssw & DF) {579579+ addr = fp->un.fmtb.daddr;580580+581581+// errorcode bit 0: 0 -> no page 1 -> protection fault582582+// errorcode bit 1: 0 -> read fault 1 -> write fault583583+584584+// (buserr_type & SUN3_BUSERR_PROTERR) -> protection fault585585+// (buserr_type & SUN3_BUSERR_INVALID) -> invalid page fault586586+587587+ if (buserr_type & SUN3_BUSERR_PROTERR)588588+ errorcode = 0x01;589589+ else if (buserr_type & SUN3_BUSERR_INVALID)590590+ errorcode = 0x00;591591+ else {592592+#ifdef DEBUG593593+ printk ("*** unexpected busfault type=%#04x\n", buserr_type);594594+ printk ("invalid %s access at %#lx from pc %#lx\n",595595+ !(ssw & RW) ? "write" : "read", addr,596596+ fp->ptregs.pc);597597+#endif598598+ die_if_kernel ("Oops", &fp->ptregs, buserr_type);599599+ force_sig (SIGBUS, current);600600+ return;601601+ }602602+603603+//todo: wtf is RM bit? --m604604+ if (!(ssw & RW) || ssw & RM)605605+ errorcode |= 0x02;606606+607607+ /* Handle page fault. */608608+ do_page_fault (&fp->ptregs, addr, errorcode);609609+610610+ /* Retry the data fault now. */611611+ return;612612+ }613613+614614+ /* Now handle the instruction fault. */615615+616616+ /* Get the fault address. */617617+ if (fp->ptregs.format == 0xA)618618+ addr = fp->ptregs.pc + 4;619619+ else620620+ addr = fp->un.fmtb.baddr;621621+ if (ssw & FC)622622+ addr -= 2;623623+624624+ if (buserr_type & SUN3_BUSERR_INVALID) {625625+ if (!mmu_emu_handle_fault (fp->un.fmtb.daddr, 1, 0))626626+ do_page_fault (&fp->ptregs, addr, 0);627627+ } else {628628+#ifdef DEBUG629629+ printk ("protection fault on insn access (segv).\n");630630+#endif631631+ force_sig (SIGSEGV, current);632632+ }633633+}634634+#else635635+#if defined(CPU_M68020_OR_M68030)636636+static inline void bus_error030 (struct frame *fp)637637+{638638+ volatile unsigned short temp;639639+ unsigned short mmusr;640640+ unsigned long addr, errorcode;641641+ unsigned short ssw = fp->un.fmtb.ssw;642642+#ifdef DEBUG643643+ unsigned long desc;644644+645645+ printk ("pid = %x ", current->pid);646646+ printk ("SSW=%#06x ", ssw);647647+648648+ if (ssw & (FC | FB))649649+ printk ("Instruction fault at %#010lx\n",650650+ ssw & FC ?651651+ fp->ptregs.format == 0xa ? fp->ptregs.pc + 2 : fp->un.fmtb.baddr - 2652652+ :653653+ fp->ptregs.format == 0xa ? fp->ptregs.pc + 4 : fp->un.fmtb.baddr);654654+ if (ssw & DF)655655+ printk ("Data %s fault at %#010lx in %s (pc=%#lx)\n",656656+ ssw & RW ? "read" : "write",657657+ fp->un.fmtb.daddr,658658+ space_names[ssw & DFC], fp->ptregs.pc);659659+#endif660660+661661+ /* ++andreas: If a data fault and an instruction fault happen662662+ at the same time map in both pages. */663663+664664+ /* First handle the data fault, if any. */665665+ if (ssw & DF) {666666+ addr = fp->un.fmtb.daddr;667667+668668+#ifdef DEBUG669669+ asm volatile ("ptestr %3,%2@,#7,%0\n\t"670670+ "pmove %%psr,%1@"671671+ : "=a&" (desc)672672+ : "a" (&temp), "a" (addr), "d" (ssw));673673+#else674674+ asm volatile ("ptestr %2,%1@,#7\n\t"675675+ "pmove %%psr,%0@"676676+ : : "a" (&temp), "a" (addr), "d" (ssw));677677+#endif678678+ mmusr = temp;679679+680680+#ifdef DEBUG681681+ printk("mmusr is %#x for addr %#lx in task %p\n",682682+ mmusr, addr, current);683683+ printk("descriptor address is %#lx, contents %#lx\n",684684+ __va(desc), *(unsigned long *)__va(desc));685685+#endif686686+687687+ errorcode = (mmusr & MMU_I) ? 0 : 1;688688+ if (!(ssw & RW) || (ssw & RM))689689+ errorcode |= 2;690690+691691+ if (mmusr & (MMU_I | MMU_WP)) {692692+ if (ssw & 4) {693693+ printk("Data %s fault at %#010lx in %s (pc=%#lx)\n",694694+ ssw & RW ? "read" : "write",695695+ fp->un.fmtb.daddr,696696+ space_names[ssw & DFC], fp->ptregs.pc);697697+ goto buserr;698698+ }699699+ /* Don't try to do anything further if an exception was700700+ handled. */701701+ if (do_page_fault (&fp->ptregs, addr, errorcode) < 0)702702+ return;703703+ } else if (!(mmusr & MMU_I)) {704704+ /* probably a 020 cas fault */705705+ if (!(ssw & RM) && send_fault_sig(&fp->ptregs) > 0)706706+ printk("unexpected bus error (%#x,%#x)\n", ssw, mmusr);707707+ } else if (mmusr & (MMU_B|MMU_L|MMU_S)) {708708+ printk("invalid %s access at %#lx from pc %#lx\n",709709+ !(ssw & RW) ? "write" : "read", addr,710710+ fp->ptregs.pc);711711+ die_if_kernel("Oops",&fp->ptregs,mmusr);712712+ force_sig(SIGSEGV, current);713713+ return;714714+ } else {715715+#if 0716716+ static volatile long tlong;717717+#endif718718+719719+ printk("weird %s access at %#lx from pc %#lx (ssw is %#x)\n",720720+ !(ssw & RW) ? "write" : "read", addr,721721+ fp->ptregs.pc, ssw);722722+ asm volatile ("ptestr #1,%1@,#0\n\t"723723+ "pmove %%psr,%0@"724724+ : /* no outputs */725725+ : "a" (&temp), "a" (addr));726726+ mmusr = temp;727727+728728+ printk ("level 0 mmusr is %#x\n", mmusr);729729+#if 0730730+ asm volatile ("pmove %%tt0,%0@"731731+ : /* no outputs */732732+ : "a" (&tlong));733733+ printk("tt0 is %#lx, ", tlong);734734+ asm volatile ("pmove %%tt1,%0@"735735+ : /* no outputs */736736+ : "a" (&tlong));737737+ printk("tt1 is %#lx\n", tlong);738738+#endif739739+#ifdef DEBUG740740+ printk("Unknown SIGSEGV - 1\n");741741+#endif742742+ die_if_kernel("Oops",&fp->ptregs,mmusr);743743+ force_sig(SIGSEGV, current);744744+ return;745745+ }746746+747747+ /* setup an ATC entry for the access about to be retried */748748+ if (!(ssw & RW) || (ssw & RM))749749+ asm volatile ("ploadw %1,%0@" : /* no outputs */750750+ : "a" (addr), "d" (ssw));751751+ else752752+ asm volatile ("ploadr %1,%0@" : /* no outputs */753753+ : "a" (addr), "d" (ssw));754754+ }755755+756756+ /* Now handle the instruction fault. */757757+758758+ if (!(ssw & (FC|FB)))759759+ return;760760+761761+ if (fp->ptregs.sr & PS_S) {762762+ printk("Instruction fault at %#010lx\n",763763+ fp->ptregs.pc);764764+ buserr:765765+ printk ("BAD KERNEL BUSERR\n");766766+ die_if_kernel("Oops",&fp->ptregs,0);767767+ force_sig(SIGKILL, current);768768+ return;769769+ }770770+771771+ /* get the fault address */772772+ if (fp->ptregs.format == 10)773773+ addr = fp->ptregs.pc + 4;774774+ else775775+ addr = fp->un.fmtb.baddr;776776+ if (ssw & FC)777777+ addr -= 2;778778+779779+ if ((ssw & DF) && ((addr ^ fp->un.fmtb.daddr) & PAGE_MASK) == 0)780780+ /* Insn fault on same page as data fault. But we781781+ should still create the ATC entry. */782782+ goto create_atc_entry;783783+784784+#ifdef DEBUG785785+ asm volatile ("ptestr #1,%2@,#7,%0\n\t"786786+ "pmove %%psr,%1@"787787+ : "=a&" (desc)788788+ : "a" (&temp), "a" (addr));789789+#else790790+ asm volatile ("ptestr #1,%1@,#7\n\t"791791+ "pmove %%psr,%0@"792792+ : : "a" (&temp), "a" (addr));793793+#endif794794+ mmusr = temp;795795+796796+#ifdef DEBUG797797+ printk ("mmusr is %#x for addr %#lx in task %p\n",798798+ mmusr, addr, current);799799+ printk ("descriptor address is %#lx, contents %#lx\n",800800+ __va(desc), *(unsigned long *)__va(desc));801801+#endif802802+803803+ if (mmusr & MMU_I)804804+ do_page_fault (&fp->ptregs, addr, 0);805805+ else if (mmusr & (MMU_B|MMU_L|MMU_S)) {806806+ printk ("invalid insn access at %#lx from pc %#lx\n",807807+ addr, fp->ptregs.pc);808808+#ifdef DEBUG809809+ printk("Unknown SIGSEGV - 2\n");810810+#endif811811+ die_if_kernel("Oops",&fp->ptregs,mmusr);812812+ force_sig(SIGSEGV, current);813813+ return;814814+ }815815+816816+create_atc_entry:817817+ /* setup an ATC entry for the access about to be retried */818818+ asm volatile ("ploadr #2,%0@" : /* no outputs */819819+ : "a" (addr));820820+}821821+#endif /* CPU_M68020_OR_M68030 */822822+#endif /* !CONFIG_SUN3 */823823+824824+asmlinkage void buserr_c(struct frame *fp)825825+{826826+ /* Only set esp0 if coming from user mode */827827+ if (user_mode(&fp->ptregs))828828+ current->thread.esp0 = (unsigned long) fp;829829+830830+#ifdef DEBUG831831+ printk ("*** Bus Error *** Format is %x\n", fp->ptregs.format);832832+#endif833833+834834+ switch (fp->ptregs.format) {835835+#if defined (CONFIG_M68060)836836+ case 4: /* 68060 access error */837837+ access_error060 (fp);838838+ break;839839+#endif840840+#if defined (CONFIG_M68040)841841+ case 0x7: /* 68040 access error */842842+ access_error040 (fp);843843+ break;844844+#endif845845+#if defined (CPU_M68020_OR_M68030)846846+ case 0xa:847847+ case 0xb:848848+ bus_error030 (fp);849849+ break;850850+#endif851851+ default:852852+ die_if_kernel("bad frame format",&fp->ptregs,0);853853+#ifdef DEBUG854854+ printk("Unknown SIGSEGV - 4\n");855855+#endif856856+ force_sig(SIGSEGV, current);857857+ }858858+}859859+860860+861861+static int kstack_depth_to_print = 48;862862+863863+void show_trace(unsigned long *stack)864864+{865865+ unsigned long *endstack;866866+ unsigned long addr;867867+ int i;868868+869869+ printk("Call Trace:");870870+ addr = (unsigned long)stack + THREAD_SIZE - 1;871871+ endstack = (unsigned long *)(addr & -THREAD_SIZE);872872+ i = 0;873873+ while (stack + 1 <= endstack) {874874+ addr = *stack++;875875+ /*876876+ * If the address is either in the text segment of the877877+ * kernel, or in the region which contains vmalloc'ed878878+ * memory, it *may* be the address of a calling879879+ * routine; if so, print it so that someone tracing880880+ * down the cause of the crash will be able to figure881881+ * out the call path that was taken.882882+ */883883+ if (__kernel_text_address(addr)) {884884+#ifndef CONFIG_KALLSYMS885885+ if (i % 5 == 0)886886+ printk("\n ");887887+#endif888888+ printk(" [<%08lx>] %pS\n", addr, (void *)addr);889889+ i++;890890+ }891891+ }892892+ printk("\n");893893+}894894+895895+void show_registers(struct pt_regs *regs)896896+{897897+ struct frame *fp = (struct frame *)regs;898898+ mm_segment_t old_fs = get_fs();899899+ u16 c, *cp;900900+ unsigned long addr;901901+ int i;902902+903903+ print_modules();904904+ printk("PC: [<%08lx>] %pS\n", regs->pc, (void *)regs->pc);905905+ printk("SR: %04x SP: %p a2: %08lx\n", regs->sr, regs, regs->a2);906906+ printk("d0: %08lx d1: %08lx d2: %08lx d3: %08lx\n",907907+ regs->d0, regs->d1, regs->d2, regs->d3);908908+ printk("d4: %08lx d5: %08lx a0: %08lx a1: %08lx\n",909909+ regs->d4, regs->d5, regs->a0, regs->a1);910910+911911+ printk("Process %s (pid: %d, task=%p)\n",912912+ current->comm, task_pid_nr(current), current);913913+ addr = (unsigned long)&fp->un;914914+ printk("Frame format=%X ", regs->format);915915+ switch (regs->format) {916916+ case 0x2:917917+ printk("instr addr=%08lx\n", fp->un.fmt2.iaddr);918918+ addr += sizeof(fp->un.fmt2);919919+ break;920920+ case 0x3:921921+ printk("eff addr=%08lx\n", fp->un.fmt3.effaddr);922922+ addr += sizeof(fp->un.fmt3);923923+ break;924924+ case 0x4:925925+ printk((CPU_IS_060 ? "fault addr=%08lx fslw=%08lx\n"926926+ : "eff addr=%08lx pc=%08lx\n"),927927+ fp->un.fmt4.effaddr, fp->un.fmt4.pc);928928+ addr += sizeof(fp->un.fmt4);929929+ break;930930+ case 0x7:931931+ printk("eff addr=%08lx ssw=%04x faddr=%08lx\n",932932+ fp->un.fmt7.effaddr, fp->un.fmt7.ssw, fp->un.fmt7.faddr);933933+ printk("wb 1 stat/addr/data: %04x %08lx %08lx\n",934934+ fp->un.fmt7.wb1s, fp->un.fmt7.wb1a, fp->un.fmt7.wb1dpd0);935935+ printk("wb 2 stat/addr/data: %04x %08lx %08lx\n",936936+ fp->un.fmt7.wb2s, fp->un.fmt7.wb2a, fp->un.fmt7.wb2d);937937+ printk("wb 3 stat/addr/data: %04x %08lx %08lx\n",938938+ fp->un.fmt7.wb3s, fp->un.fmt7.wb3a, fp->un.fmt7.wb3d);939939+ printk("push data: %08lx %08lx %08lx %08lx\n",940940+ fp->un.fmt7.wb1dpd0, fp->un.fmt7.pd1, fp->un.fmt7.pd2,941941+ fp->un.fmt7.pd3);942942+ addr += sizeof(fp->un.fmt7);943943+ break;944944+ case 0x9:945945+ printk("instr addr=%08lx\n", fp->un.fmt9.iaddr);946946+ addr += sizeof(fp->un.fmt9);947947+ break;948948+ case 0xa:949949+ printk("ssw=%04x isc=%04x isb=%04x daddr=%08lx dobuf=%08lx\n",950950+ fp->un.fmta.ssw, fp->un.fmta.isc, fp->un.fmta.isb,951951+ fp->un.fmta.daddr, fp->un.fmta.dobuf);952952+ addr += sizeof(fp->un.fmta);953953+ break;954954+ case 0xb:955955+ printk("ssw=%04x isc=%04x isb=%04x daddr=%08lx dobuf=%08lx\n",956956+ fp->un.fmtb.ssw, fp->un.fmtb.isc, fp->un.fmtb.isb,957957+ fp->un.fmtb.daddr, fp->un.fmtb.dobuf);958958+ printk("baddr=%08lx dibuf=%08lx ver=%x\n",959959+ fp->un.fmtb.baddr, fp->un.fmtb.dibuf, fp->un.fmtb.ver);960960+ addr += sizeof(fp->un.fmtb);961961+ break;962962+ default:963963+ printk("\n");964964+ }965965+ show_stack(NULL, (unsigned long *)addr);966966+967967+ printk("Code:");968968+ set_fs(KERNEL_DS);969969+ cp = (u16 *)regs->pc;970970+ for (i = -8; i < 16; i++) {971971+ if (get_user(c, cp + i) && i >= 0) {972972+ printk(" Bad PC value.");973973+ break;974974+ }975975+ printk(i ? " %04x" : " <%04x>", c);976976+ }977977+ set_fs(old_fs);978978+ printk ("\n");979979+}980980+981981+void show_stack(struct task_struct *task, unsigned long *stack)982982+{983983+ unsigned long *p;984984+ unsigned long *endstack;985985+ int i;986986+987987+ if (!stack) {988988+ if (task)989989+ stack = (unsigned long *)task->thread.esp0;990990+ else991991+ stack = (unsigned long *)&stack;992992+ }993993+ endstack = (unsigned long *)(((unsigned long)stack + THREAD_SIZE - 1) & -THREAD_SIZE);994994+995995+ printk("Stack from %08lx:", (unsigned long)stack);996996+ p = stack;997997+ for (i = 0; i < kstack_depth_to_print; i++) {998998+ if (p + 1 > endstack)999999+ break;10001000+ if (i % 8 == 0)10011001+ printk("\n ");10021002+ printk(" %08lx", *p++);10031003+ }10041004+ printk("\n");10051005+ show_trace(stack);10061006+}10071007+10081008+/*10091009+ * The architecture-independent backtrace generator10101010+ */10111011+void dump_stack(void)10121012+{10131013+ unsigned long stack;10141014+10151015+ show_trace(&stack);10161016+}10171017+10181018+EXPORT_SYMBOL(dump_stack);10191019+10201020+void bad_super_trap (struct frame *fp)10211021+{10221022+ console_verbose();10231023+ if (fp->ptregs.vector < 4 * ARRAY_SIZE(vec_names))10241024+ printk ("*** %s *** FORMAT=%X\n",10251025+ vec_names[(fp->ptregs.vector) >> 2],10261026+ fp->ptregs.format);10271027+ else10281028+ printk ("*** Exception %d *** FORMAT=%X\n",10291029+ (fp->ptregs.vector) >> 2,10301030+ fp->ptregs.format);10311031+ if (fp->ptregs.vector >> 2 == VEC_ADDRERR && CPU_IS_020_OR_030) {10321032+ unsigned short ssw = fp->un.fmtb.ssw;10331033+10341034+ printk ("SSW=%#06x ", ssw);10351035+10361036+ if (ssw & RC)10371037+ printk ("Pipe stage C instruction fault at %#010lx\n",10381038+ (fp->ptregs.format) == 0xA ?10391039+ fp->ptregs.pc + 2 : fp->un.fmtb.baddr - 2);10401040+ if (ssw & RB)10411041+ printk ("Pipe stage B instruction fault at %#010lx\n",10421042+ (fp->ptregs.format) == 0xA ?10431043+ fp->ptregs.pc + 4 : fp->un.fmtb.baddr);10441044+ if (ssw & DF)10451045+ printk ("Data %s fault at %#010lx in %s (pc=%#lx)\n",10461046+ ssw & RW ? "read" : "write",10471047+ fp->un.fmtb.daddr, space_names[ssw & DFC],10481048+ fp->ptregs.pc);10491049+ }10501050+ printk ("Current process id is %d\n", task_pid_nr(current));10511051+ die_if_kernel("BAD KERNEL TRAP", &fp->ptregs, 0);10521052+}10531053+10541054+asmlinkage void trap_c(struct frame *fp)10551055+{10561056+ int sig;10571057+ siginfo_t info;10581058+10591059+ if (fp->ptregs.sr & PS_S) {10601060+ if (fp->ptregs.vector == VEC_TRACE << 2) {10611061+ /* traced a trapping instruction on a 68020/30,10621062+ * real exception will be executed afterwards.10631063+ */10641064+ } else if (!handle_kernel_fault(&fp->ptregs))10651065+ bad_super_trap(fp);10661066+ return;10671067+ }10681068+10691069+ /* send the appropriate signal to the user program */10701070+ switch ((fp->ptregs.vector) >> 2) {10711071+ case VEC_ADDRERR:10721072+ info.si_code = BUS_ADRALN;10731073+ sig = SIGBUS;10741074+ break;10751075+ case VEC_ILLEGAL:10761076+ case VEC_LINE10:10771077+ case VEC_LINE11:10781078+ info.si_code = ILL_ILLOPC;10791079+ sig = SIGILL;10801080+ break;10811081+ case VEC_PRIV:10821082+ info.si_code = ILL_PRVOPC;10831083+ sig = SIGILL;10841084+ break;10851085+ case VEC_COPROC:10861086+ info.si_code = ILL_COPROC;10871087+ sig = SIGILL;10881088+ break;10891089+ case VEC_TRAP1:10901090+ case VEC_TRAP2:10911091+ case VEC_TRAP3:10921092+ case VEC_TRAP4:10931093+ case VEC_TRAP5:10941094+ case VEC_TRAP6:10951095+ case VEC_TRAP7:10961096+ case VEC_TRAP8:10971097+ case VEC_TRAP9:10981098+ case VEC_TRAP10:10991099+ case VEC_TRAP11:11001100+ case VEC_TRAP12:11011101+ case VEC_TRAP13:11021102+ case VEC_TRAP14:11031103+ info.si_code = ILL_ILLTRP;11041104+ sig = SIGILL;11051105+ break;11061106+ case VEC_FPBRUC:11071107+ case VEC_FPOE:11081108+ case VEC_FPNAN:11091109+ info.si_code = FPE_FLTINV;11101110+ sig = SIGFPE;11111111+ break;11121112+ case VEC_FPIR:11131113+ info.si_code = FPE_FLTRES;11141114+ sig = SIGFPE;11151115+ break;11161116+ case VEC_FPDIVZ:11171117+ info.si_code = FPE_FLTDIV;11181118+ sig = SIGFPE;11191119+ break;11201120+ case VEC_FPUNDER:11211121+ info.si_code = FPE_FLTUND;11221122+ sig = SIGFPE;11231123+ break;11241124+ case VEC_FPOVER:11251125+ info.si_code = FPE_FLTOVF;11261126+ sig = SIGFPE;11271127+ break;11281128+ case VEC_ZERODIV:11291129+ info.si_code = FPE_INTDIV;11301130+ sig = SIGFPE;11311131+ break;11321132+ case VEC_CHK:11331133+ case VEC_TRAP:11341134+ info.si_code = FPE_INTOVF;11351135+ sig = SIGFPE;11361136+ break;11371137+ case VEC_TRACE: /* ptrace single step */11381138+ info.si_code = TRAP_TRACE;11391139+ sig = SIGTRAP;11401140+ break;11411141+ case VEC_TRAP15: /* breakpoint */11421142+ info.si_code = TRAP_BRKPT;11431143+ sig = SIGTRAP;11441144+ break;11451145+ default:11461146+ info.si_code = ILL_ILLOPC;11471147+ sig = SIGILL;11481148+ break;11491149+ }11501150+ info.si_signo = sig;11511151+ info.si_errno = 0;11521152+ switch (fp->ptregs.format) {11531153+ default:11541154+ info.si_addr = (void *) fp->ptregs.pc;11551155+ break;11561156+ case 2:11571157+ info.si_addr = (void *) fp->un.fmt2.iaddr;11581158+ break;11591159+ case 7:11601160+ info.si_addr = (void *) fp->un.fmt7.effaddr;11611161+ break;11621162+ case 9:11631163+ info.si_addr = (void *) fp->un.fmt9.iaddr;11641164+ break;11651165+ case 10:11661166+ info.si_addr = (void *) fp->un.fmta.daddr;11671167+ break;11681168+ case 11:11691169+ info.si_addr = (void *) fp->un.fmtb.daddr;11701170+ break;11711171+ }11721172+ force_sig_info (sig, &info, current);11731173+}11741174+11751175+void die_if_kernel (char *str, struct pt_regs *fp, int nr)11761176+{11771177+ if (!(fp->sr & PS_S))11781178+ return;11791179+11801180+ console_verbose();11811181+ printk("%s: %08x\n",str,nr);11821182+ show_registers(fp);11831183+ add_taint(TAINT_DIE);11841184+ do_exit(SIGSEGV);11851185+}11861186+11871187+/*11881188+ * This function is called if an error occur while accessing11891189+ * user-space from the fpsp040 code.11901190+ */11911191+asmlinkage void fpsp040_die(void)11921192+{11931193+ do_exit(SIGSEGV);11941194+}11951195+11961196+#ifdef CONFIG_M68KFPU_EMU11971197+asmlinkage void fpemu_signal(int signal, int code, void *addr)11981198+{11991199+ siginfo_t info;12001200+12011201+ info.si_signo = signal;12021202+ info.si_errno = 0;12031203+ info.si_code = code;12041204+ info.si_addr = addr;12051205+ force_sig_info(signal, &info, current);12061206+}12071207+#endif
+3-8
arch/m68k/kernel/vmlinux.lds.S
···11-PHDRS22-{33- text PT_LOAD FILEHDR PHDRS FLAGS (7);44- data PT_LOAD FLAGS (7);55-}66-#ifdef CONFIG_SUN377-#include "vmlinux-sun3.lds"11+#ifdef CONFIG_MMU22+#include "vmlinux.lds_mm.S"83#else99-#include "vmlinux-std.lds"44+#include "vmlinux.lds_no.S"105#endif
+10
arch/m68k/kernel/vmlinux.lds_mm.S
···11+PHDRS22+{33+ text PT_LOAD FILEHDR PHDRS FLAGS (7);44+ data PT_LOAD FLAGS (7);55+}66+#ifdef CONFIG_SUN377+#include "vmlinux-sun3.lds"88+#else99+#include "vmlinux-std.lds"1010+#endif
···11-/*22- * INET An implementation of the TCP/IP protocol suite for the LINUX33- * operating system. INET is implemented using the BSD Socket44- * interface as the means of communication with the user level.55- *66- * IP/TCP/UDP checksumming routines77- *88- * Authors: Jorge Cwik, <jorge@laser.satlink.net>99- * Arnt Gulbrandsen, <agulbra@nvg.unit.no>1010- * Tom May, <ftom@netcom.com>1111- * Andreas Schwab, <schwab@issan.informatik.uni-dortmund.de>1212- * Lots of code moved from tcp.c and ip.c; see those files1313- * for more names.1414- *1515- * 03/02/96 Jes Sorensen, Andreas Schwab, Roman Hodek:1616- * Fixed some nasty bugs, causing some horrible crashes.1717- * A: At some points, the sum (%0) was used as1818- * length-counter instead of the length counter1919- * (%1). Thanks to Roman Hodek for pointing this out.2020- * B: GCC seems to mess up if one uses too many2121- * data-registers to hold input values and one tries to2222- * specify d0 and d1 as scratch registers. Letting gcc2323- * choose these registers itself solves the problem.2424- *2525- * This program is free software; you can redistribute it and/or2626- * modify it under the terms of the GNU General Public License2727- * as published by the Free Software Foundation; either version2828- * 2 of the License, or (at your option) any later version.2929- *3030- * 1998/8/31 Andreas Schwab:3131- * Zero out rest of buffer on exception in3232- * csum_partial_copy_from_user.3333- */3434-3535-#include <linux/module.h>3636-#include <net/checksum.h>3737-3838-/*3939- * computes a partial checksum, e.g. for TCP/UDP fragments4040- */4141-4242-__wsum csum_partial(const void *buff, int len, __wsum sum)4343-{4444- unsigned long tmp1, tmp2;4545- /*4646- * Experiments with ethernet and slip connections show that buff4747- * is aligned on either a 2-byte or 4-byte boundary.4848- */4949- __asm__("movel %2,%3\n\t"5050- "btst #1,%3\n\t" /* Check alignment */5151- "jeq 2f\n\t"5252- "subql #2,%1\n\t" /* buff%4==2: treat first word */5353- "jgt 1f\n\t"5454- "addql #2,%1\n\t" /* len was == 2, treat only rest */5555- "jra 4f\n"5656- "1:\t"5757- "addw %2@+,%0\n\t" /* add first word to sum */5858- "clrl %3\n\t"5959- "addxl %3,%0\n" /* add X bit */6060- "2:\t"6161- /* unrolled loop for the main part: do 8 longs at once */6262- "movel %1,%3\n\t" /* save len in tmp1 */6363- "lsrl #5,%1\n\t" /* len/32 */6464- "jeq 2f\n\t" /* not enough... */6565- "subql #1,%1\n"6666- "1:\t"6767- "movel %2@+,%4\n\t"6868- "addxl %4,%0\n\t"6969- "movel %2@+,%4\n\t"7070- "addxl %4,%0\n\t"7171- "movel %2@+,%4\n\t"7272- "addxl %4,%0\n\t"7373- "movel %2@+,%4\n\t"7474- "addxl %4,%0\n\t"7575- "movel %2@+,%4\n\t"7676- "addxl %4,%0\n\t"7777- "movel %2@+,%4\n\t"7878- "addxl %4,%0\n\t"7979- "movel %2@+,%4\n\t"8080- "addxl %4,%0\n\t"8181- "movel %2@+,%4\n\t"8282- "addxl %4,%0\n\t"8383- "dbra %1,1b\n\t"8484- "clrl %4\n\t"8585- "addxl %4,%0\n\t" /* add X bit */8686- "clrw %1\n\t"8787- "subql #1,%1\n\t"8888- "jcc 1b\n"8989- "2:\t"9090- "movel %3,%1\n\t" /* restore len from tmp1 */9191- "andw #0x1c,%3\n\t" /* number of rest longs */9292- "jeq 4f\n\t"9393- "lsrw #2,%3\n\t"9494- "subqw #1,%3\n"9595- "3:\t"9696- /* loop for rest longs */9797- "movel %2@+,%4\n\t"9898- "addxl %4,%0\n\t"9999- "dbra %3,3b\n\t"100100- "clrl %4\n\t"101101- "addxl %4,%0\n" /* add X bit */102102- "4:\t"103103- /* now check for rest bytes that do not fit into longs */104104- "andw #3,%1\n\t"105105- "jeq 7f\n\t"106106- "clrl %4\n\t" /* clear tmp2 for rest bytes */107107- "subqw #2,%1\n\t"108108- "jlt 5f\n\t"109109- "movew %2@+,%4\n\t" /* have rest >= 2: get word */110110- "swap %4\n\t" /* into bits 16..31 */111111- "tstw %1\n\t" /* another byte? */112112- "jeq 6f\n"113113- "5:\t"114114- "moveb %2@,%4\n\t" /* have odd rest: get byte */115115- "lslw #8,%4\n\t" /* into bits 8..15; 16..31 untouched */116116- "6:\t"117117- "addl %4,%0\n\t" /* now add rest long to sum */118118- "clrl %4\n\t"119119- "addxl %4,%0\n" /* add X bit */120120- "7:\t"121121- : "=d" (sum), "=d" (len), "=a" (buff),122122- "=&d" (tmp1), "=&d" (tmp2)123123- : "0" (sum), "1" (len), "2" (buff)124124- );125125- return(sum);126126-}127127-128128-EXPORT_SYMBOL(csum_partial);129129-130130-131131-/*132132- * copy from user space while checksumming, with exception handling.133133- */134134-135135-__wsum136136-csum_partial_copy_from_user(const void __user *src, void *dst,137137- int len, __wsum sum, int *csum_err)138138-{139139- /*140140- * GCC doesn't like more than 10 operands for the asm141141- * statements so we have to use tmp2 for the error142142- * code.143143- */144144- unsigned long tmp1, tmp2;145145-146146- __asm__("movel %2,%4\n\t"147147- "btst #1,%4\n\t" /* Check alignment */148148- "jeq 2f\n\t"149149- "subql #2,%1\n\t" /* buff%4==2: treat first word */150150- "jgt 1f\n\t"151151- "addql #2,%1\n\t" /* len was == 2, treat only rest */152152- "jra 4f\n"153153- "1:\n"154154- "10:\t"155155- "movesw %2@+,%4\n\t" /* add first word to sum */156156- "addw %4,%0\n\t"157157- "movew %4,%3@+\n\t"158158- "clrl %4\n\t"159159- "addxl %4,%0\n" /* add X bit */160160- "2:\t"161161- /* unrolled loop for the main part: do 8 longs at once */162162- "movel %1,%4\n\t" /* save len in tmp1 */163163- "lsrl #5,%1\n\t" /* len/32 */164164- "jeq 2f\n\t" /* not enough... */165165- "subql #1,%1\n"166166- "1:\n"167167- "11:\t"168168- "movesl %2@+,%5\n\t"169169- "addxl %5,%0\n\t"170170- "movel %5,%3@+\n\t"171171- "12:\t"172172- "movesl %2@+,%5\n\t"173173- "addxl %5,%0\n\t"174174- "movel %5,%3@+\n\t"175175- "13:\t"176176- "movesl %2@+,%5\n\t"177177- "addxl %5,%0\n\t"178178- "movel %5,%3@+\n\t"179179- "14:\t"180180- "movesl %2@+,%5\n\t"181181- "addxl %5,%0\n\t"182182- "movel %5,%3@+\n\t"183183- "15:\t"184184- "movesl %2@+,%5\n\t"185185- "addxl %5,%0\n\t"186186- "movel %5,%3@+\n\t"187187- "16:\t"188188- "movesl %2@+,%5\n\t"189189- "addxl %5,%0\n\t"190190- "movel %5,%3@+\n\t"191191- "17:\t"192192- "movesl %2@+,%5\n\t"193193- "addxl %5,%0\n\t"194194- "movel %5,%3@+\n\t"195195- "18:\t"196196- "movesl %2@+,%5\n\t"197197- "addxl %5,%0\n\t"198198- "movel %5,%3@+\n\t"199199- "dbra %1,1b\n\t"200200- "clrl %5\n\t"201201- "addxl %5,%0\n\t" /* add X bit */202202- "clrw %1\n\t"203203- "subql #1,%1\n\t"204204- "jcc 1b\n"205205- "2:\t"206206- "movel %4,%1\n\t" /* restore len from tmp1 */207207- "andw #0x1c,%4\n\t" /* number of rest longs */208208- "jeq 4f\n\t"209209- "lsrw #2,%4\n\t"210210- "subqw #1,%4\n"211211- "3:\n"212212- /* loop for rest longs */213213- "19:\t"214214- "movesl %2@+,%5\n\t"215215- "addxl %5,%0\n\t"216216- "movel %5,%3@+\n\t"217217- "dbra %4,3b\n\t"218218- "clrl %5\n\t"219219- "addxl %5,%0\n" /* add X bit */220220- "4:\t"221221- /* now check for rest bytes that do not fit into longs */222222- "andw #3,%1\n\t"223223- "jeq 7f\n\t"224224- "clrl %5\n\t" /* clear tmp2 for rest bytes */225225- "subqw #2,%1\n\t"226226- "jlt 5f\n\t"227227- "20:\t"228228- "movesw %2@+,%5\n\t" /* have rest >= 2: get word */229229- "movew %5,%3@+\n\t"230230- "swap %5\n\t" /* into bits 16..31 */231231- "tstw %1\n\t" /* another byte? */232232- "jeq 6f\n"233233- "5:\n"234234- "21:\t"235235- "movesb %2@,%5\n\t" /* have odd rest: get byte */236236- "moveb %5,%3@+\n\t"237237- "lslw #8,%5\n\t" /* into bits 8..15; 16..31 untouched */238238- "6:\t"239239- "addl %5,%0\n\t" /* now add rest long to sum */240240- "clrl %5\n\t"241241- "addxl %5,%0\n\t" /* add X bit */242242- "7:\t"243243- "clrl %5\n" /* no error - clear return value */244244- "8:\n"245245- ".section .fixup,\"ax\"\n"246246- ".even\n"247247- /* If any exception occurs zero out the rest.248248- Similarities with the code above are intentional :-) */249249- "90:\t"250250- "clrw %3@+\n\t"251251- "movel %1,%4\n\t"252252- "lsrl #5,%1\n\t"253253- "jeq 1f\n\t"254254- "subql #1,%1\n"255255- "91:\t"256256- "clrl %3@+\n"257257- "92:\t"258258- "clrl %3@+\n"259259- "93:\t"260260- "clrl %3@+\n"261261- "94:\t"262262- "clrl %3@+\n"263263- "95:\t"264264- "clrl %3@+\n"265265- "96:\t"266266- "clrl %3@+\n"267267- "97:\t"268268- "clrl %3@+\n"269269- "98:\t"270270- "clrl %3@+\n\t"271271- "dbra %1,91b\n\t"272272- "clrw %1\n\t"273273- "subql #1,%1\n\t"274274- "jcc 91b\n"275275- "1:\t"276276- "movel %4,%1\n\t"277277- "andw #0x1c,%4\n\t"278278- "jeq 1f\n\t"279279- "lsrw #2,%4\n\t"280280- "subqw #1,%4\n"281281- "99:\t"282282- "clrl %3@+\n\t"283283- "dbra %4,99b\n\t"284284- "1:\t"285285- "andw #3,%1\n\t"286286- "jeq 9f\n"287287- "100:\t"288288- "clrw %3@+\n\t"289289- "tstw %1\n\t"290290- "jeq 9f\n"291291- "101:\t"292292- "clrb %3@+\n"293293- "9:\t"294294-#define STR(X) STR1(X)295295-#define STR1(X) #X296296- "moveq #-" STR(EFAULT) ",%5\n\t"297297- "jra 8b\n"298298- ".previous\n"299299- ".section __ex_table,\"a\"\n"300300- ".long 10b,90b\n"301301- ".long 11b,91b\n"302302- ".long 12b,92b\n"303303- ".long 13b,93b\n"304304- ".long 14b,94b\n"305305- ".long 15b,95b\n"306306- ".long 16b,96b\n"307307- ".long 17b,97b\n"308308- ".long 18b,98b\n"309309- ".long 19b,99b\n"310310- ".long 20b,100b\n"311311- ".long 21b,101b\n"312312- ".previous"313313- : "=d" (sum), "=d" (len), "=a" (src), "=a" (dst),314314- "=&d" (tmp1), "=d" (tmp2)315315- : "0" (sum), "1" (len), "2" (src), "3" (dst)316316- );317317-318318- *csum_err = tmp2;319319-320320- return(sum);321321-}322322-323323-EXPORT_SYMBOL(csum_partial_copy_from_user);324324-325325-326326-/*327327- * copy from kernel space while checksumming, otherwise like csum_partial328328- */329329-330330-__wsum331331-csum_partial_copy_nocheck(const void *src, void *dst, int len, __wsum sum)332332-{333333- unsigned long tmp1, tmp2;334334- __asm__("movel %2,%4\n\t"335335- "btst #1,%4\n\t" /* Check alignment */336336- "jeq 2f\n\t"337337- "subql #2,%1\n\t" /* buff%4==2: treat first word */338338- "jgt 1f\n\t"339339- "addql #2,%1\n\t" /* len was == 2, treat only rest */340340- "jra 4f\n"341341- "1:\t"342342- "movew %2@+,%4\n\t" /* add first word to sum */343343- "addw %4,%0\n\t"344344- "movew %4,%3@+\n\t"345345- "clrl %4\n\t"346346- "addxl %4,%0\n" /* add X bit */347347- "2:\t"348348- /* unrolled loop for the main part: do 8 longs at once */349349- "movel %1,%4\n\t" /* save len in tmp1 */350350- "lsrl #5,%1\n\t" /* len/32 */351351- "jeq 2f\n\t" /* not enough... */352352- "subql #1,%1\n"353353- "1:\t"354354- "movel %2@+,%5\n\t"355355- "addxl %5,%0\n\t"356356- "movel %5,%3@+\n\t"357357- "movel %2@+,%5\n\t"358358- "addxl %5,%0\n\t"359359- "movel %5,%3@+\n\t"360360- "movel %2@+,%5\n\t"361361- "addxl %5,%0\n\t"362362- "movel %5,%3@+\n\t"363363- "movel %2@+,%5\n\t"364364- "addxl %5,%0\n\t"365365- "movel %5,%3@+\n\t"366366- "movel %2@+,%5\n\t"367367- "addxl %5,%0\n\t"368368- "movel %5,%3@+\n\t"369369- "movel %2@+,%5\n\t"370370- "addxl %5,%0\n\t"371371- "movel %5,%3@+\n\t"372372- "movel %2@+,%5\n\t"373373- "addxl %5,%0\n\t"374374- "movel %5,%3@+\n\t"375375- "movel %2@+,%5\n\t"376376- "addxl %5,%0\n\t"377377- "movel %5,%3@+\n\t"378378- "dbra %1,1b\n\t"379379- "clrl %5\n\t"380380- "addxl %5,%0\n\t" /* add X bit */381381- "clrw %1\n\t"382382- "subql #1,%1\n\t"383383- "jcc 1b\n"384384- "2:\t"385385- "movel %4,%1\n\t" /* restore len from tmp1 */386386- "andw #0x1c,%4\n\t" /* number of rest longs */387387- "jeq 4f\n\t"388388- "lsrw #2,%4\n\t"389389- "subqw #1,%4\n"390390- "3:\t"391391- /* loop for rest longs */392392- "movel %2@+,%5\n\t"393393- "addxl %5,%0\n\t"394394- "movel %5,%3@+\n\t"395395- "dbra %4,3b\n\t"396396- "clrl %5\n\t"397397- "addxl %5,%0\n" /* add X bit */398398- "4:\t"399399- /* now check for rest bytes that do not fit into longs */400400- "andw #3,%1\n\t"401401- "jeq 7f\n\t"402402- "clrl %5\n\t" /* clear tmp2 for rest bytes */403403- "subqw #2,%1\n\t"404404- "jlt 5f\n\t"405405- "movew %2@+,%5\n\t" /* have rest >= 2: get word */406406- "movew %5,%3@+\n\t"407407- "swap %5\n\t" /* into bits 16..31 */408408- "tstw %1\n\t" /* another byte? */409409- "jeq 6f\n"410410- "5:\t"411411- "moveb %2@,%5\n\t" /* have odd rest: get byte */412412- "moveb %5,%3@+\n\t"413413- "lslw #8,%5\n" /* into bits 8..15; 16..31 untouched */414414- "6:\t"415415- "addl %5,%0\n\t" /* now add rest long to sum */416416- "clrl %5\n\t"417417- "addxl %5,%0\n" /* add X bit */418418- "7:\t"419419- : "=d" (sum), "=d" (len), "=a" (src), "=a" (dst),420420- "=&d" (tmp1), "=&d" (tmp2)421421- : "0" (sum), "1" (len), "2" (src), "3" (dst)422422- );423423- return(sum);424424-}425425-EXPORT_SYMBOL(csum_partial_copy_nocheck);11+#ifdef CONFIG_MMU22+#include "checksum_mm.c"33+#else44+#include "checksum_no.c"55+#endif
+425
arch/m68k/lib/checksum_mm.c
···11+/*22+ * INET An implementation of the TCP/IP protocol suite for the LINUX33+ * operating system. INET is implemented using the BSD Socket44+ * interface as the means of communication with the user level.55+ *66+ * IP/TCP/UDP checksumming routines77+ *88+ * Authors: Jorge Cwik, <jorge@laser.satlink.net>99+ * Arnt Gulbrandsen, <agulbra@nvg.unit.no>1010+ * Tom May, <ftom@netcom.com>1111+ * Andreas Schwab, <schwab@issan.informatik.uni-dortmund.de>1212+ * Lots of code moved from tcp.c and ip.c; see those files1313+ * for more names.1414+ *1515+ * 03/02/96 Jes Sorensen, Andreas Schwab, Roman Hodek:1616+ * Fixed some nasty bugs, causing some horrible crashes.1717+ * A: At some points, the sum (%0) was used as1818+ * length-counter instead of the length counter1919+ * (%1). Thanks to Roman Hodek for pointing this out.2020+ * B: GCC seems to mess up if one uses too many2121+ * data-registers to hold input values and one tries to2222+ * specify d0 and d1 as scratch registers. Letting gcc2323+ * choose these registers itself solves the problem.2424+ *2525+ * This program is free software; you can redistribute it and/or2626+ * modify it under the terms of the GNU General Public License2727+ * as published by the Free Software Foundation; either version2828+ * 2 of the License, or (at your option) any later version.2929+ *3030+ * 1998/8/31 Andreas Schwab:3131+ * Zero out rest of buffer on exception in3232+ * csum_partial_copy_from_user.3333+ */3434+3535+#include <linux/module.h>3636+#include <net/checksum.h>3737+3838+/*3939+ * computes a partial checksum, e.g. for TCP/UDP fragments4040+ */4141+4242+__wsum csum_partial(const void *buff, int len, __wsum sum)4343+{4444+ unsigned long tmp1, tmp2;4545+ /*4646+ * Experiments with ethernet and slip connections show that buff4747+ * is aligned on either a 2-byte or 4-byte boundary.4848+ */4949+ __asm__("movel %2,%3\n\t"5050+ "btst #1,%3\n\t" /* Check alignment */5151+ "jeq 2f\n\t"5252+ "subql #2,%1\n\t" /* buff%4==2: treat first word */5353+ "jgt 1f\n\t"5454+ "addql #2,%1\n\t" /* len was == 2, treat only rest */5555+ "jra 4f\n"5656+ "1:\t"5757+ "addw %2@+,%0\n\t" /* add first word to sum */5858+ "clrl %3\n\t"5959+ "addxl %3,%0\n" /* add X bit */6060+ "2:\t"6161+ /* unrolled loop for the main part: do 8 longs at once */6262+ "movel %1,%3\n\t" /* save len in tmp1 */6363+ "lsrl #5,%1\n\t" /* len/32 */6464+ "jeq 2f\n\t" /* not enough... */6565+ "subql #1,%1\n"6666+ "1:\t"6767+ "movel %2@+,%4\n\t"6868+ "addxl %4,%0\n\t"6969+ "movel %2@+,%4\n\t"7070+ "addxl %4,%0\n\t"7171+ "movel %2@+,%4\n\t"7272+ "addxl %4,%0\n\t"7373+ "movel %2@+,%4\n\t"7474+ "addxl %4,%0\n\t"7575+ "movel %2@+,%4\n\t"7676+ "addxl %4,%0\n\t"7777+ "movel %2@+,%4\n\t"7878+ "addxl %4,%0\n\t"7979+ "movel %2@+,%4\n\t"8080+ "addxl %4,%0\n\t"8181+ "movel %2@+,%4\n\t"8282+ "addxl %4,%0\n\t"8383+ "dbra %1,1b\n\t"8484+ "clrl %4\n\t"8585+ "addxl %4,%0\n\t" /* add X bit */8686+ "clrw %1\n\t"8787+ "subql #1,%1\n\t"8888+ "jcc 1b\n"8989+ "2:\t"9090+ "movel %3,%1\n\t" /* restore len from tmp1 */9191+ "andw #0x1c,%3\n\t" /* number of rest longs */9292+ "jeq 4f\n\t"9393+ "lsrw #2,%3\n\t"9494+ "subqw #1,%3\n"9595+ "3:\t"9696+ /* loop for rest longs */9797+ "movel %2@+,%4\n\t"9898+ "addxl %4,%0\n\t"9999+ "dbra %3,3b\n\t"100100+ "clrl %4\n\t"101101+ "addxl %4,%0\n" /* add X bit */102102+ "4:\t"103103+ /* now check for rest bytes that do not fit into longs */104104+ "andw #3,%1\n\t"105105+ "jeq 7f\n\t"106106+ "clrl %4\n\t" /* clear tmp2 for rest bytes */107107+ "subqw #2,%1\n\t"108108+ "jlt 5f\n\t"109109+ "movew %2@+,%4\n\t" /* have rest >= 2: get word */110110+ "swap %4\n\t" /* into bits 16..31 */111111+ "tstw %1\n\t" /* another byte? */112112+ "jeq 6f\n"113113+ "5:\t"114114+ "moveb %2@,%4\n\t" /* have odd rest: get byte */115115+ "lslw #8,%4\n\t" /* into bits 8..15; 16..31 untouched */116116+ "6:\t"117117+ "addl %4,%0\n\t" /* now add rest long to sum */118118+ "clrl %4\n\t"119119+ "addxl %4,%0\n" /* add X bit */120120+ "7:\t"121121+ : "=d" (sum), "=d" (len), "=a" (buff),122122+ "=&d" (tmp1), "=&d" (tmp2)123123+ : "0" (sum), "1" (len), "2" (buff)124124+ );125125+ return(sum);126126+}127127+128128+EXPORT_SYMBOL(csum_partial);129129+130130+131131+/*132132+ * copy from user space while checksumming, with exception handling.133133+ */134134+135135+__wsum136136+csum_partial_copy_from_user(const void __user *src, void *dst,137137+ int len, __wsum sum, int *csum_err)138138+{139139+ /*140140+ * GCC doesn't like more than 10 operands for the asm141141+ * statements so we have to use tmp2 for the error142142+ * code.143143+ */144144+ unsigned long tmp1, tmp2;145145+146146+ __asm__("movel %2,%4\n\t"147147+ "btst #1,%4\n\t" /* Check alignment */148148+ "jeq 2f\n\t"149149+ "subql #2,%1\n\t" /* buff%4==2: treat first word */150150+ "jgt 1f\n\t"151151+ "addql #2,%1\n\t" /* len was == 2, treat only rest */152152+ "jra 4f\n"153153+ "1:\n"154154+ "10:\t"155155+ "movesw %2@+,%4\n\t" /* add first word to sum */156156+ "addw %4,%0\n\t"157157+ "movew %4,%3@+\n\t"158158+ "clrl %4\n\t"159159+ "addxl %4,%0\n" /* add X bit */160160+ "2:\t"161161+ /* unrolled loop for the main part: do 8 longs at once */162162+ "movel %1,%4\n\t" /* save len in tmp1 */163163+ "lsrl #5,%1\n\t" /* len/32 */164164+ "jeq 2f\n\t" /* not enough... */165165+ "subql #1,%1\n"166166+ "1:\n"167167+ "11:\t"168168+ "movesl %2@+,%5\n\t"169169+ "addxl %5,%0\n\t"170170+ "movel %5,%3@+\n\t"171171+ "12:\t"172172+ "movesl %2@+,%5\n\t"173173+ "addxl %5,%0\n\t"174174+ "movel %5,%3@+\n\t"175175+ "13:\t"176176+ "movesl %2@+,%5\n\t"177177+ "addxl %5,%0\n\t"178178+ "movel %5,%3@+\n\t"179179+ "14:\t"180180+ "movesl %2@+,%5\n\t"181181+ "addxl %5,%0\n\t"182182+ "movel %5,%3@+\n\t"183183+ "15:\t"184184+ "movesl %2@+,%5\n\t"185185+ "addxl %5,%0\n\t"186186+ "movel %5,%3@+\n\t"187187+ "16:\t"188188+ "movesl %2@+,%5\n\t"189189+ "addxl %5,%0\n\t"190190+ "movel %5,%3@+\n\t"191191+ "17:\t"192192+ "movesl %2@+,%5\n\t"193193+ "addxl %5,%0\n\t"194194+ "movel %5,%3@+\n\t"195195+ "18:\t"196196+ "movesl %2@+,%5\n\t"197197+ "addxl %5,%0\n\t"198198+ "movel %5,%3@+\n\t"199199+ "dbra %1,1b\n\t"200200+ "clrl %5\n\t"201201+ "addxl %5,%0\n\t" /* add X bit */202202+ "clrw %1\n\t"203203+ "subql #1,%1\n\t"204204+ "jcc 1b\n"205205+ "2:\t"206206+ "movel %4,%1\n\t" /* restore len from tmp1 */207207+ "andw #0x1c,%4\n\t" /* number of rest longs */208208+ "jeq 4f\n\t"209209+ "lsrw #2,%4\n\t"210210+ "subqw #1,%4\n"211211+ "3:\n"212212+ /* loop for rest longs */213213+ "19:\t"214214+ "movesl %2@+,%5\n\t"215215+ "addxl %5,%0\n\t"216216+ "movel %5,%3@+\n\t"217217+ "dbra %4,3b\n\t"218218+ "clrl %5\n\t"219219+ "addxl %5,%0\n" /* add X bit */220220+ "4:\t"221221+ /* now check for rest bytes that do not fit into longs */222222+ "andw #3,%1\n\t"223223+ "jeq 7f\n\t"224224+ "clrl %5\n\t" /* clear tmp2 for rest bytes */225225+ "subqw #2,%1\n\t"226226+ "jlt 5f\n\t"227227+ "20:\t"228228+ "movesw %2@+,%5\n\t" /* have rest >= 2: get word */229229+ "movew %5,%3@+\n\t"230230+ "swap %5\n\t" /* into bits 16..31 */231231+ "tstw %1\n\t" /* another byte? */232232+ "jeq 6f\n"233233+ "5:\n"234234+ "21:\t"235235+ "movesb %2@,%5\n\t" /* have odd rest: get byte */236236+ "moveb %5,%3@+\n\t"237237+ "lslw #8,%5\n\t" /* into bits 8..15; 16..31 untouched */238238+ "6:\t"239239+ "addl %5,%0\n\t" /* now add rest long to sum */240240+ "clrl %5\n\t"241241+ "addxl %5,%0\n\t" /* add X bit */242242+ "7:\t"243243+ "clrl %5\n" /* no error - clear return value */244244+ "8:\n"245245+ ".section .fixup,\"ax\"\n"246246+ ".even\n"247247+ /* If any exception occurs zero out the rest.248248+ Similarities with the code above are intentional :-) */249249+ "90:\t"250250+ "clrw %3@+\n\t"251251+ "movel %1,%4\n\t"252252+ "lsrl #5,%1\n\t"253253+ "jeq 1f\n\t"254254+ "subql #1,%1\n"255255+ "91:\t"256256+ "clrl %3@+\n"257257+ "92:\t"258258+ "clrl %3@+\n"259259+ "93:\t"260260+ "clrl %3@+\n"261261+ "94:\t"262262+ "clrl %3@+\n"263263+ "95:\t"264264+ "clrl %3@+\n"265265+ "96:\t"266266+ "clrl %3@+\n"267267+ "97:\t"268268+ "clrl %3@+\n"269269+ "98:\t"270270+ "clrl %3@+\n\t"271271+ "dbra %1,91b\n\t"272272+ "clrw %1\n\t"273273+ "subql #1,%1\n\t"274274+ "jcc 91b\n"275275+ "1:\t"276276+ "movel %4,%1\n\t"277277+ "andw #0x1c,%4\n\t"278278+ "jeq 1f\n\t"279279+ "lsrw #2,%4\n\t"280280+ "subqw #1,%4\n"281281+ "99:\t"282282+ "clrl %3@+\n\t"283283+ "dbra %4,99b\n\t"284284+ "1:\t"285285+ "andw #3,%1\n\t"286286+ "jeq 9f\n"287287+ "100:\t"288288+ "clrw %3@+\n\t"289289+ "tstw %1\n\t"290290+ "jeq 9f\n"291291+ "101:\t"292292+ "clrb %3@+\n"293293+ "9:\t"294294+#define STR(X) STR1(X)295295+#define STR1(X) #X296296+ "moveq #-" STR(EFAULT) ",%5\n\t"297297+ "jra 8b\n"298298+ ".previous\n"299299+ ".section __ex_table,\"a\"\n"300300+ ".long 10b,90b\n"301301+ ".long 11b,91b\n"302302+ ".long 12b,92b\n"303303+ ".long 13b,93b\n"304304+ ".long 14b,94b\n"305305+ ".long 15b,95b\n"306306+ ".long 16b,96b\n"307307+ ".long 17b,97b\n"308308+ ".long 18b,98b\n"309309+ ".long 19b,99b\n"310310+ ".long 20b,100b\n"311311+ ".long 21b,101b\n"312312+ ".previous"313313+ : "=d" (sum), "=d" (len), "=a" (src), "=a" (dst),314314+ "=&d" (tmp1), "=d" (tmp2)315315+ : "0" (sum), "1" (len), "2" (src), "3" (dst)316316+ );317317+318318+ *csum_err = tmp2;319319+320320+ return(sum);321321+}322322+323323+EXPORT_SYMBOL(csum_partial_copy_from_user);324324+325325+326326+/*327327+ * copy from kernel space while checksumming, otherwise like csum_partial328328+ */329329+330330+__wsum331331+csum_partial_copy_nocheck(const void *src, void *dst, int len, __wsum sum)332332+{333333+ unsigned long tmp1, tmp2;334334+ __asm__("movel %2,%4\n\t"335335+ "btst #1,%4\n\t" /* Check alignment */336336+ "jeq 2f\n\t"337337+ "subql #2,%1\n\t" /* buff%4==2: treat first word */338338+ "jgt 1f\n\t"339339+ "addql #2,%1\n\t" /* len was == 2, treat only rest */340340+ "jra 4f\n"341341+ "1:\t"342342+ "movew %2@+,%4\n\t" /* add first word to sum */343343+ "addw %4,%0\n\t"344344+ "movew %4,%3@+\n\t"345345+ "clrl %4\n\t"346346+ "addxl %4,%0\n" /* add X bit */347347+ "2:\t"348348+ /* unrolled loop for the main part: do 8 longs at once */349349+ "movel %1,%4\n\t" /* save len in tmp1 */350350+ "lsrl #5,%1\n\t" /* len/32 */351351+ "jeq 2f\n\t" /* not enough... */352352+ "subql #1,%1\n"353353+ "1:\t"354354+ "movel %2@+,%5\n\t"355355+ "addxl %5,%0\n\t"356356+ "movel %5,%3@+\n\t"357357+ "movel %2@+,%5\n\t"358358+ "addxl %5,%0\n\t"359359+ "movel %5,%3@+\n\t"360360+ "movel %2@+,%5\n\t"361361+ "addxl %5,%0\n\t"362362+ "movel %5,%3@+\n\t"363363+ "movel %2@+,%5\n\t"364364+ "addxl %5,%0\n\t"365365+ "movel %5,%3@+\n\t"366366+ "movel %2@+,%5\n\t"367367+ "addxl %5,%0\n\t"368368+ "movel %5,%3@+\n\t"369369+ "movel %2@+,%5\n\t"370370+ "addxl %5,%0\n\t"371371+ "movel %5,%3@+\n\t"372372+ "movel %2@+,%5\n\t"373373+ "addxl %5,%0\n\t"374374+ "movel %5,%3@+\n\t"375375+ "movel %2@+,%5\n\t"376376+ "addxl %5,%0\n\t"377377+ "movel %5,%3@+\n\t"378378+ "dbra %1,1b\n\t"379379+ "clrl %5\n\t"380380+ "addxl %5,%0\n\t" /* add X bit */381381+ "clrw %1\n\t"382382+ "subql #1,%1\n\t"383383+ "jcc 1b\n"384384+ "2:\t"385385+ "movel %4,%1\n\t" /* restore len from tmp1 */386386+ "andw #0x1c,%4\n\t" /* number of rest longs */387387+ "jeq 4f\n\t"388388+ "lsrw #2,%4\n\t"389389+ "subqw #1,%4\n"390390+ "3:\t"391391+ /* loop for rest longs */392392+ "movel %2@+,%5\n\t"393393+ "addxl %5,%0\n\t"394394+ "movel %5,%3@+\n\t"395395+ "dbra %4,3b\n\t"396396+ "clrl %5\n\t"397397+ "addxl %5,%0\n" /* add X bit */398398+ "4:\t"399399+ /* now check for rest bytes that do not fit into longs */400400+ "andw #3,%1\n\t"401401+ "jeq 7f\n\t"402402+ "clrl %5\n\t" /* clear tmp2 for rest bytes */403403+ "subqw #2,%1\n\t"404404+ "jlt 5f\n\t"405405+ "movew %2@+,%5\n\t" /* have rest >= 2: get word */406406+ "movew %5,%3@+\n\t"407407+ "swap %5\n\t" /* into bits 16..31 */408408+ "tstw %1\n\t" /* another byte? */409409+ "jeq 6f\n"410410+ "5:\t"411411+ "moveb %2@,%5\n\t" /* have odd rest: get byte */412412+ "moveb %5,%3@+\n\t"413413+ "lslw #8,%5\n" /* into bits 8..15; 16..31 untouched */414414+ "6:\t"415415+ "addl %5,%0\n\t" /* now add rest long to sum */416416+ "clrl %5\n\t"417417+ "addxl %5,%0\n" /* add X bit */418418+ "7:\t"419419+ : "=d" (sum), "=d" (len), "=a" (src), "=a" (dst),420420+ "=&d" (tmp1), "=&d" (tmp2)421421+ : "0" (sum), "1" (len), "2" (src), "3" (dst)422422+ );423423+ return(sum);424424+}425425+EXPORT_SYMBOL(csum_partial_copy_nocheck);
+5-63
arch/m68k/lib/muldi3.c
···11-/* muldi3.c extracted from gcc-2.7.2.3/libgcc2.c and22- gcc-2.7.2.3/longlong.h which is: */33-/* Copyright (C) 1989, 1992, 1993, 1994, 1995 Free Software Foundation, Inc.44-55-This file is part of GNU CC.66-77-GNU CC is free software; you can redistribute it and/or modify88-it under the terms of the GNU General Public License as published by99-the Free Software Foundation; either version 2, or (at your option)1010-any later version.1111-1212-GNU CC is distributed in the hope that it will be useful,1313-but WITHOUT ANY WARRANTY; without even the implied warranty of1414-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the1515-GNU General Public License for more details.1616-1717-You should have received a copy of the GNU General Public License1818-along with GNU CC; see the file COPYING. If not, write to1919-the Free Software Foundation, 59 Temple Place - Suite 330,2020-Boston, MA 02111-1307, USA. */2121-2222-#define BITS_PER_UNIT 82323-2424-#define umul_ppmm(w1, w0, u, v) \2525- __asm__ ("mulu%.l %3,%1:%0" \2626- : "=d" ((USItype)(w0)), \2727- "=d" ((USItype)(w1)) \2828- : "%0" ((USItype)(u)), \2929- "dmi" ((USItype)(v)))3030-3131-#define __umulsidi3(u, v) \3232- ({DIunion __w; \3333- umul_ppmm (__w.s.high, __w.s.low, u, v); \3434- __w.ll; })3535-3636-typedef int SItype __attribute__ ((mode (SI)));3737-typedef unsigned int USItype __attribute__ ((mode (SI)));3838-typedef int DItype __attribute__ ((mode (DI)));3939-typedef int word_type __attribute__ ((mode (__word__)));4040-4141-struct DIstruct {SItype high, low;};4242-4343-typedef union4444-{4545- struct DIstruct s;4646- DItype ll;4747-} DIunion;4848-4949-DItype5050-__muldi3 (DItype u, DItype v)5151-{5252- DIunion w;5353- DIunion uu, vv;5454-5555- uu.ll = u,5656- vv.ll = v;5757-5858- w.ll = __umulsidi3 (uu.s.low, vv.s.low);5959- w.s.high += ((USItype) uu.s.low * (USItype) vv.s.high6060- + (USItype) uu.s.high * (USItype) vv.s.low);6161-6262- return w.ll;6363-}11+#ifdef CONFIG_MMU22+#include "muldi3_mm.c"33+#else44+#include "muldi3_no.c"55+#endif
+5-8
arch/m68k/mm/Makefile
···11-#22-# Makefile for the linux m68k-specific parts of the memory manager.33-#44-55-obj-y := cache.o init.o fault.o hwtest.o66-77-obj-$(CONFIG_MMU_MOTOROLA) += kmap.o memory.o motorola.o88-obj-$(CONFIG_MMU_SUN3) += sun3kmap.o sun3mmu.o11+ifdef CONFIG_MMU22+include arch/m68k/mm/Makefile_mm33+else44+include arch/m68k/mm/Makefile_no55+endif
+8
arch/m68k/mm/Makefile_mm
···11+#22+# Makefile for the linux m68k-specific parts of the memory manager.33+#44+55+obj-y := cache.o init.o fault.o hwtest.o66+77+obj-$(CONFIG_MMU_MOTOROLA) += kmap.o memory.o motorola.o88+obj-$(CONFIG_MMU_SUN3) += sun3kmap.o sun3mmu.o
+4-149
arch/m68k/mm/init.c
···11-/*22- * linux/arch/m68k/mm/init.c33- *44- * Copyright (C) 1995 Hamish Macdonald55- *66- * Contains common initialization routines, specific init code moved77- * to motorola.c and sun3mmu.c88- */99-1010-#include <linux/module.h>1111-#include <linux/signal.h>1212-#include <linux/sched.h>1313-#include <linux/mm.h>1414-#include <linux/swap.h>1515-#include <linux/kernel.h>1616-#include <linux/string.h>1717-#include <linux/types.h>1818-#include <linux/init.h>1919-#include <linux/bootmem.h>2020-#include <linux/gfp.h>2121-2222-#include <asm/setup.h>2323-#include <asm/uaccess.h>2424-#include <asm/page.h>2525-#include <asm/pgalloc.h>2626-#include <asm/system.h>2727-#include <asm/machdep.h>2828-#include <asm/io.h>2929-#ifdef CONFIG_ATARI3030-#include <asm/atari_stram.h>3131-#endif3232-#include <asm/sections.h>3333-#include <asm/tlb.h>3434-3535-DEFINE_PER_CPU(struct mmu_gather, mmu_gathers);3636-3737-pg_data_t pg_data_map[MAX_NUMNODES];3838-EXPORT_SYMBOL(pg_data_map);3939-4040-int m68k_virt_to_node_shift;4141-4242-#ifndef CONFIG_SINGLE_MEMORY_CHUNK4343-pg_data_t *pg_data_table[65];4444-EXPORT_SYMBOL(pg_data_table);4545-#endif4646-4747-void __init m68k_setup_node(int node)4848-{4949-#ifndef CONFIG_SINGLE_MEMORY_CHUNK5050- struct mem_info *info = m68k_memory + node;5151- int i, end;5252-5353- i = (unsigned long)phys_to_virt(info->addr) >> __virt_to_node_shift();5454- end = (unsigned long)phys_to_virt(info->addr + info->size - 1) >> __virt_to_node_shift();5555- for (; i <= end; i++) {5656- if (pg_data_table[i])5757- printk("overlap at %u for chunk %u\n", i, node);5858- pg_data_table[i] = pg_data_map + node;5959- }6060-#endif6161- pg_data_map[node].bdata = bootmem_node_data + node;6262- node_set_online(node);6363-}6464-6565-6666-/*6767- * ZERO_PAGE is a special page that is used for zero-initialized6868- * data and COW.6969- */7070-7171-void *empty_zero_page;7272-EXPORT_SYMBOL(empty_zero_page);7373-7474-extern void init_pointer_table(unsigned long ptable);7575-7676-/* References to section boundaries */7777-7878-extern pmd_t *zero_pgtable;7979-8080-void __init mem_init(void)8181-{8282- pg_data_t *pgdat;8383- int codepages = 0;8484- int datapages = 0;8585- int initpages = 0;8686- int i;8787-8888-#ifdef CONFIG_ATARI8989- if (MACH_IS_ATARI)9090- atari_stram_mem_init_hook();9191-#endif9292-9393- /* this will put all memory onto the freelists */9494- totalram_pages = num_physpages = 0;9595- for_each_online_pgdat(pgdat) {9696- num_physpages += pgdat->node_present_pages;9797-9898- totalram_pages += free_all_bootmem_node(pgdat);9999- for (i = 0; i < pgdat->node_spanned_pages; i++) {100100- struct page *page = pgdat->node_mem_map + i;101101- char *addr = page_to_virt(page);102102-103103- if (!PageReserved(page))104104- continue;105105- if (addr >= _text &&106106- addr < _etext)107107- codepages++;108108- else if (addr >= __init_begin &&109109- addr < __init_end)110110- initpages++;111111- else112112- datapages++;113113- }114114- }115115-116116-#ifndef CONFIG_SUN3117117- /* insert pointer tables allocated so far into the tablelist */118118- init_pointer_table((unsigned long)kernel_pg_dir);119119- for (i = 0; i < PTRS_PER_PGD; i++) {120120- if (pgd_present(kernel_pg_dir[i]))121121- init_pointer_table(__pgd_page(kernel_pg_dir[i]));122122- }123123-124124- /* insert also pointer table that we used to unmap the zero page */125125- if (zero_pgtable)126126- init_pointer_table((unsigned long)zero_pgtable);127127-#endif128128-129129- printk("Memory: %luk/%luk available (%dk kernel code, %dk data, %dk init)\n",130130- nr_free_pages() << (PAGE_SHIFT-10),131131- totalram_pages << (PAGE_SHIFT-10),132132- codepages << (PAGE_SHIFT-10),133133- datapages << (PAGE_SHIFT-10),134134- initpages << (PAGE_SHIFT-10));135135-}136136-137137-#ifdef CONFIG_BLK_DEV_INITRD138138-void free_initrd_mem(unsigned long start, unsigned long end)139139-{140140- int pages = 0;141141- for (; start < end; start += PAGE_SIZE) {142142- ClearPageReserved(virt_to_page(start));143143- init_page_count(virt_to_page(start));144144- free_page(start);145145- totalram_pages++;146146- pages++;147147- }148148- printk ("Freeing initrd memory: %dk freed\n", pages);149149-}11+#ifdef CONFIG_MMU22+#include "init_mm.c"33+#else44+#include "init_no.c"1505#endif
+150
arch/m68k/mm/init_mm.c
···11+/*22+ * linux/arch/m68k/mm/init.c33+ *44+ * Copyright (C) 1995 Hamish Macdonald55+ *66+ * Contains common initialization routines, specific init code moved77+ * to motorola.c and sun3mmu.c88+ */99+1010+#include <linux/module.h>1111+#include <linux/signal.h>1212+#include <linux/sched.h>1313+#include <linux/mm.h>1414+#include <linux/swap.h>1515+#include <linux/kernel.h>1616+#include <linux/string.h>1717+#include <linux/types.h>1818+#include <linux/init.h>1919+#include <linux/bootmem.h>2020+#include <linux/gfp.h>2121+2222+#include <asm/setup.h>2323+#include <asm/uaccess.h>2424+#include <asm/page.h>2525+#include <asm/pgalloc.h>2626+#include <asm/system.h>2727+#include <asm/machdep.h>2828+#include <asm/io.h>2929+#ifdef CONFIG_ATARI3030+#include <asm/atari_stram.h>3131+#endif3232+#include <asm/sections.h>3333+#include <asm/tlb.h>3434+3535+DEFINE_PER_CPU(struct mmu_gather, mmu_gathers);3636+3737+pg_data_t pg_data_map[MAX_NUMNODES];3838+EXPORT_SYMBOL(pg_data_map);3939+4040+int m68k_virt_to_node_shift;4141+4242+#ifndef CONFIG_SINGLE_MEMORY_CHUNK4343+pg_data_t *pg_data_table[65];4444+EXPORT_SYMBOL(pg_data_table);4545+#endif4646+4747+void __init m68k_setup_node(int node)4848+{4949+#ifndef CONFIG_SINGLE_MEMORY_CHUNK5050+ struct mem_info *info = m68k_memory + node;5151+ int i, end;5252+5353+ i = (unsigned long)phys_to_virt(info->addr) >> __virt_to_node_shift();5454+ end = (unsigned long)phys_to_virt(info->addr + info->size - 1) >> __virt_to_node_shift();5555+ for (; i <= end; i++) {5656+ if (pg_data_table[i])5757+ printk("overlap at %u for chunk %u\n", i, node);5858+ pg_data_table[i] = pg_data_map + node;5959+ }6060+#endif6161+ pg_data_map[node].bdata = bootmem_node_data + node;6262+ node_set_online(node);6363+}6464+6565+6666+/*6767+ * ZERO_PAGE is a special page that is used for zero-initialized6868+ * data and COW.6969+ */7070+7171+void *empty_zero_page;7272+EXPORT_SYMBOL(empty_zero_page);7373+7474+extern void init_pointer_table(unsigned long ptable);7575+7676+/* References to section boundaries */7777+7878+extern pmd_t *zero_pgtable;7979+8080+void __init mem_init(void)8181+{8282+ pg_data_t *pgdat;8383+ int codepages = 0;8484+ int datapages = 0;8585+ int initpages = 0;8686+ int i;8787+8888+#ifdef CONFIG_ATARI8989+ if (MACH_IS_ATARI)9090+ atari_stram_mem_init_hook();9191+#endif9292+9393+ /* this will put all memory onto the freelists */9494+ totalram_pages = num_physpages = 0;9595+ for_each_online_pgdat(pgdat) {9696+ num_physpages += pgdat->node_present_pages;9797+9898+ totalram_pages += free_all_bootmem_node(pgdat);9999+ for (i = 0; i < pgdat->node_spanned_pages; i++) {100100+ struct page *page = pgdat->node_mem_map + i;101101+ char *addr = page_to_virt(page);102102+103103+ if (!PageReserved(page))104104+ continue;105105+ if (addr >= _text &&106106+ addr < _etext)107107+ codepages++;108108+ else if (addr >= __init_begin &&109109+ addr < __init_end)110110+ initpages++;111111+ else112112+ datapages++;113113+ }114114+ }115115+116116+#ifndef CONFIG_SUN3117117+ /* insert pointer tables allocated so far into the tablelist */118118+ init_pointer_table((unsigned long)kernel_pg_dir);119119+ for (i = 0; i < PTRS_PER_PGD; i++) {120120+ if (pgd_present(kernel_pg_dir[i]))121121+ init_pointer_table(__pgd_page(kernel_pg_dir[i]));122122+ }123123+124124+ /* insert also pointer table that we used to unmap the zero page */125125+ if (zero_pgtable)126126+ init_pointer_table((unsigned long)zero_pgtable);127127+#endif128128+129129+ printk("Memory: %luk/%luk available (%dk kernel code, %dk data, %dk init)\n",130130+ nr_free_pages() << (PAGE_SHIFT-10),131131+ totalram_pages << (PAGE_SHIFT-10),132132+ codepages << (PAGE_SHIFT-10),133133+ datapages << (PAGE_SHIFT-10),134134+ initpages << (PAGE_SHIFT-10));135135+}136136+137137+#ifdef CONFIG_BLK_DEV_INITRD138138+void free_initrd_mem(unsigned long start, unsigned long end)139139+{140140+ int pages = 0;141141+ for (; start < end; start += PAGE_SIZE) {142142+ ClearPageReserved(virt_to_page(start));143143+ init_page_count(virt_to_page(start));144144+ free_page(start);145145+ totalram_pages++;146146+ pages++;147147+ }148148+ printk ("Freeing initrd memory: %dk freed\n", pages);149149+}150150+#endif
+3-365
arch/m68k/mm/kmap.c
···11-/*22- * linux/arch/m68k/mm/kmap.c33- *44- * Copyright (C) 1997 Roman Hodek55- *66- * 10/01/99 cleaned up the code and changing to the same interface77- * used by other architectures /Roman Zippel88- */99-1010-#include <linux/module.h>1111-#include <linux/mm.h>1212-#include <linux/kernel.h>1313-#include <linux/string.h>1414-#include <linux/types.h>1515-#include <linux/slab.h>1616-#include <linux/vmalloc.h>1717-1818-#include <asm/setup.h>1919-#include <asm/segment.h>2020-#include <asm/page.h>2121-#include <asm/pgalloc.h>2222-#include <asm/io.h>2323-#include <asm/system.h>2424-2525-#undef DEBUG2626-2727-#define PTRTREESIZE (256*1024)2828-2929-/*3030- * For 040/060 we can use the virtual memory area like other architectures,3131- * but for 020/030 we want to use early termination page descriptor and we3232- * can't mix this with normal page descriptors, so we have to copy that code3333- * (mm/vmalloc.c) and return appriorate aligned addresses.3434- */3535-3636-#ifdef CPU_M68040_OR_M68060_ONLY3737-3838-#define IO_SIZE PAGE_SIZE3939-4040-static inline struct vm_struct *get_io_area(unsigned long size)4141-{4242- return get_vm_area(size, VM_IOREMAP);4343-}4444-4545-4646-static inline void free_io_area(void *addr)4747-{4848- vfree((void *)(PAGE_MASK & (unsigned long)addr));4949-}5050-11+#ifdef CONFIG_MMU22+#include "kmap_mm.c"513#else5252-5353-#define IO_SIZE (256*1024)5454-5555-static struct vm_struct *iolist;5656-5757-static struct vm_struct *get_io_area(unsigned long size)5858-{5959- unsigned long addr;6060- struct vm_struct **p, *tmp, *area;6161-6262- area = kmalloc(sizeof(*area), GFP_KERNEL);6363- if (!area)6464- return NULL;6565- addr = KMAP_START;6666- for (p = &iolist; (tmp = *p) ; p = &tmp->next) {6767- if (size + addr < (unsigned long)tmp->addr)6868- break;6969- if (addr > KMAP_END-size) {7070- kfree(area);7171- return NULL;7272- }7373- addr = tmp->size + (unsigned long)tmp->addr;7474- }7575- area->addr = (void *)addr;7676- area->size = size + IO_SIZE;7777- area->next = *p;7878- *p = area;7979- return area;8080-}8181-8282-static inline void free_io_area(void *addr)8383-{8484- struct vm_struct **p, *tmp;8585-8686- if (!addr)8787- return;8888- addr = (void *)((unsigned long)addr & -IO_SIZE);8989- for (p = &iolist ; (tmp = *p) ; p = &tmp->next) {9090- if (tmp->addr == addr) {9191- *p = tmp->next;9292- __iounmap(tmp->addr, tmp->size);9393- kfree(tmp);9494- return;9595- }9696- }9797-}9898-44+#include "kmap_no.c"995#endif100100-101101-/*102102- * Map some physical address range into the kernel address space.103103- */104104-/* Rewritten by Andreas Schwab to remove all races. */105105-106106-void __iomem *__ioremap(unsigned long physaddr, unsigned long size, int cacheflag)107107-{108108- struct vm_struct *area;109109- unsigned long virtaddr, retaddr;110110- long offset;111111- pgd_t *pgd_dir;112112- pmd_t *pmd_dir;113113- pte_t *pte_dir;114114-115115- /*116116- * Don't allow mappings that wrap..117117- */118118- if (!size || physaddr > (unsigned long)(-size))119119- return NULL;120120-121121-#ifdef CONFIG_AMIGA122122- if (MACH_IS_AMIGA) {123123- if ((physaddr >= 0x40000000) && (physaddr + size < 0x60000000)124124- && (cacheflag == IOMAP_NOCACHE_SER))125125- return (void __iomem *)physaddr;126126- }127127-#endif128128-129129-#ifdef DEBUG130130- printk("ioremap: 0x%lx,0x%lx(%d) - ", physaddr, size, cacheflag);131131-#endif132132- /*133133- * Mappings have to be aligned134134- */135135- offset = physaddr & (IO_SIZE - 1);136136- physaddr &= -IO_SIZE;137137- size = (size + offset + IO_SIZE - 1) & -IO_SIZE;138138-139139- /*140140- * Ok, go for it..141141- */142142- area = get_io_area(size);143143- if (!area)144144- return NULL;145145-146146- virtaddr = (unsigned long)area->addr;147147- retaddr = virtaddr + offset;148148-#ifdef DEBUG149149- printk("0x%lx,0x%lx,0x%lx", physaddr, virtaddr, retaddr);150150-#endif151151-152152- /*153153- * add cache and table flags to physical address154154- */155155- if (CPU_IS_040_OR_060) {156156- physaddr |= (_PAGE_PRESENT | _PAGE_GLOBAL040 |157157- _PAGE_ACCESSED | _PAGE_DIRTY);158158- switch (cacheflag) {159159- case IOMAP_FULL_CACHING:160160- physaddr |= _PAGE_CACHE040;161161- break;162162- case IOMAP_NOCACHE_SER:163163- default:164164- physaddr |= _PAGE_NOCACHE_S;165165- break;166166- case IOMAP_NOCACHE_NONSER:167167- physaddr |= _PAGE_NOCACHE;168168- break;169169- case IOMAP_WRITETHROUGH:170170- physaddr |= _PAGE_CACHE040W;171171- break;172172- }173173- } else {174174- physaddr |= (_PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_DIRTY);175175- switch (cacheflag) {176176- case IOMAP_NOCACHE_SER:177177- case IOMAP_NOCACHE_NONSER:178178- default:179179- physaddr |= _PAGE_NOCACHE030;180180- break;181181- case IOMAP_FULL_CACHING:182182- case IOMAP_WRITETHROUGH:183183- break;184184- }185185- }186186-187187- while ((long)size > 0) {188188-#ifdef DEBUG189189- if (!(virtaddr & (PTRTREESIZE-1)))190190- printk ("\npa=%#lx va=%#lx ", physaddr, virtaddr);191191-#endif192192- pgd_dir = pgd_offset_k(virtaddr);193193- pmd_dir = pmd_alloc(&init_mm, pgd_dir, virtaddr);194194- if (!pmd_dir) {195195- printk("ioremap: no mem for pmd_dir\n");196196- return NULL;197197- }198198-199199- if (CPU_IS_020_OR_030) {200200- pmd_dir->pmd[(virtaddr/PTRTREESIZE) & 15] = physaddr;201201- physaddr += PTRTREESIZE;202202- virtaddr += PTRTREESIZE;203203- size -= PTRTREESIZE;204204- } else {205205- pte_dir = pte_alloc_kernel(pmd_dir, virtaddr);206206- if (!pte_dir) {207207- printk("ioremap: no mem for pte_dir\n");208208- return NULL;209209- }210210-211211- pte_val(*pte_dir) = physaddr;212212- virtaddr += PAGE_SIZE;213213- physaddr += PAGE_SIZE;214214- size -= PAGE_SIZE;215215- }216216- }217217-#ifdef DEBUG218218- printk("\n");219219-#endif220220- flush_tlb_all();221221-222222- return (void __iomem *)retaddr;223223-}224224-EXPORT_SYMBOL(__ioremap);225225-226226-/*227227- * Unmap a ioremap()ed region again228228- */229229-void iounmap(void __iomem *addr)230230-{231231-#ifdef CONFIG_AMIGA232232- if ((!MACH_IS_AMIGA) ||233233- (((unsigned long)addr < 0x40000000) ||234234- ((unsigned long)addr > 0x60000000)))235235- free_io_area((__force void *)addr);236236-#else237237- free_io_area((__force void *)addr);238238-#endif239239-}240240-EXPORT_SYMBOL(iounmap);241241-242242-/*243243- * __iounmap unmaps nearly everything, so be careful244244- * it doesn't free currently pointer/page tables anymore but it245245- * wans't used anyway and might be added later.246246- */247247-void __iounmap(void *addr, unsigned long size)248248-{249249- unsigned long virtaddr = (unsigned long)addr;250250- pgd_t *pgd_dir;251251- pmd_t *pmd_dir;252252- pte_t *pte_dir;253253-254254- while ((long)size > 0) {255255- pgd_dir = pgd_offset_k(virtaddr);256256- if (pgd_bad(*pgd_dir)) {257257- printk("iounmap: bad pgd(%08lx)\n", pgd_val(*pgd_dir));258258- pgd_clear(pgd_dir);259259- return;260260- }261261- pmd_dir = pmd_offset(pgd_dir, virtaddr);262262-263263- if (CPU_IS_020_OR_030) {264264- int pmd_off = (virtaddr/PTRTREESIZE) & 15;265265- int pmd_type = pmd_dir->pmd[pmd_off] & _DESCTYPE_MASK;266266-267267- if (pmd_type == _PAGE_PRESENT) {268268- pmd_dir->pmd[pmd_off] = 0;269269- virtaddr += PTRTREESIZE;270270- size -= PTRTREESIZE;271271- continue;272272- } else if (pmd_type == 0)273273- continue;274274- }275275-276276- if (pmd_bad(*pmd_dir)) {277277- printk("iounmap: bad pmd (%08lx)\n", pmd_val(*pmd_dir));278278- pmd_clear(pmd_dir);279279- return;280280- }281281- pte_dir = pte_offset_kernel(pmd_dir, virtaddr);282282-283283- pte_val(*pte_dir) = 0;284284- virtaddr += PAGE_SIZE;285285- size -= PAGE_SIZE;286286- }287287-288288- flush_tlb_all();289289-}290290-291291-/*292292- * Set new cache mode for some kernel address space.293293- * The caller must push data for that range itself, if such data may already294294- * be in the cache.295295- */296296-void kernel_set_cachemode(void *addr, unsigned long size, int cmode)297297-{298298- unsigned long virtaddr = (unsigned long)addr;299299- pgd_t *pgd_dir;300300- pmd_t *pmd_dir;301301- pte_t *pte_dir;302302-303303- if (CPU_IS_040_OR_060) {304304- switch (cmode) {305305- case IOMAP_FULL_CACHING:306306- cmode = _PAGE_CACHE040;307307- break;308308- case IOMAP_NOCACHE_SER:309309- default:310310- cmode = _PAGE_NOCACHE_S;311311- break;312312- case IOMAP_NOCACHE_NONSER:313313- cmode = _PAGE_NOCACHE;314314- break;315315- case IOMAP_WRITETHROUGH:316316- cmode = _PAGE_CACHE040W;317317- break;318318- }319319- } else {320320- switch (cmode) {321321- case IOMAP_NOCACHE_SER:322322- case IOMAP_NOCACHE_NONSER:323323- default:324324- cmode = _PAGE_NOCACHE030;325325- break;326326- case IOMAP_FULL_CACHING:327327- case IOMAP_WRITETHROUGH:328328- cmode = 0;329329- }330330- }331331-332332- while ((long)size > 0) {333333- pgd_dir = pgd_offset_k(virtaddr);334334- if (pgd_bad(*pgd_dir)) {335335- printk("iocachemode: bad pgd(%08lx)\n", pgd_val(*pgd_dir));336336- pgd_clear(pgd_dir);337337- return;338338- }339339- pmd_dir = pmd_offset(pgd_dir, virtaddr);340340-341341- if (CPU_IS_020_OR_030) {342342- int pmd_off = (virtaddr/PTRTREESIZE) & 15;343343-344344- if ((pmd_dir->pmd[pmd_off] & _DESCTYPE_MASK) == _PAGE_PRESENT) {345345- pmd_dir->pmd[pmd_off] = (pmd_dir->pmd[pmd_off] &346346- _CACHEMASK040) | cmode;347347- virtaddr += PTRTREESIZE;348348- size -= PTRTREESIZE;349349- continue;350350- }351351- }352352-353353- if (pmd_bad(*pmd_dir)) {354354- printk("iocachemode: bad pmd (%08lx)\n", pmd_val(*pmd_dir));355355- pmd_clear(pmd_dir);356356- return;357357- }358358- pte_dir = pte_offset_kernel(pmd_dir, virtaddr);359359-360360- pte_val(*pte_dir) = (pte_val(*pte_dir) & _CACHEMASK040) | cmode;361361- virtaddr += PAGE_SIZE;362362- size -= PAGE_SIZE;363363- }364364-365365- flush_tlb_all();366366-}367367-EXPORT_SYMBOL(kernel_set_cachemode);
+367
arch/m68k/mm/kmap_mm.c
···11+/*22+ * linux/arch/m68k/mm/kmap.c33+ *44+ * Copyright (C) 1997 Roman Hodek55+ *66+ * 10/01/99 cleaned up the code and changing to the same interface77+ * used by other architectures /Roman Zippel88+ */99+1010+#include <linux/module.h>1111+#include <linux/mm.h>1212+#include <linux/kernel.h>1313+#include <linux/string.h>1414+#include <linux/types.h>1515+#include <linux/slab.h>1616+#include <linux/vmalloc.h>1717+1818+#include <asm/setup.h>1919+#include <asm/segment.h>2020+#include <asm/page.h>2121+#include <asm/pgalloc.h>2222+#include <asm/io.h>2323+#include <asm/system.h>2424+2525+#undef DEBUG2626+2727+#define PTRTREESIZE (256*1024)2828+2929+/*3030+ * For 040/060 we can use the virtual memory area like other architectures,3131+ * but for 020/030 we want to use early termination page descriptor and we3232+ * can't mix this with normal page descriptors, so we have to copy that code3333+ * (mm/vmalloc.c) and return appriorate aligned addresses.3434+ */3535+3636+#ifdef CPU_M68040_OR_M68060_ONLY3737+3838+#define IO_SIZE PAGE_SIZE3939+4040+static inline struct vm_struct *get_io_area(unsigned long size)4141+{4242+ return get_vm_area(size, VM_IOREMAP);4343+}4444+4545+4646+static inline void free_io_area(void *addr)4747+{4848+ vfree((void *)(PAGE_MASK & (unsigned long)addr));4949+}5050+5151+#else5252+5353+#define IO_SIZE (256*1024)5454+5555+static struct vm_struct *iolist;5656+5757+static struct vm_struct *get_io_area(unsigned long size)5858+{5959+ unsigned long addr;6060+ struct vm_struct **p, *tmp, *area;6161+6262+ area = kmalloc(sizeof(*area), GFP_KERNEL);6363+ if (!area)6464+ return NULL;6565+ addr = KMAP_START;6666+ for (p = &iolist; (tmp = *p) ; p = &tmp->next) {6767+ if (size + addr < (unsigned long)tmp->addr)6868+ break;6969+ if (addr > KMAP_END-size) {7070+ kfree(area);7171+ return NULL;7272+ }7373+ addr = tmp->size + (unsigned long)tmp->addr;7474+ }7575+ area->addr = (void *)addr;7676+ area->size = size + IO_SIZE;7777+ area->next = *p;7878+ *p = area;7979+ return area;8080+}8181+8282+static inline void free_io_area(void *addr)8383+{8484+ struct vm_struct **p, *tmp;8585+8686+ if (!addr)8787+ return;8888+ addr = (void *)((unsigned long)addr & -IO_SIZE);8989+ for (p = &iolist ; (tmp = *p) ; p = &tmp->next) {9090+ if (tmp->addr == addr) {9191+ *p = tmp->next;9292+ __iounmap(tmp->addr, tmp->size);9393+ kfree(tmp);9494+ return;9595+ }9696+ }9797+}9898+9999+#endif100100+101101+/*102102+ * Map some physical address range into the kernel address space.103103+ */104104+/* Rewritten by Andreas Schwab to remove all races. */105105+106106+void __iomem *__ioremap(unsigned long physaddr, unsigned long size, int cacheflag)107107+{108108+ struct vm_struct *area;109109+ unsigned long virtaddr, retaddr;110110+ long offset;111111+ pgd_t *pgd_dir;112112+ pmd_t *pmd_dir;113113+ pte_t *pte_dir;114114+115115+ /*116116+ * Don't allow mappings that wrap..117117+ */118118+ if (!size || physaddr > (unsigned long)(-size))119119+ return NULL;120120+121121+#ifdef CONFIG_AMIGA122122+ if (MACH_IS_AMIGA) {123123+ if ((physaddr >= 0x40000000) && (physaddr + size < 0x60000000)124124+ && (cacheflag == IOMAP_NOCACHE_SER))125125+ return (void __iomem *)physaddr;126126+ }127127+#endif128128+129129+#ifdef DEBUG130130+ printk("ioremap: 0x%lx,0x%lx(%d) - ", physaddr, size, cacheflag);131131+#endif132132+ /*133133+ * Mappings have to be aligned134134+ */135135+ offset = physaddr & (IO_SIZE - 1);136136+ physaddr &= -IO_SIZE;137137+ size = (size + offset + IO_SIZE - 1) & -IO_SIZE;138138+139139+ /*140140+ * Ok, go for it..141141+ */142142+ area = get_io_area(size);143143+ if (!area)144144+ return NULL;145145+146146+ virtaddr = (unsigned long)area->addr;147147+ retaddr = virtaddr + offset;148148+#ifdef DEBUG149149+ printk("0x%lx,0x%lx,0x%lx", physaddr, virtaddr, retaddr);150150+#endif151151+152152+ /*153153+ * add cache and table flags to physical address154154+ */155155+ if (CPU_IS_040_OR_060) {156156+ physaddr |= (_PAGE_PRESENT | _PAGE_GLOBAL040 |157157+ _PAGE_ACCESSED | _PAGE_DIRTY);158158+ switch (cacheflag) {159159+ case IOMAP_FULL_CACHING:160160+ physaddr |= _PAGE_CACHE040;161161+ break;162162+ case IOMAP_NOCACHE_SER:163163+ default:164164+ physaddr |= _PAGE_NOCACHE_S;165165+ break;166166+ case IOMAP_NOCACHE_NONSER:167167+ physaddr |= _PAGE_NOCACHE;168168+ break;169169+ case IOMAP_WRITETHROUGH:170170+ physaddr |= _PAGE_CACHE040W;171171+ break;172172+ }173173+ } else {174174+ physaddr |= (_PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_DIRTY);175175+ switch (cacheflag) {176176+ case IOMAP_NOCACHE_SER:177177+ case IOMAP_NOCACHE_NONSER:178178+ default:179179+ physaddr |= _PAGE_NOCACHE030;180180+ break;181181+ case IOMAP_FULL_CACHING:182182+ case IOMAP_WRITETHROUGH:183183+ break;184184+ }185185+ }186186+187187+ while ((long)size > 0) {188188+#ifdef DEBUG189189+ if (!(virtaddr & (PTRTREESIZE-1)))190190+ printk ("\npa=%#lx va=%#lx ", physaddr, virtaddr);191191+#endif192192+ pgd_dir = pgd_offset_k(virtaddr);193193+ pmd_dir = pmd_alloc(&init_mm, pgd_dir, virtaddr);194194+ if (!pmd_dir) {195195+ printk("ioremap: no mem for pmd_dir\n");196196+ return NULL;197197+ }198198+199199+ if (CPU_IS_020_OR_030) {200200+ pmd_dir->pmd[(virtaddr/PTRTREESIZE) & 15] = physaddr;201201+ physaddr += PTRTREESIZE;202202+ virtaddr += PTRTREESIZE;203203+ size -= PTRTREESIZE;204204+ } else {205205+ pte_dir = pte_alloc_kernel(pmd_dir, virtaddr);206206+ if (!pte_dir) {207207+ printk("ioremap: no mem for pte_dir\n");208208+ return NULL;209209+ }210210+211211+ pte_val(*pte_dir) = physaddr;212212+ virtaddr += PAGE_SIZE;213213+ physaddr += PAGE_SIZE;214214+ size -= PAGE_SIZE;215215+ }216216+ }217217+#ifdef DEBUG218218+ printk("\n");219219+#endif220220+ flush_tlb_all();221221+222222+ return (void __iomem *)retaddr;223223+}224224+EXPORT_SYMBOL(__ioremap);225225+226226+/*227227+ * Unmap a ioremap()ed region again228228+ */229229+void iounmap(void __iomem *addr)230230+{231231+#ifdef CONFIG_AMIGA232232+ if ((!MACH_IS_AMIGA) ||233233+ (((unsigned long)addr < 0x40000000) ||234234+ ((unsigned long)addr > 0x60000000)))235235+ free_io_area((__force void *)addr);236236+#else237237+ free_io_area((__force void *)addr);238238+#endif239239+}240240+EXPORT_SYMBOL(iounmap);241241+242242+/*243243+ * __iounmap unmaps nearly everything, so be careful244244+ * it doesn't free currently pointer/page tables anymore but it245245+ * wans't used anyway and might be added later.246246+ */247247+void __iounmap(void *addr, unsigned long size)248248+{249249+ unsigned long virtaddr = (unsigned long)addr;250250+ pgd_t *pgd_dir;251251+ pmd_t *pmd_dir;252252+ pte_t *pte_dir;253253+254254+ while ((long)size > 0) {255255+ pgd_dir = pgd_offset_k(virtaddr);256256+ if (pgd_bad(*pgd_dir)) {257257+ printk("iounmap: bad pgd(%08lx)\n", pgd_val(*pgd_dir));258258+ pgd_clear(pgd_dir);259259+ return;260260+ }261261+ pmd_dir = pmd_offset(pgd_dir, virtaddr);262262+263263+ if (CPU_IS_020_OR_030) {264264+ int pmd_off = (virtaddr/PTRTREESIZE) & 15;265265+ int pmd_type = pmd_dir->pmd[pmd_off] & _DESCTYPE_MASK;266266+267267+ if (pmd_type == _PAGE_PRESENT) {268268+ pmd_dir->pmd[pmd_off] = 0;269269+ virtaddr += PTRTREESIZE;270270+ size -= PTRTREESIZE;271271+ continue;272272+ } else if (pmd_type == 0)273273+ continue;274274+ }275275+276276+ if (pmd_bad(*pmd_dir)) {277277+ printk("iounmap: bad pmd (%08lx)\n", pmd_val(*pmd_dir));278278+ pmd_clear(pmd_dir);279279+ return;280280+ }281281+ pte_dir = pte_offset_kernel(pmd_dir, virtaddr);282282+283283+ pte_val(*pte_dir) = 0;284284+ virtaddr += PAGE_SIZE;285285+ size -= PAGE_SIZE;286286+ }287287+288288+ flush_tlb_all();289289+}290290+291291+/*292292+ * Set new cache mode for some kernel address space.293293+ * The caller must push data for that range itself, if such data may already294294+ * be in the cache.295295+ */296296+void kernel_set_cachemode(void *addr, unsigned long size, int cmode)297297+{298298+ unsigned long virtaddr = (unsigned long)addr;299299+ pgd_t *pgd_dir;300300+ pmd_t *pmd_dir;301301+ pte_t *pte_dir;302302+303303+ if (CPU_IS_040_OR_060) {304304+ switch (cmode) {305305+ case IOMAP_FULL_CACHING:306306+ cmode = _PAGE_CACHE040;307307+ break;308308+ case IOMAP_NOCACHE_SER:309309+ default:310310+ cmode = _PAGE_NOCACHE_S;311311+ break;312312+ case IOMAP_NOCACHE_NONSER:313313+ cmode = _PAGE_NOCACHE;314314+ break;315315+ case IOMAP_WRITETHROUGH:316316+ cmode = _PAGE_CACHE040W;317317+ break;318318+ }319319+ } else {320320+ switch (cmode) {321321+ case IOMAP_NOCACHE_SER:322322+ case IOMAP_NOCACHE_NONSER:323323+ default:324324+ cmode = _PAGE_NOCACHE030;325325+ break;326326+ case IOMAP_FULL_CACHING:327327+ case IOMAP_WRITETHROUGH:328328+ cmode = 0;329329+ }330330+ }331331+332332+ while ((long)size > 0) {333333+ pgd_dir = pgd_offset_k(virtaddr);334334+ if (pgd_bad(*pgd_dir)) {335335+ printk("iocachemode: bad pgd(%08lx)\n", pgd_val(*pgd_dir));336336+ pgd_clear(pgd_dir);337337+ return;338338+ }339339+ pmd_dir = pmd_offset(pgd_dir, virtaddr);340340+341341+ if (CPU_IS_020_OR_030) {342342+ int pmd_off = (virtaddr/PTRTREESIZE) & 15;343343+344344+ if ((pmd_dir->pmd[pmd_off] & _DESCTYPE_MASK) == _PAGE_PRESENT) {345345+ pmd_dir->pmd[pmd_off] = (pmd_dir->pmd[pmd_off] &346346+ _CACHEMASK040) | cmode;347347+ virtaddr += PTRTREESIZE;348348+ size -= PTRTREESIZE;349349+ continue;350350+ }351351+ }352352+353353+ if (pmd_bad(*pmd_dir)) {354354+ printk("iocachemode: bad pmd (%08lx)\n", pmd_val(*pmd_dir));355355+ pmd_clear(pmd_dir);356356+ return;357357+ }358358+ pte_dir = pte_offset_kernel(pmd_dir, virtaddr);359359+360360+ pte_val(*pte_dir) = (pte_val(*pte_dir) & _CACHEMASK040) | cmode;361361+ virtaddr += PAGE_SIZE;362362+ size -= PAGE_SIZE;363363+ }364364+365365+ flush_tlb_all();366366+}367367+EXPORT_SYMBOL(kernel_set_cachemode);
-94
arch/m68knommu/Kconfig
arch/m68k/Kconfig.nommu
···11-config M68K22- bool33- default y44- select HAVE_IDE55- select HAVE_GENERIC_HARDIRQS66- select GENERIC_HARDIRQS_NO_DEPRECATED77-88-config MMU99- bool1010- default n1111-1212-config NO_DMA1313- bool1414- depends on !COLDFIRE1515- default y1616-171config FPU1818- bool1919- default n2020-2121-config ZONE_DMA2222- bool2323- default y2424-2525-config RWSEM_GENERIC_SPINLOCK2626- bool2727- default y2828-2929-config RWSEM_XCHGADD_ALGORITHM3030- bool3131- default n3232-3333-config ARCH_HAS_ILOG2_U323434- bool3535- default n3636-3737-config ARCH_HAS_ILOG2_U64382 bool393 default n404···1046 bool1147 default n12481313-config GENERIC_HWEIGHT1414- bool1515- default y1616-1717-config GENERIC_CALIBRATE_DELAY1818- bool1919- default y2020-2149config GENERIC_CMOS_UPDATE2222- bool2323- default y2424-2525-config TIME_LOW_RES2650 bool2751 default y28522953config GENERIC_CLOCKEVENTS3054 bool3155 default n3232-3333-config NO_IOPORT3434- def_bool y35563657config COLDFIRE_SW_A73758 bool···33843485config HAVE_IPSBAR3586 bool3636-3737-source "init/Kconfig"3838-3939-source "kernel/Kconfig.freezer"4040-4141-menu "Processor type and features"42874388choice4489 prompt "CPU"···573630 running more threads on a system and also reduces the pressure574631 on the VM subsystem for higher order allocations.575632576576-config HZ577577- int578578- default 1000 if CLEOPATRA579579- default 100580580-581633comment "RAM configuration"582634583635config RAMBASE···741803742804source "kernel/time/Kconfig"743805744744-source "mm/Kconfig"745745-746746-endmenu747747-748806config ISA_DMA_API749807 bool750808 depends on !M5272···748814749815source "drivers/pcmcia/Kconfig"750816751751-menu "Executable file formats"752752-753753-source "fs/Kconfig.binfmt"754754-755755-endmenu756756-757757-menu "Power management options"758758-759759-config PM760760- bool "Power Management support"761761- help762762- Support processor power management modes763763-764764-endmenu765765-766766-source "net/Kconfig"767767-768768-source "drivers/Kconfig"769769-770770-source "fs/Kconfig"771771-772772-source "arch/m68knommu/Kconfig.debug"773773-774774-source "security/Kconfig"775775-776776-source "crypto/Kconfig"777777-778778-source "lib/Kconfig"
-35
arch/m68knommu/Kconfig.debug
···11-menu "Kernel hacking"22-33-source "lib/Kconfig.debug"44-55-config FULLDEBUG66- bool "Full Symbolic/Source Debugging support"77- help88- Enable debugging symbols on kernel build.99-1010-config HIGHPROFILE1111- bool "Use fast second timer for profiling"1212- depends on COLDFIRE1313- help1414- Use a fast secondary clock to produce profiling information.1515-1616-config BOOTPARAM1717- bool 'Compiled-in Kernel Boot Parameter'1818-1919-config BOOTPARAM_STRING2020- string 'Kernel Boot Parameter'2121- default 'console=ttyS0,19200'2222- depends on BOOTPARAM2323-2424-config NO_KERNEL_MSG2525- bool "Suppress Kernel BUG Messages"2626- help2727- Do not output any debug BUG messages within the kernel.2828-2929-config BDM_DISABLE3030- bool "Disable BDM signals"3131- depends on (EXPERIMENTAL && COLDFIRE)3232- help3333- Disable the ColdFire CPU's BDM signals.3434-3535-endmenu
+7-9
arch/m68knommu/Makefile
arch/m68k/Makefile_no
···11#22-# arch/m68knommu/Makefile22+# arch/m68k/Makefile33#44# This file is subject to the terms and conditions of the GNU General Public55# License. See the file "COPYING" in the main directory of this archive···77#88# (C) Copyright 2002, Greg Ungerer <gerg@snapgear.com>99#1010-1111-KBUILD_DEFCONFIG := m5208evb_defconfig12101311platform-$(CONFIG_M68328) := 683281412platform-$(CONFIG_M68EZ328) := 68EZ328···8082CPUCLASS := $(cpuclass-y)81838284ifneq ($(CPUCLASS),$(PLATFORM))8383-CLASSDIR := arch/m68knommu/platform/$(cpuclass-y)/8585+CLASSDIR := arch/m68k/platform/$(cpuclass-y)/8486endif85878688export PLATFORM BOARD MODEL CPUCLASS···112114KBUILD_CFLAGS += -D__linux__113115KBUILD_CFLAGS += -DUTS_SYSNAME=\"uClinux\"114116115115-head-y := arch/m68knommu/platform/$(cpuclass-y)/head.o117117+head-y := arch/m68k/platform/$(cpuclass-y)/head.o116118117117-core-y += arch/m68knommu/kernel/ \118118- arch/m68knommu/mm/ \119119+core-y += arch/m68k/kernel/ \120120+ arch/m68k/mm/ \119121 $(CLASSDIR) \120120- arch/m68knommu/platform/$(PLATFORM)/121121-libs-y += arch/m68knommu/lib/122122+ arch/m68k/platform/$(PLATFORM)/123123+libs-y += arch/m68k/lib/122124123125archclean:124126
···11+# CONFIG_MMU is not set12CONFIG_EXPERIMENTAL=y23CONFIG_LOG_BUF_SHIFT=1434# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set···1211# CONFIG_EVENTFD is not set1312# CONFIG_AIO is not set1413# CONFIG_VM_EVENT_COUNTERS is not set1515-# CONFIG_COMPAT_BRK is not set1414+# CONFIG_SLUB_DEBUG is not set1615# CONFIG_BLK_DEV_BSG is not set1716# CONFIG_IOSCHED_DEADLINE is not set1817# CONFIG_IOSCHED_CFQ is not set1919-CONFIG_M520x=y1818+CONFIG_M5307=y2019CONFIG_CLOCK_SET=y2121-CONFIG_CLOCK_FREQ=1666666662020+CONFIG_CLOCK_FREQ=900000002221CONFIG_CLOCK_DIV=22323-CONFIG_M5208EVB=y2424-# CONFIG_4KSTACKS is not set2525-CONFIG_RAMBASE=0x400000002626-CONFIG_RAMSIZE=0x20000002727-CONFIG_VECTORBASE=0x400000002828-CONFIG_KERNELBASE=0x400200002929-CONFIG_RAM16BIT=y2222+CONFIG_M5307C3=y2323+CONFIG_RAMBASE=0x000000002424+CONFIG_RAMSIZE=0x008000002525+CONFIG_VECTORBASE=0x000000002626+CONFIG_KERNELBASE=0x000200003027CONFIG_BINFMT_FLAT=y3128CONFIG_NET=y3229CONFIG_PACKET=y···3637# CONFIG_INET_LRO is not set3738# CONFIG_INET_DIAG is not set3839# CONFIG_IPV6 is not set4040+# CONFIG_FW_LOADER is not set3941CONFIG_MTD=y4042CONFIG_MTD_PARTITIONS=y4143CONFIG_MTD_CHAR=y···4747# CONFIG_MISC_DEVICES is not set4848CONFIG_NETDEVICES=y4949CONFIG_NET_ETHERNET=y5050-CONFIG_FEC=y5150# CONFIG_NETDEV_1000 is not set5251# CONFIG_NETDEV_10000 is not set5353-# CONFIG_INPUT is not set5252+CONFIG_PPP=y5353+CONFIG_SLIP=y5454+CONFIG_SLIP_COMPRESSED=y5555+# CONFIG_INPUT_MOUSEDEV is not set5656+# CONFIG_INPUT_KEYBOARD is not set5757+# CONFIG_INPUT_MOUSE is not set5458# CONFIG_SERIO is not set5559# CONFIG_VT is not set5660CONFIG_SERIAL_MCF=y5757-CONFIG_SERIAL_MCF_BAUDRATE=1152005861CONFIG_SERIAL_MCF_CONSOLE=y5959-# CONFIG_UNIX98_PTYS is not set6262+# CONFIG_LEGACY_PTYS is not set6063# CONFIG_HW_RANDOM is not set6164# CONFIG_HWMON is not set6565+# CONFIG_HID_SUPPORT is not set6266# CONFIG_USB_SUPPORT is not set6367CONFIG_EXT2_FS=y6464-# CONFIG_FILE_LOCKING is not set6568# CONFIG_DNOTIFY is not set6666-# CONFIG_SYSFS is not set6769CONFIG_ROMFS_FS=y6870CONFIG_ROMFS_BACKED_BY_MTD=y6971# CONFIG_NETWORK_FILESYSTEMS is not set···7472CONFIG_FULLDEBUG=y7573CONFIG_BOOTPARAM=y7674CONFIG_BOOTPARAM_STRING="root=/dev/mtdblock0"7575+# CONFIG_CRC32 is not set
···11+# CONFIG_MMU is not set12CONFIG_EXPERIMENTAL=y23CONFIG_LOG_BUF_SHIFT=1434# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set···1615# CONFIG_BLK_DEV_BSG is not set1716# CONFIG_IOSCHED_DEADLINE is not set1817# CONFIG_IOSCHED_CFQ is not set1919-CONFIG_M5249=y1818+CONFIG_M5275=y2019CONFIG_CLOCK_SET=y2121-CONFIG_CLOCK_FREQ=1400000002020+CONFIG_CLOCK_FREQ=1500000002221CONFIG_CLOCK_DIV=22323-CONFIG_M5249C3=y2222+CONFIG_M5275EVB=y2323+# CONFIG_4KSTACKS is not set2424CONFIG_RAMBASE=0x000000002525-CONFIG_RAMSIZE=0x008000002525+CONFIG_RAMSIZE=0x000000002626CONFIG_VECTORBASE=0x000000002727CONFIG_KERNELBASE=0x000200002828CONFIG_BINFMT_FLAT=y···3735# CONFIG_INET_LRO is not set3836# CONFIG_INET_DIAG is not set3937# CONFIG_IPV6 is not set3838+# CONFIG_FW_LOADER is not set4039CONFIG_MTD=y4140CONFIG_MTD_PARTITIONS=y4241CONFIG_MTD_CHAR=y···4845# CONFIG_MISC_DEVICES is not set4946CONFIG_NETDEVICES=y5047CONFIG_NET_ETHERNET=y4848+CONFIG_FEC=y4949+CONFIG_FEC2=y5150# CONFIG_NETDEV_1000 is not set5251# CONFIG_NETDEV_10000 is not set5352CONFIG_PPP=y···6358# CONFIG_USB_SUPPORT is not set6459CONFIG_EXT2_FS=y6560# CONFIG_FILE_LOCKING is not set6161+# CONFIG_DNOTIFY is not set6662CONFIG_ROMFS_FS=y6763CONFIG_ROMFS_BACKED_BY_MTD=y6864# CONFIG_NETWORK_FILESYSTEMS is not set6965# CONFIG_RCU_CPU_STALL_DETECTOR is not set6666+CONFIG_SYSCTL_SYSCALL_CHECK=y7067CONFIG_BOOTPARAM=y7168CONFIG_BOOTPARAM_STRING="root=/dev/mtdblock0"7269# CONFIG_CRC32 is not set
···11+# CONFIG_MMU is not set12CONFIG_EXPERIMENTAL=y23CONFIG_LOG_BUF_SHIFT=1434# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set···1211# CONFIG_EVENTFD is not set1312# CONFIG_AIO is not set1413# CONFIG_VM_EVENT_COUNTERS is not set1515-# CONFIG_SLUB_DEBUG is not set1414+CONFIG_MODULES=y1515+CONFIG_MODULE_UNLOAD=y1616# CONFIG_BLK_DEV_BSG is not set1717# CONFIG_IOSCHED_DEADLINE is not set1818# CONFIG_IOSCHED_CFQ is not set1919-CONFIG_M5272=y1919+CONFIG_M5407=y2020CONFIG_CLOCK_SET=y2121-CONFIG_M5272C3=y2121+CONFIG_CLOCK_FREQ=500000002222+CONFIG_M5407C3=y2223CONFIG_RAMBASE=0x000000002323-CONFIG_RAMSIZE=0x008000002424+CONFIG_RAMSIZE=0x000000002425CONFIG_VECTORBASE=0x000000002526CONFIG_KERNELBASE=0x000200002627CONFIG_BINFMT_FLAT=y···3633# CONFIG_INET_LRO is not set3734# CONFIG_INET_DIAG is not set3835# CONFIG_IPV6 is not set3636+# CONFIG_FW_LOADER is not set3937CONFIG_MTD=y4038CONFIG_MTD_PARTITIONS=y4139CONFIG_MTD_CHAR=y···4743# CONFIG_MISC_DEVICES is not set4844CONFIG_NETDEVICES=y4945CONFIG_NET_ETHERNET=y5050-CONFIG_FEC=y5146# CONFIG_NETDEV_1000 is not set5247# CONFIG_NETDEV_10000 is not set4848+CONFIG_PPP=y5349# CONFIG_INPUT is not set5454-# CONFIG_SERIO is not set5550# CONFIG_VT is not set5651CONFIG_SERIAL_MCF=y5752CONFIG_SERIAL_MCF_CONSOLE=y5853# CONFIG_UNIX98_PTYS is not set5454+# CONFIG_HW_RANDOM is not set5955# CONFIG_HWMON is not set6056# CONFIG_USB_SUPPORT is not set6157CONFIG_EXT2_FS=y···6561CONFIG_ROMFS_BACKED_BY_MTD=y6662# CONFIG_NETWORK_FILESYSTEMS is not set6763# CONFIG_RCU_CPU_STALL_DETECTOR is not set6464+CONFIG_SYSCTL_SYSCALL_CHECK=y6865CONFIG_BOOTPARAM=y6966CONFIG_BOOTPARAM_STRING="root=/dev/mtdblock0"6767+# CONFIG_CRC32 is not set
-72
arch/m68knommu/configs/m5275evb_defconfig
···11-CONFIG_EXPERIMENTAL=y22-CONFIG_LOG_BUF_SHIFT=1433-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set44-CONFIG_EXPERT=y55-# CONFIG_KALLSYMS is not set66-# CONFIG_HOTPLUG is not set77-# CONFIG_FUTEX is not set88-# CONFIG_EPOLL is not set99-# CONFIG_SIGNALFD is not set1010-# CONFIG_TIMERFD is not set1111-# CONFIG_EVENTFD is not set1212-# CONFIG_AIO is not set1313-# CONFIG_VM_EVENT_COUNTERS is not set1414-# CONFIG_SLUB_DEBUG is not set1515-# CONFIG_BLK_DEV_BSG is not set1616-# CONFIG_IOSCHED_DEADLINE is not set1717-# CONFIG_IOSCHED_CFQ is not set1818-CONFIG_M5275=y1919-CONFIG_CLOCK_SET=y2020-CONFIG_CLOCK_FREQ=1500000002121-CONFIG_CLOCK_DIV=22222-CONFIG_M5275EVB=y2323-# CONFIG_4KSTACKS is not set2424-CONFIG_RAMBASE=0x000000002525-CONFIG_RAMSIZE=0x000000002626-CONFIG_VECTORBASE=0x000000002727-CONFIG_KERNELBASE=0x000200002828-CONFIG_BINFMT_FLAT=y2929-CONFIG_NET=y3030-CONFIG_PACKET=y3131-CONFIG_UNIX=y3232-CONFIG_INET=y3333-# CONFIG_INET_XFRM_MODE_TRANSPORT is not set3434-# CONFIG_INET_XFRM_MODE_TUNNEL is not set3535-# CONFIG_INET_XFRM_MODE_BEET is not set3636-# CONFIG_INET_LRO is not set3737-# CONFIG_INET_DIAG is not set3838-# CONFIG_IPV6 is not set3939-CONFIG_MTD=y4040-CONFIG_MTD_PARTITIONS=y4141-CONFIG_MTD_CHAR=y4242-CONFIG_MTD_BLOCK=y4343-CONFIG_MTD_RAM=y4444-CONFIG_MTD_UCLINUX=y4545-CONFIG_BLK_DEV_RAM=y4646-# CONFIG_MISC_DEVICES is not set4747-CONFIG_NETDEVICES=y4848-CONFIG_NET_ETHERNET=y4949-CONFIG_FEC=y5050-CONFIG_FEC2=y5151-# CONFIG_NETDEV_1000 is not set5252-# CONFIG_NETDEV_10000 is not set5353-CONFIG_PPP=y5454-# CONFIG_INPUT is not set5555-# CONFIG_SERIO is not set5656-# CONFIG_VT is not set5757-CONFIG_SERIAL_MCF=y5858-CONFIG_SERIAL_MCF_CONSOLE=y5959-# CONFIG_UNIX98_PTYS is not set6060-# CONFIG_HWMON is not set6161-# CONFIG_USB_SUPPORT is not set6262-CONFIG_EXT2_FS=y6363-# CONFIG_FILE_LOCKING is not set6464-# CONFIG_DNOTIFY is not set6565-CONFIG_ROMFS_FS=y6666-CONFIG_ROMFS_BACKED_BY_MTD=y6767-# CONFIG_NETWORK_FILESYSTEMS is not set6868-# CONFIG_RCU_CPU_STALL_DETECTOR is not set6969-CONFIG_SYSCTL_SYSCALL_CHECK=y7070-CONFIG_BOOTPARAM=y7171-CONFIG_BOOTPARAM_STRING="root=/dev/mtdblock0"7272-# CONFIG_CRC32 is not set
···11+# CONFIG_MMU is not set12CONFIG_EXPERIMENTAL=y23CONFIG_LOG_BUF_SHIFT=1434# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set···1211# CONFIG_EVENTFD is not set1312# CONFIG_AIO is not set1413# CONFIG_VM_EVENT_COUNTERS is not set1515-# CONFIG_SLUB_DEBUG is not set1414+# CONFIG_COMPAT_BRK is not set1615# CONFIG_BLK_DEV_BSG is not set1716# CONFIG_IOSCHED_DEADLINE is not set1817# CONFIG_IOSCHED_CFQ is not set1919-CONFIG_M5307=y1818+CONFIG_M520x=y2019CONFIG_CLOCK_SET=y2121-CONFIG_CLOCK_FREQ=900000002020+CONFIG_CLOCK_FREQ=1666666662221CONFIG_CLOCK_DIV=22323-CONFIG_M5307C3=y2424-CONFIG_RAMBASE=0x000000002525-CONFIG_RAMSIZE=0x008000002626-CONFIG_VECTORBASE=0x000000002727-CONFIG_KERNELBASE=0x000200002222+CONFIG_M5208EVB=y2323+# CONFIG_4KSTACKS is not set2424+CONFIG_RAMBASE=0x400000002525+CONFIG_RAMSIZE=0x20000002626+CONFIG_VECTORBASE=0x400000002727+CONFIG_KERNELBASE=0x400200002828+CONFIG_RAM16BIT=y2829CONFIG_BINFMT_FLAT=y2930CONFIG_NET=y3031CONFIG_PACKET=y···3835# CONFIG_INET_LRO is not set3936# CONFIG_INET_DIAG is not set4037# CONFIG_IPV6 is not set3838+# CONFIG_FW_LOADER is not set4139CONFIG_MTD=y4240CONFIG_MTD_PARTITIONS=y4341CONFIG_MTD_CHAR=y···4945# CONFIG_MISC_DEVICES is not set5046CONFIG_NETDEVICES=y5147CONFIG_NET_ETHERNET=y4848+CONFIG_FEC=y5249# CONFIG_NETDEV_1000 is not set5350# CONFIG_NETDEV_10000 is not set5454-CONFIG_PPP=y5555-CONFIG_SLIP=y5656-CONFIG_SLIP_COMPRESSED=y5757-# CONFIG_INPUT_MOUSEDEV is not set5858-# CONFIG_INPUT_KEYBOARD is not set5959-# CONFIG_INPUT_MOUSE is not set5151+# CONFIG_INPUT is not set6052# CONFIG_SERIO is not set6153# CONFIG_VT is not set6254CONFIG_SERIAL_MCF=y5555+CONFIG_SERIAL_MCF_BAUDRATE=1152006356CONFIG_SERIAL_MCF_CONSOLE=y6464-# CONFIG_LEGACY_PTYS is not set5757+# CONFIG_UNIX98_PTYS is not set6558# CONFIG_HW_RANDOM is not set6659# CONFIG_HWMON is not set6767-# CONFIG_HID_SUPPORT is not set6860# CONFIG_USB_SUPPORT is not set6961CONFIG_EXT2_FS=y6262+# CONFIG_FILE_LOCKING is not set7063# CONFIG_DNOTIFY is not set6464+# CONFIG_SYSFS is not set7165CONFIG_ROMFS_FS=y7266CONFIG_ROMFS_BACKED_BY_MTD=y7367# CONFIG_NETWORK_FILESYSTEMS is not set···7472CONFIG_FULLDEBUG=y7573CONFIG_BOOTPARAM=y7674CONFIG_BOOTPARAM_STRING="root=/dev/mtdblock0"7777-# CONFIG_CRC32 is not set
···11+# CONFIG_MMU is not set12CONFIG_EXPERIMENTAL=y23CONFIG_LOG_BUF_SHIFT=1434# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set···1211# CONFIG_EVENTFD is not set1312# CONFIG_AIO is not set1413# CONFIG_VM_EVENT_COUNTERS is not set1515-CONFIG_MODULES=y1616-CONFIG_MODULE_UNLOAD=y1414+# CONFIG_SLUB_DEBUG is not set1715# CONFIG_BLK_DEV_BSG is not set1816# CONFIG_IOSCHED_DEADLINE is not set1917# CONFIG_IOSCHED_CFQ is not set2020-CONFIG_M5407=y1818+CONFIG_M5249=y2119CONFIG_CLOCK_SET=y2222-CONFIG_CLOCK_FREQ=500000002323-CONFIG_M5407C3=y2020+CONFIG_CLOCK_FREQ=1400000002121+CONFIG_CLOCK_DIV=22222+CONFIG_M5249C3=y2423CONFIG_RAMBASE=0x000000002525-CONFIG_RAMSIZE=0x000000002424+CONFIG_RAMSIZE=0x008000002625CONFIG_VECTORBASE=0x000000002726CONFIG_KERNELBASE=0x000200002827CONFIG_BINFMT_FLAT=y···3635# CONFIG_INET_LRO is not set3736# CONFIG_INET_DIAG is not set3837# CONFIG_IPV6 is not set3838+# CONFIG_FW_LOADER is not set3939CONFIG_MTD=y4040CONFIG_MTD_PARTITIONS=y4141CONFIG_MTD_CHAR=y···5149# CONFIG_NETDEV_10000 is not set5250CONFIG_PPP=y5351# CONFIG_INPUT is not set5252+# CONFIG_SERIO is not set5453# CONFIG_VT is not set5554CONFIG_SERIAL_MCF=y5655CONFIG_SERIAL_MCF_CONSOLE=y5756# CONFIG_UNIX98_PTYS is not set5858-# CONFIG_HW_RANDOM is not set5957# CONFIG_HWMON is not set6058# CONFIG_USB_SUPPORT is not set6159CONFIG_EXT2_FS=y6260# CONFIG_FILE_LOCKING is not set6363-# CONFIG_DNOTIFY is not set6461CONFIG_ROMFS_FS=y6562CONFIG_ROMFS_BACKED_BY_MTD=y6663# CONFIG_NETWORK_FILESYSTEMS is not set6764# CONFIG_RCU_CPU_STALL_DETECTOR is not set6868-CONFIG_SYSCTL_SYSCALL_CHECK=y6965CONFIG_BOOTPARAM=y7066CONFIG_BOOTPARAM_STRING="root=/dev/mtdblock0"7167# CONFIG_CRC32 is not set
···11+# CONFIG_MMU is not set12CONFIG_EXPERIMENTAL=y23CONFIG_LOG_BUF_SHIFT=1434# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set···1211# CONFIG_EVENTFD is not set1312# CONFIG_AIO is not set1413# CONFIG_VM_EVENT_COUNTERS is not set1515-# CONFIG_COMPAT_BRK is not set1414+# CONFIG_SLUB_DEBUG is not set1615# CONFIG_BLK_DEV_BSG is not set1716# CONFIG_IOSCHED_DEADLINE is not set1817# CONFIG_IOSCHED_CFQ is not set1919-CONFIG_M520x=y1818+CONFIG_M5272=y2019CONFIG_CLOCK_SET=y2121-CONFIG_CLOCK_FREQ=1666666662222-CONFIG_CLOCK_DIV=22323-CONFIG_M5208EVB=y2424-# CONFIG_4KSTACKS is not set2525-CONFIG_RAMBASE=0x400000002626-CONFIG_RAMSIZE=0x20000002727-CONFIG_VECTORBASE=0x400000002828-CONFIG_KERNELBASE=0x400200002929-CONFIG_RAM16BIT=y2020+CONFIG_M5272C3=y2121+CONFIG_RAMBASE=0x000000002222+CONFIG_RAMSIZE=0x008000002323+CONFIG_VECTORBASE=0x000000002424+CONFIG_KERNELBASE=0x000200003025CONFIG_BINFMT_FLAT=y3126CONFIG_NET=y3227CONFIG_PACKET=y···3437# CONFIG_INET_LRO is not set3538# CONFIG_INET_DIAG is not set3639# CONFIG_IPV6 is not set4040+# CONFIG_FW_LOADER is not set3741CONFIG_MTD=y3842CONFIG_MTD_PARTITIONS=y3943CONFIG_MTD_CHAR=y···5254# CONFIG_SERIO is not set5355# CONFIG_VT is not set5456CONFIG_SERIAL_MCF=y5555-CONFIG_SERIAL_MCF_BAUDRATE=1152005657CONFIG_SERIAL_MCF_CONSOLE=y5758# CONFIG_UNIX98_PTYS is not set5858-# CONFIG_HW_RANDOM is not set5959# CONFIG_HWMON is not set6060# CONFIG_USB_SUPPORT is not set6161CONFIG_EXT2_FS=y6262# CONFIG_FILE_LOCKING is not set6363# CONFIG_DNOTIFY is not set6464-# CONFIG_SYSFS is not set6564CONFIG_ROMFS_FS=y6665CONFIG_ROMFS_BACKED_BY_MTD=y6766# CONFIG_NETWORK_FILESYSTEMS is not set6867# CONFIG_RCU_CPU_STALL_DETECTOR is not set6969-CONFIG_SYSCTL_SYSCALL_CHECK=y7070-CONFIG_FULLDEBUG=y7168CONFIG_BOOTPARAM=y7269CONFIG_BOOTPARAM_STRING="root=/dev/mtdblock0"
···11-/* ashrdi3.c extracted from gcc-2.95.2/libgcc2.c which is: */22-/* Copyright (C) 1989, 92-98, 1999 Free Software Foundation, Inc.11+/* muldi3.c extracted from gcc-2.7.2.3/libgcc2.c and22+ gcc-2.7.2.3/longlong.h which is: */33+/* Copyright (C) 1989, 1992, 1993, 1994, 1995 Free Software Foundation, Inc.3445This file is part of GNU CC.56···21202221#define BITS_PER_UNIT 823222424-typedef int SItype __attribute__ ((mode (SI)));2323+#define umul_ppmm(w1, w0, u, v) \2424+ __asm__ ("mulu%.l %3,%1:%0" \2525+ : "=d" ((USItype)(w0)), \2626+ "=d" ((USItype)(w1)) \2727+ : "%0" ((USItype)(u)), \2828+ "dmi" ((USItype)(v)))2929+3030+#define __umulsidi3(u, v) \3131+ ({DIunion __w; \3232+ umul_ppmm (__w.s.high, __w.s.low, u, v); \3333+ __w.ll; })3434+3535+typedef int SItype __attribute__ ((mode (SI)));2536typedef unsigned int USItype __attribute__ ((mode (SI)));2637typedef int DItype __attribute__ ((mode (DI)));2738typedef int word_type __attribute__ ((mode (__word__)));···4734} DIunion;48354936DItype5050-__ashldi3 (DItype u, word_type b)3737+__muldi3 (DItype u, DItype v)5138{5239 DIunion w;5353- word_type bm;5454- DIunion uu;4040+ DIunion uu, vv;55415656- if (b == 0)5757- return u;4242+ uu.ll = u,4343+ vv.ll = v;58445959- uu.ll = u;6060-6161- bm = (sizeof (SItype) * BITS_PER_UNIT) - b;6262- if (bm <= 0)6363- {6464- w.s.low = 0;6565- w.s.high = (USItype)uu.s.low << -bm;6666- }6767- else6868- {6969- USItype carries = (USItype)uu.s.low >> bm;7070- w.s.low = (USItype)uu.s.low << b;7171- w.s.high = ((USItype)uu.s.high << b) | carries;7272- }4545+ w.ll = __umulsidi3 (uu.s.low, vv.s.low);4646+ w.s.high += ((USItype) uu.s.low * (USItype) vv.s.high4747+ + (USItype) uu.s.high * (USItype) vv.s.low);73487449 return w.ll;7550}
-63
arch/m68knommu/lib/ashrdi3.c
···11-/* ashrdi3.c extracted from gcc-2.7.2/libgcc2.c which is: */22-/* Copyright (C) 1989, 1992, 1993, 1994, 1995 Free Software Foundation, Inc.33-44-This file is part of GNU CC.55-66-GNU CC is free software; you can redistribute it and/or modify77-it under the terms of the GNU General Public License as published by88-the Free Software Foundation; either version 2, or (at your option)99-any later version.1010-1111-GNU CC is distributed in the hope that it will be useful,1212-but WITHOUT ANY WARRANTY; without even the implied warranty of1313-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the1414-GNU General Public License for more details.1515-1616-You should have received a copy of the GNU General Public License1717-along with GNU CC; see the file COPYING. If not, write to1818-the Free Software Foundation, 59 Temple Place - Suite 330,1919-Boston, MA 02111-1307, USA. */2020-2121-#define BITS_PER_UNIT 82222-2323-typedef int SItype __attribute__ ((mode (SI)));2424-typedef unsigned int USItype __attribute__ ((mode (SI)));2525-typedef int DItype __attribute__ ((mode (DI)));2626-typedef int word_type __attribute__ ((mode (__word__)));2727-2828-struct DIstruct {SItype high, low;};2929-3030-typedef union3131-{3232- struct DIstruct s;3333- DItype ll;3434-} DIunion;3535-3636-DItype3737-__ashrdi3 (DItype u, word_type b)3838-{3939- DIunion w;4040- word_type bm;4141- DIunion uu;4242-4343- if (b == 0)4444- return u;4545-4646- uu.ll = u;4747-4848- bm = (sizeof (SItype) * BITS_PER_UNIT) - b;4949- if (bm <= 0)5050- {5151- /* w.s.high = 1..1 or 0..0 */5252- w.s.high = uu.s.high >> (sizeof (SItype) * BITS_PER_UNIT - 1);5353- w.s.low = uu.s.high >> -bm;5454- }5555- else5656- {5757- USItype carries = (USItype)uu.s.high << bm;5858- w.s.high = uu.s.high >> b;5959- w.s.low = ((USItype)uu.s.low >> b) | carries;6060- }6161-6262- return w.ll;6363-}
···11-/* lshrdi3.c extracted from gcc-2.7.2/libgcc2.c which is: */22-/* Copyright (C) 1989, 1992, 1993, 1994, 1995 Free Software Foundation, Inc.33-44-This file is part of GNU CC.55-66-GNU CC is free software; you can redistribute it and/or modify77-it under the terms of the GNU General Public License as published by88-the Free Software Foundation; either version 2, or (at your option)99-any later version.1010-1111-GNU CC is distributed in the hope that it will be useful,1212-but WITHOUT ANY WARRANTY; without even the implied warranty of1313-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the1414-GNU General Public License for more details.1515-1616-You should have received a copy of the GNU General Public License1717-along with GNU CC; see the file COPYING. If not, write to1818-the Free Software Foundation, 59 Temple Place - Suite 330,1919-Boston, MA 02111-1307, USA. */2020-2121-#define BITS_PER_UNIT 82222-2323-typedef int SItype __attribute__ ((mode (SI)));2424-typedef unsigned int USItype __attribute__ ((mode (SI)));2525-typedef int DItype __attribute__ ((mode (DI)));2626-typedef int word_type __attribute__ ((mode (__word__)));2727-2828-struct DIstruct {SItype high, low;};2929-3030-typedef union3131-{3232- struct DIstruct s;3333- DItype ll;3434-} DIunion;3535-3636-DItype3737-__lshrdi3 (DItype u, word_type b)3838-{3939- DIunion w;4040- word_type bm;4141- DIunion uu;4242-4343- if (b == 0)4444- return u;4545-4646- uu.ll = u;4747-4848- bm = (sizeof (SItype) * BITS_PER_UNIT) - b;4949- if (bm <= 0)5050- {5151- w.s.high = 0;5252- w.s.low = (USItype)uu.s.high >> -bm;5353- }5454- else5555- {5656- USItype carries = (USItype)uu.s.high << bm;5757- w.s.high = (USItype)uu.s.high >> b;5858- w.s.low = ((USItype)uu.s.low >> b) | carries;5959- }6060-6161- return w.ll;6262-}