03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * CDDL HEADER START
03831d35f7499c87d51205817c93e9a8d42c4baestevel *
03831d35f7499c87d51205817c93e9a8d42c4baestevel * The contents of this file are subject to the terms of the
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Common Development and Distribution License, Version 1.0 only
03831d35f7499c87d51205817c93e9a8d42c4baestevel * (the "License"). You may not use this file except in compliance
03831d35f7499c87d51205817c93e9a8d42c4baestevel * with the License.
03831d35f7499c87d51205817c93e9a8d42c4baestevel *
03831d35f7499c87d51205817c93e9a8d42c4baestevel * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
03831d35f7499c87d51205817c93e9a8d42c4baestevel * or http://www.opensolaris.org/os/licensing.
03831d35f7499c87d51205817c93e9a8d42c4baestevel * See the License for the specific language governing permissions
03831d35f7499c87d51205817c93e9a8d42c4baestevel * and limitations under the License.
03831d35f7499c87d51205817c93e9a8d42c4baestevel *
03831d35f7499c87d51205817c93e9a8d42c4baestevel * When distributing Covered Code, include this CDDL HEADER in each
03831d35f7499c87d51205817c93e9a8d42c4baestevel * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
03831d35f7499c87d51205817c93e9a8d42c4baestevel * If applicable, add the following below this CDDL HEADER, with the
03831d35f7499c87d51205817c93e9a8d42c4baestevel * fields enclosed by brackets "[]" replaced with your own identifying
03831d35f7499c87d51205817c93e9a8d42c4baestevel * information: Portions Copyright [yyyy] [name of copyright owner]
03831d35f7499c87d51205817c93e9a8d42c4baestevel *
03831d35f7499c87d51205817c93e9a8d42c4baestevel * CDDL HEADER END
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Copyright (c) 1999-2001 by Sun Microsystems, Inc.
03831d35f7499c87d51205817c93e9a8d42c4baestevel * All rights reserved.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel#pragma ident "%Z%%M% %I% %E% SMI"
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <stdio.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <stdlib.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <unistd.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <ctype.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <string.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <kvm.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <varargs.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <errno.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <time.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <dirent.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <fcntl.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <sys/param.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <sys/stat.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <sys/types.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <sys/utsname.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <sys/openpromio.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <kstat.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <libintl.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <syslog.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <sys/dkio.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <sys/sbd_ioctl.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <sys/sbdp_mem.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <sys/serengeti.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include <sys/mc.h>
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include "pdevinfo.h"
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include "display.h"
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include "pdevinfo_sun4u.h"
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include "display_sun4u.h"
03831d35f7499c87d51205817c93e9a8d42c4baestevel#include "libprtdiag.h"
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel#if !defined(TEXT_DOMAIN)
03831d35f7499c87d51205817c93e9a8d42c4baestevel#define TEXT_DOMAIN "SYS_TEST"
03831d35f7499c87d51205817c93e9a8d42c4baestevel#endif
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel#define KBYTE 1024
03831d35f7499c87d51205817c93e9a8d42c4baestevel#define MBYTE (KBYTE * KBYTE)
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel#define MEM_UK_SIZE_MASK 0x3FF
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Global variables.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic memory_bank_t *bank_head;
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic memory_bank_t *bank_tail;
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic memory_seg_t *seg_head;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Local functions.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic void add_bank_node(uint64_t mc_decode, int portid, char *bank_status);
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic void add_seg_node(void);
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic memory_seg_t *match_seg(uint64_t);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Used for US-I and US-II systems
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*ARGSUSED0*/
03831d35f7499c87d51205817c93e9a8d42c4baestevelvoid
03831d35f7499c87d51205817c93e9a8d42c4baesteveldisplay_memorysize(Sys_tree *tree, struct system_kstat_data *kstats,
03831d35f7499c87d51205817c93e9a8d42c4baestevel struct grp_info *grps, struct mem_total *memory_total)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel log_printf(dgettext(TEXT_DOMAIN, "Memory size: "), 0);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (sysconf(_SC_PAGESIZE) == -1 || sysconf(_SC_PHYS_PAGES) == -1)
03831d35f7499c87d51205817c93e9a8d42c4baestevel log_printf(dgettext(TEXT_DOMAIN, "unable to determine\n"), 0);
03831d35f7499c87d51205817c93e9a8d42c4baestevel else {
03831d35f7499c87d51205817c93e9a8d42c4baestevel uint64_t mem_size;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel mem_size =
03831d35f7499c87d51205817c93e9a8d42c4baestevel (uint64_t)sysconf(_SC_PAGESIZE) * \
03831d35f7499c87d51205817c93e9a8d42c4baestevel (uint64_t)sysconf(_SC_PHYS_PAGES);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (mem_size >= MBYTE)
03831d35f7499c87d51205817c93e9a8d42c4baestevel log_printf(dgettext(TEXT_DOMAIN, "%d Megabytes\n"),
03831d35f7499c87d51205817c93e9a8d42c4baestevel (int)((mem_size+MBYTE-1) / MBYTE), 0);
03831d35f7499c87d51205817c93e9a8d42c4baestevel else
03831d35f7499c87d51205817c93e9a8d42c4baestevel log_printf(dgettext(TEXT_DOMAIN, "%d Kilobytes\n"),
03831d35f7499c87d51205817c93e9a8d42c4baestevel (int)((mem_size+KBYTE-1) / KBYTE), 0);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*ARGSUSED0*/
03831d35f7499c87d51205817c93e9a8d42c4baestevelvoid
03831d35f7499c87d51205817c93e9a8d42c4baesteveldisplay_memoryconf(Sys_tree *tree, struct grp_info *grps)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * This function is intentionally blank
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * The following functions are for use by any US-III based systems.
03831d35f7499c87d51205817c93e9a8d42c4baestevel * All they need to do is to call get_us3_mem_regs()
03831d35f7499c87d51205817c93e9a8d42c4baestevel * and then display_us3_banks(). Each platform then needs to decide how
03831d35f7499c87d51205817c93e9a8d42c4baestevel * to format this data by over-riding the generic function
03831d35f7499c87d51205817c93e9a8d42c4baestevel * print_us3_memory_line().
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevelint
03831d35f7499c87d51205817c93e9a8d42c4baestevelget_us3_mem_regs(Board_node *bnode)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel Prom_node *pnode;
03831d35f7499c87d51205817c93e9a8d42c4baestevel int portid;
03831d35f7499c87d51205817c93e9a8d42c4baestevel uint64_t *ma_reg_arr;
03831d35f7499c87d51205817c93e9a8d42c4baestevel uint64_t madr[NUM_MBANKS_PER_MC];
03831d35f7499c87d51205817c93e9a8d42c4baestevel void *bank_status_array;
03831d35f7499c87d51205817c93e9a8d42c4baestevel char *bank_status;
03831d35f7499c87d51205817c93e9a8d42c4baestevel int i, status_offset;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel for (pnode = dev_find_node(bnode->nodes, "memory-controller");
03831d35f7499c87d51205817c93e9a8d42c4baestevel pnode != NULL;
03831d35f7499c87d51205817c93e9a8d42c4baestevel pnode = dev_next_node(pnode, "memory-controller")) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* Get portid of this mc from libdevinfo. */
03831d35f7499c87d51205817c93e9a8d42c4baestevel portid = (*(int *)get_prop_val(find_prop(pnode, "portid")));
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* read the logical_bank_ma_regs property for this mc node. */
03831d35f7499c87d51205817c93e9a8d42c4baestevel ma_reg_arr = (uint64_t *)get_prop_val(
03831d35f7499c87d51205817c93e9a8d42c4baestevel find_prop(pnode, MEM_CFG_PROP_NAME));
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * There are situations where a memory-controller node
03831d35f7499c87d51205817c93e9a8d42c4baestevel * will not have the logical_bank_ma_regs property and
03831d35f7499c87d51205817c93e9a8d42c4baestevel * we need to allow for these cases. They include:
03831d35f7499c87d51205817c93e9a8d42c4baestevel * - Excalibur/Littleneck systems that only
03831d35f7499c87d51205817c93e9a8d42c4baestevel * support memory on one of their CPUs.
03831d35f7499c87d51205817c93e9a8d42c4baestevel * - Systems that support DR where a cpu board
03831d35f7499c87d51205817c93e9a8d42c4baestevel * can be unconfigured but still connected.
03831d35f7499c87d51205817c93e9a8d42c4baestevel * It is up to the caller of this function to ensure
03831d35f7499c87d51205817c93e9a8d42c4baestevel * that the bank_head and seg_head pointers are not
03831d35f7499c87d51205817c93e9a8d42c4baestevel * NULL after processing all memory-controllers in the
03831d35f7499c87d51205817c93e9a8d42c4baestevel * system. This would indicate a situation where no
03831d35f7499c87d51205817c93e9a8d42c4baestevel * memory-controllers in the system have a logical_bank_ma_regs
03831d35f7499c87d51205817c93e9a8d42c4baestevel * property which should never happen.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (ma_reg_arr == NULL)
03831d35f7499c87d51205817c93e9a8d42c4baestevel continue;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * The first NUM_MBANKS_PER_MC of uint64_t's in the
03831d35f7499c87d51205817c93e9a8d42c4baestevel * logical_bank_ma_regs property are the madr values.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel for (i = 0; i < NUM_MBANKS_PER_MC; i++) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel madr[i] = *ma_reg_arr++;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Get the bank_status property for this mem controller from
03831d35f7499c87d51205817c93e9a8d42c4baestevel * OBP. This contains the bank-status for each logical bank.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel bank_status_array = (void *)get_prop_val(
03831d35f7499c87d51205817c93e9a8d42c4baestevel find_prop(pnode, "bank-status"));
03831d35f7499c87d51205817c93e9a8d42c4baestevel status_offset = 0;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * process each logical bank
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel for (i = 0; i < NUM_MBANKS_PER_MC; i++) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Get the bank-status string for this bank
03831d35f7499c87d51205817c93e9a8d42c4baestevel * from the bank_status_array we just retrieved
03831d35f7499c87d51205817c93e9a8d42c4baestevel * from OBP. If the prop was not found, we
03831d35f7499c87d51205817c93e9a8d42c4baestevel * malloc a bank_status and set it to "no_status".
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (bank_status_array) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel bank_status = ((char *)bank_status_array +
03831d35f7499c87d51205817c93e9a8d42c4baestevel status_offset);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* Move offset to next bank_status string */
03831d35f7499c87d51205817c93e9a8d42c4baestevel status_offset += (strlen(bank_status) + 1);
03831d35f7499c87d51205817c93e9a8d42c4baestevel } else {
03831d35f7499c87d51205817c93e9a8d42c4baestevel bank_status = malloc(strlen("no_status"));
03831d35f7499c87d51205817c93e9a8d42c4baestevel strcpy(bank_status, "no_status");
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * create a bank_node for this bank
03831d35f7499c87d51205817c93e9a8d42c4baestevel * and add it to the list.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel add_bank_node(madr[i], portid, bank_status);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * find the segment to which this bank
03831d35f7499c87d51205817c93e9a8d42c4baestevel * belongs. If it doesn't already exist
03831d35f7499c87d51205817c93e9a8d42c4baestevel * then create it. If it exists, add to it.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel add_seg_node();
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (0);
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic void
03831d35f7499c87d51205817c93e9a8d42c4baesteveladd_bank_node(uint64_t mc_decode, int portid, char *bank_status)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel static int id = 0;
03831d35f7499c87d51205817c93e9a8d42c4baestevel memory_bank_t *new, *bank;
03831d35f7499c87d51205817c93e9a8d42c4baestevel uint32_t ifactor = MC_INTLV(mc_decode);
03831d35f7499c87d51205817c93e9a8d42c4baestevel uint64_t seg_size;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel if ((new = malloc(sizeof (memory_bank_t))) == NULL) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel perror("malloc");
03831d35f7499c87d51205817c93e9a8d42c4baestevel exit(1);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel new->portid = portid;
03831d35f7499c87d51205817c93e9a8d42c4baestevel new->id = id++;
03831d35f7499c87d51205817c93e9a8d42c4baestevel new->valid = (mc_decode >> 63);
03831d35f7499c87d51205817c93e9a8d42c4baestevel new->uk = MC_UK(mc_decode);
03831d35f7499c87d51205817c93e9a8d42c4baestevel new->um = MC_UM(mc_decode);
03831d35f7499c87d51205817c93e9a8d42c4baestevel new->lk = MC_LK(mc_decode);
03831d35f7499c87d51205817c93e9a8d42c4baestevel new->lm = MC_LM(mc_decode);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel seg_size = ((((uint64_t)new->uk & MEM_UK_SIZE_MASK) + 1) << 26);
03831d35f7499c87d51205817c93e9a8d42c4baestevel new->bank_size = seg_size / ifactor;
03831d35f7499c87d51205817c93e9a8d42c4baestevel new->bank_status = bank_status;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel new->next = NULL;
03831d35f7499c87d51205817c93e9a8d42c4baestevel new->seg_next = NULL;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* Handle the first bank found */
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (bank_head == NULL) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel bank_head = new;
03831d35f7499c87d51205817c93e9a8d42c4baestevel bank_tail = new;
03831d35f7499c87d51205817c93e9a8d42c4baestevel return;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* find last bank in list */
03831d35f7499c87d51205817c93e9a8d42c4baestevel bank = bank_head;
03831d35f7499c87d51205817c93e9a8d42c4baestevel while (bank->next)
03831d35f7499c87d51205817c93e9a8d42c4baestevel bank = bank->next;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* insert this bank into the list */
03831d35f7499c87d51205817c93e9a8d42c4baestevel bank->next = new;
03831d35f7499c87d51205817c93e9a8d42c4baestevel bank_tail = new;
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevelvoid
03831d35f7499c87d51205817c93e9a8d42c4baesteveldisplay_us3_banks(void)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel uint64_t base, bank_size;
03831d35f7499c87d51205817c93e9a8d42c4baestevel uint32_t intlv;
03831d35f7499c87d51205817c93e9a8d42c4baestevel memory_bank_t *bank, *tmp_bank;
03831d35f7499c87d51205817c93e9a8d42c4baestevel memory_seg_t *seg;
03831d35f7499c87d51205817c93e9a8d42c4baestevel int mcid;
03831d35f7499c87d51205817c93e9a8d42c4baestevel uint64_t dimm_size;
03831d35f7499c87d51205817c93e9a8d42c4baestevel uint64_t total_bank_size = 0;
03831d35f7499c87d51205817c93e9a8d42c4baestevel uint64_t total_sys_mem;
03831d35f7499c87d51205817c93e9a8d42c4baestevel static uint64_t bank0_size, bank1_size, bank2_size, bank3_size;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel if ((bank_head == NULL) || (seg_head == NULL)) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel log_printf("\nCannot find any memory bank/segment info.\n");
03831d35f7499c87d51205817c93e9a8d42c4baestevel return;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel for (bank = bank_head; bank; bank = bank->next) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Interleave factor is determined from the
03831d35f7499c87d51205817c93e9a8d42c4baestevel * lk bits in the Mem Addr Decode register.
03831d35f7499c87d51205817c93e9a8d42c4baestevel *
03831d35f7499c87d51205817c93e9a8d42c4baestevel * The Base Address of the memory segment in which this
03831d35f7499c87d51205817c93e9a8d42c4baestevel * bank belongs is determined from the um abd uk bits
03831d35f7499c87d51205817c93e9a8d42c4baestevel * of the Mem Addr Decode register.
03831d35f7499c87d51205817c93e9a8d42c4baestevel *
03831d35f7499c87d51205817c93e9a8d42c4baestevel * See section 9.1.5 of Cheetah Programmer's reference
03831d35f7499c87d51205817c93e9a8d42c4baestevel * manual.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel intlv = ((bank->lk ^ 0xF) + 1);
03831d35f7499c87d51205817c93e9a8d42c4baestevel base = bank->um & ~(bank->uk);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel mcid = SG_PORTID_TO_SAFARI_ID(bank->portid);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* If bank is not valid, set size to zero incase it's garbage */
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (bank->valid)
03831d35f7499c87d51205817c93e9a8d42c4baestevel bank_size = ((bank->bank_size) / MBYTE);
03831d35f7499c87d51205817c93e9a8d42c4baestevel else
03831d35f7499c87d51205817c93e9a8d42c4baestevel bank_size = 0;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Keep track of all banks found so we can check later
03831d35f7499c87d51205817c93e9a8d42c4baestevel * that this value matches the total memory in the
03831d35f7499c87d51205817c93e9a8d42c4baestevel * system using the pagesize and number of pages.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel total_bank_size += bank_size;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* Find the matching segment for this bank. */
03831d35f7499c87d51205817c93e9a8d42c4baestevel seg = match_seg(base);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Find the Dimm size by adding banks 0 + 2 and divide by 4
03831d35f7499c87d51205817c93e9a8d42c4baestevel * and then adding banks 1 + 3 and divide by 4. We divide
03831d35f7499c87d51205817c93e9a8d42c4baestevel * by 2 if one of the logical banks size is zero.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel switch ((bank->id) % 4) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel case 0:
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* have bank0_size, need bank2_size */
03831d35f7499c87d51205817c93e9a8d42c4baestevel bank0_size = bank_size;
03831d35f7499c87d51205817c93e9a8d42c4baestevel bank2_size = 0;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel tmp_bank = bank->next;
03831d35f7499c87d51205817c93e9a8d42c4baestevel while (tmp_bank) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (tmp_bank->valid == 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel tmp_bank = tmp_bank->next;
03831d35f7499c87d51205817c93e9a8d42c4baestevel continue;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* Is next bank on the same mc ? */
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (mcid != SG_PORTID_TO_SAFARI_ID(
03831d35f7499c87d51205817c93e9a8d42c4baestevel tmp_bank->portid)) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel if ((tmp_bank->id) % 4 == 2) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel bank2_size =
03831d35f7499c87d51205817c93e9a8d42c4baestevel (tmp_bank->bank_size / MBYTE);
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel tmp_bank = tmp_bank->next;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (bank2_size)
03831d35f7499c87d51205817c93e9a8d42c4baestevel dimm_size = (bank0_size + bank2_size) / 4;
03831d35f7499c87d51205817c93e9a8d42c4baestevel else
03831d35f7499c87d51205817c93e9a8d42c4baestevel dimm_size = bank0_size / 2;
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel case 1:
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* have bank1_size, need bank3_size */
03831d35f7499c87d51205817c93e9a8d42c4baestevel bank1_size = bank_size;
03831d35f7499c87d51205817c93e9a8d42c4baestevel bank3_size = 0;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel tmp_bank = bank->next;
03831d35f7499c87d51205817c93e9a8d42c4baestevel while (tmp_bank) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (tmp_bank->valid == 0) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel tmp_bank = tmp_bank->next;
03831d35f7499c87d51205817c93e9a8d42c4baestevel continue;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* Is next bank on the same mc ? */
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (mcid != SG_PORTID_TO_SAFARI_ID(
03831d35f7499c87d51205817c93e9a8d42c4baestevel tmp_bank->portid)) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel if ((tmp_bank->id) % 4 == 3) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel bank3_size =
03831d35f7499c87d51205817c93e9a8d42c4baestevel (tmp_bank->bank_size / MBYTE);
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel tmp_bank = tmp_bank->next;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (bank3_size)
03831d35f7499c87d51205817c93e9a8d42c4baestevel dimm_size = (bank1_size + bank3_size) / 4;
03831d35f7499c87d51205817c93e9a8d42c4baestevel else
03831d35f7499c87d51205817c93e9a8d42c4baestevel dimm_size = bank1_size / 2;
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel case 2:
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* have bank0_size and bank2_size */
03831d35f7499c87d51205817c93e9a8d42c4baestevel bank2_size = bank_size;
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (bank0_size)
03831d35f7499c87d51205817c93e9a8d42c4baestevel dimm_size = (bank0_size + bank2_size) / 4;
03831d35f7499c87d51205817c93e9a8d42c4baestevel else
03831d35f7499c87d51205817c93e9a8d42c4baestevel dimm_size = bank2_size / 2;
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel case 3:
03831d35f7499c87d51205817c93e9a8d42c4baestevel /* have bank1_size and bank3_size */
03831d35f7499c87d51205817c93e9a8d42c4baestevel bank3_size = bank_size;
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (bank1_size)
03831d35f7499c87d51205817c93e9a8d42c4baestevel dimm_size = (bank1_size + bank3_size) / 4;
03831d35f7499c87d51205817c93e9a8d42c4baestevel else
03831d35f7499c87d51205817c93e9a8d42c4baestevel dimm_size = bank3_size / 4;
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (bank->valid == 0)
03831d35f7499c87d51205817c93e9a8d42c4baestevel continue;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Call platform specific code for formatting memory
03831d35f7499c87d51205817c93e9a8d42c4baestevel * information.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel print_us3_memory_line(bank->portid, bank->id, bank_size,
03831d35f7499c87d51205817c93e9a8d42c4baestevel bank->bank_status, dimm_size, intlv, seg->id);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel printf("\n");
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Sanity check to ensure that the total amount of system
03831d35f7499c87d51205817c93e9a8d42c4baestevel * memory matches the total number of memory banks that
03831d35f7499c87d51205817c93e9a8d42c4baestevel * we find here. Scream if there is a mis-match.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel total_sys_mem = (((uint64_t)sysconf(_SC_PAGESIZE) * \
03831d35f7499c87d51205817c93e9a8d42c4baestevel (uint64_t)sysconf(_SC_PHYS_PAGES)) / MBYTE);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (total_bank_size != total_sys_mem) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel log_printf(dgettext(TEXT_DOMAIN,
03831d35f7499c87d51205817c93e9a8d42c4baestevel "\nError: total bank size [%lldMB] does not match total "
03831d35f7499c87d51205817c93e9a8d42c4baestevel "system memory [%lldMB]\n"), total_bank_size,
03831d35f7499c87d51205817c93e9a8d42c4baestevel total_sys_mem, 0);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic void
03831d35f7499c87d51205817c93e9a8d42c4baesteveladd_seg_node(void)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel uint64_t base;
03831d35f7499c87d51205817c93e9a8d42c4baestevel memory_seg_t *new;
03831d35f7499c87d51205817c93e9a8d42c4baestevel static int id = 0;
03831d35f7499c87d51205817c93e9a8d42c4baestevel memory_bank_t *bank = bank_tail;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (bank->valid != 1)
03831d35f7499c87d51205817c93e9a8d42c4baestevel return;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel base = bank->um & ~(bank->uk);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel if ((new = match_seg(base)) == NULL) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * This bank is part of a new segment, so create
03831d35f7499c87d51205817c93e9a8d42c4baestevel * a struct for it and added to the list of segments
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel if ((new = malloc(sizeof (memory_seg_t))) == NULL) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel perror("malloc");
03831d35f7499c87d51205817c93e9a8d42c4baestevel exit(1);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel new->id = id++;
03831d35f7499c87d51205817c93e9a8d42c4baestevel new->base = base;
03831d35f7499c87d51205817c93e9a8d42c4baestevel new->size = (((uint64_t)bank->uk +1) << 26);
03831d35f7499c87d51205817c93e9a8d42c4baestevel new->intlv = ((bank->lk ^ 0xF) + 1);
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * add to the seg list
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel new->next = seg_head;
03831d35f7499c87d51205817c93e9a8d42c4baestevel seg_head = new;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel new->nbanks++;
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * add bank into segs bank list. Note we add at the head
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel bank->seg_next = new->banks;
03831d35f7499c87d51205817c93e9a8d42c4baestevel new->banks = bank;
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevelstatic memory_seg_t *
03831d35f7499c87d51205817c93e9a8d42c4baestevelmatch_seg(uint64_t base)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel memory_seg_t *cur_seg;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel for (cur_seg = seg_head; cur_seg; cur_seg = cur_seg->next) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (cur_seg-> base == base)
03831d35f7499c87d51205817c93e9a8d42c4baestevel break;
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (cur_seg);
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*ARGSUSED0*/
03831d35f7499c87d51205817c93e9a8d42c4baestevelvoid
03831d35f7499c87d51205817c93e9a8d42c4baestevelprint_us3_memory_line(int portid, int bank_id, uint64_t bank_size,
03831d35f7499c87d51205817c93e9a8d42c4baestevel char *bank_status, uint64_t dimm_size, uint32_t intlv, int seg_id)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel log_printf(dgettext(TEXT_DOMAIN,
03831d35f7499c87d51205817c93e9a8d42c4baestevel "\n No print_us3_memory_line() function specified for"
03831d35f7499c87d51205817c93e9a8d42c4baestevel " this platform\n"), 0);
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevelint
03831d35f7499c87d51205817c93e9a8d42c4baesteveldisplay_us3_failed_banks(int system_failed)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel memory_bank_t *bank;
03831d35f7499c87d51205817c93e9a8d42c4baestevel int found_failed_bank = 0;
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel if ((bank_head == NULL) || (seg_head == NULL)) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel log_printf("\nCannot find any memory bank/segment info.\n");
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (1);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel for (bank = bank_head; bank; bank = bank->next) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * check to see if the bank is invalid and also
03831d35f7499c87d51205817c93e9a8d42c4baestevel * check if the bank_status is unpopulated. Unpopulated
03831d35f7499c87d51205817c93e9a8d42c4baestevel * means the bank is empty.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel if ((bank->valid == 0) &&
03831d35f7499c87d51205817c93e9a8d42c4baestevel (strcmp(bank->bank_status, "unpopulated"))) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (!system_failed && !found_failed_bank) {
03831d35f7499c87d51205817c93e9a8d42c4baestevel found_failed_bank = TRUE;
03831d35f7499c87d51205817c93e9a8d42c4baestevel log_printf("\n", 0);
03831d35f7499c87d51205817c93e9a8d42c4baestevel log_printf(dgettext(TEXT_DOMAIN,
03831d35f7499c87d51205817c93e9a8d42c4baestevel "Failed Field Replaceable Units (FRU) in "
03831d35f7499c87d51205817c93e9a8d42c4baestevel "System:\n"), 0);
03831d35f7499c87d51205817c93e9a8d42c4baestevel log_printf("=========================="
03831d35f7499c87d51205817c93e9a8d42c4baestevel "====================\n", 0);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel /*
03831d35f7499c87d51205817c93e9a8d42c4baestevel * Call platform specific code for formatting memory
03831d35f7499c87d51205817c93e9a8d42c4baestevel * information.
03831d35f7499c87d51205817c93e9a8d42c4baestevel */
03831d35f7499c87d51205817c93e9a8d42c4baestevel print_us3_failed_memory_line(bank->portid, bank->id,
03831d35f7499c87d51205817c93e9a8d42c4baestevel bank->bank_status);
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel }
03831d35f7499c87d51205817c93e9a8d42c4baestevel if (found_failed_bank)
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (1);
03831d35f7499c87d51205817c93e9a8d42c4baestevel else
03831d35f7499c87d51205817c93e9a8d42c4baestevel return (0);
03831d35f7499c87d51205817c93e9a8d42c4baestevel}
03831d35f7499c87d51205817c93e9a8d42c4baestevel
03831d35f7499c87d51205817c93e9a8d42c4baestevel/*ARGSUSED0*/
03831d35f7499c87d51205817c93e9a8d42c4baestevelvoid
03831d35f7499c87d51205817c93e9a8d42c4baestevelprint_us3_failed_memory_line(int portid, int bank_id, char *bank_status)
03831d35f7499c87d51205817c93e9a8d42c4baestevel{
03831d35f7499c87d51205817c93e9a8d42c4baestevel log_printf(dgettext(TEXT_DOMAIN,
03831d35f7499c87d51205817c93e9a8d42c4baestevel "\n No print_us3_failed_memory_line() function specified for"
03831d35f7499c87d51205817c93e9a8d42c4baestevel " this platform\n"), 0);
03831d35f7499c87d51205817c93e9a8d42c4baestevel}