summaryrefslogtreecommitdiffstats
path: root/cfe/cfe/pccons
diff options
context:
space:
mode:
Diffstat (limited to 'cfe/cfe/pccons')
-rw-r--r--cfe/cfe/pccons/Makefile3
-rw-r--r--cfe/cfe/pccons/README19
-rw-r--r--cfe/cfe/pccons/dev_pcconsole.c339
-rw-r--r--cfe/cfe/pccons/dev_pcconsole2.c298
-rw-r--r--cfe/cfe/pccons/kbd_subr.c371
-rw-r--r--cfe/cfe/pccons/kbd_subr.h82
-rw-r--r--cfe/cfe/pccons/pcibios.h72
-rw-r--r--cfe/cfe/pccons/vga.h76
-rw-r--r--cfe/cfe/pccons/vga_subr.c285
-rw-r--r--cfe/cfe/pccons/vga_subr.h82
-rw-r--r--cfe/cfe/pccons/vgainit.c1164
-rw-r--r--cfe/cfe/pccons/x86mem.c423
-rw-r--r--cfe/cfe/pccons/x86mem.h109
13 files changed, 3323 insertions, 0 deletions
diff --git a/cfe/cfe/pccons/Makefile b/cfe/cfe/pccons/Makefile
new file mode 100644
index 0000000..09b8610
--- /dev/null
+++ b/cfe/cfe/pccons/Makefile
@@ -0,0 +1,3 @@
+
+CFLAGS += -DCFG_VGACONSOLE=1
+ALLOBJS += vgainit.o vga_subr.o kbd_subr.o x86mem.o dev_pcconsole.o dev_pcconsole2.o
diff --git a/cfe/cfe/pccons/README b/cfe/cfe/pccons/README
new file mode 100644
index 0000000..0160ad5
--- /dev/null
+++ b/cfe/cfe/pccons/README
@@ -0,0 +1,19 @@
+
+This directory contains "PC Console" routines, to enable the
+SWARM board to use PC-style devices for its console. In
+particular, it contains the code to use the X86 emulator
+to initialize the VGA, and code to map scan codes to
+ASCII characters for a PC keyboard.
+
+What is this good for, you ask? Just for fun, mostly. Many of
+us have had this screwy notion that a SWARM could be used as
+a Linux "workstation" if we could get VGA support and USB
+keyboards implemented (oh, yeah, and there's this whole
+matter of PC console support in Linux, and X, and ...).
+
+Like the USB host stack, this is among the least-supported
+portions of CFE. If you find it useful, great! If it doesn't
+work or build properly, let us know, but we may not get to fixing
+it right away.
+
+
diff --git a/cfe/cfe/pccons/dev_pcconsole.c b/cfe/cfe/pccons/dev_pcconsole.c
new file mode 100644
index 0000000..fe85eca
--- /dev/null
+++ b/cfe/cfe/pccons/dev_pcconsole.c
@@ -0,0 +1,339 @@
+/* *********************************************************************
+ * Broadcom Common Firmware Environment (CFE)
+ *
+ * PC Console driver File: dev_pcconsole.c
+ *
+ * A console driver for a PC-style keyboard and mouse
+ *
+ * Author: Mitch Lichtenberg (mpl@broadcom.com)
+ *
+ *********************************************************************
+ *
+ * Copyright 2000,2001,2002,2003
+ * Broadcom Corporation. All rights reserved.
+ *
+ * This software is furnished under license and may be used and
+ * copied only in accordance with the following terms and
+ * conditions. Subject to these conditions, you may download,
+ * copy, install, use, modify and distribute modified or unmodified
+ * copies of this software in source and/or binary form. No title
+ * or ownership is transferred hereby.
+ *
+ * 1) Any source code used, modified or distributed must reproduce
+ * and retain this copyright notice and list of conditions
+ * as they appear in the source file.
+ *
+ * 2) No right is granted to use any trade name, trademark, or
+ * logo of Broadcom Corporation. The "Broadcom Corporation"
+ * name may not be used to endorse or promote products derived
+ * from this software without the prior written permission of
+ * Broadcom Corporation.
+ *
+ * 3) THIS SOFTWARE IS PROVIDED "AS-IS" AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING BUT NOT LIMITED TO, ANY IMPLIED
+ * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+ * PURPOSE, OR NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT
+ * SHALL BROADCOM BE LIABLE FOR ANY DAMAGES WHATSOEVER, AND IN
+ * PARTICULAR, BROADCOM SHALL NOT BE LIABLE FOR DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+ * TORT (INCLUDING NEGLIGENCE OR OTHERWISE), EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ ********************************************************************* */
+
+
+
+
+#include "sbmips.h"
+#include "lib_types.h"
+#include "lib_malloc.h"
+#include "lib_printf.h"
+#include "cfe_iocb.h"
+#include "cfe_device.h"
+
+#include "lib_physio.h"
+
+#include "kbd_subr.h"
+#include "vga_subr.h"
+
+#include "bsp_config.h"
+#include "pcireg.h"
+#include "pcivar.h"
+
+
+/* *********************************************************************
+ * Constants
+ ********************************************************************* */
+
+#define KBD_RXFULL 1 /* bit set if kb has data */
+#define KBD_TXFULL 2 /* bit set if we can send cmd */
+#define VGA_TEXTBUF_COLOR 0xB8000 /* VGA frame buffer */
+
+#if defined(_P5064_) || defined(_P6064_)
+ #define PCI_MEM_SPACE 0x10000000 /* 128MB: s/w configurable */
+ #define __ISAaddr(addr) ((physaddr_t)(PCI_MEM_SPACE+(addr)))
+#else
+ #define __ISAaddr(addr) ((physaddr_t)0x40000000+(addr))
+#endif
+
+#define cpu_isamap(x,y) __ISAaddr(x)
+
+/* *********************************************************************
+ * Forward references
+ ********************************************************************* */
+
+static void pcconsole_probe(cfe_driver_t *drv,
+ unsigned long probe_a, unsigned long probe_b,
+ void *probe_ptr);
+
+
+static int pcconsole_open(cfe_devctx_t *ctx);
+static int pcconsole_read(cfe_devctx_t *ctx,iocb_buffer_t *buffer);
+static int pcconsole_inpstat(cfe_devctx_t *ctx,iocb_inpstat_t *inpstat);
+static int pcconsole_write(cfe_devctx_t *ctx,iocb_buffer_t *buffer);
+static int pcconsole_ioctl(cfe_devctx_t *ctx,iocb_buffer_t *buffer);
+static int pcconsole_close(cfe_devctx_t *ctx);
+static void pcconsole_poll(cfe_devctx_t *ctx,int64_t ticks);
+
+const static cfe_devdisp_t pcconsole_dispatch = {
+ pcconsole_open,
+ pcconsole_read,
+ pcconsole_inpstat,
+ pcconsole_write,
+ pcconsole_ioctl,
+ pcconsole_close,
+ pcconsole_poll,
+ NULL
+};
+
+const cfe_driver_t pcconsole = {
+ "PC Console",
+ "pcconsole",
+ CFE_DEV_SERIAL,
+ &pcconsole_dispatch,
+ pcconsole_probe
+};
+
+
+/* *********************************************************************
+ * Structures
+ ********************************************************************* */
+
+
+typedef struct pcconsole_s {
+ vga_term_t vga;
+ keystate_t ks;
+ uint32_t kbd_status;
+ uint32_t kbd_data;
+} pcconsole_t;
+
+
+/* *********************************************************************
+ * pcconsole_poll(ctx,ticks)
+ *
+ * Poll routine - check for new keyboard events
+ *
+ * Input parameters:
+ * ctx - device context
+ * ticks - current time
+ *
+ * Return value:
+ * nothing
+ ********************************************************************* */
+
+
+static void pcconsole_poll(cfe_devctx_t *ctx,int64_t ticks)
+{
+ pcconsole_t *softc = ctx->dev_softc;
+ uint8_t status;
+ uint8_t b;
+
+ status = inb(softc->kbd_status);
+
+ if (status & KBD_RXFULL) {
+ b = inb(softc->kbd_data);
+ kbd_doscan(&(softc->ks),b);
+ }
+}
+
+/* *********************************************************************
+ * pcconsole_waitcmdready(softc)
+ *
+ * Wait for the keyboard to be ready to accept a command
+ *
+ * Input parameters:
+ * softc - console structure
+ *
+ * Return value:
+ * nothing
+ ********************************************************************* */
+
+static void pcconsole_waitcmdready(pcconsole_t *softc)
+{
+ uint8_t status;
+ uint8_t data;
+
+ for (;;) {
+ status = inb(softc->kbd_status); /* read status */
+ if (status & KBD_RXFULL) {
+ data = inb(softc->kbd_data); /* get data */
+ kbd_doscan(&(softc->ks),data); /* process scan codes */
+ }
+ if (!(status & KBD_TXFULL)) break; /* stop when kbd ready */
+ }
+}
+
+
+/* *********************************************************************
+ * pcconsole_setleds(ks,leds)
+ *
+ * Callback from the keyboard routines for setting the LEDS
+ *
+ * Input parameters:
+ * ks - keyboard state
+ * leds - new LED state
+ *
+ * Return value:
+ * 0
+ ********************************************************************* */
+
+static int pcconsole_setleds(keystate_t *ks,int leds)
+{
+ pcconsole_t *softc = kbd_getref(ks);
+
+ pcconsole_waitcmdready(softc);
+ outb(softc->kbd_data,KBDCMD_SETLEDS);
+ pcconsole_waitcmdready(softc);
+ outb(softc->kbd_data,(leds & 7));
+
+ return 0;
+}
+
+
+/* *********************************************************************
+ * pcconsole_probe(drv,probe_a,probe_b,probe_ptr)
+ *
+ * Probe routine. This routine sets up the pcconsole device
+ *
+ * Input parameters:
+ * drv - driver structure
+ * probe_a
+ * probe_b
+ * probe_ptr
+ *
+ * Return value:
+ * nothing
+ ********************************************************************* */
+
+static void pcconsole_probe(cfe_driver_t *drv,
+ unsigned long probe_a, unsigned long probe_b,
+ void *probe_ptr)
+{
+ pcconsole_t *softc;
+ char descr[80];
+ volatile uint8_t *isamem;
+
+ /*
+ * probe_a is
+ * probe_b is
+ * probe_ptr is
+ */
+
+ softc = (pcconsole_t *) KMALLOC(sizeof(pcconsole_t),0);
+ if (softc) {
+ /*
+ * XXX This should not be hardwired.
+ */
+ softc->kbd_status = 0x64;
+ softc->kbd_data = 0x60;
+ kbd_init(&(softc->ks),pcconsole_setleds,softc);
+
+ /*
+ * XXX this should not be hardwired
+ */
+ isamem = (volatile uint8_t *) ((uintptr_t)cpu_isamap(0,1024*1024));
+ vga_init(&(softc->vga),__ISAaddr(VGA_TEXTBUF_COLOR),outb);
+
+ xsprintf(descr,"%s",drv->drv_description,probe_a,probe_b);
+ cfe_attach(drv,softc,NULL,descr);
+ }
+
+}
+
+
+static int pcconsole_open(cfe_devctx_t *ctx)
+{
+ pcconsole_t *softc = ctx->dev_softc;
+
+ outb(softc->kbd_data,KBDCMD_RESET); /* reset keyboard */
+ kbd_init(&(softc->ks),pcconsole_setleds,softc);
+ vga_clear(&(softc->vga));
+ vga_setcursor(&(softc->vga),0,0);
+
+ return 0;
+}
+
+static int pcconsole_read(cfe_devctx_t *ctx,iocb_buffer_t *buffer)
+{
+ pcconsole_t *softc = ctx->dev_softc;
+ unsigned char *bptr;
+ int blen;
+
+ pcconsole_poll(ctx,0);
+
+ bptr = buffer->buf_ptr;
+ blen = buffer->buf_length;
+
+ while ((blen > 0) && (kbd_inpstat(&(softc->ks)))) {
+ *bptr++ = (kbd_read(&(softc->ks)) & 0xFF);
+ blen--;
+ }
+
+ buffer->buf_retlen = buffer->buf_length - blen;
+ return 0;
+}
+
+static int pcconsole_inpstat(cfe_devctx_t *ctx,iocb_inpstat_t *inpstat)
+{
+ pcconsole_t *softc = ctx->dev_softc;
+
+ pcconsole_poll(ctx,0);
+
+ inpstat->inp_status = kbd_inpstat(&(softc->ks)) ? 1 : 0;
+
+ return 0;
+}
+
+static int pcconsole_write(cfe_devctx_t *ctx,iocb_buffer_t *buffer)
+{
+ pcconsole_t *softc = ctx->dev_softc;
+ unsigned char *bptr;
+ int blen;
+
+ bptr = buffer->buf_ptr;
+ blen = buffer->buf_length;
+
+ vga_writestr(&(softc->vga),bptr,7,blen);
+
+ buffer->buf_retlen = buffer->buf_length;
+ return 0;
+}
+
+static int pcconsole_ioctl(cfe_devctx_t *ctx,iocb_buffer_t *buffer)
+{
+/* pcconsole_t *softc = ctx->dev_softc;*/
+
+ return -1;
+}
+
+static int pcconsole_close(cfe_devctx_t *ctx)
+{
+/* pcconsole_t *softc = ctx->dev_softc;*/
+
+ return 0;
+}
+
+
diff --git a/cfe/cfe/pccons/dev_pcconsole2.c b/cfe/cfe/pccons/dev_pcconsole2.c
new file mode 100644
index 0000000..e078c13
--- /dev/null
+++ b/cfe/cfe/pccons/dev_pcconsole2.c
@@ -0,0 +1,298 @@
+/* *********************************************************************
+ * Broadcom Common Firmware Environment (CFE)
+ *
+ * PC Console driver File: dev_pcconsole2.c
+ *
+ * A console driver for a PC-style keyboard and mouse
+ *
+ * This version is for USB keyboards. Someday we'll consolidate
+ * everything.
+ *
+ * Author: Mitch Lichtenberg (mpl@broadcom.com)
+ *
+ *********************************************************************
+ *
+ * Copyright 2000,2001,2002,2003
+ * Broadcom Corporation. All rights reserved.
+ *
+ * This software is furnished under license and may be used and
+ * copied only in accordance with the following terms and
+ * conditions. Subject to these conditions, you may download,
+ * copy, install, use, modify and distribute modified or unmodified
+ * copies of this software in source and/or binary form. No title
+ * or ownership is transferred hereby.
+ *
+ * 1) Any source code used, modified or distributed must reproduce
+ * and retain this copyright notice and list of conditions
+ * as they appear in the source file.
+ *
+ * 2) No right is granted to use any trade name, trademark, or
+ * logo of Broadcom Corporation. The "Broadcom Corporation"
+ * name may not be used to endorse or promote products derived
+ * from this software without the prior written permission of
+ * Broadcom Corporation.
+ *
+ * 3) THIS SOFTWARE IS PROVIDED "AS-IS" AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING BUT NOT LIMITED TO, ANY IMPLIED
+ * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+ * PURPOSE, OR NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT
+ * SHALL BROADCOM BE LIABLE FOR ANY DAMAGES WHATSOEVER, AND IN
+ * PARTICULAR, BROADCOM SHALL NOT BE LIABLE FOR DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+ * TORT (INCLUDING NEGLIGENCE OR OTHERWISE), EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ ********************************************************************* */
+
+
+
+
+#include "sbmips.h"
+#include "lib_types.h"
+#include "lib_malloc.h"
+#include "lib_printf.h"
+#include "lib_string.h"
+
+#include "cfe_iocb.h"
+#include "cfe_device.h"
+#include "cfe_timer.h"
+
+#include "lib_physio.h"
+
+#include "vga_subr.h"
+
+#include "bsp_config.h"
+#include "pcireg.h"
+#include "pcivar.h"
+
+/* *********************************************************************
+ * Constants
+ ********************************************************************* */
+
+#define KBD_RXFULL 1 /* bit set if kb has data */
+#define KBD_TXFULL 2 /* bit set if we can send cmd */
+#define VGA_TEXTBUF_COLOR 0xB8000 /* VGA frame buffer */
+
+/* XXX SB1250 specific */
+#define __ISAaddr(x)(0x40000000+(x))
+
+/* *********************************************************************
+ * Forward references
+ ********************************************************************* */
+
+int pcconsole_enqueue(uint8_t ch);
+
+static void pcconsole_probe(cfe_driver_t *drv,
+ unsigned long probe_a, unsigned long probe_b,
+ void *probe_ptr);
+
+
+static int pcconsole_open(cfe_devctx_t *ctx);
+static int pcconsole_read(cfe_devctx_t *ctx,iocb_buffer_t *buffer);
+static int pcconsole_inpstat(cfe_devctx_t *ctx,iocb_inpstat_t *inpstat);
+static int pcconsole_write(cfe_devctx_t *ctx,iocb_buffer_t *buffer);
+static int pcconsole_ioctl(cfe_devctx_t *ctx,iocb_buffer_t *buffer);
+static int pcconsole_close(cfe_devctx_t *ctx);
+static void pcconsole_poll(cfe_devctx_t *ctx,int64_t ticks);
+
+const static cfe_devdisp_t pcconsole_dispatch = {
+ pcconsole_open,
+ pcconsole_read,
+ pcconsole_inpstat,
+ pcconsole_write,
+ pcconsole_ioctl,
+ pcconsole_close,
+ pcconsole_poll,
+ NULL
+};
+
+const cfe_driver_t pcconsole2 = {
+ "PC Console (USB)",
+ "pcconsole",
+ CFE_DEV_SERIAL,
+ &pcconsole_dispatch,
+ pcconsole_probe
+};
+
+
+/* *********************************************************************
+ * Structures
+ ********************************************************************* */
+
+#define KBD_QUEUE_LEN 32
+
+typedef struct pcconsole_s {
+ vga_term_t vga;
+ int kbd_in;
+ int kbd_out;
+ uint8_t kbd_data[KBD_QUEUE_LEN];
+} pcconsole_t;
+
+static pcconsole_t *pcconsole_current = NULL;
+
+/* *********************************************************************
+ * pcconsole_poll(ctx,ticks)
+ *
+ * Poll routine - check for new keyboard events
+ *
+ * Input parameters:
+ * ctx - device context
+ * ticks - current time
+ *
+ * Return value:
+ * nothing
+ ********************************************************************* */
+
+
+static void pcconsole_poll(cfe_devctx_t *ctx,int64_t ticks)
+{
+ /* No polling needed, USB will do the work for us */
+}
+
+
+
+/* *********************************************************************
+ * pcconsole_probe(drv,probe_a,probe_b,probe_ptr)
+ *
+ * Probe routine. This routine sets up the pcconsole device
+ *
+ * Input parameters:
+ * drv - driver structure
+ * probe_a
+ * probe_b
+ * probe_ptr
+ *
+ * Return value:
+ * nothing
+ ********************************************************************* */
+
+static void pcconsole_probe(cfe_driver_t *drv,
+ unsigned long probe_a, unsigned long probe_b,
+ void *probe_ptr)
+{
+ pcconsole_t *softc;
+ char descr[80];
+
+ /*
+ * probe_a is
+ * probe_b is
+ * probe_ptr is
+ */
+
+ softc = (pcconsole_t *) KMALLOC(sizeof(pcconsole_t),0);
+ if (softc) {
+
+ memset(softc,0,sizeof(pcconsole_t));
+
+ /*
+ * XXX this should not be hardwired
+ */
+ vga_init(&(softc->vga),__ISAaddr(VGA_TEXTBUF_COLOR),outb);
+
+ xsprintf(descr,"%s",drv->drv_description,probe_a,probe_b);
+ cfe_attach(drv,softc,NULL,descr);
+ }
+
+}
+
+
+static int pcconsole_open(cfe_devctx_t *ctx)
+{
+ pcconsole_t *softc = ctx->dev_softc;
+
+ pcconsole_current = softc;
+
+ softc->kbd_in = 0;
+ softc->kbd_out = 0;
+
+ vga_clear(&(softc->vga));
+ vga_setcursor(&(softc->vga),0,0);
+
+ return 0;
+}
+
+static int pcconsole_read(cfe_devctx_t *ctx,iocb_buffer_t *buffer)
+{
+ pcconsole_t *softc = ctx->dev_softc;
+ unsigned char *bptr;
+ int blen;
+
+ bptr = buffer->buf_ptr;
+ blen = buffer->buf_length;
+
+ while ((blen > 0) && (softc->kbd_in != softc->kbd_out)) {
+ *bptr++ = softc->kbd_data[softc->kbd_out];
+ softc->kbd_out++;
+ if (softc->kbd_out >= KBD_QUEUE_LEN) {
+ softc->kbd_out = 0;
+ }
+ blen--;
+ }
+
+ buffer->buf_retlen = buffer->buf_length - blen;
+ return 0;
+}
+
+static int pcconsole_inpstat(cfe_devctx_t *ctx,iocb_inpstat_t *inpstat)
+{
+ pcconsole_t *softc = ctx->dev_softc;
+
+ POLL();
+
+ inpstat->inp_status = (softc->kbd_in != softc->kbd_out);
+
+ return 0;
+}
+
+static int pcconsole_write(cfe_devctx_t *ctx,iocb_buffer_t *buffer)
+{
+ pcconsole_t *softc = ctx->dev_softc;
+ unsigned char *bptr;
+ int blen;
+
+ bptr = buffer->buf_ptr;
+ blen = buffer->buf_length;
+
+ vga_writestr(&(softc->vga),bptr,7,blen);
+
+ buffer->buf_retlen = buffer->buf_length;
+ return 0;
+}
+
+static int pcconsole_ioctl(cfe_devctx_t *ctx,iocb_buffer_t *buffer)
+{
+/* pcconsole_t *softc = ctx->dev_softc;*/
+
+ return -1;
+}
+
+static int pcconsole_close(cfe_devctx_t *ctx)
+{
+/* pcconsole_t *softc = ctx->dev_softc;*/
+ pcconsole_current = NULL;
+
+ return 0;
+}
+
+/*
+ * Called by USB system to queue characters.
+ */
+int pcconsole_enqueue(uint8_t ch)
+{
+ int newidx;
+
+ if (!pcconsole_current) return -1;
+
+ newidx = pcconsole_current->kbd_in+1;
+ if (newidx >= KBD_QUEUE_LEN) newidx = 0;
+
+ if (newidx == pcconsole_current->kbd_out) return -1;
+
+ pcconsole_current->kbd_data[pcconsole_current->kbd_in] = ch;
+ pcconsole_current->kbd_in = newidx;
+
+ return 0;
+}
diff --git a/cfe/cfe/pccons/kbd_subr.c b/cfe/cfe/pccons/kbd_subr.c
new file mode 100644
index 0000000..860db94
--- /dev/null
+++ b/cfe/cfe/pccons/kbd_subr.c
@@ -0,0 +1,371 @@
+/* *********************************************************************
+ * Broadcom Common Firmware Environment (CFE)
+ *
+ * PC-style keyboard interface File: KBD_SUBR.C
+ *
+ * This module converts a stream of scancodes into ASCII
+ * characters. The scan codes come from a PC-style
+ * keyboard.
+ *
+ * Author: Mitch Lichtenberg (mpl@broadcom.com)
+ *
+ *********************************************************************
+ *
+ * Copyright 2000,2001,2002,2003
+ * Broadcom Corporation. All rights reserved.
+ *
+ * This software is furnished under license and may be used and
+ * copied only in accordance with the following terms and
+ * conditions. Subject to these conditions, you may download,
+ * copy, install, use, modify and distribute modified or unmodified
+ * copies of this software in source and/or binary form. No title
+ * or ownership is transferred hereby.
+ *
+ * 1) Any source code used, modified or distributed must reproduce
+ * and retain this copyright notice and list of conditions
+ * as they appear in the source file.
+ *
+ * 2) No right is granted to use any trade name, trademark, or
+ * logo of Broadcom Corporation. The "Broadcom Corporation"
+ * name may not be used to endorse or promote products derived
+ * from this software without the prior written permission of
+ * Broadcom Corporation.
+ *
+ * 3) THIS SOFTWARE IS PROVIDED "AS-IS" AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING BUT NOT LIMITED TO, ANY IMPLIED
+ * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+ * PURPOSE, OR NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT
+ * SHALL BROADCOM BE LIABLE FOR ANY DAMAGES WHATSOEVER, AND IN
+ * PARTICULAR, BROADCOM SHALL NOT BE LIABLE FOR DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+ * TORT (INCLUDING NEGLIGENCE OR OTHERWISE), EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ ********************************************************************* */
+
+
+#include "lib_types.h"
+#include "lib_string.h"
+
+#include "kbd_subr.h"
+
+
+/* *********************************************************************
+ * Constants
+ ********************************************************************* */
+
+#define FLG_SCROLL 0x0001 /* Toggles: same as bit positions for LEDs! */
+#define FLG_NUM 0x0002
+#define FLG_CAPS 0x0004
+#define FLG_SHIFT 0x0008 /* Shifts */
+#define FLG_CTRL 0x0100
+#define FLG_ALT 0x0200
+#define FLG_FKEY 0x0400 /* function keys */
+#define FLG_NKPD 0x0800 /* numeric keypad */
+#define FLG_ASCII 0x1000 /* regular ASCII character */
+#define FLG_NONE 0x2000
+#define FLG_BREAKBIT 0x80
+
+
+/* *********************************************************************
+ * Structures
+ ********************************************************************* */
+
+#define KC_RESPLEN 4
+typedef struct keycode_s {
+ int kc_type;
+ char kc_normal[KC_RESPLEN];
+ char kc_shifted[KC_RESPLEN];
+ char kc_ctrl[KC_RESPLEN];
+} keycode_t;
+
+
+/* *********************************************************************
+ * Scan code conversion table
+ ********************************************************************* */
+
+static keycode_t scantable[] = {
+ { FLG_NONE, "", "", "" }, /* 0 */
+ { FLG_ASCII, "\033", "\033", "\033" }, /* 1 ESC */
+ { FLG_ASCII, "1", "!", "!" }, /* 2 1 */
+ { FLG_ASCII, "2", "@", "\000" }, /* 3 2 */
+ { FLG_ASCII, "3", "#", "#" }, /* 4 3 */
+ { FLG_ASCII, "4", "$", "$" }, /* 5 4 */
+ { FLG_ASCII, "5", "%", "%" }, /* 6 5 */
+ { FLG_ASCII, "6", "^", "\036" }, /* 7 6 */
+ { FLG_ASCII, "7", "&", "&" }, /* 8 7 */
+ { FLG_ASCII, "8", "*", "\010" }, /* 9 8 */
+ { FLG_ASCII, "9", "(", "(" }, /* 10 9 */
+ { FLG_ASCII, "0", ")", ")" }, /* 11 0 */
+ { FLG_ASCII, "-", "_", "\037" }, /* 12 - */
+ { FLG_ASCII, "=", "+", "+" }, /* 13 = */
+ { FLG_ASCII, "\177", "\177", "\010" }, /* 14 <- */
+ { FLG_ASCII, "\t", "\177\t", "\t" }, /* 15 ->| */
+ { FLG_ASCII, "q", "Q", "\021" }, /* 16 q */
+ { FLG_ASCII, "w", "W", "\027" }, /* 17 w */
+ { FLG_ASCII, "e", "E", "\005" }, /* 18 e */
+ { FLG_ASCII, "r", "R", "\022" }, /* 19 r */
+ { FLG_ASCII, "t", "T", "\024" }, /* 20 t */
+ { FLG_ASCII, "y", "Y", "\031" }, /* 21 y */
+ { FLG_ASCII, "u", "U", "\025" }, /* 22 u */
+ { FLG_ASCII, "i", "I", "\011" }, /* 23 i */
+ { FLG_ASCII, "o", "O", "\017" }, /* 24 o */
+ { FLG_ASCII, "p", "P", "\020" }, /* 25 p */
+ { FLG_ASCII, "[", "{", "\033" }, /* 26 [ */
+ { FLG_ASCII, "]", "}", "\035" }, /* 27 ] */
+ { FLG_ASCII, "\r", "\r", "\n" }, /* 28 ENT */
+ { FLG_CTRL, "", "", "" }, /* 29 CTRL */
+ { FLG_ASCII, "a", "A", "\001" }, /* 30 a */
+ { FLG_ASCII, "s", "S", "\023" }, /* 31 s */
+ { FLG_ASCII, "d", "D", "\004" }, /* 32 d */
+ { FLG_ASCII, "f", "F", "\006" }, /* 33 f */
+ { FLG_ASCII, "g", "G", "\007" }, /* 34 g */
+ { FLG_ASCII, "h", "H", "\010" }, /* 35 h */
+ { FLG_ASCII, "j", "J", "\n" }, /* 36 j */
+ { FLG_ASCII, "k", "K", "\013" }, /* 37 k */
+ { FLG_ASCII, "l", "L", "\014" }, /* 38 l */
+ { FLG_ASCII, ";", ":", ";" }, /* 39 ; */
+ { FLG_ASCII, "'", "\"", "'" }, /* 40 ' */
+ { FLG_ASCII, "`", "~", "`" }, /* 41 ` */
+ { FLG_SHIFT, "", "", "" }, /* 42 SHIFT */
+ { FLG_ASCII, "\\", "|", "\034" }, /* 43 \ */
+ { FLG_ASCII, "z", "Z", "\032" }, /* 44 z */
+ { FLG_ASCII, "x", "X", "\030" }, /* 45 x */
+ { FLG_ASCII, "c", "C", "\003" }, /* 46 c */
+ { FLG_ASCII, "v", "V", "\026" }, /* 47 v */
+ { FLG_ASCII, "b", "B", "\002" }, /* 48 b */
+ { FLG_ASCII, "n", "N", "\016" }, /* 49 n */
+ { FLG_ASCII, "m", "M", "\r" }, /* 50 m */
+ { FLG_ASCII, ",", "<", "<" }, /* 51 , */
+ { FLG_ASCII, ".", ">", ">" }, /* 52 . */
+ { FLG_ASCII, "/", "?", "\037" }, /* 53 / */
+ { FLG_SHIFT, "", "", "" }, /* 54 SHIFT */
+ { FLG_NKPD, "*", "*", "*" }, /* 55 KP* */
+ { FLG_ALT, "", "", "" }, /* 56 ALT */
+ { FLG_ASCII, " ", " ", "\000" }, /* 57 SPC */
+ { FLG_CAPS, "", "", "" }, /* 58 CAPS */
+ { FLG_FKEY, "\033[M", "\033[Y", "\033[k" }, /* 59 f1 */
+ { FLG_FKEY, "\033[N", "\033[Z", "\033[l" }, /* 60 f2 */
+ { FLG_FKEY, "\033[O", "\033[a", "\033[m" }, /* 61 f3 */
+ { FLG_FKEY, "\033[P", "\033[b", "\033[n" }, /* 62 f4 */
+ { FLG_FKEY, "\033[Q", "\033[c", "\033[o" }, /* 63 f5 */
+ { FLG_FKEY, "\033[R", "\033[d", "\033[p" }, /* 64 f6 */
+ { FLG_FKEY, "\033[S", "\033[e", "\033[q" }, /* 65 f7 */
+ { FLG_FKEY, "\033[T", "\033[f", "\033[r" }, /* 66 f8 */
+ { FLG_FKEY, "\033[U", "\033[g", "\033[s" }, /* 67 f9 */
+ { FLG_FKEY, "\033[V", "\033[h", "\033[t" }, /* 68 f10 */
+ { FLG_NUM, "", "", "" }, /* 69 NUMLK */
+ { FLG_SCROLL, "", "", "" }, /* 70 SCRLK */
+ { FLG_NKPD, "7", "\033[H", "7" }, /* 71 KP7 */
+ { FLG_NKPD, "8", "\033[A", "8" }, /* 72 KP8 */
+ { FLG_NKPD, "9", "\033[I", "9" }, /* 73 KP9 */
+ { FLG_NKPD, "-", "-", "-" }, /* 74 KP- */
+ { FLG_NKPD, "4", "\033[D", "4" }, /* 75 KP4 */
+ { FLG_NKPD, "5", "\033[E", "5" }, /* 76 KP5 */
+ { FLG_NKPD, "6", "\033[C", "6" }, /* 77 KP6 */
+ { FLG_NKPD, "+", "+", "+" }, /* 78 KP+ */
+ { FLG_NKPD, "1", "\033[F", "1" }, /* 79 KP1 */
+ { FLG_NKPD, "2", "\033[B", "2" }, /* 80 KP2 */
+ { FLG_NKPD, "3", "\033[G", "3" }, /* 81 KP3 */
+ { FLG_NKPD, "0", "\033[L", "0" }, /* 82 KP0 */
+ { FLG_NKPD, ".", "\177", "." }, /* 83 KP. */
+ { FLG_NONE, "", "", "" }, /* 84 0 */
+ { FLG_NONE, "100", "", "" }, /* 85 0 */
+ { FLG_NONE, "101", "", "" }, /* 86 0 */
+ { FLG_FKEY, "\033[W", "\033[i", "\033[u" }, /* 87 f11 */
+ { FLG_FKEY, "\033[X", "\033[j", "\033[v" }, /* 88 f12 */
+ { FLG_NONE, "102", "", "" }, /* 89 0 */
+ { FLG_NONE, "103", "", "" }, /* 90 0 */
+ { FLG_NONE, "", "", "" }, /* 91 0 */
+ { FLG_NONE, "", "", "" }, /* 92 0 */
+ { FLG_NONE, "", "", "" }, /* 93 0 */
+ { FLG_NONE, "", "", "" }, /* 94 0 */
+ { FLG_NONE, "", "", "" }, /* 95 0 */
+ { FLG_NONE, "", "", "" }, /* 96 0 */
+ { FLG_NONE, "", "", "" }, /* 97 0 */
+ { FLG_NONE, "", "", "" }, /* 98 0 */
+ { FLG_NONE, "", "", "" }, /* 99 0 */
+ { FLG_NONE, "", "", "" }, /* 100 */
+ { FLG_NONE, "", "", "" }, /* 101 */
+ { FLG_NONE, "", "", "" }, /* 102 */
+ { FLG_NONE, "", "", "" }, /* 103 */
+ { FLG_NONE, "", "", "" }, /* 104 */
+ { FLG_NONE, "", "", "" }, /* 105 */
+ { FLG_NONE, "", "", "" }, /* 106 */
+ { FLG_NONE, "", "", "" }, /* 107 */
+ { FLG_NONE, "", "", "" }, /* 108 */
+ { FLG_NONE, "", "", "" }, /* 109 */
+ { FLG_NONE, "", "", "" }, /* 110 */
+ { FLG_NONE, "", "", "" }, /* 111 */
+ { FLG_NONE, "", "", "" }, /* 112 */
+ { FLG_NONE, "", "", "" }, /* 113 */
+ { FLG_NONE, "", "", "" }, /* 114 */
+ { FLG_NONE, "", "", "" }, /* 115 */
+ { FLG_NONE, "", "", "" }, /* 116 */
+ { FLG_NONE, "", "", "" }, /* 117 */
+ { FLG_NONE, "", "", "" }, /* 118 */
+ { FLG_NONE, "", "", "" }, /* 119 */
+ { FLG_NONE, "", "", "" }, /* 120 */
+ { FLG_NONE, "", "", "" }, /* 121 */
+ { FLG_NONE, "", "", "" }, /* 122 */
+ { FLG_NONE, "", "", "" }, /* 123 */
+ { FLG_NONE, "", "", "" }, /* 124 */
+ { FLG_NONE, "", "", "" }, /* 125 */
+ { FLG_NONE, "", "", "" }, /* 126 */
+ { FLG_NONE, "", "", "" }, /* 127 */
+};
+
+
+/* *********************************************************************
+ * KBD_ENQUEUECHAR(ks,ch)
+ *
+ * Put a character on the queue
+ *
+ * Input parameters:
+ * ks - keyboard state
+ * ch - character to enqueue
+ *
+ * Return value:
+ * nothing
+ ********************************************************************* */
+
+static void kbd_enqueuechar(keystate_t *ks,char ch)
+{
+ if (((ks->ks_head+1) & (KEYQUEUELEN-1)) == ks->ks_tail) {
+ /* queue is full */
+ return;
+ }
+ ks->ks_queue[ks->ks_head] = ch;
+ ks->ks_head = (ks->ks_head+1) & (KEYQUEUELEN-1);
+}
+
+
+/* *********************************************************************
+ * KBD_DEQUEUECHAR(ks)
+ *
+ * Remove a character from the queue
+ *
+ * Input parameters:
+ * ks - keystate
+ *
+ * Return value:
+ * 0 if no characters in queue
+ * else character from queue
+ ********************************************************************* */
+static int kbd_dequeuechar(keystate_t *ks)
+{
+ char ch;
+
+ if (ks->ks_head == ks->ks_tail) return 0;
+
+ ch = ks->ks_queue[ks->ks_tail];
+ ks->ks_tail = (ks->ks_tail+1) & (KEYQUEUELEN-1);
+ return ch;
+}
+
+/* *********************************************************************
+ * KBD_READ(ks)
+ *
+ * User call to kbd_dequeuechar - remove a character from
+ * the queue.
+ *
+ * Input parameters:
+ * ks - keyboard state
+ *
+ * Return value:
+ * character from queue or 0 if no chars
+ ********************************************************************* */
+
+int kbd_read(keystate_t *ks)
+{
+ return kbd_dequeuechar(ks);
+}
+
+/* *********************************************************************
+ * KBD_INPSTAT(ks)
+ *
+ * Test input status (see if a character is waiting)
+ *
+ * Input parameters:
+ * ks - keyboard state
+ *
+ * Return value:
+ * 0 if no chars waiting, 1 if characters are waiting
+ ********************************************************************* */
+
+int kbd_inpstat(keystate_t *ks)
+{
+ return (ks->ks_head != ks->ks_tail);
+}
+
+
+/* *********************************************************************
+ * KBD_DOSCAN(ks,scan)
+ *
+ * Process a scan code from the keyboard.
+ *
+ * Input parameters:
+ * ks - keyboard state
+ * scan - scan code from the keyboard
+ *
+ * Return value:
+ * nothing
+ ********************************************************************* */
+
+void kbd_doscan(keystate_t *ks,uint8_t scan)
+{
+ int breakflg;
+ keycode_t *code = 0;
+ char *str;
+
+ breakflg = (scan & FLG_BREAKBIT);
+ scan &= ~FLG_BREAKBIT;
+ code = &scantable[scan];
+
+ if (code->kc_type & (FLG_SHIFT|FLG_CTRL|FLG_ALT)) {
+ if (breakflg) ks->ks_shiftflags &= ~code->kc_type;
+ else ks->ks_shiftflags |= code->kc_type;
+ }
+ if (code->kc_type & (FLG_CAPS|FLG_SCROLL|FLG_NUM)) {
+ if (!breakflg) ks->ks_shiftflags ^= code->kc_type;
+ if (ks->ks_setleds) {
+ (*(ks->ks_setleds))(ks,ks->ks_shiftflags & (FLG_CAPS|FLG_SCROLL|FLG_NUM));
+ }
+ }
+ if (code->kc_type & (FLG_ASCII | FLG_FKEY | FLG_NKPD)) {
+ if (ks->ks_shiftflags & (FLG_SHIFT|FLG_CAPS)) str = code->kc_shifted;
+ else if (ks->ks_shiftflags & FLG_CTRL) str = code->kc_ctrl;
+ else str = code->kc_normal;
+ if (!breakflg) {
+ while (*str) {
+ kbd_enqueuechar(ks,*str++);
+ }
+ }
+ }
+}
+
+
+/* *********************************************************************
+ * KBD_INIT(ks,setleds,ref)
+ *
+ * Initialize a keyboard state object.
+ *
+ * Input parameters:
+ * ks - keyboard state
+ * setleds - routine to call when we want to set the state
+ * of the keyboard's LEDs
+ * ref - data to store in the keyboard state object
+ *
+ * Return value:
+ * nothing
+ ********************************************************************* */
+
+void kbd_init(keystate_t *ks,int (*setleds)(keystate_t *,int),void *ref)
+{
+ memset(ks,0,sizeof(keystate_t));
+ ks->ks_setleds = setleds;
+ ks->ks_ref = ref;
+}
diff --git a/cfe/cfe/pccons/kbd_subr.h b/cfe/cfe/pccons/kbd_subr.h
new file mode 100644
index 0000000..f18f8db
--- /dev/null
+++ b/cfe/cfe/pccons/kbd_subr.h
@@ -0,0 +1,82 @@
+/* *********************************************************************
+ * Broadcom Common Firmware Environment (CFE)
+ *
+ * PC-style keyboard interface File: KBD_SUBR.C
+ *
+ * This module converts a stream of scancodes into ASCII
+ * characters. The scan codes come from a PC-style
+ * keyboard.
+ *
+ * Author: Mitch Lichtenberg (mpl@broadcom.com)
+ *
+ *********************************************************************
+ *
+ * Copyright 2000,2001,2002,2003
+ * Broadcom Corporation. All rights reserved.
+ *
+ * This software is furnished under license and may be used and
+ * copied only in accordance with the following terms and
+ * conditions. Subject to these conditions, you may download,
+ * copy, install, use, modify and distribute modified or unmodified
+ * copies of this software in source and/or binary form. No title
+ * or ownership is transferred hereby.
+ *
+ * 1) Any source code used, modified or distributed must reproduce
+ * and retain this copyright notice and list of conditions
+ * as they appear in the source file.
+ *
+ * 2) No right is granted to use any trade name, trademark, or
+ * logo of Broadcom Corporation. The "Broadcom Corporation"
+ * name may not be used to endorse or promote products derived
+ * from this software without the prior written permission of
+ * Broadcom Corporation.
+ *
+ * 3) THIS SOFTWARE IS PROVIDED "AS-IS" AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING BUT NOT LIMITED TO, ANY IMPLIED
+ * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+ * PURPOSE, OR NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT
+ * SHALL BROADCOM BE LIABLE FOR ANY DAMAGES WHATSOEVER, AND IN
+ * PARTICULAR, BROADCOM SHALL NOT BE LIABLE FOR DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+ * TORT (INCLUDING NEGLIGENCE OR OTHERWISE), EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ ********************************************************************* */
+
+
+/* *********************************************************************
+ * Constants
+ ********************************************************************* */
+
+#define KEYQUEUELEN 16
+
+#define KBDCMD_RESET 0xFF
+#define KBDCMD_SETLEDS 0xED
+
+/* *********************************************************************
+ * Structures
+ ********************************************************************* */
+
+typedef struct keystate_s {
+ int ks_shiftflags;
+ char ks_queue[KEYQUEUELEN];
+ int ks_head;
+ int ks_tail;
+ int (*ks_setleds)(struct keystate_s *ks,int leds);
+ void *ks_ref;
+} keystate_t;
+
+/* *********************************************************************
+ * Prototypes
+ ********************************************************************* */
+
+int kbd_read(keystate_t *ks);
+int kbd_inpstat(keystate_t *ks);
+void kbd_init(keystate_t *ks,int (*setleds)(keystate_t *,int),void *ref);
+void kbd_doscan(keystate_t *ks,uint8_t scan);
+#define kbd_getref(x) ((x)->ks_ref)
+
+
diff --git a/cfe/cfe/pccons/pcibios.h b/cfe/cfe/pccons/pcibios.h
new file mode 100644
index 0000000..8da8648
--- /dev/null
+++ b/cfe/cfe/pccons/pcibios.h
@@ -0,0 +1,72 @@
+/* *********************************************************************
+ * Broadcom Common Firmware Environment (CFE)
+ *
+ * PCI BIOS constants File: PCIBIOS.H
+ *
+ * This module contains constants related to the X86's PCI
+ * BIOS, as described in the PCI BIOS specification.
+ *
+ * Author: Mitch Lichtenberg (mpl@broadcom.com)
+ *
+ *********************************************************************
+ *
+ * Copyright 2000,2001,2002,2003
+ * Broadcom Corporation. All rights reserved.
+ *
+ * This software is furnished under license and may be used and
+ * copied only in accordance with the following terms and
+ * conditions. Subject to these conditions, you may download,
+ * copy, install, use, modify and distribute modified or unmodified
+ * copies of this software in source and/or binary form. No title
+ * or ownership is transferred hereby.
+ *
+ * 1) Any source code used, modified or distributed must reproduce
+ * and retain this copyright notice and list of conditions
+ * as they appear in the source file.
+ *
+ * 2) No right is granted to use any trade name, trademark, or
+ * logo of Broadcom Corporation. The "Broadcom Corporation"
+ * name may not be used to endorse or promote products derived
+ * from this software without the prior written permission of
+ * Broadcom Corporation.
+ *
+ * 3) THIS SOFTWARE IS PROVIDED "AS-IS" AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING BUT NOT LIMITED TO, ANY IMPLIED
+ * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+ * PURPOSE, OR NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT
+ * SHALL BROADCOM BE LIABLE FOR ANY DAMAGES WHATSOEVER, AND IN
+ * PARTICULAR, BROADCOM SHALL NOT BE LIABLE FOR DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+ * TORT (INCLUDING NEGLIGENCE OR OTHERWISE), EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ ********************************************************************* */
+
+
+#define PCIBIOS_FN_MAJOR 0xB1
+#define PCIBIOS_FN_INSTCHK 0x01
+#define PCIBIOS_FN_FINDDEV 0x02
+#define PCIBIOS_FN_FINDCLASS 0x03
+#define PCIBIOS_FN_RDCFGBYTE 0x08
+#define PCIBIOS_FN_RDCFGWORD 0x09
+#define PCIBIOS_FN_RDCFGDWORD 0x0A
+
+#define PCIBIOS_FN_WRCFGBYTE 0x0B
+#define PCIBIOS_FN_WRCFGWORD 0x0C
+#define PCIBIOS_FN_WRCFGDWORD 0x0D
+#define PCIBIOS_SUCCESSFUL 0
+#define PCIBIOS_DEVICE_NOT_FOUND 0x86
+
+#define PCIBIOS_VERSION 0x0210
+#define PCIBIOS_SIGNATURE 0x20494350
+
+#define PCIBIOS_ROMSIG_OFFSET 0
+#define PCIBIOS_ROMSIG1 0x55
+#define PCIBIOS_ROMSIG2 0xAA
+#define PCIBIOS_ROMSIZE(x) ((unsigned int)(x)*512)
+
+#define PCIBIOS_ROMSIZE_OFFSET 2
+#define PCIBIOS_ROMENTRY_OFFSET 3
diff --git a/cfe/cfe/pccons/vga.h b/cfe/cfe/pccons/vga.h
new file mode 100644
index 0000000..5c43664
--- /dev/null
+++ b/cfe/cfe/pccons/vga.h
@@ -0,0 +1,76 @@
+/* *********************************************************************
+ * Broadcom Common Firmware Environment (CFE)
+ *
+ * VGA definitions File: VGA.H
+ *
+ * This module contains names of the registers and bits
+ * commonly used on VGA adapters.
+ *
+ * Author: Mitch Lichtenberg (mpl@broadcom.com)
+ *
+ *********************************************************************
+ *
+ * Copyright 2000,2001,2002,2003
+ * Broadcom Corporation. All rights reserved.
+ *
+ * This software is furnished under license and may be used and
+ * copied only in accordance with the following terms and
+ * conditions. Subject to these conditions, you may download,
+ * copy, install, use, modify and distribute modified or unmodified
+ * copies of this software in source and/or binary form. No title
+ * or ownership is transferred hereby.
+ *
+ * 1) Any source code used, modified or distributed must reproduce
+ * and retain this copyright notice and list of conditions
+ * as they appear in the source file.
+ *
+ * 2) No right is granted to use any trade name, trademark, or
+ * logo of Broadcom Corporation. The "Broadcom Corporation"
+ * name may not be used to endorse or promote products derived
+ * from this software without the prior written permission of
+ * Broadcom Corporation.
+ *
+ * 3) THIS SOFTWARE IS PROVIDED "AS-IS" AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING BUT NOT LIMITED TO, ANY IMPLIED
+ * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+ * PURPOSE, OR NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT
+ * SHALL BROADCOM BE LIABLE FOR ANY DAMAGES WHATSOEVER, AND IN
+ * PARTICULAR, BROADCOM SHALL NOT BE LIABLE FOR DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+ * TORT (INCLUDING NEGLIGENCE OR OTHERWISE), EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ ********************************************************************* */
+
+
+
+#define VGA_GFXCTL_INDEX 0x3CE
+#define VGA_GFXCTL_DATA 0x3CF
+#define VGA_CRTC_INDEX 0x3D4
+#define VGA_CRTC_DATA 0x3D5
+#define VGA_SEQ_INDEX 0x3C4
+#define VGA_SEQ_DATA 0x3C5
+#define VGA_INPSTATUS_R 0x3C2
+#define VGA_MISCOUTPUT_W 0x3C2
+#define VGA_MISCOUTPUT_R 0x3CC
+#define VGA_ATTRIB_INDEX 0x3C0
+#define VGA_ATTRIB_DATA 0x3C1
+#define VGA_FEATURES_W 0x3DA
+#define VGA_EXT_INDEX 0x3D6
+#define VGA_EXT_DATA 0x3D7
+
+#define CRTC_CURSOR_HIGH 0x0E
+#define CRTC_CURSOR_LOW 0x0F
+
+#define VGA_TEXTBUF_COLOR 0xB8000
+#define VGA_TEXTBUF_MONO 0xB0000
+#define VGA_TEXTBUF_SIZE 0x8000
+
+#define VGA_ATTRIB_MONO 7
+
+#define VGA_TEXTMODE_COLS 80
+#define VGA_TEXTMODE_ROWS 25
+
diff --git a/cfe/cfe/pccons/vga_subr.c b/cfe/cfe/pccons/vga_subr.c
new file mode 100644
index 0000000..7704054
--- /dev/null
+++ b/cfe/cfe/pccons/vga_subr.c
@@ -0,0 +1,285 @@
+/* *********************************************************************
+ * Broadcom Common Firmware Environment (CFE)
+ *
+ * VGA "teletype" routines File: VGA_SUBR.C
+ *
+ * These routines implement a simple "glass tty" interface
+ * to a vga monitor.
+ *
+ * Author: Mitch Lichtenberg (mpl@broadcom.com)
+ *
+ *********************************************************************
+ *
+ * Copyright 2000,2001,2002,2003
+ * Broadcom Corporation. All rights reserved.
+ *
+ * This software is furnished under license and may be used and
+ * copied only in accordance with the following terms and
+ * conditions. Subject to these conditions, you may download,
+ * copy, install, use, modify and distribute modified or unmodified
+ * copies of this software in source and/or binary form. No title
+ * or ownership is transferred hereby.
+ *
+ * 1) Any source code used, modified or distributed must reproduce
+ * and retain this copyright notice and list of conditions
+ * as they appear in the source file.
+ *
+ * 2) No right is granted to use any trade name, trademark, or
+ * logo of Broadcom Corporation. The "Broadcom Corporation"
+ * name may not be used to endorse or promote products derived
+ * from this software without the prior written permission of
+ * Broadcom Corporation.
+ *
+ * 3) THIS SOFTWARE IS PROVIDED "AS-IS" AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING BUT NOT LIMITED TO, ANY IMPLIED
+ * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+ * PURPOSE, OR NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT
+ * SHALL BROADCOM BE LIABLE FOR ANY DAMAGES WHATSOEVER, AND IN
+ * PARTICULAR, BROADCOM SHALL NOT BE LIABLE FOR DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+ * TORT (INCLUDING NEGLIGENCE OR OTHERWISE), EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ ********************************************************************* */
+
+
+#include "lib_types.h"
+#include "lib_string.h"
+#include "lib_printf.h"
+#include "lib_malloc.h"
+
+#include "lib_physio.h"
+
+#include "vga_subr.h"
+#include "vga.h"
+
+
+/* *********************************************************************
+ * Macros
+ ********************************************************************* */
+
+#define OUTB(vga,port,val) (*((vga)->vga_outb))(port,val)
+
+#ifdef __MIPSEB
+#define VGA_SPACE_CHAR 0x2007 /* belongs somewhere else */
+#else
+#define VGA_SPACE_CHAR 0x0720
+#endif
+
+/* *********************************************************************
+ * Data
+ ********************************************************************* */
+
+
+/* *********************************************************************
+ * VGA_CLEAR(vga)
+ *
+ * Clear the VGA screen
+ *
+ * Input parameters:
+ * vga - VGA object
+ *
+ * Return value:
+ * nothing
+ ********************************************************************* */
+
+void vga_clear(vga_term_t *vga)
+{
+ int idx;
+
+ /* Clear the frame buffer */
+
+ for (idx = 0; idx < VGA_TEXTBUF_SIZE; idx+=2) {
+ phys_write16(vga->vga_buffer+idx,VGA_SPACE_CHAR);
+ }
+}
+
+
+/* *********************************************************************
+ * VGA_SETCURSOR(vga,x,y)
+ *
+ * Set the hardware cursor position
+ *
+ * Input parameters:
+ * vga - VGA object
+ * x,y - cursor location
+ *
+ * Return value:
+ * nothing
+ ********************************************************************* */
+
+void vga_setcursor(vga_term_t *vga,int x,int y)
+{
+ unsigned int loc = y*vga->vga_ncols + x;
+
+ OUTB(vga,VGA_CRTC_INDEX,CRTC_CURSOR_HIGH);
+ OUTB(vga,VGA_CRTC_DATA,(loc >> 8) & 0xFF);
+ OUTB(vga,VGA_CRTC_INDEX,CRTC_CURSOR_LOW);
+ OUTB(vga,VGA_CRTC_DATA,(loc >> 0) & 0xFF);
+
+ vga->vga_cursorX = x;
+ vga->vga_cursorY = y;
+}
+
+/* *********************************************************************
+ * VGA_SCROLL(vga)
+ *
+ * Scroll the display up one line
+ *
+ * Input parameters:
+ * vga - VGA object
+ *
+ * Return value:
+ * nothing
+ ********************************************************************* */
+
+static void vga_scroll(vga_term_t *vga)
+{
+ int idx;
+ int count;
+ int rowsize;
+ uint32_t t;
+
+ rowsize = vga->vga_ncols * 2;
+ count = (vga->vga_nrows-1) * rowsize;
+
+ for (idx = 0; idx < count; idx+=4) {
+ t = phys_read32(vga->vga_buffer+idx+rowsize);
+ phys_write32(vga->vga_buffer+idx,t);
+ }
+
+ for (idx = 0; idx < rowsize; idx += 2) {
+ phys_write16(vga->vga_buffer+(vga->vga_nrows-1)*rowsize+idx,VGA_SPACE_CHAR);
+ }
+
+ vga_setcursor(vga,0,vga->vga_nrows-1);
+}
+
+/* *********************************************************************
+ * VGA_WRITECHAR(vga,ch,attr)
+ *
+ * Write a character to the display. This routine also
+ * interprets some rudimentary control characters, such
+ * as tab, backspace, linefeed, and carriage return.
+ *
+ * Input parameters:
+ * vga - VGA object
+ * ch - character to write
+ * attr - attribute byte for new character
+ *
+ * Return value:
+ * nothing
+ ********************************************************************* */
+
+void vga_writechar(vga_term_t *vga,uint8_t ch,uint8_t attr)
+{
+ physaddr_t addr;
+
+ switch (ch) {
+ case 0x07:
+ break;
+ case 0x09:
+ vga_writechar(vga,' ',attr);
+ while (vga->vga_cursorX % 8) vga_writechar(vga,' ',attr);
+ break;
+ case 0x0A:
+ vga->vga_cursorY++;
+ if (vga->vga_cursorY > (vga->vga_nrows-1)) {
+ vga_scroll(vga);
+ }
+ break;
+ case 0x08:
+ if (vga->vga_cursorX) {
+ vga->vga_cursorX--;
+ addr = vga->vga_buffer + (vga->vga_cursorX*2+vga->vga_cursorY*vga->vga_ncols*2);
+ phys_write8(addr,' ');
+ }
+ break;
+ case 0x0D:
+ vga->vga_cursorX = 0;
+ break;
+ default:
+ addr = vga->vga_buffer + (vga->vga_cursorX*2+vga->vga_cursorY*vga->vga_ncols*2);
+ phys_write8(addr,ch);
+ phys_write8(addr+1,attr);
+ vga->vga_cursorX++;
+ if (vga->vga_cursorX > (vga->vga_ncols-1)) {
+ vga->vga_cursorX = 0;
+ vga->vga_cursorY++;
+ if (vga->vga_cursorY > (vga->vga_nrows-1)) {
+ vga_scroll(vga);
+ }
+ }
+ break;
+ }
+
+ vga_setcursor(vga,vga->vga_cursorX,vga->vga_cursorY);
+}
+
+/* *********************************************************************
+ * VGA_WRITESTR(vga,str,attr,len)
+ *
+ * Write a string of characters to the VGA
+ *
+ * Input parameters:
+ * vga - VGA object
+ * str - pointer to buffer
+ * attr - attribute byte for characters we're writing
+ * len - number of characters to write
+ *
+ * Return value:
+ * nothing
+ ********************************************************************* */
+
+void vga_writestr(vga_term_t *vga,uint8_t *str,uint8_t attr,int len)
+{
+ while (len) {
+ vga_writechar(vga,*str,attr);
+ str++;
+ len--;
+ }
+}
+
+/* *********************************************************************
+ * VGA_RESET(vga)
+ *
+ * (mostly unused) - reset the VGA
+ *
+ * Input parameters:
+ * vga - vga object
+ *
+ * Return value:
+ * nothing
+ ********************************************************************* */
+
+void vga_reset(vga_term_t *vga)
+{
+ vga_clear(vga);
+}
+
+/* *********************************************************************
+ * VGA_INIT(vga,buffer,outfunc)
+ *
+ * Initialize a VGA object
+ *
+ * Input parameters:
+ * vga - VGA object
+ * buffer - pointer to VGA-style frame buffer (physical addr)
+ * outfunc - pointer to function to write ISA I/O ports
+ *
+ * Return value:
+ * nothing
+ ********************************************************************* */
+
+void vga_init(vga_term_t *vga,physaddr_t buffer,void (*outfunc)(unsigned int port,uint8_t val))
+{
+ vga->vga_buffer = buffer;
+ vga->vga_cursorX = 0;
+ vga->vga_cursorY = 0;
+ vga->vga_nrows = VGA_TEXTMODE_ROWS;
+ vga->vga_ncols = VGA_TEXTMODE_COLS;
+ vga->vga_outb = outfunc;
+}
diff --git a/cfe/cfe/pccons/vga_subr.h b/cfe/cfe/pccons/vga_subr.h
new file mode 100644
index 0000000..eb0e0e0
--- /dev/null
+++ b/cfe/cfe/pccons/vga_subr.h
@@ -0,0 +1,82 @@
+/* *********************************************************************
+ * Broadcom Common Firmware Environment (CFE)
+ *
+ * VGA "teletype" routines File: VGA_SUBR.H
+ *
+ * These routines implement a simple "glass tty" interface
+ * to a vga monitor.
+ *
+ * Author: Mitch Lichtenberg (mpl@broadcom.com)
+ *
+ *********************************************************************
+ *
+ * Copyright 2000,2001,2002,2003
+ * Broadcom Corporation. All rights reserved.
+ *
+ * This software is furnished under license and may be used and
+ * copied only in accordance with the following terms and
+ * conditions. Subject to these conditions, you may download,
+ * copy, install, use, modify and distribute modified or unmodified
+ * copies of this software in source and/or binary form. No title
+ * or ownership is transferred hereby.
+ *
+ * 1) Any source code used, modified or distributed must reproduce
+ * and retain this copyright notice and list of conditions
+ * as they appear in the source file.
+ *
+ * 2) No right is granted to use any trade name, trademark, or
+ * logo of Broadcom Corporation. The "Broadcom Corporation"
+ * name may not be used to endorse or promote products derived
+ * from this software without the prior written permission of
+ * Broadcom Corporation.
+ *
+ * 3) THIS SOFTWARE IS PROVIDED "AS-IS" AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING BUT NOT LIMITED TO, ANY IMPLIED
+ * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+ * PURPOSE, OR NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT
+ * SHALL BROADCOM BE LIABLE FOR ANY DAMAGES WHATSOEVER, AND IN
+ * PARTICULAR, BROADCOM SHALL NOT BE LIABLE FOR DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+ * TORT (INCLUDING NEGLIGENCE OR OTHERWISE), EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ ********************************************************************* */
+
+/* *********************************************************************
+ * Structures
+ ********************************************************************* */
+
+typedef struct vga_term_s {
+ physaddr_t vga_buffer;
+ int vga_nrows;
+ int vga_ncols;
+ int vga_cursorX;
+ int vga_cursorY;
+ void (*vga_outb)(unsigned int isaport,uint8_t val);
+} vga_term_t;
+
+/* *********************************************************************
+ * Prototypes
+ ********************************************************************* */
+
+
+void vga_clear(vga_term_t *vga);
+void vga_setcursor(vga_term_t *vga,int x,int y);
+void vga_writechar(vga_term_t *vga,uint8_t ch,uint8_t attr);
+void vga_writestr(vga_term_t *vga,uint8_t *str,uint8_t attr,int len);
+void vga_reset(vga_term_t *vga);
+void vga_init(vga_term_t *vga,physaddr_t buffer,void (*outfunc)(unsigned int port,uint8_t val));
+
+
+
+
+
+
+
+
+
+
+
diff --git a/cfe/cfe/pccons/vgainit.c b/cfe/cfe/pccons/vgainit.c
new file mode 100644
index 0000000..7c22af2
--- /dev/null
+++ b/cfe/cfe/pccons/vgainit.c
@@ -0,0 +1,1164 @@
+/* *********************************************************************
+ * Broadcom Common Firmware Environment (CFE)
+ *
+ * VGA BIOS initialization File: VGAINIT.C
+ *
+ * This module interfaces with the X86 emulator borrowed from
+ * XFree86 to do VGA initialization.
+ *
+ * WARNING: This code is SB1250-specific for now. It's not
+ * hard to change, but then again, aren't we interested in the 1250?
+ *
+ * Author: Mitch Lichtenberg (mpl@broadcom.com)
+ *
+ *********************************************************************
+ *
+ * Copyright 2000,2001,2002,2003
+ * Broadcom Corporation. All rights reserved.
+ *
+ * This software is furnished under license and may be used and
+ * copied only in accordance with the following terms and
+ * conditions. Subject to these conditions, you may download,
+ * copy, install, use, modify and distribute modified or unmodified
+ * copies of this software in source and/or binary form. No title
+ * or ownership is transferred hereby.
+ *
+ * 1) Any source code used, modified or distributed must reproduce
+ * and retain this copyright notice and list of conditions
+ * as they appear in the source file.
+ *
+ * 2) No right is granted to use any trade name, trademark, or
+ * logo of Broadcom Corporation. The "Broadcom Corporation"
+ * name may not be used to endorse or promote products derived
+ * from this software without the prior written permission of
+ * Broadcom Corporation.
+ *
+ * 3) THIS SOFTWARE IS PROVIDED "AS-IS" AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING BUT NOT LIMITED TO, ANY IMPLIED
+ * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+ * PURPOSE, OR NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT
+ * SHALL BROADCOM BE LIABLE FOR ANY DAMAGES WHATSOEVER, AND IN
+ * PARTICULAR, BROADCOM SHALL NOT BE LIABLE FOR DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+ * TORT (INCLUDING NEGLIGENCE OR OTHERWISE), EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ ********************************************************************* */
+
+#include "sbmips.h"
+#include "lib_types.h"
+#include "lib_string.h"
+#include "lib_printf.h"
+#include "lib_malloc.h"
+#include "pcireg.h"
+#include "pcivar.h"
+#include "cfe_console.h"
+#include "vga.h"
+#include "pcibios.h"
+#include "lib_physio.h"
+#include "vga_subr.h"
+#include "x86mem.h"
+#include "x86emu.h"
+#include "env_subr.h"
+
+
+/* *********************************************************************
+ * Configuration
+ ********************************************************************* */
+
+#define BYTESONLY 0 /* Always write registers as bytes */
+#define VGAINIT_NOISY 0 /* lots of debug output */
+
+/* *********************************************************************
+ * ISA port macros - currently SB1250-specific
+ ********************************************************************* */
+
+#define INB(x) inb(x)
+#define INW(x) inw(x)
+#define INL(x) inl(x)
+#define OUTB(x,y) outb(x,y)
+#define OUTW(x,y) outw(x,y)
+#define OUTL(x,y) outl(x,y)
+
+/* *********************************************************************
+ * ISA memory macros - currently SB1250-specific
+ ********************************************************************* */
+
+typedef uintptr_t vm_offset_t;
+
+#if defined(_P5064_) || defined(_P6064_)
+ #define PCI_MEM_SPACE 0x10000000 /* 128MB: s/w configurable */
+ #define __ISAaddr(addr) ((physaddr_t)(PCI_MEM_SPACE+(addr)))
+#else
+ #define __ISAaddr(addr) ((physaddr_t)0x40000000+(addr))
+#endif
+
+#define __ISAreadbyte(addr) phys_read8(__ISAaddr(addr))
+#define __ISAreadword(addr) phys_read16(__ISAaddr(addr))
+#define __ISAreaddword(addr) phys_read32(__ISAaddr(addr))
+#define __ISAwritebyte(addr,data) phys_write8(__ISAaddr(addr),(data))
+#define __ISAwriteword(addr,data) phys_write16(__ISAaddr(addr),(data))
+#define __ISAwritedword(addr,data) phys_write32(__ISAaddr(addr),(data))
+
+/* *********************************************************************
+ * Other macros
+ ********************************************************************* */
+
+#define OFFSET(addr) (((addr) >> 0) & 0xffff)
+#define SEGMENT(addr) (((addr) >> 4) & 0xf000)
+
+#define BSWAP_SHORT(s) ((((s) >> 8) & 0xFF) | (((s)&0xFF) << 8))
+#define BSWAP_LONG(s) ((((s) & 0xFF000000) >> 24) | \
+ (((s) & 0x00FF0000) >> 8) | \
+ (((s) & 0x0000FF00) << 8) | \
+ (((s) & 0x000000FF) << 24))
+
+
+#ifdef __MIPSEB
+#define CPU_TO_LE16(s) BSWAP_SHORT(s)
+#define CPU_TO_LE32(s) BSWAP_LONG(s)
+#define LE16_TO_CPU(s) BSWAP_SHORT(s)
+#define LE32_TO_CPU(s) BSWAP_LONG(s)
+#else
+#define CPU_TO_LE16(s) (s)
+#define CPU_TO_LE32(s) (s)
+#define LE16_TO_CPU(s) (s)
+#define LE32_TO_CPU(s) (s)
+#endif
+
+
+/* *********************************************************************
+ * Prototypes
+ ********************************************************************* */
+
+int vga_biosinit(void);
+int vga_probe(void);
+extern void ui_restart(int);
+void vgaraw_dump(char *tail);
+int x86emutest(void);
+
+/* *********************************************************************
+ * Globals
+ ********************************************************************* */
+
+static vga_term_t vga;
+static x86mem_t x86mem;
+
+#define BIOSRAMLOC (0xC0000)
+#define STACKSIZE 4096
+#define IRETOFFSET 12
+static uint8_t x86initcode[] = {
+#if (VGA_TEXTMODE_ROWS == 60)
+ 0xB8,0x02,0x4F, /* mov ax,042F */
+ 0xBB,0x08,0x01, /* mov bx,0108 */ /* VESA 80x60 */
+#else
+ 0xB8,0x03,0x00, /* mov AX,0003 */ /* 80x25 mode */
+#endif
+
+ 0xCD,0x10, /* int 10 */
+ 0xB8,0x34,0x12, /* mov ax,1234 */
+ 0xBB,0x78,0x56, /* mov bx,5678 */
+ 0xCC, /* int 3 */
+ 0xCF}; /* IRET */
+
+static uint8_t x86testcode[] = {
+ 0x90,0x90,0x90,0x90,0x90, /* nop, nop, nop, nop, nop */
+ 0xeb,0x09, /* jmp 10 */
+ 0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90, /* 9 nops */
+ 0xb8,0x34,0x12, /* mov ax,1234 */
+ 0xbb,0x78,0x56, /* mov bx,5678 */
+ 0xcc, /* int 3 */
+ 0xcf}; /* iret */
+
+static uint32_t __ISAreadmem(x86mem_t *mem,uint32_t addr,int size)
+{
+ unsigned long val;
+
+ switch (size) {
+ case M_BYTE:
+ val = __ISAreadbyte(addr);
+ break;
+ case M_WORD:
+ if (BYTESONLY || (addr & 0x1)) {
+ val = (__ISAreadbyte(addr) | (__ISAreadbyte(addr + 1) << 8));
+ }
+ else {
+ val = __ISAreadword(addr);
+ val = LE16_TO_CPU(val);
+ }
+ break;
+ case M_DWORD:
+ if (BYTESONLY || (addr & 0x3)) {
+ val = (__ISAreadbyte(addr) |
+ (__ISAreadbyte(addr + 1) << 8) |
+ (__ISAreadbyte(addr + 2) << 16) |
+ (__ISAreadbyte(addr + 3) << 24));
+ }
+ else {
+ val = __ISAreaddword(addr);
+ val = LE32_TO_CPU(val);
+ }
+ break;
+ default:
+ val = 0;
+ }
+
+ return val;
+}
+
+
+
+static void __ISAwritemem(x86mem_t *mem,uint32_t addr,uint32_t data,int size)
+{
+ switch (size) {
+ case M_BYTE:
+ __ISAwritebyte(addr, data);
+ break;
+
+ case M_WORD:
+ if (BYTESONLY || (addr & 0x1)) {
+ __ISAwritebyte(addr, data >> 0);
+ __ISAwritebyte(addr + 1, data >> 8);
+ }
+ else {
+ data = CPU_TO_LE16(data);
+ __ISAwriteword(addr, data);
+ }
+ break;
+
+ case M_DWORD:
+ if (BYTESONLY || (addr & 0x3)) {
+ __ISAwritebyte(addr, data >> 0);
+ __ISAwritebyte(addr + 1, data >> 8);
+ __ISAwritebyte(addr + 2, data >> 16);
+ __ISAwritebyte(addr + 3, data >> 24);
+ }
+ else {
+ data = CPU_TO_LE32(data);
+ __ISAwritedword(addr, data);
+ }
+ break;
+ }
+}
+
+
+static u8 __x86emu_rdb(u32 addr)
+{
+#if VGAINIT_NOISY
+ if ((addr < 0x400) || (addr > 0x100000)) {
+ xprintf("Read %08X (int %02X) ",addr,addr/4);
+ printf("CS:IP = %04X:%04X\n",M.x86.R_CS,M.x86.R_IP);
+ }
+#endif
+ return x86mem_readb(&x86mem,addr);
+}
+
+
+static u16 __x86emu_rdw(u32 addr)
+{
+#if VGAINIT_NOISY
+ if ((addr < 0x400) || (addr > 0x100000)) {
+ xprintf("Read %08X (int %02X) ",addr,addr/4);
+ printf("CS:IP = %04X:%04X\n",M.x86.R_CS,M.x86.R_IP);
+ }
+#endif
+ return x86mem_readw(&x86mem,addr);
+}
+
+
+static u32 __x86emu_rdl(u32 addr)
+{
+#if VGAINIT_NOISY
+ if ((addr < 0x400) || (addr > 0x100000)) {
+ xprintf("Read %08X (int %02X) ",addr,addr/4);
+ printf("CS:IP = %04X:%04X\n",M.x86.R_CS,M.x86.R_IP);
+ }
+#endif
+ return x86mem_readl(&x86mem,addr);
+}
+
+
+static void __x86emu_wrb(u32 addr, u8 val)
+{
+#if VGAINIT_NOISY
+ if ((addr < 0x400) || (addr > 0x100000)) {
+ xprintf("Write %08X (int %02X) ",addr,addr/4);
+ printf("CS:IP = %04X:%04X\n",M.x86.R_CS,M.x86.R_IP);
+ }
+#endif
+ x86mem_writeb(&x86mem,addr,val);
+}
+
+
+static void __x86emu_wrw(u32 addr, u16 val)
+{
+#if VGAINIT_NOISY
+ if ((addr < 0x400) || (addr > 0x100000)) {
+ xprintf("Write %08X %04X (int %02X) ",addr,val,addr/4);
+ printf("CS:IP = %04X:%04X\n",M.x86.R_CS,M.x86.R_IP);
+ }
+#endif
+ x86mem_writew(&x86mem,addr,val);
+}
+
+
+static void __x86emu_wrl(u32 addr, u32 val)
+{
+#if VGAINIT_NOISY
+ if ((addr < 0x400) || (addr > 0x100000)) {
+ xprintf("Write %08X (int %02X) ",addr,addr/4);
+ printf("CS:IP = %04X:%04X\n",M.x86.R_CS,M.x86.R_IP);
+ }
+#endif
+ x86mem_writel(&x86mem,addr,val);
+}
+
+
+#define TS_COMMAND 0
+#define TS_DATA1 1
+#define TS_DATA2 2
+static uint16_t timerCount = 0;
+static int timerState = TS_COMMAND;
+static u8 __x86emu_inb(X86EMU_pioAddr port)
+{
+ u8 val;
+
+ /*
+ * Emulate just enough functionality of the
+ * timer chip to fool the Trident BIOS
+ */
+ if (port == 0x40) {
+ timerCount++;
+ switch (timerState) {
+ case TS_COMMAND:
+ return 0;
+ case TS_DATA1:
+ timerState = TS_DATA1;
+ return timerCount & 0xFF;
+ case TS_DATA2:
+ timerState = TS_COMMAND;
+ return (timerCount >> 8) & 0xFF;
+ }
+ }
+
+ val = INB(port);
+
+#if VGAINIT_NOISY
+ /*if (port < 0x100)*/ xprintf("INB %08X %02X\n",port,val);
+ if (console_status()) ui_restart(0);
+#endif
+
+
+ return val;
+}
+
+
+static u16 __x86emu_inw(X86EMU_pioAddr port)
+{
+ u16 val;
+
+ val = INW(port);
+
+ val = LE16_TO_CPU(val);
+
+#if VGAINIT_NOISY
+ /*if (port < 0x100)*/ xprintf("INW %08X %04X\n",port,val);
+#endif
+
+ return val;
+}
+
+
+static u32 __x86emu_inl(X86EMU_pioAddr port)
+{
+ u32 val;
+
+ val = INL(port);
+
+ val = LE32_TO_CPU(val);
+
+#if VGAINIT_NOISY
+ /*if (port < 0x100)*/ xprintf("INL %08X %08X\n",port,val);
+#endif
+
+
+ return val;
+}
+
+
+static void __x86emu_outb(X86EMU_pioAddr port, u8 val)
+{
+ /*
+ * Emulate just enough functionality of the timer
+ * chip to fool the Trident BIOS
+ */
+ if (port == 0x43) {
+ timerCount++;
+ timerState = TS_DATA1;
+ return;
+ }
+
+#if VGAINIT_NOISY
+ /*if (port < 0x100)*/ xprintf("OUTB %08X %08X\n",port,val);
+#endif
+
+ OUTB(port,val);
+}
+
+
+static void __x86emu_outw(X86EMU_pioAddr port, u16 val)
+{
+ val = CPU_TO_LE16(val);
+
+#if VGAINIT_NOISY
+ /*if (port < 0x100)*/ xprintf("OUTW %08X %04X ",port,val);
+ printf("CS:IP = %04X:%04X\n",M.x86.R_CS,M.x86.R_IP);
+#endif
+
+ OUTW(port,val);
+}
+
+
+static void __x86emu_outl(X86EMU_pioAddr port, u32 val)
+{
+ if (port == 0x2D) return;
+
+ val = CPU_TO_LE32(val);
+
+#if VGAINIT_NOISY
+ /*if (port < 0x100)*/ xprintf("OUTL %08X %08X ",port,val);
+ printf("CS:IP = %04X:%04X\n",M.x86.R_CS,M.x86.R_IP);
+#endif
+
+
+ OUTL(port,val);
+}
+
+
+static void regs2tag(pcitag_t *tag)
+{
+ pcitag_t mytag;
+ int bus,device,function;
+
+ bus = M.x86.R_BH;
+ device = M.x86.R_BL >> 3;
+ function = M.x86.R_BL & 0x07;
+
+ mytag = pci_make_tag(bus,device,function);
+
+ *tag = mytag;
+}
+
+static void __SIMint10(int intno)
+{
+#if VGAINIT_NOISY
+ xprintf("Int10: BIOS function AX=%04X\n",M.x86.R_AX);
+#endif
+
+ /*
+ * The only BIOS function that VGAs appear to
+ * depend on in the real BIOS is the one
+ * that enables/disables video memory.
+ */
+
+ if ((M.x86.R_AH == 0x12) && (M.x86.R_BL == 0x32)) {
+ if (M.x86.R_AL == 0) {
+ /* enable video memory */
+ __x86emu_outb(VGA_MISCOUTPUT_W, __x86emu_inb(VGA_MISCOUTPUT_R) | 0x02);
+ return;
+ }
+ else if (M.x86.R_AL == 1) {
+ /* disable video memory */
+ __x86emu_outb(VGA_MISCOUTPUT_W, __x86emu_inb(VGA_MISCOUTPUT_R) & ~0x02);
+ return;
+ }
+ else {
+ xprintf("Int10 unknown function AX=%04X\n",
+ M.x86.R_AX);
+ }
+ }
+ else {
+
+ /* Otherwise, pass the int10 on to the ROM */
+
+ X86EMU_prepareForInt(0x10);
+ }
+}
+
+
+static void __SIMint3(int intno)
+{
+#if VGAINIT_NOISY
+ xprintf("Int3: Breakpoint reached.\n");
+#endif
+ HALT_SYS();
+}
+
+
+static void __SIMintunk(int intno)
+{
+#if VGAINIT_NOISY
+ xprintf("Int%02X: Unhandled interrupt!\n",intno);
+#endif
+ HALT_SYS();
+}
+
+static void __SIMint42(int intno)
+{
+#if VGAINIT_NOISY
+ xprintf("Int42: Function AX=%04X\n",M.x86.R_AX);
+#endif
+ switch (M.x86.R_AH) {
+ case 0:
+ vga_reset(&vga);
+ break;
+ default:
+#if VGAINIT_NOISY
+ xprintf("Int42: Unknown INT42 command: %x\n",M.x86.R_AH);
+#endif
+ break;
+ }
+}
+
+
+static void __SIMint6D(int intno)
+{
+ int reflect = 1;
+
+#if VGAINIT_NOISY
+ xprintf("Int6D: Function AX=%04X\n",M.x86.R_AX);
+#endif
+
+ switch (M.x86.R_AH) {
+ case 0:
+ break;
+ case 0x13:
+ if (M.x86.R_AL == 1) {
+ unsigned long addr;
+ unsigned long count;
+ uint8_t ch;
+
+ addr = (M.x86.R_ES << 4) + M.x86.R_BP;
+ count = M.x86.R_CX;
+
+ while (count) {
+ ch = __x86emu_rdb(addr);
+ vga_writechar(&vga,ch,M.x86.R_BL);
+ addr++;
+ count--;
+ }
+ reflect = 0;
+ }
+ break;
+ default:
+#if VGAINIT_NOISY
+ xprintf("Unknown INT6D command: %x\n",M.x86.R_AH);
+#endif
+ break;
+ }
+
+ if (reflect) X86EMU_prepareForInt(0x6D);
+}
+
+
+
+static void __SIMint1A(int intno)
+{
+ pcitag_t tag;
+ int bus,device,function;
+ int ret;
+
+ if (M.x86.R_AH != PCIBIOS_FN_MAJOR) return;
+
+ switch (M.x86.R_AL) {
+ case PCIBIOS_FN_INSTCHK:
+ M.x86.R_EAX = 0x00;
+ M.x86.R_AL = 0x01;
+ M.x86.R_EDX = PCIBIOS_SIGNATURE;
+ M.x86.R_EBX = PCIBIOS_VERSION;
+ M.x86.R_ECX &= 0xFF00;
+ M.x86.R_CL = 0; /* Highest bus number */
+#ifdef VGAINIT_NOISY
+ xprintf("Int1A: Installation check\n");
+#endif
+ CLEAR_FLAG(F_CF);
+ break;
+
+ case PCIBIOS_FN_FINDDEV:
+ ret = pci_find_device(M.x86.R_DX,M.x86.R_CX,M.x86.R_SI,&tag);
+#if VGAINIT_NOISY
+ xprintf("Int1A: Find device VID=%04X,DID=%04X,Idx=%d: ",
+ M.x86.R_DX,M.x86.R_CX,M.x86.R_SI);
+ if (ret == 0) {
+ pci_break_tag(tag,&bus,&device,&function);
+ xprintf("Found Bus%d, Dev%d, Func%d\n",bus,device,function);
+ }
+ else {
+ xprintf("not found.\n");
+ }
+#endif
+ if (ret == 0) {
+ pci_break_tag(tag,&bus,&device,&function);
+ M.x86.R_BH = bus;
+ M.x86.R_BL = (device << 3) | function;
+ M.x86.R_AH = PCIBIOS_SUCCESSFUL;
+ }
+ else {
+ M.x86.R_AH = PCIBIOS_DEVICE_NOT_FOUND;
+ }
+
+ CONDITIONAL_SET_FLAG((M.x86.R_AH != PCIBIOS_SUCCESSFUL),F_CF);
+ break;
+
+ case PCIBIOS_FN_FINDCLASS:
+ ret = pci_find_class(M.x86.R_ECX,M.x86.R_SI,&tag);
+#if VGAINIT_NOISY
+ xprintf("Int1A: Find Class %08X,Idx=%d: ",
+ M.x86.R_ECX,M.x86.R_SI);
+ if (ret == 0) {
+ pci_break_tag(tag,&bus,&device,&function);
+ xprintf("Found Bus%d, Dev%d, Func%d\n",bus,device,function);
+ }
+ else {
+ xprintf("not found.\n");
+ }
+#endif
+
+ if (ret == 0) {
+ pci_break_tag(tag,&bus,&device,&function);
+ M.x86.R_BH = bus;
+ M.x86.R_BL = (device << 3) | function;
+ M.x86.R_AH = PCIBIOS_SUCCESSFUL;
+ }
+ else {
+ M.x86.R_AH =PCIBIOS_DEVICE_NOT_FOUND;
+ }
+
+ CONDITIONAL_SET_FLAG((M.x86.R_AH != PCIBIOS_SUCCESSFUL),F_CF);
+ break;
+
+ case PCIBIOS_FN_RDCFGBYTE:
+ regs2tag(&tag);
+ M.x86.R_CL = pci_conf_read8(tag,M.x86.R_DI);
+ M.x86.R_AH = PCIBIOS_SUCCESSFUL;
+#if VGAINIT_NOISY
+ xprintf("Int1A: Read Cfg Byte %04X from ",M.x86.R_DI);
+ pci_break_tag(tag,&bus,&device,&function);
+ xprintf("Bus%d, Dev%d, Func%d",bus,device,function);
+ xprintf(": %02X\n",M.x86.R_CX);
+#endif
+
+ CLEAR_FLAG(F_CF);
+ break;
+
+ case PCIBIOS_FN_RDCFGWORD:
+ regs2tag(&tag);
+ M.x86.R_CX = pci_conf_read16(tag,M.x86.R_DI);
+ M.x86.R_AH = PCIBIOS_SUCCESSFUL;
+#if VGAINIT_NOISY
+ xprintf("Int1A: Read Cfg Word %04X from ",M.x86.R_DI);
+ pci_break_tag(tag,&bus,&device,&function);
+ xprintf("Bus%d, Dev%d, Func%d",bus,device,function);
+ xprintf(": %04X\n",M.x86.R_CX);
+#endif
+ CLEAR_FLAG(F_CF);
+ break;
+
+ case PCIBIOS_FN_RDCFGDWORD:
+ regs2tag(&tag);
+ M.x86.R_ECX = pci_conf_read(tag,M.x86.R_DI);
+#if VGAINIT_NOISY
+ xprintf("Int1A: Read Cfg Dword %04X from ",M.x86.R_DI);
+ pci_break_tag(tag,&bus,&device,&function);
+ xprintf("Bus%d, Dev%d, Func%d",bus,device,function);
+ xprintf(": %08X\n",M.x86.R_ECX);
+#endif
+ M.x86.R_AH = PCIBIOS_SUCCESSFUL;
+ CLEAR_FLAG(F_CF);
+ break;
+
+ case PCIBIOS_FN_WRCFGBYTE:
+ regs2tag(&tag);
+ pci_conf_write8(tag,M.x86.R_DI,M.x86.R_CL);
+#if VGAINIT_NOISY
+ xprintf("Int1A: Write Cfg byte %04X to ",M.x86.R_DI);
+ pci_break_tag(tag,&bus,&device,&function);
+ xprintf("Bus%d, Dev%d, Func%d",bus,device,function);
+ xprintf(": %02X\n",M.x86.R_CL);
+#endif
+
+ M.x86.R_AH = PCIBIOS_SUCCESSFUL;
+ CLEAR_FLAG(F_CF);
+ break;
+
+ case PCIBIOS_FN_WRCFGWORD:
+ regs2tag(&tag);
+ pci_conf_write16(tag,M.x86.R_DI,M.x86.R_CX);
+#if VGAINIT_NOISY
+ xprintf("Int1A: Write Cfg Word %04X to ",M.x86.R_DI);
+ pci_break_tag(tag,&bus,&device,&function);
+ xprintf("Bus%d, Dev%d, Func%d",bus,device,function);
+ xprintf(": %04X\n",M.x86.R_CX);
+#endif
+ M.x86.R_AH = PCIBIOS_SUCCESSFUL;
+ CLEAR_FLAG(F_CF);
+ break;
+
+ case PCIBIOS_FN_WRCFGDWORD:
+ regs2tag(&tag);
+ pci_conf_write(tag,M.x86.R_DI,M.x86.R_ECX);
+#if VGAINIT_NOISY
+ xprintf("Int1A: Write Cfg Dword %04X to ",M.x86.R_DI);
+ pci_break_tag(tag,&bus,&device,&function);
+ xprintf("Bus%d, Dev%d, Func%d",bus,device,function);
+ xprintf(": %08X\n",M.x86.R_ECX);
+#endif
+ M.x86.R_AH = PCIBIOS_SUCCESSFUL;
+ CLEAR_FLAG(F_CF);
+ break;
+
+ default:
+#if VGAINIT_NOISY
+ xprintf("Int1A: Unimplemented PCI BIOS function AX=%04x\n", M.x86.R_AX);
+#endif
+ break;
+ }
+}
+
+
+
+static int x86init(void)
+{
+ /*
+ * Access functions for I/O ports
+ */
+ static X86EMU_pioFuncs piofuncs = {
+ __x86emu_inb,
+ __x86emu_inw,
+ __x86emu_inl,
+ __x86emu_outb,
+ __x86emu_outw,
+ __x86emu_outl
+ };
+
+ /*
+ * Access functions for memory
+ */
+ static X86EMU_memFuncs memfuncs = {
+ __x86emu_rdb,
+ __x86emu_rdw,
+ __x86emu_rdl,
+ __x86emu_wrb,
+ __x86emu_wrw,
+ __x86emu_wrl
+ };
+
+ /*
+ * Interrupt table
+ */
+ void (*funcs[256])(int num); /* XXX: can be 2 kilobytes! */
+ int idx;
+
+ /*
+ * Establish hooks in the simulator
+ */
+ X86EMU_setupMemFuncs(&memfuncs);
+ X86EMU_setupPioFuncs(&piofuncs);
+
+ /*
+ * Decode what X86 software interrupts we need to hook
+ */
+
+ for (idx = 0; idx < 256; idx++) {
+ funcs[idx] = __SIMintunk; /* assume all are bad */
+ }
+ funcs[0x42] = __SIMint42; /* int42: video BIOS */
+ funcs[0x1F] = NULL; /* reflect INT1F */
+ funcs[0x43] = NULL; /* reflect INT43 */
+ funcs[0x6D] = __SIMint6D; /* int6D: video BIOS */
+
+ funcs[0x03] = __SIMint3; /* int3: firmware exit */
+ funcs[0x10] = __SIMint10; /* int10: video BIOS */
+ funcs[0x1A] = __SIMint1A; /* int1A: PCI BIOS */
+
+ X86EMU_setupIntrFuncs(funcs);
+
+ x86mem_init(&x86mem);
+ x86mem_hook(&x86mem,0xA0000,__ISAreadmem,__ISAwritemem);
+ x86mem_hook(&x86mem,0xA8000,__ISAreadmem,__ISAwritemem);
+ x86mem_hook(&x86mem,0xB0000,__ISAreadmem,__ISAwritemem);
+ x86mem_hook(&x86mem,0xB8000,__ISAreadmem,__ISAwritemem);
+
+ return 0;
+
+}
+
+
+static void x86uninit(void)
+{
+ x86mem_uninit(&x86mem);
+}
+
+
+int vga_probe(void)
+{
+ pcitag_t tag;
+
+ if (pci_find_class(PCI_CLASS_DISPLAY,0,&tag) == 0) {
+ return 0;
+ }
+
+ return -1;
+}
+
+int vga_biosinit(void)
+{
+ physaddr_t biosaddr;
+ pcitag_t tag;
+ uint32_t addr;
+ uint32_t romaddr;
+ uint32_t destaddr;
+ uint32_t stackaddr;
+ uint32_t iretaddr;
+ unsigned int biossize;
+ int bus,device,function;
+ int idx;
+ int res;
+
+ if (pci_find_class(PCI_CLASS_DISPLAY,0,&tag) == 0) {
+ romaddr = pci_conf_read(tag,PCI_MAPREG_ROM);
+ pci_conf_write(tag,PCI_MAPREG_ROM,romaddr | PCI_MAPREG_ROM_ENABLE);
+ }
+ else {
+ xprintf("No suitable VGA device found in the system.\n");
+ return -1;
+ }
+
+ addr = romaddr;
+ addr &= PCI_MAPREG_ROM_ADDR_MASK;
+#if defined(_P5064_) || defined(_P6064_)
+ biosaddr = cpu_isamap((vm_offset_t) romaddr,0);
+#else
+ biosaddr = (physaddr_t) romaddr;
+#endif
+
+ /*
+ * Check for the presence of a VGA BIOS on this adapter.
+ */
+
+ if (!((phys_read8(biosaddr+PCIBIOS_ROMSIG_OFFSET+0) == PCIBIOS_ROMSIG1) &&
+ (phys_read8(biosaddr+PCIBIOS_ROMSIG_OFFSET+1) == PCIBIOS_ROMSIG2))) {
+ xprintf("No VGA BIOS on this adapter.\n");
+ pci_conf_write(tag,PCI_MAPREG_ROM,romaddr);
+ return -1;
+ }
+ biossize = PCIBIOS_ROMSIZE(phys_read8(biosaddr+PCIBIOS_ROMSIZE_OFFSET));
+
+#if VGAINIT_NOISY
+ xprintf("VGA BIOS size is %d bytes\n",biossize);
+#endif
+
+ /*
+ * Initialize the X86 emulator
+ */
+
+ if (x86init() != 0) {
+ xprintf("X86 emulator did not initialize.\n");
+ pci_conf_write(tag,PCI_MAPREG_ROM,romaddr);
+ return -1;
+ }
+
+ /*
+ * Allocate space for the ROM BIOS and the stack.
+ * The basic layout is:
+ *
+ * C000:0000 VGA BIOS
+ * C000:XXXX end of VGA BIOS, start of stack
+ * C000:YYYY end of stack, start of init code
+ * C000:ZZZZ end of allocated memory
+ *
+ * We put a little code stub after the stack to allow us to have
+ * a clean exit from the simulator.
+ */
+
+
+ destaddr = BIOSRAMLOC;
+ stackaddr = destaddr + biossize + STACKSIZE;
+
+ /*
+ * Copy the BIOS from the PCI rom into RAM
+ */
+
+#if VGAINIT_NOISY
+ xprintf("Copying VGA BIOS to RAM.\n");
+#endif
+
+ for (idx = 0; idx < biossize; idx+=4) {
+ uint32_t b;
+
+ b = phys_read32(biosaddr+idx);
+ x86mem_memcpy(&x86mem,destaddr+idx,(uint8_t *) &b,sizeof(uint32_t));
+ }
+
+ /*
+ * Gross! The NVidia TNT2 BIOS expects to
+ * find a PC ROM BIOS date (just the slashes)
+ * at the right place in the ROMs.
+ */
+
+ x86mem_memcpy(&x86mem,0xFFFF5,"08/13/99",8);
+
+ /*
+ * Turn off the BIOS ROM, we have our copy now.
+ */
+
+ pci_conf_write(tag,PCI_MAPREG_ROM,romaddr);
+
+ /*
+ * Point certain vectors at a dummy IRET in our code space.
+ * Some ROMs don't take too kindly to null vectors, like
+ * the 3dfx Voodoo3 BIOS, which makes sure int1a is
+ * filled in before it attempts to call it. The
+ * code here is never really executed, since the emulator
+ * hooks it.
+ */
+
+ iretaddr = stackaddr + IRETOFFSET;
+ __x86emu_wrw(0x1A*4+0,OFFSET(iretaddr));
+ __x86emu_wrw(0x1A*4+2,SEGMENT(iretaddr));
+
+
+ /*
+ * The actual code begins 3 bytes after the beginning of the ROM. Set
+ * the start address to the first byte of executable code.
+ */
+
+ M.x86.R_CS = SEGMENT(destaddr + PCIBIOS_ROMENTRY_OFFSET);
+ M.x86.R_IP = OFFSET(destaddr + PCIBIOS_ROMENTRY_OFFSET);
+
+ /*
+ * Set the stack to point after our copy of the ROM
+ */
+
+ M.x86.R_SS = SEGMENT(stackaddr - 8);
+ M.x86.R_SP = OFFSET(stackaddr - 8);
+
+ /*
+ * GROSS! The Voodoo3 card expects BP to have
+ * the following value:
+ */
+
+ M.x86.R_BP = 0x197;
+
+ /*
+ * The PCI BIOS spec says you pass the bus, device, and function
+ * numbers in the AX register when starting the ROM code.
+ */
+
+ pci_break_tag(tag,&bus,&device,&function);
+ M.x86.R_AH = bus;
+ M.x86.R_AL = (device << 3) | (function & 7);
+
+ /*
+ * Arrange for the return address to point to a little piece
+ * of code that will do an int10 to set text mode, followed
+ * by storing a couple of simple signatures in the registers,
+ * and an int3 to stop the simulator.
+ *
+ * The location of this piece of code is just after our
+ * stack, and since the stack grows down, this is in 'stackaddr'
+ */
+
+ __x86emu_wrw(stackaddr-8,OFFSET(stackaddr));
+ __x86emu_wrw(stackaddr-6,SEGMENT(stackaddr));
+
+ /* copy in the code. */
+
+ for (idx = 0; idx < sizeof(x86initcode); idx++) {
+ __x86emu_wrb(stackaddr+idx,x86initcode[idx]);
+ }
+
+ /*
+ * Set up the VGA console descriptor. We need this to process the
+ * int10's that write firmware copyright notices and such.
+ */
+
+ vga_init(&vga,(__ISAaddr(VGA_TEXTBUF_COLOR)),outb);
+
+ /*
+ * Launch the simulator.
+ */
+
+ xprintf("Initializing VGA.\n");
+#ifdef DEBUG
+ X86EMU_trace_on();
+#endif
+ X86EMU_exec();
+
+ /*
+ * Check for the magic exit values in the registers. These get set
+ * by the code in the array 'x86initcode' that was loaded above
+ */
+
+ if ((M.x86.R_AX == 0x1234) && (M.x86.R_BX == 0x5678)) res = 0;
+ else res = -1;
+
+ /*
+ * Done!
+ */
+
+ x86uninit();
+
+ if (res < 0) {
+ xprintf("VGA initialization failed.\n");
+ }
+ else {
+ char temp[32];
+ char *str = "If you can see this message, the VGA has been successfully initialized!\r\n\r\n";
+
+ xprintf("VGA initialization successful.\n");
+ vga_writestr(&vga,str,0x07,strlen(str));
+
+ sprintf(temp,"%d",VGA_TEXTMODE_ROWS);
+ env_setenv("VGA_ROWS",temp,ENV_FLG_BUILTIN | ENV_FLG_READONLY | ENV_FLG_ADMIN);
+ sprintf(temp,"%d",VGA_TEXTMODE_COLS);
+ env_setenv("VGA_COLS",temp,ENV_FLG_BUILTIN | ENV_FLG_READONLY | ENV_FLG_ADMIN);
+
+ }
+
+ return res;
+}
+
+int x86emutest(void)
+{
+ uint32_t destaddr;
+ uint32_t stackaddr;
+ int res;
+
+ /*
+ * Initialize the X86 emulator
+ */
+
+ if (x86init() != 0) {
+ xprintf("X86 emulator did not initialize.\n");
+ return -1;
+ }
+
+ destaddr = BIOSRAMLOC;
+ stackaddr = destaddr + 1024;
+
+ /*
+ * Copy the BIOS from the PCI rom into RAM
+ */
+
+ xprintf("Copying test program to RAM.\n");
+ x86mem_memcpy(&x86mem,destaddr,x86testcode,sizeof(x86testcode));
+
+ /*
+ * The actual code begins 3 bytes after the beginning of the ROM. Set
+ * the start address to the first byte of executable code.
+ */
+
+ M.x86.R_CS = SEGMENT(destaddr + PCIBIOS_ROMENTRY_OFFSET);
+ M.x86.R_IP = OFFSET(destaddr + PCIBIOS_ROMENTRY_OFFSET);
+
+ /*
+ * Set the stack to point after our copy of the ROM
+ */
+
+ M.x86.R_SS = SEGMENT(stackaddr - 8);
+ M.x86.R_SP = OFFSET(stackaddr - 8);
+
+ /*
+ * Launch the simulator.
+ */
+
+ xprintf("Running X86emu test.\n");
+#ifdef DEBUG
+ X86EMU_trace_on();
+#endif
+ X86EMU_exec();
+
+ /*
+ * Check for the magic exit values in the registers. These get set
+ * by the code in the array 'x86initcode' that was loaded above
+ */
+
+ if ((M.x86.R_AX == 0x1234) && (M.x86.R_BX == 0x5678)) res = 0;
+ else res = -1;
+
+ /*
+ * Done!
+ */
+
+ x86uninit();
+
+ if (res < 0) xprintf("X86emu test failed.\n");
+ else xprintf("X86emu test successful.\n");
+
+ return res;
+}
+
+
+
+void vgaraw_dump(char *tail)
+{
+ physaddr_t biosaddr;
+ pcitag_t tag;
+ uint32_t addr;
+ uint32_t romaddr;
+ unsigned int biossize;
+ int idx;
+ int res;
+
+ if (pci_find_class(PCI_CLASS_DISPLAY,0,&tag) == 0) {
+ romaddr = pci_conf_read(tag,PCI_MAPREG_ROM);
+ pci_conf_write(tag,PCI_MAPREG_ROM,romaddr | PCI_MAPREG_ROM_ENABLE);
+ }
+ else {
+ xprintf("No suitable VGA device found in the system.\n");
+ return ;
+ }
+
+ addr = romaddr;
+ addr &= PCI_MAPREG_ROM_ADDR_MASK;
+
+ /* XXX This won't work if the PCI space is remapped somewhere else. */
+#if defined(_P5064_) || defined(_P6064_)
+ biosaddr = cpu_isamap((vm_offset_t) romaddr,0);
+#else
+ biosaddr = romaddr;
+#endif
+
+ /*
+ * Check for the presence of a VGA BIOS on this adapter.
+ */
+
+ xprintf("VGA BIOS is mapped to %08X\n",(uint32_t) biosaddr);
+
+ if (!((phys_read8(biosaddr+PCIBIOS_ROMSIG_OFFSET+0) == PCIBIOS_ROMSIG1) &&
+ (phys_read8(biosaddr+PCIBIOS_ROMSIG_OFFSET+1) == PCIBIOS_ROMSIG2))) {
+ xprintf("No VGA BIOS on this adapter, assuming 32K ROM\n");
+ biossize = 32768;
+ return;
+ }
+ else {
+ biossize = PCIBIOS_ROMSIZE(phys_read8(biosaddr+PCIBIOS_ROMSIZE_OFFSET));
+ xprintf("VGA BIOS size is %d bytes\n",biossize);
+ }
+
+ for (idx = 0; idx < biossize; idx+=16) {
+ xprintf("%04X: ",idx);
+ for (res = 0; res < 16; res++) {
+ xprintf("%02X ",phys_read8(biosaddr+idx+res));
+ }
+ xprintf("\n");
+ if (console_status()) break;
+ }
+
+// pci_conf_write(tag,PCI_MAPREG_ROM,romaddr);
+
+}
diff --git a/cfe/cfe/pccons/x86mem.c b/cfe/cfe/pccons/x86mem.c
new file mode 100644
index 0000000..2e9c49e
--- /dev/null
+++ b/cfe/cfe/pccons/x86mem.c
@@ -0,0 +1,423 @@
+/* *********************************************************************
+ * Broadcom Common Firmware Environment (CFE)
+ *
+ * X86 simulator sparse memory File: X86MEM.C
+ *
+ * This module implements X86 memory for the X86 emulator
+ * used by the BIOS simulator. To avoid allocating the
+ * entire 1MB of PC's addressable memory, this is a "sparse"
+ * memory model, allocating chunks of storage as needed.
+ * VGA BIOSes seem to do all sorts of bizarre things to memory
+ * so this helps reduce the total amount we need to allocate
+ * significantly.
+ *
+ * In addition, this module lets the simulator "hook"
+ * ranges of memory to be handled by a callback
+ * routine. This is used so that we can redirect
+ * accesses to VGA memory space to the PCI bus handler.
+ *
+ * Author: Mitch Lichtenberg (mpl@broadcom.com)
+ *
+ *********************************************************************
+ *
+ * Copyright 2000,2001,2002,2003
+ * Broadcom Corporation. All rights reserved.
+ *
+ * This software is furnished under license and may be used and
+ * copied only in accordance with the following terms and
+ * conditions. Subject to these conditions, you may download,
+ * copy, install, use, modify and distribute modified or unmodified
+ * copies of this software in source and/or binary form. No title
+ * or ownership is transferred hereby.
+ *
+ * 1) Any source code used, modified or distributed must reproduce
+ * and retain this copyright notice and list of conditions
+ * as they appear in the source file.
+ *
+ * 2) No right is granted to use any trade name, trademark, or
+ * logo of Broadcom Corporation. The "Broadcom Corporation"
+ * name may not be used to endorse or promote products derived
+ * from this software without the prior written permission of
+ * Broadcom Corporation.
+ *
+ * 3) THIS SOFTWARE IS PROVIDED "AS-IS" AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING BUT NOT LIMITED TO, ANY IMPLIED
+ * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+ * PURPOSE, OR NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT
+ * SHALL BROADCOM BE LIABLE FOR ANY DAMAGES WHATSOEVER, AND IN
+ * PARTICULAR, BROADCOM SHALL NOT BE LIABLE FOR DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+ * TORT (INCLUDING NEGLIGENCE OR OTHERWISE), EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ ********************************************************************* */
+
+
+#include "lib_types.h"
+#include "lib_string.h"
+#include "lib_malloc.h"
+#include "lib_printf.h"
+#include "x86mem.h"
+
+/* *********************************************************************
+ * Macros
+ ********************************************************************* */
+
+#define BSWAP_SHORT(s) ((((s) >> 8) & 0xFF) | (((s)&0xFF) << 8))
+#define BSWAP_LONG(s) ((((s) & 0xFF000000) >> 24) | \
+ (((s) & 0x00FF0000) >> 8) | \
+ (((s) & 0x0000FF00) << 8) | \
+ (((s) & 0x000000FF) << 24))
+
+
+/* *********************************************************************
+ * X86MEM_INIT()
+ *
+ * Initialize an X86mem object
+ *
+ * Input parameters:
+ * mem - X86mem object
+ *
+ * Return value:
+ * nothing
+ ********************************************************************* */
+
+void x86mem_init(x86mem_t *mem)
+{
+ memset(mem,0,sizeof(mem));
+}
+
+/* *********************************************************************
+ * X86MEM_UNINIT(mem)
+ *
+ * Uninitialize an X86mem object, freeing any storage
+ * associated with it.
+ *
+ * Input parameters:
+ * mem - x86mem object
+ *
+ * Return value:
+ * nothing
+ ********************************************************************* */
+
+void x86mem_uninit(x86mem_t *mem)
+{
+ int idx;
+
+ for (idx = 0; idx < X86MEM_CHUNKS; idx++) {
+ if (mem->data[idx]) {
+ KFREE(mem->data[idx]);
+ mem->data[idx] = NULL;
+ }
+ }
+}
+
+/* *********************************************************************
+ * X86MEM_READB(mem,addr)
+ *
+ * Read a byte of memory from the X86mem object.
+ *
+ * Input parameters:
+ * mem - x86mem object
+ * addr - address of byte to read
+ *
+ * Return value:
+ * byte read
+ ********************************************************************* */
+
+uint8_t x86mem_readb(x86mem_t *mem,uint32_t addr)
+{
+ uint8_t *p;
+
+ if (mem->read[X86MEM_REGION(addr)]) {
+ return (uint8_t) (*(mem->read[X86MEM_REGION(addr)]))(mem,addr,1);
+ }
+
+ p = (mem->data[X86MEM_REGION(addr)]);
+
+ if (p) {
+ return *(p + X86MEM_OFFSET(addr));
+ }
+ else {
+ return 0;
+ }
+}
+
+/* *********************************************************************
+ * X86MEM_READW(mem,addr)
+ *
+ * Read a 16-bit word of memory from the X86mem object.
+ *
+ * Input parameters:
+ * mem - x86mem object
+ * addr - address of word to read
+ *
+ * Return value:
+ * word read
+ ********************************************************************* */
+
+uint16_t x86mem_readw(x86mem_t *mem,uint32_t addr)
+{
+ uint8_t *p;
+ uint16_t ret;
+
+ if (mem->read[X86MEM_REGION(addr)]) {
+ return (uint8_t) (*(mem->read[X86MEM_REGION(addr)]))(mem,addr,2);
+ }
+
+ p = (mem->data[X86MEM_REGION(addr)]);
+ if (!p) return 0;
+
+ if ((addr & 1) || (X86MEM_OFFSET(addr) == X86MEM_CHUNKSIZE-1)) {
+
+ ret = ((uint16_t) x86mem_readb(mem,addr+0)) |
+ (((uint16_t) x86mem_readb(mem,addr+1)) << 8);
+ return ret;
+ }
+ else {
+ ret = *((uint16_t *) (p+X86MEM_OFFSET(addr)));
+#ifdef __MIPSEB
+ ret = BSWAP_SHORT(ret);
+#endif
+ }
+
+ return ret;
+}
+
+/* *********************************************************************
+ * X86MEM_READL(mem,addr)
+ *
+ * Read a 32-bit dword of memory from the X86mem object.
+ *
+ * Input parameters:
+ * mem - x86mem object
+ * addr - address of dword to read
+ *
+ * Return value:
+ * dword read
+ ********************************************************************* */
+
+uint32_t x86mem_readl(x86mem_t *mem,uint32_t addr)
+{
+ uint8_t *p;
+ uint32_t ret;
+
+ if (mem->read[X86MEM_REGION(addr)]) {
+ return (uint8_t) (*(mem->read[X86MEM_REGION(addr)]))(mem,addr,4);
+ }
+
+ p = (mem->data[X86MEM_REGION(addr)]);
+ if (!p) return 0;
+
+ if ((addr & 3) || (X86MEM_OFFSET(addr) >= X86MEM_CHUNKSIZE-3)) {
+ ret = ((uint32_t) x86mem_readb(mem,addr+0)) |
+ (((uint32_t) x86mem_readb(mem,addr+1)) << 8) |
+ (((uint32_t) x86mem_readb(mem,addr+2)) << 16) |
+ (((uint32_t) x86mem_readb(mem,addr+3)) << 24);
+ }
+ else {
+ ret = *((uint32_t *) (p+X86MEM_OFFSET(addr)));
+#ifdef __MIPSEB
+ ret = BSWAP_LONG(ret);
+#endif
+ }
+
+ return ret;
+}
+
+/* *********************************************************************
+ * X86MEM_WRITEB(mem,addr,data)
+ *
+ * Write a byte to the X86mem object
+ *
+ * Input parameters:
+ * mem - x86mem object
+ * addr - address of byte to write
+ * data - data to write
+ *
+ * Return value:
+ * nothing
+ ********************************************************************* */
+void x86mem_writeb(x86mem_t *mem,uint32_t addr,uint8_t data)
+{
+ uint8_t *p;
+
+ if (mem->write[X86MEM_REGION(addr)]) {
+ (*(mem->write[X86MEM_REGION(addr)]))(mem,addr,data,1);
+ return;
+ }
+
+ p = (mem->data[X86MEM_REGION(addr)]);
+
+ if (p) {
+ *(p + X86MEM_OFFSET(addr)) = data;
+ }
+ else {
+ p = mem->data[X86MEM_REGION(addr)] = KMALLOC(X86MEM_CHUNKSIZE,sizeof(uint32_t));
+ if (p) {
+ memset(p,0,X86MEM_CHUNKSIZE);
+ *(p + X86MEM_OFFSET(addr)) = data;
+ }
+ }
+}
+
+/* *********************************************************************
+ * X86MEM_WRITEW(mem,addr,data)
+ *
+ * Write a 16-bit word to the X86mem object
+ *
+ * Input parameters:
+ * mem - x86mem object
+ * addr - address of word to write
+ * data - data to write
+ *
+ * Return value:
+ * nothing
+ ********************************************************************* */
+void x86mem_writew(x86mem_t *mem,uint32_t addr,uint16_t data)
+{
+ uint8_t *p;
+
+ if (mem->write[X86MEM_REGION(addr)]) {
+ (*(mem->write[X86MEM_REGION(addr)]))(mem,addr,data,2);
+ return;
+ }
+
+ p = (mem->data[X86MEM_REGION(addr)]);
+
+ if (!p || (addr & 1) || (X86MEM_OFFSET(addr) == X86MEM_CHUNKSIZE-1)) {
+ x86mem_writeb(mem,addr+0,(data & 0xFF));
+ x86mem_writeb(mem,addr+1,((data >> 8) & 0xFF));
+ }
+ else {
+#ifdef __MIPSEB
+ data = BSWAP_SHORT(data);
+#endif
+ *((uint16_t *) (p+X86MEM_OFFSET(addr))) = data;
+ }
+}
+
+/* *********************************************************************
+ * X86MEM_WRITEL(mem,addr,data)
+ *
+ * Write a 32-bit dword to the X86mem object
+ *
+ * Input parameters:
+ * mem - x86mem object
+ * addr - address of dword to write
+ * data - data to write
+ *
+ * Return value:
+ * nothing
+ ********************************************************************* */
+void x86mem_writel(x86mem_t *mem,uint32_t addr,uint32_t data)
+{
+ uint8_t *p;
+
+ if (mem->write[X86MEM_REGION(addr)]) {
+ (*(mem->write[X86MEM_REGION(addr)]))(mem,addr,data,4);
+ return;
+ }
+
+ p = (mem->data[X86MEM_REGION(addr)]);
+
+ if (!p || (addr & 3) || (X86MEM_OFFSET(addr) >= X86MEM_CHUNKSIZE-3)) {
+ x86mem_writeb(mem,addr+0,(data & 0xFF));
+ x86mem_writeb(mem,addr+1,((data >> 8) & 0xFF));
+ x86mem_writeb(mem,addr+2,((data >> 16) & 0xFF));
+ x86mem_writeb(mem,addr+3,((data >> 24) & 0xFF));
+ }
+ else {
+#ifdef __MIPSEB
+ data = BSWAP_LONG(data);
+#endif
+ *((uint32_t *) (p+X86MEM_OFFSET(addr))) = data;
+ }
+}
+
+/* *********************************************************************
+ * X86MEM_MEMCPY(mem,dest,src,cnt)
+ *
+ * memcpy data into the X86mem object
+ *
+ * Input parameters:
+ * mem - x86mem object
+ * destaddr - destination x86mem address
+ * src - source local address
+ * cnt - number of bytes to copy
+ *
+ * Return value:
+ * nothing
+ ********************************************************************* */
+
+void x86mem_memcpy(x86mem_t *mem,uint32_t destaddr,uint8_t *src,int count)
+{
+ while (count) {
+ x86mem_writeb(mem,destaddr,*src);
+ destaddr++;
+ src++;
+ count--;
+ }
+}
+
+
+/* *********************************************************************
+ * X86MEM_HOOK(mem,addr,readf,writef)
+ *
+ * Establish a hook for a block of simulated memory
+ *
+ * Input parameters:
+ * mem - x86mem object
+ * addr - address in memory, should be aligned on a "chunk"
+ * boundary.
+ * readf - function to call on READ accesses
+ * writef - function to call on WRITE accesses
+ *
+ * Return value:
+ * nothing
+ ********************************************************************* */
+
+void x86mem_hook(x86mem_t *mem,uint32_t chunkaddr,
+ uint32_t (*readf)(x86mem_t *mem,uint32_t addr,int size),
+ void (*writef)(x86mem_t *mem,uint32_t addr,uint32_t val,int size))
+{
+ if (mem->data[X86MEM_REGION(chunkaddr)]) {
+ KFREE(mem->data[X86MEM_REGION(chunkaddr)]);
+ mem->data[X86MEM_REGION(chunkaddr)] = NULL;
+ }
+ mem->read[X86MEM_REGION(chunkaddr)] = readf;
+ mem->write[X86MEM_REGION(chunkaddr)] = writef;
+}
+
+/* *********************************************************************
+ * X86MEM_HOOK_RANGE(mem,addr,size,readf,writef)
+ *
+ * Establish a hook for a block of simulated memory
+ *
+ * Input parameters:
+ * mem - x86mem object
+ * addr - address in memory, should be aligned on a "chunk"
+ * boundary.
+ * size - size of region to hook. Should be a multiple
+ * of the chunk size
+ * readf - function to call on READ accesses
+ * writef - function to call on WRITE accesses
+ *
+ * Return value:
+ * nothing
+ ********************************************************************* */
+
+void x86mem_hook_range(x86mem_t *mem,uint32_t chunkaddr,int size,
+ uint32_t (*readf)(x86mem_t *mem,uint32_t addr,int size),
+ void (*writef)(x86mem_t *mem,uint32_t addr,uint32_t val,int size))
+{
+ while (size > 0) {
+ x86mem_hook(mem,chunkaddr,readf,writef);
+ size -= X86MEM_CHUNKSIZE;
+ chunkaddr += X86MEM_CHUNKSIZE;
+ }
+}
+
diff --git a/cfe/cfe/pccons/x86mem.h b/cfe/cfe/pccons/x86mem.h
new file mode 100644
index 0000000..ed9132b
--- /dev/null
+++ b/cfe/cfe/pccons/x86mem.h
@@ -0,0 +1,109 @@
+/* *********************************************************************
+ * Broadcom Common Firmware Environment (CFE)
+ *
+ * X86 simulator sparse memory File: X86MEM.H
+ *
+ * This module implements X86 memory for the X86 emulator
+ * used by the BIOS simulator. To avoid allocating the
+ * entire 1MB of PC's addressable memory, this is a "sparse"
+ * memory model, allocating chunks of storage as needed.
+ * VGA BIOSes seem to do all sorts of bizarre things to memory
+ * so this helps reduce the total amount we need to allocate
+ * significantly.
+ *
+ * In addition, this module lets the simulator "hook"
+ * ranges of memory to be handled by a callback
+ * routine. This is used so that we can redirect
+ * accesses to VGA memory space to the PCI bus handler.
+ *
+ * Author: Mitch Lichtenberg (mpl@broadcom.com)
+ *
+ *********************************************************************
+ *
+ * Copyright 2000,2001,2002,2003
+ * Broadcom Corporation. All rights reserved.
+ *
+ * This software is furnished under license and may be used and
+ * copied only in accordance with the following terms and
+ * conditions. Subject to these conditions, you may download,
+ * copy, install, use, modify and distribute modified or unmodified
+ * copies of this software in source and/or binary form. No title
+ * or ownership is transferred hereby.
+ *
+ * 1) Any source code used, modified or distributed must reproduce
+ * and retain this copyright notice and list of conditions
+ * as they appear in the source file.
+ *
+ * 2) No right is granted to use any trade name, trademark, or
+ * logo of Broadcom Corporation. The "Broadcom Corporation"
+ * name may not be used to endorse or promote products derived
+ * from this software without the prior written permission of
+ * Broadcom Corporation.
+ *
+ * 3) THIS SOFTWARE IS PROVIDED "AS-IS" AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING BUT NOT LIMITED TO, ANY IMPLIED
+ * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+ * PURPOSE, OR NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT
+ * SHALL BROADCOM BE LIABLE FOR ANY DAMAGES WHATSOEVER, AND IN
+ * PARTICULAR, BROADCOM SHALL NOT BE LIABLE FOR DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+ * TORT (INCLUDING NEGLIGENCE OR OTHERWISE), EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ ********************************************************************* */
+
+
+/* *********************************************************************
+ * Constants
+ ********************************************************************* */
+
+#define X86MEM_CHUNKBITS 15
+#define X86MEM_ADDRESSBITS 20
+#define X86MEM_CHUNKSIZE (1<<X86MEM_CHUNKBITS)
+#define X86MEM_CHUNKS (1<<(X86MEM_ADDRESSBITS-X86MEM_CHUNKBITS))
+#define X86MEM_REGION(addr) (((addr) >> X86MEM_CHUNKBITS) & (X86MEM_CHUNKS-1))
+#define X86MEM_OFFSET(addr) ((addr) & (X86MEM_CHUNKSIZE-1))
+
+#define M_BYTE 1
+#define M_WORD 2
+#define M_DWORD 4
+
+/* *********************************************************************
+ * Structures
+ ********************************************************************* */
+
+typedef struct x86mem_s {
+ uint8_t *data[X86MEM_CHUNKS];
+ uint32_t (*read[X86MEM_CHUNKS])(struct x86mem_s *x86mem,
+ uint32_t addr,int size);
+ void (*write[X86MEM_CHUNKS])(struct x86mem_s *x86mem,
+ uint32_t addr,uint32_t val,int size);
+} x86mem_t;
+
+/* *********************************************************************
+ * Prototypes
+ ********************************************************************* */
+
+void x86mem_init(x86mem_t *mem);
+void x86mem_uninit(x86mem_t *mem);
+
+
+uint8_t x86mem_readb(x86mem_t *mem,uint32_t addr);
+uint16_t x86mem_readw(x86mem_t *mem,uint32_t addr);
+uint32_t x86mem_readl(x86mem_t *mem,uint32_t addr);
+
+
+void x86mem_writeb(x86mem_t *mem,uint32_t addr,uint8_t data);
+void x86mem_writew(x86mem_t *mem,uint32_t addr,uint16_t data);
+void x86mem_writel(x86mem_t *mem,uint32_t addr,uint32_t data);
+void x86mem_memcpy(x86mem_t *mem,uint32_t destaddr,uint8_t *src,int count);
+void x86mem_hook(x86mem_t *mem,uint32_t chunkaddr,
+ uint32_t (*readf)(x86mem_t *mem,uint32_t addr,int size),
+ void (*writef)(x86mem_t *mem,uint32_t addr,uint32_t val,int size));
+void x86mem_hook_range(x86mem_t *mem,uint32_t chunkaddr,int size,
+ uint32_t (*readf)(x86mem_t *mem,uint32_t addr,int size),
+ void (*writef)(x86mem_t *mem,uint32_t addr,uint32_t val,int size));
+