#
# \brief  Boot test for the demo device driver manager
# \author Norman Feske
# \date   2012-01-17
#
# This test exercises the auto-probing of the boot medium performed by d3m.
# D3m support booting from both CD-ROM and USB storage. Both options are
# tested via different qemu arguments.
#

#
# Sanity checks
#
# The test does only work for platforms that use qemu to boot. Because the test
# uses x86-specific drivers, it won't execute on other architectures.
#
if {[have_spec linux]}   { puts "Does not run on Linux"; exit 0 }
if {![have_spec x86_32]} { puts "Runs only on x86_32"; exit 0 }

#
# Build
#
build {
	core
	init
	drivers/timer
	drivers/pci
	drivers/framebuffer/vesa
	drivers/input/ps2
	drivers/atapi
	drivers/nic
	drivers/usb
	server/d3m
	server/iso9660
}

create_boot_directory

#
# Config
#
set config  {
<config verbose="yes">
	<parent-provides>
		<service name="ROM"/>
		<service name="RAM"/>
		<service name="IRQ"/>
		<service name="IO_MEM"/>
		<service name="IO_PORT"/>
		<service name="CAP"/>
		<service name="PD"/>
		<service name="RM"/>
		<service name="CPU"/>
		<service name="LOG"/>
		<service name="SIGNAL"/>
	</parent-provides>
	<default-route>
		<any-service> <any-child/> <parent/> </any-service>
	</default-route>
	<start name="pci_drv">
		<resource name="RAM" quantum="1M"/>
		<provides><service name="PCI"/></provides>
	</start>
	<start name="timer">
		<resource name="RAM" quantum="1M"/>
		<provides><service name="Timer"/></provides>
	</start>
	<start name="d3m">
		<resource name="RAM" quantum="16M"/>
		<provides>
			<service name="Input"/>
			<service name="Nic"/>
			<service name="Block"/>
		</provides>
		<route>
			<service name="ROM"> <parent/> </service>
			<any-service> <any-child/> <parent/> </any-service>
		</route>
	</start>
	<start name="iso9660">
		<resource name="RAM" quantum="8M"/>
		<provides><service name="ROM"/></provides>
	</start>
</config>
}

install_config $config

# create magic tag file on iso image, which marks the boot medium
exec touch [run_dir]/libc.lib.so

#
# Boot modules
#
build_boot_image {
	core init
	pci_drv vesa_drv ps2_drv atapi_drv timer nic_drv usb_drv
	d3m iso9660 }

#
# Customized variant of spawn_qemu function, which lets us define all qemu
# arguments via the 'qemu_args' variable.
#
proc spawn_qemu { wait_for_re timeout_value } {
	global output
	global qemu_args
	global qemu
	global spawn_id
	set qemu "qemu-system-i386"

	set timeout $timeout_value
	set pid [eval "spawn $qemu $qemu_args"]
	if {$wait_for_re == "forever"} { interact $pid }
	expect {
		-re $wait_for_re { }
		timeout { puts stderr "Error: Test execution timed out"; exit -2 }
	}
	set output $expect_out(buffer)
}

#
# Inherit qemu arguments specified at the build configuration
#
set common_qemu_args "$qemu_args -serial mon:stdio -nographic -m 512 "

#
# First, try to use the ISO image as CD-ROM. We expect the ATAPI driver to
# detect the boot image.
#
set qemu_args "$common_qemu_args -cdrom [run_dir].iso"
run_genode_until {.*"iso9660" announces service "ROM".*\n} 30
close $spawn_id

puts "\nBooting from CD-ROM succeeded\n"

#
# Second, try to use the ISO image as USB stick. We expect the USB driver to
# detect the boot image.
#
# The timeout is a bit larger because using isolinux takes a while.
#
set qemu_args "$common_qemu_args -usbdevice disk::[run_dir].iso"
run_genode_until {.*"iso9660" announces service "ROM".*\n} 60
close $spawn_id

puts "\nBooting from USB storage device succeeded\n"

puts "Test succeeded"