aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichal Simek <monstr@monstr.eu>2010-09-28 02:04:14 -0400
committerMichal Simek <monstr@monstr.eu>2010-10-21 01:51:59 -0400
commit02b08045a0306c38131c6d7155c4034a775d40b1 (patch)
treee146f1811ec3c93ff4877a895e42b71a91932d2b
parente4f29092272ee91a34d3660c31f15ed103057aa0 (diff)
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>
-rw-r--r--arch/microblaze/include/asm/byteorder.h4
-rw-r--r--arch/microblaze/include/asm/checksum.h9
-rw-r--r--arch/microblaze/include/asm/cpuinfo.h3
-rw-r--r--arch/microblaze/include/asm/elf.h2
-rw-r--r--arch/microblaze/include/asm/unaligned.h12
-rw-r--r--arch/microblaze/kernel/heartbeat.c2
-rw-r--r--arch/microblaze/kernel/intc.c9
-rw-r--r--arch/microblaze/kernel/prom.c7
-rw-r--r--arch/microblaze/kernel/timer.c8
-rw-r--r--arch/microblaze/kernel/vmlinux.lds.S4
10 files changed, 42 insertions, 18 deletions
diff --git a/arch/microblaze/include/asm/byteorder.h b/arch/microblaze/include/asm/byteorder.h
index ce9c58732ffc..31902762a426 100644
--- a/arch/microblaze/include/asm/byteorder.h
+++ b/arch/microblaze/include/asm/byteorder.h
@@ -1,6 +1,10 @@
1#ifndef _ASM_MICROBLAZE_BYTEORDER_H 1#ifndef _ASM_MICROBLAZE_BYTEORDER_H
2#define _ASM_MICROBLAZE_BYTEORDER_H 2#define _ASM_MICROBLAZE_BYTEORDER_H
3 3
4#ifdef __MICROBLAZEEL__
5#include <linux/byteorder/little_endian.h>
6#else
4#include <linux/byteorder/big_endian.h> 7#include <linux/byteorder/big_endian.h>
8#endif
5 9
6#endif /* _ASM_MICROBLAZE_BYTEORDER_H */ 10#endif /* _ASM_MICROBLAZE_BYTEORDER_H */
diff --git a/arch/microblaze/include/asm/checksum.h b/arch/microblaze/include/asm/checksum.h
index 128bf03b54b7..0185cbefdda4 100644
--- a/arch/microblaze/include/asm/checksum.h
+++ b/arch/microblaze/include/asm/checksum.h
@@ -24,8 +24,13 @@ csum_tcpudp_nofold(__be32 saddr, __be32 daddr, unsigned short len,
24 "addc %0, %0, %3\n\t" 24 "addc %0, %0, %3\n\t"
25 "addc %0, %0, r0\n\t" 25 "addc %0, %0, r0\n\t"
26 : "+&d" (sum) 26 : "+&d" (sum)
27 : "d" (saddr), "d" (daddr), "d" (len + proto)); 27 : "d" (saddr), "d" (daddr),
28 28#ifdef __MICROBLAZEEL__
29 "d" ((len + proto) << 8)
30#else
31 "d" (len + proto)
32#endif
33);
29 return sum; 34 return sum;
30} 35}
31 36
diff --git a/arch/microblaze/include/asm/cpuinfo.h b/arch/microblaze/include/asm/cpuinfo.h
index 0d4f0ce3ff7c..7fab800496ae 100644
--- a/arch/microblaze/include/asm/cpuinfo.h
+++ b/arch/microblaze/include/asm/cpuinfo.h
@@ -98,7 +98,8 @@ void set_cpuinfo_pvr_full(struct cpuinfo *ci, struct device_node *cpu);
98static inline unsigned int fcpu(struct device_node *cpu, char *n) 98static inline unsigned int fcpu(struct device_node *cpu, char *n)
99{ 99{
100 int *val; 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#endif /* _ASM_MICROBLAZE_CPUINFO_H */ 105#endif /* _ASM_MICROBLAZE_CPUINFO_H */
diff --git a/arch/microblaze/include/asm/elf.h b/arch/microblaze/include/asm/elf.h
index 732caf1be741..098dfdde4b06 100644
--- a/arch/microblaze/include/asm/elf.h
+++ b/arch/microblaze/include/asm/elf.h
@@ -71,7 +71,7 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG];
71 71
72#define ELF_ET_DYN_BASE (0x08000000) 72#define ELF_ET_DYN_BASE (0x08000000)
73 73
74#ifdef __LITTLE_ENDIAN__ 74#ifdef __MICROBLAZEEL__
75#define ELF_DATA ELFDATA2LSB 75#define ELF_DATA ELFDATA2LSB
76#else 76#else
77#define ELF_DATA ELFDATA2MSB 77#define ELF_DATA ELFDATA2MSB
diff --git a/arch/microblaze/include/asm/unaligned.h b/arch/microblaze/include/asm/unaligned.h
index 3658d91ac0fb..2b97cbe500e9 100644
--- a/arch/microblaze/include/asm/unaligned.h
+++ b/arch/microblaze/include/asm/unaligned.h
@@ -12,12 +12,18 @@
12 12
13# ifdef __KERNEL__ 13# ifdef __KERNEL__
14 14
15# include <linux/unaligned/be_struct.h> 15# include <linux/unaligned/be_byteshift.h>
16# include <linux/unaligned/le_byteshift.h> 16# include <linux/unaligned/le_byteshift.h>
17# include <linux/unaligned/generic.h> 17# include <linux/unaligned/generic.h>
18 18
19# define get_unaligned __get_unaligned_be 19
20# define put_unaligned __put_unaligned_be 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# endif /* __KERNEL__ */ 28# endif /* __KERNEL__ */
23#endif /* _ASM_MICROBLAZE_UNALIGNED_H */ 29#endif /* _ASM_MICROBLAZE_UNALIGNED_H */
diff --git a/arch/microblaze/kernel/heartbeat.c b/arch/microblaze/kernel/heartbeat.c
index 5c24eb8219f1..154756f3c694 100644
--- a/arch/microblaze/kernel/heartbeat.c
+++ b/arch/microblaze/kernel/heartbeat.c
@@ -59,7 +59,7 @@ void setup_heartbeat(void)
59 } 59 }
60 60
61 if (gpio) { 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 base_addr = (unsigned long) ioremap(base_addr, PAGE_SIZE); 63 base_addr = (unsigned long) ioremap(base_addr, PAGE_SIZE);
64 printk(KERN_NOTICE "Heartbeat GPIO at 0x%x\n", base_addr); 64 printk(KERN_NOTICE "Heartbeat GPIO at 0x%x\n", base_addr);
65 65
diff --git a/arch/microblaze/kernel/intc.c b/arch/microblaze/kernel/intc.c
index e85bbea1c62b..d61ea33aff7c 100644
--- a/arch/microblaze/kernel/intc.c
+++ b/arch/microblaze/kernel/intc.c
@@ -138,12 +138,15 @@ void __init init_IRQ(void)
138 } 138 }
139 BUG_ON(!intc); 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 intc_baseaddr = (unsigned long) ioremap(intc_baseaddr, PAGE_SIZE); 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 intr_type = 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 if (intr_type >= (1 << (nr_irq + 1))) 150 if (intr_type >= (1 << (nr_irq + 1)))
148 printk(KERN_INFO " ERROR: Mismatch in kind-of-intr param\n"); 151 printk(KERN_INFO " ERROR: Mismatch in kind-of-intr param\n");
149 152
diff --git a/arch/microblaze/kernel/prom.c b/arch/microblaze/kernel/prom.c
index 608e5cf2e10a..04d3325039d9 100644
--- a/arch/microblaze/kernel/prom.c
+++ b/arch/microblaze/kernel/prom.c
@@ -77,11 +77,12 @@ static int __init early_init_dt_scan_serial(unsigned long node,
77/* find compatible node with uartlite */ 77/* find compatible node with uartlite */
78 p = of_get_flat_dt_prop(node, "compatible", &l); 78 p = of_get_flat_dt_prop(node, "compatible", &l);
79 if ((strncmp(p, "xlnx,xps-uartlite", 17) != 0) && 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 return 0; 82 return 0;
82 83
83 addr = of_get_flat_dt_prop(node, "reg", &l); 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/* this function is looking for early uartlite console - Microblaze specific */ 88/* this function is looking for early uartlite console - Microblaze specific */
@@ -115,7 +116,7 @@ static int __init early_init_dt_scan_serial_full(unsigned long node,
115 116
116 addr = *(u32 *)of_get_flat_dt_prop(node, "reg", &l); 117 addr = *(u32 *)of_get_flat_dt_prop(node, "reg", &l);
117 addr += *(u32 *)of_get_flat_dt_prop(node, "reg-offset", &l); 118 addr += *(u32 *)of_get_flat_dt_prop(node, "reg-offset", &l);
118 return addr; /* return address */ 119 return be32_to_cpu(addr); /* return address */
119} 120}
120 121
121/* this function is looking for early uartlite console - Microblaze specific */ 122/* this function is looking for early uartlite console - Microblaze specific */
diff --git a/arch/microblaze/kernel/timer.c b/arch/microblaze/kernel/timer.c
index 64ca14dbac6e..fcb97e86003d 100644
--- a/arch/microblaze/kernel/timer.c
+++ b/arch/microblaze/kernel/timer.c
@@ -270,11 +270,11 @@ void __init time_init(void)
270 } 270 }
271 BUG_ON(!timer); 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 timer_baseaddr = (unsigned long) ioremap(timer_baseaddr, PAGE_SIZE); 274 timer_baseaddr = (unsigned long) ioremap(timer_baseaddr, PAGE_SIZE);
275 irq = *(int *) of_get_property(timer, "interrupts", NULL); 275 irq = be32_to_cpup(of_get_property(timer, "interrupts", NULL));
276 timer_num = 276 timer_num = be32_to_cpup(of_get_property(timer,
277 *(int *) of_get_property(timer, "xlnx,one-timer-only", NULL); 277 "xlnx,one-timer-only", NULL));
278 if (timer_num) { 278 if (timer_num) {
279 eprintk(KERN_EMERG "Please enable two timers in HW\n"); 279 eprintk(KERN_EMERG "Please enable two timers in HW\n");
280 BUG(); 280 BUG();
diff --git a/arch/microblaze/kernel/vmlinux.lds.S b/arch/microblaze/kernel/vmlinux.lds.S
index 20b0552391d1..96a88c31fe48 100644
--- a/arch/microblaze/kernel/vmlinux.lds.S
+++ b/arch/microblaze/kernel/vmlinux.lds.S
@@ -15,7 +15,11 @@ ENTRY(microblaze_start)
15#include <asm-generic/vmlinux.lds.h> 15#include <asm-generic/vmlinux.lds.h>
16#include <asm/thread_info.h> 16#include <asm/thread_info.h>
17 17
18#ifdef __MICROBLAZEEL__
19jiffies = jiffies_64;
20#else
18jiffies = jiffies_64 + 4; 21jiffies = jiffies_64 + 4;
22#endif
19 23
20SECTIONS { 24SECTIONS {
21 . = CONFIG_KERNEL_START; 25 . = CONFIG_KERNEL_START;