mirror of https://github.com/wolfSSL/wolfBoot.git
Fixes for NXP T1024 with Integrity OS. Adds additional FDT fixups for FMAN, Ethernet, PCI. Add PCI init and enumeration.
parent
6ccf221483
commit
0b206d6758
1
arch.mk
1
arch.mk
|
@ -425,6 +425,7 @@ ifeq ($(TARGET),nxp_t1024)
|
||||||
LDFLAGS+=-Wl,--as-needed # remove weak functions not used
|
LDFLAGS+=-Wl,--as-needed # remove weak functions not used
|
||||||
OBJS+=src/boot_ppc_mp.o # support for spin table
|
OBJS+=src/boot_ppc_mp.o # support for spin table
|
||||||
OBJS+=src/fdt.o
|
OBJS+=src/fdt.o
|
||||||
|
OBJS+=src/pci.o
|
||||||
UPDATE_OBJS:=src/update_ram.o
|
UPDATE_OBJS:=src/update_ram.o
|
||||||
ifeq ($(SPMATH),1)
|
ifeq ($(SPMATH),1)
|
||||||
MATH_OBJS += ./lib/wolfssl/wolfcrypt/src/sp_c32.o
|
MATH_OBJS += ./lib/wolfssl/wolfcrypt/src/sp_c32.o
|
||||||
|
|
296
hal/nxp_t1024.c
296
hal/nxp_t1024.c
|
@ -25,6 +25,7 @@
|
||||||
#include "hal.h"
|
#include "hal.h"
|
||||||
#include "nxp_ppc.h"
|
#include "nxp_ppc.h"
|
||||||
#include "fdt.h"
|
#include "fdt.h"
|
||||||
|
#include "pci.h"
|
||||||
|
|
||||||
/* Tested on T1024E Rev 1.0, e5500 core 2.1, PVR 8024_1021 and SVR 8548_0010 */
|
/* Tested on T1024E Rev 1.0, e5500 core 2.1, PVR 8024_1021 and SVR 8548_0010 */
|
||||||
/* IFC: CS0 NOR, CS1 MRAM, CS2 APU CPLD, CS3, MPU CPLD */
|
/* IFC: CS0 NOR, CS1 MRAM, CS2 APU CPLD, CS3, MPU CPLD */
|
||||||
|
@ -118,8 +119,34 @@ static void hal_flash_unlock_sector(uint32_t sector);
|
||||||
#define DCFG_DMA2LIODNR ((volatile uint32_t*)(DCFG_BASE + 0x584))
|
#define DCFG_DMA2LIODNR ((volatile uint32_t*)(DCFG_BASE + 0x584))
|
||||||
|
|
||||||
/* PCI Express LIODN base register */
|
/* PCI Express LIODN base register */
|
||||||
#define PCI_BASE(n) (0x240000 + ((n) * 0x10000))
|
#define PCI_BASE(n) (CCSRBAR + 0x240000 + ((n-1) * 0x10000))
|
||||||
|
#define PCIE_CONFIG_ADDR(n) ((volatile uint32_t*)(PCI_BASE(n) + 0x00)) /* PEXx_PEX_CONFIG_ADDR - configuration address */
|
||||||
|
#define PCIE_CONFIG_DATA(n) ((volatile uint32_t*)(PCI_BASE(n) + 0x04)) /* PEXx_PEX_CONFIG_DATA - configuration data */
|
||||||
#define PCIE_LIODN(n) ((volatile uint32_t*)(PCI_BASE(n) + 0x40)) /* PEXx_PEX_LBR */
|
#define PCIE_LIODN(n) ((volatile uint32_t*)(PCI_BASE(n) + 0x40)) /* PEXx_PEX_LBR */
|
||||||
|
#define PCIE_BLK_REV1(n) ((volatile uint32_t*)(PCI_BASE(n) + 0xBF8)) /* PEXx_PEX_IP_BLK_REV1 */
|
||||||
|
#define PCIE_BLK_REV2(n) ((volatile uint32_t*)(PCI_BASE(n) + 0xBFC)) /* PEXx_PEX_IP_BLK_REV1 */
|
||||||
|
|
||||||
|
/* PCIe Output Windows (max 5) */
|
||||||
|
#define PCIE_OTAR(n, w) ((volatile uint32_t*)(PCI_BASE(n) + 0xC00 + ((w) * 32))) /* PEXx_PEXOTARn - outbound translation address */
|
||||||
|
#define PCIE_OTEAR(n, w) ((volatile uint32_t*)(PCI_BASE(n) + 0xC04 + ((w) * 32))) /* PEXx_PEXOTEARn - outbound translation extended address */
|
||||||
|
#define PCIE_OWBAR(n, w) ((volatile uint32_t*)(PCI_BASE(n) + 0xC08 + ((w) * 32))) /* PEXx_PEXOWBARn - outbound window base address */
|
||||||
|
#define PCIE_OWAR(n, w) ((volatile uint32_t*)(PCI_BASE(n) + 0xC10 + ((w) * 32))) /* PEXx_PEXOWARn - outbound window attributes */
|
||||||
|
#define POWAR_EN 0x80000000
|
||||||
|
#define POWAR_IO_READ 0x00080000
|
||||||
|
#define POWAR_MEM_READ 0x00040000
|
||||||
|
#define POWAR_IO_WRITE 0x00008000
|
||||||
|
#define POWAR_MEM_WRITE 0x00004000
|
||||||
|
|
||||||
|
/* PCIe Input Windows (max 4 - seq is 3,2,1,0) */
|
||||||
|
#define PCIE_ITAR(n, w) ((volatile uint32_t*)(PCI_BASE(n) + 0xD80 + ((3-((w) & 0x3)) * 32))) /* PEXx_PEXITARn - inbound translation address */
|
||||||
|
#define PCIE_IWBAR(n, w) ((volatile uint32_t*)(PCI_BASE(n) + 0xD88 + ((3-((w) & 0x3)) * 32))) /* PEXx_PEXIWBARn - inbound window base address */
|
||||||
|
#define PCIE_IWBEAR(n, w) ((volatile uint32_t*)(PCI_BASE(n) + 0xD8C + ((3-((w) & 0x3)) * 32))) /* PEXx_PEXIWBEARn- inbound window base extended address */
|
||||||
|
#define PCIE_IWAR(n, w) ((volatile uint32_t*)(PCI_BASE(n) + 0xD90 + ((3-((w) & 0x3)) * 32))) /* PEXx_PEXIWARn - inbound window attributes */
|
||||||
|
#define PIWAR_EN 0x80000000
|
||||||
|
#define PIWAR_PF 0x20000000
|
||||||
|
#define PIWAR_LOCAL 0x00f00000
|
||||||
|
#define PIWAR_READ_SNOOP 0x00050000
|
||||||
|
#define PIWAR_WRITE_SNOOP 0x00005000
|
||||||
|
|
||||||
/* Buffer Manager */
|
/* Buffer Manager */
|
||||||
#define BMAN_LIODNR ((volatile uint32_t*)(BMAN_CCSR_BASE + 0xD08))
|
#define BMAN_LIODNR ((volatile uint32_t*)(BMAN_CCSR_BASE + 0xD08))
|
||||||
|
@ -128,7 +155,7 @@ static void hal_flash_unlock_sector(uint32_t sector);
|
||||||
/* Frame Queue Descriptor (FQD) */
|
/* Frame Queue Descriptor (FQD) */
|
||||||
#define FQD_BAR ((volatile uint32_t*)(QMAN_CCSR_BASE + 0xC04))
|
#define FQD_BAR ((volatile uint32_t*)(QMAN_CCSR_BASE + 0xC04))
|
||||||
#define FQD_AR ((volatile uint32_t*)(QMAN_CCSR_BASE + 0xC10))
|
#define FQD_AR ((volatile uint32_t*)(QMAN_CCSR_BASE + 0xC10))
|
||||||
/* Packed Frame Desc riptor Record (PFDR) */
|
/* Packed Frame Descriptor Record (PFDR) */
|
||||||
#define PFDR_BARE ((volatile uint32_t*)(QMAN_CCSR_BASE + 0xC20))
|
#define PFDR_BARE ((volatile uint32_t*)(QMAN_CCSR_BASE + 0xC20))
|
||||||
#define PFDR_BAR ((volatile uint32_t*)(QMAN_CCSR_BASE + 0xC24))
|
#define PFDR_BAR ((volatile uint32_t*)(QMAN_CCSR_BASE + 0xC24))
|
||||||
#define PFDR_AR ((volatile uint32_t*)(QMAN_CCSR_BASE + 0xC30))
|
#define PFDR_AR ((volatile uint32_t*)(QMAN_CCSR_BASE + 0xC30))
|
||||||
|
@ -300,10 +327,13 @@ static void hal_flash_unlock_sector(uint32_t sector);
|
||||||
|
|
||||||
/* Hardware Ports (0-63) 4KB each (256KB total) */
|
/* Hardware Ports (0-63) 4KB each (256KB total) */
|
||||||
#define FMAN_BMI(n) ((FMAN_BASE + 0x80000) + ((n) * 0x1000))
|
#define FMAN_BMI(n) ((FMAN_BASE + 0x80000) + ((n) * 0x1000))
|
||||||
|
#define FMAN_BMI_SPLIODN(n, p) ((volatile uint32_t*)(FMAN_BMI(n) + 0x304 + ((((p) - 1) & 0x3F) * 4)))
|
||||||
|
|
||||||
#define FMAN_QMI(n) ((FMAN_BASE + 0x80000) + ((n) * 0x1000) + 0x400)
|
#define FMAN_QMI(n) ((FMAN_BASE + 0x80000) + ((n) * 0x1000) + 0x400)
|
||||||
|
|
||||||
#define FMAN_DMA (FMAN_BASE + 0xC2000UL) /* FMan DMA */
|
#define FMAN_DMA (FMAN_BASE + 0xC2000UL) /* FMan DMA */
|
||||||
|
#define FMAN_DMA_ENTRIES (32)
|
||||||
|
#define FMAN_DMA_PORT_LIODN(n) ((volatile uint32_t*)(FMAN_DMA + 0x60 + (((n) & 0x1F) * 4))) /* FMan DMA portID-LIODN #0..31 register */
|
||||||
|
|
||||||
#define FMAN_FPM (FMAN_BASE + 0xC3000UL) /* Frame processing manager (FPM) */
|
#define FMAN_FPM (FMAN_BASE + 0xC3000UL) /* Frame processing manager (FPM) */
|
||||||
|
|
||||||
|
@ -1141,6 +1171,36 @@ void hal_early_init(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef ENABLE_PCIE
|
#ifdef ENABLE_PCIE
|
||||||
|
|
||||||
|
/* PCI IO read/write functions */
|
||||||
|
/* Intel PCI addr/data mappings for compatibility with our PCI driver */
|
||||||
|
#define PCI_CONFIG_ADDR_PORT 0xcf8
|
||||||
|
#define PCI_CONFIG_DATA_PORT 0xcfc
|
||||||
|
static int pcie_bus = 0;
|
||||||
|
void io_write32(uint16_t port, uint32_t value)
|
||||||
|
{
|
||||||
|
if (port == PCI_CONFIG_ADDR_PORT) {
|
||||||
|
set32(PCIE_CONFIG_ADDR(pcie_bus), value);
|
||||||
|
}
|
||||||
|
else if (port == PCI_CONFIG_DATA_PORT) {
|
||||||
|
set32(PCIE_CONFIG_DATA(pcie_bus), value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
uint32_t io_read32(uint16_t port)
|
||||||
|
{
|
||||||
|
uint32_t value = 0;
|
||||||
|
if (port == PCI_CONFIG_ADDR_PORT) {
|
||||||
|
value = get32(PCIE_CONFIG_ADDR(1));
|
||||||
|
}
|
||||||
|
else if (port == PCI_CONFIG_DATA_PORT) {
|
||||||
|
value = get32(PCIE_CONFIG_DATA(1));
|
||||||
|
}
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define PCI_MMIO32_LENGTH (1024UL * 1024U * 1024U)
|
||||||
|
#define PCI_MMIO32_PREFETCH_LENGTH (1024UL * 1024U * 1024U)
|
||||||
|
|
||||||
#define CONFIG_SYS_PCIE1_MEM_PHYS_HIGH 0xC
|
#define CONFIG_SYS_PCIE1_MEM_PHYS_HIGH 0xC
|
||||||
#define CONFIG_SYS_PCIE1_MEM_PHYS 0x00000000
|
#define CONFIG_SYS_PCIE1_MEM_PHYS 0x00000000
|
||||||
#define CONFIG_SYS_PCIE1_MEM_VIRT 0x80000000
|
#define CONFIG_SYS_PCIE1_MEM_VIRT 0x80000000
|
||||||
|
@ -1161,17 +1221,128 @@ void hal_early_init(void)
|
||||||
#define CONFIG_SYS_PCIE3_IO_PHYS_HIGH 0xF
|
#define CONFIG_SYS_PCIE3_IO_PHYS_HIGH 0xF
|
||||||
#define CONFIG_SYS_PCIE3_IO_PHYS 0xF8020000
|
#define CONFIG_SYS_PCIE3_IO_PHYS 0xF8020000
|
||||||
#define CONFIG_SYS_PCIE3_IO_VIRT CONFIG_SYS_PCIE3_IO_PHYS
|
#define CONFIG_SYS_PCIE3_IO_VIRT CONFIG_SYS_PCIE3_IO_PHYS
|
||||||
|
|
||||||
static int hal_pcie_init(void)
|
static int hal_pcie_init(void)
|
||||||
{
|
{
|
||||||
|
int ret;
|
||||||
|
int bus, i;
|
||||||
|
int law_start = 14;
|
||||||
|
struct pci_enum_info enum_info;
|
||||||
|
|
||||||
|
for (pcie_bus=1; pcie_bus<=3; pcie_bus++) {
|
||||||
|
/* Check device disable register */
|
||||||
|
if (get32(DCFG_DEVDISR3) & (1 << (32-pcie_bus))) {
|
||||||
|
wolfBoot_printf("PCIe %d: Disabled\n", pcie_bus);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Read block revision */
|
||||||
|
wolfBoot_printf("PCIe %d: Base 0x%x, Rev 0x%x\n",
|
||||||
|
pcie_bus, PCI_BASE(pcie_bus),
|
||||||
|
get32(PCIE_BLK_REV1(pcie_bus)));
|
||||||
|
|
||||||
|
/* Setup PCIe memory regions */
|
||||||
|
memset(&enum_info, 0, sizeof(enum_info));
|
||||||
|
if (pcie_bus == 1) {
|
||||||
|
enum_info.mem = CONFIG_SYS_PCIE1_MEM_VIRT;
|
||||||
|
enum_info.io = CONFIG_SYS_PCIE1_IO_VIRT;
|
||||||
|
|
||||||
/* Map TLB for PCIe */
|
/* Map TLB for PCIe */
|
||||||
set_tlb(1, 3, CONFIG_SYS_PCIE1_MEM_VIRT,
|
set_tlb(1, law_start++, CONFIG_SYS_PCIE1_MEM_VIRT,
|
||||||
CONFIG_SYS_PCIE1_MEM_PHYS, CONFIG_SYS_PCIE1_MEM_PHYS_HIGH,
|
CONFIG_SYS_PCIE1_MEM_PHYS, CONFIG_SYS_PCIE1_MEM_PHYS_HIGH,
|
||||||
(MAS3_SX | MAS3_SW | MAS3_SR), (MAS2_I | MAS2_G), 0, BOOKE_PAGESZ_1G, 1);
|
(MAS3_SX | MAS3_SW | MAS3_SR), (MAS2_I | MAS2_G), 0, BOOKE_PAGESZ_1G, 1);
|
||||||
set_tlb(1, 4, CONFIG_SYS_PCIE1_MEM_VIRT,
|
set_tlb(1, law_start++, CONFIG_SYS_PCIE1_MEM_VIRT,
|
||||||
CONFIG_SYS_PCIE1_MEM_PHYS, CONFIG_SYS_PCIE1_MEM_PHYS_HIGH,
|
CONFIG_SYS_PCIE1_MEM_PHYS, CONFIG_SYS_PCIE1_MEM_PHYS_HIGH,
|
||||||
(MAS3_SX | MAS3_SW | MAS3_SR), (MAS2_I | MAS2_G), 0, BOOKE_PAGESZ_256K, 1);
|
(MAS3_SX | MAS3_SW | MAS3_SR), (MAS2_I | MAS2_G), 0, BOOKE_PAGESZ_256K, 1);
|
||||||
|
}
|
||||||
|
else if (pcie_bus == 2) {
|
||||||
|
enum_info.mem = CONFIG_SYS_PCIE2_MEM_VIRT;
|
||||||
|
enum_info.io = CONFIG_SYS_PCIE2_IO_VIRT;
|
||||||
|
|
||||||
return 0;
|
/* Map TLB for PCIe */
|
||||||
|
set_tlb(1, law_start++, CONFIG_SYS_PCIE2_MEM_VIRT,
|
||||||
|
CONFIG_SYS_PCIE2_MEM_PHYS, CONFIG_SYS_PCIE2_MEM_PHYS_HIGH,
|
||||||
|
(MAS3_SX | MAS3_SW | MAS3_SR), (MAS2_I | MAS2_G), 0, BOOKE_PAGESZ_1G, 1);
|
||||||
|
set_tlb(1, law_start++, CONFIG_SYS_PCIE2_MEM_VIRT,
|
||||||
|
CONFIG_SYS_PCIE2_MEM_PHYS, CONFIG_SYS_PCIE2_MEM_PHYS_HIGH,
|
||||||
|
(MAS3_SX | MAS3_SW | MAS3_SR), (MAS2_I | MAS2_G), 0, BOOKE_PAGESZ_256K, 1);
|
||||||
|
}
|
||||||
|
else if (pcie_bus == 3) {
|
||||||
|
enum_info.mem = CONFIG_SYS_PCIE3_MEM_VIRT;
|
||||||
|
enum_info.io = CONFIG_SYS_PCIE3_IO_VIRT;
|
||||||
|
|
||||||
|
/* Map TLB for PCIe */
|
||||||
|
set_tlb(1, law_start++, CONFIG_SYS_PCIE3_MEM_VIRT,
|
||||||
|
CONFIG_SYS_PCIE3_MEM_PHYS, CONFIG_SYS_PCIE3_MEM_PHYS_HIGH,
|
||||||
|
(MAS3_SX | MAS3_SW | MAS3_SR), (MAS2_I | MAS2_G), 0, BOOKE_PAGESZ_1G, 1);
|
||||||
|
set_tlb(1, law_start++, CONFIG_SYS_PCIE3_MEM_VIRT,
|
||||||
|
CONFIG_SYS_PCIE3_MEM_PHYS, CONFIG_SYS_PCIE3_MEM_PHYS_HIGH,
|
||||||
|
(MAS3_SX | MAS3_SW | MAS3_SR), (MAS2_I | MAS2_G), 0, BOOKE_PAGESZ_256K, 1);
|
||||||
|
}
|
||||||
|
enum_info.mem_limit = enum_info.mem + (PCI_MMIO32_LENGTH - 1);
|
||||||
|
enum_info.mem_pf = (enum_info.mem + PCI_MMIO32_PREFETCH_LENGTH);
|
||||||
|
enum_info.mem_pf_limit = PCI_MMIO32_PREFETCH_LENGTH;
|
||||||
|
|
||||||
|
/* Setup PCIe Output Windows */
|
||||||
|
if (pcie_bus == 1) {
|
||||||
|
set32( PCIE_OTAR(pcie_bus, 0), 0x0);
|
||||||
|
set32(PCIE_OTEAR(pcie_bus, 0), 0x0);
|
||||||
|
set32( PCIE_OWAR(pcie_bus, 0), 0x80044027);
|
||||||
|
|
||||||
|
set32( PCIE_OTAR(pcie_bus, 1), 0xE0000);
|
||||||
|
set32(PCIE_OTEAR(pcie_bus, 1), 0x0);
|
||||||
|
set32(PCIE_OWBAR(pcie_bus, 1), 0xC00000); /* MEM_PHYS >> 12 */
|
||||||
|
set32( PCIE_OWAR(pcie_bus, 1), 0x8004401B);
|
||||||
|
|
||||||
|
set32( PCIE_OTAR(pcie_bus, 2), 0x0);
|
||||||
|
set32(PCIE_OTEAR(pcie_bus, 2), 0x0);
|
||||||
|
set32(PCIE_OWBAR(pcie_bus, 2), 0xFF8000); /* IO_PHYS >> 12 */
|
||||||
|
set32( PCIE_OWAR(pcie_bus, 2), 0x8008800F);
|
||||||
|
|
||||||
|
}
|
||||||
|
else if (pcie_bus == 3) {
|
||||||
|
set32( PCIE_OTAR(pcie_bus, 0), 0x0);
|
||||||
|
set32(PCIE_OWBAR(pcie_bus, 0), 0x0);
|
||||||
|
set32( PCIE_OWAR(pcie_bus, 0), 0x80044027);
|
||||||
|
|
||||||
|
set32( PCIE_OTAR(pcie_bus, 1), 0xE0000);
|
||||||
|
set32(PCIE_OTEAR(pcie_bus, 1), 0x0);
|
||||||
|
set32(PCIE_OWBAR(pcie_bus, 1), 0xC20000); /* MEM_PHYS >> 12 */
|
||||||
|
set32( PCIE_OWAR(pcie_bus, 1), 0x8004401B);
|
||||||
|
|
||||||
|
set32( PCIE_OTAR(pcie_bus, 2), 0x0);
|
||||||
|
set32(PCIE_OTEAR(pcie_bus, 2), 0x0);
|
||||||
|
set32(PCIE_OWBAR(pcie_bus, 2), 0xFF8020); /* IO_PHYS >> 12 */
|
||||||
|
set32( PCIE_OWAR(pcie_bus, 2), 0x8008800F);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Setup PCIe Input Windows */
|
||||||
|
set32( PCIE_ITAR(pcie_bus, 0), 0xFFE000);
|
||||||
|
set32( PCIE_IWAR(pcie_bus, 0), 0x80E44017);
|
||||||
|
|
||||||
|
set32( PCIE_ITAR(pcie_bus, 1), 0x0);
|
||||||
|
set32( PCIE_IWBAR(pcie_bus, 1), 0x0);
|
||||||
|
set32( PCIE_IWAR(pcie_bus, 1), 0xA0F5501E);
|
||||||
|
|
||||||
|
set32( PCIE_ITAR(pcie_bus, 2), 0x0);
|
||||||
|
set32( PCIE_IWBAR(pcie_bus, 2), 0x1000000);
|
||||||
|
set32(PCIE_IWBEAR(pcie_bus, 2), 0x0);
|
||||||
|
set32( PCIE_IWAR(pcie_bus, 2), 0xA0F5501E);
|
||||||
|
|
||||||
|
set32( PCIE_ITAR(pcie_bus, 3), 0x0);
|
||||||
|
set32( PCIE_IWBAR(pcie_bus, 3), 0x0);
|
||||||
|
set32(PCIE_IWBEAR(pcie_bus, 3), 0x0);
|
||||||
|
set32( PCIE_IWAR(pcie_bus, 3), 0x20F44027);
|
||||||
|
|
||||||
|
/* TODO: setup PCSRBAR/PEXCSRBAR */
|
||||||
|
|
||||||
|
|
||||||
|
ret = pci_enum_bus(0, &enum_info);
|
||||||
|
if (ret != 0) {
|
||||||
|
wolfBoot_printf("PCIe %d: Enum failed %d\n", pcie_bus, ret);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -1368,24 +1539,28 @@ static const struct liodn_id_table liodn_tbl[] = {
|
||||||
SET_LIODN("fsl,qe", 559, DCFG_QELIODNR),
|
SET_LIODN("fsl,qe", 559, DCFG_QELIODNR),
|
||||||
SET_LIODN("fsl,elo3-dma", 147, DCFG_DMA1LIODNR),
|
SET_LIODN("fsl,elo3-dma", 147, DCFG_DMA1LIODNR),
|
||||||
SET_LIODN("fsl,elo3-dma", 227, DCFG_DMA2LIODNR),
|
SET_LIODN("fsl,elo3-dma", 227, DCFG_DMA2LIODNR),
|
||||||
|
SET_LIODN("fsl,fman-port-1g-rx", 0x425, NULL),
|
||||||
|
SET_LIODN("fsl,fman-port-1g-rx", 0x426, NULL),
|
||||||
|
SET_LIODN("fsl,fman-port-1g-rx", 0x427, NULL),
|
||||||
|
SET_LIODN("fsl,fman-port-1g-rx", 0x428, NULL),
|
||||||
SET_LIODN("fsl,qman", 62, QMAN_LIODNR),
|
SET_LIODN("fsl,qman", 62, QMAN_LIODNR),
|
||||||
SET_LIODN("fsl,bman", 63, BMAN_LIODNR),
|
SET_LIODN("fsl,bman", 63, BMAN_LIODNR),
|
||||||
SET_LIODN("fsl,qoriq-pcie-v2.4", 148, PCIE_LIODN(1)),
|
SET_LIODN("fsl,qoriq-pcie", 148, PCIE_LIODN(1)),
|
||||||
SET_LIODN("fsl,qoriq-pcie-v2.4", 228, PCIE_LIODN(2)),
|
SET_LIODN("fsl,qoriq-pcie", 228, PCIE_LIODN(2)),
|
||||||
SET_LIODN("fsl,qoriq-pcie-v2.4", 308, PCIE_LIODN(3)),
|
SET_LIODN("fsl,qoriq-pcie", 308, PCIE_LIODN(3)),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/* Logical I/O Device Number */
|
/* Logical I/O Device Number */
|
||||||
void hal_liodn_init(void)
|
void hal_liodn_init(void)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
for (i=0; i<(int)(sizeof(liodn_tbl)/sizeof(struct liodn_id_table)); i++) {
|
for (i=0; i<(int)(sizeof(liodn_tbl)/sizeof(struct liodn_id_table)); i++) {
|
||||||
|
if (liodn_tbl[i].reg_offset != NULL) {
|
||||||
wolfBoot_printf("LIODN %s: %p=%d\n",
|
wolfBoot_printf("LIODN %s: %p=%d\n",
|
||||||
liodn_tbl[i].compat, liodn_tbl[i].reg_offset, liodn_tbl[i].id);
|
liodn_tbl[i].compat, liodn_tbl[i].reg_offset, liodn_tbl[i].id);
|
||||||
set32(liodn_tbl[i].reg_offset, liodn_tbl[i].id);
|
set32(liodn_tbl[i].reg_offset, liodn_tbl[i].id);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ---- QUICC Engine Driver ---- */
|
/* ---- QUICC Engine Driver ---- */
|
||||||
|
@ -1609,9 +1784,11 @@ static int fman_upload_firmware(const struct qe_firmware *firmware)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define FMAN_DMA_LIODN 973
|
||||||
|
|
||||||
static int hal_fman_init(void)
|
static int hal_fman_init(void)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret, i;
|
||||||
const struct qe_firmware* fw = (const struct qe_firmware*)FMAN_FW_ADDR;
|
const struct qe_firmware* fw = (const struct qe_firmware*)FMAN_FW_ADDR;
|
||||||
|
|
||||||
/* Upload microcode to IRAM */
|
/* Upload microcode to IRAM */
|
||||||
|
@ -1620,7 +1797,17 @@ static int hal_fman_init(void)
|
||||||
ret = fman_upload_firmware(fw);
|
ret = fman_upload_firmware(fw);
|
||||||
}
|
}
|
||||||
if (ret == 0) {
|
if (ret == 0) {
|
||||||
|
/* Setup FMAN LIDON */
|
||||||
|
set32(FMAN_BMI_SPLIODN(0, 0+8), 88); /* RX_10G_TYPE2 */
|
||||||
|
set32(FMAN_BMI_SPLIODN(0, 1+8), 89); /* RX_1G */
|
||||||
|
set32(FMAN_BMI_SPLIODN(0, 2+8), 90); /* RX_1G */
|
||||||
|
set32(FMAN_BMI_SPLIODN(0, 3+8), 91); /* RX_1G */
|
||||||
|
|
||||||
|
/* Setup FMAN DMA LIODN - use same base for all */
|
||||||
|
for (i=0; i<FMAN_DMA_ENTRIES; i++) {
|
||||||
|
set32(FMAN_DMA_PORT_LIODN(i),
|
||||||
|
((FMAN_DMA_LIODN << 16) | FMAN_DMA_LIODN));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -1752,7 +1939,9 @@ void hal_init(void)
|
||||||
hal_flash_init();
|
hal_flash_init();
|
||||||
hal_cpld_init();
|
hal_cpld_init();
|
||||||
#ifdef ENABLE_PCIE
|
#ifdef ENABLE_PCIE
|
||||||
hal_pcie_init();
|
if (hal_pcie_init() != 0) {
|
||||||
|
wolfBoot_printf("PCIe: init failed!\n");
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef ENABLE_QE
|
#ifdef ENABLE_QE
|
||||||
|
@ -1947,6 +2136,10 @@ int hal_dts_fixup(void* dts_addr)
|
||||||
struct fdt_header *fdt = (struct fdt_header *)dts_addr;
|
struct fdt_header *fdt = (struct fdt_header *)dts_addr;
|
||||||
int off, i;
|
int off, i;
|
||||||
uint32_t *reg;
|
uint32_t *reg;
|
||||||
|
const char* prev_compat;
|
||||||
|
|
||||||
|
/* TODO: Ethenet MAC should be dynamic value */
|
||||||
|
uint8_t mac_addr[6] = {0xDC, 0xA7, 0xD9, 0x00, 0x07, 0x10};
|
||||||
|
|
||||||
/* verify the FTD is valid */
|
/* verify the FTD is valid */
|
||||||
off = fdt_check_header(dts_addr);
|
off = fdt_check_header(dts_addr);
|
||||||
|
@ -1960,8 +2153,8 @@ int hal_dts_fixup(void* dts_addr)
|
||||||
fdt_version(fdt), fdt_totalsize(fdt));
|
fdt_version(fdt), fdt_totalsize(fdt));
|
||||||
|
|
||||||
/* expand total size */
|
/* expand total size */
|
||||||
fdt->totalsize += 1024; /* expand by 1KB */
|
fdt->totalsize += 2048; /* expand by 2KB */
|
||||||
wolfBoot_printf("FDT: Expanded (1KB) to %d bytes\n", fdt->totalsize);
|
wolfBoot_printf("FDT: Expanded (2KB) to %d bytes\n", fdt->totalsize);
|
||||||
|
|
||||||
/* fixup the memory region - single bank */
|
/* fixup the memory region - single bank */
|
||||||
off = fdt_find_devtype(fdt, -1, "memory");
|
off = fdt_find_devtype(fdt, -1, "memory");
|
||||||
|
@ -2027,18 +2220,24 @@ int hal_dts_fixup(void* dts_addr)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* fixup the LIODN */
|
/* fixup the LIODN */
|
||||||
|
prev_compat = NULL;
|
||||||
for (i=0; i<(int)(sizeof(liodn_tbl)/sizeof(struct liodn_id_table)); i++) {
|
for (i=0; i<(int)(sizeof(liodn_tbl)/sizeof(struct liodn_id_table)); i++) {
|
||||||
off = fdt_node_offset_by_compatible(fdt, -1, liodn_tbl[i].compat);
|
if (prev_compat == NULL || strcmp(prev_compat, liodn_tbl[i].compat) != 0) {
|
||||||
|
off = -1;
|
||||||
|
}
|
||||||
|
off = fdt_node_offset_by_compatible(fdt, off, liodn_tbl[i].compat);
|
||||||
if (off >= 0) {
|
if (off >= 0) {
|
||||||
fdt_fixup_val(fdt, off, liodn_tbl[i].compat, "fsl,liodn",
|
fdt_fixup_val(fdt, off, liodn_tbl[i].compat, "fsl,liodn",
|
||||||
liodn_tbl[i].id);
|
liodn_tbl[i].id);
|
||||||
}
|
}
|
||||||
|
prev_compat = liodn_tbl[i].compat;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* fixup the QMAN portals */
|
/* fixup the QMAN portals */
|
||||||
off = fdt_node_offset_by_compatible(fdt, -1, "fsl,qman-portal");
|
off = fdt_node_offset_by_compatible(fdt, -1, "fsl,qman-portal");
|
||||||
while (off != -FDT_ERR_NOTFOUND) {
|
while (off != -FDT_ERR_NOTFOUND) {
|
||||||
uint32_t liodns[2];
|
uint32_t liodns[2];
|
||||||
|
int childoff;
|
||||||
|
|
||||||
reg = (uint32_t*)fdt_getprop(fdt, off, "cell-index", NULL);
|
reg = (uint32_t*)fdt_getprop(fdt, off, "cell-index", NULL);
|
||||||
if (reg == NULL)
|
if (reg == NULL)
|
||||||
|
@ -2054,13 +2253,72 @@ int hal_dts_fixup(void* dts_addr)
|
||||||
"qman-portal", i, off, "fsl,liodn", liodns[0], liodns[1]);
|
"qman-portal", i, off, "fsl,liodn", liodns[0], liodns[1]);
|
||||||
fdt_setprop(fdt, off, "fsl,liodn", liodns, sizeof(liodns));
|
fdt_setprop(fdt, off, "fsl,liodn", liodns, sizeof(liodns));
|
||||||
|
|
||||||
|
/* Add fman@0 node and fsl,liodon = FMAN_DMA_LIODN + index */
|
||||||
|
childoff = fdt_add_subnode(fdt, off, "fman@0");
|
||||||
|
if (childoff > 0) {
|
||||||
|
liodns[0] = FMAN_DMA_LIODN + i + 1;
|
||||||
|
wolfBoot_printf("FDT: Set %s@%d/%s (%d), %s=%d\n",
|
||||||
|
"qman-portal", i, "fman@0", childoff, "fsl,liodn", liodns[0]);
|
||||||
|
fdt_setprop(fdt, childoff, "fsl,liodn", liodns, sizeof(liodns[0]));
|
||||||
|
off = childoff;
|
||||||
|
}
|
||||||
|
|
||||||
off = fdt_node_offset_by_compatible(fdt, off, "fsl,qman-portal");
|
off = fdt_node_offset_by_compatible(fdt, off, "fsl,qman-portal");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* mpic clock */
|
/* fixup the fman clock */
|
||||||
off = fdt_find_devtype(fdt, -1, "open-pic");
|
off = fdt_node_offset_by_compatible(fdt, -1, "fsl,fman");
|
||||||
if (off != -FDT_ERR_NOTFOUND) {
|
if (off != !FDT_ERR_NOTFOUND) {
|
||||||
fdt_fixup_val(fdt, off, "open-pic", "clock-frequency", hal_get_bus_clk());
|
fdt_fixup_val(fdt, off, "fman@", "clock-frequency", hal_get_bus_clk());
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Ethernet Devices */
|
||||||
|
off = fdt_node_offset_by_compatible(fdt, -1, "fsl,fman-memac");
|
||||||
|
while (off != -FDT_ERR_NOTFOUND) {
|
||||||
|
reg = (uint32_t*)fdt_getprop(fdt, off, "cell-index", NULL);
|
||||||
|
if (reg == NULL)
|
||||||
|
break;
|
||||||
|
i = (int)fdt32_to_cpu(*reg);
|
||||||
|
|
||||||
|
wolfBoot_printf("FDT: Ethernet%d: Offset %d\n", i, off);
|
||||||
|
|
||||||
|
/* Set Ethernet MAC addresses (incrementing) */
|
||||||
|
wolfBoot_printf("FDT: Set %s@%d (%d), %s=%x:%x:%x:%x:%x:%x\n",
|
||||||
|
"ethernet", i, off, "local-mac-address",
|
||||||
|
mac_addr[0], mac_addr[1], mac_addr[2],
|
||||||
|
mac_addr[3], mac_addr[4], mac_addr[5]);
|
||||||
|
fdt_setprop(fdt, off, "local-mac-address", mac_addr, sizeof(mac_addr));
|
||||||
|
|
||||||
|
mac_addr[5]++;
|
||||||
|
off = fdt_node_offset_by_compatible(fdt, off, "fsl,fman-memac");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* PCIe Ranges */
|
||||||
|
i = 0;
|
||||||
|
off = fdt_node_offset_by_compatible(fdt, -1, "fsl,qoriq-pcie");
|
||||||
|
while (off != -FDT_ERR_NOTFOUND) {
|
||||||
|
uint32_t dma_ranges[] = {
|
||||||
|
/* TYPE BUS START PHYS SIZE */
|
||||||
|
(FDT_PCI_MEM32),
|
||||||
|
0x00, 0xff000000, 0x0f, 0xfe000000, 0x00, 0x01000000,
|
||||||
|
(FDT_PCI_PREFETCH | FDT_PCI_MEM32),
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x80000000,
|
||||||
|
(FDT_PCI_PREFETCH | FDT_PCI_MEM32),
|
||||||
|
0x10, 0x00, 0x00, 0x00, 0x00, 0x80000000
|
||||||
|
};
|
||||||
|
uint32_t bus_range[2];
|
||||||
|
bus_range[0] = 0;
|
||||||
|
bus_range[1] = i;
|
||||||
|
|
||||||
|
wolfBoot_printf("FDT: PCI%d: Offset %d\n", i, off);
|
||||||
|
|
||||||
|
/* Set "dma-ranges" */
|
||||||
|
fdt_setprop(fdt, off, "dma-ranges", dma_ranges, sizeof(dma_ranges));
|
||||||
|
/* Set "bus-range" */
|
||||||
|
fdt_setprop(fdt, off, "bus-range", bus_range, sizeof(bus_range));
|
||||||
|
|
||||||
|
i++;
|
||||||
|
off = fdt_node_offset_by_compatible(fdt, off, "fsl,qoriq-pcie");
|
||||||
}
|
}
|
||||||
#endif /* !BUILD_LOADER_STAGE1 */
|
#endif /* !BUILD_LOADER_STAGE1 */
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -91,7 +91,12 @@ struct fdt_property {
|
||||||
#define FDT_ERR_NOSPACE 7
|
#define FDT_ERR_NOSPACE 7
|
||||||
#define FDT_ERR_TRUNCATED 8
|
#define FDT_ERR_TRUNCATED 8
|
||||||
#define FDT_ERR_INTERNAL 9
|
#define FDT_ERR_INTERNAL 9
|
||||||
|
#define FDT_ERR_EXISTS 10
|
||||||
|
|
||||||
|
#define FDT_PCI_PREFETCH (0x40000000)
|
||||||
|
#define FDT_PCI_MEM32 (0x02000000)
|
||||||
|
#define FDT_PCI_IO (0x01000000)
|
||||||
|
#define FDT_PCI_MEM64 (0x03000000)
|
||||||
|
|
||||||
uint32_t cpu_to_fdt32(uint32_t x);
|
uint32_t cpu_to_fdt32(uint32_t x);
|
||||||
uint64_t cpu_to_fdt64(uint64_t x);
|
uint64_t cpu_to_fdt64(uint64_t x);
|
||||||
|
@ -137,6 +142,7 @@ int fdt_setprop(void *fdt, int nodeoffset, const char *name, const void *val, in
|
||||||
int fdt_find_devtype(void* fdt, int startoff, const char* node);
|
int fdt_find_devtype(void* fdt, int startoff, const char* node);
|
||||||
int fdt_node_check_compatible(const void *fdt, int nodeoffset, const char *compatible);
|
int fdt_node_check_compatible(const void *fdt, int nodeoffset, const char *compatible);
|
||||||
int fdt_node_offset_by_compatible(const void *fdt, int startoffset, const char *compatible);
|
int fdt_node_offset_by_compatible(const void *fdt, int startoffset, const char *compatible);
|
||||||
|
int fdt_add_subnode(void* fdt, int parentoff, const char* name);
|
||||||
|
|
||||||
/* helpers to fix/append a property to a node */
|
/* helpers to fix/append a property to a node */
|
||||||
int fdt_fixup_str(void* fdt, int off, const char* node, const char* name, const char* str);
|
int fdt_fixup_str(void* fdt, int off, const char* node, const char* name, const char* str);
|
||||||
|
|
|
@ -31,7 +31,7 @@
|
||||||
#define PCI_HEADER_TYPE_OFFSET 0x0E
|
#define PCI_HEADER_TYPE_OFFSET 0x0E
|
||||||
#define PCI_BAR0_OFFSET (0x10)
|
#define PCI_BAR0_OFFSET (0x10)
|
||||||
#define PCI_BAR5_OFFSET 0x24
|
#define PCI_BAR5_OFFSET 0x24
|
||||||
#define PCI_BAR5_MASK (~0x3)
|
#define PCI_BAR_MASK (~0x3)
|
||||||
#define PCI_INTR_OFFSET 0x3C
|
#define PCI_INTR_OFFSET 0x3C
|
||||||
#define PCI_HEADER_TYPE_MULTIFUNC_MASK 0x80
|
#define PCI_HEADER_TYPE_MULTIFUNC_MASK 0x80
|
||||||
#define PCI_HEADER_TYPE_TYPE_MASK 0x7F
|
#define PCI_HEADER_TYPE_TYPE_MASK 0x7F
|
||||||
|
@ -50,7 +50,8 @@
|
||||||
#define PCI_MMIO_LIMIT_OFF 0x22
|
#define PCI_MMIO_LIMIT_OFF 0x22
|
||||||
#define PCI_IO_BASE_OFF 0x30
|
#define PCI_IO_BASE_OFF 0x30
|
||||||
#define PCI_IO_LIMIT_OFF 0x32
|
#define PCI_IO_LIMIT_OFF 0x32
|
||||||
|
#define PCI_PWR_MGMT_CTRL_STATUS 0x84
|
||||||
|
#define PCI_POWER_STATE_MASK 0x3
|
||||||
/* Shifts & masks for CONFIG_ADDRESS register */
|
/* Shifts & masks for CONFIG_ADDRESS register */
|
||||||
#define PCI_CONFIG_ADDRESS_ENABLE_BIT_SHIFT 31
|
#define PCI_CONFIG_ADDRESS_ENABLE_BIT_SHIFT 31
|
||||||
#define PCI_CONFIG_ADDRESS_BUS_SHIFT 16
|
#define PCI_CONFIG_ADDRESS_BUS_SHIFT 16
|
||||||
|
@ -70,9 +71,33 @@
|
||||||
#define PCI_COMMAND_MEM_SPACE (1 << 1)
|
#define PCI_COMMAND_MEM_SPACE (1 << 1)
|
||||||
#define PCI_COMMAND_IO_SPACE (1 << 0)
|
#define PCI_COMMAND_IO_SPACE (1 << 0)
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
int bus;
|
||||||
|
int device;
|
||||||
|
int function;
|
||||||
|
uint32_t device_id;
|
||||||
|
} pci_ctrlr_info_t;
|
||||||
|
|
||||||
|
struct pci_enum_info {
|
||||||
|
uint32_t mem;
|
||||||
|
uint32_t mem_limit;
|
||||||
|
uint32_t io;
|
||||||
|
uint32_t mem_pf;
|
||||||
|
uint32_t mem_pf_limit;
|
||||||
|
uint8_t curr_bus_number;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C"
|
||||||
|
{
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef PCH_HAS_PCR
|
||||||
uint32_t pch_read32(uint8_t port_id, uint16_t offset);
|
uint32_t pch_read32(uint8_t port_id, uint16_t offset);
|
||||||
void pch_write32(uint8_t port_id, uint16_t offset, uint32_t val);
|
void pch_write32(uint8_t port_id, uint16_t offset, uint32_t val);
|
||||||
|
#endif
|
||||||
|
|
||||||
uint32_t pci_config_read32(uint8_t bus, uint8_t dev, uint8_t fun, uint8_t off);
|
uint32_t pci_config_read32(uint8_t bus, uint8_t dev, uint8_t fun, uint8_t off);
|
||||||
void pci_config_write32(uint8_t bus, uint8_t dev, uint8_t fun, uint8_t off,
|
void pci_config_write32(uint8_t bus, uint8_t dev, uint8_t fun, uint8_t off,
|
||||||
uint32_t value);
|
uint32_t value);
|
||||||
|
@ -82,5 +107,15 @@ void pci_config_write16(uint8_t bus, uint8_t dev, uint8_t fun, uint8_t off,
|
||||||
uint8_t pci_config_read8(uint8_t bus, uint8_t dev, uint8_t fun, uint8_t off);
|
uint8_t pci_config_read8(uint8_t bus, uint8_t dev, uint8_t fun, uint8_t off);
|
||||||
void pci_config_write8(uint8_t bus, uint8_t dev, uint8_t fun, uint8_t off,
|
void pci_config_write8(uint8_t bus, uint8_t dev, uint8_t fun, uint8_t off,
|
||||||
uint8_t value);
|
uint8_t value);
|
||||||
int pci_enum_do();
|
uint64_t pci_get_mmio_addr(uint8_t bus, uint8_t dev, uint8_t fun, uint8_t bar);
|
||||||
|
|
||||||
|
uint32_t pci_enum_bus(uint8_t bus, struct pci_enum_info *info);
|
||||||
|
|
||||||
|
int pci_enum_do(void);
|
||||||
|
int pci_pre_enum(void);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif /* PCI_H */
|
#endif /* PCI_H */
|
||||||
|
|
|
@ -544,7 +544,7 @@ init_sram_law:
|
||||||
isync
|
isync
|
||||||
|
|
||||||
init_sram_tlb:
|
init_sram_tlb:
|
||||||
/* Inital SRAM: TLB 1, Entry 9, Supervisor X/R/W, M, TS=0, IPROT */
|
/* Initial SRAM: TLB 1, Entry 9, Supervisor X/R/W, M, TS=0, IPROT */
|
||||||
set_tlb(1, 9,
|
set_tlb(1, 9,
|
||||||
INITIAL_SRAM_ADDR, INITIAL_SRAM_ADDR, 0,
|
INITIAL_SRAM_ADDR, INITIAL_SRAM_ADDR, 0,
|
||||||
MAS3_SX | MAS3_SW | MAS3_SR, MAS2_M, 0,
|
MAS3_SX | MAS3_SW | MAS3_SR, MAS2_M, 0,
|
||||||
|
|
82
src/fdt.c
82
src/fdt.c
|
@ -364,6 +364,41 @@ static int fdt_add_property_(void *fdt, int nodeoffset, const char *name,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* return: 0=no match, 1=matched */
|
||||||
|
static int fdt_nodename_eq_(const void *fdt, int offset, const char *s,
|
||||||
|
int len)
|
||||||
|
{
|
||||||
|
const char *p = fdt_offset_ptr(fdt, offset + FDT_TAGSIZE, len+1);
|
||||||
|
if (p == NULL || memcmp(p, s, len) != 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (p[len] == '\0') {
|
||||||
|
return 1;
|
||||||
|
} else if (!memchr(s, '@', len) && (p[len] == '@')) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int fdt_subnode_offset_namelen(const void *fdt, int offset,
|
||||||
|
const char *name, int namelen)
|
||||||
|
{
|
||||||
|
int depth;
|
||||||
|
for (depth = 0;
|
||||||
|
(offset >= 0) && (depth >= 0);
|
||||||
|
offset = fdt_next_node(fdt, offset, &depth))
|
||||||
|
{
|
||||||
|
if ((depth == 1) && fdt_nodename_eq_(fdt, offset, name, namelen)) {
|
||||||
|
return offset;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (depth < 0) {
|
||||||
|
return -FDT_ERR_NOTFOUND;
|
||||||
|
}
|
||||||
|
return offset; /* error */
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* Public Functions */
|
/* Public Functions */
|
||||||
int fdt_check_header(const void *fdt)
|
int fdt_check_header(const void *fdt)
|
||||||
|
@ -514,6 +549,10 @@ int fdt_setprop(void *fdt, int nodeoffset, const char *name, const void *val,
|
||||||
memcpy(prop_data, val, len);
|
memcpy(prop_data, val, len);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (err != 0) {
|
||||||
|
wolfBoot_printf("FDT: Set prop failed! %d (name %d, off %d)\n",
|
||||||
|
err, name, nodeoffset);
|
||||||
|
}
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -581,6 +620,49 @@ int fdt_node_offset_by_compatible(const void *fdt, int startoffset,
|
||||||
return offset;
|
return offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int fdt_add_subnode(void* fdt, int parentoff, const char *name)
|
||||||
|
{
|
||||||
|
int err;
|
||||||
|
struct fdt_node_header *nh;
|
||||||
|
int offset, nextoffset;
|
||||||
|
int nodelen;
|
||||||
|
uint32_t tag, *endtag;
|
||||||
|
int namelen = (int)strlen(name);
|
||||||
|
|
||||||
|
err = fdt_check_header(fdt);
|
||||||
|
if (err != 0)
|
||||||
|
return err;
|
||||||
|
|
||||||
|
offset = fdt_subnode_offset_namelen(fdt, parentoff, name, namelen);
|
||||||
|
if (offset >= 0)
|
||||||
|
return -FDT_ERR_EXISTS;
|
||||||
|
else if (offset != -FDT_ERR_NOTFOUND)
|
||||||
|
return offset;
|
||||||
|
|
||||||
|
/* Find the node after properties */
|
||||||
|
/* skip the first node (BEGIN_NODE) */
|
||||||
|
fdt_next_tag(fdt, parentoff, &nextoffset);
|
||||||
|
do {
|
||||||
|
offset = nextoffset;
|
||||||
|
tag = fdt_next_tag(fdt, offset, &nextoffset);
|
||||||
|
} while ((tag == FDT_PROP) || (tag == FDT_NOP));
|
||||||
|
|
||||||
|
nh = (struct fdt_node_header*)fdt_offset_ptr_(fdt, offset);
|
||||||
|
nodelen = sizeof(*nh) + FDT_TAGALIGN(namelen+1) + FDT_TAGSIZE;
|
||||||
|
|
||||||
|
err = fdt_splice_struct_(fdt, nh, 0, nodelen);
|
||||||
|
if (err == 0) {
|
||||||
|
nh->tag = cpu_to_fdt32(FDT_BEGIN_NODE);
|
||||||
|
memset(nh->name, 0, FDT_TAGALIGN(namelen+1));
|
||||||
|
memcpy(nh->name, name, namelen);
|
||||||
|
endtag = (uint32_t*)((char *)nh + nodelen - FDT_TAGSIZE);
|
||||||
|
*endtag = cpu_to_fdt32(FDT_END_NODE);
|
||||||
|
err = offset;
|
||||||
|
}
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* adjust the actual total size in the FDT header */
|
/* adjust the actual total size in the FDT header */
|
||||||
int fdt_shrink(void* fdt)
|
int fdt_shrink(void* fdt)
|
||||||
{
|
{
|
||||||
|
|
109
src/pci.c
109
src/pci.c
|
@ -77,17 +77,14 @@
|
||||||
#define PCI_ENUM_MM_BAR_MASK ~(0xf)
|
#define PCI_ENUM_MM_BAR_MASK ~(0xf)
|
||||||
#define PCI_ENUM_IO_BAR_MASK ~(0x3)
|
#define PCI_ENUM_IO_BAR_MASK ~(0x3)
|
||||||
|
|
||||||
|
#define CAPID0_A_0_0_0_PCI (0xE4)
|
||||||
|
#define DEVICE_ENABLE (0x54)
|
||||||
|
#define DTT_DEVICE_DISABLE (1 << 15)
|
||||||
#define ONE_MB (1024 * 1024)
|
#define ONE_MB (1024 * 1024)
|
||||||
#define FOUR_KB (4 * 1024)
|
#define FOUR_KB (4 * 1024)
|
||||||
|
|
||||||
struct pci_enum_info {
|
static int pci_enum_is_64bit(uint32_t value);
|
||||||
uint32_t mem;
|
static int pci_enum_is_mmio(uint32_t value);
|
||||||
uint32_t mem_limit;
|
|
||||||
uint32_t io;
|
|
||||||
uint32_t mem_pf;
|
|
||||||
uint32_t mem_pf_limit;
|
|
||||||
uint8_t curr_bus_number;
|
|
||||||
};
|
|
||||||
|
|
||||||
static inline uint32_t align_up(uint32_t address, uint32_t alignment) {
|
static inline uint32_t align_up(uint32_t address, uint32_t alignment) {
|
||||||
return (address + alignment - 1) & ~(alignment - 1);
|
return (address + alignment - 1) & ~(alignment - 1);
|
||||||
|
@ -202,7 +199,7 @@ static void pci_ecam_config_write16(uint8_t bus, uint8_t dev, uint8_t fun,
|
||||||
|
|
||||||
#define PCI_IO_CONFIG_ADDR(bus, dev, fn, off) \
|
#define PCI_IO_CONFIG_ADDR(bus, dev, fn, off) \
|
||||||
(uint32_t)( \
|
(uint32_t)( \
|
||||||
(1UL << PCI_CONFIG_ADDRESS_ENABLE_BIT_SHIFT) | \
|
(1 << PCI_CONFIG_ADDRESS_ENABLE_BIT_SHIFT) | \
|
||||||
(bus << PCI_CONFIG_ADDRESS_BUS_SHIFT) | \
|
(bus << PCI_CONFIG_ADDRESS_BUS_SHIFT) | \
|
||||||
(dev << PCI_CONFIG_ADDRESS_DEVICE_SHIFT) | \
|
(dev << PCI_CONFIG_ADDRESS_DEVICE_SHIFT) | \
|
||||||
(fn << PCI_CONFIG_ADDRESS_FUNCTION_SHIFT) | \
|
(fn << PCI_CONFIG_ADDRESS_FUNCTION_SHIFT) | \
|
||||||
|
@ -340,6 +337,36 @@ uint8_t pci_config_read8(uint8_t bus, uint8_t dev, uint8_t fun, uint8_t off)
|
||||||
return (reg >> shift);
|
return (reg >> shift);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint64_t pci_get_mmio_addr(uint8_t bus, uint8_t dev, uint8_t fun, uint8_t bar)
|
||||||
|
{
|
||||||
|
uint32_t reg;
|
||||||
|
uint64_t addr = 0;
|
||||||
|
|
||||||
|
if (bar >= PCI_ENUM_MAX_BARS)
|
||||||
|
{
|
||||||
|
return addr;
|
||||||
|
}
|
||||||
|
|
||||||
|
reg = pci_config_read32(bus, dev, fun, PCI_BAR0_OFFSET + (bar * 8));
|
||||||
|
wolfBoot_printf("BAR%d[0x%x] reg value = 0x%x\r\n", bar, PCI_BAR0_OFFSET + (bar * 8), reg);
|
||||||
|
|
||||||
|
if (!pci_enum_is_mmio(reg))
|
||||||
|
{
|
||||||
|
return addr;
|
||||||
|
}
|
||||||
|
|
||||||
|
addr = reg & 0xFFFFFFF0;
|
||||||
|
|
||||||
|
if (pci_enum_is_64bit(reg))
|
||||||
|
{
|
||||||
|
reg = pci_config_read32(bus, dev, fun, (PCI_BAR0_OFFSET + 4) + (bar * 8));
|
||||||
|
wolfBoot_printf("BAR%d_HIGH[0x%x] reg value = 0x%x\r\n", bar, (PCI_BAR0_OFFSET + 4) + (bar * 8), reg);
|
||||||
|
addr |= ((uint64_t)reg << 32);
|
||||||
|
}
|
||||||
|
|
||||||
|
return addr;
|
||||||
|
}
|
||||||
|
|
||||||
static int pci_enum_is_64bit(uint32_t value)
|
static int pci_enum_is_64bit(uint32_t value)
|
||||||
{
|
{
|
||||||
uint8_t type = (value & PCI_ENUM_TYPE_MASK) >> PCI_ENUM_TYPE_SHIFT;
|
uint8_t type = (value & PCI_ENUM_TYPE_MASK) >> PCI_ENUM_TYPE_SHIFT;
|
||||||
|
@ -380,7 +407,8 @@ static int pci_pre_enum_cb(uint8_t bus, uint8_t dev, uint8_t fun)
|
||||||
#ifdef WOLFBOOT_TGL
|
#ifdef WOLFBOOT_TGL
|
||||||
if (bus != 0)
|
if (bus != 0)
|
||||||
return 0;
|
return 0;
|
||||||
if (dev == 0x1e) {
|
/* don't change UART mapping */
|
||||||
|
if (dev == 0x1e && (fun == 0 || fun == 1)) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
/* PMC BARs shouldn't be programmed as per FSP integration guide */
|
/* PMC BARs shouldn't be programmed as per FSP integration guide */
|
||||||
|
@ -420,6 +448,7 @@ static int pci_program_bar(uint8_t bus, uint8_t dev, uint8_t fun,
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
is_prefetch = 0;
|
is_prefetch = 0;
|
||||||
|
(void)is_prefetch;
|
||||||
bar_off = PCI_BAR0_OFFSET + bar_idx * 4;
|
bar_off = PCI_BAR0_OFFSET + bar_idx * 4;
|
||||||
orig_bar = pci_config_read32(bus, dev, fun, bar_off);
|
orig_bar = pci_config_read32(bus, dev, fun, bar_off);
|
||||||
pci_config_write32(bus, dev, fun, bar_off, 0xffffffff);
|
pci_config_write32(bus, dev, fun, bar_off, 0xffffffff);
|
||||||
|
@ -498,6 +527,7 @@ restore_bar:
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(DEBUG_PCI)
|
||||||
static void pci_dump_id(uint8_t bus, uint8_t dev, uint8_t fun)
|
static void pci_dump_id(uint8_t bus, uint8_t dev, uint8_t fun)
|
||||||
{
|
{
|
||||||
uint16_t vid, did;
|
uint16_t vid, did;
|
||||||
|
@ -505,9 +535,17 @@ static void pci_dump_id(uint8_t bus, uint8_t dev, uint8_t fun)
|
||||||
vid = pci_config_read16(bus, dev, fun, PCI_VENDOR_ID_OFFSET);
|
vid = pci_config_read16(bus, dev, fun, PCI_VENDOR_ID_OFFSET);
|
||||||
did = pci_config_read16(bus, dev, fun, PCI_DEVICE_ID_OFFSET);
|
did = pci_config_read16(bus, dev, fun, PCI_DEVICE_ID_OFFSET);
|
||||||
|
|
||||||
PCI_DEBUG_PRINTF("PCI enum: dev: %x:%x.%x vid: %x did: %x\r\n",
|
PCI_DEBUG_PRINTF("\r\n\r\nPCI: %x:%x.%x %x:%x\r\n",
|
||||||
bus, dev, fun, (int)vid, (int)did);
|
bus, dev, fun, (int)vid, (int)did);
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
static inline void pci_dump_id(uint8_t bus, uint8_t dev, uint8_t fun)
|
||||||
|
{
|
||||||
|
(void)bus;
|
||||||
|
(void)dev;
|
||||||
|
(void)fun;
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
static int pci_program_bars(uint8_t bus, uint8_t dev, uint8_t fun,
|
static int pci_program_bars(uint8_t bus, uint8_t dev, uint8_t fun,
|
||||||
struct pci_enum_info *info)
|
struct pci_enum_info *info)
|
||||||
|
@ -535,8 +573,6 @@ static int pci_program_bars(uint8_t bus, uint8_t dev, uint8_t fun,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint32_t pci_enum_bus(uint8_t bus, struct pci_enum_info *info);
|
|
||||||
|
|
||||||
#ifdef DEBUG_PCI
|
#ifdef DEBUG_PCI
|
||||||
static void pci_dump_bridge(uint8_t bus, uint8_t dev, uint8_t fun)
|
static void pci_dump_bridge(uint8_t bus, uint8_t dev, uint8_t fun)
|
||||||
{
|
{
|
||||||
|
@ -579,12 +615,12 @@ static int pci_program_bridge(uint8_t bus, uint8_t dev, uint8_t fun,
|
||||||
uint32_t orig_cmd;
|
uint32_t orig_cmd;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
PCI_DEBUG_PRINTF("bridge: %x.%x.%x\r\n",
|
|
||||||
(int)bus, (int)dev, (int)fun);
|
|
||||||
orig_cmd = pci_config_read16(bus, dev, fun, PCI_COMMAND_OFFSET);
|
orig_cmd = pci_config_read16(bus, dev, fun, PCI_COMMAND_OFFSET);
|
||||||
pci_config_write16(bus, dev, fun, PCI_COMMAND_OFFSET, 0);
|
pci_config_write16(bus, dev, fun, PCI_COMMAND_OFFSET, 0);
|
||||||
|
|
||||||
info->curr_bus_number++;
|
info->curr_bus_number++;
|
||||||
|
PCI_DEBUG_PRINTF("Bridge: %x.%x.%x (using bus number: %d)\r\n",
|
||||||
|
(int)bus, (int)dev, (int)fun, info->curr_bus_number);
|
||||||
pci_config_write8(bus, dev, fun, PCI_PRIMARY_BUS, bus);
|
pci_config_write8(bus, dev, fun, PCI_PRIMARY_BUS, bus);
|
||||||
pci_config_write8(bus, dev, fun, PCI_SECONDARY_BUS, info->curr_bus_number);
|
pci_config_write8(bus, dev, fun, PCI_SECONDARY_BUS, info->curr_bus_number);
|
||||||
|
|
||||||
|
@ -691,27 +727,33 @@ static int pci_program_bridge(uint8_t bus, uint8_t dev, uint8_t fun,
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint32_t pci_enum_bus(uint8_t bus, struct pci_enum_info *info)
|
uint32_t pci_enum_bus(uint8_t bus, struct pci_enum_info *info)
|
||||||
{
|
{
|
||||||
uint16_t vendor_id, device_id, header_type;
|
uint16_t vendor_id, device_id, header_type;
|
||||||
uint32_t vd_code, reg;
|
uint32_t vd_code, reg;
|
||||||
uint32_t dev, fun;
|
uint32_t dev, fun;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
PCI_DEBUG_PRINTF("enumerating bus %d\r\n", bus);
|
||||||
|
|
||||||
for (dev = 0; dev < PCI_ENUM_MAX_DEV; dev++) {
|
for (dev = 0; dev < PCI_ENUM_MAX_DEV; dev++) {
|
||||||
|
|
||||||
vd_code = pci_config_read32(bus, dev, 0, 0x0);
|
vd_code = pci_config_read32(bus, dev, 0, PCI_VENDOR_ID_OFFSET);
|
||||||
if (vd_code == 0xFFFFFFFF) {
|
if (vd_code == 0xFFFFFFFF) {
|
||||||
|
PCI_DEBUG_PRINTF("Skipping %x:%x\r\n", bus, dev);
|
||||||
/* No device here. */
|
/* No device here. */
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (fun = 0; fun < PCI_ENUM_MAX_FUN; fun++) {
|
for (fun = 0; fun < PCI_ENUM_MAX_FUN; fun++) {
|
||||||
if (pci_pre_enum_cb(bus, dev, fun))
|
if (pci_pre_enum_cb(bus, dev, fun)) {
|
||||||
|
PCI_DEBUG_PRINTF("skipping fun %x:%x.%x\r\n", bus, dev, fun);
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
vd_code = pci_config_read32(bus, dev, fun, PCI_VENDOR_ID_OFFSET);
|
vd_code = pci_config_read32(bus, dev, fun, PCI_VENDOR_ID_OFFSET);
|
||||||
if (vd_code == 0xFFFFFFFF) {
|
if (vd_code == 0xFFFFFFFF) {
|
||||||
|
PCI_DEBUG_PRINTF("Skipping %x:%x.%x\r\n", bus, dev, fun);
|
||||||
/* No device here, try next function*/
|
/* No device here, try next function*/
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -725,16 +767,37 @@ static uint32_t pci_enum_bus(uint8_t bus, struct pci_enum_info *info)
|
||||||
pci_program_bridge(bus, dev, fun, info);
|
pci_program_bridge(bus, dev, fun, info);
|
||||||
}
|
}
|
||||||
/* just one function */
|
/* just one function */
|
||||||
if (!(header_type & PCI_HEADER_TYPE_MULTIFUNC_MASK))
|
if ((fun == 0) && !(header_type & PCI_HEADER_TYPE_MULTIFUNC_MASK)) {
|
||||||
|
PCI_DEBUG_PRINTF("one function only device\r\n");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int pci_enum_do()
|
int pci_pre_enum(void)
|
||||||
|
{
|
||||||
|
uint32_t reg;
|
||||||
|
|
||||||
|
reg = pci_config_read32(0, 0, 0, CAPID0_A_0_0_0_PCI);
|
||||||
|
wolfBoot_printf("cap a %d\r\n", reg);
|
||||||
|
wolfBoot_printf("ddt disabled %d\r\n", reg & DTT_DEVICE_DISABLE);
|
||||||
|
reg &= ~(DTT_DEVICE_DISABLE);
|
||||||
|
pci_config_write32(0, 0, 0, CAPID0_A_0_0_0_PCI, reg);
|
||||||
|
reg = pci_config_read32(0, 0, 0, DEVICE_ENABLE);
|
||||||
|
wolfBoot_printf("device enable: %d\r\n", reg);
|
||||||
|
reg |= (1 << 7);
|
||||||
|
pci_config_write32(0, 0, 0, DEVICE_ENABLE, reg);
|
||||||
|
reg = pci_config_read32(0, 0, 0, DEVICE_ENABLE);
|
||||||
|
wolfBoot_printf("device enable: %d\r\n", reg);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int pci_enum_do(void)
|
||||||
{
|
{
|
||||||
struct pci_enum_info enum_info;
|
struct pci_enum_info enum_info;
|
||||||
int ret;
|
int ret;
|
||||||
|
@ -747,6 +810,12 @@ int pci_enum_do()
|
||||||
enum_info.io = PCI_IO32_BASE;
|
enum_info.io = PCI_IO32_BASE;
|
||||||
enum_info.curr_bus_number = 0;
|
enum_info.curr_bus_number = 0;
|
||||||
|
|
||||||
|
ret = pci_pre_enum();
|
||||||
|
if (ret != 0) {
|
||||||
|
wolfBoot_printf("pci_pre_enum error: %d\r\n", ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
ret = pci_enum_bus(0, &enum_info);
|
ret = pci_enum_bus(0, &enum_info);
|
||||||
|
|
||||||
PCI_DEBUG_PRINTF("PCI Memory Mapped I/O range [0x%x,0x%x] (0x%x)\r\n",
|
PCI_DEBUG_PRINTF("PCI Memory Mapped I/O range [0x%x,0x%x] (0x%x)\r\n",
|
||||||
|
|
Loading…
Reference in New Issue