#!/bin/sh
# Copyright (C) 2004-2006 Nokia

FS_MODULES="ext2 jbd mbcache ext3"
USB_HOST_MODULES="ohci-hcd usbhid usbnet usbserial scsi_mod sd_mod \
		  usb-storage pl2303 net1080 cdc_ether asix"
MODULE_PATH=/lib/modules/current

dsm_enable=1
dsme_state=8

tss_testserver=/usr/bin/testserver

#if [ -e /etc/initfs.config ]; then
#	. /initfs.config
#fi

text2screen -c
text2screen -s 2 -H center -y 20 -T 0 -t "Press and hold MENU key for advanced boot menu"

init_system()
{
	mount -t proc none /proc
	mount -t sysfs none /sys
	mount -t tmpfs none -o size=512K /tmp

	mkdir /tmp/dev
	if [ ! -e /tmp/dev/retu ]; then
		mknod /tmp/dev/retu c 10 `grep retu /proc/misc | cut -d " " -f 2`
	fi
	if [ ! -e /tmp/dev/tahvo ]; then
		mknod /tmp/dev/tahvo c 10 `grep tahvo /proc/misc | cut -d " " -f 2`
	fi

	# Enable dyntick to save power
	if [ -f /sys/devices/system/timer/timer0/dyn_tick ]; then
		echo 1 > /sys/devices/system/timer/timer0/dyn_tick
	fi
}

check_partitions()
{
	grep mtdblock4 /proc/partitions >/dev/null
	if [ $? = 0 ] ; then 
		mtd_found=1
	else
		mtd_found=0
	fi

	grep sda1 /proc/partitions >/dev/null
	if [ $? = 0 ] ; then
		sda_found=1
	else
		sda_found=0
	fi

	grep mmc /proc/partitions >/dev/null
	if [ $? = 0 ] ; then
		mmc_found=1
	else
		mmc_found=0
	fi
}

wait_for_device()
{
	complained=0
	while [ true ]; do
		grep $root_dev /proc/partitions > /dev/null
		if [ $? = 0 ]; then
			break;
		fi
		if [ $complained -ne 1 ]; then
			echo -n "Waiting for $root_dev_name to become available... "
			complained=1
		fi
		sleep 1
	done
	if [ $complained -eq 1 ]; then
		echo "found it."
	fi
}

show_roots()
{
	echo "Choose bootup option:"
	if [ $mtd_found -eq 1 ]; then
		echo "	1) Flash"
	fi
	if [ $mmc_found -eq 1 ]; then
		echo "	2) MMC"
	fi
	if [ $sda_found -eq 1 ]; then
	        echo "	3) USB Mass Storage Device"
	fi
	echo "	9) Start a shell"
	echo ""
}

start_shell()
{
	echo "Starting shell"
	/bin/sh
}

load_wlan_module()
{
	if [ x"$1" = x"mtum" ]; then
		umac_name=mtum  
		wlan_driver_name=cx3110x_mt
	else
		umac_name=umac
		wlan_driver_name=cx3110x
	fi
	echo "Loading WLAN module... "
	insmod $MODULE_PATH/${umac_name}.ko
	insmod $MODULE_PATH/${wlan_driver_name}.ko
	echo "Pushing the WLAN tuned values"
	/usr/bin/wlan-cal
}

enter_test_state()
{
	echo -n "Bringing WLAN interface up... "
	ifconfig wlan0 up
	echo "done."
	echo "Starting test server..."
	$tss_testserver --sti-debug 41
	# in case of testserver failure, we start shell
	start_shell

	return 1
}

show_actdead_image()
{
	bootreason=`cat /proc/bootreason`
	if [ x"$bootreason" = x"charger" ]; then
		echo "Showing the 'charger connected' image"
		/usr/bin/fb-chaimage -l /usr/share/images/qgn_indi_charger_connection_detected -c -p ffffff -s 27 &
	fi
}

