[coreboot] New patch to review for coreboot: 0672250 userspace coreboot support
Rudolf Marek (r.marek@assembler.cz)
gerrit at coreboot.org
Tue Jun 5 01:02:24 CEST 2012
Rudolf Marek (r.marek at assembler.cz) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/1089
-gerrit
commit 0672250797641683cab727784362d1d4be9ffb28
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 | 11 ++
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(+), 4 deletions(-)
diff --git a/src/Kconfig b/src/Kconfig
index a5a0f00..21efe56 100644
--- a/src/Kconfig
+++ b/src/Kconfig
@@ -193,6 +193,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 72aa979..456f161 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 005ac33..e5ea273 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
/** clear stack */
cld
@@ -49,7 +51,7 @@ _start:
/* Save the stack location */
movl %esp, %ebp
-
+#if CONFIG_ULINUX == 0
/* Initialize the Interrupt Descriptor table */
leal _idt, %edi
leal vec0, %ebx
@@ -67,13 +69,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
@@ -315,3 +317,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 d78b859..d244d8d 100644
--- a/src/boot/hardwaremain.c
+++ b/src/boot/hardwaremain.c
@@ -35,6 +35,9 @@ it with the version available from LANL.
#include <boot/tables.h>
#include <boot/elf.h>
#include <cbfs.h>
+#if CONFIG_ULINUX
+#include <ulinux.h>
+#endif
#if CONFIG_HAVE_ACPI_RESUME
#include <arch/acpi.h>
#endif
@@ -63,6 +66,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();
@@ -143,6 +150,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
cbfs_load_payload(lb_mem, CONFIG_CBFS_PREFIX "/payload");
printk(BIOS_ERR, "Boot failed.\n");
}
diff --git a/src/console/Makefile.inc b/src/console/Makefile.inc
index f3b8758..afde535 100644
--- a/src/console/Makefile.inc
+++ b/src/console/Makefile.inc
@@ -19,6 +19,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..7efeb45 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 !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 defined(__PRE_RAM__)
return *((volatile unsigned long *)(LAPIC_DEFAULT_BASE+reg));
+#else
+ return serialice_readl((LAPIC_DEFAULT_BASE+reg));
+#endif
}
static inline __attribute__((always_inline)) void lapic_write(unsigned long reg, unsigned long v)
{
+#if defined(__PRE_RAM__)
*((volatile unsigned long *)(LAPIC_DEFAULT_BASE+reg)) = v;
+#else
+ serialice_writel(v, LAPIC_DEFAULT_BASE+reg);
+#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 7c081ac..3bd7f99 100644
--- a/src/lib/Makefile.inc
+++ b/src/lib/Makefile.inc
@@ -42,6 +42,9 @@ ramstage-y += lzma.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