vreset.c
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:18k
源码类别:

Linux/Unix编程

开发平台:

Unix_Linux

  1. /*
  2.  * BK Id: SCCS/s.vreset.c 1.13 01/11/02 10:46:08 trini
  3.  */
  4. /*
  5.  * vreset.c
  6.  *
  7.  * Initialize the VGA control registers to 80x25 text mode.
  8.  *
  9.  * Adapted from a program by:
  10.  *                                      Steve Sellgren
  11.  *                                      San Francisco Indigo Company
  12.  *                                      sfindigo!sellgren@uunet.uu.net
  13.  *
  14.  * Original concept by:
  15.  *                                      Gary Thomas <gdt@linuxppc.org>
  16.  * Adapted for Moto boxes by:
  17.  *                                      Pat Kane & Mark Scott, 1996
  18.  * Adapted for IBM portables by:
  19.  *                                      Takeshi Ishimoto
  20.  * Multi-console support:
  21.  *                                      Terje Malmedal <terje.malmedal@usit.uio.no>
  22.  */
  23. #include "iso_font.h"
  24. #include "nonstdio.h"
  25. extern char *vidmem;
  26. extern int lines, cols;
  27. struct VaRegs;
  28. /*
  29.  * VGA Register
  30.  */
  31. struct VgaRegs
  32. {
  33. unsigned short io_port;
  34. unsigned char  io_index;
  35. unsigned char  io_value;
  36. };
  37. void unlockVideo(int slot);
  38. void setTextRegs(struct VgaRegs *svp);
  39. void setTextCLUT(int shift);
  40. void clearVideoMemory(void);
  41. void loadFont(unsigned char *ISA_mem);
  42. static void mdelay(int ms)
  43. {
  44. for (; ms > 0; --ms)
  45. udelay(1000);
  46. }
  47. /*
  48.  * Default console text mode registers  used to reset
  49.  * graphics adapter.
  50.  */
  51. #define NREGS 54
  52. #define ENDMK  0xFFFF  /* End marker */
  53. #define S3Vendor 0x5333
  54. #define CirrusVendor    0x1013
  55. #define DiamondVendor   0x100E
  56. #define MatroxVendor    0x102B
  57. #define ParadiseVendor  0x101C
  58. struct VgaRegs GenVgaTextRegs[NREGS+1] = {
  59. /* port index value  */
  60. /* SR Regs */
  61. { 0x3c4, 0x1, 0x0 },
  62. { 0x3c4, 0x2, 0x3 },
  63. { 0x3c4, 0x3, 0x0 },
  64. { 0x3c4, 0x4, 0x2 },
  65.  /* CR Regs */
  66. { 0x3d4, 0x0, 0x5f },
  67. { 0x3d4, 0x1, 0x4f },
  68. { 0x3d4, 0x2, 0x50 },
  69. { 0x3d4, 0x3, 0x82 },
  70. { 0x3d4, 0x4, 0x55 },
  71. { 0x3d4, 0x5, 0x81 },
  72. { 0x3d4, 0x6, 0xbf },
  73. { 0x3d4, 0x7, 0x1f },
  74. { 0x3d4, 0x8, 0x00 },
  75. { 0x3d4, 0x9, 0x4f },
  76. { 0x3d4, 0xa, 0x0d },
  77. { 0x3d4, 0xb, 0x0e },
  78. { 0x3d4, 0xc, 0x00 },
  79. { 0x3d4, 0xd, 0x00 },
  80. { 0x3d4, 0xe, 0x00 },
  81. { 0x3d4, 0xf, 0x00 },
  82. { 0x3d4, 0x10, 0x9c },
  83. { 0x3d4, 0x11, 0x8e },
  84. { 0x3d4, 0x12, 0x8f },
  85. { 0x3d4, 0x13, 0x28 },
  86. { 0x3d4, 0x14, 0x1f },
  87. { 0x3d4, 0x15, 0x96 },
  88. { 0x3d4, 0x16, 0xb9 },
  89. { 0x3d4, 0x17, 0xa3 },
  90.  /* GR Regs */
  91. { 0x3ce, 0x0, 0x0 },
  92. { 0x3ce, 0x1, 0x0 },
  93. { 0x3ce, 0x2, 0x0 },
  94. { 0x3ce, 0x3, 0x0 },
  95. { 0x3ce, 0x4, 0x0 },
  96. { 0x3ce, 0x5, 0x10 },
  97. { 0x3ce, 0x6, 0xe },
  98. { 0x3ce, 0x7, 0x0 },
  99. { 0x3ce, 0x8, 0xff },
  100. { ENDMK }
  101. };
  102. struct RGBColors
  103. {
  104.   unsigned char r, g, b;
  105. };
  106. /*
  107.  * Default console text mode color table.
  108.  * These values were obtained by booting Linux with
  109.  * text mode firmware & then dumping the registers.
  110.  */
  111. struct RGBColors TextCLUT[256] =
  112. {
  113. /* red green blue  */
  114. { 0x0, 0x0, 0x0 },
  115. { 0x0, 0x0, 0x2a },
  116. { 0x0, 0x2a, 0x0 },
  117. { 0x0, 0x2a, 0x2a },
  118. { 0x2a, 0x0, 0x0 },
  119. { 0x2a, 0x0, 0x2a },
  120. { 0x2a, 0x2a, 0x0 },
  121. { 0x2a, 0x2a, 0x2a },
  122. { 0x0, 0x0, 0x15 },
  123. { 0x0, 0x0, 0x3f },
  124. { 0x0, 0x2a, 0x15 },
  125. { 0x0, 0x2a, 0x3f },
  126. { 0x2a, 0x0, 0x15 },
  127. { 0x2a, 0x0, 0x3f },
  128. { 0x2a, 0x2a, 0x15 },
  129. { 0x2a, 0x2a, 0x3f },
  130. { 0x0, 0x15, 0x0 },
  131. { 0x0, 0x15, 0x2a },
  132. { 0x0, 0x3f, 0x0 },
  133. { 0x0, 0x3f, 0x2a },
  134. { 0x2a, 0x15, 0x0 },
  135. { 0x2a, 0x15, 0x2a },
  136. { 0x2a, 0x3f, 0x0 },
  137. { 0x2a, 0x3f, 0x2a },
  138. { 0x0, 0x15, 0x15 },
  139. { 0x0, 0x15, 0x3f },
  140. { 0x0, 0x3f, 0x15 },
  141. { 0x0, 0x3f, 0x3f },
  142. { 0x2a, 0x15, 0x15 },
  143. { 0x2a, 0x15, 0x3f },
  144. { 0x2a, 0x3f, 0x15 },
  145. { 0x2a, 0x3f, 0x3f },
  146. { 0x15, 0x0, 0x0 },
  147. { 0x15, 0x0, 0x2a },
  148. { 0x15, 0x2a, 0x0 },
  149. { 0x15, 0x2a, 0x2a },
  150. { 0x3f, 0x0, 0x0 },
  151. { 0x3f, 0x0, 0x2a },
  152. { 0x3f, 0x2a, 0x0 },
  153. { 0x3f, 0x2a, 0x2a },
  154. { 0x15, 0x0, 0x15 },
  155. { 0x15, 0x0, 0x3f },
  156. { 0x15, 0x2a, 0x15 },
  157. { 0x15, 0x2a, 0x3f },
  158. { 0x3f, 0x0, 0x15 },
  159. { 0x3f, 0x0, 0x3f },
  160. { 0x3f, 0x2a, 0x15 },
  161. { 0x3f, 0x2a, 0x3f },
  162. { 0x15, 0x15, 0x0 },
  163. { 0x15, 0x15, 0x2a },
  164. { 0x15, 0x3f, 0x0 },
  165. { 0x15, 0x3f, 0x2a },
  166. { 0x3f, 0x15, 0x0 },
  167. { 0x3f, 0x15, 0x2a },
  168. { 0x3f, 0x3f, 0x0 },
  169. { 0x3f, 0x3f, 0x2a },
  170. { 0x15, 0x15, 0x15 },
  171. { 0x15, 0x15, 0x3f },
  172. { 0x15, 0x3f, 0x15 },
  173. { 0x15, 0x3f, 0x3f },
  174. { 0x3f, 0x15, 0x15 },
  175. { 0x3f, 0x15, 0x3f },
  176. { 0x3f, 0x3f, 0x15 },
  177. { 0x3f, 0x3f, 0x3f },
  178. { 0x39, 0xc, 0x5 },
  179. { 0x15, 0x2c, 0xf },
  180. { 0x26, 0x10, 0x3d },
  181. { 0x29, 0x29, 0x38 },
  182. { 0x4, 0x1a, 0xe },
  183. { 0x2, 0x1e, 0x3a },
  184. { 0x3c, 0x25, 0x33 },
  185. { 0x3c, 0xc, 0x2c },
  186. { 0x3f, 0x3, 0x2b },
  187. { 0x1c, 0x9, 0x13 },
  188. { 0x25, 0x2a, 0x35 },
  189. { 0x1e, 0xa, 0x38 },
  190. { 0x24, 0x8, 0x3 },
  191. { 0x3, 0xe, 0x36 },
  192. { 0xc, 0x6, 0x2a },
  193. { 0x26, 0x3, 0x32 },
  194. { 0x5, 0x2f, 0x33 },
  195. { 0x3c, 0x35, 0x2f },
  196. { 0x2d, 0x26, 0x3e },
  197. { 0xd, 0xa, 0x10 },
  198. { 0x25, 0x3c, 0x11 },
  199. { 0xd, 0x4, 0x2e },
  200. { 0x5, 0x19, 0x3e },
  201. { 0xc, 0x13, 0x34 },
  202. { 0x2b, 0x6, 0x24 },
  203. { 0x4, 0x3, 0xd },
  204. { 0x2f, 0x3c, 0xc },
  205. { 0x2a, 0x37, 0x1f },
  206. { 0xf, 0x12, 0x38 },
  207. { 0x38, 0xe, 0x2a },
  208. { 0x12, 0x2f, 0x19 },
  209. { 0x29, 0x2e, 0x31 },
  210. { 0x25, 0x13, 0x3e },
  211. { 0x33, 0x3e, 0x33 },
  212. { 0x1d, 0x2c, 0x25 },
  213. { 0x15, 0x15, 0x5 },
  214. { 0x32, 0x25, 0x39 },
  215. { 0x1a, 0x7, 0x1f },
  216. { 0x13, 0xe, 0x1d },
  217. { 0x36, 0x17, 0x34 },
  218. { 0xf, 0x15, 0x23 },
  219. { 0x2, 0x35, 0xd },
  220. { 0x15, 0x3f, 0xc },
  221. { 0x14, 0x2f, 0xf },
  222. { 0x19, 0x21, 0x3e },
  223. { 0x27, 0x11, 0x2f },
  224. { 0x38, 0x3f, 0x3c },
  225. { 0x36, 0x2d, 0x15 },
  226. { 0x16, 0x17, 0x2 },
  227. { 0x1, 0xa, 0x3d },
  228. { 0x1b, 0x11, 0x3f },
  229. { 0x21, 0x3c, 0xd },
  230. { 0x1a, 0x39, 0x3d },
  231. { 0x8, 0xe, 0xe },
  232. { 0x22, 0x21, 0x23 },
  233. { 0x1e, 0x30, 0x5 },
  234. { 0x1f, 0x22, 0x3d },
  235. { 0x1e, 0x2f, 0xa },
  236. { 0x0, 0x1c, 0xe },
  237. { 0x0, 0x1c, 0x15 },
  238. { 0x0, 0x1c, 0x1c },
  239. { 0x0, 0x15, 0x1c },
  240. { 0x0, 0xe, 0x1c },
  241. { 0x0, 0x7, 0x1c },
  242. { 0xe, 0xe, 0x1c },
  243. { 0x11, 0xe, 0x1c },
  244. { 0x15, 0xe, 0x1c },
  245. { 0x18, 0xe, 0x1c },
  246. { 0x1c, 0xe, 0x1c },
  247. { 0x1c, 0xe, 0x18 },
  248. { 0x1c, 0xe, 0x15 },
  249. { 0x1c, 0xe, 0x11 },
  250. { 0x1c, 0xe, 0xe },
  251. { 0x1c, 0x11, 0xe },
  252. { 0x1c, 0x15, 0xe },
  253. { 0x1c, 0x18, 0xe },
  254. { 0x1c, 0x1c, 0xe },
  255. { 0x18, 0x1c, 0xe },
  256. { 0x15, 0x1c, 0xe },
  257. { 0x11, 0x1c, 0xe },
  258. { 0xe, 0x1c, 0xe },
  259. { 0xe, 0x1c, 0x11 },
  260. { 0xe, 0x1c, 0x15 },
  261. { 0xe, 0x1c, 0x18 },
  262. { 0xe, 0x1c, 0x1c },
  263. { 0xe, 0x18, 0x1c },
  264. { 0xe, 0x15, 0x1c },
  265. { 0xe, 0x11, 0x1c },
  266. { 0x14, 0x14, 0x1c },
  267. { 0x16, 0x14, 0x1c },
  268. { 0x18, 0x14, 0x1c },
  269. { 0x1a, 0x14, 0x1c },
  270. { 0x1c, 0x14, 0x1c },
  271. { 0x1c, 0x14, 0x1a },
  272. { 0x1c, 0x14, 0x18 },
  273. { 0x1c, 0x14, 0x16 },
  274. { 0x1c, 0x14, 0x14 },
  275. { 0x1c, 0x16, 0x14 },
  276. { 0x1c, 0x18, 0x14 },
  277. { 0x1c, 0x1a, 0x14 },
  278. { 0x1c, 0x1c, 0x14 },
  279. { 0x1a, 0x1c, 0x14 },
  280. { 0x18, 0x1c, 0x14 },
  281. { 0x16, 0x1c, 0x14 },
  282. { 0x14, 0x1c, 0x14 },
  283. { 0x14, 0x1c, 0x16 },
  284. { 0x14, 0x1c, 0x18 },
  285. { 0x14, 0x1c, 0x1a },
  286. { 0x14, 0x1c, 0x1c },
  287. { 0x14, 0x1a, 0x1c },
  288. { 0x14, 0x18, 0x1c },
  289. { 0x14, 0x16, 0x1c },
  290. { 0x0, 0x0, 0x10 },
  291. { 0x4, 0x0, 0x10 },
  292. { 0x8, 0x0, 0x10 },
  293. { 0xc, 0x0, 0x10 },
  294. { 0x10, 0x0, 0x10 },
  295. { 0x10, 0x0, 0xc },
  296. { 0x10, 0x0, 0x8 },
  297. { 0x10, 0x0, 0x4 },
  298. { 0x10, 0x0, 0x0 },
  299. { 0x10, 0x4, 0x0 },
  300. { 0x10, 0x8, 0x0 },
  301. { 0x10, 0xc, 0x0 },
  302. { 0x10, 0x10, 0x0 },
  303. { 0xc, 0x10, 0x0 },
  304. { 0x8, 0x10, 0x0 },
  305. { 0x4, 0x10, 0x0 },
  306. { 0x0, 0x10, 0x0 },
  307. { 0x0, 0x10, 0x4 },
  308. { 0x0, 0x10, 0x8 },
  309. { 0x0, 0x10, 0xc },
  310. { 0x0, 0x10, 0x10 },
  311. { 0x0, 0xc, 0x10 },
  312. { 0x0, 0x8, 0x10 },
  313. { 0x0, 0x4, 0x10 },
  314. { 0x8, 0x8, 0x10 },
  315. { 0xa, 0x8, 0x10 },
  316. { 0xc, 0x8, 0x10 },
  317. { 0xe, 0x8, 0x10 },
  318. { 0x10, 0x8, 0x10 },
  319. { 0x10, 0x8, 0xe },
  320. { 0x10, 0x8, 0xc },
  321. { 0x10, 0x8, 0xa },
  322. { 0x10, 0x8, 0x8 },
  323. { 0x10, 0xa, 0x8 },
  324. { 0x10, 0xc, 0x8 },
  325. { 0x10, 0xe, 0x8 },
  326. { 0x10, 0x10, 0x8 },
  327. { 0xe, 0x10, 0x8 },
  328. { 0xc, 0x10, 0x8 },
  329. { 0xa, 0x10, 0x8 },
  330. { 0x8, 0x10, 0x8 },
  331. { 0x8, 0x10, 0xa },
  332. { 0x8, 0x10, 0xc },
  333. { 0x8, 0x10, 0xe },
  334. { 0x8, 0x10, 0x10 },
  335. { 0x8, 0xe, 0x10 },
  336. { 0x8, 0xc, 0x10 },
  337. { 0x8, 0xa, 0x10 },
  338. { 0xb, 0xb, 0x10 },
  339. { 0xc, 0xb, 0x10 },
  340. { 0xd, 0xb, 0x10 },
  341. { 0xf, 0xb, 0x10 },
  342. { 0x10, 0xb, 0x10 },
  343. { 0x10, 0xb, 0xf },
  344. { 0x10, 0xb, 0xd },
  345. { 0x10, 0xb, 0xc },
  346. { 0x10, 0xb, 0xb },
  347. { 0x10, 0xc, 0xb },
  348. { 0x10, 0xd, 0xb },
  349. { 0x10, 0xf, 0xb },
  350. { 0x10, 0x10, 0xb },
  351. { 0xf, 0x10, 0xb },
  352. { 0xd, 0x10, 0xb },
  353. { 0xc, 0x10, 0xb },
  354. { 0xb, 0x10, 0xb },
  355. { 0xb, 0x10, 0xc },
  356. { 0xb, 0x10, 0xd },
  357. { 0xb, 0x10, 0xf },
  358. { 0xb, 0x10, 0x10 },
  359. { 0xb, 0xf, 0x10 },
  360. { 0xb, 0xd, 0x10 },
  361. { 0xb, 0xc, 0x10 },
  362. { 0x0, 0x0, 0x0 },
  363. { 0x0, 0x0, 0x0 },
  364. { 0x0, 0x0, 0x0 },
  365. { 0x0, 0x0, 0x0 },
  366. { 0x0, 0x0, 0x0 },
  367. { 0x0, 0x0, 0x0 },
  368. { 0x0, 0x0, 0x0 }
  369. };
  370. unsigned char AC[21] = {
  371.     0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x14, 0x07,
  372.     0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F,
  373.     0x0C, 0x00, 0x0F, 0x08, 0x00};
  374. static int scanPCI(int start_slt);
  375. static int PCIVendor(int);
  376. #ifdef DEBUG
  377. static void printslots(void);
  378. #endif
  379. extern void puthex(unsigned long);
  380. extern void puts(const char *);
  381. static void unlockS3(void);
  382. static void inline
  383. outw(int port, unsigned short val)
  384. {
  385. outb(port, val >> 8);
  386. outb(port+1, val);
  387. }
  388. int
  389. vga_init(unsigned char *ISA_mem)
  390. {
  391. int slot;
  392. struct VgaRegs *VgaTextRegs;
  393. /* See if VGA already in TEXT mode - exit if so! */
  394. outb(0x3CE, 0x06);
  395. if ((inb(0x3CF) & 0x01) == 0){
  396. puts("VGA already in text moden");
  397. return 0;
  398. }
  399. /* If no VGA responding in text mode, then we have some work to do...
  400.  */
  401. slot = -1;
  402. while((slot = scanPCI(slot)) > -1) { /* find video card in use  */
  403. unlockVideo(slot);           /* enable I/O to card      */
  404. VgaTextRegs = GenVgaTextRegs;
  405. switch (PCIVendor(slot)) {
  406. default:
  407. break;
  408. case(S3Vendor):
  409. unlockS3();
  410. break;
  411. case(CirrusVendor):
  412. outw(0x3C4, 0x0612);       /* unlock ext regs */
  413. outw(0x3C4, 0x0700);       /* reset ext sequence mode */
  414. break;
  415. case(ParadiseVendor):                 /* IBM Portable 850 */
  416. outw(0x3ce, 0x0f05);      /* unlock pardise registers */
  417. outw(0x3c4, 0x0648);
  418. outw(0x3d4, 0x2985);
  419. outw(0x3d4, 0x34a6);
  420. outb(0x3ce, 0x0b);       /* disable linear addressing */
  421. outb(0x3cf, inb(0x3cf) & ~0x30);
  422. outw(0x3c4, 0x1400);
  423. outb(0x3ce, 0x0e);       /* disable 256 color mode */
  424. outb(0x3cf, inb(0x3cf) & ~0x01);
  425. outb(0xd00, 0xff);       /* enable auto-centering */
  426. if (!(inb(0xd01) & 0x03)) {
  427. outb(0x3d4, 0x33);
  428. outb(0x3d5, inb(0x3d5) & ~0x90);
  429. outb(0x3d4, 0x32);
  430. outb(0x3d5, inb(0x3d5) | 0x04);
  431. outw(0x3d4, 0x0250);
  432. outw(0x3d4, 0x07ba);
  433. outw(0x3d4, 0x0900);
  434. outw(0x3d4, 0x15e7);
  435. outw(0x3d4, 0x2a95);
  436. }
  437. outw(0x3d4, 0x34a0);
  438. break;
  439. #if 0 /* Untested - probably doesn't work */
  440. case(MatroxVendor):
  441. case(DiamondVendor):
  442. puts("VGA Chip Vendor ID: ");
  443. puthex(PCIVendor(slot));
  444. puts("n");
  445. mdelay(1000);
  446. #endif
  447. };
  448. outw(0x3C4, 0x0120);           /* disable video              */
  449. setTextRegs(VgaTextRegs);      /* initial register setup     */
  450. setTextCLUT(0);                /* load color lookup table    */
  451. loadFont(ISA_mem);             /* load font                  */
  452. setTextRegs(VgaTextRegs);      /* reload registers           */
  453. outw(0x3C4, 0x0100);           /* re-enable video            */
  454. clearVideoMemory();
  455. if (PCIVendor(slot) == S3Vendor) {
  456. outb(0x3c2, 0x63);                  /* MISC */
  457. } /* endif */
  458. #ifdef DEBUG
  459. printslots();
  460. mdelay(5000);
  461. #endif
  462. mdelay(1000); /* give time for the video monitor to come up */
  463.         }
  464. return (1);  /* 'CRT' I/O supported */
  465. }
  466. /*
  467.  * Write to VGA Attribute registers.
  468.  */
  469. void
  470. writeAttr(unsigned char index, unsigned char data, unsigned char videoOn)
  471. {
  472. unsigned char v;
  473. v = inb(0x3da);   /* reset attr. address toggle */
  474. if (videoOn)
  475. outb(0x3c0, (index & 0x1F) | 0x20);
  476. else
  477. outb(0x3c0, (index & 0x1F));
  478. outb(0x3c0, data);
  479. }
  480. void
  481. setTextRegs(struct VgaRegs *svp)
  482. {
  483. int i;
  484. /*
  485.  *  saved settings
  486.  */
  487. while( svp->io_port != ENDMK ) {
  488. outb(svp->io_port,   svp->io_index);
  489. outb(svp->io_port+1, svp->io_value);
  490. svp++;
  491. }
  492. outb(0x3c2, 0x67);  /* MISC */
  493. outb(0x3c6, 0xff);  /* MASK */
  494. for ( i = 0; i < 0x10; i++)
  495. writeAttr(i, AC[i], 0);  /* pallete */
  496. writeAttr(0x10, 0x0c, 0);    /* text mode */
  497. writeAttr(0x11, 0x00, 0);    /* overscan color (border) */
  498. writeAttr(0x12, 0x0f, 0);    /* plane enable */
  499. writeAttr(0x13, 0x08, 0);    /* pixel panning */
  500. writeAttr(0x14, 0x00, 1);    /* color select; video on  */
  501. }
  502. void
  503. setTextCLUT(int shift)
  504. {
  505. int i;
  506. outb(0x3C6, 0xFF);
  507. i = inb(0x3C7);
  508. outb(0x3C8, 0);
  509. i = inb(0x3C7);
  510. for ( i = 0; i < 256; i++) {
  511. outb(0x3C9, TextCLUT[i].r << shift);
  512. outb(0x3C9, TextCLUT[i].g << shift);
  513. outb(0x3C9, TextCLUT[i].b << shift);
  514. }
  515. }
  516. void
  517. loadFont(unsigned char *ISA_mem)
  518. {
  519. int i, j;
  520. unsigned char *font_page = (unsigned char *) &ISA_mem[0xA0000];
  521. outb(0x3C2, 0x67);
  522. /*
  523.  * Load font
  524.  */
  525. i = inb(0x3DA);  /* Reset Attr toggle */
  526. outb(0x3C0,0x30);
  527. outb(0x3C0, 0x01);      /* graphics mode */
  528. outw(0x3C4, 0x0001);    /* reset sequencer */
  529. outw(0x3C4, 0x0204);    /* write to plane 2 */
  530. outw(0x3C4, 0x0406);    /* enable plane graphics */
  531. outw(0x3C4, 0x0003);    /* reset sequencer */
  532. outw(0x3CE, 0x0402);    /* read plane 2 */
  533. outw(0x3CE, 0x0500);    /* write mode 0, read mode 0 */
  534. outw(0x3CE, 0x0605);    /* set graphics mode */
  535. for (i = 0;  i < sizeof(font);  i += 16) {
  536. for (j = 0;  j < 16;  j++) {
  537. __asm__ volatile("eieio");
  538. font_page[(2*i)+j] = font[i+j];
  539. }
  540. }
  541. }
  542. static void
  543. unlockS3(void)
  544. {
  545.         int s3_device_id;
  546. outw(0x3d4, 0x3848);
  547. outw(0x3d4, 0x39a5);
  548. outb(0x3d4, 0x2d);
  549. s3_device_id = inb(0x3d5) << 8;
  550. outb(0x3d4, 0x2e);
  551. s3_device_id |= inb(0x3d5);
  552. if (s3_device_id != 0x8812) {
  553. /* From the S3 manual */
  554. outb(0x46E8, 0x10);  /* Put into setup mode */
  555. outb(0x3C3, 0x10);
  556. outb(0x102, 0x01);   /* Enable registers */
  557. outb(0x46E8, 0x08);  /* Enable video */
  558. outb(0x3C3, 0x08);
  559. outb(0x4AE8, 0x00);
  560. #if 0
  561. outb(0x42E8, 0x80);  /* Reset graphics engine? */
  562. #endif
  563. outb(0x3D4, 0x38);  /* Unlock all registers */
  564. outb(0x3D5, 0x48);
  565. outb(0x3D4, 0x39);
  566. outb(0x3D5, 0xA5);
  567. outb(0x3D4, 0x40);
  568. outb(0x3D5, inb(0x3D5)|0x01);
  569. outb(0x3D4, 0x33);
  570. outb(0x3D5, inb(0x3D5)&~0x52);
  571. outb(0x3D4, 0x35);
  572. outb(0x3D5, inb(0x3D5)&~0x30);
  573. outb(0x3D4, 0x3A);
  574. outb(0x3D5, 0x00);
  575. outb(0x3D4, 0x53);
  576. outb(0x3D5, 0x00);
  577. outb(0x3D4, 0x31);
  578. outb(0x3D5, inb(0x3D5)&~0x4B);
  579. outb(0x3D4, 0x58);
  580. outb(0x3D5, 0);
  581. outb(0x3D4, 0x54);
  582. outb(0x3D5, 0x38);
  583. outb(0x3D4, 0x60);
  584. outb(0x3D5, 0x07);
  585. outb(0x3D4, 0x61);
  586. outb(0x3D5, 0x80);
  587. outb(0x3D4, 0x62);
  588. outb(0x3D5, 0xA1);
  589. outb(0x3D4, 0x69);  /* High order bits for cursor address */
  590. outb(0x3D5, 0);
  591. outb(0x3D4, 0x32);
  592. outb(0x3D5, inb(0x3D5)&~0x10);
  593. } else {
  594.                 outw(0x3c4, 0x0806);            /* IBM Portable 860 */
  595.                 outw(0x3c4, 0x1041);
  596.                 outw(0x3c4, 0x1128);
  597.                 outw(0x3d4, 0x4000);
  598.                 outw(0x3d4, 0x3100);
  599.                 outw(0x3d4, 0x3a05);
  600.                 outw(0x3d4, 0x6688);
  601.                 outw(0x3d4, 0x5800);            /* disable linear addressing */
  602.                 outw(0x3d4, 0x4500);            /* disable H/W cursor */
  603.                 outw(0x3c4, 0x5410);            /* enable auto-centering */
  604.                 outw(0x3c4, 0x561f);
  605.                 outw(0x3c4, 0x1b80);            /* lock DCLK selection */
  606.                 outw(0x3d4, 0x3900);            /* lock S3 registers */
  607.                 outw(0x3d4, 0x3800);
  608. } /* endif */
  609. }
  610. /*
  611.  * cursor() sets an offset (0-1999) into the 80x25 text area.
  612.  */
  613. void
  614. cursor(int x, int y)
  615. {
  616. int pos = (y*cols)+x;
  617. outb(0x3D4, 14);
  618. outb(0x3D5, pos >> 8);
  619. outb(0x3D4, 15);
  620. outb(0x3D5, pos);
  621. }
  622. void
  623. clearVideoMemory(void)
  624. {
  625. int i, j;
  626. for (i = 0;  i < lines;  i++) {
  627. for (j = 0;  j < cols;  j++) {
  628. vidmem[((i*cols)+j)*2] = 0x20; /* fill with space character */
  629. vidmem[((i*cols)+j)*2+1] = 0x07;  /* set bg & fg attributes */
  630. }
  631. }
  632. }
  633. /* ============ */
  634. #define NSLOTS 8
  635. #define NPCIREGS  5
  636. /*
  637.  should use devfunc number/indirect method to be totally safe on
  638.  all machines, this works for now on 3 slot Moto boxes
  639. */
  640. struct PCI_ConfigInfo {
  641.   unsigned long * config_addr;
  642.   unsigned long regs[NPCIREGS];
  643. } PCI_slots [NSLOTS] = {
  644.     { (unsigned long *)0x80808000, 0xDEADBEEF },   /* onboard */
  645.     { (unsigned long *)0x80800800, 0xDEADBEEF },   /* onboard */
  646.     { (unsigned long *)0x80801000, 0xDEADBEEF },   /* onboard */
  647.     { (unsigned long *)0x80802000, 0xDEADBEEF },   /* onboard */
  648.     { (unsigned long *)0x80804000, 0xDEADBEEF },   /* onboard */
  649.     { (unsigned long *)0x80810000, 0xDEADBEEF },   /* slot A/1 */
  650.     { (unsigned long *)0x80820000, 0xDEADBEEF },   /* slot B/2 */
  651.     { (unsigned long *)0x80840000, 0xDEADBEEF }    /* slot C/3 */
  652. };
  653. /*
  654.  * The following code modifies the PCI Command register
  655.  * to enable memory and I/O accesses.
  656.  */
  657. void
  658. unlockVideo(int slot)
  659. {
  660.        volatile unsigned char * ppci;
  661.         ppci =  (unsigned char * )PCI_slots[slot].config_addr;
  662. ppci[4] = 0x0003;         /* enable memory and I/O accesses */
  663. ppci[0x10] = 0x00000;     /* turn off memory mapping */
  664. ppci[0x11] = 0x00000;     /* mem_base = 0 */
  665. ppci[0x12] = 0x00000;
  666. ppci[0x13] = 0x00000;
  667. __asm__ volatile("eieio");
  668. outb(0x3d4, 0x11);
  669. outb(0x3d5, 0x0e);   /* unlock CR0-CR7 */
  670. }
  671. long
  672. SwapBytes(long lv)   /* turn little endian into big indian long */
  673. {
  674.     long t;
  675.     t  = (lv&0x000000FF) << 24;
  676.     t |= (lv&0x0000FF00) << 8;
  677.     t |= (lv&0x00FF0000) >> 8;
  678.     t |= (lv&0xFF000000) >> 24;
  679.     return(t);
  680. }
  681. #define DEVID   0
  682. #define CMD     1
  683. #define CLASS   2
  684. #define MEMBASE 4
  685. int
  686. scanPCI(int start_slt)
  687. {
  688. int slt, r;
  689. struct PCI_ConfigInfo *pslot;
  690. int theSlot = -1;
  691. int highVgaSlot = 0;
  692. for ( slt = start_slt + 1; slt < NSLOTS; slt++) {
  693. pslot = &PCI_slots[slt];
  694. for ( r = 0; r < NPCIREGS; r++) {
  695. pslot->regs[r] = SwapBytes ( pslot->config_addr[r] );
  696. }
  697. /* card in slot ? */
  698. if ( pslot->regs[DEVID] != 0xFFFFFFFF ) {
  699. /* VGA ? */
  700. if ( ((pslot->regs[CLASS] & 0xFFFFFF00) == 0x03000000) ||
  701.      ((pslot->regs[CLASS] & 0xFFFFFF00) == 0x00010000)) {
  702. highVgaSlot = slt;
  703. /* did firmware enable it ? */
  704. if ( (pslot->regs[CMD] & 0x03) ) {
  705. theSlot = slt;
  706. break;
  707. }
  708. }
  709. }
  710. }
  711. return ( theSlot );
  712. }
  713. /* return Vendor ID of card in the slot */
  714. static
  715. int PCIVendor(int slotnum) {
  716.  struct PCI_ConfigInfo *pslot;
  717.  pslot = &PCI_slots[slotnum];
  718. return (pslot->regs[DEVID] & 0xFFFF);
  719. }
  720. #ifdef DEBUG
  721. static
  722. void printslots(void)
  723. {
  724. int i;
  725. #if 0
  726. struct PCI_ConfigInfo *pslot;
  727. #endif
  728. for(i=0; i < NSLOTS; i++) {
  729. #if 0
  730. pslot = &PCI_slots[i];
  731. printf("Slot: %d, Addr: %x, Vendor: %08x, Class: %08xn",
  732.        i, pslot->config_addr, pslot->regs[0], pslot->regs[2]);
  733. #else
  734. puts("PCI Slot number: "); puthex(i);
  735. puts(" Vendor ID: ");
  736. puthex(PCIVendor(i)); puts("n");
  737. #endif
  738. }
  739. }
  740. #endif /* DEBUG */