enter_state()
{
	echo "Entering state '$dsme_state'."
	case $dsme_state in 
	    USER)
		def_runlevel=2
		/usr/bin/show_image -i /usr/share/images/logo-nokia -n
		return 0
		;;
	    ACTDEAD)
		def_runlevel=5
		show_actdead_image
		return 0
		;;
	    TEST)
		text2screen -t "TEST" -H center -y 360 -s 6 -B 0xffff
		load_wlan_module
		enter_test_state
		return 1
		;;
	    LOCAL)
		text2screen -t "LOCAL" -H center -y 360 -s 6 -B 0xffff
		load_wlan_module mtum
		enter_test_state
		return 1
		;;
	    SHUTDOWN)
		echo "Powering off"
		sync
		poweroff
		return 1
		;;
	    *)
		if [ $rd_mode -ne 0 ]; then
			start_shell
			return 1
		fi
		echo "Houston, we have a problem, powering off..."
		sync
		poweroff
		return 1
		;;
	esac
}

enable_coredumps()
{
	coredir=/media/mmc1/core-dumps
	echo -n "Enabling core dumps to $coredir/..."
	echo "$coredir/core" > /proc/sys/kernel/core_pattern
	echo 1 > /proc/sys/kernel/core_uses_pid
	ulimit -c unlimited
	echo "done."
}

start_dsm()
{
	enable_coredumps

	echo -n "Starting DSME... "
	dsme -d -l syslog -v 4 -p /usr/lib/dsme/libstartup.so
	echo "done."

	/usr/sbin/waitfordsme
	if [ $? -ne 0 ]; then
		dsme_state=MALF
		return
	fi

	/usr/sbin/dsmetool -r "/usr/bin/bme"

	dsme_state=`/usr/sbin/bootstate`
	if [ $? -ne 0 ]; then
		dsme_state=MALF
	fi
}

boot()
{
	#input layer key repeat values: delay 250ms and period 150ms or 6.67 Hz
	evrepeat /dev/input/event1 250 150
	load_wlan_module
	echo "Booting from $root_dev_name"
	echo "Mounting root on /dev/$root_dev"
	if [ -z $root_fstype ]; then
		if [ -z $root_fsoptions ]; then
			time mount /dev/$root_dev /mnt/new_root
		else
			time mount -o $root_fsoptions /dev/$root_dev /mnt/new_root
		fi
	else
		if [ -z $root_fsoptions ]; then
			time mount -t $root_fstype /dev/$root_dev /mnt/new_root
		else
			time mount -t $root_fstype -o $root_fsoptions /dev/$root_dev /mnt/new_root
		fi
	fi
	if [ $? -ne 0 ]; then
		return 1
	fi
	if [ ! -x /mnt/new_root/sbin/init ]; then
		echo "/sbin/init not found on /dev/$root_dev"
		umount /mnt/new_root
		return 1
	fi
	cd /mnt/new_root
	if [ ! -d mnt/initfs ]; then
		mkdir -p mnt/initfs
	fi
	mount -obind /tmp /mnt/new_root/tmp
	pivot_root . mnt/initfs
	echo "Starting init"
	exec /usr/sbin/chroot . /sbin/init $def_runlevel <dev/console >dev/console 2>&1
}

set_display()
{
	if [ "$dsme_state" = "TEST" ]; then
		activate_panel
	fi
	return 0
}

show_rd_versions()
{
	text2screen -c
	bg_color=0xffff
	y=4
	x=4
	line_height=20

	text2screen -t "Kernel version:" -s 2 -x $x -y $y -B $bg_color
	y=$(expr $y + $line_height)
	text2screen -t "  `uname -r`" -s 2 -x $x -y $y -B $bg_color
	y=$(expr $y + $line_height)
	text2screen -t "  `uname -v`" -s 2 -x $x -y $y -B $bg_color

	y=$(expr $y + $line_height + $line_height)
	text2screen -t "initfs version:" -s 2 -x $x -y $y -B $bg_color
	y=$(expr $y + $line_height)
	text2screen -t "  `cat /etc/initfs_version`" -x $x -y $y -s 2 -B $bg_color

	y=340
	text2screen -t "Component versions:" -x $x -y $y -s 2 -B $bg_color
	y=$(expr $y + $line_height)
	while read line ; do
		text2screen -t "  $line" -x $x -y $y -s 2 -B $bg_color
		y=$(expr $y + $line_height)
	done < /proc/component_version
}

