https://bitbucket.org/hudson/magic-lantern
Raw File
Tip revision: 5e164a63a53ac66522e2ca02d01678b0d67d07bd authored by Trammell Hudson on 24 March 2011, 13:29:27 UTC
Allow enable-liveview to be toggled on and off
Tip revision: 5e164a6
bootflags.c
/** \file
 * Autoboot flag control
 */
#include "dryos.h"
#include "bmp.h"
#include "menu.h"
#include "config.h"
#include "property.h"

/* CF device structure */
struct cf_device
{
	// If block has the top bit set the physical blocks will be read
	// instead of from the first partition.  Cool.
	int 			(*read_block)(
		struct cf_device *		dev,
		uintptr_t			block,
		size_t				num_blocks,
		void *				buf
	);

	int 			(*write_block)(
		struct cf_device *		dev,
		uintptr_t			block,
		size_t				num_blocks,
		const void *			buf
	);

	void *			io_control;
	void *			soft_reset;
};

extern struct cf_device * const cf_device;


/** Shadow copy of the NVRAM boot flags stored at 0xF8000000 */
#define NVRAM_BOOTFLAGS		((void*) 0xF8000000)
struct boot_flags
{
	uint32_t		firmware;	// 0x00
	uint32_t		bootdisk;	// 0x04
	uint32_t		ram_exe;	// 0x08
	uint32_t		update;		// 0x0c
	uint32_t		flag_0x10;
	uint32_t		flag_0x14;
	uint32_t		flag_0x18;
	uint32_t		flag_0x1c;
};

static struct boot_flags * const	boot_flags = NVRAM_BOOTFLAGS;;



/** Write the auto-boot flags to the CF card and to the flash memory */
static void
bootflag_toggle( void * priv )
{
	if( boot_flags->bootdisk )
		call( "DisableBootDisk" );
	else
		call( "EnableBootDisk" );
}


void
bootflag_display(
	void *			priv,
	int			x,
	int			y,
	int			selected
)
{
	bmp_printf(
		selected ? MENU_FONT_SEL : MENU_FONT,
		x, y,
		//23456789012
		"Autoboot    %s",
		boot_flags->bootdisk != 0 ? "ON " : "OFF"
	);
}


// gcc mempcy has odd alignment issues?
static inline void
my_memcpy(
	uint8_t *		dest,
	const uint8_t *		src,
	size_t			len
)
{
	while( len-- > 0 )
		*dest++ = *src++;
}


void
bootflag_write_bootblock( void * unused )
{
	gui_stop_menu();

	uint8_t *block = alloc_dma_memory( 0x200 );
	bmp_printf( FONT_MED, 0, 40,
		"mem=%08x read=%08x",
		(unsigned) block,
		(unsigned) cf_device->read_block
	);

	int rc = cf_device->read_block( cf_device, 0x0, 1, block );
	msleep( 100 );

	bmp_printf( FONT_MED, 600, 40, "read=%d", rc );
	bmp_hexdump( FONT_SMALL, 0, 60, block, 0x100 );

	// Update the first partition header to include the magic
	// strings
	my_memcpy( block + 0x47, (uint8_t*) "EOS_DEVELOP", 0xB );
	my_memcpy( block + 0x5C, (uint8_t*) "BOOTDISK", 0x8 );

	rc = cf_device->write_block( cf_device, 0x0, 1, block );
	bmp_printf( FONT_MED, 600, 60, "write=%d", rc );
	free_dma_memory( block );
}


#if 0
void
bootflag_display_all(
	void *			priv,
	int			x,
	int			y,
	int			selected
)
{
	bmp_printf( selected ? MENU_FONT_SEL : MENU_FONT,
		x,
		y,
		//23456789012
		"Firmware    %s\n"
		"Bootdisk    %s\n"
		"RAM_EXE     %s\n"
		"Update      %s\n",
		boot_flags->firmware == 0 ? "ON" : "OFF",
		boot_flags->bootdisk == 0  ? "ON" : "OFF",
		boot_flags->ram_exe == 0 ? "ON" : "OFF",
		boot_flags->update == 0 ? "ON" : "OFF"
	);
}
#endif


CONFIG_INT( "disable-powersave", disable_powersave, 1 );

static void
powersave_display(
	void *			priv,
	int			x,
	int			y,
	int			selected
)
{
	bmp_printf(
		selected ? MENU_FONT_SEL : MENU_FONT,
		x,
		y,
		//23456789012
		"Powersave   %s\n",
		!disable_powersave ? "ON " : "OFF"
	);
}


static void
powersave_toggle( void * unused )
{
	disable_powersave = !disable_powersave;

	prop_request_icu_auto_poweroff(
		disable_powersave ? EM_PROHIBIT : EM_ALLOW
	);
}


static void
poweroff( void * unused )
{
	uint32_t buf[] = { 0 };

	bmp_printf( FONT_SMALL, 0, 300, "SHUTDOWN");

	prop_request_change(
		PROP_TERMINATE_SHUT_REQ,
		buf,
		sizeof(buf)
	);
}



struct menu_entry boot_menus[] = {
	{
		.display	= menu_print,
		.priv		= "Write MBR",
		.select		= bootflag_write_bootblock,
	},

	{
		.display	= bootflag_display,
		.select		= bootflag_toggle,
	},

	{
		.display	= powersave_display,
		.select		= powersave_toggle,
	},

	{
		.display	= menu_print,
		.priv		= "Power off now",
		.select		= poweroff,
	},

#if 0
	{
		.display	= bootflag_display_all,
	},
#endif
};


static void
bootflags_init( void * unused )
{
	menu_add( "Boot", boot_menus, COUNT(boot_menus) );

	if( disable_powersave )
	{
		DebugMsg( DM_MAGIC, 3,
			"%s: Disabling powersave",
			__func__
		);

		prop_request_icu_auto_poweroff( EM_PROHIBIT );
	}

}


INIT_FUNC( __FILE__, bootflags_init );
back to top