printk_foo -> printk(BIOS_FOO, ...)
[coreboot.git] / src / northbridge / via / vx800 / vgabios.c
1 #include <console/console.h>
2 #include <device/pci.h>
3 #include <device/pci_ids.h>
4 #include <device/pci_ops.h>
5 #undef __KERNEL__
6 #include <arch/io.h>
7 #include <string.h>
8 #include "vgachip.h"
9 #include <cbfs.h>
10
11 /* vgabios.c. Derived from: */
12
13 /*------------------------------------------------------------ -*- C -*-
14  *  2 Kernel Monte a.k.a. Linux loading Linux on x86
15  *
16  *  Erik Arjan Hendriks <hendriks@lanl.gov>
17  *
18  *  This version is a derivative of the original two kernel monte
19  *  which is (C) 2000 Scyld.
20  *
21  *  Copyright (C) 2000 Scyld Computing Corporation
22  *
23  *  This program is free software; you can redistribute it and/or modify
24  *  it under the terms of the GNU General Public License as published by
25  *  the Free Software Foundation; version 2 of the License.
26  *
27  *  This program is distributed in the hope that it will be useful,
28  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
29  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
30  *  GNU General Public License for more details.
31  *
32  *  You should have received a copy of the GNU General Public License
33  *  along with this program; if not, write to the Free Software
34  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
35  *
36  * Portions related to the alpha architecture are:
37  *
38  *  Copyright(C) 2001 University of California.  LA-CC Number 01-67.
39  *  This software has been authored by an employee or employees of the
40  *  University of California, operator of the Los Alamos National
41  *  Laboratory under Contract No.  W-7405-ENG-36 with the U.S.
42  *  Department of Energy.  The U.S. Government has rights to use,
43  *  reproduce, and distribute this software. If the software is
44  *  modified to produce derivative works, such modified software should
45  *  be clearly marked, so as not to confuse it with the version
46  *  available from LANL.
47  *
48  *  This software may be used and distributed according to the terms
49  *  of the GNU General Public License, incorporated herein by
50  *  reference to http://www.gnu.org/licenses/gpl.html.
51  *
52  *  This software is provided by the author(s) "as is" and any express
53  *  or implied warranties, including, but not limited to, the implied
54  *  warranties of merchantability and fitness for a particular purpose
55  *  are disclaimed.  In no event shall the author(s) be liable for any
56  *  direct, indirect, incidental, special, exemplary, or consequential
57  *  damages (including, but not limited to, procurement of substitute
58  *  goods or services; loss of use, data, or profits; or business
59  *  interruption) however caused and on any theory of liability,
60  *  whether in contract, strict liability, or tort (including
61  *  negligence or otherwise) arising in any way out of the use of this
62  *  software, even if advised of the possibility of such damage.
63  *
64  *  $Id: vgabios.c,v 1.5 2004/10/06 17:33:52 rminnich Exp $
65  *--------------------------------------------------------------------*/
66
67 /* Modified to be a self sufficient plug in so that it can be used 
68    without reliance on other parts of coreboot's core
69    (C) 2005 Nick.Barker9@btinternet.com
70
71   Used initially for epia-m where there are problems getting the bios
72   emulator to successfully run this bios.
73 */
74 /* Declare a temporary global descriptor table - necessary because the
75    Core part of the bios no longer sets up any 16 bit segments */
76 __asm__(
77                /* pointer to original gdt */
78                "gdtarg:                 \n"
79                "        .word   gdt_limit       \n"
80                "        .long   gdt             \n"
81                /* compute the table limit */
82                "__mygdt_limit = __mygdt_end - __mygdt - 1       \n"
83                "__mygdtaddr:                    \n"
84                "        .word   __mygdt_limit   \n"
85                "        .long   __mygdt         \n"
86                "__mygdt:                        \n"
87                /* selgdt 0, unused */
88                "        .word   0x0000, 0x0000  \n"
89                "        .byte   0x00, 0x00, 0x00, 0x00  \n"
90                /* selgdt 8, unused */
91                "        .word   0x0000, 0x0000          \n"
92                "        .byte   0x00, 0x00, 0x00, 0x00  \n"
93                /* selgdt 0x10, flat code segment */
94                "        .word   0xffff, 0x0000          \n"
95                "        .byte   0x00, 0x9b, 0xcf, 0x00  \n"
96                /* selgdt 0x18, flat data segment */
97                "        .word   0xffff, 0x0000          \n"
98                "        .byte   0x00, 0x93, 0xcf, 0x00  \n"
99                /* selgdt 0x20, unused */
100                "        .word   0x0000, 0x0000          \n"
101                "        .byte   0x00, 0x00, 0x00, 0x00  \n"
102                /* selgdt 0x28 16-bit 64k code at 0x00000000 */
103                "        .word   0xffff, 0x0000          \n"
104                "        .byte   0, 0x9a, 0, 0           \n"
105                /* selgdt 0x30 16-bit 64k data at 0x00000000 */
106                "        .word   0xffff, 0x0000          \n"
107                "        .byte   0, 0x92, 0, 0           \n"
108                "__mygdt_end:                            \n");
109
110 /* Declare a pointer to where our idt is going to be i.e. at mem zero */
111 __asm__("__myidt:               \n"
112         /* 16-bit limit */
113         "       .word 1023      \n"
114         /* 24-bit base */
115         "       .long 0         \n" "   .word 0         \n");
116
117 /* The address arguments to this function are PHYSICAL ADDRESSES */
118 extern u8 acpi_sleep_type;
119
120 static void real_mode_switch_call_vga(unsigned long devfn)
121 {
122         if ((acpi_sleep_type == 0)/* && (PAYLOAD_IS_SEABIOS == 1)*/)
123                 return;
124         __asm__ __volatile__(
125                                     // paranoia -- does ecx get saved? not sure. This is 
126                                     // the easiest safe thing to do.
127                                     "   pushal                  \n"
128                                     /* save the stack */
129                                     "   mov     %esp, __stack   \n"
130                                     "   jmp     1f              \n"
131                                     "__stack: .long 0           \n" "1:\n"
132                                     /* get devfn into %ecx */
133                                     "   movl    %esp, %ebp      \n"
134                                     "   movl    8(%ebp), %ecx   \n"
135                                     /* load 'our' gdt */
136                                     "   lgdt    %cs:__mygdtaddr \n"
137                                     /*  This configures CS properly for real mode. */
138                                     "   ljmp    $0x28, $__rms_16bit\n"
139                                     "__rms_16bit:                       \n"
140                                     "   .code16                 \n"
141                                     /* 16 bit code from here on... */
142                                     /* Load the segment registers w/ properly configured segment
143                                      * descriptors.  They will retain these configurations (limits,
144                                      * writability, etc.) once protected mode is turned off. */
145                                     "   mov     $0x30, %ax      \n"
146                                     "   mov     %ax, %ds        \n"
147                                     "   mov     %ax, %es        \n"
148                                     "   mov     %ax, %fs        \n"
149                                     "   mov     %ax, %gs        \n"
150                                     "   mov     %ax, %ss        \n"
151                                     /* Turn off protection (bit 0 in CR0) */
152                                     "   movl    %cr0, %eax      \n"
153                                     "   andl    $0xFFFFFFFE, %eax \n"
154                                     "   movl    %eax, %cr0      \n"
155                                     /* Now really going into real mode */
156                                     "   ljmp    $0,  $__rms_real\n"
157                                     "__rms_real:                        \n"
158                                     /* put the stack at the end of page zero. 
159                                      * that way we can easily share it between real and protected, 
160                                      * since the 16-bit ESP at segment 0 will work for any case. 
161                                      /* Setup a stack */
162                                     "   mov     $0x0, %ax       \n"
163                                     "   mov     %ax, %ss        \n"
164                                     "   movl    $0x1000, %eax   \n"
165                                     "   movl    %eax, %esp      \n"
166                                     /* Load our 16 it idt */
167                                     "   xor     %ax, %ax        \n"
168                                     "   mov     %ax, %ds        \n"
169                                     "   lidt    __myidt         \n"
170                                     /* Dump zeros in the other segregs */
171                                     "   mov     %ax, %es        \n"
172                                     "   mov     %ax, %fs        \n"
173                                     "   mov     %ax, %gs        \n"
174                                     "   mov     $0x40, %ax      \n"
175                                     "   mov     %ax, %ds        \n"
176                                     "   mov     %cx, %ax        \n"
177                                     /* run VGA BIOS at 0xc000:0003 */
178                                     "   lcall   $0xc000, $0x0003\n"
179                                     /* if we got here, just about done. 
180                                      * Need to get back to protected mode */
181                                     "   movl    %cr0, %eax      \n" "   orl     $0x0000001, %eax\n"     /* PE = 1 */
182                                     "   movl    %eax, %cr0      \n"
183                                     /* Now that we are in protected mode jump to a 32 bit code segment. */
184                                     "   data32  ljmp    $0x10, $vgarestart\n"
185                                     "vgarestart:\n"
186                                     "   .code32\n"
187                                     "   movw    $0x18, %ax      \n"
188                                     "   mov     %ax, %ds        \n"
189                                     "   mov     %ax, %es        \n"
190                                     "   mov     %ax, %fs        \n"
191                                     "   mov     %ax, %gs        \n"
192                                     "   mov     %ax, %ss        \n"
193                                     /* restore proper gdt and idt */
194                                     "   lgdt    %cs:gdtarg      \n"
195                                     "   lidt    idtarg          \n"
196                                     ".globl vga_exit            \n"
197                                     "vga_exit:                  \n"
198                                     "   mov     __stack, %esp   \n"
199                                     "   popal                   \n");
200 }
201
202 __asm__(".text\n" "real_mode_switch_end:\n");
203 extern char real_mode_switch_end[];
204
205 /* call vga bios int 10 function 0x4f14 to enable main console 
206    epia-m does not always autosence the main console so forcing it on is good !! */
207 void vga_enable_console()
208 {
209         if ((acpi_sleep_type == 0)/* && (PAYLOAD_IS_SEABIOS == 1)*/)
210                 return;
211         __asm__ __volatile__(
212                                     /* paranoia -- does ecx get saved? not sure. This is 
213                                      * the easiest safe thing to do. */
214                                     "   pushal                  \n"
215                                     /* save the stack */
216                                     "   mov     %esp, __stack   \n"
217                                     /* load 'our' gdt */
218                                     "   lgdt    %cs:__mygdtaddr \n"
219                                     /*  This configures CS properly for real mode. */
220                                     "   ljmp    $0x28, $__vga_ec_16bit\n"
221                                     "__vga_ec_16bit:            \n"
222                                     "   .code16                 \n"
223                                     /* 16 bit code from here on... */
224                                     /* Load the segment registers w/ properly configured segment
225                                      * descriptors.  They will retain these configurations (limits,
226                                      * writability, etc.) once protected mode is turned off. */
227                                     "   mov     $0x30, %ax      \n"
228                                     "   mov     %ax, %ds        \n"
229                                     "   mov     %ax, %es        \n"
230                                     "   mov     %ax, %fs        \n"
231                                     "   mov     %ax, %gs        \n"
232                                     "   mov     %ax, %ss        \n"
233                                     /* Turn off protection (bit 0 in CR0) */
234                                     "   movl    %cr0, %eax      \n"
235                                     "   andl    $0xFFFFFFFE, %eax\n"
236                                     "   movl    %eax, %cr0      \n"
237                                     /* Now really going into real mode */
238                                     "   ljmp    $0, $__vga_ec_real \n"
239                                     "__vga_ec_real:                  \n"
240                                     /* put the stack at the end of page zero. 
241                                      * that way we can easily share it between real and protected, 
242                                      * since the 16-bit ESP at segment 0 will work for any case. 
243                                      /* Setup a stack */
244                                     "   mov     $0x0, %ax       \n"
245                                     "   mov     %ax, %ss        \n"
246                                     "   movl    $0x1000, %eax   \n"
247                                     "   movl    %eax, %esp      \n"
248                                     /* debugging for RGM */
249                                     "   mov     $0x11, %al      \n"
250                                     "   outb    %al, $0x80      \n"
251                                     /* Load our 16 it idt */
252                                     "   xor     %ax, %ax        \n"
253                                     "   mov     %ax, %ds        \n"
254                                     "   lidt    __myidt         \n"
255                                     /* Dump zeros in the other segregs */
256                                     "   mov     %ax, %ds        \n"
257                                     "   mov     %ax, %es        \n"
258                                     "   mov     %ax, %fs        \n"
259                                     "   mov     %ax, %gs        \n"
260                                     /* ask bios to enable main console */
261                                     /* set up for int 10 call - values found from X server
262                                      * bios call routines */
263                                     "   movw    $0x4f14,%ax     \n"
264                                     "   movw    $0x8003,%bx     \n"
265                                     "   movw    $1, %cx         \n"
266                                     "   movw    $0, %dx         \n"
267                                     "   movw    $0, %di         \n"
268                                     "   int     $0x10           \n"
269                                     "   movb    $0x55, %al      \n"
270                                     "   outb    %al, $0x80      \n"
271                                     /* if we got here, just about done. 
272                                      * Need to get back to protected mode */
273                                     "   movl    %cr0, %eax      \n" "   orl     $0x0000001, %eax\n"     /* PE = 1 */
274                                     "   movl    %eax, %cr0      \n"
275                                     /* Now that we are in protected mode jump to a 32 bit code segment. */
276                                     "   data32  ljmp    $0x10, $vga_ec_restart\n"
277                                     "vga_ec_restart:\n"
278                                     "   .code32\n"
279                                     "   movw    $0x18, %ax      \n"
280                                     "   mov     %ax, %ds        \n"
281                                     "   mov     %ax, %es        \n"
282                                     "   mov     %ax, %fs        \n"
283                                     "   mov     %ax, %gs        \n"
284                                     "   mov     %ax, %ss        \n"
285                                     /* restore proper gdt and idt */
286                                     "   lgdt    %cs:gdtarg      \n"
287                                     "   lidt    idtarg          \n"
288                                     "   .globl  vga__ec_exit    \n"
289                                     "vga_ec_exit:\n"
290                                     "   mov     __stack, %esp   \n"
291                                     "   popal\n");
292 }
293
294 void do_vgabios(void)
295 {
296         device_t dev;
297         unsigned long busdevfn;
298         unsigned int rom = 0;
299         unsigned char *buf;
300         unsigned int size = 64 * 1024;
301         int i;
302         u16 tmp;
303         u8 tmp8;
304
305         printk(BIOS_EMERG, "file '%s', line %d\n\n", __FILE__, __LINE__);
306
307         /* clear vga bios data area */
308         for (i = 0x400; i < 0x500; i++) {
309                 *(unsigned char *)i = 0;
310         }
311
312         dev = dev_find_class(PCI_CLASS_DISPLAY_VGA << 8, 0);
313
314         if (!dev) {
315                 printk(BIOS_DEBUG, "NO VGA FOUND\n");
316                 return;
317         }
318         printk(BIOS_DEBUG, "found VGA: vid=%x, did=%x\n", dev->vendor, dev->device);
319
320         /* declare rom address here - keep any config data out of the way
321          * of core LXB stuff */
322
323         rom = cbfs_load_optionrom(dev->vendor, dev->device, 0);
324         pci_write_config32(dev, PCI_ROM_ADDRESS, rom | 1);
325         printk(BIOS_DEBUG, "rom base: %x\n", rom);
326         buf = (unsigned char *)rom;
327         printk(BIOS_EMERG, "file '%s', line %d\n\n", __FILE__, __LINE__);
328
329         if ((buf[0] == 0x55) && (buf[1] == 0xaa)) {
330                 memcpy((void *)0xc0000, buf, size);
331
332                 printk(BIOS_EMERG, "file '%s', line %d\n\n", __FILE__, __LINE__);
333
334                 write_protect_vgabios();        // in northbridge
335
336                 // check signature again
337                 buf = (unsigned char *)0xc0000;
338                 if (buf[0] == 0x55 && buf[1] == 0xAA) {
339                         busdevfn =
340                             (dev->bus->secondary << 8) | dev->path.pci.devfn;
341                         printk(BIOS_DEBUG, "bus/devfn = %#x\n", busdevfn);
342                         real_mode_switch_call_vga(busdevfn);
343                 } else
344                         printk(BIOS_DEBUG, "Failed to copy VGA BIOS to 0xc0000\n");
345         } else
346                 printk(BIOS_DEBUG, "BAD SIGNATURE 0x%x 0x%x\n", buf[0], buf[1]);
347
348         printk(BIOS_EMERG, "file '%s', line %d\n\n", __FILE__, __LINE__);
349
350         pci_write_config32(dev, PCI_ROM_ADDRESS, 0);
351 }
352
353 // we had hoped to avoid this. 
354 // this is a stub IDT only. It's main purpose is to ignore calls 
355 // to the BIOS. 
356 // no longer. Dammit. We have to respond to these.
357 struct realidt {
358         unsigned short offset, cs;
359 };
360
361 // from a handy writeup that andrey found.
362
363 // handler. 
364 // There are some assumptions we can make here. 
365 // First, the Top Of Stack (TOS) is located on the top of page zero. 
366 // we can share this stack between real and protected mode. 
367 // that simplifies a lot of things ...
368 // we'll just push all the registers on the stack as longwords, 
369 // and pop to protected mode. 
370 // second, since this only ever runs as part of coreboot, 
371 // we know all the segment register values -- so we don't save any.
372 // keep the handler that calls things small. It can do a call to 
373 // more complex code in coreboot itself. This helps a lot as we don't
374 // have to do address fixup in this little stub, and calls are absolute
375 // so the handler is relocatable.
376 void handler(void)
377 {
378         __asm__ __volatile__("  .code16         \n"
379                              "idthandle:                \n"
380                              "  pushal          \n"
381                              "  movb    $0, %al \n"
382                              "  ljmp    $0, $callbiosint16\n"
383                              "end_idthandle:            \n"
384                              "  .code32         \n");
385 }
386
387 void debughandler(void)
388 {
389         __asm__ __volatile__("  .code16         \n"
390                              "debughandle:              \n"
391                              "  pushw   %cx     \n"
392                              "  movw    $250, %cx \n"
393                              "dbh1:                     \n"
394                              "  loop    dbh1    \n"
395                              "  popw    %cx     \n"
396                              "  iret            \n"
397                              "end_debughandle:  \n" ".code32            \n");
398 }
399
400 // Calling conventions. The first C function is called with this stuff
401 // on the stack. They look like value parameters, but note that if you
402 // modify them they will go back to the INTx function modified. 
403 // the C function will call the biosint function with these as
404 // REFERENCE parameters. In this way, we can easily get 
405 // returns back to the INTx caller (i.e. vgabios)
406 void callbiosint(void)
407 {
408         __asm__ __volatile__("  .code16         \n"
409                              "callbiosint16:            \n"
410                              "  push    %ds     \n"
411                              "  push    %es     \n"
412                              "  push    %fs     \n" "   push    %gs     \n"
413                              // clean up the int #. To save space we put it in the lower
414                              // byte. But the top 24 bits are junk. 
415                              "  andl    $0xff, %eax\n"
416                              // this push does two things:
417                              // - put the INT # on the stack as a parameter
418                              // - provides us with a temp for the %cr0 mods.
419                              "  pushl   %eax    \n" "   movl    %cr0, %eax\n" " orl     $0x00000001, %eax\n"    /* PE = 1 */
420                              "  movl    %eax, %cr0\n"
421                              /* Now that we are in protected mode jump to a 32 bit code segment. */
422                              "  data32  ljmp    $0x10, $biosprotect\n"
423                              "biosprotect:              \n"
424                              "  .code32         \n"
425                              "  movw    $0x18, %ax          \n"
426                              "  mov     %ax, %ds          \n"
427                              "  mov     %ax, %es          \n"
428                              "  mov     %ax, %fs          \n"
429                              "  mov     %ax, %gs          \n"
430                              "  mov     %ax, %ss          \n"
431                              "  lidt    idtarg         \n"
432                              "  call    biosint \n"
433                              // back to real mode ...
434                              "  ljmp    $0x28, $__rms_16bit2\n"
435                              "__rms_16bit2:                     \n"
436                              "  .code16                 \n"
437                              /* 16 bit code from here on... */
438                              /* Load the segment registers w/ properly configured segment
439                               * descriptors.  They will retain these configurations (limits,
440                               * writability, etc.) once protected mode is turned off. */
441                              "  mov     $0x30, %ax      \n"
442                              "  mov     %ax, %ds        \n"
443                              "  mov     %ax, %es        \n"
444                              "  mov     %ax, %fs        \n"
445                              "  mov     %ax, %gs        \n"
446                              "  mov     %ax, %ss        \n"
447                              /* Turn off protection (bit 0 in CR0) */
448                              "  movl    %cr0, %eax              \n"
449                              "  andl    $0xFFFFFFFE, %eax       \n"
450                              "  movl    %eax, %cr0              \n"
451                              /* Now really going into real mode */
452                              "  ljmp $0,  $__rms_real2  \n"
453                              "__rms_real2:                      \n"
454                              /* Setup a stack
455                               * FixME: where is esp? */
456                              "  mov     $0x0, %ax       \n"
457                              "  mov     %ax, %ss        \n"
458                              /* ebugging for RGM */
459                              "  mov     $0x11, %al      \n"
460                              "  outb    %al, $0x80      \n"
461                              /* Load our 16 it idt */
462                              "  xor     %ax, %ax        \n"
463                              "  mov     %ax, %ds        \n"
464                              "  lidt    __myidt         \n"
465                              /* Dump zeros in the other segregs */
466                              "  mov     %ax, %es        \n"
467                              "  mov     %ax, %fs        \n"
468                              "  mov     %ax, %gs        \n"
469                              "  mov     $0x40, %ax      \n"
470                              "  mov     %ax, %ds        \n"
471                              /* pop the INT # that you pushed earlier */
472                              "  popl    %eax            \n"
473                              "  pop     %gs             \n"
474                              "  pop     %fs             \n"
475                              "  pop     %es             \n"
476                              "  pop     %ds             \n"
477                              "  popal                   \n"
478                              "  iret                    \n"
479                              "  .code32                 \n");
480 }
481
482 enum {
483         PCIBIOS = 0x1a,
484         MEMSIZE = 0x12
485 };
486
487 int pcibios(unsigned long *pedi, unsigned long *pesi, unsigned long *pebp,
488             unsigned long *pesp, unsigned long *pebx, unsigned long *pedx,
489             unsigned long *pecx, unsigned long *peax, unsigned long *pflags);
490
491 int handleint21(unsigned long *pedi, unsigned long *pesi,
492                 unsigned long *pebp, unsigned long *pesp,
493                 unsigned long *pebx, unsigned long *pedx,
494                 unsigned long *pecx, unsigned long *peax,
495                 unsigned long *pflags);
496
497 extern void vga_exit(void);
498
499 int biosint(unsigned long intnumber,
500             unsigned long gsfs, unsigned long dses,
501             unsigned long edi, unsigned long esi,
502             unsigned long ebp, unsigned long esp,
503             unsigned long ebx, unsigned long edx,
504             unsigned long ecx, unsigned long eax,
505             unsigned long cs_ip, unsigned short stackflags)
506 {
507         unsigned long ip;
508         unsigned long cs;
509         unsigned long flags;
510         int ret = -1;
511
512         ip = cs_ip & 0xffff;
513         cs = cs_ip >> 16;
514         flags = stackflags;
515
516         printk(BIOS_DEBUG, "biosint: INT# 0x%lx\n", intnumber);
517         printk(BIOS_DEBUG, "biosint: eax 0x%lx ebx 0x%lx ecx 0x%lx edx 0x%lx\n",
518                      eax, ebx, ecx, edx);
519         printk(BIOS_DEBUG, "biosint: ebp 0x%lx esp 0x%lx edi 0x%lx esi 0x%lx\n",
520                      ebp, esp, edi, esi);
521         printk(BIOS_DEBUG, "biosint:  ip 0x%x   cs 0x%x  flags 0x%x\n",
522                      ip, cs, flags);
523
524         // cases in a good compiler are just as good as your own tables. 
525         switch (intnumber) {
526         case 0: case 1: case 2: case 3: case 4: case 5:
527         case 6: case 7: case 8: case 9: case 10:
528         case 11: case 12: case 13: case 14: case 15:
529                 // These are not BIOS service, but the CPU-generated exceptions
530                 printk(BIOS_INFO, "biosint: Oops, exception %u\n", intnumber);
531                 if (esp < 0x1000) {
532                         printk(BIOS_DEBUG, "Stack contents: ");
533                         while (esp < 0x1000) {
534                                 printk(BIOS_DEBUG, "0x%04x ", *(unsigned short *)esp);
535                                 esp += 2;
536                         }
537                         printk(BIOS_DEBUG, "\n");
538                 }
539                 printk(BIOS_DEBUG, "biosint: Bailing out\n");
540                 // "longjmp"
541                 if ((acpi_sleep_type == 3)/* || (PAYLOAD_IS_SEABIOS == 0)*/)    // add this to keep same with kevin's seabios patch in 2008-9-8
542                         vga_exit();
543                 break;
544
545         case PCIBIOS:
546                 ret = pcibios(&edi, &esi, &ebp, &esp,
547                               &ebx, &edx, &ecx, &eax, &flags);
548                 break;
549         case MEMSIZE:
550                 // who cares. 
551                 eax = 64 * 1024;
552                 ret = 0;
553                 break;
554         case 0x15:
555                 ret = handleint21(&edi, &esi, &ebp, &esp,
556                                   &ebx, &edx, &ecx, &eax, &flags);
557                 break;
558         default:
559                 printk(BIOS_INFO, "BIOSINT: Unsupport int #0x%x\n", intnumber);
560                 break;
561         }
562         if (ret)
563                 flags |= 1;     // carry flags
564         else
565                 flags &= ~1;
566         stackflags = flags;
567         return ret;
568 }
569
570 void setup_realmode_idt(void)
571 {
572         extern unsigned char idthandle, end_idthandle;
573         extern unsigned char debughandle, end_debughandle;
574
575         int i;
576         struct realidt *idts = (struct realidt *)0;
577         int codesize = &end_idthandle - &idthandle;
578         unsigned char *intbyte, *codeptr;
579
580         // for each int, we create a customized little handler
581         // that just pushes %ax, puts the int # in %al, 
582         // then calls the common interrupt handler. 
583         // this necessitated because intel didn't know much about 
584         // architecture when they did the 8086 (it shows)
585         // (hmm do they know anymore even now :-)
586         // obviously you can see I don't really care about memory 
587         // efficiency. If I did I would probe back through the stack
588         // and get it that way. But that's really disgusting.
589         for (i = 0; i < 256; i++) {
590                 idts[i].cs = 0;
591                 codeptr = (char *)4096 + i * codesize;
592                 idts[i].offset = (unsigned)codeptr;
593                 memcpy(codeptr, &idthandle, codesize);
594                 intbyte = codeptr + 3;
595                 *intbyte = i;
596         }
597
598         // fixed entry points
599
600         // VGA BIOSes tend to hardcode f000:f065 as the previous handler of
601         // int10. 
602         // calling convention here is the same as INTs, we can reuse
603         // the int entry code.
604         codeptr = (char *)0xff065;
605         memcpy(codeptr, &idthandle, codesize);
606         intbyte = codeptr + 3;
607         *intbyte = 0x42;        /* int42 is the relocated int10 */
608 /*
609  Fixed entry points
610   VBIOS will call f000:f859 instead of sending int15.
611  calling convertion here is the same as INTs, we can reuse the int entry code.
612 */
613         codeptr = (char *)0xff859;
614         memcpy(codeptr, &idthandle, codesize);
615         intbyte = codeptr + 3;
616         *intbyte = 0x15;
617
618         /* debug handler - useful to set a programmable delay between instructions if the
619            TF bit is set upon call to real mode */
620         idts[1].cs = 0;
621         idts[1].offset = 16384;
622         memcpy(16384, &debughandle, &end_debughandle - &debughandle);
623
624 }
625
626 enum {
627         CHECK = 0xb001,
628         FINDDEV = 0xb102,
629         READCONFBYTE = 0xb108,
630         READCONFWORD = 0xb109,
631         READCONFDWORD = 0xb10a,
632         WRITECONFBYTE = 0xb10b,
633         WRITECONFWORD = 0xb10c,
634         WRITECONFDWORD = 0xb10d
635 };
636
637 // errors go in AH. Just set these up so that word assigns
638 // will work. KISS. 
639 enum {
640         PCIBIOS_NODEV = 0x8600,
641         PCIBIOS_BADREG = 0x8700
642 };
643
644 int
645 pcibios(unsigned long *pedi, unsigned long *pesi, unsigned long *pebp,
646         unsigned long *pesp, unsigned long *pebx, unsigned long *pedx,
647         unsigned long *pecx, unsigned long *peax, unsigned long *pflags)
648 {
649         unsigned long edi = *pedi;
650         unsigned long esi = *pesi;
651         unsigned long ebp = *pebp;
652         unsigned long esp = *pesp;
653         unsigned long ebx = *pebx;
654         unsigned long edx = *pedx;
655         unsigned long ecx = *pecx;
656         unsigned long eax = *peax;
657         unsigned long flags = *pflags;
658         unsigned short func = (unsigned short)eax;
659         int retval = 0;
660         unsigned short devid, vendorid, devfn;
661         short devindex;         /* Use short to get rid of garbage in upper half of 32-bit register */
662         unsigned char bus;
663         device_t dev;
664
665         switch (func) {
666         case CHECK:
667                 *pedx = 0x4350;
668                 *pecx = 0x2049;
669                 retval = 0;
670                 break;
671         case FINDDEV:
672                 {
673                         devid = *pecx;
674                         vendorid = *pedx;
675                         devindex = *pesi;
676                         dev = 0;
677                         while ((dev = dev_find_device(vendorid, devid, dev))) {
678                                 if (devindex <= 0)
679                                         break;
680                                 devindex--;
681                         }
682                         if (dev) {
683                                 unsigned short busdevfn;
684                                 *peax = 0;
685                                 // busnum is an unsigned char;
686                                 // devfn is an int, so we mask it off. 
687                                 busdevfn = (dev->bus->secondary << 8)
688                                     | (dev->path.pci.devfn & 0xff);
689                                 printk(BIOS_DEBUG, "0x%x: return 0x%x\n", func,
690                                              busdevfn);
691                                 *pebx = busdevfn;
692                                 retval = 0;
693                         } else {
694                                 *peax = PCIBIOS_NODEV;
695                                 retval = -1;
696                         }
697                 }
698                 break;
699         case READCONFDWORD:
700         case READCONFWORD:
701         case READCONFBYTE:
702         case WRITECONFDWORD:
703         case WRITECONFWORD:
704         case WRITECONFBYTE:
705                 {
706                         unsigned long dword;
707                         unsigned short word;
708                         unsigned char byte;
709                         unsigned char reg;
710
711                         devfn = *pebx & 0xff;
712                         bus = *pebx >> 8;
713                         reg = *pedi;
714                         dev = dev_find_slot(bus, devfn);
715                         if (!dev) {
716                                 printk(BIOS_DEBUG, "0x%x: BAD DEVICE bus %d devfn 0x%x\n",
717                                      func, bus, devfn);
718                                 // idiots. the pcibios guys assumed you'd never pass a bad bus/devfn!
719                                 *peax = PCIBIOS_BADREG;
720                                 retval = -1;
721                         }
722                         switch (func) {
723                         case READCONFBYTE:
724                                 byte = pci_read_config8(dev, reg);
725                                 *pecx = byte;
726                                 break;
727                         case READCONFWORD:
728                                 word = pci_read_config16(dev, reg);
729                                 *pecx = word;
730                                 break;
731                         case READCONFDWORD:
732                                 dword = pci_read_config32(dev, reg);
733                                 *pecx = dword;
734                                 break;
735                         case WRITECONFBYTE:
736                                 byte = *pecx;
737                                 pci_write_config8(dev, reg, byte);
738                                 break;
739                         case WRITECONFWORD:
740                                 word = *pecx;
741                                 pci_write_config16(dev, reg, word);
742                                 break;
743                         case WRITECONFDWORD:
744                                 dword = *pecx;
745                                 pci_write_config32(dev, reg, dword);
746                                 break;
747                         }
748
749                         if (retval)
750                                 retval = PCIBIOS_BADREG;
751                         printk(BIOS_DEBUG, "0x%x: bus %d devfn 0x%x reg 0x%x val 0x%lx\n",
752                              func, bus, devfn, reg, *pecx);
753                         *peax = 0;
754                         retval = 0;
755                 }
756                 break;
757         default:
758                 printk(BIOS_ERR, "UNSUPPORTED PCIBIOS FUNCTION 0x%x\n", func);
759                 break;
760         }
761
762         return retval;
763 }
764
765 /* return value of int0x15(int21)
766 AH  AL                  Completion status 
767 ??  5Fh                 Function call supported 
768 ??  !=5Fh       Function not supported 
769 00  5Fh                 Function call successful 
770 01  5Fh                 Function call failed 
771 */
772 int handleint21(unsigned long *edi, unsigned long *esi, unsigned long *ebp,
773                 unsigned long *esp, unsigned long *ebx, unsigned long *edx,
774                 unsigned long *ecx, unsigned long *eax, unsigned long *flags)
775 {
776         int res = -1;
777         switch (*eax & 0xffff) {
778         case 0x5f19:
779                 *eax = 0x5f;
780                 *ecx = 0x3;
781                 res = 0;
782                 break;
783         case 0x5f18:
784                 {
785                         /*
786                            BL  
787                            Bit[7:4] 
788                            Memory Data Rate 
789                            0000: 66MHz 
790                            0001: 100MHz 
791                            0010: 133MHz 
792                            0011: 200MHz ( DDR200 ) 
793                            0100: 266MHz ( DDR266 ) 
794                            0101: 333MHz ( DDR333 ) 
795                            0110: 400MHz ( DDR400 ) 
796                            0111: 533MHz ( DDR I/II 533 
797                            1000: 667MHz ( DDR I/II 667)
798                            Bit[3:0]  
799                            N:  Frame Buffer Size 2^N  MB 
800                          */
801                         u8 i;
802                         device_t dev;
803                         dev = dev_find_slot(0, PCI_DEVFN(0, 3));
804                         i = pci_read_config8(dev, 0xa1);
805                         i = (i & 0x70);
806                         i = i >> 4;
807                         if (i == 0) {
808                                 *eax = 0x00;    //not support 5f18
809                                 break;
810                         }
811                         i = i + 2;
812                         *ebx = (u32) i;
813                         i = pci_read_config8(dev, 0x90);
814                         i = (i & 0x07);
815                         i = i + 3;
816                         i = i << 4;
817                         *ebx = (*ebx) + ((u32) i);
818                         *eax = 0x5f;
819                         res = 0;
820                         break;
821                 }
822         case 0x5f00:
823                 *eax = 0x005f;
824                 res = 0;
825                 break;
826         case 0x5f01:
827                 *eax = 0x5f;
828                 *ecx = (*ecx & 0xffffff00) | 2; // panel type =  2 = 1024 * 768
829                 res = 0;
830                 break;
831         case 0x5f02:
832                 *eax = 0x5f;
833                 *ebx = (*ebx & 0xffff0000) | 2;
834                 *ecx = (*ecx & 0xffff0000) | 0x401;     // PAL + crt only 
835                 *edx = (*edx & 0xffff0000) | 0; // TV Layout - default
836                 res = 0;
837                 break;
838         case 0x5f0f:
839                 *eax = 0x005f;
840                 res = 0;
841                 break;
842         default:
843                 *eax = 0;
844                 break;
845         }
846         return res;
847 }