• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/*
2 * PowerNV OPAL takeover assembly code, for use by prom_init.c
3 *
4 * Copyright 2011 IBM Corp.
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version
9 * 2 of the License, or (at your option) any later version.
10 */
11
12#include <asm/ppc_asm.h>
13#include <asm/hvcall.h>
14#include <asm/asm-offsets.h>
15#include <asm/opal.h>
16
17#define STK_PARAM(i)	(48 + ((i)-3)*8)
18
19#define H_HAL_TAKEOVER			0x5124
20#define H_HAL_TAKEOVER_QUERY_MAGIC	-1
21
22	.text
23_GLOBAL(opal_query_takeover)
24	mfcr	r0
25	stw	r0,8(r1)
26	std	r3,STK_PARAM(r3)(r1)
27	std	r4,STK_PARAM(r4)(r1)
28	li	r3,H_HAL_TAKEOVER
29	li	r4,H_HAL_TAKEOVER_QUERY_MAGIC
30	HVSC
31	ld	r10,STK_PARAM(r3)(r1)
32	std	r4,0(r10)
33	ld	r10,STK_PARAM(r4)(r1)
34	std	r5,0(r10)
35	lwz	r0,8(r1)
36	mtcrf	0xff,r0
37	blr
38
39_GLOBAL(opal_do_takeover)
40	mfcr	r0
41	stw	r0,8(r1)
42	mflr	r0
43	std	r0,16(r1)
44	bl	__opal_do_takeover
45	ld	r0,16(r1)
46	mtlr	r0
47	lwz	r0,8(r1)
48	mtcrf	0xff,r0
49	blr
50
51__opal_do_takeover:
52	ld	r4,0(r3)
53	ld	r5,0x8(r3)
54	ld	r6,0x10(r3)
55	ld	r7,0x18(r3)
56	ld	r8,0x20(r3)
57	ld	r9,0x28(r3)
58	ld	r10,0x30(r3)
59	ld	r11,0x38(r3)
60	li	r3,H_HAL_TAKEOVER
61	HVSC
62	blr
63
64	.globl opal_secondary_entry
65opal_secondary_entry:
66	mr	r31,r3
67	mfmsr	r11
68	li	r12,(MSR_SF | MSR_ISF)@highest
69	sldi	r12,r12,48
70	or	r11,r11,r12
71	mtmsrd	r11
72	isync
73	mfspr	r4,SPRN_PIR
74	std	r4,0(r3)
751:	HMT_LOW
76	ld	r4,8(r3)
77	cmpli	cr0,r4,0
78	beq	1b
79	HMT_MEDIUM
801:	addi	r3,r31,16
81	bl	__opal_do_takeover
82	b	1b
83
84_GLOBAL(opal_enter_rtas)
85	mflr	r0
86	std	r0,16(r1)
87        stdu	r1,-PROM_FRAME_SIZE(r1)	/* Save SP and create stack space */
88
89	/* Because PROM is running in 32b mode, it clobbers the high order half
90	 * of all registers that it saves.  We therefore save those registers
91	 * PROM might touch to the stack.  (r0, r3-r13 are caller saved)
92	*/
93	SAVE_GPR(2, r1)
94	SAVE_GPR(13, r1)
95	SAVE_8GPRS(14, r1)
96	SAVE_10GPRS(22, r1)
97	mfcr	r10
98	mfmsr	r11
99	std	r10,_CCR(r1)
100	std	r11,_MSR(r1)
101
102	/* Get the PROM entrypoint */
103	mtlr	r5
104
105	/* Switch MSR to 32 bits mode
106	 */
107        li      r12,1
108        rldicr  r12,r12,MSR_SF_LG,(63-MSR_SF_LG)
109        andc    r11,r11,r12
110        li      r12,1
111        rldicr  r12,r12,MSR_ISF_LG,(63-MSR_ISF_LG)
112        andc    r11,r11,r12
113        mtmsrd  r11
114        isync
115
116	/* Enter RTAS here... */
117	blrl
118
119	/* Just make sure that r1 top 32 bits didn't get
120	 * corrupt by OF
121	 */
122	rldicl	r1,r1,0,32
123
124	/* Restore the MSR (back to 64 bits) */
125	ld	r0,_MSR(r1)
126	MTMSRD(r0)
127        isync
128
129	/* Restore other registers */
130	REST_GPR(2, r1)
131	REST_GPR(13, r1)
132	REST_8GPRS(14, r1)
133	REST_10GPRS(22, r1)
134	ld	r4,_CCR(r1)
135	mtcr	r4
136
137        addi	r1,r1,PROM_FRAME_SIZE
138	ld	r0,16(r1)
139	mtlr    r0
140	blr
141