~ubuntu-branches/ubuntu/intrepid/xserver-xgl/intrepid

« back to all changes in this revision

Viewing changes to hw/xfree86/int10/helper_mem.c

  • Committer: Bazaar Package Importer
  • Author(s): Matthew Garrett
  • Date: 2006-02-13 14:21:43 UTC
  • Revision ID: james.westby@ubuntu.com-20060213142143-mad6z9xzem7hzxz9
Tags: upstream-7.0.0
ImportĀ upstreamĀ versionĀ 7.0.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* $XFree86: xc/programs/Xserver/hw/xfree86/int10/helper_mem.c,v 1.25 2002/09/16 18:06:08 eich Exp $ */
 
2
/*
 
3
 *                   XFree86 int10 module
 
4
 *   execute BIOS int 10h calls in x86 real mode environment
 
5
 *                 Copyright 1999 Egbert Eich
 
6
 */
 
7
#ifdef HAVE_XORG_CONFIG_H
 
8
#include <xorg-config.h>
 
9
#endif
 
10
 
 
11
#include "xf86.h"
 
12
#include "xf86_OSproc.h"
 
13
#include "xf86_ansic.h"
 
14
#include "compiler.h"
 
15
#include "xf86Pci.h"
 
16
#define _INT10_PRIVATE
 
17
#if 0
 
18
#include "int10Defines.h"
 
19
#endif
 
20
#include "xf86int10.h"
 
21
 
 
22
#define REG pInt
 
23
 
 
24
typedef enum {
 
25
    OPT_NOINT10,
 
26
    OPT_INIT_PRIMARY,
 
27
    OPT_BIOS_LOCATION
 
28
} INT10Opts;
 
29
 
 
30
static const OptionInfoRec INT10Options[] = {
 
31
    {OPT_NOINT10,       "NoINT10",      OPTV_BOOLEAN,   {0},    FALSE },
 
32
    {OPT_INIT_PRIMARY,  "InitPrimary",  OPTV_BOOLEAN,   {0},    FALSE },   
 
33
    {OPT_BIOS_LOCATION, "BiosLocation", OPTV_STRING,    {0},    FALSE },
 
34
    { -1,               NULL,           OPTV_NONE,      {0},    FALSE },
 
35
};
 
36
 
 
37
#ifdef DEBUG
 
38
void
 
39
dprint(unsigned long start, unsigned long size)
 
40
{
 
41
    int i,j;
 
42
    char *c = (char *)start;
 
43
 
 
44
    for (j = 0; j < (size >> 4); j++) {
 
45
        char *d = c;
 
46
        ErrorF("\n0x%lx:  ",(unsigned long)c);
 
47
        for (i = 0; i<16; i++)
 
48
            ErrorF("%2.2x ",(unsigned char) (*(c++)));
 
49
        c = d;
 
50
        for (i = 0; i<16; i++) {
 
51
            ErrorF("%c",((((CARD8)(*c)) > 32) && (((CARD8)(*c)) < 128)) ?
 
52
                   (unsigned char) (*(c)): '.');
 
53
            c++;
 
54
        }
 
55
    }
 
56
    ErrorF("\n");
 
57
}
 
58
#endif
 
59
 
 
60
#ifndef _PC
 
61
/*
 
62
 * here we are really paranoid about faking a "real"
 
63
 * BIOS. Most of this information was pulled from
 
64
 * dosemu.
 
65
 */
 
66
void
 
67
setup_int_vect(xf86Int10InfoPtr pInt)
 
