mirror of
https://github.com/smaeul/u-boot.git
synced 2025-10-14 04:46:01 +01:00
- mvebu: Move PCIe code from serdes to PCIe driver (Pali) - mtd: nand: pxa3xx: use marvell, prefix for custom DT properties (Pierre) - Add PCIe support for Iomega iConnect board (Tony) - ddr: marvell: a38x: Misc improvements / fixes (Marek) - tools: kwbimage: Load address fixes (Pali) - mvebu: db-88f6720: Fix CONFIG_SPL_TEXT_BASE and remove wrong memory layout (Pali) - mvebu: Replace hardcoded values 0x0030/0x4030 by proper calculation (Pali)
This commit is contained in:
commit
9b72d934c2
@ -384,9 +384,10 @@
|
|||||||
interrupts = <GIC_SPI 62 IRQ_TYPE_LEVEL_HIGH>;
|
interrupts = <GIC_SPI 62 IRQ_TYPE_LEVEL_HIGH>;
|
||||||
};
|
};
|
||||||
|
|
||||||
system-controller@18200 {
|
systemc: system-controller@18200 {
|
||||||
compatible = "marvell,armada-375-system-controller";
|
compatible = "marvell,armada-375-system-controller";
|
||||||
reg = <0x18200 0x100>;
|
reg = <0x18200 0x100>;
|
||||||
|
#reset-cells = <2>;
|
||||||
};
|
};
|
||||||
|
|
||||||
gateclk: clock-gating-control@18220 {
|
gateclk: clock-gating-control@18220 {
|
||||||
@ -616,6 +617,7 @@
|
|||||||
marvell,pcie-port = <0>;
|
marvell,pcie-port = <0>;
|
||||||
marvell,pcie-lane = <0>;
|
marvell,pcie-lane = <0>;
|
||||||
clocks = <&gateclk 5>;
|
clocks = <&gateclk 5>;
|
||||||
|
resets = <&systemc 0 0>;
|
||||||
status = "disabled";
|
status = "disabled";
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -634,6 +636,7 @@
|
|||||||
marvell,pcie-port = <0>;
|
marvell,pcie-port = <0>;
|
||||||
marvell,pcie-lane = <1>;
|
marvell,pcie-lane = <1>;
|
||||||
clocks = <&gateclk 6>;
|
clocks = <&gateclk 6>;
|
||||||
|
resets = <&systemc 0 1>;
|
||||||
status = "disabled";
|
status = "disabled";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -73,6 +73,7 @@
|
|||||||
marvell,pcie-port = <0>;
|
marvell,pcie-port = <0>;
|
||||||
marvell,pcie-lane = <0>;
|
marvell,pcie-lane = <0>;
|
||||||
clocks = <&gateclk 8>;
|
clocks = <&gateclk 8>;
|
||||||
|
resets = <&systemc 0 0>;
|
||||||
status = "disabled";
|
status = "disabled";
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -92,6 +93,7 @@
|
|||||||
marvell,pcie-port = <1>;
|
marvell,pcie-port = <1>;
|
||||||
marvell,pcie-lane = <0>;
|
marvell,pcie-lane = <0>;
|
||||||
clocks = <&gateclk 5>;
|
clocks = <&gateclk 5>;
|
||||||
|
resets = <&systemc 0 1>;
|
||||||
status = "disabled";
|
status = "disabled";
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -111,6 +113,7 @@
|
|||||||
marvell,pcie-port = <2>;
|
marvell,pcie-port = <2>;
|
||||||
marvell,pcie-lane = <0>;
|
marvell,pcie-lane = <0>;
|
||||||
clocks = <&gateclk 6>;
|
clocks = <&gateclk 6>;
|
||||||
|
resets = <&systemc 0 2>;
|
||||||
status = "disabled";
|
status = "disabled";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
@ -78,6 +78,7 @@
|
|||||||
marvell,pcie-port = <0>;
|
marvell,pcie-port = <0>;
|
||||||
marvell,pcie-lane = <0>;
|
marvell,pcie-lane = <0>;
|
||||||
clocks = <&gateclk 8>;
|
clocks = <&gateclk 8>;
|
||||||
|
resets = <&systemc 0 0>;
|
||||||
status = "disabled";
|
status = "disabled";
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -97,6 +98,7 @@
|
|||||||
marvell,pcie-port = <1>;
|
marvell,pcie-port = <1>;
|
||||||
marvell,pcie-lane = <0>;
|
marvell,pcie-lane = <0>;
|
||||||
clocks = <&gateclk 5>;
|
clocks = <&gateclk 5>;
|
||||||
|
resets = <&systemc 0 1>;
|
||||||
status = "disabled";
|
status = "disabled";
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -116,6 +118,7 @@
|
|||||||
marvell,pcie-port = <2>;
|
marvell,pcie-port = <2>;
|
||||||
marvell,pcie-lane = <0>;
|
marvell,pcie-lane = <0>;
|
||||||
clocks = <&gateclk 6>;
|
clocks = <&gateclk 6>;
|
||||||
|
resets = <&systemc 0 2>;
|
||||||
status = "disabled";
|
status = "disabled";
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -138,6 +141,7 @@
|
|||||||
marvell,pcie-port = <3>;
|
marvell,pcie-port = <3>;
|
||||||
marvell,pcie-lane = <0>;
|
marvell,pcie-lane = <0>;
|
||||||
clocks = <&gateclk 7>;
|
clocks = <&gateclk 7>;
|
||||||
|
resets = <&systemc 0 3>;
|
||||||
status = "disabled";
|
status = "disabled";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
@ -328,6 +328,7 @@
|
|||||||
compatible = "marvell,armada-380-system-controller",
|
compatible = "marvell,armada-380-system-controller",
|
||||||
"marvell,armada-370-xp-system-controller";
|
"marvell,armada-370-xp-system-controller";
|
||||||
reg = <0x18200 0x100>;
|
reg = <0x18200 0x100>;
|
||||||
|
#reset-cells = <2>;
|
||||||
};
|
};
|
||||||
|
|
||||||
gateclk: clock-gating-control@18220 {
|
gateclk: clock-gating-control@18220 {
|
||||||
|
@ -231,7 +231,7 @@
|
|||||||
#address-cells = <1>;
|
#address-cells = <1>;
|
||||||
#size-cells = <0>;
|
#size-cells = <0>;
|
||||||
clocks = <&CP110_LABEL(syscon0) 1 2>;
|
clocks = <&CP110_LABEL(syscon0) 1 2>;
|
||||||
nand-enable-arbiter;
|
marvell,nand-enable-arbiter;
|
||||||
num-cs = <1>;
|
num-cs = <1>;
|
||||||
nand-ecc-strength = <8>;
|
nand-ecc-strength = <8>;
|
||||||
nand-ecc-step-size = <512>;
|
nand-ecc-step-size = <512>;
|
||||||
|
@ -85,6 +85,7 @@
|
|||||||
marvell,pcie-port = <0>;
|
marvell,pcie-port = <0>;
|
||||||
marvell,pcie-lane = <0>;
|
marvell,pcie-lane = <0>;
|
||||||
clocks = <&gateclk 5>;
|
clocks = <&gateclk 5>;
|
||||||
|
resets = <&systemc 0 0>;
|
||||||
status = "disabled";
|
status = "disabled";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
@ -136,6 +137,7 @@
|
|||||||
systemc: system-controller@18200 {
|
systemc: system-controller@18200 {
|
||||||
compatible = "marvell,armada-370-xp-system-controller";
|
compatible = "marvell,armada-370-xp-system-controller";
|
||||||
reg = <0x18200 0x500>;
|
reg = <0x18200 0x500>;
|
||||||
|
#reset-cells = <2>;
|
||||||
};
|
};
|
||||||
|
|
||||||
gateclk: clock-gating-control@18220 {
|
gateclk: clock-gating-control@18220 {
|
||||||
|
@ -92,6 +92,7 @@
|
|||||||
marvell,pcie-port = <0>;
|
marvell,pcie-port = <0>;
|
||||||
marvell,pcie-lane = <0>;
|
marvell,pcie-lane = <0>;
|
||||||
clocks = <&gateclk 5>;
|
clocks = <&gateclk 5>;
|
||||||
|
resets = <&systemc 0 0>;
|
||||||
status = "disabled";
|
status = "disabled";
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -110,6 +111,7 @@
|
|||||||
marvell,pcie-port = <0>;
|
marvell,pcie-port = <0>;
|
||||||
marvell,pcie-lane = <1>;
|
marvell,pcie-lane = <1>;
|
||||||
clocks = <&gateclk 6>;
|
clocks = <&gateclk 6>;
|
||||||
|
resets = <&systemc 0 0>;
|
||||||
status = "disabled";
|
status = "disabled";
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -128,6 +130,7 @@
|
|||||||
marvell,pcie-port = <0>;
|
marvell,pcie-port = <0>;
|
||||||
marvell,pcie-lane = <2>;
|
marvell,pcie-lane = <2>;
|
||||||
clocks = <&gateclk 7>;
|
clocks = <&gateclk 7>;
|
||||||
|
resets = <&systemc 0 0>;
|
||||||
status = "disabled";
|
status = "disabled";
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -146,6 +149,7 @@
|
|||||||
marvell,pcie-port = <0>;
|
marvell,pcie-port = <0>;
|
||||||
marvell,pcie-lane = <3>;
|
marvell,pcie-lane = <3>;
|
||||||
clocks = <&gateclk 8>;
|
clocks = <&gateclk 8>;
|
||||||
|
resets = <&systemc 0 0>;
|
||||||
status = "disabled";
|
status = "disabled";
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -164,6 +168,7 @@
|
|||||||
marvell,pcie-port = <1>;
|
marvell,pcie-port = <1>;
|
||||||
marvell,pcie-lane = <0>;
|
marvell,pcie-lane = <0>;
|
||||||
clocks = <&gateclk 9>;
|
clocks = <&gateclk 9>;
|
||||||
|
resets = <&systemc 0 1>;
|
||||||
status = "disabled";
|
status = "disabled";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
@ -107,6 +107,7 @@
|
|||||||
marvell,pcie-port = <0>;
|
marvell,pcie-port = <0>;
|
||||||
marvell,pcie-lane = <0>;
|
marvell,pcie-lane = <0>;
|
||||||
clocks = <&gateclk 5>;
|
clocks = <&gateclk 5>;
|
||||||
|
resets = <&systemc 0 0>;
|
||||||
status = "disabled";
|
status = "disabled";
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -125,6 +126,7 @@
|
|||||||
marvell,pcie-port = <0>;
|
marvell,pcie-port = <0>;
|
||||||
marvell,pcie-lane = <1>;
|
marvell,pcie-lane = <1>;
|
||||||
clocks = <&gateclk 6>;
|
clocks = <&gateclk 6>;
|
||||||
|
resets = <&systemc 0 0>;
|
||||||
status = "disabled";
|
status = "disabled";
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -143,6 +145,7 @@
|
|||||||
marvell,pcie-port = <0>;
|
marvell,pcie-port = <0>;
|
||||||
marvell,pcie-lane = <2>;
|
marvell,pcie-lane = <2>;
|
||||||
clocks = <&gateclk 7>;
|
clocks = <&gateclk 7>;
|
||||||
|
resets = <&systemc 0 0>;
|
||||||
status = "disabled";
|
status = "disabled";
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -161,6 +164,7 @@
|
|||||||
marvell,pcie-port = <0>;
|
marvell,pcie-port = <0>;
|
||||||
marvell,pcie-lane = <3>;
|
marvell,pcie-lane = <3>;
|
||||||
clocks = <&gateclk 8>;
|
clocks = <&gateclk 8>;
|
||||||
|
resets = <&systemc 0 0>;
|
||||||
status = "disabled";
|
status = "disabled";
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -179,6 +183,7 @@
|
|||||||
marvell,pcie-port = <1>;
|
marvell,pcie-port = <1>;
|
||||||
marvell,pcie-lane = <0>;
|
marvell,pcie-lane = <0>;
|
||||||
clocks = <&gateclk 9>;
|
clocks = <&gateclk 9>;
|
||||||
|
resets = <&systemc 0 1>;
|
||||||
status = "disabled";
|
status = "disabled";
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -197,6 +202,7 @@
|
|||||||
marvell,pcie-port = <1>;
|
marvell,pcie-port = <1>;
|
||||||
marvell,pcie-lane = <1>;
|
marvell,pcie-lane = <1>;
|
||||||
clocks = <&gateclk 10>;
|
clocks = <&gateclk 10>;
|
||||||
|
resets = <&systemc 0 1>;
|
||||||
status = "disabled";
|
status = "disabled";
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -215,6 +221,7 @@
|
|||||||
marvell,pcie-port = <1>;
|
marvell,pcie-port = <1>;
|
||||||
marvell,pcie-lane = <2>;
|
marvell,pcie-lane = <2>;
|
||||||
clocks = <&gateclk 11>;
|
clocks = <&gateclk 11>;
|
||||||
|
resets = <&systemc 0 1>;
|
||||||
status = "disabled";
|
status = "disabled";
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -233,6 +240,7 @@
|
|||||||
marvell,pcie-port = <1>;
|
marvell,pcie-port = <1>;
|
||||||
marvell,pcie-lane = <3>;
|
marvell,pcie-lane = <3>;
|
||||||
clocks = <&gateclk 12>;
|
clocks = <&gateclk 12>;
|
||||||
|
resets = <&systemc 0 1>;
|
||||||
status = "disabled";
|
status = "disabled";
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -251,6 +259,7 @@
|
|||||||
marvell,pcie-port = <2>;
|
marvell,pcie-port = <2>;
|
||||||
marvell,pcie-lane = <0>;
|
marvell,pcie-lane = <0>;
|
||||||
clocks = <&gateclk 26>;
|
clocks = <&gateclk 26>;
|
||||||
|
resets = <&systemc 0 2>;
|
||||||
status = "disabled";
|
status = "disabled";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
@ -128,6 +128,7 @@
|
|||||||
marvell,pcie-port = <0>;
|
marvell,pcie-port = <0>;
|
||||||
marvell,pcie-lane = <0>;
|
marvell,pcie-lane = <0>;
|
||||||
clocks = <&gateclk 5>;
|
clocks = <&gateclk 5>;
|
||||||
|
resets = <&systemc 0 0>;
|
||||||
status = "disabled";
|
status = "disabled";
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -146,6 +147,7 @@
|
|||||||
marvell,pcie-port = <0>;
|
marvell,pcie-port = <0>;
|
||||||
marvell,pcie-lane = <1>;
|
marvell,pcie-lane = <1>;
|
||||||
clocks = <&gateclk 6>;
|
clocks = <&gateclk 6>;
|
||||||
|
resets = <&systemc 0 0>;
|
||||||
status = "disabled";
|
status = "disabled";
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -164,6 +166,7 @@
|
|||||||
marvell,pcie-port = <0>;
|
marvell,pcie-port = <0>;
|
||||||
marvell,pcie-lane = <2>;
|
marvell,pcie-lane = <2>;
|
||||||
clocks = <&gateclk 7>;
|
clocks = <&gateclk 7>;
|
||||||
|
resets = <&systemc 0 0>;
|
||||||
status = "disabled";
|
status = "disabled";
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -182,6 +185,7 @@
|
|||||||
marvell,pcie-port = <0>;
|
marvell,pcie-port = <0>;
|
||||||
marvell,pcie-lane = <3>;
|
marvell,pcie-lane = <3>;
|
||||||
clocks = <&gateclk 8>;
|
clocks = <&gateclk 8>;
|
||||||
|
resets = <&systemc 0 0>;
|
||||||
status = "disabled";
|
status = "disabled";
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -200,6 +204,7 @@
|
|||||||
marvell,pcie-port = <1>;
|
marvell,pcie-port = <1>;
|
||||||
marvell,pcie-lane = <0>;
|
marvell,pcie-lane = <0>;
|
||||||
clocks = <&gateclk 9>;
|
clocks = <&gateclk 9>;
|
||||||
|
resets = <&systemc 0 1>;
|
||||||
status = "disabled";
|
status = "disabled";
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -218,6 +223,7 @@
|
|||||||
marvell,pcie-port = <1>;
|
marvell,pcie-port = <1>;
|
||||||
marvell,pcie-lane = <1>;
|
marvell,pcie-lane = <1>;
|
||||||
clocks = <&gateclk 10>;
|
clocks = <&gateclk 10>;
|
||||||
|
resets = <&systemc 0 1>;
|
||||||
status = "disabled";
|
status = "disabled";
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -236,6 +242,7 @@
|
|||||||
marvell,pcie-port = <1>;
|
marvell,pcie-port = <1>;
|
||||||
marvell,pcie-lane = <2>;
|
marvell,pcie-lane = <2>;
|
||||||
clocks = <&gateclk 11>;
|
clocks = <&gateclk 11>;
|
||||||
|
resets = <&systemc 0 1>;
|
||||||
status = "disabled";
|
status = "disabled";
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -254,6 +261,7 @@
|
|||||||
marvell,pcie-port = <1>;
|
marvell,pcie-port = <1>;
|
||||||
marvell,pcie-lane = <3>;
|
marvell,pcie-lane = <3>;
|
||||||
clocks = <&gateclk 12>;
|
clocks = <&gateclk 12>;
|
||||||
|
resets = <&systemc 0 1>;
|
||||||
status = "disabled";
|
status = "disabled";
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -272,6 +280,7 @@
|
|||||||
marvell,pcie-port = <2>;
|
marvell,pcie-port = <2>;
|
||||||
marvell,pcie-lane = <0>;
|
marvell,pcie-lane = <0>;
|
||||||
clocks = <&gateclk 26>;
|
clocks = <&gateclk 26>;
|
||||||
|
resets = <&systemc 0 2>;
|
||||||
status = "disabled";
|
status = "disabled";
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -290,6 +299,7 @@
|
|||||||
marvell,pcie-port = <3>;
|
marvell,pcie-port = <3>;
|
||||||
marvell,pcie-lane = <0>;
|
marvell,pcie-lane = <0>;
|
||||||
clocks = <&gateclk 27>;
|
clocks = <&gateclk 27>;
|
||||||
|
resets = <&systemc 0 3>;
|
||||||
status = "disabled";
|
status = "disabled";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
@ -187,6 +187,7 @@
|
|||||||
pcie@1,0 {
|
pcie@1,0 {
|
||||||
/* Port 0, Lane 0 */
|
/* Port 0, Lane 0 */
|
||||||
status = "okay";
|
status = "okay";
|
||||||
|
num-lanes = <4>;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -214,5 +214,6 @@
|
|||||||
pcie@9,0 {
|
pcie@9,0 {
|
||||||
/* Port 2, Lane 0 */
|
/* Port 2, Lane 0 */
|
||||||
status = "okay";
|
status = "okay";
|
||||||
|
num-lanes = <4>;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
@ -78,6 +78,7 @@
|
|||||||
systemc: system-controller@18200 {
|
systemc: system-controller@18200 {
|
||||||
compatible = "marvell,armada-370-xp-system-controller";
|
compatible = "marvell,armada-370-xp-system-controller";
|
||||||
reg = <0x18200 0x500>;
|
reg = <0x18200 0x500>;
|
||||||
|
#reset-cells = <2>;
|
||||||
};
|
};
|
||||||
|
|
||||||
gateclk: clock-gating-control@18220 {
|
gateclk: clock-gating-control@18220 {
|
||||||
|
@ -21,6 +21,7 @@ else # CONFIG_ARCH_KIRKWOOD
|
|||||||
|
|
||||||
obj-y = cpu.o
|
obj-y = cpu.o
|
||||||
obj-y += dram.o
|
obj-y += dram.o
|
||||||
|
obj-$(CONFIG_DM_RESET) += system-controller.o
|
||||||
ifndef CONFIG_SPL_BUILD
|
ifndef CONFIG_SPL_BUILD
|
||||||
obj-$(CONFIG_ARMADA_375) += ../../../drivers/ddr/marvell/axp/xor.o
|
obj-$(CONFIG_ARMADA_375) += ../../../drivers/ddr/marvell/axp/xor.o
|
||||||
obj-$(CONFIG_ARMADA_38X) += ../../../drivers/ddr/marvell/a38x/xor.o
|
obj-$(CONFIG_ARMADA_38X) += ../../../drivers/ddr/marvell/a38x/xor.o
|
||||||
@ -30,6 +31,17 @@ obj-$(CONFIG_MVEBU_EFUSE) += efuse.o
|
|||||||
|
|
||||||
extra-y += kwbimage.cfg
|
extra-y += kwbimage.cfg
|
||||||
|
|
||||||
|
ifneq ($(CONFIG_ARMADA_370)$(CONFIG_ARMADA_XP),)
|
||||||
|
KWB_REPLACE += CPU
|
||||||
|
KWB_CFG_CPU = SHEEVA
|
||||||
|
else ifneq ($(CONFIG_ARMADA_375)$(CONFIG_ARMADA_38X)$(CONFIG_ARMADA_39X),)
|
||||||
|
KWB_REPLACE += CPU
|
||||||
|
KWB_CFG_CPU = A9
|
||||||
|
endif
|
||||||
|
|
||||||
|
KWB_REPLACE += LOAD_ADDRESS
|
||||||
|
KWB_CFG_LOAD_ADDRESS = $(CONFIG_SPL_TEXT_BASE)
|
||||||
|
|
||||||
KWB_REPLACE += BOOT_FROM
|
KWB_REPLACE += BOOT_FROM
|
||||||
ifneq ($(CONFIG_MVEBU_SPL_BOOT_DEVICE_SPI),)
|
ifneq ($(CONFIG_MVEBU_SPL_BOOT_DEVICE_SPI),)
|
||||||
KWB_CFG_BOOT_FROM=spi
|
KWB_CFG_BOOT_FROM=spi
|
||||||
@ -58,10 +70,20 @@ KWB_REPLACE += SEC_FUSE_DUMP
|
|||||||
KWB_CFG_SEC_FUSE_DUMP = a38x
|
KWB_CFG_SEC_FUSE_DUMP = a38x
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
ifdef CONFIG_ARMADA_38X
|
||||||
|
# BootROM output is by default enabled on pre-A38x and disabled on A38x
|
||||||
|
# DEBUG flag on A38x for non-UART boot source only enable BootROM output and nothing more
|
||||||
|
KWB_REPLACE += DEBUG
|
||||||
|
KWB_CFG_DEBUG = 1
|
||||||
|
endif
|
||||||
|
|
||||||
|
quiet_cmd_kwbcfg = KWBCFG $@
|
||||||
|
cmd_kwbcfg = sed -ne '$(foreach V,$(KWB_REPLACE),s/\#@$(V)/$(V) $(KWB_CFG_$(V))/;)p' \
|
||||||
|
<$< >$(dir $@)$(@F)
|
||||||
|
|
||||||
$(obj)/kwbimage.cfg: $(src)/kwbimage.cfg.in include/autoconf.mk \
|
$(obj)/kwbimage.cfg: $(src)/kwbimage.cfg.in include/autoconf.mk \
|
||||||
include/config/auto.conf
|
include/config/auto.conf
|
||||||
$(Q)sed -ne '$(foreach V,$(KWB_REPLACE),s/^#@$(V)/$(V) $(KWB_CFG_$(V))/;)p' \
|
$(call cmd,kwbcfg)
|
||||||
<$< >$(dir $@)$(@F)
|
|
||||||
|
|
||||||
endif # CONFIG_SPL_BUILD
|
endif # CONFIG_SPL_BUILD
|
||||||
obj-y += gpio.o
|
obj-y += gpio.o
|
||||||
|
@ -74,10 +74,11 @@ enum {
|
|||||||
/*
|
/*
|
||||||
* Default Device Address MAP BAR values
|
* Default Device Address MAP BAR values
|
||||||
*/
|
*/
|
||||||
|
#define MBUS_PCI_MAX_PORTS 6
|
||||||
#define MBUS_PCI_MEM_BASE MVEBU_SDRAM_SIZE_MAX
|
#define MBUS_PCI_MEM_BASE MVEBU_SDRAM_SIZE_MAX
|
||||||
#define MBUS_PCI_MEM_SIZE (128 << 20)
|
#define MBUS_PCI_MEM_SIZE ((MBUS_PCI_MAX_PORTS * 128) << 20)
|
||||||
#define MBUS_PCI_IO_BASE 0xF1100000
|
#define MBUS_PCI_IO_BASE 0xF1100000
|
||||||
#define MBUS_PCI_IO_SIZE (64 << 10)
|
#define MBUS_PCI_IO_SIZE ((MBUS_PCI_MAX_PORTS * 64) << 10)
|
||||||
#define MBUS_SPI_BASE 0xF4000000
|
#define MBUS_SPI_BASE 0xF4000000
|
||||||
#define MBUS_SPI_SIZE (8 << 20)
|
#define MBUS_SPI_SIZE (8 << 20)
|
||||||
#define MBUS_DFX_BASE 0xF6000000
|
#define MBUS_DFX_BASE 0xF6000000
|
||||||
|
@ -5,8 +5,14 @@
|
|||||||
# Armada 38x uses version 1 image format
|
# Armada 38x uses version 1 image format
|
||||||
VERSION 1
|
VERSION 1
|
||||||
|
|
||||||
|
# Type of the CPU core
|
||||||
|
#@CPU
|
||||||
|
|
||||||
# Boot Media configurations
|
# Boot Media configurations
|
||||||
#@BOOT_FROM
|
#@BOOT_FROM
|
||||||
|
|
||||||
# Binary Header (bin_hdr) with DDR3 training code
|
# Enable BootROM output via DEBUG flag on SoCs which require it
|
||||||
BINARY spl/u-boot-spl.bin
|
#@DEBUG
|
||||||
|
|
||||||
|
# Include U-Boot SPL with DDR3 training code into Binary Header
|
||||||
|
BINARY spl/u-boot-spl.bin #@LOAD_ADDRESS
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
# SPDX-License-Identifier: GPL-2.0+
|
# SPDX-License-Identifier: GPL-2.0+
|
||||||
|
|
||||||
obj-$(CONFIG_SPL_BUILD) = ctrl_pex.o
|
|
||||||
obj-$(CONFIG_SPL_BUILD) += high_speed_env_spec.o
|
obj-$(CONFIG_SPL_BUILD) += high_speed_env_spec.o
|
||||||
obj-$(CONFIG_SPL_BUILD) += high_speed_env_spec-38x.o
|
obj-$(CONFIG_SPL_BUILD) += high_speed_env_spec-38x.o
|
||||||
obj-$(CONFIG_SPL_BUILD) += seq_exec.o
|
obj-$(CONFIG_SPL_BUILD) += seq_exec.o
|
||||||
|
@ -1,64 +0,0 @@
|
|||||||
// SPDX-License-Identifier: GPL-2.0
|
|
||||||
/*
|
|
||||||
* Copyright (C) Marvell International Ltd. and its affiliates
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <common.h>
|
|
||||||
#include <spl.h>
|
|
||||||
#include <asm/io.h>
|
|
||||||
#include <asm/arch/cpu.h>
|
|
||||||
#include <asm/arch/soc.h>
|
|
||||||
#include <linux/bitops.h>
|
|
||||||
#include <linux/delay.h>
|
|
||||||
|
|
||||||
#include "ctrl_pex.h"
|
|
||||||
#include "sys_env_lib.h"
|
|
||||||
|
|
||||||
__weak void board_pex_config(void)
|
|
||||||
{
|
|
||||||
/* nothing in this weak default implementation */
|
|
||||||
}
|
|
||||||
|
|
||||||
int hws_pex_config(const struct serdes_map *serdes_map, u8 count)
|
|
||||||
{
|
|
||||||
enum serdes_type serdes_type;
|
|
||||||
u32 idx, tmp;
|
|
||||||
|
|
||||||
DEBUG_INIT_FULL_S("\n### hws_pex_config ###\n");
|
|
||||||
|
|
||||||
tmp = reg_read(SOC_CONTROL_REG1);
|
|
||||||
tmp &= ~0x03;
|
|
||||||
|
|
||||||
for (idx = 0; idx < count; idx++) {
|
|
||||||
serdes_type = serdes_map[idx].serdes_type;
|
|
||||||
if ((serdes_type != PEX0) &&
|
|
||||||
((serdes_map[idx].serdes_mode == PEX_ROOT_COMPLEX_X4) ||
|
|
||||||
(serdes_map[idx].serdes_mode == PEX_END_POINT_X4))) {
|
|
||||||
/* for PEX by4 - relevant for the first port only */
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (serdes_type) {
|
|
||||||
case PEX0:
|
|
||||||
tmp |= 0x1 << PCIE0_ENABLE_OFFS;
|
|
||||||
break;
|
|
||||||
case PEX1:
|
|
||||||
tmp |= 0x1 << PCIE1_ENABLE_OFFS;
|
|
||||||
break;
|
|
||||||
case PEX2:
|
|
||||||
tmp |= 0x1 << PCIE2_ENABLE_OFFS;
|
|
||||||
break;
|
|
||||||
case PEX3:
|
|
||||||
tmp |= 0x1 << PCIE3_ENABLE_OFFS;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
reg_write(SOC_CONTROL_REG1, tmp);
|
|
||||||
|
|
||||||
board_pex_config();
|
|
||||||
|
|
||||||
return MV_OK;
|
|
||||||
}
|
|
@ -1,28 +0,0 @@
|
|||||||
/* SPDX-License-Identifier: GPL-2.0 */
|
|
||||||
/*
|
|
||||||
* Copyright (C) Marvell International Ltd. and its affiliates
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef _CTRL_PEX_H
|
|
||||||
#define _CTRL_PEX_H
|
|
||||||
|
|
||||||
#include <pci.h>
|
|
||||||
#include "high_speed_env_spec.h"
|
|
||||||
|
|
||||||
/* Direct access to PEX0 Root Port's PCIe Capability structure */
|
|
||||||
#define PEX0_RP_PCIE_CFG_OFFSET (0x00080000 + 0x60)
|
|
||||||
|
|
||||||
/* SOC_CONTROL_REG1 fields */
|
|
||||||
#define PCIE0_ENABLE_OFFS 0
|
|
||||||
#define PCIE0_ENABLE_MASK (0x1 << PCIE0_ENABLE_OFFS)
|
|
||||||
#define PCIE1_ENABLE_OFFS 1
|
|
||||||
#define PCIE1_ENABLE_MASK (0x1 << PCIE1_ENABLE_OFFS)
|
|
||||||
#define PCIE2_ENABLE_OFFS 2
|
|
||||||
#define PCIE2_ENABLE_MASK (0x1 << PCIE2_ENABLE_OFFS)
|
|
||||||
#define PCIE3_ENABLE_OFFS 3
|
|
||||||
#define PCIE4_ENABLE_MASK (0x1 << PCIE3_ENABLE_OFFS)
|
|
||||||
|
|
||||||
int hws_pex_config(const struct serdes_map *serdes_map, u8 count);
|
|
||||||
void board_pex_config(void);
|
|
||||||
|
|
||||||
#endif
|
|
@ -12,7 +12,6 @@
|
|||||||
|
|
||||||
#include "high_speed_env_spec.h"
|
#include "high_speed_env_spec.h"
|
||||||
#include "sys_env_lib.h"
|
#include "sys_env_lib.h"
|
||||||
#include "ctrl_pex.h"
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* serdes_seq_db - holds all serdes sequences, their size and the
|
* serdes_seq_db - holds all serdes sequences, their size and the
|
||||||
@ -1555,9 +1554,6 @@ int hws_power_up_serdes_lanes(struct serdes_map *serdes_map, u8 count)
|
|||||||
After finish the Power_up sequence for all lanes,
|
After finish the Power_up sequence for all lanes,
|
||||||
the lanes should be released from reset state. */
|
the lanes should be released from reset state. */
|
||||||
CHECK_STATUS(hws_pex_tx_config_seq(serdes_map, count));
|
CHECK_STATUS(hws_pex_tx_config_seq(serdes_map, count));
|
||||||
|
|
||||||
/* PEX configuration */
|
|
||||||
CHECK_STATUS(hws_pex_config(serdes_map, count));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* USB2 configuration */
|
/* USB2 configuration */
|
||||||
@ -1743,21 +1739,6 @@ int serdes_power_up_ctrl(u32 serdes_num, int serdes_power_up,
|
|||||||
else
|
else
|
||||||
reg_data &= ~0x4000;
|
reg_data &= ~0x4000;
|
||||||
reg_write(SOC_CONTROL_REG1, reg_data);
|
reg_write(SOC_CONTROL_REG1, reg_data);
|
||||||
|
|
||||||
/*
|
|
||||||
* Set Maximum Link Width to X1 or X4 in Root
|
|
||||||
* Port's PCIe Link Capability register.
|
|
||||||
* This register is read-only but if is not set
|
|
||||||
* correctly then access to PCI config space of
|
|
||||||
* endpoint card behind this Root Port does not
|
|
||||||
* work.
|
|
||||||
*/
|
|
||||||
reg_data = reg_read(PEX0_RP_PCIE_CFG_OFFSET +
|
|
||||||
PCI_EXP_LNKCAP);
|
|
||||||
reg_data &= ~PCI_EXP_LNKCAP_MLW;
|
|
||||||
reg_data |= (is_pex_by1 ? 1 : 4) << 4;
|
|
||||||
reg_write(PEX0_RP_PCIE_CFG_OFFSET +
|
|
||||||
PCI_EXP_LNKCAP, reg_data);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CHECK_STATUS(mv_seq_exec(serdes_num, PEX_POWER_UP_SEQ));
|
CHECK_STATUS(mv_seq_exec(serdes_num, PEX_POWER_UP_SEQ));
|
||||||
|
105
arch/arm/mach-mvebu/system-controller.c
Normal file
105
arch/arm/mach-mvebu/system-controller.c
Normal file
@ -0,0 +1,105 @@
|
|||||||
|
// SPDX-License-Identifier: GPL-2.0+
|
||||||
|
// (C) 2021 Pali Rohár <pali@kernel.org>
|
||||||
|
|
||||||
|
#include <common.h>
|
||||||
|
#include <dm.h>
|
||||||
|
#include <reset-uclass.h>
|
||||||
|
#include <asm/io.h>
|
||||||
|
|
||||||
|
#define MVEBU_SOC_CONTROL_1_REG 0x4
|
||||||
|
|
||||||
|
#define MVEBU_PCIE_ID 0
|
||||||
|
|
||||||
|
struct mvebu_reset_data {
|
||||||
|
void *base;
|
||||||
|
};
|
||||||
|
|
||||||
|
static int mvebu_reset_of_xlate(struct reset_ctl *rst,
|
||||||
|
struct ofnode_phandle_args *args)
|
||||||
|
{
|
||||||
|
if (args->args_count < 2)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
rst->id = args->args[0];
|
||||||
|
rst->data = args->args[1];
|
||||||
|
|
||||||
|
/* Currently only PCIe is implemented */
|
||||||
|
if (rst->id != MVEBU_PCIE_ID)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
/* Four PCIe enable bits are shared across more PCIe links */
|
||||||
|
if (!(rst->data >= 0 && rst->data <= 3))
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int mvebu_reset_request(struct reset_ctl *rst)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int mvebu_reset_free(struct reset_ctl *rst)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int mvebu_reset_assert(struct reset_ctl *rst)
|
||||||
|
{
|
||||||
|
struct mvebu_reset_data *data = dev_get_priv(rst->dev);
|
||||||
|
|
||||||
|
clrbits_32(data->base + MVEBU_SOC_CONTROL_1_REG, BIT(rst->data));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int mvebu_reset_deassert(struct reset_ctl *rst)
|
||||||
|
{
|
||||||
|
struct mvebu_reset_data *data = dev_get_priv(rst->dev);
|
||||||
|
|
||||||
|
setbits_32(data->base + MVEBU_SOC_CONTROL_1_REG, BIT(rst->data));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int mvebu_reset_status(struct reset_ctl *rst)
|
||||||
|
{
|
||||||
|
struct mvebu_reset_data *data = dev_get_priv(rst->dev);
|
||||||
|
|
||||||
|
return !(readl(data->base + MVEBU_SOC_CONTROL_1_REG) & BIT(rst->data));
|
||||||
|
}
|
||||||
|
|
||||||
|
static int mvebu_reset_of_to_plat(struct udevice *dev)
|
||||||
|
{
|
||||||
|
struct mvebu_reset_data *data = dev_get_priv(dev);
|
||||||
|
|
||||||
|
data->base = (void *)dev_read_addr(dev);
|
||||||
|
if ((fdt_addr_t)data->base == FDT_ADDR_T_NONE)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct udevice_id mvebu_reset_of_match[] = {
|
||||||
|
{ .compatible = "marvell,armada-370-xp-system-controller" },
|
||||||
|
{ .compatible = "marvell,armada-375-system-controller" },
|
||||||
|
{ .compatible = "marvell,armada-380-system-controller" },
|
||||||
|
{ .compatible = "marvell,armada-390-system-controller" },
|
||||||
|
{ },
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct reset_ops mvebu_reset_ops = {
|
||||||
|
.of_xlate = mvebu_reset_of_xlate,
|
||||||
|
.request = mvebu_reset_request,
|
||||||
|
.rfree = mvebu_reset_free,
|
||||||
|
.rst_assert = mvebu_reset_assert,
|
||||||
|
.rst_deassert = mvebu_reset_deassert,
|
||||||
|
.rst_status = mvebu_reset_status,
|
||||||
|
};
|
||||||
|
|
||||||
|
U_BOOT_DRIVER(mvebu_reset) = {
|
||||||
|
.name = "mvebu-reset",
|
||||||
|
.id = UCLASS_RESET,
|
||||||
|
.of_match = mvebu_reset_of_match,
|
||||||
|
.of_to_plat = mvebu_reset_of_to_plat,
|
||||||
|
.priv_auto = sizeof(struct mvebu_reset_data),
|
||||||
|
.ops = &mvebu_reset_ops,
|
||||||
|
};
|
@ -1,5 +1,4 @@
|
|||||||
A38X BOARD
|
A38X BOARD
|
||||||
M: Dirk Eibach <dirk.eibach@gdsys.cc>
|
|
||||||
M: Mario Six <mario.six@gdsys.cc>
|
M: Mario Six <mario.six@gdsys.cc>
|
||||||
S: Maintained
|
S: Maintained
|
||||||
F: board/gdsys/a38x/
|
F: board/gdsys/a38x/
|
||||||
|
@ -94,12 +94,16 @@ int hws_board_topology_load(struct serdes_map **serdes_map_array, u8 *count)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void board_pex_config(void)
|
void spl_board_init(void)
|
||||||
{
|
{
|
||||||
#ifdef CONFIG_SPL_BUILD
|
#ifdef CONFIG_SPL_BUILD
|
||||||
uint k;
|
uint k;
|
||||||
struct gpio_desc gpio = {};
|
struct gpio_desc gpio = {};
|
||||||
|
|
||||||
|
/* Enable PCIe link 2 */
|
||||||
|
setbits_32(MVEBU_REGISTER(0x18204), BIT(2));
|
||||||
|
mdelay(10);
|
||||||
|
|
||||||
if (!request_gpio_by_name(&gpio, "pca9698@22", 31, "fpga-program-gpio")) {
|
if (!request_gpio_by_name(&gpio, "pca9698@22", 31, "fpga-program-gpio")) {
|
||||||
/* prepare FPGA reconfiguration */
|
/* prepare FPGA reconfiguration */
|
||||||
dm_gpio_set_dir_flags(&gpio, GPIOD_IS_OUT);
|
dm_gpio_set_dir_flags(&gpio, GPIOD_IS_OUT);
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
MPC8308 BOARD
|
MPC8308 BOARD
|
||||||
M: Dirk Eibach <dirk.eibach@gdsys.cc>
|
M: Mario Six <mario.six@gdsys.cc>
|
||||||
S: Maintained
|
S: Maintained
|
||||||
F: board/gdsys/mpc8308/
|
F: board/gdsys/mpc8308/
|
||||||
F: include/configs/gazerbeam.h
|
F: include/configs/gazerbeam.h
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
ICONNECT BOARD
|
ICONNECT BOARD
|
||||||
|
M: Tony Dinh <mibodhi@gmail.com>
|
||||||
M: Luka Perkov <luka@openwrt.org>
|
M: Luka Perkov <luka@openwrt.org>
|
||||||
S: Maintained
|
S: Maintained
|
||||||
F: board/iomega/iconnect/
|
F: board/iomega/iconnect/
|
||||||
|
@ -92,3 +92,10 @@ int board_init(void)
|
|||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int board_late_init(void)
|
||||||
|
{
|
||||||
|
/* Do late init to ensure successful enumeration of PCIe devices */
|
||||||
|
pci_init();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
@ -33,6 +33,7 @@ CONFIG_SYS_CONSOLE_INFO_QUIET=y
|
|||||||
CONFIG_DISPLAY_BOARDINFO_LATE=y
|
CONFIG_DISPLAY_BOARDINFO_LATE=y
|
||||||
CONFIG_BOARD_LATE_INIT=y
|
CONFIG_BOARD_LATE_INIT=y
|
||||||
CONFIG_LAST_STAGE_INIT=y
|
CONFIG_LAST_STAGE_INIT=y
|
||||||
|
CONFIG_SPL_BOARD_INIT=y
|
||||||
CONFIG_SPL_SYS_MALLOC_SIMPLE=y
|
CONFIG_SPL_SYS_MALLOC_SIMPLE=y
|
||||||
CONFIG_SPL_I2C=y
|
CONFIG_SPL_I2C=y
|
||||||
CONFIG_HUSH_PARSER=y
|
CONFIG_HUSH_PARSER=y
|
||||||
|
@ -11,7 +11,7 @@ CONFIG_ENV_SIZE=0x10000
|
|||||||
CONFIG_ENV_OFFSET=0x100000
|
CONFIG_ENV_OFFSET=0x100000
|
||||||
CONFIG_ENV_SECT_SIZE=0x10000
|
CONFIG_ENV_SECT_SIZE=0x10000
|
||||||
CONFIG_DEFAULT_DEVICE_TREE="armada-375-db"
|
CONFIG_DEFAULT_DEVICE_TREE="armada-375-db"
|
||||||
CONFIG_SPL_TEXT_BASE=0x40004030
|
CONFIG_SPL_TEXT_BASE=0x40000030
|
||||||
CONFIG_SPL_SERIAL=y
|
CONFIG_SPL_SERIAL=y
|
||||||
CONFIG_SPL=y
|
CONFIG_SPL=y
|
||||||
CONFIG_DEBUG_UART_BASE=0xf1012000
|
CONFIG_DEBUG_UART_BASE=0xf1012000
|
||||||
|
@ -2,6 +2,7 @@ CONFIG_ARM=y
|
|||||||
CONFIG_SKIP_LOWLEVEL_INIT=y
|
CONFIG_SKIP_LOWLEVEL_INIT=y
|
||||||
CONFIG_SYS_DCACHE_OFF=y
|
CONFIG_SYS_DCACHE_OFF=y
|
||||||
CONFIG_ARCH_CPU_INIT=y
|
CONFIG_ARCH_CPU_INIT=y
|
||||||
|
CONFIG_SYS_THUMB_BUILD=y
|
||||||
CONFIG_ARCH_KIRKWOOD=y
|
CONFIG_ARCH_KIRKWOOD=y
|
||||||
CONFIG_SYS_KWD_CONFIG="board/iomega/iconnect/kwbimage.cfg"
|
CONFIG_SYS_KWD_CONFIG="board/iomega/iconnect/kwbimage.cfg"
|
||||||
CONFIG_SYS_TEXT_BASE=0x600000
|
CONFIG_SYS_TEXT_BASE=0x600000
|
||||||
@ -18,9 +19,11 @@ CONFIG_USE_BOOTCOMMAND=y
|
|||||||
CONFIG_BOOTCOMMAND="setenv bootargs ${console} ${mtdparts} ${bootargs_root}; ubi part rootfs; ubifsmount ubi:rootfs; ubifsload 0x800000 ${kernel}; bootm 0x800000"
|
CONFIG_BOOTCOMMAND="setenv bootargs ${console} ${mtdparts} ${bootargs_root}; ubi part rootfs; ubifsmount ubi:rootfs; ubifsload 0x800000 ${kernel}; bootm 0x800000"
|
||||||
CONFIG_USE_PREBOOT=y
|
CONFIG_USE_PREBOOT=y
|
||||||
# CONFIG_DISPLAY_BOARDINFO is not set
|
# CONFIG_DISPLAY_BOARDINFO is not set
|
||||||
|
CONFIG_BOARD_LATE_INIT=y
|
||||||
CONFIG_SYS_PROMPT="iconnect => "
|
CONFIG_SYS_PROMPT="iconnect => "
|
||||||
# CONFIG_CMD_FLASH is not set
|
# CONFIG_CMD_FLASH is not set
|
||||||
CONFIG_CMD_NAND=y
|
CONFIG_CMD_NAND=y
|
||||||
|
CONFIG_CMD_PCI=y
|
||||||
CONFIG_CMD_USB=y
|
CONFIG_CMD_USB=y
|
||||||
# CONFIG_CMD_SETEXPR is not set
|
# CONFIG_CMD_SETEXPR is not set
|
||||||
CONFIG_CMD_MII=y
|
CONFIG_CMD_MII=y
|
||||||
@ -43,6 +46,8 @@ CONFIG_MTD=y
|
|||||||
CONFIG_MTD_RAW_NAND=y
|
CONFIG_MTD_RAW_NAND=y
|
||||||
CONFIG_MVGBE=y
|
CONFIG_MVGBE=y
|
||||||
CONFIG_MII=y
|
CONFIG_MII=y
|
||||||
|
CONFIG_PCI=y
|
||||||
|
CONFIG_PCI_MVEBU=y
|
||||||
CONFIG_SYS_NS16550=y
|
CONFIG_SYS_NS16550=y
|
||||||
CONFIG_USB=y
|
CONFIG_USB=y
|
||||||
CONFIG_USB_EHCI_HCD=y
|
CONFIG_USB_EHCI_HCD=y
|
||||||
|
@ -55,6 +55,7 @@ static int ddr3_tip_centralization(u32 dev_num, u32 mode)
|
|||||||
enum hws_training_ip_stat training_result[MAX_INTERFACE_NUM];
|
enum hws_training_ip_stat training_result[MAX_INTERFACE_NUM];
|
||||||
u32 if_id, pattern_id, bit_id;
|
u32 if_id, pattern_id, bit_id;
|
||||||
u8 bus_id;
|
u8 bus_id;
|
||||||
|
u8 current_byte_status;
|
||||||
u8 cur_start_win[BUS_WIDTH_IN_BITS];
|
u8 cur_start_win[BUS_WIDTH_IN_BITS];
|
||||||
u8 centralization_result[MAX_INTERFACE_NUM][BUS_WIDTH_IN_BITS];
|
u8 centralization_result[MAX_INTERFACE_NUM][BUS_WIDTH_IN_BITS];
|
||||||
u8 cur_end_win[BUS_WIDTH_IN_BITS];
|
u8 cur_end_win[BUS_WIDTH_IN_BITS];
|
||||||
@ -166,6 +167,10 @@ static int ddr3_tip_centralization(u32 dev_num, u32 mode)
|
|||||||
result[search_dir_id][7]));
|
result[search_dir_id][7]));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
current_byte_status =
|
||||||
|
mv_ddr_tip_sub_phy_byte_status_get(if_id,
|
||||||
|
bus_id);
|
||||||
|
|
||||||
for (bit_id = 0; bit_id < BUS_WIDTH_IN_BITS;
|
for (bit_id = 0; bit_id < BUS_WIDTH_IN_BITS;
|
||||||
bit_id++) {
|
bit_id++) {
|
||||||
/* check if this code is valid for 2 edge, probably not :( */
|
/* check if this code is valid for 2 edge, probably not :( */
|
||||||
@ -174,11 +179,32 @@ static int ddr3_tip_centralization(u32 dev_num, u32 mode)
|
|||||||
[HWS_LOW2HIGH]
|
[HWS_LOW2HIGH]
|
||||||
[bit_id],
|
[bit_id],
|
||||||
EDGE_1);
|
EDGE_1);
|
||||||
|
if (current_byte_status &
|
||||||
|
BYTE_SPLIT_OUT_MIX) {
|
||||||
|
if (cur_start_win[bit_id] >= 64)
|
||||||
|
cur_start_win[bit_id] -= 64;
|
||||||
|
else
|
||||||
|
cur_start_win[bit_id] = 0;
|
||||||
|
DEBUG_CENTRALIZATION_ENGINE
|
||||||
|
(DEBUG_LEVEL_INFO,
|
||||||
|
("pattern %d IF %d pup %d bit %d subtract 64 adll from start\n",
|
||||||
|
pattern_id, if_id, bus_id, bit_id));
|
||||||
|
}
|
||||||
cur_end_win[bit_id] =
|
cur_end_win[bit_id] =
|
||||||
GET_TAP_RESULT(result
|
GET_TAP_RESULT(result
|
||||||
[HWS_HIGH2LOW]
|
[HWS_HIGH2LOW]
|
||||||
[bit_id],
|
[bit_id],
|
||||||
EDGE_1);
|
EDGE_1);
|
||||||
|
if (cur_end_win[bit_id] >= 64 &&
|
||||||
|
(current_byte_status &
|
||||||
|
BYTE_SPLIT_OUT_MIX)) {
|
||||||
|
cur_end_win[bit_id] -= 64;
|
||||||
|
DEBUG_CENTRALIZATION_ENGINE
|
||||||
|
(DEBUG_LEVEL_INFO,
|
||||||
|
("pattern %d IF %d pup %d bit %d subtract 64 adll from end\n",
|
||||||
|
pattern_id, if_id, bus_id, bit_id));
|
||||||
|
}
|
||||||
|
|
||||||
/* window length */
|
/* window length */
|
||||||
current_window[bit_id] =
|
current_window[bit_id] =
|
||||||
cur_end_win[bit_id] -
|
cur_end_win[bit_id] -
|
||||||
|
@ -167,8 +167,6 @@ static u16 a38x_vco_freq_per_sar_ref_clk_40_mhz[] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
static u32 async_mode_at_tf;
|
|
||||||
|
|
||||||
static u32 dq_bit_map_2_phy_pin[] = {
|
static u32 dq_bit_map_2_phy_pin[] = {
|
||||||
1, 0, 2, 6, 9, 8, 3, 7, /* 0 */
|
1, 0, 2, 6, 9, 8, 3, 7, /* 0 */
|
||||||
8, 9, 1, 7, 2, 6, 3, 0, /* 1 */
|
8, 9, 1, 7, 2, 6, 3, 0, /* 1 */
|
||||||
@ -734,7 +732,8 @@ static int ddr3_tip_a38x_set_divider(u8 dev_num, u32 if_id,
|
|||||||
u32 divider = 0;
|
u32 divider = 0;
|
||||||
u32 sar_val, ref_clk_satr;
|
u32 sar_val, ref_clk_satr;
|
||||||
u32 async_val;
|
u32 async_val;
|
||||||
u32 freq = mv_ddr_freq_get(frequency);
|
u32 cpu_freq;
|
||||||
|
u32 ddr_freq = mv_ddr_freq_get(frequency);
|
||||||
|
|
||||||
if (if_id != 0) {
|
if (if_id != 0) {
|
||||||
DEBUG_TRAINING_ACCESS(DEBUG_LEVEL_ERROR,
|
DEBUG_TRAINING_ACCESS(DEBUG_LEVEL_ERROR,
|
||||||
@ -751,11 +750,14 @@ static int ddr3_tip_a38x_set_divider(u8 dev_num, u32 if_id,
|
|||||||
ref_clk_satr = reg_read(DEVICE_SAMPLE_AT_RESET2_REG);
|
ref_clk_satr = reg_read(DEVICE_SAMPLE_AT_RESET2_REG);
|
||||||
if (((ref_clk_satr >> DEVICE_SAMPLE_AT_RESET2_REG_REFCLK_OFFSET) & 0x1) ==
|
if (((ref_clk_satr >> DEVICE_SAMPLE_AT_RESET2_REG_REFCLK_OFFSET) & 0x1) ==
|
||||||
DEVICE_SAMPLE_AT_RESET2_REG_REFCLK_25MHZ)
|
DEVICE_SAMPLE_AT_RESET2_REG_REFCLK_25MHZ)
|
||||||
divider = a38x_vco_freq_per_sar_ref_clk_25_mhz[sar_val] / freq;
|
cpu_freq = a38x_vco_freq_per_sar_ref_clk_25_mhz[sar_val];
|
||||||
else
|
else
|
||||||
divider = a38x_vco_freq_per_sar_ref_clk_40_mhz[sar_val] / freq;
|
cpu_freq = a38x_vco_freq_per_sar_ref_clk_40_mhz[sar_val];
|
||||||
|
|
||||||
if ((async_mode_at_tf == 1) && (freq > 400)) {
|
divider = cpu_freq / ddr_freq;
|
||||||
|
|
||||||
|
if (((cpu_freq % ddr_freq != 0) || (divider != 2 && divider != 3)) &&
|
||||||
|
(ddr_freq > 400)) {
|
||||||
/* Set async mode */
|
/* Set async mode */
|
||||||
dunit_write(0x20220, 0x1000, 0x1000);
|
dunit_write(0x20220, 0x1000, 0x1000);
|
||||||
dunit_write(0xe42f4, 0x200, 0x200);
|
dunit_write(0xe42f4, 0x200, 0x200);
|
||||||
@ -869,8 +871,6 @@ int ddr3_tip_ext_write(u32 dev_num, u32 if_id, u32 reg_addr,
|
|||||||
|
|
||||||
int mv_ddr_early_init(void)
|
int mv_ddr_early_init(void)
|
||||||
{
|
{
|
||||||
struct mv_ddr_topology_map *tm = mv_ddr_topology_map_get();
|
|
||||||
|
|
||||||
/* FIXME: change this configuration per ddr type
|
/* FIXME: change this configuration per ddr type
|
||||||
* configure a380 and a390 to work with receiver odt timing
|
* configure a380 and a390 to work with receiver odt timing
|
||||||
* the odt_config is defined:
|
* the odt_config is defined:
|
||||||
@ -882,9 +882,6 @@ int mv_ddr_early_init(void)
|
|||||||
|
|
||||||
mv_ddr_sw_db_init(0, 0);
|
mv_ddr_sw_db_init(0, 0);
|
||||||
|
|
||||||
if (tm->interface_params[0].memory_freq != MV_DDR_FREQ_SAR)
|
|
||||||
async_mode_at_tf = 1;
|
|
||||||
|
|
||||||
return MV_OK;
|
return MV_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1862,10 +1862,10 @@ static int pxa3xx_nand_probe_dt(struct udevice *dev, struct pxa3xx_nand_info *in
|
|||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dev_read_bool(dev, "nand-enable-arbiter"))
|
if (dev_read_bool(dev, "marvell,nand-enable-arbiter"))
|
||||||
pdata->enable_arbiter = 1;
|
pdata->enable_arbiter = 1;
|
||||||
|
|
||||||
if (dev_read_bool(dev, "nand-keep-config"))
|
if (dev_read_bool(dev, "marvell,nand-keep-config"))
|
||||||
pdata->keep_config = 1;
|
pdata->keep_config = 1;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -265,6 +265,7 @@ config PCI_MVEBU
|
|||||||
bool "Enable Armada XP/38x PCIe driver"
|
bool "Enable Armada XP/38x PCIe driver"
|
||||||
depends on ARCH_MVEBU
|
depends on ARCH_MVEBU
|
||||||
select MISC
|
select MISC
|
||||||
|
select DM_RESET
|
||||||
help
|
help
|
||||||
Say Y here if you want to enable PCIe controller support on
|
Say Y here if you want to enable PCIe controller support on
|
||||||
Armada XP/38x SoCs.
|
Armada XP/38x SoCs.
|
||||||
|
@ -18,13 +18,16 @@
|
|||||||
#include <dm/lists.h>
|
#include <dm/lists.h>
|
||||||
#include <dm/of_access.h>
|
#include <dm/of_access.h>
|
||||||
#include <pci.h>
|
#include <pci.h>
|
||||||
|
#include <reset.h>
|
||||||
#include <asm/io.h>
|
#include <asm/io.h>
|
||||||
#include <asm/arch/cpu.h>
|
#include <asm/arch/cpu.h>
|
||||||
#include <asm/arch/soc.h>
|
#include <asm/arch/soc.h>
|
||||||
#include <linux/bitops.h>
|
#include <linux/bitops.h>
|
||||||
|
#include <linux/delay.h>
|
||||||
#include <linux/errno.h>
|
#include <linux/errno.h>
|
||||||
#include <linux/ioport.h>
|
#include <linux/ioport.h>
|
||||||
#include <linux/mbus.h>
|
#include <linux/mbus.h>
|
||||||
|
#include <linux/sizes.h>
|
||||||
|
|
||||||
/* PCIe unit register offsets */
|
/* PCIe unit register offsets */
|
||||||
#define SELECT(x, n) ((x >> n) & 1UL)
|
#define SELECT(x, n) ((x >> n) & 1UL)
|
||||||
@ -59,6 +62,9 @@
|
|||||||
#define PCIE_DEBUG_CTRL 0x1a60
|
#define PCIE_DEBUG_CTRL 0x1a60
|
||||||
#define PCIE_DEBUG_SOFT_RESET BIT(20)
|
#define PCIE_DEBUG_SOFT_RESET BIT(20)
|
||||||
|
|
||||||
|
#define LINK_WAIT_RETRIES 100
|
||||||
|
#define LINK_WAIT_TIMEOUT 1000
|
||||||
|
|
||||||
struct mvebu_pcie {
|
struct mvebu_pcie {
|
||||||
struct pci_controller hose;
|
struct pci_controller hose;
|
||||||
void __iomem *base;
|
void __iomem *base;
|
||||||
@ -66,8 +72,10 @@ struct mvebu_pcie {
|
|||||||
struct resource mem;
|
struct resource mem;
|
||||||
void __iomem *iobase;
|
void __iomem *iobase;
|
||||||
struct resource io;
|
struct resource io;
|
||||||
|
u32 intregs;
|
||||||
u32 port;
|
u32 port;
|
||||||
u32 lane;
|
u32 lane;
|
||||||
|
bool is_x4;
|
||||||
int devfn;
|
int devfn;
|
||||||
u32 lane_mask;
|
u32 lane_mask;
|
||||||
int first_busno;
|
int first_busno;
|
||||||
@ -80,14 +88,6 @@ struct mvebu_pcie {
|
|||||||
u32 cfgcache[(0x3c - 0x10) / 4];
|
u32 cfgcache[(0x3c - 0x10) / 4];
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
|
||||||
* MVEBU PCIe controller needs MEMORY and I/O BARs to be mapped
|
|
||||||
* into SoCs address space. Each controller will map 128M of MEM
|
|
||||||
* and 64K of I/O space when registered.
|
|
||||||
*/
|
|
||||||
static void __iomem *mvebu_pcie_membase = (void __iomem *)MBUS_PCI_MEM_BASE;
|
|
||||||
static void __iomem *mvebu_pcie_iobase = (void __iomem *)MBUS_PCI_IO_BASE;
|
|
||||||
|
|
||||||
static inline bool mvebu_pcie_link_up(struct mvebu_pcie *pcie)
|
static inline bool mvebu_pcie_link_up(struct mvebu_pcie *pcie)
|
||||||
{
|
{
|
||||||
u32 val;
|
u32 val;
|
||||||
@ -95,6 +95,23 @@ static inline bool mvebu_pcie_link_up(struct mvebu_pcie *pcie)
|
|||||||
return !(val & PCIE_STAT_LINK_DOWN);
|
return !(val & PCIE_STAT_LINK_DOWN);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void mvebu_pcie_wait_for_link(struct mvebu_pcie *pcie)
|
||||||
|
{
|
||||||
|
int retries;
|
||||||
|
|
||||||
|
/* check if the link is up or not */
|
||||||
|
for (retries = 0; retries < LINK_WAIT_RETRIES; retries++) {
|
||||||
|
if (mvebu_pcie_link_up(pcie)) {
|
||||||
|
printf("%s: Link up\n", pcie->name);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
udelay(LINK_WAIT_TIMEOUT);
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("%s: Link down\n", pcie->name);
|
||||||
|
}
|
||||||
|
|
||||||
static void mvebu_pcie_set_local_bus_nr(struct mvebu_pcie *pcie, int busno)
|
static void mvebu_pcie_set_local_bus_nr(struct mvebu_pcie *pcie, int busno)
|
||||||
{
|
{
|
||||||
u32 stat;
|
u32 stat;
|
||||||
@ -357,10 +374,63 @@ static void mvebu_pcie_setup_wins(struct mvebu_pcie *pcie)
|
|||||||
pcie->base + PCIE_BAR_CTRL_OFF(1));
|
pcie->base + PCIE_BAR_CTRL_OFF(1));
|
||||||
|
|
||||||
/* Setup BAR[0] to internal registers. */
|
/* Setup BAR[0] to internal registers. */
|
||||||
writel(SOC_REGS_PHY_BASE, pcie->base + PCIE_BAR_LO_OFF(0));
|
writel(pcie->intregs, pcie->base + PCIE_BAR_LO_OFF(0));
|
||||||
writel(0, pcie->base + PCIE_BAR_HI_OFF(0));
|
writel(0, pcie->base + PCIE_BAR_HI_OFF(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Only enable PCIe link, do not setup it */
|
||||||
|
static int mvebu_pcie_enable_link(struct mvebu_pcie *pcie, ofnode node)
|
||||||
|
{
|
||||||
|
struct reset_ctl rst;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = reset_get_by_index_nodev(node, 0, &rst);
|
||||||
|
if (ret == -ENOENT) {
|
||||||
|
return 0;
|
||||||
|
} else if (ret < 0) {
|
||||||
|
printf("%s: cannot get reset controller: %d\n", pcie->name, ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = reset_request(&rst);
|
||||||
|
if (ret) {
|
||||||
|
printf("%s: cannot request reset controller: %d\n", pcie->name, ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = reset_deassert(&rst);
|
||||||
|
reset_free(&rst);
|
||||||
|
if (ret) {
|
||||||
|
printf("%s: cannot enable PCIe port: %d\n", pcie->name, ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Setup PCIe link but do not enable it */
|
||||||
|
static void mvebu_pcie_setup_link(struct mvebu_pcie *pcie)
|
||||||
|
{
|
||||||
|
u32 reg;
|
||||||
|
|
||||||
|
/* Setup PCIe controller to Root Complex mode */
|
||||||
|
reg = readl(pcie->base + PCIE_CTRL_OFF);
|
||||||
|
reg |= PCIE_CTRL_RC_MODE;
|
||||||
|
writel(reg, pcie->base + PCIE_CTRL_OFF);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Set Maximum Link Width to X1 or X4 in Root Port's PCIe Link
|
||||||
|
* Capability register. This register is defined by PCIe specification
|
||||||
|
* as read-only but this mvebu controller has it as read-write and must
|
||||||
|
* be set to number of SerDes PCIe lanes (1 or 4). If this register is
|
||||||
|
* not set correctly then link with endpoint card is not established.
|
||||||
|
*/
|
||||||
|
reg = readl(pcie->base + PCIE_CAPAB_OFF + PCI_EXP_LNKCAP);
|
||||||
|
reg &= ~PCI_EXP_LNKCAP_MLW;
|
||||||
|
reg |= (pcie->is_x4 ? 4 : 1) << 4;
|
||||||
|
writel(reg, pcie->base + PCIE_CAPAB_OFF + PCI_EXP_LNKCAP);
|
||||||
|
}
|
||||||
|
|
||||||
static int mvebu_pcie_probe(struct udevice *dev)
|
static int mvebu_pcie_probe(struct udevice *dev)
|
||||||
{
|
{
|
||||||
struct mvebu_pcie *pcie = dev_get_plat(dev);
|
struct mvebu_pcie *pcie = dev_get_plat(dev);
|
||||||
@ -368,11 +438,6 @@ static int mvebu_pcie_probe(struct udevice *dev)
|
|||||||
struct pci_controller *hose = dev_get_uclass_priv(ctlr);
|
struct pci_controller *hose = dev_get_uclass_priv(ctlr);
|
||||||
u32 reg;
|
u32 reg;
|
||||||
|
|
||||||
/* Setup PCIe controller to Root Complex mode */
|
|
||||||
reg = readl(pcie->base + PCIE_CTRL_OFF);
|
|
||||||
reg |= PCIE_CTRL_RC_MODE;
|
|
||||||
writel(reg, pcie->base + PCIE_CTRL_OFF);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Change Class Code of PCI Bridge device to PCI Bridge (0x600400)
|
* Change Class Code of PCI Bridge device to PCI Bridge (0x600400)
|
||||||
* because default value is Memory controller (0x508000) which
|
* because default value is Memory controller (0x508000) which
|
||||||
@ -433,26 +498,26 @@ static int mvebu_pcie_probe(struct udevice *dev)
|
|||||||
mvebu_pcie_set_local_bus_nr(pcie, 0);
|
mvebu_pcie_set_local_bus_nr(pcie, 0);
|
||||||
mvebu_pcie_set_local_dev_nr(pcie, 1);
|
mvebu_pcie_set_local_dev_nr(pcie, 1);
|
||||||
|
|
||||||
pcie->mem.start = (u32)mvebu_pcie_membase;
|
if (resource_size(&pcie->mem) &&
|
||||||
pcie->mem.end = pcie->mem.start + MBUS_PCI_MEM_SIZE - 1;
|
mvebu_mbus_add_window_by_id(pcie->mem_target, pcie->mem_attr,
|
||||||
mvebu_pcie_membase += MBUS_PCI_MEM_SIZE;
|
|
||||||
|
|
||||||
if (mvebu_mbus_add_window_by_id(pcie->mem_target, pcie->mem_attr,
|
|
||||||
(phys_addr_t)pcie->mem.start,
|
(phys_addr_t)pcie->mem.start,
|
||||||
resource_size(&pcie->mem))) {
|
resource_size(&pcie->mem))) {
|
||||||
printf("PCIe unable to add mbus window for mem at %08x+%08x\n",
|
printf("%s: unable to add mbus window for mem at %08x+%08x\n",
|
||||||
|
pcie->name,
|
||||||
(u32)pcie->mem.start, (unsigned)resource_size(&pcie->mem));
|
(u32)pcie->mem.start, (unsigned)resource_size(&pcie->mem));
|
||||||
|
pcie->mem.start = 0;
|
||||||
|
pcie->mem.end = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
pcie->io.start = (u32)mvebu_pcie_iobase;
|
if (resource_size(&pcie->io) &&
|
||||||
pcie->io.end = pcie->io.start + MBUS_PCI_IO_SIZE - 1;
|
mvebu_mbus_add_window_by_id(pcie->io_target, pcie->io_attr,
|
||||||
mvebu_pcie_iobase += MBUS_PCI_IO_SIZE;
|
|
||||||
|
|
||||||
if (mvebu_mbus_add_window_by_id(pcie->io_target, pcie->io_attr,
|
|
||||||
(phys_addr_t)pcie->io.start,
|
(phys_addr_t)pcie->io.start,
|
||||||
resource_size(&pcie->io))) {
|
resource_size(&pcie->io))) {
|
||||||
printf("PCIe unable to add mbus window for IO at %08x+%08x\n",
|
printf("%s: unable to add mbus window for IO at %08x+%08x\n",
|
||||||
|
pcie->name,
|
||||||
(u32)pcie->io.start, (unsigned)resource_size(&pcie->io));
|
(u32)pcie->io.start, (unsigned)resource_size(&pcie->io));
|
||||||
|
pcie->io.start = 0;
|
||||||
|
pcie->io.end = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Setup windows and configure host bridge */
|
/* Setup windows and configure host bridge */
|
||||||
@ -461,13 +526,23 @@ static int mvebu_pcie_probe(struct udevice *dev)
|
|||||||
/* PCI memory space */
|
/* PCI memory space */
|
||||||
pci_set_region(hose->regions + 0, pcie->mem.start,
|
pci_set_region(hose->regions + 0, pcie->mem.start,
|
||||||
pcie->mem.start, resource_size(&pcie->mem), PCI_REGION_MEM);
|
pcie->mem.start, resource_size(&pcie->mem), PCI_REGION_MEM);
|
||||||
pci_set_region(hose->regions + 1,
|
hose->region_count = 1;
|
||||||
0, 0,
|
|
||||||
gd->ram_size,
|
if (resource_size(&pcie->mem)) {
|
||||||
PCI_REGION_MEM | PCI_REGION_SYS_MEMORY);
|
pci_set_region(hose->regions + hose->region_count,
|
||||||
pci_set_region(hose->regions + 2, pcie->io.start,
|
pcie->mem.start, pcie->mem.start,
|
||||||
pcie->io.start, resource_size(&pcie->io), PCI_REGION_IO);
|
resource_size(&pcie->mem),
|
||||||
hose->region_count = 3;
|
PCI_REGION_MEM);
|
||||||
|
hose->region_count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (resource_size(&pcie->io)) {
|
||||||
|
pci_set_region(hose->regions + hose->region_count,
|
||||||
|
pcie->io.start, pcie->io.start,
|
||||||
|
resource_size(&pcie->io),
|
||||||
|
PCI_REGION_IO);
|
||||||
|
hose->region_count++;
|
||||||
|
}
|
||||||
|
|
||||||
/* PCI Bridge support 32-bit I/O and 64-bit prefetch mem addressing */
|
/* PCI Bridge support 32-bit I/O and 64-bit prefetch mem addressing */
|
||||||
pcie->cfgcache[(PCI_IO_BASE - 0x10) / 4] =
|
pcie->cfgcache[(PCI_IO_BASE - 0x10) / 4] =
|
||||||
@ -475,21 +550,7 @@ static int mvebu_pcie_probe(struct udevice *dev)
|
|||||||
pcie->cfgcache[(PCI_PREF_MEMORY_BASE - 0x10) / 4] =
|
pcie->cfgcache[(PCI_PREF_MEMORY_BASE - 0x10) / 4] =
|
||||||
PCI_PREF_RANGE_TYPE_64 | (PCI_PREF_RANGE_TYPE_64 << 16);
|
PCI_PREF_RANGE_TYPE_64 | (PCI_PREF_RANGE_TYPE_64 << 16);
|
||||||
|
|
||||||
return 0;
|
mvebu_pcie_wait_for_link(pcie);
|
||||||
}
|
|
||||||
|
|
||||||
static int mvebu_pcie_port_parse_dt(ofnode node, struct mvebu_pcie *pcie)
|
|
||||||
{
|
|
||||||
const u32 *addr;
|
|
||||||
int len;
|
|
||||||
|
|
||||||
addr = ofnode_get_property(node, "assigned-addresses", &len);
|
|
||||||
if (!addr) {
|
|
||||||
pr_err("property \"assigned-addresses\" not found");
|
|
||||||
return -FDT_ERR_NOTFOUND;
|
|
||||||
}
|
|
||||||
|
|
||||||
pcie->base = (void *)(fdt32_to_cpu(addr[2]) + SOC_REGS_PHY_BASE);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -554,31 +615,38 @@ static int mvebu_get_tgt_attr(ofnode node, int devfn,
|
|||||||
return -ENOENT;
|
return -ENOENT;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int mvebu_pcie_of_to_plat(struct udevice *dev)
|
static int mvebu_pcie_port_parse_dt(ofnode node, ofnode parent, struct mvebu_pcie *pcie)
|
||||||
{
|
{
|
||||||
struct mvebu_pcie *pcie = dev_get_plat(dev);
|
struct fdt_pci_addr pci_addr;
|
||||||
|
const u32 *addr;
|
||||||
|
u32 num_lanes;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
int len;
|
||||||
|
|
||||||
/* Get port number, lane number and memory target / attr */
|
/* Get port number, lane number and memory target / attr */
|
||||||
if (ofnode_read_u32(dev_ofnode(dev), "marvell,pcie-port",
|
if (ofnode_read_u32(node, "marvell,pcie-port",
|
||||||
&pcie->port)) {
|
&pcie->port)) {
|
||||||
ret = -ENODEV;
|
ret = -ENODEV;
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ofnode_read_u32(dev_ofnode(dev), "marvell,pcie-lane", &pcie->lane))
|
if (ofnode_read_u32(node, "marvell,pcie-lane", &pcie->lane))
|
||||||
pcie->lane = 0;
|
pcie->lane = 0;
|
||||||
|
|
||||||
sprintf(pcie->name, "pcie%d.%d", pcie->port, pcie->lane);
|
sprintf(pcie->name, "pcie%d.%d", pcie->port, pcie->lane);
|
||||||
|
|
||||||
/* pci_get_devfn() returns devfn in bits 15..8, see PCI_DEV usage */
|
if (!ofnode_read_u32(node, "num-lanes", &num_lanes) && num_lanes == 4)
|
||||||
pcie->devfn = pci_get_devfn(dev);
|
pcie->is_x4 = true;
|
||||||
if (pcie->devfn < 0) {
|
|
||||||
ret = -ENODEV;
|
/* devfn is in bits [15:8], see PCI_DEV usage */
|
||||||
|
ret = ofnode_read_pci_addr(node, FDT_PCI_SPACE_CONFIG, "reg", &pci_addr);
|
||||||
|
if (ret < 0) {
|
||||||
|
printf("%s: property \"reg\" is invalid\n", pcie->name);
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
pcie->devfn = pci_addr.phys_hi & 0xff00;
|
||||||
|
|
||||||
ret = mvebu_get_tgt_attr(dev_ofnode(dev->parent), pcie->devfn,
|
ret = mvebu_get_tgt_attr(parent, pcie->devfn,
|
||||||
IORESOURCE_MEM,
|
IORESOURCE_MEM,
|
||||||
&pcie->mem_target, &pcie->mem_attr);
|
&pcie->mem_target, &pcie->mem_attr);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
@ -586,7 +654,7 @@ static int mvebu_pcie_of_to_plat(struct udevice *dev)
|
|||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = mvebu_get_tgt_attr(dev_ofnode(dev->parent), pcie->devfn,
|
ret = mvebu_get_tgt_attr(parent, pcie->devfn,
|
||||||
IORESOURCE_IO,
|
IORESOURCE_IO,
|
||||||
&pcie->io_target, &pcie->io_attr);
|
&pcie->io_target, &pcie->io_attr);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
@ -595,9 +663,15 @@ static int mvebu_pcie_of_to_plat(struct udevice *dev)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Parse PCIe controller register base from DT */
|
/* Parse PCIe controller register base from DT */
|
||||||
ret = mvebu_pcie_port_parse_dt(dev_ofnode(dev), pcie);
|
addr = ofnode_get_property(node, "assigned-addresses", &len);
|
||||||
if (ret < 0)
|
if (!addr) {
|
||||||
|
printf("%s: property \"assigned-addresses\" not found\n", pcie->name);
|
||||||
|
ret = -FDT_ERR_NOTFOUND;
|
||||||
goto err;
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
pcie->base = (void *)(u32)ofnode_translate_address(node, addr);
|
||||||
|
pcie->intregs = (u32)pcie->base - fdt32_to_cpu(addr[2]);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
@ -615,7 +689,6 @@ static struct driver pcie_mvebu_drv = {
|
|||||||
.id = UCLASS_PCI,
|
.id = UCLASS_PCI,
|
||||||
.ops = &mvebu_pcie_ops,
|
.ops = &mvebu_pcie_ops,
|
||||||
.probe = mvebu_pcie_probe,
|
.probe = mvebu_pcie_probe,
|
||||||
.of_to_plat = mvebu_pcie_of_to_plat,
|
|
||||||
.plat_auto = sizeof(struct mvebu_pcie),
|
.plat_auto = sizeof(struct mvebu_pcie),
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -625,9 +698,14 @@ static struct driver pcie_mvebu_drv = {
|
|||||||
*/
|
*/
|
||||||
static int mvebu_pcie_bind(struct udevice *parent)
|
static int mvebu_pcie_bind(struct udevice *parent)
|
||||||
{
|
{
|
||||||
|
struct mvebu_pcie **ports_pcie;
|
||||||
struct mvebu_pcie *pcie;
|
struct mvebu_pcie *pcie;
|
||||||
struct uclass_driver *drv;
|
struct uclass_driver *drv;
|
||||||
struct udevice *dev;
|
struct udevice *dev;
|
||||||
|
struct resource mem;
|
||||||
|
struct resource io;
|
||||||
|
int ports_count, i;
|
||||||
|
ofnode *ports_nodes;
|
||||||
ofnode subnode;
|
ofnode subnode;
|
||||||
|
|
||||||
/* Lookup pci driver */
|
/* Lookup pci driver */
|
||||||
@ -637,19 +715,94 @@ static int mvebu_pcie_bind(struct udevice *parent)
|
|||||||
return -ENOENT;
|
return -ENOENT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ports_count = ofnode_get_child_count(dev_ofnode(parent));
|
||||||
|
ports_pcie = calloc(ports_count, sizeof(*ports_pcie));
|
||||||
|
ports_nodes = calloc(ports_count, sizeof(*ports_nodes));
|
||||||
|
if (!ports_pcie || !ports_nodes) {
|
||||||
|
free(ports_pcie);
|
||||||
|
free(ports_nodes);
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
ports_count = 0;
|
||||||
|
|
||||||
|
mem.start = MBUS_PCI_MEM_BASE;
|
||||||
|
mem.end = MBUS_PCI_MEM_BASE + MBUS_PCI_MEM_SIZE - 1;
|
||||||
|
io.start = MBUS_PCI_IO_BASE;
|
||||||
|
io.end = MBUS_PCI_IO_BASE + MBUS_PCI_IO_SIZE - 1;
|
||||||
|
|
||||||
|
/* First phase: Fill mvebu_pcie struct for each port */
|
||||||
ofnode_for_each_subnode(subnode, dev_ofnode(parent)) {
|
ofnode_for_each_subnode(subnode, dev_ofnode(parent)) {
|
||||||
if (!ofnode_is_available(subnode))
|
if (!ofnode_is_available(subnode))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
pcie = calloc(1, sizeof(*pcie));
|
pcie = calloc(1, sizeof(*pcie));
|
||||||
if (!pcie)
|
if (!pcie)
|
||||||
return -ENOMEM;
|
continue;
|
||||||
|
|
||||||
|
if (mvebu_pcie_port_parse_dt(subnode, dev_ofnode(parent), pcie) < 0) {
|
||||||
|
free(pcie);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* MVEBU PCIe controller needs MEMORY and I/O BARs to be mapped
|
||||||
|
* into SoCs address space. Each controller will map 128M of MEM
|
||||||
|
* and 64K of I/O space when registered.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (resource_size(&mem) >= SZ_128M) {
|
||||||
|
pcie->mem.start = mem.start;
|
||||||
|
pcie->mem.end = mem.start + SZ_128M - 1;
|
||||||
|
mem.start += SZ_128M;
|
||||||
|
} else {
|
||||||
|
printf("%s: unable to assign mbus window for mem\n", pcie->name);
|
||||||
|
pcie->mem.start = 0;
|
||||||
|
pcie->mem.end = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (resource_size(&io) >= SZ_64K) {
|
||||||
|
pcie->io.start = io.start;
|
||||||
|
pcie->io.end = io.start + SZ_64K - 1;
|
||||||
|
io.start += SZ_64K;
|
||||||
|
} else {
|
||||||
|
printf("%s: unable to assign mbus window for io\n", pcie->name);
|
||||||
|
pcie->io.start = 0;
|
||||||
|
pcie->io.end = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
ports_pcie[ports_count] = pcie;
|
||||||
|
ports_nodes[ports_count] = subnode;
|
||||||
|
ports_count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Second phase: Setup all PCIe links (do not enable them yet) */
|
||||||
|
for (i = 0; i < ports_count; i++)
|
||||||
|
mvebu_pcie_setup_link(ports_pcie[i]);
|
||||||
|
|
||||||
|
/* Third phase: Enable all PCIe links and create for each UCLASS_PCI device */
|
||||||
|
for (i = 0; i < ports_count; i++) {
|
||||||
|
pcie = ports_pcie[i];
|
||||||
|
subnode = ports_nodes[i];
|
||||||
|
|
||||||
|
/*
|
||||||
|
* PCIe link can be enabled only after all PCIe links were
|
||||||
|
* properly configured. This is because more PCIe links shares
|
||||||
|
* one enable bit and some PCIe links cannot be enabled
|
||||||
|
* individually.
|
||||||
|
*/
|
||||||
|
if (mvebu_pcie_enable_link(pcie, subnode) < 0) {
|
||||||
|
free(pcie);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
/* Create child device UCLASS_PCI and bind it */
|
/* Create child device UCLASS_PCI and bind it */
|
||||||
device_bind(parent, &pcie_mvebu_drv, pcie->name, pcie, subnode,
|
device_bind(parent, &pcie_mvebu_drv, pcie->name, pcie, subnode,
|
||||||
&dev);
|
&dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
free(ports_pcie);
|
||||||
|
free(ports_nodes);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -53,7 +53,7 @@
|
|||||||
|
|
||||||
/* Defines for SPL */
|
/* Defines for SPL */
|
||||||
#define CONFIG_SPL_SIZE (140 << 10)
|
#define CONFIG_SPL_SIZE (140 << 10)
|
||||||
#define CONFIG_SPL_MAX_SIZE (CONFIG_SPL_SIZE - 0x0030)
|
#define CONFIG_SPL_MAX_SIZE (CONFIG_SPL_SIZE - (CONFIG_SPL_TEXT_BASE - 0x40000000))
|
||||||
|
|
||||||
#define CONFIG_SPL_BSS_START_ADDR (0x40000000 + CONFIG_SPL_SIZE)
|
#define CONFIG_SPL_BSS_START_ADDR (0x40000000 + CONFIG_SPL_SIZE)
|
||||||
#define CONFIG_SPL_BSS_MAX_SIZE (16 << 10)
|
#define CONFIG_SPL_BSS_MAX_SIZE (16 << 10)
|
||||||
|
@ -32,22 +32,9 @@
|
|||||||
*/
|
*/
|
||||||
#include "mv-common.h"
|
#include "mv-common.h"
|
||||||
|
|
||||||
/*
|
|
||||||
* Memory layout while starting into the bin_hdr via the
|
|
||||||
* BootROM:
|
|
||||||
*
|
|
||||||
* 0x4000.4000 - 0x4003.4000 headers space (192KiB)
|
|
||||||
* 0x4000.4030 bin_hdr start address
|
|
||||||
* 0x4003.4000 - 0x4004.7c00 BootROM memory allocations (15KiB)
|
|
||||||
* 0x4007.fffc BootROM stack top
|
|
||||||
*
|
|
||||||
* The address space between 0x4007.fffc and 0x400f.fff is not locked in
|
|
||||||
* L2 cache thus cannot be used.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* SPL */
|
/* SPL */
|
||||||
/* Defines for SPL */
|
/* Defines for SPL */
|
||||||
#define CONFIG_SPL_MAX_SIZE ((128 << 10) - 0x4030)
|
#define CONFIG_SPL_MAX_SIZE ((128 << 10) - (CONFIG_SPL_TEXT_BASE - 0x40000000))
|
||||||
|
|
||||||
#define CONFIG_SPL_BSS_START_ADDR (0x40000000 + (128 << 10))
|
#define CONFIG_SPL_BSS_START_ADDR (0x40000000 + (128 << 10))
|
||||||
#define CONFIG_SPL_BSS_MAX_SIZE (16 << 10)
|
#define CONFIG_SPL_BSS_MAX_SIZE (16 << 10)
|
||||||
|
@ -41,7 +41,7 @@
|
|||||||
|
|
||||||
/* Defines for SPL */
|
/* Defines for SPL */
|
||||||
#define CONFIG_SPL_SIZE (140 << 10)
|
#define CONFIG_SPL_SIZE (140 << 10)
|
||||||
#define CONFIG_SPL_MAX_SIZE (CONFIG_SPL_SIZE - 0x0030)
|
#define CONFIG_SPL_MAX_SIZE (CONFIG_SPL_SIZE - (CONFIG_SPL_TEXT_BASE - 0x40000000))
|
||||||
|
|
||||||
#define CONFIG_SPL_BSS_START_ADDR (0x40000000 + CONFIG_SPL_SIZE)
|
#define CONFIG_SPL_BSS_START_ADDR (0x40000000 + CONFIG_SPL_SIZE)
|
||||||
#define CONFIG_SPL_BSS_MAX_SIZE (16 << 10)
|
#define CONFIG_SPL_BSS_MAX_SIZE (16 << 10)
|
||||||
|
@ -50,7 +50,7 @@
|
|||||||
|
|
||||||
/* Defines for SPL */
|
/* Defines for SPL */
|
||||||
#define CONFIG_SPL_SIZE (140 << 10)
|
#define CONFIG_SPL_SIZE (140 << 10)
|
||||||
#define CONFIG_SPL_MAX_SIZE (CONFIG_SPL_SIZE - 0x0030)
|
#define CONFIG_SPL_MAX_SIZE (CONFIG_SPL_SIZE - (CONFIG_SPL_TEXT_BASE - 0x40000000))
|
||||||
|
|
||||||
#define CONFIG_SPL_BSS_START_ADDR (0x40000000 + CONFIG_SPL_SIZE)
|
#define CONFIG_SPL_BSS_START_ADDR (0x40000000 + CONFIG_SPL_SIZE)
|
||||||
#define CONFIG_SPL_BSS_MAX_SIZE (16 << 10)
|
#define CONFIG_SPL_BSS_MAX_SIZE (16 << 10)
|
||||||
|
@ -59,7 +59,7 @@
|
|||||||
|
|
||||||
/* SPL */
|
/* SPL */
|
||||||
/* Defines for SPL */
|
/* Defines for SPL */
|
||||||
#define CONFIG_SPL_MAX_SIZE ((128 << 10) - 0x4030)
|
#define CONFIG_SPL_MAX_SIZE ((128 << 10) - (CONFIG_SPL_TEXT_BASE - 0x40000000))
|
||||||
|
|
||||||
#define CONFIG_SPL_BSS_START_ADDR (0x40000000 + (128 << 10))
|
#define CONFIG_SPL_BSS_START_ADDR (0x40000000 + (128 << 10))
|
||||||
#define CONFIG_SPL_BSS_MAX_SIZE (16 << 10)
|
#define CONFIG_SPL_BSS_MAX_SIZE (16 << 10)
|
||||||
|
@ -45,7 +45,7 @@
|
|||||||
|
|
||||||
/* SPL */
|
/* SPL */
|
||||||
/* Defines for SPL */
|
/* Defines for SPL */
|
||||||
#define CONFIG_SPL_MAX_SIZE ((128 << 10) - 0x4030)
|
#define CONFIG_SPL_MAX_SIZE ((128 << 10) - (CONFIG_SPL_TEXT_BASE - 0x40000000))
|
||||||
|
|
||||||
#define CONFIG_SPL_BSS_START_ADDR (0x40000000 + (128 << 10))
|
#define CONFIG_SPL_BSS_START_ADDR (0x40000000 + (128 << 10))
|
||||||
#define CONFIG_SPL_BSS_MAX_SIZE (16 << 10)
|
#define CONFIG_SPL_BSS_MAX_SIZE (16 << 10)
|
||||||
|
@ -53,7 +53,7 @@
|
|||||||
|
|
||||||
/* Defines for SPL */
|
/* Defines for SPL */
|
||||||
#define CONFIG_SPL_SIZE (140 << 10)
|
#define CONFIG_SPL_SIZE (140 << 10)
|
||||||
#define CONFIG_SPL_MAX_SIZE (CONFIG_SPL_SIZE - 0x0030)
|
#define CONFIG_SPL_MAX_SIZE (CONFIG_SPL_SIZE - (CONFIG_SPL_TEXT_BASE - 0x40000000))
|
||||||
|
|
||||||
#define CONFIG_SPL_BSS_START_ADDR (0x40000000 + CONFIG_SPL_SIZE)
|
#define CONFIG_SPL_BSS_START_ADDR (0x40000000 + CONFIG_SPL_SIZE)
|
||||||
#define CONFIG_SPL_BSS_MAX_SIZE (16 << 10)
|
#define CONFIG_SPL_BSS_MAX_SIZE (16 << 10)
|
||||||
|
@ -48,7 +48,7 @@
|
|||||||
|
|
||||||
/* SPL */
|
/* SPL */
|
||||||
/* Defines for SPL */
|
/* Defines for SPL */
|
||||||
#define CONFIG_SPL_MAX_SIZE ((128 << 10) - 0x4030)
|
#define CONFIG_SPL_MAX_SIZE ((128 << 10) - (CONFIG_SPL_TEXT_BASE - 0x40000000))
|
||||||
|
|
||||||
#define CONFIG_SPL_BSS_START_ADDR (0x40000000 + (128 << 10))
|
#define CONFIG_SPL_BSS_START_ADDR (0x40000000 + (128 << 10))
|
||||||
#define CONFIG_SPL_BSS_MAX_SIZE (16 << 10)
|
#define CONFIG_SPL_BSS_MAX_SIZE (16 << 10)
|
||||||
|
@ -77,7 +77,7 @@
|
|||||||
|
|
||||||
/* SPL */
|
/* SPL */
|
||||||
/* Defines for SPL */
|
/* Defines for SPL */
|
||||||
#define CONFIG_SPL_MAX_SIZE ((128 << 10) - 0x4030)
|
#define CONFIG_SPL_MAX_SIZE ((128 << 10) - (CONFIG_SPL_TEXT_BASE - 0x40000000))
|
||||||
|
|
||||||
#define CONFIG_SPL_BSS_START_ADDR (0x40000000 + (128 << 10))
|
#define CONFIG_SPL_BSS_START_ADDR (0x40000000 + (128 << 10))
|
||||||
#define CONFIG_SPL_BSS_MAX_SIZE (16 << 10)
|
#define CONFIG_SPL_BSS_MAX_SIZE (16 << 10)
|
||||||
|
@ -28,7 +28,7 @@
|
|||||||
|
|
||||||
/* Defines for SPL */
|
/* Defines for SPL */
|
||||||
#define CONFIG_SPL_SIZE (140 << 10)
|
#define CONFIG_SPL_SIZE (140 << 10)
|
||||||
#define CONFIG_SPL_MAX_SIZE (CONFIG_SPL_SIZE - 0x0030)
|
#define CONFIG_SPL_MAX_SIZE (CONFIG_SPL_SIZE - (CONFIG_SPL_TEXT_BASE - 0x40000000))
|
||||||
|
|
||||||
#define CONFIG_SPL_BSS_START_ADDR (0x40000000 + CONFIG_SPL_SIZE)
|
#define CONFIG_SPL_BSS_START_ADDR (0x40000000 + CONFIG_SPL_SIZE)
|
||||||
#define CONFIG_SPL_BSS_MAX_SIZE (16 << 10)
|
#define CONFIG_SPL_BSS_MAX_SIZE (16 << 10)
|
||||||
|
@ -68,7 +68,7 @@
|
|||||||
|
|
||||||
/* Defines for SPL */
|
/* Defines for SPL */
|
||||||
#define CONFIG_SPL_SIZE (140 << 10)
|
#define CONFIG_SPL_SIZE (140 << 10)
|
||||||
#define CONFIG_SPL_MAX_SIZE (CONFIG_SPL_SIZE - 0x0030)
|
#define CONFIG_SPL_MAX_SIZE (CONFIG_SPL_SIZE - (CONFIG_SPL_TEXT_BASE - 0x40000000))
|
||||||
|
|
||||||
#define CONFIG_SPL_BSS_START_ADDR (0x40000000 + CONFIG_SPL_SIZE)
|
#define CONFIG_SPL_BSS_START_ADDR (0x40000000 + CONFIG_SPL_SIZE)
|
||||||
#define CONFIG_SPL_BSS_MAX_SIZE (16 << 10)
|
#define CONFIG_SPL_BSS_MAX_SIZE (16 << 10)
|
||||||
|
503
tools/kwbimage.c
503
tools/kwbimage.c
@ -99,6 +99,7 @@ enum image_cfg_type {
|
|||||||
IMAGE_CFG_NAND_BADBLK_LOCATION,
|
IMAGE_CFG_NAND_BADBLK_LOCATION,
|
||||||
IMAGE_CFG_NAND_ECC_MODE,
|
IMAGE_CFG_NAND_ECC_MODE,
|
||||||
IMAGE_CFG_NAND_PAGESZ,
|
IMAGE_CFG_NAND_PAGESZ,
|
||||||
|
IMAGE_CFG_CPU,
|
||||||
IMAGE_CFG_BINARY,
|
IMAGE_CFG_BINARY,
|
||||||
IMAGE_CFG_DATA,
|
IMAGE_CFG_DATA,
|
||||||
IMAGE_CFG_DATA_DELAY,
|
IMAGE_CFG_DATA_DELAY,
|
||||||
@ -129,6 +130,7 @@ static const char * const id_strs[] = {
|
|||||||
[IMAGE_CFG_NAND_BADBLK_LOCATION] = "NAND_BADBLK_LOCATION",
|
[IMAGE_CFG_NAND_BADBLK_LOCATION] = "NAND_BADBLK_LOCATION",
|
||||||
[IMAGE_CFG_NAND_ECC_MODE] = "NAND_ECC_MODE",
|
[IMAGE_CFG_NAND_ECC_MODE] = "NAND_ECC_MODE",
|
||||||
[IMAGE_CFG_NAND_PAGESZ] = "NAND_PAGE_SIZE",
|
[IMAGE_CFG_NAND_PAGESZ] = "NAND_PAGE_SIZE",
|
||||||
|
[IMAGE_CFG_CPU] = "CPU",
|
||||||
[IMAGE_CFG_BINARY] = "BINARY",
|
[IMAGE_CFG_BINARY] = "BINARY",
|
||||||
[IMAGE_CFG_DATA] = "DATA",
|
[IMAGE_CFG_DATA] = "DATA",
|
||||||
[IMAGE_CFG_DATA_DELAY] = "DATA_DELAY",
|
[IMAGE_CFG_DATA_DELAY] = "DATA_DELAY",
|
||||||
@ -152,9 +154,11 @@ struct image_cfg_element {
|
|||||||
enum image_cfg_type type;
|
enum image_cfg_type type;
|
||||||
union {
|
union {
|
||||||
unsigned int version;
|
unsigned int version;
|
||||||
|
unsigned int cpu_sheeva;
|
||||||
unsigned int bootfrom;
|
unsigned int bootfrom;
|
||||||
struct {
|
struct {
|
||||||
const char *file;
|
const char *file;
|
||||||
|
unsigned int loadaddr;
|
||||||
unsigned int args[BINARY_MAX_ARGS];
|
unsigned int args[BINARY_MAX_ARGS];
|
||||||
unsigned int nargs;
|
unsigned int nargs;
|
||||||
} binary;
|
} binary;
|
||||||
@ -199,7 +203,7 @@ static const char *image_boot_mode_name(unsigned int id)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
int image_boot_mode_id(const char *boot_mode_name)
|
static int image_boot_mode_id(const char *boot_mode_name)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
@ -210,7 +214,18 @@ int image_boot_mode_id(const char *boot_mode_name)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int image_nand_ecc_mode_id(const char *nand_ecc_mode_name)
|
static const char *image_nand_ecc_mode_name(unsigned int id)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; nand_ecc_modes[i].name; i++)
|
||||||
|
if (nand_ecc_modes[i].id == id)
|
||||||
|
return nand_ecc_modes[i].name;
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int image_nand_ecc_mode_id(const char *nand_ecc_mode_name)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
@ -280,6 +295,17 @@ static int image_get_bootfrom(void)
|
|||||||
return e->bootfrom;
|
return e->bootfrom;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int image_is_cpu_sheeva(void)
|
||||||
|
{
|
||||||
|
struct image_cfg_element *e;
|
||||||
|
|
||||||
|
e = image_find_option(IMAGE_CFG_CPU);
|
||||||
|
if (!e)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return e->cpu_sheeva;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Compute a 8-bit checksum of a memory area. This algorithm follows
|
* Compute a 8-bit checksum of a memory area. This algorithm follows
|
||||||
* the requirements of the Marvell SoC BootROM specifications.
|
* the requirements of the Marvell SoC BootROM specifications.
|
||||||
@ -344,6 +370,29 @@ static uint32_t image_checksum32(void *start, uint32_t len)
|
|||||||
return csum;
|
return csum;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static unsigned int options_to_baudrate(uint8_t options)
|
||||||
|
{
|
||||||
|
switch (options & 0x7) {
|
||||||
|
case MAIN_HDR_V1_OPT_BAUD_2400:
|
||||||
|
return 2400;
|
||||||
|
case MAIN_HDR_V1_OPT_BAUD_4800:
|
||||||
|
return 4800;
|
||||||
|
case MAIN_HDR_V1_OPT_BAUD_9600:
|
||||||
|
return 9600;
|
||||||
|
case MAIN_HDR_V1_OPT_BAUD_19200:
|
||||||
|
return 19200;
|
||||||
|
case MAIN_HDR_V1_OPT_BAUD_38400:
|
||||||
|
return 38400;
|
||||||
|
case MAIN_HDR_V1_OPT_BAUD_57600:
|
||||||
|
return 57600;
|
||||||
|
case MAIN_HDR_V1_OPT_BAUD_115200:
|
||||||
|
return 115200;
|
||||||
|
case MAIN_HDR_V1_OPT_BAUD_DEFAULT:
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static uint8_t baudrate_to_option(unsigned int baudrate)
|
static uint8_t baudrate_to_option(unsigned int baudrate)
|
||||||
{
|
{
|
||||||
switch (baudrate) {
|
switch (baudrate) {
|
||||||
@ -602,7 +651,8 @@ static int kwb_export_pubkey(RSA *key, struct pubkey_der_v1 *dst, FILE *hashf,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int kwb_sign(RSA *key, void *data, int datasz, struct sig_v1 *sig, char *signame)
|
static int kwb_sign(RSA *key, void *data, int datasz, struct sig_v1 *sig,
|
||||||
|
char *signame)
|
||||||
{
|
{
|
||||||
EVP_PKEY *evp_key;
|
EVP_PKEY *evp_key;
|
||||||
EVP_MD_CTX *ctx;
|
EVP_MD_CTX *ctx;
|
||||||
@ -662,7 +712,7 @@ err_key:
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int kwb_verify(RSA *key, void *data, int datasz, struct sig_v1 *sig,
|
static int kwb_verify(RSA *key, void *data, int datasz, struct sig_v1 *sig,
|
||||||
char *signame)
|
char *signame)
|
||||||
{
|
{
|
||||||
EVP_PKEY *evp_key;
|
EVP_PKEY *evp_key;
|
||||||
@ -722,8 +772,8 @@ err_key:
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int kwb_sign_and_verify(RSA *key, void *data, int datasz, struct sig_v1 *sig,
|
static int kwb_sign_and_verify(RSA *key, void *data, int datasz,
|
||||||
char *signame)
|
struct sig_v1 *sig, char *signame)
|
||||||
{
|
{
|
||||||
if (kwb_sign(key, data, datasz, sig, signame) < 0)
|
if (kwb_sign(key, data, datasz, sig, signame) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
@ -735,7 +785,7 @@ int kwb_sign_and_verify(RSA *key, void *data, int datasz, struct sig_v1 *sig,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int kwb_dump_fuse_cmds_38x(FILE *out, struct secure_hdr_v1 *sec_hdr)
|
static int kwb_dump_fuse_cmds_38x(FILE *out, struct secure_hdr_v1 *sec_hdr)
|
||||||
{
|
{
|
||||||
struct hash_v1 kak_pub_hash;
|
struct hash_v1 kak_pub_hash;
|
||||||
struct image_cfg_element *e;
|
struct image_cfg_element *e;
|
||||||
@ -992,10 +1042,13 @@ static void *image_create_v0(size_t *imagesz, struct image_tool_params *params,
|
|||||||
|
|
||||||
static size_t image_headersz_v1(int *hasext)
|
static size_t image_headersz_v1(int *hasext)
|
||||||
{
|
{
|
||||||
struct image_cfg_element *binarye;
|
struct image_cfg_element *e;
|
||||||
unsigned int count;
|
unsigned int count;
|
||||||
size_t headersz;
|
size_t headersz;
|
||||||
|
int cpu_sheeva;
|
||||||
|
struct stat s;
|
||||||
int cfgi;
|
int cfgi;
|
||||||
|
int ret;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Calculate the size of the header and the size of the
|
* Calculate the size of the header and the size of the
|
||||||
@ -1009,19 +1062,25 @@ static size_t image_headersz_v1(int *hasext)
|
|||||||
*hasext = 1;
|
*hasext = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
count = image_count_options(IMAGE_CFG_DATA);
|
cpu_sheeva = image_is_cpu_sheeva();
|
||||||
if (count > 0)
|
|
||||||
headersz += sizeof(struct register_set_hdr_v1) + 8 * count + 4;
|
|
||||||
|
|
||||||
|
count = 0;
|
||||||
for (cfgi = 0; cfgi < cfgn; cfgi++) {
|
for (cfgi = 0; cfgi < cfgn; cfgi++) {
|
||||||
int ret;
|
e = &image_cfg[cfgi];
|
||||||
struct stat s;
|
|
||||||
|
|
||||||
binarye = &image_cfg[cfgi];
|
if (e->type == IMAGE_CFG_DATA)
|
||||||
if (binarye->type != IMAGE_CFG_BINARY)
|
count++;
|
||||||
|
|
||||||
|
if (e->type == IMAGE_CFG_DATA_DELAY ||
|
||||||
|
(e->type == IMAGE_CFG_BINARY && count > 0)) {
|
||||||
|
headersz += sizeof(struct register_set_hdr_v1) + 8 * count + 4;
|
||||||
|
count = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (e->type != IMAGE_CFG_BINARY)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
ret = stat(binarye->binary.file, &s);
|
ret = stat(e->binary.file, &s);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
char cwd[PATH_MAX];
|
char cwd[PATH_MAX];
|
||||||
char *dir = cwd;
|
char *dir = cwd;
|
||||||
@ -1036,30 +1095,74 @@ static size_t image_headersz_v1(int *hasext)
|
|||||||
"Didn't find the file '%s' in '%s' which is mandatory to generate the image\n"
|
"Didn't find the file '%s' in '%s' which is mandatory to generate the image\n"
|
||||||
"This file generally contains the DDR3 training code, and should be extracted from an existing bootable\n"
|
"This file generally contains the DDR3 training code, and should be extracted from an existing bootable\n"
|
||||||
"image for your board. Use 'dumpimage -T kwbimage -p 0' to extract it from an existing image.\n",
|
"image for your board. Use 'dumpimage -T kwbimage -p 0' to extract it from an existing image.\n",
|
||||||
binarye->binary.file, dir);
|
e->binary.file, dir);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
headersz += sizeof(struct opt_hdr_v1) + sizeof(uint32_t) +
|
headersz += sizeof(struct opt_hdr_v1) + sizeof(uint32_t) +
|
||||||
(binarye->binary.nargs) * sizeof(uint32_t);
|
(e->binary.nargs) * sizeof(uint32_t);
|
||||||
|
|
||||||
|
if (e->binary.loadaddr) {
|
||||||
|
/*
|
||||||
|
* BootROM loads kwbimage header (in which the
|
||||||
|
* executable code is also stored) to address
|
||||||
|
* 0x40004000 or 0x40000000. Thus there is
|
||||||
|
* restriction for the load address of the N-th
|
||||||
|
* BINARY image.
|
||||||
|
*/
|
||||||
|
unsigned int base_addr, low_addr, high_addr;
|
||||||
|
|
||||||
|
base_addr = cpu_sheeva ? 0x40004000 : 0x40000000;
|
||||||
|
low_addr = base_addr + headersz;
|
||||||
|
high_addr = low_addr +
|
||||||
|
(BINARY_MAX_ARGS - e->binary.nargs) * sizeof(uint32_t);
|
||||||
|
|
||||||
|
if (cpu_sheeva && e->binary.loadaddr % 16) {
|
||||||
|
fprintf(stderr,
|
||||||
|
"Invalid LOAD_ADDRESS 0x%08x for BINARY %s with %d args.\n"
|
||||||
|
"Address for CPU SHEEVA must be 16-byte aligned.\n",
|
||||||
|
e->binary.loadaddr, e->binary.file, e->binary.nargs);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (e->binary.loadaddr % 4 || e->binary.loadaddr < low_addr ||
|
||||||
|
e->binary.loadaddr > high_addr) {
|
||||||
|
fprintf(stderr,
|
||||||
|
"Invalid LOAD_ADDRESS 0x%08x for BINARY %s with %d args.\n"
|
||||||
|
"Address must be 4-byte aligned and in range 0x%08x-0x%08x.\n",
|
||||||
|
e->binary.loadaddr, e->binary.file,
|
||||||
|
e->binary.nargs, low_addr, high_addr);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
headersz = e->binary.loadaddr - base_addr;
|
||||||
|
} else if (cpu_sheeva) {
|
||||||
headersz = ALIGN(headersz, 16);
|
headersz = ALIGN(headersz, 16);
|
||||||
|
} else {
|
||||||
|
headersz = ALIGN(headersz, 4);
|
||||||
|
}
|
||||||
|
|
||||||
headersz += ALIGN(s.st_size, 4) + sizeof(uint32_t);
|
headersz += ALIGN(s.st_size, 4) + sizeof(uint32_t);
|
||||||
if (hasext)
|
if (hasext)
|
||||||
*hasext = 1;
|
*hasext = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (count > 0)
|
||||||
|
headersz += sizeof(struct register_set_hdr_v1) + 8 * count + 4;
|
||||||
|
|
||||||
return image_headersz_align(headersz, image_get_bootfrom());
|
return image_headersz_align(headersz, image_get_bootfrom());
|
||||||
}
|
}
|
||||||
|
|
||||||
int add_binary_header_v1(uint8_t **cur, uint8_t **next_ext,
|
static int add_binary_header_v1(uint8_t **cur, uint8_t **next_ext,
|
||||||
struct image_cfg_element *binarye,
|
struct image_cfg_element *binarye,
|
||||||
struct main_hdr_v1 *main_hdr)
|
struct main_hdr_v1 *main_hdr)
|
||||||
{
|
{
|
||||||
struct opt_hdr_v1 *hdr = (struct opt_hdr_v1 *)*cur;
|
struct opt_hdr_v1 *hdr = (struct opt_hdr_v1 *)*cur;
|
||||||
|
uint32_t base_addr;
|
||||||
uint32_t add_args;
|
uint32_t add_args;
|
||||||
uint32_t offset;
|
uint32_t offset;
|
||||||
uint32_t *args;
|
uint32_t *args;
|
||||||
size_t binhdrsz;
|
size_t binhdrsz;
|
||||||
|
int cpu_sheeva;
|
||||||
struct stat s;
|
struct stat s;
|
||||||
int argi;
|
int argi;
|
||||||
FILE *bin;
|
FILE *bin;
|
||||||
@ -1091,13 +1194,22 @@ int add_binary_header_v1(uint8_t **cur, uint8_t **next_ext,
|
|||||||
*cur += (binarye->binary.nargs + 1) * sizeof(uint32_t);
|
*cur += (binarye->binary.nargs + 1) * sizeof(uint32_t);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ARM executable code inside the BIN header on some mvebu platforms
|
* ARM executable code inside the BIN header on platforms with Sheeva
|
||||||
* (e.g. A370, AXP) must always be aligned with the 128-bit boundary.
|
* CPU (A370 and AXP) must always be aligned with the 128-bit boundary.
|
||||||
|
* In the case when this code is not position independent (e.g. ARM
|
||||||
|
* SPL), it must be placed at fixed load and execute address.
|
||||||
* This requirement can be met by inserting dummy arguments into
|
* This requirement can be met by inserting dummy arguments into
|
||||||
* BIN header, if needed.
|
* BIN header, if needed.
|
||||||
*/
|
*/
|
||||||
|
cpu_sheeva = image_is_cpu_sheeva();
|
||||||
|
base_addr = cpu_sheeva ? 0x40004000 : 0x40000000;
|
||||||
offset = *cur - (uint8_t *)main_hdr;
|
offset = *cur - (uint8_t *)main_hdr;
|
||||||
|
if (binarye->binary.loadaddr)
|
||||||
|
add_args = (binarye->binary.loadaddr - base_addr - offset) / sizeof(uint32_t);
|
||||||
|
else if (cpu_sheeva)
|
||||||
add_args = ((16 - offset % 16) % 16) / sizeof(uint32_t);
|
add_args = ((16 - offset % 16) % 16) / sizeof(uint32_t);
|
||||||
|
else
|
||||||
|
add_args = 0;
|
||||||
if (add_args) {
|
if (add_args) {
|
||||||
*(args - 1) = cpu_to_le32(binarye->binary.nargs + add_args);
|
*(args - 1) = cpu_to_le32(binarye->binary.nargs + add_args);
|
||||||
*cur += add_args * sizeof(uint32_t);
|
*cur += add_args * sizeof(uint32_t);
|
||||||
@ -1135,7 +1247,7 @@ err_close:
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int export_pub_kak_hash(RSA *kak, struct secure_hdr_v1 *secure_hdr)
|
static int export_pub_kak_hash(RSA *kak, struct secure_hdr_v1 *secure_hdr)
|
||||||
{
|
{
|
||||||
FILE *hashf;
|
FILE *hashf;
|
||||||
int res;
|
int res;
|
||||||
@ -1154,7 +1266,7 @@ int export_pub_kak_hash(RSA *kak, struct secure_hdr_v1 *secure_hdr)
|
|||||||
return res < 0 ? 1 : 0;
|
return res < 0 ? 1 : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int kwb_sign_csk_with_kak(struct image_tool_params *params,
|
static int kwb_sign_csk_with_kak(struct image_tool_params *params,
|
||||||
struct secure_hdr_v1 *secure_hdr, RSA *csk)
|
struct secure_hdr_v1 *secure_hdr, RSA *csk)
|
||||||
{
|
{
|
||||||
RSA *kak = NULL;
|
RSA *kak = NULL;
|
||||||
@ -1196,7 +1308,7 @@ int kwb_sign_csk_with_kak(struct image_tool_params *params,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int add_secure_header_v1(struct image_tool_params *params, uint8_t *ptr,
|
static int add_secure_header_v1(struct image_tool_params *params, uint8_t *ptr,
|
||||||
int payloadsz, size_t headersz, uint8_t *image,
|
int payloadsz, size_t headersz, uint8_t *image,
|
||||||
struct secure_hdr_v1 *secure_hdr)
|
struct secure_hdr_v1 *secure_hdr)
|
||||||
{
|
{
|
||||||
@ -1248,6 +1360,22 @@ int add_secure_header_v1(struct image_tool_params *params, uint8_t *ptr,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void finish_register_set_header_v1(uint8_t **cur, uint8_t **next_ext,
|
||||||
|
struct register_set_hdr_v1 *register_set_hdr,
|
||||||
|
int *datai, uint8_t delay)
|
||||||
|
{
|
||||||
|
int size = sizeof(struct register_set_hdr_v1) + 8 * (*datai) + 4;
|
||||||
|
|
||||||
|
register_set_hdr->headertype = OPT_HDR_V1_REGISTER_TYPE;
|
||||||
|
register_set_hdr->headersz_lsb = cpu_to_le16(size & 0xFFFF);
|
||||||
|
register_set_hdr->headersz_msb = size >> 16;
|
||||||
|
register_set_hdr->data[*datai].last_entry.delay = delay;
|
||||||
|
*cur += size;
|
||||||
|
**next_ext = 1;
|
||||||
|
*next_ext = ®ister_set_hdr->data[*datai].last_entry.next;
|
||||||
|
*datai = 0;
|
||||||
|
}
|
||||||
|
|
||||||
static void *image_create_v1(size_t *imagesz, struct image_tool_params *params,
|
static void *image_create_v1(size_t *imagesz, struct image_tool_params *params,
|
||||||
uint8_t *ptr, int payloadsz)
|
uint8_t *ptr, int payloadsz)
|
||||||
{
|
{
|
||||||
@ -1260,7 +1388,8 @@ static void *image_create_v1(size_t *imagesz, struct image_tool_params *params,
|
|||||||
uint8_t *image, *cur;
|
uint8_t *image, *cur;
|
||||||
int hasext = 0;
|
int hasext = 0;
|
||||||
uint8_t *next_ext = NULL;
|
uint8_t *next_ext = NULL;
|
||||||
int cfgi, datai, size;
|
int cfgi, datai;
|
||||||
|
uint8_t delay;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Calculate the size of the header and the size of the
|
* Calculate the size of the header and the size of the
|
||||||
@ -1351,50 +1480,54 @@ static void *image_create_v1(size_t *imagesz, struct image_tool_params *params,
|
|||||||
}
|
}
|
||||||
|
|
||||||
datai = 0;
|
datai = 0;
|
||||||
register_set_hdr = (struct register_set_hdr_v1 *)cur;
|
|
||||||
for (cfgi = 0; cfgi < cfgn; cfgi++) {
|
for (cfgi = 0; cfgi < cfgn; cfgi++) {
|
||||||
e = &image_cfg[cfgi];
|
e = &image_cfg[cfgi];
|
||||||
if (e->type != IMAGE_CFG_DATA &&
|
if (e->type != IMAGE_CFG_DATA &&
|
||||||
e->type != IMAGE_CFG_DATA_DELAY)
|
e->type != IMAGE_CFG_DATA_DELAY &&
|
||||||
|
e->type != IMAGE_CFG_BINARY)
|
||||||
continue;
|
continue;
|
||||||
if (e->type == IMAGE_CFG_DATA_DELAY) {
|
|
||||||
size = sizeof(struct register_set_hdr_v1) + 8 * datai + 4;
|
if (datai == 0)
|
||||||
register_set_hdr->headertype = OPT_HDR_V1_REGISTER_TYPE;
|
register_set_hdr = (struct register_set_hdr_v1 *)cur;
|
||||||
register_set_hdr->headersz_lsb = cpu_to_le16(size & 0xFFFF);
|
|
||||||
register_set_hdr->headersz_msb = size >> 16;
|
/* If delay is not specified, use the smallest possible value. */
|
||||||
register_set_hdr->data[datai].last_entry.delay = e->regdata_delay;
|
if (e->type == IMAGE_CFG_DATA_DELAY)
|
||||||
cur += size;
|
delay = e->regdata_delay;
|
||||||
*next_ext = 1;
|
else
|
||||||
next_ext = ®ister_set_hdr->data[datai].last_entry.next;
|
delay = REGISTER_SET_HDR_OPT_DELAY_MS(0);
|
||||||
datai = 0;
|
|
||||||
continue;
|
/*
|
||||||
}
|
* DATA_DELAY command is the last entry in the register set
|
||||||
|
* header and BINARY command inserts new binary header.
|
||||||
|
* Therefore BINARY command requires to finish register set
|
||||||
|
* header if some DATA command was specified. And DATA_DELAY
|
||||||
|
* command automatically finish register set header even when
|
||||||
|
* there was no DATA command.
|
||||||
|
*/
|
||||||
|
if (e->type == IMAGE_CFG_DATA_DELAY ||
|
||||||
|
(e->type == IMAGE_CFG_BINARY && datai != 0))
|
||||||
|
finish_register_set_header_v1(&cur, &next_ext, register_set_hdr,
|
||||||
|
&datai, delay);
|
||||||
|
|
||||||
|
if (e->type == IMAGE_CFG_DATA) {
|
||||||
register_set_hdr->data[datai].entry.address =
|
register_set_hdr->data[datai].entry.address =
|
||||||
cpu_to_le32(e->regdata.raddr);
|
cpu_to_le32(e->regdata.raddr);
|
||||||
register_set_hdr->data[datai].entry.value =
|
register_set_hdr->data[datai].entry.value =
|
||||||
cpu_to_le32(e->regdata.rdata);
|
cpu_to_le32(e->regdata.rdata);
|
||||||
datai++;
|
datai++;
|
||||||
}
|
}
|
||||||
if (datai != 0) {
|
|
||||||
size = sizeof(struct register_set_hdr_v1) + 8 * datai + 4;
|
|
||||||
register_set_hdr->headertype = OPT_HDR_V1_REGISTER_TYPE;
|
|
||||||
register_set_hdr->headersz_lsb = cpu_to_le16(size & 0xFFFF);
|
|
||||||
register_set_hdr->headersz_msb = size >> 16;
|
|
||||||
/* Set delay to the smallest possible value 1ms. */
|
|
||||||
register_set_hdr->data[datai].last_entry.delay = 1;
|
|
||||||
cur += size;
|
|
||||||
*next_ext = 1;
|
|
||||||
next_ext = ®ister_set_hdr->data[datai].last_entry.next;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (cfgi = 0; cfgi < cfgn; cfgi++) {
|
|
||||||
e = &image_cfg[cfgi];
|
|
||||||
if (e->type != IMAGE_CFG_BINARY)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
|
if (e->type == IMAGE_CFG_BINARY) {
|
||||||
if (add_binary_header_v1(&cur, &next_ext, e, main_hdr))
|
if (add_binary_header_v1(&cur, &next_ext, e, main_hdr))
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
if (datai != 0) {
|
||||||
|
/* Set delay to the smallest possible value. */
|
||||||
|
delay = REGISTER_SET_HDR_OPT_DELAY_MS(0);
|
||||||
|
finish_register_set_header_v1(&cur, &next_ext, register_set_hdr,
|
||||||
|
&datai, delay);
|
||||||
|
}
|
||||||
|
|
||||||
if (secure_hdr && add_secure_header_v1(params, ptr, payloadsz + headersz,
|
if (secure_hdr && add_secure_header_v1(params, ptr, payloadsz + headersz,
|
||||||
headersz, image, secure_hdr))
|
headersz, image, secure_hdr))
|
||||||
@ -1415,7 +1548,7 @@ static void *image_create_v1(size_t *imagesz, struct image_tool_params *params,
|
|||||||
return image;
|
return image;
|
||||||
}
|
}
|
||||||
|
|
||||||
int recognize_keyword(char *keyword)
|
static int recognize_keyword(char *keyword)
|
||||||
{
|
{
|
||||||
int kw_id;
|
int kw_id;
|
||||||
|
|
||||||
@ -1455,6 +1588,18 @@ static int image_create_config_parse_oneline(char *line,
|
|||||||
case IMAGE_CFG_VERSION:
|
case IMAGE_CFG_VERSION:
|
||||||
el->version = atoi(value1);
|
el->version = atoi(value1);
|
||||||
break;
|
break;
|
||||||
|
case IMAGE_CFG_CPU:
|
||||||
|
if (strcmp(value1, "FEROCEON") == 0)
|
||||||
|
el->cpu_sheeva = 0;
|
||||||
|
else if (strcmp(value1, "SHEEVA") == 0)
|
||||||
|
el->cpu_sheeva = 1;
|
||||||
|
else if (strcmp(value1, "A9") == 0)
|
||||||
|
el->cpu_sheeva = 0;
|
||||||
|
else {
|
||||||
|
fprintf(stderr, "Invalid CPU %s\n", value1);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
case IMAGE_CFG_BOOT_FROM:
|
case IMAGE_CFG_BOOT_FROM:
|
||||||
ret = image_boot_mode_id(value1);
|
ret = image_boot_mode_id(value1);
|
||||||
|
|
||||||
@ -1488,10 +1633,40 @@ static int image_create_config_parse_oneline(char *line,
|
|||||||
el->binary.file = strdup(value1);
|
el->binary.file = strdup(value1);
|
||||||
while (1) {
|
while (1) {
|
||||||
char *value = strtok_r(NULL, delimiters, &saveptr);
|
char *value = strtok_r(NULL, delimiters, &saveptr);
|
||||||
|
char *endptr;
|
||||||
|
|
||||||
if (!value)
|
if (!value)
|
||||||
break;
|
break;
|
||||||
el->binary.args[argi] = strtoul(value, NULL, 16);
|
|
||||||
|
if (!strcmp(value, "LOAD_ADDRESS")) {
|
||||||
|
value = strtok_r(NULL, delimiters, &saveptr);
|
||||||
|
if (!value) {
|
||||||
|
fprintf(stderr,
|
||||||
|
"Missing address argument for BINARY LOAD_ADDRESS\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
el->binary.loadaddr = strtoul(value, &endptr, 16);
|
||||||
|
if (*endptr) {
|
||||||
|
fprintf(stderr,
|
||||||
|
"Invalid argument '%s' for BINARY LOAD_ADDRESS\n",
|
||||||
|
value);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
value = strtok_r(NULL, delimiters, &saveptr);
|
||||||
|
if (value) {
|
||||||
|
fprintf(stderr,
|
||||||
|
"Unexpected argument '%s' after BINARY LOAD_ADDRESS\n",
|
||||||
|
value);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
el->binary.args[argi] = strtoul(value, &endptr, 16);
|
||||||
|
if (*endptr) {
|
||||||
|
fprintf(stderr, "Invalid argument '%s' for BINARY\n", value);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
argi++;
|
argi++;
|
||||||
if (argi >= BINARY_MAX_ARGS) {
|
if (argi >= BINARY_MAX_ARGS) {
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
@ -1518,6 +1693,10 @@ static int image_create_config_parse_oneline(char *line,
|
|||||||
el->regdata_delay = REGISTER_SET_HDR_OPT_DELAY_SDRAM_SETUP;
|
el->regdata_delay = REGISTER_SET_HDR_OPT_DELAY_SDRAM_SETUP;
|
||||||
else
|
else
|
||||||
el->regdata_delay = REGISTER_SET_HDR_OPT_DELAY_MS(strtoul(value1, NULL, 10));
|
el->regdata_delay = REGISTER_SET_HDR_OPT_DELAY_MS(strtoul(value1, NULL, 10));
|
||||||
|
if (el->regdata_delay > 255) {
|
||||||
|
fprintf(stderr, "Maximal DATA_DELAY is 255\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case IMAGE_CFG_BAUDRATE:
|
case IMAGE_CFG_BAUDRATE:
|
||||||
el->baudrate = strtoul(value1, NULL, 10);
|
el->baudrate = strtoul(value1, NULL, 10);
|
||||||
@ -1727,9 +1906,12 @@ static void kwbimage_print_header(const void *ptr)
|
|||||||
|
|
||||||
for_each_opt_hdr_v1 (ohdr, mhdr) {
|
for_each_opt_hdr_v1 (ohdr, mhdr) {
|
||||||
if (ohdr->headertype == OPT_HDR_V1_BINARY_TYPE) {
|
if (ohdr->headertype == OPT_HDR_V1_BINARY_TYPE) {
|
||||||
printf("BIN Hdr Size: ");
|
printf("BIN Img Size: ");
|
||||||
genimg_print_size(opt_hdr_v1_size(ohdr) - 12 -
|
genimg_print_size(opt_hdr_v1_size(ohdr) - 12 -
|
||||||
4 * ohdr->data[0]);
|
4 * ohdr->data[0]);
|
||||||
|
printf("BIN Img Offs: %08x\n",
|
||||||
|
(unsigned)((uint8_t *)ohdr - (uint8_t *)mhdr) +
|
||||||
|
8 + 4 * ohdr->data[0]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1766,7 +1948,7 @@ static int kwbimage_verify_header(unsigned char *ptr, int image_size,
|
|||||||
if (kwbimage_version(ptr) == 0) {
|
if (kwbimage_version(ptr) == 0) {
|
||||||
struct main_hdr_v0 *mhdr = (struct main_hdr_v0 *)ptr;
|
struct main_hdr_v0 *mhdr = (struct main_hdr_v0 *)ptr;
|
||||||
|
|
||||||
if (mhdr->ext & 0x1) {
|
if (mhdr->ext) {
|
||||||
struct ext_hdr_v0 *ext_hdr = (void *)(mhdr + 1);
|
struct ext_hdr_v0 *ext_hdr = (void *)(mhdr + 1);
|
||||||
|
|
||||||
csum = image_checksum8(ext_hdr, sizeof(*ext_hdr) - 1);
|
csum = image_checksum8(ext_hdr, sizeof(*ext_hdr) - 1);
|
||||||
@ -1892,6 +2074,15 @@ static int kwbimage_generate(struct image_tool_params *params,
|
|||||||
|
|
||||||
case 1:
|
case 1:
|
||||||
alloc_len = image_headersz_v1(NULL);
|
alloc_len = image_headersz_v1(NULL);
|
||||||
|
if (!alloc_len) {
|
||||||
|
free(image_cfg);
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
if (alloc_len > 192*1024) {
|
||||||
|
fprintf(stderr, "Header is too big (%u bytes), maximal kwbimage header size is %u bytes\n", alloc_len, 192*1024);
|
||||||
|
free(image_cfg);
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@ -1931,35 +2122,164 @@ static int kwbimage_generate(struct image_tool_params *params,
|
|||||||
return 4 + (4 - s.st_size % 4) % 4;
|
return 4 + (4 - s.st_size % 4) % 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int kwbimage_generate_config(void *ptr, struct image_tool_params *params)
|
||||||
|
{
|
||||||
|
struct main_hdr_v0 *mhdr0 = (struct main_hdr_v0 *)ptr;
|
||||||
|
struct main_hdr_v1 *mhdr = (struct main_hdr_v1 *)ptr;
|
||||||
|
size_t header_size = kwbheader_size(ptr);
|
||||||
|
struct register_set_hdr_v1 *regset_hdr;
|
||||||
|
struct ext_hdr_v0_reg *regdata;
|
||||||
|
struct ext_hdr_v0 *ehdr0;
|
||||||
|
struct opt_hdr_v1 *ohdr;
|
||||||
|
unsigned offset;
|
||||||
|
int cur_idx;
|
||||||
|
int version;
|
||||||
|
FILE *f;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
f = fopen(params->outfile, "w");
|
||||||
|
if (!f) {
|
||||||
|
fprintf(stderr, "Can't open \"%s\": %s\n", params->outfile, strerror(errno));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
version = kwbimage_version(ptr);
|
||||||
|
|
||||||
|
if (version != 0)
|
||||||
|
fprintf(f, "VERSION %d\n", version);
|
||||||
|
|
||||||
|
fprintf(f, "BOOT_FROM %s\n", image_boot_mode_name(mhdr->blockid) ?: "<unknown>");
|
||||||
|
|
||||||
|
if (version == 0 && mhdr->blockid == IBR_HDR_NAND_ID)
|
||||||
|
fprintf(f, "NAND_ECC_MODE %s\n", image_nand_ecc_mode_name(mhdr0->nandeccmode));
|
||||||
|
|
||||||
|
if (mhdr->blockid == IBR_HDR_NAND_ID)
|
||||||
|
fprintf(f, "NAND_PAGE_SIZE 0x%x\n", (unsigned)mhdr->nandpagesize);
|
||||||
|
|
||||||
|
if (version != 0 && mhdr->blockid == IBR_HDR_NAND_ID) {
|
||||||
|
fprintf(f, "NAND_BLKSZ 0x%x\n", (unsigned)mhdr->nandblocksize);
|
||||||
|
fprintf(f, "NAND_BADBLK_LOCATION 0x%x\n", (unsigned)mhdr->nandbadblklocation);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (version == 0 && mhdr->blockid == IBR_HDR_SATA_ID)
|
||||||
|
fprintf(f, "SATA_PIO_MODE %u\n", (unsigned)mhdr0->satapiomode);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Addresses and sizes which are specified by mkimage command line
|
||||||
|
* arguments and not in kwbimage config file
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (version != 0)
|
||||||
|
fprintf(f, "#HEADER_SIZE 0x%x\n",
|
||||||
|
((unsigned)mhdr->headersz_msb << 8) | le16_to_cpu(mhdr->headersz_lsb));
|
||||||
|
|
||||||
|
fprintf(f, "#SRC_ADDRESS 0x%x\n", le32_to_cpu(mhdr->srcaddr));
|
||||||
|
fprintf(f, "#BLOCK_SIZE 0x%x\n", le32_to_cpu(mhdr->blocksize));
|
||||||
|
fprintf(f, "#DEST_ADDRESS 0x%08x\n", le32_to_cpu(mhdr->destaddr));
|
||||||
|
fprintf(f, "#EXEC_ADDRESS 0x%08x\n", le32_to_cpu(mhdr->execaddr));
|
||||||
|
|
||||||
|
if (version != 0) {
|
||||||
|
if (options_to_baudrate(mhdr->options))
|
||||||
|
fprintf(f, "BAUDRATE %u\n", options_to_baudrate(mhdr->options));
|
||||||
|
if (options_to_baudrate(mhdr->options) ||
|
||||||
|
((mhdr->options >> 3) & 0x3) || ((mhdr->options >> 5) & 0x7)) {
|
||||||
|
fprintf(f, "UART_PORT %u\n", (unsigned)((mhdr->options >> 3) & 0x3));
|
||||||
|
fprintf(f, "UART_MPP 0x%x\n", (unsigned)((mhdr->options >> 5) & 0x7));
|
||||||
|
}
|
||||||
|
if (mhdr->flags & 0x1)
|
||||||
|
fprintf(f, "DEBUG 1\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
cur_idx = 1;
|
||||||
|
for_each_opt_hdr_v1(ohdr, ptr) {
|
||||||
|
if (ohdr->headertype == OPT_HDR_V1_SECURE_TYPE) {
|
||||||
|
fprintf(f, "#SECURE_HEADER\n");
|
||||||
|
} else if (ohdr->headertype == OPT_HDR_V1_BINARY_TYPE) {
|
||||||
|
fprintf(f, "BINARY binary%d.bin", cur_idx);
|
||||||
|
for (i = 0; i < ohdr->data[0]; i++)
|
||||||
|
fprintf(f, " 0x%x", le32_to_cpu(((uint32_t *)ohdr->data)[i + 1]));
|
||||||
|
offset = (unsigned)((uint8_t *)ohdr - (uint8_t *)mhdr) + 8 + 4 * ohdr->data[0];
|
||||||
|
fprintf(f, " LOAD_ADDRESS 0x%08x\n", 0x40000000 + offset);
|
||||||
|
fprintf(f, " # for CPU SHEEVA: LOAD_ADDRESS 0x%08x\n", 0x40004000 + offset);
|
||||||
|
cur_idx++;
|
||||||
|
} else if (ohdr->headertype == OPT_HDR_V1_REGISTER_TYPE) {
|
||||||
|
regset_hdr = (struct register_set_hdr_v1 *)ohdr;
|
||||||
|
for (i = 0;
|
||||||
|
i < opt_hdr_v1_size(ohdr) - sizeof(struct opt_hdr_v1) -
|
||||||
|
sizeof(regset_hdr->data[0].last_entry);
|
||||||
|
i++)
|
||||||
|
fprintf(f, "DATA 0x%08x 0x%08x\n",
|
||||||
|
le32_to_cpu(regset_hdr->data[i].entry.address),
|
||||||
|
le32_to_cpu(regset_hdr->data[i].entry.value));
|
||||||
|
if (opt_hdr_v1_size(ohdr) - sizeof(struct opt_hdr_v1) >=
|
||||||
|
sizeof(regset_hdr->data[0].last_entry)) {
|
||||||
|
if (regset_hdr->data[0].last_entry.delay)
|
||||||
|
fprintf(f, "DATA_DELAY %u\n",
|
||||||
|
(unsigned)regset_hdr->data[0].last_entry.delay);
|
||||||
|
else
|
||||||
|
fprintf(f, "DATA_DELAY SDRAM_SETUP\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (version == 0 && mhdr0->ext) {
|
||||||
|
ehdr0 = (struct ext_hdr_v0 *)(mhdr0 + 1);
|
||||||
|
if (ehdr0->offset) {
|
||||||
|
for (regdata = (struct ext_hdr_v0_reg *)((uint8_t *)ptr + ehdr0->offset);
|
||||||
|
(uint8_t *)regdata < (uint8_t *)ptr + header_size && regdata->raddr &&
|
||||||
|
regdata->rdata;
|
||||||
|
regdata++)
|
||||||
|
fprintf(f, "DATA 0x%08x 0x%08x\n", le32_to_cpu(regdata->raddr),
|
||||||
|
le32_to_cpu(regdata->rdata));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (version == 0 && le16_to_cpu(mhdr0->ddrinitdelay))
|
||||||
|
fprintf(f, "DDR_INIT_DELAY %u\n", (unsigned)le16_to_cpu(mhdr0->ddrinitdelay));
|
||||||
|
|
||||||
|
/* Undocumented reserved fields */
|
||||||
|
|
||||||
|
if (version == 0 && (mhdr0->rsvd1[0] || mhdr0->rsvd1[1] || mhdr0->rsvd1[2]))
|
||||||
|
fprintf(f, "#RSVD1 0x%x 0x%x 0x%x\n", (unsigned)mhdr0->rsvd1[0],
|
||||||
|
(unsigned)mhdr0->rsvd1[1], (unsigned)mhdr0->rsvd1[2]);
|
||||||
|
|
||||||
|
if (version == 0 && mhdr0->rsvd3)
|
||||||
|
fprintf(f, "#RSVD3 0x%x\n", (unsigned)mhdr0->rsvd3);
|
||||||
|
|
||||||
|
if (version == 0 && le16_to_cpu(mhdr0->rsvd2))
|
||||||
|
fprintf(f, "#RSVD2 0x%x\n", (unsigned)le16_to_cpu(mhdr0->rsvd2));
|
||||||
|
|
||||||
|
if (version != 0 && mhdr->reserved4)
|
||||||
|
fprintf(f, "#RESERVED4 0x%x\n", (unsigned)mhdr->reserved4);
|
||||||
|
|
||||||
|
if (version != 0 && mhdr->reserved5)
|
||||||
|
fprintf(f, "#RESERVED5 0x%x\n", (unsigned)le16_to_cpu(mhdr->reserved5));
|
||||||
|
|
||||||
|
fclose(f);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int kwbimage_extract_subimage(void *ptr, struct image_tool_params *params)
|
static int kwbimage_extract_subimage(void *ptr, struct image_tool_params *params)
|
||||||
{
|
{
|
||||||
struct main_hdr_v1 *mhdr = (struct main_hdr_v1 *)ptr;
|
struct main_hdr_v1 *mhdr = (struct main_hdr_v1 *)ptr;
|
||||||
size_t header_size = kwbheader_size(ptr);
|
size_t header_size = kwbheader_size(ptr);
|
||||||
struct opt_hdr_v1 *ohdr;
|
struct opt_hdr_v1 *ohdr;
|
||||||
int idx = params->pflag;
|
int idx = params->pflag;
|
||||||
int cur_idx = 0;
|
int cur_idx;
|
||||||
uint32_t offset;
|
uint32_t offset;
|
||||||
ulong image;
|
ulong image;
|
||||||
ulong size;
|
ulong size;
|
||||||
|
|
||||||
for_each_opt_hdr_v1 (ohdr, ptr) {
|
/* Generate kwbimage config file when '-p -1' is specified */
|
||||||
if (ohdr->headertype != OPT_HDR_V1_BINARY_TYPE)
|
if (idx == -1)
|
||||||
continue;
|
return kwbimage_generate_config(ptr, params);
|
||||||
|
|
||||||
if (idx == cur_idx) {
|
image = 0;
|
||||||
image = (ulong)&ohdr->data[4 + 4 * ohdr->data[0]];
|
size = 0;
|
||||||
size = opt_hdr_v1_size(ohdr) - 12 - 4 * ohdr->data[0];
|
|
||||||
goto extract;
|
|
||||||
}
|
|
||||||
|
|
||||||
++cur_idx;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (idx != cur_idx) {
|
|
||||||
printf("Image %d is not present\n", idx);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
if (idx == 0) {
|
||||||
|
/* Extract data image when -p is not specified or when '-p 0' is specified */
|
||||||
offset = le32_to_cpu(mhdr->srcaddr);
|
offset = le32_to_cpu(mhdr->srcaddr);
|
||||||
|
|
||||||
if (mhdr->blockid == IBR_HDR_SATA_ID) {
|
if (mhdr->blockid == IBR_HDR_SATA_ID) {
|
||||||
@ -1975,8 +2295,34 @@ static int kwbimage_extract_subimage(void *ptr, struct image_tool_params *params
|
|||||||
|
|
||||||
image = (ulong)((uint8_t *)ptr + offset);
|
image = (ulong)((uint8_t *)ptr + offset);
|
||||||
size = le32_to_cpu(mhdr->blocksize) - 4;
|
size = le32_to_cpu(mhdr->blocksize) - 4;
|
||||||
|
} else {
|
||||||
|
/* Extract N-th binary header executabe image when other '-p N' is specified */
|
||||||
|
cur_idx = 1;
|
||||||
|
for_each_opt_hdr_v1(ohdr, ptr) {
|
||||||
|
if (ohdr->headertype != OPT_HDR_V1_BINARY_TYPE)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (idx == cur_idx) {
|
||||||
|
image = (ulong)&ohdr->data[4 + 4 * ohdr->data[0]];
|
||||||
|
size = opt_hdr_v1_size(ohdr) - 12 - 4 * ohdr->data[0];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
++cur_idx;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!image) {
|
||||||
|
fprintf(stderr, "Argument -p %d is invalid\n", idx);
|
||||||
|
fprintf(stderr, "Available subimages:\n");
|
||||||
|
fprintf(stderr, " -p -1 - kwbimage config file\n");
|
||||||
|
fprintf(stderr, " -p 0 - data image\n");
|
||||||
|
if (cur_idx - 1 > 0)
|
||||||
|
fprintf(stderr, " -p N - Nth binary header image (totally: %d)\n",
|
||||||
|
cur_idx - 1);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
extract:
|
|
||||||
return imagetool_save_subimage(params->outfile, image, size);
|
return imagetool_save_subimage(params->outfile, image, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1985,7 +2331,8 @@ extract:
|
|||||||
*/
|
*/
|
||||||
static int kwbimage_check_params(struct image_tool_params *params)
|
static int kwbimage_check_params(struct image_tool_params *params)
|
||||||
{
|
{
|
||||||
if (!params->iflag && (!params->imagename || !strlen(params->imagename))) {
|
if (!params->lflag && !params->iflag &&
|
||||||
|
(!params->imagename || !strlen(params->imagename))) {
|
||||||
char *msg = "Configuration file for kwbimage creation omitted";
|
char *msg = "Configuration file for kwbimage creation omitted";
|
||||||
|
|
||||||
fprintf(stderr, "Error:%s - %s\n", params->cmdname, msg);
|
fprintf(stderr, "Error:%s - %s\n", params->cmdname, msg);
|
||||||
|
@ -208,7 +208,7 @@ static inline size_t kwbheader_size(const void *header)
|
|||||||
const struct main_hdr_v0 *hdr = header;
|
const struct main_hdr_v0 *hdr = header;
|
||||||
|
|
||||||
return sizeof(*hdr) +
|
return sizeof(*hdr) +
|
||||||
(hdr->ext & 0x1) ? sizeof(struct ext_hdr_v0) : 0;
|
hdr->ext ? sizeof(struct ext_hdr_v0) : 0;
|
||||||
} else {
|
} else {
|
||||||
const struct main_hdr_v1 *hdr = header;
|
const struct main_hdr_v1 *hdr = header;
|
||||||
|
|
||||||
@ -235,11 +235,11 @@ static inline int opt_hdr_v1_valid_size(const struct opt_hdr_v1 *ohdr,
|
|||||||
{
|
{
|
||||||
uint32_t ohdr_size;
|
uint32_t ohdr_size;
|
||||||
|
|
||||||
if ((void *)(ohdr + 1) > mhdr_end)
|
if ((const void *)(ohdr + 1) > mhdr_end)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
ohdr_size = opt_hdr_v1_size(ohdr);
|
ohdr_size = opt_hdr_v1_size(ohdr);
|
||||||
if (ohdr_size < 8 || (void *)((uint8_t *)ohdr + ohdr_size) > mhdr_end)
|
if (ohdr_size < 8 || (const void *)((const uint8_t *)ohdr + ohdr_size) > mhdr_end)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
@ -252,7 +252,7 @@ static inline struct opt_hdr_v1 *opt_hdr_v1_first(void *img) {
|
|||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
mhdr = img;
|
mhdr = img;
|
||||||
if (mhdr->ext & 0x1)
|
if (mhdr->ext)
|
||||||
return (struct opt_hdr_v1 *)(mhdr + 1);
|
return (struct opt_hdr_v1 *)(mhdr + 1);
|
||||||
else
|
else
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -272,7 +272,7 @@ static inline struct opt_hdr_v1 *_opt_hdr_v1_next(struct opt_hdr_v1 *cur)
|
|||||||
|
|
||||||
static inline struct opt_hdr_v1 *opt_hdr_v1_next(struct opt_hdr_v1 *cur)
|
static inline struct opt_hdr_v1 *opt_hdr_v1_next(struct opt_hdr_v1 *cur)
|
||||||
{
|
{
|
||||||
if (*opt_hdr_v1_ext(cur) & 0x1)
|
if (*opt_hdr_v1_ext(cur))
|
||||||
return _opt_hdr_v1_next(cur);
|
return _opt_hdr_v1_next(cur);
|
||||||
else
|
else
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -1398,7 +1398,7 @@ kwboot_add_bin_ohdr_v1(void *img, size_t *size, uint32_t binsz)
|
|||||||
uint32_t ohdrsz;
|
uint32_t ohdrsz;
|
||||||
uint8_t *prev_ext;
|
uint8_t *prev_ext;
|
||||||
|
|
||||||
if (hdr->ext & 0x1) {
|
if (hdr->ext) {
|
||||||
for_each_opt_hdr_v1 (ohdr, img)
|
for_each_opt_hdr_v1 (ohdr, img)
|
||||||
if (opt_hdr_v1_next(ohdr) == NULL)
|
if (opt_hdr_v1_next(ohdr) == NULL)
|
||||||
break;
|
break;
|
||||||
@ -1422,7 +1422,7 @@ kwboot_add_bin_ohdr_v1(void *img, size_t *size, uint32_t binsz)
|
|||||||
ohdrsz = sizeof(*ohdr) + 4 + 4 * num_args + binsz + 4;
|
ohdrsz = sizeof(*ohdr) + 4 + 4 * num_args + binsz + 4;
|
||||||
kwboot_img_grow_hdr(hdr, size, ohdrsz);
|
kwboot_img_grow_hdr(hdr, size, ohdrsz);
|
||||||
|
|
||||||
*prev_ext |= 1;
|
*prev_ext = 1;
|
||||||
|
|
||||||
ohdr->headertype = OPT_HDR_V1_BINARY_TYPE;
|
ohdr->headertype = OPT_HDR_V1_BINARY_TYPE;
|
||||||
ohdr->headersz_msb = ohdrsz >> 16;
|
ohdr->headersz_msb = ohdrsz >> 16;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user