diff options
-rw-r--r-- | arch/powerpc/platforms/pseries/setup.c | 71 | ||||
-rw-r--r-- | include/asm-powerpc/firmware.h | 3 |
2 files changed, 73 insertions, 1 deletions
diff --git a/arch/powerpc/platforms/pseries/setup.c b/arch/powerpc/platforms/pseries/setup.c index 90beb444e1dd..063a0d2fba30 100644 --- a/arch/powerpc/platforms/pseries/setup.c +++ b/arch/powerpc/platforms/pseries/setup.c | |||
@@ -314,6 +314,76 @@ static int pseries_set_xdabr(unsigned long dabr) | |||
314 | H_DABRX_KERNEL | H_DABRX_USER); | 314 | H_DABRX_KERNEL | H_DABRX_USER); |
315 | } | 315 | } |
316 | 316 | ||
317 | #define CMO_CHARACTERISTICS_TOKEN 44 | ||
318 | #define CMO_MAXLENGTH 1026 | ||
319 | |||
320 | /** | ||
321 | * fw_cmo_feature_init - FW_FEATURE_CMO is not stored in ibm,hypertas-functions, | ||
322 | * handle that here. (Stolen from parse_system_parameter_string) | ||
323 | */ | ||
324 | void pSeries_cmo_feature_init(void) | ||
325 | { | ||
326 | char *ptr, *key, *value, *end; | ||
327 | int call_status; | ||
328 | int PrPSP = -1; | ||
329 | int SecPSP = -1; | ||
330 | |||
331 | pr_debug(" -> fw_cmo_feature_init()\n"); | ||
332 | spin_lock(&rtas_data_buf_lock); | ||
333 | memset(rtas_data_buf, 0, RTAS_DATA_BUF_SIZE); | ||
334 | call_status = rtas_call(rtas_token("ibm,get-system-parameter"), 3, 1, | ||
335 | NULL, | ||
336 | CMO_CHARACTERISTICS_TOKEN, | ||
337 | __pa(rtas_data_buf), | ||
338 | RTAS_DATA_BUF_SIZE); | ||
339 | |||
340 | if (call_status != 0) { | ||
341 | spin_unlock(&rtas_data_buf_lock); | ||
342 | pr_debug("CMO not available\n"); | ||
343 | pr_debug(" <- fw_cmo_feature_init()\n"); | ||
344 | return; | ||
345 | } | ||
346 | |||
347 | end = rtas_data_buf + CMO_MAXLENGTH - 2; | ||
348 | ptr = rtas_data_buf + 2; /* step over strlen value */ | ||
349 | key = value = ptr; | ||
350 | |||
351 | while (*ptr && (ptr <= end)) { | ||
352 | /* Separate the key and value by replacing '=' with '\0' and | ||
353 | * point the value at the string after the '=' | ||
354 | */ | ||
355 | if (ptr[0] == '=') { | ||
356 | ptr[0] = '\0'; | ||
357 | value = ptr + 1; | ||
358 | } else if (ptr[0] == '\0' || ptr[0] == ',') { | ||
359 | /* Terminate the string containing the key/value pair */ | ||
360 | ptr[0] = '\0'; | ||
361 | |||
362 | if (key == value) { | ||
363 | pr_debug("Malformed key/value pair\n"); | ||
364 | /* Never found a '=', end processing */ | ||
365 | break; | ||
366 | } | ||
367 | |||
368 | if (0 == strcmp(key, "PrPSP")) | ||
369 | PrPSP = simple_strtol(value, NULL, 10); | ||
370 | else if (0 == strcmp(key, "SecPSP")) | ||
371 | SecPSP = simple_strtol(value, NULL, 10); | ||
372 | value = key = ptr + 1; | ||
373 | } | ||
374 | ptr++; | ||
375 | } | ||
376 | |||
377 | if (PrPSP != -1 || SecPSP != -1) { | ||
378 | pr_info("CMO enabled\n"); | ||
379 | pr_debug("CMO enabled, PrPSP=%d, SecPSP=%d\n", PrPSP, SecPSP); | ||
380 | powerpc_firmware_features |= FW_FEATURE_CMO; | ||
381 | } else | ||
382 | pr_debug("CMO not enabled, PrPSP=%d, SecPSP=%d\n", PrPSP, SecPSP); | ||
383 | spin_unlock(&rtas_data_buf_lock); | ||
384 | pr_debug(" <- fw_cmo_feature_init()\n"); | ||
385 | } | ||
386 | |||
317 | /* | 387 | /* |
318 | * Early initialization. Relocation is on but do not reference unbolted pages | 388 | * Early initialization. Relocation is on but do not reference unbolted pages |
319 | */ | 389 | */ |
@@ -329,6 +399,7 @@ static void __init pSeries_init_early(void) | |||
329 | else if (firmware_has_feature(FW_FEATURE_XDABR)) | 399 | else if (firmware_has_feature(FW_FEATURE_XDABR)) |
330 | ppc_md.set_dabr = pseries_set_xdabr; | 400 | ppc_md.set_dabr = pseries_set_xdabr; |
331 | 401 | ||
402 | pSeries_cmo_feature_init(); | ||
332 | iommu_init_early_pSeries(); | 403 | iommu_init_early_pSeries(); |
333 | 404 | ||
334 | pr_debug(" <- pSeries_init_early()\n"); | 405 | pr_debug(" <- pSeries_init_early()\n"); |
diff --git a/include/asm-powerpc/firmware.h b/include/asm-powerpc/firmware.h index ef328995ba9d..3a179827528d 100644 --- a/include/asm-powerpc/firmware.h +++ b/include/asm-powerpc/firmware.h | |||
@@ -46,6 +46,7 @@ | |||
46 | #define FW_FEATURE_PS3_LV1 ASM_CONST(0x0000000000800000) | 46 | #define FW_FEATURE_PS3_LV1 ASM_CONST(0x0000000000800000) |
47 | #define FW_FEATURE_BEAT ASM_CONST(0x0000000001000000) | 47 | #define FW_FEATURE_BEAT ASM_CONST(0x0000000001000000) |
48 | #define FW_FEATURE_BULK_REMOVE ASM_CONST(0x0000000002000000) | 48 | #define FW_FEATURE_BULK_REMOVE ASM_CONST(0x0000000002000000) |
49 | #define FW_FEATURE_CMO ASM_CONST(0x0000000004000000) | ||
49 | 50 | ||
50 | #ifndef __ASSEMBLY__ | 51 | #ifndef __ASSEMBLY__ |
51 | 52 | ||
@@ -58,7 +59,7 @@ enum { | |||
58 | FW_FEATURE_MIGRATE | FW_FEATURE_PERFMON | FW_FEATURE_CRQ | | 59 | FW_FEATURE_MIGRATE | FW_FEATURE_PERFMON | FW_FEATURE_CRQ | |
59 | FW_FEATURE_VIO | FW_FEATURE_RDMA | FW_FEATURE_LLAN | | 60 | FW_FEATURE_VIO | FW_FEATURE_RDMA | FW_FEATURE_LLAN | |
60 | FW_FEATURE_BULK | FW_FEATURE_XDABR | FW_FEATURE_MULTITCE | | 61 | FW_FEATURE_BULK | FW_FEATURE_XDABR | FW_FEATURE_MULTITCE | |
61 | FW_FEATURE_SPLPAR | FW_FEATURE_LPAR, | 62 | FW_FEATURE_SPLPAR | FW_FEATURE_LPAR | FW_FEATURE_CMO, |
62 | FW_FEATURE_PSERIES_ALWAYS = 0, | 63 | FW_FEATURE_PSERIES_ALWAYS = 0, |
63 | FW_FEATURE_ISERIES_POSSIBLE = FW_FEATURE_ISERIES | FW_FEATURE_LPAR, | 64 | FW_FEATURE_ISERIES_POSSIBLE = FW_FEATURE_ISERIES | FW_FEATURE_LPAR, |
64 | FW_FEATURE_ISERIES_ALWAYS = FW_FEATURE_ISERIES | FW_FEATURE_LPAR, | 65 | FW_FEATURE_ISERIES_ALWAYS = FW_FEATURE_ISERIES | FW_FEATURE_LPAR, |