Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

MIPS: fw: arc: use call_o32 to call ARC prom from 64bit kernel

When using a 64bit kernel with generic spaces setup stack is
also placed in XKPYHS, which the 32bit PROM can't handle.
By using call_o32 for ARC_CALLs a stack placed in KSEG0 is used
when calling PROM.

Signed-off-by: Thomas Bogendoerfer <tbogendoerfer@suse.de>
Signed-off-by: Paul Burton <paul.burton@mips.com>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: James Hogan <jhogan@kernel.org>
Cc: linux-mips@vger.kernel.org
Cc: linux-kernel@vger.kernel.org

authored by

Thomas Bogendoerfer and committed by
Paul Burton
ce6c0a59 d11646b5

+35 -73
+5
arch/mips/fw/arc/init.c
··· 21 21 int prom_argc; 22 22 LONG *_prom_argv, *_prom_envp; 23 23 24 + #if defined(CONFIG_64BIT) && defined(CONFIG_FW_ARC32) 25 + /* stack for calling 32bit ARC prom */ 26 + u64 o32_stk[4096]; 27 + #endif 28 + 24 29 void __init prom_init(void) 25 30 { 26 31 PSYSTEM_PARAMETER_BLOCK pb = PROMBLOCK;
+30 -73
arch/mips/include/asm/sgiarcs.h
··· 12 12 #ifndef _ASM_SGIARCS_H 13 13 #define _ASM_SGIARCS_H 14 14 15 + #include <linux/kernel.h> 16 + 15 17 #include <asm/types.h> 16 18 #include <asm/fw/arc/types.h> 17 19 ··· 370 368 371 369 #if defined(CONFIG_64BIT) && defined(CONFIG_FW_ARC32) 372 370 373 - #define __arc_clobbers \ 374 - "$2", "$3" /* ... */, "$8", "$9", "$10", "$11", \ 375 - "$12", "$13", "$14", "$15", "$16", "$24", "$25", "$31" 371 + extern long call_o32(long vec, void *stack, ...); 372 + 373 + extern u64 o32_stk[4096]; 374 + #define O32_STK (&o32_stk[ARRAY_SIZE(o32_stk)]) 376 375 377 376 #define ARC_CALL0(dest) \ 378 377 ({ long __res; \ 379 378 long __vec = (long) romvec->dest; \ 380 - __asm__ __volatile__( \ 381 - "dsubu\t$29, 32\n\t" \ 382 - "jalr\t%1\n\t" \ 383 - "daddu\t$29, 32\n\t" \ 384 - "move\t%0, $2" \ 385 - : "=r" (__res), "=r" (__vec) \ 386 - : "1" (__vec) \ 387 - : __arc_clobbers, "$4", "$5", "$6", "$7"); \ 388 - (unsigned long) __res; \ 379 + __res = call_o32(__vec, O32_STK); \ 380 + __res; \ 389 381 }) 390 382 391 383 #define ARC_CALL1(dest, a1) \ 392 384 ({ long __res; \ 393 - register signed int __a1 __asm__("$4") = (int) (long) (a1); \ 385 + int __a1 = (int) (long) (a1); \ 394 386 long __vec = (long) romvec->dest; \ 395 - __asm__ __volatile__( \ 396 - "dsubu\t$29, 32\n\t" \ 397 - "jalr\t%1\n\t" \ 398 - "daddu\t$29, 32\n\t" \ 399 - "move\t%0, $2" \ 400 - : "=r" (__res), "=r" (__vec) \ 401 - : "1" (__vec), "r" (__a1) \ 402 - : __arc_clobbers, "$5", "$6", "$7"); \ 403 - (unsigned long) __res; \ 387 + __res = call_o32(__vec, O32_STK, __a1); \ 388 + __res; \ 404 389 }) 405 390 406 391 #define ARC_CALL2(dest, a1, a2) \ 407 392 ({ long __res; \ 408 - register signed int __a1 __asm__("$4") = (int) (long) (a1); \ 409 - register signed int __a2 __asm__("$5") = (int) (long) (a2); \ 393 + int __a1 = (int) (long) (a1); \ 394 + int __a2 = (int) (long) (a2); \ 410 395 long __vec = (long) romvec->dest; \ 411 - __asm__ __volatile__( \ 412 - "dsubu\t$29, 32\n\t" \ 413 - "jalr\t%1\n\t" \ 414 - "daddu\t$29, 32\n\t" \ 415 - "move\t%0, $2" \ 416 - : "=r" (__res), "=r" (__vec) \ 417 - : "1" (__vec), "r" (__a1), "r" (__a2) \ 418 - : __arc_clobbers, "$6", "$7"); \ 396 + __res = call_o32(__vec, O32_STK, __a1, __a2); \ 419 397 __res; \ 420 398 }) 421 399 422 400 #define ARC_CALL3(dest, a1, a2, a3) \ 423 401 ({ long __res; \ 424 - register signed int __a1 __asm__("$4") = (int) (long) (a1); \ 425 - register signed int __a2 __asm__("$5") = (int) (long) (a2); \ 426 - register signed int __a3 __asm__("$6") = (int) (long) (a3); \ 402 + int __a1 = (int) (long) (a1); \ 403 + int __a2 = (int) (long) (a2); \ 404 + int __a3 = (int) (long) (a3); \ 427 405 long __vec = (long) romvec->dest; \ 428 - __asm__ __volatile__( \ 429 - "dsubu\t$29, 32\n\t" \ 430 - "jalr\t%1\n\t" \ 431 - "daddu\t$29, 32\n\t" \ 432 - "move\t%0, $2" \ 433 - : "=r" (__res), "=r" (__vec) \ 434 - : "1" (__vec), "r" (__a1), "r" (__a2), "r" (__a3) \ 435 - : __arc_clobbers, "$7"); \ 406 + __res = call_o32(__vec, O32_STK, __a1, __a2, __a3); \ 436 407 __res; \ 437 408 }) 438 409 439 410 #define ARC_CALL4(dest, a1, a2, a3, a4) \ 440 411 ({ long __res; \ 441 - register signed int __a1 __asm__("$4") = (int) (long) (a1); \ 442 - register signed int __a2 __asm__("$5") = (int) (long) (a2); \ 443 - register signed int __a3 __asm__("$6") = (int) (long) (a3); \ 444 - register signed int __a4 __asm__("$7") = (int) (long) (a4); \ 412 + int __a1 = (int) (long) (a1); \ 413 + int __a2 = (int) (long) (a2); \ 414 + int __a3 = (int) (long) (a3); \ 415 + int __a4 = (int) (long) (a4); \ 445 416 long __vec = (long) romvec->dest; \ 446 - __asm__ __volatile__( \ 447 - "dsubu\t$29, 32\n\t" \ 448 - "jalr\t%1\n\t" \ 449 - "daddu\t$29, 32\n\t" \ 450 - "move\t%0, $2" \ 451 - : "=r" (__res), "=r" (__vec) \ 452 - : "1" (__vec), "r" (__a1), "r" (__a2), "r" (__a3), \ 453 - "r" (__a4) \ 454 - : __arc_clobbers); \ 417 + __res = call_o32(__vec, O32_STK, __a1, __a2, __a3, __a4); \ 455 418 __res; \ 456 419 }) 457 420 458 - #define ARC_CALL5(dest, a1, a2, a3, a4, a5) \ 421 + #define ARC_CALL5(dest, a1, a2, a3, a4, a5) \ 459 422 ({ long __res; \ 460 - register signed int __a1 __asm__("$4") = (int) (long) (a1); \ 461 - register signed int __a2 __asm__("$5") = (int) (long) (a2); \ 462 - register signed int __a3 __asm__("$6") = (int) (long) (a3); \ 463 - register signed int __a4 __asm__("$7") = (int) (long) (a4); \ 464 - register signed int __a5 = (int) (long) (a5); \ 423 + int __a1 = (int) (long) (a1); \ 424 + int __a2 = (int) (long) (a2); \ 425 + int __a3 = (int) (long) (a3); \ 426 + int __a4 = (int) (long) (a4); \ 427 + int __a5 = (int) (long) (a5); \ 465 428 long __vec = (long) romvec->dest; \ 466 - __asm__ __volatile__( \ 467 - "dsubu\t$29, 32\n\t" \ 468 - "sw\t%7, 16($29)\n\t" \ 469 - "jalr\t%1\n\t" \ 470 - "daddu\t$29, 32\n\t" \ 471 - "move\t%0, $2" \ 472 - : "=r" (__res), "=r" (__vec) \ 473 - : "1" (__vec), \ 474 - "r" (__a1), "r" (__a2), "r" (__a3), "r" (__a4), \ 475 - "r" (__a5) \ 476 - : __arc_clobbers); \ 429 + __res = call_o32(__vec, O32_STK, __a1, __a2, __a3, __a4, __a5); \ 477 430 __res; \ 478 431 }) 479 432