summaryrefslogtreecommitdiff
path: root/payloads/libpayload
diff options
context:
space:
mode:
authorJordan Crouse <jordan.crouse@amd.com>2008-03-19 23:56:58 +0000
committerJordan Crouse <jordan.crouse@amd.com>2008-03-19 23:56:58 +0000
commitf6145c3c15789123f6b4a9ce64a517048e753762 (patch)
tree0d56f31bd3f7051766c03f00d46f40511446aa96 /payloads/libpayload
parentc221349746299537de9e01a0bcfb28485b15ef84 (diff)
libpayload: The initial chunk of code writen by AMD
This is the initial chunk of code written by me and copyrighted by AMD. Includes everything but a few files that we pulled from outside sources. Signed-off-by: Jordan Crouse <jordan.crouse@amd.com> Acked-by: Uwe Hermann <uwe@hermann-uwe.de> git-svn-id: svn://svn.coreboot.org/coreboot/trunk@3170 2b7e53f0-3cfb-0310-b3e9-8179ed1497e1
Diffstat (limited to 'payloads/libpayload')
-rw-r--r--payloads/libpayload/Config.in81
-rw-r--r--payloads/libpayload/Makefile107
-rw-r--r--payloads/libpayload/README7
-rw-r--r--payloads/libpayload/curses/Makefile.inc33
-rw-r--r--payloads/libpayload/curses/colors.c59
-rw-r--r--payloads/libpayload/curses/keyboard.c303
-rw-r--r--payloads/libpayload/curses/local.h94
-rw-r--r--payloads/libpayload/curses/tinycurses.c688
-rw-r--r--payloads/libpayload/drivers/Makefile.inc33
-rw-r--r--payloads/libpayload/drivers/keyboard.c126
-rw-r--r--payloads/libpayload/drivers/serial.c78
-rw-r--r--payloads/libpayload/drivers/vga.c216
-rw-r--r--payloads/libpayload/i386/Makefile.inc31
-rw-r--r--payloads/libpayload/i386/coreboot.c147
-rw-r--r--payloads/libpayload/i386/head.S85
-rw-r--r--payloads/libpayload/i386/main.c79
-rw-r--r--payloads/libpayload/i386/sysinfo.c70
-rw-r--r--payloads/libpayload/i386/timer.c92
-rw-r--r--payloads/libpayload/i386/util.S38
-rw-r--r--payloads/libpayload/include/arch/io.h77
-rw-r--r--payloads/libpayload/include/arch/rdtsc.h40
-rw-r--r--payloads/libpayload/include/arch/types.h57
-rw-r--r--payloads/libpayload/include/coreboot_tables.h151
-rw-r--r--payloads/libpayload/include/libpayload.h99
-rw-r--r--payloads/libpayload/include/sysinfo.h53
-rw-r--r--payloads/libpayload/libc/Makefile.inc32
-rw-r--r--payloads/libpayload/libc/console.c104
-rw-r--r--payloads/libpayload/libc/ctype.c60
-rw-r--r--payloads/libpayload/libc/malloc.c262
-rw-r--r--payloads/libpayload/libc/string.c195
-rw-r--r--payloads/libpayload/libpayload.ldscript90
-rw-r--r--payloads/libpayload/sample/Makefile51
-rw-r--r--payloads/libpayload/sample/hello.c39
33 files changed, 3677 insertions, 0 deletions
diff --git a/payloads/libpayload/Config.in b/payloads/libpayload/Config.in
new file mode 100644
index 0000000000..ffd40b73bf
--- /dev/null
+++ b/payloads/libpayload/Config.in
@@ -0,0 +1,81 @@
+#
+# This file is part of the libpayload project.
+#
+# Copyright (C) 2008 Advanced Micro Devices, Inc.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+# 3. The name of the author may not be used to endorse or promote products
+# derived from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+# FOR ANY 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) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+#
+
+mainmenu "Libpayload Configuration"
+
+config HAVE_DOT_CONFIG
+ bool
+ default y
+
+# When (if) we support multiple architectures,
+# then this will become an option
+
+config TARGET_I386
+ bool
+ default y
+
+menu "Output Options"
+
+config SERIAL_CONSOLE
+ bool "See output on the serial port console"
+ default y
+
+config SERIAL_IOBASE
+ hex "I/O base for the serial port (default 0x3f8)"
+ depends SERIAL_CONSOLE
+ default 0x3f8
+
+config SERIAL_SET_SPEED
+ bool "Override the serial console baud rate"
+ default n
+ depends SERIAL_CONSOLE
+
+config SERIAL_BAUD_RATE
+ int "Serial console baud rate (default 115200)"
+ depends SERIAL_SET_SPEED
+ default 115200
+
+config VGA_CONSOLE
+ bool "See output on a VGA console"
+ default y
+
+config PC_KEYBOARD
+ bool "Allow input from a PC keyboard"
+ depends VGA_CONSOLE
+ default y
+
+endmenu
+
+menu "Build Options"
+
+config TINYCURSES
+ bool "Enable tinycurses support"
+ default y
+
+endmenu
diff --git a/payloads/libpayload/Makefile b/payloads/libpayload/Makefile
new file mode 100644
index 0000000000..f2f87abc53
--- /dev/null
+++ b/payloads/libpayload/Makefile
@@ -0,0 +1,107 @@
+##
+## This file is part of the libpayload project.
+##
+## Copyright (C) 2008 Advanced Micro Devices, Inc.
+##
+## Redistribution and use in source and binary forms, with or without
+## modification, are permitted provided that the following conditions
+## are met:
+## 1. Redistributions of source code must retain the above copyright
+## notice, this list of conditions and the following disclaimer.
+## 2. Redistributions in binary form must reproduce the above copyright
+## notice, this list of conditions and the following disclaimer in the
+## documentation and/or other materials provided with the distribution.
+## 3. The name of the author may not be used to endorse or promote products
+## derived from this software without specific prior written permission.
+##
+## THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+## ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+## FOR ANY 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) ARISING IN ANY WAY
+## OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+## SUCH DAMAGE.
+##
+
+BASE_DIR=$(shell pwd)
+KCONFIG_DIR=util/kconfig
+
+ifeq (.config, $(wildcard .config))
+dot-config := 1
+else
+dot-config := 0
+config-targets := 1
+endif
+
+ifneq ($(filter textconfig oldconfig defconfig menuconfig,$(MAKECMDGOALS)),)
+config-targets := 1
+dot-config := 0
+endif
+
+ifeq ($(dot-config),0)
+all: .config
+
+.config: oldconfig
+ @echo "Configuration completed - type make to build libpayload"
+else
+-include .config
+endif
+
+PLATFORM-$(CONFIG_TARGET_I386) += i386/Makefile.inc
+TARGETS-y :=
+
+BUILD-y := libc/Makefile.inc drivers/Makefile.inc
+BUILD-$(CONFIG_TINYCURSES) += curses/Makefile.inc
+
+include $(PLATFORM-y) $(BUILD-y)
+
+INCLUDES := -I./include
+INCLUDES += -I$(shell $(CC) -print-search-dirs | head -n 1 | cut -d' ' -f2)include
+CFLAGS := -Werror -fno-stack-protector -nostdinc $(INCLUDES)
+
+libpayload.a: $(TARGETS-y)
+ $(AR) rc $@ $(TARGETS-y)
+
+%.o: %.c
+ $(CC) -m32 $(CFLAGS) -c -o $@ $<
+
+%.o: %.S
+ $(AS) --32 -o $@ $<
+
+clean:
+ @ rm -f $(TARGETS-y)
+ @ rm -f libpayload.a
+
+distclean: clean
+ @ make -C $(KCONFIG_DIR) clean
+ @ rm -f $(KCONFIG_DIR)/lxdialog/lxdialog
+ @ rm -f .config .kconfig.d include/autoconf.h
+
+ifeq ($(config-targets),1)
+
+$(KCONFIG_DIR)/conf:
+ make -C $(KCONFIG_DIR) conf
+
+$(KCONFIG_DIR)/mconf:
+ make -C $(KCONFIG_DIR) mconf
+
+$(KCONFIG_DIR)/lxdialog/lxdialog:
+ make -C $(KCONFIG_DIR)/lxdialog lxdialog
+
+textconfig: $(KCONFIG_DIR)/conf
+ @$(KCONFIG_DIR)/conf $(BASE_DIR)/Config.in
+
+oldconfig: $(KCONFIG_DIR)/conf
+ @$(KCONFIG_DIR)/conf -o $(BASE_DIR)/Config.in
+
+defconfig: $(KCONFIG_DIR)/conf
+ @$(KCONFIG_DIR)/conf -d $(BASE_DIR)/Config.in
+
+menuconfig: $(KCONFIG_DIR)/lxdialog/lxdialog $(KCONFIG_DIR)/mconf
+ @$(KCONFIG_DIR)/mconf $(BASE_DIR)/Config.in
+
+endif
diff --git a/payloads/libpayload/README b/payloads/libpayload/README
new file mode 100644
index 0000000000..7f35fc4e07
--- /dev/null
+++ b/payloads/libpayload/README
@@ -0,0 +1,7 @@
+This is libpayload, a minimal library to support standalone payloads
+that can be booted with firmware like coreboot. It handles the setup
+code, and provides common C library symbols such as malloc() and
+printf().
+
+Please see the sample/ directory for an example of the payload in
+action.
diff --git a/payloads/libpayload/curses/Makefile.inc b/payloads/libpayload/curses/Makefile.inc
new file mode 100644
index 0000000000..29c7801755
--- /dev/null
+++ b/payloads/libpayload/curses/Makefile.inc
@@ -0,0 +1,33 @@
+#
+# This file is part of the libpayload project.
+#
+# Copyright (C) 2008 Advanced Micro Devices, Inc.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+# 3. The name of the author may not be used to endorse or promote products
+# derived from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+# FOR ANY 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) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+#
+
+TARGETS-$(CONFIG_TINYCURSES) += curses/keyboard.o
+TARGETS-$(CONFIG_TINYCURSES) += curses/tinycurses.o
+TARGETS-$(CONFIG_TINYCURSES) += curses/speaker.o
+TARGETS-$(CONFIG_TINYCURSES) += curses/colors.o
diff --git a/payloads/libpayload/curses/colors.c b/payloads/libpayload/curses/colors.c
new file mode 100644
index 0000000000..045df83ba3
--- /dev/null
+++ b/payloads/libpayload/curses/colors.c
@@ -0,0 +1,59 @@
+/*
+ * This file is part of the libpayload project.
+ *
+ * Copyright (C) 2007 Uwe Hermann <uwe@hermann-uwe.de>
+ * Copyright (C) 2008 Advanced Micro Devices, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY 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) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/* Color pair management */
+
+#include "local.h"
+
+unsigned char color_pairs[256] = {
+ [0] = 0x07,
+};
+
+int start_color(void) {
+ return 0;
+}
+
+int init_pair(short index, short fg, short bg)
+{
+ if (index == 0 || index > 255)
+ return ERR;
+
+ color_pairs[index] = ((bg & 0xF) << 4) | (fg & 0xF);
+ return 0;
+}
+
+int pair_content(short index, short *fg, short *bg)
+{
+ if (index < 0 || index > 255)
+ return ERR;
+
+ *bg = (color_pairs[index] >> 4) & 0xF;
+ *fg = color_pairs[index] & 0xF;
+}
diff --git a/payloads/libpayload/curses/keyboard.c b/payloads/libpayload/curses/keyboard.c
new file mode 100644
index 0000000000..6ab5dd0cf7
--- /dev/null
+++ b/payloads/libpayload/curses/keyboard.c
@@ -0,0 +1,303 @@
+/*
+ * This file is part of the libpayload project.
+ *
+ * Copyright (C) 2007 Uwe Hermann <uwe@hermann-uwe.de>
+ * Copyright (C) 2008 Advanced Micro Devices, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY 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) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * This file handles reading keystrokes from serial and the console
+ * and "cooking" them so that they are correct for curses.
+ * Also, implement key related functions (mainly wgetch)
+ *
+ * TODO:
+ * Actually cook the serial (handle special keys)
+ */
+
+#include "local.h"
+
+/* ============== Serial ==================== */
+
+/* FIXME: Cook the serial correctly */
+
+static int cook_serial(unsigned char ch)
+{
+ return (int) ch;
+}
+
+/* ================ Keyboard ================ */
+
+/* Scancode macros */
+
+#define DOWN(_c) (0x80 | (_c))
+#define UP(_c) (_c)
+
+#define ISDOWN(_c) ((_c) & 0x80)
+#define ISUP(_c) (!ISDOWN((_c)))
+
+#define SCANCODE(_c) ((_c) & ~0x80)
+
+/* Scancode definitions for the modifiers */
+
+#define SCANCODE_RSHIFT 0x36
+#define SCANCODE_LSHIFT 0x2a
+#define SCANCODE_CAPSLOCK 0x3a
+#define SCANCODE_LALT 0x38
+#define SCANCODE_LCTRL 0x1d
+
+/* Modifier flags */
+
+#define SHIFT_MODIFIER 0x1
+#define CAPSLOCK_MODIFIER 0x2
+#define ALT_MODIFIER 0x4
+#define CTRL_MODIFIER 0x8
+
+#define CTRL(_c) (_c & 0x1f)
+
+struct {
+ int normal;
+ int shift;
+} scancode_map[] = {
+ { },
+ { CTRL('['), CTRL('[')},
+ { '1', '!' },
+ { '2', '@' },
+ { '3', '#' },
+ { '4', '$' },
+ { '5', '%' },
+ { '6', '^' },
+ { '7', '&' },
+ { '8', '*' },
+ { '9', '(' },
+ { '0', ')' },
+ { '-', '_' },
+ { '=', '+' },
+ { KEY_BACKSPACE, KEY_BACKSPACE},
+ { CTRL('I' ), KEY_BTAB }, /* 0x0F */
+ { 'q', 'Q' },
+ { 'w', 'W' },
+ { 'e', 'E' },
+ { 'r', 'R' },
+ { 't', 'T' },
+ { 'y', 'Y' },
+ { 'u', 'U' },
+ { 'i', 'I' },
+ { 'o', 'O' },
+ { 'p', 'P' },
+ { '[', '{' },
+ { ']', '{' },
+ { KEY_ENTER, KEY_ENTER },
+ { 0 , 0 },
+ { 'a', 'A' },
+ { 's', 'S' }, /* 0x1F */
+ { 'd', 'D' },
+ { 'f', 'F' },
+ { 'g', 'G' },
+ { 'h', 'H' },
+ { 'j', 'J' },
+ { 'k', 'K' },
+ { 'l', 'L' },
+ { ';', ':' },
+ { '\'', '\"' },
+ { '`', '~', },
+ { 0, 0 },
+ { '\\', '|' },
+ { 'z', 'Z' },
+ { 'x', 'X' },
+ { 'c', 'C' },
+ { 'v', 'V' }, /* 0x2F */
+ { 'b', 'B' },
+ { 'n', 'N' },
+ { 'm', 'M' },
+ { ',', '<'},
+ { '.', '>' },
+ { '/', '?' },
+ { 0, 0 }, /* RSHIFT */
+ { '*', '*' },
+ { 0, 0 }, /* LALT */
+ { ' ', ' ' }, /* Space */
+ { 0, 0 }, /* Capslock */
+ { KEY_F(1), KEY_F(1) },
+ { KEY_F(2), KEY_F(2) },
+ { KEY_F(3), KEY_F(3) },
+ { KEY_F(4), KEY_F(4) },
+ { KEY_F(5), KEY_F(5) }, /* 0x3F */
+ { KEY_F(6), KEY_F(6) },
+ { KEY_F(7), KEY_F(7) },
+ { KEY_F(8), KEY_F(8) },
+ { KEY_F(9), KEY_F(9) },
+ { KEY_F(10), KEY_F(10) },
+ { 0, 0 }, /* Numlock */
+ { 0, 0 }, /* Scroll lock */
+ { KEY_HOME, KEY_HOME },
+ { KEY_UP, KEY_UP },
+ { KEY_PPAGE, KEY_PPAGE },
+ { '-', '-' },
+ { KEY_LEFT, KEY_LEFT },
+ { 0, 0 },
+ { KEY_RIGHT, KEY_RIGHT },
+ { '-', '-' },
+ { KEY_END, KEY_END }, /* 0x4F */
+ { KEY_DOWN, KEY_DOWN },
+ { KEY_NPAGE, KEY_NPAGE },
+ { KEY_IC, KEY_IC },
+ { KEY_DC, KEY_DC },
+ { 0, 0 }, /* sysreq */
+ { 0, 0 },
+ { KEY_F(11), KEY_F(11) },
+ { KEY_F(12), KEY_F(12) },
+};
+
+static int cook_scancodes(unsigned char code)
+{
+ static int modifiers = 0;
+ int ch = 0, sc, shift;
+
+ switch(code) {
+ case DOWN(SCANCODE_RSHIFT):
+ case DOWN(SCANCODE_LSHIFT):
+ modifiers |= SHIFT_MODIFIER;
+ return 0;
+
+ case UP(SCANCODE_RSHIFT):
+ case UP(SCANCODE_LSHIFT):
+ modifiers &= ~SHIFT_MODIFIER;
+ return 0;
+
+ case UP(SCANCODE_CAPSLOCK):
+ if (modifiers & CAPSLOCK_MODIFIER)
+ modifiers &= ~CAPSLOCK_MODIFIER;
+ else
+ modifiers |= CAPSLOCK_MODIFIER;
+ return 0;
+
+ case DOWN(SCANCODE_LALT):
+ modifiers |= ALT_MODIFIER;
+ return 0;
+
+ case UP(SCANCODE_LALT):
+ modifiers &= ~ALT_MODIFIER;
+ return 0;
+
+ case DOWN(SCANCODE_LCTRL):
+ modifiers |= CTRL_MODIFIER;
+ return 0;
+
+ case UP(SCANCODE_LCTRL):
+ modifiers &= ~CTRL_MODIFIER;
+ return 0;
+ }
+
+ /* Only process keys on an upstroke */
+
+ if (!ISUP(code))
+ return 0;
+
+ sc = SCANCODE(code);
+
+ if (sc == 0 || sc > 0x59)
+ return ERR;
+
+ shift = (modifiers & SHIFT_MODIFIER) ^ (modifiers & CAPSLOCK_MODIFIER);
+
+ ch = shift ? scancode_map[sc].shift : scancode_map[sc].normal;
+
+ if (modifiers & CTRL_MODIFIER)
+ ch = (ch >= 0x3F && ch <= 0x5F) ? CTRL(ch) : 0;
+
+ return ch;
+}
+
+static int curses_getchar(int delay) {
+
+ unsigned char c = 0;
+ int ret;
+
+ do {
+ if (curses_flags & F_ENABLE_CONSOLE)
+ c = inb(0x64);
+
+ if ((c & 1) == 0) {
+
+ if ((curses_flags & F_ENABLE_SERIAL) &&
+ serial_havechar()) {
+ c = serial_getchar();
+ return cook_serial(c);
+ }
+
+ if (!delay)
+ break;
+ }
+
+ c = inb(0x60);
+
+ ret = cook_scancodes(c);
+
+ if (ret != 0) {
+ return ret;
+ }
+
+ } while(1);
+
+ return ERR;
+}
+
+/* === Public functions === */
+
+int wgetch(WINDOW *win)
+{
+ return curses_getchar(win->_delay);
+}
+
+int nodelay(WINDOW *win, NCURSES_BOOL flag)
+{
+ win->_delay = flag ? 0 : -1;
+}
+
+#ifdef CONFIG_VGA_CONSOLE
+void curses_enable_vga(int state)
+{
+ if (state)
+ curses_flags |= F_ENABLE_CONSOLE;
+ else
+ curses_flags &= ~F_ENABLE_CONSOLE;
+}
+#else
+void curses_enable_vga(int state) { }
+#endif
+
+#ifdef CONFIG_SERIAL_CONSOLE
+void curses_enable_serial(int state)
+{
+ if (state)
+ curses_flags |= F_ENABLE_SERIAL;
+ else
+ curses_flags &= ~F_ENABLE_SERIAL;
+}
+#else
+void curses_enable_serial(int state) { }
+#endif
+
diff --git a/payloads/libpayload/curses/local.h b/payloads/libpayload/curses/local.h
new file mode 100644
index 0000000000..577fcd4000
--- /dev/null
+++ b/payloads/libpayload/curses/local.h
@@ -0,0 +1,94 @@
+/*
+ * This file is part of the libpayload project.
+ *
+ * Copyright (C) 2007 Uwe Hermann <uwe@hermann-uwe.de>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY 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) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef TINYCURSES_H
+#define TINYCURSES_H
+
+/* For curses.priv.h: */
+#define USE_RCS_IDS 0
+#define DECL_ERRNO 0
+#define HAVE_LIBGPM 0
+#define NCURSES_EXT_FUNCS 0
+#define USE_OK_BCOPY 0
+#define USE_MY_MEMMOVE 0
+#define USE_SCROLL_HINTS 0
+#define USE_HASHMAP 0
+#define USE_WIDEC_SUPPORT 0 /* We do _not_ want wide character support. */
+// #define NCURSES_EXT_COLORS 1
+#define NCURSES_EXT_COLORS 0
+#define USE_SYSMOUSE 0
+#define NCURSES_NO_PADDING 0
+#define USE_HARD_TABS 0
+#define HAVE_FCNTL_H 0
+#define USE_XMC_SUPPORT 0
+#define NCURSES_EXPANDED 0
+#define HAVE_GETCWD 0
+#define USE_XMC_SUPPORT 0
+#define HAVE_STRSTR 0
+#define NO_LEAKS 0
+#define HAVE_RESIZETERM 0
+#define HAVE_VSSCANF 0
+#define BROKEN_LINKER 0
+
+#undef USE_TERMLIB
+
+#include <libpayload.h>
+#include <arch/types.h>
+#include <arch/io.h>
+#include <curses.h>
+#include <curses.priv.h>
+
+#define SCREEN_X 80
+#define SCREEN_Y 25
+
+/* Flags used to determine what output methods are available */
+
+#ifdef CONFIG_VGA_CONSOLE
+#define F_ENABLE_CONSOLE 0x01
+#else
+#define F_ENABLE_CONSOLE 0x00
+#endif
+
+#ifdef CONFIG_SERIAL_CONSOLE
+#define F_ENABLE_SERIAL 0x02
+#else
+#define F_ENABLE_SERIAL 0x00
+#endif
+
+extern int curses_flags;
+
+/* Share the color table for easy lookup */
+extern unsigned char color_pairs[256];
+
+/* speaker.c */
+void speaker_enable(u16 freq);
+void speaker_disable(void);
+void speaker_tone(u16 freq, unsigned int duration);
+
+#endif /* TINYCURSES_H */
diff --git a/payloads/libpayload/curses/tinycurses.c b/payloads/libpayload/curses/tinycurses.c
new file mode 100644
index 0000000000..dc6b77818b
--- /dev/null
+++ b/payloads/libpayload/curses/tinycurses.c
@@ -0,0 +1,688 @@
+/*
+ * This file is part of the libpayload project.
+ *
+ * Copyright (C) 2007 Uwe Hermann <uwe@hermann-uwe.de>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY 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) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * This is a tiny implementation of the (n)curses library intended to be
+ * used in embedded/firmware/BIOS code where no libc or operating system
+ * environment is available and code size is very important.
+ *
+ * Design goals:
+ * - Small object code.
+ * - Self-contained.
+ * - Doesn't require a libc (no glibc/uclibc/dietlibc/klibc/newlib).
+ * - Works without any other external libraries or header files.
+ * - Works without an underlying operating system.
+ * - Doesn't use files, signals, syscalls, ttys, library calls, etc.
+ * - Doesn't do any dynamic memory allocation (no malloc() and friends).
+ * - All data structures are statically allocated.
+ * - Supports standard VGA console (80x25) and serial port console.
+ * - This includes character output and keyboard input over serial.
+ * - Supports beep() through a minimal PC speaker driver.
+ *
+ * Limitations:
+ * - Only implements a small subset of the (n)curses functions.
+ * - Only implements very few sanity checks (for smaller code).
+ * - Thus: Don't do obviously stupid things in your code.
+ * - Doesn't implement the 'form', 'panel', and 'menu' extentions.
+ * - Only implements C bindings (no C++, Ada95, or others).
+ * - Doesn't include wide character support.
+ */
+
+#include "local.h"
+
+#undef _XOPEN_SOURCE_EXTENDED
+#define _XOPEN_SOURCE_EXTENDED 1
+
+#define MAX_WINDOWS 3
+
+/* Statically allocate all structures (no malloc())! */
+static WINDOW window_list[MAX_WINDOWS];
+static int window_count = 1;
+
+// struct ldat foo;
+static struct ldat ldat_list[3];
+static int ldat_count = 0;
+
+/* One item bigger than SCREEN_X to reverse place for a NUL byte. */
+static NCURSES_CH_T linebuf_list[SCREEN_Y * MAX_WINDOWS][SCREEN_X + 1];
+static int linebuf_count = 0;
+
+/* Globals */
+int COLORS; /* Currently unused? */
+int COLOR_PAIRS;
+WINDOW *stdscr;
+WINDOW *curscr;
+WINDOW *newscr;
+int LINES;
+int COLS;
+int TABSIZE;
+int ESCDELAY;
+// char ttytype[];
+// cchar_t *_nc_wacs;
+SCREEN *SP;
+chtype acs_map[128];
+
+// FIXME: Ugly (and insecure!) hack!
+char sprintf_tmp[1024];
+
+
+int curses_flags = (F_ENABLE_CONSOLE | F_ENABLE_SERIAL);
+
+/* Return bit mask for clearing color pair number if given ch has color */
+#define COLOR_MASK(ch) (~(attr_t)((ch) & A_COLOR ? A_COLOR : 0))
+
+/* Compute a rendition of the given char correct for the current context. */
+static inline NCURSES_CH_T render_char(WINDOW *win, NCURSES_CH_T ch)
+{
+ /* TODO. */
+ return ch;
+}
+
+/* Make render_char() visible while still allowing us to inline it below. */
+NCURSES_CH_T _nc_render(WINDOW *win, NCURSES_CH_T ch)
+{
+ return render_char(win, ch);
+}
+
+/*
+ * Implementations of most functions marked 'implemented' in tinycurses.h:
+ */
+
+// int baudrate(void) {}
+int beep(void)
+{
+ /* TODO: Flash the screen if beeping fails? */
+ speaker_tone(1760, 500); /* 1760 == note A6 */
+ return OK;
+}
+// bool can_change_color(void) {}
+int cbreak(void) { /* TODO */ return 0; }
+/* D */ int clearok(WINDOW *win, bool flag) { win->_clear = flag; return OK; }
+// int color_content(short color, short *r, short *g, short *b) {}
+// int curs_set(int) {}
+// int def_prog_mode(void) {}
+// int def_shell_mode(void) {}
+// int delay_output(int) {}
+// void delscreen(SCREEN *) {}
+int delwin(WINDOW *win)
+{
+ /* TODO: Don't try to delete stdscr. */
+ /* TODO: Don't delete parent windows before subwindows. */
+
+ // if (win->_flags & _SUBWIN)
+ // touchwin(win->_parent);
+ // else if (curscr != 0)
+ // touchwin(curscr);
+
+ // return _nc_freewin(win);
+ return OK;
+}
+WINDOW *derwin(WINDOW *orig, int num_lines, int num_columns, int begy, int begx)
+{
+ WINDOW *win;
+ int i;
+ int flags = _SUBWIN;
+
+ /* Make sure window fits inside the original one. */
+ if (begy < 0 || begx < 0 || orig == 0 || num_lines < 0 || num_columns < 0)
+ return NULL;
+ if (begy + num_lines > orig->_maxy + 1
+ || begx + num_columns > orig->_maxx + 1)
+ return NULL;
+
+ if (num_lines == 0)
+ num_lines = orig->_maxy + 1 - begy;
+
+ if (num_columns == 0)
+ num_columns = orig->_maxx + 1 - begx;
+
+ if (orig->_flags & _ISPAD)
+ flags |= _ISPAD;
+
+ //// if ((win = _nc_makenew(num_lines, num_columns, orig->_begy + begy,
+ //// orig->_begx + begx, flags)) == 0)
+ //// return NULL;
+
+ win->_pary = begy;
+ win->_parx = begx;
+ WINDOW_ATTRS(win) = WINDOW_ATTRS(orig);
+ win->_nc_bkgd = orig->_nc_bkgd;
+
+ for (i = 0; i < num_lines; i++)
+ win->_line[i].text = &orig->_line[begy++].text[begx];
+
+ win->_parent = orig;
+
+ return win;
+}
+int doupdate(void) { /* TODO */ return(*(int *)0); }
+// WINDOW * dupwin (WINDOW *) {}
+/* D */ int echo(void) { SP->_echo = TRUE; return OK; }
+int endwin(void)
+{
+ if (!SP)
+ return ERR;
+
+ SP->_endwin = TRUE;
+ SP->_mouse_wrap(SP);
+ // _nc_screen_wrap();
+ // _nc_mvcur_wrap(); /* wrap up cursor addressing */
+ // return reset_shell_mode();
+ return OK; // FIXME
+}
+// char erasechar (void) {}
+// void filter (void) {}
+// int flash(void) {}
+// int flushinp (void) {}
+// WINDOW *getwin (FILE *) {}
+
+bool has_colors (void) { /* TODO */ return(*(bool *)0); }
+// bool has_ic (void) {}
+// bool has_il (void) {}
+// void idcok (WINDOW *, bool) {}
+// int idlok (WINDOW *, bool) {}
+void immedok(WINDOW *win, bool flag) { win->_immed = flag; }
+/** Note: Must _not_ be called twice! */
+WINDOW *initscr(void)
+{
+ int x, y;
+
+ // newterm(name, stdout, stdin);
+ // def_prog_mode();
+
+ if (curses_flags & F_ENABLE_CONSOLE) {
+
+ /* Clear the screen and kill the cursor */
+
+ vga_clear();
+ vga_cursor_enable(0);
+ }
+
+ // Speaker init?
+
+ stdscr = newwin(SCREEN_Y, SCREEN_X + 1, 0, 0);
+ // TODO: curscr, newscr?
+
+ for (y = 0; y < stdscr->_maxy; y++) {
+ for (x = 0; x < stdscr->_maxx; x++) {
+ stdscr->_line[y].text[x].chars[0] = ' ';
+ stdscr->_line[y].text[x].attr = A_NORMAL;
+ }
+ }
+
+ return stdscr;
+}
+
+// int intrflush (WINDOW *,bool) {}
+/* D */ bool isendwin(void) { return ((SP == NULL) ? FALSE : SP->_endwin); }
+// bool is_linetouched (WINDOW *,int) {}
+// bool is_wintouched (WINDOW *) {}
+// NCURSES_CONST char * keyname (int) {}
+int keypad (WINDOW *win, bool flag) { /* TODO */ return 0; }
+// char killchar (void) {}
+/* D */ int leaveok(WINDOW *win, bool flag) { win->_leaveok = flag; return OK; }
+// char *longname (void) {}
+// int meta (WINDOW *,bool) {}
+// int mvcur (int,int,int,int) {}
+// int mvderwin (WINDOW *, int, int) {}
+int mvprintw(int y, int x, const char *fmt, ...)
+{
+ va_list argp;
+ int code;
+
+ if (move(y, x) == ERR)
+ return ERR;
+
+ va_start(argp, fmt);
+ code = vwprintw(stdscr, fmt, argp);
+ va_end(argp);
+
+ return code;
+}
+// int mvscanw (int,int, NCURSES_CONST char *,...) {}
+// int mvwin (WINDOW *,int,int) {}
+int mvwprintw(WINDOW *win, int y, int x, const char *fmt, ...)
+{
+ va_list argp;
+ int code;
+
+ if (wmove(win, y, x) == ERR)
+ return ERR;
+
+ va_start(argp, fmt);
+ code = vwprintw(win, fmt, argp);
+ va_end(argp);
+
+ return code;
+}
+// int mvwscanw (WINDOW *,int,int, NCURSES_CONST char *,...) {}
+// int napms (int) {}
+// WINDOW *newpad (int,int) {}
+// SCREEN *newterm (NCURSES_CONST char *,FILE *,FILE *) {}
+WINDOW *newwin(int num_lines, int num_columns, int begy, int begx)
+{
+ int i;
+
+ /* Use next statically allocated window. */
+ // TODO: Error handling.
+ // TODO: WINDOWLIST?
+ WINDOW *win = &window_list[window_count++];
+
+ // bool is_pad = (flags & _ISPAD);
+
+ // TODO: Checks.
+
+ win->_cury = 0;
+ win->_curx = 0;
+ win->_maxy = num_lines - 1;
+ win->_maxx = num_columns - 1;
+ win->_begy = begy;
+ win->_begx = begx;
+ // win->_yoffset = SP->_topstolen;
+
+ win->_line = &ldat_list[ldat_count++];
+
+ /* FIXME: Is this right? Should the window attributes be normal? */
+ win->_color - PAIR_NUMBER(0);
+ win->_attrs = A_NORMAL;
+
+ for (i = 0; i < num_lines; i++)
+ win->_line[i].text = (NCURSES_CH_T *)&linebuf_list[linebuf_count++];
+
+ return win;
+}
+/* D */ int nl(void) { SP->_nl = TRUE; return OK; }
+int nocbreak(void) { /* TODO */ return(*(int *)0); }
+
+/* D */ int noecho(void) { SP->_echo = FALSE; return OK; }
+/* D */ int nonl(void) { SP->_nl = FALSE; return OK; }
+// void noqiflush (void) {}
+// int noraw (void) {}
+// int notimeout (WINDOW *,bool) {}
+// int overlay (const WINDOW*,WINDOW *) {}
+// int overwrite (const WINDOW*,WINDOW *) {}
+// int pair_content (short,short*,short*) {}
+// int pechochar (WINDOW *, const chtype) {}
+// int pnoutrefresh (WINDOW*,int,int,int,int,int,int) {}
+// int prefresh (WINDOW *,int,int,int,int,int,int) {}
+int printw(const char *fmt, ...)
+{
+ va_list argp;
+ int code;
+
+ va_start(argp, fmt);
+ code = vwprintw(stdscr, fmt, argp);
+ va_end(argp);
+
+ return code;
+}
+// int putwin (WINDOW *, FILE *) {}
+// void qiflush (void) {}
+// int raw (void) {}
+// int resetty (void) {}
+// int reset_prog_mode (void) {}
+// int reset_shell_mode (void) {}
+// int ripoffline (int, int (*)(WINDOW *, int)) {}
+// int savetty (void) {}
+// int scanw (NCURSES_CONST char *,...) {}
+// int scr_dump (const char *) {}
+// int scr_init (const char *) {}
+/* D */ int scrollok(WINDOW *win, bool flag) { win->_scroll = flag; return OK; }
+// int scr_restore (const char *) {}
+// int scr_set (const char *) {}
+// SCREEN *set_term (SCREEN *) {}
+// int slk_attroff (const chtype) {}
+// int slk_attron (const chtype) {}
+// int slk_attrset (const chtype) {}
+// attr_t slk_attr (void) {}
+// int slk_attr_set (const attr_t,short,void*) {}
+// int slk_clear (void) {}
+// int slk_color (short) {}
+// int slk_init (int) {}
+/* D */ char *slk_label(int n)
+{
+ // TODO: Needed?
+ // if (SP == NULL || SP->_slk == NULL || n < 1 || n > SP->_slk->labcnt)
+ // return NULL;
+ return SP->_slk->ent[n - 1].ent_text;
+}
+// int slk_noutrefresh (void) {}
+// int slk_refresh (void) {}
+// int slk_restore (void) {}
+// int slk_set (int,const char *,int) {}
+// int slk_touch (void) {}
+
+// WINDOW *subpad (WINDOW *, int, int, int, int) {}
+WINDOW *subwin(WINDOW *w, int l, int c, int y, int x)
+{
+ return derwin(w, l, c, y - w->_begy, x - w->_begx);
+}
+// int syncok (WINDOW *, bool) {}
+// chtype termattrs (void) {}
+// char *termname (void) {}
+// int typeahead (int) {}
+int ungetch(int ch) { /* TODO */ return ERR; }
+// void use_env (bool) {}
+// int vidattr (chtype) {}
+// int vidputs (chtype, int (*)(int)) {}
+int vwprintw(WINDOW *win, const char *fmt, va_list argp)
+{
+ vsprintf((char *)&sprintf_tmp, fmt, argp);
+
+ /* TODO: Error handling? */
+ return waddstr(win, (char *)&sprintf_tmp);
+}
+// int vwscanw (WINDOW *, NCURSES_CONST char *,va_list) {}
+// int waddch (WINDOW *, const chtype) {}
+int waddch(WINDOW *win, const chtype ch)
+{
+ int code = ERR;
+ // NCURSES_CH_T wch;
+ // SetChar2(wch, ch);
+
+ win->_line[win->_cury].text[win->_curx].chars[0] = ch;
+
+ /* Use the window attributes - perhaps we also pull attributes from
+ the ch itself, I don't know */
+
+ win->_line[win->_cury].text[win->_curx].attr = WINDOW_ATTRS(win);
+ win->_curx++; // FIXME
+
+ // if (win && (waddch_nosync(win, wch) != ERR)) {
+ // _nc_synchook(win);
+ // code = OK;
+ // }
+
+ return code;
+}
+// int waddchnstr (WINDOW *,const chtype *,int) {}
+int waddnstr(WINDOW *win, const char *astr, int n)
+{
+ int code = OK;
+ const char *str = astr;
+
+ if (!str)
+ return ERR;
+
+ if (n < 0)
+ n = strlen(astr);
+
+ while ((n-- > 0) && (*str != '\0')) {
+ // while (*str != '\0') {
+ win->_line[win->_cury].text[win->_curx].chars[0] = *str++;
+ win->_line[win->_cury].text[win->_curx].attr = WINDOW_ATTRS(win)
+;
+ win->_curx++; // FIXME
+
+ // NCURSES_CH_T ch;
+ // SetChar(ch, UChar(*str++), A_NORMAL);
+ // if (_nc_waddch_nosync(win, ch) == ERR) {
+ // code = ERR;
+ // break;
+ // }
+ }
+ return code;
+}
+int wattr_on(WINDOW *win, attr_t at, void *opts GCC_UNUSED)
+{
+ if (at & A_COLOR)
+ win->_color = PAIR_NUMBER(at);
+ // toggle_attr_on(WINDOW_ATTRS(win), at);
+ return OK;
+}
+int wattr_off(WINDOW *win, attr_t at, void *opts GCC_UNUSED)
+{
+ if (at & A_COLOR)
+ win->_color = 0;
+ // toggle_attr_off(WINDOW_ATTRS(win), at);
+ return 0;
+}
+// int wbkgd (WINDOW *, chtype) {}
+void wbkgdset(WINDOW *win, chtype ch) { /* TODO */ }
+// int wborder (WINDOW *,chtype,chtype,chtype,chtype,chtype,chtype,chtype,chtype) {}
+// int wchgat (WINDOW *, int, attr_t, short, const void *) {}
+/* D */ int wclear(WINDOW *win)
+{
+ if (werase(win) == ERR)
+ return ERR;
+ win->_clear = TRUE;
+ return OK;
+}
+// int wclrtobot (WINDOW *) {}
+int wclrtoeol(WINDOW *win) { /* TODO */ return(*(int *)0); }
+int wcolor_set(WINDOW *win, short color_pair_number, void *opts)
+{
+ if (!opts && (color_pair_number >= 0)
+ && (color_pair_number < COLOR_PAIRS)) {
+ SET_WINDOW_PAIR(win, color_pair_number);
+ if_EXT_COLORS(win->_color = color_pair_number);
+ return OK;
+ }
+ return ERR;
+}
+// void wcursyncup (WINDOW *) {}
+// int wdelch (WINDOW *) {}
+// int wechochar (WINDOW *, const chtype) {}
+int werase(WINDOW *win)
+{
+ int x, y;
+ for (y = 0; y < win->_maxy; y++) {
+ for (x = 0; x < win->_maxx; x++) {
+ win->_line[y].text[x].chars[0] = ' ';
+ win->_line[y].text[x].attr = WINDOW_ATTRS(win);
+ }
+ }
+ return OK;
+}
+
+// int wgetnstr (WINDOW *,char *,int) {}
+int whline(WINDOW *win, chtype ch, int n)
+{
+ NCURSES_SIZE_T start, end;
+ struct ldat *line = &(win->_line[win->_cury]);
+ NCURSES_CH_T wch;
+
+ start = win->_curx;
+ end = start + n - 1;
+ if (end > win->_maxx)
+ end = win->_maxx;
+
+ CHANGED_RANGE(line, start, end);
+
+ //// TODO:
+ //// if (ch == 0)
+ //// SetChar2(wch, ACS_HLINE);
+ //// else
+ //// SetChar2(wch, ch);
+ // Ugly hack:
+ wch.chars[0] = ((ch) & (chtype)A_CHARTEXT);
+ wch.attr = ((ch) & (chtype)A_ATTRIBUTES);
+ wch = _nc_render(win, wch);
+
+ while (end >= start) {
+ line->text[end] = wch;
+ end--;
+ }
+
+ //// _nc_synchook(win);
+
+ return OK;
+}
+/* D */ chtype winch(WINDOW *win)
+{
+ //// TODO
+ // return (CharOf(win->_line[win->_cury].text[win->_curx]) |
+ // AttrOf(win->_line[win->_cury].text[win->_curx]));
+ return OK; // FIXME
+}
+// int winchnstr (WINDOW *, chtype *, int) {}
+// int winnstr (WINDOW *, char *, int) {}
+// int winsch (WINDOW *, chtype) {}
+// int winsdelln (WINDOW *,int) {}
+// int winsnstr (WINDOW *, const char *,int) {}
+/* D */ int wmove(WINDOW *win, int y, int x)
+{
+ if (!LEGALYX(win, y, x))
+ return ERR;
+ win->_curx = (NCURSES_SIZE_T) x;
+ win->_cury = (NCURSES_SIZE_T) y;
+ win->_flags &= ~_WRAPPED;
+ win->_flags |= _HASMOVED;
+ return OK;
+}
+
+
+int wnoutrefresh(WINDOW *win)
+{
+ // FIXME.
+ int x, y;
+
+ for (y = 0; y < win->_maxy; y++) {
+ for (x = 0; x < win->_maxx; x++) {
+ if (curses_flags & F_ENABLE_SERIAL)
+ serial_putchar(win->_line[y].text[x].chars[0]);
+
+ if (curses_flags & F_ENABLE_CONSOLE) {
+ attr_t attr = win->_line[y].text[x].attr;
+ unsigned int c = ((int) color_pairs[PAIR_NUMBER(attr)]) << 8;
+
+ /* Handle some of the attributes */
+
+ if (attr & A_BOLD) {
+ c |= 0x0800;
+ }
+ if (attr & A_DIM) {
+ c &= ~0x800;
+ }
+ if (attr & A_REVERSE) {
+ unsigned char tmp = (c >> 8) & 0xF;
+ c = (c >> 4) & 0xF00;
+ c |= tmp << 12;
+ }
+
+ c |= win->_line[y].text[x].chars[0];
+
+
+ vga_putc(y, x, c);
+ }
+ }
+ }
+
+ return OK;
+}
+
+int wprintw(WINDOW *win, const char *fmt, ...)
+{
+ va_list argp;
+ int code;
+
+ va_start(argp, fmt);
+ code = vwprintw(win, fmt, argp);
+ va_end(argp);
+
+ return code;
+}
+// int wredrawln (WINDOW *,int,int) {}
+int wrefresh(WINDOW *win)
+{
+ // FIXME
+ return wnoutrefresh(win);
+
+ // XXX
+ int code;
+
+ if (win == curscr) {
+ curscr->_clear = TRUE;
+ // code = doupdate();
+ } else if ((code = wnoutrefresh(win)) == OK) {
+ if (win->_clear)
+ newscr->_clear = TRUE;
+ // code = doupdate();
+ /*
+ * Reset the clearok() flag in case it was set for the special
+ * case in hardscroll.c (if we don't reset it here, we'll get 2
+ * refreshes because the flag is copied from stdscr to newscr).
+ * Resetting the flag shouldn't do any harm, anyway.
+ */
+ win->_clear = FALSE;
+ }
+
+ return code;
+}
+// int wscanw (WINDOW *, NCURSES_CONST char *,...) {}
+int wscrl(WINDOW *win, int n)
+{
+ if (!win->_scroll)
+ return ERR;
+
+ if (n != 0) {
+ // _nc_scroll_window(win, n, win->_regtop, win->_regbottom, win->_nc_bkgd);
+ // _nc_synchook(win);
+ }
+ return OK;
+}
+int wsetscrreg(WINDOW *win, int top, int bottom)
+{
+ if (top >= 0 && top <= win->_maxy && bottom >= 0 &&
+ bottom <= win->_maxy && bottom > top) {
+ win->_regtop = (NCURSES_SIZE_T) top;
+ win->_regbottom = (NCURSES_SIZE_T) bottom;
+ return OK;
+ }
+ return ERR;
+}
+// void wsyncdown (WINDOW *) {}
+// void wsyncup (WINDOW *) {}
+// void wtimeout (WINDOW *,int) {}
+/* D */ int wtouchln(WINDOW *win, int y, int n, int changed)
+{
+ int i;
+
+ // if ((n < 0) || (y < 0) || (y > win->_maxy))
+ // return ERR;
+
+ for (i = y; i < y + n; i++) {
+ if (i > win->_maxy)
+ break;
+ win->_line[i].firstchar = changed ? 0 : _NOCHANGE;
+ win->_line[i].lastchar = changed ? win->_maxx : _NOCHANGE;
+ }
+ return OK;
+}
+// int wvline (WINDOW *,chtype,int) {}
+// int tigetflag (NCURSES_CONST char *) {}
+// int tigetnum (NCURSES_CONST char *) {}
+// char *tigetstr (NCURSES_CONST char *) {}
+// int putp (const char *) {}
+// #if NCURSES_TPARM_VARARGS
+// char *tparm (NCURSES_CONST char *, ...) {}
+// #else
+// char *tparm (NCURSES_CONST char *, long,long,long,long,long,long,long,long,long) {}
+// char *tparm_varargs (NCURSES_CONST char *, ...) {}
+// #endif
diff --git a/payloads/libpayload/drivers/Makefile.inc b/payloads/libpayload/drivers/Makefile.inc
new file mode 100644
index 0000000000..809e2e211e
--- /dev/null
+++ b/payloads/libpayload/drivers/Makefile.inc
@@ -0,0 +1,33 @@
+#
+# This file is part of the libpayload project.
+#
+# Copyright (C) 2007 Uwe Hermann <uwe@hermann-uwe.de>
+# Copyright (C) 2008 Advanced Micro Devices, Inc.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+# 3. The name of the author may not be used to endorse or promote products
+# derived from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+# FOR ANY 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) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+#
+
+TARGETS-$(CONFIG_SERIAL_CONSOLE) += drivers/serial.o
+TARGETS-$(CONFIG_VGA_CONSOLE) += drivers/vga.o
+TARGETS-$(CONFIG_PC_KEYBOARD) += drivers/keyboard.o
diff --git a/payloads/libpayload/drivers/keyboard.c b/payloads/libpayload/drivers/keyboard.c
new file mode 100644
index 0000000000..0dc93713b8
--- /dev/null
+++ b/payloads/libpayload/drivers/keyboard.c
@@ -0,0 +1,126 @@
+/*
+ * This file is part of the libpayload project.
+ *
+ * Copyright (C) 2008 Advanced Micro Devices, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY 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) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <arch/io.h>
+#include <libpayload.h>
+
+unsigned char map[2][0x57] = {
+ {
+ 0x00, 0x1B, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36,
+ 0x37, 0x38, 0x39, 0x30, 0x2D, 0x3D, 0x08, 0x09,
+ 0x71, 0x77, 0x65, 0x72, 0x74, 0x79, 0x75, 0x69,
+ 0x6F, 0x70, 0x5B, 0x5D, 0x0A, 0x00, 0x61, 0x73,
+ 0x64, 0x66, 0x67, 0x68, 0x6A, 0x6B, 0x6C, 0x3B,
+ 0x27, 0x60, 0x00, 0x5C, 0x7A, 0x78, 0x63, 0x76,
+ 0x62, 0x6E, 0x6D, 0x2C, 0x2E, 0x2F, 0x00, 0x2A,
+ 0x00, 0x20,
+ },
+ {
+ 0x00, 0x1B, 0x21, 0x40, 0x23, 0x24, 0x25, 0x5E,
+ 0x26, 0x2A, 0x28, 0x29, 0x5F, 0x2B, 0x08, 0x00,
+ 0x51, 0x57, 0x45, 0x52, 0x54, 0x59, 0x55, 0x49,
+ 0x4F, 0x50, 0x7B, 0x7D, 0x0A, 0x00, 0x41, 0x53,
+ 0x44, 0x46, 0x47, 0x48, 0x4A, 0x4B, 0x4C, 0x3A,
+ 0x22, 0x7E, 0x00, 0x7C, 0x5A, 0x58, 0x43, 0x56,
+ 0x42, 0x4E, 0x4D, 0x3C, 0x3E, 0x3F, 0x00, 0x2A,
+ 0x00, 0x20,
+ }
+};
+
+#define MOD_SHIFT 1
+#define MOD_CTRL 2
+#define MOD_CAPSLOCK 4
+
+int keyboard_havechar(void)
+{
+ unsigned char c = inb(0x64);
+ return c & 1;
+}
+
+unsigned char keyboard_get_scancode(void)
+{
+ unsigned char ch = 0;
+
+ if (keyboard_havechar())
+ ch = inb(0x60);
+
+ return ch;
+}
+
+int keyboard_getchar(void)
+{
+ static int modifier;
+ unsigned char ch;
+ int shift;
+
+ int ret = 0;
+
+ while(!keyboard_havechar())
+ ;
+
+ ch = keyboard_get_scancode();
+
+ switch(ch) {
+ case 0x36:
+ case 0x2a:
+ modifier &= ~MOD_SHIFT;
+ break;
+
+ case 0x80 | 0x36:
+ case 0x80 | 0x2a:
+ modifier |= MOD_SHIFT;
+
+ case 0x1d:
+ modifier &= ~MOD_CTRL;
+ break;
+
+ case 0x80 | 0x1d:
+ modifier |= MOD_CTRL;
+ break;
+
+ case 0x3a:
+ if (modifier & MOD_CAPSLOCK)
+ modifier &= ~MOD_CAPSLOCK;
+ else
+ modifier |= MOD_CAPSLOCK;
+ break;
+ }
+
+ if (!(ch & 0x80) && ch < 0x57) {
+ shift = (modifier & MOD_SHIFT) ^ (modifier & MOD_CAPSLOCK) ? 1 : 0;
+ ret = map[shift][ch];
+
+ if (modifier & MOD_CTRL)
+ ret = (ret >= 0x3F && ret <= 0x5F) ? ret & 0x1f : 0;
+
+ return ret;
+ }
+
+ return ret;
+}
diff --git a/payloads/libpayload/drivers/serial.c b/payloads/libpayload/drivers/serial.c
new file mode 100644
index 0000000000..bcf60df614
--- /dev/null
+++ b/payloads/libpayload/drivers/serial.c
@@ -0,0 +1,78 @@
+/*
+ * This file is part of the libpayload project.
+ *
+ * Copyright (C) 2008 Advanced Micro Devices, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY 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) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <libpayload.h>
+#include <sysinfo.h>
+
+#define IOBASE lib_sysinfo.ser_ioport
+
+#ifdef CONFIG_SERIAL_SET_SPEED
+#define DIVISOR (115200 / CONFIG_SERIAL_BAUD_RATE)
+#endif
+
+void serial_init(void)
+{
+#ifdef CONFIG_SERIAL_SET_SPEED
+ unsigned char reg;
+
+ /* Disable interrupts */
+ outb(0, IOBASE + 0x01);
+
+ /* Assert RTS and DTR */
+ outb(3, IOBASE + 0x04);
+
+ /* Set the divisor latch */
+ reg = inb(IOBASE + 0x03);
+ outb(reg | 0x80, IOBASE + 0x03);
+
+ /* Write the divisor */
+ outb(DIVISOR & 0xFF, IOBASE);
+ outb(DIVISOR >> 8 & 0xFF, IOBASE + 1);
+
+ /* Restore the previous value of the divisor */
+ outb(reg &= ~0x80, IOBASE + 0x03);
+#endif
+}
+
+void serial_putchar(unsigned char c)
+{
+ while((inb(IOBASE + 0x05) & 0x20) == 0);
+ outb(c, IOBASE);
+}
+
+int serial_havechar(void)
+{
+ return inb(IOBASE + 0x05) & 0x01;
+}
+
+int serial_getchar(void)
+{
+ while (!serial_havechar());
+ return (int) inb(IOBASE);
+}
diff --git a/payloads/libpayload/drivers/vga.c b/payloads/libpayload/drivers/vga.c
new file mode 100644
index 0000000000..5e0e406f27
--- /dev/null
+++ b/payloads/libpayload/drivers/vga.c
@@ -0,0 +1,216 @@
+/*
+ * This file is part of the libpayload project.
+ *
+ * Copyright (C) 2008 Advanced Micro Devices, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY 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) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <arch/types.h>
+#include <libpayload.h>
+
+#define WIDTH 80
+#define HEIGHT 25
+
+#define VGA_COLOR_WHITE 7
+
+#define CRTC_INDEX 0x3d4
+#define CRTC_DATA 0x3d5
+
+#define VIDEO(_r, _c)\
+ ((uint16_t *) (0xB8000 + ((_r) * (WIDTH * 2)) + ((_c) * 2)))
+
+static int cursor_enabled;
+static int cursorx;
+static int cursory;
+
+static void vga_scroll_up(void);
+
+static inline uint8_t crtc_read(uint8_t index)
+{
+ outb(index, CRTC_INDEX);
+ return inb(CRTC_DATA);
+}
+
+static inline void crtc_write(uint8_t data, uint8_t index)
+{
+ outb(index, CRTC_INDEX);
+ outb(data, CRTC_DATA);
+}
+
+static void vga_get_cursor_pos(void)
+{
+ unsigned int addr;
+ addr = ((unsigned int) crtc_read(0x0E)) << 8;
+ addr += crtc_read(0x0E);
+
+ cursorx = addr % WIDTH;
+ cursory = addr / WIDTH;
+}
+
+static void vga_fixup_cursor(void)
+{
+ unsigned int addr;
+
+ if (!cursor_enabled)
+ return;
+
+ if (cursorx < 0)
+ cursorx = 0;
+
+ if (cursory < 0)
+ cursory = 0;
+
+ if (cursorx >= WIDTH) {
+ cursorx = 0;
+ cursory++;
+ }
+
+ while(cursory >= HEIGHT)
+ vga_scroll_up();
+
+ addr = cursorx + (WIDTH * cursory);
+ crtc_write(addr >> 8, 0x0E);
+ crtc_write(addr, 0x0E);
+}
+
+void vga_cursor_enable(int state)
+{
+ unsigned char tmp = crtc_read(0x0a);
+
+ if (state == 0) {
+ tmp |= (1 << 5);
+ cursor_enabled = 0;
+ }
+ else {
+ tmp &= ~(1 << 5);
+ cursor_enabled = 1;
+ vga_fixup_cursor();
+ }
+
+ crtc_write(tmp, 0x0a);
+}
+
+void vga_clear_line(uint8_t row, uint8_t ch, uint8_t attr)
+{
+ int col;
+ uint16_t *ptr = VIDEO(0, row);
+
+ for(col = 0; col < WIDTH; col++)
+ ptr[col] = ((attr & 0xFF) << 8) | (ch & 0xFF);
+}
+
+static void vga_scroll_up(void)
+{
+ uint16_t *src = VIDEO(0,1);
+ uint16_t *dst = VIDEO(0,0);
+ int i;
+
+ for(i = 0; i < (HEIGHT - 1) * WIDTH; i++)
+ *dst++ = *src++;
+
+ vga_clear_line(HEIGHT - 1, ' ', VGA_COLOR_WHITE);
+ cursory--;
+}
+
+void vga_fill(uint8_t ch, uint8_t attr)
+{
+ uint8_t row;
+ for(row = 0; row < HEIGHT; row++)
+ vga_clear_line(row, ch, attr);
+}
+
+void vga_clear(void)
+{
+ vga_fill(' ', VGA_COLOR_WHITE);
+ vga_move_cursor(0, 0);
+}
+
+void vga_putc(uint8_t row, uint8_t col, unsigned int c)
+{
+ uint16_t *ptr = VIDEO(row, col);
+ *ptr = (uint16_t) (c & 0xFFFF);
+}
+
+void vga_putchar(unsigned int ch) {
+
+ uint16_t *ptr;
+
+ switch(ch & 0xFF) {
+ case '\r':
+ cursorx = 0;
+ break;
+ case '\n':
+ cursory++;
+ break;
+ case '\b':
+ cursorx--;
+ ptr = VIDEO(cursory, cursorx);
+ *ptr = (*ptr & 0xFF00) | ' ';
+ break;
+ case '\t':
+ cursorx = (cursorx + 8) & ~7;
+ break;
+
+ default:
+ ptr = VIDEO(cursory, cursorx);
+ *ptr = (uint16_t) (ch & 0xFFFF);
+ cursorx++;
+ break;
+ }
+
+ vga_fixup_cursor();
+}
+
+int vga_move_cursor(int x, int y)
+{
+ cursorx = x;
+ cursory = y;
+
+ vga_fixup_cursor();
+}
+
+void vga_init(void)
+{
+ /* Get the position of the cursor */
+ vga_get_cursor_pos();
+
+ /* See if it us currently enabled or not */
+ cursor_enabled = !(crtc_read(0x0A) & (1 << 5));
+
+ /* If the cursor is enabled, get us to a sane point */
+
+ if (cursor_enabled) {
+
+ /* Go to the next line */
+
+ if (cursorx) {
+ cursorx = 0;
+ cursory++;
+ }
+
+ vga_fixup_cursor();
+ }
+}
+
diff --git a/payloads/libpayload/i386/Makefile.inc b/payloads/libpayload/i386/Makefile.inc
new file mode 100644
index 0000000000..75b0749973
--- /dev/null
+++ b/payloads/libpayload/i386/Makefile.inc
@@ -0,0 +1,31 @@
+#
+# This file is part of the libpayload project.
+#
+# Copyright (C) 2008 Advanced Micro Devices, Inc.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+# 3. The name of the author may not be used to endorse or promote products
+# derived from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+# FOR ANY 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) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+#
+
+TARGETS-y += i386/head.o i386/main.o i386/sysinfo.o
+TARGETS-y += i386/timer.o i386/coreboot.o i386/util.o
diff --git a/payloads/libpayload/i386/coreboot.c b/payloads/libpayload/i386/coreboot.c
new file mode 100644
index 0000000000..6d310d0325
--- /dev/null
+++ b/payloads/libpayload/i386/coreboot.c
@@ -0,0 +1,147 @@
+/*
+ * This file is part of the libpayload project.
+ *
+ * Copyright (C) 2008 Advanced Micro Devices, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY 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) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <libpayload.h>
+#include <sysinfo.h>
+#include <ipchecksum.h>
+#include <coreboot_tables.h>
+
+/* Some of this is x86 specific, and the rest of it
+ is generic. Right now, since we only support x86,
+ we'll avoid trying to make lots of infrastructure
+ we don't need. If in the future, we want to use
+ coreboot on some other architecture, then take out
+ the generic parsing code and move it elsewhere
+*/
+
+/* === Parsing code === */
+/* This is the generic parsing code */
+
+static void cb_parse_memory(unsigned char *ptr, struct sysinfo_t *info)
+{
+ struct cb_memory *mem = (struct cb_memory *) ptr;
+ int count = MEM_RANGE_COUNT(mem);
+ int i;
+
+ if (count > SYSINFO_MAX_MEM_RANGES)
+ count = SYSINFO_MAX_MEM_RANGES;
+
+ info->n_memranges = 0;
+
+ for(i = 0; i < count; i++) {
+ struct cb_memory_range *range =
+ (struct cb_memory_range *) MEM_RANGE_PTR(mem, i);
+
+ if (range->type != CB_MEM_RAM)
+ continue;
+
+ info->memrange[info->n_memranges].base =
+ UNPACK_CB64(range->start);
+
+ info->memrange[info->n_memranges].size =
+ UNPACK_CB64(range->size);
+
+ info->n_memranges++;
+ }
+}
+
+static void cb_parse_serial(unsigned char *ptr, struct sysinfo_t *info)
+{
+ struct cb_serial *ser = (struct cb_serial *) ptr;
+ info->ser_ioport = ser->ioport;
+}
+
+static int cb_parse_header(void *addr, int len, struct sysinfo_t *info)
+{
+ struct cb_header *header;
+ unsigned char *ptr = (unsigned char *) addr;
+ int i;
+
+ for (i = 0; i < len; i += 16, ptr += 16) {
+ header = (struct cb_header *) ptr;
+
+ if (!strncmp(header->signature, "LBIO", 4))
+ break;
+ }
+
+ /* We walked the entire space and didn't find anything */
+
+ if (i >= len)
+ return -1;
+
+ if (!header->table_bytes)
+ return 0;
+
+ /* Make sure the checksums match */
+
+ if (ipchksum((uint16_t *) header, sizeof(*header)) != 0)
+ return -1;
+
+ if (ipchksum((uint16_t *) (ptr + sizeof(*header)),
+ header->table_bytes) != header->table_checksum)
+ return -1;
+
+ /* Now, walk the tables */
+ ptr += header->header_bytes;
+
+ for(i = 0; i < header->table_entries; i++) {
+ struct cb_record *rec = (struct cb_record *) ptr;
+
+ /* We only care about a few tags here - maybe
+ more will be interesting later
+ */
+
+ switch(rec->tag) {
+ case CB_TAG_MEMORY:
+ cb_parse_memory(ptr, info);
+ break;
+
+ case CB_TAG_SERIAL:
+ cb_parse_serial(ptr, info);
+ break;
+ }
+
+ ptr += rec->size;
+ }
+
+ return 1;
+}
+
+/* == Architecture specific ==*/
+/* This is the x86 specific stuff */
+
+int get_coreboot_info(struct sysinfo_t *info)
+{
+ int ret = cb_parse_header((void *) 0x0, 0x1000, info);
+
+ if (ret != 1)
+ ret = cb_parse_header((void *) 0xf0000, 0x1000, info);
+
+ return (ret == 1) ? 0 : -1;
+}
diff --git a/payloads/libpayload/i386/head.S b/payloads/libpayload/i386/head.S
new file mode 100644
index 0000000000..1278bdf4ed
--- /dev/null
+++ b/payloads/libpayload/i386/head.S
@@ -0,0 +1,85 @@
+/*
+ * This file is part of the libpayload project.
+ *
+ * Copyright (C) 2008 Advanced Micro Devices, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY 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) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+ .global _entry, _leave
+ .text
+ .align 4
+
+/* Our entry point - assume that the CPU is in
+ * 32 bit protected mode and all segments are in a
+ * flat model. Thats our operating mode, so we won't
+ * change anything
+ */
+
+_entry:
+ call _init
+
+ /* We're back - go back to the bootloader */
+ ret
+
+/* This function saves off the previous stack and
+ switches us to our own execution enviornment
+*/
+
+_init:
+ /* No interrupts, please */
+ cli
+
+ /* Get the current stack pointer */
+ movl %esp, %esi
+
+ movl _istack, %ebx
+
+ /* lret needs %cs in the stack, so copy it over */
+ movw %cs, 4(%ebx)
+
+ /* Exchange the current stack pointer for the one in
+ the initial stack (which happens to be the new
+ stack pointer) */
+
+ xchgl %esi, 16(%ebx)
+
+ /* Set the new stack pointer */
+ movl %esi, %esp
+
+ /* Return into the main entry function
+ and go
+ */
+
+ lret
+
+_leave:
+ movl _istack, %ebx
+
+ /* Restore the stack pointer from the storage area */
+ movl 16(%ebx), %esp
+
+ /* Return to the original context */
+ lret
+
diff --git a/payloads/libpayload/i386/main.c b/payloads/libpayload/i386/main.c
new file mode 100644
index 0000000000..846d46a426
--- /dev/null
+++ b/payloads/libpayload/i386/main.c
@@ -0,0 +1,79 @@
+/*
+ * This file is part of the libpayload project.
+ *
+ * Copyright (C) 2008 Advanced Micro Devices, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY 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) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <arch/types.h>
+
+/* This structure seeds the stack. We provide
+ the return address of our main function, and
+ further down, the address of the function
+ that we call when we leave and try to restore
+ the original stack. At the very bottom of the
+ stack we store the orignal stack pointer
+ from the calling application
+*/
+
+static void start_main(void);
+extern void _leave(void);
+
+static struct {
+ uint32_t eip[2];
+ uint32_t raddr[2];
+ uint32_t esp;
+} initial_stack __attribute__((section (".istack"))) = {
+ { (uint32_t) start_main, 0 },
+ { (uint32_t) _leave, 0 },
+ (uint32_t) &initial_stack,
+};
+
+void * _istack = &initial_stack;
+
+/* This is our C entry function - set up the system
+ and jump into the payload entry point */
+
+static void start_main(void)
+{
+ extern int main(void);
+
+ /* Set up the consoles */
+ console_init();
+
+ /* Gather system information */
+ lib_get_sysinfo();
+
+ /* Any other system init that has to happen before the
+ user gets control goes here. */
+
+ /* Go to the entry point */
+
+ /* in the future we may care about the return value */
+ (void) main();
+
+ /* Returning here will go to the _leave function to return
+ us to the original context */
+}
diff --git a/payloads/libpayload/i386/sysinfo.c b/payloads/libpayload/i386/sysinfo.c
new file mode 100644
index 0000000000..1fdf3fc419
--- /dev/null
+++ b/payloads/libpayload/i386/sysinfo.c
@@ -0,0 +1,70 @@
+/*
+ * This file is part of the libpayload project.
+ *
+ * Copyright (C) 2008 Advanced Micro Devices, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY 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) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <libpayload.h>
+#include <sysinfo.h>
+
+/* This is a global structure that is used through the
+ library - we set it up initially with some dummy
+ values - hopefully they will be overridden
+*/
+
+struct sysinfo_t lib_sysinfo = {
+ . cpu_khz = 200,
+ . ser_ioport = CONFIG_SERIAL_IOBASE,
+};
+
+void lib_get_sysinfo(void)
+{
+ /* Get the CPU speed (for delays) */
+ lib_sysinfo.cpu_khz = get_cpu_speed();
+
+ /* Get the memory information */
+
+ get_coreboot_info(&lib_sysinfo);
+
+ if (!lib_sysinfo.n_memranges) {
+
+ /* If we couldn't get a good memory range,
+ then use a hard coded default */
+
+ lib_sysinfo.n_memranges = 2;
+
+ lib_sysinfo.memrange[0].base = 0;
+ lib_sysinfo.memrange[0].size = 640 * 1024;
+ lib_sysinfo.memrange[1].base = 1024 * 1024;
+ lib_sysinfo.memrange[1].size = 31 * 1024 * 1024;
+ }
+}
+
+
+
+
+
+
diff --git a/payloads/libpayload/i386/timer.c b/payloads/libpayload/i386/timer.c
new file mode 100644
index 0000000000..72a3ee8f48
--- /dev/null
+++ b/payloads/libpayload/i386/timer.c
@@ -0,0 +1,92 @@
+/*
+ * This file is part of the libpayload project.
+ *
+ * Copyright (C) 2008 Advanced Micro Devices, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY 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) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <libpayload.h>
+#include <arch/rdtsc.h>
+
+static unsigned int cpu_khz;
+
+/* Calculate the speed of the processor for use in delays */
+
+void get_cpu_speed(void)
+{
+ unsigned long long start, end;
+
+ /* Set up the PPC port - disable the speaker,
+ * enable the T2 gate */
+
+ outb((inb(0x61) & ~0x02) | 0x01, 0x61);
+
+ /* Set the PIT to Mode 0, counter 2, word access */
+ outb(0xB0, 0x43);
+
+ /* Load the counter with 0xFFFF */
+
+ outb(0xFF, 0x42);
+ outb(0xFF, 0x42);
+
+ /* Read the number of ticks during the period */
+
+ start = rdtsc();
+ while(!(inb(0x61) & 0x20));
+ end = rdtsc();
+
+ /* The clock rate is 1193180 Hz
+ * the number of miliseconds for a period
+ * of 0xFFFF is 1193180 / (0xFFFF * 1000)
+ * or .0182. Multiply that by the number of
+ * measured clocks to get the khz value
+ */
+
+ cpu_khz =
+ (unsigned int ) ((end - start) * 1193180U / (1000 * 0xFFFF));
+}
+
+/* Global delay functions */
+
+static inline void _delay(unsigned int delta)
+{
+ unsigned long long timeout = rdtsc() + delta;
+ while (rdtsc() < timeout);
+}
+
+void ndelay(unsigned int n)
+{
+ _delay(n * cpu_khz / 1000000);
+}
+
+void mdelay(unsigned int m)
+{
+ _delay(m * cpu_khz);
+}
+
+void delay(unsigned int s)
+{
+ _delay(s * cpu_khz * 1000);
+}
diff --git a/payloads/libpayload/i386/util.S b/payloads/libpayload/i386/util.S
new file mode 100644
index 0000000000..a0b1b0980d
--- /dev/null
+++ b/payloads/libpayload/i386/util.S
@@ -0,0 +1,38 @@
+/*
+ * This file is part of the libpayload project.
+ *
+ * Copyright (C) 2008 Advanced Micro Devices, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY 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) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+ .global halt
+ .text
+ .align 4
+
+/* This function puts the system into a halt. */
+
+halt:
+ cli
+ hlt
+ jmp halt
diff --git a/payloads/libpayload/include/arch/io.h b/payloads/libpayload/include/arch/io.h
new file mode 100644
index 0000000000..dcf5bd97ea
--- /dev/null
+++ b/payloads/libpayload/include/arch/io.h
@@ -0,0 +1,77 @@
+/*
+ * This file is part of the libpayload project.
+ *
+ * Copyright (C) 2008 Advanced Micro Devices, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY 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) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef _X86_ARCH_IO_H_
+#define _X86_ARCH_IO_H_
+
+#define readb(_a) (*(volatile unsigned char *) (_a))
+#define readw(_a) (*(volatile unsigned short *) (_a))
+#define readl(_a) (*(volatile unsigned long *) (_a))
+
+#define writeb(_v, _a) (*(volatile unsigned char *) (_a) = (_v))
+#define writew(_v, _a) (*(volatile unsigned short *) (_a) = (_v))
+#define writel(_v, _a) (*(volatile unsigned long *) (_a) = (_v))
+
+static inline unsigned long inl(int port)
+{
+ unsigned long val;
+ __asm__ __volatile__("inl %w1, %0" : "=a"(val) : "Nd"(port));
+ return val;
+}
+
+static inline unsigned short inw(int port)
+{
+ unsigned short val;
+ __asm__ __volatile__("inw %w1, %w0" : "=a"(val) : "Nd"(port));
+ return val;
+}
+
+static inline unsigned char inb(int port)
+{
+ unsigned char val;
+ __asm__ __volatile__("inb %w1, %b0" : "=a"(val) : "Nd"(port));
+ return val;
+}
+
+static inline void outl(unsigned long val, int port)
+{
+ __asm__ __volatile__("outl %0, %w1" : : "a"(val), "Nd"(port));
+}
+
+static inline void outw(unsigned short val, int port)
+{
+ __asm__ __volatile__("outw %w0, %w1" : : "a"(val), "Nd"(port));
+}
+
+static inline void outb(unsigned char val, int port)
+{
+ __asm__ __volatile__("outb %b0, %w1" : : "a"(val), "Nd"(port));
+}
+
+#endif
diff --git a/payloads/libpayload/include/arch/rdtsc.h b/payloads/libpayload/include/arch/rdtsc.h
new file mode 100644
index 0000000000..1addedafc8
--- /dev/null
+++ b/payloads/libpayload/include/arch/rdtsc.h
@@ -0,0 +1,40 @@
+/*
+ * This file is part of the libpayload project.
+ *
+ * Copyright (C) 2008 Advanced Micro Devices, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY 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) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef _RDTSC_H_
+#define _RDTSC_H_
+
+static inline unsigned long long rdtsc(void)
+{
+ unsigned long long val;
+ __asm__ __volatile__ ("rdtsc" : "=A" (val));
+ return val;
+}
+
+#endif
diff --git a/payloads/libpayload/include/arch/types.h b/payloads/libpayload/include/arch/types.h
new file mode 100644
index 0000000000..d1f3acda5b
--- /dev/null
+++ b/payloads/libpayload/include/arch/types.h
@@ -0,0 +1,57 @@
+/*
+ * This file is part of the libpayload project.
+ *
+ * Copyright (C) 2007 Uwe Hermann <uwe@hermann-uwe.de>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY 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) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef _ARCH_X86_TYPES_H
+#define _ARCH_X86_TYPES_H
+
+typedef unsigned char uint8_t;
+typedef unsigned char u8;
+typedef signed char int8_t;
+typedef signed char s8;
+
+typedef unsigned short uint16_t;
+typedef unsigned short u16;
+typedef signed short int16_t;
+typedef signed short s16;
+
+typedef unsigned int uint32_t;
+typedef unsigned int u32;
+typedef signed int int32_t;
+typedef signed int s32;
+
+typedef unsigned long long uint64_t;
+typedef unsigned long long u64;
+typedef signed long long int64_t;
+typedef signed long long s64;
+
+#ifndef NULL
+#define NULL ((void *)0)
+#endif
+
+#endif
diff --git a/payloads/libpayload/include/coreboot_tables.h b/payloads/libpayload/include/coreboot_tables.h
new file mode 100644
index 0000000000..1542157ca7
--- /dev/null
+++ b/payloads/libpayload/include/coreboot_tables.h
@@ -0,0 +1,151 @@
+/*
+ * This file is part of the libpayload project.
+ *
+ * Copyright (C) 2008 Advanced Micro Devices, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY 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) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef _COREBOOT_TABLES_H_
+#define _COREBOOT_TABLES_H_
+
+#include <arch/types.h>
+
+struct cbuint64 {
+ uint32_t lo;
+ uint32_t hi;
+};
+
+struct cb_header {
+ uint8_t signature[4];
+ uint32_t header_bytes;
+ uint32_t header_checksum;
+ uint32_t table_bytes;
+ uint32_t table_checksum;
+ uint32_t table_entries;
+};
+
+struct cb_record {
+ uint32_t tag;
+ uint32_t size;
+};
+
+#define CB_TAG_UNUSED 0x0000
+#define CB_TAG_MEMORY 0x0001
+
+struct cb_memory_range {
+ struct cbuint64 start;
+ struct cbuint64 size;
+ uint32_t type;
+};
+
+#define CB_MEM_RAM 1
+#define CB_MEM_RESERVED 2
+#define CB_MEM_TABLE 16
+
+struct cb_memory {
+ uint32_t tag;
+ uint32_t size;
+ struct cb_memory_range map[0];
+};
+
+#define CB_TAG_HWRPB 0x0002
+
+struct cb_hwrpb {
+ uint32_t tag;
+ uint32_t size;
+ uint64_t hwrpb;
+};
+
+#define CB_TAG_MAINBOARD 0x0003
+
+struct cb_mainboard {
+ uint32_t tag;
+ uint32_t size;
+ uint8_t vendor_idx;
+ uint8_t part_number_idx;
+ uint8_t strings[0];
+};
+
+#define CB_TAG_VERSION 0x0004
+#define CB_TAG_EXTRA_VERSION 0x0005
+#define CB_TAG_BUILD 0x0006
+#define CB_TAG_COMPILE_TIME 0x0007
+#define CB_TAG_COMPILE_BY 0x0008
+#define CB_TAG_COMPILE_HOST 0x0009
+#define CB_TAG_COMPILE_DOMAIN 0x000a
+#define CB_TAG_COMPILER 0x000b
+#define CB_TAG_LINKER 0x000c
+#define CB_TAG_ASSEMBLER 0x000d
+
+struct cb_string {
+ uint32_t tag;
+ uint32_t size;
+ uint8_t string[0];
+};
+
+#define CB_TAG_SERIAL 0x000f
+
+struct cb_serial {
+ uint32_t tag;
+ uint32_t size;
+ uint16_t ioport;
+};
+
+#define CB_TAG_CONSOLE 0x00010
+
+struct cb_console {
+ uint32_t tag;
+ uint32_t size;
+ uint16_t type;
+};
+
+#define CB_TAG_CONSOLE_SERIAL8250 0
+#define CB_TAG_CONSOLE_VGA 1
+#define CB_TAG_CONSOLE_BTEXT 2
+#define CB_TAG_CONSOLE_LOGBUF 3
+#define CB_TAG_CONSOLE_SROM 4
+#define CB_TAG_CONSOLE_EHCI 5
+
+/* Still to come: CMOS information */
+
+/* Helpful macros */
+
+#define MEM_RANGE_COUNT(_rec) \
+ (((_rec)->size - sizeof(*(_rec))) / sizeof((_rec)->map[0]))
+
+#define MEM_RANGE_PTR(_rec, _idx) \
+ (((uint8_t *) (_rec)) + sizeof(*(_rec)) \
+ + (sizeof((_rec)->map[0]) * (_idx)))
+
+#define MB_VENDOR_STRING(_mb) \
+ (((unsigned char *) ((_mb)->strings)) + (_mb)->vendor_idx)
+
+#define MB_PART_STRING(_mb) \
+ (((unsigned char *) ((_mb)->strings)) + (_mb)->part_number_idx)
+
+#define UNPACK_CB64(_in) \
+ ( (((uint64_t) _in.hi) << 32) | _in.lo )
+
+#endif
diff --git a/payloads/libpayload/include/libpayload.h b/payloads/libpayload/include/libpayload.h
new file mode 100644
index 0000000000..84518563d6
--- /dev/null
+++ b/payloads/libpayload/include/libpayload.h
@@ -0,0 +1,99 @@
+/*
+ * This file is part of the libpayload project.
+ *
+ * Copyright (C) 2008 Advanced Micro Devices, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY 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) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef LIBPAYLOAD_H_
+#define LIBPAYLOAD_H_
+
+#include <autoconf.h>
+#include <stddef.h>
+#include <arch/types.h>
+#include <arch/io.h>
+#include <stdarg.h>
+
+#define MIN(a,b) ((a) < (b) ? (a) : (b))
+#define MAX(a,b) ((a) > (b) ? (a) : (b))
+#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
+
+/* serial.c */
+void serial_putchar(unsigned char c);
+
+/* console.c */
+int putchar(int c);
+extern int last_putchar;
+
+#define havechar havekey
+
+/* ctype.c */
+int isspace(int c);
+int isdigit(int c);
+int tolower(int c);
+
+/* malloc.c */
+void *malloc(size_t size);
+void free(void *ptr);
+void *calloc(size_t nmemb, size_t size);
+void *realloc(void *ptr, size_t size);
+
+/* memory.c */
+int memcmp(const char *s1, const char *s2, size_t len);
+void *memcpy(void *dst, const void *src, size_t n);
+void *memset(void *s, int c, size_t n);
+void *memmove(void *dst, const void *src, size_t n);
+
+/* printf.c */
+int sprintf(char *str, const char *fmt, ...);
+int vsnprintf(char *str, size_t size, const char *fmt, va_list ap);
+int vsprintf(char *str, const char *fmt, va_list ap);
+int printf(const char *fmt, ...);
+int vprintf(const char *fmt, va_list ap);
+
+/* string.c */
+size_t strnlen(const char *src, size_t max);
+size_t strlen(const char *src);
+int strcmp(const char *s1, const char *s2);
+char *strdup(const char *s);
+char *strchr(const char *s, int c);
+char *strncpy(char *to, const char *from, int count);
+char * strcpy (char *dest, const char *src);
+char * strstr (const char *s1, const char *s2);
+
+/* ipchchecksum.c */
+unsigned short ipchksum(const unsigned short *ptr, unsigned long nbytes);
+
+/* util.S */
+#define abort() halt()
+void halt(void) __attribute__ ((noreturn));
+
+/* Timer functions - defined by each arcitecture */
+
+void ndelay(unsigned int);
+void mdelay(unsigned int);
+void delay(unsigned int);
+
+#endif
diff --git a/payloads/libpayload/include/sysinfo.h b/payloads/libpayload/include/sysinfo.h
new file mode 100644
index 0000000000..ff39765b76
--- /dev/null
+++ b/payloads/libpayload/include/sysinfo.h
@@ -0,0 +1,53 @@
+/*
+ * This file is part of the libpayload project.
+ *
+ * Copyright (C) 2008 Advanced Micro Devices, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY 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) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef _SYSINFO_H_
+#define _SYSINFO_H_
+
+/* Allow a maximum of 16 memory range definitions */
+
+#define SYSINFO_MAX_MEM_RANGES 16
+
+struct sysinfo_t {
+ unsigned int cpu_khz;
+ unsigned short ser_ioport;
+
+ int n_memranges;
+
+ struct {
+ unsigned long long base;
+ unsigned long long size;
+ } memrange[SYSINFO_MAX_MEM_RANGES];
+};
+
+extern struct sysinfo_t lib_sysinfo;
+void lib_get_sysinfo(void);
+
+#endif
+
diff --git a/payloads/libpayload/libc/Makefile.inc b/payloads/libpayload/libc/Makefile.inc
new file mode 100644
index 0000000000..f42f836174
--- /dev/null
+++ b/payloads/libpayload/libc/Makefile.inc
@@ -0,0 +1,32 @@
+#
+# This file is part of the libpayload project.
+#
+# Copyright (C) 2008 Advanced Micro Devices, Inc.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+# 3. The name of the author may not be used to endorse or promote products
+# derived from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+# FOR ANY 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) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+#
+
+TARGETS-y += libc/malloc.o libc/printf.o libc/console.o libc/string.o
+TARGETS-y += libc/memory.o libc/ctype.o
+TARGETS-y += libc/ipchecksum.o
diff --git a/payloads/libpayload/libc/console.c b/payloads/libpayload/libc/console.c
new file mode 100644
index 0000000000..bb7dec1f94
--- /dev/null
+++ b/payloads/libpayload/libc/console.c
@@ -0,0 +1,104 @@
+/*
+ * This file is part of the libpayload project.
+ *
+ * Copyright (C) 2008 Advanced Micro Devices, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY 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) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <libpayload.h>
+
+void console_init(void)
+{
+#ifdef CONFIG_VGA_CONSOLE
+ vga_init();
+#endif
+#ifdef CONFIG_SERIAL_CONSOLE
+ serial_init();
+#endif
+}
+
+static void device_putchar(unsigned char c)
+{
+#ifdef CONFIG_VGA_CONSOLE
+ vga_putchar(0x700| c);
+#endif
+#ifdef CONFIG_SERIAL_CONSOLE
+ serial_putchar(c);
+#endif
+}
+
+int putchar(int c)
+{
+ c &= 0xff;
+ if (c == '\n')
+ device_putchar('\r');
+ device_putchar(c);
+ return c;
+}
+
+int puts(const char *s)
+{
+ int n = 0;
+
+ while (*s) {
+ putchar(*s++);
+ n++;
+ }
+
+ putchar('\n');
+ return n+1;
+}
+
+int havekey(void)
+{
+#ifdef CONFIG_SERIAL_CONSOLE
+ if (serial_havechar())
+ return 1;
+#endif
+#ifdef CONFIG_PC_KEYBOARD
+ if (keyboard_havechar())
+ return 1;
+#endif
+ return 0;
+}
+
+/* This returns an ascii value - the two getchar functions
+ cook the respective input from the device
+*/
+
+int getchar(void)
+{
+ while (1) {
+#ifdef CONFIG_SERIAL_CONSOLE
+ if (serial_havechar())
+ return serial_getchar();
+#endif
+#ifdef CONFIG_PC_KEYBOARD
+ if (keyboard_havechar())
+ return keyboard_getchar();
+#endif
+ }
+}
+
diff --git a/payloads/libpayload/libc/ctype.c b/payloads/libpayload/libc/ctype.c
new file mode 100644
index 0000000000..c2f42a52d2
--- /dev/null
+++ b/payloads/libpayload/libc/ctype.c
@@ -0,0 +1,60 @@
+/*
+ * This file is part of the libpayload project.
+ *
+ * Copyright (C) 2008 Advanced Micro Devices, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY 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) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/* Basic ctype functions */
+
+#include <libpayload.h>
+
+int isspace(int c)
+{
+ switch (c) {
+ case ' ': case '\f': case '\n':
+ case '\r': case '\t': case '\v':
+ return 1;
+ default:
+ return 0;
+ }
+}
+
+int isdigit(int c)
+{
+ switch (c) {
+ case '0'...'9':
+ return 1;
+ default:
+ return 0;
+ }
+}
+
+int tolower(int c)
+{
+ if (c >= 'A' && c <= 'Z')
+ return c - 'A' + 'a';
+ return c;
+}
diff --git a/payloads/libpayload/libc/malloc.c b/payloads/libpayload/libc/malloc.c
new file mode 100644
index 0000000000..a4877e67d9
--- /dev/null
+++ b/payloads/libpayload/libc/malloc.c
@@ -0,0 +1,262 @@
+/*
+ * This file is part of the libpayload project.
+ *
+ * Copyright (C) 2008 Advanced Micro Devices, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY 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) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/* This is a classically weak malloc() implmentation.
+ We have a relatively small and static heap, so we take
+ the easy route with an O(N) loop through the tree for
+ every malloc() and free(). Obviously, this doesn't scale
+ past a few hundred K (if that).
+
+ We're also susecptable to the usual buffer overun poisoning,
+ though the risk is within acceptable ranges for this
+ implementation (don't overrun your buffers, kids!)
+*/
+
+#include <libpayload.h>
+
+/* Defined in the ldscript */
+extern char _heap, _eheap;
+
+static void *hstart = (void *) &_heap;
+static void *hend = (void *) &_eheap;
+
+typedef unsigned int hdrtype_t;
+
+#define MAGIC (0x2a << 26)
+#define FLAG_FREE (1 << 25)
+#define FLAG_USED (1 << 24)
+
+#define SIZE(_h) ((_h) & 0xFFFFFF)
+
+#define _HEADER(_s, _f) ((hdrtype_t) (MAGIC | (_f) | ((_s) & 0xFFFFFF)))
+
+#define FREE_BLOCK(_s) _HEADER(_s, FLAG_FREE)
+#define USED_BLOCK(_s) _HEADER(_s, FLAG_USED)
+
+#define HDRSIZE (sizeof(hdrtype_t))
+
+#define IS_FREE(_h) (((_h) & (MAGIC | FLAG_FREE)) == (MAGIC | FLAG_FREE))
+#define HAS_MAGIC(_h) (((_h) & MAGIC) == MAGIC)
+
+void print_malloc_map(void);
+
+static void setup(void)
+{
+ int size = (unsigned int) (_heap - _eheap) - HDRSIZE;
+ *((hdrtype_t *) hstart) = FREE_BLOCK(size);
+}
+
+static void *alloc(int len)
+{
+ hdrtype_t header;
+ void *ptr = hstart;
+
+ /* align the size */
+ len = (len + 3) & ~3;
+
+ if (!len || len > 0xFFFFFF)
+ return (void *) NULL;
+
+ /* Make sure the region is setup correctly */
+ if (!HAS_MAGIC(*((hdrtype_t *) ptr)))
+ setup();
+
+ /* Find some free space */
+
+ do {
+ header = *((hdrtype_t *) ptr);
+ int size = SIZE(header);
+
+ if (header & FLAG_FREE) {
+
+ if (len <= size) {
+ void *nptr = ptr + HDRSIZE + len;
+ int nsize = size - (len + 8);
+
+ /* Mark the block as used */
+ *((hdrtype_t *) ptr) = USED_BLOCK(len);
+
+ /* If there is still room in this block,
+ * then mark it as such */
+
+ if (nsize > 0)
+ *((hdrtype_t *) nptr) =
+ FREE_BLOCK(nsize - 4);
+
+ return (void *) (ptr + HDRSIZE);
+ }
+ }
+
+ ptr += HDRSIZE + size;
+
+ } while(ptr < hend);
+
+ /* Nothing available */
+ return (void *) NULL;
+}
+
+static void _consolidate(void)
+{
+ void *ptr = hstart;
+
+ while(ptr < hend) {
+ void *nptr;
+ hdrtype_t hdr = *((hdrtype_t *) ptr);
+ unsigned int size = 0;
+
+ if (!IS_FREE(hdr)) {
+ ptr += HDRSIZE + SIZE(hdr);
+ continue;
+ }
+
+ size = SIZE(hdr);
+ nptr = ptr + HDRSIZE + SIZE(hdr);
+
+ while (nptr < hend) {
+ hdrtype_t nhdr = *((hdrtype_t *) nptr);
+
+ if (!(IS_FREE(nhdr)))
+ break;
+
+ size += SIZE(nhdr) + HDRSIZE;
+
+ *((hdrtype_t *) nptr) = 0;
+
+ nptr += (HDRSIZE + SIZE(nhdr));
+ }
+
+ *((hdrtype_t *) ptr) = FREE_BLOCK(size);
+ ptr = nptr;
+ }
+}
+
+void free(void *ptr)
+{
+ hdrtype_t hdr;
+
+ ptr -= HDRSIZE;
+
+ /* Sanity check */
+ if (ptr < hstart || ptr >= hend)
+ return;
+
+ hdr = *((hdrtype_t *) ptr);
+
+ /* Not our header (we're probably poisoned) */
+ if (!HAS_MAGIC(hdr))
+ return;
+
+ /* Double free */
+ if (hdr & FLAG_FREE)
+ return;
+
+ *((hdrtype_t *) ptr) = FREE_BLOCK(SIZE(hdr));
+ _consolidate();
+}
+
+void *malloc(size_t size)
+{
+ return alloc(size);
+}
+
+void *calloc(size_t nmemb, size_t size)
+{
+ unsigned int total = (nmemb * size);
+ void *ptr = alloc(size);
+
+ if (ptr)
+ memset(ptr, 0, total);
+
+ return ptr;
+}
+
+void *realloc(void *ptr, size_t size)
+{
+ void *ret;
+ void *pptr;
+ unsigned int osize;
+
+ if (ptr == NULL)
+ return alloc(size);
+
+ pptr = ptr - HDRSIZE;
+
+ if (!HAS_MAGIC(*((hdrtype_t *) pptr)))
+ return NULL;
+
+ /* Get the original size of the block */
+ osize = SIZE(*((hdrtype_t *) pptr));
+
+ /* Free the memory to update the tables - this
+ won't touch the actual memory, so we can still
+ use it for the copy after we have reallocated
+ the new space
+ */
+
+ free(ptr);
+ ret = alloc(size);
+
+ /* if ret == NULL, then doh - failure.
+ if ret == ptr then woo-hoo! no copy needed */
+
+ if (ret == NULL || ret == ptr)
+ return ret;
+
+ /* Copy the memory to the new location */
+ memcpy(ret, ptr, osize > size ? size : osize);
+ return ret;
+}
+
+/* This is for debugging purposes */
+#ifdef TEST
+
+void print_malloc_map(void)
+{
+ void *ptr = hstart;
+
+ while(ptr < hend) {
+ hdrtype_t hdr = *((hdrtype_t *) ptr);
+
+ if (!HAS_MAGIC(hdr)) {
+ printf("Poisoned magic - we're toast\n");
+ break;
+ }
+
+ /* FIXME: Verify the size of the block */
+
+ printf("%x: %s (%x bytes)\n",
+ (unsigned int) (ptr - hstart),
+ hdr & FLAG_FREE ? "FREE" : "USED",
+ SIZE(hdr));
+
+ ptr += HDRSIZE + SIZE(hdr);
+ }
+}
+
+#endif
diff --git a/payloads/libpayload/libc/string.c b/payloads/libpayload/libc/string.c
new file mode 100644
index 0000000000..c9f0603387
--- /dev/null
+++ b/payloads/libpayload/libc/string.c
@@ -0,0 +1,195 @@
+/*
+ * This file is part of the libpayload project.
+ *
+ * Copyright (C) 2007 Uwe Hermann <uwe@hermann-uwe.de>
+ * Copyright (C) 2008 Advanced Micro Devices, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY 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) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <libpayload.h>
+#include <arch/types.h>
+
+/**
+ * Calculate the length of a fixed-size string.
+ *
+ * @param str The input string.
+ * @param maxlen Return at most maxlen characters as length of the string.
+ * @return The length of the string, not including the final NUL character.
+ * The maximum length returned is maxlen.
+ */
+size_t strnlen(const char *str, size_t maxlen)
+{
+ size_t len = 0;
+
+ /* NULL and empty strings have length 0. */
+ if (!str)
+ return 0;
+
+ /* Loop until we find a NUL character, or maxlen is reached. */
+ while ((*str++ != '\0') && (len < maxlen))
+ len++;
+
+ return len;
+}
+
+/**
+ * Calculate the length of a string.
+ *
+ * @param str The input string.
+ * @return The length of the string, not including the final NUL character.
+ */
+size_t strlen(const char *str)
+{
+ size_t len = 0;
+
+ /* NULL and empty strings have length 0. */
+ if (!str)
+ return 0;
+
+ /* Loop until we find a NUL character. */
+ while (*str++ != '\0')
+ len++;
+
+ return len;
+}
+
+/**
+ * Compare two strings.
+ *
+ * @param s1 The first string.
+ * @param s2 The second string.
+ * @return Returns a value less than zero, if s1 is shorter than s2. Returns
+ * zero, if s1 equals s2. Returns a value greater than zero, if
+ * s1 is longer than s2.
+ */
+int strcmp(const char *s1, const char *s2)
+{
+ char c1, c2;
+
+ /* Set c1 == c2, so that we can enter the while loop. */
+ c1 = 0;
+ c2 = 0;
+
+ /* Compare characters until they differ, or one of the strings ends. */
+ while (c1 == c2) {
+ /* Read the next character from each string. */
+ c1 = *s1++;
+ c2 = *s2++;
+
+ /* Return something negative (if s1 is shorter than s2), or
+ zero (if s1 equals s2). */
+ if (c1 == '\0')
+ return c1 - c2;
+ }
+
+ /* Return someting positive (if s1 is longer than s2), or zero (if s1
+ and s2 are equal). */
+ return c1 - c2;
+}
+
+/**
+ * Compare two strings with fixed length.
+ *
+ * @param s1 The first string.
+ * @param s2 The second string.
+ * @param maxlen Return at most maxlen characters as length of the string.
+ * @return A non-zero value if s1 and s2 differ, or zero if s1 equals s2.
+ */
+int strncmp(const char *s1, const char *s2, int maxlen)
+{
+ int i;
+
+ for (i = 0; i < maxlen; i++) {
+ if (s1[i] != s2[i])
+ return s1[i] - s2[i];
+ }
+
+ return 0;
+}
+
+char *strncpy(char *d, const char *s, int n)
+{
+ /* use +1 to get the null terminator */
+
+ int max = n > strlen(s) + 1 ? strlen(s) + 1 : n;
+ int i;
+
+ for(i = 0; i < max; i++)
+ d[i] = (char) s[i];
+
+ return d;
+}
+
+char *strncat(char *d, const char *s, int n)
+{
+ char *p = d + strlen(d);
+ int max = n > strlen(s) ? strlen(s) : n;
+ int i;
+
+ for(i = 0; i < max; i++)
+ p[i] = s[i];
+
+ p[i] = '\0';
+ return d;
+}
+
+char * strchr(const char *s, int c)
+{
+ char *p = (char *) s;
+
+ for( ; *p != 0; p++) {
+ if (*p == c)
+ return p;
+ }
+
+ return NULL;
+}
+
+
+char *strdup(const char *s)
+{
+ int n = strlen(s);
+ char *p = malloc(n);
+
+ if (p != NULL)
+ strncpy(p, s, n);
+
+ return p;
+}
+
+char *strstr(const char *h, const char *n)
+{
+ int hn = strlen(h);
+ int nn = strlen(n);
+ int i;
+
+ for(i = 0; i <= hn - nn; i++)
+ if (!strcmp(&h[i], n))
+ return (char *) &h[i];
+
+ return NULL;
+}
+
+
diff --git a/payloads/libpayload/libpayload.ldscript b/payloads/libpayload/libpayload.ldscript
new file mode 100644
index 0000000000..81ad105842
--- /dev/null
+++ b/payloads/libpayload/libpayload.ldscript
@@ -0,0 +1,90 @@
+/*
+ This file is part of the libpayload project.
+
+ Copyright (C) 2008 Advanced Micro Devices, Inc.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ 3. The name of the author may not be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ FOR ANY 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) ARISING IN ANY WAY
+ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ SUCH DAMAGE.
+*/
+
+BASE_ADDRESS = 0x100000;
+
+OUTPUT_FORMAT(elf32-i386)
+OUTPUT_ARCH(i386)
+
+ENTRY(_entry)
+
+HEAP_SIZE = 16384;
+STACK_SIZE = 16384;
+
+SECTIONS
+{
+ . = BASE_ADDRESS;
+
+ . = ALIGN(16);
+ _start = .;
+
+ .text : {
+ *(.text._entry)
+ *(.text)
+ *(.text.*)
+ }
+
+ .rodata : {
+ *(.rodata)
+ *(.rodata.*)
+ }
+
+ .data : {
+ *(.data)
+ *(.data.*)
+ }
+
+ .bss : {
+ *(.bss)
+ *(.bss.*)
+ *(COMMON)
+
+ /* Stack and heap */
+
+ . = ALIGN(16);
+ _heap = .;
+ . += HEAP_SIZE;
+ . = ALIGN(16);
+ _eheap = .;
+
+ _stack = .;
+ . += STACK_SIZE;
+ . = ALIGN(16);
+ _stack = .;
+ }
+
+ /* Put the static bits of our inital stack at the bottom */
+ .istack : {
+ *(.istack)
+ }
+
+ _end = .;
+
+ /DISCARD/ : { *(.comment) *(.note) *(.note.*) }
+}
diff --git a/payloads/libpayload/sample/Makefile b/payloads/libpayload/sample/Makefile
new file mode 100644
index 0000000000..a2599fbc32
--- /dev/null
+++ b/payloads/libpayload/sample/Makefile
@@ -0,0 +1,51 @@
+##
+## This file is part of the libpayload project.
+##
+## Copyright (C) 2008 Advanced Micro Devices, Inc.
+##
+## Redistribution and use in source and binary forms, with or without
+## modification, are permitted provided that the following conditions
+## are met:
+## 1. Redistributions of source code must retain the above copyright
+## notice, this list of conditions and the following disclaimer.
+## 2. Redistributions in binary form must reproduce the above copyright
+## notice, this list of conditions and the following disclaimer in the
+## documentation and/or other materials provided with the distribution.
+## 3. The name of the author may not be used to endorse or promote products
+## derived from this software without specific prior written permission.
+##
+## THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+## ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+## FOR ANY 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) ARISING IN ANY WAY
+## OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+## SUCH DAMAGE.
+##
+
+# Sample libpayload Makefile.
+
+CC=gcc
+CROSS_CFLAGS = -m32
+
+INCLUDES=-I../include
+INCLUDES += -I$(shell $(CC) $(CROSS_CFLAGS) -print-search-dirs | head -n 1 | cut -d' ' -f2)include
+
+LIBPAYLOAD=../libpayload.a
+LIBGCC:=$(shell $(CC) $(CROSS_CFLAGS) -print-libgcc-file-name)
+CFLAGS := -Werror -fno-stack-protector -nostdinc $(INCLUDES)
+
+all: hello.elf
+
+hello.elf: hello.o
+ ld -T ../libpayload.ldscript -o $@ hello.o ../i386/head.o $(LIBPAYLOAD) $(LIBGCC)
+
+hello.o: hello.c
+ $(CC) $(CROSS_CFLAGS) $(CFLAGS) -c -o $@ $<
+
+clean:
+ rm -f hello.elf hello.o
diff --git a/payloads/libpayload/sample/hello.c b/payloads/libpayload/sample/hello.c
new file mode 100644
index 0000000000..01948f6d8a
--- /dev/null
+++ b/payloads/libpayload/sample/hello.c
@@ -0,0 +1,39 @@
+/*
+ * This file is part of the libpayload project.
+ *
+ * Copyright (C) 2008 Advanced Micro Devices, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY 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) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/* Example file for libpayload. */
+
+#include <libpayload.h>
+
+int main(void) {
+ printf("Hello world!\n");
+ halt();
+
+ return 0;
+}