From 9c6f6f549f46940c2d48eb9618d9d0fe471c5151 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Fri, 23 Sep 2011 09:52:24 +0200 Subject: microblaze: Clear top bit from cnt32_to_63 Top bit is used as garbage and it must be clear explicitly. It is causing the problem with soft lookup code because it checks delays which are long when top bit is setup. Signed-off-by: Michal Simek --- arch/microblaze/kernel/timer.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'arch/microblaze') diff --git a/arch/microblaze/kernel/timer.c b/arch/microblaze/kernel/timer.c index e5550ce4e0e..af74b1113aa 100644 --- a/arch/microblaze/kernel/timer.c +++ b/arch/microblaze/kernel/timer.c @@ -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; -- cgit v1.2.3 From 9b133f8d87a460e97b63efbf421a87741a029cd0 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Fri, 10 Jun 2011 11:03:44 +0200 Subject: microblaze: Change label name in copy_tofrom_user Use label 0: for zero length copying and fixups. Signed-off-by: Michal Simek --- arch/microblaze/lib/uaccess_old.S | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'arch/microblaze') diff --git a/arch/microblaze/lib/uaccess_old.S b/arch/microblaze/lib/uaccess_old.S index 5810cec54a7..5b6d69e0796 100644 --- a/arch/microblaze/lib/uaccess_old.S +++ b/arch/microblaze/lib/uaccess_old.S @@ -119,7 +119,7 @@ __copy_tofrom_user: * r7, r3 - count * r4 - tempval */ - beqid r7, 3f /* zero size is not likely */ + beqid r7, 0f /* zero size is not likely */ andi r3, r7, 0x3 /* filter add count */ bneid r3, 4f /* if is odd value then byte copying */ or r3, r5, r6 /* find if is any to/from unaligned */ @@ -142,11 +142,11 @@ __copy_tofrom_user: addik r7,r7,-1 bneid r7,1b addik r3,r3,1 /* delay slot */ -3: +0: addik r3,r7,0 rtsd r15,8 nop .size __copy_tofrom_user, . - __copy_tofrom_user .section __ex_table,"a" - .word 1b,3b,2b,3b,5b,3b,6b,3b + .word 1b,0b,2b,0b,5b,0b,6b,0b -- cgit v1.2.3 From eedac7914dd4d6effa0b970a36efd898c9fc4873 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Fri, 10 Jun 2011 11:05:45 +0200 Subject: microblaze: Separate fixup section definition Move fixups below appropriate code. Signed-off-by: Michal Simek --- arch/microblaze/lib/uaccess_old.S | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'arch/microblaze') diff --git a/arch/microblaze/lib/uaccess_old.S b/arch/microblaze/lib/uaccess_old.S index 5b6d69e0796..bacfedc3c7d 100644 --- a/arch/microblaze/lib/uaccess_old.S +++ b/arch/microblaze/lib/uaccess_old.S @@ -136,6 +136,12 @@ __copy_tofrom_user: addik r3, r7, 0 rtsd r15, 8 nop + + .section __ex_table,"a" + .word 5b, 0f; + .word 6b, 0f; + .text + 4: or r3, r0, r0 1: lbu r4,r6,r3 2: sb r4,r5,r3 @@ -149,4 +155,6 @@ __copy_tofrom_user: .size __copy_tofrom_user, . - __copy_tofrom_user .section __ex_table,"a" - .word 1b,0b,2b,0b,5b,0b,6b,0b + .word 1b, 0b; + .word 2b, 0b; + .text -- cgit v1.2.3 From c83858b3e6e8db9dbb17641de1a2420bb102ae31 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Fri, 10 Jun 2011 11:07:55 +0200 Subject: microblaze: Change label names - copy_tofrom_user Change label name to be prepared for loop unrolling. Signed-off-by: Michal Simek --- arch/microblaze/lib/uaccess_old.S | 27 +++++++++++++-------------- 1 file changed, 13 insertions(+), 14 deletions(-) (limited to 'arch/microblaze') diff --git a/arch/microblaze/lib/uaccess_old.S b/arch/microblaze/lib/uaccess_old.S index bacfedc3c7d..6dfd4a08726 100644 --- a/arch/microblaze/lib/uaccess_old.S +++ b/arch/microblaze/lib/uaccess_old.S @@ -121,32 +121,31 @@ __copy_tofrom_user: */ beqid r7, 0f /* zero size is not likely */ andi r3, r7, 0x3 /* filter add count */ - bneid r3, 4f /* if is odd value then byte copying */ + bneid r3, bu /* if is odd value then byte copying */ or r3, r5, r6 /* find if is any to/from unaligned */ andi r3, r3, 0x3 /* mask unaligned */ - bneid r3, 1f /* it is unaligned -> then jump */ + bneid r3, bu1 /* it is unaligned -> then jump */ or r3, r0, r0 -/* at least one 4 byte copy */ -5: lw r4, r6, r3 -6: sw r4, r5, r3 +w1: lw r4, r6, r3 /* at least one 4 byte copy */ +w2: sw r4, r5, r3 addik r7, r7, -4 - bneid r7, 5b + bneid r7, w1 addik r3, r3, 4 addik r3, r7, 0 rtsd r15, 8 nop .section __ex_table,"a" - .word 5b, 0f; - .word 6b, 0f; + .word w1, 0f; + .word w2, 0f; .text -4: or r3, r0, r0 -1: lbu r4,r6,r3 -2: sb r4,r5,r3 +bu: or r3, r0, r0 +bu1: lbu r4,r6,r3 +bu2: sb r4,r5,r3 addik r7,r7,-1 - bneid r7,1b + bneid r7,bu1 addik r3,r3,1 /* delay slot */ 0: addik r3,r7,0 @@ -155,6 +154,6 @@ __copy_tofrom_user: .size __copy_tofrom_user, . - __copy_tofrom_user .section __ex_table,"a" - .word 1b, 0b; - .word 2b, 0b; + .word bu1, 0b; + .word bu2, 0b; .text -- cgit v1.2.3 From 782d491fc210fac03976d01071145728339b6887 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Fri, 10 Jun 2011 11:08:57 +0200 Subject: microblaze: Simplify logic for unaligned byte copying Save jump instruction for unaligned byte copying. Signed-off-by: Michal Simek --- arch/microblaze/lib/uaccess_old.S | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) (limited to 'arch/microblaze') diff --git a/arch/microblaze/lib/uaccess_old.S b/arch/microblaze/lib/uaccess_old.S index 6dfd4a08726..d09f2dce648 100644 --- a/arch/microblaze/lib/uaccess_old.S +++ b/arch/microblaze/lib/uaccess_old.S @@ -120,11 +120,10 @@ __copy_tofrom_user: * r4 - tempval */ beqid r7, 0f /* zero size is not likely */ - andi r3, r7, 0x3 /* filter add count */ - bneid r3, bu /* if is odd value then byte copying */ or r3, r5, r6 /* find if is any to/from unaligned */ - andi r3, r3, 0x3 /* mask unaligned */ - bneid r3, bu1 /* it is unaligned -> then jump */ + or r3, r3, r7 /* find if count is unaligned */ + andi r3, r3, 0x3 /* mask last 3 bits */ + bneid r3, bu1 /* if r3 is not zero then byte copying */ or r3, r0, r0 w1: lw r4, r6, r3 /* at least one 4 byte copy */ @@ -141,7 +140,6 @@ w2: sw r4, r5, r3 .word w2, 0f; .text -bu: or r3, r0, r0 bu1: lbu r4,r6,r3 bu2: sb r4,r5,r3 addik r7,r7,-1 -- cgit v1.2.3 From ebe211254bfa6295f4ab0b33c7c881bdfabbab60 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Fri, 10 Jun 2011 10:49:08 +0200 Subject: microblaze: Add loop unrolling for PAGE in copy_tofrom_user Increase performance by loop unrolling. Signed-off-by: Michal Simek --- arch/microblaze/lib/uaccess_old.S | 84 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 84 insertions(+) (limited to 'arch/microblaze') diff --git a/arch/microblaze/lib/uaccess_old.S b/arch/microblaze/lib/uaccess_old.S index d09f2dce648..142492ec270 100644 --- a/arch/microblaze/lib/uaccess_old.S +++ b/arch/microblaze/lib/uaccess_old.S @@ -10,6 +10,7 @@ #include #include +#include /* * int __strncpy_user(char *to, char *from, int len); @@ -102,6 +103,49 @@ __strnlen_user: .section __ex_table,"a" .word 1b,4b +/* Loop unrolling for __copy_tofrom_user */ +#define COPY(offset) \ +1: lwi r4 , r6, 0x0000 + offset; \ +2: lwi r19, r6, 0x0004 + offset; \ +3: lwi r20, r6, 0x0008 + offset; \ +4: lwi r21, r6, 0x000C + offset; \ +5: lwi r22, r6, 0x0010 + offset; \ +6: lwi r23, r6, 0x0014 + offset; \ +7: lwi r24, r6, 0x0018 + offset; \ +8: lwi r25, r6, 0x001C + offset; \ +9: swi r4 , r5, 0x0000 + offset; \ +10: swi r19, r5, 0x0004 + offset; \ +11: swi r20, r5, 0x0008 + offset; \ +12: swi r21, r5, 0x000C + offset; \ +13: swi r22, r5, 0x0010 + offset; \ +14: swi r23, r5, 0x0014 + offset; \ +15: swi r24, r5, 0x0018 + offset; \ +16: swi r25, r5, 0x001C + offset; \ + .section __ex_table,"a"; \ + .word 1b, 0f; \ + .word 2b, 0f; \ + .word 3b, 0f; \ + .word 4b, 0f; \ + .word 5b, 0f; \ + .word 6b, 0f; \ + .word 7b, 0f; \ + .word 8b, 0f; \ + .word 9b, 0f; \ + .word 10b, 0f; \ + .word 11b, 0f; \ + .word 12b, 0f; \ + .word 13b, 0f; \ + .word 14b, 0f; \ + .word 15b, 0f; \ + .word 16b, 0f; \ + .text + +#define COPY_80(offset) \ + COPY(0x00 + offset);\ + COPY(0x20 + offset);\ + COPY(0x40 + offset);\ + COPY(0x60 + offset); + /* * int __copy_tofrom_user(char *to, char *from, int len) * Return: @@ -126,6 +170,10 @@ __copy_tofrom_user: bneid r3, bu1 /* if r3 is not zero then byte copying */ or r3, r0, r0 + rsubi r3, r7, PAGE_SIZE /* detect PAGE_SIZE */ + beqid r3, page; + or r3, r0, r0 + w1: lw r4, r6, r3 /* at least one 4 byte copy */ w2: sw r4, r5, r3 addik r7, r7, -4 @@ -140,6 +188,42 @@ w2: sw r4, r5, r3 .word w2, 0f; .text +.align 4 /* Alignment is important to keep icache happy */ +page: /* Create room on stack and save registers for storign values */ + addik r1, r1, -32 + swi r19, r1, 4 + swi r20, r1, 8 + swi r21, r1, 12 + swi r22, r1, 16 + swi r23, r1, 20 + swi r24, r1, 24 + swi r25, r1, 28 +loop: /* r4, r19, r20, r21, r22, r23, r24, r25 are used for storing values */ + /* Loop unrolling to get performance boost */ + COPY_80(0x000); + COPY_80(0x080); + COPY_80(0x100); + COPY_80(0x180); + /* copy loop */ + addik r6, r6, 0x200 + addik r7, r7, -0x200 + bneid r7, loop + addik r5, r5, 0x200 + /* Restore register content */ + lwi r19, r1, 4 + lwi r20, r1, 8 + lwi r21, r1, 12 + lwi r22, r1, 16 + lwi r23, r1, 20 + lwi r24, r1, 24 + lwi r25, r1, 28 + addik r1, r1, 32 + /* return back */ + addik r3, r7, 0 + rtsd r15, 8 + nop + +.align 4 /* Alignment is important to keep icache happy */ bu1: lbu r4,r6,r3 bu2: sb r4,r5,r3 addik r7,r7,-1 -- cgit v1.2.3 From 41b7602ed17a6bbb3b3d33087c39ef5c3a5589c7 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Thu, 28 Jul 2011 15:23:37 +0200 Subject: microblaze: Fix access_ok macro There is the problem with bit OR (|) because for some combination is addr | size | addr+size equal to seq. For standard kernel setting (kernel starts at 0xC0000000) is seq for user space 0xBFFFFFFF and everything below this limit is fine. But even address 0xBFFFFFFF is fine because it is below kernel space. Signed-off-by: Andrew Fedonczuk Signed-off-by: Michal Simek --- arch/microblaze/include/asm/uaccess.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch/microblaze') diff --git a/arch/microblaze/include/asm/uaccess.h b/arch/microblaze/include/asm/uaccess.h index 5bb95a11880..072b0077abf 100644 --- a/arch/microblaze/include/asm/uaccess.h +++ b/arch/microblaze/include/asm/uaccess.h @@ -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", -- cgit v1.2.3 From 2309f7cfca745ec282c125e79ac80dca2ea8390e Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Mon, 23 May 2011 13:06:43 +0200 Subject: microblaze: Add PVR for Microblaze v8.20.a Microblaze v8.20.a has 0x15 version string. Signed-off-by: Michal Simek --- arch/microblaze/kernel/cpu/cpuinfo.c | 1 + 1 file changed, 1 insertion(+) (limited to 'arch/microblaze') diff --git a/arch/microblaze/kernel/cpu/cpuinfo.c b/arch/microblaze/kernel/cpu/cpuinfo.c index 44394d80a68..54194b28574 100644 --- a/arch/microblaze/kernel/cpu/cpuinfo.c +++ b/arch/microblaze/kernel/cpu/cpuinfo.c @@ -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}, }; -- cgit v1.2.3 From cf560c1801e518abfe0951008c4f2df4bbb3f5e8 Mon Sep 17 00:00:00 2001 From: Eli Billauer Date: Sun, 11 Sep 2011 22:43:06 +0300 Subject: microblaze: Moved __dma_sync() to dma-mapping.h __dma_sync_page() was replaced by __dma_sync(), and parameters of calls to the new function were adjusted to match __dma_sync()'s format. Signed-off-by: Eli Billauer Signed-off-by: Michal Simek --- arch/microblaze/include/asm/dma-mapping.h | 20 ++++++++++++++++++-- arch/microblaze/kernel/dma.c | 22 +++------------------- 2 files changed, 21 insertions(+), 21 deletions(-) (limited to 'arch/microblaze') diff --git a/arch/microblaze/include/asm/dma-mapping.h b/arch/microblaze/include/asm/dma-mapping.h index 8fbb0ec1023..cddeca59a63 100644 --- a/arch/microblaze/include/asm/dma-mapping.h +++ b/arch/microblaze/include/asm/dma-mapping.h @@ -28,12 +28,12 @@ #include #include #include +#include #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) { @@ -95,6 +95,22 @@ static inline int dma_set_mask(struct device *dev, u64 dma_mask) #include +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); @@ -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 */ diff --git a/arch/microblaze/kernel/dma.c b/arch/microblaze/kernel/dma.c index 393e6b2db68..595130bcead 100644 --- a/arch/microblaze/kernel/dma.c +++ b/arch/microblaze/kernel/dma.c @@ -11,7 +11,6 @@ #include #include #include -#include /* * Generic direct DMA implementation @@ -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) { @@ -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); } @@ -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); } @@ -131,7 +115,7 @@ 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); } struct dma_map_ops dma_direct_ops = { -- cgit v1.2.3 From 0fb2a6f283f25731217841f961cefa0a19bd449d Mon Sep 17 00:00:00 2001 From: Eli Billauer Date: Sun, 11 Sep 2011 22:43:07 +0300 Subject: microblaze: Added DMA sync operations Added support gor dma_direct_sync_single_for_*() and dma_direct_sync_sg_for_*() Signed-off-by: Eli Billauer Signed-off-by: Michal Simek --- arch/microblaze/kernel/dma.c | 60 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) (limited to 'arch/microblaze') diff --git a/arch/microblaze/kernel/dma.c b/arch/microblaze/kernel/dma.c index 595130bcead..dc6416d265d 100644 --- a/arch/microblaze/kernel/dma.c +++ b/arch/microblaze/kernel/dma.c @@ -118,6 +118,62 @@ static inline void dma_direct_unmap_page(struct device *dev, __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 = { .alloc_coherent = dma_direct_alloc_coherent, .free_coherent = dma_direct_free_coherent, @@ -126,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); -- cgit v1.2.3 From 69515f8b957a4b1558d4726ffa6be2484e1dcb60 Mon Sep 17 00:00:00 2001 From: "Edgar E. Iglesias" Date: Tue, 23 Aug 2011 23:16:15 +0200 Subject: microblaze: Switch ELF_ARCH code to 189 Switch arch code to 189, the registered code in the upstream version of binutils. Continue to accept the experimental 0xbaab. Signed-off-by: Edgar E. Iglesias Signed-off-by: Michal Simek --- arch/microblaze/include/asm/elf.h | 8 +++++--- arch/microblaze/kernel/ptrace.c | 2 +- 2 files changed, 6 insertions(+), 4 deletions(-) (limited to 'arch/microblaze') diff --git a/arch/microblaze/include/asm/elf.h b/arch/microblaze/include/asm/elf.h index 098dfdde4b0..834849f59ae 100644 --- a/arch/microblaze/include/asm/elf.h +++ b/arch/microblaze/include/asm/elf.h @@ -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. diff --git a/arch/microblaze/kernel/ptrace.c b/arch/microblaze/kernel/ptrace.c index 6a8e0cc5c57..043cb58f9c4 100644 --- a/arch/microblaze/kernel/ptrace.c +++ b/arch/microblaze/kernel/ptrace.c @@ -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); -- cgit v1.2.3 From 15ec090833eeb2ab242c049a68b6224345771619 Mon Sep 17 00:00:00 2001 From: "Edgar E. Iglesias" Date: Mon, 22 Aug 2011 19:58:06 +0200 Subject: microblaze: Raise SIGFPE/FPE_INTDIV for div by zero It fixes the signal nr raised for divizion by zero from SIGILL to SIGFPE, in accordance to POSIX and other archs. This came up due to a failed test in the GCC testsuite. Signed-off-by: Edgar E. Iglesias --- arch/microblaze/kernel/exceptions.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch/microblaze') diff --git a/arch/microblaze/kernel/exceptions.c b/arch/microblaze/kernel/exceptions.c index 66fad230122..6348dc82f42 100644 --- a/arch/microblaze/kernel/exceptions.c +++ b/arch/microblaze/kernel/exceptions.c @@ -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 " \ -- cgit v1.2.3 From c8ae8a820880cf8bf3588752ac0ded6d4d218d50 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Fri, 23 Sep 2011 08:46:24 +0200 Subject: microblaze: Add __ucmpdi2() helper function Add missing __ucmpdi2 helper function. Error log: kernel/built-in.o: In function `print_graph_duration': : undefined reference to `__ucmpdi2' kernel/built-in.o: In function `print_graph_duration': : undefined reference to `__ucmpdi2' Based on MIPS code. Signed-off-by: Michal Simek --- arch/microblaze/lib/Makefile | 1 + arch/microblaze/lib/ucmpdi2.c | 20 ++++++++++++++++++++ 2 files changed, 21 insertions(+) create mode 100644 arch/microblaze/lib/ucmpdi2.c (limited to 'arch/microblaze') diff --git a/arch/microblaze/lib/Makefile b/arch/microblaze/lib/Makefile index 10c320aa908..c13067b243c 100644 --- a/arch/microblaze/lib/Makefile +++ b/arch/microblaze/lib/Makefile @@ -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 diff --git a/arch/microblaze/lib/ucmpdi2.c b/arch/microblaze/lib/ucmpdi2.c new file mode 100644 index 00000000000..63ca105b671 --- /dev/null +++ b/arch/microblaze/lib/ucmpdi2.c @@ -0,0 +1,20 @@ +#include + +#include "libgcc.h" + +word_type __ucmpdi2(unsigned long long a, unsigned long long b) +{ + const DWunion au = {.ll = a}; + const DWunion bu = {.ll = b}; + + if ((unsigned int) au.s.high < (unsigned int) bu.s.high) + return 0; + else if ((unsigned int) au.s.high > (unsigned int) bu.s.high) + return 2; + if ((unsigned int) au.s.low < (unsigned int) bu.s.low) + return 0; + else if ((unsigned int) au.s.low > (unsigned int) bu.s.low) + return 2; + return 1; +} +EXPORT_SYMBOL(__ucmpdi2); -- cgit v1.2.3 From 90fcf383636f452ab027656e4fb7e95c79aa878c Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Sun, 2 Oct 2011 09:12:37 +0200 Subject: microblaze: Remove NET_IP_ALIGN from system.h Use default value (which is the same) from include/linux/skbuff.h. Signed-off-by: Michal Simek --- arch/microblaze/include/asm/system.h | 7 ------- 1 file changed, 7 deletions(-) (limited to 'arch/microblaze') diff --git a/arch/microblaze/include/asm/system.h b/arch/microblaze/include/asm/system.h index e6a2284571d..0953d1425d5 100644 --- a/arch/microblaze/include/asm/system.h +++ b/arch/microblaze/include/asm/system.h @@ -96,11 +96,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 */ -- cgit v1.2.3 From cb5edfe3e553d930f9a13cb75cfe395ee38cde23 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Sun, 2 Oct 2011 13:07:02 +0200 Subject: microblaze: Use delay slot in __strnlen_user, __strncpy_user Use delay slot to speedup if maxlen is zero. Signed-off-by: Michal Simek --- arch/microblaze/lib/uaccess_old.S | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'arch/microblaze') diff --git a/arch/microblaze/lib/uaccess_old.S b/arch/microblaze/lib/uaccess_old.S index 142492ec270..f037266cdaf 100644 --- a/arch/microblaze/lib/uaccess_old.S +++ b/arch/microblaze/lib/uaccess_old.S @@ -34,8 +34,8 @@ __strncpy_user: * r3 - temp count * r4 - temp val */ + beqid r7,3f addik r3,r7,0 /* temp_count = len */ - beqi r3,3f 1: lbu r4,r6,r0 sb r4,r5,r0 @@ -77,8 +77,8 @@ __strncpy_user: .type __strnlen_user, @function .align 4; __strnlen_user: + beqid r6,3f addik r3,r6,0 - beqi r3,3f 1: lbu r4,r5,r0 beqid r4,2f /* break on NUL */ -- cgit v1.2.3 From 84ac218f0257a0cfd7689d9a44f53118dbf307b3 Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Wed, 24 Aug 2011 15:32:31 +0200 Subject: microblaze: Remove __ARCH_WANT_INTERRUPTS_ON_CTXSW usage As far as I can tell the only reason microblaze has __ARCH_WANT_INTERRUPTS_ON_CTXSW is because it initializes new task state with interrupts enabled so that on switch_to() interrupts get enabled. So change copy_thread() to clear MSR_IE instead of set it, this will ensure switch_to() will always keep IRQs disabled. The scheduler will disable IRQs when taking rq->lock in schedule() and enable IRQs in finish_lock_switch() after its done its magic. This leaves ARM the only __ARCH_WANT_INTERRUPTS_ON_CTXSW user. Signed-off-by: Peter Zijlstra Signed-off-by: Michal Simek --- arch/microblaze/include/asm/system.h | 2 -- arch/microblaze/kernel/process.c | 1 + 2 files changed, 1 insertion(+), 2 deletions(-) (limited to 'arch/microblaze') diff --git a/arch/microblaze/include/asm/system.h b/arch/microblaze/include/asm/system.h index 0953d1425d5..5a433cbaafb 100644 --- a/arch/microblaze/include/asm/system.h +++ b/arch/microblaze/include/asm/system.h @@ -17,8 +17,6 @@ #include #include -#define __ARCH_WANT_INTERRUPTS_ON_CTXSW - struct task_struct; struct thread_info; diff --git a/arch/microblaze/kernel/process.c b/arch/microblaze/kernel/process.c index dbb812421d8..95cc295976a 100644 --- a/arch/microblaze/kernel/process.c +++ b/arch/microblaze/kernel/process.c @@ -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; -- cgit v1.2.3