[Skiboot] [PATCH v3 2/6] VAS: Initialize the basic VAS internal registers

Balbir Singh bsingharora at gmail.com
Thu Dec 1 23:00:06 AEDT 2016



On 30/11/16 16:36, Sukadev Bhattiprolu wrote:
> Initialize the basic VAS internal registers that are needed for a
> functioning VAS. 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 [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        | 297 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
>  include/chip.h    |   2 +
>  4 files changed, 304 insertions(+), 1 deletion(-)
>  create mode 100644 core/vas.c
> 
> diff --git a/core/Makefile.inc b/core/Makefile.inc
> index 9223af1..f41617d 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
> +CORE_OBJS += flash-subpartition.o vas.o
>  
>  ifeq ($(SKIBOOT_GCOV),1)
>  CORE_OBJS += gcov-profiling.o
> diff --git a/core/init.c b/core/init.c
> index 9d4ab60..2af5427 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>
>  
> @@ -909,6 +910,9 @@ void __noreturn __nomcount main_cpu_entry(const void *fdt)
>  	phb3_preload_capp_ucode();
>  	start_preload_kernel();
>  
> +	/* Virtual Accelerator Switchboard */
> +	init_vas();

vas_init() -- along the lines of nx_init(). I think this will end up
affecting a lot of functions that follow

> +
>  	/* NX init */
>  	nx_init();
>  
> diff --git a/core/vas.c b/core/vas.c
> new file mode 100644
> index 0000000..2b3d8dd
> --- /dev/null
> +++ b/core/vas.c
> @@ -0,0 +1,297 @@
> +/* 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
> +
> +/*
> + * TODO: Set to 64K after initial development.
> + */
> +static int max_win_per_chip = 16;
> +static int vas_initialized;
> +
> +static uint64_t get_hvwc_mmio_bar(const int chipid)
> +{
> +	return VAS_HVWC_MMIO_BAR_BASE + chipid * VAS_HVWC_MMIO_BAR_SIZE;
> +}
> +
> +static uint64_t get_uwc_mmio_bar(int chipid)
> +{
> +	return VAS_UWC_MMIO_BAR_BASE + chipid * VAS_UWC_MMIO_BAR_SIZE;
> +}
> +

Is there a reason these are not inline?

> +static inline uint64_t compute_vas_scom_addr(uint64_t ring_sat_offset)
> +{
> +	return VAS_SCOM_BASE_ADDR + ring_sat_offset;
> +}
> +
> +static 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)
> +{

north_ctl -- north_ctrl?

> +	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 int reset_north_ctl(struct proc_chip *chip)
> +{
> +	return vas_scom_write(chip, VAS_MISC_N_CTL, 0ULL);

I think this may be incorrect. Ideally we want to set it to
a value that we read at init time from VAS_MISC_N_CTRL register.
I am saying this because I see some reserved fields in the
register and I am not sure we can write 0's to them on reset

> +}
> +
> +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 = 0ULL;
> +	val = SETFIELD(VAS_RMA_BAR_ADDR_MASK, val, 0x08000000000ULL);
> +

Isn't it simpler to say
	val = SETFIELD(VAS_RMA_BAR_ADDR_MASK, 0ULL, 0x08000000000ULL);

If I am reading the document correctly, this is also the reset value,
but I presume this function assumes that we can write to VAS_RMA_BAR_ADDR_MASK
more than once after init? Don't we also need to write the chipid bits
in the mask?

> +	rc = vas_scom_write(chip, VAS_RMA_BAR, val);
> +	if (rc)
> +		return rc;
> +
> +	val = 0ULL;
> +	val = SETFIELD(VAS_RMA_BAMR_ADDR_MASK, val, 0xFFFC0000000ULL);
> +
Ditto

> +	rc = vas_scom_write(chip, VAS_RMA_BAMR, val);
Same as above.

> +
> +	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);
gr> +
> +	/*
> +	 * 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);

Should this be zalloc? so that the window is seen as closed?

> +	if (!wcbs) {
> +		prerror("VAS: Unable to allocate memory for backing store\n");

At this point is it possible to use lesster than 512 64K windows and retry?


Balbir


More information about the Skiboot mailing list