diff -u --recursive --new-file v2.4.7/linux/Documentation/Configure.help linux/Documentation/Configure.help --- v2.4.7/linux/Documentation/Configure.help Wed Jul 25 17:10:16 2001 +++ linux/Documentation/Configure.help Thu Jul 26 16:30:04 2001 @@ -12471,6 +12471,33 @@ Say Y here if you would like to use hard disks under Linux which were partitioned on a Macintosh. +Windows' Logical Disk Manager (Dynamic Disk) support (EXPERIMENTAL) +CONFIG_LDM_PARTITION + Say Y here if you would like to use hard disks under Linux which + were partitioned using Windows 2000's or XP's Logical Disk Manager. + They are also known as "Dynamic Disks". + + Windows 2000 introduced the concept of Dynamic Disks to get around + the limitations of the PC's partitioning scheme. The Logical Disk + Manager allows the user to repartion a disk and create spanned, + mirrored, striped or RAID volumes, all without the need for + rebooting. + + Normal partitions are now called Basic Disks under Windows 2000 and XP. + + Technical documentation to accompany this driver is available from: + + + If unsure, say N. + +Windows' LDM extra logging +CONFIG_LDM_DEBUG + Say Y here if you would like LDM to log verbosely. This could be + helpful if the driver doesn't work as expected and you'd like to + report a bug. + + If unsure, say N. + PC BIOS (MSDOS partition tables) support CONFIG_MSDOS_PARTITION Say Y here if you would like to use hard disks under Linux which diff -u --recursive --new-file v2.4.7/linux/Documentation/s390/CommonIO linux/Documentation/s390/CommonIO --- v2.4.7/linux/Documentation/s390/CommonIO Wed Dec 31 16:00:00 1969 +++ linux/Documentation/s390/CommonIO Wed Jul 25 14:12:01 2001 @@ -0,0 +1,124 @@ +S/390 common I/O-Layer - command line parameters and /proc entries +================================================================== + +Command line parameters +----------------------- + +* cio_msg = yes | no + + Determines whether information on found devices and sensed device + characteristics should be shown during startup, i. e. messages of the types + "Detected device 4711 on subchannel 42" and "SenseID: Device 4711 reports: ...". + + Default is off. + + +* cio_notoper_msg = yes | no + + Determines whether messages of the type "Device 4711 became 'not operational'" + should be shown during startup; after startup, they will always be shown. + + Default is on. + + +* cio_ignore = , , ... + + The given device numbers will be ignored by the common I/O-layer; no detection + and device sensing will be done on any of those devices. The subchannel to + which the device in question is attached will be treated as if no device was + attached. + + An ignored device can be un-ignored later; see the "/proc entries"-section for + details. + + The device numbers must be given hexadecimal. + + For example, + cio_ignore=0x23-0x42,0x4711 + will ignore all devices with device numbers ranging from 23 to 42 and the + device with device number 4711, if detected. + + By default, no devices are ignored. + + +* cio_proc_devinfo = yes | no + + Determines whether the entries under /proc/deviceinfo/ (see below) should be + created. Since there are problems with systems with many devices attached, I + made it configurable. + + Until the problems are dealt with, default is off. + + +/proc entries +------------- + +* /proc/subchannels + + Shows for each subchannel + - device number + - device type/model and if applicable control unit type/model + - whether the device is in use + - path installed mask, path available mask, path operational mask and last + path used mask + - the channel path IDs (chpids) + + +* /proc/deviceinfo/ + + Shows in subdirectories for each device some characteristics: + - /proc/deviceinfo//chpids: + the channel path IDs + - /proc/deviceinfo//in_use: + whether the device is in use + - /proc/deviceinfo//sensedata: + the device type/model and if applicable control unit type/model of the + device + + NOTE: Since the number of inodes which can be dynamically allocated by procfs + is limited, device entries will only be created up to a magic number of + devices. The kernel will utter a warning that not all entries can be + created. In this case, you shouldn't use "cio_proc_devinfo=yes" (see + above). + +* /proc/cio_ignore + + Lists the ranges of device numbers which are ignored by common I/O. + + You can un-ignore certain or all devices by piping to /proc/cio_ignore. + "free all" will un-ignore all ignored devices, + "free , , ..." will un-ignore the specified devices. + + For example, if devices 23 to 42 and 4711 are ignored, + - echo free 0x30-0x32 > /proc/cio_ignore + will un-ignore devices 30 to 32 and will leave devices 23 to 2F, 33 to 42 + and 4711 ignored; + - echo free 0x41 > /proc/cio_ignore will furthermore un-ignore device 41; + - echo free all > /proc/cio_ignore will un-ignore all remaining ignored + devices. + + When a device is un-ignored, device recognition and sensing is performed and + the device driver will be notified if possible, so the device will become + available to the system. + + +* /proc/s390dbf/cio_*/ (S/390 debug feature) + + Some views generated by the debug feature to hold various debug outputs. + + - /proc/s390dbf/cio_crw/sprintf + Messages from the processing of pending channel report words (machine check + handling), which will also show when CONFIG_DEBUG_CRW is defined. + + - /proc/s390dbf/cio_msg/sprintf + Various debug messages from the common I/O-layer; generally, messages which + will also show when CONFIG_DEBUG_IO is defined. + + - /proc/s390dbf/cio_trace/hex_ascii + Logs the calling of functions in the common I/O-layer and, if applicable, + which subchannel they were called for. + + The level of logging can be changed to be more or less verbose by piping to + /proc/s390dbf/cio_*/level a number between 0 and 6; see the documentation on + the S/390 debug feature (Documentation/s390/s390dbf.txt) for details. + diff -u --recursive --new-file v2.4.7/linux/Documentation/s390/Debugging390.txt linux/Documentation/s390/Debugging390.txt --- v2.4.7/linux/Documentation/s390/Debugging390.txt Sun May 20 12:11:38 2001 +++ linux/Documentation/s390/Debugging390.txt Wed Jul 25 14:12:01 2001 @@ -1,5 +1,5 @@ - Debugging on Linux for s/390 & zSeries + Debugging on Linux for s/390 & z/Architecture by Denis Joseph Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com) Copyright (C) 2000-2001 IBM Deutschland Entwicklung GmbH, IBM Corporation @@ -8,7 +8,7 @@ Overview of Document: ===================== This document is intended to give an good overview of how to debug -Linux for s/390 & zSeries it isn't intended as a complete reference & not a +Linux for s/390 & z/Architecture it isn't intended as a complete reference & not a tutorial on the fundamentals of C & assembly, it dosen't go into 390 IO in any detail. It is intended to compliment the documents in the reference section below & any other worthwhile references you get. @@ -21,46 +21,46 @@ ======== Register Set Address Spaces on Intel Linux -Address Spaces on Linux for s/390 & zSeries -The Linux for s/390 & zSeries Kernel Task Structure -Register Usage & Stackframes on Linux for s/390 & zSeries +Address Spaces on Linux for s/390 & z/Architecture +The Linux for s/390 & z/Architecture Kernel Task Structure +Register Usage & Stackframes on Linux for s/390 & z/Architecture A sample program with comments -Compiling programs for debugging on Linux for s/390 & zSeries +Compiling programs for debugging on Linux for s/390 & z/Architecture Figuring out gcc compile errors Debugging Tools objdump strace Performance Debugging Debugging under VM -s/390 & zSeries IO Overview -Debugging IO on s/390 & zSeries under VM -GDB on s/390 & zSeries +s/390 & z/Architecture IO Overview +Debugging IO on s/390 & z/Architecture under VM +GDB on s/390 & z/Architecture Stack chaining in gdb by hand Examining core dumps ldd Debugging modules The proc file system Starting points for debugging scripting languages etc. -Tools soon to be available SysRq References +Special Thanks Register Set ============ The current architectures have the following registers. -16 General propose registers, 32 bit on s/390 64 bit on zSeries, r0-r15 or gpr0-gpr15 used for arithmetic & addressing. +16 General propose registers, 32 bit on s/390 64 bit on z/Architecture, r0-r15 or gpr0-gpr15 used for arithmetic & addressing. -16 Control registers, 32 bit on s/390 64 bit on zSeries, ( cr0-cr15 kernel usage only ) used for memory managment, +16 Control registers, 32 bit on s/390 64 bit on z/Architecture, ( cr0-cr15 kernel usage only ) used for memory managment, interrupt control,debugging control etc. -16 Access registers ( ar0-ar15 ) 32 bit on s/390 & zSeries +16 Access registers ( ar0-ar15 ) 32 bit on s/390 & z/Architecture not used by normal programs but potentially could be used as temporary storage. Their main purpose is their 1 to 1 association with general purpose registers and are used in the kernel for copying data between kernel & user address spaces. -Access register 0 ( & access register 1 on z/Series ( needs 64 bit pointer ) ) -is currently used by the pthread library as a pointer to +Access register 0 ( & access register 1 on z/Architecture ( needs 64 bit +pointer ) ) is currently used by the pthread library as a pointer to the current running threads private area. 16 64 bit floating point registers (fp0-fp15 ) IEEE & HFP floating @@ -72,7 +72,7 @@ The PSW is the most important register on the machine it -is 64 bit on s/390 & 128 bit on zSeries & serves the roles of +is 64 bit on s/390 & 128 bit on z/Architecture & serves the roles of a program counter (pc), condition code register,memory space designator. In IBM standard notation I am counting bit 0 as the MSB. It has several advantages over a normal program counter @@ -83,7 +83,7 @@ currently running at. Bit Value -s/390 zSeries +s/390 z/Architecture 0 0 Reserved ( must be 0 ) otherwise specification exception occurs. 1 1 Program Event Recording 1 PER enabled, @@ -100,7 +100,7 @@ 8-11 8-11 PSW Key used for complex memory protection mechanism not used under linux -12 12 1 on s/390 0 on zSeries +12 12 1 on s/390 0 on z/Architecture 13 13 Machine Check Mask 1=enable machine check interrupts @@ -175,15 +175,19 @@ compatible. -Prefix Page ------------ +Prefix Page(s) +-------------- This per cpu memory area is too intimately tied to the processor not to mention. -It exists between the real addresses 0-4096 on the processor & is exchanged -with a page in absolute storage by the set prefix instruction in linux'es startup. -This page different on each processor. -Bytes 0-512 ( 200 hex ) are used by the processor itself for holding such -information as exception indications & entry points for exceptions. -Bytes after 0xc00 hex are used by linux for per processor globals. +It exists between the real addresses 0-4096 on s/390 & 0-8192 z/Architecture & is exchanged +with a 1 page on s/390 or 2 pages on z/Architecture in absolute storage by the set +prefix instruction in linux'es startup. +This page is mapped to a different prefix for each processor in an SMP configuration +( assuming the os designer is sane of course :-) ). +Bytes 0-512 ( 200 hex ) on s/390 & 0-512,4096-4544,4604-5119 currently on z/Architecture +are used by the processor itself for holding such information as exception indications & +entry points for exceptions. +Bytes after 0xc00 hex are used by linux for per processor globals on s/390 & z/Architecture +( there is a gap on z/Architecure too currently between 0xc00 & 1000 which linux uses ). The closest thing to this on traditional architectures is the interrupt vector table. This is a good thing & does simplify some of the kernel coding however it means that we now cannot catch stray NULL pointers in the @@ -219,9 +223,6 @@ If using the virtual machine ( VM ) as a debugger it is quite difficult to know which user process is running as the address space you are looking at could be from any process in the run queue. -Thankfully you normally get lucky as address spaces don't overlap that & -you can recognise the code at by cross referencing with a dump made by objdump -( more about that later ). The limitation of Intels addressing technique is that the linux kernel uses a very simple real address to virtual addressing technique @@ -240,35 +241,77 @@ of our 32 bit addresses,however, we use entirely separate address spaces for the user & kernel. -This means we can support 2GB of non Extended RAM, & more -with the Extended memory managment swap device & 64 Bit -when it comes along. +This means we can support 2GB of non Extended RAM on s/390, & more +with the Extended memory managment swap device & +currently 4TB of physical memory currently on z/Architecture. -Address Spaces on Linux for S390 -================================ +Address Spaces on Linux for s/390 & z/Architecture +================================================== Our addressing scheme is as follows -Himem 0x7fffffff 2GB on s/390 ***************** **************** -2^64 bytes on zSeries * User Stack * * * - ***************** * * - * Shared Libs * * * - ***************** * * - * * * Kernel * - * User Program * * * - * Data BSS * * * - * Text * * * - * Sections * * * -0x00000000 ***************** **************** +Himem 0x7fffffff 2GB on s/390 ***************** **************** +currently 0x3ffffffffff (2^42)-1 * User Stack * * * +on z/Architecture. ***************** * * + * Shared Libs * * * + ***************** * * + * * * Kernel * + * User Program * * * + * Data BSS * * * + * Text * * * + * Sections * * * +0x00000000 ***************** **************** This also means that we need to look at the PSW problem state bit or the addressing mode to decide whether we are looking at -user or kernel space. +user or kernel space. + +Virtual Addresses on s/390 & z/Architecture +=========================================== + +A virtual address on s/390 is made up of 3 parts +The SX ( segment index, roughly corresponding to the PGD & PMD in linux terminology ) +being bits 1-11. +The PX ( page index, corresponding to the page table entry (pte) in linux terminology ) +being bits 12-19. +The remaining bits BX (the byte index are the offset in the page ) +i.e. bits 20 to 31. + +On z/Architecture in linux we currently make up an address from 4 parts. +The region index bits (RX) 0-32 we currently use bits 22-32 +The segment index (SX) being bits 33-43 +The page index (PX) being bits 44-51 +The byte index (BX) being bits 52-63 + +Notes: +1) s/390 has no PMD so the PMD is really the PGD also. +A lot of this stuff is defined in pgtable.h. + +2) Also seeing as s/390's page indexes are only 1k in size +(bits 12-19 x 4 bytes per pte ) we use 1 ( page 4k ) +to make the best use of memory by updating 4 segment indices +entries each time we mess with a PMD & use offsets +0,1024,2048 & 3072 in this page as for our segment indexes. +On z/Architecture our page indexes are now 2k in size +( bits 12-19 x 8 bytes per pte ) we do a similar trick +but only mess with 2 segment indices each time we mess with +a PMD. + +3) As z/Architecture supports upto a massive 5-level page table lookup we +can only use 3 currently on Linux ( as this is all the generic kernel +currently supports ) however this may change in future +this allows us to access ( according to my sums ) +4TB of virtual storage per process i.e. +4096*512(PTES)*1024(PMDS)*2048(PGD) = 4398046511104 bytes, +enough for another 2 or 3 of years I think :-). +to do this we use a region-third-table designation type in +our address space control registers. + -The Linux for s/390 & zSeries Kernel Task Structure -=================================================== +The Linux for s/390 & z/Architecture Kernel Task Structure +========================================================== Each process/thread under Linux for S390 has its own kernel task_struct defined in linux/include/linux/sched.h The S390 on initialisation & resuming of a process on a cpu sets @@ -287,7 +330,7 @@ * ( 4K ) * 8K aligned ************************ - zSeries + z/Architecture ************************ * 2 page kernel stack * * ( 8K ) * @@ -298,7 +341,7 @@ What this means is that we don't need to dedicate any register or global variable to point to the current running process & can retrieve it with the following -very simple construct for s/390 & one very similar for zSeries. +very simple construct for s/390 & one very similar for z/Architecture. static inline struct task_struct * get_current(void) { @@ -317,8 +360,8 @@ -Register Usage & Stackframes on Linux for s/390 & zSeries -========================================================= +Register Usage & Stackframes on Linux for s/390 & z/Architecture +================================================================= Overview: --------- This is the code that gcc produces at the top & the bottom of @@ -331,7 +374,7 @@ limited knowledge of one assembly language. It should be noted that there are some differences between the -s/390 & zSeries stack layouts as the zSeries stack layout didn't have +s/390 & z/Architecture stack layouts as the z/Architecture stack layout didn't have to maintain compatibility with older linkage formats. Glossary: @@ -367,8 +410,8 @@ The code generated by the compiler to return to the caller. frameless-function -A frameless function in Linux for s390 & zSeries is one which doesn't need -more than the register save area ( 96 bytes on s/390, 160 on zSeries ) +A frameless function in Linux for s390 & z/Architecture is one which doesn't +need more than the register save area ( 96 bytes on s/390, 160 on z/Architecture ) given to it by the caller. A frameless function never: 1) Sets up a back chain. @@ -428,8 +471,8 @@ } -s/390 & zSeries Register usage -============================== +s/390 & z/Architecture Register usage +===================================== r0 used by syscalls/assembly call-clobbered r1 used by syscalls/assembly call-clobbered r2 argument 0 / return value 0 call-clobbered @@ -449,8 +492,8 @@ f0 argument 0 / return value ( float/double ) call-clobbered f2 argument 1 call-clobbered -f4 zSeries argument 2 saved -f6 zSeries argument 3 saved +f4 z/Architecture argument 2 saved +f6 z/Architecture argument 3 saved The remaining floating points f1,f3,f5 f7-f15 are call-clobbered. @@ -479,12 +522,13 @@ area if crossing this boundary. 6) Floating point parameters are mixed with outgoing args on the outgoing args area in the order the are passed in as parameters. -7) Floating point arguments 2 & 3 are saved in the outgoing args area for zSeries +7) Floating point arguments 2 & 3 are saved in the outgoing args area for +z/Architecture Stack Frame Layout ------------------ -s/390 zSeries +s/390 z/Architecture 0 0 back chain ( a 0 here signifies end of back chain ) 4 8 eos ( end of stack, not used on Linux for S390 used in other linkage formats ) 8 16 glue used in other s/390 linkage formats for saved routine descriptors etc. @@ -598,8 +642,8 @@ stack backchain in optimised code as this also causes pipeline stalls, you have been warned. -64 bit zSeries code disassembly -------------------------------- +64 bit z/Architecture code disassembly +-------------------------------------- If you understand the stuff above you'll understand the stuff below too so I'll avoid repeating myself & just say that @@ -637,12 +681,14 @@ -Compiling programs for debugging on Linux for s/390 & zSeries -============================================================= --gdwarf2 now works & normal -g debugging works much better now +Compiling programs for debugging on Linux for s/390 & z/Architecture +==================================================================== +-gdwarf-2 now works it should be considered the default debugging +format for s/390 & z/Architecture as it is more reliable for debugging +shared libraries, normal -g debugging works much better now Thanks to the IBM java compiler developers bug reports. -This is typically done adding/appending the flags -g to the +This is typically done adding/appending the flags -g or -gdwarf-2 to the CFLAGS & LDFLAGS variables Makefile of the program concerned. If using gdb & you would like accurate displays of registers & @@ -1148,7 +1194,7 @@ -------------------------------- D G will display all the gprs Adding a extra G to all the commands is neccessary to access the full 64 bit -content in VM on zSeries obviously this isn't required for access registers +content in VM on z/Architecture obviously this isn't required for access registers as these are still 32 bit. e.g. DGG instead of DG D X will display all the control registers @@ -1251,7 +1297,7 @@ tr i pswa
Start the program, if VM drops to CP on what looks like the entry point of the main function this is most likely the process you wish to debug. -Now do a D X13 or D XG13 on zSeries. +Now do a D X13 or D XG13 on z/Architecture. On 31 bit the STD is bits 1-19 ( the STO segment table origin ) & 25-31 ( the STL segment table length ) of CR13. now type @@ -1260,7 +1306,48 @@ TR I R STD 8F32E1FF 0.7fffffff Another very useful variation is TR STORE INTO STD
+for finding out when a particular variable changes. +An alternative way of finding the STD of a currently running process +is to do the following, ( this method is more complex but +could be quite convient if you aren't updating the kernel much & +so your kernel structures will stay constant for a reasonable period of +time ). + +grep task /proc//status +from this you should see something like +task: 0f160000 ksp: 0f161de8 pt_regs: 0f161f68 +This now gives you a pointer to the task structure. +Now make CC:="s390-gcc -g" kernel/sched.s +To get the task_struct stabinfo. +( task_struct is defined in include/linux/sched.h ). +Now we want to look at +task->active_mm->pgd +on my machine the active_mm in the task structure stab is +active_mm:(4,12),672,32 +its offset is 672/8=84=0x54 +the pgd member in the mm_struct stab is +pgd:(4,6)=*(29,5),96,32 +so its offset is 96/8=12=0xc + +so we'll +hexdump -s 0xf160054 /dev/mem | more +i.e. task_struct+active_mm offset +to look at the active_mm member +f160054 0fee cc60 0019 e334 0000 0000 0000 0011 +hexdump -s 0x0feecc6c /dev/mem | more +i.e. active_mm+pgd offset +feecc6c 0f2c 0000 0000 0001 0000 0001 0000 0010 +we get something like +now do +TR I R STD 0.7fffffff +i.e. the 0x7f is added because the pgd only +gives the page table origin & we need to set the low bits +to the maximum possible segment table length. +TR I R STD 0f2c007f 0.7fffffff +on z/Architecture you'll probably need to do +TR I R STD 0.ffffffffffffffff +to set the TableType to 0x1 & the Table length to 3. @@ -1347,10 +1434,18 @@ Help for displaying ascii textstrings ------------------------------------- -As textstrings are cannot be displayed in ASCII under the VM debugger ( I love EBDIC too ) I have -written this little program which will convert a command line of hex digits to ascii text -which can be compiled under linux & you can copy the hex digits from your x3270 terminal to -your xterm if you are debugging from a linuxbox. +On the very latest VM Nucleus'es VM can now display ascii +( thanks Neale for the hint ) by doing +D TX. +e.g. +D TX0.100 + +Alternatively +============= +Under older VM debuggers ( I love EBDIC too ) you can use this little program I wrote which +will convert a command line of hex digits to ascii text which can be compiled under linux & +you can copy the hex digits from your x3270 terminal to your xterm if you are debugging +from a linuxbox. This is quite useful when looking at a parameter passed in as a text string under VM ( unless you are good at decoding ASCII in your head ). @@ -1532,8 +1627,8 @@ -s/390 & zSeries IO Overview -=========================== +s/390 & z/Architecture IO Overview +================================== I am not going to give a course in 390 IO architecture as this would take me quite a while & I'm no expert. Instead I'll give a 390 IO architecture summary for Dummies if you have @@ -1685,15 +1780,15 @@ between 2 machines. We use 2 cables under linux to do a bi-directional serial link. -Debugging IO on s/390 & zSeries under VM -========================================= +Debugging IO on s/390 & z/Architecture under VM +=============================================== Now we are ready to go on with IO tracing commands under VM A few self explanatory queries: Q OSA Q CTC -Q DISK +Q DISK ( This command is CMS specific ) Q DASD @@ -1998,9 +2093,14 @@ This is done using a the same trick described for VM p/x (*($sp+56))&0x7fffffff get the first backchain. -For zSeries do -p/x *($sp+112) i.e. replace 56 with 112 & ignore the &0x7fffffff -in the macros below. +For z/Architecture +Replace 56 with 112 & ignore the &0x7fffffff +in the macros below & do nasty casts to longs like the following +as gdb unfortunately deals with printed arguments as ints which +messes up everything. +i.e. here is a 3rd backchain dereference +p/x *(long *)(***(long ***)$sp+112) + this outputs $5 = 0x528f18 @@ -2265,6 +2365,21 @@ Some driver debugging techniques ================================ +debug feature +------------- +Some of our drivers now support a "debug feature" in +/proc/s390dbf see s390dbf.txt in the linux/Documentation directory +for more info. +e.g. +to switch on the lcs "debug feature" +echo 5 > /proc/s390dbf/lcs/level +& then after the error occured. +cat /proc/s390dbf/lcs/sprintf >/logfile +the logfile now contains some information which may help +tech support resolve a problem in the field. + + + high level debugging network drivers ------------------------------------ ifconfig is a quite useful command @@ -2339,65 +2454,10 @@ & type ? in the debugger for help. -Debugging Drivers -================= -Some of our drivers now support a debug logging feature in -/proc/s390dbf see s390dbf.txt in the linux/Documentation directory -for more info. -e.g. -to switch on lcs debugging -echo 5 > /proc/s390dbf/lcs/level -& then after the error occured. -cat /proc/s390dbf/lcs/sprintf >/logfile -the logfile now contains some information which may help -tech support resolve a problem in the field. - -If you have VM look at the chapter Debugging IO on S390 under VM. - - - - -Tools soon to be available -========================== - -Dumptool & Lcrash ------------------ -Michael Holzheu & others here at IBM have a fairly mature port of -SGI's lcrash tool which allows one to look at kernel structures in a -running kernel. - -It also complements a tool called dumptool which dumps all the kernels -memory pages & registers to either a tape or a disk. -This can be used by tech support or an ambitous end user do -post mortem debugging of a machine like gdb core dumps. - -Going into how to use this tool in detail will be explained -in other documentation supplied by IBM & the lcrash homepage -http://oss.sgi.com/projects/lkcd/. - -How they work -------------- -Lcrash is a perfectly normal application -however it requires an additional file. -It is built using a patch to the kernel source base. - - -Debugging a live system it uses /dev/mem -alternatively for post mortem debugging it uses the data -collected by dumptool. - - -Ltrace ------- -We also have a tool called ltrace in our CVS repository -no plans on a delivery date yet. -ltrace is a superset of strace in that it also allows -tracing of shared libraries calls as well as system calls, -man ltrace for more info. SysRq ===== -This is now supported by linux for s/390 & zSeries. +This is now supported by linux for s/390 & z/Architecture. To enable it do compile the kernel with Kernel Hacking -> Magic SysRq Key Enabled echo "1" > /proc/sys/kernel/sysrq. @@ -2426,14 +2486,14 @@ Various info & man pages. CMS Help on tracing commands. Linux for s/390 Elf Application Binary Interface -Linux for zSeries Elf Application Binary Interface ( Both Highly Recommended ) +Linux for z/Series Elf Application Binary Interface ( Both Highly Recommended ) z/Architecture Principles of Operation SA22-7832-00 Enterprise Systems Architecture/390 Reference Summary SA22-7209-01 & the Enterprise Systems Architecture/390 Principles of Operation SA22-7201-05 - - - - - +Special Thanks +============== +Special thanks to Neale Ferguson who maintains a much +prettier HTML version of this page at +http://penguinvm.princeton.edu/notes.html#Debug390 diff -u --recursive --new-file v2.4.7/linux/Documentation/s390/TAPE linux/Documentation/s390/TAPE --- v2.4.7/linux/Documentation/s390/TAPE Fri Feb 16 15:53:08 2001 +++ linux/Documentation/s390/TAPE Wed Jul 25 14:12:01 2001 @@ -76,10 +76,9 @@ - ensure the tape is at the beginning mt -f /dev/ntibm0 rewind -- set the blocksize of the character driver. The blocksizes 512, 1024 - and 2048 bytes are supported by ISO9660. 1024 is the default, u - which will be used here. - mt -f /dev/ntibm0 setblk 1024 +- set the blocksize of the character driver. The blocksize 2048 bytes + is commonly used on ISO9660 CD-Roms + mt -f /dev/ntibm0 setblk 2048 - write the filesystem to the character device driver mkisofs -o /dev/ntibm0 somedir @@ -88,18 +87,16 @@ mt -f /dev/ntibm0 rewind - Now you can mount your new filesystem as a block device: - mount -t iso9660 -o ro,block=1024 /dev/btibm0 /mnt + mount -t iso9660 -o ro,block=2048 /dev/btibm0 /mnt TODO List -- The backend code has to be enhanced to support error-recovery actions. - -- The seeking algorithm of the block device has to be improved to speed - things up + - Driver has to be stabelized still BUGS -There are lots of weaknesses still in the code. This is why it is EXPERIMENTAL. +This driver is considered BETA, which means some weaknesses may still +be in it. If an error occurs which cannot be handled by the code you will get a sense-data dump.In that case please do the following: diff -u --recursive --new-file v2.4.7/linux/Documentation/s390/chandev.8 linux/Documentation/s390/chandev.8 --- v2.4.7/linux/Documentation/s390/chandev.8 Wed Apr 11 19:02:27 2001 +++ linux/Documentation/s390/chandev.8 Wed Jul 25 14:12:01 2001 @@ -7,29 +7,37 @@ .SH SYNOPSIS The channel device layer is a layer to provide a consistent interface for configuration & default machine check (devices appearing & disappearing ) -handling Linux for zSeries channel devices. +handling on Linux for s/390 & z/Series channel devices. -These include among others + +s/390 & z/Series channel devices include among others .Bl -item .It lcs ( the most common ethernet/token ring/fddi standard on zSeries ) .It -ctc/escon hi speed like serial link standard on zSeries. +ctc/escon hi speed like serial link standard on s/390 & z/Series. .It claw used to talk to cisco routers. .It qeth gigabit ethernet. -.El - +.It +osad used by osa/sf to configure osa devices, e.g. to share a osa card between 2 or more vm guests. osad is just added to the channel device layer for completeness, there are no plans at the current time to write a driver to exploit this under linux. +.It These devices use two channels one read & one write for configuration & -or communication. -The motivation behind producing this layer was that there is a lot of -duplicate code among the drivers for configuration so the lcs & ctc drivers -tended to fight over 3088/08's & 3088/1F's which could be either 2216/3172 -lcs compatible devices or escons/ctc's & to resolve this fight -both device drivers had to be reconfigured rather than doing the -configuration in a single place. +or communication ( & a third channel the data channel in the case of gigabit ethernet ). +The motivation behind developing this layer was that there was a lot of +duplicate code among the channel device drivers for configuration. +Also the lcs & ctc drivers tended to fight over 3088/08's & 3088/1F's which could +be either 2216/3172 channel attached lcs compatible devices or escon/ctc pipes +between guests & to resolve this fight both device drivers had to be configured +separately, this is now simplified by doing the configuration in a single place +( the channel device layer ). + +This layer isn't invasive & it is quite okay to use channel drivers +which don't use the channel device layer in conjunction with +drivers which do. +.El .SH DESCRIPTION The current setup can be read from /proc/chandev @@ -37,30 +45,65 @@ .Bl -enum .It Piping to /proc/chandev. +e.g. echo reprobe >/proc/chandev +will cause uninitialised channel devices to be probed. .It -Entering them into /etc/chandev.conf comments are prefixed #. +Entering them into /etc/chandev.conf comments are prefixed with #. .It Or from the boot command line using the 'chandev=' keyword +e.g. chandev=noauto,0x0,0x480d;noauto,0x4810,0xffff +will allow only devno's 0x480e & 0x480f to be autodetected. .El .Bl -item .It -Multiple options can be passed separated by semicolons but no spaces are allowed between parameters. The script /bin/chandev will be called automatically on startup or a machine check of a device as follows. -/bin/chandev . -The chandev layer doesn't open stdin stdout or stderr so it is advisable that you add the following lines to the start of your script. +Multiple options can be passed separated by semicolons but no spaces are allowed between parameters. To be consistent with other hotpluggable architectures the script pointed to /proc/sys/kernel/hotplug (normally /sbin/hotplug) will be called automatically on startup or a machine check of a device as follows. +/sbin/hotplug chandev . +The chandev layer doesn't open stdin stdout or stderr so it is advisable that you add the following lines to the start of your script, here is a sample script which starts devices as they become available. .It #!/bin/bash .It exec >/dev/console 2>&1 0>&1 +.It +# Uncomment line below for debugging. +.It +# echo $* +.It +if [ "$1" = "chandev" ] && [ "$2" = "start" ] +.It +then +.It + shift 2 +.It + while [ "$1" != "" ] && [ "$1" != "machine_check" ] +.It + do +.It + isup=`ifconfig $1 2>/dev/null | grep UP` +.It + if [ "$isup" = "" ] +.It + then +.It + ifup $1 +.It + fi +.It + shift +.It + done +.It +fi +.It +.It +e.g. if tr0 & ctc0 were starting up & eth0 & eth1 devices disappeared & eth2 got a revalidate machine check ( which is normally fully recoverable ) nearly simultainously the parameters would be. +.It +/sbin/hotplug chandev start tr0 ctc0 machine_check eth0 gone gone eth1 gone gone eth2 revalidate good +.It +This can be used for example to call /etc/rc.d/init.d/network start when a device appears & make the ipldelay kernel boot parameter obselete on native machines or recover from bad machine checks where the default machine check handling isn't adequete. The machine checks that can be presented as parameters are good not_operational no_path revalidate device_gone. Normally you wouldn't want to do anything like stop networking when a device disappears as this is hopefully temporary, I just added it to be complete. The chandev layer waits a few seconds for machine checks to settle before running /sbin/hotplug because several machine checks usually happen at once & the forked scripts would possibly race against each other to shutdown & start resources at the same time & behave rather stupidly. .El -e.g. if tr0 & ctc0 were starting up & eth0 & eth1 didn't recover from a gone machine check at the same instant the parameters would be. - - -/bin/chandev start tr0 ctc0 machine_check eth0 gone gone eth1 gone gone -This can be used for example to call /etc/rc.d/init.d/network start when a device appears & make the ipldelay kernel boot parameter obselete on native machines or recover from bad machine checks where the default machine check handling isn't adequete. The machine checks that can be presented as parameters are good not_operational no_path revalidate device_gone. - valid chandev arguments are <> indicate optional parameters, | indicate a choice. .B glossary @@ -77,21 +120,49 @@ .It .Bl -item - .It -.B (ctc|escon|lcs|osad|qeth|claw), -read_devno, write_devno, , , +.B (ctc|escon|lcs|osad|qeth), +read_devno,write_devno, +.It +devif_num of -1 indicates you don't care what device interface number is chosen, omitting it indicates this is a range of devices for which you want to force to be detected as a particular type. +The data_devno field is only valid for qeth devices when not forcing a range of devices. +all parameters after & including memory_usage_in_k can be set optionally if not set they +go to default values. memory_usage_in_k ( 0 the default ) means let the driver choose,checksum_received_ip_pkts & use_hw_stats are set to false +.It +e.g. ctc0,0x7c00,0x7c01 .It -e.g. ctc0,0x7c00,0x7c01,0,0,0 +Tells the channel layer to force ctc0 if detected to use cuu's 7c00 & 7c01 port,port_no is the relative adapter no on lcs, on ctc/escon this field is the ctc/escon protocol number ( default 0 ), don't do checksumming on received ip packets & as ctc doesn't have hardware stats so it ignores this parameter. This can be used for instance to force a device if it presents bad sense data to the IO layer & thus autodetection fails. .It -Tells the channel layer to force ctc0 if detected to use cuu's 7c00 & 7c01 port,port_no is the relative adapter no on lcs, on ctc/escon this field is the ctc/escon protocol number ( normally 0 ), don't do checksumming on received ip packets & as ctc doesn't have hardware stats so it ignores this parameter. +qeth,0x7c00,0x7d00,-1,4096 +All devices between 0x7c00 & 7d00 should be detected as gigabit ethernet, let the driver use 4096k for each instance, don't care what port relative adapter number is chosen, don't checksum received ip packets & use hw stats . +.It +qeth1,0x7c00,0x7c01,0x7c02 +.It +devif_num=1,read=0x7c00,write=0x7c01,data=0x7c02, don't checksum received ip packets & use hw stats. .El .It - +.Bl -item +.B claw devif_num, +read_devno,write_devno<,memory_usage_in_k,checksum_received_ip_pkts,use_hw_stats,> +host_name,adapter_name,api_type +.It +CLAW currently is not autodetected as the host_name,adapter_name & api_type +need to be set up, possibly some convention for setting these automatically +may be contrived in the future & auto detection may be done but currently there isn't any. +The names host_name,adapter_name,api_type may be 8 upto characters in length, +host_name is the name of this host, adapter_name is the name of the adjacent host, +api_type may be name 1 to 8 chars in length API & TCPIP are common values. +The remainder of the parameters are the same as the description for other ctc escon etc. +.It +A typical setup may be +.It +claw0,0xe00,0xe01,linuxa,rs6k,TCPIP +.It +.El .Bl -item .It .B add_parms -,chan_type, +,chan_type,string .It chan_type bitfield .It @@ -99,22 +170,26 @@ .It This is for device driver specific options passed as a string to the driver not dealt with by the channel device layer it can't contain spaces. +low_devno & hi_devno are optional parameters to specify a range. +The channel device layer doesn't concatenate strings if device ranges overlap, +before passing to a device driver. .El .It .Bl -item .It .B del_parms -<,chan_type,exact_match> +<,chan_type,exact_match,lo_devno> .It This deletes some or all device driver specific options not specifying chan_type causes it to delete all the strings. exact_match=1 specifies only to remove driver parms where chan_type is exactly equal exact_match=0 specifies to remove parms where any bit matches chan_type. +lo_devno is an optional parameter the delete to only happen if lo_devno matches a lo_devno in one of the ranges. .El .It .Bl -item .It .B noauto -,- +<,lo_devno,hi_devno> .It Don't probe a range of device numbers for channel devices. .El @@ -128,7 +203,6 @@ .It e.g. a token ring read channel 0x7c00 would have an interface called tr0x7c00 this avoids name collisions on devices. .El -.El .B power user options @@ -168,7 +242,6 @@ .It .B add_model ,chan_type, cu_type, cu_model, dev_type, dev_model, max_port_no, automatic_machine_check_handling - .It Tells the channel layer to probe for the device described, -1 for any of the parameters other than chan_type & automatic_machine_check_handling is a wildcard. Set max_port_no to 0 for non lcs devices. @@ -180,18 +253,33 @@ chan_type bitfield .It ctc=0x1, escon=0x2, lcs=0x4, osad=0x8, qeth=0x10, claw=0x20 - -.It +.El .Bl -item .It .B del_model ,cu_type,cu_model,dev_type,dev_model .It --1 for any parameter is a wildcard, +-1 for any parameter is a wildcard. .El + +.Bl -item .It .B del_all_models +.It +should be obvious. +.El +.Bl -item +.It +.B non_cautious_auto_detect +.It +Tells the channel device layer to attempt to auto detect devices even if their type/model pairs don't unambigously identify the device, e.g. 3088/1F's can either be escon CTC's or channel attached 3172 lcs compatible devices. If the wrong device driver attempts to probe these channels there may be big delays on startup or even a kernel lockup, use this option with caution. +.El +.Bl -item +.It +.B cautious_auto_detect .It + See non_cautious_auto_detect this is the default. +.El .Bl -item .It .B auto_msck @@ -248,6 +336,19 @@ .It .Bl -item .It +.B unregister_probe +.It +unregisters a single probe function or all of them. +.El +.Bl -item +.It +.B unregister_probe_by_chan_type +.It +unregisters all probe functions which match the chan_type bitfield exactly, +useful if you want a configuration to survice a kernel upgrade. +.El +.Bl -item +.It .B read_conf .It Read instructions from /etc/chandev.conf. @@ -259,6 +360,16 @@ .It Don't automatically read /etc/chandev.conf on boot. .El +.Bl -item +.It +.B persist +,chan_type +.It +Force drivers modules to stay loaded even if no device is found, +this is useful for debugging & one wishes to examine debug entries in +/proc/s390dbf/ to find out why a module failed to load. +.El + .It e.g the following sequence of commands should be roughly equivalent to rebooting for channel devices. @@ -290,8 +401,8 @@ .B /proc/chandev .It cat /proc/chandev to see current options chosen. -.Iy -echo >proc/chandev to enter a new command +.It +echo >/proc/chandev to enter a new command .It .B /etc/chandev.conf .It @@ -302,7 +413,7 @@ .B 'chandev=' keyword. .It -.B /bin/chandev +.B /sbin/hotplug .It A user script/executable which is run when devices come online "appear" or go offline "disappear". diff -u --recursive --new-file v2.4.7/linux/Makefile linux/Makefile --- v2.4.7/linux/Makefile Wed Jul 25 17:10:17 2001 +++ linux/Makefile Thu Jul 26 12:25:45 2001 @@ -1,7 +1,7 @@ VERSION = 2 PATCHLEVEL = 4 -SUBLEVEL = 7 -EXTRAVERSION = +SUBLEVEL = 8 +EXTRAVERSION =-pre1 KERNELRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION) diff -u --recursive --new-file v2.4.7/linux/arch/alpha/kernel/entry.S linux/arch/alpha/kernel/entry.S --- v2.4.7/linux/arch/alpha/kernel/entry.S Wed Jul 25 17:10:17 2001 +++ linux/arch/alpha/kernel/entry.S Wed Jul 25 17:11:05 2001 @@ -739,9 +739,12 @@ mov $30,$17 br $1,do_switch_stack mov $30,$18 + subq $30,16,$30 + stq $26,0($30) jsr $26,do_sigsuspend - lda $30,SWITCH_STACK_SIZE($30) - br ret_from_sys_call + ldq $26,0($30) + lda $30,SWITCH_STACK_SIZE+16($30) + ret $31,($26),1 .end sys_sigsuspend .align 3 @@ -750,9 +753,12 @@ mov $30,$18 br $1,do_switch_stack mov $30,$19 + subq $30,16,$30 + stq $26,0($30) jsr $26,do_rt_sigsuspend - lda $30,SWITCH_STACK_SIZE($30) - br ret_from_sys_call + ldq $26,0($30) + lda $30,SWITCH_STACK_SIZE+16($30) + ret $31,($26),1 .end sys_rt_sigsuspend .data diff -u --recursive --new-file v2.4.7/linux/arch/cris/Makefile linux/arch/cris/Makefile --- v2.4.7/linux/arch/cris/Makefile Wed Jul 25 17:10:17 2001 +++ linux/arch/cris/Makefile Thu Jul 26 15:10:06 2001 @@ -1,4 +1,4 @@ -# $Id: Makefile,v 1.19 2001/06/11 12:06:40 bjornw Exp $ +# $Id: Makefile,v 1.20 2001/07/05 10:07:58 jonashg Exp $ # cris/Makefile # # This file is included by the global makefile so that you can add your own @@ -55,7 +55,8 @@ # each others config options SUBDIRS += arch/cris/boot/rescue endif -CORE_FILES += arch/cris/kernel/kernel.o arch/cris/mm/mm.o arch/cris/drivers/drivers.o +CORE_FILES += arch/cris/kernel/kernel.o arch/cris/mm/mm.o +DRIVERS += arch/cris/drivers/drivers.o LIBGCC = $(shell $(CC) $(CFLAGS) -print-file-name=libgcc.a) LIBS := $(TOPDIR)/arch/cris/lib/lib.a $(LIBS) $(TOPDIR)/arch/cris/lib/lib.a $(LIBGCC) diff -u --recursive --new-file v2.4.7/linux/arch/cris/boot/compressed/decompress.ld linux/arch/cris/boot/compressed/decompress.ld --- v2.4.7/linux/arch/cris/boot/compressed/decompress.ld Tue Jul 3 17:08:18 2001 +++ linux/arch/cris/boot/compressed/decompress.ld Thu Jul 26 15:10:06 2001 @@ -13,7 +13,6 @@ _stext = . ; *(.text) *(.rodata) - *(.rodata.*) _etext = . ; } > dram .data : diff -u --recursive --new-file v2.4.7/linux/arch/cris/config.in linux/arch/cris/config.in --- v2.4.7/linux/arch/cris/config.in Wed Jul 25 17:10:17 2001 +++ linux/arch/cris/config.in Thu Jul 26 15:10:06 2001 @@ -49,6 +49,10 @@ int 'DRAM size (dec, in MB)' CONFIG_ETRAX_DRAM_SIZE 8 int 'Buswidth of flash in bytes' CONFIG_ETRAX_FLASH_BUSWIDTH 2 +bool 'Use flash mirroring (for cramfs)' CONFIG_ETRAX_FLASH_MIRRORING_FOR_CRAMFS +if [ "$CONFIG_ETRAX_FLASH_MIRRORING_FOR_CRAMFS" = "y" ]; then + int ' Individual flash chip size (in MB)' CONFIG_ETRAX_FLASH_SIZE 2 +fi choice 'Product LED port' \ "Port-PA-LEDs CONFIG_ETRAX_PA_LEDS \ @@ -61,8 +65,8 @@ int ' First red LED bit' CONFIG_ETRAX_LED1R 3 int ' Second green LED bit' CONFIG_ETRAX_LED2G 4 int ' Second red LED bit' CONFIG_ETRAX_LED2R 5 - int ' Third green LED bit' CONFIG_ETRAX_LED3R 2 - int ' Third red LED bit' CONFIG_ETRAX_LED3G 2 + int ' Third green LED bit' CONFIG_ETRAX_LED3G 2 + int ' Third red LED bit' CONFIG_ETRAX_LED3R 2 fi if [ "$CONFIG_ETRAX_CSP0_LEDS" = "y" ]; then @@ -169,7 +173,7 @@ source drivers/ieee1394/Config.in -source drivers/message/i2o/Config.in +source drivers/i2o/Config.in if [ "$CONFIG_NET" = "y" ]; then mainmenu_option next_comment diff -u --recursive --new-file v2.4.7/linux/arch/cris/cris.ld linux/arch/cris/cris.ld --- v2.4.7/linux/arch/cris/cris.ld Tue Jul 3 17:08:18 2001 +++ linux/arch/cris/cris.ld Thu Jul 26 15:10:06 2001 @@ -24,7 +24,7 @@ *(.fixup) *(.text.__*) *(.rodata) - *(.rodata.*) + *(.rodata.__*) } . = ALIGN(4); /* Exception table */ @@ -56,11 +56,18 @@ ___setup_start = .; .setup.init : { *(.setup.init) } ___setup_end = .; - ___initcall_start = .; - .initcall.init : { *(.initcall.init) } - ___initcall_end = .; + .initcall.init : { + ___initcall_start = .; + *(.initcall.init); + ___initcall_end = .; + + /* We fill to the next page, so we can discard all init + pages without needing to consider what payload might be + appended to the kernel image. */ + FILL (0); + . = ALIGN (8192); + } __vmlinux_end = .; /* last address of the physical file */ - . = ALIGN(8192); ___init_end = .; __data_end = . ; /* Move to _edata ? */ diff -u --recursive --new-file v2.4.7/linux/arch/cris/drivers/eeprom.c linux/arch/cris/drivers/eeprom.c --- v2.4.7/linux/arch/cris/drivers/eeprom.c Wed Jul 25 17:10:17 2001 +++ linux/arch/cris/drivers/eeprom.c Thu Jul 26 15:10:06 2001 @@ -20,6 +20,18 @@ *! in the spin-lock. *! *! $Log: eeprom.c,v $ +*! Revision 1.8 2001/06/15 13:24:29 jonashg +*! * Added verification of pointers from userspace in read and write. +*! * Made busy counter volatile. +*! * Added define for inital write delay. +*! * Removed warnings by using loff_t instead of unsigned long. +*! +*! Revision 1.7 2001/06/14 15:26:54 jonashg +*! Removed test because condition is always true. +*! +*! Revision 1.6 2001/06/14 15:18:20 jonashg +*! Kb -> kB (makes quite a difference if you don't know if you have 2k or 16k). +*! *! Revision 1.5 2001/06/14 14:39:51 jonashg *! Forgot to use name when registering the driver. *! @@ -59,6 +71,7 @@ #include #include #include +#include #include "i2c.h" #define D(x) @@ -69,6 +82,10 @@ #define EEPROM_MAJOR_NR 122 /* use a LOCAL/EXPERIMENTAL major for now */ #define EEPROM_MINOR_NR 0 +/* Empirical sane initial value of the delay, the value will be adapted to + * what the chip needs when using EEPROM_ADAPTIVE_TIMING. + */ +#define INITIAL_WRITEDELAY_US 4000 #define MAX_WRITEDELAY_US 10000 /* 10 ms according to spec for 2KB EEPROM */ /* This one defines how many times to try when eeprom fails. */ @@ -98,7 +115,7 @@ /* this one is to keep the read/write operations atomic */ wait_queue_head_t wait_q; - int busy; + volatile int busy; int retry_cnt_addr; /* Used to keep track of number of retries for adaptive timing adjustments */ int retry_cnt_read; @@ -114,9 +131,8 @@ static int eeprom_address(unsigned long addr); static int read_from_eeprom(char * buf, int count); -static int eeprom_write_buf(unsigned long addr, const char * buf, int count); -static int eeprom_read_buf(unsigned long addr, - char * buf, int count); +static int eeprom_write_buf(loff_t addr, const char * buf, int count); +static int eeprom_read_buf(loff_t addr, char * buf, int count); static void eeprom_disable_write_protect(void); @@ -159,7 +175,7 @@ /* * Note: Most of this probing method was taken from the printserver (5470e) - * codebase. It did not contain a way of finding the 16Kb chips + * codebase. It did not contain a way of finding the 16kB chips * (M24128 or variants). The method used here might not work * for all models. If you encounter problems the easiest way * is probably to define your model within #ifdef's, and hard- @@ -167,7 +183,7 @@ */ eeprom.size = 0; - eeprom.usec_delay_writecycles = 4000;/*MAX_WRITEDELAY_US / EEPROM_RETRIES;*/ + eeprom.usec_delay_writecycles = INITIAL_WRITEDELAY_US; eeprom.usec_delay_step = 128; eeprom.adapt_state = 0; @@ -181,7 +197,7 @@ unsigned char buf_2k_start[16]; /* Im not sure this will work... :) */ - /* assume 2Kb, if failure go for 16Kb */ + /* assume 2kB, if failure go for 16kB */ /* Test with 16kB settings.. */ /* If it's a 2kB EEPROM and we address it outside it's range * it will mirror the address space: @@ -373,17 +389,17 @@ switch(eeprom.size) { case (EEPROM_2KB): - printk("%s: " EETEXT " i2c compatible 2Kb eeprom.\n", eeprom_name); + printk("%s: " EETEXT " i2c compatible 2kB eeprom.\n", eeprom_name); eeprom.sequential_write_pagesize = 16; eeprom.select_cmd = 0xA0; break; case (EEPROM_8KB): - printk("%s: " EETEXT " i2c compatible 8Kb eeprom.\n", eeprom_name); + printk("%s: " EETEXT " i2c compatible 8kB eeprom.\n", eeprom_name); eeprom.sequential_write_pagesize = 16; eeprom.select_cmd = 0x80; break; case (EEPROM_16KB): - printk("%s: " EETEXT " i2c compatible 16Kb eeprom.\n", eeprom_name); + printk("%s: " EETEXT " i2c compatible 16kB eeprom.\n", eeprom_name); eeprom.sequential_write_pagesize = 64; eeprom.select_cmd = 0xA0; break; @@ -463,8 +479,7 @@ /* Reads data from eeprom. */ -static int eeprom_read_buf(unsigned long addr, - char * buf, int count) +static int eeprom_read_buf(loff_t addr, char * buf, int count) { struct file f; @@ -543,7 +558,7 @@ /* Writes data to eeprom. */ -static int eeprom_write_buf(unsigned long addr, const char * buf, int count) +static int eeprom_write_buf(loff_t addr, const char * buf, int count) { struct file f; @@ -561,6 +576,11 @@ int i, written, restart=1; unsigned long p; + if (verify_area(VERIFY_READ, buf, count)) + { + return -EFAULT; + } + while(eeprom.busy) { interruptible_sleep_on(&eeprom.wait_q); @@ -641,11 +661,8 @@ /* To High before */ if (eeprom.usec_delay_step > 1) { - if (eeprom.usec_delay_step > 0) - { - eeprom.usec_delay_step *= 2; - eeprom.usec_delay_step--; - } + eeprom.usec_delay_step *= 2; + eeprom.usec_delay_step--; if (eeprom.usec_delay_writecycles > eeprom.usec_delay_step) { @@ -807,7 +824,12 @@ while( (read < count)) { - buf[read++] = i2c_inbyte(); + if (put_user(i2c_inbyte(), &buf[read++])) + { + i2c_stop(); + + return -EFAULT; + } /* * make sure we don't ack last byte or you will get very strange diff -u --recursive --new-file v2.4.7/linux/arch/cris/drivers/lpslave/e100lpslave.S linux/arch/cris/drivers/lpslave/e100lpslave.S --- v2.4.7/linux/arch/cris/drivers/lpslave/e100lpslave.S Wed Jul 25 17:10:17 2001 +++ linux/arch/cris/drivers/lpslave/e100lpslave.S Thu Jul 26 15:10:06 2001 @@ -1,4 +1,4 @@ - ;; $Id: e100lpslave.S,v 1.2 2001/06/11 12:50:01 olof Exp $ + ;; $Id: e100lpslave.S,v 1.3 2001/06/21 16:55:26 olof Exp $ ;; ;; Etrax100 slave network<->parport forwarder ;; @@ -98,7 +98,7 @@ move.d r0, [R_PAR1_CONFIG] - moveq IO_FIELD(R_PAR1_DELAY, setup, 1), r0 ; setup time of value * 160 + 20 + moveq IO_FIELD(R_PAR1_DELAY, setup, 0), r0 ; setup time of value * 160 + 20 == 20 ns move.d r0, [R_PAR1_DELAY] ;; we got four descriptors, that can be active at the same time: diff -u --recursive --new-file v2.4.7/linux/arch/cris/drivers/lpslave/e100lpslavenet.c linux/arch/cris/drivers/lpslave/e100lpslavenet.c --- v2.4.7/linux/arch/cris/drivers/lpslave/e100lpslavenet.c Wed Jul 25 17:10:17 2001 +++ linux/arch/cris/drivers/lpslave/e100lpslavenet.c Thu Jul 26 15:10:06 2001 @@ -1,4 +1,4 @@ -/* $Id: e100lpslavenet.c,v 1.2 2001/06/11 15:39:52 olof Exp $ +/* $Id: e100lpslavenet.c,v 1.4 2001/06/21 16:55:26 olof Exp $ * * e100lpslavenet.c: A network driver for the ETRAX 100LX slave controller. * @@ -7,6 +7,12 @@ * The outline of this driver comes from skeleton.c. * * $Log: e100lpslavenet.c,v $ + * Revision 1.4 2001/06/21 16:55:26 olof + * Minimized par port setup time to gain bandwidth + * + * Revision 1.3 2001/06/21 15:49:02 olof + * Removed setting of default MAC address + * * Revision 1.2 2001/06/11 15:39:52 olof * Clean up and sync with ethernet.c rev 1.16. Increased reset time of slave. * @@ -198,10 +204,6 @@ dev->get_stats = e100_get_stats; dev->set_multicast_list = set_multicast_list; dev->set_mac_address = e100_set_mac_address; - - /* set the default MAC address */ - - e100_set_mac_address(dev, &default_mac); /* Initialise the list of Etrax DMA-descriptors */ @@ -385,8 +387,8 @@ /* We want ECP forward mode since PAR1 is TX */ IO_STATE(R_PAR1_CONFIG, mode, ecp_fwd); - /* Setup time of value * 160 + 20 ns == 180 ns below */ - *R_PAR1_DELAY = IO_FIELD(R_PAR1_DELAY, setup, 1); + /* Setup time of value * 160 + 20 ns == 20 ns below */ + *R_PAR1_DELAY = IO_FIELD(R_PAR1_DELAY, setup, 0); *R_PAR1_CTRL = 0; @@ -944,7 +946,6 @@ TxDescList[1].ctrl = d_eol | d_int; TxDescList[1].buf = virt_to_phys(code); - /*TxDescList[1].buf = code;*/ TxDescList[1].next = 0; /* setup the dma channel and start it */ diff -u --recursive --new-file v2.4.7/linux/arch/cris/drivers/parport.c linux/arch/cris/drivers/parport.c --- v2.4.7/linux/arch/cris/drivers/parport.c Wed Jul 25 17:10:17 2001 +++ linux/arch/cris/drivers/parport.c Thu Jul 26 15:10:06 2001 @@ -1,4 +1,4 @@ -/* $Id: parport.c,v 1.5 2001/05/09 12:38:42 johana Exp $ +/* $Id: parport.c,v 1.7 2001/06/25 16:17:30 jonashg Exp $ * * Elinux parallel port driver * NOTE! @@ -49,7 +49,7 @@ * Par0 in : DMA3 * Par1 out : DMA4 * Par1 in : DMA5 - * NOTE! par0 is hared with ser2 and par1 is shared with ser3 regarding + * NOTE! par0 is shared with ser2 and par1 is shared with ser3 regarding * DMA and DMA irq */ @@ -80,8 +80,6 @@ volatile char *iclrintradr; /* adr to R_DMA_CHx_CLR_INTR, input */ volatile u32 *ifirstadr; /* adr to R_DMA_CHx_FIRST, input */ volatile char *icmdadr; /* adr to R_DMA_CHx_CMD, input */ - const volatile u8 *istatusadr; /* adr to R_DMA_CHx_STATUS, input */ - volatile u32 *ihwswadr; /* adr to R_DMA_CHx_HWSW, input */ /* Non DMA interrupt stuff */ unsigned long int_irq; /* R_VECT_MASK_RD */ @@ -97,15 +95,6 @@ /* ----- end of fields initialised in port_table[] below ----- */ - // struct etrax_dma_descr tr_descr; - // unsigned char tr_buf[LP_BUFFER_SIZE]; - // const unsigned char *tr_buf_curr; /* current char sent */ - // const unsigned char *tr_buf_last; /* last char in buf */ - - // int fifo_magic; /* fifo amount - bytes left in dma buffer */ - // unsigned char fifo_didmagic; /* a fifo eop has been forced */ - // volatile int tr_running; /* 1 if output is running */ - struct parport *port; /* Shadow registers */ @@ -132,8 +121,6 @@ R_DMA_CH3_CLR_INTR, R_DMA_CH3_FIRST, R_DMA_CH3_CMD, - R_DMA_CH3_STATUS, - R_DMA_CH3_HWSW, /* Non DMA interrupt stuff */ IO_BITNR(R_VECT_MASK_RD, par0), R_IRQ_MASK0_RD, @@ -161,8 +148,6 @@ R_DMA_CH5_CLR_INTR, R_DMA_CH5_FIRST, R_DMA_CH5_CMD, - R_DMA_CH5_STATUS, - R_DMA_CH5_HWSW, /* Non DMA interrupt stuff */ IO_BITNR(R_VECT_MASK_RD, par1), R_IRQ_MASK1_RD, @@ -418,7 +403,7 @@ /* ----------- Initialisation code --------------------------------- */ -static void +static void __init parport_etrax_show_parallel_version(void) { printk("ETRAX 100LX parallel port driver v1.0, (c) 2001 Axis Communications AB\n"); @@ -436,15 +421,11 @@ #define PAR1_USE_DMA 0 #endif -static void +static void __init parport_etrax_init_registers(void) { struct etrax100par_struct *info; int i; - - /* The different times below will be (value*160 + 20) ns, */ - /* i.e. 20ns-4.98us. E.g. if setup is set to 00110 (0x6), */ - /* the setup time will be (6*160+20) = 980ns. */ for (i = 0, info = port_table; i < 2; i++, info++) { #ifndef CONFIG_ETRAX_PARALLEL_PORT0 diff -u --recursive --new-file v2.4.7/linux/arch/cris/kernel/Makefile linux/arch/cris/kernel/Makefile --- v2.4.7/linux/arch/cris/kernel/Makefile Wed Jul 25 17:10:17 2001 +++ linux/arch/cris/kernel/Makefile Thu Jul 26 15:10:06 2001 @@ -1,4 +1,4 @@ -# $Id: Makefile,v 1.5 2001/05/15 05:10:00 hp Exp $ +# $Id: Makefile,v 1.7 2001/07/05 01:11:48 hp Exp $ # # Makefile for the linux kernel. # @@ -8,8 +8,10 @@ # # Note 2! The CFLAGS definitions are now in the main makefile... +# These assembly files can't be assembld with -traditional, so we +# need another build rule than the one in the toplevel Makefile. .S.o: - $(CC) $(AFLAGS) -traditional -c $< -o $*.o + $(CC) $(AFLAGS) -c $< -o $*.o all: kernel.o head.o @@ -20,6 +22,7 @@ obj-$(CONFIG_ETRAX_KGDB) += kgdb.o +# This dependency isn't caught by mkdep. See entry.S. entry.o: entryoffsets.s entryoffsets.s: entryoffsets.c diff -u --recursive --new-file v2.4.7/linux/arch/cris/kernel/entry.S linux/arch/cris/kernel/entry.S --- v2.4.7/linux/arch/cris/kernel/entry.S Wed Jul 25 17:10:17 2001 +++ linux/arch/cris/kernel/entry.S Thu Jul 26 15:10:06 2001 @@ -1,4 +1,4 @@ -/* $Id: entry.S,v 1.27 2001/05/29 11:25:27 markusl Exp $ +/* $Id: entry.S,v 1.31 2001/07/25 16:07:42 bjornw Exp $ * * linux/arch/cris/entry.S * @@ -7,6 +7,36 @@ * Authors: Bjorn Wesen (bjornw@axis.com) * * $Log: entry.S,v $ + * Revision 1.31 2001/07/25 16:07:42 bjornw + * softirq_active/mask -> softirq_pending only + * + * Revision 1.30 2001/07/05 01:03:32 hp + * - include asm/errno.h to get ENOSYS. + * - Use ENOSYS, not local constant LENOSYS; tweak comments. + * - Explain why .include, not #include is used. + * - Make oops-register-dump if watchdog bits and it's not expected. + * - Don't jsr, use jump _hard_reset_now, and skip spurious nop. + * - Use correct section attribute for section .rodata. + * - Adjust sys_ni_syscall fill number. + * + * Revision 1.29 2001/06/25 14:07:00 hp + * Fix review comment. + * * head.S: Use IO_STATE, IO_FIELD and IO_MASK constructs instead of + * magic numbers. Add comment that -traditional must not be used. + * * entry.S (SYMBOL_NAME): Change redefinition to use ## concatenation. + * Correct and update comment. + * * Makefile (.S.o): Don't use -traditional. Add comment why the + * toplevel rule can't be used (now that there's a reason). + * + * Revision 1.28 2001/06/21 02:00:40 hp + * * entry.S: Include asm/unistd.h. + * (_sys_call_table): Use section .rodata, not .data. + * (_kernel_thread): Move from... + * * process.c: ... here. + * * entryoffsets.c (VAL): Break out from... + * (OF): Use VAL. + * (LCLONE_VM): New asmified value from CLONE_VM. + * * Revision 1.27 2001/05/29 11:25:27 markusl * In case of "spurious_interrupt", do hard_reset instead of hanging system in a loop... * @@ -130,7 +160,9 @@ #include #include #include +#include #include +#include ;; functions exported from this file @@ -151,11 +183,9 @@ .globl _sys_call_table - ;; syscall error codes - -LENOSYS = 38 - - ;; Get offsets into various structs. + ;; Get values and offsets into various structs. The file isn't + ;; suitable for consumption by the preprocessor, so don't use + ;; #include. .include "entryoffsets.s" ;; process bits for ptrace. FIXME: Should be in a header file. @@ -227,7 +257,7 @@ push r10 ; push orig_r10 clear.d [sp=sp-4] ; frametype == 0, normal stackframe - movs.w -LENOSYS,r0 + movs.w -ENOSYS,r0 move.d r0,[sp+LR10] ; put the default return value in r10 in the frame ;; check if this process is syscall-traced @@ -271,9 +301,7 @@ ;; check if any bottom halves need service - move.d _irq_stat,r10 - move.d [r10+],r0 ; softirq_active - and.d [r10],r0 ; softirq_mask + test.d [_irq_stat] ; softirq_pending bne handle_softirq nop @@ -320,8 +348,8 @@ tracesys: ;; this first invocation of syscall_trace _requires_ that - ;; LR10 in the frame contains -LENOSYS (as is set in the beginning - ;; of system_call + ;; LR10 in the frame contains -ENOSYS (as is set in the beginning + ;; of system_call). jsr _syscall_trace @@ -333,7 +361,7 @@ ;; check for sanity in the requested syscall number move.d [sp+LR9], r9 - movs.w -LENOSYS, r10 + movs.w -ENOSYS, r10 cmpu.w NR_syscalls,r9 bcc 1f lslq 2,r9 ; multiply by 4, in the delay slot @@ -344,7 +372,7 @@ ;; restore r10, r11, r12, r13, mof and srp into the needed registers - move.d [sp+LORIG_R10], r10 ; LR10 is already filled with -LENOSYS + move.d [sp+LORIG_R10], r10 ; LR10 is already filled with -ENOSYS. move.d [sp+LR11], r11 move.d [sp+LR12], r12 move.d [sp+LR13], r13 @@ -484,10 +512,72 @@ #endif _IRQ1_interrupt: -_spurious_interrupt: + +#if defined(CONFIG_ETRAX_WATCHDOG) && !defined(CONFIG_SVINTO_SIM) +;; If we receive a watchdog interrupt while it is not expected, then set +;; up a canonical frame and dump register contents before dying. + + ;; this prologue MUST match the one in irq.h and the struct in ptregs.h!!! + move brp,[sp=sp-16] ; instruction pointer and room for a fake SBFS frame + push srp + push dccr + push mof di - jsr _hard_reset_now + subq 14*4,sp + movem r13,[sp] + push r10 ; push orig_r10 + clear.d [sp=sp-4] ; frametype == 0, normal frame + +;; We don't check that we actually were bit by the watchdog as opposed to +;; an external NMI, since there is currently no handler for external NMI. + +;; We'll see this in ksymoops dumps. +Watchdog_bite: + +;; We need to extend the 3.3ms after the NMI at watchdog bite, so we have +;; time for an oops-dump over a 115k2 serial wire. Another 100ms should do. + +;; Change the watchdog key to an arbitrary 3-bit value and restart the +;; watchdog. +#define WD_INIT 2 + moveq IO_FIELD (R_WATCHDOG, key, WD_INIT), r10 + move.d R_WATCHDOG, r11 + + move.d r10,[r11] + moveq IO_FIELD (R_WATCHDOG, key, \ + IO_EXTRACT (R_WATCHDOG, key, \ + IO_MASK (R_WATCHDOG, key)) \ + ^ WD_INIT) \ + | IO_STATE (R_WATCHDOG, enable, start),r10 + move.d r10,[r11] + +;; Note that we don't do "setf m" here (or after two necessary NOPs), +;; since *not* doing that saves us from re-entrancy checks. We don't want +;; to get here again due to possible subsequent NMIs; we want the watchdog +;; to reset us. + + move.d watchdogmsg,r10 + jsr _printk + + move.d sp,r10 + jsr _show_registers + +;; This nop is here so we see the "Watchdog_bite" label in ksymoops dumps +;; rather than "_spurious_interrupt". nop +;; At this point we drop down into _spurious_interrupt, which will do a +;; hard reset. + + .section .rodata,"a" +watchdogmsg: + .ascii "Oops: bitten by watchdog\n\0" + .previous + +#endif /* CONFIG_ETRAX_WATCHDOG and not CONFIG_SVINTO_SIM */ + +_spurious_interrupt: + di + jump _hard_reset_now ;; this handles the case when multiple interrupts arrive at the same time ;; we jump to the first set interrupt bit in a priority fashion @@ -579,14 +669,80 @@ _hw_bp_trig_ptr: .dword _hw_bp_trigs -/* Because we compile this file with -traditional, we need to redefine - token-concatenation to the traditional trick, using an empty comment. - Normally (in other files, with ISO C as in gcc default) this is done - with the ## preprocessor operator. */ +/* + * This is the mechanism for creating a new kernel thread. + * + * NOTE! Only a kernel-only process (i.e. the swapper or direct descendants + * who haven't done an "execve()") should use this: it will work within + * a system call from a "real" process, but the process memory space will + * not be free'd until both the parent and the child have exited. + * + * This *can* be done in C with an single-asm-wrapped-in-a-function, but you + * get more or less gross code. The safer you make the asm-constraints, + * the grosser the code, at least with the gcc version in cris-dist-1.13. + */ + +/* int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags) */ +/* r10 r11 r12 */ + + .text + .global _kernel_thread +_kernel_thread: + + /* Save ARG for later. */ + move.d r11,r13 + + /* r11 is argument 2 to clone, the flags */ + move.d r12,r11 + or.w LCLONE_VM,r11 + + /* Save FN for later. */ + move.d r10,r12 + + /* r9 contains syscall number, to sys_clone */ + movu.w __NR_clone,r9 + + /* r10 is argument 1 to clone */ + clear.d r10 + + /* call sys_clone, this will fork */ + break 13 + + /* parent or child? child returns 0 here. */ + test.d r10 + + /* jump if parent */ + bne 1f + nop /* delay slot */ + + /* set argument to function to call */ + move.d r13,r10 + + /* call specified function */ + jsr r12 + /* If we ever return from the function, something bad has happened. */ + + /* r9 is sys_exit syscall number */ + movu.w __NR_exit,r9 + + /* Give a really bad exit-value */ + moveq -1,r10 + + /* call sys_exit, killing the child */ + break 13 +1: + ret + nop /* delay slot */ + + +/* The file include/linux/linkage.h is wrong for compiling the + Linux/CRIS kernel. We currently have C symbols in the kernel (only + the kernel) prefixed with _, hence, we need to redefine SYMBOL_NAME. */ #undef SYMBOL_NAME -#define SYMBOL_NAME(X) _/**/X - +#define SYMBOL_NAME(X) _##X + + .section .rodata,"a" _sys_call_table: .long SYMBOL_NAME(sys_ni_syscall) /* 0 - old "setup()" system call*/ .long SYMBOL_NAME(sys_exit) @@ -819,7 +975,7 @@ * been shrunk every time we add a new system call. */ - .rept NR_syscalls-221 + .rept NR_syscalls-222 .long SYMBOL_NAME(sys_ni_syscall) .endr diff -u --recursive --new-file v2.4.7/linux/arch/cris/kernel/entryoffsets.c linux/arch/cris/kernel/entryoffsets.c --- v2.4.7/linux/arch/cris/kernel/entryoffsets.c Wed Jul 25 17:10:17 2001 +++ linux/arch/cris/kernel/entryoffsets.c Thu Jul 26 15:10:06 2001 @@ -18,16 +18,20 @@ #include /* Exclude everything except the assembly by wrapping it in ".if 0". */ -#undef OF -#define OF(NAME, TYPE, MEMBER) \ +#undef VAL +#define VAL(NAME, VALUE) \ void NAME ## _fun (void) \ { \ __asm__ (".endif \n" \ #NAME " = %0 \n" \ ".if 0\n" \ - : : "i" (offsetof (TYPE, MEMBER))); \ + : : "i" (VALUE)); \ } +#undef OF +#define OF(NAME, TYPE, MEMBER) \ + VAL (NAME, offsetof (TYPE, MEMBER)) + /* task_struct offsets. */ OF (LTASK_SIGPENDING, struct task_struct, sigpending) OF (LTASK_NEEDRESCHED, struct task_struct, need_resched) @@ -50,5 +54,8 @@ OF (LTHREAD_KSP, struct thread_struct, ksp) OF (LTHREAD_USP, struct thread_struct, usp) OF (LTHREAD_DCCR, struct thread_struct, dccr) + +/* linux/sched.h values - doesn't have an #ifdef __ASSEMBLY__ for these. */ +VAL (LCLONE_VM, CLONE_VM) __asm__ (".endif"); diff -u --recursive --new-file v2.4.7/linux/arch/cris/kernel/head.S linux/arch/cris/kernel/head.S --- v2.4.7/linux/arch/cris/kernel/head.S Wed Jul 25 17:10:17 2001 +++ linux/arch/cris/kernel/head.S Thu Jul 26 15:10:06 2001 @@ -1,4 +1,4 @@ -/* $Id: head.S,v 1.34 2001/05/15 07:08:14 hp Exp $ +/* $Id: head.S,v 1.36 2001/06/29 12:39:31 pkj Exp $ * * Head of the kernel - alter with care * @@ -7,6 +7,19 @@ * Authors: Bjorn Wesen (bjornw@axis.com) * * $Log: head.S,v $ + * Revision 1.36 2001/06/29 12:39:31 pkj + * Added support for mirroring the first flash to just below the + * second one, to make them look consecutive to cramfs. + * + * Revision 1.35 2001/06/25 14:07:00 hp + * Fix review comment. + * * head.S: Use IO_STATE, IO_FIELD and IO_MASK constructs instead of + * magic numbers. Add comment that -traditional must not be used. + * * entry.S (SYMBOL_NAME): Change redefinition to use ## concatenation. + * Correct and update comment. + * * Makefile (.S.o): Don't use -traditional. Add comment why the + * toplevel rule can't be used (now that there's a reason). + * * Revision 1.34 2001/05/15 07:08:14 hp * Tweak "notice" to reflect that both r8 r9 are used * @@ -122,6 +135,8 @@ #include #define ASSEMBLER_MACROS_ONLY +/* The IO_* macros use the ## token concatenation operator, so + -traditional must not be used when assembling this file. */ #include #define CRAMFS_MAGIC 0x28cd3d45 @@ -165,22 +180,72 @@ ;; 1G per process with CONFIG_CRIS_LOW_MAP. #ifdef CONFIG_CRIS_LOW_MAP - move.d 0x0004b098, r0 ; kseg mappings, temporary map of 0xc0->0x40 + ; kseg mappings, temporary map of 0xc0->0x40 + move.d IO_FIELD (R_MMU_KBASE_HI, base_c, 4) \ + | IO_FIELD (R_MMU_KBASE_HI, base_b, 0xb) \ + | IO_FIELD (R_MMU_KBASE_HI, base_9, 9) \ + | IO_FIELD (R_MMU_KBASE_HI, base_8, 8), r0 move.d r0, [R_MMU_KBASE_HI] - move.d 0x04040000, r0 ; temporary map of 0x40->0x40 and 0x00->0x00 + ; temporary map of 0x40->0x40 and 0x60->0x40 + move.d IO_FIELD (R_MMU_KBASE_LO, base_6, 4) \ + | IO_FIELD (R_MMU_KBASE_LO, base_4, 4), r0 move.d r0, [R_MMU_KBASE_LO] - move.d 0x80075c71, r0 ; mmu enable, segs c,b,9,8,6,5,4,0 segment mapped + ; mmu enable, segs e,c,b,a,6,5,4,0 segment mapped + move.d IO_STATE (R_MMU_CONFIG, mmu_enable, enable) \ + | IO_STATE (R_MMU_CONFIG, inv_excp, enable) \ + | IO_STATE (R_MMU_CONFIG, acc_excp, enable) \ + | IO_STATE (R_MMU_CONFIG, we_excp, enable) \ + | IO_STATE (R_MMU_CONFIG, seg_f, page) \ + | IO_STATE (R_MMU_CONFIG, seg_e, seg) \ + | IO_STATE (R_MMU_CONFIG, seg_d, page) \ + | IO_STATE (R_MMU_CONFIG, seg_c, seg) \ + | IO_STATE (R_MMU_CONFIG, seg_b, seg) \ + | IO_STATE (R_MMU_CONFIG, seg_a, seg) \ + | IO_STATE (R_MMU_CONFIG, seg_9, page) \ + | IO_STATE (R_MMU_CONFIG, seg_8, page) \ + | IO_STATE (R_MMU_CONFIG, seg_7, page) \ + | IO_STATE (R_MMU_CONFIG, seg_6, seg) \ + | IO_STATE (R_MMU_CONFIG, seg_5, seg) \ + | IO_STATE (R_MMU_CONFIG, seg_4, seg) \ + | IO_STATE (R_MMU_CONFIG, seg_3, page) \ + | IO_STATE (R_MMU_CONFIG, seg_2, page) \ + | IO_STATE (R_MMU_CONFIG, seg_1, page) \ + | IO_STATE (R_MMU_CONFIG, seg_0, seg), r0 move.d r0, [R_MMU_CONFIG] #else - move.d 0x0804b000, r0 ; kseg mappings + ; kseg mappings + move.d IO_FIELD (R_MMU_KBASE_HI, base_e, 8) \ + | IO_FIELD (R_MMU_KBASE_HI, base_c, 4) \ + | IO_FIELD (R_MMU_KBASE_HI, base_b, 0xb), r0 move.d r0, [R_MMU_KBASE_HI] - move.d 0x00040000, r0 ; temporary map of 0x40->0x40 and 0x00->0x00 + ; temporary map of 0x40->0x40 and 0x00->0x00 + move.d IO_FIELD (R_MMU_KBASE_LO, base_4, 4), r0 move.d r0, [R_MMU_KBASE_LO] - move.d 0x8007d811, r0 ; mmu enable, segs f,e,c,b,4,0 segment mapped + ; mmu enable, segs f,e,c,b,4,0 segment mapped + move.d IO_STATE (R_MMU_CONFIG, mmu_enable, enable) \ + | IO_STATE (R_MMU_CONFIG, inv_excp, enable) \ + | IO_STATE (R_MMU_CONFIG, acc_excp, enable) \ + | IO_STATE (R_MMU_CONFIG, we_excp, enable) \ + | IO_STATE (R_MMU_CONFIG, seg_f, seg) \ + | IO_STATE (R_MMU_CONFIG, seg_e, seg) \ + | IO_STATE (R_MMU_CONFIG, seg_d, page) \ + | IO_STATE (R_MMU_CONFIG, seg_c, seg) \ + | IO_STATE (R_MMU_CONFIG, seg_b, seg) \ + | IO_STATE (R_MMU_CONFIG, seg_a, page) \ + | IO_STATE (R_MMU_CONFIG, seg_9, page) \ + | IO_STATE (R_MMU_CONFIG, seg_8, page) \ + | IO_STATE (R_MMU_CONFIG, seg_7, page) \ + | IO_STATE (R_MMU_CONFIG, seg_6, page) \ + | IO_STATE (R_MMU_CONFIG, seg_5, page) \ + | IO_STATE (R_MMU_CONFIG, seg_4, seg) \ + | IO_STATE (R_MMU_CONFIG, seg_3, page) \ + | IO_STATE (R_MMU_CONFIG, seg_2, page) \ + | IO_STATE (R_MMU_CONFIG, seg_1, page) \ + | IO_STATE (R_MMU_CONFIG, seg_0, seg), r0 move.d r0, [R_MMU_CONFIG] #endif @@ -309,6 +374,9 @@ #else add.d 0xf0000000, r9 ; add flash start in virtual memory (cached) #endif +#ifdef CONFIG_ETRAX_FLASH_MIRRORING_FOR_CRAMFS + add.d MEM_CSE1_START-CONFIG_ETRAX_FLASH_SIZE*0x100000, r9 ; move flash start to upper mirror +#endif move.d r9, [_romfs_start] moveq 1, r0 @@ -406,26 +474,34 @@ moveq 0,r0 move.d r0,[R_EXT_DMA_0_ADDR] - move.d 0x860000,r0 ; cnt enable, word size, output, stop, size 0 + ; cnt enable, word size, output, stop, size 0 + move.d IO_STATE (R_EXT_DMA_0_CMD, cnt, enable) \ + | IO_STATE (R_EXT_DMA_0_CMD, rqpol, ahigh) \ + | IO_STATE (R_EXT_DMA_0_CMD, apol, ahigh) \ + | IO_STATE (R_EXT_DMA_0_CMD, rq_ack, burst) \ + | IO_STATE (R_EXT_DMA_0_CMD, wid, word) \ + | IO_STATE (R_EXT_DMA_0_CMD, dir, output) \ + | IO_STATE (R_EXT_DMA_0_CMD, run, stop) \ + | IO_FIELD (R_EXT_DMA_0_CMD, trf_count, 0),r0 move.d r0,[R_EXT_DMA_0_CMD] ;; reset dma4 and wait for completion - moveq 4,r0 + moveq IO_STATE (R_DMA_CH4_CMD, cmd, reset),r0 move.b r0,[R_DMA_CH4_CMD] w4u: move.b [R_DMA_CH4_CMD],r0 - and.b 7,r0 - cmp.b 4,r0 + and.b IO_MASK (R_DMA_CH4_CMD, cmd),r0 + cmp.b IO_STATE (R_DMA_CH4_CMD, cmd, reset),r0 beq w4u nop ;; reset dma5 and wait for completion - moveq 4,r0 + moveq IO_STATE (R_DMA_CH5_CMD, cmd, reset),r0 move.b r0,[R_DMA_CH5_CMD] w5u: move.b [R_DMA_CH5_CMD],r0 - and.b 7,r0 - cmp.b 4,r0 + and.b IO_MASK (R_DMA_CH5_CMD, cmd),r0 + cmp.b IO_STATE (R_DMA_CH5_CMD, cmd, reset),r0 beq w5u nop #endif @@ -434,42 +510,66 @@ moveq 0,r0 #if !defined(CONFIG_ETRAX_KGDB) && !defined(CONFIG_DMA_MEMCPY) - or.d 0x140000,r0 ; DMA channels 6 and 7 to ser0, kgdb doesnt want DMA + ; DMA channels 6 and 7 to ser0, kgdb doesnt want DMA + or.d IO_STATE (R_GEN_CONFIG, dma7, serial0) \ + | IO_STATE (R_GEN_CONFIG, dma6, serial0),r0 #endif #if !defined(CONFIG_ETRAX_KGDB) || !defined(CONFIG_ETRAX_DEBUG_PORT1) - or.d 0xc00000,r0 ; DMA channels 8 and 9 to ser1, kgdb doesnt want DMA + or.d IO_STATE (R_GEN_CONFIG, dma9, serial1) \ + | IO_STATE (R_GEN_CONFIG, dma8, serial1),r0 #endif #ifdef CONFIG_DMA_MEMCPY - or.d 0x003c0000,r0 ; 6/7 memory-memory DMA + ; 6/7 memory-memory DMA + or.d IO_STATE (R_GEN_CONFIG, dma7, intdma6) \ + | IO_STATE (R_GEN_CONFIG, dma6, intdma7),r0 #endif #ifdef CONFIG_ETRAX_SERIAL_PORT2 - or.d 0x2808,r0 ; DMA channels 2 and 3 to serport 2, port 2 enabled + ; DMA channels 2 and 3 to serport 2, port 2 enabled + or.d IO_STATE (R_GEN_CONFIG, dma3, serial2) \ + | IO_STATE (R_GEN_CONFIG, dma2, serial2) \ + | IO_STATE (R_GEN_CONFIG, ser2, select),r0 #endif #if defined(CONFIG_ETRAX_SERIAL_PORT3) || defined(CONFIG_ETRAX_SYNCHRONOUS_SERIAL_PORT1) - or.d 0x28100,r0 ; DMA channels 4 and 5 to serport 3, port 3 enabled + ; DMA channels 4 and 5 to serport 3, port 3 enabled + or.d IO_STATE (R_GEN_CONFIG, dma5, serial3) \ + | IO_STATE (R_GEN_CONFIG, dma4, serial3) \ + | IO_STATE (R_GEN_CONFIG, ser3, select),r0 #endif #if defined(CONFIG_ETRAX_PARALLEL_PORT0) || defined(CONFIG_ETRAX_ETHERNET_LPSLAVE) - or.w 0x4,r0 ; parport 0 enabled using DMA 2/3 + ; parport 0 enabled using DMA 2/3 + or.w IO_STATE (R_GEN_CONFIG, par0, select),r0 #endif #if defined(CONFIG_ETRAX_PARALLEL_PORT1) || defined(CONFIG_ETRAX_ETHERNET_LPSLAVE) - or.w 0x80,r0 ; parport 1 enabled using DMA 4/5 + ; parport 1 enabled using DMA 4/5 + or.w IO_STATE (R_GEN_CONFIG, par1, select),r0 #endif #ifdef CONFIG_ETRAX_IDE - or.d 0x3c02,r0 ; DMA channels 2 and 3 to ATA, ATA enabled + ; DMA channels 2 and 3 to ATA, ATA enabled + or.d IO_STATE (R_GEN_CONFIG, dma3, ata) \ + | IO_STATE (R_GEN_CONFIG, dma2, ata) \ + | IO_STATE (R_GEN_CONFIG, ata, select),r0 #endif #ifdef CONFIG_ETRAX_USB_HOST_PORT1 - or.d 0x20000000,r0 ; Set the USB port 1 enable bit + ; Set the USB port 1 enable bit + or.d IO_STATE (R_GEN_CONFIG, usb1, select),r0 #endif #ifdef CONFIG_ETRAX_USB_HOST_PORT2 - or.d 0x40000000,r0 ; Set the USB port 2 enable bit + ; Set the USB port 2 enable bit + or.d IO_STATE (R_GEN_CONFIG, usb2, select),r0 #endif #ifdef CONFIG_ETRAX_USB_HOST - and.d 0xff3fffff,r0 ; Connect DMA channels 8 and 9 to USB + ; Connect DMA channels 8 and 9 to USB + and.d (~(IO_MASK (R_GEN_CONFIG, dma9) \ + | IO_MASK (R_GEN_CONFIG, dma8))) \ + | IO_STATE (R_GEN_CONFIG, dma9, usb) \ + | IO_STATE (R_GEN_CONFIG, dma8, usb),r0 #endif #ifdef CONFIG_JULIETTE - or.d 0x3c000,r0 ; DMA channels 4 and 5 to EXTDMA0, for Juliette + ; DMA channels 4 and 5 to EXTDMA0, for Juliette + or.d IO_STATE (R_GEN_CONFIG, dma5, extdma0) \ + | IO_STATE (R_GEN_CONFIG, dma4, extdma0),r0 #endif move.d r0,[_genconfig_shadow] ; init a shadow register of R_GEN_CONFIG @@ -492,17 +592,17 @@ nop #endif - moveq 4,r0 + moveq IO_STATE (R_DMA_CH8_CMD, cmd, reset),r0 move.b r0,[R_DMA_CH8_CMD] ; reset (ser1 dma out) move.b r0,[R_DMA_CH9_CMD] ; reset (ser1 dma in) w81: move.b [R_DMA_CH8_CMD],r0 ; wait for reset cycle to finish - and.b 7,r0 - cmp.b 4,r0 + and.b IO_MASK (R_DMA_CH8_CMD, cmd),r0 + cmp.b IO_STATE (R_DMA_CH8_CMD, cmd, reset),r0 beq w81 nop w91: move.b [R_DMA_CH9_CMD],r0 ; wait for reset cycle to finish - and.b 7,r0 - cmp.b 4,r0 + and.b IO_MASK (R_DMA_CH9_CMD, cmd),r0 + cmp.b IO_STATE (R_DMA_CH9_CMD, cmd, reset),r0 beq w91 nop @@ -535,46 +635,106 @@ ;; setup the serial port 0 at 115200 baud for debug purposes - moveq 0,r0 + moveq IO_STATE (R_SERIAL0_XOFF, tx_stop, enable) \ + | IO_STATE (R_SERIAL0_XOFF, auto_xoff, disable) \ + | IO_FIELD (R_SERIAL0_XOFF, xoff_char, 0),r0 move.d r0,[R_SERIAL0_XOFF] - move.b 0x99,r0 - move.b r0,[R_SERIAL0_BAUD] ; 115.2kbaud for both transmit and receive - - move.b 0x40,r0 ; rec enable + ; 115.2kbaud for both transmit and receive + move.b IO_STATE (R_SERIAL0_BAUD, tr_baud, c115k2Hz) \ + | IO_STATE (R_SERIAL0_BAUD, rec_baud, c115k2Hz),r0 + move.b r0,[R_SERIAL0_BAUD] + + ; Set up and enable the serial0 receiver. + move.b IO_STATE (R_SERIAL0_REC_CTRL, dma_err, stop) \ + | IO_STATE (R_SERIAL0_REC_CTRL, rec_enable, enable) \ + | IO_STATE (R_SERIAL0_REC_CTRL, rts_, active) \ + | IO_STATE (R_SERIAL0_REC_CTRL, sampling, middle) \ + | IO_STATE (R_SERIAL0_REC_CTRL, rec_stick_par, normal) \ + | IO_STATE (R_SERIAL0_REC_CTRL, rec_par, even) \ + | IO_STATE (R_SERIAL0_REC_CTRL, rec_par_en, disable) \ + | IO_STATE (R_SERIAL0_REC_CTRL, rec_bitnr, rec_8bit),r0 move.b r0,[R_SERIAL0_REC_CTRL] - move.b 0x40,r0 ; tr enable + ; Set up and enable the serial0 transmitter. + move.b IO_FIELD (R_SERIAL0_TR_CTRL, txd, 0) \ + | IO_STATE (R_SERIAL0_TR_CTRL, tr_enable, enable) \ + | IO_STATE (R_SERIAL0_TR_CTRL, auto_cts, disabled) \ + | IO_STATE (R_SERIAL0_TR_CTRL, stop_bits, one_bit) \ + | IO_STATE (R_SERIAL0_TR_CTRL, tr_stick_par, normal) \ + | IO_STATE (R_SERIAL0_TR_CTRL, tr_par, even) \ + | IO_STATE (R_SERIAL0_TR_CTRL, tr_par_en, disable) \ + | IO_STATE (R_SERIAL0_TR_CTRL, tr_bitnr, tr_8bit),r0 move.b r0,[R_SERIAL0_TR_CTRL] ;; setup the serial port 1 at 115200 baud for debug purposes - moveq 0,r0 + moveq IO_STATE (R_SERIAL1_XOFF, tx_stop, enable) \ + | IO_STATE (R_SERIAL1_XOFF, auto_xoff, disable) \ + | IO_FIELD (R_SERIAL1_XOFF, xoff_char, 0),r0 move.d r0,[R_SERIAL1_XOFF] - move.b 0x99,r0 - move.b r0,[R_SERIAL1_BAUD] ; 115.2kbaud for both transmit and receive - - move.b 0x40,r0 ; rec enable + ; 115.2kbaud for both transmit and receive + move.b IO_STATE (R_SERIAL1_BAUD, tr_baud, c115k2Hz) \ + | IO_STATE (R_SERIAL1_BAUD, rec_baud, c115k2Hz),r0 + move.b r0,[R_SERIAL1_BAUD] + + ; Set up and enable the serial1 receiver. + move.b IO_STATE (R_SERIAL1_REC_CTRL, dma_err, stop) \ + | IO_STATE (R_SERIAL1_REC_CTRL, rec_enable, enable) \ + | IO_STATE (R_SERIAL1_REC_CTRL, rts_, active) \ + | IO_STATE (R_SERIAL1_REC_CTRL, sampling, middle) \ + | IO_STATE (R_SERIAL1_REC_CTRL, rec_stick_par, normal) \ + | IO_STATE (R_SERIAL1_REC_CTRL, rec_par, even) \ + | IO_STATE (R_SERIAL1_REC_CTRL, rec_par_en, disable) \ + | IO_STATE (R_SERIAL1_REC_CTRL, rec_bitnr, rec_8bit),r0 move.b r0,[R_SERIAL1_REC_CTRL] - move.b 0x40,r0 ; tr enable + ; Set up and enable the serial1 transmitter. + move.b IO_FIELD (R_SERIAL1_TR_CTRL, txd, 0) \ + | IO_STATE (R_SERIAL1_TR_CTRL, tr_enable, enable) \ + | IO_STATE (R_SERIAL1_TR_CTRL, auto_cts, disabled) \ + | IO_STATE (R_SERIAL1_TR_CTRL, stop_bits, one_bit) \ + | IO_STATE (R_SERIAL1_TR_CTRL, tr_stick_par, normal) \ + | IO_STATE (R_SERIAL1_TR_CTRL, tr_par, even) \ + | IO_STATE (R_SERIAL1_TR_CTRL, tr_par_en, disable) \ + | IO_STATE (R_SERIAL1_TR_CTRL, tr_bitnr, tr_8bit),r0 move.b r0,[R_SERIAL1_TR_CTRL] #ifdef CONFIG_ETRAX_SERIAL_PORT3 ;; setup the serial port 3 at 115200 baud for debug purposes - moveq 0,r0 + moveq IO_STATE (R_SERIAL3_XOFF, tx_stop, enable) \ + | IO_STATE (R_SERIAL3_XOFF, auto_xoff, disable) \ + | IO_FIELD (R_SERIAL3_XOFF, xoff_char, 0),r0 move.d r0,[R_SERIAL3_XOFF] - move.b 0x99,r0 - move.b r0,[R_SERIAL3_BAUD] ; 115.2kbaud for both transmit and receive - - move.b 0x40,r0 ; rec enable + ; 115.2kbaud for both transmit and receive + move.b IO_STATE (R_SERIAL3_BAUD, tr_baud, c115k2Hz) \ + | IO_STATE (R_SERIAL3_BAUD, rec_baud, c115k2Hz),r0 + move.b r0,[R_SERIAL3_BAUD] + + ; Set up and enable the serial3 receiver. + move.b IO_STATE (R_SERIAL3_REC_CTRL, dma_err, stop) \ + | IO_STATE (R_SERIAL3_REC_CTRL, rec_enable, enable) \ + | IO_STATE (R_SERIAL3_REC_CTRL, rts_, active) \ + | IO_STATE (R_SERIAL3_REC_CTRL, sampling, middle) \ + | IO_STATE (R_SERIAL3_REC_CTRL, rec_stick_par, normal) \ + | IO_STATE (R_SERIAL3_REC_CTRL, rec_par, even) \ + | IO_STATE (R_SERIAL3_REC_CTRL, rec_par_en, disable) \ + | IO_STATE (R_SERIAL3_REC_CTRL, rec_bitnr, rec_8bit),r0 move.b r0,[R_SERIAL3_REC_CTRL] - move.b 0x40,r0 ; tr enable + ; Set up and enable the serial3 transmitter. + move.b IO_FIELD (R_SERIAL3_TR_CTRL, txd, 0) \ + | IO_STATE (R_SERIAL3_TR_CTRL, tr_enable, enable) \ + | IO_STATE (R_SERIAL3_TR_CTRL, auto_cts, disabled) \ + | IO_STATE (R_SERIAL3_TR_CTRL, stop_bits, one_bit) \ + | IO_STATE (R_SERIAL3_TR_CTRL, tr_stick_par, normal) \ + | IO_STATE (R_SERIAL3_TR_CTRL, tr_par, even) \ + | IO_STATE (R_SERIAL3_TR_CTRL, tr_par_en, disable) \ + | IO_STATE (R_SERIAL3_TR_CTRL, tr_bitnr, tr_8bit),r0 move.b r0,[R_SERIAL3_TR_CTRL] #endif diff -u --recursive --new-file v2.4.7/linux/arch/cris/kernel/irq.c linux/arch/cris/kernel/irq.c --- v2.4.7/linux/arch/cris/kernel/irq.c Wed Jul 25 17:10:17 2001 +++ linux/arch/cris/kernel/irq.c Thu Jul 26 15:10:06 2001 @@ -1,4 +1,4 @@ -/* $Id: irq.c,v 1.15 2001/06/10 11:18:46 bjornw Exp $ +/* $Id: irq.c,v 1.17 2001/07/25 16:08:01 bjornw Exp $ * * linux/arch/cris/kernel/irq.c * @@ -32,6 +32,7 @@ #include #include #include +#include #include #include @@ -278,7 +279,7 @@ } irq_exit(cpu); - if (softirq_active(cpu) & softirq_mask(cpu)) + if (softirq_pending(cpu)) do_softirq(); /* unmasking and bottom half handling is done magically for us. */ @@ -422,7 +423,8 @@ void do_sigtrap(void); /* from entry.S */ void gdb_handle_breakpoint(void); /* from entry.S */ -void init_IRQ(void) +void __init +init_IRQ(void) { int i; @@ -488,7 +490,8 @@ #if defined(CONFIG_PROC_FS) && defined(CONFIG_SYSCTL) /* Used by other archs to show/control IRQ steering during SMP */ -void init_irq_proc(void) +void __init +init_irq_proc(void) { } #endif diff -u --recursive --new-file v2.4.7/linux/arch/cris/kernel/process.c linux/arch/cris/kernel/process.c --- v2.4.7/linux/arch/cris/kernel/process.c Wed Jul 25 17:10:17 2001 +++ linux/arch/cris/kernel/process.c Thu Jul 26 15:10:06 2001 @@ -1,4 +1,4 @@ -/* $Id: process.c,v 1.14 2001/05/29 11:27:59 markusl Exp $ +/* $Id: process.c,v 1.16 2001/06/21 02:00:40 hp Exp $ * * linux/arch/cris/kernel/process.c * @@ -8,6 +8,18 @@ * Authors: Bjorn Wesen (bjornw@axis.com) * * $Log: process.c,v $ + * Revision 1.16 2001/06/21 02:00:40 hp + * * entry.S: Include asm/unistd.h. + * (_sys_call_table): Use section .rodata, not .data. + * (_kernel_thread): Move from... + * * process.c: ... here. + * * entryoffsets.c (VAL): Break out from... + * (OF): Use VAL. + * (LCLONE_VM): New asmified value from CLONE_VM. + * + * Revision 1.15 2001/06/20 16:31:57 hp + * Add comments to describe empty functions according to review. + * * Revision 1.14 2001/05/29 11:27:59 markusl * Fixed so that hard_reset_now will do reset even if watchdog wasn't enabled * @@ -71,6 +83,15 @@ __attribute__((__section__(".data.init_task"))) = { INIT_TASK(init_task_union.task) }; +/* + * The hlt_counter, disable_hlt and enable_hlt is just here as a hook if + * there would ever be a halt sequence (for power save when idle) with + * some largish delay when halting or resuming *and* a driver that can't + * afford that delay. The hlt_counter would then be checked before + * executing the halt sequence, and the driver marks the unhaltable + * region by enable_hlt/disable_hlt. + */ + static int hlt_counter=0; void disable_hlt(void) @@ -116,52 +137,27 @@ hard_reset_now(); } -/* can't do much here... */ +/* + * Similar to machine_power_off, but don't shut off power. Add code + * here to freeze the system for e.g. post-mortem debug purpose when + * possible. This halt has nothing to do with the idle halt. + */ void machine_halt(void) { } +/* If or when software power-off is implemented, add code here. */ + void machine_power_off(void) { } /* - * This is the mechanism for creating a new kernel thread. - * - * NOTE! Only a kernel-only process(ie the swapper or direct descendants - * who haven't done an "execve()") should use this: it will work within - * a system call from a "real" process, but the process memory space will - * not be free'd until both the parent and the child have exited. - */ - -int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags) -{ - register long __a __asm__ ("r10"); - - __asm__ __volatile__ - ("movu.w %1,r9\n\t" /* r9 contains syscall number, to sys_clone */ - "clear.d r10\n\t" /* r10 is argument 1 to clone */ - "move.d %2,r11\n\t" /* r11 is argument 2 to clone, the flags */ - "break 13\n\t" /* call sys_clone, this will fork */ - "test.d r10\n\t" /* parent or child? child returns 0 here. */ - "bne 1f\n\t" /* jump if parent */ - "nop\n\t" /* delay slot */ - "move.d %4,r10\n\t" /* set argument to function to call */ - "jsr %5\n\t" /* call specified function */ - "movu.w %3,r9\n\t" /* r9 is sys_exit syscall number */ - "moveq -1,r10\n\t" /* Give a really bad exit-value */ - "break 13\n\t" /* call sys_exit, killing the child */ - "1:\n\t" - : "=r" (__a) - : "g" (__NR_clone), "r" (flags | CLONE_VM), "g" (__NR_exit), - "r" (arg), "r" (fn) - : "r10", "r11", "r9"); - - return __a; -} - - + * When a process does an "exec", machine state like FPU and debug + * registers need to be reset. This is a hook function for that. + * Currently we don't have any such state to reset, so this is empty. + */ void flush_thread(void) { diff -u --recursive --new-file v2.4.7/linux/arch/cris/kernel/ptrace.c linux/arch/cris/kernel/ptrace.c --- v2.4.7/linux/arch/cris/kernel/ptrace.c Wed Jul 25 17:10:17 2001 +++ linux/arch/cris/kernel/ptrace.c Thu Jul 26 15:10:06 2001 @@ -8,6 +8,9 @@ * Authors: Bjorn Wesen * * $Log: ptrace.c,v $ + * Revision 1.6 2001/07/25 16:08:47 bjornw + * PTRACE_ATTACH bulk moved into arch-independant code in 2.4.7 + * * Revision 1.5 2001/03/26 14:24:28 orjanf * * Changed loop condition. * * Added comment documenting non-standard ptrace behaviour. diff -u --recursive --new-file v2.4.7/linux/arch/cris/kernel/setup.c linux/arch/cris/kernel/setup.c --- v2.4.7/linux/arch/cris/kernel/setup.c Wed Jul 25 17:10:17 2001 +++ linux/arch/cris/kernel/setup.c Thu Jul 26 15:10:06 2001 @@ -1,4 +1,4 @@ -/* $Id: setup.c,v 1.16 2001/05/15 01:23:13 hp Exp $ +/* $Id: setup.c,v 1.18 2001/06/28 04:47:16 hp Exp $ * * linux/arch/cris/kernel/setup.c * @@ -162,9 +162,9 @@ paging_init(); - /* we dont use a command line yet, so just let it be an empty string - to start with */ - + /* We dont use a command line yet, so just re-initialize it without + saving anything that might be there. */ + *cmdline_p = command_line; strcpy(command_line, "root=/dev/rom"); /* use the appended romdisk as root */ @@ -249,7 +249,7 @@ cpu_info[revision].flags & HAS_SCSI ? "yes" : "no", cpu_info[revision].flags & HAS_ATA ? "yes" : "no", cpu_info[revision].flags & HAS_USB ? "yes" : "no", - (loops_per_jiffy * HZ + 500) / 100000, - ((loops_per_jiffy * HZ + 500) / 1000) % 100); + (loops_per_jiffy * HZ + 500) / 500000, + ((loops_per_jiffy * HZ + 500) / 5000) % 100); } #endif /* CONFIG_PROC_FS */ diff -u --recursive --new-file v2.4.7/linux/arch/cris/kernel/sys_cris.c linux/arch/cris/kernel/sys_cris.c --- v2.4.7/linux/arch/cris/kernel/sys_cris.c Wed Jul 25 17:10:17 2001 +++ linux/arch/cris/kernel/sys_cris.c Thu Jul 26 15:10:06 2001 @@ -1,4 +1,4 @@ -/* $Id: sys_cris.c,v 1.9 2001/05/30 06:20:26 markusl Exp $ +/* $Id: sys_cris.c,v 1.10 2001/06/27 21:16:15 hp Exp $ * * linux/arch/cris/kernel/sys_cris.c * @@ -42,34 +42,6 @@ error = -EFAULT; } return error; -} - -/* sys_mmap used to take a ptr to a buffer instead containing the args - * but we support syscalls with 6 arguments now - */ - -asmlinkage unsigned long sys_mmap(unsigned long addr, size_t len, - unsigned long prot, unsigned long flags, - unsigned long fd, off_t offset) -{ - struct file * file = NULL; - int ret = -EBADF; - - lock_kernel(); - if (!(flags & MAP_ANONYMOUS)) { - if (!(file = fget(fd))) - goto out; - } - - flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE); - down_write(¤t->mm->mmap_sem); - ret = do_mmap(file, addr, len, prot, flags, offset); - up_write(¤t->mm->mmap_sem); - if (file) - fput(file); - out: - unlock_kernel(); - return ret; } /* common code for old and new mmaps */ diff -u --recursive --new-file v2.4.7/linux/arch/cris/kernel/time.c linux/arch/cris/kernel/time.c --- v2.4.7/linux/arch/cris/kernel/time.c Wed Jul 25 17:10:17 2001 +++ linux/arch/cris/kernel/time.c Thu Jul 26 15:10:06 2001 @@ -1,9 +1,9 @@ -/* $Id: time.c,v 1.6 2001/05/29 11:29:42 markusl Exp $ +/* $Id: time.c,v 1.8 2001/07/18 14:01:03 bjornw Exp $ * * linux/arch/cris/kernel/time.c * * Copyright (C) 1991, 1992, 1995 Linus Torvalds - * Copyright (C) 1999, 2000 Axis Communications AB + * Copyright (C) 1999, 2000, 2001 Axis Communications AB * * 1994-07-02 Alan Modra * fixed set_rtc_mmss, fixed time.year for >= 2000, new mktime @@ -228,7 +228,7 @@ #define WATCHDOG_MIN_FREE_PAGES 8 -static inline void +void reset_watchdog(void) { #if defined(CONFIG_ETRAX_WATCHDOG) && !defined(CONFIG_SVINTO_SIM) @@ -242,6 +242,18 @@ #endif } +/* stop the watchdog - we still need the correct key */ + +void +stop_watchdog(void) +{ +#if defined(CONFIG_ETRAX_WATCHDOG) && !defined(CONFIG_SVINTO_SIM) + watchdog_key ^= 0x7; /* invert key, which is 3 bits */ + *R_WATCHDOG = IO_FIELD(R_WATCHDOG, key, watchdog_key) | + IO_STATE(R_WATCHDOG, enable, stop); +#endif +} + /* last time the cmos clock got updated */ static long last_rtc_update = 0; @@ -443,6 +455,19 @@ #if defined(CONFIG_ETRAX_WATCHDOG) && !defined(CONFIG_SVINTO_SIM) printk("Enabling watchdog...\n"); start_watchdog(); -#endif + /* If we use the hardware watchdog, we want to trap it as an NMI + and dump registers before it resets us. For this to happen, we + must set the "m" NMI enable flag (which once set, is unset only + when an NMI is taken). + + The same goes for the external NMI, but that doesn't have any + driver or infrastructure support yet. */ + asm ("setf m"); + + *R_IRQ_MASK0_SET = + IO_STATE(R_IRQ_MASK0_SET, watchdog_nmi, set); + *R_VECT_MASK_SET = + IO_STATE(R_VECT_MASK_SET, nmi, set); +#endif } diff -u --recursive --new-file v2.4.7/linux/arch/cris/kernel/traps.c linux/arch/cris/kernel/traps.c --- v2.4.7/linux/arch/cris/kernel/traps.c Wed Jul 25 17:10:17 2001 +++ linux/arch/cris/kernel/traps.c Thu Jul 26 15:10:06 2001 @@ -1,4 +1,4 @@ -/* $Id: traps.c,v 1.12 2001/05/15 15:46:40 bjornw Exp $ +/* $Id: traps.c,v 1.15 2001/07/18 14:02:37 bjornw Exp $ * * linux/arch/cris/traps.c * @@ -9,6 +9,7 @@ * Copyright (C) 2000,2001 Axis Communications AB * * Authors: Bjorn Wesen + * Hans-Peter Nilsson * */ @@ -20,6 +21,7 @@ #include #include #include +#include #include #include @@ -36,6 +38,13 @@ #define MODULE_RANGE (8*1024*1024) +/* + * The output (format, strings and order) is adjusted to be usable with + * ksymoops-2.4.1 with some necessary CRIS-specific patches. Please don't + * change it unless you're serious about adjusting ksymoops and syncing + * with the ksymoops maintainer. + */ + void show_stack(unsigned long *sp) { @@ -43,22 +52,31 @@ int i; extern char _stext, _etext; - /* - * debugging aid: "show_stack(NULL);" prints the - * back trace for this cpu. - */ + /* + * debugging aid: "show_stack(NULL);" prints a + * back trace. + */ if(sp == NULL) sp = (unsigned long*)rdsp(); stack = sp; + printk("\nStack from %08lx:\n ", stack); for(i = 0; i < kstack_depth_to_print; i++) { if (((long) stack & (THREAD_SIZE-1)) == 0) break; if (i && ((i % 8) == 0)) printk("\n "); - printk("%08lx ", *stack++); + if (__get_user (addr, stack)) { + /* This message matches "failing address" marked + s390 in ksymoops, so lines containing it will + not be filtered out by ksymoops. */ + printk ("Failing address 0x%lx\n", stack); + break; + } + stack++; + printk("%08lx ", addr); } printk("\nCall Trace: "); @@ -67,7 +85,15 @@ module_start = VMALLOC_START; module_end = VMALLOC_END; while (((long) stack & (THREAD_SIZE-1)) != 0) { - addr = *stack++; + if (__get_user (addr, stack)) { + /* This message matches "failing address" marked + s390 in ksymoops, so lines containing it will + not be filtered out by ksymoops. */ + printk ("Failing address 0x%lx\n", stack); + break; + } + stack++; + /* * If the address is either in the text segment of the * kernel, or in the region which contains vmalloc'ed @@ -105,38 +131,53 @@ void show_registers(struct pt_regs * regs) { + /* We either use rdusp() - the USP register, which might not + correspond to the current process for all cases we're called, + or we use the current->thread.usp, which is not up to date for + the current process. Experience shows we want the USP + register. */ unsigned long usp = rdusp(); - printk("IRP: %08lx SRP: %08lx CCR: %08lx USP: %08lx MOF: %08lx\n", + printk("IRP: %08lx SRP: %08lx DCCR: %08lx USP: %08lx MOF: %08lx\n", regs->irp, regs->srp, regs->dccr, usp, regs->mof ); - printk(" r0: %08lx r1: %08lx r2: %08lx r3: %08lx\n", + printk(" r0: %08lx r1: %08lx r2: %08lx r3: %08lx\n", regs->r0, regs->r1, regs->r2, regs->r3); - printk(" r4: %08lx r5: %08lx r6: %08lx r7: %08lx\n", + printk(" r4: %08lx r5: %08lx r6: %08lx r7: %08lx\n", regs->r4, regs->r5, regs->r6, regs->r7); - printk(" r8: %08lx r9: %08lx r10: %08lx r11: %08lx\n", + printk(" r8: %08lx r9: %08lx r10: %08lx r11: %08lx\n", regs->r8, regs->r9, regs->r10, regs->r11); printk("r12: %08lx r13: %08lx oR10: %08lx\n", regs->r12, regs->r13, regs->orig_r10); + printk("R_MMU_CAUSE: %08lx\n", *R_MMU_CAUSE); printk("Process %s (pid: %d, stackpage=%08lx)\n", current->comm, current->pid, (unsigned long)current); - /* TODO, fix in_kernel detection */ - -#if 0 /* * When in-kernel, we also print out the stack and code at the * time of the fault.. */ - if (1) { - - printk("\nStack: "); + if (! user_mode(regs)) { + int i; + show_stack((unsigned long*)usp); + /* Dump kernel stack if the previous dump wasn't one. */ + if (usp != 0) + show_stack (NULL); + printk("\nCode: "); if(regs->irp < PAGE_OFFSET) goto bad; - for(i = 0; i < 20; i++) + /* Often enough the value at regs->irp does not point to + the interesting instruction, which is most often the + _previous_ instruction. So we dump at an offset large + enough that instruction decoding should be in sync at + the interesting point, but small enough to fit on a row + (sort of). We point out the regs->irp location in a + ksymoops-friendly way by wrapping the byte for that + address in parentheses. */ + for(i = -12; i < 12; i++) { unsigned char c; if(__get_user(c, &((unsigned char*)regs->irp)[i])) { @@ -144,11 +185,14 @@ printk(" Bad IP value."); break; } - printk("%02x ", c); + + if (i == 0) + printk("(%02x) ", c); + else + printk("%02x ", c); } + printk("\n"); } - printk("\n"); -#endif } void @@ -157,10 +201,13 @@ if(user_mode(regs)) return; + stop_watchdog(); + printk("%s: %04lx\n", str, err & 0xffff); show_registers(regs); - show_stack(NULL); /* print backtrace for kernel stack on this CPU */ + + reset_watchdog(); do_exit(SIGSEGV); } diff -u --recursive --new-file v2.4.7/linux/arch/cris/lib/Makefile linux/arch/cris/lib/Makefile --- v2.4.7/linux/arch/cris/lib/Makefile Thu Feb 8 16:32:44 2001 +++ linux/arch/cris/lib/Makefile Thu Jul 26 15:10:06 2001 @@ -6,6 +6,6 @@ $(CC) -D__ASSEMBLY__ $(AFLAGS) -traditional -c $< -o $*.o L_TARGET = lib.a -obj-y = checksum.o checksumcopy.o string.o usercopy.o memset.o +obj-y = checksum.o checksumcopy.o string.o usercopy.o memset.o csumcpfruser.o include $(TOPDIR)/Rules.make diff -u --recursive --new-file v2.4.7/linux/arch/cris/lib/checksumcopy.S linux/arch/cris/lib/checksumcopy.S --- v2.4.7/linux/arch/cris/lib/checksumcopy.S Wed Jul 25 17:10:17 2001 +++ linux/arch/cris/lib/checksumcopy.S Thu Jul 26 15:10:06 2001 @@ -1,4 +1,4 @@ -/* $Id: checksumcopy.S,v 1.5 2001/05/29 11:40:14 markusl Exp $ +/* $Id: checksumcopy.S,v 1.6 2001/06/28 03:57:16 hp Exp $ * A fast checksum+copy routine using movem * Copyright (c) 1998, 2001 Axis Communications AB * @@ -37,6 +37,7 @@ subq 10*4,r12 ; update length for the first loop mloop: movem [r10+],r9 ; read 10 longwords +1: ;; A failing userspace access will have this as PC. movem r9,[r11+] ; write 10 longwords ;; perform dword checksumming on the 10 longwords @@ -105,6 +106,7 @@ subq 2,r12 wloop: move.w [r10+],r9 +2: ;; A failing userspace access will have this as PC. addu.w r9,r13 subq 2,r12 bge wloop @@ -123,9 +125,8 @@ do_byte: ;; copy and checksum the last byte move.b [r10],r9 +3: ;; A failing userspace access will have this as PC. addu.b r9,r13 move.b r9,[r11] ret move.d r13, r10 - - diff -u --recursive --new-file v2.4.7/linux/arch/cris/lib/csumcpfruser.S linux/arch/cris/lib/csumcpfruser.S --- v2.4.7/linux/arch/cris/lib/csumcpfruser.S Wed Dec 31 16:00:00 1969 +++ linux/arch/cris/lib/csumcpfruser.S Thu Jul 26 15:10:06 2001 @@ -0,0 +1,64 @@ +/* + * Add-on to transform csum_partial_copy_nocheck in checksumcopy.S into + * csum_partial_copy_from_user by adding exception records. + * + * Copyright (C) 2001 Axis Communications AB. + * + * Author: Hans-Peter Nilsson. + */ + +#include + +/* Same function body, but a different name. If we just added exception + records to _csum_partial_copy_nocheck and made it generic, we wouldn't + know a user fault from a kernel fault and we would have overhead in + each kernel caller for the error-pointer argument. + + unsigned int csum_partial_copy_from_user + (const char *src, char *dst, int len, unsigned int sum, int *errptr); + + Note that the errptr argument is only set if we encounter an error. + It is conveniently located on the stack, so the normal function body + does not have to handle it. */ + +#define _csum_partial_copy_nocheck _csum_partial_copy_from_user + +/* There are local labels numbered 1, 2 and 3 present to mark the + different from-user accesses. */ +#include "checksumcopy.S" + + .section .fixup,"ax" + +;; Here from the movem loop; restore stack. +4: + movem [sp+],r8 +;; r12 is already decremented. Add back chunk_size-2. + addq 40-2,r12 + +;; Here from the word loop; r12 is off by 2; add it back. +5: + addq 2,r12 + +;; Here from a failing single byte. +6: + +;; Signal in *errptr that we had a failing access. + moveq -EFAULT,r9 + move.d r9,[[sp]] + +;; Clear the rest of the destination area using memset. Preserve the +;; checksum for the readable bytes. + push srp + push r13 + move.d r11,r10 + clear.d r11 + jsr _memset + pop r10 + jump [sp+] + + .previous + .section __ex_table,"a" + .dword 1b,4b + .dword 2b,5b + .dword 3b,6b + .previous diff -u --recursive --new-file v2.4.7/linux/arch/cris/mm/fault.c linux/arch/cris/mm/fault.c --- v2.4.7/linux/arch/cris/mm/fault.c Wed Jul 25 17:10:17 2001 +++ linux/arch/cris/mm/fault.c Thu Jul 26 15:10:06 2001 @@ -6,6 +6,16 @@ * Authors: Bjorn Wesen * * $Log: fault.c,v $ + * Revision 1.18 2001/07/18 22:14:32 bjornw + * Enable interrupts in the bulk of do_page_fault + * + * Revision 1.17 2001/07/18 13:07:23 bjornw + * * Detect non-existant PTE's in vmalloc pmd synchronization + * * Remove comment about fast-paths for VMALLOC_START etc, because all that + * was totally bogus anyway it turned out :) + * * Fix detection of vmalloc-area synchronization + * * Add some comments + * * Revision 1.16 2001/06/13 00:06:08 bjornw * current_pgd should be volatile * @@ -76,7 +86,9 @@ volatile pgd_t *current_pgd; -/* fast TLB-fill fault handler */ +/* fast TLB-fill fault handler + * this is called from entry.S with interrupts disabled + */ void handle_mmu_bus_fault(struct pt_regs *regs) @@ -85,10 +97,9 @@ int index; int page_id; int miss, we, acc, inv; - struct mm_struct *mm = current->active_mm; pmd_t *pmd; pte_t pte; - int errcode = 0; + int errcode; unsigned long address; cause = *R_MMU_CAUSE; @@ -103,6 +114,20 @@ miss = IO_EXTRACT(R_MMU_CAUSE, miss_excp, cause); we = IO_EXTRACT(R_MMU_CAUSE, we_excp, cause); + /* Note: the reason we don't set errcode's r/w flag here + * using the 'we' flag, is because the latter is only given + * if there is a write-protection exception, not given as a + * general r/w access mode flag. It is currently not possible + * to get this from the MMU (TODO: check if this is the case + * for LXv2). + * + * The page-fault code won't care, but there will be two page- + * faults instead of one for the case of a write to a non-tabled + * page (miss, then write-protection). + */ + + errcode = 0; + D(printk("bus_fault from IRP 0x%x: addr 0x%x, miss %d, inv %d, we %d, acc %d, " "idx %d pid %d\n", regs->irp, address, miss, inv, we, acc, index, page_id)); @@ -157,14 +182,14 @@ * the write to R_TLB_LO also writes the vpn and page_id fields from * R_MMU_CAUSE, which we in this case obviously want to keep */ - + *R_TLB_LO = pte_val(pte); return; } - errcode = 0x01 | (we << 1); - + errcode = 1 | (we << 1); + dofault: /* leave it to the MM system fault handler below */ D(printk("do_page_fault %p errcode %d\n", address, errcode)); @@ -214,25 +239,21 @@ * NOTE2: This is done so that, when updating the vmalloc * mappings we don't have to walk all processes pgdirs and * add the high mappings all at once. Instead we do it as they - * are used. + * are used. However vmalloc'ed page entries have the PAGE_GLOBAL + * bit set so sometimes the TLB can use a lingering entry. * - * TODO: On CRIS, we have a PTE Global bit which should be set in - * all the PTE's related to vmalloc in all processes - that means if - * we switch process and a vmalloc PTE is still in the TLB, it won't - * need to be reloaded. It's an optimization. - * - * Linux/CRIS's kernel is not page-mapped, so the comparision below - * should really be >= VMALLOC_START, however, kernel fixup errors - * will be handled more quickly by going through vmalloc_fault and then - * into bad_area_nosemaphore than falling through the find_vma user-mode - * tests. As an aside can be mentioned that the difference in - * compiled code is neglibible; the instruction is the same, just a - * comparison with a different address of the same size. + * This verifies that the fault happens in kernel space + * and that the fault was not a protection error (error_code & 1). */ - if (address >= TASK_SIZE) + if (address >= VMALLOC_START && + !(error_code & 1) && + !user_mode(regs)) goto vmalloc_fault; + /* we can and should enable interrupts at this point */ + sti(); + mm = tsk->mm; writeaccess = error_code & 2; info.si_code = SEGV_MAPERR; @@ -409,29 +430,48 @@ * Use current_pgd instead of tsk->active_mm->pgd * since the latter might be unavailable if this * code is executed in a misfortunately run irq + * (like inside schedule() between switch_mm and + * switch_to...). */ int offset = pgd_index(address); pgd_t *pgd, *pgd_k; pmd_t *pmd, *pmd_k; + pte_t *pte_k; pgd = current_pgd + offset; pgd_k = init_mm.pgd + offset; - if (!pgd_present(*pgd)) { - if (!pgd_present(*pgd_k)) - goto bad_area_nosemaphore; - set_pgd(pgd, *pgd_k); - return; - } + /* Since we're two-level, we don't need to do both + * set_pgd and set_pmd (they do the same thing). If + * we go three-level at some point, do the right thing + * with pgd_present and set_pgd here. + * + * Also, since the vmalloc area is global, we don't + * need to copy individual PTE's, it is enough to + * copy the pgd pointer into the pte page of the + * root task. If that is there, we'll find our pte if + * it exists. + */ pmd = pmd_offset(pgd, address); pmd_k = pmd_offset(pgd_k, address); if (!pmd_present(*pmd_k)) goto bad_area_nosemaphore; + set_pmd(pmd, *pmd_k); + + /* Make sure the actual PTE exists as well to + * catch kernel vmalloc-area accesses to non-mapped + * addresses. If we don't do this, this will just + * silently loop forever. + */ + + pte_k = pte_offset(pmd_k, address); + if (!pte_present(*pte_k)) + goto no_context; + return; } - } diff -u --recursive --new-file v2.4.7/linux/arch/cris/mm/init.c linux/arch/cris/mm/init.c --- v2.4.7/linux/arch/cris/mm/init.c Wed Jul 25 17:10:17 2001 +++ linux/arch/cris/mm/init.c Thu Jul 26 15:10:06 2001 @@ -7,6 +7,18 @@ * Authors: Bjorn Wesen (bjornw@axis.com) * * $Log: init.c,v $ + * Revision 1.29 2001/07/25 16:09:50 bjornw + * val->sharedram will stay 0 + * + * Revision 1.28 2001/06/28 16:30:17 bjornw + * Oops. This needs to wait until 2.4.6 is merged + * + * Revision 1.27 2001/06/28 14:04:07 bjornw + * Fill in sharedram + * + * Revision 1.26 2001/06/18 06:36:02 hp + * Enable free_initmem of __init-type pages + * * Revision 1.25 2001/06/13 00:02:23 bjornw * Use a separate variable to store the current pgd to avoid races in schedule * @@ -438,11 +450,6 @@ void free_initmem(void) { -#if 0 - /* currently this is a bad idea since the cramfs image is catted onto - * the vmlinux image, and the end of that image is not page-padded so - * part of the cramfs image will be freed here - */ unsigned long addr; addr = (unsigned long)(&__init_begin); @@ -454,7 +461,6 @@ } printk ("Freeing unused kernel memory: %dk freed\n", (&__init_end - &__init_begin) >> 10); -#endif } void @@ -464,7 +470,7 @@ i = max_mapnr; val->totalram = 0; - val->sharedram = atomic_read(&shmem_nrpages); + val->sharedram = 0; val->freeram = nr_free_pages(); val->bufferram = atomic_read(&buffermem_pages); while (i-- > 0) { diff -u --recursive --new-file v2.4.7/linux/arch/cris/mm/tlb.c linux/arch/cris/mm/tlb.c --- v2.4.7/linux/arch/cris/mm/tlb.c Wed Jul 25 17:10:17 2001 +++ linux/arch/cris/mm/tlb.c Thu Jul 26 15:10:06 2001 @@ -40,6 +40,10 @@ * * The last page_id is never running - it is used as an invalid page_id * so we can make TLB entries that will never match. + * + * Notice that we need to make the flushes atomic, otherwise an interrupt + * handler that uses vmalloced memory might cause a TLB load in the middle + * of a flush causing. */ struct mm_struct *page_id_map[NUM_PAGEID]; @@ -49,17 +53,18 @@ /* invalidate all TLB entries */ void -flush_tlb_all() +flush_tlb_all(void) { int i; + unsigned long flags; /* the vpn of i & 0xf is so we dont write similar TLB entries * in the same 4-way entry group. details.. */ + save_and_cli(flags); /* flush needs to be atomic */ for(i = 0; i < NUM_TLB_ENTRIES; i++) { *R_TLB_SELECT = ( IO_FIELD(R_TLB_SELECT, index, i) ); - *R_TLB_HI = ( IO_FIELD(R_TLB_HI, page_id, INVALID_PAGEID ) | IO_FIELD(R_TLB_HI, vpn, i & 0xf ) ); @@ -69,6 +74,7 @@ IO_STATE(R_TLB_LO, we, no ) | IO_FIELD(R_TLB_LO, pfn, 0 ) ); } + restore_flags(flags); D(printk("tlb: flushed all\n")); } @@ -79,6 +85,7 @@ { int i; int page_id = mm->context; + unsigned long flags; D(printk("tlb: flush mm context %d (%p)\n", page_id, mm)); @@ -90,6 +97,7 @@ * global pages. is it worth the extra I/O ? */ + save_and_cli(flags); /* flush needs to be atomic */ for(i = 0; i < NUM_TLB_ENTRIES; i++) { *R_TLB_SELECT = IO_FIELD(R_TLB_SELECT, index, i); if (IO_EXTRACT(R_TLB_HI, page_id, *R_TLB_HI) == page_id) { @@ -103,6 +111,7 @@ IO_FIELD(R_TLB_LO, pfn, 0 ) ); } } + restore_flags(flags); } /* invalidate a single page */ @@ -114,6 +123,7 @@ struct mm_struct *mm = vma->vm_mm; int page_id = mm->context; int i; + unsigned long flags; D(printk("tlb: flush page %p in context %d (%p)\n", addr, page_id, mm)); @@ -126,6 +136,7 @@ * and the virtual address requested */ + save_and_cli(flags); /* flush needs to be atomic */ for(i = 0; i < NUM_TLB_ENTRIES; i++) { unsigned long tlb_hi; *R_TLB_SELECT = IO_FIELD(R_TLB_SELECT, index, i); @@ -142,6 +153,7 @@ IO_FIELD(R_TLB_LO, pfn, 0 ) ); } } + restore_flags(flags); } /* invalidate a page range */ @@ -153,6 +165,7 @@ { int page_id = mm->context; int i; + unsigned long flags; D(printk("tlb: flush range %p<->%p in context %d (%p)\n", start, end, page_id, mm)); @@ -167,6 +180,7 @@ * and the virtual address range */ + save_and_cli(flags); /* flush needs to be atomic */ for(i = 0; i < NUM_TLB_ENTRIES; i++) { unsigned long tlb_hi, vpn; *R_TLB_SELECT = IO_FIELD(R_TLB_SELECT, index, i); @@ -184,8 +198,30 @@ IO_FIELD(R_TLB_LO, pfn, 0 ) ); } } + restore_flags(flags); } +/* dump the entire TLB for debug purposes */ + +#if 0 +void +dump_tlb_all(void) +{ + int i; + unsigned long flags; + + printk("TLB dump. LO is: pfn | reserved | global | valid | kernel | we |\n"); + + save_and_cli(flags); + for(i = 0; i < NUM_TLB_ENTRIES; i++) { + *R_TLB_SELECT = ( IO_FIELD(R_TLB_SELECT, index, i) ); + printk("Entry %d: HI 0x%08lx, LO 0x%08lx\n", + i, *R_TLB_HI, *R_TLB_LO); + } + restore_flags(flags); +} +#endif + /* * Initialize the context related info for a new mm_struct * instance. @@ -228,8 +264,7 @@ map_replace_ptr++; if(map_replace_ptr == INVALID_PAGEID) - map_replace_ptr = 0; /* wrap around */ - + map_replace_ptr = 0; /* wrap around */ } /* diff -u --recursive --new-file v2.4.7/linux/arch/i386/kernel/cpuid.c linux/arch/i386/kernel/cpuid.c --- v2.4.7/linux/arch/i386/kernel/cpuid.c Sun Dec 31 09:23:51 2000 +++ linux/arch/i386/kernel/cpuid.c Thu Jul 26 13:37:38 2001 @@ -57,7 +57,7 @@ cpuid(cmd->reg, &cmd->data[0], &cmd->data[1], &cmd->data[2], &cmd->data[3]); } -extern inline void do_cpuid(int cpu, u32 reg, u32 *data) +static inline void do_cpuid(int cpu, u32 reg, u32 *data) { struct cpuid_command cmd; @@ -73,7 +73,7 @@ } #else /* ! CONFIG_SMP */ -extern inline void do_cpuid(int cpu, u32 reg, u32 *data) +static inline void do_cpuid(int cpu, u32 reg, u32 *data) { cpuid(reg, &data[0], &data[1], &data[2], &data[3]); } diff -u --recursive --new-file v2.4.7/linux/arch/i386/kernel/dmi_scan.c linux/arch/i386/kernel/dmi_scan.c --- v2.4.7/linux/arch/i386/kernel/dmi_scan.c Wed Jul 25 17:10:17 2001 +++ linux/arch/i386/kernel/dmi_scan.c Wed Jul 25 14:12:01 2001 @@ -15,12 +15,14 @@ }; #define dmi_printk(x) -//#define dmi_printk(x) printk(x) +//#define dmi_printk(x) printk x static char * __init dmi_string(struct dmi_header *dm, u8 s) { u8 *bp=(u8 *)dm; bp+=dm->length; + if(!s) + return ""; s--; while(s>0) { diff -u --recursive --new-file v2.4.7/linux/arch/i386/kernel/ldt.c linux/arch/i386/kernel/ldt.c --- v2.4.7/linux/arch/i386/kernel/ldt.c Wed Apr 11 19:05:37 2001 +++ linux/arch/i386/kernel/ldt.c Thu Jul 26 13:29:45 2001 @@ -70,34 +70,19 @@ } /* - * Horrible dependencies! Try to get rid of this. This is wrong, - * as it only reloads the ldt for the first process with this - * mm. The implications are that you should really make sure that - * you have a ldt before you do the first clone(), otherwise - * you get strange behaviour (the kernel is safe, it's just user - * space strangeness). - * - * we have two choices: either we preallocate the LDT descriptor - * and can do a shared modify_ldt(), or we postallocate it and do - * an smp message pass to update it. Currently we are a bit - * un-nice to user-space and reload the LDT only on the next - * schedule. (only an issue on SMP) - * * the GDT index of the LDT is allocated dynamically, and is * limited by MAX_LDT_DESCRIPTORS. */ down_write(&mm->mmap_sem); if (!mm->context.segments) { + void * segments = vmalloc(LDT_ENTRIES*LDT_ENTRY_SIZE); error = -ENOMEM; - mm->context.segments = vmalloc(LDT_ENTRIES*LDT_ENTRY_SIZE); - if (!mm->context.segments) + if (!segments) goto out_unlock; - memset(mm->context.segments, 0, LDT_ENTRIES*LDT_ENTRY_SIZE); - - /* - * Possibly do an SMP cross-call to other CPUs to reload - * their LDTs? - */ + memset(segments, 0, LDT_ENTRIES*LDT_ENTRY_SIZE); + wmb(); + mm->context.segments = segments; + mm->context.cpuvalid = 1UL << smp_processor_id(); load_LDT(mm); } diff -u --recursive --new-file v2.4.7/linux/arch/i386/kernel/msr.c linux/arch/i386/kernel/msr.c --- v2.4.7/linux/arch/i386/kernel/msr.c Sun Dec 31 09:24:08 2000 +++ linux/arch/i386/kernel/msr.c Thu Jul 26 13:37:38 2001 @@ -43,7 +43,7 @@ /* Note: "err" is handled in a funny way below. Otherwise one version of gcc or another breaks. */ -extern inline int wrmsr_eio(u32 reg, u32 eax, u32 edx) +static inline int wrmsr_eio(u32 reg, u32 eax, u32 edx) { int err; @@ -64,7 +64,7 @@ return err; } -extern inline int rdmsr_eio(u32 reg, u32 *eax, u32 *edx) +static inline int rdmsr_eio(u32 reg, u32 *eax, u32 *edx) { int err; @@ -110,7 +110,7 @@ cmd->err = rdmsr_eio(cmd->reg, &cmd->data[0], &cmd->data[1]); } -extern inline int do_wrmsr(int cpu, u32 reg, u32 eax, u32 edx) +static inline int do_wrmsr(int cpu, u32 reg, u32 eax, u32 edx) { struct msr_command cmd; @@ -127,7 +127,7 @@ } } -extern inline int do_rdmsr(int cpu, u32 reg, u32 *eax, u32 *edx) +static inline int do_rdmsr(int cpu, u32 reg, u32 *eax, u32 *edx) { struct msr_command cmd; @@ -148,12 +148,12 @@ #else /* ! CONFIG_SMP */ -extern inline int do_wrmsr(int cpu, u32 reg, u32 eax, u32 edx) +static inline int do_wrmsr(int cpu, u32 reg, u32 eax, u32 edx) { return wrmsr_eio(reg, eax, edx); } -extern inline int do_rdmsr(int cpu, u32 reg, u32 *eax, u32 *edx) +static inline int do_rdmsr(int cpu, u32 reg, u32 *eax, u32 *edx) { return rdmsr_eio(reg, eax, edx); } diff -u --recursive --new-file v2.4.7/linux/arch/i386/kernel/process.c linux/arch/i386/kernel/process.c --- v2.4.7/linux/arch/i386/kernel/process.c Wed Jul 25 17:10:17 2001 +++ linux/arch/i386/kernel/process.c Wed Jul 25 18:19:11 2001 @@ -518,6 +518,7 @@ memcpy(ldt, old_ldt, LDT_ENTRIES*LDT_ENTRY_SIZE); } new_mm->context.segments = ldt; + new_mm->context.cpuvalid = ~0UL; /* valid on all CPU's - they can't have stale data */ } /* diff -u --recursive --new-file v2.4.7/linux/arch/i386/math-emu/poly.h linux/arch/i386/math-emu/poly.h --- v2.4.7/linux/arch/i386/math-emu/poly.h Fri Apr 6 10:42:47 2001 +++ linux/arch/i386/math-emu/poly.h Thu Jul 26 13:37:38 2001 @@ -60,7 +60,7 @@ /* Some versions of gcc make it difficult to stop eax from being clobbered. Merely specifying that it is used doesn't work... */ -extern inline unsigned long mul_32_32(const unsigned long arg1, +static inline unsigned long mul_32_32(const unsigned long arg1, const unsigned long arg2) { int retval; @@ -73,7 +73,7 @@ /* Add the 12 byte Xsig x2 to Xsig dest, with no checks for overflow. */ -extern inline void add_Xsig_Xsig(Xsig *dest, const Xsig *x2) +static inline void add_Xsig_Xsig(Xsig *dest, const Xsig *x2) { asm volatile ("movl %1,%%edi; movl %2,%%esi; movl (%%esi),%%eax; addl %%eax,(%%edi); @@ -88,7 +88,7 @@ /* Note: the constraints in the asm statement didn't always work properly with gcc 2.5.8. Changing from using edi to using ecx got around the problem, but keep fingers crossed! */ -extern inline void add_two_Xsig(Xsig *dest, const Xsig *x2, long int *exp) +static inline void add_two_Xsig(Xsig *dest, const Xsig *x2, long int *exp) { asm volatile ("movl %2,%%ecx; movl %3,%%esi; movl (%%esi),%%eax; addl %%eax,(%%ecx); @@ -108,7 +108,7 @@ /* Negate (subtract from 1.0) the 12 byte Xsig */ /* This is faster in a loop on my 386 than using the "neg" instruction. */ -extern inline void negate_Xsig(Xsig *x) +static inline void negate_Xsig(Xsig *x) { asm volatile("movl %1,%%esi; " "xorl %%ecx,%%ecx; " diff -u --recursive --new-file v2.4.7/linux/arch/ppc/kernel/misc.S linux/arch/ppc/kernel/misc.S --- v2.4.7/linux/arch/ppc/kernel/misc.S Wed Jul 25 17:10:18 2001 +++ linux/arch/ppc/kernel/misc.S Wed Jul 25 14:12:01 2001 @@ -813,7 +813,7 @@ _GLOBAL(_set_HID0) sync mtspr HID0, r3 - SYNC /* Handle erratas in some cases */ + SYNC /* Handle errata in some cases */ blr _GLOBAL(_get_ICTC) diff -u --recursive --new-file v2.4.7/linux/arch/s390/Makefile linux/arch/s390/Makefile --- v2.4.7/linux/arch/s390/Makefile Wed Apr 11 19:02:27 2001 +++ linux/arch/s390/Makefile Wed Jul 25 14:12:01 2001 @@ -17,7 +17,11 @@ CPP=$(CC) -E OBJCOPY=$(CROSS_COMPILE)objcopy -O binary -R .note -R .comment -S LDFLAGS=-e start +ifeq ($(CONFIG_SHARED_KERNEL),y) +LINKFLAGS =-T $(TOPDIR)/arch/s390/vmlinux-shared.lds $(LDFLAGS) +else LINKFLAGS =-T $(TOPDIR)/arch/s390/vmlinux.lds $(LDFLAGS) +endif CFLAGS_PIPE := -pipe CFLAGS_NSR := -fno-strength-reduce @@ -27,8 +31,8 @@ SUBDIRS := $(SUBDIRS) arch/s390/mm arch/s390/kernel arch/s390/lib \ drivers/s390 arch/s390/math-emu -CORE_FILES := arch/s390/mm/mm.o arch/s390/kernel/kernel.o $(CORE_FILES) \ - drivers/s390/io.o +CORE_FILES := arch/s390/mm/mm.o arch/s390/kernel/kernel.o $(CORE_FILES) +DRIVERS := $(DRIVERS) drivers/s390/io.o LIBS := $(TOPDIR)/arch/s390/lib/lib.a $(LIBS) $(TOPDIR)/arch/s390/lib/lib.a ifeq ($(CONFIG_MATHEMU),y) diff -u --recursive --new-file v2.4.7/linux/arch/s390/boot/Makefile linux/arch/s390/boot/Makefile --- v2.4.7/linux/arch/s390/boot/Makefile Wed Apr 11 19:02:27 2001 +++ linux/arch/s390/boot/Makefile Wed Jul 25 14:12:01 2001 @@ -1,5 +1,5 @@ # -# Makefile for the linux s390-specific parts of the memory manager. +# arch/s390/boot/Makefile # # Note! Dependencies are done automagically by 'make dep', which also # removes any old dependencies. DON'T put your own dependencies here diff -u --recursive --new-file v2.4.7/linux/arch/s390/config.in linux/arch/s390/config.in --- v2.4.7/linux/arch/s390/config.in Tue Apr 17 17:19:25 2001 +++ linux/arch/s390/config.in Wed Jul 25 14:12:01 2001 @@ -50,6 +50,8 @@ tristate 'Kernel support for ELF binaries' CONFIG_BINFMT_ELF tristate 'Kernel support for MISC binaries' CONFIG_BINFMT_MISC bool 'Show crashed user process info' CONFIG_PROCESS_DEBUG +bool 'Pseudo page fault support' CONFIG_PFAULT +bool 'VM shared kernel support' CONFIG_SHARED_KERNEL endmenu source drivers/s390/Config.in diff -u --recursive --new-file v2.4.7/linux/arch/s390/defconfig linux/arch/s390/defconfig --- v2.4.7/linux/arch/s390/defconfig Wed Apr 11 19:02:27 2001 +++ linux/arch/s390/defconfig Wed Jul 25 14:12:01 2001 @@ -5,6 +5,8 @@ # CONFIG_EISA is not set # CONFIG_MCA is not set CONFIG_UID16=y +CONFIG_RWSEM_GENERIC_SPINLOCK=y +# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set CONFIG_ARCH_S390=y # @@ -40,6 +42,8 @@ CONFIG_BINFMT_ELF=y # CONFIG_BINFMT_MISC is not set # CONFIG_PROCESS_DEBUG is not set +CONFIG_PFAULT=y +# CONFIG_SHARED_KERNEL is not set # # Block device drivers @@ -79,10 +83,13 @@ # # S/390 character device drivers # -CONFIG_3215=y -CONFIG_3215_CONSOLE=y +CONFIG_TN3270=y +CONFIG_TN3270_CONSOLE=y +CONFIG_TN3215=y +CONFIG_TN3215_CONSOLE=y CONFIG_HWC=y CONFIG_HWC_CONSOLE=y +CONFIG_HWC_CPI=m CONFIG_S390_TAPE=m # @@ -102,6 +109,9 @@ # CONFIG_NETDEVICES=y # CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set CONFIG_NET_ETHERNET=y CONFIG_TR=y # CONFIG_FDDI is not set @@ -109,7 +119,8 @@ # # S/390 network device drivers # -# CONFIG_CHANDEV is not set +CONFIG_CHANDEV=y +CONFIG_HOTPLUG=y CONFIG_CTC=m CONFIG_IUCV=m @@ -133,7 +144,8 @@ # CONFIG_IP_MROUTE is not set # CONFIG_INET_ECN is not set # CONFIG_SYN_COOKIES is not set -# CONFIG_IPV6 is not set +CONFIG_IPV6=m +# CONFIG_IPV6_NETLINK is not set # CONFIG_KHTTPD is not set # CONFIG_ATM is not set @@ -178,16 +190,18 @@ # CONFIG_EFS_FS is not set # CONFIG_JFFS_FS is not set # CONFIG_CRAMFS is not set +# CONFIG_TMPFS is not set # CONFIG_RAMFS is not set # CONFIG_ISO9660_FS is not set # CONFIG_JOLIET is not set # CONFIG_MINIX_FS is not set +# CONFIG_VXFS_FS is not set # CONFIG_NTFS_FS is not set # CONFIG_NTFS_RW is not set # CONFIG_HPFS_FS is not set CONFIG_PROC_FS=y -# CONFIG_DEVFS_FS is not set -# CONFIG_DEVFS_MOUNT is not set +CONFIG_DEVFS_FS=y +CONFIG_DEVFS_MOUNT=y # CONFIG_DEVFS_DEBUG is not set # CONFIG_DEVPTS_FS is not set # CONFIG_QNX4FS_FS is not set @@ -195,7 +209,6 @@ # CONFIG_ROMFS_FS is not set CONFIG_EXT2_FS=y # CONFIG_SYSV_FS is not set -# CONFIG_SYSV_FS_WRITE is not set # CONFIG_UDF_FS is not set # CONFIG_UDF_RW is not set # CONFIG_UFS_FS is not set @@ -243,4 +256,4 @@ # # Kernel hacking # -# CONFIG_MAGIC_SYSRQ is not set +CONFIG_MAGIC_SYSRQ=y diff -u --recursive --new-file v2.4.7/linux/arch/s390/kernel/debug.c linux/arch/s390/kernel/debug.c --- v2.4.7/linux/arch/s390/kernel/debug.c Wed Apr 11 19:02:27 2001 +++ linux/arch/s390/kernel/debug.c Wed Jul 25 14:12:01 2001 @@ -14,7 +14,7 @@ #include #include #include -#include +#include #include #include #include diff -u --recursive --new-file v2.4.7/linux/arch/s390/kernel/entry.S linux/arch/s390/kernel/entry.S --- v2.4.7/linux/arch/s390/kernel/entry.S Wed Jul 25 17:10:18 2001 +++ linux/arch/s390/kernel/entry.S Wed Jul 25 14:12:01 2001 @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -200,8 +201,10 @@ # # check, if bottom-half has to be done # - l %r0,__LC_IRQ_STAT # get softirq_active - n %r0,__LC_IRQ_STAT+4 # and it with softirq_mask + l %r1,processor(%r9) # get cpu number from task struture + sll %r1,L1_CACHE_SHIFT + al %r1,BASED(.Lirq_stat) # get address of irq_stat + icm %r0,15,0(%r1) # test irq_stat[#cpu].__softirq_pending bnz BASED(sysc_handle_bottom_half) # # check, if reschedule is needed @@ -657,10 +660,9 @@ lh %r7,__LC_PGM_ILC # load instruction length GET_CURRENT pgm_no_sv: + la %r3,0x7f lh %r8,__LC_PGM_INT_CODE # N.B. saved int code used later KEEP it - lr %r3,%r8 - la %r0,0x7f - nr %r3,%r0 # clear per-event-bit + nr %r3,%r8 # reload & clear per-event-bit be BASED(pgm_dn) # none of Martins exceptions occurred bypass l %r1,BASED(.Ljump_table) sll %r3,2 @@ -676,8 +678,7 @@ be BASED(pgm_go) # if yes then don't reenable interrupts stosm 24(%r15),0x03 # reenable interrupts pgm_go: basr %r14,%r1 # branch to interrupt-handler -pgm_dn: la %r0,0x80 - nr %r8,%r0 # check for per exception +pgm_dn: n %r8,BASED(.Lc128) # check for per excepton be BASED(pgm_return) la %r2,SP_PTREGS(15) # address of register-save area l %r1,BASED(.Lhandle_per) # load adr. of per handler @@ -713,8 +714,10 @@ # # check, if bottom-half has to be done # - l %r0,__LC_IRQ_STAT # get softirq_active - n %r0,__LC_IRQ_STAT+4 # and it with softirq_mask + l %r1,processor(%r9) # get cpu number from task struture + sll %r1,L1_CACHE_SHIFT + al %r1,BASED(.Lirq_stat) # get address of irq_stat + icm %r0,15,0(%r1) # test irq_stat[#cpu].__softirq_pending bnz BASED(io_handle_bottom_half) io_return_bh: # @@ -843,6 +846,7 @@ .Lc0x2401: .long 0x2401 .Lc0x4000: .long 0x4000 .Lc0xff: .long 0xff +.Lc128: .long 128 /* * Symbol constants @@ -854,6 +858,7 @@ .Lentry_base: .long entry_base .Lext_hash: .long ext_int_hash .Lhandle_per: .long handle_per_exception +.Lirq_stat: .long irq_stat .Ljump_table: .long pgm_check_table .Lschedule: .long schedule .Lclone: .long sys_clone diff -u --recursive --new-file v2.4.7/linux/arch/s390/kernel/head.S linux/arch/s390/kernel/head.S --- v2.4.7/linux/arch/s390/kernel/head.S Wed Jul 25 17:10:18 2001 +++ linux/arch/s390/kernel/head.S Wed Jul 25 14:12:01 2001 @@ -461,7 +461,7 @@ .org 0x10000 startup:basr %r13,0 # get base .LPG1: lctl %c0,%c15,.Lctl-.LPG1(%r13) # load control registers - l %r12,.Lparm1-.LPG1(%r13) # pointer to parameter area + la %r12,parmarea-.LPG1(%r13) # pointer to parameter area # move IPL device to lowcore mvc __LC_IPLDEV(4),IPL_DEVICE-PARMAREA(%r12) @@ -502,9 +502,7 @@ # find out if we have an IEEE fpu # mvc __LC_PGM_NEW_PSW(8),.Lpcfpu-.LPG1(%r13) - ld %f0,.Lflt0-.LPG1(%r13) # load (float) 0.0 - ldr %f2,%f0 - adbr %f0,%f2 # test IEEE add instruction + efpc %r0,0 # test IEEE extract fpc instruction oi 3(%r12),2 # set IEEE fpu flag .Lchkfpu: @@ -514,7 +512,7 @@ mvc __LC_PGM_NEW_PSW(8),.Lpccsp-.LPG1(%r13) la %r0,0 lr %r1,%r0 - la %r2,.Lflt0-.LPG1(%r13) + la %r2,4 csp %r0,%r2 # Test CSP instruction oi 3(%r12),8 # set CSP flag .Lchkcsp: @@ -554,12 +552,7 @@ .Lpcfpu:.long 0x00080000,0x80000000 + .Lchkfpu .Lpccsp:.long 0x00080000,0x80000000 + .Lchkcsp .Lpcmvpg:.long 0x00080000,0x80000000 + .Lchkmvpg -.Lflt0: .double 0 -.Lparm1:.long PARMAREA .L4malign:.long 0xffc00000 -.Lbigmem:.long 0x04000000 -.Lrdstart:.long 0x02000000 -.Lmaxchunk:.long 0x00ffffff .Lmemsize:.long memory_size .Lmflags:.long machine_flags @@ -567,6 +560,7 @@ # params at 10400 (setup.h) # .org PARMAREA +parmarea: .long 0,0 # IPL_DEVICE .long 0,RAMDISK_ORIGIN # INITRD_START .long 0,0x800000 # INITRD_SIZE @@ -578,7 +572,11 @@ # # startup-code, running in virtual mode # +#ifdef CONFIG_SHARED_KERNEL + .org 0x100000 +#else .org 0x10800 +#endif .globl _stext _stext: basr %r13,0 # get base .LPG2: @@ -608,8 +606,8 @@ jo .-4 # branch back, if not finish # check control registers stctl %c0,%c15,0(%r15) - oc 2(1,%r15),.Locbits+5-.LPG2(%r13) # enable sigp external ints. - oc 0(1,%r15),.Locbits+4-.LPG2(%r13) # low addresss proctection + oi 2(%r15),0x20 # enable sigp external interrupts + oi 0(%r15),0x10 # switch on low address protection lctl %c0,%c15,0(%r15) # @@ -622,15 +620,12 @@ basr %r13,0 lpsw .Ldw-.(%r13) # load disabled wait psw # -.Lstart: .long start_kernel .align 8 +.Ldw: .long 0x000a0000,0x00000000 .Lprefix: .long init_S390_lowcore .Linittu: .long init_task_union +.Lstart: .long start_kernel .Lbss_bgn: .long __bss_start .Lbss_end: .long _end -.Locbits: .long 0x01020408,0x10204080 - .align 4 .Laregs: .long 0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0 - .align 8 -.Ldw: .long 0x000a0000,0x00000000 diff -u --recursive --new-file v2.4.7/linux/arch/s390/kernel/irq.c linux/arch/s390/kernel/irq.c --- v2.4.7/linux/arch/s390/kernel/irq.c Wed Jul 25 17:10:18 2001 +++ linux/arch/s390/kernel/irq.c Wed Jul 25 14:12:01 2001 @@ -21,7 +21,7 @@ #include #include #include -#include +#include #include #include #include @@ -119,7 +119,7 @@ */ #ifdef CONFIG_SMP atomic_t global_irq_holder = ATOMIC_INIT(NO_PROC_ID); -atomic_t global_irq_lock; +atomic_t global_irq_lock = ATOMIC_INIT(0); atomic_t global_irq_count = ATOMIC_INIT(0); atomic_t global_bh_count; @@ -188,7 +188,7 @@ } /* Duh, we have to loop. Release the lock to avoid deadlocks */ - clear_bit(0,&global_irq_lock); + atomic_set(&global_irq_lock, 0); for (;;) { if (!--count) { @@ -206,10 +206,8 @@ if (!local_bh_count(cpu) && atomic_read(&global_bh_count)) continue; - /* this works even though global_irq_lock not - a long, but is arch-specific --RR */ - if (!test_and_set_bit(0,&global_irq_lock)) - break; + if (!atomic_compare_and_swap(0, 1, &global_irq_lock)) + break; } } } @@ -246,18 +244,14 @@ static inline void get_irqlock(int cpu) { - /* this works even though global_irq_lock not a long, but is - arch-specific --RR */ - if (test_and_set_bit(0,&global_irq_lock)) { + if (atomic_compare_and_swap(0, 1, &global_irq_lock) != 0) { /* do we already hold the lock? */ if ( cpu == atomic_read(&global_irq_holder)) return; /* Uhhuh.. Somebody else got it. Wait.. */ do { - do { - check_smp_invalidate(cpu); - } while (test_bit(0,&global_irq_lock)); - } while (test_and_set_bit(0,&global_irq_lock)); + check_smp_invalidate(cpu); + } while (atomic_compare_and_swap(0, 1, &global_irq_lock) != 0); } /* * We also to make sure that nobody else is running @@ -391,6 +385,10 @@ EXPORT_SYMBOL(__global_sti); EXPORT_SYMBOL(__global_save_flags); EXPORT_SYMBOL(__global_restore_flags); +EXPORT_SYMBOL(global_irq_holder); +EXPORT_SYMBOL(global_irq_lock); +EXPORT_SYMBOL(global_irq_count); +EXPORT_SYMBOL(global_bh_count); #endif EXPORT_SYMBOL(global_bh_lock); diff -u --recursive --new-file v2.4.7/linux/arch/s390/kernel/process.c linux/arch/s390/kernel/process.c --- v2.4.7/linux/arch/s390/kernel/process.c Wed Apr 11 19:02:28 2001 +++ linux/arch/s390/kernel/process.c Wed Jul 25 14:12:01 2001 @@ -63,8 +63,7 @@ wait_psw.mask = _WAIT_PSW_MASK; wait_psw.addr = (unsigned long) &&idle_wakeup | 0x80000000L; while(1) { - if (softirq_active(smp_processor_id()) & - softirq_mask(smp_processor_id())) { + if (softirq_pending(smp_processor_id())) { do_softirq(); __sti(); if (!current->need_resched) @@ -307,11 +306,11 @@ frame = (struct stack_frame *) (2*PAGE_SIZE + (unsigned long) p) -1; frame = (struct stack_frame *) (((unsigned long) frame)&-8L); - p->thread.regs = &frame->childregs; + p->thread.regs = (struct pt_regs *)&frame->childregs; p->thread.ksp = (unsigned long) frame; - frame->childregs = *regs; + memcpy(&frame->childregs,regs,sizeof(struct pt_regs)); frame->childregs.gprs[15] = new_stackp; - frame->eos = 0; + frame->back_chain = frame->eos = 0; /* new return point is ret_from_sys_call */ frame->gprs[8] = ((unsigned long) &ret_from_fork) | 0x80000000; @@ -466,54 +465,3 @@ #undef last_sched #undef first_sched -/* - * This should be safe even if called from tq_scheduler - * A typical mask would be sigmask(SIGKILL)|sigmask(SIGINT)|sigmask(SIGTERM) or 0. - * - */ -void s390_daemonize(char *name,unsigned long mask,int use_init_fs) -{ - struct fs_struct *fs; - extern struct task_struct *child_reaper; - struct task_struct *this_process=current; - - /* - * If we were started as result of loading a module, close all of the - * user space pages. We don't need them, and if we didn't close them - * they would be locked into memory. - */ - exit_mm(current); - - this_process->session = 1; - this_process->pgrp = 1; - if(name) - { - strncpy(current->comm,name,15); - current->comm[15]=0; - } - else - current->comm[0]=0; - /* set signal mask to what we want to respond */ - siginitsetinv(¤t->blocked,mask); - /* exit_signal isn't set up */ - /* if we inherit from cpu idle */ - this_process->exit_signal=SIGCHLD; - /* if priority=0 schedule can go into a tight loop */ - this_process->policy= SCHED_OTHER; - /* nice goes priority=20-nice; */ - this_process->nice=10; - if(use_init_fs) - { - exit_fs(this_process); /* current->fs->count--; */ - fs = init_task.fs; - current->fs = fs; - atomic_inc(&fs->count); - exit_files(current); - } - write_lock_irq(&tasklist_lock); - /* We want init as our parent */ - REMOVE_LINKS(this_process); - this_process->p_opptr=this_process->p_pptr=child_reaper; - SET_LINKS(this_process); - write_unlock_irq(&tasklist_lock); -} diff -u --recursive --new-file v2.4.7/linux/arch/s390/kernel/s390_ext.c linux/arch/s390/kernel/s390_ext.c --- v2.4.7/linux/arch/s390/kernel/s390_ext.c Wed Apr 11 19:02:28 2001 +++ linux/arch/s390/kernel/s390_ext.c Wed Jul 25 14:12:01 2001 @@ -9,7 +9,7 @@ #include #include -#include +#include #include #include @@ -17,12 +17,13 @@ * Simple hash strategy: index = code & 0xff; * ext_int_hash[index] is the start of the list for all external interrupts * that hash to this index. With the current set of external interrupts - * (0x1202 external call, 0x1004 cpu timer, 0x2401 hwc console and 0x4000 - * iucv) this is always the first element. + * (0x1202 external call, 0x1004 cpu timer, 0x2401 hwc console, 0x4000 + * iucv and 0x2603 pfault) this is always the first element. */ ext_int_info_t *ext_int_hash[256] = { 0, }; ext_int_info_t ext_int_info_timer; ext_int_info_t ext_int_info_hwc; +ext_int_info_t ext_int_pfault; int register_external_interrupt(__u16 code, ext_int_handler_t handler) { ext_int_info_t *p; @@ -39,7 +40,9 @@ p = &ext_int_info_timer; else if (code == 0x2401) /* hwc_init is done too early too */ p = &ext_int_info_hwc; - else + else if (code == 0x2603) /* pfault_init is done too early too */ + p = &ext_int_pfault; + else p = (ext_int_info_t *) kmalloc(sizeof(ext_int_info_t), GFP_ATOMIC); if (p == NULL) @@ -70,7 +73,7 @@ q->next = p->next; else ext_int_hash[index] = p->next; - if (code != 0x1004 && code != 0x2401) + if (code != 0x1004 && code != 0x2401 && code != 0x2603) kfree(p); return 0; } diff -u --recursive --new-file v2.4.7/linux/arch/s390/kernel/s390_ksyms.c linux/arch/s390/kernel/s390_ksyms.c --- v2.4.7/linux/arch/s390/kernel/s390_ksyms.c Wed Apr 11 19:02:28 2001 +++ linux/arch/s390/kernel/s390_ksyms.c Wed Jul 25 14:12:01 2001 @@ -43,6 +43,7 @@ EXPORT_SYMBOL_NOVERS(strncpy); EXPORT_SYMBOL_NOVERS(strnlen); EXPORT_SYMBOL_NOVERS(strrchr); +EXPORT_SYMBOL_NOVERS(strstr); EXPORT_SYMBOL_NOVERS(strtok); EXPORT_SYMBOL_NOVERS(strpbrk); @@ -53,6 +54,8 @@ EXPORT_SYMBOL(__udelay); EXPORT_SYMBOL(kernel_thread); EXPORT_SYMBOL(csum_fold); +EXPORT_SYMBOL(console_mode); +EXPORT_SYMBOL(console_device); #if CONFIG_IP_MULTICAST /* Required for lcs gigabit ethernet multicast support */ diff -u --recursive --new-file v2.4.7/linux/arch/s390/kernel/setup.c linux/arch/s390/kernel/setup.c --- v2.4.7/linux/arch/s390/kernel/setup.c Wed Apr 11 19:02:28 2001 +++ linux/arch/s390/kernel/setup.c Wed Jul 25 14:12:01 2001 @@ -43,6 +43,8 @@ /* * Machine setup.. */ +unsigned int console_mode = 0; +unsigned int console_device = -1; unsigned long memory_size = 0; unsigned long machine_flags = 0; __u16 boot_cpu_addr; @@ -141,6 +143,93 @@ __setup("vmpoff=", vmpoff_setup); /* + * condev= and conmode= setup parameter. + */ + +static int __init condev_setup(char *str) +{ + int vdev; + + vdev = simple_strtoul(str, &str, 0); + if (vdev >= 0 && vdev < 65536) + console_device = vdev; + return 1; +} + +__setup("condev=", condev_setup); + +static int __init conmode_setup(char *str) +{ +#if defined(CONFIG_HWC_CONSOLE) + if (strncmp(str, "hwc", 4) == 0 && !MACHINE_IS_P390) + SET_CONSOLE_HWC; +#endif +#if defined(CONFIG_TN3215_CONSOLE) + if (strncmp(str, "3215", 5) == 0 && (MACHINE_IS_VM || MACHINE_IS_P390)) + SET_CONSOLE_3215; +#endif +#if defined(CONFIG_TN3270_CONSOLE) + if (strncmp(str, "3270", 5) == 0 && (MACHINE_IS_VM || MACHINE_IS_P390)) + SET_CONSOLE_3270; +#endif + return 1; +} + +__setup("conmode=", conmode_setup); + +static void __init conmode_default(void) +{ + char query_buffer[1024]; + char *ptr; + + if (MACHINE_IS_VM) { + cpcmd("QUERY TERM", query_buffer, 1024); + ptr = strstr(query_buffer, "CONMODE"); + /* + * Set the conmode to 3215 so that the device recognition + * will set the cu_type of the console to 3215. If the + * conmode is 3270 and we don't set it back then both + * 3215 and the 3270 driver will try to access the console + * device (3215 as console and 3270 as normal tty). + */ + cpcmd("TERM CONMODE 3215", NULL, 0); + if (ptr == NULL) { +#if defined(CONFIG_HWC_CONSOLE) + SET_CONSOLE_HWC; +#endif + return; + } + if (strncmp(ptr + 8, "3270", 4) == 0) { +#if defined(CONFIG_TN3270_CONSOLE) + SET_CONSOLE_3270; +#elif defined(CONFIG_TN3215_CONSOLE) + SET_CONSOLE_3215; +#elif defined(CONFIG_HWC_CONSOLE) + SET_CONSOLE_HWC; +#endif + } else if (strncmp(ptr + 8, "3215", 4) == 0) { +#if defined(CONFIG_TN3215_CONSOLE) + SET_CONSOLE_3215; +#elif defined(CONFIG_TN3270_CONSOLE) + SET_CONSOLE_3270; +#elif defined(CONFIG_HWC_CONSOLE) + SET_CONSOLE_HWC; +#endif + } + } else if (MACHINE_IS_P390) { +#if defined(CONFIG_TN3215_CONSOLE) + SET_CONSOLE_3215; +#elif defined(CONFIG_TN3270_CONSOLE) + SET_CONSOLE_3270; +#endif + } else { +#if defined(CONFIG_HWC_CONSOLE) + SET_CONSOLE_HWC; +#endif + } +} + +/* * Reboot, halt and power_off routines for non SMP. */ @@ -183,8 +272,6 @@ return; smptrap=1; - printk("Command line is: %s\n", COMMAND_LINE); - /* * Setup lowcore information for boot cpu */ @@ -244,7 +331,6 @@ * "ipldelay=XXX[sm]" sets ipl delay in seconds or minutes */ if (c == ' ' && strncmp(from, "ipldelay=", 9) == 0) { - if (to != command_line) to--; delay = simple_strtoul(from+9, &from, 0); if (*from == 's' || *from == 'S') { delay = delay*1000000; @@ -253,7 +339,7 @@ delay = delay*60*1000000; from++; } - /* now wait for the requestedn amount of time */ + /* now wait for the requested amount of time */ udelay(delay); } cn = *(from++); @@ -261,6 +347,8 @@ break; if (cn == '\n') cn = ' '; /* replace newlines with space */ + if (cn == 0x0d) + cn = ' '; /* replace 0x0d with space */ if (cn == ' ' && c == ' ') continue; /* remove additional spaces */ c = cn; @@ -322,6 +410,9 @@ request_resource(&iomem_resource, res); request_resource(res, &code_resource); request_resource(res, &data_resource); + + /* Setup default console */ + conmode_default(); } void print_cpu_info(struct cpuinfo_S390 *cpuinfo) diff -u --recursive --new-file v2.4.7/linux/arch/s390/kernel/signal.c linux/arch/s390/kernel/signal.c --- v2.4.7/linux/arch/s390/kernel/signal.c Wed Apr 11 19:02:28 2001 +++ linux/arch/s390/kernel/signal.c Wed Jul 25 14:12:01 2001 @@ -332,6 +332,7 @@ /* Set up registers for signal handler */ regs->gprs[15] = (addr_t)frame; regs->psw.addr = FIX_PSW(ka->sa.sa_handler); + regs->psw.mask = _USER_PSW_MASK; } /* Set up to return from userspace. If provided, use a stub already in userspace. */ @@ -358,6 +359,11 @@ #endif /* Martin wants this for pthreads */ regs->gprs[3] = (addr_t)&frame->sc; + + /* We forgot to include these in the sigcontext. + To avoid breaking binary compatibility, they are passed as args. */ + regs->gprs[4] = current->thread.trap_no; + regs->gprs[5] = current->thread.prot_addr; return; give_sigsegv: @@ -414,7 +420,7 @@ siginfo_t *info, sigset_t *oldset, struct pt_regs * regs) { /* Are we from a system call? */ - if (regs->orig_gpr2 >= 0) { + if (regs->trap == __LC_SVC_OLD_PSW) { /* If so, check system call restarting.. */ switch (regs->gprs[2]) { case -ERESTARTNOHAND: @@ -561,7 +567,6 @@ /* FALLTHRU */ default: - lock_kernel(); sigaddset(¤t->pending.signal, signr); recalc_sigpending(current); current->flags |= PF_SIGNALED; diff -u --recursive --new-file v2.4.7/linux/arch/s390/kernel/smp.c linux/arch/s390/kernel/smp.c --- v2.4.7/linux/arch/s390/kernel/smp.c Wed Jul 25 17:10:18 2001 +++ linux/arch/s390/kernel/smp.c Wed Jul 25 14:12:01 2001 @@ -556,6 +556,7 @@ * Activate a secondary processor. */ extern void init_100hz_timer(void); +extern int pfault_token(void); int __init start_secondary(void *cpuvoid) { @@ -568,6 +569,10 @@ /* nothing */ ; /* init per CPU 100 hz timer */ init_100hz_timer(); +#ifdef CONFIG_PFAULT + /* Enable pfault pseudo page faults on this cpu. */ + pfault_init(); +#endif /* cpu_idle will call schedule for us */ return cpu_idle(NULL); } diff -u --recursive --new-file v2.4.7/linux/arch/s390/kernel/time.c linux/arch/s390/kernel/time.c --- v2.4.7/linux/arch/s390/kernel/time.c Tue Feb 13 14:13:44 2001 +++ linux/arch/s390/kernel/time.c Wed Jul 25 14:12:01 2001 @@ -95,9 +95,10 @@ { unsigned long flags; unsigned long usec, sec; - unsigned long lost_ticks = jiffies - wall_jiffies; + unsigned long lost_ticks; read_lock_irqsave(&xtime_lock, flags); + lost_ticks = jiffies - wall_jiffies; usec = do_gettimeoffset(); if (lost_ticks) usec +=(USECS_PER_JIFFY*lost_ticks); diff -u --recursive --new-file v2.4.7/linux/arch/s390/kernel/traps.c linux/arch/s390/kernel/traps.c --- v2.4.7/linux/arch/s390/kernel/traps.c Wed Apr 11 19:02:28 2001 +++ linux/arch/s390/kernel/traps.c Wed Jul 25 14:12:01 2001 @@ -36,6 +36,7 @@ #include #endif #include +#include /* Called from entry.S only */ extern void handle_per_exception(struct pt_regs *regs); @@ -53,6 +54,11 @@ extern pgm_check_handler_t do_page_fault; extern pgm_check_handler_t do_pseudo_page_fault; +#ifdef CONFIG_PFAULT +extern int pfault_init(void); +extern void pfault_fini(void); +extern void pfault_interrupt(struct pt_regs *regs, __u16 error_code); +#endif spinlock_t die_lock; @@ -142,7 +148,7 @@ DO_ERROR(SIGILL, "privileged operation", privileged_op) DO_ERROR(SIGILL, "execute exception", execute_exception) DO_ERROR(SIGSEGV, "addressing exception", addressing_exception) -DO_ERROR(SIGILL, "fixpoint divide exception", divide_exception) +DO_ERROR(SIGFPE, "fixpoint divide exception", divide_exception) DO_ERROR(SIGILL, "translation exception", translation_exception) DO_ERROR(SIGILL, "special operand exception", special_op_exception) DO_ERROR(SIGILL, "operand exception", operand_exception) @@ -154,7 +160,6 @@ int signal = 0; int problem_state=(regs->psw.mask & PSW_PROBLEM_STATE); - lock_kernel(); location = (__u16 *)(regs->psw.addr-S390_lowcore.pgm_ilc); if(problem_state) get_user(*((__u16 *) opcode), location); @@ -197,7 +202,6 @@ } else if (signal) do_trap(interruption_code, signal, "illegal operation", regs, NULL); - unlock_kernel(); } @@ -210,7 +214,6 @@ __u16 *location; int signal = 0; - lock_kernel(); if (regs->psw.mask & PSW_PROBLEM_STATE) { location = (__u16 *)(regs->psw.addr-S390_lowcore.pgm_ilc); get_user(*((__u16 *) opcode), location); @@ -250,7 +253,6 @@ } else if (signal) do_trap(interruption_code, signal, "specification exception", regs, NULL); - unlock_kernel(); } #else DO_ERROR(SIGILL, "specification exception", specification_exception) @@ -262,7 +264,6 @@ __u16 *location; int signal = 0; - lock_kernel(); location = (__u16 *)(regs->psw.addr-S390_lowcore.pgm_ilc); if (MACHINE_HAS_IEEE) __asm__ volatile ("stfpc %0\n\t" @@ -333,7 +334,6 @@ } else if (signal) do_trap(interruption_code, signal, "data exception", regs, NULL); - unlock_kernel(); } @@ -361,8 +361,26 @@ pgm_check_table[0x14] = &do_pseudo_page_fault; pgm_check_table[0x15] = &operand_exception; pgm_check_table[0x1C] = &privileged_op; +#ifdef CONFIG_PFAULT + if (MACHINE_IS_VM) { + /* request the 0x2603 external interrupt */ + if (register_external_interrupt(0x2603, pfault_interrupt) != 0) + panic("Couldn't request external interrupt 0x2603"); + /* + * First try to get pfault pseudo page faults going. + * If this isn't available turn on pagex page faults. + */ + if (pfault_init() != 0) { + /* Tough luck, no pfault. */ + unregister_external_interrupt(0x2603, + pfault_interrupt); + cpcmd("SET PAGEX ON", NULL, 0); + } + } +#else if (MACHINE_IS_VM) - cpcmd("SET PAGEX ON", NULL, 0); + cpcmd("SET PAGEX ON", NULL, 0); +#endif } diff -u --recursive --new-file v2.4.7/linux/arch/s390/mm/Makefile linux/arch/s390/mm/Makefile --- v2.4.7/linux/arch/s390/mm/Makefile Tue Feb 13 14:13:44 2001 +++ linux/arch/s390/mm/Makefile Wed Jul 25 14:12:01 2001 @@ -1,5 +1,5 @@ # -# Makefile for the linux i386-specific parts of the memory manager. +# Makefile for the linux s390-specific parts of the memory manager. # # Note! Dependencies are done automagically by 'make dep', which also # removes any old dependencies. DON'T put your own dependencies here diff -u --recursive --new-file v2.4.7/linux/arch/s390/mm/fault.c linux/arch/s390/mm/fault.c --- v2.4.7/linux/arch/s390/mm/fault.c Wed Apr 11 19:02:27 2001 +++ linux/arch/s390/mm/fault.c Wed Jul 25 14:12:01 2001 @@ -22,6 +22,7 @@ #include #include #include +#include #include #include @@ -52,25 +53,14 @@ unsigned long address; unsigned long fixup; int write; - unsigned long psw_mask; - unsigned long psw_addr; int si_code = SEGV_MAPERR; int kernel_address = 0; - /* - * get psw mask of Program old psw to find out, - * if user or kernel mode - */ - - psw_mask = S390_lowcore.program_old_psw.mask; - psw_addr = S390_lowcore.program_old_psw.addr; - /* * get the failing address * more specific the segment and page table portion of * the address */ - address = S390_lowcore.trans_exc_code&0x7ffff000; tsk = current; @@ -185,7 +175,7 @@ up_read(&mm->mmap_sem); /* User mode accesses just cause a SIGSEGV */ - if (psw_mask & PSW_PROBLEM_STATE) { + if (regs->psw.mask & PSW_PROBLEM_STATE) { struct siginfo si; tsk->thread.prot_addr = address; tsk->thread.trap_no = error_code; @@ -243,7 +233,7 @@ out_of_memory: up_read(&mm->mmap_sem); printk("VM: killing process %s\n", tsk->comm); - if (psw_mask & PSW_PROBLEM_STATE) + if (regs->psw.mask & PSW_PROBLEM_STATE) do_exit(SIGKILL); goto no_context; @@ -259,7 +249,7 @@ force_sig(SIGBUS, tsk); /* Kernel mode? Handle exceptions or die */ - if (!(psw_mask & PSW_PROBLEM_STATE)) + if (!(regs->psw.mask & PSW_PROBLEM_STATE)) goto no_context; } @@ -275,25 +265,17 @@ static spinlock_t pseudo_wait_spinlock; /* spinlock to protect lock queue */ /* - * This routine handles pseudo page faults. + * This routine handles 'pagex' pseudo page faults. */ asmlinkage void do_pseudo_page_fault(struct pt_regs *regs, unsigned long error_code) { - DECLARE_WAITQUEUE(wait, current); pseudo_wait_t wait_struct; pseudo_wait_t *ptr, *last, *next; - unsigned long psw_mask; unsigned long address; int kernel_address; /* - * get psw mask of Program old psw to find out, - * if user or kernel mode - */ - psw_mask = S390_lowcore.program_old_psw.mask; - - /* * get the failing address * more specific the segment and page table portion of * the address @@ -332,7 +314,7 @@ spin_unlock(&pseudo_wait_spinlock); } else { /* Pseudo page faults in kernel mode is a bad idea */ - if (!(psw_mask & PSW_PROBLEM_STATE)) { + if (!(regs->psw.mask & PSW_PROBLEM_STATE)) { /* * VM presents pseudo page faults if the interrupted * state was not disabled for interrupts. So we can @@ -383,4 +365,127 @@ wait_event(wait_struct.queue, wait_struct.resolved); } } - + +#ifdef CONFIG_PFAULT +/* + * 'pfault' pseudo page faults routines. + */ +static int pfault_disable = 0; + +static int __init nopfault(char *str) +{ + pfault_disable = 1; + return 1; +} + +__setup("nopfault", nopfault); + +typedef struct { + __u16 refdiagc; + __u16 reffcode; + __u16 refdwlen; + __u16 refversn; + __u64 refgaddr; + __u64 refselmk; + __u64 refcmpmk; + __u64 reserved; +} __attribute__ ((packed)) pfault_refbk_t; + +int pfault_init(void) +{ + pfault_refbk_t refbk = + { 0x258, 0, 5, 2, __LC_KERNEL_STACK, 1ULL << 48, 1ULL << 48, 0ULL }; + int rc; + + if (pfault_disable) + return -1; + __asm__ __volatile__( + " diag %1,%0,0x258\n" + "0: j 2f\n" + "1: la %0,8\n" + "2:\n" + ".section __ex_table,\"a\"\n" + " .align 4\n" + " .long 0b,1b\n" + ".previous" + : "=d" (rc) : "a" (&refbk) : "cc" ); + __ctl_set_bit(0, 9); + return rc; +} + +void pfault_fini(void) +{ + pfault_refbk_t refbk = + { 0x258, 1, 5, 2, 0ULL, 0ULL, 0ULL, 0ULL }; + + if (pfault_disable) + return; + __ctl_clear_bit(0,9); + __asm__ __volatile__( + " diag %0,0,0x258\n" + "0:\n" + ".section __ex_table,\"a\"\n" + " .align 4\n" + " .long 0b,0b\n" + ".previous" + : : "a" (&refbk) : "cc" ); +} + +asmlinkage void +pfault_interrupt(struct pt_regs *regs, __u16 error_code) +{ + DECLARE_WAITQUEUE(wait, current); + struct task_struct *tsk; + wait_queue_head_t queue; + wait_queue_head_t *qp; + __u16 subcode; + + /* + * Get the external interruption subcode & pfault + * initial/completion signal bit. VM stores this + * in the 'cpu address' field associated with the + * external interrupt. + */ + subcode = S390_lowcore.cpu_addr; + if ((subcode & 0xff00) != 0x06) + return; + + /* + * Get the token (= address of kernel stack of affected task). + */ + tsk = (struct task_struct *) + (*((unsigned long *) __LC_PFAULT_INTPARM) - THREAD_SIZE); + + if (subcode & 0x0080) { + /* signal bit is set -> a page has been swapped in by VM */ + qp = (wait_queue_head_t *) + xchg(&tsk->thread.pfault_wait, -1); + if (qp != NULL) { + /* Initial interrupt was faster than the completion + * interrupt. pfault_wait is valid. Set pfault_wait + * back to zero and wake up the process. This can + * safely be done because the task is still sleeping + * and can't procude new pfaults. */ + tsk->thread.pfault_wait = 0ULL; + wake_up(qp); + } + } else { + /* signal bit not set -> a real page is missing. */ + init_waitqueue_head (&queue); + qp = (wait_queue_head_t *) + xchg(&tsk->thread.pfault_wait, (addr_t) &queue); + if (qp != NULL) { + /* Completion interrupt was faster than the initial + * interrupt (swapped in a -1 for pfault_wait). Set + * pfault_wait back to zero and exit. This can be + * done safely because tsk is running in kernel + * mode and can't produce new pfaults. */ + tsk->thread.pfault_wait = 0ULL; + } + + /* go to sleep */ + wait_event(queue, tsk->thread.pfault_wait == 0ULL); + } +} +#endif + diff -u --recursive --new-file v2.4.7/linux/arch/s390/tools/dasdfmt/Makefile linux/arch/s390/tools/dasdfmt/Makefile --- v2.4.7/linux/arch/s390/tools/dasdfmt/Makefile Tue Feb 13 14:13:44 2001 +++ linux/arch/s390/tools/dasdfmt/Makefile Wed Dec 31 16:00:00 1969 @@ -1,9 +0,0 @@ -all: dasdfmt - -dasdfmt: dasdfmt.c - $(CC) -o $@ $^ - $(STRIP) $@ - -clean: - rm -f dasdfmt - diff -u --recursive --new-file v2.4.7/linux/arch/s390/tools/dasdfmt/dasdfmt.8 linux/arch/s390/tools/dasdfmt/dasdfmt.8 --- v2.4.7/linux/arch/s390/tools/dasdfmt/dasdfmt.8 Fri Mar 2 11:12:06 2001 +++ linux/arch/s390/tools/dasdfmt/dasdfmt.8 Wed Dec 31 16:00:00 1969 @@ -1,68 +0,0 @@ -.TH DASDFMT 8 "Tue Jan 25 2000" -.UC 4 -.SH NAME -dasdfmt \- formatting of DSAD (ECKD) disk drives. -.SH SYNOPSIS -\fBdasdfmt\fR [-tvyLV] [-b \fIblockSize\fR] [-l \fIdiskLabel\fR] \fIdiskSpec\fR -.SH DESCRIPTION -\fBdasdfmt\fR formats a DASD (ECKD) disk drive to prepare it -for usage with Linux for S/390. \fBWARNING\fR: Incautious usage of -\fBdasdfmt\fR can result in \fBLOSS OF DATA\fR. - -.SH OPTIONS -.TP -\fB-t\fR -Disables any modification of the disk drive. \fBdasdfmt\fR just prints -out, what it \fBwould\fR do. - -.TP -\fB-v\fR -Increases verbosity. - -.TP -\fB-y\fR -Start formatting without further user-confirmation. - -.TP -\fB-L\fR -Omit the writing of a disk label after formatting. - -.TP -\fB-V\fR -Print version number and exit. - -.TP -\fB-b\fR \fIblockSize\fR -Specify blocksize to be used. \fIblocksize\fR must be a positive integer -and always be a power of two. Due due some limitations in the driver, -it is \fBstrongly\fR recommended to use a \fIblockSize\fR of \fI4096\fR. - -.TP -\fB-l\fR \fIdiskLabel\fR -Specify the label to be written to disk after formatting. If no label is -specified, a sensible default is used. \fIdiskLabel\fR is interpreted as -ASCII string and is automatically converted to EBCDIC. - -.TP -\fIdiskSpec\fR -This parameter specified the device to be formatted. It also can be -given in two variants: -.sp - \fB-f\fR \fB/dev/dasd\fR\fIX\fR -.br -or -.br - \fB-n\fR \fIdevnum\fR -.sp -The first form uses the commonly used -.SM UNIX -device notation where \fIX\fR is a single lowercase letter. -The second form uses simply the device number. - -.SH BUGS -None so far ;-) - -.SH AUTHOR -.nf -This man-page was written by Fritz Elfert -.fi diff -u --recursive --new-file v2.4.7/linux/arch/s390/tools/dasdfmt/dasdfmt.c linux/arch/s390/tools/dasdfmt/dasdfmt.c --- v2.4.7/linux/arch/s390/tools/dasdfmt/dasdfmt.c Wed Apr 11 19:02:27 2001 +++ linux/arch/s390/tools/dasdfmt/dasdfmt.c Wed Dec 31 16:00:00 1969 @@ -1,839 +0,0 @@ -/* - * - * dasdfmt.c - * - * S390 version - * Copyright (C) 1999,2000 IBM Corporation - * Author(s): Utz Bacher, - * - * Device-in-use-checks by Fritz Elfert, - * Compatible Disk Layout enhancements by Carsten Otte, - * - * Still to do: - * detect non-switch parameters ("dasdfmt -n 170 XY") and complain about them - */ - -/* #define _LINUX_BLKDEV_H */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#define __KERNEL__ /* we want to use kdev_t and not have to define it */ -#include -#undef __KERNEL__ - -#include -#include -#include - -#define EXIT_MISUSE 1 -#define EXIT_BUSY 2 -#define TEMPFILENAME "/tmp/ddfXXXXXX" -#define TEMPFILENAMECHARS 8 /* 8 characters are fixed in all temp filenames */ -#define SLASHDEV "/dev/" -#define PROC_DASD_DEVICES "/proc/dasd/devices" -/* _PATH_MOUNTED is /etc/mtab - /proc/mounts does not show root-fs correctly */ -#define PROC_MOUNTS _PATH_MOUNTED -#define PROC_SWAPS "/proc/swaps" -#define DASD_DRIVER_NAME "dasd" -#define LABEL_LENGTH 10 -#define PROC_LINE_LENGTH 80 -#define ERR_LENGTH 80 - -#define MAX_FILELEN NAME_MAX+PATH_MAX - -#define GIVEN_DEVNO 1 -#define GIVEN_MAJOR 2 -#define GIVEN_MINOR 4 - -#define CHECK_START 1 -#define CHECK_END 2 -#define CHECK_BLKSIZE 4 -#define CHECK_ALL ~0 - -#define ERRMSG(x...) {fflush(stdout);fprintf(stderr,x);} -#define ERRMSG_EXIT(ec,x...) {fflush(stdout);fprintf(stderr,x);exit(ec);} - -#define CHECK_SPEC_MAX_ONCE(i,str) \ - {if (i>1) \ - ERRMSG_EXIT(EXIT_MISUSE,"%s: " str " " \ - "can only be specified once\n",prog_name);} - -#define PARSE_PARAM_INTO(x,param,base,str) \ - {x=(int)strtol(param,&endptr,base); \ - if (*endptr) \ - ERRMSG_EXIT(EXIT_MISUSE,"%s: " str " " \ - "is in invalid format\n",prog_name);} - -char *prog_name;/*="dasdfmt";*/ -char tempfilename[]=TEMPFILENAME; - -__u8 _ascebc[256] = -{ - /*00 NUL SOH STX ETX EOT ENQ ACK BEL */ - 0x00, 0x01, 0x02, 0x03, 0x37, 0x2D, 0x2E, 0x2F, - /*08 BS HT LF VT FF CR SO SI */ - /* ->NL */ - 0x16, 0x05, 0x15, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, - /*10 DLE DC1 DC2 DC3 DC4 NAK SYN ETB */ - 0x10, 0x11, 0x12, 0x13, 0x3C, 0x3D, 0x32, 0x26, - /*18 CAN EM SUB ESC FS GS RS US */ - /* ->IGS ->IRS ->IUS */ - 0x18, 0x19, 0x3F, 0x27, 0x22, 0x1D, 0x1E, 0x1F, - /*20 SP ! " # $ % & ' */ - 0x40, 0x5A, 0x7F, 0x7B, 0x5B, 0x6C, 0x50, 0x7D, - /*28 ( ) * + , - . / */ - 0x4D, 0x5D, 0x5C, 0x4E, 0x6B, 0x60, 0x4B, 0x61, - /*30 0 1 2 3 4 5 6 7 */ - 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, - /*38 8 9 : ; < = > ? */ - 0xF8, 0xF9, 0x7A, 0x5E, 0x4C, 0x7E, 0x6E, 0x6F, - /*40 @ A B C D E F G */ - 0x7C, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, - /*48 H I J K L M N O */ - 0xC8, 0xC9, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, - /*50 P Q R S T U V W */ - 0xD7, 0xD8, 0xD9, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, - /*58 X Y Z [ \ ] ^ _ */ - 0xE7, 0xE8, 0xE9, 0xBA, 0xE0, 0xBB, 0xB0, 0x6D, - /*60 ` a b c d e f g */ - 0x79, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, - /*68 h i j k l m n o */ - 0x88, 0x89, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, - /*70 p q r s t u v w */ - 0x97, 0x98, 0x99, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, - /*78 x y z { | } ~ DL */ - 0xA7, 0xA8, 0xA9, 0xC0, 0x4F, 0xD0, 0xA1, 0x07, - /*80*/ - 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, - /*88*/ - 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, - /*90*/ - 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, - /*98*/ - 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, - /*A0*/ - 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, - /*A8*/ - 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, - /*B0*/ - 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, - /*B8*/ - 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, - /*C0*/ - 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, - /*C8*/ - 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, - /*D0*/ - 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, - /*D8*/ - 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, - /*E0 sz */ - 0x3F, 0x59, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, - /*E8*/ - 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, - /*F0*/ - 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, - /*F8*/ - 0x90, 0x3F, 0x3F, 0x3F, 0x3F, 0xEA, 0x3F, 0xFF -}; - -void convert_label(char *str) -{ - int i; - for (i=0;i] [-b ] [] " \ - "\n\n",prog_name); -#else /* RANGE_FORMATTING */ - printf("Usage: %s [-htvyCLV] [-l