From patchwork Tue Oct 15 03:07:14 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nicholas Piggin X-Patchwork-Id: 1176755 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.ozlabs.org (lists.ozlabs.org [203.11.71.2]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 46sgfp25G1z9sPJ for ; Tue, 15 Oct 2019 14:20:34 +1100 (AEDT) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="Te/yLon9"; dkim-atps=neutral Received: from bilbo.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) by lists.ozlabs.org (Postfix) with ESMTP id 46sgfn0M92zDqkW for ; Tue, 15 Oct 2019 14:20:33 +1100 (AEDT) X-Original-To: skiboot@lists.ozlabs.org Delivered-To: skiboot@lists.ozlabs.org Authentication-Results: lists.ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=gmail.com (client-ip=2607:f8b0:4864:20::543; helo=mail-pg1-x543.google.com; envelope-from=npiggin@gmail.com; receiver=) Authentication-Results: lists.ozlabs.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: lists.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="Te/yLon9"; dkim-atps=neutral Received: from mail-pg1-x543.google.com (mail-pg1-x543.google.com [IPv6:2607:f8b0:4864:20::543]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by lists.ozlabs.org (Postfix) with ESMTPS id 46sgV86V1mzDqgB for ; Tue, 15 Oct 2019 14:13:04 +1100 (AEDT) Received: by mail-pg1-x543.google.com with SMTP id e10so7219516pgd.11 for ; Mon, 14 Oct 2019 20:13:04 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=WDZrDcqMSwlgakEugGDmBMAhVGiG3L2Vm5eipi9WBks=; b=Te/yLon979/vBqdFP98bRx0MfIM8PcqV7wx5KvTd+twsJ3/H3JI4vX+xM431xio7Li 4O8no3dA8+yfOFPCSacQKaykgz3QYSbJ9cfRK/IrGX64HQFU10prk66wFDiE0u0IDmIM c7l1vbMLzwgoqJKaAGJcVBjh9BTnMv2Xl2IdQN+DH30gILGSmu2xq3MPJPzpPt1QxaNt JCxjeHiXTwQakQI651Gq6HmBYkS8KPBPVZ11W6iOIQFKrn9glIrXDSyUvsZs/Gn8yarf B/mT1//GDxbZckc8s2Pz9k+tpIpTCogblgbMm6ddtSW8dXCyLGHNrXCDzwFTS2rLcs7P STTg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=WDZrDcqMSwlgakEugGDmBMAhVGiG3L2Vm5eipi9WBks=; b=NN3Ei0GeUvkTEVSHXqqXZXs01T981pi7eK/SC6mqbpOd5+XMiRxCJg0vnRk/DXXYkK AuhHVKiRjPPLhIcnEyFs52G8UFDF5DHvkgO6nqUdY2WgAn/Wj8IzJLfM4P3ZVbRLRxvW /KpDg1/sgl/qWqr5Tei2XKcPXe5WnrEQIDlkNQhmUWxZWL9xciAs7DUbQe4esg0+1MzN jetGHh9b7aBs47WJWLW2B3nJNjprwXMlZCt9ejnjZvnm7nuM6xcIXM/sAo5WNA3r+jwH b/yFTrUuG7u2yp7ACvLwco+BoNPc4/YBCG0E3ixYtvXk26tBwqC3w5fTKGrnFZIKOirZ lyTA== X-Gm-Message-State: APjAAAWiMNh3NhkymtuqaI4GRz8Ki3GWZnPJfPXCP51E7B03iJKrfIfU C77YA111InoRxhZiXJM0YGEYj4UOmMI= X-Google-Smtp-Source: APXvYqym3+mllXqtCcQZjaFUB3kQu5WKGMkaELID9ribuzBHdCHDF9H2H87Ybn8myJyBL6fiFSXZXg== X-Received: by 2002:a17:90a:a781:: with SMTP id f1mr40712289pjq.29.1571109180624; Mon, 14 Oct 2019 20:13:00 -0700 (PDT) Received: from bobo.local0.net (60-240-111-58.tpgi.com.au. [60.240.111.58]) by smtp.gmail.com with ESMTPSA id w6sm23089828pfw.84.2019.10.14.20.12.58 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 14 Oct 2019 20:13:00 -0700 (PDT) From: Nicholas Piggin To: skiboot@lists.ozlabs.org Date: Tue, 15 Oct 2019 13:07:14 +1000 Message-Id: <20191015030717.15637-25-npiggin@gmail.com> X-Mailer: git-send-email 2.23.0 In-Reply-To: <20191015030717.15637-1-npiggin@gmail.com> References: <20191015030717.15637-1-npiggin@gmail.com> MIME-Version: 1.0 Subject: [Skiboot] [PATCH v5 24/27] add little endian support X-BeenThere: skiboot@lists.ozlabs.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Mailing list for skiboot development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: skiboot-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org Sender: "Skiboot" This adds support for building LE skiboot with LITTLE_ENDIAN=1. This is not complete, notably PHB3, NPU* and *CAPI*, but it is sufficient to build and boot on mambo and OpenPOWER POWER9 systems. LE/ELFv2 is a nicer calling convention, and results in smaller image and less stack usage. It also follows the rest of the Linux/OpenPOWER stack moving to LE. The OPALv3 call interface still requires an ugly transition through BE for compatibility, but that is all handled on the OPAL side. Signed-off-by: Nicholas Piggin --- Makefile.main | 38 ++++++++++++-- asm/head.S | 66 +++++++++++++++++------- core/cpu.c | 24 +++++++-- core/init.c | 1 + doc/stb.rst | 2 +- include/asm-utils.h | 22 ++++++-- include/cpu.h | 3 ++ libpore/p9_cpu_reg_restore_instruction.H | 23 +++++---- 8 files changed, 135 insertions(+), 44 deletions(-) diff --git a/Makefile.main b/Makefile.main index 2d60bbbf5..1d834e81b 100644 --- a/Makefile.main +++ b/Makefile.main @@ -65,21 +65,35 @@ CPPFLAGS += -I$(SRC)/libfdt -I$(SRC)/libflash -I$(SRC)/libxz -I$(SRC)/libc/inclu CPPFLAGS += -I$(SRC)/libpore CPPFLAGS += -D__SKIBOOT__ -nostdinc CPPFLAGS += -isystem $(shell $(CC) -print-file-name=include) -CPPFLAGS += -DBITS_PER_LONG=64 -DHAVE_BIG_ENDIAN +CPPFLAGS += -DBITS_PER_LONG=64 + # We might want to remove our copy of stdint.h # but that means uint64_t becomes an ulong instead of an ullong # causing all our printf's to warn CPPFLAGS += -ffreestanding +ifeq ($(LITTLE_ENDIAN),1) +CPPFLAGS += -DHAVE_LITTLE_ENDIAN +else +CPPFLAGS += -DHAVE_BIG_ENDIAN +endif + ifeq ($(DEBUG),1) CPPFLAGS += -DDEBUG -DCCAN_LIST_DEBUG endif -CFLAGS := -fno-strict-aliasing -pie -fpie -fno-pic -mbig-endian -m64 -fno-asynchronous-unwind-tables +CFLAGS := -fno-strict-aliasing -pie -fpie -fno-pic -m64 -fno-asynchronous-unwind-tables CFLAGS += -mcpu=power8 CFLAGS += -Wl,--oformat,elf64-powerpc -ggdb CFLAGS += $(call try-cflag,$(CC),-ffixed-r13) CFLAGS += $(call try-cflag,$(CC),-std=gnu11) + +ifeq ($(LITTLE_ENDIAN),1) +CFLAGS += -mlittle-endian +else +CFLAGS += -mbig-endian +endif + ifeq ($(ELF_ABI_v2),1) CFLAGS += $(call try-cflag,$(CC),-mabi=elfv2) else @@ -135,8 +149,8 @@ LDFLAGS := -m64 -static -nostdlib -pie LDFLAGS += -Wl,-pie LDFLAGS += -Wl,-Ttext-segment,$(LD_TEXT) -Wl,-N -Wl,--build-id=none LDFLAGS += -Wl,--no-multi-toc -LDFLAGS += -mcpu=power8 -mbig-endian -Wl,--oformat,elf64-powerpc -LDFLAGS_FINAL = -EB -m elf64ppc --no-multi-toc -N --build-id=none --whole-archive +LDFLAGS += -mcpu=power8 -Wl,--oformat,elf64-powerpc +LDFLAGS_FINAL = -m elf64lppc --no-multi-toc -N --build-id=none --whole-archive LDFLAGS_FINAL += -static -nostdlib -pie -Ttext-segment=$(LD_TEXT) --oformat=elf64-powerpc LDFLAGS_FINAL += --orphan-handling=warn @@ -144,11 +158,25 @@ LDRFLAGS=-melf64ppc # Debug stuff #LDFLAGS += -Wl,-v -Wl,-Map,foomap +ifeq ($(LITTLE_ENDIAN),1) +LDFLAGS += -mlittle-endian +LDFLAGS_FINAL += -EL +else +LDFLAGS += -mbig-endian +LDFLAGS_FINAL += -EB +endif + ifeq ($(DEAD_CODE_ELIMINATION),1) LDFLAGS += -Wl,--gc-sections endif -AFLAGS := -D__ASSEMBLY__ -mbig-endian -m64 +AFLAGS := -D__ASSEMBLY__ -m64 +ifeq ($(LITTLE_ENDIAN),1) +AFLAGS += -mlittle-endian +else +AFLAGS += -mbig-endian +endif + ifeq ($(ELF_ABI_v2),1) AFLAGS += $(call try-cflag,$(CC),-mabi=elfv2) else diff --git a/asm/head.S b/asm/head.S index e70462299..d396f16c9 100644 --- a/asm/head.S +++ b/asm/head.S @@ -43,6 +43,7 @@ __head: . = 0x10 .global fdt_entry fdt_entry: + FIXUP_ENDIAN mr %r27,%r3 b boot_entry @@ -89,6 +90,7 @@ hir_trigger: . = 0x100 sreset_vector: /* BML entry, load up r3 with device tree location */ + FIXUP_ENDIAN li %r3, 0 oris %r3, %r3, 0xa b fdt_entry /* hack for lab boot */ @@ -96,6 +98,7 @@ sreset_vector: /* Entry point set by the FSP */ .= 0x180 hdat_entry: + FIXUP_ENDIAN li %r27,0 b boot_entry @@ -364,7 +367,11 @@ boot_entry: add %r2,%r2,%r29 /* Fixup our MSR (remove TA) */ +#if HAVE_BIG_ENDIAN LOAD_IMM64(%r3, (MSR_HV | MSR_SF)) +#else + LOAD_IMM64(%r3, (MSR_HV | MSR_SF | MSR_LE)) +#endif mtmsrd %r3,0 /* Check our PIR, avoid threads */ @@ -698,14 +705,18 @@ init_shared_sprs: mtspr SPR_TSCR, %r3 /* HID0: Clear bit 13 (enable core recovery) - * Clear bit 19 (HILE) + * Set/clear bit 19 (HILE) depending on skiboot endian */ mfspr %r3,SPR_HID0 li %r0,1 sldi %r4,%r0,(63-13) - sldi %r5,%r0,(63-19) - or %r0,%r4,%r5 - andc %r3,%r3,%r0 + andc %r3,%r3,%r4 + sldi %r4,%r0,(63-19) +#if HAVE_BIG_ENDIAN + andc %r3,%r3,%r4 +#else + or %r3,%r3,%r4 +#endif sync mtspr SPR_HID0,%r3 mfspr %r3,SPR_HID0 @@ -732,17 +743,21 @@ init_shared_sprs: LOAD_IMM32(%r3,0x80287880) mtspr SPR_TSCR, %r3 /* HID0: Clear bit 5 (enable core recovery) - * Clear bit 4 (HILE) + * Set/clear bit 4 (HILE) depending on skiboot endian * Set bit 8 (radix) */ mfspr %r3,SPR_HID0 li %r0,1 - sldi %r4,%r0,(63-8) + sldi %r4,%r0,(63-4) +#if HAVE_BIG_ENDIAN + andc %r3,%r3,%r4 +#else or %r3,%r3,%r4 +#endif sldi %r4,%r0,(63-5) - sldi %r5,%r0,(63-4) - or %r0,%r4,%r5 - andc %r3,%r3,%r0 + andc %r3,%r3,%r4 + sldi %r4,%r0,(63-8) + or %r3,%r3,%r4 sync mtspr SPR_HID0,%r3 isync @@ -822,6 +837,8 @@ enter_nap: .balign 0x10 .global opal_entry opal_entry: + OPAL_ENTRY_TO_SKIBOOT_ENDIAN + /* Get our per CPU pointer in r12 to check for quiesce */ mfspr %r12,SPR_PIR GET_STACK(%r12,%r12) @@ -968,20 +985,33 @@ opal_entry: lwz %r11,CPUTHREAD_IN_OPAL_CALL(%r12) subi %r11,%r11,1 stw %r11,CPUTHREAD_IN_OPAL_CALL(%r12) +#if HAVE_BIG_ENDIAN /* * blr with BH=01b means it's not a function return, OPAL was entered * via (h)rfid not bl, so we don't have a corresponding link stack * prediction to return to here. */ bclr 20,0,1 +#else + mflr %r12 + mtspr SPR_HSRR0,%r12 + mfmsr %r11 + li %r12,MSR_LE + andc %r11,%r11,%r12 + mtspr SPR_HSRR1,%r11 + hrfid +#endif .global start_kernel start_kernel: + LOAD_IMM64(%r10,MSR_HV|MSR_SF) +__start_kernel: sync icbi 0,%r3 sync isync - mtctr %r3 + mtspr SPR_HSRR0,%r3 + mtspr SPR_HSRR1,%r10 mr %r3,%r4 LOAD_IMM64(%r8,SKIBOOT_BASE); LOAD_IMM32(%r10, opal_entry - __head) @@ -990,21 +1020,19 @@ start_kernel: addi %r7,%r5,1 li %r4,0 li %r5,0 - bctr + hrfid .global start_kernel32 start_kernel32: - mfmsr %r10 - clrldi %r10,%r10,1 - mtmsrd %r10,0 - sync - isync - b start_kernel + LOAD_IMM64(%r10,MSR_HV) + b __start_kernel .global start_kernel_secondary start_kernel_secondary: sync isync - mtctr %r3 + LOAD_IMM64(%r10,MSR_HV|MSR_SF) + mtspr SPR_HSRR0,%r3 + mtspr SPR_HSRR1,%r10 mfspr %r3,SPR_PIR - bctr + hrfid diff --git a/core/cpu.c b/core/cpu.c index b3433aef5..3d6a59033 100644 --- a/core/cpu.c +++ b/core/cpu.c @@ -42,7 +42,7 @@ static unsigned long hid0_attn; static bool sreset_enabled; static bool ipi_enabled; static bool pm_enabled; -static bool current_hile_mode; +static bool current_hile_mode = HAVE_LITTLE_ENDIAN; static bool current_radix_mode = true; static bool tm_suspend_enabled; @@ -1415,6 +1415,24 @@ static int64_t cpu_change_all_hid0(struct hid0_change_req *req) return OPAL_SUCCESS; } +void cpu_set_hile_mode(bool hile) +{ + struct hid0_change_req req; + + if (hile == current_hile_mode) + return; + + if (hile) { + req.clr_bits = 0; + req.set_bits = hid0_hile; + } else { + req.clr_bits = hid0_hile; + req.set_bits = 0; + } + cpu_change_all_hid0(&req); + current_hile_mode = hile; +} + static void cpu_cleanup_one(void *param __unused) { mtspr(SPR_AMR, 0); @@ -1453,8 +1471,8 @@ static int64_t cpu_cleanup_all(void) void cpu_fast_reboot_complete(void) { - /* Fast reboot will have cleared HID0:HILE */ - current_hile_mode = false; + /* Fast reboot will have set HID0:HILE to skiboot endian */ + current_hile_mode = HAVE_LITTLE_ENDIAN; /* and set HID0:RADIX */ current_radix_mode = true; diff --git a/core/init.c b/core/init.c index 67185c9e1..0b63655bc 100644 --- a/core/init.c +++ b/core/init.c @@ -630,6 +630,7 @@ void __noreturn load_and_boot_kernel(bool is_reboot) cpu_disable_ME_RI_all(); patch_traps(false); + cpu_set_hile_mode(false); /* Clear HILE on all CPUs */ debug_descriptor.state_flags |= OPAL_BOOT_COMPLETE; diff --git a/doc/stb.rst b/doc/stb.rst index 6fc8f73da..84855ca55 100644 --- a/doc/stb.rst +++ b/doc/stb.rst @@ -92,7 +92,7 @@ CVC-verify Service .. code-block:: c int call_cvc_verify(void *buf, size_t size, const void *hw_key_hash, - size_t hw_key_hash_size, uint64_t *log) + size_t hw_key_hash_size, __be64 *log) This function wrapper calls into the *CVC-verify*, which verifies if the firmware code provided in ``@buf`` is properly signed with the keys trusted by diff --git a/include/asm-utils.h b/include/asm-utils.h index 2d26545e7..c3d8c09ea 100644 --- a/include/asm-utils.h +++ b/include/asm-utils.h @@ -28,17 +28,29 @@ /* Load an address via the TOC */ #define LOAD_ADDR_FROM_TOC(r, e) ld r,e@got(%r2) -#define FIXUP_ENDIAN \ - tdi 0,0,0x48; /* Reverse endian of b . + 8 */ \ - b 191f; /* Skip trampoline if endian is good */ \ +/* This must preserve LR, so can't use Linux kernel's FIXUP_ENDIAN */ +#define SWITCH_ENDIAN \ .long 0xa600607d; /* mfmsr r11 */ \ .long 0x01006b69; /* xori r11,r11,1 */ \ + .long 0xa64b7b7d; /* mthsrr1 r11 */ \ + .long 0xa602687d; /* mflr r11 */ \ .long 0x05009f42; /* bcl 20,31,$+4 */ \ .long 0xa602487d; /* mflr r10 */ \ .long 0x14004a39; /* addi r10,r10,20 */ \ .long 0xa64b5a7d; /* mthsrr0 r10 */ \ - .long 0xa64b7b7d; /* mthsrr1 r11 */ \ - .long 0x2402004c; /* hrfid */ \ + .long 0xa603687d; /* mtlr r11 */ \ + .long 0x2402004c /* hrfid */ + +#define FIXUP_ENDIAN \ + tdi 0,0,0x48; /* Reverse endian of b . + 8 */ \ + b 191f; /* Skip trampoline if endian is good */ \ + SWITCH_ENDIAN; /* Do the switch */ \ 191: +#if HAVE_BIG_ENDIAN +#define OPAL_ENTRY_TO_SKIBOOT_ENDIAN +#else +#define OPAL_ENTRY_TO_SKIBOOT_ENDIAN SWITCH_ENDIAN +#endif + #endif /* __ASM_UTILS_H */ diff --git a/include/cpu.h b/include/cpu.h index cda78644d..008f08a68 100644 --- a/include/cpu.h +++ b/include/cpu.h @@ -282,6 +282,9 @@ extern void cpu_process_local_jobs(void); /* Check if there's any job pending */ bool cpu_check_jobs(struct cpu_thread *cpu); +/* Set/clear HILE on all CPUs */ +void cpu_set_hile_mode(bool hile); + /* OPAL sreset vector in place at 0x100 */ void cpu_set_sreset_enable(bool sreset_enabled); diff --git a/libpore/p9_cpu_reg_restore_instruction.H b/libpore/p9_cpu_reg_restore_instruction.H index dd4358a82..cf00ff5e5 100644 --- a/libpore/p9_cpu_reg_restore_instruction.H +++ b/libpore/p9_cpu_reg_restore_instruction.H @@ -61,23 +61,24 @@ enum RLDICR_CONST = 1, MTSPR_CONST1 = 467, MTMSRD_CONST1 = 178, - MR_R0_TO_R10 = 0x7c0a0378, //mr r10, r0 - MR_R0_TO_R21 = 0x7c150378, //mr r21, r0 - MR_R0_TO_R9 = 0x7c090378, //mr r9, r0 - URMOR_CORRECTION = 0x7d397ba6, MFSPR_CONST = 339, - BLR_INST = 0x4e800020, - MTSPR_BASE_OPCODE = 0x7c0003a6, - ATTN_OPCODE = 0x00000200, OPCODE_18 = 18, SELF_SAVE_FUNC_ADD = 0x2300, SELF_SAVE_OFFSET = 0x180, - SKIP_SPR_REST_INST = 0x4800001c, //b . +0x01c - MFLR_R30 = 0x7fc802a6, - SKIP_SPR_SELF_SAVE = 0x3bff0020, //addi r31 r31, 0x20 - MTLR_INST = 0x7fc803a6 //mtlr r30 }; +#define MR_R0_TO_R10 0x7c0a0378UL //mr r10 r0 +#define MR_R0_TO_R21 0x7c150378UL //mr r21 r0 +#define MR_R0_TO_R9 0x7c090378UL //mr r9 r0 +#define URMOR_CORRECTION 0x7d397ba6UL +#define BLR_INST 0x4e800020UL +#define MTSPR_BASE_OPCODE 0x7c0003a6UL +#define ATTN_OPCODE 0x00000200UL +#define SKIP_SPR_REST_INST 0x4800001cUL //b . +0x01c +#define MFLR_R30 0x7fc802a6UL +#define SKIP_SPR_SELF_SAVE 0x3bff0020UL //addi r31 r31 0x20 +#define MTLR_INST 0x7fc803a6UL //mtlr r30 + #ifdef __cplusplus } // namespace stopImageSection ends