load_usb_host_modules()
{
	for mod in $USB_HOST_MODULES $FS_MODULES ; do
		if [ -f $MODULE_PATH/$mod.ko ]; then
			insmod $MODULE_PATH/$mod.ko
		fi
	done
}

load_mmc_modules()
{
       for mod in $FS_MODULES ; do
               if [ -f $MODULE_PATH/$mod.ko ]; then
                       insmod $MODULE_PATH/$mod.ko
               fi
       done
}

init_system

if [ $dsm_enable -eq 1 ]; then
	start_dsm
	if [ $? -ne 0 ]; then
		return 1
	fi
else
	def_runlevel=
fi


rd_mode=$(cal-tool --get-rd-mode 2> /dev/null)
if [ "$rd_mode" = "enabled" ]; then
	rd_mode=1
	echo "R&D mode enabled"
	show_rd_versions
else
	rd_mode=0
fi


usb_host_mode=$(cal-tool --get-usb-host-mode 2> /dev/null)
if [ "$usb_host_mode" = "enabled" ]; then
	echo "USB host mode enabled"
	load_usb_host_modules
	echo host > /sys/devices/platform/tahvo-usb/otg_mode
else
	echo peripheral > /sys/devices/platform/tahvo-usb/otg_mode
fi

#set_display
enter_state

# We are in USER state now

want_menu=0
if [ $rd_mode -ne 0 ]; then
	echo
	echo "Press any key for interactive startup"
	key_pressed 1
	if [ $? -ne 0 ]; then
		want_menu=1
	fi
fi

if [ $want_menu -ne 1 ]; then

	#default is boot from flash
	root_dev=mtdblock4
	root_dev_name="Flash"
	root_fstype="jffs2"
	root_fsoptions="rpsize=1024,rpuid=0,rpuid=30000"
	default_root=$(cal-tool --get-root-device 2> /dev/null)

	#now check HW key state
	HWKEYSTATE=`evkey -s /dev/input/event1`
	# if Escape was not pressed, execute advanced menu script
	if [ "$HWKEYSTATE" != "1" ] ; then
	        [ -f /bootmenu.sh ] && . /bootmenu.sh
	fi
	case "$default_root" in
	mmc)
		root_dev=mmcblk0p1
		root_dev_name="MMC"
		root_dev_set=1
		root_fstype=""
		root_fsoptions=""
		load_mmc_modules
		;;
	usb)
		root_dev=sda1
		root_dev_name="USB hard drive"
		root_dev_set=1
		root_fstype=""
		root_fsoptions=""
		echo host > /sys/devices/platform/tahvo-usb/otg_mode
		;;
	*)
		;;
	esac
	wait_for_device
	boot
	# 2nd try, boot from internal flash
	text2screen -c
	text2screen -s 2 -H center -y 20 -T 0 -t "Boot from $default_root failed, booting from flash ..."
	root_dev=mtdblock4
	root_dev_name="Flash"
	root_fstype="jffs2"
	root_fsoptions="rpsize=1024,rpuid=0,rpuid=30000"
	boot
fi

root="invalid";
while [ true ]; do
	check_partitions
	show_roots
	root_dev_set=0
	read root
	case "$root" in
	    1)
		root_dev=mtdblock4
                root_dev_name="Flash"
                root_dev_set=1
                root_fstype="jffs2"
                root_fsoptions="rpsize=500,rpuid=0"
                ;;
            2)
                root_dev=mmcblk0p1
                root_dev_name="MMC"
                root_dev_set=1
                root_fstype=""
                root_fsoptions=""
                ;;
            3)
                root_dev=sda1
                root_dev_name="USB hard drive"
                root_dev_set=1
                root_fstype=""
                root_fsoptions=""
                ;;
            9)
                start_shell
                ;;
            *)
                echo "Invalid selection";
                ;;
        esac
        if [ $root_dev_set -eq 1 ]; then
                boot
        fi
done
