video_bios.c 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219
  1. /*
  2. * (C) Copyright 2002
  3. * Daniel Engström, Omicron Ceti AB, daniel@omicron.se
  4. *
  5. * See file CREDITS for list of people who contributed to this
  6. * project.
  7. *
  8. * This program is free software; you can redistribute it and/or
  9. * modify it under the terms of the GNU General Public License as
  10. * published by the Free Software Foundation; either version 2 of
  11. * the License, or (at your option) any later version.
  12. *
  13. * This program is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU General Public License
  19. * along with this program; if not, write to the Free Software
  20. * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  21. * MA 02111-1307 USA
  22. */
  23. #include <common.h>
  24. #include <pci.h>
  25. #include <malloc.h>
  26. #include <asm/ptrace.h>
  27. #include <asm/realmode.h>
  28. #include <asm/io.h>
  29. #include <asm/pci.h>
  30. #undef PCI_BIOS_DEBUG
  31. #undef VGA_BIOS_DEBUG
  32. #ifdef VGA_BIOS_DEBUG
  33. #define PRINTF(fmt,args...) printf (fmt ,##args)
  34. #else
  35. #define PRINTF(fmt,args...)
  36. #endif
  37. #ifdef CONFIG_PCI
  38. #ifdef PCI_BIOS_DEBUG
  39. #define RELOC_16(seg, off) *(u32*)(seg << 4 | (u32)&off)
  40. extern u32 num_pci_bios_present;
  41. extern u32 num_pci_bios_find_device;
  42. extern u32 num_pci_bios_find_class;
  43. extern u32 num_pci_bios_generate_special_cycle;
  44. extern u32 num_pci_bios_read_cfg_byte;
  45. extern u32 num_pci_bios_read_cfg_word;
  46. extern u32 num_pci_bios_read_cfg_dword;
  47. extern u32 num_pci_bios_write_cfg_byte;
  48. extern u32 num_pci_bios_write_cfg_word;
  49. extern u32 num_pci_bios_write_cfg_dword;
  50. extern u32 num_pci_bios_get_irq_routing;
  51. extern u32 num_pci_bios_set_irq;
  52. extern u32 num_pci_bios_unknown_function;
  53. void print_bios_bios_stat(void)
  54. {
  55. printf("16 bit functions:\n");
  56. printf("pci_bios_present: %d\n", RELOC_16(0xf000, num_pci_bios_present));
  57. printf("pci_bios_find_device: %d\n", RELOC_16(0xf000, num_pci_bios_find_device));
  58. printf("pci_bios_find_class: %d\n", RELOC_16(0xf000, num_pci_bios_find_class));
  59. printf("pci_bios_generate_special_cycle: %d\n", RELOC_16(0xf000, num_pci_bios_generate_special_cycle));
  60. printf("pci_bios_read_cfg_byte: %d\n", RELOC_16(0xf000, num_pci_bios_read_cfg_byte));
  61. printf("pci_bios_read_cfg_word: %d\n", RELOC_16(0xf000, num_pci_bios_read_cfg_word));
  62. printf("pci_bios_read_cfg_dword: %d\n", RELOC_16(0xf000, num_pci_bios_read_cfg_dword));
  63. printf("pci_bios_write_cfg_byte: %d\n", RELOC_16(0xf000, num_pci_bios_write_cfg_byte));
  64. printf("pci_bios_write_cfg_word: %d\n", RELOC_16(0xf000, num_pci_bios_write_cfg_word));
  65. printf("pci_bios_write_cfg_dword: %d\n", RELOC_16(0xf000, num_pci_bios_write_cfg_dword));
  66. printf("pci_bios_get_irq_routing: %d\n", RELOC_16(0xf000, num_pci_bios_get_irq_routing));
  67. printf("pci_bios_set_irq: %d\n", RELOC_16(0xf000, num_pci_bios_set_irq));
  68. printf("pci_bios_unknown_function: %d\n", RELOC_16(0xf000, num_pci_bios_unknown_function));
  69. }
  70. #endif
  71. #define PCI_CLASS_VIDEO 3
  72. #define PCI_CLASS_VIDEO_STD 0
  73. #define PCI_CLASS_VIDEO_PROG_IF_VGA 0
  74. static u32 probe_pci_video(void)
  75. {
  76. pci_dev_t devbusfn;
  77. if ((devbusfn = pci_find_class(PCI_CLASS_VIDEO,
  78. PCI_CLASS_VIDEO_STD,
  79. PCI_CLASS_VIDEO_PROG_IF_VGA, 0)) != -1) {
  80. u32 old;
  81. u32 addr;
  82. /* PCI video device detected */
  83. printf("Found PCI VGA device at %02x.%02x.%x\n",
  84. PCI_BUS(devbusfn), PCI_DEV(devbusfn), PCI_FUNC(devbusfn));
  85. /* Enable I/O decoding as well, PCI viudeo boards
  86. * support I/O accesses, but they provide no
  87. * bar register for this since the ports are fixed.
  88. */
  89. pci_write_config_word(devbusfn, PCI_COMMAND, PCI_COMMAND_MEMORY | PCI_COMMAND_IO | PCI_COMMAND_MASTER);
  90. /* Test the ROM decoder, do the device support a rom? */
  91. pci_read_config_dword(devbusfn, PCI_ROM_ADDRESS, &old);
  92. pci_write_config_dword(devbusfn, PCI_ROM_ADDRESS, PCI_ROM_ADDRESS_MASK);
  93. pci_read_config_dword(devbusfn, PCI_ROM_ADDRESS, &addr);
  94. pci_write_config_dword(devbusfn, PCI_ROM_ADDRESS, old);
  95. if (!addr) {
  96. printf("PCI VGA have no ROM?\n");
  97. return 0;
  98. }
  99. /* device have a rom */
  100. if (pci_shadow_rom(devbusfn, (void*)0xc0000)) {
  101. printf("Shadowing of PCI VGA BIOS failed\n");
  102. return 0;
  103. }
  104. /* Now enable lagacy VGA port access */
  105. if (pci_enable_legacy_video_ports(pci_bus_to_hose(PCI_BUS(devbusfn)))) {
  106. printf("PCI VGA enable failed\n");
  107. return 0;
  108. }
  109. /* return the pci device info, that we'll need later */
  110. return PCI_BUS(devbusfn) << 8 |
  111. PCI_DEV(devbusfn) << 3 | (PCI_FUNC(devbusfn)&7);
  112. }
  113. return 0;
  114. }
  115. #endif
  116. static int probe_isa_video(void)
  117. {
  118. u32 ptr;
  119. char *buf;
  120. if (0 == (ptr = isa_map_rom(0xc0000, 0x8000))) {
  121. return -1;
  122. }
  123. if (NULL == (buf=malloc(0x8000))) {
  124. isa_unmap_rom(ptr);
  125. return -1;
  126. }
  127. if (readw(ptr) != 0xaa55) {
  128. free(buf);
  129. isa_unmap_rom(ptr);
  130. return -1;
  131. }
  132. /* shadow the rom */
  133. memcpy(buf, (void*)ptr, 0x8000);
  134. isa_unmap_rom(ptr);
  135. memcpy((void*)0xc0000, buf, 0x8000);
  136. free(buf);
  137. return 0;
  138. }
  139. int video_bios_init(void)
  140. {
  141. struct pt_regs regs;
  142. /* clear the video bios area in case we warmbooted */
  143. memset((void*)0xc0000, 0, 0x8000);
  144. memset(&regs, 0, sizeof(struct pt_regs));
  145. if (probe_isa_video()) {
  146. /* No ISA board found, try the PCI bus */
  147. regs.eax = probe_pci_video();
  148. }
  149. /* Did we succeed in mapping any video bios */
  150. if (readw(0xc0000) == 0xaa55) {
  151. int size;
  152. int i;
  153. u8 sum;
  154. PRINTF("Found video bios signature\n");
  155. size = 512*readb(0xc0002);
  156. PRINTF("size %d\n", size);
  157. sum=0;
  158. for (i=0;i<size;i++) {
  159. sum += readb(0xc0000 + i);
  160. }
  161. PRINTF("Checksum is %sOK\n",sum?"NOT ":"");
  162. if (sum) {
  163. return 1;
  164. }
  165. /* some video bioses (ATI Mach64) seem to think that
  166. * the original int 10 handler is always at
  167. * 0xf000:0xf065 , place an iret instruction there
  168. */
  169. writeb(0xcf, 0xff065);
  170. regs.esp = 0x8000;
  171. regs.xss = 0x2000;
  172. enter_realmode(0xc000, 3, &regs, &regs);
  173. PRINTF("INT 0x10 vector after: %04x:%04x\n",
  174. readw(0x42), readw(0x40));
  175. PRINTF("BIOS returned %scarry\n", regs.eflags & 1?"":"NOT ");
  176. #ifdef PCI_BIOS_DEBUG
  177. print_bios_bios_stat();
  178. #endif
  179. return (regs.eflags & 1);
  180. }
  181. return 1;
  182. }