summaryrefslogtreecommitdiffstats
path: root/arch/mips/orion/promcon.c
blob: 564d6cfae5735a751351d1e8282fd640978a6290 (plain)
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
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
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
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
/*
 * Wrap-around code for a console using the
 * SGI PROM io-routines.
 *
 * Copyright (c) 1999 Ulf Carlsson
 *
 * Derived from DECstation promcon.c
 * Copyright (c) 1998 Harald Koerfgen 
 */
#include <linux/tty.h>
#include <linux/major.h>
#include <linux/ptrace.h>
#include <linux/init.h>
#include <linux/console.h>
#include <linux/fs.h>

extern void prom_printf(char *fmt, ...);
unsigned long splx(unsigned long mask){return 0;}
#if 0
unsigned long ramsize=0x100000;
unsigned long RamSize(){return ramsize;}
extern void prom_printf(char *fmt, ...);
unsigned long splx(unsigned long mask){return 0;}
long PssSetIntHandler(unsigned long intnum, void *handler){}
long PssEnableInt(unsigned long intnum){}
long PssDisableInt(unsigned long intnum){}
unsigned long t_ident(char name[4], unsigned long node, unsigned long *tid){}
#endif

extern void  SerialPollConout(unsigned char c);
static void prom_console_write(struct console *co, const char *s,
			       unsigned count)
{
	unsigned i;

	/*
	 *    Now, do each character
	 */
	for (i = 0; i < count; i++) {
		if (*s == 10)
			SerialPollConout(13);
		SerialPollConout(*s++);
	}
}

extern int prom_getchar(void);
static int prom_console_wait_key(struct console *co)
{
	return prom_getchar();
}

extern void SerialPollInit(void);
extern void  SerialSetup(unsigned long  baud, unsigned long  console, unsigned long  host, unsigned long  intr_desc);
static int __init prom_console_setup(struct console *co, char *options)
{
	SerialSetup(19200,1,1,3);
	SerialPollInit();
	SerialPollOn();

	return 0;
}

static kdev_t prom_console_device(struct console *c)
{
	return MKDEV(TTY_MAJOR, 64 + c->index);
}

static struct console sercons =
{
	"ttyS",
	prom_console_write,
	NULL,
	prom_console_device,
	prom_console_wait_key,
	NULL,
	prom_console_setup,
	CON_PRINTBUFFER,
	-1,
	0,
	NULL
};

/*
 *    Register console.
 */
extern void zs_serial_console_init();
void serial_console_init(void)
{
	register_console(&sercons);
	/*zs_serial_console_init();*/
}

void prom_putchar(char c);

static char ppbuf[1000];

void prom_printf(char *fmt, ...)
{
	va_list args;
	char ch, *bptr;
	int i;

	va_start(args, fmt);
	i = vsprintf(ppbuf, fmt, args);

	bptr = ppbuf;

	while((ch = *(bptr++)) != 0) {
		if(ch == '\n')
			prom_putchar('\r');

		prom_putchar(ch);
	}
	va_end(args);
	return;
}

#define kSCC_Control	0xbf200008
#define kSCC_Data	(kSCC_Control + 4)

#define Tx_BUF_EMP      0x4     /* Tx Buffer empty */

static inline void RegisterDelay(void)
{
	int delay = 2*125;	/* Assuming 4us clock.  */
	while (delay--);
}

static inline unsigned char read_zsreg(unsigned char reg)
{
	unsigned char retval;

	if (reg != 0) {
		*(volatile unsigned char *)kSCC_Control = reg & 0xf;
		RegisterDelay();
	}

	retval = *(volatile unsigned char *) kSCC_Control;
	RegisterDelay();

	return retval;
}

static inline void write_zsreg(unsigned char reg, unsigned char value)
{
	if (reg != 0) {
		*((volatile unsigned char *) (kSCC_Control)) = reg & 0xf ;
		RegisterDelay();
	}

	*((volatile unsigned char *) (kSCC_Control)) = value ;
	RegisterDelay();
}

static inline unsigned char read_zsdata(void)
{
	unsigned char retval;

	retval = *(volatile unsigned char *)kSCC_Data;
	RegisterDelay();

	return retval;
}

static inline void write_zsdata(unsigned char value)
{
	*(volatile unsigned char *)kSCC_Data = value;
	RegisterDelay();

        return;
}

void prom_putchar(char c)
{
	while ((read_zsreg(0) & Tx_BUF_EMP) == 0)
		RegisterDelay();
	write_zsdata(c);
}

int prom_getchar(void)
{
	return 0;
}