/*
 *  linux/arch/m68k/kernel/setup.c
 *
 *  Copyright (C) 1995  Hamish Macdonald
 */

/*
 * This file handles the architecture-dependent parts of system setup
 */

#include <linux/config.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/interrupt.h>
#include <linux/fs.h>
#include <linux/console.h>
#include <linux/genhd.h>
#include <linux/errno.h>

#include <asm/bootinfo.h>

struct bootinfo boot_info = {0,};
int bisize = sizeof boot_info;

int m68k_is040or060 = 0;

char m68k_debug_device[6] = "";

extern int ramdisk_size;
extern int end;
extern unsigned long availmem;

/* setup some dummy routines */
static unsigned long dummy_floppy_init (unsigned long start,
					unsigned long end)
{
    return start;
}
static void dummy_waitbut(void)
{
}

void (*mach_sched_init) (isrfunc);
unsigned long (*mach_keyb_init) (unsigned long);
int (*mach_kbdrate) (struct kbd_repeat *) = NULL;
void (*mach_kbd_leds) (unsigned int) = NULL;
void (*mach_init_INTS) (void);
int (*mach_add_isr) (unsigned long, isrfunc, int, void *, char *);
int (*mach_remove_isr) (unsigned long, isrfunc);
void (*mach_process_int) (int, struct intframe *) = NULL;
void (*mach_enable_irq) (unsigned) = NULL;
void (*mach_disable_irq) (unsigned) = NULL;
int (*mach_get_irq_list) (char *, int) = NULL;
unsigned long (*mach_gettimeoffset) (void);
void (*mach_gettod) (int*, int*, int*, int*, int*, int*);
int (*mach_hwclk) (int, struct hwclk_time*) = NULL;
int (*mach_set_clock_mmss) (unsigned long) = NULL;
void (*mach_check_partition) (struct gendisk *, unsigned int);
void (*mach_mksound)( unsigned int count, unsigned int ticks );
void (*mach_reset)( void );
#ifdef CONFIG_BLK_DEV_FD
unsigned long (*mach_floppy_init) (unsigned long, unsigned long) = dummy_floppy_init;
void (*mach_floppy_setup) (char *, int *) = NULL;
#endif
void (*waitbut)(void) = dummy_waitbut;
struct fb_info *(*mach_fb_init)(long *);
void (*mach_debug_init)(void);
void (*mach_video_setup) (char *, int *);

extern void config_amiga(void);
extern void config_atari(void);
extern void config_mac(void);

extern void register_console(void (*proc)(const char *));
extern void ami_serial_print (const char *str);
extern void ata_mfp_print (const char *str);

#define MASK_256K 0xfffc0000

void setup_arch(char **cmdline_p,
	unsigned long * memory_start_p, unsigned long * memory_end_p)
{
	unsigned long memory_start, memory_end;
	int i;
	char *p, *q;
	
#ifdef CONFIG_AMIGA
	if (MACH_IS_AMIGA)
	  register_console (ami_serial_print);
#endif
#ifdef CONFIG_ATARI
	if (MACH_IS_ATARI)
	  register_console (ata_mfp_print);
#endif

	ramdisk_size = boot_info.ramdisk_size;
	if (boot_info.cputype & CPU_68040)
		m68k_is040or060 = 4;
	else if (boot_info.cputype & CPU_68060)
		m68k_is040or060 = 6;

	memory_start = availmem;
	memory_end = 0;

	for (i = 0; i < boot_info.num_memory; i++)
		memory_end += boot_info.memory[i].size & MASK_256K;

	*cmdline_p = boot_info.command_line;

	/* Parse the command line for arch-specific options.
	 * For the m68k, this is currently only "debug=xxx" to enable printing
	 * certain kernel messages to some machine-specific device.
	 */
	for( p = *cmdline_p; p && *p; ) {
		i = 0;
		if (!strncmp( p, "debug=", 6 )) {
			strncpy( m68k_debug_device, p+6, sizeof(m68k_debug_device)-1 );
			m68k_debug_device[sizeof(m68k_debug_device)-1] = 0;
			if ((q = strchr( m68k_debug_device, ' ' ))) *q = 0;
			i = 1;
		}

		if (i) {
			/* option processed, delete it */
			if ((q = strchr( p, ' ' )))
				strcpy( p, q+1 );
			else
				*p = 0;
		}
		else {
			if ((p = strchr( p, ' ' ))) ++p;
		}
	}

	*memory_start_p = memory_start;
	*memory_end_p = memory_end;

	switch (boot_info.machtype) {
#ifdef CONFIG_AMIGA
	    case MACH_AMIGA:
		config_amiga();
		break;
#endif
#ifdef CONFIG_ATARI
	    case MACH_ATARI:
		config_atari();
		break;
#endif
#ifdef CONFIG_MAC
	    case MACH_MAC:
		config_mac();
		break;
#endif
	    default:
		panic ("No configuration setup");
	}
}

int setkeycode(unsigned int scancode, unsigned int keycode)
{
	return -EOPNOTSUPP;
}

int getkeycode(unsigned int scancode)
{
	return -EOPNOTSUPP;
}

#ifdef CONFIG_BLK_DEV_FD
void floppy_setup(char *str, int *ints)
{
	if (mach_floppy_setup)
		mach_floppy_setup (str, ints);
}
#endif

void video_setup (char *str, int *ints)
{
	if (mach_video_setup)
		mach_video_setup (str, ints);
}
