www.pudn.com > mizi_vivi.rar > gamepark.c


/*
 * vivi/arch/s3c2400/gamepark.c:
 *
 * This code is GPL
 *
 * Author: Janghoon Lyu 
 * Date  : $Date: 2002/08/21 06:39:00 $
 *
 * $Revision: 1.6 $
 */

#include "config.h"
#include "machine.h"
#include "vivi.h"
#include "mtd/map.h"
#include "priv_data.h"
#include "boot_kernel.h"
#include "vivi_string.h"
#include "printk.h"
#include "mmu.h"
#include "command.h"

mtd_partition_t default_mtd_partitions[] = {
	{
		name:		"gpos",
		offset:		0x0,
		size:		0x000c0000,
		flag:		0
	}, {
		name:		"param",
		offset:		0x000c0000,
		size:		0x00020000,
		flag:		0
	}, {
		name:		"vivi",
		offset:		0x00100000,
		size:		0x00020000,
		flag:		0
	}, {
		name:		"kernel",
		offset:		0x00120000,
		size:		0x000c0000,
		flag:		0
	}, {
		name:		"root",
		offset:		0x001e0000,
		size:		0x00140000,
		flag:		0
	}, {
		name:		"usr",
		offset:		0x00320000,
		size:		0x00ce0000,
		flag:		MF_JFFS2
	}
};
int default_nb_part = ARRAY_SIZE(default_mtd_partitions);


vivi_parameter_t default_vivi_parameters[] = {
	{ "mach_type",			MACH_TYPE,	NULL },
	{ "media_type",			MT_NOR_FLASH,	NULL },
	{ "boot_mem_base",		0x0C800000,	NULL },
	{ "baudrate",			UART_BAUD_RATE,	NULL },
	{ "xmodem",			1,		NULL },
	{ "xmodem_one_nak",		0,		NULL },
	{ "xmodem_initial_timeout",	300000,		NULL },
	{ "xmodem_timeout",		1000000,	NULL },
	{ "boot_delay",			0x1000000,	NULL }
};
int default_nb_params = ARRAY_SIZE(default_vivi_parameters);

char linux_cmd[] = "noinitrd root=/dev/mtdblock4 init=/linuxrc console=ttySA0 mem=24M";


void set_gpios(void)
{
}

int board_init(void)
{
	void set_gpios(void);

	return 0;
}

void set_vpp(struct map_info *map, int vpp)
{
}



#define RET_REG         (*(volatile unsigned long *)(0x15a00034))

static inline void printr(char *name, unsigned long r)
{
	printk("%s = 0x%08lx\n", name, r);
}

void go_sleep(void)
{
        unsigned long cpsr;

        putstr("Go SLEEP\r\n");

        _SRCPND = 0xffffffff;
        _INTPND = 0xffffffff;

        __asm__("mrs %0, cpsr" : "=r" (cpsr));
        cpsr &= ~(I_BIT);
        __asm__("msr cpsr_c, %0" : : "r" (cpsr));       /* enable IRQ */

        _PECON = 0x0;
        _PEUP = 0x0;
        _EXTINT = 0x0;
#if 1
        /* power button */
        _PECON = (0x2 << 2);
        _PEUP = (0 << 1);
        _EXTINT = (4 << 4);
        /* hall switch */
#if 1
        _PECON |= (0x2 << 14);
        _PEUP &= ~(1 << 7);
        _EXTINT |= (4 << 28);
        //_EXTINT |= (2 << 28);
#endif

        _INTMSK = ~(IRQ_EINT1 | IRQ_EINT7);
        //_INTMSK = ~(IRQ_EINT7);
        //_INTMSK = ~(IRQ_EINT1);
#endif
        _SRCPND = 0xffffffff;
        _INTPND = 0xffffffff;

        _PEDAT = 0x0;           
#if 0
        putstr("\r\n\r\nIn VIVI\r\n");
        printr("INTMSK", _INTMSK);
        printr("PACON", _PACON);
        printr("PADAT", _PADAT);
        printr("PBCON", _PBCON);
        printr("PBDAT", _PBDAT);
        printr("PBUP", _PBUP);
        printr("PCCON", _PCCON);
        printr("PCDAT", _PCDAT);
        printr("PCUP", _PCUP);
        printr("PDCON", _PDCON);
        printr("PDDAT", _PDDAT);
        printr("PDUP", _PDUP);
        printr("PECON", _PECON);
        printr("PEDAT", _PEDAT);
        printr("PEUP", _PEUP);
        printr("PFCON", _PFCON);
        printr("PFDAT", _PFDAT);
        printr("PFUP", _PFUP);
        printr("PGCON", _PGCON);
        printr("PGDAT", _PGDAT);
        printr("PGUP", _PGUP);
        putstr("\r\n\r\n");
#endif

        cache_clean_invalidate();
        tlb_invalidate();

        __asm__("mov    r1, #0\n"
                "mov    r2, #0x100000\n"
                "orr    r2, r2, #0x34\n"
                "mrc    p15, 0, r1, c1, c0, 0\n"        /* read ctrl register */
                "bic    r1, r1, #0x1100\n"              /* ...i...s........ */
                "bic    r1, r1, #0x000f\n"              /* .............cam */
                "mcr    p15, 0, r1, c1, c0, 0\n"        /* write ctrl register */
                "mov    pc, r2\n"
                "nop\n"
                "nop\n");
}

