[coreboot] Patch set updated for coreboot: 75527f0 userspace coreboot support

Cristian Măgherușan-Stanciu (cristi.magherusan@gmail.com) gerrit at coreboot.org
Sun Nov 4 00:07:34 CET 2012


Cristian Măgherușan-Stanciu (cristi.magherusan at gmail.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/1089

-gerrit

commit 75527f07de68f146b1798276f41091166c26e36b
Author: Rudolf Marek <r.marek at assembler.cz>
Date:   Tue Jun 5 00:15:56 2012 +0200

    userspace coreboot support
    
    Add the basic linux userspace support. Avoid the priviledge ops
    and map low mem area to 64KB (which is normally mappable)
    Provide the linux sycall & console.
    
    Change-Id: Iaeef5c159a1e8871ea24f57b4fd161f979a4ed77
    Signed-off-by: Rudolf Marek <r.marek at assembler.cz>
---
 src/Kconfig                    |  20 ++++
 src/arch/x86/boot/gdt.c        |   5 +-
 src/arch/x86/boot/tables.c     |   6 ++
 src/arch/x86/include/arch/io.h |  76 ++++++++++++++
 src/arch/x86/lib/c_start.S     |  36 ++++++-
 src/arch/x86/lib/ebda.c        |   3 +
 src/boot/hardwaremain.c        |  12 ++-
 src/console/Makefile.inc       |   1 +
 src/console/ulinux_console.c   |  18 ++++
 src/include/cpu/x86/lapic.h    |  12 +++
 src/include/termios.h          | 219 +++++++++++++++++++++++++++++++++++++++++
 src/include/ulinux.h           |  36 +++++++
 src/lib/Makefile.inc           |   3 +
 src/lib/ulinux.c               | 160 ++++++++++++++++++++++++++++++
 14 files changed, 602 insertions(+), 5 deletions(-)

diff --git a/src/Kconfig b/src/Kconfig
index 9630e0c..dce26b3 100644
--- a/src/Kconfig
+++ b/src/Kconfig
@@ -194,6 +194,26 @@ config REQUIRES_BLOB
 	  coreboot build for such a board can override this manually, but
 	  this option serves as warning that it might fail.
 
+config ULINUX
+	bool "Compile and run coreboot as Linux userspace process"
+	default n
+	help
+	  This option enables to run coreboot as Linux process which
+	  communicates with hardware using SerialICE.
+
+config ULINUX_VALGRIND
+	bool "Add valgrind instrumentation"
+	default n
+	depends on ULINUX
+	help
+	  This option enables to track heap using valgrind.
+
+config SERIALICE_HOST_DEV
+	string "SerialICE host device"
+	default "/dev/ttyUSB0"
+	depends on ULINUX
+	help
+	  Selects the serial port to which is connected your remote target.
 endmenu
 
 source src/mainboard/Kconfig
diff --git a/src/arch/x86/boot/gdt.c b/src/arch/x86/boot/gdt.c
index b425ade..407cfe2 100644
--- a/src/arch/x86/boot/gdt.c
+++ b/src/arch/x86/boot/gdt.c
@@ -38,7 +38,9 @@ void move_gdt(void)
 {
 	void *newgdt;
 	u16 num_gdt_bytes = &gdt_end - &gdt;
+#if CONFIG_ULINUX == 0
 	struct gdtarg gdtarg;
+#endif
 
 	newgdt = cbmem_find(CBMEM_ID_GDT);
 	if (!newgdt) {
@@ -50,11 +52,12 @@ void move_gdt(void)
 		printk(BIOS_DEBUG, "Moving GDT to %p...", newgdt);
 		memcpy((void*)newgdt, &gdt, num_gdt_bytes);
 	}
-
+#if CONFIG_ULINUX == 0
 	gdtarg.base = (u32)newgdt;
 	gdtarg.limit = num_gdt_bytes - 1;
 
 	__asm__ __volatile__ ("lgdt %0\n\t" : : "m" (gdtarg));
+#endif
 	printk(BIOS_DEBUG, "ok\n");
 }
 
diff --git a/src/arch/x86/boot/tables.c b/src/arch/x86/boot/tables.c
index df4729a..44c03c5 100644
--- a/src/arch/x86/boot/tables.c
+++ b/src/arch/x86/boot/tables.c
@@ -32,6 +32,7 @@
 #include <cbmem.h>
 #include <lib.h>
 #include <smbios.h>
+#include <ulinux.h>
 
 uint64_t high_tables_base = 0;
 uint64_t high_tables_size;
@@ -69,7 +70,12 @@ struct lb_memory *write_tables(void)
 	 * and the coreboot table use low_tables.
 	 */
 	low_table_start = 0;
+#if CONFIG_ULINUX
+	low_table_end = 0x10000;
+	ulinux_mmap(low_table_end, 0x1000);
+#else
 	low_table_end = 0x500;
+#endif
 
 #if CONFIG_GENERATE_PIRQ_TABLE
 #define MAX_PIRQ_TABLE_SIZE (4 * 1024)
diff --git a/src/arch/x86/include/arch/io.h b/src/arch/x86/include/arch/io.h
index f4c6967..88338e1 100644
--- a/src/arch/x86/include/arch/io.h
+++ b/src/arch/x86/include/arch/io.h
@@ -9,6 +9,7 @@
  * (insb/insw/insl/outsb/outsw/outsl).
  */
 #if defined(__ROMCC__)
+
 static inline void outb(uint8_t value, uint16_t port)
 {
 	__builtin_outb(value, port);
@@ -41,6 +42,9 @@ static inline uint32_t inl(uint16_t port)
 	return __builtin_inl(port);
 }
 #else
+
+#if defined(__PRE_RAM__) || defined(__SMM__) || CONFIG_ULINUX == 0
+
 static inline void outb(uint8_t value, uint16_t port)
 {
 	__asm__ __volatile__ ("outb %b0, %w1" : : "a" (value), "Nd" (port));
@@ -76,6 +80,43 @@ static inline uint32_t inl(uint16_t port)
 	__asm__ __volatile__ ("inl %w1, %0" : "=a"(value) : "Nd" (port));
 	return value;
 }
+
+#else /* CONFIG_ULINUX == 1 */
+
+#include <console/console.h>
+#include <serialice_host.h>
+
+static inline void outb(uint8_t value, uint16_t port)
+{
+	serialice_outb(value, port);
+}
+
+static inline void outw(uint16_t value, uint16_t port)
+{
+	serialice_outw(value, port);
+}
+
+static inline void outl(uint32_t value, uint16_t port)
+{
+	serialice_outl(value, port);
+}
+
+static inline uint8_t inb(uint16_t port)
+{
+	return serialice_inb(port);
+}
+
+static inline uint16_t inw(uint16_t port)
+{
+	return serialice_inw(port);
+}
+
+static inline uint32_t inl(uint16_t port)
+{
+	return serialice_inl(port);
+}
+
+#endif /* CONFIG_ULINUX */
 #endif /* __ROMCC__ */
 
 static inline void outsb(uint16_t port, const void *addr, unsigned long count)
@@ -133,6 +174,9 @@ static inline void insl(uint16_t port, void *addr, unsigned long count)
 		);
 }
 