68
{
 
69
    int i;
 
70
 
 
71
    /* let the int vects point to the SYS_BIOS seg */
 
72
    for (i = 0; i < 0x80; i++) {
 
73
        MEM_WW(pInt, i << 2, 0);
 
74
        MEM_WW(pInt, (i << 2) + 2, SYS_BIOS >> 4);
 
75
    }
 
76
 
 
77
    reset_int_vect(pInt);
 
78
    /* font tables default location (int 1F) */
 
79
    MEM_WW(pInt,0x1f<<2,0xfa6e);
 
80
 
 
81
    /* int 11 default location (Get Equipment Configuration) */
 
82
    MEM_WW(pInt, 0x11 << 2, 0xf84d);
 
83
    /* int 12 default location (Get Conventional Memory Size) */
 
84
    MEM_WW(pInt, 0x12 << 2, 0xf841);
 
85
    /* int 15 default location (I/O System Extensions) */
 
86
    MEM_WW(pInt, 0x15 << 2, 0xf859);
 
87
    /* int 1A default location (RTC, PCI and others) */
 
88
    MEM_WW(pInt, 0x1a << 2, 0xff6e);
 
89
    /* int 05 default location (Bound Exceeded) */
 
90
    MEM_WW(pInt, 0x05 << 2, 0xff54);
 
91
    /* int 08 default location (Double Fault) */
 
92
    MEM_WW(pInt, 0x08 << 2, 0xfea5);
 
93
    /* int 13 default location (Disk) */
 
94
    MEM_WW(pInt, 0x13 << 2, 0xec59);
 
95
    /* int 0E default location (Page Fault) */
 
96
    MEM_WW(pInt, 0x0e << 2, 0xef57);
 
97
    /* int 17 default location (Parallel Port) */
 
98
    MEM_WW(pInt, 0x17 << 2, 0xefd2);
 
99
    /* fdd table default location (int 1e) */
 
100
    MEM_WW(pInt, 0x1e << 2, 0xefc7);
 
101
 
 
102
    /* Set Equipment flag to VGA */
 
103
    i = MEM_RB(pInt, 0x0410) & 0xCF;
 
104
    MEM_WB(pInt, 0x0410, i);
 
105
    /* XXX Perhaps setup more of the BDA here.  See also int42(0x00). */
 
106
}
 
107
#endif
 
108
 
 
109
int
 
110
setup_system_bios(void *base_addr)
 
111
{
 
112
    char *base = (char *) base_addr;
 
113
 
 
114
    /*
 
115
     * we trap the "industry standard entry points" to the BIOS
 
116
     * and all other locations by filling them with "hlt"
 
117
     * TODO: implement hlt-handler for these
 
118
     */
 
119
    memset(base, 0xf4, 0x10000);
 
120
 
 
121
    /* set bios date */
 
122
    strcpy(base + 0x0FFF5, "06/11/99");
 
123
    /* set up eisa ident string */
 
124
    strcpy(base + 0x0FFD9, "PCI_ISA");
 
125
    /* write system model id for IBM-AT */
 
126
    *((unsigned char *)(base + 0x0FFFE)) = 0xfc;
 
127
 
 
128
    return 1;
 
129
}
 
130
 
 
131
void
 
132
reset_int_vect(xf86Int10InfoPtr pInt)
 
