Skip to content

Commit

Permalink
Merge branch 'next' of git://git.monstr.eu/linux-2.6-microblaze
Browse files Browse the repository at this point in the history
* 'next' of git://git.monstr.eu/linux-2.6-microblaze:
  microblaze: Remove __ARCH_WANT_INTERRUPTS_ON_CTXSW usage
  microblaze: Use delay slot in __strnlen_user, __strncpy_user
  microblaze: Remove NET_IP_ALIGN from system.h
  microblaze: Add __ucmpdi2() helper function
  microblaze: Raise SIGFPE/FPE_INTDIV for div by zero
  microblaze: Switch ELF_ARCH code to 189
  microblaze: Added DMA sync operations
  microblaze: Moved __dma_sync() to dma-mapping.h
  microblaze: Add PVR for Microblaze v8.20.a
  microblaze: Fix access_ok macro
  microblaze: Add loop unrolling for PAGE in copy_tofrom_user
  microblaze: Simplify logic for unaligned byte copying
  microblaze: Change label names - copy_tofrom_user
  microblaze: Separate fixup section definition
  microblaze: Change label name in copy_tofrom_user
  microblaze: Clear top bit from cnt32_to_63
  • Loading branch information
Linus Torvalds committed Oct 31, 2011
2 parents 91e67a9 + 84ac218 commit b1c907f
Show file tree
Hide file tree
Showing 13 changed files with 220 additions and 54 deletions.
20 changes: 18 additions & 2 deletions arch/microblaze/include/asm/dma-mapping.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,12 @@
#include <linux/dma-attrs.h>
#include <asm/io.h>
#include <asm-generic/dma-coherent.h>
#include <asm/cacheflush.h>

#define DMA_ERROR_CODE (~(dma_addr_t)0x0)

#define __dma_alloc_coherent(dev, gfp, size, handle) NULL
#define __dma_free_coherent(size, addr) ((void)0)
#define __dma_sync(addr, size, rw) ((void)0)

