From aa546d10dd1c92c770f2bba56a140b87c1dc05c0 Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Fri, 23 Nov 2007 15:21:51 -0500 Subject: [PATCH] Linux 2.2.17pre13 o Fix compile errors on userhelper (Several people) o Small Alpha update/fixes (Jay Estabrook) o Add bootup documentation (H Peter Anvin) o S/390 partial merge of updates (Martin Schwidefsky) o Bonding driver fixes (Andreas Steinmetz) o Geert changed address (Geert Uytterhoeven) --- CREDITS | 2 +- Documentation/Changes | 2 +- Documentation/Debugging390.txt | 103 +- Documentation/fb/00-INDEX | 3 +- Documentation/fb/framebuffer.txt | 2 +- Documentation/fb/internals.txt | 2 +- Documentation/i386/boot.txt | 381 ++ Documentation/serial-console.txt | 6 +- Makefile | 2 +- Rules.make | 3 + arch/alpha/config.in | 30 +- arch/alpha/kernel/sys_mikasa.c | 16 +- arch/alpha/kernel/sys_noritake.c | 93 +- arch/m68k/amiga/chipram.c | 3 +- arch/m68k/tools/amiga/dmesg.c | 3 +- arch/s390/Makefile | 2 +- arch/s390/boot/Makefile | 2 +- arch/s390/defconfig | 11 +- arch/s390/kernel/debug.c | 10 +- arch/s390/kernel/debug.h | 55 - arch/s390/kernel/entry.S | 6 +- arch/s390/kernel/head.S | 534 ++- arch/s390/kernel/irq.c | 6 +- arch/s390/kernel/mathemu.c | 114 +- arch/s390/kernel/process.c | 7 +- arch/s390/kernel/s390_ksyms.c | 50 +- arch/s390/kernel/s390io.c | 104 +- arch/s390/kernel/s390mach.c | 4 +- arch/s390/kernel/setup.c | 21 +- arch/s390/kernel/signal.c | 6 +- arch/s390/kernel/smp.c | 14 +- arch/s390/kernel/time.c | 10 +- arch/s390/lib/delay.c | 35 +- arch/s390/mm/fault.c | 23 +- arch/s390/tools/dasdfmt/Makefile | 4 +- arch/s390/tools/dasdfmt/dasdfmt.8 | 28 +- arch/s390/tools/dasdfmt/dasdfmt.c | 211 +- arch/s390/tools/hwc_cntl_key/hwc_cntl_key.c | 2 +- arch/s390/tools/silo/silo.c | 2 +- drivers/char/console.c | 2 +- drivers/net/Space.c | 6 + drivers/net/a2065.c | 3 +- drivers/net/a2065.h | 3 +- drivers/net/ariadne.c | 3 +- drivers/net/ariadne.h | 3 +- drivers/net/bonding.c | 25 +- drivers/net/de4x5.c | 3 +- drivers/net/hydra.c | 2 +- drivers/s390/Config.in | 2 +- drivers/s390/Makefile | 6 +- drivers/s390/block/Makefile | 24 +- drivers/s390/block/dasd.c | 3509 ++++++++++++------- drivers/s390/block/dasd.h | 10 + drivers/s390/block/dasd_3370_erp.c | 105 + drivers/s390/block/dasd_3990_erp.c | 9 +- drivers/s390/block/dasd_9336_erp.c | 64 + drivers/s390/block/dasd_9343_erp.c | 9 +- drivers/s390/block/dasd_ccwstuff.c | 546 --- drivers/s390/block/dasd_ccwstuff.h | 11 - drivers/s390/block/dasd_diag.c | 555 +++ drivers/s390/block/dasd_diag.h | 67 + drivers/s390/block/dasd_eckd.c | 1101 +++--- drivers/s390/block/dasd_eckd.h | 286 ++ drivers/s390/block/dasd_eckd_erp.c | 14 +- drivers/s390/block/dasd_erp.c | 77 - drivers/s390/block/dasd_erp.h | 32 - drivers/s390/block/dasd_fba.c | 460 +-- drivers/s390/block/dasd_fba.h | 70 + drivers/s390/block/dasd_mdsk.c | 366 -- drivers/s390/block/dasd_mdsk.h | 63 - drivers/s390/block/dasd_proc.c | 135 - drivers/s390/block/dasd_profile.c | 212 -- drivers/s390/block/dasd_setup.c | 343 -- drivers/s390/block/dasd_types.h | 359 -- drivers/s390/ccwcache.c | 381 ++ drivers/s390/char/con3215.c | 172 +- drivers/s390/char/hwc_tty.c | 8 +- drivers/s390/net/ctc.c | 53 +- drivers/s390/net/iucv.c | 26 +- include/asm-s390/atomic.h | 35 +- include/asm-s390/bitops.h | 60 +- include/asm-s390/ccwcache.h | 88 + include/asm-s390/dasd.h | 253 ++ include/asm-s390/debug.h | 120 + include/asm-s390/delay.h | 5 +- include/asm-s390/irq.h | 27 +- include/asm-s390/pgtable.h | 27 +- include/asm-s390/processor.h | 24 +- include/asm-s390/queue.h | 9 + include/asm-s390/s390io.h | 3 +- include/asm-s390/setup.h | 1 + include/asm-s390/spinlock.h | 49 +- include/asm-s390/string.h | 7 +- include/asm-s390/uaccess.h | 137 +- include/asm-s390/ucontext.h | 1 + include/linux/dasd.h | 241 -- include/linux/kmod.h | 2 + init/main.c | 15 +- net/core/dev.c | 4 + scripts/makelst | 21 + 100 files changed, 6894 insertions(+), 5272 deletions(-) create mode 100644 Documentation/i386/boot.txt delete mode 100644 arch/s390/kernel/debug.h create mode 100644 drivers/s390/block/dasd.h create mode 100644 drivers/s390/block/dasd_3370_erp.c create mode 100644 drivers/s390/block/dasd_9336_erp.c delete mode 100644 drivers/s390/block/dasd_ccwstuff.c delete mode 100644 drivers/s390/block/dasd_ccwstuff.h create mode 100644 drivers/s390/block/dasd_diag.c create mode 100644 drivers/s390/block/dasd_diag.h create mode 100644 drivers/s390/block/dasd_eckd.h delete mode 100644 drivers/s390/block/dasd_erp.c delete mode 100644 drivers/s390/block/dasd_erp.h create mode 100644 drivers/s390/block/dasd_fba.h delete mode 100644 drivers/s390/block/dasd_mdsk.c delete mode 100644 drivers/s390/block/dasd_mdsk.h delete mode 100644 drivers/s390/block/dasd_proc.c delete mode 100644 drivers/s390/block/dasd_profile.c delete mode 100644 drivers/s390/block/dasd_setup.c delete mode 100644 drivers/s390/block/dasd_types.h create mode 100644 drivers/s390/ccwcache.c create mode 100644 include/asm-s390/ccwcache.h create mode 100644 include/asm-s390/dasd.h create mode 100644 include/asm-s390/debug.h delete mode 100644 include/linux/dasd.h create mode 100644 scripts/makelst diff --git a/CREDITS b/CREDITS index 1be684dbcb58..44b8e4fe5be4 100644 --- a/CREDITS +++ b/CREDITS @@ -2124,7 +2124,7 @@ S: Germany N: Geert Uytterhoeven E: geert@linux-m68k.org -W: http://www.cs.kuleuven.ac.be/~geert/ +W: http://home.tvd.be/cr26864/ P: 1024/EC4A1EE1 8B 88 38 35 88 1E 95 A1 CD 9E AE DC 4B 4A 2F 41 D: m68k/Amiga and PPC/CHRP Longtrail coordinator D: Frame buffer device and XF68_FBDev maintainer diff --git a/Documentation/Changes b/Documentation/Changes index a22e2da9b909..405b900ac5b8 100644 --- a/Documentation/Changes +++ b/Documentation/Changes @@ -753,7 +753,7 @@ Fbset ===== The 2.1 release: -http://www.cs.kuleuven.ac.be/~geert/bin/fbset-2.1.tar.gz +http://home.tvd.be/cr26864/Linux/fbdev/ PCI utils ========= diff --git a/Documentation/Debugging390.txt b/Documentation/Debugging390.txt index 7c67c06d0220..6123b097dcf5 100644 --- a/Documentation/Debugging390.txt +++ b/Documentation/Debugging390.txt @@ -520,9 +520,46 @@ main(int argc,char *argv[]) } +New compiler changes +==================== + +main(int argc,char *argv[]) +{ + 4004fc: 90 7f f0 1c stm %r7,%r15,28(%r15) + 400500: a7 d5 00 04 bras %r13,400508 + 400504: 00 40 04 f4 .long 0x004004f4 + # compiler now puts constant pool in code to so it saves an instruction + 400508: 18 0f lr %r0,%r15 + 40050a: a7 fa ff a0 ahi %r15,-96 + 40050e: 50 00 f0 00 st %r0,0(%r15) + return(test(5)); + 400512: 58 10 d0 00 l %r1,0(%r13) + 400516: a7 28 00 05 lhi %r2,5 + 40051a: 0d e1 basr %r14,%r1 + # compiler adds 1 extra instruction to epilogue this is done to + # avoid processor pipeline stalls owing to data dependencies on g5 & + # above as register 14 in the old code was needed directly after being loaded + # by the lm %r11,%r15,140(%r15) for the br %14. + 40051c: 58 40 f0 98 l %r4,152(%r15) + 400520: 98 7f f0 7c lm %r7,%r15,124(%r15) + 400524: 07 f4 br %r4 +} + +Hartmut ( our compiler developer ) also has been threatening to take out the +stack backchain in optimised code as this also causes pipeline stalls, you +have been warned. + + + Compiling programs for debugging on Linux for S390 ================================================== -Make sure that the gcc is compiling & linking with the -g flag on. +Make sure that the gcc is compiling & linking with the -g flag on +this generates plain old gnu stabs, don't use +-ggdb, -gxcoff+ or any other silly option these other options more than +likely don't work ( we haven't tested them ), -gstabs is supposed to add +extra extensions to the debugging info for debugging c++ we haven't got +round to testing this yet. + This is typically done adding/appending the flags -g to the CFLAGS & LDFLAGS variables Makefile of the program concerned. @@ -695,6 +732,39 @@ extern inline void spin_lock(spinlock_t *lp) 6) If debugging under VM go down to that section in the document for more info. +I now have a tool which takes the pain out of --adjust-vma +& you are able to do something like +make /arch/s390/kernel/traps.lst +& it automatically generates the correctly relocated entries for +the text segment in traps.lst. + +Add the following lines to you Rules.make +%.lst: %.c + $(CC) $(CFLAGS) $(EXTRA_CFLAGS) $(CFLAGS_$@) -g -c -o $*.o $< + $(TOPDIR)/scripts/makelst $* $(TOPDIR) $(OBJDUMP) + +Copy the code snippet below into the scripts directory in a file called makelst +it is'nt very pretty but it works & dont forget to chmod 755 makelst +to make it an executable. +# $(CC) $(CFLAGS) $(EXTRA_CFLAGS) $(CFLAGS_$@) -g -c -o $*.o $< +# $(TOPDIR)/scripts/makelst $* $(TOPDIR) $(OBJDUMP) +# +# Copyright (C) 2000 IBM Corporation +# Author(s): DJ Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com) +# + +t1=`$3 --syms $2/$1.o | grep .text | grep " F " | head -n 1` +t2=`echo $t1 | gawk '{ print $6 }'` +t3=`grep $t2 $2/System.map` +t4=`echo $t3 | gawk '{ print $1 }'` +t5=`echo $t1 | gawk '{ print $1 }'` +t6=`echo $t4 - $t5 | sed s/a/A/ | sed s/b/B/ | sed s/c/C/ | sed s/d/D/ | sed s/e/E/ | sed s/f/F/` +t7=`( echo ibase=16 ; echo $t6 ) | bc` +$3 --source --adjust-vma=$t7 $2/$1.o > $2/$1.lst + + + + strace: ------- Q. What is it ? @@ -941,6 +1011,9 @@ TR BR will trace branches into or out of an address. e.g. TR BR INTO 0 is often quite useful if a program is getting awkward & deciding to branch to 0 & crashing as this will stop at the address before in jumps to 0. +TR I R
RUN cmd d g +single steps a range of addresses but stays running & +displays the gprs on each step. @@ -992,6 +1065,9 @@ script with breakpoints on every kernel procedure, this isn't a good idea because there are thousands of these routines & VM can only set 255 breakpoints at a time so you nearly had to spend as long pruning the file down as you would entering the msg's by hand ),however, the trick might be useful for a single object file. +On linux'es 3270 emulator x3270 there is a very useful option under the file ment +Save Screens In File this is very good of keeping a copy of traces. + Tracing Program Exceptions @@ -1436,9 +1512,9 @@ Ingo's favourite trick is tracing all the IO's & CCWS & spooling them into the r VM guest so he can ftp the logfile back to his own machine.I'll do a small bit of this & give you a look at the output. -1) Spool stdout to VM guest linux4's reader -SP PRT TO * -2) Fill linux4's reader with the trace +1) Spool stdout to VM reader +SP PRT TO (another vm guest ) or * for the local vm guest +2) Fill the reader with the trace TR IO 7c08-7c09 INST INT CCW PRT RUN 3) Start up linux i 00c @@ -1775,7 +1851,9 @@ Breakpoint 2 at 0x4d87a4: file top.c, line 2609. LDD === -This is a program which lists the shared libraries which a library needs. +This is a program which lists the shared libraries which a library needs, +Note you also get the relocations of the shared library text segments which +help when using objdump --source. e.g. ldd ./gdb outputs @@ -1784,6 +1862,21 @@ libm.so.6 => /lib/libm.so.6 (0x4005e000) libc.so.6 => /lib/libc.so.6 (0x40084000) /lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x40000000) + +Debugging shared libraries +========================== +Most programs use shared libraries, however it can be very painful +when you single step instruction into a function like printf for the +first time & you end up in functions like _dl_runtime_resolve this is +the ld.so doing lazy binding, lazy binding is a concept in ELF where +shared library functions are not loaded into memory unless they are +actually used, great for saving memory but a pain to debug. +To get around this either relink the program -static or exit gdb type +export LD_BIND_NOW=true this will stop lazy binding & restart the gdb'ing +the program in question. + + + Debugging modules ================= As modules are dynamically loaded into the kernel their address can be diff --git a/Documentation/fb/00-INDEX b/Documentation/fb/00-INDEX index 4140afb88c26..4bdd38e1484d 100644 --- a/Documentation/fb/00-INDEX +++ b/Documentation/fb/00-INDEX @@ -1,8 +1,7 @@ Index of files in Documentation/fb. If you think something about frame buffer devices needs an entry here, needs correction or you've written one please mail me. - Geert Uytterhoeven - + Geert Uytterhoeven 00-INDEX - this file diff --git a/Documentation/fb/framebuffer.txt b/Documentation/fb/framebuffer.txt index 644a007a57e7..c268d025a40b 100644 --- a/Documentation/fb/framebuffer.txt +++ b/Documentation/fb/framebuffer.txt @@ -1,7 +1,7 @@ The Frame Buffer Device ----------------------- -Maintained by Geert Uytterhoeven (Geert.Uytterhoeven@cs.kuleuven.ac.be) +Maintained by Geert Uytterhoeven Last revised: November 7, 1998 diff --git a/Documentation/fb/internals.txt b/Documentation/fb/internals.txt index 7a6b9e99c0d1..a73d721d7bba 100644 --- a/Documentation/fb/internals.txt +++ b/Documentation/fb/internals.txt @@ -2,7 +2,7 @@ This is a first start for some documentation about frame buffer device internals. -Geert Uytterhoeven , 21 July 1998 +Geert Uytterhoeven , 21 July 1998 -------------------------------------------------------------------------------- diff --git a/Documentation/i386/boot.txt b/Documentation/i386/boot.txt new file mode 100644 index 000000000000..5b600161d2c3 --- /dev/null +++ b/Documentation/i386/boot.txt @@ -0,0 +1,381 @@ + THE LINUX/I386 BOOT PROTOCOL + ---------------------------- + + H. Peter Anvin + Updated as of protocol version 2.02 + +On the i386 platform, the Linux kernel uses a rather complicated boot +convention. This has evolved partially due to historical aspects, as +well as the desire in the early days to have the kernel itself be a +bootable image, the complicated PC memory model and due to changed +expectations in the PC industry caused by the effective demise of +real-mode DOS as a mainstream operating system. + +Currently, four versions of the Linux/i386 boot protocol exist. + +Old kernels: zImage/Image support only. Some very early kernels + may not even support a command line. + +Protocol 2.00: Added bzImage and initrd support, as well as a + formalized way to communicate between the boot loader + and the kernel. + +Protocol 2.01: Added a heap overrun warning. + +Protocol 2.02: New command line protocol. Lower the + conventional-memory ceiling. zImage deprecated but + still supported. + + +**** MEMORY LAYOUT + +The traditional memory map for the kernel loader, used for Image or +zImage kernels, typically looks like: + + | | +0A0000 +------------------------+ + | Reserved for BIOS | Do not use. Reserved for BIOS EBDA. +09A000 +------------------------+ + | Stack/heap/cmdline | For use by the kernel real-mode code. +098000 +------------------------+ + | Kernel setup | The kernel real-mode code. +090200 +------------------------+ + | Kernel boot sector | The kernel legacy boot sector. +090000 +------------------------+ + | Protected-mode kernel | The bulk of the kernel image. +010000 +------------------------+ + | Boot loader | <- Boot sector entry point 0000:7C00 +001000 +------------------------+ + | Reserved for MBR/BIOS | +000800 +------------------------+ + | Typically used by MBR | +000600 +------------------------+ + | BIOS use only | +000000 +------------------------+ + + +When using bzImage, the protected-mode kernel was relocated to +0x100000 ("high memory"), and the kernel real-mode block (boot sector, +setup, and stack/heap) was made relocatable to any address between +0x10000 and end of low memory. Unfortunately, in protocols 2.00 and +2.01 the command line is still required to live in the 0x9XXXX memory +range, and that memory range is still overwritten by the early kernel. +The 2.02 protocol fixes that. + +It is desirable to keep the "memory ceiling" -- the highest point in +low memory touched by the boot loader -- as low as possible, since +some newer BIOSes have begun to allocate some rather large amounts of +memory, called the Extended BIOS Data Area, near the top of low +memory. The boot loader should use the "INT 12h" BIOS call to verify +how much low memory is available. + +Unfortunately, if INT 12h reports that the amount of memory is too +low, there is usually nothing the boot loader can do but to report an +error to the user. The boot loader should therefore be designed to +take up as little space in low memory as it reasonably can. For +zImage or old bzImage kernels, which need data written into the +0x90000 segment, the boot loader should make sure not to use memory +above the 0x9A000 point; too many BIOSes will break above that point. + + +**** THE REAL-MODE KERNEL HEADER + +In the following text, and anywhere in the kernel boot sequence, "a +sector" refers to 512 bytes. It is independent of the actual sector +size of the underlying medium. + +The first step in loading a Linux kernel should be to load the +real-mode code (boot sector and setup code) and then examine the +following header at offset 0x01f1. The real-mode code can total up to +32K, although the boot loader may choose to load only the first two +sectors (1K) and then examine the bootup sector size. + +The header looks like: + +Offset Proto Name Meaning +Size + +01F1/1 ALL setup_sects The size of the setup in sectors +01F2/2 ALL root_flags If set, the root is mounted readonly +01F4/2 ALL syssize DO NOT USE - for bootsect.S use only +01F6/2 ALL swap_dev DO NOT USE - obsolete +01F8/2 ALL ram_size DO NOT USE - for bootsect.S use only +01FA/2 ALL vid_mode Video mode control +01FC/2 ALL root_dev Default root device number +01FE/2 ALL boot_flag 0xAA55 magic number +0200/2 2.00+ jump Jump instruction +0202/4 2.00+ header Magic signature "HdrS" +0206/2 2.00+ version Boot protocol version supported +0208/4 2.00+ realmode_swtch Boot loader hook (see below) +020C/4 2.00+ start_sys Points to kernel version string +0210/1 2.00+ type_of_loader Boot loader identifier +0211/1 2.00+ loadflags Boot protocol option flags +0212/2 2.00+ setup_move_size Move to high memory size (used with hooks) +0214/4 2.00+ code32_start Boot loader hook (see below) +0218/4 2.00+ ramdisk_image initrd load address (set by boot loader) +021C/4 2.00+ ramdisk_size initrd size (set by boot loader) +0220/4 2.00+ bootsect_kludge DO NOT USE - for bootsect.S use only +0224/4 2.01+ heap_end_ptr Free memory after setup end +0226/2 N/A pad1 Unused +0228/4 2.02+ cmd_line_ptr 32-bit pointer to the kernel command line + +For backwards compatibility, if the setup_sects field contains 0, the +real value is 4. + +If the "HdrS" (0x53726448) magic number is not found at offset 0x202, +the boot protocol version is "old". Loading an old kernel, the +following parameters should be assumed: + + Image type = zImage + initrd not supported + Real-mode kernel must be located at 0x90000. + +Otherwise, the "version" field contains the protocol version, +e.g. protocol version 2.01 will contain 0x0201 in this field. When +setting fields in the header, you must make sure only to set fields +supported by the protocol version in use. + +Most boot loaders will simply load the kernel at its target address +directly. Such a boot loader do not need to worry about filling in +most of the fields in the header. The following fields should be +filled out, however: + + type_of_loader: + If your boot loader has an identifier assigned in + arch/i386/boot/setup.S, enter that value. Otherwise, enter + 0xFF here. + + loadflags, heap_end_ptr: + If the protocol version is 2.01 or higher, enter the + offset limit of the setup heap into heap_end_ptr and set the + 0x80 bit (CAN_USE_HEAP) of loadflags. heap_end_ptr appears to + be relative to the start of setup (offset 0x0200). + + setup_move_size: + When using protocol 2.00 or 2.01, if the real mode + kernel is not loaded at 0x90000, it gets moved there later in + the loading sequence. Fill in this field if you want + additional data (such as the kernel command line) moved in + addition to the real-mode kernel itself. + + ramdisk_image, ramdisk_size: + If your boot loader has loaded an initial ramdisk (initrd), + set ramdisk_image to the 32-bit pointer to the ramdisk data + and the ramdisk_size to the size of the ramdisk data. + + The initrd should typically be located as high in memory as + possible, as it may otherwise get overwritten by the early + kernel initialization sequence. However, it must never be + located above address 0x3C000000 if you want all kernels to + read it. + + cmd_line_ptr: + If the protocol version is 2.02 or higher, this is a 32-bit + pointer to the kernel command line. The kernel command line + can be located anywhere between the end of setup and 0xA0000. + Fill in this field even if your boot loader does not support a + command line, in which case you can point this to an empty + string (or better yet, to the string "auto".) If this field + is left at zero, the kernel will assume that your boot loader + does not support the 2.02 protocol. + + +**** THE KERNEL COMMAND LINE + +The kernel command line has become an important way for the boot +loader to communicate with the kernel. Some of its options are also +relevant to the boot loader itself, see "special command line options" +below. + +The kernel command line is a null-terminated string up to 255 +characters long, plus the final null. + +If the boot protocol version is 2.02 or later, the address of the +kernel command line is given by the header field cmd_line_ptr (see +above.) + +If the protocol version is *not* 2.02 or higher, the kernel +command line is entered using the following protocol: + + At offset 0x0020 (word), "cmd_line_magic", enter the magic + number 0xA33F. + + At offset 0x0022 (word), "cmd_line_offset", enter the offset + of the kernel command line (relative to the start of the + real-mode kernel). + + The kernel command line *must* be within the memory region + covered by setup_move_size, so you may need to adjust this + field. + + +**** SAMPLE BOOT CONFIGURATION + +As a sample configuration, assume the following layout of the real +mode segment: + + 0x0000-0x7FFF Real mode kernel + 0x8000-0x8FFF Stack and heap + 0x9000-0x90FF Kernel command line + +Such a boot loader should enter the following fields in the header: + + unsigned long base_ptr; /* base address for real-mode segment */ + + if ( setup_sects == 0 ) { + setup_sects = 4; + } + + if ( protocol >= 0x0200 ) { + type_of_loader = ; + if ( loading_initrd ) { + ramdisk_image = ; + ramdisk_size = ; + } + if ( protocol >= 0x0201 ) { + heap_end_ptr = 0x9000 - 0x200; + loadflags |= 0x80; /* CAN_USE_HEAP */ + } + if ( protocol >= 0x0202 ) { + cmd_line_ptr = base_ptr + 0x9000; + } else { + cmd_line_magic = 0xA33F; + cmd_line_offset = 0x9000; + setup_move_size = 0x9100; + } + } else { + /* Very old kernel */ + + cmd_line_magic = 0xA33F; + cmd_line_offset = 0x9000; + + /* A very old kernel MUST have its real-mode code + loaded at 0x90000 */ + + if ( base_ptr != 0x90000 ) { + /* Copy the real-mode kernel */ + memcpy(0x90000, base_ptr, (setup_sects+1)*512); + /* Copy the command line */ + memcpy(0x99000, base_ptr+0x9000, 256); + } + + /* It is recommended to clear memory up to the 32K mark */ + memset(0x90000 + (setup_sects-1)*512, 0, + (64-setup_sects-1)*512); + } + + +**** LOADING THE REST OF THE KERNEL + +The non-real-mode kernel starts at offset (setup_sects+1)*512 in the +kernel file (again, if setup_sects == 0 the real value is 4.) It +should be loaded at address 0x10000 for Image/zImage kernels and +0x100000 for bzImage kernels. + +The kernel is a bzImage kernel if the protocol >= 2.00 and the 0x01 +bit (LOAD_HIGH) in the loadflags field is set: + + is_bzImage = (protocol >= 0x0200) && (loadflags & 0x01); + load_address = is_bzImage ? 0x100000 : 0x10000; + +Note that Image/zImage kernels can be up to 512K in size, and thus use +the entire 0x10000-0x90000 range of memory. This means it is pretty +much a requirement for these kernels to load the real-mode part at +0x90000. bzImage kernels allow much more flexibility. + + +**** SPECIAL COMMAND LINE OPTIONS + +If the command line provided by the boot loader is entered by the +user, the user may expect the following command line options to work. +They should normally not be deleted from the kernel command line even +though not all of them are actually meaningful to the kernel. + + vga= + here is either an integer (in C notation, either + decimal, octal, or hexadecimal) or one of the strings + "normal" (meaning 0xFFFF), "ext" (meaning 0xFFFE) or "ask" + (meaning 0xFFFD). This value should be entered into the + vid_mode field, as it is used by the kernel before the command + line is parsed. + + mem= + is an integer in C notation optionally followed by K, M + or G (meaning << 10, << 20 or << 30). This specifies to the + kernel the memory size. This affects the possible placement + of an initrd, since an initrd should be placed near end of + memory. + + initrd= + An initrd should be loaded. The meaning of is + obviously bootloader-dependent. + +In addition, some boot loaders add the following options to the +user-specified command line: + + BOOT_IMAGE= + The boot image which was loaded. Again, the meaning of + is obviously bootloader-dependent. + + auto + The kernel was booted without explicit user intervention. + +If these options are added by the boot loader, it is highly +recommended that they are located *first*, before the user-specified +or configuration-specified command line. Otherwise, "init=/bin/sh" +gets confused by the "auto" option. + + +**** RUNNING THE KERNEL + +The kernel is started by jumping to the kernel entry point, which is +located at *segment* offset 0x20 from the start of the real mode +kernel. This means that if you loaded your real-mode kernel code at +0x90000, the kernel entry point is 9020:0000. + +At entry, ds = es = ss = fs = gs should point to the start of the +real-mode kernel code (0x9000 if the code is loaded at 0x90000), and +sp should be set up properly, normally pointing to the top of the +heap. In our example from above, we would do: + + seg = base_ptr >> 4; + + cli(); /* Enter with interrupts disabled! */ + + _SS = seg; + _SP = 0x9000; /* Load SP right after loading SS! */ + _DS = _ES = _FS = _GS = seg; + jmp_far(seg+0x20, 0); /* Run the kernel */ + +If your boot sector accesses a floppy drive, it is recommended to +switch off the floppy motor before running the kernel, since the +kernel boot leaves interrupts off and thus the motor will not be +switched off. + + +**** ADVANCED BOOT TIME HOOKS + +If the boot loader runs in a particularly hostile environment (such as +LOADLIN, which runs under DOS) it may be impossible to follow the +standard memory location requirements. Such a boot loader may use the +following hooks that, if set, are invoked by the kernel at the +appropriate time. The use of these hooks should probably be +considered an absolutely last resort! + +IMPORTANT: All the hooks are required to preserve %ebp, %esi and %edi +across invocation. + + realmode_swtch: + A 16-bit real mode far subroutine invoked immediately before + entering protected mode. The default routine disables NMI, so + your routine should probably do so, too. + + code32_start: + A 32-bit flat-mode routine *jumped* to immediately after the + transition to protected mode, but before the kernel is + uncompressed. No segments, except CS, are set up; you should + set them up to KERNEL_DS (0x18) yourself. + + After completing your hook, you should jump to the address + that was in this field before your boot loader overwrote it. + diff --git a/Documentation/serial-console.txt b/Documentation/serial-console.txt index 2894b8008110..50ac8058cfd1 100644 --- a/Documentation/serial-console.txt +++ b/Documentation/serial-console.txt @@ -87,8 +87,8 @@ Replace the sample values as needed. 6. Thanks - Thanks to Geert Uytterhoeven - for porting the patches from 2.1.4x to 2.1.6x for taking care of - the integration of these patches into m68k, ppc and alpha. + Thanks to Geert Uytterhoeven for porting + the patches from 2.1.4x to 2.1.6x and for taking care of the + integration of these patches into m68k, ppc and alpha. Miquel van Smoorenburg , 21-Mar-1998 diff --git a/Makefile b/Makefile index 5fe6d2d0b791..a5da9d79ada9 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ VERSION = 2 PATCHLEVEL = 2 SUBLEVEL = 17 -EXTRAVERSION = pre12 +EXTRAVERSION = pre13 ARCH := $(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ -e s/arm.*/arm/ -e s/sa110/arm/) diff --git a/Rules.make b/Rules.make index 9d0311f8f44d..88d70750d044 100644 --- a/Rules.make +++ b/Rules.make @@ -61,6 +61,9 @@ first_rule: sub_dirs %.o: %.s $(AS) $(ASFLAGS) $(EXTRA_CFLAGS) -o $@ $< +%.lst: %.c + $(CC) $(CFLAGS) $(EXTRA_CFLAGS) $(CFLAGS_$@) -g -c -o $*.o $< + $(TOPDIR)/scripts/makelst $* $(TOPDIR) $(OBJDUMP) # # # diff --git a/arch/alpha/config.in b/arch/alpha/config.in index 72f8eb345c2f..d26f0bff07c7 100644 --- a/arch/alpha/config.in +++ b/arch/alpha/config.in @@ -149,22 +149,26 @@ then define_bool CONFIG_ALPHA_IRONGATE y fi +if [ "$CONFIG_ALPHA_JENSEN" = "y" -o "$CONFIG_ALPHA_MIKASA" = "y" \ + -o "$CONFIG_ALPHA_SABLE" = "y" -o "$CONFIG_ALPHA_NORITAKE" = "y" \ + -o "$CONFIG_ALPHA_DP264" = "y" -o "$CONFIG_ALPHA_RAWHIDE" = "y" \ + -o "$CONFIG_ALPHA_EIGER" = "y" ] +then + define_bool CONFIG_ALPHA_SRM y +fi if [ "$CONFIG_ALPHA_CABRIOLET" = "y" -o "$CONFIG_ALPHA_AVANTI" = "y" \ - -o "$CONFIG_ALPHA_EB64P" = "y" -o "$CONFIG_ALPHA_JENSEN" = "y" \ - -o "$CONFIG_ALPHA_TAKARA" = "y" -o "$CONFIG_ALPHA_EB164" = "y" \ - -o "$CONFIG_ALPHA_MIKASA" = "y" -o "$CONFIG_ALPHA_ALCOR" = "y" \ - -o "$CONFIG_ALPHA_SABLE" = "y" -o "$CONFIG_ALPHA_MIATA" = "y" \ - -o "$CONFIG_ALPHA_NORITAKE" = "y" -o "$CONFIG_ALPHA_PC164" = "y" \ - -o "$CONFIG_ALPHA_LX164" = "y" -o "$CONFIG_ALPHA_SX164" = "y" \ - -o "$CONFIG_ALPHA_DP264" = "y" -o "$CONFIG_ALPHA_RAWHIDE" = "y" \ - -o "$CONFIG_ALPHA_EIGER" = "y" -o "$CONFIG_ALPHA_NAUTILUS" = "y" ] + -o "$CONFIG_ALPHA_EB64P" = "y" -o "$CONFIG_ALPHA_PC164" = "y" \ + -o "$CONFIG_ALPHA_TAKARA" = "y" -o "$CONFIG_ALPHA_EB164" = "y" \ + -o "$CONFIG_ALPHA_ALCOR" = "y" -o "$CONFIG_ALPHA_MIATA" = "y" \ + -o "$CONFIG_ALPHA_LX164" = "y" -o "$CONFIG_ALPHA_SX164" = "y" \ + -o "$CONFIG_ALPHA_NAUTILUS" = "y" ] then bool 'Use SRM as bootloader' CONFIG_ALPHA_SRM - if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then - if [ "$CONFIG_ALPHA_SRM" = "y" ]; then - bool ' Use SRM PCI setup' CONFIG_ALPHA_SRM_SETUP - fi - fi +# if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then +# if [ "$CONFIG_ALPHA_SRM" = "y" ]; then +# bool ' Use SRM PCI setup' CONFIG_ALPHA_SRM_SETUP +# fi +# fi fi if [ "$CONFIG_ALPHA_ALCOR" = "y" -o "$CONFIG_ALPHA_MIKASA" = "y" \ -o "$CONFIG_ALPHA_SABLE" = "y" -o "$CONFIG_ALPHA_NORITAKE" = "y" \ diff --git a/arch/alpha/kernel/sys_mikasa.c b/arch/alpha/kernel/sys_mikasa.c index fa438dfb9a03..8e14593dda31 100644 --- a/arch/alpha/kernel/sys_mikasa.c +++ b/arch/alpha/kernel/sys_mikasa.c @@ -151,8 +151,9 @@ mikasa_primo_pci_fixup(void) common_pci_fixup(mikasa_map_irq, common_swizzle); } +#if defined(CONFIG_ALPHA_GENERIC) || !defined(CONFIG_ALPHA_PRIMO) static void -mikasa_machine_check(unsigned long vector, unsigned long la_ptr, +mikasa_apecs_machine_check(unsigned long vector, unsigned long la_ptr, struct pt_regs * regs) { #define MCHK_NO_DEVSEL 0x205U @@ -175,14 +176,14 @@ mikasa_machine_check(unsigned long vector, unsigned long la_ptr, (la_ptr + mchk_header->sys_offset); #ifdef DEBUG - printk("mikasa_machine_check: vector=0x%lx la_ptr=0x%lx\n", + printk("mikasa_apecs_machine_check: vector=0x%lx la_ptr=0x%lx\n", vector, la_ptr); printk(" pc=0x%lx size=0x%x procoffset=0x%x sysoffset 0x%x\n", regs->pc, mchk_header->size, mchk_header->proc_offset, mchk_header->sys_offset); - printk("mikasa_machine_check: expected %d DCSR 0x%lx PEAR 0x%lx\n", - apecs_mcheck_expected, mchk_sysdata->epic_dcsr, - mchk_sysdata->epic_pear); + printk("mikasa_apecs_machine_check: expected %d DCSR 0x%lx" + " PEAR 0x%lx\n", apecs_mcheck_expected, + mchk_sysdata->epic_dcsr, mchk_sysdata->epic_pear); ptr = (unsigned long *)la_ptr; for (i = 0; i < mchk_header->size / sizeof(long); i += 2) { printk(" +%lx %lx %lx\n", i*sizeof(long), ptr[i], ptr[i+1]); @@ -213,7 +214,7 @@ mikasa_machine_check(unsigned long vector, unsigned long la_ptr, wrmces(0x1f); mb(); draina(); - printk("mikasa_machine_check: HW correctable (0x%lx)\n", + printk("mikasa_apecs_machine_check: HW correctable (0x%lx)\n", vector); } else { @@ -239,6 +240,7 @@ mikasa_machine_check(unsigned long vector, unsigned long la_ptr, #endif } } +#endif /* @@ -252,7 +254,7 @@ struct alpha_machine_vector mikasa_mv __initmv = { DO_DEFAULT_RTC, DO_APECS_IO, DO_APECS_BUS, - machine_check: mikasa_machine_check, + machine_check: mikasa_apecs_machine_check, max_dma_address: ALPHA_MAX_DMA_ADDRESS, nr_irqs: 32, diff --git a/arch/alpha/kernel/sys_noritake.c b/arch/alpha/kernel/sys_noritake.c index 2ade29654e70..1bbefee1227e 100644 --- a/arch/alpha/kernel/sys_noritake.c +++ b/arch/alpha/kernel/sys_noritake.c @@ -238,6 +238,97 @@ noritake_primo_pci_fixup(void) common_pci_fixup(noritake_map_irq, noritake_swizzle); } +#if defined(CONFIG_ALPHA_GENERIC) || !defined(CONFIG_ALPHA_PRIMO) +static void +noritake_apecs_machine_check(unsigned long vector, unsigned long la_ptr, + struct pt_regs * regs) +{ +#define MCHK_NO_DEVSEL 0x205U +#define MCHK_NO_TABT 0x204U + + struct el_common *mchk_header; + struct el_apecs_procdata *mchk_procdata; + struct el_apecs_mikasa_sysdata_mcheck *mchk_sysdata; + unsigned long *ptr; + unsigned int code; /* workaround EGCS problem */ + int i; + + mchk_header = (struct el_common *)la_ptr; + + mchk_procdata = (struct el_apecs_procdata *) + (la_ptr + mchk_header->proc_offset + - sizeof(mchk_procdata->paltemp)); + + mchk_sysdata = (struct el_apecs_mikasa_sysdata_mcheck *) + (la_ptr + mchk_header->sys_offset); + +#ifdef DEBUG + printk("noritake_apecs_machine_check: vector=0x%lx la_ptr=0x%lx\n", + vector, la_ptr); + printk(" pc=0x%lx size=0x%x procoffset=0x%x sysoffset 0x%x\n", + regs->pc, mchk_header->size, mchk_header->proc_offset, + mchk_header->sys_offset); + printk("noritake_apecs_machine_check: expected %d DCSR 0x%lx" + " PEAR 0x%lx\n", apecs_mcheck_expected, + mchk_sysdata->epic_dcsr, mchk_sysdata->epic_pear); + ptr = (unsigned long *)la_ptr; + for (i = 0; i < mchk_header->size / sizeof(long); i += 2) { + printk(" +%lx %lx %lx\n", i*sizeof(long), ptr[i], ptr[i+1]); + } +#endif + + /* + * Check if machine check is due to a badaddr() and if so, + * ignore the machine check. + */ + + code = mchk_header->code; /* workaround EGCS problem */ + + if (apecs_mcheck_expected && + (code == MCHK_NO_DEVSEL || code == MCHK_NO_TABT)) + { + apecs_mcheck_expected = 0; + apecs_mcheck_taken = 1; + mb(); + mb(); /* magic */ + apecs_pci_clr_err(); + wrmces(0x7); + mb(); + draina(); + } + else if (vector == 0x620 || vector == 0x630) { + /* Disable correctable from now on. */ + wrmces(0x1f); + mb(); + draina(); + printk("noritake_apecs_machine_check: HW correctable (0x%lx)\n", + vector); + } + else { + printk(KERN_CRIT "NORITAKE APECS machine check:\n"); + printk(KERN_CRIT " vector=0x%lx la_ptr=0x%lx code=0x%x\n", + vector, la_ptr, code); + printk(KERN_CRIT + " pc=0x%lx size=0x%x procoffset=0x%x sysoffset 0x%x\n", + regs->pc, mchk_header->size, mchk_header->proc_offset, + mchk_header->sys_offset); + printk(KERN_CRIT " expected %d DCSR 0x%lx PEAR 0x%lx\n", + apecs_mcheck_expected, mchk_sysdata->epic_dcsr, + mchk_sysdata->epic_pear); + + ptr = (unsigned long *)la_ptr; + for (i = 0; i < mchk_header->size / sizeof(long); i += 2) { + printk(KERN_CRIT " +%lx %lx %lx\n", + i*sizeof(long), ptr[i], ptr[i+1]); + } +#if 0 + /* doesn't work with MILO */ + show_regs(regs); +#endif + } +} +#endif + /* * The System Vectors @@ -250,7 +341,7 @@ struct alpha_machine_vector noritake_mv __initmv = { DO_DEFAULT_RTC, DO_APECS_IO, DO_APECS_BUS, - machine_check: apecs_machine_check, + machine_check: noritake_apecs_machine_check, max_dma_address: ALPHA_MAX_DMA_ADDRESS, nr_irqs: 48, diff --git a/arch/m68k/amiga/chipram.c b/arch/m68k/amiga/chipram.c index 50d5a0de0be0..9211f85997a2 100644 --- a/arch/m68k/amiga/chipram.c +++ b/arch/m68k/amiga/chipram.c @@ -1,8 +1,7 @@ /* ** linux/amiga/chipram.c ** -** Modified 03-May-94 by Geert Uytterhoeven -** (Geert.Uytterhoeven@cs.kuleuven.ac.be) +** Modified 03-May-94 by Geert Uytterhoeven ** - 64-bit aligned allocations for full AGA compatibility */ diff --git a/arch/m68k/tools/amiga/dmesg.c b/arch/m68k/tools/amiga/dmesg.c index 9affff5659cc..e892748e7386 100644 --- a/arch/m68k/tools/amiga/dmesg.c +++ b/arch/m68k/tools/amiga/dmesg.c @@ -3,8 +3,7 @@ * in Chip RAM with the kernel command * line option `debug=mem'. * - * © Copyright 1996 by Geert Uytterhoeven - * (Geert.Uytterhoeven@cs.kuleuven.ac.be) + * © Copyright 1996 by Geert Uytterhoeven * * * Usage: diff --git a/arch/s390/Makefile b/arch/s390/Makefile index d78d10d1e25f..22b04fe6dec6 100644 --- a/arch/s390/Makefile +++ b/arch/s390/Makefile @@ -1,5 +1,5 @@ -# i386/Makefile +# s390/Makefile # # This file is included by the global makefile so that you can add your own # architecture-specific flags and dependencies. Remember to do have actions diff --git a/arch/s390/boot/Makefile b/arch/s390/boot/Makefile index 9d3a7911ffca..693522a6c22e 100644 --- a/arch/s390/boot/Makefile +++ b/arch/s390/boot/Makefile @@ -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 --git a/arch/s390/defconfig b/arch/s390/defconfig index c2fda8dd5feb..cb4a8d726246 100644 --- a/arch/s390/defconfig +++ b/arch/s390/defconfig @@ -26,8 +26,8 @@ CONFIG_KMOD=y # CONFIG_FAST_IRQ=y CONFIG_IPL=y -# CONFIG_IPL_TAPE is not set -CONFIG_IPL_VM=y +CONFIG_IPL_TAPE=y +# CONFIG_IPL_VM is not set CONFIG_NET=y CONFIG_SYSVIPC=y # CONFIG_BSD_PROCESS_ACCT is not set @@ -41,9 +41,9 @@ CONFIG_BLK_DEV_LOOP=y # CONFIG_BLK_DEV_NBD is not set # CONFIG_BLK_DEV_MD is not set CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_SIZE=8192 CONFIG_BLK_DEV_INITRD=y -CONFIG_BLK_DEV_XPRAM=y -CONFIG_BLK_DEV_INITRD=y +CONFIG_BLK_DEV_XPRAM=m # CONFIG_MDISK is not set CONFIG_DASD=y CONFIG_DASD_ECKD=y @@ -140,7 +140,8 @@ CONFIG_EXT2_FS=y # # CONFIG_CODA_FS is not set CONFIG_NFS_FS=y -# CONFIG_NFSD is not set +CONFIG_NFSD=y +# CONFIG_NFSD_SUN is not set CONFIG_SUNRPC=y CONFIG_LOCKD=y # CONFIG_SMB_FS is not set diff --git a/arch/s390/kernel/debug.c b/arch/s390/kernel/debug.c index 6a69d8902a01..d03d566110c6 100644 --- a/arch/s390/kernel/debug.c +++ b/arch/s390/kernel/debug.c @@ -3,6 +3,7 @@ #include #include #include +#include #ifdef MODULE #include @@ -10,9 +11,7 @@ #include -#include "debug.h" - -debug_info_t debug_areas[MAX_DEBUG_AREAS]; +debug_info_t debug_areas[MAX_DEBUG_AREAS] = { {NULL, },}; debug_info_t *free_area = 0; static int initialized = 0; @@ -38,6 +37,7 @@ debug_register (char *name, int page_order, int nr_areas) rc = free_area; free_area = *((debug_info_t **) rc); + memset(rc, 0, nr_areas * sizeof(debug_info_t)); rc->areas = (debug_entry_t **) kmalloc (nr_areas * sizeof (debug_entry_t *), GFP_ATOMIC); @@ -59,14 +59,16 @@ debug_register (char *name, int page_order, int nr_areas) goto nopages; } } - rc->page_order = page_order; rc->nr_areas = nr_areas; rc->name = kmalloc (strlen (name) + 1, GFP_ATOMIC); strncpy (rc->name, name, strlen (name)); + ASCEBC(rc->name, strlen (name)); rc->name[strlen (name)] = 0; + rc->active_entry = kmalloc (nr_areas, GFP_ATOMIC); memset(rc->active_entry, 0, nr_areas * sizeof(int)); + rc->level=3; printk (KERN_INFO "reserved %d areas of %d pages for debugging %s\n", nr_areas, 1 << page_order, name); goto exit; diff --git a/arch/s390/kernel/debug.h b/arch/s390/kernel/debug.h deleted file mode 100644 index 836204ff8d7c..000000000000 --- a/arch/s390/kernel/debug.h +++ /dev/null @@ -1,55 +0,0 @@ - -#ifndef DEBUG_H -#define DEBUG_H - -#include - -#define MAX_DEBUG_AREAS 16 - -#define STCK(x) asm volatile ("STCK %0":"=m" (x)) - -typedef struct -{ - union - { - struct - { - unsigned long long cpuid:4; - unsigned long long clock:60; - } - fields; - unsigned long long stck; - } - id; - void *caller; - union - { - unsigned long tag; - char text[4]; - } - tag; -} -debug_entry_t; - -typedef struct -{ - char *name; - int level; - int nr_areas; - int page_order; - debug_entry_t **areas; - int active_area; - int *active_entry; - spinlock_t lock; -} -debug_info_t; - -int debug_init (void); -debug_info_t *debug_register (char *name, int pages_index, int nr_areas); -void debug_unregister (debug_info_t * id, char *name); -void debug_event (debug_info_t * id, int level, unsigned int tag); -void debug_text_event (debug_info_t * id, int level, char tag[4]); -void debug_exception (debug_info_t * id, int level, unsigned int tag); -void debug_text_exception (debug_info_t * id, int level, char tag[4]); - -#endif diff --git a/arch/s390/kernel/entry.S b/arch/s390/kernel/entry.S index 89048b793647..6affe76f9828 100644 --- a/arch/s390/kernel/entry.S +++ b/arch/s390/kernel/entry.S @@ -300,7 +300,7 @@ ret_from_fork: stosm 24(%r15),0x03 # reenable interrupts sr %r0,%r0 # child returns 0 st %r0,SP_R2(%r15) # store return value (change R2 on stack) -#ifdef __SMP__ +#ifdef CONFIG_SMP l %r1,BASED(.Lschedtail) la %r14,BASED(sysc_return) br %r1 # call schedule_tail, return to sysc_return @@ -787,7 +787,7 @@ mcck_int_handler: mcck_return: RESTORE_ALL -#ifdef __SMP__ +#ifdef CONFIG_SMP /* * Restart interruption handler, kick starter for additional CPUs */ @@ -862,6 +862,6 @@ restart_go: .Ltrace: .long syscall_trace .Lvfork: .long sys_vfork -#ifdef __SMP__ +#ifdef CONFIG_SMP .Lschedtail: .long schedule_tail #endif diff --git a/arch/s390/kernel/head.S b/arch/s390/kernel/head.S index dd63400322c2..ff047820cf2e 100644 --- a/arch/s390/kernel/head.S +++ b/arch/s390/kernel/head.S @@ -5,8 +5,9 @@ * Copyright (C) 1999,2000 IBM Deutschland Entwicklung GmbH, IBM Corporation * Author(s): Hartmut Penner (hp@de.ibm.com), * Martin Schwidefsky (schwidefsky@de.ibm.com), + * Rob van der Heij * - * There are 4 different IPL methods + * There are 5 different IPL methods * 1) load the image directly into ram at address 0 and do an PSW restart * 2) linload will load the image from address 0x10000 to memory 0x10000 * and start the code thru LPSW 0x0008000080010000 (VM only, deprecated) @@ -14,6 +15,7 @@ * and ipl from it * 4) generate the vm reader ipl header, move the generated image to the * VM reader (use option NOH!) and do a ipl from reader (VM only) + * 5) direct call of start by the SALIPL loader * We use the cpuid to distinguish between VM and native ipl * params for kernel are pushed to 0x10400 (see setup.h) */ @@ -24,34 +26,7 @@ #ifndef CONFIG_IPL .org 0 - .long 0x00080000,0x80000000+iplstart # Just a restart PSW - -iplstart: - l %r12,.Lparm # pointer to parameter area -# -# find out memory size -# - mvc 104(8,0),.Lpcmem0 # setup program check handler - slr %r2,%r2 - lhi %r3,1 - sll %r3,20 -.Lloop0: - l %r0,0(%r2) # test page - ar %r2,%r3 # add 1M - jnm .Lloop0 # r1 < 0x80000000 -> loop -.Lchkmem0: - n %r2,.L4malign0 # align to multiples of 4M - st %r2,MEMORY_SIZE-PARMAREA(%r12) # store memory size - slr %r2,%r2 - st %r2,INITRD_SIZE-PARMAREA(%r12) # null ramdisk - st %r2,INITRD_START-PARMAREA(%r12) - j start - -.Lparm: .long PARMAREA -.L4malign0:.long 0xffc00000 - .align 8 -.Lpcmem0:.long 0x00080000,0x80000000 + .Lchkmem0 - + .long 0x00080000,0x80000000+startup # Just a restart PSW #else #ifdef CONFIG_IPL_TAPE #define IPL_BS 1024 @@ -74,92 +49,6 @@ iplstart: .long 0x00080000,0x80000000+.Lioint # io new psw .org 0x100 -iplstart: - l %r1,0xb8 # load ipl subchannel number - lhi %r2,IPL_BS # load start address - bras %r14,.Lloader # load rest of ipl image - st %r1,__LC_IPLDEV # store ipl device number - l %r12,.Lparm # pointer to parameter area - -# -# find out memory size -# - mvc 104(8,0),.Lpcmem0 # setup program check handler - slr %r2,%r2 - lhi %r3,1 - sll %r3,20 -.Lloop0: - l %r0,0(%r2) # test page - ar %r2,%r3 # add 1M - jnm .Lloop0 # r1 < 0x80000000 -> loop -.Lchkmem0: - n %r2,.L4malign0 # align to multiples of 4M - st %r2,MEMORY_SIZE-PARMAREA(%r12) # store memory size - c %r2,.Lbigmem # more than 64 MB of memory ? - jl .Lmemok # if yes load ramdisk to 32 MB - mvc INITRD_START-PARMAREA(4,%r12),.Lrdstart -.Lmemok: - -# -# load parameter file from tape -# - l %r2,INITRD_START-PARMAREA(%r12) # use ramdisk location as temp - bras %r14,.Lloader # load parameter file - ltr %r2,%r2 # got anything ? - jz .Lnopf - chi %r2,895 - jnh .Lnotrunc - lhi %r2,895 -.Lnotrunc: - l %r4,INITRD_START-PARMAREA(%r12) - la %r5,0(%r4,%r2) - lr %r3,%r2 -.Lidebc: - tm 0(%r5),0x80 # high order bit set ? - jo .Ldocv # yes -> convert from EBCDIC - ahi %r5,-1 - brct %r3,.Lidebc - j .Lnocv -.Ldocv: - l %r3,.Lcvtab - tr 0(256,%r4),0(%r3) # convert parameters to ascii - tr 256(256,%r4),0(%r3) - tr 512(256,%r4),0(%r3) - tr 768(122,%r4),0(%r3) -.Lnocv: la %r3,COMMAND_LINE-PARMAREA(%r12) # load adr. of command line - mvc 0(256,%r3),0(%r4) - mvc 256(256,%r3),256(%r4) - mvc 512(256,%r3),512(%r4) - mvc 768(122,%r3),768(%r4) - slr %r0,%r0 - j .Lcntlp -.Ldelspc: - ic %r0,0(%r2,%r3) - chi %r0,0x20 # is it a space ? - je .Lcntlp - ahi %r2,1 - j .Leolp -.Lcntlp: - brct %r2,.Ldelspc -.Leolp: - slr %r0,%r0 - stc %r0,0(%r2,%r3) # terminate buffer -.Lnopf: - -# -# load ramdisk from tape -# - l %r2,INITRD_START-PARMAREA(%r12) # load adr. of ramdisk - bras %r14,.Lloader # load ramdisk - st %r2,INITRD_SIZE-PARMAREA(%r12) # store size of ramdisk - ltr %r2,%r2 - jnz .Lrdcont - st %r2,INITRD_START-PARMAREA(%r12) # no ramdisk found, null it -.Lrdcont: -# -# everything loaded, go for it -# - j start # # subroutine for loading from tape # Paramters: @@ -173,32 +62,32 @@ iplstart: lctl %c6,%c6,.Lcr6 slr %r2,%r2 .Lldlp: - lhi %r6,3 # 3 retries + la %r6,3 # 3 retries .Lssch: ssch 0(%r3) # load chunk of IPL_BS bytes - jnz .Llderr + bnz .Llderr .Lw4end: - bras %r14,.Lwait4io + bas %r14,.Lwait4io tm 8(%r5),0x82 # do we have a problem ? - jnz .Lrecov + bnz .Lrecov slr %r7,%r7 icm %r7,3,10(%r5) # get residual count lcr %r7,%r7 - ahi %r7,IPL_BS # IPL_BS-residual=#bytes read + la %r7,IPL_BS(%r7) # IPL_BS-residual=#bytes read ar %r2,%r7 # add to total size tm 8(%r5),0x01 # found a tape mark ? - jnz .Ldone + bnz .Ldone l %r0,.Lccwread+4 # update CCW data addresses ar %r0,%r7 st %r0,.Lccwread+4 - j .Lldlp + b .Lldlp .Ldone: l %r14,.Lldret br %r14 # r2 contains the total size .Lrecov: - bras %r14,.Lsense # do the sensing - brct %r6,.Lssch # dec. retry count & branch - j .Llderr + bas %r14,.Lsense # do the sensing + bct %r6,.Lssch # dec. retry count & branch + b .Llderr # # Sense subroutine # @@ -206,11 +95,11 @@ iplstart: st %r14,.Lsnsret la %r7,.Lorbsense ssch 0(%r7) # start sense command - jnz .Llderr - bras %r14,.Lwait4io + bnz .Llderr + bas %r14,.Lwait4io l %r14,.Lsnsret tm 8(%r5),0x82 # do we have a problem ? - jnz .Llderr + bnz .Llderr br %r14 # # Wait for interrupt subroutine @@ -219,13 +108,13 @@ iplstart: lpsw .Lwaitpsw .Lioint: c %r1,0xb8 # compare subchannel number - jne .Lwait4io + bne .Lwait4io tsch 0(%r5) slr %r0,%r0 tm 8(%r5),0x82 # do we have a problem ? - jnz .Lwtexit + bnz .Lwtexit tm 8(%r5),0x04 # got device end ? - jz .Lwait4io + bz .Lwait4io .Lwtexit: br %r14 .Llderr: @@ -249,18 +138,12 @@ iplstart: .Lcr6: .long 0xff000000 .align 8 .Lcrash:.long 0x000a0000,0x00000000 -.Lpcmem0:.long 0x00080000,0x80000000 + .Lchkmem0 -.Lparm: .long PARMAREA -.L4malign0:.long 0xffc00000 -.Lbigmem:.long 0x04000000 -.Lrdstart:.long 0x02000000 .Lldret:.long 0 .Lsnsret: .long 0 -.Lcvtab:.long _ebcasc # ebcdic to ascii table - -#endif /* CONFIG_IPL_TAPE */ +#endif /* CONFIG_IPL_NONE */ #ifdef CONFIG_IPL_VM +#define IPL_BS 0x730 .org 0 .long 0x00080000,0x80000000+iplstart # The first 24 bytes are loaded .long 0x02000018,0x60000050 # by ipl to addresses 0-23. @@ -287,103 +170,7 @@ iplstart: .long 0x02000690,0x60000050 .long 0x020006e0,0x20000050 - .org 0xf0 -iplstart: - l %r1,0xb8 # load ipl subchannel number - lhi %r2,0x730 # load start address - bras %r14,.Lloader # load rest of ipl image - st %r1,__LC_IPLDEV # store ipl device number - l %r12,.Lparm # pointer to parameter area - -# -# find out memory size -# - mvc 104(8,0),.Lpcmem0 # setup program check handler - slr %r2,%r2 - lhi %r3,1 - sll %r3,20 -.Lloop0: - l %r0,0(%r2) # test page - ar %r2,%r3 # add 1M - jnm .Lloop0 # r1 < 0x80000000 -> loop -.Lchkmem0: - n %r2,.L4malign0 # align to multiples of 4M - st %r2,MEMORY_SIZE-PARMAREA(%r12) # store memory size - c %r2,.Lbigmem # more than 64 MB of memory ? - jl .Lmemok # if yes load ramdisk to 32 MB - mvc INITRD_START-PARMAREA(4,%r12),.Lrdstart -.Lmemok: - -# -# load parameter file from reader -# - l %r2,INITRD_START-PARMAREA(%r12) # use ramdisk location as temp - bras %r14,.Lloader # load parameter file - ltr %r2,%r2 # got anything ? - jz .Lnopf - chi %r2,895 - jnh .Lnotrunc - lhi %r2,895 -.Lnotrunc: - l %r4,INITRD_START-PARMAREA(%r12) - la %r5,0(%r4,%r2) - lr %r3,%r2 -.Lidebc: - tm 0(%r5),0x80 # high order bit set ? - jo .Ldocv # yes -> convert from EBCDIC - ahi %r5,-1 - brct %r3,.Lidebc - j .Lnocv -.Ldocv: - l %r3,.Lcvtab - tr 0(256,%r4),0(%r3) # convert parameters to ascii - tr 256(256,%r4),0(%r3) - tr 512(256,%r4),0(%r3) - tr 768(122,%r4),0(%r3) -.Lnocv: la %r3,COMMAND_LINE-PARMAREA(%r12) # load adr. of command line - mvc 0(256,%r3),0(%r4) - mvc 256(256,%r3),256(%r4) - mvc 512(256,%r3),512(%r4) - mvc 768(122,%r3),768(%r4) - slr %r0,%r0 - j .Lcntlp -.Ldelspc: - ic %r0,0(%r2,%r3) - chi %r0,0x20 # is it a space ? - je .Lcntlp - ahi %r2,1 - j .Leolp -.Lcntlp: - brct %r2,.Ldelspc -.Leolp: - slr %r0,%r0 - stc %r0,0(%r2,%r3) # terminate buffer -.Lnopf: - -# -# load ramdisk from reader -# - l %r2,INITRD_START-PARMAREA(%r12) # load adr. of ramdisk - bras %r14,.Lloader # load ramdisk - st %r2,INITRD_SIZE-PARMAREA(%r12) # store size of ramdisk - ltr %r2,%r2 - jnz .Lrdcont - st %r2,INITRD_START-PARMAREA(%r12) # no ramdisk found, null it -.Lrdcont: - -# -# everything loaded, reset files in reader, then go for it -# - stidp __LC_CPUID # store cpuid - lh %r0,__LC_CPUID+4 # get cpu version - chi %r0,0x7490 # running on P/390 ? - je start # no -> skip reset - la %r2,.Lreset - lhi %r3,26 - .long 0x83230008 - j start - # # subroutine for loading cards from the reader # @@ -394,29 +181,29 @@ iplstart: la %r7,20 .Linit: st %r2,4(%r6) # initialize CCW data addresses - ahi %r2,0x50 - ahi %r6,8 - brct 7,.Linit + la %r2,0x50(%r2) + la %r6,8(%r6) + bct 7,.Linit lctl %c6,%c6,.Lcr6 # set IO subclass mask slr %r2,%r2 .Lldlp: ssch 0(%r3) # load chunk of 1600 bytes - jnz .Llderr + bnz .Llderr .Lwait4irq: mvc __LC_IO_NEW_PSW(8),.Lnewpsw # set up IO interrupt psw lpsw .Lwaitpsw .Lioint: c %r1,0xb8 # compare subchannel number - jne .Lwait4irq + bne .Lwait4irq tsch 0(%r5) slr %r0,%r0 ic %r0,8(%r5) # get device status chi %r0,8 # channel end ? - je .Lcont + be .Lcont chi %r0,12 # channel end + device end ? - je .Lcont + be .Lcont l %r0,4(%r5) s %r0,8(%r3) # r0/8 = number of ccws executed @@ -436,9 +223,9 @@ iplstart: ahi %r0,0x640 st %r0,4(%r6) ahi %r6,8 - brct 7,.Lincr + bct 7,.Lincr - j .Lldlp + b .Lldlp .Llderr: lpsw .Lcrash @@ -447,16 +234,7 @@ iplstart: .Lirb: .long 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 .Lcr6: .long 0xff000000 .Lloadp:.long 0,0 -.Lparm: .long PARMAREA -.L4malign0:.long 0xffc00000 -.Lbigmem:.long 0x04000000 -.Lrdstart:.long 0x02000000 -.Lcvtab:.long _ebcasc # ebcdic to ascii table -.Lreset:.byte 0xc3,0xc8,0xc1,0xd5,0xc7,0xc5,0x40,0xd9,0xc4,0xd9,0x40 - .byte 0xc1,0xd3,0xd3,0x40,0xd2,0xc5,0xc5,0xd7,0x40,0xd5,0xd6 - .byte 0xc8,0xd6,0xd3,0xc4 # "change rdr all keep nohold" .align 8 -.Lpcmem0:.long 0x00080000,0x80000000 + .Lchkmem0 .Lcrash:.long 0x000a0000,0x00000000 .Lnewpsw: .long 0x00080000,0x80000000+.Lioint @@ -468,28 +246,203 @@ iplstart: .long 0x02600050,0x00000000 .endr .long 0x02200050,0x00000000 - - .org 0x730 # end of the area loaded by the ipl channel program #endif /* CONFIG_IPL_VM */ +iplstart: + lh %r1,0xb8 # test if subchannel number + bct %r1,.Lnoload # is valid + l %r1,0xb8 # load ipl subchannel number + la %r2,IPL_BS # load start address + bas %r14,.Lloader # load rest of ipl image + st %r1,__LC_IPLDEV # store ipl device number + l %r12,.Lparm # pointer to parameter area + +# +# load parameter file from ipl device +# + l %r2,INITRD_START-PARMAREA(%r12) # use ramdisk location as temp + bas %r14,.Lloader # load parameter file + ltr %r2,%r2 # got anything ? + bz .Lnopf + chi %r2,895 + bnh .Lnotrunc + la %r2,895 +.Lnotrunc: + l %r4,INITRD_START-PARMAREA(%r12) + la %r5,0(%r4,%r2) + lr %r3,%r2 +.Lidebc: + tm 0(%r5),0x80 # high order bit set ? + bo .Ldocv # yes -> convert from EBCDIC + ahi %r5,-1 + bct %r3,.Lidebc + b .Lnocv +.Ldocv: + l %r3,.Lcvtab + tr 0(256,%r4),0(%r3) # convert parameters to ascii + tr 256(256,%r4),0(%r3) + tr 512(256,%r4),0(%r3) + tr 768(122,%r4),0(%r3) +.Lnocv: la %r3,COMMAND_LINE-PARMAREA(%r12) # load adr. of command line + mvc 0(256,%r3),0(%r4) + mvc 256(256,%r3),256(%r4) + mvc 512(256,%r3),512(%r4) + mvc 768(122,%r3),768(%r4) + slr %r0,%r0 + b .Lcntlp +.Ldelspc: + ic %r0,0(%r2,%r3) + chi %r0,0x20 # is it a space ? + be .Lcntlp + ahi %r2,1 + b .Leolp +.Lcntlp: + brct %r2,.Ldelspc +.Leolp: + slr %r0,%r0 + stc %r0,0(%r2,%r3) # terminate buffer +.Lnopf: + +# +# load ramdisk from ipl device +# + l %r2,INITRD_START-PARMAREA(%r12) # load adr. of ramdisk + bas %r14,.Lloader # load ramdisk + st %r2,INITRD_SIZE-PARMAREA(%r12) # store size of ramdisk + ltr %r2,%r2 + bnz .Lrdcont + st %r2,INITRD_START-PARMAREA(%r12) # no ramdisk found, null it +.Lrdcont: + +#ifdef CONFIG_IPL_VM +# +# reset files in VM reader +# + stidp __LC_CPUID # store cpuid + lh %r0,__LC_CPUID+4 # get cpu version + chi %r0,0x7490 # running on P/390 ? + be start # no -> skip reset + la %r2,.Lreset + lhi %r3,26 + .long 0x83230008 +#endif + +# +# everything loaded, go for it +# +.Lnoload: + l %r1,.Lstartup + br %r1 + +.Lparm: .long PARMAREA +.Lstartup: .long startup +.Lcvtab:.long _ebcasc # ebcdic to ascii table +.Lreset:.byte 0xc3,0xc8,0xc1,0xd5,0xc7,0xc5,0x40,0xd9,0xc4,0xd9,0x40 + .byte 0xc1,0xd3,0xd3,0x40,0xd2,0xc5,0xc5,0xd7,0x40,0xd5,0xd6 + .byte 0xc8,0xd6,0xd3,0xc4 # "change rdr all keep nohold" + #endif /* CONFIG_IPL */ +# +# SALIPL loader support. Based on a patch by Rob van der Heij. +# This entry point is called directly from the SALIPL loader and +# doesn't need a builtin ipl record. +# + .org 0x800 + .globl start +start: + stm %r0,%r15,0x07b0 # store registers + basr %r12,%r0 +.base: + l %r11,.parm + l %r8,.cmd # pointer to command buffer + + ltr %r9,%r9 # do we have SALIPL parameters? + bp .sk8x8 + + mvc 0(64,%r8),0x00b0 # copy saved registers + xc 64(240-64,%r8),0(%r8) # remainder of buffer + tr 0(64,%r8),.lowcase + b .gotr +.sk8x8: + mvc 0(240,%r8),0(%r9) # copy iplparms into buffer +.gotr: + l %r10,.tbl # EBCDIC to ASCII table + tr 0(240,%r8),0(%r10) + stidp __LC_CPUID # Are we running on VM maybe + cli __LC_CPUID,0xff + bnz .test + .long 0x83300060 # diag 3,0,x'0060' - storage size + b .done +.test: + mvc 0x68(8,0),.pgmnw # set up pgm check handler + l %r2,.fourmeg + lr %r3,%r2 + bctr %r3,%r0 # 4M-1 +.loop: iske %r0,%r3 + ar %r3,%r2 +.pgmx: + sr %r3,%r2 + la %r3,1(%r3) +.done: + st %r3,MEMORY_SIZE-PARMAREA(%r11) + slr %r0,%r0 + st %r0,INITRD_SIZE-PARMAREA(%r11) + st %r0,INITRD_START-PARMAREA(%r11) + j startup # continue with startup +.tbl: .long _ebcasc # translate table +.cmd: .long COMMAND_LINE # address of command line buffer +.parm: .long PARMAREA +.fourmeg: .long 0x00400000 # 4M +.pgmnw: .long 0x00080000,.pgmx +.lowcase: + .byte 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07 + .byte 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f + .byte 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17 + .byte 0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f + .byte 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27 + .byte 0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f + .byte 0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37 + .byte 0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f + .byte 0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47 + .byte 0x48,0x49,0x4a,0x4b,0x4c,0x4d,0x4e,0x4f + .byte 0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57 + .byte 0x58,0x59,0x5a,0x5b,0x5c,0x5d,0x5e,0x5f + .byte 0x60,0x61,0x62,0x63,0x64,0x65,0x66,0x67 + .byte 0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f + .byte 0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77 + .byte 0x78,0x79,0x7a,0x7b,0x7c,0x7d,0x7e,0x7f + + .byte 0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87 + .byte 0x88,0x89,0x8a,0x8b,0x8c,0x8d,0x8e,0x8f + .byte 0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97 + .byte 0x98,0x99,0x9a,0x9b,0x9c,0x9d,0x9e,0x9f + .byte 0xa0,0xa1,0xa2,0xa3,0xa4,0xa5,0xa6,0xa7 + .byte 0xa8,0xa9,0xaa,0xab,0xac,0xad,0xae,0xaf + .byte 0xb0,0xb1,0xb2,0xb3,0xb4,0xb5,0xb6,0xb7 + .byte 0xb8,0xb9,0xba,0xbb,0xbc,0xbd,0xbe,0xbf + .byte 0xc0,0x81,0x82,0x83,0x84,0x85,0x86,0x87 # .abcdefg + .byte 0x88,0x89,0xca,0xcb,0xcc,0xcd,0xce,0xcf # hi + .byte 0xd0,0x91,0x92,0x93,0x94,0x95,0x96,0x97 # .jklmnop + .byte 0x98,0x99,0xda,0xdb,0xdc,0xdd,0xde,0xdf # qr + .byte 0xe0,0xe1,0xa2,0xa3,0xa4,0xa5,0xa6,0xa7 # ..stuvwx + .byte 0xa8,0xa9,0xea,0xeb,0xec,0xed,0xee,0xef # yz + .byte 0xf0,0xf1,0xf2,0xf3,0xf4,0xf5,0xf6,0xf7 + .byte 0xf8,0xf9,0xfa,0xfb,0xfc,0xfd,0xfe,0xff + # # startup-code at 0x10000, running in real mode -# this is called either by the ipl loader or directly by PSW restart or linload +# this is called either by the ipl loader or directly by PSW restart +# or linload or SALIPL # .org 0x10000 - .globl start -start: basr %r13,0 # get base +startup:basr %r13,0 # get base .LPG1: lctl %c0,%c15,.Lctl-.LPG1(%r13) # load all control registers l %r12,.Lparm1-.LPG1(%r13) # pointer to parameter area # -# find out memory size. That is done in the ipl loader too but for -# ipl from dasd the size of the memory has to be detected too... +# find out memory size. # - icm %r0,15,MEMORY_SIZE-PARMAREA(%r12) - jnz .Lsizeok mvc 104(8,0),.Lpcmem-.LPG1(%r13) # setup program check handler slr %r1,%r1 lhi %r2,1 @@ -497,23 +450,57 @@ start: basr %r13,0 # get base .Lloop: l %r0,0(%r1) # test page ar %r1,%r2 # add 1M - jnm .Lloop # r1 < 0x80000000 -> loop + bnm .Lloop-.LPG1(%r13) # r1 < 0x80000000 -> loop .Lchkmem: n %r1,.L4malign-.LPG1(%r13) # align to multiples of 4M st %r1,MEMORY_SIZE-PARMAREA(%r12) # store memory size .Lsizeok: +# +# Now we have to move the ramdisk to a location approriate for the +# memory size. If we have more than 64 MB of memory we move it to 32MB +# to make room for the page tables set up by paging_init. +# + l %r1,MEMORY_SIZE-PARMAREA(%r12) + cl %r1,.Lbigmem-.LPG1(%r13) # memory < 64mb ? + bl .Lnomove-.LPG1(%r13) # if yes ramdisk @8MB is ok + icm %r4,15,INITRD_START-PARMAREA(%r12) + bz .Lnomove-.LPG1(%r13) + l %r2,.Lrdstart-.LPG1(%r13) # new address of ramdisk + st %r2,INITRD_START-PARMAREA(%r12) + l %r1,INITRD_SIZE-PARMAREA(%r12) + ar %r2,%r1 # we start moving at the end + ar %r4,%r1 # because new location > old location +.Lmove: lr %r0,%r2 # new - old is the maximum we can move + sr %r0,%r4 # because of overlapping + cr %r0,%r1 # we shouldn't move more than there is + bnh .Lnoend-.LPG1(%r13) + lr %r0,%r1 +.Lnoend:cl %r0,.Lmaxchunk-.LPG1(%r13) # mvcl can move 2^24-1 in one go + bnh .Lchunk-.LPG1(%r13) + l %r0,.Lmaxchunk-.LPG1(%r13) +.Lchunk:sr %r2,%r0 # make source & destination pointer + sr %r4,%r0 + lr %r3,%r0 # set source & destination length + lr %r5,%r0 + mvcl %r2,%r4 + sr %r2,%r0 # substract length again, since + sr %r4,%r0 # mvcl added it to the pointers + sr %r1,%r0 # substract chunk size from length + bnz .Lmove-.LPG1(%r13) +.Lnomove: + # # find out if we are running under VM # stidp __LC_CPUID # store cpuid tm __LC_CPUID,0xff # running under VM ? - jno .Lnovm + bno .Lnovm-.LPG1(%r13) oi MACHINE_FLAGS+3-PARMAREA(%r12),1 # set VM flag .Lnovm: lh %r0,__LC_CPUID+4 # get cpu version chi %r0,0x7490 # running on a P/390 ? - jne .Lnop390 + bne .Lnop390-.LPG1(%r13) oi MACHINE_FLAGS+3-PARMAREA(%r12),4 # set P/390 flag .Lnop390: @@ -526,6 +513,7 @@ start: basr %r13,0 # get base adbr %f0,%f2 # test IEEE add instruction oi MACHINE_FLAGS+3-PARMAREA(%r12),2 # set IEEE fpu flag .Lchkfpu: + # # find out if we have the CSP instruction # @@ -563,6 +551,9 @@ start: basr %r13,0 # get base .Lflt0: .double 0 .Lparm1:.long PARMAREA .L4malign:.long 0xffc00000 +.Lbigmem:.long 0x04000000 +.Lrdstart:.long 0x02000000 +.Lmaxchunk:.long 0x00ffffff # # params at 10400 (setup.h) @@ -573,21 +564,12 @@ start: basr %r13,0 # get base .long 0 # MEMORY_SIZE .long 0 # MACHINE_FLAGS (bit 0:VM, bit 1:IEEE) .long RAMDISK_ORIGIN # INITRD_START - .long 0x800000 # INITRD_SIZE + .long RAMDISK_SIZE # INITRD_SIZE .word 0 # RAMDISK_FLAGS .org COMMAND_LINE -# .byte "root=/dev/nfs rw nfsroot=9.164.160.7:/home/mschwide/nfsboot " -# .byte "ip=9.164.147.12:9.164.160.7:9.164.147.1:255.255.255.0:vmlinux:tr0:off" -# .byte "root=/dev/nfs nfsroot=9.164.160.7:/home/mschwide/nfsboot " -# .byte "ip=9.164.181.228:9.164.160.7:9.164.181.1:255.255.224.0:vmlinux:tr0:off" -# .byte "root=/dev/nfs nfsroot=9.164.160.7:/home/pasch/nfsboot " -# .byte "ip=9.164.185.120:9.164.160.7:9.164.181.1:255.255.224.0:vmlinux:tr0:off" -# .byte "mdisk=402:65536:1229,403:131072:2780 root=/dev/mnda ro" -# .byte "root=/dev/nfs rw nfsroot=9.164.160.209:/usr/local/nfsboot " -# .byte "ip=9.164.181.228:9.164.160.209:9.164.181.1:255.255.224.0:vmlinux:tr0:off" .byte "root=/dev/ram0 ro" -# .byte 0 + .byte 0 # # startup-code, running in virtual mode diff --git a/arch/s390/kernel/irq.c b/arch/s390/kernel/irq.c index f90f91632eeb..d110f9afdcf3 100644 --- a/arch/s390/kernel/irq.c +++ b/arch/s390/kernel/irq.c @@ -86,7 +86,7 @@ int get_irq_list(char *buf) continue; p += sprintf(p, "%3d: ",i); -#ifndef __SMP__ +#ifndef CONFIG_SMP p += sprintf(p, "%10u ", kstat_irqs(i)); #else for (j=0; j #include +static void display_emulation_not_implemented(char *instr) +{ + struct pt_regs *regs=current->tss.regs; + printk("%s not implemented\n",instr); + printk("Process with %s instruction %s (pid: %d, stackpage=%08X)\n", + instr, + current->comm, current->pid, 4096+(addr_t)current); + printk("%s's PSW: %08lx %08lx\n",instr, + (unsigned long) regs->psw.mask, + (unsigned long) regs->psw.addr); +} + static void set_CC_df(__u64 val1,__u64 val2) { int rc; rc = __cmpdf2(val1,val2); @@ -69,7 +81,7 @@ static void emu_aebr (int rx, int ry) { } static void emu_axbr (int rx, int ry) { - printk("axbr emulation not implemented!\n"); + display_emulation_not_implemented("axbr"); } static void emu_cdb (int rx, __u64 val) { @@ -109,15 +121,15 @@ static void emu_cfebr (int rx, int ry, int mask) { } static void emu_cfxbr (int rx, int ry, int mask) { - printk("cfxbr emulation not implemented!\n"); + display_emulation_not_implemented("cfxbr"); } static void emu_cxbr (int rx, int ry) { - printk("cxbr emulation not implemented!\n"); + display_emulation_not_implemented("cxbr"); } static void emu_cxfbr (int rx, int ry) { - printk("cxfbr emulation not implemented!\n"); + display_emulation_not_implemented("cxfbr"); } static void emu_ddb (int rx, __u64 val) { @@ -143,51 +155,51 @@ static void emu_debr (int rx, int ry) { } static void emu_didbr (int rx, int ry, int mask) { - printk("didbr emulation not implemented!\n"); + display_emulation_not_implemented("didbr"); } static void emu_diebr (int rx, int ry, int mask) { - printk("diebr emulation not implemented!\n"); + display_emulation_not_implemented("diebr"); } static void emu_dxbr (int rx, int ry) { - printk("dxbr emulation not implemented!\n"); + display_emulation_not_implemented("dxbr"); } static void emu_efpc (int rx, int ry) { - printk("efpc emulation not implemented!\n"); + display_emulation_not_implemented("efpc"); } static void emu_fidbr (int rx, int ry, int mask) { - printk("fidbr emulation not implemented!\n"); + display_emulation_not_implemented("fidbr"); } static void emu_fiebr (int rx, int ry, int mask) { - printk("fiebr emulation not implemented!\n"); + display_emulation_not_implemented("fiebr"); } static void emu_fixbr (int rx, int ry, int mask) { - printk("fixbr emulation not implemented!\n"); + display_emulation_not_implemented("fixbr"); } static void emu_kdb (int rx, __u64 val) { - printk("kdb emulation not implemented!\n"); + display_emulation_not_implemented("kdb"); } static void emu_kdbr (int rx, int ry) { - printk("kdbr emulation not implemented!\n"); + display_emulation_not_implemented("kdbr"); } static void emu_keb (int rx, __u32 val) { - printk("keb emulation not implemented!\n"); + display_emulation_not_implemented("keb"); } static void emu_kebr (int rx, int ry) { - printk("kebr emulation not implemented!\n"); + display_emulation_not_implemented("kebr"); } static void emu_kxbr (int rx, int ry) { - printk("kxbr emulation not implemented!\n"); + display_emulation_not_implemented("kxbr"); } static void emu_lcdbr (int rx, int ry) { @@ -203,7 +215,7 @@ static void emu_lcebr (int rx, int ry) { } static void emu_lcxbr (int rx, int ry) { - printk("lcxbr emulation not implemented!\n"); + display_emulation_not_implemented("lcxbr"); } static void emu_ldeb (int rx, __u32 val) { @@ -216,7 +228,7 @@ static void emu_ldebr (int rx, int ry) { } static void emu_ldxbr (int rx, int ry) { - printk("ldxbr emulation not implemented!\n"); + display_emulation_not_implemented("ldxbr"); } static void emu_ledbr (int rx, int ry) { @@ -225,19 +237,19 @@ static void emu_ledbr (int rx, int ry) { } static void emu_lexbr (int rx, int ry) { - printk("lexbr emulation not implemented!\n"); + display_emulation_not_implemented("lexbr"); } static void emu_lndbr (int rx, int ry) { - printk("lndbr emulation not implemented!\n"); + display_emulation_not_implemented("lndbr"); } static void emu_lnebr (int rx, int ry) { - printk("lnebr emulation not implemented!\n"); + display_emulation_not_implemented("lnebr"); } static void emu_lnxbr (int rx, int ry) { - printk("lnxbr emulation not implemented!\n"); + display_emulation_not_implemented("lnxbr"); } static void emu_lpdbr (int rx, int ry) { @@ -251,7 +263,7 @@ static void emu_lpebr (int rx, int ry) { } static void emu_lpxbr (int rx, int ry) { - printk("lpxbr emulation not implemented!\n"); + display_emulation_not_implemented("lpxbr"); } static void emu_ltdbr (int rx, int ry) { @@ -265,39 +277,39 @@ static void emu_ltebr (int rx, int ry) { } static void emu_ltxbr (int rx, int ry) { - printk("ltxbr emulation not implemented!\n"); + display_emulation_not_implemented("ltxbr"); } static void emu_lxdb (int rx, __u64 val) { - printk("lxdb emulation not implemented!\n"); + display_emulation_not_implemented("lxdb"); } static void emu_lxdbr (int rx, int ry) { - printk("lxdbr emulation not implemented!\n"); + display_emulation_not_implemented("lxdbr"); } static void emu_lxeb (int rx, __u32 val) { - printk("lxeb emulation not implemented!\n"); + display_emulation_not_implemented("lxeb"); } static void emu_lxebr (int rx, int ry) { - printk("lxebr emulation not implemented!\n"); + display_emulation_not_implemented("lxebr"); } static void emu_madb (int rx, __u64 val, int mask) { - printk("madb emulation not implemented!\n"); + display_emulation_not_implemented("madb"); } static void emu_madbr (int rx, int ry, int mask) { - printk(" emulation not implemented!\n"); + display_emulation_not_implemented("madbr"); } static void emu_maeb (int rx, __u32 val, int mask) { - printk("maeb emulation not implemented!\n"); + display_emulation_not_implemented("maeb"); } static void emu_maebr (int rx, int ry, int mask) { - printk("maebr emulation not implemented!\n"); + display_emulation_not_implemented("maebr"); } static void emu_mdb (int rx, __u64 val) { @@ -312,11 +324,11 @@ static void emu_mdbr (int rx, int ry) { } static void emu_mdeb (int rx, __u32 val) { - printk("mdeb emulation not implemented!\n"); + display_emulation_not_implemented("mdeb"); } static void emu_mdebr (int rx, int ry) { - printk("mdebr emulation not implemented!\n"); + display_emulation_not_implemented("mdebr"); } static void emu_meeb (int rx, __u32 val) { @@ -332,31 +344,31 @@ static void emu_meebr (int rx, int ry) { } static void emu_msdb (int rx, __u64 val, int mask) { - printk("msdb emulation not implemented!\n"); + display_emulation_not_implemented("msdb"); } static void emu_msdbr (int rx, int ry, int mask) { - printk("msdbr emulation not implemented!\n"); + display_emulation_not_implemented("msdbr"); } static void emu_mseb (int rx, __u32 val, int mask) { - printk("mseb emulation not implemented!\n"); + display_emulation_not_implemented("mseb"); } static void emu_msebr (int rx, int ry, int mask) { - printk("msebr emulation not implemented!\n"); + display_emulation_not_implemented("msebr"); } static void emu_mxbr (int rx, int ry) { - printk("mxbr emulation not implemented!\n"); + display_emulation_not_implemented("mxbr"); } static void emu_mxdb (int rx, __u64 val) { - printk("mxdb emulation not implemented!\n"); + display_emulation_not_implemented("mxdb"); } static void emu_mxdbr (int rx, int ry) { - printk("mxdbr emulation not implemented!\n"); + display_emulation_not_implemented("mxdbr"); } static void emu_sdb (int rx, __u64 val) { @@ -384,43 +396,43 @@ static void emu_sebr (int rx, int ry) { } static void emu_sfpc (int rx, int ry) { - printk("sfpc emulation not implemented!\n"); + display_emulation_not_implemented("sfpc"); } static void emu_sqdb (int rx, __u64 val) { - printk("sqdb emulation not implemented!\n"); + display_emulation_not_implemented("sqdb"); } static void emu_sqdbr (int rx, int ry) { - printk("sqdbr emulation not implemented!\n"); + display_emulation_not_implemented("sqdbr"); } static void emu_sqeb (int rx, __u32 val) { - printk("sqeb emulation not implemented!\n"); + display_emulation_not_implemented("sqeb"); } static void emu_sqebr (int rx, int ry) { - printk("sqebr emulation not implemented!\n"); + display_emulation_not_implemented("sqebr"); } static void emu_sqxbr (int rx, int ry) { - printk("sqxbr emulation not implemented!\n"); + display_emulation_not_implemented("sqxbr"); } static void emu_sxbr (int rx, int ry) { - printk("sxbr emulation not implemented!\n"); + display_emulation_not_implemented("sxbr"); } static void emu_tcdb (int rx, __u64 val) { - printk("tcdb emulation not implemented!\n"); + display_emulation_not_implemented("tcdb"); } static void emu_tceb (int rx, __u32 val) { - printk("tceb emulation not implemented!\n"); + display_emulation_not_implemented("tceb"); } static void emu_tcxb (int rx, __u64 val) { - printk("tcxb emulation not implemented!\n"); + display_emulation_not_implemented("tcxb"); } diff --git a/arch/s390/kernel/process.c b/arch/s390/kernel/process.c index f5d13c3c22f7..f71b5fc31e1c 100644 --- a/arch/s390/kernel/process.c +++ b/arch/s390/kernel/process.c @@ -57,7 +57,7 @@ asmlinkage void ret_from_fork(void) __asm__("ret_from_fork"); static psw_t wait_psw; -#ifndef __SMP__ +#ifndef CONFIG_SMP static #endif int cpu_idle(void *unused) @@ -69,7 +69,12 @@ int cpu_idle(void *unused) wait_psw.mask = _WAIT_PSW_MASK; wait_psw.addr = (unsigned long) &&idle_wakeup | 0x80000000L; while(1) { +#ifdef CONFIG_SMP + if (atomic_read(&global_bh_lock) == 0 && + (bh_mask & bh_active)) { +#else if (bh_mask & bh_active) { +#endif do_bottom_half(); continue; } diff --git a/arch/s390/kernel/s390_ksyms.c b/arch/s390/kernel/s390_ksyms.c index 71a693960632..58a2568cab70 100644 --- a/arch/s390/kernel/s390_ksyms.c +++ b/arch/s390/kernel/s390_ksyms.c @@ -5,10 +5,17 @@ */ #include #include +#include +#include +#include #include #include #include #include +#include +#include +#include +#include #if CONFIG_CHANDEV #include #endif @@ -16,7 +23,6 @@ #include #endif - /* * I/O subsystem */ @@ -30,13 +36,28 @@ EXPORT_SYMBOL(get_irq_by_devno); EXPORT_SYMBOL(get_devno_by_irq); EXPORT_SYMBOL(get_irq_first); EXPORT_SYMBOL(get_irq_next); +EXPORT_SYMBOL(read_conf_data); +EXPORT_SYMBOL(read_dev_chars); +EXPORT_SYMBOL(s390_request_irq_special); +EXPORT_SYMBOL(s390_device_register); +EXPORT_SYMBOL(s390_device_unregister); + +EXPORT_SYMBOL(ccw_alloc_request); +EXPORT_SYMBOL(ccw_free_request); -/* - * External interrupts - */ EXPORT_SYMBOL(register_external_interrupt); EXPORT_SYMBOL(unregister_external_interrupt); +/* + * debug feature + */ +EXPORT_SYMBOL(debug_register); +EXPORT_SYMBOL(debug_unregister); +EXPORT_SYMBOL(debug_event); +EXPORT_SYMBOL(debug_text_event); +EXPORT_SYMBOL(debug_exception); +EXPORT_SYMBOL(debug_text_exception); + /* * memory management */ @@ -61,10 +82,18 @@ EXPORT_SYMBOL_NOVERS(strrchr); EXPORT_SYMBOL_NOVERS(strtok); EXPORT_SYMBOL_NOVERS(strpbrk); +EXPORT_SYMBOL_NOVERS(_ascebc_500); +EXPORT_SYMBOL_NOVERS(_ebcasc_500); +EXPORT_SYMBOL_NOVERS(_ascebc); +EXPORT_SYMBOL_NOVERS(_ebcasc); +EXPORT_SYMBOL_NOVERS(_ebc_tolower); +EXPORT_SYMBOL_NOVERS(_ebc_toupper); + /* * misc. */ -#ifdef __SMP__ +EXPORT_SYMBOL(__udelay); +#ifdef CONFIG_SMP #include EXPORT_SYMBOL(__global_cli); EXPORT_SYMBOL(__global_sti); @@ -73,17 +102,14 @@ EXPORT_SYMBOL(__global_restore_flags); EXPORT_SYMBOL(global_bh_lock); EXPORT_SYMBOL(synchronize_bh); EXPORT_SYMBOL(kernel_flag); +EXPORT_SYMBOL(smp_ctl_set_bit); +EXPORT_SYMBOL(smp_ctl_clear_bit); #endif EXPORT_SYMBOL(kernel_thread); EXPORT_SYMBOL(csum_fold); -#if CONFIG_CHANDEV -EXPORT_SYMBOL(chandev_register_and_probe); -EXPORT_SYMBOL(chandev_unregister); -EXPORT_SYMBOL(chandev_initdevice); -EXPORT_SYMBOL(chandev_initnetdevice); -#endif +EXPORT_SYMBOL(genhd_dasd_name); + #if CONFIG_IP_MULTICAST /* Required for lcs gigibit ethernet multicast support */ EXPORT_SYMBOL(arp_mc_map); #endif - diff --git a/arch/s390/kernel/s390io.c b/arch/s390/kernel/s390io.c index e80b1d05465d..c63e62852d89 100644 --- a/arch/s390/kernel/s390io.c +++ b/arch/s390/kernel/s390io.c @@ -49,7 +49,6 @@ ioinfo_t *ioinfo[__MAX_SUBCHANNELS] = { static spinlock_t sync_isc = SPIN_LOCK_UNLOCKED; // synchronous irq processing lock static psw_t io_sync_wait; // wait PSW for sync IO, prot. by sync_isc -static psw_t io_new_psw; // save I/O new PSW, prot. by sync_isc static int cons_dev = -1; // identify console device static int init_IRQ_complete = 0; static schib_t init_schib; @@ -340,7 +339,8 @@ void s390_free_irq(unsigned int irq, void *dev_id) { s390irq_spin_unlock_irqrestore( irq, flags); - printk("free_irq() : error, dev_id does not match !"); + printk( "free_irq(%04X) : error, " + "dev_id does not match !", irq); } /* endif */ @@ -349,7 +349,8 @@ void s390_free_irq(unsigned int irq, void *dev_id) { s390irq_spin_unlock_irqrestore( irq, flags); - printk("free_irq() : error, no action block ... !"); + printk( "free_irq(%04X) : error, " + "no action block ... !\n", irq); } /* endif */ @@ -906,7 +907,6 @@ int s390_start_IO( int irq, /* IRQ */ if ( flag & DOIO_WAIT_FOR_INTERRUPT ) { int io_sub = -1; - __u32 io_parm; psw_t io_new_psw; int ccode; uint64_t time_start; @@ -2504,15 +2504,7 @@ int s390_process_IRQ( unsigned int irq ) ioinfo[irq]->devstat.flag |= DEVSTAT_FINAL_STATUS; ((devstat_t *)(action->dev_id))->flag |= DEVSTAT_FINAL_STATUS; - if ( ioinfo[irq]->ui.flags.newreq ) - { - action->handler( irq, ioinfo[irq]->u_intparm ); - } - else - { - ((io_handler_func1_t)action->handler)( irq, action->dev_id, ®s ); - - } /* endif */ + action->handler( irq, action->dev_id, ®s ); // // reset intparm after final status or we will badly present unsolicited @@ -2544,15 +2536,7 @@ int s390_process_IRQ( unsigned int irq ) */ if ( ret ) { - if ( ioinfo[irq]->ui.flags.newreq ) - { - action->handler( irq, ioinfo[irq]->u_intparm ); - } - else - { - ((io_handler_func1_t)action->handler)( irq, action->dev_id, ®s ); - - } /* endif */ + action->handler( irq, action->dev_id, ®s ); } /* endif */ @@ -2573,23 +2557,14 @@ int s390_process_IRQ( unsigned int irq ) ((devstat_t *)(action->dev_id))->flag |= DEVSTAT_PCI; ioinfo[irq]->devstat.cstat &= ~SCHN_STAT_PCI; } - else if ( actl & SCSW_ACTL_SUSPENDED ) + + if ( actl & SCSW_ACTL_SUSPENDED ) { ((devstat_t *)(action->dev_id))->flag |= DEVSTAT_SUSPENDED; } /* endif */ - if ( ioinfo[irq]->ui.flags.newreq ) - { - action->handler( irq, ioinfo[irq]->u_intparm ); - } - else - { - ((io_handler_func1_t)action->handler)( irq, - action->dev_id, - ®s ); - - } /* endif */ + action->handler( irq, action->dev_id, ®s ); } /* endif */ @@ -2672,15 +2647,7 @@ int s390_process_IRQ( unsigned int irq ) if ( !ioinfo[irq]->ui.flags.s_pend ) { - if ( ioinfo[irq]->ui.flags.newreq ) - { - action->handler( irq, ioinfo[irq]->u_intparm ); - } - else - { - ((io_handler_func1_t)action->handler)( irq, action->dev_id, ®s ); - - } /* endif */ + action->handler( irq, action->dev_id, ®s ); } /* endif */ @@ -3794,17 +3761,27 @@ int get_dev_info_by_irq( int irq, dev_info_t *pdi) pdi->devno = ioinfo[irq]->schib.pmcw.dev; pdi->irq = irq; - if ( ioinfo[irq]->ui.flags.oper ) + if ( ioinfo[irq]->ui.flags.oper + && !ioinfo[irq]->ui.flags.unknown ) { pdi->status = 0; memcpy( &(pdi->sid_data), &ioinfo[irq]->senseid, sizeof( senseid_t)); } + else if ( ioinfo[irq]->ui.flags.unknown ) + { + pdi->status = DEVSTAT_UNKNOWN_DEV; + memset( &(pdi->sid_data), + '\0', + sizeof( senseid_t)); + pdi->sid_data.cu_type = 0xFFFF; + + } else { pdi->status = DEVSTAT_NOT_OPER; - memcpy( &(pdi->sid_data), + memset( &(pdi->sid_data), '\0', sizeof( senseid_t)); pdi->sid_data.cu_type = 0xFFFF; @@ -3814,10 +3791,9 @@ int get_dev_info_by_irq( int irq, dev_info_t *pdi) if ( ioinfo[irq]->ui.flags.ready ) pdi->status |= DEVSTAT_DEVICE_OWNED; - return 0; - } /* endif */ + return 0; } @@ -3843,23 +3819,37 @@ int get_dev_info_by_devno( unsigned int devno, dev_info_t *pdi) if ( ioinfo[i] != INVALID_STORAGE_AREA && ioinfo[i]->schib.pmcw.dev == devno ) { - if ( ioinfo[i]->ui.flags.oper ) - { - pdi->status = 0; + pdi->irq = i; pdi->devno = devno; + if ( ioinfo[i]->ui.flags.oper + && !ioinfo[i]->ui.flags.unknown ) + { + pdi->status = 0; + memcpy( &(pdi->sid_data), &ioinfo[i]->senseid, sizeof( senseid_t)); } + else if ( ioinfo[i]->ui.flags.unknown ) + { + pdi->status = DEVSTAT_UNKNOWN_DEV; + + memset( &(pdi->sid_data), + '\0', + sizeof( senseid_t)); + + pdi->sid_data.cu_type = 0xFFFF; + } else { pdi->status = DEVSTAT_NOT_OPER; - pdi->irq = i; - pdi->devno = devno; - memcpy( &(pdi->sid_data), '\0', sizeof( senseid_t)); + memset( &(pdi->sid_data), + '\0', + sizeof( senseid_t)); + pdi->sid_data.cu_type = 0xFFFF; } /* endif */ @@ -3975,6 +3965,7 @@ void s390_device_recognition_irq( int irq ) else { ioinfo[irq]->ui.flags.syncio = 1; // global + ioinfo[irq]->ui.flags.unknown = 0; memset( &ioinfo[irq]->senseid, '\0', sizeof( senseid_t)); @@ -4735,14 +4726,14 @@ int s390_SenseID( int irq, senseid_t *sid, __u8 lpm ) ioinfo[irq]->schib.pmcw.dev, irq); #endif - ioinfo[irq]->ui.flags.oper = 0; + ioinfo[irq]->ui.flags.unknown = 1; } /* endif */ /* * Issue device info message if unit was operational . */ - if ( ioinfo[irq]->ui.flags.oper ) + if ( ioinfo[irq]->ui.flags.unknown ) { if ( sid->dev_type != 0 ) { @@ -4766,7 +4757,7 @@ int s390_SenseID( int irq, senseid_t *sid, __u8 lpm ) } /* endif */ - if ( ioinfo[irq]->ui.flags.oper ) + if ( ioinfo[irq]->ui.flags.unknown ) irq_ret = 0; else irq_ret = -ENODEV; @@ -5524,6 +5515,7 @@ void s390_do_crw_pending( crwe_t *pcrwe ) /* added by Holger Smolinski for reipl support in reipl.S */ +extern void do_reipl (int); void reipl ( int sch ) { diff --git a/arch/s390/kernel/s390mach.c b/arch/s390/kernel/s390mach.c index 0ac379cf624b..898f0307e462 100644 --- a/arch/s390/kernel/s390mach.c +++ b/arch/s390/kernel/s390mach.c @@ -119,9 +119,9 @@ void s390_init_machine_check( void ) down( &s_sem[0]); - smp_ctl_clear_bit( 14, 25 ); // disable damage MCH + ctl_clear_bit( 14, 25 ); // disable damage MCH #if 1 - smp_ctl_set_bit( 14, 28 ); // enable channel report MCH + ctl_set_bit( 14, 28 ); // enable channel report MCH #endif #ifdef S390_MACHCHK_DEBUG diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c index 2fecb21e1308..c7fdaa682554 100644 --- a/arch/s390/kernel/setup.c +++ b/arch/s390/kernel/setup.c @@ -43,6 +43,7 @@ __u16 boot_cpu_addr; int cpus_initialized = 0; unsigned long cpu_initialized = 0; +volatile int __cpu_logical_map[NR_CPUS]; /* logical cpu to cpu address */ /* * Setup options @@ -75,6 +76,7 @@ static char command_line[COMMAND_LINE_SIZE] = { 0, }; void cpu_init (void) { int nr = smp_processor_id(); + int addr = hard_smp_processor_id(); if (test_and_set_bit(nr,&cpu_initialized)) { printk("CPU#%d ALREADY INITIALIZED!!!!!!!!!\n", nr); @@ -86,7 +88,7 @@ void cpu_init (void) * Store processor id in lowcore (used e.g. in timer_interrupt) */ asm volatile ("stidp %0": "=m" (S390_lowcore.cpu_data.cpu_id)); - S390_lowcore.cpu_data.cpu_addr = hard_smp_processor_id(); + S390_lowcore.cpu_data.cpu_addr = addr; S390_lowcore.cpu_data.cpu_nr = nr; /* @@ -132,7 +134,7 @@ __initfunc(void vmpoff_setup(char *str, char *ints)) * Reboot, halt and power_off routines for non SMP. */ -#ifndef __SMP__ +#ifndef CONFIG_SMP void machine_restart(char * __unused) { reipl(S390_lowcore.ipl_device); @@ -142,14 +144,14 @@ void machine_halt(void) { if (MACHINE_IS_VM && strlen(vmhalt_cmd) > 0) cpcmd(vmhalt_cmd, NULL, 0); - disabled_wait(0); + signal_processor(smp_processor_id(), sigp_stop_and_store_status); } void machine_power_off(void) { if (MACHINE_IS_VM && strlen(vmpoff_cmd) > 0) cpcmd(vmpoff_cmd, NULL, 0); - disabled_wait(0); + signal_processor(smp_processor_id(), sigp_stop_and_store_status); } #endif @@ -190,6 +192,7 @@ __initfunc(void setup_arch(char **cmdline_p, */ cpu_init(); boot_cpu_addr = S390_lowcore.cpu_data.cpu_addr; + __cpu_logical_map[0] = boot_cpu_addr; /* * print what head.S has found out about the machine @@ -259,11 +262,14 @@ __initfunc(void setup_arch(char **cmdline_p, delay = delay*60*1000000; from++; } - tod_wait(delay); + /* now wait for the requested amount of time */ + udelay(delay); } cn = *(from++); if (!cn) break; + if (cn == '\n') + cn = ' '; /* replace newlines with space */ if (cn == ' ' && c == ' ') continue; /* remove additional spaces */ c = cn; @@ -271,6 +277,7 @@ __initfunc(void setup_arch(char **cmdline_p, break; *(to++) = c; } + if (c == ' ' && to > command_line) to--; *to = '\0'; *cmdline_p = command_line; memory_end += PAGE_OFFSET; @@ -298,12 +305,12 @@ __initfunc(void setup_arch(char **cmdline_p, void print_cpu_info(struct cpuinfo_S390 *cpuinfo) { printk("cpu %d " -#ifdef __SMP__ +#ifdef CONFIG_SMP "phys_idx=%d " #endif "vers=%02X ident=%06X machine=%04X unused=%04X\n", cpuinfo->cpu_nr, -#ifdef __SMP__ +#ifdef CONFIG_SMP cpuinfo->cpu_addr, #endif cpuinfo->cpu_id.version, diff --git a/arch/s390/kernel/signal.c b/arch/s390/kernel/signal.c index 6fd939aaecc8..cdd09d293d18 100644 --- a/arch/s390/kernel/signal.c +++ b/arch/s390/kernel/signal.c @@ -231,15 +231,12 @@ badframe: asmlinkage int sys_rt_sigreturn(struct pt_regs *regs) { rt_sigframe *frame = (rt_sigframe *)regs->gprs[15]; - stack_t st; if (sigreturn_common(regs,sizeof(rt_sigframe))) goto badframe; - if (__copy_from_user(&st, &frame->uc.uc_stack, sizeof(st))) - goto badframe; /* It is more difficult to avoid calling this function than to call it and ignore errors. */ - do_sigaltstack(&st, NULL, regs->gprs[15]); + do_sigaltstack(&frame->uc.uc_stack, NULL, regs->gprs[15]); return regs->gprs[2]; badframe: @@ -359,6 +356,7 @@ static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, err |= __put_user(sas_ss_flags(orig_sp), &frame->uc.uc_stack.ss_flags); err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size); + err |= __put_user(&frame->sc,&frame->uc.sc); regs->gprs[3] = (addr_t)&frame->info; regs->gprs[4] = (addr_t)&frame->uc; diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c index b16c827f63f1..80b4acc27646 100644 --- a/arch/s390/kernel/smp.c +++ b/arch/s390/kernel/smp.c @@ -43,6 +43,7 @@ extern void update_one_process( struct task_struct *p, extern int cpu_idle(void * unused); extern __u16 boot_cpu_addr; +extern volatile int __cpu_logical_map[]; /* * An array with a pointer the lowcore of every CPU. @@ -53,7 +54,6 @@ struct _lowcore *lowcore_ptr[NR_CPUS]; unsigned int prof_multiplier[NR_CPUS]; unsigned int prof_counter[NR_CPUS]; volatile int cpu_number_map[NR_CPUS]; -volatile int __cpu_logical_map[NR_CPUS]; /* logical cpu to cpu address */ cycles_t cacheflush_time=0; int smp_threads_ready=0; /* Set when the idlers are all forked. */ unsigned long ipi_count=0; /* Number of IPIs delivered. */ @@ -107,7 +107,7 @@ void do_machine_halt(void) smp_send_stop(); if (MACHINE_IS_VM && strlen(vmhalt_cmd) > 0) cpcmd(vmhalt_cmd, NULL, 0); - disabled_wait(0); + signal_processor(smp_processor_id(), sigp_stop_and_store_status); } void machine_halt(void) @@ -124,7 +124,7 @@ void do_machine_power_off(void) smp_send_stop(); if (MACHINE_IS_VM && strlen(vmpoff_cmd) > 0) cpcmd(vmpoff_cmd, NULL, 0); - disabled_wait(0); + signal_processor(smp_processor_id(), sigp_stop_and_store_status); } void machine_power_off(void) @@ -417,7 +417,7 @@ int smp_signal_others(sigp_order_code order_code, u32 parameter, void smp_send_stop(void) { - smp_signal_others(sigp_stop, 0, TRUE, NULL); + smp_signal_others(sigp_stop_and_store_status, 0, TRUE, NULL); } /* @@ -472,7 +472,6 @@ void smp_count_cpus(void) { int curr_cpu; - __cpu_logical_map[0] = boot_cpu_addr; current->processor = 0; smp_num_cpus = 1; for (curr_cpu = 0; @@ -498,11 +497,16 @@ extern void cpu_init (void); int __init start_secondary(void *cpuvoid) { + /* Setup the cpu */ cpu_init(); + /* Print info about this processor */ print_cpu_info(&safe_get_cpu_lowcore(smp_processor_id()).cpu_data); + /* Wait for completion of smp startup */ while (!atomic_read(&smp_commenced)) /* nothing */ ; + /* init per CPU 100 hz timer */ init_100hz_timer(); + /* cpu_idle will call schedule for us */ return cpu_idle(NULL); } diff --git a/arch/s390/kernel/time.c b/arch/s390/kernel/time.c index 53c4c2e68a97..cc650354f9aa 100644 --- a/arch/s390/kernel/time.c +++ b/arch/s390/kernel/time.c @@ -145,7 +145,7 @@ void do_settimeofday(struct timeval *tv) * as well as call the "do_timer()" routine every clocktick */ -#ifdef __SMP__ +#ifdef CONFIG_SMP extern __u16 boot_cpu_addr; #endif @@ -160,7 +160,7 @@ void do_timer_interrupt(struct pt_regs *regs, __u16 error_code) save_flags(flags); cli(); -#ifdef __SMP__ +#ifdef CONFIG_SMP if(S390_lowcore.cpu_data.cpu_addr==boot_cpu_addr) { write_lock(&xtime_lock); last_timer_cc = S390_lowcore.jiffy_timer_cc; @@ -177,7 +177,7 @@ void do_timer_interrupt(struct pt_regs *regs, __u16 error_code) * profiling, except when we simulate SMP mode on a uniprocessor * system, in that case we have to call the local interrupt handler. */ -#ifdef __SMP__ +#ifdef CONFIG_SMP /* when SMP, do smp_local_timer_interrupt for *all* CPUs, but only do the rest for the boot CPU */ smp_local_timer_interrupt(regs); @@ -186,12 +186,12 @@ void do_timer_interrupt(struct pt_regs *regs, __u16 error_code) s390_do_profile(regs->psw.addr); #endif -#ifdef __SMP__ +#ifdef CONFIG_SMP if(S390_lowcore.cpu_data.cpu_addr==boot_cpu_addr) #endif { do_timer(regs); -#ifdef __SMP__ +#ifdef CONFIG_SMP write_unlock(&xtime_lock); #endif } diff --git a/arch/s390/lib/delay.c b/arch/s390/lib/delay.c index a30c3896c65d..136218a6783f 100644 --- a/arch/s390/lib/delay.c +++ b/arch/s390/lib/delay.c @@ -20,25 +20,30 @@ void __delay(unsigned long loops) { + /* + * To end the bloody studid and useless discussion about the + * BogoMips number I took the liberty to define the __delay + * function in a way that that resulting BogoMips number will + * yield the megahertz number of the cpu. The important function + * is udelay and that is done using the tod clock. -- martin. + */ __asm__ __volatile__( - "0: ahi %0,-1\n" - " jnm 0b" - : /* no outputs */ : "r" (loops) ); + "0: brct %0,0b" + : /* no outputs */ : "r" (loops/2) ); } -inline void __const_udelay(unsigned long xloops) +/* + * Waits for 'usecs' microseconds using the tod clock + */ +void __udelay(unsigned long usecs) { + uint64_t start_cc, end_cc; - __asm__("LR 3,%1\n\t" - "MR 2,%2\n\t" - "LR %0,2\n\t" - : "=r" (xloops) - : "r" (xloops) , "r" (loops_per_sec) - : "2" , "3"); - __delay(xloops); + if (usecs == 0) + return; + asm volatile ("STCK %0" : "=m" (start_cc)); + do { + asm volatile ("STCK %0" : "=m" (end_cc)); + } while (((end_cc - start_cc)/4096) < usecs); } -void __udelay(unsigned long usecs) -{ - __const_udelay(usecs * 0x000010c6); /* 2**32 / 1000000 */ -} diff --git a/arch/s390/mm/fault.c b/arch/s390/mm/fault.c index 2817e8375ff1..7f777fbebb58 100644 --- a/arch/s390/mm/fault.c +++ b/arch/s390/mm/fault.c @@ -74,24 +74,14 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long error_code) down(&mm->mmap_sem); vma = find_vma(mm, address); - if (!vma) { - printk("no vma for address %lX\n",address); + if (!vma) goto bad_area; - } if (vma->vm_start <= address) goto good_area; - if (!(vma->vm_flags & VM_GROWSDOWN)) { - printk("VM_GROWSDOWN not set, but address %lX \n",address); - printk("not in vma %p (start %lX end %lX)\n",vma, - vma->vm_start,vma->vm_end); + if (!(vma->vm_flags & VM_GROWSDOWN)) goto bad_area; - } - if (expand_stack(vma, address)) { - printk("expand of vma failed address %lX\n",address); - printk("vma %p (start %lX end %lX)\n",vma, - vma->vm_start,vma->vm_end); + if (expand_stack(vma, address)) goto bad_area; - } /* * Ok, we have a good vm_area for this memory access, so * we can handle it.. @@ -104,13 +94,8 @@ good_area: break; case 0x10: /* not present*/ case 0x11: /* not present*/ - if (!(vma->vm_flags & (VM_READ | VM_EXEC | VM_WRITE))) { - printk("flags %X of vma for address %lX wrong \n", - vma->vm_flags,address); - printk("vma %p (start %lX end %lX)\n",vma, - vma->vm_start,vma->vm_end); + if (!(vma->vm_flags & (VM_READ | VM_EXEC | VM_WRITE))) goto bad_area; - } break; default: printk("code should be 4, 10 or 11 (%lX) \n",error_code&0xFF); diff --git a/arch/s390/tools/dasdfmt/Makefile b/arch/s390/tools/dasdfmt/Makefile index f63ff468bd1b..81cbdea5f2e0 100644 --- a/arch/s390/tools/dasdfmt/Makefile +++ b/arch/s390/tools/dasdfmt/Makefile @@ -1,8 +1,8 @@ all: dasdfmt dasdfmt: dasdfmt.c - $(CROSS_COMPILE)gcc -o $@ $^ - $(STRIP) $@ + $(CROSS_COMPILE)gcc -I$(HPATH) -o $@ $^ + $(CROSS_COMPILE)strip $@ clean: rm -f dasdfmt diff --git a/arch/s390/tools/dasdfmt/dasdfmt.8 b/arch/s390/tools/dasdfmt/dasdfmt.8 index b082443223bc..9cbf87ab79e8 100644 --- a/arch/s390/tools/dasdfmt/dasdfmt.8 +++ b/arch/s390/tools/dasdfmt/dasdfmt.8 @@ -3,8 +3,7 @@ .SH NAME dasdfmt \- formatting of DSAD (ECKD) disk drives. .SH SYNOPSIS -\fBdasdfmt\fR [-tvyV] [-b \fIblockSize\fR] [\fIblockRange\fI] - \fIdiskSpec\fR +\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 @@ -25,6 +24,10 @@ Increases verbosity. 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. @@ -35,26 +38,17 @@ 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 -\fIblockRange\fR -This parameter specifies the number of the first and last block to be -formatted. If this parameter is \fBomitted\fR, formatting the \fBwhole\fR disk -is assumed. The \fIblockRange\fR can be specified in two different formats: -.sp - \fB-s\fR \fIstartBlock\fR \fB-e\fR \fIendBlock\fR -.br -or -.br - \fB-r\fR \fIstartBlock\fR-\fIendBlock\fR -.sp -If \fIstartBlock\fR is omitted, block \fB0\fR is assumed. If -\fIendBlock\fR is omitted, the last block of the disk is assumed. +\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/dd\fR\fIX\fR + \fB-f\fR \fB/dev/dasd\fR\fIX\fR .br or .br @@ -63,7 +57,7 @@ or 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 VM vdev number. +The second form uses simply the device number. .SH BUGS None so far ;-) diff --git a/arch/s390/tools/dasdfmt/dasdfmt.c b/arch/s390/tools/dasdfmt/dasdfmt.c index 2fabd0cc3cae..9f86a8f0477d 100644 --- a/arch/s390/tools/dasdfmt/dasdfmt.c +++ b/arch/s390/tools/dasdfmt/dasdfmt.c @@ -12,6 +12,8 @@ * detect non-switch parameters ("dasdfmt -n 170 XY") and complain about them */ +/* #define _LINUX_BLKDEV_H */ + #include #include #include @@ -31,7 +33,8 @@ #undef __KERNEL__ #include -#include +#include +#include #define EXIT_MISUSE 1 #define EXIT_BUSY 2 @@ -39,9 +42,11 @@ #define TEMPFILENAMECHARS 8 /* 8 characters are fixed in all temp filenames */ #define SLASHDEV "/dev/" #define PROC_DASD_DEVICES "/proc/dasd/devices" -#define PROC_MOUNTS "/proc/mounts" /* _PATH_MOUNTED is /etc/mtab - maybe bad */ +/* _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 @@ -73,19 +78,105 @@ 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] [] \n\n", - prog_name); +#ifdef RANGE_FORMATTING + printf("Usage: %s [-htvyLV] [-l