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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 * 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 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 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 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 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 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 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 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 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 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