Skip to content

Commit

Permalink
microblaze: Add support for little-endian Microblaze
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Michal Simek committed Oct 21, 2010
1 parent e4f2909 commit 02b0804
Show file tree
Hide file tree
Showing 10 changed files with 42 additions and 18 deletions.
4 changes: 4 additions & 0 deletions arch/microblaze/include/asm/byteorder.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
#ifndef _ASM_MICROBLAZE_BYTEORDER_H
#define _ASM_MICROBLAZE_BYTEORDER_H

#ifdef __MICROBLAZEEL__
#include <linux/byteorder/little_endian.h>
#else
#include <linux/byteorder/big_endian.h>
#endif

#endif /* _ASM_MICROBLAZE_BYTEORDER_H */
9 changes: 7 additions & 2 deletions arch/microblaze/include/asm/checksum.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,13 @@ csum_tcpudp_nofold(__be32 saddr, __be32 daddr, unsigned short len,
"addc %0, %0, %3\n\t"
"addc %0, %0, r0\n\t"
: "+&d" (sum)
: "d" (saddr), "d" (daddr), "d" (len + proto));

: "d" (saddr), "d" (daddr),
#ifdef __MICROBLAZEEL__
"d" ((len + proto) << 8)
#else
"d" (len + proto)
#endif
);
return sum;
}

Expand Down
3 changes: 2 additions & 1 deletion arch/microblaze/include/asm/cpuinfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,8 @@ void set_cpuinfo_pvr_full(struct cpuinfo *ci, struct device_node *cpu);
static inline unsigned int fcpu(struct device_node *cpu, char *n)
{
int *val;
return (val = (int *) of_get_property(cpu, n, NULL)) ? *val : 0;
return (val = (int *) of_get_property(cpu, n, NULL)) ?
be32_to_cpup(val) : 0;
}

#endif /* _ASM_MICROBLAZE_CPUINFO_H */
2 changes: 1 addition & 1 deletion arch/microblaze/include/asm/elf.h
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG];

#define ELF_ET_DYN_BASE (0x08000000)

#ifdef __LITTLE_ENDIAN__
#ifdef __MICROBLAZEEL__
#define ELF_DATA ELFDATA2LSB
#else
#define ELF_DATA ELFDATA2MSB
Expand Down
12 changes: 9 additions & 3 deletions arch/microblaze/include/asm/unaligned.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,18 @@

# ifdef __KERNEL__

# include <linux/unaligned/be_struct.h>
# include <linux/unaligned/be_byteshift.h>
# include <linux/unaligned/le_byteshift.h>
# include <linux/unaligned/generic.h>

# define get_unaligned __get_unaligned_be
# define put_unaligned __put_unaligned_be

# ifdef __MICROBLAZEEL__
# define get_unaligned __get_unaligned_le
# define put_unaligned __put_unaligned_le
# else
# define get_unaligned __get_unaligned_be
# define put_unaligned __put_unaligned_be
# endif

# endif /* __KERNEL__ */
#endif /* _ASM_MICROBLAZE_UNALIGNED_H */
2 changes: 1 addition & 1 deletion arch/microblaze/kernel/heartbeat.c
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ void setup_heartbeat(void)
}

if (gpio) {
base_addr = *(int *) of_get_property(gpio, "reg", NULL);
base_addr = be32_to_cpup(of_get_property(gpio, "reg", NULL));
base_addr = (unsigned long) ioremap(base_addr, PAGE_SIZE);
printk(KERN_NOTICE "Heartbeat GPIO at 0x%x\n", base_addr);

Expand Down
9 changes: 6 additions & 3 deletions arch/microblaze/kernel/intc.c
Original file line number Diff line number Diff line change
Expand Up @@ -138,12 +138,15 @@ void __init init_IRQ(void)
}
BUG_ON(!intc);

intc_baseaddr = *(int *) of_get_property(intc, "reg", NULL);
intc_baseaddr = be32_to_cpup(of_get_property(intc,
"reg", NULL));
intc_baseaddr = (unsigned long) ioremap(intc_baseaddr, PAGE_SIZE);
nr_irq = *(int *) of_get_property(intc, "xlnx,num-intr-inputs", NULL);
nr_irq = be32_to_cpup(of_get_property(intc,
"xlnx,num-intr-inputs", NULL));

intr_type =
*(int *) of_get_property(intc, "xlnx,kind-of-intr", NULL);
be32_to_cpup(of_get_property(intc,
"xlnx,kind-of-intr", NULL));
if (intr_type >= (1 << (nr_irq + 1)))
printk(KERN_INFO " ERROR: Mismatch in kind-of-intr param\n");

Expand Down
7 changes: 4 additions & 3 deletions arch/microblaze/kernel/prom.c
Original file line number Diff line number Diff line change
Expand Up @@ -77,11 +77,12 @@ static int __init early_init_dt_scan_serial(unsigned long node,
/* find compatible node with uartlite */
p = of_get_flat_dt_prop(node, "compatible", &l);
if ((strncmp(p, "xlnx,xps-uartlite", 17) != 0) &&
(strncmp(p, "xlnx,opb-uartlite", 17) != 0))
(strncmp(p, "xlnx,opb-uartlite", 17) != 0) &&
(strncmp(p, "xlnx,axi-uartlite", 17) != 0))
return 0;

addr = of_get_flat_dt_prop(node, "reg", &l);
return *addr; /* return address */
return be32_to_cpup(addr); /* return address */
}

/* this function is looking for early uartlite console - Microblaze specific */
Expand Down Expand Up @@ -115,7 +116,7 @@ static int __init early_init_dt_scan_serial_full(unsigned long node,

addr = *(u32 *)of_get_flat_dt_prop(node, "reg", &l);
addr += *(u32 *)of_get_flat_dt_prop(node, "reg-offset", &l);
return addr; /* return address */
return be32_to_cpu(addr); /* return address */
}

/* this function is looking for early uartlite console - Microblaze specific */
Expand Down
8 changes: 4 additions & 4 deletions arch/microblaze/kernel/timer.c
Original file line number Diff line number Diff line change
Expand Up @@ -270,11 +270,11 @@ void __init time_init(void)
}
BUG_ON(!timer);

timer_baseaddr = *(int *) of_get_property(timer, "reg", NULL);
timer_baseaddr = be32_to_cpup(of_get_property(timer, "reg", NULL));
timer_baseaddr = (unsigned long) ioremap(timer_baseaddr, PAGE_SIZE);
irq = *(int *) of_get_property(timer, "interrupts", NULL);
timer_num =
*(int *) of_get_property(timer, "xlnx,one-timer-only", NULL);
irq = be32_to_cpup(of_get_property(timer, "interrupts", NULL));
timer_num = be32_to_cpup(of_get_property(timer,
"xlnx,one-timer-only", NULL));
if (timer_num) {
eprintk(KERN_EMERG "Please enable two timers in HW\n");
BUG();
Expand Down
4 changes: 4 additions & 0 deletions arch/microblaze/kernel/vmlinux.lds.S
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,11 @@ ENTRY(microblaze_start)
#include <asm-generic/vmlinux.lds.h>
#include <asm/thread_info.h>

#ifdef __MICROBLAZEEL__
jiffies = jiffies_64;
#else
jiffies = jiffies_64 + 4;
#endif

SECTIONS {
. = CONFIG_KERNEL_START;
Expand Down

0 comments on commit 02b0804

Please sign in to comment.