17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate * CDDL HEADER START
37c478bd9Sstevel@tonic-gate *
47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the
57c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only
67c478bd9Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance
77c478bd9Sstevel@tonic-gate * with the License.
87c478bd9Sstevel@tonic-gate *
97c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
107c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
117c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions
127c478bd9Sstevel@tonic-gate * and limitations under the License.
137c478bd9Sstevel@tonic-gate *
147c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
157c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
167c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
177c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
187c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
197c478bd9Sstevel@tonic-gate *
207c478bd9Sstevel@tonic-gate * CDDL HEADER END
217c478bd9Sstevel@tonic-gate */
227c478bd9Sstevel@tonic-gate /*
23*6d22b733Sdhain * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
24*6d22b733Sdhain * Use is subject to license terms.
257c478bd9Sstevel@tonic-gate */
267c478bd9Sstevel@tonic-gate
277c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI"
287c478bd9Sstevel@tonic-gate
297c478bd9Sstevel@tonic-gate #include <stdio.h>
307c478bd9Sstevel@tonic-gate #include <stdlib.h>
317c478bd9Sstevel@tonic-gate #include <strings.h>
327c478bd9Sstevel@tonic-gate
337c478bd9Sstevel@tonic-gate #include <fcode/private.h>
347c478bd9Sstevel@tonic-gate #include <fcode/log.h>
357c478bd9Sstevel@tonic-gate
367c478bd9Sstevel@tonic-gate #include <fcdriver/fcdriver.h>
377c478bd9Sstevel@tonic-gate
387c478bd9Sstevel@tonic-gate static fc_cell_t
fc_reg_read(fcode_env_t * env,char * service,fstack_t virt,int * errp)397c478bd9Sstevel@tonic-gate fc_reg_read(fcode_env_t *env, char *service, fstack_t virt, int *errp)
407c478bd9Sstevel@tonic-gate {
417c478bd9Sstevel@tonic-gate fc_cell_t virtaddr, data;
427c478bd9Sstevel@tonic-gate int error, nin;
437c478bd9Sstevel@tonic-gate
447c478bd9Sstevel@tonic-gate if (!is_mcookie(virt))
457c478bd9Sstevel@tonic-gate forth_abort(env, "fc_reg_read: bad mcookie: 0x%x\n", virt);
467c478bd9Sstevel@tonic-gate
477c478bd9Sstevel@tonic-gate virtaddr = mcookie_to_addr(virt);
487c478bd9Sstevel@tonic-gate
497c478bd9Sstevel@tonic-gate /* Supress fc_run_priv error msgs on peeks */
507c478bd9Sstevel@tonic-gate nin = ((errp == NULL) ? 1 : (1 | FCRP_NOERROR));
517c478bd9Sstevel@tonic-gate
527c478bd9Sstevel@tonic-gate error = fc_run_priv(env->private, service, nin, 1, virtaddr, &data);
537c478bd9Sstevel@tonic-gate if (errp)
547c478bd9Sstevel@tonic-gate /* Don't report error on peeks */
557c478bd9Sstevel@tonic-gate *errp = error;
567c478bd9Sstevel@tonic-gate else if (error) {
57*6d22b733Sdhain forth_abort(env, "fc_read_reg: ERROR: cookie: %llx"
587c478bd9Sstevel@tonic-gate " virt: %llx\n", (uint64_t)virt, (uint64_t)virtaddr);
597c478bd9Sstevel@tonic-gate }
607c478bd9Sstevel@tonic-gate return (data);
617c478bd9Sstevel@tonic-gate }
627c478bd9Sstevel@tonic-gate
637c478bd9Sstevel@tonic-gate static void
fc_reg_write(fcode_env_t * env,char * service,fstack_t virt,fc_cell_t data,int * errp)647c478bd9Sstevel@tonic-gate fc_reg_write(fcode_env_t *env, char *service, fstack_t virt, fc_cell_t data,
657c478bd9Sstevel@tonic-gate int *errp)
667c478bd9Sstevel@tonic-gate {
677c478bd9Sstevel@tonic-gate fc_cell_t virtaddr;
687c478bd9Sstevel@tonic-gate int error, nin;
697c478bd9Sstevel@tonic-gate
707c478bd9Sstevel@tonic-gate if (!is_mcookie(virt))
717c478bd9Sstevel@tonic-gate forth_abort(env, "fc_reg_write: bad mcookie: 0x%x\n", virt);
727c478bd9Sstevel@tonic-gate
737c478bd9Sstevel@tonic-gate virtaddr = mcookie_to_addr(virt);
747c478bd9Sstevel@tonic-gate
757c478bd9Sstevel@tonic-gate /* Supress fc_run_priv error msgs on pokes */
767c478bd9Sstevel@tonic-gate nin = ((errp == NULL) ? 2 : (2 | FCRP_NOERROR));
777c478bd9Sstevel@tonic-gate
787c478bd9Sstevel@tonic-gate error = fc_run_priv(env->private, service, nin, 0, virtaddr, data);
797c478bd9Sstevel@tonic-gate if (errp)
807c478bd9Sstevel@tonic-gate /* Don't report error on pokes */
817c478bd9Sstevel@tonic-gate *errp = error;
827c478bd9Sstevel@tonic-gate else if (error) {
83*6d22b733Sdhain forth_abort(env, "fc_write_reg: ERROR: cookie: %llx"
847c478bd9Sstevel@tonic-gate " virt: %llx\n", (uint64_t)virt, (uint64_t)virtaddr);
857c478bd9Sstevel@tonic-gate }
867c478bd9Sstevel@tonic-gate }
877c478bd9Sstevel@tonic-gate
887c478bd9Sstevel@tonic-gate static int
check_address_abuse(fcode_env_t * env,fstack_t addr,char * type,int want_mcookie,void (* alt)(fcode_env_t *))897c478bd9Sstevel@tonic-gate check_address_abuse(fcode_env_t *env, fstack_t addr, char *type,
907c478bd9Sstevel@tonic-gate int want_mcookie, void (*alt)(fcode_env_t *))
917c478bd9Sstevel@tonic-gate {
927c478bd9Sstevel@tonic-gate if (is_mcookie(addr) != want_mcookie) {
937c478bd9Sstevel@tonic-gate debug_msg(DEBUG_ADDR_ABUSE, "Warning: %s to %s address: %llx\n",
947c478bd9Sstevel@tonic-gate type, want_mcookie ? "unmapped" : "mapped",
957c478bd9Sstevel@tonic-gate (uint64_t)addr);
967c478bd9Sstevel@tonic-gate (*alt)(env);
977c478bd9Sstevel@tonic-gate return (1);
987c478bd9Sstevel@tonic-gate }
997c478bd9Sstevel@tonic-gate return (0);
1007c478bd9Sstevel@tonic-gate }
1017c478bd9Sstevel@tonic-gate
1027c478bd9Sstevel@tonic-gate static void
rlfetch(fcode_env_t * env)1037c478bd9Sstevel@tonic-gate rlfetch(fcode_env_t *env)
1047c478bd9Sstevel@tonic-gate {
1057c478bd9Sstevel@tonic-gate fstack_t p;
1067c478bd9Sstevel@tonic-gate
1077c478bd9Sstevel@tonic-gate CHECK_DEPTH(env, 1, "rl@");
1087c478bd9Sstevel@tonic-gate p = TOS;
1097c478bd9Sstevel@tonic-gate if (!check_address_abuse(env, p, "rl@", 1, lfetch))
1107c478bd9Sstevel@tonic-gate TOS = (lforth_t)fc_reg_read(env, "rl@", p, NULL);
1117c478bd9Sstevel@tonic-gate }
1127c478bd9Sstevel@tonic-gate
1137c478bd9Sstevel@tonic-gate static void
rlstore(fcode_env_t * env)1147c478bd9Sstevel@tonic-gate rlstore(fcode_env_t *env)
1157c478bd9Sstevel@tonic-gate {
1167c478bd9Sstevel@tonic-gate fstack_t p, d;
1177c478bd9Sstevel@tonic-gate
1187c478bd9Sstevel@tonic-gate CHECK_DEPTH(env, 2, "rl!");
1197c478bd9Sstevel@tonic-gate p = TOS;
1207c478bd9Sstevel@tonic-gate if (!check_address_abuse(env, p, "rl!", 1, lstore)) {
1217c478bd9Sstevel@tonic-gate p = POP(DS);
1227c478bd9Sstevel@tonic-gate d = POP(DS);
1237c478bd9Sstevel@tonic-gate fc_reg_write(env, "rl!", p, d, NULL);
1247c478bd9Sstevel@tonic-gate }
1257c478bd9Sstevel@tonic-gate }
1267c478bd9Sstevel@tonic-gate
1277c478bd9Sstevel@tonic-gate static void
rwfetch(fcode_env_t * env)1287c478bd9Sstevel@tonic-gate rwfetch(fcode_env_t *env)
1297c478bd9Sstevel@tonic-gate {
1307c478bd9Sstevel@tonic-gate fstack_t p;
1317c478bd9Sstevel@tonic-gate
1327c478bd9Sstevel@tonic-gate CHECK_DEPTH(env, 1, "rw@");
1337c478bd9Sstevel@tonic-gate p = TOS;
1347c478bd9Sstevel@tonic-gate if (!check_address_abuse(env, p, "rw@", 1, wfetch))
1357c478bd9Sstevel@tonic-gate TOS = (wforth_t)fc_reg_read(env, "rw@", p, NULL);
1367c478bd9Sstevel@tonic-gate }
1377c478bd9Sstevel@tonic-gate
1387c478bd9Sstevel@tonic-gate static void
rwstore(fcode_env_t * env)1397c478bd9Sstevel@tonic-gate rwstore(fcode_env_t *env)
1407c478bd9Sstevel@tonic-gate {
1417c478bd9Sstevel@tonic-gate fstack_t p, d;
1427c478bd9Sstevel@tonic-gate
1437c478bd9Sstevel@tonic-gate CHECK_DEPTH(env, 2, "rw!");
1447c478bd9Sstevel@tonic-gate p = TOS;
1457c478bd9Sstevel@tonic-gate if (!check_address_abuse(env, p, "rw!", 1, wstore)) {
1467c478bd9Sstevel@tonic-gate p = POP(DS);
1477c478bd9Sstevel@tonic-gate d = POP(DS);
1487c478bd9Sstevel@tonic-gate fc_reg_write(env, "rw!", p, d, NULL);
1497c478bd9Sstevel@tonic-gate }
1507c478bd9Sstevel@tonic-gate }
1517c478bd9Sstevel@tonic-gate
1527c478bd9Sstevel@tonic-gate void
rbfetch(fcode_env_t * env)1537c478bd9Sstevel@tonic-gate rbfetch(fcode_env_t *env)
1547c478bd9Sstevel@tonic-gate {
1557c478bd9Sstevel@tonic-gate fstack_t p;
1567c478bd9Sstevel@tonic-gate
1577c478bd9Sstevel@tonic-gate CHECK_DEPTH(env, 1, "rb@");
1587c478bd9Sstevel@tonic-gate p = TOS;
1597c478bd9Sstevel@tonic-gate if (!check_address_abuse(env, p, "rb@", 1, cfetch)) {
1607c478bd9Sstevel@tonic-gate TOS = (uchar_t)fc_reg_read(env, "rb@", p, NULL);
1617c478bd9Sstevel@tonic-gate }
1627c478bd9Sstevel@tonic-gate }
1637c478bd9Sstevel@tonic-gate
1647c478bd9Sstevel@tonic-gate static void
rbstore(fcode_env_t * env)1657c478bd9Sstevel@tonic-gate rbstore(fcode_env_t *env)
1667c478bd9Sstevel@tonic-gate {
1677c478bd9Sstevel@tonic-gate fstack_t p, d;
1687c478bd9Sstevel@tonic-gate
1697c478bd9Sstevel@tonic-gate CHECK_DEPTH(env, 2, "rb!");
1707c478bd9Sstevel@tonic-gate p = TOS;
1717c478bd9Sstevel@tonic-gate if (!check_address_abuse(env, p, "rb!", 1, cstore)) {
1727c478bd9Sstevel@tonic-gate p = POP(DS);
1737c478bd9Sstevel@tonic-gate d = POP(DS);
1747c478bd9Sstevel@tonic-gate fc_reg_write(env, "rb!", p, d, NULL);
1757c478bd9Sstevel@tonic-gate }
1767c478bd9Sstevel@tonic-gate }
1777c478bd9Sstevel@tonic-gate
1787c478bd9Sstevel@tonic-gate /*
1797c478bd9Sstevel@tonic-gate * rx@ ( xa -- xv )
1807c478bd9Sstevel@tonic-gate */
1817c478bd9Sstevel@tonic-gate static void
rxfetch(fcode_env_t * env)1827c478bd9Sstevel@tonic-gate rxfetch(fcode_env_t *env)
1837c478bd9Sstevel@tonic-gate {
1847c478bd9Sstevel@tonic-gate fstack_t p;
1857c478bd9Sstevel@tonic-gate xforth_t x;
1867c478bd9Sstevel@tonic-gate
1877c478bd9Sstevel@tonic-gate CHECK_DEPTH(env, 1, "rx@");
1887c478bd9Sstevel@tonic-gate p = TOS;
1897c478bd9Sstevel@tonic-gate if (!check_address_abuse(env, p, "rx@", 1, xfetch)) {
1907c478bd9Sstevel@tonic-gate p = POP(DS);
1917c478bd9Sstevel@tonic-gate push_xforth(env, (xforth_t)fc_reg_read(env, "rx@", p, NULL));
1927c478bd9Sstevel@tonic-gate }
1937c478bd9Sstevel@tonic-gate }
1947c478bd9Sstevel@tonic-gate
1957c478bd9Sstevel@tonic-gate /*
1967c478bd9Sstevel@tonic-gate * rx! ( xv xa -- )
1977c478bd9Sstevel@tonic-gate */
1987c478bd9Sstevel@tonic-gate static void
rxstore(fcode_env_t * env)1997c478bd9Sstevel@tonic-gate rxstore(fcode_env_t *env)
2007c478bd9Sstevel@tonic-gate {
2017c478bd9Sstevel@tonic-gate fstack_t p;
2027c478bd9Sstevel@tonic-gate xforth_t d;
2037c478bd9Sstevel@tonic-gate
2047c478bd9Sstevel@tonic-gate CHECK_DEPTH(env, 2, "rx!");
2057c478bd9Sstevel@tonic-gate p = TOS;
2067c478bd9Sstevel@tonic-gate if (!check_address_abuse(env, p, "rx!", 1, xstore)) {
2077c478bd9Sstevel@tonic-gate p = POP(DS);
2087c478bd9Sstevel@tonic-gate d = pop_xforth(env);
2097c478bd9Sstevel@tonic-gate fc_reg_write(env, "rx!", p, d, NULL);
2107c478bd9Sstevel@tonic-gate }
2117c478bd9Sstevel@tonic-gate }
2127c478bd9Sstevel@tonic-gate
2137c478bd9Sstevel@tonic-gate static void
lpeek(fcode_env_t * env)2147c478bd9Sstevel@tonic-gate lpeek(fcode_env_t *env)
2157c478bd9Sstevel@tonic-gate {
2167c478bd9Sstevel@tonic-gate fstack_t p;
2177c478bd9Sstevel@tonic-gate lforth_t r;
2187c478bd9Sstevel@tonic-gate int error;
2197c478bd9Sstevel@tonic-gate
2207c478bd9Sstevel@tonic-gate CHECK_DEPTH(env, 1, "lpeek");
2217c478bd9Sstevel@tonic-gate p = POP(DS);
2227c478bd9Sstevel@tonic-gate r = (lforth_t)fc_reg_read(env, "rl@", p, &error);
2237c478bd9Sstevel@tonic-gate if (error)
2247c478bd9Sstevel@tonic-gate PUSH(DS, FALSE);
2257c478bd9Sstevel@tonic-gate else {
2267c478bd9Sstevel@tonic-gate PUSH(DS, r);
2277c478bd9Sstevel@tonic-gate PUSH(DS, TRUE);
2287c478bd9Sstevel@tonic-gate }
2297c478bd9Sstevel@tonic-gate }
2307c478bd9Sstevel@tonic-gate
2317c478bd9Sstevel@tonic-gate static void
lpoke(fcode_env_t * env)2327c478bd9Sstevel@tonic-gate lpoke(fcode_env_t *env)
2337c478bd9Sstevel@tonic-gate {
2347c478bd9Sstevel@tonic-gate fstack_t p, d;
2357c478bd9Sstevel@tonic-gate int error;
2367c478bd9Sstevel@tonic-gate
2377c478bd9Sstevel@tonic-gate CHECK_DEPTH(env, 2, "lpoke");
2387c478bd9Sstevel@tonic-gate p = POP(DS);
2397c478bd9Sstevel@tonic-gate d = POP(DS);
2407c478bd9Sstevel@tonic-gate fc_reg_write(env, "rl!", p, d, &error);
2417c478bd9Sstevel@tonic-gate PUSH(DS, error ? FALSE : TRUE);
2427c478bd9Sstevel@tonic-gate }
2437c478bd9Sstevel@tonic-gate
2447c478bd9Sstevel@tonic-gate static void
wpeek(fcode_env_t * env)2457c478bd9Sstevel@tonic-gate wpeek(fcode_env_t *env)
2467c478bd9Sstevel@tonic-gate {
2477c478bd9Sstevel@tonic-gate fstack_t p;
2487c478bd9Sstevel@tonic-gate int error;
2497c478bd9Sstevel@tonic-gate wforth_t r;
2507c478bd9Sstevel@tonic-gate
2517c478bd9Sstevel@tonic-gate CHECK_DEPTH(env, 1, "wpeek");
2527c478bd9Sstevel@tonic-gate p = POP(DS);
2537c478bd9Sstevel@tonic-gate r = (wforth_t)fc_reg_read(env, "rw@", p, &error);
2547c478bd9Sstevel@tonic-gate if (error)
2557c478bd9Sstevel@tonic-gate PUSH(DS, FALSE);
2567c478bd9Sstevel@tonic-gate else {
2577c478bd9Sstevel@tonic-gate PUSH(DS, r);
2587c478bd9Sstevel@tonic-gate PUSH(DS, TRUE);
2597c478bd9Sstevel@tonic-gate }
2607c478bd9Sstevel@tonic-gate }
2617c478bd9Sstevel@tonic-gate
2627c478bd9Sstevel@tonic-gate static void
wpoke(fcode_env_t * env)2637c478bd9Sstevel@tonic-gate wpoke(fcode_env_t *env)
2647c478bd9Sstevel@tonic-gate {
2657c478bd9Sstevel@tonic-gate fstack_t p, d;
2667c478bd9Sstevel@tonic-gate int error;
2677c478bd9Sstevel@tonic-gate
2687c478bd9Sstevel@tonic-gate CHECK_DEPTH(env, 2, "wpoke");
2697c478bd9Sstevel@tonic-gate p = POP(DS);
2707c478bd9Sstevel@tonic-gate d = POP(DS);
2717c478bd9Sstevel@tonic-gate fc_reg_write(env, "rw!", p, d, &error);
2727c478bd9Sstevel@tonic-gate PUSH(DS, error ? FALSE : TRUE);
2737c478bd9Sstevel@tonic-gate }
2747c478bd9Sstevel@tonic-gate
2757c478bd9Sstevel@tonic-gate static void
cpeek(fcode_env_t * env)2767c478bd9Sstevel@tonic-gate cpeek(fcode_env_t *env)
2777c478bd9Sstevel@tonic-gate {
2787c478bd9Sstevel@tonic-gate fstack_t p;
2797c478bd9Sstevel@tonic-gate uchar_t r;
2807c478bd9Sstevel@tonic-gate int error;
2817c478bd9Sstevel@tonic-gate
2827c478bd9Sstevel@tonic-gate CHECK_DEPTH(env, 1, "cpeek");
2837c478bd9Sstevel@tonic-gate p = POP(DS);
2847c478bd9Sstevel@tonic-gate r = (uchar_t)fc_reg_read(env, "rb@", p, &error);
2857c478bd9Sstevel@tonic-gate if (error)
2867c478bd9Sstevel@tonic-gate PUSH(DS, FALSE);
2877c478bd9Sstevel@tonic-gate else {
2887c478bd9Sstevel@tonic-gate PUSH(DS, r);
2897c478bd9Sstevel@tonic-gate PUSH(DS, TRUE);
2907c478bd9Sstevel@tonic-gate }
2917c478bd9Sstevel@tonic-gate }
2927c478bd9Sstevel@tonic-gate
2937c478bd9Sstevel@tonic-gate static void
cpoke(fcode_env_t * env)2947c478bd9Sstevel@tonic-gate cpoke(fcode_env_t *env)
2957c478bd9Sstevel@tonic-gate {
2967c478bd9Sstevel@tonic-gate fstack_t p, d;
2977c478bd9Sstevel@tonic-gate int error;
2987c478bd9Sstevel@tonic-gate
2997c478bd9Sstevel@tonic-gate CHECK_DEPTH(env, 2, "cpoke");
3007c478bd9Sstevel@tonic-gate p = POP(DS);
3017c478bd9Sstevel@tonic-gate d = POP(DS);
3027c478bd9Sstevel@tonic-gate fc_reg_write(env, "rb!", p, d, &error);
3037c478bd9Sstevel@tonic-gate PUSH(DS, error ? FALSE : TRUE);
3047c478bd9Sstevel@tonic-gate }
3057c478bd9Sstevel@tonic-gate
3067c478bd9Sstevel@tonic-gate /*
3077c478bd9Sstevel@tonic-gate * fcdriver version of cfetch, replaces base 'c@'
3087c478bd9Sstevel@tonic-gate */
3097c478bd9Sstevel@tonic-gate static void
fcd_cfetch(fcode_env_t * env)3107c478bd9Sstevel@tonic-gate fcd_cfetch(fcode_env_t *env)
3117c478bd9Sstevel@tonic-gate {
3127c478bd9Sstevel@tonic-gate fstack_t addr = TOS;
3137c478bd9Sstevel@tonic-gate
3147c478bd9Sstevel@tonic-gate CHECK_DEPTH(env, 1, "c@");
3157c478bd9Sstevel@tonic-gate if (!check_address_abuse(env, addr, "c@", 0, rbfetch))
3167c478bd9Sstevel@tonic-gate cfetch(env);
3177c478bd9Sstevel@tonic-gate }
3187c478bd9Sstevel@tonic-gate
3197c478bd9Sstevel@tonic-gate /*
3207c478bd9Sstevel@tonic-gate * fcdriver version of cstore, replaces base 'c!'
3217c478bd9Sstevel@tonic-gate */
3227c478bd9Sstevel@tonic-gate static void
fcd_cstore(fcode_env_t * env)3237c478bd9Sstevel@tonic-gate fcd_cstore(fcode_env_t *env)
3247c478bd9Sstevel@tonic-gate {
3257c478bd9Sstevel@tonic-gate fstack_t addr = TOS;
3267c478bd9Sstevel@tonic-gate
3277c478bd9Sstevel@tonic-gate CHECK_DEPTH(env, 2, "c!");
3287c478bd9Sstevel@tonic-gate if (!check_address_abuse(env, addr, "c!", 0, rbstore))
3297c478bd9Sstevel@tonic-gate cstore(env);
3307c478bd9Sstevel@tonic-gate }
3317c478bd9Sstevel@tonic-gate
3327c478bd9Sstevel@tonic-gate /*
3337c478bd9Sstevel@tonic-gate * fcdriver version of wfetch, replaces base 'w@'
3347c478bd9Sstevel@tonic-gate */
3357c478bd9Sstevel@tonic-gate static void
fcd_wfetch(fcode_env_t * env)3367c478bd9Sstevel@tonic-gate fcd_wfetch(fcode_env_t *env)
3377c478bd9Sstevel@tonic-gate {
3387c478bd9Sstevel@tonic-gate fstack_t addr = TOS;
3397c478bd9Sstevel@tonic-gate
3407c478bd9Sstevel@tonic-gate CHECK_DEPTH(env, 1, "w@");
3417c478bd9Sstevel@tonic-gate if (!check_address_abuse(env, addr, "w@", 0, rwfetch))
3427c478bd9Sstevel@tonic-gate wfetch(env);
3437c478bd9Sstevel@tonic-gate }
3447c478bd9Sstevel@tonic-gate
3457c478bd9Sstevel@tonic-gate /*
3467c478bd9Sstevel@tonic-gate * fcdriver version of wstore, replaces base 'w!'
3477c478bd9Sstevel@tonic-gate */
3487c478bd9Sstevel@tonic-gate static void
fcd_wstore(fcode_env_t * env)3497c478bd9Sstevel@tonic-gate fcd_wstore(fcode_env_t *env)
3507c478bd9Sstevel@tonic-gate {
3517c478bd9Sstevel@tonic-gate fstack_t addr = TOS;
3527c478bd9Sstevel@tonic-gate
3537c478bd9Sstevel@tonic-gate CHECK_DEPTH(env, 2, "w!");
3547c478bd9Sstevel@tonic-gate if (!check_address_abuse(env, addr, "w!", 0, rwstore))
3557c478bd9Sstevel@tonic-gate wstore(env);
3567c478bd9Sstevel@tonic-gate }
3577c478bd9Sstevel@tonic-gate
3587c478bd9Sstevel@tonic-gate /*
3597c478bd9Sstevel@tonic-gate * fcdriver version of lfetch, replaces base 'l@'
3607c478bd9Sstevel@tonic-gate */
3617c478bd9Sstevel@tonic-gate static void
fcd_lfetch(fcode_env_t * env)3627c478bd9Sstevel@tonic-gate fcd_lfetch(fcode_env_t *env)
3637c478bd9Sstevel@tonic-gate {
3647c478bd9Sstevel@tonic-gate fstack_t addr = TOS;
3657c478bd9Sstevel@tonic-gate
3667c478bd9Sstevel@tonic-gate CHECK_DEPTH(env, 1, "l@");
3677c478bd9Sstevel@tonic-gate if (!check_address_abuse(env, addr, "l@", 0, rlfetch))
3687c478bd9Sstevel@tonic-gate lfetch(env);
3697c478bd9Sstevel@tonic-gate }
3707c478bd9Sstevel@tonic-gate
3717c478bd9Sstevel@tonic-gate /*
3727c478bd9Sstevel@tonic-gate * fcdriver version of lstore, replaces base 'l!'
3737c478bd9Sstevel@tonic-gate */
3747c478bd9Sstevel@tonic-gate static void
fcd_lstore(fcode_env_t * env)3757c478bd9Sstevel@tonic-gate fcd_lstore(fcode_env_t *env)
3767c478bd9Sstevel@tonic-gate {
3777c478bd9Sstevel@tonic-gate fstack_t addr = TOS;
3787c478bd9Sstevel@tonic-gate
3797c478bd9Sstevel@tonic-gate CHECK_DEPTH(env, 2, "l!");
3807c478bd9Sstevel@tonic-gate if (!check_address_abuse(env, addr, "l!", 0, rlstore))
3817c478bd9Sstevel@tonic-gate lstore(env);
3827c478bd9Sstevel@tonic-gate }
3837c478bd9Sstevel@tonic-gate
3847c478bd9Sstevel@tonic-gate /*
3857c478bd9Sstevel@tonic-gate * fcdriver version of xfetch, replaces base 'x@'
3867c478bd9Sstevel@tonic-gate */
3877c478bd9Sstevel@tonic-gate static void
fcd_xfetch(fcode_env_t * env)3887c478bd9Sstevel@tonic-gate fcd_xfetch(fcode_env_t *env)
3897c478bd9Sstevel@tonic-gate {
3907c478bd9Sstevel@tonic-gate fstack_t addr = TOS;
3917c478bd9Sstevel@tonic-gate
3927c478bd9Sstevel@tonic-gate CHECK_DEPTH(env, 1, "x@");
3937c478bd9Sstevel@tonic-gate if (!check_address_abuse(env, addr, "x@", 0, rxfetch))
3947c478bd9Sstevel@tonic-gate xfetch(env);
3957c478bd9Sstevel@tonic-gate }
3967c478bd9Sstevel@tonic-gate
3977c478bd9Sstevel@tonic-gate /*
3987c478bd9Sstevel@tonic-gate * fcdriver version of xstore, replaces base 'x!'
3997c478bd9Sstevel@tonic-gate */
4007c478bd9Sstevel@tonic-gate static void
fcd_xstore(fcode_env_t * env)4017c478bd9Sstevel@tonic-gate fcd_xstore(fcode_env_t *env)
4027c478bd9Sstevel@tonic-gate {
4037c478bd9Sstevel@tonic-gate fstack_t addr = TOS;
4047c478bd9Sstevel@tonic-gate
4057c478bd9Sstevel@tonic-gate CHECK_DEPTH(env, 2, "x!");
4067c478bd9Sstevel@tonic-gate if (!check_address_abuse(env, addr, "x!", 0, rxstore))
4077c478bd9Sstevel@tonic-gate xstore(env);
4087c478bd9Sstevel@tonic-gate }
4097c478bd9Sstevel@tonic-gate
4107c478bd9Sstevel@tonic-gate /*
4117c478bd9Sstevel@tonic-gate * fcdriver version of move, replaces base 'move'
4127c478bd9Sstevel@tonic-gate */
4137c478bd9Sstevel@tonic-gate static void
fcd_move(fcode_env_t * env)4147c478bd9Sstevel@tonic-gate fcd_move(fcode_env_t *env)
4157c478bd9Sstevel@tonic-gate {
4167c478bd9Sstevel@tonic-gate size_t len;
4177c478bd9Sstevel@tonic-gate uchar_t *destaddr, *srcaddr;
4187c478bd9Sstevel@tonic-gate
4197c478bd9Sstevel@tonic-gate CHECK_DEPTH(env, 3, "move");
4207c478bd9Sstevel@tonic-gate len = POP(DS);
4217c478bd9Sstevel@tonic-gate destaddr = ((uchar_t *)POP(DS));
4227c478bd9Sstevel@tonic-gate srcaddr = ((uchar_t *)POP(DS));
4237c478bd9Sstevel@tonic-gate for (; len > 0; len--, srcaddr++, destaddr++) {
4247c478bd9Sstevel@tonic-gate PUSH(DS, (fstack_t)srcaddr);
4257c478bd9Sstevel@tonic-gate fcd_cfetch(env);
4267c478bd9Sstevel@tonic-gate PUSH(DS, (fstack_t)destaddr);
4277c478bd9Sstevel@tonic-gate fcd_cstore(env);
4287c478bd9Sstevel@tonic-gate }
4297c478bd9Sstevel@tonic-gate }
4307c478bd9Sstevel@tonic-gate
4317c478bd9Sstevel@tonic-gate static void
fcd_comp(fcode_env_t * env)4327c478bd9Sstevel@tonic-gate fcd_comp(fcode_env_t *env)
4337c478bd9Sstevel@tonic-gate {
4347c478bd9Sstevel@tonic-gate char *str1, *str2, byte1, byte2;
4357c478bd9Sstevel@tonic-gate size_t len;
4367c478bd9Sstevel@tonic-gate
4377c478bd9Sstevel@tonic-gate CHECK_DEPTH(env, 3, "comp");
4387c478bd9Sstevel@tonic-gate len = (size_t)POP(DS);
4397c478bd9Sstevel@tonic-gate str1 = (char *)POP(DS);
4407c478bd9Sstevel@tonic-gate str2 = (char *)POP(DS);
4417c478bd9Sstevel@tonic-gate for (; len > 0; len--, str1++, str2++) {
4427c478bd9Sstevel@tonic-gate PUSH(DS, (fstack_t)str1);
4437c478bd9Sstevel@tonic-gate fcd_cfetch(env);
4447c478bd9Sstevel@tonic-gate byte1 = POP(DS);
4457c478bd9Sstevel@tonic-gate PUSH(DS, (fstack_t)str2);
4467c478bd9Sstevel@tonic-gate fcd_cfetch(env);
4477c478bd9Sstevel@tonic-gate byte2 = POP(DS);
4487c478bd9Sstevel@tonic-gate if (byte1 > byte2) {
4497c478bd9Sstevel@tonic-gate PUSH(DS, -1);
4507c478bd9Sstevel@tonic-gate return;
4517c478bd9Sstevel@tonic-gate }
4527c478bd9Sstevel@tonic-gate if (byte1 < byte2) {
4537c478bd9Sstevel@tonic-gate PUSH(DS, 1);
4547c478bd9Sstevel@tonic-gate return;
4557c478bd9Sstevel@tonic-gate }
4567c478bd9Sstevel@tonic-gate }
4577c478bd9Sstevel@tonic-gate PUSH(DS, 0);
4587c478bd9Sstevel@tonic-gate }
4597c478bd9Sstevel@tonic-gate
4607c478bd9Sstevel@tonic-gate char *
get_eeprom_value(fcode_env_t * env,char * name)4617c478bd9Sstevel@tonic-gate get_eeprom_value(fcode_env_t *env, char *name)
4627c478bd9Sstevel@tonic-gate {
4637c478bd9Sstevel@tonic-gate FILE *fd;
4647c478bd9Sstevel@tonic-gate char buf[80], *p;
4657c478bd9Sstevel@tonic-gate
4667c478bd9Sstevel@tonic-gate sprintf(buf, "eeprom '%s'", name);
4677c478bd9Sstevel@tonic-gate if ((fd = popen(buf, "r")) == NULL)
4687c478bd9Sstevel@tonic-gate return (NULL);
4697c478bd9Sstevel@tonic-gate fgets(buf, sizeof (buf), fd);
4707c478bd9Sstevel@tonic-gate pclose(fd);
4717c478bd9Sstevel@tonic-gate if ((p = strchr(buf, '\n')) != NULL)
4727c478bd9Sstevel@tonic-gate *p = '\0';
4737c478bd9Sstevel@tonic-gate if ((p = strchr(buf, '=')) != NULL)
4747c478bd9Sstevel@tonic-gate return (p + 1);
4757c478bd9Sstevel@tonic-gate return (NULL);
4767c478bd9Sstevel@tonic-gate }
4777c478bd9Sstevel@tonic-gate
4787c478bd9Sstevel@tonic-gate static void
local_mac_address(fcode_env_t * env)4797c478bd9Sstevel@tonic-gate local_mac_address(fcode_env_t *env)
4807c478bd9Sstevel@tonic-gate {
4817c478bd9Sstevel@tonic-gate char *mac_str;
4827c478bd9Sstevel@tonic-gate int mac_value;
4837c478bd9Sstevel@tonic-gate
4847c478bd9Sstevel@tonic-gate mac_str = get_eeprom_value(env, "local-mac-address?");
4857c478bd9Sstevel@tonic-gate if (mac_str != NULL && strcmp(mac_str, "true") == 0)
4867c478bd9Sstevel@tonic-gate mac_value = TRUE;
4877c478bd9Sstevel@tonic-gate else
4887c478bd9Sstevel@tonic-gate mac_value = FALSE;
4897c478bd9Sstevel@tonic-gate PUSH(DS, mac_value);
4907c478bd9Sstevel@tonic-gate }
4917c478bd9Sstevel@tonic-gate
4927c478bd9Sstevel@tonic-gate /*
4937c478bd9Sstevel@tonic-gate * Allow for programmatic over-ride of 'mac-address'
4947c478bd9Sstevel@tonic-gate */
4957c478bd9Sstevel@tonic-gate #define MAC_ADDR_SIZE 6
4967c478bd9Sstevel@tonic-gate static char *mac_addr;
4977c478bd9Sstevel@tonic-gate static int mac_addr_is_valid;
4987c478bd9Sstevel@tonic-gate
4997c478bd9Sstevel@tonic-gate void
set_mac_address(char * macaddr)5007c478bd9Sstevel@tonic-gate set_mac_address(char *macaddr)
5017c478bd9Sstevel@tonic-gate {
5027c478bd9Sstevel@tonic-gate mac_addr_is_valid = 1;
5037c478bd9Sstevel@tonic-gate memcpy(mac_addr, macaddr, MAC_ADDR_SIZE);
5047c478bd9Sstevel@tonic-gate }
5057c478bd9Sstevel@tonic-gate
5067c478bd9Sstevel@tonic-gate void
push_mac_address(fcode_env_t * env)5077c478bd9Sstevel@tonic-gate push_mac_address(fcode_env_t *env)
5087c478bd9Sstevel@tonic-gate {
5097c478bd9Sstevel@tonic-gate PUSH(DS, (fstack_t)mac_addr);
5107c478bd9Sstevel@tonic-gate PUSH(DS, MAC_ADDR_SIZE);
5117c478bd9Sstevel@tonic-gate }
5127c478bd9Sstevel@tonic-gate
5137c478bd9Sstevel@tonic-gate /*
5147c478bd9Sstevel@tonic-gate * Does driver call to get this.
5157c478bd9Sstevel@tonic-gate */
5167c478bd9Sstevel@tonic-gate static void
local_ether_addr(fcode_env_t * env)5177c478bd9Sstevel@tonic-gate local_ether_addr(fcode_env_t *env)
5187c478bd9Sstevel@tonic-gate {
5197c478bd9Sstevel@tonic-gate static fc_cell_t *mac_add;
5207c478bd9Sstevel@tonic-gate int error;
5217c478bd9Sstevel@tonic-gate
5227c478bd9Sstevel@tonic-gate mac_add = MALLOC(sizeof (fc_cell_t) * 2);
5237c478bd9Sstevel@tonic-gate error = fc_run_priv(env->private, "local-ether-addr", 0, 2, &mac_add[0],
5247c478bd9Sstevel@tonic-gate &mac_add[1]);
5257c478bd9Sstevel@tonic-gate if (error) {
5267c478bd9Sstevel@tonic-gate bzero(mac_add, sizeof (mac_add));
5277c478bd9Sstevel@tonic-gate }
5287c478bd9Sstevel@tonic-gate
5297c478bd9Sstevel@tonic-gate PUSH(DS, (fstack_t)&mac_add[0]);
5307c478bd9Sstevel@tonic-gate PUSH(DS, 6);
5317c478bd9Sstevel@tonic-gate }
5327c478bd9Sstevel@tonic-gate
5337c478bd9Sstevel@tonic-gate /*
5347c478bd9Sstevel@tonic-gate * 'mac-address' - complicated by 'local-mac-address' stuff.
5357c478bd9Sstevel@tonic-gate */
5367c478bd9Sstevel@tonic-gate static void
mac_address(fcode_env_t * env)5377c478bd9Sstevel@tonic-gate mac_address(fcode_env_t *env)
5387c478bd9Sstevel@tonic-gate {
5397c478bd9Sstevel@tonic-gate fstack_t d;
5407c478bd9Sstevel@tonic-gate
5417c478bd9Sstevel@tonic-gate if (mac_addr_is_valid) {
5427c478bd9Sstevel@tonic-gate push_mac_address(env);
5437c478bd9Sstevel@tonic-gate return;
5447c478bd9Sstevel@tonic-gate }
5457c478bd9Sstevel@tonic-gate
5467c478bd9Sstevel@tonic-gate /*
5477c478bd9Sstevel@tonic-gate * From here, we essentially re-implement OBP's 'mac-address' word.
5487c478bd9Sstevel@tonic-gate * on some platforms, this may need to be re-implemented.
5497c478bd9Sstevel@tonic-gate */
5507c478bd9Sstevel@tonic-gate local_mac_address(env);
5517c478bd9Sstevel@tonic-gate d = POP(DS);
5527c478bd9Sstevel@tonic-gate if (d) {
5537c478bd9Sstevel@tonic-gate push_a_string(env, "local-mac-address");
5547c478bd9Sstevel@tonic-gate get_inherited_prop(env);
5557c478bd9Sstevel@tonic-gate d = POP(DS);
5567c478bd9Sstevel@tonic-gate if (d == FALSE && TOS == 6)
5577c478bd9Sstevel@tonic-gate return;
5587c478bd9Sstevel@tonic-gate two_drop(env);
5597c478bd9Sstevel@tonic-gate }
5607c478bd9Sstevel@tonic-gate local_ether_addr(env);
5617c478bd9Sstevel@tonic-gate }
5627c478bd9Sstevel@tonic-gate
5637c478bd9Sstevel@tonic-gate /*
5647c478bd9Sstevel@tonic-gate * Allow for the programmatic setting of diagnostic-mode?
5657c478bd9Sstevel@tonic-gate */
5667c478bd9Sstevel@tonic-gate static int diag_mode_is_valid = 0;
5677c478bd9Sstevel@tonic-gate static int diag_mode = 0;
5687c478bd9Sstevel@tonic-gate
5697c478bd9Sstevel@tonic-gate void
set_diagnostic_mode(fcode_env_t * env)5707c478bd9Sstevel@tonic-gate set_diagnostic_mode(fcode_env_t *env)
5717c478bd9Sstevel@tonic-gate {
5727c478bd9Sstevel@tonic-gate fstack_t d = POP(DS);
5737c478bd9Sstevel@tonic-gate
5747c478bd9Sstevel@tonic-gate diag_mode = d;
5757c478bd9Sstevel@tonic-gate diag_mode_is_valid = 1;
5767c478bd9Sstevel@tonic-gate }
5777c478bd9Sstevel@tonic-gate
5787c478bd9Sstevel@tonic-gate void
push_diagnostic_mode(fcode_env_t * env)5797c478bd9Sstevel@tonic-gate push_diagnostic_mode(fcode_env_t *env)
5807c478bd9Sstevel@tonic-gate {
5817c478bd9Sstevel@tonic-gate PUSH(DS, (fstack_t)diag_mode);
5827c478bd9Sstevel@tonic-gate }
5837c478bd9Sstevel@tonic-gate
5847c478bd9Sstevel@tonic-gate /*
5857c478bd9Sstevel@tonic-gate * 'diagnostic-mode?' - diagnostic-mode? is equivalent to NVRAM 'diag-switch?'
5867c478bd9Sstevel@tonic-gate */
5877c478bd9Sstevel@tonic-gate static void
diagnostic_mode(fcode_env_t * env)5887c478bd9Sstevel@tonic-gate diagnostic_mode(fcode_env_t *env)
5897c478bd9Sstevel@tonic-gate {
5907c478bd9Sstevel@tonic-gate char *diag_str;
5917c478bd9Sstevel@tonic-gate int diag_value;
5927c478bd9Sstevel@tonic-gate
5937c478bd9Sstevel@tonic-gate if (!diag_mode_is_valid) {
5947c478bd9Sstevel@tonic-gate diag_str = get_eeprom_value(env, "diag-switch?");
5957c478bd9Sstevel@tonic-gate if (diag_str != NULL && strcmp(diag_str, "false") == 0)
5967c478bd9Sstevel@tonic-gate diag_value = FALSE;
5977c478bd9Sstevel@tonic-gate else
5987c478bd9Sstevel@tonic-gate diag_value = TRUE;
5997c478bd9Sstevel@tonic-gate PUSH(DS, diag_value);
6007c478bd9Sstevel@tonic-gate set_diagnostic_mode(env);
6017c478bd9Sstevel@tonic-gate }
6027c478bd9Sstevel@tonic-gate
6037c478bd9Sstevel@tonic-gate push_diagnostic_mode(env);
6047c478bd9Sstevel@tonic-gate }
6057c478bd9Sstevel@tonic-gate
6067c478bd9Sstevel@tonic-gate /*
6077c478bd9Sstevel@tonic-gate * May need to implement other memory-access Fcodes here (depending upon
6087c478bd9Sstevel@tonic-gate * abuse), like fill, comp, +!, etc., etc.
6097c478bd9Sstevel@tonic-gate */
6107c478bd9Sstevel@tonic-gate
6117c478bd9Sstevel@tonic-gate #pragma init(_init)
6127c478bd9Sstevel@tonic-gate
6137c478bd9Sstevel@tonic-gate static void
_init(void)6147c478bd9Sstevel@tonic-gate _init(void)
6157c478bd9Sstevel@tonic-gate {
6167c478bd9Sstevel@tonic-gate fcode_env_t *env = initial_env;
6177c478bd9Sstevel@tonic-gate
6187c478bd9Sstevel@tonic-gate mac_addr = MALLOC(MAC_ADDR_SIZE);
6197c478bd9Sstevel@tonic-gate
6207c478bd9Sstevel@tonic-gate ASSERT(env);
6217c478bd9Sstevel@tonic-gate NOTICE;
6227c478bd9Sstevel@tonic-gate
6237c478bd9Sstevel@tonic-gate ANSI(0x06e, 0, "l@", fcd_lfetch);
6247c478bd9Sstevel@tonic-gate ANSI(0x06f, 0, "w@", fcd_wfetch);
6257c478bd9Sstevel@tonic-gate ANSI(0x071, 0, "c@", fcd_cfetch);
6267c478bd9Sstevel@tonic-gate ANSI(0x073, 0, "l!", fcd_lstore);
6277c478bd9Sstevel@tonic-gate ANSI(0x074, 0, "w!", fcd_wstore);
6287c478bd9Sstevel@tonic-gate ANSI(0x075, 0, "c!", fcd_cstore);
6297c478bd9Sstevel@tonic-gate ANSI(0x078, 0, "move", fcd_move);
6307c478bd9Sstevel@tonic-gate ANSI(0x07a, 0, "comp", fcd_comp);
6317c478bd9Sstevel@tonic-gate
6327c478bd9Sstevel@tonic-gate ANSI(0x120, 0, "diagnostic-mode?", diagnostic_mode);
6337c478bd9Sstevel@tonic-gate
6347c478bd9Sstevel@tonic-gate ANSI(0x1a4, 0, "mac-address", mac_address);
6357c478bd9Sstevel@tonic-gate
6367c478bd9Sstevel@tonic-gate P1275(0x220, 0, "cpeek", cpeek);
6377c478bd9Sstevel@tonic-gate P1275(0x221, 0, "wpeek", wpeek);
6387c478bd9Sstevel@tonic-gate P1275(0x222, 0, "lpeek", lpeek);
6397c478bd9Sstevel@tonic-gate P1275(0x223, 0, "cpoke", cpoke);
6407c478bd9Sstevel@tonic-gate P1275(0x224, 0, "wpoke", wpoke);
6417c478bd9Sstevel@tonic-gate P1275(0x225, 0, "lpoke", lpoke);
6427c478bd9Sstevel@tonic-gate
6437c478bd9Sstevel@tonic-gate P1275(0x230, 0, "rb@", rbfetch);
6447c478bd9Sstevel@tonic-gate P1275(0x231, 0, "rb!", rbstore);
6457c478bd9Sstevel@tonic-gate P1275(0x232, 0, "rw@", rwfetch);
6467c478bd9Sstevel@tonic-gate P1275(0x233, 0, "rw!", rwstore);
6477c478bd9Sstevel@tonic-gate P1275(0x234, 0, "rl@", rlfetch);
6487c478bd9Sstevel@tonic-gate P1275(0x235, 0, "rl!", rlstore);
6497c478bd9Sstevel@tonic-gate
6507c478bd9Sstevel@tonic-gate P1275(0x246, 0, "x@", fcd_xfetch);
6517c478bd9Sstevel@tonic-gate P1275(0x247, 0, "x!", fcd_xstore);
6527c478bd9Sstevel@tonic-gate
6537c478bd9Sstevel@tonic-gate P1275(0x22e, 0, "rx@", rxfetch);
6547c478bd9Sstevel@tonic-gate P1275(0x22f, 0, "rx!", rxstore);
6557c478bd9Sstevel@tonic-gate FORTH(0, "set-diagnostic-mode", set_diagnostic_mode);
6567c478bd9Sstevel@tonic-gate FORTH(0, "local-mac-address?", local_mac_address);
6577c478bd9Sstevel@tonic-gate FORTH(0, "local-ether-addr", local_ether_addr);
6587c478bd9Sstevel@tonic-gate }
659