Initial commit of OpenSPARC T2 architecture model.
[OpenSPARC-T2-SAM] / hypervisor / src / greatlakes / common / src / svc_init.c
CommitLineData
920dae64
AT
1/*
2* ========== Copyright Header Begin ==========================================
3*
4* Hypervisor Software File: svc_init.c
5*
6* Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved.
7*
8* - Do no alter or remove copyright notices
9*
10* - Redistribution and use of this software in source and binary forms, with
11* or without modification, are permitted provided that the following
12* conditions are met:
13*
14* - Redistribution of source code must retain the above copyright notice,
15* this list of conditions and the following disclaimer.
16*
17* - Redistribution in binary form must reproduce the above copyright notice,
18* this list of conditions and the following disclaimer in the
19* documentation and/or other materials provided with the distribution.
20*
21* Neither the name of Sun Microsystems, Inc. or the names of contributors
22* may be used to endorse or promote products derived from this software
23* without specific prior written permission.
24*
25* This software is provided "AS IS," without a warranty of any kind.
26* ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
27* INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
28* PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
29* MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
30* ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
31* DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN
32* OR ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR
33* FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
34* DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
35* ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
36* SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
37*
38* You acknowledge that this software is not designed, licensed or
39* intended for use in the design, construction, operation or maintenance of
40* any nuclear facility.
41*
42* ========== Copyright Header End ============================================
43*/
44/*
45 * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
46 * Use is subject to license terms.
47 */
48
49#pragma ident "@(#)svc_init.c 1.4 07/08/14 SMI"
50
51#ifdef CONFIG_SVC
52#include <stdarg.h>
53#include <sys/htypes.h>
54#include <vdev_ops.h>
55#include <vdev_intr.h>
56#include <ncs.h>
57#include <cyclic.h>
58#include <vcpu.h>
59#include <strand.h>
60#include <guest.h>
61#include <md.h>
62#include <debug.h>
63
64#include <svc.h>
65#include <svc_vbsc.h>
66
67
68static uint64_t
69c_svc_register(uint64_t cookie, uint64_t xid, uint64_t sid, uint64_t recv,
70uint64_t send)
71{
72 hv_svc_data_t *r_svcp = config.svc;
73
74 if (r_svcp != NULL) {
75 svc_ctrl_t *r_svcsp = r_svcp->svcs;
76 int i;
77
78 /* for the requested services */
79 for (i = r_svcp->num_svcs; i > 0; i--, r_svcsp++) {
80
81 if ((r_svcsp->xid == xid) && (r_svcsp->sid == sid)) {
82 /*
83 * attach the callbacks to this service
84 * Ensure intrs are disabled on the channel
85 * and set the CALLBACK flag in both the svc
86 * config and state variables
87 */
88 r_svcsp->config |= SVC_CFG_CALLBACK;
89 r_svcsp->state |= SVC_CFG_CALLBACK;
90 r_svcsp->callback.rx = (uint64_t)recv;
91 r_svcsp->callback.tx = (uint64_t)send;
92 r_svcsp->callback.cookie = cookie;
93 return ((uint64_t)r_svcsp);
94 }
95 }
96 }
97 return (0);
98}
99
100/*
101 * c_setup_err_svc - setup error service channel
102 */
103static void
104c_setup_err_svc()
105{
106 uint64_t rv;
107 strand_t *sp = c_mystrand();
108
109 rv = c_svc_register((uint64_t)sp, XPID_HV, SID_ERROR,
110 (uint64_t)error_svc_rx, (uint64_t)error_svc_tx);
111
112 if (rv == 0) {
113 DBGINIT(c_printf("WARNING:c_setup_err_svc register fail\r\n"));
114 }
115 config.error_svch = rv;
116}
117
118#ifdef CONFIG_VBSC_SVC
119
120/*
121 * c_setup_vbsc_svc - setup vbsc service channel
122 */
123static void
124c_setup_vbsc_svc()
125{
126 uint64_t rv;
127 strand_t *sp = c_mystrand();
128
129 /* Put error_svc handle into the debug structure */
130 config.vbsc_dbgerror.error_svch = config.error_svch;
131
132 rv = c_svc_register((uint64_t)sp, XPID_HV, SID_VBSC_CTL,
133 (uint64_t)vbsc_rx, (uint64_t)vbsc_tx);
134
135 if (rv) {
136 config.vbsc_svch = rv;
137 } else {
138 c_hvabort(-1);
139 }
140}
141
142/*
143 * c_vbsc_send_polled - send a vbsc command and poll for response
144 */
145static void
146c_vbsc_send_polled(uint64_t cmd1, uint64_t cmd2, uint64_t cmd3)
147{
148 uint16_t fpga_cmd_offset;
149 volatile uint8_t *fpga_statusp;
150 uint16_t *fpga_basep;
151 uint64_t *fpga_cmdp;
152 uint8_t fpga_cmd_status;
153
154c_vbsc_send_polled_resend:
155 fpga_basep = (uint16_t *)(FPGA_Q3OUT_BASE);
156 fpga_statusp = (uint8_t *)fpga_basep;
157
158 fpga_cmdp = (uint64_t *)(FPGA_BASE + FPGA_SRAM_BASE);
159 fpga_cmd_offset = *((uint16_t *)((uint64_t)fpga_basep + FPGA_Q_BASE));
160
161 /* sram buffer words */
162 fpga_cmdp = (uint64_t *)((uint64_t)fpga_cmdp +
163 (uint64_t)fpga_cmd_offset);
164
165 /* insert the command bytes */
166 *(fpga_cmdp + 2) = cmd3;
167 *(fpga_cmdp + 1) = cmd2;
168 *(fpga_cmdp + 0) = cmd1;
169
170 /* initiate the command */
171 *((uint8_t *)((uint64_t)fpga_statusp + FPGA_Q_SEND)) = 1;
172
173 /*
174 * Wait for a non-zero status. If we get an ACK then we're done.
175 * Otherwise re-send the packet. Failure is not an option, even
176 * to hv_abort we need to send a message to vbsc. So keep trying.
177 */
178 fpga_statusp = (uint8_t *)((uint64_t)fpga_statusp + FPGA_Q_STATUS);
179 do {
180 fpga_cmd_status = *fpga_statusp;
181 fpga_cmd_status &= (QINTR_ACK | QINTR_NACK | QINTR_BUSY
182 | QINTR_ABORT);
183 } while (fpga_cmd_status == 0);
184
185 if (fpga_cmd_status & QINTR_ACK) {
186 *fpga_statusp = fpga_cmd_status; /* ack the command */
187 } else {
188 goto c_vbsc_send_polled_resend;
189 }
190}
191
192/*
193 * c_vbsc_guest_start - send a message indicating guest is starting
194 */
195void
196c_vbsc_guest_start(uint64_t gid)
197{
198 guest_t *guestp = (guest_t *)config.guests;
199
200 guestp = &(guestp[gid]);
201
202 c_vbsc_send_polled(VBSC_GUEST_ON, guestp->guestid + XPID_GUESTBASE, 0);
203}
204#endif /* CONFIG_VBSC_SVC */
205
206
207/*
208 * c_svc_init - initialize the service channels
209 */
210void
211c_svc_init()
212{
213 hv_svc_data_t *r_svcp = config.svc;
214 svc_ctrl_t *r_svcsp = r_svcp->svcs;
215 int i;
216
217 /* for each of the configured services */
218 for (i = r_svcp->num_svcs; i > 0; i--, r_svcsp++) {
219
220 /* if there is an RCV or XMT configured */
221 if (r_svcsp->config & (SVC_CFG_RE | SVC_CFG_TE)) {
222
223 if (r_svcsp->xid >= XPID_GUESTBASE) {
224 guest_t *guestp = (guest_t *)config.guests;
225
226 /* determine the guest for this service */
227 guestp = &(guestp[r_svcsp->xid-XPID_GUESTBASE]);
228
229 /* register the interrupt; save the cookie */
230 r_svcsp->intr_cookie = c_vdev_intr_register(
231 guestp, r_svcsp->ino, r_svcsp,
232 svc_intr_getstate, (intr_setstate_f)NULL);
233 }
234 }
235 }
236
237#ifdef CONFIG_FPGA
238 /*
239 * Mailbox hardware initialization
240 */
241 {
242 volatile uint8_t *fpgap;
243 uint8_t tmp;
244
245 /* Clear previously-pending state */
246 fpgap = (uint8_t *)(FPGA_Q_BASE + FPGA_Q_STATUS);
247 tmp = *fpgap;
248 *fpgap = tmp;
249
250 /* Enable interrupts */
251 fpgap = (uint8_t *)(FPGA_INTR_BASE + FPGA_MBOX_INTR_ENABLE);
252 *fpgap = (IRQ_QUEUE_IN|IRQ_QUEUE_OUT|IRQ_LDC_OUT);
253 }
254#endif /* CONFIG_FPGA */
255
256 /* Must be before setup_vbsc_svc */
257 c_setup_err_svc();
258
259#ifdef CONFIG_VBSC_SVC
260 DBGINIT(c_printf("c_svc_init: setup vbsc_svc\n"));
261 c_setup_vbsc_svc();
262#endif /* CONFIG_VBSC_SVC */
263}
264#endif /* CONFIG_SVC */