Commit ae04feb3 authored by Linus Torvalds's avatar Linus Torvalds

Import 2.1.79

parent 05648d56
# Maintained by Axel Boldt (boldt@math.ucsb.edu)
# Maintained by Axel Boldt (boldt@math.ucsb.edu)
#
# This version of the Linux kernel configuration help texts
# corresponds to the kernel versions 2.1.x. Be aware that these are
......@@ -3515,28 +3515,6 @@ CONFIG_SDLA
sdla.o. If you want to compile it as a module, say M here and read
Documentation/modules.txt.
WAN Router
CONFIG_WAN_ROUTER
Wide Area Networks (WANs), such as X.25, frame relay and leased
lines, are used to interconnect Local Area Networks (LANs) over vast
distances with data transfer rates significantly higher than those
achievable with commonly used asynchronous modem connections.
Usually, a quite expensive external device called `WAN router' is
needed to connect to a WAN.
As an alternative, WAN routing can be built into the Linux
kernel. With relatively inexpensive WAN interface cards available
on the market, a perfectly usable router can be built for less than
half the price of an external router. If you have one of those
cards (with appropriate WAN Link Driver) and wish to use your Linux
box as a WAN router, you may say 'Y' to this option. You will also
need a wan-tools package available via FTP (user: anonymous) from
ftp.sangoma.com. Read Documentation/networking/wan-router.txt for
more information.
WAN routing is always built as a module ( = code which can be
inserted in and removed from the running kernel whenever you want).
The module is called wanrouter.o. For general information about
modules read Documentation/modules.txt.
CPU is too slow to handle full bandwidth
CONFIG_CPU_IS_SLOW
###
......@@ -3640,68 +3618,79 @@ CONFIG_NET_SCH_PRIO
### schedulers?
###
WAN Router
CONFIG_WAN_ROUTER
Wide Area Networks (WANs), such as X.25, frame relay and leased
lines, are used to interconnect Local Area Networks (LANs) over vast
distances with data transfer rates significantly higher than those
achievable with commonly used asynchronous modem connections.
Usually, a quite expensive external device called `WAN router' is
needed to connect to WAN.
As an alternative, WAN router can be build into Linux kernel.
With relatively inexpensive WAN interface cards available on the
market, a perfectly usable router can be built for less than half a
price of an external router. If you have one of those cards (with
appropriate WAN Link Driver) and wish to use your Linux box as a WAN
router, you may say 'Y' to this option. You will also need a
wan-tools package available via FTP (user: anonymous) from
ftp.sangoma.com. Read Documentation/networking/wan-router.txt for
more information.
WAN router is always built as a module ( = code which can be
inserted in and removed from the running kernel whenever you want).
For general information about modules read Documentation/modules.txt.
WAN Drivers
CONFIG_WAN_DRIVERS
Say Y to this option if you are planning to use your Linux box as a
WAN ( = Wide Area Network) router ( = device used to interconnect
local area networks over wide area communication links, such as
leased lines and public data networks, e.g. X.25 and frame relay)
and you will be offered a list of WAN drivers currently available.
For more information, read
Documentation/networking/wan-router.txt. Note that the answer to
this question won't directly affect the kernel: saying N will just
cause this configure script to skip all the questions about WAN
drivers. If unsure, say N.
Say 'Y' to this option if you are planning to use your Linux box
as a WAN router ( = device used to interconnect local area networks
over wide area communication links, such as leased lines and public
data networks, e.g. X.25 and frame relay) and you will be offered a
list of WAN drivers currently available. For more information, read
Documentation/networking/wan-router.txt.
Sangoma WANPIPE(tm) multiprotocol cards
CONFIG_VENDOR_SANGOMA
WANPIPE from Sangoma Technologies Inc. (http://www.sangoma.com; to
browse the WWW, you need to have access to a machine on the Internet
that has a program like lynx or netscape) is a family of intelligent
multiprotocol WAN adapters with data transfer rates up to T1 (1.544
Mbps). They are also known as Synchronous Data Link Adapters (SDLA)
and designated S502E(A), S503 or S508. These cards support the X.25,
Frame Relay, and PPP protocols. If you have one or more of these
cards, say Y to this option and read
Documentation/networking/wanpipe.txt. The next questions will ask
you about the protocols you want the driver to support. The driver
will be compiled as a module ( = code which can be inserted in and
removed from the running kernel whenever you want). The module will
be called wanpipe.o. For general information about modules read
Documentation/modules.txt.
WANPIPE from Sangoma Technologies Inc. (http://www.sangoma.com)
is a family of intelligent multiprotocol WAN adapter with data
transfer rates up to T1 (1.544 Mbps). They are also known as
Synchronous Data Link Adapters (SDLA) and designated S502E(A), S503
or S508. If you have one of these cards, say 'Y' to this option.
WANPIPE driver is always built as a module ( = code which can be
inserted in and removed from the running kernel whenever you want).
For general information about modules read Documentation/modules.txt.
Maximum number of cards
CONFIG_WANPIPE_CARDS
Enter number of WANPIPE adapters installed in your machine. The
driver can support up to 8 cards. You may enter more than you
Enter number of WANPIPE adapters installed in your machine. The
driver can support up to 8 cards. You may enter more that you
actually have if you plan to add more cards in the future without
re-compiling the driver, but remember that in this case you'll waste
some kernel memory (about 1K per card).
WANPIPE X.25 support
CONFIG_WANPIPE_X25
Say Y to this option, if you are planning to connect a WANPIPE card
to an X.25 network. You should then also have said Y to "CCITT X.25
Packet Layer" and "LAPB Data Link Driver", above. If you say N, the
X.25 support will not be included in the driver (saves about 16K of
kernel memory).
Say 'Y' to this option, if you are planning to connect WANPIPE
card to an X.25 network. If you say 'N', the X.25 support will not
be included in the driver (saves about 16K of kernel memory).
WANPIPE Frame Relay support
CONFIG_WANPIPE_FR
Say Y to this option, if you are planning to connect a WANPIPE card
to a frame relay network. You should then also have said Y to "Frame
Relay (DLCI) support", above. If you say N, the frame relay
Say 'Y' to this option, if you are planning to connect WANPIPE
card to a frame relay network. If you say 'N', the frame relay
support will not be included in the driver (saves about 16K of
kernel memory).
WANPIPE PPP support
CONFIG_WANPIPE_PPP
Say Y to this option, if you are planning to connect a WANPIPE card
to a leased line using Point-to-Point protocol (PPP). You should
then also have said Y to "PPP (point-to-point) support", above. If
you say N, the PPP support will not be included in the driver (saves
Say 'Y' to this option, if you are planning to connect WANPIPE
card to a leased line using Point-to-Point protocol (PPP). If you
say 'N', the PPP support will not be included in the driver (saves
about 16K of kernel memory).
Sun LANCE Ethernet support
CONFIG_SUN_LANCE
This is support for lance ethernet cards on Sun workstations such as
Sun LANCE Ethernet support
CONFIG_SUN_LANCE
This is support for lance ethernet cards on Sun workstations such as
......@@ -7566,6 +7555,13 @@ CONFIG_VIDEO_BWQCAM
compile it as a module, say M here and read
Documentation/modules.txt.
Colour QuickCam Video For Linux
CONFIG_VIDEO_CQCAM
This is the video4linux driver for the colour version of the Connectix
Quickcam. If you have one of these cameras, say Y here, otherwise say N.
This driver does not work with the original monochrome Quickcam,
Quickcam VC or QuickClip. It is also available as a module (c-qcam.o).
Mediavision Pro Movie Studio Video For Linux
CONFIG_VIDEO_PMS
Say Y if you have such a thing. This driver is also available as a
......
------------------------------------------------------------------------------
WAN Router for Linux Operating System
------------------------------------------------------------------------------
Version 2.0.1 - Nov 28, 1997
Version 2.0.0 - Nov 06, 1997
Version 1.0.3 - June 3, 1997
Version 1.0.1 - January 30, 1997
Author: Jaspreet Singh <jaspreet@sangoma.com>
......@@ -8,6 +10,11 @@ Author: Jaspreet Singh <jaspreet@sangoma.com>
Copyright (c) 1995-1997 Sangoma Technologies Inc.
------------------------------------------------------------------------------
WARNING: This Version of WANPIPE supports only the S508 and S508/FT1 cards.
IF YOU OWN A S502E OR A S508 CARD THEN PLEASE CONTACT SANGOMA TECHNOLOGIES FOR
AN UPGRADE.
INTRODUCTION
Wide Area Networks (WANs) are used to interconnect Local Area Networks (LANs)
......@@ -73,10 +80,14 @@ assist WAN device driver writer by providing common services, such as:
To ba able to use Linux WAN Router you will also need a WAN Tools package
available from
ftp.sangoma.com/pub/linux/wantools-X.Y.Z.tgz
ftp.sangoma.com/pub/linux/vX.Y.Z/wantools-X.Y.Z.tgz
or
ftp.sangoma.com/pub/linux/vX.Y.Z/wanpipe-X.Y.Z.tgz
where vX.Y.Z represent the linux kernel version number.
For technical questions and/or comments regarding this product please e-mail
to genek@compuserve.com or dm@sangoma.com.
to jaspreet@sangoma.com or dm@sangoma.com.
......@@ -117,19 +128,55 @@ product.
REVISION HISTORY
2.0.1 Nov 28, 1997 - Protection of "enable_irq()" while
"disable_irq()" has been enabled from any other
routine (for Frame Relay, PPP and X25).
- Added additional Stats for Fpipemon and Ppipemon - Improved Load Sharing for multiple boards.
2.0.0 Nov 07, 1997 - Implemented protection of RACE conditions by
critical flags for FRAME RELAY and PPP.
- DLCI List interrupt mode implemented.
- IPX support in FRAME RELAY and PPP.
- IPX Server Support (MARS)
- More driver specific stats included in FPIPEMON
and PIPEMON.
1.0.5 July 28, 1997 - Configurable T391,T392,N391,N392,N393 for Frame
Relay in router.conf.
- Configurable Memory Address through router.conf
for Frame Relay, PPP and X.25. (commenting this
out enables auto-detection).
- Fixed freeing up received buffers using kfree()
for Frame Relay and X.25.
- Protect sdla_peek() by calling save_flags(),
cli() and restore_flags().
- Changed number of Trace elements from 32 to 20
- Added DLCI specific data monitoring in FPIPEMON.
1.0.4 July 10, 1997 - S508/FT1 monitoring capability in fpipemon and
ppipemon utilities.
- Configurable TTL for UDP packets.
- Multicast and Broadcast IP source addresses are
silently discarded.
1.0.3 June 3, 1997
o UDP port for multiple boards (Frame relay, PPP)
o Continuous Transmission of Configure Request Packet for PPP (this
support is only added for 508 cards)
o Connection Timeout for PPP changed from 900 to 0
o Flow Control for multiple boards and multiple channels (Frame Relay)
- UDP port for multiple boards (Frame relay, PPP)
Continuous Transmission of Configure Request
- Packet for PPP (this support is only added for
508 cards)
- Connection Timeout for PPP changed from 900 to 0
- Flow Control for multiple boards and multiple
channels (Frame Relay)
1.0.1 January 30, 1997
o Implemented user-readable status and statistics via /proc filesystem
- Implemented user-readable status and statistics
via /proc filesystem
1.0.0 December 31, 1996
o Initial version
- Initial version
>>>>>> END <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
------------------------------------------------------------------------------
WANPIPE(tm) Multiprotocol WAN Driver for Linux WAN Router
------------------------------------------------------------------------------
Release 3.1.0
January 30, 1997
Author: Gene Kozin <genek@compuserve.com>
Release 4.1
November 17, 1997
Author: Jaspreet Singh <jaspreet@sangoma.com>
Copyright (c) 1995-1997 Sangoma Technologies Inc.
------------------------------------------------------------------------------
......@@ -23,8 +23,13 @@ package to be able to use Linux WAN Router and WANPIPE driver. The package
is available via the Internet from Sangoma Technologies' anonymous FTP server:
ftp.sangoma.com/pub/linux/wantools-X.Y.Z.tgz
or
ftp.sangoma.com/pub/linux/wanpipe-X.Y.Z.tgz
For technical questions and/or comments please e-mail to genek@compuserve.com.
The name of the package differ only due to naming convention. The functionalityof wantools and wanpipe packages are the same. The latest version of WAN
Drivers is wanpipe-2.0.0.
For technical questions and/or comments please e-mail to jaspreet@sangoma.com.
For general inquiries please contact Sangoma Technologies Inc. by
Hotline: 1-800-388-2475 (USA and Canada, toll free)
......@@ -53,10 +58,13 @@ Ave, Cambridge, MA 02139, USA.
NEW IN THIS RELEASE
o Implemented as WAN Link Driver compliant with Linux WAN Router interface
o Added support for X.25 protocol
o Miscellaneous bug fixes and performance improvements
o This Version of WANPIPE supports only the S508 and S508/FT1 cards. IF YOU
OWN A S502E OR A S508 CARD THEN PLEASE CONTACT SANGOMA TECHNOLOGIES FOR AN
UPGRADE.
o Protection of "enable_irq()" while "disable_irq()" has been enabled from
any other routine (for Frame Relay, PPP and X25).
o Added additional Stats for Fpipemon and Ppipemon.
o Improved Load Sharing for multiple boards
FILE LIST
......@@ -64,23 +72,39 @@ FILE LIST
drivers/net:
README.wanpipe This file
sdladrv.c SDLA support module source code
wpmain.c WANPIPE driver module main source code
wpx.c WANPIPE driver module X.25 source code
wpf.c WANPIPE driver module frame relay source code
wpp.c WANPIPE driver module PPP source code
sdla_fr.c SDLA Frame Relay source code
sdla_ppp.c SDLA PPP source code
sdla_x25.c SDLA X25 source code
sdlamain.c SDLA support source code
include/linux:
sdla_x25.h SDLA X.25 firmware API definitions
sdla_fr.h SDLA frame relay firmware API definitions
sdla_ppp.h SDLA PPP firmware API definitions
include/linux:
wanpipe.h WANPIPE API definitions
sdladrv.h SDLA support module API definitions
sdlasfm.h SDLA firmware module definitions
router.h
REVISION HISTORY
4.1 November 28, 1997
o Protection of "enable_irq()" while "disable_irq()" has been enabled
from any other routine (for Frame Relay, PPP and X25).
o Added additional Stats for Fpipemon and Ppipemon
o Improved Load Sharing for multiple boards
4.0 November 06, 1997
o Implemented better protection of RACE conditions by critical flags for
FRAME RELAY, PPP and X25.
o DLCI List interrupt mode implemented for DLCI specific CIR.
o IPX support for FRAME RELAY, PPP and X25.
o IPX Server Support (MARS) for FRAME RELAY, PPP and X25.
o More driver specific stats included.
o MULTICAST for FRAME RELAY and PPP.
3.1.0 January 30, 1997
o Implemented IOCTL for executing adapter commands.
......
......@@ -7,5 +7,8 @@ please mail me.
- this file
ppc_htab.txt
- info about the Linux/PPC /proc/ppc_htab entry
smp.txt
- use and state info about Linux/PPC on MP machines
sound.txt
- info on sound support under Linux/PPC
Information about Linux/PPC SMP mode
=====================================================================
This document and the related code was written by me (Cort Dougan), please
email me (cort@cs.nmt.edu) if you have questions, comments or corrections.
SMP support for Linux/PPC is still in its early stages and likely to
be buggy for a while. If you want to help by writing code or testing
different hardware please email me!
1. State of Supported Hardware
UMAX s900
The second processor on this machine boots up just fine and
enters its idle loop. Hopefully a completely working SMP kernel
on this machine will be done shortly.
BeBox
BeBox support hasn't been added to the 2.1.X kernels from 2.0.X
but work is being done and SMP support for BeBox is in the works.
On Fri, 2 Jan 1998, Doug Ledford wrote:
>
> I'm working on making the aic7xxx driver more SMP friendly (as well as
> importing the latest FreeBSD sequencer code to have 7895 support) and wanted
> to get some info from you. The goal here is to make the various routines
> SMP safe as well as UP safe during interrupts and other manipulating
> routines. So far, I've added a spin_lock variable to things like my queue
> structs. Now, from what I recall, there are some spin lock functions I can
> use to lock these spin locks frmo other use as oppossed to a (nasty)
> save_flags(); cli(); stuff; restore_flags(); construct. Where do I find
> these routines and go about making use of them? Do they only lock on a
> per-processor basis or can they also lock say an interrupt routine from
> mucking with a queue if the queue routine was manipulating it when the
> interrupt occured, or should I still use a cli(); based construct on that
> one?
See <asm/spinlock.h>. The basic version is:
spinlock_t xxx_lock = SPIN_LOCK_UNLOCKED;
unsigned long flags;
spin_lock_irqsave(&xxx_lock, flags);
... critical section here ..
spin_unlock_irqrestore(&xxx_lock, flags);
and the above is always safe. It will disable interrupt _locally_, but the
spinlock itself will guarantee the global lock, so it will guarantee that
there is only one thread-of-control within the region(s) protected by that
lock.
Note that it works well even under UP - the above sequence under UP
essentially is just the same as doing a
unsigned long flags;
save_flags(flags); cli();
... critical section ...
restore_flags(flags);
so the code does _not_ need to worry about UP vs SMP issues: the spinlocks
work correctly under both (and spinlocks are actually more efficient on
architectures that allow doing the "save_flags + cli" in one go because I
don't export that interface normally).
NOTE NOTE NOTE! The reason the spinlock is so much faster than a global
interrupt lock under SMP is exactly because it disables interrupts only on
the local CPU. The spin-lock is safe only when you _also_ use the lock
itself to do locking across CPU's, which implies that EVERYTHING that
touches a shared variable has to agree about the spinlock they want to
use.
The above is usually pretty simple (you usually need and want only one
spinlock for most things - using more than one spinlock can make things a
lot more complex and even slower and is usually worth it only for
sequences that you _know_ need to be split up: avoid it at all cost if you
aren't sure). HOWEVER, it _does_ mean that if you have some code that does
cli();
.. critical section ..
sti();
and another sequence that does
spin_lock_irqsave(flags);
.. critical section ..
spin_unlock_irqrestore(flags);
then they are NOT mutually exclusive, and the critical regions can happen
at the same time on two different CPU's. That's fine per se, but the
critical regions had better be critical for different things (ie they
can't stomp on each other).
The above is a problem mainly if you end up mixing code - for example the
routines in ll_rw_block() tend to use cli/sti to protect the atomicity of
their actions, and if a driver uses spinlocks instead then you should
think about issues like the above..
This is really the only really hard part about spinlocks: once you start
using spinlocks they tend to expand to areas you might not have noticed
before, because you have to make sure the spinlocks correctly protect the
shared data structures _everywhere_ they are used. The spinlocks are most
easily added to places that are completely independent of other code (ie
internal driver data structures that nobody else ever touches, for
example).
----
Lesson 2: reader-writer spinlocks.
If your data accesses have a very natural pattern where you usually tend
to mostly read from the shared variables, the reader-writer locks
(rw_lock) versions of the spinlocks are often nicer. They allow multiple
readers to be in the same critical region at once, but if somebody wants
to change the variables it has to get an exclusive write lock. The
routines look the same as above:
rwlock_t xxx_lock = RW_LOCK_UNLOCKED;
unsigned long flags;
read_lock_irqsave(&xxx_lock, flags);
.. critical section that only reads the info ...
read_unlock_irqrestore(&xxx_lock, flags);
write_lock_irqsave(&xxx_lock, flags);
.. read and write exclusive access to the info ...
write_unlock_irqrestore(&xxx_lock, flags);
The above kind of lock is useful for complex data structures like linked
lists etc, especially when you know that most of the work is to just
traverse the list searching for entries without changing the list itself,
for example. Then you can use the read lock for that kind of list
traversal, which allows many concurrent readers. Anything that _changes_
the list will have to get the write lock.
Note: you cannot "upgrade" a read-lock to a write-lock, so if you at _any_
time need to do any changes (even if you don't do it every time), you have
to get the write-lock at the very beginning. I could fairly easily add a
primitive to create a "upgradeable" read-lock, but it hasn't been an issue
yet. Tell me if you'd want one.
----
Lesson 3: spinlocks revisited.
The single spin-lock primitives above are by no means the only ones. They
are the most safe ones, and the ones that work under all circumstances,
but partly _because_ they are safe they are also fairly slow. They are
much faster than a generic global cli/sti pair, but slower than they'd
need to be, because they do have to disable interrupts (which is just a
single instruction on a x86, but it's an expensive one - and on other
architectures it can be worse).
If you have a case where you have to protect a data structure across
several CPU's and you want to use spinlocks you can potentially use
cheaper versions of the spinlocks. IFF you know that the spinlocks are
never used in interrupt handlers, you can use the non-irq versions:
spin_lock(&lock);
...
spin_unlock(&lock);
(and the equivalent read-write versions too, of course). The spinlock will
guarantee the same kind of exclusive access, and it will be much faster.
This is useful if you know that the data in question is only ever
manipulated from a "process context", ie no interrupts involved.
The reasons you mustn't use these versions if you have interrupts that
play with the spinlock is that you can get deadlocks:
spin_lock(&lock);
...
<- interrupt comes in:
spin_lock(&lock);
where an interrupt tries to lock an already locked variable. This is ok if
the other interrupt happens on another CPU, but it is _not_ ok if the
interrupt happens on the same CPU that already holds the lock, because the
lock will obviously never be released (because the interrupt is waiting
for the lock, and the lock-holder is interrupted by the interrupt and will
not continue until the interrupt has been processed).
(This is also the reason why the irq-versions of the spinlocks only need
to disable the _local_ interrupts - it's ok to use spinlocks in interrupts
on other CPU's, because an interrupt on another CPU doesn't interrupt the
CPU that holds the lock, so the lock-holder can continue and eventually
releases the lock).
Note that you can be clever with read-write locks and interrupts. For
example, if you know that the interrupt only ever gets a read-lock, then
you can use a non-irq version of read locks everywhere - because they
don't block on each other (and thus there is no dead-lock wrt interrupts.
But when you do the write-lock, you have to use the irq-safe version.
For an example of being clever with rw-locks, see the "waitqueue_lock"
handling in kernel/sched.c - nothing ever _changes_ a wait-queue from
within an interrupt, they only read the queue in order to know whom to
wake up. So read-locks are safe (which is good: they are very common
indeed), while write-locks need to protect themselves against interrupts.
Linus
......@@ -442,6 +442,12 @@ P: Jens Maurer
M: jmaurer@cck.uni-kl.de
S: Maintained
PCI SUBSYSTEM
P: Martin Mares
M: mj@atrey.karlin.mff.cuni.cz
L: linux-kernel@vger.rutgers.edu
S: Maintained
PCNET32 NETWORK DRIVER
P: Thomas Bogendoerfer
M: tsbogend@alpha.franken.de
......@@ -537,7 +543,7 @@ S: Maintained
SVGA HANDLING:
P: Martin Mares
M: mj@k332.feld.cvut.cz
M: mj@atrey.karlin.mff.cuni.cz
L: linux-video@atrey.karlin.mff.cuni.cz
S: Maintained
......
......@@ -44,3 +44,6 @@ archclean:
archdep:
@$(MAKEBOOT) dep
bootpfile:
@$(MAKEBOOT) bootpfile
......@@ -26,6 +26,7 @@ endif
$(CC) -D__ASSEMBLY__ -traditional -c -o $*.o $<
OBJECTS = head.o main.o
BPOBJECTS = head.o bootp.o
TARGETS = vmlinux.gz tools/objstrip # also needed by aboot & milo
VMLINUX = $(TOPDIR)/vmlinux
OBJSTRIP = tools/objstrip
......@@ -44,6 +45,9 @@ bootimage: tools/mkbb tools/lxboot tools/bootlx vmlinux.nh
( cat tools/lxboot tools/bootlx vmlinux.nh ) > bootimage
tools/mkbb bootimage tools/lxboot
bootpfile: tools/bootph vmlinux.nh
( cat tools/bootph vmlinux.nh ) > bootpfile
srmboot: bootdevice bootimage
dd if=bootimage of=$(BOOTDEV) bs=512 seek=1 skip=1
tools/mkbb $(BOOTDEV) tools/lxboot
......@@ -59,6 +63,8 @@ vmlinux.gz: vmlinux
#
main.o: ksize.h
bootp.o: ksize.h
ksize.h: $(OBJSTRIP) vmlinux.nh
echo "#define KERNEL_SIZE `$(OBJSTRIP) -p vmlinux.nh /dev/null`" > $@
......@@ -82,6 +88,9 @@ tools/lxboot: $(OBJSTRIP) bootloader
tools/bootlx: bootloader $(OBJSTRIP)
$(OBJSTRIP) -vb bootloader tools/bootlx
tools/bootph: bootpheader $(OBJSTRIP)
$(OBJSTRIP) -vb bootpheader tools/bootph
$(OBJSTRIP): $(OBJSTRIP).c
$(HOSTCC) $(OBJSTRIP).c -o $(OBJSTRIP)
......@@ -95,8 +104,15 @@ bootloader: $(OBJECTS)
-o bootloader && strip bootloader || \
(rm -f bootloader && exit 1)
bootpheader: $(BPOBJECTS)
$(LD) $(LINKFLAGS) \
$(BPOBJECTS) \
$(LIBS) \
-o bootpheader && strip bootpheader || \
(rm -f bootpheader && exit 1)
clean:
rm -f $(TARGETS) bootloader bootimage vmlinux.nh \
tools/mkbb tools/bootlx tools/lxboot
tools/mkbb tools/bootlx tools/lxboot ksize.h
dep:
/*
* arch/alpha/boot/bootp.c
*
* Copyright (C) 1997 Jay Estabrook
*
* This file is used for creating a bootp file for the Linux/AXP kernel
*
* based significantly on the arch/alpha/boot/main.c of Linus Torvalds
*/
#include <linux/kernel.h>
#include <linux/string.h>
#include <linux/version.h>
#include <linux/mm.h>
#include <asm/system.h>
#include <asm/console.h>
#include <asm/hwrpb.h>
#include <asm/pgtable.h>
#include <stdarg.h>
#include "ksize.h"
extern int vsprintf(char *, const char *, va_list);
extern unsigned long switch_to_osf_pal(unsigned long nr,
struct pcb_struct * pcb_va, struct pcb_struct * pcb_pa,
unsigned long vptb, unsigned long *kstk);
int printk(const char * fmt, ...)
{
va_list args;
int i, j, written, remaining, num_nl;
static char buf[1024];
char * str;
va_start(args, fmt);
i = vsprintf(buf, fmt, args);
va_end(args);
/* expand \n into \r\n: */
num_nl = 0;
for (j = 0; j < i; ++j) {
if (buf[j] == '\n')
++num_nl;
}
remaining = i + num_nl;
for (j = i - 1; j >= 0; --j) {
buf[j + num_nl] = buf[j];
if (buf[j] == '\n') {
--num_nl;
buf[j + num_nl] = '\r';
}
}
str = buf;
do {
written = puts(str, remaining);
remaining -= written;
str += written;
} while (remaining > 0);
return i;
}
#define hwrpb (*INIT_HWRPB)
/*
* Find a physical address of a virtual object..
*
* This is easy using the virtual page table address.
*/
struct pcb_struct * find_pa(unsigned long *vptb, struct pcb_struct * pcb)
{
unsigned long address = (unsigned long) pcb;
unsigned long result;
result = vptb[address >> 13];
result >>= 32;
result <<= 13;
result |= address & 0x1fff;
return (struct pcb_struct *) result;
}
/*
* This function moves into OSF/1 pal-code, and has a temporary
* PCB for that. The kernel proper should replace this PCB with
* the real one as soon as possible.
*
* The page table muckery in here depends on the fact that the boot
* code has the L1 page table identity-map itself in the second PTE
* in the L1 page table. Thus the L1-page is virtually addressable
* itself (through three levels) at virtual address 0x200802000.
*
* As we don't want it there anyway, we also move the L1 self-map
* up as high as we can, so that the last entry in the L1 page table
* maps the page tables.
*
* As a result, the OSF/1 pal-code will instead use a virtual page table
* map located at 0xffffffe00000000.
*/
#define pcb_va ((struct pcb_struct *) 0x20000000)
#define old_vptb (0x0000000200000000UL)
#define new_vptb (0xfffffffe00000000UL)
void pal_init(void)
{
unsigned long i, rev, sum;
unsigned long *L1, *l;
struct percpu_struct * percpu;
struct pcb_struct * pcb_pa;
/* Find the level 1 page table and duplicate it in high memory */
L1 = (unsigned long *) 0x200802000UL; /* (1<<33 | 1<<23 | 1<<13) */
L1[1023] = L1[1];
percpu = (struct percpu_struct *)
(hwrpb.processor_offset + (unsigned long) &hwrpb),
pcb_va->ksp = 0;
pcb_va->usp = 0;
pcb_va->ptbr = L1[1] >> 32;
pcb_va->asn = 0;
pcb_va->pcc = 0;
pcb_va->unique = 0;
pcb_va->flags = 1;
pcb_pa = find_pa((unsigned long *) old_vptb, pcb_va);
printk("Switching to OSF PAL-code .. ");
/*
* a0 = 2 (OSF)
* a1 = return address, but we give the asm the vaddr of the PCB
* a2 = physical addr of PCB
* a3 = new virtual page table pointer
* a4 = KSP (but we give it 0, asm sets it)
*/
i = switch_to_osf_pal(
2,
pcb_va,
pcb_pa,
new_vptb,
0);
if (i) {
printk("failed, code %ld\n", i);
halt();
}
rev = percpu->pal_revision = percpu->palcode_avail[2];
hwrpb.vptb = new_vptb;
/* update checksum: */
sum = 0;
for (l = (unsigned long *) &hwrpb;
l < (unsigned long *) &hwrpb.chksum;
++l)
sum += *l;
hwrpb.chksum = sum;
printk("Ok (rev %lx)\n", rev);
/* remove the old virtual page-table mapping */
L1[1] = 0;
flush_tlb_all();
}
static inline long load(unsigned long dst,
unsigned long src,
unsigned long count)
{
extern void * memcpy(void *, const void *, size_t);
memcpy((void *)dst, (void *)src, count);
return count;
}
/*
* Start the kernel.
*/
static void runkernel(void)
{
__asm__ __volatile__(
"bis %1,%1,$30\n\t"
"bis %0,%0,$27\n\t"
"jmp ($27)"
: /* no outputs: it doesn't even return */
: "r" (START_ADDR),
"r" (PAGE_SIZE + INIT_STACK));
}
extern char _end;
#define KERNEL_ORIGIN \
((((unsigned long)&_end) + 511) & ~511)
void start_kernel(void)
{
long i;
int nbytes;
char envval[256];
printk("Linux/AXP bootp loader for Linux " UTS_RELEASE "\n");
if (hwrpb.pagesize != 8192) {
printk("Expected 8kB pages, got %ldkB\n", hwrpb.pagesize >> 10);
return;
}
pal_init();
nbytes = dispatch(CCB_GET_ENV, ENV_BOOTED_OSFLAGS,
envval, sizeof(envval));
if (nbytes < 0) {
nbytes = 0;
}
envval[nbytes] = '\0';
strcpy((char*)ZERO_PAGE, envval);
printk("Loading the kernel ...\n");
/* NOTE: *no* callbacks or printouts from here on out!!! */
i = load(START_ADDR, KERNEL_ORIGIN, KERNEL_SIZE);
runkernel();
for (i = 0 ; i < 0x100000000 ; i++)
/* nothing */;
halt();
}
......@@ -6,7 +6,10 @@ mainmenu_name "Kernel configuration of Linux for Alpha machines"
# clear all implied options (don't want default values for those):
unset CONFIG_CROSSCOMPILE CONFIG_NATIVE
unset CONFIG_PCI CONFIG_ALPHA_LCA CONFIG_ALPHA_APECS
unset CONFIG_ALPHA_EV4 CONFIG_ALPHA_EV5
unset CONFIG_PCI CONFIG_ALPHA_EISA
unset CONFIG_ALPHA_LCA CONFIG_ALPHA_APECS CONFIG_ALPHA_CIA
unset CONFIG_ALPHA_T2 CONFIG_ALPHA_PYXIS
unset CONFIG_ALPHA_NEED_ROUNDING_EMULATION
mainmenu_option next_comment
......@@ -46,19 +49,29 @@ choice 'Alpha system type' \
Jensen CONFIG_ALPHA_JENSEN \
Noname CONFIG_ALPHA_NONAME \
Mikasa CONFIG_ALPHA_MIKASA \
Noritake CONFIG_ALPHA_NORITAKE \
Alcor CONFIG_ALPHA_ALCOR \
Miata CONFIG_ALPHA_MIATA \
Sable CONFIG_ALPHA_SABLE \
AlphaBook1 CONFIG_ALPHA_BOOK1 \
Platform2000 CONFIG_ALPHA_P2K" Cabriolet
if [ "$CONFIG_ALPHA_BOOK1" = "y" ]
then
define_bool CONFIG_ALPHA_NONAME y
fi
if [ "$CONFIG_ALPHA_NONAME" = "y" -o "$CONFIG_ALPHA_EB66" = "y" \
-o "$CONFIG_ALPHA_EB66P" = "y" -o "$CONFIG_ALPHA_P2K" = "y" ]
then
define_bool CONFIG_PCI y
define_bool CONFIG_ALPHA_EV4 y
define_bool CONFIG_ALPHA_LCA y
fi
if [ "$CONFIG_ALPHA_CABRIOLET" = "y" -o "$CONFIG_ALPHA_AVANTI" = "y" \
-o "$CONFIG_ALPHA_EB64P" = "y" -o "$CONFIG_ALPHA_MIKASA" = "y" \
-o "$CONFIG_ALPHA_XL" = "y" ]
-o "$CONFIG_ALPHA_EB64P" = "y" -o "$CONFIG_ALPHA_XL" = "y" ]
then
define_bool CONFIG_PCI y
define_bool CONFIG_ALPHA_EV4 y
define_bool CONFIG_ALPHA_APECS y
fi
if [ "$CONFIG_ALPHA_EB164" = "y" -o "$CONFIG_ALPHA_PC164" = "y" \
......@@ -67,17 +80,57 @@ then
define_bool CONFIG_PCI y
define_bool CONFIG_ALPHA_EV5 y
define_bool CONFIG_ALPHA_CIA y
else
fi
if [ "$CONFIG_ALPHA_MIKASA" = "y" -o "$CONFIG_ALPHA_NORITAKE" = "y" ]
then
choice 'CPU daughtercard' \
"Pinnacle CONFIG_ALPHA_PINNACLE \
Primo CONFIG_ALPHA_PRIMO" Primo
if [ "$CONFIG_ALPHA_PRIMO" = "y" ]
then
define_bool CONFIG_ALPHA_EV5 y
define_bool CONFIG_ALPHA_CIA y
else
define_bool CONFIG_ALPHA_EV4 y
define_bool CONFIG_ALPHA_APECS y
fi
define_bool CONFIG_PCI y
fi
if [ "$CONFIG_ALPHA_SABLE" = "y" ]
then
define_bool CONFIG_PCI y
define_bool CONFIG_ALPHA_EV4 y
define_bool CONFIG_ALPHA_T2 y
fi
if [ "$CONFIG_ALPHA_MIATA" = "y" ]
then
define_bool CONFIG_PCI y
define_bool CONFIG_ALPHA_EV5 y
define_bool CONFIG_ALPHA_PYXIS y
fi
if [ "$CONFIG_ALPHA_JENSEN" = "y" ]
then
define_bool CONFIG_ALPHA_EV4 y
fi
if [ "$CONFIG_ALPHA_EV4" = "y" ]
then
# EV45 and older do not support all rounding modes in hw:
define_bool CONFIG_ALPHA_NEED_ROUNDING_EMULATION 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_MIKASA" = "y" -o "$CONFIG_ALPHA_ALCOR" = "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" ]
then
bool 'Using SRM as bootloader' CONFIG_ALPHA_SRM
fi
if [ "$CONFIG_ALPHA_ALCOR" = "y" -o "$CONFIG_ALPHA_MIKASA" = "y" \
-o "$CONFIG_ALPHA_SABLE" = "y" -o "$CONFIG_ALPHA_NORITAKE" = "y" ]
then
define_bool CONFIG_ALPHA_EISA y
fi
if [ "$CONFIG_ALPHA_XL" = "y" ]
then
define_bool CONFIG_ALPHA_AVANTI y
......
......@@ -16,9 +16,26 @@ all: kernel.o head.o
O_TARGET := kernel.o
O_OBJS := entry.o traps.o process.o osf_sys.o irq.o signal.o setup.o \
bios32.o ptrace.o time.o apecs.o lca.o cia.o
bios32.o ptrace.o time.o
OX_OBJS := alpha_ksyms.o
ifdef CONFIG_ALPHA_APECS
O_OBJS += apecs.o
endif
ifdef CONFIG_ALPHA_CIA
O_OBJS += cia.o
endif
ifdef CONFIG_ALPHA_LCA
O_OBJS += lca.o
endif
ifdef CONFIG_ALPHA_PYXIS
O_OBJS += pyxis.o
endif
ifdef CONFIG_ALPHA_T2
O_OBJS += t2.o
endif
all: kernel.o head.o
head.o: head.s
......
......@@ -21,12 +21,11 @@
extern struct hwrpb_struct *hwrpb;
extern asmlinkage void wrmces(unsigned long mces);
extern int alpha_sys_type;
/*
* BIOS32-style PCI interface:
*/
#ifdef CONFIG_ALPHA_APECS
#ifdef DEBUG
# define DBG(args) printk args
#else
......@@ -88,7 +87,8 @@ static int mk_conf_addr(unsigned char bus, unsigned char device_fn,
{
unsigned long addr;
DBG(("mk_conf_addr(bus=%d ,device_fn=0x%x, where=0x%x, pci_addr=0x%p, type1=0x%p)\n",
DBG(("mk_conf_addr(bus=%d ,device_fn=0x%x, where=0x%x,"
" pci_addr=0x%p, type1=0x%p)\n",
bus, device_fn, where, pci_addr, type1));
if (bus == 0) {
......@@ -97,7 +97,8 @@ static int mk_conf_addr(unsigned char bus, unsigned char device_fn,
/* type 0 configuration cycle: */
if (device > 20) {
DBG(("mk_conf_addr: device (%d) > 20, returning -1\n", device));
DBG(("mk_conf_addr: device (%d) > 20, returning -1\n",
device));
return -1;
}
......@@ -142,15 +143,15 @@ static unsigned int conf_read(unsigned long addr, unsigned char type1)
DBG(("conf_read(addr=0x%lx, type1=%d)\n", addr, type1));
/* reset status register to avoid losing errors: */
stat0 = *((volatile unsigned int *)APECS_IOC_DCSR);
*((volatile unsigned int *)APECS_IOC_DCSR) = stat0;
stat0 = *(vuip)APECS_IOC_DCSR;
*(vuip)APECS_IOC_DCSR = stat0;
mb();
DBG(("conf_read: APECS DCSR was 0x%x\n", stat0));
/* if Type1 access, must set HAE #2 */
if (type1) {
haxr2 = *((unsigned int *)APECS_IOC_HAXR2);
haxr2 = *(vuip)APECS_IOC_HAXR2;
mb();
*((unsigned int *)APECS_IOC_HAXR2) = haxr2 | 1;
*(vuip)APECS_IOC_HAXR2 = haxr2 | 1;
DBG(("conf_read: TYPE1 access\n"));
}
......@@ -159,8 +160,7 @@ static unsigned int conf_read(unsigned long addr, unsigned char type1)
apecs_mcheck_taken = 0;
mb();
/* access configuration space: */
value = *((volatile unsigned int *)addr);
mb();
value = *(vuip)addr;
mb();
if (apecs_mcheck_taken) {
apecs_mcheck_taken = 0;
......@@ -169,17 +169,18 @@ static unsigned int conf_read(unsigned long addr, unsigned char type1)
}
apecs_mcheck_expected = 0;
mb();
#if 1
/*
* david.rusling@reo.mts.dec.com. This code is needed for the
* EB64+ as it does not generate a machine check (why I don't
* know). When we build kernels for one particular platform
* then we can make this conditional on the type.
*/
#if 1
draina();
/* now look for any errors */
stat0 = *((unsigned int *)APECS_IOC_DCSR);
stat0 = *(vuip)APECS_IOC_DCSR;
DBG(("conf_read: APECS DCSR after read 0x%x\n", stat0));
if (stat0 & 0xffe0U) { /* is any error bit set? */
/* if not NDEV, print status */
......@@ -188,7 +189,7 @@ static unsigned int conf_read(unsigned long addr, unsigned char type1)
}
/* reset error status: */
*((volatile unsigned long *)APECS_IOC_DCSR) = stat0;
*(vulp)APECS_IOC_DCSR = stat0;
mb();
wrmces(0x7); /* reset machine check */
value = 0xffffffff;
......@@ -197,7 +198,7 @@ static unsigned int conf_read(unsigned long addr, unsigned char type1)
/* if Type1 access, must reset HAE #2 so normal IO space ops work */
if (type1) {
*((unsigned int *)APECS_IOC_HAXR2) = haxr2 & ~1;
*(vuip)APECS_IOC_HAXR2 = haxr2 & ~1;
mb();
}
restore_flags(flags);
......@@ -224,37 +225,37 @@ static void conf_write(unsigned long addr, unsigned int value, unsigned char typ
cli();
/* reset status register to avoid losing errors: */
stat0 = *((volatile unsigned int *)APECS_IOC_DCSR);
*((volatile unsigned int *)APECS_IOC_DCSR) = stat0;
stat0 = *(vuip)APECS_IOC_DCSR;
*(vuip)APECS_IOC_DCSR = stat0;
mb();
/* if Type1 access, must set HAE #2 */
if (type1) {
haxr2 = *((unsigned int *)APECS_IOC_HAXR2);
haxr2 = *(vuip)APECS_IOC_HAXR2;
mb();
*((unsigned int *)APECS_IOC_HAXR2) = haxr2 | 1;
*(vuip)APECS_IOC_HAXR2 = haxr2 | 1;
}
draina();
apecs_mcheck_expected = 1;
mb();
/* access configuration space: */
*((volatile unsigned int *)addr) = value;
mb();
*(vuip)addr = value;
mb();
apecs_mcheck_expected = 0;
mb();
#if 1
/*
* david.rusling@reo.mts.dec.com. This code is needed for the
* EB64+ as it does not generate a machine check (why I don't
* know). When we build kernels for one particular platform
* then we can make this conditional on the type.
*/
#if 1
draina();
/* now look for any errors */
stat0 = *((unsigned int *)APECS_IOC_DCSR);
stat0 = *(vuip)APECS_IOC_DCSR;
if (stat0 & 0xffe0U) { /* is any error bit set? */
/* if not NDEV, print status */
if (!(stat0 & 0x0800)) {
......@@ -262,7 +263,7 @@ static void conf_write(unsigned long addr, unsigned int value, unsigned char typ
}
/* reset error status: */
*((volatile unsigned long *)APECS_IOC_DCSR) = stat0;
*(vulp)APECS_IOC_DCSR = stat0;
mb();
wrmces(0x7); /* reset machine check */
}
......@@ -270,7 +271,7 @@ static void conf_write(unsigned long addr, unsigned int value, unsigned char typ
/* if Type1 access, must reset HAE #2 so normal IO space ops work */
if (type1) {
*((unsigned int *)APECS_IOC_HAXR2) = haxr2 & ~1;
*(vuip)APECS_IOC_HAXR2 = haxr2 & ~1;
mb();
}
restore_flags(flags);
......@@ -433,7 +434,7 @@ unsigned long apecs_init(unsigned long mem_start, unsigned long mem_end)
#ifdef CONFIG_ALPHA_CABRIOLET
/*
* JAE: HACK!!! for now, hardwire if configured...
* davidm: Older miniloader versions don't set the clockfrequency
* davidm: Older miniloader versions don't set the clock frequency
* right, so hardcode it for now.
*/
if (hwrpb->sys_type == ST_DEC_EB64P) {
......@@ -448,7 +449,9 @@ unsigned long apecs_init(unsigned long mem_start, unsigned long mem_end)
unsigned long *l, sum;
sum = 0;
for (l = (unsigned long *) hwrpb; l < (unsigned long *) &hwrpb->chksum; ++l)
for (l = (unsigned long *) hwrpb;
l < (unsigned long *) &hwrpb->chksum;
++l)
sum += *l;
hwrpb->chksum = sum;
}
......@@ -462,10 +465,10 @@ unsigned long apecs_init(unsigned long mem_start, unsigned long mem_end)
*/
{
#if 0
unsigned int haxr2 = *((unsigned int *)APECS_IOC_HAXR2); mb();
unsigned int haxr2 = *(vuip)APECS_IOC_HAXR2; mb();
if (haxr2) printk("apecs_init: HAXR2 was 0x%x\n", haxr2);
#endif
*((unsigned int *)APECS_IOC_HAXR2) = 0; mb();
*(vuip)APECS_IOC_HAXR2 = 0; mb();
}
......@@ -474,15 +477,15 @@ unsigned long apecs_init(unsigned long mem_start, unsigned long mem_end)
int apecs_pci_clr_err(void)
{
apecs_jd = *((unsigned long *)APECS_IOC_DCSR);
apecs_jd = *(vulp)APECS_IOC_DCSR;
if (apecs_jd & 0xffe0L) {
apecs_jd1 = *((unsigned long *)APECS_IOC_SEAR);
*((unsigned long *)APECS_IOC_DCSR) = apecs_jd | 0xffe1L;
apecs_jd = *((unsigned long *)APECS_IOC_DCSR);
apecs_jd1 = *(vulp)APECS_IOC_SEAR;
*(vulp)APECS_IOC_DCSR = apecs_jd | 0xffe1L;
apecs_jd = *(vulp)APECS_IOC_DCSR;
mb();
}
*((unsigned long *)APECS_IOC_TBIA) = APECS_IOC_TBIA;
apecs_jd2 = *((unsigned long *)APECS_IOC_TBIA);
*(vulp)APECS_IOC_TBIA = APECS_IOC_TBIA;
apecs_jd2 = *(vulp)APECS_IOC_TBIA;
mb();
return 0;
}
......@@ -547,7 +550,8 @@ void apecs_machine_check(unsigned long vector, unsigned long la_ptr,
wrmces(0x1f); /* disable correctable from now on */
mb();
draina();
printk("apecs_machine_check: HW correctable (0x%lx)\n", vector);
printk("apecs_machine_check: HW correctable (0x%lx)\n",
vector);
}
else {
printk(KERN_CRIT "APECS machine check:\n");
......@@ -572,4 +576,3 @@ void apecs_machine_check(unsigned long vector, unsigned long la_ptr,
#endif
}
}
#endif /* CONFIG_ALPHA_APECS */
This diff is collapsed.
This diff is collapsed.
......@@ -80,6 +80,48 @@ wrmces:
ret ($26)
.end wrmces
.align 3
.globl whami
.ent whami
whami:
call_pal PAL_whami
ret ($26)
.end whami
.align 3
.globl wripir
.ent wripir
wripir:
call_pal PAL_wripir
ret ($26)
.end wripir
#
# The following two functions are needed for supporting SRM PALcode
# on the PC164 (at least), since that PALcode manages the interrupt
# masking, and we cannot duplicate the effort without causing problems
#
.align 3
.globl cserve_ena
.ent cserve_ena
cserve_ena:
bis $16,$16,$17
lda $16,52($31)
call_pal PAL_cserve
ret ($26)
.end cserve_ena
.align 3
.globl cserve_dis
.ent cserve_dis
cserve_dis:
bis $16,$16,$17
lda $16,53($31)
call_pal PAL_cserve
ret ($26)
.end cserve_dis
#
# The following two functions don't need trapb/excb instructions
# around the mf_fpcr/mt_fpcr instructions because (a) the kernel
......
This diff is collapsed.
This diff is collapsed.
......@@ -846,10 +846,6 @@ asmlinkage unsigned long osf_getsysinfo(unsigned long op, void *buffer,
return -EOPNOTSUPP;
}
/* Dummy functions for now */
#define wrfpcr(x) do { } while (0)
#define rdfpcr() 0
asmlinkage unsigned long osf_setsysinfo(unsigned long op, void *buffer,
unsigned long nbytes,
int *start, void *arg)
......
......@@ -38,6 +38,7 @@
#include <asm/system.h>
#include <asm/io.h>
#include <asm/pgtable.h>
#include <asm/hwrpb.h>
/*
* Initial task structure. Make this a per-architecture thing,
......@@ -86,7 +87,7 @@ asmlinkage int sys_idle(void)
return ret;
}
void machine_restart(char * __unused)
static void finish_shutdown(void)
{
#ifdef CONFIG_RTC /* reset rtc to defaults */
unsigned char control;
......@@ -105,7 +106,6 @@ void machine_restart(char * __unused)
CMOS_READ(RTC_INTR_FLAGS);
restore_flags(flags);
#endif
#if defined(CONFIG_ALPHA_SRM) && defined(CONFIG_ALPHA_ALCOR)
/* who said DEC engineer's have no sense of humor? ;-)) */
*(int *) GRU_RESET = 0x0000dead;
......@@ -114,12 +114,50 @@ void machine_restart(char * __unused)
halt();
}
void machine_restart(char * __unused)
{
#if defined(CONFIG_ALPHA_SRM)
extern struct hwrpb_struct *hwrpb;
struct percpu_struct *cpup;
unsigned long flags;
cpup = (struct percpu_struct *)
((unsigned long)hwrpb + hwrpb->processor_offset);
flags = cpup->flags;
flags &= ~0x0000000000ff0001UL; /* clear reason to "default" */
flags |= 0x0000000000020000UL; /* this is "cold bootstrap" */
/* flags |= 0x0000000000030000UL; *//* this is "warm bootstrap" */
cpup->flags = flags;
mb();
#endif /* SRM */
finish_shutdown();
}
void machine_halt(void)
{
#if defined(CONFIG_ALPHA_SRM)
extern struct hwrpb_struct *hwrpb;
struct percpu_struct *cpup;
unsigned long flags;
cpup = (struct percpu_struct *)
((unsigned long)hwrpb + hwrpb->processor_offset);
flags = cpup->flags;
flags &= ~0x0000000000ff0001UL; /* clear reason to "default" */
flags |= 0x0000000000040000UL; /* this is "remain halted" */
cpup->flags = flags;
mb();
finish_shutdown();
#endif /* SRM */
}
void machine_power_off(void)
{
/* None of the machines we support, at least, has switchable
power supplies. */
machine_halt();
}
void show_regs(struct pt_regs * regs)
......
This diff is collapsed.
......@@ -62,6 +62,18 @@ static char command_line[COMMAND_LINE_SIZE] = { 0, };
* code think we're on a VGA color display.
*/
struct screen_info screen_info = {
#if defined(CONFIG_ALPHA_BOOK1)
/* the AlphaBook1 has LCD video fixed at 800x600, 37 rows and 100 cols */
0, 37, /* orig-x, orig-y */
{ 0, 0 }, /* unused */
0, /* orig-video-page */
0, /* orig-video-mode */
100, /* orig-video-cols */
0,0,0, /* ega_ax, ega_bx, ega_cx */
37, /* orig-video-lines */
1, /* orig-video-isVGA */
16 /* orig-video-points */
#else
0, 25, /* orig-x, orig-y */
{ 0, 0 }, /* unused */
0, /* orig-video-page */
......@@ -71,6 +83,7 @@ struct screen_info screen_info = {
25, /* orig-video-lines */
1, /* orig-video-isVGA */
16 /* orig-video-points */
#endif
};
/*
......@@ -166,6 +179,10 @@ void setup_arch(char **cmdline_p,
*memory_start_p = apecs_init(*memory_start_p, *memory_end_p);
#elif defined(CONFIG_ALPHA_CIA)
*memory_start_p = cia_init(*memory_start_p, *memory_end_p);
#elif defined(CONFIG_ALPHA_PYXIS)
*memory_start_p = pyxis_init(*memory_start_p, *memory_end_p);
#elif defined(CONFIG_ALPHA_T2)
*memory_start_p = t2_init(*memory_start_p, *memory_end_p);
#endif
}
......@@ -175,7 +192,8 @@ void setup_arch(char **cmdline_p,
int get_cpuinfo(char *buffer)
{
const char *cpu_name[] = {
"EV3", "EV4", "Unknown 1", "LCA4", "EV5", "EV45"
"EV3", "EV4", "Unknown 1", "LCA4", "EV5", "EV45", "EV56",
"EV6", "PCA56"
};
# define SYSTYPE_NAME_BIAS 20
const char *systype_name[] = {
......@@ -185,8 +203,9 @@ int get_cpuinfo(char *buffer)
"ADU", "Cobra", "Ruby", "Flamingo", "5", "Jensen",
"Pelican", "8", "Sable", "AXPvme", "Noname",
"Turbolaser", "Avanti", "Mustang", "Alcor", "16",
"Mikasa", "18", "EB66", "EB64+", "21", "22", "23",
"24", "25", "EB164"
"Mikasa", "18", "EB66", "EB64+", "AlphaBook1",
"Rawhide", "Lego", "Lynx", "25", "EB164", "Noritake",
"Cortex", "29", "Miata", "31", "Takara", "Yukon"
};
struct percpu_struct *cpu;
unsigned int cpu_index;
......
This diff is collapsed.
......@@ -58,10 +58,14 @@ csum_ipv6_magic:
addq $3,$1,$3 # .. e1 :
addq $0,$3,$0 # e0 :
unop # :
extwl $0,2,$1 # e0 :
extwl $0,2,$1 # e0 : fold 18-bit value
zapnot $0,3,$0 # .. e1 :
addq $0,$1,$0 # e0 :
not $0,$0 # e1 :
unop # :
extwl $0,2,$1 # e0 : fold 17-bit value
zapnot $0,3,$0 # .. e1 :
addq $0,$1,$0 # e0 :
not $0,$0 # e1 : and compliment.
zapnot $0,3,$0 # e0 :
ret # .. e1 :
......
......@@ -84,7 +84,6 @@ CONFIG_PACKET=y
# CONFIG_NETLINK is not set
# CONFIG_FIREWALL is not set
# CONFIG_NET_ALIAS is not set
# CONFIG_FILTER is not set
CONFIG_UNIX=y
CONFIG_INET=y
# CONFIG_IP_MULTICAST is not set
......@@ -267,7 +266,6 @@ CONFIG_82C710_MOUSE=y
# CONFIG_RTC is not set
# CONFIG_VIDEO_DEV is not set
# CONFIG_VIDEO_BT848 is not set
# CONFIG_VIDEO_BWQCAM is not set
# CONFIG_VIDEO_PMS is not set
# CONFIG_NVRAM is not set
# CONFIG_JOYSTICK is not set
......
......@@ -55,7 +55,7 @@
extern unsigned long start_kernel, _etext;
extern void update_one_process( struct task_struct *p,
unsigned long ticks, unsigned long user,
unsigned long system);
unsigned long system, int cpu);
/*
* Some notes on processor bugs:
*
......@@ -1346,8 +1346,7 @@ void smp_local_timer_interrupt(struct pt_regs * regs)
irq_enter(cpu, 0);
if (p->pid) {
update_one_process(p, 1, user, system);
update_one_process(p, 1, user, system, cpu);
p->counter -= 1;
if (p->counter < 0) {
......@@ -1360,6 +1359,7 @@ void smp_local_timer_interrupt(struct pt_regs * regs)
kstat.cpu_user += user;
kstat.cpu_system += system;
kstat.per_cpu_system[cpu] += system;
} else {
#ifdef __SMP_PROF__
......@@ -1382,7 +1382,7 @@ void smp_local_timer_interrupt(struct pt_regs * regs)
* we might want to decouple profiling from the 'long path',
* and do the profiling totally in assembly.
*
* Currently this isnt too much of an issue (performancewise),
* Currently this isnt too much of an issue (performance wise),
* we can take more than 100K local irqs per second on a 100 MHz P5.
*/
}
......
......@@ -29,8 +29,8 @@ addr_limit = 12
__get_user_1:
movl %esp,%edx
andl $0xffffe000,%edx
cmpl %eax,addr_limit(%edx)
jnb bad_get_user
cmpl addr_limit(%edx),%eax
jae bad_get_user
1: movzbl (%eax),%edx
xorl %eax,%eax
ret
......@@ -42,8 +42,8 @@ __get_user_2:
movl %esp,%edx
jc bad_get_user
andl $0xffffe000,%edx
cmpl %eax,addr_limit(%edx)
jnb bad_get_user
cmpl addr_limit(%edx),%eax
jae bad_get_user
2: movzwl -1(%eax),%edx
xorl %eax,%eax
ret
......@@ -55,8 +55,8 @@ __get_user_4:
movl %esp,%edx
jc bad_get_user
andl $0xffffe000,%edx
cmpl %eax,addr_limit(%edx)
jnb bad_get_user
cmpl addr_limit(%edx),%eax
jae bad_get_user
3: movl -3(%eax),%edx
xorl %eax,%eax
ret
......
......@@ -28,8 +28,8 @@ addr_limit = 12
__put_user_1:
movl %esp,%ecx
andl $0xffffe000,%ecx
cmpl %eax,addr_limit(%ecx)
jnb bad_put_user
cmpl addr_limit(%ecx),%eax
jae bad_put_user
1: movb %dl,(%eax)
xorl %eax,%eax
ret
......@@ -41,8 +41,8 @@ __put_user_2:
movl %esp,%ecx
jc bad_put_user
andl $0xffffe000,%ecx
cmpl %eax,addr_limit(%ecx)
jnb bad_put_user
cmpl addr_limit(%ecx),%eax
jae bad_put_user
2: movw %dx,-1(%eax)
xorl %eax,%eax
ret
......@@ -54,8 +54,8 @@ __put_user_4:
movl %esp,%ecx
jc bad_put_user
andl $0xffffe000,%ecx
cmpl %eax,addr_limit(%ecx)
jnb bad_put_user
cmpl addr_limit(%ecx),%eax
jae bad_put_user
3: movl %edx,-3(%eax)
xorl %eax,%eax
ret
......
......@@ -72,7 +72,7 @@ pte_t __bad_page(void)
void show_mem(void)
{
int i,free = 0,total = 0,reserved = 0;
int shared = 0;
int shared = 0, cached = 0;
printk("Mem-info:\n");
show_free_areas();
......@@ -82,6 +82,8 @@ void show_mem(void)
total++;
if (PageReserved(mem_map+i))
reserved++;
if (PageSwapCache(mem_map+i))
cached++;
else if (!atomic_read(&mem_map[i].count))
free++;
else
......@@ -91,6 +93,7 @@ void show_mem(void)
printk("%d free pages\n",free);
printk("%d reserved pages\n",reserved);
printk("%d pages shared\n",shared);
printk("%d pages swap cached\n",cached);
show_buffers();
#ifdef CONFIG_NET
show_net_buffers();
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment