Files
meta-riscv/recipes-devtools/riscv-tools/files/0003-Add-microsemi-pcie-entry-in-bbl.patch
Alistair Francis 0e4b714f49 riscv-tools: Add support for the MicroSemi PCIe device
Add functionality to bbl to modify the device tree passed to Linux to
specify the MicroSemi PCIe device.

Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
2018-12-21 09:49:59 -08:00

132 lines
5.2 KiB
Diff

From cc4cc207c0cb3bdb9cce938b48aaa6ed117bf913 Mon Sep 17 00:00:00 2001
From: Atish Patra <atish.patra@wdc.com>
Date: Fri, 6 Jul 2018 10:35:48 -0700
Subject: [PATCH 2/2] Add microsemi pcie entry in bbl.
Signed-off-by: Atish Patra <atish.patra@wdc.com>
---
bbl/bbl.c | 10 ++++++++++
machine/mfdt.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++
machine/mfdt.h | 1 +
3 files changed, 65 insertions(+)
diff --git a/bbl/bbl.c b/bbl/bbl.c
index 523b771..9f48346 100644
--- a/bbl/bbl.c
+++ b/bbl/bbl.c
@@ -7,6 +7,8 @@
#include "bits.h"
#include "config.h"
#include "mfdt.h"
+#include "libfdt.h"
+#include "fdt.h"
#include <string.h>
extern char _payload_start, _payload_end; /* internal payload */
@@ -29,10 +31,18 @@ static uintptr_t dtb_output()
static void filter_dtb(uintptr_t source)
{
+ int err;
uintptr_t dest = dtb_output();
uint32_t size = fdt_size(source);
memcpy((void*)dest, (void*)source, size);
+ // Allocate space for additional nodes i.e. timer, cpu-map
+ err = fdt_open_into((void *)dest, (void *)dest, size + 2048);
+
+ if (err < 0)
+ die("%s: fdt buffer couldn't be expanded err = [%d]!!\n", __func__, err);
+
+ add_msemi_pcie_node((void *)dest);
// Remove information from the chained FDT
filter_harts(dest, &disabled_hart_mask);
filter_plic(dest);
diff --git a/machine/mfdt.c b/machine/mfdt.c
index a6ccbad..886d691 100644
--- a/machine/mfdt.c
+++ b/machine/mfdt.c
@@ -5,6 +5,8 @@
#include <string.h>
#include "config.h"
#include "mfdt.h"
+#include "libfdt.h"
+#include "fdt.h"
#include "mtrap.h"
static inline uint32_t bswap(uint32_t x)
@@ -685,6 +687,58 @@ void filter_harts(uintptr_t fdt, long *disabled_hart_mask)
fdt_scan(fdt, &cb);
}
+//////////////////////////////////////////// NODE ADD //////////////////////////////////////////////
+#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
+
+#define fdt_setprop_cells(fdt, node_offset, property, ...) \
+ do { \
+ uint32_t qdt_tmp[] = { __VA_ARGS__ }; \
+ int i; \
+ \
+ for (i = 0; i < ARRAY_SIZE(qdt_tmp); i++) { \
+ qdt_tmp[i] = bswap(qdt_tmp[i]); \
+ } \
+ fdt_setprop(fdt, node_offset, property, qdt_tmp, \
+ sizeof(qdt_tmp)); \
+ } while (0)
+
+void add_msemi_pcie_node(void *dtb)
+{
+ int pci_offset;
+ int msemi_pci_offset;
+ int intc_offset;
+ int pci_intc_phandle;
+ int pci_intc_parent = fdt_get_phandle(dtb,fdt_path_offset(dtb, "/soc/interrupt-controller"));
+ pci_offset = fdt_path_offset(dtb, "/soc");
+ msemi_pci_offset = fdt_add_subnode(dtb, pci_offset, "pcix");
+ printm("In pci_offset = [%d] msem = [%d] parent = [%d]\n", pci_offset, msemi_pci_offset, pci_intc_parent);
+ fdt_setprop_cell(dtb, msemi_pci_offset, "#address-cells", 3);
+ fdt_setprop_cell(dtb, msemi_pci_offset, "#interrupt-cells", 1);
+ fdt_setprop_cell(dtb, msemi_pci_offset, "#size-cells", 2);
+ fdt_setprop_string(dtb, msemi_pci_offset, "compatible", "ms-pf,axi-pcie-host");
+ fdt_setprop_string(dtb, msemi_pci_offset, "device_type", "pci");
+
+ fdt_setprop_cells(dtb, msemi_pci_offset, "bus-range", 0x01, 0x7f);
+ fdt_setprop_cells(dtb, msemi_pci_offset, "interrupt-map-mask", 0, 0, 0, 7);
+ fdt_setprop_cell(dtb, msemi_pci_offset, "interrupt-parent", pci_intc_parent);
+ fdt_setprop_cell(dtb, msemi_pci_offset, "interrupts", 32);
+
+
+ fdt_setprop_cells(dtb, msemi_pci_offset, "ranges", 0x2000000, 0x0, 0x40000000, 0x0, 0x40000000, 0x0, 0x20000000);
+ fdt_setprop_cells(dtb, msemi_pci_offset, "reg", 0x20, 0x30000000, 0x0, 0x4000000, 0x20, 0x0, 0x0, 0x100000);
+ fdt_setprop(dtb, msemi_pci_offset, "reg-names", "control",sizeof("control"));
+ fdt_appendprop(dtb, msemi_pci_offset, "reg-names", "apb",sizeof("apb"));
+
+
+ intc_offset = fdt_add_subnode(dtb, msemi_pci_offset, "ms_pcie_intc");
+ fdt_setprop_cell(dtb, intc_offset, "#address-cells", 0);
+ fdt_setprop_cell(dtb, intc_offset, "#interrupt-cells", 1);
+ fdt_setprop(dtb, intc_offset, "interrupt-controller", NULL, 0);
+ fdt_setprop_cells(dtb, intc_offset, "phandle", 50);
+
+ pci_intc_phandle = fdt_get_phandle(dtb,intc_offset);
+ fdt_setprop_cells(dtb, msemi_pci_offset, "interrupt-map", 0, 0, 0, 1, pci_intc_phandle, 1, 0, 0, 0, 2, pci_intc_phandle, 2, 0, 0, 0 ,3,pci_intc_phandle, 3, 0, 0, 0, 4, pci_intc_phandle, 4);
+}
//////////////////////////////////////////// PRINT //////////////////////////////////////////////
#ifdef PK_PRINT_DEVICE_TREE
diff --git a/machine/mfdt.h b/machine/mfdt.h
index 97aa70d..1b0109d 100644
--- a/machine/mfdt.h
+++ b/machine/mfdt.h
@@ -68,6 +68,7 @@ void filter_harts(uintptr_t fdt, long *disabled_hart_mask);
void filter_plic(uintptr_t fdt);
void filter_compat(uintptr_t fdt, const char *compat);
+void add_msemi_pcie_node(void *fdt);
// The hartids of available harts
extern uint64_t hart_mask;
--
2.19.1