Coverage Report

Created: 2017-10-25 09:10

/root/src/xen/xen/drivers/video/vga.c
Line
Count
Source (jump to first uncovered line)
1
/******************************************************************************
2
 * vga.c
3
 * 
4
 * VGA support routines.
5
 */
6
7
#include <xen/init.h>
8
#include <xen/lib.h>
9
#include <xen/mm.h>
10
#include <xen/vga.h>
11
#include <xen/pci.h>
12
#include <asm/io.h>
13
14
/* Filled in by arch boot code. */
15
struct xen_vga_console_info vga_console_info;
16
17
static int vgacon_keep;
18
static unsigned int xpos, ypos;
19
static unsigned char *video;
20
21
static void vga_text_puts(const char *s);
22
118k
static void vga_noop_puts(const char *s) {}
23
void (*video_puts)(const char *) = vga_noop_puts;
24
25
/*
26
 * 'vga=<mode-specifier>[,keep]' where <mode-specifier> is one of:
27
 * 
28
 *   'vga=ask':
29
 *      display a vga menu of available modes
30
 * 
31
 *   'vga=current':
32
 *      use the current vga mode without modification
33
 * 
34
 *   'vga=text-80x<rows>':
35
 *      text mode, where <rows> is one of {25,28,30,34,43,50,60}
36
 * 
37
 *   'vga=gfx-<width>x<height>x<depth>':
38
 *      graphics mode, e.g., vga=gfx-1024x768x16
39
 * 
40
 *   'vga=mode-<mode>:
41
 *      specifies a mode as specified in 'vga=ask' menu
42
 *      (NB. menu modes are displayed in hex, so mode numbers here must
43
 *           be prefixed with '0x' (e.g., 'vga=mode-0x0318'))
44
 * 
45
 * The option 'keep' causes Xen to continue to print to the VGA console even 
46
 * after domain 0 starts to boot. The default behaviour is to relinquish
47
 * control of the console to domain 0.
48
 */
