Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/gerg/m68knommu

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/gerg/m68knommu:
m68k: merge m68k and m68knommu arch directories

+6983 -7198
+35 -425
arch/m68k/Kconfig
··· 1 config M68K 2 bool 3 default y 4 - select HAVE_AOUT 5 select HAVE_IDE 6 - select GENERIC_ATOMIC64 7 - 8 - config MMU 9 - bool 10 - default y 11 12 config RWSEM_GENERIC_SPINLOCK 13 bool ··· 32 bool 33 default y 34 35 - config GENERIC_IOMAP 36 - bool 37 - default y 38 - 39 - config ARCH_MAY_HAVE_PC_FDC 40 - bool 41 - depends on BROKEN && (Q40 || SUN3X) 42 - default y 43 - 44 config NO_IOPORT 45 def_bool y 46 47 config NO_DMA 48 - def_bool SUN3 49 50 config HZ 51 int 52 default 100 53 - 54 - config ARCH_USES_GETTIMEOFFSET 55 - def_bool y 56 57 source "init/Kconfig" 58 59 source "kernel/Kconfig.freezer" 60 61 menu "Platform dependent setup" 62 63 - config EISA 64 - bool 65 - ---help--- 66 - The Extended Industry Standard Architecture (EISA) bus was 67 - developed as an open alternative to the IBM MicroChannel bus. 68 - 69 - The EISA bus provided some of the features of the IBM MicroChannel 70 - bus while maintaining backward compatibility with cards made for 71 - the older ISA bus. The EISA bus saw limited use between 1988 and 72 - 1995 when it was made obsolete by the PCI bus. 73 - 74 - Say Y here if you are building a kernel for an EISA-based machine. 75 - 76 - Otherwise, say N. 77 - 78 - config MCA 79 - bool 80 - help 81 - MicroChannel Architecture is found in some IBM PS/2 machines and 82 - laptops. It is a bus system similar to PCI or ISA. See 83 - <file:Documentation/mca.txt> (and especially the web page given 84 - there) before attempting to build an MCA bus kernel. 85 - 86 - config PCMCIA 87 - tristate 88 - ---help--- 89 - Say Y here if you want to attach PCMCIA- or PC-cards to your Linux 90 - computer. These are credit-card size devices such as network cards, 91 - modems or hard drives often used with laptops computers. There are 92 - actually two varieties of these cards: the older 16 bit PCMCIA cards 93 - and the newer 32 bit CardBus cards. If you want to use CardBus 94 - cards, you need to say Y here and also to "CardBus support" below. 95 - 96 - To use your PC-cards, you will need supporting software from David 97 - Hinds' pcmcia-cs package (see the file <file:Documentation/Changes> 98 - for location). Please also read the PCMCIA-HOWTO, available from 99 - <http://www.tldp.org/docs.html#howto>. 100 - 101 - To compile this driver as modules, choose M here: the 102 - modules will be called pcmcia_core and ds. 103 - 104 - config AMIGA 105 - bool "Amiga support" 106 - select MMU_MOTOROLA if MMU 107 - help 108 - This option enables support for the Amiga series of computers. If 109 - you plan to use this kernel on an Amiga, say Y here and browse the 110 - material available in <file:Documentation/m68k>; otherwise say N. 111 - 112 - config ATARI 113 - bool "Atari support" 114 - select MMU_MOTOROLA if MMU 115 - help 116 - This option enables support for the 68000-based Atari series of 117 - computers (including the TT, Falcon and Medusa). If you plan to use 118 - this kernel on an Atari, say Y here and browse the material 119 - available in <file:Documentation/m68k>; otherwise say N. 120 - 121 - config MAC 122 - bool "Macintosh support" 123 - select MMU_MOTOROLA if MMU 124 - help 125 - This option enables support for the Apple Macintosh series of 126 - computers (yes, there is experimental support now, at least for part 127 - of the series). 128 - 129 - Say N unless you're willing to code the remaining necessary support. 130 - ;) 131 - 132 - config NUBUS 133 - bool 134 - depends on MAC 135 - default y 136 - 137 - config M68K_L2_CACHE 138 - bool 139 - depends on MAC 140 - default y 141 - 142 - config APOLLO 143 - bool "Apollo support" 144 - select MMU_MOTOROLA if MMU 145 - help 146 - Say Y here if you want to run Linux on an MC680x0-based Apollo 147 - Domain workstation such as the DN3500. 148 - 149 - config VME 150 - bool "VME (Motorola and BVM) support" 151 - select MMU_MOTOROLA if MMU 152 - help 153 - Say Y here if you want to build a kernel for a 680x0 based VME 154 - board. Boards currently supported include Motorola boards MVME147, 155 - MVME162, MVME166, MVME167, MVME172, and MVME177. BVME4000 and 156 - BVME6000 boards from BVM Ltd are also supported. 157 - 158 - config MVME147 159 - bool "MVME147 support" 160 - depends on VME 161 - help 162 - Say Y to include support for early Motorola VME boards. This will 163 - build a kernel which can run on MVME147 single-board computers. If 164 - you select this option you will have to select the appropriate 165 - drivers for SCSI, Ethernet and serial ports later on. 166 - 167 - config MVME16x 168 - bool "MVME162, 166 and 167 support" 169 - depends on VME 170 - help 171 - Say Y to include support for Motorola VME boards. This will build a 172 - kernel which can run on MVME162, MVME166, MVME167, MVME172, and 173 - MVME177 boards. If you select this option you will have to select 174 - the appropriate drivers for SCSI, Ethernet and serial ports later 175 - on. 176 - 177 - config BVME6000 178 - bool "BVME4000 and BVME6000 support" 179 - depends on VME 180 - help 181 - Say Y to include support for VME boards from BVM Ltd. This will 182 - build a kernel which can run on BVME4000 and BVME6000 boards. If 183 - you select this option you will have to select the appropriate 184 - drivers for SCSI, Ethernet and serial ports later on. 185 - 186 - config HP300 187 - bool "HP9000/300 and HP9000/400 support" 188 - select MMU_MOTOROLA if MMU 189 - help 190 - This option enables support for the HP9000/300 and HP9000/400 series 191 - of workstations. Support for these machines is still somewhat 192 - experimental. If you plan to try to use the kernel on such a machine 193 - say Y here. 194 - Everybody else says N. 195 - 196 - config DIO 197 - bool "DIO bus support" 198 - depends on HP300 199 - default y 200 - help 201 - Say Y here to enable support for the "DIO" expansion bus used in 202 - HP300 machines. If you are using such a system you almost certainly 203 - want this. 204 - 205 - config SUN3X 206 - bool "Sun3x support" 207 - select MMU_MOTOROLA if MMU 208 - select M68030 209 - help 210 - This option enables support for the Sun 3x series of workstations. 211 - Be warned that this support is very experimental. 212 - Note that Sun 3x kernels are not compatible with Sun 3 hardware. 213 - General Linux information on the Sun 3x series (now discontinued) 214 - is at <http://www.angelfire.com/ca2/tech68k/sun3.html>. 215 - 216 - If you don't want to compile a kernel for a Sun 3x, say N. 217 - 218 - config Q40 219 - bool "Q40/Q60 support" 220 - select MMU_MOTOROLA if MMU 221 - help 222 - The Q40 is a Motorola 68040-based successor to the Sinclair QL 223 - manufactured in Germany. There is an official Q40 home page at 224 - <http://www.q40.de/>. This option enables support for the Q40 and 225 - Q60. Select your CPU below. For 68LC060 don't forget to enable FPU 226 - emulation. 227 - 228 - config SUN3 229 - bool "Sun3 support" 230 - depends on !MMU_MOTOROLA 231 - select MMU_SUN3 if MMU 232 - select M68020 233 - help 234 - This option enables support for the Sun 3 series of workstations 235 - (3/50, 3/60, 3/1xx, 3/2xx systems). Enabling this option requires 236 - that all other hardware types must be disabled, as Sun 3 kernels 237 - are incompatible with all other m68k targets (including Sun 3x!). 238 - 239 - If you don't want to compile a kernel exclusively for a Sun 3, say N. 240 - 241 - config NATFEAT 242 - bool "ARAnyM emulator support" 243 - depends on ATARI 244 - help 245 - This option enables support for ARAnyM native features, such as 246 - access to a disk image as /dev/hda. 247 - 248 - config NFBLOCK 249 - tristate "NatFeat block device support" 250 - depends on BLOCK && NATFEAT 251 - help 252 - Say Y to include support for the ARAnyM NatFeat block device 253 - which allows direct access to the hard drives without using 254 - the hardware emulation. 255 - 256 - config NFCON 257 - tristate "NatFeat console driver" 258 - depends on NATFEAT 259 - help 260 - Say Y to include support for the ARAnyM NatFeat console driver 261 - which allows the console output to be redirected to the stderr 262 - output of ARAnyM. 263 - 264 - config NFETH 265 - tristate "NatFeat Ethernet support" 266 - depends on NET_ETHERNET && NATFEAT 267 - help 268 - Say Y to include support for the ARAnyM NatFeat network device 269 - which will emulate a regular ethernet device while presenting an 270 - ethertap device to the host system. 271 - 272 - comment "Processor type" 273 - 274 - config M68020 275 - bool "68020 support" 276 - help 277 - If you anticipate running this kernel on a computer with a MC68020 278 - processor, say Y. Otherwise, say N. Note that the 68020 requires a 279 - 68851 MMU (Memory Management Unit) to run Linux/m68k, except on the 280 - Sun 3, which provides its own version. 281 - 282 - config M68030 283 - bool "68030 support" 284 - depends on !MMU_SUN3 285 - help 286 - If you anticipate running this kernel on a computer with a MC68030 287 - processor, say Y. Otherwise, say N. Note that a MC68EC030 will not 288 - work, as it does not include an MMU (Memory Management Unit). 289 - 290 - config M68040 291 - bool "68040 support" 292 - depends on !MMU_SUN3 293 - help 294 - If you anticipate running this kernel on a computer with a MC68LC040 295 - or MC68040 processor, say Y. Otherwise, say N. Note that an 296 - MC68EC040 will not work, as it does not include an MMU (Memory 297 - Management Unit). 298 - 299 - config M68060 300 - bool "68060 support" 301 - depends on !MMU_SUN3 302 - help 303 - If you anticipate running this kernel on a computer with a MC68060 304 - processor, say Y. Otherwise, say N. 305 - 306 - config MMU_MOTOROLA 307 - bool 308 - 309 - config MMU_SUN3 310 - bool 311 - depends on MMU && !MMU_MOTOROLA 312 - 313 - config M68KFPU_EMU 314 - bool "Math emulation support (EXPERIMENTAL)" 315 - depends on EXPERIMENTAL 316 - help 317 - At some point in the future, this will cause floating-point math 318 - instructions to be emulated by the kernel on machines that lack a 319 - floating-point math coprocessor. Thrill-seekers and chronically 320 - sleep-deprived psychotic hacker types can say Y now, everyone else 321 - should probably wait a while. 322 - 323 - config M68KFPU_EMU_EXTRAPREC 324 - bool "Math emulation extra precision" 325 - depends on M68KFPU_EMU 326 - help 327 - The fpu uses normally a few bit more during calculations for 328 - correct rounding, the emulator can (often) do the same but this 329 - extra calculation can cost quite some time, so you can disable 330 - it here. The emulator will then "only" calculate with a 64 bit 331 - mantissa and round slightly incorrect, what is more than enough 332 - for normal usage. 333 - 334 - config M68KFPU_EMU_ONLY 335 - bool "Math emulation only kernel" 336 - depends on M68KFPU_EMU 337 - help 338 - This option prevents any floating-point instructions from being 339 - compiled into the kernel, thereby the kernel doesn't save any 340 - floating point context anymore during task switches, so this 341 - kernel will only be usable on machines without a floating-point 342 - math coprocessor. This makes the kernel a bit faster as no tests 343 - needs to be executed whether a floating-point instruction in the 344 - kernel should be executed or not. 345 - 346 - config ADVANCED 347 - bool "Advanced configuration options" 348 - ---help--- 349 - This gives you access to some advanced options for the CPU. The 350 - defaults should be fine for most users, but these options may make 351 - it possible for you to improve performance somewhat if you know what 352 - you are doing. 353 - 354 - Note that the answer to this question won't directly affect the 355 - kernel: saying N will just cause the configurator to skip all 356 - the questions about these options. 357 - 358 - Most users should say N to this question. 359 - 360 - config RMW_INSNS 361 - bool "Use read-modify-write instructions" 362 - depends on ADVANCED 363 - ---help--- 364 - This allows to use certain instructions that work with indivisible 365 - read-modify-write bus cycles. While this is faster than the 366 - workaround of disabling interrupts, it can conflict with DMA 367 - ( = direct memory access) on many Amiga systems, and it is also said 368 - to destabilize other machines. It is very likely that this will 369 - cause serious problems on any Amiga or Atari Medusa if set. The only 370 - configuration where it should work are 68030-based Ataris, where it 371 - apparently improves performance. But you've been warned! Unless you 372 - really know what you are doing, say N. Try Y only if you're quite 373 - adventurous. 374 - 375 - config SINGLE_MEMORY_CHUNK 376 - bool "Use one physical chunk of memory only" if ADVANCED && !SUN3 377 - default y if SUN3 378 - select NEED_MULTIPLE_NODES 379 - help 380 - Ignore all but the first contiguous chunk of physical memory for VM 381 - purposes. This will save a few bytes kernel size and may speed up 382 - some operations. Say N if not sure. 383 - 384 - config 060_WRITETHROUGH 385 - bool "Use write-through caching for 68060 supervisor accesses" 386 - depends on ADVANCED && M68060 387 - ---help--- 388 - The 68060 generally uses copyback caching of recently accessed data. 389 - Copyback caching means that memory writes will be held in an on-chip 390 - cache and only written back to memory some time later. Saying Y 391 - here will force supervisor (kernel) accesses to use writethrough 392 - caching. Writethrough caching means that data is written to memory 393 - straight away, so that cache and memory data always agree. 394 - Writethrough caching is less efficient, but is needed for some 395 - drivers on 68060 based systems where the 68060 bus snooping signal 396 - is hardwired on. The 53c710 SCSI driver is known to suffer from 397 - this problem. 398 - 399 - config ARCH_DISCONTIGMEM_ENABLE 400 - def_bool !SINGLE_MEMORY_CHUNK 401 - 402 - config NODES_SHIFT 403 - int 404 - default "3" 405 - depends on !SINGLE_MEMORY_CHUNK 406 407 source "mm/Kconfig" 408 409 endmenu 410 411 - menu "General setup" 412 413 source "fs/Kconfig.binfmt" 414 415 - config ZORRO 416 - bool "Amiga Zorro (AutoConfig) bus support" 417 - depends on AMIGA 418 - help 419 - This enables support for the Zorro bus in the Amiga. If you have 420 - expansion cards in your Amiga that conform to the Amiga 421 - AutoConfig(tm) specification, say Y, otherwise N. Note that even 422 - expansion cards that do not fit in the Zorro slots but fit in e.g. 423 - the CPU slot may fall in this category, so you have to say Y to let 424 - Linux use these. 425 426 - config AMIGA_PCMCIA 427 - bool "Amiga 1200/600 PCMCIA support (EXPERIMENTAL)" 428 - depends on AMIGA && EXPERIMENTAL 429 - help 430 - Include support in the kernel for pcmcia on Amiga 1200 and Amiga 431 - 600. If you intend to use pcmcia cards say Y; otherwise say N. 432 433 - config STRAM_PROC 434 - bool "ST-RAM statistics in /proc" 435 - depends on ATARI 436 - help 437 - Say Y here to report ST-RAM usage statistics in /proc/stram. 438 - 439 - config HEARTBEAT 440 - bool "Use power LED as a heartbeat" if AMIGA || APOLLO || ATARI || MAC ||Q40 441 - default y if !AMIGA && !APOLLO && !ATARI && !MAC && !Q40 && HP300 442 - help 443 - Use the power-on LED on your machine as a load meter. The exact 444 - behavior is platform-dependent, but normally the flash frequency is 445 - a hyperbolic function of the 5-minute load average. 446 - 447 - # We have a dedicated heartbeat LED. :-) 448 - config PROC_HARDWARE 449 - bool "/proc/hardware support" 450 - help 451 - Say Y here to support the /proc/hardware file, which gives you 452 - access to information about the machine you're running on, 453 - including the model, CPU, MMU, clock speed, BogoMIPS rating, 454 - and memory size. 455 - 456 - config ISA 457 - bool 458 - depends on Q40 || AMIGA_PCMCIA 459 - default y 460 - help 461 - Find out whether you have ISA slots on your motherboard. ISA is the 462 - name of a bus system, i.e. the way the CPU talks to the other stuff 463 - inside your box. Other bus systems are PCI, EISA, MicroChannel 464 - (MCA) or VESA. ISA is an older system, now being displaced by PCI; 465 - newer boards don't support it. If you have ISA, say Y, otherwise N. 466 - 467 - config GENERIC_ISA_DMA 468 - bool 469 - depends on Q40 || AMIGA_PCMCIA 470 - default y 471 - 472 - config ZONE_DMA 473 - bool 474 - default y 475 - 476 - source "drivers/pci/Kconfig" 477 - 478 - source "drivers/zorro/Kconfig" 479 480 endmenu 481 482 source "net/Kconfig" 483 484 source "drivers/Kconfig" 485 486 menu "Character devices" 487 ··· 234 If unsure, say N. 235 236 endmenu 237 238 source "fs/Kconfig" 239
··· 1 config M68K 2 bool 3 default y 4 select HAVE_IDE 5 + select HAVE_AOUT if MMU 6 + select GENERIC_ATOMIC64 if MMU 7 + select HAVE_GENERIC_HARDIRQS if !MMU 8 + select GENERIC_HARDIRQS_NO_DEPRECATED if !MMU 9 10 config RWSEM_GENERIC_SPINLOCK 11 bool ··· 34 bool 35 default y 36 37 config NO_IOPORT 38 def_bool y 39 40 config NO_DMA 41 + def_bool (MMU && SUN3) || (!MMU && !COLDFIRE) 42 43 + config ZONE_DMA 44 + bool 45 + default y 46 config HZ 47 int 48 + default 1000 if CLEOPATRA 49 default 100 50 51 source "init/Kconfig" 52 53 source "kernel/Kconfig.freezer" 54 55 + config MMU 56 + bool "MMU-based Paged Memory Management Support" 57 + default y 58 + help 59 + Select if you want MMU-based virtualised addressing space 60 + support by paged memory management. If unsure, say 'Y'. 61 + 62 menu "Platform dependent setup" 63 64 + if MMU 65 + source arch/m68k/Kconfig.mmu 66 + endif 67 + if !MMU 68 + source arch/m68k/Kconfig.nommu 69 + endif 70 71 source "mm/Kconfig" 72 73 endmenu 74 75 + menu "Executable file formats" 76 77 source "fs/Kconfig.binfmt" 78 79 + endmenu 80 81 + if !MMU 82 + menu "Power management options" 83 84 + config PM 85 + bool "Power Management support" 86 + help 87 + Support processor power management modes 88 89 endmenu 90 + endif 91 92 source "net/Kconfig" 93 94 source "drivers/Kconfig" 95 + 96 + if MMU 97 98 menu "Character devices" 99 ··· 626 If unsure, say N. 627 628 endmenu 629 + 630 + endif 631 632 source "fs/Kconfig" 633
+34
arch/m68k/Kconfig.debug
··· 2 3 source "lib/Kconfig.debug" 4 5 endmenu
··· 2 3 source "lib/Kconfig.debug" 4 5 + if !MMU 6 + 7 + config FULLDEBUG 8 + bool "Full Symbolic/Source Debugging support" 9 + help 10 + Enable debugging symbols on kernel build. 11 + 12 + config HIGHPROFILE 13 + bool "Use fast second timer for profiling" 14 + depends on COLDFIRE 15 + help 16 + Use a fast secondary clock to produce profiling information. 17 + 18 + config BOOTPARAM 19 + bool 'Compiled-in Kernel Boot Parameter' 20 + 21 + config BOOTPARAM_STRING 22 + string 'Kernel Boot Parameter' 23 + default 'console=ttyS0,19200' 24 + depends on BOOTPARAM 25 + 26 + config NO_KERNEL_MSG 27 + bool "Suppress Kernel BUG Messages" 28 + help 29 + Do not output any debug BUG messages within the kernel. 30 + 31 + config BDM_DISABLE 32 + bool "Disable BDM signals" 33 + depends on (EXPERIMENTAL && COLDFIRE) 34 + help 35 + Disable the ColdFire CPU's BDM signals. 36 + 37 + endif 38 + 39 endmenu
+417
arch/m68k/Kconfig.mmu
···
··· 1 + config GENERIC_IOMAP 2 + bool 3 + default y 4 + 5 + config ARCH_MAY_HAVE_PC_FDC 6 + bool 7 + depends on BROKEN && (Q40 || SUN3X) 8 + default y 9 + 10 + config ARCH_USES_GETTIMEOFFSET 11 + def_bool y 12 + 13 + config EISA 14 + bool 15 + ---help--- 16 + The Extended Industry Standard Architecture (EISA) bus was 17 + developed as an open alternative to the IBM MicroChannel bus. 18 + 19 + The EISA bus provided some of the features of the IBM MicroChannel 20 + bus while maintaining backward compatibility with cards made for 21 + the older ISA bus. The EISA bus saw limited use between 1988 and 22 + 1995 when it was made obsolete by the PCI bus. 23 + 24 + Say Y here if you are building a kernel for an EISA-based machine. 25 + 26 + Otherwise, say N. 27 + 28 + config MCA 29 + bool 30 + help 31 + MicroChannel Architecture is found in some IBM PS/2 machines and 32 + laptops. It is a bus system similar to PCI or ISA. See 33 + <file:Documentation/mca.txt> (and especially the web page given 34 + there) before attempting to build an MCA bus kernel. 35 + 36 + config PCMCIA 37 + tristate 38 + ---help--- 39 + Say Y here if you want to attach PCMCIA- or PC-cards to your Linux 40 + computer. These are credit-card size devices such as network cards, 41 + modems or hard drives often used with laptops computers. There are 42 + actually two varieties of these cards: the older 16 bit PCMCIA cards 43 + and the newer 32 bit CardBus cards. If you want to use CardBus 44 + cards, you need to say Y here and also to "CardBus support" below. 45 + 46 + To use your PC-cards, you will need supporting software from David 47 + Hinds' pcmcia-cs package (see the file <file:Documentation/Changes> 48 + for location). Please also read the PCMCIA-HOWTO, available from 49 + <http://www.tldp.org/docs.html#howto>. 50 + 51 + To compile this driver as modules, choose M here: the 52 + modules will be called pcmcia_core and ds. 53 + 54 + config AMIGA 55 + bool "Amiga support" 56 + select MMU_MOTOROLA if MMU 57 + help 58 + This option enables support for the Amiga series of computers. If 59 + you plan to use this kernel on an Amiga, say Y here and browse the 60 + material available in <file:Documentation/m68k>; otherwise say N. 61 + 62 + config ATARI 63 + bool "Atari support" 64 + select MMU_MOTOROLA if MMU 65 + help 66 + This option enables support for the 68000-based Atari series of 67 + computers (including the TT, Falcon and Medusa). If you plan to use 68 + this kernel on an Atari, say Y here and browse the material 69 + available in <file:Documentation/m68k>; otherwise say N. 70 + 71 + config MAC 72 + bool "Macintosh support" 73 + select MMU_MOTOROLA if MMU 74 + help 75 + This option enables support for the Apple Macintosh series of 76 + computers (yes, there is experimental support now, at least for part 77 + of the series). 78 + 79 + Say N unless you're willing to code the remaining necessary support. 80 + ;) 81 + 82 + config NUBUS 83 + bool 84 + depends on MAC 85 + default y 86 + 87 + config M68K_L2_CACHE 88 + bool 89 + depends on MAC 90 + default y 91 + 92 + config APOLLO 93 + bool "Apollo support" 94 + select MMU_MOTOROLA if MMU 95 + help 96 + Say Y here if you want to run Linux on an MC680x0-based Apollo 97 + Domain workstation such as the DN3500. 98 + 99 + config VME 100 + bool "VME (Motorola and BVM) support" 101 + select MMU_MOTOROLA if MMU 102 + help 103 + Say Y here if you want to build a kernel for a 680x0 based VME 104 + board. Boards currently supported include Motorola boards MVME147, 105 + MVME162, MVME166, MVME167, MVME172, and MVME177. BVME4000 and 106 + BVME6000 boards from BVM Ltd are also supported. 107 + 108 + config MVME147 109 + bool "MVME147 support" 110 + depends on VME 111 + help 112 + Say Y to include support for early Motorola VME boards. This will 113 + build a kernel which can run on MVME147 single-board computers. If 114 + you select this option you will have to select the appropriate 115 + drivers for SCSI, Ethernet and serial ports later on. 116 + 117 + config MVME16x 118 + bool "MVME162, 166 and 167 support" 119 + depends on VME 120 + help 121 + Say Y to include support for Motorola VME boards. This will build a 122 + kernel which can run on MVME162, MVME166, MVME167, MVME172, and 123 + MVME177 boards. If you select this option you will have to select 124 + the appropriate drivers for SCSI, Ethernet and serial ports later 125 + on. 126 + 127 + config BVME6000 128 + bool "BVME4000 and BVME6000 support" 129 + depends on VME 130 + help 131 + Say Y to include support for VME boards from BVM Ltd. This will 132 + build a kernel which can run on BVME4000 and BVME6000 boards. If 133 + you select this option you will have to select the appropriate 134 + drivers for SCSI, Ethernet and serial ports later on. 135 + 136 + config HP300 137 + bool "HP9000/300 and HP9000/400 support" 138 + select MMU_MOTOROLA if MMU 139 + help 140 + This option enables support for the HP9000/300 and HP9000/400 series 141 + of workstations. Support for these machines is still somewhat 142 + experimental. If you plan to try to use the kernel on such a machine 143 + say Y here. 144 + Everybody else says N. 145 + 146 + config DIO 147 + bool "DIO bus support" 148 + depends on HP300 149 + default y 150 + help 151 + Say Y here to enable support for the "DIO" expansion bus used in 152 + HP300 machines. If you are using such a system you almost certainly 153 + want this. 154 + 155 + config SUN3X 156 + bool "Sun3x support" 157 + select MMU_MOTOROLA if MMU 158 + select M68030 159 + help 160 + This option enables support for the Sun 3x series of workstations. 161 + Be warned that this support is very experimental. 162 + Note that Sun 3x kernels are not compatible with Sun 3 hardware. 163 + General Linux information on the Sun 3x series (now discontinued) 164 + is at <http://www.angelfire.com/ca2/tech68k/sun3.html>. 165 + 166 + If you don't want to compile a kernel for a Sun 3x, say N. 167 + 168 + config Q40 169 + bool "Q40/Q60 support" 170 + select MMU_MOTOROLA if MMU 171 + help 172 + The Q40 is a Motorola 68040-based successor to the Sinclair QL 173 + manufactured in Germany. There is an official Q40 home page at 174 + <http://www.q40.de/>. This option enables support for the Q40 and 175 + Q60. Select your CPU below. For 68LC060 don't forget to enable FPU 176 + emulation. 177 + 178 + config SUN3 179 + bool "Sun3 support" 180 + depends on !MMU_MOTOROLA 181 + select MMU_SUN3 if MMU 182 + select M68020 183 + help 184 + This option enables support for the Sun 3 series of workstations 185 + (3/50, 3/60, 3/1xx, 3/2xx systems). Enabling this option requires 186 + that all other hardware types must be disabled, as Sun 3 kernels 187 + are incompatible with all other m68k targets (including Sun 3x!). 188 + 189 + If you don't want to compile a kernel exclusively for a Sun 3, say N. 190 + 191 + config NATFEAT 192 + bool "ARAnyM emulator support" 193 + depends on ATARI 194 + help 195 + This option enables support for ARAnyM native features, such as 196 + access to a disk image as /dev/hda. 197 + 198 + config NFBLOCK 199 + tristate "NatFeat block device support" 200 + depends on BLOCK && NATFEAT 201 + help 202 + Say Y to include support for the ARAnyM NatFeat block device 203 + which allows direct access to the hard drives without using 204 + the hardware emulation. 205 + 206 + config NFCON 207 + tristate "NatFeat console driver" 208 + depends on NATFEAT 209 + help 210 + Say Y to include support for the ARAnyM NatFeat console driver 211 + which allows the console output to be redirected to the stderr 212 + output of ARAnyM. 213 + 214 + config NFETH 215 + tristate "NatFeat Ethernet support" 216 + depends on NET_ETHERNET && NATFEAT 217 + help 218 + Say Y to include support for the ARAnyM NatFeat network device 219 + which will emulate a regular ethernet device while presenting an 220 + ethertap device to the host system. 221 + 222 + comment "Processor type" 223 + 224 + config M68020 225 + bool "68020 support" 226 + help 227 + If you anticipate running this kernel on a computer with a MC68020 228 + processor, say Y. Otherwise, say N. Note that the 68020 requires a 229 + 68851 MMU (Memory Management Unit) to run Linux/m68k, except on the 230 + Sun 3, which provides its own version. 231 + 232 + config M68030 233 + bool "68030 support" 234 + depends on !MMU_SUN3 235 + help 236 + If you anticipate running this kernel on a computer with a MC68030 237 + processor, say Y. Otherwise, say N. Note that a MC68EC030 will not 238 + work, as it does not include an MMU (Memory Management Unit). 239 + 240 + config M68040 241 + bool "68040 support" 242 + depends on !MMU_SUN3 243 + help 244 + If you anticipate running this kernel on a computer with a MC68LC040 245 + or MC68040 processor, say Y. Otherwise, say N. Note that an 246 + MC68EC040 will not work, as it does not include an MMU (Memory 247 + Management Unit). 248 + 249 + config M68060 250 + bool "68060 support" 251 + depends on !MMU_SUN3 252 + help 253 + If you anticipate running this kernel on a computer with a MC68060 254 + processor, say Y. Otherwise, say N. 255 + 256 + config MMU_MOTOROLA 257 + bool 258 + 259 + config MMU_SUN3 260 + bool 261 + depends on MMU && !MMU_MOTOROLA 262 + 263 + config M68KFPU_EMU 264 + bool "Math emulation support (EXPERIMENTAL)" 265 + depends on EXPERIMENTAL 266 + help 267 + At some point in the future, this will cause floating-point math 268 + instructions to be emulated by the kernel on machines that lack a 269 + floating-point math coprocessor. Thrill-seekers and chronically 270 + sleep-deprived psychotic hacker types can say Y now, everyone else 271 + should probably wait a while. 272 + 273 + config M68KFPU_EMU_EXTRAPREC 274 + bool "Math emulation extra precision" 275 + depends on M68KFPU_EMU 276 + help 277 + The fpu uses normally a few bit more during calculations for 278 + correct rounding, the emulator can (often) do the same but this 279 + extra calculation can cost quite some time, so you can disable 280 + it here. The emulator will then "only" calculate with a 64 bit 281 + mantissa and round slightly incorrect, what is more than enough 282 + for normal usage. 283 + 284 + config M68KFPU_EMU_ONLY 285 + bool "Math emulation only kernel" 286 + depends on M68KFPU_EMU 287 + help 288 + This option prevents any floating-point instructions from being 289 + compiled into the kernel, thereby the kernel doesn't save any 290 + floating point context anymore during task switches, so this 291 + kernel will only be usable on machines without a floating-point 292 + math coprocessor. This makes the kernel a bit faster as no tests 293 + needs to be executed whether a floating-point instruction in the 294 + kernel should be executed or not. 295 + 296 + config ADVANCED 297 + bool "Advanced configuration options" 298 + ---help--- 299 + This gives you access to some advanced options for the CPU. The 300 + defaults should be fine for most users, but these options may make 301 + it possible for you to improve performance somewhat if you know what 302 + you are doing. 303 + 304 + Note that the answer to this question won't directly affect the 305 + kernel: saying N will just cause the configurator to skip all 306 + the questions about these options. 307 + 308 + Most users should say N to this question. 309 + 310 + config RMW_INSNS 311 + bool "Use read-modify-write instructions" 312 + depends on ADVANCED 313 + ---help--- 314 + This allows to use certain instructions that work with indivisible 315 + read-modify-write bus cycles. While this is faster than the 316 + workaround of disabling interrupts, it can conflict with DMA 317 + ( = direct memory access) on many Amiga systems, and it is also said 318 + to destabilize other machines. It is very likely that this will 319 + cause serious problems on any Amiga or Atari Medusa if set. The only 320 + configuration where it should work are 68030-based Ataris, where it 321 + apparently improves performance. But you've been warned! Unless you 322 + really know what you are doing, say N. Try Y only if you're quite 323 + adventurous. 324 + 325 + config SINGLE_MEMORY_CHUNK 326 + bool "Use one physical chunk of memory only" if ADVANCED && !SUN3 327 + default y if SUN3 328 + select NEED_MULTIPLE_NODES 329 + help 330 + Ignore all but the first contiguous chunk of physical memory for VM 331 + purposes. This will save a few bytes kernel size and may speed up 332 + some operations. Say N if not sure. 333 + 334 + config 060_WRITETHROUGH 335 + bool "Use write-through caching for 68060 supervisor accesses" 336 + depends on ADVANCED && M68060 337 + ---help--- 338 + The 68060 generally uses copyback caching of recently accessed data. 339 + Copyback caching means that memory writes will be held in an on-chip 340 + cache and only written back to memory some time later. Saying Y 341 + here will force supervisor (kernel) accesses to use writethrough 342 + caching. Writethrough caching means that data is written to memory 343 + straight away, so that cache and memory data always agree. 344 + Writethrough caching is less efficient, but is needed for some 345 + drivers on 68060 based systems where the 68060 bus snooping signal 346 + is hardwired on. The 53c710 SCSI driver is known to suffer from 347 + this problem. 348 + 349 + config ARCH_DISCONTIGMEM_ENABLE 350 + def_bool !SINGLE_MEMORY_CHUNK 351 + 352 + config NODES_SHIFT 353 + int 354 + default "3" 355 + depends on !SINGLE_MEMORY_CHUNK 356 + 357 + config ZORRO 358 + bool "Amiga Zorro (AutoConfig) bus support" 359 + depends on AMIGA 360 + help 361 + This enables support for the Zorro bus in the Amiga. If you have 362 + expansion cards in your Amiga that conform to the Amiga 363 + AutoConfig(tm) specification, say Y, otherwise N. Note that even 364 + expansion cards that do not fit in the Zorro slots but fit in e.g. 365 + the CPU slot may fall in this category, so you have to say Y to let 366 + Linux use these. 367 + 368 + config AMIGA_PCMCIA 369 + bool "Amiga 1200/600 PCMCIA support (EXPERIMENTAL)" 370 + depends on AMIGA && EXPERIMENTAL 371 + help 372 + Include support in the kernel for pcmcia on Amiga 1200 and Amiga 373 + 600. If you intend to use pcmcia cards say Y; otherwise say N. 374 + 375 + config STRAM_PROC 376 + bool "ST-RAM statistics in /proc" 377 + depends on ATARI 378 + help 379 + Say Y here to report ST-RAM usage statistics in /proc/stram. 380 + 381 + config HEARTBEAT 382 + bool "Use power LED as a heartbeat" if AMIGA || APOLLO || ATARI || MAC ||Q40 383 + default y if !AMIGA && !APOLLO && !ATARI && !MAC && !Q40 && HP300 384 + help 385 + Use the power-on LED on your machine as a load meter. The exact 386 + behavior is platform-dependent, but normally the flash frequency is 387 + a hyperbolic function of the 5-minute load average. 388 + 389 + # We have a dedicated heartbeat LED. :-) 390 + config PROC_HARDWARE 391 + bool "/proc/hardware support" 392 + help 393 + Say Y here to support the /proc/hardware file, which gives you 394 + access to information about the machine you're running on, 395 + including the model, CPU, MMU, clock speed, BogoMIPS rating, 396 + and memory size. 397 + 398 + config ISA 399 + bool 400 + depends on Q40 || AMIGA_PCMCIA 401 + default y 402 + help 403 + Find out whether you have ISA slots on your motherboard. ISA is the 404 + name of a bus system, i.e. the way the CPU talks to the other stuff 405 + inside your box. Other bus systems are PCI, EISA, MicroChannel 406 + (MCA) or VESA. ISA is an older system, now being displaced by PCI; 407 + newer boards don't support it. If you have ISA, say Y, otherwise N. 408 + 409 + config GENERIC_ISA_DMA 410 + bool 411 + depends on Q40 || AMIGA_PCMCIA 412 + default y 413 + 414 + source "drivers/pci/Kconfig" 415 + 416 + source "drivers/zorro/Kconfig" 417 +
+3 -119
arch/m68k/Makefile
··· 1 - # 2 - # m68k/Makefile 3 - # 4 - # This file is included by the global makefile so that you can add your own 5 - # architecture-specific flags and dependencies. Remember to do have actions 6 - # for "archclean" and "archdep" for cleaning up and making dependencies for 7 - # this architecture 8 - # 9 - # This file is subject to the terms and conditions of the GNU General Public 10 - # License. See the file "COPYING" in the main directory of this archive 11 - # for more details. 12 - # 13 - # Copyright (C) 1994 by Hamish Macdonald 14 - # 15 - 16 KBUILD_DEFCONFIG := multi_defconfig 17 18 - # override top level makefile 19 - AS += -m68020 20 - LDFLAGS := -m m68kelf 21 - KBUILD_LDFLAGS_MODULE += -T $(srctree)/arch/m68k/kernel/module.lds 22 - ifneq ($(SUBARCH),$(ARCH)) 23 - ifeq ($(CROSS_COMPILE),) 24 - CROSS_COMPILE := $(call cc-cross-prefix, \ 25 - m68k-linux-gnu- m68k-linux- m68k-unknown-linux-gnu-) 26 - endif 27 - endif 28 - 29 - ifdef CONFIG_SUN3 30 - LDFLAGS_vmlinux = -N 31 - endif 32 - 33 - CHECKFLAGS += -D__mc68000__ 34 - 35 - # without -fno-strength-reduce the 53c7xx.c driver fails ;-( 36 - KBUILD_CFLAGS += -pipe -fno-strength-reduce -ffixed-a2 37 - 38 - # enable processor switch if compiled only for a single cpu 39 - ifndef CONFIG_M68020 40 - ifndef CONFIG_M68030 41 - 42 - ifndef CONFIG_M68060 43 - KBUILD_CFLAGS += -m68040 44 - endif 45 - 46 - ifndef CONFIG_M68040 47 - KBUILD_CFLAGS += -m68060 48 - endif 49 - 50 - endif 51 - endif 52 - 53 - ifdef CONFIG_KGDB 54 - # If configured for kgdb support, include debugging infos and keep the 55 - # frame pointer 56 - KBUILD_CFLAGS := $(subst -fomit-frame-pointer,,$(KBUILD_CFLAGS)) -g 57 - endif 58 - 59 - ifndef CONFIG_SUN3 60 - head-y := arch/m68k/kernel/head.o 61 else 62 - head-y := arch/m68k/kernel/sun3-head.o 63 endif 64 - 65 - core-y += arch/m68k/kernel/ arch/m68k/mm/ 66 - libs-y += arch/m68k/lib/ 67 - 68 - core-$(CONFIG_Q40) += arch/m68k/q40/ 69 - core-$(CONFIG_AMIGA) += arch/m68k/amiga/ 70 - core-$(CONFIG_ATARI) += arch/m68k/atari/ 71 - core-$(CONFIG_MAC) += arch/m68k/mac/ 72 - core-$(CONFIG_HP300) += arch/m68k/hp300/ 73 - core-$(CONFIG_APOLLO) += arch/m68k/apollo/ 74 - core-$(CONFIG_MVME147) += arch/m68k/mvme147/ 75 - core-$(CONFIG_MVME16x) += arch/m68k/mvme16x/ 76 - core-$(CONFIG_BVME6000) += arch/m68k/bvme6000/ 77 - core-$(CONFIG_SUN3X) += arch/m68k/sun3x/ arch/m68k/sun3/ 78 - core-$(CONFIG_SUN3) += arch/m68k/sun3/ arch/m68k/sun3/prom/ 79 - core-$(CONFIG_NATFEAT) += arch/m68k/emu/ 80 - core-$(CONFIG_M68040) += arch/m68k/fpsp040/ 81 - core-$(CONFIG_M68060) += arch/m68k/ifpsp060/ 82 - core-$(CONFIG_M68KFPU_EMU) += arch/m68k/math-emu/ 83 - 84 - all: zImage 85 - 86 - lilo: vmlinux 87 - if [ -f $(INSTALL_PATH)/vmlinux ]; then mv -f $(INSTALL_PATH)/vmlinux $(INSTALL_PATH)/vmlinux.old; fi 88 - if [ -f $(INSTALL_PATH)/System.map ]; then mv -f $(INSTALL_PATH)/System.map $(INSTALL_PATH)/System.old; fi 89 - cat vmlinux > $(INSTALL_PATH)/vmlinux 90 - cp System.map $(INSTALL_PATH)/System.map 91 - if [ -x /sbin/lilo ]; then /sbin/lilo; else /etc/lilo/install; fi 92 - 93 - zImage compressed: vmlinux.gz 94 - 95 - vmlinux.gz: vmlinux 96 - 97 - ifndef CONFIG_KGDB 98 - cp vmlinux vmlinux.tmp 99 - $(STRIP) vmlinux.tmp 100 - gzip -9c vmlinux.tmp >vmlinux.gz 101 - rm vmlinux.tmp 102 - else 103 - gzip -9c vmlinux >vmlinux.gz 104 - endif 105 - 106 - bzImage: vmlinux.bz2 107 - 108 - vmlinux.bz2: vmlinux 109 - 110 - ifndef CONFIG_KGDB 111 - cp vmlinux vmlinux.tmp 112 - $(STRIP) vmlinux.tmp 113 - bzip2 -1c vmlinux.tmp >vmlinux.bz2 114 - rm vmlinux.tmp 115 - else 116 - bzip2 -1c vmlinux >vmlinux.bz2 117 - endif 118 - 119 - archclean: 120 - rm -f vmlinux.gz vmlinux.bz2 121 - 122 - install: 123 - sh $(srctree)/arch/m68k/install.sh $(KERNELRELEASE) vmlinux.gz System.map "$(INSTALL_PATH)"
··· 1 KBUILD_DEFCONFIG := multi_defconfig 2 3 + ifdef CONFIG_MMU 4 + include $(srctree)/arch/m68k/Makefile_mm 5 else 6 + include $(srctree)/arch/m68k/Makefile_no 7 endif
+121
arch/m68k/Makefile_mm
···
··· 1 + # 2 + # m68k/Makefile 3 + # 4 + # This file is included by the global makefile so that you can add your own 5 + # architecture-specific flags and dependencies. Remember to do have actions 6 + # for "archclean" and "archdep" for cleaning up and making dependencies for 7 + # this architecture 8 + # 9 + # This file is subject to the terms and conditions of the GNU General Public 10 + # License. See the file "COPYING" in the main directory of this archive 11 + # for more details. 12 + # 13 + # Copyright (C) 1994 by Hamish Macdonald 14 + # 15 + 16 + # override top level makefile 17 + AS += -m68020 18 + LDFLAGS := -m m68kelf 19 + KBUILD_LDFLAGS_MODULE += -T $(srctree)/arch/m68k/kernel/module.lds 20 + ifneq ($(SUBARCH),$(ARCH)) 21 + ifeq ($(CROSS_COMPILE),) 22 + CROSS_COMPILE := $(call cc-cross-prefix, \ 23 + m68k-linux-gnu- m68k-linux- m68k-unknown-linux-gnu-) 24 + endif 25 + endif 26 + 27 + ifdef CONFIG_SUN3 28 + LDFLAGS_vmlinux = -N 29 + endif 30 + 31 + CHECKFLAGS += -D__mc68000__ 32 + 33 + # without -fno-strength-reduce the 53c7xx.c driver fails ;-( 34 + KBUILD_CFLAGS += -pipe -fno-strength-reduce -ffixed-a2 35 + 36 + # enable processor switch if compiled only for a single cpu 37 + ifndef CONFIG_M68020 38 + ifndef CONFIG_M68030 39 + 40 + ifndef CONFIG_M68060 41 + KBUILD_CFLAGS += -m68040 42 + endif 43 + 44 + ifndef CONFIG_M68040 45 + KBUILD_CFLAGS += -m68060 46 + endif 47 + 48 + endif 49 + endif 50 + 51 + ifdef CONFIG_KGDB 52 + # If configured for kgdb support, include debugging infos and keep the 53 + # frame pointer 54 + KBUILD_CFLAGS := $(subst -fomit-frame-pointer,,$(KBUILD_CFLAGS)) -g 55 + endif 56 + 57 + ifndef CONFIG_SUN3 58 + head-y := arch/m68k/kernel/head.o 59 + else 60 + head-y := arch/m68k/kernel/sun3-head.o 61 + endif 62 + 63 + core-y += arch/m68k/kernel/ arch/m68k/mm/ 64 + libs-y += arch/m68k/lib/ 65 + 66 + core-$(CONFIG_Q40) += arch/m68k/q40/ 67 + core-$(CONFIG_AMIGA) += arch/m68k/amiga/ 68 + core-$(CONFIG_ATARI) += arch/m68k/atari/ 69 + core-$(CONFIG_MAC) += arch/m68k/mac/ 70 + core-$(CONFIG_HP300) += arch/m68k/hp300/ 71 + core-$(CONFIG_APOLLO) += arch/m68k/apollo/ 72 + core-$(CONFIG_MVME147) += arch/m68k/mvme147/ 73 + core-$(CONFIG_MVME16x) += arch/m68k/mvme16x/ 74 + core-$(CONFIG_BVME6000) += arch/m68k/bvme6000/ 75 + core-$(CONFIG_SUN3X) += arch/m68k/sun3x/ arch/m68k/sun3/ 76 + core-$(CONFIG_SUN3) += arch/m68k/sun3/ arch/m68k/sun3/prom/ 77 + core-$(CONFIG_NATFEAT) += arch/m68k/emu/ 78 + core-$(CONFIG_M68040) += arch/m68k/fpsp040/ 79 + core-$(CONFIG_M68060) += arch/m68k/ifpsp060/ 80 + core-$(CONFIG_M68KFPU_EMU) += arch/m68k/math-emu/ 81 + 82 + all: zImage 83 + 84 + lilo: vmlinux 85 + if [ -f $(INSTALL_PATH)/vmlinux ]; then mv -f $(INSTALL_PATH)/vmlinux $(INSTALL_PATH)/vmlinux.old; fi 86 + if [ -f $(INSTALL_PATH)/System.map ]; then mv -f $(INSTALL_PATH)/System.map $(INSTALL_PATH)/System.old; fi 87 + cat vmlinux > $(INSTALL_PATH)/vmlinux 88 + cp System.map $(INSTALL_PATH)/System.map 89 + if [ -x /sbin/lilo ]; then /sbin/lilo; else /etc/lilo/install; fi 90 + 91 + zImage compressed: vmlinux.gz 92 + 93 + vmlinux.gz: vmlinux 94 + 95 + ifndef CONFIG_KGDB 96 + cp vmlinux vmlinux.tmp 97 + $(STRIP) vmlinux.tmp 98 + gzip -9c vmlinux.tmp >vmlinux.gz 99 + rm vmlinux.tmp 100 + else 101 + gzip -9c vmlinux >vmlinux.gz 102 + endif 103 + 104 + bzImage: vmlinux.bz2 105 + 106 + vmlinux.bz2: vmlinux 107 + 108 + ifndef CONFIG_KGDB 109 + cp vmlinux vmlinux.tmp 110 + $(STRIP) vmlinux.tmp 111 + bzip2 -1c vmlinux.tmp >vmlinux.bz2 112 + rm vmlinux.tmp 113 + else 114 + bzip2 -1c vmlinux >vmlinux.bz2 115 + endif 116 + 117 + archclean: 118 + rm -f vmlinux.gz vmlinux.bz2 119 + 120 + install: 121 + sh $(srctree)/arch/m68k/install.sh $(KERNELRELEASE) vmlinux.gz System.map "$(INSTALL_PATH)"
+3 -15
arch/m68k/kernel/Makefile
··· 1 - # 2 - # Makefile for the linux kernel. 3 - # 4 - 5 - ifndef CONFIG_SUN3 6 - extra-y := head.o 7 else 8 - extra-y := sun3-head.o 9 endif 10 - extra-y += vmlinux.lds 11 - 12 - obj-y := entry.o process.o traps.o ints.o signal.o ptrace.o module.o \ 13 - sys_m68k.o time.o setup.o m68k_ksyms.o devres.o 14 - 15 - devres-y = ../../../kernel/irq/devres.o 16 - 17 - obj-y$(CONFIG_MMU_SUN3) += dma.o # no, it's not a typo
··· 1 + ifdef CONFIG_MMU 2 + include arch/m68k/kernel/Makefile_mm 3 else 4 + include arch/m68k/kernel/Makefile_no 5 endif
+17
arch/m68k/kernel/Makefile_mm
···
··· 1 + # 2 + # Makefile for the linux kernel. 3 + # 4 + 5 + ifndef CONFIG_SUN3 6 + extra-y := head.o 7 + else 8 + extra-y := sun3-head.o 9 + endif 10 + extra-y += vmlinux.lds 11 + 12 + obj-y := entry.o process.o traps.o ints.o signal.o ptrace.o module.o \ 13 + sys_m68k.o time.o setup.o m68k_ksyms.o devres.o 14 + 15 + devres-y = ../../../kernel/irq/devres.o 16 + 17 + obj-y$(CONFIG_MMU_SUN3) += dma.o # no, it's not a typo
+3 -98
arch/m68k/kernel/asm-offsets.c
··· 1 - /* 2 - * This program is used to generate definitions needed by 3 - * assembly language modules. 4 - * 5 - * We use the technique used in the OSF Mach kernel code: 6 - * generate asm statements containing #defines, 7 - * compile this file to assembler, and then extract the 8 - * #defines from the assembly-language output. 9 - */ 10 - 11 - #define ASM_OFFSETS_C 12 - 13 - #include <linux/stddef.h> 14 - #include <linux/sched.h> 15 - #include <linux/kernel_stat.h> 16 - #include <linux/kbuild.h> 17 - #include <asm/bootinfo.h> 18 - #include <asm/irq.h> 19 - #include <asm/amigahw.h> 20 - #include <linux/font.h> 21 - 22 - int main(void) 23 - { 24 - /* offsets into the task struct */ 25 - DEFINE(TASK_THREAD, offsetof(struct task_struct, thread)); 26 - DEFINE(TASK_INFO, offsetof(struct task_struct, thread.info)); 27 - DEFINE(TASK_MM, offsetof(struct task_struct, mm)); 28 #ifdef CONFIG_MMU 29 - DEFINE(TASK_TINFO, offsetof(struct task_struct, thread.info)); 30 #endif 31 - 32 - /* offsets into the thread struct */ 33 - DEFINE(THREAD_KSP, offsetof(struct thread_struct, ksp)); 34 - DEFINE(THREAD_USP, offsetof(struct thread_struct, usp)); 35 - DEFINE(THREAD_SR, offsetof(struct thread_struct, sr)); 36 - DEFINE(THREAD_FS, offsetof(struct thread_struct, fs)); 37 - DEFINE(THREAD_CRP, offsetof(struct thread_struct, crp)); 38 - DEFINE(THREAD_ESP0, offsetof(struct thread_struct, esp0)); 39 - DEFINE(THREAD_FPREG, offsetof(struct thread_struct, fp)); 40 - DEFINE(THREAD_FPCNTL, offsetof(struct thread_struct, fpcntl)); 41 - DEFINE(THREAD_FPSTATE, offsetof(struct thread_struct, fpstate)); 42 - 43 - /* offsets into the thread_info struct */ 44 - DEFINE(TINFO_PREEMPT, offsetof(struct thread_info, preempt_count)); 45 - DEFINE(TINFO_FLAGS, offsetof(struct thread_info, flags)); 46 - 47 - /* offsets into the pt_regs */ 48 - DEFINE(PT_OFF_D0, offsetof(struct pt_regs, d0)); 49 - DEFINE(PT_OFF_ORIG_D0, offsetof(struct pt_regs, orig_d0)); 50 - DEFINE(PT_OFF_D1, offsetof(struct pt_regs, d1)); 51 - DEFINE(PT_OFF_D2, offsetof(struct pt_regs, d2)); 52 - DEFINE(PT_OFF_D3, offsetof(struct pt_regs, d3)); 53 - DEFINE(PT_OFF_D4, offsetof(struct pt_regs, d4)); 54 - DEFINE(PT_OFF_D5, offsetof(struct pt_regs, d5)); 55 - DEFINE(PT_OFF_A0, offsetof(struct pt_regs, a0)); 56 - DEFINE(PT_OFF_A1, offsetof(struct pt_regs, a1)); 57 - DEFINE(PT_OFF_A2, offsetof(struct pt_regs, a2)); 58 - DEFINE(PT_OFF_PC, offsetof(struct pt_regs, pc)); 59 - DEFINE(PT_OFF_SR, offsetof(struct pt_regs, sr)); 60 - /* bitfields are a bit difficult */ 61 - DEFINE(PT_OFF_FORMATVEC, offsetof(struct pt_regs, pc) + 4); 62 - 63 - /* offsets into the irq_cpustat_t struct */ 64 - DEFINE(CPUSTAT_SOFTIRQ_PENDING, offsetof(irq_cpustat_t, __softirq_pending)); 65 - 66 - /* offsets into the bi_record struct */ 67 - DEFINE(BIR_TAG, offsetof(struct bi_record, tag)); 68 - DEFINE(BIR_SIZE, offsetof(struct bi_record, size)); 69 - DEFINE(BIR_DATA, offsetof(struct bi_record, data)); 70 - 71 - /* offsets into font_desc (drivers/video/console/font.h) */ 72 - DEFINE(FONT_DESC_IDX, offsetof(struct font_desc, idx)); 73 - DEFINE(FONT_DESC_NAME, offsetof(struct font_desc, name)); 74 - DEFINE(FONT_DESC_WIDTH, offsetof(struct font_desc, width)); 75 - DEFINE(FONT_DESC_HEIGHT, offsetof(struct font_desc, height)); 76 - DEFINE(FONT_DESC_DATA, offsetof(struct font_desc, data)); 77 - DEFINE(FONT_DESC_PREF, offsetof(struct font_desc, pref)); 78 - 79 - /* signal defines */ 80 - DEFINE(LSIGSEGV, SIGSEGV); 81 - DEFINE(LSEGV_MAPERR, SEGV_MAPERR); 82 - DEFINE(LSIGTRAP, SIGTRAP); 83 - DEFINE(LTRAP_TRACE, TRAP_TRACE); 84 - 85 - /* offsets into the custom struct */ 86 - DEFINE(CUSTOMBASE, &amiga_custom); 87 - DEFINE(C_INTENAR, offsetof(struct CUSTOM, intenar)); 88 - DEFINE(C_INTREQR, offsetof(struct CUSTOM, intreqr)); 89 - DEFINE(C_INTENA, offsetof(struct CUSTOM, intena)); 90 - DEFINE(C_INTREQ, offsetof(struct CUSTOM, intreq)); 91 - DEFINE(C_SERDATR, offsetof(struct CUSTOM, serdatr)); 92 - DEFINE(C_SERDAT, offsetof(struct CUSTOM, serdat)); 93 - DEFINE(C_SERPER, offsetof(struct CUSTOM, serper)); 94 - DEFINE(CIAABASE, &ciaa); 95 - DEFINE(CIABBASE, &ciab); 96 - DEFINE(C_PRA, offsetof(struct CIA, pra)); 97 - DEFINE(ZTWOBASE, zTwoBase); 98 - 99 - return 0; 100 - }
··· 1 #ifdef CONFIG_MMU 2 + #include "asm-offsets_mm.c" 3 + #else 4 + #include "asm-offsets_no.c" 5 #endif
+100
arch/m68k/kernel/asm-offsets_mm.c
···
··· 1 + /* 2 + * This program is used to generate definitions needed by 3 + * assembly language modules. 4 + * 5 + * We use the technique used in the OSF Mach kernel code: 6 + * generate asm statements containing #defines, 7 + * compile this file to assembler, and then extract the 8 + * #defines from the assembly-language output. 9 + */ 10 + 11 + #define ASM_OFFSETS_C 12 + 13 + #include <linux/stddef.h> 14 + #include <linux/sched.h> 15 + #include <linux/kernel_stat.h> 16 + #include <linux/kbuild.h> 17 + #include <asm/bootinfo.h> 18 + #include <asm/irq.h> 19 + #include <asm/amigahw.h> 20 + #include <linux/font.h> 21 + 22 + int main(void) 23 + { 24 + /* offsets into the task struct */ 25 + DEFINE(TASK_THREAD, offsetof(struct task_struct, thread)); 26 + DEFINE(TASK_INFO, offsetof(struct task_struct, thread.info)); 27 + DEFINE(TASK_MM, offsetof(struct task_struct, mm)); 28 + #ifdef CONFIG_MMU 29 + DEFINE(TASK_TINFO, offsetof(struct task_struct, thread.info)); 30 + #endif 31 + 32 + /* offsets into the thread struct */ 33 + DEFINE(THREAD_KSP, offsetof(struct thread_struct, ksp)); 34 + DEFINE(THREAD_USP, offsetof(struct thread_struct, usp)); 35 + DEFINE(THREAD_SR, offsetof(struct thread_struct, sr)); 36 + DEFINE(THREAD_FS, offsetof(struct thread_struct, fs)); 37 + DEFINE(THREAD_CRP, offsetof(struct thread_struct, crp)); 38 + DEFINE(THREAD_ESP0, offsetof(struct thread_struct, esp0)); 39 + DEFINE(THREAD_FPREG, offsetof(struct thread_struct, fp)); 40 + DEFINE(THREAD_FPCNTL, offsetof(struct thread_struct, fpcntl)); 41 + DEFINE(THREAD_FPSTATE, offsetof(struct thread_struct, fpstate)); 42 + 43 + /* offsets into the thread_info struct */ 44 + DEFINE(TINFO_PREEMPT, offsetof(struct thread_info, preempt_count)); 45 + DEFINE(TINFO_FLAGS, offsetof(struct thread_info, flags)); 46 + 47 + /* offsets into the pt_regs */ 48 + DEFINE(PT_OFF_D0, offsetof(struct pt_regs, d0)); 49 + DEFINE(PT_OFF_ORIG_D0, offsetof(struct pt_regs, orig_d0)); 50 + DEFINE(PT_OFF_D1, offsetof(struct pt_regs, d1)); 51 + DEFINE(PT_OFF_D2, offsetof(struct pt_regs, d2)); 52 + DEFINE(PT_OFF_D3, offsetof(struct pt_regs, d3)); 53 + DEFINE(PT_OFF_D4, offsetof(struct pt_regs, d4)); 54 + DEFINE(PT_OFF_D5, offsetof(struct pt_regs, d5)); 55 + DEFINE(PT_OFF_A0, offsetof(struct pt_regs, a0)); 56 + DEFINE(PT_OFF_A1, offsetof(struct pt_regs, a1)); 57 + DEFINE(PT_OFF_A2, offsetof(struct pt_regs, a2)); 58 + DEFINE(PT_OFF_PC, offsetof(struct pt_regs, pc)); 59 + DEFINE(PT_OFF_SR, offsetof(struct pt_regs, sr)); 60 + /* bitfields are a bit difficult */ 61 + DEFINE(PT_OFF_FORMATVEC, offsetof(struct pt_regs, pc) + 4); 62 + 63 + /* offsets into the irq_cpustat_t struct */ 64 + DEFINE(CPUSTAT_SOFTIRQ_PENDING, offsetof(irq_cpustat_t, __softirq_pending)); 65 + 66 + /* offsets into the bi_record struct */ 67 + DEFINE(BIR_TAG, offsetof(struct bi_record, tag)); 68 + DEFINE(BIR_SIZE, offsetof(struct bi_record, size)); 69 + DEFINE(BIR_DATA, offsetof(struct bi_record, data)); 70 + 71 + /* offsets into font_desc (drivers/video/console/font.h) */ 72 + DEFINE(FONT_DESC_IDX, offsetof(struct font_desc, idx)); 73 + DEFINE(FONT_DESC_NAME, offsetof(struct font_desc, name)); 74 + DEFINE(FONT_DESC_WIDTH, offsetof(struct font_desc, width)); 75 + DEFINE(FONT_DESC_HEIGHT, offsetof(struct font_desc, height)); 76 + DEFINE(FONT_DESC_DATA, offsetof(struct font_desc, data)); 77 + DEFINE(FONT_DESC_PREF, offsetof(struct font_desc, pref)); 78 + 79 + /* signal defines */ 80 + DEFINE(LSIGSEGV, SIGSEGV); 81 + DEFINE(LSEGV_MAPERR, SEGV_MAPERR); 82 + DEFINE(LSIGTRAP, SIGTRAP); 83 + DEFINE(LTRAP_TRACE, TRAP_TRACE); 84 + 85 + /* offsets into the custom struct */ 86 + DEFINE(CUSTOMBASE, &amiga_custom); 87 + DEFINE(C_INTENAR, offsetof(struct CUSTOM, intenar)); 88 + DEFINE(C_INTREQR, offsetof(struct CUSTOM, intreqr)); 89 + DEFINE(C_INTENA, offsetof(struct CUSTOM, intena)); 90 + DEFINE(C_INTREQ, offsetof(struct CUSTOM, intreq)); 91 + DEFINE(C_SERDATR, offsetof(struct CUSTOM, serdatr)); 92 + DEFINE(C_SERDAT, offsetof(struct CUSTOM, serdat)); 93 + DEFINE(C_SERPER, offsetof(struct CUSTOM, serper)); 94 + DEFINE(CIAABASE, &ciaa); 95 + DEFINE(CIABBASE, &ciab); 96 + DEFINE(C_PRA, offsetof(struct CIA, pra)); 97 + DEFINE(ZTWOBASE, zTwoBase); 98 + 99 + return 0; 100 + }
+5 -130
arch/m68k/kernel/dma.c
··· 1 - /* 2 - * This file is subject to the terms and conditions of the GNU General Public 3 - * License. See the file COPYING in the main directory of this archive 4 - * for more details. 5 - */ 6 - 7 - #undef DEBUG 8 - 9 - #include <linux/dma-mapping.h> 10 - #include <linux/device.h> 11 - #include <linux/kernel.h> 12 - #include <linux/scatterlist.h> 13 - #include <linux/slab.h> 14 - #include <linux/vmalloc.h> 15 - 16 - #include <asm/pgalloc.h> 17 - 18 - void *dma_alloc_coherent(struct device *dev, size_t size, 19 - dma_addr_t *handle, gfp_t flag) 20 - { 21 - struct page *page, **map; 22 - pgprot_t pgprot; 23 - void *addr; 24 - int i, order; 25 - 26 - pr_debug("dma_alloc_coherent: %d,%x\n", size, flag); 27 - 28 - size = PAGE_ALIGN(size); 29 - order = get_order(size); 30 - 31 - page = alloc_pages(flag, order); 32 - if (!page) 33 - return NULL; 34 - 35 - *handle = page_to_phys(page); 36 - map = kmalloc(sizeof(struct page *) << order, flag & ~__GFP_DMA); 37 - if (!map) { 38 - __free_pages(page, order); 39 - return NULL; 40 - } 41 - split_page(page, order); 42 - 43 - order = 1 << order; 44 - size >>= PAGE_SHIFT; 45 - map[0] = page; 46 - for (i = 1; i < size; i++) 47 - map[i] = page + i; 48 - for (; i < order; i++) 49 - __free_page(page + i); 50 - pgprot = __pgprot(_PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_DIRTY); 51 - if (CPU_IS_040_OR_060) 52 - pgprot_val(pgprot) |= _PAGE_GLOBAL040 | _PAGE_NOCACHE_S; 53 - else 54 - pgprot_val(pgprot) |= _PAGE_NOCACHE030; 55 - addr = vmap(map, size, VM_MAP, pgprot); 56 - kfree(map); 57 - 58 - return addr; 59 - } 60 - EXPORT_SYMBOL(dma_alloc_coherent); 61 - 62 - void dma_free_coherent(struct device *dev, size_t size, 63 - void *addr, dma_addr_t handle) 64 - { 65 - pr_debug("dma_free_coherent: %p, %x\n", addr, handle); 66 - vfree(addr); 67 - } 68 - EXPORT_SYMBOL(dma_free_coherent); 69 - 70 - void dma_sync_single_for_device(struct device *dev, dma_addr_t handle, 71 - size_t size, enum dma_data_direction dir) 72 - { 73 - switch (dir) { 74 - case DMA_TO_DEVICE: 75 - cache_push(handle, size); 76 - break; 77 - case DMA_FROM_DEVICE: 78 - cache_clear(handle, size); 79 - break; 80 - default: 81 - if (printk_ratelimit()) 82 - printk("dma_sync_single_for_device: unsupported dir %u\n", dir); 83 - break; 84 - } 85 - } 86 - EXPORT_SYMBOL(dma_sync_single_for_device); 87 - 88 - void dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg, int nents, 89 - enum dma_data_direction dir) 90 - { 91 - int i; 92 - 93 - for (i = 0; i < nents; sg++, i++) 94 - dma_sync_single_for_device(dev, sg->dma_address, sg->length, dir); 95 - } 96 - EXPORT_SYMBOL(dma_sync_sg_for_device); 97 - 98 - dma_addr_t dma_map_single(struct device *dev, void *addr, size_t size, 99 - enum dma_data_direction dir) 100 - { 101 - dma_addr_t handle = virt_to_bus(addr); 102 - 103 - dma_sync_single_for_device(dev, handle, size, dir); 104 - return handle; 105 - } 106 - EXPORT_SYMBOL(dma_map_single); 107 - 108 - dma_addr_t dma_map_page(struct device *dev, struct page *page, 109 - unsigned long offset, size_t size, 110 - enum dma_data_direction dir) 111 - { 112 - dma_addr_t handle = page_to_phys(page) + offset; 113 - 114 - dma_sync_single_for_device(dev, handle, size, dir); 115 - return handle; 116 - } 117 - EXPORT_SYMBOL(dma_map_page); 118 - 119 - int dma_map_sg(struct device *dev, struct scatterlist *sg, int nents, 120 - enum dma_data_direction dir) 121 - { 122 - int i; 123 - 124 - for (i = 0; i < nents; sg++, i++) { 125 - sg->dma_address = sg_phys(sg); 126 - dma_sync_single_for_device(dev, sg->dma_address, sg->length, dir); 127 - } 128 - return nents; 129 - } 130 - EXPORT_SYMBOL(dma_map_sg);
··· 1 + #ifdef CONFIG_MMU 2 + #include "dma_mm.c" 3 + #else 4 + #include "dma_no.c" 5 + #endif
+130
arch/m68k/kernel/dma_mm.c
···
··· 1 + /* 2 + * This file is subject to the terms and conditions of the GNU General Public 3 + * License. See the file COPYING in the main directory of this archive 4 + * for more details. 5 + */ 6 + 7 + #undef DEBUG 8 + 9 + #include <linux/dma-mapping.h> 10 + #include <linux/device.h> 11 + #include <linux/kernel.h> 12 + #include <linux/scatterlist.h> 13 + #include <linux/slab.h> 14 + #include <linux/vmalloc.h> 15 + 16 + #include <asm/pgalloc.h> 17 + 18 + void *dma_alloc_coherent(struct device *dev, size_t size, 19 + dma_addr_t *handle, gfp_t flag) 20 + { 21 + struct page *page, **map; 22 + pgprot_t pgprot; 23 + void *addr; 24 + int i, order; 25 + 26 + pr_debug("dma_alloc_coherent: %d,%x\n", size, flag); 27 + 28 + size = PAGE_ALIGN(size); 29 + order = get_order(size); 30 + 31 + page = alloc_pages(flag, order); 32 + if (!page) 33 + return NULL; 34 + 35 + *handle = page_to_phys(page); 36 + map = kmalloc(sizeof(struct page *) << order, flag & ~__GFP_DMA); 37 + if (!map) { 38 + __free_pages(page, order); 39 + return NULL; 40 + } 41 + split_page(page, order); 42 + 43 + order = 1 << order; 44 + size >>= PAGE_SHIFT; 45 + map[0] = page; 46 + for (i = 1; i < size; i++) 47 + map[i] = page + i; 48 + for (; i < order; i++) 49 + __free_page(page + i); 50 + pgprot = __pgprot(_PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_DIRTY); 51 + if (CPU_IS_040_OR_060) 52 + pgprot_val(pgprot) |= _PAGE_GLOBAL040 | _PAGE_NOCACHE_S; 53 + else 54 + pgprot_val(pgprot) |= _PAGE_NOCACHE030; 55 + addr = vmap(map, size, VM_MAP, pgprot); 56 + kfree(map); 57 + 58 + return addr; 59 + } 60 + EXPORT_SYMBOL(dma_alloc_coherent); 61 + 62 + void dma_free_coherent(struct device *dev, size_t size, 63 + void *addr, dma_addr_t handle) 64 + { 65 + pr_debug("dma_free_coherent: %p, %x\n", addr, handle); 66 + vfree(addr); 67 + } 68 + EXPORT_SYMBOL(dma_free_coherent); 69 + 70 + void dma_sync_single_for_device(struct device *dev, dma_addr_t handle, 71 + size_t size, enum dma_data_direction dir) 72 + { 73 + switch (dir) { 74 + case DMA_TO_DEVICE: 75 + cache_push(handle, size); 76 + break; 77 + case DMA_FROM_DEVICE: 78 + cache_clear(handle, size); 79 + break; 80 + default: 81 + if (printk_ratelimit()) 82 + printk("dma_sync_single_for_device: unsupported dir %u\n", dir); 83 + break; 84 + } 85 + } 86 + EXPORT_SYMBOL(dma_sync_single_for_device); 87 + 88 + void dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg, int nents, 89 + enum dma_data_direction dir) 90 + { 91 + int i; 92 + 93 + for (i = 0; i < nents; sg++, i++) 94 + dma_sync_single_for_device(dev, sg->dma_address, sg->length, dir); 95 + } 96 + EXPORT_SYMBOL(dma_sync_sg_for_device); 97 + 98 + dma_addr_t dma_map_single(struct device *dev, void *addr, size_t size, 99 + enum dma_data_direction dir) 100 + { 101 + dma_addr_t handle = virt_to_bus(addr); 102 + 103 + dma_sync_single_for_device(dev, handle, size, dir); 104 + return handle; 105 + } 106 + EXPORT_SYMBOL(dma_map_single); 107 + 108 + dma_addr_t dma_map_page(struct device *dev, struct page *page, 109 + unsigned long offset, size_t size, 110 + enum dma_data_direction dir) 111 + { 112 + dma_addr_t handle = page_to_phys(page) + offset; 113 + 114 + dma_sync_single_for_device(dev, handle, size, dir); 115 + return handle; 116 + } 117 + EXPORT_SYMBOL(dma_map_page); 118 + 119 + int dma_map_sg(struct device *dev, struct scatterlist *sg, int nents, 120 + enum dma_data_direction dir) 121 + { 122 + int i; 123 + 124 + for (i = 0; i < nents; sg++, i++) { 125 + sg->dma_address = sg_phys(sg); 126 + dma_sync_single_for_device(dev, sg->dma_address, sg->length, dir); 127 + } 128 + return nents; 129 + } 130 + EXPORT_SYMBOL(dma_map_sg);
+4 -752
arch/m68k/kernel/entry.S
··· 1 - /* -*- mode: asm -*- 2 - * 3 - * linux/arch/m68k/kernel/entry.S 4 - * 5 - * Copyright (C) 1991, 1992 Linus Torvalds 6 - * 7 - * This file is subject to the terms and conditions of the GNU General Public 8 - * License. See the file README.legal in the main directory of this archive 9 - * for more details. 10 - * 11 - * Linux/m68k support by Hamish Macdonald 12 - * 13 - * 68060 fixes by Jesper Skov 14 - * 15 - */ 16 - 17 - /* 18 - * entry.S contains the system-call and fault low-level handling routines. 19 - * This also contains the timer-interrupt handler, as well as all interrupts 20 - * and faults that can result in a task-switch. 21 - * 22 - * NOTE: This code handles signal-recognition, which happens every time 23 - * after a timer-interrupt and after each system call. 24 - * 25 - */ 26 - 27 - /* 28 - * 12/03/96 Jes: Currently we only support m68k single-cpu systems, so 29 - * all pointers that used to be 'current' are now entry 30 - * number 0 in the 'current_set' list. 31 - * 32 - * 6/05/00 RZ: addedd writeback completion after return from sighandler 33 - * for 68040 34 - */ 35 - 36 - #include <linux/linkage.h> 37 - #include <asm/entry.h> 38 - #include <asm/errno.h> 39 - #include <asm/setup.h> 40 - #include <asm/segment.h> 41 - #include <asm/traps.h> 42 - #include <asm/unistd.h> 43 - 44 - #include <asm/asm-offsets.h> 45 - 46 - .globl system_call, buserr, trap, resume 47 - .globl sys_call_table 48 - .globl sys_fork, sys_clone, sys_vfork 49 - .globl ret_from_interrupt, bad_interrupt 50 - .globl auto_irqhandler_fixup 51 - .globl user_irqvec_fixup, user_irqhandler_fixup 52 - 53 - .text 54 - ENTRY(buserr) 55 - SAVE_ALL_INT 56 - GET_CURRENT(%d0) 57 - movel %sp,%sp@- | stack frame pointer argument 58 - bsrl buserr_c 59 - addql #4,%sp 60 - jra .Lret_from_exception 61 - 62 - ENTRY(trap) 63 - SAVE_ALL_INT 64 - GET_CURRENT(%d0) 65 - movel %sp,%sp@- | stack frame pointer argument 66 - bsrl trap_c 67 - addql #4,%sp 68 - jra .Lret_from_exception 69 - 70 - | After a fork we jump here directly from resume, 71 - | so that %d1 contains the previous task 72 - | schedule_tail now used regardless of CONFIG_SMP 73 - ENTRY(ret_from_fork) 74 - movel %d1,%sp@- 75 - jsr schedule_tail 76 - addql #4,%sp 77 - jra .Lret_from_exception 78 - 79 - do_trace_entry: 80 - movel #-ENOSYS,%sp@(PT_OFF_D0)| needed for strace 81 - subql #4,%sp 82 - SAVE_SWITCH_STACK 83 - jbsr syscall_trace 84 - RESTORE_SWITCH_STACK 85 - addql #4,%sp 86 - movel %sp@(PT_OFF_ORIG_D0),%d0 87 - cmpl #NR_syscalls,%d0 88 - jcs syscall 89 - badsys: 90 - movel #-ENOSYS,%sp@(PT_OFF_D0) 91 - jra ret_from_syscall 92 - 93 - do_trace_exit: 94 - subql #4,%sp 95 - SAVE_SWITCH_STACK 96 - jbsr syscall_trace 97 - RESTORE_SWITCH_STACK 98 - addql #4,%sp 99 - jra .Lret_from_exception 100 - 101 - ENTRY(ret_from_signal) 102 - tstb %curptr@(TASK_INFO+TINFO_FLAGS+2) 103 - jge 1f 104 - jbsr syscall_trace 105 - 1: RESTORE_SWITCH_STACK 106 - addql #4,%sp 107 - /* on 68040 complete pending writebacks if any */ 108 - #ifdef CONFIG_M68040 109 - bfextu %sp@(PT_OFF_FORMATVEC){#0,#4},%d0 110 - subql #7,%d0 | bus error frame ? 111 - jbne 1f 112 - movel %sp,%sp@- 113 - jbsr berr_040cleanup 114 - addql #4,%sp 115 - 1: 116 #endif 117 - jra .Lret_from_exception 118 - 119 - ENTRY(system_call) 120 - SAVE_ALL_SYS 121 - 122 - GET_CURRENT(%d1) 123 - | save top of frame 124 - movel %sp,%curptr@(TASK_THREAD+THREAD_ESP0) 125 - 126 - | syscall trace? 127 - tstb %curptr@(TASK_INFO+TINFO_FLAGS+2) 128 - jmi do_trace_entry 129 - cmpl #NR_syscalls,%d0 130 - jcc badsys 131 - syscall: 132 - jbsr @(sys_call_table,%d0:l:4)@(0) 133 - movel %d0,%sp@(PT_OFF_D0) | save the return value 134 - ret_from_syscall: 135 - |oriw #0x0700,%sr 136 - movew %curptr@(TASK_INFO+TINFO_FLAGS+2),%d0 137 - jne syscall_exit_work 138 - 1: RESTORE_ALL 139 - 140 - syscall_exit_work: 141 - btst #5,%sp@(PT_OFF_SR) | check if returning to kernel 142 - bnes 1b | if so, skip resched, signals 143 - lslw #1,%d0 144 - jcs do_trace_exit 145 - jmi do_delayed_trace 146 - lslw #8,%d0 147 - jmi do_signal_return 148 - pea resume_userspace 149 - jra schedule 150 - 151 - 152 - ENTRY(ret_from_exception) 153 - .Lret_from_exception: 154 - btst #5,%sp@(PT_OFF_SR) | check if returning to kernel 155 - bnes 1f | if so, skip resched, signals 156 - | only allow interrupts when we are really the last one on the 157 - | kernel stack, otherwise stack overflow can occur during 158 - | heavy interrupt load 159 - andw #ALLOWINT,%sr 160 - 161 - resume_userspace: 162 - moveb %curptr@(TASK_INFO+TINFO_FLAGS+3),%d0 163 - jne exit_work 164 - 1: RESTORE_ALL 165 - 166 - exit_work: 167 - | save top of frame 168 - movel %sp,%curptr@(TASK_THREAD+THREAD_ESP0) 169 - lslb #1,%d0 170 - jmi do_signal_return 171 - pea resume_userspace 172 - jra schedule 173 - 174 - 175 - do_signal_return: 176 - |andw #ALLOWINT,%sr 177 - subql #4,%sp | dummy return address 178 - SAVE_SWITCH_STACK 179 - pea %sp@(SWITCH_STACK_SIZE) 180 - bsrl do_signal 181 - addql #4,%sp 182 - RESTORE_SWITCH_STACK 183 - addql #4,%sp 184 - jbra resume_userspace 185 - 186 - do_delayed_trace: 187 - bclr #7,%sp@(PT_OFF_SR) | clear trace bit in SR 188 - pea 1 | send SIGTRAP 189 - movel %curptr,%sp@- 190 - pea LSIGTRAP 191 - jbsr send_sig 192 - addql #8,%sp 193 - addql #4,%sp 194 - jbra resume_userspace 195 - 196 - 197 - /* This is the main interrupt handler for autovector interrupts */ 198 - 199 - ENTRY(auto_inthandler) 200 - SAVE_ALL_INT 201 - GET_CURRENT(%d0) 202 - addqb #1,%curptr@(TASK_INFO+TINFO_PREEMPT+1) 203 - | put exception # in d0 204 - bfextu %sp@(PT_OFF_FORMATVEC){#4,#10},%d0 205 - subw #VEC_SPUR,%d0 206 - 207 - movel %sp,%sp@- 208 - movel %d0,%sp@- | put vector # on stack 209 - auto_irqhandler_fixup = . + 2 210 - jsr __m68k_handle_int | process the IRQ 211 - addql #8,%sp | pop parameters off stack 212 - 213 - ret_from_interrupt: 214 - subqb #1,%curptr@(TASK_INFO+TINFO_PREEMPT+1) 215 - jeq ret_from_last_interrupt 216 - 2: RESTORE_ALL 217 - 218 - ALIGN 219 - ret_from_last_interrupt: 220 - moveq #(~ALLOWINT>>8)&0xff,%d0 221 - andb %sp@(PT_OFF_SR),%d0 222 - jne 2b 223 - 224 - /* check if we need to do software interrupts */ 225 - tstl irq_stat+CPUSTAT_SOFTIRQ_PENDING 226 - jeq .Lret_from_exception 227 - pea ret_from_exception 228 - jra do_softirq 229 - 230 - /* Handler for user defined interrupt vectors */ 231 - 232 - ENTRY(user_inthandler) 233 - SAVE_ALL_INT 234 - GET_CURRENT(%d0) 235 - addqb #1,%curptr@(TASK_INFO+TINFO_PREEMPT+1) 236 - | put exception # in d0 237 - bfextu %sp@(PT_OFF_FORMATVEC){#4,#10},%d0 238 - user_irqvec_fixup = . + 2 239 - subw #VEC_USER,%d0 240 - 241 - movel %sp,%sp@- 242 - movel %d0,%sp@- | put vector # on stack 243 - user_irqhandler_fixup = . + 2 244 - jsr __m68k_handle_int | process the IRQ 245 - addql #8,%sp | pop parameters off stack 246 - 247 - subqb #1,%curptr@(TASK_INFO+TINFO_PREEMPT+1) 248 - jeq ret_from_last_interrupt 249 - RESTORE_ALL 250 - 251 - /* Handler for uninitialized and spurious interrupts */ 252 - 253 - ENTRY(bad_inthandler) 254 - SAVE_ALL_INT 255 - GET_CURRENT(%d0) 256 - addqb #1,%curptr@(TASK_INFO+TINFO_PREEMPT+1) 257 - 258 - movel %sp,%sp@- 259 - jsr handle_badint 260 - addql #4,%sp 261 - 262 - subqb #1,%curptr@(TASK_INFO+TINFO_PREEMPT+1) 263 - jeq ret_from_last_interrupt 264 - RESTORE_ALL 265 - 266 - 267 - ENTRY(sys_fork) 268 - SAVE_SWITCH_STACK 269 - pea %sp@(SWITCH_STACK_SIZE) 270 - jbsr m68k_fork 271 - addql #4,%sp 272 - RESTORE_SWITCH_STACK 273 - rts 274 - 275 - ENTRY(sys_clone) 276 - SAVE_SWITCH_STACK 277 - pea %sp@(SWITCH_STACK_SIZE) 278 - jbsr m68k_clone 279 - addql #4,%sp 280 - RESTORE_SWITCH_STACK 281 - rts 282 - 283 - ENTRY(sys_vfork) 284 - SAVE_SWITCH_STACK 285 - pea %sp@(SWITCH_STACK_SIZE) 286 - jbsr m68k_vfork 287 - addql #4,%sp 288 - RESTORE_SWITCH_STACK 289 - rts 290 - 291 - ENTRY(sys_sigreturn) 292 - SAVE_SWITCH_STACK 293 - jbsr do_sigreturn 294 - RESTORE_SWITCH_STACK 295 - rts 296 - 297 - ENTRY(sys_rt_sigreturn) 298 - SAVE_SWITCH_STACK 299 - jbsr do_rt_sigreturn 300 - RESTORE_SWITCH_STACK 301 - rts 302 - 303 - resume: 304 - /* 305 - * Beware - when entering resume, prev (the current task) is 306 - * in a0, next (the new task) is in a1,so don't change these 307 - * registers until their contents are no longer needed. 308 - */ 309 - 310 - /* save sr */ 311 - movew %sr,%a0@(TASK_THREAD+THREAD_SR) 312 - 313 - /* save fs (sfc,%dfc) (may be pointing to kernel memory) */ 314 - movec %sfc,%d0 315 - movew %d0,%a0@(TASK_THREAD+THREAD_FS) 316 - 317 - /* save usp */ 318 - /* it is better to use a movel here instead of a movew 8*) */ 319 - movec %usp,%d0 320 - movel %d0,%a0@(TASK_THREAD+THREAD_USP) 321 - 322 - /* save non-scratch registers on stack */ 323 - SAVE_SWITCH_STACK 324 - 325 - /* save current kernel stack pointer */ 326 - movel %sp,%a0@(TASK_THREAD+THREAD_KSP) 327 - 328 - /* save floating point context */ 329 - #ifndef CONFIG_M68KFPU_EMU_ONLY 330 - #ifdef CONFIG_M68KFPU_EMU 331 - tstl m68k_fputype 332 - jeq 3f 333 - #endif 334 - fsave %a0@(TASK_THREAD+THREAD_FPSTATE) 335 - 336 - #if defined(CONFIG_M68060) 337 - #if !defined(CPU_M68060_ONLY) 338 - btst #3,m68k_cputype+3 339 - beqs 1f 340 - #endif 341 - /* The 060 FPU keeps status in bits 15-8 of the first longword */ 342 - tstb %a0@(TASK_THREAD+THREAD_FPSTATE+2) 343 - jeq 3f 344 - #if !defined(CPU_M68060_ONLY) 345 - jra 2f 346 - #endif 347 - #endif /* CONFIG_M68060 */ 348 - #if !defined(CPU_M68060_ONLY) 349 - 1: tstb %a0@(TASK_THREAD+THREAD_FPSTATE) 350 - jeq 3f 351 - #endif 352 - 2: fmovemx %fp0-%fp7,%a0@(TASK_THREAD+THREAD_FPREG) 353 - fmoveml %fpcr/%fpsr/%fpiar,%a0@(TASK_THREAD+THREAD_FPCNTL) 354 - 3: 355 - #endif /* CONFIG_M68KFPU_EMU_ONLY */ 356 - /* Return previous task in %d1 */ 357 - movel %curptr,%d1 358 - 359 - /* switch to new task (a1 contains new task) */ 360 - movel %a1,%curptr 361 - 362 - /* restore floating point context */ 363 - #ifndef CONFIG_M68KFPU_EMU_ONLY 364 - #ifdef CONFIG_M68KFPU_EMU 365 - tstl m68k_fputype 366 - jeq 4f 367 - #endif 368 - #if defined(CONFIG_M68060) 369 - #if !defined(CPU_M68060_ONLY) 370 - btst #3,m68k_cputype+3 371 - beqs 1f 372 - #endif 373 - /* The 060 FPU keeps status in bits 15-8 of the first longword */ 374 - tstb %a1@(TASK_THREAD+THREAD_FPSTATE+2) 375 - jeq 3f 376 - #if !defined(CPU_M68060_ONLY) 377 - jra 2f 378 - #endif 379 - #endif /* CONFIG_M68060 */ 380 - #if !defined(CPU_M68060_ONLY) 381 - 1: tstb %a1@(TASK_THREAD+THREAD_FPSTATE) 382 - jeq 3f 383 - #endif 384 - 2: fmovemx %a1@(TASK_THREAD+THREAD_FPREG),%fp0-%fp7 385 - fmoveml %a1@(TASK_THREAD+THREAD_FPCNTL),%fpcr/%fpsr/%fpiar 386 - 3: frestore %a1@(TASK_THREAD+THREAD_FPSTATE) 387 - 4: 388 - #endif /* CONFIG_M68KFPU_EMU_ONLY */ 389 - 390 - /* restore the kernel stack pointer */ 391 - movel %a1@(TASK_THREAD+THREAD_KSP),%sp 392 - 393 - /* restore non-scratch registers */ 394 - RESTORE_SWITCH_STACK 395 - 396 - /* restore user stack pointer */ 397 - movel %a1@(TASK_THREAD+THREAD_USP),%a0 398 - movel %a0,%usp 399 - 400 - /* restore fs (sfc,%dfc) */ 401 - movew %a1@(TASK_THREAD+THREAD_FS),%a0 402 - movec %a0,%sfc 403 - movec %a0,%dfc 404 - 405 - /* restore status register */ 406 - movew %a1@(TASK_THREAD+THREAD_SR),%sr 407 - 408 - rts 409 - 410 - .data 411 - ALIGN 412 - sys_call_table: 413 - .long sys_restart_syscall /* 0 - old "setup()" system call, used for restarting */ 414 - .long sys_exit 415 - .long sys_fork 416 - .long sys_read 417 - .long sys_write 418 - .long sys_open /* 5 */ 419 - .long sys_close 420 - .long sys_waitpid 421 - .long sys_creat 422 - .long sys_link 423 - .long sys_unlink /* 10 */ 424 - .long sys_execve 425 - .long sys_chdir 426 - .long sys_time 427 - .long sys_mknod 428 - .long sys_chmod /* 15 */ 429 - .long sys_chown16 430 - .long sys_ni_syscall /* old break syscall holder */ 431 - .long sys_stat 432 - .long sys_lseek 433 - .long sys_getpid /* 20 */ 434 - .long sys_mount 435 - .long sys_oldumount 436 - .long sys_setuid16 437 - .long sys_getuid16 438 - .long sys_stime /* 25 */ 439 - .long sys_ptrace 440 - .long sys_alarm 441 - .long sys_fstat 442 - .long sys_pause 443 - .long sys_utime /* 30 */ 444 - .long sys_ni_syscall /* old stty syscall holder */ 445 - .long sys_ni_syscall /* old gtty syscall holder */ 446 - .long sys_access 447 - .long sys_nice 448 - .long sys_ni_syscall /* 35 */ /* old ftime syscall holder */ 449 - .long sys_sync 450 - .long sys_kill 451 - .long sys_rename 452 - .long sys_mkdir 453 - .long sys_rmdir /* 40 */ 454 - .long sys_dup 455 - .long sys_pipe 456 - .long sys_times 457 - .long sys_ni_syscall /* old prof syscall holder */ 458 - .long sys_brk /* 45 */ 459 - .long sys_setgid16 460 - .long sys_getgid16 461 - .long sys_signal 462 - .long sys_geteuid16 463 - .long sys_getegid16 /* 50 */ 464 - .long sys_acct 465 - .long sys_umount /* recycled never used phys() */ 466 - .long sys_ni_syscall /* old lock syscall holder */ 467 - .long sys_ioctl 468 - .long sys_fcntl /* 55 */ 469 - .long sys_ni_syscall /* old mpx syscall holder */ 470 - .long sys_setpgid 471 - .long sys_ni_syscall /* old ulimit syscall holder */ 472 - .long sys_ni_syscall 473 - .long sys_umask /* 60 */ 474 - .long sys_chroot 475 - .long sys_ustat 476 - .long sys_dup2 477 - .long sys_getppid 478 - .long sys_getpgrp /* 65 */ 479 - .long sys_setsid 480 - .long sys_sigaction 481 - .long sys_sgetmask 482 - .long sys_ssetmask 483 - .long sys_setreuid16 /* 70 */ 484 - .long sys_setregid16 485 - .long sys_sigsuspend 486 - .long sys_sigpending 487 - .long sys_sethostname 488 - .long sys_setrlimit /* 75 */ 489 - .long sys_old_getrlimit 490 - .long sys_getrusage 491 - .long sys_gettimeofday 492 - .long sys_settimeofday 493 - .long sys_getgroups16 /* 80 */ 494 - .long sys_setgroups16 495 - .long sys_old_select 496 - .long sys_symlink 497 - .long sys_lstat 498 - .long sys_readlink /* 85 */ 499 - .long sys_uselib 500 - .long sys_swapon 501 - .long sys_reboot 502 - .long sys_old_readdir 503 - .long sys_old_mmap /* 90 */ 504 - .long sys_munmap 505 - .long sys_truncate 506 - .long sys_ftruncate 507 - .long sys_fchmod 508 - .long sys_fchown16 /* 95 */ 509 - .long sys_getpriority 510 - .long sys_setpriority 511 - .long sys_ni_syscall /* old profil syscall holder */ 512 - .long sys_statfs 513 - .long sys_fstatfs /* 100 */ 514 - .long sys_ni_syscall /* ioperm for i386 */ 515 - .long sys_socketcall 516 - .long sys_syslog 517 - .long sys_setitimer 518 - .long sys_getitimer /* 105 */ 519 - .long sys_newstat 520 - .long sys_newlstat 521 - .long sys_newfstat 522 - .long sys_ni_syscall 523 - .long sys_ni_syscall /* 110 */ /* iopl for i386 */ 524 - .long sys_vhangup 525 - .long sys_ni_syscall /* obsolete idle() syscall */ 526 - .long sys_ni_syscall /* vm86old for i386 */ 527 - .long sys_wait4 528 - .long sys_swapoff /* 115 */ 529 - .long sys_sysinfo 530 - .long sys_ipc 531 - .long sys_fsync 532 - .long sys_sigreturn 533 - .long sys_clone /* 120 */ 534 - .long sys_setdomainname 535 - .long sys_newuname 536 - .long sys_cacheflush /* modify_ldt for i386 */ 537 - .long sys_adjtimex 538 - .long sys_mprotect /* 125 */ 539 - .long sys_sigprocmask 540 - .long sys_ni_syscall /* old "create_module" */ 541 - .long sys_init_module 542 - .long sys_delete_module 543 - .long sys_ni_syscall /* 130 - old "get_kernel_syms" */ 544 - .long sys_quotactl 545 - .long sys_getpgid 546 - .long sys_fchdir 547 - .long sys_bdflush 548 - .long sys_sysfs /* 135 */ 549 - .long sys_personality 550 - .long sys_ni_syscall /* for afs_syscall */ 551 - .long sys_setfsuid16 552 - .long sys_setfsgid16 553 - .long sys_llseek /* 140 */ 554 - .long sys_getdents 555 - .long sys_select 556 - .long sys_flock 557 - .long sys_msync 558 - .long sys_readv /* 145 */ 559 - .long sys_writev 560 - .long sys_getsid 561 - .long sys_fdatasync 562 - .long sys_sysctl 563 - .long sys_mlock /* 150 */ 564 - .long sys_munlock 565 - .long sys_mlockall 566 - .long sys_munlockall 567 - .long sys_sched_setparam 568 - .long sys_sched_getparam /* 155 */ 569 - .long sys_sched_setscheduler 570 - .long sys_sched_getscheduler 571 - .long sys_sched_yield 572 - .long sys_sched_get_priority_max 573 - .long sys_sched_get_priority_min /* 160 */ 574 - .long sys_sched_rr_get_interval 575 - .long sys_nanosleep 576 - .long sys_mremap 577 - .long sys_setresuid16 578 - .long sys_getresuid16 /* 165 */ 579 - .long sys_getpagesize 580 - .long sys_ni_syscall /* old sys_query_module */ 581 - .long sys_poll 582 - .long sys_nfsservctl 583 - .long sys_setresgid16 /* 170 */ 584 - .long sys_getresgid16 585 - .long sys_prctl 586 - .long sys_rt_sigreturn 587 - .long sys_rt_sigaction 588 - .long sys_rt_sigprocmask /* 175 */ 589 - .long sys_rt_sigpending 590 - .long sys_rt_sigtimedwait 591 - .long sys_rt_sigqueueinfo 592 - .long sys_rt_sigsuspend 593 - .long sys_pread64 /* 180 */ 594 - .long sys_pwrite64 595 - .long sys_lchown16; 596 - .long sys_getcwd 597 - .long sys_capget 598 - .long sys_capset /* 185 */ 599 - .long sys_sigaltstack 600 - .long sys_sendfile 601 - .long sys_ni_syscall /* streams1 */ 602 - .long sys_ni_syscall /* streams2 */ 603 - .long sys_vfork /* 190 */ 604 - .long sys_getrlimit 605 - .long sys_mmap2 606 - .long sys_truncate64 607 - .long sys_ftruncate64 608 - .long sys_stat64 /* 195 */ 609 - .long sys_lstat64 610 - .long sys_fstat64 611 - .long sys_chown 612 - .long sys_getuid 613 - .long sys_getgid /* 200 */ 614 - .long sys_geteuid 615 - .long sys_getegid 616 - .long sys_setreuid 617 - .long sys_setregid 618 - .long sys_getgroups /* 205 */ 619 - .long sys_setgroups 620 - .long sys_fchown 621 - .long sys_setresuid 622 - .long sys_getresuid 623 - .long sys_setresgid /* 210 */ 624 - .long sys_getresgid 625 - .long sys_lchown 626 - .long sys_setuid 627 - .long sys_setgid 628 - .long sys_setfsuid /* 215 */ 629 - .long sys_setfsgid 630 - .long sys_pivot_root 631 - .long sys_ni_syscall 632 - .long sys_ni_syscall 633 - .long sys_getdents64 /* 220 */ 634 - .long sys_gettid 635 - .long sys_tkill 636 - .long sys_setxattr 637 - .long sys_lsetxattr 638 - .long sys_fsetxattr /* 225 */ 639 - .long sys_getxattr 640 - .long sys_lgetxattr 641 - .long sys_fgetxattr 642 - .long sys_listxattr 643 - .long sys_llistxattr /* 230 */ 644 - .long sys_flistxattr 645 - .long sys_removexattr 646 - .long sys_lremovexattr 647 - .long sys_fremovexattr 648 - .long sys_futex /* 235 */ 649 - .long sys_sendfile64 650 - .long sys_mincore 651 - .long sys_madvise 652 - .long sys_fcntl64 653 - .long sys_readahead /* 240 */ 654 - .long sys_io_setup 655 - .long sys_io_destroy 656 - .long sys_io_getevents 657 - .long sys_io_submit 658 - .long sys_io_cancel /* 245 */ 659 - .long sys_fadvise64 660 - .long sys_exit_group 661 - .long sys_lookup_dcookie 662 - .long sys_epoll_create 663 - .long sys_epoll_ctl /* 250 */ 664 - .long sys_epoll_wait 665 - .long sys_remap_file_pages 666 - .long sys_set_tid_address 667 - .long sys_timer_create 668 - .long sys_timer_settime /* 255 */ 669 - .long sys_timer_gettime 670 - .long sys_timer_getoverrun 671 - .long sys_timer_delete 672 - .long sys_clock_settime 673 - .long sys_clock_gettime /* 260 */ 674 - .long sys_clock_getres 675 - .long sys_clock_nanosleep 676 - .long sys_statfs64 677 - .long sys_fstatfs64 678 - .long sys_tgkill /* 265 */ 679 - .long sys_utimes 680 - .long sys_fadvise64_64 681 - .long sys_mbind 682 - .long sys_get_mempolicy 683 - .long sys_set_mempolicy /* 270 */ 684 - .long sys_mq_open 685 - .long sys_mq_unlink 686 - .long sys_mq_timedsend 687 - .long sys_mq_timedreceive 688 - .long sys_mq_notify /* 275 */ 689 - .long sys_mq_getsetattr 690 - .long sys_waitid 691 - .long sys_ni_syscall /* for sys_vserver */ 692 - .long sys_add_key 693 - .long sys_request_key /* 280 */ 694 - .long sys_keyctl 695 - .long sys_ioprio_set 696 - .long sys_ioprio_get 697 - .long sys_inotify_init 698 - .long sys_inotify_add_watch /* 285 */ 699 - .long sys_inotify_rm_watch 700 - .long sys_migrate_pages 701 - .long sys_openat 702 - .long sys_mkdirat 703 - .long sys_mknodat /* 290 */ 704 - .long sys_fchownat 705 - .long sys_futimesat 706 - .long sys_fstatat64 707 - .long sys_unlinkat 708 - .long sys_renameat /* 295 */ 709 - .long sys_linkat 710 - .long sys_symlinkat 711 - .long sys_readlinkat 712 - .long sys_fchmodat 713 - .long sys_faccessat /* 300 */ 714 - .long sys_ni_syscall /* Reserved for pselect6 */ 715 - .long sys_ni_syscall /* Reserved for ppoll */ 716 - .long sys_unshare 717 - .long sys_set_robust_list 718 - .long sys_get_robust_list /* 305 */ 719 - .long sys_splice 720 - .long sys_sync_file_range 721 - .long sys_tee 722 - .long sys_vmsplice 723 - .long sys_move_pages /* 310 */ 724 - .long sys_sched_setaffinity 725 - .long sys_sched_getaffinity 726 - .long sys_kexec_load 727 - .long sys_getcpu 728 - .long sys_epoll_pwait /* 315 */ 729 - .long sys_utimensat 730 - .long sys_signalfd 731 - .long sys_timerfd_create 732 - .long sys_eventfd 733 - .long sys_fallocate /* 320 */ 734 - .long sys_timerfd_settime 735 - .long sys_timerfd_gettime 736 - .long sys_signalfd4 737 - .long sys_eventfd2 738 - .long sys_epoll_create1 /* 325 */ 739 - .long sys_dup3 740 - .long sys_pipe2 741 - .long sys_inotify_init1 742 - .long sys_preadv 743 - .long sys_pwritev /* 330 */ 744 - .long sys_rt_tgsigqueueinfo 745 - .long sys_perf_event_open 746 - .long sys_get_thread_area 747 - .long sys_set_thread_area 748 - .long sys_atomic_cmpxchg_32 /* 335 */ 749 - .long sys_atomic_barrier 750 - .long sys_fanotify_init 751 - .long sys_fanotify_mark 752 - .long sys_prlimit64 753 -
··· 1 + #ifdef CONFIG_MMU 2 + #include "entry_mm.S" 3 + #else 4 + #include "entry_no.S" 5 #endif
+753
arch/m68k/kernel/entry_mm.S
···
··· 1 + /* -*- mode: asm -*- 2 + * 3 + * linux/arch/m68k/kernel/entry.S 4 + * 5 + * Copyright (C) 1991, 1992 Linus Torvalds 6 + * 7 + * This file is subject to the terms and conditions of the GNU General Public 8 + * License. See the file README.legal in the main directory of this archive 9 + * for more details. 10 + * 11 + * Linux/m68k support by Hamish Macdonald 12 + * 13 + * 68060 fixes by Jesper Skov 14 + * 15 + */ 16 + 17 + /* 18 + * entry.S contains the system-call and fault low-level handling routines. 19 + * This also contains the timer-interrupt handler, as well as all interrupts 20 + * and faults that can result in a task-switch. 21 + * 22 + * NOTE: This code handles signal-recognition, which happens every time 23 + * after a timer-interrupt and after each system call. 24 + * 25 + */ 26 + 27 + /* 28 + * 12/03/96 Jes: Currently we only support m68k single-cpu systems, so 29 + * all pointers that used to be 'current' are now entry 30 + * number 0 in the 'current_set' list. 31 + * 32 + * 6/05/00 RZ: addedd writeback completion after return from sighandler 33 + * for 68040 34 + */ 35 + 36 + #include <linux/linkage.h> 37 + #include <asm/entry.h> 38 + #include <asm/errno.h> 39 + #include <asm/setup.h> 40 + #include <asm/segment.h> 41 + #include <asm/traps.h> 42 + #include <asm/unistd.h> 43 + 44 + #include <asm/asm-offsets.h> 45 + 46 + .globl system_call, buserr, trap, resume 47 + .globl sys_call_table 48 + .globl sys_fork, sys_clone, sys_vfork 49 + .globl ret_from_interrupt, bad_interrupt 50 + .globl auto_irqhandler_fixup 51 + .globl user_irqvec_fixup, user_irqhandler_fixup 52 + 53 + .text 54 + ENTRY(buserr) 55 + SAVE_ALL_INT 56 + GET_CURRENT(%d0) 57 + movel %sp,%sp@- | stack frame pointer argument 58 + bsrl buserr_c 59 + addql #4,%sp 60 + jra .Lret_from_exception 61 + 62 + ENTRY(trap) 63 + SAVE_ALL_INT 64 + GET_CURRENT(%d0) 65 + movel %sp,%sp@- | stack frame pointer argument 66 + bsrl trap_c 67 + addql #4,%sp 68 + jra .Lret_from_exception 69 + 70 + | After a fork we jump here directly from resume, 71 + | so that %d1 contains the previous task 72 + | schedule_tail now used regardless of CONFIG_SMP 73 + ENTRY(ret_from_fork) 74 + movel %d1,%sp@- 75 + jsr schedule_tail 76 + addql #4,%sp 77 + jra .Lret_from_exception 78 + 79 + do_trace_entry: 80 + movel #-ENOSYS,%sp@(PT_OFF_D0)| needed for strace 81 + subql #4,%sp 82 + SAVE_SWITCH_STACK 83 + jbsr syscall_trace 84 + RESTORE_SWITCH_STACK 85 + addql #4,%sp 86 + movel %sp@(PT_OFF_ORIG_D0),%d0 87 + cmpl #NR_syscalls,%d0 88 + jcs syscall 89 + badsys: 90 + movel #-ENOSYS,%sp@(PT_OFF_D0) 91 + jra ret_from_syscall 92 + 93 + do_trace_exit: 94 + subql #4,%sp 95 + SAVE_SWITCH_STACK 96 + jbsr syscall_trace 97 + RESTORE_SWITCH_STACK 98 + addql #4,%sp 99 + jra .Lret_from_exception 100 + 101 + ENTRY(ret_from_signal) 102 + tstb %curptr@(TASK_INFO+TINFO_FLAGS+2) 103 + jge 1f 104 + jbsr syscall_trace 105 + 1: RESTORE_SWITCH_STACK 106 + addql #4,%sp 107 + /* on 68040 complete pending writebacks if any */ 108 + #ifdef CONFIG_M68040 109 + bfextu %sp@(PT_OFF_FORMATVEC){#0,#4},%d0 110 + subql #7,%d0 | bus error frame ? 111 + jbne 1f 112 + movel %sp,%sp@- 113 + jbsr berr_040cleanup 114 + addql #4,%sp 115 + 1: 116 + #endif 117 + jra .Lret_from_exception 118 + 119 + ENTRY(system_call) 120 + SAVE_ALL_SYS 121 + 122 + GET_CURRENT(%d1) 123 + | save top of frame 124 + movel %sp,%curptr@(TASK_THREAD+THREAD_ESP0) 125 + 126 + | syscall trace? 127 + tstb %curptr@(TASK_INFO+TINFO_FLAGS+2) 128 + jmi do_trace_entry 129 + cmpl #NR_syscalls,%d0 130 + jcc badsys 131 + syscall: 132 + jbsr @(sys_call_table,%d0:l:4)@(0) 133 + movel %d0,%sp@(PT_OFF_D0) | save the return value 134 + ret_from_syscall: 135 + |oriw #0x0700,%sr 136 + movew %curptr@(TASK_INFO+TINFO_FLAGS+2),%d0 137 + jne syscall_exit_work 138 + 1: RESTORE_ALL 139 + 140 + syscall_exit_work: 141 + btst #5,%sp@(PT_OFF_SR) | check if returning to kernel 142 + bnes 1b | if so, skip resched, signals 143 + lslw #1,%d0 144 + jcs do_trace_exit 145 + jmi do_delayed_trace 146 + lslw #8,%d0 147 + jmi do_signal_return 148 + pea resume_userspace 149 + jra schedule 150 + 151 + 152 + ENTRY(ret_from_exception) 153 + .Lret_from_exception: 154 + btst #5,%sp@(PT_OFF_SR) | check if returning to kernel 155 + bnes 1f | if so, skip resched, signals 156 + | only allow interrupts when we are really the last one on the 157 + | kernel stack, otherwise stack overflow can occur during 158 + | heavy interrupt load 159 + andw #ALLOWINT,%sr 160 + 161 + resume_userspace: 162 + moveb %curptr@(TASK_INFO+TINFO_FLAGS+3),%d0 163 + jne exit_work 164 + 1: RESTORE_ALL 165 + 166 + exit_work: 167 + | save top of frame 168 + movel %sp,%curptr@(TASK_THREAD+THREAD_ESP0) 169 + lslb #1,%d0 170 + jmi do_signal_return 171 + pea resume_userspace 172 + jra schedule 173 + 174 + 175 + do_signal_return: 176 + |andw #ALLOWINT,%sr 177 + subql #4,%sp | dummy return address 178 + SAVE_SWITCH_STACK 179 + pea %sp@(SWITCH_STACK_SIZE) 180 + bsrl do_signal 181 + addql #4,%sp 182 + RESTORE_SWITCH_STACK 183 + addql #4,%sp 184 + jbra resume_userspace 185 + 186 + do_delayed_trace: 187 + bclr #7,%sp@(PT_OFF_SR) | clear trace bit in SR 188 + pea 1 | send SIGTRAP 189 + movel %curptr,%sp@- 190 + pea LSIGTRAP 191 + jbsr send_sig 192 + addql #8,%sp 193 + addql #4,%sp 194 + jbra resume_userspace 195 + 196 + 197 + /* This is the main interrupt handler for autovector interrupts */ 198 + 199 + ENTRY(auto_inthandler) 200 + SAVE_ALL_INT 201 + GET_CURRENT(%d0) 202 + addqb #1,%curptr@(TASK_INFO+TINFO_PREEMPT+1) 203 + | put exception # in d0 204 + bfextu %sp@(PT_OFF_FORMATVEC){#4,#10},%d0 205 + subw #VEC_SPUR,%d0 206 + 207 + movel %sp,%sp@- 208 + movel %d0,%sp@- | put vector # on stack 209 + auto_irqhandler_fixup = . + 2 210 + jsr __m68k_handle_int | process the IRQ 211 + addql #8,%sp | pop parameters off stack 212 + 213 + ret_from_interrupt: 214 + subqb #1,%curptr@(TASK_INFO+TINFO_PREEMPT+1) 215 + jeq ret_from_last_interrupt 216 + 2: RESTORE_ALL 217 + 218 + ALIGN 219 + ret_from_last_interrupt: 220 + moveq #(~ALLOWINT>>8)&0xff,%d0 221 + andb %sp@(PT_OFF_SR),%d0 222 + jne 2b 223 + 224 + /* check if we need to do software interrupts */ 225 + tstl irq_stat+CPUSTAT_SOFTIRQ_PENDING 226 + jeq .Lret_from_exception 227 + pea ret_from_exception 228 + jra do_softirq 229 + 230 + /* Handler for user defined interrupt vectors */ 231 + 232 + ENTRY(user_inthandler) 233 + SAVE_ALL_INT 234 + GET_CURRENT(%d0) 235 + addqb #1,%curptr@(TASK_INFO+TINFO_PREEMPT+1) 236 + | put exception # in d0 237 + bfextu %sp@(PT_OFF_FORMATVEC){#4,#10},%d0 238 + user_irqvec_fixup = . + 2 239 + subw #VEC_USER,%d0 240 + 241 + movel %sp,%sp@- 242 + movel %d0,%sp@- | put vector # on stack 243 + user_irqhandler_fixup = . + 2 244 + jsr __m68k_handle_int | process the IRQ 245 + addql #8,%sp | pop parameters off stack 246 + 247 + subqb #1,%curptr@(TASK_INFO+TINFO_PREEMPT+1) 248 + jeq ret_from_last_interrupt 249 + RESTORE_ALL 250 + 251 + /* Handler for uninitialized and spurious interrupts */ 252 + 253 + ENTRY(bad_inthandler) 254 + SAVE_ALL_INT 255 + GET_CURRENT(%d0) 256 + addqb #1,%curptr@(TASK_INFO+TINFO_PREEMPT+1) 257 + 258 + movel %sp,%sp@- 259 + jsr handle_badint 260 + addql #4,%sp 261 + 262 + subqb #1,%curptr@(TASK_INFO+TINFO_PREEMPT+1) 263 + jeq ret_from_last_interrupt 264 + RESTORE_ALL 265 + 266 + 267 + ENTRY(sys_fork) 268 + SAVE_SWITCH_STACK 269 + pea %sp@(SWITCH_STACK_SIZE) 270 + jbsr m68k_fork 271 + addql #4,%sp 272 + RESTORE_SWITCH_STACK 273 + rts 274 + 275 + ENTRY(sys_clone) 276 + SAVE_SWITCH_STACK 277 + pea %sp@(SWITCH_STACK_SIZE) 278 + jbsr m68k_clone 279 + addql #4,%sp 280 + RESTORE_SWITCH_STACK 281 + rts 282 + 283 + ENTRY(sys_vfork) 284 + SAVE_SWITCH_STACK 285 + pea %sp@(SWITCH_STACK_SIZE) 286 + jbsr m68k_vfork 287 + addql #4,%sp 288 + RESTORE_SWITCH_STACK 289 + rts 290 + 291 + ENTRY(sys_sigreturn) 292 + SAVE_SWITCH_STACK 293 + jbsr do_sigreturn 294 + RESTORE_SWITCH_STACK 295 + rts 296 + 297 + ENTRY(sys_rt_sigreturn) 298 + SAVE_SWITCH_STACK 299 + jbsr do_rt_sigreturn 300 + RESTORE_SWITCH_STACK 301 + rts 302 + 303 + resume: 304 + /* 305 + * Beware - when entering resume, prev (the current task) is 306 + * in a0, next (the new task) is in a1,so don't change these 307 + * registers until their contents are no longer needed. 308 + */ 309 + 310 + /* save sr */ 311 + movew %sr,%a0@(TASK_THREAD+THREAD_SR) 312 + 313 + /* save fs (sfc,%dfc) (may be pointing to kernel memory) */ 314 + movec %sfc,%d0 315 + movew %d0,%a0@(TASK_THREAD+THREAD_FS) 316 + 317 + /* save usp */ 318 + /* it is better to use a movel here instead of a movew 8*) */ 319 + movec %usp,%d0 320 + movel %d0,%a0@(TASK_THREAD+THREAD_USP) 321 + 322 + /* save non-scratch registers on stack */ 323 + SAVE_SWITCH_STACK 324 + 325 + /* save current kernel stack pointer */ 326 + movel %sp,%a0@(TASK_THREAD+THREAD_KSP) 327 + 328 + /* save floating point context */ 329 + #ifndef CONFIG_M68KFPU_EMU_ONLY 330 + #ifdef CONFIG_M68KFPU_EMU 331 + tstl m68k_fputype 332 + jeq 3f 333 + #endif 334 + fsave %a0@(TASK_THREAD+THREAD_FPSTATE) 335 + 336 + #if defined(CONFIG_M68060) 337 + #if !defined(CPU_M68060_ONLY) 338 + btst #3,m68k_cputype+3 339 + beqs 1f 340 + #endif 341 + /* The 060 FPU keeps status in bits 15-8 of the first longword */ 342 + tstb %a0@(TASK_THREAD+THREAD_FPSTATE+2) 343 + jeq 3f 344 + #if !defined(CPU_M68060_ONLY) 345 + jra 2f 346 + #endif 347 + #endif /* CONFIG_M68060 */ 348 + #if !defined(CPU_M68060_ONLY) 349 + 1: tstb %a0@(TASK_THREAD+THREAD_FPSTATE) 350 + jeq 3f 351 + #endif 352 + 2: fmovemx %fp0-%fp7,%a0@(TASK_THREAD+THREAD_FPREG) 353 + fmoveml %fpcr/%fpsr/%fpiar,%a0@(TASK_THREAD+THREAD_FPCNTL) 354 + 3: 355 + #endif /* CONFIG_M68KFPU_EMU_ONLY */ 356 + /* Return previous task in %d1 */ 357 + movel %curptr,%d1 358 + 359 + /* switch to new task (a1 contains new task) */ 360 + movel %a1,%curptr 361 + 362 + /* restore floating point context */ 363 + #ifndef CONFIG_M68KFPU_EMU_ONLY 364 + #ifdef CONFIG_M68KFPU_EMU 365 + tstl m68k_fputype 366 + jeq 4f 367 + #endif 368 + #if defined(CONFIG_M68060) 369 + #if !defined(CPU_M68060_ONLY) 370 + btst #3,m68k_cputype+3 371 + beqs 1f 372 + #endif 373 + /* The 060 FPU keeps status in bits 15-8 of the first longword */ 374 + tstb %a1@(TASK_THREAD+THREAD_FPSTATE+2) 375 + jeq 3f 376 + #if !defined(CPU_M68060_ONLY) 377 + jra 2f 378 + #endif 379 + #endif /* CONFIG_M68060 */ 380 + #if !defined(CPU_M68060_ONLY) 381 + 1: tstb %a1@(TASK_THREAD+THREAD_FPSTATE) 382 + jeq 3f 383 + #endif 384 + 2: fmovemx %a1@(TASK_THREAD+THREAD_FPREG),%fp0-%fp7 385 + fmoveml %a1@(TASK_THREAD+THREAD_FPCNTL),%fpcr/%fpsr/%fpiar 386 + 3: frestore %a1@(TASK_THREAD+THREAD_FPSTATE) 387 + 4: 388 + #endif /* CONFIG_M68KFPU_EMU_ONLY */ 389 + 390 + /* restore the kernel stack pointer */ 391 + movel %a1@(TASK_THREAD+THREAD_KSP),%sp 392 + 393 + /* restore non-scratch registers */ 394 + RESTORE_SWITCH_STACK 395 + 396 + /* restore user stack pointer */ 397 + movel %a1@(TASK_THREAD+THREAD_USP),%a0 398 + movel %a0,%usp 399 + 400 + /* restore fs (sfc,%dfc) */ 401 + movew %a1@(TASK_THREAD+THREAD_FS),%a0 402 + movec %a0,%sfc 403 + movec %a0,%dfc 404 + 405 + /* restore status register */ 406 + movew %a1@(TASK_THREAD+THREAD_SR),%sr 407 + 408 + rts 409 + 410 + .data 411 + ALIGN 412 + sys_call_table: 413 + .long sys_restart_syscall /* 0 - old "setup()" system call, used for restarting */ 414 + .long sys_exit 415 + .long sys_fork 416 + .long sys_read 417 + .long sys_write 418 + .long sys_open /* 5 */ 419 + .long sys_close 420 + .long sys_waitpid 421 + .long sys_creat 422 + .long sys_link 423 + .long sys_unlink /* 10 */ 424 + .long sys_execve 425 + .long sys_chdir 426 + .long sys_time 427 + .long sys_mknod 428 + .long sys_chmod /* 15 */ 429 + .long sys_chown16 430 + .long sys_ni_syscall /* old break syscall holder */ 431 + .long sys_stat 432 + .long sys_lseek 433 + .long sys_getpid /* 20 */ 434 + .long sys_mount 435 + .long sys_oldumount 436 + .long sys_setuid16 437 + .long sys_getuid16 438 + .long sys_stime /* 25 */ 439 + .long sys_ptrace 440 + .long sys_alarm 441 + .long sys_fstat 442 + .long sys_pause 443 + .long sys_utime /* 30 */ 444 + .long sys_ni_syscall /* old stty syscall holder */ 445 + .long sys_ni_syscall /* old gtty syscall holder */ 446 + .long sys_access 447 + .long sys_nice 448 + .long sys_ni_syscall /* 35 */ /* old ftime syscall holder */ 449 + .long sys_sync 450 + .long sys_kill 451 + .long sys_rename 452 + .long sys_mkdir 453 + .long sys_rmdir /* 40 */ 454 + .long sys_dup 455 + .long sys_pipe 456 + .long sys_times 457 + .long sys_ni_syscall /* old prof syscall holder */ 458 + .long sys_brk /* 45 */ 459 + .long sys_setgid16 460 + .long sys_getgid16 461 + .long sys_signal 462 + .long sys_geteuid16 463 + .long sys_getegid16 /* 50 */ 464 + .long sys_acct 465 + .long sys_umount /* recycled never used phys() */ 466 + .long sys_ni_syscall /* old lock syscall holder */ 467 + .long sys_ioctl 468 + .long sys_fcntl /* 55 */ 469 + .long sys_ni_syscall /* old mpx syscall holder */ 470 + .long sys_setpgid 471 + .long sys_ni_syscall /* old ulimit syscall holder */ 472 + .long sys_ni_syscall 473 + .long sys_umask /* 60 */ 474 + .long sys_chroot 475 + .long sys_ustat 476 + .long sys_dup2 477 + .long sys_getppid 478 + .long sys_getpgrp /* 65 */ 479 + .long sys_setsid 480 + .long sys_sigaction 481 + .long sys_sgetmask 482 + .long sys_ssetmask 483 + .long sys_setreuid16 /* 70 */ 484 + .long sys_setregid16 485 + .long sys_sigsuspend 486 + .long sys_sigpending 487 + .long sys_sethostname 488 + .long sys_setrlimit /* 75 */ 489 + .long sys_old_getrlimit 490 + .long sys_getrusage 491 + .long sys_gettimeofday 492 + .long sys_settimeofday 493 + .long sys_getgroups16 /* 80 */ 494 + .long sys_setgroups16 495 + .long sys_old_select 496 + .long sys_symlink 497 + .long sys_lstat 498 + .long sys_readlink /* 85 */ 499 + .long sys_uselib 500 + .long sys_swapon 501 + .long sys_reboot 502 + .long sys_old_readdir 503 + .long sys_old_mmap /* 90 */ 504 + .long sys_munmap 505 + .long sys_truncate 506 + .long sys_ftruncate 507 + .long sys_fchmod 508 + .long sys_fchown16 /* 95 */ 509 + .long sys_getpriority 510 + .long sys_setpriority 511 + .long sys_ni_syscall /* old profil syscall holder */ 512 + .long sys_statfs 513 + .long sys_fstatfs /* 100 */ 514 + .long sys_ni_syscall /* ioperm for i386 */ 515 + .long sys_socketcall 516 + .long sys_syslog 517 + .long sys_setitimer 518 + .long sys_getitimer /* 105 */ 519 + .long sys_newstat 520 + .long sys_newlstat 521 + .long sys_newfstat 522 + .long sys_ni_syscall 523 + .long sys_ni_syscall /* 110 */ /* iopl for i386 */ 524 + .long sys_vhangup 525 + .long sys_ni_syscall /* obsolete idle() syscall */ 526 + .long sys_ni_syscall /* vm86old for i386 */ 527 + .long sys_wait4 528 + .long sys_swapoff /* 115 */ 529 + .long sys_sysinfo 530 + .long sys_ipc 531 + .long sys_fsync 532 + .long sys_sigreturn 533 + .long sys_clone /* 120 */ 534 + .long sys_setdomainname 535 + .long sys_newuname 536 + .long sys_cacheflush /* modify_ldt for i386 */ 537 + .long sys_adjtimex 538 + .long sys_mprotect /* 125 */ 539 + .long sys_sigprocmask 540 + .long sys_ni_syscall /* old "create_module" */ 541 + .long sys_init_module 542 + .long sys_delete_module 543 + .long sys_ni_syscall /* 130 - old "get_kernel_syms" */ 544 + .long sys_quotactl 545 + .long sys_getpgid 546 + .long sys_fchdir 547 + .long sys_bdflush 548 + .long sys_sysfs /* 135 */ 549 + .long sys_personality 550 + .long sys_ni_syscall /* for afs_syscall */ 551 + .long sys_setfsuid16 552 + .long sys_setfsgid16 553 + .long sys_llseek /* 140 */ 554 + .long sys_getdents 555 + .long sys_select 556 + .long sys_flock 557 + .long sys_msync 558 + .long sys_readv /* 145 */ 559 + .long sys_writev 560 + .long sys_getsid 561 + .long sys_fdatasync 562 + .long sys_sysctl 563 + .long sys_mlock /* 150 */ 564 + .long sys_munlock 565 + .long sys_mlockall 566 + .long sys_munlockall 567 + .long sys_sched_setparam 568 + .long sys_sched_getparam /* 155 */ 569 + .long sys_sched_setscheduler 570 + .long sys_sched_getscheduler 571 + .long sys_sched_yield 572 + .long sys_sched_get_priority_max 573 + .long sys_sched_get_priority_min /* 160 */ 574 + .long sys_sched_rr_get_interval 575 + .long sys_nanosleep 576 + .long sys_mremap 577 + .long sys_setresuid16 578 + .long sys_getresuid16 /* 165 */ 579 + .long sys_getpagesize 580 + .long sys_ni_syscall /* old sys_query_module */ 581 + .long sys_poll 582 + .long sys_nfsservctl 583 + .long sys_setresgid16 /* 170 */ 584 + .long sys_getresgid16 585 + .long sys_prctl 586 + .long sys_rt_sigreturn 587 + .long sys_rt_sigaction 588 + .long sys_rt_sigprocmask /* 175 */ 589 + .long sys_rt_sigpending 590 + .long sys_rt_sigtimedwait 591 + .long sys_rt_sigqueueinfo 592 + .long sys_rt_sigsuspend 593 + .long sys_pread64 /* 180 */ 594 + .long sys_pwrite64 595 + .long sys_lchown16; 596 + .long sys_getcwd 597 + .long sys_capget 598 + .long sys_capset /* 185 */ 599 + .long sys_sigaltstack 600 + .long sys_sendfile 601 + .long sys_ni_syscall /* streams1 */ 602 + .long sys_ni_syscall /* streams2 */ 603 + .long sys_vfork /* 190 */ 604 + .long sys_getrlimit 605 + .long sys_mmap2 606 + .long sys_truncate64 607 + .long sys_ftruncate64 608 + .long sys_stat64 /* 195 */ 609 + .long sys_lstat64 610 + .long sys_fstat64 611 + .long sys_chown 612 + .long sys_getuid 613 + .long sys_getgid /* 200 */ 614 + .long sys_geteuid 615 + .long sys_getegid 616 + .long sys_setreuid 617 + .long sys_setregid 618 + .long sys_getgroups /* 205 */ 619 + .long sys_setgroups 620 + .long sys_fchown 621 + .long sys_setresuid 622 + .long sys_getresuid 623 + .long sys_setresgid /* 210 */ 624 + .long sys_getresgid 625 + .long sys_lchown 626 + .long sys_setuid 627 + .long sys_setgid 628 + .long sys_setfsuid /* 215 */ 629 + .long sys_setfsgid 630 + .long sys_pivot_root 631 + .long sys_ni_syscall 632 + .long sys_ni_syscall 633 + .long sys_getdents64 /* 220 */ 634 + .long sys_gettid 635 + .long sys_tkill 636 + .long sys_setxattr 637 + .long sys_lsetxattr 638 + .long sys_fsetxattr /* 225 */ 639 + .long sys_getxattr 640 + .long sys_lgetxattr 641 + .long sys_fgetxattr 642 + .long sys_listxattr 643 + .long sys_llistxattr /* 230 */ 644 + .long sys_flistxattr 645 + .long sys_removexattr 646 + .long sys_lremovexattr 647 + .long sys_fremovexattr 648 + .long sys_futex /* 235 */ 649 + .long sys_sendfile64 650 + .long sys_mincore 651 + .long sys_madvise 652 + .long sys_fcntl64 653 + .long sys_readahead /* 240 */ 654 + .long sys_io_setup 655 + .long sys_io_destroy 656 + .long sys_io_getevents 657 + .long sys_io_submit 658 + .long sys_io_cancel /* 245 */ 659 + .long sys_fadvise64 660 + .long sys_exit_group 661 + .long sys_lookup_dcookie 662 + .long sys_epoll_create 663 + .long sys_epoll_ctl /* 250 */ 664 + .long sys_epoll_wait 665 + .long sys_remap_file_pages 666 + .long sys_set_tid_address 667 + .long sys_timer_create 668 + .long sys_timer_settime /* 255 */ 669 + .long sys_timer_gettime 670 + .long sys_timer_getoverrun 671 + .long sys_timer_delete 672 + .long sys_clock_settime 673 + .long sys_clock_gettime /* 260 */ 674 + .long sys_clock_getres 675 + .long sys_clock_nanosleep 676 + .long sys_statfs64 677 + .long sys_fstatfs64 678 + .long sys_tgkill /* 265 */ 679 + .long sys_utimes 680 + .long sys_fadvise64_64 681 + .long sys_mbind 682 + .long sys_get_mempolicy 683 + .long sys_set_mempolicy /* 270 */ 684 + .long sys_mq_open 685 + .long sys_mq_unlink 686 + .long sys_mq_timedsend 687 + .long sys_mq_timedreceive 688 + .long sys_mq_notify /* 275 */ 689 + .long sys_mq_getsetattr 690 + .long sys_waitid 691 + .long sys_ni_syscall /* for sys_vserver */ 692 + .long sys_add_key 693 + .long sys_request_key /* 280 */ 694 + .long sys_keyctl 695 + .long sys_ioprio_set 696 + .long sys_ioprio_get 697 + .long sys_inotify_init 698 + .long sys_inotify_add_watch /* 285 */ 699 + .long sys_inotify_rm_watch 700 + .long sys_migrate_pages 701 + .long sys_openat 702 + .long sys_mkdirat 703 + .long sys_mknodat /* 290 */ 704 + .long sys_fchownat 705 + .long sys_futimesat 706 + .long sys_fstatat64 707 + .long sys_unlinkat 708 + .long sys_renameat /* 295 */ 709 + .long sys_linkat 710 + .long sys_symlinkat 711 + .long sys_readlinkat 712 + .long sys_fchmodat 713 + .long sys_faccessat /* 300 */ 714 + .long sys_ni_syscall /* Reserved for pselect6 */ 715 + .long sys_ni_syscall /* Reserved for ppoll */ 716 + .long sys_unshare 717 + .long sys_set_robust_list 718 + .long sys_get_robust_list /* 305 */ 719 + .long sys_splice 720 + .long sys_sync_file_range 721 + .long sys_tee 722 + .long sys_vmsplice 723 + .long sys_move_pages /* 310 */ 724 + .long sys_sched_setaffinity 725 + .long sys_sched_getaffinity 726 + .long sys_kexec_load 727 + .long sys_getcpu 728 + .long sys_epoll_pwait /* 315 */ 729 + .long sys_utimensat 730 + .long sys_signalfd 731 + .long sys_timerfd_create 732 + .long sys_eventfd 733 + .long sys_fallocate /* 320 */ 734 + .long sys_timerfd_settime 735 + .long sys_timerfd_gettime 736 + .long sys_signalfd4 737 + .long sys_eventfd2 738 + .long sys_epoll_create1 /* 325 */ 739 + .long sys_dup3 740 + .long sys_pipe2 741 + .long sys_inotify_init1 742 + .long sys_preadv 743 + .long sys_pwritev /* 330 */ 744 + .long sys_rt_tgsigqueueinfo 745 + .long sys_perf_event_open 746 + .long sys_get_thread_area 747 + .long sys_set_thread_area 748 + .long sys_atomic_cmpxchg_32 /* 335 */ 749 + .long sys_atomic_barrier 750 + .long sys_fanotify_init 751 + .long sys_fanotify_mark 752 + .long sys_prlimit64 753 +
+5 -16
arch/m68k/kernel/m68k_ksyms.c
··· 1 - #include <linux/module.h> 2 - 3 - asmlinkage long long __ashldi3 (long long, int); 4 - asmlinkage long long __ashrdi3 (long long, int); 5 - asmlinkage long long __lshrdi3 (long long, int); 6 - asmlinkage long long __muldi3 (long long, long long); 7 - 8 - /* The following are special because they're not called 9 - explicitly (the C compiler generates them). Fortunately, 10 - their interface isn't gonna change any time soon now, so 11 - it's OK to leave it out of version control. */ 12 - EXPORT_SYMBOL(__ashldi3); 13 - EXPORT_SYMBOL(__ashrdi3); 14 - EXPORT_SYMBOL(__lshrdi3); 15 - EXPORT_SYMBOL(__muldi3); 16 -
··· 1 + #ifdef CONFIG_MMU 2 + #include "m68k_ksyms_mm.c" 3 + #else 4 + #include "m68k_ksyms_no.c" 5 + #endif
+16
arch/m68k/kernel/m68k_ksyms_mm.c
···
··· 1 + #include <linux/module.h> 2 + 3 + asmlinkage long long __ashldi3 (long long, int); 4 + asmlinkage long long __ashrdi3 (long long, int); 5 + asmlinkage long long __lshrdi3 (long long, int); 6 + asmlinkage long long __muldi3 (long long, long long); 7 + 8 + /* The following are special because they're not called 9 + explicitly (the C compiler generates them). Fortunately, 10 + their interface isn't gonna change any time soon now, so 11 + it's OK to leave it out of version control. */ 12 + EXPORT_SYMBOL(__ashldi3); 13 + EXPORT_SYMBOL(__ashrdi3); 14 + EXPORT_SYMBOL(__lshrdi3); 15 + EXPORT_SYMBOL(__muldi3); 16 +
+3 -153
arch/m68k/kernel/module.c
··· 1 - /* 2 - * This file is subject to the terms and conditions of the GNU General Public 3 - * License. See the file COPYING in the main directory of this archive 4 - * for more details. 5 - */ 6 - 7 - #include <linux/moduleloader.h> 8 - #include <linux/elf.h> 9 - #include <linux/vmalloc.h> 10 - #include <linux/fs.h> 11 - #include <linux/string.h> 12 - #include <linux/kernel.h> 13 - 14 - #if 0 15 - #define DEBUGP printk 16 #else 17 - #define DEBUGP(fmt...) 18 #endif 19 - 20 - #ifdef CONFIG_MODULES 21 - 22 - void *module_alloc(unsigned long size) 23 - { 24 - if (size == 0) 25 - return NULL; 26 - return vmalloc(size); 27 - } 28 - 29 - 30 - /* Free memory returned from module_alloc */ 31 - void module_free(struct module *mod, void *module_region) 32 - { 33 - vfree(module_region); 34 - } 35 - 36 - /* We don't need anything special. */ 37 - int module_frob_arch_sections(Elf_Ehdr *hdr, 38 - Elf_Shdr *sechdrs, 39 - char *secstrings, 40 - struct module *mod) 41 - { 42 - return 0; 43 - } 44 - 45 - int apply_relocate(Elf32_Shdr *sechdrs, 46 - const char *strtab, 47 - unsigned int symindex, 48 - unsigned int relsec, 49 - struct module *me) 50 - { 51 - unsigned int i; 52 - Elf32_Rel *rel = (void *)sechdrs[relsec].sh_addr; 53 - Elf32_Sym *sym; 54 - uint32_t *location; 55 - 56 - DEBUGP("Applying relocate section %u to %u\n", relsec, 57 - sechdrs[relsec].sh_info); 58 - for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rel); i++) { 59 - /* This is where to make the change */ 60 - location = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr 61 - + rel[i].r_offset; 62 - /* This is the symbol it is referring to. Note that all 63 - undefined symbols have been resolved. */ 64 - sym = (Elf32_Sym *)sechdrs[symindex].sh_addr 65 - + ELF32_R_SYM(rel[i].r_info); 66 - 67 - switch (ELF32_R_TYPE(rel[i].r_info)) { 68 - case R_68K_32: 69 - /* We add the value into the location given */ 70 - *location += sym->st_value; 71 - break; 72 - case R_68K_PC32: 73 - /* Add the value, subtract its postition */ 74 - *location += sym->st_value - (uint32_t)location; 75 - break; 76 - default: 77 - printk(KERN_ERR "module %s: Unknown relocation: %u\n", 78 - me->name, ELF32_R_TYPE(rel[i].r_info)); 79 - return -ENOEXEC; 80 - } 81 - } 82 - return 0; 83 - } 84 - 85 - int apply_relocate_add(Elf32_Shdr *sechdrs, 86 - const char *strtab, 87 - unsigned int symindex, 88 - unsigned int relsec, 89 - struct module *me) 90 - { 91 - unsigned int i; 92 - Elf32_Rela *rel = (void *)sechdrs[relsec].sh_addr; 93 - Elf32_Sym *sym; 94 - uint32_t *location; 95 - 96 - DEBUGP("Applying relocate_add section %u to %u\n", relsec, 97 - sechdrs[relsec].sh_info); 98 - for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rel); i++) { 99 - /* This is where to make the change */ 100 - location = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr 101 - + rel[i].r_offset; 102 - /* This is the symbol it is referring to. Note that all 103 - undefined symbols have been resolved. */ 104 - sym = (Elf32_Sym *)sechdrs[symindex].sh_addr 105 - + ELF32_R_SYM(rel[i].r_info); 106 - 107 - switch (ELF32_R_TYPE(rel[i].r_info)) { 108 - case R_68K_32: 109 - /* We add the value into the location given */ 110 - *location = rel[i].r_addend + sym->st_value; 111 - break; 112 - case R_68K_PC32: 113 - /* Add the value, subtract its postition */ 114 - *location = rel[i].r_addend + sym->st_value - (uint32_t)location; 115 - break; 116 - default: 117 - printk(KERN_ERR "module %s: Unknown relocation: %u\n", 118 - me->name, ELF32_R_TYPE(rel[i].r_info)); 119 - return -ENOEXEC; 120 - } 121 - } 122 - return 0; 123 - } 124 - 125 - int module_finalize(const Elf_Ehdr *hdr, 126 - const Elf_Shdr *sechdrs, 127 - struct module *mod) 128 - { 129 - module_fixup(mod, mod->arch.fixup_start, mod->arch.fixup_end); 130 - 131 - return 0; 132 - } 133 - 134 - void module_arch_cleanup(struct module *mod) 135 - { 136 - } 137 - 138 - #endif /* CONFIG_MODULES */ 139 - 140 - void module_fixup(struct module *mod, struct m68k_fixup_info *start, 141 - struct m68k_fixup_info *end) 142 - { 143 - struct m68k_fixup_info *fixup; 144 - 145 - for (fixup = start; fixup < end; fixup++) { 146 - switch (fixup->type) { 147 - case m68k_fixup_memoffset: 148 - *(u32 *)fixup->addr = m68k_memoffset; 149 - break; 150 - case m68k_fixup_vnode_shift: 151 - *(u16 *)fixup->addr += m68k_virt_to_node_shift; 152 - break; 153 - } 154 - } 155 - }
··· 1 + #ifdef CONFIG_MMU 2 + #include "module_mm.c" 3 #else 4 + #include "module_no.c" 5 #endif
+155
arch/m68k/kernel/module_mm.c
···
··· 1 + /* 2 + * This file is subject to the terms and conditions of the GNU General Public 3 + * License. See the file COPYING in the main directory of this archive 4 + * for more details. 5 + */ 6 + 7 + #include <linux/moduleloader.h> 8 + #include <linux/elf.h> 9 + #include <linux/vmalloc.h> 10 + #include <linux/fs.h> 11 + #include <linux/string.h> 12 + #include <linux/kernel.h> 13 + 14 + #if 0 15 + #define DEBUGP printk 16 + #else 17 + #define DEBUGP(fmt...) 18 + #endif 19 + 20 + #ifdef CONFIG_MODULES 21 + 22 + void *module_alloc(unsigned long size) 23 + { 24 + if (size == 0) 25 + return NULL; 26 + return vmalloc(size); 27 + } 28 + 29 + 30 + /* Free memory returned from module_alloc */ 31 + void module_free(struct module *mod, void *module_region) 32 + { 33 + vfree(module_region); 34 + } 35 + 36 + /* We don't need anything special. */ 37 + int module_frob_arch_sections(Elf_Ehdr *hdr, 38 + Elf_Shdr *sechdrs, 39 + char *secstrings, 40 + struct module *mod) 41 + { 42 + return 0; 43 + } 44 + 45 + int apply_relocate(Elf32_Shdr *sechdrs, 46 + const char *strtab, 47 + unsigned int symindex, 48 + unsigned int relsec, 49 + struct module *me) 50 + { 51 + unsigned int i; 52 + Elf32_Rel *rel = (void *)sechdrs[relsec].sh_addr; 53 + Elf32_Sym *sym; 54 + uint32_t *location; 55 + 56 + DEBUGP("Applying relocate section %u to %u\n", relsec, 57 + sechdrs[relsec].sh_info); 58 + for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rel); i++) { 59 + /* This is where to make the change */ 60 + location = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr 61 + + rel[i].r_offset; 62 + /* This is the symbol it is referring to. Note that all 63 + undefined symbols have been resolved. */ 64 + sym = (Elf32_Sym *)sechdrs[symindex].sh_addr 65 + + ELF32_R_SYM(rel[i].r_info); 66 + 67 + switch (ELF32_R_TYPE(rel[i].r_info)) { 68 + case R_68K_32: 69 + /* We add the value into the location given */ 70 + *location += sym->st_value; 71 + break; 72 + case R_68K_PC32: 73 + /* Add the value, subtract its postition */ 74 + *location += sym->st_value - (uint32_t)location; 75 + break; 76 + default: 77 + printk(KERN_ERR "module %s: Unknown relocation: %u\n", 78 + me->name, ELF32_R_TYPE(rel[i].r_info)); 79 + return -ENOEXEC; 80 + } 81 + } 82 + return 0; 83 + } 84 + 85 + int apply_relocate_add(Elf32_Shdr *sechdrs, 86 + const char *strtab, 87 + unsigned int symindex, 88 + unsigned int relsec, 89 + struct module *me) 90 + { 91 + unsigned int i; 92 + Elf32_Rela *rel = (void *)sechdrs[relsec].sh_addr; 93 + Elf32_Sym *sym; 94 + uint32_t *location; 95 + 96 + DEBUGP("Applying relocate_add section %u to %u\n", relsec, 97 + sechdrs[relsec].sh_info); 98 + for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rel); i++) { 99 + /* This is where to make the change */ 100 + location = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr 101 + + rel[i].r_offset; 102 + /* This is the symbol it is referring to. Note that all 103 + undefined symbols have been resolved. */ 104 + sym = (Elf32_Sym *)sechdrs[symindex].sh_addr 105 + + ELF32_R_SYM(rel[i].r_info); 106 + 107 + switch (ELF32_R_TYPE(rel[i].r_info)) { 108 + case R_68K_32: 109 + /* We add the value into the location given */ 110 + *location = rel[i].r_addend + sym->st_value; 111 + break; 112 + case R_68K_PC32: 113 + /* Add the value, subtract its postition */ 114 + *location = rel[i].r_addend + sym->st_value - (uint32_t)location; 115 + break; 116 + default: 117 + printk(KERN_ERR "module %s: Unknown relocation: %u\n", 118 + me->name, ELF32_R_TYPE(rel[i].r_info)); 119 + return -ENOEXEC; 120 + } 121 + } 122 + return 0; 123 + } 124 + 125 + int module_finalize(const Elf_Ehdr *hdr, 126 + const Elf_Shdr *sechdrs, 127 + struct module *mod) 128 + { 129 + module_fixup(mod, mod->arch.fixup_start, mod->arch.fixup_end); 130 + 131 + return 0; 132 + } 133 + 134 + void module_arch_cleanup(struct module *mod) 135 + { 136 + } 137 + 138 + #endif /* CONFIG_MODULES */ 139 + 140 + void module_fixup(struct module *mod, struct m68k_fixup_info *start, 141 + struct m68k_fixup_info *end) 142 + { 143 + struct m68k_fixup_info *fixup; 144 + 145 + for (fixup = start; fixup < end; fixup++) { 146 + switch (fixup->type) { 147 + case m68k_fixup_memoffset: 148 + *(u32 *)fixup->addr = m68k_memoffset; 149 + break; 150 + case m68k_fixup_vnode_shift: 151 + *(u16 *)fixup->addr += m68k_virt_to_node_shift; 152 + break; 153 + } 154 + } 155 + }
+3 -352
arch/m68k/kernel/process.c
··· 1 - /* 2 - * linux/arch/m68k/kernel/process.c 3 - * 4 - * Copyright (C) 1995 Hamish Macdonald 5 - * 6 - * 68060 fixes by Jesper Skov 7 - */ 8 - 9 - /* 10 - * This file handles the architecture-dependent parts of process handling.. 11 - */ 12 - 13 - #include <linux/errno.h> 14 - #include <linux/module.h> 15 - #include <linux/sched.h> 16 - #include <linux/kernel.h> 17 - #include <linux/mm.h> 18 - #include <linux/slab.h> 19 - #include <linux/fs.h> 20 - #include <linux/smp.h> 21 - #include <linux/stddef.h> 22 - #include <linux/unistd.h> 23 - #include <linux/ptrace.h> 24 - #include <linux/user.h> 25 - #include <linux/reboot.h> 26 - #include <linux/init_task.h> 27 - #include <linux/mqueue.h> 28 - 29 - #include <asm/uaccess.h> 30 - #include <asm/system.h> 31 - #include <asm/traps.h> 32 - #include <asm/machdep.h> 33 - #include <asm/setup.h> 34 - #include <asm/pgtable.h> 35 - 36 - /* 37 - * Initial task/thread structure. Make this a per-architecture thing, 38 - * because different architectures tend to have different 39 - * alignment requirements and potentially different initial 40 - * setup. 41 - */ 42 - static struct signal_struct init_signals = INIT_SIGNALS(init_signals); 43 - static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand); 44 - union thread_union init_thread_union __init_task_data 45 - __attribute__((aligned(THREAD_SIZE))) = 46 - { INIT_THREAD_INFO(init_task) }; 47 - 48 - /* initial task structure */ 49 - struct task_struct init_task = INIT_TASK(init_task); 50 - 51 - EXPORT_SYMBOL(init_task); 52 - 53 - asmlinkage void ret_from_fork(void); 54 - 55 - 56 - /* 57 - * Return saved PC from a blocked thread 58 - */ 59 - unsigned long thread_saved_pc(struct task_struct *tsk) 60 - { 61 - struct switch_stack *sw = (struct switch_stack *)tsk->thread.ksp; 62 - /* Check whether the thread is blocked in resume() */ 63 - if (in_sched_functions(sw->retpc)) 64 - return ((unsigned long *)sw->a6)[1]; 65 - else 66 - return sw->retpc; 67 - } 68 - 69 - /* 70 - * The idle loop on an m68k.. 71 - */ 72 - static void default_idle(void) 73 - { 74 - if (!need_resched()) 75 - #if defined(MACH_ATARI_ONLY) 76 - /* block out HSYNC on the atari (falcon) */ 77 - __asm__("stop #0x2200" : : : "cc"); 78 #else 79 - __asm__("stop #0x2000" : : : "cc"); 80 #endif 81 - } 82 - 83 - void (*idle)(void) = default_idle; 84 - 85 - /* 86 - * The idle thread. There's no useful work to be 87 - * done, so just try to conserve power and have a 88 - * low exit latency (ie sit in a loop waiting for 89 - * somebody to say that they'd like to reschedule) 90 - */ 91 - void cpu_idle(void) 92 - { 93 - /* endless idle loop with no priority at all */ 94 - while (1) { 95 - while (!need_resched()) 96 - idle(); 97 - preempt_enable_no_resched(); 98 - schedule(); 99 - preempt_disable(); 100 - } 101 - } 102 - 103 - void machine_restart(char * __unused) 104 - { 105 - if (mach_reset) 106 - mach_reset(); 107 - for (;;); 108 - } 109 - 110 - void machine_halt(void) 111 - { 112 - if (mach_halt) 113 - mach_halt(); 114 - for (;;); 115 - } 116 - 117 - void machine_power_off(void) 118 - { 119 - if (mach_power_off) 120 - mach_power_off(); 121 - for (;;); 122 - } 123 - 124 - void (*pm_power_off)(void) = machine_power_off; 125 - EXPORT_SYMBOL(pm_power_off); 126 - 127 - void show_regs(struct pt_regs * regs) 128 - { 129 - printk("\n"); 130 - printk("Format %02x Vector: %04x PC: %08lx Status: %04x %s\n", 131 - regs->format, regs->vector, regs->pc, regs->sr, print_tainted()); 132 - printk("ORIG_D0: %08lx D0: %08lx A2: %08lx A1: %08lx\n", 133 - regs->orig_d0, regs->d0, regs->a2, regs->a1); 134 - printk("A0: %08lx D5: %08lx D4: %08lx\n", 135 - regs->a0, regs->d5, regs->d4); 136 - printk("D3: %08lx D2: %08lx D1: %08lx\n", 137 - regs->d3, regs->d2, regs->d1); 138 - if (!(regs->sr & PS_S)) 139 - printk("USP: %08lx\n", rdusp()); 140 - } 141 - 142 - /* 143 - * Create a kernel thread 144 - */ 145 - int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags) 146 - { 147 - int pid; 148 - mm_segment_t fs; 149 - 150 - fs = get_fs(); 151 - set_fs (KERNEL_DS); 152 - 153 - { 154 - register long retval __asm__ ("d0"); 155 - register long clone_arg __asm__ ("d1") = flags | CLONE_VM | CLONE_UNTRACED; 156 - 157 - retval = __NR_clone; 158 - __asm__ __volatile__ 159 - ("clrl %%d2\n\t" 160 - "trap #0\n\t" /* Linux/m68k system call */ 161 - "tstl %0\n\t" /* child or parent */ 162 - "jne 1f\n\t" /* parent - jump */ 163 - "lea %%sp@(%c7),%6\n\t" /* reload current */ 164 - "movel %6@,%6\n\t" 165 - "movel %3,%%sp@-\n\t" /* push argument */ 166 - "jsr %4@\n\t" /* call fn */ 167 - "movel %0,%%d1\n\t" /* pass exit value */ 168 - "movel %2,%%d0\n\t" /* exit */ 169 - "trap #0\n" 170 - "1:" 171 - : "+d" (retval) 172 - : "i" (__NR_clone), "i" (__NR_exit), 173 - "r" (arg), "a" (fn), "d" (clone_arg), "r" (current), 174 - "i" (-THREAD_SIZE) 175 - : "d2"); 176 - 177 - pid = retval; 178 - } 179 - 180 - set_fs (fs); 181 - return pid; 182 - } 183 - EXPORT_SYMBOL(kernel_thread); 184 - 185 - void flush_thread(void) 186 - { 187 - unsigned long zero = 0; 188 - set_fs(USER_DS); 189 - current->thread.fs = __USER_DS; 190 - if (!FPU_IS_EMU) 191 - asm volatile (".chip 68k/68881\n\t" 192 - "frestore %0@\n\t" 193 - ".chip 68k" : : "a" (&zero)); 194 - } 195 - 196 - /* 197 - * "m68k_fork()".. By the time we get here, the 198 - * non-volatile registers have also been saved on the 199 - * stack. We do some ugly pointer stuff here.. (see 200 - * also copy_thread) 201 - */ 202 - 203 - asmlinkage int m68k_fork(struct pt_regs *regs) 204 - { 205 - return do_fork(SIGCHLD, rdusp(), regs, 0, NULL, NULL); 206 - } 207 - 208 - asmlinkage int m68k_vfork(struct pt_regs *regs) 209 - { 210 - return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, rdusp(), regs, 0, 211 - NULL, NULL); 212 - } 213 - 214 - asmlinkage int m68k_clone(struct pt_regs *regs) 215 - { 216 - unsigned long clone_flags; 217 - unsigned long newsp; 218 - int __user *parent_tidptr, *child_tidptr; 219 - 220 - /* syscall2 puts clone_flags in d1 and usp in d2 */ 221 - clone_flags = regs->d1; 222 - newsp = regs->d2; 223 - parent_tidptr = (int __user *)regs->d3; 224 - child_tidptr = (int __user *)regs->d4; 225 - if (!newsp) 226 - newsp = rdusp(); 227 - return do_fork(clone_flags, newsp, regs, 0, 228 - parent_tidptr, child_tidptr); 229 - } 230 - 231 - int copy_thread(unsigned long clone_flags, unsigned long usp, 232 - unsigned long unused, 233 - struct task_struct * p, struct pt_regs * regs) 234 - { 235 - struct pt_regs * childregs; 236 - struct switch_stack * childstack, *stack; 237 - unsigned long *retp; 238 - 239 - childregs = (struct pt_regs *) (task_stack_page(p) + THREAD_SIZE) - 1; 240 - 241 - *childregs = *regs; 242 - childregs->d0 = 0; 243 - 244 - retp = ((unsigned long *) regs); 245 - stack = ((struct switch_stack *) retp) - 1; 246 - 247 - childstack = ((struct switch_stack *) childregs) - 1; 248 - *childstack = *stack; 249 - childstack->retpc = (unsigned long)ret_from_fork; 250 - 251 - p->thread.usp = usp; 252 - p->thread.ksp = (unsigned long)childstack; 253 - 254 - if (clone_flags & CLONE_SETTLS) 255 - task_thread_info(p)->tp_value = regs->d5; 256 - 257 - /* 258 - * Must save the current SFC/DFC value, NOT the value when 259 - * the parent was last descheduled - RGH 10-08-96 260 - */ 261 - p->thread.fs = get_fs().seg; 262 - 263 - if (!FPU_IS_EMU) { 264 - /* Copy the current fpu state */ 265 - asm volatile ("fsave %0" : : "m" (p->thread.fpstate[0]) : "memory"); 266 - 267 - if (!CPU_IS_060 ? p->thread.fpstate[0] : p->thread.fpstate[2]) 268 - asm volatile ("fmovemx %/fp0-%/fp7,%0\n\t" 269 - "fmoveml %/fpiar/%/fpcr/%/fpsr,%1" 270 - : : "m" (p->thread.fp[0]), "m" (p->thread.fpcntl[0]) 271 - : "memory"); 272 - /* Restore the state in case the fpu was busy */ 273 - asm volatile ("frestore %0" : : "m" (p->thread.fpstate[0])); 274 - } 275 - 276 - return 0; 277 - } 278 - 279 - /* Fill in the fpu structure for a core dump. */ 280 - 281 - int dump_fpu (struct pt_regs *regs, struct user_m68kfp_struct *fpu) 282 - { 283 - char fpustate[216]; 284 - 285 - if (FPU_IS_EMU) { 286 - int i; 287 - 288 - memcpy(fpu->fpcntl, current->thread.fpcntl, 12); 289 - memcpy(fpu->fpregs, current->thread.fp, 96); 290 - /* Convert internal fpu reg representation 291 - * into long double format 292 - */ 293 - for (i = 0; i < 24; i += 3) 294 - fpu->fpregs[i] = ((fpu->fpregs[i] & 0xffff0000) << 15) | 295 - ((fpu->fpregs[i] & 0x0000ffff) << 16); 296 - return 1; 297 - } 298 - 299 - /* First dump the fpu context to avoid protocol violation. */ 300 - asm volatile ("fsave %0" :: "m" (fpustate[0]) : "memory"); 301 - if (!CPU_IS_060 ? !fpustate[0] : !fpustate[2]) 302 - return 0; 303 - 304 - asm volatile ("fmovem %/fpiar/%/fpcr/%/fpsr,%0" 305 - :: "m" (fpu->fpcntl[0]) 306 - : "memory"); 307 - asm volatile ("fmovemx %/fp0-%/fp7,%0" 308 - :: "m" (fpu->fpregs[0]) 309 - : "memory"); 310 - return 1; 311 - } 312 - EXPORT_SYMBOL(dump_fpu); 313 - 314 - /* 315 - * sys_execve() executes a new program. 316 - */ 317 - asmlinkage int sys_execve(const char __user *name, 318 - const char __user *const __user *argv, 319 - const char __user *const __user *envp) 320 - { 321 - int error; 322 - char * filename; 323 - struct pt_regs *regs = (struct pt_regs *) &name; 324 - 325 - filename = getname(name); 326 - error = PTR_ERR(filename); 327 - if (IS_ERR(filename)) 328 - return error; 329 - error = do_execve(filename, argv, envp, regs); 330 - putname(filename); 331 - return error; 332 - } 333 - 334 - unsigned long get_wchan(struct task_struct *p) 335 - { 336 - unsigned long fp, pc; 337 - unsigned long stack_page; 338 - int count = 0; 339 - if (!p || p == current || p->state == TASK_RUNNING) 340 - return 0; 341 - 342 - stack_page = (unsigned long)task_stack_page(p); 343 - fp = ((struct switch_stack *)p->thread.ksp)->a6; 344 - do { 345 - if (fp < stack_page+sizeof(struct thread_info) || 346 - fp >= 8184+stack_page) 347 - return 0; 348 - pc = ((unsigned long *)fp)[1]; 349 - if (!in_sched_functions(pc)) 350 - return pc; 351 - fp = *(unsigned long *) fp; 352 - } while (count++ < 16); 353 - return 0; 354 - }
··· 1 + #ifdef CONFIG_MMU 2 + #include "process_mm.c" 3 #else 4 + #include "process_no.c" 5 #endif
+354
arch/m68k/kernel/process_mm.c
···
··· 1 + /* 2 + * linux/arch/m68k/kernel/process.c 3 + * 4 + * Copyright (C) 1995 Hamish Macdonald 5 + * 6 + * 68060 fixes by Jesper Skov 7 + */ 8 + 9 + /* 10 + * This file handles the architecture-dependent parts of process handling.. 11 + */ 12 + 13 + #include <linux/errno.h> 14 + #include <linux/module.h> 15 + #include <linux/sched.h> 16 + #include <linux/kernel.h> 17 + #include <linux/mm.h> 18 + #include <linux/slab.h> 19 + #include <linux/fs.h> 20 + #include <linux/smp.h> 21 + #include <linux/stddef.h> 22 + #include <linux/unistd.h> 23 + #include <linux/ptrace.h> 24 + #include <linux/user.h> 25 + #include <linux/reboot.h> 26 + #include <linux/init_task.h> 27 + #include <linux/mqueue.h> 28 + 29 + #include <asm/uaccess.h> 30 + #include <asm/system.h> 31 + #include <asm/traps.h> 32 + #include <asm/machdep.h> 33 + #include <asm/setup.h> 34 + #include <asm/pgtable.h> 35 + 36 + /* 37 + * Initial task/thread structure. Make this a per-architecture thing, 38 + * because different architectures tend to have different 39 + * alignment requirements and potentially different initial 40 + * setup. 41 + */ 42 + static struct signal_struct init_signals = INIT_SIGNALS(init_signals); 43 + static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand); 44 + union thread_union init_thread_union __init_task_data 45 + __attribute__((aligned(THREAD_SIZE))) = 46 + { INIT_THREAD_INFO(init_task) }; 47 + 48 + /* initial task structure */ 49 + struct task_struct init_task = INIT_TASK(init_task); 50 + 51 + EXPORT_SYMBOL(init_task); 52 + 53 + asmlinkage void ret_from_fork(void); 54 + 55 + 56 + /* 57 + * Return saved PC from a blocked thread 58 + */ 59 + unsigned long thread_saved_pc(struct task_struct *tsk) 60 + { 61 + struct switch_stack *sw = (struct switch_stack *)tsk->thread.ksp; 62 + /* Check whether the thread is blocked in resume() */ 63 + if (in_sched_functions(sw->retpc)) 64 + return ((unsigned long *)sw->a6)[1]; 65 + else 66 + return sw->retpc; 67 + } 68 + 69 + /* 70 + * The idle loop on an m68k.. 71 + */ 72 + static void default_idle(void) 73 + { 74 + if (!need_resched()) 75 + #if defined(MACH_ATARI_ONLY) 76 + /* block out HSYNC on the atari (falcon) */ 77 + __asm__("stop #0x2200" : : : "cc"); 78 + #else 79 + __asm__("stop #0x2000" : : : "cc"); 80 + #endif 81 + } 82 + 83 + void (*idle)(void) = default_idle; 84 + 85 + /* 86 + * The idle thread. There's no useful work to be 87 + * done, so just try to conserve power and have a 88 + * low exit latency (ie sit in a loop waiting for 89 + * somebody to say that they'd like to reschedule) 90 + */ 91 + void cpu_idle(void) 92 + { 93 + /* endless idle loop with no priority at all */ 94 + while (1) { 95 + while (!need_resched()) 96 + idle(); 97 + preempt_enable_no_resched(); 98 + schedule(); 99 + preempt_disable(); 100 + } 101 + } 102 + 103 + void machine_restart(char * __unused) 104 + { 105 + if (mach_reset) 106 + mach_reset(); 107 + for (;;); 108 + } 109 + 110 + void machine_halt(void) 111 + { 112 + if (mach_halt) 113 + mach_halt(); 114 + for (;;); 115 + } 116 + 117 + void machine_power_off(void) 118 + { 119 + if (mach_power_off) 120 + mach_power_off(); 121 + for (;;); 122 + } 123 + 124 + void (*pm_power_off)(void) = machine_power_off; 125 + EXPORT_SYMBOL(pm_power_off); 126 + 127 + void show_regs(struct pt_regs * regs) 128 + { 129 + printk("\n"); 130 + printk("Format %02x Vector: %04x PC: %08lx Status: %04x %s\n", 131 + regs->format, regs->vector, regs->pc, regs->sr, print_tainted()); 132 + printk("ORIG_D0: %08lx D0: %08lx A2: %08lx A1: %08lx\n", 133 + regs->orig_d0, regs->d0, regs->a2, regs->a1); 134 + printk("A0: %08lx D5: %08lx D4: %08lx\n", 135 + regs->a0, regs->d5, regs->d4); 136 + printk("D3: %08lx D2: %08lx D1: %08lx\n", 137 + regs->d3, regs->d2, regs->d1); 138 + if (!(regs->sr & PS_S)) 139 + printk("USP: %08lx\n", rdusp()); 140 + } 141 + 142 + /* 143 + * Create a kernel thread 144 + */ 145 + int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags) 146 + { 147 + int pid; 148 + mm_segment_t fs; 149 + 150 + fs = get_fs(); 151 + set_fs (KERNEL_DS); 152 + 153 + { 154 + register long retval __asm__ ("d0"); 155 + register long clone_arg __asm__ ("d1") = flags | CLONE_VM | CLONE_UNTRACED; 156 + 157 + retval = __NR_clone; 158 + __asm__ __volatile__ 159 + ("clrl %%d2\n\t" 160 + "trap #0\n\t" /* Linux/m68k system call */ 161 + "tstl %0\n\t" /* child or parent */ 162 + "jne 1f\n\t" /* parent - jump */ 163 + "lea %%sp@(%c7),%6\n\t" /* reload current */ 164 + "movel %6@,%6\n\t" 165 + "movel %3,%%sp@-\n\t" /* push argument */ 166 + "jsr %4@\n\t" /* call fn */ 167 + "movel %0,%%d1\n\t" /* pass exit value */ 168 + "movel %2,%%d0\n\t" /* exit */ 169 + "trap #0\n" 170 + "1:" 171 + : "+d" (retval) 172 + : "i" (__NR_clone), "i" (__NR_exit), 173 + "r" (arg), "a" (fn), "d" (clone_arg), "r" (current), 174 + "i" (-THREAD_SIZE) 175 + : "d2"); 176 + 177 + pid = retval; 178 + } 179 + 180 + set_fs (fs); 181 + return pid; 182 + } 183 + EXPORT_SYMBOL(kernel_thread); 184 + 185 + void flush_thread(void) 186 + { 187 + unsigned long zero = 0; 188 + set_fs(USER_DS); 189 + current->thread.fs = __USER_DS; 190 + if (!FPU_IS_EMU) 191 + asm volatile (".chip 68k/68881\n\t" 192 + "frestore %0@\n\t" 193 + ".chip 68k" : : "a" (&zero)); 194 + } 195 + 196 + /* 197 + * "m68k_fork()".. By the time we get here, the 198 + * non-volatile registers have also been saved on the 199 + * stack. We do some ugly pointer stuff here.. (see 200 + * also copy_thread) 201 + */ 202 + 203 + asmlinkage int m68k_fork(struct pt_regs *regs) 204 + { 205 + return do_fork(SIGCHLD, rdusp(), regs, 0, NULL, NULL); 206 + } 207 + 208 + asmlinkage int m68k_vfork(struct pt_regs *regs) 209 + { 210 + return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, rdusp(), regs, 0, 211 + NULL, NULL); 212 + } 213 + 214 + asmlinkage int m68k_clone(struct pt_regs *regs) 215 + { 216 + unsigned long clone_flags; 217 + unsigned long newsp; 218 + int __user *parent_tidptr, *child_tidptr; 219 + 220 + /* syscall2 puts clone_flags in d1 and usp in d2 */ 221 + clone_flags = regs->d1; 222 + newsp = regs->d2; 223 + parent_tidptr = (int __user *)regs->d3; 224 + child_tidptr = (int __user *)regs->d4; 225 + if (!newsp) 226 + newsp = rdusp(); 227 + return do_fork(clone_flags, newsp, regs, 0, 228 + parent_tidptr, child_tidptr); 229 + } 230 + 231 + int copy_thread(unsigned long clone_flags, unsigned long usp, 232 + unsigned long unused, 233 + struct task_struct * p, struct pt_regs * regs) 234 + { 235 + struct pt_regs * childregs; 236 + struct switch_stack * childstack, *stack; 237 + unsigned long *retp; 238 + 239 + childregs = (struct pt_regs *) (task_stack_page(p) + THREAD_SIZE) - 1; 240 + 241 + *childregs = *regs; 242 + childregs->d0 = 0; 243 + 244 + retp = ((unsigned long *) regs); 245 + stack = ((struct switch_stack *) retp) - 1; 246 + 247 + childstack = ((struct switch_stack *) childregs) - 1; 248 + *childstack = *stack; 249 + childstack->retpc = (unsigned long)ret_from_fork; 250 + 251 + p->thread.usp = usp; 252 + p->thread.ksp = (unsigned long)childstack; 253 + 254 + if (clone_flags & CLONE_SETTLS) 255 + task_thread_info(p)->tp_value = regs->d5; 256 + 257 + /* 258 + * Must save the current SFC/DFC value, NOT the value when 259 + * the parent was last descheduled - RGH 10-08-96 260 + */ 261 + p->thread.fs = get_fs().seg; 262 + 263 + if (!FPU_IS_EMU) { 264 + /* Copy the current fpu state */ 265 + asm volatile ("fsave %0" : : "m" (p->thread.fpstate[0]) : "memory"); 266 + 267 + if (!CPU_IS_060 ? p->thread.fpstate[0] : p->thread.fpstate[2]) 268 + asm volatile ("fmovemx %/fp0-%/fp7,%0\n\t" 269 + "fmoveml %/fpiar/%/fpcr/%/fpsr,%1" 270 + : : "m" (p->thread.fp[0]), "m" (p->thread.fpcntl[0]) 271 + : "memory"); 272 + /* Restore the state in case the fpu was busy */ 273 + asm volatile ("frestore %0" : : "m" (p->thread.fpstate[0])); 274 + } 275 + 276 + return 0; 277 + } 278 + 279 + /* Fill in the fpu structure for a core dump. */ 280 + 281 + int dump_fpu (struct pt_regs *regs, struct user_m68kfp_struct *fpu) 282 + { 283 + char fpustate[216]; 284 + 285 + if (FPU_IS_EMU) { 286 + int i; 287 + 288 + memcpy(fpu->fpcntl, current->thread.fpcntl, 12); 289 + memcpy(fpu->fpregs, current->thread.fp, 96); 290 + /* Convert internal fpu reg representation 291 + * into long double format 292 + */ 293 + for (i = 0; i < 24; i += 3) 294 + fpu->fpregs[i] = ((fpu->fpregs[i] & 0xffff0000) << 15) | 295 + ((fpu->fpregs[i] & 0x0000ffff) << 16); 296 + return 1; 297 + } 298 + 299 + /* First dump the fpu context to avoid protocol violation. */ 300 + asm volatile ("fsave %0" :: "m" (fpustate[0]) : "memory"); 301 + if (!CPU_IS_060 ? !fpustate[0] : !fpustate[2]) 302 + return 0; 303 + 304 + asm volatile ("fmovem %/fpiar/%/fpcr/%/fpsr,%0" 305 + :: "m" (fpu->fpcntl[0]) 306 + : "memory"); 307 + asm volatile ("fmovemx %/fp0-%/fp7,%0" 308 + :: "m" (fpu->fpregs[0]) 309 + : "memory"); 310 + return 1; 311 + } 312 + EXPORT_SYMBOL(dump_fpu); 313 + 314 + /* 315 + * sys_execve() executes a new program. 316 + */ 317 + asmlinkage int sys_execve(const char __user *name, 318 + const char __user *const __user *argv, 319 + const char __user *const __user *envp) 320 + { 321 + int error; 322 + char * filename; 323 + struct pt_regs *regs = (struct pt_regs *) &name; 324 + 325 + filename = getname(name); 326 + error = PTR_ERR(filename); 327 + if (IS_ERR(filename)) 328 + return error; 329 + error = do_execve(filename, argv, envp, regs); 330 + putname(filename); 331 + return error; 332 + } 333 + 334 + unsigned long get_wchan(struct task_struct *p) 335 + { 336 + unsigned long fp, pc; 337 + unsigned long stack_page; 338 + int count = 0; 339 + if (!p || p == current || p->state == TASK_RUNNING) 340 + return 0; 341 + 342 + stack_page = (unsigned long)task_stack_page(p); 343 + fp = ((struct switch_stack *)p->thread.ksp)->a6; 344 + do { 345 + if (fp < stack_page+sizeof(struct thread_info) || 346 + fp >= 8184+stack_page) 347 + return 0; 348 + pc = ((unsigned long *)fp)[1]; 349 + if (!in_sched_functions(pc)) 350 + return pc; 351 + fp = *(unsigned long *) fp; 352 + } while (count++ < 16); 353 + return 0; 354 + }
+5 -277
arch/m68k/kernel/ptrace.c
··· 1 - /* 2 - * linux/arch/m68k/kernel/ptrace.c 3 - * 4 - * Copyright (C) 1994 by Hamish Macdonald 5 - * Taken from linux/kernel/ptrace.c and modified for M680x0. 6 - * linux/kernel/ptrace.c is by Ross Biro 1/23/92, edited by Linus Torvalds 7 - * 8 - * This file is subject to the terms and conditions of the GNU General 9 - * Public License. See the file COPYING in the main directory of 10 - * this archive for more details. 11 - */ 12 - 13 - #include <linux/kernel.h> 14 - #include <linux/sched.h> 15 - #include <linux/mm.h> 16 - #include <linux/smp.h> 17 - #include <linux/errno.h> 18 - #include <linux/ptrace.h> 19 - #include <linux/user.h> 20 - #include <linux/signal.h> 21 - 22 - #include <asm/uaccess.h> 23 - #include <asm/page.h> 24 - #include <asm/pgtable.h> 25 - #include <asm/system.h> 26 - #include <asm/processor.h> 27 - 28 - /* 29 - * does not yet catch signals sent when the child dies. 30 - * in exit.c or in signal.c. 31 - */ 32 - 33 - /* determines which bits in the SR the user has access to. */ 34 - /* 1 = access 0 = no access */ 35 - #define SR_MASK 0x001f 36 - 37 - /* sets the trace bits. */ 38 - #define TRACE_BITS 0xC000 39 - #define T1_BIT 0x8000 40 - #define T0_BIT 0x4000 41 - 42 - /* Find the stack offset for a register, relative to thread.esp0. */ 43 - #define PT_REG(reg) ((long)&((struct pt_regs *)0)->reg) 44 - #define SW_REG(reg) ((long)&((struct switch_stack *)0)->reg \ 45 - - sizeof(struct switch_stack)) 46 - /* Mapping from PT_xxx to the stack offset at which the register is 47 - saved. Notice that usp has no stack-slot and needs to be treated 48 - specially (see get_reg/put_reg below). */ 49 - static const int regoff[] = { 50 - [0] = PT_REG(d1), 51 - [1] = PT_REG(d2), 52 - [2] = PT_REG(d3), 53 - [3] = PT_REG(d4), 54 - [4] = PT_REG(d5), 55 - [5] = SW_REG(d6), 56 - [6] = SW_REG(d7), 57 - [7] = PT_REG(a0), 58 - [8] = PT_REG(a1), 59 - [9] = PT_REG(a2), 60 - [10] = SW_REG(a3), 61 - [11] = SW_REG(a4), 62 - [12] = SW_REG(a5), 63 - [13] = SW_REG(a6), 64 - [14] = PT_REG(d0), 65 - [15] = -1, 66 - [16] = PT_REG(orig_d0), 67 - [17] = PT_REG(sr), 68 - [18] = PT_REG(pc), 69 - }; 70 - 71 - /* 72 - * Get contents of register REGNO in task TASK. 73 - */ 74 - static inline long get_reg(struct task_struct *task, int regno) 75 - { 76 - unsigned long *addr; 77 - 78 - if (regno == PT_USP) 79 - addr = &task->thread.usp; 80 - else if (regno < ARRAY_SIZE(regoff)) 81 - addr = (unsigned long *)(task->thread.esp0 + regoff[regno]); 82 - else 83 - return 0; 84 - /* Need to take stkadj into account. */ 85 - if (regno == PT_SR || regno == PT_PC) { 86 - long stkadj = *(long *)(task->thread.esp0 + PT_REG(stkadj)); 87 - addr = (unsigned long *) ((unsigned long)addr + stkadj); 88 - /* The sr is actually a 16 bit register. */ 89 - if (regno == PT_SR) 90 - return *(unsigned short *)addr; 91 - } 92 - return *addr; 93 - } 94 - 95 - /* 96 - * Write contents of register REGNO in task TASK. 97 - */ 98 - static inline int put_reg(struct task_struct *task, int regno, 99 - unsigned long data) 100 - { 101 - unsigned long *addr; 102 - 103 - if (regno == PT_USP) 104 - addr = &task->thread.usp; 105 - else if (regno < ARRAY_SIZE(regoff)) 106 - addr = (unsigned long *)(task->thread.esp0 + regoff[regno]); 107 - else 108 - return -1; 109 - /* Need to take stkadj into account. */ 110 - if (regno == PT_SR || regno == PT_PC) { 111 - long stkadj = *(long *)(task->thread.esp0 + PT_REG(stkadj)); 112 - addr = (unsigned long *) ((unsigned long)addr + stkadj); 113 - /* The sr is actually a 16 bit register. */ 114 - if (regno == PT_SR) { 115 - *(unsigned short *)addr = data; 116 - return 0; 117 - } 118 - } 119 - *addr = data; 120 - return 0; 121 - } 122 - 123 - /* 124 - * Make sure the single step bit is not set. 125 - */ 126 - static inline void singlestep_disable(struct task_struct *child) 127 - { 128 - unsigned long tmp = get_reg(child, PT_SR) & ~TRACE_BITS; 129 - put_reg(child, PT_SR, tmp); 130 - clear_tsk_thread_flag(child, TIF_DELAYED_TRACE); 131 - } 132 - 133 - /* 134 - * Called by kernel/ptrace.c when detaching.. 135 - */ 136 - void ptrace_disable(struct task_struct *child) 137 - { 138 - singlestep_disable(child); 139 - } 140 - 141 - void user_enable_single_step(struct task_struct *child) 142 - { 143 - unsigned long tmp = get_reg(child, PT_SR) & ~TRACE_BITS; 144 - put_reg(child, PT_SR, tmp | T1_BIT); 145 - set_tsk_thread_flag(child, TIF_DELAYED_TRACE); 146 - } 147 - 148 - void user_enable_block_step(struct task_struct *child) 149 - { 150 - unsigned long tmp = get_reg(child, PT_SR) & ~TRACE_BITS; 151 - put_reg(child, PT_SR, tmp | T0_BIT); 152 - } 153 - 154 - void user_disable_single_step(struct task_struct *child) 155 - { 156 - singlestep_disable(child); 157 - } 158 - 159 - long arch_ptrace(struct task_struct *child, long request, 160 - unsigned long addr, unsigned long data) 161 - { 162 - unsigned long tmp; 163 - int i, ret = 0; 164 - int regno = addr >> 2; /* temporary hack. */ 165 - unsigned long __user *datap = (unsigned long __user *) data; 166 - 167 - switch (request) { 168 - /* read the word at location addr in the USER area. */ 169 - case PTRACE_PEEKUSR: 170 - if (addr & 3) 171 - goto out_eio; 172 - 173 - if (regno >= 0 && regno < 19) { 174 - tmp = get_reg(child, regno); 175 - } else if (regno >= 21 && regno < 49) { 176 - tmp = child->thread.fp[regno - 21]; 177 - /* Convert internal fpu reg representation 178 - * into long double format 179 - */ 180 - if (FPU_IS_EMU && (regno < 45) && !(regno % 3)) 181 - tmp = ((tmp & 0xffff0000) << 15) | 182 - ((tmp & 0x0000ffff) << 16); 183 - } else 184 - goto out_eio; 185 - ret = put_user(tmp, datap); 186 - break; 187 - 188 - case PTRACE_POKEUSR: 189 - /* write the word at location addr in the USER area */ 190 - if (addr & 3) 191 - goto out_eio; 192 - 193 - if (regno == PT_SR) { 194 - data &= SR_MASK; 195 - data |= get_reg(child, PT_SR) & ~SR_MASK; 196 - } 197 - if (regno >= 0 && regno < 19) { 198 - if (put_reg(child, regno, data)) 199 - goto out_eio; 200 - } else if (regno >= 21 && regno < 48) { 201 - /* Convert long double format 202 - * into internal fpu reg representation 203 - */ 204 - if (FPU_IS_EMU && (regno < 45) && !(regno % 3)) { 205 - data <<= 15; 206 - data = (data & 0xffff0000) | 207 - ((data & 0x0000ffff) >> 1); 208 - } 209 - child->thread.fp[regno - 21] = data; 210 - } else 211 - goto out_eio; 212 - break; 213 - 214 - case PTRACE_GETREGS: /* Get all gp regs from the child. */ 215 - for (i = 0; i < 19; i++) { 216 - tmp = get_reg(child, i); 217 - ret = put_user(tmp, datap); 218 - if (ret) 219 - break; 220 - datap++; 221 - } 222 - break; 223 - 224 - case PTRACE_SETREGS: /* Set all gp regs in the child. */ 225 - for (i = 0; i < 19; i++) { 226 - ret = get_user(tmp, datap); 227 - if (ret) 228 - break; 229 - if (i == PT_SR) { 230 - tmp &= SR_MASK; 231 - tmp |= get_reg(child, PT_SR) & ~SR_MASK; 232 - } 233 - put_reg(child, i, tmp); 234 - datap++; 235 - } 236 - break; 237 - 238 - case PTRACE_GETFPREGS: /* Get the child FPU state. */ 239 - if (copy_to_user(datap, &child->thread.fp, 240 - sizeof(struct user_m68kfp_struct))) 241 - ret = -EFAULT; 242 - break; 243 - 244 - case PTRACE_SETFPREGS: /* Set the child FPU state. */ 245 - if (copy_from_user(&child->thread.fp, datap, 246 - sizeof(struct user_m68kfp_struct))) 247 - ret = -EFAULT; 248 - break; 249 - 250 - case PTRACE_GET_THREAD_AREA: 251 - ret = put_user(task_thread_info(child)->tp_value, datap); 252 - break; 253 - 254 - default: 255 - ret = ptrace_request(child, request, addr, data); 256 - break; 257 - } 258 - 259 - return ret; 260 - out_eio: 261 - return -EIO; 262 - } 263 - 264 - asmlinkage void syscall_trace(void) 265 - { 266 - ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD) 267 - ? 0x80 : 0)); 268 - /* 269 - * this isn't the same as continuing with a signal, but it will do 270 - * for normal use. strace only continues with a signal if the 271 - * stopping signal is not SIGTRAP. -brl 272 - */ 273 - if (current->exit_code) { 274 - send_sig(current->exit_code, current, 1); 275 - current->exit_code = 0; 276 - } 277 - }
··· 1 + #ifdef CONFIG_MMU 2 + #include "ptrace_mm.c" 3 + #else 4 + #include "ptrace_no.c" 5 + #endif
+277
arch/m68k/kernel/ptrace_mm.c
···
··· 1 + /* 2 + * linux/arch/m68k/kernel/ptrace.c 3 + * 4 + * Copyright (C) 1994 by Hamish Macdonald 5 + * Taken from linux/kernel/ptrace.c and modified for M680x0. 6 + * linux/kernel/ptrace.c is by Ross Biro 1/23/92, edited by Linus Torvalds 7 + * 8 + * This file is subject to the terms and conditions of the GNU General 9 + * Public License. See the file COPYING in the main directory of 10 + * this archive for more details. 11 + */ 12 + 13 + #include <linux/kernel.h> 14 + #include <linux/sched.h> 15 + #include <linux/mm.h> 16 + #include <linux/smp.h> 17 + #include <linux/errno.h> 18 + #include <linux/ptrace.h> 19 + #include <linux/user.h> 20 + #include <linux/signal.h> 21 + 22 + #include <asm/uaccess.h> 23 + #include <asm/page.h> 24 + #include <asm/pgtable.h> 25 + #include <asm/system.h> 26 + #include <asm/processor.h> 27 + 28 + /* 29 + * does not yet catch signals sent when the child dies. 30 + * in exit.c or in signal.c. 31 + */ 32 + 33 + /* determines which bits in the SR the user has access to. */ 34 + /* 1 = access 0 = no access */ 35 + #define SR_MASK 0x001f 36 + 37 + /* sets the trace bits. */ 38 + #define TRACE_BITS 0xC000 39 + #define T1_BIT 0x8000 40 + #define T0_BIT 0x4000 41 + 42 + /* Find the stack offset for a register, relative to thread.esp0. */ 43 + #define PT_REG(reg) ((long)&((struct pt_regs *)0)->reg) 44 + #define SW_REG(reg) ((long)&((struct switch_stack *)0)->reg \ 45 + - sizeof(struct switch_stack)) 46 + /* Mapping from PT_xxx to the stack offset at which the register is 47 + saved. Notice that usp has no stack-slot and needs to be treated 48 + specially (see get_reg/put_reg below). */ 49 + static const int regoff[] = { 50 + [0] = PT_REG(d1), 51 + [1] = PT_REG(d2), 52 + [2] = PT_REG(d3), 53 + [3] = PT_REG(d4), 54 + [4] = PT_REG(d5), 55 + [5] = SW_REG(d6), 56 + [6] = SW_REG(d7), 57 + [7] = PT_REG(a0), 58 + [8] = PT_REG(a1), 59 + [9] = PT_REG(a2), 60 + [10] = SW_REG(a3), 61 + [11] = SW_REG(a4), 62 + [12] = SW_REG(a5), 63 + [13] = SW_REG(a6), 64 + [14] = PT_REG(d0), 65 + [15] = -1, 66 + [16] = PT_REG(orig_d0), 67 + [17] = PT_REG(sr), 68 + [18] = PT_REG(pc), 69 + }; 70 + 71 + /* 72 + * Get contents of register REGNO in task TASK. 73 + */ 74 + static inline long get_reg(struct task_struct *task, int regno) 75 + { 76 + unsigned long *addr; 77 + 78 + if (regno == PT_USP) 79 + addr = &task->thread.usp; 80 + else if (regno < ARRAY_SIZE(regoff)) 81 + addr = (unsigned long *)(task->thread.esp0 + regoff[regno]); 82 + else 83 + return 0; 84 + /* Need to take stkadj into account. */ 85 + if (regno == PT_SR || regno == PT_PC) { 86 + long stkadj = *(long *)(task->thread.esp0 + PT_REG(stkadj)); 87 + addr = (unsigned long *) ((unsigned long)addr + stkadj); 88 + /* The sr is actually a 16 bit register. */ 89 + if (regno == PT_SR) 90 + return *(unsigned short *)addr; 91 + } 92 + return *addr; 93 + } 94 + 95 + /* 96 + * Write contents of register REGNO in task TASK. 97 + */ 98 + static inline int put_reg(struct task_struct *task, int regno, 99 + unsigned long data) 100 + { 101 + unsigned long *addr; 102 + 103 + if (regno == PT_USP) 104 + addr = &task->thread.usp; 105 + else if (regno < ARRAY_SIZE(regoff)) 106 + addr = (unsigned long *)(task->thread.esp0 + regoff[regno]); 107 + else 108 + return -1; 109 + /* Need to take stkadj into account. */ 110 + if (regno == PT_SR || regno == PT_PC) { 111 + long stkadj = *(long *)(task->thread.esp0 + PT_REG(stkadj)); 112 + addr = (unsigned long *) ((unsigned long)addr + stkadj); 113 + /* The sr is actually a 16 bit register. */ 114 + if (regno == PT_SR) { 115 + *(unsigned short *)addr = data; 116 + return 0; 117 + } 118 + } 119 + *addr = data; 120 + return 0; 121 + } 122 + 123 + /* 124 + * Make sure the single step bit is not set. 125 + */ 126 + static inline void singlestep_disable(struct task_struct *child) 127 + { 128 + unsigned long tmp = get_reg(child, PT_SR) & ~TRACE_BITS; 129 + put_reg(child, PT_SR, tmp); 130 + clear_tsk_thread_flag(child, TIF_DELAYED_TRACE); 131 + } 132 + 133 + /* 134 + * Called by kernel/ptrace.c when detaching.. 135 + */ 136 + void ptrace_disable(struct task_struct *child) 137 + { 138 + singlestep_disable(child); 139 + } 140 + 141 + void user_enable_single_step(struct task_struct *child) 142 + { 143 + unsigned long tmp = get_reg(child, PT_SR) & ~TRACE_BITS; 144 + put_reg(child, PT_SR, tmp | T1_BIT); 145 + set_tsk_thread_flag(child, TIF_DELAYED_TRACE); 146 + } 147 + 148 + void user_enable_block_step(struct task_struct *child) 149 + { 150 + unsigned long tmp = get_reg(child, PT_SR) & ~TRACE_BITS; 151 + put_reg(child, PT_SR, tmp | T0_BIT); 152 + } 153 + 154 + void user_disable_single_step(struct task_struct *child) 155 + { 156 + singlestep_disable(child); 157 + } 158 + 159 + long arch_ptrace(struct task_struct *child, long request, 160 + unsigned long addr, unsigned long data) 161 + { 162 + unsigned long tmp; 163 + int i, ret = 0; 164 + int regno = addr >> 2; /* temporary hack. */ 165 + unsigned long __user *datap = (unsigned long __user *) data; 166 + 167 + switch (request) { 168 + /* read the word at location addr in the USER area. */ 169 + case PTRACE_PEEKUSR: 170 + if (addr & 3) 171 + goto out_eio; 172 + 173 + if (regno >= 0 && regno < 19) { 174 + tmp = get_reg(child, regno); 175 + } else if (regno >= 21 && regno < 49) { 176 + tmp = child->thread.fp[regno - 21]; 177 + /* Convert internal fpu reg representation 178 + * into long double format 179 + */ 180 + if (FPU_IS_EMU && (regno < 45) && !(regno % 3)) 181 + tmp = ((tmp & 0xffff0000) << 15) | 182 + ((tmp & 0x0000ffff) << 16); 183 + } else 184 + goto out_eio; 185 + ret = put_user(tmp, datap); 186 + break; 187 + 188 + case PTRACE_POKEUSR: 189 + /* write the word at location addr in the USER area */ 190 + if (addr & 3) 191 + goto out_eio; 192 + 193 + if (regno == PT_SR) { 194 + data &= SR_MASK; 195 + data |= get_reg(child, PT_SR) & ~SR_MASK; 196 + } 197 + if (regno >= 0 && regno < 19) { 198 + if (put_reg(child, regno, data)) 199 + goto out_eio; 200 + } else if (regno >= 21 && regno < 48) { 201 + /* Convert long double format 202 + * into internal fpu reg representation 203 + */ 204 + if (FPU_IS_EMU && (regno < 45) && !(regno % 3)) { 205 + data <<= 15; 206 + data = (data & 0xffff0000) | 207 + ((data & 0x0000ffff) >> 1); 208 + } 209 + child->thread.fp[regno - 21] = data; 210 + } else 211 + goto out_eio; 212 + break; 213 + 214 + case PTRACE_GETREGS: /* Get all gp regs from the child. */ 215 + for (i = 0; i < 19; i++) { 216 + tmp = get_reg(child, i); 217 + ret = put_user(tmp, datap); 218 + if (ret) 219 + break; 220 + datap++; 221 + } 222 + break; 223 + 224 + case PTRACE_SETREGS: /* Set all gp regs in the child. */ 225 + for (i = 0; i < 19; i++) { 226 + ret = get_user(tmp, datap); 227 + if (ret) 228 + break; 229 + if (i == PT_SR) { 230 + tmp &= SR_MASK; 231 + tmp |= get_reg(child, PT_SR) & ~SR_MASK; 232 + } 233 + put_reg(child, i, tmp); 234 + datap++; 235 + } 236 + break; 237 + 238 + case PTRACE_GETFPREGS: /* Get the child FPU state. */ 239 + if (copy_to_user(datap, &child->thread.fp, 240 + sizeof(struct user_m68kfp_struct))) 241 + ret = -EFAULT; 242 + break; 243 + 244 + case PTRACE_SETFPREGS: /* Set the child FPU state. */ 245 + if (copy_from_user(&child->thread.fp, datap, 246 + sizeof(struct user_m68kfp_struct))) 247 + ret = -EFAULT; 248 + break; 249 + 250 + case PTRACE_GET_THREAD_AREA: 251 + ret = put_user(task_thread_info(child)->tp_value, datap); 252 + break; 253 + 254 + default: 255 + ret = ptrace_request(child, request, addr, data); 256 + break; 257 + } 258 + 259 + return ret; 260 + out_eio: 261 + return -EIO; 262 + } 263 + 264 + asmlinkage void syscall_trace(void) 265 + { 266 + ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD) 267 + ? 0x80 : 0)); 268 + /* 269 + * this isn't the same as continuing with a signal, but it will do 270 + * for normal use. strace only continues with a signal if the 271 + * stopping signal is not SIGTRAP. -brl 272 + */ 273 + if (current->exit_code) { 274 + send_sig(current->exit_code, current, 1); 275 + current->exit_code = 0; 276 + } 277 + }
+3 -531
arch/m68k/kernel/setup.c
··· 1 - /* 2 - * linux/arch/m68k/kernel/setup.c 3 - * 4 - * Copyright (C) 1995 Hamish Macdonald 5 - */ 6 - 7 - /* 8 - * This file handles the architecture-dependent parts of system setup 9 - */ 10 - 11 - #include <linux/kernel.h> 12 - #include <linux/mm.h> 13 - #include <linux/sched.h> 14 - #include <linux/delay.h> 15 - #include <linux/interrupt.h> 16 - #include <linux/fs.h> 17 - #include <linux/console.h> 18 - #include <linux/genhd.h> 19 - #include <linux/errno.h> 20 - #include <linux/string.h> 21 - #include <linux/init.h> 22 - #include <linux/bootmem.h> 23 - #include <linux/proc_fs.h> 24 - #include <linux/seq_file.h> 25 - #include <linux/module.h> 26 - #include <linux/initrd.h> 27 - 28 - #include <asm/bootinfo.h> 29 - #include <asm/sections.h> 30 - #include <asm/setup.h> 31 - #include <asm/fpu.h> 32 - #include <asm/irq.h> 33 - #include <asm/io.h> 34 - #include <asm/machdep.h> 35 - #ifdef CONFIG_AMIGA 36 - #include <asm/amigahw.h> 37 - #endif 38 - #ifdef CONFIG_ATARI 39 - #include <asm/atarihw.h> 40 - #include <asm/atari_stram.h> 41 - #endif 42 - #ifdef CONFIG_SUN3X 43 - #include <asm/dvma.h> 44 - #endif 45 - #include <asm/natfeat.h> 46 - 47 - #if !FPSTATESIZE || !NR_IRQS 48 - #warning No CPU/platform type selected, your kernel will not work! 49 - #warning Are you building an allnoconfig kernel? 50 - #endif 51 - 52 - unsigned long m68k_machtype; 53 - EXPORT_SYMBOL(m68k_machtype); 54 - unsigned long m68k_cputype; 55 - EXPORT_SYMBOL(m68k_cputype); 56 - unsigned long m68k_fputype; 57 - unsigned long m68k_mmutype; 58 - EXPORT_SYMBOL(m68k_mmutype); 59 - #ifdef CONFIG_VME 60 - unsigned long vme_brdtype; 61 - EXPORT_SYMBOL(vme_brdtype); 62 - #endif 63 - 64 - int m68k_is040or060; 65 - EXPORT_SYMBOL(m68k_is040or060); 66 - 67 - extern unsigned long availmem; 68 - 69 - int m68k_num_memory; 70 - EXPORT_SYMBOL(m68k_num_memory); 71 - int m68k_realnum_memory; 72 - EXPORT_SYMBOL(m68k_realnum_memory); 73 - unsigned long m68k_memoffset; 74 - struct mem_info m68k_memory[NUM_MEMINFO]; 75 - EXPORT_SYMBOL(m68k_memory); 76 - 77 - struct mem_info m68k_ramdisk; 78 - 79 - static char m68k_command_line[CL_SIZE]; 80 - 81 - void (*mach_sched_init) (irq_handler_t handler) __initdata = NULL; 82 - /* machine dependent irq functions */ 83 - void (*mach_init_IRQ) (void) __initdata = NULL; 84 - void (*mach_get_model) (char *model); 85 - void (*mach_get_hardware_list) (struct seq_file *m); 86 - /* machine dependent timer functions */ 87 - unsigned long (*mach_gettimeoffset) (void); 88 - int (*mach_hwclk) (int, struct rtc_time*); 89 - EXPORT_SYMBOL(mach_hwclk); 90 - int (*mach_set_clock_mmss) (unsigned long); 91 - unsigned int (*mach_get_ss)(void); 92 - int (*mach_get_rtc_pll)(struct rtc_pll_info *); 93 - int (*mach_set_rtc_pll)(struct rtc_pll_info *); 94 - EXPORT_SYMBOL(mach_get_ss); 95 - EXPORT_SYMBOL(mach_get_rtc_pll); 96 - EXPORT_SYMBOL(mach_set_rtc_pll); 97 - void (*mach_reset)( void ); 98 - void (*mach_halt)( void ); 99 - void (*mach_power_off)( void ); 100 - long mach_max_dma_address = 0x00ffffff; /* default set to the lower 16MB */ 101 - #ifdef CONFIG_HEARTBEAT 102 - void (*mach_heartbeat) (int); 103 - EXPORT_SYMBOL(mach_heartbeat); 104 - #endif 105 - #ifdef CONFIG_M68K_L2_CACHE 106 - void (*mach_l2_flush) (int); 107 - #endif 108 - #if defined(CONFIG_INPUT_M68K_BEEP) || defined(CONFIG_INPUT_M68K_BEEP_MODULE) 109 - void (*mach_beep)(unsigned int, unsigned int); 110 - EXPORT_SYMBOL(mach_beep); 111 - #endif 112 - #if defined(CONFIG_ISA) && defined(MULTI_ISA) 113 - int isa_type; 114 - int isa_sex; 115 - EXPORT_SYMBOL(isa_type); 116 - EXPORT_SYMBOL(isa_sex); 117 - #endif 118 - 119 - extern int amiga_parse_bootinfo(const struct bi_record *); 120 - extern int atari_parse_bootinfo(const struct bi_record *); 121 - extern int mac_parse_bootinfo(const struct bi_record *); 122 - extern int q40_parse_bootinfo(const struct bi_record *); 123 - extern int bvme6000_parse_bootinfo(const struct bi_record *); 124 - extern int mvme16x_parse_bootinfo(const struct bi_record *); 125 - extern int mvme147_parse_bootinfo(const struct bi_record *); 126 - extern int hp300_parse_bootinfo(const struct bi_record *); 127 - extern int apollo_parse_bootinfo(const struct bi_record *); 128 - 129 - extern void config_amiga(void); 130 - extern void config_atari(void); 131 - extern void config_mac(void); 132 - extern void config_sun3(void); 133 - extern void config_apollo(void); 134 - extern void config_mvme147(void); 135 - extern void config_mvme16x(void); 136 - extern void config_bvme6000(void); 137 - extern void config_hp300(void); 138 - extern void config_q40(void); 139 - extern void config_sun3x(void); 140 - 141 - #define MASK_256K 0xfffc0000 142 - 143 - extern void paging_init(void); 144 - 145 - static void __init m68k_parse_bootinfo(const struct bi_record *record) 146 - { 147 - while (record->tag != BI_LAST) { 148 - int unknown = 0; 149 - const unsigned long *data = record->data; 150 - 151 - switch (record->tag) { 152 - case BI_MACHTYPE: 153 - case BI_CPUTYPE: 154 - case BI_FPUTYPE: 155 - case BI_MMUTYPE: 156 - /* Already set up by head.S */ 157 - break; 158 - 159 - case BI_MEMCHUNK: 160 - if (m68k_num_memory < NUM_MEMINFO) { 161 - m68k_memory[m68k_num_memory].addr = data[0]; 162 - m68k_memory[m68k_num_memory].size = data[1]; 163 - m68k_num_memory++; 164 - } else 165 - printk("m68k_parse_bootinfo: too many memory chunks\n"); 166 - break; 167 - 168 - case BI_RAMDISK: 169 - m68k_ramdisk.addr = data[0]; 170 - m68k_ramdisk.size = data[1]; 171 - break; 172 - 173 - case BI_COMMAND_LINE: 174 - strlcpy(m68k_command_line, (const char *)data, 175 - sizeof(m68k_command_line)); 176 - break; 177 - 178 - default: 179 - if (MACH_IS_AMIGA) 180 - unknown = amiga_parse_bootinfo(record); 181 - else if (MACH_IS_ATARI) 182 - unknown = atari_parse_bootinfo(record); 183 - else if (MACH_IS_MAC) 184 - unknown = mac_parse_bootinfo(record); 185 - else if (MACH_IS_Q40) 186 - unknown = q40_parse_bootinfo(record); 187 - else if (MACH_IS_BVME6000) 188 - unknown = bvme6000_parse_bootinfo(record); 189 - else if (MACH_IS_MVME16x) 190 - unknown = mvme16x_parse_bootinfo(record); 191 - else if (MACH_IS_MVME147) 192 - unknown = mvme147_parse_bootinfo(record); 193 - else if (MACH_IS_HP300) 194 - unknown = hp300_parse_bootinfo(record); 195 - else if (MACH_IS_APOLLO) 196 - unknown = apollo_parse_bootinfo(record); 197 - else 198 - unknown = 1; 199 - } 200 - if (unknown) 201 - printk("m68k_parse_bootinfo: unknown tag 0x%04x ignored\n", 202 - record->tag); 203 - record = (struct bi_record *)((unsigned long)record + 204 - record->size); 205 - } 206 - 207 - m68k_realnum_memory = m68k_num_memory; 208 - #ifdef CONFIG_SINGLE_MEMORY_CHUNK 209 - if (m68k_num_memory > 1) { 210 - printk("Ignoring last %i chunks of physical memory\n", 211 - (m68k_num_memory - 1)); 212 - m68k_num_memory = 1; 213 - } 214 - #endif 215 - } 216 - 217 - void __init setup_arch(char **cmdline_p) 218 - { 219 - int i; 220 - 221 - /* The bootinfo is located right after the kernel bss */ 222 - m68k_parse_bootinfo((const struct bi_record *)_end); 223 - 224 - if (CPU_IS_040) 225 - m68k_is040or060 = 4; 226 - else if (CPU_IS_060) 227 - m68k_is040or060 = 6; 228 - 229 - /* FIXME: m68k_fputype is passed in by Penguin booter, which can 230 - * be confused by software FPU emulation. BEWARE. 231 - * We should really do our own FPU check at startup. 232 - * [what do we do with buggy 68LC040s? if we have problems 233 - * with them, we should add a test to check_bugs() below] */ 234 - #ifndef CONFIG_M68KFPU_EMU_ONLY 235 - /* clear the fpu if we have one */ 236 - if (m68k_fputype & (FPU_68881|FPU_68882|FPU_68040|FPU_68060)) { 237 - volatile int zero = 0; 238 - asm volatile ("frestore %0" : : "m" (zero)); 239 - } 240 - #endif 241 - 242 - if (CPU_IS_060) { 243 - u32 pcr; 244 - 245 - asm (".chip 68060; movec %%pcr,%0; .chip 68k" 246 - : "=d" (pcr)); 247 - if (((pcr >> 8) & 0xff) <= 5) { 248 - printk("Enabling workaround for errata I14\n"); 249 - asm (".chip 68060; movec %0,%%pcr; .chip 68k" 250 - : : "d" (pcr | 0x20)); 251 - } 252 - } 253 - 254 - init_mm.start_code = PAGE_OFFSET; 255 - init_mm.end_code = (unsigned long)_etext; 256 - init_mm.end_data = (unsigned long)_edata; 257 - init_mm.brk = (unsigned long)_end; 258 - 259 - *cmdline_p = m68k_command_line; 260 - memcpy(boot_command_line, *cmdline_p, CL_SIZE); 261 - 262 - parse_early_param(); 263 - 264 - #ifdef CONFIG_DUMMY_CONSOLE 265 - conswitchp = &dummy_con; 266 - #endif 267 - 268 - switch (m68k_machtype) { 269 - #ifdef CONFIG_AMIGA 270 - case MACH_AMIGA: 271 - config_amiga(); 272 - break; 273 - #endif 274 - #ifdef CONFIG_ATARI 275 - case MACH_ATARI: 276 - config_atari(); 277 - break; 278 - #endif 279 - #ifdef CONFIG_MAC 280 - case MACH_MAC: 281 - config_mac(); 282 - break; 283 - #endif 284 - #ifdef CONFIG_SUN3 285 - case MACH_SUN3: 286 - config_sun3(); 287 - break; 288 - #endif 289 - #ifdef CONFIG_APOLLO 290 - case MACH_APOLLO: 291 - config_apollo(); 292 - break; 293 - #endif 294 - #ifdef CONFIG_MVME147 295 - case MACH_MVME147: 296 - config_mvme147(); 297 - break; 298 - #endif 299 - #ifdef CONFIG_MVME16x 300 - case MACH_MVME16x: 301 - config_mvme16x(); 302 - break; 303 - #endif 304 - #ifdef CONFIG_BVME6000 305 - case MACH_BVME6000: 306 - config_bvme6000(); 307 - break; 308 - #endif 309 - #ifdef CONFIG_HP300 310 - case MACH_HP300: 311 - config_hp300(); 312 - break; 313 - #endif 314 - #ifdef CONFIG_Q40 315 - case MACH_Q40: 316 - config_q40(); 317 - break; 318 - #endif 319 - #ifdef CONFIG_SUN3X 320 - case MACH_SUN3X: 321 - config_sun3x(); 322 - break; 323 - #endif 324 - default: 325 - panic("No configuration setup"); 326 - } 327 - 328 - #ifdef CONFIG_NATFEAT 329 - nf_init(); 330 - #endif 331 - 332 - paging_init(); 333 - 334 - #ifndef CONFIG_SUN3 335 - for (i = 1; i < m68k_num_memory; i++) 336 - free_bootmem_node(NODE_DATA(i), m68k_memory[i].addr, 337 - m68k_memory[i].size); 338 - #ifdef CONFIG_BLK_DEV_INITRD 339 - if (m68k_ramdisk.size) { 340 - reserve_bootmem_node(__virt_to_node(phys_to_virt(m68k_ramdisk.addr)), 341 - m68k_ramdisk.addr, m68k_ramdisk.size, 342 - BOOTMEM_DEFAULT); 343 - initrd_start = (unsigned long)phys_to_virt(m68k_ramdisk.addr); 344 - initrd_end = initrd_start + m68k_ramdisk.size; 345 - printk("initrd: %08lx - %08lx\n", initrd_start, initrd_end); 346 - } 347 - #endif 348 - 349 - #ifdef CONFIG_ATARI 350 - if (MACH_IS_ATARI) 351 - atari_stram_reserve_pages((void *)availmem); 352 - #endif 353 - #ifdef CONFIG_SUN3X 354 - if (MACH_IS_SUN3X) { 355 - dvma_init(); 356 - } 357 - #endif 358 - 359 - #endif /* !CONFIG_SUN3 */ 360 - 361 - /* set ISA defs early as possible */ 362 - #if defined(CONFIG_ISA) && defined(MULTI_ISA) 363 - if (MACH_IS_Q40) { 364 - isa_type = ISA_TYPE_Q40; 365 - isa_sex = 0; 366 - } 367 - #ifdef CONFIG_AMIGA_PCMCIA 368 - if (MACH_IS_AMIGA && AMIGAHW_PRESENT(PCMCIA)) { 369 - isa_type = ISA_TYPE_AG; 370 - isa_sex = 1; 371 - } 372 - #endif 373 - #endif 374 - } 375 - 376 - static int show_cpuinfo(struct seq_file *m, void *v) 377 - { 378 - const char *cpu, *mmu, *fpu; 379 - unsigned long clockfreq, clockfactor; 380 - 381 - #define LOOP_CYCLES_68020 (8) 382 - #define LOOP_CYCLES_68030 (8) 383 - #define LOOP_CYCLES_68040 (3) 384 - #define LOOP_CYCLES_68060 (1) 385 - 386 - if (CPU_IS_020) { 387 - cpu = "68020"; 388 - clockfactor = LOOP_CYCLES_68020; 389 - } else if (CPU_IS_030) { 390 - cpu = "68030"; 391 - clockfactor = LOOP_CYCLES_68030; 392 - } else if (CPU_IS_040) { 393 - cpu = "68040"; 394 - clockfactor = LOOP_CYCLES_68040; 395 - } else if (CPU_IS_060) { 396 - cpu = "68060"; 397 - clockfactor = LOOP_CYCLES_68060; 398 - } else { 399 - cpu = "680x0"; 400 - clockfactor = 0; 401 - } 402 - 403 - #ifdef CONFIG_M68KFPU_EMU_ONLY 404 - fpu = "none(soft float)"; 405 #else 406 - if (m68k_fputype & FPU_68881) 407 - fpu = "68881"; 408 - else if (m68k_fputype & FPU_68882) 409 - fpu = "68882"; 410 - else if (m68k_fputype & FPU_68040) 411 - fpu = "68040"; 412 - else if (m68k_fputype & FPU_68060) 413 - fpu = "68060"; 414 - else if (m68k_fputype & FPU_SUNFPA) 415 - fpu = "Sun FPA"; 416 - else 417 - fpu = "none"; 418 #endif 419 - 420 - if (m68k_mmutype & MMU_68851) 421 - mmu = "68851"; 422 - else if (m68k_mmutype & MMU_68030) 423 - mmu = "68030"; 424 - else if (m68k_mmutype & MMU_68040) 425 - mmu = "68040"; 426 - else if (m68k_mmutype & MMU_68060) 427 - mmu = "68060"; 428 - else if (m68k_mmutype & MMU_SUN3) 429 - mmu = "Sun-3"; 430 - else if (m68k_mmutype & MMU_APOLLO) 431 - mmu = "Apollo"; 432 - else 433 - mmu = "unknown"; 434 - 435 - clockfreq = loops_per_jiffy * HZ * clockfactor; 436 - 437 - seq_printf(m, "CPU:\t\t%s\n" 438 - "MMU:\t\t%s\n" 439 - "FPU:\t\t%s\n" 440 - "Clocking:\t%lu.%1luMHz\n" 441 - "BogoMips:\t%lu.%02lu\n" 442 - "Calibration:\t%lu loops\n", 443 - cpu, mmu, fpu, 444 - clockfreq/1000000,(clockfreq/100000)%10, 445 - loops_per_jiffy/(500000/HZ),(loops_per_jiffy/(5000/HZ))%100, 446 - loops_per_jiffy); 447 - return 0; 448 - } 449 - 450 - static void *c_start(struct seq_file *m, loff_t *pos) 451 - { 452 - return *pos < 1 ? (void *)1 : NULL; 453 - } 454 - static void *c_next(struct seq_file *m, void *v, loff_t *pos) 455 - { 456 - ++*pos; 457 - return NULL; 458 - } 459 - static void c_stop(struct seq_file *m, void *v) 460 - { 461 - } 462 - const struct seq_operations cpuinfo_op = { 463 - .start = c_start, 464 - .next = c_next, 465 - .stop = c_stop, 466 - .show = show_cpuinfo, 467 - }; 468 - 469 - #ifdef CONFIG_PROC_HARDWARE 470 - static int hardware_proc_show(struct seq_file *m, void *v) 471 - { 472 - char model[80]; 473 - unsigned long mem; 474 - int i; 475 - 476 - if (mach_get_model) 477 - mach_get_model(model); 478 - else 479 - strcpy(model, "Unknown m68k"); 480 - 481 - seq_printf(m, "Model:\t\t%s\n", model); 482 - for (mem = 0, i = 0; i < m68k_num_memory; i++) 483 - mem += m68k_memory[i].size; 484 - seq_printf(m, "System Memory:\t%ldK\n", mem >> 10); 485 - 486 - if (mach_get_hardware_list) 487 - mach_get_hardware_list(m); 488 - 489 - return 0; 490 - } 491 - 492 - static int hardware_proc_open(struct inode *inode, struct file *file) 493 - { 494 - return single_open(file, hardware_proc_show, NULL); 495 - } 496 - 497 - static const struct file_operations hardware_proc_fops = { 498 - .open = hardware_proc_open, 499 - .read = seq_read, 500 - .llseek = seq_lseek, 501 - .release = single_release, 502 - }; 503 - 504 - static int __init proc_hardware_init(void) 505 - { 506 - proc_create("hardware", 0, NULL, &hardware_proc_fops); 507 - return 0; 508 - } 509 - module_init(proc_hardware_init); 510 - #endif 511 - 512 - void check_bugs(void) 513 - { 514 - #ifndef CONFIG_M68KFPU_EMU 515 - if (m68k_fputype == 0) { 516 - printk(KERN_EMERG "*** YOU DO NOT HAVE A FLOATING POINT UNIT, " 517 - "WHICH IS REQUIRED BY LINUX/M68K ***\n"); 518 - printk(KERN_EMERG "Upgrade your hardware or join the FPU " 519 - "emulation project\n"); 520 - panic("no FPU"); 521 - } 522 - #endif /* !CONFIG_M68KFPU_EMU */ 523 - } 524 - 525 - #ifdef CONFIG_ADB 526 - static int __init adb_probe_sync_enable (char *str) { 527 - extern int __adb_probe_sync; 528 - __adb_probe_sync = 1; 529 - return 1; 530 - } 531 - 532 - __setup("adb_sync", adb_probe_sync_enable); 533 - #endif /* CONFIG_ADB */
··· 1 + #ifdef CONFIG_MMU 2 + #include "setup_mm.c" 3 #else 4 + #include "setup_no.c" 5 #endif
+533
arch/m68k/kernel/setup_mm.c
···
··· 1 + /* 2 + * linux/arch/m68k/kernel/setup.c 3 + * 4 + * Copyright (C) 1995 Hamish Macdonald 5 + */ 6 + 7 + /* 8 + * This file handles the architecture-dependent parts of system setup 9 + */ 10 + 11 + #include <linux/kernel.h> 12 + #include <linux/mm.h> 13 + #include <linux/sched.h> 14 + #include <linux/delay.h> 15 + #include <linux/interrupt.h> 16 + #include <linux/fs.h> 17 + #include <linux/console.h> 18 + #include <linux/genhd.h> 19 + #include <linux/errno.h> 20 + #include <linux/string.h> 21 + #include <linux/init.h> 22 + #include <linux/bootmem.h> 23 + #include <linux/proc_fs.h> 24 + #include <linux/seq_file.h> 25 + #include <linux/module.h> 26 + #include <linux/initrd.h> 27 + 28 + #include <asm/bootinfo.h> 29 + #include <asm/sections.h> 30 + #include <asm/setup.h> 31 + #include <asm/fpu.h> 32 + #include <asm/irq.h> 33 + #include <asm/io.h> 34 + #include <asm/machdep.h> 35 + #ifdef CONFIG_AMIGA 36 + #include <asm/amigahw.h> 37 + #endif 38 + #ifdef CONFIG_ATARI 39 + #include <asm/atarihw.h> 40 + #include <asm/atari_stram.h> 41 + #endif 42 + #ifdef CONFIG_SUN3X 43 + #include <asm/dvma.h> 44 + #endif 45 + #include <asm/natfeat.h> 46 + 47 + #if !FPSTATESIZE || !NR_IRQS 48 + #warning No CPU/platform type selected, your kernel will not work! 49 + #warning Are you building an allnoconfig kernel? 50 + #endif 51 + 52 + unsigned long m68k_machtype; 53 + EXPORT_SYMBOL(m68k_machtype); 54 + unsigned long m68k_cputype; 55 + EXPORT_SYMBOL(m68k_cputype); 56 + unsigned long m68k_fputype; 57 + unsigned long m68k_mmutype; 58 + EXPORT_SYMBOL(m68k_mmutype); 59 + #ifdef CONFIG_VME 60 + unsigned long vme_brdtype; 61 + EXPORT_SYMBOL(vme_brdtype); 62 + #endif 63 + 64 + int m68k_is040or060; 65 + EXPORT_SYMBOL(m68k_is040or060); 66 + 67 + extern unsigned long availmem; 68 + 69 + int m68k_num_memory; 70 + EXPORT_SYMBOL(m68k_num_memory); 71 + int m68k_realnum_memory; 72 + EXPORT_SYMBOL(m68k_realnum_memory); 73 + unsigned long m68k_memoffset; 74 + struct mem_info m68k_memory[NUM_MEMINFO]; 75 + EXPORT_SYMBOL(m68k_memory); 76 + 77 + struct mem_info m68k_ramdisk; 78 + 79 + static char m68k_command_line[CL_SIZE]; 80 + 81 + void (*mach_sched_init) (irq_handler_t handler) __initdata = NULL; 82 + /* machine dependent irq functions */ 83 + void (*mach_init_IRQ) (void) __initdata = NULL; 84 + void (*mach_get_model) (char *model); 85 + void (*mach_get_hardware_list) (struct seq_file *m); 86 + /* machine dependent timer functions */ 87 + unsigned long (*mach_gettimeoffset) (void); 88 + int (*mach_hwclk) (int, struct rtc_time*); 89 + EXPORT_SYMBOL(mach_hwclk); 90 + int (*mach_set_clock_mmss) (unsigned long); 91 + unsigned int (*mach_get_ss)(void); 92 + int (*mach_get_rtc_pll)(struct rtc_pll_info *); 93 + int (*mach_set_rtc_pll)(struct rtc_pll_info *); 94 + EXPORT_SYMBOL(mach_get_ss); 95 + EXPORT_SYMBOL(mach_get_rtc_pll); 96 + EXPORT_SYMBOL(mach_set_rtc_pll); 97 + void (*mach_reset)( void ); 98 + void (*mach_halt)( void ); 99 + void (*mach_power_off)( void ); 100 + long mach_max_dma_address = 0x00ffffff; /* default set to the lower 16MB */ 101 + #ifdef CONFIG_HEARTBEAT 102 + void (*mach_heartbeat) (int); 103 + EXPORT_SYMBOL(mach_heartbeat); 104 + #endif 105 + #ifdef CONFIG_M68K_L2_CACHE 106 + void (*mach_l2_flush) (int); 107 + #endif 108 + #if defined(CONFIG_INPUT_M68K_BEEP) || defined(CONFIG_INPUT_M68K_BEEP_MODULE) 109 + void (*mach_beep)(unsigned int, unsigned int); 110 + EXPORT_SYMBOL(mach_beep); 111 + #endif 112 + #if defined(CONFIG_ISA) && defined(MULTI_ISA) 113 + int isa_type; 114 + int isa_sex; 115 + EXPORT_SYMBOL(isa_type); 116 + EXPORT_SYMBOL(isa_sex); 117 + #endif 118 + 119 + extern int amiga_parse_bootinfo(const struct bi_record *); 120 + extern int atari_parse_bootinfo(const struct bi_record *); 121 + extern int mac_parse_bootinfo(const struct bi_record *); 122 + extern int q40_parse_bootinfo(const struct bi_record *); 123 + extern int bvme6000_parse_bootinfo(const struct bi_record *); 124 + extern int mvme16x_parse_bootinfo(const struct bi_record *); 125 + extern int mvme147_parse_bootinfo(const struct bi_record *); 126 + extern int hp300_parse_bootinfo(const struct bi_record *); 127 + extern int apollo_parse_bootinfo(const struct bi_record *); 128 + 129 + extern void config_amiga(void); 130 + extern void config_atari(void); 131 + extern void config_mac(void); 132 + extern void config_sun3(void); 133 + extern void config_apollo(void); 134 + extern void config_mvme147(void); 135 + extern void config_mvme16x(void); 136 + extern void config_bvme6000(void); 137 + extern void config_hp300(void); 138 + extern void config_q40(void); 139 + extern void config_sun3x(void); 140 + 141 + #define MASK_256K 0xfffc0000 142 + 143 + extern void paging_init(void); 144 + 145 + static void __init m68k_parse_bootinfo(const struct bi_record *record) 146 + { 147 + while (record->tag != BI_LAST) { 148 + int unknown = 0; 149 + const unsigned long *data = record->data; 150 + 151 + switch (record->tag) { 152 + case BI_MACHTYPE: 153 + case BI_CPUTYPE: 154 + case BI_FPUTYPE: 155 + case BI_MMUTYPE: 156 + /* Already set up by head.S */ 157 + break; 158 + 159 + case BI_MEMCHUNK: 160 + if (m68k_num_memory < NUM_MEMINFO) { 161 + m68k_memory[m68k_num_memory].addr = data[0]; 162 + m68k_memory[m68k_num_memory].size = data[1]; 163 + m68k_num_memory++; 164 + } else 165 + printk("m68k_parse_bootinfo: too many memory chunks\n"); 166 + break; 167 + 168 + case BI_RAMDISK: 169 + m68k_ramdisk.addr = data[0]; 170 + m68k_ramdisk.size = data[1]; 171 + break; 172 + 173 + case BI_COMMAND_LINE: 174 + strlcpy(m68k_command_line, (const char *)data, 175 + sizeof(m68k_command_line)); 176 + break; 177 + 178 + default: 179 + if (MACH_IS_AMIGA) 180 + unknown = amiga_parse_bootinfo(record); 181 + else if (MACH_IS_ATARI) 182 + unknown = atari_parse_bootinfo(record); 183 + else if (MACH_IS_MAC) 184 + unknown = mac_parse_bootinfo(record); 185 + else if (MACH_IS_Q40) 186 + unknown = q40_parse_bootinfo(record); 187 + else if (MACH_IS_BVME6000) 188 + unknown = bvme6000_parse_bootinfo(record); 189 + else if (MACH_IS_MVME16x) 190 + unknown = mvme16x_parse_bootinfo(record); 191 + else if (MACH_IS_MVME147) 192 + unknown = mvme147_parse_bootinfo(record); 193 + else if (MACH_IS_HP300) 194 + unknown = hp300_parse_bootinfo(record); 195 + else if (MACH_IS_APOLLO) 196 + unknown = apollo_parse_bootinfo(record); 197 + else 198 + unknown = 1; 199 + } 200 + if (unknown) 201 + printk("m68k_parse_bootinfo: unknown tag 0x%04x ignored\n", 202 + record->tag); 203 + record = (struct bi_record *)((unsigned long)record + 204 + record->size); 205 + } 206 + 207 + m68k_realnum_memory = m68k_num_memory; 208 + #ifdef CONFIG_SINGLE_MEMORY_CHUNK 209 + if (m68k_num_memory > 1) { 210 + printk("Ignoring last %i chunks of physical memory\n", 211 + (m68k_num_memory - 1)); 212 + m68k_num_memory = 1; 213 + } 214 + #endif 215 + } 216 + 217 + void __init setup_arch(char **cmdline_p) 218 + { 219 + int i; 220 + 221 + /* The bootinfo is located right after the kernel bss */ 222 + m68k_parse_bootinfo((const struct bi_record *)_end); 223 + 224 + if (CPU_IS_040) 225 + m68k_is040or060 = 4; 226 + else if (CPU_IS_060) 227 + m68k_is040or060 = 6; 228 + 229 + /* FIXME: m68k_fputype is passed in by Penguin booter, which can 230 + * be confused by software FPU emulation. BEWARE. 231 + * We should really do our own FPU check at startup. 232 + * [what do we do with buggy 68LC040s? if we have problems 233 + * with them, we should add a test to check_bugs() below] */ 234 + #ifndef CONFIG_M68KFPU_EMU_ONLY 235 + /* clear the fpu if we have one */ 236 + if (m68k_fputype & (FPU_68881|FPU_68882|FPU_68040|FPU_68060)) { 237 + volatile int zero = 0; 238 + asm volatile ("frestore %0" : : "m" (zero)); 239 + } 240 + #endif 241 + 242 + if (CPU_IS_060) { 243 + u32 pcr; 244 + 245 + asm (".chip 68060; movec %%pcr,%0; .chip 68k" 246 + : "=d" (pcr)); 247 + if (((pcr >> 8) & 0xff) <= 5) { 248 + printk("Enabling workaround for errata I14\n"); 249 + asm (".chip 68060; movec %0,%%pcr; .chip 68k" 250 + : : "d" (pcr | 0x20)); 251 + } 252 + } 253 + 254 + init_mm.start_code = PAGE_OFFSET; 255 + init_mm.end_code = (unsigned long)_etext; 256 + init_mm.end_data = (unsigned long)_edata; 257 + init_mm.brk = (unsigned long)_end; 258 + 259 + *cmdline_p = m68k_command_line; 260 + memcpy(boot_command_line, *cmdline_p, CL_SIZE); 261 + 262 + parse_early_param(); 263 + 264 + #ifdef CONFIG_DUMMY_CONSOLE 265 + conswitchp = &dummy_con; 266 + #endif 267 + 268 + switch (m68k_machtype) { 269 + #ifdef CONFIG_AMIGA 270 + case MACH_AMIGA: 271 + config_amiga(); 272 + break; 273 + #endif 274 + #ifdef CONFIG_ATARI 275 + case MACH_ATARI: 276 + config_atari(); 277 + break; 278 + #endif 279 + #ifdef CONFIG_MAC 280 + case MACH_MAC: 281 + config_mac(); 282 + break; 283 + #endif 284 + #ifdef CONFIG_SUN3 285 + case MACH_SUN3: 286 + config_sun3(); 287 + break; 288 + #endif 289 + #ifdef CONFIG_APOLLO 290 + case MACH_APOLLO: 291 + config_apollo(); 292 + break; 293 + #endif 294 + #ifdef CONFIG_MVME147 295 + case MACH_MVME147: 296 + config_mvme147(); 297 + break; 298 + #endif 299 + #ifdef CONFIG_MVME16x 300 + case MACH_MVME16x: 301 + config_mvme16x(); 302 + break; 303 + #endif 304 + #ifdef CONFIG_BVME6000 305 + case MACH_BVME6000: 306 + config_bvme6000(); 307 + break; 308 + #endif 309 + #ifdef CONFIG_HP300 310 + case MACH_HP300: 311 + config_hp300(); 312 + break; 313 + #endif 314 + #ifdef CONFIG_Q40 315 + case MACH_Q40: 316 + config_q40(); 317 + break; 318 + #endif 319 + #ifdef CONFIG_SUN3X 320 + case MACH_SUN3X: 321 + config_sun3x(); 322 + break; 323 + #endif 324 + default: 325 + panic("No configuration setup"); 326 + } 327 + 328 + #ifdef CONFIG_NATFEAT 329 + nf_init(); 330 + #endif 331 + 332 + paging_init(); 333 + 334 + #ifndef CONFIG_SUN3 335 + for (i = 1; i < m68k_num_memory; i++) 336 + free_bootmem_node(NODE_DATA(i), m68k_memory[i].addr, 337 + m68k_memory[i].size); 338 + #ifdef CONFIG_BLK_DEV_INITRD 339 + if (m68k_ramdisk.size) { 340 + reserve_bootmem_node(__virt_to_node(phys_to_virt(m68k_ramdisk.addr)), 341 + m68k_ramdisk.addr, m68k_ramdisk.size, 342 + BOOTMEM_DEFAULT); 343 + initrd_start = (unsigned long)phys_to_virt(m68k_ramdisk.addr); 344 + initrd_end = initrd_start + m68k_ramdisk.size; 345 + printk("initrd: %08lx - %08lx\n", initrd_start, initrd_end); 346 + } 347 + #endif 348 + 349 + #ifdef CONFIG_ATARI 350 + if (MACH_IS_ATARI) 351 + atari_stram_reserve_pages((void *)availmem); 352 + #endif 353 + #ifdef CONFIG_SUN3X 354 + if (MACH_IS_SUN3X) { 355 + dvma_init(); 356 + } 357 + #endif 358 + 359 + #endif /* !CONFIG_SUN3 */ 360 + 361 + /* set ISA defs early as possible */ 362 + #if defined(CONFIG_ISA) && defined(MULTI_ISA) 363 + if (MACH_IS_Q40) { 364 + isa_type = ISA_TYPE_Q40; 365 + isa_sex = 0; 366 + } 367 + #ifdef CONFIG_AMIGA_PCMCIA 368 + if (MACH_IS_AMIGA && AMIGAHW_PRESENT(PCMCIA)) { 369 + isa_type = ISA_TYPE_AG; 370 + isa_sex = 1; 371 + } 372 + #endif 373 + #endif 374 + } 375 + 376 + static int show_cpuinfo(struct seq_file *m, void *v) 377 + { 378 + const char *cpu, *mmu, *fpu; 379 + unsigned long clockfreq, clockfactor; 380 + 381 + #define LOOP_CYCLES_68020 (8) 382 + #define LOOP_CYCLES_68030 (8) 383 + #define LOOP_CYCLES_68040 (3) 384 + #define LOOP_CYCLES_68060 (1) 385 + 386 + if (CPU_IS_020) { 387 + cpu = "68020"; 388 + clockfactor = LOOP_CYCLES_68020; 389 + } else if (CPU_IS_030) { 390 + cpu = "68030"; 391 + clockfactor = LOOP_CYCLES_68030; 392 + } else if (CPU_IS_040) { 393 + cpu = "68040"; 394 + clockfactor = LOOP_CYCLES_68040; 395 + } else if (CPU_IS_060) { 396 + cpu = "68060"; 397 + clockfactor = LOOP_CYCLES_68060; 398 + } else { 399 + cpu = "680x0"; 400 + clockfactor = 0; 401 + } 402 + 403 + #ifdef CONFIG_M68KFPU_EMU_ONLY 404 + fpu = "none(soft float)"; 405 + #else 406 + if (m68k_fputype & FPU_68881) 407 + fpu = "68881"; 408 + else if (m68k_fputype & FPU_68882) 409 + fpu = "68882"; 410 + else if (m68k_fputype & FPU_68040) 411 + fpu = "68040"; 412 + else if (m68k_fputype & FPU_68060) 413 + fpu = "68060"; 414 + else if (m68k_fputype & FPU_SUNFPA) 415 + fpu = "Sun FPA"; 416 + else 417 + fpu = "none"; 418 + #endif 419 + 420 + if (m68k_mmutype & MMU_68851) 421 + mmu = "68851"; 422 + else if (m68k_mmutype & MMU_68030) 423 + mmu = "68030"; 424 + else if (m68k_mmutype & MMU_68040) 425 + mmu = "68040"; 426 + else if (m68k_mmutype & MMU_68060) 427 + mmu = "68060"; 428 + else if (m68k_mmutype & MMU_SUN3) 429 + mmu = "Sun-3"; 430 + else if (m68k_mmutype & MMU_APOLLO) 431 + mmu = "Apollo"; 432 + else 433 + mmu = "unknown"; 434 + 435 + clockfreq = loops_per_jiffy * HZ * clockfactor; 436 + 437 + seq_printf(m, "CPU:\t\t%s\n" 438 + "MMU:\t\t%s\n" 439 + "FPU:\t\t%s\n" 440 + "Clocking:\t%lu.%1luMHz\n" 441 + "BogoMips:\t%lu.%02lu\n" 442 + "Calibration:\t%lu loops\n", 443 + cpu, mmu, fpu, 444 + clockfreq/1000000,(clockfreq/100000)%10, 445 + loops_per_jiffy/(500000/HZ),(loops_per_jiffy/(5000/HZ))%100, 446 + loops_per_jiffy); 447 + return 0; 448 + } 449 + 450 + static void *c_start(struct seq_file *m, loff_t *pos) 451 + { 452 + return *pos < 1 ? (void *)1 : NULL; 453 + } 454 + static void *c_next(struct seq_file *m, void *v, loff_t *pos) 455 + { 456 + ++*pos; 457 + return NULL; 458 + } 459 + static void c_stop(struct seq_file *m, void *v) 460 + { 461 + } 462 + const struct seq_operations cpuinfo_op = { 463 + .start = c_start, 464 + .next = c_next, 465 + .stop = c_stop, 466 + .show = show_cpuinfo, 467 + }; 468 + 469 + #ifdef CONFIG_PROC_HARDWARE 470 + static int hardware_proc_show(struct seq_file *m, void *v) 471 + { 472 + char model[80]; 473 + unsigned long mem; 474 + int i; 475 + 476 + if (mach_get_model) 477 + mach_get_model(model); 478 + else 479 + strcpy(model, "Unknown m68k"); 480 + 481 + seq_printf(m, "Model:\t\t%s\n", model); 482 + for (mem = 0, i = 0; i < m68k_num_memory; i++) 483 + mem += m68k_memory[i].size; 484 + seq_printf(m, "System Memory:\t%ldK\n", mem >> 10); 485 + 486 + if (mach_get_hardware_list) 487 + mach_get_hardware_list(m); 488 + 489 + return 0; 490 + } 491 + 492 + static int hardware_proc_open(struct inode *inode, struct file *file) 493 + { 494 + return single_open(file, hardware_proc_show, NULL); 495 + } 496 + 497 + static const struct file_operations hardware_proc_fops = { 498 + .open = hardware_proc_open, 499 + .read = seq_read, 500 + .llseek = seq_lseek, 501 + .release = single_release, 502 + }; 503 + 504 + static int __init proc_hardware_init(void) 505 + { 506 + proc_create("hardware", 0, NULL, &hardware_proc_fops); 507 + return 0; 508 + } 509 + module_init(proc_hardware_init); 510 + #endif 511 + 512 + void check_bugs(void) 513 + { 514 + #ifndef CONFIG_M68KFPU_EMU 515 + if (m68k_fputype == 0) { 516 + printk(KERN_EMERG "*** YOU DO NOT HAVE A FLOATING POINT UNIT, " 517 + "WHICH IS REQUIRED BY LINUX/M68K ***\n"); 518 + printk(KERN_EMERG "Upgrade your hardware or join the FPU " 519 + "emulation project\n"); 520 + panic("no FPU"); 521 + } 522 + #endif /* !CONFIG_M68KFPU_EMU */ 523 + } 524 + 525 + #ifdef CONFIG_ADB 526 + static int __init adb_probe_sync_enable (char *str) { 527 + extern int __adb_probe_sync; 528 + __adb_probe_sync = 1; 529 + return 1; 530 + } 531 + 532 + __setup("adb_sync", adb_probe_sync_enable); 533 + #endif /* CONFIG_ADB */
+3 -1015
arch/m68k/kernel/signal.c
··· 1 - /* 2 - * linux/arch/m68k/kernel/signal.c 3 - * 4 - * Copyright (C) 1991, 1992 Linus Torvalds 5 - * 6 - * This file is subject to the terms and conditions of the GNU General Public 7 - * License. See the file COPYING in the main directory of this archive 8 - * for more details. 9 - */ 10 - 11 - /* 12 - * Linux/m68k support by Hamish Macdonald 13 - * 14 - * 68060 fixes by Jesper Skov 15 - * 16 - * 1997-12-01 Modified for POSIX.1b signals by Andreas Schwab 17 - * 18 - * mathemu support by Roman Zippel 19 - * (Note: fpstate in the signal context is completely ignored for the emulator 20 - * and the internal floating point format is put on stack) 21 - */ 22 - 23 - /* 24 - * ++roman (07/09/96): implemented signal stacks (specially for tosemu on 25 - * Atari :-) Current limitation: Only one sigstack can be active at one time. 26 - * If a second signal with SA_ONSTACK set arrives while working on a sigstack, 27 - * SA_ONSTACK is ignored. This behaviour avoids lots of trouble with nested 28 - * signal handlers! 29 - */ 30 - 31 - #include <linux/sched.h> 32 - #include <linux/mm.h> 33 - #include <linux/kernel.h> 34 - #include <linux/signal.h> 35 - #include <linux/syscalls.h> 36 - #include <linux/errno.h> 37 - #include <linux/wait.h> 38 - #include <linux/ptrace.h> 39 - #include <linux/unistd.h> 40 - #include <linux/stddef.h> 41 - #include <linux/highuid.h> 42 - #include <linux/personality.h> 43 - #include <linux/tty.h> 44 - #include <linux/binfmts.h> 45 - #include <linux/module.h> 46 - 47 - #include <asm/setup.h> 48 - #include <asm/uaccess.h> 49 - #include <asm/pgtable.h> 50 - #include <asm/traps.h> 51 - #include <asm/ucontext.h> 52 - 53 - #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) 54 - 55 - static const int frame_extra_sizes[16] = { 56 - [1] = -1, /* sizeof(((struct frame *)0)->un.fmt1), */ 57 - [2] = sizeof(((struct frame *)0)->un.fmt2), 58 - [3] = sizeof(((struct frame *)0)->un.fmt3), 59 - [4] = sizeof(((struct frame *)0)->un.fmt4), 60 - [5] = -1, /* sizeof(((struct frame *)0)->un.fmt5), */ 61 - [6] = -1, /* sizeof(((struct frame *)0)->un.fmt6), */ 62 - [7] = sizeof(((struct frame *)0)->un.fmt7), 63 - [8] = -1, /* sizeof(((struct frame *)0)->un.fmt8), */ 64 - [9] = sizeof(((struct frame *)0)->un.fmt9), 65 - [10] = sizeof(((struct frame *)0)->un.fmta), 66 - [11] = sizeof(((struct frame *)0)->un.fmtb), 67 - [12] = -1, /* sizeof(((struct frame *)0)->un.fmtc), */ 68 - [13] = -1, /* sizeof(((struct frame *)0)->un.fmtd), */ 69 - [14] = -1, /* sizeof(((struct frame *)0)->un.fmte), */ 70 - [15] = -1, /* sizeof(((struct frame *)0)->un.fmtf), */ 71 - }; 72 - 73 - int handle_kernel_fault(struct pt_regs *regs) 74 - { 75 - const struct exception_table_entry *fixup; 76 - struct pt_regs *tregs; 77 - 78 - /* Are we prepared to handle this kernel fault? */ 79 - fixup = search_exception_tables(regs->pc); 80 - if (!fixup) 81 - return 0; 82 - 83 - /* Create a new four word stack frame, discarding the old one. */ 84 - regs->stkadj = frame_extra_sizes[regs->format]; 85 - tregs = (struct pt_regs *)((long)regs + regs->stkadj); 86 - tregs->vector = regs->vector; 87 - tregs->format = 0; 88 - tregs->pc = fixup->fixup; 89 - tregs->sr = regs->sr; 90 - 91 - return 1; 92 - } 93 - 94 - /* 95 - * Atomically swap in the new signal mask, and wait for a signal. 96 - */ 97 - asmlinkage int 98 - sys_sigsuspend(int unused0, int unused1, old_sigset_t mask) 99 - { 100 - mask &= _BLOCKABLE; 101 - spin_lock_irq(&current->sighand->siglock); 102 - current->saved_sigmask = current->blocked; 103 - siginitset(&current->blocked, mask); 104 - recalc_sigpending(); 105 - spin_unlock_irq(&current->sighand->siglock); 106 - 107 - current->state = TASK_INTERRUPTIBLE; 108 - schedule(); 109 - set_restore_sigmask(); 110 - 111 - return -ERESTARTNOHAND; 112 - } 113 - 114 - asmlinkage int 115 - sys_sigaction(int sig, const struct old_sigaction __user *act, 116 - struct old_sigaction __user *oact) 117 - { 118 - struct k_sigaction new_ka, old_ka; 119 - int ret; 120 - 121 - if (act) { 122 - old_sigset_t mask; 123 - if (!access_ok(VERIFY_READ, act, sizeof(*act)) || 124 - __get_user(new_ka.sa.sa_handler, &act->sa_handler) || 125 - __get_user(new_ka.sa.sa_restorer, &act->sa_restorer) || 126 - __get_user(new_ka.sa.sa_flags, &act->sa_flags) || 127 - __get_user(mask, &act->sa_mask)) 128 - return -EFAULT; 129 - siginitset(&new_ka.sa.sa_mask, mask); 130 - } 131 - 132 - ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL); 133 - 134 - if (!ret && oact) { 135 - if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)) || 136 - __put_user(old_ka.sa.sa_handler, &oact->sa_handler) || 137 - __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer) || 138 - __put_user(old_ka.sa.sa_flags, &oact->sa_flags) || 139 - __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask)) 140 - return -EFAULT; 141 - } 142 - 143 - return ret; 144 - } 145 - 146 - asmlinkage int 147 - sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss) 148 - { 149 - return do_sigaltstack(uss, uoss, rdusp()); 150 - } 151 - 152 - 153 - /* 154 - * Do a signal return; undo the signal stack. 155 - * 156 - * Keep the return code on the stack quadword aligned! 157 - * That makes the cache flush below easier. 158 - */ 159 - 160 - struct sigframe 161 - { 162 - char __user *pretcode; 163 - int sig; 164 - int code; 165 - struct sigcontext __user *psc; 166 - char retcode[8]; 167 - unsigned long extramask[_NSIG_WORDS-1]; 168 - struct sigcontext sc; 169 - }; 170 - 171 - struct rt_sigframe 172 - { 173 - char __user *pretcode; 174 - int sig; 175 - struct siginfo __user *pinfo; 176 - void __user *puc; 177 - char retcode[8]; 178 - struct siginfo info; 179 - struct ucontext uc; 180 - }; 181 - 182 - 183 - static unsigned char fpu_version; /* version number of fpu, set by setup_frame */ 184 - 185 - static inline int restore_fpu_state(struct sigcontext *sc) 186 - { 187 - int err = 1; 188 - 189 - if (FPU_IS_EMU) { 190 - /* restore registers */ 191 - memcpy(current->thread.fpcntl, sc->sc_fpcntl, 12); 192 - memcpy(current->thread.fp, sc->sc_fpregs, 24); 193 - return 0; 194 - } 195 - 196 - if (CPU_IS_060 ? sc->sc_fpstate[2] : sc->sc_fpstate[0]) { 197 - /* Verify the frame format. */ 198 - if (!CPU_IS_060 && (sc->sc_fpstate[0] != fpu_version)) 199 - goto out; 200 - if (CPU_IS_020_OR_030) { 201 - if (m68k_fputype & FPU_68881 && 202 - !(sc->sc_fpstate[1] == 0x18 || sc->sc_fpstate[1] == 0xb4)) 203 - goto out; 204 - if (m68k_fputype & FPU_68882 && 205 - !(sc->sc_fpstate[1] == 0x38 || sc->sc_fpstate[1] == 0xd4)) 206 - goto out; 207 - } else if (CPU_IS_040) { 208 - if (!(sc->sc_fpstate[1] == 0x00 || 209 - sc->sc_fpstate[1] == 0x28 || 210 - sc->sc_fpstate[1] == 0x60)) 211 - goto out; 212 - } else if (CPU_IS_060) { 213 - if (!(sc->sc_fpstate[3] == 0x00 || 214 - sc->sc_fpstate[3] == 0x60 || 215 - sc->sc_fpstate[3] == 0xe0)) 216 - goto out; 217 - } else 218 - goto out; 219 - 220 - __asm__ volatile (".chip 68k/68881\n\t" 221 - "fmovemx %0,%%fp0-%%fp1\n\t" 222 - "fmoveml %1,%%fpcr/%%fpsr/%%fpiar\n\t" 223 - ".chip 68k" 224 - : /* no outputs */ 225 - : "m" (*sc->sc_fpregs), "m" (*sc->sc_fpcntl)); 226 - } 227 - __asm__ volatile (".chip 68k/68881\n\t" 228 - "frestore %0\n\t" 229 - ".chip 68k" : : "m" (*sc->sc_fpstate)); 230 - err = 0; 231 - 232 - out: 233 - return err; 234 - } 235 - 236 - #define FPCONTEXT_SIZE 216 237 - #define uc_fpstate uc_filler[0] 238 - #define uc_formatvec uc_filler[FPCONTEXT_SIZE/4] 239 - #define uc_extra uc_filler[FPCONTEXT_SIZE/4+1] 240 - 241 - static inline int rt_restore_fpu_state(struct ucontext __user *uc) 242 - { 243 - unsigned char fpstate[FPCONTEXT_SIZE]; 244 - int context_size = CPU_IS_060 ? 8 : 0; 245 - fpregset_t fpregs; 246 - int err = 1; 247 - 248 - if (FPU_IS_EMU) { 249 - /* restore fpu control register */ 250 - if (__copy_from_user(current->thread.fpcntl, 251 - uc->uc_mcontext.fpregs.f_fpcntl, 12)) 252 - goto out; 253 - /* restore all other fpu register */ 254 - if (__copy_from_user(current->thread.fp, 255 - uc->uc_mcontext.fpregs.f_fpregs, 96)) 256 - goto out; 257 - return 0; 258 - } 259 - 260 - if (__get_user(*(long *)fpstate, (long __user *)&uc->uc_fpstate)) 261 - goto out; 262 - if (CPU_IS_060 ? fpstate[2] : fpstate[0]) { 263 - if (!CPU_IS_060) 264 - context_size = fpstate[1]; 265 - /* Verify the frame format. */ 266 - if (!CPU_IS_060 && (fpstate[0] != fpu_version)) 267 - goto out; 268 - if (CPU_IS_020_OR_030) { 269 - if (m68k_fputype & FPU_68881 && 270 - !(context_size == 0x18 || context_size == 0xb4)) 271 - goto out; 272 - if (m68k_fputype & FPU_68882 && 273 - !(context_size == 0x38 || context_size == 0xd4)) 274 - goto out; 275 - } else if (CPU_IS_040) { 276 - if (!(context_size == 0x00 || 277 - context_size == 0x28 || 278 - context_size == 0x60)) 279 - goto out; 280 - } else if (CPU_IS_060) { 281 - if (!(fpstate[3] == 0x00 || 282 - fpstate[3] == 0x60 || 283 - fpstate[3] == 0xe0)) 284 - goto out; 285 - } else 286 - goto out; 287 - if (__copy_from_user(&fpregs, &uc->uc_mcontext.fpregs, 288 - sizeof(fpregs))) 289 - goto out; 290 - __asm__ volatile (".chip 68k/68881\n\t" 291 - "fmovemx %0,%%fp0-%%fp7\n\t" 292 - "fmoveml %1,%%fpcr/%%fpsr/%%fpiar\n\t" 293 - ".chip 68k" 294 - : /* no outputs */ 295 - : "m" (*fpregs.f_fpregs), 296 - "m" (*fpregs.f_fpcntl)); 297 - } 298 - if (context_size && 299 - __copy_from_user(fpstate + 4, (long __user *)&uc->uc_fpstate + 1, 300 - context_size)) 301 - goto out; 302 - __asm__ volatile (".chip 68k/68881\n\t" 303 - "frestore %0\n\t" 304 - ".chip 68k" : : "m" (*fpstate)); 305 - err = 0; 306 - 307 - out: 308 - return err; 309 - } 310 - 311 - static int mangle_kernel_stack(struct pt_regs *regs, int formatvec, 312 - void __user *fp) 313 - { 314 - int fsize = frame_extra_sizes[formatvec >> 12]; 315 - if (fsize < 0) { 316 - /* 317 - * user process trying to return with weird frame format 318 - */ 319 - #ifdef DEBUG 320 - printk("user process returning with weird frame format\n"); 321 - #endif 322 - return 1; 323 - } 324 - if (!fsize) { 325 - regs->format = formatvec >> 12; 326 - regs->vector = formatvec & 0xfff; 327 - } else { 328 - struct switch_stack *sw = (struct switch_stack *)regs - 1; 329 - unsigned long buf[fsize / 2]; /* yes, twice as much */ 330 - 331 - /* that'll make sure that expansion won't crap over data */ 332 - if (copy_from_user(buf + fsize / 4, fp, fsize)) 333 - return 1; 334 - 335 - /* point of no return */ 336 - regs->format = formatvec >> 12; 337 - regs->vector = formatvec & 0xfff; 338 - #define frame_offset (sizeof(struct pt_regs)+sizeof(struct switch_stack)) 339 - __asm__ __volatile__ 340 - (" movel %0,%/a0\n\t" 341 - " subl %1,%/a0\n\t" /* make room on stack */ 342 - " movel %/a0,%/sp\n\t" /* set stack pointer */ 343 - /* move switch_stack and pt_regs */ 344 - "1: movel %0@+,%/a0@+\n\t" 345 - " dbra %2,1b\n\t" 346 - " lea %/sp@(%c3),%/a0\n\t" /* add offset of fmt */ 347 - " lsrl #2,%1\n\t" 348 - " subql #1,%1\n\t" 349 - /* copy to the gap we'd made */ 350 - "2: movel %4@+,%/a0@+\n\t" 351 - " dbra %1,2b\n\t" 352 - " bral ret_from_signal\n" 353 - : /* no outputs, it doesn't ever return */ 354 - : "a" (sw), "d" (fsize), "d" (frame_offset/4-1), 355 - "n" (frame_offset), "a" (buf + fsize/4) 356 - : "a0"); 357 - #undef frame_offset 358 - } 359 - return 0; 360 - } 361 - 362 - static inline int 363 - restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *usc, void __user *fp) 364 - { 365 - int formatvec; 366 - struct sigcontext context; 367 - int err; 368 - 369 - /* Always make any pending restarted system calls return -EINTR */ 370 - current_thread_info()->restart_block.fn = do_no_restart_syscall; 371 - 372 - /* get previous context */ 373 - if (copy_from_user(&context, usc, sizeof(context))) 374 - goto badframe; 375 - 376 - /* restore passed registers */ 377 - regs->d0 = context.sc_d0; 378 - regs->d1 = context.sc_d1; 379 - regs->a0 = context.sc_a0; 380 - regs->a1 = context.sc_a1; 381 - regs->sr = (regs->sr & 0xff00) | (context.sc_sr & 0xff); 382 - regs->pc = context.sc_pc; 383 - regs->orig_d0 = -1; /* disable syscall checks */ 384 - wrusp(context.sc_usp); 385 - formatvec = context.sc_formatvec; 386 - 387 - err = restore_fpu_state(&context); 388 - 389 - if (err || mangle_kernel_stack(regs, formatvec, fp)) 390 - goto badframe; 391 - 392 - return 0; 393 - 394 - badframe: 395 - return 1; 396 - } 397 - 398 - static inline int 399 - rt_restore_ucontext(struct pt_regs *regs, struct switch_stack *sw, 400 - struct ucontext __user *uc) 401 - { 402 - int temp; 403 - greg_t __user *gregs = uc->uc_mcontext.gregs; 404 - unsigned long usp; 405 - int err; 406 - 407 - /* Always make any pending restarted system calls return -EINTR */ 408 - current_thread_info()->restart_block.fn = do_no_restart_syscall; 409 - 410 - err = __get_user(temp, &uc->uc_mcontext.version); 411 - if (temp != MCONTEXT_VERSION) 412 - goto badframe; 413 - /* restore passed registers */ 414 - err |= __get_user(regs->d0, &gregs[0]); 415 - err |= __get_user(regs->d1, &gregs[1]); 416 - err |= __get_user(regs->d2, &gregs[2]); 417 - err |= __get_user(regs->d3, &gregs[3]); 418 - err |= __get_user(regs->d4, &gregs[4]); 419 - err |= __get_user(regs->d5, &gregs[5]); 420 - err |= __get_user(sw->d6, &gregs[6]); 421 - err |= __get_user(sw->d7, &gregs[7]); 422 - err |= __get_user(regs->a0, &gregs[8]); 423 - err |= __get_user(regs->a1, &gregs[9]); 424 - err |= __get_user(regs->a2, &gregs[10]); 425 - err |= __get_user(sw->a3, &gregs[11]); 426 - err |= __get_user(sw->a4, &gregs[12]); 427 - err |= __get_user(sw->a5, &gregs[13]); 428 - err |= __get_user(sw->a6, &gregs[14]); 429 - err |= __get_user(usp, &gregs[15]); 430 - wrusp(usp); 431 - err |= __get_user(regs->pc, &gregs[16]); 432 - err |= __get_user(temp, &gregs[17]); 433 - regs->sr = (regs->sr & 0xff00) | (temp & 0xff); 434 - regs->orig_d0 = -1; /* disable syscall checks */ 435 - err |= __get_user(temp, &uc->uc_formatvec); 436 - 437 - err |= rt_restore_fpu_state(uc); 438 - 439 - if (err || do_sigaltstack(&uc->uc_stack, NULL, usp) == -EFAULT) 440 - goto badframe; 441 - 442 - if (mangle_kernel_stack(regs, temp, &uc->uc_extra)) 443 - goto badframe; 444 - 445 - return 0; 446 - 447 - badframe: 448 - return 1; 449 - } 450 - 451 - asmlinkage int do_sigreturn(unsigned long __unused) 452 - { 453 - struct switch_stack *sw = (struct switch_stack *) &__unused; 454 - struct pt_regs *regs = (struct pt_regs *) (sw + 1); 455 - unsigned long usp = rdusp(); 456 - struct sigframe __user *frame = (struct sigframe __user *)(usp - 4); 457 - sigset_t set; 458 - 459 - if (!access_ok(VERIFY_READ, frame, sizeof(*frame))) 460 - goto badframe; 461 - if (__get_user(set.sig[0], &frame->sc.sc_mask) || 462 - (_NSIG_WORDS > 1 && 463 - __copy_from_user(&set.sig[1], &frame->extramask, 464 - sizeof(frame->extramask)))) 465 - goto badframe; 466 - 467 - sigdelsetmask(&set, ~_BLOCKABLE); 468 - current->blocked = set; 469 - recalc_sigpending(); 470 - 471 - if (restore_sigcontext(regs, &frame->sc, frame + 1)) 472 - goto badframe; 473 - return regs->d0; 474 - 475 - badframe: 476 - force_sig(SIGSEGV, current); 477 - return 0; 478 - } 479 - 480 - asmlinkage int do_rt_sigreturn(unsigned long __unused) 481 - { 482 - struct switch_stack *sw = (struct switch_stack *) &__unused; 483 - struct pt_regs *regs = (struct pt_regs *) (sw + 1); 484 - unsigned long usp = rdusp(); 485 - struct rt_sigframe __user *frame = (struct rt_sigframe __user *)(usp - 4); 486 - sigset_t set; 487 - 488 - if (!access_ok(VERIFY_READ, frame, sizeof(*frame))) 489 - goto badframe; 490 - if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set))) 491 - goto badframe; 492 - 493 - sigdelsetmask(&set, ~_BLOCKABLE); 494 - current->blocked = set; 495 - recalc_sigpending(); 496 - 497 - if (rt_restore_ucontext(regs, sw, &frame->uc)) 498 - goto badframe; 499 - return regs->d0; 500 - 501 - badframe: 502 - force_sig(SIGSEGV, current); 503 - return 0; 504 - } 505 - 506 - /* 507 - * Set up a signal frame. 508 - */ 509 - 510 - static inline void save_fpu_state(struct sigcontext *sc, struct pt_regs *regs) 511 - { 512 - if (FPU_IS_EMU) { 513 - /* save registers */ 514 - memcpy(sc->sc_fpcntl, current->thread.fpcntl, 12); 515 - memcpy(sc->sc_fpregs, current->thread.fp, 24); 516 - return; 517 - } 518 - 519 - __asm__ volatile (".chip 68k/68881\n\t" 520 - "fsave %0\n\t" 521 - ".chip 68k" 522 - : : "m" (*sc->sc_fpstate) : "memory"); 523 - 524 - if (CPU_IS_060 ? sc->sc_fpstate[2] : sc->sc_fpstate[0]) { 525 - fpu_version = sc->sc_fpstate[0]; 526 - if (CPU_IS_020_OR_030 && 527 - regs->vector >= (VEC_FPBRUC * 4) && 528 - regs->vector <= (VEC_FPNAN * 4)) { 529 - /* Clear pending exception in 68882 idle frame */ 530 - if (*(unsigned short *) sc->sc_fpstate == 0x1f38) 531 - sc->sc_fpstate[0x38] |= 1 << 3; 532 - } 533 - __asm__ volatile (".chip 68k/68881\n\t" 534 - "fmovemx %%fp0-%%fp1,%0\n\t" 535 - "fmoveml %%fpcr/%%fpsr/%%fpiar,%1\n\t" 536 - ".chip 68k" 537 - : "=m" (*sc->sc_fpregs), 538 - "=m" (*sc->sc_fpcntl) 539 - : /* no inputs */ 540 - : "memory"); 541 - } 542 - } 543 - 544 - static inline int rt_save_fpu_state(struct ucontext __user *uc, struct pt_regs *regs) 545 - { 546 - unsigned char fpstate[FPCONTEXT_SIZE]; 547 - int context_size = CPU_IS_060 ? 8 : 0; 548 - int err = 0; 549 - 550 - if (FPU_IS_EMU) { 551 - /* save fpu control register */ 552 - err |= copy_to_user(uc->uc_mcontext.fpregs.f_fpcntl, 553 - current->thread.fpcntl, 12); 554 - /* save all other fpu register */ 555 - err |= copy_to_user(uc->uc_mcontext.fpregs.f_fpregs, 556 - current->thread.fp, 96); 557 - return err; 558 - } 559 - 560 - __asm__ volatile (".chip 68k/68881\n\t" 561 - "fsave %0\n\t" 562 - ".chip 68k" 563 - : : "m" (*fpstate) : "memory"); 564 - 565 - err |= __put_user(*(long *)fpstate, (long __user *)&uc->uc_fpstate); 566 - if (CPU_IS_060 ? fpstate[2] : fpstate[0]) { 567 - fpregset_t fpregs; 568 - if (!CPU_IS_060) 569 - context_size = fpstate[1]; 570 - fpu_version = fpstate[0]; 571 - if (CPU_IS_020_OR_030 && 572 - regs->vector >= (VEC_FPBRUC * 4) && 573 - regs->vector <= (VEC_FPNAN * 4)) { 574 - /* Clear pending exception in 68882 idle frame */ 575 - if (*(unsigned short *) fpstate == 0x1f38) 576 - fpstate[0x38] |= 1 << 3; 577 - } 578 - __asm__ volatile (".chip 68k/68881\n\t" 579 - "fmovemx %%fp0-%%fp7,%0\n\t" 580 - "fmoveml %%fpcr/%%fpsr/%%fpiar,%1\n\t" 581 - ".chip 68k" 582 - : "=m" (*fpregs.f_fpregs), 583 - "=m" (*fpregs.f_fpcntl) 584 - : /* no inputs */ 585 - : "memory"); 586 - err |= copy_to_user(&uc->uc_mcontext.fpregs, &fpregs, 587 - sizeof(fpregs)); 588 - } 589 - if (context_size) 590 - err |= copy_to_user((long __user *)&uc->uc_fpstate + 1, fpstate + 4, 591 - context_size); 592 - return err; 593 - } 594 - 595 - static void setup_sigcontext(struct sigcontext *sc, struct pt_regs *regs, 596 - unsigned long mask) 597 - { 598 - sc->sc_mask = mask; 599 - sc->sc_usp = rdusp(); 600 - sc->sc_d0 = regs->d0; 601 - sc->sc_d1 = regs->d1; 602 - sc->sc_a0 = regs->a0; 603 - sc->sc_a1 = regs->a1; 604 - sc->sc_sr = regs->sr; 605 - sc->sc_pc = regs->pc; 606 - sc->sc_formatvec = regs->format << 12 | regs->vector; 607 - save_fpu_state(sc, regs); 608 - } 609 - 610 - static inline int rt_setup_ucontext(struct ucontext __user *uc, struct pt_regs *regs) 611 - { 612 - struct switch_stack *sw = (struct switch_stack *)regs - 1; 613 - greg_t __user *gregs = uc->uc_mcontext.gregs; 614 - int err = 0; 615 - 616 - err |= __put_user(MCONTEXT_VERSION, &uc->uc_mcontext.version); 617 - err |= __put_user(regs->d0, &gregs[0]); 618 - err |= __put_user(regs->d1, &gregs[1]); 619 - err |= __put_user(regs->d2, &gregs[2]); 620 - err |= __put_user(regs->d3, &gregs[3]); 621 - err |= __put_user(regs->d4, &gregs[4]); 622 - err |= __put_user(regs->d5, &gregs[5]); 623 - err |= __put_user(sw->d6, &gregs[6]); 624 - err |= __put_user(sw->d7, &gregs[7]); 625 - err |= __put_user(regs->a0, &gregs[8]); 626 - err |= __put_user(regs->a1, &gregs[9]); 627 - err |= __put_user(regs->a2, &gregs[10]); 628 - err |= __put_user(sw->a3, &gregs[11]); 629 - err |= __put_user(sw->a4, &gregs[12]); 630 - err |= __put_user(sw->a5, &gregs[13]); 631 - err |= __put_user(sw->a6, &gregs[14]); 632 - err |= __put_user(rdusp(), &gregs[15]); 633 - err |= __put_user(regs->pc, &gregs[16]); 634 - err |= __put_user(regs->sr, &gregs[17]); 635 - err |= __put_user((regs->format << 12) | regs->vector, &uc->uc_formatvec); 636 - err |= rt_save_fpu_state(uc, regs); 637 - return err; 638 - } 639 - 640 - static inline void push_cache (unsigned long vaddr) 641 - { 642 - /* 643 - * Using the old cache_push_v() was really a big waste. 644 - * 645 - * What we are trying to do is to flush 8 bytes to ram. 646 - * Flushing 2 cache lines of 16 bytes is much cheaper than 647 - * flushing 1 or 2 pages, as previously done in 648 - * cache_push_v(). 649 - * Jes 650 - */ 651 - if (CPU_IS_040) { 652 - unsigned long temp; 653 - 654 - __asm__ __volatile__ (".chip 68040\n\t" 655 - "nop\n\t" 656 - "ptestr (%1)\n\t" 657 - "movec %%mmusr,%0\n\t" 658 - ".chip 68k" 659 - : "=r" (temp) 660 - : "a" (vaddr)); 661 - 662 - temp &= PAGE_MASK; 663 - temp |= vaddr & ~PAGE_MASK; 664 - 665 - __asm__ __volatile__ (".chip 68040\n\t" 666 - "nop\n\t" 667 - "cpushl %%bc,(%0)\n\t" 668 - ".chip 68k" 669 - : : "a" (temp)); 670 - } 671 - else if (CPU_IS_060) { 672 - unsigned long temp; 673 - __asm__ __volatile__ (".chip 68060\n\t" 674 - "plpar (%0)\n\t" 675 - ".chip 68k" 676 - : "=a" (temp) 677 - : "0" (vaddr)); 678 - __asm__ __volatile__ (".chip 68060\n\t" 679 - "cpushl %%bc,(%0)\n\t" 680 - ".chip 68k" 681 - : : "a" (temp)); 682 - } 683 - else { 684 - /* 685 - * 68030/68020 have no writeback cache; 686 - * still need to clear icache. 687 - * Note that vaddr is guaranteed to be long word aligned. 688 - */ 689 - unsigned long temp; 690 - asm volatile ("movec %%cacr,%0" : "=r" (temp)); 691 - temp += 4; 692 - asm volatile ("movec %0,%%caar\n\t" 693 - "movec %1,%%cacr" 694 - : : "r" (vaddr), "r" (temp)); 695 - asm volatile ("movec %0,%%caar\n\t" 696 - "movec %1,%%cacr" 697 - : : "r" (vaddr + 4), "r" (temp)); 698 - } 699 - } 700 - 701 - static inline void __user * 702 - get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size) 703 - { 704 - unsigned long usp; 705 - 706 - /* Default to using normal stack. */ 707 - usp = rdusp(); 708 - 709 - /* This is the X/Open sanctioned signal stack switching. */ 710 - if (ka->sa.sa_flags & SA_ONSTACK) { 711 - if (!sas_ss_flags(usp)) 712 - usp = current->sas_ss_sp + current->sas_ss_size; 713 - } 714 - return (void __user *)((usp - frame_size) & -8UL); 715 - } 716 - 717 - static int setup_frame (int sig, struct k_sigaction *ka, 718 - sigset_t *set, struct pt_regs *regs) 719 - { 720 - struct sigframe __user *frame; 721 - int fsize = frame_extra_sizes[regs->format]; 722 - struct sigcontext context; 723 - int err = 0; 724 - 725 - if (fsize < 0) { 726 - #ifdef DEBUG 727 - printk ("setup_frame: Unknown frame format %#x\n", 728 - regs->format); 729 - #endif 730 - goto give_sigsegv; 731 - } 732 - 733 - frame = get_sigframe(ka, regs, sizeof(*frame) + fsize); 734 - 735 - if (fsize) 736 - err |= copy_to_user (frame + 1, regs + 1, fsize); 737 - 738 - err |= __put_user((current_thread_info()->exec_domain 739 - && current_thread_info()->exec_domain->signal_invmap 740 - && sig < 32 741 - ? current_thread_info()->exec_domain->signal_invmap[sig] 742 - : sig), 743 - &frame->sig); 744 - 745 - err |= __put_user(regs->vector, &frame->code); 746 - err |= __put_user(&frame->sc, &frame->psc); 747 - 748 - if (_NSIG_WORDS > 1) 749 - err |= copy_to_user(frame->extramask, &set->sig[1], 750 - sizeof(frame->extramask)); 751 - 752 - setup_sigcontext(&context, regs, set->sig[0]); 753 - err |= copy_to_user (&frame->sc, &context, sizeof(context)); 754 - 755 - /* Set up to return from userspace. */ 756 - err |= __put_user(frame->retcode, &frame->pretcode); 757 - /* moveq #,d0; trap #0 */ 758 - err |= __put_user(0x70004e40 + (__NR_sigreturn << 16), 759 - (long __user *)(frame->retcode)); 760 - 761 - if (err) 762 - goto give_sigsegv; 763 - 764 - push_cache ((unsigned long) &frame->retcode); 765 - 766 - /* 767 - * Set up registers for signal handler. All the state we are about 768 - * to destroy is successfully copied to sigframe. 769 - */ 770 - wrusp ((unsigned long) frame); 771 - regs->pc = (unsigned long) ka->sa.sa_handler; 772 - 773 - /* 774 - * This is subtle; if we build more than one sigframe, all but the 775 - * first one will see frame format 0 and have fsize == 0, so we won't 776 - * screw stkadj. 777 - */ 778 - if (fsize) 779 - regs->stkadj = fsize; 780 - 781 - /* Prepare to skip over the extra stuff in the exception frame. */ 782 - if (regs->stkadj) { 783 - struct pt_regs *tregs = 784 - (struct pt_regs *)((ulong)regs + regs->stkadj); 785 - #ifdef DEBUG 786 - printk("Performing stackadjust=%04x\n", regs->stkadj); 787 - #endif 788 - /* This must be copied with decreasing addresses to 789 - handle overlaps. */ 790 - tregs->vector = 0; 791 - tregs->format = 0; 792 - tregs->pc = regs->pc; 793 - tregs->sr = regs->sr; 794 - } 795 - return 0; 796 - 797 - give_sigsegv: 798 - force_sigsegv(sig, current); 799 - return err; 800 - } 801 - 802 - static int setup_rt_frame (int sig, struct k_sigaction *ka, siginfo_t *info, 803 - sigset_t *set, struct pt_regs *regs) 804 - { 805 - struct rt_sigframe __user *frame; 806 - int fsize = frame_extra_sizes[regs->format]; 807 - int err = 0; 808 - 809 - if (fsize < 0) { 810 - #ifdef DEBUG 811 - printk ("setup_frame: Unknown frame format %#x\n", 812 - regs->format); 813 - #endif 814 - goto give_sigsegv; 815 - } 816 - 817 - frame = get_sigframe(ka, regs, sizeof(*frame)); 818 - 819 - if (fsize) 820 - err |= copy_to_user (&frame->uc.uc_extra, regs + 1, fsize); 821 - 822 - err |= __put_user((current_thread_info()->exec_domain 823 - && current_thread_info()->exec_domain->signal_invmap 824 - && sig < 32 825 - ? current_thread_info()->exec_domain->signal_invmap[sig] 826 - : sig), 827 - &frame->sig); 828 - err |= __put_user(&frame->info, &frame->pinfo); 829 - err |= __put_user(&frame->uc, &frame->puc); 830 - err |= copy_siginfo_to_user(&frame->info, info); 831 - 832 - /* Create the ucontext. */ 833 - err |= __put_user(0, &frame->uc.uc_flags); 834 - err |= __put_user(NULL, &frame->uc.uc_link); 835 - err |= __put_user((void __user *)current->sas_ss_sp, 836 - &frame->uc.uc_stack.ss_sp); 837 - err |= __put_user(sas_ss_flags(rdusp()), 838 - &frame->uc.uc_stack.ss_flags); 839 - err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size); 840 - err |= rt_setup_ucontext(&frame->uc, regs); 841 - err |= copy_to_user (&frame->uc.uc_sigmask, set, sizeof(*set)); 842 - 843 - /* Set up to return from userspace. */ 844 - err |= __put_user(frame->retcode, &frame->pretcode); 845 - #ifdef __mcoldfire__ 846 - /* movel #__NR_rt_sigreturn,d0; trap #0 */ 847 - err |= __put_user(0x203c0000, (long __user *)(frame->retcode + 0)); 848 - err |= __put_user(0x00004e40 + (__NR_rt_sigreturn << 16), 849 - (long __user *)(frame->retcode + 4)); 850 #else 851 - /* moveq #,d0; notb d0; trap #0 */ 852 - err |= __put_user(0x70004600 + ((__NR_rt_sigreturn ^ 0xff) << 16), 853 - (long __user *)(frame->retcode + 0)); 854 - err |= __put_user(0x4e40, (short __user *)(frame->retcode + 4)); 855 #endif 856 - 857 - if (err) 858 - goto give_sigsegv; 859 - 860 - push_cache ((unsigned long) &frame->retcode); 861 - 862 - /* 863 - * Set up registers for signal handler. All the state we are about 864 - * to destroy is successfully copied to sigframe. 865 - */ 866 - wrusp ((unsigned long) frame); 867 - regs->pc = (unsigned long) ka->sa.sa_handler; 868 - 869 - /* 870 - * This is subtle; if we build more than one sigframe, all but the 871 - * first one will see frame format 0 and have fsize == 0, so we won't 872 - * screw stkadj. 873 - */ 874 - if (fsize) 875 - regs->stkadj = fsize; 876 - 877 - /* Prepare to skip over the extra stuff in the exception frame. */ 878 - if (regs->stkadj) { 879 - struct pt_regs *tregs = 880 - (struct pt_regs *)((ulong)regs + regs->stkadj); 881 - #ifdef DEBUG 882 - printk("Performing stackadjust=%04x\n", regs->stkadj); 883 - #endif 884 - /* This must be copied with decreasing addresses to 885 - handle overlaps. */ 886 - tregs->vector = 0; 887 - tregs->format = 0; 888 - tregs->pc = regs->pc; 889 - tregs->sr = regs->sr; 890 - } 891 - return 0; 892 - 893 - give_sigsegv: 894 - force_sigsegv(sig, current); 895 - return err; 896 - } 897 - 898 - static inline void 899 - handle_restart(struct pt_regs *regs, struct k_sigaction *ka, int has_handler) 900 - { 901 - switch (regs->d0) { 902 - case -ERESTARTNOHAND: 903 - if (!has_handler) 904 - goto do_restart; 905 - regs->d0 = -EINTR; 906 - break; 907 - 908 - case -ERESTART_RESTARTBLOCK: 909 - if (!has_handler) { 910 - regs->d0 = __NR_restart_syscall; 911 - regs->pc -= 2; 912 - break; 913 - } 914 - regs->d0 = -EINTR; 915 - break; 916 - 917 - case -ERESTARTSYS: 918 - if (has_handler && !(ka->sa.sa_flags & SA_RESTART)) { 919 - regs->d0 = -EINTR; 920 - break; 921 - } 922 - /* fallthrough */ 923 - case -ERESTARTNOINTR: 924 - do_restart: 925 - regs->d0 = regs->orig_d0; 926 - regs->pc -= 2; 927 - break; 928 - } 929 - } 930 - 931 - void ptrace_signal_deliver(struct pt_regs *regs, void *cookie) 932 - { 933 - if (regs->orig_d0 < 0) 934 - return; 935 - switch (regs->d0) { 936 - case -ERESTARTNOHAND: 937 - case -ERESTARTSYS: 938 - case -ERESTARTNOINTR: 939 - regs->d0 = regs->orig_d0; 940 - regs->orig_d0 = -1; 941 - regs->pc -= 2; 942 - break; 943 - } 944 - } 945 - 946 - /* 947 - * OK, we're invoking a handler 948 - */ 949 - static void 950 - handle_signal(int sig, struct k_sigaction *ka, siginfo_t *info, 951 - sigset_t *oldset, struct pt_regs *regs) 952 - { 953 - int err; 954 - /* are we from a system call? */ 955 - if (regs->orig_d0 >= 0) 956 - /* If so, check system call restarting.. */ 957 - handle_restart(regs, ka, 1); 958 - 959 - /* set up the stack frame */ 960 - if (ka->sa.sa_flags & SA_SIGINFO) 961 - err = setup_rt_frame(sig, ka, info, oldset, regs); 962 - else 963 - err = setup_frame(sig, ka, oldset, regs); 964 - 965 - if (err) 966 - return; 967 - 968 - sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask); 969 - if (!(ka->sa.sa_flags & SA_NODEFER)) 970 - sigaddset(&current->blocked,sig); 971 - recalc_sigpending(); 972 - 973 - if (test_thread_flag(TIF_DELAYED_TRACE)) { 974 - regs->sr &= ~0x8000; 975 - send_sig(SIGTRAP, current, 1); 976 - } 977 - 978 - clear_thread_flag(TIF_RESTORE_SIGMASK); 979 - } 980 - 981 - /* 982 - * Note that 'init' is a special process: it doesn't get signals it doesn't 983 - * want to handle. Thus you cannot kill init even with a SIGKILL even by 984 - * mistake. 985 - */ 986 - asmlinkage void do_signal(struct pt_regs *regs) 987 - { 988 - siginfo_t info; 989 - struct k_sigaction ka; 990 - int signr; 991 - sigset_t *oldset; 992 - 993 - current->thread.esp0 = (unsigned long) regs; 994 - 995 - if (test_thread_flag(TIF_RESTORE_SIGMASK)) 996 - oldset = &current->saved_sigmask; 997 - else 998 - oldset = &current->blocked; 999 - 1000 - signr = get_signal_to_deliver(&info, &ka, regs, NULL); 1001 - if (signr > 0) { 1002 - /* Whee! Actually deliver the signal. */ 1003 - handle_signal(signr, &ka, &info, oldset, regs); 1004 - return; 1005 - } 1006 - 1007 - /* Did we come from a system call? */ 1008 - if (regs->orig_d0 >= 0) 1009 - /* Restart the system call - no handlers present */ 1010 - handle_restart(regs, NULL, 0); 1011 - 1012 - /* If there's no signal to deliver, we just restore the saved mask. */ 1013 - if (test_thread_flag(TIF_RESTORE_SIGMASK)) { 1014 - clear_thread_flag(TIF_RESTORE_SIGMASK); 1015 - sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL); 1016 - } 1017 - }
··· 1 + #ifdef CONFIG_MMU 2 + #include "signal_mm.c" 3 #else 4 + #include "signal_no.c" 5 #endif
+1017
arch/m68k/kernel/signal_mm.c
···
··· 1 + /* 2 + * linux/arch/m68k/kernel/signal.c 3 + * 4 + * Copyright (C) 1991, 1992 Linus Torvalds 5 + * 6 + * This file is subject to the terms and conditions of the GNU General Public 7 + * License. See the file COPYING in the main directory of this archive 8 + * for more details. 9 + */ 10 + 11 + /* 12 + * Linux/m68k support by Hamish Macdonald 13 + * 14 + * 68060 fixes by Jesper Skov 15 + * 16 + * 1997-12-01 Modified for POSIX.1b signals by Andreas Schwab 17 + * 18 + * mathemu support by Roman Zippel 19 + * (Note: fpstate in the signal context is completely ignored for the emulator 20 + * and the internal floating point format is put on stack) 21 + */ 22 + 23 + /* 24 + * ++roman (07/09/96): implemented signal stacks (specially for tosemu on 25 + * Atari :-) Current limitation: Only one sigstack can be active at one time. 26 + * If a second signal with SA_ONSTACK set arrives while working on a sigstack, 27 + * SA_ONSTACK is ignored. This behaviour avoids lots of trouble with nested 28 + * signal handlers! 29 + */ 30 + 31 + #include <linux/sched.h> 32 + #include <linux/mm.h> 33 + #include <linux/kernel.h> 34 + #include <linux/signal.h> 35 + #include <linux/syscalls.h> 36 + #include <linux/errno.h> 37 + #include <linux/wait.h> 38 + #include <linux/ptrace.h> 39 + #include <linux/unistd.h> 40 + #include <linux/stddef.h> 41 + #include <linux/highuid.h> 42 + #include <linux/personality.h> 43 + #include <linux/tty.h> 44 + #include <linux/binfmts.h> 45 + #include <linux/module.h> 46 + 47 + #include <asm/setup.h> 48 + #include <asm/uaccess.h> 49 + #include <asm/pgtable.h> 50 + #include <asm/traps.h> 51 + #include <asm/ucontext.h> 52 + 53 + #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) 54 + 55 + static const int frame_extra_sizes[16] = { 56 + [1] = -1, /* sizeof(((struct frame *)0)->un.fmt1), */ 57 + [2] = sizeof(((struct frame *)0)->un.fmt2), 58 + [3] = sizeof(((struct frame *)0)->un.fmt3), 59 + [4] = sizeof(((struct frame *)0)->un.fmt4), 60 + [5] = -1, /* sizeof(((struct frame *)0)->un.fmt5), */ 61 + [6] = -1, /* sizeof(((struct frame *)0)->un.fmt6), */ 62 + [7] = sizeof(((struct frame *)0)->un.fmt7), 63 + [8] = -1, /* sizeof(((struct frame *)0)->un.fmt8), */ 64 + [9] = sizeof(((struct frame *)0)->un.fmt9), 65 + [10] = sizeof(((struct frame *)0)->un.fmta), 66 + [11] = sizeof(((struct frame *)0)->un.fmtb), 67 + [12] = -1, /* sizeof(((struct frame *)0)->un.fmtc), */ 68 + [13] = -1, /* sizeof(((struct frame *)0)->un.fmtd), */ 69 + [14] = -1, /* sizeof(((struct frame *)0)->un.fmte), */ 70 + [15] = -1, /* sizeof(((struct frame *)0)->un.fmtf), */ 71 + }; 72 + 73 + int handle_kernel_fault(struct pt_regs *regs) 74 + { 75 + const struct exception_table_entry *fixup; 76 + struct pt_regs *tregs; 77 + 78 + /* Are we prepared to handle this kernel fault? */ 79 + fixup = search_exception_tables(regs->pc); 80 + if (!fixup) 81 + return 0; 82 + 83 + /* Create a new four word stack frame, discarding the old one. */ 84 + regs->stkadj = frame_extra_sizes[regs->format]; 85 + tregs = (struct pt_regs *)((long)regs + regs->stkadj); 86 + tregs->vector = regs->vector; 87 + tregs->format = 0; 88 + tregs->pc = fixup->fixup; 89 + tregs->sr = regs->sr; 90 + 91 + return 1; 92 + } 93 + 94 + /* 95 + * Atomically swap in the new signal mask, and wait for a signal. 96 + */ 97 + asmlinkage int 98 + sys_sigsuspend(int unused0, int unused1, old_sigset_t mask) 99 + { 100 + mask &= _BLOCKABLE; 101 + spin_lock_irq(&current->sighand->siglock); 102 + current->saved_sigmask = current->blocked; 103 + siginitset(&current->blocked, mask); 104 + recalc_sigpending(); 105 + spin_unlock_irq(&current->sighand->siglock); 106 + 107 + current->state = TASK_INTERRUPTIBLE; 108 + schedule(); 109 + set_restore_sigmask(); 110 + 111 + return -ERESTARTNOHAND; 112 + } 113 + 114 + asmlinkage int 115 + sys_sigaction(int sig, const struct old_sigaction __user *act, 116 + struct old_sigaction __user *oact) 117 + { 118 + struct k_sigaction new_ka, old_ka; 119 + int ret; 120 + 121 + if (act) { 122 + old_sigset_t mask; 123 + if (!access_ok(VERIFY_READ, act, sizeof(*act)) || 124 + __get_user(new_ka.sa.sa_handler, &act->sa_handler) || 125 + __get_user(new_ka.sa.sa_restorer, &act->sa_restorer) || 126 + __get_user(new_ka.sa.sa_flags, &act->sa_flags) || 127 + __get_user(mask, &act->sa_mask)) 128 + return -EFAULT; 129 + siginitset(&new_ka.sa.sa_mask, mask); 130 + } 131 + 132 + ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL); 133 + 134 + if (!ret && oact) { 135 + if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)) || 136 + __put_user(old_ka.sa.sa_handler, &oact->sa_handler) || 137 + __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer) || 138 + __put_user(old_ka.sa.sa_flags, &oact->sa_flags) || 139 + __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask)) 140 + return -EFAULT; 141 + } 142 + 143 + return ret; 144 + } 145 + 146 + asmlinkage int 147 + sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss) 148 + { 149 + return do_sigaltstack(uss, uoss, rdusp()); 150 + } 151 + 152 + 153 + /* 154 + * Do a signal return; undo the signal stack. 155 + * 156 + * Keep the return code on the stack quadword aligned! 157 + * That makes the cache flush below easier. 158 + */ 159 + 160 + struct sigframe 161 + { 162 + char __user *pretcode; 163 + int sig; 164 + int code; 165 + struct sigcontext __user *psc; 166 + char retcode[8]; 167 + unsigned long extramask[_NSIG_WORDS-1]; 168 + struct sigcontext sc; 169 + }; 170 + 171 + struct rt_sigframe 172 + { 173 + char __user *pretcode; 174 + int sig; 175 + struct siginfo __user *pinfo; 176 + void __user *puc; 177 + char retcode[8]; 178 + struct siginfo info; 179 + struct ucontext uc; 180 + }; 181 + 182 + 183 + static unsigned char fpu_version; /* version number of fpu, set by setup_frame */ 184 + 185 + static inline int restore_fpu_state(struct sigcontext *sc) 186 + { 187 + int err = 1; 188 + 189 + if (FPU_IS_EMU) { 190 + /* restore registers */ 191 + memcpy(current->thread.fpcntl, sc->sc_fpcntl, 12); 192 + memcpy(current->thread.fp, sc->sc_fpregs, 24); 193 + return 0; 194 + } 195 + 196 + if (CPU_IS_060 ? sc->sc_fpstate[2] : sc->sc_fpstate[0]) { 197 + /* Verify the frame format. */ 198 + if (!CPU_IS_060 && (sc->sc_fpstate[0] != fpu_version)) 199 + goto out; 200 + if (CPU_IS_020_OR_030) { 201 + if (m68k_fputype & FPU_68881 && 202 + !(sc->sc_fpstate[1] == 0x18 || sc->sc_fpstate[1] == 0xb4)) 203 + goto out; 204 + if (m68k_fputype & FPU_68882 && 205 + !(sc->sc_fpstate[1] == 0x38 || sc->sc_fpstate[1] == 0xd4)) 206 + goto out; 207 + } else if (CPU_IS_040) { 208 + if (!(sc->sc_fpstate[1] == 0x00 || 209 + sc->sc_fpstate[1] == 0x28 || 210 + sc->sc_fpstate[1] == 0x60)) 211 + goto out; 212 + } else if (CPU_IS_060) { 213 + if (!(sc->sc_fpstate[3] == 0x00 || 214 + sc->sc_fpstate[3] == 0x60 || 215 + sc->sc_fpstate[3] == 0xe0)) 216 + goto out; 217 + } else 218 + goto out; 219 + 220 + __asm__ volatile (".chip 68k/68881\n\t" 221 + "fmovemx %0,%%fp0-%%fp1\n\t" 222 + "fmoveml %1,%%fpcr/%%fpsr/%%fpiar\n\t" 223 + ".chip 68k" 224 + : /* no outputs */ 225 + : "m" (*sc->sc_fpregs), "m" (*sc->sc_fpcntl)); 226 + } 227 + __asm__ volatile (".chip 68k/68881\n\t" 228 + "frestore %0\n\t" 229 + ".chip 68k" : : "m" (*sc->sc_fpstate)); 230 + err = 0; 231 + 232 + out: 233 + return err; 234 + } 235 + 236 + #define FPCONTEXT_SIZE 216 237 + #define uc_fpstate uc_filler[0] 238 + #define uc_formatvec uc_filler[FPCONTEXT_SIZE/4] 239 + #define uc_extra uc_filler[FPCONTEXT_SIZE/4+1] 240 + 241 + static inline int rt_restore_fpu_state(struct ucontext __user *uc) 242 + { 243 + unsigned char fpstate[FPCONTEXT_SIZE]; 244 + int context_size = CPU_IS_060 ? 8 : 0; 245 + fpregset_t fpregs; 246 + int err = 1; 247 + 248 + if (FPU_IS_EMU) { 249 + /* restore fpu control register */ 250 + if (__copy_from_user(current->thread.fpcntl, 251 + uc->uc_mcontext.fpregs.f_fpcntl, 12)) 252 + goto out; 253 + /* restore all other fpu register */ 254 + if (__copy_from_user(current->thread.fp, 255 + uc->uc_mcontext.fpregs.f_fpregs, 96)) 256 + goto out; 257 + return 0; 258 + } 259 + 260 + if (__get_user(*(long *)fpstate, (long __user *)&uc->uc_fpstate)) 261 + goto out; 262 + if (CPU_IS_060 ? fpstate[2] : fpstate[0]) { 263 + if (!CPU_IS_060) 264 + context_size = fpstate[1]; 265 + /* Verify the frame format. */ 266 + if (!CPU_IS_060 && (fpstate[0] != fpu_version)) 267 + goto out; 268 + if (CPU_IS_020_OR_030) { 269 + if (m68k_fputype & FPU_68881 && 270 + !(context_size == 0x18 || context_size == 0xb4)) 271 + goto out; 272 + if (m68k_fputype & FPU_68882 && 273 + !(context_size == 0x38 || context_size == 0xd4)) 274 + goto out; 275 + } else if (CPU_IS_040) { 276 + if (!(context_size == 0x00 || 277 + context_size == 0x28 || 278 + context_size == 0x60)) 279 + goto out; 280 + } else if (CPU_IS_060) { 281 + if (!(fpstate[3] == 0x00 || 282 + fpstate[3] == 0x60 || 283 + fpstate[3] == 0xe0)) 284 + goto out; 285 + } else 286 + goto out; 287 + if (__copy_from_user(&fpregs, &uc->uc_mcontext.fpregs, 288 + sizeof(fpregs))) 289 + goto out; 290 + __asm__ volatile (".chip 68k/68881\n\t" 291 + "fmovemx %0,%%fp0-%%fp7\n\t" 292 + "fmoveml %1,%%fpcr/%%fpsr/%%fpiar\n\t" 293 + ".chip 68k" 294 + : /* no outputs */ 295 + : "m" (*fpregs.f_fpregs), 296 + "m" (*fpregs.f_fpcntl)); 297 + } 298 + if (context_size && 299 + __copy_from_user(fpstate + 4, (long __user *)&uc->uc_fpstate + 1, 300 + context_size)) 301 + goto out; 302 + __asm__ volatile (".chip 68k/68881\n\t" 303 + "frestore %0\n\t" 304 + ".chip 68k" : : "m" (*fpstate)); 305 + err = 0; 306 + 307 + out: 308 + return err; 309 + } 310 + 311 + static int mangle_kernel_stack(struct pt_regs *regs, int formatvec, 312 + void __user *fp) 313 + { 314 + int fsize = frame_extra_sizes[formatvec >> 12]; 315 + if (fsize < 0) { 316 + /* 317 + * user process trying to return with weird frame format 318 + */ 319 + #ifdef DEBUG 320 + printk("user process returning with weird frame format\n"); 321 + #endif 322 + return 1; 323 + } 324 + if (!fsize) { 325 + regs->format = formatvec >> 12; 326 + regs->vector = formatvec & 0xfff; 327 + } else { 328 + struct switch_stack *sw = (struct switch_stack *)regs - 1; 329 + unsigned long buf[fsize / 2]; /* yes, twice as much */ 330 + 331 + /* that'll make sure that expansion won't crap over data */ 332 + if (copy_from_user(buf + fsize / 4, fp, fsize)) 333 + return 1; 334 + 335 + /* point of no return */ 336 + regs->format = formatvec >> 12; 337 + regs->vector = formatvec & 0xfff; 338 + #define frame_offset (sizeof(struct pt_regs)+sizeof(struct switch_stack)) 339 + __asm__ __volatile__ 340 + (" movel %0,%/a0\n\t" 341 + " subl %1,%/a0\n\t" /* make room on stack */ 342 + " movel %/a0,%/sp\n\t" /* set stack pointer */ 343 + /* move switch_stack and pt_regs */ 344 + "1: movel %0@+,%/a0@+\n\t" 345 + " dbra %2,1b\n\t" 346 + " lea %/sp@(%c3),%/a0\n\t" /* add offset of fmt */ 347 + " lsrl #2,%1\n\t" 348 + " subql #1,%1\n\t" 349 + /* copy to the gap we'd made */ 350 + "2: movel %4@+,%/a0@+\n\t" 351 + " dbra %1,2b\n\t" 352 + " bral ret_from_signal\n" 353 + : /* no outputs, it doesn't ever return */ 354 + : "a" (sw), "d" (fsize), "d" (frame_offset/4-1), 355 + "n" (frame_offset), "a" (buf + fsize/4) 356 + : "a0"); 357 + #undef frame_offset 358 + } 359 + return 0; 360 + } 361 + 362 + static inline int 363 + restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *usc, void __user *fp) 364 + { 365 + int formatvec; 366 + struct sigcontext context; 367 + int err; 368 + 369 + /* Always make any pending restarted system calls return -EINTR */ 370 + current_thread_info()->restart_block.fn = do_no_restart_syscall; 371 + 372 + /* get previous context */ 373 + if (copy_from_user(&context, usc, sizeof(context))) 374 + goto badframe; 375 + 376 + /* restore passed registers */ 377 + regs->d0 = context.sc_d0; 378 + regs->d1 = context.sc_d1; 379 + regs->a0 = context.sc_a0; 380 + regs->a1 = context.sc_a1; 381 + regs->sr = (regs->sr & 0xff00) | (context.sc_sr & 0xff); 382 + regs->pc = context.sc_pc; 383 + regs->orig_d0 = -1; /* disable syscall checks */ 384 + wrusp(context.sc_usp); 385 + formatvec = context.sc_formatvec; 386 + 387 + err = restore_fpu_state(&context); 388 + 389 + if (err || mangle_kernel_stack(regs, formatvec, fp)) 390 + goto badframe; 391 + 392 + return 0; 393 + 394 + badframe: 395 + return 1; 396 + } 397 + 398 + static inline int 399 + rt_restore_ucontext(struct pt_regs *regs, struct switch_stack *sw, 400 + struct ucontext __user *uc) 401 + { 402 + int temp; 403 + greg_t __user *gregs = uc->uc_mcontext.gregs; 404 + unsigned long usp; 405 + int err; 406 + 407 + /* Always make any pending restarted system calls return -EINTR */ 408 + current_thread_info()->restart_block.fn = do_no_restart_syscall; 409 + 410 + err = __get_user(temp, &uc->uc_mcontext.version); 411 + if (temp != MCONTEXT_VERSION) 412 + goto badframe; 413 + /* restore passed registers */ 414 + err |= __get_user(regs->d0, &gregs[0]); 415 + err |= __get_user(regs->d1, &gregs[1]); 416 + err |= __get_user(regs->d2, &gregs[2]); 417 + err |= __get_user(regs->d3, &gregs[3]); 418 + err |= __get_user(regs->d4, &gregs[4]); 419 + err |= __get_user(regs->d5, &gregs[5]); 420 + err |= __get_user(sw->d6, &gregs[6]); 421 + err |= __get_user(sw->d7, &gregs[7]); 422 + err |= __get_user(regs->a0, &gregs[8]); 423 + err |= __get_user(regs->a1, &gregs[9]); 424 + err |= __get_user(regs->a2, &gregs[10]); 425 + err |= __get_user(sw->a3, &gregs[11]); 426 + err |= __get_user(sw->a4, &gregs[12]); 427 + err |= __get_user(sw->a5, &gregs[13]); 428 + err |= __get_user(sw->a6, &gregs[14]); 429 + err |= __get_user(usp, &gregs[15]); 430 + wrusp(usp); 431 + err |= __get_user(regs->pc, &gregs[16]); 432 + err |= __get_user(temp, &gregs[17]); 433 + regs->sr = (regs->sr & 0xff00) | (temp & 0xff); 434 + regs->orig_d0 = -1; /* disable syscall checks */ 435 + err |= __get_user(temp, &uc->uc_formatvec); 436 + 437 + err |= rt_restore_fpu_state(uc); 438 + 439 + if (err || do_sigaltstack(&uc->uc_stack, NULL, usp) == -EFAULT) 440 + goto badframe; 441 + 442 + if (mangle_kernel_stack(regs, temp, &uc->uc_extra)) 443 + goto badframe; 444 + 445 + return 0; 446 + 447 + badframe: 448 + return 1; 449 + } 450 + 451 + asmlinkage int do_sigreturn(unsigned long __unused) 452 + { 453 + struct switch_stack *sw = (struct switch_stack *) &__unused; 454 + struct pt_regs *regs = (struct pt_regs *) (sw + 1); 455 + unsigned long usp = rdusp(); 456 + struct sigframe __user *frame = (struct sigframe __user *)(usp - 4); 457 + sigset_t set; 458 + 459 + if (!access_ok(VERIFY_READ, frame, sizeof(*frame))) 460 + goto badframe; 461 + if (__get_user(set.sig[0], &frame->sc.sc_mask) || 462 + (_NSIG_WORDS > 1 && 463 + __copy_from_user(&set.sig[1], &frame->extramask, 464 + sizeof(frame->extramask)))) 465 + goto badframe; 466 + 467 + sigdelsetmask(&set, ~_BLOCKABLE); 468 + current->blocked = set; 469 + recalc_sigpending(); 470 + 471 + if (restore_sigcontext(regs, &frame->sc, frame + 1)) 472 + goto badframe; 473 + return regs->d0; 474 + 475 + badframe: 476 + force_sig(SIGSEGV, current); 477 + return 0; 478 + } 479 + 480 + asmlinkage int do_rt_sigreturn(unsigned long __unused) 481 + { 482 + struct switch_stack *sw = (struct switch_stack *) &__unused; 483 + struct pt_regs *regs = (struct pt_regs *) (sw + 1); 484 + unsigned long usp = rdusp(); 485 + struct rt_sigframe __user *frame = (struct rt_sigframe __user *)(usp - 4); 486 + sigset_t set; 487 + 488 + if (!access_ok(VERIFY_READ, frame, sizeof(*frame))) 489 + goto badframe; 490 + if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set))) 491 + goto badframe; 492 + 493 + sigdelsetmask(&set, ~_BLOCKABLE); 494 + current->blocked = set; 495 + recalc_sigpending(); 496 + 497 + if (rt_restore_ucontext(regs, sw, &frame->uc)) 498 + goto badframe; 499 + return regs->d0; 500 + 501 + badframe: 502 + force_sig(SIGSEGV, current); 503 + return 0; 504 + } 505 + 506 + /* 507 + * Set up a signal frame. 508 + */ 509 + 510 + static inline void save_fpu_state(struct sigcontext *sc, struct pt_regs *regs) 511 + { 512 + if (FPU_IS_EMU) { 513 + /* save registers */ 514 + memcpy(sc->sc_fpcntl, current->thread.fpcntl, 12); 515 + memcpy(sc->sc_fpregs, current->thread.fp, 24); 516 + return; 517 + } 518 + 519 + __asm__ volatile (".chip 68k/68881\n\t" 520 + "fsave %0\n\t" 521 + ".chip 68k" 522 + : : "m" (*sc->sc_fpstate) : "memory"); 523 + 524 + if (CPU_IS_060 ? sc->sc_fpstate[2] : sc->sc_fpstate[0]) { 525 + fpu_version = sc->sc_fpstate[0]; 526 + if (CPU_IS_020_OR_030 && 527 + regs->vector >= (VEC_FPBRUC * 4) && 528 + regs->vector <= (VEC_FPNAN * 4)) { 529 + /* Clear pending exception in 68882 idle frame */ 530 + if (*(unsigned short *) sc->sc_fpstate == 0x1f38) 531 + sc->sc_fpstate[0x38] |= 1 << 3; 532 + } 533 + __asm__ volatile (".chip 68k/68881\n\t" 534 + "fmovemx %%fp0-%%fp1,%0\n\t" 535 + "fmoveml %%fpcr/%%fpsr/%%fpiar,%1\n\t" 536 + ".chip 68k" 537 + : "=m" (*sc->sc_fpregs), 538 + "=m" (*sc->sc_fpcntl) 539 + : /* no inputs */ 540 + : "memory"); 541 + } 542 + } 543 + 544 + static inline int rt_save_fpu_state(struct ucontext __user *uc, struct pt_regs *regs) 545 + { 546 + unsigned char fpstate[FPCONTEXT_SIZE]; 547 + int context_size = CPU_IS_060 ? 8 : 0; 548 + int err = 0; 549 + 550 + if (FPU_IS_EMU) { 551 + /* save fpu control register */ 552 + err |= copy_to_user(uc->uc_mcontext.fpregs.f_fpcntl, 553 + current->thread.fpcntl, 12); 554 + /* save all other fpu register */ 555 + err |= copy_to_user(uc->uc_mcontext.fpregs.f_fpregs, 556 + current->thread.fp, 96); 557 + return err; 558 + } 559 + 560 + __asm__ volatile (".chip 68k/68881\n\t" 561 + "fsave %0\n\t" 562 + ".chip 68k" 563 + : : "m" (*fpstate) : "memory"); 564 + 565 + err |= __put_user(*(long *)fpstate, (long __user *)&uc->uc_fpstate); 566 + if (CPU_IS_060 ? fpstate[2] : fpstate[0]) { 567 + fpregset_t fpregs; 568 + if (!CPU_IS_060) 569 + context_size = fpstate[1]; 570 + fpu_version = fpstate[0]; 571 + if (CPU_IS_020_OR_030 && 572 + regs->vector >= (VEC_FPBRUC * 4) && 573 + regs->vector <= (VEC_FPNAN * 4)) { 574 + /* Clear pending exception in 68882 idle frame */ 575 + if (*(unsigned short *) fpstate == 0x1f38) 576 + fpstate[0x38] |= 1 << 3; 577 + } 578 + __asm__ volatile (".chip 68k/68881\n\t" 579 + "fmovemx %%fp0-%%fp7,%0\n\t" 580 + "fmoveml %%fpcr/%%fpsr/%%fpiar,%1\n\t" 581 + ".chip 68k" 582 + : "=m" (*fpregs.f_fpregs), 583 + "=m" (*fpregs.f_fpcntl) 584 + : /* no inputs */ 585 + : "memory"); 586 + err |= copy_to_user(&uc->uc_mcontext.fpregs, &fpregs, 587 + sizeof(fpregs)); 588 + } 589 + if (context_size) 590 + err |= copy_to_user((long __user *)&uc->uc_fpstate + 1, fpstate + 4, 591 + context_size); 592 + return err; 593 + } 594 + 595 + static void setup_sigcontext(struct sigcontext *sc, struct pt_regs *regs, 596 + unsigned long mask) 597 + { 598 + sc->sc_mask = mask; 599 + sc->sc_usp = rdusp(); 600 + sc->sc_d0 = regs->d0; 601 + sc->sc_d1 = regs->d1; 602 + sc->sc_a0 = regs->a0; 603 + sc->sc_a1 = regs->a1; 604 + sc->sc_sr = regs->sr; 605 + sc->sc_pc = regs->pc; 606 + sc->sc_formatvec = regs->format << 12 | regs->vector; 607 + save_fpu_state(sc, regs); 608 + } 609 + 610 + static inline int rt_setup_ucontext(struct ucontext __user *uc, struct pt_regs *regs) 611 + { 612 + struct switch_stack *sw = (struct switch_stack *)regs - 1; 613 + greg_t __user *gregs = uc->uc_mcontext.gregs; 614 + int err = 0; 615 + 616 + err |= __put_user(MCONTEXT_VERSION, &uc->uc_mcontext.version); 617 + err |= __put_user(regs->d0, &gregs[0]); 618 + err |= __put_user(regs->d1, &gregs[1]); 619 + err |= __put_user(regs->d2, &gregs[2]); 620 + err |= __put_user(regs->d3, &gregs[3]); 621 + err |= __put_user(regs->d4, &gregs[4]); 622 + err |= __put_user(regs->d5, &gregs[5]); 623 + err |= __put_user(sw->d6, &gregs[6]); 624 + err |= __put_user(sw->d7, &gregs[7]); 625 + err |= __put_user(regs->a0, &gregs[8]); 626 + err |= __put_user(regs->a1, &gregs[9]); 627 + err |= __put_user(regs->a2, &gregs[10]); 628 + err |= __put_user(sw->a3, &gregs[11]); 629 + err |= __put_user(sw->a4, &gregs[12]); 630 + err |= __put_user(sw->a5, &gregs[13]); 631 + err |= __put_user(sw->a6, &gregs[14]); 632 + err |= __put_user(rdusp(), &gregs[15]); 633 + err |= __put_user(regs->pc, &gregs[16]); 634 + err |= __put_user(regs->sr, &gregs[17]); 635 + err |= __put_user((regs->format << 12) | regs->vector, &uc->uc_formatvec); 636 + err |= rt_save_fpu_state(uc, regs); 637 + return err; 638 + } 639 + 640 + static inline void push_cache (unsigned long vaddr) 641 + { 642 + /* 643 + * Using the old cache_push_v() was really a big waste. 644 + * 645 + * What we are trying to do is to flush 8 bytes to ram. 646 + * Flushing 2 cache lines of 16 bytes is much cheaper than 647 + * flushing 1 or 2 pages, as previously done in 648 + * cache_push_v(). 649 + * Jes 650 + */ 651 + if (CPU_IS_040) { 652 + unsigned long temp; 653 + 654 + __asm__ __volatile__ (".chip 68040\n\t" 655 + "nop\n\t" 656 + "ptestr (%1)\n\t" 657 + "movec %%mmusr,%0\n\t" 658 + ".chip 68k" 659 + : "=r" (temp) 660 + : "a" (vaddr)); 661 + 662 + temp &= PAGE_MASK; 663 + temp |= vaddr & ~PAGE_MASK; 664 + 665 + __asm__ __volatile__ (".chip 68040\n\t" 666 + "nop\n\t" 667 + "cpushl %%bc,(%0)\n\t" 668 + ".chip 68k" 669 + : : "a" (temp)); 670 + } 671 + else if (CPU_IS_060) { 672 + unsigned long temp; 673 + __asm__ __volatile__ (".chip 68060\n\t" 674 + "plpar (%0)\n\t" 675 + ".chip 68k" 676 + : "=a" (temp) 677 + : "0" (vaddr)); 678 + __asm__ __volatile__ (".chip 68060\n\t" 679 + "cpushl %%bc,(%0)\n\t" 680 + ".chip 68k" 681 + : : "a" (temp)); 682 + } 683 + else { 684 + /* 685 + * 68030/68020 have no writeback cache; 686 + * still need to clear icache. 687 + * Note that vaddr is guaranteed to be long word aligned. 688 + */ 689 + unsigned long temp; 690 + asm volatile ("movec %%cacr,%0" : "=r" (temp)); 691 + temp += 4; 692 + asm volatile ("movec %0,%%caar\n\t" 693 + "movec %1,%%cacr" 694 + : : "r" (vaddr), "r" (temp)); 695 + asm volatile ("movec %0,%%caar\n\t" 696 + "movec %1,%%cacr" 697 + : : "r" (vaddr + 4), "r" (temp)); 698 + } 699 + } 700 + 701 + static inline void __user * 702 + get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size) 703 + { 704 + unsigned long usp; 705 + 706 + /* Default to using normal stack. */ 707 + usp = rdusp(); 708 + 709 + /* This is the X/Open sanctioned signal stack switching. */ 710 + if (ka->sa.sa_flags & SA_ONSTACK) { 711 + if (!sas_ss_flags(usp)) 712 + usp = current->sas_ss_sp + current->sas_ss_size; 713 + } 714 + return (void __user *)((usp - frame_size) & -8UL); 715 + } 716 + 717 + static int setup_frame (int sig, struct k_sigaction *ka, 718 + sigset_t *set, struct pt_regs *regs) 719 + { 720 + struct sigframe __user *frame; 721 + int fsize = frame_extra_sizes[regs->format]; 722 + struct sigcontext context; 723 + int err = 0; 724 + 725 + if (fsize < 0) { 726 + #ifdef DEBUG 727 + printk ("setup_frame: Unknown frame format %#x\n", 728 + regs->format); 729 + #endif 730 + goto give_sigsegv; 731 + } 732 + 733 + frame = get_sigframe(ka, regs, sizeof(*frame) + fsize); 734 + 735 + if (fsize) 736 + err |= copy_to_user (frame + 1, regs + 1, fsize); 737 + 738 + err |= __put_user((current_thread_info()->exec_domain 739 + && current_thread_info()->exec_domain->signal_invmap 740 + && sig < 32 741 + ? current_thread_info()->exec_domain->signal_invmap[sig] 742 + : sig), 743 + &frame->sig); 744 + 745 + err |= __put_user(regs->vector, &frame->code); 746 + err |= __put_user(&frame->sc, &frame->psc); 747 + 748 + if (_NSIG_WORDS > 1) 749 + err |= copy_to_user(frame->extramask, &set->sig[1], 750 + sizeof(frame->extramask)); 751 + 752 + setup_sigcontext(&context, regs, set->sig[0]); 753 + err |= copy_to_user (&frame->sc, &context, sizeof(context)); 754 + 755 + /* Set up to return from userspace. */ 756 + err |= __put_user(frame->retcode, &frame->pretcode); 757 + /* moveq #,d0; trap #0 */ 758 + err |= __put_user(0x70004e40 + (__NR_sigreturn << 16), 759 + (long __user *)(frame->retcode)); 760 + 761 + if (err) 762 + goto give_sigsegv; 763 + 764 + push_cache ((unsigned long) &frame->retcode); 765 + 766 + /* 767 + * Set up registers for signal handler. All the state we are about 768 + * to destroy is successfully copied to sigframe. 769 + */ 770 + wrusp ((unsigned long) frame); 771 + regs->pc = (unsigned long) ka->sa.sa_handler; 772 + 773 + /* 774 + * This is subtle; if we build more than one sigframe, all but the 775 + * first one will see frame format 0 and have fsize == 0, so we won't 776 + * screw stkadj. 777 + */ 778 + if (fsize) 779 + regs->stkadj = fsize; 780 + 781 + /* Prepare to skip over the extra stuff in the exception frame. */ 782 + if (regs->stkadj) { 783 + struct pt_regs *tregs = 784 + (struct pt_regs *)((ulong)regs + regs->stkadj); 785 + #ifdef DEBUG 786 + printk("Performing stackadjust=%04x\n", regs->stkadj); 787 + #endif 788 + /* This must be copied with decreasing addresses to 789 + handle overlaps. */ 790 + tregs->vector = 0; 791 + tregs->format = 0; 792 + tregs->pc = regs->pc; 793 + tregs->sr = regs->sr; 794 + } 795 + return 0; 796 + 797 + give_sigsegv: 798 + force_sigsegv(sig, current); 799 + return err; 800 + } 801 + 802 + static int setup_rt_frame (int sig, struct k_sigaction *ka, siginfo_t *info, 803 + sigset_t *set, struct pt_regs *regs) 804 + { 805 + struct rt_sigframe __user *frame; 806 + int fsize = frame_extra_sizes[regs->format]; 807 + int err = 0; 808 + 809 + if (fsize < 0) { 810 + #ifdef DEBUG 811 + printk ("setup_frame: Unknown frame format %#x\n", 812 + regs->format); 813 + #endif 814 + goto give_sigsegv; 815 + } 816 + 817 + frame = get_sigframe(ka, regs, sizeof(*frame)); 818 + 819 + if (fsize) 820 + err |= copy_to_user (&frame->uc.uc_extra, regs + 1, fsize); 821 + 822 + err |= __put_user((current_thread_info()->exec_domain 823 + && current_thread_info()->exec_domain->signal_invmap 824 + && sig < 32 825 + ? current_thread_info()->exec_domain->signal_invmap[sig] 826 + : sig), 827 + &frame->sig); 828 + err |= __put_user(&frame->info, &frame->pinfo); 829 + err |= __put_user(&frame->uc, &frame->puc); 830 + err |= copy_siginfo_to_user(&frame->info, info); 831 + 832 + /* Create the ucontext. */ 833 + err |= __put_user(0, &frame->uc.uc_flags); 834 + err |= __put_user(NULL, &frame->uc.uc_link); 835 + err |= __put_user((void __user *)current->sas_ss_sp, 836 + &frame->uc.uc_stack.ss_sp); 837 + err |= __put_user(sas_ss_flags(rdusp()), 838 + &frame->uc.uc_stack.ss_flags); 839 + err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size); 840 + err |= rt_setup_ucontext(&frame->uc, regs); 841 + err |= copy_to_user (&frame->uc.uc_sigmask, set, sizeof(*set)); 842 + 843 + /* Set up to return from userspace. */ 844 + err |= __put_user(frame->retcode, &frame->pretcode); 845 + #ifdef __mcoldfire__ 846 + /* movel #__NR_rt_sigreturn,d0; trap #0 */ 847 + err |= __put_user(0x203c0000, (long __user *)(frame->retcode + 0)); 848 + err |= __put_user(0x00004e40 + (__NR_rt_sigreturn << 16), 849 + (long __user *)(frame->retcode + 4)); 850 + #else 851 + /* moveq #,d0; notb d0; trap #0 */ 852 + err |= __put_user(0x70004600 + ((__NR_rt_sigreturn ^ 0xff) << 16), 853 + (long __user *)(frame->retcode + 0)); 854 + err |= __put_user(0x4e40, (short __user *)(frame->retcode + 4)); 855 + #endif 856 + 857 + if (err) 858 + goto give_sigsegv; 859 + 860 + push_cache ((unsigned long) &frame->retcode); 861 + 862 + /* 863 + * Set up registers for signal handler. All the state we are about 864 + * to destroy is successfully copied to sigframe. 865 + */ 866 + wrusp ((unsigned long) frame); 867 + regs->pc = (unsigned long) ka->sa.sa_handler; 868 + 869 + /* 870 + * This is subtle; if we build more than one sigframe, all but the 871 + * first one will see frame format 0 and have fsize == 0, so we won't 872 + * screw stkadj. 873 + */ 874 + if (fsize) 875 + regs->stkadj = fsize; 876 + 877 + /* Prepare to skip over the extra stuff in the exception frame. */ 878 + if (regs->stkadj) { 879 + struct pt_regs *tregs = 880 + (struct pt_regs *)((ulong)regs + regs->stkadj); 881 + #ifdef DEBUG 882 + printk("Performing stackadjust=%04x\n", regs->stkadj); 883 + #endif 884 + /* This must be copied with decreasing addresses to 885 + handle overlaps. */ 886 + tregs->vector = 0; 887 + tregs->format = 0; 888 + tregs->pc = regs->pc; 889 + tregs->sr = regs->sr; 890 + } 891 + return 0; 892 + 893 + give_sigsegv: 894 + force_sigsegv(sig, current); 895 + return err; 896 + } 897 + 898 + static inline void 899 + handle_restart(struct pt_regs *regs, struct k_sigaction *ka, int has_handler) 900 + { 901 + switch (regs->d0) { 902 + case -ERESTARTNOHAND: 903 + if (!has_handler) 904 + goto do_restart; 905 + regs->d0 = -EINTR; 906 + break; 907 + 908 + case -ERESTART_RESTARTBLOCK: 909 + if (!has_handler) { 910 + regs->d0 = __NR_restart_syscall; 911 + regs->pc -= 2; 912 + break; 913 + } 914 + regs->d0 = -EINTR; 915 + break; 916 + 917 + case -ERESTARTSYS: 918 + if (has_handler && !(ka->sa.sa_flags & SA_RESTART)) { 919 + regs->d0 = -EINTR; 920 + break; 921 + } 922 + /* fallthrough */ 923 + case -ERESTARTNOINTR: 924 + do_restart: 925 + regs->d0 = regs->orig_d0; 926 + regs->pc -= 2; 927 + break; 928 + } 929 + } 930 + 931 + void ptrace_signal_deliver(struct pt_regs *regs, void *cookie) 932 + { 933 + if (regs->orig_d0 < 0) 934 + return; 935 + switch (regs->d0) { 936 + case -ERESTARTNOHAND: 937 + case -ERESTARTSYS: 938 + case -ERESTARTNOINTR: 939 + regs->d0 = regs->orig_d0; 940 + regs->orig_d0 = -1; 941 + regs->pc -= 2; 942 + break; 943 + } 944 + } 945 + 946 + /* 947 + * OK, we're invoking a handler 948 + */ 949 + static void 950 + handle_signal(int sig, struct k_sigaction *ka, siginfo_t *info, 951 + sigset_t *oldset, struct pt_regs *regs) 952 + { 953 + int err; 954 + /* are we from a system call? */ 955 + if (regs->orig_d0 >= 0) 956 + /* If so, check system call restarting.. */ 957 + handle_restart(regs, ka, 1); 958 + 959 + /* set up the stack frame */ 960 + if (ka->sa.sa_flags & SA_SIGINFO) 961 + err = setup_rt_frame(sig, ka, info, oldset, regs); 962 + else 963 + err = setup_frame(sig, ka, oldset, regs); 964 + 965 + if (err) 966 + return; 967 + 968 + sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask); 969 + if (!(ka->sa.sa_flags & SA_NODEFER)) 970 + sigaddset(&current->blocked,sig); 971 + recalc_sigpending(); 972 + 973 + if (test_thread_flag(TIF_DELAYED_TRACE)) { 974 + regs->sr &= ~0x8000; 975 + send_sig(SIGTRAP, current, 1); 976 + } 977 + 978 + clear_thread_flag(TIF_RESTORE_SIGMASK); 979 + } 980 + 981 + /* 982 + * Note that 'init' is a special process: it doesn't get signals it doesn't 983 + * want to handle. Thus you cannot kill init even with a SIGKILL even by 984 + * mistake. 985 + */ 986 + asmlinkage void do_signal(struct pt_regs *regs) 987 + { 988 + siginfo_t info; 989 + struct k_sigaction ka; 990 + int signr; 991 + sigset_t *oldset; 992 + 993 + current->thread.esp0 = (unsigned long) regs; 994 + 995 + if (test_thread_flag(TIF_RESTORE_SIGMASK)) 996 + oldset = &current->saved_sigmask; 997 + else 998 + oldset = &current->blocked; 999 + 1000 + signr = get_signal_to_deliver(&info, &ka, regs, NULL); 1001 + if (signr > 0) { 1002 + /* Whee! Actually deliver the signal. */ 1003 + handle_signal(signr, &ka, &info, oldset, regs); 1004 + return; 1005 + } 1006 + 1007 + /* Did we come from a system call? */ 1008 + if (regs->orig_d0 >= 0) 1009 + /* Restart the system call - no handlers present */ 1010 + handle_restart(regs, NULL, 0); 1011 + 1012 + /* If there's no signal to deliver, we just restore the saved mask. */ 1013 + if (test_thread_flag(TIF_RESTORE_SIGMASK)) { 1014 + clear_thread_flag(TIF_RESTORE_SIGMASK); 1015 + sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL); 1016 + } 1017 + }
+5 -546
arch/m68k/kernel/sys_m68k.c
··· 1 - /* 2 - * linux/arch/m68k/kernel/sys_m68k.c 3 - * 4 - * This file contains various random system calls that 5 - * have a non-standard calling sequence on the Linux/m68k 6 - * platform. 7 - */ 8 - 9 - #include <linux/capability.h> 10 - #include <linux/errno.h> 11 - #include <linux/sched.h> 12 - #include <linux/mm.h> 13 - #include <linux/fs.h> 14 - #include <linux/smp.h> 15 - #include <linux/sem.h> 16 - #include <linux/msg.h> 17 - #include <linux/shm.h> 18 - #include <linux/stat.h> 19 - #include <linux/syscalls.h> 20 - #include <linux/mman.h> 21 - #include <linux/file.h> 22 - #include <linux/ipc.h> 23 - 24 - #include <asm/setup.h> 25 - #include <asm/uaccess.h> 26 - #include <asm/cachectl.h> 27 - #include <asm/traps.h> 28 - #include <asm/page.h> 29 - #include <asm/unistd.h> 30 - #include <linux/elf.h> 31 - #include <asm/tlb.h> 32 - 33 - asmlinkage int do_page_fault(struct pt_regs *regs, unsigned long address, 34 - unsigned long error_code); 35 - 36 - asmlinkage long sys_mmap2(unsigned long addr, unsigned long len, 37 - unsigned long prot, unsigned long flags, 38 - unsigned long fd, unsigned long pgoff) 39 - { 40 - /* 41 - * This is wrong for sun3 - there PAGE_SIZE is 8Kb, 42 - * so we need to shift the argument down by 1; m68k mmap64(3) 43 - * (in libc) expects the last argument of mmap2 in 4Kb units. 44 - */ 45 - return sys_mmap_pgoff(addr, len, prot, flags, fd, pgoff); 46 - } 47 - 48 - /* Convert virtual (user) address VADDR to physical address PADDR */ 49 - #define virt_to_phys_040(vaddr) \ 50 - ({ \ 51 - unsigned long _mmusr, _paddr; \ 52 - \ 53 - __asm__ __volatile__ (".chip 68040\n\t" \ 54 - "ptestr (%1)\n\t" \ 55 - "movec %%mmusr,%0\n\t" \ 56 - ".chip 68k" \ 57 - : "=r" (_mmusr) \ 58 - : "a" (vaddr)); \ 59 - _paddr = (_mmusr & MMU_R_040) ? (_mmusr & PAGE_MASK) : 0; \ 60 - _paddr; \ 61 - }) 62 - 63 - static inline int 64 - cache_flush_040 (unsigned long addr, int scope, int cache, unsigned long len) 65 - { 66 - unsigned long paddr, i; 67 - 68 - switch (scope) 69 - { 70 - case FLUSH_SCOPE_ALL: 71 - switch (cache) 72 - { 73 - case FLUSH_CACHE_DATA: 74 - /* This nop is needed for some broken versions of the 68040. */ 75 - __asm__ __volatile__ ("nop\n\t" 76 - ".chip 68040\n\t" 77 - "cpusha %dc\n\t" 78 - ".chip 68k"); 79 - break; 80 - case FLUSH_CACHE_INSN: 81 - __asm__ __volatile__ ("nop\n\t" 82 - ".chip 68040\n\t" 83 - "cpusha %ic\n\t" 84 - ".chip 68k"); 85 - break; 86 - default: 87 - case FLUSH_CACHE_BOTH: 88 - __asm__ __volatile__ ("nop\n\t" 89 - ".chip 68040\n\t" 90 - "cpusha %bc\n\t" 91 - ".chip 68k"); 92 - break; 93 - } 94 - break; 95 - 96 - case FLUSH_SCOPE_LINE: 97 - /* Find the physical address of the first mapped page in the 98 - address range. */ 99 - if ((paddr = virt_to_phys_040(addr))) { 100 - paddr += addr & ~(PAGE_MASK | 15); 101 - len = (len + (addr & 15) + 15) >> 4; 102 - } else { 103 - unsigned long tmp = PAGE_SIZE - (addr & ~PAGE_MASK); 104 - 105 - if (len <= tmp) 106 - return 0; 107 - addr += tmp; 108 - len -= tmp; 109 - tmp = PAGE_SIZE; 110 - for (;;) 111 - { 112 - if ((paddr = virt_to_phys_040(addr))) 113 - break; 114 - if (len <= tmp) 115 - return 0; 116 - addr += tmp; 117 - len -= tmp; 118 - } 119 - len = (len + 15) >> 4; 120 - } 121 - i = (PAGE_SIZE - (paddr & ~PAGE_MASK)) >> 4; 122 - while (len--) 123 - { 124 - switch (cache) 125 - { 126 - case FLUSH_CACHE_DATA: 127 - __asm__ __volatile__ ("nop\n\t" 128 - ".chip 68040\n\t" 129 - "cpushl %%dc,(%0)\n\t" 130 - ".chip 68k" 131 - : : "a" (paddr)); 132 - break; 133 - case FLUSH_CACHE_INSN: 134 - __asm__ __volatile__ ("nop\n\t" 135 - ".chip 68040\n\t" 136 - "cpushl %%ic,(%0)\n\t" 137 - ".chip 68k" 138 - : : "a" (paddr)); 139 - break; 140 - default: 141 - case FLUSH_CACHE_BOTH: 142 - __asm__ __volatile__ ("nop\n\t" 143 - ".chip 68040\n\t" 144 - "cpushl %%bc,(%0)\n\t" 145 - ".chip 68k" 146 - : : "a" (paddr)); 147 - break; 148 - } 149 - if (!--i && len) 150 - { 151 - /* 152 - * No need to page align here since it is done by 153 - * virt_to_phys_040(). 154 - */ 155 - addr += PAGE_SIZE; 156 - i = PAGE_SIZE / 16; 157 - /* Recompute physical address when crossing a page 158 - boundary. */ 159 - for (;;) 160 - { 161 - if ((paddr = virt_to_phys_040(addr))) 162 - break; 163 - if (len <= i) 164 - return 0; 165 - len -= i; 166 - addr += PAGE_SIZE; 167 - } 168 - } 169 - else 170 - paddr += 16; 171 - } 172 - break; 173 - 174 - default: 175 - case FLUSH_SCOPE_PAGE: 176 - len += (addr & ~PAGE_MASK) + (PAGE_SIZE - 1); 177 - for (len >>= PAGE_SHIFT; len--; addr += PAGE_SIZE) 178 - { 179 - if (!(paddr = virt_to_phys_040(addr))) 180 - continue; 181 - switch (cache) 182 - { 183 - case FLUSH_CACHE_DATA: 184 - __asm__ __volatile__ ("nop\n\t" 185 - ".chip 68040\n\t" 186 - "cpushp %%dc,(%0)\n\t" 187 - ".chip 68k" 188 - : : "a" (paddr)); 189 - break; 190 - case FLUSH_CACHE_INSN: 191 - __asm__ __volatile__ ("nop\n\t" 192 - ".chip 68040\n\t" 193 - "cpushp %%ic,(%0)\n\t" 194 - ".chip 68k" 195 - : : "a" (paddr)); 196 - break; 197 - default: 198 - case FLUSH_CACHE_BOTH: 199 - __asm__ __volatile__ ("nop\n\t" 200 - ".chip 68040\n\t" 201 - "cpushp %%bc,(%0)\n\t" 202 - ".chip 68k" 203 - : : "a" (paddr)); 204 - break; 205 - } 206 - } 207 - break; 208 - } 209 - return 0; 210 - } 211 - 212 - #define virt_to_phys_060(vaddr) \ 213 - ({ \ 214 - unsigned long paddr; \ 215 - __asm__ __volatile__ (".chip 68060\n\t" \ 216 - "plpar (%0)\n\t" \ 217 - ".chip 68k" \ 218 - : "=a" (paddr) \ 219 - : "0" (vaddr)); \ 220 - (paddr); /* XXX */ \ 221 - }) 222 - 223 - static inline int 224 - cache_flush_060 (unsigned long addr, int scope, int cache, unsigned long len) 225 - { 226 - unsigned long paddr, i; 227 - 228 - /* 229 - * 68060 manual says: 230 - * cpush %dc : flush DC, remains valid (with our %cacr setup) 231 - * cpush %ic : invalidate IC 232 - * cpush %bc : flush DC + invalidate IC 233 - */ 234 - switch (scope) 235 - { 236 - case FLUSH_SCOPE_ALL: 237 - switch (cache) 238 - { 239 - case FLUSH_CACHE_DATA: 240 - __asm__ __volatile__ (".chip 68060\n\t" 241 - "cpusha %dc\n\t" 242 - ".chip 68k"); 243 - break; 244 - case FLUSH_CACHE_INSN: 245 - __asm__ __volatile__ (".chip 68060\n\t" 246 - "cpusha %ic\n\t" 247 - ".chip 68k"); 248 - break; 249 - default: 250 - case FLUSH_CACHE_BOTH: 251 - __asm__ __volatile__ (".chip 68060\n\t" 252 - "cpusha %bc\n\t" 253 - ".chip 68k"); 254 - break; 255 - } 256 - break; 257 - 258 - case FLUSH_SCOPE_LINE: 259 - /* Find the physical address of the first mapped page in the 260 - address range. */ 261 - len += addr & 15; 262 - addr &= -16; 263 - if (!(paddr = virt_to_phys_060(addr))) { 264 - unsigned long tmp = PAGE_SIZE - (addr & ~PAGE_MASK); 265 - 266 - if (len <= tmp) 267 - return 0; 268 - addr += tmp; 269 - len -= tmp; 270 - tmp = PAGE_SIZE; 271 - for (;;) 272 - { 273 - if ((paddr = virt_to_phys_060(addr))) 274 - break; 275 - if (len <= tmp) 276 - return 0; 277 - addr += tmp; 278 - len -= tmp; 279 - } 280 - } 281 - len = (len + 15) >> 4; 282 - i = (PAGE_SIZE - (paddr & ~PAGE_MASK)) >> 4; 283 - while (len--) 284 - { 285 - switch (cache) 286 - { 287 - case FLUSH_CACHE_DATA: 288 - __asm__ __volatile__ (".chip 68060\n\t" 289 - "cpushl %%dc,(%0)\n\t" 290 - ".chip 68k" 291 - : : "a" (paddr)); 292 - break; 293 - case FLUSH_CACHE_INSN: 294 - __asm__ __volatile__ (".chip 68060\n\t" 295 - "cpushl %%ic,(%0)\n\t" 296 - ".chip 68k" 297 - : : "a" (paddr)); 298 - break; 299 - default: 300 - case FLUSH_CACHE_BOTH: 301 - __asm__ __volatile__ (".chip 68060\n\t" 302 - "cpushl %%bc,(%0)\n\t" 303 - ".chip 68k" 304 - : : "a" (paddr)); 305 - break; 306 - } 307 - if (!--i && len) 308 - { 309 - 310 - /* 311 - * We just want to jump to the first cache line 312 - * in the next page. 313 - */ 314 - addr += PAGE_SIZE; 315 - addr &= PAGE_MASK; 316 - 317 - i = PAGE_SIZE / 16; 318 - /* Recompute physical address when crossing a page 319 - boundary. */ 320 - for (;;) 321 - { 322 - if ((paddr = virt_to_phys_060(addr))) 323 - break; 324 - if (len <= i) 325 - return 0; 326 - len -= i; 327 - addr += PAGE_SIZE; 328 - } 329 - } 330 - else 331 - paddr += 16; 332 - } 333 - break; 334 - 335 - default: 336 - case FLUSH_SCOPE_PAGE: 337 - len += (addr & ~PAGE_MASK) + (PAGE_SIZE - 1); 338 - addr &= PAGE_MASK; /* Workaround for bug in some 339 - revisions of the 68060 */ 340 - for (len >>= PAGE_SHIFT; len--; addr += PAGE_SIZE) 341 - { 342 - if (!(paddr = virt_to_phys_060(addr))) 343 - continue; 344 - switch (cache) 345 - { 346 - case FLUSH_CACHE_DATA: 347 - __asm__ __volatile__ (".chip 68060\n\t" 348 - "cpushp %%dc,(%0)\n\t" 349 - ".chip 68k" 350 - : : "a" (paddr)); 351 - break; 352 - case FLUSH_CACHE_INSN: 353 - __asm__ __volatile__ (".chip 68060\n\t" 354 - "cpushp %%ic,(%0)\n\t" 355 - ".chip 68k" 356 - : : "a" (paddr)); 357 - break; 358 - default: 359 - case FLUSH_CACHE_BOTH: 360 - __asm__ __volatile__ (".chip 68060\n\t" 361 - "cpushp %%bc,(%0)\n\t" 362 - ".chip 68k" 363 - : : "a" (paddr)); 364 - break; 365 - } 366 - } 367 - break; 368 - } 369 - return 0; 370 - } 371 - 372 - /* sys_cacheflush -- flush (part of) the processor cache. */ 373 - asmlinkage int 374 - sys_cacheflush (unsigned long addr, int scope, int cache, unsigned long len) 375 - { 376 - struct vm_area_struct *vma; 377 - int ret = -EINVAL; 378 - 379 - if (scope < FLUSH_SCOPE_LINE || scope > FLUSH_SCOPE_ALL || 380 - cache & ~FLUSH_CACHE_BOTH) 381 - goto out; 382 - 383 - if (scope == FLUSH_SCOPE_ALL) { 384 - /* Only the superuser may explicitly flush the whole cache. */ 385 - ret = -EPERM; 386 - if (!capable(CAP_SYS_ADMIN)) 387 - goto out; 388 - } else { 389 - /* 390 - * Verify that the specified address region actually belongs 391 - * to this process. 392 - */ 393 - vma = find_vma (current->mm, addr); 394 - ret = -EINVAL; 395 - /* Check for overflow. */ 396 - if (addr + len < addr) 397 - goto out; 398 - if (vma == NULL || addr < vma->vm_start || addr + len > vma->vm_end) 399 - goto out; 400 - } 401 - 402 - if (CPU_IS_020_OR_030) { 403 - if (scope == FLUSH_SCOPE_LINE && len < 256) { 404 - unsigned long cacr; 405 - __asm__ ("movec %%cacr, %0" : "=r" (cacr)); 406 - if (cache & FLUSH_CACHE_INSN) 407 - cacr |= 4; 408 - if (cache & FLUSH_CACHE_DATA) 409 - cacr |= 0x400; 410 - len >>= 2; 411 - while (len--) { 412 - __asm__ __volatile__ ("movec %1, %%caar\n\t" 413 - "movec %0, %%cacr" 414 - : /* no outputs */ 415 - : "r" (cacr), "r" (addr)); 416 - addr += 4; 417 - } 418 - } else { 419 - /* Flush the whole cache, even if page granularity requested. */ 420 - unsigned long cacr; 421 - __asm__ ("movec %%cacr, %0" : "=r" (cacr)); 422 - if (cache & FLUSH_CACHE_INSN) 423 - cacr |= 8; 424 - if (cache & FLUSH_CACHE_DATA) 425 - cacr |= 0x800; 426 - __asm__ __volatile__ ("movec %0, %%cacr" : : "r" (cacr)); 427 - } 428 - ret = 0; 429 - goto out; 430 - } else { 431 - /* 432 - * 040 or 060: don't blindly trust 'scope', someone could 433 - * try to flush a few megs of memory. 434 - */ 435 - 436 - if (len>=3*PAGE_SIZE && scope<FLUSH_SCOPE_PAGE) 437 - scope=FLUSH_SCOPE_PAGE; 438 - if (len>=10*PAGE_SIZE && scope<FLUSH_SCOPE_ALL) 439 - scope=FLUSH_SCOPE_ALL; 440 - if (CPU_IS_040) { 441 - ret = cache_flush_040 (addr, scope, cache, len); 442 - } else if (CPU_IS_060) { 443 - ret = cache_flush_060 (addr, scope, cache, len); 444 - } 445 - } 446 - out: 447 - return ret; 448 - } 449 - 450 - asmlinkage int sys_getpagesize(void) 451 - { 452 - return PAGE_SIZE; 453 - } 454 - 455 - /* 456 - * Do a system call from kernel instead of calling sys_execve so we 457 - * end up with proper pt_regs. 458 - */ 459 - int kernel_execve(const char *filename, 460 - const char *const argv[], 461 - const char *const envp[]) 462 - { 463 - register long __res asm ("%d0") = __NR_execve; 464 - register long __a asm ("%d1") = (long)(filename); 465 - register long __b asm ("%d2") = (long)(argv); 466 - register long __c asm ("%d3") = (long)(envp); 467 - asm volatile ("trap #0" : "+d" (__res) 468 - : "d" (__a), "d" (__b), "d" (__c)); 469 - return __res; 470 - } 471 - 472 - asmlinkage unsigned long sys_get_thread_area(void) 473 - { 474 - return current_thread_info()->tp_value; 475 - } 476 - 477 - asmlinkage int sys_set_thread_area(unsigned long tp) 478 - { 479 - current_thread_info()->tp_value = tp; 480 - return 0; 481 - } 482 - 483 - /* This syscall gets its arguments in A0 (mem), D2 (oldval) and 484 - D1 (newval). */ 485 - asmlinkage int 486 - sys_atomic_cmpxchg_32(unsigned long newval, int oldval, int d3, int d4, int d5, 487 - unsigned long __user * mem) 488 - { 489 - /* This was borrowed from ARM's implementation. */ 490 - for (;;) { 491 - struct mm_struct *mm = current->mm; 492 - pgd_t *pgd; 493 - pmd_t *pmd; 494 - pte_t *pte; 495 - spinlock_t *ptl; 496 - unsigned long mem_value; 497 - 498 - down_read(&mm->mmap_sem); 499 - pgd = pgd_offset(mm, (unsigned long)mem); 500 - if (!pgd_present(*pgd)) 501 - goto bad_access; 502 - pmd = pmd_offset(pgd, (unsigned long)mem); 503 - if (!pmd_present(*pmd)) 504 - goto bad_access; 505 - pte = pte_offset_map_lock(mm, pmd, (unsigned long)mem, &ptl); 506 - if (!pte_present(*pte) || !pte_dirty(*pte) 507 - || !pte_write(*pte)) { 508 - pte_unmap_unlock(pte, ptl); 509 - goto bad_access; 510 - } 511 - 512 - mem_value = *mem; 513 - if (mem_value == oldval) 514 - *mem = newval; 515 - 516 - pte_unmap_unlock(pte, ptl); 517 - up_read(&mm->mmap_sem); 518 - return mem_value; 519 - 520 - bad_access: 521 - up_read(&mm->mmap_sem); 522 - /* This is not necessarily a bad access, we can get here if 523 - a memory we're trying to write to should be copied-on-write. 524 - Make the kernel do the necessary page stuff, then re-iterate. 525 - Simulate a write access fault to do that. */ 526 - { 527 - /* The first argument of the function corresponds to 528 - D1, which is the first field of struct pt_regs. */ 529 - struct pt_regs *fp = (struct pt_regs *)&newval; 530 - 531 - /* '3' is an RMW flag. */ 532 - if (do_page_fault(fp, (unsigned long)mem, 3)) 533 - /* If the do_page_fault() failed, we don't 534 - have anything meaningful to return. 535 - There should be a SIGSEGV pending for 536 - the process. */ 537 - return 0xdeadbeef; 538 - } 539 - } 540 - } 541 - 542 - asmlinkage int sys_atomic_barrier(void) 543 - { 544 - /* no code needed for uniprocs */ 545 - return 0; 546 - }
··· 1 + #ifdef CONFIG_MMU 2 + #include "sys_m68k_mm.c" 3 + #else 4 + #include "sys_m68k_no.c" 5 + #endif
+546
arch/m68k/kernel/sys_m68k_mm.c
···
··· 1 + /* 2 + * linux/arch/m68k/kernel/sys_m68k.c 3 + * 4 + * This file contains various random system calls that 5 + * have a non-standard calling sequence on the Linux/m68k 6 + * platform. 7 + */ 8 + 9 + #include <linux/capability.h> 10 + #include <linux/errno.h> 11 + #include <linux/sched.h> 12 + #include <linux/mm.h> 13 + #include <linux/fs.h> 14 + #include <linux/smp.h> 15 + #include <linux/sem.h> 16 + #include <linux/msg.h> 17 + #include <linux/shm.h> 18 + #include <linux/stat.h> 19 + #include <linux/syscalls.h> 20 + #include <linux/mman.h> 21 + #include <linux/file.h> 22 + #include <linux/ipc.h> 23 + 24 + #include <asm/setup.h> 25 + #include <asm/uaccess.h> 26 + #include <asm/cachectl.h> 27 + #include <asm/traps.h> 28 + #include <asm/page.h> 29 + #include <asm/unistd.h> 30 + #include <linux/elf.h> 31 + #include <asm/tlb.h> 32 + 33 + asmlinkage int do_page_fault(struct pt_regs *regs, unsigned long address, 34 + unsigned long error_code); 35 + 36 + asmlinkage long sys_mmap2(unsigned long addr, unsigned long len, 37 + unsigned long prot, unsigned long flags, 38 + unsigned long fd, unsigned long pgoff) 39 + { 40 + /* 41 + * This is wrong for sun3 - there PAGE_SIZE is 8Kb, 42 + * so we need to shift the argument down by 1; m68k mmap64(3) 43 + * (in libc) expects the last argument of mmap2 in 4Kb units. 44 + */ 45 + return sys_mmap_pgoff(addr, len, prot, flags, fd, pgoff); 46 + } 47 + 48 + /* Convert virtual (user) address VADDR to physical address PADDR */ 49 + #define virt_to_phys_040(vaddr) \ 50 + ({ \ 51 + unsigned long _mmusr, _paddr; \ 52 + \ 53 + __asm__ __volatile__ (".chip 68040\n\t" \ 54 + "ptestr (%1)\n\t" \ 55 + "movec %%mmusr,%0\n\t" \ 56 + ".chip 68k" \ 57 + : "=r" (_mmusr) \ 58 + : "a" (vaddr)); \ 59 + _paddr = (_mmusr & MMU_R_040) ? (_mmusr & PAGE_MASK) : 0; \ 60 + _paddr; \ 61 + }) 62 + 63 + static inline int 64 + cache_flush_040 (unsigned long addr, int scope, int cache, unsigned long len) 65 + { 66 + unsigned long paddr, i; 67 + 68 + switch (scope) 69 + { 70 + case FLUSH_SCOPE_ALL: 71 + switch (cache) 72 + { 73 + case FLUSH_CACHE_DATA: 74 + /* This nop is needed for some broken versions of the 68040. */ 75 + __asm__ __volatile__ ("nop\n\t" 76 + ".chip 68040\n\t" 77 + "cpusha %dc\n\t" 78 + ".chip 68k"); 79 + break; 80 + case FLUSH_CACHE_INSN: 81 + __asm__ __volatile__ ("nop\n\t" 82 + ".chip 68040\n\t" 83 + "cpusha %ic\n\t" 84 + ".chip 68k"); 85 + break; 86 + default: 87 + case FLUSH_CACHE_BOTH: 88 + __asm__ __volatile__ ("nop\n\t" 89 + ".chip 68040\n\t" 90 + "cpusha %bc\n\t" 91 + ".chip 68k"); 92 + break; 93 + } 94 + break; 95 + 96 + case FLUSH_SCOPE_LINE: 97 + /* Find the physical address of the first mapped page in the 98 + address range. */ 99 + if ((paddr = virt_to_phys_040(addr))) { 100 + paddr += addr & ~(PAGE_MASK | 15); 101 + len = (len + (addr & 15) + 15) >> 4; 102 + } else { 103 + unsigned long tmp = PAGE_SIZE - (addr & ~PAGE_MASK); 104 + 105 + if (len <= tmp) 106 + return 0; 107 + addr += tmp; 108 + len -= tmp; 109 + tmp = PAGE_SIZE; 110 + for (;;) 111 + { 112 + if ((paddr = virt_to_phys_040(addr))) 113 + break; 114 + if (len <= tmp) 115 + return 0; 116 + addr += tmp; 117 + len -= tmp; 118 + } 119 + len = (len + 15) >> 4; 120 + } 121 + i = (PAGE_SIZE - (paddr & ~PAGE_MASK)) >> 4; 122 + while (len--) 123 + { 124 + switch (cache) 125 + { 126 + case FLUSH_CACHE_DATA: 127 + __asm__ __volatile__ ("nop\n\t" 128 + ".chip 68040\n\t" 129 + "cpushl %%dc,(%0)\n\t" 130 + ".chip 68k" 131 + : : "a" (paddr)); 132 + break; 133 + case FLUSH_CACHE_INSN: 134 + __asm__ __volatile__ ("nop\n\t" 135 + ".chip 68040\n\t" 136 + "cpushl %%ic,(%0)\n\t" 137 + ".chip 68k" 138 + : : "a" (paddr)); 139 + break; 140 + default: 141 + case FLUSH_CACHE_BOTH: 142 + __asm__ __volatile__ ("nop\n\t" 143 + ".chip 68040\n\t" 144 + "cpushl %%bc,(%0)\n\t" 145 + ".chip 68k" 146 + : : "a" (paddr)); 147 + break; 148 + } 149 + if (!--i && len) 150 + { 151 + /* 152 + * No need to page align here since it is done by 153 + * virt_to_phys_040(). 154 + */ 155 + addr += PAGE_SIZE; 156 + i = PAGE_SIZE / 16; 157 + /* Recompute physical address when crossing a page 158 + boundary. */ 159 + for (;;) 160 + { 161 + if ((paddr = virt_to_phys_040(addr))) 162 + break; 163 + if (len <= i) 164 + return 0; 165 + len -= i; 166 + addr += PAGE_SIZE; 167 + } 168 + } 169 + else 170 + paddr += 16; 171 + } 172 + break; 173 + 174 + default: 175 + case FLUSH_SCOPE_PAGE: 176 + len += (addr & ~PAGE_MASK) + (PAGE_SIZE - 1); 177 + for (len >>= PAGE_SHIFT; len--; addr += PAGE_SIZE) 178 + { 179 + if (!(paddr = virt_to_phys_040(addr))) 180 + continue; 181 + switch (cache) 182 + { 183 + case FLUSH_CACHE_DATA: 184 + __asm__ __volatile__ ("nop\n\t" 185 + ".chip 68040\n\t" 186 + "cpushp %%dc,(%0)\n\t" 187 + ".chip 68k" 188 + : : "a" (paddr)); 189 + break; 190 + case FLUSH_CACHE_INSN: 191 + __asm__ __volatile__ ("nop\n\t" 192 + ".chip 68040\n\t" 193 + "cpushp %%ic,(%0)\n\t" 194 + ".chip 68k" 195 + : : "a" (paddr)); 196 + break; 197 + default: 198 + case FLUSH_CACHE_BOTH: 199 + __asm__ __volatile__ ("nop\n\t" 200 + ".chip 68040\n\t" 201 + "cpushp %%bc,(%0)\n\t" 202 + ".chip 68k" 203 + : : "a" (paddr)); 204 + break; 205 + } 206 + } 207 + break; 208 + } 209 + return 0; 210 + } 211 + 212 + #define virt_to_phys_060(vaddr) \ 213 + ({ \ 214 + unsigned long paddr; \ 215 + __asm__ __volatile__ (".chip 68060\n\t" \ 216 + "plpar (%0)\n\t" \ 217 + ".chip 68k" \ 218 + : "=a" (paddr) \ 219 + : "0" (vaddr)); \ 220 + (paddr); /* XXX */ \ 221 + }) 222 + 223 + static inline int 224 + cache_flush_060 (unsigned long addr, int scope, int cache, unsigned long len) 225 + { 226 + unsigned long paddr, i; 227 + 228 + /* 229 + * 68060 manual says: 230 + * cpush %dc : flush DC, remains valid (with our %cacr setup) 231 + * cpush %ic : invalidate IC 232 + * cpush %bc : flush DC + invalidate IC 233 + */ 234 + switch (scope) 235 + { 236 + case FLUSH_SCOPE_ALL: 237 + switch (cache) 238 + { 239 + case FLUSH_CACHE_DATA: 240 + __asm__ __volatile__ (".chip 68060\n\t" 241 + "cpusha %dc\n\t" 242 + ".chip 68k"); 243 + break; 244 + case FLUSH_CACHE_INSN: 245 + __asm__ __volatile__ (".chip 68060\n\t" 246 + "cpusha %ic\n\t" 247 + ".chip 68k"); 248 + break; 249 + default: 250 + case FLUSH_CACHE_BOTH: 251 + __asm__ __volatile__ (".chip 68060\n\t" 252 + "cpusha %bc\n\t" 253 + ".chip 68k"); 254 + break; 255 + } 256 + break; 257 + 258 + case FLUSH_SCOPE_LINE: 259 + /* Find the physical address of the first mapped page in the 260 + address range. */ 261 + len += addr & 15; 262 + addr &= -16; 263 + if (!(paddr = virt_to_phys_060(addr))) { 264 + unsigned long tmp = PAGE_SIZE - (addr & ~PAGE_MASK); 265 + 266 + if (len <= tmp) 267 + return 0; 268 + addr += tmp; 269 + len -= tmp; 270 + tmp = PAGE_SIZE; 271 + for (;;) 272 + { 273 + if ((paddr = virt_to_phys_060(addr))) 274 + break; 275 + if (len <= tmp) 276 + return 0; 277 + addr += tmp; 278 + len -= tmp; 279 + } 280 + } 281 + len = (len + 15) >> 4; 282 + i = (PAGE_SIZE - (paddr & ~PAGE_MASK)) >> 4; 283 + while (len--) 284 + { 285 + switch (cache) 286 + { 287 + case FLUSH_CACHE_DATA: 288 + __asm__ __volatile__ (".chip 68060\n\t" 289 + "cpushl %%dc,(%0)\n\t" 290 + ".chip 68k" 291 + : : "a" (paddr)); 292 + break; 293 + case FLUSH_CACHE_INSN: 294 + __asm__ __volatile__ (".chip 68060\n\t" 295 + "cpushl %%ic,(%0)\n\t" 296 + ".chip 68k" 297 + : : "a" (paddr)); 298 + break; 299 + default: 300 + case FLUSH_CACHE_BOTH: 301 + __asm__ __volatile__ (".chip 68060\n\t" 302 + "cpushl %%bc,(%0)\n\t" 303 + ".chip 68k" 304 + : : "a" (paddr)); 305 + break; 306 + } 307 + if (!--i && len) 308 + { 309 + 310 + /* 311 + * We just want to jump to the first cache line 312 + * in the next page. 313 + */ 314 + addr += PAGE_SIZE; 315 + addr &= PAGE_MASK; 316 + 317 + i = PAGE_SIZE / 16; 318 + /* Recompute physical address when crossing a page 319 + boundary. */ 320 + for (;;) 321 + { 322 + if ((paddr = virt_to_phys_060(addr))) 323 + break; 324 + if (len <= i) 325 + return 0; 326 + len -= i; 327 + addr += PAGE_SIZE; 328 + } 329 + } 330 + else 331 + paddr += 16; 332 + } 333 + break; 334 + 335 + default: 336 + case FLUSH_SCOPE_PAGE: 337 + len += (addr & ~PAGE_MASK) + (PAGE_SIZE - 1); 338 + addr &= PAGE_MASK; /* Workaround for bug in some 339 + revisions of the 68060 */ 340 + for (len >>= PAGE_SHIFT; len--; addr += PAGE_SIZE) 341 + { 342 + if (!(paddr = virt_to_phys_060(addr))) 343 + continue; 344 + switch (cache) 345 + { 346 + case FLUSH_CACHE_DATA: 347 + __asm__ __volatile__ (".chip 68060\n\t" 348 + "cpushp %%dc,(%0)\n\t" 349 + ".chip 68k" 350 + : : "a" (paddr)); 351 + break; 352 + case FLUSH_CACHE_INSN: 353 + __asm__ __volatile__ (".chip 68060\n\t" 354 + "cpushp %%ic,(%0)\n\t" 355 + ".chip 68k" 356 + : : "a" (paddr)); 357 + break; 358 + default: 359 + case FLUSH_CACHE_BOTH: 360 + __asm__ __volatile__ (".chip 68060\n\t" 361 + "cpushp %%bc,(%0)\n\t" 362 + ".chip 68k" 363 + : : "a" (paddr)); 364 + break; 365 + } 366 + } 367 + break; 368 + } 369 + return 0; 370 + } 371 + 372 + /* sys_cacheflush -- flush (part of) the processor cache. */ 373 + asmlinkage int 374 + sys_cacheflush (unsigned long addr, int scope, int cache, unsigned long len) 375 + { 376 + struct vm_area_struct *vma; 377 + int ret = -EINVAL; 378 + 379 + if (scope < FLUSH_SCOPE_LINE || scope > FLUSH_SCOPE_ALL || 380 + cache & ~FLUSH_CACHE_BOTH) 381 + goto out; 382 + 383 + if (scope == FLUSH_SCOPE_ALL) { 384 + /* Only the superuser may explicitly flush the whole cache. */ 385 + ret = -EPERM; 386 + if (!capable(CAP_SYS_ADMIN)) 387 + goto out; 388 + } else { 389 + /* 390 + * Verify that the specified address region actually belongs 391 + * to this process. 392 + */ 393 + vma = find_vma (current->mm, addr); 394 + ret = -EINVAL; 395 + /* Check for overflow. */ 396 + if (addr + len < addr) 397 + goto out; 398 + if (vma == NULL || addr < vma->vm_start || addr + len > vma->vm_end) 399 + goto out; 400 + } 401 + 402 + if (CPU_IS_020_OR_030) { 403 + if (scope == FLUSH_SCOPE_LINE && len < 256) { 404 + unsigned long cacr; 405 + __asm__ ("movec %%cacr, %0" : "=r" (cacr)); 406 + if (cache & FLUSH_CACHE_INSN) 407 + cacr |= 4; 408 + if (cache & FLUSH_CACHE_DATA) 409 + cacr |= 0x400; 410 + len >>= 2; 411 + while (len--) { 412 + __asm__ __volatile__ ("movec %1, %%caar\n\t" 413 + "movec %0, %%cacr" 414 + : /* no outputs */ 415 + : "r" (cacr), "r" (addr)); 416 + addr += 4; 417 + } 418 + } else { 419 + /* Flush the whole cache, even if page granularity requested. */ 420 + unsigned long cacr; 421 + __asm__ ("movec %%cacr, %0" : "=r" (cacr)); 422 + if (cache & FLUSH_CACHE_INSN) 423 + cacr |= 8; 424 + if (cache & FLUSH_CACHE_DATA) 425 + cacr |= 0x800; 426 + __asm__ __volatile__ ("movec %0, %%cacr" : : "r" (cacr)); 427 + } 428 + ret = 0; 429 + goto out; 430 + } else { 431 + /* 432 + * 040 or 060: don't blindly trust 'scope', someone could 433 + * try to flush a few megs of memory. 434 + */ 435 + 436 + if (len>=3*PAGE_SIZE && scope<FLUSH_SCOPE_PAGE) 437 + scope=FLUSH_SCOPE_PAGE; 438 + if (len>=10*PAGE_SIZE && scope<FLUSH_SCOPE_ALL) 439 + scope=FLUSH_SCOPE_ALL; 440 + if (CPU_IS_040) { 441 + ret = cache_flush_040 (addr, scope, cache, len); 442 + } else if (CPU_IS_060) { 443 + ret = cache_flush_060 (addr, scope, cache, len); 444 + } 445 + } 446 + out: 447 + return ret; 448 + } 449 + 450 + asmlinkage int sys_getpagesize(void) 451 + { 452 + return PAGE_SIZE; 453 + } 454 + 455 + /* 456 + * Do a system call from kernel instead of calling sys_execve so we 457 + * end up with proper pt_regs. 458 + */ 459 + int kernel_execve(const char *filename, 460 + const char *const argv[], 461 + const char *const envp[]) 462 + { 463 + register long __res asm ("%d0") = __NR_execve; 464 + register long __a asm ("%d1") = (long)(filename); 465 + register long __b asm ("%d2") = (long)(argv); 466 + register long __c asm ("%d3") = (long)(envp); 467 + asm volatile ("trap #0" : "+d" (__res) 468 + : "d" (__a), "d" (__b), "d" (__c)); 469 + return __res; 470 + } 471 + 472 + asmlinkage unsigned long sys_get_thread_area(void) 473 + { 474 + return current_thread_info()->tp_value; 475 + } 476 + 477 + asmlinkage int sys_set_thread_area(unsigned long tp) 478 + { 479 + current_thread_info()->tp_value = tp; 480 + return 0; 481 + } 482 + 483 + /* This syscall gets its arguments in A0 (mem), D2 (oldval) and 484 + D1 (newval). */ 485 + asmlinkage int 486 + sys_atomic_cmpxchg_32(unsigned long newval, int oldval, int d3, int d4, int d5, 487 + unsigned long __user * mem) 488 + { 489 + /* This was borrowed from ARM's implementation. */ 490 + for (;;) { 491 + struct mm_struct *mm = current->mm; 492 + pgd_t *pgd; 493 + pmd_t *pmd; 494 + pte_t *pte; 495 + spinlock_t *ptl; 496 + unsigned long mem_value; 497 + 498 + down_read(&mm->mmap_sem); 499 + pgd = pgd_offset(mm, (unsigned long)mem); 500 + if (!pgd_present(*pgd)) 501 + goto bad_access; 502 + pmd = pmd_offset(pgd, (unsigned long)mem); 503 + if (!pmd_present(*pmd)) 504 + goto bad_access; 505 + pte = pte_offset_map_lock(mm, pmd, (unsigned long)mem, &ptl); 506 + if (!pte_present(*pte) || !pte_dirty(*pte) 507 + || !pte_write(*pte)) { 508 + pte_unmap_unlock(pte, ptl); 509 + goto bad_access; 510 + } 511 + 512 + mem_value = *mem; 513 + if (mem_value == oldval) 514 + *mem = newval; 515 + 516 + pte_unmap_unlock(pte, ptl); 517 + up_read(&mm->mmap_sem); 518 + return mem_value; 519 + 520 + bad_access: 521 + up_read(&mm->mmap_sem); 522 + /* This is not necessarily a bad access, we can get here if 523 + a memory we're trying to write to should be copied-on-write. 524 + Make the kernel do the necessary page stuff, then re-iterate. 525 + Simulate a write access fault to do that. */ 526 + { 527 + /* The first argument of the function corresponds to 528 + D1, which is the first field of struct pt_regs. */ 529 + struct pt_regs *fp = (struct pt_regs *)&newval; 530 + 531 + /* '3' is an RMW flag. */ 532 + if (do_page_fault(fp, (unsigned long)mem, 3)) 533 + /* If the do_page_fault() failed, we don't 534 + have anything meaningful to return. 535 + There should be a SIGSEGV pending for 536 + the process. */ 537 + return 0xdeadbeef; 538 + } 539 + } 540 + } 541 + 542 + asmlinkage int sys_atomic_barrier(void) 543 + { 544 + /* no code needed for uniprocs */ 545 + return 0; 546 + }
+5 -114
arch/m68k/kernel/time.c
··· 1 - /* 2 - * linux/arch/m68k/kernel/time.c 3 - * 4 - * Copyright (C) 1991, 1992, 1995 Linus Torvalds 5 - * 6 - * This file contains the m68k-specific time handling details. 7 - * Most of the stuff is located in the machine specific files. 8 - * 9 - * 1997-09-10 Updated NTP code according to technical memorandum Jan '96 10 - * "A Kernel Model for Precision Timekeeping" by Dave Mills 11 - */ 12 - 13 - #include <linux/errno.h> 14 - #include <linux/module.h> 15 - #include <linux/sched.h> 16 - #include <linux/kernel.h> 17 - #include <linux/param.h> 18 - #include <linux/string.h> 19 - #include <linux/mm.h> 20 - #include <linux/rtc.h> 21 - #include <linux/platform_device.h> 22 - 23 - #include <asm/machdep.h> 24 - #include <asm/io.h> 25 - #include <asm/irq_regs.h> 26 - 27 - #include <linux/time.h> 28 - #include <linux/timex.h> 29 - #include <linux/profile.h> 30 - 31 - static inline int set_rtc_mmss(unsigned long nowtime) 32 - { 33 - if (mach_set_clock_mmss) 34 - return mach_set_clock_mmss (nowtime); 35 - return -1; 36 - } 37 - 38 - /* 39 - * timer_interrupt() needs to keep up the real-time clock, 40 - * as well as call the "xtime_update()" routine every clocktick 41 - */ 42 - static irqreturn_t timer_interrupt(int irq, void *dummy) 43 - { 44 - xtime_update(1); 45 - update_process_times(user_mode(get_irq_regs())); 46 - profile_tick(CPU_PROFILING); 47 - 48 - #ifdef CONFIG_HEARTBEAT 49 - /* use power LED as a heartbeat instead -- much more useful 50 - for debugging -- based on the version for PReP by Cort */ 51 - /* acts like an actual heart beat -- ie thump-thump-pause... */ 52 - if (mach_heartbeat) { 53 - static unsigned cnt = 0, period = 0, dist = 0; 54 - 55 - if (cnt == 0 || cnt == dist) 56 - mach_heartbeat( 1 ); 57 - else if (cnt == 7 || cnt == dist+7) 58 - mach_heartbeat( 0 ); 59 - 60 - if (++cnt > period) { 61 - cnt = 0; 62 - /* The hyperbolic function below modifies the heartbeat period 63 - * length in dependency of the current (5min) load. It goes 64 - * through the points f(0)=126, f(1)=86, f(5)=51, 65 - * f(inf)->30. */ 66 - period = ((672<<FSHIFT)/(5*avenrun[0]+(7<<FSHIFT))) + 30; 67 - dist = period / 4; 68 - } 69 - } 70 - #endif /* CONFIG_HEARTBEAT */ 71 - return IRQ_HANDLED; 72 - } 73 - 74 - void read_persistent_clock(struct timespec *ts) 75 - { 76 - struct rtc_time time; 77 - ts->tv_sec = 0; 78 - ts->tv_nsec = 0; 79 - 80 - if (mach_hwclk) { 81 - mach_hwclk(0, &time); 82 - 83 - if ((time.tm_year += 1900) < 1970) 84 - time.tm_year += 100; 85 - ts->tv_sec = mktime(time.tm_year, time.tm_mon, time.tm_mday, 86 - time.tm_hour, time.tm_min, time.tm_sec); 87 - } 88 - } 89 - 90 - void __init time_init(void) 91 - { 92 - mach_sched_init(timer_interrupt); 93 - } 94 - 95 - u32 arch_gettimeoffset(void) 96 - { 97 - return mach_gettimeoffset() * 1000; 98 - } 99 - 100 - static int __init rtc_init(void) 101 - { 102 - struct platform_device *pdev; 103 - 104 - if (!mach_hwclk) 105 - return -ENODEV; 106 - 107 - pdev = platform_device_register_simple("rtc-generic", -1, NULL, 0); 108 - if (IS_ERR(pdev)) 109 - return PTR_ERR(pdev); 110 - 111 - return 0; 112 - } 113 - 114 - module_init(rtc_init);
··· 1 + #ifdef CONFIG_MMU 2 + #include "time_mm.c" 3 + #else 4 + #include "time_no.c" 5 + #endif
+114
arch/m68k/kernel/time_mm.c
···
··· 1 + /* 2 + * linux/arch/m68k/kernel/time.c 3 + * 4 + * Copyright (C) 1991, 1992, 1995 Linus Torvalds 5 + * 6 + * This file contains the m68k-specific time handling details. 7 + * Most of the stuff is located in the machine specific files. 8 + * 9 + * 1997-09-10 Updated NTP code according to technical memorandum Jan '96 10 + * "A Kernel Model for Precision Timekeeping" by Dave Mills 11 + */ 12 + 13 + #include <linux/errno.h> 14 + #include <linux/module.h> 15 + #include <linux/sched.h> 16 + #include <linux/kernel.h> 17 + #include <linux/param.h> 18 + #include <linux/string.h> 19 + #include <linux/mm.h> 20 + #include <linux/rtc.h> 21 + #include <linux/platform_device.h> 22 + 23 + #include <asm/machdep.h> 24 + #include <asm/io.h> 25 + #include <asm/irq_regs.h> 26 + 27 + #include <linux/time.h> 28 + #include <linux/timex.h> 29 + #include <linux/profile.h> 30 + 31 + static inline int set_rtc_mmss(unsigned long nowtime) 32 + { 33 + if (mach_set_clock_mmss) 34 + return mach_set_clock_mmss (nowtime); 35 + return -1; 36 + } 37 + 38 + /* 39 + * timer_interrupt() needs to keep up the real-time clock, 40 + * as well as call the "xtime_update()" routine every clocktick 41 + */ 42 + static irqreturn_t timer_interrupt(int irq, void *dummy) 43 + { 44 + xtime_update(1); 45 + update_process_times(user_mode(get_irq_regs())); 46 + profile_tick(CPU_PROFILING); 47 + 48 + #ifdef CONFIG_HEARTBEAT 49 + /* use power LED as a heartbeat instead -- much more useful 50 + for debugging -- based on the version for PReP by Cort */ 51 + /* acts like an actual heart beat -- ie thump-thump-pause... */ 52 + if (mach_heartbeat) { 53 + static unsigned cnt = 0, period = 0, dist = 0; 54 + 55 + if (cnt == 0 || cnt == dist) 56 + mach_heartbeat( 1 ); 57 + else if (cnt == 7 || cnt == dist+7) 58 + mach_heartbeat( 0 ); 59 + 60 + if (++cnt > period) { 61 + cnt = 0; 62 + /* The hyperbolic function below modifies the heartbeat period 63 + * length in dependency of the current (5min) load. It goes 64 + * through the points f(0)=126, f(1)=86, f(5)=51, 65 + * f(inf)->30. */ 66 + period = ((672<<FSHIFT)/(5*avenrun[0]+(7<<FSHIFT))) + 30; 67 + dist = period / 4; 68 + } 69 + } 70 + #endif /* CONFIG_HEARTBEAT */ 71 + return IRQ_HANDLED; 72 + } 73 + 74 + void read_persistent_clock(struct timespec *ts) 75 + { 76 + struct rtc_time time; 77 + ts->tv_sec = 0; 78 + ts->tv_nsec = 0; 79 + 80 + if (mach_hwclk) { 81 + mach_hwclk(0, &time); 82 + 83 + if ((time.tm_year += 1900) < 1970) 84 + time.tm_year += 100; 85 + ts->tv_sec = mktime(time.tm_year, time.tm_mon, time.tm_mday, 86 + time.tm_hour, time.tm_min, time.tm_sec); 87 + } 88 + } 89 + 90 + void __init time_init(void) 91 + { 92 + mach_sched_init(timer_interrupt); 93 + } 94 + 95 + u32 arch_gettimeoffset(void) 96 + { 97 + return mach_gettimeoffset() * 1000; 98 + } 99 + 100 + static int __init rtc_init(void) 101 + { 102 + struct platform_device *pdev; 103 + 104 + if (!mach_hwclk) 105 + return -ENODEV; 106 + 107 + pdev = platform_device_register_simple("rtc-generic", -1, NULL, 0); 108 + if (IS_ERR(pdev)) 109 + return PTR_ERR(pdev); 110 + 111 + return 0; 112 + } 113 + 114 + module_init(rtc_init);
+3 -1205
arch/m68k/kernel/traps.c
··· 1 - /* 2 - * linux/arch/m68k/kernel/traps.c 3 - * 4 - * Copyright (C) 1993, 1994 by Hamish Macdonald 5 - * 6 - * 68040 fixes by Michael Rausch 7 - * 68040 fixes by Martin Apel 8 - * 68040 fixes and writeback by Richard Zidlicky 9 - * 68060 fixes by Roman Hodek 10 - * 68060 fixes by Jesper Skov 11 - * 12 - * This file is subject to the terms and conditions of the GNU General Public 13 - * License. See the file COPYING in the main directory of this archive 14 - * for more details. 15 - */ 16 - 17 - /* 18 - * Sets up all exception vectors 19 - */ 20 - 21 - #include <linux/sched.h> 22 - #include <linux/signal.h> 23 - #include <linux/kernel.h> 24 - #include <linux/mm.h> 25 - #include <linux/module.h> 26 - #include <linux/user.h> 27 - #include <linux/string.h> 28 - #include <linux/linkage.h> 29 - #include <linux/init.h> 30 - #include <linux/ptrace.h> 31 - #include <linux/kallsyms.h> 32 - 33 - #include <asm/setup.h> 34 - #include <asm/fpu.h> 35 - #include <asm/system.h> 36 - #include <asm/uaccess.h> 37 - #include <asm/traps.h> 38 - #include <asm/pgalloc.h> 39 - #include <asm/machdep.h> 40 - #include <asm/siginfo.h> 41 - 42 - /* assembler routines */ 43 - asmlinkage void system_call(void); 44 - asmlinkage void buserr(void); 45 - asmlinkage void trap(void); 46 - asmlinkage void nmihandler(void); 47 - #ifdef CONFIG_M68KFPU_EMU 48 - asmlinkage void fpu_emu(void); 49 - #endif 50 - 51 - e_vector vectors[256]; 52 - 53 - /* nmi handler for the Amiga */ 54 - asm(".text\n" 55 - __ALIGN_STR "\n" 56 - "nmihandler: rte"); 57 - 58 - /* 59 - * this must be called very early as the kernel might 60 - * use some instruction that are emulated on the 060 61 - * and so we're prepared for early probe attempts (e.g. nf_init). 62 - */ 63 - void __init base_trap_init(void) 64 - { 65 - if (MACH_IS_SUN3X) { 66 - extern e_vector *sun3x_prom_vbr; 67 - 68 - __asm__ volatile ("movec %%vbr, %0" : "=r" (sun3x_prom_vbr)); 69 - } 70 - 71 - /* setup the exception vector table */ 72 - __asm__ volatile ("movec %0,%%vbr" : : "r" ((void*)vectors)); 73 - 74 - if (CPU_IS_060) { 75 - /* set up ISP entry points */ 76 - asmlinkage void unimp_vec(void) asm ("_060_isp_unimp"); 77 - 78 - vectors[VEC_UNIMPII] = unimp_vec; 79 - } 80 - 81 - vectors[VEC_BUSERR] = buserr; 82 - vectors[VEC_ILLEGAL] = trap; 83 - vectors[VEC_SYS] = system_call; 84 - } 85 - 86 - void __init trap_init (void) 87 - { 88 - int i; 89 - 90 - for (i = VEC_SPUR; i <= VEC_INT7; i++) 91 - vectors[i] = bad_inthandler; 92 - 93 - for (i = 0; i < VEC_USER; i++) 94 - if (!vectors[i]) 95 - vectors[i] = trap; 96 - 97 - for (i = VEC_USER; i < 256; i++) 98 - vectors[i] = bad_inthandler; 99 - 100 - #ifdef CONFIG_M68KFPU_EMU 101 - if (FPU_IS_EMU) 102 - vectors[VEC_LINE11] = fpu_emu; 103 - #endif 104 - 105 - if (CPU_IS_040 && !FPU_IS_EMU) { 106 - /* set up FPSP entry points */ 107 - asmlinkage void dz_vec(void) asm ("dz"); 108 - asmlinkage void inex_vec(void) asm ("inex"); 109 - asmlinkage void ovfl_vec(void) asm ("ovfl"); 110 - asmlinkage void unfl_vec(void) asm ("unfl"); 111 - asmlinkage void snan_vec(void) asm ("snan"); 112 - asmlinkage void operr_vec(void) asm ("operr"); 113 - asmlinkage void bsun_vec(void) asm ("bsun"); 114 - asmlinkage void fline_vec(void) asm ("fline"); 115 - asmlinkage void unsupp_vec(void) asm ("unsupp"); 116 - 117 - vectors[VEC_FPDIVZ] = dz_vec; 118 - vectors[VEC_FPIR] = inex_vec; 119 - vectors[VEC_FPOVER] = ovfl_vec; 120 - vectors[VEC_FPUNDER] = unfl_vec; 121 - vectors[VEC_FPNAN] = snan_vec; 122 - vectors[VEC_FPOE] = operr_vec; 123 - vectors[VEC_FPBRUC] = bsun_vec; 124 - vectors[VEC_LINE11] = fline_vec; 125 - vectors[VEC_FPUNSUP] = unsupp_vec; 126 - } 127 - 128 - if (CPU_IS_060 && !FPU_IS_EMU) { 129 - /* set up IFPSP entry points */ 130 - asmlinkage void snan_vec6(void) asm ("_060_fpsp_snan"); 131 - asmlinkage void operr_vec6(void) asm ("_060_fpsp_operr"); 132 - asmlinkage void ovfl_vec6(void) asm ("_060_fpsp_ovfl"); 133 - asmlinkage void unfl_vec6(void) asm ("_060_fpsp_unfl"); 134 - asmlinkage void dz_vec6(void) asm ("_060_fpsp_dz"); 135 - asmlinkage void inex_vec6(void) asm ("_060_fpsp_inex"); 136 - asmlinkage void fline_vec6(void) asm ("_060_fpsp_fline"); 137 - asmlinkage void unsupp_vec6(void) asm ("_060_fpsp_unsupp"); 138 - asmlinkage void effadd_vec6(void) asm ("_060_fpsp_effadd"); 139 - 140 - vectors[VEC_FPNAN] = snan_vec6; 141 - vectors[VEC_FPOE] = operr_vec6; 142 - vectors[VEC_FPOVER] = ovfl_vec6; 143 - vectors[VEC_FPUNDER] = unfl_vec6; 144 - vectors[VEC_FPDIVZ] = dz_vec6; 145 - vectors[VEC_FPIR] = inex_vec6; 146 - vectors[VEC_LINE11] = fline_vec6; 147 - vectors[VEC_FPUNSUP] = unsupp_vec6; 148 - vectors[VEC_UNIMPEA] = effadd_vec6; 149 - } 150 - 151 - /* if running on an amiga, make the NMI interrupt do nothing */ 152 - if (MACH_IS_AMIGA) { 153 - vectors[VEC_INT7] = nmihandler; 154 - } 155 - } 156 - 157 - 158 - static const char *vec_names[] = { 159 - [VEC_RESETSP] = "RESET SP", 160 - [VEC_RESETPC] = "RESET PC", 161 - [VEC_BUSERR] = "BUS ERROR", 162 - [VEC_ADDRERR] = "ADDRESS ERROR", 163 - [VEC_ILLEGAL] = "ILLEGAL INSTRUCTION", 164 - [VEC_ZERODIV] = "ZERO DIVIDE", 165 - [VEC_CHK] = "CHK", 166 - [VEC_TRAP] = "TRAPcc", 167 - [VEC_PRIV] = "PRIVILEGE VIOLATION", 168 - [VEC_TRACE] = "TRACE", 169 - [VEC_LINE10] = "LINE 1010", 170 - [VEC_LINE11] = "LINE 1111", 171 - [VEC_RESV12] = "UNASSIGNED RESERVED 12", 172 - [VEC_COPROC] = "COPROCESSOR PROTOCOL VIOLATION", 173 - [VEC_FORMAT] = "FORMAT ERROR", 174 - [VEC_UNINT] = "UNINITIALIZED INTERRUPT", 175 - [VEC_RESV16] = "UNASSIGNED RESERVED 16", 176 - [VEC_RESV17] = "UNASSIGNED RESERVED 17", 177 - [VEC_RESV18] = "UNASSIGNED RESERVED 18", 178 - [VEC_RESV19] = "UNASSIGNED RESERVED 19", 179 - [VEC_RESV20] = "UNASSIGNED RESERVED 20", 180 - [VEC_RESV21] = "UNASSIGNED RESERVED 21", 181 - [VEC_RESV22] = "UNASSIGNED RESERVED 22", 182 - [VEC_RESV23] = "UNASSIGNED RESERVED 23", 183 - [VEC_SPUR] = "SPURIOUS INTERRUPT", 184 - [VEC_INT1] = "LEVEL 1 INT", 185 - [VEC_INT2] = "LEVEL 2 INT", 186 - [VEC_INT3] = "LEVEL 3 INT", 187 - [VEC_INT4] = "LEVEL 4 INT", 188 - [VEC_INT5] = "LEVEL 5 INT", 189 - [VEC_INT6] = "LEVEL 6 INT", 190 - [VEC_INT7] = "LEVEL 7 INT", 191 - [VEC_SYS] = "SYSCALL", 192 - [VEC_TRAP1] = "TRAP #1", 193 - [VEC_TRAP2] = "TRAP #2", 194 - [VEC_TRAP3] = "TRAP #3", 195 - [VEC_TRAP4] = "TRAP #4", 196 - [VEC_TRAP5] = "TRAP #5", 197 - [VEC_TRAP6] = "TRAP #6", 198 - [VEC_TRAP7] = "TRAP #7", 199 - [VEC_TRAP8] = "TRAP #8", 200 - [VEC_TRAP9] = "TRAP #9", 201 - [VEC_TRAP10] = "TRAP #10", 202 - [VEC_TRAP11] = "TRAP #11", 203 - [VEC_TRAP12] = "TRAP #12", 204 - [VEC_TRAP13] = "TRAP #13", 205 - [VEC_TRAP14] = "TRAP #14", 206 - [VEC_TRAP15] = "TRAP #15", 207 - [VEC_FPBRUC] = "FPCP BSUN", 208 - [VEC_FPIR] = "FPCP INEXACT", 209 - [VEC_FPDIVZ] = "FPCP DIV BY 0", 210 - [VEC_FPUNDER] = "FPCP UNDERFLOW", 211 - [VEC_FPOE] = "FPCP OPERAND ERROR", 212 - [VEC_FPOVER] = "FPCP OVERFLOW", 213 - [VEC_FPNAN] = "FPCP SNAN", 214 - [VEC_FPUNSUP] = "FPCP UNSUPPORTED OPERATION", 215 - [VEC_MMUCFG] = "MMU CONFIGURATION ERROR", 216 - [VEC_MMUILL] = "MMU ILLEGAL OPERATION ERROR", 217 - [VEC_MMUACC] = "MMU ACCESS LEVEL VIOLATION ERROR", 218 - [VEC_RESV59] = "UNASSIGNED RESERVED 59", 219 - [VEC_UNIMPEA] = "UNASSIGNED RESERVED 60", 220 - [VEC_UNIMPII] = "UNASSIGNED RESERVED 61", 221 - [VEC_RESV62] = "UNASSIGNED RESERVED 62", 222 - [VEC_RESV63] = "UNASSIGNED RESERVED 63", 223 - }; 224 - 225 - static const char *space_names[] = { 226 - [0] = "Space 0", 227 - [USER_DATA] = "User Data", 228 - [USER_PROGRAM] = "User Program", 229 - #ifndef CONFIG_SUN3 230 - [3] = "Space 3", 231 #else 232 - [FC_CONTROL] = "Control", 233 - #endif 234 - [4] = "Space 4", 235 - [SUPER_DATA] = "Super Data", 236 - [SUPER_PROGRAM] = "Super Program", 237 - [CPU_SPACE] = "CPU" 238 - }; 239 - 240 - void die_if_kernel(char *,struct pt_regs *,int); 241 - asmlinkage int do_page_fault(struct pt_regs *regs, unsigned long address, 242 - unsigned long error_code); 243 - int send_fault_sig(struct pt_regs *regs); 244 - 245 - asmlinkage void trap_c(struct frame *fp); 246 - 247 - #if defined (CONFIG_M68060) 248 - static inline void access_error060 (struct frame *fp) 249 - { 250 - unsigned long fslw = fp->un.fmt4.pc; /* is really FSLW for access error */ 251 - 252 - #ifdef DEBUG 253 - printk("fslw=%#lx, fa=%#lx\n", fslw, fp->un.fmt4.effaddr); 254 - #endif 255 - 256 - if (fslw & MMU060_BPE) { 257 - /* branch prediction error -> clear branch cache */ 258 - __asm__ __volatile__ ("movec %/cacr,%/d0\n\t" 259 - "orl #0x00400000,%/d0\n\t" 260 - "movec %/d0,%/cacr" 261 - : : : "d0" ); 262 - /* return if there's no other error */ 263 - if (!(fslw & MMU060_ERR_BITS) && !(fslw & MMU060_SEE)) 264 - return; 265 - } 266 - 267 - if (fslw & (MMU060_DESC_ERR | MMU060_WP | MMU060_SP)) { 268 - unsigned long errorcode; 269 - unsigned long addr = fp->un.fmt4.effaddr; 270 - 271 - if (fslw & MMU060_MA) 272 - addr = (addr + PAGE_SIZE - 1) & PAGE_MASK; 273 - 274 - errorcode = 1; 275 - if (fslw & MMU060_DESC_ERR) { 276 - __flush_tlb040_one(addr); 277 - errorcode = 0; 278 - } 279 - if (fslw & MMU060_W) 280 - errorcode |= 2; 281 - #ifdef DEBUG 282 - printk("errorcode = %d\n", errorcode ); 283 - #endif 284 - do_page_fault(&fp->ptregs, addr, errorcode); 285 - } else if (fslw & (MMU060_SEE)){ 286 - /* Software Emulation Error. 287 - * fault during mem_read/mem_write in ifpsp060/os.S 288 - */ 289 - send_fault_sig(&fp->ptregs); 290 - } else if (!(fslw & (MMU060_RE|MMU060_WE)) || 291 - send_fault_sig(&fp->ptregs) > 0) { 292 - printk("pc=%#lx, fa=%#lx\n", fp->ptregs.pc, fp->un.fmt4.effaddr); 293 - printk( "68060 access error, fslw=%lx\n", fslw ); 294 - trap_c( fp ); 295 - } 296 - } 297 - #endif /* CONFIG_M68060 */ 298 - 299 - #if defined (CONFIG_M68040) 300 - static inline unsigned long probe040(int iswrite, unsigned long addr, int wbs) 301 - { 302 - unsigned long mmusr; 303 - mm_segment_t old_fs = get_fs(); 304 - 305 - set_fs(MAKE_MM_SEG(wbs)); 306 - 307 - if (iswrite) 308 - asm volatile (".chip 68040; ptestw (%0); .chip 68k" : : "a" (addr)); 309 - else 310 - asm volatile (".chip 68040; ptestr (%0); .chip 68k" : : "a" (addr)); 311 - 312 - asm volatile (".chip 68040; movec %%mmusr,%0; .chip 68k" : "=r" (mmusr)); 313 - 314 - set_fs(old_fs); 315 - 316 - return mmusr; 317 - } 318 - 319 - static inline int do_040writeback1(unsigned short wbs, unsigned long wba, 320 - unsigned long wbd) 321 - { 322 - int res = 0; 323 - mm_segment_t old_fs = get_fs(); 324 - 325 - /* set_fs can not be moved, otherwise put_user() may oops */ 326 - set_fs(MAKE_MM_SEG(wbs)); 327 - 328 - switch (wbs & WBSIZ_040) { 329 - case BA_SIZE_BYTE: 330 - res = put_user(wbd & 0xff, (char __user *)wba); 331 - break; 332 - case BA_SIZE_WORD: 333 - res = put_user(wbd & 0xffff, (short __user *)wba); 334 - break; 335 - case BA_SIZE_LONG: 336 - res = put_user(wbd, (int __user *)wba); 337 - break; 338 - } 339 - 340 - /* set_fs can not be moved, otherwise put_user() may oops */ 341 - set_fs(old_fs); 342 - 343 - 344 - #ifdef DEBUG 345 - printk("do_040writeback1, res=%d\n",res); 346 - #endif 347 - 348 - return res; 349 - } 350 - 351 - /* after an exception in a writeback the stack frame corresponding 352 - * to that exception is discarded, set a few bits in the old frame 353 - * to simulate what it should look like 354 - */ 355 - static inline void fix_xframe040(struct frame *fp, unsigned long wba, unsigned short wbs) 356 - { 357 - fp->un.fmt7.faddr = wba; 358 - fp->un.fmt7.ssw = wbs & 0xff; 359 - if (wba != current->thread.faddr) 360 - fp->un.fmt7.ssw |= MA_040; 361 - } 362 - 363 - static inline void do_040writebacks(struct frame *fp) 364 - { 365 - int res = 0; 366 - #if 0 367 - if (fp->un.fmt7.wb1s & WBV_040) 368 - printk("access_error040: cannot handle 1st writeback. oops.\n"); 369 - #endif 370 - 371 - if ((fp->un.fmt7.wb2s & WBV_040) && 372 - !(fp->un.fmt7.wb2s & WBTT_040)) { 373 - res = do_040writeback1(fp->un.fmt7.wb2s, fp->un.fmt7.wb2a, 374 - fp->un.fmt7.wb2d); 375 - if (res) 376 - fix_xframe040(fp, fp->un.fmt7.wb2a, fp->un.fmt7.wb2s); 377 - else 378 - fp->un.fmt7.wb2s = 0; 379 - } 380 - 381 - /* do the 2nd wb only if the first one was successful (except for a kernel wb) */ 382 - if (fp->un.fmt7.wb3s & WBV_040 && (!res || fp->un.fmt7.wb3s & 4)) { 383 - res = do_040writeback1(fp->un.fmt7.wb3s, fp->un.fmt7.wb3a, 384 - fp->un.fmt7.wb3d); 385 - if (res) 386 - { 387 - fix_xframe040(fp, fp->un.fmt7.wb3a, fp->un.fmt7.wb3s); 388 - 389 - fp->un.fmt7.wb2s = fp->un.fmt7.wb3s; 390 - fp->un.fmt7.wb3s &= (~WBV_040); 391 - fp->un.fmt7.wb2a = fp->un.fmt7.wb3a; 392 - fp->un.fmt7.wb2d = fp->un.fmt7.wb3d; 393 - } 394 - else 395 - fp->un.fmt7.wb3s = 0; 396 - } 397 - 398 - if (res) 399 - send_fault_sig(&fp->ptregs); 400 - } 401 - 402 - /* 403 - * called from sigreturn(), must ensure userspace code didn't 404 - * manipulate exception frame to circumvent protection, then complete 405 - * pending writebacks 406 - * we just clear TM2 to turn it into a userspace access 407 - */ 408 - asmlinkage void berr_040cleanup(struct frame *fp) 409 - { 410 - fp->un.fmt7.wb2s &= ~4; 411 - fp->un.fmt7.wb3s &= ~4; 412 - 413 - do_040writebacks(fp); 414 - } 415 - 416 - static inline void access_error040(struct frame *fp) 417 - { 418 - unsigned short ssw = fp->un.fmt7.ssw; 419 - unsigned long mmusr; 420 - 421 - #ifdef DEBUG 422 - printk("ssw=%#x, fa=%#lx\n", ssw, fp->un.fmt7.faddr); 423 - printk("wb1s=%#x, wb2s=%#x, wb3s=%#x\n", fp->un.fmt7.wb1s, 424 - fp->un.fmt7.wb2s, fp->un.fmt7.wb3s); 425 - printk ("wb2a=%lx, wb3a=%lx, wb2d=%lx, wb3d=%lx\n", 426 - fp->un.fmt7.wb2a, fp->un.fmt7.wb3a, 427 - fp->un.fmt7.wb2d, fp->un.fmt7.wb3d); 428 - #endif 429 - 430 - if (ssw & ATC_040) { 431 - unsigned long addr = fp->un.fmt7.faddr; 432 - unsigned long errorcode; 433 - 434 - /* 435 - * The MMU status has to be determined AFTER the address 436 - * has been corrected if there was a misaligned access (MA). 437 - */ 438 - if (ssw & MA_040) 439 - addr = (addr + 7) & -8; 440 - 441 - /* MMU error, get the MMUSR info for this access */ 442 - mmusr = probe040(!(ssw & RW_040), addr, ssw); 443 - #ifdef DEBUG 444 - printk("mmusr = %lx\n", mmusr); 445 - #endif 446 - errorcode = 1; 447 - if (!(mmusr & MMU_R_040)) { 448 - /* clear the invalid atc entry */ 449 - __flush_tlb040_one(addr); 450 - errorcode = 0; 451 - } 452 - 453 - /* despite what documentation seems to say, RMW 454 - * accesses have always both the LK and RW bits set */ 455 - if (!(ssw & RW_040) || (ssw & LK_040)) 456 - errorcode |= 2; 457 - 458 - if (do_page_fault(&fp->ptregs, addr, errorcode)) { 459 - #ifdef DEBUG 460 - printk("do_page_fault() !=0\n"); 461 - #endif 462 - if (user_mode(&fp->ptregs)){ 463 - /* delay writebacks after signal delivery */ 464 - #ifdef DEBUG 465 - printk(".. was usermode - return\n"); 466 - #endif 467 - return; 468 - } 469 - /* disable writeback into user space from kernel 470 - * (if do_page_fault didn't fix the mapping, 471 - * the writeback won't do good) 472 - */ 473 - disable_wb: 474 - #ifdef DEBUG 475 - printk(".. disabling wb2\n"); 476 - #endif 477 - if (fp->un.fmt7.wb2a == fp->un.fmt7.faddr) 478 - fp->un.fmt7.wb2s &= ~WBV_040; 479 - if (fp->un.fmt7.wb3a == fp->un.fmt7.faddr) 480 - fp->un.fmt7.wb3s &= ~WBV_040; 481 - } 482 - } else { 483 - /* In case of a bus error we either kill the process or expect 484 - * the kernel to catch the fault, which then is also responsible 485 - * for cleaning up the mess. 486 - */ 487 - current->thread.signo = SIGBUS; 488 - current->thread.faddr = fp->un.fmt7.faddr; 489 - if (send_fault_sig(&fp->ptregs) >= 0) 490 - printk("68040 bus error (ssw=%x, faddr=%lx)\n", ssw, 491 - fp->un.fmt7.faddr); 492 - goto disable_wb; 493 - } 494 - 495 - do_040writebacks(fp); 496 - } 497 - #endif /* CONFIG_M68040 */ 498 - 499 - #if defined(CONFIG_SUN3) 500 - #include <asm/sun3mmu.h> 501 - 502 - extern int mmu_emu_handle_fault (unsigned long, int, int); 503 - 504 - /* sun3 version of bus_error030 */ 505 - 506 - static inline void bus_error030 (struct frame *fp) 507 - { 508 - unsigned char buserr_type = sun3_get_buserr (); 509 - unsigned long addr, errorcode; 510 - unsigned short ssw = fp->un.fmtb.ssw; 511 - extern unsigned long _sun3_map_test_start, _sun3_map_test_end; 512 - 513 - #ifdef DEBUG 514 - if (ssw & (FC | FB)) 515 - printk ("Instruction fault at %#010lx\n", 516 - ssw & FC ? 517 - fp->ptregs.format == 0xa ? fp->ptregs.pc + 2 : fp->un.fmtb.baddr - 2 518 - : 519 - fp->ptregs.format == 0xa ? fp->ptregs.pc + 4 : fp->un.fmtb.baddr); 520 - if (ssw & DF) 521 - printk ("Data %s fault at %#010lx in %s (pc=%#lx)\n", 522 - ssw & RW ? "read" : "write", 523 - fp->un.fmtb.daddr, 524 - space_names[ssw & DFC], fp->ptregs.pc); 525 - #endif 526 - 527 - /* 528 - * Check if this page should be demand-mapped. This needs to go before 529 - * the testing for a bad kernel-space access (demand-mapping applies 530 - * to kernel accesses too). 531 - */ 532 - 533 - if ((ssw & DF) 534 - && (buserr_type & (SUN3_BUSERR_PROTERR | SUN3_BUSERR_INVALID))) { 535 - if (mmu_emu_handle_fault (fp->un.fmtb.daddr, ssw & RW, 0)) 536 - return; 537 - } 538 - 539 - /* Check for kernel-space pagefault (BAD). */ 540 - if (fp->ptregs.sr & PS_S) { 541 - /* kernel fault must be a data fault to user space */ 542 - if (! ((ssw & DF) && ((ssw & DFC) == USER_DATA))) { 543 - // try checking the kernel mappings before surrender 544 - if (mmu_emu_handle_fault (fp->un.fmtb.daddr, ssw & RW, 1)) 545 - return; 546 - /* instruction fault or kernel data fault! */ 547 - if (ssw & (FC | FB)) 548 - printk ("Instruction fault at %#010lx\n", 549 - fp->ptregs.pc); 550 - if (ssw & DF) { 551 - /* was this fault incurred testing bus mappings? */ 552 - if((fp->ptregs.pc >= (unsigned long)&_sun3_map_test_start) && 553 - (fp->ptregs.pc <= (unsigned long)&_sun3_map_test_end)) { 554 - send_fault_sig(&fp->ptregs); 555 - return; 556 - } 557 - 558 - printk ("Data %s fault at %#010lx in %s (pc=%#lx)\n", 559 - ssw & RW ? "read" : "write", 560 - fp->un.fmtb.daddr, 561 - space_names[ssw & DFC], fp->ptregs.pc); 562 - } 563 - printk ("BAD KERNEL BUSERR\n"); 564 - 565 - die_if_kernel("Oops", &fp->ptregs,0); 566 - force_sig(SIGKILL, current); 567 - return; 568 - } 569 - } else { 570 - /* user fault */ 571 - if (!(ssw & (FC | FB)) && !(ssw & DF)) 572 - /* not an instruction fault or data fault! BAD */ 573 - panic ("USER BUSERR w/o instruction or data fault"); 574 - } 575 - 576 - 577 - /* First handle the data fault, if any. */ 578 - if (ssw & DF) { 579 - addr = fp->un.fmtb.daddr; 580 - 581 - // errorcode bit 0: 0 -> no page 1 -> protection fault 582 - // errorcode bit 1: 0 -> read fault 1 -> write fault 583 - 584 - // (buserr_type & SUN3_BUSERR_PROTERR) -> protection fault 585 - // (buserr_type & SUN3_BUSERR_INVALID) -> invalid page fault 586 - 587 - if (buserr_type & SUN3_BUSERR_PROTERR) 588 - errorcode = 0x01; 589 - else if (buserr_type & SUN3_BUSERR_INVALID) 590 - errorcode = 0x00; 591 - else { 592 - #ifdef DEBUG 593 - printk ("*** unexpected busfault type=%#04x\n", buserr_type); 594 - printk ("invalid %s access at %#lx from pc %#lx\n", 595 - !(ssw & RW) ? "write" : "read", addr, 596 - fp->ptregs.pc); 597 - #endif 598 - die_if_kernel ("Oops", &fp->ptregs, buserr_type); 599 - force_sig (SIGBUS, current); 600 - return; 601 - } 602 - 603 - //todo: wtf is RM bit? --m 604 - if (!(ssw & RW) || ssw & RM) 605 - errorcode |= 0x02; 606 - 607 - /* Handle page fault. */ 608 - do_page_fault (&fp->ptregs, addr, errorcode); 609 - 610 - /* Retry the data fault now. */ 611 - return; 612 - } 613 - 614 - /* Now handle the instruction fault. */ 615 - 616 - /* Get the fault address. */ 617 - if (fp->ptregs.format == 0xA) 618 - addr = fp->ptregs.pc + 4; 619 - else 620 - addr = fp->un.fmtb.baddr; 621 - if (ssw & FC) 622 - addr -= 2; 623 - 624 - if (buserr_type & SUN3_BUSERR_INVALID) { 625 - if (!mmu_emu_handle_fault (fp->un.fmtb.daddr, 1, 0)) 626 - do_page_fault (&fp->ptregs, addr, 0); 627 - } else { 628 - #ifdef DEBUG 629 - printk ("protection fault on insn access (segv).\n"); 630 - #endif 631 - force_sig (SIGSEGV, current); 632 - } 633 - } 634 - #else 635 - #if defined(CPU_M68020_OR_M68030) 636 - static inline void bus_error030 (struct frame *fp) 637 - { 638 - volatile unsigned short temp; 639 - unsigned short mmusr; 640 - unsigned long addr, errorcode; 641 - unsigned short ssw = fp->un.fmtb.ssw; 642 - #ifdef DEBUG 643 - unsigned long desc; 644 - 645 - printk ("pid = %x ", current->pid); 646 - printk ("SSW=%#06x ", ssw); 647 - 648 - if (ssw & (FC | FB)) 649 - printk ("Instruction fault at %#010lx\n", 650 - ssw & FC ? 651 - fp->ptregs.format == 0xa ? fp->ptregs.pc + 2 : fp->un.fmtb.baddr - 2 652 - : 653 - fp->ptregs.format == 0xa ? fp->ptregs.pc + 4 : fp->un.fmtb.baddr); 654 - if (ssw & DF) 655 - printk ("Data %s fault at %#010lx in %s (pc=%#lx)\n", 656 - ssw & RW ? "read" : "write", 657 - fp->un.fmtb.daddr, 658 - space_names[ssw & DFC], fp->ptregs.pc); 659 - #endif 660 - 661 - /* ++andreas: If a data fault and an instruction fault happen 662 - at the same time map in both pages. */ 663 - 664 - /* First handle the data fault, if any. */ 665 - if (ssw & DF) { 666 - addr = fp->un.fmtb.daddr; 667 - 668 - #ifdef DEBUG 669 - asm volatile ("ptestr %3,%2@,#7,%0\n\t" 670 - "pmove %%psr,%1@" 671 - : "=a&" (desc) 672 - : "a" (&temp), "a" (addr), "d" (ssw)); 673 - #else 674 - asm volatile ("ptestr %2,%1@,#7\n\t" 675 - "pmove %%psr,%0@" 676 - : : "a" (&temp), "a" (addr), "d" (ssw)); 677 - #endif 678 - mmusr = temp; 679 - 680 - #ifdef DEBUG 681 - printk("mmusr is %#x for addr %#lx in task %p\n", 682 - mmusr, addr, current); 683 - printk("descriptor address is %#lx, contents %#lx\n", 684 - __va(desc), *(unsigned long *)__va(desc)); 685 - #endif 686 - 687 - errorcode = (mmusr & MMU_I) ? 0 : 1; 688 - if (!(ssw & RW) || (ssw & RM)) 689 - errorcode |= 2; 690 - 691 - if (mmusr & (MMU_I | MMU_WP)) { 692 - if (ssw & 4) { 693 - printk("Data %s fault at %#010lx in %s (pc=%#lx)\n", 694 - ssw & RW ? "read" : "write", 695 - fp->un.fmtb.daddr, 696 - space_names[ssw & DFC], fp->ptregs.pc); 697 - goto buserr; 698 - } 699 - /* Don't try to do anything further if an exception was 700 - handled. */ 701 - if (do_page_fault (&fp->ptregs, addr, errorcode) < 0) 702 - return; 703 - } else if (!(mmusr & MMU_I)) { 704 - /* probably a 020 cas fault */ 705 - if (!(ssw & RM) && send_fault_sig(&fp->ptregs) > 0) 706 - printk("unexpected bus error (%#x,%#x)\n", ssw, mmusr); 707 - } else if (mmusr & (MMU_B|MMU_L|MMU_S)) { 708 - printk("invalid %s access at %#lx from pc %#lx\n", 709 - !(ssw & RW) ? "write" : "read", addr, 710 - fp->ptregs.pc); 711 - die_if_kernel("Oops",&fp->ptregs,mmusr); 712 - force_sig(SIGSEGV, current); 713 - return; 714 - } else { 715 - #if 0 716 - static volatile long tlong; 717 - #endif 718 - 719 - printk("weird %s access at %#lx from pc %#lx (ssw is %#x)\n", 720 - !(ssw & RW) ? "write" : "read", addr, 721 - fp->ptregs.pc, ssw); 722 - asm volatile ("ptestr #1,%1@,#0\n\t" 723 - "pmove %%psr,%0@" 724 - : /* no outputs */ 725 - : "a" (&temp), "a" (addr)); 726 - mmusr = temp; 727 - 728 - printk ("level 0 mmusr is %#x\n", mmusr); 729 - #if 0 730 - asm volatile ("pmove %%tt0,%0@" 731 - : /* no outputs */ 732 - : "a" (&tlong)); 733 - printk("tt0 is %#lx, ", tlong); 734 - asm volatile ("pmove %%tt1,%0@" 735 - : /* no outputs */ 736 - : "a" (&tlong)); 737 - printk("tt1 is %#lx\n", tlong); 738 - #endif 739 - #ifdef DEBUG 740 - printk("Unknown SIGSEGV - 1\n"); 741 - #endif 742 - die_if_kernel("Oops",&fp->ptregs,mmusr); 743 - force_sig(SIGSEGV, current); 744 - return; 745 - } 746 - 747 - /* setup an ATC entry for the access about to be retried */ 748 - if (!(ssw & RW) || (ssw & RM)) 749 - asm volatile ("ploadw %1,%0@" : /* no outputs */ 750 - : "a" (addr), "d" (ssw)); 751 - else 752 - asm volatile ("ploadr %1,%0@" : /* no outputs */ 753 - : "a" (addr), "d" (ssw)); 754 - } 755 - 756 - /* Now handle the instruction fault. */ 757 - 758 - if (!(ssw & (FC|FB))) 759 - return; 760 - 761 - if (fp->ptregs.sr & PS_S) { 762 - printk("Instruction fault at %#010lx\n", 763 - fp->ptregs.pc); 764 - buserr: 765 - printk ("BAD KERNEL BUSERR\n"); 766 - die_if_kernel("Oops",&fp->ptregs,0); 767 - force_sig(SIGKILL, current); 768 - return; 769 - } 770 - 771 - /* get the fault address */ 772 - if (fp->ptregs.format == 10) 773 - addr = fp->ptregs.pc + 4; 774 - else 775 - addr = fp->un.fmtb.baddr; 776 - if (ssw & FC) 777 - addr -= 2; 778 - 779 - if ((ssw & DF) && ((addr ^ fp->un.fmtb.daddr) & PAGE_MASK) == 0) 780 - /* Insn fault on same page as data fault. But we 781 - should still create the ATC entry. */ 782 - goto create_atc_entry; 783 - 784 - #ifdef DEBUG 785 - asm volatile ("ptestr #1,%2@,#7,%0\n\t" 786 - "pmove %%psr,%1@" 787 - : "=a&" (desc) 788 - : "a" (&temp), "a" (addr)); 789 - #else 790 - asm volatile ("ptestr #1,%1@,#7\n\t" 791 - "pmove %%psr,%0@" 792 - : : "a" (&temp), "a" (addr)); 793 - #endif 794 - mmusr = temp; 795 - 796 - #ifdef DEBUG 797 - printk ("mmusr is %#x for addr %#lx in task %p\n", 798 - mmusr, addr, current); 799 - printk ("descriptor address is %#lx, contents %#lx\n", 800 - __va(desc), *(unsigned long *)__va(desc)); 801 - #endif 802 - 803 - if (mmusr & MMU_I) 804 - do_page_fault (&fp->ptregs, addr, 0); 805 - else if (mmusr & (MMU_B|MMU_L|MMU_S)) { 806 - printk ("invalid insn access at %#lx from pc %#lx\n", 807 - addr, fp->ptregs.pc); 808 - #ifdef DEBUG 809 - printk("Unknown SIGSEGV - 2\n"); 810 - #endif 811 - die_if_kernel("Oops",&fp->ptregs,mmusr); 812 - force_sig(SIGSEGV, current); 813 - return; 814 - } 815 - 816 - create_atc_entry: 817 - /* setup an ATC entry for the access about to be retried */ 818 - asm volatile ("ploadr #2,%0@" : /* no outputs */ 819 - : "a" (addr)); 820 - } 821 - #endif /* CPU_M68020_OR_M68030 */ 822 - #endif /* !CONFIG_SUN3 */ 823 - 824 - asmlinkage void buserr_c(struct frame *fp) 825 - { 826 - /* Only set esp0 if coming from user mode */ 827 - if (user_mode(&fp->ptregs)) 828 - current->thread.esp0 = (unsigned long) fp; 829 - 830 - #ifdef DEBUG 831 - printk ("*** Bus Error *** Format is %x\n", fp->ptregs.format); 832 - #endif 833 - 834 - switch (fp->ptregs.format) { 835 - #if defined (CONFIG_M68060) 836 - case 4: /* 68060 access error */ 837 - access_error060 (fp); 838 - break; 839 - #endif 840 - #if defined (CONFIG_M68040) 841 - case 0x7: /* 68040 access error */ 842 - access_error040 (fp); 843 - break; 844 - #endif 845 - #if defined (CPU_M68020_OR_M68030) 846 - case 0xa: 847 - case 0xb: 848 - bus_error030 (fp); 849 - break; 850 - #endif 851 - default: 852 - die_if_kernel("bad frame format",&fp->ptregs,0); 853 - #ifdef DEBUG 854 - printk("Unknown SIGSEGV - 4\n"); 855 - #endif 856 - force_sig(SIGSEGV, current); 857 - } 858 - } 859 - 860 - 861 - static int kstack_depth_to_print = 48; 862 - 863 - void show_trace(unsigned long *stack) 864 - { 865 - unsigned long *endstack; 866 - unsigned long addr; 867 - int i; 868 - 869 - printk("Call Trace:"); 870 - addr = (unsigned long)stack + THREAD_SIZE - 1; 871 - endstack = (unsigned long *)(addr & -THREAD_SIZE); 872 - i = 0; 873 - while (stack + 1 <= endstack) { 874 - addr = *stack++; 875 - /* 876 - * If the address is either in the text segment of the 877 - * kernel, or in the region which contains vmalloc'ed 878 - * memory, it *may* be the address of a calling 879 - * routine; if so, print it so that someone tracing 880 - * down the cause of the crash will be able to figure 881 - * out the call path that was taken. 882 - */ 883 - if (__kernel_text_address(addr)) { 884 - #ifndef CONFIG_KALLSYMS 885 - if (i % 5 == 0) 886 - printk("\n "); 887 - #endif 888 - printk(" [<%08lx>] %pS\n", addr, (void *)addr); 889 - i++; 890 - } 891 - } 892 - printk("\n"); 893 - } 894 - 895 - void show_registers(struct pt_regs *regs) 896 - { 897 - struct frame *fp = (struct frame *)regs; 898 - mm_segment_t old_fs = get_fs(); 899 - u16 c, *cp; 900 - unsigned long addr; 901 - int i; 902 - 903 - print_modules(); 904 - printk("PC: [<%08lx>] %pS\n", regs->pc, (void *)regs->pc); 905 - printk("SR: %04x SP: %p a2: %08lx\n", regs->sr, regs, regs->a2); 906 - printk("d0: %08lx d1: %08lx d2: %08lx d3: %08lx\n", 907 - regs->d0, regs->d1, regs->d2, regs->d3); 908 - printk("d4: %08lx d5: %08lx a0: %08lx a1: %08lx\n", 909 - regs->d4, regs->d5, regs->a0, regs->a1); 910 - 911 - printk("Process %s (pid: %d, task=%p)\n", 912 - current->comm, task_pid_nr(current), current); 913 - addr = (unsigned long)&fp->un; 914 - printk("Frame format=%X ", regs->format); 915 - switch (regs->format) { 916 - case 0x2: 917 - printk("instr addr=%08lx\n", fp->un.fmt2.iaddr); 918 - addr += sizeof(fp->un.fmt2); 919 - break; 920 - case 0x3: 921 - printk("eff addr=%08lx\n", fp->un.fmt3.effaddr); 922 - addr += sizeof(fp->un.fmt3); 923 - break; 924 - case 0x4: 925 - printk((CPU_IS_060 ? "fault addr=%08lx fslw=%08lx\n" 926 - : "eff addr=%08lx pc=%08lx\n"), 927 - fp->un.fmt4.effaddr, fp->un.fmt4.pc); 928 - addr += sizeof(fp->un.fmt4); 929 - break; 930 - case 0x7: 931 - printk("eff addr=%08lx ssw=%04x faddr=%08lx\n", 932 - fp->un.fmt7.effaddr, fp->un.fmt7.ssw, fp->un.fmt7.faddr); 933 - printk("wb 1 stat/addr/data: %04x %08lx %08lx\n", 934 - fp->un.fmt7.wb1s, fp->un.fmt7.wb1a, fp->un.fmt7.wb1dpd0); 935 - printk("wb 2 stat/addr/data: %04x %08lx %08lx\n", 936 - fp->un.fmt7.wb2s, fp->un.fmt7.wb2a, fp->un.fmt7.wb2d); 937 - printk("wb 3 stat/addr/data: %04x %08lx %08lx\n", 938 - fp->un.fmt7.wb3s, fp->un.fmt7.wb3a, fp->un.fmt7.wb3d); 939 - printk("push data: %08lx %08lx %08lx %08lx\n", 940 - fp->un.fmt7.wb1dpd0, fp->un.fmt7.pd1, fp->un.fmt7.pd2, 941 - fp->un.fmt7.pd3); 942 - addr += sizeof(fp->un.fmt7); 943 - break; 944 - case 0x9: 945 - printk("instr addr=%08lx\n", fp->un.fmt9.iaddr); 946 - addr += sizeof(fp->un.fmt9); 947 - break; 948 - case 0xa: 949 - printk("ssw=%04x isc=%04x isb=%04x daddr=%08lx dobuf=%08lx\n", 950 - fp->un.fmta.ssw, fp->un.fmta.isc, fp->un.fmta.isb, 951 - fp->un.fmta.daddr, fp->un.fmta.dobuf); 952 - addr += sizeof(fp->un.fmta); 953 - break; 954 - case 0xb: 955 - printk("ssw=%04x isc=%04x isb=%04x daddr=%08lx dobuf=%08lx\n", 956 - fp->un.fmtb.ssw, fp->un.fmtb.isc, fp->un.fmtb.isb, 957 - fp->un.fmtb.daddr, fp->un.fmtb.dobuf); 958 - printk("baddr=%08lx dibuf=%08lx ver=%x\n", 959 - fp->un.fmtb.baddr, fp->un.fmtb.dibuf, fp->un.fmtb.ver); 960 - addr += sizeof(fp->un.fmtb); 961 - break; 962 - default: 963 - printk("\n"); 964 - } 965 - show_stack(NULL, (unsigned long *)addr); 966 - 967 - printk("Code:"); 968 - set_fs(KERNEL_DS); 969 - cp = (u16 *)regs->pc; 970 - for (i = -8; i < 16; i++) { 971 - if (get_user(c, cp + i) && i >= 0) { 972 - printk(" Bad PC value."); 973 - break; 974 - } 975 - printk(i ? " %04x" : " <%04x>", c); 976 - } 977 - set_fs(old_fs); 978 - printk ("\n"); 979 - } 980 - 981 - void show_stack(struct task_struct *task, unsigned long *stack) 982 - { 983 - unsigned long *p; 984 - unsigned long *endstack; 985 - int i; 986 - 987 - if (!stack) { 988 - if (task) 989 - stack = (unsigned long *)task->thread.esp0; 990 - else 991 - stack = (unsigned long *)&stack; 992 - } 993 - endstack = (unsigned long *)(((unsigned long)stack + THREAD_SIZE - 1) & -THREAD_SIZE); 994 - 995 - printk("Stack from %08lx:", (unsigned long)stack); 996 - p = stack; 997 - for (i = 0; i < kstack_depth_to_print; i++) { 998 - if (p + 1 > endstack) 999 - break; 1000 - if (i % 8 == 0) 1001 - printk("\n "); 1002 - printk(" %08lx", *p++); 1003 - } 1004 - printk("\n"); 1005 - show_trace(stack); 1006 - } 1007 - 1008 - /* 1009 - * The architecture-independent backtrace generator 1010 - */ 1011 - void dump_stack(void) 1012 - { 1013 - unsigned long stack; 1014 - 1015 - show_trace(&stack); 1016 - } 1017 - 1018 - EXPORT_SYMBOL(dump_stack); 1019 - 1020 - void bad_super_trap (struct frame *fp) 1021 - { 1022 - console_verbose(); 1023 - if (fp->ptregs.vector < 4 * ARRAY_SIZE(vec_names)) 1024 - printk ("*** %s *** FORMAT=%X\n", 1025 - vec_names[(fp->ptregs.vector) >> 2], 1026 - fp->ptregs.format); 1027 - else 1028 - printk ("*** Exception %d *** FORMAT=%X\n", 1029 - (fp->ptregs.vector) >> 2, 1030 - fp->ptregs.format); 1031 - if (fp->ptregs.vector >> 2 == VEC_ADDRERR && CPU_IS_020_OR_030) { 1032 - unsigned short ssw = fp->un.fmtb.ssw; 1033 - 1034 - printk ("SSW=%#06x ", ssw); 1035 - 1036 - if (ssw & RC) 1037 - printk ("Pipe stage C instruction fault at %#010lx\n", 1038 - (fp->ptregs.format) == 0xA ? 1039 - fp->ptregs.pc + 2 : fp->un.fmtb.baddr - 2); 1040 - if (ssw & RB) 1041 - printk ("Pipe stage B instruction fault at %#010lx\n", 1042 - (fp->ptregs.format) == 0xA ? 1043 - fp->ptregs.pc + 4 : fp->un.fmtb.baddr); 1044 - if (ssw & DF) 1045 - printk ("Data %s fault at %#010lx in %s (pc=%#lx)\n", 1046 - ssw & RW ? "read" : "write", 1047 - fp->un.fmtb.daddr, space_names[ssw & DFC], 1048 - fp->ptregs.pc); 1049 - } 1050 - printk ("Current process id is %d\n", task_pid_nr(current)); 1051 - die_if_kernel("BAD KERNEL TRAP", &fp->ptregs, 0); 1052 - } 1053 - 1054 - asmlinkage void trap_c(struct frame *fp) 1055 - { 1056 - int sig; 1057 - siginfo_t info; 1058 - 1059 - if (fp->ptregs.sr & PS_S) { 1060 - if (fp->ptregs.vector == VEC_TRACE << 2) { 1061 - /* traced a trapping instruction on a 68020/30, 1062 - * real exception will be executed afterwards. 1063 - */ 1064 - } else if (!handle_kernel_fault(&fp->ptregs)) 1065 - bad_super_trap(fp); 1066 - return; 1067 - } 1068 - 1069 - /* send the appropriate signal to the user program */ 1070 - switch ((fp->ptregs.vector) >> 2) { 1071 - case VEC_ADDRERR: 1072 - info.si_code = BUS_ADRALN; 1073 - sig = SIGBUS; 1074 - break; 1075 - case VEC_ILLEGAL: 1076 - case VEC_LINE10: 1077 - case VEC_LINE11: 1078 - info.si_code = ILL_ILLOPC; 1079 - sig = SIGILL; 1080 - break; 1081 - case VEC_PRIV: 1082 - info.si_code = ILL_PRVOPC; 1083 - sig = SIGILL; 1084 - break; 1085 - case VEC_COPROC: 1086 - info.si_code = ILL_COPROC; 1087 - sig = SIGILL; 1088 - break; 1089 - case VEC_TRAP1: 1090 - case VEC_TRAP2: 1091 - case VEC_TRAP3: 1092 - case VEC_TRAP4: 1093 - case VEC_TRAP5: 1094 - case VEC_TRAP6: 1095 - case VEC_TRAP7: 1096 - case VEC_TRAP8: 1097 - case VEC_TRAP9: 1098 - case VEC_TRAP10: 1099 - case VEC_TRAP11: 1100 - case VEC_TRAP12: 1101 - case VEC_TRAP13: 1102 - case VEC_TRAP14: 1103 - info.si_code = ILL_ILLTRP; 1104 - sig = SIGILL; 1105 - break; 1106 - case VEC_FPBRUC: 1107 - case VEC_FPOE: 1108 - case VEC_FPNAN: 1109 - info.si_code = FPE_FLTINV; 1110 - sig = SIGFPE; 1111 - break; 1112 - case VEC_FPIR: 1113 - info.si_code = FPE_FLTRES; 1114 - sig = SIGFPE; 1115 - break; 1116 - case VEC_FPDIVZ: 1117 - info.si_code = FPE_FLTDIV; 1118 - sig = SIGFPE; 1119 - break; 1120 - case VEC_FPUNDER: 1121 - info.si_code = FPE_FLTUND; 1122 - sig = SIGFPE; 1123 - break; 1124 - case VEC_FPOVER: 1125 - info.si_code = FPE_FLTOVF; 1126 - sig = SIGFPE; 1127 - break; 1128 - case VEC_ZERODIV: 1129 - info.si_code = FPE_INTDIV; 1130 - sig = SIGFPE; 1131 - break; 1132 - case VEC_CHK: 1133 - case VEC_TRAP: 1134 - info.si_code = FPE_INTOVF; 1135 - sig = SIGFPE; 1136 - break; 1137 - case VEC_TRACE: /* ptrace single step */ 1138 - info.si_code = TRAP_TRACE; 1139 - sig = SIGTRAP; 1140 - break; 1141 - case VEC_TRAP15: /* breakpoint */ 1142 - info.si_code = TRAP_BRKPT; 1143 - sig = SIGTRAP; 1144 - break; 1145 - default: 1146 - info.si_code = ILL_ILLOPC; 1147 - sig = SIGILL; 1148 - break; 1149 - } 1150 - info.si_signo = sig; 1151 - info.si_errno = 0; 1152 - switch (fp->ptregs.format) { 1153 - default: 1154 - info.si_addr = (void *) fp->ptregs.pc; 1155 - break; 1156 - case 2: 1157 - info.si_addr = (void *) fp->un.fmt2.iaddr; 1158 - break; 1159 - case 7: 1160 - info.si_addr = (void *) fp->un.fmt7.effaddr; 1161 - break; 1162 - case 9: 1163 - info.si_addr = (void *) fp->un.fmt9.iaddr; 1164 - break; 1165 - case 10: 1166 - info.si_addr = (void *) fp->un.fmta.daddr; 1167 - break; 1168 - case 11: 1169 - info.si_addr = (void *) fp->un.fmtb.daddr; 1170 - break; 1171 - } 1172 - force_sig_info (sig, &info, current); 1173 - } 1174 - 1175 - void die_if_kernel (char *str, struct pt_regs *fp, int nr) 1176 - { 1177 - if (!(fp->sr & PS_S)) 1178 - return; 1179 - 1180 - console_verbose(); 1181 - printk("%s: %08x\n",str,nr); 1182 - show_registers(fp); 1183 - add_taint(TAINT_DIE); 1184 - do_exit(SIGSEGV); 1185 - } 1186 - 1187 - /* 1188 - * This function is called if an error occur while accessing 1189 - * user-space from the fpsp040 code. 1190 - */ 1191 - asmlinkage void fpsp040_die(void) 1192 - { 1193 - do_exit(SIGSEGV); 1194 - } 1195 - 1196 - #ifdef CONFIG_M68KFPU_EMU 1197 - asmlinkage void fpemu_signal(int signal, int code, void *addr) 1198 - { 1199 - siginfo_t info; 1200 - 1201 - info.si_signo = signal; 1202 - info.si_errno = 0; 1203 - info.si_code = code; 1204 - info.si_addr = addr; 1205 - force_sig_info(signal, &info, current); 1206 - } 1207 #endif
··· 1 + #ifdef CONFIG_MMU 2 + #include "traps_mm.c" 3 #else 4 + #include "traps_no.c" 5 #endif
+1207
arch/m68k/kernel/traps_mm.c
···
··· 1 + /* 2 + * linux/arch/m68k/kernel/traps.c 3 + * 4 + * Copyright (C) 1993, 1994 by Hamish Macdonald 5 + * 6 + * 68040 fixes by Michael Rausch 7 + * 68040 fixes by Martin Apel 8 + * 68040 fixes and writeback by Richard Zidlicky 9 + * 68060 fixes by Roman Hodek 10 + * 68060 fixes by Jesper Skov 11 + * 12 + * This file is subject to the terms and conditions of the GNU General Public 13 + * License. See the file COPYING in the main directory of this archive 14 + * for more details. 15 + */ 16 + 17 + /* 18 + * Sets up all exception vectors 19 + */ 20 + 21 + #include <linux/sched.h> 22 + #include <linux/signal.h> 23 + #include <linux/kernel.h> 24 + #include <linux/mm.h> 25 + #include <linux/module.h> 26 + #include <linux/user.h> 27 + #include <linux/string.h> 28 + #include <linux/linkage.h> 29 + #include <linux/init.h> 30 + #include <linux/ptrace.h> 31 + #include <linux/kallsyms.h> 32 + 33 + #include <asm/setup.h> 34 + #include <asm/fpu.h> 35 + #include <asm/system.h> 36 + #include <asm/uaccess.h> 37 + #include <asm/traps.h> 38 + #include <asm/pgalloc.h> 39 + #include <asm/machdep.h> 40 + #include <asm/siginfo.h> 41 + 42 + /* assembler routines */ 43 + asmlinkage void system_call(void); 44 + asmlinkage void buserr(void); 45 + asmlinkage void trap(void); 46 + asmlinkage void nmihandler(void); 47 + #ifdef CONFIG_M68KFPU_EMU 48 + asmlinkage void fpu_emu(void); 49 + #endif 50 + 51 + e_vector vectors[256]; 52 + 53 + /* nmi handler for the Amiga */ 54 + asm(".text\n" 55 + __ALIGN_STR "\n" 56 + "nmihandler: rte"); 57 + 58 + /* 59 + * this must be called very early as the kernel might 60 + * use some instruction that are emulated on the 060 61 + * and so we're prepared for early probe attempts (e.g. nf_init). 62 + */ 63 + void __init base_trap_init(void) 64 + { 65 + if (MACH_IS_SUN3X) { 66 + extern e_vector *sun3x_prom_vbr; 67 + 68 + __asm__ volatile ("movec %%vbr, %0" : "=r" (sun3x_prom_vbr)); 69 + } 70 + 71 + /* setup the exception vector table */ 72 + __asm__ volatile ("movec %0,%%vbr" : : "r" ((void*)vectors)); 73 + 74 + if (CPU_IS_060) { 75 + /* set up ISP entry points */ 76 + asmlinkage void unimp_vec(void) asm ("_060_isp_unimp"); 77 + 78 + vectors[VEC_UNIMPII] = unimp_vec; 79 + } 80 + 81 + vectors[VEC_BUSERR] = buserr; 82 + vectors[VEC_ILLEGAL] = trap; 83 + vectors[VEC_SYS] = system_call; 84 + } 85 + 86 + void __init trap_init (void) 87 + { 88 + int i; 89 + 90 + for (i = VEC_SPUR; i <= VEC_INT7; i++) 91 + vectors[i] = bad_inthandler; 92 + 93 + for (i = 0; i < VEC_USER; i++) 94 + if (!vectors[i]) 95 + vectors[i] = trap; 96 + 97 + for (i = VEC_USER; i < 256; i++) 98 + vectors[i] = bad_inthandler; 99 + 100 + #ifdef CONFIG_M68KFPU_EMU 101 + if (FPU_IS_EMU) 102 + vectors[VEC_LINE11] = fpu_emu; 103 + #endif 104 + 105 + if (CPU_IS_040 && !FPU_IS_EMU) { 106 + /* set up FPSP entry points */ 107 + asmlinkage void dz_vec(void) asm ("dz"); 108 + asmlinkage void inex_vec(void) asm ("inex"); 109 + asmlinkage void ovfl_vec(void) asm ("ovfl"); 110 + asmlinkage void unfl_vec(void) asm ("unfl"); 111 + asmlinkage void snan_vec(void) asm ("snan"); 112 + asmlinkage void operr_vec(void) asm ("operr"); 113 + asmlinkage void bsun_vec(void) asm ("bsun"); 114 + asmlinkage void fline_vec(void) asm ("fline"); 115 + asmlinkage void unsupp_vec(void) asm ("unsupp"); 116 + 117 + vectors[VEC_FPDIVZ] = dz_vec; 118 + vectors[VEC_FPIR] = inex_vec; 119 + vectors[VEC_FPOVER] = ovfl_vec; 120 + vectors[VEC_FPUNDER] = unfl_vec; 121 + vectors[VEC_FPNAN] = snan_vec; 122 + vectors[VEC_FPOE] = operr_vec; 123 + vectors[VEC_FPBRUC] = bsun_vec; 124 + vectors[VEC_LINE11] = fline_vec; 125 + vectors[VEC_FPUNSUP] = unsupp_vec; 126 + } 127 + 128 + if (CPU_IS_060 && !FPU_IS_EMU) { 129 + /* set up IFPSP entry points */ 130 + asmlinkage void snan_vec6(void) asm ("_060_fpsp_snan"); 131 + asmlinkage void operr_vec6(void) asm ("_060_fpsp_operr"); 132 + asmlinkage void ovfl_vec6(void) asm ("_060_fpsp_ovfl"); 133 + asmlinkage void unfl_vec6(void) asm ("_060_fpsp_unfl"); 134 + asmlinkage void dz_vec6(void) asm ("_060_fpsp_dz"); 135 + asmlinkage void inex_vec6(void) asm ("_060_fpsp_inex"); 136 + asmlinkage void fline_vec6(void) asm ("_060_fpsp_fline"); 137 + asmlinkage void unsupp_vec6(void) asm ("_060_fpsp_unsupp"); 138 + asmlinkage void effadd_vec6(void) asm ("_060_fpsp_effadd"); 139 + 140 + vectors[VEC_FPNAN] = snan_vec6; 141 + vectors[VEC_FPOE] = operr_vec6; 142 + vectors[VEC_FPOVER] = ovfl_vec6; 143 + vectors[VEC_FPUNDER] = unfl_vec6; 144 + vectors[VEC_FPDIVZ] = dz_vec6; 145 + vectors[VEC_FPIR] = inex_vec6; 146 + vectors[VEC_LINE11] = fline_vec6; 147 + vectors[VEC_FPUNSUP] = unsupp_vec6; 148 + vectors[VEC_UNIMPEA] = effadd_vec6; 149 + } 150 + 151 + /* if running on an amiga, make the NMI interrupt do nothing */ 152 + if (MACH_IS_AMIGA) { 153 + vectors[VEC_INT7] = nmihandler; 154 + } 155 + } 156 + 157 + 158 + static const char *vec_names[] = { 159 + [VEC_RESETSP] = "RESET SP", 160 + [VEC_RESETPC] = "RESET PC", 161 + [VEC_BUSERR] = "BUS ERROR", 162 + [VEC_ADDRERR] = "ADDRESS ERROR", 163 + [VEC_ILLEGAL] = "ILLEGAL INSTRUCTION", 164 + [VEC_ZERODIV] = "ZERO DIVIDE", 165 + [VEC_CHK] = "CHK", 166 + [VEC_TRAP] = "TRAPcc", 167 + [VEC_PRIV] = "PRIVILEGE VIOLATION", 168 + [VEC_TRACE] = "TRACE", 169 + [VEC_LINE10] = "LINE 1010", 170 + [VEC_LINE11] = "LINE 1111", 171 + [VEC_RESV12] = "UNASSIGNED RESERVED 12", 172 + [VEC_COPROC] = "COPROCESSOR PROTOCOL VIOLATION", 173 + [VEC_FORMAT] = "FORMAT ERROR", 174 + [VEC_UNINT] = "UNINITIALIZED INTERRUPT", 175 + [VEC_RESV16] = "UNASSIGNED RESERVED 16", 176 + [VEC_RESV17] = "UNASSIGNED RESERVED 17", 177 + [VEC_RESV18] = "UNASSIGNED RESERVED 18", 178 + [VEC_RESV19] = "UNASSIGNED RESERVED 19", 179 + [VEC_RESV20] = "UNASSIGNED RESERVED 20", 180 + [VEC_RESV21] = "UNASSIGNED RESERVED 21", 181 + [VEC_RESV22] = "UNASSIGNED RESERVED 22", 182 + [VEC_RESV23] = "UNASSIGNED RESERVED 23", 183 + [VEC_SPUR] = "SPURIOUS INTERRUPT", 184 + [VEC_INT1] = "LEVEL 1 INT", 185 + [VEC_INT2] = "LEVEL 2 INT", 186 + [VEC_INT3] = "LEVEL 3 INT", 187 + [VEC_INT4] = "LEVEL 4 INT", 188 + [VEC_INT5] = "LEVEL 5 INT", 189 + [VEC_INT6] = "LEVEL 6 INT", 190 + [VEC_INT7] = "LEVEL 7 INT", 191 + [VEC_SYS] = "SYSCALL", 192 + [VEC_TRAP1] = "TRAP #1", 193 + [VEC_TRAP2] = "TRAP #2", 194 + [VEC_TRAP3] = "TRAP #3", 195 + [VEC_TRAP4] = "TRAP #4", 196 + [VEC_TRAP5] = "TRAP #5", 197 + [VEC_TRAP6] = "TRAP #6", 198 + [VEC_TRAP7] = "TRAP #7", 199 + [VEC_TRAP8] = "TRAP #8", 200 + [VEC_TRAP9] = "TRAP #9", 201 + [VEC_TRAP10] = "TRAP #10", 202 + [VEC_TRAP11] = "TRAP #11", 203 + [VEC_TRAP12] = "TRAP #12", 204 + [VEC_TRAP13] = "TRAP #13", 205 + [VEC_TRAP14] = "TRAP #14", 206 + [VEC_TRAP15] = "TRAP #15", 207 + [VEC_FPBRUC] = "FPCP BSUN", 208 + [VEC_FPIR] = "FPCP INEXACT", 209 + [VEC_FPDIVZ] = "FPCP DIV BY 0", 210 + [VEC_FPUNDER] = "FPCP UNDERFLOW", 211 + [VEC_FPOE] = "FPCP OPERAND ERROR", 212 + [VEC_FPOVER] = "FPCP OVERFLOW", 213 + [VEC_FPNAN] = "FPCP SNAN", 214 + [VEC_FPUNSUP] = "FPCP UNSUPPORTED OPERATION", 215 + [VEC_MMUCFG] = "MMU CONFIGURATION ERROR", 216 + [VEC_MMUILL] = "MMU ILLEGAL OPERATION ERROR", 217 + [VEC_MMUACC] = "MMU ACCESS LEVEL VIOLATION ERROR", 218 + [VEC_RESV59] = "UNASSIGNED RESERVED 59", 219 + [VEC_UNIMPEA] = "UNASSIGNED RESERVED 60", 220 + [VEC_UNIMPII] = "UNASSIGNED RESERVED 61", 221 + [VEC_RESV62] = "UNASSIGNED RESERVED 62", 222 + [VEC_RESV63] = "UNASSIGNED RESERVED 63", 223 + }; 224 + 225 + static const char *space_names[] = { 226 + [0] = "Space 0", 227 + [USER_DATA] = "User Data", 228 + [USER_PROGRAM] = "User Program", 229 + #ifndef CONFIG_SUN3 230 + [3] = "Space 3", 231 + #else 232 + [FC_CONTROL] = "Control", 233 + #endif 234 + [4] = "Space 4", 235 + [SUPER_DATA] = "Super Data", 236 + [SUPER_PROGRAM] = "Super Program", 237 + [CPU_SPACE] = "CPU" 238 + }; 239 + 240 + void die_if_kernel(char *,struct pt_regs *,int); 241 + asmlinkage int do_page_fault(struct pt_regs *regs, unsigned long address, 242 + unsigned long error_code); 243 + int send_fault_sig(struct pt_regs *regs); 244 + 245 + asmlinkage void trap_c(struct frame *fp); 246 + 247 + #if defined (CONFIG_M68060) 248 + static inline void access_error060 (struct frame *fp) 249 + { 250 + unsigned long fslw = fp->un.fmt4.pc; /* is really FSLW for access error */ 251 + 252 + #ifdef DEBUG 253 + printk("fslw=%#lx, fa=%#lx\n", fslw, fp->un.fmt4.effaddr); 254 + #endif 255 + 256 + if (fslw & MMU060_BPE) { 257 + /* branch prediction error -> clear branch cache */ 258 + __asm__ __volatile__ ("movec %/cacr,%/d0\n\t" 259 + "orl #0x00400000,%/d0\n\t" 260 + "movec %/d0,%/cacr" 261 + : : : "d0" ); 262 + /* return if there's no other error */ 263 + if (!(fslw & MMU060_ERR_BITS) && !(fslw & MMU060_SEE)) 264 + return; 265 + } 266 + 267 + if (fslw & (MMU060_DESC_ERR | MMU060_WP | MMU060_SP)) { 268 + unsigned long errorcode; 269 + unsigned long addr = fp->un.fmt4.effaddr; 270 + 271 + if (fslw & MMU060_MA) 272 + addr = (addr + PAGE_SIZE - 1) & PAGE_MASK; 273 + 274 + errorcode = 1; 275 + if (fslw & MMU060_DESC_ERR) { 276 + __flush_tlb040_one(addr); 277 + errorcode = 0; 278 + } 279 + if (fslw & MMU060_W) 280 + errorcode |= 2; 281 + #ifdef DEBUG 282 + printk("errorcode = %d\n", errorcode ); 283 + #endif 284 + do_page_fault(&fp->ptregs, addr, errorcode); 285 + } else if (fslw & (MMU060_SEE)){ 286 + /* Software Emulation Error. 287 + * fault during mem_read/mem_write in ifpsp060/os.S 288 + */ 289 + send_fault_sig(&fp->ptregs); 290 + } else if (!(fslw & (MMU060_RE|MMU060_WE)) || 291 + send_fault_sig(&fp->ptregs) > 0) { 292 + printk("pc=%#lx, fa=%#lx\n", fp->ptregs.pc, fp->un.fmt4.effaddr); 293 + printk( "68060 access error, fslw=%lx\n", fslw ); 294 + trap_c( fp ); 295 + } 296 + } 297 + #endif /* CONFIG_M68060 */ 298 + 299 + #if defined (CONFIG_M68040) 300 + static inline unsigned long probe040(int iswrite, unsigned long addr, int wbs) 301 + { 302 + unsigned long mmusr; 303 + mm_segment_t old_fs = get_fs(); 304 + 305 + set_fs(MAKE_MM_SEG(wbs)); 306 + 307 + if (iswrite) 308 + asm volatile (".chip 68040; ptestw (%0); .chip 68k" : : "a" (addr)); 309 + else 310 + asm volatile (".chip 68040; ptestr (%0); .chip 68k" : : "a" (addr)); 311 + 312 + asm volatile (".chip 68040; movec %%mmusr,%0; .chip 68k" : "=r" (mmusr)); 313 + 314 + set_fs(old_fs); 315 + 316 + return mmusr; 317 + } 318 + 319 + static inline int do_040writeback1(unsigned short wbs, unsigned long wba, 320 + unsigned long wbd) 321 + { 322 + int res = 0; 323 + mm_segment_t old_fs = get_fs(); 324 + 325 + /* set_fs can not be moved, otherwise put_user() may oops */ 326 + set_fs(MAKE_MM_SEG(wbs)); 327 + 328 + switch (wbs & WBSIZ_040) { 329 + case BA_SIZE_BYTE: 330 + res = put_user(wbd & 0xff, (char __user *)wba); 331 + break; 332 + case BA_SIZE_WORD: 333 + res = put_user(wbd & 0xffff, (short __user *)wba); 334 + break; 335 + case BA_SIZE_LONG: 336 + res = put_user(wbd, (int __user *)wba); 337 + break; 338 + } 339 + 340 + /* set_fs can not be moved, otherwise put_user() may oops */ 341 + set_fs(old_fs); 342 + 343 + 344 + #ifdef DEBUG 345 + printk("do_040writeback1, res=%d\n",res); 346 + #endif 347 + 348 + return res; 349 + } 350 + 351 + /* after an exception in a writeback the stack frame corresponding 352 + * to that exception is discarded, set a few bits in the old frame 353 + * to simulate what it should look like 354 + */ 355 + static inline void fix_xframe040(struct frame *fp, unsigned long wba, unsigned short wbs) 356 + { 357 + fp->un.fmt7.faddr = wba; 358 + fp->un.fmt7.ssw = wbs & 0xff; 359 + if (wba != current->thread.faddr) 360 + fp->un.fmt7.ssw |= MA_040; 361 + } 362 + 363 + static inline void do_040writebacks(struct frame *fp) 364 + { 365 + int res = 0; 366 + #if 0 367 + if (fp->un.fmt7.wb1s & WBV_040) 368 + printk("access_error040: cannot handle 1st writeback. oops.\n"); 369 + #endif 370 + 371 + if ((fp->un.fmt7.wb2s & WBV_040) && 372 + !(fp->un.fmt7.wb2s & WBTT_040)) { 373 + res = do_040writeback1(fp->un.fmt7.wb2s, fp->un.fmt7.wb2a, 374 + fp->un.fmt7.wb2d); 375 + if (res) 376 + fix_xframe040(fp, fp->un.fmt7.wb2a, fp->un.fmt7.wb2s); 377 + else 378 + fp->un.fmt7.wb2s = 0; 379 + } 380 + 381 + /* do the 2nd wb only if the first one was successful (except for a kernel wb) */ 382 + if (fp->un.fmt7.wb3s & WBV_040 && (!res || fp->un.fmt7.wb3s & 4)) { 383 + res = do_040writeback1(fp->un.fmt7.wb3s, fp->un.fmt7.wb3a, 384 + fp->un.fmt7.wb3d); 385 + if (res) 386 + { 387 + fix_xframe040(fp, fp->un.fmt7.wb3a, fp->un.fmt7.wb3s); 388 + 389 + fp->un.fmt7.wb2s = fp->un.fmt7.wb3s; 390 + fp->un.fmt7.wb3s &= (~WBV_040); 391 + fp->un.fmt7.wb2a = fp->un.fmt7.wb3a; 392 + fp->un.fmt7.wb2d = fp->un.fmt7.wb3d; 393 + } 394 + else 395 + fp->un.fmt7.wb3s = 0; 396 + } 397 + 398 + if (res) 399 + send_fault_sig(&fp->ptregs); 400 + } 401 + 402 + /* 403 + * called from sigreturn(), must ensure userspace code didn't 404 + * manipulate exception frame to circumvent protection, then complete 405 + * pending writebacks 406 + * we just clear TM2 to turn it into a userspace access 407 + */ 408 + asmlinkage void berr_040cleanup(struct frame *fp) 409 + { 410 + fp->un.fmt7.wb2s &= ~4; 411 + fp->un.fmt7.wb3s &= ~4; 412 + 413 + do_040writebacks(fp); 414 + } 415 + 416 + static inline void access_error040(struct frame *fp) 417 + { 418 + unsigned short ssw = fp->un.fmt7.ssw; 419 + unsigned long mmusr; 420 + 421 + #ifdef DEBUG 422 + printk("ssw=%#x, fa=%#lx\n", ssw, fp->un.fmt7.faddr); 423 + printk("wb1s=%#x, wb2s=%#x, wb3s=%#x\n", fp->un.fmt7.wb1s, 424 + fp->un.fmt7.wb2s, fp->un.fmt7.wb3s); 425 + printk ("wb2a=%lx, wb3a=%lx, wb2d=%lx, wb3d=%lx\n", 426 + fp->un.fmt7.wb2a, fp->un.fmt7.wb3a, 427 + fp->un.fmt7.wb2d, fp->un.fmt7.wb3d); 428 + #endif 429 + 430 + if (ssw & ATC_040) { 431 + unsigned long addr = fp->un.fmt7.faddr; 432 + unsigned long errorcode; 433 + 434 + /* 435 + * The MMU status has to be determined AFTER the address 436 + * has been corrected if there was a misaligned access (MA). 437 + */ 438 + if (ssw & MA_040) 439 + addr = (addr + 7) & -8; 440 + 441 + /* MMU error, get the MMUSR info for this access */ 442 + mmusr = probe040(!(ssw & RW_040), addr, ssw); 443 + #ifdef DEBUG 444 + printk("mmusr = %lx\n", mmusr); 445 + #endif 446 + errorcode = 1; 447 + if (!(mmusr & MMU_R_040)) { 448 + /* clear the invalid atc entry */ 449 + __flush_tlb040_one(addr); 450 + errorcode = 0; 451 + } 452 + 453 + /* despite what documentation seems to say, RMW 454 + * accesses have always both the LK and RW bits set */ 455 + if (!(ssw & RW_040) || (ssw & LK_040)) 456 + errorcode |= 2; 457 + 458 + if (do_page_fault(&fp->ptregs, addr, errorcode)) { 459 + #ifdef DEBUG 460 + printk("do_page_fault() !=0\n"); 461 + #endif 462 + if (user_mode(&fp->ptregs)){ 463 + /* delay writebacks after signal delivery */ 464 + #ifdef DEBUG 465 + printk(".. was usermode - return\n"); 466 + #endif 467 + return; 468 + } 469 + /* disable writeback into user space from kernel 470 + * (if do_page_fault didn't fix the mapping, 471 + * the writeback won't do good) 472 + */ 473 + disable_wb: 474 + #ifdef DEBUG 475 + printk(".. disabling wb2\n"); 476 + #endif 477 + if (fp->un.fmt7.wb2a == fp->un.fmt7.faddr) 478 + fp->un.fmt7.wb2s &= ~WBV_040; 479 + if (fp->un.fmt7.wb3a == fp->un.fmt7.faddr) 480 + fp->un.fmt7.wb3s &= ~WBV_040; 481 + } 482 + } else { 483 + /* In case of a bus error we either kill the process or expect 484 + * the kernel to catch the fault, which then is also responsible 485 + * for cleaning up the mess. 486 + */ 487 + current->thread.signo = SIGBUS; 488 + current->thread.faddr = fp->un.fmt7.faddr; 489 + if (send_fault_sig(&fp->ptregs) >= 0) 490 + printk("68040 bus error (ssw=%x, faddr=%lx)\n", ssw, 491 + fp->un.fmt7.faddr); 492 + goto disable_wb; 493 + } 494 + 495 + do_040writebacks(fp); 496 + } 497 + #endif /* CONFIG_M68040 */ 498 + 499 + #if defined(CONFIG_SUN3) 500 + #include <asm/sun3mmu.h> 501 + 502 + extern int mmu_emu_handle_fault (unsigned long, int, int); 503 + 504 + /* sun3 version of bus_error030 */ 505 + 506 + static inline void bus_error030 (struct frame *fp) 507 + { 508 + unsigned char buserr_type = sun3_get_buserr (); 509 + unsigned long addr, errorcode; 510 + unsigned short ssw = fp->un.fmtb.ssw; 511 + extern unsigned long _sun3_map_test_start, _sun3_map_test_end; 512 + 513 + #ifdef DEBUG 514 + if (ssw & (FC | FB)) 515 + printk ("Instruction fault at %#010lx\n", 516 + ssw & FC ? 517 + fp->ptregs.format == 0xa ? fp->ptregs.pc + 2 : fp->un.fmtb.baddr - 2 518 + : 519 + fp->ptregs.format == 0xa ? fp->ptregs.pc + 4 : fp->un.fmtb.baddr); 520 + if (ssw & DF) 521 + printk ("Data %s fault at %#010lx in %s (pc=%#lx)\n", 522 + ssw & RW ? "read" : "write", 523 + fp->un.fmtb.daddr, 524 + space_names[ssw & DFC], fp->ptregs.pc); 525 + #endif 526 + 527 + /* 528 + * Check if this page should be demand-mapped. This needs to go before 529 + * the testing for a bad kernel-space access (demand-mapping applies 530 + * to kernel accesses too). 531 + */ 532 + 533 + if ((ssw & DF) 534 + && (buserr_type & (SUN3_BUSERR_PROTERR | SUN3_BUSERR_INVALID))) { 535 + if (mmu_emu_handle_fault (fp->un.fmtb.daddr, ssw & RW, 0)) 536 + return; 537 + } 538 + 539 + /* Check for kernel-space pagefault (BAD). */ 540 + if (fp->ptregs.sr & PS_S) { 541 + /* kernel fault must be a data fault to user space */ 542 + if (! ((ssw & DF) && ((ssw & DFC) == USER_DATA))) { 543 + // try checking the kernel mappings before surrender 544 + if (mmu_emu_handle_fault (fp->un.fmtb.daddr, ssw & RW, 1)) 545 + return; 546 + /* instruction fault or kernel data fault! */ 547 + if (ssw & (FC | FB)) 548 + printk ("Instruction fault at %#010lx\n", 549 + fp->ptregs.pc); 550 + if (ssw & DF) { 551 + /* was this fault incurred testing bus mappings? */ 552 + if((fp->ptregs.pc >= (unsigned long)&_sun3_map_test_start) && 553 + (fp->ptregs.pc <= (unsigned long)&_sun3_map_test_end)) { 554 + send_fault_sig(&fp->ptregs); 555 + return; 556 + } 557 + 558 + printk ("Data %s fault at %#010lx in %s (pc=%#lx)\n", 559 + ssw & RW ? "read" : "write", 560 + fp->un.fmtb.daddr, 561 + space_names[ssw & DFC], fp->ptregs.pc); 562 + } 563 + printk ("BAD KERNEL BUSERR\n"); 564 + 565 + die_if_kernel("Oops", &fp->ptregs,0); 566 + force_sig(SIGKILL, current); 567 + return; 568 + } 569 + } else { 570 + /* user fault */ 571 + if (!(ssw & (FC | FB)) && !(ssw & DF)) 572 + /* not an instruction fault or data fault! BAD */ 573 + panic ("USER BUSERR w/o instruction or data fault"); 574 + } 575 + 576 + 577 + /* First handle the data fault, if any. */ 578 + if (ssw & DF) { 579 + addr = fp->un.fmtb.daddr; 580 + 581 + // errorcode bit 0: 0 -> no page 1 -> protection fault 582 + // errorcode bit 1: 0 -> read fault 1 -> write fault 583 + 584 + // (buserr_type & SUN3_BUSERR_PROTERR) -> protection fault 585 + // (buserr_type & SUN3_BUSERR_INVALID) -> invalid page fault 586 + 587 + if (buserr_type & SUN3_BUSERR_PROTERR) 588 + errorcode = 0x01; 589 + else if (buserr_type & SUN3_BUSERR_INVALID) 590 + errorcode = 0x00; 591 + else { 592 + #ifdef DEBUG 593 + printk ("*** unexpected busfault type=%#04x\n", buserr_type); 594 + printk ("invalid %s access at %#lx from pc %#lx\n", 595 + !(ssw & RW) ? "write" : "read", addr, 596 + fp->ptregs.pc); 597 + #endif 598 + die_if_kernel ("Oops", &fp->ptregs, buserr_type); 599 + force_sig (SIGBUS, current); 600 + return; 601 + } 602 + 603 + //todo: wtf is RM bit? --m 604 + if (!(ssw & RW) || ssw & RM) 605 + errorcode |= 0x02; 606 + 607 + /* Handle page fault. */ 608 + do_page_fault (&fp->ptregs, addr, errorcode); 609 + 610 + /* Retry the data fault now. */ 611 + return; 612 + } 613 + 614 + /* Now handle the instruction fault. */ 615 + 616 + /* Get the fault address. */ 617 + if (fp->ptregs.format == 0xA) 618 + addr = fp->ptregs.pc + 4; 619 + else 620 + addr = fp->un.fmtb.baddr; 621 + if (ssw & FC) 622 + addr -= 2; 623 + 624 + if (buserr_type & SUN3_BUSERR_INVALID) { 625 + if (!mmu_emu_handle_fault (fp->un.fmtb.daddr, 1, 0)) 626 + do_page_fault (&fp->ptregs, addr, 0); 627 + } else { 628 + #ifdef DEBUG 629 + printk ("protection fault on insn access (segv).\n"); 630 + #endif 631 + force_sig (SIGSEGV, current); 632 + } 633 + } 634 + #else 635 + #if defined(CPU_M68020_OR_M68030) 636 + static inline void bus_error030 (struct frame *fp) 637 + { 638 + volatile unsigned short temp; 639 + unsigned short mmusr; 640 + unsigned long addr, errorcode; 641 + unsigned short ssw = fp->un.fmtb.ssw; 642 + #ifdef DEBUG 643 + unsigned long desc; 644 + 645 + printk ("pid = %x ", current->pid); 646 + printk ("SSW=%#06x ", ssw); 647 + 648 + if (ssw & (FC | FB)) 649 + printk ("Instruction fault at %#010lx\n", 650 + ssw & FC ? 651 + fp->ptregs.format == 0xa ? fp->ptregs.pc + 2 : fp->un.fmtb.baddr - 2 652 + : 653 + fp->ptregs.format == 0xa ? fp->ptregs.pc + 4 : fp->un.fmtb.baddr); 654 + if (ssw & DF) 655 + printk ("Data %s fault at %#010lx in %s (pc=%#lx)\n", 656 + ssw & RW ? "read" : "write", 657 + fp->un.fmtb.daddr, 658 + space_names[ssw & DFC], fp->ptregs.pc); 659 + #endif 660 + 661 + /* ++andreas: If a data fault and an instruction fault happen 662 + at the same time map in both pages. */ 663 + 664 + /* First handle the data fault, if any. */ 665 + if (ssw & DF) { 666 + addr = fp->un.fmtb.daddr; 667 + 668 + #ifdef DEBUG 669 + asm volatile ("ptestr %3,%2@,#7,%0\n\t" 670 + "pmove %%psr,%1@" 671 + : "=a&" (desc) 672 + : "a" (&temp), "a" (addr), "d" (ssw)); 673 + #else 674 + asm volatile ("ptestr %2,%1@,#7\n\t" 675 + "pmove %%psr,%0@" 676 + : : "a" (&temp), "a" (addr), "d" (ssw)); 677 + #endif 678 + mmusr = temp; 679 + 680 + #ifdef DEBUG 681 + printk("mmusr is %#x for addr %#lx in task %p\n", 682 + mmusr, addr, current); 683 + printk("descriptor address is %#lx, contents %#lx\n", 684 + __va(desc), *(unsigned long *)__va(desc)); 685 + #endif 686 + 687 + errorcode = (mmusr & MMU_I) ? 0 : 1; 688 + if (!(ssw & RW) || (ssw & RM)) 689 + errorcode |= 2; 690 + 691 + if (mmusr & (MMU_I | MMU_WP)) { 692 + if (ssw & 4) { 693 + printk("Data %s fault at %#010lx in %s (pc=%#lx)\n", 694 + ssw & RW ? "read" : "write", 695 + fp->un.fmtb.daddr, 696 + space_names[ssw & DFC], fp->ptregs.pc); 697 + goto buserr; 698 + } 699 + /* Don't try to do anything further if an exception was 700 + handled. */ 701 + if (do_page_fault (&fp->ptregs, addr, errorcode) < 0) 702 + return; 703 + } else if (!(mmusr & MMU_I)) { 704 + /* probably a 020 cas fault */ 705 + if (!(ssw & RM) && send_fault_sig(&fp->ptregs) > 0) 706 + printk("unexpected bus error (%#x,%#x)\n", ssw, mmusr); 707 + } else if (mmusr & (MMU_B|MMU_L|MMU_S)) { 708 + printk("invalid %s access at %#lx from pc %#lx\n", 709 + !(ssw & RW) ? "write" : "read", addr, 710 + fp->ptregs.pc); 711 + die_if_kernel("Oops",&fp->ptregs,mmusr); 712 + force_sig(SIGSEGV, current); 713 + return; 714 + } else { 715 + #if 0 716 + static volatile long tlong; 717 + #endif 718 + 719 + printk("weird %s access at %#lx from pc %#lx (ssw is %#x)\n", 720 + !(ssw & RW) ? "write" : "read", addr, 721 + fp->ptregs.pc, ssw); 722 + asm volatile ("ptestr #1,%1@,#0\n\t" 723 + "pmove %%psr,%0@" 724 + : /* no outputs */ 725 + : "a" (&temp), "a" (addr)); 726 + mmusr = temp; 727 + 728 + printk ("level 0 mmusr is %#x\n", mmusr); 729 + #if 0 730 + asm volatile ("pmove %%tt0,%0@" 731 + : /* no outputs */ 732 + : "a" (&tlong)); 733 + printk("tt0 is %#lx, ", tlong); 734 + asm volatile ("pmove %%tt1,%0@" 735 + : /* no outputs */ 736 + : "a" (&tlong)); 737 + printk("tt1 is %#lx\n", tlong); 738 + #endif 739 + #ifdef DEBUG 740 + printk("Unknown SIGSEGV - 1\n"); 741 + #endif 742 + die_if_kernel("Oops",&fp->ptregs,mmusr); 743 + force_sig(SIGSEGV, current); 744 + return; 745 + } 746 + 747 + /* setup an ATC entry for the access about to be retried */ 748 + if (!(ssw & RW) || (ssw & RM)) 749 + asm volatile ("ploadw %1,%0@" : /* no outputs */ 750 + : "a" (addr), "d" (ssw)); 751 + else 752 + asm volatile ("ploadr %1,%0@" : /* no outputs */ 753 + : "a" (addr), "d" (ssw)); 754 + } 755 + 756 + /* Now handle the instruction fault. */ 757 + 758 + if (!(ssw & (FC|FB))) 759 + return; 760 + 761 + if (fp->ptregs.sr & PS_S) { 762 + printk("Instruction fault at %#010lx\n", 763 + fp->ptregs.pc); 764 + buserr: 765 + printk ("BAD KERNEL BUSERR\n"); 766 + die_if_kernel("Oops",&fp->ptregs,0); 767 + force_sig(SIGKILL, current); 768 + return; 769 + } 770 + 771 + /* get the fault address */ 772 + if (fp->ptregs.format == 10) 773 + addr = fp->ptregs.pc + 4; 774 + else 775 + addr = fp->un.fmtb.baddr; 776 + if (ssw & FC) 777 + addr -= 2; 778 + 779 + if ((ssw & DF) && ((addr ^ fp->un.fmtb.daddr) & PAGE_MASK) == 0) 780 + /* Insn fault on same page as data fault. But we 781 + should still create the ATC entry. */ 782 + goto create_atc_entry; 783 + 784 + #ifdef DEBUG 785 + asm volatile ("ptestr #1,%2@,#7,%0\n\t" 786 + "pmove %%psr,%1@" 787 + : "=a&" (desc) 788 + : "a" (&temp), "a" (addr)); 789 + #else 790 + asm volatile ("ptestr #1,%1@,#7\n\t" 791 + "pmove %%psr,%0@" 792 + : : "a" (&temp), "a" (addr)); 793 + #endif 794 + mmusr = temp; 795 + 796 + #ifdef DEBUG 797 + printk ("mmusr is %#x for addr %#lx in task %p\n", 798 + mmusr, addr, current); 799 + printk ("descriptor address is %#lx, contents %#lx\n", 800 + __va(desc), *(unsigned long *)__va(desc)); 801 + #endif 802 + 803 + if (mmusr & MMU_I) 804 + do_page_fault (&fp->ptregs, addr, 0); 805 + else if (mmusr & (MMU_B|MMU_L|MMU_S)) { 806 + printk ("invalid insn access at %#lx from pc %#lx\n", 807 + addr, fp->ptregs.pc); 808 + #ifdef DEBUG 809 + printk("Unknown SIGSEGV - 2\n"); 810 + #endif 811 + die_if_kernel("Oops",&fp->ptregs,mmusr); 812 + force_sig(SIGSEGV, current); 813 + return; 814 + } 815 + 816 + create_atc_entry: 817 + /* setup an ATC entry for the access about to be retried */ 818 + asm volatile ("ploadr #2,%0@" : /* no outputs */ 819 + : "a" (addr)); 820 + } 821 + #endif /* CPU_M68020_OR_M68030 */ 822 + #endif /* !CONFIG_SUN3 */ 823 + 824 + asmlinkage void buserr_c(struct frame *fp) 825 + { 826 + /* Only set esp0 if coming from user mode */ 827 + if (user_mode(&fp->ptregs)) 828 + current->thread.esp0 = (unsigned long) fp; 829 + 830 + #ifdef DEBUG 831 + printk ("*** Bus Error *** Format is %x\n", fp->ptregs.format); 832 + #endif 833 + 834 + switch (fp->ptregs.format) { 835 + #if defined (CONFIG_M68060) 836 + case 4: /* 68060 access error */ 837 + access_error060 (fp); 838 + break; 839 + #endif 840 + #if defined (CONFIG_M68040) 841 + case 0x7: /* 68040 access error */ 842 + access_error040 (fp); 843 + break; 844 + #endif 845 + #if defined (CPU_M68020_OR_M68030) 846 + case 0xa: 847 + case 0xb: 848 + bus_error030 (fp); 849 + break; 850 + #endif 851 + default: 852 + die_if_kernel("bad frame format",&fp->ptregs,0); 853 + #ifdef DEBUG 854 + printk("Unknown SIGSEGV - 4\n"); 855 + #endif 856 + force_sig(SIGSEGV, current); 857 + } 858 + } 859 + 860 + 861 + static int kstack_depth_to_print = 48; 862 + 863 + void show_trace(unsigned long *stack) 864 + { 865 + unsigned long *endstack; 866 + unsigned long addr; 867 + int i; 868 + 869 + printk("Call Trace:"); 870 + addr = (unsigned long)stack + THREAD_SIZE - 1; 871 + endstack = (unsigned long *)(addr & -THREAD_SIZE); 872 + i = 0; 873 + while (stack + 1 <= endstack) { 874 + addr = *stack++; 875 + /* 876 + * If the address is either in the text segment of the 877 + * kernel, or in the region which contains vmalloc'ed 878 + * memory, it *may* be the address of a calling 879 + * routine; if so, print it so that someone tracing 880 + * down the cause of the crash will be able to figure 881 + * out the call path that was taken. 882 + */ 883 + if (__kernel_text_address(addr)) { 884 + #ifndef CONFIG_KALLSYMS 885 + if (i % 5 == 0) 886 + printk("\n "); 887 + #endif 888 + printk(" [<%08lx>] %pS\n", addr, (void *)addr); 889 + i++; 890 + } 891 + } 892 + printk("\n"); 893 + } 894 + 895 + void show_registers(struct pt_regs *regs) 896 + { 897 + struct frame *fp = (struct frame *)regs; 898 + mm_segment_t old_fs = get_fs(); 899 + u16 c, *cp; 900 + unsigned long addr; 901 + int i; 902 + 903 + print_modules(); 904 + printk("PC: [<%08lx>] %pS\n", regs->pc, (void *)regs->pc); 905 + printk("SR: %04x SP: %p a2: %08lx\n", regs->sr, regs, regs->a2); 906 + printk("d0: %08lx d1: %08lx d2: %08lx d3: %08lx\n", 907 + regs->d0, regs->d1, regs->d2, regs->d3); 908 + printk("d4: %08lx d5: %08lx a0: %08lx a1: %08lx\n", 909 + regs->d4, regs->d5, regs->a0, regs->a1); 910 + 911 + printk("Process %s (pid: %d, task=%p)\n", 912 + current->comm, task_pid_nr(current), current); 913 + addr = (unsigned long)&fp->un; 914 + printk("Frame format=%X ", regs->format); 915 + switch (regs->format) { 916 + case 0x2: 917 + printk("instr addr=%08lx\n", fp->un.fmt2.iaddr); 918 + addr += sizeof(fp->un.fmt2); 919 + break; 920 + case 0x3: 921 + printk("eff addr=%08lx\n", fp->un.fmt3.effaddr); 922 + addr += sizeof(fp->un.fmt3); 923 + break; 924 + case 0x4: 925 + printk((CPU_IS_060 ? "fault addr=%08lx fslw=%08lx\n" 926 + : "eff addr=%08lx pc=%08lx\n"), 927 + fp->un.fmt4.effaddr, fp->un.fmt4.pc); 928 + addr += sizeof(fp->un.fmt4); 929 + break; 930 + case 0x7: 931 + printk("eff addr=%08lx ssw=%04x faddr=%08lx\n", 932 + fp->un.fmt7.effaddr, fp->un.fmt7.ssw, fp->un.fmt7.faddr); 933 + printk("wb 1 stat/addr/data: %04x %08lx %08lx\n", 934 + fp->un.fmt7.wb1s, fp->un.fmt7.wb1a, fp->un.fmt7.wb1dpd0); 935 + printk("wb 2 stat/addr/data: %04x %08lx %08lx\n", 936 + fp->un.fmt7.wb2s, fp->un.fmt7.wb2a, fp->un.fmt7.wb2d); 937 + printk("wb 3 stat/addr/data: %04x %08lx %08lx\n", 938 + fp->un.fmt7.wb3s, fp->un.fmt7.wb3a, fp->un.fmt7.wb3d); 939 + printk("push data: %08lx %08lx %08lx %08lx\n", 940 + fp->un.fmt7.wb1dpd0, fp->un.fmt7.pd1, fp->un.fmt7.pd2, 941 + fp->un.fmt7.pd3); 942 + addr += sizeof(fp->un.fmt7); 943 + break; 944 + case 0x9: 945 + printk("instr addr=%08lx\n", fp->un.fmt9.iaddr); 946 + addr += sizeof(fp->un.fmt9); 947 + break; 948 + case 0xa: 949 + printk("ssw=%04x isc=%04x isb=%04x daddr=%08lx dobuf=%08lx\n", 950 + fp->un.fmta.ssw, fp->un.fmta.isc, fp->un.fmta.isb, 951 + fp->un.fmta.daddr, fp->un.fmta.dobuf); 952 + addr += sizeof(fp->un.fmta); 953 + break; 954 + case 0xb: 955 + printk("ssw=%04x isc=%04x isb=%04x daddr=%08lx dobuf=%08lx\n", 956 + fp->un.fmtb.ssw, fp->un.fmtb.isc, fp->un.fmtb.isb, 957 + fp->un.fmtb.daddr, fp->un.fmtb.dobuf); 958 + printk("baddr=%08lx dibuf=%08lx ver=%x\n", 959 + fp->un.fmtb.baddr, fp->un.fmtb.dibuf, fp->un.fmtb.ver); 960 + addr += sizeof(fp->un.fmtb); 961 + break; 962 + default: 963 + printk("\n"); 964 + } 965 + show_stack(NULL, (unsigned long *)addr); 966 + 967 + printk("Code:"); 968 + set_fs(KERNEL_DS); 969 + cp = (u16 *)regs->pc; 970 + for (i = -8; i < 16; i++) { 971 + if (get_user(c, cp + i) && i >= 0) { 972 + printk(" Bad PC value."); 973 + break; 974 + } 975 + printk(i ? " %04x" : " <%04x>", c); 976 + } 977 + set_fs(old_fs); 978 + printk ("\n"); 979 + } 980 + 981 + void show_stack(struct task_struct *task, unsigned long *stack) 982 + { 983 + unsigned long *p; 984 + unsigned long *endstack; 985 + int i; 986 + 987 + if (!stack) { 988 + if (task) 989 + stack = (unsigned long *)task->thread.esp0; 990 + else 991 + stack = (unsigned long *)&stack; 992 + } 993 + endstack = (unsigned long *)(((unsigned long)stack + THREAD_SIZE - 1) & -THREAD_SIZE); 994 + 995 + printk("Stack from %08lx:", (unsigned long)stack); 996 + p = stack; 997 + for (i = 0; i < kstack_depth_to_print; i++) { 998 + if (p + 1 > endstack) 999 + break; 1000 + if (i % 8 == 0) 1001 + printk("\n "); 1002 + printk(" %08lx", *p++); 1003 + } 1004 + printk("\n"); 1005 + show_trace(stack); 1006 + } 1007 + 1008 + /* 1009 + * The architecture-independent backtrace generator 1010 + */ 1011 + void dump_stack(void) 1012 + { 1013 + unsigned long stack; 1014 + 1015 + show_trace(&stack); 1016 + } 1017 + 1018 + EXPORT_SYMBOL(dump_stack); 1019 + 1020 + void bad_super_trap (struct frame *fp) 1021 + { 1022 + console_verbose(); 1023 + if (fp->ptregs.vector < 4 * ARRAY_SIZE(vec_names)) 1024 + printk ("*** %s *** FORMAT=%X\n", 1025 + vec_names[(fp->ptregs.vector) >> 2], 1026 + fp->ptregs.format); 1027 + else 1028 + printk ("*** Exception %d *** FORMAT=%X\n", 1029 + (fp->ptregs.vector) >> 2, 1030 + fp->ptregs.format); 1031 + if (fp->ptregs.vector >> 2 == VEC_ADDRERR && CPU_IS_020_OR_030) { 1032 + unsigned short ssw = fp->un.fmtb.ssw; 1033 + 1034 + printk ("SSW=%#06x ", ssw); 1035 + 1036 + if (ssw & RC) 1037 + printk ("Pipe stage C instruction fault at %#010lx\n", 1038 + (fp->ptregs.format) == 0xA ? 1039 + fp->ptregs.pc + 2 : fp->un.fmtb.baddr - 2); 1040 + if (ssw & RB) 1041 + printk ("Pipe stage B instruction fault at %#010lx\n", 1042 + (fp->ptregs.format) == 0xA ? 1043 + fp->ptregs.pc + 4 : fp->un.fmtb.baddr); 1044 + if (ssw & DF) 1045 + printk ("Data %s fault at %#010lx in %s (pc=%#lx)\n", 1046 + ssw & RW ? "read" : "write", 1047 + fp->un.fmtb.daddr, space_names[ssw & DFC], 1048 + fp->ptregs.pc); 1049 + } 1050 + printk ("Current process id is %d\n", task_pid_nr(current)); 1051 + die_if_kernel("BAD KERNEL TRAP", &fp->ptregs, 0); 1052 + } 1053 + 1054 + asmlinkage void trap_c(struct frame *fp) 1055 + { 1056 + int sig; 1057 + siginfo_t info; 1058 + 1059 + if (fp->ptregs.sr & PS_S) { 1060 + if (fp->ptregs.vector == VEC_TRACE << 2) { 1061 + /* traced a trapping instruction on a 68020/30, 1062 + * real exception will be executed afterwards. 1063 + */ 1064 + } else if (!handle_kernel_fault(&fp->ptregs)) 1065 + bad_super_trap(fp); 1066 + return; 1067 + } 1068 + 1069 + /* send the appropriate signal to the user program */ 1070 + switch ((fp->ptregs.vector) >> 2) { 1071 + case VEC_ADDRERR: 1072 + info.si_code = BUS_ADRALN; 1073 + sig = SIGBUS; 1074 + break; 1075 + case VEC_ILLEGAL: 1076 + case VEC_LINE10: 1077 + case VEC_LINE11: 1078 + info.si_code = ILL_ILLOPC; 1079 + sig = SIGILL; 1080 + break; 1081 + case VEC_PRIV: 1082 + info.si_code = ILL_PRVOPC; 1083 + sig = SIGILL; 1084 + break; 1085 + case VEC_COPROC: 1086 + info.si_code = ILL_COPROC; 1087 + sig = SIGILL; 1088 + break; 1089 + case VEC_TRAP1: 1090 + case VEC_TRAP2: 1091 + case VEC_TRAP3: 1092 + case VEC_TRAP4: 1093 + case VEC_TRAP5: 1094 + case VEC_TRAP6: 1095 + case VEC_TRAP7: 1096 + case VEC_TRAP8: 1097 + case VEC_TRAP9: 1098 + case VEC_TRAP10: 1099 + case VEC_TRAP11: 1100 + case VEC_TRAP12: 1101 + case VEC_TRAP13: 1102 + case VEC_TRAP14: 1103 + info.si_code = ILL_ILLTRP; 1104 + sig = SIGILL; 1105 + break; 1106 + case VEC_FPBRUC: 1107 + case VEC_FPOE: 1108 + case VEC_FPNAN: 1109 + info.si_code = FPE_FLTINV; 1110 + sig = SIGFPE; 1111 + break; 1112 + case VEC_FPIR: 1113 + info.si_code = FPE_FLTRES; 1114 + sig = SIGFPE; 1115 + break; 1116 + case VEC_FPDIVZ: 1117 + info.si_code = FPE_FLTDIV; 1118 + sig = SIGFPE; 1119 + break; 1120 + case VEC_FPUNDER: 1121 + info.si_code = FPE_FLTUND; 1122 + sig = SIGFPE; 1123 + break; 1124 + case VEC_FPOVER: 1125 + info.si_code = FPE_FLTOVF; 1126 + sig = SIGFPE; 1127 + break; 1128 + case VEC_ZERODIV: 1129 + info.si_code = FPE_INTDIV; 1130 + sig = SIGFPE; 1131 + break; 1132 + case VEC_CHK: 1133 + case VEC_TRAP: 1134 + info.si_code = FPE_INTOVF; 1135 + sig = SIGFPE; 1136 + break; 1137 + case VEC_TRACE: /* ptrace single step */ 1138 + info.si_code = TRAP_TRACE; 1139 + sig = SIGTRAP; 1140 + break; 1141 + case VEC_TRAP15: /* breakpoint */ 1142 + info.si_code = TRAP_BRKPT; 1143 + sig = SIGTRAP; 1144 + break; 1145 + default: 1146 + info.si_code = ILL_ILLOPC; 1147 + sig = SIGILL; 1148 + break; 1149 + } 1150 + info.si_signo = sig; 1151 + info.si_errno = 0; 1152 + switch (fp->ptregs.format) { 1153 + default: 1154 + info.si_addr = (void *) fp->ptregs.pc; 1155 + break; 1156 + case 2: 1157 + info.si_addr = (void *) fp->un.fmt2.iaddr; 1158 + break; 1159 + case 7: 1160 + info.si_addr = (void *) fp->un.fmt7.effaddr; 1161 + break; 1162 + case 9: 1163 + info.si_addr = (void *) fp->un.fmt9.iaddr; 1164 + break; 1165 + case 10: 1166 + info.si_addr = (void *) fp->un.fmta.daddr; 1167 + break; 1168 + case 11: 1169 + info.si_addr = (void *) fp->un.fmtb.daddr; 1170 + break; 1171 + } 1172 + force_sig_info (sig, &info, current); 1173 + } 1174 + 1175 + void die_if_kernel (char *str, struct pt_regs *fp, int nr) 1176 + { 1177 + if (!(fp->sr & PS_S)) 1178 + return; 1179 + 1180 + console_verbose(); 1181 + printk("%s: %08x\n",str,nr); 1182 + show_registers(fp); 1183 + add_taint(TAINT_DIE); 1184 + do_exit(SIGSEGV); 1185 + } 1186 + 1187 + /* 1188 + * This function is called if an error occur while accessing 1189 + * user-space from the fpsp040 code. 1190 + */ 1191 + asmlinkage void fpsp040_die(void) 1192 + { 1193 + do_exit(SIGSEGV); 1194 + } 1195 + 1196 + #ifdef CONFIG_M68KFPU_EMU 1197 + asmlinkage void fpemu_signal(int signal, int code, void *addr) 1198 + { 1199 + siginfo_t info; 1200 + 1201 + info.si_signo = signal; 1202 + info.si_errno = 0; 1203 + info.si_code = code; 1204 + info.si_addr = addr; 1205 + force_sig_info(signal, &info, current); 1206 + } 1207 + #endif
+3 -8
arch/m68k/kernel/vmlinux.lds.S
··· 1 - PHDRS 2 - { 3 - text PT_LOAD FILEHDR PHDRS FLAGS (7); 4 - data PT_LOAD FLAGS (7); 5 - } 6 - #ifdef CONFIG_SUN3 7 - #include "vmlinux-sun3.lds" 8 #else 9 - #include "vmlinux-std.lds" 10 #endif
··· 1 + #ifdef CONFIG_MMU 2 + #include "vmlinux.lds_mm.S" 3 #else 4 + #include "vmlinux.lds_no.S" 5 #endif
+10
arch/m68k/kernel/vmlinux.lds_mm.S
···
··· 1 + PHDRS 2 + { 3 + text PT_LOAD FILEHDR PHDRS FLAGS (7); 4 + data PT_LOAD FLAGS (7); 5 + } 6 + #ifdef CONFIG_SUN3 7 + #include "vmlinux-sun3.lds" 8 + #else 9 + #include "vmlinux-std.lds" 10 + #endif
+5 -6
arch/m68k/lib/Makefile
··· 1 - # 2 - # Makefile for m68k-specific library files.. 3 - # 4 - 5 - lib-y := ashldi3.o ashrdi3.o lshrdi3.o muldi3.o \ 6 - checksum.o string.o uaccess.o
··· 1 + ifdef CONFIG_MMU 2 + include arch/m68k/lib/Makefile_mm 3 + else 4 + include arch/m68k/lib/Makefile_no 5 + endif
+6
arch/m68k/lib/Makefile_mm
···
··· 1 + # 2 + # Makefile for m68k-specific library files.. 3 + # 4 + 5 + lib-y := ashldi3.o ashrdi3.o lshrdi3.o muldi3.o \ 6 + checksum.o string.o uaccess.o
+5 -425
arch/m68k/lib/checksum.c
··· 1 - /* 2 - * INET An implementation of the TCP/IP protocol suite for the LINUX 3 - * operating system. INET is implemented using the BSD Socket 4 - * interface as the means of communication with the user level. 5 - * 6 - * IP/TCP/UDP checksumming routines 7 - * 8 - * Authors: Jorge Cwik, <jorge@laser.satlink.net> 9 - * Arnt Gulbrandsen, <agulbra@nvg.unit.no> 10 - * Tom May, <ftom@netcom.com> 11 - * Andreas Schwab, <schwab@issan.informatik.uni-dortmund.de> 12 - * Lots of code moved from tcp.c and ip.c; see those files 13 - * for more names. 14 - * 15 - * 03/02/96 Jes Sorensen, Andreas Schwab, Roman Hodek: 16 - * Fixed some nasty bugs, causing some horrible crashes. 17 - * A: At some points, the sum (%0) was used as 18 - * length-counter instead of the length counter 19 - * (%1). Thanks to Roman Hodek for pointing this out. 20 - * B: GCC seems to mess up if one uses too many 21 - * data-registers to hold input values and one tries to 22 - * specify d0 and d1 as scratch registers. Letting gcc 23 - * choose these registers itself solves the problem. 24 - * 25 - * This program is free software; you can redistribute it and/or 26 - * modify it under the terms of the GNU General Public License 27 - * as published by the Free Software Foundation; either version 28 - * 2 of the License, or (at your option) any later version. 29 - * 30 - * 1998/8/31 Andreas Schwab: 31 - * Zero out rest of buffer on exception in 32 - * csum_partial_copy_from_user. 33 - */ 34 - 35 - #include <linux/module.h> 36 - #include <net/checksum.h> 37 - 38 - /* 39 - * computes a partial checksum, e.g. for TCP/UDP fragments 40 - */ 41 - 42 - __wsum csum_partial(const void *buff, int len, __wsum sum) 43 - { 44 - unsigned long tmp1, tmp2; 45 - /* 46 - * Experiments with ethernet and slip connections show that buff 47 - * is aligned on either a 2-byte or 4-byte boundary. 48 - */ 49 - __asm__("movel %2,%3\n\t" 50 - "btst #1,%3\n\t" /* Check alignment */ 51 - "jeq 2f\n\t" 52 - "subql #2,%1\n\t" /* buff%4==2: treat first word */ 53 - "jgt 1f\n\t" 54 - "addql #2,%1\n\t" /* len was == 2, treat only rest */ 55 - "jra 4f\n" 56 - "1:\t" 57 - "addw %2@+,%0\n\t" /* add first word to sum */ 58 - "clrl %3\n\t" 59 - "addxl %3,%0\n" /* add X bit */ 60 - "2:\t" 61 - /* unrolled loop for the main part: do 8 longs at once */ 62 - "movel %1,%3\n\t" /* save len in tmp1 */ 63 - "lsrl #5,%1\n\t" /* len/32 */ 64 - "jeq 2f\n\t" /* not enough... */ 65 - "subql #1,%1\n" 66 - "1:\t" 67 - "movel %2@+,%4\n\t" 68 - "addxl %4,%0\n\t" 69 - "movel %2@+,%4\n\t" 70 - "addxl %4,%0\n\t" 71 - "movel %2@+,%4\n\t" 72 - "addxl %4,%0\n\t" 73 - "movel %2@+,%4\n\t" 74 - "addxl %4,%0\n\t" 75 - "movel %2@+,%4\n\t" 76 - "addxl %4,%0\n\t" 77 - "movel %2@+,%4\n\t" 78 - "addxl %4,%0\n\t" 79 - "movel %2@+,%4\n\t" 80 - "addxl %4,%0\n\t" 81 - "movel %2@+,%4\n\t" 82 - "addxl %4,%0\n\t" 83 - "dbra %1,1b\n\t" 84 - "clrl %4\n\t" 85 - "addxl %4,%0\n\t" /* add X bit */ 86 - "clrw %1\n\t" 87 - "subql #1,%1\n\t" 88 - "jcc 1b\n" 89 - "2:\t" 90 - "movel %3,%1\n\t" /* restore len from tmp1 */ 91 - "andw #0x1c,%3\n\t" /* number of rest longs */ 92 - "jeq 4f\n\t" 93 - "lsrw #2,%3\n\t" 94 - "subqw #1,%3\n" 95 - "3:\t" 96 - /* loop for rest longs */ 97 - "movel %2@+,%4\n\t" 98 - "addxl %4,%0\n\t" 99 - "dbra %3,3b\n\t" 100 - "clrl %4\n\t" 101 - "addxl %4,%0\n" /* add X bit */ 102 - "4:\t" 103 - /* now check for rest bytes that do not fit into longs */ 104 - "andw #3,%1\n\t" 105 - "jeq 7f\n\t" 106 - "clrl %4\n\t" /* clear tmp2 for rest bytes */ 107 - "subqw #2,%1\n\t" 108 - "jlt 5f\n\t" 109 - "movew %2@+,%4\n\t" /* have rest >= 2: get word */ 110 - "swap %4\n\t" /* into bits 16..31 */ 111 - "tstw %1\n\t" /* another byte? */ 112 - "jeq 6f\n" 113 - "5:\t" 114 - "moveb %2@,%4\n\t" /* have odd rest: get byte */ 115 - "lslw #8,%4\n\t" /* into bits 8..15; 16..31 untouched */ 116 - "6:\t" 117 - "addl %4,%0\n\t" /* now add rest long to sum */ 118 - "clrl %4\n\t" 119 - "addxl %4,%0\n" /* add X bit */ 120 - "7:\t" 121 - : "=d" (sum), "=d" (len), "=a" (buff), 122 - "=&d" (tmp1), "=&d" (tmp2) 123 - : "0" (sum), "1" (len), "2" (buff) 124 - ); 125 - return(sum); 126 - } 127 - 128 - EXPORT_SYMBOL(csum_partial); 129 - 130 - 131 - /* 132 - * copy from user space while checksumming, with exception handling. 133 - */ 134 - 135 - __wsum 136 - csum_partial_copy_from_user(const void __user *src, void *dst, 137 - int len, __wsum sum, int *csum_err) 138 - { 139 - /* 140 - * GCC doesn't like more than 10 operands for the asm 141 - * statements so we have to use tmp2 for the error 142 - * code. 143 - */ 144 - unsigned long tmp1, tmp2; 145 - 146 - __asm__("movel %2,%4\n\t" 147 - "btst #1,%4\n\t" /* Check alignment */ 148 - "jeq 2f\n\t" 149 - "subql #2,%1\n\t" /* buff%4==2: treat first word */ 150 - "jgt 1f\n\t" 151 - "addql #2,%1\n\t" /* len was == 2, treat only rest */ 152 - "jra 4f\n" 153 - "1:\n" 154 - "10:\t" 155 - "movesw %2@+,%4\n\t" /* add first word to sum */ 156 - "addw %4,%0\n\t" 157 - "movew %4,%3@+\n\t" 158 - "clrl %4\n\t" 159 - "addxl %4,%0\n" /* add X bit */ 160 - "2:\t" 161 - /* unrolled loop for the main part: do 8 longs at once */ 162 - "movel %1,%4\n\t" /* save len in tmp1 */ 163 - "lsrl #5,%1\n\t" /* len/32 */ 164 - "jeq 2f\n\t" /* not enough... */ 165 - "subql #1,%1\n" 166 - "1:\n" 167 - "11:\t" 168 - "movesl %2@+,%5\n\t" 169 - "addxl %5,%0\n\t" 170 - "movel %5,%3@+\n\t" 171 - "12:\t" 172 - "movesl %2@+,%5\n\t" 173 - "addxl %5,%0\n\t" 174 - "movel %5,%3@+\n\t" 175 - "13:\t" 176 - "movesl %2@+,%5\n\t" 177 - "addxl %5,%0\n\t" 178 - "movel %5,%3@+\n\t" 179 - "14:\t" 180 - "movesl %2@+,%5\n\t" 181 - "addxl %5,%0\n\t" 182 - "movel %5,%3@+\n\t" 183 - "15:\t" 184 - "movesl %2@+,%5\n\t" 185 - "addxl %5,%0\n\t" 186 - "movel %5,%3@+\n\t" 187 - "16:\t" 188 - "movesl %2@+,%5\n\t" 189 - "addxl %5,%0\n\t" 190 - "movel %5,%3@+\n\t" 191 - "17:\t" 192 - "movesl %2@+,%5\n\t" 193 - "addxl %5,%0\n\t" 194 - "movel %5,%3@+\n\t" 195 - "18:\t" 196 - "movesl %2@+,%5\n\t" 197 - "addxl %5,%0\n\t" 198 - "movel %5,%3@+\n\t" 199 - "dbra %1,1b\n\t" 200 - "clrl %5\n\t" 201 - "addxl %5,%0\n\t" /* add X bit */ 202 - "clrw %1\n\t" 203 - "subql #1,%1\n\t" 204 - "jcc 1b\n" 205 - "2:\t" 206 - "movel %4,%1\n\t" /* restore len from tmp1 */ 207 - "andw #0x1c,%4\n\t" /* number of rest longs */ 208 - "jeq 4f\n\t" 209 - "lsrw #2,%4\n\t" 210 - "subqw #1,%4\n" 211 - "3:\n" 212 - /* loop for rest longs */ 213 - "19:\t" 214 - "movesl %2@+,%5\n\t" 215 - "addxl %5,%0\n\t" 216 - "movel %5,%3@+\n\t" 217 - "dbra %4,3b\n\t" 218 - "clrl %5\n\t" 219 - "addxl %5,%0\n" /* add X bit */ 220 - "4:\t" 221 - /* now check for rest bytes that do not fit into longs */ 222 - "andw #3,%1\n\t" 223 - "jeq 7f\n\t" 224 - "clrl %5\n\t" /* clear tmp2 for rest bytes */ 225 - "subqw #2,%1\n\t" 226 - "jlt 5f\n\t" 227 - "20:\t" 228 - "movesw %2@+,%5\n\t" /* have rest >= 2: get word */ 229 - "movew %5,%3@+\n\t" 230 - "swap %5\n\t" /* into bits 16..31 */ 231 - "tstw %1\n\t" /* another byte? */ 232 - "jeq 6f\n" 233 - "5:\n" 234 - "21:\t" 235 - "movesb %2@,%5\n\t" /* have odd rest: get byte */ 236 - "moveb %5,%3@+\n\t" 237 - "lslw #8,%5\n\t" /* into bits 8..15; 16..31 untouched */ 238 - "6:\t" 239 - "addl %5,%0\n\t" /* now add rest long to sum */ 240 - "clrl %5\n\t" 241 - "addxl %5,%0\n\t" /* add X bit */ 242 - "7:\t" 243 - "clrl %5\n" /* no error - clear return value */ 244 - "8:\n" 245 - ".section .fixup,\"ax\"\n" 246 - ".even\n" 247 - /* If any exception occurs zero out the rest. 248 - Similarities with the code above are intentional :-) */ 249 - "90:\t" 250 - "clrw %3@+\n\t" 251 - "movel %1,%4\n\t" 252 - "lsrl #5,%1\n\t" 253 - "jeq 1f\n\t" 254 - "subql #1,%1\n" 255 - "91:\t" 256 - "clrl %3@+\n" 257 - "92:\t" 258 - "clrl %3@+\n" 259 - "93:\t" 260 - "clrl %3@+\n" 261 - "94:\t" 262 - "clrl %3@+\n" 263 - "95:\t" 264 - "clrl %3@+\n" 265 - "96:\t" 266 - "clrl %3@+\n" 267 - "97:\t" 268 - "clrl %3@+\n" 269 - "98:\t" 270 - "clrl %3@+\n\t" 271 - "dbra %1,91b\n\t" 272 - "clrw %1\n\t" 273 - "subql #1,%1\n\t" 274 - "jcc 91b\n" 275 - "1:\t" 276 - "movel %4,%1\n\t" 277 - "andw #0x1c,%4\n\t" 278 - "jeq 1f\n\t" 279 - "lsrw #2,%4\n\t" 280 - "subqw #1,%4\n" 281 - "99:\t" 282 - "clrl %3@+\n\t" 283 - "dbra %4,99b\n\t" 284 - "1:\t" 285 - "andw #3,%1\n\t" 286 - "jeq 9f\n" 287 - "100:\t" 288 - "clrw %3@+\n\t" 289 - "tstw %1\n\t" 290 - "jeq 9f\n" 291 - "101:\t" 292 - "clrb %3@+\n" 293 - "9:\t" 294 - #define STR(X) STR1(X) 295 - #define STR1(X) #X 296 - "moveq #-" STR(EFAULT) ",%5\n\t" 297 - "jra 8b\n" 298 - ".previous\n" 299 - ".section __ex_table,\"a\"\n" 300 - ".long 10b,90b\n" 301 - ".long 11b,91b\n" 302 - ".long 12b,92b\n" 303 - ".long 13b,93b\n" 304 - ".long 14b,94b\n" 305 - ".long 15b,95b\n" 306 - ".long 16b,96b\n" 307 - ".long 17b,97b\n" 308 - ".long 18b,98b\n" 309 - ".long 19b,99b\n" 310 - ".long 20b,100b\n" 311 - ".long 21b,101b\n" 312 - ".previous" 313 - : "=d" (sum), "=d" (len), "=a" (src), "=a" (dst), 314 - "=&d" (tmp1), "=d" (tmp2) 315 - : "0" (sum), "1" (len), "2" (src), "3" (dst) 316 - ); 317 - 318 - *csum_err = tmp2; 319 - 320 - return(sum); 321 - } 322 - 323 - EXPORT_SYMBOL(csum_partial_copy_from_user); 324 - 325 - 326 - /* 327 - * copy from kernel space while checksumming, otherwise like csum_partial 328 - */ 329 - 330 - __wsum 331 - csum_partial_copy_nocheck(const void *src, void *dst, int len, __wsum sum) 332 - { 333 - unsigned long tmp1, tmp2; 334 - __asm__("movel %2,%4\n\t" 335 - "btst #1,%4\n\t" /* Check alignment */ 336 - "jeq 2f\n\t" 337 - "subql #2,%1\n\t" /* buff%4==2: treat first word */ 338 - "jgt 1f\n\t" 339 - "addql #2,%1\n\t" /* len was == 2, treat only rest */ 340 - "jra 4f\n" 341 - "1:\t" 342 - "movew %2@+,%4\n\t" /* add first word to sum */ 343 - "addw %4,%0\n\t" 344 - "movew %4,%3@+\n\t" 345 - "clrl %4\n\t" 346 - "addxl %4,%0\n" /* add X bit */ 347 - "2:\t" 348 - /* unrolled loop for the main part: do 8 longs at once */ 349 - "movel %1,%4\n\t" /* save len in tmp1 */ 350 - "lsrl #5,%1\n\t" /* len/32 */ 351 - "jeq 2f\n\t" /* not enough... */ 352 - "subql #1,%1\n" 353 - "1:\t" 354 - "movel %2@+,%5\n\t" 355 - "addxl %5,%0\n\t" 356 - "movel %5,%3@+\n\t" 357 - "movel %2@+,%5\n\t" 358 - "addxl %5,%0\n\t" 359 - "movel %5,%3@+\n\t" 360 - "movel %2@+,%5\n\t" 361 - "addxl %5,%0\n\t" 362 - "movel %5,%3@+\n\t" 363 - "movel %2@+,%5\n\t" 364 - "addxl %5,%0\n\t" 365 - "movel %5,%3@+\n\t" 366 - "movel %2@+,%5\n\t" 367 - "addxl %5,%0\n\t" 368 - "movel %5,%3@+\n\t" 369 - "movel %2@+,%5\n\t" 370 - "addxl %5,%0\n\t" 371 - "movel %5,%3@+\n\t" 372 - "movel %2@+,%5\n\t" 373 - "addxl %5,%0\n\t" 374 - "movel %5,%3@+\n\t" 375 - "movel %2@+,%5\n\t" 376 - "addxl %5,%0\n\t" 377 - "movel %5,%3@+\n\t" 378 - "dbra %1,1b\n\t" 379 - "clrl %5\n\t" 380 - "addxl %5,%0\n\t" /* add X bit */ 381 - "clrw %1\n\t" 382 - "subql #1,%1\n\t" 383 - "jcc 1b\n" 384 - "2:\t" 385 - "movel %4,%1\n\t" /* restore len from tmp1 */ 386 - "andw #0x1c,%4\n\t" /* number of rest longs */ 387 - "jeq 4f\n\t" 388 - "lsrw #2,%4\n\t" 389 - "subqw #1,%4\n" 390 - "3:\t" 391 - /* loop for rest longs */ 392 - "movel %2@+,%5\n\t" 393 - "addxl %5,%0\n\t" 394 - "movel %5,%3@+\n\t" 395 - "dbra %4,3b\n\t" 396 - "clrl %5\n\t" 397 - "addxl %5,%0\n" /* add X bit */ 398 - "4:\t" 399 - /* now check for rest bytes that do not fit into longs */ 400 - "andw #3,%1\n\t" 401 - "jeq 7f\n\t" 402 - "clrl %5\n\t" /* clear tmp2 for rest bytes */ 403 - "subqw #2,%1\n\t" 404 - "jlt 5f\n\t" 405 - "movew %2@+,%5\n\t" /* have rest >= 2: get word */ 406 - "movew %5,%3@+\n\t" 407 - "swap %5\n\t" /* into bits 16..31 */ 408 - "tstw %1\n\t" /* another byte? */ 409 - "jeq 6f\n" 410 - "5:\t" 411 - "moveb %2@,%5\n\t" /* have odd rest: get byte */ 412 - "moveb %5,%3@+\n\t" 413 - "lslw #8,%5\n" /* into bits 8..15; 16..31 untouched */ 414 - "6:\t" 415 - "addl %5,%0\n\t" /* now add rest long to sum */ 416 - "clrl %5\n\t" 417 - "addxl %5,%0\n" /* add X bit */ 418 - "7:\t" 419 - : "=d" (sum), "=d" (len), "=a" (src), "=a" (dst), 420 - "=&d" (tmp1), "=&d" (tmp2) 421 - : "0" (sum), "1" (len), "2" (src), "3" (dst) 422 - ); 423 - return(sum); 424 - } 425 - EXPORT_SYMBOL(csum_partial_copy_nocheck);
··· 1 + #ifdef CONFIG_MMU 2 + #include "checksum_mm.c" 3 + #else 4 + #include "checksum_no.c" 5 + #endif
+425
arch/m68k/lib/checksum_mm.c
···
··· 1 + /* 2 + * INET An implementation of the TCP/IP protocol suite for the LINUX 3 + * operating system. INET is implemented using the BSD Socket 4 + * interface as the means of communication with the user level. 5 + * 6 + * IP/TCP/UDP checksumming routines 7 + * 8 + * Authors: Jorge Cwik, <jorge@laser.satlink.net> 9 + * Arnt Gulbrandsen, <agulbra@nvg.unit.no> 10 + * Tom May, <ftom@netcom.com> 11 + * Andreas Schwab, <schwab@issan.informatik.uni-dortmund.de> 12 + * Lots of code moved from tcp.c and ip.c; see those files 13 + * for more names. 14 + * 15 + * 03/02/96 Jes Sorensen, Andreas Schwab, Roman Hodek: 16 + * Fixed some nasty bugs, causing some horrible crashes. 17 + * A: At some points, the sum (%0) was used as 18 + * length-counter instead of the length counter 19 + * (%1). Thanks to Roman Hodek for pointing this out. 20 + * B: GCC seems to mess up if one uses too many 21 + * data-registers to hold input values and one tries to 22 + * specify d0 and d1 as scratch registers. Letting gcc 23 + * choose these registers itself solves the problem. 24 + * 25 + * This program is free software; you can redistribute it and/or 26 + * modify it under the terms of the GNU General Public License 27 + * as published by the Free Software Foundation; either version 28 + * 2 of the License, or (at your option) any later version. 29 + * 30 + * 1998/8/31 Andreas Schwab: 31 + * Zero out rest of buffer on exception in 32 + * csum_partial_copy_from_user. 33 + */ 34 + 35 + #include <linux/module.h> 36 + #include <net/checksum.h> 37 + 38 + /* 39 + * computes a partial checksum, e.g. for TCP/UDP fragments 40 + */ 41 + 42 + __wsum csum_partial(const void *buff, int len, __wsum sum) 43 + { 44 + unsigned long tmp1, tmp2; 45 + /* 46 + * Experiments with ethernet and slip connections show that buff 47 + * is aligned on either a 2-byte or 4-byte boundary. 48 + */ 49 + __asm__("movel %2,%3\n\t" 50 + "btst #1,%3\n\t" /* Check alignment */ 51 + "jeq 2f\n\t" 52 + "subql #2,%1\n\t" /* buff%4==2: treat first word */ 53 + "jgt 1f\n\t" 54 + "addql #2,%1\n\t" /* len was == 2, treat only rest */ 55 + "jra 4f\n" 56 + "1:\t" 57 + "addw %2@+,%0\n\t" /* add first word to sum */ 58 + "clrl %3\n\t" 59 + "addxl %3,%0\n" /* add X bit */ 60 + "2:\t" 61 + /* unrolled loop for the main part: do 8 longs at once */ 62 + "movel %1,%3\n\t" /* save len in tmp1 */ 63 + "lsrl #5,%1\n\t" /* len/32 */ 64 + "jeq 2f\n\t" /* not enough... */ 65 + "subql #1,%1\n" 66 + "1:\t" 67 + "movel %2@+,%4\n\t" 68 + "addxl %4,%0\n\t" 69 + "movel %2@+,%4\n\t" 70 + "addxl %4,%0\n\t" 71 + "movel %2@+,%4\n\t" 72 + "addxl %4,%0\n\t" 73 + "movel %2@+,%4\n\t" 74 + "addxl %4,%0\n\t" 75 + "movel %2@+,%4\n\t" 76 + "addxl %4,%0\n\t" 77 + "movel %2@+,%4\n\t" 78 + "addxl %4,%0\n\t" 79 + "movel %2@+,%4\n\t" 80 + "addxl %4,%0\n\t" 81 + "movel %2@+,%4\n\t" 82 + "addxl %4,%0\n\t" 83 + "dbra %1,1b\n\t" 84 + "clrl %4\n\t" 85 + "addxl %4,%0\n\t" /* add X bit */ 86 + "clrw %1\n\t" 87 + "subql #1,%1\n\t" 88 + "jcc 1b\n" 89 + "2:\t" 90 + "movel %3,%1\n\t" /* restore len from tmp1 */ 91 + "andw #0x1c,%3\n\t" /* number of rest longs */ 92 + "jeq 4f\n\t" 93 + "lsrw #2,%3\n\t" 94 + "subqw #1,%3\n" 95 + "3:\t" 96 + /* loop for rest longs */ 97 + "movel %2@+,%4\n\t" 98 + "addxl %4,%0\n\t" 99 + "dbra %3,3b\n\t" 100 + "clrl %4\n\t" 101 + "addxl %4,%0\n" /* add X bit */ 102 + "4:\t" 103 + /* now check for rest bytes that do not fit into longs */ 104 + "andw #3,%1\n\t" 105 + "jeq 7f\n\t" 106 + "clrl %4\n\t" /* clear tmp2 for rest bytes */ 107 + "subqw #2,%1\n\t" 108 + "jlt 5f\n\t" 109 + "movew %2@+,%4\n\t" /* have rest >= 2: get word */ 110 + "swap %4\n\t" /* into bits 16..31 */ 111 + "tstw %1\n\t" /* another byte? */ 112 + "jeq 6f\n" 113 + "5:\t" 114 + "moveb %2@,%4\n\t" /* have odd rest: get byte */ 115 + "lslw #8,%4\n\t" /* into bits 8..15; 16..31 untouched */ 116 + "6:\t" 117 + "addl %4,%0\n\t" /* now add rest long to sum */ 118 + "clrl %4\n\t" 119 + "addxl %4,%0\n" /* add X bit */ 120 + "7:\t" 121 + : "=d" (sum), "=d" (len), "=a" (buff), 122 + "=&d" (tmp1), "=&d" (tmp2) 123 + : "0" (sum), "1" (len), "2" (buff) 124 + ); 125 + return(sum); 126 + } 127 + 128 + EXPORT_SYMBOL(csum_partial); 129 + 130 + 131 + /* 132 + * copy from user space while checksumming, with exception handling. 133 + */ 134 + 135 + __wsum 136 + csum_partial_copy_from_user(const void __user *src, void *dst, 137 + int len, __wsum sum, int *csum_err) 138 + { 139 + /* 140 + * GCC doesn't like more than 10 operands for the asm 141 + * statements so we have to use tmp2 for the error 142 + * code. 143 + */ 144 + unsigned long tmp1, tmp2; 145 + 146 + __asm__("movel %2,%4\n\t" 147 + "btst #1,%4\n\t" /* Check alignment */ 148 + "jeq 2f\n\t" 149 + "subql #2,%1\n\t" /* buff%4==2: treat first word */ 150 + "jgt 1f\n\t" 151 + "addql #2,%1\n\t" /* len was == 2, treat only rest */ 152 + "jra 4f\n" 153 + "1:\n" 154 + "10:\t" 155 + "movesw %2@+,%4\n\t" /* add first word to sum */ 156 + "addw %4,%0\n\t" 157 + "movew %4,%3@+\n\t" 158 + "clrl %4\n\t" 159 + "addxl %4,%0\n" /* add X bit */ 160 + "2:\t" 161 + /* unrolled loop for the main part: do 8 longs at once */ 162 + "movel %1,%4\n\t" /* save len in tmp1 */ 163 + "lsrl #5,%1\n\t" /* len/32 */ 164 + "jeq 2f\n\t" /* not enough... */ 165 + "subql #1,%1\n" 166 + "1:\n" 167 + "11:\t" 168 + "movesl %2@+,%5\n\t" 169 + "addxl %5,%0\n\t" 170 + "movel %5,%3@+\n\t" 171 + "12:\t" 172 + "movesl %2@+,%5\n\t" 173 + "addxl %5,%0\n\t" 174 + "movel %5,%3@+\n\t" 175 + "13:\t" 176 + "movesl %2@+,%5\n\t" 177 + "addxl %5,%0\n\t" 178 + "movel %5,%3@+\n\t" 179 + "14:\t" 180 + "movesl %2@+,%5\n\t" 181 + "addxl %5,%0\n\t" 182 + "movel %5,%3@+\n\t" 183 + "15:\t" 184 + "movesl %2@+,%5\n\t" 185 + "addxl %5,%0\n\t" 186 + "movel %5,%3@+\n\t" 187 + "16:\t" 188 + "movesl %2@+,%5\n\t" 189 + "addxl %5,%0\n\t" 190 + "movel %5,%3@+\n\t" 191 + "17:\t" 192 + "movesl %2@+,%5\n\t" 193 + "addxl %5,%0\n\t" 194 + "movel %5,%3@+\n\t" 195 + "18:\t" 196 + "movesl %2@+,%5\n\t" 197 + "addxl %5,%0\n\t" 198 + "movel %5,%3@+\n\t" 199 + "dbra %1,1b\n\t" 200 + "clrl %5\n\t" 201 + "addxl %5,%0\n\t" /* add X bit */ 202 + "clrw %1\n\t" 203 + "subql #1,%1\n\t" 204 + "jcc 1b\n" 205 + "2:\t" 206 + "movel %4,%1\n\t" /* restore len from tmp1 */ 207 + "andw #0x1c,%4\n\t" /* number of rest longs */ 208 + "jeq 4f\n\t" 209 + "lsrw #2,%4\n\t" 210 + "subqw #1,%4\n" 211 + "3:\n" 212 + /* loop for rest longs */ 213 + "19:\t" 214 + "movesl %2@+,%5\n\t" 215 + "addxl %5,%0\n\t" 216 + "movel %5,%3@+\n\t" 217 + "dbra %4,3b\n\t" 218 + "clrl %5\n\t" 219 + "addxl %5,%0\n" /* add X bit */ 220 + "4:\t" 221 + /* now check for rest bytes that do not fit into longs */ 222 + "andw #3,%1\n\t" 223 + "jeq 7f\n\t" 224 + "clrl %5\n\t" /* clear tmp2 for rest bytes */ 225 + "subqw #2,%1\n\t" 226 + "jlt 5f\n\t" 227 + "20:\t" 228 + "movesw %2@+,%5\n\t" /* have rest >= 2: get word */ 229 + "movew %5,%3@+\n\t" 230 + "swap %5\n\t" /* into bits 16..31 */ 231 + "tstw %1\n\t" /* another byte? */ 232 + "jeq 6f\n" 233 + "5:\n" 234 + "21:\t" 235 + "movesb %2@,%5\n\t" /* have odd rest: get byte */ 236 + "moveb %5,%3@+\n\t" 237 + "lslw #8,%5\n\t" /* into bits 8..15; 16..31 untouched */ 238 + "6:\t" 239 + "addl %5,%0\n\t" /* now add rest long to sum */ 240 + "clrl %5\n\t" 241 + "addxl %5,%0\n\t" /* add X bit */ 242 + "7:\t" 243 + "clrl %5\n" /* no error - clear return value */ 244 + "8:\n" 245 + ".section .fixup,\"ax\"\n" 246 + ".even\n" 247 + /* If any exception occurs zero out the rest. 248 + Similarities with the code above are intentional :-) */ 249 + "90:\t" 250 + "clrw %3@+\n\t" 251 + "movel %1,%4\n\t" 252 + "lsrl #5,%1\n\t" 253 + "jeq 1f\n\t" 254 + "subql #1,%1\n" 255 + "91:\t" 256 + "clrl %3@+\n" 257 + "92:\t" 258 + "clrl %3@+\n" 259 + "93:\t" 260 + "clrl %3@+\n" 261 + "94:\t" 262 + "clrl %3@+\n" 263 + "95:\t" 264 + "clrl %3@+\n" 265 + "96:\t" 266 + "clrl %3@+\n" 267 + "97:\t" 268 + "clrl %3@+\n" 269 + "98:\t" 270 + "clrl %3@+\n\t" 271 + "dbra %1,91b\n\t" 272 + "clrw %1\n\t" 273 + "subql #1,%1\n\t" 274 + "jcc 91b\n" 275 + "1:\t" 276 + "movel %4,%1\n\t" 277 + "andw #0x1c,%4\n\t" 278 + "jeq 1f\n\t" 279 + "lsrw #2,%4\n\t" 280 + "subqw #1,%4\n" 281 + "99:\t" 282 + "clrl %3@+\n\t" 283 + "dbra %4,99b\n\t" 284 + "1:\t" 285 + "andw #3,%1\n\t" 286 + "jeq 9f\n" 287 + "100:\t" 288 + "clrw %3@+\n\t" 289 + "tstw %1\n\t" 290 + "jeq 9f\n" 291 + "101:\t" 292 + "clrb %3@+\n" 293 + "9:\t" 294 + #define STR(X) STR1(X) 295 + #define STR1(X) #X 296 + "moveq #-" STR(EFAULT) ",%5\n\t" 297 + "jra 8b\n" 298 + ".previous\n" 299 + ".section __ex_table,\"a\"\n" 300 + ".long 10b,90b\n" 301 + ".long 11b,91b\n" 302 + ".long 12b,92b\n" 303 + ".long 13b,93b\n" 304 + ".long 14b,94b\n" 305 + ".long 15b,95b\n" 306 + ".long 16b,96b\n" 307 + ".long 17b,97b\n" 308 + ".long 18b,98b\n" 309 + ".long 19b,99b\n" 310 + ".long 20b,100b\n" 311 + ".long 21b,101b\n" 312 + ".previous" 313 + : "=d" (sum), "=d" (len), "=a" (src), "=a" (dst), 314 + "=&d" (tmp1), "=d" (tmp2) 315 + : "0" (sum), "1" (len), "2" (src), "3" (dst) 316 + ); 317 + 318 + *csum_err = tmp2; 319 + 320 + return(sum); 321 + } 322 + 323 + EXPORT_SYMBOL(csum_partial_copy_from_user); 324 + 325 + 326 + /* 327 + * copy from kernel space while checksumming, otherwise like csum_partial 328 + */ 329 + 330 + __wsum 331 + csum_partial_copy_nocheck(const void *src, void *dst, int len, __wsum sum) 332 + { 333 + unsigned long tmp1, tmp2; 334 + __asm__("movel %2,%4\n\t" 335 + "btst #1,%4\n\t" /* Check alignment */ 336 + "jeq 2f\n\t" 337 + "subql #2,%1\n\t" /* buff%4==2: treat first word */ 338 + "jgt 1f\n\t" 339 + "addql #2,%1\n\t" /* len was == 2, treat only rest */ 340 + "jra 4f\n" 341 + "1:\t" 342 + "movew %2@+,%4\n\t" /* add first word to sum */ 343 + "addw %4,%0\n\t" 344 + "movew %4,%3@+\n\t" 345 + "clrl %4\n\t" 346 + "addxl %4,%0\n" /* add X bit */ 347 + "2:\t" 348 + /* unrolled loop for the main part: do 8 longs at once */ 349 + "movel %1,%4\n\t" /* save len in tmp1 */ 350 + "lsrl #5,%1\n\t" /* len/32 */ 351 + "jeq 2f\n\t" /* not enough... */ 352 + "subql #1,%1\n" 353 + "1:\t" 354 + "movel %2@+,%5\n\t" 355 + "addxl %5,%0\n\t" 356 + "movel %5,%3@+\n\t" 357 + "movel %2@+,%5\n\t" 358 + "addxl %5,%0\n\t" 359 + "movel %5,%3@+\n\t" 360 + "movel %2@+,%5\n\t" 361 + "addxl %5,%0\n\t" 362 + "movel %5,%3@+\n\t" 363 + "movel %2@+,%5\n\t" 364 + "addxl %5,%0\n\t" 365 + "movel %5,%3@+\n\t" 366 + "movel %2@+,%5\n\t" 367 + "addxl %5,%0\n\t" 368 + "movel %5,%3@+\n\t" 369 + "movel %2@+,%5\n\t" 370 + "addxl %5,%0\n\t" 371 + "movel %5,%3@+\n\t" 372 + "movel %2@+,%5\n\t" 373 + "addxl %5,%0\n\t" 374 + "movel %5,%3@+\n\t" 375 + "movel %2@+,%5\n\t" 376 + "addxl %5,%0\n\t" 377 + "movel %5,%3@+\n\t" 378 + "dbra %1,1b\n\t" 379 + "clrl %5\n\t" 380 + "addxl %5,%0\n\t" /* add X bit */ 381 + "clrw %1\n\t" 382 + "subql #1,%1\n\t" 383 + "jcc 1b\n" 384 + "2:\t" 385 + "movel %4,%1\n\t" /* restore len from tmp1 */ 386 + "andw #0x1c,%4\n\t" /* number of rest longs */ 387 + "jeq 4f\n\t" 388 + "lsrw #2,%4\n\t" 389 + "subqw #1,%4\n" 390 + "3:\t" 391 + /* loop for rest longs */ 392 + "movel %2@+,%5\n\t" 393 + "addxl %5,%0\n\t" 394 + "movel %5,%3@+\n\t" 395 + "dbra %4,3b\n\t" 396 + "clrl %5\n\t" 397 + "addxl %5,%0\n" /* add X bit */ 398 + "4:\t" 399 + /* now check for rest bytes that do not fit into longs */ 400 + "andw #3,%1\n\t" 401 + "jeq 7f\n\t" 402 + "clrl %5\n\t" /* clear tmp2 for rest bytes */ 403 + "subqw #2,%1\n\t" 404 + "jlt 5f\n\t" 405 + "movew %2@+,%5\n\t" /* have rest >= 2: get word */ 406 + "movew %5,%3@+\n\t" 407 + "swap %5\n\t" /* into bits 16..31 */ 408 + "tstw %1\n\t" /* another byte? */ 409 + "jeq 6f\n" 410 + "5:\t" 411 + "moveb %2@,%5\n\t" /* have odd rest: get byte */ 412 + "moveb %5,%3@+\n\t" 413 + "lslw #8,%5\n" /* into bits 8..15; 16..31 untouched */ 414 + "6:\t" 415 + "addl %5,%0\n\t" /* now add rest long to sum */ 416 + "clrl %5\n\t" 417 + "addxl %5,%0\n" /* add X bit */ 418 + "7:\t" 419 + : "=d" (sum), "=d" (len), "=a" (src), "=a" (dst), 420 + "=&d" (tmp1), "=&d" (tmp2) 421 + : "0" (sum), "1" (len), "2" (src), "3" (dst) 422 + ); 423 + return(sum); 424 + } 425 + EXPORT_SYMBOL(csum_partial_copy_nocheck);
+5 -63
arch/m68k/lib/muldi3.c
··· 1 - /* muldi3.c extracted from gcc-2.7.2.3/libgcc2.c and 2 - gcc-2.7.2.3/longlong.h which is: */ 3 - /* Copyright (C) 1989, 1992, 1993, 1994, 1995 Free Software Foundation, Inc. 4 - 5 - This file is part of GNU CC. 6 - 7 - GNU CC is free software; you can redistribute it and/or modify 8 - it under the terms of the GNU General Public License as published by 9 - the Free Software Foundation; either version 2, or (at your option) 10 - any later version. 11 - 12 - GNU CC is distributed in the hope that it will be useful, 13 - but WITHOUT ANY WARRANTY; without even the implied warranty of 14 - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 - GNU General Public License for more details. 16 - 17 - You should have received a copy of the GNU General Public License 18 - along with GNU CC; see the file COPYING. If not, write to 19 - the Free Software Foundation, 59 Temple Place - Suite 330, 20 - Boston, MA 02111-1307, USA. */ 21 - 22 - #define BITS_PER_UNIT 8 23 - 24 - #define umul_ppmm(w1, w0, u, v) \ 25 - __asm__ ("mulu%.l %3,%1:%0" \ 26 - : "=d" ((USItype)(w0)), \ 27 - "=d" ((USItype)(w1)) \ 28 - : "%0" ((USItype)(u)), \ 29 - "dmi" ((USItype)(v))) 30 - 31 - #define __umulsidi3(u, v) \ 32 - ({DIunion __w; \ 33 - umul_ppmm (__w.s.high, __w.s.low, u, v); \ 34 - __w.ll; }) 35 - 36 - typedef int SItype __attribute__ ((mode (SI))); 37 - typedef unsigned int USItype __attribute__ ((mode (SI))); 38 - typedef int DItype __attribute__ ((mode (DI))); 39 - typedef int word_type __attribute__ ((mode (__word__))); 40 - 41 - struct DIstruct {SItype high, low;}; 42 - 43 - typedef union 44 - { 45 - struct DIstruct s; 46 - DItype ll; 47 - } DIunion; 48 - 49 - DItype 50 - __muldi3 (DItype u, DItype v) 51 - { 52 - DIunion w; 53 - DIunion uu, vv; 54 - 55 - uu.ll = u, 56 - vv.ll = v; 57 - 58 - w.ll = __umulsidi3 (uu.s.low, vv.s.low); 59 - w.s.high += ((USItype) uu.s.low * (USItype) vv.s.high 60 - + (USItype) uu.s.high * (USItype) vv.s.low); 61 - 62 - return w.ll; 63 - }
··· 1 + #ifdef CONFIG_MMU 2 + #include "muldi3_mm.c" 3 + #else 4 + #include "muldi3_no.c" 5 + #endif
+5 -8
arch/m68k/mm/Makefile
··· 1 - # 2 - # Makefile for the linux m68k-specific parts of the memory manager. 3 - # 4 - 5 - obj-y := cache.o init.o fault.o hwtest.o 6 - 7 - obj-$(CONFIG_MMU_MOTOROLA) += kmap.o memory.o motorola.o 8 - obj-$(CONFIG_MMU_SUN3) += sun3kmap.o sun3mmu.o
··· 1 + ifdef CONFIG_MMU 2 + include arch/m68k/mm/Makefile_mm 3 + else 4 + include arch/m68k/mm/Makefile_no 5 + endif
+8
arch/m68k/mm/Makefile_mm
···
··· 1 + # 2 + # Makefile for the linux m68k-specific parts of the memory manager. 3 + # 4 + 5 + obj-y := cache.o init.o fault.o hwtest.o 6 + 7 + obj-$(CONFIG_MMU_MOTOROLA) += kmap.o memory.o motorola.o 8 + obj-$(CONFIG_MMU_SUN3) += sun3kmap.o sun3mmu.o
+4 -149
arch/m68k/mm/init.c
··· 1 - /* 2 - * linux/arch/m68k/mm/init.c 3 - * 4 - * Copyright (C) 1995 Hamish Macdonald 5 - * 6 - * Contains common initialization routines, specific init code moved 7 - * to motorola.c and sun3mmu.c 8 - */ 9 - 10 - #include <linux/module.h> 11 - #include <linux/signal.h> 12 - #include <linux/sched.h> 13 - #include <linux/mm.h> 14 - #include <linux/swap.h> 15 - #include <linux/kernel.h> 16 - #include <linux/string.h> 17 - #include <linux/types.h> 18 - #include <linux/init.h> 19 - #include <linux/bootmem.h> 20 - #include <linux/gfp.h> 21 - 22 - #include <asm/setup.h> 23 - #include <asm/uaccess.h> 24 - #include <asm/page.h> 25 - #include <asm/pgalloc.h> 26 - #include <asm/system.h> 27 - #include <asm/machdep.h> 28 - #include <asm/io.h> 29 - #ifdef CONFIG_ATARI 30 - #include <asm/atari_stram.h> 31 - #endif 32 - #include <asm/sections.h> 33 - #include <asm/tlb.h> 34 - 35 - DEFINE_PER_CPU(struct mmu_gather, mmu_gathers); 36 - 37 - pg_data_t pg_data_map[MAX_NUMNODES]; 38 - EXPORT_SYMBOL(pg_data_map); 39 - 40 - int m68k_virt_to_node_shift; 41 - 42 - #ifndef CONFIG_SINGLE_MEMORY_CHUNK 43 - pg_data_t *pg_data_table[65]; 44 - EXPORT_SYMBOL(pg_data_table); 45 - #endif 46 - 47 - void __init m68k_setup_node(int node) 48 - { 49 - #ifndef CONFIG_SINGLE_MEMORY_CHUNK 50 - struct mem_info *info = m68k_memory + node; 51 - int i, end; 52 - 53 - i = (unsigned long)phys_to_virt(info->addr) >> __virt_to_node_shift(); 54 - end = (unsigned long)phys_to_virt(info->addr + info->size - 1) >> __virt_to_node_shift(); 55 - for (; i <= end; i++) { 56 - if (pg_data_table[i]) 57 - printk("overlap at %u for chunk %u\n", i, node); 58 - pg_data_table[i] = pg_data_map + node; 59 - } 60 - #endif 61 - pg_data_map[node].bdata = bootmem_node_data + node; 62 - node_set_online(node); 63 - } 64 - 65 - 66 - /* 67 - * ZERO_PAGE is a special page that is used for zero-initialized 68 - * data and COW. 69 - */ 70 - 71 - void *empty_zero_page; 72 - EXPORT_SYMBOL(empty_zero_page); 73 - 74 - extern void init_pointer_table(unsigned long ptable); 75 - 76 - /* References to section boundaries */ 77 - 78 - extern pmd_t *zero_pgtable; 79 - 80 - void __init mem_init(void) 81 - { 82 - pg_data_t *pgdat; 83 - int codepages = 0; 84 - int datapages = 0; 85 - int initpages = 0; 86 - int i; 87 - 88 - #ifdef CONFIG_ATARI 89 - if (MACH_IS_ATARI) 90 - atari_stram_mem_init_hook(); 91 - #endif 92 - 93 - /* this will put all memory onto the freelists */ 94 - totalram_pages = num_physpages = 0; 95 - for_each_online_pgdat(pgdat) { 96 - num_physpages += pgdat->node_present_pages; 97 - 98 - totalram_pages += free_all_bootmem_node(pgdat); 99 - for (i = 0; i < pgdat->node_spanned_pages; i++) { 100 - struct page *page = pgdat->node_mem_map + i; 101 - char *addr = page_to_virt(page); 102 - 103 - if (!PageReserved(page)) 104 - continue; 105 - if (addr >= _text && 106 - addr < _etext) 107 - codepages++; 108 - else if (addr >= __init_begin && 109 - addr < __init_end) 110 - initpages++; 111 - else 112 - datapages++; 113 - } 114 - } 115 - 116 - #ifndef CONFIG_SUN3 117 - /* insert pointer tables allocated so far into the tablelist */ 118 - init_pointer_table((unsigned long)kernel_pg_dir); 119 - for (i = 0; i < PTRS_PER_PGD; i++) { 120 - if (pgd_present(kernel_pg_dir[i])) 121 - init_pointer_table(__pgd_page(kernel_pg_dir[i])); 122 - } 123 - 124 - /* insert also pointer table that we used to unmap the zero page */ 125 - if (zero_pgtable) 126 - init_pointer_table((unsigned long)zero_pgtable); 127 - #endif 128 - 129 - printk("Memory: %luk/%luk available (%dk kernel code, %dk data, %dk init)\n", 130 - nr_free_pages() << (PAGE_SHIFT-10), 131 - totalram_pages << (PAGE_SHIFT-10), 132 - codepages << (PAGE_SHIFT-10), 133 - datapages << (PAGE_SHIFT-10), 134 - initpages << (PAGE_SHIFT-10)); 135 - } 136 - 137 - #ifdef CONFIG_BLK_DEV_INITRD 138 - void free_initrd_mem(unsigned long start, unsigned long end) 139 - { 140 - int pages = 0; 141 - for (; start < end; start += PAGE_SIZE) { 142 - ClearPageReserved(virt_to_page(start)); 143 - init_page_count(virt_to_page(start)); 144 - free_page(start); 145 - totalram_pages++; 146 - pages++; 147 - } 148 - printk ("Freeing initrd memory: %dk freed\n", pages); 149 - } 150 #endif
··· 1 + #ifdef CONFIG_MMU 2 + #include "init_mm.c" 3 + #else 4 + #include "init_no.c" 5 #endif
+150
arch/m68k/mm/init_mm.c
···
··· 1 + /* 2 + * linux/arch/m68k/mm/init.c 3 + * 4 + * Copyright (C) 1995 Hamish Macdonald 5 + * 6 + * Contains common initialization routines, specific init code moved 7 + * to motorola.c and sun3mmu.c 8 + */ 9 + 10 + #include <linux/module.h> 11 + #include <linux/signal.h> 12 + #include <linux/sched.h> 13 + #include <linux/mm.h> 14 + #include <linux/swap.h> 15 + #include <linux/kernel.h> 16 + #include <linux/string.h> 17 + #include <linux/types.h> 18 + #include <linux/init.h> 19 + #include <linux/bootmem.h> 20 + #include <linux/gfp.h> 21 + 22 + #include <asm/setup.h> 23 + #include <asm/uaccess.h> 24 + #include <asm/page.h> 25 + #include <asm/pgalloc.h> 26 + #include <asm/system.h> 27 + #include <asm/machdep.h> 28 + #include <asm/io.h> 29 + #ifdef CONFIG_ATARI 30 + #include <asm/atari_stram.h> 31 + #endif 32 + #include <asm/sections.h> 33 + #include <asm/tlb.h> 34 + 35 + DEFINE_PER_CPU(struct mmu_gather, mmu_gathers); 36 + 37 + pg_data_t pg_data_map[MAX_NUMNODES]; 38 + EXPORT_SYMBOL(pg_data_map); 39 + 40 + int m68k_virt_to_node_shift; 41 + 42 + #ifndef CONFIG_SINGLE_MEMORY_CHUNK 43 + pg_data_t *pg_data_table[65]; 44 + EXPORT_SYMBOL(pg_data_table); 45 + #endif 46 + 47 + void __init m68k_setup_node(int node) 48 + { 49 + #ifndef CONFIG_SINGLE_MEMORY_CHUNK 50 + struct mem_info *info = m68k_memory + node; 51 + int i, end; 52 + 53 + i = (unsigned long)phys_to_virt(info->addr) >> __virt_to_node_shift(); 54 + end = (unsigned long)phys_to_virt(info->addr + info->size - 1) >> __virt_to_node_shift(); 55 + for (; i <= end; i++) { 56 + if (pg_data_table[i]) 57 + printk("overlap at %u for chunk %u\n", i, node); 58 + pg_data_table[i] = pg_data_map + node; 59 + } 60 + #endif 61 + pg_data_map[node].bdata = bootmem_node_data + node; 62 + node_set_online(node); 63 + } 64 + 65 + 66 + /* 67 + * ZERO_PAGE is a special page that is used for zero-initialized 68 + * data and COW. 69 + */ 70 + 71 + void *empty_zero_page; 72 + EXPORT_SYMBOL(empty_zero_page); 73 + 74 + extern void init_pointer_table(unsigned long ptable); 75 + 76 + /* References to section boundaries */ 77 + 78 + extern pmd_t *zero_pgtable; 79 + 80 + void __init mem_init(void) 81 + { 82 + pg_data_t *pgdat; 83 + int codepages = 0; 84 + int datapages = 0; 85 + int initpages = 0; 86 + int i; 87 + 88 + #ifdef CONFIG_ATARI 89 + if (MACH_IS_ATARI) 90 + atari_stram_mem_init_hook(); 91 + #endif 92 + 93 + /* this will put all memory onto the freelists */ 94 + totalram_pages = num_physpages = 0; 95 + for_each_online_pgdat(pgdat) { 96 + num_physpages += pgdat->node_present_pages; 97 + 98 + totalram_pages += free_all_bootmem_node(pgdat); 99 + for (i = 0; i < pgdat->node_spanned_pages; i++) { 100 + struct page *page = pgdat->node_mem_map + i; 101 + char *addr = page_to_virt(page); 102 + 103 + if (!PageReserved(page)) 104 + continue; 105 + if (addr >= _text && 106 + addr < _etext) 107 + codepages++; 108 + else if (addr >= __init_begin && 109 + addr < __init_end) 110 + initpages++; 111 + else 112 + datapages++; 113 + } 114 + } 115 + 116 + #ifndef CONFIG_SUN3 117 + /* insert pointer tables allocated so far into the tablelist */ 118 + init_pointer_table((unsigned long)kernel_pg_dir); 119 + for (i = 0; i < PTRS_PER_PGD; i++) { 120 + if (pgd_present(kernel_pg_dir[i])) 121 + init_pointer_table(__pgd_page(kernel_pg_dir[i])); 122 + } 123 + 124 + /* insert also pointer table that we used to unmap the zero page */ 125 + if (zero_pgtable) 126 + init_pointer_table((unsigned long)zero_pgtable); 127 + #endif 128 + 129 + printk("Memory: %luk/%luk available (%dk kernel code, %dk data, %dk init)\n", 130 + nr_free_pages() << (PAGE_SHIFT-10), 131 + totalram_pages << (PAGE_SHIFT-10), 132 + codepages << (PAGE_SHIFT-10), 133 + datapages << (PAGE_SHIFT-10), 134 + initpages << (PAGE_SHIFT-10)); 135 + } 136 + 137 + #ifdef CONFIG_BLK_DEV_INITRD 138 + void free_initrd_mem(unsigned long start, unsigned long end) 139 + { 140 + int pages = 0; 141 + for (; start < end; start += PAGE_SIZE) { 142 + ClearPageReserved(virt_to_page(start)); 143 + init_page_count(virt_to_page(start)); 144 + free_page(start); 145 + totalram_pages++; 146 + pages++; 147 + } 148 + printk ("Freeing initrd memory: %dk freed\n", pages); 149 + } 150 + #endif
+3 -365
arch/m68k/mm/kmap.c
··· 1 - /* 2 - * linux/arch/m68k/mm/kmap.c 3 - * 4 - * Copyright (C) 1997 Roman Hodek 5 - * 6 - * 10/01/99 cleaned up the code and changing to the same interface 7 - * used by other architectures /Roman Zippel 8 - */ 9 - 10 - #include <linux/module.h> 11 - #include <linux/mm.h> 12 - #include <linux/kernel.h> 13 - #include <linux/string.h> 14 - #include <linux/types.h> 15 - #include <linux/slab.h> 16 - #include <linux/vmalloc.h> 17 - 18 - #include <asm/setup.h> 19 - #include <asm/segment.h> 20 - #include <asm/page.h> 21 - #include <asm/pgalloc.h> 22 - #include <asm/io.h> 23 - #include <asm/system.h> 24 - 25 - #undef DEBUG 26 - 27 - #define PTRTREESIZE (256*1024) 28 - 29 - /* 30 - * For 040/060 we can use the virtual memory area like other architectures, 31 - * but for 020/030 we want to use early termination page descriptor and we 32 - * can't mix this with normal page descriptors, so we have to copy that code 33 - * (mm/vmalloc.c) and return appriorate aligned addresses. 34 - */ 35 - 36 - #ifdef CPU_M68040_OR_M68060_ONLY 37 - 38 - #define IO_SIZE PAGE_SIZE 39 - 40 - static inline struct vm_struct *get_io_area(unsigned long size) 41 - { 42 - return get_vm_area(size, VM_IOREMAP); 43 - } 44 - 45 - 46 - static inline void free_io_area(void *addr) 47 - { 48 - vfree((void *)(PAGE_MASK & (unsigned long)addr)); 49 - } 50 - 51 #else 52 - 53 - #define IO_SIZE (256*1024) 54 - 55 - static struct vm_struct *iolist; 56 - 57 - static struct vm_struct *get_io_area(unsigned long size) 58 - { 59 - unsigned long addr; 60 - struct vm_struct **p, *tmp, *area; 61 - 62 - area = kmalloc(sizeof(*area), GFP_KERNEL); 63 - if (!area) 64 - return NULL; 65 - addr = KMAP_START; 66 - for (p = &iolist; (tmp = *p) ; p = &tmp->next) { 67 - if (size + addr < (unsigned long)tmp->addr) 68 - break; 69 - if (addr > KMAP_END-size) { 70 - kfree(area); 71 - return NULL; 72 - } 73 - addr = tmp->size + (unsigned long)tmp->addr; 74 - } 75 - area->addr = (void *)addr; 76 - area->size = size + IO_SIZE; 77 - area->next = *p; 78 - *p = area; 79 - return area; 80 - } 81 - 82 - static inline void free_io_area(void *addr) 83 - { 84 - struct vm_struct **p, *tmp; 85 - 86 - if (!addr) 87 - return; 88 - addr = (void *)((unsigned long)addr & -IO_SIZE); 89 - for (p = &iolist ; (tmp = *p) ; p = &tmp->next) { 90 - if (tmp->addr == addr) { 91 - *p = tmp->next; 92 - __iounmap(tmp->addr, tmp->size); 93 - kfree(tmp); 94 - return; 95 - } 96 - } 97 - } 98 - 99 #endif 100 - 101 - /* 102 - * Map some physical address range into the kernel address space. 103 - */ 104 - /* Rewritten by Andreas Schwab to remove all races. */ 105 - 106 - void __iomem *__ioremap(unsigned long physaddr, unsigned long size, int cacheflag) 107 - { 108 - struct vm_struct *area; 109 - unsigned long virtaddr, retaddr; 110 - long offset; 111 - pgd_t *pgd_dir; 112 - pmd_t *pmd_dir; 113 - pte_t *pte_dir; 114 - 115 - /* 116 - * Don't allow mappings that wrap.. 117 - */ 118 - if (!size || physaddr > (unsigned long)(-size)) 119 - return NULL; 120 - 121 - #ifdef CONFIG_AMIGA 122 - if (MACH_IS_AMIGA) { 123 - if ((physaddr >= 0x40000000) && (physaddr + size < 0x60000000) 124 - && (cacheflag == IOMAP_NOCACHE_SER)) 125 - return (void __iomem *)physaddr; 126 - } 127 - #endif 128 - 129 - #ifdef DEBUG 130 - printk("ioremap: 0x%lx,0x%lx(%d) - ", physaddr, size, cacheflag); 131 - #endif 132 - /* 133 - * Mappings have to be aligned 134 - */ 135 - offset = physaddr & (IO_SIZE - 1); 136 - physaddr &= -IO_SIZE; 137 - size = (size + offset + IO_SIZE - 1) & -IO_SIZE; 138 - 139 - /* 140 - * Ok, go for it.. 141 - */ 142 - area = get_io_area(size); 143 - if (!area) 144 - return NULL; 145 - 146 - virtaddr = (unsigned long)area->addr; 147 - retaddr = virtaddr + offset; 148 - #ifdef DEBUG 149 - printk("0x%lx,0x%lx,0x%lx", physaddr, virtaddr, retaddr); 150 - #endif 151 - 152 - /* 153 - * add cache and table flags to physical address 154 - */ 155 - if (CPU_IS_040_OR_060) { 156 - physaddr |= (_PAGE_PRESENT | _PAGE_GLOBAL040 | 157 - _PAGE_ACCESSED | _PAGE_DIRTY); 158 - switch (cacheflag) { 159 - case IOMAP_FULL_CACHING: 160 - physaddr |= _PAGE_CACHE040; 161 - break; 162 - case IOMAP_NOCACHE_SER: 163 - default: 164 - physaddr |= _PAGE_NOCACHE_S; 165 - break; 166 - case IOMAP_NOCACHE_NONSER: 167 - physaddr |= _PAGE_NOCACHE; 168 - break; 169 - case IOMAP_WRITETHROUGH: 170 - physaddr |= _PAGE_CACHE040W; 171 - break; 172 - } 173 - } else { 174 - physaddr |= (_PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_DIRTY); 175 - switch (cacheflag) { 176 - case IOMAP_NOCACHE_SER: 177 - case IOMAP_NOCACHE_NONSER: 178 - default: 179 - physaddr |= _PAGE_NOCACHE030; 180 - break; 181 - case IOMAP_FULL_CACHING: 182 - case IOMAP_WRITETHROUGH: 183 - break; 184 - } 185 - } 186 - 187 - while ((long)size > 0) { 188 - #ifdef DEBUG 189 - if (!(virtaddr & (PTRTREESIZE-1))) 190 - printk ("\npa=%#lx va=%#lx ", physaddr, virtaddr); 191 - #endif 192 - pgd_dir = pgd_offset_k(virtaddr); 193 - pmd_dir = pmd_alloc(&init_mm, pgd_dir, virtaddr); 194 - if (!pmd_dir) { 195 - printk("ioremap: no mem for pmd_dir\n"); 196 - return NULL; 197 - } 198 - 199 - if (CPU_IS_020_OR_030) { 200 - pmd_dir->pmd[(virtaddr/PTRTREESIZE) & 15] = physaddr; 201 - physaddr += PTRTREESIZE; 202 - virtaddr += PTRTREESIZE; 203 - size -= PTRTREESIZE; 204 - } else { 205 - pte_dir = pte_alloc_kernel(pmd_dir, virtaddr); 206 - if (!pte_dir) { 207 - printk("ioremap: no mem for pte_dir\n"); 208 - return NULL; 209 - } 210 - 211 - pte_val(*pte_dir) = physaddr; 212 - virtaddr += PAGE_SIZE; 213 - physaddr += PAGE_SIZE; 214 - size -= PAGE_SIZE; 215 - } 216 - } 217 - #ifdef DEBUG 218 - printk("\n"); 219 - #endif 220 - flush_tlb_all(); 221 - 222 - return (void __iomem *)retaddr; 223 - } 224 - EXPORT_SYMBOL(__ioremap); 225 - 226 - /* 227 - * Unmap a ioremap()ed region again 228 - */ 229 - void iounmap(void __iomem *addr) 230 - { 231 - #ifdef CONFIG_AMIGA 232 - if ((!MACH_IS_AMIGA) || 233 - (((unsigned long)addr < 0x40000000) || 234 - ((unsigned long)addr > 0x60000000))) 235 - free_io_area((__force void *)addr); 236 - #else 237 - free_io_area((__force void *)addr); 238 - #endif 239 - } 240 - EXPORT_SYMBOL(iounmap); 241 - 242 - /* 243 - * __iounmap unmaps nearly everything, so be careful 244 - * it doesn't free currently pointer/page tables anymore but it 245 - * wans't used anyway and might be added later. 246 - */ 247 - void __iounmap(void *addr, unsigned long size) 248 - { 249 - unsigned long virtaddr = (unsigned long)addr; 250 - pgd_t *pgd_dir; 251 - pmd_t *pmd_dir; 252 - pte_t *pte_dir; 253 - 254 - while ((long)size > 0) { 255 - pgd_dir = pgd_offset_k(virtaddr); 256 - if (pgd_bad(*pgd_dir)) { 257 - printk("iounmap: bad pgd(%08lx)\n", pgd_val(*pgd_dir)); 258 - pgd_clear(pgd_dir); 259 - return; 260 - } 261 - pmd_dir = pmd_offset(pgd_dir, virtaddr); 262 - 263 - if (CPU_IS_020_OR_030) { 264 - int pmd_off = (virtaddr/PTRTREESIZE) & 15; 265 - int pmd_type = pmd_dir->pmd[pmd_off] & _DESCTYPE_MASK; 266 - 267 - if (pmd_type == _PAGE_PRESENT) { 268 - pmd_dir->pmd[pmd_off] = 0; 269 - virtaddr += PTRTREESIZE; 270 - size -= PTRTREESIZE; 271 - continue; 272 - } else if (pmd_type == 0) 273 - continue; 274 - } 275 - 276 - if (pmd_bad(*pmd_dir)) { 277 - printk("iounmap: bad pmd (%08lx)\n", pmd_val(*pmd_dir)); 278 - pmd_clear(pmd_dir); 279 - return; 280 - } 281 - pte_dir = pte_offset_kernel(pmd_dir, virtaddr); 282 - 283 - pte_val(*pte_dir) = 0; 284 - virtaddr += PAGE_SIZE; 285 - size -= PAGE_SIZE; 286 - } 287 - 288 - flush_tlb_all(); 289 - } 290 - 291 - /* 292 - * Set new cache mode for some kernel address space. 293 - * The caller must push data for that range itself, if such data may already 294 - * be in the cache. 295 - */ 296 - void kernel_set_cachemode(void *addr, unsigned long size, int cmode) 297 - { 298 - unsigned long virtaddr = (unsigned long)addr; 299 - pgd_t *pgd_dir; 300 - pmd_t *pmd_dir; 301 - pte_t *pte_dir; 302 - 303 - if (CPU_IS_040_OR_060) { 304 - switch (cmode) { 305 - case IOMAP_FULL_CACHING: 306 - cmode = _PAGE_CACHE040; 307 - break; 308 - case IOMAP_NOCACHE_SER: 309 - default: 310 - cmode = _PAGE_NOCACHE_S; 311 - break; 312 - case IOMAP_NOCACHE_NONSER: 313 - cmode = _PAGE_NOCACHE; 314 - break; 315 - case IOMAP_WRITETHROUGH: 316 - cmode = _PAGE_CACHE040W; 317 - break; 318 - } 319 - } else { 320 - switch (cmode) { 321 - case IOMAP_NOCACHE_SER: 322 - case IOMAP_NOCACHE_NONSER: 323 - default: 324 - cmode = _PAGE_NOCACHE030; 325 - break; 326 - case IOMAP_FULL_CACHING: 327 - case IOMAP_WRITETHROUGH: 328 - cmode = 0; 329 - } 330 - } 331 - 332 - while ((long)size > 0) { 333 - pgd_dir = pgd_offset_k(virtaddr); 334 - if (pgd_bad(*pgd_dir)) { 335 - printk("iocachemode: bad pgd(%08lx)\n", pgd_val(*pgd_dir)); 336 - pgd_clear(pgd_dir); 337 - return; 338 - } 339 - pmd_dir = pmd_offset(pgd_dir, virtaddr); 340 - 341 - if (CPU_IS_020_OR_030) { 342 - int pmd_off = (virtaddr/PTRTREESIZE) & 15; 343 - 344 - if ((pmd_dir->pmd[pmd_off] & _DESCTYPE_MASK) == _PAGE_PRESENT) { 345 - pmd_dir->pmd[pmd_off] = (pmd_dir->pmd[pmd_off] & 346 - _CACHEMASK040) | cmode; 347 - virtaddr += PTRTREESIZE; 348 - size -= PTRTREESIZE; 349 - continue; 350 - } 351 - } 352 - 353 - if (pmd_bad(*pmd_dir)) { 354 - printk("iocachemode: bad pmd (%08lx)\n", pmd_val(*pmd_dir)); 355 - pmd_clear(pmd_dir); 356 - return; 357 - } 358 - pte_dir = pte_offset_kernel(pmd_dir, virtaddr); 359 - 360 - pte_val(*pte_dir) = (pte_val(*pte_dir) & _CACHEMASK040) | cmode; 361 - virtaddr += PAGE_SIZE; 362 - size -= PAGE_SIZE; 363 - } 364 - 365 - flush_tlb_all(); 366 - } 367 - EXPORT_SYMBOL(kernel_set_cachemode);
··· 1 + #ifdef CONFIG_MMU 2 + #include "kmap_mm.c" 3 #else 4 + #include "kmap_no.c" 5 #endif
+367
arch/m68k/mm/kmap_mm.c
···
··· 1 + /* 2 + * linux/arch/m68k/mm/kmap.c 3 + * 4 + * Copyright (C) 1997 Roman Hodek 5 + * 6 + * 10/01/99 cleaned up the code and changing to the same interface 7 + * used by other architectures /Roman Zippel 8 + */ 9 + 10 + #include <linux/module.h> 11 + #include <linux/mm.h> 12 + #include <linux/kernel.h> 13 + #include <linux/string.h> 14 + #include <linux/types.h> 15 + #include <linux/slab.h> 16 + #include <linux/vmalloc.h> 17 + 18 + #include <asm/setup.h> 19 + #include <asm/segment.h> 20 + #include <asm/page.h> 21 + #include <asm/pgalloc.h> 22 + #include <asm/io.h> 23 + #include <asm/system.h> 24 + 25 + #undef DEBUG 26 + 27 + #define PTRTREESIZE (256*1024) 28 + 29 + /* 30 + * For 040/060 we can use the virtual memory area like other architectures, 31 + * but for 020/030 we want to use early termination page descriptor and we 32 + * can't mix this with normal page descriptors, so we have to copy that code 33 + * (mm/vmalloc.c) and return appriorate aligned addresses. 34 + */ 35 + 36 + #ifdef CPU_M68040_OR_M68060_ONLY 37 + 38 + #define IO_SIZE PAGE_SIZE 39 + 40 + static inline struct vm_struct *get_io_area(unsigned long size) 41 + { 42 + return get_vm_area(size, VM_IOREMAP); 43 + } 44 + 45 + 46 + static inline void free_io_area(void *addr) 47 + { 48 + vfree((void *)(PAGE_MASK & (unsigned long)addr)); 49 + } 50 + 51 + #else 52 + 53 + #define IO_SIZE (256*1024) 54 + 55 + static struct vm_struct *iolist; 56 + 57 + static struct vm_struct *get_io_area(unsigned long size) 58 + { 59 + unsigned long addr; 60 + struct vm_struct **p, *tmp, *area; 61 + 62 + area = kmalloc(sizeof(*area), GFP_KERNEL); 63 + if (!area) 64 + return NULL; 65 + addr = KMAP_START; 66 + for (p = &iolist; (tmp = *p) ; p = &tmp->next) { 67 + if (size + addr < (unsigned long)tmp->addr) 68 + break; 69 + if (addr > KMAP_END-size) { 70 + kfree(area); 71 + return NULL; 72 + } 73 + addr = tmp->size + (unsigned long)tmp->addr; 74 + } 75 + area->addr = (void *)addr; 76 + area->size = size + IO_SIZE; 77 + area->next = *p; 78 + *p = area; 79 + return area; 80 + } 81 + 82 + static inline void free_io_area(void *addr) 83 + { 84 + struct vm_struct **p, *tmp; 85 + 86 + if (!addr) 87 + return; 88 + addr = (void *)((unsigned long)addr & -IO_SIZE); 89 + for (p = &iolist ; (tmp = *p) ; p = &tmp->next) { 90 + if (tmp->addr == addr) { 91 + *p = tmp->next; 92 + __iounmap(tmp->addr, tmp->size); 93 + kfree(tmp); 94 + return; 95 + } 96 + } 97 + } 98 + 99 + #endif 100 + 101 + /* 102 + * Map some physical address range into the kernel address space. 103 + */ 104 + /* Rewritten by Andreas Schwab to remove all races. */ 105 + 106 + void __iomem *__ioremap(unsigned long physaddr, unsigned long size, int cacheflag) 107 + { 108 + struct vm_struct *area; 109 + unsigned long virtaddr, retaddr; 110 + long offset; 111 + pgd_t *pgd_dir; 112 + pmd_t *pmd_dir; 113 + pte_t *pte_dir; 114 + 115 + /* 116 + * Don't allow mappings that wrap.. 117 + */ 118 + if (!size || physaddr > (unsigned long)(-size)) 119 + return NULL; 120 + 121 + #ifdef CONFIG_AMIGA 122 + if (MACH_IS_AMIGA) { 123 + if ((physaddr >= 0x40000000) && (physaddr + size < 0x60000000) 124 + && (cacheflag == IOMAP_NOCACHE_SER)) 125 + return (void __iomem *)physaddr; 126 + } 127 + #endif 128 + 129 + #ifdef DEBUG 130 + printk("ioremap: 0x%lx,0x%lx(%d) - ", physaddr, size, cacheflag); 131 + #endif 132 + /* 133 + * Mappings have to be aligned 134 + */ 135 + offset = physaddr & (IO_SIZE - 1); 136 + physaddr &= -IO_SIZE; 137 + size = (size + offset + IO_SIZE - 1) & -IO_SIZE; 138 + 139 + /* 140 + * Ok, go for it.. 141 + */ 142 + area = get_io_area(size); 143 + if (!area) 144 + return NULL; 145 + 146 + virtaddr = (unsigned long)area->addr; 147 + retaddr = virtaddr + offset; 148 + #ifdef DEBUG 149 + printk("0x%lx,0x%lx,0x%lx", physaddr, virtaddr, retaddr); 150 + #endif 151 + 152 + /* 153 + * add cache and table flags to physical address 154 + */ 155 + if (CPU_IS_040_OR_060) { 156 + physaddr |= (_PAGE_PRESENT | _PAGE_GLOBAL040 | 157 + _PAGE_ACCESSED | _PAGE_DIRTY); 158 + switch (cacheflag) { 159 + case IOMAP_FULL_CACHING: 160 + physaddr |= _PAGE_CACHE040; 161 + break; 162 + case IOMAP_NOCACHE_SER: 163 + default: 164 + physaddr |= _PAGE_NOCACHE_S; 165 + break; 166 + case IOMAP_NOCACHE_NONSER: 167 + physaddr |= _PAGE_NOCACHE; 168 + break; 169 + case IOMAP_WRITETHROUGH: 170 + physaddr |= _PAGE_CACHE040W; 171 + break; 172 + } 173 + } else { 174 + physaddr |= (_PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_DIRTY); 175 + switch (cacheflag) { 176 + case IOMAP_NOCACHE_SER: 177 + case IOMAP_NOCACHE_NONSER: 178 + default: 179 + physaddr |= _PAGE_NOCACHE030; 180 + break; 181 + case IOMAP_FULL_CACHING: 182 + case IOMAP_WRITETHROUGH: 183 + break; 184 + } 185 + } 186 + 187 + while ((long)size > 0) { 188 + #ifdef DEBUG 189 + if (!(virtaddr & (PTRTREESIZE-1))) 190 + printk ("\npa=%#lx va=%#lx ", physaddr, virtaddr); 191 + #endif 192 + pgd_dir = pgd_offset_k(virtaddr); 193 + pmd_dir = pmd_alloc(&init_mm, pgd_dir, virtaddr); 194 + if (!pmd_dir) { 195 + printk("ioremap: no mem for pmd_dir\n"); 196 + return NULL; 197 + } 198 + 199 + if (CPU_IS_020_OR_030) { 200 + pmd_dir->pmd[(virtaddr/PTRTREESIZE) & 15] = physaddr; 201 + physaddr += PTRTREESIZE; 202 + virtaddr += PTRTREESIZE; 203 + size -= PTRTREESIZE; 204 + } else { 205 + pte_dir = pte_alloc_kernel(pmd_dir, virtaddr); 206 + if (!pte_dir) { 207 + printk("ioremap: no mem for pte_dir\n"); 208 + return NULL; 209 + } 210 + 211 + pte_val(*pte_dir) = physaddr; 212 + virtaddr += PAGE_SIZE; 213 + physaddr += PAGE_SIZE; 214 + size -= PAGE_SIZE; 215 + } 216 + } 217 + #ifdef DEBUG 218 + printk("\n"); 219 + #endif 220 + flush_tlb_all(); 221 + 222 + return (void __iomem *)retaddr; 223 + } 224 + EXPORT_SYMBOL(__ioremap); 225 + 226 + /* 227 + * Unmap a ioremap()ed region again 228 + */ 229 + void iounmap(void __iomem *addr) 230 + { 231 + #ifdef CONFIG_AMIGA 232 + if ((!MACH_IS_AMIGA) || 233 + (((unsigned long)addr < 0x40000000) || 234 + ((unsigned long)addr > 0x60000000))) 235 + free_io_area((__force void *)addr); 236 + #else 237 + free_io_area((__force void *)addr); 238 + #endif 239 + } 240 + EXPORT_SYMBOL(iounmap); 241 + 242 + /* 243 + * __iounmap unmaps nearly everything, so be careful 244 + * it doesn't free currently pointer/page tables anymore but it 245 + * wans't used anyway and might be added later. 246 + */ 247 + void __iounmap(void *addr, unsigned long size) 248 + { 249 + unsigned long virtaddr = (unsigned long)addr; 250 + pgd_t *pgd_dir; 251 + pmd_t *pmd_dir; 252 + pte_t *pte_dir; 253 + 254 + while ((long)size > 0) { 255 + pgd_dir = pgd_offset_k(virtaddr); 256 + if (pgd_bad(*pgd_dir)) { 257 + printk("iounmap: bad pgd(%08lx)\n", pgd_val(*pgd_dir)); 258 + pgd_clear(pgd_dir); 259 + return; 260 + } 261 + pmd_dir = pmd_offset(pgd_dir, virtaddr); 262 + 263 + if (CPU_IS_020_OR_030) { 264 + int pmd_off = (virtaddr/PTRTREESIZE) & 15; 265 + int pmd_type = pmd_dir->pmd[pmd_off] & _DESCTYPE_MASK; 266 + 267 + if (pmd_type == _PAGE_PRESENT) { 268 + pmd_dir->pmd[pmd_off] = 0; 269 + virtaddr += PTRTREESIZE; 270 + size -= PTRTREESIZE; 271 + continue; 272 + } else if (pmd_type == 0) 273 + continue; 274 + } 275 + 276 + if (pmd_bad(*pmd_dir)) { 277 + printk("iounmap: bad pmd (%08lx)\n", pmd_val(*pmd_dir)); 278 + pmd_clear(pmd_dir); 279 + return; 280 + } 281 + pte_dir = pte_offset_kernel(pmd_dir, virtaddr); 282 + 283 + pte_val(*pte_dir) = 0; 284 + virtaddr += PAGE_SIZE; 285 + size -= PAGE_SIZE; 286 + } 287 + 288 + flush_tlb_all(); 289 + } 290 + 291 + /* 292 + * Set new cache mode for some kernel address space. 293 + * The caller must push data for that range itself, if such data may already 294 + * be in the cache. 295 + */ 296 + void kernel_set_cachemode(void *addr, unsigned long size, int cmode) 297 + { 298 + unsigned long virtaddr = (unsigned long)addr; 299 + pgd_t *pgd_dir; 300 + pmd_t *pmd_dir; 301 + pte_t *pte_dir; 302 + 303 + if (CPU_IS_040_OR_060) { 304 + switch (cmode) { 305 + case IOMAP_FULL_CACHING: 306 + cmode = _PAGE_CACHE040; 307 + break; 308 + case IOMAP_NOCACHE_SER: 309 + default: 310 + cmode = _PAGE_NOCACHE_S; 311 + break; 312 + case IOMAP_NOCACHE_NONSER: 313 + cmode = _PAGE_NOCACHE; 314 + break; 315 + case IOMAP_WRITETHROUGH: 316 + cmode = _PAGE_CACHE040W; 317 + break; 318 + } 319 + } else { 320 + switch (cmode) { 321 + case IOMAP_NOCACHE_SER: 322 + case IOMAP_NOCACHE_NONSER: 323 + default: 324 + cmode = _PAGE_NOCACHE030; 325 + break; 326 + case IOMAP_FULL_CACHING: 327 + case IOMAP_WRITETHROUGH: 328 + cmode = 0; 329 + } 330 + } 331 + 332 + while ((long)size > 0) { 333 + pgd_dir = pgd_offset_k(virtaddr); 334 + if (pgd_bad(*pgd_dir)) { 335 + printk("iocachemode: bad pgd(%08lx)\n", pgd_val(*pgd_dir)); 336 + pgd_clear(pgd_dir); 337 + return; 338 + } 339 + pmd_dir = pmd_offset(pgd_dir, virtaddr); 340 + 341 + if (CPU_IS_020_OR_030) { 342 + int pmd_off = (virtaddr/PTRTREESIZE) & 15; 343 + 344 + if ((pmd_dir->pmd[pmd_off] & _DESCTYPE_MASK) == _PAGE_PRESENT) { 345 + pmd_dir->pmd[pmd_off] = (pmd_dir->pmd[pmd_off] & 346 + _CACHEMASK040) | cmode; 347 + virtaddr += PTRTREESIZE; 348 + size -= PTRTREESIZE; 349 + continue; 350 + } 351 + } 352 + 353 + if (pmd_bad(*pmd_dir)) { 354 + printk("iocachemode: bad pmd (%08lx)\n", pmd_val(*pmd_dir)); 355 + pmd_clear(pmd_dir); 356 + return; 357 + } 358 + pte_dir = pte_offset_kernel(pmd_dir, virtaddr); 359 + 360 + pte_val(*pte_dir) = (pte_val(*pte_dir) & _CACHEMASK040) | cmode; 361 + virtaddr += PAGE_SIZE; 362 + size -= PAGE_SIZE; 363 + } 364 + 365 + flush_tlb_all(); 366 + } 367 + EXPORT_SYMBOL(kernel_set_cachemode);
-94
arch/m68knommu/Kconfig arch/m68k/Kconfig.nommu
··· 1 - config M68K 2 - bool 3 - default y 4 - select HAVE_IDE 5 - select HAVE_GENERIC_HARDIRQS 6 - select GENERIC_HARDIRQS_NO_DEPRECATED 7 - 8 - config MMU 9 - bool 10 - default n 11 - 12 - config NO_DMA 13 - bool 14 - depends on !COLDFIRE 15 - default y 16 - 17 config FPU 18 - bool 19 - default n 20 - 21 - config ZONE_DMA 22 - bool 23 - default y 24 - 25 - config RWSEM_GENERIC_SPINLOCK 26 - bool 27 - default y 28 - 29 - config RWSEM_XCHGADD_ALGORITHM 30 - bool 31 - default n 32 - 33 - config ARCH_HAS_ILOG2_U32 34 - bool 35 - default n 36 - 37 - config ARCH_HAS_ILOG2_U64 38 bool 39 default n 40 ··· 10 bool 11 default n 12 13 - config GENERIC_HWEIGHT 14 - bool 15 - default y 16 - 17 - config GENERIC_CALIBRATE_DELAY 18 - bool 19 - default y 20 - 21 config GENERIC_CMOS_UPDATE 22 - bool 23 - default y 24 - 25 - config TIME_LOW_RES 26 bool 27 default y 28 29 config GENERIC_CLOCKEVENTS 30 bool 31 default n 32 - 33 - config NO_IOPORT 34 - def_bool y 35 36 config COLDFIRE_SW_A7 37 bool ··· 33 34 config HAVE_IPSBAR 35 bool 36 - 37 - source "init/Kconfig" 38 - 39 - source "kernel/Kconfig.freezer" 40 - 41 - menu "Processor type and features" 42 43 choice 44 prompt "CPU" ··· 573 running more threads on a system and also reduces the pressure 574 on the VM subsystem for higher order allocations. 575 576 - config HZ 577 - int 578 - default 1000 if CLEOPATRA 579 - default 100 580 - 581 comment "RAM configuration" 582 583 config RAMBASE ··· 741 742 source "kernel/time/Kconfig" 743 744 - source "mm/Kconfig" 745 - 746 - endmenu 747 - 748 config ISA_DMA_API 749 bool 750 depends on !M5272 ··· 748 749 source "drivers/pcmcia/Kconfig" 750 751 - menu "Executable file formats" 752 - 753 - source "fs/Kconfig.binfmt" 754 - 755 - endmenu 756 - 757 - menu "Power management options" 758 - 759 - config PM 760 - bool "Power Management support" 761 - help 762 - Support processor power management modes 763 - 764 - endmenu 765 - 766 - source "net/Kconfig" 767 - 768 - source "drivers/Kconfig" 769 - 770 - source "fs/Kconfig" 771 - 772 - source "arch/m68knommu/Kconfig.debug" 773 - 774 - source "security/Kconfig" 775 - 776 - source "crypto/Kconfig" 777 - 778 - source "lib/Kconfig"
··· 1 config FPU 2 bool 3 default n 4 ··· 46 bool 47 default n 48 49 config GENERIC_CMOS_UPDATE 50 bool 51 default y 52 53 config GENERIC_CLOCKEVENTS 54 bool 55 default n 56 57 config COLDFIRE_SW_A7 58 bool ··· 84 85 config HAVE_IPSBAR 86 bool 87 88 choice 89 prompt "CPU" ··· 630 running more threads on a system and also reduces the pressure 631 on the VM subsystem for higher order allocations. 632 633 comment "RAM configuration" 634 635 config RAMBASE ··· 803 804 source "kernel/time/Kconfig" 805 806 config ISA_DMA_API 807 bool 808 depends on !M5272 ··· 814 815 source "drivers/pcmcia/Kconfig" 816
-35
arch/m68knommu/Kconfig.debug
··· 1 - menu "Kernel hacking" 2 - 3 - source "lib/Kconfig.debug" 4 - 5 - config FULLDEBUG 6 - bool "Full Symbolic/Source Debugging support" 7 - help 8 - Enable debugging symbols on kernel build. 9 - 10 - config HIGHPROFILE 11 - bool "Use fast second timer for profiling" 12 - depends on COLDFIRE 13 - help 14 - Use a fast secondary clock to produce profiling information. 15 - 16 - config BOOTPARAM 17 - bool 'Compiled-in Kernel Boot Parameter' 18 - 19 - config BOOTPARAM_STRING 20 - string 'Kernel Boot Parameter' 21 - default 'console=ttyS0,19200' 22 - depends on BOOTPARAM 23 - 24 - config NO_KERNEL_MSG 25 - bool "Suppress Kernel BUG Messages" 26 - help 27 - Do not output any debug BUG messages within the kernel. 28 - 29 - config BDM_DISABLE 30 - bool "Disable BDM signals" 31 - depends on (EXPERIMENTAL && COLDFIRE) 32 - help 33 - Disable the ColdFire CPU's BDM signals. 34 - 35 - endmenu
···
+7 -9
arch/m68knommu/Makefile arch/m68k/Makefile_no
··· 1 # 2 - # arch/m68knommu/Makefile 3 # 4 # This file is subject to the terms and conditions of the GNU General Public 5 # License. See the file "COPYING" in the main directory of this archive ··· 7 # 8 # (C) Copyright 2002, Greg Ungerer <gerg@snapgear.com> 9 # 10 - 11 - KBUILD_DEFCONFIG := m5208evb_defconfig 12 13 platform-$(CONFIG_M68328) := 68328 14 platform-$(CONFIG_M68EZ328) := 68EZ328 ··· 80 CPUCLASS := $(cpuclass-y) 81 82 ifneq ($(CPUCLASS),$(PLATFORM)) 83 - CLASSDIR := arch/m68knommu/platform/$(cpuclass-y)/ 84 endif 85 86 export PLATFORM BOARD MODEL CPUCLASS ··· 112 KBUILD_CFLAGS += -D__linux__ 113 KBUILD_CFLAGS += -DUTS_SYSNAME=\"uClinux\" 114 115 - head-y := arch/m68knommu/platform/$(cpuclass-y)/head.o 116 117 - core-y += arch/m68knommu/kernel/ \ 118 - arch/m68knommu/mm/ \ 119 $(CLASSDIR) \ 120 - arch/m68knommu/platform/$(PLATFORM)/ 121 - libs-y += arch/m68knommu/lib/ 122 123 archclean: 124
··· 1 # 2 + # arch/m68k/Makefile 3 # 4 # This file is subject to the terms and conditions of the GNU General Public 5 # License. See the file "COPYING" in the main directory of this archive ··· 7 # 8 # (C) Copyright 2002, Greg Ungerer <gerg@snapgear.com> 9 # 10 11 platform-$(CONFIG_M68328) := 68328 12 platform-$(CONFIG_M68EZ328) := 68EZ328 ··· 82 CPUCLASS := $(cpuclass-y) 83 84 ifneq ($(CPUCLASS),$(PLATFORM)) 85 + CLASSDIR := arch/m68k/platform/$(cpuclass-y)/ 86 endif 87 88 export PLATFORM BOARD MODEL CPUCLASS ··· 114 KBUILD_CFLAGS += -D__linux__ 115 KBUILD_CFLAGS += -DUTS_SYSNAME=\"uClinux\" 116 117 + head-y := arch/m68k/platform/$(cpuclass-y)/head.o 118 119 + core-y += arch/m68k/kernel/ \ 120 + arch/m68k/mm/ \ 121 $(CLASSDIR) \ 122 + arch/m68k/platform/$(PLATFORM)/ 123 + libs-y += arch/m68k/lib/ 124 125 archclean: 126
+19 -16
arch/m68knommu/configs/m5208evb_defconfig arch/m68k/configs/m5307c3_defconfig
··· 1 CONFIG_EXPERIMENTAL=y 2 CONFIG_LOG_BUF_SHIFT=14 3 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set ··· 12 # CONFIG_EVENTFD is not set 13 # CONFIG_AIO is not set 14 # CONFIG_VM_EVENT_COUNTERS is not set 15 - # CONFIG_COMPAT_BRK is not set 16 # CONFIG_BLK_DEV_BSG is not set 17 # CONFIG_IOSCHED_DEADLINE is not set 18 # CONFIG_IOSCHED_CFQ is not set 19 - CONFIG_M520x=y 20 CONFIG_CLOCK_SET=y 21 - CONFIG_CLOCK_FREQ=166666666 22 CONFIG_CLOCK_DIV=2 23 - CONFIG_M5208EVB=y 24 - # CONFIG_4KSTACKS is not set 25 - CONFIG_RAMBASE=0x40000000 26 - CONFIG_RAMSIZE=0x2000000 27 - CONFIG_VECTORBASE=0x40000000 28 - CONFIG_KERNELBASE=0x40020000 29 - CONFIG_RAM16BIT=y 30 CONFIG_BINFMT_FLAT=y 31 CONFIG_NET=y 32 CONFIG_PACKET=y ··· 36 # CONFIG_INET_LRO is not set 37 # CONFIG_INET_DIAG is not set 38 # CONFIG_IPV6 is not set 39 CONFIG_MTD=y 40 CONFIG_MTD_PARTITIONS=y 41 CONFIG_MTD_CHAR=y ··· 47 # CONFIG_MISC_DEVICES is not set 48 CONFIG_NETDEVICES=y 49 CONFIG_NET_ETHERNET=y 50 - CONFIG_FEC=y 51 # CONFIG_NETDEV_1000 is not set 52 # CONFIG_NETDEV_10000 is not set 53 - # CONFIG_INPUT is not set 54 # CONFIG_SERIO is not set 55 # CONFIG_VT is not set 56 CONFIG_SERIAL_MCF=y 57 - CONFIG_SERIAL_MCF_BAUDRATE=115200 58 CONFIG_SERIAL_MCF_CONSOLE=y 59 - # CONFIG_UNIX98_PTYS is not set 60 # CONFIG_HW_RANDOM is not set 61 # CONFIG_HWMON is not set 62 # CONFIG_USB_SUPPORT is not set 63 CONFIG_EXT2_FS=y 64 - # CONFIG_FILE_LOCKING is not set 65 # CONFIG_DNOTIFY is not set 66 - # CONFIG_SYSFS is not set 67 CONFIG_ROMFS_FS=y 68 CONFIG_ROMFS_BACKED_BY_MTD=y 69 # CONFIG_NETWORK_FILESYSTEMS is not set ··· 74 CONFIG_FULLDEBUG=y 75 CONFIG_BOOTPARAM=y 76 CONFIG_BOOTPARAM_STRING="root=/dev/mtdblock0"
··· 1 + # CONFIG_MMU is not set 2 CONFIG_EXPERIMENTAL=y 3 CONFIG_LOG_BUF_SHIFT=14 4 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set ··· 11 # CONFIG_EVENTFD is not set 12 # CONFIG_AIO is not set 13 # CONFIG_VM_EVENT_COUNTERS is not set 14 + # CONFIG_SLUB_DEBUG is not set 15 # CONFIG_BLK_DEV_BSG is not set 16 # CONFIG_IOSCHED_DEADLINE is not set 17 # CONFIG_IOSCHED_CFQ is not set 18 + CONFIG_M5307=y 19 CONFIG_CLOCK_SET=y 20 + CONFIG_CLOCK_FREQ=90000000 21 CONFIG_CLOCK_DIV=2 22 + CONFIG_M5307C3=y 23 + CONFIG_RAMBASE=0x00000000 24 + CONFIG_RAMSIZE=0x00800000 25 + CONFIG_VECTORBASE=0x00000000 26 + CONFIG_KERNELBASE=0x00020000 27 CONFIG_BINFMT_FLAT=y 28 CONFIG_NET=y 29 CONFIG_PACKET=y ··· 37 # CONFIG_INET_LRO is not set 38 # CONFIG_INET_DIAG is not set 39 # CONFIG_IPV6 is not set 40 + # CONFIG_FW_LOADER is not set 41 CONFIG_MTD=y 42 CONFIG_MTD_PARTITIONS=y 43 CONFIG_MTD_CHAR=y ··· 47 # CONFIG_MISC_DEVICES is not set 48 CONFIG_NETDEVICES=y 49 CONFIG_NET_ETHERNET=y 50 # CONFIG_NETDEV_1000 is not set 51 # CONFIG_NETDEV_10000 is not set 52 + CONFIG_PPP=y 53 + CONFIG_SLIP=y 54 + CONFIG_SLIP_COMPRESSED=y 55 + # CONFIG_INPUT_MOUSEDEV is not set 56 + # CONFIG_INPUT_KEYBOARD is not set 57 + # CONFIG_INPUT_MOUSE is not set 58 # CONFIG_SERIO is not set 59 # CONFIG_VT is not set 60 CONFIG_SERIAL_MCF=y 61 CONFIG_SERIAL_MCF_CONSOLE=y 62 + # CONFIG_LEGACY_PTYS is not set 63 # CONFIG_HW_RANDOM is not set 64 # CONFIG_HWMON is not set 65 + # CONFIG_HID_SUPPORT is not set 66 # CONFIG_USB_SUPPORT is not set 67 CONFIG_EXT2_FS=y 68 # CONFIG_DNOTIFY is not set 69 CONFIG_ROMFS_FS=y 70 CONFIG_ROMFS_BACKED_BY_MTD=y 71 # CONFIG_NETWORK_FILESYSTEMS is not set ··· 72 CONFIG_FULLDEBUG=y 73 CONFIG_BOOTPARAM=y 74 CONFIG_BOOTPARAM_STRING="root=/dev/mtdblock0" 75 + # CONFIG_CRC32 is not set
+11 -4
arch/m68knommu/configs/m5249evb_defconfig arch/m68k/configs/m5275evb_defconfig
··· 1 CONFIG_EXPERIMENTAL=y 2 CONFIG_LOG_BUF_SHIFT=14 3 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set ··· 16 # CONFIG_BLK_DEV_BSG is not set 17 # CONFIG_IOSCHED_DEADLINE is not set 18 # CONFIG_IOSCHED_CFQ is not set 19 - CONFIG_M5249=y 20 CONFIG_CLOCK_SET=y 21 - CONFIG_CLOCK_FREQ=140000000 22 CONFIG_CLOCK_DIV=2 23 - CONFIG_M5249C3=y 24 CONFIG_RAMBASE=0x00000000 25 - CONFIG_RAMSIZE=0x00800000 26 CONFIG_VECTORBASE=0x00000000 27 CONFIG_KERNELBASE=0x00020000 28 CONFIG_BINFMT_FLAT=y ··· 37 # CONFIG_INET_LRO is not set 38 # CONFIG_INET_DIAG is not set 39 # CONFIG_IPV6 is not set 40 CONFIG_MTD=y 41 CONFIG_MTD_PARTITIONS=y 42 CONFIG_MTD_CHAR=y ··· 48 # CONFIG_MISC_DEVICES is not set 49 CONFIG_NETDEVICES=y 50 CONFIG_NET_ETHERNET=y 51 # CONFIG_NETDEV_1000 is not set 52 # CONFIG_NETDEV_10000 is not set 53 CONFIG_PPP=y ··· 63 # CONFIG_USB_SUPPORT is not set 64 CONFIG_EXT2_FS=y 65 # CONFIG_FILE_LOCKING is not set 66 CONFIG_ROMFS_FS=y 67 CONFIG_ROMFS_BACKED_BY_MTD=y 68 # CONFIG_NETWORK_FILESYSTEMS is not set 69 # CONFIG_RCU_CPU_STALL_DETECTOR is not set 70 CONFIG_BOOTPARAM=y 71 CONFIG_BOOTPARAM_STRING="root=/dev/mtdblock0" 72 # CONFIG_CRC32 is not set
··· 1 + # CONFIG_MMU is not set 2 CONFIG_EXPERIMENTAL=y 3 CONFIG_LOG_BUF_SHIFT=14 4 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set ··· 15 # CONFIG_BLK_DEV_BSG is not set 16 # CONFIG_IOSCHED_DEADLINE is not set 17 # CONFIG_IOSCHED_CFQ is not set 18 + CONFIG_M5275=y 19 CONFIG_CLOCK_SET=y 20 + CONFIG_CLOCK_FREQ=150000000 21 CONFIG_CLOCK_DIV=2 22 + CONFIG_M5275EVB=y 23 + # CONFIG_4KSTACKS is not set 24 CONFIG_RAMBASE=0x00000000 25 + CONFIG_RAMSIZE=0x00000000 26 CONFIG_VECTORBASE=0x00000000 27 CONFIG_KERNELBASE=0x00020000 28 CONFIG_BINFMT_FLAT=y ··· 35 # CONFIG_INET_LRO is not set 36 # CONFIG_INET_DIAG is not set 37 # CONFIG_IPV6 is not set 38 + # CONFIG_FW_LOADER is not set 39 CONFIG_MTD=y 40 CONFIG_MTD_PARTITIONS=y 41 CONFIG_MTD_CHAR=y ··· 45 # CONFIG_MISC_DEVICES is not set 46 CONFIG_NETDEVICES=y 47 CONFIG_NET_ETHERNET=y 48 + CONFIG_FEC=y 49 + CONFIG_FEC2=y 50 # CONFIG_NETDEV_1000 is not set 51 # CONFIG_NETDEV_10000 is not set 52 CONFIG_PPP=y ··· 58 # CONFIG_USB_SUPPORT is not set 59 CONFIG_EXT2_FS=y 60 # CONFIG_FILE_LOCKING is not set 61 + # CONFIG_DNOTIFY is not set 62 CONFIG_ROMFS_FS=y 63 CONFIG_ROMFS_BACKED_BY_MTD=y 64 # CONFIG_NETWORK_FILESYSTEMS is not set 65 # CONFIG_RCU_CPU_STALL_DETECTOR is not set 66 + CONFIG_SYSCTL_SYSCALL_CHECK=y 67 CONFIG_BOOTPARAM=y 68 CONFIG_BOOTPARAM_STRING="root=/dev/mtdblock0" 69 # CONFIG_CRC32 is not set
+12 -6
arch/m68knommu/configs/m5272c3_defconfig arch/m68k/configs/m5407c3_defconfig
··· 1 CONFIG_EXPERIMENTAL=y 2 CONFIG_LOG_BUF_SHIFT=14 3 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set ··· 12 # CONFIG_EVENTFD is not set 13 # CONFIG_AIO is not set 14 # CONFIG_VM_EVENT_COUNTERS is not set 15 - # CONFIG_SLUB_DEBUG is not set 16 # CONFIG_BLK_DEV_BSG is not set 17 # CONFIG_IOSCHED_DEADLINE is not set 18 # CONFIG_IOSCHED_CFQ is not set 19 - CONFIG_M5272=y 20 CONFIG_CLOCK_SET=y 21 - CONFIG_M5272C3=y 22 CONFIG_RAMBASE=0x00000000 23 - CONFIG_RAMSIZE=0x00800000 24 CONFIG_VECTORBASE=0x00000000 25 CONFIG_KERNELBASE=0x00020000 26 CONFIG_BINFMT_FLAT=y ··· 36 # CONFIG_INET_LRO is not set 37 # CONFIG_INET_DIAG is not set 38 # CONFIG_IPV6 is not set 39 CONFIG_MTD=y 40 CONFIG_MTD_PARTITIONS=y 41 CONFIG_MTD_CHAR=y ··· 47 # CONFIG_MISC_DEVICES is not set 48 CONFIG_NETDEVICES=y 49 CONFIG_NET_ETHERNET=y 50 - CONFIG_FEC=y 51 # CONFIG_NETDEV_1000 is not set 52 # CONFIG_NETDEV_10000 is not set 53 # CONFIG_INPUT is not set 54 - # CONFIG_SERIO is not set 55 # CONFIG_VT is not set 56 CONFIG_SERIAL_MCF=y 57 CONFIG_SERIAL_MCF_CONSOLE=y 58 # CONFIG_UNIX98_PTYS is not set 59 # CONFIG_HWMON is not set 60 # CONFIG_USB_SUPPORT is not set 61 CONFIG_EXT2_FS=y ··· 65 CONFIG_ROMFS_BACKED_BY_MTD=y 66 # CONFIG_NETWORK_FILESYSTEMS is not set 67 # CONFIG_RCU_CPU_STALL_DETECTOR is not set 68 CONFIG_BOOTPARAM=y 69 CONFIG_BOOTPARAM_STRING="root=/dev/mtdblock0"
··· 1 + # CONFIG_MMU is not set 2 CONFIG_EXPERIMENTAL=y 3 CONFIG_LOG_BUF_SHIFT=14 4 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set ··· 11 # CONFIG_EVENTFD is not set 12 # CONFIG_AIO is not set 13 # CONFIG_VM_EVENT_COUNTERS is not set 14 + CONFIG_MODULES=y 15 + CONFIG_MODULE_UNLOAD=y 16 # CONFIG_BLK_DEV_BSG is not set 17 # CONFIG_IOSCHED_DEADLINE is not set 18 # CONFIG_IOSCHED_CFQ is not set 19 + CONFIG_M5407=y 20 CONFIG_CLOCK_SET=y 21 + CONFIG_CLOCK_FREQ=50000000 22 + CONFIG_M5407C3=y 23 CONFIG_RAMBASE=0x00000000 24 + CONFIG_RAMSIZE=0x00000000 25 CONFIG_VECTORBASE=0x00000000 26 CONFIG_KERNELBASE=0x00020000 27 CONFIG_BINFMT_FLAT=y ··· 33 # CONFIG_INET_LRO is not set 34 # CONFIG_INET_DIAG is not set 35 # CONFIG_IPV6 is not set 36 + # CONFIG_FW_LOADER is not set 37 CONFIG_MTD=y 38 CONFIG_MTD_PARTITIONS=y 39 CONFIG_MTD_CHAR=y ··· 43 # CONFIG_MISC_DEVICES is not set 44 CONFIG_NETDEVICES=y 45 CONFIG_NET_ETHERNET=y 46 # CONFIG_NETDEV_1000 is not set 47 # CONFIG_NETDEV_10000 is not set 48 + CONFIG_PPP=y 49 # CONFIG_INPUT is not set 50 # CONFIG_VT is not set 51 CONFIG_SERIAL_MCF=y 52 CONFIG_SERIAL_MCF_CONSOLE=y 53 # CONFIG_UNIX98_PTYS is not set 54 + # CONFIG_HW_RANDOM is not set 55 # CONFIG_HWMON is not set 56 # CONFIG_USB_SUPPORT is not set 57 CONFIG_EXT2_FS=y ··· 61 CONFIG_ROMFS_BACKED_BY_MTD=y 62 # CONFIG_NETWORK_FILESYSTEMS is not set 63 # CONFIG_RCU_CPU_STALL_DETECTOR is not set 64 + CONFIG_SYSCTL_SYSCALL_CHECK=y 65 CONFIG_BOOTPARAM=y 66 CONFIG_BOOTPARAM_STRING="root=/dev/mtdblock0" 67 + # CONFIG_CRC32 is not set
-72
arch/m68knommu/configs/m5275evb_defconfig
··· 1 - CONFIG_EXPERIMENTAL=y 2 - CONFIG_LOG_BUF_SHIFT=14 3 - # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set 4 - CONFIG_EXPERT=y 5 - # CONFIG_KALLSYMS is not set 6 - # CONFIG_HOTPLUG is not set 7 - # CONFIG_FUTEX is not set 8 - # CONFIG_EPOLL is not set 9 - # CONFIG_SIGNALFD is not set 10 - # CONFIG_TIMERFD is not set 11 - # CONFIG_EVENTFD is not set 12 - # CONFIG_AIO is not set 13 - # CONFIG_VM_EVENT_COUNTERS is not set 14 - # CONFIG_SLUB_DEBUG is not set 15 - # CONFIG_BLK_DEV_BSG is not set 16 - # CONFIG_IOSCHED_DEADLINE is not set 17 - # CONFIG_IOSCHED_CFQ is not set 18 - CONFIG_M5275=y 19 - CONFIG_CLOCK_SET=y 20 - CONFIG_CLOCK_FREQ=150000000 21 - CONFIG_CLOCK_DIV=2 22 - CONFIG_M5275EVB=y 23 - # CONFIG_4KSTACKS is not set 24 - CONFIG_RAMBASE=0x00000000 25 - CONFIG_RAMSIZE=0x00000000 26 - CONFIG_VECTORBASE=0x00000000 27 - CONFIG_KERNELBASE=0x00020000 28 - CONFIG_BINFMT_FLAT=y 29 - CONFIG_NET=y 30 - CONFIG_PACKET=y 31 - CONFIG_UNIX=y 32 - CONFIG_INET=y 33 - # CONFIG_INET_XFRM_MODE_TRANSPORT is not set 34 - # CONFIG_INET_XFRM_MODE_TUNNEL is not set 35 - # CONFIG_INET_XFRM_MODE_BEET is not set 36 - # CONFIG_INET_LRO is not set 37 - # CONFIG_INET_DIAG is not set 38 - # CONFIG_IPV6 is not set 39 - CONFIG_MTD=y 40 - CONFIG_MTD_PARTITIONS=y 41 - CONFIG_MTD_CHAR=y 42 - CONFIG_MTD_BLOCK=y 43 - CONFIG_MTD_RAM=y 44 - CONFIG_MTD_UCLINUX=y 45 - CONFIG_BLK_DEV_RAM=y 46 - # CONFIG_MISC_DEVICES is not set 47 - CONFIG_NETDEVICES=y 48 - CONFIG_NET_ETHERNET=y 49 - CONFIG_FEC=y 50 - CONFIG_FEC2=y 51 - # CONFIG_NETDEV_1000 is not set 52 - # CONFIG_NETDEV_10000 is not set 53 - CONFIG_PPP=y 54 - # CONFIG_INPUT is not set 55 - # CONFIG_SERIO is not set 56 - # CONFIG_VT is not set 57 - CONFIG_SERIAL_MCF=y 58 - CONFIG_SERIAL_MCF_CONSOLE=y 59 - # CONFIG_UNIX98_PTYS is not set 60 - # CONFIG_HWMON is not set 61 - # CONFIG_USB_SUPPORT is not set 62 - CONFIG_EXT2_FS=y 63 - # CONFIG_FILE_LOCKING is not set 64 - # CONFIG_DNOTIFY is not set 65 - CONFIG_ROMFS_FS=y 66 - CONFIG_ROMFS_BACKED_BY_MTD=y 67 - # CONFIG_NETWORK_FILESYSTEMS is not set 68 - # CONFIG_RCU_CPU_STALL_DETECTOR is not set 69 - CONFIG_SYSCTL_SYSCALL_CHECK=y 70 - CONFIG_BOOTPARAM=y 71 - CONFIG_BOOTPARAM_STRING="root=/dev/mtdblock0" 72 - # CONFIG_CRC32 is not set
···
+18 -17
arch/m68knommu/configs/m5307c3_defconfig arch/m68k/configs/m5208evb_defconfig
··· 1 CONFIG_EXPERIMENTAL=y 2 CONFIG_LOG_BUF_SHIFT=14 3 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set ··· 12 # CONFIG_EVENTFD is not set 13 # CONFIG_AIO is not set 14 # CONFIG_VM_EVENT_COUNTERS is not set 15 - # CONFIG_SLUB_DEBUG is not set 16 # CONFIG_BLK_DEV_BSG is not set 17 # CONFIG_IOSCHED_DEADLINE is not set 18 # CONFIG_IOSCHED_CFQ is not set 19 - CONFIG_M5307=y 20 CONFIG_CLOCK_SET=y 21 - CONFIG_CLOCK_FREQ=90000000 22 CONFIG_CLOCK_DIV=2 23 - CONFIG_M5307C3=y 24 - CONFIG_RAMBASE=0x00000000 25 - CONFIG_RAMSIZE=0x00800000 26 - CONFIG_VECTORBASE=0x00000000 27 - CONFIG_KERNELBASE=0x00020000 28 CONFIG_BINFMT_FLAT=y 29 CONFIG_NET=y 30 CONFIG_PACKET=y ··· 38 # CONFIG_INET_LRO is not set 39 # CONFIG_INET_DIAG is not set 40 # CONFIG_IPV6 is not set 41 CONFIG_MTD=y 42 CONFIG_MTD_PARTITIONS=y 43 CONFIG_MTD_CHAR=y ··· 49 # CONFIG_MISC_DEVICES is not set 50 CONFIG_NETDEVICES=y 51 CONFIG_NET_ETHERNET=y 52 # CONFIG_NETDEV_1000 is not set 53 # CONFIG_NETDEV_10000 is not set 54 - CONFIG_PPP=y 55 - CONFIG_SLIP=y 56 - CONFIG_SLIP_COMPRESSED=y 57 - # CONFIG_INPUT_MOUSEDEV is not set 58 - # CONFIG_INPUT_KEYBOARD is not set 59 - # CONFIG_INPUT_MOUSE is not set 60 # CONFIG_SERIO is not set 61 # CONFIG_VT is not set 62 CONFIG_SERIAL_MCF=y 63 CONFIG_SERIAL_MCF_CONSOLE=y 64 - # CONFIG_LEGACY_PTYS is not set 65 # CONFIG_HW_RANDOM is not set 66 # CONFIG_HWMON is not set 67 - # CONFIG_HID_SUPPORT is not set 68 # CONFIG_USB_SUPPORT is not set 69 CONFIG_EXT2_FS=y 70 # CONFIG_DNOTIFY is not set 71 CONFIG_ROMFS_FS=y 72 CONFIG_ROMFS_BACKED_BY_MTD=y 73 # CONFIG_NETWORK_FILESYSTEMS is not set ··· 74 CONFIG_FULLDEBUG=y 75 CONFIG_BOOTPARAM=y 76 CONFIG_BOOTPARAM_STRING="root=/dev/mtdblock0" 77 - # CONFIG_CRC32 is not set
··· 1 + # CONFIG_MMU is not set 2 CONFIG_EXPERIMENTAL=y 3 CONFIG_LOG_BUF_SHIFT=14 4 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set ··· 11 # CONFIG_EVENTFD is not set 12 # CONFIG_AIO is not set 13 # CONFIG_VM_EVENT_COUNTERS is not set 14 + # CONFIG_COMPAT_BRK is not set 15 # CONFIG_BLK_DEV_BSG is not set 16 # CONFIG_IOSCHED_DEADLINE is not set 17 # CONFIG_IOSCHED_CFQ is not set 18 + CONFIG_M520x=y 19 CONFIG_CLOCK_SET=y 20 + CONFIG_CLOCK_FREQ=166666666 21 CONFIG_CLOCK_DIV=2 22 + CONFIG_M5208EVB=y 23 + # CONFIG_4KSTACKS is not set 24 + CONFIG_RAMBASE=0x40000000 25 + CONFIG_RAMSIZE=0x2000000 26 + CONFIG_VECTORBASE=0x40000000 27 + CONFIG_KERNELBASE=0x40020000 28 + CONFIG_RAM16BIT=y 29 CONFIG_BINFMT_FLAT=y 30 CONFIG_NET=y 31 CONFIG_PACKET=y ··· 35 # CONFIG_INET_LRO is not set 36 # CONFIG_INET_DIAG is not set 37 # CONFIG_IPV6 is not set 38 + # CONFIG_FW_LOADER is not set 39 CONFIG_MTD=y 40 CONFIG_MTD_PARTITIONS=y 41 CONFIG_MTD_CHAR=y ··· 45 # CONFIG_MISC_DEVICES is not set 46 CONFIG_NETDEVICES=y 47 CONFIG_NET_ETHERNET=y 48 + CONFIG_FEC=y 49 # CONFIG_NETDEV_1000 is not set 50 # CONFIG_NETDEV_10000 is not set 51 + # CONFIG_INPUT is not set 52 # CONFIG_SERIO is not set 53 # CONFIG_VT is not set 54 CONFIG_SERIAL_MCF=y 55 + CONFIG_SERIAL_MCF_BAUDRATE=115200 56 CONFIG_SERIAL_MCF_CONSOLE=y 57 + # CONFIG_UNIX98_PTYS is not set 58 # CONFIG_HW_RANDOM is not set 59 # CONFIG_HWMON is not set 60 # CONFIG_USB_SUPPORT is not set 61 CONFIG_EXT2_FS=y 62 + # CONFIG_FILE_LOCKING is not set 63 # CONFIG_DNOTIFY is not set 64 + # CONFIG_SYSFS is not set 65 CONFIG_ROMFS_FS=y 66 CONFIG_ROMFS_BACKED_BY_MTD=y 67 # CONFIG_NETWORK_FILESYSTEMS is not set ··· 72 CONFIG_FULLDEBUG=y 73 CONFIG_BOOTPARAM=y 74 CONFIG_BOOTPARAM_STRING="root=/dev/mtdblock0"
+9 -9
arch/m68knommu/configs/m5407c3_defconfig arch/m68k/configs/m5249evb_defconfig
··· 1 CONFIG_EXPERIMENTAL=y 2 CONFIG_LOG_BUF_SHIFT=14 3 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set ··· 12 # CONFIG_EVENTFD is not set 13 # CONFIG_AIO is not set 14 # CONFIG_VM_EVENT_COUNTERS is not set 15 - CONFIG_MODULES=y 16 - CONFIG_MODULE_UNLOAD=y 17 # CONFIG_BLK_DEV_BSG is not set 18 # CONFIG_IOSCHED_DEADLINE is not set 19 # CONFIG_IOSCHED_CFQ is not set 20 - CONFIG_M5407=y 21 CONFIG_CLOCK_SET=y 22 - CONFIG_CLOCK_FREQ=50000000 23 - CONFIG_M5407C3=y 24 CONFIG_RAMBASE=0x00000000 25 - CONFIG_RAMSIZE=0x00000000 26 CONFIG_VECTORBASE=0x00000000 27 CONFIG_KERNELBASE=0x00020000 28 CONFIG_BINFMT_FLAT=y ··· 36 # CONFIG_INET_LRO is not set 37 # CONFIG_INET_DIAG is not set 38 # CONFIG_IPV6 is not set 39 CONFIG_MTD=y 40 CONFIG_MTD_PARTITIONS=y 41 CONFIG_MTD_CHAR=y ··· 51 # CONFIG_NETDEV_10000 is not set 52 CONFIG_PPP=y 53 # CONFIG_INPUT is not set 54 # CONFIG_VT is not set 55 CONFIG_SERIAL_MCF=y 56 CONFIG_SERIAL_MCF_CONSOLE=y 57 # CONFIG_UNIX98_PTYS is not set 58 - # CONFIG_HW_RANDOM is not set 59 # CONFIG_HWMON is not set 60 # CONFIG_USB_SUPPORT is not set 61 CONFIG_EXT2_FS=y 62 # CONFIG_FILE_LOCKING is not set 63 - # CONFIG_DNOTIFY is not set 64 CONFIG_ROMFS_FS=y 65 CONFIG_ROMFS_BACKED_BY_MTD=y 66 # CONFIG_NETWORK_FILESYSTEMS is not set 67 # CONFIG_RCU_CPU_STALL_DETECTOR is not set 68 - CONFIG_SYSCTL_SYSCALL_CHECK=y 69 CONFIG_BOOTPARAM=y 70 CONFIG_BOOTPARAM_STRING="root=/dev/mtdblock0" 71 # CONFIG_CRC32 is not set
··· 1 + # CONFIG_MMU is not set 2 CONFIG_EXPERIMENTAL=y 3 CONFIG_LOG_BUF_SHIFT=14 4 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set ··· 11 # CONFIG_EVENTFD is not set 12 # CONFIG_AIO is not set 13 # CONFIG_VM_EVENT_COUNTERS is not set 14 + # CONFIG_SLUB_DEBUG is not set 15 # CONFIG_BLK_DEV_BSG is not set 16 # CONFIG_IOSCHED_DEADLINE is not set 17 # CONFIG_IOSCHED_CFQ is not set 18 + CONFIG_M5249=y 19 CONFIG_CLOCK_SET=y 20 + CONFIG_CLOCK_FREQ=140000000 21 + CONFIG_CLOCK_DIV=2 22 + CONFIG_M5249C3=y 23 CONFIG_RAMBASE=0x00000000 24 + CONFIG_RAMSIZE=0x00800000 25 CONFIG_VECTORBASE=0x00000000 26 CONFIG_KERNELBASE=0x00020000 27 CONFIG_BINFMT_FLAT=y ··· 35 # CONFIG_INET_LRO is not set 36 # CONFIG_INET_DIAG is not set 37 # CONFIG_IPV6 is not set 38 + # CONFIG_FW_LOADER is not set 39 CONFIG_MTD=y 40 CONFIG_MTD_PARTITIONS=y 41 CONFIG_MTD_CHAR=y ··· 49 # CONFIG_NETDEV_10000 is not set 50 CONFIG_PPP=y 51 # CONFIG_INPUT is not set 52 + # CONFIG_SERIO is not set 53 # CONFIG_VT is not set 54 CONFIG_SERIAL_MCF=y 55 CONFIG_SERIAL_MCF_CONSOLE=y 56 # CONFIG_UNIX98_PTYS is not set 57 # CONFIG_HWMON is not set 58 # CONFIG_USB_SUPPORT is not set 59 CONFIG_EXT2_FS=y 60 # CONFIG_FILE_LOCKING is not set 61 CONFIG_ROMFS_FS=y 62 CONFIG_ROMFS_BACKED_BY_MTD=y 63 # CONFIG_NETWORK_FILESYSTEMS is not set 64 # CONFIG_RCU_CPU_STALL_DETECTOR is not set 65 CONFIG_BOOTPARAM=y 66 CONFIG_BOOTPARAM_STRING="root=/dev/mtdblock0" 67 # CONFIG_CRC32 is not set
+9 -16
arch/m68knommu/defconfig arch/m68k/configs/m5272c3_defconfig
··· 1 CONFIG_EXPERIMENTAL=y 2 CONFIG_LOG_BUF_SHIFT=14 3 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set ··· 12 # CONFIG_EVENTFD is not set 13 # CONFIG_AIO is not set 14 # CONFIG_VM_EVENT_COUNTERS is not set 15 - # CONFIG_COMPAT_BRK is not set 16 # CONFIG_BLK_DEV_BSG is not set 17 # CONFIG_IOSCHED_DEADLINE is not set 18 # CONFIG_IOSCHED_CFQ is not set 19 - CONFIG_M520x=y 20 CONFIG_CLOCK_SET=y 21 - CONFIG_CLOCK_FREQ=166666666 22 - CONFIG_CLOCK_DIV=2 23 - CONFIG_M5208EVB=y 24 - # CONFIG_4KSTACKS is not set 25 - CONFIG_RAMBASE=0x40000000 26 - CONFIG_RAMSIZE=0x2000000 27 - CONFIG_VECTORBASE=0x40000000 28 - CONFIG_KERNELBASE=0x40020000 29 - CONFIG_RAM16BIT=y 30 CONFIG_BINFMT_FLAT=y 31 CONFIG_NET=y 32 CONFIG_PACKET=y ··· 34 # CONFIG_INET_LRO is not set 35 # CONFIG_INET_DIAG is not set 36 # CONFIG_IPV6 is not set 37 CONFIG_MTD=y 38 CONFIG_MTD_PARTITIONS=y 39 CONFIG_MTD_CHAR=y ··· 52 # CONFIG_SERIO is not set 53 # CONFIG_VT is not set 54 CONFIG_SERIAL_MCF=y 55 - CONFIG_SERIAL_MCF_BAUDRATE=115200 56 CONFIG_SERIAL_MCF_CONSOLE=y 57 # CONFIG_UNIX98_PTYS is not set 58 - # CONFIG_HW_RANDOM is not set 59 # CONFIG_HWMON is not set 60 # CONFIG_USB_SUPPORT is not set 61 CONFIG_EXT2_FS=y 62 # CONFIG_FILE_LOCKING is not set 63 # CONFIG_DNOTIFY is not set 64 - # CONFIG_SYSFS is not set 65 CONFIG_ROMFS_FS=y 66 CONFIG_ROMFS_BACKED_BY_MTD=y 67 # CONFIG_NETWORK_FILESYSTEMS is not set 68 # CONFIG_RCU_CPU_STALL_DETECTOR is not set 69 - CONFIG_SYSCTL_SYSCALL_CHECK=y 70 - CONFIG_FULLDEBUG=y 71 CONFIG_BOOTPARAM=y 72 CONFIG_BOOTPARAM_STRING="root=/dev/mtdblock0"
··· 1 + # CONFIG_MMU is not set 2 CONFIG_EXPERIMENTAL=y 3 CONFIG_LOG_BUF_SHIFT=14 4 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set ··· 11 # CONFIG_EVENTFD is not set 12 # CONFIG_AIO is not set 13 # CONFIG_VM_EVENT_COUNTERS is not set 14 + # CONFIG_SLUB_DEBUG is not set 15 # CONFIG_BLK_DEV_BSG is not set 16 # CONFIG_IOSCHED_DEADLINE is not set 17 # CONFIG_IOSCHED_CFQ is not set 18 + CONFIG_M5272=y 19 CONFIG_CLOCK_SET=y 20 + CONFIG_M5272C3=y 21 + CONFIG_RAMBASE=0x00000000 22 + CONFIG_RAMSIZE=0x00800000 23 + CONFIG_VECTORBASE=0x00000000 24 + CONFIG_KERNELBASE=0x00020000 25 CONFIG_BINFMT_FLAT=y 26 CONFIG_NET=y 27 CONFIG_PACKET=y ··· 37 # CONFIG_INET_LRO is not set 38 # CONFIG_INET_DIAG is not set 39 # CONFIG_IPV6 is not set 40 + # CONFIG_FW_LOADER is not set 41 CONFIG_MTD=y 42 CONFIG_MTD_PARTITIONS=y 43 CONFIG_MTD_CHAR=y ··· 54 # CONFIG_SERIO is not set 55 # CONFIG_VT is not set 56 CONFIG_SERIAL_MCF=y 57 CONFIG_SERIAL_MCF_CONSOLE=y 58 # CONFIG_UNIX98_PTYS is not set 59 # CONFIG_HWMON is not set 60 # CONFIG_USB_SUPPORT is not set 61 CONFIG_EXT2_FS=y 62 # CONFIG_FILE_LOCKING is not set 63 # CONFIG_DNOTIFY is not set 64 CONFIG_ROMFS_FS=y 65 CONFIG_ROMFS_BACKED_BY_MTD=y 66 # CONFIG_NETWORK_FILESYSTEMS is not set 67 # CONFIG_RCU_CPU_STALL_DETECTOR is not set 68 CONFIG_BOOTPARAM=y 69 CONFIG_BOOTPARAM_STRING="root=/dev/mtdblock0"
-1
arch/m68knommu/kernel/.gitignore
··· 1 - vmlinux.lds
···
arch/m68knommu/kernel/Makefile arch/m68k/kernel/Makefile_no
arch/m68knommu/kernel/asm-offsets.c arch/m68k/kernel/asm-offsets_no.c
arch/m68knommu/kernel/dma.c arch/m68k/kernel/dma_no.c
arch/m68knommu/kernel/entry.S arch/m68k/kernel/entry_no.S
arch/m68knommu/kernel/init_task.c arch/m68k/kernel/init_task.c
arch/m68knommu/kernel/irq.c arch/m68k/kernel/irq.c
arch/m68knommu/kernel/m68k_ksyms.c arch/m68k/kernel/m68k_ksyms_no.c
arch/m68knommu/kernel/module.c arch/m68k/kernel/module_no.c
arch/m68knommu/kernel/process.c arch/m68k/kernel/process_no.c
arch/m68knommu/kernel/ptrace.c arch/m68k/kernel/ptrace_no.c
arch/m68knommu/kernel/setup.c arch/m68k/kernel/setup_no.c
arch/m68knommu/kernel/signal.c arch/m68k/kernel/signal_no.c
arch/m68knommu/kernel/sys_m68k.c arch/m68k/kernel/sys_m68k_no.c
arch/m68knommu/kernel/syscalltable.S arch/m68k/kernel/syscalltable.S
arch/m68knommu/kernel/time.c arch/m68k/kernel/time_no.c
arch/m68knommu/kernel/traps.c arch/m68k/kernel/traps_no.c
arch/m68knommu/kernel/vmlinux.lds.S arch/m68k/kernel/vmlinux.lds_no.S
arch/m68knommu/lib/Makefile arch/m68k/lib/Makefile_no
+23 -22
arch/m68knommu/lib/ashldi3.c arch/m68k/lib/muldi3_mm.c
··· 1 - /* ashrdi3.c extracted from gcc-2.95.2/libgcc2.c which is: */ 2 - /* Copyright (C) 1989, 92-98, 1999 Free Software Foundation, Inc. 3 4 This file is part of GNU CC. 5 ··· 21 22 #define BITS_PER_UNIT 8 23 24 - typedef int SItype __attribute__ ((mode (SI))); 25 typedef unsigned int USItype __attribute__ ((mode (SI))); 26 typedef int DItype __attribute__ ((mode (DI))); 27 typedef int word_type __attribute__ ((mode (__word__))); ··· 47 } DIunion; 48 49 DItype 50 - __ashldi3 (DItype u, word_type b) 51 { 52 DIunion w; 53 - word_type bm; 54 - DIunion uu; 55 56 - if (b == 0) 57 - return u; 58 59 - uu.ll = u; 60 - 61 - bm = (sizeof (SItype) * BITS_PER_UNIT) - b; 62 - if (bm <= 0) 63 - { 64 - w.s.low = 0; 65 - w.s.high = (USItype)uu.s.low << -bm; 66 - } 67 - else 68 - { 69 - USItype carries = (USItype)uu.s.low >> bm; 70 - w.s.low = (USItype)uu.s.low << b; 71 - w.s.high = ((USItype)uu.s.high << b) | carries; 72 - } 73 74 return w.ll; 75 }
··· 1 + /* muldi3.c extracted from gcc-2.7.2.3/libgcc2.c and 2 + gcc-2.7.2.3/longlong.h which is: */ 3 + /* Copyright (C) 1989, 1992, 1993, 1994, 1995 Free Software Foundation, Inc. 4 5 This file is part of GNU CC. 6 ··· 20 21 #define BITS_PER_UNIT 8 22 23 + #define umul_ppmm(w1, w0, u, v) \ 24 + __asm__ ("mulu%.l %3,%1:%0" \ 25 + : "=d" ((USItype)(w0)), \ 26 + "=d" ((USItype)(w1)) \ 27 + : "%0" ((USItype)(u)), \ 28 + "dmi" ((USItype)(v))) 29 + 30 + #define __umulsidi3(u, v) \ 31 + ({DIunion __w; \ 32 + umul_ppmm (__w.s.high, __w.s.low, u, v); \ 33 + __w.ll; }) 34 + 35 + typedef int SItype __attribute__ ((mode (SI))); 36 typedef unsigned int USItype __attribute__ ((mode (SI))); 37 typedef int DItype __attribute__ ((mode (DI))); 38 typedef int word_type __attribute__ ((mode (__word__))); ··· 34 } DIunion; 35 36 DItype 37 + __muldi3 (DItype u, DItype v) 38 { 39 DIunion w; 40 + DIunion uu, vv; 41 42 + uu.ll = u, 43 + vv.ll = v; 44 45 + w.ll = __umulsidi3 (uu.s.low, vv.s.low); 46 + w.s.high += ((USItype) uu.s.low * (USItype) vv.s.high 47 + + (USItype) uu.s.high * (USItype) vv.s.low); 48 49 return w.ll; 50 }
-63
arch/m68knommu/lib/ashrdi3.c
··· 1 - /* ashrdi3.c extracted from gcc-2.7.2/libgcc2.c which is: */ 2 - /* Copyright (C) 1989, 1992, 1993, 1994, 1995 Free Software Foundation, Inc. 3 - 4 - This file is part of GNU CC. 5 - 6 - GNU CC is free software; you can redistribute it and/or modify 7 - it under the terms of the GNU General Public License as published by 8 - the Free Software Foundation; either version 2, or (at your option) 9 - any later version. 10 - 11 - GNU CC is distributed in the hope that it will be useful, 12 - but WITHOUT ANY WARRANTY; without even the implied warranty of 13 - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 - GNU General Public License for more details. 15 - 16 - You should have received a copy of the GNU General Public License 17 - along with GNU CC; see the file COPYING. If not, write to 18 - the Free Software Foundation, 59 Temple Place - Suite 330, 19 - Boston, MA 02111-1307, USA. */ 20 - 21 - #define BITS_PER_UNIT 8 22 - 23 - typedef int SItype __attribute__ ((mode (SI))); 24 - typedef unsigned int USItype __attribute__ ((mode (SI))); 25 - typedef int DItype __attribute__ ((mode (DI))); 26 - typedef int word_type __attribute__ ((mode (__word__))); 27 - 28 - struct DIstruct {SItype high, low;}; 29 - 30 - typedef union 31 - { 32 - struct DIstruct s; 33 - DItype ll; 34 - } DIunion; 35 - 36 - DItype 37 - __ashrdi3 (DItype u, word_type b) 38 - { 39 - DIunion w; 40 - word_type bm; 41 - DIunion uu; 42 - 43 - if (b == 0) 44 - return u; 45 - 46 - uu.ll = u; 47 - 48 - bm = (sizeof (SItype) * BITS_PER_UNIT) - b; 49 - if (bm <= 0) 50 - { 51 - /* w.s.high = 1..1 or 0..0 */ 52 - w.s.high = uu.s.high >> (sizeof (SItype) * BITS_PER_UNIT - 1); 53 - w.s.low = uu.s.high >> -bm; 54 - } 55 - else 56 - { 57 - USItype carries = (USItype)uu.s.high << bm; 58 - w.s.high = uu.s.high >> b; 59 - w.s.low = ((USItype)uu.s.low >> b) | carries; 60 - } 61 - 62 - return w.ll; 63 - }
···
arch/m68knommu/lib/checksum.c arch/m68k/lib/checksum_no.c
arch/m68knommu/lib/delay.c arch/m68k/lib/delay.c
arch/m68knommu/lib/divsi3.S arch/m68k/lib/divsi3.S
-62
arch/m68knommu/lib/lshrdi3.c
··· 1 - /* lshrdi3.c extracted from gcc-2.7.2/libgcc2.c which is: */ 2 - /* Copyright (C) 1989, 1992, 1993, 1994, 1995 Free Software Foundation, Inc. 3 - 4 - This file is part of GNU CC. 5 - 6 - GNU CC is free software; you can redistribute it and/or modify 7 - it under the terms of the GNU General Public License as published by 8 - the Free Software Foundation; either version 2, or (at your option) 9 - any later version. 10 - 11 - GNU CC is distributed in the hope that it will be useful, 12 - but WITHOUT ANY WARRANTY; without even the implied warranty of 13 - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 - GNU General Public License for more details. 15 - 16 - You should have received a copy of the GNU General Public License 17 - along with GNU CC; see the file COPYING. If not, write to 18 - the Free Software Foundation, 59 Temple Place - Suite 330, 19 - Boston, MA 02111-1307, USA. */ 20 - 21 - #define BITS_PER_UNIT 8 22 - 23 - typedef int SItype __attribute__ ((mode (SI))); 24 - typedef unsigned int USItype __attribute__ ((mode (SI))); 25 - typedef int DItype __attribute__ ((mode (DI))); 26 - typedef int word_type __attribute__ ((mode (__word__))); 27 - 28 - struct DIstruct {SItype high, low;}; 29 - 30 - typedef union 31 - { 32 - struct DIstruct s; 33 - DItype ll; 34 - } DIunion; 35 - 36 - DItype 37 - __lshrdi3 (DItype u, word_type b) 38 - { 39 - DIunion w; 40 - word_type bm; 41 - DIunion uu; 42 - 43 - if (b == 0) 44 - return u; 45 - 46 - uu.ll = u; 47 - 48 - bm = (sizeof (SItype) * BITS_PER_UNIT) - b; 49 - if (bm <= 0) 50 - { 51 - w.s.high = 0; 52 - w.s.low = (USItype)uu.s.high >> -bm; 53 - } 54 - else 55 - { 56 - USItype carries = (USItype)uu.s.high << bm; 57 - w.s.high = (USItype)uu.s.high >> b; 58 - w.s.low = ((USItype)uu.s.low >> b) | carries; 59 - } 60 - 61 - return w.ll; 62 - }
···
arch/m68knommu/lib/memcpy.c arch/m68k/lib/memcpy.c
arch/m68knommu/lib/memmove.c arch/m68k/lib/memmove.c
arch/m68knommu/lib/memset.c arch/m68k/lib/memset.c
arch/m68knommu/lib/modsi3.S arch/m68k/lib/modsi3.S
arch/m68knommu/lib/muldi3.c arch/m68k/lib/muldi3_no.c
arch/m68knommu/lib/mulsi3.S arch/m68k/lib/mulsi3.S
arch/m68knommu/lib/udivsi3.S arch/m68k/lib/udivsi3.S
arch/m68knommu/lib/umodsi3.S arch/m68k/lib/umodsi3.S
arch/m68knommu/mm/Makefile arch/m68k/mm/Makefile_no
arch/m68knommu/mm/init.c arch/m68k/mm/init_no.c
arch/m68knommu/mm/kmap.c arch/m68k/mm/kmap_no.c
arch/m68knommu/platform/5206/Makefile arch/m68k/platform/5206/Makefile
arch/m68knommu/platform/5206/config.c arch/m68k/platform/5206/config.c
arch/m68knommu/platform/5206/gpio.c arch/m68k/platform/5206/gpio.c
arch/m68knommu/platform/5206e/Makefile arch/m68k/platform/5206e/Makefile
arch/m68knommu/platform/5206e/config.c arch/m68k/platform/5206e/config.c
arch/m68knommu/platform/5206e/gpio.c arch/m68k/platform/5206e/gpio.c
arch/m68knommu/platform/520x/Makefile arch/m68k/platform/520x/Makefile
arch/m68knommu/platform/520x/config.c arch/m68k/platform/520x/config.c
arch/m68knommu/platform/520x/gpio.c arch/m68k/platform/520x/gpio.c
arch/m68knommu/platform/523x/Makefile arch/m68k/platform/523x/Makefile
arch/m68knommu/platform/523x/config.c arch/m68k/platform/523x/config.c
arch/m68knommu/platform/523x/gpio.c arch/m68k/platform/523x/gpio.c
arch/m68knommu/platform/5249/Makefile arch/m68k/platform/5249/Makefile
arch/m68knommu/platform/5249/config.c arch/m68k/platform/5249/config.c
arch/m68knommu/platform/5249/gpio.c arch/m68k/platform/5249/gpio.c
arch/m68knommu/platform/5249/intc2.c arch/m68k/platform/5249/intc2.c
arch/m68knommu/platform/5272/Makefile arch/m68k/platform/5272/Makefile
arch/m68knommu/platform/5272/config.c arch/m68k/platform/5272/config.c
arch/m68knommu/platform/5272/gpio.c arch/m68k/platform/5272/gpio.c
arch/m68knommu/platform/5272/intc.c arch/m68k/platform/5272/intc.c
arch/m68knommu/platform/527x/Makefile arch/m68k/platform/527x/Makefile
arch/m68knommu/platform/527x/config.c arch/m68k/platform/527x/config.c
arch/m68knommu/platform/527x/gpio.c arch/m68k/platform/527x/gpio.c
arch/m68knommu/platform/528x/Makefile arch/m68k/platform/528x/Makefile
arch/m68knommu/platform/528x/config.c arch/m68k/platform/528x/config.c
arch/m68knommu/platform/528x/gpio.c arch/m68k/platform/528x/gpio.c
arch/m68knommu/platform/5307/Makefile arch/m68k/platform/5307/Makefile
arch/m68knommu/platform/5307/config.c arch/m68k/platform/5307/config.c
arch/m68knommu/platform/5307/gpio.c arch/m68k/platform/5307/gpio.c
arch/m68knommu/platform/5307/nettel.c arch/m68k/platform/5307/nettel.c
arch/m68knommu/platform/532x/Makefile arch/m68k/platform/532x/Makefile
arch/m68knommu/platform/532x/config.c arch/m68k/platform/532x/config.c
arch/m68knommu/platform/532x/gpio.c arch/m68k/platform/532x/gpio.c
arch/m68knommu/platform/5407/Makefile arch/m68k/platform/5407/Makefile
arch/m68knommu/platform/5407/config.c arch/m68k/platform/5407/config.c
arch/m68knommu/platform/5407/gpio.c arch/m68k/platform/5407/gpio.c
arch/m68knommu/platform/54xx/Makefile arch/m68k/platform/54xx/Makefile
arch/m68knommu/platform/54xx/config.c arch/m68k/platform/54xx/config.c
arch/m68knommu/platform/54xx/firebee.c arch/m68k/platform/54xx/firebee.c
arch/m68knommu/platform/68328/Makefile arch/m68k/platform/68328/Makefile
arch/m68knommu/platform/68328/bootlogo.h arch/m68k/platform/68328/bootlogo.h
arch/m68knommu/platform/68328/bootlogo.pl arch/m68k/platform/68328/bootlogo.pl
arch/m68knommu/platform/68328/config.c arch/m68k/platform/68328/config.c
arch/m68knommu/platform/68328/entry.S arch/m68k/platform/68328/entry.S
arch/m68knommu/platform/68328/head-de2.S arch/m68k/platform/68328/head-de2.S
arch/m68knommu/platform/68328/head-pilot.S arch/m68k/platform/68328/head-pilot.S
arch/m68knommu/platform/68328/head-ram.S arch/m68k/platform/68328/head-ram.S
arch/m68knommu/platform/68328/head-rom.S arch/m68k/platform/68328/head-rom.S
arch/m68knommu/platform/68328/ints.c arch/m68k/platform/68328/ints.c
arch/m68knommu/platform/68328/romvec.S arch/m68k/platform/68328/romvec.S
arch/m68knommu/platform/68328/timers.c arch/m68k/platform/68328/timers.c
arch/m68knommu/platform/68360/Makefile arch/m68k/platform/68360/Makefile
arch/m68knommu/platform/68360/commproc.c arch/m68k/platform/68360/commproc.c
arch/m68knommu/platform/68360/config.c arch/m68k/platform/68360/config.c
arch/m68knommu/platform/68360/entry.S arch/m68k/platform/68360/entry.S
arch/m68knommu/platform/68360/head-ram.S arch/m68k/platform/68360/head-ram.S
arch/m68knommu/platform/68360/head-rom.S arch/m68k/platform/68360/head-rom.S
arch/m68knommu/platform/68360/ints.c arch/m68k/platform/68360/ints.c
arch/m68knommu/platform/68EZ328/Makefile arch/m68k/platform/68EZ328/Makefile
arch/m68knommu/platform/68EZ328/bootlogo.h arch/m68k/platform/68EZ328/bootlogo.h
arch/m68knommu/platform/68EZ328/config.c arch/m68k/platform/68EZ328/config.c
arch/m68knommu/platform/68VZ328/Makefile arch/m68k/platform/68VZ328/Makefile
arch/m68knommu/platform/68VZ328/config.c arch/m68k/platform/68VZ328/config.c
arch/m68knommu/platform/Makefile arch/m68k/platform/Makefile
arch/m68knommu/platform/coldfire/Makefile arch/m68k/platform/coldfire/Makefile
arch/m68knommu/platform/coldfire/cache.c arch/m68k/platform/coldfire/cache.c
arch/m68knommu/platform/coldfire/clk.c arch/m68k/platform/coldfire/clk.c
arch/m68knommu/platform/coldfire/dma.c arch/m68k/platform/coldfire/dma.c
arch/m68knommu/platform/coldfire/dma_timer.c arch/m68k/platform/coldfire/dma_timer.c
arch/m68knommu/platform/coldfire/entry.S arch/m68k/platform/coldfire/entry.S
arch/m68knommu/platform/coldfire/gpio.c arch/m68k/platform/coldfire/gpio.c
arch/m68knommu/platform/coldfire/head.S arch/m68k/platform/coldfire/head.S
arch/m68knommu/platform/coldfire/intc-2.c arch/m68k/platform/coldfire/intc-2.c
arch/m68knommu/platform/coldfire/intc-simr.c arch/m68k/platform/coldfire/intc-simr.c
arch/m68knommu/platform/coldfire/intc.c arch/m68k/platform/coldfire/intc.c
arch/m68knommu/platform/coldfire/pinmux.c arch/m68k/platform/coldfire/pinmux.c
arch/m68knommu/platform/coldfire/pit.c arch/m68k/platform/coldfire/pit.c
arch/m68knommu/platform/coldfire/sltimers.c arch/m68k/platform/coldfire/sltimers.c
arch/m68knommu/platform/coldfire/timers.c arch/m68k/platform/coldfire/timers.c
arch/m68knommu/platform/coldfire/vectors.c arch/m68k/platform/coldfire/vectors.c