Beispiel #1
0
static void
do_get_hwd_va(fcode_env_t *env)
{
	private_data_t	*pdp = DEVICE_PRIVATE(env);
	char		*service = "get-hwd-va";
	char		*buf;
	uint32_t	portid = 0;
	int		ch;
	int		error;
	fc_cell_t	status;
	void		*hwd_va;

	CHECK_DEPTH(env, 2, "jupiter:get-hwd-va");

	/* Get a portid with string format */
	buf = pop_a_string(env, NULL);

	/* Convert to the integer from the string */
	if (sscanf(buf, "%x", &portid) != 1) {
		throw_from_fclib(env, 1, "jupiter:%s: invalid portid",
		    service);
	}

	ch = OPL_PORTID_TO_CHANNEL(portid);
	if (!OPL_VALID_CHANNEL(ch)) {
		throw_from_fclib(env, 1, "jupiter:%s: invalid poritd",
		    service);
		hwd_va = 0;
		goto out;
	}

	if (ch == OPL_CMU_CHANNEL) {
		hwd_va = (void *)&hwd_va_cmu;
	} else {
		hwd_va = (void *)&hwd_va_pci;
	}

	/*
	 * Get the virtual address of hwd specified with portid.
	 */
	error = fc_run_priv(pdp->common, service, 2, 1,
	    fc_uint32_t2cell(portid), fc_ptr2cell(hwd_va), &status);

	if (error || !status)
		throw_from_fclib(env, 1, "jupiter:%s: failed\n", service);

out:
	PUSH(DS, (fstack_t)hwd_va);
}
Beispiel #2
0
static void
do_master_interrupt(fcode_env_t *env)
{
	private_data_t	*pdp = DEVICE_PRIVATE(env);
	char		*service = "master-interrupt";
	int		portid;
	token_t		xt;
	int		error;
	fc_cell_t	status;

	CHECK_DEPTH(env, 2, "jupiter:master-interrupt");
	portid	= POP(DS);
	xt	= POP(DS);

	/*
	 * Install the master interrupt handler for this port id.
	 */
	error = fc_run_priv(pdp->common, service, 2, 1,
	    fc_uint32_t2cell(portid), fc_uint32_t2cell(xt), &status);

	if (error || !status)
		throw_from_fclib(env, 1, "jupiter:%s: failed\n", service);

	PUSH(DS, FALSE);

	debug_msg(DEBUG_REG_ACCESS,
	    "jupiter:master-interrupt ( %x %x ) -> %x\n",
	    portid, xt, (int)FALSE);
}
Beispiel #3
0
static void
do_decode_unit(fcode_env_t *env)
{
	uint32_t	hi;
	long long	lo;
	unsigned int	portid, lsb, ch;
	char		*buf;

	CHECK_DEPTH(env, 2, "jupiter:decode-unit");

	buf = pop_a_string(env, NULL);
	if (sscanf(buf, "%x,%llx", &portid, &lo) != 2) {
		if (sscanf(buf, "%x", &portid) != 1) {
			throw_from_fclib(env, 1, "jupiter:decode_unit:%s",
			    buf);
		}
		lo = 0;
	}

	lsb = OPL_IO_PORTID_TO_LSB(portid);
	ch  = OPL_PORTID_TO_CHANNEL(portid);
	hi  = OPL_ADDR_HI(lsb, ch);

	debug_msg(DEBUG_REG_ACCESS,
	    "jupiter:decode_unit ( '%s' ) -> %x %llx\n", buf, hi, lo);

	PUSH(DS, (fstack_t)lo);
	PUSH(DS, (fstack_t)hi);
}
Beispiel #4
0
void
alloc_mem(fcode_env_t *env)
{
	CHECK_DEPTH(env, 1, "alloc-mem");
	TOS = (fstack_t)MALLOC((size_t)TOS);
	if (!TOS) {
		throw_from_fclib(env, 1, "alloc-mem failed");
	}
}
Beispiel #5
0
fstack_t
mem_map_in(fcode_env_t *env, fstack_t hi, fstack_t lo, fstack_t len)
{
	private_data_t	*pdp = DEVICE_PRIVATE(env);
	fc_cell_t	virt;
	fstack_t	mcookie = NULL;
	char		*service = "map-in";
	int		error;
	int		offset = 0;

	/*
	 * The calculation of the offset, lo and len are left here
	 * due to historical precedence.
	 */

	offset = lo & PAGEOFFSET;
	lo &= PAGEMASK;
	len = (len + offset + PAGEOFFSET) & PAGEMASK;

	error = fc_run_priv(pdp->common, service, 3, 1, fc_size2cell(len),
	    fc_uint32_t2cell(hi), fc_uint32_t2cell(lo), &virt);

	if (error)
		throw_from_fclib(env, 1, "jupiter:%s: failed\n", service);

	mcookie = mapping_to_mcookie(virt, len, NULL, NULL);

	if (mcookie == NULL)
		throw_from_fclib(env, 1,
		    "jupiter:%s: mapping_to_mcookie failed\n", service);

	mcookie += offset;

	debug_msg(DEBUG_REG_ACCESS, "jupiter:%s: %llx -> %x\n", service,
	    (long long)virt, (uint32_t)mcookie);

	return (mcookie);
}
Beispiel #6
0
void
release(fcode_env_t *env)
{
	size_t size;
	void *addr;
	int error;

	CHECK_DEPTH(env, 2, "release-memory");
	addr = (void *)POP(DS);
	size = POP(DS);
	error = fc_run_priv(env->private, "release-memory", 2, 0,
	    fc_size2cell(size), fc_ptr2cell(addr));
	if (error)
		throw_from_fclib(env, 1, "client-services/release failed\n");
	delete_mapping((fstack_t)addr);
}
Beispiel #7
0
static void
fc_vtop(fcode_env_t *env)
{
	void *vaddr;
	fc_cell_t physlo, physhi;
	int error;

	CHECK_DEPTH(env, 1, "vtop");
	vaddr = (void *)POP(DS);
	error = fc_run_priv(env->private, "vtop", 1, 2,
	    fc_ptr2cell(vaddr), &physlo, &physhi);
	if (error)
		throw_from_fclib(env, 1, "fc_vtop: '>physical' failed\n");

	PUSH(DS, physlo);
	PUSH(DS, physhi);
}
Beispiel #8
0
void
parse_two_int(fcode_env_t *env)
{
	uint_t lo, hi;
	char *str;
	int len;

	CHECK_DEPTH(env, 2, "parse-2int");
	lo = 0;
	hi = 0;
	str = pop_a_string(env, &len);
	if (len) {
		if (sscanf(str, "%x,%x", &hi, &lo) != 2) {
			throw_from_fclib(env, 1, "parse_2int");
		}
	}
	PUSH(DS, lo);
	PUSH(DS, hi);
}
Beispiel #9
0
/*
 * claim under /openprom/client-services is used by schizo and oberon Fcode, we
 * call "claim-memory" service.
 */