static inline unsigned long device_to_mask(struct device *dev)
{
Expand Down Expand Up @@ -95,6 +95,22 @@ static inline int dma_set_mask(struct device *dev, u64 dma_mask)

#include <asm-generic/dma-mapping-common.h>

static inline void __dma_sync(unsigned long paddr,
size_t size, enum dma_data_direction direction)
{
switch (direction) {
case DMA_TO_DEVICE:
case DMA_BIDIRECTIONAL:
flush_dcache_range(paddr, paddr + size);
break;
case DMA_FROM_DEVICE:
invalidate_dcache_range(paddr, paddr + size);
break;
default:
BUG();
}
}

static inline int dma_mapping_error(struct device *dev, dma_addr_t dma_addr)
{
struct dma_map_ops *ops = get_dma_ops(dev);
Expand Down Expand Up @@ -135,7 +151,7 @@ static inline void dma_cache_sync(struct device *dev, void *vaddr, size_t size,
enum dma_data_direction direction)
{
BUG_ON(direction == DMA_NONE);
__dma_sync(vaddr, size, (int)direction);
__dma_sync(virt_to_phys(vaddr), size, (int)direction);
}

#endif /* _ASM_MICROBLAZE_DMA_MAPPING_H */
8 changes: 5 additions & 3 deletions arch/microblaze/include/asm/elf.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,15 @@
* I've snaffled the value from the microblaze binutils source code
* /binutils/microblaze/include/elf/microblaze.h
*/
#define EM_XILINX_MICROBLAZE 0xbaab
#define ELF_ARCH EM_XILINX_MICROBLAZE
#define EM_MICROBLAZE 189
#define EM_MICROBLAZE_OLD 0xbaab
#define ELF_ARCH EM_MICROBLAZE

/*
* This is used to ensure we don't load something for the wrong architecture.
*/
#define elf_check_arch(x) ((x)->e_machine == EM_XILINX_MICROBLAZE)
#define elf_check_arch(x) ((x)->e_machine == EM_MICROBLAZE \
|| (x)->e_machine == EM_MICROBLAZE_OLD)

/*
* These are used to set parameters in the core dumps.
Expand Down
9 changes: 0 additions & 9 deletions arch/microblaze/include/asm/system.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,6 @@
#include <asm-generic/cmpxchg.h>
#include <asm-generic/cmpxchg-local.h>

#define __ARCH_WANT_INTERRUPTS_ON_CTXSW

struct task_struct;
struct thread_info;

Expand Down Expand Up @@ -96,11 +94,4 @@ extern struct dentry *of_debugfs_root;

#define arch_align_stack(x) (x)

/*
* MicroBlaze doesn't handle unaligned accesses in hardware.
*
* Based on this we force the IP header alignment in network drivers.
*/
#define NET_IP_ALIGN 2

#endif /* _ASM_MICROBLAZE_SYSTEM_H */
2 changes: 1 addition & 1 deletion arch/microblaze/include/asm/uaccess.h
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ static inline int ___range_ok(unsigned long addr, unsigned long size)
* - "addr", "addr + size" and "size" are all below the limit
*/
#define access_ok(type, addr, size) \
(get_fs().seg > (((unsigned long)(addr)) | \
(get_fs().seg >= (((unsigned long)(addr)) | \
(size) | ((unsigned long)(addr) + (size))))

/* || printk("access_ok failed for %s at 0x%08lx (size %d), seg 0x%08x\n",
Expand Down
1 change: 1 addition & 0 deletions arch/microblaze/kernel/cpu/cpuinfo.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ const struct cpu_ver_key cpu_ver_lookup[] = {
{"8.00.a", 0x12},
{"8.00.b", 0x13},
{"8.10.a", 0x14},
{"8.20.a", 0x15},
{NULL, 0},
};

Expand Down
82 changes: 63 additions & 19 deletions arch/microblaze/kernel/dma.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
#include <linux/gfp.h>
#include <linux/dma-debug.h>
#include <asm/bug.h>
#include <asm/cacheflush.h>

/*
* Generic direct DMA implementation
Expand All @@ -21,21 +20,6 @@
* can set archdata.dma_data to an unsigned long holding the offset. By
* default the offset is PCI_DRAM_OFFSET.
*/
static inline void __dma_sync_page(unsigned long paddr, unsigned long offset,
size_t size, enum dma_data_direction direction)
{
switch (direction) {
case DMA_TO_DEVICE:
case DMA_BIDIRECTIONAL:
flush_dcache_range(paddr + offset, paddr + offset + size);
break;
case DMA_FROM_DEVICE:
invalidate_dcache_range(paddr + offset, paddr + offset + size);
break;
default:
BUG();
}
}

static unsigned long get_dma_direct_offset(struct device *dev)
{
Expand Down Expand Up @@ -91,7 +75,7 @@ static int dma_direct_map_sg(struct device *dev, struct scatterlist *sgl,
/* FIXME this part of code is untested */
for_each_sg(sgl, sg, nents, i) {
sg->dma_address = sg_phys(sg) + get_dma_direct_offset(dev);
__dma_sync_page(page_to_phys(sg_page(sg)), sg->offset,
__dma_sync(page_to_phys(sg_page(sg)) + sg->offset,
sg->length, direction);
}

Expand All @@ -116,7 +100,7 @@ static inline dma_addr_t dma_direct_map_page(struct device *dev,
enum dma_data_direction direction,
struct dma_attrs *attrs)
{
__dma_sync_page(page_to_phys(page), offset, size, direction);
__dma_sync(page_to_phys(page) + offset, size, direction);
return page_to_phys(page) + offset + get_dma_direct_offset(dev);
}

Expand All @@ -131,7 +115,63 @@ static inline void dma_direct_unmap_page(struct device *dev,
* phys_to_virt is here because in __dma_sync_page is __virt_to_phys and
* dma_address is physical address
*/
__dma_sync_page(dma_address, 0 , size, direction);
__dma_sync(dma_address, size, direction);
}

static inline void
dma_direct_sync_single_for_cpu(struct device *dev,
dma_addr_t dma_handle, size_t size,
enum dma_data_direction direction)
{
/*
* It's pointless to flush the cache as the memory segment
* is given to the CPU
*/

if (direction == DMA_FROM_DEVICE)
__dma_sync(dma_handle, size, direction);
}

static inline void
dma_direct_sync_single_for_device(struct device *dev,
dma_addr_t dma_handle, size_t size,
enum dma_data_direction direction)
{
/*
* It's pointless to invalidate the cache if the device isn't
* supposed to write to the relevant region
*/

if (direction == DMA_TO_DEVICE)
__dma_sync(dma_handle, size, direction);
}

static inline void
dma_direct_sync_sg_for_cpu(struct device *dev,
struct scatterlist *sgl, int nents,
enum dma_data_direction direction)
{
struct scatterlist *sg;
int i;

/* FIXME this part of code is untested */
if (direction == DMA_FROM_DEVICE)
for_each_sg(sgl, sg, nents, i)
__dma_sync(sg->dma_address, sg->length, direction);
}

static inline void
dma_direct_sync_sg_for_device(struct device *dev,
struct scatterlist *sgl, int nents,
enum dma_data_direction direction)
{
struct scatterlist *sg;
int i;

/* FIXME this part of code is untested */
if (direction == DMA_TO_DEVICE)
for_each_sg(sgl, sg, nents, i)
__dma_sync(sg->dma_address, sg->length, direction);
}

struct dma_map_ops dma_direct_ops = {
Expand All @@ -142,6 +182,10 @@ struct dma_map_ops dma_direct_ops = {
.dma_supported = dma_direct_dma_supported,
.map_page = dma_direct_map_page,
.unmap_page = dma_direct_unmap_page,
.sync_single_for_cpu = dma_direct_sync_single_for_cpu,
.sync_single_for_device = dma_direct_sync_single_for_device,
.sync_sg_for_cpu = dma_direct_sync_sg_for_cpu,
.sync_sg_for_device = dma_direct_sync_sg_for_device,
};
EXPORT_SYMBOL(dma_direct_ops);

Expand Down
2 changes: 1 addition & 1 deletion arch/microblaze/kernel/exceptions.c
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ asmlinkage void full_exception(struct pt_regs *regs, unsigned int type,
case MICROBLAZE_DIV_ZERO_EXCEPTION:
if (user_mode(regs)) {
pr_debug("Divide by zero exception in user mode\n");
_exception(SIGILL, regs, FPE_INTDIV, addr);
_exception(SIGFPE, regs, FPE_INTDIV, addr);
return;
}
printk(KERN_WARNING "Divide by zero exception " \
Expand Down
1 change: 1 addition & 0 deletions arch/microblaze/kernel/process.c
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,7 @@ int copy_thread(unsigned long clone_flags, unsigned long usp,

ti->cpu_context.msr = (childregs->msr|MSR_VM);
ti->cpu_context.msr &= ~MSR_UMS; /* switch_to to kernel mode */
ti->cpu_context.msr &= ~MSR_IE;
#endif
ti->cpu_context.r15 = (unsigned long)ret_from_fork - 8;

Expand Down
2 changes: 1 addition & 1 deletion arch/microblaze/kernel/ptrace.c
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ asmlinkage long do_syscall_trace_enter(struct pt_regs *regs)
ret = -1L;

if (unlikely(current->audit_context))
audit_syscall_entry(EM_XILINX_MICROBLAZE, regs->r12,
audit_syscall_entry(EM_MICROBLAZE, regs->r12,
regs->r5, regs->r6,
regs->r7, regs->r8);

Expand Down
3 changes: 2 additions & 1 deletion arch/microblaze/kernel/timer.c
Original file line number Diff line number Diff line change
Expand Up @@ -308,7 +308,8 @@ unsigned long long notrace sched_clock(void)
{
if (timer_initialized) {
struct clocksource *cs = &clocksource_microblaze;
cycle_t cyc = cnt32_to_63(cs->read(NULL));

cycle_t cyc = cnt32_to_63(cs->read(NULL)) & LLONG_MAX;
return clocksource_cyc2ns(cyc, cs->mult, cs->shift);
}
return 0;
Expand Down
1 change: 1 addition & 0 deletions arch/microblaze/lib/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -25,5 +25,6 @@ lib-y += lshrdi3.o
lib-y += modsi3.o
lib-y += muldi3.o
lib-y += mulsi3.o
lib-y += ucmpdi2.o
lib-y += udivsi3.o
lib-y += umodsi3.o
Loading

0 comments on commit b1c907f

Please sign in to comment.