Commit 56f41d50 authored by Matthew Wilcox's avatar Matthew Wilcox Committed by Linus Torvalds

[PATCH] PA-RISC updates

PA-RISC updates for 2.6.0-test6
 - Some more support for 64-bit userspace
 - Move many EXPORT_SYMBOLs out of parisc_ksyms.c
 - Make both the OSS and ALSA harmony drivers build
 - ioctl typechecking
 - Make math-emu build without warnings.
 - Persuade SuckyIO to not crash the machine.
parent 7e2552dc
......@@ -150,6 +150,7 @@ config COMPAT
config HPUX
bool "Support for HP-UX binaries"
depends on !PARISC64
config NR_CPUS
int "Maximum number of CPUs (2-32)"
......@@ -190,6 +191,8 @@ source drivers/message/fusion/Kconfig
#source drivers/message/i2o/Kconfig
source "net/Kconfig"
#source "drivers/isdn/Kconfig"
#source "drivers/telephony/Kconfig"
......
......@@ -8,6 +8,7 @@
#include <linux/sched.h>
#include <linux/thread_info.h>
#include <linux/version.h>
#include <linux/ptrace.h>
#include <asm/ptrace.h>
#include <asm/processor.h>
......@@ -249,5 +250,8 @@ int main(void)
DEFINE(DTLB_OFF_COUNT, offsetof(struct pdc_cache_info, dt_off_count));
DEFINE(DTLB_LOOP, offsetof(struct pdc_cache_info, dt_loop));
BLANK();
DEFINE(PA_BLOCKSTEP_BIT, 31-PT_BLOCKSTEP_BIT);
DEFINE(PA_SINGLESTEP_BIT, 31-PT_SINGLESTEP_BIT);
BLANK();
return 0;
}
......@@ -88,7 +88,9 @@ struct elf_prpsinfo32
*/
#define SET_PERSONALITY(ex, ibcs2) \
current->personality = PER_LINUX_32BIT
current->personality = PER_LINUX32; \
current->thread.map_base = DEFAULT_MAP_BASE32; \
current->thread.task_size = DEFAULT_TASK_SIZE32 \
#define jiffies_to_timeval jiffies_to_compat_timeval
static __inline__ void
......@@ -99,3 +101,25 @@ jiffies_to_compat_timeval(unsigned long jiffies, struct compat_timeval *value)
}
#include "../../../fs/binfmt_elf.c"
/* Set up a separate execution domain for ELF32 binaries running
* on an ELF64 kernel */
static struct exec_domain parisc32_exec_domain = {
.name = "Linux/ELF32",
.pers_low = PER_LINUX32,
.pers_high = PER_LINUX32,
};
static int __init parisc32_exec_init(void)
{
/* steal the identity signal mappings from the default domain */
parisc32_exec_domain.signal_map = default_exec_domain.signal_map;
parisc32_exec_domain.signal_invmap = default_exec_domain.signal_invmap;
register_exec_domain(&parisc32_exec_domain);
return 0;
}
__initcall(parisc32_exec_init);
......@@ -28,6 +28,7 @@
/* See comments in include/asm-parisc/pci.h */
struct hppa_dma_ops *hppa_dma_ops;
EXPORT_SYMBOL(hppa_dma_ops);
static struct parisc_device root;
......@@ -155,6 +156,7 @@ int register_parisc_driver(struct parisc_driver *driver)
return driver_register(&driver->drv);
}
EXPORT_SYMBOL(register_parisc_driver);
/**
* count_parisc_driver - count # of devices this driver would match
......@@ -187,6 +189,7 @@ int unregister_parisc_driver(struct parisc_driver *driver)
driver_unregister(&driver->drv);
return 0;
}
EXPORT_SYMBOL(unregister_parisc_driver);
static struct parisc_device *find_device_by_addr(unsigned long hpa)
{
......@@ -257,7 +260,7 @@ char *print_pa_hwpath(struct parisc_device *dev, char *output)
path.mod = dev->hw_path;
return print_hwpath(&path, output);
}
EXPORT_SYMBOL(print_pa_hwpath);
#if defined(CONFIG_PCI) || defined(CONFIG_ISA)
/**
......@@ -289,6 +292,7 @@ void get_pci_node_path(struct pci_dev *dev, struct hardware_path *path)
padev = padev->parent;
}
}
EXPORT_SYMBOL(get_pci_node_path);
/**
* print_pci_hwpath - Returns hardware path for PCI devices
......@@ -306,6 +310,8 @@ char *print_pci_hwpath(struct pci_dev *dev, char *output)
get_pci_node_path(dev, &path);
return print_hwpath(&path, output);
}
EXPORT_SYMBOL(print_pci_hwpath);
#endif /* defined(CONFIG_PCI) || defined(CONFIG_ISA) */
......
......@@ -2225,18 +2225,23 @@ syscall_exit:
LDREG TI_TASK(%r1),%r1
STREG %r28,TASK_PT_GR28(%r1)
/* Save other hpux returns if personality is PER_HPUX */
#ifdef CONFIG_HPUX
/* <linux/personality.h> cannot be easily included */
#define PER_HPUX 0x10
LDREG TASK_PERSONALITY(%r1),%r19
#warning the ldo+CMPIB could probably be done better but 0x10 i soutside of range of CMPIB
/* We can't use "CMPIB<> PER_HPUX" since "im5" field is sign extended */
ldo -PER_HPUX(%r19), %r19
CMPIB<>,n 0,%r19,1f
/* Save other hpux returns if personality is PER_HPUX */
STREG %r22,TASK_PT_GR22(%r1)
STREG %r29,TASK_PT_GR29(%r1)
1:
#endif /* CONFIG_HPUX */
/* Seems to me that dp could be wrong here, if the syscall involved
* calling a module, and nothing got round to restoring dp on return.
*/
......@@ -2315,18 +2320,16 @@ syscall_restore:
depi 3,31,2,%r31 /* ensure return to user mode. */
#ifdef __LP64__
/* Since we are returning to a 32 bit user process, we always
* clear the W bit. This means that the be (and mtsp) gets
* executed in narrow mode, but that is OK, since we are
* returning to a 32 bit process. When we support 64 bit processes
* we won't clear the W bit, so the be will run in wide mode.
*/
be 0(%sr3,%r31) /* return to user space */
/* decide whether to reset the wide mode bit
*
* For a syscall, the W bit is stored in the lowest bit
* of sp. Extract it and reset W if it is zero */
extrd,u,*<> %r30,63,1,%r1
rsm PSW_SM_W, %r0
#else
be,n 0(%sr3,%r31) /* return to user space */
/* now reset the lowest bit of sp if it was set */
xor %r30,%r1,%r30
#endif
be,n 0(%sr3,%r31) /* return to user space */
/* We have to return via an RFI, so that PSW T and R bits can be set
* appropriately.
......@@ -2340,12 +2343,19 @@ syscall_restore_rfi:
LDREG TASK_PT_PSW(%r1),%r2 /* Get old PSW */
ldi 0x0b,%r20 /* Create new PSW */
depi -1,13,1,%r20 /* C, Q, D, and I bits */
bb,>=,n %r19,15,try_tbit /* PT_SINGLESTEP */
/* The values of PA_SINGLESTEP_BIT and PA_BLOCKSTEP_BIT are
* set in include/linux/ptrace.h and converted to PA bitmap
* numbers in asm-offsets.c */
/* if ((%r19.PA_SINGLESTEP_BIT)) { %r20.27=1} */
extru,= %r19,PA_SINGLESTEP_BIT,1,%r0
depi -1,27,1,%r20 /* R bit */
try_tbit:
bb,>=,n %r19,14,psw_setup /* PT_BLOCKSTEP, see ptrace.c */
/* if ((%r19.PA_BLOCKSTEP_BIT)) { %r20.7=1} */
extru,= %r19,PA_BLOCKSTEP_BIT,1,%r0
depi -1,7,1,%r20 /* T bit */
psw_setup:
STREG %r20,TASK_PT_PSW(%r1)
/* Always store space registers, since sr3 can be changed (e.g. fork) */
......
......@@ -41,19 +41,20 @@
* prumpf 991016
*/
#include <stdarg.h>
#include <linux/delay.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/string.h>
#include <linux/spinlock.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <asm/page.h>
#include <asm/pdc.h>
#include <asm/system.h>
#include <asm/processor.h> /* for boot_cpu_data */
#include <stdarg.h>
static spinlock_t pdc_lock = SPIN_LOCK_UNLOCKED;
static unsigned long pdc_result[32] __attribute__ ((aligned (8)));
static unsigned long pdc_result2[32] __attribute__ ((aligned (8)));
......@@ -151,6 +152,7 @@ int pdc_add_valid(unsigned long address)
return retval;
}
EXPORT_SYMBOL(pdc_add_valid);
/**
* pdc_chassis_info - Return chassis information.
......@@ -264,6 +266,7 @@ int pdc_iodc_read(unsigned long *actcnt, unsigned long hpa, unsigned int index,
return retval;
}
EXPORT_SYMBOL(pdc_iodc_read);
/**
* pdc_system_map_find_mods - Locate unarchitected modules.
......@@ -518,6 +521,7 @@ int pdc_lan_station_id(char *lan_addr, unsigned long hpa)
return retval;
}
EXPORT_SYMBOL(pdc_lan_station_id);
/**
......@@ -594,6 +598,7 @@ int pdc_get_initiator( struct hardware_path *hwpath, unsigned char *scsi_id,
spin_unlock_irq(&pdc_lock);
return retval >= PDC_OK;
}
EXPORT_SYMBOL(pdc_get_initiator);
/**
......@@ -660,6 +665,7 @@ int pdc_tod_read(struct pdc_tod *tod)
return retval;
}
EXPORT_SYMBOL(pdc_tod_read);
/**
* pdc_tod_set - Set the Time-Of-Day clock.
......@@ -678,6 +684,7 @@ int pdc_tod_set(unsigned long sec, unsigned long usec)
return retval;
}
EXPORT_SYMBOL(pdc_tod_set);
#ifdef __LP64__
int pdc_mem_mem_table(struct pdc_memory_table_raddr *r_addr,
......@@ -772,20 +779,34 @@ int pdc_soft_power_button(int sw_control)
}
/*
* pdc_suspend_usb - Stop USB controller
* pdc_io_reset - Hack to avoid overlapping range registers of Bridges devices.
* Primarily a problem on T600 (which parisc-linux doesn't support) but
* who knows what other platform firmware might do with this OS "hook".
*/
void pdc_io_reset(void)
{
spin_lock_irq(&pdc_lock);
mem_pdc_call(PDC_IO, PDC_IO_RESET, 0);
spin_unlock_irq(&pdc_lock);
}
/*
* pdc_io_reset_devices - Hack to Stop USB controller
*
* If PDC used the usb controller, the usb controller
* is still running and will crash the machines during iommu
* setup, because of still running DMA. This PDC call
* stops the USB controller
* stops the USB controller.
* Normally called after calling pdc_io_reset().
*/
void pdc_suspend_usb(void)
void pdc_io_reset_devices(void)
{
spin_lock_irq(&pdc_lock);
mem_pdc_call(PDC_IO, PDC_IO_SUSPEND_USB, 0);
mem_pdc_call(PDC_IO, PDC_IO_RESET_DEVICES, 0);
spin_unlock_irq(&pdc_lock);
}
/**
* pdc_iodc_putc - Console character print using IODC.
* @c: the character to output.
......@@ -905,6 +926,7 @@ int pdc_sti_call(unsigned long func, unsigned long flags,
return retval;
}
EXPORT_SYMBOL(pdc_sti_call);
#ifdef __LP64__
/**
......
......@@ -526,12 +526,14 @@ static void __init system_map_inventory(void)
int i;
long status = PDC_OK;
#if defined(CONFIG_IOMMU_SBA) && defined(CONFIG_SUPERIO)
/*
* first stop the usb controller, otherwise the machine
* might crash during iommu setup
* Stop the suckyio usb controller on Astro based systems.
* Otherwise the machine might crash during iommu setup.
*/
#warning We still probably need to worry about USB here, but how?
/* pdc_suspend_usb(); */
pdc_io_reset();
pdc_io_reset_devices();
#endif
for (i = 0; status != PDC_BAD_PROC && status != PDC_NE_MOD; i++) {
struct parisc_device *dev;
......
......@@ -193,6 +193,7 @@ void disable_irq(int irq)
else
BUG();
}
EXPORT_SYMBOL(disable_irq);
void enable_irq(int irq)
{
......@@ -208,6 +209,7 @@ void enable_irq(int irq)
else
BUG();
}
EXPORT_SYMBOL(enable_irq);
int show_interrupts(struct seq_file *p, void *v)
{
......@@ -698,6 +700,7 @@ void synchronize_irq(unsigned int irqnum)
{
while (in_irq()) ;
}
EXPORT_SYMBOL(synchronize_irq);
#endif
......@@ -847,6 +850,7 @@ unsigned int probe_irq_mask(unsigned long irqs)
{
return 0;
}
EXPORT_SYMBOL(probe_irq_mask);
void __init init_IRQ(void)
{
......
......@@ -73,10 +73,7 @@ struct got_entry {
Elf32_Addr addr;
};
struct fdesc_entry {
Elf32_Addr addr;
Elf32_Addr gp;
};
#define Elf_Fdesc Elf32_Fdesc
struct stub_entry {
Elf32_Word insns[2]; /* each stub entry has two insns */
......@@ -86,11 +83,7 @@ struct got_entry {
Elf64_Addr addr;
};
struct fdesc_entry {
Elf64_Addr dummy[2];
Elf64_Addr addr;
Elf64_Addr gp;
};
#define Elf_Fdesc Elf64_Fdesc
struct stub_entry {
Elf64_Word insns[4]; /* each stub entry has four insns */
......@@ -276,7 +269,7 @@ int module_frob_arch_sections(CONST Elf_Ehdr *hdr,
me->core_size = ALIGN(me->core_size, 16);
me->arch.fdesc_offset = me->core_size;
me->core_size += fdescs * sizeof(struct fdesc_entry);
me->core_size += fdescs * sizeof(Elf_Fdesc);
me->core_size = ALIGN(me->core_size, 16);
me->arch.stub_offset = me->core_size;
......@@ -322,7 +315,7 @@ static Elf64_Word get_got(struct module *me, unsigned long value, long addend)
#ifdef __LP64__
static Elf_Addr get_fdesc(struct module *me, unsigned long value)
{
struct fdesc_entry *fdesc = me->module_core + me->arch.fdesc_offset;
Elf_Fdesc *fdesc = me->module_core + me->arch.fdesc_offset;
if (!value) {
printk(KERN_ERR "%s: zero OPD requested!\n", me->name);
......@@ -664,7 +657,7 @@ int apply_relocate_add(Elf_Shdr *sechdrs,
*loc64 = get_fdesc(me, val+addend);
DEBUGP("FDESC for %s at %p points to %lx\n",
strtab + sym->st_name, *loc64,
((struct fdesc_entry *)*loc64)->addr);
((Elf_Fdesc *)*loc64)->addr);
} else {
/* if the symbol is not local to this
* module then val+addend is a pointer
......@@ -696,10 +689,10 @@ int module_finalize(const Elf_Ehdr *hdr,
Elf_Sym *newptr, *oldptr;
Elf_Shdr *symhdr = NULL;
#ifdef DEBUG
struct fdesc_entry *entry;
Elf_Fdesc *entry;
u32 *addr;
entry = (struct fdesc_entry *)me->init;
entry = (Elf_Fdesc *)me->init;
printk("FINALIZE, ->init FPTR is %p, GP %lx ADDR %lx\n", entry,
entry->gp, entry->addr);
addr = (u32 *)entry->addr;
......
......@@ -26,19 +26,6 @@ EXPORT_SYMBOL(strrchr);
EXPORT_SYMBOL(strstr);
EXPORT_SYMBOL(strpbrk);
#include <asm/hardware.h> /* struct parisc_device for asm/pci.h */
#include <linux/pci.h>
EXPORT_SYMBOL(hppa_dma_ops);
#if defined(CONFIG_PCI) || defined(CONFIG_ISA)
EXPORT_SYMBOL(get_pci_node_path);
#endif
#include <linux/sched.h>
#include <asm/irq.h>
EXPORT_SYMBOL(enable_irq);
EXPORT_SYMBOL(disable_irq);
EXPORT_SYMBOL(probe_irq_mask);
#include <asm/processor.h>
EXPORT_SYMBOL(kernel_thread);
EXPORT_SYMBOL(boot_cpu_data);
......@@ -46,10 +33,6 @@ EXPORT_SYMBOL(boot_cpu_data);
#include <linux/pm.h>
EXPORT_SYMBOL(pm_power_off);
#ifdef CONFIG_SMP
EXPORT_SYMBOL(synchronize_irq);
#endif /* CONFIG_SMP */
#include <asm/atomic.h>
EXPORT_SYMBOL(__xchg8);
EXPORT_SYMBOL(__xchg32);
......@@ -74,14 +57,6 @@ extern int $global$;
EXPORT_SYMBOL($global$);
#endif
EXPORT_SYMBOL(register_parisc_driver);
EXPORT_SYMBOL(unregister_parisc_driver);
EXPORT_SYMBOL(print_pci_hwpath);
EXPORT_SYMBOL(print_pa_hwpath);
EXPORT_SYMBOL(pdc_iodc_read);
EXPORT_SYMBOL(pdc_tod_read);
EXPORT_SYMBOL(pdc_tod_set);
#include <asm/io.h>
EXPORT_SYMBOL(__ioremap);
EXPORT_SYMBOL(iounmap);
......@@ -89,22 +64,6 @@ EXPORT_SYMBOL(__memcpy_toio);
EXPORT_SYMBOL(__memcpy_fromio);
EXPORT_SYMBOL(__memset_io);
#if defined(CONFIG_PCI) || defined(CONFIG_ISA)
EXPORT_SYMBOL(inb);
EXPORT_SYMBOL(inw);
EXPORT_SYMBOL(inl);
EXPORT_SYMBOL(outb);
EXPORT_SYMBOL(outw);
EXPORT_SYMBOL(outl);
EXPORT_SYMBOL(insb);
EXPORT_SYMBOL(insw);
EXPORT_SYMBOL(insl);
EXPORT_SYMBOL(outsb);
EXPORT_SYMBOL(outsw);
EXPORT_SYMBOL(outsl);
#endif
#include <asm/cache.h>
EXPORT_SYMBOL(flush_kernel_dcache_range_asm);
EXPORT_SYMBOL(flush_kernel_dcache_page);
......@@ -130,17 +89,6 @@ EXPORT_SYMBOL(__up);
EXPORT_SYMBOL(__down_interruptible);
EXPORT_SYMBOL(__down);
#include <linux/in6.h>
#include <asm/checksum.h>
EXPORT_SYMBOL(csum_partial_copy_nocheck);
EXPORT_SYMBOL(csum_partial_copy_from_user);
#include <asm/pdc.h>
EXPORT_SYMBOL(pdc_add_valid);
EXPORT_SYMBOL(pdc_lan_station_id);
EXPORT_SYMBOL(pdc_get_initiator);
EXPORT_SYMBOL(pdc_sti_call);
extern void $$divI(void);
extern void $$divU(void);
extern void $$remI(void);
......@@ -218,6 +166,3 @@ EXPORT_SYMBOL(__moddi3);
extern void $$dyncall(void);
EXPORT_SYMBOL($$dyncall);
#endif
#include <asm/pgtable.h>
EXPORT_SYMBOL(vmalloc_start);
......@@ -88,7 +88,8 @@ u##size in##type (int addr) \
EISA_IN(size); \
if (!parisc_pci_hba[b]) return (u##size) -1; \
return pci_port->in##type(parisc_pci_hba[b], PCI_PORT_ADDR(addr)); \
}
} \
EXPORT_SYMBOL(in##type);
PCI_PORT_IN(b, 8)
PCI_PORT_IN(w, 16)
......@@ -102,7 +103,8 @@ void out##type (u##size d, int addr) \
EISA_OUT(size); \
if (!parisc_pci_hba[b]) return; \
pci_port->out##type(parisc_pci_hba[b], PCI_PORT_ADDR(addr), d); \
}
} \
EXPORT_SYMBOL(out##type);
PCI_PORT_OUT(b, 8)
PCI_PORT_OUT(w, 16)
......
......@@ -23,16 +23,6 @@
#include <asm/processor.h>
#include <asm/offsets.h>
/* These are used in entry.S, syscall_restore_rfi. We need to record the
* current stepping mode somewhere other than in PSW, because there is no
* concept of saving and restoring the users PSW over a syscall. We choose
* to use these two bits in task->ptrace. These bits must not clash with
* any PT_* defined in include/linux/sched.h, and must match with the bit
* tests in entry.S
*/
#define PT_SINGLESTEP 0x10000
#define PT_BLOCKSTEP 0x20000
/* PSW bits we allow the debugger to modify */
#define USER_PSW_BITS (PSW_N | PSW_V | PSW_CB)
......
......@@ -43,6 +43,7 @@
#include <asm/led.h>
#include <asm/machdep.h> /* for pa7300lc_init() proto */
#include <asm/pdc_chassis.h>
#include <asm/io.h>
#define COMMAND_LINE_SIZE 1024
char saved_command_line[COMMAND_LINE_SIZE];
......@@ -208,27 +209,32 @@ static void __init parisc_proc_mkdir(void)
proc_runway_root = proc_mkdir("bus/runway", 0);
}
break;
default:
/* FIXME: this was added to prevent the compiler
* complaining about missing pcx, pcxs and pcxt
* I'm assuming they have neither gsc nor runway */
break;
}
}
static struct resource central_bus = {
.name = "Central Bus",
.start = (unsigned long)0xfffffffffff80000,
.end = (unsigned long)0xfffffffffffaffff,
.start = F_EXTEND(0xfff80000),
.end = F_EXTEND(0xfffaffff),
.flags = IORESOURCE_MEM,
};
static struct resource local_broadcast = {
.name = "Local Broadcast",
.start = (unsigned long)0xfffffffffffb0000,
.end = (unsigned long)0xfffffffffffdffff,
.start = F_EXTEND(0xfffb0000),
.end = F_EXTEND(0xfffdffff),
.flags = IORESOURCE_MEM,
};
static struct resource global_broadcast = {
.name = "Global Broadcast",
.start = (unsigned long)0xfffffffffffe0000,
.end = (unsigned long)0xffffffffffffffff,
.start = F_EXTEND(0xfffe0000),
.end = F_EXTEND(0xffffffff),
.flags = IORESOURCE_MEM,
};
......
......@@ -25,6 +25,8 @@
#include <linux/unistd.h>
#include <linux/stddef.h>
#include <linux/compat.h>
#include <linux/elf.h>
#include <linux/personality.h>
#include <asm/ucontext.h>
#include <asm/rt_sigframe.h>
#include <asm/uaccess.h>
......@@ -41,8 +43,11 @@
#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
/* Use this to get at 32-bit user passed pointers.
* See sys_sparc32.c for description about these. */
/* gcc will complain if a pointer is cast to an integer of different
* size. If you really need to do this (and we do for an ELF32 user
* application in an ELF64 kernel) then you have to do a cast to an
* integer of the same size first. The A() macro accomplishes
* this. */
#define A(__x) ((unsigned long)(__x))
int do_signal(sigset_t *oldset, struct pt_regs *regs, int in_syscall);
......@@ -166,11 +171,17 @@ sys_rt_sigreturn(struct pt_regs *regs, int in_syscall)
struct rt_sigframe *frame;
struct siginfo si;
sigset_t set;
unsigned long usp = regs->gr[30];
unsigned long usp = (regs->gr[30] & ~(0x01UL));
unsigned long sigframe_size = PARISC_RT_SIGFRAME_SIZE;
#ifdef __LP64__
if(personality(current->personality) == PER_LINUX32)
sigframe_size = PARISC_RT_SIGFRAME_SIZE32;
#endif
/* Unwind the user stack to get the rt_sigframe structure. */
frame = (struct rt_sigframe *)
(usp - PARISC_RT_SIGFRAME_SIZE);
(usp - sigframe_size);
DBG(("in sys_rt_sigreturn, frame is %p\n", frame));
if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set)))
......@@ -271,11 +282,12 @@ setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
sigset_t *set, struct pt_regs *regs, int in_syscall)
{
struct rt_sigframe *frame;
unsigned long rp, usp, haddr;
unsigned long rp, usp;
unsigned long haddr, sigframe_size;
struct siginfo si;
int err = 0;
usp = regs->gr[30];
usp = (regs->gr[30] & ~(0x01UL));
frame = get_sigframe(ka, usp, sizeof(*frame));
DBG(("setup_rt_frame 1: frame %p info %p\n", frame, info));
......@@ -308,64 +320,86 @@ setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
}
#endif
#undef CACHE_FLUSHING_IS_NOT_BROKEN
#ifdef CACHE_FLUSHING_IS_NOT_BROKEN
flush_user_dcache_range((unsigned long) &frame->tramp[0],
(unsigned long) &frame->tramp[4]);
flush_user_icache_range((unsigned long) &frame->tramp[0],
(unsigned long) &frame->tramp[4]);
#else
/* It should *always* be cache line-aligned, but the compiler
sometimes screws up. */
asm volatile("fdc 0(%%sr3,%0)\n\t"
"fdc %1(%%sr3,%0)\n\t"
"sync\n\t"
"fic 0(%%sr3,%0)\n\t"
"fic %1(%%sr3,%0)\n\t"
"sync\n\t"
: : "r" (frame->tramp), "r" (L1_CACHE_BYTES));
#endif
rp = (unsigned long) frame->tramp;
if (err)
goto give_sigsegv;
/* Much more has to happen with signals than this -- but it'll at least */
/* provide a pointer to some places which definitely need a look. */
#define HACK u32
haddr = A(ka->sa.sa_handler);
/* The sa_handler may be a pointer to a function descriptor */
#ifdef __LP64__
if(personality(current->personality) == PER_LINUX32) {
#endif
if (haddr & PA_PLABEL_FDESC) {
Elf32_Fdesc fdesc;
Elf32_Fdesc *ufdesc = (Elf32_Fdesc *)A(haddr & ~3);
err = __copy_from_user(&fdesc, ufdesc, sizeof(fdesc));
haddr = (HACK)A(ka->sa.sa_handler);
/* ARGH! Fucking brain damage. You don't want to know. */
if (haddr & 2) {
HACK *plabel;
HACK ltp;
if (err)
goto give_sigsegv;
plabel = (HACK *) (haddr & ~3);
err |= __get_user(haddr, plabel);
err |= __get_user(ltp, plabel + 1);
haddr = fdesc.addr;
regs->gr[19] = fdesc.gp;
}
#ifdef __LP64__
} else {
Elf64_Fdesc fdesc;
Elf64_Fdesc *ufdesc = (Elf64_Fdesc *)A(haddr & ~3);
err = __copy_from_user(&fdesc, ufdesc, sizeof(fdesc));
if (err)
goto give_sigsegv;
regs->gr[19] = ltp;
haddr = fdesc.addr;
regs->gr[19] = fdesc.gp;
DBG(("64 bit signal, exe=%#lx, r19=%#lx, in_syscall=%d\n",
haddr, regs->gr[19], in_syscall));
}
#endif
/* The syscall return path will create IAOQ values from r31.
*/
if (in_syscall)
regs->gr[31] = (HACK) haddr;
else {
regs->gr[0] = USER_PSW;
regs->iaoq[0] = (HACK) haddr | 3;
sigframe_size = PARISC_RT_SIGFRAME_SIZE;
#ifdef __LP64__
if(personality(current->personality) == PER_LINUX32)
sigframe_size = PARISC_RT_SIGFRAME_SIZE32;
#endif
if (in_syscall) {
regs->gr[31] = haddr;
#ifdef __LP64__
if(personality(current->personality) == PER_LINUX)
sigframe_size |= 1;
#endif
} else {
unsigned long psw = USER_PSW;
#ifdef __LP64__
if(personality(current->personality) == PER_LINUX)
psw |= PSW_W;
#endif
regs->gr[0] = psw;
regs->iaoq[0] = haddr | 3;
regs->iaoq[1] = regs->iaoq[0] + 4;
}
regs->gr[2] = rp; /* userland return pointer */
regs->gr[26] = sig; /* signal number */
regs->gr[25] = (HACK)A(&frame->info); /* siginfo pointer */
regs->gr[24] = (HACK)A(&frame->uc); /* ucontext pointer */
regs->gr[25] = A(&frame->info); /* siginfo pointer */
regs->gr[24] = A(&frame->uc); /* ucontext pointer */
DBG(("making sigreturn frame: %#lx + %#x = %#lx\n",
regs->gr[30], PARISC_RT_SIGFRAME_SIZE,
regs->gr[30] + PARISC_RT_SIGFRAME_SIZE));
regs->gr[30], sigframe_size,
regs->gr[30] + sigframe_size));
/* Raise the user stack pointer to make a proper call frame. */
regs->gr[30] = ((HACK)A(frame) + PARISC_RT_SIGFRAME_SIZE);
regs->gr[30] = (A(frame) + sigframe_size);
DBG(("SIG deliver (%s:%d): frame=0x%p sp=%#lx iaoq=%#lx/%#lx rp=%#lx\n",
current->comm, current->pid, frame, regs->gr[30],
......
......@@ -65,7 +65,7 @@ static int get_offset(struct address_space *mapping)
*/
static int get_offset(struct address_space *mapping)
{
int offset = (int) mapping << (PAGE_SHIFT - 8);
int offset = (unsigned long) mapping << (PAGE_SHIFT - 8);
return offset & 0x3FF000;
}
#endif
......@@ -165,12 +165,13 @@ long sys_shmat_wrapper(int shmid, char *shmaddr, int shmflag)
return raddr;
}
/* Fucking broken ABI */
#ifdef CONFIG_PARISC64
extern asmlinkage long sys_truncate(const char *, unsigned long);
extern asmlinkage long sys_ftruncate(unsigned int, unsigned long);
extern asmlinkage long sys_fcntl(unsigned int, unsigned int, unsigned long);
asmlinkage long parisc_truncate64(const char * path,
unsigned int high, unsigned int low)
{
......@@ -182,6 +183,21 @@ asmlinkage long parisc_ftruncate64(unsigned int fd,
{
return sys_ftruncate(fd, (long)high << 32 | low);
}
/* stubs for the benefit of the syscall_table since truncate64 and truncate
* are identical on LP64 */
asmlinkage long sys_truncate64(const char * path, unsigned long length)
{
return sys_truncate(path, length);
}
asmlinkage long sys_ftruncate64(unsigned int fd, unsigned long length)
{
return sys_ftruncate(fd, length);
}
asmlinkage long sys_fcntl64(unsigned int fd, unsigned int cmd, unsigned long arg)
{
return sys_fcntl(fd, cmd, arg);
}
#else
extern asmlinkage long sys_truncate64(const char *, loff_t);
......
This diff is collapsed.
#undef ENTRY_SAME
#undef ENTRY_DIFF
#undef ENTRY_UHOH
#undef ENTRY_COMP
#undef ENTRY_OURS
#if defined(__LP64__) && !defined(SYSCALL_TABLE_64BIT)
/* Use ENTRY_SAME for 32-bit syscalls which are the same on wide and
* narrow palinux. Use ENTRY_DIFF for those where a 32-bit specific
* implementation is required on wide palinux. Use ENTRY_COMP where
* the compatability layer has a useful 32-bit implementation.
*/
#define ENTRY_SAME(_name_) .dword sys_##_name_
#define ENTRY_DIFF(_name_) .dword sys32_##_name_
#define ENTRY_UHOH(_name_) .dword sys32_##unimplemented
#define ENTRY_OURS(_name_) .dword parisc_##_name_
#define ENTRY_COMP(_name_) .dword compat_sys_##_name_
#elif defined(__LP64__) && defined(SYSCALL_TABLE_64BIT)
#define ENTRY_SAME(_name_) .dword sys_##_name_
#define ENTRY_DIFF(_name_) .dword sys_##_name_
#define ENTRY_UHOH(_name_) .dword sys_##_name_
#define ENTRY_OURS(_name_) .dword sys_##_name_
#define ENTRY_COMP(_name_) .dword sys_##_name_
#else
#define ENTRY_SAME(_name_) .word sys_##_name_
#define ENTRY_DIFF(_name_) .word sys_##_name_
#define ENTRY_UHOH(_name_) .word sys_##_name_
#define ENTRY_OURS(_name_) .word parisc_##_name_
#define ENTRY_COMP(_name_) .word sys_##_name_
#endif
ENTRY_SAME(ni_syscall) /* 0 - old "setup()" system call*/
ENTRY_SAME(exit)
ENTRY_SAME(fork_wrapper)
ENTRY_SAME(read)
ENTRY_SAME(write)
ENTRY_SAME(open) /* 5 */
ENTRY_SAME(close)
ENTRY_SAME(waitpid)
ENTRY_SAME(creat)
ENTRY_SAME(link)
ENTRY_SAME(unlink) /* 10 */
ENTRY_DIFF(execve_wrapper)
ENTRY_SAME(chdir)
/* See comments in kernel/time.c!!! Maybe we don't need this? */
ENTRY_DIFF(time)
ENTRY_SAME(mknod)
ENTRY_SAME(chmod) /* 15 */
ENTRY_SAME(lchown)
ENTRY_SAME(socket)
/* struct stat is MAYBE identical wide and narrow ?? */
ENTRY_COMP(newstat)
ENTRY_DIFF(lseek)
ENTRY_SAME(getpid) /* 20 */
/* the 'void * data' parameter may need re-packing in wide */
ENTRY_DIFF(mount)
/* concerned about struct sockaddr in wide/narrow */
/* ---> I think sockaddr is OK unless the compiler packs the struct */
/* differently to align the char array */
ENTRY_SAME(bind)
ENTRY_SAME(setuid)
ENTRY_SAME(getuid)
ENTRY_SAME(stime) /* 25 */
ENTRY_SAME(ptrace)
ENTRY_SAME(alarm)
/* see stat comment */
ENTRY_COMP(newfstat)
ENTRY_SAME(pause)
/* struct utimbuf uses time_t which might vary */
ENTRY_COMP(utime) /* 30 */
/* struct sockaddr... */
ENTRY_SAME(connect)
ENTRY_SAME(listen)
ENTRY_SAME(access)
ENTRY_SAME(nice)
/* struct sockaddr... */
ENTRY_SAME(accept) /* 35 */
ENTRY_SAME(sync)
ENTRY_SAME(kill)
ENTRY_SAME(rename)
ENTRY_SAME(mkdir)
ENTRY_SAME(rmdir) /* 40 */
ENTRY_SAME(dup)
ENTRY_SAME(pipe)
ENTRY_COMP(times)
/* struct sockaddr... */
ENTRY_SAME(getsockname)
/* it seems possible brk() could return a >4G pointer... */
ENTRY_SAME(brk) /* 45 */
ENTRY_SAME(setgid)
ENTRY_SAME(getgid)
ENTRY_SAME(signal)
ENTRY_SAME(geteuid)
ENTRY_SAME(getegid) /* 50 */
ENTRY_SAME(acct)
ENTRY_SAME(umount)
/* struct sockaddr... */
ENTRY_SAME(getpeername)
ENTRY_COMP(ioctl)
ENTRY_COMP(fcntl) /* 55 */
ENTRY_SAME(socketpair)
ENTRY_SAME(setpgid)
ENTRY_SAME(send)
ENTRY_SAME(newuname)
ENTRY_SAME(umask) /* 60 */
ENTRY_SAME(chroot)
ENTRY_SAME(ustat)
ENTRY_SAME(dup2)
ENTRY_SAME(getppid)
ENTRY_SAME(getpgrp) /* 65 */
ENTRY_SAME(setsid)
ENTRY_SAME(pivot_root)
/* I don't like this */
ENTRY_UHOH(sgetmask)
ENTRY_UHOH(ssetmask)
ENTRY_SAME(setreuid) /* 70 */
ENTRY_SAME(setregid)
ENTRY_SAME(mincore)
ENTRY_COMP(sigpending)
ENTRY_SAME(sethostname)
/* Following 3 have linux-common-code structs containing longs -( */
ENTRY_COMP(setrlimit) /* 75 */
ENTRY_COMP(getrlimit)
ENTRY_COMP(getrusage)
/* struct timeval and timezone are maybe?? consistent wide and narrow */
ENTRY_DIFF(gettimeofday)
ENTRY_DIFF(settimeofday)
ENTRY_SAME(getgroups) /* 80 */
ENTRY_SAME(setgroups)
/* struct socketaddr... */
ENTRY_SAME(sendto)
ENTRY_SAME(symlink)
/* see stat comment */
ENTRY_COMP(newlstat)
ENTRY_SAME(readlink) /* 85 */
ENTRY_SAME(ni_syscall) /* was uselib */
ENTRY_SAME(swapon)
ENTRY_SAME(reboot)
ENTRY_SAME(mmap2)
ENTRY_SAME(mmap) /* 90 */
ENTRY_SAME(munmap)
ENTRY_SAME(truncate)
ENTRY_SAME(ftruncate)
ENTRY_SAME(fchmod)
ENTRY_SAME(fchown) /* 95 */
ENTRY_SAME(getpriority)
ENTRY_SAME(setpriority)
ENTRY_SAME(recv)
ENTRY_COMP(statfs)
ENTRY_COMP(fstatfs) /* 100 */
ENTRY_SAME(stat64)
ENTRY_SAME(ni_syscall) /* was socketcall */
ENTRY_SAME(syslog)
/* even though manpage says struct timeval contains longs, ours has
* time_t and suseconds_t -- both of which are safe wide/narrow */
ENTRY_COMP(setitimer)
ENTRY_COMP(getitimer) /* 105 */
ENTRY_SAME(capget)
ENTRY_SAME(capset)
ENTRY_OURS(pread64)
ENTRY_OURS(pwrite64)
ENTRY_SAME(getcwd) /* 110 */
ENTRY_SAME(vhangup)
ENTRY_SAME(fstat64)
ENTRY_SAME(vfork_wrapper)
/* struct rusage contains longs... */
ENTRY_COMP(wait4)
ENTRY_SAME(swapoff) /* 115 */
ENTRY_DIFF(sysinfo)
ENTRY_SAME(shutdown)
ENTRY_SAME(fsync)
ENTRY_SAME(madvise)
ENTRY_SAME(clone_wrapper) /* 120 */
ENTRY_SAME(setdomainname)
ENTRY_DIFF(sendfile)
/* struct sockaddr... */
ENTRY_SAME(recvfrom)
/* struct timex contains longs */
ENTRY_DIFF(adjtimex)
ENTRY_SAME(mprotect) /* 125 */
/* old_sigset_t forced to 32 bits. Beware glibc sigset_t */
ENTRY_COMP(sigprocmask)
ENTRY_SAME(ni_syscall) /* create_module */
ENTRY_SAME(init_module)
ENTRY_SAME(delete_module)
ENTRY_SAME(ni_syscall) /* 130: get_kernel_syms */
/* time_t inside struct dqblk */
ENTRY_SAME(quotactl)
ENTRY_SAME(getpgid)
ENTRY_SAME(fchdir)
ENTRY_SAME(bdflush)
ENTRY_SAME(sysfs) /* 135 */
ENTRY_SAME(personality)
ENTRY_SAME(ni_syscall) /* for afs_syscall */
ENTRY_SAME(setfsuid)
ENTRY_SAME(setfsgid)
/* I think this might work */
ENTRY_SAME(llseek) /* 140 */
/* struct linux_dirent has longs, like 'unsigned long d_ino' which
* almost definitely should be 'ino_t d_ino' but it's too late now */
ENTRY_DIFF(getdents)
/* it is POSSIBLE that select will be OK because even though fd_set
* contains longs, the macros and sizes are clever. */
ENTRY_DIFF(select)
ENTRY_SAME(flock)
ENTRY_SAME(msync)
/* struct iovec contains pointers */
ENTRY_DIFF(readv) /* 145 */
ENTRY_DIFF(writev)
ENTRY_SAME(getsid)
ENTRY_SAME(fdatasync)
/* struct __sysctl_args is a mess */
ENTRY_DIFF(sysctl)
ENTRY_SAME(mlock) /* 150 */
ENTRY_SAME(munlock)
ENTRY_SAME(mlockall)
ENTRY_SAME(munlockall)
/* struct sched_param is ok for now */
ENTRY_SAME(sched_setparam)
ENTRY_SAME(sched_getparam) /* 155 */
ENTRY_SAME(sched_setscheduler)
ENTRY_SAME(sched_getscheduler)
ENTRY_SAME(sched_yield)
ENTRY_SAME(sched_get_priority_max)
ENTRY_SAME(sched_get_priority_min) /* 160 */
/* These 2 would've worked if someone had defined struct timespec
* carefully, like timeval for example (which is about the same).
* Unfortunately it contains a long :-( */
ENTRY_DIFF(sched_rr_get_interval)
ENTRY_COMP(nanosleep)
ENTRY_SAME(mremap)
ENTRY_SAME(setresuid)
ENTRY_SAME(getresuid) /* 165 */
ENTRY_DIFF(sigaltstack_wrapper)
ENTRY_SAME(ni_syscall) /* query_module */
ENTRY_SAME(poll)
/* structs contain pointers and an in_addr... */
ENTRY_DIFF(nfsservctl)
ENTRY_SAME(setresgid) /* 170 */
ENTRY_SAME(getresgid)
ENTRY_SAME(prctl)
/* signals need a careful review */
ENTRY_SAME(rt_sigreturn_wrapper)
ENTRY_DIFF(rt_sigaction)
ENTRY_DIFF(rt_sigprocmask) /* 175 */
ENTRY_DIFF(rt_sigpending)
ENTRY_UHOH(rt_sigtimedwait)
/* even though the struct siginfo_t is different, it appears like
* all the paths use values which should be same wide and narrow.
* Also the struct is padded to 128 bytes which means we don't have
* to worry about faulting trying to copy in a larger 64-bit
* struct from a 32-bit user-space app.
*/
ENTRY_SAME(rt_sigqueueinfo)
ENTRY_SAME(rt_sigsuspend_wrapper) /* not really SAME -- see the code */
ENTRY_SAME(chown) /* 180 */
/* setsockopt() used by iptables: SO_SET_REPLACE/SO_SET_ADD_COUNTERS */
ENTRY_COMP(setsockopt)
ENTRY_SAME(getsockopt)
ENTRY_COMP(sendmsg)
ENTRY_COMP(recvmsg)
ENTRY_SAME(semop) /* 185 */
ENTRY_SAME(semget)
ENTRY_DIFF(semctl_broken)
ENTRY_DIFF(msgsnd)
ENTRY_DIFF(msgrcv)
ENTRY_SAME(msgget) /* 190 */
ENTRY_SAME(msgctl_broken)
ENTRY_SAME(shmat_wrapper)
ENTRY_SAME(shmdt)
ENTRY_SAME(shmget)
ENTRY_SAME(shmctl_broken) /* 195 */
ENTRY_SAME(ni_syscall) /* streams1 */
ENTRY_SAME(ni_syscall) /* streams2 */
ENTRY_SAME(lstat64)
ENTRY_OURS(truncate64)
ENTRY_OURS(ftruncate64) /* 200 */
ENTRY_SAME(getdents64)
ENTRY_COMP(fcntl64)
ENTRY_SAME(ni_syscall)
ENTRY_SAME(ni_syscall)
ENTRY_SAME(ni_syscall) /* 205 */
ENTRY_SAME(gettid)
ENTRY_OURS(readahead)
ENTRY_SAME(ni_syscall) /* tkill */
ENTRY_SAME(sendfile64)
ENTRY_COMP(futex) /* 210 */
ENTRY_COMP(sched_setaffinity)
ENTRY_COMP(sched_getaffinity)
ENTRY_SAME(ni_syscall)
ENTRY_SAME(ni_syscall)
ENTRY_SAME(io_setup) /* 215 */
ENTRY_SAME(io_destroy)
ENTRY_SAME(io_getevents)
ENTRY_SAME(io_submit)
ENTRY_SAME(io_cancel)
ENTRY_SAME(alloc_hugepages) /* 220 */
ENTRY_SAME(free_hugepages)
ENTRY_SAME(exit_group)
ENTRY_DIFF(lookup_dcookie)
ENTRY_SAME(epoll_create)
ENTRY_SAME(epoll_ctl) /* 225 */
ENTRY_SAME(epoll_wait)
ENTRY_SAME(remap_file_pages)
......@@ -48,7 +48,9 @@ static inline void
parisc_do_profile(struct pt_regs *regs)
{
unsigned long pc = regs->iaoq[0];
#if 0
extern unsigned long prof_cpu_mask;
#endif
extern char _stext;
profile_hook(regs);
......@@ -60,6 +62,10 @@ parisc_do_profile(struct pt_regs *regs)
return;
#if 0
/* FIXME: when we have irq affinity to cpu, we need to
* only look at the cpus specified in this mask
*/
if (!((1 << smp_processor_id()) & prof_cpu_mask))
return;
#endif
......@@ -206,7 +212,6 @@ do_settimeofday (struct timespec *tv)
* done, and then undo it!
*/
nsec -= gettimeoffset() * 1000;
nsec -= (jiffies - wall_jiffies) * (NSEC_PER_SEC / HZ);
wtm_sec = wall_to_monotonic.tv_sec + (xtime.tv_sec - sec);
wtm_nsec = wall_to_monotonic.tv_nsec + (xtime.tv_nsec - nsec);
......@@ -223,6 +228,16 @@ do_settimeofday (struct timespec *tv)
return 0;
}
/*
* XXX: We can do better than this.
* Returns nanoseconds
*/
unsigned long long sched_clock(void)
{
return (unsigned long long)jiffies * (1000000000 / HZ);
}
void __init time_init(void)
{
......
......@@ -678,12 +678,13 @@ void handle_interruption(int code, struct pt_regs *regs)
}
if (user_mode(regs)) {
if (fault_space != regs->sr[7]) {
if ((fault_space>>SPACEID_SHIFT) != (regs->sr[7] >> SPACEID_SHIFT)) {
#ifdef PRINT_USER_FAULTS
if (fault_space == 0)
printk(KERN_DEBUG "User Fault on Kernel Space ");
else
printk(KERN_DEBUG "User Fault (long pointer) ");
printk(KERN_DEBUG "User Fault (long pointer) (fault %d) ",
code);
printk("pid=%d command='%s'\n", current->pid, current->comm);
show_regs(regs);
#endif
......
......@@ -369,8 +369,8 @@ static int emulate_std(struct pt_regs *regs, int frreg, int flop)
void handle_unaligned(struct pt_regs *regs)
{
unsigned long unaligned_count = 0;
unsigned long last_time = 0;
static unsigned long unaligned_count = 0;
static unsigned long last_time = 0;
unsigned long newbase = R1(regs->iir)?regs->gr[R1(regs->iir)]:0;
int modify = 0;
int ret = -1;
......@@ -380,7 +380,6 @@ void handle_unaligned(struct pt_regs *regs)
/* if the unaligned access is inside the kernel:
* if the access is caused by a syscall, then we fault the calling
* user process
* otherwise we halt the kernel
*/
if (!user_mode(regs))
{
......@@ -427,10 +426,10 @@ void handle_unaligned(struct pt_regs *regs)
show_regs(regs);
#endif
}
}
if (!unaligned_enabled)
goto force_sigbus;
if (!unaligned_enabled)
goto force_sigbus;
}
/* handle modification - OK, it's ugly, see the instruction manual */
switch (MAJOR_OP(regs->iir))
......
......@@ -16,8 +16,10 @@
*
* $Id: checksum.c,v 1.3 1997/12/01 17:57:34 ralf Exp $
*/
#include <net/checksum.h>
#include <linux/module.h>
#include <linux/types.h>
#include <net/checksum.h>
#include <asm/byteorder.h>
#include <asm/string.h>
#include <asm/uaccess.h>
......@@ -109,6 +111,7 @@ unsigned int csum_partial_copy_nocheck(const char *src, char *dst,
return sum;
}
EXPORT_SYMBOL(csum_partial_copy_nocheck);
/*
* Copy from userspace and compute checksum. If we catch an exception
......@@ -128,3 +131,4 @@ unsigned int csum_partial_copy_from_user (const char *src, char *dst,
return csum_partial(dst, len, sum);
}
EXPORT_SYMBOL(csum_partial_copy_from_user);
......@@ -8,6 +8,7 @@
*/
#include <linux/kernel.h>
#include <linux/module.h>
#include <asm/io.h>
/* Copies a block of memory to a device in an efficient manner.
......@@ -457,3 +458,10 @@ void outsl (unsigned long port, const void *src, unsigned long count)
break;
}
}
EXPORT_SYMBOL(insb);
EXPORT_SYMBOL(insw);
EXPORT_SYMBOL(insl);
EXPORT_SYMBOL(outsb);
EXPORT_SYMBOL(outsw);
EXPORT_SYMBOL(outsl);
......@@ -2,6 +2,11 @@
# Makefile for the linux/parisc floating point code
#
# See arch/parisc/math-emu/README
CFLAGS += -Wno-parentheses -Wno-implicit-function-declaration \
-Wno-uninitialized -Wno-strict-prototypes -Wno-return-type \
-Wno-implicit-int
obj-y := frnd.o driver.o decode_exc.o fpudispatch.o denormal.o \
dfmpy.o sfmpy.o sfsqrt.o dfsqrt.o dfadd.o fmpyfadd.o \
sfadd.o dfsub.o sfsub.o fcnvfxt.o fcnvff.o fcnvxf.o \
......
......@@ -47,7 +47,7 @@
#include "sgl_float.h"
#include "dbl_float.h"
#include "hppa.h"
#include "types.h"
#include <linux/kernel.h>
/* #include <machine/sys/mdep_private.h> */
#undef Fpustatus_register
......
......@@ -50,7 +50,7 @@
#define FPUDEBUG 0
#include "float.h"
#include "types.h"
#include <linux/kernel.h>
#include <asm/processor.h>
/* #include <sys/debug.h> */
/* #include <machine/sys/mdep_private.h> */
......
/*
* Linux/PA-RISC Project (http://www.parisc-linux.org/)
*
* Floating-point emulation code
* Copyright (C) 2001 Hewlett-Packard (Paul Bame) <bame@debian.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <linux/kernel.h>
#define BUG() do { \
printk(KERN_ERR "floating-pt emulation BUG at %s:%d!\n", __FILE__, __LINE__); \
} while (0)
......@@ -430,6 +430,8 @@ void free_initmem(void)
& ~(VM_MAP_OFFSET-1)))
void *vmalloc_start;
EXPORT_SYMBOL(vmalloc_start);
#ifdef CONFIG_PA11
unsigned long pcxl_dma_start;
#endif
......@@ -618,8 +620,6 @@ static void __init pagetable_init(void)
{
int range;
printk("pagetable_init\n");
/* Map each physical memory range to its kernel vaddr */
for (range = 0; range < npmem_ranges; range++) {
......
......@@ -530,11 +530,6 @@ static struct pci_driver superio_driver = {
static int __init superio_modinit(void)
{
#ifdef CONFIG_SERIAL_8250
extern int serial8250_init(void);
serial8250_init();
#endif
return pci_module_init(&superio_driver);
}
......@@ -543,5 +538,10 @@ static void __exit superio_exit(void)
pci_unregister_driver(&superio_driver);
}
module_init(superio_modinit);
/* Make late initcall to ensure the serial and tty layers are initialised
* before we start superio.
*
* FIXME: does this break the superio console?
*/
late_initcall(superio_modinit);
module_exit(superio_exit);
......@@ -988,7 +988,7 @@ static int __devinit sticore_pci_init(struct pci_dev *pd,
if (!sti) {
printk(KERN_WARNING "Unable to handle STI device '%s'\n",
pd->dev.name);
pci_name(pd));
return -ENODEV;
}
#endif /* CONFIG_PCI */
......
......@@ -1238,7 +1238,7 @@ stifb_init_fb(struct sti_struct *sti, int force_bpp)
/* get framebuffer physical and virtual base addr & len (64bit ready) */
fix->smem_start = fb->sti->regions_phys[1] | 0xffffffff00000000;
fix->smem_start = F_EXTEND(fb->sti->regions_phys[1]);
fix->smem_len = fb->sti->regions[1].region_desc.length * 4096;
fix->line_length = (fb->sti->glob_cfg->total_x * bpp) / 8;
......
......@@ -129,8 +129,9 @@ __cmpxchg(volatile void *ptr, unsigned long old, unsigned long new_, int size)
/* It's possible to reduce all atomic operations to either
* __atomic_add_return, __atomic_set and __atomic_ret (the latter
* is there only for consistency). */
* __atomic_add_return, atomic_set and atomic_read (the latter
* is there only for consistency).
*/
static __inline__ int __atomic_add_return(int i, atomic_t *v)
{
......@@ -144,7 +145,7 @@ static __inline__ int __atomic_add_return(int i, atomic_t *v)
return ret;
}
static __inline__ void __atomic_set(atomic_t *v, int i)
static __inline__ void atomic_set(atomic_t *v, int i)
{
unsigned long flags;
SPIN_LOCK_IRQSAVE(ATOMIC_HASH(v), flags);
......@@ -154,28 +155,25 @@ static __inline__ void __atomic_set(atomic_t *v, int i)
SPIN_UNLOCK_IRQRESTORE(ATOMIC_HASH(v), flags);
}
static __inline__ int __atomic_read(atomic_t *v)
static __inline__ int atomic_read(const atomic_t *v)
{
return v->counter;
}
/* exported interface */
#define atomic_add(i,v) ((void)(__atomic_add_return( (i),(v))))
#define atomic_sub(i,v) ((void)(__atomic_add_return(-(i),(v))))
#define atomic_inc(v) ((void)(__atomic_add_return( 1,(v))))
#define atomic_dec(v) ((void)(__atomic_add_return( -1,(v))))
#define atomic_add(i,v) ((void)(__atomic_add_return( ((int)i),(v))))
#define atomic_sub(i,v) ((void)(__atomic_add_return(-((int)i),(v))))
#define atomic_inc(v) ((void)(__atomic_add_return( 1,(v))))
#define atomic_dec(v) ((void)(__atomic_add_return( -1,(v))))
#define atomic_add_return(i,v) (__atomic_add_return( (i),(v)))
#define atomic_sub_return(i,v) (__atomic_add_return(-(i),(v)))
#define atomic_add_return(i,v) (__atomic_add_return( ((int)i),(v)))
#define atomic_sub_return(i,v) (__atomic_add_return(-((int)i),(v)))
#define atomic_inc_return(v) (__atomic_add_return( 1,(v)))
#define atomic_dec_return(v) (__atomic_add_return( -1,(v)))
#define atomic_dec_and_test(v) (atomic_dec_return(v) == 0)
#define atomic_set(v,i) (__atomic_set((v),i))
#define atomic_read(v) (__atomic_read(v))
#define ATOMIC_INIT(i) { (i) }
#define smp_mb__before_atomic_dec() smp_mb()
......
......@@ -232,24 +232,24 @@ static __inline__ unsigned long __ffs(unsigned long x)
#if BITS_PER_LONG > 32
" ldi 63,%1\n"
" extrd,u,*<> %0,63,32,%%r0\n"
" extrd,u,*TR %0,31,32,%0\n"
" extrd,u,*TR %0,31,32,%0\n" /* move top 32-bits down */
" addi -32,%1,%1\n"
#else
" ldi 31,%1\n"
#endif
" extru,<> %0,31,16,%%r0\n"
" extru,TR %0,15,16,%0\n"
" extru,TR %0,15,16,%0\n" /* xxxx0000 -> 0000xxxx */
" addi -16,%1,%1\n"
" extru,<> %0,31,8,%%r0\n"
" extru,TR %0,23,8,%0\n"
" extru,TR %0,23,8,%0\n" /* 0000xx00 -> 000000xx */
" addi -8,%1,%1\n"
" extru,<> %0,31,4,%%r0\n"
" extru,TR %0,27,4,%0\n"
" extru,TR %0,27,4,%0\n" /* 000000x0 -> 0000000x */
" addi -4,%1,%1\n"
" extru,<> %0,31,2,%%r0\n"
" extru,TR %0,29,2,%0\n"
" extru,TR %0,29,2,%0\n" /* 0000000y, 1100b -> 0011b */
" addi -2,%1,%1\n"
" extru,= %0,31,1,%%r0\n"
" extru,= %0,31,1,%%r0\n" /* check last bit */
" addi -1,%1,%1\n"
: "+r" (x), "=r" (ret) );
return ret;
......@@ -291,7 +291,7 @@ static __inline__ int fls(int x)
" zdep,TR %0,27,28,%0\n" /* x0000000 */
" addi 4,%1,%1\n"
" extru,<> %0,1,2,%%r0\n"
" zdep,TR %0,29,30,%0\n" /* y0000000 (y&3 = 0 */
" zdep,TR %0,29,30,%0\n" /* y0000000 (y&3 = 0) */
" addi 2,%1,%1\n"
" extru,= %0,0,1,%%r0\n"
" addi 1,%1,%1\n" /* if y & 8, add 1 */
......
......@@ -2,6 +2,7 @@
#define _PARISC_DMA_MAPPING_H
#include <linux/mm.h>
#include <linux/config.h>
#include <asm/cacheflush.h>
/*
......
......@@ -144,6 +144,30 @@
#define R_PARISC_LTOFF_TP16DF 231 /* 16 bits LT-TP-rel. address. */
#define R_PARISC_HIRESERVE 255
#define PA_PLABEL_FDESC 0x02 /* bit set if PLABEL points to
* a function descriptor, not
* an address */
/* The following are PA function descriptors
*
* addr: the absolute address of the function
* gp: either the data pointer (r27) for non-PIC code or the
* the PLT pointer (r19) for PIC code */
/* Format for the Elf32 Function descriptor */
typedef struct elf32_fdesc {
__u32 addr;
__u32 gp;
} Elf32_Fdesc;
/* Format for the Elf64 Function descriptor */
typedef struct elf64_fdesc {
__u64 dummy[2]; /* FIXME: nothing uses these, why waste
* the space */
__u64 addr;
__u64 gp;
} Elf64_Fdesc;
/* Legal values for p_type field of Elf32_Phdr/Elf64_Phdr. */
#define PT_HP_TLS (PT_LOOS + 0x0)
......@@ -215,7 +239,10 @@ typedef unsigned long elf_greg_t;
#ifdef __KERNEL__
#define SET_PERSONALITY(ex, ibcs2) \
current->personality = PER_LINUX
current->personality = PER_LINUX; \
current->thread.map_base = DEFAULT_MAP_BASE; \
current->thread.task_size = DEFAULT_TASK_SIZE \
#endif
/*
......
......@@ -44,11 +44,21 @@
((nr) << _IOC_NRSHIFT) | \
((size) << _IOC_SIZESHIFT))
/* provoke compile error for invalid uses of size argument */
extern int __invalid_size_argument_for_IOC;
#define _IOC_TYPECHECK(t) \
((sizeof(t) == sizeof(t[1]) && \
sizeof(t) < (1 << _IOC_SIZEBITS)) ? \
sizeof(t) : __invalid_size_argument_for_IOC)
/* used to create numbers */
#define _IO(type,nr) _IOC(_IOC_NONE,(type),(nr),0)
#define _IOR(type,nr,size) _IOC(_IOC_READ,(type),(nr),sizeof(size))
#define _IOW(type,nr,size) _IOC(_IOC_WRITE,(type),(nr),sizeof(size))
#define _IOWR(type,nr,size) _IOC(_IOC_READ|_IOC_WRITE,(type),(nr),sizeof(size))
#define _IOR(type,nr,size) _IOC(_IOC_READ,(type),(nr),(_IOC_TYPECHECK(size)))
#define _IOW(type,nr,size) _IOC(_IOC_WRITE,(type),(nr),(_IOC_TYPECHECK(size)))
#define _IOWR(type,nr,size) _IOC(_IOC_READ|_IOC_WRITE,(type),(nr),(_IOC_TYPECHECK(size)))
#define _IOR_BAD(type,nr,size) _IOC(_IOC_READ,(type),(nr),sizeof(size))
#define _IOW_BAD(type,nr,size) _IOC(_IOC_WRITE,(type),(nr),sizeof(size))
#define _IOWR_BAD(type,nr,size) _IOC(_IOC_READ|_IOC_WRITE,(type),(nr),sizeof(size))
/* used to decode ioctl numbers.. */
#define _IOC_DIR(nr) (((nr) >> _IOC_DIRSHIFT) & _IOC_DIRMASK)
......
......@@ -17,6 +17,7 @@
#include <linux/string.h>
#include <linux/interrupt.h>
#include <linux/config.h>
#define CPU_IRQ_REGION 1
......
......@@ -25,8 +25,6 @@
#ifndef _PARISC_KEYBOARD_H
#define _PARISC_KEYBOARD_H
#include <linux/config.h>
#ifdef __KERNEL__
#include <linux/kernel.h>
......
......@@ -7,6 +7,7 @@
#define PAGE_MASK (~(PAGE_SIZE-1))
#ifdef __KERNEL__
#include <linux/config.h>
#ifndef __ASSEMBLY__
#include <asm/cache.h>
......
......@@ -2,6 +2,7 @@
#define _ASMPARISC_PARAM_H
#ifdef __KERNEL__
#include <linux/config.h>
# ifdef CONFIG_PA20
# define HZ 1000 /* Faster machines */
# else
......
#ifndef __ASM_PARISC_PCI_H
#define __ASM_PARISC_PCI_H
#include <linux/config.h>
#include <asm/scatterlist.h>
/*
......
#ifndef _PARISC_PDC_H
#define _PARISC_PDC_H
#include <linux/config.h>
/*
* PDC return values ...
* All PDC calls return a subset of these errors.
......@@ -191,8 +193,8 @@ typedef struct {
#define PDC_IO 135 /* log error info, reset IO system */
#define PDC_IO_READ_AND_CLEAR_ERRORS 0
#define PDC_IO_READ_AND_LOG_ERRORS 1
#define PDC_IO_SUSPEND_USB 2
#define PDC_IO_RESET 1
#define PDC_IO_RESET_DEVICES 2
/* sets bits 6&7 (little endian) of the HcControl Register */
#define PDC_IO_USB_SUSPEND 0xC000000000000000
#define PDC_IO_EEPROM_IO_ERR_TABLE_FULL -5 /* return value */
......@@ -951,7 +953,8 @@ int pdc_do_firm_test_reset(unsigned long ftc_bitmap);
int pdc_do_reset(void);
int pdc_soft_power_info(unsigned long *power_reg);
int pdc_soft_power_button(int sw_control);
void pdc_suspend_usb(void);
void pdc_io_reset(void);
void pdc_io_reset_devices(void);
int pdc_iodc_getc(void);
void pdc_iodc_putc(unsigned char c);
void pdc_iodc_outc(unsigned char c);
......
#ifndef _ASM_PGALLOC_H
#define _ASM_PGALLOC_H
#include <linux/config.h>
#include <linux/gfp.h>
#include <linux/mm.h>
#include <linux/threads.h>
......
#ifndef _PARISC_PGTABLE_H
#define _PARISC_PGTABLE_H
#include <linux/config.h>
#include <asm/fixmap.h>
#ifndef __ASSEMBLY__
......
......@@ -36,10 +36,18 @@
#define current_text_addr() ({ void *pc; __asm__("\n\tblr 0,%0\n\tnop":"=r" (pc)); pc; })
#define TASK_SIZE (current->thread.task_size)
#define DEFAULT_TASK_SIZE (0xFFF00000UL)
#define TASK_UNMAPPED_BASE (current->thread.map_base)
#define DEFAULT_MAP_BASE (0x40000000UL)
#define DEFAULT_TASK_SIZE32 (0xFFF00000UL)
#define DEFAULT_MAP_BASE32 (0x40000000UL)
#ifdef __LP64__
#define DEFAULT_TASK_SIZE (MAX_ADDRESS-0xf000000)
#define DEFAULT_MAP_BASE (0x200000000UL)
#else
#define DEFAULT_TASK_SIZE DEFAULT_TASK_SIZE32
#define DEFAULT_MAP_BASE DEFAULT_MAP_BASE32
#endif
#ifndef __ASSEMBLY__
......@@ -247,8 +255,18 @@ on downward growing arches, it looks like this:
*
* Note that the S/390 people took the easy way out and hacked their
* GCC to make the stack grow downwards.
*
* Final Note: For entry from syscall, the W (wide) bit of the PSW
* is stuffed into the lowest bit of the user sp (%r30), so we fill
* it in here from the current->personality
*/
#ifdef __LP64__
#define USER_WIDE_MODE (personality(current->personality) == PER_LINUX)
#else
#define USER_WIDE_MODE 0
#endif
#define start_thread(regs, new_pc, new_sp) do { \
elf_addr_t *sp = (elf_addr_t *)new_sp; \
__u32 spaceid = (__u32)current->mm->context; \
......@@ -266,12 +284,12 @@ on downward growing arches, it looks like this:
regs->sr[5] = spaceid; \
regs->sr[6] = spaceid; \
regs->sr[7] = spaceid; \
regs->gr[ 0] = USER_PSW; \
regs->gr[ 0] = USER_PSW | (USER_WIDE_MODE ? PSW_W : 0); \
regs->fr[ 0] = 0LL; \
regs->fr[ 1] = 0LL; \
regs->fr[ 2] = 0LL; \
regs->fr[ 3] = 0LL; \
regs->gr[30] = ((unsigned long)sp + 63) &~ 63; \
regs->gr[30] = (((unsigned long)sp + 63) &~ 63) | (USER_WIDE_MODE ? 1 : 0); \
regs->gr[31] = pc; \
\
get_user(regs->gr[25], (argv - 1)); \
......@@ -299,8 +317,6 @@ static inline unsigned long get_wchan(struct task_struct *p)
#define KSTK_EIP(tsk) ((tsk)->thread.regs.iaoq[0])
#define KSTK_ESP(tsk) ((tsk)->thread.regs.gr[30])
#endif /* __ASSEMBLY__ */
#ifdef CONFIG_PA20
#define ARCH_HAS_PREFETCH
extern inline void prefetch(const void *addr)
......@@ -317,4 +333,6 @@ extern inline void prefetchw(const void *addr)
#define cpu_relax() barrier()
#endif /* __ASSEMBLY__ */
#endif /* __ASM_PARISC_PROCESSOR_H */
......@@ -13,7 +13,20 @@ struct rt_sigframe {
* which Linux/parisc uses is sp-20 for the saved return pointer...)
* Then, the stack pointer must be rounded to a cache line (64 bytes).
*/
#define SIGFRAME32 64
#define FUNCTIONCALLFRAME32 48
#define PARISC_RT_SIGFRAME_SIZE32 \
(((sizeof(struct rt_sigframe) + FUNCTIONCALLFRAME32) + SIGFRAME32) & -SIGFRAME32)
#ifdef __LP64__
#define SIGFRAME 128
#define FUNCTIONCALLFRAME 96
#define PARISC_RT_SIGFRAME_SIZE \
(((sizeof(struct rt_sigframe) + 48) + 63) & -64)
(((sizeof(struct rt_sigframe) + FUNCTIONCALLFRAME) + SIGFRAME) & -SIGFRAME)
#else
#define SIGFRAME SIGFRAME32
#define FUNCTIONCALLFRAME FUNCTIONCALLFRAME32
#define PARISC_RT_SIGFRAME_SIZE PARISC_RT_SIGFRAME_SIZE32
#endif
#endif
......@@ -3,6 +3,7 @@
/* TLB flushing routines.... */
#include <linux/config.h>
#include <linux/mm.h>
#include <asm/mmu_context.h>
......
......@@ -198,6 +198,8 @@ static inline int _snd_magic_bad(void *obj, unsigned long magic)
#define vx_pipe_t_magic 0xa15a4112
#define azf3328_t_magic 0xa15a4200
#define snd_card_harmony_t_magic 0xa15a4300
#else
#define snd_magic_kcalloc(type, extra, flags) (type *) snd_kcalloc(sizeof(type) + extra, flags)
......
......@@ -28,14 +28,14 @@
#include <linux/delay.h>
#include <linux/errno.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/ioport.h>
#include <linux/types.h>
#include <linux/mm.h>
#include <linux/pci.h>
#include <asm/gsc.h>
#include <asm/parisc-device.h>
#include <asm/io.h>
#include <asm/pgalloc.h>
#include "sound_config.h"
......
......@@ -66,6 +66,7 @@
#include <linux/delay.h>
#include <sound/driver.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/slab.h>
#include <linux/time.h>
#include <linux/wait.h>
......@@ -77,8 +78,8 @@
#include <sound/initval.h>
#include <sound/info.h>
#include <asm/hardware.h>
#include <asm/gsc.h>
#include <asm/io.h>
#include <asm/parisc-device.h>
MODULE_AUTHOR("Laurent Canet <canetl@esiee.fr>");
MODULE_DESCRIPTION("ALSA Harmony sound driver");
......@@ -709,8 +710,8 @@ static int snd_card_harmony_playback_open(snd_pcm_substream_t * substream)
* harmony is not "real" pci, but we need a pci_dev
* to alloc PCI DMA pages
*/
substream->dma_private = harmony->fake_pci_dev;
substream->dma_type = SNDRV_PCM_DMA_TYPE_PCI;
substream->runtime->dma_private = harmony->fake_pci_dev;
// substream->dma_type = SNDRV_PCM_DMA_TYPE_PCI;
harmony->playback_substream = substream;
runtime->hw = snd_card_harmony_playback;
......@@ -733,8 +734,8 @@ static int snd_card_harmony_capture_open(snd_pcm_substream_t * substream)
* harmony is not "real" pci, but we need a pci_dev
* to alloc PCI DMA pages
*/
substream->dma_private = harmony->fake_pci_dev;
substream->dma_type = SNDRV_PCM_DMA_TYPE_PCI;
substream->runtime->dma_private = harmony->fake_pci_dev;
// substream->dma_type = SNDRV_PCM_DMA_TYPE_PCI;
harmony->capture_substream = substream;
runtime->hw = snd_card_harmony_capture;
......
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