linux/arch/powerpc/platforms/pseries/firmware.c
<<
>>
Prefs
   1/*
   2 *  pSeries firmware setup code.
   3 *
   4 *  Portions from arch/powerpc/platforms/pseries/setup.c:
   5 *   Copyright (C) 1995  Linus Torvalds
   6 *   Adapted from 'alpha' version by Gary Thomas
   7 *   Modified by Cort Dougan (cort@cs.nmt.edu)
   8 *   Modified by PPC64 Team, IBM Corp
   9 *
  10 *  Portions from arch/powerpc/kernel/firmware.c
  11 *   Copyright (C) 2001 Ben. Herrenschmidt (benh@kernel.crashing.org)
  12 *   Modifications for ppc64:
  13 *    Copyright (C) 2003 Dave Engebretsen <engebret@us.ibm.com>
  14 *    Copyright (C) 2005 Stephen Rothwell, IBM Corporation
  15 *
  16 *  Copyright 2006 IBM Corporation.
  17 *
  18 * This program is free software; you can redistribute it and/or
  19 * modify it under the terms of the GNU General Public License
  20 * as published by the Free Software Foundation; either version
  21 * 2 of the License, or (at your option) any later version.
  22 */
  23
  24
  25#include <asm/firmware.h>
  26#include <asm/prom.h>
  27#include <asm/udbg.h>
  28
  29#include "pseries.h"
  30
  31struct hypertas_fw_feature {
  32    unsigned long val;
  33    char * name;
  34};
  35
  36/*
  37 * The names in this table match names in rtas/ibm,hypertas-functions.  If the
  38 * entry ends in a '*', only upto the '*' is matched.  Otherwise the entire
  39 * string must match.
  40 */
  41static __initdata struct hypertas_fw_feature
  42hypertas_fw_features_table[] = {
  43        {FW_FEATURE_PFT,                "hcall-pft"},
  44        {FW_FEATURE_TCE,                "hcall-tce"},
  45        {FW_FEATURE_SPRG0,              "hcall-sprg0"},
  46        {FW_FEATURE_DABR,               "hcall-dabr"},
  47        {FW_FEATURE_COPY,               "hcall-copy"},
  48        {FW_FEATURE_ASR,                "hcall-asr"},
  49        {FW_FEATURE_DEBUG,              "hcall-debug"},
  50        {FW_FEATURE_PERF,               "hcall-perf"},
  51        {FW_FEATURE_DUMP,               "hcall-dump"},
  52        {FW_FEATURE_INTERRUPT,          "hcall-interrupt"},
  53        {FW_FEATURE_MIGRATE,            "hcall-migrate"},
  54        {FW_FEATURE_PERFMON,            "hcall-perfmon"},
  55        {FW_FEATURE_CRQ,                "hcall-crq"},
  56        {FW_FEATURE_VIO,                "hcall-vio"},
  57        {FW_FEATURE_RDMA,               "hcall-rdma"},
  58        {FW_FEATURE_LLAN,               "hcall-lLAN"},
  59        {FW_FEATURE_BULK_REMOVE,        "hcall-bulk"},
  60        {FW_FEATURE_XDABR,              "hcall-xdabr"},
  61        {FW_FEATURE_MULTITCE,           "hcall-multi-tce"},
  62        {FW_FEATURE_SPLPAR,             "hcall-splpar"},
  63        {FW_FEATURE_VPHN,               "hcall-vphn"},
  64        {FW_FEATURE_SET_MODE,           "hcall-set-mode"},
  65        {FW_FEATURE_BEST_ENERGY,        "hcall-best-energy-1*"},
  66};
  67
  68/* Build up the firmware features bitmask using the contents of
  69 * device-tree/ibm,hypertas-functions.  Ultimately this functionality may
  70 * be moved into prom.c prom_init().
  71 */
  72void __init fw_hypertas_feature_init(const char *hypertas, unsigned long len)
  73{
  74        const char *s;
  75        int i;
  76
  77        pr_debug(" -> fw_hypertas_feature_init()\n");
  78
  79        for (s = hypertas; s < hypertas + len; s += strlen(s) + 1) {
  80                for (i = 0; i < ARRAY_SIZE(hypertas_fw_features_table); i++) {
  81                        const char *name = hypertas_fw_features_table[i].name;
  82                        size_t size;
  83
  84                        /*
  85                         * If there is a '*' at the end of name, only check
  86                         * upto there
  87                         */
  88                        size = strlen(name);
  89                        if (size && name[size - 1] == '*') {
  90                                if (strncmp(name, s, size - 1))
  91                                        continue;
  92                        } else if (strcmp(name, s))
  93                                continue;
  94
  95                        /* we have a match */
  96                        powerpc_firmware_features |=
  97                                hypertas_fw_features_table[i].val;
  98                        break;
  99                }
 100        }
 101
 102        pr_debug(" <- fw_hypertas_feature_init()\n");
 103}
 104
 105struct vec5_fw_feature {
 106        unsigned long   val;
 107        unsigned int    feature;
 108};
 109
 110static __initdata struct vec5_fw_feature
 111vec5_fw_features_table[] = {
 112        {FW_FEATURE_TYPE1_AFFINITY,     OV5_TYPE1_AFFINITY},
 113        {FW_FEATURE_PRRN,               OV5_PRRN},
 114};
 115
 116void __init fw_vec5_feature_init(const char *vec5, unsigned long len)
 117{
 118        unsigned int index, feat;
 119        int i;
 120
 121        pr_debug(" -> fw_vec5_feature_init()\n");
 122
 123        for (i = 0; i < ARRAY_SIZE(vec5_fw_features_table); i++) {
 124                index = OV5_INDX(vec5_fw_features_table[i].feature);
 125                feat = OV5_FEAT(vec5_fw_features_table[i].feature);
 126
 127                if (vec5[index] & feat)
 128                        powerpc_firmware_features |=
 129                                vec5_fw_features_table[i].val;
 130        }
 131
 132        pr_debug(" <- fw_vec5_feature_init()\n");
 133}
 134