Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

microblaze: Add support for little-endian Microblaze

Microblaze little-endian toolchain exports __MICROBLAZEEL__
which is used in the kernel to identify little/big endian.

The most of the changes are in loading values from DTB which
is always big endian.

Little endian platforms are based on new AXI bus which has
impact to early uartlite initialization.

Signed-off-by: Michal Simek <monstr@monstr.eu>

+42 -18
+4
arch/microblaze/include/asm/byteorder.h
··· 1 1 #ifndef _ASM_MICROBLAZE_BYTEORDER_H 2 2 #define _ASM_MICROBLAZE_BYTEORDER_H 3 3 4 + #ifdef __MICROBLAZEEL__ 5 + #include <linux/byteorder/little_endian.h> 6 + #else 4 7 #include <linux/byteorder/big_endian.h> 8 + #endif 5 9 6 10 #endif /* _ASM_MICROBLAZE_BYTEORDER_H */
+7 -2
arch/microblaze/include/asm/checksum.h
··· 24 24 "addc %0, %0, %3\n\t" 25 25 "addc %0, %0, r0\n\t" 26 26 : "+&d" (sum) 27 - : "d" (saddr), "d" (daddr), "d" (len + proto)); 28 - 27 + : "d" (saddr), "d" (daddr), 28 + #ifdef __MICROBLAZEEL__ 29 + "d" ((len + proto) << 8) 30 + #else 31 + "d" (len + proto) 32 + #endif 33 + ); 29 34 return sum; 30 35 } 31 36
+2 -1
arch/microblaze/include/asm/cpuinfo.h
··· 98 98 static inline unsigned int fcpu(struct device_node *cpu, char *n) 99 99 { 100 100 int *val; 101 - return (val = (int *) of_get_property(cpu, n, NULL)) ? *val : 0; 101 + return (val = (int *) of_get_property(cpu, n, NULL)) ? 102 + be32_to_cpup(val) : 0; 102 103 } 103 104 104 105 #endif /* _ASM_MICROBLAZE_CPUINFO_H */
+1 -1
arch/microblaze/include/asm/elf.h
··· 71 71 72 72 #define ELF_ET_DYN_BASE (0x08000000) 73 73 74 - #ifdef __LITTLE_ENDIAN__ 74 + #ifdef __MICROBLAZEEL__ 75 75 #define ELF_DATA ELFDATA2LSB 76 76 #else 77 77 #define ELF_DATA ELFDATA2MSB
+9 -3
arch/microblaze/include/asm/unaligned.h
··· 12 12 13 13 # ifdef __KERNEL__ 14 14 15 - # include <linux/unaligned/be_struct.h> 15 + # include <linux/unaligned/be_byteshift.h> 16 16 # include <linux/unaligned/le_byteshift.h> 17 17 # include <linux/unaligned/generic.h> 18 18 19 - # define get_unaligned __get_unaligned_be 20 - # define put_unaligned __put_unaligned_be 19 + 20 + # ifdef __MICROBLAZEEL__ 21 + # define get_unaligned __get_unaligned_le 22 + # define put_unaligned __put_unaligned_le 23 + # else 24 + # define get_unaligned __get_unaligned_be 25 + # define put_unaligned __put_unaligned_be 26 + # endif 21 27 22 28 # endif /* __KERNEL__ */ 23 29 #endif /* _ASM_MICROBLAZE_UNALIGNED_H */
+1 -1
arch/microblaze/kernel/heartbeat.c
··· 59 59 } 60 60 61 61 if (gpio) { 62 - base_addr = *(int *) of_get_property(gpio, "reg", NULL); 62 + base_addr = be32_to_cpup(of_get_property(gpio, "reg", NULL)); 63 63 base_addr = (unsigned long) ioremap(base_addr, PAGE_SIZE); 64 64 printk(KERN_NOTICE "Heartbeat GPIO at 0x%x\n", base_addr); 65 65
+6 -3
arch/microblaze/kernel/intc.c
··· 138 138 } 139 139 BUG_ON(!intc); 140 140 141 - intc_baseaddr = *(int *) of_get_property(intc, "reg", NULL); 141 + intc_baseaddr = be32_to_cpup(of_get_property(intc, 142 + "reg", NULL)); 142 143 intc_baseaddr = (unsigned long) ioremap(intc_baseaddr, PAGE_SIZE); 143 - nr_irq = *(int *) of_get_property(intc, "xlnx,num-intr-inputs", NULL); 144 + nr_irq = be32_to_cpup(of_get_property(intc, 145 + "xlnx,num-intr-inputs", NULL)); 144 146 145 147 intr_type = 146 - *(int *) of_get_property(intc, "xlnx,kind-of-intr", NULL); 148 + be32_to_cpup(of_get_property(intc, 149 + "xlnx,kind-of-intr", NULL)); 147 150 if (intr_type >= (1 << (nr_irq + 1))) 148 151 printk(KERN_INFO " ERROR: Mismatch in kind-of-intr param\n"); 149 152
+4 -3
arch/microblaze/kernel/prom.c
··· 77 77 /* find compatible node with uartlite */ 78 78 p = of_get_flat_dt_prop(node, "compatible", &l); 79 79 if ((strncmp(p, "xlnx,xps-uartlite", 17) != 0) && 80 - (strncmp(p, "xlnx,opb-uartlite", 17) != 0)) 80 + (strncmp(p, "xlnx,opb-uartlite", 17) != 0) && 81 + (strncmp(p, "xlnx,axi-uartlite", 17) != 0)) 81 82 return 0; 82 83 83 84 addr = of_get_flat_dt_prop(node, "reg", &l); 84 - return *addr; /* return address */ 85 + return be32_to_cpup(addr); /* return address */ 85 86 } 86 87 87 88 /* this function is looking for early uartlite console - Microblaze specific */ ··· 116 115 117 116 addr = *(u32 *)of_get_flat_dt_prop(node, "reg", &l); 118 117 addr += *(u32 *)of_get_flat_dt_prop(node, "reg-offset", &l); 119 - return addr; /* return address */ 118 + return be32_to_cpu(addr); /* return address */ 120 119 } 121 120 122 121 /* this function is looking for early uartlite console - Microblaze specific */
+4 -4
arch/microblaze/kernel/timer.c
··· 270 270 } 271 271 BUG_ON(!timer); 272 272 273 - timer_baseaddr = *(int *) of_get_property(timer, "reg", NULL); 273 + timer_baseaddr = be32_to_cpup(of_get_property(timer, "reg", NULL)); 274 274 timer_baseaddr = (unsigned long) ioremap(timer_baseaddr, PAGE_SIZE); 275 - irq = *(int *) of_get_property(timer, "interrupts", NULL); 276 - timer_num = 277 - *(int *) of_get_property(timer, "xlnx,one-timer-only", NULL); 275 + irq = be32_to_cpup(of_get_property(timer, "interrupts", NULL)); 276 + timer_num = be32_to_cpup(of_get_property(timer, 277 + "xlnx,one-timer-only", NULL)); 278 278 if (timer_num) { 279 279 eprintk(KERN_EMERG "Please enable two timers in HW\n"); 280 280 BUG();
+4
arch/microblaze/kernel/vmlinux.lds.S
··· 15 15 #include <asm-generic/vmlinux.lds.h> 16 16 #include <asm/thread_info.h> 17 17 18 + #ifdef __MICROBLAZEEL__ 19 + jiffies = jiffies_64; 20 + #else 18 21 jiffies = jiffies_64 + 4; 22 + #endif 19 23 20 24 SECTIONS { 21 25 . = CONFIG_KERNEL_START;