mirror of
https://github.com/thead-yocto-mirror/meta-riscv
synced 2026-09-18 13:12:34 +02:00
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>
132 lines
5.2 KiB
Diff
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
|
|
|