Commit fbda5aab authored by Linus Torvalds's avatar Linus Torvalds

Import 2.1.0

parent 734e34f1
...@@ -1320,7 +1320,7 @@ N: Linus Torvalds ...@@ -1320,7 +1320,7 @@ N: Linus Torvalds
E: Linus.Torvalds@Helsinki.FI E: Linus.Torvalds@Helsinki.FI
W: http://www.cs.helsinki.fi/~torvalds/ W: http://www.cs.helsinki.fi/~torvalds/
P: 1024/A86B35C5 96 54 50 29 EC 11 44 7A BE 67 3C 24 03 13 62 C8 P: 1024/A86B35C5 96 54 50 29 EC 11 44 7A BE 67 3C 24 03 13 62 C8
D: General kernel hacker D: Original kernel hacker
S: Kalevankatu 55 B 37 S: Kalevankatu 55 B 37
S: 00180 Helsinki S: 00180 Helsinki
S: Finland S: Finland
......
...@@ -183,14 +183,8 @@ values. To do the latter, you can stick the following in your .emacs file: ...@@ -183,14 +183,8 @@ values. To do the latter, you can stick the following in your .emacs file:
"C mode with adjusted defaults for use with the Linux kernel." "C mode with adjusted defaults for use with the Linux kernel."
(interactive) (interactive)
(c-mode) (c-mode)
(setq c-indent-level 8) (c-set-style "K&R")
(setq c-brace-imaginary-offset 0) (setq c-basic-offset 8))
(setq c-brace-offset -8)
(setq c-argdecl-indent 8)
(setq c-label-offset -8)
(setq c-continued-statement-offset 8)
(setq indent-tabs-mode nil)
(setq tab-width 8))
This will define the M-x linux-c-mode command. When hacking on a This will define the M-x linux-c-mode command. When hacking on a
module, if you put the string -*- linux-c -*- somewhere on the first module, if you put the string -*- linux-c -*- somewhere on the first
......
[ This is a mail-message in response to a query on IO mapping, thus the
strange format for a "document" ]
The aha1542 is a bus-master device, and your patch makes the driver give the
controller the physical address of the buffers, which is correct on x86
(because all bus master devices see the physical memory mappings directly).
However, on many setups, there are actually _three_ different ways of looking
at memory addresses, and in this case we actually want the third, the
so-called "bus address".
Essentially, the three ways of addressing memory are (this is "real memory",
ie normal RAM, see later about other details):
- CPU untranslated. This is the "physical" address, ie physical address
0 is what the CPU sees when it drives zeroes on the memory bus.
- CPU translated address. This is the "virtual" address, and is
completely internal to the CPU itself with the CPU doing the appropriate
translations into "CPU untranslated".
- bus address. This is the address of memory as seen by OTHER devices,
not the CPU. Now, in theory there could be many different bus
addresses, with each device seeing memory in some device-specific way, but
happily most hardware designers aren't actually actively trying to make
things any more complex than necessary, so you can assume that all
external hardware sees the memory the same way.
Now, on normal PC's the bus address is exactly the same as the physical
address, and things are very simple indeed. However, they are that simple
because the memory and the devices share the same address space, and that is
not generally necessarily true on other PCI/ISA setups.
Now, just as an example, on the PReP (PowerPC Reference Platform), the
CPU sees a memory map something like this (this is from memory):
0-2GB "real memory"
2GB-3GB "system IO" (ie inb/out type accesses on x86)
3GB-4GB "IO memory" (ie shared memory over the IO bus)
Now, that looks simple enough. However, when you look at the same thing from
the viewpoint of the devices, you have the reverse, and the physical memory
address 0 actually shows up as address 2GB for any IO master.
So when the CPU wants any bus master to write to physical memory 0, it
has to give the master address 0x80000000 as the memory address.
So, for example, depending on how the kernel is actually mapped on the
PPC, you can end up with a setup like this:
physical address: 0
virtual address: 0xC0000000
bus address: 0x80000000
where all the addresses actually point to the same thing, it's just seen
through different translations..
Similarly, on the alpha, the normal translation is
physical address: 0
virtual address: 0xfffffc0000000000
bus address: 0x40000000
(but there are also alpha's where the physical address and the bus address
are the same).
Anyway, the way to look up all these translations, you do
#include <asm/io.h>
phys_addr = virt_to_phys(virt_addr);
virt_addr = phys_to_virt(phys_addr);
bus_addr = virt_to_bus(virt_addr);
virt_addr = bus_to_virt(bus_addr);
Now, when do you need these?
You want the _virtual_ address when you are actually going to access that
pointer from the kernel. So you can have something like this:
/*
* this is the hardware "mailbox" we use to communicate with
* the controller. The controller sees this directly.
*/
struct mailbox {
__u32 status;
__u32 bufstart;
__u32 buflen;
..
} mbox;
unsigned char * retbuffer;
/* get the address from the controller */
retbuffer = bus_to_virt(mbox.bufstart);
switch (retbuffer[0]) {
case STATUS_OK:
...
on the other hand, you want the bus address when you have a buffer that
you want to give to the controller:
/* ask the controller to read the sense status into "sense_buffer" */
mbox.bufstart = virt_to_bus(&sense_buffer);
mbox.buflen = sizeof(sense_buffer);
mbox.status = 0;
notify_controller(&mbox);
And you generally _never_ want to use the physical address, because you can't
use that from the CPU (the CPU only uses translated virtual addresses), and
you can't use it from the bus master.
So why do we care about the physical address at all? We do need the physical
address in some cases, it's just not very often in normal code. The physical
address is needed if you use memory mappings, for example, because the
"remap_page_range()" mm function wants the physical address of the memory to
be remapped (the memory management layer doesn't know about devices outside
the CPU, so it shouldn't need to know about "bus addresses" etc).
NOTE NOTE NOTE! The above is only one part of the whole equation. The above
only talks about "real memory", ie CPU memory, ie RAM.
There is a completely different type of memory too, and that's the "shared
memory" on the PCI or ISA bus. That's generally not RAM (although in the case
of a video graphics card it can be normal DRAM that is just used for a frame
buffer), but can be things like a packet buffer in a network card etc.
This memory is called "PCI memory" or "shared memory" or "IO memory" or
whatever, and there is only one way to access it: the readb/writeb and
related functions. You should never take the address of such memory, because
there is really nothing you can do with such an address: it's not
conceptually in the same memory space as "real memory" at all, so you cannot
just dereference a pointer. (Sadly, on x86 it _is_ in the same memory space,
so on x86 it actually works to just deference a pointer, but it's not
portable).
For such memory, you can do things like
- reading:
/*
* read first 32 bits from ISA memory at 0xC0000, aka
* C000:0000 in DOS terms
*/
unsigned int signature = readl(0xC0000);
- remapping and writing:
/*
* remap framebuffer PCI memory area at 0xFC000000,
* size 1MB, so that we can access it: We can directly
* access only the 640k-1MB area, so anything else
* has to be remapped.
*/
char * baseptr = ioremap(0xFC000000, 1024*1024);
/* write a 'A' to the offset 10 of the area */
writeb('A',baseptr+10);
/* unmap when we unload the driver */
iounmap(baseptr);
- copying and clearing:
/* get the 6-byte ethernet address at ISA address E000:0040 */
memcpy_fromio(kernel_buffer, 0xE0040, 6);
/* write a packet to the driver */
memcpy_toio(0xE1000, skb->data, skb->len);
/* clear the frame buffer */
memset_io(0xA0000, 0, 0x10000);
Ok, that just about covers the basics of accessing IO portably. Questions?
Comments? You may think that all the above is overly complex, but one day you
might find yourself with a 500MHz alpha in front of you, and then you'll be
happy that your driver works ;)
Note that kernel versions 2.0.x (and earlier) mistakenly called the
ioremap() function "vremap()". ioremap() is the proper name, but I
didn't think straight when I wrote it originally. People who have to
support both can do something like:
/* support old naming sillyness */
#if LINUX_VERSION_CODE < 0x020100
#define ioremap vremap
#define iounmap vfree
#endif
at the top of their source files, and then they can use the right names
even on 2.0.x systems.
And the above sounds worse than it really is. Most real drivers really
don't do all that complex things (or rather: the complexity is not so
much in the actual IO accesses as in error handling and timeouts etc).
It's generally not hard to fix drivers, and in many cases the code
actually looks better afterwards:
unsigned long signature = *(unsigned int *) 0xC0000;
vs
unsigned long signature = readl(0xC0000);
I think the second version actually is more readable, no?
Linus
...@@ -352,6 +352,14 @@ e. Directory listings are unpredictably truncated, and `dmesg' shows ...@@ -352,6 +352,14 @@ e. Directory listings are unpredictably truncated, and `dmesg' shows
bug. bug.
f. Data corruption.
- Random data corruption was occasionally observed with the Hitachi
CDR-7730 cdrom. If you experience data corruption, using "hdx=slow"
as a command line parameter may work around the problem, at the
expense of low system performance.
6. cdload.c 6. cdload.c
----------- -----------
......
...@@ -255,6 +255,8 @@ Summary of ide driver parameters for kernel "command line": ...@@ -255,6 +255,8 @@ Summary of ide driver parameters for kernel "command line":
Not fully supported by all chipset types, Not fully supported by all chipset types,
and quite likely to cause trouble with and quite likely to cause trouble with
older/odd IDE drives. older/odd IDE drives.
"hdx=slow" : insert a huge pause after each access to the data
port. Should be used only as a last resort.
"idebus=xx" : inform IDE driver of VESA/PCI bus speed in Mhz, "idebus=xx" : inform IDE driver of VESA/PCI bus speed in Mhz,
where "xx" is between 20 and 66 inclusive, where "xx" is between 20 and 66 inclusive,
......
...@@ -2,14 +2,14 @@ ...@@ -2,14 +2,14 @@
Andy Walker <andy@lysaker.kvaerner.no> Andy Walker <andy@lysaker.kvaerner.no>
15 May 1996 21 Sep 1996
What's New? 1. What's New?
----------- --------------
Flock Emulation Warnings 1.1 Flock Emulation Warnings
------------------------ ----------------------------
Many people will have noticed the ugly messages that the file locking Many people will have noticed the ugly messages that the file locking
code started generating with the release of kernel version 1.3.95. The code started generating with the release of kernel version 1.3.95. The
messages look something like this: messages look something like this:
...@@ -23,16 +23,21 @@ especially with respect to parent-child lock sharing, and can give bad ...@@ -23,16 +23,21 @@ especially with respect to parent-child lock sharing, and can give bad
results if, for example, sendmail attempts to use them. results if, for example, sendmail attempts to use them.
Fixed versions of the C libraries have been on public release for many Fixed versions of the C libraries have been on public release for many
months. The latest versions are 5.2.18 or 5.3.12 for ELF, and I believe months. The latest versions at the time of writing are 5.3.12 (released)
somebody made a 4.7.6 release for people using a.out systems. or 5.4.6 (testing) for ELF. There is also a 4.7.6 release for people
using a.out systems.
With the release of Linux 2.0 Linus decided to be lenient on the
stragglers and changed the warning message so that the kernel will only
complain once and then shut up. That should make life more bearable even
for people who, for some reason, don't want to upgrade their libraries.
In 1.3.96 Linus decided to be lenient on the stragglers and changed the 1.2 Disallow Mixed Locks
warning message so that the kernel will only complain five times and ------------------------
then shut up. That should make life more bearable even for people who,
for some reason, don't want to upgrade.
Sendmail Problems 1.2.1 Sendmail Problems
----------------- ---------------------
Because sendmail was unable to use the old flock() emulation, many sendmail Because sendmail was unable to use the old flock() emulation, many sendmail
installations use fcntl() instead of flock(). This is true of Slackware 3.0 installations use fcntl() instead of flock(). This is true of Slackware 3.0
for example. This gave rise to some other subtle problems if sendmail was for example. This gave rise to some other subtle problems if sendmail was
...@@ -42,8 +47,9 @@ file with flock(). With pre 1.3.96 kernels this could result in deadlocks that, ...@@ -42,8 +47,9 @@ file with flock(). With pre 1.3.96 kernels this could result in deadlocks that,
over time, or under a very heavy mail load, would eventually cause the kernel over time, or under a very heavy mail load, would eventually cause the kernel
to lock solid with deadlocked processes. to lock solid with deadlocked processes.
Disallow Mixed Locks
-------------------- 1.2.2 The Solution
------------------
I have chosen the rather cruel solution of disallowing mixed locking styles I have chosen the rather cruel solution of disallowing mixed locking styles
on a given file at a given time. Attempts to lock a file with flock() when on a given file at a given time. Attempts to lock a file with flock() when
fcntl() locks exist, or vice versa, return with an error status of EBUSY. fcntl() locks exist, or vice versa, return with an error status of EBUSY.
...@@ -61,4 +67,3 @@ Some programs may break (again, groan). In particular the aforementioned ...@@ -61,4 +67,3 @@ Some programs may break (again, groan). In particular the aforementioned
sendmail may have problems running in 'newaliases' mode. It will no longer sendmail may have problems running in 'newaliases' mode. It will no longer
deadlock though. Recompile sendmail to use flock() and your troubles will deadlock though. Recompile sendmail to use flock() and your troubles will
be over. be over.
...@@ -5,8 +5,8 @@ ...@@ -5,8 +5,8 @@
15 April 1996 15 April 1996
What is mandatory locking? 1. What is mandatory locking?
--------------------------- ------------------------------
Mandatory locking is kernel enforced file locking, as opposed to the more usual Mandatory locking is kernel enforced file locking, as opposed to the more usual
cooperative file locking used to guarantee sequential access to files among cooperative file locking used to guarantee sequential access to files among
...@@ -44,8 +44,8 @@ Note 2: POSIX.1 does not specify any scheme for mandatory locking, despite ...@@ -44,8 +44,8 @@ Note 2: POSIX.1 does not specify any scheme for mandatory locking, despite
borrowing the fcntl() locking scheme from System V. The mandatory locking borrowing the fcntl() locking scheme from System V. The mandatory locking
scheme is defined by the System V Interface Definition (SVID) Version 3. scheme is defined by the System V Interface Definition (SVID) Version 3.
Marking a file for mandatory locking 2. Marking a file for mandatory locking
------------------------------------ ---------------------------------------
A file is marked as a candidate for mandatory by setting the group-id bit in A file is marked as a candidate for mandatory by setting the group-id bit in
its file mode but removing the group-execute bit. This is an otherwise its file mode but removing the group-execute bit. This is an otherwise
...@@ -58,8 +58,8 @@ modified to recognize the special case of a mandatory lock candidate and to ...@@ -58,8 +58,8 @@ modified to recognize the special case of a mandatory lock candidate and to
refrain from clearing this bit. Similarly the kernel has been modified not refrain from clearing this bit. Similarly the kernel has been modified not
to run mandatory lock candidates with setgid privileges. to run mandatory lock candidates with setgid privileges.
Available implementations 3. Available implementations
------------------------- ----------------------------
I have considered the implementations of mandatory locking available with I have considered the implementations of mandatory locking available with
SunOS 4.1.x, Solaris 2.x and HP-UX 9.x. SunOS 4.1.x, Solaris 2.x and HP-UX 9.x.
...@@ -93,8 +93,8 @@ I'm afraid that this is such an esoteric area that the semantics described ...@@ -93,8 +93,8 @@ I'm afraid that this is such an esoteric area that the semantics described
below are just as valid as any others, so long as the main points seem to below are just as valid as any others, so long as the main points seem to
agree. agree.
Semantics 4. Semantics
--------- ------------
1. Mandatory locks can only be applied via the fcntl()/lockf() locking 1. Mandatory locks can only be applied via the fcntl()/lockf() locking
interface - in other words the System V/POSIX interface. BSD style interface - in other words the System V/POSIX interface. BSD style
...@@ -124,8 +124,8 @@ Semantics ...@@ -124,8 +124,8 @@ Semantics
that has any mandatory locks in effect will be rejected with the error status that has any mandatory locks in effect will be rejected with the error status
EAGAIN. EAGAIN.
Which system calls are affected? 5. Which system calls are affected?
-------------------------------- -----------------------------------
Those which modify a file's contents, not just the inode. That gives read(), Those which modify a file's contents, not just the inode. That gives read(),
write(), readv(), writev(), open(), creat(), mmap(), truncate() and write(), readv(), writev(), open(), creat(), mmap(), truncate() and
...@@ -142,8 +142,8 @@ Note 3: I may have overlooked some system calls that need mandatory lock ...@@ -142,8 +142,8 @@ Note 3: I may have overlooked some system calls that need mandatory lock
checking in my eagerness to get this code out the door. Please let me know, or checking in my eagerness to get this code out the door. Please let me know, or
better still fix the system calls yourself and submit a patch to me or Linus. better still fix the system calls yourself and submit a patch to me or Linus.
Warning! 6. Warning!
-------- -----------
Not even root can override a mandatory lock, so runaway process can wreak Not even root can override a mandatory lock, so runaway process can wreak
havoc if they lock crucial files. The way around it is to change the file havoc if they lock crucial files. The way around it is to change the file
......
...@@ -159,6 +159,12 @@ M: mike@i-Connect.Net ...@@ -159,6 +159,12 @@ M: mike@i-Connect.Net
L: linux-eata@i-connect.net, linux-scsi@vger.rutgers.edu L: linux-eata@i-connect.net, linux-scsi@vger.rutgers.edu
S: Maintained S: Maintained
FILE LOCKING (flock() and fcntl()/lockf())
P: Andy Walker
M: andy@lysaker.kvaerner.no
L: linux-kernel@vger.rutgers.edu
S: Maintained
FRAME RELAY DLCI/FRAD (Sangoma drivers too) FRAME RELAY DLCI/FRAD (Sangoma drivers too)
P: Mike McLagan P: Mike McLagan
M: mike.mclagan@linux.org M: mike.mclagan@linux.org
......
VERSION = 2 VERSION = 2
PATCHLEVEL = 0 PATCHLEVEL = 1
SUBLEVEL = 21 SUBLEVEL = 0
ARCH = i386 ARCH = i386
...@@ -26,7 +26,7 @@ TOPDIR := $(shell if [ "$$PWD" != "" ]; then echo $$PWD; else pwd; fi) ...@@ -26,7 +26,7 @@ TOPDIR := $(shell if [ "$$PWD" != "" ]; then echo $$PWD; else pwd; fi)
HPATH = $(TOPDIR)/include HPATH = $(TOPDIR)/include
FINDHPATH = $(HPATH)/asm $(HPATH)/linux $(HPATH)/scsi $(HPATH)/net FINDHPATH = $(HPATH)/asm $(HPATH)/linux $(HPATH)/scsi $(HPATH)/net
HOSTCC =gcc -I$(HPATH) HOSTCC =gcc
HOSTCFLAGS =-O2 -fomit-frame-pointer HOSTCFLAGS =-O2 -fomit-frame-pointer
CROSS_COMPILE = CROSS_COMPILE =
......
Linux kernel release 2.0.xx Linux kernel release 2.1.xx
These are the release notes for linux version 2.0. Read them carefully, These are the release notes for linux version 2.1. Read them carefully,
as they tell you what this is all about, explain how to install the as they tell you what this is all about, explain how to install the
kernel, and what to do if something goes wrong. kernel, and what to do if something goes wrong.
Linux version 2.1 is a DEVELOPMENT kernel, and not intended for general
public use. Different releases may have various and sometimes severe
bugs. It is *strongly* recommended that you back up the previous kernel
before installing any new 2.1.xx release.
If you need to use a proven and stable Linux kernel, please use 1.0.9,
1.2.13, or 2.0.xx. All features which will be in the 2.1.xx releases will
be contained in 2.2.xx when the code base has stabilized again.
If you decide to use 2.1, it is recommended that you join the kernel mailing
list. To do this, e-mail majordomo@vger.rutgers.edu, and put in the body
of the message "subscribe linux-kernel" or "subscribe linux-kernel-digest"
for a daily digest of the mailing list (it is a high-traffic list.)
WHAT IS LINUX? WHAT IS LINUX?
Linux is a Unix clone written from scratch by Linus Torvalds with Linux is a Unix clone written from scratch by Linus Torvalds with
...@@ -27,7 +41,7 @@ ON WHAT HARDWARE DOES IT RUN? ...@@ -27,7 +41,7 @@ ON WHAT HARDWARE DOES IT RUN?
DOCUMENTATION: DOCUMENTATION:
- there is a lot of documentation available both in electronic form on - There is a lot of documentation available both in electronic form on
the internet and in books, both Linux-specific and pertaining to the internet and in books, both Linux-specific and pertaining to
general UNIX questions. I'd recommend looking into the documentation general UNIX questions. I'd recommend looking into the documentation
subdirectories on any Linux ftp site for the LDP (Linux Documentation subdirectories on any Linux ftp site for the LDP (Linux Documentation
...@@ -44,13 +58,13 @@ INSTALLING the kernel: ...@@ -44,13 +58,13 @@ INSTALLING the kernel:
- If you install the full sources, do a - If you install the full sources, do a
cd /usr/src cd /usr/src
gzip -cd linux-2.0.XX.tar.gz | tar xfv - gzip -cd linux-2.1.XX.tar.gz | tar xfv -
to get it all put in place. Replace "XX" with the version number of the to get it all put in place. Replace "XX" with the version number of the
latest kernel. latest kernel.
- You can also upgrade between 2.0.xx releases by patching. Each - You can also upgrade between 2.1.xx releases by patching. Each
patch that is released for 2.0.xx contains only bugfixes. No patch that is released for 2.1.xx contains only bugfixes. No
new features will be added to the Linux kernel until the 2.1.xx new features will be added to the Linux kernel until the 2.1.xx
development effort begins. To install by patching, get all the development effort begins. To install by patching, get all the
newer patch files and do newer patch files and do
...@@ -76,7 +90,7 @@ INSTALLING the kernel: ...@@ -76,7 +90,7 @@ INSTALLING the kernel:
the current directory, but an alternative directory can be specified the current directory, but an alternative directory can be specified
as the second argument. as the second argument.
- make sure your /usr/include/asm, /usr/include/linux, and /usr/include/scsi - Make sure your /usr/include/asm, /usr/include/linux, and /usr/include/scsi
directories are just symlinks to the kernel sources: directories are just symlinks to the kernel sources:
cd /usr/include cd /usr/include
...@@ -85,7 +99,7 @@ INSTALLING the kernel: ...@@ -85,7 +99,7 @@ INSTALLING the kernel:
ln -s /usr/src/linux/include/linux linux ln -s /usr/src/linux/include/linux linux
ln -s /usr/src/linux/include/scsi scsi ln -s /usr/src/linux/include/scsi scsi
- make sure you have no stale .o files and dependencies lying around: - Make sure you have no stale .o files and dependencies lying around:
cd /usr/src/linux cd /usr/src/linux
make mrproper make mrproper
...@@ -94,7 +108,7 @@ INSTALLING the kernel: ...@@ -94,7 +108,7 @@ INSTALLING the kernel:
CONFIGURING the kernel: CONFIGURING the kernel:
- do a "make config" to configure the basic kernel. "make config" - Do a "make config" to configure the basic kernel. "make config"
needs bash to work: it will search for bash in $BASH, /bin/bash and needs bash to work: it will search for bash in $BASH, /bin/bash and
/bin/sh (in that order), so hopefully one of those is correct. /bin/sh (in that order), so hopefully one of those is correct.
...@@ -128,26 +142,28 @@ CONFIGURING the kernel: ...@@ -128,26 +142,28 @@ CONFIGURING the kernel:
COMPILING the kernel: COMPILING the kernel:
- make sure you have gcc-2.6.3 or newer available. It seems older gcc - Make sure you have gcc-2.7.0 or newer available. It seems older gcc
versions can have problems compiling newer versions of linux. If you versions can have problems compiling newer versions of linux. This
upgrade your compiler, remember to get the new binutils package too is mainly because they only compile programs in the a.out binary
format. As of Linux 2.1.0, the kernel must be compiled as ELF. If
you upgrade your compiler, remember to get the new binutils package too
(for as/ld/nm and company). (for as/ld/nm and company).
- do a "make zImage" to create a compressed kernel image. If you want - Do a "make zImage" to create a compressed kernel image. If you want
to make a bootdisk (without root filesystem or lilo), insert a floppy to make a bootdisk (without root filesystem or lilo), insert a floppy
in your A: drive, and do a "make zdisk". It is also possible to do in your A: drive, and do a "make zdisk". It is also possible to do
"make zlilo" if you have lilo installed to suit the kernel makefiles, "make zlilo" if you have lilo installed to suit the kernel makefiles,
but you may want to check your particular lilo setup first. but you may want to check your particular lilo setup first.
- if your kernel is too large for "make zImage", use "make bzImage" - If your kernel is too large for "make zImage", use "make bzImage"
instead. instead.
- if you configured any of the parts of the kernel as `modules', you - If you configured any of the parts of the kernel as `modules', you
will have to do "make modules" followed by "make modules_install". will have to do "make modules" followed by "make modules_install".
Read Documentation/modules.txt for more information. For example, Read Documentation/modules.txt for more information. For example,
an explanation of how to use the modules is included there. an explanation of how to use the modules is included there.
- keep a backup kernel handy in case something goes wrong. This is - Keep a backup kernel handy in case something goes wrong. This is
especially true for the development releases, since each new release especially true for the development releases, since each new release
contains new code which has not been debugged. contains new code which has not been debugged.
...@@ -157,9 +173,9 @@ COMPILING the kernel: ...@@ -157,9 +173,9 @@ COMPILING the kernel:
For some, this is on a floppy disk, in which case you can "cp For some, this is on a floppy disk, in which case you can "cp
/usr/src/linux/arch/i386/boot/zImage /dev/fd0" to make a bootable /usr/src/linux/arch/i386/boot/zImage /dev/fd0" to make a bootable
floppy. Note that as of Linux 2.0.0, a kernel copied to a 720k floppy. Note that a change in the 1.3.x series prevented a kernel
double-density 3.5" floppy disk no longer boots. In this case, copied to a 720k double-density 3.5" floppy from booting. In this
it is highly recommended that you install LILO on your case, it is highly recommended that you install LILO on your
double-density bootfloppy or switch to high-density floppies. double-density bootfloppy or switch to high-density floppies.
If you boot Linux from the hard drive, chances are you use LILO which If you boot Linux from the hard drive, chances are you use LILO which
...@@ -183,11 +199,11 @@ COMPILING the kernel: ...@@ -183,11 +199,11 @@ COMPILING the kernel:
alternatively the LILO boot options when appropriate). No need to alternatively the LILO boot options when appropriate). No need to
recompile the kernel to change these parameters. recompile the kernel to change these parameters.
- reboot with the new kernel and enjoy. - Reboot with the new kernel and enjoy.
IF SOMETHING GOES WRONG: IF SOMETHING GOES WRONG:
- if you have problems that seem to be due to kernel bugs, please check - If you have problems that seem to be due to kernel bugs, please check
the file MAINTAINERS to see if there is a particular person associated the file MAINTAINERS to see if there is a particular person associated
with the part of the kernel that you are having trouble with. If there with the part of the kernel that you are having trouble with. If there
isn't anyone listed there, then the second best thing is to mail isn't anyone listed there, then the second best thing is to mail
...@@ -201,7 +217,7 @@ IF SOMETHING GOES WRONG: ...@@ -201,7 +217,7 @@ IF SOMETHING GOES WRONG:
sense). If the problem is new, tell me so, and if the problem is sense). If the problem is new, tell me so, and if the problem is
old, please try to tell me when you first noticed it. old, please try to tell me when you first noticed it.
- if the bug results in a message like - If the bug results in a message like
unable to handle kernel paging request at address C0000010 unable to handle kernel paging request at address C0000010
Oops: 0002 Oops: 0002
...@@ -224,7 +240,7 @@ IF SOMETHING GOES WRONG: ...@@ -224,7 +240,7 @@ IF SOMETHING GOES WRONG:
the C++ sources under the scripts/ directory to avoid having to do the C++ sources under the scripts/ directory to avoid having to do
the dump lookup by hand: the dump lookup by hand:
- in debugging dumps like the above, it helps enormously if you can - In debugging dumps like the above, it helps enormously if you can
look up what the EIP value means. The hex value as such doesn't help look up what the EIP value means. The hex value as such doesn't help
me or anybody else very much: it will depend on your particular me or anybody else very much: it will depend on your particular
kernel setup. What you should do is take the hex value from the EIP kernel setup. What you should do is take the hex value from the EIP
...@@ -255,7 +271,7 @@ IF SOMETHING GOES WRONG: ...@@ -255,7 +271,7 @@ IF SOMETHING GOES WRONG:
kernel image or similar), telling me as much about your setup as kernel image or similar), telling me as much about your setup as
possible will help. possible will help.
- alternately, you can use gdb on a running kernel. (read-only; i.e. you - Alternately, you can use gdb on a running kernel. (read-only; i.e. you
cannot change values or set break points.) To do this, first compile the cannot change values or set break points.) To do this, first compile the
kernel with -g; edit arch/i386/Makefile appropriately, then do a "make kernel with -g; edit arch/i386/Makefile appropriately, then do a "make
clean". You'll also need to enable CONFIG_PROC_FS (via "make config"). clean". You'll also need to enable CONFIG_PROC_FS (via "make config").
......
...@@ -197,7 +197,7 @@ static unsigned long get_long(struct task_struct * tsk, ...@@ -197,7 +197,7 @@ static unsigned long get_long(struct task_struct * tsk,
} }
page = pte_page(*pgtable); page = pte_page(*pgtable);
/* this is a hack for non-kernel-mapped video buffers and similar */ /* this is a hack for non-kernel-mapped video buffers and similar */
if (page >= high_memory) if (MAP_NR(page) >= max_mapnr)
return 0; return 0;
page += addr & ~PAGE_MASK; page += addr & ~PAGE_MASK;
return *(unsigned long *) page; return *(unsigned long *) page;
...@@ -252,7 +252,7 @@ static void put_long(struct task_struct * tsk, struct vm_area_struct * vma, ...@@ -252,7 +252,7 @@ static void put_long(struct task_struct * tsk, struct vm_area_struct * vma,
goto repeat; goto repeat;
} }
/* this is a hack for non-kernel-mapped video buffers and similar */ /* this is a hack for non-kernel-mapped video buffers and similar */
if (page < high_memory) if (MAP_NR(page) < max_mapnr)
*(unsigned long *) (page + (addr & ~PAGE_MASK)) = data; *(unsigned long *) (page + (addr & ~PAGE_MASK)) = data;
/* we're bypassing pagetables, so we have to set the dirty bit ourselves */ /* we're bypassing pagetables, so we have to set the dirty bit ourselves */
/* this should also re-instate whatever read-only mode there was before */ /* this should also re-instate whatever read-only mode there was before */
......
...@@ -59,7 +59,7 @@ void show_mem(void) ...@@ -59,7 +59,7 @@ void show_mem(void)
printk("\nMem-info:\n"); printk("\nMem-info:\n");
show_free_areas(); show_free_areas();
printk("Free swap: %6dkB\n",nr_swap_pages<<(PAGE_SHIFT-10)); printk("Free swap: %6dkB\n",nr_swap_pages<<(PAGE_SHIFT-10));
i = MAP_NR(high_memory); i = max_mapnr;
while (i-- > 0) { while (i-- > 0) {
total++; total++;
if (PageReserved(mem_map+i)) if (PageReserved(mem_map+i))
...@@ -145,7 +145,8 @@ void mem_init(unsigned long start_mem, unsigned long end_mem) ...@@ -145,7 +145,8 @@ void mem_init(unsigned long start_mem, unsigned long end_mem)
unsigned long tmp; unsigned long tmp;
end_mem &= PAGE_MASK; end_mem &= PAGE_MASK;
high_memory = end_mem; max_mapnr = MAP_NR(end_mem);
high_memory = (void *) end_mem;
start_mem = PAGE_ALIGN(start_mem); start_mem = PAGE_ALIGN(start_mem);
/* /*
...@@ -157,7 +158,7 @@ void mem_init(unsigned long start_mem, unsigned long end_mem) ...@@ -157,7 +158,7 @@ void mem_init(unsigned long start_mem, unsigned long end_mem)
tmp += PAGE_SIZE; tmp += PAGE_SIZE;
} }
for (tmp = PAGE_OFFSET ; tmp < high_memory ; tmp += PAGE_SIZE) { for (tmp = PAGE_OFFSET ; tmp < end_mem ; tmp += PAGE_SIZE) {
if (tmp >= MAX_DMA_ADDRESS) if (tmp >= MAX_DMA_ADDRESS)
clear_bit(PG_DMA, &mem_map[MAP_NR(tmp)].flags); clear_bit(PG_DMA, &mem_map[MAP_NR(tmp)].flags);
if (PageReserved(mem_map+MAP_NR(tmp))) if (PageReserved(mem_map+MAP_NR(tmp)))
...@@ -174,7 +175,7 @@ void si_meminfo(struct sysinfo *val) ...@@ -174,7 +175,7 @@ void si_meminfo(struct sysinfo *val)
{ {
int i; int i;
i = MAP_NR(high_memory); i = max_mapnr;
val->totalram = 0; val->totalram = 0;
val->sharedram = 0; val->sharedram = 0;
val->freeram = nr_free_pages << PAGE_SHIFT; val->freeram = nr_free_pages << PAGE_SHIFT;
......
...@@ -13,27 +13,25 @@ ...@@ -13,27 +13,25 @@
# Copyright (C) 1994 by Linus Torvalds # Copyright (C) 1994 by Linus Torvalds
# #
AS86 =$(CROSS_COMPILE)as86 -0 -a
AS386 =$(CROSS_COMPILE)as86 -3
LD86 =$(CROSS_COMPILE)ld86 -0
# #
# Set these to indicate how to link it.. # ZIMAGE_OFFSET is the load offset of the compression loader
# # BZIMAGE_OFFSET is the load offset of the high loaded compression loader
# -zmagic: (aout, old GCC-2.5.2)
#
# ZLINKFLAGS = -Ttext 0x1000
# BZLINKFLAGS = -Ttext 0x100000 # (for big high loaded kernels)
# LINKFLAGS = -Ttext 0x100000
# #
# -qmagic: (aout) ZIMAGE_OFFSET=0x1000
BZIMAGE_OFFSET=0x100000
# #
# ZLINKFLAGS = -Ttext 0x0xfe0 # IMAGE_OFFSET is the load offset of the _real_ kernel, soon
# BZLINKFLAGS = -Ttext 0xfffe0 # (for big high loaded kernels) # to be offset by another 0xC0000000...
# LINKFLAGS = -Ttext 0xfffe0
# #
IMAGE_OFFSET=0xC0100000
AS86 =$(CROSS_COMPILE)as86 -0 -a # This is used for ELF - it needs to migrate or be moved.
AS386 =$(CROSS_COMPILE)as86 -3 LD_RFLAG = -m elf_i386
LD86 =$(CROSS_COMPILE)ld86 -0
ifdef CONFIG_KERNEL_ELF
LD=$(CROSS_COMPILE)ld -m elf_i386 LD=$(CROSS_COMPILE)ld -m elf_i386
CPP=$(CC) -E -D__ELF__ CPP=$(CC) -E -D__ELF__
...@@ -43,22 +41,10 @@ ENCAPS=$(CROSS_COMPILE)encaps ...@@ -43,22 +41,10 @@ ENCAPS=$(CROSS_COMPILE)encaps
OBJCOPY=$(CROSS_COMPILE)objcopy -O binary -R .note -R .comment -R .stab -R .stabstr OBJCOPY=$(CROSS_COMPILE)objcopy -O binary -R .note -R .comment -R .stab -R .stabstr
ZLDFLAGS=-e startup_32 ZLDFLAGS=-e startup_32
LDFLAGS=-e stext LDFLAGS=-e stext
ZIMAGE_OFFSET=0x1000
IMAGE_OFFSET=0x100000
ZLINKFLAGS =-Ttext $(ZIMAGE_OFFSET) $(ZLDFLAGS) ZLINKFLAGS =-Ttext $(ZIMAGE_OFFSET) $(ZLDFLAGS)
BZLINKFLAGS =-Ttext $(IMAGE_OFFSET) $(ZLDFLAGS) BZLINKFLAGS =-Ttext $(BZIMAGE_OFFSET) $(ZLDFLAGS)
LINKFLAGS =-Ttext $(IMAGE_OFFSET) $(LDFLAGS) LINKFLAGS =-Ttext $(IMAGE_OFFSET) $(LDFLAGS)
else
#
# -qmagic (we need to remove the 32 byte header for bootup purposes)
#
ZLINKFLAGS =-qmagic -Ttext 0xfe0
BZLINKFLAGS =-qmagic -Ttext 0xfffe0
LINKFLAGS =-qmagic -Ttext 0xfffe0
endif
CFLAGS := $(CFLAGS) -pipe CFLAGS := $(CFLAGS) -pipe
ifdef CONFIG_M386 ifdef CONFIG_M386
......
...@@ -8,38 +8,28 @@ ...@@ -8,38 +8,28 @@
# Copyright (C) 1994 by Linus Torvalds # Copyright (C) 1994 by Linus Torvalds
# #
ifdef CONFIG_KERNEL_ELF
HOSTCFLAGS := $(HOSTCFLAGS) -D__BFD__ HOSTCFLAGS := $(HOSTCFLAGS) -D__BFD__
endif
ifdef SMP ifdef SMP
HOSTCFLAGS := $(HOSTCFLAGS) -D__SMP__ HOSTCFLAGS := $(HOSTCFLAGS) -D__SMP__
endif endif
zImage: $(CONFIGURE) bootsect setup compressed/vmlinux tools/build zImage: $(CONFIGURE) bootsect setup compressed/vmlinux tools/build
ifdef CONFIG_KERNEL_ELF
if hash $(ENCAPS) 2> /dev/null; then \ if hash $(ENCAPS) 2> /dev/null; then \
$(OBJDUMP) $(OBJDUMP_FLAGS) -o $(ZIMAGE_OFFSET) compressed/vmlinux > compressed/vmlinux.out; \ $(OBJDUMP) $(OBJDUMP_FLAGS) -o $(ZIMAGE_OFFSET) compressed/vmlinux > compressed/vmlinux.out; \
else \ else \
$(OBJCOPY) compressed/vmlinux compressed/vmlinux.out; \ $(OBJCOPY) compressed/vmlinux compressed/vmlinux.out; \
fi fi
tools/build bootsect setup compressed/vmlinux.out $(ROOT_DEV) > zImage tools/build bootsect setup compressed/vmlinux.out $(ROOT_DEV) > zImage
else
tools/build bootsect setup compressed/vmlinux $(ROOT_DEV) > zImage
endif
sync sync
bzImage: $(CONFIGURE) bbootsect setup compressed/bvmlinux tools/bbuild bzImage: $(CONFIGURE) bbootsect setup compressed/bvmlinux tools/bbuild
ifdef CONFIG_KERNEL_ELF
if hash $(ENCAPS) 2> /dev/null; then \ if hash $(ENCAPS) 2> /dev/null; then \
$(OBJDUMP) $(OBJDUMP_FLAGS) -o $(IMAGE_OFFSET) compressed/bvmlinux > compressed/bvmlinux.out; \ $(OBJDUMP) $(OBJDUMP_FLAGS) -o $(IMAGE_OFFSET) compressed/bvmlinux > compressed/bvmlinux.out; \
else \ else \
$(OBJCOPY) compressed/bvmlinux compressed/bvmlinux.out; \ $(OBJCOPY) compressed/bvmlinux compressed/bvmlinux.out; \
fi fi
tools/bbuild bbootsect setup compressed/bvmlinux.out $(ROOT_DEV) > bzImage tools/bbuild bbootsect setup compressed/bvmlinux.out $(ROOT_DEV) > bzImage
else
tools/bbuild bbootsect setup compressed/bvmlinux $(ROOT_DEV) > bzImage
endif
sync sync
compressed/vmlinux: $(TOPDIR)/vmlinux compressed/vmlinux: $(TOPDIR)/vmlinux
......
...@@ -15,11 +15,9 @@ ifdef SMP ...@@ -15,11 +15,9 @@ ifdef SMP
CFLAGS := $(CFLAGS) -D__SMP__ CFLAGS := $(CFLAGS) -D__SMP__
endif endif
ifdef CONFIG_KERNEL_ELF
TARGET=--target elf32-i386 TARGET=--target elf32-i386
INPUT_DATA=input_data INPUT_DATA=input_data
INPUT_LEN=input_len INPUT_LEN=input_len
endif
all: vmlinux all: vmlinux
...@@ -41,7 +39,6 @@ head.o: head.S $(TOPDIR)/include/linux/tasks.h ...@@ -41,7 +39,6 @@ head.o: head.S $(TOPDIR)/include/linux/tasks.h
endif endif
ifdef CONFIG_KERNEL_ELF
# You cannot compress a file and have the kernel uncompress it, it must # You cannot compress a file and have the kernel uncompress it, it must
# be stdin # be stdin
...@@ -61,18 +58,6 @@ piggy.o: $(SYSTEM) ...@@ -61,18 +58,6 @@ piggy.o: $(SYSTEM)
$(LD) -m elf_i386 -r -o piggy.o -b binary $$tmppiggy.gz -b elf32-i386 -T $$tmppiggy.lnk; \ $(LD) -m elf_i386 -r -o piggy.o -b binary $$tmppiggy.gz -b elf32-i386 -T $$tmppiggy.lnk; \
fi; \ fi; \
rm -f $$tmppiggy $$tmppiggy.gz $$tmppiggy.lnk rm -f $$tmppiggy $$tmppiggy.gz $$tmppiggy.lnk
else
piggy.o: $(SYSTEM) xtract piggyback
./xtract $(SYSTEM) | gzip -9 | ./piggyback > piggy.o
xtract: xtract.c
$(HOSTCC) $(CFLAGS) -o xtract xtract.c
piggyback: piggyback.c
$(HOSTCC) $(CFLAGS) -o piggyback piggyback.c
endif
clean: clean:
rm -f xtract piggyback vmlinux bvmlinux rm -f xtract piggyback vmlinux bvmlinux
...@@ -21,6 +21,8 @@ ...@@ -21,6 +21,8 @@
#define OF(args) args #define OF(args) args
#define STATIC static #define STATIC static
#undef memset
#undef memcpy
#define memzero(s, n) memset ((s), 0, (n)) #define memzero(s, n) memset ((s), 0, (n))
typedef unsigned char uch; typedef unsigned char uch;
......
...@@ -36,7 +36,6 @@ tristate 'Kernel support for ELF binaries' CONFIG_BINFMT_ELF ...@@ -36,7 +36,6 @@ tristate 'Kernel support for ELF binaries' CONFIG_BINFMT_ELF
if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
tristate 'Kernel support for JAVA binaries' CONFIG_BINFMT_JAVA tristate 'Kernel support for JAVA binaries' CONFIG_BINFMT_JAVA
fi fi
bool 'Compile kernel as ELF - if your GCC is ELF-GCC' CONFIG_KERNEL_ELF
choice 'Processor type' \ choice 'Processor type' \
"386 CONFIG_M386 \ "386 CONFIG_M386 \
......
...@@ -24,7 +24,6 @@ CONFIG_PCI=y ...@@ -24,7 +24,6 @@ CONFIG_PCI=y
CONFIG_SYSVIPC=y CONFIG_SYSVIPC=y
CONFIG_BINFMT_AOUT=y CONFIG_BINFMT_AOUT=y
CONFIG_BINFMT_ELF=y CONFIG_BINFMT_ELF=y
CONFIG_KERNEL_ELF=y
# CONFIG_M386 is not set # CONFIG_M386 is not set
# CONFIG_M486 is not set # CONFIG_M486 is not set
CONFIG_M586=y CONFIG_M586=y
......
...@@ -55,6 +55,7 @@ ...@@ -55,6 +55,7 @@
#include <linux/bios32.h> #include <linux/bios32.h>
#include <linux/pci.h> #include <linux/pci.h>
#include <asm/page.h>
#include <asm/segment.h> #include <asm/segment.h>
#define PCIBIOS_PCI_FUNCTION_ID 0xb1XX #define PCIBIOS_PCI_FUNCTION_ID 0xb1XX
...@@ -164,7 +165,7 @@ extern unsigned long check_pcibios(unsigned long memory_start, unsigned long mem ...@@ -164,7 +165,7 @@ extern unsigned long check_pcibios(unsigned long memory_start, unsigned long mem
int pack; int pack;
if ((pcibios_entry = bios32_service(PCI_SERVICE))) { if ((pcibios_entry = bios32_service(PCI_SERVICE))) {
pci_indirect.address = pcibios_entry; pci_indirect.address = pcibios_entry | PAGE_OFFSET;
__asm__("lcall (%%edi)\n\t" __asm__("lcall (%%edi)\n\t"
"jc 1f\n\t" "jc 1f\n\t"
...@@ -417,7 +418,9 @@ unsigned long pcibios_init(unsigned long memory_start, unsigned long memory_end) ...@@ -417,7 +418,9 @@ unsigned long pcibios_init(unsigned long memory_start, unsigned long memory_end)
* *
*/ */
for (check = (union bios32 *) 0xe0000; check <= (union bios32 *) 0xffff0; ++check) { for (check = (union bios32 *) __va(0xe0000);
check <= (union bios32 *) __va(0xffff0);
++check) {
if (check->fields.signature != BIOS32_SIGNATURE) if (check->fields.signature != BIOS32_SIGNATURE)
continue; continue;
length = check->fields.length * 16; length = check->fields.length * 16;
...@@ -438,8 +441,9 @@ unsigned long pcibios_init(unsigned long memory_start, unsigned long memory_end) ...@@ -438,8 +441,9 @@ unsigned long pcibios_init(unsigned long memory_start, unsigned long memory_end)
if (check->fields.entry >= 0x100000) { if (check->fields.entry >= 0x100000) {
printk("pcibios_init: entry in high memory, unable to access\n"); printk("pcibios_init: entry in high memory, unable to access\n");
} else { } else {
bios32_indirect.address = bios32_entry = check->fields.entry; bios32_entry = check->fields.entry;
printk ("pcibios_init : BIOS32 Service Directory entry at 0x%lx\n", bios32_entry); printk ("pcibios_init : BIOS32 Service Directory entry at 0x%lx\n", bios32_entry);
bios32_indirect.address = bios32_entry + PAGE_OFFSET;
} }
} }
} }
......
...@@ -38,6 +38,8 @@ ...@@ -38,6 +38,8 @@
* 38(%esp) - %eflags * 38(%esp) - %eflags
* 3C(%esp) - %oldesp * 3C(%esp) - %oldesp
* 40(%esp) - %oldss * 40(%esp) - %oldss
*
* "current" is in register %ebx during any slow entries.
*/ */
#include <linux/sys.h> #include <linux/sys.h>
...@@ -99,9 +101,7 @@ ENOSYS = 38 ...@@ -99,9 +101,7 @@ ENOSYS = 38
pushl %ebx; \ pushl %ebx; \
movl $(KERNEL_DS),%edx; \ movl $(KERNEL_DS),%edx; \
mov %dx,%ds; \ mov %dx,%ds; \
mov %dx,%es; \ mov %dx,%es;
movl $(USER_DS),%edx; \
mov %dx,%fs;
#ifdef __SMP__ #ifdef __SMP__
...@@ -194,13 +194,7 @@ ENOSYS = 38 ...@@ -194,13 +194,7 @@ ENOSYS = 38
#define RESTORE_ALL \ #define RESTORE_ALL \
cmpw $(KERNEL_CS),CS(%esp); \ LEAVE_KERNEL \
je 1f; \
GET_PROCESSOR_OFFSET(%edx) \
movl SYMBOL_NAME(current_set)(,%edx), %eax ; ; \
movl dbgreg7(%eax),%ebx; \
movl %ebx,%db7; \
1: LEAVE_KERNEL \
popl %ebx; \ popl %ebx; \
popl %ecx; \ popl %ecx; \
popl %edx; \ popl %edx; \
...@@ -215,15 +209,16 @@ ENOSYS = 38 ...@@ -215,15 +209,16 @@ ENOSYS = 38
addl $4,%esp; \ addl $4,%esp; \
iret iret
#define GET_CURRENT \
GET_PROCESSOR_OFFSET(%ebx) \
movl SYMBOL_NAME(current_set)(%ebx),%ebx
#else #else
#define GET_CURRENT \
movl SYMBOL_NAME(current_set),%ebx
#define RESTORE_ALL \ #define RESTORE_ALL \
cmpw $(KERNEL_CS),CS(%esp); \
je 1f; \
movl SYMBOL_NAME(current_set),%eax; \
movl dbgreg7(%eax),%ebx; \
movl %ebx,%db7; \
1: \
popl %ebx; \ popl %ebx; \
popl %ecx; \ popl %ecx; \
popl %edx; \ popl %edx; \
...@@ -244,6 +239,7 @@ ENTRY(lcall7) ...@@ -244,6 +239,7 @@ ENTRY(lcall7)
pushfl # We get a different stack layout with call gates, pushfl # We get a different stack layout with call gates,
pushl %eax # which has to be cleaned up later.. pushl %eax # which has to be cleaned up later..
SAVE_ALL SAVE_ALL
GET_CURRENT
#ifdef __SMP__ #ifdef __SMP__
ENTER_KERNEL ENTER_KERNEL
#endif #endif
...@@ -281,6 +277,7 @@ reschedule: ...@@ -281,6 +277,7 @@ reschedule:
ENTRY(system_call) ENTRY(system_call)
pushl %eax # save orig_eax pushl %eax # save orig_eax
SAVE_ALL SAVE_ALL
GET_CURRENT
#ifdef __SMP__ #ifdef __SMP__
ENTER_KERNEL ENTER_KERNEL
#endif #endif
...@@ -290,33 +287,11 @@ ENTRY(system_call) ...@@ -290,33 +287,11 @@ ENTRY(system_call)
movl SYMBOL_NAME(sys_call_table)(,%eax,4),%eax movl SYMBOL_NAME(sys_call_table)(,%eax,4),%eax
testl %eax,%eax testl %eax,%eax
je ret_from_sys_call je ret_from_sys_call
#ifdef __SMP__
GET_PROCESSOR_OFFSET(%edx)
movl SYMBOL_NAME(current_set)(,%edx),%ebx
#else
movl SYMBOL_NAME(current_set),%ebx
#endif
andl $~CF_MASK,EFLAGS(%esp) # clear carry - assume no errors andl $~CF_MASK,EFLAGS(%esp) # clear carry - assume no errors
movl %db6,%edx
movl %edx,dbgreg6(%ebx) # save current hardware debugging status
testb $0x20,flags(%ebx) # PF_TRACESYS testb $0x20,flags(%ebx) # PF_TRACESYS
jne 1f jne tracesys
call *%eax call *%eax
movl %eax,EAX(%esp) # save the return value movl %eax,EAX(%esp) # save the return value
jmp ret_from_sys_call
ALIGN
1: call SYMBOL_NAME(syscall_trace)
movl ORIG_EAX(%esp),%eax
call SYMBOL_NAME(sys_call_table)(,%eax,4)
movl %eax,EAX(%esp) # save the return value
#ifdef __SMP__
GET_PROCESSOR_OFFSET(%eax)
movl SYMBOL_NAME(current_set)(,%eax),%eax
#else
movl SYMBOL_NAME(current_set),%eax
#endif
call SYMBOL_NAME(syscall_trace)
ALIGN ALIGN
.globl ret_from_sys_call .globl ret_from_sys_call
ret_from_sys_call: ret_from_sys_call:
...@@ -336,18 +311,12 @@ ret_from_sys_call: ...@@ -336,18 +311,12 @@ ret_from_sys_call:
movl %eax,EFLAGS(%esp) # stupid movl %eax,EFLAGS(%esp) # stupid
cmpl $0,SYMBOL_NAME(need_resched) cmpl $0,SYMBOL_NAME(need_resched)
jne reschedule jne reschedule
#ifdef __SMP__ cmpl SYMBOL_NAME(task),%ebx # task[0] cannot have signals
GET_PROCESSOR_OFFSET(%eax)
movl SYMBOL_NAME(current_set)(,%eax), %eax
#else
movl SYMBOL_NAME(current_set),%eax
#endif
cmpl SYMBOL_NAME(task),%eax # task[0] cannot have signals
je 2f je 2f
movl blocked(%eax),%ecx movl blocked(%ebx),%ecx
movl %ecx,%ebx # save blocked in %ebx for signal handling movl %ecx,%eax # save blocked in %eax for signal handling
notl %ecx notl %ecx
andl signal(%eax),%ecx andl signal(%ebx),%ecx
jne signal_return jne signal_return
2: RESTORE_ALL 2: RESTORE_ALL
ALIGN ALIGN
...@@ -356,21 +325,32 @@ signal_return: ...@@ -356,21 +325,32 @@ signal_return:
pushl %ecx pushl %ecx
testl $(VM_MASK),EFLAGS(%ecx) testl $(VM_MASK),EFLAGS(%ecx)
jne v86_signal_return jne v86_signal_return
pushl %ebx pushl %eax
call SYMBOL_NAME(do_signal) call SYMBOL_NAME(do_signal)
popl %ebx popl %eax
popl %ebx popl %eax
RESTORE_ALL RESTORE_ALL
ALIGN ALIGN
v86_signal_return: v86_signal_return:
pushl %eax
call SYMBOL_NAME(save_v86_state) call SYMBOL_NAME(save_v86_state)
popl %edx
movl %eax,%esp movl %eax,%esp
pushl %eax pushl %eax
pushl %ebx pushl %edx
call SYMBOL_NAME(do_signal) call SYMBOL_NAME(do_signal)
popl %ebx popl %edx
popl %ebx popl %edx
RESTORE_ALL RESTORE_ALL
ALIGN
tracesys:
call SYMBOL_NAME(syscall_trace)
movl ORIG_EAX(%esp),%eax
call SYMBOL_NAME(sys_call_table)(,%eax,4)
movl %eax,EAX(%esp) # save the return value
call SYMBOL_NAME(syscall_trace)
jmp ret_from_sys_call
ENTRY(divide_error) ENTRY(divide_error)
pushl $0 # no error code pushl $0 # no error code
...@@ -390,28 +370,21 @@ error_code: ...@@ -390,28 +370,21 @@ error_code:
pushl %ecx pushl %ecx
pushl %ebx pushl %ebx
cld cld
xorl %ebx,%ebx # zero ebx xorl %ecx,%ecx # zero ecx
xchgl %eax, ORIG_EAX(%esp) # orig_eax (get the error code. ) xchgl %eax, ORIG_EAX(%esp) # orig_eax (get the error code. )
mov %gs,%bx # get the lower order bits of gs mov %gs,%bx # get the lower order bits of gs
movl %esp,%edx movl %esp,%edx
xchgl %ebx, GS(%esp) # get the address and save gs. xchgl %ecx, GS(%esp) # get the address and save gs.
pushl %eax # push the error code pushl %eax # push the error code
pushl %edx pushl %edx
movl $(KERNEL_DS),%edx movl $(KERNEL_DS),%edx
mov %dx,%ds mov %dx,%ds
mov %dx,%es mov %dx,%es
movl $(USER_DS),%edx GET_CURRENT
mov %dx,%fs
#ifdef __SMP__ #ifdef __SMP__
ENTER_KERNEL ENTER_KERNEL
GET_PROCESSOR_OFFSET(%eax)
movl SYMBOL_NAME(current_set)(,%eax), %eax
#else
movl SYMBOL_NAME(current_set),%eax
#endif #endif
movl %db6,%edx call *%ecx
movl %edx,dbgreg6(%eax) # save current hardware debugging status
call *%ebx
addl $8,%esp addl $8,%esp
jmp ret_from_sys_call jmp ret_from_sys_call
...@@ -423,6 +396,7 @@ ENTRY(coprocessor_error) ...@@ -423,6 +396,7 @@ ENTRY(coprocessor_error)
ENTRY(device_not_available) ENTRY(device_not_available)
pushl $-1 # mark this as an int pushl $-1 # mark this as an int
SAVE_ALL SAVE_ALL
GET_CURRENT
#ifdef __SMP__ #ifdef __SMP__
ENTER_KERNEL ENTER_KERNEL
#endif #endif
......
This diff is collapsed.
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
#include <linux/elfcore.h> #include <linux/elfcore.h>
#include <asm/semaphore.h> #include <asm/semaphore.h>
#include <asm/io.h>
extern void dump_thread(struct pt_regs *, struct user *); extern void dump_thread(struct pt_regs *, struct user *);
extern int dump_fpu(elf_fpregset_t *); extern int dump_fpu(elf_fpregset_t *);
...@@ -13,6 +14,7 @@ static struct symbol_table arch_symbol_table = { ...@@ -13,6 +14,7 @@ static struct symbol_table arch_symbol_table = {
/* platform dependent support */ /* platform dependent support */
X(dump_thread), X(dump_thread),
X(dump_fpu), X(dump_fpu),
X(ioremap),
XNOVERS(down_failed), XNOVERS(down_failed),
XNOVERS(up_wakeup), XNOVERS(up_wakeup),
#ifdef __SMP__ #ifdef __SMP__
......
...@@ -8,9 +8,11 @@ ...@@ -8,9 +8,11 @@
#include <linux/sched.h> #include <linux/sched.h>
#include <linux/string.h> #include <linux/string.h>
#include <linux/mm.h> #include <linux/mm.h>
#include <linux/vmalloc.h>
#include <asm/segment.h> #include <asm/segment.h>
#include <asm/system.h> #include <asm/system.h>
#include <linux/ldt.h> #include <asm/ldt.h>
static int read_ldt(void * ptr, unsigned long bytecount) static int read_ldt(void * ptr, unsigned long bytecount)
{ {
......
...@@ -19,19 +19,20 @@ ...@@ -19,19 +19,20 @@
#include <linux/unistd.h> #include <linux/unistd.h>
#include <linux/ptrace.h> #include <linux/ptrace.h>
#include <linux/malloc.h> #include <linux/malloc.h>
#include <linux/ldt.h> #include <linux/vmalloc.h>
#include <linux/user.h> #include <linux/user.h>
#include <linux/a.out.h> #include <linux/a.out.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/config.h> #include <linux/config.h>
#include <linux/unistd.h> #include <linux/unistd.h>
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/smp.h>
#include <asm/segment.h> #include <asm/segment.h>
#include <asm/pgtable.h> #include <asm/pgtable.h>
#include <asm/system.h> #include <asm/system.h>
#include <asm/io.h> #include <asm/io.h>
#include <linux/smp.h> #include <asm/ldt.h>
asmlinkage void ret_from_sys_call(void) __asm__("ret_from_sys_call"); asmlinkage void ret_from_sys_call(void) __asm__("ret_from_sys_call");
...@@ -182,6 +183,17 @@ int cpu_idle(void *unused) ...@@ -182,6 +183,17 @@ int cpu_idle(void *unused)
* and if it doesn't work, we do some other stupid things. * and if it doesn't work, we do some other stupid things.
*/ */
static long no_idt[2] = {0, 0}; static long no_idt[2] = {0, 0};
static int reboot_mode = 0;
void reboot_setup(char *str, int *ints)
{
int mode = 0;
/* "w" for "warm" reboot (no memory testing etc) */
if (str[0] == 'w')
mode = 0x1234;
reboot_mode = mode;
}
static inline void kb_wait(void) static inline void kb_wait(void)
{ {
...@@ -197,16 +209,14 @@ void hard_reset_now(void) ...@@ -197,16 +209,14 @@ void hard_reset_now(void)
int i, j; int i, j;
sti(); sti();
/* rebooting needs to touch the page at absolute addr 0 */ *((unsigned short *)__va(0x472)) = reboot_mode;
pg0[0] = 7;
*((unsigned short *)0x472) = 0x1234;
for (;;) { for (;;) {
for (i=0; i<100; i++) { for (i=0; i<100; i++) {
kb_wait(); kb_wait();
for(j = 0; j < 100000 ; j++) for(j = 0; j < 100000 ; j++)
/* nothing */; /* nothing */;
outb(0xfe,0x64); /* pulse reset low */ outb(0xfe,0x64); /* pulse reset low */
udelay(10); udelay(100);
} }
__asm__ __volatile__("\tlidt %0": "=m" (no_idt)); __asm__ __volatile__("\tlidt %0": "=m" (no_idt));
} }
...@@ -307,6 +317,7 @@ void copy_thread(int nr, unsigned long clone_flags, unsigned long esp, ...@@ -307,6 +317,7 @@ void copy_thread(int nr, unsigned long clone_flags, unsigned long esp,
childregs = ((struct pt_regs *) (p->kernel_stack_page + PAGE_SIZE)) - 1; childregs = ((struct pt_regs *) (p->kernel_stack_page + PAGE_SIZE)) - 1;
p->tss.esp = (unsigned long) childregs; p->tss.esp = (unsigned long) childregs;
p->tss.eip = (unsigned long) ret_from_sys_call; p->tss.eip = (unsigned long) ret_from_sys_call;
p->tss.ebx = (unsigned long) p;
*childregs = *regs; *childregs = *regs;
childregs->eax = 0; childregs->eax = 0;
childregs->esp = esp; childregs->esp = esp;
......
...@@ -119,7 +119,7 @@ static unsigned long get_long(struct task_struct * tsk, ...@@ -119,7 +119,7 @@ static unsigned long get_long(struct task_struct * tsk,
} }
page = pte_page(*pgtable); page = pte_page(*pgtable);
/* this is a hack for non-kernel-mapped video buffers and similar */ /* this is a hack for non-kernel-mapped video buffers and similar */
if (page >= high_memory) if (MAP_NR(page) >= max_mapnr)
return 0; return 0;
page += addr & ~PAGE_MASK; page += addr & ~PAGE_MASK;
return *(unsigned long *) page; return *(unsigned long *) page;
...@@ -174,7 +174,7 @@ static void put_long(struct task_struct * tsk, struct vm_area_struct * vma, unsi ...@@ -174,7 +174,7 @@ static void put_long(struct task_struct * tsk, struct vm_area_struct * vma, unsi
goto repeat; goto repeat;
} }
/* this is a hack for non-kernel-mapped video buffers and similar */ /* this is a hack for non-kernel-mapped video buffers and similar */
if (page < high_memory) if (MAP_NR(page) < max_mapnr)
*(unsigned long *) (page + (addr & ~PAGE_MASK)) = data; *(unsigned long *) (page + (addr & ~PAGE_MASK)) = data;
/* we're bypassing pagetables, so we have to set the dirty bit ourselves */ /* we're bypassing pagetables, so we have to set the dirty bit ourselves */
/* this should also re-instate whatever read-only mode there was before */ /* this should also re-instate whatever read-only mode there was before */
......
...@@ -16,7 +16,6 @@ ...@@ -16,7 +16,6 @@
#include <linux/unistd.h> #include <linux/unistd.h>
#include <linux/ptrace.h> #include <linux/ptrace.h>
#include <linux/malloc.h> #include <linux/malloc.h>
#include <linux/ldt.h>
#include <linux/user.h> #include <linux/user.h>
#include <linux/a.out.h> #include <linux/a.out.h>
#include <linux/tty.h> #include <linux/tty.h>
...@@ -140,10 +139,10 @@ void setup_arch(char **cmdline_p, ...@@ -140,10 +139,10 @@ void setup_arch(char **cmdline_p,
if (!MOUNT_ROOT_RDONLY) if (!MOUNT_ROOT_RDONLY)
root_mountflags &= ~MS_RDONLY; root_mountflags &= ~MS_RDONLY;
memory_start = (unsigned long) &_end; memory_start = (unsigned long) &_end;
init_task.mm->start_code = TASK_SIZE; init_task.mm->start_code = PAGE_OFFSET;
init_task.mm->end_code = TASK_SIZE + (unsigned long) &_etext; init_task.mm->end_code = (unsigned long) &_etext;
init_task.mm->end_data = TASK_SIZE + (unsigned long) &_edata; init_task.mm->end_data = (unsigned long) &_edata;
init_task.mm->brk = TASK_SIZE + (unsigned long) &_end; init_task.mm->brk = (unsigned long) &_end;
/* Save unparsed command line copy for /proc/cmdline */ /* Save unparsed command line copy for /proc/cmdline */
memcpy(saved_command_line, COMMAND_LINE, COMMAND_LINE_SIZE); memcpy(saved_command_line, COMMAND_LINE, COMMAND_LINE_SIZE);
...@@ -180,13 +179,14 @@ void setup_arch(char **cmdline_p, ...@@ -180,13 +179,14 @@ void setup_arch(char **cmdline_p,
} }
*to = '\0'; *to = '\0';
*cmdline_p = command_line; *cmdline_p = command_line;
memory_end += PAGE_OFFSET;
*memory_start_p = memory_start; *memory_start_p = memory_start;
*memory_end_p = memory_end; *memory_end_p = memory_end;
#ifdef CONFIG_BLK_DEV_INITRD #ifdef CONFIG_BLK_DEV_INITRD
if (LOADER_TYPE) { if (LOADER_TYPE) {
initrd_start = INITRD_START; initrd_start = INITRD_START + PAGE_OFFSET;
initrd_end = INITRD_START+INITRD_SIZE; initrd_end = initrd_start+INITRD_SIZE;
if (initrd_end > memory_end) { if (initrd_end > memory_end) {
printk("initrd extends beyond end of memory " printk("initrd extends beyond end of memory "
"(0x%08lx > 0x%08lx)\ndisabling initrd\n", "(0x%08lx > 0x%08lx)\ndisabling initrd\n",
......
...@@ -197,7 +197,7 @@ static void setup_frame(struct sigaction * sa, ...@@ -197,7 +197,7 @@ static void setup_frame(struct sigaction * sa,
put_user(regs->eflags, frame+18); put_user(regs->eflags, frame+18);
put_user(regs->esp, frame+19); put_user(regs->esp, frame+19);
put_user(regs->ss, frame+20); put_user(regs->ss, frame+20);
put_user(save_i387((struct _fpstate *)(frame+32)),frame+21); put_user((unsigned long) save_i387((struct _fpstate *)(frame+32)),frame+21);
/* non-iBCS2 extensions.. */ /* non-iBCS2 extensions.. */
put_user(oldmask, frame+22); put_user(oldmask, frame+22);
put_user(current->tss.cr2, frame+23); put_user(current->tss.cr2, frame+23);
......
...@@ -67,7 +67,7 @@ int apic_version[NR_CPUS]; /* APIC version number */ ...@@ -67,7 +67,7 @@ int apic_version[NR_CPUS]; /* APIC version number */
static volatile int smp_commenced=0; /* Tripped when we start scheduling */ static volatile int smp_commenced=0; /* Tripped when we start scheduling */
unsigned long apic_addr=0xFEE00000; /* Address of APIC (defaults to 0xFEE00000) */ unsigned long apic_addr=0xFEE00000; /* Address of APIC (defaults to 0xFEE00000) */
unsigned long nlong = 0; /* dummy used for apic_reg address + 0x20 */ unsigned long nlong = 0; /* dummy used for apic_reg address + 0x20 */
unsigned char *apic_reg=((unsigned char *)(&nlong))-0x20;/* Later set to the vremap() of the APIC */ unsigned char *apic_reg=((unsigned char *)(&nlong))-0x20;/* Later set to the ioremap() of the APIC */
unsigned long apic_retval; /* Just debugging the assembler.. */ unsigned long apic_retval; /* Just debugging the assembler.. */
unsigned char *kernel_stacks[NR_CPUS]; /* Kernel stack pointers for CPU's (debugging) */ unsigned char *kernel_stacks[NR_CPUS]; /* Kernel stack pointers for CPU's (debugging) */
...@@ -619,7 +619,7 @@ void smp_boot_cpus(void) ...@@ -619,7 +619,7 @@ void smp_boot_cpus(void)
* Map the local APIC into kernel space * Map the local APIC into kernel space
*/ */
apic_reg = vremap(apic_addr,4096); apic_reg = ioremap(apic_addr,4096);
if(apic_reg == NULL) if(apic_reg == NULL)
panic("Unable to map local apic.\n"); panic("Unable to map local apic.\n");
......
...@@ -134,7 +134,8 @@ int kstack_depth_to_print = 24; ...@@ -134,7 +134,8 @@ int kstack_depth_to_print = 24;
printk("\nCall Trace: "); printk("\nCall Trace: ");
stack = (unsigned long *) esp; stack = (unsigned long *) esp;
i = 1; i = 1;
module_start = ((high_memory + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1)); module_start = PAGE_OFFSET + (max_mapnr << PAGE_SHIFT);
module_start = ((module_start + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1));
module_end = module_start + MODULE_RANGE; module_end = module_start + MODULE_RANGE;
while (((long) stack & 4095) != 0) { while (((long) stack & 4095) != 0) {
addr = get_seg_long(ss, stack++); addr = get_seg_long(ss, stack++);
...@@ -329,7 +330,7 @@ void trap_init(void) ...@@ -329,7 +330,7 @@ void trap_init(void)
return; return;
} }
smptrap++; smptrap++;
if (strncmp((char*)0x0FFFD9, "EISA", 4) == 0) if (strncmp((char*)phys_to_virt(0x0FFFD9), "EISA", 4) == 0)
EISA_bus = 1; EISA_bus = 1;
set_call_gate(&default_ldt,lcall7); set_call_gate(&default_ldt,lcall7);
set_trap_gate(0,&divide_error); set_trap_gate(0,&divide_error);
......
...@@ -102,10 +102,11 @@ static void mark_screen_rdonly(struct task_struct * tsk) ...@@ -102,10 +102,11 @@ static void mark_screen_rdonly(struct task_struct * tsk)
asmlinkage int sys_vm86(struct vm86_struct * v86) asmlinkage int sys_vm86(struct vm86_struct * v86)
{ {
struct vm86_struct info; struct vm86_struct info;
struct task_struct *tsk = current;
struct pt_regs * pt_regs = (struct pt_regs *) &v86; struct pt_regs * pt_regs = (struct pt_regs *) &v86;
int error; int error;
if (current->saved_kernel_stack) if (tsk->saved_kernel_stack)
return -EPERM; return -EPERM;
/* v86 must be readable (now) and writable (for save_v86_state) */ /* v86 must be readable (now) and writable (for save_v86_state) */
error = verify_area(VERIFY_WRITE,v86,sizeof(*v86)); error = verify_area(VERIFY_WRITE,v86,sizeof(*v86));
...@@ -131,16 +132,16 @@ asmlinkage int sys_vm86(struct vm86_struct * v86) ...@@ -131,16 +132,16 @@ asmlinkage int sys_vm86(struct vm86_struct * v86)
switch (info.cpu_type) { switch (info.cpu_type) {
case CPU_286: case CPU_286:
current->tss.v86mask = 0; tsk->tss.v86mask = 0;
break; break;
case CPU_386: case CPU_386:
current->tss.v86mask = NT_MASK | IOPL_MASK; tsk->tss.v86mask = NT_MASK | IOPL_MASK;
break; break;
case CPU_486: case CPU_486:
current->tss.v86mask = AC_MASK | NT_MASK | IOPL_MASK; tsk->tss.v86mask = AC_MASK | NT_MASK | IOPL_MASK;
break; break;
default: default:
current->tss.v86mask = ID_MASK | AC_MASK | NT_MASK | IOPL_MASK; tsk->tss.v86mask = ID_MASK | AC_MASK | NT_MASK | IOPL_MASK;
break; break;
} }
...@@ -148,17 +149,17 @@ asmlinkage int sys_vm86(struct vm86_struct * v86) ...@@ -148,17 +149,17 @@ asmlinkage int sys_vm86(struct vm86_struct * v86)
* Save old state, set default return value (%eax) to 0 * Save old state, set default return value (%eax) to 0
*/ */
pt_regs->eax = 0; pt_regs->eax = 0;
current->saved_kernel_stack = current->tss.esp0; tsk->saved_kernel_stack = tsk->tss.esp0;
current->tss.esp0 = (unsigned long) pt_regs; tsk->tss.esp0 = (unsigned long) pt_regs;
current->tss.vm86_info = v86; tsk->tss.vm86_info = v86;
current->tss.screen_bitmap = info.screen_bitmap; tsk->tss.screen_bitmap = info.screen_bitmap;
if (info.flags & VM86_SCREEN_BITMAP) if (info.flags & VM86_SCREEN_BITMAP)
mark_screen_rdonly(current); mark_screen_rdonly(tsk);
__asm__ __volatile__("movl %0,%%esp\n\t" __asm__ __volatile__("movl %0,%%esp\n\t"
"jmp ret_from_sys_call" "jmp ret_from_sys_call"
: /* no outputs */ : /* no outputs */
:"r" (&info.regs)); :"r" (&info.regs), "b" (tsk));
return 0; return 0;
} }
...@@ -170,7 +171,7 @@ static inline void return_to_32bit(struct vm86_regs * regs16, int retval) ...@@ -170,7 +171,7 @@ static inline void return_to_32bit(struct vm86_regs * regs16, int retval)
regs32->eax = retval; regs32->eax = retval;
__asm__ __volatile__("movl %0,%%esp\n\t" __asm__ __volatile__("movl %0,%%esp\n\t"
"jmp ret_from_sys_call" "jmp ret_from_sys_call"
: : "r" (regs32)); : : "r" (regs32), "b" (current));
} }
static inline void set_IF(struct vm86_regs * regs) static inline void set_IF(struct vm86_regs * regs)
......
...@@ -97,101 +97,6 @@ unsigned int csum_partial(const unsigned char * buff, int len, unsigned int sum) ...@@ -97,101 +97,6 @@ unsigned int csum_partial(const unsigned char * buff, int len, unsigned int sum)
/*
* copy from fs while checksumming, otherwise like csum_partial
*/
unsigned int csum_partial_copy_fromuser(const char *src, char *dst,
int len, int sum) {
__asm__("
testl $2, %%edi # Check alignment.
jz 2f # Jump if alignment is ok.
subl $2, %%ecx # Alignment uses up two bytes.
jae 1f # Jump if we had at least two bytes.
addl $2, %%ecx # ecx was < 2. Deal with it.
jmp 4f
1: movw %%fs:(%%esi), %%bx
addl $2, %%esi
movw %%bx, (%%edi)
addl $2, %%edi
addw %%bx, %%ax
adcl $0, %%eax
2:
movl %%ecx, %%edx
shrl $5, %%ecx
jz 2f
testl %%esi, %%esi
1: movl %%fs:(%%esi), %%ebx
adcl %%ebx, %%eax
movl %%ebx, (%%edi)
movl %%fs:4(%%esi), %%ebx
adcl %%ebx, %%eax
movl %%ebx, 4(%%edi)
movl %%fs:8(%%esi), %%ebx
adcl %%ebx, %%eax
movl %%ebx, 8(%%edi)
movl %%fs:12(%%esi), %%ebx
adcl %%ebx, %%eax
movl %%ebx, 12(%%edi)
movl %%fs:16(%%esi), %%ebx
adcl %%ebx, %%eax
movl %%ebx, 16(%%edi)
movl %%fs:20(%%esi), %%ebx
adcl %%ebx, %%eax
movl %%ebx, 20(%%edi)
movl %%fs:24(%%esi), %%ebx
adcl %%ebx, %%eax
movl %%ebx, 24(%%edi)
movl %%fs:28(%%esi), %%ebx
adcl %%ebx, %%eax
movl %%ebx, 28(%%edi)
lea 32(%%esi), %%esi
lea 32(%%edi), %%edi
dec %%ecx
jne 1b
adcl $0, %%eax
2: movl %%edx, %%ecx
andl $28, %%edx
je 4f
shrl $2, %%edx
testl %%esi, %%esi
3: movl %%fs:(%%esi), %%ebx
adcl %%ebx, %%eax
movl %%ebx, (%%edi)
lea 4(%%esi), %%esi
lea 4(%%edi), %%edi
dec %%edx
jne 3b
adcl $0, %%eax
4: andl $3, %%ecx
jz 7f
cmpl $2, %%ecx
jb 5f
movw %%fs:(%%esi), %%cx
leal 2(%%esi), %%esi
movw %%cx, (%%edi)
leal 2(%%edi), %%edi
je 6f
shll $16,%%ecx
5: movb %%fs:(%%esi), %%cl
movb %%cl, (%%edi)
6: addl %%ecx, %%eax
adcl $0, %%eax
7:
"
: "=a" (sum)
: "0"(sum), "c"(len), "S"(src), "D" (dst)
: "bx", "cx", "dx", "si", "di" );
return(sum);
}
/* /*
* copy from ds while checksumming, otherwise like csum_partial * copy from ds while checksumming, otherwise like csum_partial
*/ */
......
...@@ -97,9 +97,9 @@ extern char emulating; ...@@ -97,9 +97,9 @@ extern char emulating;
struct address { struct address {
unsigned int offset; unsigned int offset;
unsigned int selector:16; unsigned short selector;
unsigned int opcode:11; unsigned short opcode:11,
unsigned int empty:5; empty:5;
}; };
typedef void (*FUNC)(void); typedef void (*FUNC)(void);
typedef struct fpu_reg FPU_REG; typedef struct fpu_reg FPU_REG;
......
...@@ -8,6 +8,6 @@ ...@@ -8,6 +8,6 @@
# Note 2! The CFLAGS definition is now in the main makefile... # Note 2! The CFLAGS definition is now in the main makefile...
O_TARGET := mm.o O_TARGET := mm.o
O_OBJS := init.o fault.o O_OBJS := init.o fault.o ioremap.o
include $(TOPDIR)/Rules.make include $(TOPDIR)/Rules.make
...@@ -123,14 +123,14 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long error_code) ...@@ -123,14 +123,14 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long error_code)
* *
* First we check if it was the bootup rw-test, though.. * First we check if it was the bootup rw-test, though..
*/ */
if (wp_works_ok < 0 && address == TASK_SIZE && (error_code & 1)) { if (wp_works_ok < 0 && !address && (error_code & 1)) {
wp_works_ok = 1; wp_works_ok = 1;
pg0[0] = pte_val(mk_pte(0, PAGE_SHARED)); pg0[0] = pte_val(mk_pte(0, PAGE_SHARED));
flush_tlb(); flush_tlb();
printk("This processor honours the WP bit even when in supervisor mode. Good.\n"); printk("This processor honours the WP bit even when in supervisor mode. Good.\n");
return; return;
} }
if ((unsigned long) (address-TASK_SIZE) < PAGE_SIZE) { if (address < PAGE_SIZE) {
printk(KERN_ALERT "Unable to handle kernel NULL pointer dereference"); printk(KERN_ALERT "Unable to handle kernel NULL pointer dereference");
pg0[0] = pte_val(mk_pte(0, PAGE_SHARED)); pg0[0] = pte_val(mk_pte(0, PAGE_SHARED));
} else } else
...@@ -139,12 +139,12 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long error_code) ...@@ -139,12 +139,12 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long error_code)
__asm__("movl %%cr3,%0" : "=r" (page)); __asm__("movl %%cr3,%0" : "=r" (page));
printk(KERN_ALERT "current->tss.cr3 = %08lx, %%cr3 = %08lx\n", printk(KERN_ALERT "current->tss.cr3 = %08lx, %%cr3 = %08lx\n",
tsk->tss.cr3, page); tsk->tss.cr3, page);
page = ((unsigned long *) page)[address >> 22]; page = ((unsigned long *) __va(page))[address >> 22];
printk(KERN_ALERT "*pde = %08lx\n", page); printk(KERN_ALERT "*pde = %08lx\n", page);
if (page & 1) { if (page & 1) {
page &= PAGE_MASK; page &= PAGE_MASK;
address &= 0x003ff000; address &= 0x003ff000;
page = ((unsigned long *) page)[address >> PAGE_SHIFT]; page = ((unsigned long *) __va(page))[address >> PAGE_SHIFT];
printk(KERN_ALERT "*pte = %08lx\n", page); printk(KERN_ALERT "*pte = %08lx\n", page);
} }
die_if_kernel("Oops", regs, error_code); die_if_kernel("Oops", regs, error_code);
......
...@@ -81,7 +81,7 @@ void show_mem(void) ...@@ -81,7 +81,7 @@ void show_mem(void)
printk("Mem-info:\n"); printk("Mem-info:\n");
show_free_areas(); show_free_areas();
printk("Free swap: %6dkB\n",nr_swap_pages<<(PAGE_SHIFT-10)); printk("Free swap: %6dkB\n",nr_swap_pages<<(PAGE_SHIFT-10));
i = high_memory >> PAGE_SHIFT; i = max_mapnr;
while (i-- > 0) { while (i-- > 0) {
total++; total++;
if (PageReserved(mem_map+i)) if (PageReserved(mem_map+i))
...@@ -149,8 +149,10 @@ unsigned long paging_init(unsigned long start_mem, unsigned long end_mem) ...@@ -149,8 +149,10 @@ unsigned long paging_init(unsigned long start_mem, unsigned long end_mem)
wp_works_ok = 0; wp_works_ok = 0;
#endif #endif
start_mem = PAGE_ALIGN(start_mem); start_mem = PAGE_ALIGN(start_mem);
address = 0; address = PAGE_OFFSET;
pg_dir = swapper_pg_dir; pg_dir = swapper_pg_dir;
/* unmap the original low memory mappings */
pgd_val(pg_dir[0]) = 0;
while (address < end_mem) { while (address < end_mem) {
#ifdef USE_PENTIUM_MM #ifdef USE_PENTIUM_MM
/* /*
...@@ -172,29 +174,29 @@ unsigned long paging_init(unsigned long start_mem, unsigned long end_mem) ...@@ -172,29 +174,29 @@ unsigned long paging_init(unsigned long start_mem, unsigned long end_mem)
: : :"ax"); : : :"ax");
#endif #endif
wp_works_ok = 1; wp_works_ok = 1;
pgd_val(pg_dir[0]) = _PAGE_TABLE | _PAGE_4M | address; pgd_val(pg_dir[768]) = _PAGE_TABLE + _PAGE_4M + __pa(address);
pgd_val(pg_dir[768]) = _PAGE_TABLE | _PAGE_4M | address;
pg_dir++; pg_dir++;
address += 4*1024*1024; address += 4*1024*1024;
continue; continue;
} }
#endif #endif
/* map the memory at virtual addr 0xC0000000 */ /* map the memory at virtual addr 0xC0000000 */
/* pg_table is physical at this point */
pg_table = (pte_t *) (PAGE_MASK & pgd_val(pg_dir[768])); pg_table = (pte_t *) (PAGE_MASK & pgd_val(pg_dir[768]));
if (!pg_table) { if (!pg_table) {
pg_table = (pte_t *) start_mem; pg_table = (pte_t *) __pa(start_mem);
start_mem += PAGE_SIZE; start_mem += PAGE_SIZE;
} }
/* also map it temporarily at 0x0000000 for init */
pgd_val(pg_dir[0]) = _PAGE_TABLE | (unsigned long) pg_table;
pgd_val(pg_dir[768]) = _PAGE_TABLE | (unsigned long) pg_table; pgd_val(pg_dir[768]) = _PAGE_TABLE | (unsigned long) pg_table;
pg_dir++; pg_dir++;
/* now change pg_table to kernel virtual addresses */
pg_table = (pte_t *) __va(pg_table);
for (tmp = 0 ; tmp < PTRS_PER_PTE ; tmp++,pg_table++) { for (tmp = 0 ; tmp < PTRS_PER_PTE ; tmp++,pg_table++) {
if (address < end_mem) pte_t pte = mk_pte(address, PAGE_KERNEL);
set_pte(pg_table, mk_pte(address, PAGE_SHARED)); if (address >= end_mem)
else pte_val(pte) = 0;
pte_clear(pg_table); set_pte(pg_table, pte);
address += PAGE_SIZE; address += PAGE_SIZE;
} }
} }
...@@ -212,13 +214,14 @@ void mem_init(unsigned long start_mem, unsigned long end_mem) ...@@ -212,13 +214,14 @@ void mem_init(unsigned long start_mem, unsigned long end_mem)
extern int _etext; extern int _etext;
end_mem &= PAGE_MASK; end_mem &= PAGE_MASK;
high_memory = end_mem; high_memory = (void *) end_mem;
max_mapnr = MAP_NR(end_mem);
/* clear the zero-page */ /* clear the zero-page */
memset(empty_zero_page, 0, PAGE_SIZE); memset(empty_zero_page, 0, PAGE_SIZE);
/* mark usable pages in the mem_map[] */ /* mark usable pages in the mem_map[] */
start_low_mem = PAGE_ALIGN(start_low_mem); start_low_mem = PAGE_ALIGN(start_low_mem)+PAGE_OFFSET;
#ifdef __SMP__ #ifdef __SMP__
/* /*
...@@ -234,20 +237,20 @@ void mem_init(unsigned long start_mem, unsigned long end_mem) ...@@ -234,20 +237,20 @@ void mem_init(unsigned long start_mem, unsigned long end_mem)
* They seem to have done something stupid with the floppy * They seem to have done something stupid with the floppy
* controller as well.. * controller as well..
*/ */
while (start_low_mem < 0x9f000) { while (start_low_mem < 0x9f000+PAGE_OFFSET) {
clear_bit(PG_reserved, &mem_map[MAP_NR(start_low_mem)].flags); clear_bit(PG_reserved, &mem_map[MAP_NR(start_low_mem)].flags);
start_low_mem += PAGE_SIZE; start_low_mem += PAGE_SIZE;
} }
while (start_mem < high_memory) { while (start_mem < end_mem) {
clear_bit(PG_reserved, &mem_map[MAP_NR(start_mem)].flags); clear_bit(PG_reserved, &mem_map[MAP_NR(start_mem)].flags);
start_mem += PAGE_SIZE; start_mem += PAGE_SIZE;
} }
for (tmp = 0 ; tmp < high_memory ; tmp += PAGE_SIZE) { for (tmp = PAGE_OFFSET ; tmp < end_mem ; tmp += PAGE_SIZE) {
if (tmp >= MAX_DMA_ADDRESS) if (tmp >= MAX_DMA_ADDRESS)
clear_bit(PG_DMA, &mem_map[MAP_NR(tmp)].flags); clear_bit(PG_DMA, &mem_map[MAP_NR(tmp)].flags);
if (PageReserved(mem_map+MAP_NR(tmp))) { if (PageReserved(mem_map+MAP_NR(tmp))) {
if (tmp >= 0xA0000 && tmp < 0x100000) if (tmp >= 0xA0000+PAGE_OFFSET && tmp < 0x100000+PAGE_OFFSET)
reservedpages++; reservedpages++;
else if (tmp < (unsigned long) &_etext) else if (tmp < (unsigned long) &_etext)
codepages++; codepages++;
...@@ -262,19 +265,24 @@ void mem_init(unsigned long start_mem, unsigned long end_mem) ...@@ -262,19 +265,24 @@ void mem_init(unsigned long start_mem, unsigned long end_mem)
#endif #endif
free_page(tmp); free_page(tmp);
} }
tmp = nr_free_pages << PAGE_SHIFT;
printk("Memory: %luk/%luk available (%dk kernel code, %dk reserved, %dk data)\n", printk("Memory: %luk/%luk available (%dk kernel code, %dk reserved, %dk data)\n",
tmp >> 10, (unsigned long) nr_free_pages << (PAGE_SHIFT-10),
high_memory >> 10, max_mapnr << (PAGE_SHIFT-10),
codepages << (PAGE_SHIFT-10), codepages << (PAGE_SHIFT-10),
reservedpages << (PAGE_SHIFT-10), reservedpages << (PAGE_SHIFT-10),
datapages << (PAGE_SHIFT-10)); datapages << (PAGE_SHIFT-10));
/* test if the WP bit is honoured in supervisor mode */ /* test if the WP bit is honoured in supervisor mode */
if (wp_works_ok < 0) { if (wp_works_ok < 0) {
pg0[0] = pte_val(mk_pte(0, PAGE_READONLY)); unsigned char tmp_reg;
pg0[0] = pte_val(mk_pte(PAGE_OFFSET, PAGE_READONLY));
local_flush_tlb(); local_flush_tlb();
__asm__ __volatile__("movb 0,%%al ; movb %%al,0": : :"ax", "memory"); __asm__ __volatile__(
pg0[0] = 0; "movb %0,%1 ; movb %1,%0"
:"=m" (*(char *) __va(0)),
"=q" (tmp_reg)
:/* no inputs */
:"memory");
pg0[0] = pte_val(mk_pte(PAGE_OFFSET, PAGE_KERNEL));
local_flush_tlb(); local_flush_tlb();
if (wp_works_ok < 0) if (wp_works_ok < 0)
wp_works_ok = 0; wp_works_ok = 0;
...@@ -286,7 +294,7 @@ void si_meminfo(struct sysinfo *val) ...@@ -286,7 +294,7 @@ void si_meminfo(struct sysinfo *val)
{ {
int i; int i;
i = high_memory >> PAGE_SHIFT; i = max_mapnr;
val->totalram = 0; val->totalram = 0;
val->sharedram = 0; val->sharedram = 0;
val->freeram = nr_free_pages << PAGE_SHIFT; val->freeram = nr_free_pages << PAGE_SHIFT;
......
/*
* arch/i386/mm/ioremap.c
*
* Re-map IO memory to kernel address space so that we can access it.
* This is needed for high PCI addresses that aren't mapped in the
* 640k-1MB IO memory area on PC's
*
* (C) Copyright 1995 1996 Linus Torvalds
*/
#include <linux/vmalloc.h>
#include <asm/io.h>
static inline void remap_area_pte(pte_t * pte, unsigned long address, unsigned long size,
unsigned long phys_addr)
{
unsigned long end;
address &= ~PMD_MASK;
end = address + size;
if (end > PMD_SIZE)
end = PMD_SIZE;
do {
if (!pte_none(*pte))
printk("remap_area_pte: page already exists\n");
set_pte(pte, mk_pte_phys(phys_addr, PAGE_KERNEL));
address += PAGE_SIZE;
phys_addr += PAGE_SIZE;
pte++;
} while (address < end);
}
static inline int remap_area_pmd(pmd_t * pmd, unsigned long address, unsigned long size,
unsigned long phys_addr)
{
unsigned long end;
address &= ~PGDIR_MASK;
end = address + size;
if (end > PGDIR_SIZE)
end = PGDIR_SIZE;
phys_addr -= address;
do {
pte_t * pte = pte_alloc_kernel(pmd, address);
if (!pte)
return -ENOMEM;
remap_area_pte(pte, address, end - address, address + phys_addr);
address = (address + PMD_SIZE) & PMD_MASK;
pmd++;
} while (address < end);
return 0;
}
static int remap_area_pages(unsigned long address, unsigned long phys_addr, unsigned long size)
{
pgd_t * dir;
unsigned long end = address + size;
phys_addr -= address;
dir = pgd_offset(&init_mm, address);
flush_cache_all();
while (address < end) {
pmd_t *pmd = pmd_alloc_kernel(dir, address);
if (!pmd)
return -ENOMEM;
if (remap_area_pmd(pmd, address, end - address, phys_addr + address))
return -ENOMEM;
set_pgdir(address, *dir);
address = (address + PGDIR_SIZE) & PGDIR_MASK;
dir++;
}
flush_tlb_all();
return 0;
}
/*
* Remap an arbitrary physical address space into the kernel virtual
* address space. Needed when the kernel wants to access high addresses
* directly.
*/
void * ioremap(unsigned long phys_addr, unsigned long size)
{
void * addr;
struct vm_struct * area;
if (phys_addr < virt_to_phys(high_memory))
return phys_to_virt(phys_addr);
if (phys_addr & ~PAGE_MASK)
return NULL;
size = PAGE_ALIGN(size);
if (!size || size > phys_addr + size)
return NULL;
area = get_vm_area(size);
if (!area)
return NULL;
addr = area->addr;
if (remap_area_pages(VMALLOC_VMADDR(addr), phys_addr, size)) {
vfree(addr);
return NULL;
}
return addr;
}
void iounmap(void *addr)
{
if (addr > high_memory)
return vfree(addr);
}
...@@ -21,7 +21,7 @@ CC := $(CC) ...@@ -21,7 +21,7 @@ CC := $(CC)
# set up for cross compiling # set up for cross compiling
COMPILE_ARCH = $(shell uname -m) COMPILE_ARCH = $(shell uname -m)
ifneq ($(COMPILE_ARCH),$(ARCH)) ifneq ($(COMPILE_ARCH),$(ARCH))
CROSSDIR=/usr/$(ARCH)-linux CROSSDIR=/usr/$(ARCH)-linux/bin
CC := $(CROSSDIR)/$(CC) CC := $(CROSSDIR)/$(CC)
AS := $(CROSSDIR)/$(AS) AS := $(CROSSDIR)/$(AS)
LD := $(CROSSDIR)/$(LD) LD := $(CROSSDIR)/$(LD)
...@@ -50,12 +50,16 @@ LINKFLAGS = -Ttext 0x1000 ...@@ -50,12 +50,16 @@ LINKFLAGS = -Ttext 0x1000
else else
LINKFLAGS = -qmagic -Ttext 0xFE0 LINKFLAGS = -qmagic -Ttext 0xFE0
endif endif
CFLAGS := $(CFLAGS) -pipe CFLAGS := $(CFLAGS) -pipe
ifdef CONFIG_OPTIMIZE_040
CFLAGS := $(CFLAGS) -m68040
endif
HEAD := arch/m68k/kernel/head.o HEAD := arch/m68k/kernel/head.o
SUBDIRS += arch/m68k/kernel arch/m68k/mm arch/m68k/console arch/m68k/lib SUBDIRS += arch/m68k/kernel arch/m68k/mm arch/m68k/console arch/m68k/lib
#SUBDIRS += arch/m68k/kernel arch/m68k/mm arch/m68k/lib
ARCHIVES := arch/m68k/kernel/kernel.o arch/m68k/mm/mm.o $(ARCHIVES) ARCHIVES := arch/m68k/kernel/kernel.o arch/m68k/mm/mm.o $(ARCHIVES)
LIBS += arch/m68k/lib/lib.a LIBS += arch/m68k/lib/lib.a
...@@ -77,12 +81,12 @@ endif ...@@ -77,12 +81,12 @@ endif
# add in console.a after {amiga,atari}.o that need it # add in console.a after {amiga,atari}.o that need it
ARCHIVES := $(ARCHIVES) arch/m68k/console/console.a ARCHIVES := $(ARCHIVES) arch/m68k/console/console.a
ifdef CONFIG_FPSP_040 ifdef CONFIG_M68040
ARCHIVES := $(ARCHIVES) arch/m68k/fpsp040/fpsp.o ARCHIVES := $(ARCHIVES) arch/m68k/fpsp040/fpsp.o
SUBDIRS := $(SUBDIRS) arch/m68k/fpsp040 SUBDIRS := $(SUBDIRS) arch/m68k/fpsp040
endif endif
ifdef CONFIG_IFPSP_060 ifdef CONFIG_M68060
ARCHIVES := $(ARCHIVES) arch/m68k/ifpsp060/ifpsp.o ARCHIVES := $(ARCHIVES) arch/m68k/ifpsp060/ifpsp.o
SUBDIRS := $(SUBDIRS) arch/m68k/ifpsp060 SUBDIRS := $(SUBDIRS) arch/m68k/ifpsp060
endif endif
......
#
# m68k/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
# for "archclean" and "archdep" for cleaning up and making dependencies for
# this architecture
#
# This file is subject to the terms and conditions of the GNU General Public
# License. See the file "COPYING" in the main directory of this archive
# for more details.
#
# Copyright (C) 1994 by Hamish Macdonald
#
# override top level makefile
AS = as -m68020
#CC := $(CC) -b m68kelf
LD = ld -m m68kelf
#
# Set these to indicate how to link it..
#
# -zmagic:
#
# LINKFLAGS = -Ttext 0x100000
#
# -qmagic (we need to remove the 32 byte header for bootup purposes)
#
LINKFLAGS = -qmagic -Ttext 0xFE0
HEAD := arch/m68k/kernel/head.o
SUBDIRS := $(SUBDIRS) arch/m68k/kernel arch/m68k/mm arch/m68k/lib
ARCHIVES := arch/m68k/kernel/kernel.o arch/m68k/mm/mm.o $(ARCHIVES)
LIBS := $(TOPDIR)/arch/m68k/lib/lib.a $(LIBS) $(TOPDIR)/arch/m68k/lib/lib.a
ifdef CONFIG_AMIGA
ARCHIVES := $(ARCHIVES) arch/m68k/amiga/amiga.o
SUBDIRS := $(SUBDIRS) arch/m68k/amiga
endif
ifdef CONFIG_ATARI
ARCHIVES := $(ARCHIVES) arch/m68k/atari/atari.o
SUBDIRS := $(SUBDIRS) arch/m68k/atari
endif
ifdef CONFIG_MAC
ARCHIVES := $(ARCHIVES) arch/m68k/mac/mac.o
SUBDIRS := $(SUBDIRS) arch/m68k/mac
endif
ifdef CONFIG_FPSP_040
ARCHIVES := $(ARCHIVES) arch/m68k/fpsp040/fpsp.o
SUBDIRS := $(SUBDIRS) arch/m68k/fpsp040
endif
arch/m68k/kernel: dummy
$(MAKE) linuxsubdirs SUBDIRS=arch/m68k/kernel
arch/m68k/mm: dummy
$(MAKE) linuxsubdirs SUBDIRS=arch/m68k/mm
arch/m68k/lib: dummy
$(MAKE) linuxsubdirs SUBDIRS=arch/m68k/lib
arch/m68k/amiga: dummy
$(MAKE) linuxsubdirs SUBDIRS=arch/m68k/amiga
arch/m68k/atari: dummy
$(MAKE) linuxsubdirs SUBDIRS=arch/m68k/atari
MAKEBOOT = $(MAKE) -C arch/$(ARCH)/boot
lilo: vmlinux
if [ -f $(INSTALL_PATH)/vmlinux ]; then mv -f $(INSTALL_PATH)/vmlinux $(INSTALL_PATH)/vmlinux.old; fi
if [ -f $(INSTALL_PATH)/System.map ]; then mv -f $(INSTALL_PATH)/System.map $(INSTALL_PATH)/System.old; fi
cat vmlinux > $(INSTALL_PATH)/vmlinux
cp System.map $(INSTALL_PATH)/System.map
if [ -x /sbin/lilo ]; then /sbin/lilo; else /etc/lilo/install; fi
bootstrap:
@$(MAKEBOOT) bootstrap
archclean:
@$(MAKEBOOT) clean
archdep:
$(MAKEBOOT) dep
...@@ -8,9 +8,8 @@ ...@@ -8,9 +8,8 @@
# Note 2! The CFLAGS definitions are now in the main makefile... # Note 2! The CFLAGS definitions are now in the main makefile...
O_TARGET := amiga.o O_TARGET := amiga.o
O_OBJS := config.o amikeyb.o amiints.o \ O_OBJS := config.o amikeyb.o amiints.o cia.o \
chipram.o amisound.o amifb.o zorro.o chipram.o amisound.o amifb.o zorro.o ksyms.o
OX_OBJS = ksyms.o
ifdef CONFIG_FB_CYBER ifdef CONFIG_FB_CYBER
O_OBJS := $(O_OBJS) cyberfb.o O_OBJS := $(O_OBJS) cyberfb.o
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
/* /*
* linux/amiga/amisound.c * linux/arch/m68k/amiga/amisound.c
* *
* amiga sound driver for 680x0 Linux * amiga sound driver for Linux/m68k
* *
* This file is subject to the terms and conditions of the GNU General Public * This file is subject to the terms and conditions of the GNU General Public
* License. See the file COPYING in the main directory of this archive * License. See the file COPYING in the main directory of this archive
...@@ -11,9 +11,9 @@ ...@@ -11,9 +11,9 @@
#include <linux/sched.h> #include <linux/sched.h>
#include <linux/timer.h> #include <linux/timer.h>
#include <asm/amigatypes.h>
#include <asm/system.h> #include <asm/system.h>
#include <asm/amigahw.h> #include <asm/amigahw.h>
#include <asm/bootinfo.h>
static u_short *snd_data = NULL; static u_short *snd_data = NULL;
static const signed char sine_data[] = { static const signed char sine_data[] = {
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
#include <linux/types.h> #include <linux/types.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <asm/bootinfo.h> #include <asm/setup.h>
#include <asm/amigahw.h> #include <asm/amigahw.h>
struct chip_desc { struct chip_desc {
...@@ -22,6 +22,17 @@ struct chip_desc { ...@@ -22,6 +22,17 @@ struct chip_desc {
#define DP(ptr) ((struct chip_desc *)(ptr)) #define DP(ptr) ((struct chip_desc *)(ptr))
static unsigned long chipsize; static unsigned long chipsize;
static unsigned long chipavail; /*MILAN*/
/*MILAN*/
unsigned long amiga_chip_avail( void )
{
#ifdef DEBUG
printk("chip_avail : %ld bytes\n",chipavail);
#endif
return chipavail;
}
void amiga_chip_init (void) void amiga_chip_init (void)
{ {
...@@ -46,6 +57,7 @@ void amiga_chip_init (void) ...@@ -46,6 +57,7 @@ void amiga_chip_init (void)
dp->alloced = 0; dp->alloced = 0;
dp->length = chipsize - 2*sizeof(*dp); dp->length = chipsize - 2*sizeof(*dp);
chipavail = dp->length; /*MILAN*/
#ifdef DEBUG #ifdef DEBUG
printk ("chipram end boundary is %p, length is %d\n", dp, printk ("chipram end boundary is %p, length is %d\n", dp,
...@@ -63,7 +75,7 @@ void *amiga_chip_alloc (long size) ...@@ -63,7 +75,7 @@ void *amiga_chip_alloc (long size)
size = (size + 7) & ~7; size = (size + 7) & ~7;
#ifdef DEBUG #ifdef DEBUG
printk ("chip_alloc: allocate %ld bytes\n", size); printk("chip_alloc: allocate %ld bytes\n", size);
#endif #endif
/* /*
...@@ -121,7 +133,9 @@ void *amiga_chip_alloc (long size) ...@@ -121,7 +133,9 @@ void *amiga_chip_alloc (long size)
if ((unsigned long)ptr & 7) if ((unsigned long)ptr & 7)
panic("chip_alloc: alignment violation\n"); panic("chip_alloc: alignment violation\n");
return ptr; chipavail -= size + (2*sizeof(*dp)); /*MILAN*/
return ptr;
} }
void amiga_chip_free (void *ptr) void amiga_chip_free (void *ptr)
...@@ -129,6 +143,10 @@ void amiga_chip_free (void *ptr) ...@@ -129,6 +143,10 @@ void amiga_chip_free (void *ptr)
struct chip_desc *sdp = DP(ptr) - 1, *dp2; struct chip_desc *sdp = DP(ptr) - 1, *dp2;
struct chip_desc *edp = DP((unsigned long)ptr + sdp->length); struct chip_desc *edp = DP((unsigned long)ptr + sdp->length);
chipavail += sdp->length + (2* sizeof(sdp)); /*MILAN*/
#ifdef DEBUG
printk("chip_free: free %ld bytes at %p\n",sdp->length,ptr);
#endif
/* deallocate the chunk */ /* deallocate the chunk */
sdp->alloced = edp->alloced = 0; sdp->alloced = edp->alloced = 0;
......
/*
* linux/arch/m68k/amiga/cia.c - CIA support
*
* Copyright (C) 1996 Roman Zippel
*
* The concept of some functions bases on the original Amiga OS function
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file COPYING in the main directory of this archive
* for more details.
*/
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/errno.h>
#include <linux/kernel_stat.h>
#include <asm/irq.h>
#include <asm/amigahw.h>
#include <asm/amigaints.h>
struct ciabase {
volatile struct CIA *cia;
u_char icr_mask, icr_data;
u_short int_mask;
int handler_irq, cia_irq, server_irq;
char *name;
struct irq_server server;
irq_handler_t irq_list[CIA_IRQS];
} ciaa_base = {
&ciaa, 0, 0, IF_PORTS,
IRQ2, IRQ_AMIGA_CIAA,
IRQ_IDX(IRQ_AMIGA_PORTS),
"CIAA handler", {0, 0}
}, ciab_base = {
&ciab, 0, 0, IF_EXTER,
IRQ6, IRQ_AMIGA_CIAB,
IRQ_IDX(IRQ_AMIGA_EXTER),
"CIAB handler", {0, 0}
};
/*
* Cause or clear CIA interrupts, return old interrupt status.
*/
unsigned char cia_set_irq(struct ciabase *base, unsigned char mask)
{
u_char old;
old = (base->icr_data |= base->cia->icr);
if (mask & CIA_ICR_SETCLR)
base->icr_data |= mask;
else
base->icr_data &= ~mask;
if (base->icr_data & base->icr_mask)
custom.intreq = IF_SETCLR | base->int_mask;
return (old & base->icr_mask);
}
/*
* Enable or disable CIA interrupts, return old interrupt mask,
* interrupts will only be enabled if a handler exists
*/
unsigned char cia_able_irq(struct ciabase *base, unsigned char mask)
{
u_char old, tmp;
int i;
old = base->icr_mask;
base->icr_data |= base->cia->icr;
base->cia->icr = mask;
if (mask & CIA_ICR_SETCLR)
base->icr_mask |= mask;
else
base->icr_mask &= ~mask;
base->icr_mask &= CIA_ICR_ALL;
for (i = 0, tmp = 1; i < CIA_IRQS; i++, tmp <<= 1) {
if ((tmp & base->icr_mask) && !base->irq_list[i].handler)
base->icr_mask &= ~tmp;
}
if (base->icr_data & base->icr_mask)
custom.intreq = IF_SETCLR | base->int_mask;
return (old);
}
int cia_request_irq(struct ciabase *base, unsigned int irq,
void (*handler)(int, void *, struct pt_regs *),
unsigned long flags, const char *devname, void *dev_id)
{
u_char mask;
if (!(base->irq_list[irq].flags & IRQ_FLG_STD)) {
if (base->irq_list[irq].flags & IRQ_FLG_LOCK) {
printk("%s: IRQ %ld from %s is not replaceable\n",
__FUNCTION__, IRQ_IDX(base->cia_irq + irq),
base->irq_list[irq].devname);
return -EBUSY;
}
if (flags & IRQ_FLG_REPLACE) {
printk("%s: %s can't replace IRQ %ld from %s\n", __FUNCTION__,
devname, IRQ_IDX(base->cia_irq + irq),
base->irq_list[irq].devname);
return -EBUSY;
}
}
base->irq_list[irq].handler = handler;
base->irq_list[irq].flags = flags;
base->irq_list[irq].dev_id = dev_id;
base->irq_list[irq].devname = devname;
/* enable the interrupt */
mask = 1 << irq;
cia_set_irq(base, mask);
cia_able_irq(base, CIA_ICR_SETCLR | mask);
return 0;
}
void cia_free_irq(struct ciabase *base, unsigned int irq, void *dev_id)
{
if (base->irq_list[irq].dev_id != dev_id)
printk("%s: removing probably wrong IRQ %ld from %s\n",
__FUNCTION__, IRQ_IDX(base->cia_irq + irq),
base->irq_list[irq].devname);
base->irq_list[irq].handler = NULL;
base->irq_list[irq].flags = IRQ_FLG_STD;
cia_able_irq(base, 1 << irq);
}
static void cia_handler(int irq, void *dev_id, struct pt_regs *fp)
{
struct ciabase *base = (struct ciabase *)dev_id;
int mach_irq, i;
unsigned char ints;
mach_irq = base->cia_irq;
irq = SYS_IRQS + IRQ_IDX(mach_irq);
ints = cia_set_irq(base, CIA_ICR_ALL);
custom.intreq = base->int_mask;
for (i = 0; i < CIA_IRQS; i++, irq++, mach_irq++) {
if (ints & 1) {
kstat.interrupts[irq]++;
base->irq_list[i].handler(mach_irq, base->irq_list[i].dev_id, fp);
}
ints >>= 1;
}
amiga_do_irq_list(base->server_irq, fp, &base->server);
}
void cia_init_IRQ(struct ciabase *base)
{
int i;
/* init isr handlers */
for (i = 0; i < CIA_IRQS; i++) {
base->irq_list[i].handler = NULL;
base->irq_list[i].flags = IRQ_FLG_STD;
}
/* clear any pending interrupt and turn off all interrupts */
cia_set_irq(base, CIA_ICR_ALL);
cia_able_irq(base, CIA_ICR_ALL);
/* install CIA handler */
request_irq(base->handler_irq, cia_handler, IRQ_FLG_LOCK, base->name, base);
custom.intena = IF_SETCLR | base->int_mask;
}
int cia_get_irq_list(struct ciabase *base, char *buf)
{
int i, j, len = 0;
j = IRQ_IDX(base->cia_irq);
for (i = 0; i < CIA_IRQS; i++) {
if (!(base->irq_list[i].flags & IRQ_FLG_STD)) {
len += sprintf(buf+len, "cia %2d: %10d ", j + i,
kstat.interrupts[SYS_IRQS + j + i]);
if (base->irq_list[i].flags & IRQ_FLG_LOCK)
len += sprintf(buf+len, "L ");
else
len += sprintf(buf+len, " ");
len += sprintf(buf+len, "%s\n", base->irq_list[i].devname);
}
}
return len;
}
/* /*
* linux/amiga/config.c * linux/arch/m68k/amiga/config.c
* *
* Copyright (C) 1993 Hamish Macdonald * Copyright (C) 1993 Hamish Macdonald
* *
...@@ -20,11 +20,10 @@ ...@@ -20,11 +20,10 @@
#include <linux/kd.h> #include <linux/kd.h>
#include <linux/tty.h> #include <linux/tty.h>
#include <linux/console.h> #include <linux/console.h>
#include <linux/linkage.h>
#include <asm/setup.h>
#include <asm/system.h> #include <asm/system.h>
#include <asm/pgtable.h> #include <asm/pgtable.h>
#include <asm/bootinfo.h>
#include <asm/amigahw.h> #include <asm/amigahw.h>
#include <asm/amigaints.h> #include <asm/amigaints.h>
#include <asm/irq.h> #include <asm/irq.h>
...@@ -35,15 +34,20 @@ u_long amiga_colorclock; ...@@ -35,15 +34,20 @@ u_long amiga_colorclock;
extern char m68k_debug_device[]; extern char m68k_debug_device[];
extern void amiga_sched_init(isrfunc handler); extern void amiga_sched_init(void (*handler)(int, void *, struct pt_regs *));
/* amiga specific keyboard functions */
extern int amiga_keyb_init(void); extern int amiga_keyb_init(void);
extern int amiga_kbdrate (struct kbd_repeat *); extern int amiga_kbdrate (struct kbd_repeat *);
extern void amiga_init_INTS (void); /* amiga specific irq functions */
extern int amiga_add_isr (unsigned long, isrfunc, int, void *, char *); extern void amiga_init_IRQ (void);
extern int amiga_remove_isr (unsigned long, isrfunc, void *); extern void (*amiga_default_handler[]) (int, void *, struct pt_regs *);
extern int amiga_get_irq_list (char *, int); extern int amiga_request_irq (unsigned int irq, void (*handler)(int, void *, struct pt_regs *),
extern void amiga_enable_irq(unsigned int); unsigned long flags, const char *devname, void *dev_id);
extern void amiga_disable_irq(unsigned int); extern int amiga_free_irq (unsigned int irq, void *dev_id);
extern void amiga_enable_irq (unsigned int);
extern void amiga_disable_irq (unsigned int);
extern int amiga_get_irq_list (char *);
/* amiga specific timer functions */
extern unsigned long amiga_gettimeoffset (void); extern unsigned long amiga_gettimeoffset (void);
extern void a3000_gettod (int *, int *, int *, int *, int *, int *); extern void a3000_gettod (int *, int *, int *, int *, int *, int *);
extern void a2000_gettod (int *, int *, int *, int *, int *, int *); extern void a2000_gettod (int *, int *, int *, int *, int *, int *);
...@@ -199,7 +203,7 @@ void config_amiga(void) ...@@ -199,7 +203,7 @@ void config_amiga(void)
switch (custom.deniseid & 0xf) { switch (custom.deniseid & 0xf) {
case 0x0c: case 0x0c:
AMIGAHW_SET(DENISE_HR); AMIGAHW_SET(DENISE_HR);
printk("DENISE_HR"); printk("DENISE_HR ");
break; break;
case 0x08: case 0x08:
AMIGAHW_SET(LISA); AMIGAHW_SET(LISA);
...@@ -257,9 +261,10 @@ void config_amiga(void) ...@@ -257,9 +261,10 @@ void config_amiga(void)
mach_sched_init = amiga_sched_init; mach_sched_init = amiga_sched_init;
mach_keyb_init = amiga_keyb_init; mach_keyb_init = amiga_keyb_init;
mach_kbdrate = amiga_kbdrate; mach_kbdrate = amiga_kbdrate;
mach_init_INTS = amiga_init_INTS; mach_init_IRQ = amiga_init_IRQ;
mach_add_isr = amiga_add_isr; mach_default_handler = &amiga_default_handler;
mach_remove_isr = amiga_remove_isr; mach_request_irq = amiga_request_irq;
mach_free_irq = amiga_free_irq;
mach_enable_irq = amiga_enable_irq; mach_enable_irq = amiga_enable_irq;
mach_disable_irq = amiga_disable_irq; mach_disable_irq = amiga_disable_irq;
mach_get_irq_list = amiga_get_irq_list; mach_get_irq_list = amiga_get_irq_list;
...@@ -330,60 +335,24 @@ void config_amiga(void) ...@@ -330,60 +335,24 @@ void config_amiga(void)
#endif /* CONFIG_ZORRO */ #endif /* CONFIG_ZORRO */
} }
extern long time_finetune; /* from kernel/sched.c */
static unsigned short jiffy_ticks; static unsigned short jiffy_ticks;
#if 1 /* ++1.3++ */ void amiga_sched_init(void (*timer_routine)(int, void *, struct pt_regs *))
static void timer_wrapper( int irq, struct pt_regs *fp, void *otimerf )
{
unsigned short flags, old_flags;
ciab.icr = 0x01;
save_flags(flags);
old_flags = (flags & ~0x0700) | (fp->sr & 0x0700);
restore_flags(old_flags);
(*(isrfunc)otimerf)( irq, fp, NULL );
restore_flags(flags);
ciab.icr = 0x81;
}
#endif
void amiga_sched_init (isrfunc timer_routine)
{ {
jiffy_ticks = (amiga_eclock+HZ/2)/HZ;
#if 0 /* XXX */ /* I think finetune was removed by the 1.3.29 patch */
double finetune; ciab.cra &= 0xC0; /* turn off timer A, continuous mode, from Eclk */
#endif ciab.talo = jiffy_ticks % 256;
ciab.tahi = jiffy_ticks / 256;
jiffy_ticks = (amiga_eclock+50)/100;
#if 0 /* XXX */ /* install interrupt service routine for CIAB Timer A
finetune = (jiffy_ticks-amiga_eclock/HZ)/amiga_eclock*1000000*(1<<24); *
time_finetune = finetune+0.5; * Please don't change this to use ciaa, as it interferes with the
#endif * SCSI code. We'll have to take a look at this later
*/
ciab.cra &= 0xC0; /* turn off timer A, continuous mode, from Eclk */ request_irq(IRQ_AMIGA_CIAB_TA, timer_routine, IRQ_FLG_LOCK, "timer", NULL);
ciab.talo = jiffy_ticks % 256; /* start timer */
ciab.tahi = jiffy_ticks / 256; ciab.cra |= 0x11;
/* CIA interrupts when counter underflows, so adjust ticks by 1 */
jiffy_ticks -= 1;
/* install interrupt service routine for CIAB Timer A */
/*
* Please don't change this to use ciaa, as it interferes with the
* SCSI code. We'll have to take a look at this later
*/
#if 0
add_isr (IRQ_AMIGA_CIAB_TA, timer_routine, 0, NULL, "timer");
#else
add_isr (IRQ_AMIGA_CIAB_TA, timer_wrapper, 0, timer_routine, "timer");
#endif
/* start timer */
ciab.cra |= 0x01;
} }
#define TICK_SIZE 10000 #define TICK_SIZE 10000
...@@ -391,33 +360,30 @@ void amiga_sched_init (isrfunc timer_routine) ...@@ -391,33 +360,30 @@ void amiga_sched_init (isrfunc timer_routine)
/* This is always executed with interrupts disabled. */ /* This is always executed with interrupts disabled. */
unsigned long amiga_gettimeoffset (void) unsigned long amiga_gettimeoffset (void)
{ {
unsigned short hi, lo, hi2; unsigned short hi, lo, hi2;
unsigned long ticks, offset = 0; unsigned long ticks, offset = 0;
/* read CIA A timer A current value */ /* read CIA B timer A current value */
hi = ciab.tahi; hi = ciab.tahi;
lo = ciab.talo; lo = ciab.talo;
hi2 = ciab.tahi; hi2 = ciab.tahi;
if (hi != hi2) { if (hi != hi2) {
lo = ciab.talo; lo = ciab.talo;
hi = hi2; hi = hi2;
} }
ticks = hi << 8 | lo; ticks = hi << 8 | lo;
#if 0 /* XXX */ if (ticks > jiffy_ticks / 2)
/* reading the ICR clears all interrupts. bad idea! */ /* check for pending interrupt */
if (ticks > jiffy_ticks - jiffy_ticks / 100) if (cia_set_irq(&ciab_base, 0) & CIA_ICR_TA)
/* check for pending interrupt */ offset = 10000;
if (ciab.icr & CIA_ICR_TA)
offset = 10000;
#endif
ticks = (jiffy_ticks-1) - ticks; ticks = jiffy_ticks - ticks;
ticks = (10000 * ticks) / jiffy_ticks; ticks = (10000 * ticks) / jiffy_ticks;
return ticks + offset; return ticks + offset;
} }
void a3000_gettod (int *yearp, int *monp, int *dayp, void a3000_gettod (int *yearp, int *monp, int *dayp,
...@@ -657,7 +623,7 @@ void amiga_reset (void) ...@@ -657,7 +623,7 @@ void amiga_reset (void)
unsigned long jmp_addr = VTOP(&&jmp_addr_label); unsigned long jmp_addr = VTOP(&&jmp_addr_label);
cli(); cli();
if (m68k_is040or060) if (CPU_IS_040_OR_060)
/* Setup transparent translation registers for mapping /* Setup transparent translation registers for mapping
* of 16 MB kernel segment before disabling translation * of 16 MB kernel segment before disabling translation
*/ */
......
...@@ -29,11 +29,9 @@ ...@@ -29,11 +29,9 @@
#include <linux/tty.h> #include <linux/tty.h>
#include <linux/malloc.h> #include <linux/malloc.h>
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/config.h>
#include <asm/segment.h> #include <asm/segment.h>
#include <asm/system.h> #include <asm/system.h>
#include <asm/irq.h> #include <asm/irq.h>
#include <asm/bootinfo.h>
#include <asm/zorro.h> #include <asm/zorro.h>
#include <asm/pgtable.h> #include <asm/pgtable.h>
#include <linux/fb.h> #include <linux/fb.h>
...@@ -331,7 +329,8 @@ for (i = 0; i < 256; i++) ...@@ -331,7 +329,8 @@ for (i = 0; i < 256; i++)
} }
*memstart = (*memstart + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1); *memstart = (*memstart + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1);
CyberMem = kernel_map (board_addr + 0x01400000, 0x00400000, /* This includes the video memory as well as the S3 register set */
CyberMem = kernel_map (board_addr + 0x01400000, 0x01000000,
KERNELMAP_NOCACHE_SER, memstart); KERNELMAP_NOCACHE_SER, memstart);
if (Cyberfb_Cyber8) if (Cyberfb_Cyber8)
...@@ -339,8 +338,7 @@ if (Cyberfb_Cyber8) ...@@ -339,8 +338,7 @@ if (Cyberfb_Cyber8)
else else
memset ((char*)CyberMem, 0, CYBER16_WIDTH * CYBER16_HEIGHT); memset ((char*)CyberMem, 0, CYBER16_WIDTH * CYBER16_HEIGHT);
CyberRegs = (char*) kernel_map (board_addr + 0x02000000, 0xf000, CyberRegs = (char*) (CyberMem + 0x00c00000);
KERNELMAP_NOCACHE_SER, memstart);
/* Disable hardware cursor */ /* Disable hardware cursor */
*(CyberRegs + S3_CRTC_ADR) = S3_REG_LOCK2; *(CyberRegs + S3_CRTC_ADR) = S3_REG_LOCK2;
...@@ -410,7 +408,11 @@ static int Cyber_encode_fix(struct fb_fix_screeninfo *fix, ...@@ -410,7 +408,11 @@ static int Cyber_encode_fix(struct fb_fix_screeninfo *fix,
strcpy(fix->id, Cyber_fb_name); strcpy(fix->id, Cyber_fb_name);
fix->smem_start = CyberMem; fix->smem_start = CyberMem;
#if 0
fix->smem_len = CyberSize; fix->smem_len = CyberSize;
#else
fix->smem_len = 0x01000000;
#endif
fix->type = FB_TYPE_PACKED_PIXELS; fix->type = FB_TYPE_PACKED_PIXELS;
fix->type_aux = 0; fix->type_aux = 0;
......
#include <linux/module.h> #include <linux/module.h>
#include <asm/zorro.h> #include <asm/zorro.h>
#include <asm/amigatypes.h>
#include <asm/amigahw.h>
static struct symbol_table mach_amiga_symbol_table = { static struct symbol_table mach_amiga_symbol_table = {
#include <linux/symtab_begin.h> #include <linux/symtab_begin.h>
...@@ -7,11 +9,16 @@ static struct symbol_table mach_amiga_symbol_table = { ...@@ -7,11 +9,16 @@ static struct symbol_table mach_amiga_symbol_table = {
/* /*
* Add things here when you find the need for it. * Add things here when you find the need for it.
*/ */
X(amiga_colorclock),
X(amiga_chip_alloc),
X(amiga_chip_free),
X(amiga_chip_avail),
X(zorro_find), X(zorro_find),
X(zorro_get_board), X(zorro_get_board),
X(zorro_config_board), X(zorro_config_board),
X(zorro_unconfig_board), X(zorro_unconfig_board),
X(zorro_unused_z2ram),
/* example /* example
X(something_you_need), X(something_you_need),
......
This diff is collapsed.
...@@ -11,7 +11,6 @@ EXTRA_CFLAGS := -Wa,-m68030 ...@@ -11,7 +11,6 @@ EXTRA_CFLAGS := -Wa,-m68030
O_TARGET := atari.o O_TARGET := atari.o
O_OBJS := config.o atakeyb.o ataints.o \ O_OBJS := config.o atakeyb.o ataints.o \
stdma.o atasound.o joystick.o stram.o atafb.o stdma.o atasound.o joystick.o stram.o atafb.o ksyms.o
OX_OBJS = ksyms.o
include $(TOPDIR)/Rules.make include $(TOPDIR)/Rules.make
This diff is collapsed.
This diff is collapsed.
...@@ -29,10 +29,9 @@ ...@@ -29,10 +29,9 @@
#include <asm/atari_joystick.h> #include <asm/atari_joystick.h>
#include <asm/irq.h> #include <asm/irq.h>
extern int do_poke_blanked_console; extern void handle_scancode(unsigned char);
extern void process_keycode (int);
extern int ovsc_switchmode; extern int ovsc_switchmode;
unsigned char mach_keyboard_type; extern unsigned char mach_keyboard_type;
static void atakeyb_rep( unsigned long ignore ); static void atakeyb_rep( unsigned long ignore );
extern unsigned int keymap_count; extern unsigned int keymap_count;
...@@ -41,7 +40,6 @@ void (*atari_MIDI_interrupt_hook) (void); ...@@ -41,7 +40,6 @@ void (*atari_MIDI_interrupt_hook) (void);
/* Hook for mouse driver */ /* Hook for mouse driver */
void (*atari_mouse_interrupt_hook) (char *); void (*atari_mouse_interrupt_hook) (char *);
#define ATAKEY_CAPS (58)
#define BREAK_MASK (0x80) #define BREAK_MASK (0x80)
/* /*
...@@ -83,6 +81,11 @@ void (*atari_mouse_interrupt_hook) (char *); ...@@ -83,6 +81,11 @@ void (*atari_mouse_interrupt_hook) (char *);
* Alt + Down -> Scroll forward console (if implemented) * Alt + Down -> Scroll forward console (if implemented)
* Alt + CapsLock -> NumLock * Alt + CapsLock -> NumLock
* *
* ++Andreas:
*
* - Help mapped to K_HELP
* - Undo mapped to K_UNDO (= K_F246)
* - Keypad Left/Right Parenthesis mapped to new K_PPAREN[LR]
*/ */
static u_short ataplain_map[NR_KEYS] = { static u_short ataplain_map[NR_KEYS] = {
...@@ -98,7 +101,7 @@ static u_short ataplain_map[NR_KEYS] = { ...@@ -98,7 +101,7 @@ static u_short ataplain_map[NR_KEYS] = {
0xf603, 0xf200, 0xf30b, 0xf601, 0xf200, 0xf602, 0xf30a, 0xf200, 0xf603, 0xf200, 0xf30b, 0xf601, 0xf200, 0xf602, 0xf30a, 0xf200,
0xf600, 0xf200, 0xf115, 0xf07f, 0xf200, 0xf200, 0xf200, 0xf200, 0xf600, 0xf200, 0xf115, 0xf07f, 0xf200, 0xf200, 0xf200, 0xf200,
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0xf200, 0xf121, 0xf11b, 0xf028, 0xf029, 0xf30d, 0xf30c, 0xf307, 0xf200, 0xf1ff, 0xf11b, 0xf312, 0xf313, 0xf30d, 0xf30c, 0xf307,
0xf308, 0xf309, 0xf304, 0xf305, 0xf306, 0xf301, 0xf302, 0xf303, 0xf308, 0xf309, 0xf304, 0xf305, 0xf306, 0xf301, 0xf302, 0xf303,
0xf300, 0xf310, 0xf30e, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf300, 0xf310, 0xf30e, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200
...@@ -117,7 +120,7 @@ static u_short atashift_map[NR_KEYS] = { ...@@ -117,7 +120,7 @@ static u_short atashift_map[NR_KEYS] = {
0xf118, 0xf200, 0xf30b, 0xf601, 0xf200, 0xf602, 0xf30a, 0xf200, 0xf118, 0xf200, 0xf30b, 0xf601, 0xf200, 0xf602, 0xf30a, 0xf200,
0xf119, 0xf200, 0xf115, 0xf07f, 0xf200, 0xf200, 0xf200, 0xf200, 0xf119, 0xf200, 0xf115, 0xf07f, 0xf200, 0xf200, 0xf200, 0xf200,
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0xf200, 0xf205, 0xf203, 0xf028, 0xf029, 0xf30d, 0xf30c, 0xf307, 0xf200, 0xf205, 0xf203, 0xf312, 0xf313, 0xf30d, 0xf30c, 0xf307,
0xf308, 0xf309, 0xf304, 0xf305, 0xf306, 0xf301, 0xf302, 0xf303, 0xf308, 0xf309, 0xf304, 0xf305, 0xf306, 0xf301, 0xf302, 0xf303,
0xf300, 0xf310, 0xf30e, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf300, 0xf310, 0xf30e, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200
...@@ -136,7 +139,7 @@ static u_short atactrl_map[NR_KEYS] = { ...@@ -136,7 +139,7 @@ static u_short atactrl_map[NR_KEYS] = {
0xf603, 0xf200, 0xf30b, 0xf601, 0xf200, 0xf602, 0xf30a, 0xf200, 0xf603, 0xf200, 0xf30b, 0xf601, 0xf200, 0xf602, 0xf30a, 0xf200,
0xf600, 0xf200, 0xf115, 0xf07f, 0xf200, 0xf200, 0xf200, 0xf200, 0xf600, 0xf200, 0xf115, 0xf07f, 0xf200, 0xf200, 0xf200, 0xf200,
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0xf200, 0xf121, 0xf202, 0xf028, 0xf029, 0xf30d, 0xf30c, 0xf307, 0xf200, 0xf1ff, 0xf202, 0xf312, 0xf313, 0xf30d, 0xf30c, 0xf307,
0xf308, 0xf309, 0xf304, 0xf305, 0xf306, 0xf301, 0xf302, 0xf303, 0xf308, 0xf309, 0xf304, 0xf305, 0xf306, 0xf301, 0xf302, 0xf303,
0xf300, 0xf310, 0xf30e, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf300, 0xf310, 0xf30e, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200
...@@ -155,7 +158,7 @@ static u_short atashift_ctrl_map[NR_KEYS] = { ...@@ -155,7 +158,7 @@ static u_short atashift_ctrl_map[NR_KEYS] = {
0xf603, 0xf200, 0xf30b, 0xf601, 0xf200, 0xf602, 0xf30a, 0xf200, 0xf603, 0xf200, 0xf30b, 0xf601, 0xf200, 0xf602, 0xf30a, 0xf200,
0xf600, 0xf200, 0xf115, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf600, 0xf200, 0xf115, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0xf200, 0xf200, 0xf200, 0xf028, 0xf029, 0xf30d, 0xf30c, 0xf307, 0xf200, 0xf200, 0xf200, 0xf312, 0xf313, 0xf30d, 0xf30c, 0xf307,
0xf308, 0xf309, 0xf304, 0xf305, 0xf306, 0xf301, 0xf302, 0xf303, 0xf308, 0xf309, 0xf304, 0xf305, 0xf306, 0xf301, 0xf302, 0xf303,
0xf300, 0xf310, 0xf30e, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf300, 0xf310, 0xf30e, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200
...@@ -174,7 +177,7 @@ static u_short ataalt_map[NR_KEYS] = { ...@@ -174,7 +177,7 @@ static u_short ataalt_map[NR_KEYS] = {
0xf20b, 0xf200, 0xf30b, 0xf601, 0xf200, 0xf602, 0xf30a, 0xf200, 0xf20b, 0xf200, 0xf30b, 0xf601, 0xf200, 0xf602, 0xf30a, 0xf200,
0xf20a, 0xf200, 0xf209, 0xf87f, 0xf200, 0xf200, 0xf200, 0xf200, 0xf20a, 0xf200, 0xf209, 0xf87f, 0xf200, 0xf200, 0xf200, 0xf200,
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0xf200, 0xf206, 0xf204, 0xf028, 0xf029, 0xf30d, 0xf30c, 0xf907, 0xf200, 0xf206, 0xf204, 0xf312, 0xf313, 0xf30d, 0xf30c, 0xf907,
0xf908, 0xf909, 0xf904, 0xf905, 0xf906, 0xf901, 0xf902, 0xf903, 0xf908, 0xf909, 0xf904, 0xf905, 0xf906, 0xf901, 0xf902, 0xf903,
0xf900, 0xf310, 0xf30e, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf900, 0xf310, 0xf30e, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200
...@@ -193,7 +196,7 @@ static u_short atashift_alt_map[NR_KEYS] = { ...@@ -193,7 +196,7 @@ static u_short atashift_alt_map[NR_KEYS] = {
0xf118, 0xf200, 0xf30b, 0xf601, 0xf200, 0xf602, 0xf30a, 0xf200, 0xf118, 0xf200, 0xf30b, 0xf601, 0xf200, 0xf602, 0xf30a, 0xf200,
0xf119, 0xf200, 0xf115, 0xf87f, 0xf200, 0xf200, 0xf200, 0xf200, 0xf119, 0xf200, 0xf115, 0xf87f, 0xf200, 0xf200, 0xf200, 0xf200,
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0xf200, 0xf200, 0xf200, 0xf028, 0xf029, 0xf30d, 0xf30c, 0xf307, 0xf200, 0xf200, 0xf200, 0xf312, 0xf313, 0xf30d, 0xf30c, 0xf307,
0xf308, 0xf309, 0xf304, 0xf305, 0xf306, 0xf301, 0xf302, 0xf303, 0xf308, 0xf309, 0xf304, 0xf305, 0xf306, 0xf301, 0xf302, 0xf303,
0xf300, 0xf310, 0xf30e, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf300, 0xf310, 0xf30e, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200
...@@ -212,7 +215,7 @@ static u_short atactrl_alt_map[NR_KEYS] = { ...@@ -212,7 +215,7 @@ static u_short atactrl_alt_map[NR_KEYS] = {
0xf603, 0xf200, 0xf30b, 0xf601, 0xf200, 0xf602, 0xf30a, 0xf200, 0xf603, 0xf200, 0xf30b, 0xf601, 0xf200, 0xf602, 0xf30a, 0xf200,
0xf600, 0xf200, 0xf115, 0xf07f, 0xf200, 0xf200, 0xf200, 0xf200, 0xf600, 0xf200, 0xf115, 0xf07f, 0xf200, 0xf200, 0xf200, 0xf200,
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0xf200, 0xf121, 0xf202, 0xf028, 0xf029, 0xf30d, 0xf30c, 0xf307, 0xf200, 0xf1ff, 0xf202, 0xf312, 0xf313, 0xf30d, 0xf30c, 0xf307,
0xf308, 0xf309, 0xf304, 0xf305, 0xf306, 0xf301, 0xf302, 0xf303, 0xf308, 0xf309, 0xf304, 0xf305, 0xf306, 0xf301, 0xf302, 0xf303,
0xf300, 0xf310, 0xf30e, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf300, 0xf310, 0xf30e, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200
...@@ -231,7 +234,7 @@ static u_short atashift_ctrl_alt_map[NR_KEYS] = { ...@@ -231,7 +234,7 @@ static u_short atashift_ctrl_alt_map[NR_KEYS] = {
0xf603, 0xf200, 0xf30b, 0xf601, 0xf200, 0xf602, 0xf30a, 0xf200, 0xf603, 0xf200, 0xf30b, 0xf601, 0xf200, 0xf602, 0xf30a, 0xf200,
0xf600, 0xf200, 0xf115, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf600, 0xf200, 0xf115, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0xf200, 0xf200, 0xf200, 0xf028, 0xf029, 0xf30d, 0xf30c, 0xf307, 0xf200, 0xf200, 0xf200, 0xf312, 0xf313, 0xf30d, 0xf30c, 0xf307,
0xf308, 0xf309, 0xf304, 0xf305, 0xf306, 0xf301, 0xf302, 0xf303, 0xf308, 0xf309, 0xf304, 0xf305, 0xf306, 0xf301, 0xf302, 0xf303,
0xf300, 0xf310, 0xf30e, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf300, 0xf310, 0xf30e, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200
...@@ -270,7 +273,7 @@ static void atakeyb_rep( unsigned long ignore ) ...@@ -270,7 +273,7 @@ static void atakeyb_rep( unsigned long ignore )
{ {
pt_regs = NULL; pt_regs = NULL;
/* Disable keyboard it for the time we call process_keycode(), else a race /* Disable keyboard for the time we call handle_scancode(), else a race
* in the keyboard tty queue may happen */ * in the keyboard tty queue may happen */
atari_disable_irq( IRQ_MFP_ACIA ); atari_disable_irq( IRQ_MFP_ACIA );
del_timer( &atakeyb_rep_timer ); del_timer( &atakeyb_rep_timer );
...@@ -282,7 +285,7 @@ static void atakeyb_rep( unsigned long ignore ) ...@@ -282,7 +285,7 @@ static void atakeyb_rep( unsigned long ignore )
atakeyb_rep_timer.prev = atakeyb_rep_timer.next = NULL; atakeyb_rep_timer.prev = atakeyb_rep_timer.next = NULL;
add_timer( &atakeyb_rep_timer ); add_timer( &atakeyb_rep_timer );
process_keycode (rep_scancode); handle_scancode(rep_scancode);
} }
atari_enable_irq( IRQ_MFP_ACIA ); atari_enable_irq( IRQ_MFP_ACIA );
...@@ -306,7 +309,7 @@ static void atakeyb_rep( unsigned long ignore ) ...@@ -306,7 +309,7 @@ static void atakeyb_rep( unsigned long ignore )
* because then the keyboard repeat strikes... * because then the keyboard repeat strikes...
*/ */
static void keyboard_interrupt(int irq, struct pt_regs *fp, void *dummy) static void keyboard_interrupt(int irq, void *dummy, struct pt_regs *fp)
{ {
u_char acia_stat; u_char acia_stat;
int scancode; int scancode;
...@@ -335,7 +338,7 @@ static void keyboard_interrupt(int irq, struct pt_regs *fp, void *dummy) ...@@ -335,7 +338,7 @@ static void keyboard_interrupt(int irq, struct pt_regs *fp, void *dummy)
rep_scancode = 0; rep_scancode = 0;
if (IS_SYNC_CODE(scancode)) { if (IS_SYNC_CODE(scancode)) {
/* This code seem already to be the start of a new packet or a /* This code seem already to be the start of a new packet or a
* single keycode */ * single scancode */
kb_state.state = KEYBOARD; kb_state.state = KEYBOARD;
goto interpret_scancode; goto interpret_scancode;
} }
...@@ -350,6 +353,7 @@ static void keyboard_interrupt(int irq, struct pt_regs *fp, void *dummy) ...@@ -350,6 +353,7 @@ static void keyboard_interrupt(int irq, struct pt_regs *fp, void *dummy)
if (acia_stat & ACIA_RDRF) /* received a character */ if (acia_stat & ACIA_RDRF) /* received a character */
{ {
scancode = acia.key_data; /* get it or reset the ACIA, I'll get it! */ scancode = acia.key_data; /* get it or reset the ACIA, I'll get it! */
mark_bh(KEYBOARD_BH);
interpret_scancode: interpret_scancode:
switch (kb_state.state) switch (kb_state.state)
{ {
...@@ -398,11 +402,7 @@ static void keyboard_interrupt(int irq, struct pt_regs *fp, void *dummy) ...@@ -398,11 +402,7 @@ static void keyboard_interrupt(int irq, struct pt_regs *fp, void *dummy)
add_timer( &atakeyb_rep_timer ); add_timer( &atakeyb_rep_timer );
} }
process_keycode( break_flag | scancode ); handle_scancode(break_flag | scancode);
do_poke_blanked_console = 1;
mark_bh(CONSOLE_BH);
add_keyboard_randomness(scancode);
break; break;
} }
break; break;
...@@ -482,7 +482,7 @@ static void keyboard_interrupt(int irq, struct pt_regs *fp, void *dummy) ...@@ -482,7 +482,7 @@ static void keyboard_interrupt(int irq, struct pt_regs *fp, void *dummy)
printk("Error in keyboard communication\n"); printk("Error in keyboard communication\n");
} }
/* process_keycode() can take a lot of time, so check again if /* handle_scancode() can take a lot of time, so check again if
* some character arrived * some character arrived
*/ */
goto repeat; goto repeat;
...@@ -775,8 +775,8 @@ int atari_keyb_init(void) ...@@ -775,8 +775,8 @@ int atari_keyb_init(void)
kb_state.state = KEYBOARD; kb_state.state = KEYBOARD;
kb_state.len = 0; kb_state.len = 0;
add_isr(IRQ_MFP_ACIA, keyboard_interrupt, IRQ_TYPE_SLOW, NULL, request_irq(IRQ_MFP_ACIA, keyboard_interrupt, IRQ_TYPE_SLOW,
"keyboard/mouse/MIDI"); "keyboard/mouse/MIDI", keyboard_interrupt);
atari_turnoff_irq(IRQ_MFP_ACIA); atari_turnoff_irq(IRQ_MFP_ACIA);
do { do {
......
gcc -D__KERNEL__ -O2 -m68030 -c atacon.c -o atacon.o
gcc -D__KERNEL__ -O2 -m68030 -c atasound.c -o atasound.o
gcc -D__KERNEL__ -O2 -m68030 -c ataints.c -o ataints.o
gcc -D__KERNEL__ -O2 -m68030 -c atapart.c -o atapart.o
gcc -D__KERNEL__ -O2 -m68030 -c atakeyb.c -o atakeyb.o
gcc -D__KERNEL__ -O2 -m68030 -c joystick.c -o joystick.o
gcc -D__KERNEL__ -O2 -m68030 -c mouse.c -o mouse.o
gcc -D__KERNEL__ -O2 -m68030 -c config.c -o config.o
gcc -D__KERNEL__ -O2 -m68030 -c font_8x16.c -o font_8x16.o
gcc -D__KERNEL__ -O2 -m68030 -c font_8x8.c -o font_8x8.o
gcc -D__KERNEL__ -O2 -m68030 -c stdma.c -o stdma.o
lnx-ld -r -o atari.o atacon.o atasound.o ataints.o atapart.o atakeyb.o config.o font_8x8.o font_8x1.o joystick.o mouse.o stdma.o
cp atari.o ..\makedir
This diff is collapsed.
This diff is collapsed.
#include <linux/config.h>
#include <linux/module.h> #include <linux/module.h>
#include <asm/ptrace.h> #include <asm/ptrace.h>
#include <asm/traps.h> #include <asm/traps.h>
...@@ -13,6 +12,7 @@ static struct symbol_table mach_atari_symbol_table = { ...@@ -13,6 +12,7 @@ static struct symbol_table mach_atari_symbol_table = {
X(is_medusa), X(is_medusa),
X(atari_register_vme_int), X(atari_register_vme_int),
X(atari_unregister_vme_int),
X(stdma_lock), X(stdma_lock),
X(stdma_release), X(stdma_release),
X(stdma_others_waiting), X(stdma_others_waiting),
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
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