Commit 830e4ab4 authored by Linus Torvalds's avatar Linus Torvalds

Linux-2.1.124...

.. is out there now, and includes:

 - subtle fix for lazy FP save and restore on x86. The bug has been there
   for a long time, but was apparently triggered by the re-write of the
   low-level scheduling function. It could result in corrupted i387 state
   under certain (admittedly fairly unlikely) circumstances.
 - various networking updates. Some of the bugs fixed could result in
   kernel Oopses. None of them were common, though.
 - fixes for both filesystem accounting and quota handling.
 - the much-ado-about-little video driver merge.
 - PPC and Sparc updates
 - i386/SMP interrupt handling falls back on the safe mode.. Please tell
   me whether there are still machines with problems.
 - some new network drivers and updates
 - final (we hope) IP masquerade update

I still have a problem with certain machines that apparently don't want to
boot with the keyboard not plugged in even though they should. Kill me
now. If you have problems with i386/SMP on a machine without a keyboard,
plug one in and send me a report..
parent b03770e4
......@@ -943,8 +943,8 @@ S: L-1148 Luxembourg-City
S: Luxembourg
N: Gerd Knorr
E: kraxel@cs.tu-berlin.de
D: SCSI CD-ROM driver hacking, minor bug fixes
E: kraxel@goldbach.in-berlin.de
D: SCSI CD-ROM driver hacking, vesafb, v4l, minor bug fixes
N: Harald Koenig
E: koenig@tat.physik.uni-tuebingen.de
......
......@@ -226,6 +226,9 @@ will no longer work. You need to optain "ipchains," available from
http://www.adelaide.net.au/~rustcorp/ipfwchains/ipfwchains.html, and use
that instead of ipfwadm.
To use port forwarding and auto forwarding you will need 'ipmasqadm'
tool, available from http://juanjox.home.ml.org.
Memory
======
......@@ -540,6 +543,11 @@ The 1.3.3 release:
http://www.adelaide.net.au/~rustcorp/ipfwchains/ipchains-source-1.3.3.tar.gz
http://www.adelaide.net.au/~rustcorp/ipfwchains/ipchains-source-1.3.3.tar.bz2
IP Masq Adm
===========
The 0.4.1 release:
http://juanjox.home.ml.org/ipmasqadm-0.4.1.tar.gz
iBCS
====
......
This diff is collapsed.
......@@ -79,17 +79,20 @@ You can pass kernel command line options to vesafb with
by comma. Accepted options:
invers - no comment...
redraw - scroll by redrawing the affected part of the screen
redraw - scroll by redrawing the affected part of the screen.
This is the default.
ypan - enable display panning using the VESA protected mode
interface. This enables the Shift-PgUp scrollback
thing and greatly speeds up fullscreen scrolling.
It is slower than "redraw" when scrolling only a halve
screen. This is the default.
screen. Seems not to work with some BIOSes.
ywrap - If your gfx board supports wrap-around, use this one
instead of ypan.
nopal - Don't use the protected mode interface for palette
changes. vesafb will try the standard vga registers
instead.
vgapal - Use the standard vga registers for palette changes.
This is the default.
pmipal - Use the protected mode interface for palette changes.
Have fun!
......
/*
There is only 1 optname (see setsockopt(2)), IP_FW_MASQ_CTL that
must be used.
Funcionality depends on your kernel CONFIG options, here is
an example you can use to create an ``incoming'' tunnel:
See "user.c" module under ipmasqadm tree for a generic example
*/
#undef __KERNEL__ /* Makefile lazyness ;) */
#include <stdio.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <arpa/inet.h>
#include <asm/types.h> /* For __uXX types */
#include <net/if.h>
#include <netinet/ip_icmp.h>
#include <netinet/udp.h>
#include <netinet/tcp.h>
#include <linux/ip_fw.h> /* For IP_FW_MASQ_CTL */
#include <linux/ip_masq.h> /* For specific masq defs */
int create_listening_masq(struct ip_masq_ctl *masq, int proto, u_int32_t src_addr, u_int16_t src_port, u_int32_t dst_addr)
{
int sockfd;
sockfd = socket(AF_INET, SOCK_RAW, IPPROTO_RAW);
if (sockfd<0) {
perror("socket(RAW)");
return -1;
}
memset (masq, 0, sizeof (*masq));
/*
* Want user tunnel control
*/
masq->m_target = IP_MASQ_TARGET_USER;
/*
* Want to insert new
*/
masq->m_cmd = IP_MASQ_CMD_INSERT;
masq->u.user.protocol = proto;
masq->u.user.saddr = src_addr;
masq->u.user.sport = src_port;
masq->u.user.rt_daddr = inet_addr("192.168.21.239");
if (setsockopt(sockfd, IPPROTO_IP,
IP_FW_MASQ_CTL, (char *)masq, sizeof(*masq))) {
perror("setsockopt()");
return -1;
}
/* masq struct now contains tunnel details */
fprintf(stderr, "PROTO=%d SRC=0x%X:%x - MASQ=0x%X:%x - DST=0x%X:%x\n",
masq->u.user.protocol,
ntohl(masq->u.user.saddr), ntohs(masq->u.user.sport),
ntohl(masq->u.user.maddr), ntohs(masq->u.user.mport),
ntohl(masq->u.user.daddr), ntohs(masq->u.user.dport));
return 0;
}
int main(void) {
struct ip_masq_ctl masq_buf;
return create_listening_masq(&masq_buf,
IPPROTO_TCP,
inet_addr("192.168.1.4"),
htons(23),
inet_addr("192.168.21.3"));
}
......@@ -316,10 +316,11 @@ modules_install:
if [ -f VIDEO_MODULES ]; then inst_mod VIDEO_MODULES video; fi; \
if [ -f FC4_MODULES ]; then inst_mod FC4_MODULES fc4; fi; \
\
ls *.o > .allmods; \
echo $$MODULES | tr ' ' '\n' | sort | comm -23 .allmods - > .misc; \
if [ -s .misc ]; then inst_mod .misc misc; fi; \
rm -f .misc .allmods; \
rm -f /tmp/.misc.$$$$ /tmp/.allmods.$$$$; \
ls *.o > /tmp/.allmods.$$$$; \
echo $$MODULES | tr ' ' '\n' | sort | comm -23 /tmp/.allmods.$$$$ - > /tmp/.misc.$$$$; \
if [ -s /tmp/.misc.$$$$ ]; then inst_mod /tmp/.misc.$$$$ misc; fi; \
rm -f /tmp/.misc.$$$$ /tmp/.allmods.$$$$; \
)
# modules disabled....
......
......@@ -135,8 +135,9 @@ if [ "$CONFIG_VT" = "y" ]; then
mainmenu_option next_comment
comment 'Console drivers'
bool 'VGA text console' CONFIG_VGA_CONSOLE
bool 'Video mode selection support' CONFIG_VIDEO_SELECT
if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
bool 'Video mode selection support' CONFIG_VIDEO_SELECT
tristate 'MDA text console (dual-headed) (EXPERIMENTAL)' CONFIG_MDA_CONSOLE
bool 'Support for frame buffer devices (EXPERIMENTAL)' CONFIG_FB
fi
source drivers/video/Config.in
......
......@@ -288,6 +288,7 @@ CONFIG_DEVPTS_FS=y
# Console drivers
#
CONFIG_VGA_CONSOLE=y
# CONFIG_VIDEO_SELECT is not set
#
# Sound
......
......@@ -290,10 +290,23 @@ int IO_APIC_get_PCI_irq_vector(int bus, int slot, int pci_pin)
return -1;
}
/*
* Unclear documentation on what a "conforming ISA interrupt" means.
*
* Should we, or should we not, take the ELCR register into account?
* It's part of the EISA specification, but maybe it should only be
* used if the interrupt is actually marked as EISA?
*
* Oh, well. Don't do it until somebody tells us what the right thing
* to do is..
*/
#undef USE_ELCR_TRIGGER_LEVEL
#ifdef USE_ELCR_TRIGGER_LEVEL
/*
* ISA Edge/Level control register, ELCR
*/
static int __init ISA_ELCR(unsigned int irq)
static int __init EISA_ELCR(unsigned int irq)
{
if (irq < 16) {
unsigned int port = 0x4d0 + (irq >> 3);
......@@ -303,41 +316,15 @@ static int __init ISA_ELCR(unsigned int irq)
return 0;
}
/*
* ISA interrupts can be:
* - level triggered, active low (ELCR = 1)
* - edge triggered, active high (ELCR = 0)
* - edge triggered, active low (magic irq 8)
*/
static int __init default_ISA_trigger(int idx)
{
unsigned int irq = mp_irqs[idx].mpc_dstirq;
#define default_ISA_trigger(idx) (EISA_ELCR(mp_irqs[idx].mpc_dstirq))
#define default_ISA_polarity(idx) (0)
if (irq == 8)
return 0;
return ISA_ELCR(irq);
}
#else
static int __init default_ISA_polarity(int idx)
{
#if 0
unsigned int irq = mp_irqs[idx].mpc_dstirq;
#define default_ISA_trigger(idx) (0)
#define default_ISA_polarity(idx) (0)
if (irq == 8)
return 1;
return ISA_ELCR(irq);
#else
return 0;
#endif
}
/*
* There are broken mptables which register ISA+high-active+level IRQs,
* these are illegal and are converted here to ISA+high-active+edge
* IRQ sources. Careful, ISA+low-active+level is another broken entry
* type, it represents PCI IRQs 'embedded into an ISA bus', they have
* to be accepted. Yes, ugh.
*/
static int __init MPBIOS_polarity(int idx)
{
......@@ -457,37 +444,14 @@ static int __init MPBIOS_trigger(int idx)
return trigger;
}
static int __init trigger_flag_broken(int idx)
{
#if 0
int bus = mp_irqs[idx].mpc_srcbus;
int polarity = MPBIOS_polarity(idx);
int trigger = MPBIOS_trigger(idx);
if ( (mp_bus_id_to_type[bus] == MP_BUS_ISA) &&
(polarity == 0) /* active-high */ &&
(trigger == 1) /* level */ )
return 1; /* broken */
#endif
return 0;
}
static inline int irq_polarity(int idx)
{
/*
* There are no known BIOS bugs wrt polarity. yet.
*/
return MPBIOS_polarity(idx);
}
static inline int irq_trigger(int idx)
{
int trigger = MPBIOS_trigger(idx);
if (trigger_flag_broken(idx))
trigger = 0;
return trigger;
return MPBIOS_trigger(idx);
}
static int __init pin_2_irq(int idx, int pin)
......@@ -622,9 +586,6 @@ void __init setup_IO_APIC_irqs(void)
bus = mp_irqs[idx].mpc_srcbus;
if (trigger_flag_broken (idx))
printk("broken BIOS, changing pin %d to edge\n", pin);
io_apic_write(0x11+2*pin, *(((int *)&entry)+1));
io_apic_write(0x10+2*pin, *(((int *)&entry)+0));
}
......
......@@ -736,6 +736,7 @@ int __init start_secondary(void *unused)
/* Must be done before calibration delay is computed */
mtrr_init_secondary_cpu ();
#endif
stts();
smp_callin();
while (!smp_commenced)
barrier();
......@@ -1751,8 +1752,8 @@ void __init setup_APIC_clock(void)
static volatile int calibration_lock;
save_flags(flags);
cli();
__save_flags(flags);
__cli();
SMP_PRINTK(("setup_APIC_clock() called.\n"));
......@@ -1790,8 +1791,7 @@ void __init setup_APIC_clock(void)
ack_APIC_irq ();
restore_flags(flags);
__restore_flags(flags);
}
/*
......
......@@ -191,7 +191,7 @@ void die(const char * str, struct pt_regs * regs, long err)
do_exit(SIGSEGV);
}
static void die_if_kernel(const char * str, struct pt_regs * regs, long err)
static inline void die_if_kernel(const char * str, struct pt_regs * regs, long err)
{
if (!(regs->eflags & VM_MASK) && !(3 & regs->xcs))
die(str, regs, err);
......@@ -427,7 +427,7 @@ asmlinkage void do_spurious_interrupt_bug(struct pt_regs * regs,
* Careful.. There are problems with IBM-designed IRQ13 behaviour.
* Don't touch unless you *really* know how it works.
*/
asmlinkage void math_state_restore(void)
asmlinkage void math_state_restore(struct pt_regs regs)
{
__asm__ __volatile__("clts"); /* Allow maths ops (or we recurse) */
if(current->used_math)
......
......@@ -21,6 +21,7 @@
* applications that require more DP ram, we can expand the boundaries
* but then we have to be careful of any downloaded microcode.
*/
#include <linux/config.h>
#include <linux/errno.h>
#include <linux/sched.h>
#include <linux/kernel.h>
......
......@@ -25,6 +25,7 @@
* /Roman Zippel
*/
#include <linux/config.h>
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/sched.h>
......
#include <linux/config.h> /* CONFIG_HEARTBEAT */
#include <linux/errno.h>
#include <linux/sched.h>
#include <linux/kernel.h>
......
......@@ -12,6 +12,7 @@
* I f**ked around for a day trying to figure out how to make EPPC-Bug
* use SMC1, but gave up and decided to fix it here.
*/
#include <linux/config.h>
#include <linux/types.h>
#ifdef CONFIG_MBX
#include <asm/mbx.h>
......
......@@ -18,7 +18,6 @@
*
*/
#include <linux/config.h>
#include <linux/string.h>
#include <asm/residual.h>
#include <asm/pnp.h>
......
# $Id: Makefile,v 1.36 1998/06/02 00:36:40 davem Exp $
# $Id: Makefile,v 1.39 1998/09/16 12:31:31 jj Exp $
# sparc/Makefile
#
# Makefile for the architecture dependent flags and dependencies on the
......@@ -15,26 +15,35 @@ SHELL =/bin/bash
# Uncomment the first CFLAGS if you are doing kgdb source level
# debugging of the kernel to get the proper debugging information.
IS_EGCS := $(shell if $(CC) --version 2>&1 | grep 'egcs' > /dev/null; then echo y; else echo n; fi)
NEW_GAS := $(shell if $(LD) --version 2>&1 | grep 'elf64_sparc' > /dev/null; then echo y; else echo n; fi)
ifeq ($(NEW_GAS),y)
AS := $(AS) -32
LD := $(LD) -m elf32_sparc
endif
#CFLAGS := $(CFLAGS) -g -pipe -fcall-used-g5 -fcall-used-g7
ifneq ($(IS_EGCS),y)
CFLAGS := $(CFLAGS) -pipe -mno-fpu -fcall-used-g5 -fcall-used-g7
else
CFLAGS := $(CFLAGS) -m32 -pipe -mno-fpu -fcall-used-g5 -fcall-used-g7
endif
#LINKFLAGS = -N -Ttext 0xf0004000
LINKFLAGS = -T arch/sparc/vmlinux.lds
HEAD := arch/sparc/kernel/head.o arch/sparc/kernel/init_task.o
# Note arch/sparc/mm has to be the last subdir
SUBDIRS := $(SUBDIRS) arch/sparc/kernel arch/sparc/lib arch/sparc/prom \
arch/sparc/mm
arch/sparc/mm arch/sparc/math-emu
CORE_FILES := arch/sparc/kernel/kernel.o arch/sparc/mm/mm.o $(CORE_FILES)
CORE_FILES := arch/sparc/kernel/kernel.o arch/sparc/mm/mm.o $(CORE_FILES) \
arch/sparc/math-emu/math-emu.o
LIBS := $(TOPDIR)/lib/lib.a $(LIBS) $(TOPDIR)/arch/sparc/prom/promlib.a \
$(TOPDIR)/arch/sparc/lib/lib.a
SUBDIRS += arch/sparc/math-emu
CORE_FILES += arch/sparc/math-emu/math-emu.o
ifdef CONFIG_AP1000
SUBDIRS := $(SUBDIRS) arch/sparc/ap1000 mpp
CORE_FILES := $(TOPDIR)/arch/sparc/ap1000/ap1000lib.o \
......@@ -43,8 +52,14 @@ DRIVERS := $(DRIVERS) drivers/ap1000/ap1000.a
CFLAGS := $(CFLAGS) -D__MPP__=1
endif
# This one has to come last
SUBDIRS += arch/sparc/boot
CORE_FILES_NO_BTFIX := $(CORE_FILES)
CORE_FILES += arch/sparc/boot/btfix.o
archclean:
-$(MAKE) -C arch/sparc/boot archclean
rm -f $(TOPDIR)/vmlinux.aout
-$(MAKE) -C arch/sparc/boot clean
archmrproper:
-$(MAKE) -C arch/sparc/math-emu cleansymlinks
......@@ -57,19 +72,3 @@ check_asm:
tftpboot.img:
$(MAKE) -C arch/sparc/boot tftpboot.img
vmlinux.o: $(CONFIGURATION) init/main.o init/version.o linuxsubdirs
$(LD) -r $(VMLINUX.OBJS) -o vmlinux.o
arch/sparc/boot/btfix.s: arch/sparc/boot/btfixupprep vmlinux.o
$(OBJDUMP) -x vmlinux.o | arch/sparc/boot/btfixupprep > arch/sparc/boot/btfix.s
arch/sparc/boot/btfix.o: arch/sparc/boot/btfix.s
$(CC) -c -o arch/sparc/boot/btfix.o arch/sparc/boot/btfix.s
arch/sparc/boot/btfixupprep: arch/sparc/boot/btfixupprep.c
$(MAKE) -C arch/sparc/boot btfixupprep
vmlinux: arch/sparc/boot/btfix.o
$(LD) $(LINKFLAGS) vmlinux.o arch/sparc/boot/btfix.o -o vmlinux
$(NM) vmlinux | grep -v '\(compiled\)\|\(\.o$$\)\|\( [aU] \)\|\(\.\.ng$$\)\|\(LASH[RL]DI\)' | sort > System.map
# $Id: Makefile,v 1.6 1998/02/23 01:44:39 rth Exp $
# $Id: Makefile,v 1.8 1998/09/16 12:24:51 jj Exp $
# Makefile for the Sparc boot stuff.
#
# Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
# Copyright (C) 1997 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
# Copyright (C) 1997,1998 Jakub Jelinek (jj@ultra.linux.cz)
ROOT_IMG =/usr/src/root.img
ELFTOAOUT =elftoaout
all: boot
boot:
@echo "Nothing special to be done for 'boot' on Linux/SPARC."
all: btfix.o
tftpboot.img: piggyback
$(ELFTOAOUT) $(TOPDIR)/vmlinux -o tftpboot.img
......@@ -22,8 +19,20 @@ piggyback: piggyback.c
btfixupprep: btfixupprep.c
$(HOSTCC) $(HOSTCFLAGS) -o btfixupprep btfixupprep.c
archclean:
rm -f btfixupprep piggyback tftpboot.img
clean:
rm -f btfixupprep piggyback tftpboot.img btfix.o btfix.s
BTOBJS := $(HEAD) init/main.o init/version.o \
$(CORE_FILES_NO_BTFIX) $(FILESYSTEMS) \
$(NETWORKS) $(DRIVERS)
vmlinux.o: dummy
$(LD) -r $(patsubst %,$(TOPDIR)/%,$(BTOBJS)) $(LIBS) -o vmlinux.o
btfix.s: btfixupprep vmlinux.o
$(OBJDUMP) -x vmlinux.o | ./btfixupprep > btfix.s
dep:
btfix.o: btfix.s
$(CC) -c -o btfix.o btfix.s
include $(TOPDIR)/Rules.make
/* $Id: btfixupprep.c,v 1.3 1998/03/09 14:03:10 jj Exp $
/* $Id: btfixupprep.c,v 1.5 1998/09/16 12:24:55 jj Exp $
Simple utility to prepare vmlinux image for sparc.
Resolves all BTFIXUP uses and settings and creates
a special .s object to link to the image.
......@@ -29,8 +29,11 @@
#define MAXSYMS 1024
static char *symtab = "SYMBOL TABLE:";
static char *relrec = "RELOCATION RECORDS FOR [";
static int rellen;
static int symlen;
int mode;
struct _btfixup;
......@@ -97,6 +100,20 @@ int main(int argc,char **argv)
unsigned long offset;
char *initvalstr;
symlen = strlen(symtab);
while (fgets (buffer, 1024, stdin) != NULL)
if (!strncmp (buffer, symtab, symlen))
goto main0;
fatal();
main0:
if (fgets (buffer, 1024, stdin) == NULL || buffer[0] < '0' || buffer[0] > '9')
fatal();
for (mode = 0;; mode++)
if (buffer[mode] < '0' || buffer[mode] > '9')
break;
if (mode != 8 && mode != 16)
fatal();
rellen = strlen(relrec);
while (fgets (buffer, 1024, stdin) != NULL)
if (!strncmp (buffer, relrec, rellen))
......@@ -112,17 +129,19 @@ int main(int argc,char **argv)
if (fgets (buffer, 1024, stdin) == NULL)
fatal();
while (fgets (buffer, 1024, stdin) != NULL) {
int nbase;
if (!strncmp (buffer, relrec, rellen))
goto main1;
p = strchr (buffer, '\n');
if (p) *p = 0;
if (strlen (buffer) < 30)
if (strlen (buffer) < 22+mode)
continue;
if (strncmp (buffer + 8, " R_SPARC_", 9))
if (strncmp (buffer + mode, " R_SPARC_", 9))
continue;
if (buffer[27] != '_' || buffer[28] != '_' || buffer[29] != '_')
nbase = 27 - 8 + mode;
if (buffer[nbase] != '_' || buffer[nbase+1] != '_' || buffer[nbase+2] != '_')
continue;
switch (buffer[30]) {
switch (buffer[nbase+3]) {
case 'f': /* CALL */
case 'b': /* BLACKBOX */
case 's': /* SIMM13 */
......@@ -133,26 +152,26 @@ int main(int argc,char **argv)
default:
continue;
}
p = strchr (buffer + 32, '+');
p = strchr (buffer + nbase+5, '+');
if (p) *p = 0;
shift = 32;
if (buffer[31] == 's' && buffer[32] == '_') {
shift = 33;
shift = nbase + 5;
if (buffer[nbase+4] == 's' && buffer[nbase+5] == '_') {
shift = nbase + 6;
if (strcmp (sect, ".text.init")) {
fprintf(stderr, "Wrong use of '%s' BTFIXUPSET.\nBTFIXUPSET_CALL can be used only in __init sections\n", buffer+shift);
exit(1);
}
} else if (buffer[31] != '_')
} else if (buffer[nbase+4] != '_')
continue;
if (strcmp (sect, ".text") && strcmp (sect, ".text.init") && (strcmp (sect, "__ksymtab") || buffer[30] != 'f')) {
if (buffer[30] == 'f')
fprintf(stderr, "Wrong use of '%s' in '%s' section. It can be only used in .text, .text.init and __ksymtab\n", buffer + shift, sect);
if (strcmp (sect, ".text") && strcmp (sect, ".text.init") && strcmp (sect, ".fixup") && (strcmp (sect, "__ksymtab") || buffer[nbase+3] != 'f')) {
if (buffer[nbase+3] == 'f')
fprintf(stderr, "Wrong use of '%s' in '%s' section. It can be only used in .text, .text.init, .fixup and __ksymtab\n", buffer + shift, sect);
else
fprintf(stderr, "Wrong use of '%s' in '%s' section. It can be only used in .text and .text.init\n", buffer + shift, sect);
fprintf(stderr, "Wrong use of '%s' in '%s' section. It can be only used in .text, .fixup and .text.init\n", buffer + shift, sect);
exit(1);
}
p = strstr (buffer + shift, "__btset_");
if (p && buffer[31] == 's') {
if (p && buffer[nbase+4] == 's') {
fprintf(stderr, "__btset_ in BTFIXUP name can only be used when defining the variable, not for setting\n%s\n", buffer);
exit(1);
}
......@@ -171,23 +190,23 @@ int main(int argc,char **argv)
initvalstr = p + 10;
*p = 0;
}
f = find(buffer[30], buffer + shift);
if (buffer[31] == 's')
f = find(buffer[nbase+3], buffer + shift);
if (buffer[nbase+4] == 's')
continue;
switch (buffer[30]) {
switch (buffer[nbase+3]) {
case 'f':
if (initval) {
fprintf(stderr, "Cannot use pre-initalized fixups for calls\n%s\n", buffer);
exit(1);
}
if (!strcmp (sect, "__ksymtab")) {
if (strncmp (buffer + 17, "32 ", 10)) {
if (strncmp (buffer + mode+9, "32 ", 10)) {
fprintf(stderr, "BTFIXUP_CALL in EXPORT_SYMBOL results in relocation other than R_SPARC_32\n\%s\n", buffer);
exit(1);
}
} else if (strncmp (buffer + 17, "WDISP30 ", 10) &&
strncmp (buffer + 17, "HI22 ", 10) &&
strncmp (buffer + 17, "LO10 ", 10)) {
} else if (strncmp (buffer + mode+9, "WDISP30 ", 10) &&
strncmp (buffer + mode+9, "HI22 ", 10) &&
strncmp (buffer + mode+9, "LO10 ", 10)) {
fprintf(stderr, "BTFIXUP_CALL results in relocation other than R_SPARC_WDISP30, R_SPARC_HI22 or R_SPARC_LO10\n%s\n", buffer);
exit(1);
}
......@@ -197,7 +216,7 @@ int main(int argc,char **argv)
fprintf(stderr, "Cannot use pre-initialized fixups for blackboxes\n%s\n", buffer);
exit(1);
}
if (strncmp (buffer + 17, "HI22 ", 10)) {
if (strncmp (buffer + mode+9, "HI22 ", 10)) {
fprintf(stderr, "BTFIXUP_BLACKBOX results in relocation other than R_SPARC_HI22\n%s\n", buffer);
exit(1);
}
......@@ -207,7 +226,7 @@ int main(int argc,char **argv)
fprintf(stderr, "Wrong initializer for SIMM13. Has to be from $fffff000 to $00000fff\n%s\n", buffer);
exit(1);
}
if (strncmp (buffer + 17, "13 ", 10)) {
if (strncmp (buffer + mode+9, "13 ", 10)) {
fprintf(stderr, "BTFIXUP_SIMM13 results in relocation other than R_SPARC_13\n%s\n", buffer);
exit(1);
}
......@@ -217,7 +236,7 @@ int main(int argc,char **argv)
fprintf(stderr, "Wrong initializer for HALF.\n%s\n", buffer);
exit(1);
}
if (strncmp (buffer + 17, "13 ", 10)) {
if (strncmp (buffer + mode+9, "13 ", 10)) {
fprintf(stderr, "BTFIXUP_HALF results in relocation other than R_SPARC_13\n%s\n", buffer);
exit(1);
}
......@@ -227,7 +246,7 @@ int main(int argc,char **argv)
fprintf(stderr, "Wrong initializer for SETHI. Cannot have set low 10 bits\n%s\n", buffer);
exit(1);
}
if (strncmp (buffer + 17, "HI22 ", 10)) {
if (strncmp (buffer + mode+9, "HI22 ", 10)) {
fprintf(stderr, "BTFIXUP_SETHI results in relocation other than R_SPARC_HI22\n%s\n", buffer);
exit(1);
}
......@@ -237,7 +256,7 @@ int main(int argc,char **argv)
fprintf(stderr, "Cannot use pre-initalized fixups for INT\n%s\n", buffer);
exit(1);
}
if (strncmp (buffer + 17, "HI22 ", 10) && strncmp (buffer + 17, "LO10 ", 10)) {
if (strncmp (buffer + mode+9, "HI22 ", 10) && strncmp (buffer + mode+9, "LO10 ", 10)) {
fprintf(stderr, "BTFIXUP_INT results in relocation other than R_SPARC_HI22 and R_SPARC_LO10\n%s\n", buffer);
exit(1);
}
......@@ -261,7 +280,7 @@ int main(int argc,char **argv)
exit(1);
}
offset = strtoul(buffer, &q, 16);
if (q != buffer + 8 || (!offset && strncmp (buffer, "00000000 ", 9))) {
if (q != buffer + mode || (!offset && (mode == 8 ? strncmp (buffer, "00000000 ", 9) : strncmp (buffer, "0000000000000000 ", 17)))) {
fprintf(stderr, "Malformed relocation address in\n%s\n", buffer);
exit(1);
}
......@@ -274,7 +293,7 @@ int main(int argc,char **argv)
if (!*rr) fatal();
(*rr)->offset = offset;
(*rr)->f = NULL;
if (buffer[30] == 'f') {
if (buffer[nbase+3] == 'f') {
lastf = f;
lastfoffset = offset;
lastfrelno = k;
......@@ -302,11 +321,13 @@ int main(int argc,char **argv)
printf("0\n");
for (r = f->rel, j--; r != NULL; j--, r = r->next) {
if (!strcmp (r->sect, ".text"))
printf ("_stext+0x%08x", r->offset);
printf ("_stext+0x%08lx", r->offset);
else if (!strcmp (r->sect, ".text.init"))
printf ("__init_begin+0x%08x", r->offset);
printf ("__init_begin+0x%08lx", r->offset);
else if (!strcmp (r->sect, "__ksymtab"))
printf ("__start___ksymtab+0x%08x", r->offset);
printf ("__start___ksymtab+0x%08lx", r->offset);
else if (!strcmp (r->sect, ".fixup"))
printf ("__start___fixup+0x%08lx", r->offset);
else
fatal();
if (f->type == 'f' || !r->f)
......
# $Id: config.in,v 1.58 1998/07/29 05:06:41 davem Exp $
# $Id: config.in,v 1.63 1998/09/21 05:05:56 jj Exp $
# For a description of the syntax of this configuration file,
# see the Configure script.
#
......@@ -35,6 +35,9 @@ if [ "$CONFIG_AP1000" = "y" ]; then
tristate 'OPIU DDV Driver' CONFIG_DDV
else
bool 'Support for SUN4 machines (disables SUN4[CDM] support)' CONFIG_SUN4
if [ "$CONFIG_SUN4" != "y" ]; then
bool 'Support for PCI and PS/2 keyboard/mouse' CONFIG_PCI
fi
mainmenu_option next_comment
comment 'Console drivers'
......@@ -54,9 +57,7 @@ else
define_bool CONFIG_SUN_CONSOLE y
define_bool CONFIG_SUN_AUXIO y
define_bool CONFIG_SUN_IO y
if [ "$CONFIG_SUN4" = "y" ]; then
bool 'Force early PROM Console' CONFIG_SUN4_FORCECONSOLE
else
if [ "$CONFIG_SUN4" != "y" ]; then
source drivers/sbus/char/Config.in
source drivers/sbus/audio/Config.in
fi
......
......@@ -120,8 +120,7 @@ CONFIG_IP_MASQUERADE=y
#
# Protocol-specific masquerading support will be built as modules.
#
# CONFIG_IP_MASQUERADE_IPAUTOFW is not set
# CONFIG_IP_MASQUERADE_IPPORTFW is not set
# CONFIG_IP_MASQUERADE_MOD is not set
# CONFIG_IP_ROUTER is not set
# CONFIG_NET_IPIP is not set
# CONFIG_NET_IPGRE is not set
......@@ -136,7 +135,7 @@ CONFIG_IP_ALIAS=y
CONFIG_INET_RARP=m
CONFIG_IP_NOSR=y
CONFIG_SKB_LARGE=y
CONFIG_IPV6=m
CONFIG_IPV6=y
# CONFIG_IPV6_EUI64 is not set
#
......@@ -273,7 +272,8 @@ CONFIG_BSD_DISKLABEL=y
CONFIG_SMD_DISKLABEL=y
# CONFIG_SOLARIS_X86_PARTITION is not set
# CONFIG_ADFS_FS is not set
CONFIG_DEVPTS_FS=y
CONFIG_QNX4FS_FS=m
# CONFIG_QNX4FS_RW is not set
# CONFIG_MAC_PARTITION is not set
CONFIG_NLS=y
......
# $Id: Makefile,v 1.45 1998/07/28 16:52:42 jj Exp $
# $Id: Makefile,v 1.48 1998/09/21 05:04:46 jj Exp $
# Makefile for the linux kernel.
#
# Note! Dependencies are done automagically by 'make dep', which also
......@@ -22,7 +22,7 @@ O_OBJS := entry.o wof.o wuf.o etrap.o rtrap.o traps.o ${IRQ_OBJS} \
sys_sparc.o sunos_asm.o sparc-stub.o systbls.o sys_sunos.o \
sunos_ioctl.o time.o windows.o cpu.o devices.o \
sclow.o solaris.o tadpole.o tick14.o ptrace.o sys_solaris.o \
unaligned.o muldiv.o
unaligned.o muldiv.o pcic.o
OX_OBJS := sparc_ksyms.o
......@@ -38,6 +38,10 @@ ifdef CONFIG_SUN_AUXIO
O_OBJS += auxio.o
endif
ifdef CONFIG_PCI
O_OBJS += ebus.o
endif
head.o: head.S
$(CC) -D__ASSEMBLY__ $(AFLAGS) -ansi -c $*.S -o $*.o
......
......@@ -5,6 +5,7 @@
#include <linux/stddef.h>
#include <linux/init.h>
#include <linux/config.h>
#include <asm/oplib.h>
#include <asm/io.h>
#include <asm/auxio.h>
......@@ -32,6 +33,11 @@ __initfunc(void auxio_probe(void))
node = prom_getchild(node);
auxio_nd = prom_searchsiblings(node, "auxio");
if(!auxio_nd) {
#ifdef CONFIG_PCI
/* There may be auxio on Ebus */
auxio_register = 0;
return;
#else
if(prom_searchsiblings(node, "leds")) {
/* VME chassis sun4m machine, no auxio exists. */
auxio_register = 0;
......@@ -39,6 +45,7 @@ __initfunc(void auxio_probe(void))
}
prom_printf("Cannot find auxio node, cannot continue...\n");
prom_halt();
#endif
}
}
prom_getproperty(auxio_nd, "reg", (char *) auxregs, sizeof(auxregs));
......
/* $Id: ebus.c,v 1.1 1998/09/18 10:43:43 jj Exp $
* ebus.c: PCI to EBus bridge device.
*
* Copyright (C) 1997 Eddie C. Dost (ecd@skynet.be)
*
* Adopted for sparc by V. Roganov and G. Raiko.
*/
#include <linux/config.h>
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/init.h>
#include <linux/malloc.h>
#include <linux/string.h>
#include <asm/system.h>
#include <asm/page.h>
#include <asm/pbm.h>
#include <asm/ebus.h>
#include <asm/io.h>
#include <asm/oplib.h>
#include <asm/bpp.h>
#undef PROM_DEBUG
#undef DEBUG_FILL_EBUS_DEV
#ifdef PROM_DEBUG
#define dprintf prom_printf
#else
#define dprintf printk
#endif
struct linux_ebus *ebus_chain = 0;
#ifdef CONFIG_SUN_OPENPROMIO
extern int openprom_init(void);
#endif
#ifdef CONFIG_SPARCAUDIO
extern int sparcaudio_init(void);
#endif
#ifdef CONFIG_SUN_AUXIO
extern void auxio_probe(void);
#endif
#ifdef CONFIG_OBP_FLASH
extern int flash_init(void);
#endif
#ifdef CONFIG_ENVCTRL
extern int envctrl_init(void);
#endif
static inline unsigned long ebus_alloc(size_t size)
{
return (unsigned long)kmalloc(size, GFP_ATOMIC);
}
__initfunc(void fill_ebus_child(int node, struct linux_prom_registers *preg,
struct linux_ebus_child *dev))
{
int regs[PROMREG_MAX];
int irqs[PROMREG_MAX];
char lbuf[128];
int i, len;
dev->prom_node = node;
prom_getstring(node, "name", lbuf, sizeof(lbuf));
strcpy(dev->prom_name, lbuf);
len = prom_getproperty(node, "reg", (void *)regs, sizeof(regs));
dev->num_addrs = len / sizeof(regs[0]);
for (i = 0; i < dev->num_addrs; i++) {
if (regs[i] >= dev->parent->num_addrs) {
prom_printf("UGH: property for %s was %d, need < %d\n",
dev->prom_name, len, dev->parent->num_addrs);
panic(__FUNCTION__);
}
dev->base_address[i] = dev->parent->base_address[regs[i]];
}
len = prom_getproperty(node, "interrupts", (char *)&irqs, sizeof(irqs));
if ((len == -1) || (len == 0)) {
dev->num_irqs = 0;
/*
* Oh, well, some PROMs don't export interrupts
* property to children of EBus devices...
*
* Be smart about PS/2 keyboard and mouse.
*/
if (!strcmp(dev->parent->prom_name, "8042")) {
dev->num_irqs = 1;
dev->irqs[0] = dev->parent->irqs[0];
}
} else {
dev->num_irqs = len / sizeof(irqs[0]);
printk("FIXME: %s irq(%d)\n", dev->prom_name, irqs[0]);
}
#ifdef DEBUG_FILL_EBUS_DEV
dprintk("child '%s': address%s\n", dev->prom_name,
dev->num_addrs > 1 ? "es" : "");
for (i = 0; i < dev->num_addrs; i++)
dprintk(" %016lx\n", dev->base_address[i]);
if (dev->num_irqs) {
dprintk(" IRQ%s", dev->num_irqs > 1 ? "s" : "");
for (i = 0; i < dev->num_irqs; i++)
dprintk(" %08x", dev->irqs[i]);
dprintk("\n");
}
#endif
}
__initfunc(void fill_ebus_device(int node, struct linux_ebus_device *dev))
{
struct linux_prom_registers regs[PROMREG_MAX];
struct linux_ebus_child *child;
int irqs[PROMINTR_MAX];
char lbuf[128];
int i, n, len;
dev->prom_node = node;
prom_getstring(node, "name", lbuf, sizeof(lbuf));
strcpy(dev->prom_name, lbuf);
len = prom_getproperty(node, "reg", (void *)regs, sizeof(regs));
if (len % sizeof(struct linux_prom_registers)) {
prom_printf("UGH: proplen for %s was %d, need multiple of %d\n",
dev->prom_name, len,
(int)sizeof(struct linux_prom_registers));
panic(__FUNCTION__);
}
dev->num_addrs = len / sizeof(struct linux_prom_registers);
for (i = 0; i < dev->num_addrs; i++) {
n = (regs[i].which_io - 0x10) >> 2;
dev->base_address[i] = dev->bus->self->base_address[n];
dev->base_address[i] += regs[i].phys_addr;
if (dev->base_address[i]) {
dev->base_address[i] =
(unsigned long)sparc_alloc_io (dev->base_address[i], 0,
regs[i].reg_size,
dev->prom_name, 0, 0);
if (dev->base_address[i] == 0 ) {
panic("ebus: unable sparc_alloc_io for dev %s",
dev->prom_name);
}
}
}
len = prom_getproperty(node, "interrupts", (char *)&irqs, sizeof(irqs));
if ((len == -1) || (len == 0)) {
dev->num_irqs = 0;
} else {
dev->num_irqs = len / sizeof(irqs[0]);
#define IRQ_8042 7
if (irqs[0] == 4) dev->irqs[0] = IRQ_8042;
printk("FIXME: %s irq(%d)\n", dev->prom_name, irqs[0]);
}
#ifdef DEBUG_FILL_EBUS_DEV
dprintk("'%s': address%s\n", dev->prom_name,
dev->num_addrs > 1 ? "es" : "");
for (i = 0; i < dev->num_addrs; i++)
dprintk(" %016lx\n", dev->base_address[i]);
if (dev->num_irqs) {
dprintk(" IRQ%s", dev->num_irqs > 1 ? "s" : "");
for (i = 0; i < dev->num_irqs; i++)
dprintk(" %08x", dev->irqs[i]);
dprintk("\n");
}
#endif
if ((node = prom_getchild(node))) {
dev->children = (struct linux_ebus_child *)
ebus_alloc(sizeof(struct linux_ebus_child));
child = dev->children;
child->next = 0;
child->parent = dev;
child->bus = dev->bus;
fill_ebus_child(node, &regs[0], child);
while ((node = prom_getsibling(node))) {
child->next = (struct linux_ebus_child *)
ebus_alloc(sizeof(struct linux_ebus_child));
child = child->next;
child->next = 0;
child->parent = dev;
child->bus = dev->bus;
fill_ebus_child(node, &regs[0], child);
}
}
}
__initfunc(void ebus_init(void))
{
struct linux_prom_pci_registers regs[PROMREG_MAX];
struct linux_pbm_info *pbm;
struct linux_ebus_device *dev;
struct linux_ebus *ebus;
struct pci_dev *pdev;
struct pcidev_cookie *cookie;
char lbuf[128];
unsigned long addr, *base;
unsigned short pci_command;
int nd, len, ebusnd;
int reg, nreg;
int num_ebus = 0;
if (!pci_present())
return;
pdev = pci_find_device(PCI_VENDOR_ID_SUN, PCI_DEVICE_ID_SUN_EBUS, 0);
if (!pdev) {
#ifdef PROM_DEBUG
dprintk("ebus: No EBus's found.\n");
#endif
return;
}
cookie = pdev->sysdata;
ebusnd = cookie->prom_node;
ebus_chain = ebus = (struct linux_ebus *)
ebus_alloc(sizeof(struct linux_ebus));
ebus->next = 0;
while (ebusnd) {
#ifdef PROM_DEBUG
dprintk("ebus%d:", num_ebus);
#endif
prom_getstring(ebusnd, "name", lbuf, sizeof(lbuf));
ebus->prom_node = ebusnd;
strcpy(ebus->prom_name, lbuf);
ebus->self = pdev;
ebus->parent = pbm = cookie->pbm;
/* Enable BUS Master. */
pci_read_config_word(pdev, PCI_COMMAND, &pci_command);
pci_command |= PCI_COMMAND_MASTER;
pci_write_config_word(pdev, PCI_COMMAND, pci_command);
len = prom_getproperty(ebusnd, "reg", (void *)regs,
sizeof(regs));
if (len == 0 || len == -1) {
prom_printf("%s: can't find reg property\n",
__FUNCTION__);
prom_halt();
}
nreg = len / sizeof(struct linux_prom_pci_registers);
base = &ebus->self->base_address[0];
for (reg = 0; reg < nreg; reg++) {
if (!(regs[reg].which_io & 0x03000000))
continue;
addr = regs[reg].phys_lo;
*base++ = addr;
#ifdef PROM_DEBUG
dprintk(" %lx[%x]", addr, regs[reg].size_lo);
#endif
}
#ifdef PROM_DEBUG
dprintk("\n");
#endif
nd = prom_getchild(ebusnd);
if (!nd)
goto next_ebus;
ebus->devices = (struct linux_ebus_device *)
ebus_alloc(sizeof(struct linux_ebus_device));
dev = ebus->devices;
dev->next = 0;
dev->children = 0;
dev->bus = ebus;
fill_ebus_device(nd, dev);
while ((nd = prom_getsibling(nd))) {
dev->next = (struct linux_ebus_device *)
ebus_alloc(sizeof(struct linux_ebus_device));
dev = dev->next;
dev->next = 0;
dev->children = 0;
dev->bus = ebus;
fill_ebus_device(nd, dev);
}
next_ebus:
pdev = pci_find_device(PCI_VENDOR_ID_SUN,
PCI_DEVICE_ID_SUN_EBUS, pdev);
if (!pdev)
break;
cookie = pdev->sysdata;
ebusnd = cookie->prom_node;
ebus->next = (struct linux_ebus *)
ebus_alloc(sizeof(struct linux_ebus));
ebus = ebus->next;
ebus->next = 0;
++num_ebus;
}
#ifdef CONFIG_SUN_OPENPROMIO
openprom_init();
#endif
#ifdef CONFIG_SPARCAUDIO
sparcaudio_init();
#endif
#ifdef CONFIG_SUN_BPP
bpp_init();
#endif
#ifdef CONFIG_SUN_AUXIO
auxio_probe();
#endif
#ifdef CONFIG_ENVCTRL
envctrl_init();
#endif
#ifdef CONFIG_OBP_FLASH
flash_init();
#endif
}
/* $Id: irq.c,v 1.86 1998/06/04 09:54:49 jj Exp $
/* $Id: irq.c,v 1.89 1998/09/21 05:05:12 jj Exp $
* arch/sparc/kernel/irq.c: Interrupt request handling routines. On the
* Sparc the IRQ's are basically 'cast in stone'
* and you are supposed to probe the prom's device
......@@ -6,7 +6,7 @@
*
* Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
* Copyright (C) 1995 Miguel de Icaza (miguel@nuclecu.unam.mx)
* Copyright (C) 1995 Pete A. Zaitcev (zaitcev@ipmce.su)
* Copyright (C) 1995 Pete A. Zaitcev (zaitcev@metabyte.com)
* Copyright (C) 1996 Dave Redman (djhr@tadpole.co.uk)
*/
......@@ -40,6 +40,7 @@
#include <asm/spinlock.h>
#include <asm/hardirq.h>
#include <asm/softirq.h>
#include <asm/pcic.h>
/*
* Dave Redman (djhr@tadpole.co.uk)
......@@ -669,6 +670,13 @@ __initfunc(void init_IRQ(void))
break;
case sun4m:
#ifdef CONFIG_PCI
pcic_probe();
if (pci_present()) {
sun4m_pci_init_IRQ();
break;
}
#endif
sun4m_init_IRQ();
break;
......
This diff is collapsed.
/* $Id: process.c,v 1.118 1998/08/04 20:48:47 davem Exp $
/* $Id: process.c,v 1.126 1998/09/21 05:05:18 jj Exp $
* linux/arch/sparc/kernel/process.c
*
* Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
......@@ -61,8 +61,8 @@ asmlinkage int sys_idle(void)
goto out;
/* endless idle loop with no priority at all */
current->priority = -100;
current->counter = -100;
current->priority = 0;
current->counter = 0;
for (;;) {
if (ARCH_SUN4C_SUN4) {
static int count = HZ;
......@@ -108,16 +108,13 @@ asmlinkage int sys_idle(void)
/* This is being executed in task 0 'user space'. */
int cpu_idle(void *unused)
{
extern volatile int smp_commenced;
current->priority = -100;
current->priority = 0;
while(1) {
srmmu_check_pgt_cache();
run_task_queue(&tq_scheduler);
/* endless idle loop with no priority at all */
current->counter = -100;
if(!smp_commenced || current->need_resched)
schedule();
check_pgt_cache();
run_task_queue(&tq_scheduler);
/* endless idle loop with no priority at all */
current->counter = 0;
schedule();
}
}
......@@ -176,8 +173,10 @@ void machine_restart(char * cmd)
void machine_power_off(void)
{
#ifdef CONFIG_SUN_AUXIO
if (auxio_power_register)
*auxio_power_register |= AUXIO_POWER_OFF;
#endif
machine_halt();
}
......@@ -594,8 +593,44 @@ void dump_thread(struct pt_regs * regs, struct user * dump)
*/
int dump_fpu (struct pt_regs * regs, elf_fpregset_t * fpregs)
{
/* Currently we report that we couldn't dump the fpu structure */
return 0;
if (current->used_math == 0) {
memset(fpregs, 0, sizeof(*fpregs));
fpregs->pr_q_entrysize = 8;
return 1;
}
#ifdef __SMP__
if (current->flags & PF_USEDFPU) {
put_psr(get_psr() | PSR_EF);
fpsave(&current->tss.float_regs[0], &current->tss.fsr,
&current->tss.fpqueue[0], &current->tss.fpqdepth);
regs->psr &= ~(PSR_EF);
current->flags &= ~(PF_USEDFPU);
}
#else
if (current == last_task_used_math) {
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 = 0;
regs->psr &= ~(PSR_EF);
}
#endif
memcpy(&fpregs->pr_fr.pr_regs[0],
&current->tss.float_regs[0],
(sizeof(unsigned long) * 32));
fpregs->pr_fsr = current->tss.fsr;
fpregs->pr_qcnt = current->tss.fpqdepth;
fpregs->pr_q_entrysize = 8;
fpregs->pr_en = 1;
if(fpregs->pr_qcnt != 0) {
memcpy(&fpregs->pr_q[0],
&current->tss.fpqueue[0],
sizeof(struct fpq) * fpregs->pr_qcnt);
}
/* Zero out the rest. */
memset(&fpregs->pr_q[fpregs->pr_qcnt], 0,
sizeof(struct fpq) * (32 - fpregs->pr_qcnt));
return 1;
}
/*
......
/* $Id: setup.c,v 1.99 1998/07/28 16:52:45 jj Exp $
/* $Id: setup.c,v 1.103 1998/09/21 05:05:23 jj Exp $
* linux/arch/sparc/kernel/setup.c
*
* Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
......@@ -332,9 +332,6 @@ __initfunc(void setup_arch(char **cmdline_p,
switch(sparc_cpu_model) {
case sun4:
printk("SUN4\n");
#ifdef CONFIG_SUN4_FORCECONSOLE
register_console(&prom_console);
#endif
packed = 0;
break;
case sun4c:
......@@ -443,8 +440,14 @@ __initfunc(void setup_arch(char **cmdline_p,
serial_console = 1;
} else if (idev == PROMDEV_ITTYB && odev == PROMDEV_OTTYB) {
serial_console = 2;
} else if (idev == PROMDEV_I_UNK && odev == PROMDEV_OTTYA) {
prom_printf("MrCoffee ttya\n");
serial_console = 1;
} else if (idev == PROMDEV_I_UNK && odev == PROMDEV_OSCREEN) {
serial_console = 0;
prom_printf("MrCoffee keyboard\n");
} else {
prom_printf("Inconsistent console\n");
prom_printf("Inconsistent or unknown console\n");
prom_halt();
}
}
......
This diff is collapsed.
......@@ -159,7 +159,7 @@ void smp_flush_tlb_mm(struct mm_struct *mm)
local_flush_tlb_mm(mm);
} else {
xc1((smpfunc_t) BTFIXUP_CALL(local_flush_tlb_mm), (unsigned long) mm);
if(mm->count == 1 && current->mm == mm)
if(atomic_read(&mm->count) == 1 && current->mm == mm)
mm->cpu_vm_mask = (1 << smp_processor_id());
}
}
......@@ -275,3 +275,26 @@ int setup_profiling_timer(unsigned int multiplier)
return 0;
}
int smp_bogo_info(char *buf)
{
int len = 0, i;
for (i = 0; i < NR_CPUS; i++)
if (cpu_present_map & (1 << i))
len += sprintf(buf + len, "Cpu%dBogo\t: %lu.%02lu\n",
i,
cpu_data[i].udelay_val/500000,
(cpu_data[i].udelay_val/5000)%100);
return len;
}
int smp_info(char *buf)
{
int len = 0, i;
for (i = 0; i < NR_CPUS; i++)
if (cpu_present_map & (1 << i))
len += sprintf(buf + len, "CPU%d\t\t: online\n", i);
return len;
}
/* $Id: sparc_ksyms.c,v 1.65 1998/06/04 09:54:50 jj Exp $
/* $Id: sparc_ksyms.c,v 1.70 1998/09/17 11:04:55 jj Exp $
* arch/sparc/kernel/ksyms.c: Sparc specific ksyms support.
*
* Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
......@@ -85,11 +85,6 @@ __attribute__((section("__ksymtab"))) = \
/* used by various drivers */
EXPORT_SYMBOL(sparc_cpu_model);
#ifdef __SMP__
EXPORT_SYMBOL(klock_info);
#endif
EXPORT_SYMBOL_PRIVATE(_lock_kernel);
EXPORT_SYMBOL_PRIVATE(_unlock_kernel);
EXPORT_SYMBOL_PRIVATE(_spinlock_waitfor);
#ifdef SPIN_LOCK_DEBUG
EXPORT_SYMBOL(_spin_lock);
......@@ -119,14 +114,10 @@ EXPORT_SYMBOL_PRIVATE(_rw_write_enter);
EXPORT_SYMBOL(__sparc_bh_counter);
#ifdef __SMP__
#ifdef DEBUG_IRQLOCK
EXPORT_SYMBOL(irq_enter);
EXPORT_SYMBOL(irq_exit);
EXPORT_SYMBOL(__global_restore_flags);
EXPORT_SYMBOL(__global_sti);
EXPORT_SYMBOL(__global_cli);
#else
EXPORT_SYMBOL_PRIVATE(_irq_enter);
EXPORT_SYMBOL_PRIVATE(_irq_exit);
EXPORT_SYMBOL_PRIVATE(_global_restore_flags);
EXPORT_SYMBOL_PRIVATE(_global_sti);
EXPORT_SYMBOL_PRIVATE(_global_cli);
......@@ -134,7 +125,10 @@ EXPORT_SYMBOL_PRIVATE(_global_cli);
#endif
EXPORT_SYMBOL(page_offset);
#ifndef CONFIG_SUN4
EXPORT_SYMBOL(stack_top);
#endif
/* Atomic operations. */
EXPORT_SYMBOL_PRIVATE(_atomic_add);
......@@ -227,7 +221,7 @@ EXPORT_SYMBOL(__prom_getsibling);
/* sparc library symbols */
EXPORT_SYMBOL(bcopy);
EXPORT_SYMBOL(memscan);
EXPORT_SYMBOL_NOVERS(memscan);
EXPORT_SYMBOL(strlen);
EXPORT_SYMBOL(strnlen);
EXPORT_SYMBOL(strcpy);
......@@ -235,7 +229,7 @@ EXPORT_SYMBOL(strncpy);
EXPORT_SYMBOL(strcat);
EXPORT_SYMBOL(strncat);
EXPORT_SYMBOL(strcmp);
EXPORT_SYMBOL(strncmp);
EXPORT_SYMBOL_NOVERS(strncmp);
EXPORT_SYMBOL(strchr);
EXPORT_SYMBOL(strrchr);
EXPORT_SYMBOL(strpbrk);
......
......@@ -121,7 +121,7 @@ static void sun4c_clear_clock_irq(void)
{
volatile unsigned int clear_intr;
#ifdef CONFIG_SUN4
if( idprom->id_machtype == SM_SUN4 | SM_4_260 )
if (idprom->id_machtype == (SM_SUN4 | SM_4_260))
clear_intr = sun4_timer.timer_limit10;
else
#endif
......@@ -146,7 +146,7 @@ __initfunc(static void sun4c_init_timers(void (*counter_fn)(int, void *, struct
* the cache chip on the sun4c.
*/
#ifdef CONFIG_SUN4
if (idprom->id_machtype == SM_SUN4 | SM_4_260)
if (idprom->id_machtype == (SM_SUN4 | SM_4_260))
sun4c_timers = &sun4_timer;
else
#endif
......@@ -171,7 +171,10 @@ __initfunc(static void sun4c_init_timers(void (*counter_fn)(int, void *, struct
prom_halt();
}
#if 0
/* This does not work on 4/330 */
sun4c_enable_irq(10);
#endif
claim_ticker14(NULL, PROFILE_IRQ, 0);
}
......
/* $Id: sun4d_irq.c,v 1.14 1998/06/04 09:54:47 jj Exp $
/* $Id: sun4d_irq.c,v 1.15 1998/09/29 09:46:12 davem Exp $
* arch/sparc/kernel/sun4d_irq.c:
* SS1000/SC2000 interrupt handling.
*
......@@ -284,11 +284,12 @@ int sun4d_request_irq(unsigned int irq,
/* If this is flagged as statically allocated then we use our
* private struct which is never freed.
*/
if (irqflags & SA_STATIC_ALLOC)
if (irqflags & SA_STATIC_ALLOC) {
if (static_irq_count < MAX_STATIC_ALLOC)
action = &static_irqaction[static_irq_count++];
else
printk("Request for IRQ%d (%s) SA_STATIC_ALLOC failed using kmalloc\n",irq, devname);
}
if (action == NULL)
action = (struct irqaction *)kmalloc(sizeof(struct irqaction),
......
......@@ -57,7 +57,6 @@ extern unsigned char boot_cpu_id;
extern int smp_activated;
extern volatile int cpu_number_map[NR_CPUS];
extern volatile int __cpu_logical_map[NR_CPUS];
extern struct klock_info klock_info;
extern volatile unsigned long ipi_count;
extern volatile int smp_process_available;
extern volatile int smp_commenced;
......@@ -71,31 +70,6 @@ extern int __smp4d_processor_id(void);
#define SMP_PRINTK(x)
#endif
int smp4d_bogo_info(char *buf)
{
int len = 0, i;
for (i = 0; i < NR_CPUS; i++)
if (cpu_present_map & (1 << i))
len += sprintf(buf + len, "Cpu%dBogo\t: %lu.%02lu\n",
i,
cpu_data[i].udelay_val/500000,
(cpu_data[i].udelay_val/5000)%100);
return len;
}
int smp4d_info(char *buf)
{
int len = 0, i;
for (i = 0; i < NR_CPUS; i++)
if (cpu_present_map & (1 << i))
len += sprintf(buf + len, "CPU%d\t\t: %s\n",
i,
(klock_info.akp == i) ? "akp" : "online");
return len;
}
static inline unsigned long swap(volatile unsigned long *ptr, unsigned long val)
{
__asm__ __volatile__("swap [%1], %0\n\t" :
......@@ -216,7 +190,6 @@ __initfunc(void smp4d_boot_cpus(void))
mid_xlate[i] = i;
cpu_number_map[boot_cpu_id] = 0;
__cpu_logical_map[0] = boot_cpu_id;
klock_info.akp = boot_cpu_id;
current->processor = boot_cpu_id;
smp_store_cpu_info(boot_cpu_id);
smp_setup_percpu_timer();
......@@ -436,6 +409,8 @@ void smp4d_message_pass(int target, int msg, unsigned long data, int wait)
/* Protects counters touched during level14 ticker */
static spinlock_t ticker_lock = SPIN_LOCK_UNLOCKED;
#ifdef CONFIG_PROFILE
/* 32-bit Sparc specific profiling function. */
static inline void sparc_do_profile(unsigned long pc)
{
......@@ -454,6 +429,8 @@ static inline void sparc_do_profile(unsigned long pc)
}
}
#endif
extern unsigned int prof_multiplier[NR_CPUS];
extern unsigned int prof_counter[NR_CPUS];
......@@ -479,9 +456,10 @@ void smp4d_percpu_timer_interrupt(struct pt_regs *regs)
show_leds(cpu);
}
#ifdef CONFIG_PROFILE
if(!user_mode(regs))
sparc_do_profile(regs->pc);
#endif
if(!--prof_counter[cpu]) {
int user = user_mode(regs);
if(current->pid) {
......@@ -559,8 +537,6 @@ __initfunc(void sun4d_init_smp(void))
BTFIXUPSET_BLACKBOX(load_current, smp4d_blackbox_current);
BTFIXUPSET_CALL(smp_cross_call, smp4d_cross_call, BTFIXUPCALL_NORM);
BTFIXUPSET_CALL(smp_message_pass, smp4d_message_pass, BTFIXUPCALL_NORM);
BTFIXUPSET_CALL(smp_bogo_info, smp4d_bogo_info, BTFIXUPCALL_NORM);
BTFIXUPSET_CALL(smp_info, smp4d_info, BTFIXUPCALL_NORM);
BTFIXUPSET_CALL(__smp_processor_id, __smp4d_processor_id, BTFIXUPCALL_NORM);
for (i = 0; i < NR_CPUS; i++) {
......
......@@ -47,10 +47,12 @@ unsigned long *irq_rcvreg = &dummy;
*
* take an encoded intr value and lookup if it's valid
* then get the mask bits that match from irq_mask
*
* P3: Translation from irq 0x0d to mask 0x2000 is for MrCoffee.
*/
static unsigned char irq_xlate[32] = {
/* 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, a, b, c, d, e, f */
0, 0, 0, 0, 1, 0, 2, 0, 3, 0, 4, 5, 6, 0, 0, 7,
0, 0, 0, 0, 1, 0, 2, 0, 3, 0, 4, 5, 6, 14, 0, 7,
0, 0, 8, 9, 0, 10, 0, 11, 0, 12, 0, 13, 0, 14, 0, 0
};
......
......@@ -53,7 +53,6 @@ extern unsigned char boot_cpu_id;
extern int smp_activated;
extern volatile int cpu_number_map[NR_CPUS];
extern volatile int __cpu_logical_map[NR_CPUS];
extern struct klock_info klock_info;
extern volatile unsigned long ipi_count;
extern volatile int smp_process_available;
extern volatile int smp_commenced;
......@@ -67,30 +66,6 @@ extern int __smp4m_processor_id(void);
#define SMP_PRINTK(x)
#endif
int smp4m_bogo_info(char *buf)
{
return sprintf(buf,
"Cpu0Bogo\t: %lu.%02lu\n"
"Cpu1Bogo\t: %lu.%02lu\n"
"Cpu2Bogo\t: %lu.%02lu\n"
"Cpu3Bogo\t: %lu.%02lu\n",
cpu_data[0].udelay_val/500000, (cpu_data[0].udelay_val/5000)%100,
cpu_data[1].udelay_val/500000, (cpu_data[1].udelay_val/5000)%100,
cpu_data[2].udelay_val/500000, (cpu_data[2].udelay_val/5000)%100,
cpu_data[3].udelay_val/500000, (cpu_data[3].udelay_val/5000)%100);
}
int smp4m_info(char *buf)
{
return sprintf(buf,
" CPU0\t\tCPU1\t\tCPU2\t\tCPU3\n"
"State: %s\t\t%s\t\t%s\t\t%s\n",
(cpu_present_map & 1) ? ((klock_info.akp == 0) ? "akp" : "online") : "offline",
(cpu_present_map & 2) ? ((klock_info.akp == 1) ? "akp" : "online") : "offline",
(cpu_present_map & 4) ? ((klock_info.akp == 2) ? "akp" : "online") : "offline",
(cpu_present_map & 8) ? ((klock_info.akp == 3) ? "akp" : "online") : "offline");
}
static inline unsigned long swap(volatile unsigned long *ptr, unsigned long val)
{
__asm__ __volatile__("swap [%1], %0\n\t" :
......@@ -186,7 +161,6 @@ __initfunc(void smp4m_boot_cpus(void))
mid_xlate[boot_cpu_id] = (linux_cpus[boot_cpu_id].mid & ~8);
cpu_number_map[boot_cpu_id] = 0;
__cpu_logical_map[0] = boot_cpu_id;
klock_info.akp = boot_cpu_id;
current->processor = boot_cpu_id;
smp_store_cpu_info(boot_cpu_id);
set_irq_udt(mid_xlate[boot_cpu_id]);
......@@ -468,6 +442,7 @@ void smp4m_percpu_timer_interrupt(struct pt_regs *regs)
if(!--prof_counter[cpu]) {
int user = user_mode(regs);
if(current->pid) {
update_one_process(current, 1, user, !user, cpu);
......@@ -534,7 +509,5 @@ __initfunc(void sun4m_init_smp(void))
BTFIXUPSET_BLACKBOX(load_current, smp4m_blackbox_current);
BTFIXUPSET_CALL(smp_cross_call, smp4m_cross_call, BTFIXUPCALL_NORM);
BTFIXUPSET_CALL(smp_message_pass, smp4m_message_pass, BTFIXUPCALL_NORM);
BTFIXUPSET_CALL(smp_bogo_info, smp4m_bogo_info, BTFIXUPCALL_NORM);
BTFIXUPSET_CALL(smp_info, smp4m_info, BTFIXUPCALL_NORM);
BTFIXUPSET_CALL(__smp_processor_id, __smp4m_processor_id, BTFIXUPCALL_NORM);
}
/* $Id: sys_sparc.c,v 1.46 1998/08/03 23:58:01 davem Exp $
/* $Id: sys_sparc.c,v 1.48 1998/09/07 09:19:34 davem Exp $
* linux/arch/sparc/kernel/sys_sparc.c
*
* This file contains various random system calls that
......@@ -206,6 +206,7 @@ asmlinkage unsigned long sys_mmap(unsigned long addr, unsigned long len,
}
}
flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
retval = do_mmap(file, addr, len, prot, flags, off);
out_putf:
......@@ -298,6 +299,11 @@ sys_rt_sigaction(int sig, const struct sigaction *act, struct sigaction *oact,
if (sigsetsize != sizeof(sigset_t))
return -EINVAL;
/* All tasks which use RT signals (effectively) use
* new style signals.
*/
current->tss.new_signal = 1;
if (act) {
new_ka.ka_restorer = restorer;
if (copy_from_user(&new_ka.sa, act, sizeof(*act)))
......
/* $Id: sys_sunos.c,v 1.91 1998/06/16 04:37:04 davem Exp $
/* $Id: sys_sunos.c,v 1.92 1998/08/31 03:40:53 davem Exp $
* sys_sunos.c: SunOS specific syscall compatibility support.
*
* Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
......@@ -118,6 +118,7 @@ asmlinkage unsigned long sunos_mmap(unsigned long addr, unsigned long len,
}
}
flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
retval = do_mmap(file, addr, len, prot, flags, off);
if(!ret_type)
retval = ((retval < PAGE_OFFSET) ? 0 : retval);
......
This diff is collapsed.
/* $Id: time.c,v 1.33 1998/07/28 16:52:48 jj Exp $
/* $Id: time.c,v 1.39 1998/09/29 09:46:15 davem Exp $
* linux/arch/sparc/kernel/time.c
*
* Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
......@@ -7,6 +7,9 @@
* Chris Davis (cdavis@cois.on.ca) 03/27/1998
* Added support for the intersil on the sun4/4200
*
* Gleb Raiko (rajko@mech.math.msu.su) 08/18/1998
* Support for MicroSPARC-IIep, PCI CPU.
*
* This file handles the Sparc specific time handling details.
*/
#include <linux/config.h>
......@@ -19,6 +22,7 @@
#include <linux/interrupt.h>
#include <linux/timex.h>
#include <linux/init.h>
#include <linux/pci.h>
#include <asm/oplib.h>
#include <asm/segment.h>
......@@ -36,6 +40,7 @@ enum sparc_clock_type sp_clock_typ;
struct mostek48t02 *mstk48t02_regs = 0;
struct mostek48t08 *mstk48t08_regs = 0;
static int set_rtc_mmss(unsigned long);
static void sbus_do_settimeofday(struct timeval *tv);
#ifdef CONFIG_SUN4
struct intersil *intersil_clock;
......@@ -71,10 +76,13 @@ void timer_interrupt(int irq, void *dev_id, struct pt_regs * regs)
static long last_rtc_update=0;
#ifdef CONFIG_SUN4
int temp;
intersil_read_intr(intersil_clock, temp);
/* re-enable the irq */
enable_pil_irq(10);
if((idprom->id_machtype == (SM_SUN4 | SM_4_260)) ||
(idprom->id_machtype == (SM_SUN4 | SM_4_110))) {
int temp;
intersil_read_intr(intersil_clock, temp);
/* re-enable the irq */
enable_pil_irq(10);
}
#endif
clear_clock_irq();
......@@ -83,11 +91,12 @@ void timer_interrupt(int irq, void *dev_id, struct pt_regs * regs)
/* Determine when to update the Mostek clock. */
if (time_state != TIME_BAD && xtime.tv_sec > last_rtc_update + 660 &&
xtime.tv_usec > 500000 - (tick >> 1) &&
xtime.tv_usec < 500000 + (tick >> 1))
xtime.tv_usec < 500000 + (tick >> 1)) {
if (set_rtc_mmss(xtime.tv_sec) == 0)
last_rtc_update = xtime.tv_sec;
else
last_rtc_update = xtime.tv_sec - 600; /* do it again in 60 s */
}
}
/* Converts Gregorian date to seconds since 1970-01-01 00:00:00.
......@@ -316,7 +325,7 @@ static __inline__ void clock_probe(void)
kick_start_clock();
}
__initfunc(void time_init(void))
__initfunc(void sbus_time_init(void))
{
unsigned int year, mon, day, hour, min, sec;
struct mostek48t02 *mregs;
......@@ -327,6 +336,8 @@ __initfunc(void time_init(void))
#endif
do_get_fast_time = do_gettimeofday;
BTFIXUPSET_CALL(bus_do_settimeofday, sbus_do_settimeofday, BTFIXUPCALL_NORM);
btfixup();
#if CONFIG_AP1000
init_timers(timer_interrupt);
......@@ -344,7 +355,6 @@ __initfunc(void time_init(void))
#ifdef CONFIG_SUN4
if(idprom->id_machtype == (SM_SUN4 | SM_4_330)) {
#endif
mregs = mstk48t02_regs;
if(!mregs) {
prom_printf("Something wrong, clock regs not mapped yet.\n");
......@@ -397,7 +407,19 @@ __initfunc(void time_init(void))
__sti();
}
static __inline__ unsigned long do_gettimeoffset(void)
__initfunc(void time_init(void))
{
#ifdef CONFIG_PCI
extern void pci_time_init(void);
if (pci_present()) {
pci_time_init();
return;
}
#endif
sbus_time_init();
}
extern __inline__ unsigned long do_gettimeoffset(void)
{
unsigned long offset = 0;
unsigned int count;
......@@ -458,6 +480,11 @@ void do_gettimeofday(struct timeval *tv)
}
void do_settimeofday(struct timeval *tv)
{
bus_do_settimeofday(tv);
}
static void sbus_do_settimeofday(struct timeval *tv)
{
cli();
#if !CONFIG_AP1000
......
/* $Id: traps.c,v 1.56 1998/04/06 16:08:32 jj Exp $
/* $Id: traps.c,v 1.57 1998/09/17 11:04:51 jj Exp $
* arch/sparc/kernel/traps.c
*
* Copyright 1995 David S. Miller (davem@caip.rutgers.edu)
......@@ -242,8 +242,8 @@ extern int do_mathemu(struct pt_regs *, struct task_struct *);
void do_fpe_trap(struct pt_regs *regs, unsigned long pc, unsigned long npc,
unsigned long psr)
{
static calls = 0;
int ret;
static int calls = 0;
int ret = 0;
#ifndef __SMP__
struct task_struct *fpt = last_task_used_math;
#else
......
......@@ -3,7 +3,7 @@
* Copyright(C) 1995 Linus Torvalds
* Copyright(C) 1996 David S. Miller
* Copyright(C) 1996 Eddie C. Dost
* Copyright(C) 1996 Jakub Jelinek
* Copyright(C) 1996,1998 Jakub Jelinek
*
* derived from:
* e-mail between David and Eddie.
......@@ -13,13 +13,14 @@
#include <asm/cprefix.h>
#include <asm/ptrace.h>
#include <asm/asmmacro.h>
#define EX(x,y,a,b,z) \
98: x,y; \
.section .fixup,z##alloc,z##execinstr; \
.align 4; \
99: retl; \
a, b, %o0; \
99: ba fixupretl; \
a, b, %g3; \
.section __ex_table,z##alloc; \
.align 4; \
.word 98b, 99b; \
......@@ -31,8 +32,8 @@
.section .fixup,z##alloc,z##execinstr; \
.align 4; \
99: c, d, e; \
retl; \
a, b, %o0; \
ba fixupretl; \
a, b, %g3; \
.section __ex_table,z##alloc; \
.align 4; \
.word 98b, 99b; \
......@@ -340,7 +341,7 @@ short_aligned_end:
andcc %o2, 4, %g0
EXO2(ld [%o1 + 0x00], %g2,#)
EX(ld [%o1 + 0x04], %g3, sub %o2, 4,#)
EXO2(ld [%o1 + 0x04], %g3,#)
add %o1, 8, %o1
EXO2(st %g2, [%o0 + 0x00],#)
EX(st %g3, [%o0 + 0x04], sub %o2, 4,#)
......@@ -352,16 +353,32 @@ short_aligned_end:
.section .fixup,#alloc,#execinstr
.align 4
97:
retl
mov %o2, %o0
mov %o2, %g3
fixupretl:
GET_PAGE_OFFSET(g1)
cmp %o0, %g1
blu 1f
cmp %o1, %g1
bgeu 1f
nop
save %sp, -64, %sp
mov %i0, %o0
call __bzero
mov %g3, %o1
restore
1: retl
mov %g3, %o0
/* exception routine sets %g2 to (broken_insn - first_insn)>>2 */
50:
/* This magic counts how many bytes are left when crash in MOVE_BIGCHUNK
* happens. This is derived from the amount ldd reads, st stores, etc.
* x = g2 % 12;
* o0 = g1 + g7 - ((g2 / 12) * 32 + (x < 4) ? x * 8 : (x - 4) * 4)
* g3 = g1 + g7 - ((g2 / 12) * 32 + (x < 4) ? 0 : (x - 4) * 4);
* o0 += (g2 / 12) * 32;
*/
cmp %g2, 12
add %o0, %g7, %o0
bcs 1f
cmp %g2, 24
bcs 2f
......@@ -370,84 +387,97 @@ short_aligned_end:
nop
sub %g2, 12, %g2
sub %g7, 32, %g7
3:
sub %g2, 12, %g2
3: sub %g2, 12, %g2
sub %g7, 32, %g7
2:
sub %g2, 12, %g2
2: sub %g2, 12, %g2
sub %g7, 32, %g7
1:
cmp %g2, 4
bcs,a 1f
sll %g2, 3, %g2
1: cmp %g2, 4
bcs,a 60f
clr %g2
sub %g2, 4, %g2
sll %g2, 2, %g2
1:
and %g1, 0x7f, %o0
add %o0, %g7, %o0
retl
sub %o0, %g2, %o0
60: and %g1, 0x7f, %g3
sub %o0, %g7, %o0
add %g3, %g7, %g3
ba fixupretl
sub %g3, %g2, %g3
51:
/* i = 41 - g2; j = i % 6;
* o0 = (g1 & 15) + (i / 6) * 16 + (j < 4) ? (j + 1) * 4 : (j - 3) * 8;
* g3 = (g1 & 15) + (i / 6) * 16 + (j < 4) ? (j + 1) * 4 : 16;
* o0 -= (i / 6) * 16 + 16;
*/
neg %g2
and %g1, 0xf, %g1
add %g2, 41, %g2
1:
cmp %g2, 6
add %o0, %g1, %o0
1: cmp %g2, 6
bcs,a 2f
cmp %g2, 4
add %g1, 16, %g1
b 1b
sub %g2, 6, %g2
2:
bcs,a 3f
inc %g2
sub %g2, 3, %g2
b 2f
sll %g2, 3, %g2
3:
2: bcc,a 2f
mov 16, %g2
inc %g2
sll %g2, 2, %g2
2:
retl
add %g1, %g2, %o0
2: add %g1, %g2, %g3
ba fixupretl
sub %o0, %g3, %o0
52:
/* o0 = g1 + g7 - (g2 / 8) * 32 + (x & 3) * 8 */
and %g2, 0xfffffff8, %g4
/* g3 = g1 + g7 - (g2 / 8) * 32 + (g2 & 4) ? (g2 & 3) * 8 : 0;
o0 += (g2 / 8) * 32 */
andn %g2, 7, %g4
add %o0, %g7, %o0
andcc %g2, 4, %g0
and %g2, 3, %g2
sll %g4, 2, %g4
sll %g2, 3, %g2
add %g2, %g4, %g2
b,a 1b
bne 60b
sub %g7, %g4, %g7
ba 60b
clr %g2
53:
/* o0 = o3 + (o2 & 15) - (g2 & 8) - (g2 & 3) * 2 */
/* g3 = o3 + (o2 & 15) - (g2 & 8) - (g2 & 4) ? (g2 & 3) * 2 : 0;
o0 += (g2 & 8) */
and %g2, 3, %g4
and %g2, 0xfffffff8, %g2
andcc %g2, 4, %g0
and %g2, 8, %g2
sll %g4, 1, %g4
be 1f
add %o0, %g2, %o0
add %g2, %g4, %g2
and %o2, 0xf, %o0
add %o0, %o3, %o0
retl
sub %o0, %g2, %o0
1: and %o2, 0xf, %g3
add %g3, %o3, %g3
ba fixupretl
sub %g3, %g2, %g3
54:
/* o0 = o3 + (o2 & 15) - (g2 / 4) * 2 - (g2 & 1) */
/* g3 = o3 + (o2 & 15) - (g2 / 4) * 2 - (g2 & 2) ? (g2 & 1) : 0;
o0 += (g2 / 4) * 2 */
srl %g2, 2, %o4
and %g2, 1, %o1
sll %o4, 1, %o4
and %g2, 1, %o5
srl %g2, 1, %g2
add %o4, %o4, %o4
and %o5, %g2, %o5
and %o2, 0xf, %o2
sub %o3, %o1, %o3
add %o0, %o4, %o0
sub %o3, %o5, %o3
sub %o2, %o4, %o2
retl
add %o2, %o3, %o0
ba fixupretl
add %o2, %o3, %g3
55:
/* o0 = (o2 & 1) + (27 - g2)/4 * 2 + ((27 - g2) & 1) */
/* i = 27 - g2;
g3 = (o2 & 1) + i / 4 * 2 + !(i & 3);
o0 -= i / 4 * 2 + 1 */
neg %g2
and %o2, 1, %o2
add %g2, 27, %g2
srl %g2, 2, %o1
and %g2, 1, %g2
sll %o1, 1, %o1
add %o2, %g2, %o0
retl
add %o0, %o1, %o0
srl %g2, 2, %o5
andcc %g2, 3, %g0
mov 1, %g2
add %o5, %o5, %o5
be,a 1f
clr %g2
1: add %g2, %o5, %g3
sub %o0, %g3, %o0
ba fixupretl
add %g3, %o2, %g3
This diff is collapsed.
# $Id: Makefile,v 1.31 1998/07/26 03:02:45 davem Exp $
# $Id: Makefile,v 1.32 1998/08/16 16:02:25 ecd Exp $
# Makefile for the linux Sparc-specific parts of the memory manager.
#
# Note! Dependencies are done automagically by 'make dep', which also
......@@ -12,7 +12,7 @@ O_OBJS := fault.o init.o loadmmu.o generic.o asyncd.o extable.o btfixup.o
ifeq ($(CONFIG_SUN4),y)
O_OBJS += nosrmmu.o
else
O_OBJS += srmmu.o iommu.o io-unit.o hypersparc.o viking.o tsunami.o turbosparc.o
O_OBJS += srmmu.o iommu.o io-unit.o hypersparc.o viking.o tsunami.o
endif
ifdef SMP
O_OBJS += nosun4c.o
......@@ -25,9 +25,6 @@ include $(TOPDIR)/Rules.make
hypersparc.o: hypersparc.S
$(CC) -D__ASSEMBLY__ $(AFLAGS) -ansi -c -o hypersparc.o hypersparc.S
turbosparc.o: turbosparc.S
$(CC) -D__ASSEMBLY__ $(AFLAGS) -ansi -c -o turbosparc.o turbosparc.S
viking.o: viking.S
$(CC) -D__ASSEMBLY__ $(AFLAGS) -ansi -c -o viking.o viking.S
......
/* $Id: asyncd.c,v 1.11 1997/12/14 23:24:34 ecd Exp $
/* $Id: asyncd.c,v 1.12 1998/09/13 04:30:30 davem Exp $
* The asyncd kernel daemon. This handles paging on behalf of
* processes that receive page faults due to remote (async) memory
* accesses.
......
/* $Id: fault.c,v 1.94 1998/05/01 16:00:27 jj Exp $
/* $Id: fault.c,v 1.95 1998/09/18 19:50:32 davem Exp $
* fault.c: Page fault handlers for the Sparc.
*
* Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
......@@ -149,7 +149,9 @@ static void unhandled_fault(unsigned long address, struct task_struct *tsk,
(unsigned long) tsk->mm->context);
printk(KERN_ALERT "tsk->mm->pgd = %08lx\n",
(unsigned long) tsk->mm->pgd);
lock_kernel();
die_if_kernel("Oops", regs);
unlock_kernel();
}
asmlinkage int lookup_fault(unsigned long pc, unsigned long ret_pc,
......@@ -196,11 +198,11 @@ asmlinkage void do_sparc_fault(struct pt_regs *regs, int text_fault, int write,
unsigned int fixup;
unsigned long g2;
int from_user = !(regs->psr & PSR_PS);
lock_kernel();
down(&mm->mmap_sem);
if(text_fault)
address = regs->pc;
down(&mm->mmap_sem);
/* The kernel referencing a bad kernel pointer can lock up
* a sun4c machine completely, so we must attempt recovery.
*/
......@@ -231,7 +233,7 @@ asmlinkage void do_sparc_fault(struct pt_regs *regs, int text_fault, int write,
}
handle_mm_fault(current, vma, address, write);
up(&mm->mmap_sem);
goto out;
return;
/*
* Something tried to access memory that isn't in our memory map..
* Fix it, but check if it's kernel or user first..
......@@ -263,7 +265,7 @@ asmlinkage void do_sparc_fault(struct pt_regs *regs, int text_fault, int write,
regs->u_regs[UREG_G2] = g2;
regs->pc = fixup;
regs->npc = regs->pc + 4;
goto out;
return;
}
}
if(from_user) {
......@@ -274,11 +276,9 @@ asmlinkage void do_sparc_fault(struct pt_regs *regs, int text_fault, int write,
tsk->tss.sig_address = address;
tsk->tss.sig_desc = SUBSIG_NOMAPPING;
force_sig(SIGSEGV, tsk);
goto out;
return;
}
unhandled_fault (address, tsk, regs);
out:
unlock_kernel();
}
asmlinkage void do_sun4c_fault(struct pt_regs *regs, int text_fault, int write,
......
/* $Id: init.c,v 1.59 1998/03/27 06:59:57 davem Exp $
/* $Id: init.c,v 1.60 1998/09/13 04:30:31 davem Exp $
* linux/arch/sparc/mm/init.c
*
* Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
......
/* $Id: srmmu.c,v 1.173 1998/08/04 20:48:57 davem Exp $
/* $Id: srmmu.c,v 1.175 1998/08/28 18:57:31 zaitcev Exp $
* srmmu.c: SRMMU specific routines for memory management.
*
* Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
......@@ -1997,7 +1997,7 @@ static void srmmu_update_mmu_cache(struct vm_area_struct * vma, unsigned long ad
static void srmmu_destroy_context(struct mm_struct *mm)
{
if(mm->context != NO_CONTEXT && mm->count == 1) {
if(mm->context != NO_CONTEXT && atomic_read(&mm->count) == 1) {
flush_cache_mm(mm);
ctxd_set(&srmmu_context_table[mm->context], swapper_pg_dir);
flush_tlb_mm(mm);
......@@ -2071,7 +2071,7 @@ static void srmmu_vac_update_mmu_cache(struct vm_area_struct * vma,
static void hypersparc_destroy_context(struct mm_struct *mm)
{
if(mm->context != NO_CONTEXT && mm->count == 1) {
if(mm->context != NO_CONTEXT && atomic_read(&mm->count) == 1) {
ctxd_t *ctxp;
/* HyperSparc is copy-back, any data for this
......@@ -2399,10 +2399,93 @@ __initfunc(static void init_swift(void))
poke_srmmu = poke_swift;
}
/* turbosparc.S */
extern void turbosparc_flush_cache_all(void);
extern void turbosparc_flush_sig_insns(struct mm_struct *mm, unsigned long insn_addr);
extern void turbosparc_flush_page_for_dma(unsigned long page);
static void turbosparc_flush_cache_all(void)
{
flush_user_windows();
turbosparc_idflash_clear();
}
static void turbosparc_flush_cache_mm(struct mm_struct *mm)
{
FLUSH_BEGIN(mm)
flush_user_windows();
turbosparc_idflash_clear();
FLUSH_END
}
static void turbosparc_flush_cache_range(struct mm_struct *mm, unsigned long start, unsigned long end)
{
FLUSH_BEGIN(mm)
flush_user_windows();
turbosparc_idflash_clear();
FLUSH_END
}
static void turbosparc_flush_cache_page(struct vm_area_struct *vma, unsigned long page)
{
FLUSH_BEGIN(vma->vm_mm)
flush_user_windows();
if (vma->vm_flags & VM_EXEC)
turbosparc_flush_icache();
turbosparc_flush_dcache();
FLUSH_END
}
/* TurboSparc is copy-back, if we turn it on, but this does not work. */
static void turbosparc_flush_page_to_ram(unsigned long page)
{
#ifdef TURBOSPARC_WRITEBACK
volatile unsigned long clear;
if (srmmu_hwprobe(page))
turbosparc_flush_page_cache(page);
clear = srmmu_get_fstatus();
#endif
}
static void turbosparc_flush_sig_insns(struct mm_struct *mm, unsigned long insn_addr)
{
}
static void turbosparc_flush_page_for_dma(unsigned long page)
{
turbosparc_flush_dcache();
}
static void turbosparc_flush_chunk(unsigned long chunk)
{
}
static void turbosparc_flush_tlb_all(void)
{
srmmu_flush_whole_tlb();
module_stats.invall++;
}
static void turbosparc_flush_tlb_mm(struct mm_struct *mm)
{
FLUSH_BEGIN(mm)
srmmu_flush_whole_tlb();
module_stats.invmm++;
FLUSH_END
}
static void turbosparc_flush_tlb_range(struct mm_struct *mm, unsigned long start, unsigned long end)
{
FLUSH_BEGIN(mm)
srmmu_flush_whole_tlb();
module_stats.invrnge++;
FLUSH_END
}
static void turbosparc_flush_tlb_page(struct vm_area_struct *vma, unsigned long page)
{
FLUSH_BEGIN(vma->vm_mm)
srmmu_flush_whole_tlb();
module_stats.invpg++;
FLUSH_END
}
__initfunc(static void poke_turbosparc(void))
{
......@@ -2420,7 +2503,7 @@ __initfunc(static void poke_turbosparc(void))
#ifdef TURBOSPARC_WRITEBACK
ccreg |= (TURBOSPARC_SNENABLE); /* Do DVMA snooping in Dcache */
ccreg &= ~(TURBOSPARC_uS2 | TURBOSPARC_WTENABLE);
/* Write-back D-cache, emulate VLSI
/* Write-back D-cache, emulate VLSI
* abortion number three, not number one */
#else
/* For now let's play safe, optimize later */
......@@ -2428,7 +2511,8 @@ __initfunc(static void poke_turbosparc(void))
/* Do DVMA snooping in Dcache, Write-thru D-cache */
ccreg &= ~(TURBOSPARC_uS2);
/* Emulate VLSI abortion number three, not number one */
#endif
#endif
switch (ccreg & 7) {
case 0: /* No SE cache */
case 7: /* Test mode */
......@@ -2449,22 +2533,17 @@ __initfunc(static void init_turbosparc(void))
srmmu_modtype = TurboSparc;
BTFIXUPSET_CALL(flush_cache_all, turbosparc_flush_cache_all, BTFIXUPCALL_NORM);
BTFIXUPSET_CALL(flush_cache_mm, hypersparc_flush_cache_mm, BTFIXUPCALL_NORM);
BTFIXUPSET_CALL(flush_cache_page, hypersparc_flush_cache_page, BTFIXUPCALL_NORM);
BTFIXUPSET_CALL(flush_cache_range, hypersparc_flush_cache_range, BTFIXUPCALL_NORM);
BTFIXUPSET_CALL(flush_cache_mm, turbosparc_flush_cache_mm, BTFIXUPCALL_NORM);
BTFIXUPSET_CALL(flush_cache_page, turbosparc_flush_cache_page, BTFIXUPCALL_NORM);
BTFIXUPSET_CALL(flush_cache_range, turbosparc_flush_cache_range, BTFIXUPCALL_NORM);
BTFIXUPSET_CALL(flush_tlb_all, hypersparc_flush_tlb_all, BTFIXUPCALL_NORM);
BTFIXUPSET_CALL(flush_tlb_mm, hypersparc_flush_tlb_mm, BTFIXUPCALL_NORM);
BTFIXUPSET_CALL(flush_tlb_page, hypersparc_flush_tlb_page, BTFIXUPCALL_NORM);
BTFIXUPSET_CALL(flush_tlb_range, hypersparc_flush_tlb_range, BTFIXUPCALL_NORM);
BTFIXUPSET_CALL(flush_tlb_all, turbosparc_flush_tlb_all, BTFIXUPCALL_NORM);
BTFIXUPSET_CALL(flush_tlb_mm, turbosparc_flush_tlb_mm, BTFIXUPCALL_NORM);
BTFIXUPSET_CALL(flush_tlb_page, turbosparc_flush_tlb_page, BTFIXUPCALL_NORM);
BTFIXUPSET_CALL(flush_tlb_range, turbosparc_flush_tlb_range, BTFIXUPCALL_NORM);
#ifdef TURBOSPARC_WRITEBACK
BTFIXUPSET_CALL(flush_page_to_ram, hypersparc_flush_page_to_ram, BTFIXUPCALL_NORM);
BTFIXUPSET_CALL(flush_chunk, hypersparc_flush_chunk, BTFIXUPCALL_NORM);
#else
BTFIXUPSET_CALL(flush_page_to_ram, swift_flush_page_to_ram, BTFIXUPCALL_NOP);
BTFIXUPSET_CALL(flush_chunk, swift_flush_chunk, BTFIXUPCALL_NOP);
#endif
BTFIXUPSET_CALL(flush_page_to_ram, turbosparc_flush_page_to_ram, BTFIXUPCALL_NORM);
BTFIXUPSET_CALL(flush_chunk, turbosparc_flush_chunk, BTFIXUPCALL_NORM);
BTFIXUPSET_CALL(flush_sig_insns, turbosparc_flush_sig_insns, BTFIXUPCALL_NOP);
BTFIXUPSET_CALL(flush_page_for_dma, turbosparc_flush_page_for_dma, BTFIXUPCALL_NOP);
......
/* $Id: sun4c.c,v 1.166 1998/08/04 20:49:05 davem Exp $
/* $Id: sun4c.c,v 1.171 1998/09/21 05:05:41 jj Exp $
* sun4c.c: Doing in software what should be done in hardware.
*
* Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
......@@ -400,7 +400,9 @@ void sun4c_complete_all_stores(void)
_unused = sun4c_get_context();
sun4c_set_context(_unused);
#ifdef CONFIG_SUN_AUXIO
_unused = *AUXREG;
#endif
}
/* Bootup utility functions. */
......@@ -622,9 +624,8 @@ __initfunc(static void sun4c_probe_mmu(void))
break;
case (SM_SUN4|SM_4_470):
prom_printf("No support for 4400 yet\n");
prom_halt();
num_segmaps = 1024;
/* should be 1024 segmaps. when it get fixed */
num_segmaps = 256;
num_contexts = 64;
break;
default:
......@@ -755,13 +756,15 @@ static inline void fix_permissions(unsigned long vaddr, unsigned long bits_on,
~bits_off);
}
/* the 4/260 dies real hard on the prom_putsegment line.
not sure why, but it seems to work without it cgd */
static inline void sun4c_init_map_kernelprom(unsigned long kernel_end)
{
unsigned long vaddr;
unsigned char pseg, ctx;
#ifndef CONFIG_SUN4
#ifdef CONFIG_SUN4
/* sun4/110 and 260 have no kadb. */
if((idprom->id_machtype != (SM_SUN4 | SM_4_260)) &&
(idprom->id_machtype != (SM_SUN4 | SM_4_110))) {
#endif
for(vaddr = KADB_DEBUGGER_BEGVM;
vaddr < LINUX_OPPROM_ENDVM;
vaddr += SUN4C_REAL_PGDIR_SIZE) {
......@@ -773,6 +776,8 @@ static inline void sun4c_init_map_kernelprom(unsigned long kernel_end)
fix_permissions(vaddr, _SUN4C_PAGE_PRIV, 0);
}
}
#ifdef CONFIG_SUN4
}
#endif
for(vaddr = KERNBASE; vaddr < kernel_end; vaddr += SUN4C_REAL_PGDIR_SIZE) {
pseg = sun4c_get_segmap(vaddr);
......@@ -2142,7 +2147,7 @@ static void sun4c_destroy_context_hw(struct mm_struct *mm)
{
struct ctx_list *ctx_old;
if(mm->context != NO_CONTEXT && mm->count == 1) {
if(mm->context != NO_CONTEXT && atomic_read(&mm->count) == 1) {
sun4c_demap_context_hw(&sun4c_context_ring[mm->context], mm->context);
ctx_old = ctx_list_pool + mm->context;
remove_from_ctx_list(ctx_old);
......@@ -2205,7 +2210,7 @@ static void sun4c_destroy_context_sw(struct mm_struct *mm)
{
struct ctx_list *ctx_old;
if(mm->context != NO_CONTEXT && mm->count == 1) {
if(mm->context != NO_CONTEXT && atomic_read(&mm->count) == 1) {
sun4c_demap_context_sw(&sun4c_context_ring[mm->context], mm->context);
ctx_old = ctx_list_pool + mm->context;
remove_from_ctx_list(ctx_old);
......
/* $Id: turbosparc.S,v 1.3 1998/02/05 14:19:04 jj Exp $
* turbosparc.S: High speed TurboSparc mmu/cache operations.
*
* Copyright (C) 1997 David S. Miller (davem@caip.rutgers.edu)
* Copyright (C) 1997 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
*/
#include <asm/ptrace.h>
#include <asm/psr.h>
#include <asm/asi.h>
#include <asm/page.h>
#include <asm/pgtsrmmu.h>
#define WINDOW_FLUSH(tmp1, tmp2) \
mov 0, tmp1; \
98: ld [%g6 + AOFF_task_tss + AOFF_thread_uwinmask], tmp2; \
orcc %g0, tmp2, %g0; \
add tmp1, 1, tmp1; \
bne 98b; \
save %sp, -64, %sp; \
99: subcc tmp1, 1, tmp1; \
bne 99b; \
restore %g0, %g0, %g0;
.text
.align 4
.globl turbosparc_flush_cache_all
.globl turbosparc_flush_sig_insns
.globl turbosparc_flush_page_for_dma
turbosparc_flush_cache_all:
WINDOW_FLUSH(%g4, %g5)
sethi %hi(vac_cache_size), %g4
ld [%g4 + %lo(vac_cache_size)], %g5
sethi %hi(vac_line_size), %g1
ld [%g1 + %lo(vac_line_size)], %g2
1:
subcc %g5, %g2, %g5
bne 1b
sta %g0, [%g5] ASI_M_DATAC_TAG
retl
sta %g0, [%g0] ASI_M_IC_FLCLEAR
turbosparc_flush_sig_insns:
turbosparc_flush_page_for_dma:
retl
nop
/* $Id: console.c,v 1.17 1998/03/09 14:04:21 jj Exp $
/* $Id: console.c,v 1.20 1998/09/21 05:05:50 jj Exp $
* console.c: Routines that deal with sending and receiving IO
* to/from the current console device using the PROM.
*
* Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
* Copyright (C) 1998 Pete Zaitcev <zaitcev@metabyte.com>
*/
#include <linux/config.h>
......@@ -17,6 +18,9 @@
extern void restore_current(void);
static char con_name_jmc[] = "/obio/su@"; /* "/obio/su@0,3002f8"; */
#define CON_SIZE_JMC (sizeof(con_name_jmc))
/* Non blocking get character from console input device, returns -1
* if no input was taken. This can be used for polling.
*/
......@@ -83,7 +87,6 @@ prom_nbputchar(char c)
i = 0;
}
#endif
break;
default:
i = -1;
......@@ -139,9 +142,14 @@ prom_query_input_device()
restore_flags(flags);
if(prom_node_has_property(st_p, "keyboard"))
return PROMDEV_IKBD;
prom_getproperty(st_p, "device_type", propb, sizeof(propb));
if (prom_getproperty(st_p, "name", propb, sizeof(propb)) != -1) {
if(strncmp(propb, "keyboard", sizeof("serial")) == 0)
return PROMDEV_IKBD;
}
if (prom_getproperty(st_p, "device_type", propb, sizeof(propb)) != -1) {
if(strncmp(propb, "serial", sizeof("serial")))
return PROMDEV_I_UNK;
}
prom_getproperty(prom_root_node, "stdin-path", propb, sizeof(propb));
p = propb;
while(*p) p++; p -= 2;
......@@ -154,7 +162,7 @@ prom_query_input_device()
return PROMDEV_I_UNK;
case PROM_AP1000:
return PROMDEV_I_UNK;
};
}
}
/* Query for output device type */
......@@ -190,9 +198,12 @@ prom_query_output_device()
return PROMDEV_OSCREEN;
}
if(prom_vers == PROM_V3) {
if(strncmp("serial", propb, sizeof("serial")))
if(propl >= 0 &&
strncmp("serial", propb, sizeof("serial")) != 0)
return PROMDEV_O_UNK;
prom_getproperty(prom_root_node, "stdout-path", propb, sizeof(propb));
if(strncmp(propb, con_name_jmc, CON_SIZE_JMC) == 0)
return PROMDEV_OTTYA;
p = propb;
while(*p) p++; p -= 2;
if(p[0]==':') {
......@@ -201,9 +212,7 @@ prom_query_output_device()
else if(p[1] == 'b')
return PROMDEV_OTTYB;
}
return PROMDEV_O_UNK;
} else {
/* This works on SS-2 (an early OpenFirmware) still. */
switch(*romvec->pv_stdin) {
case PROMDEV_TTYA: return PROMDEV_OTTYA;
case PROMDEV_TTYB: return PROMDEV_OTTYB;
......@@ -212,7 +221,6 @@ prom_query_output_device()
break;
case PROM_AP1000:
default:
return PROMDEV_I_UNK;
};
}
return PROMDEV_O_UNK;
}
/* $Id: tree.c,v 1.24 1998/03/09 14:04:29 jj Exp $
/* $Id: tree.c,v 1.25 1998/09/17 11:04:58 jj Exp $
* tree.c: Basic device tree traversal/scanning for the Linux
* prom library.
*
......@@ -11,6 +11,7 @@
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/ctype.h>
#include <asm/openprom.h>
#include <asm/oplib.h>
......@@ -257,29 +258,49 @@ char * prom_nextprop(int node, char *oprop, char *buffer)
int prom_finddevice(char *name)
{
int topnd = prom_getchild(prom_root_node);
int srch;
if(name[0] == '/')
name++;
if(sparc_cpu_model == sun4d) {
if(!strcmp(name, "sbus"))
name = "sbi";
if((srch = prom_searchsiblings(topnd, "io-unit")) == 0 ||
(srch = prom_getchild(srch)) == 0 ||
(srch = prom_searchsiblings(srch, name)) == 0) {
prom_printf("%s prom node not found.\n", name);
prom_halt();
}
} else if((srch = prom_searchsiblings(topnd, name)) == 0) {
if((srch = prom_searchsiblings(topnd, "iommu")) == 0 ||
(srch = prom_getchild(srch)) == 0 ||
(srch = prom_searchsiblings(srch, name)) == 0) {
prom_printf("Cannot find node %s\n", name);
prom_halt();
char nbuf[128];
char *s = name, *d;
int node = prom_root_node, node2;
unsigned int which_io, phys_addr;
struct linux_prom_registers reg[PROMREG_MAX];
while (*s++) {
if (!*s) return node; /* path '.../' is legal */
node = prom_getchild(node);
for (d = nbuf; *s != 0 && *s != '@' && *s != '/';)
*d++ = *s++;
*d = 0;
node = prom_searchsiblings(node, nbuf);
if (!node)
return 0;
if (*s == '@') {
if (isxdigit(s[1]) && s[2] == ',') {
which_io = simple_strtoul(s+1, NULL, 16);
phys_addr = simple_strtoul(s+3, &d, 16);
if (d != s + 3 && (!*d || *d == '/')
&& d <= s + 3 + 8) {
node2 = node;
while (node2 && node2 != -1) {
if (prom_getproperty (node2, "reg", (char *)reg, sizeof (reg)) > 0) {
if (which_io == reg[0].which_io && phys_addr == reg[0].phys_addr) {
node = node2;
break;
}
}
node2 = prom_getsibling(node2);
if (!node2 || node2 == -1)
break;
node2 = prom_searchsiblings(prom_getsibling(node2), nbuf);
}
}
}
while (*s != 0 && *s != '/') s++;
}
}
return srch;
return node;
}
int prom_node_has_property(int node, char *prop)
......
......@@ -22,7 +22,9 @@ SECTIONS
.data1 : { *(.data1) }
_edata = .;
PROVIDE (edata = .);
__start___fixup = .;
.fixup : { *(.fixup) }
__stop___fixup = .;
__start___ex_table = .;
__ex_table : { *(__ex_table) }
__stop___ex_table = .;
......
# $Id: Makefile,v 1.27 1998/07/27 07:36:16 davem Exp $
# $Id: Makefile,v 1.29 1998/09/16 12:25:20 jj Exp $
# sparc64/Makefile
#
# Makefile for the architecture dependent flags and dependencies on the
......@@ -12,14 +12,22 @@
SHELL =/bin/bash
CC = sparc64-linux-gcc -D__KERNEL__ -I$(TOPDIR)/include
IS_EGCS := $(shell if $(CC) --version 2>&1 | grep 'egcs' > /dev/null; then echo y; else echo n; fi)
NEW_GAS := $(shell if $(LD) --version 2>&1 | grep 'elf64_sparc' > /dev/null; then echo y; else echo n; fi)
ifneq ($(NEW_GAS),y)
AS = sparc64-linux-as
LD = sparc64-linux-ld
NM = sparc64-linux-nm
AR = sparc64-linux-ar
RANLIB = sparc64-linux-ranlib
else
AS := $(AS) -64
LD := $(LD) -m elf64_sparc
endif
ELFTOAOUT = elftoaout
IS_EGCS := $(shell if $(CC) --version 2>&1 | grep 'egcs' > /dev/null; then echo y; else echo n; fi)
#
# Uncomment the first CFLAGS if you are doing kgdb source level
......@@ -30,7 +38,7 @@ ifneq ($(IS_EGCS),y)
CFLAGS := $(CFLAGS) -pipe -mno-fpu -mtune=ultrasparc -mmedlow \
-ffixed-g4 -fcall-used-g5 -fcall-used-g7 -Wno-sign-compare
else
CFLAGS := $(CFLAGS) -pipe -mno-fpu -mtune=ultrasparc -mcmodel=medlow \
CFLAGS := $(CFLAGS) -m64 -pipe -mno-fpu -mcpu=ultrasparc -mcmodel=medlow \
-ffixed-g4 -fcall-used-g5 -fcall-used-g7 -Wno-sign-compare
endif
......
# $Id: config.in,v 1.55 1998/08/03 15:28:38 davem Exp $
# $Id: config.in,v 1.57 1998/09/17 11:05:14 jj Exp $
# For a description of the syntax of this configuration file,
# see the Configure script.
#
......@@ -51,14 +51,15 @@ else
define_bool CONFIG_SUN_CONSOLE y
define_bool CONFIG_SUN_AUXIO y
define_bool CONFIG_SUN_IO y
define_bool CONFIG_PCI y
define_bool CONFIG_PCI_CONSOLE y
bool 'PCI support' CONFIG_PCI
source drivers/sbus/char/Config.in
source drivers/sbus/audio/Config.in
fi
tristate 'Openprom tree appears in /proc/openprom (EXPERIMENTAL)' CONFIG_SUN_OPENPROMFS
bool 'Backward-compatible /proc/pci' CONFIG_PCI_OLD_PROC
if [ "$CONFIG_PCI" = "y" ]; then
bool 'Backward-compatible /proc/pci' CONFIG_PCI_OLD_PROC
fi
bool 'Networking support' CONFIG_NET
bool 'System V IPC' CONFIG_SYSVIPC
bool 'BSD Process Accounting' CONFIG_BSD_PROCESS_ACCT
......@@ -246,5 +247,5 @@ mainmenu_option next_comment
comment 'Kernel hacking'
bool 'Magic SysRq key' CONFIG_MAGIC_SYSRQ
bool 'ECache flush trap support at ta 0x72' CONFIG_EC_FLUSH_TRAP
#bool 'ECache flush trap support at ta 0x72' CONFIG_EC_FLUSH_TRAP
endmenu
......@@ -55,7 +55,6 @@ CONFIG_SUN_CONSOLE=y
CONFIG_SUN_AUXIO=y
CONFIG_SUN_IO=y
CONFIG_PCI=y
CONFIG_PCI_CONSOLE=y
#
# Misc Linux/SPARC drivers
......@@ -73,6 +72,7 @@ CONFIG_OBP_FLASH=m
# CONFIG_SPARCAUDIO is not set
# CONFIG_SPARCAUDIO_AMD7930 is not set
# CONFIG_SPARCAUDIO_CS4231 is not set
# CONFIG_SPARCAUDIO_DBRI is not set
CONFIG_SUN_OPENPROMFS=m
CONFIG_PCI_OLD_PROC=y
CONFIG_NET=y
......@@ -91,7 +91,7 @@ CONFIG_PARPORT_AX=y
# CONFIG_PARPORT_OTHER is not set
CONFIG_PRINTER=y
CONFIG_PRINTER_READBACK=y
CONFIG_ENVCTRL=y
CONFIG_ENVCTRL=m
#
# Floppy, IDE, and other block devices
......@@ -105,7 +105,7 @@ CONFIG_MD_RAID5=m
CONFIG_BLK_DEV_RAM=y
CONFIG_BLK_DEV_INITRD=y
CONFIG_BLK_DEV_LOOP=m
# CONFIG_BLK_DEV_NBD is not set
CONFIG_BLK_DEV_NBD=m
CONFIG_BLK_DEV_IDE=y
CONFIG_BLK_DEV_IDEDISK=y
CONFIG_BLK_DEV_IDECD=y
......@@ -292,7 +292,8 @@ CONFIG_BSD_DISKLABEL=y
CONFIG_SMD_DISKLABEL=y
CONFIG_SOLARIS_X86_PARTITION=y
# CONFIG_ADFS_FS is not set
# CONFIG_DEVPTS_FS is not set
CONFIG_QNX4FS_FS=m
# CONFIG_QNX4FS_RW is not set
# CONFIG_MAC_PARTITION is not set
CONFIG_NLS=y
......@@ -335,4 +336,3 @@ CONFIG_NLS=y
# Kernel hacking
#
# CONFIG_MAGIC_SYSRQ is not set
# CONFIG_EC_FLUSH_TRAP is not set
# $Id: Makefile,v 1.38 1998/07/26 03:02:47 davem Exp $
# $Id: Makefile,v 1.40 1998/09/17 11:05:03 jj Exp $
# Makefile for the linux kernel.
#
# Note! Dependencies are done automagically by 'make dep', which also
......@@ -20,9 +20,13 @@ O_OBJS := process.o setup.o cpu.o idprom.o \
traps.o devices.o auxio.o ioport.o \
irq.o ptrace.o time.o sys_sparc.o signal.o \
unaligned.o sys_sunos32.o sunos_ioctl32.o \
central.o psycho.o ebus.o
central.o psycho.o
OX_OBJS := sparc64_ksyms.o
ifdef CONFIG_PCI
O_OBJS += ebus.o
endif
ifdef SMP
O_OBJS += smp.o trampoline.o
endif
......@@ -48,6 +52,12 @@ head.o: head.S ttable.S itlb_base.S dtlb_base.S dtlb_backend.S dtlb_prot.S \
#
binfmt_elf32.o: $(TOPDIR)/fs/binfmt_elf.c
ifneq ($(IS_EGCS),y)
CMODEL_CFLAG := -mmedlow
else
CMODEL_CFLAG := -mcmodel=medlow
endif
check_asm: dummy
@echo "/* Automatically generated. Do not edit. */" > asm_offsets.h
@echo "#ifndef __ASM_OFFSETS_H__" >> asm_offsets.h
......@@ -70,7 +80,7 @@ check_asm: dummy
@rm -f tmp.[ci]
#$(CC) -o check_asm check_asm.c
# <hack> Until we can do this natively, a hack has to take place
$(CC) -mmedlow -ffixed-g4 -S -o check_asm.s check_asm.c
$(CC) $(CMODEL_CFLAG) -ffixed-g4 -S -o check_asm.s check_asm.c
$(HOSTCC) -Wa,-Av9a -o check_asm check_asm.s
@rm -f check_asm.s
# </hack>
......@@ -94,7 +104,7 @@ check_asm: dummy
@rm -f tmp.[ci]
#$(CC) -D__SMP__ -o check_asm check_asm.c
# <hack> Until we can do this natively, a hack has to take place
$(CC) -D__SMP__ -mmedlow -ffixed-g4 -S -o check_asm.s check_asm.c
$(CC) -D__SMP__ $(CMODEL_CFLAG) -ffixed-g4 -S -o check_asm.s check_asm.c
$(HOSTCC) -Wa,-Av9a -o check_asm check_asm.s
@rm -f check_asm.s
# </hack>
......
......@@ -91,7 +91,7 @@ do_aout32_core_dump(long signr, struct pt_regs * regs)
# define START_DATA(u) (u.u_tsize)
# define START_STACK(u) ((regs->u_regs[UREG_FP]) & ~(PAGE_SIZE - 1))
if (!current->dumpable || current->mm->count != 1)
if (!current->dumpable || atomic_read(&current->mm->count) != 1)
return 0;
current->dumpable = 0;
......@@ -201,7 +201,8 @@ aout32_core_dump(long signr, struct pt_regs * regs)
* memory and creates the pointer tables from them, and puts their
* addresses on the "stack", returning the new stack pointer value.
*/
#define A(x) ((unsigned long)x)
#define A(__x) ((unsigned long)(__x))
static u32 *create_aout32_tables(char * p, struct linux_binprm * bprm)
{
u32 *argv, *envp;
......
This diff is collapsed.
#!/bin/sh
sed -n -e '/struct[ ]*'$1'_struct[ ]*{/,/};/p' < $2 | sed '/struct[ ]*'$1'_struct[ ]*{/d;/:[0-9]*[ ]*;/d;/^[ ]*$/d;/};/d;s/^[ ]*//;s/volatile[ ]*//;s/\(unsigned\|signed\|struct\)[ ]*//;s/\(\[\|__attribute__\).*;[ ]*$//;s/;[ ]*$//;s/^[^ ]*[ ]*//;s/,/\
/g' | sed 's/^[ *]*//;s/[ ]*$//;s/^.*$/printf ("#define AOFF_'$1'_\0 0x%08x\\n#define ASIZ_'$1'_\0 0x%08x\\n", ((char *)\&_'$1'.\0) - ((char *)\&_'$1'), sizeof(_'$1'.\0));/' >> $3
echo "printf (\"#define ASIZ_$1\\t0x%08x\\n\", sizeof(_$1));" >> $3
/* $Id: dtlb_backend.S,v 1.4 1998/06/15 16:59:34 jj Exp $
/* $Id: dtlb_backend.S,v 1.6 1998/09/24 03:21:32 davem Exp $
* dtlb_backend.S: Back end to DTLB miss replacement strategy.
* This is included directly into the trap table.
*
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -8,9 +8,9 @@
#define LO_MAGIC 0x01010101
#define HI_MAGIC 0x80808080
.align 4
.global strlen
strlen:
.align 32
.global __strlen
__strlen:
mov %o0, %o1
andcc %o0, 3, %g0
be,pt %icc, 9f
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
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