void
claim(fcode_env_t *env)
{
	size_t size;
	void *hint;
	int align;
	fc_cell_t vaddr;
	int error;

	CHECK_DEPTH(env, 3, "claim-memory");
	hint = (void *)POP(DS);
	size = POP(DS);
	align = POP(DS);
	error = fc_run_priv(env->private, "claim-memory", 3, 1,
	    fc_int2cell(align), fc_size2cell(size), fc_ptr2cell(hint), &vaddr);
	if (error)
		throw_from_fclib(env, 1, "client-services/claim failed\n");
	vaddr = mapping_to_mcookie(vaddr, size, NULL, NULL);
	PUSH(DS, (fstack_t)vaddr);
}
Beispiel #10
0
static void
do_device_id(fcode_env_t *env)
{
	common_data_t	*cdp = COMMON_PRIVATE(env);
	char		*buf = NULL;
	uint32_t	hi;
	long long	lo;
	uint32_t	portid, ch, leaf;

	CHECK_DEPTH(env, 2, "jupiter:device-id");

	hi = POP(DS);
	lo = POP(DS);

	portid = 0;
	if (cdp && cdp->fc.unit_address &&
	    ((buf = strdup(cdp->fc.unit_address)) != NULL)) {
		/*
		 * Get portid number from unit_address
		 * Because of no leaf information in physical address
		 */
		if (sscanf(buf, "%x,%llx", &portid, &lo) != 2) {
			if (sscanf(buf, "%x", &portid) != 1) {
				throw_from_fclib(env, 1,
				    "jupiter:do_device_id: invalid %s", buf);
			}
		}
	} else {
		/*
		 * Non existence unit_address case.
		 * Convert physical address to portid.
		 */
		throw_from_fclib(env, 1,
		    "jupiter:do_device_id: failed unit address");
		DO_GET_IO_PORTID(env, lo, hi, portid);
	}

	debug_msg(DEBUG_FIND_FCODE,
	    "jupiter:do_device_id:(%x,%llx)\n", portid, lo);

	/* Pick up each ID from portid */
	ch   = OPL_PORTID_TO_CHANNEL(portid);
	leaf = OPL_PORTID_TO_LEAF(portid);

	if (ch == OPL_CMU_CHANNEL) {
		/*
		 * CMU-CH: PCICMU CHANNEL
		 */
		debug_msg(DEBUG_FIND_FCODE,
		    "jupiter:do_device_id:cmu-ch\n");
		push_a_string(env, "cmu-ch");
	} else if (OPL_OBERON_CHANNEL(ch) && OPL_VALID_LEAF(leaf)) {
		/*
		 * PCI-CH: Oberon Leaves CHANNEL
		 */
		if (leaf) {
			/* Leaf B */
			debug_msg(DEBUG_FIND_FCODE,
			    "jupiter:do_device_id:jup-oberon-pci1\n");
			push_a_string(env, "jup-oberon-pci1");
		} else {
			/* Leaf A */
			debug_msg(DEBUG_FIND_FCODE,
			    "jupiter:do_device_id:jup-oberon-pci0\n");
			push_a_string(env, "jup-oberon-pci0");
		}
	} else {
		/* Not matched to any channels */
		throw_from_fclib(env, 1,
		    "jupiter:do_device_id: invalid portid %x", portid);
		push_a_string(env, "");
	}

	/* Free the duplicated buf */
	if (buf != NULL)
		free(buf);
}