src/arch/x86. Signed-off-by: Stefan Reinauer <stepan@coreboot.org> Acked-by: Patrick Georgi <patrick@georgi-clan.de> git-svn-id: svn://svn.coreboot.org/coreboot/trunk@6161 2b7e53f0-3cfb-0310-b3e9-8179ed1497e1
902 lines
15 KiB
PHP
902 lines
15 KiB
PHP
|
|
#define RET_LABEL(label) \
|
|
jmp label##_done
|
|
|
|
#define CALL_LABEL(label) \
|
|
jmp label ;\
|
|
label##_done:
|
|
|
|
#define CALLSP(func) \
|
|
lea 0f, %esp ; \
|
|
jmp func ; \
|
|
0:
|
|
|
|
#define RETSP \
|
|
jmp *%esp
|
|
|
|
|
|
#include "console.inc"
|
|
#include "pci.inc"
|
|
#include "ramtest.inc"
|
|
|
|
jmp llshell_out
|
|
|
|
// (c) 2004 Bryan Chafy, This program is released under the GPL
|
|
|
|
// LLShell, A low level interactive debug shell
|
|
// Designed to be an interactive shell that operates with zero
|
|
// system resources. For example at initial boot.
|
|
|
|
// to use, jump to label "low_level_shell"
|
|
// set %esp to the return address for exiting
|
|
|
|
|
|
#define UART_BASEADDR $0x3f8
|
|
#define resultreg %esi
|
|
#define subroutinereg %edi
|
|
#define freqtime $2193 // 1.93 * freq
|
|
#define timertime $6000
|
|
.equ sys_IOPL, 110
|
|
|
|
// .data
|
|
// .text
|
|
|
|
welcome:
|
|
.string "\r\n! Low Level Shell (LLShell) (c)2004 Bryan Chafy \r\n\r\n"
|
|
prompt:
|
|
.string "\r\n!> "
|
|
badcmd:
|
|
.string "bad command\r\n"
|
|
sorry:
|
|
.string "sorry, not yet implemented\r\n"
|
|
cmds:
|
|
.string "\r\nList of commands:\r\n \
|
|
\r\nbeep -- pc speaker beep \
|
|
\r\nrst (or RST) -- reset \
|
|
\r\nout(b,w,l) <val> <port> -- raw out val at port \
|
|
\r\nin(b,w,l) <port> -- show raw port value \
|
|
\r\njmp <address> -- jmp to address (llshell addr is in eax) \
|
|
\r\ncall <address> -- funcion call (assumes a working stack) \
|
|
\r\ncli -- clear interrupts \
|
|
\r\nsti -- enable interrupts \
|
|
\r\npush <value> -- push value onto stack \
|
|
\r\npop -- pop from stack and display \
|
|
\r\nwm(b,w,l) <addr> <val> -- write mem \
|
|
\r\ndm <addr> <lines> -- dump mem \
|
|
\r\nmcp <src> <dst> <size> -- mem copy \
|
|
\r\nmpat <pat> <dst> <size> -- mem pattern \
|
|
\r\nmemt <begin> <end> -- memory test \
|
|
\r\npcir(b,w,l) <loc> -- pci read config \
|
|
\r\npciw(b,w,l) <loc> <val> -- pci write config \
|
|
\r\ndl <addr> <size> -- memory download (display xor cheksum at completion) \
|
|
\r\ncram <addr> <size> -- enable cache to be ram (experimental) \
|
|
\r\nbaud <val> -- change baudrate (not yet implemented) \
|
|
\r\nexit -- exit shell \
|
|
\r\nAll values in hex (0x prefixing ok) \
|
|
\r\n"
|
|
|
|
cr:
|
|
.string "\r\n"
|
|
spaces:
|
|
.string " "
|
|
|
|
// .globl _start
|
|
//ASSUME CS:@CODE, DS:@DATA
|
|
|
|
// _start:
|
|
|
|
// call ioperms
|
|
|
|
low_level_shell:
|
|
|
|
mov $preamble,subroutinereg
|
|
jmp beep
|
|
preamble:
|
|
mov $welcome,resultreg
|
|
mov $readcommand,subroutinereg
|
|
jmp displaystring
|
|
|
|
readcommand:
|
|
mov $prompt,resultreg
|
|
mov $rcmd,subroutinereg
|
|
jmp displaystring
|
|
|
|
rcmd:
|
|
mov $readcommand,subroutinereg
|
|
movl $0x0, resultreg
|
|
|
|
readchar:
|
|
mov UART_BASEADDR+5,%dx
|
|
in %dx, %al
|
|
and $0x9f,%al
|
|
test $0x01,%al
|
|
jz readchar
|
|
mov UART_BASEADDR,%dx
|
|
in %dx,%al //char in al
|
|
xchg %al,%ah
|
|
|
|
send_char:
|
|
mov UART_BASEADDR+5,%dx
|
|
us_wait:
|
|
in %dx,%al
|
|
test $0x20,%al
|
|
jz us_wait
|
|
mov UART_BASEADDR,%dx
|
|
xchg %al,%ah
|
|
out %al,%dx // output char
|
|
|
|
cmp $0x0D,%al //CR
|
|
jnz eval_char
|
|
mov $0x0A,%ah
|
|
jmp send_char
|
|
|
|
eval_char:
|
|
cmp $0x20,%al //space
|
|
jz cmdtable
|
|
cmp $0x0A,%al //CR
|
|
jz cmdtable
|
|
cmp $0x08,%al //BS
|
|
jnz additup
|
|
//subit:
|
|
shr $0x8,resultreg
|
|
jmp readchar
|
|
additup:
|
|
shl $0x8,resultreg
|
|
and $0xff,%eax
|
|
add %eax,resultreg
|
|
jmp readchar
|
|
|
|
cmdtable:
|
|
mov resultreg,%eax
|
|
cmp $0,%eax
|
|
jz readcommand
|
|
cmp $0x74657374,%eax
|
|
jz dotest
|
|
cmp $0x68656c70,%eax
|
|
jz dohelp
|
|
cmp $0x0000003f,%eax
|
|
jz dohelp
|
|
cmp $0x6f757462,%eax
|
|
jz dooutb
|
|
cmp $0x6f757477,%eax
|
|
jz dooutw
|
|
cmp $0x6f75746c,%eax
|
|
jz dooutd
|
|
cmp $0x00696e62,%eax
|
|
jz doinb
|
|
cmp $0x00696e77,%eax
|
|
jz doinw
|
|
cmp $0x00696e6c,%eax
|
|
jz doind
|
|
cmp $0x63697262,%eax
|
|
jz pcirb
|
|
cmp $0x63697277,%eax
|
|
jz pcirw
|
|
cmp $0x6369726c,%eax
|
|
jz pcirl
|
|
cmp $0x63697762,%eax
|
|
jz pciwb
|
|
cmp $0x63697777,%eax
|
|
jz pciww
|
|
cmp $0x6369776c,%eax
|
|
jz pciwl
|
|
cmp $0x00776d62,%eax
|
|
jz wmemb
|
|
cmp $0x00776d77,%eax
|
|
jz wmemw
|
|
cmp $0x00776d6c,%eax
|
|
jz wmeml
|
|
cmp $0x0000646d,%eax
|
|
jz dodmem
|
|
cmp $0x6d656d74,%eax
|
|
jz memt // mem test
|
|
cmp $0x00727374,%eax
|
|
jz rst // reset
|
|
cmp $0x00525354,%eax
|
|
jz RST
|
|
cmp $0x62656570,%eax
|
|
jz beep
|
|
cmp $0x0000646c,%eax
|
|
jz dodl // download to mem <loc> <size>
|
|
cmp $0x006a6d70,%eax
|
|
jz jmpto // jump to location (eax holds return addr)
|
|
cmp $0x62617564,%eax
|
|
jz baud // change baudrate
|
|
cmp $0x00696e74,%eax
|
|
jz doint // trigger an interrupt
|
|
cmp $0x63616c6c,%eax
|
|
jz callto // call assumes memory
|
|
cmp $0x70757368,%eax
|
|
jz dopush // assumes mem
|
|
cmp $0x00706f70,%eax
|
|
jz dopop // assumes mem
|
|
cmp $0x6372616d,%eax
|
|
jz cram // cache ram trick <location> <size>
|
|
cmp $0x006d6370,%eax
|
|
jz mcp // mem copy <src> <dst> <size>
|
|
cmp $0x6d706174,%eax
|
|
jz dopattern
|
|
cmp $0x00636c69,%eax
|
|
jz docli
|
|
cmp $0x00737469,%eax
|
|
jz dosti
|
|
cmp $0x65786974,%eax
|
|
jz doexit
|
|
mov $badcmd,resultreg
|
|
mov $readcommand,subroutinereg
|
|
jmp displaystring
|
|
|
|
|
|
readnibbles:
|
|
movl $0x0, resultreg
|
|
readit:
|
|
mov UART_BASEADDR+5,%dx
|
|
in %dx, %al
|
|
and $0x9f,%al
|
|
test $0x1,%al
|
|
jz readit
|
|
mov UART_BASEADDR,%dx
|
|
in %dx,%al
|
|
xchg %al,%ah
|
|
|
|
sendchar:
|
|
mov UART_BASEADDR+5,%dx
|
|
us_waitit:
|
|
in %dx,%al
|
|
test $0x20,%al
|
|
jz us_waitit
|
|
mov UART_BASEADDR,%dx
|
|
xchg %al,%ah
|
|
out %al,%dx // output char
|
|
|
|
cmp $0x78,%al
|
|
jz readit
|
|
cmp $0x0D,%al //CR
|
|
jnz evalchar
|
|
mov $0x0A,%ah
|
|
jmp sendchar
|
|
|
|
evalchar:
|
|
cmp $0x20,%al //space
|
|
jz gosub
|
|
cmp $0x0A,%al //CR
|
|
jz gosub
|
|
cmp $0x08,%al //BS
|
|
jnz processchar
|
|
//subit:
|
|
shr $0x04,resultreg
|
|
jmp readit
|
|
processchar:
|
|
cmp $0x3A,%al
|
|
jl subnum
|
|
cmp $0x47,%al
|
|
jl subcaps
|
|
//sublc:
|
|
sub $0x57,%al
|
|
jmp additupn
|
|
subcaps:
|
|
sub $0x37,%al
|
|
jmp additupn
|
|
subnum:
|
|
sub $0x30,%al
|
|
additupn:
|
|
shl $0x04,resultreg
|
|
and $0xf,%eax
|
|
add %eax,resultreg
|
|
jmp readit
|
|
|
|
gosub:
|
|
jmp *subroutinereg
|
|
|
|
//intersubcall
|
|
// eax,edx,esi,edi
|
|
|
|
// ebx,ecx,ebp,esp(?)
|
|
// ds,es,fs,gs
|
|
|
|
dotest:
|
|
mov $ramtest,resultreg
|
|
mov $test1a,subroutinereg
|
|
jmp displayhex
|
|
test1a:
|
|
mov $welcome,resultreg
|
|
mov $readcommand,subroutinereg
|
|
jmp displayhex
|
|
|
|
dodmem:
|
|
|
|
movl $dmem1a, subroutinereg
|
|
jmp readnibbles
|
|
dmem1a:
|
|
mov resultreg,%ebx // address
|
|
movl $dmem1b, subroutinereg
|
|
jmp readnibbles
|
|
dmem1b:
|
|
mov resultreg,%ecx // length
|
|
|
|
dmemloop:
|
|
mov %ebx,resultreg
|
|
mov $daddr1,subroutinereg
|
|
jmp displayhex
|
|
daddr1:
|
|
mov $spaces,resultreg
|
|
mov $startshowm,subroutinereg
|
|
jmp displaystring
|
|
|
|
startshowm:
|
|
mov (%ebx),resultreg
|
|
mov $showm1,subroutinereg
|
|
jmp displayhexlinear
|
|
showm1:
|
|
add $0x04,%ebx
|
|
mov (%ebx),resultreg
|
|
mov $showm2,subroutinereg
|
|
jmp displayhexlinear
|
|
showm2:
|
|
add $0x04,%ebx
|
|
mov (%ebx),resultreg
|
|
mov $showm3,subroutinereg
|
|
jmp displayhexlinear
|
|
showm3:
|
|
add $0x04,%ebx
|
|
mov (%ebx),resultreg
|
|
mov $showa0,subroutinereg
|
|
jmp displayhexlinear
|
|
|
|
showa0:
|
|
sub $0xC,%ebx
|
|
mov (%ebx),resultreg
|
|
mov $showa1,subroutinereg
|
|
jmp displayasciilinear
|
|
showa1:
|
|
add $0x04,%ebx
|
|
mov (%ebx),resultreg
|
|
mov $showa2,subroutinereg
|
|
jmp displayasciilinear
|
|
showa2:
|
|
add $0x04,%ebx
|
|
mov (%ebx),resultreg
|
|
mov $showa3,subroutinereg
|
|
jmp displayasciilinear
|
|
showa3:
|
|
add $0x04,%ebx
|
|
mov (%ebx),resultreg
|
|
mov $doneshow,subroutinereg
|
|
jmp displayasciilinear
|
|
doneshow:
|
|
mov $cr,resultreg
|
|
mov $doneshow1,subroutinereg
|
|
jmp displaystring
|
|
doneshow1:
|
|
dec %cx
|
|
cmp $0x0,%cx
|
|
jz exitdmem
|
|
add $0x04,%ebx
|
|
jmp dmemloop
|
|
exitdmem:
|
|
jmp readcommand
|
|
|
|
dooutb:
|
|
// out val,port
|
|
movl $outb1a, subroutinereg
|
|
jmp readnibbles
|
|
outb1a:
|
|
mov resultreg,%ebx
|
|
movl $outb1b, subroutinereg
|
|
jmp readnibbles
|
|
outb1b:
|
|
mov resultreg,%edx
|
|
mov %ebx,%eax
|
|
out %al,%dx
|
|
jmp readcommand
|
|
|
|
dooutw:
|
|
// out val,port
|
|
movl $outw1a, subroutinereg
|
|
jmp readnibbles
|
|
outw1a:
|
|
mov resultreg,%ebx
|
|
movl $outw1b, subroutinereg
|
|
jmp readnibbles
|
|
outw1b:
|
|
mov resultreg,%edx
|
|
mov %ebx,%eax
|
|
out %ax,%dx
|
|
jmp readcommand
|
|
|
|
dooutd:
|
|
// out val,port
|
|
movl $outd1a, subroutinereg
|
|
jmp readnibbles
|
|
outd1a:
|
|
mov resultreg,%ebx
|
|
movl $outd1b, subroutinereg
|
|
jmp readnibbles
|
|
outd1b:
|
|
mov resultreg,%edx
|
|
mov %ebx,%eax
|
|
out %eax,%dx
|
|
jmp readcommand
|
|
|
|
wmemb:
|
|
movl $wmemba, subroutinereg
|
|
jmp readnibbles
|
|
wmemba:
|
|
mov resultreg,%ebx
|
|
movl $wmembb, subroutinereg
|
|
jmp readnibbles
|
|
wmembb:
|
|
mov resultreg,%eax
|
|
mov %al,(%ebx)
|
|
jmp readcommand
|
|
|
|
wmemw:
|
|
movl $wmemwa, subroutinereg
|
|
jmp readnibbles
|
|
wmemwa:
|
|
mov resultreg,%ebx
|
|
movl $wmemwb, subroutinereg
|
|
jmp readnibbles
|
|
wmemwb:
|
|
mov resultreg,%eax
|
|
mov %ax,(%ebx)
|
|
jmp readcommand
|
|
|
|
wmeml:
|
|
movl $wmemla, subroutinereg
|
|
jmp readnibbles
|
|
wmemla:
|
|
mov resultreg,%ebx
|
|
movl $wmemlb, subroutinereg
|
|
jmp readnibbles
|
|
wmemlb:
|
|
mov resultreg,%eax
|
|
mov %eax,(%ebx)
|
|
jmp readcommand
|
|
|
|
doinb:
|
|
// in port
|
|
movl $inb1a, subroutinereg
|
|
jmp readnibbles
|
|
inb1a:
|
|
mov resultreg,%edx
|
|
mov $0x0,%eax
|
|
in %dx,%al
|
|
mov %eax,resultreg
|
|
mov $readcommand,subroutinereg
|
|
jmp displayhex
|
|
|
|
doinw:
|
|
// in port
|
|
movl $inw1a, subroutinereg
|
|
jmp readnibbles
|
|
inw1a:
|
|
mov resultreg,%edx
|
|
mov $0x0,%eax
|
|
in %dx,%ax
|
|
mov %eax,resultreg
|
|
mov $readcommand,subroutinereg
|
|
jmp displayhex
|
|
|
|
doind:
|
|
// in port
|
|
movl $ind1a, subroutinereg
|
|
jmp readnibbles
|
|
ind1a:
|
|
mov resultreg,%edx
|
|
in %dx,%eax
|
|
mov %eax,resultreg
|
|
mov $readcommand,subroutinereg
|
|
jmp displayhex
|
|
|
|
jmpto:
|
|
movl $jmp1a, subroutinereg
|
|
jmp readnibbles
|
|
jmp1a:
|
|
mov $readcommand,%eax
|
|
jmp *resultreg
|
|
|
|
callto:
|
|
movl $call1a, subroutinereg
|
|
jmp readnibbles
|
|
call1a:
|
|
mov $readcommand,%eax
|
|
call *resultreg
|
|
jmp readcommand
|
|
|
|
dopush:
|
|
movl $push1a, subroutinereg
|
|
jmp readnibbles
|
|
push1a:
|
|
mov resultreg,%eax
|
|
push %eax
|
|
jmp readcommand
|
|
|
|
doint:
|
|
movl $int1a, subroutinereg
|
|
jmp readnibbles
|
|
int1a:
|
|
mov resultreg,%eax
|
|
// need to lookup int table?
|
|
// int %eax
|
|
jmp readcommand
|
|
|
|
doenter:
|
|
//setup stack frame
|
|
|
|
|
|
dopop:
|
|
movl $readcommand, subroutinereg
|
|
pop resultreg
|
|
jmp displayhex
|
|
|
|
docli:
|
|
cli
|
|
jmp readcommand
|
|
|
|
dosti:
|
|
sti
|
|
jmp readcommand
|
|
|
|
|
|
displaystring:
|
|
// resultreg= pointer to string terminated by \0
|
|
dsloop:
|
|
movb (resultreg),%ah
|
|
cmp $0x0, %ah
|
|
jz displaystringexit
|
|
mov UART_BASEADDR+5,%dx
|
|
us_waits:
|
|
in %dx,%al
|
|
test $0x20,%al
|
|
jz us_waits
|
|
mov UART_BASEADDR,%dx
|
|
xchg %al,%ah
|
|
out %al,%dx // output char
|
|
inc resultreg
|
|
jmp dsloop
|
|
displaystringexit:
|
|
jmp *subroutinereg
|
|
|
|
displayhexlinear:
|
|
mov resultreg,%eax
|
|
xchg %al,%ah
|
|
rol $0x10,%eax
|
|
xchg %al,%ah
|
|
mov %eax,resultreg
|
|
displayhex:
|
|
rol $0x10,%ecx
|
|
mov $0x8,%cx
|
|
dhloop:
|
|
cmp $0xf,%cl
|
|
je exitdisplayhex
|
|
rol $0x04,resultreg
|
|
movl resultreg,%eax
|
|
and $0xf,%al
|
|
cmp $0xa,%al
|
|
jl addnum
|
|
//addcaps
|
|
add $0x37,%al
|
|
jmp outcharhex
|
|
addnum:
|
|
add $0x30,%al
|
|
outcharhex:
|
|
xchg %al,%ah
|
|
mov UART_BASEADDR+5,%dx
|
|
us_waith:
|
|
in %dx,%al
|
|
test $0x20,%al
|
|
jz us_waith
|
|
mov UART_BASEADDR,%dx
|
|
xchg %al,%ah
|
|
out %al,%dx // output char
|
|
dec %cx
|
|
cmp $0x0,%cx
|
|
jne dhloop
|
|
mov $0x20,%al
|
|
mov $0x10,%cl
|
|
jmp outcharhex
|
|
exitdisplayhex:
|
|
rol $0x10,%ecx
|
|
jmp *subroutinereg
|
|
|
|
displayasciilinear:
|
|
mov resultreg,%eax
|
|
xchg %al,%ah
|
|
rol $0x10,%eax
|
|
xchg %al,%ah
|
|
mov %eax,resultreg
|
|
displayascii:
|
|
rol $0x10,%ecx
|
|
mov $0x4,%cx
|
|
daloop:
|
|
rol $0x08,resultreg
|
|
movl resultreg,%eax
|
|
cmp $0x7e,%al
|
|
jg unprintable
|
|
cmp $0x20,%al
|
|
jl unprintable
|
|
jmp outcharascii
|
|
unprintable:
|
|
mov $0x2e,%al // dot
|
|
outcharascii:
|
|
xchg %al,%ah
|
|
mov UART_BASEADDR+5,%dx
|
|
us_waita:
|
|
in %dx,%al
|
|
test $0x20,%al
|
|
jz us_waita
|
|
mov UART_BASEADDR,%dx
|
|
xchg %al,%ah
|
|
out %al,%dx // output char
|
|
dec %cx
|
|
cmp $0x0,%cx
|
|
jne daloop
|
|
rol $0x10,%ecx
|
|
jmp *subroutinereg
|
|
|
|
rst:
|
|
cli
|
|
movb $0x0fe,%al
|
|
out %al,$0x64
|
|
hlt
|
|
|
|
RST:
|
|
cli
|
|
lidt %cs:0x03fff
|
|
int $0x3
|
|
hlt
|
|
|
|
|
|
beep:
|
|
mov timertime,%eax
|
|
rol $0x10,%eax
|
|
mov $0xb6,%al
|
|
out %al,$0x43
|
|
mov freqtime,%ax
|
|
out %al,$0x42
|
|
xchg %al,%ah
|
|
out %al,$0x42
|
|
|
|
in $0x61,%al
|
|
or $0x03,%al
|
|
out %al,$0x61
|
|
|
|
//timer here
|
|
timer:
|
|
in $0x42,%al
|
|
// xchg %al,%ah
|
|
in $0x42,%al
|
|
// xchg %al,%ah
|
|
cmp $0x0,%al
|
|
jnz timer
|
|
rol $0x10,%eax
|
|
dec %ax
|
|
cmp $0x0,%ax;
|
|
rol $0x10,%eax
|
|
jnz timer
|
|
// timer
|
|
|
|
in $0x61,%al
|
|
and $0xfc,%al
|
|
out %al,$0x61
|
|
jmp *subroutinereg
|
|
|
|
dohelp:
|
|
mov $cmds,resultreg
|
|
mov $readcommand,subroutinereg
|
|
jmp displaystring
|
|
|
|
memt:
|
|
movl $memt1, subroutinereg
|
|
jmp readnibbles
|
|
memt1:
|
|
mov resultreg,%ecx
|
|
movl $memt2, subroutinereg
|
|
jmp readnibbles
|
|
memt2:
|
|
mov resultreg,%ebx
|
|
xchg %ecx,%eax
|
|
mov $readcommand,%esp // internal to linux bios
|
|
jmp ramtest
|
|
|
|
pcirb:
|
|
movl $pcirb1, subroutinereg
|
|
jmp readnibbles
|
|
pcirb1:
|
|
mov resultreg,%eax
|
|
PCI_READ_CONFIG_BYTE
|
|
and $0xff,%eax
|
|
mov %eax,resultreg
|
|
mov $readcommand,subroutinereg
|
|
jmp displayhex
|
|
|
|
pcirw:
|
|
movl $pcirw1, subroutinereg
|
|
jmp readnibbles
|
|
pcirw1:
|
|
mov resultreg,%eax
|
|
PCI_READ_CONFIG_WORD
|
|
and $0xffff,%eax
|
|
mov %eax,resultreg
|
|
mov $readcommand,subroutinereg
|
|
jmp displayhex
|
|
|
|
pcirl:
|
|
movl $pcirl1, subroutinereg
|
|
jmp readnibbles
|
|
pcirl1:
|
|
mov resultreg,%eax
|
|
PCI_READ_CONFIG_DWORD
|
|
mov %eax,resultreg
|
|
mov $readcommand,subroutinereg
|
|
jmp displayhex
|
|
|
|
|
|
|
|
|
|
pciwb:
|
|
movl $pciwb1, subroutinereg
|
|
jmp readnibbles
|
|
pciwb1:
|
|
mov resultreg,%ebx
|
|
movl $pciwb2, subroutinereg
|
|
jmp readnibbles
|
|
pciwb2:
|
|
mov resultreg,%edx
|
|
mov %ebx,%eax
|
|
PCI_WRITE_CONFIG_BYTE
|
|
jmp readcommand
|
|
|
|
pciww:
|
|
movl $pciww1, subroutinereg
|
|
jmp readnibbles
|
|
pciww1:
|
|
mov resultreg,%ebx
|
|
movl $pciww2, subroutinereg
|
|
jmp readnibbles
|
|
pciww2:
|
|
mov resultreg,%ecx
|
|
mov %ebx,%eax
|
|
PCI_WRITE_CONFIG_WORD
|
|
jmp readcommand
|
|
|
|
pciwl:
|
|
movl $pciwl1, subroutinereg
|
|
jmp readnibbles
|
|
pciwl1:
|
|
mov resultreg,%ebx
|
|
movl $pciwl2, subroutinereg
|
|
jmp readnibbles
|
|
pciwl2:
|
|
mov resultreg,%ecx
|
|
mov %ebx,%eax
|
|
PCI_WRITE_CONFIG_DWORD
|
|
jmp readcommand
|
|
|
|
cram:
|
|
//likely not working. Just testing for now
|
|
movl $cram1, subroutinereg
|
|
jmp readnibbles
|
|
cram1:
|
|
mov resultreg,%ebx
|
|
movl $cram1, subroutinereg
|
|
jmp readnibbles
|
|
cram2:
|
|
mov resultreg,%ecx
|
|
// enable it
|
|
mov %cr0,%eax
|
|
and $0x9fffffff,%eax // also try 0x0fff, 0x2ff(write back)...
|
|
mov %eax,%cr0
|
|
//wbinvd ??
|
|
cacheloop:
|
|
mov (%ebx),%eax
|
|
inc %ebx
|
|
loop cacheloop
|
|
// disable it
|
|
mov %cr0,%eax
|
|
or $0x60000000,%eax
|
|
mov %eax,%cr0
|
|
//wbinvd ??
|
|
|
|
dodl:
|
|
movl $dl1, subroutinereg
|
|
jmp readnibbles
|
|
dl1:
|
|
mov resultreg,%ebx
|
|
movl $dl2, subroutinereg
|
|
jmp readnibbles
|
|
dl2:
|
|
mov resultreg,%ecx
|
|
mov resultreg,subroutinereg
|
|
mov %ebx,resultreg
|
|
dlloop:
|
|
mov UART_BASEADDR+5,%dx
|
|
in %dx, %al
|
|
and $0x9f,%al
|
|
test $0x01,%al
|
|
jz dlloop
|
|
mov UART_BASEADDR,%dx
|
|
in %dx,%al
|
|
mov %al,(%ebx)
|
|
inc %ebx
|
|
loop dlloop
|
|
csum:
|
|
mov subroutinereg,%ecx
|
|
shr $0x02,%ecx
|
|
mov resultreg,%ebx
|
|
mov $0x0,%eax
|
|
csumloop:
|
|
rol $0x03,%eax
|
|
mov (%ebx),%dl
|
|
xor %dl,%al
|
|
inc %ebx
|
|
loop csumloop
|
|
mov $readcommand,subroutinereg
|
|
mov %eax,resultreg
|
|
jmp displayhex
|
|
|
|
baud:
|
|
mov $sorry,resultreg
|
|
mov $readcommand,subroutinereg
|
|
jmp displaystring
|
|
|
|
mcp:
|
|
movl $mcp1, subroutinereg
|
|
jmp readnibbles
|
|
mcp1:
|
|
mov resultreg,%ebx
|
|
movl $mcp2, subroutinereg
|
|
jmp readnibbles
|
|
mcp2:
|
|
mov resultreg,%ecx
|
|
movl $mcp3, subroutinereg
|
|
jmp readnibbles
|
|
mcp3:
|
|
mov resultreg,%eax
|
|
xchg %ecx,%eax
|
|
mcploop:
|
|
mov (%ebx),%dl
|
|
mov %dl,(%eax)
|
|
inc %ebx
|
|
inc %eax
|
|
loop mcploop
|
|
jmp readcommand
|
|
|
|
dopattern:
|
|
movl $pat1, subroutinereg
|
|
jmp readnibbles
|
|
pat1:
|
|
mov resultreg,%ebx
|
|
movl $pat2, subroutinereg
|
|
jmp readnibbles
|
|
pat2:
|
|
mov resultreg,%ecx
|
|
movl $pat3, subroutinereg
|
|
jmp readnibbles
|
|
pat3:
|
|
mov resultreg,%eax
|
|
xchg %ecx,%eax
|
|
patloop:
|
|
rol $0x08,%ebx
|
|
mov %bl,(%eax)
|
|
inc %eax
|
|
loop patloop
|
|
jmp readcommand
|
|
|
|
|
|
doexit:
|
|
// LB specific:
|
|
RETSP // if there's no stack yet, caller must set %esp manually
|
|
// RET_LABEL(low_level_shell)
|
|
|
|
|
|
//Linux OS Specific
|
|
ioperms:
|
|
movl $sys_IOPL, %eax # system-call ID-number
|
|
movl $3, %ebx # new value for IO0PL
|
|
int $0x80 # enter the kernel
|
|
ret
|
|
|
|
llshell_out:
|