[Skiboot] [PATCH v5 3/7] vas: Initialize VAS registers
Sukadev Bhattiprolu
sukadev at linux.vnet.ibm.com
Thu Jan 26 12:32:29 AEDT 2017
Initialize the VAS registers on each of instance that we discover.
Initializing VAS involves writing either pre-defined values or allocated
addresses to appropriate SCOM addresses.
Signed-off-by: Sukadev Bhattiprolu <sukadev at linux.vnet.ibm.com>
---
Changelog [v6]
- Move creation of device tree nodes to separate patch
- Assign a sequential id to each instance of VAS that callers/users
can use to identif a specific instance of VAS.
Changelog [v4]
- Balbir Singh] Make some functions inline; Zero the memory allocated
for backin-store; simplify some bit-field initializations;
create a per-chip device tree node for VAS
- Drop init_windows() function. Kernel initializes the windows
before each use. No need to initialize during boot.
Changelog [v3]
- [Oliver O'Halloran] Fold changes to vas.c and Makefile.inc from
patch 1 into current patch; use constant 'true' for the
(unnecessary) macros that were removed by earlier patch;
free wcbs memory if any chip fails initialization;use
prolog()/prerror() instead of printf; Use out_be64() to
write to the MMIO address
- [Oliver O'Halloran, Alistair Popple] Use proc_gen to check for P9
- Move vas_vdbg() macro from later patch into this.
---
core/Makefile.inc | 2 +-
core/init.c | 4 +
core/vas.c | 245 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
include/chip.h | 3 +
4 files changed, 253 insertions(+), 1 deletion(-)
create mode 100644 core/vas.c
diff --git a/core/Makefile.inc b/core/Makefile.inc
index 2167044..3f70d4c 100644
--- a/core/Makefile.inc
+++ b/core/Makefile.inc
@@ -8,7 +8,7 @@ CORE_OBJS += pci-opal.o fast-reboot.o device.o exceptions.o trace.o affinity.o
CORE_OBJS += vpd.o hostservices.o platform.o nvram.o nvram-format.o hmi.o
CORE_OBJS += console-log.o ipmi.o time-utils.o pel.o pool.o errorlog.o
CORE_OBJS += timer.o i2c.o rtc.o flash.o sensor.o ipmi-opal.o
-CORE_OBJS += flash-subpartition.o bitmap.o buddy.o
+CORE_OBJS += flash-subpartition.o bitmap.o buddy.o vas.o
ifeq ($(SKIBOOT_GCOV),1)
CORE_OBJS += gcov-profiling.o
diff --git a/core/init.c b/core/init.c
index c753b61..1f5a8f3 100644
--- a/core/init.c
+++ b/core/init.c
@@ -45,6 +45,7 @@
#include <sensor.h>
#include <xive.h>
#include <nvram.h>
+#include <vas.h>
#include <libstb/stb.h>
#include <libstb/container.h>
@@ -915,6 +916,9 @@ void __noreturn __nomcount main_cpu_entry(const void *fdt)
phb3_preload_capp_ucode();
start_preload_kernel();
+ /* Virtual Accelerator Switchboard */
+ vas_init();
+
/* NX init */
nx_init();
diff --git a/core/vas.c b/core/vas.c
new file mode 100644
index 0000000..63a3f42
--- /dev/null
+++ b/core/vas.c
@@ -0,0 +1,245 @@
+/* Copyright 2013-2016 IBM Corp.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ * implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include <skiboot.h>
+#include <chip.h>
+#include <xscom.h>
+#include <io.h>
+#include <vas.h>
+
+#undef VAS_VERBOSE_DEBUG
+#ifdef VAS_VERBOSE_DEBUG
+#define vas_vdbg(__x,__fmt,...) prlog(PR_DEBUG,"VAS: " __fmt, ##__VA_ARGS)
+#else
+#define vas_vdbg(__x,__fmt,...) do { } while (0)
+#endif
+
+static int vas_initialized;
+
+static inline uint64_t get_hvwc_mmio_bar(const int chipid)
+{
+ return VAS_HVWC_MMIO_BAR_BASE + chipid * VAS_HVWC_MMIO_BAR_SIZE;
+}
+
+static inline uint64_t get_uwc_mmio_bar(int chipid)
+{
+ return VAS_UWC_MMIO_BAR_BASE + chipid * VAS_UWC_MMIO_BAR_SIZE;
+}
+
+static inline uint64_t compute_vas_scom_addr(uint64_t ring_sat_offset)
+{
+ return VAS_SCOM_BASE_ADDR + ring_sat_offset;
+}
+
+static inline int vas_scom_write(struct proc_chip *chip, uint64_t reg,
+ uint64_t val)
+{
+ return xscom_write(chip->id, compute_vas_scom_addr(reg), val);
+}
+
+static inline int vas_scom_read(struct proc_chip *chip, uint64_t reg,
+ uint64_t *val)
+{
+ return xscom_read(chip->id, compute_vas_scom_addr(reg), val);
+}
+
+static int init_north_ctl(struct proc_chip *chip)
+{
+ uint64_t val = 0ULL;
+
+ val = SETFIELD(VAS_64K_MODE_MASK, val, true);
+ val = SETFIELD(VAS_ACCEPT_PASTE_MASK, val, true);
+
+ return vas_scom_write(chip, VAS_MISC_N_CTL, val);
+}
+
+static inline int reset_north_ctl(struct proc_chip *chip)
+{
+ return vas_scom_write(chip, VAS_MISC_N_CTL, 0ULL);
+}
+
+static void reset_fir(struct proc_chip *chip)
+{
+ uint64_t val;
+
+ val = 0x0ULL;
+ vas_scom_write(chip, VAS_FIR0, val);
+ vas_scom_write(chip, VAS_FIR1, val);
+ vas_scom_write(chip, VAS_FIR2, val);
+ vas_scom_write(chip, VAS_FIR3, val);
+ vas_scom_write(chip, VAS_FIR4, val);
+ vas_scom_write(chip, VAS_FIR5, val);
+ vas_scom_write(chip, VAS_FIR6, val);
+ vas_scom_write(chip, VAS_FIR7, val);
+}
+
+/*
+ * Initialize RMA BAR and RMA Base Address Mask Register (BAMR) to their
+ * default values. This will cause VAS to accept paste commands to all
+ * chips in the system.
+ */
+static int init_rma(struct proc_chip *chip)
+{
+ int rc;
+ uint64_t val;
+
+ val = SETFIELD(VAS_RMA_BAR_ADDR_MASK, 0ULL, 0x08000000000ULL);
+
+ rc = vas_scom_write(chip, VAS_RMA_BAR, val);
+ if (rc)
+ return rc;
+
+ val = SETFIELD(VAS_RMA_BAMR_ADDR_MASK, 0ULL, 0xFFFC0000000ULL);
+
+ rc = vas_scom_write(chip, VAS_RMA_BAMR, val);
+
+ return rc;
+}
+
+/*
+ * Window Context MMIO (WCM) Region for each chip is assigned in the P9
+ * MMIO MAP spreadsheet. Write this value to the SCOM address associated
+ * with WCM_BAR.
+ */
+static int init_wcm(struct proc_chip *chip)
+{
+ uint64_t wcmbar;
+
+ wcmbar = get_hvwc_mmio_bar(chip->id);
+
+ /*
+ * Write the entire WCMBAR address to the SCOM address. VAS will
+ * extract bits that it thinks are relevant i.e bits 8..38
+ */
+ return vas_scom_write(chip, VAS_WCM_BAR, wcmbar);
+}
+
+/*
+ * OS/User Window Context MMIO (UWCM) Region for each is assigned in the
+ * P9 MMIO MAP spreadsheet. Write this value to the SCOM address associated
+ * with UWCM_BAR.
+ */
+static int init_uwcm(struct proc_chip *chip)
+{
+ uint64_t uwcmbar;
+
+ uwcmbar = get_uwc_mmio_bar(chip->id);
+
+ /*
+ * Write the entire UWCMBAR address to the SCOM address. VAS will
+ * extract bits that it thinks are relevant i.e bits 8..35.
+ */
+ return vas_scom_write(chip, VAS_UWCM_BAR, uwcmbar);
+}
+
+static inline void free_wcbs(struct proc_chip *chip)
+{
+ free((void *)chip->vas_wcbs);
+}
+
+/*
+ * VAS needs a backing store for the 64K window contexts on a chip.
+ * (64K times 512 = 8MB). This region needs to be contiguous, so
+ * allocate during early boot. Then write the allocated address to
+ * the SCOM address for the Backing store BAR.
+ */
+static int alloc_init_wcbs(struct proc_chip *chip)
+{
+ int rc;
+ uint64_t wcbs;
+ size_t size;
+
+ /* align to the backing store size */
+ size = (size_t)VAS_WCBS_SIZE;
+ wcbs = (uint64_t)local_alloc(chip->id, size, size);
+ if (!wcbs) {
+ prerror("VAS: Unable to allocate memory for backing store\n");
+ return -ENOMEM;
+ }
+ memset((void *)wcbs, 0ULL, size);
+
+ /*
+ * Write entire WCBS_BAR address to the SCOM address. VAS will extract
+ * relevant bits.
+ */
+ rc = vas_scom_write(chip, VAS_WCBS_BAR, wcbs);
+ if (rc != OPAL_SUCCESS)
+ goto out;
+
+ chip->vas_wcbs = wcbs;
+ return OPAL_SUCCESS;
+
+out:
+ free((void *)wcbs);
+ return rc;
+}
+
+/*
+ * Initialize VAS on one chip
+ */
+static int init_one_chip(struct proc_chip *chip)
+{
+ static int vas_instance;
+
+ chip->vas_id = vas_instance++;
+ if (alloc_init_wcbs(chip) || init_wcm(chip) || init_uwcm(chip))
+ return -1;
+
+ reset_fir(chip);
+
+ if (init_north_ctl(chip))
+ goto free_wcbs;
+
+ if (init_rma(chip))
+ goto out;
+
+ prlog(PR_INFO, "VAS: Initialized chip %d\n", chip->id);
+ return 0;
+
+out:
+ reset_north_ctl(chip);
+free_wcbs:
+ free_wcbs(chip);
+ return -1;
+}
+
+void vas_init()
+{
+ struct proc_chip *chip;
+
+ chip = next_chip(NULL);
+
+ if (proc_gen != proc_gen_p9)
+ return;
+
+ for_each_chip(chip) {
+ assert(chip->vas_wcbs == 0ULL);
+ if (init_one_chip(chip))
+ goto cleanup;
+ }
+
+ vas_initialized = 1;
+ prlog(PR_NOTICE, "VAS: Initialized\n");
+ return;
+
+cleanup:
+ /* Free memory and ensure no chip accepts paste instructions */
+ for_each_chip(chip) {
+ free_wcbs(chip);
+ reset_north_ctl(chip);
+ }
+ prerror("VAS: Disabled (failed initialization)\n");
+ return;
+}
diff --git a/include/chip.h b/include/chip.h
index f16f00b..9756a98 100644
--- a/include/chip.h
+++ b/include/chip.h
@@ -209,6 +209,9 @@ struct proc_chip {
/* Used by hw/xive.c */
struct xive *xive;
+
+ uint32_t vas_id;
+ uint64_t vas_wcbs;
};
extern uint32_t pir_to_chip_id(uint32_t pir);
--
2.7.4
More information about the Skiboot
mailing list