diff options
Diffstat (limited to 'arch/sparc')
-rw-r--r-- | arch/sparc/Makefile | 3 | ||||
-rw-r--r-- | arch/sparc/boot/Makefile | 4 | ||||
-rw-r--r-- | arch/sparc/boot/install.sh | 50 | ||||
-rw-r--r-- | arch/sparc/include/asm/io_64.h | 381 | ||||
-rw-r--r-- | arch/sparc/include/asm/tlbflush_64.h | 12 | ||||
-rw-r--r-- | arch/sparc/kernel/ldc.c | 2 | ||||
-rw-r--r-- | arch/sparc/kernel/mdesc.c | 82 | ||||
-rw-r--r-- | arch/sparc/kernel/unaligned_32.c | 2 | ||||
-rw-r--r-- | arch/sparc/lib/PeeCeeI.c | 36 | ||||
-rw-r--r-- | arch/sparc/math-emu/math_32.c | 2 | ||||
-rw-r--r-- | arch/sparc/mm/init_64.c | 96 |
11 files changed, 390 insertions, 280 deletions
diff --git a/arch/sparc/Makefile b/arch/sparc/Makefile index 9ff4236..eaee146 100644 --- a/arch/sparc/Makefile +++ b/arch/sparc/Makefile @@ -68,6 +68,9 @@ all: zImage image zImage uImage tftpboot.img vmlinux.aout: vmlinux $(Q)$(MAKE) $(build)=$(boot) $(boot)/$@ +install: + $(Q)$(MAKE) $(build)=$(boot) $@ + archclean: $(Q)$(MAKE) $(clean)=$(boot) diff --git a/arch/sparc/boot/Makefile b/arch/sparc/boot/Makefile index 6e63afb..6a4ceae 100644 --- a/arch/sparc/boot/Makefile +++ b/arch/sparc/boot/Makefile @@ -69,3 +69,7 @@ $(obj)/image: vmlinux FORCE $(obj)/tftpboot.img: $(obj)/image $(obj)/piggyback System.map $(ROOT_IMG) FORCE $(call if_changed,elftoaout) $(call if_changed,piggy) + +install: + sh $(srctree)/$(src)/install.sh $(KERNELRELEASE) $(obj)/zImage \ + System.map "$(INSTALL_PATH)" diff --git a/arch/sparc/boot/install.sh b/arch/sparc/boot/install.sh new file mode 100644 index 0000000..b32851e --- /dev/null +++ b/arch/sparc/boot/install.sh @@ -0,0 +1,50 @@ +#!/bin/sh +# +# This file is subject to the terms and conditions of the GNU General Public +# License. See the file "COPYING" in the main directory of this archive +# for more details. +# +# Copyright (C) 1995 by Linus Torvalds +# +# Adapted from code in arch/i386/boot/Makefile by H. Peter Anvin +# +# "make install" script for SPARC architecture +# +# Arguments: +# $1 - kernel version +# $2 - kernel image file +# $3 - kernel map file +# $4 - default install path (blank if root directory) +# + +verify () { + if [ ! -f "$1" ]; then + echo "" 1>&2 + echo " *** Missing file: $1" 1>&2 + echo ' *** You need to run "make" before "make install".' 1>&2 + echo "" 1>&2 + exit 1 + fi +} + +# Make sure the files actually exist +verify "$2" +verify "$3" + +# User may have a custom install script + +if [ -x ~/bin/${INSTALLKERNEL} ]; then exec ~/bin/${INSTALLKERNEL} "$@"; fi +if [ -x /sbin/${INSTALLKERNEL} ]; then exec /sbin/${INSTALLKERNEL} "$@"; fi + +# Default install - same as make zlilo + +if [ -f $4/vmlinuz ]; then + mv $4/vmlinuz $4/vmlinuz.old +fi + +if [ -f $4/System.map ]; then + mv $4/System.map $4/System.old +fi + +cat $2 > $4/vmlinuz +cp $3 $4/System.map diff --git a/arch/sparc/include/asm/io_64.h b/arch/sparc/include/asm/io_64.h index 05381c3..80b54b3 100644 --- a/arch/sparc/include/asm/io_64.h +++ b/arch/sparc/include/asm/io_64.h @@ -9,125 +9,99 @@ #include <asm/asi.h> #include <asm-generic/pci_iomap.h> -/* PC crapola... */ -#define __SLOW_DOWN_IO do { } while (0) -#define SLOW_DOWN_IO do { } while (0) - /* BIO layer definitions. */ extern unsigned long kern_base, kern_size; -static inline u8 _inb(unsigned long addr) +/* __raw_{read,write}{b,w,l,q} uses direct access. + * Access the memory as big endian bypassing the cache + * by using ASI_PHYS_BYPASS_EC_E + */ +#define __raw_readb __raw_readb +static inline u8 __raw_readb(const volatile void __iomem *addr) { u8 ret; - __asm__ __volatile__("lduba\t[%1] %2, %0\t/* pci_inb */" + __asm__ __volatile__("lduba\t[%1] %2, %0\t/* pci_raw_readb */" : "=r" (ret) - : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L) - : "memory"); + : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E)); return ret; } -static inline u16 _inw(unsigned long addr) +#define __raw_readw __raw_readw +static inline u16 __raw_readw(const volatile void __iomem *addr) { u16 ret; - __asm__ __volatile__("lduha\t[%1] %2, %0\t/* pci_inw */" + __asm__ __volatile__("lduha\t[%1] %2, %0\t/* pci_raw_readw */" : "=r" (ret) - : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L) - : "memory"); + : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E)); return ret; } -static inline u32 _inl(unsigned long addr) +#define __raw_readl __raw_readl +static inline u32 __raw_readl(const volatile void __iomem *addr) { u32 ret; - __asm__ __volatile__("lduwa\t[%1] %2, %0\t/* pci_inl */" + __asm__ __volatile__("lduwa\t[%1] %2, %0\t/* pci_raw_readl */" : "=r" (ret) - : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L) - : "memory"); + : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E)); return ret; } -static inline void _outb(u8 b, unsigned long addr) -{ - __asm__ __volatile__("stba\t%r0, [%1] %2\t/* pci_outb */" - : /* no outputs */ - : "Jr" (b), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L) - : "memory"); -} - -static inline void _outw(u16 w, unsigned long addr) +#define __raw_readq __raw_readq +static inline u64 __raw_readq(const volatile void __iomem *addr) { - __asm__ __volatile__("stha\t%r0, [%1] %2\t/* pci_outw */" - : /* no outputs */ - : "Jr" (w), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L) - : "memory"); -} - -static inline void _outl(u32 l, unsigned long addr) -{ - __asm__ __volatile__("stwa\t%r0, [%1] %2\t/* pci_outl */" - : /* no outputs */ - : "Jr" (l), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L) - : "memory"); -} - -#define inb(__addr) (_inb((unsigned long)(__addr))) -#define inw(__addr) (_inw((unsigned long)(__addr))) -#define inl(__addr) (_inl((unsigned long)(__addr))) -#define outb(__b, __addr) (_outb((u8)(__b), (unsigned long)(__addr))) -#define outw(__w, __addr) (_outw((u16)(__w), (unsigned long)(__addr))) -#define outl(__l, __addr) (_outl((u32)(__l), (unsigned long)(__addr))) - -#define inb_p(__addr) inb(__addr) -#define outb_p(__b, __addr) outb(__b, __addr) -#define inw_p(__addr) inw(__addr) -#define outw_p(__w, __addr) outw(__w, __addr) -#define inl_p(__addr) inl(__addr) -#define outl_p(__l, __addr) outl(__l, __addr) + u64 ret; -void outsb(unsigned long, const void *, unsigned long); -void outsw(unsigned long, const void *, unsigned long); -void outsl(unsigned long, const void *, unsigned long); -void insb(unsigned long, void *, unsigned long); -void insw(unsigned long, void *, unsigned long); -void insl(unsigned long, void *, unsigned long); + __asm__ __volatile__("ldxa\t[%1] %2, %0\t/* pci_raw_readq */" + : "=r" (ret) + : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E)); -static inline void ioread8_rep(void __iomem *port, void *buf, unsigned long count) -{ - insb((unsigned long __force)port, buf, count); -} -static inline void ioread16_rep(void __iomem *port, void *buf, unsigned long count) -{ - insw((unsigned long __force)port, buf, count); + return ret; } -static inline void ioread32_rep(void __iomem *port, void *buf, unsigned long count) +#define __raw_writeb __raw_writeb +static inline void __raw_writeb(u8 b, const volatile void __iomem *addr) { - insl((unsigned long __force)port, buf, count); + __asm__ __volatile__("stba\t%r0, [%1] %2\t/* pci_raw_writeb */" + : /* no outputs */ + : "Jr" (b), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E)); } -static inline void iowrite8_rep(void __iomem *port, const void *buf, unsigned long count) +#define __raw_writew __raw_writew +static inline void __raw_writew(u16 w, const volatile void __iomem *addr) { - outsb((unsigned long __force)port, buf, count); + __asm__ __volatile__("stha\t%r0, [%1] %2\t/* pci_raw_writew */" + : /* no outputs */ + : "Jr" (w), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E)); } -static inline void iowrite16_rep(void __iomem *port, const void *buf, unsigned long count) +#define __raw_writel __raw_writel +static inline void __raw_writel(u32 l, const volatile void __iomem *addr) { - outsw((unsigned long __force)port, buf, count); + __asm__ __volatile__("stwa\t%r0, [%1] %2\t/* pci_raw_writel */" + : /* no outputs */ + : "Jr" (l), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E)); } -static inline void iowrite32_rep(void __iomem *port, const void *buf, unsigned long count) +#define __raw_writeq __raw_writeq +static inline void __raw_writeq(u64 q, const volatile void __iomem *addr) { - outsl((unsigned long __force)port, buf, count); + __asm__ __volatile__("stxa\t%r0, [%1] %2\t/* pci_raw_writeq */" + : /* no outputs */ + : "Jr" (q), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E)); } -/* Memory functions, same as I/O accesses on Ultra. */ -static inline u8 _readb(const volatile void __iomem *addr) +/* Memory functions, same as I/O accesses on Ultra. + * Access memory as little endian bypassing + * the cache by using ASI_PHYS_BYPASS_EC_E_L + */ +#define readb readb +static inline u8 readb(const volatile void __iomem *addr) { u8 ret; __asm__ __volatile__("lduba\t[%1] %2, %0\t/* pci_readb */" @@ -137,7 +111,8 @@ static inline u8 _readb(const volatile void __iomem *addr) return ret; } -static inline u16 _readw(const volatile void __iomem *addr) +#define readw readw +static inline u16 readw(const volatile void __iomem *addr) { u16 ret; __asm__ __volatile__("lduha\t[%1] %2, %0\t/* pci_readw */" @@ -148,7 +123,8 @@ static inline u16 _readw(const volatile void __iomem *addr) return ret; } -static inline u32 _readl(const volatile void __iomem *addr) +#define readl readl +static inline u32 readl(const volatile void __iomem *addr) { u32 ret; __asm__ __volatile__("lduwa\t[%1] %2, %0\t/* pci_readl */" @@ -159,7 +135,8 @@ static inline u32 _readl(const volatile void __iomem *addr) return ret; } -static inline u64 _readq(const volatile void __iomem *addr) +#define readq readq +static inline u64 readq(const volatile void __iomem *addr) { u64 ret; __asm__ __volatile__("ldxa\t[%1] %2, %0\t/* pci_readq */" @@ -170,7 +147,8 @@ static inline u64 _readq(const volatile void __iomem *addr) return ret; } -static inline void _writeb(u8 b, volatile void __iomem *addr) +#define writeb writeb +static inline void writeb(u8 b, volatile void __iomem *addr) { __asm__ __volatile__("stba\t%r0, [%1] %2\t/* pci_writeb */" : /* no outputs */ @@ -178,7 +156,8 @@ static inline void _writeb(u8 b, volatile void __iomem *addr) : "memory"); } -static inline void _writew(u16 w, volatile void __iomem *addr) +#define writew writew +static inline void writew(u16 w, volatile void __iomem *addr) { __asm__ __volatile__("stha\t%r0, [%1] %2\t/* pci_writew */" : /* no outputs */ @@ -186,7 +165,8 @@ static inline void _writew(u16 w, volatile void __iomem *addr) : "memory"); } -static inline void _writel(u32 l, volatile void __iomem *addr) +#define writel writel +static inline void writel(u32 l, volatile void __iomem *addr) { __asm__ __volatile__("stwa\t%r0, [%1] %2\t/* pci_writel */" : /* no outputs */ @@ -194,7 +174,8 @@ static inline void _writel(u32 l, volatile void __iomem *addr) : "memory"); } -static inline void _writeq(u64 q, volatile void __iomem *addr) +#define writeq writeq +static inline void writeq(u64 q, volatile void __iomem *addr) { __asm__ __volatile__("stxa\t%r0, [%1] %2\t/* pci_writeq */" : /* no outputs */ @@ -202,100 +183,91 @@ static inline void _writeq(u64 q, volatile void __iomem *addr) : "memory"); } -#define readb(__addr) _readb(__addr) -#define readw(__addr) _readw(__addr) -#define readl(__addr) _readl(__addr) -#define readq(__addr) _readq(__addr) -#define readb_relaxed(__addr) _readb(__addr) -#define readw_relaxed(__addr) _readw(__addr) -#define readl_relaxed(__addr) _readl(__addr) -#define readq_relaxed(__addr) _readq(__addr) -#define writeb(__b, __addr) _writeb(__b, __addr) -#define writew(__w, __addr) _writew(__w, __addr) -#define writel(__l, __addr) _writel(__l, __addr) -#define writeq(__q, __addr) _writeq(__q, __addr) -/* Now versions without byte-swapping. */ -static inline u8 _raw_readb(unsigned long addr) +#define inb inb +static inline u8 inb(unsigned long addr) { - u8 ret; - - __asm__ __volatile__("lduba\t[%1] %2, %0\t/* pci_raw_readb */" - : "=r" (ret) - : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E)); - - return ret; + return readb((volatile void __iomem *)addr); } -static inline u16 _raw_readw(unsigned long addr) +#define inw inw +static inline u16 inw(unsigned long addr) { - u16 ret; - - __asm__ __volatile__("lduha\t[%1] %2, %0\t/* pci_raw_readw */" - : "=r" (ret) - : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E)); - - return ret; + return readw((volatile void __iomem *)addr); } -static inline u32 _raw_readl(unsigned long addr) +#define inl inl +static inline u32 inl(unsigned long addr) { - u32 ret; + return readl((volatile void __iomem *)addr); +} - __asm__ __volatile__("lduwa\t[%1] %2, %0\t/* pci_raw_readl */" - : "=r" (ret) - : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E)); +#define outb outb +static inline void outb(u8 b, unsigned long addr) +{ + writeb(b, (volatile void __iomem *)addr); +} - return ret; +#define outw outw +static inline void outw(u16 w, unsigned long addr) +{ + writew(w, (volatile void __iomem *)addr); } -static inline u64 _raw_readq(unsigned long addr) +#define outl outl +static inline void outl(u32 l, unsigned long addr) { - u64 ret; + writel(l, (volatile void __iomem *)addr); +} - __asm__ __volatile__("ldxa\t[%1] %2, %0\t/* pci_raw_readq */" - : "=r" (ret) - : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E)); - return ret; +#define inb_p(__addr) inb(__addr) +#define outb_p(__b, __addr) outb(__b, __addr) +#define inw_p(__addr) inw(__addr) +#define outw_p(__w, __addr) outw(__w, __addr) +#define inl_p(__addr) inl(__addr) +#define outl_p(__l, __addr) outl(__l, __addr) + +void outsb(unsigned long, const void *, unsigned long); +void outsw(unsigned long, const void *, unsigned long); +void outsl(unsigned long, const void *, unsigned long); +void insb(unsigned long, void *, unsigned long); +void insw(unsigned long, void *, unsigned long); +void insl(unsigned long, void *, unsigned long); + +static inline void ioread8_rep(void __iomem *port, void *buf, unsigned long count) +{ + insb((unsigned long __force)port, buf, count); +} +static inline void ioread16_rep(void __iomem *port, void *buf, unsigned long count) +{ + insw((unsigned long __force)port, buf, count); } -static inline void _raw_writeb(u8 b, unsigned long addr) +static inline void ioread32_rep(void __iomem *port, void *buf, unsigned long count) { - __asm__ __volatile__("stba\t%r0, [%1] %2\t/* pci_raw_writeb */" - : /* no outputs */ - : "Jr" (b), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E)); + insl((unsigned long __force)port, buf, count); } -static inline void _raw_writew(u16 w, unsigned long addr) +static inline void iowrite8_rep(void __iomem *port, const void *buf, unsigned long count) { - __asm__ __volatile__("stha\t%r0, [%1] %2\t/* pci_raw_writew */" - : /* no outputs */ - : "Jr" (w), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E)); + outsb((unsigned long __force)port, buf, count); } -static inline void _raw_writel(u32 l, unsigned long addr) +static inline void iowrite16_rep(void __iomem *port, const void *buf, unsigned long count) { - __asm__ __volatile__("stwa\t%r0, [%1] %2\t/* pci_raw_writel */" - : /* no outputs */ - : "Jr" (l), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E)); + outsw((unsigned long __force)port, buf, count); } -static inline void _raw_writeq(u64 q, unsigned long addr) +static inline void iowrite32_rep(void __iomem *port, const void *buf, unsigned long count) { - __asm__ __volatile__("stxa\t%r0, [%1] %2\t/* pci_raw_writeq */" - : /* no outputs */ - : "Jr" (q), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E)); + outsl((unsigned long __force)port, buf, count); } -#define __raw_readb(__addr) (_raw_readb((unsigned long)(__addr))) -#define __raw_readw(__addr) (_raw_readw((unsigned long)(__addr))) -#define __raw_readl(__addr) (_raw_readl((unsigned long)(__addr))) -#define __raw_readq(__addr) (_raw_readq((unsigned long)(__addr))) -#define __raw_writeb(__b, __addr) (_raw_writeb((u8)(__b), (unsigned long)(__addr))) -#define __raw_writew(__w, __addr) (_raw_writew((u16)(__w), (unsigned long)(__addr))) -#define __raw_writel(__l, __addr) (_raw_writel((u32)(__l), (unsigned long)(__addr))) -#define __raw_writeq(__q, __addr) (_raw_writeq((u64)(__q), (unsigned long)(__addr))) +#define readb_relaxed(__addr) readb(__addr) +#define readw_relaxed(__addr) readw(__addr) +#define readl_relaxed(__addr) readl(__addr) +#define readq_relaxed(__addr) readq(__addr) /* Valid I/O Space regions are anywhere, because each PCI bus supported * can live in an arbitrary area of the physical address range. @@ -305,96 +277,47 @@ static inline void _raw_writeq(u64 q, unsigned long addr) /* Now, SBUS variants, only difference from PCI is that we do * not use little-endian ASIs. */ -static inline u8 _sbus_readb(const volatile void __iomem *addr) +static inline u8 sbus_readb(const volatile void __iomem *addr) { - u8 ret; - - __asm__ __volatile__("lduba\t[%1] %2, %0\t/* sbus_readb */" - : "=r" (ret) - : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E) - : "memory"); - - return ret; + return __raw_readb(addr); } -static inline u16 _sbus_readw(const volatile void __iomem *addr) +static inline u16 sbus_readw(const volatile void __iomem *addr) { - u16 ret; - - __asm__ __volatile__("lduha\t[%1] %2, %0\t/* sbus_readw */" - : "=r" (ret) - : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E) - : "memory"); - - return ret; + return __raw_readw(addr); } -static inline u32 _sbus_readl(const volatile void __iomem *addr) +static inline u32 sbus_readl(const volatile void __iomem *addr) { - u32 ret; - - __asm__ __volatile__("lduwa\t[%1] %2, %0\t/* sbus_readl */" - : "=r" (ret) - : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E) - : "memory"); - - return ret; + return __raw_readl(addr); } -static inline u64 _sbus_readq(const volatile void __iomem *addr) +static inline u64 sbus_readq(const volatile void __iomem *addr) { - u64 ret; - - __asm__ __volatile__("ldxa\t[%1] %2, %0\t/* sbus_readq */" - : "=r" (ret) - : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E) - : "memory"); - - return ret; + return __raw_readq(addr); } -static inline void _sbus_writeb(u8 b, volatile void __iomem *addr) +static inline void sbus_writeb(u8 b, volatile void __iomem *addr) { - __asm__ __volatile__("stba\t%r0, [%1] %2\t/* sbus_writeb */" - : /* no outputs */ - : "Jr" (b), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E) - : "memory"); + __raw_writeb(b, addr); } -static inline void _sbus_writew(u16 w, volatile void __iomem *addr) +static inline void sbus_writew(u16 w, volatile void __iomem *addr) { - __asm__ __volatile__("stha\t%r0, [%1] %2\t/* sbus_writew */" - : /* no outputs */ - : "Jr" (w), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E) - : "memory"); + __raw_writew(w, addr); } -static inline void _sbus_writel(u32 l, volatile void __iomem *addr) +static inline void sbus_writel(u32 l, volatile void __iomem *addr) { - __asm__ __volatile__("stwa\t%r0, [%1] %2\t/* sbus_writel */" - : /* no outputs */ - : "Jr" (l), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E) - : "memory"); + __raw_writel(l, addr); } -static inline void _sbus_writeq(u64 l, volatile void __iomem *addr) +static inline void sbus_writeq(u64 q, volatile void __iomem *addr) { - __asm__ __volatile__("stxa\t%r0, [%1] %2\t/* sbus_writeq */" - : /* no outputs */ - : "Jr" (l), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E) - : "memory"); + __raw_writeq(q, addr); } -#define sbus_readb(__addr) _sbus_readb(__addr) -#define sbus_readw(__addr) _sbus_readw(__addr) -#define sbus_readl(__addr) _sbus_readl(__addr) -#define sbus_readq(__addr) _sbus_readq(__addr) -#define sbus_writeb(__b, __addr) _sbus_writeb(__b, __addr) -#define sbus_writew(__w, __addr) _sbus_writew(__w, __addr) -#define sbus_writel(__l, __addr) _sbus_writel(__l, __addr) -#define sbus_writeq(__l, __addr) _sbus_writeq(__l, __addr) - -static inline void _sbus_memset_io(volatile void __iomem *dst, int c, __kernel_size_t n) +static inline void sbus_memset_io(volatile void __iomem *dst, int c, __kernel_size_t n) { while(n--) { sbus_writeb(c, dst); @@ -402,10 +325,7 @@ static inline void _sbus_memset_io(volatile void __iomem *dst, int c, __kernel_s } } -#define sbus_memset_io(d,c,sz) _sbus_memset_io(d,c,sz) - -static inline void -_memset_io(volatile void __iomem *dst, int c, __kernel_size_t n) +static inline void memset_io(volatile void __iomem *dst, int c, __kernel_size_t n) { volatile void __iomem *d = dst; @@ -415,11 +335,8 @@ _memset_io(volatile void __iomem *dst, int c, __kernel_size_t n) } } -#define memset_io(d,c,sz) _memset_io(d,c,sz) - -static inline void -_sbus_memcpy_fromio(void *dst, const volatile void __iomem *src, - __kernel_size_t n) +static inline void sbus_memcpy_fromio(void *dst, const volatile void __iomem *src, + __kernel_size_t n) { char *d = dst; @@ -430,10 +347,9 @@ _sbus_memcpy_fromio(void *dst, const volatile void __iomem *src, } } -#define sbus_memcpy_fromio(d, s, sz) _sbus_memcpy_fromio(d, s, sz) -static inline void -_memcpy_fromio(void *dst, const volatile void __iomem *src, __kernel_size_t n) +static inline void memcpy_fromio(void *dst, const volatile void __iomem *src, + __kernel_size_t n) { char *d = dst; @@ -444,11 +360,8 @@ _memcpy_fromio(void *dst, const volatile void __iomem *src, __kernel_size_t n) } } -#define memcpy_fromio(d,s,sz) _memcpy_fromio(d,s,sz) - -static inline void -_sbus_memcpy_toio(volatile void __iomem *dst, const void *src, - __kernel_size_t n) +static inline void sbus_memcpy_toio(volatile void __iomem *dst, const void *src, + __kernel_size_t n) { const char *s = src; volatile void __iomem *d = dst; @@ -460,10 +373,8 @@ _sbus_memcpy_toio(volatile void __iomem *dst, const void *src, } } -#define sbus_memcpy_toio(d, s, sz) _sbus_memcpy_toio(d, s, sz) - -static inline void -_memcpy_toio(volatile void __iomem *dst, const void *src, __kernel_size_t n) +static inline void memcpy_toio(volatile void __iomem *dst, const void *src, + __kernel_size_t n) { const char *s = src; volatile void __iomem *d = dst; @@ -475,8 +386,6 @@ _memcpy_toio(volatile void __iomem *dst, const void *src, __kernel_size_t n) } } -#define memcpy_toio(d,s,sz) _memcpy_toio(d,s,sz) - #define mmiowb() #ifdef __KERNEL__ diff --git a/arch/sparc/include/asm/tlbflush_64.h b/arch/sparc/include/asm/tlbflush_64.h index 816d820..dea1cfa 100644 --- a/arch/sparc/include/asm/tlbflush_64.h +++ b/arch/sparc/include/asm/tlbflush_64.h @@ -34,6 +34,8 @@ static inline void flush_tlb_range(struct vm_area_struct *vma, { } +void flush_tlb_kernel_range(unsigned long start, unsigned long end); + #define __HAVE_ARCH_ENTER_LAZY_MMU_MODE void flush_tlb_pending(void); @@ -48,11 +50,6 @@ void __flush_tlb_kernel_range(unsigned long start, unsigned long end); #ifndef CONFIG_SMP -#define flush_tlb_kernel_range(start,end) \ -do { flush_tsb_kernel_range(start,end); \ - __flush_tlb_kernel_range(start,end); \ -} while (0) - static inline void global_flush_tlb_page(struct mm_struct *mm, unsigned long vaddr) { __flush_tlb_page(CTX_HWBITS(mm->context), vaddr); @@ -63,11 +60,6 @@ static inline void global_flush_tlb_page(struct mm_struct *mm, unsigned long vad void smp_flush_tlb_kernel_range(unsigned long start, unsigned long end); void smp_flush_tlb_page(struct mm_struct *mm, unsigned long vaddr); -#define flush_tlb_kernel_range(start, end) \ -do { flush_tsb_kernel_range(start,end); \ - smp_flush_tlb_kernel_range(start, end); \ -} while (0) - #define global_flush_tlb_page(mm, vaddr) \ smp_flush_tlb_page(mm, vaddr) diff --git a/arch/sparc/kernel/ldc.c b/arch/sparc/kernel/ldc.c index e01d75d..66dacd5 100644 --- a/arch/sparc/kernel/ldc.c +++ b/arch/sparc/kernel/ldc.c @@ -1336,7 +1336,7 @@ int ldc_connect(struct ldc_channel *lp) if (!(lp->flags & LDC_FLAG_ALLOCED_QUEUES) || !(lp->flags & LDC_FLAG_REGISTERED_QUEUES) || lp->hs_state != LDC_HS_OPEN) - err = -EINVAL; + err = ((lp->hs_state > LDC_HS_OPEN) ? 0 : -EINVAL); else err = start_handshake(lp); diff --git a/arch/sparc/kernel/mdesc.c b/arch/sparc/kernel/mdesc.c index a1a4400..99632a8 100644 --- a/arch/sparc/kernel/mdesc.c +++ b/arch/sparc/kernel/mdesc.c @@ -906,29 +906,85 @@ void mdesc_fill_in_cpu_data(cpumask_t *mask) smp_fill_in_sib_core_maps(); } -static ssize_t mdesc_read(struct file *file, char __user *buf, - size_t len, loff_t *offp) +/* mdesc_open() - Grab a reference to mdesc_handle when /dev/mdesc is + * opened. Hold this reference until /dev/mdesc is closed to ensure + * mdesc data structure is not released underneath us. Store the + * pointer to mdesc structure in private_data for read and seek to use + */ +static int mdesc_open(struct inode *inode, struct file *file) { struct mdesc_handle *hp = mdesc_grab(); - int err; if (!hp) return -ENODEV; - err = hp->handle_size; - if (len < hp->handle_size) - err = -EMSGSIZE; - else if (copy_to_user(buf, &hp->mdesc, hp->handle_size)) - err = -EFAULT; - mdesc_release(hp); + file->private_data = hp; + + return 0; +} + +static ssize_t mdesc_read(struct file *file, char __user *buf, + size_t len, loff_t *offp) +{ + struct mdesc_handle *hp = file->private_data; + unsigned char *mdesc; + int bytes_left, count = len; + + if (*offp >= hp->handle_size) + return 0; + + bytes_left = hp->handle_size - *offp; + if (count > bytes_left) + count = bytes_left; + + mdesc = (unsigned char *)&hp->mdesc; + mdesc += *offp; + if (!copy_to_user(buf, mdesc, count)) { + *offp += count; + return count; + } else { + return -EFAULT; + } +} - return err; +static loff_t mdesc_llseek(struct file *file, loff_t offset, int whence) +{ + struct mdesc_handle *hp; + + switch (whence) { + case SEEK_CUR: + offset += file->f_pos; + break; + case SEEK_SET: + break; + default: + return -EINVAL; + } + + hp = file->private_data; + if (offset > hp->handle_size) + return -EINVAL; + else + file->f_pos = offset; + + return offset; +} + +/* mdesc_close() - /dev/mdesc is being closed, release the reference to + * mdesc structure. + */ +static int mdesc_close(struct inode *inode, struct file *file) +{ + mdesc_release(file->private_data); + return 0; } static const struct file_operations mdesc_fops = { - .read = mdesc_read, - .owner = THIS_MODULE, - .llseek = noop_llseek, + .open = mdesc_open, + .read = mdesc_read, + .llseek = mdesc_llseek, + .release = mdesc_close, + .owner = THIS_MODULE, }; static struct miscdevice mdesc_misc = { diff --git a/arch/sparc/kernel/unaligned_32.c b/arch/sparc/kernel/unaligned_32.c index c5c61b3..32b61d1 100644 --- a/arch/sparc/kernel/unaligned_32.c +++ b/arch/sparc/kernel/unaligned_32.c @@ -166,7 +166,7 @@ unsigned long safe_compute_effective_address(struct pt_regs *regs, /* This is just to make gcc think panic does return... */ static void unaligned_panic(char *str) { - panic(str); + panic("%s", str); } /* una_asm.S */ diff --git a/arch/sparc/lib/PeeCeeI.c b/arch/sparc/lib/PeeCeeI.c index 6529f86..e6d183675 100644 --- a/arch/sparc/lib/PeeCeeI.c +++ b/arch/sparc/lib/PeeCeeI.c @@ -15,7 +15,7 @@ void outsb(unsigned long __addr, const void *src, unsigned long count) const u8 *p = src; while (count--) - outb(*p++, addr); + __raw_writeb(*p++, addr); } EXPORT_SYMBOL(outsb); @@ -93,21 +93,21 @@ void insb(unsigned long __addr, void *dst, unsigned long count) u8 *pb = dst; while ((((unsigned long)pb) & 0x3) && count--) - *pb++ = inb(addr); + *pb++ = __raw_readb(addr); pi = (u32 *)pb; while (count >= 4) { u32 w; - w = (inb(addr) << 24); - w |= (inb(addr) << 16); - w |= (inb(addr) << 8); - w |= (inb(addr) << 0); + w = (__raw_readb(addr) << 24); + w |= (__raw_readb(addr) << 16); + w |= (__raw_readb(addr) << 8); + w |= (__raw_readb(addr) << 0); *pi++ = w; count -= 4; } pb = (u8 *)pi; while (count--) - *pb++ = inb(addr); + *pb++ = __raw_readb(addr); } } EXPORT_SYMBOL(insb); @@ -121,21 +121,21 @@ void insw(unsigned long __addr, void *dst, unsigned long count) u32 *pi; if (((unsigned long)ps) & 0x2) { - *ps++ = le16_to_cpu(inw(addr)); + *ps++ = __raw_readw(addr); count--; } pi = (u32 *)ps; while (count >= 2) { u32 w; - w = (le16_to_cpu(inw(addr)) << 16); - w |= (le16_to_cpu(inw(addr)) << 0); + w = __raw_readw(addr) << 16; + w |= __raw_readw(addr) << 0; *pi++ = w; count -= 2; } ps = (u16 *)pi; if (count) - *ps = le16_to_cpu(inw(addr)); + *ps = __raw_readw(addr); } } EXPORT_SYMBOL(insw); @@ -148,7 +148,7 @@ void insl(unsigned long __addr, void *dst, unsigned long count) if ((((unsigned long)dst) & 0x3) == 0) { u32 *pi = dst; while (count--) - *pi++ = le32_to_cpu(inl(addr)); + *pi++ = __raw_readl(addr); } else { u32 l = 0, l2, *pi; u16 *ps; @@ -158,11 +158,11 @@ void insl(unsigned long __addr, void *dst, unsigned long count) case 0x2: ps = dst; count -= 1; - l = le32_to_cpu(inl(addr)); + l = __raw_readl(addr); *ps++ = l; pi = (u32 *)ps; while (count--) { - l2 = le32_to_cpu(inl(addr)); + l2 = __raw_readl(addr); *pi++ = (l << 16) | (l2 >> 16); l = l2; } @@ -173,13 +173,13 @@ void insl(unsigned long __addr, void *dst, unsigned long count) case 0x1: pb = dst; count -= 1; - l = le32_to_cpu(inl(addr)); + l = __raw_readl(addr); *pb++ = l >> 24; ps = (u16 *)pb; *ps++ = ((l >> 8) & 0xffff); pi = (u32 *)ps; while (count--) { - l2 = le32_to_cpu(inl(addr)); + l2 = __raw_readl(addr); *pi++ = (l << 24) | (l2 >> 8); l = l2; } @@ -190,11 +190,11 @@ void insl(unsigned long __addr, void *dst, unsigned long count) case 0x3: pb = (u8 *)dst; count -= 1; - l = le32_to_cpu(inl(addr)); + l = __raw_readl(addr); *pb++ = l >> 24; pi = (u32 *)pb; while (count--) { - l2 = le32_to_cpu(inl(addr)); + l2 = __raw_readl(addr); *pi++ = (l << 8) | (l2 >> 24); l = l2; } diff --git a/arch/sparc/math-emu/math_32.c b/arch/sparc/math-emu/math_32.c index aa4d55b..5ce8f2f 100644 --- a/arch/sparc/math-emu/math_32.c +++ b/arch/sparc/math-emu/math_32.c @@ -499,7 +499,7 @@ static int do_one_mathemu(u32 insn, unsigned long *pfsr, unsigned long *fregs) case 0: fsr = *pfsr; if (IR == -1) IR = 2; /* fcc is always fcc0 */ - fsr &= ~0xc00; fsr |= (IR << 10); break; + fsr &= ~0xc00; fsr |= (IR << 10); *pfsr = fsr; break; case 1: rd->s = IR; break; diff --git a/arch/sparc/mm/init_64.c b/arch/sparc/mm/init_64.c index 16b58ff..98ac8e8 100644 --- a/arch/sparc/mm/init_64.c +++ b/arch/sparc/mm/init_64.c @@ -22,6 +22,7 @@ #include <linux/kprobes.h> #include <linux/cache.h> #include <linux/sort.h> +#include <linux/ioport.h> #include <linux/percpu.h> #include <linux/memblock.h> #include <linux/mmzone.h> @@ -351,6 +352,10 @@ void update_mmu_cache(struct vm_area_struct *vma, unsigned long address, pte_t * mm = vma->vm_mm; + /* Don't insert a non-valid PTE into the TSB, we'll deadlock. */ + if (!pte_accessible(mm, pte)) + return; + spin_lock_irqsave(&mm->context.lock, flags); #if defined(CONFIG_HUGETLB_PAGE) || defined(CONFIG_TRANSPARENT_HUGEPAGE) @@ -2619,6 +2624,10 @@ void update_mmu_cache_pmd(struct vm_area_struct *vma, unsigned long addr, pte = pmd_val(entry); + /* Don't insert a non-valid PMD into the TSB, we'll deadlock. */ + if (!(pte & _PAGE_VALID)) + return; + /* We are fabricating 8MB pages using 4MB real hw pages. */ pte |= (addr & (1UL << REAL_HPAGE_SHIFT)); @@ -2699,3 +2708,90 @@ void hugetlb_setup(struct pt_regs *regs) } } #endif + +static struct resource code_resource = { + .name = "Kernel code", + .flags = IORESOURCE_BUSY | IORESOURCE_MEM +}; + +static struct resource data_resource = { + .name = "Kernel data", + .flags = IORESOURCE_BUSY | IORESOURCE_MEM +}; + +static struct resource bss_resource = { + .name = "Kernel bss", + .flags = IORESOURCE_BUSY | IORESOURCE_MEM +}; + +static inline resource_size_t compute_kern_paddr(void *addr) +{ + return (resource_size_t) (addr - KERNBASE + kern_base); +} + +static void __init kernel_lds_init(void) +{ + code_resource.start = compute_kern_paddr(_text); + code_resource.end = compute_kern_paddr(_etext - 1); + data_resource.start = compute_kern_paddr(_etext); + data_resource.end = compute_kern_paddr(_edata - 1); + bss_resource.start = compute_kern_paddr(__bss_start); + bss_resource.end = compute_kern_paddr(_end - 1); +} + +static int __init report_memory(void) +{ + int i; + struct resource *res; + + kernel_lds_init(); + + for (i = 0; i < pavail_ents; i++) { + res = kzalloc(sizeof(struct resource), GFP_KERNEL); + + if (!res) { + pr_warn("Failed to allocate source.\n"); + break; + } + + res->name = "System RAM"; + res->start = pavail[i].phys_addr; + res->end = pavail[i].phys_addr + pavail[i].reg_size - 1; + res->flags = IORESOURCE_BUSY | IORESOURCE_MEM; + + if (insert_resource(&iomem_resource, res) < 0) { + pr_warn("Resource insertion failed.\n"); + break; + } + + insert_resource(res, &code_resource); + insert_resource(res, &data_resource); + insert_resource(res, &bss_resource); + } + + return 0; +} +device_initcall(report_memory); + +#ifdef CONFIG_SMP +#define do_flush_tlb_kernel_range smp_flush_tlb_kernel_range +#else +#define do_flush_tlb_kernel_range __flush_tlb_kernel_range +#endif + +void flush_tlb_kernel_range(unsigned long start, unsigned long end) +{ + if (start < HI_OBP_ADDRESS && end > LOW_OBP_ADDRESS) { + if (start < LOW_OBP_ADDRESS) { + flush_tsb_kernel_range(start, LOW_OBP_ADDRESS); + do_flush_tlb_kernel_range(start, LOW_OBP_ADDRESS); + } + if (end > HI_OBP_ADDRESS) { + flush_tsb_kernel_range(end, HI_OBP_ADDRESS); + do_flush_tlb_kernel_range(end, HI_OBP_ADDRESS); + } + } else { + flush_tsb_kernel_range(start, end); + do_flush_tlb_kernel_range(start, end); + } +} |