Commit 79e1fe75 authored by Linus Torvalds's avatar Linus Torvalds

Import 2.1.126pre1

parent c968c37a
......@@ -1304,7 +1304,7 @@ S: Lafayette, Indiana 47905
S: USA
N: Johan Myreen
E: jem@vipunen.hut.fi
E: jem@iki.fi
D: PS/2 mouse driver writer etc.
S: Dragonvagen 1 A 13
S: FIN-00330 Helsingfors
......@@ -1852,6 +1852,18 @@ S: Schleiermacherstrasse 12
S: 90491 Nuernberg
S: Germany
N: Geert Uytterhoeven
E: geert@linux-m68k.org
W: http://www.cs.kuleuven.ac.be/~geert/
P: 1024/EC4A1EE1 8B 88 38 35 88 1E 95 A1 CD 9E AE DC 4B 4A 2F 41
D: m68k/Amiga and PPC/CHRP Longtrail coordinator
D: Frame buffer device and XF68_FBDev maintainer
D: m68k IDE maintainer
D: Amiga Zorro maintainer
S: C. Huysmansstraat 12
S: B-3128 Baal
S: Belgium
N: Petr Vandrovec
E: vandrove@vc.cvut.cz
D: Small contributions to ncpfs
......@@ -1991,14 +2003,15 @@ S: 2612 XV Delft
S: The Netherlands
N: David Woodhouse
E: Dave@mvhi.com
E: Dave@imladris.demon.co.uk
D: Extensive ARCnet rewrite
D: ARCnet COM20020, COM90xx IO-MAP drivers
D: SO_BINDTODEVICE in 2.1.x (from Elliot Poger's code in 2.0.31)
D: Contributed to NCPFS rewrite for 2.1.x dcache
D: Alpha platforms: SX164, LX164 and Ruffian ported to 2.1.x
S: Robinson College, Grange Road
S: Cambridge. CB3 9AN
S: 29, David Bull Way
S: Milton, Cambridge. CB4 6DP
S: England
N: Frank Xia
......
This diff is collapsed.
......@@ -1196,15 +1196,6 @@ CONFIG_HUB6
Say Y here to enable support in the dumb serial driver to support
the HUB6 card.
TGA Console Support
CONFIG_TGA_CONSOLE
Many Alpha systems (e.g the Multia) are shipped with a graphics card
that implements the TGA interface (much like the VGA standard, but
older TGA adapters are *not* VGA compatible). On such systems, you
should say Y here so that the TGA driver rather than the standard
VGA driver is used. Note that, at this time, there is no X server
for these systems. If unsure, try N.
PCI support
CONFIG_PCI
Find out whether you have a PCI motherboard. PCI is the name of a
......@@ -3217,6 +3208,16 @@ CONFIG_NETLINK_DEV
This is a backward compatibility option, choose Y for now.
This option will be removed soon.
HIgh Performance Parallel Interface support (EXPERIMENTAL)
CONFIG_HIPPI
HIgh Performance Parallel Interface (HIPPI) is a 800Mbit/sec and
1600Mbit/sec dual-simplex switched or point-to-point network. HIPPI
can run over copper (25m) or fiber (300m on multi-mode or 10km on
single-mode). If you are connected to a HIPPI network, and want
to enable HIPPI support in the kernel, say Y here (you must also
remember to enable the driver for your HIPPI card below). Most
people will say N here.
SCSI support?
CONFIG_SCSI
If you want to use a SCSI hard disk, SCSI tape drive, SCSI CDROM or
......@@ -5312,7 +5313,7 @@ CONFIG_ARCNET_RIM_I
This is yet another chipset driver for the COM90xx cards, but this
time only using memory-mapped mode, and no IO ports at all. This
driver is completely untested, so if you have one of these cards,
please mail dwmw2@cam.ac.uk, especially if it works!
please mail David.Woodhouse@mvhi.com, especially if it works!
This driver is also available as a module ( = code which can be
inserted in and removed from the running kernel whenever you
......@@ -8187,7 +8188,7 @@ CONFIG_SOUND
say more than an occasional beep, by programming the PC speaker.
Kernel patches and programs to do that are in the pcsndrv package on
ftp://sunsite.unc.edu/pub/Linux/kernel/patches/console/ and in the
pcsp patch at ftp://dwmw2.robinson.cam.ac.uk/pub/kernel/ .
pcsp patch at http://www.imladris.demon.co.uk/pcsp/
OSS sound modules
CONFIG_SOUND_OSS
......@@ -9261,7 +9262,7 @@ CONFIG_TT_DMA_EMUL
Ariadne support
CONFIG_ARIADNE
If you have a VillageTronics Ariadne Ethernet adapter, say Y.
If you have a Village Tronic Ariadne Ethernet adapter, say Y.
Otherwise, say N.
This driver is also available as a module ( = code which can be
......@@ -9271,7 +9272,7 @@ CONFIG_ARIADNE
Ariadne II support
CONFIG_ARIADNE2
If you have a VillageTronics Ariadne II Ethernet adapter, say Y.
If you have a Village Tronic Ariadne II Ethernet adapter, say Y.
Otherwise, say N.
This driver is also available as a module ( = code which can be
......@@ -9745,6 +9746,46 @@ CONFIG_VIDC_SOUND
Say 'Y' here for ARM systems with the VIDC video controller and 16-bit
Linear sound DACs. If unsure, say N.
Backward compatibility mode for Xpmac
CONFIG_FB_COMPAT_XPMAC
If you use the Xpmac X server (common with mklinux), you'll need
to enable this to use X. You should consider changing to XFree86
which includes a server that supports the frame buffer device
directly (XF68_FBDev).
Support for PowerMac keyboard
CONFIG_MAC_KEYBOARD
This option allows you to use an ADB keyboard attached to your
machine. Note that this disables any other (ie. PS/2) keyboard
support, even if your machine is physically capable of using both
at the same time.
If you use an ADB keyboard (4 pin connector), say Y here.
If you use a PS/2 keyboard (6 pin connector), say N here.
Support for PowerMac floppy
CONFIG_MAC_FLOPPY
If you have a SWIM-3 (Super Woz Integrated Machine 3; from Apple)
floppy controller, say Y here. Most commonly found in PowerMacs.
Support for PowerMac serial ports
CONFIG_MAC_SERIAL
If you have Macintosh style serial ports (8 pin mini-DIN), this
is the driver for them. If you also have regular serial ports
and enable the driver for them, you can't currently use the
serial console feature.
Support for PowerMac ADB mouse
CONFIG_ADBMOUSE
If you have an ADB mouse (4 pin connector) as is common on
Macintoshes, say Y here.
Winbond SL82c105 support
CONFIG_BLK_DEV_SL82C105
If you have a Winbond SL82c105 IDE controller, say Y here to
enable special configuration for this chip. This is common
on various CHRP motherboards, but could be used elsewhere.
If in doubt, say Y.
#
# A couple of things I keep forgetting:
# capitalize: AppleTalk, Ethernet, DMA, FTP, Internet, Intel, IRQ,
......@@ -9853,7 +9894,7 @@ CONFIG_VIDC_SOUND
# LocalWords: INSNS Ataris AutoConfig ZORRO OCS AMIFB Agnus Denise ECS CDTV GB
# LocalWords: AGA Cybervision CYBER GSP TMS DMI Zorro ACSI ROMs SLM BioNet GVP
# LocalWords: PAMsNet TekMagic Cyberstorm MkI CYBERSTORMII MkII BLZ onboard cx
# LocalWords: VillageTronics ATARILANCE RieblCard PAMCard VME MFP sangoma LAPB
# LocalWords: Village Tronic ATARILANCE RieblCard PAMCard VME MFP sangoma LAPB
# LocalWords: Rhotron BioData's Multiface AMIGAMOUSE COPCON Amiga's bitplanes
# LocalWords: ATARIMOUSE MFPSER SCC's MegaSTE ESCC Atari's GVPIOEXT DMASOUND
# LocalWords: fdutils cisco univercd rpcg htm iface lapb LAPBETHER tpqic qic
......
......@@ -11,4 +11,5 @@ smp.txt
- use and state info about Linux/PPC on MP machines
sound.txt
- info on sound support under Linux/PPC
zImage_layout.txt
- info on the kernel images for Linux/PPC
......@@ -5,7 +5,7 @@ This document and the related code was written by me
(Cort Dougan, cort@cs.nmt.edu) please email me if you have questions,
comments or corrections.
Last Change: 4.1.98
Last Change: 10.8.98
SMP support for Linux/PPC is still in its early stages and likely to
be buggy for a while. If you want to help by writing code or testing
......@@ -13,7 +13,7 @@ different hardware please email me!
1. State of Supported Hardware
PowerSurge Architecture - UMAX s900, Apple 9500/9600/8500/8600/7500/7600
PowerSurge Architecture - tested on UMAX s900, Apple 9600
The second processor on this machine boots up just fine and
enters its idle loop. Hopefully a completely working SMP kernel
on this machine will be done shortly.
......@@ -22,7 +22,9 @@ different hardware please email me!
necessary to work with any number would not be overly difficult but
I don't have any machines with >2 processors so it's not high on my
list of priorities. If anyone else would like do to the work email
me and I can point out the places that need changed.
me and I can point out the places that need changed. If you have >2
processors and don't want to add support yourself let me know and I
can take a look into it.
BeBox
BeBox support hasn't been added to the 2.1.X kernels from 2.0.X
......
Information about PowerPC Sound support
=====================================================================
Please mail me me (Cort Dougan, cort@cs.nmt.edu) if you have questions,
Please mail me (Cort Dougan, cort@cs.nmt.edu) if you have questions,
comments or corrections.
Last Change: 3.24.98
......
Information about the Linux/PPC kernel images
=====================================================================
Please mail me me (Cort Dougan, cort@cs.nmt.edu) if you have questions,
comments or corrections.
This document is meant to answer several questions I've had about how
the PReP system boots and how Linux/PPC interacts with that mechanism.
It would be nice if we could have information on how other architectures
boot here as well. If you have anything to contribute, please
let me know.
1. PReP boot file
This is the file necessary to boot PReP systems from floppy or
hard drive. The firmware reads the PReP partition table entry
and will load the image accordingly.
To boot the zImage, copy it onto a floppy with dd if=zImage of=/dev/fd0h1440
or onto a PReP hard drive partition with dd if=zImage of=/dev/sda4
assuming you've created a PReP partition (type 0x41) with fdisk on
/dev/sda4.
The layout of the image format is:
0x0 +------------+
| | PReP partition table entry
| |
0x400 +------------+
| | Bootstrap program code + data
| |
| |
+------------+
| | compressed kernel, elf header removed
+------------+
| | initrd (if loaded)
+------------+
| | Elf section table for bootstrap program
+------------+
2. MBX boot file
The MBX boards can load an elf image, and relocate it to the
proper location in memory - it copies the image to the location it was
linked at.
This diff is collapsed.
......@@ -16,7 +16,8 @@ trivial patch so apply some common sense.
SMC etherpower for that.)
3. Make sure your changes compile correctly in multiple
configurations.
configurations. In paticular check changes work both as a module
and built into the kernel.
4. When you are happy with a change make it generally available for
testing and await feedback.
......@@ -28,7 +29,8 @@ trivial patch so apply some common sense.
job the maintainers (and especially Linus) do is to keep things
looking the same. Sometimes this means that the clever hack in
your driver to get around a problem actual needs to become a
generalized kernel feature ready for next time.
generalized kernel feature ready for next time. See
Documentation/CodingStyle for guidance here.
PLEASE try to include any credit lines you want added with the
patch. It avoids people being missed off by mistake and makes
......@@ -240,6 +242,11 @@ M: Philip.Blundell@pobox.com
L: linux-net@vger.rutgers.edu
S: Maintained
ETHERTEAM 16I DRIVER
P: Mika Kuoppala
M: miku@iki.fi
S: Maintained
EXT2 FILE SYSTEM
P: Remy Card
M: Remy.Card@linux.org
......@@ -303,6 +310,12 @@ M: oe1kib@oe1kib.ampr.org
L: linux-hams@vger.rutgers.edu
S: Maintained
HIPPI
P: Jes Sorensen
M: Jes.Sorensen@cern.ch
L: linux-hippi@sunsite.auc.dk
S: Maintained
HP100: Driver for HP 10/100 Mbit/s Voice Grade Network Adapter Series
P: Jaroslav Kysela
M: perex@jcu.cz
......@@ -702,6 +715,12 @@ M: eis@baty.hanse.de
L: linux-x25@vger.rutgers.edu
S: Maintained
Z85230 SYNCHRONOUS DRIVER
P: Alan Cox
M: alan@redhat.com
W: http://roadrunner.swansea.linux.org.uk/synchronous.shtml
S: Maintained
Z8530 DRIVER FOR AX.25
P: Joerg Reuter
M: jreuter@poboxes.com
......@@ -710,7 +729,6 @@ W: http://qsl.net/dl1bke/
L: linux-hams@vger.rutgers.edu
S: Maintained
REST:
P: Linus Torvalds
S: Buried alive in diapers
......@@ -96,15 +96,6 @@ 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
directories are just symlinks to the kernel sources:
cd /usr/include
rm -rf asm linux scsi
ln -s /usr/src/linux/include/asm-i386 asm
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:
cd /usr/src/linux
......
......@@ -19,17 +19,23 @@ old_gas := $(shell if $(AS) --version 2>&1 | grep 'version 2.7' > /dev/null; the
# Determine if GCC understands the -mcpu= option.
have_mcpu := $(shell if $(CC) -mcpu=ev5 -S -o /dev/null -xc /dev/null > /dev/null 2>&1; then echo y; else echo n; fi)
# If GENERIC, make sure to turn off any instruction set extensions that
# the host compiler might have on by default. Given that EV4 and EV5
# have the same instruction set, prefer EV5 because an EV5 schedule is
# more likely to keep an EV4 processor busy than vice-versa.
ifeq ($(CONFIG_ALPHA_GENERIC)$(have_mcpu),yy)
CFLAGS := $(CFLAGS) -mcpu=ev5
endif
# If EV6, turn on the proper optimizations.
ifeq ($(CONFIG_ALPHA_EV6)$(have_mcpu),yy)
CFLAGS := $(CFLAGS) -mcpu=ev6
# Turn on the proper cpu optimizations.
ifeq ($(have_mcpu),y)
# If GENERIC, make sure to turn off any instruction set extensions that
# the host compiler might have on by default. Given that EV4 and EV5
# have the same instruction set, prefer EV5 because an EV5 schedule is
# more likely to keep an EV4 processor busy than vice-versa.
ifeq ($(CONFIG_ALPHA_GENERIC),y)
CFLAGS := $(CFLAGS) -mcpu=ev5
endif
ifeq ($(CONFIG_ALPHA_EV4),y)
CFLAGS := $(CFLAGS) -mcpu=ev4
endif
# Leave out EV5, since it is too hard to figure out whether we
# should use EV56 insns or not.
ifeq ($(CONFIG_ALPHA_EV6),y)
CFLAGS := $(CFLAGS) -mcpu=ev6
endif
endif
# For TSUNAMI, we must have the assembler not emulate our instructions.
......
......@@ -36,7 +36,10 @@ bootimage: tools/mkbb tools/lxboot tools/bootlx vmlinux.nh
tools/mkbb bootimage tools/lxboot
bootpfile: tools/bootph vmlinux.nh
( cat tools/bootph vmlinux.nh ) > bootpfile
cat tools/bootph vmlinux.nh > bootpfile
ifdef INITRD
cat $(INITRD) >> bootpfile
endif
srmboot: bootdevice bootimage
dd if=bootimage of=$(BOOTDEV) bs=512 seek=1 skip=1
......@@ -48,15 +51,18 @@ bootdevice:
vmlinux.gz: vmlinux
gzip -fv9 vmlinux
#
# A raw binary without header. Used by raw boot.
#
main.o: ksize.h
bootp.o: ksize.h
ksize.h: $(OBJSTRIP) vmlinux.nh
echo "#define KERNEL_SIZE `$(OBJSTRIP) -p vmlinux.nh /dev/null`" > $@
ksize.h: vmlinux.nh dummy
echo "#define KERNEL_SIZE `ls -l vmlinux.nh | awk '{print $$5}'`" > $@T
ifdef INITRD
[ -f $(INITRD) ] || exit 1
echo "#define INITRD_SIZE `ls -l $(INITRD) | awk '{print $$5}'`" >> $@T
endif
cmp -s $@T $@ || mv -f $@T $@
rm -f $@T
vmlinux.nh: $(VMLINUX) $(OBJSTRIP)
$(OBJSTRIP) -v $(VMLINUX) vmlinux.nh
......@@ -91,3 +97,5 @@ clean:
rm -f vmlinux.nh ksize.h
dep:
dummy:
......@@ -22,74 +22,30 @@
#include "ksize.h"
extern int vsprintf(char *, const char *, va_list);
extern unsigned long switch_to_osf_pal(unsigned long nr,
struct pcb_struct * pcb_va, struct pcb_struct * pcb_pa,
unsigned long vptb, unsigned long *kstk);
unsigned long *vptb);
extern long dispatch(long code, ...);
static void
puts(const char *str, int len)
{
long written;
while (len > 0) {
written = dispatch(CCB_PUTS, 0, str, len);
if (written < 0)
break;
len -= (unsigned int) written;
str += (unsigned int) written;
}
}
int printk(const char * fmt, ...)
{
va_list args;
int i, j, remaining, num_nl;
static char buf[1024];
va_start(args, fmt);
i = vsprintf(buf, fmt, args);
va_end(args);
/* expand \n into \r\n: */
num_nl = 0;
for (j = 0; j < i; ++j) {
if (buf[j] == '\n')
++num_nl;
}
remaining = i + num_nl;
for (j = i - 1; j >= 0; --j) {
buf[j + num_nl] = buf[j];
if (buf[j] == '\n') {
--num_nl;
buf[j + num_nl] = '\r';
}
}
puts(buf, remaining);
return i;
}
#define hwrpb (*INIT_HWRPB)
struct hwrpb_struct *hwrpb = INIT_HWRPB;
static struct pcb_struct pcb_va[1];
/*
* Find a physical address of a virtual object..
*
* This is easy using the virtual page table address.
*/
struct pcb_struct * find_pa(unsigned long *vptb, struct pcb_struct * pcb)
static inline void *
find_pa(unsigned long *vptb, void *ptr)
{
unsigned long address = (unsigned long) pcb;
unsigned long address = (unsigned long) ptr;
unsigned long result;
result = vptb[address >> 13];
result >>= 32;
result <<= 13;
result |= address & 0x1fff;
return (struct pcb_struct *) result;
return (void *) result;
}
/*
......@@ -101,31 +57,19 @@ struct pcb_struct * find_pa(unsigned long *vptb, struct pcb_struct * pcb)
* code has the L1 page table identity-map itself in the second PTE
* in the L1 page table. Thus the L1-page is virtually addressable
* itself (through three levels) at virtual address 0x200802000.
*
* As we don't want it there anyway, we also move the L1 self-map
* up as high as we can, so that the last entry in the L1 page table
* maps the page tables.
*
* As a result, the OSF/1 pal-code will instead use a virtual page table
* map located at 0xffffffe00000000.
*/
#define pcb_va ((struct pcb_struct *) 0x20000000)
#define old_vptb (0x0000000200000000UL)
#define new_vptb (0xfffffffe00000000UL)
void pal_init(void)
#define VPTB ((unsigned long *) 0x200000000)
#define L1 ((unsigned long *) 0x200802000)
void
pal_init(void)
{
unsigned long i, rev, sum;
unsigned long *L1, *l;
unsigned long i, rev;
struct percpu_struct * percpu;
struct pcb_struct * pcb_pa;
/* Find the level 1 page table and duplicate it in high memory */
L1 = (unsigned long *) 0x200802000UL; /* (1<<33 | 1<<23 | 1<<13) */
L1[1023] = L1[1];
percpu = (struct percpu_struct *)
(hwrpb.processor_offset + (unsigned long) &hwrpb),
/* Create the dummy PCB. */
pcb_va->ksp = 0;
pcb_va->usp = 0;
pcb_va->ptbr = L1[1] >> 32;
......@@ -133,58 +77,45 @@ void pal_init(void)
pcb_va->pcc = 0;
pcb_va->unique = 0;
pcb_va->flags = 1;
pcb_pa = find_pa((unsigned long *) old_vptb, pcb_va);
printk("Switching to OSF PAL-code .. ");
pcb_va->res1 = 0;
pcb_va->res2 = 0;
pcb_pa = find_pa(VPTB, pcb_va);
/*
* a0 = 2 (OSF)
* a1 = return address, but we give the asm the vaddr of the PCB
* a2 = physical addr of PCB
* a3 = new virtual page table pointer
* a4 = KSP (but we give it 0, asm sets it)
* a4 = KSP (but the asm sets it)
*/
i = switch_to_osf_pal(
2,
pcb_va,
pcb_pa,
new_vptb,
0);
srm_printk("Switching to OSF PAL-code .. ");
i = switch_to_osf_pal(2, pcb_va, pcb_pa, VPTB);
if (i) {
printk("failed, code %ld\n", i);
srm_printk("failed, code %ld\n", i);
halt();
}
rev = percpu->pal_revision = percpu->palcode_avail[2];
hwrpb.vptb = new_vptb;
/* update checksum: */
sum = 0;
for (l = (unsigned long *) &hwrpb;
l < (unsigned long *) &hwrpb.chksum;
++l)
sum += *l;
hwrpb.chksum = sum;
percpu = (struct percpu_struct *)
(INIT_HWRPB->processor_offset + (unsigned long) INIT_HWRPB);
rev = percpu->pal_revision = percpu->palcode_avail[2];
printk("Ok (rev %lx)\n", rev);
/* remove the old virtual page-table mapping */
L1[1] = 0;
srm_printk("Ok (rev %lx)\n", rev);
tbia(); /* do it directly in case we are SMP */
}
static inline long load(unsigned long dst,
unsigned long src,
unsigned long count)
static inline void
load(unsigned long dst, unsigned long src, unsigned long count)
{
extern void * memcpy(void *, const void *, size_t);
memcpy((void *)dst, (void *)src, count);
return count;
}
/*
* Start the kernel.
*/
static void runkernel(void)
static inline void
runkernel(void)
{
__asm__ __volatile__(
"bis %1,%1,$30\n\t"
......@@ -199,65 +130,82 @@ extern char _end;
#define KERNEL_ORIGIN \
((((unsigned long)&_end) + 511) & ~511)
void start_kernel(void)
void
start_kernel(void)
{
static long i;
static int nbytes;
/*
* note that this crufty stuff with static and envval and envbuf
* is because:
* Note that this crufty stuff with static and envval
* and envbuf is because:
*
* 1. frequently, the stack is is short, and we don't want to overrun;
* 2. frequently the stack is where we are going to copy the kernel to;
* 3. a certain SRM console required the GET_ENV output to stack.
* 1. Frequently, the stack is short, and we don't want to overrun;
* 2. Frequently the stack is where we are going to copy the kernel to;
* 3. A certain SRM console required the GET_ENV output to stack.
* ??? A comment in the aboot sources indicates that the GET_ENV
* destination must be quadword aligned. Might this explain the
* behaviour, rather than requiring output to the stack, which
* seems rather far-fetched.
*/
static char envval[256];
char envbuf[256];
static long nbytes;
static char envval[256] __attribute__((aligned(8)));
#ifdef INITRD_SIZE
static unsigned long initrd_start;
#endif
printk("Linux/AXP bootp loader for Linux " UTS_RELEASE "\n");
if (hwrpb.pagesize != 8192) {
printk("Expected 8kB pages, got %ldkB\n",
hwrpb.pagesize >> 10);
srm_printk("Linux/AXP bootp loader for Linux " UTS_RELEASE "\n");
if (INIT_HWRPB->pagesize != 8192) {
srm_printk("Expected 8kB pages, got %ldkB\n",
INIT_HWRPB->pagesize >> 10);
return;
}
if (INIT_HWRPB->vptb != (unsigned long) VPTB) {
srm_printk("Expected vptb at %p, got %p\n",
VPTB, (void *)INIT_HWRPB->vptb);
return;
}
pal_init();
nbytes = dispatch(CCB_GET_ENV, ENV_BOOTED_OSFLAGS,
envbuf, sizeof(envbuf));
if (nbytes < 0 || nbytes >= sizeof(envbuf)) {
#ifdef INITRD_SIZE
/* The initrd must be page-aligned. See below for the
cause of the magic number 5. */
initrd_start = ((START_ADDR + 5*KERNEL_SIZE) | (PAGE_SIZE-1)) + 1;
srm_printk("Initrd positioned at %#lx\n", initrd_start);
#endif
nbytes = srm_dispatch(CCB_GET_ENV, ENV_BOOTED_OSFLAGS,
envval, sizeof(envval));
if (nbytes < 0 || nbytes >= sizeof(envval)) {
nbytes = 0;
}
envbuf[nbytes] = '\0';
memcpy(envval, envbuf, nbytes+1);
printk("Loading the kernel...'%s'\n", envval);
envval[nbytes] = '\0';
srm_printk("Loading the kernel...'%s'\n", envval);
/* NOTE: *no* callbacks or printouts from here on out!!! */
#if 1
/*
* this is a hack, as some consoles seem to get virtual 20000000
* This is a hack, as some consoles seem to get virtual 20000000
* (ie where the SRM console puts the kernel bootp image) memory
* overlapping physical 310000 memory, which causes real problems
* when attempting to copy the former to the latter... :-(
*
* so, we first move the kernel virtual-to-physical way above where
* So, we first move the kernel virtual-to-physical way above where
* we physically want the kernel to end up, then copy it from there
* to its final resting place... ;-}
*
* sigh...
* Sigh...
*/
i = load(START_ADDR+(4*KERNEL_SIZE), KERNEL_ORIGIN, KERNEL_SIZE);
i = load(START_ADDR, START_ADDR+(4*KERNEL_SIZE), KERNEL_SIZE);
#else
i = load(START_ADDR, KERNEL_ORIGIN, KERNEL_SIZE);
#ifdef INITRD_SIZE
load(initrd_start, KERNEL_ORIGIN+KERNEL_SIZE, INITRD_SIZE);
#endif
load(START_ADDR+(4*KERNEL_SIZE), KERNEL_ORIGIN, KERNEL_SIZE);
load(START_ADDR, START_ADDR+(4*KERNEL_SIZE), KERNEL_SIZE);
memset((char*)ZERO_PAGE, 0, PAGE_SIZE);
strcpy((char*)ZERO_PAGE, envval);
#ifdef INITRD_SIZE
((long *)(ZERO_PAGE+256))[0] = initrd_start;
((long *)(ZERO_PAGE+256))[1] = INITRD_SIZE;
#endif
runkernel();
for (i = 0 ; i < 0x100000000 ; i++)
/* nothing */;
halt();
}
......@@ -6,28 +6,22 @@
#include <asm/system.h>
#define halt .long PAL_halt
.set noreorder
.globl __start
.ent __start
__start:
bis $31,$31,$31
br 1f
/* room for the initial PCB, which comes here */
.quad 0,0,0,0,0,0,0,0
1: br $27,2f
2: ldgp $29,0($27)
lda $27,start_kernel
jsr $26,($27),start_kernel
halt
br $29,2f
2: ldgp $29,0($29)
jsr $26,start_kernel
call_pal PAL_halt
.end __start
.align 5
.globl wrent
.ent wrent
wrent:
.long PAL_wrent
.prologue 0
call_pal PAL_wrent
ret ($26)
.end wrent
......@@ -35,7 +29,8 @@ wrent:
.globl wrkgp
.ent wrkgp
wrkgp:
.long PAL_wrkgp
.prologue 0
call_pal PAL_wrkgp
ret ($26)
.end wrkgp
......@@ -44,6 +39,7 @@ wrkgp:
.ent switch_to_osf_pal
switch_to_osf_pal:
subq $30,128,$30
.frame $30,128,$26
stq $26,0($30)
stq $1,8($30)
stq $2,16($30)
......@@ -60,11 +56,12 @@ switch_to_osf_pal:
stq $13,104($30)
stq $14,112($30)
stq $15,120($30)
.prologue 0
stq $30,0($17) /* save KSP in PCB */
bis $30,$30,$20 /* a4 = KSP */
br $17,__do_swppal
br $17,1f
ldq $26,0($30)
ldq $1,8($30)
......@@ -84,56 +81,22 @@ switch_to_osf_pal:
ldq $15,120($30)
addq $30,128,$30
ret ($26)
__do_swppal:
.long PAL_swppal
1: call_pal PAL_swppal
.end switch_to_osf_pal
.globl dispatch
.ent dispatch
dispatch:
subq $30,80,$30
stq $26,0($30)
stq $29,8($30)
stq $8,16($30)
stq $9,24($30)
stq $10,32($30)
stq $11,40($30)
stq $12,48($30)
stq $13,56($30)
stq $14,64($30)
stq $15,72($30)
lda $1,0x10000000 /* hwrpb */
ldq $2,0xc0($1) /* crb offset */
addq $2,$1,$2 /* crb */
ldq $27,0($2) /* dispatch procedure value */
ldq $2,8($27) /* dispatch call address */
jsr $26,($2) /* call it (weird VMS call seq) */
ldq $26,0($30)
ldq $29,8($30)
ldq $8,16($30)
ldq $9,24($30)
ldq $10,32($30)
ldq $11,40($30)
ldq $12,48($30)
ldq $13,56($30)
ldq $14,64($30)
ldq $15,72($30)
addq $30,80,$30
ret $31,($26)
.end dispatch
.align 3
.globl tbi
.ent tbi
tbi:
.long PAL_tbi
.prologue 0
call_pal PAL_tbi
ret ($26)
.end tbi
.align 3
.globl halt
.ent halt
halt:
.prologue 0
call_pal PAL_halt
.end halt
......@@ -175,8 +175,6 @@ then
define_bool CONFIG_ALPHA_AVANTI y
fi
#bool 'Echo console messages on /dev/ttyS0 (COM1)' CONFIG_SERIAL_ECHO
if [ "$CONFIG_PCI" = "y" ]; then
bool 'PCI quirks' CONFIG_PCI_QUIRKS
if [ "$CONFIG_PCI_QUIRKS" = "y" -a "$CONFIG_EXPERIMENTAL" = "y" ]; then
......
......@@ -136,6 +136,37 @@ EXPORT_SYMBOL_NOVERS(__do_clear_user);
EXPORT_SYMBOL(__strncpy_from_user);
EXPORT_SYMBOL(__strlen_user);
/*
* SMP-specific symbols.
*/
#ifdef __SMP__
EXPORT_SYMBOL(synchronize_irq);
EXPORT_SYMBOL(flush_tlb_all);
EXPORT_SYMBOL(flush_tlb_mm);
EXPORT_SYMBOL(flush_tlb_page);
EXPORT_SYMBOL(flush_tlb_range);
EXPORT_SYMBOL(cpu_data);
EXPORT_SYMBOL(cpu_number_map);
EXPORT_SYMBOL(global_bh_lock);
EXPORT_SYMBOL(global_bh_count);
EXPORT_SYMBOL(synchronize_bh);
EXPORT_SYMBOL(global_irq_holder);
EXPORT_SYMBOL(__global_cli);
EXPORT_SYMBOL(__global_sti);
EXPORT_SYMBOL(__global_save_flags);
EXPORT_SYMBOL(__global_restore_flags);
#if DEBUG_SPINLOCK
EXPORT_SYMBOL(spin_unlock);
EXPORT_SYMBOL(spin_lock);
EXPORT_SYMBOL(spin_trylock);
#endif
#if DEBUG_RWLOCK
EXPORT_SYMBOL(write_lock);
EXPORT_SYMBOL(read_lock);
#endif
#endif /* __SMP__ */
/*
* The following are special because they're not called
* explicitly (the C compiler or assembler generates them in
......
......@@ -524,16 +524,8 @@ layout_dev(struct pci_dev *dev)
size = (mask & base) & 0xffffffff;
switch (type) {
case PCI_BASE_ADDRESS_MEM_TYPE_32:
break;
case PCI_BASE_ADDRESS_MEM_TYPE_64:
printk("bios32 WARNING: "
"ignoring 64-bit device in "
"slot %d, function %d: \n",
PCI_SLOT(dev->devfn),
PCI_FUNC(dev->devfn));
idx++; /* skip extra 4 bytes */
continue;
break;
case PCI_BASE_ADDRESS_MEM_TYPE_1M:
/*
......@@ -594,6 +586,29 @@ layout_dev(struct pci_dev *dev)
off, base);
handle = PCI_HANDLE(bus->number) | base;
dev->base_address[idx] = handle;
/*
* Currently for 64-bit cards, we simply do the usual
* for setup of the first register (low) of the pair,
* and then clear out the second (high) register, as
* we are not yet able to do 64-bit addresses, and
* setting the high register to 0 allows 32-bit SAC
* addresses to be used.
*/
if (type == PCI_BASE_ADDRESS_MEM_TYPE_64) {
pcibios_write_config_dword(bus->number,
dev->devfn,
off+4, 0);
/* Bypass hi reg in the loop. */
dev->base_address[++idx] = 0;
printk("bios32 WARNING: "
"handling 64-bit device in "
"slot %d, function %d: \n",
PCI_SLOT(dev->devfn),
PCI_FUNC(dev->devfn));
}
DBG_DEVS(("layout_dev: dev 0x%x MEM @ 0x%lx (0x%x)\n",
dev->device, handle, size));
}
......@@ -692,36 +707,46 @@ layout_bus(struct pci_bus *bus)
struct pci_dev *bridge = bus->self;
DBG_DEVS(("layout_bus: config bus %d bridge\n", bus->number));
/*
* Set up the top and bottom of the PCI I/O segment
* for this bus.
*/
pcibios_read_config_dword(bridge->bus->number, bridge->devfn,
0x1c, &l);
PCI_IO_BASE, &l);
l &= 0xffff0000;
l |= ((bio >> 8) & 0x00f0) | ((tio - 1) & 0xf000);
pcibios_write_config_dword(bridge->bus->number, bridge->devfn,
0x1c, l);
PCI_IO_BASE, l);
/* Also clear out the upper 16 bits. */
pcibios_write_config_dword(bridge->bus->number, bridge->devfn,
PCI_IO_BASE_UPPER16, 0);
/*
* Set up the top and bottom of the PCI Memory segment
* for this bus.
*/
l = ((bmem & 0xfff00000) >> 16) | ((tmem - 1) & 0xfff00000);
pcibios_write_config_dword(bridge->bus->number, bridge->devfn,
0x20, l);
PCI_MEMORY_BASE, l);
/*
* Turn off downstream PF memory address range:
*/
pcibios_write_config_dword(bridge->bus->number, bridge->devfn,
0x24, 0x0000ffff);
PCI_PREF_MEMORY_BASE, 0x0000ffff);
/*
* Tell bridge that there is an ISA bus in the system,
* and (possibly) a VGA as well.
*/
/* ??? This appears to be a single-byte write into MIN_GNT.
What is up with this? */
l = 0x00040000; /* ISA present */
if (found_vga) l |= 0x00080000; /* VGA present */
pcibios_write_config_dword(bridge->bus->number, bridge->devfn,
0x3c, l);
/*
* Clear status bits, enable I/O (for downstream I/O),
* turn on master enable (for upstream I/O), turn on
......@@ -729,7 +754,7 @@ layout_bus(struct pci_bus *bus)
* master enable (for upstream memory and I/O).
*/
pcibios_write_config_dword(bridge->bus->number, bridge->devfn,
0x4, 0xffff0007);
PCI_COMMAND, 0xffff0007);
}
DBG_DEVS(("layout_bus: bus %d finished\n", bus->number));
return found_vga;
......
......@@ -99,33 +99,13 @@ static int
mk_conf_addr(u8 bus, u8 device_fn, u8 where, unsigned long *pci_addr,
unsigned char *type1)
{
unsigned long addr;
*type1 = (bus == 0) ? 0 : 1;
*pci_addr = (bus << 16) | (device_fn << 8) | (where);
DBG_CNF(("mk_conf_addr(bus=%d ,device_fn=0x%x, where=0x%x,"
" pci_addr=0x%p, type1=0x%p)\n",
bus, device_fn, where, pci_addr, type1));
if (bus == 0) {
int device;
device = device_fn >> 3;
/* Type 0 configuration cycle. */
#if NOT_NOW
if (device > 20) {
DBG_CNF(("mk_conf_addr: device (%d) > 20, return -1\n",
device));
return -1;
}
#endif
*type1 = 0;
addr = (device_fn << 8) | (where);
} else {
/* Type 1 configuration cycle. */
*type1 = 1;
addr = (bus << 16) | (device_fn << 8) | (where);
}
*pci_addr = addr;
DBG_CNF(("mk_conf_addr: returning pci_addr 0x%lx\n", addr));
" returning address 0x%p\n"
bus, device_fn, where, *pci_addr));
return 0;
}
......@@ -142,12 +122,11 @@ conf_read(unsigned long addr, unsigned char type1)
stat0 = *(vuip)PYXIS_ERR;
*(vuip)PYXIS_ERR = stat0; mb();
temp = *(vuip)PYXIS_ERR; /* re-read to force write */
DBG_CNF(("conf_read: PYXIS ERR was 0x%x\n", stat0));
/* If Type1 access, must set PYXIS CFG. */
if (type1) {
pyxis_cfg = *(vuip)PYXIS_CFG;
*(vuip)PYXIS_CFG = pyxis_cfg | 1; mb();
*(vuip)PYXIS_CFG = (pyxis_cfg & ~3L) | 1; mb();
temp = *(vuip)PYXIS_CFG; /* re-read to force write */
}
......@@ -172,14 +151,15 @@ conf_read(unsigned long addr, unsigned char type1)
/* If Type1 access, must reset IOC CFG so normal IO space ops work. */
if (type1) {
*(vuip)PYXIS_CFG = pyxis_cfg & ~1; mb();
*(vuip)PYXIS_CFG = pyxis_cfg & ~3L; mb();
temp = *(vuip)PYXIS_CFG; /* re-read to force write */
}
__restore_flags(flags);
DBG_CNF(("conf_read(addr=0x%lx, type1=%d) = %#x\n",
addr, type1, value));
__restore_flags(flags);
return value;
}
......@@ -190,9 +170,6 @@ conf_write(unsigned long addr, unsigned int value, unsigned char type1)
unsigned int stat0, temp;
unsigned int pyxis_cfg = 0;
DBG_CNF(("conf_write(addr=%#lx, value=%#x, type1=%d)\n",
addr, value, type1));
__save_and_cli(flags); /* avoid getting hit by machine check */
/* Reset status register to avoid losing errors. */
......@@ -203,7 +180,7 @@ conf_write(unsigned long addr, unsigned int value, unsigned char type1)
/* If Type1 access, must set PYXIS CFG. */
if (type1) {
pyxis_cfg = *(vuip)PYXIS_CFG;
*(vuip)PYXIS_CFG = pyxis_cfg | 1; mb();
*(vuip)PYXIS_CFG = (pyxis_cfg & ~3L) | 1; mb();
temp = *(vuip)PYXIS_CFG; /* re-read to force write */
}
......@@ -216,18 +193,20 @@ conf_write(unsigned long addr, unsigned int value, unsigned char type1)
/* Access configuration space. */
*(vuip)addr = value;
mb();
mb(); /* magic */
temp = *(vuip)PYXIS_ERR; /* do a PYXIS read to force the write */
temp = *(vuip)addr; /* read back to force the write */
PYXIS_mcheck_expected = 0;
mb();
/* If Type1 access, must reset IOC CFG so normal IO space ops work. */
if (type1) {
*(vuip)PYXIS_CFG = pyxis_cfg & ~1; mb();
*(vuip)PYXIS_CFG = pyxis_cfg & ~3L; mb();
temp = *(vuip)PYXIS_CFG; /* re-read to force write */
}
__restore_flags(flags);
DBG_CNF(("conf_write(addr=%#lx, value=%#x, type1=%d)\n",
addr, value, type1));
}
int
......
......@@ -552,7 +552,6 @@ entSys:
ret_from_sys_call:
cmovne $26,0,$19 /* $19 = 0 => non-restartable */
/* check bottom half interrupts */
bne $1,ret_from_handle_bh
ldq $3,bh_active
ldq $4,bh_mask
and $3,$4,$2
......@@ -678,7 +677,7 @@ signal_return:
bis $30,$30,$18
bis $31,$31,$16
jsr $26,do_signal
lda $30,SWITCH_STACK_SIZE($30)
bsr $1,undo_switch_stack
br $31,restore_all
.end entSys
......
......@@ -9,8 +9,6 @@
#include <asm/system.h>
#define halt call_pal PAL_halt
.globl swapper_pg_dir
.globl _stext
swapper_pg_dir=SWAPPER_PGD
......@@ -29,28 +27,28 @@ __start:
lda $30,0x4000($8)
/* ... and then we can start the kernel. */
jsr $26,start_kernel
halt
call_pal PAL_halt
.end __start
#ifdef __SMP__
.align 3
.globl __start_cpu
.ent __start_cpu
/* on entry here from SRM console, the HWPCB of this processor */
/* has been loaded, and $27 contains the task pointer */
/* On entry here from SRM console, the HWPCB of this processor
has been loaded, and $27 contains the task pointer */
__start_cpu:
.prologue 0
/* first order of business, load the GP */
/* First order of business, load the GP */
br $26,1f
1: ldgp $29,0($26)
/* We need to get current loaded up with our first task... */
lda $8,0($27)
/* set FEN */
mov $27,$8
/* Set FEN */
lda $16,1($31)
call_pal PAL_wrfen
/* ... and then we can start the processor. */
jsr $26,start_secondary
halt
call_pal PAL_halt
.end __start_cpu
#endif /* __SMP__ */
......@@ -121,10 +119,20 @@ whami:
.globl wripir
.ent wripir
wripir:
.prologue 0
call_pal PAL_wripir
ret ($26)
.end wripir
.align 3
.globl wrvptptr
.ent wrvptptr
wrvptptr:
.prologue 0
call_pal PAL_wrvptptr
ret ($26)
.end wrvptptr
#
# The following two functions are needed for supporting SRM PALcode
# on the PC164 (at least), since that PALcode manages the interrupt
......@@ -152,3 +160,17 @@ cserve_dis:
call_pal PAL_cserve
ret ($26)
.end cserve_dis
#
# It is handy, on occasion, to make halt actually just loop.
# Putting it here means we dont have to recompile the whole
# kernel.
#
.align 3
.globl halt
.ent halt
halt:
.prologue 0
call_pal PAL_halt
.end halt
......@@ -311,26 +311,41 @@ free_irq(unsigned int irq, void *dev_id)
int get_irq_list(char *buf)
{
int i, len = 0;
int i, j;
struct irqaction * action;
int cpu = smp_processor_id();
char *p = buf;
#ifdef __SMP__
p += sprintf(p, " ");
for (j = 0; j < smp_num_cpus; j++)
p += sprintf(p, "CPU%d ", j);
*p++ = '\n';
#endif
for (i = 0; i < NR_IRQS; i++) {
action = irq_action[i];
if (!action)
continue;
len += sprintf(buf+len, "%2d: %10u %c %s",
i, kstat.irqs[cpu][i],
(action->flags & SA_INTERRUPT) ? '+' : ' ',
action->name);
p += sprintf(p, "%3d: ",i);
#ifndef __SMP__
p += sprintf(p, "%10u ", kstat_irqs(i));
#else
for (j = 0; j < smp_num_cpus; j++)
p += sprintf(p, "%10u ",
kstat.irqs[cpu_logical_map(j)][i]);
#endif
p += sprintf(p, " %c%s",
(action->flags & SA_INTERRUPT)?'+':' ',
action->name);
for (action=action->next; action; action = action->next) {
len += sprintf(buf+len, ", %s%s",
(action->flags & SA_INTERRUPT) ? "+":"",
action->name);
p += sprintf(p, ", %c%s",
(action->flags & SA_INTERRUPT)?'+':' ',
action->name);
}
len += sprintf(buf+len, "\n");
*p++ = '\n';
}
return len;
return p - buf;
}
#ifdef __SMP__
......@@ -427,8 +442,10 @@ get_irqlock(int cpu, void* where)
/*
* Finally.
*/
#if DEBUG_SPINLOCK
global_irq_lock.task = current;
global_irq_lock.previous = where;
#endif
global_irq_holder = cpu;
previous_irqholder = where;
}
......
......@@ -11,12 +11,8 @@
#define STANDARD_INIT_IRQ_PROLOG \
outb(0, DMA1_RESET_REG); \
outb(0, DMA2_RESET_REG); \
outb(0, DMA1_MASK_REG); \
outb(0, DMA2_MASK_REG); \
outb(0, DMA1_CLR_MASK_REG); \
outb(0, DMA2_CLR_MASK_REG); \
outb(DMA_MODE_CASCADE, DMA2_MODE_REG)
outb(0, DMA2_CLR_MASK_REG)
extern unsigned long alpha_irq_mask;
......
......@@ -27,8 +27,7 @@
#define CAT1(x,y) x##y
#define CAT(x,y) CAT1(x,y)
#define DO_DEFAULT_RTC \
rtc_port: 0x70, rtc_addr: 0x80, rtc_bcd: 0
#define DO_DEFAULT_RTC rtc_port: 0x70
#define DO_EV4_MMU \
max_asn: EV4_MAX_ASN, \
......
......@@ -181,6 +181,9 @@ generic_kill_arch (int mode, char *restart_cmd)
return;
}
if (alpha_using_srm)
srm_paging_stop();
halt();
}
......
......@@ -143,6 +143,7 @@ extern void reset_for_srm(void);
/* time.c */
extern void timer_interrupt(int irq, void *dev, struct pt_regs * regs);
extern unsigned long est_cycle_freq;
/* smc37c93x.c */
extern void SMC93x_Init(void);
......@@ -172,5 +173,12 @@ extern void entSys(void);
extern void entUna(void);
/* process.c */
void generic_kill_arch (int mode, char *reboot_cmd);
void cpu_idle(void *) __attribute__((noreturn));
extern void generic_kill_arch (int mode, char *reboot_cmd);
extern void cpu_idle(void *) __attribute__((noreturn));
/* ptrace.c */
extern int ptrace_set_bpt (struct task_struct *child);
extern int ptrace_cancel_bpt (struct task_struct *child);
/* ../mm/init.c */
void srm_paging_stop(void);
This diff is collapsed.
......@@ -467,19 +467,22 @@ get_sysvec(long type, long variation, long cpu)
vec = eb66_vecs[eb66_indices[member]];
break;
case ST_DEC_1000:
if (cpu == EV5_CPU)
cpu &= 0xffffffff;
if (cpu == EV5_CPU || cpu == EV56_CPU)
vec = &mikasa_primo_mv;
else
vec = &mikasa_mv;
break;
case ST_DEC_NORITAKE:
if (cpu == EV5_CPU)
cpu &= 0xffffffff;
if (cpu == EV5_CPU || cpu == EV56_CPU)
vec = &noritake_primo_mv;
else
vec = &noritake_mv;
break;
case ST_DEC_2100_A500:
if (cpu == EV5_CPU)
cpu &= 0xffffffff;
if (cpu == EV5_CPU || cpu == EV56_CPU)
vec = &sable_gamma_mv;
else
vec = &sable_mv;
......@@ -678,7 +681,7 @@ int get_cpuinfo(char *buffer)
"system variation\t: %s\n"
"system revision\t\t: %ld\n"
"system serial number\t: %s\n"
"cycle frequency [Hz]\t: %lu\n"
"cycle frequency [Hz]\t: %lu %s\n"
"timer frequency [Hz]\t: %lu.%02lu\n"
"page size [bytes]\t: %ld\n"
"phys. address bits\t: %ld\n"
......@@ -691,7 +694,8 @@ int get_cpuinfo(char *buffer)
(char*)cpu->serial_no,
systype_name, sysvariation_name, hwrpb->sys_revision,
(char*)hwrpb->ssn,
hwrpb->cycle_freq,
hwrpb->cycle_freq ? : est_cycle_freq,
hwrpb->cycle_freq ? "" : "est.",
hwrpb->intr_freq / 4096,
(100 * hwrpb->intr_freq / 4096) % 100,
hwrpb->pagesize,
......@@ -703,8 +707,8 @@ int get_cpuinfo(char *buffer)
platform_string());
#ifdef __SMP__
return len + smp_info(buffer+len);
#else
return len;
len += smp_info(buffer+len);
#endif
return len;
}
......@@ -33,9 +33,6 @@ asmlinkage void ret_from_sys_call(void);
asmlinkage int do_signal(sigset_t *, struct pt_regs *,
struct switch_stack *, unsigned long, unsigned long);
extern int ptrace_set_bpt (struct task_struct *child);
extern int ptrace_cancel_bpt (struct task_struct *child);
/*
* The OSF/1 sigprocmask calling sequence is different from the
......
......@@ -8,6 +8,7 @@
#include <linux/malloc.h>
#include <linux/mm.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <asm/hwrpb.h>
#include <asm/io.h>
......@@ -86,21 +87,28 @@ static unsigned long __init SMCConfigState(unsigned long baseAddr)
unsigned long indexPort;
unsigned long dataPort;
int i;
configPort = indexPort = baseAddr;
dataPort = configPort + 1;
outb(CONFIG_ON_KEY, configPort);
outb(CONFIG_ON_KEY, configPort);
outb(DEVICE_ID, indexPort);
devId = inb(dataPort);
if ( devId == VALID_DEVICE_ID ) {
outb(DEVICE_REV, indexPort);
devRev = inb(dataPort);
}
else {
baseAddr = 0;
#define NUM_RETRIES 5
for (i = 0; i < NUM_RETRIES; i++)
{
outb(CONFIG_ON_KEY, configPort);
outb(CONFIG_ON_KEY, configPort);
outb(DEVICE_ID, indexPort);
devId = inb(dataPort);
if (devId == VALID_DEVICE_ID) {
outb(DEVICE_REV, indexPort);
devRev = inb(dataPort);
break;
}
else
udelay(100);
}
return baseAddr;
return (i != NUM_RETRIES) ? baseAddr : 0L;
}
static void __init SMCRunState(unsigned long baseAddr)
......
......@@ -39,6 +39,7 @@ spinlock_t kernel_flag = SPIN_LOCK_UNLOCKED;
unsigned int boot_cpu_id = 0;
static int smp_activated = 0;
static unsigned long ipicnt[NR_CPUS] = {0,}; /* IPI counts */
int smp_found_config = 0; /* Have we found an SMP box */
static int max_cpus = -1;
......@@ -619,7 +620,6 @@ local_flush_tlb_all(unsigned int this_cpu)
{
tbia();
clear_bit(this_cpu, &ipi_msg_flush_tb.flush_tb_mask);
mb();
return 0;
}
......@@ -627,12 +627,9 @@ static int
local_flush_tlb_mm(unsigned int this_cpu)
{
struct mm_struct * mm = ipi_msg_flush_tb.p.flush_mm;
if (mm != current->mm)
flush_tlb_other(mm);
else
if (mm == current->mm)
flush_tlb_current(mm);
clear_bit(this_cpu, &ipi_msg_flush_tb.flush_tb_mask);
mb();
return 0;
}
......@@ -642,12 +639,9 @@ local_flush_tlb_page(unsigned int this_cpu)
struct vm_area_struct * vma = ipi_msg_flush_tb.p.flush_vma;
struct mm_struct * mm = vma->vm_mm;
if (mm != current->mm)
flush_tlb_other(mm);
else
if (mm == current->mm)
flush_tlb_current_page(mm, vma, ipi_msg_flush_tb.flush_addr);
clear_bit(this_cpu, &ipi_msg_flush_tb.flush_tb_mask);
mb();
return 0;
}
......@@ -701,7 +695,7 @@ handle_ipi(struct pt_regs *regs)
volatile int * pending_ipis = &ipi_bits[this_cpu];
int ops;
mb();
mb(); /* Order bit setting and interrupt. */
#if 0
printk("handle_ipi: on CPU %d ops 0x%x PC 0x%lx\n",
this_cpu, *pending_ipis, regs->pc);
......@@ -711,10 +705,10 @@ handle_ipi(struct pt_regs *regs)
for (first = 0; (ops & 1) == 0; ++first, ops >>= 1)
; /* look for the first thing to do */
clear_bit(first, pending_ipis);
mb();
mb(); /* Order bit clearing and data access. */
if ((*ipi_func[first])(this_cpu))
printk("%d\n", first);
mb();
printk("%d\n", first);
mb(); /* Order data access and bit clearing. */
}
if (hwrpb->txrdy)
secondary_console_message();
......@@ -726,19 +720,26 @@ send_ipi_message(long to_whom, enum ipi_message_type operation)
int i;
unsigned int j;
mb(); /* Order out-of-band data and bit setting. */
for (i = 0, j = 1; i < NR_CPUS; ++i, j += j) {
if ((to_whom & j) == 0)
continue;
set_bit(operation, &ipi_bits[i]);
mb();
mb(); /* Order bit setting and interrupt. */
wripir(i);
}
}
int smp_info(char *buffer)
int
smp_info(char *buffer)
{
return sprintf(buffer, "CPUs probed %d active %d map 0x%x\n",
smp_num_probed, smp_num_cpus, cpu_present_map);
int i;
unsigned long sum = 0;
for (i = 0; i < NR_CPUS; i++)
sum += ipicnt[i];
return sprintf(buffer, "CPUs probed %d active %d map 0x%x IPIs %ld\n",
smp_num_probed, smp_num_cpus, cpu_present_map, sum);
}
/* wrapper for call from panic() */
......@@ -763,19 +764,22 @@ flush_tlb_all(void)
unsigned int to_whom = cpu_present_map ^ (1 << smp_processor_id());
int timeout = 10000;
spin_lock_own(&kernel_flag, "flush_tlb_all");
ipi_msg_flush_tb.flush_tb_mask = to_whom;
send_ipi_message(to_whom, TLB_ALL);
tbia();
while (ipi_msg_flush_tb.flush_tb_mask) {
if (--timeout < 0) {
printk("flush_tlb_all: STUCK on CPU %d mask 0x%x\n",
smp_processor_id(), ipi_msg_flush_tb.flush_tb_mask);
ipi_msg_flush_tb.flush_tb_mask = 0;
break;
}
udelay(100);
; /* Wait for all clear from other CPUs. */
if (--timeout < 0) {
printk("flush_tlb_all: STUCK on CPU %d mask 0x%x\n",
smp_processor_id(),
ipi_msg_flush_tb.flush_tb_mask);
ipi_msg_flush_tb.flush_tb_mask = 0;
break;
}
/* Wait for all clear from other CPUs. */
udelay(100);
}
}
......@@ -785,6 +789,8 @@ flush_tlb_mm(struct mm_struct *mm)
unsigned int to_whom = cpu_present_map ^ (1 << smp_processor_id());
int timeout = 10000;
spin_lock_own(&kernel_flag, "flush_tlb_mm");
ipi_msg_flush_tb.p.flush_mm = mm;
ipi_msg_flush_tb.flush_tb_mask = to_whom;
send_ipi_message(to_whom, TLB_MM);
......@@ -814,6 +820,8 @@ flush_tlb_page(struct vm_area_struct *vma, unsigned long addr)
struct mm_struct * mm = vma->vm_mm;
int timeout = 10000;
spin_lock_own(&kernel_flag, "flush_tlb_page");
ipi_msg_flush_tb.p.flush_vma = vma;
ipi_msg_flush_tb.flush_addr = addr;
ipi_msg_flush_tb.flush_tb_mask = to_whom;
......@@ -849,6 +857,8 @@ flush_tlb_range(struct mm_struct *mm, unsigned long start, unsigned long end)
timeout = 10000;
to_whom = cpu_present_map ^ (1 << smp_processor_id());
spin_lock_own(&kernel_flag, "flush_tlb_range");
ipi_msg_flush_tb.p.flush_mm = mm;
ipi_msg_flush_tb.flush_tb_mask = to_whom;
send_ipi_message(to_whom, TLB_MM);
......@@ -871,11 +881,51 @@ flush_tlb_range(struct mm_struct *mm, unsigned long start, unsigned long end)
}
#if DEBUG_SPINLOCK
void spin_lock(spinlock_t * lock)
#ifdef MANAGE_SPINLOCK_IPL
static inline long
spinlock_raise_ipl(spinlock_t * lock)
{
long min_ipl = lock->target_ipl;
long last_ipl = swpipl(7);
if (last_ipl < 7 && min_ipl < 7)
setipl(min_ipl < last_ipl ? last_ipl : min_ipl);
return last_ipl;
}
static inline void
spinlock_restore_ipl(long prev)
{
setipl(prev);
}
#else
#define spinlock_raise_ipl(LOCK) 0
#define spinlock_restore_ipl(PREV) ((void)0)
#endif /* MANAGE_SPINLOCK_IPL */
void
spin_unlock(spinlock_t * lock)
{
long old_ipl = lock->saved_ipl;
mb();
lock->lock = 0;
spinlock_restore_ipl(old_ipl);
}
void
spin_lock(spinlock_t * lock)
{
long tmp;
long stuck;
long stuck = 1<<27;
void *inline_pc = __builtin_return_address(0);
unsigned long started = jiffies;
int printed = 0;
int cpu = smp_processor_id();
long old_ipl = spinlock_raise_ipl(lock);
try_again:
......@@ -885,15 +935,15 @@ void spin_lock(spinlock_t * lock)
of this object file's text section so as to perfect
branch prediction. */
__asm__ __volatile__(
"1: ldq_l %0,%1\n"
"1: ldl_l %0,%1\n"
" subq %2,1,%2\n"
" blbs %0,2f\n"
" or %0,1,%0\n"
" stq_c %0,%1\n"
" stl_c %0,%1\n"
" beq %0,3f\n"
"4: mb\n"
".section .text2,\"ax\"\n"
"2: ldq %0,%1\n"
"2: ldl %0,%1\n"
" subq %2,1,%2\n"
"3: blt %2,4b\n"
" blbs %0,2b\n"
......@@ -905,13 +955,43 @@ void spin_lock(spinlock_t * lock)
: "2" (stuck));
if (stuck < 0) {
printk("spinlock stuck at %p (cur=%p, own=%p, prev=%p)\n",
inline_pc, current, lock->task, lock->previous);
if (!printed) {
printk("spinlock stuck at %p(%d) owner %s at %p\n",
inline_pc, cpu, lock->task->comm,
lock->previous);
printed = 1;
}
stuck = 1<<30;
goto try_again;
} else {
lock->previous = inline_pc;
}
/* Exiting. Got the lock. */
lock->saved_ipl = old_ipl;
lock->on_cpu = cpu;
lock->previous = inline_pc;
lock->task = current;
if (printed) {
printk("spinlock grabbed at %p(%d) %ld ticks\n",
inline_pc, cpu, jiffies - started);
}
}
int
spin_trylock(spinlock_t * lock)
{
long old_ipl = spinlock_raise_ipl(lock);
int ret;
if ((ret = !test_and_set_bit(0, lock))) {
mb();
lock->saved_ipl = old_ipl;
lock->on_cpu = smp_processor_id();
lock->previous = __builtin_return_address(0);
lock->task = current;
} else {
spinlock_restore_ipl(old_ipl);
}
return ret;
}
#endif /* DEBUG_SPINLOCK */
......@@ -930,22 +1010,21 @@ void write_lock(rwlock_t * lock)
__asm__ __volatile__(
"1: ldl_l %1,%0\n"
" blbs %1,6f\n"
" or %1,1,%2\n"
" stl_c %2,%0\n"
" beq %2,6f\n"
" blt %1,8f\n"
" mov 1,%1\n"
" stl_c %1,%0\n"
" beq %1,6f\n"
"4: mb\n"
".section .text2,\"ax\"\n"
"6: ldl %1,%0\n"
" blt %3,4b # debug\n"
"6: blt %3,4b # debug\n"
" subl %3,1,%3 # debug\n"
" ldl %1,%0\n"
" blbs %1,6b\n"
" br 1b\n"
"8: ldl %1,%0\n"
" blt %4,4b # debug\n"
"8: blt %4,4b # debug\n"
" subl %4,1,%4 # debug\n"
" ldl %1,%0\n"
" blt %1,8b\n"
" br 4b\n"
" br 1b\n"
".previous"
: "=m" (__dummy_lock(lock)), "=&r" (regx), "=&r" (regy)
, "=&r" (stuck_lock), "=&r" (stuck_reader)
......
......@@ -128,7 +128,7 @@ struct alpha_machine_vector jensen_mv __initmv = {
BUS(jensen),
machine_check: jensen_machine_check,
max_dma_address: ALPHA_MAX_DMA_ADDRESS,
rtc_port: 0x170, rtc_addr: 0, rtc_bcd: 1,
rtc_port: 0x170,
nr_irqs: 16,
irq_probe_mask: _PROBE_MASK(16),
......
......@@ -247,8 +247,7 @@ ruffian_kill_arch (int mode, char *reboot_cmd)
struct alpha_machine_vector ruffian_mv __initmv = {
vector_name: "Ruffian",
DO_EV5_MMU,
/* RUFFIAN always uses BCD, like a PeeCee. */
rtc_port: 0x70, rtc_addr: 0x80, rtc_bcd: 1,
DO_DEFAULT_RTC,
/* For the moment, do not use BWIO on RUFFIAN. */
IO(PYXIS,pyxis,pyxis),
DO_PYXIS_BUS,
......
......@@ -103,7 +103,10 @@ sx164_device_interrupt(unsigned long vector, struct pt_regs *regs)
static void
sx164_init_irq(void)
{
STANDARD_INIT_IRQ_PROLOG;
outb(0, DMA1_RESET_REG);
outb(0, DMA2_RESET_REG);
outb(DMA_MODE_CASCADE, DMA2_MODE_REG);
outb(0, DMA2_MASK_REG);
if (alpha_using_srm) {
alpha_mv.update_irq_hw = sx164_srm_update_irq_hw;
......
......@@ -62,6 +62,8 @@ static struct {
time_t last_rtc_update;
} state;
unsigned long est_cycle_freq;
static inline __u32 rpcc(void)
{
......@@ -162,7 +164,7 @@ static inline unsigned long mktime(unsigned int year, unsigned int mon,
* drivers depend on them being initialized (e.g., joystick driver).
*/
/* It is (normally) only counter 1 that presents config problems, so
/* It is (normally) only counter 0 that presents config problems, so
provide this support function to do the rest of the job. */
void inline
......@@ -184,12 +186,20 @@ init_pit_rest(void)
static inline void
rtc_init_pit (void)
{
unsigned char control;
/* Setup interval timer if /dev/rtc is being used */
outb(0x34, 0x43); /* binary, mode 2, LSB/MSB, ch 0 */
outb(LATCH & 0xff, 0x40); /* LSB */
outb(LATCH >> 8, 0x40); /* MSB */
request_region(0x40, 0x20, "timer"); /* reserve pit */
/* Turn off RTC interrupts before /dev/rtc is initialized */
control = CMOS_READ(RTC_CONTROL);
control &= ~(RTC_PIE | RTC_AIE | RTC_UIE);
CMOS_WRITE(control, RTC_CONTROL);
CMOS_READ(RTC_INTR_FLAGS);
init_pit_rest();
}
#endif
......@@ -197,11 +207,25 @@ rtc_init_pit (void)
void
generic_init_pit (void)
{
int x;
if ((x = (CMOS_READ(RTC_FREQ_SELECT) & 0x3f)) != 0x26) {
unsigned char x;
/* Reset periodic interrupt frequency. */
x = CMOS_READ(RTC_FREQ_SELECT) & 0x3f;
if (x != 0x26 && x != 0x19 && x != 0x06) {
printk("Setting RTC_FREQ to 1024 Hz (%x)\n", x);
CMOS_WRITE(0x26, RTC_FREQ_SELECT);
}
/* Turn on periodic interrupts. */
x = CMOS_READ(RTC_CONTROL);
if (!(x & RTC_PIE)) {
printk("Turning on RTC interrupts.\n");
x |= RTC_PIE;
x &= ~(RTC_AIE | RTC_UIE);
CMOS_WRITE(x, RTC_CONTROL);
}
CMOS_READ(RTC_INTR_FLAGS);
request_region(RTC_PORT(0), 0x10, "timer"); /* reserve rtc */
/* Turn off the PIT. */
......@@ -223,11 +247,9 @@ generic_init_pit (void)
void
time_init(void)
{
#ifdef CONFIG_RTC
unsigned char save_control;
#endif
void (*irq_handler)(int, void *, struct pt_regs *);
unsigned int year, mon, day, hour, min, sec, cc1, cc2;
unsigned long cycle_freq;
/* Initialize the timers. */
init_pit();
......@@ -246,16 +268,17 @@ time_init(void)
/* If our cycle frequency isn't valid, go another round and give
a guess at what it should be. */
if (hwrpb->cycle_freq == 0) {
cycle_freq = hwrpb->cycle_freq;
if (cycle_freq == 0) {
printk("HWRPB cycle frequency bogus. Estimating... ");
do { } while (!(CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP));
do { } while (CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP);
cc2 = rpcc();
hwrpb->cycle_freq = cc2 - cc1;
est_cycle_freq = cycle_freq = cc2 - cc1;
cc1 = cc2;
printk("%lu Hz\n", hwrpb->cycle_freq);
printk("%lu Hz\n", cycle_freq);
}
/* From John Bowman <bowman@math.ualberta.ca>: allow the values
......@@ -300,19 +323,9 @@ time_init(void)
state.last_time = cc1;
state.scaled_ticks_per_cycle
= ((unsigned long) HZ << FIX_SHIFT) / hwrpb->cycle_freq;
= ((unsigned long) HZ << FIX_SHIFT) / cycle_freq;
state.last_rtc_update = 0;
#ifdef CONFIG_RTC
/* turn off RTC interrupts before /dev/rtc is initialized */
save_control = CMOS_READ(RTC_CONTROL);
save_control &= ~RTC_PIE;
save_control &= ~RTC_AIE;
save_control &= ~RTC_UIE;
CMOS_WRITE(save_control, RTC_CONTROL);
CMOS_READ(RTC_INTR_FLAGS);
#endif
/* setup timer */
irq_handler = timer_interrupt;
if (request_irq(TIMER_IRQ, irq_handler, 0, "timer", NULL))
......
......@@ -149,8 +149,6 @@ asmlinkage void do_entIF(unsigned long type, unsigned long a1,
unsigned long a2, unsigned long a3, unsigned long a4,
unsigned long a5, struct pt_regs regs)
{
extern int ptrace_cancel_bpt (struct task_struct *who);
lock_kernel();
die_if_kernel("Instruction fault", &regs, type, 0);
switch (type) {
......@@ -558,11 +556,12 @@ s_reg_to_mem (unsigned long s_reg)
#define OP_INT_MASK ( 1L << 0x28 | 1L << 0x2c /* ldl stl */ \
| 1L << 0x29 | 1L << 0x2d /* ldq stq */ \
| 1L << 0x0c | 1L << 0x0d ) /* ldwu stw */
| 1L << 0x0c | 1L << 0x0d /* ldwu stw */ \
| 1L << 0x0a | 1L << 0x0e ) /* ldbu stb */
#define OP_WRITE_MASK ( 1L << 0x26 | 1L << 0x27 /* sts stt */ \
| 1L << 0x2c | 1L << 0x2d /* stl stq */ \
| 1L << 0xd ) /* stw */
| 1L << 0x0d | 1L << 0x0e ) /* stw stb */
#define R(x) ((size_t) &((struct pt_regs *)0)->x)
......
......@@ -7,7 +7,8 @@ OBJS = __divqu.o __remqu.o __divlu.o __remlu.o memset.o memcpy.o io.o \
strcat.o strcpy.o strncat.o strncpy.o stxcpy.o stxncpy.o \
strchr.o strrchr.o \
copy_user.o clear_user.o strncpy_from_user.o strlen_user.o \
csum_ipv6_magic.o strcasecmp.o
csum_ipv6_magic.o strcasecmp.o \
srm_dispatch.o srm_fixup.o srm_puts.o srm_printk.o
lib.a: $(OBJS)
$(AR) rcs lib.a $(OBJS)
......
/*
* arch/alpha/lib/srm_dispatch.S
*/
.globl srm_dispatch
.ent srm_dispatch
srm_dispatch:
.frame $30,30,$26
subq $30,80,$30
stq $26,0($30)
stq $8,8($30)
stq $9,16($30)
stq $10,24($30)
stq $11,32($30)
stq $12,40($30)
stq $13,48($30)
stq $14,56($30)
stq $15,64($30)
stq $29,72($30)
.mask 0x2400FF00, -80
.prologue 0
ldq $1,hwrpb
ldq $2,0xc0($1) /* crb offset */
addq $2,$1,$2 /* crb */
ldq $27,0($2) /* dispatch procedure value */
ldq $2,8($27) /* dispatch call address */
jsr $26,($2) /* call it (weird VMS call seq) */
ldq $26,0($30)
ldq $8,8($30)
ldq $9,16($30)
ldq $10,24($30)
ldq $11,32($30)
ldq $12,40($30)
ldq $13,48($30)
ldq $14,56($30)
ldq $15,64($30)
ldq $29,72($30)
addq $30,80,$30
ret $31,($26),1
.end srm_dispatch
/*
* arch/alpha/lib/srm_fixup.S
*/
.globl srm_fixup
.ent srm_fixup
srm_fixup:
.frame $30,30,$26
subq $30,80,$30
stq $26,0($30)
stq $8,8($30)
stq $9,16($30)
stq $10,24($30)
stq $11,32($30)
stq $12,40($30)
stq $13,48($30)
stq $14,56($30)
stq $15,64($30)
stq $29,72($30)
.mask 0x2400FF00, -80
.prologue 0
ldq $2,0xc0($17) /* crb offset */
addq $2,$1,$2 /* crb */
ldq $27,16($2) /* fixup procedure value */
ldq $2,8($27) /* dispatch call address */
jsr $26,($2) /* call it (weird VMS call seq) */
ldq $26,0($30)
ldq $8,8($30)
ldq $9,16($30)
ldq $10,24($30)
ldq $11,32($30)
ldq $12,40($30)
ldq $13,48($30)
ldq $14,56($30)
ldq $15,64($30)
ldq $29,72($30)
addq $30,80,$30
ret $31,($26),1
.end srm_fixup
/*
* arch/alpha/lib/srm_printk.c
*/
#include <linux/kernel.h>
#include <asm/console.h>
long
srm_printk(const char *fmt, ...)
{
static char buf[1024];
va_list args;
long i;
va_start(args, fmt);
i = vsprintf(buf,fmt,args);
va_end(args);
srm_puts(buf);
return i;
}
/*
* arch/alpha/lib/srm_puts.c
*/
#include <linux/string.h>
#include <asm/console.h>
void
srm_puts(const char *str)
{
/* Expand \n to \r\n as we go. */
while (*str) {
long len;
const char *e = str;
if (*str == '\n') {
if (srm_dispatch(CCB_PUTS, 0, "\r", 1) < 0)
return;
++e;
}
e = strchr(e, '\n') ? : strchr(e, '\0');
len = e - str;
while (len > 0) {
long written = srm_dispatch(CCB_PUTS, 0, str, len);
if (written < 0)
return;
len -= written & 0xffffffff;
str += written & 0xffffffff;
}
}
}
......@@ -30,7 +30,7 @@
extern void die_if_kernel(char *,struct pt_regs *,long);
extern void show_net_buffers(void);
struct thread_struct * original_pcb_ptr;
struct thread_struct original_pcb;
#ifndef __SMP__
struct pgtable_cache_struct quicklists;
......@@ -193,47 +193,66 @@ paging_init(unsigned long start_mem, unsigned long end_mem)
unsigned long newptbr;
struct memclust_struct * cluster;
struct memdesc_struct * memdesc;
struct thread_struct *original_pcb_ptr;
/* initialize mem_map[] */
start_mem = free_area_init(start_mem, end_mem);
/* find free clusters, update mem_map[] accordingly */
memdesc = (struct memdesc_struct *)
(INIT_HWRPB->mddt_offset + (unsigned long) INIT_HWRPB);
(hwrpb->mddt_offset + (unsigned long) hwrpb);
cluster = memdesc->cluster;
for (i = memdesc->numclusters ; i > 0; i--, cluster++) {
unsigned long pfn, nr;
if (cluster->usage & 1)
/* Bit 0 is console/PALcode reserved. Bit 1 is
non-volatile memory -- we might want to mark
this for later */
if (cluster->usage & 3)
continue;
pfn = cluster->start_pfn;
nr = cluster->numpages;
/* non-volatile memory. We might want to mark this for later */
if (cluster->usage & 2)
continue;
while (nr--)
clear_bit(PG_reserved, &mem_map[pfn++].flags);
}
/* unmap the console stuff: we don't need it, and we don't want it */
/* Also set up the real kernel PCB while we're at it.. */
/* Initialize the kernel's page tables. Linux puts the vptb in
the last slot of the L1 page table. */
memset((void *) ZERO_PAGE, 0, PAGE_SIZE);
memset(swapper_pg_dir, 0, PAGE_SIZE);
newptbr = ((unsigned long) swapper_pg_dir - PAGE_OFFSET) >> PAGE_SHIFT;
pgd_val(swapper_pg_dir[1023]) =
(newptbr << 32) | pgprot_val(PAGE_KERNEL);
/* Set the vptb. This is often done by the bootloader, but
shouldn't be required. */
if (hwrpb->vptb != 0xfffffffe00000000) {
wrvptptr(0xfffffffe00000000);
hwrpb->vptb = 0xfffffffe00000000;
hwrpb_update_checksum(hwrpb);
}
/* Also set up the real kernel PCB while we're at it. */
init_task.tss.ptbr = newptbr;
init_task.tss.pal_flags = 1; /* set FEN, clear everything else */
init_task.tss.flags = 0;
original_pcb_ptr =
phys_to_virt((unsigned long)load_PCB(&init_task.tss));
#if 0
printk("OKSP 0x%lx OPTBR 0x%lx\n",
original_pcb_ptr->ksp, original_pcb_ptr->ptbr);
#endif
original_pcb_ptr = load_PCB(&init_task.tss);
tbia();
/* Save off the contents of the original PCB so that we can
restore the original console's page tables for a clean reboot.
Note that the PCB is supposed to be a physical address, but
since KSEG values also happen to work, folks get confused.
Check this here. */
if ((unsigned long)original_pcb_ptr < PAGE_OFFSET) {
original_pcb_ptr = (struct thread_struct *)
phys_to_virt((unsigned long) original_pcb_ptr);
}
original_pcb = *original_pcb_ptr;
return start_mem;
}
......@@ -250,12 +269,6 @@ paging_init_secondary(void)
current->tss.ptbr = init_task.tss.ptbr;
current->tss.pal_flags = 1;
current->tss.flags = 0;
#if 0
printk("paging_init_secondary: KSP 0x%lx PTBR 0x%lx\n",
current->tss.ksp, current->tss.ptbr);
#endif
load_PCB(&current->tss);
tbia();
......@@ -263,6 +276,23 @@ printk("paging_init_secondary: KSP 0x%lx PTBR 0x%lx\n",
}
#endif /* __SMP__ */
#if defined(CONFIG_ALPHA_GENERIC) || defined(CONFIG_ALPHA_SRM)
void
srm_paging_stop (void)
{
/* Move the vptb back to where the SRM console expects it. */
swapper_pg_dir[1] = swapper_pg_dir[1023];
tbia();
wrvptptr(0x200000000);
hwrpb->vptb = 0x200000000;
hwrpb_update_checksum(hwrpb);
/* Reload the page tables that the console had in use. */
load_PCB(&original_pcb);
tbia();
}
#endif
#if DEBUG_POISON
static void
kill_page(unsigned long pg)
......
......@@ -346,7 +346,7 @@ static struct pci_access pci_direct_conf2 = {
* attempt to make use of direct access hints provided by the PCI BIOS).
*
* This should be close to trivial, but it isn't, because there are buggy
* chipsets (yes, you guessed it, by Intel) that have no class ID.
* chipsets (yes, you guessed it, by Intel and Compaq) that have no class ID.
*/
__initfunc(int pci_sanity_check(struct pci_access *a))
{
......@@ -356,9 +356,9 @@ __initfunc(int pci_sanity_check(struct pci_access *a))
return 1;
for(dfn=0; dfn < 0x100; dfn++)
if ((!a->read_config_word(0, dfn, PCI_CLASS_DEVICE, &x) &&
x == PCI_CLASS_BRIDGE_HOST) ||
(x == PCI_CLASS_BRIDGE_HOST || x == PCI_CLASS_DISPLAY_VGA)) ||
(!a->read_config_word(0, dfn, PCI_VENDOR_ID, &x) &&
x == PCI_VENDOR_ID_INTEL))
(x == PCI_VENDOR_ID_INTEL || x == PCI_VENDOR_ID_COMPAQ)))
return 1;
DBG("PCI: Sanity check failed\n");
return 0;
......
......@@ -431,9 +431,9 @@ static struct cpu_model_info cpu_models[] __initdata = {
"486 SX/2", NULL, "486 DX/2-WB", "486 DX/4", "486 DX/4-WB", NULL,
NULL, NULL, NULL, NULL, NULL }},
{ X86_VENDOR_INTEL, 5,
{ "Pentium 60/66 A-step", "Pentium 60/66", "Pentium 75+",
{ "Pentium 60/66 A-step", "Pentium 60/66", "Pentium 75 - 200",
"OverDrive PODP5V83", "Pentium MMX", NULL, NULL,
"Mobile Pentium 75+", "Mobile Pentium MMX", NULL, NULL, NULL,
"Mobile Pentium 75 - 200", "Mobile Pentium MMX", NULL, NULL, NULL,
NULL, NULL, NULL, NULL }},
{ X86_VENDOR_INTEL, 6,
{ "Pentium Pro A-step", "Pentium Pro", NULL, "Pentium II (Klamath)",
......
This diff is collapsed.
......@@ -145,6 +145,12 @@ pmac_get_cpuinfo(char *buffer)
#include "../../../drivers/scsi/sd.h"
#include "../../../drivers/scsi/hosts.h"
#define SD_MAJOR(i) (!(i) ? SCSI_DISK0_MAJOR : SCSI_DISK1_MAJOR-1+(i))
#define SD_MAJOR_NUMBER(i) SD_MAJOR((i) >> 8)
#define SD_MINOR_NUMBER(i) ((i) & 255)
#define MKDEV_SD_PARTITION(i) MKDEV(SD_MAJOR_NUMBER(i), SD_MINOR_NUMBER(i))
#define MKDEV_SD(index) MKDEV_SD_PARTITION((index) << 4)
kdev_t sd_find_target(void *host, int tgt)
{
Scsi_Disk *dp;
......@@ -153,7 +159,7 @@ kdev_t sd_find_target(void *host, int tgt)
for (dp = rscsi_disks, i = 0; i < sd_template.dev_max; ++i, ++dp)
if (dp->device != NULL && dp->device->host == host
&& dp->device->id == tgt)
return MKDEV(SCSI_DISK_MAJOR, i << 4);
return MKDEV_SD(i);
return 0;
}
#endif
......
/*
* linux/arch/ppc/kernel/setup.c
*
* PowerPC version
* Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
*
* Adapted for Power Macintosh by Paul Mackerras
* Copyright (C) 1996 Paul Mackerras (paulus@cs.anu.edu.au)
*
* Derived from "arch/alpha/kernel/setup.c"
* Copyright (C) 1995 Linus Torvalds
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*
*/
/*
* bootup setup stuff..
*/
#include <linux/config.h>
#include <linux/init.h>
#include <linux/errno.h>
#include <linux/sched.h>
#include <linux/kernel.h>
#include <linux/mm.h>
#include <linux/stddef.h>
#include <linux/unistd.h>
#include <linux/ptrace.h>
#include <linux/malloc.h>
#include <linux/user.h>
#include <linux/a.out.h>
#include <linux/tty.h>
#include <linux/string.h>
#include <linux/delay.h>
#include <linux/ioport.h>
#include <linux/major.h>
#include <linux/blk.h>
#include <linux/vt_kern.h>
#include <linux/console.h>
#include <asm/prom.h>
#include <asm/system.h>
#include <asm/pgtable.h>
#include <asm/io.h>
#include <asm/pci-bridge.h>
#include <asm/adb.h>
#include <asm/cuda.h>
#include <asm/pmu.h>
#include <asm/mediabay.h>
#include <asm/ohare.h>
#include <asm/mediabay.h>
#include "time.h"
unsigned char drive_info;
extern char saved_command_line[];
#define DEFAULT_ROOT_DEVICE 0x0801 /* sda1 - slightly silly choice */
extern void zs_kgdb_hook(int tty_num);
static void ohare_init(void);
__pmac
int
pmac_get_cpuinfo(char *buffer)
{
int len;
struct device_node *np;
char *pp;
int plen;
/* find motherboard type */
len = sprintf(buffer, "machine\t\t: ");
np = find_devices("device-tree");
if (np != NULL) {
pp = (char *) get_property(np, "model", NULL);
if (pp != NULL)
len += sprintf(buffer+len, "%s\n", pp);
else
len += sprintf(buffer+len, "PowerMac\n");
pp = (char *) get_property(np, "compatible", &plen);
if (pp != NULL) {
len += sprintf(buffer+len, "motherboard\t:");
while (plen > 0) {
int l = strlen(pp) + 1;
len += sprintf(buffer+len, " %s", pp);
plen -= l;
pp += l;
}
buffer[len++] = '\n';
}
} else
len += sprintf(buffer+len, "PowerMac\n");
/* find l2 cache info */
np = find_devices("l2-cache");
if (np == 0)
np = find_type_devices("cache");
if (np != 0) {
unsigned int *ic = (unsigned int *)
get_property(np, "i-cache-size", NULL);
unsigned int *dc = (unsigned int *)
get_property(np, "d-cache-size", NULL);
len += sprintf(buffer+len, "L2 cache\t:");
if (get_property(np, "cache-unified", NULL) != 0 && dc) {
len += sprintf(buffer+len, " %dK unified", *dc / 1024);
} else {
if (ic)
len += sprintf(buffer+len, " %dK instruction",
*ic / 1024);
if (dc)
len += sprintf(buffer+len, "%s %dK data",
(ic? " +": ""), *dc / 1024);
}
pp = get_property(np, "ram-type", NULL);
if (pp)
len += sprintf(buffer+len, " %s", pp);
buffer[len++] = '\n';
}
/* find ram info */
np = find_devices("memory");
if (np != 0) {
struct reg_property *reg = (struct reg_property *)
get_property(np, "reg", NULL);
if (reg != 0) {
len += sprintf(buffer+len, "memory\t\t: %dMB\n",
reg->size >> 20);
}
}
return len;
}
#ifdef CONFIG_SCSI
/* Find the device number for the disk (if any) at target tgt
on host adaptor host.
XXX this really really should be in drivers/scsi/sd.c. */
#include <linux/blkdev.h>
#include "../../../drivers/scsi/scsi.h"
#include "../../../drivers/scsi/sd.h"
#include "../../../drivers/scsi/hosts.h"
kdev_t sd_find_target(void *host, int tgt)
{
Scsi_Disk *dp;
int i;
for (dp = rscsi_disks, i = 0; i < sd_template.dev_max; ++i, ++dp)
if (dp->device != NULL && dp->device->host == host
&& dp->device->id == tgt)
return MKDEV(SCSI_DISK_MAJOR, i << 4);
return 0;
}
#endif
/*
* Dummy mksound function that does nothing.
* The real one is in the dmasound driver.
*/
static void
pmac_mksound(unsigned int hz, unsigned int ticks)
{
}
static volatile u32 *sysctrl_regs;
static volatile u32 *feature_addr;
__initfunc(void
pmac_setup_arch(unsigned long *memory_start_p, unsigned long *memory_end_p))
{
struct device_node *cpu;
int *fp;
/* Set loops_per_sec to a half-way reasonable value,
for use until calibrate_delay gets called. */
cpu = find_type_devices("cpu");
if (cpu != 0) {
fp = (int *) get_property(cpu, "clock-frequency", NULL);
if (fp != 0) {
switch (_get_PVR() >> 16) {
case 4: /* 604 */
case 9: /* 604e */
case 10: /* mach V (604ev5) */
case 20: /* 620 */
loops_per_sec = *fp;
break;
default: /* 601, 603, etc. */
loops_per_sec = *fp / 2;
}
} else
loops_per_sec = 50000000;
}
/* this area has the CPU identification register
and some registers used by smp boards */
sysctrl_regs = (volatile u32 *) ioremap(0xf8000000, 0x1000);
__ioremap(0xffc00000, 0x400000, pgprot_val(PAGE_READONLY));
*memory_start_p = pmac_find_bridges(*memory_start_p, *memory_end_p);
ohare_init();
#ifdef CONFIG_KGDB
zs_kgdb_hook(0);
#endif
find_via_cuda();
find_via_pmu();
#ifdef CONFIG_DUMMY_CONSOLE
conswitchp = &dummy_con;
#endif
kd_mksound = pmac_mksound;
#ifdef CONFIG_BLK_DEV_INITRD
if (initrd_start)
ROOT_DEV = MKDEV(RAMDISK_MAJOR, 0);
else
#endif
ROOT_DEV = to_kdev_t(DEFAULT_ROOT_DEVICE);
}
__initfunc(static void ohare_init(void))
{
struct device_node *np;
np = find_devices("ohare");
if (np == 0)
return;
if (np->next != 0)
printk(KERN_WARNING "only using the first ohare\n");
if (np->n_addrs == 0) {
printk(KERN_ERR "No addresses for %s\n", np->full_name);
return;
}
feature_addr = (volatile u32 *)
ioremap(np->addrs[0].address + OHARE_FEATURE_REG, 4);
if (find_devices("via-pmu") == 0) {
printk(KERN_INFO "Twiddling the magic ohare bits\n");
out_le32(feature_addr, STARMAX_FEATURES);
} else {
out_le32(feature_addr, in_le32(feature_addr) | PBOOK_FEATURES);
printk(KERN_DEBUG "feature reg = %x\n", in_le32(feature_addr));
}
/*
* Turn on the L2 cache.
* We assume that we have a PSX memory controller iff
* we have an ohare I/O controller.
*/
if (((sysctrl_regs[2] >> 24) & 0xf) >= 3) {
if (sysctrl_regs[4] & 0x10)
sysctrl_regs[4] |= 0x04000020;
else
sysctrl_regs[4] |= 0x04000000;
printk(KERN_INFO "Level 2 cache enabled\n");
}
}
extern char *bootpath;
extern char *bootdevice;
void *boot_host;
int boot_target;
int boot_part;
kdev_t boot_dev;
__initfunc(void powermac_init(void))
{
adb_init();
pmac_nvram_init();
if (_machine == _MACH_Pmac) {
media_bay_init();
}
}
#ifdef CONFIG_SCSI
__initfunc(void
note_scsi_host(struct device_node *node, void *host))
{
int l;
char *p;
l = strlen(node->full_name);
if (bootpath != NULL && bootdevice != NULL
&& strncmp(node->full_name, bootdevice, l) == 0
&& (bootdevice[l] == '/' || bootdevice[l] == 0)) {
boot_host = host;
/*
* There's a bug in OF 1.0.5. (Why am I not surprised.)
* If you pass a path like scsi/sd@1:0 to canon, it returns
* something like /bandit@F2000000/gc@10/53c94@10000/sd@0,0
* That is, the scsi target number doesn't get preserved.
* So we pick the target number out of bootpath and use that.
*/
p = strstr(bootpath, "/sd@");
if (p != NULL) {
p += 4;
boot_target = simple_strtoul(p, NULL, 10);
p = strchr(p, ':');
if (p != NULL)
boot_part = simple_strtoul(p + 1, NULL, 10);
}
}
}
#endif
#ifdef CONFIG_BLK_DEV_IDE_PMAC
extern int pmac_ide_count;
extern struct device_node *pmac_ide_node[];
static int ide_majors[] = { 3, 22, 33, 34, 56, 57 };
__initfunc(kdev_t find_ide_boot(void))
{
char *p;
int i, n;
if (bootdevice == NULL)
return 0;
p = strrchr(bootdevice, '/');
if (p == NULL)
return 0;
n = p - bootdevice;
/*
* Look through the list of IDE interfaces for this one.
*/
for (i = 0; i < pmac_ide_count; ++i) {
char *name = pmac_ide_node[i]->full_name;
if (memcmp(name, bootdevice, n) == 0 && name[n] == 0) {
/* XXX should cope with the 2nd drive as well... */
return MKDEV(ide_majors[i], 0);
}
}
return 0;
}
#endif /* CONFIG_BLK_DEV_IDE_PMAC */
__initfunc(void find_boot_device(void))
{
#ifdef CONFIG_SCSI
if (boot_host != NULL) {
boot_dev = sd_find_target(boot_host, boot_target);
if (boot_dev != 0)
return;
}
#endif
#ifdef CONFIG_BLK_DEV_IDE_PMAC
boot_dev = find_ide_boot();
#endif
}
__initfunc(void note_bootable_part(kdev_t dev, int part))
{
static int found_boot = 0;
char *p;
/* Do nothing if the root has been set already. */
if (ROOT_DEV != to_kdev_t(DEFAULT_ROOT_DEVICE))
return;
p = strstr(saved_command_line, "root=");
if (p != NULL && (p == saved_command_line || p[-1] == ' '))
return;
if (!found_boot) {
find_boot_device();
found_boot = 1;
}
if (dev == boot_dev) {
ROOT_DEV = MKDEV(MAJOR(dev), MINOR(dev) + part);
boot_dev = NODEV;
printk(" (root)");
}
}
......@@ -43,6 +43,7 @@ else
bool ' Tekram TRM290 chipset support (EXPERIMENTAL)' CONFIG_BLK_DEV_TRM290
bool ' NS87415 chipset support (EXPERIMENTAL)' CONFIG_BLK_DEV_NS87415
bool ' VIA82C586 chipset support (EXPERIMENTAL)' CONFIG_BLK_DEV_VIA82C586
bool ' CMD646 chipset support (EXPERIMENTAL)' CONFIG_BLK_DEV_CMD646
fi
fi
fi
......
......@@ -102,12 +102,12 @@ isn't, use the old method using environment variables.
Tells the floppy driver that a workable DMA channel is available
(the default).
floppy=nofifo
floppy=nofifo
Disables the FIFO entirely. This is needed if you get "Bus
master arbitration error" messages from your Ethernet card (or
from other devices) while accessing the floppy.
floppy=fifo
floppy=fifo
Enables the FIFO (default)
floppy=<threshold>,fifo_depth
......@@ -189,6 +189,13 @@ floppy=fifo
floppy=<nr>,dma
Sets the floppy DMA channel to <nr> instead of 2
floppy=slow
Use PS/2 stepping rate:
" PS/2 floppies have much slower step rates than regular floppies.
It's been recommended that take about 1/4 of the default speed
in some more extreme cases."
Supporting utilities and additional documentation:
==================================================
......
......@@ -3,7 +3,7 @@
*
* Copyright 1994 Roman Hodek <Roman.Hodek@informatik.uni-erlangen.de>
*
* Some parts are based on hd.c by Linus Thorvalds
* Some parts are based on hd.c by Linus Torvalds
*
* 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
......
This diff is collapsed.
......@@ -71,7 +71,7 @@ char *disk_name (struct gendisk *hd, int minor, char *buf)
{
unsigned int part;
const char *maj = hd->major_name;
char unit = (minor >> hd->minor_shift) + 'a';
int unit = (minor >> hd->minor_shift) + 'a';
/*
* IDE devices use multiple major numbers, but the drives
......@@ -91,8 +91,19 @@ char *disk_name (struct gendisk *hd, int minor, char *buf)
unit += 2;
case IDE0_MAJOR:
maj = "hd";
break;
}
part = minor & ((1 << hd->minor_shift) - 1);
if (hd->major >= SCSI_DISK1_MAJOR && hd->major <= SCSI_DISK7_MAJOR) {
unit = unit + (hd->major - SCSI_DISK1_MAJOR + 1) * 16;
if (unit > 'z') {
unit -= 'z' + 1;
sprintf(buf, "sd%c%c", 'a' + unit / 26, 'a' + unit % 26);
if (part)
sprintf(buf + 4, "%d", part);
return buf;
}
}
if (part)
sprintf(buf, "%s%c%d", maj, unit, part);
else
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -56,7 +56,7 @@ if [ "$CONFIG_MOUSE" = "y" ]; then
tristate 'ATIXL busmouse support' CONFIG_ATIXL_BUSMOUSE
tristate 'Logitech busmouse support' CONFIG_BUSMOUSE
tristate 'Microsoft busmouse support' CONFIG_MS_BUSMOUSE
tristate 'PS/2 mouse (aka "auxiliary device") support' CONFIG_PSMOUSE
bool 'PS/2 mouse (aka "auxiliary device") support' CONFIG_PSMOUSE
tristate 'C&T 82C710 mouse port support (as on TI Travelmate)' CONFIG_82C710_MOUSE
tristate 'PC110 digitizer pad support' CONFIG_PC110_PAD
fi
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
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