133
{
 
134
    /*
 
135
     * This table is normally located at 0xF000:0xF0A4.  However, int 0x42,
 
136
     * function 0 (Mode Set) expects it (or a copy) somewhere in the bottom
 
137
     * 64kB.  Note that because this data doesn't survive POST, int 0x42 should
 
138
     * only be used during EGA/VGA BIOS initialisation.
 
139
     */
 
140
    static const CARD8 VideoParms[] = {
 
141
        /* Timing for modes 0x00 & 0x01 */
 
142
        0x38, 0x28, 0x2d, 0x0a, 0x1f, 0x06, 0x19, 0x1c,
 
143
        0x02, 0x07, 0x06, 0x07, 0x00, 0x00, 0x00, 0x00,
 
144
        /* Timing for modes 0x02 & 0x03 */
 
145
        0x71, 0x50, 0x5a, 0x0a, 0x1f, 0x06, 0x19, 0x1c,
 
146
        0x02, 0x07, 0x06, 0x07, 0x00, 0x00, 0x00, 0x00,
 
147
        /* Timing for modes 0x04, 0x05 & 0x06 */
 
148
        0x38, 0x28, 0x2d, 0x0a, 0x7f, 0x06, 0x64, 0x70,
 
149
        0x02, 0x01, 0x06, 0x07, 0x00, 0x00, 0x00, 0x00,
 
150
        /* Timing for mode 0x07 */
 
151
        0x61, 0x50, 0x52, 0x0f, 0x19, 0x06, 0x19, 0x19,
 
152
        0x02, 0x0d, 0x0b, 0x0c, 0x00, 0x00, 0x00, 0x00,
 
153
        /* Display page lengths in little endian order */
 
154
        0x00, 0x08, /* Modes 0x00 and 0x01 */
 
155
        0x00, 0x10, /* Modes 0x02 and 0x03 */
 
156
        0x00, 0x40, /* Modes 0x04 and 0x05 */
 
157
        0x00, 0x40, /* Modes 0x06 and 0x07 */
 
158
        /* Number of columns for each mode */
 
159
        40, 40, 80, 80, 40, 40, 80, 80,
 
160
        /* CGA Mode register value for each mode */
 
161
        0x2c, 0x28, 0x2d, 0x29, 0x2a, 0x2e, 0x1e, 0x29,
 
162
        /* Padding */
 
163
        0x00, 0x00, 0x00, 0x00
 
164
        };
 
165
    int i;
 
166
 
 
167
    for (i = 0; i < sizeof(VideoParms); i++)
 
168
        MEM_WB(pInt, i + (0x1000 - sizeof(VideoParms)), VideoParms[i]);
 
169
    MEM_WW(pInt,  0x1d << 2, 0x1000 - sizeof(VideoParms));
 
170
    MEM_WW(pInt, (0x1d << 2) + 2, 0);
 
171
 
 
172
    MEM_WW(pInt,  0x10 << 2, 0xf065);
 
173
    MEM_WW(pInt, (0x10 << 2) + 2, SYS_BIOS >> 4);
 
174
    MEM_WW(pInt,  0x42 << 2, 0xf065);
 
175
    MEM_WW(pInt, (0x42 << 2) + 2, SYS_BIOS >> 4);
 
176
    MEM_WW(pInt,  0x6D << 2, 0xf065);
 
177
    MEM_WW(pInt, (0x6D << 2) + 2, SYS_BIOS >> 4);
 
178
}
 
179
 
 
180
void
 
181
set_return_trap(xf86Int10InfoPtr pInt)
 
182
{
 
183
    /*
 
184
     * Here we set the exit condition:  We return when we encounter
 
185
     * 'hlt' (=0xf4), which we locate at address 0x600 in x86 memory.
 
186
     */
 
187
    MEM_WB(pInt, 0x0600, 0xf4);
 
188
 
 
189
    /*
 
190
     * Allocate a segment for the stack
 
191
     */
 
192
    xf86Int10AllocPages(pInt, 1, &pInt->stackseg);
 
193
}
 
194
 
 
195
void *
 
196
xf86HandleInt10Options(ScrnInfoPtr pScrn, int entityIndex)
 
197
{
 
198
    EntityInfoPtr pEnt = xf86GetEntityInfo(entityIndex);
 
199
    OptionInfoPtr options = NULL;
 
200
    
 
201
    if (pEnt->device) {
 
202
        pointer configOptions = NULL;
 
203
 
 
204
        /* Check if xf86CollectOptions() has already been called */
 
205
        if (((pEnt->index < 0) ||
 
206
            !pScrn ||
 
207
            !(configOptions = pScrn->options)) &&
 
208
            pEnt->device)
 
209
            configOptions = pEnt->device->options;
 
210
 
 
211
        if (configOptions) {
 
212
            if (!(options = (OptionInfoPtr) xalloc(sizeof(INT10Options))))
 
213
                return NULL;
 
214
             
 
215
            (void)memcpy(options, INT10Options, sizeof(INT10Options));
 
216
            xf86ProcessOptions(pScrn->scrnIndex, configOptions, options);
 
217
        }
 
218
    }
 
219
    xfree(pEnt);
 
220
 
 
221
    return options;
 
222
}
 
223
 
 
224
Bool
 
225
int10skip(void* options)
 
