prom.c 3.6 KB
Newer Older
L
Linus Torvalds 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
/* Prom access routines for the sun3x */

#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/tty.h>
#include <linux/console.h>
#include <linux/init.h>
#include <linux/mm.h>
#include <linux/string.h>

#include <asm/page.h>
#include <asm/pgtable.h>
#include <asm/bootinfo.h>
#include <asm/setup.h>
#include <asm/traps.h>
#include <asm/sun3xprom.h>
#include <asm/idprom.h>
#include <asm/segment.h>
#include <asm/sun3ints.h>
#include <asm/openprom.h>
#include <asm/machines.h>

void (*sun3x_putchar)(int);
int (*sun3x_getchar)(void);
int (*sun3x_mayget)(void);
int (*sun3x_mayput)(int);
void (*sun3x_prom_reboot)(void);
e_vector sun3x_prom_abort;
struct linux_romvec *romvec;

/* prom vector table */
e_vector *sun3x_prom_vbr;

/* Handle returning to the prom */
void sun3x_halt(void)
{
R
Roman Zippel 已提交
37
	unsigned long flags;
L
Linus Torvalds 已提交
38

R
Roman Zippel 已提交
39 40
	/* Disable interrupts while we mess with things */
	local_irq_save(flags);
L
Linus Torvalds 已提交
41

R
Roman Zippel 已提交
42 43
	/* Restore prom vbr */
	asm volatile ("movec %0,%%vbr" : : "r" ((void*)sun3x_prom_vbr));
L
Linus Torvalds 已提交
44

R
Roman Zippel 已提交
45 46 47
	/* Restore prom NMI clock */
//	sun3x_disable_intreg(5);
	sun3_enable_irq(7);
L
Linus Torvalds 已提交
48

R
Roman Zippel 已提交
49 50
	/* Let 'er rip */
	asm volatile ("trap #14");
L
Linus Torvalds 已提交
51

R
Roman Zippel 已提交
52 53 54
	/* Restore everything */
	sun3_disable_irq(7);
	sun3_enable_irq(5);
L
Linus Torvalds 已提交
55

R
Roman Zippel 已提交
56 57
	asm volatile ("movec %0,%%vbr" : : "r" ((void*)vectors));
	local_irq_restore(flags);
L
Linus Torvalds 已提交
58 59 60 61
}

void sun3x_reboot(void)
{
R
Roman Zippel 已提交
62 63
	/* This never returns, don't bother saving things */
	local_irq_disable();
L
Linus Torvalds 已提交
64

R
Roman Zippel 已提交
65 66
	/* Restore prom vbr */
	asm volatile ("movec %0,%%vbr" : : "r" ((void*)sun3x_prom_vbr));
L
Linus Torvalds 已提交
67

R
Roman Zippel 已提交
68 69 70
	/* Restore prom NMI clock */
	sun3_disable_irq(5);
	sun3_enable_irq(7);
L
Linus Torvalds 已提交
71

R
Roman Zippel 已提交
72 73
	/* Let 'er rip */
	(*romvec->pv_reboot)("vmlinux");
L
Linus Torvalds 已提交
74 75 76 77 78
}

static void sun3x_prom_write(struct console *co, const char *s,
                             unsigned int count)
{
R
Roman Zippel 已提交
79 80 81 82 83
	while (count--) {
		if (*s == '\n')
			sun3x_putchar('\r');
		sun3x_putchar(*s++);
	}
L
Linus Torvalds 已提交
84 85 86 87 88
}

/* debug console - write-only */

static struct console sun3x_debug = {
R
Roman Zippel 已提交
89 90 91 92
	.name	= "debug",
	.write	= sun3x_prom_write,
	.flags	= CON_PRINTBUFFER,
	.index	= -1,
L
Linus Torvalds 已提交
93 94
};

A
Al Viro 已提交
95
void __init sun3x_prom_init(void)
L
Linus Torvalds 已提交
96
{
R
Roman Zippel 已提交
97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119
	/* Read the vector table */

	sun3x_putchar = *(void (**)(int)) (SUN3X_P_PUTCHAR);
	sun3x_getchar = *(int (**)(void)) (SUN3X_P_GETCHAR);
	sun3x_mayget = *(int (**)(void))  (SUN3X_P_MAYGET);
	sun3x_mayput = *(int (**)(int))   (SUN3X_P_MAYPUT);
	sun3x_prom_reboot = *(void (**)(void)) (SUN3X_P_REBOOT);
	sun3x_prom_abort = *(e_vector *)  (SUN3X_P_ABORT);
	romvec = (struct linux_romvec *)SUN3X_PROM_BASE;

	idprom_init();

	if (!((idprom->id_machtype & SM_ARCH_MASK) == SM_SUN3X)) {
		printk("Warning: machine reports strange type %02x\n",
			idprom->id_machtype);
		printk("Pretending it's a 3/80, but very afraid...\n");
		idprom->id_machtype = SM_SUN3X | SM_3_80;
	}

	/* point trap #14 at abort.
	 * XXX this is futile since we restore the vbr first - oops
	 */
	vectors[VEC_TRAP14] = sun3x_prom_abort;
R
Roman Zippel 已提交
120
}
R
Roman Zippel 已提交
121

R
Roman Zippel 已提交
122 123
static int __init sun3x_debug_setup(char *arg)
{
R
Roman Zippel 已提交
124
	/* If debug=prom was specified, start the debug console */
R
Roman Zippel 已提交
125
	if (MACH_IS_SUN3X && !strcmp(arg, "prom"))
R
Roman Zippel 已提交
126
		register_console(&sun3x_debug);
R
Roman Zippel 已提交
127
	return 0;
L
Linus Torvalds 已提交
128 129
}

R
Roman Zippel 已提交
130 131
early_param("debug", sun3x_debug_setup);

L
Linus Torvalds 已提交
132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161
/* some prom functions to export */
int prom_getintdefault(int node, char *property, int deflt)
{
	return deflt;
}

int prom_getbool (int node, char *prop)
{
	return 1;
}

void prom_printf(char *fmt, ...)
{
}

void prom_halt (void)
{
	sun3x_halt();
}

/* Get the idprom and stuff it into buffer 'idbuf'.  Returns the
 * format type.  'num_bytes' is the number of bytes that your idbuf
 * has space for.  Returns 0xff on error.
 */
unsigned char
prom_get_idprom(char *idbuf, int num_bytes)
{
        int i;

	/* make a copy of the idprom structure */
R
Roman Zippel 已提交
162
	for (i = 0; i < num_bytes; i++)
L
Linus Torvalds 已提交
163 164 165 166
		idbuf[i] = ((char *)SUN3X_IDPROM)[i];

        return idbuf[0];
}