Commit c51fcfae authored by Matthew Wilcox's avatar Matthew Wilcox Committed by Linus Torvalds

[PATCH] misc PA updates

 - Remove obsolete documentation
 - Update arch/parisc/lib
 - Remove arch/parisc/tools, we use asm-offsets.c these days
 - Update arch/parisc/Makefile, defconfig & vmlinux.lds.S
parent ff3f38bc
Some notes on IODC, its general brokenness, and how to work around it.
Short Version
IODC is HP's pre-PCI standard for device identification (a la PCI vendor,
device IDs), detection, configuration, initialization and so on.
It also can provide firmware function to do the actual IO, which are slow,
not really defined for runtime usage and generally not desirable. (There
are other firmware standards, such as STI, to do real IO).
Usually, there are two parts to IODC. The actual ROMs, which are laid out,
detected aso in a bus-specific manner (IO_DC_ADDRESS / IO_DC_DATA on
GSC/Runway, PCI spec - compliant ROMs for PCI, God-only-knows how on EISA),
and the slightly cooked data read by PDC_IODC.
The ROM layout is generally icky (only one byte out of every 4-byte-word
might be valid, and many devices don't implement required options), so
using PDC_IODC is highly recommended. (In fact, you should use the device
lists set up by the kernel proper instead of calling PDC_IODC yourself).
Now, let's have a look at what the cooked ROM looks like (see iodc.pdf for
the details, this is the simplified version).
Basically, the first 8 bytes of IODC contain two 32-bit ids called HVERSION
and SVERSION. Those are further split up into bit fields, and
unfortunately just ignoring this split up isn't an option.
SVERSION consists of a 4-bit revision field, a 20-bit model field and a
8-bit opt field. Now, forget the revision and opt fields exist. Basically,
the model field is equivalent to a PCI device id (there is no vendor id.
this is proprietary hardware we're talking about). That is, all your
driver cares for, in 90 % of the cases, is to find all devices that match
the model field.
The rev field is - you guessed it - roughly equivalent to the revision
byte for PCI, with the exception that higher revisions should be strict
supersets of lower revisions.
The last byte of HVERSION, "type", and the last byte of SVERSION, "opt",
belong together; type gives a very rough indication of what the device
is supposed to do, and opt contains some type-specific information. (For
example, the "bus converter" (ie bus bridge) type encodes the kind of
bus behind the bridge in the opt field.
The rest of HVERSION contains, in most cases, a number identifying the
machine the chip was used in, or a revision indicator that just fixed
bugs and didn't add any features (or was done in a shrinked process or
whatever).
So, here's the interface you actually should use to find your devices:
/* Find a device, matching the model field of sversion only (from=NULL
* for the first call */
struct iodc_dev *iodc_find_device(u32 sversion, struct iodc_dev *from);
Here's a function you should use if you have special requirements, such
as finding devices by type rather than by model. Generally, if you're
using this, you should be me).
/* Find a device, masking out bits as specified */
struct iodc_dev *iodc_find_device_mask(u32 hversion, u32 sversion,
u32 hversion_mask, u32 sversion_mask, struct iodc_dev *from);
Philipp Rumpf <prumpf@tux.org>
......@@ -17,6 +17,19 @@
# Mike Shaver, Helge Deller and Martin K. Petersen
#
ifdef CONFIG_PARISC64
CROSS_COMPILE := hppa64-linux-
UTS_MACHINE := parisc64
#CFLAGS += -b hppa64-linux
else
MACHINE := $(subst 64,,$(shell uname -m))
ifneq (${MACHINE},parisc)
# cross compilation
CROSS_COMPILE := hppa-linux-
endif
endif
FINAL_LD=$(CROSS_COMPILE)ld --warn-common --warn-section-align
OBJCOPY_FLAGS =-O binary -R .note -R .comment -S
......@@ -29,29 +42,63 @@ CFLAGS := $(CFLAGS) -D__linux__ $(CFLAGS_PIPE) $(CFLAGS_NSR)
# enable them by default.
CFLAGS += -mno-space-regs -mfast-indirect-calls
# If we become able to compile for specific platforms, this should be
# conditional on that.
CFLAGS += -mschedule=7200
# No fixed-point multiply
CFLAGS += -mdisable-fpregs
HEAD = arch/parisc/kernel/head.o
# Without this, "ld -r" results in .text sections that are too big
# (> 0x40000) for branches to reach stubs.
CFLAGS += -ffunction-sections
# select which processor to optimise for
ifdef CONFIG_PA7100
CFLAGS += -march=1.1 -mschedule=7100
endif
ifdef CONFIG_PA7200
CFLAGS += -march=1.1 -mschedule=7200
endif
ifdef CONFIG_PA7100LC
CFLAGS += -march=1.1 -mschedule=7100LC
endif
ifdef CONFIG_PA8X00
CFLAGS += -march=2.0 -mschedule=8000
endif
HEAD := arch/parisc/kernel/head.o
ifdef CONFIG_PARISC64
HEAD := arch/parisc/kernel/head64.o
endif
SUBDIRS += arch/parisc/tools
core-y += arch/parisc/kernel/pdc_cons.o \
arch/parisc/kernel/process.o \
arch/parisc/mm/ \
arch/parisc/kernel/ \
arch/parisc/hpux/ \
arch/parisc/math-emu/ \
arch/parisc/kernel/init_task.o
libs-y += arch/parisc/lib/lib.a \
libs-y += arch/parisc/lib/ \
`$(CC) -print-libgcc-file-name`
drivers-$(CONFIG_MATH_EMULATION) += arch/parisc/math-emu/
drivers-$(CONFIG_KWDB) += arch/parisc/kdb/
palo: vmlinux
export TOPDIR=`pwd`; export CONFIG_STI_CONSOLE=$(CONFIG_STI_CONSOLE); \
@if [ $$(palo -f /dev/null >/dev/null 2>&1 ; echo $$?) != 2 ]; then \
echo 'ERROR: Please install palo first (apt-get install palo)';\
echo 'or build it from source and install it somewhere in your $$PATH';\
false; \
fi
@if [ ! -f ./palo.conf ]; then \
cp arch/parisc/defpalo.conf palo.conf; \
echo 'A generic palo config file (./palo.conf) has been created for you.'; \
echo 'You should check it and re-run "make palo".'; \
echo 'WARNING: the "lifimage" file is now placed in this directory by default!'; \
false; \
fi
palo -f ./palo.conf
oldpalo: vmlinux
export TOPDIR=`pwd`; \
unset STRIP LDFLAGS CPP CPPFLAGS AFLAGS CFLAGS CC LD; cd ../palo && make lifimage
Image: palo
......@@ -68,6 +115,19 @@ compressed: zImage
install:
archmrproper:
archclean:
archmrproper:
prepare: include/asm-$(ARCH)/offsets.h
arch/$(ARCH)/kernel/asm-offsets.s: include/asm include/linux/version.h \
include/config/MARKER
include/asm-$(ARCH)/offsets.h.tmp: arch/$(ARCH)/kernel/asm-offsets.s
@$(generate-asm-offsets.h) < $< > $@
include/asm-$(ARCH)/offsets.h: include/asm-$(ARCH)/offsets.h.tmp
@echo -n ' Generating $@'
@$(update-if-changed)
This diff is collapsed.
# This a generic Palo configuration file. For more information about how
# it works try 'palo -?'.
#
# Most people using 'make palo' want a bootable file, usable for
# network or tape booting for example.
--init-tape=lifimage
--recoverykernel=vmlinux
########## Pick your ROOT here! ##########
# You need at least one 'root='!
#
# If you want a root ramdisk, use the next 2 lines
# (Edit the ramdisk image name!!!!)
--ramdisk=ram-disk-image-file
--commandline=0/vmlinux HOME=/ root=/dev/ram initrd=0/ramdisk
# If you want NFS root, use the following command line (Edit the HOSTNAME!!!)
#--commandline=0/vmlinux HOME=/ root=/dev/nfs nfsroot=HOSTNAME ip=bootp
# If you have root on a disk partition, use this (Edit the partition name!!!)
#--commandline=0/vmlinux HOME=/ root=/dev/sda1
......@@ -2,10 +2,8 @@
# Makefile for parisc-specific library files..
#
L_TARGET = lib.a
obj-y := lusercopy.o bitops.o checksum.o
EXTRA_AFLAGS := -traditional
L_TARGET = lib.a
obj-y := lusercopy.o bitops.o checksum.o io.o memset.o
include $(TOPDIR)/Rules.make
/* atomic.c: atomic operations which got too long to be inlined all over
* the place.
/*
* bitops.c: atomic operations which got too long to be inlined all over
* the place.
*
* Copyright 1999 Philipp Rumpf (prumpf@tux.org */
* Copyright 1999 Philipp Rumpf (prumpf@tux.org)
* Copyright 2000 Grant Grundler (grundler@cup.hp.com)
*/
#include <linux/config.h>
#include <linux/kernel.h>
......@@ -17,44 +20,67 @@ spinlock_t __atomic_hash[ATOMIC_HASH_SIZE] = {
spinlock_t __atomic_lock = SPIN_LOCK_UNLOCKED;
#ifndef __LP64__
unsigned long __xchg(unsigned long x, unsigned long *ptr, int size)
#ifdef __LP64__
unsigned long __xchg64(unsigned long x, unsigned long *ptr)
{
unsigned long temp, flags;
if (size != sizeof x) {
printk("__xchg called with bad pointer\n");
}
spin_lock_irqsave(&__atomic_lock, flags);
SPIN_LOCK_IRQSAVE(ATOMIC_HASH(ptr), flags);
temp = *ptr;
*ptr = x;
spin_unlock_irqrestore(&__atomic_lock, flags);
SPIN_UNLOCK_IRQRESTORE(ATOMIC_HASH(ptr), flags);
return temp;
}
#else
unsigned long __xchg(unsigned long x, unsigned long *ptr, int size)
#endif
unsigned long __xchg32(int x, int *ptr)
{
unsigned long temp, flags;
unsigned int *ptr32;
if (size == 8) {
try_long:
spin_lock_irqsave(&__atomic_lock, flags);
temp = *ptr;
*ptr = x;
spin_unlock_irqrestore(&__atomic_lock, flags);
return temp;
}
if (size == 4) {
ptr32 = (unsigned int *)ptr;
spin_lock_irqsave(&__atomic_lock, flags);
temp = (unsigned long)*ptr32;
*ptr32 = (unsigned int)x;
spin_unlock_irqrestore(&__atomic_lock, flags);
return temp;
}
printk("__xchg called with bad pointer\n");
goto try_long;
unsigned long flags;
unsigned long temp;
SPIN_LOCK_IRQSAVE(ATOMIC_HASH(ptr), flags);
(long) temp = (long) *ptr; /* XXX - sign extension wanted? */
*ptr = x;
SPIN_UNLOCK_IRQRESTORE(ATOMIC_HASH(ptr), flags);
return temp;
}
unsigned long __xchg8(char x, char *ptr)
{
unsigned long flags;
unsigned long temp;
SPIN_LOCK_IRQSAVE(ATOMIC_HASH(ptr), flags);
(long) temp = (long) *ptr; /* XXX - sign extension wanted? */
*ptr = x;
SPIN_UNLOCK_IRQRESTORE(ATOMIC_HASH(ptr), flags);
return temp;
}
#ifdef __LP64__
unsigned long __cmpxchg_u64(volatile unsigned long *ptr, unsigned long old, unsigned long new)
{
unsigned long flags;
unsigned long prev;
SPIN_LOCK_IRQSAVE(ATOMIC_HASH(ptr), flags);
if ((prev = *ptr) == old)
*ptr = new;
SPIN_UNLOCK_IRQRESTORE(ATOMIC_HASH(ptr), flags);
return prev;
}
#endif
unsigned long __cmpxchg_u32(volatile unsigned int *ptr, unsigned int old, unsigned int new)
{
unsigned long flags;
unsigned int prev;
SPIN_LOCK_IRQSAVE(ATOMIC_HASH(ptr), flags);
if ((prev = *ptr) == old)
*ptr = new;
SPIN_UNLOCK_IRQRESTORE(ATOMIC_HASH(ptr), flags);
return (unsigned long)prev;
}
This diff is collapsed.
/*------------------------------------------------------------------------------
* Native PARISC/Linux Project (http://www.puffingroup.com/parisc)
/*
* Linux/PA-RISC Project (http://www.parisc-linux.org/)
*
* Assembly Language User Access Routines
* Copyright (C) 2000 Hewlett-Packard (John Marvin)
......@@ -30,7 +30,6 @@
*/
.level 1.1
.text
#include <asm/assembly.h>
......@@ -42,12 +41,9 @@
* on the flag stored in the task structure.
*/
/* FIXME! depi below has hardcoded idea of kernel stack size */
.macro get_sr
copy %r30,%r1 ;! Get task structure
depi 0,31,14,%r1 ;! into r1
ldw TASK_SEGMENT(%r1),%r22
mfctl %cr30,%r1
ldw TI_SEGMENT(%r1),%r22
mfsp %sr3,%r1
or,<> %r22,%r0,%r0
copy %r0,%r1
......@@ -82,7 +78,11 @@ $lctu_done:
ldo 1(%r24),%r24
.section __ex_table,"a"
#ifdef __LP64__
.dword 1b,(2b-1b)
#else
.word 1b,(2b-1b)
#endif
.previous
.procend
......@@ -123,7 +123,11 @@ $lcfu_zero_loop:
nop
.section __ex_table,"a"
#ifdef __LP64__
.dword 1b,(2b-1b)
#else
.word 1b,(2b-1b)
#endif
.previous
.procend
......@@ -133,7 +137,7 @@ $lcfu_zero_loop:
*
* Returns -EFAULT if exception before terminator,
* N if the entire buffer filled,
* otherwise strlen + 1 (i.e. includes zero byte)
* otherwise strlen (i.e. excludes zero byte)
*/
.export lstrncpy_from_user,code
......@@ -142,7 +146,7 @@ lstrncpy_from_user:
.callinfo NO_CALLS
.entry
comib,= 0,%r24,$lsfu_done
copy %r26,%r23
copy %r24,%r23
get_sr
1: ldbs,ma 1(%sr1,%r25),%r1
$lsfu_loop:
......@@ -151,7 +155,7 @@ $lsfu_loop:
addib,<>,n -1,%r24,$lsfu_loop
2: ldbs,ma 1(%sr1,%r25),%r1
$lsfu_done:
sub %r26,%r23,%r28
sub %r23,%r24,%r28
$lsfu_exit:
bv %r0(%r2)
nop
......@@ -161,8 +165,13 @@ $lsfu_exit:
ldi -EFAULT,%r28
.section __ex_table,"a"
#ifdef __LP64__
.dword 1b,(3b-1b)
.dword 2b,(3b-2b)
#else
.word 1b,(3b-1b)
.word 2b,(2b-1b)
.word 2b,(3b-2b)
#endif
.previous
.procend
......@@ -194,7 +203,11 @@ $lclu_done:
ldo 1(%r25),%r25
.section __ex_table,"a"
#ifdef __LP64__
.dword 1b,(2b-1b)
#else
.word 1b,(2b-1b)
#endif
.previous
.procend
......@@ -233,8 +246,13 @@ $lslen_nzero:
copy %r24,%r26 /* reset r26 so 0 is returned on fault */
.section __ex_table,"a"
#ifdef __LP64__
.dword 1b,(3b-1b)
.dword 2b,(3b-2b)
#else
.word 1b,(3b-1b)
.word 2b,(2b-1b)
.word 2b,(3b-2b)
#endif
.previous
.procend
......
/* Copyright (C) 1991, 1997 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, write to the Free
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA. */
/* Slight modifications for pa-risc linux - Paul Bame <bame@debian.org> */
#include <linux/types.h>
#include <asm/string.h>
#define OPSIZ (BITS_PER_LONG/8)
typedef unsigned long op_t;
void *
memset (void *dstpp, int sc, size_t len)
{
unsigned int c = sc;
long int dstp = (long int) dstpp;
if (len >= 8)
{
size_t xlen;
op_t cccc;
cccc = (unsigned char) c;
cccc |= cccc << 8;
cccc |= cccc << 16;
if (OPSIZ > 4)
/* Do the shift in two steps to avoid warning if long has 32 bits. */
cccc |= (cccc << 16) << 16;
/* There are at least some bytes to set.
No need to test for LEN == 0 in this alignment loop. */
while (dstp % OPSIZ != 0)
{
((unsigned char *) dstp)[0] = c;
dstp += 1;
len -= 1;
}
/* Write 8 `op_t' per iteration until less than 8 `op_t' remain. */
xlen = len / (OPSIZ * 8);
while (xlen > 0)
{
((op_t *) dstp)[0] = cccc;
((op_t *) dstp)[1] = cccc;
((op_t *) dstp)[2] = cccc;
((op_t *) dstp)[3] = cccc;
((op_t *) dstp)[4] = cccc;
((op_t *) dstp)[5] = cccc;
((op_t *) dstp)[6] = cccc;
((op_t *) dstp)[7] = cccc;
dstp += 8 * OPSIZ;
xlen -= 1;
}
len %= OPSIZ * 8;
/* Write 1 `op_t' per iteration until less than OPSIZ bytes remain. */
xlen = len / OPSIZ;
while (xlen > 0)
{
((op_t *) dstp)[0] = cccc;
dstp += OPSIZ;
xlen -= 1;
}
len %= OPSIZ;
}
/* Write the last few bytes. */
while (len > 0)
{
((unsigned char *) dstp)[0] = c;
dstp += 1;
len -= 1;
}
return dstpp;
}
# Makefile for MIPS kernel build tools.
#
# Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
# Copyright (C) 1997 Ralf Baechle (ralf@gnu.ai.mit.edu)
#
# $Id: Makefile,v 1.3 1999/09/29 05:19:56 grundler Exp $
#
TARGET := $(TOPDIR)/include/asm-$(ARCH)/offset.h
all: $(TARGET)
$(TARGET): offset.h
cmp -s $^ $@ || (cp $^ $(TARGET).new && mv $(TARGET).new $(TARGET))
offset.h: offset.s
sed -n '/^@@@/s///p' $^ >$@
offset.s: offset.c
clean:
rm -f offset.[hs] $(TARGET).new
include $(TOPDIR)/Rules.make
This diff is collapsed.
#include <linux/config.h>
/* ld script to make hppa Linux kernel */
OUTPUT_FORMAT("elf32-hppa")
#ifndef CONFIG_PARISC64
OUTPUT_FORMAT("elf32-hppa-linux")
OUTPUT_ARCH(hppa)
#else
OUTPUT_FORMAT("elf64-hppa-linux")
OUTPUT_ARCH(hppa:hppa2.0w)
#endif
ENTRY(_stext)
#ifndef CONFIG_PARISC64
jiffies = jiffies_64 + 4;
#else
jiffies = jiffies_64;
#endif
SECTIONS
{
/* right now use 0x10000/0x11000, later when we don't use Console and
* Boot-Device IODC, we will change this to 0x8000 !!!
*/
. = 0xc0100000;
/* . = 0x10000; */
. = 0x10100000;
_text = .; /* Text and read-only data */
.text BLOCK(16) : {
......@@ -22,12 +29,12 @@ SECTIONS
*(.gnu.warning)
} = 0
_etext = .; /* End of text section */
. = ALIGN(16);
.rodata : { *(.rodata) *(.rodata.*) }
.kstrtab : { *(.kstrtab) }
_etext = .; /* End of text section */
.data BLOCK(8192) : { /* Data without special */
data_start = .;
*(.data)
......@@ -42,6 +49,16 @@ SECTIONS
__ksymtab : { *(__ksymtab) }
__stop___ksymtab = .;
__start___kallsyms = .; /* All kernel symbols */
__kallsyms : { *(__kallsyms) }
__stop___kallsyms = .;
#ifdef CONFIG_PARISC64
. = ALIGN(16); /* Linkage tables */
.opd : { *(.opd) } PROVIDE (__gp = .);
.plt : { *(.plt) }
.dlt : { *(.dlt) }
#endif
. = ALIGN(16384);
__init_begin = .;
......@@ -49,7 +66,7 @@ SECTIONS
.init.data : { *(.init.data) }
. = ALIGN(16);
__setup_start = .;
.setup.init : { *(.setup.init) }
.init.setup : { *(.init.setup) }
__setup_end = .;
__initcall_start = .;
.initcall.init : {
......@@ -62,9 +79,13 @@ SECTIONS
*(.initcall7.init)
}
__initcall_end = .;
. = ALIGN(32);
__per_cpu_start = .;
.data.percpu : { *(.data.percpu) }
__per_cpu_end = .;
. = ALIGN(4096);
__init_end = .;
init_task BLOCK(16384) : { *(init_task) } /* The initial task and kernel stack */
_edata = .; /* End of data section */
......@@ -84,5 +105,15 @@ SECTIONS
.stab.indexstr 0 : { *(.stab.indexstr) }
.comment 0 : { *(.comment) }
.note 0 : { *(.note) }
#ifdef CONFIG_PARISC64
/* temporary hack until binutils is fixed to not emit these
for static binaries */
/DISCARD/ : {
*(.dynsym)
*(.dynstr)
*(.dynamic)
*(.hash)
}
#endif
}
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