Received: by 2002:a05:6a10:f3d0:0:0:0:0 with SMTP id a16csp1151695pxv; Fri, 9 Jul 2021 19:40:29 -0700 (PDT) X-Google-Smtp-Source: ABdhPJzy0iBZkkzXRrZqdfX6lAs34SY1eVOrVEk/EH7EwgzHchuwJG108XlQqP+td5eqEOpcAk2d X-Received: by 2002:a17:906:2b47:: with SMTP id b7mr40521192ejg.240.1625884829311; Fri, 09 Jul 2021 19:40:29 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1625884829; cv=none; d=google.com; s=arc-20160816; b=0gQBo7jdBOOUr3Q9mKQwxBXiI0YpQre+T5mjuHcNrZcZRMcIjsdvhefZQf22igVYeu ErzEUbVHRSqNHl8oqVTzK3PDocTsusmeQZklXo9Ws/iusC2M0l60Klwb8Adp9rDksPl8 6J/CLpsIRZvKYJMylwHTNSxnPUy52MLCfbQE8zlz5oC+jlr7vspDpt4OSVjw6R1E2wzP oZ2iKCpPuRVHruHzIUE4qDz2Xb7XUpUAgy76xjc2anc0oY2XU1xlJBpV3q/0du4M0uL1 vAqoPq8/3WQu2P9iUmDxokRxBuIefUhtJSfyXFY/luzceKnTibgUKrUsg5La+YrZ0yNi xtew== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=P83qLao0q0CT23E4Uyjd9v8VVY1ii/J1gZa58iQvfBg=; b=tM/Izqdhwrc8uMichj5aM6Crd2U+1tFXbpLIiN4BfFzw0RfZjH3L7FRc1pBC8Dde7n EpHUOA8OAxwGGt/TXmsz5uAIaTgWfR/nD21ON3IGRLtC3IwWUbyIWd1Mtn0tXhTu3WeF noEbYcAjStg9VMwQQgl5t2LPAh5ExSwglrdO1mLQuisXYYeAir7g5K3/iOF0rckVvEEB XYdXeQWYQWfGwdyVF21H8d1Jc4uoN1fEEegMuaPGXdsi9hpY/M3nuSptJd+9nBcqjD2j Up1FNby9w5ILZCc3SaPEqQM1UEPwglQ0rVbsyx0C6ZqZOk6zKeX/tS/EKKp13gohYlhI Phjg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=qYqWRjjV; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id eb8si10117378edb.608.2021.07.09.19.40.03; Fri, 09 Jul 2021 19:40:29 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=qYqWRjjV; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234745AbhGJCkA (ORCPT + 99 others); Fri, 9 Jul 2021 22:40:00 -0400 Received: from mail.kernel.org ([198.145.29.99]:58370 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234885AbhGJCjR (ORCPT ); Fri, 9 Jul 2021 22:39:17 -0400 Received: by mail.kernel.org (Postfix) with ESMTPSA id 555F6613E1; Sat, 10 Jul 2021 02:35:04 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1625884505; bh=7jr1Lvt1ILnCkPldOAG79bnseWQuYmGuSXtbZT78/qU=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=qYqWRjjVDYwgsTfw/u1XkW/IThTT4Lm2T74O7R4FCKAeAApFtWTJQFkU03dMcwL+R KJVUw49lG2zl6gv8kt9iBWVonefGuqD+2Q/GxjCZEEPLnQCCWMEAb0V/zedxCLc6o/ kx44KslsOe6vrLMpfBTOMQ8uHZXYqIzIAAKeOwl2njACKaNHC2H7QeBLiXTezXB873 VDQUxho+ttPCvpsz0Fyl+l9lvvuSkl8vDgVAjEX1WuHUzUB5snlfLMDBARnmZ6ikeq sVl3k0xZwaUr25jA26sv8TNyekpULT0r5N4uwFvLylg1dWTaFbJYblK8KxtF3300AK KCVPpftQw2PZA== From: Sasha Levin To: linux-kernel@vger.kernel.org, stable@vger.kernel.org Cc: Benjamin Herrenschmidt , Paul Mackerras , Segher Boessenkool , Nicholas Piggin , Michael Ellerman , Sasha Levin , linuxppc-dev@lists.ozlabs.org Subject: [PATCH AUTOSEL 4.19 32/39] powerpc/boot: Fixup device-tree on little endian Date: Fri, 9 Jul 2021 22:31:57 -0400 Message-Id: <20210710023204.3171428-32-sashal@kernel.org> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20210710023204.3171428-1-sashal@kernel.org> References: <20210710023204.3171428-1-sashal@kernel.org> MIME-Version: 1.0 X-stable: review X-Patchwork-Hint: Ignore Content-Transfer-Encoding: 8bit Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Benjamin Herrenschmidt [ Upstream commit c93f80849bdd9b45d834053ae1336e28f0026c84 ] This fixes the core devtree.c functions and the ns16550 UART backend. Signed-off-by: Benjamin Herrenschmidt Signed-off-by: Paul Mackerras Reviewed-by: Segher Boessenkool Acked-by: Nicholas Piggin Signed-off-by: Michael Ellerman Link: https://lore.kernel.org/r/YMwXrPT8nc4YUdJ9@thinks.paulus.ozlabs.org Signed-off-by: Sasha Levin --- arch/powerpc/boot/devtree.c | 59 +++++++++++++++++++++---------------- arch/powerpc/boot/ns16550.c | 9 ++++-- 2 files changed, 41 insertions(+), 27 deletions(-) diff --git a/arch/powerpc/boot/devtree.c b/arch/powerpc/boot/devtree.c index a7e21a35c03a..27c84b82b588 100644 --- a/arch/powerpc/boot/devtree.c +++ b/arch/powerpc/boot/devtree.c @@ -17,6 +17,7 @@ #include "string.h" #include "stdio.h" #include "ops.h" +#include "of.h" void dt_fixup_memory(u64 start, u64 size) { @@ -27,21 +28,25 @@ void dt_fixup_memory(u64 start, u64 size) root = finddevice("/"); if (getprop(root, "#address-cells", &naddr, sizeof(naddr)) < 0) naddr = 2; + else + naddr = be32_to_cpu(naddr); if (naddr < 1 || naddr > 2) fatal("Can't cope with #address-cells == %d in /\n\r", naddr); if (getprop(root, "#size-cells", &nsize, sizeof(nsize)) < 0) nsize = 1; + else + nsize = be32_to_cpu(nsize); if (nsize < 1 || nsize > 2) fatal("Can't cope with #size-cells == %d in /\n\r", nsize); i = 0; if (naddr == 2) - memreg[i++] = start >> 32; - memreg[i++] = start & 0xffffffff; + memreg[i++] = cpu_to_be32(start >> 32); + memreg[i++] = cpu_to_be32(start & 0xffffffff); if (nsize == 2) - memreg[i++] = size >> 32; - memreg[i++] = size & 0xffffffff; + memreg[i++] = cpu_to_be32(size >> 32); + memreg[i++] = cpu_to_be32(size & 0xffffffff); memory = finddevice("/memory"); if (! memory) { @@ -49,9 +54,9 @@ void dt_fixup_memory(u64 start, u64 size) setprop_str(memory, "device_type", "memory"); } - printf("Memory <- <0x%x", memreg[0]); + printf("Memory <- <0x%x", be32_to_cpu(memreg[0])); for (i = 1; i < (naddr + nsize); i++) - printf(" 0x%x", memreg[i]); + printf(" 0x%x", be32_to_cpu(memreg[i])); printf("> (%ldMB)\n\r", (unsigned long)(size >> 20)); setprop(memory, "reg", memreg, (naddr + nsize)*sizeof(u32)); @@ -69,10 +74,10 @@ void dt_fixup_cpu_clocks(u32 cpu, u32 tb, u32 bus) printf("CPU bus-frequency <- 0x%x (%dMHz)\n\r", bus, MHZ(bus)); while ((devp = find_node_by_devtype(devp, "cpu"))) { - setprop_val(devp, "clock-frequency", cpu); - setprop_val(devp, "timebase-frequency", tb); + setprop_val(devp, "clock-frequency", cpu_to_be32(cpu)); + setprop_val(devp, "timebase-frequency", cpu_to_be32(tb)); if (bus > 0) - setprop_val(devp, "bus-frequency", bus); + setprop_val(devp, "bus-frequency", cpu_to_be32(bus)); } timebase_period_ns = 1000000000 / tb; @@ -84,7 +89,7 @@ void dt_fixup_clock(const char *path, u32 freq) if (devp) { printf("%s: clock-frequency <- %x (%dMHz)\n\r", path, freq, MHZ(freq)); - setprop_val(devp, "clock-frequency", freq); + setprop_val(devp, "clock-frequency", cpu_to_be32(freq)); } } @@ -137,8 +142,12 @@ void dt_get_reg_format(void *node, u32 *naddr, u32 *nsize) { if (getprop(node, "#address-cells", naddr, 4) != 4) *naddr = 2; + else + *naddr = be32_to_cpu(*naddr); if (getprop(node, "#size-cells", nsize, 4) != 4) *nsize = 1; + else + *nsize = be32_to_cpu(*nsize); } static void copy_val(u32 *dest, u32 *src, int naddr) @@ -167,9 +176,9 @@ static int add_reg(u32 *reg, u32 *add, int naddr) int i, carry = 0; for (i = MAX_ADDR_CELLS - 1; i >= MAX_ADDR_CELLS - naddr; i--) { - u64 tmp = (u64)reg[i] + add[i] + carry; + u64 tmp = (u64)be32_to_cpu(reg[i]) + be32_to_cpu(add[i]) + carry; carry = tmp >> 32; - reg[i] = (u32)tmp; + reg[i] = cpu_to_be32((u32)tmp); } return !carry; @@ -184,18 +193,18 @@ static int compare_reg(u32 *reg, u32 *range, u32 *rangesize) u32 end; for (i = 0; i < MAX_ADDR_CELLS; i++) { - if (reg[i] < range[i]) + if (be32_to_cpu(reg[i]) < be32_to_cpu(range[i])) return 0; - if (reg[i] > range[i]) + if (be32_to_cpu(reg[i]) > be32_to_cpu(range[i])) break; } for (i = 0; i < MAX_ADDR_CELLS; i++) { - end = range[i] + rangesize[i]; + end = be32_to_cpu(range[i]) + be32_to_cpu(rangesize[i]); - if (reg[i] < end) + if (be32_to_cpu(reg[i]) < end) break; - if (reg[i] > end) + if (be32_to_cpu(reg[i]) > end) return 0; } @@ -244,7 +253,6 @@ static int dt_xlate(void *node, int res, int reglen, unsigned long *addr, return 0; dt_get_reg_format(parent, &naddr, &nsize); - if (nsize > 2) return 0; @@ -256,10 +264,10 @@ static int dt_xlate(void *node, int res, int reglen, unsigned long *addr, copy_val(last_addr, prop_buf + offset, naddr); - ret_size = prop_buf[offset + naddr]; + ret_size = be32_to_cpu(prop_buf[offset + naddr]); if (nsize == 2) { ret_size <<= 32; - ret_size |= prop_buf[offset + naddr + 1]; + ret_size |= be32_to_cpu(prop_buf[offset + naddr + 1]); } for (;;) { @@ -282,7 +290,6 @@ static int dt_xlate(void *node, int res, int reglen, unsigned long *addr, offset = find_range(last_addr, prop_buf, prev_naddr, naddr, prev_nsize, buflen / 4); - if (offset < 0) return 0; @@ -300,8 +307,7 @@ static int dt_xlate(void *node, int res, int reglen, unsigned long *addr, if (naddr > 2) return 0; - ret_addr = ((u64)last_addr[2] << 32) | last_addr[3]; - + ret_addr = ((u64)be32_to_cpu(last_addr[2]) << 32) | be32_to_cpu(last_addr[3]); if (sizeof(void *) == 4 && (ret_addr >= 0x100000000ULL || ret_size > 0x100000000ULL || ret_addr + ret_size > 0x100000000ULL)) @@ -354,11 +360,14 @@ int dt_is_compatible(void *node, const char *compat) int dt_get_virtual_reg(void *node, void **addr, int nres) { unsigned long xaddr; - int n; + int n, i; n = getprop(node, "virtual-reg", addr, nres * 4); - if (n > 0) + if (n > 0) { + for (i = 0; i < n/4; i ++) + ((u32 *)addr)[i] = be32_to_cpu(((u32 *)addr)[i]); return n / 4; + } for (n = 0; n < nres; n++) { if (!dt_xlate_reg(node, n, &xaddr, NULL)) diff --git a/arch/powerpc/boot/ns16550.c b/arch/powerpc/boot/ns16550.c index b0da4466d419..f16d2be1d0f3 100644 --- a/arch/powerpc/boot/ns16550.c +++ b/arch/powerpc/boot/ns16550.c @@ -15,6 +15,7 @@ #include "stdio.h" #include "io.h" #include "ops.h" +#include "of.h" #define UART_DLL 0 /* Out: Divisor Latch Low */ #define UART_DLM 1 /* Out: Divisor Latch High */ @@ -58,16 +59,20 @@ int ns16550_console_init(void *devp, struct serial_console_data *scdp) int n; u32 reg_offset; - if (dt_get_virtual_reg(devp, (void **)®_base, 1) < 1) + if (dt_get_virtual_reg(devp, (void **)®_base, 1) < 1) { + printf("virt reg parse fail...\r\n"); return -1; + } n = getprop(devp, "reg-offset", ®_offset, sizeof(reg_offset)); if (n == sizeof(reg_offset)) - reg_base += reg_offset; + reg_base += be32_to_cpu(reg_offset); n = getprop(devp, "reg-shift", ®_shift, sizeof(reg_shift)); if (n != sizeof(reg_shift)) reg_shift = 0; + else + reg_shift = be32_to_cpu(reg_shift); scdp->open = ns16550_open; scdp->putc = ns16550_putc; -- 2.30.2