Commit fbda5aab authored by Linus Torvalds's avatar Linus Torvalds

Import 2.1.0

parent 734e34f1
......@@ -1320,7 +1320,7 @@ N: Linus Torvalds
E: Linus.Torvalds@Helsinki.FI
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
D: General kernel hacker
D: Original kernel hacker
S: Kalevankatu 55 B 37
S: 00180 Helsinki
S: Finland
......
......@@ -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."
(interactive)
(c-mode)
(setq c-indent-level 8)
(setq c-brace-imaginary-offset 0)
(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))
(c-set-style "K&R")
(setq c-basic-offset 8))
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
......
[ 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
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
-----------
......
......@@ -255,6 +255,8 @@ Summary of ide driver parameters for kernel "command line":
Not fully supported by all chipset types,
and quite likely to cause trouble with
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,
where "xx" is between 20 and 66 inclusive,
......
......@@ -2,14 +2,14 @@
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
code started generating with the release of kernel version 1.3.95. The
messages look something like this:
......@@ -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.
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
somebody made a 4.7.6 release for people using a.out systems.
months. The latest versions at the time of writing are 5.3.12 (released)
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
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.
1.2 Disallow Mixed Locks
------------------------
Sendmail Problems
-----------------
1.2.1 Sendmail Problems
---------------------
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
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,
over time, or under a very heavy mail load, would eventually cause the kernel
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
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.
......@@ -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
deadlock though. Recompile sendmail to use flock() and your troubles will
be over.
......@@ -5,8 +5,8 @@
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
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
borrowing the fcntl() locking scheme from System V. The mandatory locking
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
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
refrain from clearing this bit. Similarly the kernel has been modified not
to run mandatory lock candidates with setgid privileges.
Available implementations
-------------------------
3. Available implementations
----------------------------
I have considered the implementations of mandatory locking available with
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
below are just as valid as any others, so long as the main points seem to
agree.
Semantics
---------
4. Semantics
------------
1. Mandatory locks can only be applied via the fcntl()/lockf() locking
interface - in other words the System V/POSIX interface. BSD style
......@@ -124,8 +124,8 @@ Semantics
that has any mandatory locks in effect will be rejected with the error status
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(),
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
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.
Warning!
--------
6. Warning!
-----------
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
......
......@@ -159,6 +159,12 @@ M: mike@i-Connect.Net
L: linux-eata@i-connect.net, linux-scsi@vger.rutgers.edu
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)
P: Mike McLagan
M: mike.mclagan@linux.org
......
VERSION = 2
PATCHLEVEL = 0
SUBLEVEL = 21
PATCHLEVEL = 1
SUBLEVEL = 0
ARCH = i386
......@@ -26,7 +26,7 @@ TOPDIR := $(shell if [ "$$PWD" != "" ]; then echo $$PWD; else pwd; fi)
HPATH = $(TOPDIR)/include
FINDHPATH = $(HPATH)/asm $(HPATH)/linux $(HPATH)/scsi $(HPATH)/net
HOSTCC =gcc -I$(HPATH)
HOSTCC =gcc
HOSTCFLAGS =-O2 -fomit-frame-pointer
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
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?
Linux is a Unix clone written from scratch by Linus Torvalds with
......@@ -27,7 +41,7 @@ ON WHAT HARDWARE DOES IT RUN?
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
general UNIX questions. I'd recommend looking into the documentation
subdirectories on any Linux ftp site for the LDP (Linux Documentation
......@@ -44,13 +58,13 @@ INSTALLING the kernel:
- If you install the full sources, do a
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
latest kernel.
- You can also upgrade between 2.0.xx releases by patching. Each
patch that is released for 2.0.xx contains only bugfixes. No
- You can also upgrade between 2.1.xx releases by patching. Each
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
development effort begins. To install by patching, get all the
newer patch files and do
......@@ -76,7 +90,7 @@ INSTALLING the kernel:
the current directory, but an alternative directory can be specified
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:
cd /usr/include
......@@ -85,7 +99,7 @@ INSTALLING the kernel:
ln -s /usr/src/linux/include/linux linux
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
make mrproper
......@@ -94,7 +108,7 @@ INSTALLING 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
/bin/sh (in that order), so hopefully one of those is correct.
......@@ -128,26 +142,28 @@ CONFIGURING the kernel:
COMPILING the kernel:
- make sure you have gcc-2.6.3 or newer available. It seems older gcc
versions can have problems compiling newer versions of linux. If you
upgrade your compiler, remember to get the new binutils package too
- Make sure you have gcc-2.7.0 or newer available. It seems older gcc
versions can have problems compiling newer versions of linux. This
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).
- 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
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,
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.
- 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".
Read Documentation/modules.txt for more information. For example,
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
contains new code which has not been debugged.
......@@ -157,9 +173,9 @@ COMPILING the kernel:
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
floppy. Note that as of Linux 2.0.0, a kernel copied to a 720k
double-density 3.5" floppy disk no longer boots. In this case,
it is highly recommended that you install LILO on your
floppy. Note that a change in the 1.3.x series prevented a kernel
copied to a 720k double-density 3.5" floppy from booting. In this
case, it is highly recommended that you install LILO on your
double-density bootfloppy or switch to high-density floppies.
If you boot Linux from the hard drive, chances are you use LILO which
......@@ -183,11 +199,11 @@ COMPILING the kernel:
alternatively the LILO boot options when appropriate). No need to
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 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
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
......@@ -201,7 +217,7 @@ IF SOMETHING GOES WRONG:
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.
- 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
Oops: 0002
......@@ -224,7 +240,7 @@ IF SOMETHING GOES WRONG:
the C++ sources under the scripts/ directory to avoid having to do
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
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
......@@ -255,7 +271,7 @@ IF SOMETHING GOES WRONG:
kernel image or similar), telling me as much about your setup as
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
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").
......
......@@ -197,7 +197,7 @@ static unsigned long get_long(struct task_struct * tsk,
}
page = pte_page(*pgtable);
/* this is a hack for non-kernel-mapped video buffers and similar */
if (page >= high_memory)
if (MAP_NR(page) >= max_mapnr)
return 0;
page += addr & ~PAGE_MASK;
return *(unsigned long *) page;
......@@ -252,7 +252,7 @@ static void put_long(struct task_struct * tsk, struct vm_area_struct * vma,
goto repeat;
}
/* 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;
/* 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 */
......
......@@ -59,7 +59,7 @@ void show_mem(void)
printk("\nMem-info:\n");
show_free_areas();
printk("Free swap: %6dkB\n",nr_swap_pages<<(PAGE_SHIFT-10));
i = MAP_NR(high_memory);
i = max_mapnr;
while (i-- > 0) {
total++;
if (PageReserved(mem_map+i))
......@@ -145,7 +145,8 @@ void mem_init(unsigned long start_mem, unsigned long end_mem)
unsigned long tmp;
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);
/*
......@@ -157,7 +158,7 @@ void mem_init(unsigned long start_mem, unsigned long end_mem)
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)
clear_bit(PG_DMA, &mem_map[MAP_NR(tmp)].flags);
if (PageReserved(mem_map+MAP_NR(tmp)))
......@@ -174,7 +175,7 @@ void si_meminfo(struct sysinfo *val)
{
int i;
i = MAP_NR(high_memory);
i = max_mapnr;
val->totalram = 0;
val->sharedram = 0;
val->freeram = nr_free_pages << PAGE_SHIFT;
......
......@@ -13,27 +13,25 @@
# 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..
#
# -zmagic: (aout, old GCC-2.5.2)
#
# ZLINKFLAGS = -Ttext 0x1000
# BZLINKFLAGS = -Ttext 0x100000 # (for big high loaded kernels)
# LINKFLAGS = -Ttext 0x100000
# ZIMAGE_OFFSET is the load offset of the compression loader
# BZIMAGE_OFFSET is the load offset of the high loaded compression loader
#
# -qmagic: (aout)
ZIMAGE_OFFSET=0x1000
BZIMAGE_OFFSET=0x100000
#
# ZLINKFLAGS = -Ttext 0x0xfe0
# BZLINKFLAGS = -Ttext 0xfffe0 # (for big high loaded kernels)
# LINKFLAGS = -Ttext 0xfffe0
# IMAGE_OFFSET is the load offset of the _real_ kernel, soon
# to be offset by another 0xC0000000...
#
IMAGE_OFFSET=0xC0100000
AS86 =$(CROSS_COMPILE)as86 -0 -a
AS386 =$(CROSS_COMPILE)as86 -3
LD86 =$(CROSS_COMPILE)ld86 -0
ifdef CONFIG_KERNEL_ELF
# This is used for ELF - it needs to migrate or be moved.
LD_RFLAG = -m elf_i386
LD=$(CROSS_COMPILE)ld -m elf_i386
CPP=$(CC) -E -D__ELF__
......@@ -43,22 +41,10 @@ ENCAPS=$(CROSS_COMPILE)encaps
OBJCOPY=$(CROSS_COMPILE)objcopy -O binary -R .note -R .comment -R .stab -R .stabstr
ZLDFLAGS=-e startup_32
LDFLAGS=-e stext
ZIMAGE_OFFSET=0x1000
IMAGE_OFFSET=0x100000
ZLINKFLAGS =-Ttext $(ZIMAGE_OFFSET) $(ZLDFLAGS)
BZLINKFLAGS =-Ttext $(IMAGE_OFFSET) $(ZLDFLAGS)
BZLINKFLAGS =-Ttext $(BZIMAGE_OFFSET) $(ZLDFLAGS)
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
ifdef CONFIG_M386
......
......@@ -8,38 +8,28 @@
# Copyright (C) 1994 by Linus Torvalds
#
ifdef CONFIG_KERNEL_ELF
HOSTCFLAGS := $(HOSTCFLAGS) -D__BFD__
endif
ifdef SMP
HOSTCFLAGS := $(HOSTCFLAGS) -D__SMP__
endif
zImage: $(CONFIGURE) bootsect setup compressed/vmlinux tools/build
ifdef CONFIG_KERNEL_ELF
if hash $(ENCAPS) 2> /dev/null; then \
$(OBJDUMP) $(OBJDUMP_FLAGS) -o $(ZIMAGE_OFFSET) compressed/vmlinux > compressed/vmlinux.out; \
else \
$(OBJCOPY) compressed/vmlinux compressed/vmlinux.out; \
fi
tools/build bootsect setup compressed/vmlinux.out $(ROOT_DEV) > zImage
else
tools/build bootsect setup compressed/vmlinux $(ROOT_DEV) > zImage
endif
sync
bzImage: $(CONFIGURE) bbootsect setup compressed/bvmlinux tools/bbuild
ifdef CONFIG_KERNEL_ELF
if hash $(ENCAPS) 2> /dev/null; then \
$(OBJDUMP) $(OBJDUMP_FLAGS) -o $(IMAGE_OFFSET) compressed/bvmlinux > compressed/bvmlinux.out; \
else \
$(OBJCOPY) compressed/bvmlinux compressed/bvmlinux.out; \
fi
tools/bbuild bbootsect setup compressed/bvmlinux.out $(ROOT_DEV) > bzImage
else
tools/bbuild bbootsect setup compressed/bvmlinux $(ROOT_DEV) > bzImage
endif
sync
compressed/vmlinux: $(TOPDIR)/vmlinux
......
......@@ -15,11 +15,9 @@ ifdef SMP
CFLAGS := $(CFLAGS) -D__SMP__
endif
ifdef CONFIG_KERNEL_ELF
TARGET=--target elf32-i386
INPUT_DATA=input_data
INPUT_LEN=input_len
endif
all: vmlinux
......@@ -41,7 +39,6 @@ head.o: head.S $(TOPDIR)/include/linux/tasks.h
endif
ifdef CONFIG_KERNEL_ELF
# You cannot compress a file and have the kernel uncompress it, it must
# be stdin
......@@ -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; \
fi; \
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:
rm -f xtract piggyback vmlinux bvmlinux
......@@ -21,6 +21,8 @@
#define OF(args) args
#define STATIC static
#undef memset
#undef memcpy
#define memzero(s, n) memset ((s), 0, (n))
typedef unsigned char uch;
......
......@@ -36,7 +36,6 @@ tristate 'Kernel support for ELF binaries' CONFIG_BINFMT_ELF
if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
tristate 'Kernel support for JAVA binaries' CONFIG_BINFMT_JAVA
fi
bool 'Compile kernel as ELF - if your GCC is ELF-GCC' CONFIG_KERNEL_ELF
choice 'Processor type' \
"386 CONFIG_M386 \
......
......@@ -24,7 +24,6 @@ CONFIG_PCI=y
CONFIG_SYSVIPC=y
CONFIG_BINFMT_AOUT=y
CONFIG_BINFMT_ELF=y
CONFIG_KERNEL_ELF=y
# CONFIG_M386 is not set
# CONFIG_M486 is not set
CONFIG_M586=y
......
......@@ -55,6 +55,7 @@
#include <linux/bios32.h>
#include <linux/pci.h>
#include <asm/page.h>
#include <asm/segment.h>
#define PCIBIOS_PCI_FUNCTION_ID 0xb1XX
......@@ -164,7 +165,7 @@ extern unsigned long check_pcibios(unsigned long memory_start, unsigned long mem
int pack;
if ((pcibios_entry = bios32_service(PCI_SERVICE))) {
pci_indirect.address = pcibios_entry;
pci_indirect.address = pcibios_entry | PAGE_OFFSET;
__asm__("lcall (%%edi)\n\t"
"jc 1f\n\t"
......@@ -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)
continue;
length = check->fields.length * 16;
......@@ -438,8 +441,9 @@ unsigned long pcibios_init(unsigned long memory_start, unsigned long memory_end)
if (check->fields.entry >= 0x100000) {
printk("pcibios_init: entry in high memory, unable to access\n");
} 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);
bios32_indirect.address = bios32_entry + PAGE_OFFSET;
}
}
}
......
......@@ -38,6 +38,8 @@
* 38(%esp) - %eflags
* 3C(%esp) - %oldesp
* 40(%esp) - %oldss
*
* "current" is in register %ebx during any slow entries.
*/
#include <linux/sys.h>
......@@ -99,9 +101,7 @@ ENOSYS = 38
pushl %ebx; \
movl $(KERNEL_DS),%edx; \
mov %dx,%ds; \
mov %dx,%es; \
movl $(USER_DS),%edx; \
mov %dx,%fs;
mov %dx,%es;
#ifdef __SMP__
......@@ -194,13 +194,7 @@ ENOSYS = 38
#define RESTORE_ALL \
cmpw $(KERNEL_CS),CS(%esp); \
je 1f; \
GET_PROCESSOR_OFFSET(%edx) \
movl SYMBOL_NAME(current_set)(,%edx), %eax ; ; \
movl dbgreg7(%eax),%ebx; \
movl %ebx,%db7; \
1: LEAVE_KERNEL \
LEAVE_KERNEL \
popl %ebx; \
popl %ecx; \
popl %edx; \
......@@ -215,15 +209,16 @@ ENOSYS = 38
addl $4,%esp; \
iret
#define GET_CURRENT \
GET_PROCESSOR_OFFSET(%ebx) \
movl SYMBOL_NAME(current_set)(%ebx),%ebx
#else
#define GET_CURRENT \
movl SYMBOL_NAME(current_set),%ebx
#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 %ecx; \
popl %edx; \
......@@ -244,6 +239,7 @@ ENTRY(lcall7)
pushfl # We get a different stack layout with call gates,
pushl %eax # which has to be cleaned up later..
SAVE_ALL
GET_CURRENT
#ifdef __SMP__
ENTER_KERNEL
#endif
......@@ -281,6 +277,7 @@ reschedule:
ENTRY(system_call)
pushl %eax # save orig_eax
SAVE_ALL
GET_CURRENT
#ifdef __SMP__
ENTER_KERNEL
#endif
......@@ -290,33 +287,11 @@ ENTRY(system_call)
movl SYMBOL_NAME(sys_call_table)(,%eax,4),%eax
testl %eax,%eax
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
movl %db6,%edx
movl %edx,dbgreg6(%ebx) # save current hardware debugging status
testb $0x20,flags(%ebx) # PF_TRACESYS
jne 1f
jne tracesys
call *%eax
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
.globl ret_from_sys_call
ret_from_sys_call:
......@@ -336,18 +311,12 @@ ret_from_sys_call:
movl %eax,EFLAGS(%esp) # stupid
cmpl $0,SYMBOL_NAME(need_resched)
jne reschedule
#ifdef __SMP__
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
cmpl SYMBOL_NAME(task),%ebx # task[0] cannot have signals
je 2f
movl blocked(%eax),%ecx
movl %ecx,%ebx # save blocked in %ebx for signal handling
movl blocked(%ebx),%ecx
movl %ecx,%eax # save blocked in %eax for signal handling
notl %ecx
andl signal(%eax),%ecx
andl signal(%ebx),%ecx
jne signal_return
2: RESTORE_ALL
ALIGN
......@@ -356,21 +325,32 @@ signal_return:
pushl %ecx
testl $(VM_MASK),EFLAGS(%ecx)
jne v86_signal_return
pushl %ebx
pushl %eax
call SYMBOL_NAME(do_signal)
popl %ebx
popl %ebx
popl %eax
popl %eax
RESTORE_ALL
ALIGN
v86_signal_return:
pushl %eax
call SYMBOL_NAME(save_v86_state)
popl %edx
movl %eax,%esp
pushl %eax
pushl %ebx
pushl %edx
call SYMBOL_NAME(do_signal)
popl %ebx
popl %ebx
popl %edx
popl %edx
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)
pushl $0 # no error code
......@@ -390,28 +370,21 @@ error_code:
pushl %ecx
pushl %ebx
cld
xorl %ebx,%ebx # zero ebx
xorl %ecx,%ecx # zero ecx
xchgl %eax, ORIG_EAX(%esp) # orig_eax (get the error code. )
mov %gs,%bx # get the lower order bits of gs
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 %edx
movl $(KERNEL_DS),%edx
mov %dx,%ds
mov %dx,%es
movl $(USER_DS),%edx
mov %dx,%fs
GET_CURRENT
#ifdef __SMP__
ENTER_KERNEL
GET_PROCESSOR_OFFSET(%eax)
movl SYMBOL_NAME(current_set)(,%eax), %eax
#else
movl SYMBOL_NAME(current_set),%eax
#endif
movl %db6,%edx
movl %edx,dbgreg6(%eax) # save current hardware debugging status
call *%ebx
call *%ecx
addl $8,%esp
jmp ret_from_sys_call
......@@ -423,6 +396,7 @@ ENTRY(coprocessor_error)
ENTRY(device_not_available)
pushl $-1 # mark this as an int
SAVE_ALL
GET_CURRENT
#ifdef __SMP__
ENTER_KERNEL
#endif
......
This diff is collapsed.
......@@ -4,6 +4,7 @@
#include <linux/elfcore.h>
#include <asm/semaphore.h>
#include <asm/io.h>
extern void dump_thread(struct pt_regs *, struct user *);
extern int dump_fpu(elf_fpregset_t *);
......@@ -13,6 +14,7 @@ static struct symbol_table arch_symbol_table = {
/* platform dependent support */
X(dump_thread),
X(dump_fpu),
X(ioremap),
XNOVERS(down_failed),
XNOVERS(up_wakeup),
#ifdef __SMP__
......
......@@ -8,9 +8,11 @@
#include <linux/sched.h>
#include <linux/string.h>
#include <linux/mm.h>
#include <linux/vmalloc.h>
#include <asm/segment.h>
#include <asm/system.h>
#include <linux/ldt.h>
#include <asm/ldt.h>
static int read_ldt(void * ptr, unsigned long bytecount)
{
......
......@@ -19,19 +19,20 @@
#include <linux/unistd.h>
#include <linux/ptrace.h>
#include <linux/malloc.h>
#include <linux/ldt.h>
#include <linux/vmalloc.h>
#include <linux/user.h>
#include <linux/a.out.h>
#include <linux/interrupt.h>
#include <linux/config.h>
#include <linux/unistd.h>
#include <linux/delay.h>
#include <linux/smp.h>
#include <asm/segment.h>
#include <asm/pgtable.h>
#include <asm/system.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");
......@@ -182,6 +183,17 @@ int cpu_idle(void *unused)
* and if it doesn't work, we do some other stupid things.
*/
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)
{
......@@ -197,16 +209,14 @@ void hard_reset_now(void)
int i, j;
sti();
/* rebooting needs to touch the page at absolute addr 0 */
pg0[0] = 7;
*((unsigned short *)0x472) = 0x1234;
*((unsigned short *)__va(0x472)) = reboot_mode;
for (;;) {
for (i=0; i<100; i++) {
kb_wait();
for(j = 0; j < 100000 ; j++)
/* nothing */;
outb(0xfe,0x64); /* pulse reset low */
udelay(10);
udelay(100);
}
__asm__ __volatile__("\tlidt %0": "=m" (no_idt));
}
......@@ -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;
p->tss.esp = (unsigned long) childregs;
p->tss.eip = (unsigned long) ret_from_sys_call;
p->tss.ebx = (unsigned long) p;
*childregs = *regs;
childregs->eax = 0;
childregs->esp = esp;
......
......@@ -119,7 +119,7 @@ static unsigned long get_long(struct task_struct * tsk,
}
page = pte_page(*pgtable);
/* this is a hack for non-kernel-mapped video buffers and similar */
if (page >= high_memory)
if (MAP_NR(page) >= max_mapnr)
return 0;
page += addr & ~PAGE_MASK;
return *(unsigned long *) page;
......@@ -174,7 +174,7 @@ static void put_long(struct task_struct * tsk, struct vm_area_struct * vma, unsi
goto repeat;
}
/* 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;
/* 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 */
......
......@@ -16,7 +16,6 @@
#include <linux/unistd.h>
#include <linux/ptrace.h>
#include <linux/malloc.h>
#include <linux/ldt.h>
#include <linux/user.h>
#include <linux/a.out.h>
#include <linux/tty.h>
......@@ -140,10 +139,10 @@ void setup_arch(char **cmdline_p,
if (!MOUNT_ROOT_RDONLY)
root_mountflags &= ~MS_RDONLY;
memory_start = (unsigned long) &_end;
init_task.mm->start_code = TASK_SIZE;
init_task.mm->end_code = TASK_SIZE + (unsigned long) &_etext;
init_task.mm->end_data = TASK_SIZE + (unsigned long) &_edata;
init_task.mm->brk = TASK_SIZE + (unsigned long) &_end;
init_task.mm->start_code = PAGE_OFFSET;
init_task.mm->end_code = (unsigned long) &_etext;
init_task.mm->end_data = (unsigned long) &_edata;
init_task.mm->brk = (unsigned long) &_end;
/* Save unparsed command line copy for /proc/cmdline */
memcpy(saved_command_line, COMMAND_LINE, COMMAND_LINE_SIZE);
......@@ -180,13 +179,14 @@ void setup_arch(char **cmdline_p,
}
*to = '\0';
*cmdline_p = command_line;
memory_end += PAGE_OFFSET;
*memory_start_p = memory_start;
*memory_end_p = memory_end;
#ifdef CONFIG_BLK_DEV_INITRD
if (LOADER_TYPE) {
initrd_start = INITRD_START;
initrd_end = INITRD_START+INITRD_SIZE;
initrd_start = INITRD_START + PAGE_OFFSET;
initrd_end = initrd_start+INITRD_SIZE;
if (initrd_end > memory_end) {
printk("initrd extends beyond end of memory "
"(0x%08lx > 0x%08lx)\ndisabling initrd\n",
......
......@@ -197,7 +197,7 @@ static void setup_frame(struct sigaction * sa,
put_user(regs->eflags, frame+18);
put_user(regs->esp, frame+19);
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.. */
put_user(oldmask, frame+22);
put_user(current->tss.cr2, frame+23);
......
......@@ -67,7 +67,7 @@ int apic_version[NR_CPUS]; /* APIC version number */
static volatile int smp_commenced=0; /* Tripped when we start scheduling */
unsigned long apic_addr=0xFEE00000; /* Address of APIC (defaults to 0xFEE00000) */
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 char *kernel_stacks[NR_CPUS]; /* Kernel stack pointers for CPU's (debugging) */
......@@ -619,7 +619,7 @@ void smp_boot_cpus(void)
* Map the local APIC into kernel space
*/
apic_reg = vremap(apic_addr,4096);
apic_reg = ioremap(apic_addr,4096);
if(apic_reg == NULL)
panic("Unable to map local apic.\n");
......
......@@ -134,7 +134,8 @@ int kstack_depth_to_print = 24;
printk("\nCall Trace: ");
stack = (unsigned long *) esp;
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;
while (((long) stack & 4095) != 0) {
addr = get_seg_long(ss, stack++);
......@@ -329,7 +330,7 @@ void trap_init(void)
return;
}
smptrap++;
if (strncmp((char*)0x0FFFD9, "EISA", 4) == 0)
if (strncmp((char*)phys_to_virt(0x0FFFD9), "EISA", 4) == 0)
EISA_bus = 1;
set_call_gate(&default_ldt,lcall7);
set_trap_gate(0,&divide_error);
......
......@@ -102,10 +102,11 @@ static void mark_screen_rdonly(struct task_struct * tsk)
asmlinkage int sys_vm86(struct vm86_struct * v86)
{
struct vm86_struct info;
struct task_struct *tsk = current;
struct pt_regs * pt_regs = (struct pt_regs *) &v86;
int error;
if (current->saved_kernel_stack)
if (tsk->saved_kernel_stack)
return -EPERM;
/* v86 must be readable (now) and writable (for save_v86_state) */
error = verify_area(VERIFY_WRITE,v86,sizeof(*v86));
......@@ -131,16 +132,16 @@ asmlinkage int sys_vm86(struct vm86_struct * v86)
switch (info.cpu_type) {
case CPU_286:
current->tss.v86mask = 0;
tsk->tss.v86mask = 0;
break;
case CPU_386:
current->tss.v86mask = NT_MASK | IOPL_MASK;
tsk->tss.v86mask = NT_MASK | IOPL_MASK;
break;
case CPU_486:
current->tss.v86mask = AC_MASK | NT_MASK | IOPL_MASK;
tsk->tss.v86mask = AC_MASK | NT_MASK | IOPL_MASK;
break;
default:
current->tss.v86mask = ID_MASK | AC_MASK | NT_MASK | IOPL_MASK;
tsk->tss.v86mask = ID_MASK | AC_MASK | NT_MASK | IOPL_MASK;
break;
}
......@@ -148,17 +149,17 @@ asmlinkage int sys_vm86(struct vm86_struct * v86)
* Save old state, set default return value (%eax) to 0
*/
pt_regs->eax = 0;
current->saved_kernel_stack = current->tss.esp0;
current->tss.esp0 = (unsigned long) pt_regs;
current->tss.vm86_info = v86;
tsk->saved_kernel_stack = tsk->tss.esp0;
tsk->tss.esp0 = (unsigned long) pt_regs;
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)
mark_screen_rdonly(current);
mark_screen_rdonly(tsk);
__asm__ __volatile__("movl %0,%%esp\n\t"
"jmp ret_from_sys_call"
: /* no outputs */
:"r" (&info.regs));
:"r" (&info.regs), "b" (tsk));
return 0;
}
......@@ -170,7 +171,7 @@ static inline void return_to_32bit(struct vm86_regs * regs16, int retval)
regs32->eax = retval;
__asm__ __volatile__("movl %0,%%esp\n\t"
"jmp ret_from_sys_call"
: : "r" (regs32));
: : "r" (regs32), "b" (current));
}
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)
/*
* 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
*/
......
......@@ -97,9 +97,9 @@ extern char emulating;
struct address {
unsigned int offset;
unsigned int selector:16;
unsigned int opcode:11;
unsigned int empty:5;
unsigned short selector;
unsigned short opcode:11,
empty:5;
};
typedef void (*FUNC)(void);
typedef struct fpu_reg FPU_REG;
......
......@@ -8,6 +8,6 @@
# Note 2! The CFLAGS definition is now in the main makefile...
O_TARGET := mm.o
O_OBJS := init.o fault.o
O_OBJS := init.o fault.o ioremap.o
include $(TOPDIR)/Rules.make
......@@ -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..
*/
if (wp_works_ok < 0 && address == TASK_SIZE && (error_code & 1)) {
if (wp_works_ok < 0 && !address && (error_code & 1)) {
wp_works_ok = 1;
pg0[0] = pte_val(mk_pte(0, PAGE_SHARED));
flush_tlb();
printk("This processor honours the WP bit even when in supervisor mode. Good.\n");
return;
}
if ((unsigned long) (address-TASK_SIZE) < PAGE_SIZE) {
if (address < PAGE_SIZE) {
printk(KERN_ALERT "Unable to handle kernel NULL pointer dereference");
pg0[0] = pte_val(mk_pte(0, PAGE_SHARED));
} else
......@@ -139,12 +139,12 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long error_code)
__asm__("movl %%cr3,%0" : "=r" (page));
printk(KERN_ALERT "current->tss.cr3 = %08lx, %%cr3 = %08lx\n",
tsk->tss.cr3, page);
page = ((unsigned long *) page)[address >> 22];
page = ((unsigned long *) __va(page))[address >> 22];
printk(KERN_ALERT "*pde = %08lx\n", page);
if (page & 1) {
page &= PAGE_MASK;
address &= 0x003ff000;
page = ((unsigned long *) page)[address >> PAGE_SHIFT];
page = ((unsigned long *) __va(page))[address >> PAGE_SHIFT];
printk(KERN_ALERT "*pte = %08lx\n", page);
}
die_if_kernel("Oops", regs, error_code);
......
......@@ -81,7 +81,7 @@ void show_mem(void)
printk("Mem-info:\n");
show_free_areas();
printk("Free swap: %6dkB\n",nr_swap_pages<<(PAGE_SHIFT-10));
i = high_memory >> PAGE_SHIFT;
i = max_mapnr;
while (i-- > 0) {
total++;
if (PageReserved(mem_map+i))
......@@ -149,8 +149,10 @@ unsigned long paging_init(unsigned long start_mem, unsigned long end_mem)
wp_works_ok = 0;
#endif
start_mem = PAGE_ALIGN(start_mem);
address = 0;
address = PAGE_OFFSET;
pg_dir = swapper_pg_dir;
/* unmap the original low memory mappings */
pgd_val(pg_dir[0]) = 0;
while (address < end_mem) {
#ifdef USE_PENTIUM_MM
/*
......@@ -172,29 +174,29 @@ unsigned long paging_init(unsigned long start_mem, unsigned long end_mem)
: : :"ax");
#endif
wp_works_ok = 1;
pgd_val(pg_dir[0]) = _PAGE_TABLE | _PAGE_4M | address;
pgd_val(pg_dir[768]) = _PAGE_TABLE | _PAGE_4M | address;
pgd_val(pg_dir[768]) = _PAGE_TABLE + _PAGE_4M + __pa(address);
pg_dir++;
address += 4*1024*1024;
continue;
}
#endif
/* 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]));
if (!pg_table) {
pg_table = (pte_t *) start_mem;
pg_table = (pte_t *) __pa(start_mem);
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;
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++) {
if (address < end_mem)
set_pte(pg_table, mk_pte(address, PAGE_SHARED));
else
pte_clear(pg_table);
pte_t pte = mk_pte(address, PAGE_KERNEL);
if (address >= end_mem)
pte_val(pte) = 0;
set_pte(pg_table, pte);
address += PAGE_SIZE;
}
}
......@@ -212,13 +214,14 @@ void mem_init(unsigned long start_mem, unsigned long end_mem)
extern int _etext;
end_mem &= PAGE_MASK;
high_memory = end_mem;
high_memory = (void *) end_mem;
max_mapnr = MAP_NR(end_mem);
/* clear the zero-page */
memset(empty_zero_page, 0, PAGE_SIZE);
/* 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__
/*
......@@ -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
* 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);
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);
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)
clear_bit(PG_DMA, &mem_map[MAP_NR(tmp)].flags);
if (PageReserved(mem_map+MAP_NR(tmp))) {
if (tmp >= 0xA0000 && tmp < 0x100000)
if (tmp >= 0xA0000+PAGE_OFFSET && tmp < 0x100000+PAGE_OFFSET)
reservedpages++;
else if (tmp < (unsigned long) &_etext)
codepages++;
......@@ -262,19 +265,24 @@ void mem_init(unsigned long start_mem, unsigned long end_mem)
#endif
free_page(tmp);
}
tmp = nr_free_pages << PAGE_SHIFT;
printk("Memory: %luk/%luk available (%dk kernel code, %dk reserved, %dk data)\n",
tmp >> 10,
high_memory >> 10,
(unsigned long) nr_free_pages << (PAGE_SHIFT-10),
max_mapnr << (PAGE_SHIFT-10),
codepages << (PAGE_SHIFT-10),
reservedpages << (PAGE_SHIFT-10),
datapages << (PAGE_SHIFT-10));
/* test if the WP bit is honoured in supervisor mode */
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();
__asm__ __volatile__("movb 0,%%al ; movb %%al,0": : :"ax", "memory");
pg0[0] = 0;
__asm__ __volatile__(
"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();
if (wp_works_ok < 0)
wp_works_ok = 0;
......@@ -286,7 +294,7 @@ void si_meminfo(struct sysinfo *val)
{
int i;
i = high_memory >> PAGE_SHIFT;
i = max_mapnr;
val->totalram = 0;
val->sharedram = 0;
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)
# set up for cross compiling
COMPILE_ARCH = $(shell uname -m)
ifneq ($(COMPILE_ARCH),$(ARCH))
CROSSDIR=/usr/$(ARCH)-linux
CROSSDIR=/usr/$(ARCH)-linux/bin
CC := $(CROSSDIR)/$(CC)
AS := $(CROSSDIR)/$(AS)
LD := $(CROSSDIR)/$(LD)
......@@ -50,12 +50,16 @@ LINKFLAGS = -Ttext 0x1000
else
LINKFLAGS = -qmagic -Ttext 0xFE0
endif
CFLAGS := $(CFLAGS) -pipe
ifdef CONFIG_OPTIMIZE_040
CFLAGS := $(CFLAGS) -m68040
endif
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/lib
ARCHIVES := arch/m68k/kernel/kernel.o arch/m68k/mm/mm.o $(ARCHIVES)
LIBS += arch/m68k/lib/lib.a
......@@ -77,12 +81,12 @@ endif
# add in console.a after {amiga,atari}.o that need it
ARCHIVES := $(ARCHIVES) arch/m68k/console/console.a
ifdef CONFIG_FPSP_040
ifdef CONFIG_M68040
ARCHIVES := $(ARCHIVES) arch/m68k/fpsp040/fpsp.o
SUBDIRS := $(SUBDIRS) arch/m68k/fpsp040
endif
ifdef CONFIG_IFPSP_060
ifdef CONFIG_M68060
ARCHIVES := $(ARCHIVES) arch/m68k/ifpsp060/ifpsp.o
SUBDIRS := $(SUBDIRS) arch/m68k/ifpsp060
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 @@
# Note 2! The CFLAGS definitions are now in the main makefile...
O_TARGET := amiga.o
O_OBJS := config.o amikeyb.o amiints.o \
chipram.o amisound.o amifb.o zorro.o
OX_OBJS = ksyms.o
O_OBJS := config.o amikeyb.o amiints.o cia.o \
chipram.o amisound.o amifb.o zorro.o ksyms.o
ifdef CONFIG_FB_CYBER
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
* License. See the file COPYING in the main directory of this archive
......@@ -11,9 +11,9 @@
#include <linux/sched.h>
#include <linux/timer.h>
#include <asm/amigatypes.h>
#include <asm/system.h>
#include <asm/amigahw.h>
#include <asm/bootinfo.h>
static u_short *snd_data = NULL;
static const signed char sine_data[] = {
......
......@@ -8,7 +8,7 @@
#include <linux/types.h>
#include <linux/kernel.h>
#include <asm/bootinfo.h>
#include <asm/setup.h>
#include <asm/amigahw.h>
struct chip_desc {
......@@ -22,6 +22,17 @@ struct chip_desc {
#define DP(ptr) ((struct chip_desc *)(ptr))
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)
{
......@@ -46,6 +57,7 @@ void amiga_chip_init (void)
dp->alloced = 0;
dp->length = chipsize - 2*sizeof(*dp);
chipavail = dp->length; /*MILAN*/
#ifdef DEBUG
printk ("chipram end boundary is %p, length is %d\n", dp,
......@@ -63,7 +75,7 @@ void *amiga_chip_alloc (long size)
size = (size + 7) & ~7;
#ifdef DEBUG
printk ("chip_alloc: allocate %ld bytes\n", size);
printk("chip_alloc: allocate %ld bytes\n", size);
#endif
/*
......@@ -121,7 +133,9 @@ void *amiga_chip_alloc (long size)
if ((unsigned long)ptr & 7)
panic("chip_alloc: alignment violation\n");
return ptr;
chipavail -= size + (2*sizeof(*dp)); /*MILAN*/
return ptr;
}
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 *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 */
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
*
......@@ -20,11 +20,10 @@
#include <linux/kd.h>
#include <linux/tty.h>
#include <linux/console.h>
#include <linux/linkage.h>
#include <asm/setup.h>
#include <asm/system.h>
#include <asm/pgtable.h>
#include <asm/bootinfo.h>
#include <asm/amigahw.h>
#include <asm/amigaints.h>
#include <asm/irq.h>
......@@ -35,15 +34,20 @@ u_long amiga_colorclock;
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_kbdrate (struct kbd_repeat *);
extern void amiga_init_INTS (void);
extern int amiga_add_isr (unsigned long, isrfunc, int, void *, char *);
extern int amiga_remove_isr (unsigned long, isrfunc, void *);
extern int amiga_get_irq_list (char *, int);
extern void amiga_enable_irq(unsigned int);
extern void amiga_disable_irq(unsigned int);
/* amiga specific irq functions */
extern void amiga_init_IRQ (void);
extern void (*amiga_default_handler[]) (int, void *, struct pt_regs *);
extern int amiga_request_irq (unsigned int irq, void (*handler)(int, void *, struct pt_regs *),
unsigned long flags, const char *devname, void *dev_id);
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 void a3000_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)
switch (custom.deniseid & 0xf) {
case 0x0c:
AMIGAHW_SET(DENISE_HR);
printk("DENISE_HR");
printk("DENISE_HR ");
break;
case 0x08:
AMIGAHW_SET(LISA);
......@@ -257,9 +261,10 @@ void config_amiga(void)
mach_sched_init = amiga_sched_init;
mach_keyb_init = amiga_keyb_init;
mach_kbdrate = amiga_kbdrate;
mach_init_INTS = amiga_init_INTS;
mach_add_isr = amiga_add_isr;
mach_remove_isr = amiga_remove_isr;
mach_init_IRQ = amiga_init_IRQ;
mach_default_handler = &amiga_default_handler;
mach_request_irq = amiga_request_irq;
mach_free_irq = amiga_free_irq;
mach_enable_irq = amiga_enable_irq;
mach_disable_irq = amiga_disable_irq;
mach_get_irq_list = amiga_get_irq_list;
......@@ -330,60 +335,24 @@ void config_amiga(void)
#endif /* CONFIG_ZORRO */
}
extern long time_finetune; /* from kernel/sched.c */
static unsigned short jiffy_ticks;
#if 1 /* ++1.3++ */
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)
void amiga_sched_init(void (*timer_routine)(int, void *, struct pt_regs *))
{
#if 0 /* XXX */ /* I think finetune was removed by the 1.3.29 patch */
double finetune;
#endif
jiffy_ticks = (amiga_eclock+50)/100;
#if 0 /* XXX */
finetune = (jiffy_ticks-amiga_eclock/HZ)/amiga_eclock*1000000*(1<<24);
time_finetune = finetune+0.5;
#endif
ciab.cra &= 0xC0; /* turn off timer A, continuous mode, from Eclk */
ciab.talo = jiffy_ticks % 256;
ciab.tahi = jiffy_ticks / 256;
/* 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;
jiffy_ticks = (amiga_eclock+HZ/2)/HZ;
ciab.cra &= 0xC0; /* turn off timer A, continuous mode, from Eclk */
ciab.talo = jiffy_ticks % 256;
ciab.tahi = jiffy_ticks / 256;
/* 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
*/
request_irq(IRQ_AMIGA_CIAB_TA, timer_routine, IRQ_FLG_LOCK, "timer", NULL);
/* start timer */
ciab.cra |= 0x11;
}
#define TICK_SIZE 10000
......@@ -391,33 +360,30 @@ void amiga_sched_init (isrfunc timer_routine)
/* This is always executed with interrupts disabled. */
unsigned long amiga_gettimeoffset (void)
{
unsigned short hi, lo, hi2;
unsigned long ticks, offset = 0;
unsigned short hi, lo, hi2;
unsigned long ticks, offset = 0;
/* read CIA A timer A current value */
hi = ciab.tahi;
lo = ciab.talo;
hi2 = ciab.tahi;
/* read CIA B timer A current value */
hi = ciab.tahi;
lo = ciab.talo;
hi2 = ciab.tahi;
if (hi != hi2) {
lo = ciab.talo;
hi = hi2;
}
if (hi != hi2) {
lo = ciab.talo;
hi = hi2;
}
ticks = hi << 8 | lo;
ticks = hi << 8 | lo;
#if 0 /* XXX */
/* reading the ICR clears all interrupts. bad idea! */
if (ticks > jiffy_ticks - jiffy_ticks / 100)
/* check for pending interrupt */
if (ciab.icr & CIA_ICR_TA)
offset = 10000;
#endif
if (ticks > jiffy_ticks / 2)
/* check for pending interrupt */
if (cia_set_irq(&ciab_base, 0) & CIA_ICR_TA)
offset = 10000;
ticks = (jiffy_ticks-1) - ticks;
ticks = (10000 * ticks) / jiffy_ticks;
ticks = jiffy_ticks - ticks;
ticks = (10000 * ticks) / jiffy_ticks;
return ticks + offset;
return ticks + offset;
}
void a3000_gettod (int *yearp, int *monp, int *dayp,
......@@ -657,7 +623,7 @@ void amiga_reset (void)
unsigned long jmp_addr = VTOP(&&jmp_addr_label);
cli();
if (m68k_is040or060)
if (CPU_IS_040_OR_060)
/* Setup transparent translation registers for mapping
* of 16 MB kernel segment before disabling translation
*/
......
......@@ -29,11 +29,9 @@
#include <linux/tty.h>
#include <linux/malloc.h>
#include <linux/delay.h>
#include <linux/config.h>
#include <asm/segment.h>
#include <asm/system.h>
#include <asm/irq.h>
#include <asm/bootinfo.h>
#include <asm/zorro.h>
#include <asm/pgtable.h>
#include <linux/fb.h>
......@@ -331,7 +329,8 @@ for (i = 0; i < 256; i++)
}
*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);
if (Cyberfb_Cyber8)
......@@ -339,8 +338,7 @@ if (Cyberfb_Cyber8)
else
memset ((char*)CyberMem, 0, CYBER16_WIDTH * CYBER16_HEIGHT);
CyberRegs = (char*) kernel_map (board_addr + 0x02000000, 0xf000,
KERNELMAP_NOCACHE_SER, memstart);
CyberRegs = (char*) (CyberMem + 0x00c00000);
/* Disable hardware cursor */
*(CyberRegs + S3_CRTC_ADR) = S3_REG_LOCK2;
......@@ -410,7 +408,11 @@ static int Cyber_encode_fix(struct fb_fix_screeninfo *fix,
strcpy(fix->id, Cyber_fb_name);
fix->smem_start = CyberMem;
#if 0
fix->smem_len = CyberSize;
#else
fix->smem_len = 0x01000000;
#endif
fix->type = FB_TYPE_PACKED_PIXELS;
fix->type_aux = 0;
......
#include <linux/module.h>
#include <asm/zorro.h>
#include <asm/amigatypes.h>
#include <asm/amigahw.h>
static struct symbol_table mach_amiga_symbol_table = {
#include <linux/symtab_begin.h>
......@@ -7,11 +9,16 @@ static struct symbol_table mach_amiga_symbol_table = {
/*
* 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_get_board),
X(zorro_config_board),
X(zorro_unconfig_board),
X(zorro_unused_z2ram),
/* example
X(something_you_need),
......
This diff is collapsed.
......@@ -11,7 +11,6 @@ EXTRA_CFLAGS := -Wa,-m68030
O_TARGET := atari.o
O_OBJS := config.o atakeyb.o ataints.o \
stdma.o atasound.o joystick.o stram.o atafb.o
OX_OBJS = ksyms.o
stdma.o atasound.o joystick.o stram.o atafb.o ksyms.o
include $(TOPDIR)/Rules.make
This diff is collapsed.
This diff is collapsed.
......@@ -29,10 +29,9 @@
#include <asm/atari_joystick.h>
#include <asm/irq.h>
extern int do_poke_blanked_console;
extern void process_keycode (int);
extern void handle_scancode(unsigned char);
extern int ovsc_switchmode;
unsigned char mach_keyboard_type;
extern unsigned char mach_keyboard_type;
static void atakeyb_rep( unsigned long ignore );
extern unsigned int keymap_count;
......@@ -41,7 +40,6 @@ void (*atari_MIDI_interrupt_hook) (void);
/* Hook for mouse driver */
void (*atari_mouse_interrupt_hook) (char *);
#define ATAKEY_CAPS (58)
#define BREAK_MASK (0x80)
/*
......@@ -83,6 +81,11 @@ void (*atari_mouse_interrupt_hook) (char *);
* Alt + Down -> Scroll forward console (if implemented)
* 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] = {
......@@ -98,7 +101,7 @@ static u_short ataplain_map[NR_KEYS] = {
0xf603, 0xf200, 0xf30b, 0xf601, 0xf200, 0xf602, 0xf30a, 0xf200,
0xf600, 0xf200, 0xf115, 0xf07f, 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,
0xf300, 0xf310, 0xf30e, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200
......@@ -117,7 +120,7 @@ static u_short atashift_map[NR_KEYS] = {
0xf118, 0xf200, 0xf30b, 0xf601, 0xf200, 0xf602, 0xf30a, 0xf200,
0xf119, 0xf200, 0xf115, 0xf07f, 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,
0xf300, 0xf310, 0xf30e, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200
......@@ -136,7 +139,7 @@ static u_short atactrl_map[NR_KEYS] = {
0xf603, 0xf200, 0xf30b, 0xf601, 0xf200, 0xf602, 0xf30a, 0xf200,
0xf600, 0xf200, 0xf115, 0xf07f, 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,
0xf300, 0xf310, 0xf30e, 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] = {
0xf603, 0xf200, 0xf30b, 0xf601, 0xf200, 0xf602, 0xf30a, 0xf200,
0xf600, 0xf200, 0xf115, 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,
0xf300, 0xf310, 0xf30e, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200
......@@ -174,7 +177,7 @@ static u_short ataalt_map[NR_KEYS] = {
0xf20b, 0xf200, 0xf30b, 0xf601, 0xf200, 0xf602, 0xf30a, 0xf200,
0xf20a, 0xf200, 0xf209, 0xf87f, 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,
0xf900, 0xf310, 0xf30e, 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] = {
0xf118, 0xf200, 0xf30b, 0xf601, 0xf200, 0xf602, 0xf30a, 0xf200,
0xf119, 0xf200, 0xf115, 0xf87f, 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,
0xf300, 0xf310, 0xf30e, 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] = {
0xf603, 0xf200, 0xf30b, 0xf601, 0xf200, 0xf602, 0xf30a, 0xf200,
0xf600, 0xf200, 0xf115, 0xf07f, 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,
0xf300, 0xf310, 0xf30e, 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] = {
0xf603, 0xf200, 0xf30b, 0xf601, 0xf200, 0xf602, 0xf30a, 0xf200,
0xf600, 0xf200, 0xf115, 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,
0xf300, 0xf310, 0xf30e, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200
......@@ -270,7 +273,7 @@ static void atakeyb_rep( unsigned long ignore )
{
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 */
atari_disable_irq( IRQ_MFP_ACIA );
del_timer( &atakeyb_rep_timer );
......@@ -282,7 +285,7 @@ static void atakeyb_rep( unsigned long ignore )
atakeyb_rep_timer.prev = atakeyb_rep_timer.next = NULL;
add_timer( &atakeyb_rep_timer );
process_keycode (rep_scancode);
handle_scancode(rep_scancode);
}
atari_enable_irq( IRQ_MFP_ACIA );
......@@ -306,7 +309,7 @@ static void atakeyb_rep( unsigned long ignore )
* 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;
int scancode;
......@@ -335,7 +338,7 @@ static void keyboard_interrupt(int irq, struct pt_regs *fp, void *dummy)
rep_scancode = 0;
if (IS_SYNC_CODE(scancode)) {
/* This code seem already to be the start of a new packet or a
* single keycode */
* single scancode */
kb_state.state = KEYBOARD;
goto interpret_scancode;
}
......@@ -350,6 +353,7 @@ static void keyboard_interrupt(int irq, struct pt_regs *fp, void *dummy)
if (acia_stat & ACIA_RDRF) /* received a character */
{
scancode = acia.key_data; /* get it or reset the ACIA, I'll get it! */
mark_bh(KEYBOARD_BH);
interpret_scancode:
switch (kb_state.state)
{
......@@ -398,11 +402,7 @@ static void keyboard_interrupt(int irq, struct pt_regs *fp, void *dummy)
add_timer( &atakeyb_rep_timer );
}
process_keycode( break_flag | scancode );
do_poke_blanked_console = 1;
mark_bh(CONSOLE_BH);
add_keyboard_randomness(scancode);
handle_scancode(break_flag | scancode);
break;
}
break;
......@@ -482,7 +482,7 @@ static void keyboard_interrupt(int irq, struct pt_regs *fp, void *dummy)
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
*/
goto repeat;
......@@ -775,8 +775,8 @@ int atari_keyb_init(void)
kb_state.state = KEYBOARD;
kb_state.len = 0;
add_isr(IRQ_MFP_ACIA, keyboard_interrupt, IRQ_TYPE_SLOW, NULL,
"keyboard/mouse/MIDI");
request_irq(IRQ_MFP_ACIA, keyboard_interrupt, IRQ_TYPE_SLOW,
"keyboard/mouse/MIDI", keyboard_interrupt);
atari_turnoff_irq(IRQ_MFP_ACIA);
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 <asm/ptrace.h>
#include <asm/traps.h>
......@@ -13,6 +12,7 @@ static struct symbol_table mach_atari_symbol_table = {
X(is_medusa),
X(atari_register_vme_int),
X(atari_unregister_vme_int),
X(stdma_lock),
X(stdma_release),
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