Statistics
| Branch: | Revision:

scoutos / prex-0.9.0 / bsp / hal / x86 / pc / diag.c @ 03e9c04a

History | View | Annotate | Download (3.92 KB)

1
/*-
2
 * Copyright (c) 2005-2009, Kohsuke Ohtani
3
 * All rights reserved.
4
 *
5
 * Redistribution and use in source and binary forms, with or without
6
 * modification, are permitted provided that the following conditions
7
 * are met:
8
 * 1. Redistributions of source code must retain the above copyright
9
 *    notice, this list of conditions and the following disclaimer.
10
 * 2. Redistributions in binary form must reproduce the above copyright
11
 *    notice, this list of conditions and the following disclaimer in the
12
 *    documentation and/or other materials provided with the distribution.
13
 * 3. Neither the name of the author nor the names of any co-contributors
14
 *    may be used to endorse or promote products derived from this software
15
 *    without specific prior written permission.
16
 *
17
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27
 * SUCH DAMAGE.
28
 */
29

    
30
/*
31
 * diag.c - diagnostic message support.
32
 */
33

    
34
#include <kernel.h>
35
#include <sys/bootinfo.h>
36
#include <cpufunc.h>
37

    
38
#ifdef CONFIG_DIAG_SCREEN
39

    
40
#define VID_ATTR        0x0F00
41
#define VID_PORT        0x03d4
42
#define VID_RAM                0xB8000
43

    
44
/* Screen info */
45
static short        *vram;
46
static int        pos_x;
47
static int        pos_y;
48
static int        screen_x;
49
static int        screen_y;
50

    
51
static void
52
screen_scroll_up(void)
53
{
54
        int i;
55

    
56
        memcpy(vram, vram + screen_x, (size_t)(screen_x * (screen_y - 1) * 2));
57
        for (i = 0; i < screen_x; i++)
58
                vram[screen_x * (screen_y - 1) + i] = ' ';
59
}
60

    
61
static void
62
screen_move_cursor(void)
63
{
64
        int pos = pos_y * screen_x + pos_x;
65

    
66
        outb(VID_PORT, 0x0e);
67
        outb(VID_PORT + 1, (u_int)pos >> 8);
68

    
69
        outb(VID_PORT, 0x0f);
70
        outb(VID_PORT + 1, (u_int)pos & 0xff);
71
}
72

    
73
static void
74
screen_newline(void)
75
{
76

    
77
        pos_x = 0;
78
        pos_y++;
79
        if (pos_y >= screen_y) {
80
                pos_y = screen_y - 1;
81
                screen_scroll_up();
82
        }
83
}
84

    
85
static void
86
screen_putc(char c)
87
{
88

    
89
        switch (c) {
90
        case '\n':
91
                screen_newline();
92
                return;
93
        case '\r':
94
                pos_x = 0;
95
                return;
96
        case '\b':
97
                if (pos_x == 0)
98
                        return;
99
                pos_x--;
100
                return;
101
        }
102
        vram[pos_y * screen_x + pos_x] = c | VID_ATTR;
103
        pos_x++;
104
        if (pos_x >= screen_x) {
105
                pos_x = 0;
106
                pos_y++;
107
                if (pos_y >= screen_y) {
108
                        pos_y = screen_y - 1;
109
                        screen_scroll_up();
110
                }
111
        }
112
}
113

    
114
void
115
diag_puts(char *str)
116
{
117

    
118
        while (*str)
119
                screen_putc(*str++);
120

    
121
        screen_move_cursor();
122
}
123

    
124
void
125
diag_init(void)
126
{
127
        struct bootinfo *bi;
128

    
129
        machine_bootinfo(&bi);
130

    
131
        vram = ptokv(VID_RAM);
132
        pos_x = 0;
133
        pos_y = 0;
134
        screen_x = bi->video.text_x;
135
        screen_y = bi->video.text_y;
136
}
137
#endif        /* !CONFIG_DIAG_SCREEN */
138

    
139

    
140
#ifdef CONFIG_DIAG_BOCHS
141
static void
142
bochs_putc(char c)
143
{
144
        /* Write to the bochs debug port. */
145
        outb(0xe9, (u_char)c);
146
}
147

    
148
void
149
diag_puts(char *str)
150
{
151

    
152
        /* Skip if Bochs is not running. */
153
        if (inb(0xe9) != 0xe9)
154
                return;
155

    
156
        while (*str)
157
                bochs_putc(*str++);
158
}
159

    
160
void
161
diag_init(void)
162
{
163
}
164
#endif        /* !CONFIG_DIAG_BOCHS */
165

    
166

    
167
#ifdef CONFIG_DIAG_SERIAL
168

    
169
#define COM_BASE        CONFIG_NS16550_BASE
170
#define COM_THR                (COM_BASE + 0x00)        /* transmit holding register */
171
#define COM_LSR                (COM_BASE + 0x05)        /* line status register */
172

    
173
static void
174
serial_putc(char c)
175
{
176

    
177
        while (!(inb(COM_LSR) & 0x20))
178
                ;
179
        outb(COM_THR, c);
180
}
181

    
182
void
183
diag_puts(char *str)
184
{
185

    
186
        while (*str) {
187
                if (*str == '\n')
188
                        serial_putc('\r');
189
                serial_putc(*str++);
190
        }
191
}
192

    
193
/*
194
 * We assume the serial port has already been initialized by
195
 * the boot loader.
196
 */
197
void
198
diag_init(void)
199
{
200
        /* DO NOTHING */
201
}
202

    
203
#endif        /* !CONFIG_DIAG_SERIAL */