aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFeng Tang <feng.tang@intel.com>2010-06-30 14:11:21 +0800
committerFeng Tang <feng.tang@intel.com>2010-07-20 11:10:04 +0800
commitf83c57717377fa74c89d27e72bf138d4265731fb (patch)
tree2f33e01a4fa654e8c052af6f35dfde4c49912b32
parent387d33fbfcdbe2d039ba719d487359b205181873 (diff)
downloadsyslinux-f83c57717377fa74c89d27e72bf138d4265731fb.tar.gz
syslinux-f83c57717377fa74c89d27e72bf138d4265731fb.tar.xz
syslinux-f83c57717377fa74c89d27e72bf138d4265731fb.zip
elflink: add several files to com32/elflink/modules
They are meminfo/pcitest/dir/vesainfo/cpuid/cpuidtest. But not all of their .c32 works. One note from vesainfo.c32 is, we need change all cs_bounce usage to lmalloc/free
-rwxr-xr-xbuild.sh1
-rw-r--r--com32/elflink/modules/MCONFIG2
-rw-r--r--com32/elflink/modules/Makefile21
-rw-r--r--com32/elflink/modules/cpuid.c63
-rw-r--r--com32/elflink/modules/cpuidtest.c140
-rw-r--r--com32/elflink/modules/dir.c178
-rw-r--r--com32/elflink/modules/disk.c60
-rw-r--r--com32/elflink/modules/meminfo.c126
-rw-r--r--com32/elflink/modules/pcitest.c156
-rw-r--r--com32/elflink/modules/vesainfo.c93
10 files changed, 838 insertions, 2 deletions
diff --git a/build.sh b/build.sh
index bcd17eb0..1f25d8dd 100755
--- a/build.sh
+++ b/build.sh
@@ -2,5 +2,6 @@ make -j 4 || exit 1
cp extlinux/extlinux /home/feng/test/syslinux/
cp com32/elflink/modules/*.c32 /home/feng/test/syslinux/cd/
cp memdisk/memdisk /home/feng/test/syslinux/cd/
+cp modules.dep /home/feng/test/syslinux/cd/
sudo extlinux/extlinux -i /home/feng/test/syslinux/cd/
qemu -hda /home/feng/test/syslinux/test.img
diff --git a/com32/elflink/modules/MCONFIG b/com32/elflink/modules/MCONFIG
index 7157e1b3..0049128e 100644
--- a/com32/elflink/modules/MCONFIG
+++ b/com32/elflink/modules/MCONFIG
@@ -36,7 +36,7 @@ com32 = $(topdir)/com32
CFLAGS = $(GCCOPT) -W -Wall -march=i386 \
-fomit-frame-pointer -D__COM32__ -DDYNAMIC_MODULE \
-nostdinc -iwithprefix include \
- -I$(com32)/libutil/include -I$(com32)/include
+ -I$(com32)/libutil/include -I$(com32)/include -I$(com32)/gplinclude
SFLAGS = $(GCCOPT) -D__COM32__ -march=i386
LDFLAGS = -m elf_i386 -shared --hash-style=gnu -T $(com32)/lib/elf32.ld
LIBGCC := $(shell $(CC) $(GCCOPT) --print-libgcc)
diff --git a/com32/elflink/modules/Makefile b/com32/elflink/modules/Makefile
index ee16f8bc..9c9cb972 100644
--- a/com32/elflink/modules/Makefile
+++ b/com32/elflink/modules/Makefile
@@ -14,7 +14,8 @@ topdir = ../../..
include MCONFIG
MODULES = hello.c32 sort.c32 mytest.c32 menumain.c32 printmsg.c32 background.c32 passwd.c32 sha1hash.c32 \
- unbase64.c32 sha512crypt.c32 md5.c32 crypt-md5.c32 sha256crypt.c32 get_key.c32 ansiraw.c32 test.c32 menu.c32 drain.c32
+ unbase64.c32 sha512crypt.c32 md5.c32 crypt-md5.c32 sha256crypt.c32 get_key.c32 ansiraw.c32 test.c32 \
+ meminfo.c32 menu.c32 drain.c32 dir.c32 pcitest.c32 vesainfo.c32 cpuid.c32 cpuidtest.c32
TESTFILES =
@@ -74,6 +75,24 @@ get_key.c32 : get_key.o
ansiraw.c32 : ansiraw.o
$(LD) $(LDFLAGS) -o $@ $^
+meminfo.c32 : meminfo.o
+ $(LD) $(LDFLAGS) -o $@ $^
+
+pcitest.c32 : pcitest.o
+ $(LD) $(LDFLAGS) -o $@ $^
+
+dir.c32 : dir.o
+ $(LD) $(LDFLAGS) -o $@ $^
+
+vesainfo.c32 : vesainfo.o
+ $(LD) $(LDFLAGS) -o $@ $^
+
+cpuid.c32 : cpuid.o
+ $(LD) $(LDFLAGS) -o $@ $^
+
+cpuidtest.c32 : cpuidtest.o
+ $(LD) $(LDFLAGS) -o $@ $^
+
tidy dist:
rm -f *.o *.lo *.a *.lst .*.d
diff --git a/com32/elflink/modules/cpuid.c b/com32/elflink/modules/cpuid.c
new file mode 100644
index 00000000..eac59d54
--- /dev/null
+++ b/com32/elflink/modules/cpuid.c
@@ -0,0 +1,63 @@
+/* ----------------------------------------------------------------------- *
+ *
+ * Copyright 2010 Intel Corporation; author: H. Peter Anvin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston MA 02110-1301, USA; either version 2 of the License, or
+ * (at your option) any later version; incorporated herein by reference.
+ *
+ * ----------------------------------------------------------------------- */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/cpu.h>
+#include <console.h>
+#include <com32.h>
+
+#include <sys/module.h>
+
+static void dump_reg(const char *name, uint32_t val)
+{
+ int i;
+
+ printf("%-3s : %10u 0x%08x ", name, val, val);
+
+ for (i = 3; i >= 0; i--) {
+ uint8_t c = val >> (i*8);
+ putchar((c >= ' ' && c <= '~') ? c : '.');
+ }
+ putchar('\n');
+}
+
+static int cpuid_main(int argc, char *argv[])
+{
+ uint32_t leaf, counter;
+ uint32_t eax, ebx, ecx, edx;
+
+ if (argc < 2 || argc > 4) {
+ printf("Usage: %s leaf [counter]\n", argv[0]);
+ exit(1);
+ }
+
+ mp("argv[1] = %s, argv[2] = %s", argv[0], argv[1]);
+
+ leaf = strtoul(argv[1], NULL, 0);
+ counter = (argc > 2) ? strtoul(argv[2], NULL, 0) : 0;
+
+ if (!cpu_has_eflag(EFLAGS_ID)) {
+ printf("The CPUID instruction is not supported\n");
+ exit(1);
+ }
+
+ cpuid_count(leaf, counter, &eax, &ebx, &ecx, &edx);
+
+ dump_reg("eax", eax);
+ dump_reg("ebx", ebx);
+ dump_reg("ecx", ecx);
+ dump_reg("edx", edx);
+
+ return 0;
+}
+MODULE_MAIN(cpuid_main);
diff --git a/com32/elflink/modules/cpuidtest.c b/com32/elflink/modules/cpuidtest.c
new file mode 100644
index 00000000..942955fe
--- /dev/null
+++ b/com32/elflink/modules/cpuidtest.c
@@ -0,0 +1,140 @@
+/* ----------------------------------------------------------------------- *
+ *
+ * Copyright 2006 Erwan Velu - All Rights Reserved
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom
+ * the Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall
+ * be included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * -----------------------------------------------------------------------
+*/
+
+/*
+ * cpuidtest.c
+ *
+ * A CPUID demo program using libcom32
+ */
+
+#include <string.h>
+#include <stdio.h>
+#include <console.h>
+#include "cpuid.h"
+
+#include <sys/module.h>
+
+char display_line;
+
+static int cpuidtest_main(void)
+{
+ s_cpu cpu;
+
+ for (;;) {
+ detect_cpu(&cpu);
+ printf("Vendor = %s\n", cpu.vendor);
+ printf("Model = %s\n", cpu.model);
+ printf("Vendor ID = %d\n", cpu.vendor_id);
+ printf("Family = %d\n", cpu.family);
+ printf("Model ID = %d\n", cpu.model_id);
+ printf("Stepping = %d\n", cpu.stepping);
+ printf("Flags = ");
+ if (cpu.flags.fpu)
+ printf("fpu ");
+ if (cpu.flags.vme)
+ printf("vme ");
+ if (cpu.flags.de)
+ printf("de ");
+ if (cpu.flags.pse)
+ printf("pse ");
+ if (cpu.flags.tsc)
+ printf("tsc ");
+ if (cpu.flags.msr)
+ printf("msr ");
+ if (cpu.flags.pae)
+ printf("pae ");
+ if (cpu.flags.mce)
+ printf("mce ");
+ if (cpu.flags.cx8)
+ printf("cx8 ");
+ if (cpu.flags.apic)
+ printf("apic ");
+ if (cpu.flags.sep)
+ printf("sep ");
+ if (cpu.flags.mtrr)
+ printf("mtrr ");
+ if (cpu.flags.pge)
+ printf("pge ");
+ if (cpu.flags.mca)
+ printf("mca ");
+ if (cpu.flags.cmov)
+ printf("cmov ");
+ if (cpu.flags.pat)
+ printf("pat ");
+ if (cpu.flags.pse_36)
+ printf("pse_36 ");
+ if (cpu.flags.psn)
+ printf("psn ");
+ if (cpu.flags.clflsh)
+ printf("clflsh ");
+ if (cpu.flags.dts)
+ printf("dts ");
+ if (cpu.flags.acpi)
+ printf("acpi ");
+ if (cpu.flags.mmx)
+ printf("mmx ");
+ if (cpu.flags.sse)
+ printf("sse ");
+ if (cpu.flags.sse2)
+ printf("sse2 ");
+ if (cpu.flags.ss)
+ printf("ss ");
+ if (cpu.flags.htt)
+ printf("ht ");
+ if (cpu.flags.acc)
+ printf("acc ");
+ if (cpu.flags.syscall)
+ printf("syscall ");
+ if (cpu.flags.mp)
+ printf("mp ");
+ if (cpu.flags.nx)
+ printf("nx ");
+ if (cpu.flags.mmxext)
+ printf("mmxext ");
+ if (cpu.flags.lm)
+ printf("lm ");
+ if (cpu.flags.nowext)
+ printf("3dnowext ");
+ if (cpu.flags.now)
+ printf("3dnow! ");
+ if (cpu.flags.vmx)
+ printf("vmx ");
+ if (cpu.flags.svm)
+ printf("svm ");
+ printf("\n");
+ printf("SMP = ");
+ if (cpu.flags.smp)
+ printf("yes\n");
+ else
+ printf("no\n");
+ break;
+ }
+
+ return 0;
+}
+MODULE_MAIN(cpuidtest_main);
diff --git a/com32/elflink/modules/dir.c b/com32/elflink/modules/dir.c
new file mode 100644
index 00000000..17e78801
--- /dev/null
+++ b/com32/elflink/modules/dir.c
@@ -0,0 +1,178 @@
+/*
+ * Display directory contents
+ */
+#include <stdlib.h>
+#include <stdio.h>
+#include <console.h>
+#include <string.h>
+#include <com32.h>
+#include <dirent.h>
+#include <minmax.h>
+#include <unistd.h>
+#include <getkey.h>
+
+#include <sys/module.h>
+
+static int rows, cols; /* Screen parameters */
+
+#define DIR_CHUNK 1024
+
+static const char *type_str(int type)
+{
+ switch (type) {
+ case DT_FIFO:
+ return "[fif]";
+ case DT_CHR:
+ return "[chr]";
+ case DT_DIR:
+ return "[dir]";
+ case DT_BLK:
+ return "[blk]";
+ case DT_UNKNOWN:
+ case DT_REG:
+ return "";
+ case DT_LNK:
+ return "[lnk]";
+ case DT_SOCK:
+ return "[sck]";
+ case DT_WHT:
+ return "[wht]";
+ default:
+ return "[???]";
+ }
+}
+
+static void free_dirents(struct dirent **dex, size_t n_de)
+{
+ size_t i;
+
+ for (i = 0; i < n_de; i++)
+ free(dex[i]);
+
+ free(dex);
+}
+
+static int compare_dirent(const void *p_de1, const void *p_de2)
+{
+ const struct dirent *de1 = *(const struct dirent **)p_de1;
+ const struct dirent *de2 = *(const struct dirent **)p_de2;
+ int ndir1, ndir2;
+
+ ndir1 = de1->d_type != DT_DIR;
+ ndir2 = de2->d_type != DT_DIR;
+
+ if (ndir1 != ndir2)
+ return ndir1 - ndir2;
+
+ return strcmp(de1->d_name, de2->d_name);
+}
+
+static int display_directory(const char *dirname)
+{
+ DIR *dir;
+ struct dirent *de;
+ struct dirent **dex = NULL;
+ size_t n_dex = 0, n_de = 0;
+ size_t i, j, k;
+ size_t nrows, ncols, perpage;
+ size_t endpage;
+ int maxlen = 0;
+ int pos, tpos, colwidth;
+
+ dir = opendir(dirname);
+ if (!dir) {
+ printf("Unable to read directory: %s\n", dirname);
+ return -1;
+ }
+
+ while ((de = readdir(dir)) != NULL) {
+ struct dirent *nde;
+
+ if (n_de >= n_dex) {
+ struct dirent **ndex;
+
+ ndex = realloc(dex, (n_dex + DIR_CHUNK) * sizeof *dex);
+ if (!ndex)
+ goto nomem;
+
+ dex = ndex;
+ n_dex += DIR_CHUNK;
+ }
+
+ nde = malloc(de->d_reclen);
+ if (!nde)
+ goto nomem;
+
+ memcpy(nde, de, de->d_reclen);
+ dex[n_de++] = nde;
+
+ maxlen = max(maxlen, de->d_reclen);
+ }
+
+ closedir(dir);
+
+ qsort(dex, n_de, sizeof *dex, compare_dirent);
+
+ maxlen -= offsetof(struct dirent, d_name) + 1;
+ ncols = (cols + 2)/(maxlen + 8);
+ ncols = min(ncols, n_de);
+ ncols = max(ncols, 1U);
+ colwidth = (cols + 2)/ncols;
+ perpage = ncols * (rows - 1);
+
+ for (i = 0; i < n_de; i += perpage) {
+ /* Rows on this page */
+ endpage = min(i+perpage, n_de);
+ nrows = ((endpage-i) + ncols - 1)/ncols;
+
+ for (j = 0; j < nrows; j++) {
+ pos = tpos = 0;
+ for (k = i+j; k < endpage; k += nrows) {
+ pos += printf("%*s%-5s %s",
+ (tpos - pos), "",
+ type_str(dex[k]->d_type),
+ dex[k]->d_name);
+ tpos += colwidth;
+ }
+ printf("\n");
+ }
+
+ if (endpage >= n_de)
+ break;
+
+ get_key(stdin, 0);
+ }
+
+ free_dirents(dex, n_de);
+ return 0;
+
+nomem:
+ closedir(dir);
+ printf("Out of memory error!\n");
+ free_dirents(dex, n_de);
+ return -1;
+}
+
+static int dir_main(int argc, char *argv[])
+{
+ int rv;
+
+ if (getscreensize(1, &rows, &cols)) {
+ /* Unknown screen size? */
+ rows = 24;
+ cols = 80;
+ }
+
+ if (argc < 2)
+ rv = display_directory(".");
+ else if (argc == 2)
+ rv = display_directory(argv[1]);
+ else {
+ printf("Usage: dir directory\n");
+ rv = 1;
+ }
+
+ return rv ? 1 : 0;
+}
+MODULE_MAIN(dir_main);
+
diff --git a/com32/elflink/modules/disk.c b/com32/elflink/modules/disk.c
new file mode 100644
index 00000000..3c864bd1
--- /dev/null
+++ b/com32/elflink/modules/disk.c
@@ -0,0 +1,60 @@
+/* ----------------------------------------------------------------------- *
+ *
+ * Copyright 2009 Pierre-Alexandre Meyer - All Rights Reserved
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston MA 02110-1301, USA; either version 2 of the License, or
+ * (at your option) any later version; incorporated herein by reference.
+ *
+ * ----------------------------------------------------------------------- */
+
+#include <stdio.h>
+#include <console.h>
+#include <stdlib.h>
+#include <string.h>
+#include <disk/geom.h>
+#include <disk/util.h>
+#include <disk/errno_disk.h>
+#include <disk/error.h>
+
+#include <sys/module.h>
+
+int disk_main(int argc, char *argv[])
+{
+ struct driveinfo drive;
+ struct driveinfo *d = &drive;
+
+ for (int disk = 0x80; disk < 0xff; disk++) {
+ memset(d, 0, sizeof(struct driveinfo));
+ d->disk = disk;
+ get_drive_parameters(d);
+
+ /* Do not print output when drive does not exists */
+ if (errno_disk == -1 || !d->cbios)
+ continue;
+
+ if (errno_disk) {
+ printf("reading disk");
+ continue;
+ }
+
+ printf("DISK 0x%X:\n", d->disk);
+ printf(" C/H/S: %d heads, %d cylinders\n",
+ d->legacy_max_head + 1, d->legacy_max_cylinder + 1);
+ printf(" %d sectors/track, %d drives\n",
+ d->legacy_sectors_per_track, d->legacy_max_drive);
+ printf(" EDD: ebios=%d, EDD version: %X\n",
+ d->ebios, d->edd_version);
+ printf(" %d heads, %d cylinders\n",
+ (int) d->edd_params.heads, (int) d->edd_params.cylinders);
+ printf(" %d sectors, %d bytes/sector, %d sectors/track\n",
+ (int) d->edd_params.sectors, (int) d->edd_params.bytes_per_sector,
+ (int) d->edd_params.sectors_per_track);
+ printf(" Host bus: %s, Interface type: %s\n\n",
+ d->edd_params.host_bus_type, d->edd_params.interface_type);
+ }
+ return 0;
+}
+MODULE_MAIN(disk_main);
diff --git a/com32/elflink/modules/meminfo.c b/com32/elflink/modules/meminfo.c
new file mode 100644
index 00000000..d5e3f380
--- /dev/null
+++ b/com32/elflink/modules/meminfo.c
@@ -0,0 +1,126 @@
+/* ----------------------------------------------------------------------- *
+ *
+ * Copyright 2008 H. Peter Anvin - All Rights Reserved
+ * Copyright 2009 Intel Corporation; author: H. Peter Anvin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston MA 02110-1301, USA; either version 2 of the License, or
+ * (at your option) any later version; incorporated herein by reference.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * meminfo.c
+ *
+ * Dump the memory map of the system
+ */
+#include <inttypes.h>
+#include <stdio.h>
+#include <string.h>
+#include <console.h>
+#include <com32.h>
+
+#include <sys/module.h>
+
+struct e820_data {
+ uint64_t base;
+ uint64_t len;
+ uint32_t type;
+ uint32_t extattr;
+} __attribute__ ((packed));
+
+static const char *const e820_types[] = {
+ "usable",
+ "reserved",
+ "ACPI reclaim",
+ "ACPI NVS",
+ "unusable",
+};
+
+static void dump_e820(void)
+{
+ com32sys_t ireg, oreg;
+ struct e820_data ed;
+ uint32_t type;
+
+ memset(&ireg, 0, sizeof ireg);
+
+ ireg.eax.w[0] = 0xe820;
+ ireg.edx.l = 0x534d4150;
+ ireg.ecx.l = sizeof(struct e820_data);
+ ireg.edi.w[0] = OFFS(__com32.cs_bounce);
+ ireg.es = SEG(__com32.cs_bounce);
+
+ memset(&ed, 0, sizeof ed);
+ ed.extattr = 1;
+
+ do {
+ memcpy(__com32.cs_bounce, &ed, sizeof ed);
+
+ __intcall(0x15, &ireg, &oreg);
+ if (oreg.eflags.l & EFLAGS_CF ||
+ oreg.eax.l != 0x534d4150 || oreg.ecx.l < 20)
+ break;
+
+ memcpy(&ed, __com32.cs_bounce, sizeof ed);
+
+ if (oreg.ecx.l >= 24) {
+ /* ebx base length end type */
+ printf("%8x %016llx %016llx %016llx %d [%x]",
+ ireg.ebx.l, ed.base, ed.len, ed.base + ed.len, ed.type,
+ ed.extattr);
+ } else {
+ /* ebx base length end */
+ printf("%8x %016llx %016llx %016llx %d [-]",
+ ireg.ebx.l, ed.base, ed.len, ed.base + ed.len, ed.type);
+ ed.extattr = 1;
+ }
+
+ type = ed.type - 1;
+ if (type < sizeof(e820_types) / sizeof(e820_types[0]))
+ printf(" %s", e820_types[type]);
+
+ putchar('\n');
+
+ ireg.ebx.l = oreg.ebx.l;
+ } while (ireg.ebx.l);
+}
+
+static void dump_legacy(void)
+{
+ com32sys_t ireg, oreg;
+ uint16_t dosram = *(uint16_t *) 0x413;
+ struct {
+ uint16_t offs, seg;
+ } *const ivt = (void *)0;
+
+ memset(&ireg, 0, sizeof ireg);
+
+ __intcall(0x12, &ireg, &oreg);
+
+ printf
+ ("INT 15h = %04x:%04x DOS RAM: %dK (0x%05x) INT 12h: %dK (0x%05x)\n",
+ ivt[0x15].seg, ivt[0x15].offs, dosram, dosram << 10, oreg.eax.w[0],
+ oreg.eax.w[0] << 10);
+
+ ireg.eax.b[1] = 0x88;
+ __intcall(0x15, &ireg, &oreg);
+
+ printf("INT 15 88: 0x%04x (%uK) ", oreg.eax.w[0], oreg.eax.w[0]);
+
+ ireg.eax.w[0] = 0xe801;
+ __intcall(0x15, &ireg, &oreg);
+
+ printf("INT 15 E801: 0x%04x (%uK) 0x%04x (%uK)\n",
+ oreg.ecx.w[0], oreg.ecx.w[0], oreg.edx.w[0], oreg.edx.w[0] << 6);
+}
+
+static int meminfo_main(void)
+{
+ dump_legacy();
+ dump_e820();
+ return 0;
+}
+MODULE_MAIN(meminfo_main);
diff --git a/com32/elflink/modules/pcitest.c b/com32/elflink/modules/pcitest.c
new file mode 100644
index 00000000..dcb80983
--- /dev/null
+++ b/com32/elflink/modules/pcitest.c
@@ -0,0 +1,156 @@
+/* ----------------------------------------------------------------------- *
+ *
+ * Copyright 2006 Erwan Velu - All Rights Reserved
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom
+ * the Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall
+ * be included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * -----------------------------------------------------------------------
+*/
+
+/*
+ * pcitest.c
+ *
+ */
+
+#include <inttypes.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <console.h>
+#include <com32.h>
+#include <sys/pci.h>
+#include <stdbool.h>
+
+#include <sys/module.h>
+
+#ifdef DEBUG
+# define dprintf printf
+#else
+# define dprintf(...) ((void)0)
+#endif
+
+char display_line = 0;
+#define moreprintf(...) \
+ do { \
+ display_line++; \
+ if (display_line == 24) { \
+ char tempbuf[10]; \
+ display_line=0; \
+ printf("Press Enter to continue\n"); \
+ fgets(tempbuf, sizeof tempbuf, stdin); \
+ } \
+ printf ( __VA_ARGS__); \
+ } while (0);
+
+void display_pci_devices(struct pci_domain *pci_domain)
+{
+ struct pci_device *pci_device;
+ char kernel_modules[LINUX_KERNEL_MODULE_SIZE *
+ MAX_KERNEL_MODULES_PER_PCI_DEVICE];
+
+ for_each_pci_func(pci_device, pci_domain) {
+
+ memset(kernel_modules, 0, sizeof kernel_modules);
+
+/* printf("PCI: found %d kernel modules for %04x:%04x[%04x:%04x]\n",
+ pci_device->dev_info->linux_kernel_module_count,
+ pci_device->vendor, pci_device->product,
+ pci_device->sub_vendor, pci_device->sub_product);
+*/
+ for (int i = 0; i < pci_device->dev_info->linux_kernel_module_count;
+ i++) {
+ if (i > 0) {
+ strncat(kernel_modules, " | ", 3);
+ }
+ strncat(kernel_modules,
+ pci_device->dev_info->linux_kernel_module[i],
+ LINUX_KERNEL_MODULE_SIZE - 1);
+ }
+
+ moreprintf("%04x:%04x[%04x:%04x]: %s\n",
+ pci_device->vendor, pci_device->product,
+ pci_device->sub_vendor, pci_device->sub_product,
+ pci_device->dev_info->class_name);
+
+ moreprintf(" Vendor Name : %s\n",
+ pci_device->dev_info->vendor_name);
+ moreprintf(" Product Name : %s\n",
+ pci_device->dev_info->product_name);
+ moreprintf(" PCI bus position : %02x:%02x.%01x\n", __pci_bus,
+ __pci_slot, __pci_func);
+ moreprintf(" Kernel modules : %s\n\n", kernel_modules);
+ }
+}
+
+static int pcitest_main(int argc, char *argv[])
+{
+ struct pci_domain *pci_domain;
+ int return_code = 0;
+ int nb_pci_devices = 0;
+
+ /* Scanning to detect pci buses and devices */
+ printf("PCI: Scanning PCI BUS\n");
+ pci_domain = pci_scan();
+ if (!pci_domain) {
+ printf("PCI: no devices found!\n");
+ return 1;
+ }
+
+ struct pci_device *pci_device;
+ for_each_pci_func(pci_device, pci_domain) {
+ nb_pci_devices++;
+ }
+
+ printf("PCI: %d PCI devices found\n", nb_pci_devices);
+
+ printf("PCI: Looking for device name\n");
+ /* Assigning product & vendor name for each device */
+ return_code = get_name_from_pci_ids(pci_domain, "pci.ids");
+ if (return_code == -ENOPCIIDS) {
+ printf("PCI: ERROR !\n");
+ printf("PCI: Unable to open pci.ids file in current directory.\n");
+ printf("PCI: PCI Device names can't be computed.\n");
+ }
+
+ printf("PCI: Resolving class names\n");
+ /* Assigning class name for each device */
+ return_code = get_class_name_from_pci_ids(pci_domain, "pci.ids");
+ if (return_code == -ENOPCIIDS) {
+ printf("PCI: ERROR !\n");
+ printf("PCI: Unable to open pci.ids file in current directory.\n");
+ printf("PCI: PCI class names can't be computed.\n");
+ }
+
+ printf("PCI: Looking for Kernel modules\n");
+ /* Detecting which kernel module should match each device */
+ return_code = get_module_name_from_pcimap(pci_domain, "modules.pcimap");
+ if (return_code == -ENOMODULESPCIMAP) {
+ printf("PCI: ERROR !\n");
+ printf("PCI: Unable to open modules.pcimap file in current directory.\n");
+ printf("PCI: Kernel Module names can't be computed.\n");
+ }
+
+ /* display the pci devices we found */
+ display_pci_devices(pci_domain);
+ return 0;
+}
+MODULE_MAIN(pcitest_main);
diff --git a/com32/elflink/modules/vesainfo.c b/com32/elflink/modules/vesainfo.c
new file mode 100644
index 00000000..05e4f2c9
--- /dev/null
+++ b/com32/elflink/modules/vesainfo.c
@@ -0,0 +1,93 @@
+/*
+ * vesainfo.c
+ *
+ * Dump information about what VESA graphics modes are supported.
+ */
+
+#include <string.h>
+#include <stdio.h>
+#include <console.h>
+#include <com32.h>
+#include <inttypes.h>
+#include "../lib/sys/vesa/vesa.h"
+
+#include <sys/module.h>
+
+/* Wait for a keypress */
+static void wait_key(void)
+{
+ char ch;
+ while (fread(&ch, 1, 1, stdin) == 0) ;
+}
+
+static void print_modes(void)
+{
+ static com32sys_t rm;
+ struct vesa_general_info *gi;
+ struct vesa_mode_info *mi;
+ uint16_t mode, *mode_ptr;
+ int lines;
+
+ struct vesa_info *vesa;
+
+ vesa = lmalloc(sizeof(*vesa));
+ if (!vesa) {
+ printf("vesainfo.c32: fail in lmalloc\n");
+ return;
+ }
+ gi = &vesa->gi;
+ mi = &vesa->mi;
+
+ gi->signature = VBE2_MAGIC; /* Get VBE2 extended data */
+ rm.eax.w[0] = 0x4F00; /* Get SVGA general information */
+ rm.edi.w[0] = OFFS(gi);
+ rm.es = SEG(gi);
+ __intcall(0x10, &rm, &rm);
+
+ if (rm.eax.w[0] != 0x004F) {
+ printf("No VESA BIOS detected\n");
+ goto exit;
+ } else if (gi->signature != VESA_MAGIC) {
+ printf("VESA information structure has bad magic, trying anyway...\n");
+ }
+
+ printf("VBE version %d.%d\n"
+ "Mode attrib h_res v_res bpp layout rpos gpos bpos\n",
+ (gi->version >> 8) & 0xff, gi->version & 0xff);
+
+ lines = 1;
+
+ mode_ptr = GET_PTR(gi->video_mode_ptr);
+
+ while ((mode = *mode_ptr++) != 0xFFFF) {
+ if (++lines >= 23) {
+ wait_key();
+ lines = 0;
+ }
+
+ rm.eax.w[0] = 0x4F01; /* Get SVGA mode information */
+ rm.ecx.w[0] = mode;
+ rm.edi.w[0] = OFFS(mi);
+ rm.es = SEG(mi);
+ __intcall(0x10, &rm, &rm);
+
+ /* Must be a supported mode */
+ if (rm.eax.w[0] != 0x004f)
+ continue;
+
+ printf("0x%04x 0x%04x %5u %5u %3u %6u %4u %4u %4u\n",
+ mode, mi->mode_attr, mi->h_res, mi->v_res, mi->bpp,
+ mi->memory_layout, mi->rpos, mi->gpos, mi->bpos);
+ }
+
+exit:
+ free(vesa);
+ return;
+}
+
+static int vesainfo_main(void)
+{
+ print_modes();
+ return 0;
+}
+MODULE_MAIN(vesainfo_main);