+
+#if defined(__PRE_RAM__) || defined(__SMM__) || CONFIG_ULINUX == 0
+
 static inline __attribute__((always_inline)) uint8_t read8(unsigned long addr)
 {
 	return *((volatile uint8_t *)(addr));
@@ -163,5 +207,37 @@ static inline __attribute__((always_inline)) void write32(unsigned long addr, ui
 	*((volatile uint32_t *)(addr)) = value;
 }
 
+#else /* CONFIG_ULINUX */
+
+static inline __attribute__((always_inline)) uint8_t read8(unsigned long addr)
+{
+	return serialice_readb(addr);
+}
+
+static inline __attribute__((always_inline)) uint16_t read16(unsigned long addr)
+{
+	return serialice_readw(addr);
+}
+
+static inline __attribute__((always_inline)) uint32_t read32(unsigned long addr)
+{
+	return serialice_readl(addr);
+}
+
+static inline __attribute__((always_inline)) void write8(unsigned long addr, uint8_t value)
+{
+	serialice_writeb(value, addr);
+}
+
+static inline __attribute__((always_inline)) void write16(unsigned long addr, uint16_t value)
+{
+	serialice_writew(value, addr);
+}
+
+static inline __attribute__((always_inline)) void write32(unsigned long addr, uint32_t value)
+{
+	serialice_writel(value, addr);
+}
+#endif
 #endif
 
diff --git a/src/arch/x86/lib/c_start.S b/src/arch/x86/lib/c_start.S
index 9c1fdb1..ca37a19 100644
--- a/src/arch/x86/lib/c_start.S
+++ b/src/arch/x86/lib/c_start.S
@@ -4,6 +4,8 @@
 	.code32
 	.globl _start
 _start:
+
+#if CONFIG_ULINUX == 0
 	cli
 	lgdt	%cs:gdtaddr
 	ljmp	$0x10, $1f
@@ -13,8 +15,8 @@ _start:
 	movl	%eax, %ss
 	movl	%eax, %fs
 	movl	%eax, %gs
-
 	post_code(POST_ENTRY_C_START)		/* post 13 */
+#endif
 
 	/** poison the stack. Code should not count on the
 	 * stack being full of zeros. This stack poisoning
@@ -53,7 +55,7 @@ _start:
 
 	/* Save the stack location */
 	movl	%esp, %ebp
-
+#if CONFIG_ULINUX == 0
 	/* Initialize the Interrupt Descriptor table */
 	leal	_idt, %edi
 	leal	vec0, %ebx
@@ -71,13 +73,13 @@ _start:
 
 	/* Load the Interrupt descriptor table */
 	lidt	idtarg
-
 	/*
 	 *	Now we are finished. Memory is up, data is copied and
 	 *	bss is cleared.   Now we call the main routine and
 	 *	let it do the rest.
 	 */
 	post_code(POST_PRE_HARDWAREMAIN)	/* post fe */
+#endif
 
 	/* Restore the stack location */
 	movl	%ebp, %esp
@@ -322,3 +324,31 @@ _idt_end:
 
 	.previous
 .code32
+
+#if CONFIG_ULINUX
+	.globl _call_linux
+	/* be paranoid of what registers to preserve for GCC */
+_call_linux:
+	pushl	%ebp
+	movl	%esp, %ebp
+	push	%ebx
+	push	%ecx
+	push	%edx
+	push	%esi
+	push	%edi
+	movl	0x8(%ebp), %eax
+	movl	0xc(%ebp), %ebx
+	movl	0x10(%ebp), %ecx
+	movl	0x14(%ebp), %edx
+	movl	0x18(%ebp), %esi
+	movl	0x1c(%ebp), %edi
+	movl	0x20(%ebp), %ebp
+	int	$0x80
+	popl	%edi
+	popl	%esi
+	popl	%edx
+	popl	%ecx
+	popl	%ebx
+	popl	%ebp
+	ret
+#endif
diff --git a/src/arch/x86/lib/ebda.c b/src/arch/x86/lib/ebda.c
index fb407b6..1a1d16d 100644
--- a/src/arch/x86/lib/ebda.c
+++ b/src/arch/x86/lib/ebda.c
@@ -35,6 +35,9 @@ void setup_ebda(u32 low_memory_size, u16 ebda_segment, u16 ebda_size)
 		return;
 #endif
 
+#if CONFIG_ULINUX
+	return;
+#endif
 	if (!low_memory_size || !ebda_segment || !ebda_size)
 		return;
 
diff --git a/src/boot/hardwaremain.c b/src/boot/hardwaremain.c
index 099ab3a..470b20e 100644
--- a/src/boot/hardwaremain.c
+++ b/src/boot/hardwaremain.c
@@ -36,6 +36,9 @@ it with the version available from LANL.
 #include <boot/elf.h>
 #include <cbfs.h>
 #include <lib.h>
+#if CONFIG_ULINUX
+#include <ulinux.h>
+#endif
 #if CONFIG_HAVE_ACPI_RESUME
 #include <arch/acpi.h>
 #endif
@@ -64,6 +67,10 @@ void hardwaremain(int boot_complete)
 #endif
 	post_code(POST_ENTRY_RAMSTAGE);
 
+#if CONFIG_ULINUX
+	ulinux_init();
+#endif
+
 	/* console_init() MUST PRECEDE ALL printk()! */
 	console_init();
 
@@ -146,7 +153,10 @@ void hardwaremain(int boot_complete)
 	lb_mem = write_tables();
 
 	timestamp_add_now(TS_LOAD_PAYLOAD);
-
+#if CONFIG_ULINUX
+	printk(BIOS_INFO, "All done, exiting\n");
+	ulinux_exit(0);
+#endif
 	void *payload;
 	payload = cbfs_load_payload(lb_mem, CONFIG_CBFS_PREFIX "/payload");
 	if (! payload)
diff --git a/src/console/Makefile.inc b/src/console/Makefile.inc
index f8928ad..c1d55da 100644
--- a/src/console/Makefile.inc
+++ b/src/console/Makefile.inc
@@ -20,6 +20,7 @@ driver-$(CONFIG_USBDEBUG) += usbdebug_console.c
 driver-$(CONFIG_CONSOLE_LOGBUF) += logbuf_console.c
 driver-$(CONFIG_CONSOLE_NE2K) += ne2k_console.c
 driver-$(CONFIG_CONSOLE_CBMEM) += cbmem_console.c
+driver-$(CONFIG_ULINUX) += ulinux_console.c
 
 
 $(obj)/console/console.ramstage.o : $(obj)/build.h
diff --git a/src/console/ulinux_console.c b/src/console/ulinux_console.c
new file mode 100644
index 0000000..4a5dd47
--- /dev/null
+++ b/src/console/ulinux_console.c
@@ -0,0 +1,18 @@
+#include <console/console.h>
+#include <ulinux.h>
+
+static void linux_tx_byte(unsigned char byte)
+{
+	unsigned char c;
+	c = byte;
+
+	ulinux_write(1, &c, 1);
+}
+
+
+static const struct console_driver linux_console __console = {
+	.init    = 0,
+	.tx_byte = linux_tx_byte,
+	.rx_byte = 0,
+	.tst_byte = 0,
+};
diff --git a/src/include/cpu/x86/lapic.h b/src/include/cpu/x86/lapic.h
index 078f2a7..a6a07c1 100644
--- a/src/include/cpu/x86/lapic.h
+++ b/src/include/cpu/x86/lapic.h
@@ -5,6 +5,10 @@
 #include <cpu/x86/msr.h>
 #include <arch/hlt.h>
 
+#if CONFIG_ULINUX && !defined(__PRE_RAM__)
+#include <serialice_host.h>
+#endif
+
 /* See if I need to initialize the local apic */
 #if CONFIG_SMP || CONFIG_IOAPIC
 #  define NEED_LAPIC 1
@@ -14,12 +18,20 @@
 
 static inline __attribute__((always_inline)) unsigned long lapic_read(unsigned long reg)
 {
+#if CONFIG_ULINUX && !defined(__PRE_RAM__)
+	return serialice_readl((LAPIC_DEFAULT_BASE+reg));
+#else
 	return *((volatile unsigned long *)(LAPIC_DEFAULT_BASE+reg));
+#endif
 }
 
 static inline __attribute__((always_inline)) void lapic_write(unsigned long reg, unsigned long v)
 {
+#if CONFIG_ULINUX && !defined(__PRE_RAM__)
+	serialice_writel(v, LAPIC_DEFAULT_BASE+reg);
+#else
 	*((volatile unsigned long *)(LAPIC_DEFAULT_BASE+reg)) = v;
+#endif
 }
 
 static inline __attribute__((always_inline)) void lapic_wait_icr_idle(void)
diff --git a/src/include/termios.h b/src/include/termios.h
new file mode 100644
index 0000000..5133e6b
--- /dev/null
+++ b/src/include/termios.h
@@ -0,0 +1,219 @@
+/* termios type and macro definitions.  Linux version.
+   Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2003, 2005
+	Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#ifndef _TERMIOS_H
+///# error "Never include <bits/termios.h> directly; use <termios.h> instead."
+#define _TERMIOS_H
+
+typedef unsigned char	cc_t;
+typedef unsigned int	speed_t;
+typedef unsigned int	tcflag_t;
+
+#define NCCS 32
+struct termios
+  {
+    tcflag_t c_iflag;		/* input mode flags */
+    tcflag_t c_oflag;		/* output mode flags */
+    tcflag_t c_cflag;		/* control mode flags */
+    tcflag_t c_lflag;		/* local mode flags */
+    cc_t c_line;			/* line discipline */
+    cc_t c_cc[NCCS];		/* control characters */
+    speed_t c_ispeed;		/* input speed */
+    speed_t c_ospeed;		/* output speed */
+#define _HAVE_STRUCT_TERMIOS_C_ISPEED 1
+#define _HAVE_STRUCT_TERMIOS_C_OSPEED 1
+  };
+
+/* c_cc characters */
+#define VINTR 0
+#define VQUIT 1
+#define VERASE 2
+#define VKILL 3
+#define VEOF 4
+#define VTIME 5
+#define VMIN 6
+#define VSWTC 7
+#define VSTART 8
+#define VSTOP 9
+#define VSUSP 10
+#define VEOL 11
+#define VREPRINT 12
+#define VDISCARD 13
+#define VWERASE 14
+#define VLNEXT 15
+#define VEOL2 16
+
+/* c_iflag bits */
+#define IGNBRK	0000001
+#define BRKINT	0000002
+#define IGNPAR	0000004
+#define PARMRK	0000010
+#define INPCK	0000020
+#define ISTRIP	0000040
+#define INLCR	0000100
+#define IGNCR	0000200
+#define ICRNL	0000400
+#define IUCLC	0001000
+#define IXON	0002000
+#define IXANY	0004000
+#define IXOFF	0010000
+#define IMAXBEL	0020000
+#define IUTF8	0040000
+
+/* c_oflag bits */
+#define OPOST	0000001
+#define OLCUC	0000002
+#define ONLCR	0000004
+#define OCRNL	0000010
+#define ONOCR	0000020
+#define ONLRET	0000040
+#define OFILL	0000100
+#define OFDEL	0000200
+#if defined __USE_MISC || defined __USE_XOPEN
+# define NLDLY	0000400
+# define   NL0	0000000
+# define   NL1	0000400
+# define CRDLY	0003000
+# define   CR0	0000000
+# define   CR1	0001000
+# define   CR2	0002000
+# define   CR3	0003000
+# define TABDLY	0014000
+# define   TAB0	0000000
+# define   TAB1	0004000
+# define   TAB2	0010000
+# define   TAB3	0014000
+# define BSDLY	0020000
+# define   BS0	0000000
+# define   BS1	0020000
+# define FFDLY	0100000
+# define   FF0	0000000
+# define   FF1	0100000
+#endif
+
+#define VTDLY	0040000
+#define   VT0	0000000
+#define   VT1	0040000
+
+#ifdef __USE_MISC
+# define XTABS	0014000
+#endif
+
+/* c_cflag bit meaning */
+#ifdef __USE_MISC
+# define CBAUD	0010017
+#endif
+#define  B0	0000000		/* hang up */
+#define  B50	0000001
+#define  B75	0000002
+#define  B110	0000003
+#define  B134	0000004
+#define  B150	0000005
+#define  B200	0000006
+#define  B300	0000007
+#define  B600	0000010
+#define  B1200	0000011
+#define  B1800	0000012
+#define  B2400	0000013
+#define  B4800	0000014
+#define  B9600	0000015
+#define  B19200	0000016
+#define  B38400	0000017
+#ifdef __USE_MISC
+# define EXTA B19200
+# define EXTB B38400
+#endif
+#define CSIZE	0000060
+#define   CS5	0000000
+#define   CS6	0000020
+#define   CS7	0000040
+#define   CS8	0000060
+#define CSTOPB	0000100
+#define CREAD	0000200
+#define PARENB	0000400
+#define PARODD	0001000
+#define HUPCL	0002000
+#define CLOCAL	0004000
+#ifdef __USE_MISC
+# define CBAUDEX 0010000
+#endif
+#define  B57600   0010001
+#define  B115200  0010002
+#define  B230400  0010003
+#define  B460800  0010004
+#define  B500000  0010005
+#define  B576000  0010006
+#define  B921600  0010007
+#define  B1000000 0010010
+#define  B1152000 0010011
+#define  B1500000 0010012
+#define  B2000000 0010013
+#define  B2500000 0010014
+#define  B3000000 0010015
+#define  B3500000 0010016
+#define  B4000000 0010017
+#define __MAX_BAUD B4000000
+#ifdef __USE_MISC
+# define CIBAUD	  002003600000		/* input baud rate (not used) */
+# define CMSPAR   010000000000		/* mark or space (stick) parity */
+# define CRTSCTS  020000000000		/* flow control */
+#endif
+
+/* c_lflag bits */
+#define ISIG	0000001
+#define ICANON	0000002
+#if defined __USE_MISC || defined __USE_XOPEN
+# define XCASE	0000004
+#endif
+#define ECHO	0000010
+#define ECHOE	0000020
+#define ECHOK	0000040
+#define ECHONL	0000100
+#define NOFLSH	0000200
+#define TOSTOP	0000400
+#ifdef __USE_MISC
+# define ECHOCTL 0001000
+# define ECHOPRT 0002000
+# define ECHOKE	 0004000
+# define FLUSHO	 0010000
+# define PENDIN	 0040000
+#endif
+#define IEXTEN	0100000
+
+/* tcflow() and TCXONC use these */
+#define	TCOOFF		0
+#define	TCOON		1
+#define	TCIOFF		2
+#define	TCION		3
+
+/* tcflush() and TCFLSH use these */
+#define	TCIFLUSH	0
+#define	TCOFLUSH	1
+#define	TCIOFLUSH	2
+
+/* tcsetattr uses these */
+#define	TCSANOW		0
+#define	TCSADRAIN	1
+#define	TCSAFLUSH	2
+
+
+#define _IOT_termios /* Hurd ioctl type field.  */ \
+  _IOT (_IOTS (cflag_t), 4, _IOTS (cc_t), NCCS, _IOTS (speed_t), 2)
+#endif
diff --git a/src/include/ulinux.h b/src/include/ulinux.h
new file mode 100644
index 0000000..e0408ad
--- /dev/null
+++ b/src/include/ulinux.h
@@ -0,0 +1,36 @@
+#include <stdint.h>
+#include <termios.h>
+extern  int _call_linux(uint32_t a0, uint32_t a1, uint32_t a2, uint32_t a3, uint32_t a4, uint32_t a5, uint32_t a6);
+
+void __stack_chk_init(void);
+void *ulinux_mmap(unsigned long addr, unsigned int length);
+int ulinux_write(int fd, const void *buf, unsigned int count);
+int ulinux_close(int fd);
+int ulinux_read(int fd, void *buf, unsigned int count);
+int ulinux_open(const char *pathname, int flags);
+
+#define EINTR 4
+extern int ulinux_errno;
+
+#define O_RDWR		00000002
+#define O_NOCTTY	   0400	/* not fcntl */
+#define O_NONBLOCK	  04000
+#define O_NDELAY	O_NONBLOCK
+#define F_SETFL		4	/* Set file status flags.  */
+#define EOF -1
+
+#define perror(x) printk(BIOS_ERR, x)
+
+int ulinux_ioctl(int d, int request);
+
+int ulinux_tcgetattr(int fd, struct termios *termios_p);
+int ulinux_cfsetispeed(struct termios *termios_p, speed_t speed);
+int ulinux_cfsetospeed(struct termios *termios_p, speed_t speed);
+int ulinux_tcsetattr(int fd, int optional_actions,
+                     const struct termios *termios_p);
+void ulinux_exit(int status);
+int ulinux_fcntl(int fd, int cmd, int a);
+int ulinux_tcflush(int fd, int queue_selector);
+void ulinux_init(void);
+
+#define TIOCEXCL        0x540C
diff --git a/src/lib/Makefile.inc b/src/lib/Makefile.inc
index ec57bc2..6eeae78 100644
--- a/src/lib/Makefile.inc
+++ b/src/lib/Makefile.inc
@@ -44,6 +44,9 @@ ramstage-y += stack.c
 ramstage-y += gcc.c
 ramstage-y += clog2.c
 ramstage-y += cbmem.c
