summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/Kconfig8
-rw-r--r--src/arch/i386/Makefile.inc5
-rw-r--r--src/arch/i386/include/arch/llshell.h11
-rw-r--r--src/arch/i386/llshell/console.inc515
-rw-r--r--src/arch/i386/llshell/llshell.inc4
-rw-r--r--src/arch/i386/llshell/pci.inc229
-rw-r--r--src/arch/i386/llshell/ramtest.inc125
-rw-r--r--src/mainboard/thomson/ip1000/romstage.c4
8 files changed, 901 insertions, 0 deletions
diff --git a/src/Kconfig b/src/Kconfig
index 96413ffd3f..1331f557e9 100644
--- a/src/Kconfig
+++ b/src/Kconfig
@@ -793,6 +793,14 @@ config X86EMU_DEBUG_IO
If unsure, say N.
+config LLSHELL
+ bool "Built-in low-level shell"
+ default n
+ help
+ If enabled, you will have a low level shell to examine your machine.
+ Put llshell() in your (romstage) code to start the shell.
+ See src/arch/i386/llshell/llshell.inc for details.
+
endmenu
config LIFT_BSP_APIC_ID
diff --git a/src/arch/i386/Makefile.inc b/src/arch/i386/Makefile.inc
index a16972ca93..e9a9225d20 100644
--- a/src/arch/i386/Makefile.inc
+++ b/src/arch/i386/Makefile.inc
@@ -148,6 +148,11 @@ ifeq ($(CONFIG_ROMCC),y)
crt0s += $(obj)/mainboard/$(MAINBOARDDIR)/failover.inc
endif
endif
+
+ifeq ($(CONFIG_LLSHELL),y)
+crt0s += $(src)/arch/i386/llshell/llshell.inc
+endif
+
crt0s += $(obj)/mainboard/$(MAINBOARDDIR)/romstage.inc
ifeq ($(CONFIG_SSE),y)
diff --git a/src/arch/i386/include/arch/llshell.h b/src/arch/i386/include/arch/llshell.h
new file mode 100644
index 0000000000..556df7d046
--- /dev/null
+++ b/src/arch/i386/include/arch/llshell.h
@@ -0,0 +1,11 @@
+#ifndef __ARCH_LLSHELL__
+#define __ARCH_LLSHELL__
+
+
+#if CONFIG_LLSHELL
+#define llshell() asm("jmp low_level_shell");
+#else
+#define llshell() print_debug("LLSHELL not active.\n");
+#endif
+
+#endif
diff --git a/src/arch/i386/llshell/console.inc b/src/arch/i386/llshell/console.inc
new file mode 100644
index 0000000000..fbe9d632bf
--- /dev/null
+++ b/src/arch/i386/llshell/console.inc
@@ -0,0 +1,515 @@
+// #include <loglevel.h>
+
+jmp console0
+
+#define __STR(X) #X
+#define STR(X) __STR(X)
+
+
+#undef STR
+ /* uses: ax, dx */
+#if defined(SERIAL_CONSOLE)
+#define __CONSOLE_INLINE_TX_AL TTYS0_TX_AL
+#else
+#define __CONSOLE_INLINE_TX_AL
+#endif
+
+ /* uses: esp, ax, dx */
+#define __CONSOLE_TX_CHAR(byte) \
+ mov byte, %al ; \
+ CALLSP(console_tx_al)
+
+ /* uses: ax, dx */
+#define __CONSOLE_INLINE_TX_CHAR(byte) \
+ mov byte, %al ; \
+ __CONSOLE_INLINE_TX_AL
+
+ /* uses: esp, ax, edx */
+#define __CONSOLE_TX_HEX8(byte) \
+ mov byte, %al ; \
+ CALLSP(console_tx_hex8)
+
+ /* uses: byte, ax, dx */
+#define __CONSOLE_INLINE_TX_HEX8(byte) \
+ movb byte, %dl ; \
+ shll $16, %edx ; \
+ shr $4, %al ; \
+ add $'0', %al ; \
+ cmp $'9', %al ; \
+ jle 9f ; \
+ add $39, %al ; \
+9: ; \
+ __CONSOLE_INLINE_TX_AL ; \
+ shrl $16, %edx ; \
+ movb %dl, %al ; \
+ and $0x0f, %al ; \
+ add $'0', %al ; \
+ cmp $'9', %al ; \
+ jle 9f ; \
+ add $39, %al ; \
+9: ; \
+ __CONSOLE_INLINE_TX_AL
+
+ /* uses: esp, eax, ebx, dx */
+#define __CONSOLE_TX_HEX32(lword) \
+ mov lword, %eax ; \
+ CALLSP(console_tx_hex32)
+
+ /* uses: eax, lword, dx */
+#define __CONSOLE_INLINE_TX_HEX32(lword) \
+ mov lword, %eax ; \
+ shr $28, %eax ; \
+ add $'0', %al ; \
+ cmp $'9', %al ; \
+ jle 9f ; \
+ add $39, %al ; \
+9: ; \
+ __CONSOLE_INLINE_TX_AL ; \
+ ; \
+ mov lword, %eax ; \
+ shr $24, %eax ; \
+ and $0x0f, %al ; \
+ add $'0', %al ; \
+ cmp $'9', %al ; \
+ jle 9f ; \
+ add $39, %al ; \
+9: ; \
+ __CONSOLE_INLINE_TX_AL ; \
+ ; \
+ mov lword, %eax ; \
+ shr $20, %eax ; \
+ and $0x0f, %al ; \
+ add $'0', %al ; \
+ cmp $'9', %al ; \
+ jle 9f ; \
+ add $39, %al ; \
+9: ; \
+ __CONSOLE_INLINE_TX_AL ; \
+ ; \
+ mov lword, %eax ; \
+ shr $16, %eax ; \
+ and $0x0f, %al ; \
+ add $'0', %al ; \
+ cmp $'9', %al ; \
+ jle 9f ; \
+ add $39, %al ; \
+9: ; \
+ __CONSOLE_INLINE_TX_AL ; \
+ ; \
+ mov lword, %eax ; \
+ shr $12, %eax ; \
+ and $0x0f, %al ; \
+ add $'0', %al ; \
+ cmp $'9', %al ; \
+ jle 9f ; \
+ add $39, %al ; \
+9: ; \
+ __CONSOLE_INLINE_TX_AL ; \
+ ; \
+ mov lword, %eax ; \
+ shr $8, %eax ; \
+ and $0x0f, %al ; \
+ add $'0', %al ; \
+ cmp $'9', %al ; \
+ jle 9f ; \
+ add $39, %al ; \
+9: ; \
+ __CONSOLE_INLINE_TX_AL ; \
+ ; \
+ mov lword, %eax ; \
+ shr $4, %eax ; \
+ and $0x0f, %al ; \
+ add $'0', %al ; \
+ cmp $'9', %al ; \
+ jle 9f ; \
+ add $39, %al ; \
+9: ; \
+ __CONSOLE_INLINE_TX_AL ; \
+ ; \
+ mov lword, %eax ; \
+ and $0x0f, %al ; \
+ add $'0', %al ; \
+ cmp $'9', %al ; \
+ jle 9f ; \
+ add $39, %al ; \
+9: ; \
+ __CONSOLE_INLINE_TX_AL
+
+
+ /* uses: esp, ebx, ax, dx */
+#define __CONSOLE_TX_STRING(string) \
+ mov string, %ebx ; \
+ CALLSP(console_tx_string)
+
+ /* uses: ebx, ax, dx */
+#define __CONSOLE_INLINE_TX_STRING(string) \
+ movl string, %ebx ; \
+10: movb (%ebx), %al ; \
+ incl %ebx ; \
+ testb %al, %al ; \
+ jz 11f ; \
+ __CONSOLE_INLINE_TX_AL ; \
+ jmp 10b ; \
+11:
+
+
+#define CONSOLE_EMERG_TX_CHAR(byte) __CONSOLE_TX_CHAR(byte)
+#define CONSOLE_EMERG_INLINE_TX_CHAR(byte) __CONSOLE_INLINE_TX_CHAR(byte)
+#define CONSOLE_EMERG_TX_HEX8(byte) __CONSOLE_TX_HEX8(byte)
+#define CONSOLE_EMERG_INLINE_TX_HEX8(byte) __CONSOLE_INLINE_TX_HEX8(byte)
+#define CONSOLE_EMERG_TX_HEX32(lword) __CONSOLE_TX_HEX32(lword)
+#define CONSOLE_EMERG_INLINE_TX_HEX32(lword) __CONSOLE_INLINE_TX_HEX32(lword)
+#define CONSOLE_EMERG_TX_STRING(string) __CONSOLE_TX_STRING(string)
+#define CONSOLE_EMERG_INLINE_TX_STRING(string) __CONSOLE_INLINE_TX_STRING(string)
+
+#define CONSOLE_ALERT_TX_CHAR(byte) __CONSOLE_TX_CHAR(byte)
+#define CONSOLE_ALERT_INLINE_TX_CHAR(byte) __CONSOLE_INLINE_TX_CHAR(byte)
+#define CONSOLE_ALERT_TX_HEX8(byte) __CONSOLE_TX_HEX8(byte)
+#define CONSOLE_ALERT_INLINE_TX_HEX8(byte) __CONSOLE_INLINE_TX_HEX8(byte)
+#define CONSOLE_ALERT_TX_HEX32(lword) __CONSOLE_TX_HEX32(lword)
+#define CONSOLE_ALERT_INLINE_TX_HEX32(lword) __CONSOLE_INLINE_TX_HEX32(lword)
+#define CONSOLE_ALERT_TX_STRING(string) __CONSOLE_TX_STRING(string)
+#define CONSOLE_ALERT_INLINE_TX_STRING(string) __CONSOLE_INLINE_TX_STRING(string)
+
+#define CONSOLE_CRIT_TX_CHAR(byte) __CONSOLE_TX_CHAR(byte)
+#define CONSOLE_CRIT_INLINE_TX_CHAR(byte) __CONSOLE_INLINE_TX_CHAR(byte)
+#define CONSOLE_CRIT_TX_HEX8(byte) __CONSOLE_TX_HEX8(byte)
+#define CONSOLE_CRIT_INLINE_TX_HEX8(byte) __CONSOLE_INLINE_TX_HEX8(byte)
+#define CONSOLE_CRIT_TX_HEX32(lword) __CONSOLE_TX_HEX32(lword)
+#define CONSOLE_CRIT_INLINE_TX_HEX32(lword) __CONSOLE_INLINE_TX_HEX32(lword)
+#define CONSOLE_CRIT_TX_STRING(string) __CONSOLE_TX_STRING(string)
+#define CONSOLE_CRIT_INLINE_TX_STRING(string) __CONSOLE_INLINE_TX_STRING(string)
+
+#define CONSOLE_ERR_TX_CHAR(byte) __CONSOLE_TX_CHAR(byte)
+#define CONSOLE_ERR_INLINE_TX_CHAR(byte) __CONSOLE_INLINE_TX_CHAR(byte)
+#define CONSOLE_ERR_TX_HEX8(byte) __CONSOLE_TX_HEX8(byte)
+#define CONSOLE_ERR_INLINE_TX_HEX8(byte) __CONSOLE_INLINE_TX_HEX8(byte)
+#define CONSOLE_ERR_TX_HEX32(lword) __CONSOLE_TX_HEX32(lword)
+#define CONSOLE_ERR_INLINE_TX_HEX32(lword) __CONSOLE_INLINE_TX_HEX32(lword)
+#define CONSOLE_ERR_TX_STRING(string) __CONSOLE_TX_STRING(string)
+#define CONSOLE_ERR_INLINE_TX_STRING(string) __CONSOLE_INLINE_TX_STRING(string)
+
+#define CONSOLE_WARNING_TX_CHAR(byte) __CONSOLE_TX_CHAR(byte)
+#define CONSOLE_WARNING_INLINE_TX_CHAR(byte) __CONSOLE_INLINE_TX_CHAR(byte)
+#define CONSOLE_WARNING_TX_HEX8(byte) __CONSOLE_TX_HEX8(byte)
+#define CONSOLE_WARNING_INLINE_TX_HEX8(byte) __CONSOLE_INLINE_TX_HEX8(byte)
+#define CONSOLE_WARNING_TX_HEX32(lword) __CONSOLE_TX_HEX32(lword)
+#define CONSOLE_WARNING_INLINE_TX_HEX32(lword) __CONSOLE_INLINE_TX_HEX32(lword)
+#define CONSOLE_WARNING_TX_STRING(string) __CONSOLE_TX_STRING(string)
+#define CONSOLE_WARNING_INLINE_TX_STRING(string) __CONSOLE_INLINE_TX_STRING(string)
+
+#define CONSOLE_NOTICE_TX_CHAR(byte) __CONSOLE_TX_CHAR(byte)
+#define CONSOLE_NOTICE_INLINE_TX_CHAR(byte) __CONSOLE_INLINE_TX_CHAR(byte)
+#define CONSOLE_NOTICE_TX_HEX8(byte) __CONSOLE_TX_HEX8(byte)
+#define CONSOLE_NOTICE_INLINE_TX_HEX8(byte) __CONSOLE_INLINE_TX_HEX8(byte)
+#define CONSOLE_NOTICE_TX_HEX32(lword) __CONSOLE_TX_HEX32(lword)
+#define CONSOLE_NOTICE_INLINE_TX_HEX32(lword) __CONSOLE_INLINE_TX_HEX32(lword)
+#define CONSOLE_NOTICE_TX_STRING(string) __CONSOLE_TX_STRING(string)
+#define CONSOLE_NOTICE_INLINE_TX_STRING(string) __CONSOLE_INLINE_TX_STRING(string)
+
+#define CONSOLE_INFO_TX_CHAR(byte) __CONSOLE_TX_CHAR(byte)
+#define CONSOLE_INFO_INLINE_TX_CHAR(byte) __CONSOLE_INLINE_TX_CHAR(byte)
+#define CONSOLE_INFO_TX_HEX8(byte) __CONSOLE_TX_HEX8(byte)
+#define CONSOLE_INFO_INLINE_TX_HEX8(byte) __CONSOLE_INLINE_TX_HEX8(byte)
+#define CONSOLE_INFO_TX_HEX32(lword) __CONSOLE_TX_HEX32(lword)
+#define CONSOLE_INFO_INLINE_TX_HEX32(lword) __CONSOLE_INLINE_TX_HEX32(lword)
+#define CONSOLE_INFO_TX_STRING(string) __CONSOLE_TX_STRING(string)
+#define CONSOLE_INFO_INLINE_TX_STRING(string) __CONSOLE_INLINE_TX_STRING(string)
+
+#define CONSOLE_DEBUG_TX_CHAR(byte) __CONSOLE_TX_CHAR(byte)
+#define CONSOLE_DEBUG_INLINE_TX_CHAR(byte) __CONSOLE_INLINE_TX_CHAR(byte)
+#define CONSOLE_DEBUG_TX_HEX8(byte) __CONSOLE_TX_HEX8(byte)
+#define CONSOLE_DEBUG_INLINE_TX_HEX8(byte) __CONSOLE_INLINE_TX_HEX8(byte)
+#define CONSOLE_DEBUG_TX_HEX32(lword) __CONSOLE_TX_HEX32(lword)
+#define CONSOLE_DEBUG_INLINE_TX_HEX32(lword) __CONSOLE_INLINE_TX_HEX32(lword)
+#define CONSOLE_DEBUG_TX_STRING(string) __CONSOLE_TX_STRING(string)
+#define CONSOLE_DEBUG_INLINE_TX_STRING(string) __CONSOLE_INLINE_TX_STRING(string)
+
+#define CONSOLE_SPEW_TX_CHAR(byte) __CONSOLE_TX_CHAR(byte)
+#define CONSOLE_SPEW_INLINE_TX_CHAR(byte) __CONSOLE_INLINE_TX_CHAR(byte)
+#define CONSOLE_SPEW_TX_HEX8(byte) __CONSOLE_TX_HEX8(byte)
+#define CONSOLE_SPEW_INLINE_TX_HEX8(byte) __CONSOLE_INLINE_TX_HEX8(byte)
+#define CONSOLE_SPEW_TX_HEX32(lword) __CONSOLE_TX_HEX32(lword)
+#define CONSOLE_SPEW_INLINE_TX_HEX32(lword) __CONSOLE_INLINE_TX_HEX32(lword)
+#define CONSOLE_SPEW_TX_STRING(string) __CONSOLE_TX_STRING(string)
+#define CONSOLE_SPEW_INLINE_TX_STRING(string) __CONSOLE_INLINE_TX_STRING(string)
+
+#if 0
+#if ASM_CONSOLE_LOGLEVEL <= BIOS_EMERG
+#undef CONSOLE_EMERG_TX_CHAR
+#undef CONSOLE_EMERG_INLINE_TX_CHAR
+#undef CONSOLE_EMERG_TX_HEX8
+#undef CONSOLE_EMERG_INLINE_TX_HEX8
+#undef CONSOLE_EMERG_TX_HEX32
+#undef CONSOLE_EMERG_INLINE_TX_HEX32
+#undef CONSOLE_EMERG_TX_STRING
+#undef CONSOLE_EMERG_INLINE_TX_STRING
+#define CONSOLE_EMERG_TX_CHAR(byte)
+#define CONSOLE_EMERG_INLINE_TX_CHAR(byte)
+#define CONSOLE_EMERG_TX_HEX8(byte)
+#define CONSOLE_EMERG_INLINE_TX_HEX8(byte)
+#define CONSOLE_EMERG_TX_HEX32(lword)
+#define CONSOLE_EMERG_INLINE_TX_HEX32(lword)
+#define CONSOLE_EMERG_TX_STRING(string)
+#define CONSOLE_EMERG_INLINE_TX_STRING(string)
+#endif
+
+
+#if ASM_CONSOLE_LOGLEVEL <= BIOS_ALERT
+#undef CONSOLE_ALERT_TX_CHAR
+#undef CONSOLE_ALERT_INLINE_TX_CHAR
+#undef CONSOLE_ALERT_TX_HEX8
+#undef CONSOLE_ALERT_INLINE_TX_HEX8
+#undef CONSOLE_ALERT_TX_HEX32
+#undef CONSOLE_ALERT_INLINE_TX_HEX32
+#undef CONSOLE_ALERT_TX_STRING
+#undef CONSOLE_ALERT_INLINE_TX_STRING
+#define CONSOLE_ALERT_TX_CHAR(byte)
+#define CONSOLE_ALERT_INLINE_TX_CHAR(byte)
+#define CONSOLE_ALERT_TX_HEX8(byte)
+#define CONSOLE_ALERT_INLINE_TX_HEX8(byte)
+#define CONSOLE_ALERT_TX_HEX32(lword)
+#define CONSOLE_ALERT_INLINE_TX_HEX32(lword)
+#define CONSOLE_ALERT_TX_STRING(string)
+#define CONSOLE_ALERT_INLINE_TX_STRING(string)
+#endif
+
+#if ASM_CONSOLE_LOGLEVEL <= BIOS_CRIT
+#undef CONSOLE_CRIT_TX_CHAR
+#undef CONSOLE_CRIT_INLINE_TX_CHAR
+#undef CONSOLE_CRIT_TX_HEX8
+#undef CONSOLE_CRIT_INLINE_TX_HEX8
+#undef CONSOLE_CRIT_TX_HEX32
+#undef CONSOLE_CRIT_INLINE_TX_HEX32
+#undef CONSOLE_CRIT_TX_STRING
+#undef CONSOLE_CRIT_INLINE_TX_STRING
+#define CONSOLE_CRIT_TX_CHAR(byte)
+#define CONSOLE_CRIT_INLINE_TX_CHAR(byte)
+#define CONSOLE_CRIT_TX_HEX8(byte)
+#define CONSOLE_CRIT_INLINE_TX_HEX8(byte)
+#define CONSOLE_CRIT_TX_HEX32(lword)
+#define CONSOLE_CRIT_INLINE_TX_HEX32(lword)
+#define CONSOLE_CRIT_TX_STRING(string)
+#define CONSOLE_CRIT_INLINE_TX_STRING(string)
+#endif
+
+#if ASM_CONSOLE_LOGLEVEL <= BIOS_ERR
+#undef CONSOLE_ERR_TX_CHAR
+#undef CONSOLE_ERR_INLINE_TX_CHAR
+#undef CONSOLE_ERR_TX_HEX8
+#undef CONSOLE_ERR_INLINE_TX_HEX8
+#undef CONSOLE_ERR_TX_HEX32
+#undef CONSOLE_ERR_INLINE_TX_HEX32
+#undef CONSOLE_ERR_TX_STRING
+#undef CONSOLE_ERR_INLINE_TX_STRING
+#define CONSOLE_ERR_TX_CHAR(byte)
+#define CONSOLE_ERR_INLINE_TX_CHAR(byte)
+#define CONSOLE_ERR_TX_HEX8(byte)
+#define CONSOLE_ERR_INLINE_TX_HEX8(byte)
+#define CONSOLE_ERR_TX_HEX32(lword)
+#define CONSOLE_ERR_INLINE_TX_HEX32(lword)
+#define CONSOLE_ERR_TX_STRING(string)
+#define CONSOLE_ERR_INLINE_TX_STRING(string)
+#endif
+
+#if ASM_CONSOLE_LOGLEVEL <= BIOS_WARNING
+#undef CONSOLE_WARNING_TX_CHAR
+#undef CONSOLE_WARNING_INLINE_TX_CHAR
+#undef CONSOLE_WARNING_TX_HEX8
+#undef CONSOLE_WARNING_INLINE_TX_HEX8
+#undef CONSOLE_WARNING_TX_HEX32
+#undef CONSOLE_WARNING_INLINE_TX_HEX32
+#undef CONSOLE_WARNING_TX_STRING
+#undef CONSOLE_WARNING_INLINE_TX_STRING
+#define CONSOLE_WARNING_TX_CHAR(byte)
+#define CONSOLE_WARNING_INLINE_TX_CHAR(byte)
+#define CONSOLE_WARNING_TX_HEX8(byte)
+#define CONSOLE_WARNING_INLINE_TX_HEX8(byte)
+#define CONSOLE_WARNING_TX_HEX32(lword)
+#define CONSOLE_WARNING_INLINE_TX_HEX32(lword)
+#define CONSOLE_WARNING_TX_STRING(string)
+#define CONSOLE_WARNING_INLINE_TX_STRING(string)
+#endif
+
+#if ASM_CONSOLE_LOGLEVEL <= BIOS_NOTICE
+#undef CONSOLE_NOTICE_TX_CHAR
+#undef CONSOLE_NOTICE_INLINE_TX_CHAR
+#undef CONSOLE_NOTICE_TX_HEX8
+#undef CONSOLE_NOTICE_INLINE_TX_HEX8
+#undef CONSOLE_NOTICE_TX_HEX32
+#undef CONSOLE_NOTICE_INLINE_TX_HEX32
+#undef CONSOLE_NOTICE_TX_STRING
+#undef CONSOLE_NOTICE_INLINE_TX_STRING
+#define CONSOLE_NOTICE_TX_CHAR(byte)
+#define CONSOLE_NOTICE_INLINE_TX_CHAR(byte)
+#define CONSOLE_NOTICE_TX_HEX8(byte)
+#define CONSOLE_NOTICE_INLINE_TX_HEX8(byte)
+#define CONSOLE_NOTICE_TX_HEX32(lword)
+#define CONSOLE_NOTICE_INLINE_TX_HEX32(lword)
+#define CONSOLE_NOTICE_TX_STRING(string)
+#define CONSOLE_NOTICE_INLINE_TX_STRING(string)
+#endif
+
+#if ASM_CONSOLE_LOGLEVEL <= BIOS_INFO
+#undef CONSOLE_INFO_TX_CHAR
+#undef CONSOLE_INFO_INLINE_TX_CHAR
+#undef CONSOLE_INFO_TX_HEX8
+#undef CONSOLE_INFO_INLINE_TX_HEX8
+#undef CONSOLE_INFO_TX_HEX32
+#undef CONSOLE_INFO_INLINE_TX_HEX32
+#undef CONSOLE_INFO_TX_STRING
+#undef CONSOLE_INFO_INLINE_TX_STRING
+#define CONSOLE_INFO_TX_CHAR(byte)
+#define CONSOLE_INFO_INLINE_TX_CHAR(byte)
+#define CONSOLE_INFO_TX_HEX8(byte)
+#define CONSOLE_INFO_INLINE_TX_HEX8(byte)
+#define CONSOLE_INFO_TX_HEX32(lword)
+#define CONSOLE_INFO_INLINE_TX_HEX32(lword)
+#define CONSOLE_INFO_TX_STRING(string)
+#define CONSOLE_INFO_INLINE_TX_STRING(string)
+#endif
+
+#if ASM_CONSOLE_LOGLEVEL <= BIOS_DEBUG
+#undef CONSOLE_DEBUG_TX_CHAR
+#undef CONSOLE_DEBUG_INLINE_TX_CHAR
+#undef CONSOLE_DEBUG_TX_HEX8
+#undef CONSOLE_DEBUG_INLINE_TX_HEX8
+#undef CONSOLE_DEBUG_TX_HEX32
+#undef CONSOLE_DEBUG_INLINE_TX_HEX32
+#undef CONSOLE_DEBUG_TX_STRING
+#undef CONSOLE_DEBUG_INLINE_TX_STRING
+#define CONSOLE_DEBUG_TX_CHAR(byte)
+#define CONSOLE_DEBUG_INLINE_TX_CHAR(byte)
+#define CONSOLE_DEBUG_TX_HEX8(byte)
+#define CONSOLE_DEBUG_INLINE_TX_HEX8(byte)
+#define CONSOLE_DEBUG_TX_HEX32(lword)
+#define CONSOLE_DEBUG_INLINE_TX_HEX32(lword)
+#define CONSOLE_DEBUG_TX_STRING(string)
+#define CONSOLE_DEBUG_INLINE_TX_STRING(string)
+#endif
+
+#if ASM_CONSOLE_LOGLEVEL <= BIOS_SPEW
+#undef CONSOLE_SPEW_TX_CHAR
+#undef CONSOLE_SPEW_INLINE_TX_CHAR
+#undef CONSOLE_SPEW_TX_HEX8
+#undef CONSOLE_SPEW_INLINE_TX_HEX8
+#undef CONSOLE_SPEW_TX_HEX32
+#undef CONSOLE_SPEW_INLINE_TX_HEX32
+#undef CONSOLE_SPEW_TX_STRING
+#undef CONSOLE_SPEW_INLINE_TX_STRING
+#define CONSOLE_SPEW_TX_CHAR(byte)
+#define CONSOLE_SPEW_INLINE_TX_CHAR(byte)
+#define CONSOLE_SPEW_TX_HEX8(byte)
+#define CONSOLE_SPEW_INLINE_TX_HEX8(byte)
+#define CONSOLE_SPEW_TX_HEX32(lword)
+#define CONSOLE_SPEW_INLINE_TX_HEX32(lword)
+#define CONSOLE_SPEW_TX_STRING(string)
+#define CONSOLE_SPEW_INLINE_TX_STRING(string)
+#endif
+#endif
+
+ /* uses: esp, ax, dx */
+console_tx_al:
+ __CONSOLE_INLINE_TX_AL
+ RETSP
+
+ /* uses: esp, ax, edx */
+console_tx_hex8:
+ __CONSOLE_INLINE_TX_HEX8(%al)
+ RETSP
+
+
+ /* uses: esp, ebx, eax, dx */
+console_tx_hex32:
+ mov %eax, %ebx
+ shr $28, %eax
+ add $'0', %al
+ cmp $'9', %al
+ jle 9f
+ add $39, %al
+9:
+ __CONSOLE_INLINE_TX_AL
+
+ mov %ebx, %eax
+ shr $24, %eax
+ and $0x0f, %al
+ add $'0', %al
+ cmp $'9', %al
+ jle 9f
+ add $39, %al
+9:
+ __CONSOLE_INLINE_TX_AL
+
+ mov %ebx, %eax
+ shr $20, %eax
+ and $0x0f, %al
+ add $'0', %al
+ cmp $'9', %al
+ jle 9f
+ add $39, %al
+9:
+ __CONSOLE_INLINE_TX_AL
+
+ mov %ebx, %eax
+ shr $16, %eax
+ and $0x0f, %al
+ add $'0', %al
+ cmp $'9', %al
+ jle 9f
+ add $39, %al
+9:
+ __CONSOLE_INLINE_TX_AL
+
+ mov %ebx, %eax
+ shr $12, %eax
+ and $0x0f, %al
+ add $'0', %al
+ cmp $'9', %al
+ jle 9f
+ add $39, %al
+9:
+ __CONSOLE_INLINE_TX_AL
+
+ mov %ebx, %eax
+ shr $8, %eax
+ and $0x0f, %al
+ add $'0', %al
+ cmp $'9', %al
+ jle 9f
+ add $39, %al
+9:
+ __CONSOLE_INLINE_TX_AL
+
+ mov %ebx, %eax
+ shr $4, %eax
+ and $0x0f, %al
+ add $'0', %al
+ cmp $'9', %al
+ jle 9f
+ add $39, %al
+9:
+ __CONSOLE_INLINE_TX_AL
+
+ mov %ebx, %eax
+ and $0x0f, %al
+ add $'0', %al
+ cmp $'9', %al
+ jle 9f
+ add $39, %al
+9:
+ __CONSOLE_INLINE_TX_AL
+ RETSP
+
+ /* Uses esp, ebx, ax, dx */
+
+console_tx_string:
+ mov (%ebx), %al
+ inc %ebx
+ cmp $0, %al
+ jne 9f
+ RETSP
+9:
+ __CONSOLE_INLINE_TX_AL
+ jmp console_tx_string
+
+console0:
diff --git a/src/arch/i386/llshell/llshell.inc b/src/arch/i386/llshell/llshell.inc
index 8054a0a6e7..6c91661f83 100644
--- a/src/arch/i386/llshell/llshell.inc
+++ b/src/arch/i386/llshell/llshell.inc
@@ -1,3 +1,7 @@
+#include "console.inc"
+#include "pci.inc"
+#include "ramtest.inc"
+
jmp llshell_out
// (c) 2004 Bryan Chafy, This program is released under the GPL
diff --git a/src/arch/i386/llshell/pci.inc b/src/arch/i386/llshell/pci.inc
new file mode 100644
index 0000000000..eb4d3c3845
--- /dev/null
+++ b/src/arch/i386/llshell/pci.inc
@@ -0,0 +1,229 @@
+
+ /*
+ * Macro: PCI_WRITE_CONFIG_BYTE
+ * Arguments: %eax address to write to (includes bus, device, function, &offset)
+ * %dl byte to write
+ *
+ * Results: none
+ *
+ * Trashed: %eax, %edx
+ * Effects: writes a single byte to pci config space
+ *
+ * Notes: This routine is optimized for minimal register usage.
+ * And the tricks it does cannot scale beyond writing a single byte.
+ *
+ * What it does is almost simple.
+ * It preserves %eax (baring special bits) until it is written
+ * out to the appropriate port. And hides the data byte
+ * in the high half of edx.
+ *
+ * In %edx[3] it stores the byte to write.
+ * In %edx[2] it stores the lower three bits of the address.
+ */
+
+
+#define PCI_WRITE_CONFIG_BYTE \
+ shll $8, %edx ; \
+ movb %al, %dl ; \
+ andb $0x3, %dl ; \
+ shll $16, %edx ; \
+ \
+ orl $0x80000000, %eax ; \
+ andl $0xfffffffc, %eax ; \
+ movw $0xcf8, %dx ; \
+ outl %eax, %dx ; \
+ \
+ shrl $16, %edx ; \
+ movb %dh, %al ; \
+ movb $0, %dh ; \
+ addl $0xcfc, %edx ; \
+ outb %al, %dx
+
+
+ /*
+ * Macro: PCI_WRITE_CONFIG_WORD
+ * Arguments: %eax address to write to (includes bus, device, function, &offset)
+ * %ecx word to write
+ *
+ * Results: none
+ *
+ * Trashed: %eax, %edx
+ * Preserved: %ecx
+ * Effects: writes a single byte to pci config space
+ *
+ * Notes: This routine is optimized for minimal register usage.
+ *
+ * What it does is almost simple.
+ * It preserves %eax (baring special bits) until it is written
+ * out to the appropriate port. And hides the least significant
+ * bits of the address in the high half of edx.
+ *
+ * In %edx[2] it stores the lower three bits of the address.
+ */
+
+
+#define PCI_WRITE_CONFIG_WORD \
+ movb %al, %dl ; \
+ andl $0x3, %edx ; \
+ shll $16, %edx ; \
+ \
+ orl $0x80000000, %eax ; \
+ andl $0xfffffffc, %eax ; \
+ movw $0xcf8, %dx ; \
+ outl %eax, %dx ; \
+ \
+ shrl $16, %edx ; \
+ movl %ecx, %eax ; \
+ addl $0xcfc, %edx ; \
+ outw %ax, %dx
+
+
+
+ /*
+ * Macro: PCI_WRITE_CONFIG_DWORD
+ * Arguments: %eax address to write to (includes bus, device, function, &offset)
+ * %ecx dword to write
+ *
+ * Results: none
+ *
+ * Trashed: %eax, %edx
+ * Preserved: %ecx
+ * Effects: writes a single byte to pci config space
+ *
+ * Notes: This routine is optimized for minimal register usage.
+ *
+ * What it does is almost simple.
+ * It preserves %eax (baring special bits) until it is written
+ * out to the appropriate port. And hides the least significant
+ * bits of the address in the high half of edx.
+ *
+ * In %edx[2] it stores the lower three bits of the address.
+ */
+
+
+#define PCI_WRITE_CONFIG_DWORD \
+ movb %al, %dl ; \
+ andl $0x3, %edx ; \
+ shll $16, %edx ; \
+ \
+ orl $0x80000000, %eax ; \
+ andl $0xfffffffc, %eax ; \
+ movw $0xcf8, %dx ; \
+ outl %eax, %dx ; \
+ \
+ shrl $16, %edx ; \
+ movl %ecx, %eax ; \
+ addl $0xcfc, %edx ; \
+ outl %eax, %dx
+
+
+
+
+ /*
+ * Macro: PCI_READ_CONFIG_BYTE
+ * Arguments: %eax address to read from (includes bus, device, function, &offset)
+ *
+ * Results: %al Byte read
+ *
+ * Trashed: %eax, %edx
+ * Effects: reads a single byte from pci config space
+ *
+ * Notes: This routine is optimized for minimal register usage.
+ *
+ * What it does is almost simple.
+ * It preserves %eax (baring special bits) until it is written
+ * out to the appropriate port. And hides the least significant
+ * bits of the address in the high half of edx.
+ *
+ * In %edx[2] it stores the lower three bits of the address.
+ */
+
+
+#define PCI_READ_CONFIG_BYTE \
+ movb %al, %dl ; \
+ andl $0x3, %edx ; \
+ shll $16, %edx ; \
+ \
+ orl $0x80000000, %eax ; \
+ andl $0xfffffffc, %eax ; \
+ movw $0xcf8, %dx ; \
+ outl %eax, %dx ; \
+ \
+ shrl $16, %edx ; \
+ addl $0xcfc, %edx ; \
+ inb %dx, %al
+
+
+
+ /*
+ * Macro: PCI_READ_CONFIG_WORD
+ * Arguments: %eax address to read from (includes bus, device, function, &offset)
+ *
+ * Results: %ax word read
+ *
+ * Trashed: %eax, %edx
+ * Effects: reads a 2 bytes from pci config space
+ *
+ * Notes: This routine is optimized for minimal register usage.
+ *
+ * What it does is almost simple.
+ * It preserves %eax (baring special bits) until it is written
+ * out to the appropriate port. And hides the least significant
+ * bits of the address in the high half of edx.
+ *
+ * In %edx[2] it stores the lower three bits of the address.
+ */
+
+
+#define PCI_READ_CONFIG_WORD \
+ movb %al, %dl ; \
+ andl $0x3, %edx ; \
+ shll $16, %edx ; \
+ \
+ orl $0x80000000, %eax ; \
+ andl $0xfffffffc, %eax ; \
+ movw $0xcf8, %dx ; \
+ outl %eax, %dx ; \
+ \
+ shrl $16, %edx ; \
+ addl $0xcfc, %edx ; \
+ inw %dx, %ax
+
+
+
+ /*
+ * Macro: PCI_READ_CONFIG_DWORD
+ * Arguments: %eax address to read from (includes bus, device, function, &offset)
+ *
+ * Results: %eax
+ *
+ * Trashed: %edx
+ * Effects: reads 4 bytes from pci config space
+ *
+ * Notes: This routine is optimized for minimal register usage.
+ *
+ * What it does is almost simple.
+ * It preserves %eax (baring special bits) until it is written
+ * out to the appropriate port. And hides the least significant
+ * bits of the address in the high half of edx.
+ *
+ * In %edx[2] it stores the lower three bits of the address.
+ */
+
+
+#define PCI_READ_CONFIG_DWORD \
+ movb %al, %dl ; \
+ andl $0x3, %edx ; \
+ shll $16, %edx ; \
+ \
+ orl $0x80000000, %eax ; \
+ andl $0xfffffffc, %eax ; \
+ movw $0xcf8, %dx ; \
+ outl %eax, %dx ; \
+ \
+ shrl $16, %edx ; \
+ addl $0xcfc, %edx ; \
+ inl %dx, %eax
+
+
+
diff --git a/src/arch/i386/llshell/ramtest.inc b/src/arch/i386/llshell/ramtest.inc
new file mode 100644
index 0000000000..dfe06adf71
--- /dev/null
+++ b/src/arch/i386/llshell/ramtest.inc
@@ -0,0 +1,125 @@
+ /*
+ * This is much more of a "Is my SDRAM properly configured?"
+ * test than a "Is my SDRAM faulty?" test. Not all bits
+ * are tested. -Tyson
+ */
+
+ jmp rt_skip
+#define RAMTEST 1
+#if RAMTEST
+ .section ".rom.data"
+
+rt_test: .string "Testing SDRAM : "
+rt_fill: .string "SDRAM fill:\r\n"
+rt_verify: .string "SDRAM verify:\r\n"
+rt_toomany: .string "Too many errors.\r\n"
+rt_done: .string "Done.\r\n"
+ .previous
+#endif
+
+ramtest:
+#if RAMTEST
+ mov %eax, %esi
+ mov %ebx, %edi
+ mov %esp, %ebp
+
+ CONSOLE_INFO_TX_STRING($rt_test)
+ CONSOLE_INFO_TX_HEX32(%esi)
+ CONSOLE_INFO_TX_CHAR($'-')
+ CONSOLE_INFO_TX_HEX32(%edi)
+ CONSOLE_INFO_TX_CHAR($'\r')
+ CONSOLE_INFO_TX_CHAR($'\n')
+
+ /* ============== Fill ram block ==== */
+
+ CONSOLE_INFO_TX_STRING($rt_fill)
+
+ mov %esi, %ebx
+1:
+ cmp $0, %bx
+ jne 2f
+
+ /* Display address being filled */
+ /* CONSOLE_INFO_TX_HEX32(arg) will overwrite %ebx with arg */
+
+ CONSOLE_INFO_TX_HEX32(%ebx)
+ CONSOLE_INFO_TX_CHAR($'\r')
+2:
+#if i786
+ /* Use a non temporal store to go faster and
+ * to bypass the cache.
+ */
+ movnti %ebx, (%ebx)
+#else
+ mov %ebx, (%ebx)
+#endif
+ add $4, %ebx
+ cmp %edi, %ebx
+ jl 1b
+
+ /* Display final address */
+
+ CONSOLE_INFO_TX_HEX32(%edi)
+ CONSOLE_INFO_TX_CHAR($'\r')
+ CONSOLE_INFO_TX_CHAR($'\n')
+
+ /* ========= Verify ram block ========== */
+
+ CONSOLE_INFO_TX_STRING($rt_verify)
+ mov %esi, %ebx
+
+1:
+ cmp $0, %bx
+ jne 2f
+
+ /* Display address being tested */
+
+ CONSOLE_INFO_TX_HEX32(%ebx)
+ CONSOLE_INFO_TX_CHAR($'\r')
+2:
+ cmp %ebx, (%ebx)
+ jne 4f
+3:
+ add $4, %ebx
+ cmp %edi, %ebx
+ jl 1b
+
+ /* Display final address */
+ CONSOLE_INFO_TX_HEX32(%edi)
+ CONSOLE_INFO_TX_CHAR($'\r')
+ CONSOLE_INFO_TX_CHAR($'\n')
+ jmp 6f
+
+4:
+ /* Display address with error */
+
+ CONSOLE_INFO_TX_HEX32(%ebx)
+ CONSOLE_INFO_TX_CHAR($':')
+
+ /* Display data in address with error */
+
+ /* CONSOLE_INFO_TX_HEX32(arg) will overwrite %ebx with arg */
+
+ mov %ebx, %esi
+ mov 0(%ebx), %eax
+ CONSOLE_INFO_TX_HEX32(%eax)
+ mov %esi, %ebx
+
+ CONSOLE_INFO_TX_CHAR($'\r')
+ CONSOLE_INFO_TX_CHAR($'\n')
+ sub $1, %ecx
+ jz 5f
+ jmp 3b
+5:
+ CONSOLE_INFO_TX_STRING($rt_toomany)
+ intel_chip_post_macro(0xf1)
+ jmp .Lhlt
+
+6:
+ CONSOLE_INFO_TX_STRING($rt_done)
+ mov %ebp, %esp
+
+#endif
+ RETSP
+
+rt_skip:
diff --git a/src/mainboard/thomson/ip1000/romstage.c b/src/mainboard/thomson/ip1000/romstage.c
index 8b70d9ffc7..362f04e992 100644
--- a/src/mainboard/thomson/ip1000/romstage.c
+++ b/src/mainboard/thomson/ip1000/romstage.c
@@ -28,6 +28,7 @@
#include <device/pnp_def.h>
#include <arch/romcc_io.h>
#include <arch/hlt.h>
+#include <arch/llshell.h>
#include "pc80/serial.c"
#include "pc80/udelay_io.c"
#include "arch/i386/lib/console.c"
@@ -129,6 +130,9 @@ static void main(unsigned long bist)
/* Initialize memory */
sdram_initialize();
+#if CONFIG_LLSHELL
+ llshell();
+#endif
/* Check RAM. */
/* ram_check(0, 640 * 1024); */
/* ram_check(64512 * 1024, 65536 * 1024); */