Commit cf996dcf authored by Linus Torvalds's avatar Linus Torvalds

Import 1.3.71

parent d26708ba
......@@ -344,6 +344,13 @@ S: 1123 North Oak Park Avenue
S: Oak Park, Illinois 60302
S: USA
N: Bob Frey
E: bobf@advansys.com
D: AdvanSys SCSI driver
S: 1150 Ringwood Court
S: San Jose, California 95131
S: USA
N: Nigel Gamble
E: nigel@nrg.org
E: nigel@sgi.com
......@@ -609,6 +616,10 @@ S: Am Muehlenweg 38
S: D53424 Remagen
S: Germany
N: Martin von Loewis
E: loewis@informatik.hu-berlin.de
D: script binary format
N: Mark Lord
E: mlord@pobox.com
D: Author of IDE driver (ide.c), hd.c support
......
......@@ -1654,22 +1654,45 @@ CONFIG_NET_ISA
linux, read the Multiple-Ethernet-mini-HOWTO, available from
sunsite.unc.edu:/pub/Linux/docs/HOWTO/mini.
Arcnet support
ARCnet support
CONFIG_ARCNET
If you have a network card of this type, say Y and check out the
beautiful poetry in Documentation/networking/arcnet.txt in the
kernel source. If you get this driver to work or not, either way,
send mail to the author. You might also want to have a look at the
Ethernet-HOWTO, available via ftp (user: anonymous) in
sunsite.unc.edu:/pub/Linux/docs/HOWTO (even though arcnet is no true
ethernet). This driver is also available as a module ( = code which
can be inserted in and removed from the running kernel whenever you
want). If you want to compile it as a module, say M here and read
Documentation/modules.txt as well as
(arguably) beautiful poetry in Documentation/networking/arcnet.txt.
You might also want to have a look at the Ethernet-HOWTO, available
via ftp (user: anonymous) in sunsite.unc.edu:/pub/Linux/docs/HOWTO
(even though ARCnet is not really ethernet). This driver is also
available as a module ( = code which can be inserted in and removed
from the running kernel whenever you want). If you want to compile it
as a module, say M here and read Documentation/modules.txt as well as
Documentation/networking/net-modules.txt. If you plan to use more
than one network card under linux, read the
Multiple-Ethernet-mini-HOWTO, available from
sunsite.unc.edu:/pub/Linux/docs/HOWTO/mini.
Enable arc0e (ARCnet "ether-encap" packet format)
CONFIG_ARCNET_ETH
This allows you to use "ethernet encapsulation" with your ARCnet card
via the virtual arc0e device. You only need arc0e if you want to
talk to nonstandard ARCnet software, specifically, DOS/Windows-style
"NDIS" drivers. You do not need to enable this option to communicate
with industry-standard RFC1201 implementations, like the arcether.com
packet driver or most DOS/Windows ODI drivers. RFC1201 is included
automatically as the arc0 device. Please read the ARCnet
documentation in Documentation/networking/arcnet.txt for more
information about using arc0e and arc0s.
Enable arc0s (ARCnet RFC1051 packet format)
CONFIG_ARCNET_1051
This allows you to use RFC1051 with your ARCnet card via the virtual
arc0s device. You only need arc0s if you want to talk to ARCnet
software complying with the "old" standard, specifically, the DOS
arcnet.com packet driver, Amigas running AmiTCP, and some variants of
NetBSD. You do not need to enable this option to communicate with
industry-standard RFC1201 implementations, like the arcether.com
packet driver or most DOS/Windows ODI drivers. RFC1201 is included
automatically as the arc0 device. Please read the ARCnet
documentation in Documentation/networking/arcnet.txt for more
information about using arc0e and arc0s.
Cabletron E21xx support
CONFIG_E2100
......
......@@ -41,8 +41,8 @@ foo \kill}%
{\end{tabbing}}
%
\title{{\bf Linux Allocated Devices}}
\author{Maintained by H. Peter Anvin $<$hpa@storm.net$>$}
\date{Last revised: February 24, 1996}
\author{Maintained by H. Peter Anvin $<$hpa@zytor.com$>$}
\date{Last revised: March 2, 1996}
\maketitle
%
\noindent
......@@ -88,12 +88,13 @@ an unreasonable effort.
\major{ 5}{}{char }{Alternate TTY devices}
\major{ 6}{}{char }{Parallel printer devices}
\major{ 7}{}{char }{Virtual console access devices}
\major{ }{}{block}{Loopback devices}
\major{ 8}{}{block}{SCSI disk devices}
\major{ 9}{}{char }{SCSI tape devices}
\major{ }{}{block}{Metadisk (RAID) devices}
\major{10}{}{char }{Non-serial mice, misc features}
\major{11}{}{block}{SCSI CD-ROM devices}
\major{ }{}{block}{Loopback devices}
\major{11}{}{char }{Raw keyboard device}
\major{ }{}{block}{SCSI CD-ROM devices}
\major{12}{}{char }{QIC-02 tape}
\major{ }{}{block}{MSCDEX CD-ROM callback support}
\major{13}{}{char }{PC speaker}
......@@ -352,17 +353,6 @@ Not all computers have the {\hex 0x3bc} parallel port, hence the
\noindent
NOTE: These devices permit both read and write access.
\major{ }{}{block}{Loopback devices}
\minor{0}{/dev/loop0}{First loopback device}
\minor{1}{/dev/loop1}{Second loopback device}
\minordots
\end{devicelist}
\noindent
The loopback devices are used to mount filesystems not associated with
block devices. The binding to the loopback devices is usually handled
by mount(1).
\begin{devicelist}
\major{ 8}{}{block}{SCSI disk devices}
\minor{0}{/dev/sda}{First SCSI disk whole disk}
......@@ -403,18 +393,37 @@ physical disks.
\minor{2}{/dev/inportbm}{Microsoft Inport bus mouse}
\minor{3}{/dev/atibm}{ATI XL bus mouse}
\minor{4}{/dev/jbm}{J-mouse}
\minor{4}{/dev/amigamouse}{Amiga Mouse (68k/Amiga)}
\minor{5}{/dev/atarimouse}{Atari Mouse}
\minor{4}{/dev/amigamouse}{Amiga mouse (68k/Amiga)}
\minor{5}{/dev/atarimouse}{Atari mouse}
\minor{6}{/dev/sunmouse}{Sun mouse}
\minor{128}{/dev/beep}{Fancy beep device}
\minor{129}{/dev/modreq}{Kernel module load request}
\minor{130}{/dev/watchdog}{Watchdog timer port}
\minor{131}{/dev/temperature}{Machine internal temperature}
\minor{132}{/dev/hwtrap}{Hardware fault trap}
\minor{133}{/dev/exttrp}{External device trap}
\\
\major{ }{}{block}{Loopback devices}
\minor{0}{/dev/loop0}{First loopback device}
\minor{1}{/dev/loop1}{Second loopback device}
\minordots
\end{devicelist}
\noindent
The loopback devices are used to mount filesystems not associated with
block devices. The binding to the loopback devices is usually handled
by mount(1).
\begin{devicelist}
\major{11}{}{char }{Raw keyboard device}
\minor{0}{/dev/kbd}{Raw keyboard device}
\end{devicelist}
\noindent
The raw keyboard device is used on Linux/SPARC only.
\begin{devicelist}
\major{11}{}{block}{SCSI CD-ROM devices}
\major{ }{}{block}{SCSI CD-ROM devices}
\minor{0}{/dev/sr0}{First SCSI CD-ROM}
\minor{1}{/dev/sr1}{Second SCSI CD-ROM}
\minordots
......@@ -693,12 +702,12 @@ disk (same as SCSI.)
\begin{devicelist}
\major{29}{}{char }{Universal frame buffer}
\minor{0}{/dev/fb0current}{First frame buffer}
\minor{0}{/dev/fb0}{First frame buffer}
\minor{1}{/dev/fb0autodetect}{}
\minor{24}{/dev/fb0user0}{}
\minordots
\minor{31}{/dev/fb0user7}{}
\minor{32}{/dev/fb1current}{Second frame buffer}
\minor{32}{/dev/fb1}{Second frame buffer}
\minor{33}{/dev/fb1autodetect}{}
\minor{56}{/dev/fb1user0}{}
\minordots
......@@ -708,13 +717,15 @@ disk (same as SCSI.)
\noindent
The universal frame buffer device is currently supported only on
Linux/68k. The {\file current} device accesses the frame buffer at
current resolution; the {\file autodetect} one at bootup (default)
resolution. Minor numbers 2--23 within each frame buffer assignment
are used for specific device-dependent resolutions. There appears to
be no standard naming for these devices. Finally, 24--31 within each
device are reserved for user-selected modes, usually entered at boot
time.
Linux/68k and Linux/SPARC. The plain device accesses the frame
buffer at current resolution (Linux/68k calls this file {\file
current}, e.g. {\file /dev/fb0current}); the {\file autodetect} one at
bootup (default) resolution. Minor numbers 2--23 within each frame
buffer assignment are used for specific device-dependent resolutions.
There appears to be no standard naming for these devices. Finally,
24--31 within each device are reserved for user-selected modes,
usually entered at boot time. Currently only Linux/68k uses the
mode-specific devices.
\begin{devicelist}
\major{ }{}{block}{Aztech/Orchid/Okano/Wearnes CD-ROM}
......@@ -1057,7 +1068,7 @@ point to the ``cooked'' devices ({\file /dev/st*} and {\file
/dev/scanner} should point to the appropriate generic SCSI devices
({\file /dev/sg*}.)
{\file /dev/mouse} may point to a dialout (alternate) TTY device, a
{\file /dev/mouse} may point to a primary serial TTY device, a
hardware mouse device, or a socket for a mouse driver program
(e.g. {\file /dev/gpmdata}.)
......
LINUX ALLOCATED DEVICES
Maintained by H. Peter Anvin <hpa@storm.net>
Maintained by H. Peter Anvin <hpa@zytor.com>
Last revised: February 24, 1996
Last revised: March 2, 1996
This list is the successor to Rick Miller's Linux Device List, which
he stopped maintaining when he got busy with other things in 1993. It
......@@ -131,7 +131,7 @@ an unreasonable effort.
1 = /dev/hd?1 First partition
2 = /dev/hd?2 Second partition
...
63 = /dev/hd?63 63rd logical partition
63 = /dev/hd?63 63rd partition
For Linux/i386, partitions 1-4 are the primary
partitions, and 5 and above are logical partitions.
......@@ -187,15 +187,6 @@ an unreasonable effort.
NOTE: These devices permit both read and write access.
block Loopback devices
0 = /dev/loop0 First loopback device
1 = /dev/loop1 Second loopback device
...
The loopback devices are used to mount filesystems not
associated with block devices. The binding to the
loopback devices is usually handled by mount(1).
8 block SCSI disk devices
0 = /dev/sda First SCSI disk whole disk
16 = /dev/sdb Second SCSI disk whole disk
......@@ -228,8 +219,9 @@ an unreasonable effort.
2 = /dev/inportbm Microsoft Inport bus mouse
3 = /dev/atibm ATI XL bus mouse
4 = /dev/jbm J-mouse
4 = /dev/amigamouse Amiga Mouse (68k/Amiga)
5 = /dev/atarimouse Atari Mouse
4 = /dev/amigamouse Amiga mouse (68k/Amiga)
5 = /dev/atarimouse Atari mouse
6 = /dev/sunmouse Sun mouse
128 = /dev/beep Fancy beep device
129 = /dev/modreq Kernel module load request
130 = /dev/watchdog Watchdog timer port
......@@ -237,7 +229,21 @@ an unreasonable effort.
132 = /dev/hwtrap Hardware fault trap
133 = /dev/exttrp External device trap
11 block SCSI CD-ROM devices
block Loopback devices
0 = /dev/loop0 First loopback device
1 = /dev/loop1 Second loopback device
...
The loopback devices are used to mount filesystems not
associated with block devices. The binding to the
loopback devices is usually handled by mount(1).
11 char Raw keyboard device
0 = /dev/kbd Raw keyboard device
The raw keyboard device is used on Linux/SPARC only.
block SCSI CD-ROM devices
0 = /dev/sr0 First SCSI CD-ROM
1 = /dev/sr1 Second SCSI CD-ROM
...
......@@ -450,28 +456,32 @@ an unreasonable effort.
partitions is 15, like SCSI.
29 char Universal frame buffer
0 = /dev/fb0current First frame buffer
0 = /dev/fb0 First frame buffer
1 = /dev/fb0autodetect
24 = /dev/fb0user0
...
31 = /dev/fb0user7
32 = /dev/fb1current Second frame buffer
32 = /dev/fb1 Second frame buffer
33 = /dev/fb1autodetect
56 = /dev/fb1user0
...
63 = /dev/fb1user7
block Aztech/Orchid/Okano/Wearnes CD-ROM
0 = /dev/aztcd Aztech CD-ROM
The universal frame buffer device is currenly only
supported on Linux/68k. The "current" device accesses
the fame buffer at current resolution; the
"autodetect" one at bootup (default) resolution.
Minor numbers 2-23 within each frame buffer assignment
are used for specific device-dependent resolutions.
There appears to be no standard naming for these devices.
Finally, 2-31 within each device are reserved for
user-selected modes, usually entered at boot time.
supported on Linux/68k and Linux/SPARC. The plain
device accesses the frame buffer at current resolution
(Linux/68k calls this device "current",
e.g. /dev/fb0current); the "autodetect" one at bootup
(default) resolution. Minor numbers 2-23 within each
frame buffer assignment are used for specific
device-dependent resolutions. There appears to be no
standard naming for these devices. Finally, 2-31
within each device are reserved for user-selected
modes, usually entered at boot time. Currently only
Linux/68k uses the mode-specific devices.
block Aztech/Orchid/Okano/Wearnes CD-ROM
0 = /dev/aztcd Aztech CD-ROM
30 char iBCS-2 compatibility devices
0 = /dev/socksys Socket access
......@@ -615,6 +625,7 @@ an unreasonable effort.
49 = /dev/ml16pb-c0 Second card, first counter/timer
50 = /dev/ml16pb-c1 Second card, second counter/timer
51 = /dev/ml16pb-c2 Second card, third counter/timer
...
40 UNALLOCATED
......@@ -732,8 +743,8 @@ For SCSI devices, /dev/tape and /dev/cdrom should point to the
/dev/cdwriter and /dev/scanner should point to the appropriate generic
SCSI devices (/dev/sg*).
/dev/mouse may point to a dialout (alternate) TTY device, a hardware
mouse device, or a socket for a mouse driver program (e.g. /dev/gpmdata).
/dev/mouse may point to a primary serial TTY device, a hardware mouse
device, or a socket for a mouse driver program (e.g. /dev/gpmdata).
Sockets and pipes
......
......@@ -53,7 +53,7 @@ Klingon language support
Unfortunately, Unicode/ISO 10646 does not allocate code points for the
language Klingon, probably fearing the potential code point explosion
if many fictional lanugages were submitted for inclusion. There are
if many fictional languages were submitted for inclusion. There are
also political reasons (the Japanese, for example, are not too happy
about the whole 16-bit concept to begin with.) However, with Linux
being a hacker-driven OS it seems this is a brilliant linguistic hack
......
......@@ -80,6 +80,7 @@ Ioctl Include File Comments
'C' linux/soundcard.h
'I' linux/isdn.h
'K' linux/kd.h
'L' linux/loop.h
'M' linux/soundcard.h
'P' linux/soundcard.h
'Q' linux/soundcard.h
......
VERSION = 1
PATCHLEVEL = 3
SUBLEVEL = 70
SUBLEVEL = 71
ARCH = i386
......@@ -196,7 +196,6 @@ xconfig: symlinks
menuconfig: include/linux/version.h symlinks
$(MAKE) -C scripts/lxdialog all
$(CONFIG_SHELL) scripts/Menuconfig arch/$(ARCH)/config.in
config: symlinks
$(CONFIG_SHELL) scripts/Configure arch/$(ARCH)/config.in
......@@ -314,7 +313,7 @@ endif
clean: archclean
rm -f kernel/ksyms.lst include/linux/compile.h
rm -f core `find . -name '*.[oas]' ! -regex '.*lxdialog' -print`
rm -f core `find . -name '*.[oas]' ! -regex '.*lxdialog/.*' -print`
rm -f core `find . -type f -name 'core' -print`
rm -f vmlinux System.map
rm -f .tmp* drivers/sound/configure
......@@ -329,7 +328,7 @@ mrproper: clean
rm -f .version .config* config.in config.old
rm -f scripts/tkparse scripts/kconfig.tk scripts/kconfig.tmp
rm -f scripts/lxdialog/*.o scripts/lxdialog/lxdialog
rm -f .menuconfig.in
rm -f .menuconfig .menuconfig.log
rm -f include/asm
rm -f .depend `find . -name .depend -print`
rm -f .hdepend
......
......@@ -639,7 +639,7 @@ sys_call_table:
.quad sys_fsync, sys_setpriority, sys_socket, sys_connect, sys_accept
/*100*/ .quad osf_getpriority, sys_send, sys_recv, sys_sigreturn, sys_bind
.quad sys_setsockopt, sys_listen, do_entSys, do_entSys, do_entSys
.quad do_entSys, sys_sigsuspend, do_entSys, do_entSys, do_entSys
.quad do_entSys, sys_sigsuspend, do_entSys, sys_recvmsg, sys_sendmsg
.quad do_entSys, sys_gettimeofday, sys_getrusage, sys_getsockopt, do_entSys
.quad sys_readv, sys_writev, sys_settimeofday, sys_fchown, sys_fchmod
.quad sys_recvfrom, sys_setreuid, sys_setregid, sys_rename, sys_truncate
......@@ -686,5 +686,5 @@ sys_call_table:
.quad sys_setfsuid, sys_setfsgid, sys_ustat, sys_statfs, sys_fstatfs
.quad sys_sched_setparam, sys_sched_getparam, sys_sched_setscheduler, sys_sched_getscheduler, sys_sched_yield
.quad sys_sched_get_priority_max, sys_sched_get_priority_min, sys_sched_rr_get_interval, do_entSys /* sys_afs_syscall */, sys_newuname
.quad do_entSys, do_entSys, do_entSys, do_entSys, do_entSys
.quad sys_nanosleep, do_entSys, do_entSys, do_entSys, do_entSys
.quad do_entSys, do_entSys, do_entSys, do_entSys, do_entSys
This diff is collapsed.
......@@ -49,6 +49,8 @@ static struct symbol_table arch_symbol_table = {
X(strncpy),
X(strnlen),
X(strstr),
X(strtok),
X(strchr),
X(hwrpb),
X(memcmp),
X(memmove),
......@@ -72,6 +74,9 @@ static struct symbol_table arch_symbol_table = {
XNOVERS(__remlu),
XNOVERS(__remq),
XNOVERS(__remqu),
XNOVERS(memcpy),
XNOVERS(memset),
/* these shouldn't be necessary---they should be versioned: */
XNOVERS(__memcpy),
XNOVERS(__memset),
#include <linux/symtab_end.h>
......
......@@ -32,10 +32,10 @@
*/
#define FLTI_FUNC_ADDS 0x000
#define FLTI_FUNC_ADDT 0x020
#define FLTI_FUNC_CMPTEQ 0x0a5
#define FLTI_FUNC_CMPTLT 0x0a6
#define FLTI_FUNC_CMPTLE 0x0a7
#define FLTI_FUNC_CMPTUN 0x0a4
#define FLTI_FUNC_CMPTEQ 0x025
#define FLTI_FUNC_CMPTLT 0x026
#define FLTI_FUNC_CMPTLE 0x027
#define FLTI_FUNC_CMPTUN 0x024
#define FLTI_FUNC_CVTTS_or_CVTST 0x02c
#define FLTI_FUNC_CVTTQ 0x02f
#define FLTI_FUNC_CVTQS 0x03c
......@@ -288,8 +288,8 @@ alpha_fp_emul (unsigned long pc)
break;
default:
printk("alpha_fp_emul: unexpected function code %#lx at %#lx",
opcode, pc);
printk("alpha_fp_emul: unexpected function code %#lx at %#lx\n",
func & 0x3f, pc);
return 0;
}
/*
......
......@@ -7,8 +7,8 @@
* Much of the core SMP work is based on previous work by Thomas Radke, to
* whom a great many thanks are extended.
*
* Thanks to Intel for testing against several Pentium and Pentium Pro
* MP machines.
* Thanks to Intel for making available several different Pentium and
* Pentium Pro MP machines.
*
* This code is released under the GNU public license version 2 or
* later.
......@@ -543,7 +543,7 @@ void smp_boot_cpus(void)
* Map the local APIC into kernel space
*/
apic_reg = vremap(0xFEE00000,4096);
apic_reg = vremap(apic_addr,4096);
if(apic_reg == NULL)
panic("Unable to map local apic.\n");
......@@ -638,17 +638,19 @@ void smp_boot_cpus(void)
* Install a writable page 0 entry.
*/
cfg=pg0[0];
CMOS_WRITE(0xa, 0xf);
pg0[0]=7;
local_invalidate();
*((volatile unsigned short *) 0x467) = ((unsigned long)stack)>>4;
*((volatile unsigned short *) 0x469) = 0;
*((volatile unsigned short *) 0x469) = ((unsigned long)stack)>>4;
*((volatile unsigned short *) 0x467) = 0;
/*
* Protect it again
*/
pg0[0]= pte_val(mk_pte(0, PAGE_READONLY));
pg0[0]= cfg;
local_invalidate();
/*
......@@ -1048,7 +1050,7 @@ void smp_invalidate(void)
* Reschedule call back
*/
void smp_reschedule_irq(int cpl, void *dev_id, struct pt_regs *regs)
void smp_reschedule_irq(int cpl, struct pt_regs *regs)
{
#ifdef DEBUGGING_SMP_RESCHED
static int ct=0;
......
/* $Id: bare.S,v 1.2 1995/11/25 00:57:39 davem Exp $
/* $Id: bare.S,v 1.3 1995/11/27 02:42:50 davem Exp $
* base.S: Ugly low-level boot program entry code. The job of this
* module is to parse the boot flags, try to mount the remote
* root filesystem and load the kernel into virtual memory.
......@@ -51,7 +51,7 @@ C_LABEL(b_block_cksum):
start_of_execution:
sethi %hi(C_LABEL(first_adr_in_text)), %o1 ! This is our top
or %o1, %lo(C_LABEL(first_adr_in_text)), %o1 ! of stack too.
sub %o1, STACKFRAME_SZ, %o1
sub %o1, REGWIN_SZ, %o1
add %o1, 0x7, %o1
andn %o1, 0x7, %o1
save %o1, 0x0, %sp ! save is an add
......
# $Id: config.in,v 1.5 1995/11/25 00:57:32 davem Exp $
# $Id: config.in,v 1.8 1996/03/01 07:15:47 davem Exp $
# For a description of the syntax of this configuration file,
# see the Configure script.
#
......@@ -10,14 +10,16 @@ comment 'General setup'
# Global things across all Sparc machines.
define_bool CONFIG_SBUS y
define_bool CONFIG_SUN_MOUSE y
define_bool CONFIG_SERIAL y
define_bool CONFIG_SUN_SERIAL y
define_bool CONFIG_SUN_KEYBOARD y
define_bool CONFIG_SUN_CONSOLE y
define_bool CONFIG_NET_ALIAS n
define_bool CONFIG_BINFMT_AOUT y
bool 'Networking support' CONFIG_NET
bool 'System V IPC' CONFIG_SYSVIPC
tristate 'Kernel support for ELF binaries' CONFIG_BINFMT_ELF
tristate 'Kernel support for A.OUT binaries' CONFIG_BINFMT_AOUT
endmenu
source drivers/block/Config.in
......
......@@ -10,13 +10,14 @@ CONFIG_SUN_MOUSE=y
CONFIG_SUN_SERIAL=y
CONFIG_SUN_KEYBOARD=y
CONFIG_SUN_CONSOLE=y
# CONFIG_NET_ALIAS is not set
CONFIG_BINFMT_AOUT=y
CONFIG_NET=y
CONFIG_SYSVIPC=y
# CONFIG_BINFMT_ELF is not set
CONFIG_BINFMT_AOUT=y
#
# block devices
# Floppy, IDE, and other block devices
#
# CONFIG_BLK_DEV_FD is not set
......@@ -38,6 +39,10 @@ CONFIG_INET=y
# CONFIG_TCP_NAGLE_OFF is not set
CONFIG_IP_NOSR=y
# CONFIG_SKB_LARGE is not set
#
#
#
# CONFIG_IPX is not set
# CONFIG_ATALK is not set
# CONFIG_AX25 is not set
......@@ -52,8 +57,8 @@ CONFIG_SCSI=y
# SCSI support type (disk, tape, CDrom)
#
CONFIG_BLK_DEV_SD=y
CONFIG_CHR_DEV_ST=y
CONFIG_BLK_DEV_SR=y
# CONFIG_CHR_DEV_ST is not set
# CONFIG_BLK_DEV_SR is not set
# CONFIG_CHR_DEV_SG is not set
#
......@@ -79,19 +84,22 @@ CONFIG_SUNLANCE=y
#
# Filesystems
#
# CONFIG_QUOTA is not set
# CONFIG_MINIX_FS is not set
# CONFIG_EXT_FS is not set
CONFIG_EXT2_FS=y
# CONFIG_XIA_FS is not set
CONFIG_MSDOS_FS=y
# CONFIG_FAT_FS is not set
# CONFIG_MSDOS_FS is not set
# CONFIG_VFAT_FS is not set
# CONFIG_UMSDOS_FS is not set
CONFIG_PROC_FS=y
CONFIG_NFS_FS=y
CONFIG_ROOT_NFS=y
CONFIG_ISO9660_FS=y
# CONFIG_SMB_FS is not set
# CONFIG_ISO9660_FS is not set
# CONFIG_HPFS_FS is not set
# CONFIG_SYSV_FS is not set
# CONFIG_SMB_FS is not set
#
# Kernel hacking
......
# $Id: Makefile,v 1.18 1995/11/25 00:57:48 davem Exp $
# $Id: Makefile,v 1.22 1996/03/01 07:15:52 davem Exp $
# Makefile for the linux kernel.
#
# Note! Dependencies are done automagically by 'make dep', which also
......@@ -12,21 +12,18 @@
.S.o:
$(CC) -D__ASSEMBLY__ -ansi -c $< -o $*.o
OBJS = entry.o wof.o wuf.o etrap.o rtrap.o switch.o traps.o irq.o \
process.o signal.o ioport.o setup.o idprom.o probe.o mp.o \
c_mp.o sys_sparc.o sunos_asm.o sparc-stub.o systbls.o \
sys_sunos.o sunos_ioctl.o time.o
all: kernel.o head.o
O_TARGET := kernel.o
O_OBJS := entry.o wof.o wuf.o etrap.o rtrap.o switch.o traps.o irq.o \
process.o signal.o ioport.o setup.o idprom.o mp.o c_mp.o \
sys_sparc.o sunos_asm.o sparc-stub.o systbls.o sys_sunos.o \
sunos_ioctl.o time.o windows.o cpu.o auxio.o devices.o ksyms.o \
sclow.o
all: kernel.o head.o
head.o: head.S
$(CC) -D__ASSEMBLY__ -ansi -c $*.S -o $*.o
kernel.o: $(OBJS)
$(LD) -r -o kernel.o $(OBJS)
sync
dep:
$(CPP) -M *.c > .depend
include $(TOPDIR)/Rules.make
/* auxio.c: Probing for the Sparc AUXIO register at boot time.
*
* Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
*/
#include <asm/oplib.h>
#include <asm/io.h>
/* Probe and map in the Auxiliary I/O register */
unsigned char *auxio_register;
void
auxio_probe(void)
{
int node, auxio_nd;
struct linux_prom_registers auxregs[1];
node = prom_getchild(prom_root_node);
auxio_nd = prom_searchsiblings(node, "auxiliary-io");
if(!auxio_nd) {
node = prom_searchsiblings(node, "obio");
node = prom_getchild(node);
auxio_nd = prom_searchsiblings(node, "auxio");
if(!auxio_nd) {
prom_printf("Cannot find auxio node, cannot continue...\n");
prom_halt();
}
}
prom_getproperty(auxio_nd, "reg", (char *) auxregs, sizeof(auxregs));
prom_apply_obio_ranges(auxregs, 0x1);
/* Map the register both read and write */
auxio_register = (unsigned char *) sparc_alloc_io(auxregs[0].phys_addr, 0,
auxregs[0].reg_size,
"auxilliaryIO",
auxregs[0].which_io, 0x0);
/* Fix the address on sun4m and sun4c. */
if((((unsigned long) auxregs[0].phys_addr) & 3) == 3 ||
sparc_cpu_model == sun4c)
auxio_register = (unsigned char *) ((int)auxio_register | 3);
}
/* cpu.c: Dinky routines to look for the kind of Sparc cpu
* we are on.
*
* Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
*/
#include <linux/kernel.h>
#include <asm/oplib.h>
#include <asm/head.h>
#include <asm/psr.h>
#include <asm/mbus.h>
struct cpu_iu_info {
int psr_impl;
int psr_vers;
char* cpu_name; /* should be enough I hope... */
};
struct cpu_fp_info {
int psr_impl;
int fp_vers;
char* fp_name;
};
/* In order to get the fpu type correct, you need to take the IDPROM's
* machine type value into consideration too. I will fix this.
*/
struct cpu_fp_info linux_sparc_fpu[] = {
{ 0, 0, "Fujitsu MB86910 or Weitek WTL1164/5"},
{ 0, 1, "Fujitsu MB86911 or Weitek WTL1164/5 or LSI L64831"},
{ 0, 2, "LSI Logic L64802 or Texas Instruments ACT8847"},
/* SparcStation SLC, SparcStation1 */
{ 0, 3, "Weitek WTL3170/2"},
/* SPARCstation-5 */
{ 0, 4, "Lsi Logic/Meiko L64804 or compatible"},
{ 0, 5, "reserved"},
{ 0, 6, "reserved"},
{ 0, 7, "No FPU"},
{ 1, 0, "ROSS HyperSparc combined IU/FPU"},
{ 1, 1, "Lsi Logic L64814"},
{ 1, 2, "Texas Instruments TMS390-C602A"},
{ 1, 3, "Cypress CY7C602 FPU"},
{ 1, 4, "reserved"},
{ 1, 5, "reserved"},
{ 1, 6, "reserved"},
{ 1, 7, "No FPU"},
{ 2, 0, "BIT B5010 or B5110/20 or B5210"},
{ 2, 1, "reserved"},
{ 2, 2, "reserved"},
{ 2, 3, "reserved"},
{ 2, 4, "reserved"},
{ 2, 5, "reserved"},
{ 2, 6, "reserved"},
{ 2, 7, "No FPU"},
/* SuperSparc 50 module */
{ 4, 0, "SuperSparc on-chip FPU"},
/* SparcClassic */
{ 4, 4, "TI MicroSparc on chip FPU"},
{ 5, 0, "Matsushita MN10501"},
{ 5, 1, "reserved"},
{ 5, 2, "reserved"},
{ 5, 3, "reserved"},
{ 5, 4, "reserved"},
{ 5, 5, "reserved"},
{ 5, 6, "reserved"},
{ 5, 7, "No FPU"},
};
#define NSPARCFPU (sizeof(linux_sparc_fpu)/sizeof(struct cpu_fp_info))
struct cpu_iu_info linux_sparc_chips[] = {
/* Sun4/100, 4/200, SLC */
{ 0, 0, "Fujitsu MB86900/1A or LSI L64831 SparcKIT-40"},
/* borned STP1012PGA */
{ 0, 4, "Fujitsu MB86904"},
/* SparcStation2, SparcServer 490 & 690 */
{ 1, 0, "LSI Logic Corporation - L64811"},
/* SparcStation2 */
{ 1, 1, "Cypress/ROSS CY7C601"},
/* Embedded controller */
{ 1, 3, "Cypress/ROSS CY7C611"},
/* Ross Technologies HyperSparc */
{ 1, 0xf, "ROSS HyperSparc RT620"},
{ 1, 0xe, "ROSS HyperSparc RT625"},
/* ECL Implementation, CRAY S-MP Supercomputer... AIEEE! */
/* Someone please write the code to support this beast! ;) */
{ 2, 0, "Bipolar Integrated Technology - B5010"},
{ 3, 0, "LSI Logic Corporation - unknown-type"},
{ 4, 0, "Texas Instruments, Inc. - SuperSparc 50"},
/* SparcClassic -- borned STP1010TAB-50*/
{ 4, 1, "Texas Instruments, Inc. - MicroSparc"},
{ 4, 2, "Texas Instruments, Inc. - MicroSparc II"},
{ 4, 3, "Texas Instruments, Inc. - SuperSparc 51"},
{ 4, 4, "Texas Instruments, Inc. - SuperSparc 61"},
{ 4, 5, "Texas Instruments, Inc. - unknown"},
{ 5, 0, "Matsushita - MN10501"},
{ 6, 0, "Philips Corporation - unknown"},
{ 7, 0, "Harvest VLSI Design Center, Inc. - unknown"},
/* Gallium arsenide 200MHz, BOOOOGOOOOMIPS!!! */
{ 8, 0, "Systems and Processes Engineering Corporation (SPEC)"},
{ 9, 0, "Fujitsu #3"},
{ 0xa, 0, "UNKNOWN CPU-VENDOR/TYPE"},
{ 0xb, 0, "UNKNOWN CPU-VENDOR/TYPE"},
{ 0xc, 0, "UNKNOWN CPU-VENDOR/TYPE"},
{ 0xd, 0, "UNKNOWN CPU-VENDOR/TYPE"},
{ 0xe, 0, "UNKNOWN CPU-VENDOR/TYPE"},
{ 0xf, 0, "UNKNOWN CPU-VENDOR/TYPE"},
};
#define NSPARCCHIPS (sizeof(linux_sparc_chips)/sizeof(struct cpu_iu_info))
char *sparc_cpu_type[NCPUS] = { "cpu-oops", "cpu-oops1", "cpu-oops2", "cpu-oops3" };
char *sparc_fpu_type[NCPUS] = { "fpu-oops", "fpu-oops1", "fpu-oops2", "fpu-oops3" };
unsigned int fsr_storage;
void
cpu_probe(void)
{
int psr_impl, psr_vers, fpu_vers;
int i, cpuid;
cpuid = get_cpuid();
psr_impl = ((get_psr()>>28)&0xf);
psr_vers = ((get_psr()>>24)&0xf);
fpu_vers = ((get_fsr()>>17)&0x7);
for(i = 0; i<NSPARCCHIPS; i++) {
if(linux_sparc_chips[i].psr_impl == psr_impl)
if(linux_sparc_chips[i].psr_vers == psr_vers) {
sparc_cpu_type[cpuid] = linux_sparc_chips[i].cpu_name;
break;
}
}
if(i==NSPARCCHIPS)
printk("DEBUG: psr.impl = 0x%x psr.vers = 0x%x\n", psr_impl,
psr_vers);
for(i = 0; i<NSPARCFPU; i++) {
if(linux_sparc_fpu[i].psr_impl == psr_impl)
if(linux_sparc_fpu[i].fp_vers == fpu_vers) {
sparc_fpu_type[cpuid] = linux_sparc_fpu[i].fp_name;
break;
}
}
if(i == NSPARCFPU) {
printk("DEBUG: psr.impl = 0x%x fsr.vers = 0x%x\n", psr_impl,
fpu_vers);
sparc_fpu_type[cpuid] = linux_sparc_fpu[31].fp_name;
}
}
/* devices.c: Initial scan of the prom device tree for important
* Sparc device nodes which we need to find.
*
* Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
*/
#include <linux/kernel.h>
#include <asm/page.h>
#include <asm/oplib.h>
#include <asm/mp.h>
#include <asm/system.h>
struct prom_cpuinfo linux_cpus[NCPUS];
int linux_num_cpus;
extern void cpu_probe(void);
extern void auxio_probe(void);
unsigned long
device_scan(unsigned long mem_start)
{
char node_str[128];
int nd, prom_node_cpu, thismid;
int cpu_nds[NCPUS]; /* One node for each cpu */
int cpu_ctr = 0;
prom_getstring(prom_root_node, "device_type", node_str, sizeof(node_str));
if(strcmp(node_str, "cpu") == 0) {
cpu_nds[0] = prom_root_node;
cpu_ctr++;
} else {
int scan;
scan = prom_getchild(prom_root_node);
nd = 0;
while((scan = prom_getsibling(scan)) != 0) {
prom_getstring(scan, "device_type", node_str, sizeof(node_str));
if(strcmp(node_str, "cpu") == 0) {
cpu_nds[cpu_ctr] = scan;
linux_cpus[cpu_ctr].prom_node = scan;
prom_getproperty(scan, "mid", (char *) &thismid, sizeof(thismid));
linux_cpus[cpu_ctr].mid = thismid;
cpu_ctr++;
}
};
if(cpu_ctr == 0) {
printk("No CPU nodes found, cannot continue.\n");
/* Probably a sun4d or sun4e, Sun is trying to trick us ;-) */
halt();
}
printk("Found %d CPU prom device tree node(s).\n", cpu_ctr);
};
prom_node_cpu = cpu_nds[0];
linux_num_cpus = cpu_ctr;
cpu_probe();
auxio_probe();
return mem_start;
}
This diff is collapsed.
/* $Id: etrap.S,v 1.10 1995/11/25 00:57:58 davem Exp $
/* $Id: etrap.S,v 1.16 1996/02/20 07:45:01 davem Exp $
* etrap.S: Sparc trap window preparation for entry into the
* Linux kernel.
*
......@@ -7,6 +7,8 @@
#include <asm/cprefix.h>
#include <asm/head.h>
#include <asm/asi.h>
#include <asm/contregs.h>
#include <asm/page.h>
#include <asm/psr.h>
#include <asm/ptrace.h>
......@@ -84,8 +86,8 @@ trap_setup:
/* From kernel, allocate more kernel stack and
* build a pt_regs trap frame.
*/
sub %fp, (STACKFRAME_SZ + TRACEREG_SZ), %t_kstack
STORE_PT_ALL(t_kstack, t_psr, t_pc, t_npc, t_wim, g2)
sub %fp, (REGWIN_SZ + TRACEREG_SZ), %t_kstack
STORE_PT_ALL(t_kstack, t_psr, t_pc, t_npc, g2)
/* See if we are in the trap window. */
andcc %t_twinmask, %t_wim, %g0
......@@ -99,12 +101,11 @@ trap_setup:
* Just do it...
*/
1:
mov %t_kstack, %sp ! jump onto new stack
jmpl %t_retpc + 0x8, %g0 ! return to caller
nop
mov %t_kstack, %sp ! jump onto new stack
trap_setup_kernel_spill:
LOAD_CURRENT(curptr)
LOAD_CURRENT(curptr, g1)
ld [%curptr + THREAD_UMASK], %g1
orcc %g0, %g1, %g0
bne trap_setup_user_spill ! there are some user windows, yuck
......@@ -129,21 +130,21 @@ tsetup_patch2: and %g2, 0xff, %g2 ! patched on 7 window Sparcs
restore %g0, %g0, %g0
mov %t_kstack, %sp ! and onto new kernel stack
jmpl %t_retpc + 0x8, %g0 ! return to caller
nop
mov %t_kstack, %sp ! and onto new kernel stack
trap_setup_from_user:
/* We can't use %curptr yet. */
LOAD_CURRENT(t_kstack)
ld [%t_kstack + TASK_KSTACK_PG], %t_kstack
LOAD_CURRENT(t_kstack, t_twinmask)
mov 1, %t_twinmask
ld [%t_kstack + TASK_SAVED_KSTACK], %t_kstack
sll %t_twinmask, %t_psr, %t_twinmask ! t_twinmask = (1 << psr)
/* Build pt_regs frame. */
add %t_kstack, (PAGE_SIZE - STACKFRAME_SZ - TRACEREG_SZ), %t_kstack
STORE_PT_ALL(t_kstack, t_psr, t_pc, t_npc, t_wim, g2)
STORE_PT_ALL(t_kstack, t_psr, t_pc, t_npc, g2)
/* Clear current->tss.w_saved */
LOAD_CURRENT(curptr)
LOAD_CURRENT(curptr, g1)
st %g0, [%curptr + THREAD_W_SAVED]
/* See if we are in the trap window. */
......@@ -176,9 +177,8 @@ trap_setup_from_user:
tsetup_patch3: and %g2, 0xff, %g2 ! patched on 7win Sparcs
st %g2, [%curptr + THREAD_UMASK] ! store new umask
mov %t_kstack, %sp ! and onto kernel stack
jmpl %t_retpc + 0x8, %g0 ! return to caller
nop
mov %t_kstack, %sp ! and onto kernel stack
trap_setup_user_spill:
/* A spill occured from either kernel or user mode
......@@ -213,18 +213,18 @@ trap_setup_user_stack_is_bolixed:
*/
SAVE_BOLIXED_USER_STACK(curptr, g3)
restore %g0, %g0, %g0
mov %t_kstack, %sp
jmpl %t_retpc + 0x8, %g0
nop
mov %t_kstack, %sp
trap_setup_good_ustack:
STORE_WINDOW(sp)
trap_setup_finish_up:
restore %g0, %g0, %g0
mov %t_kstack, %sp
jmpl %t_retpc + 0x8, %g0
nop
mov %t_kstack, %sp
/* Architecture specific stack checking routines. When either
* of these routines are called, the globals are free to use
......@@ -234,7 +234,6 @@ trap_setup_finish_up:
#define glob_tmp g1
.globl C_LABEL(tsetup_sun4c_stackchk)
.globl C_LABEL(tsetup_srmmu_stackchk)
C_LABEL(tsetup_sun4c_stackchk):
/* Done by caller: andcc %sp, 0x7, %g0 */
be 1f
......@@ -293,6 +292,7 @@ tsetup_sun4c_onepage:
b trap_setup_user_stack_is_bolixed
nop
.globl C_LABEL(tsetup_srmmu_stackchk)
C_LABEL(tsetup_srmmu_stackchk):
/* Check results of callers andcc %sp, 0x7, %g0 */
bne trap_setup_user_stack_is_bolixed
......@@ -302,8 +302,6 @@ C_LABEL(tsetup_srmmu_stackchk):
nop
/* Clear the fault status and turn on the no_fault bit. */
mov AC_M_SFSR, %glob_tmp ! delay from above...
lda [%glob_tmp] ASI_M_MMUREGS, %g0 ! eat SFSR
lda [%g0] ASI_M_MMUREGS, %glob_tmp ! read MMU control
or %glob_tmp, 0x2, %glob_tmp ! or in no_fault bit
sta %glob_tmp, [%g0] ASI_M_MMUREGS ! set it
......@@ -317,10 +315,11 @@ C_LABEL(tsetup_srmmu_stackchk):
mov AC_M_SFAR, %glob_tmp
lda [%glob_tmp] ASI_M_MMUREGS, %g0
mov AC_M_SFSR, %glob_tmp
lda [%glob_tmp] ASI_M_MMUREGS, %glob_tmp
lda [%glob_tmp] ASI_M_MMUREGS, %glob_tmp ! save away status of winstore
andcc %glob_tmp, 0x2, %g0 ! did we fault?
be trap_setup_finish_up ! cool beans, success
nop
b trap_setup_user_stack_is_bolixed ! we faulted, ugh
nop
/* $Id: head.S,v 1.39 1995/11/25 00:58:01 davem Exp $
/* $Id: head.S,v 1.47 1996/02/15 09:11:57 davem Exp $
* head.S: The initial boot code for the Sparc port of Linux.
*
* Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
......@@ -49,7 +49,7 @@ C_LABEL(cputypvallen) = C_LABEL(cputypvar) - C_LABEL(cputypval)
C_LABEL(cputypvar):
.asciz "compatability"
/* Tested on SS-5, SS-10. Probably someone at Sun applied a spell-checker. --P3 */
/* Tested on SS-5, SS-10. Probably someone at Sun applied a spell-checker. */
.align 4
C_LABEL(cputypvar_sun4m):
.asciz "compatible"
......@@ -82,7 +82,7 @@ start:
C_LABEL(trapbase):
/* We get control passed to us here at t_zero. */
t_zero: b gokernel; nop; nop; nop;
t_tflt: TRAP_ENTRY(0x1, sparc_fault) /* Inst. Access Exception */
t_tflt: SPARC_TFAULT /* Inst. Access Exception */
t_bins: TRAP_ENTRY(0x2, bad_instruction) /* Illegal Instruction */
t_pins: TRAP_ENTRY(0x3, priv_instruction) /* Privileged Instruction */
t_fpd: TRAP_ENTRY(0x4, fpd_trap_handler) /* Floating Point Disabled */
......@@ -90,16 +90,16 @@ t_wovf: WINDOW_SPILL /* Window Overflow */
t_wunf: WINDOW_FILL /* Window Underflow */
t_mna: TRAP_ENTRY(0x7, mna_handler) /* Memory Address Not Aligned */
t_fpe: TRAP_ENTRY(0x8, fpe_trap_handler) /* Floating Point Exception */
t_dflt: TRAP_ENTRY(0x9, sparc_fault) /* Data Miss Exception */
t_dflt: SPARC_DFAULT /* Data Miss Exception */
t_tio: TRAP_ENTRY(0xa, do_tag_overflow) /* Tagged Instruction Ovrflw */
t_wpt: TRAP_ENTRY(0xb, do_watchpoint) /* Watchpoint Detected */
t_badc: BAD_TRAP(0xc) BAD_TRAP(0xd) BAD_TRAP(0xe) BAD_TRAP(0xf) BAD_TRAP(0x10)
t_irq1: TRAP_ENTRY_SOFTINT(1) /* IRQ Software/SBUS Level 1 */
t_irq1: TRAP_ENTRY_INTERRUPT(1) /* IRQ Software/SBUS Level 1 */
t_irq2: TRAP_ENTRY_INTERRUPT(2) /* IRQ SBUS Level 2 */
t_irq3: TRAP_ENTRY_INTERRUPT(3) /* IRQ SCSI/DMA/SBUS Level 3 */
t_irq4: TRAP_ENTRY_SOFTINT(4) /* IRQ Software Level 4 */
t_irq4: TRAP_ENTRY_INTERRUPT(4) /* IRQ Software Level 4 */
t_irq5: TRAP_ENTRY_INTERRUPT(5) /* IRQ SBUS/Ethernet Level 5 */
t_irq6: TRAP_ENTRY_SOFTINT(6) /* IRQ Software Level 6 */
t_irq6: TRAP_ENTRY_INTERRUPT(6) /* IRQ Software Level 6 */
t_irq7: TRAP_ENTRY_INTERRUPT(7) /* IRQ Video/SBUS Level 5 */
t_irq8: TRAP_ENTRY_INTERRUPT(8) /* IRQ SBUS Level 6 */
t_irq9: TRAP_ENTRY_INTERRUPT(9) /* IRQ SBUS Level 7 */
......@@ -110,20 +110,20 @@ t_irq13:TRAP_ENTRY_INTERRUPT(13) /* IRQ Audio Intr. */
t_irq14:TRAP_ENTRY_INTERRUPT(14) /* IRQ Timer #2 */
t_nmi: NMI_TRAP /* Level 15 (NMI) */
t_racc: TRAP_ENTRY(0x20, do_reg_access) /* General Register Access Error */
t_iacce:TRAP_ENTRY(0x21, sparc_fault) /* Instr Access Error */
t_iacce:BAD_TRAP(0x21) /* Instr Access Error */
t_bad22:BAD_TRAP(0x22) BAD_TRAP(0x23)
t_cpdis:TRAP_ENTRY(0x24, do_cp_disabled) /* Co-Processor Disabled */
t_uflsh:TRAP_ENTRY(0x25, do_bad_flush) /* Unimplemented FLUSH inst. */
t_bad26:BAD_TRAP(0x26) BAD_TRAP(0x27)
t_cpexc:TRAP_ENTRY(0x28, do_cp_exception) /* Co-Processor Exception */
t_dacce:TRAP_ENTRY(0x29, sparc_fault) /* Data Access Error */
t_dacce:BAD_TRAP(0x29) /* Data Access Error */
t_hwdz: TRAP_ENTRY(0x2a, do_hw_divzero) /* Division by zero, you lose... */
t_dserr:TRAP_ENTRY(0x2b, sparc_fault) /* Data Store Error */
t_daccm:TRAP_ENTRY(0x2c, sparc_fault) /* Data Access MMU-Miss */
t_dserr:BAD_TRAP(0x2b) /* Data Store Error */
t_daccm:BAD_TRAP(0x2c) /* Data Access MMU-Miss */
t_bad2d:BAD_TRAP(0x2d) BAD_TRAP(0x2e) BAD_TRAP(0x2f) BAD_TRAP(0x30) BAD_TRAP(0x31)
t_bad32:BAD_TRAP(0x32) BAD_TRAP(0x33) BAD_TRAP(0x34) BAD_TRAP(0x35) BAD_TRAP(0x36)
t_bad37:BAD_TRAP(0x37) BAD_TRAP(0x38) BAD_TRAP(0x39) BAD_TRAP(0x3a) BAD_TRAP(0x3b)
t_iaccm:TRAP_ENTRY(0x3c, sparc_fault) /* Instr Access MMU-Miss */
t_iaccm:BAD_TRAP(0x3c) /* Instr Access MMU-Miss */
t_bad3d:BAD_TRAP(0x3d) BAD_TRAP(0x3e) BAD_TRAP(0x3f) BAD_TRAP(0x40) BAD_TRAP(0x41)
t_bad42:BAD_TRAP(0x42) BAD_TRAP(0x43) BAD_TRAP(0x44) BAD_TRAP(0x45) BAD_TRAP(0x46)
t_bad47:BAD_TRAP(0x47) BAD_TRAP(0x48) BAD_TRAP(0x49) BAD_TRAP(0x4a) BAD_TRAP(0x4b)
......@@ -186,16 +186,6 @@ C_LABEL(end_traptable):
/* This was the only reasonable way I could think of to properly align
* these page-table data structures.
*/
.globl C_LABEL(auxio_reg_addr)
C_LABEL(auxio_reg_addr): .skip (PAGE_SIZE)
.globl C_LABEL(clock_reg_addr)
C_LABEL(clock_reg_addr): .skip (PAGE_SIZE*5)
.globl C_LABEL(int_reg_addr)
C_LABEL(int_reg_addr): .skip (PAGE_SIZE*5)
.globl C_LABEL(bootup_user_stack)
.globl C_LABEL(bootup_kernel_stack)
.globl C_LABEL(pg0)
......@@ -279,21 +269,6 @@ copy_prom_lvl14:
ldd [%g2 + 0x8], %g4
std %g4, [%g3 + 0x8] ! Copy proms handler
/* Copy over the Prom/debugger's trap entry points. */
copy_prom_bpoint:
or %g0, (0xfe<<4), %g2
or %g1, %g2, %g2
set dbtrap, %g3
sub %g3, %l6, %g3
ldd [%g2], %g4
std %g4, [%g3]
ldd [%g2 + 0x8], %g4
std %g4, [%g3 + 0x8]
ldd [%g2 + 0x10], %g4
std %g4, [%g3 + 0x10]
ldd [%g2 + 0x18], %g4
std %g4, [%g3 + 0x18]
/* Must determine whether we are on a sun4c MMU, SRMMU, or SUN4/400 MUTANT
* MMU so we can remap ourselves properly. DONT TOUCH %l0 thru %l5 in these
* remapping routines, we need their values afterwards!
......@@ -652,7 +627,7 @@ sun4c_continue_boot:
/* I want a kernel stack NOW! */
set C_LABEL(bootup_user_stack), %g1
add %g1, (PAGE_SIZE - STACKFRAME_SZ - TRACEREG_SZ), %sp
add %g1, (PAGE_SIZE - REGWIN_SZ), %sp
mov 0, %fp /* And for good luck */
/* Zero out our BSS section. */
......@@ -673,7 +648,7 @@ sun4c_continue_boot:
st %g4, [%g2]
/* So now this should work. */
LOAD_CURRENT(g2)
LOAD_CURRENT(g2, g4)
set C_LABEL(bootup_kernel_stack), %g4
st %g4, [%g2 + TASK_KSTACK_PG]
st %g0, [%g2 + THREAD_UMASK]
......
/* $Id: ioport.c,v 1.12 1995/11/25 00:58:07 davem Exp $
/* $Id: ioport.c,v 1.14 1996/01/03 03:34:41 davem Exp $
* ioport.c: Simple io mapping allocator.
*
* Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
......@@ -54,20 +54,19 @@ void *sparc_alloc_io (void *address, void *virtual, int len, char *name,
unsigned long addr = (unsigned long) address;
unsigned long offset = (addr & (~PAGE_MASK));
if (virtual){
if (virtual)
vaddr = (unsigned long) virtual;
} else {
else
vaddr = next_free_region;
}
len += offset;
if (((unsigned long) virtual + len) > (IOBASE_VADDR + IOBASE_LEN)){
printk ("alloc_io: Mapping ouside IOBASE area\n");
prom_halt ();
if(((unsigned long) virtual + len) > (IOBASE_VADDR + IOBASE_LEN)) {
prom_printf("alloc_io: Mapping ouside IOBASE area\n");
prom_halt();
}
if (check_region ((vaddr | offset), len)){
printk ("alloc_io: 0x%lx is already in use\n", vaddr);
prom_halt ();
if(check_region ((vaddr | offset), len)) {
prom_printf("alloc_io: 0x%lx is already in use\n", vaddr);
prom_halt();
}
/* Tell Linux resource manager about the mapping */
......@@ -75,10 +74,10 @@ void *sparc_alloc_io (void *address, void *virtual, int len, char *name,
base_address = vaddr;
/* Do the actual mapping */
for (; len > 0; len -= PAGE_SIZE){
mapioaddr (addr, vaddr, bus_type, rdonly);
for (; len > 0; len -= PAGE_SIZE) {
mapioaddr(addr, vaddr, bus_type, rdonly);
vaddr += PAGE_SIZE;
addr += PAGE_SIZE;
addr += PAGE_SIZE;
if (!virtual)
next_free_region += PAGE_SIZE;
}
......@@ -99,13 +98,13 @@ void *sparc_dvma_malloc (int len, char *name)
unsigned long vaddr, base_address;
vaddr = dvma_next_free;
if (check_region (vaddr, len)){
printk ("alloc_dma: 0x%lx is already in use\n", vaddr);
prom_halt ();
if(check_region (vaddr, len)) {
prom_printf("alloc_dma: 0x%lx is already in use\n", vaddr);
prom_halt();
}
if (vaddr + len > (DVMA_VADDR + DVMA_LEN)){
printk ("alloc_dvma: out of dvma memory\n");
prom_halt ();
if(vaddr + len > (DVMA_VADDR + DVMA_LEN)) {
prom_printf("alloc_dvma: out of dvma memory\n");
prom_halt();
}
/* Basically these can be mapped just like any old
......
This diff is collapsed.
/* $Id: ksyms.c,v 1.1 1996/02/25 06:30:18 davem Exp $
* arch/sparc/kernel/ksyms.c: Sparc specific ksyms support.
*
* Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
*/
#include <linux/config.h>
#include <linux/module.h>
#include <linux/types.h>
/* We really haven't played around with modules at all in our
* port, but this is here as a starting point for when we do.
* One thing to note is that the way the symbols of the mul/div
* support routines are named is a mess, they all start with
* a '.' which makes it a bitch to export, we'll see.
*/
extern void bcopy (const char *src, char *dst, int len);
extern void * memmove(void *,const void *,size_t);
extern void * memcpy(void *,const void *,size_t);
static struct symbol_table arch_symbol_table = {
#include <linux/symtab_begin.h>
/* platform dependent support */
X(bcopy),
X(memmove),
X(memcpy),
#include <linux/symtab_end.h>
};
void arch_syms_export(void)
{
register_symtab(&arch_symbol_table);
}
/* $Id: probe.c,v 1.39 1995/11/26 00:54:37 davem Exp $
/* $Id: probe.c,v 1.42 1995/12/26 01:38:08 davem Exp $
* probe.c: Preliminary device tree probing routines...
*
* Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
......@@ -187,9 +187,6 @@ probe_cpu(void)
fpu_vers);
sparc_fpu_type[cpuid] = linux_sparc_fpu[31].fp_name;
}
printk("cpu%d CPU: %s \n", cpuid, sparc_cpu_type[cpuid]);
printk("cpu%d FPU: %s \n", cpuid, sparc_fpu_type[cpuid]);
}
void
......@@ -212,8 +209,9 @@ probe_vac(void)
sun4c_vacinfo.log2lsize = 5;
break;
default:
printk("probe_vac: Didn't expect vac-linesize of %d, halting\n",
prom_printf("probe_vac: Didn't expect vac-linesize of %d, halting\n",
sun4c_vacinfo.linesize);
prom_halt();
};
propval = prom_getintdefault(prom_root_node, "vac_hwflush", -1);
......@@ -222,49 +220,13 @@ probe_vac(void)
"vac-hwflush", 0) :
propval);
printk("SUN4C: VAC size %d line size %d using %s flushes ",
sun4c_vacinfo.num_bytes, sun4c_vacinfo.linesize,
(sun4c_vacinfo.do_hwflushes ? "hardware" : "software"));
if(sun4c_vacinfo.num_bytes != 65536) {
printk("WEIRD Sun4C VAC cache size, tell davem");
prom_printf("WEIRD Sun4C VAC cache size, tell davem");
prom_halt();
}
/* setup the low-level assembly routine ptrs */
if(sun4c_vacinfo.do_hwflushes) {
if(sun4c_vacinfo.linesize == 16) {
sun4c_ctxflush = (unsigned long)sun4c_ctxflush_hw64KB16B;
sun4c_segflush = (unsigned long)sun4c_segflush_hw64KB16B;
sun4c_pgflush = (unsigned long)sun4c_pgflush_hw64KB16B;
} else if(sun4c_vacinfo.linesize == 32) {
sun4c_ctxflush = (unsigned long)sun4c_ctxflush_hw64KB32B;
sun4c_segflush = (unsigned long)sun4c_segflush_hw64KB32B;
sun4c_pgflush = (unsigned long)sun4c_pgflush_hw64KB32B;
} else {
printk("WEIRD Sun4C VAC cache line size, tell davem\n");
prom_halt();
}
} else {
if(sun4c_vacinfo.linesize == 16) {
sun4c_ctxflush = (unsigned long)sun4c_ctxflush_sw64KB16B;
sun4c_segflush = (unsigned long)sun4c_segflush_sw64KB16B;
sun4c_pgflush = (unsigned long)sun4c_pgflush_sw64KB16B;
} else if(sun4c_vacinfo.linesize == 32) {
sun4c_ctxflush = (unsigned long)sun4c_ctxflush_sw64KB32B;
sun4c_segflush = (unsigned long)sun4c_segflush_sw64KB32B;
sun4c_pgflush = (unsigned long)sun4c_pgflush_sw64KB32B;
} else {
printk("WEIRD Sun4C VAC cache line size, tell davem\n");
prom_halt();
}
}
sun4c_flush_all();
sun4c_enable_vac();
printk("enabled\n");
return;
}
extern int num_segmaps, num_contexts;
......@@ -284,9 +246,6 @@ probe_mmu(void)
/* A sun4, sun4c or sun4e. */
num_segmaps = prom_getintdefault(prom_root_node, "mmu-npmg", 128);
num_contexts = find_mmu_num_contexts(prom_root_node);
printk("cpu%d MMU segmaps: %d MMU contexts: %d\n", cpuid,
num_segmaps, num_contexts);
break;
default:
printk("cpu%d probe_mmu: sparc_cpu_model botch\n", cpuid);
......@@ -444,9 +403,6 @@ probe_auxio(void)
/* Map the register both read and write */
sparc_alloc_io(auxregs[0].phys_addr, (void *) AUXIO_VADDR,
auxregs[0].reg_size, "auxilliaryIO", auxregs[0].which_io, 0x0);
printk("Mapped AUXIO at paddr %08lx vaddr %08lx\n",
(unsigned long) auxregs[0].phys_addr,
(unsigned long) AUXIO_VADDR);
}
extern unsigned long probe_memory(void);
......@@ -495,7 +451,9 @@ probe_devices(unsigned long mem_start)
linux_num_cpus = cpu_ctr;
for(i=0; i<cpu_ctr; i++) {
prom_getstring(cpu_nds[i], "name", node_str, sizeof(node_str));
#if 0
printk("cpu%d: %s \n", i, node_str);
#endif
}
probe_cpu();
......
/* $Id: process.c,v 1.29 1995/11/25 00:58:17 davem Exp $
/* $Id: process.c,v 1.42 1996/02/20 07:45:08 davem Exp $
* linux/arch/sparc/kernel/process.c
*
* Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
......@@ -26,10 +26,13 @@
#include <asm/system.h>
#include <asm/page.h>
#include <asm/pgtable.h>
#include <asm/delay.h>
#include <asm/processor.h>
#include <asm/psr.h>
int current_user_segment = USER_DS; /* the return value from get_fs */
extern void fpsave(unsigned long *, unsigned long *, void *, unsigned long *);
int active_ds = USER_DS;
/*
* the idle loop on a Sparc... ;)
......@@ -46,9 +49,15 @@ asmlinkage int sys_idle(void)
}
}
extern char saved_command_line[];
void hard_reset_now(void)
{
prom_halt();
sti();
udelay(8000);
cli();
prom_feval("reset");
panic("Reboot failed!");
}
void show_regwindow(struct reg_window *rw)
......@@ -84,9 +93,15 @@ void show_regs(struct pt_regs * regs)
*/
void exit_thread(void)
{
if(last_task_used_math == current)
flush_user_windows();
if(last_task_used_math == current) {
/* Keep process from leaving FPU in a bogon state. */
put_psr(get_psr() | PSR_EF);
fpsave(&current->tss.float_regs[0], &current->tss.fsr,
&current->tss.fpqueue[0], &current->tss.fpqdepth);
last_task_used_math = NULL;
mmu_exit_hook(current);
}
mmu_exit_hook();
}
/*
......@@ -94,29 +109,33 @@ void exit_thread(void)
*/
void release_thread(struct task_struct *dead_task)
{
mmu_release_hook(dead_task);
}
void flush_thread(void)
{
/* Make sure old user windows don't get in the way. */
mmu_flush_hook(current);
flush_user_windows();
current->signal &= ~(1<<(SIGILL-1));
current->tss.w_saved = 0;
current->tss.uwinmask = 0;
current->tss.sig_address = 0;
current->tss.sig_desc = 0;
/* Signal stack state does not inherit. XXX Really? XXX */
current->tss.sstk_info.cur_status = 0;
current->tss.sstk_info.the_stack = 0;
if(last_task_used_math == current) {
/* Clean the fpu. */
put_psr(get_psr() | PSR_EF);
fpsave(&current->tss.float_regs[0], &current->tss.fsr,
&current->tss.fpqueue[0], &current->tss.fpqdepth);
}
memset(&current->tss.reg_window[0], 0,
(sizeof(struct reg_window) * NSWINS));
memset(&current->tss.rwbuf_stkptrs[0], 0,
(sizeof(unsigned long) * NSWINS));
mmu_flush_hook();
/* Now, this task is no longer a kernel thread. */
current->tss.flags &= ~SPARC_FLAG_KTHREAD;
}
/*
......@@ -125,7 +144,12 @@ void flush_thread(void)
* Parent --> %o0 == childs pid, %o1 == 0
* Child --> %o0 == parents pid, %o1 == 1
*
* I'm feeling sick...
* NOTE: We have a seperate fork kpsr/kwim because
* the parent could change these values between
* sys_fork invocation and when we reach here
* if the parent should sleep while trying to
* allocate the task_struct and kernel stack in
* do_fork().
*/
extern void ret_sys_call(void);
......@@ -133,34 +157,37 @@ void copy_thread(int nr, unsigned long clone_flags, unsigned long sp,
struct task_struct *p, struct pt_regs *regs)
{
struct pt_regs *childregs;
struct sparc_stackf *old_stack, *new_stack;
unsigned long stack_offset, kthread_usp = 0;
struct reg_window *old_stack, *new_stack;
unsigned long stack_offset;
mmu_task_cacheflush(current);
p->tss.context = -1;
if(last_task_used_math == current) {
put_psr(get_psr() | PSR_EF);
fpsave(&p->tss.float_regs[0], &p->tss.fsr,
&p->tss.fpqueue[0], &p->tss.fpqdepth);
}
/* Calculate offset to stack_frame & pt_regs */
stack_offset = (PAGE_SIZE - TRACEREG_SZ);
stack_offset = ((PAGE_SIZE*2) - TRACEREG_SZ);
if(regs->psr & PSR_PS)
stack_offset -= REGWIN_SZ;
childregs = ((struct pt_regs *) (p->kernel_stack_page + stack_offset));
*childregs = *regs;
new_stack = (((struct sparc_stackf *) childregs) - 1);
old_stack = (((struct sparc_stackf *) regs) - 1);
new_stack = (((struct reg_window *) childregs) - 1);
old_stack = (((struct reg_window *) regs) - 1);
*new_stack = *old_stack;
p->tss.ksp = (unsigned long) new_stack;
p->tss.ksp = p->saved_kernel_stack = (unsigned long) new_stack;
p->tss.kpc = (((unsigned long) ret_sys_call) - 0x8);
p->tss.kpsr = current->tss.fork_kpsr;
p->tss.kwim = current->tss.fork_kwim;
p->tss.kregs = childregs;
childregs->u_regs[UREG_FP] = sp;
/* As a special case, if this is a kernel fork we need
* to give the child a new fresh stack for when it returns
* from the syscall. (ie. the "user" stack) This happens
* only once and we count on the page acquisition happening
* successfully.
*/
if(regs->psr & PSR_PS) {
unsigned long n_stack = get_free_page(GFP_KERNEL);
childregs->u_regs[UREG_FP] = (n_stack | (sp & 0xfff));
memcpy((char *)n_stack,(char *)(sp & PAGE_MASK),PAGE_SIZE);
kthread_usp = n_stack;
}
stack_offset += TRACEREG_SZ;
childregs->u_regs[UREG_FP] = p->kernel_stack_page + stack_offset;
p->tss.flags |= SPARC_FLAG_KTHREAD;
} else
p->tss.flags &= ~SPARC_FLAG_KTHREAD;
/* Set the return value for the child. */
childregs->u_regs[UREG_I0] = current->pid;
......@@ -168,8 +195,6 @@ void copy_thread(int nr, unsigned long clone_flags, unsigned long sp,
/* Set the return value for the parent. */
regs->u_regs[UREG_I1] = 0;
mmu_fork_hook(p, kthread_usp);
}
/*
......@@ -177,6 +202,31 @@ void copy_thread(int nr, unsigned long clone_flags, unsigned long sp,
*/
void dump_thread(struct pt_regs * regs, struct user * dump)
{
unsigned long first_stack_page;
dump->magic = SUNOS_CORE_MAGIC;
dump->len = sizeof(struct user);
dump->regs.psr = regs->psr;
dump->regs.pc = regs->pc;
dump->regs.npc = regs->npc;
dump->regs.y = regs->y;
/* fuck me plenty */
memcpy(&dump->regs.regs[0], &regs->u_regs[1], (sizeof(unsigned long) * 15));
dump->uexec = current->tss.core_exec;
dump->u_tsize = (((unsigned long) current->mm->end_code) -
((unsigned long) current->mm->start_code)) & ~(PAGE_SIZE - 1);
dump->u_dsize = ((unsigned long) (current->mm->brk + (PAGE_SIZE-1)));
dump->u_dsize -= dump->u_tsize;
dump->u_dsize &= ~(PAGE_SIZE - 1);
first_stack_page = (regs->u_regs[UREG_FP] & ~(PAGE_SIZE - 1));
dump->u_ssize = (TASK_SIZE - first_stack_page) & ~(PAGE_SIZE - 1);
memcpy(&dump->fpu.fpstatus.fregs.regs[0], &current->tss.float_regs[0], (sizeof(unsigned long) * 32));
dump->fpu.fpstatus.fsr = current->tss.fsr;
dump->fpu.fpstatus.flags = dump->fpu.fpstatus.extra = 0;
dump->fpu.fpstatus.fpq_count = current->tss.fpqdepth;
memcpy(&dump->fpu.fpstatus.fpq[0], &current->tss.fpqueue[0],
((sizeof(unsigned long) * 2) * 16));
dump->sigcode = current->tss.sig_desc;
}
/*
......@@ -198,7 +248,6 @@ asmlinkage int sparc_execve(struct pt_regs *regs)
char *filename;
flush_user_windows();
mmu_task_cacheflush(current);
error = getname((char *) regs->u_regs[UREG_I0], &filename);
if(error)
return error;
......@@ -207,27 +256,3 @@ asmlinkage int sparc_execve(struct pt_regs *regs)
putname(filename);
return error;
}
void start_thread(struct pt_regs * regs, unsigned long pc, unsigned long sp)
{
unsigned long saved_psr = (regs->psr & (PSR_CWP)) | PSR_S;
memset(regs, 0, sizeof(struct pt_regs));
regs->pc = ((pc & (~3)) - 4); /* whee borken a.out header fields... */
regs->npc = regs->pc + 4;
regs->psr = saved_psr;
regs->u_regs[UREG_G1] = sp; /* Base of arg/env stack area */
/* XXX More mysterious netbsd garbage... XXX */
regs->u_regs[UREG_G2] = regs->u_regs[UREG_G7] = regs->npc;
/* Allocate one reg window because the first jump into
* user mode will restore one register window by definition
* of the 'rett' instruction. Also, SunOS crt.o code
* depends upon the arg/envp area being _exactly_ one
* register window above %sp when the process begins
* execution.
*/
sp -= REGWIN_SZ;
regs->u_regs[UREG_FP] = sp;
}
/* $Id: rtrap.S,v 1.11 1995/11/25 00:58:19 davem Exp $
/* $Id: rtrap.S,v 1.21 1996/02/20 07:45:11 davem Exp $
* rtrap.S: Return from Sparc trap low-level code.
*
* Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
......@@ -45,16 +45,15 @@ rtrap_7win_patch5: and %g1, 0x7f, %g1
.globl ret_trap_entry, rtrap_patch1, rtrap_patch2
.globl rtrap_patch3, rtrap_patch4, rtrap_patch5
ret_trap_entry:
ld [%sp + STACKFRAME_SZ + PT_PSR], %t_psr
ld [%sp + REGWIN_SZ + PT_PSR], %t_psr
andcc %t_psr, PSR_PS, %g0
bne ret_trap_kernel
nop
sethi %hi(C_LABEL(need_resched)), %twin_tmp1
ld [%twin_tmp1 + %lo(C_LABEL(need_resched))], %twin_tmp2
LOAD_CURRENT(twin_tmp1)
cmp %twin_tmp2, 0x0
cmp %twin_tmp2, 0
be signal_p
nop
......@@ -70,41 +69,51 @@ ret_trap_entry:
signal_p:
/* No signals for swapper. */
sethi %hi(C_LABEL(init_task)), %twin_tmp3
or %twin_tmp3, %lo(C_LABEL(init_task)), %twin_tmp3
LOAD_CURRENT(twin_tmp1, twin_tmp3)
set C_LABEL(init_task), %twin_tmp3
cmp %twin_tmp3, %twin_tmp1
be ret_trap_continue
nop
ld [%twin_tmp1 + TASK_SIGNAL], %twin_tmp2
ld [%twin_tmp1 + TASK_BLOCKED], %twin_tmp3
andncc %twin_tmp2, %twin_tmp3, %twin_tmp2
ld [%twin_tmp1 + TASK_BLOCKED], %o0
andncc %twin_tmp2, %o0, %g0
be ret_trap_continue
nop
mov %twin_tmp2, %o0 ! oldmask
add %sp, STACKFRAME_SZ, %o1 ! pt_regs ptr
call C_LABEL(do_signal)
nop
add %sp, REGWIN_SZ, %o1 ! pt_regs ptr
/* Fall through... */
ret_trap_continue:
ld [%sp + REGWIN_SZ + PT_PSR], %t_psr
wr %t_psr, 0x0, %psr
WRITE_PAUSE
LOAD_CURRENT(twin_tmp2)
/* If not current fpu proc, disable fp-ops */
LOAD_CURRENT(twin_tmp2, twin_tmp1)
set C_LABEL(last_task_used_math), %twin_tmp1
ld [%twin_tmp1], %twin_tmp1
cmp %twin_tmp2, %twin_tmp1
be 1f
nop
set PSR_EF, %twin_tmp1
andn %t_psr, %twin_tmp1, %t_psr
st %t_psr, [%sp + REGWIN_SZ + PT_PSR]
1:
ld [%twin_tmp2 + THREAD_W_SAVED], %twin_tmp1
orcc %g0, %twin_tmp1, %g0
be ret_trap_nobufwins
nop
wr %t_psr, 0x0, %psr
wr %t_psr, PSR_ET, %psr
WRITE_PAUSE
mov 1, %o1
call C_LABEL(do_sparc_winfault)
add %sp, STACKFRAME_SZ, %o0
call C_LABEL(try_to_clear_window_buffer)
add %sp, REGWIN_SZ, %o0
b ret_trap_entry
nop
......@@ -126,6 +135,7 @@ ret_trap_nobufwins:
/* Calculate new %wim, we have to pull a register
* window from the users stack.
*/
ret_trap_pull_one_window:
rd %wim, %t_wim
sll %t_wim, 0x1, %twin_tmp1
rtrap_patch1: srl %t_wim, 0x7, %twin_tmp2
......@@ -159,23 +169,36 @@ ret_trap_userwins_ok:
jmp %t_pc
rett %t_npc
/* HyperSparc special nop patching, if we are on a hypersparc
* we nop the top two instructions and the first nop coming
* up to be:
* rd %iccr, %g0 <-- flush on-chip instruction cache
* jmp %t_pc
* rett %t_npc
*/
nop
nop
ret_trap_unaligned_pc:
add %sp, STACKFRAME_SZ, %o0
ld [%sp + STACKFRAME_SZ + PT_PC], %o1
ld [%sp + STACKFRAME_SZ + PT_NPC], %o2
ld [%sp + STACKFRAME_SZ + PT_PSR], %o3
add %sp, REGWIN_SZ, %o0
ld [%sp + REGWIN_SZ + PT_PC], %o1
ld [%sp + REGWIN_SZ + PT_NPC], %o2
ld [%sp + REGWIN_SZ + PT_PSR], %o3
wr %t_wim, 0x0, %wim ! or else...
WRITE_PAUSE
wr %t_psr, 0x0, %psr
wr %t_psr, PSR_ET, %psr
WRITE_PAUSE
call C_LABEL(do_memaccess_unaligned)
nop
b ret_trap_entry
b ret_trap_entry ! maybe signal posted
nop
ret_trap_kernel:
ld [%sp + REGWIN_SZ + PT_PSR], %t_psr
wr %t_psr, 0x0, %psr
WRITE_PAUSE
......@@ -218,15 +241,12 @@ ret_trap_user_stack_is_bolixed:
wr %t_wim, 0x0, %wim
WRITE_PAUSE
wr %t_psr, 0x0, %psr
wr %t_psr, PSR_ET, %psr
WRITE_PAUSE
mov 0, %o1
call C_LABEL(do_sparc_winfault)
add %sp, STACKFRAME_SZ, %o0
call C_LABEL(window_ret_fault)
add %sp, REGWIN_SZ, %o0
/* Try it all again. */
b ret_trap_entry
nop
......@@ -297,7 +317,7 @@ sun4c_rett_onepage:
b ret_trap_userwins_ok
nop
.globl C_LABEL(sun4c_rett_stackchk)
.globl C_LABEL(srmmu_rett_stackchk)
C_LABEL(srmmu_rett_stackchk):
bne ret_trap_user_stack_is_bolixed
sethi %hi(KERNBASE), %g1
......
/* sclow.S: Low level special syscall handling.
* Basically these are cases where we can completly
* handle the system call without saving any state
* because we know that the process will not sleep.
*
* Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
*/
#include <asm/cprefix.h>
#include <asm/ptrace.h>
#include <asm/errno.h>
#include <asm/winmacro.h>
#include <asm/psr.h>
#define CC_AND_RETT \
set PSR_C, %l4; \
andn %l0, %l4, %l4; \
wr %l4, 0x0, %psr; \
nop; nop; nop; \
jmp %l2; \
rett %l2 + 4;
#define SC_AND_RETT \
set PSR_C, %l4; \
or %l0, %l4, %l4; \
wr %l4, 0x0, %psr; \
nop; nop; nop; \
jmp %l2; \
rett %l2 + 4;
#define LABEL(func) CONCAT(func, _low)
.globl LABEL(sunosnop)
LABEL(sunosnop):
CC_AND_RETT
.globl LABEL(sunosgetpid)
LABEL(sunosgetpid):
LOAD_CURRENT(l4, l5)
ld [%l4 + 108], %i0
ld [%l4 + 256], %l5
ld [%l5 + 108], %i1
CC_AND_RETT
.globl LABEL(sunosgetuid)
LABEL(sunosgetuid):
LOAD_CURRENT(l4, l5)
lduh [%l4 + 280], %i0
lduh [%l4 + 282], %i1
CC_AND_RETT
.globl LABEL(sunosgetgid)
LABEL(sunosgetgid):
LOAD_CURRENT(l4, l5)
lduh [%l4 + 288], %i0
lduh [%l4 + 290], %i1
CC_AND_RETT
.globl LABEL(sunosmctl)
LABEL(sunosmctl):
mov 0, %i0
CC_AND_RETT
.globl LABEL(sunosgdtsize)
LABEL(sunosgdtsize):
mov 256, %i0
CC_AND_RETT
.globl LABEL(sunossblock)
LABEL(sunossblock):
LOAD_CURRENT(l4, l5)
set -65793, %l5
and %i0, %l5, %l5
ld [%l4 + TASK_BLOCKED], %i0
or %i0, %l5, %l5
st %l5, [%l4 + TASK_BLOCKED]
CC_AND_RETT
.globl LABEL(sunossmask)
LABEL(sunossmask):
LOAD_CURRENT(l4, l5)
set -65793, %l5
and %i0, %l5, %l5
ld [%l4 + TASK_BLOCKED], %i0
st %l5, [%l4 + TASK_BLOCKED]
CC_AND_RETT
.globl LABEL(getpagesize)
LABEL(getpagesize):
set 4096, %i0
CC_AND_RETT
.globl LABEL(umask)
LABEL(umask):
LOAD_CURRENT(l4, l5)
ld [%l4 + 1560], %l5
and %i0, 511, %l4
lduh [%l5 + 4], %i0
sth %l4, [%l5 + 4]
CC_AND_RETT
.globl LABEL(write)
LABEL(write):
cmp %i0, 255 /* fd >= NR_OPEN */
bgu,a write_error_return
mov EBADF, %i0
LOAD_CURRENT(l4, l5)
ld [%l4 + 1564], %l5
sll %i0, 2, %l6
add %l5, %l6, %l5
ld [%l5 + 36], %l6
cmp %l6, 0 /* !(file=current->files->fd[fd]) */
be,a write_error_return
mov EBADF, %i0
ld [%l6 + 36], %l5
cmp %l5, 0 /* !(inode=file->f_inode) */
be,a write_error_return
mov EBADF, %i0
lduh [%l6], %l5 /* !(file->f_mode & 2) */
andcc %l5, 2, %g0
be,a write_error_return
mov EBADF, %i0
ld [%l6 + 40], %l5
cmp %l5, 0 /* !file->f_op */
be,a write_error_return
mov EINVAL, %i0
ld [%l5 + 8], %l5 /* !file->f_op->write */
cmp %l5, 0
be,a write_error_return
mov EINVAL, %i0
cmp %i2, 0 /* count == 0 */
bne 1f
nop
mov 0, %i0
CC_AND_RETT
1:
/* See if we can do the optimization... */
ld [%l6 + 36], %l5
lduh [%l5 + 16], %l5
srl %l5, 8, %l6
cmp %l6, 1 /* MEM_MAJOR */
bne,a write_is_too_hard
sethi %hi(C_LABEL(quick_sys_write)), %l7
and %l5, 0xff, %l5
cmp %l5, 3 /* NULL_MINOR */
bne,a write_is_too_hard
sethi %hi(C_LABEL(quick_sys_write)), %l7
/* We only optimize for the /dev/null case currently,
* however to stay POSIX4 compliant we must check the
* validity of the passed buffer. Blowlaris2.x does not
* do this and is therefore not POSIX4 compliant!
* If you are going to optimize for benchmarks, fine,
* but to break behavior of a system call in the process
* is complete brain damage...
*/
/* XXX write verify_area thingy for full POSIX conformance! XXX */
mov %i2, %i0
CC_AND_RETT
write_is_too_hard:
b syscall_is_too_hard
or %l7, %lo(C_LABEL(quick_sys_write)), %l7
write_error_return:
SC_AND_RETT
/* XXX sys_nice() XXX */
/* XXX sys_setpriority() XXX */
/* XXX sys_getpriority() XXX */
/* XXX sys_setregid() XXX */
/* XXX sys_setgid() XXX */
/* XXX sys_setreuid() XXX */
/* XXX sys_setuid() XXX */
/* XXX sys_setfsuid() XXX */
/* XXX sys_setfsgid() XXX */
/* XXX sys_setpgid() XXX */
/* XXX sys_getpgid() XXX */
/* XXX sys_setsid() XXX */
/* XXX sys_getsid() XXX */
/* $Id: setup.c,v 1.41 1995/11/25 00:58:21 davem Exp $
/* $Id: setup.c,v 1.54 1996/02/25 06:49:18 davem Exp $
* linux/arch/sparc/kernel/setup.c
*
* Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
......@@ -16,6 +16,11 @@
#include <linux/user.h>
#include <linux/a.out.h>
#include <linux/tty.h>
#include <linux/delay.h>
#include <linux/config.h>
#include <linux/fs.h>
#include <linux/kdev_t.h>
#include <linux/major.h>
#include <asm/segment.h>
#include <asm/system.h>
......@@ -28,6 +33,7 @@
#include <asm/traps.h>
#include <asm/vaddrs.h>
#include <asm/kdebug.h>
#include <asm/mbus.h>
struct screen_info screen_info = {
0, 0, /* orig-x, orig-y */
......@@ -42,6 +48,7 @@ struct screen_info screen_info = {
};
char wp_works_ok = 0;
unsigned int phys_bytes_of_ram, end_of_phys_memory;
unsigned long bios32_init(unsigned long memory_start, unsigned long memory_end)
{
......@@ -55,6 +62,9 @@ unsigned long bios32_init(unsigned long memory_start, unsigned long memory_end)
*/
extern unsigned long trapbase;
extern void breakpoint(void);
extern void console_restore_palette(void);
asmlinkage void sys_sync(void); /* it's really int */
/* Pretty sick eh? */
void prom_sync_me(void)
......@@ -68,8 +78,14 @@ void prom_sync_me(void)
"nop\n\t"
"nop\n\t" : : "r" (&trapbase));
console_restore_palette ();
prom_printf("PROM SYNC COMMAND...\n");
show_free_areas();
if(current != task[0]) {
sti();
sys_sync();
cli();
}
prom_printf("Returning to prom\n");
__asm__ __volatile__("wr %0, 0x0, %%tbr\n\t"
......@@ -145,23 +161,30 @@ boot_flags_init(char *commands)
extern void load_mmu(void);
extern int prom_probe_memory(void);
extern void probe_vac(void);
extern void sun4c_probe_vac(void);
extern void get_idprom(void);
extern unsigned int end_of_phys_memory;
extern char cputypval;
extern unsigned long start, end, bootup_stack, bootup_kstack;
extern unsigned long start, end;
extern void panic_setup(char *, int *);
char sparc_command_line[256]; /* Should be enough */
char saved_command_line[256];
enum sparc_cpu sparc_cpu_model;
struct tt_entry *sparc_ttable;
static struct pt_regs fake_swapper_regs = { 0, 0, 0, 0, { 0, } };
void setup_arch(char **cmdline_p,
unsigned long * memory_start_p, unsigned long * memory_end_p)
{
int total, i;
int total, i, panic_stuff[2];
/* Always reboot on panic, but give 5 seconds to hit L1-A
* and look at debugging info if desired.
*/
panic_stuff[0] = 1;
panic_stuff[1] = 5;
panic_setup(0, panic_stuff);
sparc_ttable = (struct tt_entry *) &start;
......@@ -181,7 +204,7 @@ void setup_arch(char **cmdline_p,
{
case sun4c:
printk("SUN4C\n");
probe_vac();
sun4c_probe_vac();
break;
case sun4m:
printk("SUN4M\n");
......@@ -215,8 +238,10 @@ void setup_arch(char **cmdline_p,
load_mmu();
total = prom_probe_memory();
*memory_start_p = (((unsigned long) &end));
printk("Physical Memory: %d bytes (in hex %08lx)\n", (int) total,
#if 0
prom_printf("Physical Memory: %d bytes (in hex %08lx)\n", (int) total,
(unsigned long) total);
#endif
for(i=0; sp_banks[i].num_bytes != 0; i++) {
#if 0
......@@ -229,10 +254,15 @@ void setup_arch(char **cmdline_p,
prom_setsync(prom_sync_me);
*memory_end_p = (end_of_phys_memory + PAGE_OFFSET);
if(*memory_end_p > IOBASE_VADDR)
*memory_end_p = IOBASE_VADDR;
/* Due to stack alignment restrictions and assumptions... */
init_task.mm->mmap->vm_page_prot = PAGE_SHARED;
*memory_end_p = (end_of_phys_memory + PAGE_OFFSET);
init_task.mm->mmap->vm_start = KERNBASE;
init_task.mm->mmap->vm_end = *memory_end_p;
init_task.tss.kregs = &fake_swapper_regs;
{
extern int serial_console; /* in console.c, of course */
......@@ -250,6 +280,15 @@ void setup_arch(char **cmdline_p,
prom_halt();
}
}
#if 1
/* XXX ROOT_DEV hack for kgdb - davem XXX */
#if 1
ROOT_DEV = MKDEV(UNNAMED_MAJOR, 255); /* NFS */
#else
ROOT_DEV = 0x801; /* SCSI DISK */
#endif
#endif
}
asmlinkage int sys_ioperm(unsigned long from, unsigned long num, int on)
......@@ -257,12 +296,35 @@ asmlinkage int sys_ioperm(unsigned long from, unsigned long num, int on)
return -EIO;
}
/*
* BUFFER is PAGE_SIZE bytes long.
*
* XXX Need to do better than this! XXX
*/
/* BUFFER is PAGE_SIZE bytes long. */
extern char *sparc_cpu_type[];
extern char *sparc_fpu_type[];
int get_cpuinfo(char *buffer)
{
return sprintf(buffer, "Sparc RISC\n");
int cpuid=get_cpuid();
return sprintf(buffer, "cpu\t\t: %s\n"
"fpu\t\t: %s\n"
"promlib\t\t: Version %d Revision %d\n"
"wp\t\t: %s\n"
"type\t\t: %s\n"
"Elf Support\t: %s\n" /* I can't remember when I do --ralp */
"BogoMips\t: %lu.%02lu\n"
"%s",
sparc_cpu_type[cpuid],
sparc_fpu_type[cpuid],
romvec->pv_romvers, prom_rev,
wp_works_ok ? "yes" : "no",
&cputypval,
#if CONFIG_BINFMT_ELF
"yes",
#else
"no",
#endif
loops_per_sec/500000, (loops_per_sec/5000) % 100,
mmu_info()
);
}
This diff is collapsed.
/* smp.c: Sparc SMP support.
*
* Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
*/
#include <linux/kernel.h>
#include <linux/smp.h>
int smp_num_cpus;
int smp_threads_ready;
volatile unsigned long smp_msg_data;
volatile int smp_src_cpu;
volatile int smp_msg_id;
static volatile int smp_commenced = 0;
/* The only guarenteed locking primitive available on all Sparc
* processors is 'ldstub [%addr_reg + imm], %dest_reg' which atomicly
* places the current byte at the effective address into dest_reg and
* places 0xff there afterwards. Pretty lame locking primitive
* compared to the Alpha and the intel no? Most Sparcs have 'swap'
* instruction which is muct better...
*/
klock_t kernel_lock;
void smp_commence(void)
{
/*
* Lets the callin's below out of their loop.
*/
smp_commenced = 1;
}
void smp_callin(void)
{
int cpuid = smp_get_processor_id();
/* XXX Clear the software interrupts _HERE_. */
sti();
calibrate_delay();
smp_store_cpu_info(cpuid);
set_bit(cpuid, (unsigned long *)&cpu_callin_map[0]);
local_invalidate_all();
while(!smp_commenced);
if(cpu_number_map[cpuid] == -1)
while(1);
local_invalidate_all();
}
void smp_boot_cpus(void)
{
}
void smp_message_pass(int target, int msg, unsigned long data, int wait)
{
struct sparc_ipimsg *msg = (struct sparc_ipimsg *) data;
unsigned long target_map;
int p = smp_processor_id();
static volatile int message_cpu = NO_PROC_ID;
if(!smp_activated || !smp_commenced)
return;
if(msg == MSG_RESCHEDULE) {
if(smp_cpu_in_msg[p])
return;
}
if(message_cpu != NO_PROC_ID && msg != MSG_STOP_CPU) {
panic("CPU #%d: Message pass %d but pass in progress by %d of %d\n",
smp_processor_id(),msg,message_cpu, smp_msg_id);
}
message_cpu = smp_processor_id();
smp_cpu_in_msg[p]++;
if(msg != MSG_RESCHEDULE) {
smp_src_cpu = p;
smp_msg_id = msg;
smp_msg_data = data;
}
if(target == MSG_ALL_BUT_SELF) {
target_map = cpu_present_map;
cpu_callin_map[0] = (1<<smp_src_cpu);
} else if(target == MSG_ALL) {
target_map = cpu_present_map;
cpu_callin_map[0] = 0;
} else {
target_map = (1<<target);
cpu_callin_map[0] = 0;
}
/* XXX Send lvl15 soft interrupt to cpus here XXX */
switch(wait) {
case 1:
while(cpu_callin_map[0] != target_map);
break;
case 2:
while(smp_invalidate_needed);
break;
}
smp_cpu_in_msg[p]--;
message_cpu = NO_PROC_ID;
}
inline void smp_invalidate(int type, unsigned long a, unsigned long b, unsigned long c)
{
unsigned long flags;
smp_invalidate_needed = cpu_present_map & ~(1<<smp_processor_id());
save_flags(flags); cli();
smp_message_pass(MSG_ALL_BUT_SELF, MSG_INVALIDATE_TLB, 0L, 2);
local_invalidate();
restore_flags(flags);
}
void smp_invalidate_all(void)
{
smp_invalidate(0, 0, 0, 0);
}
void smp_invalidate_mm(struct mm_struct *mm)
{
smp_invalidate(1, (unsigned long) mm, 0, 0);
}
void smp_invalidate_range(struct mm_struct *mm, unsigned long start, unsigned long end)
{
smp_invalidate(2, (unsigned long) mm, start, end);
}
void smp_invalidate_page(struct vm_area_struct *vmap, unsigned long page)
{
smp_invalidate(3, (unsigned long)vmap->vm_mm, page, 0);
}
void smp_reschedule_irq(int cpl, struct pt_regs *regs)
{
if(smp_processor_id() != active_kernel_processor)
panic("SMP Reschedule on CPU #%d, but #%d is active.\n",
smp_processor_id(), active_kernel_processor);
if(user_mode(regs)) {
current->utime++;
if (current->pid) {
if (current->priority < 15)
kstat.cpu_nice++;
else
kstat.cpu_user++;
}
/* Update ITIMER_VIRT for current task if not in a system call */
if (current->it_virt_value && !(--current->it_virt_value)) {
current->it_virt_value = current->it_virt_incr;
send_sig(SIGVTALRM,current,1);
}
} else {
current->stime++;
if(current->pid)
kstat.cpu_system++;
#ifdef CONFIG_PROFILE
if (prof_buffer && current->pid) {
extern int _stext;
unsigned long eip = regs->eip - (unsigned long) &_stext;
eip >>= CONFIG_PROFILE_SHIFT;
if (eip < prof_len)
prof_buffer[eip]++;
}
#endif
}
/*
* check the cpu time limit on the process.
*/
if ((current->rlim[RLIMIT_CPU].rlim_max != RLIM_INFINITY) &&
(((current->stime + current->utime) / HZ) >= current->rlim[RLIMIT_CPU].rlim_max))
send_sig(SIGKILL, current, 1);
if ((current->rlim[RLIMIT_CPU].rlim_cur != RLIM_INFINITY) &&
(((current->stime + current->utime) % HZ) == 0)) {
unsigned long psecs = (current->stime + current->utime) / HZ;
/* send when equal */
if (psecs == current->rlim[RLIMIT_CPU].rlim_cur)
send_sig(SIGXCPU, current, 1);
/* and every five seconds thereafter. */
else if ((psecs > current->rlim[RLIMIT_CPU].rlim_cur) &&
((psecs - current->rlim[RLIMIT_CPU].rlim_cur) % 5) == 0)
send_sig(SIGXCPU, current, 1);
}
/* Update ITIMER_PROF for the current task */
if (current->it_prof_value && !(--current->it_prof_value)) {
current->it_prof_value = current->it_prof_incr;
send_sig(SIGPROF,current,1);
}
if(0 > --current->counter || current->pid == 0) {
current->counter = 0;
need_resched = 1;
}
}
void smp_message_irq(int cpl, struct pt_regs *regs)
{
int i=smp_processor_id();
/* static int n=0;
if(n++<NR_CPUS)
printk("IPI %d->%d(%d,%ld)\n",smp_src_cpu,i,smp_msg_id,smp_msg_data);*/
switch(smp_msg_id)
{
case 0: /* IRQ 13 testing - boring */
return;
/*
* A TLB flush is needed.
*/
case MSG_INVALIDATE_TLB:
if(clear_bit(i,(unsigned long *)&smp_invalidate_needed))
local_invalidate();
set_bit(i, (unsigned long *)&cpu_callin_map[0]);
cpu_callin_map[0]|=1<<smp_processor_id();
break;
/*
* Halt other CPU's for a panic or reboot
*/
case MSG_STOP_CPU:
while(1)
{
if(cpu_data[smp_processor_id()].hlt_works_ok)
__asm__("hlt");
}
default:
printk("CPU #%d sent invalid cross CPU message to CPU #%d: %X(%lX).\n",
smp_src_cpu,smp_processor_id(),smp_msg_id,smp_msg_data);
break;
}
/*
* Clear the IPI, so we can receive future IPI's
*/
apic_read(APIC_SPIV); /* Dummy read */
apic_write(APIC_EOI, 0); /* Docs say use 0 for future compatibility */
}
/* $Id: sparc-stub.c,v 1.7 1995/11/25 00:58:26 davem Exp $
/* $Id: sparc-stub.c,v 1.10 1996/02/15 09:12:09 davem Exp $
* sparc-stub.c: KGDB support for the Linux kernel.
*
* Modifications to run under Linux
......@@ -636,7 +636,6 @@ handle_exception (unsigned long *registers)
* breakpoint, and the icache probably has no way of knowing that a data ref to
* some location may have changed something that is in the instruction cache.
*/
/* Only instruction cache flushing on the sun4c/sun4
* for now. We assume control flow during the kgdb
* transaction has not left the context in which it
......
/* $Id: sunos_asm.S,v 1.8 1995/11/25 00:58:29 davem Exp $
/* $Id: sunos_asm.S,v 1.10 1995/12/26 04:09:33 davem Exp $
* sunos_asm.S: SunOS system calls which must have a low-level
* entry point to operate correctly.
*
......@@ -12,79 +12,69 @@
#include <asm/cprefix.h>
#include <asm/ptrace.h>
/* Note that for dual value returning system calls we
* need to store the second one ourselves in the pt_regs
* trap-frame. linux_sparc_syscall does %o0 for us
* however.
*/
.text
.align 4
/* SunOS getpid() returns pid in %o0 and ppid in %o1 */
.globl C_LABEL(sunos_getpid)
C_LABEL(sunos_getpid):
save %sp, -STACKFRAME_SZ, %sp
call C_LABEL(sys_getpid)
nop
nop
mov %o0, %i0
st %o0, [%sp + REGWIN_SZ + PT_I0]
call C_LABEL(sys_getppid)
nop
nop
st %o0, [%fp + STACKFRAME_SZ + PT_I1]
st %o0, [%sp + REGWIN_SZ + PT_I1]
ret
restore
b C_LABEL(ret_sys_call)
nop
/* SunOS getuid() returns uid in %o0 and euid in %o1 */
.globl C_LABEL(sunos_getuid)
C_LABEL(sunos_getuid):
save %sp, -STACKFRAME_SZ, %sp
call C_LABEL(sys_getuid)
nop
nop
mov %o0, %i0
st %o0, [%sp + REGWIN_SZ + PT_I0]
call C_LABEL(sys_geteuid)
nop
nop
st %o0, [%fp + STACKFRAME_SZ + PT_I1]
st %o0, [%sp + REGWIN_SZ + PT_I1]
ret
restore
b C_LABEL(ret_sys_call)
nop
/* SunOS getgid() returns gid in %o0 and egid in %o1 */
.globl C_LABEL(sunos_getgid)
C_LABEL(sunos_getgid):
save %sp, -STACKFRAME_SZ, %sp
call C_LABEL(sys_getgid)
nop
nop
mov %o0, %i0
st %o0, [%sp + REGWIN_SZ + PT_I0]
call C_LABEL(sys_getegid)
nop
nop
st %o0, [%fp + STACKFRAME_SZ + PT_I1]
st %o0, [%sp + REGWIN_SZ + PT_I1]
ret
restore
b C_LABEL(ret_sys_call)
nop
/* SunOS's execv() call only specifies the argv argument, the
* environment settings are the same as the calling processes.
*/
.globl C_LABEL(sunos_execv)
C_LABEL(sunos_execv):
save %sp, -STACKFRAME_SZ, %sp
st %g0, [%sp + REGWIN_SZ + PT_I2]
st %g0, [%fp + STACKFRAME_SZ + PT_I2]
call C_LABEL(sparc_execve)
add %fp, STACKFRAME_SZ, %o0
add %sp, REGWIN_SZ, %o0
st %o0, [%fp + STACKFRAME_SZ + PT_I1]
st %o0, [%sp + REGWIN_SZ + PT_I0]
ret
restore
b C_LABEL(ret_sys_call)
nop
/* $Id: sunos_ioctl.c,v 1.8 1995/11/26 04:07:39 davem Exp $
/* $Id: sunos_ioctl.c,v 1.17 1996/02/10 04:29:20 davem Exp $
* sunos_ioctl.c: The Linux Operating system: SunOS ioctl compatibility.
*
* Copyright (C) 1995 Miguel de Icaza (miguel@nuclecu.unam.mx)
......@@ -17,16 +17,45 @@
#include <linux/if.h>
#include <linux/if_arp.h>
#include <linux/fs.h>
#include <linux/mm.h>
#include <asm/kbio.h>
#if 0
extern char sunkbd_type;
extern char sunkbd_layout;
#endif
extern asmlinkage int sys_ioctl(unsigned int, unsigned int, unsigned long);
extern asmlinkage int sys_setsid(void);
asmlinkage int sunos_ioctl (int fd, unsigned long cmd, unsigned long arg)
{
struct file *filp;
int foo;
if (fd >= NR_OPEN || !(filp = current->files->fd [fd]))
return -EBADF;
/* First handle an easy compat. case for tty ldisc. */
if(cmd == TIOCSETD) {
int *p, ntty = N_TTY, old_fs;
p = (int *) arg;
foo = verify_area(VERIFY_WRITE, p, sizeof(int));
if(foo) return foo;
if(*p == 2) {
old_fs = get_fs();
set_fs(KERNEL_DS);
foo = sys_ioctl(fd, cmd, (int) &ntty);
set_fs(old_fs);
return (foo == -EINVAL ? -EOPNOTSUPP : foo);
}
}
/* Binary compatability is good American knowhow fuckin' up. */
if(cmd == TIOCNOTTY)
return sys_setsid();
/* SunOS networking ioctls. */
switch (cmd) {
case _IOW('r', 10, struct rtentry):
......@@ -49,7 +78,7 @@ asmlinkage int sunos_ioctl (int fd, unsigned long cmd, unsigned long arg)
return sys_ioctl(fd, SIOCSIFMEM, arg);
case _IORW('i', 19, struct ifreq):
return sys_ioctl(fd, SIOCGIFMEM, arg);
case _IORW('i', 20, struct ifreq):
case _IORW('i', 20, struct ifconf):
return sys_ioctl(fd, SIOCGIFCONF, arg);
case _IOW('i', 21, struct ifreq): /* SIOCSIFMTU */
return sys_ioctl(fd, SIOCSIFMTU, arg);
......@@ -83,7 +112,7 @@ asmlinkage int sunos_ioctl (int fd, unsigned long cmd, unsigned long arg)
case _IOW('i', 46, struct ifreq): /* SIOCSSDSTATS */
case _IOW('i', 47, struct ifreq): /* SIOCSSESTATS */
case _IOW('i', 48, struct ifreq): /* SIOCSPROMISC */
return -EINVAL;
return -EOPNOTSUPP;
case _IOW('i', 49, struct ifreq):
return sys_ioctl(fd, SIOCADDMULTI, arg);
......@@ -91,6 +120,7 @@ asmlinkage int sunos_ioctl (int fd, unsigned long cmd, unsigned long arg)
return sys_ioctl(fd, SIOCDELMULTI, arg);
/* FDDI interface ioctls, unsupported. */
case _IOW('i', 51, struct ifreq): /* SIOCFDRESET */
case _IOW('i', 52, struct ifreq): /* SIOCFDSLEEP */
case _IOW('i', 53, struct ifreq): /* SIOCSTRTFMWAR */
......@@ -100,10 +130,27 @@ asmlinkage int sunos_ioctl (int fd, unsigned long cmd, unsigned long arg)
case _IOW('i', 57, struct ifreq): /* SIOCFDEXUSER */
case _IOW('i', 58, struct ifreq): /* SIOCFDGNETMAP */
case _IOW('i', 59, struct ifreq): /* SIOCFDGIOCTL */
return -EINVAL;
printk("FDDI ioctl, returning EOPNOTSUPP\n");
return -EOPNOTSUPP;
case _IOW('t', 125, int):
/* More stupid tty sunos ioctls, just
* say it worked.
*/
return 0;
/* Non posix grp */
case _IOR('t', 119, int):
return -EIO;
}
#if 0
if (cmd & 0xff00 == ('k' << 8)){
printk ("[[KBIO: %8.8x\n", (unsigned int) cmd);
}
#endif
return sys_ioctl (fd, cmd, arg);
foo = sys_ioctl(fd, cmd, arg);
/* so stupid... */
return (foo == -EINVAL ? -EOPNOTSUPP : foo);
}
/* $Id: switch.S,v 1.9 1995/11/25 00:58:32 davem Exp $
/* $Id: switch.S,v 1.14 1995/12/29 21:47:22 davem Exp $
* switch.S: Sparc task switch code.
*
* Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
......@@ -13,8 +13,6 @@
#include <asm/winmacro.h>
#define sw_ntask g1
#define sw_sp g2
#define sw_pc g3
#define sw_psr g4
#define sw_wim g5
#define sw_tmp g6
......@@ -26,7 +24,7 @@
* First successful task switch 05/13/95 21:52:37
*/
.align 4
.globl C_LABEL(sparc_switch_to), C_LABEL(mmu_switch_lowlevel)
.globl C_LABEL(sparc_switch_to)
C_LABEL(sparc_switch_to):
mov %o0, %sw_ntask
......@@ -34,37 +32,24 @@ C_LABEL(sparc_switch_to):
FLUSH_ALL_KERNEL_WINDOWS;
STORE_WINDOW(sp)
rd %psr, %sw_psr
sethi %hi(PSR_EF), %sw_tmp
andn %sw_psr, %sw_tmp, %sw_psr
LOAD_CURRENT(sw_tmp)
LOAD_CURRENT(sw_tmp, sw_wim)
rd %wim, %sw_wim
std %sw_psr, [%sw_tmp + THREAD_KPSR]
std %sp, [%sw_tmp + THREAD_KSP]
/* Load new kernel state. */
wr %sw_psr, PSR_ET, %psr
WRITE_PAUSE
sethi %hi(C_LABEL(current_set)), %sw_tmp
st %sw_ntask, [%sw_tmp + %lo(C_LABEL(current_set))]
ldd [%sw_ntask + THREAD_KPSR], %sw_psr
ldd [%sw_ntask + THREAD_KSP], %sw_sp
wr %sw_psr, PSR_ET, %psr
WRITE_PAUSE
wr %sw_wim, 0x0, %wim
WRITE_PAUSE
mov %sw_sp, %sp
ldd [%sw_ntask + THREAD_KSP], %sp
LOAD_WINDOW(sp)
mov %sw_pc, %o7
/* Jump into the proper context. */
ld [%sw_ntask + THREAD_CONTEXT], %sw_ctx
tst %sw_ctx
bneg 1f ! this must be swapper
nop
C_LABEL(mmu_switch_lowlevel):
sethi %hi(AC_CONTEXT), %sw_tmp ! else set new context
stba %sw_ctx, [%sw_tmp] ASI_CONTROL
1:
wr %sw_psr, 0x0, %psr ! traps back on
WRITE_PAUSE
......
/* sys_bsd.c: {net, open}bsd specific system call handling.
*
* Copyright (C) 1995 David S. Miller (davem@caipfs.rutgers.edu)
*/
#include <linux/kernel.h>
#include <asm/ptrace.h>
#include <asm/bsderrno.h>
static int errno_trans[] = {
0,
BSD_EPERM, BSD_ENOENT, BSD_ESRCH, BSD_EINTR, BSD_EIO,
BSD_ENXIO, BSD_E2BIG, BSD_ENOEXEC, BSD_EBADF, BSD_ECHILD,
BSD_EAGAIN, BSD_ENOMEM, BSD_EACCES, BSD_EFAULT, BSD_ENOTBLK,
BSD_EBUSY, BSD_EEXIST, BSD_EXDEV, BSD_ENODEV, BSD_ENOTDIR,
BSD_EISDIR, BSD_EINVAL, BSD_ENFILE, BSD_EMFILE, BSD_ENOTTY,
BSD_ETXTBSY, BSD_EFBIG, BSD_ENOSPC, BSD_ESPIPE, BSD_EROFS,
BSD_EMLINK, BSD_EPIPE, BSD_EDOM, BSD_ERANGE, BSD_EWOULDBLOCK,
BSD_EINPROGRESS, BSD_EALREADY, BSD_ENOTSOCK, BSD_EDESTADDRREQ,
BSD_EMSGSIZE, BSD_EPROTOTYPE, BSD_ENOPROTOOPT, BSD_EPROTONOSUPPORT,
BSD_ESOCKTNOSUPPORT, BSD_EOPNOTSUPP, BSD_EPFNOSUPPORT, BSD_EAFNOSUPPORT,
BSD_EADDRINUSE,
BSD_EADDRNOTAVAIL, BSD_ENETDOWN, BSD_ENETUNREACH, BSD_ENETRESET,
BSD_ECONNABORTED, BSD_ECONNRESET, BSD_ENOBUFS, BSD_EISCONN,
BSD_ENOTCONN, BSD_ESHUTDOWN, BSD_ETOOMANYREFS, BSD_ETIMEDOUT,
BSD_ECONNREFUSED, BSD_ELOOP, BSD_ENAMETOOLONG, BSD_EHOSTDOWN,
BSD_EHOSTUNREACH, BSD_ENOTEMPTY, BSD_EPROCLIM, BSD_EUSERS,
BSD_EDQUOT, BSD_ESTALE, BSD_EREMOTE, BSD_ENOSTR, BSD_ETIME,
BSD_ENOSR, BSD_ENOMSG, BSD_EBADMSG, BSD_EIDRM, BSD_EDEADLK,
BSD_ENOLCK, BSD_ENONET, BSD_ERREMOTE, BSD_ENOLINK, BSD_EADV,
BSD_ESRMNT, BSD_ECOMM, BSD_EPROTO, BSD_EMULTIHOP, BSD_EDOTDOT,
BSD_EREMCHG, BSD_ENOSYS
};
asmlinkage int netbsd_nosys(void)
{
struct pt_regs *regs;
regs = (struct pt_regs *) (current->saved_kernel_stack +
sizeof(struct reg_window));
current->tss.sig_address = regs->pc;
current->tss.sig_desc = regs->u_regs[UREG_G1];
send_sig(SIGSYS, current, 1);
printk("Process makes ni_syscall number %d, register dump:\n",
(int) regs->u_regs[UREG_G1]);
show_regs(regs);
return -BSD_ENOSYS;
}
/* $Id: sys_sparc.c,v 1.6 1995/11/25 00:58:34 davem Exp $
/* $Id: sys_sparc.c,v 1.7 1996/03/01 07:15:58 davem Exp $
* linux/arch/sparc/kernel/sys_sparc.c
*
* This file contains various random system calls that
......@@ -43,6 +43,38 @@ asmlinkage void sparc_pipe(struct pt_regs *regs)
}
}
/* Note most sanity checking already done in sclow.S code. */
asmlinkage int quick_sys_write(unsigned int fd, char *buf, unsigned int count)
{
struct file *file = current->files->fd[fd];
struct inode *inode = file->f_inode;
int error;
error = verify_area(VERIFY_READ, buf, count);
if(error)
return error;
/*
* If data has been written to the file, remove the setuid and
* the setgid bits. We do it anyway otherwise there is an
* extremely exploitable race - does your OS get it right |->
*
* Set ATTR_FORCE so it will always be changed.
*/
if (!suser() && (inode->i_mode & (S_ISUID | S_ISGID))) {
struct iattr newattrs;
newattrs.ia_mode = inode->i_mode & ~(S_ISUID | S_ISGID);
newattrs.ia_valid = ATTR_CTIME | ATTR_MODE | ATTR_FORCE;
notify_change(inode, &newattrs);
}
down(&inode->i_sem);
error = file->f_op->write(inode,file,buf,count);
up(&inode->i_sem);
return error;
}
/* XXX do we need this crap? XXX */
/*
* sys_ipc() is the de-multiplexer for the SysV IPC calls..
*
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
/* windows.c: Routines to deal with register window management
* at the C-code level.
*
* Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
*/
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/string.h>
#include <linux/mm.h>
/* Do save's until all user register windows are out of the cpu. */
void flush_user_windows(void)
{
if(current->tss.uwinmask)
flush_user_windows();
}
static inline void shift_window_buffer(int first_win, int last_win, struct thread_struct *tp)
{
int i;
for(i = first_win; i < last_win; i++) {
tp->rwbuf_stkptrs[i] = tp->rwbuf_stkptrs[i+1];
memcpy(&tp->reg_window[i], &tp->reg_window[i+1], sizeof(struct reg_window));
}
}
/* Place as many of the user's current register windows
* on the stack that we can. Even if the %sp is unaligned
* we still copy the window there, the only case that we don't
* succeed is if the %sp points to a bum mapping altogether.
* setup_frame() and do_sigreturn() use this before shifting
* the user stack around. Future instruction and hardware
* bug workaround routines will need this functionality as
* well.
*/
void synchronize_user_stack(void)
{
struct thread_struct *tp = &current->tss;
int window;
flush_user_windows();
if(!tp->w_saved)
return;
/* Ok, there is some dirty work to do. */
for(window = tp->w_saved - 1; window >= 0; window--) {
unsigned long sp = tp->rwbuf_stkptrs[window];
/* See if %sp is reasonable at all. */
if(verify_area(VERIFY_WRITE, (char *) sp, sizeof(struct reg_window)))
continue;
/* Ok, let it rip. */
memcpy((char *) sp, &tp->reg_window[window], sizeof(struct reg_window));
shift_window_buffer(window, tp->w_saved - 1, tp);
tp->w_saved--;
}
}
/* An optimization. */
static inline void copy_aligned_window(void *dest, const void *src)
{
__asm__ __volatile__("ldd [%1], %%g2\n\t"
"ldd [%1 + 0x8], %%g4\n\t"
"std %%g2, [%0]\n\t"
"std %%g4, [%0 + 0x8]\n\t"
"ldd [%1 + 0x10], %%g2\n\t"
"ldd [%1 + 0x18], %%g4\n\t"
"std %%g2, [%0 + 0x10]\n\t"
"std %%g4, [%0 + 0x18]\n\t"
"ldd [%1 + 0x20], %%g2\n\t"
"ldd [%1 + 0x28], %%g4\n\t"
"std %%g2, [%0 + 0x20]\n\t"
"std %%g4, [%0 + 0x28]\n\t"
"ldd [%1 + 0x30], %%g2\n\t"
"ldd [%1 + 0x38], %%g4\n\t"
"std %%g2, [%0 + 0x30]\n\t"
"std %%g4, [%0 + 0x38]\n\t" : :
"r" (dest), "r" (src) :
"g2", "g3", "g4", "g5");
}
/* Try to push the windows in a threads window buffer to the
* user stack. Unaligned %sp's are not allowed here.
*/
#define stack_is_bad(sp, rw) \
(((sp) & 7) || verify_area(rw, (char *) (sp), sizeof(struct reg_window)))
void try_to_clear_window_buffer(struct pt_regs *regs, int who)
{
struct thread_struct *tp = &current->tss;
int window;
flush_user_windows();
for(window = 0; window < tp->w_saved; window++) {
unsigned long sp = tp->rwbuf_stkptrs[window];
if(stack_is_bad(sp, VERIFY_WRITE))
do_exit(SIGILL);
else
copy_aligned_window((char *) sp, &tp->reg_window[window]);
}
tp->w_saved = 0;
}
/* $Id: wof.S,v 1.14 1995/11/25 00:58:49 davem Exp $
/* $Id: wof.S,v 1.20 1996/02/20 07:45:18 davem Exp $
* wof.S: Sparc window overflow handler.
*
* Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
......@@ -87,14 +87,14 @@ spnwin_patch2: and %glob_tmp, 0xff, %glob_tmp
* up for us to see if this is from user or kernel.
* Get the load of 'curptr' out of the way.
*/
LOAD_CURRENT(curptr)
LOAD_CURRENT(curptr, twin_tmp)
andcc %t_psr, PSR_PS, %g0
be spwin_fromuser ! all user wins, branch
nop
/* See if any user windows are active in the set. */
ld [%curptr + THREAD_UMASK], %twin_tmp ! grab currents win mask
ld [%curptr + THREAD_UMASK], %twin_tmp ! grab win mask
orcc %g0, %twin_tmp, %g0 ! check for set bits
bne spwin_exist_uwins ! yep, there are some
nop
......@@ -237,22 +237,25 @@ spnwin_patch3: and %twin_tmp, 0xff, %twin_tmp ! patched on 7win Sparcs
st %twin_tmp, [%curptr + THREAD_UMASK]
/* Jump onto kernel stack for this process... */
ld [%curptr + TASK_KSTACK_PG], %sp
add %sp, (PAGE_SIZE - TRACEREG_SZ - STACKFRAME_SZ), %sp
ld [%curptr + TASK_SAVED_KSTACK], %sp
/* Restore the saved globals and build a pt_regs frame. */
mov %saved_g5, %g5
mov %saved_g6, %g6
rd %wim, %twin_tmp
STORE_PT_ALL(sp, t_psr, t_pc, t_npc, twin_tmp, g1)
STORE_PT_ALL(sp, t_psr, t_pc, t_npc, g1)
/* Turn on traps and call c-code to deal with it. */
wr %t_psr, PSR_ET, %psr
WRITE_PAUSE
mov 1, %o1
call C_LABEL(do_sparc_winfault)
add %sp, STACKFRAME_SZ, %o0
#if 0
mov 0, %o1
call C_LABEL(try_to_clear_window_buffer)
add %sp, REGWIN_SZ, %o0
#else
call C_LABEL(window_overflow_fault)
nop
#endif
/* Return from trap if C-code actually fixes things, if it
* doesn't then we never get this far as the process will
......@@ -388,7 +391,7 @@ C_LABEL(spwin_srmmu_stackchk):
*/
/* Check results of callers andcc %sp, 0x7, %g0 */
bne spwin_user_stack_is_bolixed
sethi %hi(KERNBASE), %glob_tmp
sethi %hi(KERNBASE), %glob_tmp
cmp %glob_tmp, %sp
bleu spwin_user_stack_is_bolixed
mov AC_M_SFSR, %glob_tmp
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
3.5-beta7
3.5-beta10
0x030505
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
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