Patchwork revive llshell

login
register
about
Submitter Stefan Reinauer
Date 2010-03-07 14:40:09
Message ID <4B93BAC9.2070900@coresystems.de>
Download mbox | patch
Permalink /patch/1021/
State Accepted
Commit r5206
Headers show

Comments

Stefan Reinauer - 2010-03-07 14:40:09
Ron and Peter should like this.... "Panic Room" there you go.

It's of course completely useless if the machine hangs. It could be made
part of "die()" though.

Stefan
So either we kill llshell or we fix it. Attached patch fixes it.
llshell was broken since we're not version 1 anymore.. Incredible.

The new files are taken from v1 code; if anyone wants this to work, I'll go
look for the correct headers... 

Signed-off-by: Stefan Reinauer <stepan@coresystems.de>
Patrick Georgi - 2010-03-10 08:57:37
Am 07.03.2010 15:40, schrieb Stefan Reinauer:
> Ron and Peter should like this.... "Panic Room" there you go.
> 
> It's of course completely useless if the machine hangs. It could be made
> part of "die()" though.
Maybe guard the Kconfig option with "depends on CONFIG_EXPERT"?

With or without, it's
Acked-by: Patrick Georgi <patrick.georgi@coresystems.de>

Patch

Index: src/Kconfig
===================================================================
--- src/Kconfig	(revision 5195)
+++ src/Kconfig	(working copy)
@@ -793,6 +793,14 @@ 
 
 	  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
Index: src/mainboard/thomson/ip1000/romstage.c
===================================================================
--- src/mainboard/thomson/ip1000/romstage.c	(revision 5195)
+++ src/mainboard/thomson/ip1000/romstage.c	(working copy)
@@ -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 @@ 
 	/* Initialize memory */
 	sdram_initialize();
 
+#if CONFIG_LLSHELL
+	llshell();
+#endif
 	/* Check RAM. */
 	/* ram_check(0, 640 * 1024); */
 	/* ram_check(64512 * 1024, 65536 * 1024); */
Index: src/arch/i386/llshell/pci.inc
===================================================================
--- src/arch/i386/llshell/pci.inc	(revision 0)
+++ src/arch/i386/llshell/pci.inc	(revision 0)
@@ -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
+
+
+
Index: src/arch/i386/llshell/llshell.inc
===================================================================
--- src/arch/i386/llshell/llshell.inc	(revision 5195)
+++ src/arch/i386/llshell/llshell.inc	(working copy)
@@ -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
Index: src/arch/i386/llshell/ramtest.inc
===================================================================
--- src/arch/i386/llshell/ramtest.inc	(revision 0)
+++ src/arch/i386/llshell/ramtest.inc	(revision 0)
@@ -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:
Index: src/arch/i386/llshell/console.inc
===================================================================
--- src/arch/i386/llshell/console.inc	(revision 0)
+++ src/arch/i386/llshell/console.inc	(revision 0)
@@ -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:
Index: src/arch/i386/include/arch/llshell.h
===================================================================
--- src/arch/i386/include/arch/llshell.h	(revision 0)
+++ src/arch/i386/include/arch/llshell.h	(revision 0)
@@ -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
Index: src/arch/i386/Makefile.inc
===================================================================
--- src/arch/i386/Makefile.inc	(revision 5195)
+++ src/arch/i386/Makefile.inc	(working copy)
@@ -148,6 +148,11 @@ 
 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)