49
static char __initdata opt_vga[30] = "";
50
string_param("vga", opt_vga);
51
52
/* VGA text-mode definitions. */
53
static unsigned int columns, lines;
54
12.3k
#define ATTRIBUTE   7
55
56
#ifdef CONFIG_X86
57
void vesa_early_init(void);
58
void vesa_endboot(bool_t keep);
59
#else
60
#define vesa_early_init() ((void)0)
61
#define vesa_endboot(x)   ((void)0)
62
#endif
63
64
void __init video_init(void)
65
1
{
66
1
    char *p;
67
1
68
1
    /* Look for 'keep' in comma-separated options. */
69
2
    for ( p = opt_vga; p != NULL; p = strchr(p, ',') )
70
1
    {
71
1
        if ( *p == ',' )
72
0
            p++;
73
1
        if ( strncmp(p, "keep", 4) == 0 )
74
0
            vgacon_keep = 1;
75
1
    }
76
1
77
1
    switch ( vga_console_info.video_type )
78
1
    {
79
1
    case XEN_VGATYPE_TEXT_MODE_3:
80
1
        if ( page_is_ram_type(paddr_to_pfn(0xB8000), RAM_TYPE_CONVENTIONAL) ||
81
1
             ((video = ioremap(0xB8000, 0x8000)) == NULL) )
82
0
            return;
83
1
        outw(0x200a, 0x3d4); /* disable cursor */
84
1
        columns = vga_console_info.u.text_mode_3.columns;
85
1
        lines   = vga_console_info.u.text_mode_3.rows;
86
1
        memset(video, 0, columns * lines * 2);
87
1
        video_puts = vga_text_puts;
88
1
        break;
89
0
    case XEN_VGATYPE_VESA_LFB:
90
0
    case XEN_VGATYPE_EFI_LFB:
91
0
        vesa_early_init();
92
0
        break;
93
0
    default:
94
0
        memset(&vga_console_info, 0, sizeof(vga_console_info));
95
0
        break;
96
1
    }
97
1
}
98
99
void __init video_endboot(void)
100
1
{
101
1
    if ( video_puts == vga_noop_puts )
102
0
        return;
103
1
104
1
    printk("Xen is %s VGA console.\n",
105
1
           vgacon_keep ? "keeping" : "relinquishing");
106
1
107
1
    if ( !vgacon_keep )
108
1
        video_puts = vga_noop_puts;
109
1
    else
110
0
    {
111
0
        int bus, devfn;
112
0
113
0
        for ( bus = 0; bus < 256; ++bus )
114
0
            for ( devfn = 0; devfn < 256; ++devfn )
115
0
            {
116
0
                const struct pci_dev *pdev;
117
0
                u8 b = bus, df = devfn, sb;
118
0
119
0
                pcidevs_lock();
120
0
                pdev = pci_get_pdev(0, bus, devfn);
121
0
                pcidevs_unlock();
122
0
123
0
                if ( !pdev ||
124
0
                     pci_conf_read16(0, bus, PCI_SLOT(devfn), PCI_FUNC(devfn),
125
0
                                     PCI_CLASS_DEVICE) != 0x0300 ||
126
0
                     !(pci_conf_read16(0, bus, PCI_SLOT(devfn),
127
0
                                       PCI_FUNC(devfn), PCI_COMMAND) &
128
0
                       (PCI_COMMAND_IO | PCI_COMMAND_MEMORY)) )
129
0
                    continue;
130
0
131
0
                while ( b )
132
0
                {
133
0
                    switch ( find_upstream_bridge(0, &b, &df, &sb) )
134
0
                    {
135
0
                    case 0:
136
0
                        b = 0;
137
0
                        break;
138
0
                    case 1:
139
0
                        switch ( pci_conf_read8(0, b, PCI_SLOT(df),
140
0
                                                PCI_FUNC(df),
141
0
                                                PCI_HEADER_TYPE) )
142
0
                        {
143
0
                        case PCI_HEADER_TYPE_BRIDGE:
144
0
                        case PCI_HEADER_TYPE_CARDBUS:
145
0
                            if ( pci_conf_read16(0, b, PCI_SLOT(df),
146
0
                                                 PCI_FUNC(df),
147
0
                                                 PCI_BRIDGE_CONTROL) &
148
0
                                 PCI_BRIDGE_CTL_VGA )
149
0
                                continue;
150
0
                            break;
151
0
                        }
152
0
                        break;
153
0
                    }
154
0
                    break;
155
0
                }
156
0
                if ( !b )
157
0
                {
158
0
                    printk(XENLOG_INFO "Boot video device %02x:%02x.%u\n",
159
0
                           bus, PCI_SLOT(devfn), PCI_FUNC(devfn));
160
0
                    pci_hide_device(bus, devfn);
161
0
                }
162
0
            }
163
0
    }
164
1
165
1
    switch ( vga_console_info.video_type )
166
1
    {
167
1
    case XEN_VGATYPE_TEXT_MODE_3:
168
1
        if ( !vgacon_keep )
169
1
            memset(video, 0, columns * lines * 2);
170
1
        break;
171
0
    case XEN_VGATYPE_VESA_LFB:
172
0
    case XEN_VGATYPE_EFI_LFB:
173
0
        vesa_endboot(vgacon_keep);
174
0
        break;
175
0
    default:
176
0
        BUG();
177
1
    }
178
1
}
179
180
static void vga_text_puts(const char *s)
181
882
{
182
882
    char c;
183
882
184
13.4k
    while ( (c = *s++) != '\0' )
185
12.6k
    {
186
12.6k
        if ( (c == '\n') || (xpos >= columns) )
187
272
        {
188
272
            if ( ++ypos >= lines )
189
248
            {
190
248
                ypos = lines - 1;
191
248
                memmove(video, video + 2 * columns, ypos * 2 * columns);
192
248
                memset(video + ypos * 2 * columns, 0, 2 * xpos);
193
248
            }
194
272
            xpos = 0;
195
272
        }
196
12.6k
197
12.6k
        if ( c != '\n' )
198
12.3k
        {
199
12.3k
            video[(xpos + ypos * columns) * 2]     = c;
200
12.3k
            video[(xpos + ypos * columns) * 2 + 1] = ATTRIBUTE;
201
12.3k
            xpos++;
202
12.3k
        }
203
12.6k
    }
204
882
}
205
206
int __init fill_console_start_info(struct dom0_vga_console_info *ci)
207
0
{
208
0
    memcpy(ci, &vga_console_info, sizeof(*ci));
209
0
    return 1;
210
0
}