static void go_gpos(void)
{
        putstr("Go GPOS\r\n");

//      putLabeledWord("return address = 0x", RET_REG);

        _SRCPND = 0xffffffff;
        _INTPND = 0xffffffff;

        cache_clean_invalidate();
        tlb_invalidate();

        __asm__("mov r0, #0\n"
                "mcr p15, 0, r0, c8, c7, 0\n"  /* flush I and D TlB */
                "mcr p15, 0, r0, c7, c10, 4\n" /* drain the write buffer */
                "mov r3, #0x1000\n"            /* I cache on */
                "orr r3, r3, #0x4\n"           /* D cache on */
                "mcr p15, 0, r3, c1, c0, 0\n"  /* disable the MMU */
                /* make sure the pipeline is emptied */
                "mov r0, #0\n"
                "mov r0, r0\n"
                "mov r0, r0\n"
                "mov r0, r0\n"
                "mov r0, r0\n"
                /* zero PID in Fast Context Switch Extension PID register */
                "mov r0, #0\n"
                "mcr p15, 0, r0, c13, c0, 0\n"
                "mov r0, #0\n"
                "mov pc, r0\n"
                "nop\n"
                "nop\n"
                : : );
}

static void go_linux(void)
{
        unsigned long ret_addr = 0;

        ret_addr = RET_REG;
	printk("Go Linux to 0x%08lx\n", ret_addr);

#if 0
        printr("INTMS", _INTMSK);
        printr("PACON", _PACON);
        printr("PBCON", _PBCON);
        printr("INTPND", _INTPND);
        printr("SRCPNT", _SRCPND);
        printr("EXTINT", _EXTINT);
        printr("EXTINT", _EXTINT);
#endif


        /* reset control registers */
        _INTMSK = 0xffffffff;

        _PACON = 0x3ffff;
        _PADAT = 0x0;
        _PBCON = 0xaaaaaaaa;
        _PBDAT = 0x0;
        _PBUP = 0x0;
        _PCCON = 0x0;
        _PCDAT = 0x0;
        _PCUP = 0x0;
        _PDCON = 0x0;
        _PDDAT = 0x0;
        _PDUP = 0x620;
        _PECON = 0x0;
        _PEDAT = 0x0;
        _PEUP = 0x003;
        _PFCON = 0x0;
        _PFDAT = 0x0;
        _PFUP = 0x0;
        _PGCON = 0x0;
        _PGDAT = 0x0;
        _PGUP = 0x0;
        _OPENCR = 0x0;
        _MISCCR = 0x00;
        _EXTINT = 0x00000000;

        _TCFG0 = 0;
        _TCON = 0x0;
        _TCNTB4 = 0x00000000;

        _SRCPND = 0xffffffff;
        _INTPND = 0xffffffff;

        _CLKCON = 0xfff8;

        cache_clean_invalidate();
        tlb_invalidate();

        __asm__("mov    r1, #0\n"
                "mov    r2, %0\n"
                "mrc    p15, 0, r1, c1, c0, 0\n"        /* read ctrl register */
                "bic    r1, r1, #0x1100\n"              /* ...i...s........ */
                "bic    r1, r1, #0x000f\n"              /* .............cam */
                "mcr    p15, 0, r1, c1, c0, 0\n"        /* write ctrl register */
                "mov    pc, r2\n"
                "nop\n"
                "nop\n": : "r" (ret_addr));
}

void support_os_switch(void)
{
        unsigned long cpsr;
        unsigned long ret_addr;
        unsigned char whoami; 

        ret_addr = RET_REG;
        whoami = (RET_REG >> 28); 

        putstr_hex("return address = 0x", ret_addr);
        putstr_hex("whoami = 0x", whoami);  

#if 0
        __asm__("mrs %0, cpsr" : "=r" (cpsr));
        putLabeledWord("  Processor CPSR: ", cpsr);
#endif
        __asm__("mrs %0, cpsr" : "=r" (cpsr));
        cpsr |= (I_BIT | F_BIT); 
        __asm__("msr cpsr_c, %0" : : "r" (cpsr));       /* enable IRQ */
#if 0
        __asm__("mrs %0, cpsr" : "=r" (cpsr));
        putLabeledWord("  Processor CPSR: ", cpsr);
#endif

        if (ret_addr == 0) 
                return;         /* hardware reset */

	switch (whoami) {
		case 0:
			putstr("From the GPOS\r\n");
			go_linux();
			break;
		case 1:
			putstr("From the Linux for OS Switching\r\n");
			RET_REG &= ~(0xf0000000);
			go_gpos();
			break;
		case 2:
			putstr("From the Linux for sleep\r\n");
			RET_REG &= ~(0xf0000000);
			go_sleep();
			break;
		case 3:
			putstr("Test GPOS, Enter the VIVI\r\n");
			RET_REG = 0x0;
			break;
		default:
			return;
	}
}

extern user_command_t test_cmd;

int misc(void)
{
#ifdef CONFIG_TEST
	add_command(&test_cmd);
#endif
	support_os_switch();

	return 0;
}