2 * Copyright (c) 2000 Daniel Capo Sobral
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * Additional FICL words designed for FreeBSD's loader
35 #include <sys/types.h>
47 #include <machine/cpufunc.h>
49 #include "bootstrap.h"
54 #include <uuid/uuid.h>
59 extern int biospci_count_device_type(uint32_t);
60 extern int biospci_write_config(uint32_t, int, int, uint32_t);
61 extern int biospci_read_config(uint32_t, int, int, uint32_t *);
62 extern int biospci_find_devclass(uint32_t, int, uint32_t *);
63 extern int biospci_find_device(uint32_t, int, uint32_t *);
64 extern uint32_t biospci_locator(uint8_t, uint8_t, uint8_t);
67 * FreeBSD's loader interaction words and extras
69 * setenv ( value n name n' -- )
70 * setenv? ( value n name n' flag -- )
71 * getenv ( addr n -- addr' n' | -1 )
72 * unsetenv ( addr n -- )
73 * copyin ( addr addr' len -- )
74 * copyout ( addr addr' len -- )
75 * findfile ( name len type len' -- addr )
76 * pnpdevices ( -- addr )
77 * pnphandlers ( -- addr )
78 * ccall ( [[...[p10] p9] ... p1] n addr -- result )
79 * uuid-from-string ( addr n -- addr' )
80 * uuid-to-string ( addr' -- addr n | -1 )
85 ficlSetenv(ficlVm
*pVM
)
91 FICL_STACK_CHECK(ficlVmGetDataStack(pVM
), 4, 0);
93 names
= ficlStackPopInteger(ficlVmGetDataStack(pVM
));
94 namep
= (char *)ficlStackPopPointer(ficlVmGetDataStack(pVM
));
95 values
= ficlStackPopInteger(ficlVmGetDataStack(pVM
));
96 valuep
= (char *)ficlStackPopPointer(ficlVmGetDataStack(pVM
));
98 name
= (char *)ficlMalloc(names
+1);
100 ficlVmThrowError(pVM
, "Error: out of memory");
101 strncpy(name
, namep
, names
);
103 value
= (char *)ficlMalloc(values
+1);
105 ficlVmThrowError(pVM
, "Error: out of memory");
106 strncpy(value
, valuep
, values
);
107 value
[values
] = '\0';
109 setenv(name
, value
, 1);
115 ficlSetenvq(ficlVm
*pVM
)
118 char *namep
, *valuep
;
119 int names
, values
, overwrite
;
121 FICL_STACK_CHECK(ficlVmGetDataStack(pVM
), 5, 0);
123 overwrite
= ficlStackPopInteger(ficlVmGetDataStack(pVM
));
124 names
= ficlStackPopInteger(ficlVmGetDataStack(pVM
));
125 namep
= (char *)ficlStackPopPointer(ficlVmGetDataStack(pVM
));
126 values
= ficlStackPopInteger(ficlVmGetDataStack(pVM
));
127 valuep
= (char *)ficlStackPopPointer(ficlVmGetDataStack(pVM
));
129 name
= (char *)ficlMalloc(names
+1);
131 ficlVmThrowError(pVM
, "Error: out of memory");
132 strncpy(name
, namep
, names
);
134 value
= (char *)ficlMalloc(values
+1);
136 ficlVmThrowError(pVM
, "Error: out of memory");
137 strncpy(value
, valuep
, values
);
138 value
[values
] = '\0';
140 setenv(name
, value
, overwrite
);
146 ficlGetenv(ficlVm
*pVM
)
152 FICL_STACK_CHECK(ficlVmGetDataStack(pVM
), 2, 2);
154 names
= ficlStackPopInteger(ficlVmGetDataStack(pVM
));
155 namep
= (char *)ficlStackPopPointer(ficlVmGetDataStack(pVM
));
157 name
= (char *)ficlMalloc(names
+1);
159 ficlVmThrowError(pVM
, "Error: out of memory");
160 strncpy(name
, namep
, names
);
163 value
= getenv(name
);
167 ficlStackPushPointer(ficlVmGetDataStack(pVM
), value
);
168 ficlStackPushInteger(ficlVmGetDataStack(pVM
), strlen(value
));
170 ficlStackPushInteger(ficlVmGetDataStack(pVM
), -1);
174 ficlUnsetenv(ficlVm
*pVM
)
180 FICL_STACK_CHECK(ficlVmGetDataStack(pVM
), 2, 0);
182 names
= ficlStackPopInteger(ficlVmGetDataStack(pVM
));
183 namep
= (char *)ficlStackPopPointer(ficlVmGetDataStack(pVM
));
185 name
= (char *)ficlMalloc(names
+1);
187 ficlVmThrowError(pVM
, "Error: out of memory");
188 strncpy(name
, namep
, names
);
196 ficlCopyin(ficlVm
*pVM
)
204 FICL_STACK_CHECK(ficlVmGetDataStack(pVM
), 3, 0);
207 len
= ficlStackPopInteger(ficlVmGetDataStack(pVM
));
208 dest
= ficlStackPopInteger(ficlVmGetDataStack(pVM
));
209 src
= ficlStackPopPointer(ficlVmGetDataStack(pVM
));
210 archsw
.arch_copyin(src
, dest
, len
);
212 (void) ficlStackPopInteger(ficlVmGetDataStack(pVM
));
213 (void) ficlStackPopInteger(ficlVmGetDataStack(pVM
));
214 (void) ficlStackPopPointer(ficlVmGetDataStack(pVM
));
219 ficlCopyout(ficlVm
*pVM
)
227 FICL_STACK_CHECK(ficlVmGetDataStack(pVM
), 3, 0);
230 len
= ficlStackPopInteger(ficlVmGetDataStack(pVM
));
231 dest
= ficlStackPopPointer(ficlVmGetDataStack(pVM
));
232 src
= ficlStackPopInteger(ficlVmGetDataStack(pVM
));
233 archsw
.arch_copyout(src
, dest
, len
);
235 (void) ficlStackPopInteger(ficlVmGetDataStack(pVM
));
236 (void) ficlStackPopPointer(ficlVmGetDataStack(pVM
));
237 (void) ficlStackPopInteger(ficlVmGetDataStack(pVM
));
242 ficlFindfile(ficlVm
*pVM
)
249 struct preloaded_file
*fp
;
251 FICL_STACK_CHECK(ficlVmGetDataStack(pVM
), 4, 1);
254 types
= ficlStackPopInteger(ficlVmGetDataStack(pVM
));
255 typep
= (char *)ficlStackPopPointer(ficlVmGetDataStack(pVM
));
256 names
= ficlStackPopInteger(ficlVmGetDataStack(pVM
));
257 namep
= (char *)ficlStackPopPointer(ficlVmGetDataStack(pVM
));
259 name
= (char *)ficlMalloc(names
+1);
261 ficlVmThrowError(pVM
, "Error: out of memory");
262 strncpy(name
, namep
, names
);
264 type
= (char *)ficlMalloc(types
+1);
266 ficlVmThrowError(pVM
, "Error: out of memory");
267 strncpy(type
, typep
, types
);
270 fp
= file_findfile(name
, type
);
272 (void) ficlStackPopInteger(ficlVmGetDataStack(pVM
));
273 (void) ficlStackPopPointer(ficlVmGetDataStack(pVM
));
274 (void) ficlStackPopInteger(ficlVmGetDataStack(pVM
));
275 (void) ficlStackPopPointer(ficlVmGetDataStack(pVM
));
279 ficlStackPushPointer(ficlVmGetDataStack(pVM
), fp
);
286 ficlPnpdevices(ficlVm
*pVM
)
288 static int pnp_devices_initted
= 0;
290 FICL_STACK_CHECK(ficlVmGetDataStack(pVM
), 0, 1);
292 if (!pnp_devices_initted
) {
293 STAILQ_INIT(&pnp_devices
);
294 pnp_devices_initted
= 1;
297 ficlStackPushPointer(ficlVmGetDataStack(pVM
), &pnp_devices
);
301 ficlPnphandlers(ficlVm
*pVM
)
303 FICL_STACK_CHECK(ficlVmGetDataStack(pVM
), 0, 1);
305 ficlStackPushPointer(ficlVmGetDataStack(pVM
), pnphandlers
);
309 #endif /* ifdef STAND */
312 ficlCcall(ficlVm
*pVM
)
314 int (*func
)(int, ...);
318 FICL_STACK_CHECK(ficlVmGetDataStack(pVM
), 2, 0);
320 func
= (int (*)(int, ...))ficlStackPopPointer(ficlVmGetDataStack(pVM
));
321 nparam
= ficlStackPopInteger(ficlVmGetDataStack(pVM
));
323 FICL_STACK_CHECK(ficlVmGetDataStack(pVM
), nparam
, 1);
325 for (i
= 0; i
< nparam
; i
++)
326 p
[i
] = ficlStackPopInteger(ficlVmGetDataStack(pVM
));
328 result
= func(p
[0], p
[1], p
[2], p
[3], p
[4], p
[5], p
[6], p
[7], p
[8],
331 ficlStackPushInteger(ficlVmGetDataStack(pVM
), result
);
335 ficlUuidFromString(ficlVm
*pVM
)
347 FICL_STACK_CHECK(ficlVmGetDataStack(pVM
), 2, 0);
349 uuid_size
= ficlStackPopInteger(ficlVmGetDataStack(pVM
));
350 uuid_ptr
= ficlStackPopPointer(ficlVmGetDataStack(pVM
));
352 uuid
= ficlMalloc(uuid_size
+ 1);
354 ficlVmThrowError(pVM
, "Error: out of memory");
355 (void) memcpy(uuid
, uuid_ptr
, uuid_size
);
356 uuid
[uuid_size
] = '\0';
358 u
= ficlMalloc(sizeof (*u
));
360 uuid_from_string(uuid
, u
, &status
);
362 if (status
!= uuid_s_ok
) {
367 status
= uuid_parse(uuid
, *u
);
374 ficlStackPushPointer(ficlVmGetDataStack(pVM
), u
);
378 ficlUuidToString(ficlVm
*pVM
)
386 FICL_STACK_CHECK(ficlVmGetDataStack(pVM
), 1, 0);
388 u
= ficlStackPopPointer(ficlVmGetDataStack(pVM
));
390 uuid_to_string(u
, &uuid
, &status
);
391 if (status
== uuid_s_ok
) {
392 ficlStackPushPointer(ficlVmGetDataStack(pVM
), uuid
);
393 ficlStackPushInteger(ficlVmGetDataStack(pVM
), strlen(uuid
));
396 uuid
= ficlMalloc(UUID_PRINTABLE_STRING_LENGTH
);
398 uuid_unparse(*u
, uuid
);
399 ficlStackPushPointer(ficlVmGetDataStack(pVM
), uuid
);
400 ficlStackPushInteger(ficlVmGetDataStack(pVM
), strlen(uuid
));
403 ficlStackPushInteger(ficlVmGetDataStack(pVM
), -1);
407 * f i c l E x e c F D
408 * reads in text from file fd and passes it to ficlExec()
409 * returns FICL_VM_STATUS_OUT_OF_TEXT on success or the ficlExec() error
414 ficlExecFD(ficlVm
*pVM
, int fd
)
417 int nLine
= 0, rval
= FICL_VM_STATUS_OUT_OF_TEXT
;
423 pVM
->sourceId
.i
= fd
+1; /* in loader we can get 0, there is no stdin */
425 /* feed each line to ficlExec */
430 while ((status
= read(fd
, &ch
, 1)) > 0 && ch
!= '\n')
441 FICL_STRING_SET_POINTER(s
, cp
);
442 FICL_STRING_SET_LENGTH(s
, i
);
444 rval
= ficlVmExecuteString(pVM
, s
);
445 if (rval
!= FICL_VM_STATUS_QUIT
&&
446 rval
!= FICL_VM_STATUS_USER_EXIT
&&
447 rval
!= FICL_VM_STATUS_OUT_OF_TEXT
) {
449 (void) ficlVmEvaluate(pVM
, "");
456 * Pass an empty line with SOURCE-ID == -1 to flush
457 * any pending REFILLs (as required by FILE wordset)
459 (void) ficlVmEvaluate(pVM
, "");
461 if (rval
== FICL_VM_STATUS_USER_EXIT
)
462 ficlVmThrow(pVM
, FICL_VM_STATUS_USER_EXIT
);
467 static void displayCellNoPad(ficlVm
*pVM
)
470 FICL_STACK_CHECK(ficlVmGetDataStack(pVM
), 1, 0);
472 c
= ficlStackPop(ficlVmGetDataStack(pVM
));
473 ficlLtoa((c
).i
, pVM
->pad
, pVM
->base
);
474 ficlVmTextOut(pVM
, pVM
->pad
);
478 * isdir? - Return whether an fd corresponds to a directory.
480 * isdir? ( fd -- bool )
483 isdirQuestion(ficlVm
*pVM
)
489 FICL_STACK_CHECK(ficlVmGetDataStack(pVM
), 1, 1);
491 fd
= ficlStackPopInteger(ficlVmGetDataStack(pVM
));
496 if (fstat(fd
, &sb
) < 0)
498 if (!S_ISDIR(sb
.st_mode
))
502 ficlStackPushInteger(ficlVmGetDataStack(pVM
), flag
);
506 * fopen - open a file and return new fd on stack.
508 * fopen ( ptr count mode -- fd )
510 extern char *get_dev(const char *);
521 FICL_STACK_CHECK(ficlVmGetDataStack(pVM
), 3, 1);
523 mode
= ficlStackPopInteger(ficlVmGetDataStack(pVM
)); /* get mode */
524 count
= ficlStackPopInteger(ficlVmGetDataStack(pVM
)); /* get count */
525 ptr
= ficlStackPopPointer(ficlVmGetDataStack(pVM
)); /* get ptr */
527 if ((count
< 0) || (ptr
== NULL
)) {
528 ficlStackPushInteger(ficlVmGetDataStack(pVM
), -1);
532 /* ensure that the string is null terminated */
533 name
= (char *)malloc(count
+1);
534 bcopy(ptr
, name
, count
);
543 fd
= open(name
, mode
);
545 ficlStackPushInteger(ficlVmGetDataStack(pVM
), fd
);
549 * fclose - close a file who's fd is on stack.
557 FICL_STACK_CHECK(ficlVmGetDataStack(pVM
), 1, 0);
559 fd
= ficlStackPopInteger(ficlVmGetDataStack(pVM
)); /* get fd */
565 * fread - read file contents
566 * fread ( fd buf nbytes -- nread )
574 FICL_STACK_CHECK(ficlVmGetDataStack(pVM
), 3, 1);
576 len
= ficlStackPopInteger(ficlVmGetDataStack(pVM
));
577 buf
= ficlStackPopPointer(ficlVmGetDataStack(pVM
)); /* get buffer */
578 fd
= ficlStackPopInteger(ficlVmGetDataStack(pVM
)); /* get fd */
579 if (len
> 0 && buf
&& fd
!= -1)
580 ficlStackPushInteger(ficlVmGetDataStack(pVM
),
583 ficlStackPushInteger(ficlVmGetDataStack(pVM
), -1);
587 * fopendir - open directory
589 * fopendir ( addr len -- ptr TRUE | FALSE )
591 static void pfopendir(ficlVm
*pVM
)
602 ficlInteger flag
= FICL_FALSE
;
604 FICL_STACK_CHECK(ficlVmGetDataStack(pVM
), 2, 1);
606 count
= ficlStackPopInteger(ficlVmGetDataStack(pVM
));
607 ptr
= ficlStackPopPointer(ficlVmGetDataStack(pVM
)); /* get ptr */
609 if ((count
< 0) || (ptr
== NULL
)) {
610 ficlStackPushInteger(ficlVmGetDataStack(pVM
), -1);
613 /* ensure that the string is null terminated */
614 name
= (char *)malloc(count
+1);
615 bcopy(ptr
, name
, count
);
622 fd
= open(name
, O_RDONLY
);
627 if (fstat(fd
, &sb
) < 0)
629 if (!S_ISDIR(sb
.st_mode
))
632 ficlStackPushInteger(ficlVmGetDataStack(pVM
), fd
);
633 ficlStackPushInteger(ficlVmGetDataStack(pVM
), flag
);
640 ficlStackPushInteger(ficlVmGetDataStack(pVM
), flag
);
646 ficlStackPushInteger(ficlVmGetDataStack(pVM
), flag
);
651 ficlStackPushPointer(ficlVmGetDataStack(pVM
), dir
);
652 ficlStackPushInteger(ficlVmGetDataStack(pVM
), flag
);
657 * freaddir - read directory contents
658 * freaddir ( fd -- ptr len TRUE | FALSE )
661 pfreaddir(ficlVm
*pVM
)
664 static DIR *dir
= NULL
;
668 struct dirent
*d
= NULL
;
670 FICL_STACK_CHECK(ficlVmGetDataStack(pVM
), 1, 3);
672 * libstand readdir does not always return . nor .. so filter
673 * them out to have consistent behaviour.
676 dir
= ficlStackPopPointer(ficlVmGetDataStack(pVM
));
680 if (d
!= NULL
&& strcmp(d
->d_name
, ".") == 0)
682 if (d
!= NULL
&& strcmp(d
->d_name
, "..") == 0)
687 fd
= ficlStackPopInteger(ficlVmGetDataStack(pVM
));
691 if (d
!= NULL
&& strcmp(d
->d_name
, ".") == 0)
693 if (d
!= NULL
&& strcmp(d
->d_name
, "..") == 0)
699 ficlStackPushPointer(ficlVmGetDataStack(pVM
), d
->d_name
);
700 ficlStackPushInteger(ficlVmGetDataStack(pVM
),
702 ficlStackPushInteger(ficlVmGetDataStack(pVM
), FICL_TRUE
);
704 ficlStackPushInteger(ficlVmGetDataStack(pVM
), FICL_FALSE
);
709 * fclosedir - close a dir on stack.
711 * fclosedir ( fd -- )
714 pfclosedir(ficlVm
*pVM
)
722 FICL_STACK_CHECK(ficlVmGetDataStack(pVM
), 1, 0);
725 dir
= ficlStackPopPointer(ficlVmGetDataStack(pVM
)); /* get dir */
729 fd
= ficlStackPopInteger(ficlVmGetDataStack(pVM
)); /* get fd */
736 * fload - interpret file contents
740 static void pfload(ficlVm
*pVM
)
744 FICL_STACK_CHECK(ficlVmGetDataStack(pVM
), 1, 0);
746 fd
= ficlStackPopInteger(ficlVmGetDataStack(pVM
)); /* get fd */
752 * fwrite - write file contents
754 * fwrite ( fd buf nbytes -- nwritten )
762 FICL_STACK_CHECK(ficlVmGetDataStack(pVM
), 3, 1);
764 len
= ficlStackPopInteger(ficlVmGetDataStack(pVM
)); /* bytes to read */
765 buf
= ficlStackPopPointer(ficlVmGetDataStack(pVM
)); /* get buffer */
766 fd
= ficlStackPopInteger(ficlVmGetDataStack(pVM
)); /* get fd */
767 if (len
> 0 && buf
&& fd
!= -1)
768 ficlStackPushInteger(ficlVmGetDataStack(pVM
),
769 write(fd
, buf
, len
));
771 ficlStackPushInteger(ficlVmGetDataStack(pVM
), -1);
775 * fseek - seek to a new position in a file
777 * fseek ( fd ofs whence -- pos )
784 FICL_STACK_CHECK(ficlVmGetDataStack(pVM
), 3, 1);
786 whence
= ficlStackPopInteger(ficlVmGetDataStack(pVM
));
787 pos
= ficlStackPopInteger(ficlVmGetDataStack(pVM
));
788 fd
= ficlStackPopInteger(ficlVmGetDataStack(pVM
));
789 ficlStackPushInteger(ficlVmGetDataStack(pVM
), lseek(fd
, pos
, whence
));
793 * key - get a character from stdin
800 FICL_STACK_CHECK(ficlVmGetDataStack(pVM
), 0, 1);
802 ficlStackPushInteger(ficlVmGetDataStack(pVM
), getchar());
806 * key? - check for a character from stdin (FACILITY)
810 keyQuestion(ficlVm
*pVM
)
818 FICL_STACK_CHECK(ficlVmGetDataStack(pVM
), 0, 1);
821 tcgetattr(STDIN_FILENO
, &oldt
);
823 newt
.c_lflag
&= ~(ICANON
| ECHO
);
825 newt
.c_cc
[VTIME
] = 0;
826 tcsetattr(STDIN_FILENO
, TCSANOW
, &newt
);
828 tcsetattr(STDIN_FILENO
, TCSANOW
, &oldt
);
831 (void) ungetc(ch
, stdin
);
833 ficlStackPushInteger(ficlVmGetDataStack(pVM
),
834 ch
!= -1? FICL_TRUE
: FICL_FALSE
);
836 ficlStackPushInteger(ficlVmGetDataStack(pVM
),
837 ischar()? FICL_TRUE
: FICL_FALSE
);
842 * seconds - gives number of seconds since beginning of time
844 * beginning of time is defined as:
846 * BTX - number of seconds since midnight
847 * FreeBSD - number of seconds since Jan 1 1970
852 pseconds(ficlVm
*pVM
)
854 FICL_STACK_CHECK(ficlVmGetDataStack(pVM
), 0, 1);
856 ficlStackPushUnsigned(ficlVmGetDataStack(pVM
),
857 (ficlUnsigned
) time(NULL
));
861 * ms - wait at least that many milliseconds (FACILITY)
867 FICL_STACK_CHECK(ficlVmGetDataStack(pVM
), 1, 0);
870 usleep(ficlStackPopUnsigned(ficlVmGetDataStack(pVM
)) * 1000);
872 delay(ficlStackPopUnsigned(ficlVmGetDataStack(pVM
)) * 1000);
877 * fkey - get a character from a file
878 * fkey ( file -- char )
886 FICL_STACK_CHECK(ficlVmGetDataStack(pVM
), 1, 1);
888 fd
= ficlStackPopInteger(ficlVmGetDataStack(pVM
));
889 i
= read(fd
, &ch
, 1);
890 ficlStackPushInteger(ficlVmGetDataStack(pVM
), i
> 0 ? ch
: -1);
898 * outb ( port# c -- )
899 * Store a byte to I/O port number port#
902 ficlOutb(ficlVm
*pVM
)
907 port
= ficlStackPopUnsigned(ficlVmGetDataStack(pVM
));
908 c
= ficlStackPopInteger(ficlVmGetDataStack(pVM
));
914 * Fetch a byte from I/O port number port#
922 port
= ficlStackPopUnsigned(ficlVmGetDataStack(pVM
));
924 ficlStackPushInteger(ficlVmGetDataStack(pVM
), c
);
928 * pcibios-device-count (devid -- count)
930 * Returns the PCI BIOS' count of how many devices matching devid are
931 * in the system. devid is the 32-bit vendor + device.
934 ficlPciBiosCountDevices(ficlVm
*pVM
)
939 devid
= ficlStackPopInteger(ficlVmGetDataStack(pVM
));
941 i
= biospci_count_device_type(devid
);
943 ficlStackPushInteger(ficlVmGetDataStack(pVM
), i
);
947 * pcibios-write-config (locator offset width value -- )
949 * Writes the specified config register.
950 * Locator is bus << 8 | device << 3 | fuction
951 * offset is the pci config register
952 * width is 0 for byte, 1 for word, 2 for dword
953 * value is the value to write
956 ficlPciBiosWriteConfig(ficlVm
*pVM
)
958 uint32_t value
, width
, offset
, locator
;
960 value
= ficlStackPopInteger(ficlVmGetDataStack(pVM
));
961 width
= ficlStackPopInteger(ficlVmGetDataStack(pVM
));
962 offset
= ficlStackPopInteger(ficlVmGetDataStack(pVM
));
963 locator
= ficlStackPopInteger(ficlVmGetDataStack(pVM
));
965 biospci_write_config(locator
, offset
, width
, value
);
969 * pcibios-read-config (locator offset width -- value)
971 * Reads the specified config register.
972 * Locator is bus << 8 | device << 3 | fuction
973 * offset is the pci config register
974 * width is 0 for byte, 1 for word, 2 for dword
975 * value is the value to read from the register
978 ficlPciBiosReadConfig(ficlVm
*pVM
)
980 uint32_t value
, width
, offset
, locator
;
982 width
= ficlStackPopInteger(ficlVmGetDataStack(pVM
));
983 offset
= ficlStackPopInteger(ficlVmGetDataStack(pVM
));
984 locator
= ficlStackPopInteger(ficlVmGetDataStack(pVM
));
986 biospci_read_config(locator
, offset
, width
, &value
);
988 ficlStackPushInteger(ficlVmGetDataStack(pVM
), value
);
992 * pcibios-find-devclass (class index -- locator)
994 * Finds the index'th instance of class in the pci tree.
995 * must be an exact match.
996 * class is the class to search for.
997 * index 0..N (set to 0, increment until error)
999 * Locator is bus << 8 | device << 3 | fuction (or -1 on error)
1002 ficlPciBiosFindDevclass(ficlVm
*pVM
)
1004 uint32_t index
, class, locator
;
1006 index
= ficlStackPopInteger(ficlVmGetDataStack(pVM
));
1007 class = ficlStackPopInteger(ficlVmGetDataStack(pVM
));
1009 if (biospci_find_devclass(class, index
, &locator
))
1010 locator
= 0xffffffff;
1012 ficlStackPushInteger(ficlVmGetDataStack(pVM
), locator
);
1016 * pcibios-find-device(devid index -- locator)
1018 * Finds the index'th instance of devid in the pci tree.
1019 * must be an exact match.
1020 * class is the class to search for.
1021 * index 0..N (set to 0, increment until error)
1023 * Locator is bus << 8 | device << 3 | fuction (or -1 on error)
1026 ficlPciBiosFindDevice(ficlVm
*pVM
)
1028 uint32_t index
, devid
, locator
;
1030 index
= ficlStackPopInteger(ficlVmGetDataStack(pVM
));
1031 devid
= ficlStackPopInteger(ficlVmGetDataStack(pVM
));
1033 if (biospci_find_device(devid
, index
, &locator
))
1034 locator
= 0xffffffff;
1036 ficlStackPushInteger(ficlVmGetDataStack(pVM
), locator
);
1040 * pcibios-find-device(bus device function -- locator)
1042 * converts bus, device, function to locator.
1044 * Locator is bus << 8 | device << 3 | fuction
1047 ficlPciBiosLocator(ficlVm
*pVM
)
1049 uint32_t bus
, device
, function
, locator
;
1051 function
= ficlStackPopInteger(ficlVmGetDataStack(pVM
));
1052 device
= ficlStackPopInteger(ficlVmGetDataStack(pVM
));
1053 bus
= ficlStackPopInteger(ficlVmGetDataStack(pVM
));
1055 locator
= biospci_locator(bus
, device
, function
);
1057 ficlStackPushInteger(ficlVmGetDataStack(pVM
), locator
);
1063 * Retrieves free space remaining on the dictionary
1066 freeHeap(ficlVm
*pVM
)
1068 ficlStackPushInteger(ficlVmGetDataStack(pVM
),
1069 ficlDictionaryCellsAvailable(ficlVmGetDictionary(pVM
)));
1073 * f i c l C o m p i l e P l a t f o r m
1074 * Build FreeBSD platform extensions into the system dictionary
1077 ficlSystemCompilePlatform(ficlSystem
*pSys
)
1079 ficlDictionary
*dp
= ficlSystemGetDictionary(pSys
);
1080 ficlDictionary
*env
= ficlSystemGetEnvironment(pSys
);
1082 FICL_SYSTEM_ASSERT(pSys
, dp
);
1083 FICL_SYSTEM_ASSERT(pSys
, env
);
1085 ficlDictionarySetPrimitive(dp
, ".#", displayCellNoPad
,
1087 ficlDictionarySetPrimitive(dp
, "isdir?", isdirQuestion
,
1089 ficlDictionarySetPrimitive(dp
, "fopen", pfopen
, FICL_WORD_DEFAULT
);
1090 ficlDictionarySetPrimitive(dp
, "fclose", pfclose
, FICL_WORD_DEFAULT
);
1091 ficlDictionarySetPrimitive(dp
, "fread", pfread
, FICL_WORD_DEFAULT
);
1092 ficlDictionarySetPrimitive(dp
, "fopendir", pfopendir
,
1094 ficlDictionarySetPrimitive(dp
, "freaddir", pfreaddir
,
1096 ficlDictionarySetPrimitive(dp
, "fclosedir", pfclosedir
,
1098 ficlDictionarySetPrimitive(dp
, "fload", pfload
, FICL_WORD_DEFAULT
);
1099 ficlDictionarySetPrimitive(dp
, "fkey", fkey
, FICL_WORD_DEFAULT
);
1100 ficlDictionarySetPrimitive(dp
, "fseek", pfseek
, FICL_WORD_DEFAULT
);
1101 ficlDictionarySetPrimitive(dp
, "fwrite", pfwrite
, FICL_WORD_DEFAULT
);
1102 ficlDictionarySetPrimitive(dp
, "key", key
, FICL_WORD_DEFAULT
);
1103 ficlDictionarySetPrimitive(dp
, "key?", keyQuestion
, FICL_WORD_DEFAULT
);
1104 ficlDictionarySetPrimitive(dp
, "ms", ms
, FICL_WORD_DEFAULT
);
1105 ficlDictionarySetPrimitive(dp
, "seconds", pseconds
, FICL_WORD_DEFAULT
);
1106 ficlDictionarySetPrimitive(dp
, "heap?", freeHeap
, FICL_WORD_DEFAULT
);
1108 ficlDictionarySetPrimitive(dp
, "setenv", ficlSetenv
, FICL_WORD_DEFAULT
);
1109 ficlDictionarySetPrimitive(dp
, "setenv?", ficlSetenvq
,
1111 ficlDictionarySetPrimitive(dp
, "getenv", ficlGetenv
, FICL_WORD_DEFAULT
);
1112 ficlDictionarySetPrimitive(dp
, "unsetenv", ficlUnsetenv
,
1114 ficlDictionarySetPrimitive(dp
, "copyin", ficlCopyin
, FICL_WORD_DEFAULT
);
1115 ficlDictionarySetPrimitive(dp
, "copyout", ficlCopyout
,
1117 ficlDictionarySetPrimitive(dp
, "findfile", ficlFindfile
,
1119 ficlDictionarySetPrimitive(dp
, "ccall", ficlCcall
, FICL_WORD_DEFAULT
);
1120 ficlDictionarySetPrimitive(dp
, "uuid-from-string", ficlUuidFromString
,
1122 ficlDictionarySetPrimitive(dp
, "uuid-to-string", ficlUuidToString
,
1126 ficlDictionarySetPrimitive(dp
, "outb", ficlOutb
, FICL_WORD_DEFAULT
);
1127 ficlDictionarySetPrimitive(dp
, "inb", ficlInb
, FICL_WORD_DEFAULT
);
1130 ficlDictionarySetPrimitive(dp
, "pnpdevices", ficlPnpdevices
,
1132 ficlDictionarySetPrimitive(dp
, "pnphandlers", ficlPnphandlers
,
1136 ficlDictionarySetPrimitive(dp
, "pcibios-device-count",
1137 ficlPciBiosCountDevices
, FICL_WORD_DEFAULT
);
1138 ficlDictionarySetPrimitive(dp
, "pcibios-read-config",
1139 ficlPciBiosReadConfig
, FICL_WORD_DEFAULT
);
1140 ficlDictionarySetPrimitive(dp
, "pcibios-write-config",
1141 ficlPciBiosWriteConfig
, FICL_WORD_DEFAULT
);
1142 ficlDictionarySetPrimitive(dp
, "pcibios-find-devclass",
1143 ficlPciBiosFindDevclass
, FICL_WORD_DEFAULT
);
1144 ficlDictionarySetPrimitive(dp
, "pcibios-find-device",
1145 ficlPciBiosFindDevice
, FICL_WORD_DEFAULT
);
1146 ficlDictionarySetPrimitive(dp
, "pcibios-locator", ficlPciBiosLocator
,
1151 #if defined(__i386__) || defined(__amd64__)
1152 ficlDictionarySetConstant(env
, "arch-i386", FICL_TRUE
);
1153 ficlDictionarySetConstant(env
, "arch-sparc", FICL_FALSE
);
1156 ficlDictionarySetConstant(env
, "arch-i386", FICL_FALSE
);
1157 ficlDictionarySetConstant(env
, "arch-sparc", FICL_TRUE
);