Merge branch '2022-06-22-platform-updates-and-additions' into next
- Add hpe gxp architecture and platform, Arm corstone1000 platform. - ast2600, devkit8000, NPCM7xx improvements
This commit is contained in:
commit
9121478ee6
13
MAINTAINERS
13
MAINTAINERS
@ -279,6 +279,19 @@ F: arch/arm/cpu/armv8/hisilicon
|
||||
F: arch/arm/include/asm/arch-hi6220/
|
||||
F: arch/arm/include/asm/arch-hi3660/
|
||||
|
||||
ARM HPE GXP ARCHITECTURE
|
||||
M: Jean-Marie Verdun <verdun@hpe.com>
|
||||
M: Nick Hawkins <nick.hawkins@hpe.com>
|
||||
S: Maintained
|
||||
F: arch/arm/dts/hpe-bmc*
|
||||
F: arch/arm/dts/hpe-gxp*
|
||||
F: arch/arm/mach-hpe/
|
||||
F: board/hpe/
|
||||
F: configs/gxp_defconfig
|
||||
F: doc/device-tree-bindings/spi/hpe,gxp-spi.yaml
|
||||
F: drivers/timer/gxp-timer.c
|
||||
F: drivers/spi/gxp_spi.c
|
||||
|
||||
ARM IPQ40XX
|
||||
M: Robert Marko <robert.marko@sartura.hr>
|
||||
M: Luka Kovacic <luka.kovacic@sartura.hr>
|
||||
|
1
README
1
README
@ -2415,6 +2415,7 @@ rarpboot- boot image via network using RARP/TFTP protocol
|
||||
diskboot- boot from IDE devicebootd - boot default, i.e., run 'bootcmd'
|
||||
loads - load S-Record file over serial line
|
||||
loadb - load binary file over serial line (kermit mode)
|
||||
loadm - load binary blob from source address to destination address
|
||||
md - memory display
|
||||
mm - memory modify (auto-incrementing)
|
||||
nm - memory modify (constant address)
|
||||
|
@ -1352,6 +1352,12 @@ config ARCH_VEXPRESS64
|
||||
select ENV_IS_IN_FLASH if MTD
|
||||
imply DISTRO_DEFAULTS
|
||||
|
||||
config TARGET_CORSTONE1000
|
||||
bool "Support Corstone1000 Platform"
|
||||
select ARM64
|
||||
select PL01X_SERIAL
|
||||
select DM
|
||||
|
||||
config TARGET_TOTAL_COMPUTE
|
||||
bool "Support Total Compute Platform"
|
||||
select ARM64
|
||||
@ -2089,6 +2095,12 @@ config TARGET_XENGUEST_ARM64
|
||||
select SSCANF
|
||||
imply OF_HAS_PRIOR_STAGE
|
||||
|
||||
config ARCH_GXP
|
||||
bool "Support HPE GXP SoCs"
|
||||
select DM
|
||||
select OF_CONTROL
|
||||
imply CMD_DM
|
||||
|
||||
endchoice
|
||||
|
||||
config SUPPORT_PASSING_ATAGS
|
||||
@ -2199,6 +2211,8 @@ source "arch/arm/mach-davinci/Kconfig"
|
||||
|
||||
source "arch/arm/mach-exynos/Kconfig"
|
||||
|
||||
source "arch/arm/mach-hpe/gxp/Kconfig"
|
||||
|
||||
source "arch/arm/mach-highbank/Kconfig"
|
||||
|
||||
source "arch/arm/mach-integrator/Kconfig"
|
||||
@ -2300,7 +2314,7 @@ source "arch/arm/mach-nexell/Kconfig"
|
||||
source "arch/arm/mach-npcm/Kconfig"
|
||||
|
||||
source "board/armltd/total_compute/Kconfig"
|
||||
|
||||
source "board/armltd/corstone1000/Kconfig"
|
||||
source "board/bosch/shc/Kconfig"
|
||||
source "board/bosch/guardian/Kconfig"
|
||||
source "board/Marvell/octeontx/Kconfig"
|
||||
|
@ -63,6 +63,7 @@ machine-$(CONFIG_ARCH_BCMBCA) += bcmbca
|
||||
machine-$(CONFIG_ARCH_BCMSTB) += bcmstb
|
||||
machine-$(CONFIG_ARCH_DAVINCI) += davinci
|
||||
machine-$(CONFIG_ARCH_EXYNOS) += exynos
|
||||
machine-$(CONFIG_ARCH_GXP) += hpe
|
||||
machine-$(CONFIG_ARCH_HIGHBANK) += highbank
|
||||
machine-$(CONFIG_ARCH_IPQ40XX) += ipq40xx
|
||||
machine-$(CONFIG_ARCH_K3) += k3
|
||||
|
@ -1069,6 +1069,8 @@ dtb-$(CONFIG_TARGET_OMAP3_BEAGLE) += \
|
||||
omap3-beagle-xm.dtb \
|
||||
omap3-beagle.dtb
|
||||
|
||||
dtb-$(CONFIG_TARGET_DEVKIT8000) += omap3-devkit8000.dtb
|
||||
|
||||
dtb-$(CONFIG_TARGET_OMAP3_IGEP00X0) += \
|
||||
omap3-igep0020.dtb
|
||||
|
||||
@ -1245,6 +1247,8 @@ dtb-$(CONFIG_TARGET_POMELO) += phytium-pomelo.dtb
|
||||
|
||||
dtb-$(CONFIG_TARGET_PRESIDIO_ASIC) += ca-presidio-engboard.dtb
|
||||
|
||||
dtb-$(CONFIG_TARGET_GXP) += hpe-bmc-dl360gen10.dts
|
||||
|
||||
dtb-$(CONFIG_TARGET_IMX8MM_CL_IOT_GATE) += imx8mm-cl-iot-gate.dtb \
|
||||
imx8mm-cl-iot-gate-ied.dtbo \
|
||||
imx8mm-cl-iot-gate-ied-adc0.dtbo \
|
||||
@ -1271,6 +1275,9 @@ dtb-$(CONFIG_TARGET_EA_LPC3250DEVKITV2) += lpc3250-ea3250.dtb
|
||||
|
||||
dtb-$(CONFIG_ARCH_QEMU) += qemu-arm.dtb qemu-arm64.dtb
|
||||
|
||||
dtb-$(CONFIG_TARGET_CORSTONE1000) += corstone1000-mps3.dtb \
|
||||
corstone1000-fvp.dtb
|
||||
|
||||
include $(srctree)/scripts/Makefile.dts
|
||||
|
||||
targets += $(dtb-y)
|
||||
|
51
arch/arm/dts/corstone1000-fvp.dts
Normal file
51
arch/arm/dts/corstone1000-fvp.dts
Normal file
@ -0,0 +1,51 @@
|
||||
// SPDX-License-Identifier: GPL-2.0 or MIT
|
||||
/*
|
||||
* Copyright (c) 2022, Arm Limited. All rights reserved.
|
||||
* Copyright (c) 2022, Linaro Limited. All rights reserved.
|
||||
*
|
||||
*/
|
||||
|
||||
/dts-v1/;
|
||||
|
||||
#include "corstone1000.dtsi"
|
||||
|
||||
/ {
|
||||
model = "ARM Corstone1000 FVP (Fixed Virtual Platform)";
|
||||
compatible = "arm,corstone1000-fvp";
|
||||
|
||||
smsc: ethernet@4010000 {
|
||||
compatible = "smsc,lan91c111";
|
||||
reg = <0x40100000 0x10000>;
|
||||
phy-mode = "mii";
|
||||
interrupts = <GIC_SPI 116 IRQ_TYPE_LEVEL_HIGH>;
|
||||
reg-io-width = <2>;
|
||||
};
|
||||
|
||||
vmmc_v3_3d: fixed_v3_3d {
|
||||
compatible = "regulator-fixed";
|
||||
regulator-name = "vmmc_supply";
|
||||
regulator-min-microvolt = <3300000>;
|
||||
regulator-max-microvolt = <3300000>;
|
||||
regulator-always-on;
|
||||
};
|
||||
|
||||
sdmmc0: mmc@40300000 {
|
||||
compatible = "arm,pl18x", "arm,primecell";
|
||||
reg = <0x40300000 0x1000>;
|
||||
interrupts = <GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH>;
|
||||
max-frequency = <12000000>;
|
||||
vmmc-supply = <&vmmc_v3_3d>;
|
||||
clocks = <&smbclk>, <&refclk100mhz>;
|
||||
clock-names = "smclk", "apb_pclk";
|
||||
};
|
||||
|
||||
sdmmc1: mmc@50000000 {
|
||||
compatible = "arm,pl18x", "arm,primecell";
|
||||
reg = <0x50000000 0x10000>;
|
||||
interrupts = <GIC_SPI 115 IRQ_TYPE_LEVEL_HIGH>;
|
||||
max-frequency = <12000000>;
|
||||
vmmc-supply = <&vmmc_v3_3d>;
|
||||
clocks = <&smbclk>, <&refclk100mhz>;
|
||||
clock-names = "smclk", "apb_pclk";
|
||||
};
|
||||
};
|
32
arch/arm/dts/corstone1000-mps3.dts
Normal file
32
arch/arm/dts/corstone1000-mps3.dts
Normal file
@ -0,0 +1,32 @@
|
||||
// SPDX-License-Identifier: GPL-2.0 or MIT
|
||||
/*
|
||||
* Copyright (c) 2022, Arm Limited. All rights reserved.
|
||||
* Copyright (c) 2022, Linaro Limited. All rights reserved.
|
||||
*
|
||||
*/
|
||||
|
||||
/dts-v1/;
|
||||
|
||||
#include "corstone1000.dtsi"
|
||||
|
||||
/ {
|
||||
model = "ARM Corstone1000 FPGA MPS3 board";
|
||||
compatible = "arm,corstone1000-mps3";
|
||||
|
||||
smsc: ethernet@4010000 {
|
||||
compatible = "smsc,lan9220", "smsc,lan9115";
|
||||
reg = <0x40100000 0x10000>;
|
||||
phy-mode = "mii";
|
||||
interrupts = <GIC_SPI 116 IRQ_TYPE_LEVEL_HIGH>;
|
||||
reg-io-width = <2>;
|
||||
smsc,irq-push-pull;
|
||||
};
|
||||
|
||||
usb_host: usb@40200000 {
|
||||
compatible = "nxp,usb-isp1763";
|
||||
reg = <0x40200000 0x100000>;
|
||||
interrupts = <GIC_SPI 114 IRQ_TYPE_LEVEL_HIGH>;
|
||||
bus-width = <16>;
|
||||
dr_mode = "host";
|
||||
};
|
||||
};
|
164
arch/arm/dts/corstone1000.dtsi
Normal file
164
arch/arm/dts/corstone1000.dtsi
Normal file
@ -0,0 +1,164 @@
|
||||
// SPDX-License-Identifier: GPL-2.0 or MIT
|
||||
/*
|
||||
* Copyright (c) 2022, Arm Limited. All rights reserved.
|
||||
* Copyright (c) 2022, Linaro Limited. All rights reserved.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <dt-bindings/interrupt-controller/arm-gic.h>
|
||||
|
||||
/ {
|
||||
interrupt-parent = <&gic>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
|
||||
aliases {
|
||||
serial0 = &uart0;
|
||||
serial1 = &uart1;
|
||||
};
|
||||
|
||||
chosen {
|
||||
stdout-path = "serial0:115200n8";
|
||||
};
|
||||
|
||||
cpus {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
cpu: cpu@0 {
|
||||
device_type = "cpu";
|
||||
compatible = "arm,cortex-a35";
|
||||
reg = <0>;
|
||||
next-level-cache = <&L2_0>;
|
||||
};
|
||||
};
|
||||
|
||||
memory@88200000 {
|
||||
device_type = "memory";
|
||||
reg = <0x88200000 0x77e00000>;
|
||||
};
|
||||
|
||||
gic: interrupt-controller@1c000000 {
|
||||
compatible = "arm,gic-400";
|
||||
#interrupt-cells = <3>;
|
||||
#address-cells = <0>;
|
||||
interrupt-controller;
|
||||
reg = <0x1c010000 0x1000>,
|
||||
<0x1c02f000 0x2000>,
|
||||
<0x1c04f000 0x1000>,
|
||||
<0x1c06f000 0x2000>;
|
||||
interrupts = <GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(1) |
|
||||
IRQ_TYPE_LEVEL_LOW)>;
|
||||
};
|
||||
|
||||
L2_0: l2-cache0 {
|
||||
compatible = "cache";
|
||||
cache-level = <2>;
|
||||
cache-size = <0x80000>;
|
||||
cache-line-size = <64>;
|
||||
cache-sets = <1024>;
|
||||
};
|
||||
|
||||
refclk100mhz: refclk100mhz {
|
||||
compatible = "fixed-clock";
|
||||
#clock-cells = <0>;
|
||||
clock-frequency = <100000000>;
|
||||
clock-output-names = "apb_pclk";
|
||||
};
|
||||
|
||||
smbclk: refclk24mhzx2 {
|
||||
/* Reference 24MHz clock x 2 */
|
||||
compatible = "fixed-clock";
|
||||
#clock-cells = <0>;
|
||||
clock-frequency = <48000000>;
|
||||
clock-output-names = "smclk";
|
||||
};
|
||||
|
||||
timer {
|
||||
compatible = "arm,armv8-timer";
|
||||
interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(1) |
|
||||
IRQ_TYPE_LEVEL_LOW)>,
|
||||
<GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(1) |
|
||||
IRQ_TYPE_LEVEL_LOW)>,
|
||||
<GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(1) |
|
||||
IRQ_TYPE_LEVEL_LOW)>,
|
||||
<GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(1) |
|
||||
IRQ_TYPE_LEVEL_LOW)>;
|
||||
};
|
||||
|
||||
uartclk: uartclk {
|
||||
/* UART clock - 50MHz */
|
||||
compatible = "fixed-clock";
|
||||
#clock-cells = <0>;
|
||||
clock-frequency = <50000000>;
|
||||
clock-output-names = "uartclk";
|
||||
};
|
||||
|
||||
psci {
|
||||
compatible = "arm,psci-1.0", "arm,psci-0.2";
|
||||
method = "smc";
|
||||
};
|
||||
|
||||
soc {
|
||||
compatible = "simple-bus";
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
interrupt-parent = <&gic>;
|
||||
ranges;
|
||||
|
||||
timer@1a220000 {
|
||||
compatible = "arm,armv7-timer-mem";
|
||||
reg = <0x1a220000 0x1000>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
clock-frequency = <50000000>;
|
||||
ranges;
|
||||
|
||||
frame@1a230000 {
|
||||
frame-number = <0>;
|
||||
interrupts = <GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH>;
|
||||
reg = <0x1a230000 0x1000>;
|
||||
};
|
||||
};
|
||||
|
||||
uart0: serial@1a510000 {
|
||||
compatible = "arm,pl011", "arm,primecell";
|
||||
reg = <0x1a510000 0x1000>;
|
||||
interrupts = <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clocks = <&uartclk>, <&refclk100mhz>;
|
||||
clock-names = "uartclk", "apb_pclk";
|
||||
};
|
||||
|
||||
uart1: serial@1a520000 {
|
||||
compatible = "arm,pl011", "arm,primecell";
|
||||
reg = <0x1a520000 0x1000>;
|
||||
interrupts = <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clocks = <&uartclk>, <&refclk100mhz>;
|
||||
clock-names = "uartclk", "apb_pclk";
|
||||
};
|
||||
|
||||
mhu_hse1: mailbox@1b820000 {
|
||||
compatible = "arm,mhuv2-tx", "arm,primecell";
|
||||
reg = <0x1b820000 0x1000>;
|
||||
clocks = <&refclk100mhz>;
|
||||
clock-names = "apb_pclk";
|
||||
interrupts = <GIC_SPI 45 IRQ_TYPE_LEVEL_HIGH>;
|
||||
#mbox-cells = <2>;
|
||||
arm,mhuv2-protocols = <0 0>;
|
||||
secure-status = "okay"; /* secure-world-only */
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
mhu_seh1: mailbox@1b830000 {
|
||||
compatible = "arm,mhuv2-rx", "arm,primecell";
|
||||
reg = <0x1b830000 0x1000>;
|
||||
clocks = <&refclk100mhz>;
|
||||
clock-names = "apb_pclk";
|
||||
interrupts = <GIC_SPI 46 IRQ_TYPE_LEVEL_HIGH>;
|
||||
#mbox-cells = <2>;
|
||||
arm,mhuv2-protocols = <0 0>;
|
||||
secure-status = "okay"; /* secure-world-only */
|
||||
status = "disabled";
|
||||
};
|
||||
};
|
||||
};
|
26
arch/arm/dts/hpe-bmc-dl360gen10.dts
Normal file
26
arch/arm/dts/hpe-bmc-dl360gen10.dts
Normal file
@ -0,0 +1,26 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Device Tree file for HPE DL360Gen10
|
||||
*/
|
||||
|
||||
/include/ "hpe-gxp-u-boot.dtsi"
|
||||
|
||||
/ {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
compatible = "hpe,gxp-dl360gen10", "hpe,gxp";
|
||||
model = "Hewlett Packard Enterprise ProLiant dl360 Gen10";
|
||||
|
||||
aliases {
|
||||
serial0 = &uartc;
|
||||
};
|
||||
|
||||
chosen {
|
||||
stdout-path = "serial0:115200n8";
|
||||
};
|
||||
|
||||
memory@40000000 {
|
||||
device_type = "memory";
|
||||
reg = <0x40000000 0x20000000>;
|
||||
};
|
||||
};
|
25
arch/arm/dts/hpe-gxp-u-boot.dtsi
Normal file
25
arch/arm/dts/hpe-gxp-u-boot.dtsi
Normal file
@ -0,0 +1,25 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Device Tree file for HPE GXP
|
||||
*/
|
||||
|
||||
/include/ "hpe-gxp.dtsi"
|
||||
|
||||
/ {
|
||||
|
||||
axi {
|
||||
u-boot,dm-pre-reloc;
|
||||
|
||||
ahb@c0000000 {
|
||||
u-boot,dm-pre-reloc;
|
||||
|
||||
spi0: spi@200 {
|
||||
compatible = "hpe,gxp-spi";
|
||||
reg = <0x200 0x80>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
status = "okay";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
127
arch/arm/dts/hpe-gxp.dtsi
Normal file
127
arch/arm/dts/hpe-gxp.dtsi
Normal file
@ -0,0 +1,127 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Device Tree file for HPE GXP
|
||||
*/
|
||||
|
||||
/dts-v1/;
|
||||
/ {
|
||||
model = "Hewlett Packard Enterprise GXP BMC";
|
||||
compatible = "hpe,gxp";
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
|
||||
cpus {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
cpu@0 {
|
||||
compatible = "arm,cortex-a9";
|
||||
reg = <0>;
|
||||
device_type = "cpu";
|
||||
next-level-cache = <&L2>;
|
||||
};
|
||||
};
|
||||
|
||||
clocks {
|
||||
pll: clock-0 {
|
||||
compatible = "fixed-clock";
|
||||
#clock-cells = <0>;
|
||||
clock-frequency = <1600000000>;
|
||||
};
|
||||
|
||||
iopclk: clock-1 {
|
||||
compatible = "fixed-factor-clock";
|
||||
#clock-cells = <0>;
|
||||
clock-div = <4>;
|
||||
clock-mult = <1>;
|
||||
clocks = <&pll>;
|
||||
};
|
||||
};
|
||||
|
||||
axi {
|
||||
compatible = "simple-bus";
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
ranges;
|
||||
dma-ranges;
|
||||
|
||||
L2: cache-controller@b0040000 {
|
||||
compatible = "arm,pl310-cache";
|
||||
reg = <0xb0040000 0x1000>;
|
||||
cache-unified;
|
||||
cache-level = <2>;
|
||||
};
|
||||
|
||||
ahb@c0000000 {
|
||||
compatible = "simple-bus";
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
ranges = <0x0 0xc0000000 0x30000000>;
|
||||
dma-ranges;
|
||||
|
||||
vic0: interrupt-controller@eff0000 {
|
||||
compatible = "arm,pl192-vic";
|
||||
reg = <0xeff0000 0x1000>;
|
||||
interrupt-controller;
|
||||
#interrupt-cells = <1>;
|
||||
};
|
||||
|
||||
vic1: interrupt-controller@80f00000 {
|
||||
compatible = "arm,pl192-vic";
|
||||
reg = <0x80f00000 0x1000>;
|
||||
interrupt-controller;
|
||||
#interrupt-cells = <1>;
|
||||
};
|
||||
|
||||
uarta: serial@e0 {
|
||||
compatible = "ns16550a";
|
||||
reg = <0xe0 0x8>;
|
||||
interrupts = <17>;
|
||||
interrupt-parent = <&vic0>;
|
||||
clock-frequency = <1846153>;
|
||||
reg-shift = <0>;
|
||||
};
|
||||
|
||||
uartb: serial@e8 {
|
||||
compatible = "ns16550a";
|
||||
reg = <0xe8 0x8>;
|
||||
interrupts = <18>;
|
||||
interrupt-parent = <&vic0>;
|
||||
clock-frequency = <1846153>;
|
||||
reg-shift = <0>;
|
||||
};
|
||||
|
||||
uartc: serial@f0 {
|
||||
compatible = "ns16550a";
|
||||
reg = <0xf0 0x8>;
|
||||
interrupts = <19>;
|
||||
interrupt-parent = <&vic0>;
|
||||
clock-frequency = <1846153>;
|
||||
reg-shift = <0>;
|
||||
};
|
||||
|
||||
usb0: usb@efe0000 {
|
||||
compatible = "hpe,gxp-ehci", "generic-ehci";
|
||||
reg = <0xefe0000 0x100>;
|
||||
interrupts = <7>;
|
||||
interrupt-parent = <&vic0>;
|
||||
};
|
||||
|
||||
st: timer@80 {
|
||||
compatible = "hpe,gxp-timer";
|
||||
reg = <0x80 0x16>;
|
||||
interrupts = <0>;
|
||||
interrupt-parent = <&vic0>;
|
||||
clocks = <&iopclk>;
|
||||
clock-names = "iop";
|
||||
};
|
||||
|
||||
usb1: usb@efe0100 {
|
||||
compatible = "hpe,gxp-ohci", "generic-ohci";
|
||||
reg = <0xefe0100 0x110>;
|
||||
interrupts = <6>;
|
||||
interrupt-parent = <&vic0>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
20
arch/arm/dts/omap3-devkit8000-u-boot.dtsi
Normal file
20
arch/arm/dts/omap3-devkit8000-u-boot.dtsi
Normal file
@ -0,0 +1,20 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* U-Boot additions
|
||||
*
|
||||
* (C) Copyright 2017 Derald D. Woods <woods.technical@gmail.com>
|
||||
*/
|
||||
|
||||
#include "omap3-u-boot.dtsi"
|
||||
|
||||
/ {
|
||||
chosen {
|
||||
stdout-path = &uart3;
|
||||
};
|
||||
|
||||
ethernet@2c000000 {
|
||||
compatible = "davicom,dm9000";
|
||||
reg = <0x2c000000 2 0x2c000400 2>;
|
||||
bank-width = <2>;
|
||||
};
|
||||
};
|
349
arch/arm/dts/omap3-devkit8000.dts
Normal file
349
arch/arm/dts/omap3-devkit8000.dts
Normal file
@ -0,0 +1,349 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Author: Anthoine Bourgeois <anthoine.bourgeois@gmail.com>
|
||||
*/
|
||||
/dts-v1/;
|
||||
|
||||
#include "omap34xx.dtsi"
|
||||
/ {
|
||||
model = "TimLL OMAP3 Devkit8000";
|
||||
compatible = "timll,omap3-devkit8000", "ti,omap3430", "ti,omap3";
|
||||
|
||||
aliases {
|
||||
display1 = &dvi0;
|
||||
display2 = &tv0;
|
||||
};
|
||||
|
||||
memory@80000000 {
|
||||
device_type = "memory";
|
||||
reg = <0x80000000 0x10000000>; /* 256 MB */
|
||||
};
|
||||
|
||||
leds {
|
||||
compatible = "gpio-leds";
|
||||
|
||||
heartbeat {
|
||||
label = "devkit8000::led1";
|
||||
gpios = <&gpio6 26 GPIO_ACTIVE_HIGH>; /* 186 -> LED1 */
|
||||
default-state = "on";
|
||||
linux,default-trigger = "heartbeat";
|
||||
};
|
||||
|
||||
mmc {
|
||||
label = "devkit8000::led2";
|
||||
gpios = <&gpio6 3 GPIO_ACTIVE_HIGH>; /* 163 -> LED2 */
|
||||
default-state = "on";
|
||||
linux,default-trigger = "none";
|
||||
};
|
||||
|
||||
usr {
|
||||
label = "devkit8000::led3";
|
||||
gpios = <&gpio6 4 GPIO_ACTIVE_HIGH>; /* 164 -> LED3 */
|
||||
default-state = "on";
|
||||
linux,default-trigger = "usr";
|
||||
};
|
||||
|
||||
pmu_stat {
|
||||
label = "devkit8000::pmu_stat";
|
||||
gpios = <&twl_gpio 19 GPIO_ACTIVE_HIGH>; /* LEDB */
|
||||
};
|
||||
};
|
||||
|
||||
sound {
|
||||
compatible = "ti,omap-twl4030";
|
||||
ti,model = "devkit8000";
|
||||
|
||||
ti,mcbsp = <&mcbsp2>;
|
||||
ti,audio-routing =
|
||||
"Ext Spk", "PREDRIVEL",
|
||||
"Ext Spk", "PREDRIVER",
|
||||
"MAINMIC", "Main Mic",
|
||||
"Main Mic", "Mic Bias 1";
|
||||
};
|
||||
|
||||
tfp410: encoder0 {
|
||||
compatible = "ti,tfp410";
|
||||
powerdown-gpios = <&twl_gpio 7 GPIO_ACTIVE_LOW>;
|
||||
|
||||
ports {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
port@0 {
|
||||
reg = <0>;
|
||||
|
||||
tfp410_in: endpoint {
|
||||
remote-endpoint = <&dpi_dvi_out>;
|
||||
};
|
||||
};
|
||||
|
||||
port@1 {
|
||||
reg = <1>;
|
||||
|
||||
tfp410_out: endpoint {
|
||||
remote-endpoint = <&dvi_connector_in>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
dvi0: connector0 {
|
||||
compatible = "dvi-connector";
|
||||
label = "dvi";
|
||||
|
||||
digital;
|
||||
|
||||
ddc-i2c-bus = <&i2c2>;
|
||||
|
||||
port {
|
||||
dvi_connector_in: endpoint {
|
||||
remote-endpoint = <&tfp410_out>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
tv0: connector1 {
|
||||
compatible = "svideo-connector";
|
||||
label = "tv";
|
||||
|
||||
port {
|
||||
tv_connector_in: endpoint {
|
||||
remote-endpoint = <&venc_out>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
&i2c1 {
|
||||
clock-frequency = <2600000>;
|
||||
|
||||
twl: twl@48 {
|
||||
reg = <0x48>;
|
||||
interrupts = <7>; /* SYS_NIRQ cascaded to intc */
|
||||
|
||||
twl_audio: audio {
|
||||
compatible = "ti,twl4030-audio";
|
||||
codec {
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
&i2c2 {
|
||||
clock-frequency = <400000>;
|
||||
};
|
||||
|
||||
&i2c3 {
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
#include "twl4030.dtsi"
|
||||
#include "twl4030_omap3.dtsi"
|
||||
|
||||
&mmc1 {
|
||||
vmmc-supply = <&vmmc1>;
|
||||
vqmmc-supply = <&vsim>;
|
||||
bus-width = <8>;
|
||||
};
|
||||
|
||||
&mmc2 {
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
&mmc3 {
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
&twl_gpio {
|
||||
ti,use-leds;
|
||||
/*
|
||||
* pulldowns:
|
||||
* BIT(1), BIT(2), BIT(6), BIT(7), BIT(8), BIT(13)
|
||||
* BIT(15), BIT(16), BIT(17)
|
||||
*/
|
||||
ti,pulldowns = <0x03a1c6>;
|
||||
};
|
||||
|
||||
&wdt2 {
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
&mcbsp2 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&gpmc {
|
||||
ranges = <0 0 0x30000000 0x1000000 /* CS0: 16MB for NAND */
|
||||
6 0 0x2c000000 0x1000000>; /* CS6: 16MB for DM9000 */
|
||||
|
||||
nand@0,0 {
|
||||
compatible = "ti,omap2-nand";
|
||||
reg = <0 0 4>; /* CS0, offset 0, IO size 4 */
|
||||
interrupt-parent = <&gpmc>;
|
||||
interrupts = <0 IRQ_TYPE_NONE>, /* fifoevent */
|
||||
<1 IRQ_TYPE_NONE>; /* termcount */
|
||||
nand-bus-width = <16>;
|
||||
gpmc,device-width = <2>;
|
||||
ti,nand-ecc-opt = "sw";
|
||||
|
||||
gpmc,sync-clk-ps = <0>;
|
||||
gpmc,cs-on-ns = <0>;
|
||||
gpmc,cs-rd-off-ns = <44>;
|
||||
gpmc,cs-wr-off-ns = <44>;
|
||||
gpmc,adv-on-ns = <6>;
|
||||
gpmc,adv-rd-off-ns = <34>;
|
||||
gpmc,adv-wr-off-ns = <44>;
|
||||
gpmc,we-off-ns = <40>;
|
||||
gpmc,oe-off-ns = <54>;
|
||||
gpmc,access-ns = <64>;
|
||||
gpmc,rd-cycle-ns = <82>;
|
||||
gpmc,wr-cycle-ns = <82>;
|
||||
gpmc,wr-access-ns = <40>;
|
||||
gpmc,wr-data-mux-bus-ns = <0>;
|
||||
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
|
||||
x-loader@0 {
|
||||
label = "X-Loader";
|
||||
reg = <0 0x80000>;
|
||||
};
|
||||
|
||||
bootloaders@80000 {
|
||||
label = "U-Boot";
|
||||
reg = <0x80000 0x1e0000>;
|
||||
};
|
||||
|
||||
bootloaders_env@260000 {
|
||||
label = "U-Boot Env";
|
||||
reg = <0x260000 0x20000>;
|
||||
};
|
||||
|
||||
kernel@280000 {
|
||||
label = "Kernel";
|
||||
reg = <0x280000 0x400000>;
|
||||
};
|
||||
|
||||
filesystem@680000 {
|
||||
label = "File System";
|
||||
reg = <0x680000 0xf980000>;
|
||||
};
|
||||
};
|
||||
|
||||
ethernet@6,0 {
|
||||
compatible = "davicom,dm9000";
|
||||
reg = <6 0x000 2
|
||||
6 0x400 2>; /* CS6, offset 0 and 0x400, IO size 2 */
|
||||
bank-width = <2>;
|
||||
interrupt-parent = <&gpio1>;
|
||||
interrupts = <25 IRQ_TYPE_LEVEL_LOW>;
|
||||
davicom,no-eeprom;
|
||||
|
||||
gpmc,mux-add-data = <0>;
|
||||
gpmc,device-width = <1>;
|
||||
gpmc,wait-pin = <0>;
|
||||
gpmc,cycle2cycle-samecsen;
|
||||
gpmc,cycle2cycle-diffcsen;
|
||||
|
||||
gpmc,cs-on-ns = <6>;
|
||||
gpmc,cs-rd-off-ns = <180>;
|
||||
gpmc,cs-wr-off-ns = <180>;
|
||||
gpmc,adv-on-ns = <0>;
|
||||
gpmc,adv-rd-off-ns = <18>;
|
||||
gpmc,adv-wr-off-ns = <48>;
|
||||
gpmc,oe-on-ns = <54>;
|
||||
gpmc,oe-off-ns = <168>;
|
||||
gpmc,we-on-ns = <54>;
|
||||
gpmc,we-off-ns = <168>;
|
||||
gpmc,rd-cycle-ns = <186>;
|
||||
gpmc,wr-cycle-ns = <186>;
|
||||
gpmc,access-ns = <144>;
|
||||
gpmc,page-burst-access-ns = <24>;
|
||||
gpmc,bus-turnaround-ns = <90>;
|
||||
gpmc,cycle2cycle-delay-ns = <90>;
|
||||
gpmc,wait-monitoring-ns = <0>;
|
||||
gpmc,clk-activation-ns = <0>;
|
||||
gpmc,wr-data-mux-bus-ns = <0>;
|
||||
gpmc,wr-access-ns = <0>;
|
||||
};
|
||||
};
|
||||
|
||||
&omap3_pmx_core {
|
||||
dss_dpi_pins: pinmux_dss_dpi_pins {
|
||||
pinctrl-single,pins = <
|
||||
OMAP3_CORE1_IOPAD(0x20d4, PIN_OUTPUT | MUX_MODE0) /* dss_pclk.dss_pclk */
|
||||
OMAP3_CORE1_IOPAD(0x20d6, PIN_OUTPUT | MUX_MODE0) /* dss_hsync.dss_hsync */
|
||||
OMAP3_CORE1_IOPAD(0x20d8, PIN_OUTPUT | MUX_MODE0) /* dss_vsync.dss_vsync */
|
||||
OMAP3_CORE1_IOPAD(0x20da, PIN_OUTPUT | MUX_MODE0) /* dss_acbias.dss_acbias */
|
||||
OMAP3_CORE1_IOPAD(0x20dc, PIN_OUTPUT | MUX_MODE0) /* dss_data0.dss_data0 */
|
||||
OMAP3_CORE1_IOPAD(0x20de, PIN_OUTPUT | MUX_MODE0) /* dss_data1.dss_data1 */
|
||||
OMAP3_CORE1_IOPAD(0x20e0, PIN_OUTPUT | MUX_MODE0) /* dss_data2.dss_data2 */
|
||||
OMAP3_CORE1_IOPAD(0x20e2, PIN_OUTPUT | MUX_MODE0) /* dss_data3.dss_data3 */
|
||||
OMAP3_CORE1_IOPAD(0x20e4, PIN_OUTPUT | MUX_MODE0) /* dss_data4.dss_data4 */
|
||||
OMAP3_CORE1_IOPAD(0x20e6, PIN_OUTPUT | MUX_MODE0) /* dss_data5.dss_data5 */
|
||||
OMAP3_CORE1_IOPAD(0x20e8, PIN_OUTPUT | MUX_MODE0) /* dss_data6.dss_data6 */
|
||||
OMAP3_CORE1_IOPAD(0x20ea, PIN_OUTPUT | MUX_MODE0) /* dss_data7.dss_data7 */
|
||||
OMAP3_CORE1_IOPAD(0x20ec, PIN_OUTPUT | MUX_MODE0) /* dss_data8.dss_data8 */
|
||||
OMAP3_CORE1_IOPAD(0x20ee, PIN_OUTPUT | MUX_MODE0) /* dss_data9.dss_data9 */
|
||||
OMAP3_CORE1_IOPAD(0x20f0, PIN_OUTPUT | MUX_MODE0) /* dss_data10.dss_data10 */
|
||||
OMAP3_CORE1_IOPAD(0x20f2, PIN_OUTPUT | MUX_MODE0) /* dss_data11.dss_data11 */
|
||||
OMAP3_CORE1_IOPAD(0x20f4, PIN_OUTPUT | MUX_MODE0) /* dss_data12.dss_data12 */
|
||||
OMAP3_CORE1_IOPAD(0x20f6, PIN_OUTPUT | MUX_MODE0) /* dss_data13.dss_data13 */
|
||||
OMAP3_CORE1_IOPAD(0x20f8, PIN_OUTPUT | MUX_MODE0) /* dss_data14.dss_data14 */
|
||||
OMAP3_CORE1_IOPAD(0x20fa, PIN_OUTPUT | MUX_MODE0) /* dss_data15.dss_data15 */
|
||||
OMAP3_CORE1_IOPAD(0x20fc, PIN_OUTPUT | MUX_MODE0) /* dss_data16.dss_data16 */
|
||||
OMAP3_CORE1_IOPAD(0x20fe, PIN_OUTPUT | MUX_MODE0) /* dss_data17.dss_data17 */
|
||||
OMAP3_CORE1_IOPAD(0x2100, PIN_OUTPUT | MUX_MODE0) /* dss_data18.dss_data18 */
|
||||
OMAP3_CORE1_IOPAD(0x2102, PIN_OUTPUT | MUX_MODE0) /* dss_data19.dss_data19 */
|
||||
OMAP3_CORE1_IOPAD(0x2104, PIN_OUTPUT | MUX_MODE0) /* dss_data20.dss_data20 */
|
||||
OMAP3_CORE1_IOPAD(0x2106, PIN_OUTPUT | MUX_MODE0) /* dss_data21.dss_data21 */
|
||||
OMAP3_CORE1_IOPAD(0x2108, PIN_OUTPUT | MUX_MODE0) /* dss_data22.dss_data22 */
|
||||
OMAP3_CORE1_IOPAD(0x210a, PIN_OUTPUT | MUX_MODE0) /* dss_data23.dss_data23 */
|
||||
>;
|
||||
};
|
||||
};
|
||||
|
||||
&vpll1 {
|
||||
/* Needed for DSS */
|
||||
regulator-name = "vdds_dsi";
|
||||
|
||||
regulator-min-microvolt = <1800000>;
|
||||
regulator-max-microvolt = <1800000>;
|
||||
};
|
||||
|
||||
&dss {
|
||||
status = "okay";
|
||||
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&dss_dpi_pins>;
|
||||
|
||||
vdds_dsi-supply = <&vpll1>;
|
||||
vdda_dac-supply = <&vdac>;
|
||||
|
||||
port {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
dpi_dvi_out: endpoint@0 {
|
||||
reg = <0>;
|
||||
remote-endpoint = <&tfp410_in>;
|
||||
data-lines = <24>;
|
||||
};
|
||||
|
||||
endpoint@1 {
|
||||
reg = <1>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
&venc {
|
||||
status = "okay";
|
||||
|
||||
vdda-supply = <&vdac>;
|
||||
|
||||
port {
|
||||
venc_out: endpoint {
|
||||
remote-endpoint = <&tv_connector_in>;
|
||||
ti,channels = <2>;
|
||||
};
|
||||
};
|
||||
};
|
@ -78,4 +78,5 @@
|
||||
|
||||
&i2c1 {
|
||||
u-boot,dm-spl;
|
||||
clock-frequency = <100000>;
|
||||
};
|
||||
|
@ -87,6 +87,9 @@
|
||||
#define SCU_HWSTRAP1_CPU_FREQ_SHIFT 8
|
||||
#define SCU_HWSTRAP1_MAC2_INTF BIT(7)
|
||||
#define SCU_HWSTRAP1_MAC1_INTF BIT(6)
|
||||
#define SCU_HWSTRAP1_BOOT_EMMC BIT(2)
|
||||
|
||||
#define SCU_HWSTRAP2_BOOT_UART BIT(8)
|
||||
|
||||
#define SCU_EFUSE_DIS_DP BIT(17)
|
||||
#define SCU_EFUSE_DIS_VGA BIT(14)
|
||||
|
53
arch/arm/include/asm/arch-npcm7xx/aes.h
Normal file
53
arch/arm/include/asm/arch-npcm7xx/aes.h
Normal file
@ -0,0 +1,53 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0+ */
|
||||
|
||||
#ifndef _NPCM_AES_H_
|
||||
#define _NPCM_AES_H_
|
||||
|
||||
#define AES_OP_ENCRYPT 0
|
||||
#define AES_OP_DECRYPT 1
|
||||
#define SIZE_AES_BLOCK (AES128_KEY_LENGTH)
|
||||
|
||||
struct npcm_aes_regs {
|
||||
unsigned char reserved_0[0x400]; // 0x000
|
||||
unsigned int aes_key_0; // 0x400
|
||||
unsigned int aes_key_1; // 0x404
|
||||
unsigned int aes_key_2; // 0x408
|
||||
unsigned int aes_key_3; // 0x40c
|
||||
unsigned char reserved_1[0x30]; // 0x410
|
||||
unsigned int aes_iv_0; // 0x440
|
||||
unsigned char reserved_2[0x1c]; // 0x444
|
||||
unsigned int aes_ctr_0; // 0x460
|
||||
unsigned char reserved_3[0x0c]; // 0x464
|
||||
unsigned int aes_busy; // 0x470
|
||||
unsigned char reserved_4[0x04]; // 0x474
|
||||
unsigned int aes_sk; // 0x478
|
||||
unsigned char reserved_5[0x14]; // 0x47c
|
||||
unsigned int aes_prev_iv_0; // 0x490
|
||||
unsigned char reserved_6[0x0c]; // 0x494
|
||||
unsigned int aes_din_dout; // 0x4a0
|
||||
unsigned char reserved_7[0x1c]; // 0x4a4
|
||||
unsigned int aes_control; // 0x4c0
|
||||
unsigned int aes_version; // 0x4c4
|
||||
unsigned int aes_hw_flags; // 0x4c8
|
||||
unsigned char reserved_8[0x28]; // 0x4cc
|
||||
unsigned int aes_sw_reset; // 0x4f4
|
||||
unsigned char reserved_9[0x08]; // 0x4f8
|
||||
unsigned int aes_fifo_data; // 0x500
|
||||
unsigned char reserved_10[0xfc]; // 0x504
|
||||
unsigned int aes_fifo_status; // 0x600
|
||||
};
|
||||
|
||||
#define AES_BUSY_BIT BIT(0)
|
||||
#define SW_RESET_BIT BIT(0)
|
||||
#define AES_SK_BIT BIT(0)
|
||||
|
||||
#define DIN_FIFO_FULL BIT(0)
|
||||
#define DIN_FIFO_EMPTY BIT(1)
|
||||
#define DOUT_FIFO_FULL BIT(2)
|
||||
#define DOUT_FIFO_EMPTY BIT(3)
|
||||
#define DIN_FIFO_OVERFLOW BIT(4)
|
||||
#define DOUT_FIFO_UNDERFLOW BIT(5)
|
||||
|
||||
int npcm_aes_select_key(u8 fkeyind);
|
||||
|
||||
#endif
|
90
arch/arm/include/asm/arch-npcm7xx/otp.h
Normal file
90
arch/arm/include/asm/arch-npcm7xx/otp.h
Normal file
@ -0,0 +1,90 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0+ */
|
||||
|
||||
#ifndef _NPCM_OTP_H_
|
||||
#define _NPCM_OTP_H_
|
||||
|
||||
#ifdef CONFIG_ARCH_NPCM8XX
|
||||
enum {
|
||||
NPCM_KEY_SA = 0,
|
||||
NPCM_FUSE_SA = 0,
|
||||
NPCM_NUM_OF_SA = 1
|
||||
};
|
||||
#else
|
||||
enum {
|
||||
NPCM_KEY_SA = 0,
|
||||
NPCM_FUSE_SA = 1,
|
||||
NPCM_NUM_OF_SA = 2
|
||||
};
|
||||
#endif
|
||||
|
||||
struct npcm_otp_regs {
|
||||
unsigned int fst;
|
||||
unsigned int faddr;
|
||||
unsigned int fdata;
|
||||
unsigned int fcfg;
|
||||
unsigned int fustrap_fkeyind;
|
||||
unsigned int fctl;
|
||||
};
|
||||
|
||||
#define FST_RDY BIT(0)
|
||||
#define FST_RDST BIT(1)
|
||||
#define FST_RIEN BIT(2)
|
||||
|
||||
#ifdef CONFIG_ARCH_NPCM8XX
|
||||
#define FADDR_BYTEADDR(addr) ((addr) << 3)
|
||||
#define FADDR_BITPOS(pos) ((pos) << 0)
|
||||
#define FADDR_VAL(addr, pos) (FADDR_BITPOS(pos) | FADDR_BYTEADDR(addr))
|
||||
#define FADDR_IN_PROG BIT(16)
|
||||
#else
|
||||
#define FADDR_BYTEADDR(addr) ((addr) << 0)
|
||||
#define FADDR_BITPOS(pos) ((pos) << 10)
|
||||
#define FADDR_VAL(addr, pos) (FADDR_BYTEADDR(addr) | FADDR_BITPOS(pos))
|
||||
#define FADDR_IN_PROG BIT(16)
|
||||
#endif
|
||||
|
||||
#define FDATA_MASK (0xff)
|
||||
|
||||
#define FUSTRAP_O_SECBOOT BIT(23)
|
||||
|
||||
#define FCFG_FDIS BIT(31)
|
||||
|
||||
#define FKEYIND_KVAL BIT(0)
|
||||
#define FKEYIND_KSIZE_MASK (0x00000070)
|
||||
#define FKEYIND_KSIZE_128 (0x40)
|
||||
#define FKEYIND_KSIZE_192 (0x50)
|
||||
#define FKEYIND_KSIZE_256 (0x60)
|
||||
#define FKEYIND_KIND_MASK (0x000c0000)
|
||||
#define FKEYIND_KIND_KEY(indx) ((indx) << 18)
|
||||
|
||||
// Program cycle initiation values (sequence of two adjacent writes)
|
||||
#define PROGRAM_ARM 0x1
|
||||
#define PROGRAM_INIT 0xBF79E5D0
|
||||
|
||||
#define OTP2_BASE 0xF018A000
|
||||
#define FUSTRAP (OTP2_BASE + 0x10)
|
||||
|
||||
// Read cycle initiation value
|
||||
#define READ_INIT 0x02
|
||||
|
||||
// Value to clean FDATA contents
|
||||
#define FDATA_CLEAN_VALUE 0x01
|
||||
|
||||
#ifdef CONFIG_ARCH_NPCM8XX
|
||||
#define NPCM_OTP_ARR_BYTE_SIZE 8192
|
||||
#else
|
||||
#define NPCM_OTP_ARR_BYTE_SIZE 1024
|
||||
#endif
|
||||
|
||||
#define MIN_PROGRAM_PULSES 4
|
||||
#define MAX_PROGRAM_PULSES 20
|
||||
#define NPCM_OTP_ARR_BYTE_SIZE 1024
|
||||
|
||||
int fuse_prog_image(u32 bank, uintptr_t address);
|
||||
int fuse_program_data(u32 bank, u32 word, u8 *data, u32 size);
|
||||
int npcm_otp_select_key(u8 key_index);
|
||||
bool npcm_otp_is_fuse_array_disabled(u32 arr);
|
||||
void npcm_otp_nibble_parity_ecc_encode(u8 *datain, u8 *dataout, u32 size);
|
||||
void npcm_otp_majority_rule_ecc_encode(u8 *datain, u8 *dataout, u32 size);
|
||||
void npcm_arch_preboot_os(void);
|
||||
|
||||
#endif
|
@ -7,6 +7,7 @@
|
||||
#include <dm.h>
|
||||
#include <spl.h>
|
||||
#include <init.h>
|
||||
#include <linux/err.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/arch/scu_ast2600.h>
|
||||
#include <asm/global_data.h>
|
||||
@ -21,8 +22,37 @@ void board_init_f(ulong dummy)
|
||||
dram_init();
|
||||
}
|
||||
|
||||
/*
|
||||
* Try to detect the boot mode. Fallback to the default,
|
||||
* memory mapped SPI XIP booting if detection failed.
|
||||
*/
|
||||
u32 spl_boot_device(void)
|
||||
{
|
||||
int rc;
|
||||
struct udevice *scu_dev;
|
||||
struct ast2600_scu *scu;
|
||||
|
||||
rc = uclass_get_device_by_driver(UCLASS_CLK,
|
||||
DM_DRIVER_GET(aspeed_ast2600_scu), &scu_dev);
|
||||
if (rc) {
|
||||
debug("%s: failed to get SCU driver\n", __func__);
|
||||
goto out;
|
||||
}
|
||||
|
||||
scu = devfdt_get_addr_ptr(scu_dev);
|
||||
if (IS_ERR_OR_NULL(scu)) {
|
||||
debug("%s: failed to get SCU base\n", __func__);
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* boot from UART has higher priority */
|
||||
if (scu->hwstrap2 & SCU_HWSTRAP2_BOOT_UART)
|
||||
return BOOT_DEVICE_UART;
|
||||
|
||||
if (scu->hwstrap1 & SCU_HWSTRAP1_BOOT_EMMC)
|
||||
return BOOT_DEVICE_MMC1;
|
||||
|
||||
out:
|
||||
return BOOT_DEVICE_RAM;
|
||||
}
|
||||
|
||||
|
94
arch/arm/mach-aspeed/ast2600/u-boot-spl.lds
Normal file
94
arch/arm/mach-aspeed/ast2600/u-boot-spl.lds
Normal file
@ -0,0 +1,94 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0+ */
|
||||
/*
|
||||
* Copyright (c) 2004-2008 Texas Instruments
|
||||
*
|
||||
* (C) Copyright 2002
|
||||
* Gary Jennejohn, DENX Software Engineering, <garyj@denx.de>
|
||||
*
|
||||
* (C) Copyright 2022
|
||||
* Chia-Wei Wang <chiawei_wang@aspeedtech.com>
|
||||
*/
|
||||
|
||||
MEMORY { .nor : ORIGIN = CONFIG_SPL_TEXT_BASE,
|
||||
LENGTH = CONFIG_SPL_SIZE_LIMIT }
|
||||
MEMORY { .bss : ORIGIN = CONFIG_SPL_BSS_START_ADDR,
|
||||
LENGTH = CONFIG_SPL_BSS_MAX_SIZE }
|
||||
|
||||
OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
|
||||
OUTPUT_ARCH(arm)
|
||||
ENTRY(_start)
|
||||
SECTIONS
|
||||
{
|
||||
. = 0x00000000;
|
||||
|
||||
. = ALIGN(4);
|
||||
.text :
|
||||
{
|
||||
__image_copy_start = .;
|
||||
*(.vectors)
|
||||
CPUDIR/start.o (.text*)
|
||||
*(.text*)
|
||||
*(.glue*)
|
||||
} > .nor
|
||||
|
||||
. = ALIGN(4);
|
||||
.rodata : { *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) } > .nor
|
||||
|
||||
. = ALIGN(4);
|
||||
.data : {
|
||||
*(.data*)
|
||||
} > .nor
|
||||
|
||||
. = ALIGN(4);
|
||||
.u_boot_list : {
|
||||
KEEP(*(SORT(.u_boot_list*)));
|
||||
} > .nor
|
||||
|
||||
. = ALIGN(4);
|
||||
.binman_sym_table : {
|
||||
__binman_sym_start = .;
|
||||
KEEP(*(SORT(.binman_sym*)));
|
||||
__binman_sym_end = .;
|
||||
} > .nor
|
||||
|
||||
. = ALIGN(4);
|
||||
|
||||
__image_copy_end = .;
|
||||
|
||||
.rel.dyn : {
|
||||
__rel_dyn_start = .;
|
||||
*(.rel*)
|
||||
__rel_dyn_end = .;
|
||||
} > .nor
|
||||
|
||||
.end :
|
||||
{
|
||||
*(.__end)
|
||||
} > .nor
|
||||
|
||||
_image_binary_end = .;
|
||||
|
||||
.bss : {
|
||||
__bss_start = .;
|
||||
*(.bss*)
|
||||
. = ALIGN(4);
|
||||
__bss_end = .;
|
||||
} > .bss
|
||||
|
||||
__bss_size = __bss_end - __bss_start;
|
||||
}
|
||||
|
||||
#if defined(IMAGE_MAX_SIZE)
|
||||
ASSERT(__image_copy_end - __image_copy_start <= (IMAGE_MAX_SIZE), \
|
||||
"SPL image too big");
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_SPL_BSS_MAX_SIZE)
|
||||
ASSERT(__bss_end - __bss_start <= (CONFIG_SPL_BSS_MAX_SIZE), \
|
||||
"SPL image BSS too big");
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_SPL_MAX_FOOTPRINT)
|
||||
ASSERT(__bss_end - _start <= (CONFIG_SPL_MAX_FOOTPRINT), \
|
||||
"SPL image plus BSS too big");
|
||||
#endif
|
1
arch/arm/mach-hpe/Makefile
Normal file
1
arch/arm/mach-hpe/Makefile
Normal file
@ -0,0 +1 @@
|
||||
obj-$(CONFIG_SOC_GXP) += gxp/
|
9
arch/arm/mach-hpe/gxp/Kconfig
Normal file
9
arch/arm/mach-hpe/gxp/Kconfig
Normal file
@ -0,0 +1,9 @@
|
||||
if ARCH_GXP
|
||||
|
||||
config SOC_GXP
|
||||
bool
|
||||
select CPU_V7A
|
||||
|
||||
source "board/hpe/gxp/Kconfig"
|
||||
|
||||
endif
|
1
arch/arm/mach-hpe/gxp/Makefile
Normal file
1
arch/arm/mach-hpe/gxp/Makefile
Normal file
@ -0,0 +1 @@
|
||||
obj-y += reset.o
|
25
arch/arm/mach-hpe/gxp/reset.c
Normal file
25
arch/arm/mach-hpe/gxp/reset.c
Normal file
@ -0,0 +1,25 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* GXP driver
|
||||
*
|
||||
* (C) Copyright 2022 Hewlett Packard Enterprise Development LP.
|
||||
* Author: Nick Hawkins <nick.hawkins@hpe.com>
|
||||
* Author: Jean-Marie Verdun <verdun@hpe.com>
|
||||
*/
|
||||
|
||||
#include <asm/io.h>
|
||||
|
||||
#define GXP_CCR 0xc0000000
|
||||
|
||||
/* empty to satisfy current lowlevel_init, can be removed any time */
|
||||
void lowlevel_init(void)
|
||||
{
|
||||
}
|
||||
|
||||
void reset_cpu(ulong ignored)
|
||||
{
|
||||
writel(1, GXP_CCR);
|
||||
|
||||
while (1)
|
||||
; /* loop forever till reset */
|
||||
}
|
12
board/armltd/corstone1000/Kconfig
Normal file
12
board/armltd/corstone1000/Kconfig
Normal file
@ -0,0 +1,12 @@
|
||||
if TARGET_CORSTONE1000
|
||||
|
||||
config SYS_BOARD
|
||||
default "corstone1000"
|
||||
|
||||
config SYS_VENDOR
|
||||
default "armltd"
|
||||
|
||||
config SYS_CONFIG_NAME
|
||||
default "corstone1000"
|
||||
|
||||
endif
|
7
board/armltd/corstone1000/MAINTAINERS
Normal file
7
board/armltd/corstone1000/MAINTAINERS
Normal file
@ -0,0 +1,7 @@
|
||||
CORSTONE1000 BOARD
|
||||
M: Rui Miguel Silva <rui.silva@linaro.org>
|
||||
M: Vishnu Banavath <vishnu.banavath@arm.com>
|
||||
S: Maintained
|
||||
F: board/armltd/corstone1000/
|
||||
F: include/configs/corstone1000.h
|
||||
F: configs/corstone1000_defconfig
|
7
board/armltd/corstone1000/Makefile
Normal file
7
board/armltd/corstone1000/Makefile
Normal file
@ -0,0 +1,7 @@
|
||||
# SPDX-License-Identifier: GPL-2.0+
|
||||
#
|
||||
# (C) Copyright 2022 Arm Limited
|
||||
# (C) Copyright 2022 Linaro
|
||||
# Rui Miguel Silva <rui.silva@linaro.org>
|
||||
|
||||
obj-y := corstone1000.o
|
91
board/armltd/corstone1000/corstone1000.c
Normal file
91
board/armltd/corstone1000/corstone1000.c
Normal file
@ -0,0 +1,91 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* (C) Copyright 2022 ARM Limited
|
||||
* (C) Copyright 2022 Linaro
|
||||
* Rui Miguel Silva <rui.silva@linaro.org>
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <dm.h>
|
||||
#include <netdev.h>
|
||||
#include <dm/platform_data/serial_pl01x.h>
|
||||
#include <asm/armv8/mmu.h>
|
||||
#include <asm/global_data.h>
|
||||
|
||||
static struct mm_region corstone1000_mem_map[] = {
|
||||
{
|
||||
/* CVM */
|
||||
.virt = 0x02000000UL,
|
||||
.phys = 0x02000000UL,
|
||||
.size = 0x02000000UL,
|
||||
.attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
|
||||
PTE_BLOCK_INNER_SHARE
|
||||
}, {
|
||||
/* QSPI */
|
||||
.virt = 0x08000000UL,
|
||||
.phys = 0x08000000UL,
|
||||
.size = 0x08000000UL,
|
||||
.attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
|
||||
PTE_BLOCK_INNER_SHARE
|
||||
}, {
|
||||
/* Host Peripherals */
|
||||
.virt = 0x1A000000UL,
|
||||
.phys = 0x1A000000UL,
|
||||
.size = 0x26000000UL,
|
||||
.attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
|
||||
PTE_BLOCK_NON_SHARE |
|
||||
PTE_BLOCK_PXN | PTE_BLOCK_UXN
|
||||
}, {
|
||||
/* USB */
|
||||
.virt = 0x40200000UL,
|
||||
.phys = 0x40200000UL,
|
||||
.size = 0x00100000UL,
|
||||
.attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
|
||||
PTE_BLOCK_NON_SHARE |
|
||||
PTE_BLOCK_PXN | PTE_BLOCK_UXN
|
||||
}, {
|
||||
/* ethernet */
|
||||
.virt = 0x40100000UL,
|
||||
.phys = 0x40100000UL,
|
||||
.size = 0x00100000UL,
|
||||
.attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
|
||||
PTE_BLOCK_NON_SHARE |
|
||||
PTE_BLOCK_PXN | PTE_BLOCK_UXN
|
||||
}, {
|
||||
/* OCVM */
|
||||
.virt = 0x80000000UL,
|
||||
.phys = 0x80000000UL,
|
||||
.size = 0x80000000UL,
|
||||
.attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
|
||||
PTE_BLOCK_INNER_SHARE
|
||||
}, {
|
||||
/* List terminator */
|
||||
0,
|
||||
}
|
||||
};
|
||||
|
||||
struct mm_region *mem_map = corstone1000_mem_map;
|
||||
|
||||
int board_init(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int dram_init(void)
|
||||
{
|
||||
gd->ram_size = PHYS_SDRAM_1_SIZE;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int dram_init_banksize(void)
|
||||
{
|
||||
gd->bd->bi_dram[0].start = PHYS_SDRAM_1;
|
||||
gd->bd->bi_dram[0].size = PHYS_SDRAM_1_SIZE;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void reset_cpu(ulong addr)
|
||||
{
|
||||
}
|
13
board/armltd/corstone1000/corstone1000.env
Normal file
13
board/armltd/corstone1000/corstone1000.env
Normal file
@ -0,0 +1,13 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0+ */
|
||||
|
||||
usb_pgood_delay=250
|
||||
boot_bank_flag=0x08002000
|
||||
kernel_addr_bank_0=0x083EE000
|
||||
kernel_addr_bank_1=0x0936E000
|
||||
retrieve_kernel_load_addr=
|
||||
if itest.l *${boot_bank_flag} == 0; then
|
||||
setenv kernel_addr $kernel_addr_bank_0;
|
||||
else
|
||||
setenv kernel_addr $kernel_addr_bank_1;
|
||||
fi;
|
||||
kernel_addr_r=0x88200000
|
46
board/hpe/gxp/Kconfig
Normal file
46
board/hpe/gxp/Kconfig
Normal file
@ -0,0 +1,46 @@
|
||||
choice
|
||||
prompt "SoC select"
|
||||
|
||||
config TARGET_GXP
|
||||
bool "GXP"
|
||||
select DM
|
||||
select SOC_GXP
|
||||
imply CMD_DM
|
||||
|
||||
config TARGET_GXP2
|
||||
bool "GXP2"
|
||||
select DM
|
||||
select SOC_GXP
|
||||
select GXP_ECC
|
||||
imply CMD_DM
|
||||
|
||||
endchoice
|
||||
|
||||
choice
|
||||
prompt "GXP VROM size"
|
||||
default GXP_VROM_64MB
|
||||
optional
|
||||
|
||||
config GXP_VROM_64MB
|
||||
bool "64MB"
|
||||
|
||||
config GXP_VROM_32MB
|
||||
bool "32MB"
|
||||
endchoice
|
||||
|
||||
config GXP_ECC
|
||||
bool "Enable memory ECC protected"
|
||||
help
|
||||
Use half of memory to enable ECC protected
|
||||
|
||||
config SYS_BOARD
|
||||
default "gxp"
|
||||
|
||||
config SYS_VENDOR
|
||||
default "hpe"
|
||||
|
||||
config SYS_CONFIG_NAME
|
||||
default "gxp"
|
||||
|
||||
config SYS_TEXT_BASE
|
||||
default 0x50000000
|
1
board/hpe/gxp/Makefile
Normal file
1
board/hpe/gxp/Makefile
Normal file
@ -0,0 +1 @@
|
||||
obj-y += gxp_board.o
|
27
board/hpe/gxp/gxp.env
Normal file
27
board/hpe/gxp/gxp.env
Normal file
@ -0,0 +1,27 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0+ */
|
||||
|
||||
recover_file=openbmc-hpe-recovery-image.mtd
|
||||
recover_cmd=usb start; mw.b 0xD100000D 0x40;
|
||||
if fatload usb 0 0x50000000 $recover_file 0x4C0000 0x80000; then
|
||||
setenv bootargs console=ttyS0,115200 recovery;
|
||||
setenv force_recovery;
|
||||
saveenv;
|
||||
bootm 0x50000000;
|
||||
else
|
||||
while itest 0 < 1; do
|
||||
mw.b 0xd1000005 0xc0;
|
||||
sleep .1;
|
||||
mw.b 0xd1000005 0x00;
|
||||
sleep .1;
|
||||
done;
|
||||
fi;
|
||||
reset;
|
||||
spiboot=if itest.b *0xD10000B2 == 6; then
|
||||
run recover_cmd;
|
||||
fi;
|
||||
if printenv force_recovery; then
|
||||
run recover_cmd;
|
||||
else
|
||||
bootm 0xfc080000;
|
||||
run recover_cmd;
|
||||
fi;
|
75
board/hpe/gxp/gxp_board.c
Normal file
75
board/hpe/gxp/gxp_board.c
Normal file
@ -0,0 +1,75 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* GXP timer driver
|
||||
*
|
||||
* (C) Copyright 2022 Hewlett Packard Enterprise Development LP.
|
||||
* Author: Nick Hawkins <nick.hawkins@hpe.com>
|
||||
* Author: Jean-Marie Verdun <verdun@hpe.com>
|
||||
*/
|
||||
|
||||
#include <linux/sizes.h>
|
||||
#include <asm/io.h>
|
||||
#include <dm.h>
|
||||
#include <dm/uclass.h>
|
||||
#include <ram.h>
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
#define ECHI_CMD 0xcefe0010
|
||||
|
||||
int board_init(void)
|
||||
{
|
||||
writel(0x00080002, ECHI_CMD);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int dram_init(void)
|
||||
{
|
||||
if (IS_ENABLED(CONFIG_TARGET_GXP)) {
|
||||
if (IS_ENABLED(CONFIG_GXP_ECC)) {
|
||||
/* 0x0f800000 */
|
||||
gd->ram_size = SZ_128M + SZ_64M + SZ_32M + SZ_16M + SZ_8M;
|
||||
} else {
|
||||
/* 0x1f000000 */
|
||||
gd->ram_size = SZ_256M + SZ_128M + SZ_64M + SZ_32M + SZ_16M;
|
||||
}
|
||||
|
||||
if (IS_ENABLED(CONFIG_GXP_VROM_64MB)) {
|
||||
if (IS_ENABLED(CONFIG_GXP_ECC)) {
|
||||
/* 0x0c000000 */
|
||||
gd->ram_size = SZ_128M + SZ_64M;
|
||||
} else {
|
||||
/* 0x18000000 */
|
||||
gd->ram_size = SZ_256M + SZ_128M;
|
||||
}
|
||||
}
|
||||
|
||||
if (IS_ENABLED(CONFIG_GXP_VROM_32MB)) {
|
||||
if (IS_ENABLED(CONFIG_GXP_ECC)) {
|
||||
/* 0x0e000000 */
|
||||
gd->ram_size = SZ_128M + SZ_64M + SZ_32M;
|
||||
} else {
|
||||
/* 0x1c000000 */
|
||||
gd->ram_size = SZ_256M + SZ_128M + SZ_64M;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (IS_ENABLED(CONFIG_TARGET_GXP2)) {
|
||||
/* 0x1b200000 */
|
||||
gd->ram_size = SZ_256M + SZ_128M + SZ_32M + SZ_16M + SZ_2M;
|
||||
if (IS_ENABLED(CONFIG_GXP_VROM_64MB)) {
|
||||
/* 0x14000000 */
|
||||
gd->ram_size = SZ_256M + SZ_64M;
|
||||
}
|
||||
|
||||
if (IS_ENABLED(CONFIG_GXP_VROM_32MB)) {
|
||||
/* 0x18000000 */
|
||||
gd->ram_size = SZ_256M + SZ_128M;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -1160,6 +1160,11 @@ config CMD_LOADB
|
||||
help
|
||||
Load a binary file over serial line.
|
||||
|
||||
config CMD_LOADM
|
||||
bool "loadm"
|
||||
help
|
||||
Load a binary over memory mapped.
|
||||
|
||||
config CMD_LOADS
|
||||
bool "loads"
|
||||
default y
|
||||
|
@ -34,6 +34,18 @@ static struct efi_device_path *bootefi_device_path;
|
||||
static void *image_addr;
|
||||
static size_t image_size;
|
||||
|
||||
/**
|
||||
* efi_get_image_parameters() - return image parameters
|
||||
*
|
||||
* @img_addr: address of loaded image in memory
|
||||
* @img_size: size of loaded image
|
||||
*/
|
||||
void efi_get_image_parameters(void **img_addr, size_t *img_size)
|
||||
{
|
||||
*img_addr = image_addr;
|
||||
*img_size = image_size;
|
||||
}
|
||||
|
||||
/**
|
||||
* efi_clear_bootdev() - clear boot device
|
||||
*/
|
||||
|
48
cmd/load.c
48
cmd/load.c
@ -1063,6 +1063,44 @@ static ulong load_serial_ymodem(ulong offset, int mode)
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_CMD_LOADM)
|
||||
static int do_load_memory_bin(struct cmd_tbl *cmdtp, int flag, int argc,
|
||||
char *const argv[])
|
||||
{
|
||||
ulong addr, dest, size;
|
||||
void *src, *dst;
|
||||
|
||||
if (argc != 4)
|
||||
return CMD_RET_USAGE;
|
||||
|
||||
addr = simple_strtoul(argv[1], NULL, 16);
|
||||
|
||||
dest = simple_strtoul(argv[2], NULL, 16);
|
||||
|
||||
size = simple_strtoul(argv[3], NULL, 16);
|
||||
|
||||
if (!size) {
|
||||
printf("loadm: can not load zero bytes\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
src = map_sysmem(addr, size);
|
||||
dst = map_sysmem(dest, size);
|
||||
|
||||
memcpy(dst, src, size);
|
||||
|
||||
unmap_sysmem(src);
|
||||
unmap_sysmem(dst);
|
||||
|
||||
if (IS_ENABLED(CONFIG_CMD_BOOTEFI))
|
||||
efi_set_bootdev("Mem", "", "", map_sysmem(dest, 0), size);
|
||||
|
||||
printf("loaded bin to memory: size: %lu\n", size);
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
|
||||
#if defined(CONFIG_CMD_LOADS)
|
||||
@ -1137,3 +1175,13 @@ U_BOOT_CMD(
|
||||
);
|
||||
|
||||
#endif /* CONFIG_CMD_LOADB */
|
||||
|
||||
#if defined(CONFIG_CMD_LOADM)
|
||||
U_BOOT_CMD(
|
||||
loadm, 4, 0, do_load_memory_bin,
|
||||
"load binary blob from source address to destination address",
|
||||
"[src_addr] [dst_addr] [size]\n"
|
||||
" - load a binary blob from one memory location to other"
|
||||
" from src_addr to dst_addr by size bytes"
|
||||
);
|
||||
#endif /* CONFIG_CMD_LOADM */
|
||||
|
@ -44,7 +44,6 @@ static int do_misc_list(struct cmd_tbl *cmdtp, int flag,
|
||||
static int do_misc_op(struct cmd_tbl *cmdtp, int flag,
|
||||
int argc, char *const argv[], enum misc_op op)
|
||||
{
|
||||
int (*misc_op)(struct udevice *, int, void *, int);
|
||||
struct udevice *dev;
|
||||
int offset;
|
||||
void *buf;
|
||||
@ -62,11 +61,10 @@ static int do_misc_op(struct cmd_tbl *cmdtp, int flag,
|
||||
size = hextoul(argv[3], NULL);
|
||||
|
||||
if (op == MISC_OP_READ)
|
||||
misc_op = misc_read;
|
||||
ret = misc_read(dev, offset, buf, size);
|
||||
else
|
||||
misc_op = misc_write;
|
||||
ret = misc_write(dev, offset, buf, size);
|
||||
|
||||
ret = misc_op(dev, offset, buf, size);
|
||||
if (ret < 0) {
|
||||
if (ret == -ENOSYS) {
|
||||
printf("The device does not support %s\n",
|
||||
|
52
configs/corstone1000_defconfig
Normal file
52
configs/corstone1000_defconfig
Normal file
@ -0,0 +1,52 @@
|
||||
CONFIG_ARM=y
|
||||
CONFIG_SKIP_LOWLEVEL_INIT=y
|
||||
CONFIG_TARGET_CORSTONE1000=y
|
||||
CONFIG_SYS_TEXT_BASE=0x80000000
|
||||
CONFIG_SYS_MALLOC_LEN=0x2000000
|
||||
CONFIG_NR_DRAM_BANKS=1
|
||||
CONFIG_DEFAULT_DEVICE_TREE="corstone1000-mps3"
|
||||
CONFIG_IDENT_STRING=" corstone1000 aarch64 "
|
||||
CONFIG_SYS_LOAD_ADDR=0x82100000
|
||||
CONFIG_DISTRO_DEFAULTS=y
|
||||
CONFIG_HAS_CUSTOM_SYS_INIT_SP_ADDR=y
|
||||
CONFIG_CUSTOM_SYS_INIT_SP_ADDR=0x83f00000
|
||||
CONFIG_FIT=y
|
||||
CONFIG_BOOTDELAY=3
|
||||
CONFIG_USE_BOOTARGS=y
|
||||
CONFIG_BOOTARGS="console=ttyAMA0 loglevel=9 ip=dhcp earlyprintk"
|
||||
CONFIG_BOOTCOMMAND="run retrieve_kernel_load_addr; echo Loading kernel from $kernel_addr to memory ... ; loadm $kernel_addr $kernel_addr_r 0xc00000; usb start; usb reset; run distro_bootcmd; bootefi $kernel_addr_r $fdtcontroladdr;"
|
||||
CONFIG_CONSOLE_RECORD=y
|
||||
CONFIG_LOGLEVEL=7
|
||||
# CONFIG_DISPLAY_CPUINFO is not set
|
||||
# CONFIG_DISPLAY_BOARDINFO is not set
|
||||
CONFIG_SYS_PROMPT="corstone1000# "
|
||||
CONFIG_SYS_MAXARGS=64
|
||||
CONFIG_SYS_CBSIZE=512
|
||||
# CONFIG_CMD_CONSOLE is not set
|
||||
CONFIG_CMD_BOOTZ=y
|
||||
# CONFIG_CMD_XIMG is not set
|
||||
CONFIG_CMD_LOADM=y
|
||||
# CONFIG_CMD_LOADS is not set
|
||||
# CONFIG_CMD_SETEXPR is not set
|
||||
# CONFIG_CMD_NFS is not set
|
||||
CONFIG_CMD_CACHE=y
|
||||
CONFIG_CMD_RTC=y
|
||||
CONFIG_CMD_TIME=y
|
||||
CONFIG_CMD_GETTIME=y
|
||||
CONFIG_OF_CONTROL=y
|
||||
CONFIG_VERSION_VARIABLE=y
|
||||
CONFIG_NET_RANDOM_ETHADDR=y
|
||||
CONFIG_REGMAP=y
|
||||
CONFIG_MISC=y
|
||||
# CONFIG_MMC is not set
|
||||
CONFIG_PHYLIB=y
|
||||
CONFIG_PHY_SMSC=y
|
||||
CONFIG_DM_ETH=y
|
||||
CONFIG_SMC911X=y
|
||||
CONFIG_PHY=y
|
||||
CONFIG_RAM=y
|
||||
CONFIG_DM_RTC=y
|
||||
CONFIG_RTC_EMULATION=y
|
||||
CONFIG_DM_SERIAL=y
|
||||
CONFIG_USB=y
|
||||
CONFIG_ERRNO_STR=y
|
@ -2,21 +2,26 @@ CONFIG_ARM=y
|
||||
CONFIG_ARCH_OMAP2PLUS=y
|
||||
CONFIG_SYS_TEXT_BASE=0x80100000
|
||||
CONFIG_SYS_MALLOC_LEN=0x40000
|
||||
CONFIG_SYS_MALLOC_F_LEN=0x400
|
||||
CONFIG_SYS_MALLOC_F_LEN=0x4000
|
||||
CONFIG_NR_DRAM_BANKS=2
|
||||
CONFIG_DEFAULT_DEVICE_TREE="omap3-devkit8000"
|
||||
CONFIG_SPL_TEXT_BASE=0x40200000
|
||||
CONFIG_TARGET_DEVKIT8000=y
|
||||
CONFIG_SPL_SYS_MALLOC_F_LEN=0x400
|
||||
CONFIG_SPL=y
|
||||
CONFIG_DISTRO_DEFAULTS=y
|
||||
CONFIG_HAS_CUSTOM_SYS_INIT_SP_ADDR=y
|
||||
CONFIG_CUSTOM_SYS_INIT_SP_ADDR=0x4020ff00
|
||||
CONFIG_BOOTCOMMAND="run autoboot"
|
||||
CONFIG_USE_PREBOOT=y
|
||||
CONFIG_SYS_CONSOLE_INFO_QUIET=y
|
||||
CONFIG_SPL_MAX_SIZE=0xec00
|
||||
CONFIG_SPL_BSS_START_ADDR=0x80000500
|
||||
CONFIG_SPL_SYS_MALLOC_SIMPLE=y
|
||||
CONFIG_SYS_SPL_MALLOC=y
|
||||
CONFIG_HAS_CUSTOM_SPL_MALLOC_START=y
|
||||
CONFIG_CUSTOM_SYS_SPL_MALLOC_ADDR=0x80208000
|
||||
# CONFIG_SPL_FS_EXT4 is not set
|
||||
CONFIG_SPL_NAND_DRIVERS=y
|
||||
CONFIG_SPL_NAND_ECC=y
|
||||
CONFIG_SPL_NAND_SIMPLE=y
|
||||
@ -31,8 +36,8 @@ CONFIG_SYS_MMCSD_RAW_MODE_ARGS_SECTORS=8
|
||||
CONFIG_SYS_MAXARGS=64
|
||||
# CONFIG_CMD_IMI is not set
|
||||
CONFIG_CMD_SPL=y
|
||||
CONFIG_CMD_SPL_NAND_OFS=0x680000
|
||||
CONFIG_CMD_SPL_WRITE_SIZE=0x400
|
||||
CONFIG_CMD_SPL_NAND_OFS=0x280000
|
||||
CONFIG_CMD_SPL_WRITE_SIZE=0x20000
|
||||
# CONFIG_CMD_FLASH is not set
|
||||
CONFIG_CMD_I2C=y
|
||||
CONFIG_CMD_MMC=y
|
||||
@ -50,16 +55,25 @@ CONFIG_JFFS2_PART_SIZE=0xF980000
|
||||
CONFIG_CMD_MTDPARTS=y
|
||||
CONFIG_MTDIDS_DEFAULT="nand0=nand"
|
||||
CONFIG_MTDPARTS_DEFAULT="mtdparts=nand:512k(x-loader),1920k(u-boot),128k(u-boot-env),4m(kernel),-(fs)"
|
||||
# CONFIG_ISO_PARTITION is not set
|
||||
# CONFIG_SPL_EFI_PARTITION is not set
|
||||
CONFIG_OF_CONTROL=y
|
||||
CONFIG_SPL_OF_CONTROL=y
|
||||
CONFIG_OF_SPL_REMOVE_PROPS="clocks clock-names interrupt-parent"
|
||||
CONFIG_ENV_OVERWRITE=y
|
||||
CONFIG_ENV_IS_IN_NAND=y
|
||||
CONFIG_SYS_RELOC_GD_ENV_ADDR=y
|
||||
CONFIG_VERSION_VARIABLE=y
|
||||
CONFIG_NET_RETRY_COUNT=20
|
||||
CONFIG_BOOTP_SEND_HOSTNAME=y
|
||||
CONFIG_SPL_DM=y
|
||||
CONFIG_SPL_DM_SEQ_ALIAS=y
|
||||
CONFIG_SPL_OF_TRANSLATE=y
|
||||
CONFIG_SYS_I2C_LEGACY=y
|
||||
CONFIG_SPL_SYS_I2C_LEGACY=y
|
||||
CONFIG_TWL4030_LED=y
|
||||
CONFIG_MMC_OMAP_HS=y
|
||||
CONFIG_DM_I2C=y
|
||||
CONFIG_MTD=y
|
||||
CONFIG_MTD_RAW_NAND=y
|
||||
CONFIG_NAND_OMAP_ECCSCHEME_HAM1_CODE_HW=y
|
||||
@ -70,7 +84,6 @@ CONFIG_SYS_NAND_OOBSIZE=0x40
|
||||
CONFIG_SYS_NAND_BUSWIDTH_16BIT=y
|
||||
CONFIG_SYS_NAND_U_BOOT_LOCATIONS=y
|
||||
CONFIG_SYS_NAND_U_BOOT_OFFS=0x80000
|
||||
CONFIG_DM_ETH=y
|
||||
CONFIG_DRIVER_DM9000=y
|
||||
CONFIG_CONS_INDEX=3
|
||||
CONFIG_JFFS2_NAND=y
|
||||
CONFIG_OF_LIBFDT=y
|
||||
|
@ -1,6 +1,7 @@
|
||||
CONFIG_ARM=y
|
||||
CONFIG_SYS_DCACHE_OFF=y
|
||||
CONFIG_SPL_SYS_THUMB_BUILD=y
|
||||
CONFIG_SPL_LDSCRIPT="arch/arm/mach-aspeed/ast2600/u-boot-spl.lds"
|
||||
CONFIG_ARCH_ASPEED=y
|
||||
CONFIG_SYS_TEXT_BASE=0x80000000
|
||||
CONFIG_SYS_MALLOC_LEN=0x2000000
|
||||
@ -32,10 +33,13 @@ CONFIG_BOOTCOMMAND="run bootspi"
|
||||
# CONFIG_DISPLAY_CPUINFO is not set
|
||||
CONFIG_SPL_SIZE_LIMIT_SUBTRACT_GD=y
|
||||
CONFIG_SPL_SIZE_LIMIT_SUBTRACT_MALLOC=y
|
||||
CONFIG_SPL_NO_BSS_LIMIT=y
|
||||
CONFIG_SPL_HAS_BSS_LINKER_SECTION=y
|
||||
CONFIG_SPL_BSS_START_ADDR=0x83000000
|
||||
CONFIG_SPL_BSS_MAX_SIZE=0x1000000
|
||||
CONFIG_SPL_SYS_MALLOC_SIMPLE=y
|
||||
CONFIG_SPL_STACK_R=y
|
||||
CONFIG_SPL_STACK_R_MALLOC_SIMPLE_LEN=0x2000000
|
||||
CONFIG_SPL_SEPARATE_BSS=y
|
||||
CONFIG_SPL_FIT_IMAGE_TINY=y
|
||||
CONFIG_SPL_DM_RESET=y
|
||||
CONFIG_SPL_RAM_SUPPORT=y
|
||||
|
60
configs/gxp_defconfig
Normal file
60
configs/gxp_defconfig
Normal file
@ -0,0 +1,60 @@
|
||||
CONFIG_ARM=y
|
||||
CONFIG_SKIP_LOWLEVEL_INIT=y
|
||||
CONFIG_SYS_THUMB_BUILD=y
|
||||
CONFIG_ARCH_GXP=y
|
||||
CONFIG_SYS_MALLOC_LEN=0x4000000
|
||||
CONFIG_GXP_VROM_64MB=y
|
||||
CONFIG_NR_DRAM_BANKS=1
|
||||
CONFIG_ENV_SIZE=0x10000
|
||||
CONFIG_ENV_OFFSET=0x60000
|
||||
CONFIG_ENV_SECT_SIZE=0x10000
|
||||
CONFIG_DEFAULT_DEVICE_TREE="hpe-bmc-dl360gen10"
|
||||
CONFIG_ENV_OFFSET_REDUND=0x70000
|
||||
CONFIG_SYS_LOAD_ADDR=0x40100000
|
||||
CONFIG_HAS_CUSTOM_SYS_INIT_SP_ADDR=y
|
||||
CONFIG_CUSTOM_SYS_INIT_SP_ADDR=0x2000000
|
||||
CONFIG_FIT=y
|
||||
CONFIG_FIT_SIGNATURE=y
|
||||
CONFIG_FIT_VERBOSE=y
|
||||
CONFIG_BOOTDELAY=5
|
||||
CONFIG_AUTOBOOT_KEYED=y
|
||||
CONFIG_AUTOBOOT_PROMPT="Press SPACE to abort autoboot in %d seconds\n"
|
||||
CONFIG_AUTOBOOT_STOP_STR=" "
|
||||
CONFIG_USE_BOOTARGS=y
|
||||
CONFIG_BOOTARGS="earlyprintk console=ttyS2,115200 user_debug=31"
|
||||
CONFIG_USE_BOOTCOMMAND=y
|
||||
CONFIG_BOOTCOMMAND="run spiboot"
|
||||
# CONFIG_DISPLAY_CPUINFO is not set
|
||||
# CONFIG_DISPLAY_BOARDINFO is not set
|
||||
CONFIG_HUSH_PARSER=y
|
||||
CONFIG_SYS_PROMPT="gxp# "
|
||||
# CONFIG_BOOTM_NETBSD is not set
|
||||
# CONFIG_BOOTM_PLAN9 is not set
|
||||
# CONFIG_BOOTM_RTEMS is not set
|
||||
# CONFIG_BOOTM_VXWORKS is not set
|
||||
CONFIG_CMD_GPT=y
|
||||
# CONFIG_RANDOM_UUID is not set
|
||||
CONFIG_CMD_MISC=y
|
||||
CONFIG_CMD_FAT=y
|
||||
CONFIG_ENV_IS_IN_SPI_FLASH=y
|
||||
CONFIG_SYS_REDUNDAND_ENVIRONMENT=y
|
||||
CONFIG_NETCONSOLE=y
|
||||
CONFIG_MISC=y
|
||||
# CONFIG_MMC is not set
|
||||
CONFIG_DM_SPI_FLASH=y
|
||||
CONFIG_SF_DEFAULT_MODE=3
|
||||
CONFIG_SPI_FLASH_MACRONIX=y
|
||||
CONFIG_SPI_FLASH_SPANSION=y
|
||||
CONFIG_SPI_FLASH_STMICRO=y
|
||||
CONFIG_SPI_FLASH_SST=y
|
||||
CONFIG_SPI_FLASH_WINBOND=y
|
||||
# CONFIG_POWER is not set
|
||||
CONFIG_RAM=y
|
||||
CONFIG_DM_SERIAL=y
|
||||
CONFIG_SYS_NS16550=y
|
||||
CONFIG_SPI=y
|
||||
CONFIG_DM_SPI=y
|
||||
CONFIG_GXP_SPI=y
|
||||
CONFIG_TIMER=y
|
||||
CONFIG_GXP_TIMER=y
|
||||
CONFIG_SHA512=y
|
@ -47,6 +47,7 @@ CONFIG_CMD_GPT=y
|
||||
CONFIG_CMD_GPT_RENAME=y
|
||||
CONFIG_CMD_IDE=y
|
||||
CONFIG_CMD_I2C=y
|
||||
CONFIG_CMD_LOADM=y
|
||||
CONFIG_CMD_OSD=y
|
||||
CONFIG_CMD_PCI=y
|
||||
CONFIG_CMD_READ=y
|
||||
|
@ -67,6 +67,7 @@ CONFIG_CMD_GPT=y
|
||||
CONFIG_CMD_GPT_RENAME=y
|
||||
CONFIG_CMD_IDE=y
|
||||
CONFIG_CMD_I2C=y
|
||||
CONFIG_CMD_LOADM=y
|
||||
CONFIG_CMD_LSBLK=y
|
||||
CONFIG_CMD_MUX=y
|
||||
CONFIG_CMD_OSD=y
|
||||
|
37
doc/device-tree-bindings/spi/hpe,gxp-spi.yaml
Normal file
37
doc/device-tree-bindings/spi/hpe,gxp-spi.yaml
Normal file
@ -0,0 +1,37 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: "http://devicetree.org/schemas/spi/hpe,gxp-spi.yaml#"
|
||||
$schema: "http://devicetree.org/meta-schemas/core.yaml#"
|
||||
|
||||
title: HPE GXP SPI Controller
|
||||
|
||||
maintainers:
|
||||
- Nick Hawkins <nick.hawkins@hpe.com>
|
||||
- Jean-Marie Verdun <verdun@hpe.com>
|
||||
|
||||
allOf:
|
||||
- $ref: "spi-controller.yaml#"
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: mikrotik,rb4xx-spi
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
spi@c00000200{
|
||||
compatible = "hpe,gxp-spi";
|
||||
reg = <0xc0000200 0x80>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
};
|
||||
|
49
doc/usage/cmd/loadm.rst
Normal file
49
doc/usage/cmd/loadm.rst
Normal file
@ -0,0 +1,49 @@
|
||||
.. SPDX-License-Identifier: GPL-2.0+:
|
||||
|
||||
loadm command
|
||||
=============
|
||||
|
||||
Synopsis
|
||||
--------
|
||||
|
||||
::
|
||||
|
||||
loadm <src_addr> <dst_addr> <len>
|
||||
|
||||
Description
|
||||
-----------
|
||||
|
||||
The loadm command is used to copy memory content from source address
|
||||
to destination address and, if efi is enabled, will setup a "Mem" efi
|
||||
boot device.
|
||||
|
||||
The number of transferred bytes must be set by bytes parameter
|
||||
|
||||
src_addr
|
||||
start address of the memory location to be loaded
|
||||
|
||||
dst_addr
|
||||
destination address of the byte stream to be loaded
|
||||
|
||||
len
|
||||
number of bytes to be copied in hexadecimal. Can not be 0 (zero).
|
||||
|
||||
Example
|
||||
-------
|
||||
|
||||
::
|
||||
|
||||
=> loadm ${kernel_addr} ${kernel_addr_r} ${kernel_size}
|
||||
loaded bin to memory: size: 12582912
|
||||
|
||||
Configuration
|
||||
-------------
|
||||
|
||||
The command is only available if CONFIG_CMD_LOADM=y.
|
||||
|
||||
Return value
|
||||
------------
|
||||
|
||||
The return value $? is set 0 (true) if the loading is succefull, and
|
||||
is set to 1 (false) in case of error.
|
||||
|
@ -44,6 +44,7 @@ Shell commands
|
||||
cmd/fatload
|
||||
cmd/for
|
||||
cmd/load
|
||||
cmd/loadm
|
||||
cmd/loady
|
||||
cmd/mbr
|
||||
cmd/md
|
||||
|
@ -6,4 +6,6 @@ source drivers/crypto/fsl/Kconfig
|
||||
|
||||
source drivers/crypto/aspeed/Kconfig
|
||||
|
||||
source drivers/crypto/nuvoton/Kconfig
|
||||
|
||||
endmenu
|
||||
|
@ -8,3 +8,4 @@ obj-y += rsa_mod_exp/
|
||||
obj-y += fsl/
|
||||
obj-y += hash/
|
||||
obj-y += aspeed/
|
||||
obj-y += nuvoton/
|
||||
|
14
drivers/crypto/nuvoton/Kconfig
Normal file
14
drivers/crypto/nuvoton/Kconfig
Normal file
@ -0,0 +1,14 @@
|
||||
config NPCM_AES
|
||||
bool "Support the NPCM AES algorithm"
|
||||
select NPCM_OTP
|
||||
help
|
||||
This provides a means to encrypt and decrypt data using the NPCM
|
||||
AES (Advanced Encryption Standard). This algorithm uses a symmetric
|
||||
key and is widely used as a streaming cipher. This command only
|
||||
supports AES256-CBC.
|
||||
|
||||
config NPCM_SHA
|
||||
bool "Enable NPCM cryptographic HW SHA accelerator"
|
||||
help
|
||||
This option enables support of NPCM cryptographic HW SHA accelerator.
|
||||
It supports SHA1 and SHA256 hashing algorithms.
|
2
drivers/crypto/nuvoton/Makefile
Normal file
2
drivers/crypto/nuvoton/Makefile
Normal file
@ -0,0 +1,2 @@
|
||||
obj-$(CONFIG_NPCM_AES) += npcm_aes.o
|
||||
obj-$(CONFIG_NPCM_SHA) += npcm_sha.o
|
301
drivers/crypto/nuvoton/npcm_aes.c
Normal file
301
drivers/crypto/nuvoton/npcm_aes.c
Normal file
@ -0,0 +1,301 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright (c) 2021 Nuvoton Technology Corp.
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <dm.h>
|
||||
#include <uboot_aes.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/arch/aes.h>
|
||||
#include <asm/arch/otp.h>
|
||||
#include <malloc.h>
|
||||
|
||||
#define ONE_SECOND 0xC00000
|
||||
|
||||
struct npcm_aes_priv {
|
||||
struct npcm_aes_regs *regs;
|
||||
};
|
||||
|
||||
static struct npcm_aes_priv *aes_priv;
|
||||
static u8 fkeyind_to_set = 0xff;
|
||||
|
||||
static int second_timeout(u32 *addr, u32 bitmask, u32 bitpol)
|
||||
{
|
||||
ulong time, i = 0;
|
||||
|
||||
time = get_timer(0);
|
||||
|
||||
/* default 1 second timeout */
|
||||
while (((readl(addr) & bitmask) == bitpol) && i < ONE_SECOND)
|
||||
i++;
|
||||
|
||||
if (i == ONE_SECOND) {
|
||||
printf("%xms timeout: addr = %x, mask = %x\n", (u32)get_timer(time),
|
||||
*addr, bitmask);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int npcm_aes_select_key(u8 fkeyind)
|
||||
{
|
||||
if (npcm_otp_is_fuse_array_disabled(NPCM_KEY_SA)) {
|
||||
printf("AES key access denied\n");
|
||||
return -EACCES;
|
||||
}
|
||||
|
||||
if (fkeyind < 4)
|
||||
fkeyind_to_set = fkeyind;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int npcm_aes_init(u8 dec_enc)
|
||||
{
|
||||
struct npcm_aes_regs *regs = aes_priv->regs;
|
||||
u32 ctrl, orgctrlval, wrtimeout;
|
||||
|
||||
/* reset hw */
|
||||
writel(readl(®s->aes_sw_reset) | SW_RESET_BIT, ®s->aes_sw_reset);
|
||||
writel(readl(®s->aes_fifo_status) | DIN_FIFO_OVERFLOW, ®s->aes_fifo_status);
|
||||
writel(readl(®s->aes_fifo_status) | DOUT_FIFO_UNDERFLOW, ®s->aes_fifo_status);
|
||||
|
||||
/* Workaround to over come Errata #648 */
|
||||
orgctrlval = readl(®s->aes_control);
|
||||
ctrl = (0x00002004 | dec_enc); /* AES256(CBC) */
|
||||
|
||||
if (ctrl != orgctrlval) {
|
||||
writel(ctrl, ®s->aes_control);
|
||||
|
||||
if (ctrl != readl(®s->aes_control)) {
|
||||
u32 read_ctrl;
|
||||
int intwr;
|
||||
|
||||
for (wrtimeout = 0; wrtimeout < 1000; wrtimeout++) {
|
||||
for (intwr = 0 ; intwr < 10; intwr++) {
|
||||
writel(ctrl, ®s->aes_control);
|
||||
writew(ctrl, (u16 *)®s->aes_control + 1);
|
||||
/* Write configurable info in a single write operation */
|
||||
mb();
|
||||
}
|
||||
|
||||
read_ctrl = readl(®s->aes_control);
|
||||
if (ctrl == read_ctrl)
|
||||
break;
|
||||
}
|
||||
|
||||
if (wrtimeout == 1000) {
|
||||
printf("\nTIMEOUT expected data=0x%x Actual AES_CONTROL data 0x%x\n\n",
|
||||
ctrl, read_ctrl);
|
||||
return -EAGAIN;
|
||||
}
|
||||
|
||||
printf("Workaround success, wrtimeout = %d\n", wrtimeout);
|
||||
}
|
||||
}
|
||||
|
||||
if (second_timeout(®s->aes_busy, AES_BUSY_BIT, AES_BUSY_BIT))
|
||||
return -EAGAIN;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void npcm_aes_load_iv(u8 *iv)
|
||||
{
|
||||
struct npcm_aes_regs *regs = aes_priv->regs;
|
||||
u32 *p = (u32 *)iv;
|
||||
u32 i;
|
||||
|
||||
/* Initialization Vector is loaded in 32-bit chunks */
|
||||
for (i = 0; i < (SIZE_AES_BLOCK / sizeof(u32)); i++)
|
||||
writel(p[i], ®s->aes_iv_0 + i);
|
||||
}
|
||||
|
||||
static inline void npcm_aes_load_key(u8 *key)
|
||||
{
|
||||
struct npcm_aes_regs *regs = aes_priv->regs;
|
||||
u32 *p = (u32 *)key;
|
||||
u32 i;
|
||||
|
||||
/* The key can be loaded either via the configuration or by using sideband
|
||||
* key port (aes_select_key).
|
||||
* If aes_select_key has been called ('fkeyind_to_set' was set to desired
|
||||
* key index) and no key is specified (key is NULL), we should use the
|
||||
* key index. Otherwise, we write the given key to the registers.
|
||||
*/
|
||||
if (!key && fkeyind_to_set < 4) {
|
||||
npcm_otp_select_key(fkeyind_to_set);
|
||||
|
||||
/* Sample the new key */
|
||||
writel(readl(®s->aes_sk) | AES_SK_BIT, ®s->aes_sk);
|
||||
|
||||
} else {
|
||||
/* Initialization Vector is loaded in 32-bit chunks */
|
||||
for (i = 0; i < (2 * SIZE_AES_BLOCK / sizeof(u32)); i++)
|
||||
writel(p[i], ®s->aes_key_0 + i);
|
||||
|
||||
fkeyind_to_set = 0xff;
|
||||
}
|
||||
}
|
||||
|
||||
static inline void npcm_aes_write(u32 *in)
|
||||
{
|
||||
struct npcm_aes_regs *regs = aes_priv->regs;
|
||||
u32 i;
|
||||
|
||||
/* 16 Byte AES Block is written in 32-bit chunks */
|
||||
for (i = 0; i < (SIZE_AES_BLOCK / sizeof(u32)); i++)
|
||||
writel(in[i], ®s->aes_fifo_data);
|
||||
}
|
||||
|
||||
static inline void npcm_aes_read(u32 *out)
|
||||
{
|
||||
struct npcm_aes_regs *regs = aes_priv->regs;
|
||||
u32 i;
|
||||
|
||||
/* Data is read in 32-bit chunks */
|
||||
for (i = 0; i < (SIZE_AES_BLOCK / sizeof(u32)); i++)
|
||||
out[i] = readl(®s->aes_fifo_data);
|
||||
}
|
||||
|
||||
static void npcm_aes_feed(u32 num_aes_blocks, u32 *datain, u32 *dataout)
|
||||
{
|
||||
struct npcm_aes_regs *regs = aes_priv->regs;
|
||||
u32 aes_datablk;
|
||||
u32 total_blocks = num_aes_blocks;
|
||||
u32 blocks_left = num_aes_blocks;
|
||||
|
||||
/* data mode */
|
||||
writel(readl(®s->aes_busy) | AES_BUSY_BIT, ®s->aes_busy);
|
||||
|
||||
/* Clear overflow and underflow */
|
||||
writel(readl(®s->aes_fifo_status) | DIN_FIFO_OVERFLOW, ®s->aes_fifo_status);
|
||||
writel(readl(®s->aes_fifo_status) | DOUT_FIFO_UNDERFLOW, ®s->aes_fifo_status);
|
||||
|
||||
/* datain/dataout is advanced in 32-bit chunks */
|
||||
aes_datablk = (SIZE_AES_BLOCK / sizeof(u32));
|
||||
|
||||
/* Quit if there is no complete blocks */
|
||||
if (total_blocks == 0)
|
||||
return;
|
||||
|
||||
/* Write the first block */
|
||||
if (total_blocks > 1) {
|
||||
npcm_aes_write(datain);
|
||||
datain += aes_datablk;
|
||||
blocks_left--;
|
||||
}
|
||||
|
||||
/* Write the second block */
|
||||
if (total_blocks > 2) {
|
||||
second_timeout(®s->aes_fifo_status, DIN_FIFO_EMPTY, 0);
|
||||
npcm_aes_write(datain);
|
||||
datain += aes_datablk;
|
||||
blocks_left--;
|
||||
}
|
||||
|
||||
/* Write & read available blocks */
|
||||
while (blocks_left > 0) {
|
||||
second_timeout(®s->aes_fifo_status, DIN_FIFO_FULL, DIN_FIFO_FULL);
|
||||
|
||||
/* Write next block */
|
||||
npcm_aes_write(datain);
|
||||
datain += aes_datablk;
|
||||
|
||||
/* Wait till DOUT FIFO is empty */
|
||||
second_timeout(®s->aes_fifo_status, DOUT_FIFO_EMPTY, DOUT_FIFO_EMPTY);
|
||||
|
||||
/* Read next block */
|
||||
npcm_aes_read(dataout);
|
||||
dataout += aes_datablk;
|
||||
|
||||
blocks_left--;
|
||||
}
|
||||
|
||||
if (total_blocks > 2) {
|
||||
second_timeout(®s->aes_fifo_status, DOUT_FIFO_FULL, 0);
|
||||
|
||||
/* Read next block */
|
||||
npcm_aes_read(dataout);
|
||||
dataout += aes_datablk;
|
||||
|
||||
second_timeout(®s->aes_fifo_status, DOUT_FIFO_FULL, 0);
|
||||
|
||||
/* Read next block */
|
||||
npcm_aes_read(dataout);
|
||||
dataout += aes_datablk;
|
||||
} else if (total_blocks > 1) {
|
||||
second_timeout(®s->aes_fifo_status, DOUT_FIFO_FULL, 0);
|
||||
|
||||
/* Read next block */
|
||||
npcm_aes_read(dataout);
|
||||
dataout += aes_datablk;
|
||||
}
|
||||
}
|
||||
|
||||
void aes_expand_key(u8 *key, u32 key_size, u8 *expkey)
|
||||
{
|
||||
/* npcm hw expands the key automatically, just copy it */
|
||||
memcpy(expkey, key, SIZE_AES_BLOCK * 2);
|
||||
}
|
||||
|
||||
void aes_cbc_encrypt_blocks(u32 key_size, u8 *key_exp, u8 *iv, u8 *src, u8 *dst,
|
||||
u32 num_aes_blocks)
|
||||
{
|
||||
if (npcm_aes_init(AES_OP_ENCRYPT))
|
||||
return;
|
||||
|
||||
npcm_aes_load_iv(iv);
|
||||
|
||||
npcm_aes_load_key(key_exp);
|
||||
|
||||
npcm_aes_feed(num_aes_blocks, (u32 *)src, (u32 *)dst);
|
||||
}
|
||||
|
||||
void aes_cbc_decrypt_blocks(u32 key_size, u8 *key_exp, u8 *iv, u8 *src, u8 *dst,
|
||||
u32 num_aes_blocks)
|
||||
{
|
||||
if (npcm_aes_init(AES_OP_DECRYPT))
|
||||
return;
|
||||
|
||||
npcm_aes_load_iv(iv);
|
||||
|
||||
npcm_aes_load_key(key_exp);
|
||||
|
||||
npcm_aes_feed(num_aes_blocks, (u32 *)src, (u32 *)dst);
|
||||
}
|
||||
|
||||
static int npcm_aes_bind(struct udevice *dev)
|
||||
{
|
||||
aes_priv = calloc(1, sizeof(struct npcm_aes_priv));
|
||||
if (!aes_priv) {
|
||||
printf("%s: %d\n", __func__, __LINE__);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
aes_priv->regs = dev_read_addr_ptr(dev);
|
||||
if (!aes_priv->regs) {
|
||||
printf("Cannot find aes reg address, binding failed\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
printf("AES: NPCM AES module bind OK\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct udevice_id npcm_aes_ids[] = {
|
||||
{ .compatible = "nuvoton,npcm845-aes" },
|
||||
{ .compatible = "nuvoton,npcm750-aes" },
|
||||
{ }
|
||||
};
|
||||
|
||||
U_BOOT_DRIVER(npcm_aes) = {
|
||||
.name = "npcm_aes",
|
||||
.id = UCLASS_MISC,
|
||||
.of_match = npcm_aes_ids,
|
||||
.priv_auto = sizeof(struct npcm_aes_priv),
|
||||
.bind = npcm_aes_bind,
|
||||
};
|
897
drivers/crypto/nuvoton/npcm_sha.c
Normal file
897
drivers/crypto/nuvoton/npcm_sha.c
Normal file
@ -0,0 +1,897 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright (c) 2022 Nuvoton Technology Corp.
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <dm.h>
|
||||
#include <hash.h>
|
||||
#include <malloc.h>
|
||||
#include <uboot_aes.h>
|
||||
#include <asm/io.h>
|
||||
|
||||
#define HASH_DIG_H_NUM 8
|
||||
|
||||
#define HASH_CTR_STS_SHA_EN BIT(0)
|
||||
#define HASH_CTR_STS_SHA_BUSY BIT(1)
|
||||
#define HASH_CTR_STS_SHA_RST BIT(2)
|
||||
#define HASH_CFG_SHA1_SHA2 BIT(0)
|
||||
|
||||
/* SHA type */
|
||||
enum npcm_sha_type {
|
||||
npcm_sha_type_sha2 = 0,
|
||||
npcm_sha_type_sha1,
|
||||
npcm_sha_type_num
|
||||
};
|
||||
|
||||
struct npcm_sha_regs {
|
||||
unsigned int hash_data_in;
|
||||
unsigned char hash_ctr_sts;
|
||||
unsigned char reserved_0[0x03];
|
||||
unsigned char hash_cfg;
|
||||
unsigned char reserved_1[0x03];
|
||||
unsigned char hash_ver;
|
||||
unsigned char reserved_2[0x13];
|
||||
unsigned int hash_dig[HASH_DIG_H_NUM];
|
||||
};
|
||||
|
||||
struct npcm_sha_priv {
|
||||
struct npcm_sha_regs *regs;
|
||||
};
|
||||
|
||||
static struct npcm_sha_priv *sha_priv;
|
||||
|
||||
#ifdef SHA_DEBUG_MODULE
|
||||
#define sha_print(fmt, args...) printf(fmt, ##args)
|
||||
#else
|
||||
#define sha_print(fmt, args...) (void)0
|
||||
#endif
|
||||
|
||||
#define SHA_BLOCK_LENGTH (512 / 8)
|
||||
#define SHA_2_HASH_LENGTH (256 / 8)
|
||||
#define SHA_1_HASH_LENGTH (160 / 8)
|
||||
#define SHA_HASH_LENGTH(type) ((type == npcm_sha_type_sha2) ? \
|
||||
(SHA_2_HASH_LENGTH) : (SHA_1_HASH_LENGTH))
|
||||
|
||||
#define SHA_SECRUN_BUFF_SIZE 64
|
||||
#define SHA_TIMEOUT 100
|
||||
#define SHA_DATA_LAST_BYTE 0x80
|
||||
|
||||
#define SHA2_NUM_OF_SELF_TESTS 3
|
||||
#define SHA1_NUM_OF_SELF_TESTS 4
|
||||
|
||||
#define NUVOTON_ALIGNMENT 4
|
||||
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
/* SHA instance struct handler */
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
struct SHA_HANDLE_T {
|
||||
u32 hv[SHA_2_HASH_LENGTH / sizeof(u32)];
|
||||
u32 length0;
|
||||
u32 length1;
|
||||
u32 block[SHA_BLOCK_LENGTH / sizeof(u32)];
|
||||
u8 type;
|
||||
bool active;
|
||||
};
|
||||
|
||||
// The # of bytes currently in the sha block buffer
|
||||
#define SHA_BUFF_POS(length) ((length) & (SHA_BLOCK_LENGTH - 1))
|
||||
|
||||
// The # of free bytes in the sha block buffer
|
||||
#define SHA_BUFF_FREE(length) (SHA_BLOCK_LENGTH - SHA_BUFF_POS(length))
|
||||
|
||||
static void SHA_FlushLocalBuffer_l(const u32 *buff);
|
||||
static int SHA_BusyWait_l(void);
|
||||
static void SHA_GetShaDigest_l(u8 *hashdigest, u8 type);
|
||||
static void SHA_SetShaDigest_l(const u32 *hashdigest, u8 type);
|
||||
static void SHA_SetBlock_l(const u8 *data, u32 len, u16 position, u32 *block);
|
||||
static void SHA_ClearBlock_l(u16 len, u16 position, u32 *block);
|
||||
static void SHA_SetLength32_l(struct SHA_HANDLE_T *handleptr, u32 *block);
|
||||
|
||||
static int SHA_Init(struct SHA_HANDLE_T *handleptr);
|
||||
static int SHA_Start(struct SHA_HANDLE_T *handleptr, u8 type);
|
||||
static int SHA_Update(struct SHA_HANDLE_T *handleptr, const u8 *buffer, u32 len);
|
||||
static int SHA_Finish(struct SHA_HANDLE_T *handleptr, u8 *hashdigest);
|
||||
static int SHA_Reset(void);
|
||||
static int SHA_Power(bool on);
|
||||
#ifdef SHA_PRINT
|
||||
static void SHA_PrintRegs(void);
|
||||
static void SHA_PrintVersion(void);
|
||||
#endif
|
||||
|
||||
static struct SHA_HANDLE_T sha_handle;
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/* Checks if give function returns int error, and returns the error */
|
||||
/* immediately after SHA disabling */
|
||||
/*----------------------------------------------------------------------------*/
|
||||
int npcm_sha_check(int status)
|
||||
{
|
||||
if (status != 0) {
|
||||
SHA_Power(false);
|
||||
return status;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/* Function: npcm_sha_calc */
|
||||
/* */
|
||||
/* Parameters: type - SHA module type */
|
||||
/* inBuff - Pointer to a buffer containing the data to */
|
||||
/* be hashed */
|
||||
/* len - Length of the data to hash */
|
||||
/* hashDigest - Pointer to a buffer where the reseulting */
|
||||
/* digest will be copied to */
|
||||
/* */
|
||||
/* Returns: 0 on success or other int error code on error */
|
||||
/* Side effects: */
|
||||
/* Description: */
|
||||
/* This routine performs complete SHA calculation in one */
|
||||
/* step */
|
||||
/*----------------------------------------------------------------------------*/
|
||||
int npcm_sha_calc(u8 type, const u8 *inbuff, u32 len, u8 *hashdigest)
|
||||
{
|
||||
int status;
|
||||
struct SHA_HANDLE_T handle;
|
||||
|
||||
SHA_Init(&handle);
|
||||
SHA_Power(true);
|
||||
SHA_Reset();
|
||||
SHA_Start(&handle, type);
|
||||
status = SHA_Update(&handle, inbuff, len);
|
||||
npcm_sha_check(status);
|
||||
status = SHA_Finish(&handle, hashdigest);
|
||||
npcm_sha_check(status);
|
||||
SHA_Power(false);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Computes hash value of input pbuf using h/w acceleration
|
||||
*
|
||||
* @param in_addr A pointer to the input buffer
|
||||
* @param bufleni Byte length of input buffer
|
||||
* @param out_addr A pointer to the output buffer. When complete
|
||||
* 32 bytes are copied to pout[0]...pout[31]. Thus, a user
|
||||
* should allocate at least 32 bytes at pOut in advance.
|
||||
* @param chunk_size chunk size for sha256
|
||||
*/
|
||||
void hw_sha256(const uchar *in_addr, uint buflen, uchar *out_addr, uint chunk_size)
|
||||
{
|
||||
puts("\nhw_sha256 using BMC HW accelerator\t");
|
||||
npcm_sha_calc(npcm_sha_type_sha2, (u8 *)in_addr, buflen, (u8 *)out_addr);
|
||||
}
|
||||
|
||||
/*
|
||||
* Computes hash value of input pbuf using h/w acceleration
|
||||
*
|
||||
* @param in_addr A pointer to the input buffer
|
||||
* @param bufleni Byte length of input buffer
|
||||
* @param out_addr A pointer to the output buffer. When complete
|
||||
* 32 bytes are copied to pout[0]...pout[31]. Thus, a user
|
||||
* should allocate at least 32 bytes at pOut in advance.
|
||||
* @param chunk_size chunk_size for sha1
|
||||
*/
|
||||
void hw_sha1(const uchar *in_addr, uint buflen, uchar *out_addr, uint chunk_size)
|
||||
{
|
||||
puts("\nhw_sha1 using BMC HW accelerator\t");
|
||||
npcm_sha_calc(npcm_sha_type_sha1, (u8 *)in_addr, buflen, (u8 *)out_addr);
|
||||
}
|
||||
|
||||
/*
|
||||
* Create the context for sha progressive hashing using h/w acceleration
|
||||
*
|
||||
* @algo: Pointer to the hash_algo struct
|
||||
* @ctxp: Pointer to the pointer of the context for hashing
|
||||
* @return 0 if ok, -ve on error
|
||||
*/
|
||||
int hw_sha_init(struct hash_algo *algo, void **ctxp)
|
||||
{
|
||||
const char *algo_name1 = "sha1";
|
||||
const char *algo_name2 = "sha256";
|
||||
|
||||
SHA_Init(&sha_handle);
|
||||
SHA_Power(true);
|
||||
SHA_Reset();
|
||||
if (!strcmp(algo_name1, algo->name))
|
||||
return SHA_Start(&sha_handle, npcm_sha_type_sha1);
|
||||
else if (!strcmp(algo_name2, algo->name))
|
||||
return SHA_Start(&sha_handle, npcm_sha_type_sha2);
|
||||
else
|
||||
return -EPROTO;
|
||||
}
|
||||
|
||||
/*
|
||||
* Update buffer for sha progressive hashing using h/w acceleration
|
||||
*
|
||||
* The context is freed by this function if an error occurs.
|
||||
*
|
||||
* @algo: Pointer to the hash_algo struct
|
||||
* @ctx: Pointer to the context for hashing
|
||||
* @buf: Pointer to the buffer being hashed
|
||||
* @size: Size of the buffer being hashed
|
||||
* @is_last: 1 if this is the last update; 0 otherwise
|
||||
* @return 0 if ok, -ve on error
|
||||
*/
|
||||
int hw_sha_update(struct hash_algo *algo, void *ctx, const void *buf,
|
||||
unsigned int size, int is_last)
|
||||
{
|
||||
return SHA_Update(&sha_handle, buf, size);
|
||||
}
|
||||
|
||||
/*
|
||||
* Copy sha hash result at destination location
|
||||
*
|
||||
* The context is freed after completion of hash operation or after an error.
|
||||
*
|
||||
* @algo: Pointer to the hash_algo struct
|
||||
* @ctx: Pointer to the context for hashing
|
||||
* @dest_buf: Pointer to the destination buffer where hash is to be copied
|
||||
* @size: Size of the buffer being hashed
|
||||
* @return 0 if ok, -ve on error
|
||||
*/
|
||||
int hw_sha_finish(struct hash_algo *algo, void *ctx, void *dest_buf, int size)
|
||||
{
|
||||
int status;
|
||||
|
||||
status = SHA_Finish(&sha_handle, dest_buf);
|
||||
npcm_sha_check(status);
|
||||
return SHA_Power(false);
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/* Function: SHA_Init */
|
||||
/* */
|
||||
/* Parameters: handlePtr - SHA processing handle pointer */
|
||||
/* Returns: 0 on success or other int error code on error. */
|
||||
/* Side effects: */
|
||||
/* Description: */
|
||||
/* This routine initialize the SHA module */
|
||||
/*----------------------------------------------------------------------------*/
|
||||
static int SHA_Init(struct SHA_HANDLE_T *handleptr)
|
||||
{
|
||||
handleptr->active = false;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/* Function: SHA_Start */
|
||||
/* */
|
||||
/* Parameters: handlePtr - SHA processing handle pointer */
|
||||
/* type - SHA module type */
|
||||
/* */
|
||||
/* Returns: 0 on success or other int error code on error. */
|
||||
/* Side effects: */
|
||||
/* Description: */
|
||||
/* This routine start a single SHA process */
|
||||
/*----------------------------------------------------------------------------*/
|
||||
static int SHA_Start(struct SHA_HANDLE_T *handleptr, u8 type)
|
||||
{
|
||||
struct npcm_sha_regs *regs = sha_priv->regs;
|
||||
|
||||
// Initialize handle
|
||||
handleptr->length0 = 0;
|
||||
handleptr->length1 = 0;
|
||||
handleptr->type = type;
|
||||
handleptr->active = true;
|
||||
|
||||
// Set SHA type
|
||||
writeb(handleptr->type & HASH_CFG_SHA1_SHA2, ®s->hash_cfg);
|
||||
|
||||
// Reset SHA hardware
|
||||
SHA_Reset();
|
||||
|
||||
/* The handlePtr->hv is initialized with the correct IV as the SHA engine
|
||||
* automatically fill the HASH_DIG_Hn registers according to SHA spec
|
||||
* (following SHA_RST assertion)
|
||||
*/
|
||||
SHA_GetShaDigest_l((u8 *)handleptr->hv, type);
|
||||
|
||||
// Init block with zeros
|
||||
memset(handleptr->block, 0, sizeof(handleptr->block));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/* Function: SHA_Update */
|
||||
/* */
|
||||
/* Parameters: handlePtr - SHA processing handle pointer */
|
||||
/* buffer - Pointer to the data that will be added to */
|
||||
/* the hash calculation */
|
||||
/* len - Length of data to add to SHA calculation */
|
||||
/* */
|
||||
/* */
|
||||
/* Returns: 0 on success or other int error code on error */
|
||||
/* Side effects: */
|
||||
/* Description: */
|
||||
/* This routine adds data to previously started SHA */
|
||||
/* calculation */
|
||||
/*----------------------------------------------------------------------------*/
|
||||
static int SHA_Update(struct SHA_HANDLE_T *handleptr, const u8 *buffer, u32 len)
|
||||
{
|
||||
struct npcm_sha_regs *regs = sha_priv->regs;
|
||||
u32 localbuffer[SHA_SECRUN_BUFF_SIZE / sizeof(u32)];
|
||||
u32 bufferlen = len;
|
||||
u16 pos = 0;
|
||||
u8 *blockptr;
|
||||
int status;
|
||||
|
||||
// Error check
|
||||
if (!handleptr->active)
|
||||
return -EPROTO;
|
||||
|
||||
// Wait till SHA is not busy
|
||||
status = SHA_BusyWait_l();
|
||||
npcm_sha_check(status);
|
||||
|
||||
// Set SHA type
|
||||
writeb(handleptr->type & HASH_CFG_SHA1_SHA2, ®s->hash_cfg);
|
||||
|
||||
// Write SHA latest digest into SHA module
|
||||
SHA_SetShaDigest_l(handleptr->hv, handleptr->type);
|
||||
|
||||
// Set number of unhashed bytes which remained from last update
|
||||
pos = SHA_BUFF_POS(handleptr->length0);
|
||||
|
||||
// Copy unhashed bytes which remained from last update to secrun buffer
|
||||
SHA_SetBlock_l((u8 *)handleptr->block, pos, 0, localbuffer);
|
||||
|
||||
while (len) {
|
||||
// Wait for the hardware to be available (in case we are hashing)
|
||||
status = SHA_BusyWait_l();
|
||||
npcm_sha_check(status);
|
||||
|
||||
// Move as much bytes as we can into the secrun buffer
|
||||
bufferlen = min(len, SHA_BUFF_FREE(handleptr->length0));
|
||||
|
||||
// Copy current given buffer to the secrun buffer
|
||||
SHA_SetBlock_l((u8 *)buffer, bufferlen, pos, localbuffer);
|
||||
|
||||
// Update size of hashed bytes
|
||||
handleptr->length0 += bufferlen;
|
||||
|
||||
if (handleptr->length0 < bufferlen)
|
||||
handleptr->length1++;
|
||||
|
||||
// Update length of data left to digest
|
||||
len -= bufferlen;
|
||||
|
||||
// Update given buffer pointer
|
||||
buffer += bufferlen;
|
||||
|
||||
// If secrun buffer is full
|
||||
if (SHA_BUFF_POS(handleptr->length0) == 0) {
|
||||
/* We just filled up the buffer perfectly, so let it hash (we'll
|
||||
* unload the hash only when we are done with all hashing)
|
||||
*/
|
||||
SHA_FlushLocalBuffer_l(localbuffer);
|
||||
|
||||
pos = 0;
|
||||
bufferlen = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Wait till SHA is not busy
|
||||
status = SHA_BusyWait_l();
|
||||
npcm_sha_check(status);
|
||||
|
||||
/* Copy unhashed bytes from given buffer to handle block for next update/finish */
|
||||
blockptr = (u8 *)handleptr->block;
|
||||
while (bufferlen)
|
||||
blockptr[--bufferlen + pos] = *(--buffer);
|
||||
|
||||
// Save SHA current digest
|
||||
SHA_GetShaDigest_l((u8 *)handleptr->hv, handleptr->type);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/* Function: SHA_Finish */
|
||||
/* */
|
||||
/* Parameters: handlePtr - SHA processing handle pointer */
|
||||
/* hashDigest - Pointer to a buffer where the final digest */
|
||||
/* will be copied to */
|
||||
/* */
|
||||
/* Returns: 0 on success or other int error code on error */
|
||||
/* Side effects: */
|
||||
/* Description: */
|
||||
/* This routine finish SHA calculation and get */
|
||||
/* the resulting SHA digest */
|
||||
/*----------------------------------------------------------------------------*/
|
||||
static int SHA_Finish(struct SHA_HANDLE_T *handleptr, u8 *hashdigest)
|
||||
{
|
||||
struct npcm_sha_regs *regs = sha_priv->regs;
|
||||
u32 localbuffer[SHA_SECRUN_BUFF_SIZE / sizeof(u32)];
|
||||
const u8 lastbyte = SHA_DATA_LAST_BYTE;
|
||||
u16 pos;
|
||||
int status;
|
||||
|
||||
// Error check
|
||||
if (!handleptr->active)
|
||||
return -EPROTO;
|
||||
|
||||
// Set SHA type
|
||||
writeb(handleptr->type & HASH_CFG_SHA1_SHA2, ®s->hash_cfg);
|
||||
|
||||
// Wait till SHA is not busy
|
||||
status = SHA_BusyWait_l();
|
||||
npcm_sha_check(status);
|
||||
|
||||
// Finish off the current buffer with the SHA spec'ed padding
|
||||
pos = SHA_BUFF_POS(handleptr->length0);
|
||||
|
||||
// Init SHA digest
|
||||
SHA_SetShaDigest_l(handleptr->hv, handleptr->type);
|
||||
|
||||
// Load data into secrun buffer
|
||||
SHA_SetBlock_l((u8 *)handleptr->block, pos, 0, localbuffer);
|
||||
|
||||
// Set data last byte as in SHA algorithm spec
|
||||
SHA_SetBlock_l(&lastbyte, 1, pos++, localbuffer);
|
||||
|
||||
// If the remainder of data is longer then one block
|
||||
if (pos > (SHA_BLOCK_LENGTH - 8)) {
|
||||
/* The length will be in the next block Pad the rest of the last block with 0's */
|
||||
SHA_ClearBlock_l((SHA_BLOCK_LENGTH - pos), pos, localbuffer);
|
||||
|
||||
// Hash the current block
|
||||
SHA_FlushLocalBuffer_l(localbuffer);
|
||||
|
||||
pos = 0;
|
||||
|
||||
// Wait till SHA is not busy
|
||||
status = SHA_BusyWait_l();
|
||||
npcm_sha_check(status);
|
||||
}
|
||||
|
||||
// Pad the rest of the last block with 0's except for the last 8-3 bytes
|
||||
SHA_ClearBlock_l((SHA_BLOCK_LENGTH - (8 - 3)) - pos, pos, localbuffer);
|
||||
|
||||
/* The last 8-3 bytes are set to the bit-length of the message in big-endian form */
|
||||
SHA_SetLength32_l(handleptr, localbuffer);
|
||||
|
||||
// Hash all that, and save the hash for the caller
|
||||
SHA_FlushLocalBuffer_l(localbuffer);
|
||||
|
||||
// Wait till SHA is not busy
|
||||
status = SHA_BusyWait_l();
|
||||
npcm_sha_check(status);
|
||||
|
||||
// Save SHA final digest into given buffer
|
||||
SHA_GetShaDigest_l(hashdigest, handleptr->type);
|
||||
|
||||
// Free handle
|
||||
handleptr->active = false;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/* Function: SHA_Reset */
|
||||
/* */
|
||||
/* Parameters: none */
|
||||
/* Returns: none */
|
||||
/* Side effects: */
|
||||
/* Description: */
|
||||
/* This routine reset SHA module */
|
||||
/*----------------------------------------------------------------------------*/
|
||||
static int SHA_Reset(void)
|
||||
{
|
||||
struct npcm_sha_regs *regs = sha_priv->regs;
|
||||
|
||||
writel(readl(®s->hash_ctr_sts) | HASH_CTR_STS_SHA_RST, ®s->hash_ctr_sts);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/* Function: SHA_Power */
|
||||
/* */
|
||||
/* Parameters: on - true enable the module, false disable the module */
|
||||
/* Returns: none */
|
||||
/* Side effects: */
|
||||
/* Description: */
|
||||
/* This routine set SHA module power on/off */
|
||||
/*----------------------------------------------------------------------------*/
|
||||
static int SHA_Power(bool on)
|
||||
{
|
||||
struct npcm_sha_regs *regs = sha_priv->regs;
|
||||
u8 hash_sts;
|
||||
|
||||
hash_sts = readb(®s->hash_ctr_sts) & ~HASH_CTR_STS_SHA_EN;
|
||||
writeb(hash_sts | (on & HASH_CTR_STS_SHA_EN), ®s->hash_ctr_sts);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef SHA_PRINT
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/* Function: SHA_PrintRegs */
|
||||
/* */
|
||||
/* Parameters: none */
|
||||
/* Returns: none */
|
||||
/* Side effects: */
|
||||
/* Description: */
|
||||
/* This routine prints the module registers */
|
||||
/*----------------------------------------------------------------------------*/
|
||||
static void SHA_PrintRegs(void)
|
||||
{
|
||||
#ifdef SHA_DEBUG_MODULE
|
||||
struct npcm_sha_regs *regs = sha_priv->regs;
|
||||
#endif
|
||||
unsigned int i;
|
||||
|
||||
sha_print("/*--------------*/\n");
|
||||
sha_print("/* SHA */\n");
|
||||
sha_print("/*--------------*/\n\n");
|
||||
|
||||
sha_print("HASH_CTR_STS = 0x%02X\n", readb(®s->hash_ctr_sts));
|
||||
sha_print("HASH_CFG = 0x%02X\n", readb(®s->hash_cfg));
|
||||
|
||||
for (i = 0; i < HASH_DIG_H_NUM; i++)
|
||||
sha_print("HASH_DIG_H%d = 0x%08X\n", i, readl(®s->hash_dig[i]));
|
||||
|
||||
sha_print("HASH_VER = 0x%08X\n", readb(®s->hash_ver));
|
||||
|
||||
sha_print("\n");
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/* Function: SHA_PrintVersion */
|
||||
/* */
|
||||
/* Parameters: none */
|
||||
/* Returns: none */
|
||||
/* Side effects: */
|
||||
/* Description: */
|
||||
/* This routine prints the module version */
|
||||
/*----------------------------------------------------------------------------*/
|
||||
static void SHA_PrintVersion(void)
|
||||
{
|
||||
struct npcm_sha_regs *regs = sha_priv->regs;
|
||||
|
||||
printf("SHA MODULE VER = %d\n", readb(®s->hash_ver));
|
||||
}
|
||||
#endif
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/* Function: npcm_sha_selftest */
|
||||
/* */
|
||||
/* Parameters: type - SHA module type */
|
||||
/* Returns: 0 on success or other int error code on error */
|
||||
/* Side effects: */
|
||||
/* Description: */
|
||||
/* This routine performs various tests on the SHA HW and SW */
|
||||
/*----------------------------------------------------------------------------*/
|
||||
int npcm_sha_selftest(u8 type)
|
||||
{
|
||||
int status;
|
||||
struct SHA_HANDLE_T handle;
|
||||
u8 hashdigest[max(SHA_1_HASH_LENGTH, SHA_2_HASH_LENGTH)];
|
||||
u16 i, j;
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* SHA1 tests info */
|
||||
/*------------------------------------------------------------------------*/
|
||||
|
||||
static const u8 sha1selftestbuff[SHA1_NUM_OF_SELF_TESTS][94] = {
|
||||
{"abc"},
|
||||
{"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"},
|
||||
{"0123456789012345678901234567890123456789012345678901234567890123"},
|
||||
{0x30, 0x5c, 0x30, 0x2c, 0x02, 0x01, 0x00, 0x30, 0x09, 0x06, 0x05, 0x2b,
|
||||
0x0e, 0x03, 0x02, 0x1a, 0x05, 0x00, 0x30, 0x06, 0x06, 0x04, 0x67, 0x2a,
|
||||
0x01, 0x0c, 0x04, 0x14, 0xe1, 0xb6, 0x93, 0xfe, 0x33, 0x43, 0xc1, 0x20,
|
||||
0x5d, 0x4b, 0xaa, 0xb8, 0x63, 0xfb, 0xcf, 0x6c, 0x46, 0x1e, 0x88, 0x04,
|
||||
0x30, 0x2c, 0x02, 0x01, 0x00, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03,
|
||||
0x02, 0x1a, 0x05, 0x00, 0x30, 0x06, 0x06, 0x04, 0x67, 0x2a, 0x01, 0x0c,
|
||||
0x04, 0x14, 0x13, 0xc1, 0x0c, 0xfc, 0xc8, 0x92, 0xd7, 0xde, 0x07, 0x1c,
|
||||
0x40, 0xde, 0x4f, 0xcd, 0x07, 0x5b, 0x68, 0x20, 0x5a, 0x6c}
|
||||
};
|
||||
|
||||
static const u8 sha1selftestbufflen[SHA1_NUM_OF_SELF_TESTS] = {
|
||||
3, 56, 64, 94
|
||||
};
|
||||
|
||||
static const u8 sha1selftestexpres[SHA1_NUM_OF_SELF_TESTS][SHA_1_HASH_LENGTH] = {
|
||||
{0xA9, 0x99, 0x3E, 0x36,
|
||||
0x47, 0x06, 0x81, 0x6A,
|
||||
0xBA, 0x3E, 0x25, 0x71,
|
||||
0x78, 0x50, 0xC2, 0x6C,
|
||||
0x9C, 0xD0, 0xD8, 0x9D},
|
||||
{0x84, 0x98, 0x3E, 0x44,
|
||||
0x1C, 0x3B, 0xD2, 0x6E,
|
||||
0xBA, 0xAE, 0x4A, 0xA1,
|
||||
0xF9, 0x51, 0x29, 0xE5,
|
||||
0xE5, 0x46, 0x70, 0xF1},
|
||||
{0xCF, 0x08, 0x00, 0xF7,
|
||||
0x64, 0x4A, 0xCE, 0x3C,
|
||||
0xB4, 0xC3, 0xFA, 0x33,
|
||||
0x38, 0x8D, 0x3B, 0xA0,
|
||||
0xEA, 0x3C, 0x8B, 0x6E},
|
||||
{0xc9, 0x84, 0x45, 0xc8,
|
||||
0x64, 0x04, 0xb1, 0xe3,
|
||||
0x3c, 0x6b, 0x0a, 0x8c,
|
||||
0x8b, 0x80, 0x94, 0xfc,
|
||||
0xf3, 0xc9, 0x98, 0xab}
|
||||
};
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* SHA2 tests info */
|
||||
/*------------------------------------------------------------------------*/
|
||||
|
||||
static const u8 sha2selftestbuff[SHA2_NUM_OF_SELF_TESTS][100] = {
|
||||
{ "abc" },
|
||||
{ "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" },
|
||||
{'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a',
|
||||
'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a',
|
||||
'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a',
|
||||
'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a',
|
||||
'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a',
|
||||
'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a',
|
||||
'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a',
|
||||
'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a',
|
||||
'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a',
|
||||
'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a'}
|
||||
};
|
||||
|
||||
static const u8 sha2selftestbufflen[SHA2_NUM_OF_SELF_TESTS] = {
|
||||
3, 56, 100
|
||||
};
|
||||
|
||||
static const u8 sha2selftestexpres[SHA2_NUM_OF_SELF_TESTS][SHA_2_HASH_LENGTH] = {
|
||||
/*
|
||||
* SHA-256 test vectors
|
||||
*/
|
||||
{ 0xBA, 0x78, 0x16, 0xBF, 0x8F, 0x01, 0xCF, 0xEA,
|
||||
0x41, 0x41, 0x40, 0xDE, 0x5D, 0xAE, 0x22, 0x23,
|
||||
0xB0, 0x03, 0x61, 0xA3, 0x96, 0x17, 0x7A, 0x9C,
|
||||
0xB4, 0x10, 0xFF, 0x61, 0xF2, 0x00, 0x15, 0xAD },
|
||||
{ 0x24, 0x8D, 0x6A, 0x61, 0xD2, 0x06, 0x38, 0xB8,
|
||||
0xE5, 0xC0, 0x26, 0x93, 0x0C, 0x3E, 0x60, 0x39,
|
||||
0xA3, 0x3C, 0xE4, 0x59, 0x64, 0xFF, 0x21, 0x67,
|
||||
0xF6, 0xEC, 0xED, 0xD4, 0x19, 0xDB, 0x06, 0xC1 },
|
||||
{ 0xCD, 0xC7, 0x6E, 0x5C, 0x99, 0x14, 0xFB, 0x92,
|
||||
0x81, 0xA1, 0xC7, 0xE2, 0x84, 0xD7, 0x3E, 0x67,
|
||||
0xF1, 0x80, 0x9A, 0x48, 0xA4, 0x97, 0x20, 0x0E,
|
||||
0x04, 0x6D, 0x39, 0xCC, 0xC7, 0x11, 0x2C, 0xD0 },
|
||||
};
|
||||
|
||||
if (type == npcm_sha_type_sha1) {
|
||||
/*--------------------------------------------------------------------*/
|
||||
/* SHA 1 TESTS */
|
||||
/*--------------------------------------------------------------------*/
|
||||
for (i = 0; i < SHA1_NUM_OF_SELF_TESTS; i++) {
|
||||
if (i != 3) {
|
||||
status = npcm_sha_calc(npcm_sha_type_sha1, sha1selftestbuff[i], sha1selftestbufflen[i], hashdigest);
|
||||
npcm_sha_check(status);
|
||||
} else {
|
||||
SHA_Power(true);
|
||||
SHA_Reset();
|
||||
status = SHA_Start(&handle, npcm_sha_type_sha1);
|
||||
npcm_sha_check(status);
|
||||
status = SHA_Update(&handle, sha1selftestbuff[i], 73);
|
||||
npcm_sha_check(status);
|
||||
status = SHA_Update(&handle, &sha1selftestbuff[i][73], sha1selftestbufflen[i] - 73);
|
||||
npcm_sha_check(status);
|
||||
status = SHA_Finish(&handle, hashdigest);
|
||||
npcm_sha_check(status);
|
||||
SHA_Power(false);
|
||||
}
|
||||
|
||||
if (memcmp(hashdigest, sha1selftestexpres[i], SHA_1_HASH_LENGTH))
|
||||
return -1;
|
||||
}
|
||||
|
||||
} else {
|
||||
/*--------------------------------------------------------------------*/
|
||||
/* SHA 2 TESTS */
|
||||
/*--------------------------------------------------------------------*/
|
||||
for (i = 0; i < SHA2_NUM_OF_SELF_TESTS; i++) {
|
||||
SHA_Power(true);
|
||||
SHA_Reset();
|
||||
status = SHA_Start(&handle, npcm_sha_type_sha2);
|
||||
npcm_sha_check(status);
|
||||
if (i == 2) {
|
||||
for (j = 0; j < 10000; j++) { //not working
|
||||
status = SHA_Update(&handle, sha2selftestbuff[i], sha2selftestbufflen[i]);
|
||||
npcm_sha_check(status);
|
||||
}
|
||||
} else {
|
||||
status = SHA_Update(&handle, sha2selftestbuff[i], sha2selftestbufflen[i]);
|
||||
npcm_sha_check(status);
|
||||
}
|
||||
|
||||
status = SHA_Finish(&handle, hashdigest);
|
||||
npcm_sha_check(status);
|
||||
SHA_Power(false);
|
||||
if (memcmp(hashdigest, sha2selftestexpres[i], SHA_2_HASH_LENGTH))
|
||||
return -1;
|
||||
|
||||
npcm_sha_calc(npcm_sha_type_sha2, sha2selftestbuff[i], sha2selftestbufflen[i], hashdigest);
|
||||
if (memcmp(hashdigest, sha2selftestexpres[i], SHA_2_HASH_LENGTH))
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/* Function: SHA_FlushLocalBuffer_l */
|
||||
/* */
|
||||
/* Parameters: */
|
||||
/* Returns: none */
|
||||
/* Side effects: */
|
||||
/* Description: This routine flush secrun buffer to SHA module */
|
||||
/*----------------------------------------------------------------------------*/
|
||||
static void SHA_FlushLocalBuffer_l(const u32 *buff)
|
||||
{
|
||||
struct npcm_sha_regs *regs = sha_priv->regs;
|
||||
u32 i;
|
||||
|
||||
for (i = 0; i < (SHA_BLOCK_LENGTH / sizeof(u32)); i++)
|
||||
writel(buff[i], ®s->hash_data_in);
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/* Function: SHA_BusyWait_l */
|
||||
/* */
|
||||
/* Parameters: */
|
||||
/* Returns: 0 if no error was found or DEFS_STATUS_ERROR otherwise */
|
||||
/* Side effects: */
|
||||
/* Description: This routine wait for SHA unit to no longer be busy */
|
||||
/*----------------------------------------------------------------------------*/
|
||||
static int SHA_BusyWait_l(void)
|
||||
{
|
||||
struct npcm_sha_regs *regs = sha_priv->regs;
|
||||
u32 timeout = SHA_TIMEOUT;
|
||||
|
||||
do {
|
||||
if (timeout-- == 0)
|
||||
return -ETIMEDOUT;
|
||||
} while ((readb(®s->hash_ctr_sts) & HASH_CTR_STS_SHA_BUSY)
|
||||
== HASH_CTR_STS_SHA_BUSY);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/* Function: SHA_GetShaDigest_l */
|
||||
/* */
|
||||
/* Parameters: hashDigest - buffer for the hash output. */
|
||||
/* type - SHA module type */
|
||||
/* Returns: none */
|
||||
/* Side effects: */
|
||||
/* Description: This routine copy the hash digest from the hardware */
|
||||
/* and into given buffer (in ram) */
|
||||
/*----------------------------------------------------------------------------*/
|
||||
static void SHA_GetShaDigest_l(u8 *hashdigest, u8 type)
|
||||
{
|
||||
struct npcm_sha_regs *regs = sha_priv->regs;
|
||||
u16 j;
|
||||
u8 len = SHA_HASH_LENGTH(type) / sizeof(u32);
|
||||
|
||||
// Copy Bytes from SHA module to given buffer
|
||||
for (j = 0; j < len; j++)
|
||||
((u32 *)hashdigest)[j] = readl(®s->hash_dig[j]);
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/* Function: SHA_SetShaDigest_l */
|
||||
/* */
|
||||
/* Parameters: hashDigest - input buffer to set as hash digest */
|
||||
/* type - SHA module type */
|
||||
/* Returns: none */
|
||||
/* Side effects: */
|
||||
/* Description: This routine set the hash digest in the hardware from */
|
||||
/* a given buffer (in ram) */
|
||||
/*----------------------------------------------------------------------------*/
|
||||
static void SHA_SetShaDigest_l(const u32 *hashdigest, u8 type)
|
||||
{
|
||||
struct npcm_sha_regs *regs = sha_priv->regs;
|
||||
u16 j;
|
||||
u8 len = SHA_HASH_LENGTH(type) / sizeof(u32);
|
||||
|
||||
// Copy Bytes from given buffer to SHA module
|
||||
for (j = 0; j < len; j++)
|
||||
writel(hashdigest[j], ®s->hash_dig[j]);
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/* Function: SHA_SetBlock_l */
|
||||
/* */
|
||||
/* Parameters: data - data to copy */
|
||||
/* len - size of data */
|
||||
/* position - byte offset into the block at which data */
|
||||
/* should be placed */
|
||||
/* block - block buffer */
|
||||
/* Returns: none */
|
||||
/* Side effects: */
|
||||
/* Description: This routine load bytes into block buffer */
|
||||
/*----------------------------------------------------------------------------*/
|
||||
static void SHA_SetBlock_l(const u8 *data, u32 len, u16 position, u32 *block)
|
||||
{
|
||||
u8 *dest = (u8 *)block;
|
||||
|
||||
memcpy(dest + position, data, len);
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/* Function: SHA_SetBlock_l */
|
||||
/* */
|
||||
/* Parameters: */
|
||||
/* len - size of data */
|
||||
/* position - byte offset into the block at which data */
|
||||
/* should be placed */
|
||||
/* block - block buffer */
|
||||
/* Returns: none */
|
||||
/* Side effects: */
|
||||
/* Description: This routine load zero's into the block buffer */
|
||||
/*----------------------------------------------------------------------------*/
|
||||
static void SHA_ClearBlock_l(u16 len, u16 position, u32 *block)
|
||||
{
|
||||
u8 *dest = (u8 *)block;
|
||||
|
||||
memset(dest + position, 0, len);
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/* Function: SHA_SetLength32_l */
|
||||
/* */
|
||||
/* Parameters: */
|
||||
/* handlePtr - SHA processing handle pointer */
|
||||
/* block - block buffer */
|
||||
/* Returns: none */
|
||||
/* Side effects: */
|
||||
/* Description: This routine set the length of the hash's data */
|
||||
/* len is the 32-bit byte length of the message */
|
||||
/*lint -efunc(734,SHA_SetLength32_l) Supperess loss of percision lint warning */
|
||||
/*----------------------------------------------------------------------------*/
|
||||
static void SHA_SetLength32_l(struct SHA_HANDLE_T *handleptr, u32 *block)
|
||||
{
|
||||
u16 *secrunbufferswappedptr = (u16 *)(void *)(block);
|
||||
|
||||
secrunbufferswappedptr[(SHA_BLOCK_LENGTH / sizeof(u16)) - 1] = (u16)
|
||||
((handleptr->length0 << 3) << 8) | ((u16)(handleptr->length0 << 3) >> 8);
|
||||
secrunbufferswappedptr[(SHA_BLOCK_LENGTH / sizeof(u16)) - 2] = (u16)
|
||||
((handleptr->length0 >> (16 - 3)) >> 8) | ((u16)(handleptr->length0 >> (16 - 3)) << 8);
|
||||
secrunbufferswappedptr[(SHA_BLOCK_LENGTH / sizeof(u16)) - 3] = (u16)
|
||||
((handleptr->length1 << 3) << 8) | ((u16)(handleptr->length1 << 3) >> 8);
|
||||
secrunbufferswappedptr[(SHA_BLOCK_LENGTH / sizeof(u16)) - 4] = (u16)
|
||||
((handleptr->length1 >> (16 - 3)) >> 8) | ((u16)(handleptr->length1 >> (16 - 3)) << 8);
|
||||
}
|
||||
|
||||
static int npcm_sha_bind(struct udevice *dev)
|
||||
{
|
||||
sha_priv = calloc(1, sizeof(struct npcm_sha_priv));
|
||||
if (!sha_priv)
|
||||
return -ENOMEM;
|
||||
|
||||
sha_priv->regs = dev_remap_addr_index(dev, 0);
|
||||
if (!sha_priv->regs) {
|
||||
printf("Cannot find sha reg address, binding failed\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
printf("SHA: NPCM SHA module bind OK\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct udevice_id npcm_sha_ids[] = {
|
||||
{ .compatible = "nuvoton,npcm845-sha" },
|
||||
{ .compatible = "nuvoton,npcm750-sha" },
|
||||
{ }
|
||||
};
|
||||
|
||||
U_BOOT_DRIVER(npcm_sha) = {
|
||||
.name = "npcm_sha",
|
||||
.id = UCLASS_MISC,
|
||||
.of_match = npcm_sha_ids,
|
||||
.priv_auto = sizeof(struct npcm_sha_priv),
|
||||
.bind = npcm_sha_bind,
|
||||
};
|
@ -321,6 +321,15 @@ config SPL_MXC_OCOTP
|
||||
Programmable memory pages, that are stored on some
|
||||
Freescale i.MX processors, in SPL.
|
||||
|
||||
config NPCM_OTP
|
||||
bool "Nnvoton NPCM BMC On-Chip OTP Memory Support"
|
||||
depends on (ARM && ARCH_NPCM)
|
||||
default n
|
||||
help
|
||||
Support NPCM BMC OTP memory (fuse).
|
||||
To compile this driver as a module, choose M here: the module
|
||||
will be called npcm_otp.
|
||||
|
||||
config NUVOTON_NCT6102D
|
||||
bool "Enable Nuvoton NCT6102D Super I/O driver"
|
||||
help
|
||||
|
@ -56,6 +56,7 @@ obj-$(CONFIG_MPC83XX_SERDES) += mpc83xx_serdes.o
|
||||
obj-$(CONFIG_$(SPL_TPL_)LS2_SFP) += ls2_sfp.o
|
||||
obj-$(CONFIG_$(SPL_)MXC_OCOTP) += mxc_ocotp.o
|
||||
obj-$(CONFIG_MXS_OCOTP) += mxs_ocotp.o
|
||||
obj-$(CONFIG_NPCM_OTP) += npcm_otp.o
|
||||
obj-$(CONFIG_NUVOTON_NCT6102D) += nuvoton_nct6102d.o
|
||||
obj-$(CONFIG_P2SB) += p2sb-uclass.o
|
||||
obj-$(CONFIG_PCA9551_LED) += pca9551_led.o
|
||||
|
512
drivers/misc/npcm_otp.c
Normal file
512
drivers/misc/npcm_otp.c
Normal file
@ -0,0 +1,512 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright (c) 2021 Nuvoton Technology Corp.
|
||||
*/
|
||||
|
||||
#include <clk.h>
|
||||
#include <common.h>
|
||||
#include <dm.h>
|
||||
#include <errno.h>
|
||||
#include <fuse.h>
|
||||
#include <asm/io.h>
|
||||
#include <linux/delay.h>
|
||||
#include <asm/arch/otp.h>
|
||||
|
||||
struct npcm_otp_priv {
|
||||
struct npcm_otp_regs *regs[2];
|
||||
};
|
||||
|
||||
static struct npcm_otp_priv *otp_priv;
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/* Function: npcm_otp_check_inputs */
|
||||
/* */
|
||||
/* Parameters: arr - fuse array number to check */
|
||||
/* word - fuse word (offset) to check */
|
||||
/* Returns: int */
|
||||
/* Side effects: */
|
||||
/* Description: Checks is arr and word are illegal and do not exceed */
|
||||
/* their range. Return 0 if they are legal, -1 if not */
|
||||
/*----------------------------------------------------------------------------*/
|
||||
static int npcm_otp_check_inputs(u32 arr, u32 word)
|
||||
{
|
||||
if (arr >= NPCM_NUM_OF_SA) {
|
||||
if (IS_ENABLED(CONFIG_ARCH_NPCM8XX))
|
||||
printf("\nError: npcm8XX otp includs only one bank: 0\n");
|
||||
if (IS_ENABLED(CONFIG_ARCH_NPCM7XX))
|
||||
printf("\nError: npcm7XX otp includs only two banks: 0 and 1\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (word >= NPCM_OTP_ARR_BYTE_SIZE) {
|
||||
printf("\nError: npcm otp array comprises only %d bytes, numbered from 0 to %d\n",
|
||||
NPCM_OTP_ARR_BYTE_SIZE, NPCM_OTP_ARR_BYTE_SIZE - 1);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/* Function: npcm_otp_wait_for_otp_ready */
|
||||
/* */
|
||||
/* Parameters: array - fuse array to wait for */
|
||||
/* Returns: int */
|
||||
/* Side effects: */
|
||||
/* Description: Initialize the Fuse HW module. */
|
||||
/*----------------------------------------------------------------------------*/
|
||||
static int npcm_otp_wait_for_otp_ready(u32 arr, u32 timeout)
|
||||
{
|
||||
struct npcm_otp_regs *regs = otp_priv->regs[arr];
|
||||
u32 time = timeout;
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* check parameters validity */
|
||||
/*------------------------------------------------------------------------*/
|
||||
if (arr > NPCM_FUSE_SA)
|
||||
return -EINVAL;
|
||||
|
||||
while (--time > 1) {
|
||||
if (readl(®s->fst) & FST_RDY) {
|
||||
/* fuse is ready, clear the status. */
|
||||
writel(readl(®s->fst) | FST_RDST, ®s->fst);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* try to clear the status in case it was set */
|
||||
writel(readl(®s->fst) | FST_RDST, ®s->fst);
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/* Function: npcm_otp_read_byte */
|
||||
/* */
|
||||
/* Parameters: arr - Storage Array type [input]. */
|
||||
/* addr - Byte-address to read from [input]. */
|
||||
/* data - Pointer to result [output]. */
|
||||
/* Returns: none */
|
||||
/* Side effects: */
|
||||
/* Description: Read 8-bit data from an OTP storage array. */
|
||||
/*----------------------------------------------------------------------------*/
|
||||
static void npcm_otp_read_byte(u32 arr, u32 addr, u8 *data)
|
||||
{
|
||||
struct npcm_otp_regs *regs = otp_priv->regs[arr];
|
||||
|
||||
/* Wait for the Fuse Box Idle */
|
||||
npcm_otp_wait_for_otp_ready(arr, 0xDEADBEEF);
|
||||
|
||||
/* Configure the byte address in the fuse array for read operation */
|
||||
writel(FADDR_VAL(addr, 0), ®s->faddr);
|
||||
|
||||
/* Initiate a read cycle */
|
||||
writel(READ_INIT, ®s->fctl);
|
||||
|
||||
/* Wait for read operation completion */
|
||||
npcm_otp_wait_for_otp_ready(arr, 0xDEADBEEF);
|
||||
|
||||
/* Read the result */
|
||||
*data = readl(®s->fdata) & FDATA_MASK;
|
||||
|
||||
/* Clean FDATA contents to prevent unauthorized software from reading
|
||||
* sensitive information
|
||||
*/
|
||||
writel(FDATA_CLEAN_VALUE, ®s->fdata);
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/* Function: npcm_otp_bit_is_programmed */
|
||||
/* */
|
||||
/* Parameters: arr - Storage Array type [input]. */
|
||||
/* byte_offset - Byte offset in array [input]. */
|
||||
/* bit_offset - Bit offset in byte [input]. */
|
||||
/* Returns: Nonzero if bit is programmed, zero otherwise. */
|
||||
/* Side effects: */
|
||||
/* Description: Check if a bit is programmed in an OTP storage array. */
|
||||
/*----------------------------------------------------------------------------*/
|
||||
static bool npcm_otp_bit_is_programmed(u32 arr,
|
||||
u32 byte_offset, u8 bit_offset)
|
||||
{
|
||||
u32 data = 0;
|
||||
|
||||
/* Read the entire byte you wish to program */
|
||||
npcm_otp_read_byte(arr, byte_offset, (u8 *)&data);
|
||||
|
||||
/* Check whether the bit is already programmed */
|
||||
if (data & (1 << bit_offset))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/* Function: npcm_otp_program_bit */
|
||||
/* */
|
||||
/* Parameters: arr - Storage Array type [input]. */
|
||||
/* byte)offset - Byte offset in array [input]. */
|
||||
/* bit_offset - Bit offset in byte [input]. */
|
||||
/* Returns: int */
|
||||
/* Side effects: */
|
||||
/* Description: Program (set to 1) a bit in an OTP storage array. */
|
||||
/*----------------------------------------------------------------------------*/
|
||||
static int npcm_otp_program_bit(u32 arr, u32 byte_offset,
|
||||
u8 bit_offset)
|
||||
{
|
||||
struct npcm_otp_regs *regs = otp_priv->regs[arr];
|
||||
int count;
|
||||
u8 read_data;
|
||||
|
||||
/* Wait for the Fuse Box Idle */
|
||||
npcm_otp_wait_for_otp_ready(arr, 0xDEADBEEF);
|
||||
|
||||
/* Make sure the bit is not already programmed */
|
||||
if (npcm_otp_bit_is_programmed(arr, byte_offset, bit_offset))
|
||||
return 0;
|
||||
|
||||
/* Configure the bit address in the fuse array for program operation */
|
||||
writel(FADDR_VAL(byte_offset, bit_offset), ®s->faddr);
|
||||
writel(readl(®s->faddr) | FADDR_IN_PROG, ®s->faddr);
|
||||
|
||||
// program up to MAX_PROGRAM_PULSES
|
||||
for (count = 1; count <= MAX_PROGRAM_PULSES; count++) {
|
||||
/* Initiate a program cycle */
|
||||
writel(PROGRAM_ARM, ®s->fctl);
|
||||
writel(PROGRAM_INIT, ®s->fctl);
|
||||
|
||||
/* Wait for program operation completion */
|
||||
npcm_otp_wait_for_otp_ready(arr, 0xDEADBEEF);
|
||||
|
||||
// after MIN_PROGRAM_PULSES start verifying the result
|
||||
if (count >= MIN_PROGRAM_PULSES) {
|
||||
/* Initiate a read cycle */
|
||||
writel(READ_INIT, ®s->fctl);
|
||||
|
||||
/* Wait for read operation completion */
|
||||
npcm_otp_wait_for_otp_ready(arr, 0xDEADBEEF);
|
||||
|
||||
/* Read the result */
|
||||
read_data = readl(®s->fdata) & FDATA_MASK;
|
||||
|
||||
/* If the bit is set the sequence ended correctly */
|
||||
if (read_data & (1 << bit_offset))
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// check if programmking failed
|
||||
if (count > MAX_PROGRAM_PULSES) {
|
||||
printf("program fail\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Clean FDATA contents to prevent unauthorized software from reading
|
||||
* sensitive information
|
||||
*/
|
||||
writel(FDATA_CLEAN_VALUE, ®s->fdata);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/* Function: npcm_otp_program_byte */
|
||||
/* */
|
||||
/* Parameters: arr - Storage Array type [input]. */
|
||||
/* byte_offset - Byte offset in array [input]. */
|
||||
/* value - Byte to program [input]. */
|
||||
/* Returns: int */
|
||||
/* Side effects: */
|
||||
/* Description: Program (set to 1) a given byte's relevant bits in an */
|
||||
/* OTP storage array. */
|
||||
/*----------------------------------------------------------------------------*/
|
||||
static int npcm_otp_program_byte(u32 arr, u32 byte_offset,
|
||||
u8 value)
|
||||
{
|
||||
int status = 0;
|
||||
unsigned int i;
|
||||
u8 data = 0;
|
||||
int rc;
|
||||
|
||||
rc = npcm_otp_check_inputs(arr, byte_offset);
|
||||
if (rc != 0)
|
||||
return rc;
|
||||
|
||||
/* Wait for the Fuse Box Idle */
|
||||
npcm_otp_wait_for_otp_ready(arr, 0xDEADBEEF);
|
||||
|
||||
/* Read the entire byte you wish to program */
|
||||
npcm_otp_read_byte(arr, byte_offset, &data);
|
||||
|
||||
/* In case all relevant bits are already programmed - nothing to do */
|
||||
if ((~data & value) == 0)
|
||||
return status;
|
||||
|
||||
/* Program unprogrammed bits. */
|
||||
for (i = 0; i < 8; i++) {
|
||||
if (value & (1 << i)) {
|
||||
/* Program (set to 1) the relevant bit */
|
||||
int last_status = npcm_otp_program_bit(arr, byte_offset, (u8)i);
|
||||
|
||||
if (last_status != 0)
|
||||
status = last_status;
|
||||
}
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/* Function: npcm_otp_is_fuse_array_disabled */
|
||||
/* */
|
||||
/* Parameters: arr - Storage Array type [input]. */
|
||||
/* Returns: bool */
|
||||
/* Side effects: */
|
||||
/* Description: Return true if access to the first 2048 bits of the */
|
||||
/* specified fuse array is disabled, false if not */
|
||||
/*----------------------------------------------------------------------------*/
|
||||
bool npcm_otp_is_fuse_array_disabled(u32 arr)
|
||||
{
|
||||
struct npcm_otp_regs *regs = otp_priv->regs[arr];
|
||||
|
||||
return (readl(®s->fcfg) & FCFG_FDIS) != 0;
|
||||
}
|
||||
|
||||
int npcm_otp_select_key(u8 key_index)
|
||||
{
|
||||
struct npcm_otp_regs *regs = otp_priv->regs[NPCM_KEY_SA];
|
||||
u32 idx = 0;
|
||||
u32 time = 0xDAEDBEEF;
|
||||
|
||||
if (key_index >= 4)
|
||||
return -1;
|
||||
|
||||
/* Do not destroy ECCDIS bit */
|
||||
idx = readl(®s->fustrap_fkeyind);
|
||||
|
||||
/* Configure the key size */
|
||||
idx &= ~FKEYIND_KSIZE_MASK;
|
||||
idx |= FKEYIND_KSIZE_256;
|
||||
|
||||
/* Configure the key index (0 to 3) */
|
||||
idx &= ~FKEYIND_KIND_MASK;
|
||||
idx |= FKEYIND_KIND_KEY(key_index);
|
||||
|
||||
writel(idx, ®s->fustrap_fkeyind);
|
||||
|
||||
/* Wait for selection completetion */
|
||||
while (--time > 1) {
|
||||
if (readl(®s->fustrap_fkeyind) & FKEYIND_KVAL)
|
||||
return 0;
|
||||
udelay(1);
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/* Function: npcm_otp_nibble_parity_ecc_encode */
|
||||
/* */
|
||||
/* Parameters: datain - pointer to decoded data buffer */
|
||||
/* dataout - pointer to encoded data buffer (buffer size */
|
||||
/* should be 2 x dataout) */
|
||||
/* size - size of encoded data (decoded data x 2) */
|
||||
/* Returns: none */
|
||||
/* Side effects: */
|
||||
/* Description: Decodes the data according to nibble parity ECC scheme. */
|
||||
/* Size specifies the encoded data size. */
|
||||
/* Decodes whole bytes only */
|
||||
/*----------------------------------------------------------------------------*/
|
||||
void npcm_otp_nibble_parity_ecc_encode(u8 *datain, u8 *dataout, u32 size)
|
||||
{
|
||||
u32 i, idx;
|
||||
u8 E0, E1, E2, E3;
|
||||
|
||||
for (i = 0; i < (size / 2); i++) {
|
||||
E0 = (datain[i] >> 0) & 0x01;
|
||||
E1 = (datain[i] >> 1) & 0x01;
|
||||
E2 = (datain[i] >> 2) & 0x01;
|
||||
E3 = (datain[i] >> 3) & 0x01;
|
||||
|
||||
idx = i * 2;
|
||||
dataout[idx] = datain[i] & 0x0f;
|
||||
dataout[idx] |= (E0 ^ E1) << 4;
|
||||
dataout[idx] |= (E2 ^ E3) << 5;
|
||||
dataout[idx] |= (E0 ^ E2) << 6;
|
||||
dataout[idx] |= (E1 ^ E3) << 7;
|
||||
|
||||
E0 = (datain[i] >> 4) & 0x01;
|
||||
E1 = (datain[i] >> 5) & 0x01;
|
||||
E2 = (datain[i] >> 6) & 0x01;
|
||||
E3 = (datain[i] >> 7) & 0x01;
|
||||
|
||||
idx = i * 2 + 1;
|
||||
dataout[idx] = (datain[i] & 0xf0) >> 4;
|
||||
dataout[idx] |= (E0 ^ E1) << 4;
|
||||
dataout[idx] |= (E2 ^ E3) << 5;
|
||||
dataout[idx] |= (E0 ^ E2) << 6;
|
||||
dataout[idx] |= (E1 ^ E3) << 7;
|
||||
}
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/* Function: npcm_otp_majority_rule_ecc_encode */
|
||||
/* */
|
||||
/* Parameters: datain - pointer to decoded data buffer */
|
||||
/* dataout - pointer to encoded data buffer (buffer size */
|
||||
/* should be 3 x dataout) */
|
||||
/* size - size of encoded data (decoded data x 3) */
|
||||
/* Returns: none */
|
||||
/* Side effects: */
|
||||
/* Description: Decodes the data according to Major Rule ECC scheme. */
|
||||
/* Size specifies the encoded data size. */
|
||||
/* Decodes whole bytes only */
|
||||
/*----------------------------------------------------------------------------*/
|
||||
void npcm_otp_majority_rule_ecc_encode(u8 *datain, u8 *dataout, u32 size)
|
||||
{
|
||||
u32 byte;
|
||||
u32 bit;
|
||||
u8 bit_val;
|
||||
u32 decoded_size = size / 3;
|
||||
|
||||
for (byte = 0; byte < decoded_size; byte++) {
|
||||
for (bit = 0; bit < 8; bit++) {
|
||||
bit_val = (datain[byte] >> bit) & 0x01;
|
||||
|
||||
if (bit_val) {
|
||||
dataout[byte] |= (1 << bit);
|
||||
dataout[decoded_size + byte] |= (1 << bit);
|
||||
dataout[decoded_size * 2 + byte] |= (1 << bit);
|
||||
} else {
|
||||
dataout[byte] &= ~(1 << bit);
|
||||
dataout[decoded_size + byte] &= ~(1 << bit);
|
||||
dataout[decoded_size * 2 + byte] &= ~(1 << bit);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/* Function: fuse_program_data */
|
||||
/* */
|
||||
/* Parameters: bank - Storage Array type [input]. */
|
||||
/* word - Byte offset in array [input]. */
|
||||
/* data - Pointer to data buffer to program. */
|
||||
/* size - Number of bytes to program. */
|
||||
/* Returns: none */
|
||||
/* Side effects: */
|
||||
/* Description: Programs the given byte array (size bytes) to the given */
|
||||
/* OTP storage array, starting from offset word. */
|
||||
/*----------------------------------------------------------------------------*/
|
||||
int fuse_program_data(u32 bank, u32 word, u8 *data, u32 size)
|
||||
{
|
||||
u32 arr = (u32)bank;
|
||||
u32 byte;
|
||||
int rc;
|
||||
|
||||
rc = npcm_otp_check_inputs(bank, word + size - 1);
|
||||
if (rc != 0)
|
||||
return rc;
|
||||
|
||||
for (byte = 0; byte < size; byte++) {
|
||||
u8 val;
|
||||
|
||||
val = data[byte];
|
||||
if (val == 0) // optimization
|
||||
continue;
|
||||
|
||||
rc = npcm_otp_program_byte(arr, word + byte, data[byte]);
|
||||
if (rc != 0)
|
||||
return rc;
|
||||
|
||||
// verify programming of every '1' bit
|
||||
val = 0;
|
||||
npcm_otp_read_byte((u32)bank, byte, &val);
|
||||
if ((data[byte] & ~val) != 0)
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int fuse_prog_image(u32 bank, uintptr_t address)
|
||||
{
|
||||
return fuse_program_data(bank, 0, (u8 *)address, NPCM_OTP_ARR_BYTE_SIZE);
|
||||
}
|
||||
|
||||
int fuse_read(u32 bank, u32 word, u32 *val)
|
||||
{
|
||||
int rc = npcm_otp_check_inputs(bank, word);
|
||||
|
||||
if (rc != 0)
|
||||
return rc;
|
||||
|
||||
*val = 0;
|
||||
npcm_otp_read_byte((u32)bank, word, (u8 *)val);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int fuse_sense(u32 bank, u32 word, u32 *val)
|
||||
{
|
||||
/* We do not support overriding */
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
int fuse_prog(u32 bank, u32 word, u32 val)
|
||||
{
|
||||
int rc;
|
||||
|
||||
rc = npcm_otp_check_inputs(bank, word);
|
||||
if (rc != 0)
|
||||
return rc;
|
||||
|
||||
return npcm_otp_program_byte(bank, word, (u8)val);
|
||||
}
|
||||
|
||||
int fuse_override(u32 bank, u32 word, u32 val)
|
||||
{
|
||||
/* We do not support overriding */
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static int npcm_otp_bind(struct udevice *dev)
|
||||
{
|
||||
struct npcm_otp_regs *regs;
|
||||
|
||||
otp_priv = calloc(1, sizeof(struct npcm_otp_priv));
|
||||
if (!otp_priv)
|
||||
return -ENOMEM;
|
||||
|
||||
regs = dev_remap_addr_index(dev, 0);
|
||||
if (!regs) {
|
||||
printf("Cannot find reg address (arr #0), binding failed\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
otp_priv->regs[0] = regs;
|
||||
|
||||
if (IS_ENABLED(CONFIG_ARCH_NPCM7xx)) {
|
||||
regs = dev_remap_addr_index(dev, 1);
|
||||
if (!regs) {
|
||||
printf("Cannot find reg address (arr #1), binding failed\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
otp_priv->regs[1] = regs;
|
||||
}
|
||||
printf("OTP: NPCM OTP module bind OK\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct udevice_id npcm_otp_ids[] = {
|
||||
{ .compatible = "nuvoton,npcm845-otp" },
|
||||
{ .compatible = "nuvoton,npcm750-otp" },
|
||||
{ }
|
||||
};
|
||||
|
||||
U_BOOT_DRIVER(npcm_otp) = {
|
||||
.name = "npcm_otp",
|
||||
.id = UCLASS_MISC,
|
||||
.of_match = npcm_otp_ids,
|
||||
.priv_auto = sizeof(struct npcm_otp_priv),
|
||||
.bind = npcm_otp_bind,
|
||||
};
|
@ -186,6 +186,12 @@ config FSL_QSPI_AHB_FULL_MAP
|
||||
Enable the Freescale QSPI driver to use full AHB memory map space for
|
||||
flash access.
|
||||
|
||||
config GXP_SPI
|
||||
bool "SPI driver for GXP"
|
||||
imply SPI_FLASH_BAR
|
||||
help
|
||||
Enable support for SPI on GXP.
|
||||
|
||||
config ICH_SPI
|
||||
bool "Intel ICH SPI driver"
|
||||
help
|
||||
|
@ -33,6 +33,7 @@ obj-$(CONFIG_EXYNOS_SPI) += exynos_spi.o
|
||||
obj-$(CONFIG_FSL_DSPI) += fsl_dspi.o
|
||||
obj-$(CONFIG_FSL_ESPI) += fsl_espi.o
|
||||
obj-$(CONFIG_SYNQUACER_SPI) += spi-synquacer.o
|
||||
obj-$(CONFIG_GXP_SPI) += gxp_spi.o
|
||||
obj-$(CONFIG_ICH_SPI) += ich.o
|
||||
obj-$(CONFIG_IPROC_QSPI) += iproc_qspi.o
|
||||
obj-$(CONFIG_KIRKWOOD_SPI) += kirkwood_spi.o
|
||||
|
304
drivers/spi/gxp_spi.c
Normal file
304
drivers/spi/gxp_spi.c
Normal file
@ -0,0 +1,304 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* GXP SPI driver
|
||||
*
|
||||
* (C) Copyright 2022 Hewlett Packard Enterprise Development LP.
|
||||
* Author: Nick Hawkins <nick.hawkins@hpe.com>
|
||||
* Author: Jean-Marie Verdun <verdun@hpe.com>
|
||||
*/
|
||||
|
||||
#include <spi.h>
|
||||
#include <asm/io.h>
|
||||
#include <dm.h>
|
||||
|
||||
#define GXP_SPI0_MAX_CHIPSELECT 2
|
||||
|
||||
#define MANUAL_MODE 0
|
||||
#define AUTO_MODE 1
|
||||
#define OFFSET_SPIMCFG 0x00
|
||||
#define OFFSET_SPIMCTRL 0x04
|
||||
#define OFFSET_SPICMD 0x05
|
||||
#define OFFSET_SPIDCNT 0x06
|
||||
#define OFFSET_SPIADDR 0x08
|
||||
#define OFFSET_SPILDAT 0x40
|
||||
#define GXP_SPILDAT_SIZE 64
|
||||
|
||||
#define SPIMCTRL_START 0x01
|
||||
#define SPIMCTRL_BUSY 0x02
|
||||
|
||||
#define CMD_READ_ARRAY_FAST 0x0b
|
||||
|
||||
struct gxp_spi_priv {
|
||||
struct spi_slave slave;
|
||||
void __iomem *base;
|
||||
unsigned int mode;
|
||||
|
||||
};
|
||||
|
||||
static void spi_set_mode(struct gxp_spi_priv *priv, int mode)
|
||||
{
|
||||
unsigned char value;
|
||||
|
||||
value = readb(priv->base + OFFSET_SPIMCTRL);
|
||||
if (mode == MANUAL_MODE) {
|
||||
writeb(0x55, priv->base + OFFSET_SPICMD);
|
||||
writeb(0xaa, priv->base + OFFSET_SPICMD);
|
||||
/* clear bit5 and bit4, auto_start and start_mask */
|
||||
value &= ~(0x03 << 4);
|
||||
} else {
|
||||
value |= (0x03 << 4);
|
||||
}
|
||||
writeb(value, priv->base + OFFSET_SPIMCTRL);
|
||||
}
|
||||
|
||||
static int gxp_spi_xfer(struct udevice *dev, unsigned int bitlen, const void *dout, void *din,
|
||||
unsigned long flags)
|
||||
{
|
||||
struct gxp_spi_priv *priv = dev_get_priv(dev->parent);
|
||||
struct spi_slave *slave = dev_get_parent_priv(dev);
|
||||
struct dm_spi_slave_plat *slave_plat = dev_get_parent_plat(dev);
|
||||
|
||||
unsigned int len = bitlen / 8;
|
||||
unsigned int value;
|
||||
unsigned int addr = 0;
|
||||
unsigned char uchar_out[len];
|
||||
unsigned char *uchar_in = (unsigned char *)din;
|
||||
int read_len;
|
||||
int read_ptr;
|
||||
|
||||
if (dout && din) {
|
||||
/*
|
||||
* error: gxp spi engin cannot send data to dout and read data from din at the same
|
||||
* time
|
||||
*/
|
||||
return -1;
|
||||
}
|
||||
|
||||
memset(uchar_out, 0, sizeof(uchar_out));
|
||||
if (dout)
|
||||
memcpy(uchar_out, dout, len);
|
||||
|
||||
if (flags & SPI_XFER_BEGIN) {
|
||||
/* the dout is cmd + addr, cmd=dout[0], add1~3=dout[1~3]. */
|
||||
/* cmd reg */
|
||||
writeb(uchar_out[0], priv->base + OFFSET_SPICMD);
|
||||
|
||||
/* config reg */
|
||||
value = readl(priv->base + OFFSET_SPIMCFG);
|
||||
value &= ~(1 << 24);
|
||||
/* set chipselect */
|
||||
value |= (slave_plat->cs << 24);
|
||||
|
||||
/* addr reg and addr size */
|
||||
if (len >= 4) {
|
||||
addr = uchar_out[1] << 16 | uchar_out[2] << 8 | uchar_out[3];
|
||||
writel(addr, priv->base + OFFSET_SPIADDR);
|
||||
value &= ~(0x07 << 16);
|
||||
/* set the address size to 3 byte */
|
||||
value |= (3 << 16);
|
||||
} else {
|
||||
writel(0, priv->base + OFFSET_SPIADDR);
|
||||
/* set the address size to 0 byte */
|
||||
value &= ~(0x07 << 16);
|
||||
}
|
||||
|
||||
/* dummy */
|
||||
/* clear dummy_cnt to */
|
||||
value &= ~(0x1f << 19);
|
||||
if (uchar_out[0] == CMD_READ_ARRAY_FAST) {
|
||||
/* fast read needs 8 dummy clocks */
|
||||
value |= (8 << 19);
|
||||
}
|
||||
|
||||
writel(value, priv->base + OFFSET_SPIMCFG);
|
||||
|
||||
if (flags & SPI_XFER_END) {
|
||||
/* no data cmd just start it */
|
||||
/* set the data direction bit to 1 */
|
||||
value = readb(priv->base + OFFSET_SPIMCTRL);
|
||||
value |= (1 << 3);
|
||||
writeb(value, priv->base + OFFSET_SPIMCTRL);
|
||||
|
||||
/* set the data byte count */
|
||||
writeb(0, priv->base + OFFSET_SPIDCNT);
|
||||
|
||||
/* set the start bit */
|
||||
value = readb(priv->base + OFFSET_SPIMCTRL);
|
||||
value |= SPIMCTRL_START;
|
||||
writeb(value, priv->base + OFFSET_SPIMCTRL);
|
||||
|
||||
/* wait busy bit is cleared */
|
||||
do {
|
||||
value = readb(priv->base + OFFSET_SPIMCTRL);
|
||||
} while (value & SPIMCTRL_BUSY);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (!(flags & SPI_XFER_END) && (flags & SPI_XFER_BEGIN)) {
|
||||
/* first of spi_xfer calls */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* if dout != null, write data to buf and start transaction */
|
||||
if (dout) {
|
||||
if (len > slave->max_write_size) {
|
||||
printf("SF: write length is too big(>%d)\n", slave->max_write_size);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* load the data bytes */
|
||||
memcpy((u8 *)priv->base + OFFSET_SPILDAT, dout, len);
|
||||
|
||||
/* write: set the data direction bit to 1 */
|
||||
value = readb(priv->base + OFFSET_SPIMCTRL);
|
||||
value |= (1 << 3);
|
||||
writeb(value, priv->base + OFFSET_SPIMCTRL);
|
||||
|
||||
/* set the data byte count */
|
||||
writeb(len, priv->base + OFFSET_SPIDCNT);
|
||||
|
||||
/* set the start bit */
|
||||
value = readb(priv->base + OFFSET_SPIMCTRL);
|
||||
value |= SPIMCTRL_START;
|
||||
writeb(value, priv->base + OFFSET_SPIMCTRL);
|
||||
|
||||
/* wait busy bit is cleared */
|
||||
do {
|
||||
value = readb(priv->base + OFFSET_SPIMCTRL);
|
||||
} while (value & SPIMCTRL_BUSY);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* if din !=null, start and read data */
|
||||
if (uchar_in) {
|
||||
read_ptr = 0;
|
||||
|
||||
while (read_ptr < len) {
|
||||
read_len = len - read_ptr;
|
||||
if (read_len > GXP_SPILDAT_SIZE)
|
||||
read_len = GXP_SPILDAT_SIZE;
|
||||
|
||||
/* read: set the data direction bit to 0 */
|
||||
value = readb(priv->base + OFFSET_SPIMCTRL);
|
||||
value &= ~(1 << 3);
|
||||
writeb(value, priv->base + OFFSET_SPIMCTRL);
|
||||
|
||||
/* set the data byte count */
|
||||
writeb(read_len, priv->base + OFFSET_SPIDCNT);
|
||||
|
||||
/* set the start bit */
|
||||
value = readb(priv->base + OFFSET_SPIMCTRL);
|
||||
value |= SPIMCTRL_START;
|
||||
writeb(value, priv->base + OFFSET_SPIMCTRL);
|
||||
|
||||
/* wait busy bit is cleared */
|
||||
do {
|
||||
value = readb(priv->base + OFFSET_SPIMCTRL);
|
||||
} while (value & SPIMCTRL_BUSY);
|
||||
|
||||
/* store the data bytes */
|
||||
memcpy(uchar_in + read_ptr, (u8 *)priv->base + OFFSET_SPILDAT, read_len);
|
||||
/* update read_ptr and addr reg */
|
||||
read_ptr += read_len;
|
||||
|
||||
addr = readl(priv->base + OFFSET_SPIADDR);
|
||||
addr += read_len;
|
||||
writel(addr, priv->base + OFFSET_SPIADDR);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
return -2;
|
||||
}
|
||||
|
||||
static int gxp_spi_set_speed(struct udevice *dev, unsigned int speed)
|
||||
{
|
||||
/* Accept any speed */
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int gxp_spi_set_mode(struct udevice *dev, unsigned int mode)
|
||||
{
|
||||
struct gxp_spi_priv *priv = dev_get_priv(dev->parent);
|
||||
|
||||
priv->mode = mode;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int gxp_spi_claim_bus(struct udevice *dev)
|
||||
{
|
||||
struct gxp_spi_priv *priv = dev_get_priv(dev->parent);
|
||||
unsigned char cmd;
|
||||
|
||||
spi_set_mode(priv, MANUAL_MODE);
|
||||
|
||||
/* exit 4 bytes addr mode, uboot spi_flash only supports 3 byets address mode */
|
||||
cmd = 0xe9;
|
||||
gxp_spi_xfer(dev, 1 * 8, &cmd, NULL, SPI_XFER_BEGIN | SPI_XFER_END);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int gxp_spi_release_bus(struct udevice *dev)
|
||||
{
|
||||
struct gxp_spi_priv *priv = dev_get_priv(dev->parent);
|
||||
|
||||
spi_set_mode(priv, AUTO_MODE);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int gxp_spi_cs_info(struct udevice *bus, unsigned int cs, struct spi_cs_info *info)
|
||||
{
|
||||
if (cs < GXP_SPI0_MAX_CHIPSELECT)
|
||||
return 0;
|
||||
else
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
static int gxp_spi_probe(struct udevice *bus)
|
||||
{
|
||||
struct gxp_spi_priv *priv = dev_get_priv(bus);
|
||||
|
||||
priv->base = dev_read_addr_ptr(bus);
|
||||
if (!priv->base)
|
||||
return -ENOENT;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int gxp_spi_child_pre_probe(struct udevice *dev)
|
||||
{
|
||||
struct spi_slave *slave = dev_get_parent_priv(dev);
|
||||
|
||||
slave->max_write_size = GXP_SPILDAT_SIZE;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct dm_spi_ops gxp_spi_ops = {
|
||||
.claim_bus = gxp_spi_claim_bus,
|
||||
.release_bus = gxp_spi_release_bus,
|
||||
.xfer = gxp_spi_xfer,
|
||||
.set_speed = gxp_spi_set_speed,
|
||||
.set_mode = gxp_spi_set_mode,
|
||||
.cs_info = gxp_spi_cs_info,
|
||||
};
|
||||
|
||||
static const struct udevice_id gxp_spi_ids[] = {
|
||||
{ .compatible = "hpe,gxp-spi" },
|
||||
{ }
|
||||
};
|
||||
|
||||
U_BOOT_DRIVER(gxp_spi) = {
|
||||
.name = "gxp_spi",
|
||||
.id = UCLASS_SPI,
|
||||
.of_match = gxp_spi_ids,
|
||||
.ops = &gxp_spi_ops,
|
||||
.priv_auto = sizeof(struct gxp_spi_priv),
|
||||
.probe = gxp_spi_probe,
|
||||
.child_pre_probe = gxp_spi_child_pre_probe,
|
||||
};
|
||||
|
@ -139,6 +139,13 @@ config DESIGNWARE_APB_TIMER
|
||||
Enables support for the Designware APB Timer driver. This timer is
|
||||
present on Altera SoCFPGA SoCs.
|
||||
|
||||
config GXP_TIMER
|
||||
bool "HPE GXP Timer"
|
||||
depends on TIMER
|
||||
help
|
||||
Enables support for the GXP Timer driver. This timer is
|
||||
present on HPE GXP SoCs.
|
||||
|
||||
config MPC83XX_TIMER
|
||||
bool "MPC83xx timer support"
|
||||
depends on TIMER
|
||||
|
@ -12,6 +12,7 @@ obj-$(CONFIG_$(SPL_)ATMEL_PIT_TIMER) += atmel_pit_timer.o
|
||||
obj-$(CONFIG_$(SPL_)ATMEL_TCB_TIMER) += atmel_tcb_timer.o
|
||||
obj-$(CONFIG_CADENCE_TTC_TIMER) += cadence-ttc.o
|
||||
obj-$(CONFIG_DESIGNWARE_APB_TIMER) += dw-apb-timer.o
|
||||
obj-$(CONFIG_GXP_TIMER) += gxp-timer.o
|
||||
obj-$(CONFIG_MPC83XX_TIMER) += mpc83xx_timer.o
|
||||
obj-$(CONFIG_NOMADIK_MTU_TIMER) += nomadik-mtu-timer.o
|
||||
obj-$(CONFIG_NPCM_TIMER) += npcm-timer.o
|
||||
|
64
drivers/timer/gxp-timer.c
Normal file
64
drivers/timer/gxp-timer.c
Normal file
@ -0,0 +1,64 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* GXP timer driver
|
||||
*
|
||||
* (C) Copyright 2022 Hewlett Packard Enterprise Development LP.
|
||||
* Author: Nick Hawkins <nick.hawkins@hpe.com>
|
||||
* Author: Jean-Marie Verdun <verdun@hpe.com>
|
||||
*/
|
||||
|
||||
#include <clk.h>
|
||||
#include <dm.h>
|
||||
#include <timer.h>
|
||||
#include <asm/io.h>
|
||||
|
||||
#define USTIMELO 0x18
|
||||
#define USTIMEHI 0x1C
|
||||
|
||||
struct gxp_timer_priv {
|
||||
void __iomem *base;
|
||||
};
|
||||
|
||||
static u64 gxp_timer_get_count(struct udevice *dev)
|
||||
{
|
||||
struct gxp_timer_priv *priv = dev_get_priv(dev);
|
||||
u64 val;
|
||||
|
||||
val = readl(priv->base + USTIMEHI);
|
||||
val = (val << 32) | readl(priv->base + USTIMELO);
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
static int gxp_timer_probe(struct udevice *dev)
|
||||
{
|
||||
struct timer_dev_priv *uc_priv = dev_get_uclass_priv(dev);
|
||||
struct gxp_timer_priv *priv = dev_get_priv(dev);
|
||||
|
||||
priv->base = dev_read_addr_ptr(dev);
|
||||
if (!priv->base)
|
||||
return -ENOENT;
|
||||
|
||||
uc_priv->clock_rate = 1000000;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct timer_ops gxp_timer_ops = {
|
||||
.get_count = gxp_timer_get_count,
|
||||
};
|
||||
|
||||
static const struct udevice_id gxp_timer_ids[] = {
|
||||
{ .compatible = "hpe,gxp-timer" },
|
||||
{}
|
||||
};
|
||||
|
||||
U_BOOT_DRIVER(gxp_timer) = {
|
||||
.name = "gxp-timer",
|
||||
.id = UCLASS_TIMER,
|
||||
.of_match = gxp_timer_ids,
|
||||
.priv_auto = sizeof(struct gxp_timer_priv),
|
||||
.probe = gxp_timer_probe,
|
||||
.ops = &gxp_timer_ops,
|
||||
.flags = DM_FLAG_PRE_RELOC,
|
||||
};
|
27
include/configs/corstone1000.h
Normal file
27
include/configs/corstone1000.h
Normal file
@ -0,0 +1,27 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0+ */
|
||||
/*
|
||||
* (C) Copyright 2022 ARM Limited
|
||||
* (C) Copyright 2022 Linaro
|
||||
* Rui Miguel Silva <rui.silva@linaro.org>
|
||||
* Abdellatif El Khlifi <abdellatif.elkhlifi@arm.com>
|
||||
*
|
||||
* Configuration for Corstone1000. Parts were derived from other ARM
|
||||
* configurations.
|
||||
*/
|
||||
|
||||
#ifndef __CORSTONE1000_H
|
||||
#define __CORSTONE1000_H
|
||||
|
||||
#include <linux/sizes.h>
|
||||
|
||||
#define V2M_BASE 0x80000000
|
||||
|
||||
#define CONFIG_PL011_CLOCK 50000000
|
||||
|
||||
/* Physical Memory Map */
|
||||
#define PHYS_SDRAM_1 (V2M_BASE)
|
||||
#define PHYS_SDRAM_1_SIZE 0x80000000
|
||||
|
||||
#define CONFIG_SYS_SDRAM_BASE PHYS_SDRAM_1
|
||||
|
||||
#endif
|
@ -14,17 +14,6 @@
|
||||
#ifndef __CONFIG_H
|
||||
#define __CONFIG_H
|
||||
|
||||
/* High Level Configuration Options */
|
||||
|
||||
/*
|
||||
* 1MB into the SDRAM to allow for SPL's bss at the beginning of SDRAM
|
||||
* 64 bytes before this address should be set aside for u-boot.img's
|
||||
* header. That is 0x800FFFC0--0x80100000 should not be used for any
|
||||
* other needs.
|
||||
*/
|
||||
|
||||
/* Physical Memory Map */
|
||||
|
||||
#include <configs/ti_omap3_common.h>
|
||||
|
||||
/* Hardware drivers */
|
||||
@ -40,9 +29,12 @@
|
||||
|
||||
/* BOOTP/DHCP options */
|
||||
|
||||
#define MEM_LAYOUT_ENV_SETTINGS \
|
||||
DEFAULT_LINUX_BOOT_ENV
|
||||
|
||||
/* Environment information */
|
||||
#define CONFIG_EXTRA_ENV_SETTINGS \
|
||||
"loadaddr=0x82000000\0" \
|
||||
MEM_LAYOUT_ENV_SETTINGS \
|
||||
"console=ttyO2,115200n8\0" \
|
||||
"mmcdev=0\0" \
|
||||
"vram=12M\0" \
|
||||
|
15
include/configs/gxp.h
Normal file
15
include/configs/gxp.h
Normal file
@ -0,0 +1,15 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0+ */
|
||||
/*
|
||||
* GXP board
|
||||
*
|
||||
* (C) Copyright 2022 Hewlett Packard Enterprise Development LP.
|
||||
* Author: Nick Hawkins <nick.hawkins@hpe.com>
|
||||
* Author: Jean-Marie Verdun <verdun@hpe.com>
|
||||
*/
|
||||
|
||||
#ifndef _GXP_H_
|
||||
#define _GXP_H_
|
||||
|
||||
#define CONFIG_SYS_SDRAM_BASE 0x40000000
|
||||
|
||||
#endif
|
@ -591,6 +591,8 @@ efi_status_t efi_load_pe(struct efi_loaded_image_obj *handle,
|
||||
void efi_save_gd(void);
|
||||
/* Call this to relocate the runtime section to an address space */
|
||||
void efi_runtime_relocate(ulong offset, struct efi_mem_desc *map);
|
||||
/* Call this to get image parameters */
|
||||
void efi_get_image_parameters(void **img_addr, size_t *img_size);
|
||||
/* Add a new object to the object list. */
|
||||
void efi_add_handle(efi_handle_t obj);
|
||||
/* Create handle */
|
||||
|
@ -39,6 +39,7 @@ int do_ut_compression(struct cmd_tbl *cmdtp, int flag, int argc,
|
||||
int do_ut_dm(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]);
|
||||
int do_ut_env(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]);
|
||||
int do_ut_lib(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]);
|
||||
int do_ut_loadm(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]);
|
||||
int do_ut_log(struct cmd_tbl *cmdtp, int flag, int argc, char * const argv[]);
|
||||
int do_ut_mem(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]);
|
||||
int do_ut_optee(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]);
|
||||
|
@ -1158,6 +1158,8 @@ efi_status_t efi_dp_from_name(const char *dev, const char *devnr,
|
||||
{
|
||||
struct blk_desc *desc = NULL;
|
||||
struct disk_partition fs_partition;
|
||||
size_t image_size;
|
||||
void *image_addr;
|
||||
int part = 0;
|
||||
char *filename;
|
||||
char *s;
|
||||
@ -1173,6 +1175,13 @@ efi_status_t efi_dp_from_name(const char *dev, const char *devnr,
|
||||
} else if (!strcmp(dev, "Uart")) {
|
||||
if (device)
|
||||
*device = efi_dp_from_uart();
|
||||
} else if (!strcmp(dev, "Mem")) {
|
||||
efi_get_image_parameters(&image_addr, &image_size);
|
||||
|
||||
if (device)
|
||||
*device = efi_dp_from_mem(EFI_RESERVED_MEMORY_TYPE,
|
||||
(uintptr_t)image_addr,
|
||||
image_size);
|
||||
} else {
|
||||
part = blk_get_device_part_str(dev, devnr, &desc, &fs_partition,
|
||||
1);
|
||||
|
@ -7,6 +7,7 @@ obj-$(CONFIG_CONSOLE_RECORD) += test_echo.o
|
||||
endif
|
||||
obj-y += mem.o
|
||||
obj-$(CONFIG_CMD_ADDRMAP) += addrmap.o
|
||||
obj-$(CONFIG_CMD_LOADM) += loadm.o
|
||||
obj-$(CONFIG_CMD_MEM_SEARCH) += mem_search.o
|
||||
obj-$(CONFIG_CMD_PINMUX) += pinmux.o
|
||||
obj-$(CONFIG_CMD_PWM) += pwm.o
|
||||
|
72
test/cmd/loadm.c
Normal file
72
test/cmd/loadm.c
Normal file
@ -0,0 +1,72 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Test for loadm command
|
||||
*
|
||||
* Copyright 2022 ARM Limited
|
||||
* Copyright 2022 Linaro
|
||||
*
|
||||
* Authors:
|
||||
* Rui Miguel Silva <rui.silva@linaro.org>
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <console.h>
|
||||
#include <mapmem.h>
|
||||
#include <asm/global_data.h>
|
||||
#include <dm/test.h>
|
||||
#include <test/suites.h>
|
||||
#include <test/test.h>
|
||||
#include <test/ut.h>
|
||||
|
||||
#define BUF_SIZE 0x100
|
||||
|
||||
#define LOADM_TEST(_name, _flags) UNIT_TEST(_name, _flags, loadm_test)
|
||||
|
||||
static int loadm_test_params(struct unit_test_state *uts)
|
||||
{
|
||||
ut_assertok(console_record_reset_enable());
|
||||
run_command("loadm", 0);
|
||||
ut_assert_nextline("loadm - load binary blob from source address to destination address");
|
||||
|
||||
ut_assertok(console_record_reset_enable());
|
||||
run_command("loadm 0x12345678", 0);
|
||||
ut_assert_nextline("loadm - load binary blob from source address to destination address");
|
||||
|
||||
ut_assertok(console_record_reset_enable());
|
||||
run_command("loadm 0x12345678 0x12345678", 0);
|
||||
ut_assert_nextline("loadm - load binary blob from source address to destination address");
|
||||
|
||||
ut_assertok(console_record_reset_enable());
|
||||
run_command("loadm 0x12345678 0x12345678 0", 0);
|
||||
ut_assert_nextline("loadm: can not load zero bytes");
|
||||
|
||||
return 0;
|
||||
}
|
||||
LOADM_TEST(loadm_test_params, UT_TESTF_CONSOLE_REC);
|
||||
|
||||
static int loadm_test_load (struct unit_test_state *uts)
|
||||
{
|
||||
char *buf;
|
||||
|
||||
buf = map_sysmem(0, BUF_SIZE);
|
||||
memset(buf, '\0', BUF_SIZE);
|
||||
memset(buf, 0xaa, BUF_SIZE / 2);
|
||||
|
||||
ut_assertok(console_record_reset_enable());
|
||||
run_command("loadm 0x0 0x80 0x80", 0);
|
||||
ut_assert_nextline("loaded bin to memory: size: 128");
|
||||
|
||||
unmap_sysmem(buf);
|
||||
|
||||
return 0;
|
||||
}
|
||||
LOADM_TEST(loadm_test_load, UT_TESTF_CONSOLE_REC);
|
||||
|
||||
int do_ut_loadm(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
|
||||
{
|
||||
struct unit_test *tests = UNIT_TEST_SUITE_START(loadm_test);
|
||||
const int n_ents = UNIT_TEST_SUITE_COUNT(loadm_test);
|
||||
|
||||
return cmd_ut_category("loadm", "loadm_test_", tests, n_ents, argc,
|
||||
argv);
|
||||
}
|
@ -74,6 +74,9 @@ static struct cmd_tbl cmd_ut_sub[] = {
|
||||
#ifdef CONFIG_CMD_ADDRMAP
|
||||
U_BOOT_CMD_MKENT(addrmap, CONFIG_SYS_MAXARGS, 1, do_ut_addrmap, "", ""),
|
||||
#endif
|
||||
#ifdef CONFIG_CMD_LOADM
|
||||
U_BOOT_CMD_MKENT(loadm, CONFIG_SYS_MAXARGS, 1, do_ut_loadm, "", ""),
|
||||
#endif
|
||||
};
|
||||
|
||||
static int do_ut_all(struct cmd_tbl *cmdtp, int flag, int argc,
|
||||
@ -155,6 +158,9 @@ static char ut_help_text[] =
|
||||
#endif
|
||||
#ifdef CONFIG_CMD_ADDRMAP
|
||||
"ut addrmap - Very basic test of addrmap command\n"
|
||||
#endif
|
||||
#ifdef CONFIG_CMD_LOADM
|
||||
"ut loadm [test-name]- test of parameters and load memory blob\n"
|
||||
#endif
|
||||
;
|
||||
#endif /* CONFIG_SYS_LONGHELP */
|
||||
|
Loading…
Reference in New Issue
Block a user