226
{
 
227
    Bool noint10 = FALSE;
 
228
 
 
229
    if (!options) return FALSE;
 
230
    
 
231
    xf86GetOptValBool(options, OPT_NOINT10, &noint10);
 
232
    return noint10;
 
233
}
 
234
 
 
235
Bool
 
236
int10_check_bios(int scrnIndex, int codeSeg, unsigned char* vbiosMem)
 
237
{
 
238
    int size;
 
239
 
 
240
    if ((codeSeg & 0x1f) ||     /* Not 512-byte aligned otherwise */
 
241
        ((codeSeg << 4) < V_BIOS) ||
 
242
        ((codeSeg << 4) >= SYS_SIZE))
 
243
        return FALSE;
 
244
 
 
245
    if (xf86IsPc98())
 
246
        return FALSE;
 
247
 
 
248
    if ((*vbiosMem != 0x55) || (*(vbiosMem+1) != 0xAA) || !*(vbiosMem+2))
 
249
        return FALSE;
 
250
 
 
251
    size = *(vbiosMem + 2) * 512;
 
252
 
 
253
    if ((size + (codeSeg << 4)) > SYS_SIZE)
 
254
        return FALSE;
 
255
 
 
256
    if (bios_checksum(vbiosMem, size))
 
257
        xf86DrvMsg(scrnIndex, X_WARNING, "Bad V_BIOS checksum\n");
 
258
 
 
259
    return TRUE;
 
260
}
 
261
 
 
262
Bool
 
263
initPrimary(void* options)
 
264
{
 
265
    Bool initPrimary = FALSE;
 
266
 
 
267
    if (!options) return FALSE;
 
268
    
 
269
    xf86GetOptValBool(options, OPT_INIT_PRIMARY, &initPrimary);
 
270
    return initPrimary;
 
271
}
 
272
 
 
273
/*
 
274
 * xf86int10ParseBiosLocation(): allows to set the location of the
 
275
 * BIOS. One may select a BIOS of another card for posting or the
 
276
 * legacy V_BIOS range located at 0xc0000 or an alternative address
 
277
 * (BUS_ISA).
 
278
 * This is only useful under very special circumstances and should
 
279
 * be used with extreme care.
 
280
 */
 
281
void
 
282
xf86int10ParseBiosLocation(void* options, 
 
283
                           xf86int10BiosLocationPtr bios)
 
284
{
 
285
    char *s;
 
286
    char *p;
 
287
    char *str = NULL;
 
288
 
 
289
    if (options)
 
290
        str = xf86GetOptValString(options,OPT_BIOS_LOCATION);
 
291
 
 
292
    bios->bus = BUS_NONE;
 
293
    if (!str)
 
294
        return;
 
295
    
 
296
    s = xstrdup(str);
 
297
    p = strtok(s,":");
 
298
    if (xf86NameCmp(p,"pci") == 0) bios->bus = BUS_PCI;
 
299
    else
 
300
        if (xf86NameCmp(p,"primary") == 0) bios->bus = BUS_ISA;
 
301
 
 
302
    xfree(s);
 
303
    
 
304
    if (bios->bus == BUS_NONE) return;
 
305
    
 
306
    s = xstrdup(str);
 
307
    p = strchr(s, ':');
 
308
                     
 
309
    switch (bios->bus) {
 
310
    case BUS_ISA:
 
311
        if (p)
 
312
            bios->location.legacy = atoi(++p);
 
313
        else
 
314
            bios->location.legacy = 0;
 
315
        break;
 
316
    case BUS_PCI:
 
317
        if (p) {
 
318
            bios->location.pci.bus = atoi(++p);
 
319
            if ((p = strchr(p, ':'))) {
 
320
                bios->location.pci.dev = atoi(++p);
 
321
                if ((p = strchr(p, ':'))) {
 
322
                    bios->location.pci.func = atoi(++p);
 
323
                    break;
 
324
                }
 
325
            }
 
326
        }
 
327
        /* fall through */
 
328
        bios->bus = BUS_NONE;
 
329
        break;
 
330
    default:
 
331
        break;
 
332
    }
 
333
    xfree(s);
 
334
}
 
335
 
 
336
 
 
337