xref: /titanic_51/usr/src/lib/efcode/jupiter/jupiter.c (revision 531232457f24de82ba95346b3de302b990fe50f4)
125cf1a30Sjl139090 /*
225cf1a30Sjl139090  * CDDL HEADER START
325cf1a30Sjl139090  *
425cf1a30Sjl139090  * The contents of this file are subject to the terms of the
525cf1a30Sjl139090  * Common Development and Distribution License (the "License").
625cf1a30Sjl139090  * You may not use this file except in compliance with the License.
725cf1a30Sjl139090  *
825cf1a30Sjl139090  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
925cf1a30Sjl139090  * or http://www.opensolaris.org/os/licensing.
1025cf1a30Sjl139090  * See the License for the specific language governing permissions
1125cf1a30Sjl139090  * and limitations under the License.
1225cf1a30Sjl139090  *
1325cf1a30Sjl139090  * When distributing Covered Code, include this CDDL HEADER in each
1425cf1a30Sjl139090  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
1525cf1a30Sjl139090  * If applicable, add the following below this CDDL HEADER, with the
1625cf1a30Sjl139090  * fields enclosed by brackets "[]" replaced with your own identifying
1725cf1a30Sjl139090  * information: Portions Copyright [yyyy] [name of copyright owner]
1825cf1a30Sjl139090  *
1925cf1a30Sjl139090  * CDDL HEADER END
2025cf1a30Sjl139090  */
2125cf1a30Sjl139090 /*
2225cf1a30Sjl139090  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
2325cf1a30Sjl139090  * Use is subject to license terms.
2425cf1a30Sjl139090  */
2525cf1a30Sjl139090 
2625cf1a30Sjl139090 #pragma ident	"%Z%%M%	%I%	%E% SMI"
2725cf1a30Sjl139090 
2825cf1a30Sjl139090 #include <stdio.h>
2925cf1a30Sjl139090 #include <stdlib.h>
3025cf1a30Sjl139090 #include <strings.h>
3125cf1a30Sjl139090 
3225cf1a30Sjl139090 #include <fcode/private.h>
3325cf1a30Sjl139090 #include <fcode/log.h>
3425cf1a30Sjl139090 
3525cf1a30Sjl139090 #include <fcdriver/fcdriver.h>
3625cf1a30Sjl139090 
3725cf1a30Sjl139090 #include <sys/opl_cfg.h>
3825cf1a30Sjl139090 
3925cf1a30Sjl139090 /* VA for HardWare Descriptor */
4025cf1a30Sjl139090 static	hwd_cmu_chan_t	hwd_va_cmu;
4125cf1a30Sjl139090 static	hwd_leaf_t	hwd_va_pci;
4225cf1a30Sjl139090 
4325cf1a30Sjl139090 /* Macro to get I/O portid */
4425cf1a30Sjl139090 #define	DO_GET_IO_PORTID(env, lo, hi, portid)	\
4525cf1a30Sjl139090 	PUSH(DS, lo);				\
4625cf1a30Sjl139090 	PUSH(DS, hi);				\
4725cf1a30Sjl139090 	do_get_io_portid(env);			\
4825cf1a30Sjl139090 	portid = (uint32_t)POP(DS)
4925cf1a30Sjl139090 
5025cf1a30Sjl139090 fstack_t
5125cf1a30Sjl139090 mem_map_in(fcode_env_t *env, fstack_t hi, fstack_t lo, fstack_t len)
5225cf1a30Sjl139090 {
5325cf1a30Sjl139090 	private_data_t	*pdp = DEVICE_PRIVATE(env);
5425cf1a30Sjl139090 	fc_cell_t	virt;
5525cf1a30Sjl139090 	fstack_t	mcookie = NULL;
5625cf1a30Sjl139090 	char		*service = "map-in";
5725cf1a30Sjl139090 	int		error;
5825cf1a30Sjl139090 	int		offset = 0;
5925cf1a30Sjl139090 
6025cf1a30Sjl139090 	/*
6125cf1a30Sjl139090 	 * The calculation of the offset, lo and len are left here
6225cf1a30Sjl139090 	 * due to historical precedence.
6325cf1a30Sjl139090 	 */
6425cf1a30Sjl139090 
6525cf1a30Sjl139090 	offset = lo & PAGEOFFSET;
6625cf1a30Sjl139090 	lo &= PAGEMASK;
6725cf1a30Sjl139090 	len = (len + offset + PAGEOFFSET) & PAGEMASK;
6825cf1a30Sjl139090 
6925cf1a30Sjl139090 	error = fc_run_priv(pdp->common, service, 3, 1, fc_size2cell(len),
7025cf1a30Sjl139090 	    fc_uint32_t2cell(hi), fc_uint32_t2cell(lo), &virt);
7125cf1a30Sjl139090 
7225cf1a30Sjl139090 	if (error)
7325cf1a30Sjl139090 		throw_from_fclib(env, 1, "jupiter:%s: failed\n", service);
7425cf1a30Sjl139090 
7525cf1a30Sjl139090 	mcookie = mapping_to_mcookie(virt, len, NULL, NULL);
7625cf1a30Sjl139090 
7725cf1a30Sjl139090 	if (mcookie == NULL)
7825cf1a30Sjl139090 		throw_from_fclib(env, 1,
7925cf1a30Sjl139090 		    "jupiter:%s: mapping_to_mcookie failed\n", service);
8025cf1a30Sjl139090 
8125cf1a30Sjl139090 	mcookie += offset;
8225cf1a30Sjl139090 
8325cf1a30Sjl139090 	debug_msg(DEBUG_REG_ACCESS, "jupiter:%s: %llx -> %x\n", service,
8425cf1a30Sjl139090 	    (long long)virt, (uint32_t)mcookie);
8525cf1a30Sjl139090 
8625cf1a30Sjl139090 	return (mcookie);
8725cf1a30Sjl139090 }
8825cf1a30Sjl139090 
8925cf1a30Sjl139090 static void
9025cf1a30Sjl139090 mem_map_out(fcode_env_t *env, fstack_t mcookie, fstack_t len)
9125cf1a30Sjl139090 {
9225cf1a30Sjl139090 	private_data_t	*pdp = DEVICE_PRIVATE(env);
9325cf1a30Sjl139090 	fc_cell_t	virt;
9425cf1a30Sjl139090 	char		*service = "map-out";
9525cf1a30Sjl139090 	int		error;
9625cf1a30Sjl139090 	int		offset;
9725cf1a30Sjl139090 
9825cf1a30Sjl139090 	/*
9925cf1a30Sjl139090 	 * The calculation of the offset, lo and len are left here
10025cf1a30Sjl139090 	 * due to historical precedence.
10125cf1a30Sjl139090 	 */
10225cf1a30Sjl139090 
10325cf1a30Sjl139090 	offset = mcookie & PAGEOFFSET;
10425cf1a30Sjl139090 	mcookie &= PAGEMASK;
10525cf1a30Sjl139090 	len = (len + offset + PAGEOFFSET) & PAGEMASK;
10625cf1a30Sjl139090 
10725cf1a30Sjl139090 	if (!is_mcookie(mcookie)) {
10825cf1a30Sjl139090 		log_message(MSG_ERROR, "jupiter:%s: %x not an mcookie!\n",
10925cf1a30Sjl139090 		    service, (int)mcookie);
11025cf1a30Sjl139090 		virt = mcookie;
11125cf1a30Sjl139090 	} else {
11225cf1a30Sjl139090 		virt = mcookie_to_addr(mcookie);
11325cf1a30Sjl139090 		debug_msg(DEBUG_REG_ACCESS, "jupiter:%s: %x -> %llx\n",
11425cf1a30Sjl139090 		    service, (int)mcookie, (long long)virt);
11525cf1a30Sjl139090 		delete_mapping(mcookie);
11625cf1a30Sjl139090 	}
11725cf1a30Sjl139090 
11825cf1a30Sjl139090 	error = fc_run_priv(pdp->common, service, 2, 0,
11925cf1a30Sjl139090 	    fc_size2cell(len), virt);
12025cf1a30Sjl139090 	if (error)
12125cf1a30Sjl139090 		log_message(MSG_ERROR, "jupiter:%s: failed\n", service);
12225cf1a30Sjl139090 }
12325cf1a30Sjl139090 
12425cf1a30Sjl139090 static void
12525cf1a30Sjl139090 do_map_in(fcode_env_t *env)
12625cf1a30Sjl139090 {
12725cf1a30Sjl139090 	fstack_t	phi, plo, len, addr;
12825cf1a30Sjl139090 
12925cf1a30Sjl139090 	CHECK_DEPTH(env, 3, "jupiter:map-in");
13025cf1a30Sjl139090 	len = POP(DS);
13125cf1a30Sjl139090 	phi = POP(DS);
13225cf1a30Sjl139090 	plo = POP(DS);
13325cf1a30Sjl139090 	addr = mem_map_in(env, phi, plo, len);
13425cf1a30Sjl139090 	PUSH(DS, addr);
13525cf1a30Sjl139090 }
13625cf1a30Sjl139090 
13725cf1a30Sjl139090 static void
13825cf1a30Sjl139090 do_map_out(fcode_env_t *env)
13925cf1a30Sjl139090 {
14025cf1a30Sjl139090 	fstack_t	addr, len;
14125cf1a30Sjl139090 
14225cf1a30Sjl139090 	CHECK_DEPTH(env, 2, "jupiter:map-out");
14325cf1a30Sjl139090 	len = POP(DS);
14425cf1a30Sjl139090 	addr = POP(DS);
14525cf1a30Sjl139090 	mem_map_out(env, addr, len);
14625cf1a30Sjl139090 }
14725cf1a30Sjl139090 
14825cf1a30Sjl139090 static void
14925cf1a30Sjl139090 do_get_io_portid(fcode_env_t *env)
15025cf1a30Sjl139090 {
15125cf1a30Sjl139090 	fstack_t	phi, plo;
15225cf1a30Sjl139090 	unsigned int	portid, lsb, ch, leaf;
15325cf1a30Sjl139090 
15425cf1a30Sjl139090 	CHECK_DEPTH(env, 2, "jupiter:get-portid");
15525cf1a30Sjl139090 
15625cf1a30Sjl139090 	phi = POP(DS);
15725cf1a30Sjl139090 	plo = POP(DS);
15825cf1a30Sjl139090 
15925cf1a30Sjl139090 	lsb  = OPL_ADDR_TO_LSB(phi);
16025cf1a30Sjl139090 	ch   = OPL_ADDR_TO_CHANNEL(phi);
16125cf1a30Sjl139090 	leaf = OPL_ADDR_TO_LEAF(phi, plo);
16225cf1a30Sjl139090 
16325cf1a30Sjl139090 	portid = OPL_IO_PORTID(lsb, ch, leaf);
16425cf1a30Sjl139090 
16525cf1a30Sjl139090 	debug_msg(DEBUG_REG_ACCESS, "jupiter:get-portid ( %x %x ) -> %x\n",
16625cf1a30Sjl139090 	    (int)phi, (int)plo, (int)portid);
16725cf1a30Sjl139090 	PUSH(DS, portid);
16825cf1a30Sjl139090 }
16925cf1a30Sjl139090 
17025cf1a30Sjl139090 static void
17125cf1a30Sjl139090 do_encode_unit(fcode_env_t *env)
17225cf1a30Sjl139090 {
17325cf1a30Sjl139090 	char		enc_buf[64];
17425cf1a30Sjl139090 	fstack_t	hi, lo;
17525cf1a30Sjl139090 	uint32_t	id;
17625cf1a30Sjl139090 	long long	off;
17725cf1a30Sjl139090 
17825cf1a30Sjl139090 	CHECK_DEPTH(env, 2, "jupiter:encode-unit");
17925cf1a30Sjl139090 
18025cf1a30Sjl139090 	hi = POP(DS);
18125cf1a30Sjl139090 	lo = POP(DS);
18225cf1a30Sjl139090 	off = (long long)(((hi & 0x1F) << 32) | lo);
18325cf1a30Sjl139090 
18425cf1a30Sjl139090 	/* Convert physical address to portid */
18525cf1a30Sjl139090 	DO_GET_IO_PORTID(env, lo, hi, id);
18625cf1a30Sjl139090 
18725cf1a30Sjl139090 	if (off) {
18825cf1a30Sjl139090 		(void) sprintf(enc_buf, "%x,%llx", id, off);
18925cf1a30Sjl139090 	} else {
19025cf1a30Sjl139090 		(void) sprintf(enc_buf, "%x", id);
19125cf1a30Sjl139090 	}
19225cf1a30Sjl139090 
19325cf1a30Sjl139090 	debug_msg(DEBUG_REG_ACCESS, "jupiter:encode_unit ( %x %x ) -> '%s'\n",
19425cf1a30Sjl139090 	    (uint32_t)hi, (uint32_t)lo, enc_buf);
19525cf1a30Sjl139090 
19625cf1a30Sjl139090 	push_a_string(env, STRDUP(enc_buf));
19725cf1a30Sjl139090 }
19825cf1a30Sjl139090 
19925cf1a30Sjl139090 static void
20025cf1a30Sjl139090 do_decode_unit(fcode_env_t *env)
20125cf1a30Sjl139090 {
20225cf1a30Sjl139090 	uint32_t	hi;
20325cf1a30Sjl139090 	long long	lo;
20425cf1a30Sjl139090 	unsigned int	portid, lsb, ch;
20525cf1a30Sjl139090 	char		*buf;
20625cf1a30Sjl139090 
20725cf1a30Sjl139090 	CHECK_DEPTH(env, 2, "jupiter:decode-unit");
20825cf1a30Sjl139090 
20925cf1a30Sjl139090 	buf = pop_a_string(env, NULL);
21025cf1a30Sjl139090 	if (sscanf(buf, "%x,%llx", &portid, &lo) != 2) {
21125cf1a30Sjl139090 		if (sscanf(buf, "%x", &portid) != 1) {
21225cf1a30Sjl139090 			throw_from_fclib(env, 1, "jupiter:decode_unit:%s",
21325cf1a30Sjl139090 			    buf);
21425cf1a30Sjl139090 		}
21525cf1a30Sjl139090 		lo = 0;
21625cf1a30Sjl139090 	}
21725cf1a30Sjl139090 
21825cf1a30Sjl139090 	lsb = OPL_IO_PORTID_TO_LSB(portid);
21925cf1a30Sjl139090 	ch  = OPL_PORTID_TO_CHANNEL(portid);
22025cf1a30Sjl139090 	hi  = OPL_ADDR_HI(lsb, ch);
22125cf1a30Sjl139090 
22225cf1a30Sjl139090 	debug_msg(DEBUG_REG_ACCESS,
22325cf1a30Sjl139090 	    "jupiter:decode_unit ( '%s' ) -> %x %llx\n", buf, hi, lo);
22425cf1a30Sjl139090 
22525cf1a30Sjl139090 	PUSH(DS, (fstack_t)lo);
22625cf1a30Sjl139090 	PUSH(DS, (fstack_t)hi);
22725cf1a30Sjl139090 }
22825cf1a30Sjl139090 
22925cf1a30Sjl139090 static void
23025cf1a30Sjl139090 do_device_id(fcode_env_t *env)
23125cf1a30Sjl139090 {
23225cf1a30Sjl139090 	common_data_t	*cdp = COMMON_PRIVATE(env);
23325cf1a30Sjl139090 	char		*buf = NULL;
23425cf1a30Sjl139090 	uint32_t	hi;
23525cf1a30Sjl139090 	long long	lo;
23625cf1a30Sjl139090 	uint32_t	portid, ch, leaf;
23725cf1a30Sjl139090 
23825cf1a30Sjl139090 	CHECK_DEPTH(env, 2, "jupiter:device-id");
23925cf1a30Sjl139090 
24025cf1a30Sjl139090 	hi = POP(DS);
24125cf1a30Sjl139090 	lo = POP(DS);
24225cf1a30Sjl139090 
24325cf1a30Sjl139090 	portid = 0;
24425cf1a30Sjl139090 	if (cdp && cdp->fc.unit_address &&
24525cf1a30Sjl139090 	    ((buf = strdup(cdp->fc.unit_address)) != NULL)) {
24625cf1a30Sjl139090 		/*
24725cf1a30Sjl139090 		 * Get portid number from unit_address
24825cf1a30Sjl139090 		 * Because of no leaf information in physical address
24925cf1a30Sjl139090 		 */
25025cf1a30Sjl139090 		if (sscanf(buf, "%x,%llx", &portid, &lo) != 2) {
25125cf1a30Sjl139090 			if (sscanf(buf, "%x", &portid) != 1) {
25225cf1a30Sjl139090 				throw_from_fclib(env, 1,
25325cf1a30Sjl139090 				    "jupiter:do_device_id: invalid %s", buf);
25425cf1a30Sjl139090 			}
25525cf1a30Sjl139090 		}
25625cf1a30Sjl139090 	} else {
25725cf1a30Sjl139090 		/*
25825cf1a30Sjl139090 		 * Non existence unit_address case.
25925cf1a30Sjl139090 		 * Convert physical address to portid.
26025cf1a30Sjl139090 		 */
26125cf1a30Sjl139090 		throw_from_fclib(env, 1,
26225cf1a30Sjl139090 		    "jupiter:do_device_id: failed unit address");
26325cf1a30Sjl139090 		DO_GET_IO_PORTID(env, lo, hi, portid);
26425cf1a30Sjl139090 	}
26525cf1a30Sjl139090 
26625cf1a30Sjl139090 	debug_msg(DEBUG_FIND_FCODE,
26725cf1a30Sjl139090 	    "jupiter:do_device_id:(%x,%llx)\n", portid, lo);
26825cf1a30Sjl139090 
26925cf1a30Sjl139090 	/* Pick up each ID from portid */
27025cf1a30Sjl139090 	ch   = OPL_PORTID_TO_CHANNEL(portid);
27125cf1a30Sjl139090 	leaf = OPL_PORTID_TO_LEAF(portid);
27225cf1a30Sjl139090 
27325cf1a30Sjl139090 	if (ch == OPL_CMU_CHANNEL) {
27425cf1a30Sjl139090 		/*
27525cf1a30Sjl139090 		 * CMU-CH: PCICMU CHANNEL
27625cf1a30Sjl139090 		 */
27725cf1a30Sjl139090 		debug_msg(DEBUG_FIND_FCODE,
27825cf1a30Sjl139090 		    "jupiter:do_device_id:cmu-ch\n");
27925cf1a30Sjl139090 		push_a_string(env, "cmu-ch");
28025cf1a30Sjl139090 	} else if (OPL_OBERON_CHANNEL(ch) && OPL_VALID_LEAF(leaf)) {
28125cf1a30Sjl139090 		/*
28225cf1a30Sjl139090 		 * PCI-CH: Oberon Leaves CHANNEL
28325cf1a30Sjl139090 		 */
28425cf1a30Sjl139090 		if (leaf) {
28525cf1a30Sjl139090 			/* Leaf B */
28625cf1a30Sjl139090 			debug_msg(DEBUG_FIND_FCODE,
28725cf1a30Sjl139090 			    "jupiter:do_device_id:jup-oberon-pci1\n");
28825cf1a30Sjl139090 			push_a_string(env, "jup-oberon-pci1");
28925cf1a30Sjl139090 		} else {
29025cf1a30Sjl139090 			/* Leaf A */
29125cf1a30Sjl139090 			debug_msg(DEBUG_FIND_FCODE,
29225cf1a30Sjl139090 			    "jupiter:do_device_id:jup-oberon-pci0\n");
29325cf1a30Sjl139090 			push_a_string(env, "jup-oberon-pci0");
29425cf1a30Sjl139090 		}
29525cf1a30Sjl139090 	} else {
29625cf1a30Sjl139090 		/* Not matched to any channels */
29725cf1a30Sjl139090 		throw_from_fclib(env, 1,
29825cf1a30Sjl139090 		    "jupiter:do_device_id: invalid portid %x", portid);
29925cf1a30Sjl139090 		push_a_string(env, "");
30025cf1a30Sjl139090 	}
30125cf1a30Sjl139090 
30225cf1a30Sjl139090 	/* Free the duplicated buf */
30325cf1a30Sjl139090 	if (buf != NULL)
30425cf1a30Sjl139090 		free(buf);
30525cf1a30Sjl139090 }
30625cf1a30Sjl139090 
30725cf1a30Sjl139090 static void
30825cf1a30Sjl139090 do_get_hwd_va(fcode_env_t *env)
30925cf1a30Sjl139090 {
31025cf1a30Sjl139090 	private_data_t	*pdp = DEVICE_PRIVATE(env);
31125cf1a30Sjl139090 	char		*service = "get-hwd-va";
31225cf1a30Sjl139090 	char		*buf;
31325cf1a30Sjl139090 	uint32_t	portid = 0;
31425cf1a30Sjl139090 	int		ch;
31525cf1a30Sjl139090 	int		error;
31625cf1a30Sjl139090 	fc_cell_t	status;
31725cf1a30Sjl139090 	void		*hwd_va;
31825cf1a30Sjl139090 
31925cf1a30Sjl139090 	CHECK_DEPTH(env, 2, "jupiter:get-hwd-va");
32025cf1a30Sjl139090 
32125cf1a30Sjl139090 	/* Get a portid with string format */
32225cf1a30Sjl139090 	buf = pop_a_string(env, NULL);
32325cf1a30Sjl139090 
32425cf1a30Sjl139090 	/* Convert to the integer from the string */
32525cf1a30Sjl139090 	if (sscanf(buf, "%x", &portid) != 1) {
32625cf1a30Sjl139090 		throw_from_fclib(env, 1, "jupiter:%s: invalid portid",
32725cf1a30Sjl139090 		    service);
32825cf1a30Sjl139090 	}
32925cf1a30Sjl139090 
33025cf1a30Sjl139090 	ch = OPL_PORTID_TO_CHANNEL(portid);
33125cf1a30Sjl139090 	if (!OPL_VALID_CHANNEL(ch)) {
33225cf1a30Sjl139090 		throw_from_fclib(env, 1, "jupiter:%s: invalid poritd",
33325cf1a30Sjl139090 		    service);
33425cf1a30Sjl139090 		hwd_va = 0;
33525cf1a30Sjl139090 		goto out;
33625cf1a30Sjl139090 	}
33725cf1a30Sjl139090 
33825cf1a30Sjl139090 	if (ch == OPL_CMU_CHANNEL) {
33925cf1a30Sjl139090 		hwd_va = (void *)&hwd_va_cmu;
34025cf1a30Sjl139090 	} else {
34125cf1a30Sjl139090 		hwd_va = (void *)&hwd_va_pci;
34225cf1a30Sjl139090 	}
34325cf1a30Sjl139090 
34425cf1a30Sjl139090 	/*
34525cf1a30Sjl139090 	 * Get the virtual address of hwd specified with portid.
34625cf1a30Sjl139090 	 */
34725cf1a30Sjl139090 	error = fc_run_priv(pdp->common, service, 2, 1,
34825cf1a30Sjl139090 	    fc_uint32_t2cell(portid), fc_ptr2cell(hwd_va), &status);
34925cf1a30Sjl139090 
35025cf1a30Sjl139090 	if (error || !status)
35125cf1a30Sjl139090 		throw_from_fclib(env, 1, "jupiter:%s: failed\n", service);
35225cf1a30Sjl139090 
35325cf1a30Sjl139090 out:
35425cf1a30Sjl139090 	PUSH(DS, (fstack_t)hwd_va);
35525cf1a30Sjl139090 }
35625cf1a30Sjl139090 
35725cf1a30Sjl139090 static void
35825cf1a30Sjl139090 do_get_intrp_name(fcode_env_t *env)
35925cf1a30Sjl139090 {
36025cf1a30Sjl139090 	/*
36125cf1a30Sjl139090 	 * Just pass the "eFCode" string.
36225cf1a30Sjl139090 	 */
36325cf1a30Sjl139090 
36425cf1a30Sjl139090 	debug_msg(DEBUG_FIND_FCODE,
36525cf1a30Sjl139090 	    "jupiter: do_get_intrp_name: eFCode\n");
36625cf1a30Sjl139090 
36725cf1a30Sjl139090 	push_a_string(env, "eFCode");
36825cf1a30Sjl139090 }
36925cf1a30Sjl139090 
37025cf1a30Sjl139090 static void
37125cf1a30Sjl139090 do_master_interrupt(fcode_env_t *env)
37225cf1a30Sjl139090 {
373*53123245Smv143129 	private_data_t	*pdp = DEVICE_PRIVATE(env);
374*53123245Smv143129 	char		*service = "master-interrupt";
37525cf1a30Sjl139090 	int		portid;
37625cf1a30Sjl139090 	token_t		xt;
377*53123245Smv143129 	int		error;
378*53123245Smv143129 	fc_cell_t	status;
37925cf1a30Sjl139090 
380*53123245Smv143129 	CHECK_DEPTH(env, 2, "jupiter:master-interrupt");
38125cf1a30Sjl139090 	portid	= POP(DS);
38225cf1a30Sjl139090 	xt	= POP(DS);
38325cf1a30Sjl139090 
384*53123245Smv143129 	/*
385*53123245Smv143129 	 * Install the master interrupt handler for this port id.
386*53123245Smv143129 	 */
387*53123245Smv143129 	error = fc_run_priv(pdp->common, service, 2, 1,
388*53123245Smv143129 	    fc_uint32_t2cell(portid), fc_uint32_t2cell(xt), &status);
389*53123245Smv143129 
390*53123245Smv143129 	if (error || !status)
391*53123245Smv143129 		throw_from_fclib(env, 1, "jupiter:%s: failed\n", service);
392*53123245Smv143129 
39325cf1a30Sjl139090 	PUSH(DS, FALSE);
394*53123245Smv143129 
39525cf1a30Sjl139090 	debug_msg(DEBUG_REG_ACCESS,
39625cf1a30Sjl139090 	    "jupiter:master-interrupt ( %x %x ) -> %x\n",
39725cf1a30Sjl139090 	    portid, xt, (int)FALSE);
39825cf1a30Sjl139090 }
39925cf1a30Sjl139090 
40025cf1a30Sjl139090 static void
40125cf1a30Sjl139090 do_register_vector_entry(fcode_env_t *env)
40225cf1a30Sjl139090 {
40325cf1a30Sjl139090 	int	ign, ino, level;
40425cf1a30Sjl139090 
40525cf1a30Sjl139090 	CHECK_DEPTH(env, 3, "jupiter:register-vector-entry");
40625cf1a30Sjl139090 	ign   = POP(DS);
40725cf1a30Sjl139090 	ino   = POP(DS);
40825cf1a30Sjl139090 	level = POP(DS);
40925cf1a30Sjl139090 
41025cf1a30Sjl139090 	PUSH(DS, FALSE);
41125cf1a30Sjl139090 	debug_msg(DEBUG_REG_ACCESS,
41225cf1a30Sjl139090 	    "jupiter:register-vector-entry ( %x %x %x ) -> %x\n",
41325cf1a30Sjl139090 	    ign, ino, level, (int)FALSE);
41425cf1a30Sjl139090 }
41525cf1a30Sjl139090 
41625cf1a30Sjl139090 static void
41725cf1a30Sjl139090 do_get_interrupt_target(fcode_env_t *env)
41825cf1a30Sjl139090 {
41925cf1a30Sjl139090 	int	mid = -1;
42025cf1a30Sjl139090 
42125cf1a30Sjl139090 	PUSH(DS, mid);
42225cf1a30Sjl139090 	debug_msg(DEBUG_REG_ACCESS,
42325cf1a30Sjl139090 		"jupiter:get-interrupt-target ( ) -> %x\n", mid);
42425cf1a30Sjl139090 }
42525cf1a30Sjl139090 
42625cf1a30Sjl139090 
42725cf1a30Sjl139090 #pragma init(_init)
42825cf1a30Sjl139090 
42925cf1a30Sjl139090 static void
43025cf1a30Sjl139090 _init(void)
43125cf1a30Sjl139090 {
43225cf1a30Sjl139090 	fcode_env_t *env = initial_env;
43325cf1a30Sjl139090 
43425cf1a30Sjl139090 	ASSERT(env);
43525cf1a30Sjl139090 	ASSERT(env->current_device);
43625cf1a30Sjl139090 	NOTICE;
43725cf1a30Sjl139090 
43825cf1a30Sjl139090 	create_int_prop(env, "#address-cells", 2);
43925cf1a30Sjl139090 
44025cf1a30Sjl139090 	FORTH(0,	"map-in",		do_map_in);
44125cf1a30Sjl139090 	FORTH(0,	"map-out",		do_map_out);
44225cf1a30Sjl139090 	FORTH(0,	"get-portid",		do_get_io_portid);
44325cf1a30Sjl139090 	FORTH(0,	"decode-unit",		do_decode_unit);
44425cf1a30Sjl139090 	FORTH(0,	"encode-unit",		do_encode_unit);
44525cf1a30Sjl139090 	FORTH(0,	"device-id",		do_device_id);
44625cf1a30Sjl139090 	FORTH(0,	"get-hwd-va",		do_get_hwd_va);
44725cf1a30Sjl139090 	FORTH(0,	"get-fcinterp-name",	do_get_intrp_name);
44825cf1a30Sjl139090 	FORTH(0,	"master-interrupt",	do_master_interrupt);
44925cf1a30Sjl139090 	FORTH(0,	"register-vector-entry", do_register_vector_entry);
45025cf1a30Sjl139090 	FORTH(0,	"get-interrupt-target",	do_get_interrupt_target);
45125cf1a30Sjl139090 }
452