Skip to content

Commit

Permalink
kexec/ppc64: bring up new ppc64le architecture
Browse files Browse the repository at this point in the history
This patch provides support for the new Power PC litte endian (LE) mode. The
LE mode only differs in the way the instructions and data are stored in memory
thus there is no real need to duplicate the ppc64 code.

However some compilation's options, especially for the purgatory, differ
between little and big endian mode's support. A new "SUBARCH" build variable
is introduced which is currently only used for PPC64 to specify the
endianness.

Another set of changes in this patch is fixing minor endianess issues in the
ppc64 code and fix an alignment issue raised on Power7 little endian mode.
Among these fixes, the check on the kernel binary endianess is removed,
since we can imagine kexecing a LE kernel from a BE environment, as far as
the specified root filesystem and initrd file are containing the right
binaries.

This patch depends on the patch "kexec/ppc64: use common architecture
fs2dt.c file" I sent earlier on the kexec mailing list.

Signed-off-by: Laurent Dufour <[email protected]>
Signed-off-by: Simon Horman <[email protected]>
  • Loading branch information
Laurent Dufour authored and horms committed Nov 19, 2013
1 parent 818d452 commit 75efb89
Show file tree
Hide file tree
Showing 8 changed files with 25 additions and 8 deletions.
1 change: 1 addition & 0 deletions Makefile.in
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ includedir = @includedir@

# The target architecture
ARCH = @ARCH@
SUBARCH = @SUBARCH@
OBJDIR = @OBJDIR@
target = @target@
host = @host@
Expand Down
5 changes: 4 additions & 1 deletion config/config.guess
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
# 2011, 2012 Free Software Foundation, Inc.

timestamp='2012-02-10'
timestamp='2013-10-21'

# This file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
Expand Down Expand Up @@ -972,6 +972,9 @@ EOF
ppc64:Linux:*:*)
echo powerpc64-unknown-linux-gnu
exit ;;
ppc64le:Linux:*:*)
echo powerpc64le-unknown-linux-gnu
exit ;;
ppc:Linux:*:*)
echo powerpc-unknown-linux-gnu
exit ;;
Expand Down
6 changes: 6 additions & 0 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,11 @@ case $target_cpu in
;;
powerpc64 )
ARCH="ppc64"
SUBARCH="BE"
;;
powerpc64le )
ARCH="ppc64"
SUBARCH="LE"
;;
arm* )
ARCH="arm"
Expand Down Expand Up @@ -197,6 +202,7 @@ AC_SUBST([TARGET_CFLAGS])
AC_SUBST([ASFLAGS])

AC_SUBST([ARCH])
AC_SUBST([SUBARCH])
AC_SUBST([OBJDIR])
AC_SUBST([INSTALL])

Expand Down
6 changes: 3 additions & 3 deletions kexec/arch/ppc64/kexec-elf-ppc64.c
Original file line number Diff line number Diff line change
Expand Up @@ -237,13 +237,13 @@ int elf_ppc64_load(int argc, char **argv, const char *buf, off_t len,
* entry is before this one
*/
bb_ptr = (struct bootblock *)(seg_buf);
rsvmap_ptr = (uint64_t *)(seg_buf + bb_ptr->off_mem_rsvmap);
rsvmap_ptr = (uint64_t *)(seg_buf + be32_to_cpu(bb_ptr->off_mem_rsvmap));
while (*rsvmap_ptr || *(rsvmap_ptr+1))
rsvmap_ptr += 2;
rsvmap_ptr -= 2;
*rsvmap_ptr = my_dt_offset;
*rsvmap_ptr = cpu_to_be64(my_dt_offset);
rsvmap_ptr++;
*rsvmap_ptr = bb_ptr->totalsize;
*rsvmap_ptr = cpu_to_be64((uint64_t)be32_to_cpu(bb_ptr->totalsize));
#endif

/* Set kernel */
Expand Down
3 changes: 0 additions & 3 deletions kexec/arch/ppc64/kexec-elf-rel-ppc64.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,6 @@

int machine_verify_elf_rel(struct mem_ehdr *ehdr)
{
if (ehdr->ei_data != ELFDATA2MSB) {
return 0;
}
if (ehdr->ei_class != ELFCLASS64) {
return 0;
}
Expand Down
3 changes: 3 additions & 0 deletions kexec/arch/ppc64/kexec-ppc64.c
Original file line number Diff line number Diff line change
Expand Up @@ -532,6 +532,7 @@ static int get_devtree_details(unsigned long kexec_flags)
perror(fname);
goto error_openfile;
}
rtas_base = be32_to_cpu(rtas_base);
memset(fname, 0, sizeof(fname));
strcpy(fname, device_tree);
strcat(fname, dentry->d_name);
Expand All @@ -545,6 +546,7 @@ static int get_devtree_details(unsigned long kexec_flags)
goto error_openfile;
}
closedir(cdir);
rtas_size = be32_to_cpu(rtas_size);
/* Add rtas to exclude_range */
exclude_range[i].start = rtas_base;
exclude_range[i].end = rtas_base + rtas_size;
Expand Down Expand Up @@ -798,6 +800,7 @@ const struct arch_map_entry arches[] = {
* So pass KEXEC_ARCH_PPC64 here
*/
{ "ppc64", KEXEC_ARCH_PPC64 },
{ "ppc64le", KEXEC_ARCH_PPC64 },
{ NULL, 0 },
};

Expand Down
8 changes: 7 additions & 1 deletion purgatory/arch/ppc64/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,13 @@ ppc64_PURGATORY_SRCS += purgatory/arch/ppc64/misc.S

ppc64_PURGATORY_EXTRA_CFLAGS += -m64 -mcall-aixdesc -msoft-float
ppc64_PURGATORY_EXTRA_ASFLAGS += -m64 -mcall-aixdesc
ppc64_PURGATORY_EXTRA_LDFLAGS += -melf64ppc
ifeq ($(SUBARCH),BE)
ppc64_PURGATORY_EXTRA_LDFLAGS += -melf64ppc
else
ppc64_PURGATORY_EXTRA_LDFLAGS += -melf64lppc
ppc64_PURGATORY_EXTRA_CFLAGS += -mlittle-endian
ppc64_PURGATORY_EXTRA_ASFLAGS += -mlittle-endian
endif

dist += purgatory/arch/ppc64/Makefile $(ppc64_PURGATORY_SRCS) \
purgatory/arch/ppc64/hvCall.h \
Expand Down
1 change: 1 addition & 0 deletions purgatory/arch/ppc64/v2wrap.S
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
ori rn,rn,name##@l

.machine ppc64
.align 8
.globl purgatory_start
purgatory_start: b master
.org purgatory_start + 0x5c # ABI: possible run_at_load flag at 0x5c
Expand Down

0 comments on commit 75efb89

Please sign in to comment.