summaryrefslogtreecommitdiffstats
path: root/board/MAI/bios_emulator/scitech/src/v86bios/cbios.c
diff options
context:
space:
mode:
Diffstat (limited to 'board/MAI/bios_emulator/scitech/src/v86bios/cbios.c')
-rw-r--r--board/MAI/bios_emulator/scitech/src/v86bios/cbios.c415
1 files changed, 415 insertions, 0 deletions
diff --git a/board/MAI/bios_emulator/scitech/src/v86bios/cbios.c b/board/MAI/bios_emulator/scitech/src/v86bios/cbios.c
new file mode 100644
index 0000000000..4173c953ba
--- /dev/null
+++ b/board/MAI/bios_emulator/scitech/src/v86bios/cbios.c
@@ -0,0 +1,415 @@
+#include <unistd.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <sys/mman.h>
+#include <sys/types.h>
+#include <string.h>
+#include <stdlib.h>
+#include <signal.h>
+#include <sys/stat.h>
+#include <getopt.h>
+#if defined(__alpha__) || defined (__ia64__)
+#include <sys/io.h>
+#elif defined(HAVE_SYS_PERM)
+#include <sys/perm.h>
+#endif
+#include "debug.h"
+#include "v86bios.h"
+#include "pci.h"
+#include "AsmMacros.h"
+
+#define SIZE 0x100000
+#define VRAM_START 0xA0000
+#define VRAM_SIZE 0x1FFFF
+#define V_BIOS_SIZE 0x1FFFF
+#define BIOS_START 0x7C00 /* default BIOS entry */
+#define BIOS_MEM 0x600
+
+CARD8 code[] = { 0xcd, 0x10, 0xf4 };
+struct config Config;
+
+static int map(void);
+static void unmap(void);
+static void runBIOS(int argc, char **argv);
+static int map_vram(void);
+static void unmap_vram(void);
+static int copy_vbios(memType base);
+static int copy_sys_bios(void);
+static CARD32 setup_int_vect(void);
+static void update_bios_vars(void);
+static int chksum(CARD8 *start);
+static void setup_bios_regs(i86biosRegsPtr regs, int argc, char **argv);
+static void print_regs(i86biosRegsPtr regs);
+void dprint(unsigned long start, unsigned long size);
+
+void loadCodeToMem(unsigned char *ptr, CARD8 *code);
+
+static int vram_mapped = 0;
+static char* bios_var;
+
+
+int
+main(int argc,char **argv)
+{
+ CARD32 vbios_base;
+
+ Config.PrintPort = PRINT_PORT;
+ Config.IoStatistics = IO_STATISTICS;
+ Config.PrintIrq = PRINT_IRQ;
+ Config.PrintPci = PRINT_PCI;
+ Config.ShowAllDev = SHOW_ALL_DEV;
+ Config.PrintIp = PRINT_IP;
+ Config.SaveBios = SAVE_BIOS;
+ Config.Trace = TRACE;
+ Config.ConfigActiveOnly = CONFIG_ACTIVE_ONLY;
+ Config.ConfigActiveDevice = CONFIG_ACTIVE_DEVICE;
+ Config.MapSysBios = MAP_SYS_BIOS;
+ Config.Resort = RESORT;
+ Config.FixRom = FIX_ROM;
+ Config.NoConsole = NO_CONSOLE;
+ Config.Verbose = VERBOSE;
+
+ if (!map())
+ exit(1);
+ if (!copy_sys_bios())
+ exit(1);
+ if (!(vbios_base = setup_int_vect()))
+ exit(1);
+ if (!map_vram())
+ exit(1);
+ if (!copy_vbios(vbios_base))
+ exit(1);
+
+ iopl(3);
+ setup_io();
+ runBIOS(argc,argv);
+ update_bios_vars();
+ unmap_vram();
+ iopl(0);
+ unmap();
+ printf("done !\n");
+ exit (1);
+}
+
+int
+map(void)
+{
+ void* mem;
+
+ mem = mmap(0, (size_t)SIZE,
+ PROT_EXEC | PROT_READ | PROT_WRITE,
+ MAP_FIXED | MAP_PRIVATE | MAP_ANON,
+ -1, 0 );
+ if (mem != 0) {
+ perror("anonymous map");
+ return (0);
+ }
+ memset(mem,0,SIZE);
+
+ loadCodeToMem((unsigned char *) BIOS_START, code);
+ return (1);
+}
+
+static int
+copy_sys_bios(void)
+{
+#define SYS_BIOS 0xF0000
+ int mem_fd;
+
+ if ((mem_fd = open(MEM_FILE,O_RDONLY))<0) {
+ perror("opening memory");
+ return (0);
+ }
+
+ if (lseek(mem_fd,(off_t) SYS_BIOS,SEEK_SET) != (off_t) SYS_BIOS)
+ goto Error;
+ if (read(mem_fd, (char *)SYS_BIOS, (size_t) 0xFFFF) != (size_t) 0xFFFF)
+ goto Error;
+
+ close(mem_fd);
+ return (1);
+
+Error:
+ perror("sys_bios");
+ close(mem_fd);
+ return (0);
+}
+
+static int
+map_vram(void)
+{
+ int mem_fd;
+
+#ifdef __ia64__
+ if ((mem_fd = open(MEM_FILE,O_RDWR | O_SYNC))<0)
+#else
+ if ((mem_fd = open(MEM_FILE,O_RDWR))<0)
+#endif
+ {
+ perror("opening memory");
+ return 0;
+ }
+
+#ifndef __alpha__
+ if (mmap((void *) VRAM_START, (size_t) VRAM_SIZE,
+ PROT_EXEC | PROT_READ | PROT_WRITE, MAP_SHARED | MAP_FIXED,
+ mem_fd, VRAM_START) == (void *) -1)
+#else
+ if (!_bus_base()) sparse_shift = 7; /* Uh, oh, JENSEN... */
+ if (!_bus_base_sparse()) sparse_shift = 0;
+ if ((vram_map = mmap(0,(size_t) (VRAM_SIZE << sparse_shift),
+ PROT_READ | PROT_WRITE,
+ MAP_SHARED,
+ mem_fd, (VRAM_START << sparse_shift)
+ | _bus_base_sparse())) == (void *) -1)
+#endif
+ {
+ perror("mmap error in map_hardware_ram");
+ close(mem_fd);
+ return (0);
+ }
+ vram_mapped = 1;
+ close(mem_fd);
+ return (1);
+}
+
+static int
+copy_vbios(memType v_base)
+{
+ int mem_fd;
+ unsigned char *tmp;
+ int size;
+
+ if ((mem_fd = open(MEM_FILE,O_RDONLY))<0) {
+ perror("opening memory");
+ return (0);
+ }
+
+ if (lseek(mem_fd,(off_t) v_base, SEEK_SET) != (off_t) v_base) {
+ fprintf(stderr,"Cannot lseek\n");
+ goto Error;
+ }
+ tmp = (unsigned char *)malloc(3);
+ if (read(mem_fd, (char *)tmp, (size_t) 3) != (size_t) 3) {
+ fprintf(stderr,"Cannot read\n");
+ goto Error;
+ }
+ if (lseek(mem_fd,(off_t) v_base,SEEK_SET) != (off_t) v_base)
+ goto Error;
+
+ if (*tmp != 0x55 || *(tmp+1) != 0xAA ) {
+ fprintf(stderr,"No bios found at: 0x%lx\n",v_base);
+ goto Error;
+ }
+#ifdef DEBUG
+ dprint((unsigned long)tmp,0x100);
+#endif
+ size = *(tmp+2) * 512;
+
+ if (read(mem_fd, (char *)v_base, (size_t) size) != (size_t) size) {
+ fprintf(stderr,"Cannot read\n");
+ goto Error;
+ }
+ free(tmp);
+ close(mem_fd);
+ if (!chksum((CARD8*)v_base))
+ return (0);
+
+ return (1);
+
+Error:
+ perror("v_bios");
+ close(mem_fd);
+ return (0);
+}
+
+static void
+unmap(void)
+{
+ munmap(0,SIZE);
+}
+
+static void
+unmap_vram(void)
+{
+ if (!vram_mapped) return;
+
+ munmap((void*)VRAM_START,VRAM_SIZE);
+ vram_mapped = 0;
+}
+
+static void
+runBIOS(int argc, char ** argv)
+{
+ i86biosRegs bRegs;
+#ifdef V86BIOS_DEBUG
+ printf("starting BIOS\n");
+#endif
+ setup_bios_regs(&bRegs, argc, argv);
+ do_x86(BIOS_START,&bRegs);
+ print_regs(&bRegs);
+#ifdef V86BIOS_DEBUG
+ printf("done\n");
+#endif
+}
+
+static CARD32
+setup_int_vect(void)
+{
+ int mem_fd;
+ CARD32 vbase;
+ void *map;
+
+ if ((mem_fd = open(MEM_FILE,O_RDONLY))<0) {
+ perror("opening memory");
+ return (0);
+ }
+
+ if ((map = mmap((void *) 0, (size_t) 0x2000,
+ PROT_EXEC | PROT_READ | PROT_WRITE, MAP_SHARED,
+ mem_fd, 0)) == (void *)-1) {
+ perror("mmap error in map_hardware_ram");
+ close(mem_fd);
+ return (0);
+ }
+
+ close(mem_fd);
+ memcpy(0,map,BIOS_MEM);
+ munmap(map,0x2000);
+ /*
+ * create a backup copy of the bios variables to write back the
+ * modified values
+ */
+ bios_var = (char *)malloc(BIOS_MEM);
+ memcpy(bios_var,0,BIOS_MEM);
+
+ vbase = (*((CARD16*)(0x10 << 2) + 1)) << 4;
+ fprintf(stderr,"vbase: 0x%x\n",vbase);
+ return vbase;
+}
+
+static void
+update_bios_vars(void)
+{
+ int mem_fd;
+ void *map;
+ memType i;
+
+#ifdef __ia64__
+ if ((mem_fd = open(MEM_FILE,O_RDWR | O_SYNC))<0)
+#else
+ if ((mem_fd = open(MEM_FILE,O_RDWR))<0)
+#endif
+ {
+ perror("opening memory");
+ return;
+ }
+
+ if ((map = mmap((void *) 0, (size_t) 0x2000,
+ PROT_EXEC | PROT_READ | PROT_WRITE, MAP_SHARED,
+ mem_fd, 0)) == (void *)-1) {
+ perror("mmap error in map_hardware_ram");
+ close(mem_fd);
+ return;
+ }
+
+ for (i = 0; i < BIOS_MEM; i++) {
+ if (bios_var[i] != *(CARD8*)i)
+ *((CARD8*)map + i) = *(CARD8*)i;
+ }
+
+ munmap(map,0x2000);
+ close(mem_fd);
+}
+
+
+static void
+setup_bios_regs(i86biosRegsPtr regs, int argc, char **argv)
+{
+ int c;
+
+ regs->ax = 0;
+ regs->bx = 0;
+ regs->cx = 0;
+ regs->dx = 0;
+ regs->es = 0;
+ regs->di = 0;
+ opterr = 0;
+ while ((c = getopt(argc,argv,"a:b:c:d:e:i:")) != EOF) {
+ switch (c) {
+ case 'a':
+ regs->ax = strtol(optarg,NULL,0);
+ break;
+ case 'b':
+ regs->bx = strtol(optarg,NULL,0);
+ break;
+ case 'c':
+ regs->cx = strtol(optarg,NULL,0);
+ break;
+ case 'd':
+ regs->dx = strtol(optarg,NULL,0);
+ break;
+ case 'e':
+ regs->es = strtol(optarg,NULL,0);
+ break;
+ case 'i':
+ regs->di = strtol(optarg,NULL,0);
+ break;
+ }
+ }
+}
+
+
+static int
+chksum(CARD8 *start)
+{
+ CARD16 size;
+ CARD8 val = 0;
+ int i;
+
+ size = *(start+2) * 512;
+ for (i = 0; i<size; i++)
+ val += *(start + i);
+
+ if (!val)
+ return 1;
+
+ fprintf(stderr,"BIOS cksum wrong!\n");
+ return 0;
+}
+
+static void
+print_regs(i86biosRegsPtr regs)
+{
+ printf("ax=%x bx=%x cx=%x dx=%x es=%x di=%x\n",(CARD16)regs->ax,
+ (CARD16)regs->bx,(CARD16)regs->cx,(CARD16)regs->dx,
+ (CARD16)regs->es,(CARD16)regs->di);
+}
+
+void
+loadCodeToMem(unsigned char *ptr, CARD8 code[])
+{
+ int i;
+ CARD8 val;
+
+ for ( i=0;;i++) {
+ val = code[i];
+ *ptr++ = val;
+ if (val == 0xf4) break;
+ }
+ return;
+}
+
+void
+dprint(unsigned long start, unsigned long size)
+{
+ int i,j;
+ char *c = (char *)start;
+
+ for (j = 0; j < (size >> 4); j++) {
+ printf ("\n0x%lx: ",(unsigned long)c);
+ for (i = 0; i<16; i++)
+ printf("%x ",(unsigned char) (*(c++)));
+ }
+ printf("\n");
+}
OpenPOWER on IntegriCloud