+ramstage-$(CONFIG_ULINUX) += ulinux.c
+ramstage-$(CONFIG_ULINUX) += serialice_host.c
+
 ramstage-$(CONFIG_CONSOLE_SERIAL8250) += uart8250.c
 ramstage-$(CONFIG_CONSOLE_SERIAL8250MEM) += uart8250mem.c
 ramstage-$(CONFIG_CONSOLE_CBMEM) += cbmem_console.c
diff --git a/src/lib/ulinux.c b/src/lib/ulinux.c
new file mode 100644
index 0000000..a9c0431
--- /dev/null
+++ b/src/lib/ulinux.c
@@ -0,0 +1,160 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2012 Rudolf Marek <r.marek at assembler.cz>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+
+#include <stdlib.h>
+#include <console/console.h>
+#include <serialice_host.h>
+#include <ulinux.h>
+
+#if CONFIG_ULINUX_VALGRIND
+#include "valgrind.h"
+#include "memcheck.h"
+extern unsigned char _heap, _eheap;
+#endif
+
+#define NR_EXIT 1
+#define NR_MMAP 192
+#define NR_READ 3
+#define NR_WRITE 4
+#define NR_OPEN 5
+#define NR_CLOSE 6
+#define NR_IOCTL 54
+#define NR_FCNTL 55
+
+#define TCGETS 0x5401
+#define TCSETS 0x5402
+#define TCFLSH 0x540b
+
+int ulinux_errno;
+
+
+unsigned long __stack_chk_guard = 0xdeadbeef;
+
+void __stack_chk_init(void)
+{
+}
+
+void __stack_chk_fail(void);
+
+void __attribute__ ((noreturn)) __stack_chk_fail(void)
+{
+	die("Stack SMASHED\n");
+}
+
+void ulinux_init(void)
+{
+	/* Map last 64KB of 1MB */
+	ulinux_mmap((960 * 1024), 64 * 1024);
+
+#if CONFIG_ULINUX_VALGRIND
+	VALGRIND_CREATE_MEMPOOL(&_heap, 8, 0);
+	VALGRIND_MAKE_MEM_NOACCESS(&_heap,  &_eheap - &_heap);
+#endif
+
+//	serialice_init();
+
+}
+
+void *ulinux_mmap(unsigned long addr, unsigned int size)
+{
+	return (void *) _call_linux(NR_MMAP, (uint32_t) addr, size,
+				    (uint32_t) 3, 0x32, -1, 0);
+}
+
+int ulinux_write(int fd, const void *buf, unsigned int count)
+{
+	return _call_linux(NR_WRITE, (uint32_t) fd, (uint32_t) buf,
+			   (uint32_t) count, 0, 0, 0);
+}
+
+int ulinux_close(int fd)
+{
+	return _call_linux(NR_CLOSE, (uint32_t) fd, 0, 0, 0, 0, 0);
+}
+
+int ulinux_read(int fd, void *buf, unsigned int count)
+{
+	int ret =
+	    _call_linux(NR_READ, (uint32_t) fd, (uint32_t) buf,
+			(uint32_t) count,
+			0, 0, 0);
+	ulinux_errno = (ret < 0) ? -ret : 0;
+	return ret;
+}
+
+
+int ulinux_open(const char *pathname, int flags)
+{
+	return _call_linux(NR_OPEN, (uint32_t) pathname, (uint32_t) flags,
+			   (uint32_t) 0, 0, 0, 0);
+
+}
+
+
+int ulinux_ioctl(int fd, int request)
+{
+	return _call_linux(NR_IOCTL, (uint32_t) fd, (uint32_t) request,
+			   (uint32_t) 0, 0, 0, 0);
+}
+
+int ulinux_tcgetattr(int fd, struct termios *termios_p)
+{
+	return _call_linux(NR_IOCTL, (uint32_t) fd, TCGETS,
+			   (uint32_t) termios_p, 0, 0, 0);
+}
+
+
+int ulinux_cfsetispeed(struct termios *termios_p, speed_t speed)
+{
+	termios_p->c_ispeed = speed;
+	return 0;
+}
+
+int ulinux_cfsetospeed(struct termios *termios_p, speed_t speed)
+{
+	termios_p->c_ospeed = speed;
+	return 0;
+}
+
+int ulinux_tcsetattr(int fd, int optional_actions,
+		     const struct termios *termios_p)
+{
+	return _call_linux(NR_IOCTL, (uint32_t) fd, TCSETS,
+			   (uint32_t) termios_p,
+			   (uint32_t) optional_actions, 0, 0);
+
+}
+
+void ulinux_exit(int status)
+{
+	_call_linux(NR_EXIT, status, 0, 0, 0, 0, 0);
+}
+
+int ulinux_fcntl(int fd, int cmd, int a)
+{
+	return _call_linux(NR_FCNTL, (uint32_t) fd, (uint32_t) cmd,
+			   (uint32_t) a, 0, 0, 0);
+}
+
+int ulinux_tcflush(int fd, int queue_selector)
+{
+	return _call_linux(NR_IOCTL, (uint32_t) fd, TCFLSH,
+			   (uint32_t) queue_selector, 0, 0, 0);
+
+}




More information about the coreboot mailing list