11965746bSMichael Ellerman /* 21965746bSMichael Ellerman * pSeries firmware setup code. 31965746bSMichael Ellerman * 41965746bSMichael Ellerman * Portions from arch/powerpc/platforms/pseries/setup.c: 51965746bSMichael Ellerman * Copyright (C) 1995 Linus Torvalds 61965746bSMichael Ellerman * Adapted from 'alpha' version by Gary Thomas 71965746bSMichael Ellerman * Modified by Cort Dougan (cort@cs.nmt.edu) 81965746bSMichael Ellerman * Modified by PPC64 Team, IBM Corp 91965746bSMichael Ellerman * 101965746bSMichael Ellerman * Portions from arch/powerpc/kernel/firmware.c 111965746bSMichael Ellerman * Copyright (C) 2001 Ben. Herrenschmidt (benh@kernel.crashing.org) 121965746bSMichael Ellerman * Modifications for ppc64: 131965746bSMichael Ellerman * Copyright (C) 2003 Dave Engebretsen <engebret@us.ibm.com> 141965746bSMichael Ellerman * Copyright (C) 2005 Stephen Rothwell, IBM Corporation 151965746bSMichael Ellerman * 161965746bSMichael Ellerman * Copyright 2006 IBM Corporation. 171965746bSMichael Ellerman * 181965746bSMichael Ellerman * This program is free software; you can redistribute it and/or 191965746bSMichael Ellerman * modify it under the terms of the GNU General Public License 201965746bSMichael Ellerman * as published by the Free Software Foundation; either version 211965746bSMichael Ellerman * 2 of the License, or (at your option) any later version. 221965746bSMichael Ellerman */ 231965746bSMichael Ellerman 241965746bSMichael Ellerman 251965746bSMichael Ellerman #include <asm/firmware.h> 261965746bSMichael Ellerman #include <asm/prom.h> 27aa39be09Swill schmidt #include <asm/udbg.h> 281965746bSMichael Ellerman 293ff1999bSMichael Ellerman #include "pseries.h" 301965746bSMichael Ellerman 311965746bSMichael Ellerman typedef struct { 321965746bSMichael Ellerman unsigned long val; 331965746bSMichael Ellerman char * name; 341965746bSMichael Ellerman } firmware_feature_t; 351965746bSMichael Ellerman 362f1d4ea7SMichael Neuling /* 372f1d4ea7SMichael Neuling * The names in this table match names in rtas/ibm,hypertas-functions. If the 382f1d4ea7SMichael Neuling * entry ends in a '*', only upto the '*' is matched. Otherwise the entire 392f1d4ea7SMichael Neuling * string must match. 402f1d4ea7SMichael Neuling */ 411965746bSMichael Ellerman static __initdata firmware_feature_t 421965746bSMichael Ellerman firmware_features_table[FIRMWARE_MAX_FEATURES] = { 431965746bSMichael Ellerman {FW_FEATURE_PFT, "hcall-pft"}, 441965746bSMichael Ellerman {FW_FEATURE_TCE, "hcall-tce"}, 451965746bSMichael Ellerman {FW_FEATURE_SPRG0, "hcall-sprg0"}, 461965746bSMichael Ellerman {FW_FEATURE_DABR, "hcall-dabr"}, 471965746bSMichael Ellerman {FW_FEATURE_COPY, "hcall-copy"}, 481965746bSMichael Ellerman {FW_FEATURE_ASR, "hcall-asr"}, 491965746bSMichael Ellerman {FW_FEATURE_DEBUG, "hcall-debug"}, 501965746bSMichael Ellerman {FW_FEATURE_PERF, "hcall-perf"}, 511965746bSMichael Ellerman {FW_FEATURE_DUMP, "hcall-dump"}, 521965746bSMichael Ellerman {FW_FEATURE_INTERRUPT, "hcall-interrupt"}, 531965746bSMichael Ellerman {FW_FEATURE_MIGRATE, "hcall-migrate"}, 541965746bSMichael Ellerman {FW_FEATURE_PERFMON, "hcall-perfmon"}, 551965746bSMichael Ellerman {FW_FEATURE_CRQ, "hcall-crq"}, 561965746bSMichael Ellerman {FW_FEATURE_VIO, "hcall-vio"}, 571965746bSMichael Ellerman {FW_FEATURE_RDMA, "hcall-rdma"}, 581965746bSMichael Ellerman {FW_FEATURE_LLAN, "hcall-lLAN"}, 59b6dcde5cSAnton Blanchard {FW_FEATURE_BULK_REMOVE, "hcall-bulk"}, 601965746bSMichael Ellerman {FW_FEATURE_XDABR, "hcall-xdabr"}, 611965746bSMichael Ellerman {FW_FEATURE_MULTITCE, "hcall-multi-tce"}, 621965746bSMichael Ellerman {FW_FEATURE_SPLPAR, "hcall-splpar"}, 6336f567b4SJesse Larrew {FW_FEATURE_VPHN, "hcall-vphn"}, 64d8f48eccSIan Munsie {FW_FEATURE_SET_MODE, "hcall-set-mode"}, 65*0388c79cSMichael Neuling {FW_FEATURE_BEST_ENERGY, "hcall-best-energy-1*"}, 661965746bSMichael Ellerman }; 671965746bSMichael Ellerman 681965746bSMichael Ellerman /* Build up the firmware features bitmask using the contents of 691965746bSMichael Ellerman * device-tree/ibm,hypertas-functions. Ultimately this functionality may 701965746bSMichael Ellerman * be moved into prom.c prom_init(). 711965746bSMichael Ellerman */ 72ca8ffc97SMichael Neuling void __init fw_feature_init(const char *hypertas, unsigned long len) 731965746bSMichael Ellerman { 74ca8ffc97SMichael Neuling const char *s; 75ca8ffc97SMichael Neuling int i; 761965746bSMichael Ellerman 77f7ebf352SMichael Ellerman pr_debug(" -> fw_feature_init()\n"); 781965746bSMichael Ellerman 791965746bSMichael Ellerman for (s = hypertas; s < hypertas + len; s += strlen(s) + 1) { 801965746bSMichael Ellerman for (i = 0; i < FIRMWARE_MAX_FEATURES; i++) { 812f1d4ea7SMichael Neuling const char *name = firmware_features_table[i].name; 822f1d4ea7SMichael Neuling size_t size; 831965746bSMichael Ellerman /* check value against table of strings */ 842f1d4ea7SMichael Neuling if (!name) 852f1d4ea7SMichael Neuling continue; 862f1d4ea7SMichael Neuling /* 872f1d4ea7SMichael Neuling * If there is a '*' at the end of name, only check 882f1d4ea7SMichael Neuling * upto there 892f1d4ea7SMichael Neuling */ 902f1d4ea7SMichael Neuling size = strlen(name); 912f1d4ea7SMichael Neuling if (size && name[size - 1] == '*') { 922f1d4ea7SMichael Neuling if (strncmp(name, s, size - 1)) 932f1d4ea7SMichael Neuling continue; 942f1d4ea7SMichael Neuling } else if (strcmp(name, s)) 951965746bSMichael Ellerman continue; 961965746bSMichael Ellerman 971965746bSMichael Ellerman /* we have a match */ 98d0160bf0SMichael Ellerman powerpc_firmware_features |= 991965746bSMichael Ellerman firmware_features_table[i].val; 1001965746bSMichael Ellerman break; 1011965746bSMichael Ellerman } 1021965746bSMichael Ellerman } 1031965746bSMichael Ellerman 104f7ebf352SMichael Ellerman pr_debug(" <- fw_feature_init()\n"); 1051965746bSMichael Ellerman } 106