Received: by 2002:a05:6a10:f3d0:0:0:0:0 with SMTP id a16csp1146479pxv; Fri, 9 Jul 2021 19:29:36 -0700 (PDT) X-Google-Smtp-Source: ABdhPJwNwVUO0tLzgwTZBpyGS/QjAfUzeAb1iea9UQXnsoCLkBuPcG1moPiv9u68F7zDec5hpx7f X-Received: by 2002:a05:6402:2044:: with SMTP id bc4mr22322769edb.307.1625884176792; Fri, 09 Jul 2021 19:29:36 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1625884176; cv=none; d=google.com; s=arc-20160816; b=t/H+xgaVkv/ZiEzFNUbw13NbCA7ES16t1AIlknlJoHU2wE59rMY8htcarQAgYdOpp3 rCP7GcXiqF98rU2KTOBuW7OukC14UDYwVsVo+muyKtg+W6htTCaymX8g6uCriQ4xcsoa eKssWxK5Pg4Zw49UiEdZ6uc+nGvIMXAjMM1bDfJRfeIQk8UNhxMkVzkJ+INUYr9yR6XQ PbPHIXJBxhQUBXCPL7qk+Msku5Pvuk+F2MMkQLDXImmApOuNEIQi214RISL7LqC4JLYa ty8a7Fj8u/g8B3qyqEkpp5aHLGo1Hcx/1jVpiNjDKfCU8Hrl0Bj9S6X3iQScAQ8u0u+T JXQw== 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=RYcTgH9RklQI50neBFxDPL7ItoiqpIMD5agIEU0Sic4=; b=Ay3luwijMmcKQrHgyqCiQ7PUqwSYR+cqTrO31kY/pQ3bvCqga/GiCAz+QM7ws0xonp owGOkCMVS8fWH/p+fGoqMXCs9YfwnzGlefgCqtJWCKRp76jYvO6iwC8kaVwP6PSqPXCZ tXnP8lZrGrlwdsPC94E5aoB5EkpdSEd0e/vE2QeEWEl41o7wMPbJUGbIoGJoMpV7Oa/i Nt4XQ9gOYMvmau53eQGqX7tNUXkJYyw7Xd1L+Td11qDOgJ6UgtRZsq6lHccrTBC5k5cT XimahS89ZZiA61s18ZDPoig76uM11kQEkdh/2ARvJWTWOcD7Pqd6HT3aBulgBcC3Sltf qoWw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=c3mjVubV; 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 d26si8849166ejc.620.2021.07.09.19.29.13; Fri, 09 Jul 2021 19:29:36 -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=c3mjVubV; 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 S233156AbhGJC2i (ORCPT + 99 others); Fri, 9 Jul 2021 22:28:38 -0400 Received: from mail.kernel.org ([198.145.29.99]:43180 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231958AbhGJC04 (ORCPT ); Fri, 9 Jul 2021 22:26:56 -0400 Received: by mail.kernel.org (Postfix) with ESMTPSA id C84076141D; Sat, 10 Jul 2021 02:24:04 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1625883845; bh=sk5rvFib5S+/tFVACJhPL3D9r+kcEJmN/zFpx1YCRI4=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=c3mjVubVmg5W5oBgFepHAE2VrFcJoM3jkZ1HRqD0xJw/slNqk6qezcUGbkr9XL+xq jXecAKRa9FXIhlmt7H2PnoxOHxWtfA/Bsw7x7gWxCCdXk6gAEKqJHD+2bnfazlL/wc Iwc/L+bIKTTJaJ8Ai3mH8PnAUStamPO5dI5taTNWVj4/gKkY/B1svdr2sRG/WkwYPE XDExdYX3QN844bhh85d2JnsDgm62x7iY5lycbQayYjQRCxaTJIdqMeEjJ4rZEGBJ59 sWqCvjlIySm6N5tjic26nbrvUFZ2hQqCOZDc3k1xB6Y32Ocr6QLm8X9xLx5vs3zGmR upcqlqQgJPsDA== 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 5.12 090/104] powerpc/boot: Fixup device-tree on little endian Date: Fri, 9 Jul 2021 22:21:42 -0400 Message-Id: <20210710022156.3168825-90-sashal@kernel.org> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20210710022156.3168825-1-sashal@kernel.org> References: <20210710022156.3168825-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 5d91036ad626..58fbcfcc98c9 100644 --- a/arch/powerpc/boot/devtree.c +++ b/arch/powerpc/boot/devtree.c @@ -13,6 +13,7 @@ #include "string.h" #include "stdio.h" #include "ops.h" +#include "of.h" void dt_fixup_memory(u64 start, u64 size) { @@ -23,21 +24,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) { @@ -45,9 +50,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)); @@ -65,10 +70,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; @@ -80,7 +85,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)); } } @@ -133,8 +138,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) @@ -163,9 +172,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; @@ -180,18 +189,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; } @@ -240,7 +249,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; @@ -252,10 +260,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 (;;) { @@ -278,7 +286,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; @@ -296,8 +303,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)) @@ -350,11 +356,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